Active Member Mind Rapist 188 Posted January 13, 2019 Active Member Share Posted January 13, 2019 Hey, does anyone have a guide or smth for the official logout method, where logout gets canceled if any packet is received or sent to the client (regarding the character) except walking? For example if the character attacks, mounts, opens shop, drops item, anything other than walking, countdown for logout stops. Link to comment Share on other sites More sharing options...
OtherChoice 77 Posted January 13, 2019 Share Posted January 13, 2019 This is not how official logout works: in game/battle.cpp you have a function bool timed_event_cancel(LPCHARACTER ch) which checks whether the argument (LPCHARACTER ch) is logging off or not, if so it will cancel the timed event and return true. This function is called in int battle_melee_attack (LPCHARACTER ch, LPCHARACTER victim) on both victim and attacker and on a true (stopped logout attempt) will send chat_packet "the battle has begun..." If you want to stop logout on a custom defined action you can simply call timed_event_cancel(ch). 1 Link to comment Share on other sites More sharing options...
Active Member Mind Rapist 188 Posted January 13, 2019 Author Active Member Share Posted January 13, 2019 8 hours ago, OtherChoice said: This is not how official logout works: in game/battle.cpp you have a function bool timed_event_cancel(LPCHARACTER ch) which checks whether the argument (LPCHARACTER ch) is logging off or not, if so it will cancel the timed event and return true. This function is called in int battle_melee_attack (LPCHARACTER ch, LPCHARACTER victim) on both victim and attacker and on a true (stopped logout attempt) will send chat_packet "the battle has begun..." If you want to stop logout on a custom defined action you can simply call timed_event_cancel(ch). Wow thanks for the information. Isn't there a more generic method to call the cancel event like a general packet handler or something? Link to comment Share on other sites More sharing options...
Silver Sonitex 1438 Posted January 13, 2019 Silver Share Posted January 13, 2019 You can call the function from input_main.cpp and other source files which handle received packets. Same goes for sent packets Like so: //input_main.cpp case HEADER_CG_PARTY_INVITE: PartyInvite(ch, c_pData); timed_event_cancel((ch); break; Link to comment Share on other sites More sharing options...
Active Member Mind Rapist 188 Posted January 13, 2019 Author Active Member Share Posted January 13, 2019 6 minutes ago, Sonitex said: You can call the function from input_main.cpp and other source files which handle received packets. Same goes for sent packets Like so: //input_main.cpp case HEADER_CG_PARTY_INVITE: PartyInvite(ch, c_pData); timed_event_cancel((ch); break; Thanks I'm gonna try Link to comment Share on other sites More sharing options...
OtherChoice 77 Posted January 14, 2019 Share Posted January 14, 2019 If you won't succed on your own just let us know what are you exactly trying to accomplish, gl Link to comment Share on other sites More sharing options...
Active Member Mind Rapist 188 Posted January 14, 2019 Author Active Member Share Posted January 14, 2019 13 hours ago, OtherChoice said: If you won't succed on your own just let us know what are you exactly trying to accomplish, gl Thanks, well I got this: error: use of undeclared identifier 'timed_event_cancel'; did you mean 'event_cancel'? I searched for the function but I couldn't find it in any header file (*.h) to include, so I thought asking here before I mess this up. Also a few questions came up. Is there a generic file which handles sent packets (like input_main.cpp for received packets) and 2nd: timed_event_cancel is only about the logout event, or there are more timed events handled by this? EDIT: I also tried event_cancel(&m_pkDisconnectEvent); and included desc.h of course but I'm still getting compiling errors: error: use of undeclared identifier 'm_pkDisconnectEvent' Link to comment Share on other sites More sharing options...
OtherChoice 77 Posted January 15, 2019 Share Posted January 15, 2019 Honestly i do not know why timed_event_cancel has no declaration however just go in game/battle.h, find extern void battle_end(LPCHARACTER ch); and add below extern bool timed_event_cancel(LPCHARACTER ch); then check game/battle.cpp should contain this function bool timed_event_cancel(LPCHARACTER ch) { if (ch->m_pkTimedEvent) { event_cancel(&ch->m_pkTimedEvent); return true; } return false; } Now you should not have any compiling error. Next you asked about packets: input_main.cpp handles packets with HEADER_CG (CG == client to game) in function int CInputMain::Analyze(LPDESC d, BYTE bHeader, const char * c_pData). Packets with HEADER_GC (GC == game to client) are instead handled by the client itself but according to the phase the client is in (eg. phaseGame, phaseSelect...). phaseGame packets (which are most probably what are you looking for) are recived in Userinterface/PythonNetworkStreamPhaseGame.cpp in void CPythonNetworkStream::GamePhase(). Other Client Packet Reciever Spoiler bool CGuildMarkDownloader::__DispatchPacket(UINT header) //GuilMarkDownloader.cpp { switch (header) { case HEADER_GC_PHASE: return __LoginState_RecvPhase(); case HEADER_GC_HANDSHAKE: return __LoginState_RecvHandshake(); case HEADER_GC_PING: return __LoginState_RecvPing(); case HEADER_GC_MARK_IDXLIST: return __LoginState_RecvMarkIndex(); case HEADER_GC_MARK_BLOCK: return __LoginState_RecvMarkBlock(); case HEADER_GC_GUILD_SYMBOL_DATA: return __LoginState_RecvSymbolData(); case HEADER_GC_MARK_DIFF_DATA: return true; } return false; } void CPythonNetworkStream::LoginPhase() //UserInterface/PythonNetworkStreamPhaseLogin.cpp { TPacketHeader header; if (!CheckPacket(&header)) return; switch (header) { case HEADER_GC_PHASE: if (RecvPhasePacket()) return; break; case HEADER_GC_LOGIN_SUCCESS3: if (__RecvLoginSuccessPacket3()) return; break; case HEADER_GC_LOGIN_SUCCESS4: if (__RecvLoginSuccessPacket4()) return; break; and so on (if you want to find em all go in visual studio CTRL+F -> find HEADER_GC -> in whole solution And lastly there are some HEADER_GD packets which are game to database handled by db binary. Link to comment Share on other sites More sharing options...
Active Member Mind Rapist 188 Posted January 15, 2019 Author Active Member Share Posted January 15, 2019 4 hours ago, OtherChoice said: Honestly i do not know why timed_event_cancel has no declaration however just go in game/battle.h, find extern void battle_end(LPCHARACTER ch); and add below extern bool timed_event_cancel(LPCHARACTER ch); then check game/battle.cpp should contain this function bool timed_event_cancel(LPCHARACTER ch) { if (ch->m_pkTimedEvent) { event_cancel(&ch->m_pkTimedEvent); return true; } return false; } Now you should not have any compiling error. Next you asked about packets: input_main.cpp handles packets with HEADER_CG (CG == client to game) in function int CInputMain::Analyze(LPDESC d, BYTE bHeader, const char * c_pData). Packets with HEADER_GC (GC == game to client) are instead handled by the client itself but according to the phase the client is in (eg. phaseGame, phaseSelect...). phaseGame packets (which are most probably what are you looking for) are recived in Userinterface/PythonNetworkStreamPhaseGame.cpp in void CPythonNetworkStream::GamePhase(). Other Client Packet Reciever Hide contents bool CGuildMarkDownloader::__DispatchPacket(UINT header) //GuilMarkDownloader.cpp { switch (header) { case HEADER_GC_PHASE: return __LoginState_RecvPhase(); case HEADER_GC_HANDSHAKE: return __LoginState_RecvHandshake(); case HEADER_GC_PING: return __LoginState_RecvPing(); case HEADER_GC_MARK_IDXLIST: return __LoginState_RecvMarkIndex(); case HEADER_GC_MARK_BLOCK: return __LoginState_RecvMarkBlock(); case HEADER_GC_GUILD_SYMBOL_DATA: return __LoginState_RecvSymbolData(); case HEADER_GC_MARK_DIFF_DATA: return true; } return false; } void CPythonNetworkStream::LoginPhase() //UserInterface/PythonNetworkStreamPhaseLogin.cpp { TPacketHeader header; if (!CheckPacket(&header)) return; switch (header) { case HEADER_GC_PHASE: if (RecvPhasePacket()) return; break; case HEADER_GC_LOGIN_SUCCESS3: if (__RecvLoginSuccessPacket3()) return; break; case HEADER_GC_LOGIN_SUCCESS4: if (__RecvLoginSuccessPacket4()) return; break; and so on (if you want to find em all go in visual studio CTRL+F -> find HEADER_GC -> in whole solution And lastly there are some HEADER_GD packets which are game to database handled by db binary. Thanks, packets became very clear now. It worked so I added that to a few packets but for some reason I cannot logout now. Just sitting there, hitting logout and the countdown never starts. I reviewed the affected packets but I don't seem to understand why this is happening. Here is a list of the packets I edited: HEADER_CG_CHAT HEADER_CG_WHISPER HEADER_CG_ITEM_USE HEADER_CG_ITEM_DROP HEADER_CG_ITEM_DROP2 HEADER_CG_ITEM_MOVE HEADER_CG_ITEM_PICKUP HEADER_CG_ITEM_USE_TO_ITEM HEADER_CG_ITEM_GIVE HEADER_CG_EXCHANGE HEADER_CG_ATTACK HEADER_CG_SHOOT HEADER_CG_USE_SKILL HEADER_CG_SHOP HEADER_CG_MESSENGER HEADER_CG_SAFEBOX_CHECKIN HEADER_CG_PARTY_INVITE HEADER_CG_PARTY_ANSWER HEADER_CG_PARTY_USE_SKILL HEADER_CG_ANSWER_MAKE_GUILD HEADER_CG_FISHING HEADER_CG_MYSHOP HEADER_CG_REFINE HEADER_CG_DRAGON_SOUL_REFINE Each time, I added the timed_event_cancel right above break; Link to comment Share on other sites More sharing options...
OtherChoice 77 Posted January 15, 2019 Share Posted January 15, 2019 Uhm at first i would say you should remove it from HEADER_CG_CHAT HEADER_CG_WHISPER and try again, if this is not the problem it will need some deeper debugging Link to comment Share on other sites More sharing options...
Active Member Mind Rapist 188 Posted January 15, 2019 Author Active Member Share Posted January 15, 2019 2 hours ago, OtherChoice said: Uhm at first i would say you should remove it from HEADER_CG_CHAT HEADER_CG_WHISPER and try again, if this is not the problem it will need some deeper debugging Thanks, it worked. Although I found something else. Seems like what I was trying to do was to copy these lines for every command that the player gives to the game (horse riding for example): if (ch->m_pkTimedEvent) { ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("취소 되었습니다.")); event_cancel(&ch->m_pkTimedEvent); } Is there a more generic way of doing this for all of the commands and for [SPACE] pressing, equipment change/remove, item moving, etc? 1 Link to comment Share on other sites More sharing options...
Recommended Posts
Please sign in to comment
You will be able to leave a comment after signing in
Sign In Now