diff --git a/Cargo.lock b/Cargo.lock index 7a3ee7c..56038af 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -123,12 +123,24 @@ dependencies = [ "alloc-stdlib", ] +[[package]] +name = "byteorder" +version = "1.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" + [[package]] name = "bytes" version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ec8a7b6a70fde80372154c65702f00a0f56f3e1c36abbc6c440484be248856db" +[[package]] +name = "cc" +version = "1.0.77" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e9f73505338f7d905b19d18738976aae232eb46b8efc15554ffc56deb5d9ebe4" + [[package]] name = "cfg-if" version = "1.0.0" @@ -156,6 +168,22 @@ dependencies = [ "version_check", ] +[[package]] +name = "core-foundation" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "194a7a9e6de53fa55116934067c844d9d749312f75c6f6d0980e8c252f8c2146" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "core-foundation-sys" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5827cebf4670468b8772dd191856768aedcb1b0278a04f989f7766351917b9dc" + [[package]] name = "cpufeatures" version = "0.2.5" @@ -293,6 +321,21 @@ version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" +[[package]] +name = "foreign-types" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" +dependencies = [ + "foreign-types-shared", +] + +[[package]] +name = "foreign-types-shared" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" + [[package]] name = "form_urlencoded" version = "1.1.0" @@ -302,6 +345,21 @@ dependencies = [ "percent-encoding", ] +[[package]] +name = "futures" +version = "0.3.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38390104763dc37a5145a53c29c63c1290b5d316d6086ec32c293f6736051bb0" +dependencies = [ + "futures-channel", + "futures-core", + "futures-executor", + "futures-io", + "futures-sink", + "futures-task", + "futures-util", +] + [[package]] name = "futures-channel" version = "0.3.25" @@ -309,6 +367,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "52ba265a92256105f45b719605a571ffe2d1f0fea3807304b522c1d778f79eed" dependencies = [ "futures-core", + "futures-sink", ] [[package]] @@ -317,6 +376,17 @@ version = "0.3.25" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "04909a7a7e4633ae6c4a9ab280aeb86da1236243a77b694a49eacd659a4bd3ac" +[[package]] +name = "futures-executor" +version = "0.3.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7acc85df6714c176ab5edf386123fafe217be88c0840ec11f199441134a074e2" +dependencies = [ + "futures-core", + "futures-task", + "futures-util", +] + [[package]] name = "futures-io" version = "0.3.25" @@ -352,9 +422,11 @@ version = "0.3.25" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "197676987abd2f9cadff84926f410af1c183608d36641465df73ae8211dc65d6" dependencies = [ + "futures-channel", "futures-core", "futures-io", "futures-macro", + "futures-sink", "futures-task", "memchr", "pin-project-lite", @@ -383,6 +455,17 @@ dependencies = [ "wasi 0.9.0+wasi-snapshot-preview1", ] +[[package]] +name = "getrandom" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c05aeb6a22b8f62540c194aac980f2115af067bfe15a0734d7277a768d396b31" +dependencies = [ + "cfg-if", + "libc", + "wasi 0.11.0+wasi-snapshot-preview1", +] + [[package]] name = "h2" version = "0.3.15" @@ -541,6 +624,12 @@ version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4217ad341ebadf8d8e724e264f13e593e0648f5b3e94b3896a5df283be015ecc" +[[package]] +name = "lazy_static" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" + [[package]] name = "libc" version = "0.2.137" @@ -606,7 +695,7 @@ dependencies = [ "libc", "log", "wasi 0.11.0+wasi-snapshot-preview1", - "windows-sys", + "windows-sys 0.42.0", ] [[package]] @@ -636,6 +725,24 @@ dependencies = [ "serde", ] +[[package]] +name = "native-tls" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07226173c32f2926027b63cce4bcd8076c3552846cbe7925f3aaffeac0a3b92e" +dependencies = [ + "lazy_static", + "libc", + "log", + "openssl", + "openssl-probe", + "openssl-sys", + "schannel", + "security-framework", + "security-framework-sys", + "tempfile", +] + [[package]] name = "num_cpus" version = "1.14.0" @@ -652,6 +759,51 @@ version = "1.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "86f0b0d4bf799edbc74508c1e8bf170ff5f41238e5f8225603ca7caaae2b7860" +[[package]] +name = "openssl" +version = "0.10.42" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "12fc0523e3bd51a692c8850d075d74dc062ccf251c0110668cbd921917118a13" +dependencies = [ + "bitflags", + "cfg-if", + "foreign-types", + "libc", + "once_cell", + "openssl-macros", + "openssl-sys", +] + +[[package]] +name = "openssl-macros" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b501e44f11665960c7e7fcf062c7d96a14ade4aa98116c004b2e37b5be7d736c" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "openssl-probe" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" + +[[package]] +name = "openssl-sys" +version = "0.9.77" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b03b84c3b2d099b81f0953422b4d4ad58761589d0229b5506356afca05a3670a" +dependencies = [ + "autocfg", + "cc", + "libc", + "pkg-config", + "vcpkg", +] + [[package]] name = "parking_lot" version = "0.12.1" @@ -672,7 +824,7 @@ dependencies = [ "libc", "redox_syscall", "smallvec", - "windows-sys", + "windows-sys 0.42.0", ] [[package]] @@ -693,6 +845,12 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" +[[package]] +name = "pkg-config" +version = "0.3.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ac9a59f73473f1b8d852421e59e64809f025994837ef743615c6d0c5b305160" + [[package]] name = "ppv-lite86" version = "0.2.17" @@ -734,13 +892,24 @@ version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" dependencies = [ - "getrandom", + "getrandom 0.1.16", "libc", - "rand_chacha", - "rand_core", + "rand_chacha 0.2.2", + "rand_core 0.5.1", "rand_hc", ] +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "libc", + "rand_chacha 0.3.1", + "rand_core 0.6.4", +] + [[package]] name = "rand_chacha" version = "0.2.2" @@ -748,7 +917,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402" dependencies = [ "ppv-lite86", - "rand_core", + "rand_core 0.5.1", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core 0.6.4", ] [[package]] @@ -757,7 +936,16 @@ version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" dependencies = [ - "getrandom", + "getrandom 0.1.16", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom 0.2.8", ] [[package]] @@ -766,7 +954,7 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" dependencies = [ - "rand_core", + "rand_core 0.5.1", ] [[package]] @@ -900,12 +1088,45 @@ dependencies = [ "syn", ] +[[package]] +name = "schannel" +version = "0.1.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88d6731146462ea25d9244b2ed5fd1d716d25c52e4d54aa4fb0f3c4e9854dbe2" +dependencies = [ + "lazy_static", + "windows-sys 0.36.1", +] + [[package]] name = "scopeguard" version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" +[[package]] +name = "security-framework" +version = "2.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2bc1bb97804af6631813c55739f771071e0f2ed33ee20b68c86ec505d906356c" +dependencies = [ + "bitflags", + "core-foundation", + "core-foundation-sys", + "libc", + "security-framework-sys", +] + +[[package]] +name = "security-framework-sys" +version = "2.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0160a13a177a45bfb43ce71c01580998474f556ad854dcbca936dd2841a5c556" +dependencies = [ + "core-foundation-sys", + "libc", +] + [[package]] name = "serde" version = "1.0.147" @@ -949,6 +1170,17 @@ dependencies = [ "serde", ] +[[package]] +name = "sha-1" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "028f48d513f9678cda28f6e4064755b3fbb2af6acd672f2c209b62323f7aea0f" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest", +] + [[package]] name = "sha1" version = "0.10.5" @@ -1017,6 +1249,10 @@ dependencies = [ [[package]] name = "tasks" version = "0.1.0" +dependencies = [ + "once_cell", + "redis", +] [[package]] name = "tempfile" @@ -1039,7 +1275,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7743f8d70cd784ed1dc33106a18998d77758d281dc40dc3e6d050cf0f5286683" dependencies = [ "base64 0.12.3", - "rand", + "rand 0.7.3", ] [[package]] @@ -1133,6 +1369,16 @@ dependencies = [ "syn", ] +[[package]] +name = "tokio-native-tls" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f7d995660bd2b7f8c1568414c1126076c13fbb725c40112dc0120b78eb9b717b" +dependencies = [ + "native-tls", + "tokio", +] + [[package]] name = "tokio-stream" version = "0.1.11" @@ -1144,6 +1390,20 @@ dependencies = [ "tokio", ] +[[package]] +name = "tokio-tungstenite" +version = "0.17.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f714dd15bead90401d77e04243611caec13726c2408afd5b31901dfcdcb3b181" +dependencies = [ + "futures-util", + "log", + "native-tls", + "tokio", + "tokio-native-tls", + "tungstenite", +] + [[package]] name = "tokio-util" version = "0.7.4" @@ -1211,6 +1471,26 @@ version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "59547bce71d9c38b83d9c0e92b6066c4253371f15005def0c30d9657f50c7642" +[[package]] +name = "tungstenite" +version = "0.17.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e27992fd6a8c29ee7eef28fc78349aa244134e10ad447ce3b9f0ac0ed0fa4ce0" +dependencies = [ + "base64 0.13.1", + "byteorder", + "bytes", + "http", + "httparse", + "log", + "native-tls", + "rand 0.8.5", + "sha-1", + "thiserror", + "url", + "utf-8", +] + [[package]] name = "typenum" version = "1.15.0" @@ -1258,6 +1538,18 @@ dependencies = [ "percent-encoding", ] +[[package]] +name = "utf-8" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" + +[[package]] +name = "vcpkg" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" + [[package]] name = "version_check" version = "0.9.4" @@ -1289,6 +1581,17 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "websocket" version = "0.1.0" +dependencies = [ + "futures", + "futures-util", + "once_cell", + "redis", + "serde", + "serde_json", + "tokio", + "tokio-tungstenite", + "url", +] [[package]] name = "winapi" @@ -1312,6 +1615,19 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" +[[package]] +name = "windows-sys" +version = "0.36.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ea04155a16a59f9eab786fe12a4a450e75cdb175f9e0d80da1e17db09f55b8d2" +dependencies = [ + "windows_aarch64_msvc 0.36.1", + "windows_i686_gnu 0.36.1", + "windows_i686_msvc 0.36.1", + "windows_x86_64_gnu 0.36.1", + "windows_x86_64_msvc 0.36.1", +] + [[package]] name = "windows-sys" version = "0.42.0" @@ -1319,12 +1635,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5a3e1820f08b8513f676f7ab6c1f99ff312fb97b553d30ff4dd86f9f15728aa7" dependencies = [ "windows_aarch64_gnullvm", - "windows_aarch64_msvc", - "windows_i686_gnu", - "windows_i686_msvc", - "windows_x86_64_gnu", + "windows_aarch64_msvc 0.42.0", + "windows_i686_gnu 0.42.0", + "windows_i686_msvc 0.42.0", + "windows_x86_64_gnu 0.42.0", "windows_x86_64_gnullvm", - "windows_x86_64_msvc", + "windows_x86_64_msvc 0.42.0", ] [[package]] @@ -1333,24 +1649,48 @@ version = "0.42.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "41d2aa71f6f0cbe00ae5167d90ef3cfe66527d6f613ca78ac8024c3ccab9a19e" +[[package]] +name = "windows_aarch64_msvc" +version = "0.36.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9bb8c3fd39ade2d67e9874ac4f3db21f0d710bee00fe7cab16949ec184eeaa47" + [[package]] name = "windows_aarch64_msvc" version = "0.42.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dd0f252f5a35cac83d6311b2e795981f5ee6e67eb1f9a7f64eb4500fbc4dcdb4" +[[package]] +name = "windows_i686_gnu" +version = "0.36.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "180e6ccf01daf4c426b846dfc66db1fc518f074baa793aa7d9b9aaeffad6a3b6" + [[package]] name = "windows_i686_gnu" version = "0.42.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fbeae19f6716841636c28d695375df17562ca208b2b7d0dc47635a50ae6c5de7" +[[package]] +name = "windows_i686_msvc" +version = "0.36.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2e7917148b2812d1eeafaeb22a97e4813dfa60a3f8f78ebe204bcc88f12f024" + [[package]] name = "windows_i686_msvc" version = "0.42.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "84c12f65daa39dd2babe6e442988fc329d6243fdce47d7d2d155b8d874862246" +[[package]] +name = "windows_x86_64_gnu" +version = "0.36.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4dcd171b8776c41b97521e5da127a2d86ad280114807d0b2ab1e462bc764d9e1" + [[package]] name = "windows_x86_64_gnu" version = "0.42.0" @@ -1363,6 +1703,12 @@ version = "0.42.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09d525d2ba30eeb3297665bd434a54297e4170c7f1a44cad4ef58095b4cd2028" +[[package]] +name = "windows_x86_64_msvc" +version = "0.36.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c811ca4a8c853ef420abd8592ba53ddbbac90410fab6903b3e79972a631f7680" + [[package]] name = "windows_x86_64_msvc" version = "0.42.0" diff --git a/services/api/src/main.rs b/services/api/src/main.rs index 0168d51..e113e5c 100644 --- a/services/api/src/main.rs +++ b/services/api/src/main.rs @@ -19,6 +19,7 @@ struct Factions { tr: u32, nc: u32, vs: u32, + ns: u32, } #[derive(Serialize, Deserialize, Debug)] @@ -95,10 +96,11 @@ async fn get_world_pop(world_id: String) -> WorldPopulation { .unwrap() .as_secs(); - let (vs, nc, tr): (u32, u32, u32) = redis::pipe() - .zcount(format!("{}/{}", world_id, 1), filter_timestamp, "+inf") - .zcount(format!("{}/{}", world_id, 2), filter_timestamp, "+inf") - .zcount(format!("{}/{}", world_id, 3), filter_timestamp, "+inf") + let (vs, nc, tr, ns): (u32, u32, u32, u32) = redis::pipe() + .zcount(format!("wp:{}/{}", world_id, 1), filter_timestamp, "+inf") + .zcount(format!("wp:{}/{}", world_id, 2), filter_timestamp, "+inf") + .zcount(format!("wp:{}/{}", world_id, 3), filter_timestamp, "+inf") + .zcount(format!("wp:{}/{}", world_id, 4), filter_timestamp, "+inf") .query(&mut con) .unwrap(); @@ -107,7 +109,7 @@ async fn get_world_pop(world_id: String) -> WorldPopulation { let response = WorldPopulation { world_id: world_id.parse().unwrap(), total, - factions: Factions { tr, nc, vs }, + factions: Factions { tr, nc, vs, ns }, }; response diff --git a/services/tasks/Cargo.toml b/services/tasks/Cargo.toml index b454c4a..995472f 100644 --- a/services/tasks/Cargo.toml +++ b/services/tasks/Cargo.toml @@ -6,3 +6,5 @@ edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] +redis = "0.22.1" +once_cell = "1.16.0" diff --git a/services/tasks/src/main.rs b/services/tasks/src/main.rs index e7a11a9..75915dd 100644 --- a/services/tasks/src/main.rs +++ b/services/tasks/src/main.rs @@ -1,3 +1,48 @@ -fn main() { - println!("Hello, world!"); +use once_cell::sync::Lazy; +use redis::Commands; +use std::env::args; +use std::ops::Sub; +use std::time::{Duration, SystemTime}; + +pub static REDIS_CLIENT: Lazy = Lazy::new(|| { + redis::Client::open(std::env::var("REDIS_ADDR").unwrap_or("redis://localhost:6379".to_string())) + .unwrap() +}); + +fn cmd_prune() { + println!("Pruning old data..."); + let mut con = REDIS_CLIENT.get_connection().unwrap(); + + let prune_after = SystemTime::now() + .sub(Duration::from_secs(60)) + .duration_since(SystemTime::UNIX_EPOCH) + .unwrap() + .as_secs(); + + let keys: Vec = con.keys("wp:*").unwrap(); + for key in keys { + println!("-> Pruning {}", key); + let removed_items: u64 = con.zrembyscore(key, 0, prune_after).unwrap(); + println!("==> Removed {} items", removed_items); + } +} + +fn cmd_help() { + println!("Usage: {} [command]", args().nth(0).unwrap()); + println!("Commands:"); + println!(" help - Show this help message"); + println!(" prune - Remove stale data from Redis"); +} + +fn main() { + let command = args().nth(1).unwrap_or("help".to_string()); + + match command.as_str() { + "help" => cmd_help(), + "prune" => cmd_prune(), + _ => { + println!("Unknown command: {}", command); + cmd_help(); + } + } } diff --git a/services/websocket/Cargo.toml b/services/websocket/Cargo.toml index ddb77ff..ad9766c 100644 --- a/services/websocket/Cargo.toml +++ b/services/websocket/Cargo.toml @@ -6,3 +6,12 @@ edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] +redis = "0.22.1" +once_cell = "1.16.0" +tokio-tungstenite = { version = "0.17.2", features=["native-tls"] } +serde_json = "1.0.88" +serde = { version = "1.0.147", features = ["derive"] } +tokio = { version = "1.22.0" } +url = "2.3.1" +futures-util = "0.3.25" +futures = "0.3.25" \ No newline at end of file diff --git a/services/websocket/src/main.rs b/services/websocket/src/main.rs index e7a11a9..814ce47 100644 --- a/services/websocket/src/main.rs +++ b/services/websocket/src/main.rs @@ -1,3 +1,122 @@ -fn main() { - println!("Hello, world!"); +use futures::{pin_mut, FutureExt}; +use futures_util::StreamExt; +use once_cell::sync::Lazy; +use redis::Commands; +use serde::Deserialize; +use serde_json::json; +use std::{env, time::SystemTime}; +use tokio_tungstenite::{connect_async, tungstenite::Message}; + +pub static REDIS_CLIENT: Lazy = Lazy::new(|| { + redis::Client::open(std::env::var("REDIS_ADDR").unwrap_or("redis://localhost:6379".to_string())) + .unwrap() +}); + +async fn send_init(tx: futures::channel::mpsc::UnboundedSender) { + let worlds_raw = env::var("WORLDS").unwrap_or_default(); + if worlds_raw == "" { + println!("WORLDS not set"); + return; + } + let worlds: Vec<&str> = worlds_raw.split(',').collect(); + + // Send setup message + let setup_msg = json!({ + "action": "subscribe", + "worlds": worlds, + "eventNames": ["Death", "VehicleDestroy"], + "characters": ["all"], + "logicalAndCharactersWithWorlds": true, + "service": "event", + }); + + tx.unbounded_send(Message::text(setup_msg.to_string())) + .unwrap(); + + println!("Sent setup message"); +} + +fn process_event(event: &Event) { + let mut con = REDIS_CLIENT.get_connection().unwrap(); + + let timestamp = SystemTime::now() + .duration_since(SystemTime::UNIX_EPOCH) + .unwrap() + .as_secs(); + + let key: String = format!("wp:{}/{}", event.world_id, event.team_id); + con.zadd::(key, event.character_id.clone(), timestamp) + .unwrap(); + + if event.attacker_character_id != "" { + let key = format!("wp:{}/{}", event.world_id, event.attacker_team_id); + con.zadd::(key, event.attacker_character_id.clone(), timestamp) + .unwrap(); + } +} + +#[derive(Deserialize, Debug, Clone)] +struct Event { + event_name: String, + world_id: String, + character_id: String, + attacker_character_id: String, + attacker_team_id: String, + team_id: String, +} + +#[derive(Deserialize, Debug, Clone)] +struct Payload { + payload: Event, +} + +#[tokio::main] +async fn main() { + let addr = env::var("WS_ADDR").unwrap_or_default(); + if addr == "" { + println!("WS_ADDR not set"); + return; + } + let url = url::Url::parse(&addr).unwrap(); + let (tx, rx) = futures::channel::mpsc::unbounded(); + let (ws_stream, _) = connect_async(url).await.expect("Failed to connect"); + let (write, read) = ws_stream.split(); + + let fused_writer = rx.map(Ok).forward(write).fuse(); + let fused_reader = read + .for_each(|msg| async move { + let body = &msg.unwrap().to_string(); + let data: Payload = serde_json::from_str(body).unwrap_or(Payload { + payload: Event { + event_name: "".to_string(), + world_id: "".to_string(), + character_id: "".to_string(), + attacker_character_id: "".to_string(), + attacker_team_id: "".to_string(), + team_id: "".to_string(), + }, + }); + + if data.payload.event_name == "" { + return; + } + + process_event(&data.payload); + }) + .fuse(); + + pin_mut!(fused_writer, fused_reader); + + let init = tokio::spawn(send_init(tx.clone())); + + futures::select! { + _ = fused_reader => { + println!("Reader finished"); + } + _ = fused_writer => { + println!("Writer finished"); + } + } + + init.await.unwrap(); }