Welcome!

Join our community of MMO enthusiasts and game developers! By registering, you'll gain access to discussions on the latest developments in MMO server files and collaborate with like-minded individuals. Join us today and unlock the potential of MMO server development!

Join Today!

[xmas release] V Matrix System (5th Job)

Initiate Mage
Joined
Nov 6, 2016
Messages
3
Reaction score
0
First of all, that's a very informative response, thank you.

Correct. Following Nexon's styles, User-related handling belongs in CUser, so this class would be inside of his User class itself. An incoming packet would go from ClientSocket.ProcessPacket, filter down to ClientSocket.ProcessUserPacket, and if the pUser (User reference) isn't null, it should call to pUser.OnPacket, which will hit both of the provided functions from a switch. CharacterData is the portion of User encoded within SetField.

:)

As for your question towards the client reading in CharacterData, not all but most of all that data is indeed read in entirely by the client within CharacterData::Decode (the rest of the variables are handled from the data you do send/read). You can control how much you want to Encode or Decode through the "DBChar" flag which is the first 8-byte flag in the Encode packet. In higher versions there are some classes that are encoded always, regardless of flag though..sadly.

I see, did you actually xref'd the values to check that ? (Just curious)

As for Message.Encode, that shouldn't be an inner-class within User, it should just be a Message class. The way Nexon handles "Message" (or CWvsContext::OnMessage) is through 10 different functions leading to a major function with massive amounts of parameters. To simplify it, we just made a class. In this case the MessageResult enum points to SystemMessage, which is going to display the common "Red" notice equivalent to ServerNotice 5 in OdinMS. It is actually its own function (SendSystemMessage to be exact, like @Fraysa was pointing out), but he just sends the packet itself here. However.. assuming the Encode is a standard static OutPacket returned function like it's supposed to be, then it should be passed into SendPacket, as that won't do anything at all currently -- Encode just means to write data within that class.

:Facepalm:, I thought Message.Encode deos something else haha, thank you for enlightening me.

From a server-end standpoint, you may refer to BMS v53's files. This will help explain the similarities between Nexon's client-end and server-end if you wish to know more. The point of CharacterData is to simply split up a character's Items, Skill Data, and their Records (Mini Game information, Rings/Marriage information, etc) from the main User class and have it all stored and encoded elsewhere. CharacterData also holds an additional class reference for GW_CharacterStat which holds the character's stat information, and all of this is the data that Nexon saves/loads from their databases (plus, this is the information they send between servers to migrate your character). This is why it makes sense to why they store the matrix here as it was done. ;P


I did not know about BMS files, I just downloaded them and they actually include the server files (&pdb) and their server structure (Channel/World/Login - Center/Game/Login), But I did not find the database files, any case you have them ?



Edit: did not see PacketBakery's response.

It seems the people above me explained it pretty well, GetCharacterData is just retrieving the reference of my CharacterData class via an initialized variable in User. All of my User related decode packets (handlers) are inside my user class.

Message is not an inner class but it's own class. It is a switch case encode for the packet using opcode "Message".

I reckon they have, thank you for responding nevertheless :)
 
Newbie Spellweaver
Joined
Sep 11, 2016
Messages
59
Reaction score
81
First of all, that's a very informative response, thank you.
I did not know about BMS files, I just downloaded them and they actually include the server files (&pdb) and their server structure (Channel/World/Login - Center/Game/Login), But I did not find the database files, any case you have them ?
Database.dll
 
Joined
Jun 5, 2010
Messages
567
Reaction score
598
oPacket.EncodeInt(this.bActive ? 2 : 1);

It's actually the state of the node I believe. There's 3 that I've seen so far:
0: Disassembled
1: Inactive/Not selected
2: Active in V Matrix

Yes, Nexon keeps track of all the disassembled nodes for some reason. That's why a lot of people are getting stuck since they opened like thousands of these.
 
