Page 1 of 1
How to react on crashed clients
Posted: Tue Sep 24, 2013 1:32 pm
by BlubBlab
I realized I didn't post my final solution for how I auto restart a crashed client:
This isn't my code but is looks very simalar:
First we to make need sure that we run even the bot stucks in the moveTo loop.
We doing that by:
bot.lua line 662
Code: Select all
while(true) do
if isClientCrashed() then
error("Client crash detected in main bot loop.")
end
changing to
Code: Select all
-- 10 sec but you can use less if wanted
registerTimer("ClientDetection", secondsToTimer(10), checkclient);
while(true) do
somewhere above the main function
Code: Select all
function checkclient()
local crashflag, cpid = isClientCrashed();
if crashflag then
error("Client crash detected .")
end
end
But thats not all how to restart the client first you need this:
http://solarstrike.net/phpBB3/viewtopic ... &start=540
Then you must know that the error callback call also isClientCrashed() if memory readings goes wrong, so you need to do that there:
function.lua
Code: Select all
function isClientCrashed()
local crashwins = findWindowList("Crash Report", "#32770");
local numcrashs = #crashwins;
local crashflag = false;
local pid = 0;
if( #crashwins == 0 ) then
return false
end
printf("Found "..numcrashs.." crashed clients \n");
local crashparent
for i = 1, #crashwins, 1 do
crashparent = getWindowParent(crashwins[i])
if crashparent and crashparent == getWin() then
-- Looks like the paired game client crashed.
pid = findProcessByWindow(crashwins[i]);
crashflag = true;
end
end
if(RestartChar ~= nil and crashflag == true)then
RestartChar();
return false, pid;
end
return crashflag , pid
end
RestartChar() is a wrapper function from me and looks like that:
Code: Select all
function RestartChar( client)
if(client == nil) then
client = "Client"
end
char = getChar();
acc = getAcc();
ChangeCharRestart(char,acc,client);
player:update()
loadProfile()
if( char ~= getChar() or acc ~= getAcc())then
ChangeCharRestart(char,acc,"Client")
end
showWindow(getWin(),sw.minimize)
end
This works in 99% of all cases and the bot continue exactly where he was disconnected, so writing an onclientcrashed event would be the next step
Re: How to react on crashed clients
Posted: Wed Sep 25, 2013 1:40 am
by rock5
Firstly, I wouldn't change isClientCrashed. It's an informational function. It tells you if the client is crashed. I'm not going to have it do a restart too.
Secondly you are using a custom link called "Client". What's that doing there?
Thirdly, the obvious place to deal with the client crashing is in the errorCallback function which it checks probably more regularly than a timed event.
Also I'm not sure how it is working. If it detects a crashed client then it uses RoMScript commands, to get the acc and char info, which shouldn't work if it's crashed. Did you test it with actual client crashes?
What it should do is, when the bot starts it should record the account and character numbers. Then when ChangeChar or LoginNextChar is run it should update those values. Then when it detects a crash it will know which character to log into. The problem is there is no way to know which link was used to log in the first time. I don't know how to solve it. But the onclientcrashed idea is a good one. Then users can write their own code to deal with crashes and determine themselves which link they will use.
Re: How to react on crashed clients
Posted: Wed Sep 25, 2013 2:06 am
by rock5
Maybe we could create link names for each server. Then we could get the server from in game and know which link to use. Of course you can log into more than 1 server in one game. Maybe we could have a list of server names linked to shortcuts and use that to determine which link to use. Eg.
Code: Select all
list = {
["Siochain"] = "romeu",
["Smacht"] = "romeu",
["Sin City"] = "rom4u",
["Angel City"] = "rom4u",
}
Re: How to react on crashed clients
Posted: Wed Sep 25, 2013 3:55 am
by BlubBlab
rock5 wrote:Firstly, I
Also I'm not sure how it is working. If it detects a crashed client then it uses RoMScript commands, to get the acc and char info, which shouldn't work if it's crashed. Did you test it with actual client crashes?
It is absolute strangely but it works I thought myself that can't work but it does(about 150 times tested), I can only assume that the client still works in background when the rom's crash report pops up.
Okay assume is a little bit less because I once caught the rom client with the debug tool from windows and I let the client run in VS's debugger and it still did run.
The only thing I'm not sure if windows(7) bug reports are caught correctly.
About the link I forgot to delete it basically this function was a all-you-need function and I use only one *.lnk, but memorizing all that stuff is good idea independent
Re: How to react on crashed clients
Posted: Wed Sep 25, 2013 1:24 pm
by rock5
I got it working to my satisfaction including onclientcrash. The only downside is you have to put code in every profile to make it work for every character. Maybe I should use a default function something like you did and like lisa did with the unstick functions. If the function exists then it uses it. Then I could even include the function in the userfunction with default values to restart the client and users could overwrite it with their own function if they like.
Ok, then a bit more work to do.
Re: How to react on crashed clients
Posted: Wed Sep 25, 2013 2:51 pm
by rock5
Ok. Try this out for me. You'll need these files.
- -- userfunction_login.lua --
-- userfunction_LoginNextChar.lua --
-- bot.lua --
Files removed as the originals have been updated to include the changes.
I ended up using a timed event after all. I don't think the onerror callback is always triggered.
Instead of a profile onclientcrash event I went for a function it runs if it exists, namely 'onClientCrash()'. A default for this function is included in userfunction_loginnextchar so all you have to do is install that userfunction and it will automatically restart crashed clients.
I thought about using the RomScript commands to get the account info seeing as it works but what happens if it crashes while changing character? I don't think it would work but I can't test it anyway but I included a crash test in watForLoadingScreen() anyway. It should work ok except if you are changing to an account on a different server.
I've added support for a server/link list. It will still default to 'rom' link so if you only use the one link you don't need to use the server/link list. But if you do use more than one link you can include a file in the same folder as userfunction_login.lua called 'ServerLinkList.lua' for the other links besides 'rom'. Eg. mine looks like this
Code: Select all
ServerLinkList = {
["Sin City"] = "rom4u",
["Angel City"] = "rom4u",
}
So if a rom4u client crashes it knows to use the rom4u link. If one of my EU or AU clients crash it will use the default 'rom' link because they use the same link.
Re: How to react on crashed clients
Posted: Thu Sep 26, 2013 11:32 am
by rock5
While reviewing my changes for committing, I find that I don't like the fact that the bot is remembering some values for a userfunction. But I can't see any way around it, no elegant way anyway. Grrr...
Re: How to react on crashed clients
Posted: Thu Sep 26, 2013 11:59 am
by BlubBlab
How a about a common memory ability(table) for the bot that all userfunction can use?
It really a pain that userfunction can't safe their values.
EDIT: mom shouldn't that work with _G as global
Re: How to react on crashed clients
Posted: Thu Sep 26, 2013 12:08 pm
by rock5
The problem is not where is can save them but that RoMScript wont work when the userfunctions are being loaded. So I need to somehow get the account details after the bot has started when RoMScript will work. The only way I can think of is to register a timer to keep trying to get the values until the bot has fully loaded and it can, which is a pretty ugly way to do it. I'm still not sure which way I'll go.
Re: How to react on crashed clients
Posted: Thu Sep 26, 2013 12:19 pm
by BlubBlab
Ah you mean because you haven't change char you don't know have memorized the data for a relogin.
Is see the only possible is timer or a callback function in which you register your update function and clear it afterwards
I must say I don't see other options.