diff --git a/Cargo.lock b/Cargo.lock index c9f9dd5..95d55db 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -356,6 +356,16 @@ dependencies = [ "generic-array", ] +[[package]] +name = "combine" +version = "4.6.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "35ed6e9d84f0b51a7f52daf1c7d71dd136fd7a3f41a8462b8cdb8c78d920fad4" +dependencies = [ + "bytes", + "memchr", +] + [[package]] name = "concurrent-queue" version = "2.1.0" @@ -1233,6 +1243,20 @@ dependencies = [ "num_cpus", ] +[[package]] +name = "redis" +version = "0.23.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ea8c51b5dc1d8e5fd3350ec8167f464ec0995e79f2e90a075b63371500d557f" +dependencies = [ + "combine", + "itoa", + "percent-encoding", + "ryu", + "sha1_smol", + "url", +] + [[package]] name = "redox_syscall" version = "0.2.16" @@ -1438,6 +1462,12 @@ dependencies = [ "digest", ] +[[package]] +name = "sha1_smol" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae1a47186c03a32177042e55dbc5fd5aee900b8e0069a8d70fba96a9375cd012" + [[package]] name = "sha2" version = "0.10.6" @@ -1545,6 +1575,7 @@ version = "0.1.0" dependencies = [ "once_cell", "rand", + "redis", "serde", "toml", "tracing", diff --git a/Cargo.toml b/Cargo.toml index fd34062..74d0ef6 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -8,6 +8,7 @@ edition = "2021" [dependencies] once_cell = "1.17.1" rand = "0.8.5" +redis = "0.23.0" serde = { version = "1.0.159", features = ["derive"] } toml = "0.7.3" tracing = "0.1.37" diff --git a/TODO.md b/TODO.md index cad7287..4e2594c 100644 --- a/TODO.md +++ b/TODO.md @@ -1,9 +1,9 @@ # TODO - Implement waiting room system [✔️] - Chat [✔️] +- Wins leaderboard using a database [✔️] - Make the game automatically start - Make spectator mode work properly - Maybe make the floors use a random block each round? -- Leaderboards using a database, probably Surreal - Maybe some kind of events that can randomly happen? Could be a cool mechanic that other spleef servers (probably) don't have - Eventually add world support for nicer looking arenas \ No newline at end of file diff --git a/config.toml b/config.toml index 7d02cba..75b2902 100644 --- a/config.toml +++ b/config.toml @@ -8,4 +8,7 @@ platform_size = 15 operators = [ "dc524fc6-bdba-4f55-9f7b-cefc824cc77e" -] \ No newline at end of file +] + +[db] +address = "redis://127.0.0.1:6379/" \ No newline at end of file diff --git a/src/config.rs b/src/config.rs index e774b77..30ae488 100644 --- a/src/config.rs +++ b/src/config.rs @@ -4,7 +4,7 @@ use once_cell::sync::Lazy; use serde::Deserialize; use valence::uuid::Uuid; -#[derive(Deserialize)] +#[derive(Deserialize, Clone)] pub struct Config { // USE ONLY FOR DEVELOPMENT PURPOSES pub no_auto_stop: Option, @@ -16,6 +16,13 @@ pub struct Config { pub platform_size: i32, pub operators: Vec, + + pub db: DBConfig, +} + +#[derive(Deserialize, Clone)] +pub struct DBConfig { + pub address: String, } pub static CONFIG: Lazy = Lazy::new(|| { diff --git a/src/db.rs b/src/db.rs new file mode 100644 index 0000000..63d2074 --- /dev/null +++ b/src/db.rs @@ -0,0 +1,12 @@ +use crate::config::CONFIG; +use valence::bevy_ecs::{self, prelude::*}; + +#[derive(Resource)] +pub struct Connection(pub redis::Connection); + +pub fn setup(mut commands: Commands) { + let client = redis::Client::open(CONFIG.db.address.clone()).unwrap(); + let connection = client.get_connection().unwrap(); + + commands.insert_resource(Connection(connection)); +} diff --git a/src/game.rs b/src/game.rs index ec97788..03f91e3 100644 --- a/src/game.rs +++ b/src/game.rs @@ -1,7 +1,8 @@ use rand::prelude::*; +use redis::Commands as RedisCommands; use valence::prelude::*; -use crate::{player::Alive, GameState, CONFIG}; +use crate::{db::Connection, player::Alive, GameState, CONFIG}; pub fn start_game( mut clients: Query<(&mut Client, &mut Position, &mut GameMode, &mut Alive)>, @@ -43,15 +44,17 @@ pub fn stop_game( &mut GameMode, &mut Alive, &Username, + &UniqueId, )>, + mut connection: ResMut, ) { tracing::debug!("Stopping game!"); let mut alive_players = vec![]; - for (mut client, mut pos, mut gamemode, mut alive, username) in &mut clients { + for (mut client, mut pos, mut gamemode, mut alive, username, uuid) in &mut clients { if alive.0 { - alive_players.push(username); + alive_players.push((username, uuid)); } *gamemode = GameMode::Spectator; @@ -66,13 +69,20 @@ pub fn stop_game( // if statement to not panic if somehow no one was alive when the game ended if alive_players.len() >= 1 { // let's assume there's only one alive player - alive_players[0].0.clone() + alive_players[0].0 .0.clone() } else { "Somehow, no one".to_string() } ), None, ); + + if alive_players.len() == 1 { + let _: i32 = connection + .0 + .hincr("wins".to_string(), alive_players[0].1 .0.to_string(), 1) + .unwrap(); + } } } diff --git a/src/main.rs b/src/main.rs index 5fe4cb3..434fcbb 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,6 +1,7 @@ mod chat; mod commands; mod config; +mod db; mod game; mod player; mod world; @@ -25,7 +26,7 @@ fn main() { App::new() .add_state::() .add_plugin(ServerPlugin::new(())) - .add_startup_system(world::setup) + .add_startup_systems((world::setup, db::setup)) .add_system(player::init_clients) .add_systems( (