Developer:Opcodes
- Last edited 3 years ago by Vlash Nytefall
EQ2Emulator -- Opcodes Explained
An Opcode (operation code) are instructions sent via network packets between two running applications, be it server->server, server->client or client->server. These packets contain special instructions as to what function they are expected to perform, and/or what data to return.
Basic example of an opcode transaction between a server and a client:
Server needs to know a players current position, so it may update that position to all over players in the area
Server asks Client "Hey, what is player_1's x,y,z,heading by sending an Opcode to the client
Client receives the specific opcode, and knows "Server wants to know where player_1 is"
Client then reports back to server, in another opcode packet "Player_1 is {right here}"
Server can then tell the other players in the area the whereabouts of player_1
This is the non-technical process. To get a little more technical, I will demonstrate
For EQ2Emulator, our ```opcodes``` are unique to different client versions in most cases, so our opcodes table is laid out as follows (using a single opcode as an example):
Version Ranges - Explained
When a client attempts to connect to a LoginServer, the client sends it's internal data version to the LoginServer. If the current data version is unknown to Login, the connection is denied. Otherwise, the client is allowed to log in. This is determined by each opcode having a minimum and maximum version range it is valid for. If a client's data version falls outside of a particular opcode's range, the data in a packet could be misinterpreted, and in all likelihood the result is a crashing client (because the client gets data it does not expect).
A basic example of this:
version_range1 version_range2 name opcode
0 0 OP_ZoneInfoMsg 31
839 844 OP_ZoneInfoMsg 31
908 927 OP_ZoneInfoMsg 31
1008 1011 OP_ZoneInfoMsg 31
1045 1046 OP_ZoneInfoMsg 31
1096 1096 OP_ZoneInfoMsg 32
1119 1123 OP_ZoneInfoMsg 33
1142 1147 OP_ZoneInfoMsg 33
Let's say my client's data version is 1096 (DoV client). I connect to Login, because 1096 - 1096 is valid, I am allowed to log in and create a character, then enter a world and play.
However, if my client's data version was 1072 for example, I would be denied logging in through the LoginServer due to an incompatible version detected - and I might see a message in the client that I need to patch. For the sake of EQ2Emulator, this merely means your Everquest2.exe is not supported, and you must acquire one that is before you can connect.
The second example of version ranges is that during development of a current client where many opcodes and their values are unknown (in our case, DoV), because the 1096 range exists, you may log into the world just fine... but then find that the data on the screen is all wrong, or your client keeps crashing. In this example, the client requests opcode 31 (OP_ZoneInfoMsg) when a player logs in, but since opcode 31 is still set to OP_ExpectClientAsCharacterRequest (because all opcodes moved +1 in 1096-1096 from what they were in 1045-1046), the world sends back what IT knows is opcode 31, the client receives the incorrect data, tries to shove it into it's stream, and crashes.
Why So Many?
This rather ingenious method of utilizing opcode "ranges" helps EQ2Emulator support multiple clients with the same core executable, without limitation. The only limit is on how much time the EQ2Emu developers have to identify and adjust opcode (and Packet Structure data) before yet another data stream change is made by SOE to their Everquest2.exe.
(more to come)