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!

V83 Client - IDA Code Changes

Custom Title Activated
Loyal Member
Joined
Mar 17, 2009
Messages
1,911
Reaction score
538
Hey guys, probably one for Eric but I have a weird one regarding IDA.

Currently on the 'FadeYesNo' you can get two different types of results:

1.

Party Invite
From Sparrow

2.

From Sparrow
Guild Invite

I believe this is handled in (v83: 52065D / CUIFadeYesNo::Draw)

Guild Invite
PHP:
case 8: //guild

 sub_79E805();
      v89 = (int *)sub_406455(&v320, 763); //763 = From %s
      v236 = *((_DWORD *)v2 + 50);
      From_%S = *v89;
      LOBYTE(v333) = 64;
      sub_445B4B((int)&v332, (char *)From_%S, v236);
      LOBYTE(v333) = 1;
      sub_4062DF(&v320);
      sub_402F85(&v255, &pvargSrc);
      LOBYTE(v333) = 65;
      sub_402F85(&v257, &pvargSrc);
      v236 = (signed int)&v255;
      v90 = (int)(v2 + 272);
      From_%S = (int)&v257;
      LOBYTE(v333) = 66;
      v234 = (VARIANTARG *)sub_4284A5(v90);
      v91 = sub_428226(&v332);
      xx_invite = v92;
      v331 = (int *)&xx_invite;
      sub_425ADD(v91);
      LOBYTE(v333) = 66;
      v93 = (_DWORD *)sub_414576(&a2);
      sub_4277AD(v93, 27, 7, xx_invite, (int)v234, (_DWORD *)From_%S, (_DWORD *)v236);
      LOBYTE(v333) = 65;
      v94 = sub_40291D(&v257);
      if ( v94 < 0 )
        sub_A5FDE4(v94);
      LOBYTE(v333) = 1;
      v95 = sub_40291D(&v255);
      if ( v95 < 0 )
        sub_A5FDE4(v95);
      sub_402F85(&v251, &pvargSrc);
      LOBYTE(v333) = 68;
      sub_402F85(&v253, &pvargSrc);
      v236 = (signed int)&v251;
      From_%S = (int)&v253;
      LOBYTE(v333) = 69;
      v234 = (VARIANTARG *)sub_4284A5(v90);
      xx_invite = v96;
      v331 = (int *)&xx_invite;
      sub_79E805();
      sub_406292((int)&xx_invite, 768); //768 = Guild Invite
      LOBYTE(v333) = 69;
      v97 = (_DWORD *)sub_414576(&a2);
      sub_4277AD(v97, 27, 20, xx_invite, (int)v234, (_DWORD *)From_%S, (_DWORD *)v236);
      LOBYTE(v333) = 68;
      v98 = sub_40291D(&v253);
      if ( v98 < 0 )
        sub_A5FDE4(v98);
      LOBYTE(v333) = 1;
      v14 = &v251;
      goto LABEL_244;

All cases seem to go to the same function (sub_4277AD) which is confusing as to why I'm getting varied results.

I was modifying some values around, but my end result was:

Guild Invite
From %s - couldn't get the variable to pick up the username.

Does anyone have any ideas or suggestions? :D

It's not urgent, just having some fun with client editing :D

Cheers,
Daniel
 
Last edited:
Newbie Spellweaver
Joined
Jan 31, 2019
Messages
50
Reaction score
18
sub_4277AD is IWzCanvas::DrawTextA, which is used all over the client to draw text (hundreds of xrefs). Full function signature:

unsigned int __thiscall IWzCanvas::DrawTextA(IWzCanvas *this, int nLeft, int nTop, Ztl_bstr_t sText, IWzFont *pFont, Ztl_variant_t *vAlpha, Ztl_variant_t *vTabOrg)

nTop and sText are the parameters relevant to you

