677 lines
32 KiB
Markdown
677 lines
32 KiB
Markdown
# Protocol #135 (RSC)
|
|
|
|
This is a RuneScape Classic protocol.
|
|
You can find a partially refactored client for it [here](https://bitbucket.org/_mthd0/rsc/).
|
|
|
|
## Packet structure
|
|
|
|
```
|
|
if (len >= 160 {
|
|
[byte] (160 + (len / 256))
|
|
[byte] (len & 0xff)
|
|
} else {
|
|
[byte] len
|
|
if (len > 0) {
|
|
len--; // skip it
|
|
[byte] data[len] // last byte
|
|
}
|
|
}
|
|
[byte] opcode
|
|
for (int i = 0; i < len; i++)
|
|
[byte] data[i]
|
|
```
|
|
|
|
## Byte order
|
|
|
|
This protocol uses big-endian byte order exclusively.
|
|
|
|
## Data types
|
|
|
|
| Name | Description |
|
|
|---|---|
|
|
| int8 | An 8-bit integer (i.e. byte) |
|
|
| int16 | An 16-bit integer (i.e. short/Word) |
|
|
| int32 | An 32-bit integer (i.e. int/DWord) |
|
|
| int64 | An 64-bit integer (i.e. long/QWord) |
|
|
|
|
Note: If the name is postfixed with `u`, it means that the type is unsigned.
|
|
|
|
Note: If the name is postfixed with `a`, then when writing, increment the MSB
|
|
(most significant byte, or first byte) by 128.
|
|
When reading, if the first byte unsigned is lower than 128, that's your
|
|
value, otherwise decrement the first byte by 128 and read as normally.
|
|
|
|
## Bit access
|
|
|
|
```java
|
|
private static final int bitmasks[] = {
|
|
0, 1, 3, 7, 15, 31, 63, 127, 255, 511, 1023, 2047, 4095, 8191, 16383, 32767, 65535,
|
|
0x1ffff, 0x3ffff, 0x7ffff, 0xfffff, 0x1fffff, 0x3fffff, 0x7fffff, 0xffffff, 0x1ffffff,
|
|
0x3ffffff, 0x7ffffff, 0xfffffff, 0x1fffffff, 0x3fffffff, 0x7fffffff, -1
|
|
};
|
|
|
|
public void start_bit_access() {
|
|
bitpos = offset * 8;
|
|
}
|
|
|
|
public void write_bits(int num, int val) {
|
|
int bytepos = bitpos >> 3;
|
|
int bitoffset = 8 - (bitpos & 7);
|
|
bitpos += num;
|
|
for (; num > bitoffset; bitoffset = 8) {
|
|
buffer[bytepos] &= ~bitmasks[bitoffset];
|
|
buffer[bytepos++] |= (val >> (num - bitoffset)) & bitmasks[bitoffset];
|
|
num -= bitoffset;
|
|
}
|
|
if (num == bitoffset) {
|
|
buffer[bytepos] &= ~bitmasks[bitoffset];
|
|
buffer[bytepos] |= val & bitmasks[bitoffset];
|
|
} else {
|
|
buffer[bytepos] &= ~(bitmasks[num] << (bitoffset - num));
|
|
buffer[bytepos] |= (val & bitmasks[num]) << (bitoffset - num);
|
|
}
|
|
}
|
|
|
|
public void end_bit_access() {
|
|
offset = (bitpos + 7) / 8;
|
|
}
|
|
```
|
|
|
|
## Reference
|
|
|
|
Player usernames are encoded and decoded with the following methods:
|
|
|
|
```java
|
|
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;
|
|
}
|
|
|
|
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;
|
|
}
|
|
}
|
|
return s;
|
|
}
|
|
```
|
|
|
|
Chat messages are encoded and decoded with the following methods:
|
|
|
|
```java
|
|
public static byte encodedmsg[] = new byte[100];
|
|
public static char decodedmsg[] = new char[100];
|
|
private static char charmap[] = {
|
|
' ', 'e', 't', 'a', 'o', 'i', 'h', 'n', 's', 'r', 'd', 'l', 'u', 'm', 'w', 'c', 'y', 'f',
|
|
'g', 'p', 'b', 'v', 'k', 'x', 'j', 'q', 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8',
|
|
'9', ' ', '!', '?', '.', ',', ':', ';', '(', ')', '-', '&', '*', '\\', '\'', '@', '#', '+',
|
|
'=', '\243', '$', '%', '"', '[', ']'
|
|
};
|
|
|
|
public static String decode_msg(byte buffer[], int off, int enclen) {
|
|
try {
|
|
int i = 0;
|
|
int j = -1;
|
|
for (int k = 0; k < enclen; k++) {
|
|
int l = buffer[off++] & 0xff;
|
|
int i1 = l >> 4 & 0xf;
|
|
if (j == -1) {
|
|
if (i1 < 13)
|
|
decodedmsg[i++] = charmap[i1];
|
|
else
|
|
j = i1;
|
|
} else {
|
|
decodedmsg[i++] = charmap[((j << 4) + i1) - 195];
|
|
j = -1;
|
|
}
|
|
i1 = l & 0xf;
|
|
if (j == -1) {
|
|
if (i1 < 13)
|
|
decodedmsg[i++] = charmap[i1];
|
|
else
|
|
j = i1;
|
|
} else {
|
|
decodedmsg[i++] = charmap[((j << 4) + i1) - 195];
|
|
j = -1;
|
|
}
|
|
}
|
|
boolean flag = true;
|
|
for (int j1 = 0; j1 < i; j1++) {
|
|
char c = decodedmsg[j1];
|
|
if (j1 > 4 && c == '@')
|
|
decodedmsg[j1] = ' ';
|
|
if (c == '%')
|
|
decodedmsg[j1] = ' ';
|
|
if (flag && c >= 'a' && c <= 'z') {
|
|
decodedmsg[j1] += '\uFFE0';
|
|
flag = false;
|
|
}
|
|
if (c == '.' || c == '!')
|
|
flag = true;
|
|
}
|
|
return new String(decodedmsg, 0, i);
|
|
} catch (Exception ex) {
|
|
return "Cabbage";
|
|
}
|
|
}
|
|
|
|
public static int encode_msg(String str) {
|
|
if (str.length() > 80)
|
|
str = str.substring(0, 80);
|
|
str = str.toLowerCase();
|
|
int enclen = 0;
|
|
int i = -1;
|
|
for (int j = 0; j < str.length(); j++) {
|
|
char c = str.charAt(j);
|
|
int k = 0;
|
|
for (int l = 0; l < charmap.length; l++) {
|
|
if (c != charmap[l])
|
|
continue;
|
|
k = l;
|
|
break;
|
|
}
|
|
if (k > 12)
|
|
k += 195;
|
|
if (i == -1) {
|
|
if (k < 13)
|
|
i = k;
|
|
else
|
|
encodedmsg[enclen++] = (byte) k;
|
|
} else if (k < 13) {
|
|
encodedmsg[enclen++] = (byte) ((i << 4) + k);
|
|
i = -1;
|
|
} else {
|
|
encodedmsg[enclen++] = (byte) ((i << 4) + (k >> 4));
|
|
i = k & 0xf;
|
|
}
|
|
}
|
|
if (i != -1)
|
|
encodedmsg[enclen++] = (byte) (i << 4);
|
|
return enclen;
|
|
}
|
|
```
|
|
|
|
## Login
|
|
|
|
* The username and password are prepared 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.
|
|
|
|
Login responses
|
|
|
|
| Response Code | Description
|
|
|---|---|
|
|
| 0 | Success. |
|
|
| 1 | ? |
|
|
| 3 | Invalid username or password. |
|
|
| 4 | Username already in use. |
|
|
| 5 | Client has been updated. |
|
|
| 6 | IP address 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 | Members only area? |
|
|
|
|
## 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.
|
|
|
|
Registration responses
|
|
|
|
| Response Code | Description |
|
|
|---|---|
|
|
| 2 | Success. |
|
|
| 3 | Username already taken. |
|
|
| 5 | Client has been updated. |
|
|
| 6 | IP address already in use. |
|
|
| 7 | Registration attempts exceeded? |
|
|
|
|
## Mob Appearance Update
|
|
|
|
Firstly, create a new packet with the opcode 250.
|
|
Write the total number of expected updates (uint16).
|
|
|
|
Secondly, for each entity to update, write the (server) index of the
|
|
mob the update applies to (uint16), and the 'update type' (int8)
|
|
followed by whatever data that type expects.
|
|
|
|
### Update type 1: Public chat messages
|
|
|
|
* uint8 - The length of the chat message.
|
|
* string (raw) - The encoded chat message.
|
|
|
|
### Update type 2: Combat damage
|
|
|
|
* uint8 - The damage recieved.
|
|
* uint8 - That mob's 'current' hitpoints level.
|
|
* uint8 - That mob's 'base' hitpoints.
|
|
|
|
### Update type 3/4: Projectiles
|
|
|
|
The update type is 3 when the target is a NPC, or 4 is the target is a
|
|
player.
|
|
|
|
The standard magic projectile id is 1, and the standard ranged
|
|
projectile id is 2.
|
|
|
|
* uint16 - The projectile's id.
|
|
* uint16 - The (server) index of the projectile's target entity.
|
|
|
|
### Update type 5: Appearance
|
|
|
|
Hair style, body type, leg type, and colours are as they are sent by the
|
|
client's character design packet.
|
|
|
|
* uint16 - The player's status? Doesn't appear to do anything.
|
|
* int64 - The player's username encoded with mod37.
|
|
* uint8 - The size of the sub-update.
|
|
* uint8 - The player's hair style + 1, or 0 if they are wearing a helmet.
|
|
* uint8 - The player's body type + 1, or 0 if they are wearing a platebody.
|
|
* uint8 - The player's leg type + 1, or 0 if they are wearing legs.
|
|
* uint8 - The animation id + 1 (look in the client) of the player's offhand item or 0.
|
|
* uint8 - The animation id + 1 of the player's hand item or 0.
|
|
* uint8 - The animation id + 1 of the player's head item or 0.
|
|
* uint8 - The animation id + 1 of the player's body item or 0.
|
|
* uint8 - The animation id + 1 of the player's leg item or 0.
|
|
* uint8 - The animation id + 1 of the player's neck item or 0.
|
|
* uint8 - The animation id + 1 of the player's shoes or 0.
|
|
* uint8 - The animation id + 1 of the player's gloves or 0.
|
|
* uint8 - The animation id + 1 of the player's cape or 0.
|
|
* uint8 - The player's hair colour.
|
|
* uint8 - The player's top colour.
|
|
* uint8 - The player's leg colour.
|
|
* uint8 - The player's skin colour.
|
|
* uint8 - The player's combat level.
|
|
* uint8 - 1 if the player is skulled.
|
|
|
|
## 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 packets
|
|
'''TODO: Duelling stuff, 240''' {\|
|
|
class="wikitable" \|- ! scope="col" width="140px" \| Name ! scope="col"
|
|
width="50px" \| Opcode ! scope="col" width="350px" \| Payload !
|
|
scope="col" width="300px" \| Description \|- ! Display Message \| 8 \|\|
|
|
\* string - A raw string, the message. \| Informs the client of a line
|
|
to be printed in the in-game message box. Messages preceded by @que@ are
|
|
sent to the quest history box, messages preceded by @pri@ are sent to
|
|
the private chat history box. \|- ! Close Connection \| 9 \|\| \* None
|
|
\| Forces the client to log out. \|- ! Logout Failed \| 10 \|\| \* None
|
|
\| You can't log out now! \|- ! Initialize Friends List \| 23 \|\| \*
|
|
uint8 - The total number of players in the list. \* int64... - The
|
|
friend's username, encoded with mod37. \* uint8... - The world the
|
|
friend is logged in to. 0 indicates the player is logged out. \|
|
|
Initializes the player's friends list. Variable length. \|- ! Update
|
|
Friends List \| 24 \|\| \* int64 - The friend's username, encoded with
|
|
mod37. \* uint8 - 0 if the friend is logged in, 1 if the friend is
|
|
logged out. \| Informs the client that a friend has logged in/out or
|
|
that a new friend has been added to the list. \|- ! Initialize Ignore
|
|
List \| 26 \|\| \* uint8 - The total number of players in the list. \*
|
|
int64... - The friend's username, encoded with mod37. \| Initializes the
|
|
player's ignore list. Variable length. \|- ! Initialize Privacy Settings
|
|
\| 27 \|\| \* int8 - 0/1. Block public chat messages. \* int8 - 0/1.
|
|
Block private chat messages. \* int8 - 0/1. Block trade requests. \*
|
|
int8 - 0/1. Block duel requests. \| Initializes the player's privacy
|
|
settings. \|- ! Private Message \| 28 \|\| \* int64 - The sender's
|
|
username, encoded with mod37. \* string - The encoded message. \| Sends
|
|
a private message to the client. \|- ! Player Movement \| 255 \|\| \*
|
|
bits\[10\] - This player's x position. \* bits\[12\] - This player's y
|
|
position. \* bits\[4\] - This player's direction. \* bits\[8\] - The
|
|
number of players the client already knows about to be sent (but it
|
|
reads them in order?) \*\* bits\[1\]... - If the player has not moved &
|
|
does not need to be removed, 0 & don't send the next 2 lots of bits,
|
|
otherwise 1. \*\* bits\[1\]... - 1 if the player is to be removed. \*\*
|
|
bits\[3/4\]... - The player's direction. 4 bits with a value of 12 if
|
|
the player is to be removed, otherwise 3 bits. \* bits\[11\]... - The
|
|
new player's (server) index. \* bits\[5\]... - The new player's offset x
|
|
position. \* bits\[5\]... - The new player's offset y position. \*
|
|
bits\[4\]... - The new player's direction. \* bits\[1\]... - something
|
|
to do with c\>s 254? 0 \| Updates the position/movement of the client's
|
|
player and nearby players. Usually sent every game engine tick (600ms)
|
|
rather than when needed as with other packets. Offset positions are
|
|
this\_x - player\_x and are incremented by 32 if less than zero.
|
|
Variable length. \|- ! Ground Item Positions \| 254 \|\| \* uint16 - The
|
|
id of the item to update \* int8 - The x position of the item relative
|
|
to the player (item\_x - player\_x) \* int8 - The y position of the item
|
|
relative to the player (item\_y - player\_y) \| Updates the positions of
|
|
nearby ground items. if ((id & 0x8000) == 0), remove the item.
|
|
Therefore, if the server increments the id by 0x8000, the item will be
|
|
removed by the client. Variable length. \|- ! Object Positions \| 253
|
|
\|\| \* uint16 - The id of the object to update \* int8 - The x position
|
|
of the object relative to the player (object\_x - player\_x) \* int8 -
|
|
The y position of the object relative to the player (object\_y -
|
|
player\_y) \| Updates the positions of nearby objects. Variable length.
|
|
If the id is real fuckin' big, remove it. \|- ! Whole Inventory \| 252
|
|
\|\| \* uint8 - The number of items in the player's inventory. \*
|
|
uint16... - The item's id. If equipped, increment by 0x8000. \*
|
|
int32a... - The item's stack size. Only sent when the item is stackable.
|
|
\| Sends over the player's whole inventory. Variable length. \|- !
|
|
Player Appearance \| 250 \|\| \* See \[\[135 Protocol\#Mob Appearance
|
|
Update\|Mob Appearance Update\]\] \| Updates things to do with nearby
|
|
players that aren't related to movement. \|- ! Boundary Positions \| 249
|
|
\|\| \* uint16 - The id of the bound to update \* int8 - The x position
|
|
of the bound relative to the player (object\_x - player\_x) \* int8 -
|
|
The y position of the bound relative to the player (object\_y -
|
|
player\_y) \* int8 - The bound's direction \| Updates the positions of
|
|
nearby bounds. Variable length. If the id is real fuckin' big, remove
|
|
it. \|- ! NPC Movement \| 248 \|\| \* bits\[8\] - The number of NPCs the
|
|
client already knows about to be sent (but it reads them in order?).
|
|
\*\* bits\[1\]... - 1 if the NPC has moved, otherwise 0 & don't send the
|
|
next 2 lots of bits. \*\* bits\[1\]... - 1 if the NPC is to be removed,
|
|
otherwise 0. \*\* bits\[3/4\]... - The NPC's direction, 4 bits with a
|
|
value of 12 if the NPC is to be removed, otherwise 3 bits. \*
|
|
bits\[11\]... - The new NPC's (server) index. \* bits\[5\]... - The new
|
|
NPC's offset x position. \* bits\[5\]... - The new NPC's offset y
|
|
position. \* bits\[4\]... - The new NPC's direction. \* bits\[9\]... -
|
|
The new NPC's id. \| Updates the positions/movement of nearby NPCs.
|
|
Usually sent every game engine tick (600ms) rather than when needed as
|
|
with other packets. Offset positions are player\_x - npc\_x and are
|
|
incremented by 32 if less than zero. Variable length. \|- ! NPC
|
|
Appearance \| 247 \|\| \* See \[\[135 Protocol\#Mob Appearance
|
|
Update\|Mob Appearance Update\]\]. \| Updates things to do with nearby
|
|
NPCs that aren't related to movement. Only the first two update types
|
|
apply (NPCs cannot send projectiles or have changed sprites). NPC server
|
|
index is used instead of player server index, obviously. \|- ! Display
|
|
Dialog \| 246 \|\| \* uint8 - The total number of options. \* uint8... -
|
|
The length of the option string. \* string... - The option string. \|
|
|
Displays a NPC chat dialog. Variable length. \|- ! Hide Dialog \| 245
|
|
\|\| \* None \| Hides the NPC chat dialog. \|- ! Initialize Plane \| 244
|
|
\|\| \* uint16 - The player's server index. \* uint16 - The width of the
|
|
plane. (2304) \* uint16 - The height of the plane. (1776) \* uint16 -
|
|
The index of the plane. (player\_y / multiplier) \* uint16 - The plane
|
|
multiplier. (944) \| Initializes the plane. Sent when the player first
|
|
logs in, and when the player is teleported or moves up/down a height.
|
|
\|- ! All Skills \| 243 \|\| \* for (int i = 0; i \< skill\_count; i++)
|
|
\* uint8... - The skill's current level. \* for (int i = 0; i \<
|
|
skill\_count; i++) \* uint8... - The skill's base level. \* for (int i =
|
|
0; i \< skill\_count; i++) \* int32... - The skill's xp points. \* uint8
|
|
- The player's quest points. \| Updates all of the player's skills and
|
|
quest points. The 135 client reads 18 skills: Attack, Defense, Strength,
|
|
Hits, Ranged, Prayer, Magic, Cooking, Woodcutting, Fletching, Fishing,
|
|
Firemaking, Crafting, Smithing, Mining, Herblaw, Carpentry, Thieving.
|
|
\|- ! Equipment Bonuses \| 242 \|\| \* uint8 - The armour's bonus. \*
|
|
uint8 - The weapon's accuracy bonus. \* uint8 - The weapon's strength
|
|
bonus. \* uint8 - The magic bonus. \* unit8 - The prayer bonus. \|
|
|
Updates the player's equipment bonuses. Variable length. \|- ! Player
|
|
Death \| 241 \|\| \* None \| Displays the "Oh dear! You are dead..."
|
|
screen. \|- ! Environment \| 240 \|\| \* ? \| Doesn't appear to be
|
|
important when you have everything else. It might be useful to have
|
|
though, so why don't you be kind and document it? :) \|- ! Display
|
|
Character Design \| 239 \|\| \* None \| Displays the character design
|
|
interface. \|- ! Display Trade Offer \| 238 \|\| \* uint16 - The server
|
|
index of the player we are trading with. \| Displays the trade offer
|
|
interface. \|- ! Hide Trade \| 237 \|\| \* None \| Hides the trade offer
|
|
and confirm interfaces. \|- ! Update Trade Offer \| 236 \|\| \* int8 -
|
|
The number of items the other player has traded. \* uint16... - The
|
|
item's id. \* int32a... - The item's stack size. \| Updates the other
|
|
player's trade offer. \|- ! Other's Trade Status \| 235 \|\| \* int8 - 1
|
|
= yes, anything else = no \| Has the other player accepted the trade
|
|
offer? \|- ! Display Shop \| 234 \|\| \* uint8 - The number of items in
|
|
the shop. \* int8 - 1 if the shop is a general store. \* uint8 - This
|
|
shop's selling price modifier. \* uint8 - This shop's buying price
|
|
modifier. \* uint16... - The item's id. \* uint16... - The item's stack
|
|
size. \* uint8... - The item's price. \| Displays the shop interface.
|
|
Variable length. \|- ! Hide Shop \| 233 \|\| \* None \| Hides the shop
|
|
interface. \|- ! Our Trade Status \| 229 \|\| \* int8 - 1 = yes,
|
|
anything else = no \| Have we accepted the trade offer? \|- ! Init Game
|
|
Settings \| 228 \|\| \* int8 - Automatic camera rotation. 1 = enabled,
|
|
anything else is disabled. \* int8 - Single mouse button. 1 = enabled,
|
|
anything else is disabled. \* int8 - Sound effects. 1 = disabled,
|
|
anything else is enabled. \| Sets the player's gameplay settings. \|- !
|
|
Set Prayers \| 227 \|\| \* int8... - The prayer's status. 1 = enabled,
|
|
anything else is disabled. \| Sets the status of every prayer. Variable
|
|
length. \|- ! Set Quests \| 226 \|\| \* int8... - The quest's completion
|
|
status. 1 = completed, anything else is incomplete. \| Sets the player's
|
|
quest completion status. Variable length. \|- ! Display Bank \| 222 \|\|
|
|
\* uint8 - The number of items in the player's bank. \* uint8 - The
|
|
maximum number of items the player is allowed to store. \* uint16... -
|
|
The item's id. \* int32a... - The item's stack size. \| Displays the
|
|
bank interface. Variable length. \|- ! Hide Bank \| 221 \|\| \* None \|
|
|
Hides the bank interface. \|- ! Bank Update \| 214 \|\| \* uint8 - The
|
|
item's slot. \* uint16 - The item's id. \* int32a - The item's stack
|
|
size. 0 to remove. \| Updates/adds/removes a single item in the bank
|
|
interface to save bytes. \|- ! Single XP Update \| 220 \|\| \* uint8 -
|
|
The skill's id. \* int32 - The skill's xp. \| Updates a single skill's
|
|
XP to save bytes. \|- ! Update InvItem \| 213 \|\| \* uint8 - The item's
|
|
slot. \* uint16 - The item's id. Increment by 0x7fff to change stack
|
|
size. \* int32a - The item's stack size. May not be read. \| Adds a
|
|
single item, or changes the ID, or changes the stack size to save bytes.
|
|
If id / 32768 == 1, the item is equipped. \|- ! Remove InvItem \| 212
|
|
\|\| \* uint8 - The item's slot. \| Removes a single item from the
|
|
player's inventory to save bytes. \|- ! Single Skill Update \| 211 \|\|
|
|
\* uint8 - The skill's id. \* uint8 - The skill's current level. \*
|
|
uint8 - The skill's base level. \* int32 - The skill's experience
|
|
points. \| Updates a single skill to save bytes. \|- ! Play Sound \| 207
|
|
\|\| \* byte\[\] - The name of the sound. \| Plays a sound/audio file in
|
|
the client. \|- ! Open Character Design Panel \| 203 \|\| \* None. \|
|
|
Open the character design panel. \|- \|} === '''Outgoing Data''' ===
|
|
'''TODO: recovery questions''' {\| class="wikitable" \|- ! scope="col"
|
|
width="140px" \| Name ! scope="col" width="50px" \| Opcode ! scope="col"
|
|
width="350px" \| Payload ! scope="col" width="300px" \| Description \|-
|
|
! Login \| 0 \|\| \* See \[\[135 Protocol\#Login\|Login\]\] \| Logs the
|
|
player in. \|- ! Reconnect \| 19 \|\| \* See \[\[135
|
|
Protocol\#Login\|Login\]\] \| Reconnects the player after they are
|
|
disconnected. \|- ! Disconnect \| 1 \|\| \* None \| Sent after the
|
|
server sends Close Connection (opcode 9), possibly to notify the server
|
|
that the player is to be removed. \|- ! Newplayer (Registration) \| 2
|
|
\|\| \* See \[\[135 Protocol\#Registration\|Registration\]\] \|
|
|
Registers a new user. \|- ! Public Chat \| 3 \|\| \* String - The
|
|
encoded message. \| Sends a message to public chat. \|- ! Ping \| 5 \|\|
|
|
\* None \| Ping \|- ! Attempt Logout \| 6 \|\| \* None \| Inform the
|
|
server that the client is attempting to log out \|- ! Admin Command \| 7
|
|
\|\| \* String - The command \| Sends a command to the server to be
|
|
executed \|- ! Report Abuse \| 10 \|\| \* int64 - The mod37 encoded
|
|
username to report \| Sends an abuse report to the server \|- ! Change
|
|
Password \| 25 \|\| \* RSAString - Your old password + new password
|
|
encoded with RSA \* Old password substring -
|
|
RSAString.substring(0,20).trim() \* New password substring -
|
|
RSAString.substring(20, RSAString.length()).trim(); \| Is used to change
|
|
your password ingame \|- ! Add Friend \| 26 \|\| \* int64 - mod37
|
|
encoded username \| Adds a user to your friends list \|- ! Remove Friend
|
|
\| 27 \|\| \* int64 - The mod37 encoded username to report \| Removes a
|
|
user from your friends list \|- ! Private Message \| 28 \|\| \* int64 -
|
|
The mod37 encoded username to send the message to \* String - The
|
|
message, scrambed \| Sends a message to the specified user \|- ! Ignore
|
|
User \| 29 \|\| \* int64 - The mod37 encoded username to ignore \| Adds
|
|
a user to your ignore list \|- ! Remove Ignore \| 30 \|\| \* int64 -
|
|
mod37 encoded username \| Removes a user from your ignore list \|- !
|
|
Update Privacy Settings \| 31 \|\| \* int8 - 1 to block public chat \*
|
|
int8 - 1 to block private chat \* int8 - 1 to block trade requests \*
|
|
int8 - 1 to block duel requests \| Updates the privacy settings \|- !
|
|
Walk to Tile \| 255 \|\| \* int16 - (start\_x + area\_x). The initial
|
|
position. \* int16 - (start\_y + area\_y) \* int8... - (route\_x\[i\] -
|
|
start\_x) \* int8... - (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. \|- ! Player Response \|
|
|
254 \|\| \* int16 - The number of players sent \* int16... - The
|
|
player's server index \* int16... - The player's status, as sent with
|
|
the appearance update packet \| Variable length. Informs the server of
|
|
players the client knows about after a positions/movement update packet.
|
|
\|- ! Drop Item \| 251 \|\| \* int16 - The slot of the item to drop \|
|
|
Drops the specified item on the ground \|- ! Cast on Item \| 220 \|\| \*
|
|
int16 - The slot of the item to cast a spell on \* int16 - The id of the
|
|
spell to cast \| Casts a spell (such as High Alchemy) on the specified
|
|
item \|- ! Use with Item \| 240 \|\| \* int16 - The slot of the first
|
|
item to use \* int16 - 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 \|\| \* int16 - The slot of the item
|
|
to unequip \| Unequips the specified inventory item \|- ! Wear Item \|
|
|
249 \|\| \* int16 - The slot of the item to equip \| Equips the
|
|
specified inventory item \|- ! Item Command \| 246 \|\| \* int16 - The
|
|
slot of the item to use \| Buries, eats, etc the specified inventory
|
|
item \|- ! Select Option \| 237 \|\| \* int8 - The position of the
|
|
option in the dialog\_options array \| Selects an option in a NPC dialog
|
|
\|- ! Combat Style \| 231 \|\| \* int8 - The position of the combat
|
|
style in the list \| Sets the player's combat style. \* 0 - Controlled
|
|
\* 1 - Aggressive \* 2 - Accurate \* 3 - Defensive \|- ! Close Bank \|
|
|
207 \|\| \* None \| Informs the server that the player has closed the
|
|
banking interface. \|- ! Withdraw Item \| 206 \|\| \* int16 - The ID of
|
|
the item to withdraw \* int16 - The amount of the specified item to
|
|
withdraw \| Withdraws a single type of item from the player's bank. \|-
|
|
! Deposit Item \| 205 \|\| \* int16 - The ID of the item to deposit \*
|
|
int16 - The amount of the specified item to deposit \| Deposits a single
|
|
type of item into the player's bank. \|- ! Disable Prayer \| 211 \|\| \*
|
|
int8 - The ID of the prayer to disable \| Disables a prayer. \|- !
|
|
Enable Prayer \| 212 \|\| \* int8 - The ID of the prayer to enable \|
|
|
Enables a prayer. \|- ! Update Game Setting \| 213 \|\| \* int8 - The
|
|
setting type \* int8 - The setting value (1 or 0) \| Setting types: \* 0
|
|
- Camera angle mode (auto/manual) \* 1 - Number of mouse buttons (1/2)
|
|
\* 2 - Sound effects (off/on) \|- ! 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 \|\| \* int8 - The
|
|
amount of traded items to send to the server \* int16... - The id of the
|
|
item \* int32... - The amount/stack size of the item \| Variable length.
|
|
Updates the trade offer. \|- ! Cast on GItem \| 224\* \|\| \* int16 -
|
|
The item's X coordinate \* int16 - The item's Y coordinate \* int16 -
|
|
The item's ID \* int16 - The spell's ID \| Casts a spell on an item on
|
|
the ground. \|- ! Use with GItem \| 250\* \|\| \* int16 - The item's X
|
|
coordinate \* int16 - The item's Y coordinate \* int16 - The item's ID
|
|
\* int16 - The inventory slot \| Uses an item in the player's inventory
|
|
with an item on the ground. \|- ! Take GItem \| 252\* \|\| \* int16 -
|
|
The item's X coordinate \* int16 - The item's Y coordinate \* int16 -
|
|
The item's ID \| Picks up an item on the ground. \|- ! Cast on Boundary
|
|
\| 223\* \|\| \* int16 - The bound's X coordinate \* int16 - The bound's
|
|
Y coordinate \* int8 - The bound's direction \* int16 - The spell's ID
|
|
\| Casts a spell on a boundary (or 'wall object'). \|- ! Use with
|
|
Boundary \| 239\* \|\| \* int16 - The bound's X coordinate \* int16 -
|
|
The bound's Y coordinate \* int8 - The bound's direction \* int16 - The
|
|
inventory slot \| Uses an item in the player's inventory with a boundary
|
|
(or 'wall object'). \|- ! Boundary Cmd 1 \| 238\* \|\| \* int16 - The
|
|
bound's X coordinate \* int16 - The bound's Y coordinate \* int8 - The
|
|
bound's direction \| Performs the primary action (usually 'open') on a
|
|
boundary (or 'wall object'). \|- ! Boundary Cmd 2 \| 229\* \|\| \* int16
|
|
- The bound's X coordinate \* int16 - The bound's Y coordinate \* int8 -
|
|
The bound's direction \| Performs the secondary action (usually 'close'
|
|
or 'picklock') on a boundary (or 'wall object'). \|- ! Cast on Object \|
|
|
222\* \|\| \* int16 - The object's X coordinate \* int16 - The object's
|
|
Y coordinate \* int16 - The spell's ID \| Casts a spell on an object.
|
|
\|- ! Use with Object \| 241\* \|\| \* int16 - The object's X coordinate
|
|
\* int16 - The object's Y coordinate \* int16 - The inventory slot \|
|
|
Uses an item in the player's inventory with an object. \|- ! Object Cmd
|
|
1 \| 241\* \|\| \* int16 - The object's X coordinate \* int16 - The
|
|
object's Y coordinate \| Performs the primary action on an object (for
|
|
example, 'mine'). \|- ! Object Cmd 2 \| 230\* \|\| \* int16 - The
|
|
object's X coordinate \* int16 - The object's Y coordinate \| Performs
|
|
the secondary action on an object (for example, 'prospect'). \|- ! Cast
|
|
on NPC \| 225\* \|\| \* int16 - The NPC's server index \* int16 - The
|
|
spell's ID \| Casts a spell on a non-player character. \|- ! Use with
|
|
NPC \| 243\* \|\| \* int16 - The NPC's server index \* int16 - The
|
|
inventory slot \| Uses an item in the player's inventory with a
|
|
non-player character. \|- ! Talk to NPC \| 245\* \|\| \* int16 - The
|
|
NPC's server index \| Starts talking to a non-player character. \|- !
|
|
Attack NPC \| 244\* \|\| \* int16 - The NPC's server index \| Starts
|
|
attacking a non-player character. \|- ! NPC Cmd 2 \| 195\* \|\| \* int16
|
|
- The NPC's server index \| Performs the secondary action on a
|
|
non-player character, usually 'pickpocket'. \|- ! Cast on Self \| 227
|
|
\|\| \* int16 - The spell's ID \| Cast a teleport or charge spell on the
|
|
local player. \|- ! Cast on Player \| 226\* \|\| \* int16 - The player's
|
|
server index \* int16 - The spell's ID \| Casts a spell on another
|
|
player. \|- ! Use with Player \| 219\* \|\| \* int16 - The player's
|
|
server index \* int16 - The inventory slot \| Uses an item (for example,
|
|
a Gnomeball, or a Christmas cracker) on another player. \|- ! Attack
|
|
Player \| 228\* \|\| \* int16 - The player's server index \| Starts
|
|
attacking another player. \|- ! Trade Player \| 235 \|\| \* int16 - The
|
|
player's server index \| Sends a trade request to another player. \|- !
|
|
Follow Player \| 214 \|\| \* int16 - The player's server index \| Starts
|
|
following another player. \|- ! Duel Player \| 204 \|\| \* int16 - The
|
|
player's server index \| Sends a duel request to another player. \|- !
|
|
RuntimeException \| 17 \|\| \* String - The text of the error. \| Sent
|
|
when the client throws an exception while processing data sent by the
|
|
server. \|- ! Confirm Duel Offer \| 198 \|\| \* None \| Confirms the
|
|
duel offer. \|- ! Accept Duel Offer \| 199 \|\| \* None \| Accepts the
|
|
duel offer. \|- ! Duel Settings \| 200 \|\| \* int8 - No retreating, 1
|
|
or 0 \* int8 - No magic, 1 or 0 \* int8 - No prayers, 1 or 0 \* int8 -
|
|
No weapons, 1 or 0 \| Updates the duel settings. \|- ! Duel Items \| 201
|
|
\|\| \* int8 - The total number of offered items \* int16... - Offered
|
|
item ID \* int32... - Offered item stack size \| Variable length.
|
|
Updates the stake. \|- ! Decline Duel Offer \| 203 \|\| \* None \|
|
|
Declines the duel offer. \|- ! Character Design \| 236 \|\| \* int8 -
|
|
The player's gender - 2=Female, 1=Male \* int8 - The player's hair style
|
|
\* int8 - The player's 'body type' - 4=Female, 1=Male \* int8 - The
|
|
player's 'leg type' - always 2 \* int8 - The player's hair colour \*
|
|
int8 - The player's top colour \* int8 - The player's leg colour \* int8
|
|
- The player's skin colour \* int8 - The player's class \| Submits the
|
|
player's chosen design when they log in for the first time. \* 0 -
|
|
Adventurer class \* 1 - Warrior class \* 2 - Wizard class \* 3 - Ranger
|
|
class \* 4 - Miner class \|} Notes:
|
|
|
|
* 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.
|