A read-only, high-level, virtual file API for the RuneScape cache.
This crate provides high performant data reads into the Oldschool RuneScape and RuneScape 3 cache file systems. It can read the necessary data to synchronize the client's cache with the server. There are also some loaders that give access to definitions from the cache such as items or npcs.
For read-heavy workloads, a writer can be used to prevent continuous buffer allocations. By default every read will allocate a writer with the correct capacity.
RuneScape's chat system uses huffman coding to compress messages. In order to decompress them this library has
a Huffman
implementation.
When a RuneScape client sends game packets the id's are encoded and can be decoded with the IsaacRand
implementation. These id's are encoded by the client in a predictable random order which can be reversed if
the server has its own IsaacRand
with the same encoder/decoder keys. These keys are sent by the client
on login and are user specific. It will only send encoded packet id's if the packets are game packets.
Note that this crate is still evolving; both OSRS & RS3 are not fully supported/implemented and will probably contain bugs or miss core features. If you require features or find bugs consider opening an issue.
Useful links:\
Releases\
Documentation\
Examples
In order to read bytes in a high performant way the cache uses memmap2. This can be unsafe because of its potential for Undefined Behaviour when the underlying file is subsequently modified, in or out of process. Using Mmap
here is safe because the RuneScape cache is a read-only binary file system. The map will remain valid even after the File
is dropped, it's completely independent of the File
used to create it. Therefore, the use of unsafe is not propagated outwards. When the Cache
is dropped memory will be subsequently unmapped.
The cache's protocol defaults to OSRS. In order to use the RS3 protocol you can enable the rs3
feature flag.
A lot of types derive serde's Serialize
and Deserialize
. The serde-derive
feature flag can be used to enable (de)serialization on any compatible types.
```rust use rscache::Cache;
fn main() -> rscache::Result<()> { let cache = Cache::new("./data/osrs_cache")?;
let index_id = 2; // Config index.
let archive_id = 10; // Archive containing item definitions.
let buffer: Vec<u8> = cache.read(index_id, archive_id)?;
Ok(())
} ```
The osrs specifications and rs3 specifications documents contain a detailed description of the design of the corresponding cache for educational purposes. Both documents are still a work in progress and are possibly incomplete.
Integration tests are running on Oldschool RuneScape version 180, which you can run at any time because the cache is included in the ./data/osrs_cache
directory. RS3 Integration tests are running on version 904. The RS3 cache is too large to include on GitHub.
This crate is marked as experimental. I will implement additional features once I need them for my own project. If you require a certain feature feel free to open an issue.
Add this to your Cargo.toml
:
toml
[dependencies]
rs-cache = "0.7"
Examples can be found in the examples directory which include both update protocols.
The following sources aided with the development of this crate:\
OpenRS\
RuneLite\
OSRS Cache Parsing Blog\
RSMod\
Librsfs\
OSRSBox\
Jagex-Store-5\
Matrix 876
rs-cache
is distributed under the terms of the MIT license.
See LICENSE for details.