2 releases
0.1.1 | Nov 3, 2023 |
---|---|
0.1.0 | Nov 3, 2023 |
#1764 in Encoding
26KB
488 lines
gsi-cs2-rs
Ready-to-use structures for serializing data from Counter Strike 2 GSI
Info
Documentation can be found here.
Examples can be found here.
GSI wiki and guide, it's a bit outdated, but "this is fine".
Examples
All examples in the repository are using the poem framework server. But you can use any other alternatives, for example, axum :)
The first thing you will probably want to do is enable GSI in Counter Strike 2. There are two files in the gsi_cfg folder, the first of which is prefixed with "fast", use it if you want to receive data very quickly on your local machine, the other file "normal" sends data with a delay, it can be used for transfer over the network. Copy one of these files to (cs2)/game/csgo/cfg
. And that's it, restart the game.
In order to run examples, you need to add this to Cargo.toml
[dependencies]
gsi-cs2 = "0.1.1"
poem = { version = "1.3.48", features = ["server"] }
serde_json = "1.0.87"
tokio = { version = "1.21.2", features = ["rt-multi-thread", "macros"] }
tracing-subscriber = { version = "0.3.16" }
In this example we can see serialized data from cs2
example/payload.rs | cargo run --example payload
use poem::{
handler, listener::TcpListener, post,
Route, Server, web::Json
};
use gsi_cs2::Body;
#[handler]
fn update(data: Json<Body>) {
println!("{:#?}", data);
}
#[tokio::main]
async fn main() -> Result<(), std::io::Error> {
tracing_subscriber::fmt::init();
let app = Route::new().at("/", post(update));
Server::new(TcpListener::bind("127.0.0.1:3000"))
.run(app)
.await
}
This example shows how to get the state of your active weapon.
example/weapons.rs | cargo run --example weapons
use poem::{
handler, listener::TcpListener, post,
Route, Server, web::Json
};
use gsi_cs2::{
Body, weapon::{
WeaponState, WeaponType::*, WeaponName
}
};
#[handler]
fn update(data: Json<Body>) {
let map = data.map.as_ref();
if let None = map {
println!("You need to load map");
return;
}
let player_data = data.player.as_ref();
if let None = player_data {
return;
}
let player = player_data.unwrap();
let weapons = &player.weapons;
print!("\x1B[2J\x1B[1;1H"); //clear
// A loop through all weapons
for (_k, weapon) in weapons.iter() {
// Check if the weapon is currently active
if let WeaponState::Active = weapon.state {
// There is no ammunition for these types of weapons
match weapon.r#type {
Some(Knife) => println!("Knife"),
Some(Melee) => println!("Melee"),
Some(Fists) => println!("Fists"),
Some(C4) => println!("C4"),
Some(Grenade) => println!("Grenade"),
Some(Tablet) => println!("Tablet"),
Some(StackableItem) => println!("StackableItem"),
_ => {
let deserialized_name = serde_json::to_string(&weapon.name).unwrap();
let weapon_type = weapon.r#type.as_ref().unwrap();
println!("Name: {}\nType: {:?}\nAmmo: ( {} / {} )",
deserialized_name, weapon_type, weapon.ammo_clip,
weapon.ammo_reserve
);
if weapon.ammo_clip < weapon.ammo_clip_max / 5 {
println!("Low on ammo. Reload.");
}
}
}
// Check if the name of the weapon is "weapon_glock"
if let WeaponName::Glock = weapon.name {
println!("\nWow, is that a Glock?");
}
// The same, but for "weapon_usp_silencer"
if let WeaponName::USPS = weapon.name {
println!("\nWow, is that a USP-S?");
}
return;
}
// Checking if the weapon is reloading
if let WeaponState::Reloading = weapon.state {
println!("Reloading...");
}
}
}
#[tokio::main]
async fn main() -> Result<(), std::io::Error> {
tracing_subscriber::fmt::init();
let app = Route::new().at("/", post(update));
Server::new(TcpListener::bind("127.0.0.1:3000"))
.run(app)
.await
}
Sometimes, cs2 may not send data to the server for about 30 seconds.
Dependencies
~0.3–1MB
~21K SLoC