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!

[v62/v83] [For WZ Edits] Hair/Item Cap Client Fix

Joined
Jan 18, 2010
Messages
3,109
Reaction score
1,139
By popular demand I decided to go back and look into the client to see where to remove the very common Item and Hair client caps. For anyone that doesn't already know, in low-version clients (such as 62), the maximum ItemID that will be recognized for items is is something that has a ID less than 3000 (e.g 1003000 for hats won't work in 62). There is also the common Hair cap where your character's hair becomes bald if the HairID is >= 40000.

Starting off with the Item Cap in lower version clients -- why does it happen? Well, Nexon has three genders used for items and this is how they are identified: 0 for Males, 1 for Females, and 2 for None. So with these three genders and how Nexon's items work (using hats again for example), 1000000 is a Male-only item, 1001000 is a Female-only item, and 1002000 is a item for all genders. Let's see the math behind this.

PHP:
if ( nItemID / 1000000 == 1 )
    nItemGender = nItemID / 1000 % 10;
  else
    nItemGender = 2;
  if ( nGender != 2 && nItemGender != 2 && nGender != nItemGender )
    return 0;

So first off, this Gender check is only in place for equipment (ID's that start with 1). The gender is formed from nItemID / 1000 % 10. So, 1000000 / 1000 % 10 = 0 (Male), 1001000 / 1000 % 10 = 1 (Female), and 1002000 / 1000 % 10 = 2 (None). This makes sense, so what about items that are 3, like 1003000+? Well, 1003000 / 1000 % 10 = 3.. It's not 0, 1, or 2. So the only way to wear an item over 1003000 is if you made your character's gender a 3 so that the character's gender is equal to the same gender of the item.

So how can we fix this? Well, we can easily just change the assembly instruction in the client from checking if the Gender is NOT 2 and the Item's Gender is NOT 2, and instead change it so if the Gender is LESS than 2 or if the Item's Gender is LESS than 2 (either 0 or 1 -- Male or Female), THEN we can validate if the character's gender and the item's gender are equal or not.

This is a extremely easy fix! We just need to change two simple instructions from JE to JL (you can do this in OllyDbg). For v62, here is what you have to modify (ignore the comments, they're just to better explain):
Code:
Change:
0044D7D4	je      short 0044D7DF ; if (nItemGender != 2)
0044DA9A	je      short 0044DAA5 ; if (nItemGender != 2)

To:
0044D7D4	jge     short 0044D7DF ; if (nItemGender < 2)
0044DA9A	jge     short 0044DAA5 ; if (nItemGender < 2)

Change:
004C2221	cmp     edx, 2
004C2224	je      short 004C2235

To:
004C2221	cmp     edx, 1
004C2224	jg      short 004C2235

Next up is the Hair Cap. A lot of people seem to need this fixed, especially now that the new clients actually have hairs that are over 40000. The issue here is the same issue as above with the math and the conditions expected. When the client registers your Local User, it processes your item's actions and merges the sprite into the Sprite Animator which the WZ will then calculate each position specific to your character's current action which will result in Drawing your character on the screen. When you load all of the item's actions, the client has to parse each ID on your character and then find the assets within your game files. It determines the directories based on the unique type of Item (as Nexon refers to "Type Index" -> ItemID / 10000). The reason why hairs can't go over 39999 is because the directory path for Hair is only located for Hairs if the HairID / 10000 == 3 (meaning no matter what, the first digit is always a 3). In newer clients, Nexon made this into a big switch statement including case 3: case 4: for the hairs. I'm not really sure which version this was initially changed since the v95 PDB still uses a 30k hair cap.

Here's a quick glimpse at the check:
PHP:
if ( v2 == 3 )
{
  v8 = StringPool::GetStringW(&v42, 2300);
  LOBYTE(v45) = 4;
  sub_419192(v8);
  LOBYTE(v45) = 1;
  v5 = &v42;
  goto LABEL_17;
}

The fix? Just as simple as the one above, change two instructions! Now, while v83 has the Item Cap fixed, Hairs will continue to remain a problem for quite a long time, which is why I include the addresses for this version in addition to 62.

v62 Addresses:
Code:
Change:
0054E321	cmp     eax, 3
0054E324	je      0054E3F8 ; if (nID / 10000 == 3)

To:
0054E321	cmp     eax, 4
0054E324	jle     0054E3F8 ; if (nID / 10000 <= 4)

v83 Addresses:
Code:
Change:
005C94FC	cmp     eax, 3
005C94FF	je      005C958D ; if (nID / 10000 != 3)

To:
005C94FC	cmp     eax, 4
005C94FF	jle     005C958D ; if (nID / 10000 > 4)

NOTE: If for whatever reason you wanted Hairs to later cap at 50000 and not 40000, just change that "4" to a "5" and your client will then render hairs up to 59999.

Hope this helps all the low-version WZ Edit servers!

- Eric
 
Last edited:
Initiate Mage
Joined
Aug 28, 2012
Messages
11
Reaction score
7
OMG THANK YOU THANK YOU THANK YOU :love:

praise lord eric :adore:
 
Moderator
Staff member
Moderator
Joined
Jul 30, 2012
Messages
1,102
Reaction score
432
Great job!

However, our .wz editor ran into issues with the fix applied. Basically, equipment above 3000 still can't be equipped besides unisex. So not male and females. I checked twice over the patch and pretty sure I've applied it correctly. To put it short, with the fix applied nothing has changed. Here are the references:

Code:
Change:
0044D7CF	je      short 0044D7DF ; if (nGender != 2)
0044D7D4	je      short 0044D7DF ; if (nItemGender != 2)

To:
0044D7CF	jl      short 0044D7DF ; if (nGender < 2)
0044D7D4	jl      short 0044D7DF ; if (nItemGender < 2)

Change 1:
a280b9f2b5978e5fd76ee6e61df508ab - [v62/v83] [For WZ Edits] Hair/Item Cap Client Fix - RaGEZONE Forums


Change 2:
9cd4b4a23e724914a7874e87fa631e5d - [v62/v83] [For WZ Edits] Hair/Item Cap Client Fix - RaGEZONE Forums


Most likely I am blind somewhere.

EDIT: The item was added in the .xml too.

V0.62.
 

Attachments

You must be registered for see attachments list
Junior Spellweaver
Joined
Aug 5, 2011
Messages
132
Reaction score
10
Lmao. No wonder I couldn't find it!
I was looking for comparisons that involved 40000 or the several cases that return a 0.

Thank you so much for releasing this, it works great for v83!
 
Joined
Jan 18, 2010
Messages
3,109
Reaction score
1,139

Oh nope, it's not you.. Nexon actually has multiple checks for it, and that's only the first function.

Change these two addresses as well:
Code:
004C2221	cmp     edx, 1
004C2224	jg      short 004C2235

Then change this one:
Code:
0044DA9A	jl      short 0044DAA5

That should hopefully do it. There's another one for tooltips, but finding the sub for that in v62 will probably take me ages. Soo hopefully it doesn't require that at all. :p
 
Moderator
Staff member
Moderator
Joined
Jul 30, 2012
Messages
1,102
Reaction score
432

Still nothing unfortunately. Nexon ffs.

Here are the edits I have done:

a5942389ce3ce0f528e99abb6c9f01cb - [v62/v83] [For WZ Edits] Hair/Item Cap Client Fix - RaGEZONE Forums


21d1e3b1365f84dd23b52c6cc1bd92e2 - [v62/v83] [For WZ Edits] Hair/Item Cap Client Fix - RaGEZONE Forums


The ItemID we use is 1053001, which is an overall. Once again no notable changes visible, which means Males can't wear it, Females can't, and unisex can (Gender 2).

EDIT: According to our .wz editor things more broke instead. Females can no longer wear unisex items, where ID 1052000 was used as example.

EDIT 2: This break listed above happened since the newest changes you've just provided. The previous client they still work fine, according to the .wz editor/tester



Problem solved.

0044DA9A jl short 0044DAA5

This need be changed to JGE.

Thank you so much! <3

EDIT 26: It looks like the first patch on OP is not even need to make it work.

0044DA9A JGE short 0044DAA5

Is all that is needed and we can wear items above the 3000 ID.
 

Attachments

You must be registered for see attachments list
Last edited:
Joined
Jan 18, 2010
Messages
3,109
Reaction score
1,139
@Kimberly yep, my mistake, I had it backwards. That instruction makes it continue if the item's returned gender is >= 2 and not validate, which is what we want in this situation. The original instruction should also be changed from JL to JGE as they are both the same conditionals. Though it's surprising that you're able to equip the item with only this function modified.. the client checks if you can equip it, but the one you changed just gets the position where to place it on the character. The first two are to fix the regular client checks, but hey I'm glad it works! :p

EDIT: Also, the very first address doesn't need to be changed at all. I've updated the OP as well now.
 
Last edited:
Experienced Elementalist
Joined
Sep 27, 2016
Messages
217
Reaction score
68
Amazing release, this takes so much stress off my back *-* I was just wondering though, any hints at removing, or at least increasing pet limitations for v83? This is one of the only things left that are still bothering me :/
 
Joined
Jan 18, 2010
Messages
3,109
Reaction score
1,139
Amazing release, this takes so much stress off my back *-* I was just wondering though, any hints at removing, or at least increasing pet limitations for v83? This is one of the only things left that are still bothering me :/

Pet limitations? I don't recall having any limitations on pets in the client, I only knew Odin had pet checks on the server-side. I think the range of pets was 5000000~5001000?

Oh, and what do you mean ring/mobs dolev159? There's no caps on either of those. Special types of rings have formulas but that's about it lol
 
Initiate Mage
Joined
Jun 30, 2017
Messages
22
Reaction score
0
By popular demand I decided to go back and look into the client to see where to remove the very common Item and Hair client caps. For anyone that doesn't already know, in low-version clients (such as 62), the maximum ItemID that will be recognized for items is is something that has a ID less than 3000 (e.g 1003000 for hats won't work in 62). There is also the common Hair cap where your character's hair becomes bald if the HairID is >= 40000.

Starting off with the Item Cap in lower version clients -- why does it happen? Well, Nexon has three genders used for items and this is how they are identified: 0 for Males, 1 for Females, and 2 for None. So with these three genders and how Nexon's items work (using hats again for example), 1000000 is a Male-only item, 1001000 is a Female-only item, and 1002000 is a item for all genders. Let's see the math behind this.

PHP:
if ( nItemID / 1000000 == 1 )
    nItemGender = nItemID / 1000 % 10;
  else
    nItemGender = 2;
  if ( nGender != 2 && nItemGender != 2 && nGender != nItemGender )
    return 0;

So first off, this Gender check is only in place for equipment (ID's that start with 1). The gender is formed from nItemID / 1000 % 10. So, 1000000 / 1000 % 10 = 0 (Male), 1001000 / 1000 % 10 = 1 (Female), and 1002000 / 1000 % 10 = 2 (None). This makes sense, so what about items that are 3, like 1003000+? Well, 1003000 / 1000 % 10 = 3.. It's not 0, 1, or 2. So the only way to wear an item over 1003000 is if you made your character's gender a 3 so that the character's gender is equal to the same gender of the item.

So how can we fix this? Well, we can easily just change the assembly instruction in the client from checking if the Gender is NOT 2 and the Item's Gender is NOT 2, and instead change it so if the Gender is LESS than 2 or if the Item's Gender is LESS than 2 (either 0 or 1 -- Male or Female), THEN we can validate if the character's gender and the item's gender are equal or not.

This is a extremely easy fix! We just need to change two simple instructions from JE to JL (you can do this in OllyDbg). For v62, here is what you have to modify (ignore the comments, they're just to better explain):
Code:
Change:
0044D7D4    je      short 0044D7DF ; if (nItemGender != 2)
0044DA9A    je      short 0044DAA5 ; if (nItemGender != 2)

To:
0044D7D4    jge     short 0044D7DF ; if (nItemGender < 2)
0044DA9A    jge     short 0044DAA5 ; if (nItemGender < 2)

Change:
004C2221    cmp     edx, 2
004C2224    je      short 004C2235

To:
004C2221    cmp     edx, 1
004C2224    jg      short 004C2235

Next up is the Hair Cap. A lot of people seem to need this fixed, especially now that the new clients actually have hairs that are over 40000. The issue here is the same issue as above with the math and the conditions expected. When the client registers your Local User, it processes your item's actions and merges the sprite into the Sprite Animator which the WZ will then calculate each position specific to your character's current action which will result in Drawing your character on the screen. When you load all of the item's actions, the client has to parse each ID on your character and then find the assets within your game files. It determines the directories based on the unique type of Item (as Nexon refers to "Type Index" -> ItemID / 10000). The reason why hairs can't go over 39999 is because the directory path for Hair is only located for Hairs if the HairID / 10000 == 3 (meaning no matter what, the first digit is always a 3). In newer clients, Nexon made this into a big switch statement including case 3: case 4: for the hairs. I'm not really sure which version this was initially changed since the v95 PDB still uses a 30k hair cap.

Here's a quick glimpse at the check:
PHP:
if ( v2 == 3 )
{
  v8 = StringPool::GetStringW(&v42, 2300);
  LOBYTE(v45) = 4;
  sub_419192(v8);
  LOBYTE(v45) = 1;
  v5 = &v42;
  goto LABEL_17;
}

The fix? Just as simple as the one above, change two instructions! Now, while v83 has the Item Cap fixed, Hairs will continue to remain a problem for quite a long time, which is why I include the addresses for this version in addition to 62.

v62 Addresses:
Code:
Change:
0054E321    cmp     eax, 3
0054E324    je      0054E3F8 ; if (nID / 10000 == 3)

To:
0054E321    cmp     eax, 4
0054E324    jle     0054E3F8 ; if (nID / 10000 <= 4)

v83 Addresses:
Code:
Change:
005C94FC    cmp     eax, 3
005C94FF    je      005C958D ; if (nID / 10000 != 3)

To:
005C94FC    cmp     eax, 4
005C94FF    jle     005C958D ; if (nID / 10000 > 4)

NOTE: If for whatever reason you wanted Hairs to later cap at 50000 and not 40000, just change that "4" to a "5" and your client will then render hairs up to 59999.

Hope this helps all the low-version WZ Edit servers!

- Eric

Hey, Im totally new to this software and mine started with 77F10000 i didn't found any 005C94C how to u view that and also how to save after done.
 
Joined
Jan 18, 2010
Messages
3,109
Reaction score
1,139
Hey, Im totally new to this software and mine started with 77F10000 i didn't found any 005C94C how to u view that and also how to save after done.

Make sure you're opening an unpacked localhost in OllyDBG properly. It will analyse the executable and the addresses should appear properly; do not use a hex editor.
 
Initiate Mage
Joined
Jun 30, 2017
Messages
22
Reaction score
0
Make sure you're opening an unpacked localhost in OllyDBG properly. It will analyse the executable and the addresses should appear properly; do not use a hex editor.

I've open a clean localhost v83 and placed it tgt with my game file to open this am i doing right?
olly1 - [v62/v83] [For WZ Edits] Hair/Item Cap Client Fix - RaGEZONE Forums olly - [v62/v83] [For WZ Edits] Hair/Item Cap Client Fix - RaGEZONE Forums
and this is what i could see. Could u guide me more how to find this 005C94FC . Thank you!
 

Attachments

You must be registered for see attachments list
Experienced Elementalist
Joined
Sep 27, 2016
Messages
217
Reaction score
68
Ctrl+G, paste the address, ok
To save:
Right click, copy to executable > all modifications, right click again, save file
 
Junior Spellweaver
Joined
Apr 30, 2012
Messages
100
Reaction score
40
I figure I'd toss everyone else a bone here as thanks for the OP.

You may or may not have noticed this, however, when using avatar dialogues you will disconnect if the first hair ID is not within the 30,000->39,999 range. There is another check within CUtilDlgEx::SetUtilDlgEx_AVATAR (a function called upon by the client within OnAskAvatar) that determines whether or not the ID is for Face, Skin, or Hair. Let's take a look at this in IDA's pseudocode.
Code:
  nAvatarType = aCandidate[0] / 10000;
  if (nAvatarType == 2)
    nType = 0;
  else
    nType = (nAvatarType != 3) + 1;
  this->m_nAvatarType = nType;
Or ASM if you prefer
Code:
cmp     eax, 3
setnz   cl
Simple arithmetic tells you that if the hair id / 10000 is not equal to 3, it will result in a nAvatarType of 2. The assumption here is that 0 is for faces, 1 is for hair, and 2 is... well, for crashing your client. The fix here is simple. We take that nAvatarType != 3 and turn it into nAvatarType == 0. If the nType is a skin (0002000/10000 = 0) it will result in 2, but if it is anything but a face, it will result in the hair type of 1. From this point it's up to you to validate that the ID you're sending is in the wz, or you'll crash anyway.

Here is the array of bytes for the check:
Code:
83 F8 03 0F 95 C1 41 8B

And here is what it should become:
Code:
83 F8 [B]00[/B] 0F [B]94[/B] C1 41 8B
Which translates to
Code:
cmp     eax, 0
sete    cl
 
Last edited:
Joined
Jan 18, 2010
Messages
3,109
Reaction score
1,139
how about face?

If faceid >= 25000 it doesnt work.

What about it doesn't work exactly? In my past v83 servers I usually made my face 29999 and/or 29998 and it worked just fine. Anything below 30000 (start of hair) should work. However, I usually used a command so that only I could access it, so I'm not sure if it would display correctly or not in a NPC window if that's what you mean (though afaik it should).
 
Back
Top