Using a very old game client?

General support forum. If you require assistance and your problem doesnt fall in any of the other categories, this is the forum for you!

Moderator: Team Members

Forum rules
READ THE FORUM STICKY THREADS BEFORE ASKING FOR HELP!
Most information can be found there, and if not, the posts will help you determine the information required to get assistance from the development team.
Incomplete Help Requests will be locked or deleted.
User avatar
ilythor
Retired
Posts: 436
Joined: Sun Oct 14, 2007 3:44 am
EQ2Emu Server: TessEq2
Location: Australia, mate!
Contact:

Re: Using a very old game client?

Post by ilythor » Fri Nov 05, 2010 11:57 pm

Haha, thanks Sylaei for that explanation. I had a rough idea but now it makes sense. I think... :lol:
"Everytime you pull the trigger in space, you will ruin someone's day, somewhere, and eventually, some time."

User avatar
John Adams
Retired
Posts: 9684
Joined: Thu Jul 26, 2007 6:27 am
EQ2Emu Server: EQ2Emulator Test Center
Characters: John
Location: Arizona
Contact:

Re: Using a very old game client?

Post by John Adams » Sat Nov 06, 2010 3:21 pm

I'm in the middle of a ton of crap at home, but I'll try to sum up as best I can from what I know/remember.

Sylaei hit it right on, with how the client/server communicate. That's exactly what's going on. EQ2Emu is different than most others though, because LethalEncounter came up with an ingenious way for us to support multiple clients in the same code. These are done through "Structs and Opcodes lists", those xml files you see in the eq2world directory, and the opcodes table in the database.

The "Struct" (for World, Spawns and Items) is an xml data file that simple says "for opcode ____, client version ____, the data in this packet is <this type> and is <this long>.

Example:

Code: Select all

<Struct Name="WS_SpawnStruct" ClientVersion="1">
<Data ElementName="position" Substruct="Substruct_SpawnPositionStruct" Size="1" />
<Data ElementName="vis" Substruct="Substruct_SpawnVisualizationInfoStruct" Size="1" />
<Data ElementName="info" Substruct="Substruct_SpawnInfoStruct" Size="1" />
</Struct>
WS_SpawnStruct is the entry point for determining how to decipher the incoming packets relating to Spawns. The example is for client verion 1 (which merely means this is the struct in the very first client ever used to start EQ2Emu), and you see there are 3 substructs - position, vis and info. Sorry to start out with a confusing one, but this is the only one I actually (almost) understand ;) Substruct= tells the server to go find yet another struct by that name/client version and build the entire packet structure.

Code: Select all

<Struct Name="Substruct_SpawnPositionStruct" ClientVersion="1" >
<Data ElementName="pos_grid_id" Type="int32" Size="1" />
<Data ElementName="pos_x" Type="float" Size="1" />
.
.
etc...
then add to that:

Code: Select all

<Struct Name="Substruct_SpawnVisualizationInfoStruct" ClientVersion="1">
<Data ElementName="arrow_color" Type="int8" Size="1" />
<Data ElementName="locked_no_loot" Type="int8" Size="1" />
.
.
etc...
and finally:

Code: Select all

<Struct Name="Substruct_SpawnInfoStruct" ClientVersion="1" >
<Data ElementName="hp_remaining" Type="int8" Size="1" />
<Data ElementName="unknown2a" Type="int8" Size="3" />
<Data ElementName="power_percent" Type="int8" Size="1" />
.
.
etc...
In the end, the server has this huge amount of data elements, in a specific order, of specific types and lengths, and now knows that when client version "1" logs in, that client will understand the data from the server sent in that structure. Make sense? (there is of course a static header/footer added to the beginning and end - you will find this info in SpawnStructs.xml)

As for what this all means to you, it means when the world starts, it connects to a LoginServer. The LoginServer allows clients to connect to itself, where it identifies the version # of the client (client version 1, 863, 945, 1045 etc). The client tells Login what version it is. Login then looks in it's own list of supported clients (version_range1 through version_range2 in the `opcodes` table) and if the client matches one of those opcode ranges, Login allows the client through.

The client then picks what server it wants to log into - and though the LoginServer might have allowed the client to log in, if the server receiving the client data does not support client version 1045, then the client gets rejected.

If all the stars are aligned, and login+server allow the client entry, the client logs into a zone - and the zone startup wants to push Spawn data to the client - and it does so by looking at the client's version, building the list of recognizable opcodes based on version_rangeX, and then pushes the Spawn data it knows about to the client - and the client can see a spawn's position, visual appearance, and info (those 3 elements from above).

