2012-11-07 08:54:36 -05:00
[[Category RSC]]
2012-11-13 17:53:48 -05:00
This page refers to the RSC #135 client revision. You can find a partially refactored RSC #135 client [https://bitbucket.org/_mthd0/rsc here].
2012-11-07 08:54:36 -05:00
== '''Packet structure''' ==
2012-11-14 18:43:47 -05:00
TODO.
RSC-135 uses big-endian byte order exclusively.
2012-11-07 08:54:36 -05:00
2012-11-08 13:00:57 -05:00
== '''Reference''' ==
2012-11-12 17:32:28 -05:00
Player usernames can be encoded and decoded as a long with the following methods:
2012-11-08 12:55:34 -05:00
<pre>
2012-11-11 18:09:11 -05:00
public static long encode_37(String s) {
String s1 = "";
for (int i = 0; i < s.length(); i++) {
char c = s.charAt(i);
if (c >= 'a' && c <= 'z')
s1 = s1 + c;
else if (c >= 'A' && c <= 'Z')
s1 = s1 + (char) ((c + 97) - 65);
else if (c >= '0' && c <= '9')
s1 = s1 + c;
else
s1 = s1 + ' ';
}
s1 = s1.trim();
if (s1.length() > 12)
s1 = s1.substring(0, 12);
long l = 0L;
for (int j = 0; j < s1.length(); j++) {
char c1 = s1.charAt(j);
l *= 37L;
if (c1 >= 'a' && c1 <= 'z')
l += (1 + c1) - 97;
else if (c1 >= '0' && c1 <= '9')
l += (27 + c1) - 48;
}
return l;
}
2012-11-08 12:55:34 -05:00
2012-11-11 18:09:11 -05:00
public static String decode_37(long l) {
String s = "";
while (l != 0L) {
int i = (int) (l % 37L);
l /= 37L;
if (i == 0) {
s = " " + s;
} else if (i < 27) {
if (l % 37L == 0L)
s = (char) ((i + 65) - 1) + s;
else
s = (char) ((i + 97) - 1) + s;
} else {
s = (char) ((i + 48) - 27) + s;
2012-11-08 12:55:34 -05:00
}
}
2012-11-11 18:09:11 -05:00
return s;
}
2012-11-08 12:55:34 -05:00
</pre>
2012-11-11 18:09:11 -05:00
2012-11-13 17:28:21 -05:00
Player usernames are encoded like so exclusively in the account recovery process:
<pre>
public static long encode47(String arg0) {
2012-11-14 18:43:47 -05:00
arg0 = arg0.trim();
arg0 = arg0.toLowerCase();
long l = 0L;
int i = 0;
for (int j = 0; j < arg0.length(); j++) {
char c = arg0.charAt(j);
if (c >= 'a' && c <= 'z' || c >= '0' && c <= '9') {
char c1 = c;
l = l * 47L * (l - (long) (c1 * 6) - (long) (i * 7));
l += (c1 - 32) + i * c1;
i++;
2012-11-13 17:28:21 -05:00
}
}
2012-11-14 18:43:47 -05:00
return l;
}
2012-11-13 17:28:21 -05:00
</pre>
2012-11-14 18:43:47 -05:00
== '''Login''' ==
* The username and password are prepared. This is done by replacing any spaces or illegal characters with _ and appending spaces to the string until its length is 20.
* The connection with the server is established.
* The client reads a raw long from the server, this is the "session id".
* The client creates a new frame, opcode 0 or 19 if the player is reconnecting.
* A short, the client's revision number (135) is placed in the buffer.
* A long, the player's username encoded with mod37 (see above) is placed in the buffer.
* A string encoded with RSA and the player's session id (the password) is placed in the buffer.
* An integer, the player's "ranseed" value is placed in the buffer.
** "ranseed" does not seed anything. RSC135 does not use ISAAC ciphering. It is an applet parameter or read from uid.dat. Presumably, it was used to identify players connecting from the same computer.
* The stream is then flushed.
* A byte is read from the stream and discarded.
* Another byte is read, this is the login response code from the server.
2012-11-12 19:01:08 -05:00
2012-11-12 17:32:28 -05:00
{| class="wikitable"
|-
2012-11-12 19:01:08 -05:00
! Login Resp.
2012-11-12 17:32:28 -05:00
! Description
|-
2012-11-12 19:01:08 -05:00
| 0
| Successful login
|-
| 1
|?
|-
| 3
| Invalid username or password
|-
| 4
| Username already in use
|-
| 5
| Client has been updated
|-
| 6
| IP address is already in use
|-
| 7
| Login attempts exceeded
|-
| 11
| Account temporarily disabled
|-
| 12
| Account permanently disabled
|-
| 15
| Server is currently full
|-
| 16
| Members-only server
|-
| 17
2012-11-14 18:43:47 -05:00
| Members-only area?
2012-11-12 17:32:28 -05:00
|}
2012-11-12 09:45:43 -05:00
2012-11-14 18:43:47 -05:00
== '''Registration''' ==
* The username and password are prepared. This is done by replacing any spaces or illegal characters with _ and appending spaces to the string until its length is 20.
* The connection with the server is established.
* The client reads a raw long from the server, this is the "session id".
* The client creates a new frame, opcode 2.
* A short, the client's revision number (135) is placed in the buffer.
* A long, the player's username encoded with mod37 (see above) is placed in the buffer.
* A short, the applet's "referid" parameter is placed in the buffer.
* A string encoded with RSA and the player's session id (the password) is placed in the buffer.
* An integer, the player's "ranseed" value is placed in the buffer.
** "ranseed" does not seed anything. RSC135 does not use ISAAC ciphering. It is an applet parameter or read from uid.dat. Presumably, it was used to identify players connecting from the same computer.
* The stream is then flushed.
* A byte is read from the stream and discarded.
* Another byte is read, this is the newplayer response code from the server.
2012-11-12 17:32:28 -05:00
{| class="wikitable"
|-
2012-11-12 19:01:08 -05:00
! Newp Resp.
2012-11-12 17:32:28 -05:00
! Description
|-
2012-11-12 19:01:08 -05:00
| 2
| Successful registration
|-
| 3
| Username already taken
|-
| 5
| Client has been updated
|-
| 6
| IP address is already in use
|-
| 7
| Registration attempts exceeded?
2012-11-12 17:32:28 -05:00
|}
2012-11-07 08:54:36 -05:00
2012-11-14 18:43:47 -05:00
== '''Password Recovery''' ==
Firstly, an integer is read from the stream.
Then, the previous password and the new password are formatted and stored locally.
The client begins a packet with opcode 8. The username is encoded and the long is written.
Next, the client session ID is written.
RSA line is put (old password + new password)
(Presumably) The username is written as RSA long 5 times encoded with a special method used exclusively in the account recovery process (documented above).
One byte is read and discarded.
The next byte is the recovery response. The possible values:
{| class="wikitable"
|-
! Response Code
! Meaning
|-
| 0 || Sorry, recovery failed! You may try again in one hour.
|-
| 1 || Your pass has been reset. You may now use the new pass to login.
|}
Literally any other value results in a recovery failure and the following error message:
"Recovery failed! Attempts exceeded?"
== '''Packets''' ==
The packet opcodes are unchanged from previous revisions, presumably this was before the protocol was being regularly modified to deter the developers of bots such as [[AutoRune]]. The payload/structure is quite similar to most other RSC revisions.
=== '''Incoming Data''' ===
'''TODO:'''
{| class="wikitable"
|-
! Name
! Opcode
! Payload
! Description
|-
! Display Message
| 8 ||
* ?
| ?
|-
! Close Connection
| 9 ||
* ?
| ?
|-
! Logout Failed
| 10 ||
* ?
| ?
|-
! Initialize Friends List
| 23 ||
* ?
| ?
|-
! Update Friends List
| 24 ||
* ?
| ?
|-
! Initialize Ignore List
| 26 ||
* ?
| ?
|-
! Privacy Settings
| 27 ||
* ?
| ?
|-
! Private Message
| 28 ||
* ?
| ?
|-
! Player Positions
| 255 ||
* ?
| ?
|-
! Ground Items
| 254 ||
* ?
| ?
|-
! Objects
| 253 ||
* ?
| ?
|-
! Inventory
| 252 ||
* ?
| ?
|-
! Players
| 250 ||
* ?
| ?
|-
! Boundaries
| 249 ||
* ?
| ?
|-
! NPC Positions
| 248 ||
* ?
| ?
|-
! NPCs
| 247 ||
* ?
| ?
|-
! Dialog
| 246 ||
* ?
| ?
|-
! Hide Dialog
| 245 ||
* ?
| ?
|-
2012-11-25 10:10:56 -05:00
! Init Map Region
2012-11-14 18:43:47 -05:00
| 244 ||
* ?
| ?
|-
! Skills
| 243 ||
* ?
| ?
|-
! Equipment Bonuses
| 242 ||
* ?
| ?
|-
! Player Death
| 241 ||
* ?
| ?
|-
! Environment
| 240 ||
* ?
| ?
|-
! Character Design
| 239 ||
* ?
| ?
|-
! Display Trade Offer
| 238 ||
* ?
| ?
|-
! Hide Trade
| 237 ||
* ?
| ?
|-
! Update Trade Offer
| 236 ||
* ?
| ?
|-
! Other's Trade Status
| 235 ||
* ?
| ?
|-
! Display Shop
| 234 ||
* ?
| ?
|-
! Hide Shop
| 233 ||
* ?
| ?
|-
! Our Trade Status
| 229 ||
* ?
| ?
|-
! Game Settings
| 228 ||
* ?
| ?
|-
! Prayers
| 227 ||
* ?
| ?
|-
! Quests
| 226 ||
* ?
| ?
|-
! Display Bank
| 222 ||
* ?
| ?
|-
! Hide Bank
| 221 ||
* ?
| ?
|-
! Bank Update
| 214 ||
* ?
| ?
|-
! XP Update
| 220 ||
* ?
| ?
|-
! Update InvItem
| 213 ||
* ?
| ?
|-
! Remove InvItem
| 212 ||
* ?
| ?
|-
! Skill Update
| 211 ||
* ?
| ?
|-
|}
2012-11-12 17:32:28 -05:00
=== '''Outgoing Data''' ===
2012-11-14 17:38:19 -05:00
'''TODO: Password recovery & recovery questions, 254'''
2012-11-08 12:10:49 -05:00
{| class="wikitable"
2012-11-08 11:56:46 -05:00
|-
2012-11-08 12:01:18 -05:00
! Name
! Opcode
! Payload
2012-11-08 12:08:49 -05:00
! Description
2012-11-08 11:56:46 -05:00
|-
2012-11-10 08:43:16 -05:00
! Disconnect
| 1 ||
* None
2012-11-11 10:59:20 -05:00
| Sends the disconnect packet
2012-11-10 08:43:16 -05:00
|-
2012-11-08 12:05:17 -05:00
! Newplayer (Registration)
| 2 ||
2012-11-12 17:32:28 -05:00
* Short - The client's revision number (135)
* Long - Long representation of the username
2012-11-08 12:51:37 -05:00
* Short - Referrer ID
2012-11-08 12:05:17 -05:00
** Integer.parseInt(getParameter("referrerid"));
2012-11-08 12:51:37 -05:00
* Line-RSA - Password, server session ID, bigintegers
2012-11-12 17:32:28 -05:00
* Int - The "ranseed" value
| Registers a new user.
|-
! Login
2012-11-14 18:43:47 -05:00
| 0 ||
2012-11-12 17:32:28 -05:00
* Short - The client's revision number (135)
* Long - Long representation of the username
* Line-RSA - Password, server session ID, bigintegers
* Int - The "ranseed" value
2012-11-14 18:43:47 -05:00
| Logs the player in.
|-
! Reconnect
| 19 ||
* Same as 0
| Reconnects the player after they are disconnected.
2012-11-08 12:08:49 -05:00
|-
! Logout
| 6 ||
2012-11-08 12:10:49 -05:00
* None
2012-11-08 12:08:49 -05:00
| Sends the logout packet to the server
2012-11-08 12:05:53 -05:00
|-
2012-11-12 17:32:28 -05:00
! Admin Command
2012-11-08 12:46:13 -05:00
| 7 ||
* String - The command
| Sends a command to the server to be executed
|-
2012-11-08 12:51:37 -05:00
! Report Abuse
| 10 ||
* Long - The long representation of the username of the user to report
| Sends an abuse report to the server
|-
! Add Friend
2012-11-08 12:01:18 -05:00
| 26 ||
2012-11-12 17:32:28 -05:00
* Long - long representation of username
2012-11-08 12:08:49 -05:00
| Adds a user to your friends list
2012-11-08 12:51:37 -05:00
|-
! Remove Friend
| 27 ||
* Long - The long representation of the username of the user to report
| Removes a user from your friends list
|-
! Send Message
| 28 ||
* Long - The long representation of the username of the user to send the message to
* Byte[] - A byte array containing the bytes of the message to send to the user
| Sends a message to the specified user
|-
! Ignore User
| 29 ||
* Long - The long representation of the username of the user to ignore
| Adds a user to your ignore list
2012-11-10 16:50:56 -05:00
|-
2012-11-12 17:32:28 -05:00
! Walk to Tile
| 255 ||
* Short - (start_x + area_x). The initial position.
* Short - (start_y + area_y)
* Byte... - (route_x[i] - start_x)
* Byte... - (route_y[i] - start_y)
| Variable length. Walks to a tile. The number of steps can be calculated by dividing the available data by 2.
|-
! Walk to Entity
| 215 ||
* The same as 255.
| Variable length. Walks to an entity. The number of steps can be calculated by dividing the available data by 2.
|-
! Acknowledge Players
| 254 ||
* Short - Size?
* Short... - The player's server index
* Short... - ???
| Variable length. Informs the server of new players. Why?
|-
2012-11-10 16:50:56 -05:00
! Drop Item
| 251 ||
2012-11-12 09:25:15 -05:00
* Short - The slot of the item to drop
2012-11-10 16:50:56 -05:00
| Drops the specified item on the ground
2012-11-12 09:25:15 -05:00
|-
2012-11-12 17:32:28 -05:00
! Cast on Item
2012-11-12 09:25:15 -05:00
| 220 ||
* Short - The slot of the item to cast a spell on
* Short - The id of the spell to cast
| Casts a spell (such as High Alchemy) on the specified item
|-
2012-11-12 17:32:28 -05:00
! Use with Item
2012-11-12 09:25:15 -05:00
| 240 ||
* Short - The slot of the first item to use
* Short - The slot of the second item to use
| Uses an item in the player's inventory with another item in the player's inventory
|-
! Remove Item
| 248 ||
* Short - The slot of the item to unequip
2012-11-12 17:32:28 -05:00
| Unequips the specified inventory item
2012-11-12 09:25:15 -05:00
|-
! Wear Item
| 249 ||
* Short - The slot of the item to equip
2012-11-12 17:32:28 -05:00
| Equips the specified inventory item
2012-11-12 09:25:15 -05:00
|-
2012-11-12 17:32:28 -05:00
! Item Command
2012-11-12 09:25:15 -05:00
| 246 ||
* Short - The slot of the item to use
2012-11-12 17:32:28 -05:00
| Buries, eats, etc the specified inventory item
2012-11-12 09:45:43 -05:00
|-
! Select Option
| 237 ||
* Byte - The position of the option in the dialog_options array
| Selects an option in a dialog (dialog referring to, for example, the menu displayed when certing)
|-
2012-11-12 17:32:28 -05:00
! Combat Style
2012-11-12 09:45:43 -05:00
| 231 ||
* Byte - The position of the combat style in the list
2012-11-12 17:32:28 -05:00
| Sets the player's combat style.
* 0 - Controlled
* 1 - Aggressive
* 2 - Accurate
* 3 - Defensive
2012-11-12 09:45:43 -05:00
|-
! Close Bank
| 207 ||
* None
| Informs the server that the player has closed the banking interface.
|-
! Withdraw Item
| 206 ||
* Short - The ID of the item to withdraw
* Short - The amount of the specified item to withdraw
| Withdraws a single type of item from the player's bank.
|-
! Deposit Item
| 205 ||
* Short - The ID of the item to deposit
* Short - The amount of the specified item to deposit
| Deposits a single type of item into the player's bank.
|-
! Disable Prayer
| 211 ||
* Byte - The ID of the prayer to disable
| Disables a prayer.
|-
! Enable Prayer
| 212 ||
* Byte - The ID of the prayer to enable
| Enables a prayer.
2012-11-12 17:32:28 -05:00
|-
! Confirm Trade
| 202 ||
* None
| Confirms the trade offer.
|-
! Accept Trade
| 232 ||
* None
| Accepts the trade offer.
|-
! Decline Trade
| 233 ||
* None
| Declines the trade offer.
|-
! Trade Update
| 234 ||
* Byte - The amount of traded items to send to the server
* Short... - The id of the item
* Int... - The amount/stack size of the item
| Variable length. Updates the trade offer.
|-
! Cast on GItem
| 224* ||
* Short - The item's X coordinate
* Short - The item's Y coordinate
* Short - The item's ID
* Short - The spell's ID
| Casts a spell on an item on the ground.
|-
! Use with GItem
| 250* ||
* Short - The item's X coordinate
* Short - The item's Y coordinate
* Short - The item's ID
* Short - The inventory slot
| Uses an item in the player's inventory with an item on the ground.
|-
! Take GItem
| 252* ||
* Short - The item's X coordinate
* Short - The item's Y coordinate
* Short - The item's ID
| Picks up an item on the ground.
|-
! Cast on Boundary
| 223* ||
* Short - The bound's X coordinate
* Short - The bound's Y coordinate
* Byte - The bound's direction
* Short - The spell's ID
| Casts a spell on a boundary (or 'wall object').
|-
! Use with Boundary
| 239* ||
* Short - The bound's X coordinate
* Short - The bound's Y coordinate
* Byte - The bound's direction
* Short - The inventory slot
| Uses an item in the player's inventory with a boundary (or 'wall object').
|-
! Boundary Cmd 1
| 238* ||
* Short - The bound's X coordinate
* Short - The bound's Y coordinate
* Byte - The bound's direction
| Performs the primary action (usually 'open') on a boundary (or 'wall object').
|-
! Boundary Cmd 2
| 229* ||
* Short - The bound's X coordinate
* Short - The bound's Y coordinate
* Byte - The bound's direction
| Performs the secondary action (usually 'close' or 'picklock') on a boundary (or 'wall object').
|-
! Cast on Object
| 222* ||
* Short - The object's X coordinate
* Short - The object's Y coordinate
* Short - The spell's ID
| Casts a spell on an object. Unused?
|-
! Use with Object
| 241* ||
* Short - The object's X coordinate
* Short - The object's Y coordinate
* Short - The inventory slot
| Uses an item in the player's inventory with an object.
|-
! Object Cmd 1
| 241* ||
* Short - The object's X coordinate
* Short - The object's Y coordinate
| Performs the primary action on an object (for example, 'mine').
|-
! Object Cmd 2
| 230* ||
* Short - The object's X coordinate
* Short - The object's Y coordinate
| Performs the secondary action on an object (for example, 'prospect').
|-
! Cast on NPC
| 225* ||
* Short - The NPC's server index
* Short - The spell's ID
| Casts a spell on a non-player character.
|-
! Use with NPC
| 243* ||
* Short - The NPC's server index
* Short - The inventory slot
| Uses an item in the player's inventory with a non-player character.
|-
! Talk to NPC
| 245* ||
* Short - The NPC's server index
| Starts talking to a non-player character.
|-
! Attack NPC
| 244* ||
* Short - The NPC's server index
| Starts attacking a non-player character.
|-
! NPC Cmd 2
| 195* ||
* Short - The NPC's server index
| Performs the secondary action on a non-player character, usually 'pickpocket'.
|-
! Cast on Player
| 226* ||
* Short - The player's server index
* Short - The spell's ID
| Casts a spell on another player.
|-
! Use with Player
| 219* ||
* Short - The player's server index
* Short - The inventory slot
| Uses an item (for example, a Gnomeball, or a Christmas cracker) on another player.
|-
! Attack Player
| 228* ||
* Short - The player's server index
| Starts attacking another player.
|-
! Trade Player
| 235 ||
* Short - The player's server index
| Sends a trade request to another player.
|-
! Follow Player
| 214 ||
* Short - The player's server index
| Starts following another player.
|-
! Duel Player
| 204 ||
* Short - The player's server index
| Sends a duel request to another player.
2012-11-12 17:52:51 -05:00
|-
! RuntimeException
| 17 ||
* String - The text of the error.
| Sent when the client throws an exception while processing data sent by the server.
2012-11-14 17:38:19 -05:00
|-
! Confirm Duel Offer
| 198 ||
* None
| Confirms the duel offer.
|-
! Accept Duel Offer
| 199 ||
* None
| Accepts the duel offer.
|-
! Duel Settings
| 200 ||
* Byte - No retreating, 0 or 1
* Byte - No magic, 0 or 1
* Byte - No prayers, 0 or 1
* Byte - No weapons, 0 or 1
| Updates the duel settings.
|-
! Duel Items
| 201 ||
* Byte - The total number of offered items
* Short... - Offered item ID
* Int... - Offered item stack size
| Variable length. Updates the stake.
|-
! Decline Duel Offer
| 203 ||
* None
| Declines the duel offer.
2012-11-15 18:52:41 -05:00
|-
! Character Design
| 236 ||
* Byte - A value that is not used in the player update process.
* Byte - The player's hair style.
* Byte - The player's gender. 4 = Female, 1 = Male
* Byte - Constant 2
* Byte - The player's hair colour
* Byte - The player's top colour
* Byte - The player's leg colour
* Byte - The player's skin colour
* Byte - The player's class
| Submits the player's chosen design when they log in for the first time.
The first byte appears to be unused.
The constant value is used in the update process, but why?
* 0 - Adventurer class
* 1 - Warrior class
* 2 - Wizard class
* 3 - Ranger class
* 4 - Miner class
2012-11-12 17:32:28 -05:00
|}
Notes:
2012-11-14 17:38:19 -05:00
* Opcodes marked with * are preceded by Walk to Entity.
* When closing the duel confirm screen, it may send the decline trade packet, for some reason.