Custom Title Activated
Loyal Member
Joined
Jun 30, 2008
Messages
3,451
Reaction score
1,616
oPacket.EncodeInt(this.bActive ? 2 : 1);

It's actually the state of the node I believe. There's 3 that I've seen so far:
0: Disassembled
1: Inactive/Not selected
2: Active in V Matrix

Yes, Nexon keeps track of all the disassembled nodes for some reason. That's why a lot of people are getting stuck since they opened like thousands of these.
That's correct, it's the state. The server couldn't handle it and it made characters stuck. I really wonder what they will do after the maintenance. They have a fix.. I assume they won't send disassembled nodes anymore!! That way I can finally use 6k nodestones lol.
Since when do you still dev lol?

PacketBakery
Nice release, really useful though I have some comments:
1. Please don't capital letters in Java.. it's getCharacterData, not GetCharacterData (pls pls)
2. Don't split the time in high and low time. Just write a long like we've always done in java sources (I personally made a class to handle file times. Converts java time into file time etc)

Nice reverse engineering though..

Edit: Also the last byte in the VMatrixUpdate is a boolean. It's used when you enhance/disassemble nodes. It will make the UI where you handle this, remove the node.
Also the packet you receive, the last int is NOT always -1. It's the node you used to enhance another node (which is in the int before this one). Type 2 is enhancing and type 3 is disassemble... so don't use > 0 there
 
Newbie Spellweaver
Joined
Sep 11, 2016
Messages
59
Reaction score
81
@PacketBakeryNice release, really useful though I have some comments:
1. Please don't capital letters in Java.. it's getCharacterData, not GetCharacterData (pls pls)

Sorry I don't follow java convention in this as most of my coding is done in c++, I simply released in java cause everyone uses it here.

2. Don't split the time in high and low time. Just write a long like we've always done in java sources (I personally made a class to handle file times. Converts java time into file time etc)

You should not be sending a long, it is in fact 2 ints for high and low time. I don't know why you would suggest doing it incorrectly.

Edit: Also the last byte in the VMatrixUpdate is a boolean. It's used when you enhance/disassemble nodes. It will make the UI where you handle this, remove the node.
Also the packet you receive, the last int is NOT always -1. It's the node you used to enhance another node (which is in the int before this one). Type 2 is enhancing and type 3 is disassemble... so don't use > 0 there
Thanks for the notes, I judged it all based on what I saw in ida so I appreciate the changes and I will update the thread sometime this week to reflect them.
 
Custom Title Activated
Loyal Member
Joined
Jun 30, 2008
Messages
3,451
Reaction score
1,616
Sorry I don't follow java convention in this as most of my coding is done in c++, I simply released in java cause everyone uses it here.



You should not be sending a long, it is in fact 2 ints for high and low time. I don't know why you would suggest doing it incorrectly.


Thanks for the notes, I judged it all based on what I saw in ida so I appreciate the changes and I will update the thread sometime this week to reflect them.

Np, figured you had done it in a different language.

In Java I highly suggest writing it as a long like we already do. You will only make it harder by writing two ints.

Glad I could help too :) let's see what Nexon changes after the maintenance
 
Newbie Spellweaver
Joined
Sep 11, 2016
Messages
59
Reaction score
81
In Java I highly suggest writing it as a long like we already do. You will only make it harder by writing two ints.
Why are you suggesting that though and why does the language matter? It's only a long because someone decided to change it into a long. If you have a proper FileTime class, you should be using 2 ints for high and low time. I believe using a long is incorrect and also a bad practice.

Edit: Updated OP with changes based on kevintjuh93 notes
 
Last edited:
Joined
Jun 5, 2010
Messages
567
Reaction score
598
Np, figured you had done it in a different language.

In Java I highly suggest writing it as a long like we already do. You will only make it harder by writing two ints.

Glad I could help too :) let's see what Nexon changes after the maintenance

I follow the GMS scene and do not dev. btw they didn't change the nodestones. Disassembled nodes still exist in data.
 
Back
Top