The process just terminated silently, so I can't provide any information to figure out what's wrong.
Adding some codes to try{} catch exceptions globaly and logging it might help.
This happens both old versions and the new version 4.98, once a week or more.
Even if there was one, I doubt it would tell us much, like why it happened. Last time this happened to you it was some subtle issue with triggers. Without seeing your setup it is hard to comment, but maybe you are somehow deleting something while it is still in use.
Even if there was one, I doubt it would tell us much, like why it happened. Last time this happened to you it was some subtle issue with triggers. Without seeing your setup it is hard to comment, but maybe you are somehow deleting something while it is still in use.
I think the main program should work normally even if there was an unexpected exception or fatal error in plugins.
And, logs are helpful to find out what's wrong in plugin.
What is the difference going to be from getting a message "Access Violation" (which it probably is) to just having it crash? Neither one really points at what the problem is.
What is the difference going to be from getting a message "Access Violation" (which it probably is) to just having it crash? Neither one really points at what the problem is.
If the main program crashed, the connection would be disconnected, and the role will be offline and lose something.
If it continue to work, although one of the plugin had stopped working, but the rest is still fine. The role is alive at least.
And I have chance to reinstall the stopped plugin via another Idle-Check plugin.
I think I tried the try...catch idea once. Either it didn't work at all, didn't do anything useful, or made things worse.
In an event-driven system like MFC, I don't even control the "main loop". That is part of the Windows event handler. The "first part" (where you might possibly add such a handler) is when an event comes in, like a keypress, mouse movement, or incoming byte from the server.
Even then, quite a few events result in the original event being consumed and another "helper" event pushed into the event queue.
I think you need to isolate down what is causing this. When did it start? At around that time, what did you change? New plugin? New trigger? Can you remove things (eg, plugins) and see if the problem goes away?
The plugin does working normally at most time.
And it will does crash after unknown time, maybe one hour, one day, one week or more.
The problem is, when it crashed, the process terminated silently, without leaving any tips or output from mud server, so I have no way to find out the wrong place.
Can you leave me some stack trace or others helpful?
In the release version, a stack trace wouldn't tell you much. If you had the debug version running, with the IDE, and it crashed, the stack trace might help.
I'm presuming one of your plugins is doing it, because no-one else has complained.
All I can suggest is the "binary" approach.
Remove half the plugins, test for a week. If it crashes, the problem is in the half you still have - if not, it is in the other half. Then remove half of what is left, and so on, until you narrow it down to one plugin.
I found out the function which caused the crash,and write a simple test code to demonstrate it.
<aliases>
<alias match="restart" enabled="y" script="restart" />
</aliases>
<script><![CDATA[
require "wait"
function restart()
ResetPlugin()
wait.make(function()
-- Do something here.
-- When we need to restart, we setup a timer to check it
if IsTimer("restart_timer") ~= 0 then
AddTimer("restart_timer", 0, 0, 3, "", timer_flag.Enabled, "restart_timer_func")
else
EnableTimer("restart_timer", true)
end
end)
end
function restart_timer_func()
wait.make(function()
-- Do restart check here
Note("restart now")
EnableTimer("restart_timer", false)
DoAfterSpecial(0.1, "restart", 10)
end)
end
function ResetPlugin()
DeleteTemporaryTriggers()
DeleteTemporaryTimers()
DeleteTemporaryAliases()
end
]]></script>
I don't understand why you are using "wait.make" here. None of the code you have uses the wait functions, so that is just adding unnecessary complexity.
I changed your code to:
function restart()
ResetPlugin()
-- Do something here.
-- When we need to restart, we setup a timer to check it
if IsTimer("restart_timer") ~= 0 then
AddTimer("restart_timer", 0, 0, 3, "", timer_flag.Enabled, "restart_timer_func")
else
EnableTimer("restart_timer", true)
end
end
function restart_timer_func()
-- Do restart check here
Note("restart now")
EnableTimer("restart_timer", false)
DoAfterSpecial(0.1, "restart", 10)
end
That didn't crash.
Also, what is it doing? The alias "restart" calls restart(), that adds a timer that calls restart_timer_func(), that calls restart() and so on. What does it all mean?
DoAfterSpecial(0.1, "restart", 10)
...
function restart()
ResetPlugin()
...
function ResetPlugin()
DeleteTemporaryTriggers()
DeleteTemporaryTimers()
DeleteTemporaryAliases()
end
DoAfterSpecial creates a temporary timer. Then when that calls restart() that calls ResetPlugin() which deletes the timer which has the script which is currently running. Hence the client crashes. Don't do that.
I have added guard code into version 4.99 to not allow a temporary timer to be deleted if a script is running from it.
I don't understand why you are using "wait.make" here. None of the code you have uses the wait functions, so that is just adding unnecessary complexity.
I changed your code to:
function restart()
ResetPlugin()
-- Do something here.
-- When we need to restart, we setup a timer to check it
if IsTimer("restart_timer") ~= 0 then
AddTimer("restart_timer", 0, 0, 3, "", timer_flag.Enabled, "restart_timer_func")
else
EnableTimer("restart_timer", true)
end
end
function restart_timer_func()
-- Do restart check here
Note("restart now")
EnableTimer("restart_timer", false)
DoAfterSpecial(0.1, "restart", 10)
end
That didn't crash.
Also, what is it doing? The alias "restart" calls restart(), that adds a timer that calls restart_timer_func(), that calls restart() and so on. What does it all mean?
I did some quests by the plugin. The procedure is nested loop, and possible to pause in a given situation.
When paused, it need to be restarted at some special conditions and delete temporaries.