diff --git a/bin/scripts/__core_hookHelper.def b/bin/scripts/__core_hookHelper.def index f437e32..3498899 100644 --- a/bin/scripts/__core_hookHelper.def +++ b/bin/scripts/__core_hookHelper.def @@ -1,34 +1,59 @@ +#script=hookhelper +#onload +set,CurScript +#/onload + #script=IsHooked // @def: script name -return ?{ScriptHasLine,{${@def}} #tag:hook:${@caller}} +// [@0: hook name / name of script that hooked script in @def] +set,sc ${@0} +default,sc ${@caller} +return ?{ScriptHasLine,{${@def}} #tag:hook:${sc}} #script=HookStart // @def: script name -appenddef,{${@def}} #tag:hook:${@caller} -set,{#HookHelper::CurScript} ${@def} +// [@0: calling script] +set,c ${@0} +default,c ${@caller} +appenddef,{${@def}} #tag:hook:${c} +set,{#hookhelper::CurScript} ${@def} #script=HookEnd -set,sc ${@0} -default,sc ${#HookHelper::CurScript} -appenddef,{${sc}} #tag:hook-end:${@caller} +// [@def: name of script that was hooked] +// [@0: name of calling script] +set,sc ${@def} +default,sc ${#hookhelper::CurScript} +set,c ${@0} +default,c ${@caller} +appenddef,{${sc}} #tag:hook-end:${c} +set,#hookhelper::CurScript unset ${sc} unset sc #script=HookAdd // @def: script line -// @0: script name +// [@0: script name. default: last script passed to HookStart] set,sc ${@0} -default,sc ${#HookHelper::CurScript} +default,sc ${#hookhelper::CurScript} +if ?{not ?{strlen ${sc}}} + return +endif appenddef,{${sc}} ${@def} unset sc #script=HookAddList // @def: list name -// @0: script name +// [@0: script name. default: last script passed to HookStart] +// [@1: name of calling script] set,sc ${@0} -set,l ?{globname,{${@caller}} ${@def}} -default,sc ${#HookHelper::CurScript} +set,c ${@1} +default,c ${@caller} +set,l ?{globname,{${c}} ${@def}} +default,sc ${#hookhelper::CurScript} +if ?{not ?{strlen ${sc}}} + return +endif set,i 0 loop if ?{bigger_eq,${i} ?{llen ${l}}} @@ -41,14 +66,74 @@ unset sc #script=HookStartOpcode // @def: opcode name -HookStart OPCODE::${@def} +// [@0: calling script] +set,c ${@0} +default,c ${@caller} +HookStart,{${c}} OPCODE::${@def} +#script=UnHook +// @def: name of script where to remove hook from +// [@0: hook name (usually name of script that installed the hook). default: name of calling script] +set,sc ${@0} +default,sc ${@caller} +set,sl #DEFSCRIPT::SCRIPT::${@def} +set,hn #tag:hook:${sc} +set,hne #tag:hook-end:${sc} +loop + if ?{not ?{IsHooked,{${sc}} ${@def}}} + exitloop + endif + set,p ?{lfind,{${sl}} ${hn}} + if ?{strlen ${p}} + loop + if ?{equal,{?{lerase,{${sl}} ${p}}} ${hne}} + exitloop + endif + endloop + endif +endloop +unset sl +unset hn +unset hne +unset sc -////////////////////////////////////////////////////////// -#comments-start -TODO: -- add UnHook[,which_script] hook_name -- add UnHookAll which_script -- Add HookStartAfter +#script=UnHookOpcode +// @def: opcode name +// [@0: name of calling script] +set,sc ?{@0} +default,sc ${@caller} +UnHook,{${sc}} OPCODE::${@def} -#comments-end \ No newline at end of file +#script=UnHookAll +// @def: name of script to remove all hooks from +// [@0: name of calling script] +set,sc ${@0} +set,sl #DEFSCRIPT::SCRIPT::${@def} +set,hn #tag:hook: +set,hne #tag:hook-end: +set,i 0 +set,hookcode false +loop + set,erased false + if ?{bigger_eq,${i} ?{llen ${sl}}} + exitloop + endif + set,line ?{lindex,{${sl}} ${i}} + if ?{equal,{${hn}} ?{substr,?{strlen ${hn}} ${line}}} + set,hookcode true + else + if ?{equal,{${hne}} ?{substr,?{strlen ${hn}} ${line}}} + lerase,{${sl}} ${i} + set,hookcode false + set,erased true + endif + endif + + if ${hookcode} + lerase,{${sl}} ${i} + set,erased true + endif + if ?{not ${erased}} + add,i 1 + endif +endloop diff --git a/src/Client/PseuWoW.cpp b/src/Client/PseuWoW.cpp index 8c980db..7f6b55e 100644 --- a/src/Client/PseuWoW.cpp +++ b/src/Client/PseuWoW.cpp @@ -213,7 +213,7 @@ void PseuInstance::Run(void) logdebug("GUI: switching to startup display..."); GetGUI()->SetSceneState(SCENESTATE_GUISTART); } - // TODO: as soon as username ans password can be inputted into the gui, wait until it was set by user. + // TODO: as soon as username and password can be inputted into the gui, wait until it was set by user. if(GetConf()->realmlist.empty() || GetConf()->realmport==0) { @@ -268,9 +268,9 @@ void PseuInstance::Run(void) void PseuInstance::Update() { - // if the user typed anything into the console, process it before anything else - if(_cli) // need to to process only if cli exists - ProcessCliQueue(); + // if the user typed anything into the console, process it before anything else. + // note that it can also be used for simulated cli commands sent by other threads, so it needs to be checked even if cli is disabled + ProcessCliQueue(); // delete sessions if they are no longer needed if(_rsession && _rsession->MustDie()) diff --git a/src/Client/Realm/RealmSession.cpp b/src/Client/Realm/RealmSession.cpp index 08314bf..6139826 100644 --- a/src/Client/Realm/RealmSession.cpp +++ b/src/Client/Realm/RealmSession.cpp @@ -500,8 +500,7 @@ void RealmSession::_HandleLogonProof(ByteBuffer& pkt) { logerror("AUTH_LOGON_PROOF: Recieved incorrect/unknown packet. Hexdump:"); DumpInvalidPacket(pkt); - if(GetInstance()->GetConf()->reconnect) - SetMustDie(); + DieOrReconnect(true); return; } uint8 error = pkt[1]; @@ -511,11 +510,13 @@ void RealmSession::_HandleLogonProof(ByteBuffer& pkt) { case REALM_AUTH_UPDATE_CLIENT: log("The realm server requested client update."); + DieOrReconnect(true); return; case REALM_AUTH_NO_MATCH: case REALM_AUTH_UNKNOWN2: logerror("Wrong password or invalid account information or authentication error"); + DieOrReconnect(true); return; // cover all other cases. continue only if success. @@ -524,7 +525,7 @@ void RealmSession::_HandleLogonProof(ByteBuffer& pkt) { logerror("AUTH_LOGON_PROOF: unk error = 0x%X",error); pkt.rpos(2); - SetMustDie(); + DieOrReconnect(true); return; } } @@ -547,10 +548,7 @@ void RealmSession::_HandleLogonProof(ByteBuffer& pkt) printf("My M2 :"); printchex((char*)_m2,20,true); printf("Srv M2:"); printchex((char*)lp.M2,20,true); - if(GetInstance()->GetConf()->reconnect) - SetMustDie(); - else - GetInstance()->SetError(); + DieOrReconnect(true); } } @@ -584,7 +582,7 @@ void RealmSession::_HandleTransferData(ByteBuffer& pkt) if(!_file_size) { logerror("Realm server attempted to transfer a file, but didn't init!"); - SetMustDie(); + DieOrReconnect(false); return; } @@ -693,7 +691,14 @@ void RealmSession::SendRealmPacket(ByteBuffer& pkt) } } - - - - +// err=true will close PseuWoW if ExitOnError=1 +void RealmSession::DieOrReconnect(bool err) +{ + if(GetInstance()->GetConf()->reconnect) + SetMustDie(); + else if(err) + { + SetMustDie(); + GetInstance()->SetError(); + } +} diff --git a/src/Client/Realm/RealmSession.h b/src/Client/Realm/RealmSession.h index 8224443..f6557da 100644 --- a/src/Client/Realm/RealmSession.h +++ b/src/Client/Realm/RealmSession.h @@ -32,6 +32,7 @@ private: AuthHandler *_GetAuthHandlerTable(void) const; void SendRealmPacket(ByteBuffer&); void DumpInvalidPacket(ByteBuffer&); + void DieOrReconnect(bool err = false); SocketHandler _sh; PseuInstance *_instance;