Hey everyone,
Could someone please tell me how creating/deleting characters works?
Also, does anyone know what the server has to do when the client clicks accept on the character selection screen?
Thanks,
Nini
Hey everyone,
Could someone please tell me how creating/deleting characters works?
Also, does anyone know what the server has to do when the client clicks accept on the character selection screen?
Thanks,
Nini
please feel free to look over my c++ source to get some reference and direction. even though its c++ you can still get the structure.
and if c++ source proves too confusing, please feel free to look over OSAFlyFF the C# source.
Lol, ok.
Btw, c++ was the first programming language that I learned, and I have known it for almost 3 years now, I just decided to write my server files in Visual Basic because there were already servers done in c++. Also, your/KiKi's source is where I got the base for the socket system from in my source :P.
Sorry for the double post, but could someone tell me what the ClusterServer needs to send immediately after the user makes/deletes a character? Any help would be much appreciated.
Thanks,
Nini
So this is how it works:
A user clicks create character and it asks for details like hairstyle, gender etc etc.
Then when the user clicks OK, the button becomes disabled, a packet is sent to the cluster server containing all information in it. Most of the information is bytes as far as I can remember, except for haircolor, username, password and character name (obviously).
Then your cluster server should check if the character exists. If it does, you send back 0xFE packet (same as login's) with error code 0x524 (not sure about this one as I'm currently typing this post without looking at my source). otherwise, the server creates the character and sends back the character list packet with the new character.
Deleting a character - once you click delete, you'll be prompted if you are sure about it. If your client is not eflyff's client, then you'll probably be asked to type in a password to delete your character.
The packet your cluster receives will contain the username, the password that was entered during login, the password that was entered in the prompt screen (or just a random md5 hash if you're emulating eflyff) and the target character's ID to delete.
Keep in mind that your server should check all of the details everytime to avoid deleting someone else's character through packet editing.
When done, the character should be deleted from the database (or just marked as deleted, like I do, so I can recover old characters when I want, if I want) and once deleted, send back character list packet.
Hope that helped
Ok,
I think I'm doing everything that you said the cluster server should do, but it still isn't working. Whenever I create a character, I click ok and it sends the packet and creates the character, but it gets stuck and you can't get back to the character select screen.
For the deleting, sometimes everything works, and sometimes it doesn't work and the client gets disconnected. The character is still marked deleted, but the client will usually get disconnected so they have to go back to the channel select screen then reload the character select from there.
Thanks for any further help,
Nini
Remember, the character list packet requires the client's synchronization dword, so whenever you receive the packet you should read the dword and send it back during character list packet.
Ok, I am sending [INT - 0] right now immediately after &HF3 (0xf3), and it works perfectly fine, except after character create/delete.
*New train of thought*
Do you mean these 4 bytes?
If so, then great, but now what should I put in the character list packet when I need to send it after creating/deleting? I am going to assume the [0B] packet and try it out.Code:[5e] [INT - Length] [f3] [00] [00] [00] [INT - Verification]
Character creation:
Character deletionCode:string strUser = dp.Readstring(); string strPass = GetUnsafePasswordString(dp.Readstring()); if (strUser != this.strUsername || strPass.ToLower() != this.strPassword.ToLower()) { Destruct("Possible hack attempt: invalid username/password received when trying to create character", Log.MessageType.hack); return; } int dwDstSlot = dp.Readbyte(); string strCharacterName = dp.Readstring(); dp.dwPointer += 3; int dwHairstyle = dp.Readbyte(); int dwHaircolor = dp.Readint32(); int dwGender = dp.Readbyte(); dp.dwPointer++; int dwFacemodel = dp.Readbyte(); dp.dwPointer = dp.dwSize - 4; int dw = dp.Readint32(); // ......... SendCharacterList(dw);
List packet:Code:if (this.strUsername != dp.Readstring() || this.strPassword != GetUnsafePasswordString(dp.Readstring())) { Destruct("Possible hack attempt: invalid username/password while trying to delete character", Log.MessageType.hack); return; } dp.Readstring(); int dwCharacterID = dp.Readint32(); int dw = dp.Readint32(); //............ SendCharacterList(dw);
This is how you should do it, at least that works for me (pay attention to the dw variable)Code:public void SendCharacterList(int dw) { Packet pak = new Packet(); pak.Addint32(PAK_CHARACTER_LIST); pak.Addint32(dw); // ......
So what you are trying to say is that the 4 bytes after the character list header are supposed to be the same as the very last 4 bytes of the character create/delete packets?
I am going to go with that and test it as soon as my ****ing computer is fixed. Got a virus or something ><.