Jump to content

Official logout method


Recommended Posts

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

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).

  • Love 1
Link to comment
Share on other sites

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

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

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

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

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

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?

  • Good 1
Link to comment
Share on other sites

Please sign in to comment

You will be able to leave a comment after signing in



Sign In Now

Announcements



×
×
  • Create New...

Important Information

Terms of Use / Privacy Policy / Guidelines / We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.