Old Engine/Login Protocol: Difference between revisions
From RuneWiki
No edit summary |
No edit summary |
||
Line 3: | Line 3: | ||
==Resources== | ==Resources== | ||
[[Data Types]] | [[Data Types]] | ||
[[Old Engine/File Archive]] | |||
==Handshaking== | ==Handshaking== | ||
The client begins by sending a single byte, 14. | |||
The server should then send 8 bytes as a response to initiate the response. These bytes are ignored, but should be all 0s anyways. | |||
Following that the server needs to send a response code of 0, followed by a random 64-bit number that will be used as part of the ISAAC seed. | |||
== Connection == | |||
Packet 16. | |||
Structure: | |||
* Packet length: Byte | |||
* Magic number: 255 (Byte) | |||
* Client version: Word | |||
* Memory type: Byte (Highmem / Lowmem) | |||
* CRCs: 9 DWords, CRC of all .idx0 File Archives loaded by the client | |||
* RSA length: Byte | |||
* '''After this point the remaining bytes must be decrypted!''' | |||
* RSA magic number: 10 (Byte) - this is used to check if the block was correctly decrypted | |||
* Client ISAAC seed: QWord | |||
* Server ISAAC seed: QWord | |||
* Client UID: DWord - ID to track client/player installations (can be changed client-side by deleting uid.dat and relaunching) | |||
* Username: String | |||
* Password: String | |||
Both client and server ISAAC seeds should be combined into a complete 16-byte seed for ISAAC to use. | |||
The decryptor ISAAC (used while reading packets from the client) should be initialized as-is from the ISAAC seed. | |||
The encryptor ISAAC (used while sending packets to the client) should have 50 added to every 4-bytes of the ISAAC seed and then initialized, e.g.<syntaxhighlight lang="javascript"> | |||
let clientIsaac = data.readQWord(); | |||
let serverIsaac = data.readQWord(); | |||
let sessionDecoder = [ | |||
(clientIsaac.shiftRight(32).toInt()), | |||
(clientIsaac.toInt()), | |||
(serverIsaac.shiftRight(32).toInt()), | |||
(serverIsaac.toInt()) | |||
]; | |||
let sessionEncoder = [ | |||
(clientIsaac.shiftRight(32).toInt()) + 50, | |||
(clientIsaac.toInt()) + 50, | |||
(serverIsaac.shiftRight(32).toInt()) + 50, | |||
(serverIsaac.toInt()) + 50 | |||
]; | |||
</syntaxhighlight> | |||
== Reconnection == | |||
Packet 18. Same as [[Old Engine/Login Protocol#Connection|Connection]]. | |||
== Responses == | |||
=== 0 === | |||
Continue to exchange login information (packet 16 or 18). | |||
=== 1 === | |||
Waits for 2000ms and tries again. | |||
=== 2 === | |||
Successful login. | |||
You will also need to send the privilege level (0 to 2), and a single byte (1 or 0) that tells the client to send additional input information during the game session. This was used to flag suspected bot behavior. | |||
Privilege levels: | |||
* 0: Normal player | |||
* 1: PMod | |||
* 2: JMod | |||
=== 3 === | |||
"Invalid username or password" | |||
=== 4 === | |||
"Your account has been disabled. Please check your message-center for details." | |||
=== 5 === | |||
"Your account is already logged in. Try again in 60 secs..." | |||
=== 6 === | |||
"RuneScape has been updated! Please reload this page." | |||
=== 7 === | |||
"This world is full. Please use a different world." | |||
=== 8 === | |||
"Unable to connect. Login server offline." | |||
=== 9 === | |||
"Login limit exceeded. Too many connections from your address." | |||
=== 10 === | |||
"Unable to connect. Bad session id." | |||
=== 11 === | |||
"Login server rejected session. Please try again." | |||
=== 12 === | |||
"You need a members account to login to this world. Please subscribe, or use a different world." | |||
=== 13 === | |||
"Could not complete login. Please try using a different world." | |||
=== 14 === | |||
"The server is being updated. Please wait 1 minute and try again." | |||
=== 15 === | |||
Successful reconnection. | |||
=== 16 === | |||
"Login attempts exceeded. Please wait 1 minute and try again." | |||
=== 17 === | |||
"You are standing in a members-only area. To play on this world move to a free area first." | |||
=== 20 === | |||
"Invalid loginserver requested. Please try using a different world." | |||
=== 21 === | |||
"You have only just left another world. Your profile will be transferred in: (number) seconds." | |||
=== -1 === | |||
Waits for 2000 ms and tries again while counting failures. | |||
=== Others === | |||
Any other response code will be unrecognized by the client and display "Unexpected server response. Please try using a different world." |
Revision as of 00:22, 7 September 2021
Resources
Handshaking
The client begins by sending a single byte, 14.
The server should then send 8 bytes as a response to initiate the response. These bytes are ignored, but should be all 0s anyways.
Following that the server needs to send a response code of 0, followed by a random 64-bit number that will be used as part of the ISAAC seed.
Connection
Packet 16.
Structure:
- Packet length: Byte
- Magic number: 255 (Byte)
- Client version: Word
- Memory type: Byte (Highmem / Lowmem)
- CRCs: 9 DWords, CRC of all .idx0 File Archives loaded by the client
- RSA length: Byte
- After this point the remaining bytes must be decrypted!
- RSA magic number: 10 (Byte) - this is used to check if the block was correctly decrypted
- Client ISAAC seed: QWord
- Server ISAAC seed: QWord
- Client UID: DWord - ID to track client/player installations (can be changed client-side by deleting uid.dat and relaunching)
- Username: String
- Password: String
Both client and server ISAAC seeds should be combined into a complete 16-byte seed for ISAAC to use.
The decryptor ISAAC (used while reading packets from the client) should be initialized as-is from the ISAAC seed.
The encryptor ISAAC (used while sending packets to the client) should have 50 added to every 4-bytes of the ISAAC seed and then initialized, e.g.
let clientIsaac = data.readQWord();
let serverIsaac = data.readQWord();
let sessionDecoder = [
(clientIsaac.shiftRight(32).toInt()),
(clientIsaac.toInt()),
(serverIsaac.shiftRight(32).toInt()),
(serverIsaac.toInt())
];
let sessionEncoder = [
(clientIsaac.shiftRight(32).toInt()) + 50,
(clientIsaac.toInt()) + 50,
(serverIsaac.shiftRight(32).toInt()) + 50,
(serverIsaac.toInt()) + 50
];
Reconnection
Packet 18. Same as Connection.
Responses
0
Continue to exchange login information (packet 16 or 18).
1
Waits for 2000ms and tries again.
2
Successful login.
You will also need to send the privilege level (0 to 2), and a single byte (1 or 0) that tells the client to send additional input information during the game session. This was used to flag suspected bot behavior.
Privilege levels:
- 0: Normal player
- 1: PMod
- 2: JMod
3
"Invalid username or password"
4
"Your account has been disabled. Please check your message-center for details."
5
"Your account is already logged in. Try again in 60 secs..."
6
"RuneScape has been updated! Please reload this page."
7
"This world is full. Please use a different world."
8
"Unable to connect. Login server offline."
9
"Login limit exceeded. Too many connections from your address."
10
"Unable to connect. Bad session id."
11
"Login server rejected session. Please try again."
12
"You need a members account to login to this world. Please subscribe, or use a different world."
13
"Could not complete login. Please try using a different world."
14
"The server is being updated. Please wait 1 minute and try again."
15
Successful reconnection.
16
"Login attempts exceeded. Please wait 1 minute and try again."
17
"You are standing in a members-only area. To play on this world move to a free area first."
20
"Invalid loginserver requested. Please try using a different world."
21
"You have only just left another world. Your profile will be transferred in: (number) seconds."
-1
Waits for 2000 ms and tries again while counting failures.
Others
Any other response code will be unrecognized by the client and display "Unexpected server response. Please try using a different world."