In order to get a very old client to work, you would probably need to disassemble the client and tear apart every opcode and build a version_rangeX from scratch. No small task, or we would have done it by now. Plus, not all of us have original clients ;) (though I do!)

How WE derive current client structs, is to collect data from EQ2 Live, open the file in an editor, and start comparing, byte by byte, whether something has changed or not (usually we only do that when something we know is broken or changed). Once we see SOE slipped a new INT32 in, we build a new struct xml to handle that specific client version #. If SOE changed opcodes (which they do all the time), we find out what the old packet was, and look for the same data and see what the new opcode is (usually opcode + 2 it seems in most cases and only for specific sets of functions - spawns, items, spells, achievements, etc) and build new opcode ranges for the client version in the `opcodes` table.

Almost sounds like I know what I'm talking about, huh? Zcoretri could answer better, he's the opcodes/structs guru around here.

I hope this is more helpful than my previous response ;) Good luck.
John Adams
EQ2Emulator - Project Ghost
"Everything should work now, except the stuff that doesn't" ~Xinux

User avatar
John Adams
Retired
Posts: 9684
Joined: Thu Jul 26, 2007 6:27 am
EQ2Emu Server: EQ2Emulator Test Center
Characters: John
Location: Arizona
Contact:

Re: Using a very old game client?

Post by John Adams » Sat Nov 06, 2010 3:28 pm

Let me add, the client actually has 2 versions; the Client Version is the one you see in the title bar when you launch the client - ie., 6128L or whatever.

The "data version" is the one LoginServer and World care about, and you cannot see that from outside the client - you can only see it by running the collector or wireshark and tapping into the stream to see what version the client is sending during login attempts.

Sorry for the confusion.

User avatar
Sylaei
Retired
Posts: 57
Joined: Mon Jul 05, 2010 1:40 pm

Re: Using a very old game client?

Post by Sylaei » Sat Nov 06, 2010 8:14 pm

Thanks John,
Lots of good info in that post, I didn't understand how that part worked until now.

User avatar
ilythor
Retired
Posts: 436
Joined: Sun Oct 14, 2007 3:44 am
EQ2Emu Server: TessEq2
Location: Australia, mate!
Contact:

Re: Using a very old game client?

Post by ilythor » Sat Nov 06, 2010 8:25 pm

I think I finally got used to how JA writes!

In all honesty this solution sounds incredibly ingenious, perhaps laborious, but none the less ingenious.
"Everytime you pull the trigger in space, you will ruin someone's day, somewhere, and eventually, some time."

User avatar
Chrisworld
Posts: 89
Joined: Thu Jul 29, 2010 9:51 pm
Location: Vineland, NJ

Re: Using a very old game client?

Post by Chrisworld » Sun Nov 07, 2010 6:55 pm

Well then, wow! Thanks for the info, John. I've finally got a basic understanding of how it all works. All this time i've been toying around with opcodes and client files to try to get that pesky TSO box to run with the latest Server Pack, to no avail. Now I know why, haha. I was way off. Well, at least, on top of knowing a little more about it, I also know I will never get it to work myself, so I can finally rest...lol. The Server pack 1.0 + my TSO box is more or less a gigantic Guild Hall now.

I do still have Client 6122 (Will of a Tyrant GU). It can no longer play music (for the life of me I DON'T know why, no files have changed) and It works perfectly with 1.2 & the emu project servers. I figured out that it's really not damaged aside from the music issue. That's about all I have up to this point related to project compatibility. Client 6170 does not work with the project yet, so that's something I'm going to hold onto for future use hopefully, haha.

Anyways, thanks again for that post.

Chris

User avatar
Zcoretri
Team Member
Posts: 1642
Joined: Fri Jul 27, 2007 12:55 pm
Location: SoCal

Re: Using a very old game client?

Post by Zcoretri » Sun Nov 07, 2010 11:34 pm

How WE derive current client structs, is to collect data from EQ2 Live, open the file in an editor, and start comparing, byte by byte, whether something has changed or not (usually we only do that when something we know is broken or changed). Once we see SOE slipped a new INT32 in, we build a new struct xml to handle that specific client version #. If SOE changed opcodes (which they do all the time), we find out what the old packet was, and look for the same data and see what the new opcode is (usually opcode + 2 it seems in most cases and only for specific sets of functions - spawns, items, spells, achievements, etc) and build new opcode ranges for the client version in the `opcodes` table.

Almost sounds like I know what I'm talking about, huh? Zcoretri could answer better, he's the opcodes/structs guru around here.

I hope this is more helpful than my previous response ;) Good luck.
Not much I can add there, John pretty much covered how it works. If there any specific questions, I may be able to answer them.

Post Reply

Who is online

Users browsing this forum: No registered users and 1 guest