For guild invitations (case 8), you can see two calls to this function. The first has nLeft = 27, nTop = 7 and sText = "from %s" (%s is already replaced with the ign at this point). Then drawtext is called again with nLeft = 27, nTop = 20, and sText = "Guild Invite" (from stringpool). nLeft and nTop correspond to x and y coordinates (relative to the origin of IWzCanvas object the text is drawn on); y increases as you go down, which explains why the "Guild Invite" text is below the "From %s".

For party invites, the two calls to drawtext are: nLeft = 27, nTop = 7, sText = "Party invite"; nLeft = 27, nTop = 20, sText = "From %s", so the "Party invite" text is above.

You can just change the nTop values for each of these drawtext calls if you want to rearrange the lines of text, i.e. make nTop = 7 for the first drawtext and 20 for the second one.

 
Upvote 0
Custom Title Activated
Loyal Member
Joined
Mar 17, 2009
Messages
1,911
Reaction score
538
Interesting, thank you Feras. Maybe it’s just my lack of understanding of IDA but it seems to be a strange way to do it. I can see in both calls to “ sub_4277AD” it contains the 2 parameters (guild invite and username), but nothing in the function to say use one or the other. I’ll have to check it out further tonight, thank you again :)
 
Upvote 0
Newbie Spellweaver
Joined
Jan 31, 2019
Messages
50
Reaction score
18
but nothing in the function to say use one or the other

One or the other what? Not sure what you're referring to.

sub_4277AD (IWzCanvas::DrawTextA) is only used to show text on the screen, nothing else. Its parameters are only related to the text itself, the positioning, and some other font-specific values. I'll write some pseudocode that's more readable, ignoring the stuff that doesn't matter to us:

Code:
//client receives a guild invite from Sparrow
case 8:
String senderIgn = this->senderIgn; //"Sparrow"
String ignString = String.format("From %s", senderIgn); //== "From Sparrow"
drawText(27, 7, ignString); //writes "From Sparrow" at coordinates (27, 7)
String typeOfInvite = "Guild invite";
drawText(27, 20, typeOfInvite); //writes "Guild invite" at coordinates (27, 20), 13 pixels below the previous drawtext

Drawing text on the FadeWnd seems to be the only thing that's done in CUIFadeYesNo::Draw (and calling methods of the base CWnd class). If you're wondering about the different UI used for each type of invite, that's handled in other CUIFadeYesNo methods:

UEivOwS - V83 Client - IDA Code Changes - RaGEZONE Forums


Easy to find in any version by following the associated InPacket handlers
 

Attachments

You must be registered for see attachments list
Upvote 0
Custom Title Activated
Loyal Member
Joined
Mar 17, 2009
Messages
1,911
Reaction score
538
I shouldn't make posts straight out of bed in the morning :D

What I meant was, if you look at these 2 lines

PHP:
sub_4277AD(v93, 27, 7, xx_invite, (int)v234, (_DWORD *)From_%S, (_DWORD *)v236);
sub_4277AD(v97, 27, 20, xx_invite, (int)v234, (_DWORD *)From_%S, (_DWORD *)v236);

While the co-ordinates change, both contain the "Username" and "Guild Invite" variables as parameters. But I need to look deeper at the subroutine itself. It's not important, it's just what caused my confusion.

Thank you for the help thus far though, very informative.
 
Upvote 0
Newbie Spellweaver
Joined
Jan 31, 2019
Messages
50
Reaction score
18
They use the same variable but the variables get updated in between those calls.
There's only one string parameter, which you have named as xx_invite. In that first call, xx_invite is "From whoever", but at some point before that second call it becomes "Guild invite".

The variable you named From_%S is used to store "From %s" initially, but gets reassigned to something else later (see this line: From_%S = (int)&v253;). When reading pseudocode, a variable does not necessarily have one singular purpose, because in the program itself that variable is just a location on the stack (or a register), and the compiler has optimized the program to reuse that location for other purposes when possible. So at first, your From_%S variable actually did contain "From %s", but later on it holds some other data, which isn't even a string.
 
Upvote 0
Back
Top