eRose-DatabaseCleaning / Sources-non-evo

6 stars 3 forks source link

When jewel equipped, char name changes #9

Open hdelanno opened 6 years ago

hdelanno commented 6 years ago

Actually yes I have seen that or something very similar.

The problem comes from a mismatched packet structure and client side memory structure structure. First you have to understand how packets and memory structures work. It's a bit weird the way they do it in the client.

The packet sent from the server is loaded into a temporary memory buffer on receipt. Once fully loaded it is them mem-copied directly into the memory space reserved by the defined memory structure. A relevent example is the very packet that deals with adding a gem to an item. Of the top of my head i don't remember the exact packet name or precise structure. i would have to spend ages tracking it down to give a better answer.

In short though, it starts out like this

tagPartITEM                                        
    struct tagPartITEM                                     
    {                   Bitfields (uggghh)                 
32 bits     //unsigned int      m_nItemNo       : 18;   // 0~1023       Ah system number(ITEM_ID)   (0 ~ 999)   
        //unsigned int      m_nGEM_OP       : 9;    // 0~512        Jewelry number(m_bHasSocket==1) Or a number of options(m_bHasSocket==0)    
        //unsigned int      m_bHasSocket        : 1;    // 0~1      Jewelry, whether or not a socket       
        //unsigned int      m_cGrade         : 4;   // 0~15     Rating  (0~9)   

        //PY modified version for 137                                  
48 bits     short   m_nItemNo;          // 0~9999                  
        short   m_nGEM_OP;          // 0~512                   
        byte    m_bHasSocket;           // 0~1                 
        byte    m_cGrade;           // 0~15                
    } ;                                    

As you can see from this, the original is the one at the top which uses bitfields to seperate all the data. I modified mine to get rid of those awkward little things but that's another story TagPartItem is a structure used to communicate all the information related to an item in game, so when you add a gem to an item you are modifying this structure(m_nGEM_OP contains the items gem number ). You are actually sending in a complete new version of it from the server which completely overwrites whatever the client already contains.

Anyway, this is just the start, there are a load more structures sent through in the packet, terminating with a string containing your character name. For some reason they put that right at the end. All it takes it to get one bit of data out of place or missing and then the remaining bits in the packet all get offset. Say your character name is "BoBidy", this get tagged on the end of the packet. Let's also say that somewhere in the server packet generation it's missing a bit in the data generation. Maybe m_nGEM_OP only sends 8 bits rather than the 9 that are defined in the receiving structure. Everything after the gem id will be offset 1 bit to the left. You will see this first in your name which will no longer be "BoBidy" but will be some garbled mess( I'm not going to bother seeing what happens to 8 bit ASCII characters when you bit shift an entire string but I'm sure you can imagine it). In some cases you might lose an entire byte (which makes it a little easier to diagnose) in which case your name will now be "oBidy "

It's going to be a pain in the ass to figure it all out. You will basically have to capture the packet and print it all out then compare it bitwise to the data structures at either end (server and client) to figure out where the bug is located. I basically just trashed the Arc server entirely as it was way to much of a mess to even think about trying to fix. All my development is done using a modified dev-rev 2 server along with my 137 client. I've come up with this kind of thing many times. It always comes down to analyzing packets and data structures to find out where they are mis-aligned. Not the easiest job in the world but it is definitely doable if you have the source code and a bit of basic data structure understanding.

hdelanno commented 6 years ago

This is the function responsible to print avatar's name: https://github.com/eRose-DatabaseCleaning/Sources-non-evo/blob/master/Client/Interface/DLGs/AvatarInfoDlg.cpp#L84