From 2f7502f346a61114c7df002215bfe9ce2cc38b17 Mon Sep 17 00:00:00 2001 From: PureCS Date: Tue, 3 Jul 2018 05:59:44 -0700 Subject: [PATCH] Add data section + rewrite them --- src/Archive-Format.md | 245 ++++++++++++++++++++++++--------------- src/DWord.md | 5 +- src/Data-Types.md | 133 +++++++++++---------- src/Data.md | 7 ++ src/Home.md | 6 +- src/JAGGRAB-Protocol.md | 60 +++++----- src/OB3.md | 42 ++++--- src/Ondemand-Protocol.md | 36 +++--- src/QWord.md | 7 +- src/RS-String.md | 20 ++-- src/SUMMARY.md | 18 +-- src/Word.md | 7 +- 12 files changed, 348 insertions(+), 238 deletions(-) create mode 100644 src/Data.md diff --git a/src/Archive-Format.md b/src/Archive-Format.md index e8bc1ec..484202f 100644 --- a/src/Archive-Format.md +++ b/src/Archive-Format.md @@ -1,156 +1,217 @@ -\[\[Category Cache\]\] +# Archive format -== Introduction == +From client revision 194 until 377, all the files in cache 0 +are in an archive-like format which contains a collection of named +files (e.g. `BADENC.TXT` is a file which contains bad words in the +`wordenc` archive). -Since 194 all way up until 377, all the files in cache 0 have an -archive-like format which contains a collection of named files (e.g. -'''BADENC.TXT''' is a file which contains bad words in the '''wordenc''' -archive). +## Usage -=== Diagram === +These files are used by the client for a variety of purpose. ------------------------------------------------------------------------- +The files themselves represent either an index, which contains +information about to where to locate data in the cache, and +the data themselves. -\[http://img263.imageshack.us/img263/9678/68481568.png External Diagram -Image\] +e.g. `DATA` contains data for interfaces. -== Usage == +e.g. `MAP_INDEX` contains information about where to find the map and landscape files in the cache. -These files are used by the client for a variety of purposes. Some, such -as the '''DATA''' file contain data themselves (in this case the -interfaces). Others, such as the '''MAP\_INDEX''' file, contain -information about where to locate the map and landscape files in the -cache. +## Format -== Format == - -tribyte uncompressedsize tribyte compressedsize +``` +tribyte uncompressedSize +tribyte compressedSize +``` If the uncompressed and compressed sizes are equal, the whole file is -not compressed but the individual entries are compressed using bzip2. If -they are not equal, the entire file is compressed using bzip2 but the -individual entries are not. +not compressed but the individual entries are compressed using bzip2. +If they are not equal, the entire file is compressed using bzip2 but +the individual entries are not. -Also note, the magic id at the start of the bzip2 entries are not -included in the cache. If you use an existing API to read the files and -want to add this back, you must append the four characters: BZh1 before -you decompress. +Note: The magic id at the start of the bzip2 entries are not included +in the cache. +If you use an existing API to read the files and want to add this back, +you must append the characters `BZh1` before you decompress. -short fileCount +```short fileCount``` Each file entry has the format: -int nameHash tribyte uncompressedSize tribyte compressedSize +``` +int nameHash +tribyte uncompressedSize +tribyte compressedSize +``` -When you are looping through the files, you need to keep track of the -file offset yourself. This psuedocode demonstrates how: +# Extracting the data -int offset = buffer.getCurrentOffset() + numFiles \* 10; for(int i = 0; -i \< numFiles; i++) { // read values int thisFileOffset = offset; offset -+= thisFileCompressedSize; } +If you iterate over the files using a for-loop, you need to keep track of the +file offset. +The following pseudo-code demonstates how: -To get a named file by its name, you should first hash the name using -this method: +```java +int offset = buffer.getCurrentOffset() + numFiles * 10; -public static int hash(String name) { int hash = 0; name = -name.toUpperCase(); for(int j = 0; j \< name.length(); j++) { hash = -(hash \* 61 + name.charAt(j)) - 32; } return hash; } +for(int i = 0; i < numFiles; i++) { + // read values + int thisFileOffset = offset; + offset += thisFileCompressedSize; +} +``` + +To acquire a named file using its name, hash the name as follows: + +```java +public static int hash(String name) { + int hash = 0; + name = name.toUpperCase(); + + for(int j = 0; j < name.length(); j++) { + hash = (hash * 61 + name.charAt(j)) - 32; + } + return hash; +} +``` Then, loop through the file entries you loaded earlier to find a matching hash. Read the compressed file size from the offset. If the whole file is not compressed, you should decompress the individual entry. -== '''\#194 Archive Format''' == +## \#194 Archive Format -The 194 (RuneScape 2 beta) client worked with a very simple cache -format. Each file in the cache was a file on the operating system. +The \#194 (RuneScape 2 beta) client worked with a very simple cache +format. +Each file in the cache corresponded to a file on the operating system. -=== Name hashing === +### Name hashing Every name in the cache was hashed using the following method which is, incidentally, similar to the way player names are converted to longs. -public static final long gethash(String string) { string = -string.trim(); long l = 0L; for (int i = 0; i \< string.length() && i \< -12; i++) { char c = string.charAt(i); l \*= 37L; if (c \>= 'A' && c \<= -'Z') l += (long) ('\\001' + c - 'A'); else if (c \>= 'a' && c \<= 'z') l -+= (long) ('\\001' + c - 'a'); else if (c \>= '0' && c \<= '9') l += -(long) ('\\033' + c - '0'); } return l; } +```java +public static final long gethash(String string) { + string = string.trim(); + long l = 0L; + + for (int i = 0; i < string.length() && i < 12; i++) { + char c = string.charAt(i); + l \*= 37L; + + if (c >= 'A' && c <= 'Z') + l += (long) ('\\001' + c - 'A'); + else if (c >= 'a' && c <= 'z') + l += (long) ('\\001' + c - 'a'); + else if (c >= '0' && c <= '9') + l += (long) ('\\033' + c - '0'); + } + return l; +} +``` The resulting long was converted to a string and the file was given that name. -=== Files === +### Files -The files in the cache were the ones used in the \[\[JAGGRAB -Protocol\|JAGGRAB Protocol\]\] (i.e. files in cache 0 in old engine -caches) and map (mX\_Y) and landscape (lX\_Y) files. Incidentally, this -naming is very similar to the names of the map and landscape files in -new engine caches. +The files in the cache were the ones used in the [JAGGRAB protocol](./JAGGRAB-Protocol.html) (i.e. files in cache 0 in old engine caches), + map (mX_Y), and landscape (lX_Y) files. -== '''\#317 Archive Format''' == +Incidentally, this naming is very similar to the names of the map and +landscape files in new engine caches. + +## \#317 Archive Format The old engine cache is made up two types of files. -=== Data file === +### Data file The data file holds all of the files in the cache and is named -'''main\_file\_cache.dat'''. It is therefore very big, typically \~10-20 -megabytes.. +`main_file_cache.dat`. +It is therefore very big, typically ~10-20MB in size. -=== Index file === +### Index file -There are several index files, named '''main\_file\_cache.idx''' and -then postfixed with a number. Each index file holds 'pointers' to where -a file is located in the main cache. Each index file represents a type -of file. +There are several index files, named `main_file_cache.idx` and +then post-fixed with a number. +Each index file holds 'pointers' to where a file is located in +the main cache. +Each index file represents a type of file. -=== Index file format === +### Index file format -The index file is made up of 6 byte blocks which hold information about -where a file can be located in the data file. The format of a single -block is as follows: +The index file is comprised of a collection of six byte blocks which hold +information about where a file can be located in the data file. -tribyte fileSize tribyte initialDataBlockId +The format of a single block is as follows: +``` +tribyte fileSize +tribyte initialDataBlockId +``` -=== Data file format === +### Data file format -The data file is made up of 520 byte blocks. The format of each of these -blocks is as follows: +The data file is comprised of a collection of 520 byte blocks. -short nextFileId short currentFilePartId tribyte nextDataBlockId byte -nextFileTypeId byte\[512\] blockData +The format of each of these blocks is as follows: -=== Explanation === +``` +short nextFileId +short currentFilePartId +tribyte nextDataBlockId +byte nextFileTypeId +byte[512] blockData +``` -An example will be used here as it is easier to follow. +### Running example -Let us say, the client wishes to fetch file type 2, file id 17. +Suppose, the client wishes to fetch file type 2, file id 17. -First off, it will open the main\_file\_cache.idx2 file and seek to the -index 17 \* 6 (102). It will then read two tribytes. +First off, it will open the `main_file_cache.idx2` file and seek to the +index `17 * 6` (102). +It will then read the two tribytes: +``` +fileSize = 1200 +intialDataBlockId = 4 +``` -fileSize = 1200 intialDataBlockId = 4 +The client will now open the `main_file_cache.dat` file and seek to the +index `4 * 520` (2080). -The client will now open the main\_file\_cache.dat file and seek to the -index 4 \* 520 (2080). The values it reads will be: - -nextFileId = 17 currentFilePartId = 0 nextDataBlockId = 5 nextFileTypeId -= 2 blockData = ... +It will then read the following: +``` +nextFileId = 17 +currentFilePartId = 0 +nextDataBlockId = 5 +nextFileTypeId = 2 +blockData = ... // 512 bytes of data +``` It will read the first 512 bytes of the file and then knows that there -is 688 bytes left. Therefore, it has to read the next block. +is 688 bytes left. -nextFileId = 17 currentFilePartId = 1 nextDataBlockId = 6 nextFileTypeId -= 2 blockData ... +Therefore, it has to read the next block: +``` +nextFileId = 17 +currentFilePartId = 1 +nextDataBlockId = 6 +nextFileTypeId = 2 +blockData ... // 512 bytes of data +``` It reads these next 512 bytes of the file and now knows that there are -176 bytes left. So for a final time, it will read the next block. +176 bytes left. -nextFileId = 18 currentFilePartId = 2 nextDataBlockId = 7 nextFileTypeId -= 2 blockData = ... +So for a final time, it will read the next block: +``` +nextFileId = 18 +currentFilePartId = 2 +nextDataBlockId = 7 +nextFileTypeId = 2 +blockData = ... // 176 bytes of data +``` It can ignore most of these values (the next ones are meaningless at -this stage) and read the final 176 bytes. The whole 1200 byte file has -now been read. +this stage) and read the final 176 bytes. +The whole 1200 byte file has now been read. diff --git a/src/DWord.md b/src/DWord.md index 77b1d9c..af1b346 100644 --- a/src/DWord.md +++ b/src/DWord.md @@ -1,3 +1,4 @@ -A "DWord" (double-word) is a data-type that consists of 4 bytes.
+# DWord + +A "DWord" (double-word) is a data-type that consists of 4 bytes. It is also commonly known as the "int" data-type in programming. -\[\[Category Data Type\]\] diff --git a/src/Data-Types.md b/src/Data-Types.md index 70df5b6..ee65d0f 100644 --- a/src/Data-Types.md +++ b/src/Data-Types.md @@ -1,85 +1,96 @@ -== Introduction == +# Data types -RuneScape uses a number of standard and non-standard data types. +RuneScape uses a number of common and bespoke data types in the +process of data transmission. -== Byte Order == +## Byte Order Data types that are two bytes or larger can be stored and ordered in a -variety of different ways. Generally people either use big endian or -little endian. +variety of different ways. +The traditional byte orders are big endian and little endian. +Generally people either use big endian or little endian. -=== Big Endian === +RuneScape uses both little and big-endian byte orders throughout the +protocol (however, the 194 client only uses big-endian order). +This presumably to make reverse-engineering of the protocol harder. + +Note: Some confusion has arisen over the byte order as the data types +are named incorrectly in Winterlove's server where little endian data +types are incorrectly named as big endian types. + +### Big Endian In big endian order, the most significant byte (MSB) is stored first and the least significant byte (LSB) is stored last. -=== Little Endian === +### Little Endian In little endian order, the least significant byte (LSB) is stored first and the most significant byte (MSB) is stored last. -=== Byte order in RuneScape === - -RuneScape uses both little and big-endian byte orders throughout the -protocol (however, the 194 client only uses big-endian order), -presumably to make reverse-engineering of the protocol harder. Some -confusion has arisen over the byte order as the data types are named -incorrectly in \[\[Server Winterlove\|Winterlove\]\]'s server where -little endian data types are incorrectly named as big endian types. - -== Standard data types == These datatypes can also be read/written by a -DataWriter/DataReader implementation (DataStreams and Buffers) - -Naming conventions: {\| border=2 ! Official name ! Datatype name ! Jagex -name ! Encoding \|- \| Byte \| byte \| 1,1b \|- \| \[\[Word\|WORD\]\] \| -short \| 2,2b \|- \| \[\[DWord\|DWORD\]\] \| int,int32 \| 4,4b \|- \| -\[\[QWord\|QWORD\]\] \| long,int64 \| 8,8b \|- \| C style string \| -string,String,char *,char\[\] \| str,strbyte \| text bytes then '\n' or -10 \|- \| Java style string \| string,String,char *,char\[\] \| strraw -\| WORD length then text bytes \|} - -Note that \[\[Jagex\]\] used to use a new line character as string -terminator, in more recent versions they use the null character \\0 or 0 -to support multi-line strings. - -== Non Standard Data Types == - -{\| border=2 ! Winterlove's name ! Jagex name ! Read transformation ! -Write transformation \|- \| Special A \| Unknown \| value - 128 \| value -+ 128 \|- \| Special C \| Unknown \| 0 - value \| 0 - value \|- \| -Special S \| Unknown \| 128 - value \| 128 - value \|- \| SpaceSaverA \| -smarts \| (value\[0\] \< 128) ? (((value\[0\] - 128)\<\<8)+value\[1\]) : -value\[0\] \| if(value \< 128) putword(value+32768) else putbyte(value); -\|- \| SpaceSaverB \| smart \| (value\[0\] \< 128) ? value\[0\] - 64 \| -((value\[0\]\<\<8)+value\[1\]) - 49152 \| if(i \< 64 && i \>= -64) -putbyte(i + 64) else if(i \< 16384 && i \>= -16384) putword(i + 49152); -\|- \| tribyte / RGBColour / 3Byte / int3 / medium \| 3 \| (value\[0\] -\<\< 24) + (value\[1\] \<\< 16) + value\[2\] \| putbyte(value \>\> -24);putbyte(value \>\> 16);putbyte(value); \|- \| \[\[RS -String\|RS\_String\]\] \| jstr \| Old engine: read until newline -delimiter ("\n")
New engine: read until null byte (value 0). \| -Old engine: write and finish with newline delimiter ("\n")
New -engine: write and finish with null byte (value 0). \|} +## Bespoke Byte Orders Additionally, RuneScape also uses two endian orders for integers that -are different from a big- or low endian order. Both byte orders are -called middle-endian. +are different from a big- or low endian order. +We call these byte orders middle endian. -Their orders could be described as following: +### Middle Endian Big Int -Middle-endian big int: C3 D4 A1 B2 +The bytes are stored in the following order, where A1 is the smallest byte (I.e. LSB) and D4 the bigger (i.e. MSB): C3 D4 A1 B2. -Middle-endian small int: B2 A1 D4 C3 +### Middle Endian Small Int -Where A1 is the smallest byte (LSB), and D4 the biggest byte (MSB). +The bytes are stored in the following order, where A1 is the smallest byte (I.e. LSB) and D4 the bigger (i.e. MSB): B2 A1 D4 C3. -== Bit Access == +## Common data types -=== Initiating Bit Access === +These data types are traditional, hence they can typically be written +and read by a standard DataStream, or Buffer implementation. + +Naming conventions: + +| Standardized name | Data-type name | Jagex name | Encoding | +|---|---|---|---| +| Byte | byte | 1,1b | Bytes | +| [Word](./Word.md) | short | 2,2b | Bytes | +| [DWord](./DWord.md) | int, int32 | 2,2b | Bytes | +| [QWord](./QWord.md) | long, int64 | 8,8b | Bytes | +| C-style String | string, String, char*, char[] | str, strbyte | Text bytes followed by `\n` or the byte `10`. | +| Java-string String | string, String, char*, char[] | strraw | Length as a word, followed by the text bytes. | + +Note: In more recent versions of the client, C-style strings are terminated with the null character (i.e. `\0`) or the byte `0` to support multi-line strings. + +## Bespoke data types + +These data types are bespoke, that is, they were developed with the +sole intention of only being used within Jagex products. + +We presume that this is another technique employed to make +reverse-engineering and packet manipulation harder. + +Naming conventions: + +| Winterlove's name | Jagex name | Read transformation | Write transformation | +|---|---|---|---| +| Special A | Unknown | value - 128 | value + 128 | +| Special C | Unknown | 0 - value | 0 - value | +| Special S | Unknown | 128 - value | 128 - value | +| SpaceSaverA | smarts | `(value[0] < 128) ? (((value[0] - 128) << 8) + value[1]) : value[0]` | `if(value < 128) putword(value+32768) else putbyte(value);` | +| SpaceSaverB | smart | `(value[0] << 24) + (value[1] << 16) + value[2] ` | `putbyte(value >> 24); putbyte(value >> 16); putbyte(value); ` | +| Tribyte, RGBColour, 3Byte, int3, medium | 3 | `(value[0] << 24) + (value[1] << 16) + value[2]` | `putbyte(value >> 24); putbyte(value >> 16); putbyte(value); ` | +| [RS String](./RS-String.md) | jstr | Old engine: read until newline terminated ("\n"). New engine: read until null byte (value 0). | Old engine: write and finish with newline delimiter ("\n"). New engine: write and finish with null byte (value 0). | + +Note: The read transformation is the process which must be applied to +read data, to reconstruct the original. +The write transformation applies analogously, to when data is written. + +## Bit Access + +### Initiating Bit Access Whenever data is to be sent to the server or to the client using bits; -the stream needs to be prepared by setting the bit position. The bit -position can be calculated by multiplying the current buffer position by -8. This is because each byte is comprised of 8 bits. +the stream needs to be prepared by setting the bit position. +The bit position can be calculated by multiplying the current buffer +position by 8. This is because each byte is comprised of 8 bits. -Example: int bitPos = bufferPos \* 8; +e.g. `int bitPos = bufferPos * 8;` diff --git a/src/Data.md b/src/Data.md new file mode 100644 index 0000000..1b02c11 --- /dev/null +++ b/src/Data.md @@ -0,0 +1,7 @@ +# Data + +This section covers the raw data-related facilities and systems within the Client. + +This includes an overview of the [data-types](./Data-Types.md) used, as well as +protocols like [JAGGRAB Protocol](./JAGGRAB-Protocol.md) and +[Ondemand Protocol](./Ondemand-Protocol.md). diff --git a/src/Home.md b/src/Home.md index 48760fb..2259021 100644 --- a/src/Home.md +++ b/src/Home.md @@ -16,9 +16,9 @@ A source of documentation for the RSC/RS2/RS3 protocols and related systems. * [[RS3|Category RS3]] (2013 - present) ### Cache -* [[JAGGRAB|JAGGRAB Protocol]] -* [[Ondemand|Ondemand Protocol]] -* [[Archive Format]] +* [JAGGRAB protocol](./JAGGRAB-Protocol.html) +* [Ondemand protocol](./Ondemand-Protocol.html) +* [Archive format](./Archive-Format.html) ### Miscellaneous diff --git a/src/JAGGRAB-Protocol.md b/src/JAGGRAB-Protocol.md index 33ab657..7dbc88f 100644 --- a/src/JAGGRAB-Protocol.md +++ b/src/JAGGRAB-Protocol.md @@ -1,48 +1,54 @@ -\[\[Category Cache\]\] +# JAGGGRAB protocol -== Introduction == +# Introduction -The JAGGRAB protocol is used to 'grab' cache files from the file server -and download them. +In the early days of the client, it was distributed as an embedded +JAR within a web page. +So, reloading the web page would result in the user being served an up-to-date +client. +However, the cache files were stored locally and thus required a separate +mechanism for updating. + +The JAGGRAB protocol addresses this by updating the client's cache files. +It does this by 'grabbing' cache files from the file server and downloading them. It is a text-based protocol, similar to HTTP/0.9, and the client will -fall back to HTTP if JAGGRAB is unavailable. This generally happens in +fall-back to HTTP if JAGGRAB is unavailable. This generally happens in unsigned mode and helps users who are behind firewalls. -== Request format == +## Request format A request is simply the text JAGGRAB, a space, the path to the file and a newline character. Therefore, it is very similar to a HTTP/0.9 GET request. -JAGGRAB /path/to/file +e.g. `JAGGRAB /path/to/file`. -=== New engine === - -In (perhaps all) new engine clients, the client prefixes the JAGGRAB +Note: In possibly all new engine clients, the client prefixes the JAGGRAB request line with a single byte (value 17). -== Response format == +## Response format -The response is simply the raw file data. Once the response is sent, the -connection is closed. +The response is the file bytes. Once the response is sent, the connection +is closed. -== Files == +## Files There are a number of files which map to files in the cache. -- '''/crc''' - the CRC table -- '''/title''' - cache 0, file 1 -- '''/config''' - cache 0, file 2 -- '''/interface''' - cache 0, file 3 -- '''/media''' - cache 0, file 4 -- '''/versionlist''' - cache 0, file 5 -- '''/textures''' - cache 0, file 6 -- '''/wordenc''' - cache 0, file 7 -- '''/sounds''' - cache 0, file 8 +- `/crc` - the CRC table +- `/title` - cache 0, file 1 +- `/config` - cache 0, file 2 +- `/interface` - cache 0, file 3 +- `/media` - cache 0, file 4 +- `/versionlist` - cache 0, file 5 +- `/textures` - cache 0, file 6 +- `/wordenc` - cache 0, file 7 +- `/sounds` - cache 0, file 8 -NOTE: the client will usually postfix these with random numbers, so when +Note: the client will usually postfixes these with random numbers, so when checking for the file only the start of the string should be examined: -not the whole one. This is to help avoid caches when these files are -fetched over HTTP.
NOTE: The crc is postfixed with the client -revision +not the whole one. +This is to help avoid caches when these files are fetched over HTTP. + +Note: The crc is postfixed with the client revision. diff --git a/src/OB3.md b/src/OB3.md index 08809e4..74cd369 100644 --- a/src/OB3.md +++ b/src/OB3.md @@ -1,10 +1,17 @@ -\[\[Category RSC\]\] +# 0B3 -This page refers to .ob3, a custom format for 3D models created by -Jagex. It is used by the RuneScape Classic engine since client version -\#74. For the earlier version of the format see \[\[OB2\|OB2\]\]. +This page documents the `.ob3` format, a bespoke format for 3D models +created by Jagex. +It is used by the RuneScape Classic engine since client version +\#74. -
public class OB3Model {
+Note: There is also an earlier version of this format called `.ob2`.
+
+## OB3 Model Class
+The following is the fully renamed client code used to represent OB3 models.
+
+```java
+public class OB3Model {
 
     private static final int num_seq = 0xbc614e; // 12345678
     public int vertex_count;
@@ -104,26 +111,29 @@ Jagex. It is used by the RuneScape Classic engine since client version
         return i;
     }
 }
-
-== '''Faces''' == A '''negative''' face\_fill\_back or face\_fill\_front -value indicates a '''solid colour''', whereas a'''positive''' value -indicates a '''texture'''. The texture is defined by its offset in the -client's texture array. +``` -When converting to/from -\[http://en.wikipedia.org/wiki/Wavefront\_.obj\_file Wavefront OBJ\] +## Faces + +A negative face_fill_back or face_fill_front value indicates a solid colour, whereas a positive value indicates a texture. +The texture is defined by its offset in the client's texture array. + +When converting to/from [Wavefront OBJ](https://en.wikipedia.org/wiki/Wavefront_.obj_file) format, remember that the OB3 face vertices are one less than the OBJ face vertices. -
public static int decode_colour(int i) {
+The below code will allow you to encode or decode colours in this format.
+
+```java
+public static int decode_colour(int i) {
     i = -(i + 1);
     int r = i >> 10 & 0x1f;
     int g = i >> 5 & 0x1f;
     int b = i & 0x1f;
     return (r << 19) + (g << 11) + (b << 3);
 }
-
-
public static int encode_colour(int r, int g, int b) {
+
+public static int encode_colour(int r, int g, int b) {
     return -1 - (r / 8) * 1024 - (g / 8) * 32 - b / 8;
 }
-
+``` diff --git a/src/Ondemand-Protocol.md b/src/Ondemand-Protocol.md index 79e2f51..706db88 100644 --- a/src/Ondemand-Protocol.md +++ b/src/Ondemand-Protocol.md @@ -1,28 +1,34 @@ -\[\[Category Cache\]\] +# Ondemand protocol -== Introduction == +The Ondemand protocol is used to stream updates to the cache. +The client knows which files to update from the CRC file downloaded +using the [JAGGRAB Protocol](./JAGGRAB-Protocol.html). -The 'Ondemand' protocol is used to stream updates to the cache. The -client knows which files to update from the CRC file downloaded using -the \[\[JAGGRAB Protocol\|JAGGRAB protocol\]\]. - -== Request packet == +## Request format The client first authenticates as an ondemand client by using the opcode '15' (as opposed to the game, which uses the type '14'). The format of the request is: -unsigned byte cacheId; unsigned short fileId; unsigned byte priority; +``` +unsigned byte cacheId; +unsigned short fileId; +unsigned byte priority; +``` -There can be multiple requests per session. +Furthermore, there can be multiple requests per session. -== Response packet == +## Response format The response is sent in blocks. The maximum size of a block is 500 -bytes. Smaller blocks (at the end of a file) are permitted. +bytes. Smaller blocks (e.g. towards the end of a file) are permitted. -Each block has the format: - -unsigned byte cacheId; unsigned short fileId; unsigned short fileSize; -unsigned byte blockNumber; unsigned byte\[\] blockData; +The format of a block is: +``` +unsigned byte cacheId; +unsigned short fileId; +unsigned short fileSize; +unsigned byte blockNumber; +unsigned byte[] blockData; +``` diff --git a/src/QWord.md b/src/QWord.md index 181f51b..c5c3e2d 100644 --- a/src/QWord.md +++ b/src/QWord.md @@ -1,3 +1,4 @@ -A "QWord" (quad-word) is a data-type that consists of 8 bytes.
It -is also commonly known as the "long" data-type in programming. -\[\[Category Data Type\]\] +# QWord + +A "QWord" (quad-word) is a data-type that consists of 8 bytes. +It is also commonly known as the "long" data-type in programming. diff --git a/src/RS-String.md b/src/RS-String.md index c7a141b..b90857b 100644 --- a/src/RS-String.md +++ b/src/RS-String.md @@ -1,11 +1,15 @@ -== Introduction == +# RS String -RS String is a codename for a custom string data-type used in the -RuneScape protocol.
The string data-type is used to hold a series -of characters in order to form a message. +RS String is the internal name for a custom string data-type used in the +RuneScape protocol. +The string data-type stores a collection of characters in order to +represent a textual message. -===Old Engine Protocol=== In the old engine client, the RS String -datatype is delimited by a newline character (value "\n"). +## Old Engine -===New Engine Protocol=== In the new-engine client, the RS String -datatype is delimited by a null byte (value 0). +In the old engine client, the RS String datatype is terminated by the new line +character (i.e. `\n`). + +# New Engine + +In the new-engine client, the RS String datatype is terminated by a null byte (i.e. `0`). diff --git a/src/SUMMARY.md b/src/SUMMARY.md index 7ac4ee7..8e1f2e7 100644 --- a/src/SUMMARY.md +++ b/src/SUMMARY.md @@ -7,18 +7,20 @@ - [General disclaimer](./General-disclaimer.md) - [DMCA policy](./DMCA-policy.md) - [Privacy policy](./Privacy-policy.md) -- [Archive-Format](./Archive-Format.md) +- [Data](./Data.md) + - [Data-Types](./Data-Types.md) + - [Word](./Word.md) + - [DWord](./DWord.md) + - [QWord](./QWord.md) + - [RS String](./RS-String.md) + - [JAGGRAB protocol](./JAGGRAB-Protocol.md) + - [Ondemand protocol](./Ondemand-Protocol.md) + - [Archive format](./Archive-Format.md) + - [OB3](./OB3.md) - [Class-Check](./Class-Check.md) -- [Data-Types](./Data-Types.md) -- [DWord](./DWord.md) -- [JAGGRAB-Protocol](./JAGGRAB-Protocol.md) - [Map-Region-System](./Map-Region-System.md) -- [OB3](./OB3.md) -- [Ondemand-Protocol](./Ondemand-Protocol.md) -- [QWord](./QWord.md) - [RS-String](./RS-String.md) - [Template-Packet](./Template-Packet.md) -- [Word](./Word.md) - [135-Protocol](./135-Protocol.md) - [194-Clear-screen](./194-Clear-screen.md) - [194-Logout](./194-Logout.md) diff --git a/src/Word.md b/src/Word.md index 9b67c21..2ff0e2e 100644 --- a/src/Word.md +++ b/src/Word.md @@ -1,3 +1,4 @@ -A "word" is a data-type that consists of 2 bytes.
It is also -commonly known as the "short" data-type in programming. \[\[Category -Data Type\]\] +# Word + +A "word" is a data-type that consists of 2 bytes. +It is also commonly known as the "short" data-type in programming.