Hello,
The past few days I have been looking over the forum and getting addicted to ROTMG and I've decided to work on a custom client. I've found quite a bit of resources, but the one thing I'm stuck on is the network protocol; I've found some resources but I cannot replicate the data given
Here's the protocol reverse:
Code:
(C) 2012 Anoos: 3
Reverse engineering the protocol the game Realm Of The Mad God. / Build ver. 123 (?) /
Server Address: ec2-176-34-240-11.eu-est-1.compute.amazonaws.com (176.34.240.11) / EuNorth /
The addresses of all servers (on May 8, 2012, ver. 123.0.0)
+ --------------- + --------------- + ----------------- ------------------------------------------ +
| Name | IP | hostname |
| --------------- + ----------------- + --------------- ------------------------------------------ +
| USWest | 50.18.113.133 | ec2-50-18-113-133.us-west-1.compute.amazonaws.com |
| USMidWest | 107.22.218.252 | ec2-107-22-218-252.compute-1.amazonaws.com |
| EUWest | 46.137.187.86 | ec2-46-137-187-86.eu-west-1.compute.amazonaws.com |
| USEast | 184.72.218.199 | ec2-184-72-218-199.compute-1.amazonaws.com |
| AsiaSouthEast | 46.137.247.5 | ec2-46-137-247-5.ap-southeast-1.compute.amazonaws.com |
| USSouth | 107.22.231.55 | ec2-107-22-231-55.compute-1.amazonaws.com |
| USSouthWest | 50.18.176.194 | ec2-50-18-176-194.us-west-1.compute.amazonaws.com |
| EUEast | 46.51.176.123 | ec2-46-51-176-123.eu-west-1.compute.amazonaws.com |
| EUNorth | 176.34.240.11 | ec2-176-34-240-11.eu-west-1.compute.amazonaws.com |
| EUSouthWest | 176.34.240.126 | ec2-176-34-240-126.eu-west-1.compute.amazonaws.com |
| EUWest2 | 46.137.143.87 | ec2-46-137-143-87.eu-west-1.compute.amazonaws.com |
| USEast3 | 50.19.47.160 | ec2-50-19-47-160.compute-1.amazonaws.com |
| USWest2 | 184.169.130.44 | ec2-184-169-130-44.us-west-1.compute.amazonaws.com |
| USMidWest2 | 174.129.56.145 | ec2-174-129-56-145.compute-1.amazonaws.com |
| USEast2 | 23.21.243.164 | ec2-23-21-243-164.compute-1.amazonaws.com |
| USNorthWest | 184.169.131.108 | ec2-184-169-131-108.us-west-1.compute.amazonaws.com |
| USSouth2 | 107.20.55.255 | ec2-107-20-55-255.compute-1.amazonaws.com |
| AsiaEast | 46.137.218.95 | ec2-46-137-218-95.ap-southeast-1.compute.amazonaws.com |
| USSouth3 | 204.236.195.161 | ec2-204-236-195-161.compute-1.amazonaws.com |
| EUSouth | 176.34.71.225 | ec2-176-34-71-225.eu-west-1.compute.amazonaws.com |
| EUNorth2 | 46.137.38.91 | ec2-46-137-38-91.eu-west-1.compute.amazonaws.com |
+ --------------- + --------------- + ----------------- ------------------------------------------ +
The client requests a file from the server crossdomain.xml (http://www.adobe.com/devnet/articles/crossdomain_policy_file_spec.html)
Information on packages == ==
The format of the package:
[LENGTH] <ID> (DETAILS)
| 01020304 | 05 | 0xDATA |
awwa
Presentation:
int length # length includes 5 byte header (4 bytes in length, and one byte for the ID), hence the length of the data
*******************# == Length-5
ubyte id # ID package
Vector <byte> data # Data is encrypted RC4, uses two keys:
*******************# 311f80691451c71b09a13a2a6e -> Outgoing Data
*******************# 72c5583cafb6818995cbd74b80 <- Incoming stream
Package List ========= =======================
== Presented in order of how the developers ==
# Srv - server sends a packet
# Cli - client sends a packet
#?? - Purpose of the package is unknown
------- ------------ Format
ID NAME
type field
type2 field2
---------------------------
================================================
0 FAILURE # Srv, an error message
int errorID # ID errors
String errorDescription # description of the error
59 CREATE_SUCCESS # Srv, object creation was successful
int objectID # ID of the object
int charID # ID Team
49 CREATE # Cli, a game object
short objectType # ID object type
20 PLAYERSHOO T # Cli, shoot
int timestamp # Time shot
int bulletID # ID texture bullet
short containerType #???
Point startingPos # coordinates x, y the shooting
float angle # degree angle shot in the plane xOy
61 MOVE # Cli, player movement
int tickID # ID game timer tick (anti-spidhak?)
int time # Timestamp start of motion (anti-spidhak?)
Point newPosition # coordinates x, y destination
short recordsLength #???
Vector records #???
39 PLAYERTEXT # Cli, send a chat message
String message # UTF-8 string posts
7 TEXT # Srv, chat message
String name # name of the message sender (player or bot quest)
int objectID # ID of the object (?)
int numStars # The number of asterisks wound (by a class quests) player, who wrote the message
ubyte bubbleTime # time, how much it will hold a bubble message on the player (in seconds?)
String recipient # Name of the message recipient (for personal messages)
String text # Message
String cleanText # (formatted?) Text messages
21 SHOOT (_-u5, _-FL) # Srv, shot
ubyte bulletID # ID texture shot
int ownerID # ID "owner" of the shot
short containerType #???
Point startingPos # initial coordinates x, y shots
float angle # degree angle shot in the plane xOy
short damage # damage that will cause the bullet when hit
31 SHOOT # Srv, handling multiple shots at once
ubyte bulletID # ID texture shot
int ownerID # ID "owner" of the shot
short containerType #???
Point startingPos # initial coordinates x, y shots
float angle # degree angle shot in the plane xOy
short damage # damage that will cause the bullet when hit
# - Following is the list of shots, if there are bytes, then:
# Every next byte is the number of shots
# Next to him is a float angle that will be fired
Byte # If not, then the number of shots = 1, and angle = 0
38 DAMAGE # Srv, notification of the damage caused and the effects (blindness, weakness, slow, etc.)
int targetID # ID purposes
ubyte length # length of the list of effects
Vector effects # byte array, ID effects (blind, slow)
int damageAmount # How much damage inflicted
bool kill # Killed?
ubyte bulletID # ID bullet
int objectID # ID of the object (?)
5 UPDATE # Srv, renewal of the world (new chunks (tiles), objects (mobs players?) Drops (bags))
short length_tiles # list length tiles
Vector <_-MV> tiles # The block list for updates (you need to understand the structure of the object block)
short length_newObjs # length of the list newObjs
Vector <_-Oe> newObjs # list of objects to be updated (----- ^)
short drops_length # length of the list drops
Vector <int> drops # List of drops (id drops?)
14??
63 NOTIFICATI ON # Srv, notification
int objectID
String text # Text Alerts
int color # text color
57 NEW_TICK # Srv,?
int tickID
int tickTime # unix timestamp (?)
short length # Length of the following list
Vector <ObjectStatusData> statuses # List status (?)
65 INVSWAP # Cli, a permutation of items in the inventory
int time # timestamp permutation (for syncing?)
Point position # Location (coordinates x, y) permutation (for drops?)
Slot slotObject1 # source object slots (slots necessary to identify the data structure Slot)
Slot slotObject2 # The target slot (- ^)
58 USEITEM # Cli, use things (elixir, egg)
int time # timestamp of use (for timing?)
Slot slotObject # object slot
Point itemUsePos # The place where the object is used (for use pots at once out of the bag?)
77 SHOW_EFFECT # Srv, to show the effect of
ubyte effectType # type of effect (0-15)
int targetObjectID # ID purposes
Point pos1 #???
Point pos2 #???
int color # Color effect (?)
17 HELLO # Cli, login to the server package
String buildVersion # version Build # 123
Int gameID # ID game (?)
String guid # Login
String password # Password
String secret # secret
int keyTime #???
short keyLength # Key length (?)
Vector <byte> key # key
int? length # length of the array
An array of String utf8bytes # utf-8 bytes
# Login, password, and secret encrypted with the public key PEM.RSA
# The encrypted data is encoded Base64
# RSA public key is available and within the swf-file
# ----- BEGIN PUBLIC KEY ----- \ n
50 GOTO # Srv, pemereschenie object
int objectID # ID moving object
Point pos # kordinaty move
11 INVDROP # Cli, drop a thing of the slot
Slot slotObject # Data from the slot
75 INVRESULT # Srv, the result of actions with the inventory
int result # result code
4 RECONNECT # Srv, reconnect to the (different) server
String name
String host
int port
int gameID
int keyTime
short keyLength
Vector <byte> key
41 PING # Srv
int serial # serial number ping
27 PONG # Cli
int serial # serial number of the processing of PING, this package should be sent immediately after the PING
37 MAPINFO # Srv, the card information
int width # Map width (at the nexus 255)
int height # length card (at the nexus 255)
String name # name card (Nexus)
uint fp #???
int background # code background cards (2 - blue by default)
bool allowplayertp # Allow teleport players to each other (eg smoking in the castle Oryx)
34 LOAD # Cli, download cara
int charID # ID chara
3 PIC # Srv, loading images (bitmaps)
int height
int width
Vector <byte> byteArray # Data file picture size: (height * width) * 4
28 SETCONDITI ON # Cli, installation conditions (?)
byte conditionEffect # ID effect
float conditionDuration # The duration of the effect (second?)
23 TELEPORT # Cli, a request to teleport to the object
int objectID
45 USEPORTAL # Cli, use the portal (or the hatch in the dungeon)
int objectID
47 DEATH # Srv, notification of death
int accountID
int charID
String killedBy
68 BUY # Cli, a request for purchase (from a shop in Nexus)
int objectID
10 BUYRESULT # Srv, the result of purchase
int result # result code
String resultString # Message (an error or a successful purchase)
62 AOE # Srv, AOE (Area of Effect) damage as a bomb jellyfish.
Point position # Position of the center
float radius # Radius effect
ushort damage # Damage Done
ushort origType # Damage type (?) probably bombs, ladders, etc. Khilki
19 GROUNDDAMA GE # Cli, drawing earth damage (blocks)
int time
Point position
18 PLAYERHIT # Cli, getting into the player
byte bulletID
int objectID
24 ENEMYHIT # Cli, hit the enemy
int time
byte bulletID
int targetID
bool kill
26 AOEACK # Cli
int time
Point position
64 SHOOTACK # Cli
int time
6 OTHERHIT # Cli
int time
byte bulletID
int objectID
int targetID
16 SQUAREHIT # Cli
int time
byte bulletID
int targetID
51 GOTOACK # Cli
int time
55 EDITACCOUN TLIST # Cli
int accountListID
bool add
int objectID
66 ACCOUNTLIS T # Srv
int id
short listLength
Vector <int> accountIDs
74 QUESTOBJID # Srv
int objectID
40 CHOOSENAME # Cli, name change
String name
67 NAMERESULT # Srv, the result of the name change
bool success
String errorText
76 CREATEGUIL D # Cli, creating a guild (clan)
String name # Name Clan
69 CREATEGUIL DRESULT # Srv, the result of making the guild (clan)
bool success
String errorText
8 GUILDREMOVE # Cli, removal of the guild (clan)
String name
22 GUILDINVIT E # Cli, invite to the guild
String name # name of the invited player
53 ALLYSHOOT # Srv, shots allies (other players)
ubyte bulletID
int ownerID
short containerType
float angle
48 REQUESTTRA DE # Cli, a request to trade a player
String name
36 TRADEREQUE STED # Srv, alert the player that want to trade with him
String name
9 TRADESTART # Srv, start trading
short myItemsLength # length of the list of things that I'm willing to trade
Vector <Slot> myItems # The list of things
String yourName # Name (whose?)
short yourItemsLength # length of the list of things
Vector <Slot> yourItems # The list of things
12 CHANGETRAD E # Cli, change trade, boolean list of selected slots
short offerLength # length of the list of marks
Vector <bool> offer # List marks true - a slot is selected, false - not selected
44 TRADECHANG ED # Srv, the player changed his proposal
short offerLength # length of the list of marks slots
Vector <bool> offer # List marks slots
15 ACCEPTTRAD E # Cli, to take trade
short myOfferLength
Vector <Slot> myOffer
short yourOfferLength
Vector <Slot> yourOffer
25 CANCELTRAD E # Cli, cancel trade
# The data is not passed
42 TRADEDONE # Srv, trade completed
int code # result code
String desription # Description
1 TRADEACCEPTED # Srv, trade adopted
short myOfferLength
Vector <Slot> myOffer
short yourOfferLength
Vector <Slot> yourOffer
46 CLIENTSTAT # Srv, stats Client Team
String name # Name stat
int value # value
30 CHECKCREDI TS # Cli, Captions, like pressing a button on the main menu Credits
# The data is not passed
33 ESCAPE # Cli, teleport to the Nexus
# The data is not passed
56 FILE # Srv, download the file from the server (?)
String name
int filesize
# The following array of 8-byte UTF-size filesize
35 INVITEDTOG UILD # Srv, warning that the player client was invited to the guild (clan)
int objectID # ID Guild
int charID # ID players invited to the guild
52 JOINGUILD # Cli, to accept the invitation to the guild
String guildName # Name Guild
60 CHANGEGUIL DRANK # Cli, change the rank player in the guild (guild for admins)
String name # Player Name
int guildRank # New Rank
13 PLAYSOUND # Srv, play a sound
int ownerID
ubyte soundID
I also checked it with sources of other custom clients that have been released and they have the same information, however when packet sniffing to verify the network information, the data seems incorrect
For example:
Packet sniffed:
cli->srv
Code:
00 00 00 0D 10 71 11 89 1D 08 50 E8 DA
Using the information above:
00 00 00 0D = 13 (there is 13 bytes in the above packet, but only 8 in the data)
10 = 16 (Square Hit)
71 11 89 1D 08 50 E8 DA decrypted = B3 06 5C 90 6F 55 F6 32
given the information the structure for square hits should contain an integer, a byte, and an integer, however there is only 8 bytes of data available
Another example:
cli->srv
Code:
00 00 00 23 07 5B AD 0E 0D BC C8 41 72 99 EA 77 7B FF B7 07 D1 B5 56 CC C4 3F F0 7E 5E 97 B8 FA 95 4A FC
Len: 35 (correct, but length of entire packet, not data)
ID: 7 (TEXT)
so first off TEXT commands are only srv->cli, however this was recorded cli->srv, but let's ignore that for now
DATA (decrypted):
Code:
99 BA DB 80 DB CD 5F 9A 99 67 58 D9 2C 5C 0B 70 D9 2A 41 F3 5E C6 1B BF 41 59 5D AF 4B 79
so for that there's no NUL terminator for the strings and there's no series of characters that makes any sense
so then I thought maybe the ID is included in the encryption, so adding to that starts off with a 106 as the ID which doesn't exist
I'm not exactly sure what is wrong, I was looking through the source of this:
http://www.mpgh.net/forum/655-realm-...er-please.html
and from what I can tell it works the same way the protocol would suggest:
Code:
[File: ./rotmg java proxy/rotmgclient/src/client/base/GameConnection.java]
[Lines: 173-183]
private void writePacket(RWable rw) throws IOException {
if (!dontPrin*****ntains(rw.getId()))
System.out.println(rw);
ByteArrayDataOutput bado = new ByteArrayDataOutput(100000);
rw.writeToOutput(bado);
byte[] encr = cipher_fromServer.rc4(bado.getArray());
out.writeInt(encr.length + 5);
out.writeByte(rw.getId());
out.write(encr);
out.flush();
}
basically it gets the packet data, encrypts the data with rc4 and outputs to a new array (hmm 100,000 bytes seems a bit big ^^), writes the length of the encrypted data, writes the ID of the packet, and then writes the encrypted data, then flushes the stream, however sniffing packet data from the client (currently hexed modselector from
here for simplicity) doesn't have information that matches with the protocol
After looking through the packets, the length and IDs are all valid (where length is the length of the packet, not the encrypted data), however the DATA information doesn't match with the protocol
I'm kinda stuck on this and can't continue until this is resolved, any help would be appreciated
TL;DR:
Sniffer data doesn't match up with the reversed protocol information