diff --git a/.gitignore b/.gitignore index fe026e3..883caa7 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,4 @@ -/target +target/ .vscode main main.exe @@ -7,4 +7,5 @@ main.pdb restarts.log nohup.out server.log -control_panel.log \ No newline at end of file +control_panel.log +onefetch.out \ No newline at end of file diff --git a/Cargo.lock b/Cargo.lock deleted file mode 100644 index c86c789..0000000 --- a/Cargo.lock +++ /dev/null @@ -1,798 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -version = 3 - -[[package]] -name = "async-attributes" -version = "1.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a3203e79f4dd9bdda415ed03cf14dae5a2bf775c683a00f94e9cd1faf0f596e5" -dependencies = [ - "quote", - "syn", -] - -[[package]] -name = "async-channel" -version = "1.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2114d64672151c0c5eaa5e131ec84a74f06e1e559830dabba01ca30605d66319" -dependencies = [ - "concurrent-queue", - "event-listener", - "futures-core", -] - -[[package]] -name = "async-executor" -version = "1.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "871f9bb5e0a22eeb7e8cf16641feb87c9dc67032ccf8ff49e772eb9941d3a965" -dependencies = [ - "async-task", - "concurrent-queue", - "fastrand", - "futures-lite", - "once_cell", - "slab", -] - -[[package]] -name = "async-global-executor" -version = "2.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c026b7e44f1316b567ee750fea85103f87fcb80792b860e979f221259796ca0a" -dependencies = [ - "async-channel", - "async-executor", - "async-io", - "async-mutex", - "blocking", - "futures-lite", - "num_cpus", - "once_cell", -] - -[[package]] -name = "async-io" -version = "1.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a811e6a479f2439f0c04038796b5cfb3d2ad56c230e0f2d3f7b04d68cfee607b" -dependencies = [ - "concurrent-queue", - "futures-lite", - "libc", - "log", - "once_cell", - "parking", - "polling", - "slab", - "socket2", - "waker-fn", - "winapi", -] - -[[package]] -name = "async-lock" -version = "2.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e97a171d191782fba31bb902b14ad94e24a68145032b7eedf871ab0bc0d077b6" -dependencies = [ - "event-listener", -] - -[[package]] -name = "async-mutex" -version = "1.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "479db852db25d9dbf6204e6cb6253698f175c15726470f78af0d918e99d6156e" -dependencies = [ - "event-listener", -] - -[[package]] -name = "async-notify" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8356f653934a654817bceada97a857ef8d68ab8992753d23ed8e8ccd5fc8fa31" -dependencies = [ - "futures-channel", - "futures-util", -] - -[[package]] -name = "async-std" -version = "1.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8056f1455169ab86dd47b47391e4ab0cbd25410a70e9fe675544f49bafaf952" -dependencies = [ - "async-attributes", - "async-channel", - "async-global-executor", - "async-io", - "async-lock", - "crossbeam-utils", - "futures-channel", - "futures-core", - "futures-io", - "futures-lite", - "gloo-timers", - "kv-log-macro", - "log", - "memchr", - "num_cpus", - "once_cell", - "pin-project-lite", - "pin-utils", - "slab", - "wasm-bindgen-futures", -] - -[[package]] -name = "async-task" -version = "4.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30696a84d817107fc028e049980e09d5e140e8da8f1caeb17e8e950658a3cea9" - -[[package]] -name = "atomic-waker" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "065374052e7df7ee4047b1160cca5e1467a12351a40b3da123c870ba0b8eda2a" - -[[package]] -name = "autocfg" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" - -[[package]] -name = "blocking" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "046e47d4b2d391b1f6f8b407b1deb8dee56c1852ccd868becf2710f601b5f427" -dependencies = [ - "async-channel", - "async-task", - "atomic-waker", - "fastrand", - "futures-lite", - "once_cell", -] - -[[package]] -name = "bumpalo" -version = "3.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4a45a46ab1f2412e53d3a0ade76ffad2025804294569aae387231a0cd6e0899" - -[[package]] -name = "cache-padded" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1db59621ec70f09c5e9b597b220c7a2b43611f4710dc03ceb8748637775692c" - -[[package]] -name = "cc" -version = "1.0.73" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2fff2a6927b3bb87f9595d67196a70493f627687a71d87a0d692242c33f58c11" - -[[package]] -name = "cfg-if" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" - -[[package]] -name = "chrono" -version = "0.4.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "670ad68c9088c2a963aaa298cb369688cf3f9465ce5e2d4ca10e6e0098a1ce73" -dependencies = [ - "libc", - "num-integer", - "num-traits", - "time 0.1.44", - "winapi", -] - -[[package]] -name = "concurrent-queue" -version = "1.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30ed07550be01594c6026cff2a1d7fe9c8f683caa798e12b68694ac9e88286a3" -dependencies = [ - "cache-padded", -] - -[[package]] -name = "crossbeam-utils" -version = "0.8.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5e5bed1f1c269533fa816a0a5492b3545209a205ca1a54842be180eb63a16a6" -dependencies = [ - "cfg-if", - "lazy_static", -] - -[[package]] -name = "ctor" -version = "0.1.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ccc0a48a9b826acdf4028595adc9db92caea352f7af011a3034acd172a52a0aa" -dependencies = [ - "quote", - "syn", -] - -[[package]] -name = "event-listener" -version = "2.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77f3309417938f28bf8228fcff79a4a37103981e3e186d2ccd19c74b38f4eb71" - -[[package]] -name = "fastrand" -version = "1.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3fcf0cee53519c866c09b5de1f6c56ff9d647101f81c1964fa632e148896cdf" -dependencies = [ - "instant", -] - -[[package]] -name = "futures" -version = "0.3.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f73fe65f54d1e12b726f517d3e2135ca3125a437b6d998caf1962961f7172d9e" -dependencies = [ - "futures-channel", - "futures-core", - "futures-executor", - "futures-io", - "futures-sink", - "futures-task", - "futures-util", -] - -[[package]] -name = "futures-channel" -version = "0.3.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3083ce4b914124575708913bca19bfe887522d6e2e6d0952943f5eac4a74010" -dependencies = [ - "futures-core", - "futures-sink", -] - -[[package]] -name = "futures-core" -version = "0.3.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c09fd04b7e4073ac7156a9539b57a484a8ea920f79c7c675d05d289ab6110d3" - -[[package]] -name = "futures-executor" -version = "0.3.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9420b90cfa29e327d0429f19be13e7ddb68fa1cccb09d65e5706b8c7a749b8a6" -dependencies = [ - "futures-core", - "futures-task", - "futures-util", -] - -[[package]] -name = "futures-io" -version = "0.3.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc4045962a5a5e935ee2fdedaa4e08284547402885ab326734432bed5d12966b" - -[[package]] -name = "futures-lite" -version = "1.12.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7694489acd39452c77daa48516b894c153f192c3578d5a839b62c58099fcbf48" -dependencies = [ - "fastrand", - "futures-core", - "futures-io", - "memchr", - "parking", - "pin-project-lite", - "waker-fn", -] - -[[package]] -name = "futures-macro" -version = "0.3.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33c1e13800337f4d4d7a316bf45a567dbcb6ffe087f16424852d97e97a91f512" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "futures-sink" -version = "0.3.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21163e139fa306126e6eedaf49ecdb4588f939600f0b1e770f4205ee4b7fa868" - -[[package]] -name = "futures-task" -version = "0.3.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57c66a976bf5909d801bbef33416c41372779507e7a6b3a5e25e4749c58f776a" - -[[package]] -name = "futures-util" -version = "0.3.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8b7abd5d659d9b90c8cba917f6ec750a74e2dc23902ef9cd4cc8c8b22e6036a" -dependencies = [ - "futures-channel", - "futures-core", - "futures-io", - "futures-macro", - "futures-sink", - "futures-task", - "memchr", - "pin-project-lite", - "pin-utils", - "slab", -] - -[[package]] -name = "gloo-timers" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d12a7f4e95cfe710f1d624fb1210b7d961a5fb05c4fd942f4feab06e61f590e" -dependencies = [ - "futures-channel", - "futures-core", - "js-sys", - "wasm-bindgen", -] - -[[package]] -name = "hermit-abi" -version = "0.1.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" -dependencies = [ - "libc", -] - -[[package]] -name = "instant" -version = "0.1.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" -dependencies = [ - "cfg-if", -] - -[[package]] -name = "itoa" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1aab8fc367588b89dcee83ab0fd66b72b50b72fa1904d7095045ace2b0c81c35" - -[[package]] -name = "js-sys" -version = "0.3.56" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a38fc24e30fd564ce974c02bf1d337caddff65be6cc4735a1f7eab22a7440f04" -dependencies = [ - "wasm-bindgen", -] - -[[package]] -name = "kv-log-macro" -version = "1.0.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0de8b303297635ad57c9f5059fd9cee7a47f8e8daa09df0fcd07dd39fb22977f" -dependencies = [ - "log", -] - -[[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.117" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e74d72e0f9b65b5b4ca49a346af3976df0f9c61d550727f349ecd559f251a26c" - -[[package]] -name = "log" -version = "0.4.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710" -dependencies = [ - "cfg-if", - "value-bag", -] - -[[package]] -name = "memchr" -version = "2.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "308cc39be01b73d0d18f82a0e7b2a3df85245f84af96fdddc5d202d27e47b86a" - -[[package]] -name = "num-integer" -version = "0.1.44" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2cc698a63b549a70bc047073d2949cce27cd1c7b0a4a862d08a8031bc2801db" -dependencies = [ - "autocfg", - "num-traits", -] - -[[package]] -name = "num-traits" -version = "0.2.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a64b1ec5cda2586e284722486d802acf1f7dbdc623e2bfc57e65ca1cd099290" -dependencies = [ - "autocfg", -] - -[[package]] -name = "num_cpus" -version = "1.13.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19e64526ebdee182341572e50e9ad03965aa510cd94427a4549448f285e957a1" -dependencies = [ - "hermit-abi", - "libc", -] - -[[package]] -name = "num_threads" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2819ce041d2ee131036f4fc9d6ae7ae125a3a40e97ba64d04fe799ad9dabbb44" -dependencies = [ - "libc", -] - -[[package]] -name = "once_cell" -version = "1.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87f3e037eac156d1775da914196f0f37741a274155e34a0b7e427c35d2a2ecb9" - -[[package]] -name = "parking" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "427c3892f9e783d91cc128285287e70a59e206ca452770ece88a76f7a3eddd72" - -[[package]] -name = "pin-project-lite" -version = "0.2.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e280fbe77cc62c91527259e9442153f4688736748d24660126286329742b4c6c" - -[[package]] -name = "pin-utils" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" - -[[package]] -name = "polling" -version = "2.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "685404d509889fade3e86fe3a5803bca2ec09b0c0778d5ada6ec8bf7a8de5259" -dependencies = [ - "cfg-if", - "libc", - "log", - "wepoll-ffi", - "winapi", -] - -[[package]] -name = "proc-macro2" -version = "1.0.36" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7342d5883fbccae1cc37a2353b09c87c9b0f3afd73f5fb9bba687a1f733b029" -dependencies = [ - "unicode-xid", -] - -[[package]] -name = "quote" -version = "1.0.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "864d3e96a899863136fc6e99f3d7cae289dafe43bf2c5ac19b70df7210c0a145" -dependencies = [ - "proc-macro2", -] - -[[package]] -name = "ryu" -version = "1.0.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73b4b750c782965c211b42f022f59af1fbceabdd026623714f104152f1ec149f" - -[[package]] -name = "serde" -version = "1.0.136" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce31e24b01e1e524df96f1c2fdd054405f8d7376249a5110886fb4b658484789" -dependencies = [ - "serde_derive", -] - -[[package]] -name = "serde_derive" -version = "1.0.136" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08597e7152fcd306f41838ed3e37be9eaeed2b61c42e2117266a554fab4662f9" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "serde_json" -version = "1.0.79" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e8d9fa5c3b304765ce1fd9c4c8a3de2c8db365a5b91be52f186efc675681d95" -dependencies = [ - "itoa", - "ryu", - "serde", -] - -[[package]] -name = "simplelog" -version = "0.12.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48dfff04aade74dd495b007c831cd6f4e0cee19c344dd9dc0884c0289b70a786" -dependencies = [ - "log", - "termcolor", - "time 0.3.11", -] - -[[package]] -name = "slab" -version = "0.4.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9def91fd1e018fe007022791f865d0ccc9b3a0d5001e01aabb8b40e46000afb5" - -[[package]] -name = "socket2" -version = "0.4.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "66d72b759436ae32898a2af0a14218dbf55efde3feeb170eb623637db85ee1e0" -dependencies = [ - "libc", - "winapi", -] - -[[package]] -name = "syn" -version = "1.0.86" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a65b3f4ffa0092e9887669db0eae07941f023991ab58ea44da8fe8e2d511c6b" -dependencies = [ - "proc-macro2", - "quote", - "unicode-xid", -] - -[[package]] -name = "termcolor" -version = "1.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bab24d30b911b2376f3a13cc2cd443142f0c81dda04c118693e35b3835757755" -dependencies = [ - "winapi-util", -] - -[[package]] -name = "time" -version = "0.1.44" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6db9e6914ab8b1ae1c260a4ae7a49b6c5611b40328a735b21862567685e73255" -dependencies = [ - "libc", - "wasi", - "winapi", -] - -[[package]] -name = "time" -version = "0.3.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72c91f41dcb2f096c05f0873d667dceec1087ce5bcf984ec8ffb19acddbb3217" -dependencies = [ - "itoa", - "libc", - "num_threads", - "time-macros", -] - -[[package]] -name = "time-macros" -version = "0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42657b1a6f4d817cda8e7a0ace261fe0cc946cf3a80314390b22cc61ae080792" - -[[package]] -name = "unicode-xid" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3" - -[[package]] -name = "value-bag" -version = "1.0.0-alpha.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "79923f7731dc61ebfba3633098bf3ac533bbd35ccd8c57e7088d9a5eebe0263f" -dependencies = [ - "ctor", - "version_check", -] - -[[package]] -name = "velnet_server" -version = "0.2.0" -dependencies = [ - "async-notify", - "async-std", - "chrono", - "futures", - "log", - "serde", - "serde_json", - "simplelog", -] - -[[package]] -name = "version_check" -version = "0.9.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" - -[[package]] -name = "waker-fn" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d5b2c62b4012a3e1eca5a7e077d13b3bf498c4073e33ccd58626607748ceeca" - -[[package]] -name = "wasi" -version = "0.10.0+wasi-snapshot-preview1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a143597ca7c7793eff794def352d41792a93c481eb1042423ff7ff72ba2c31f" - -[[package]] -name = "wasm-bindgen" -version = "0.2.79" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25f1af7423d8588a3d840681122e72e6a24ddbcb3f0ec385cac0d12d24256c06" -dependencies = [ - "cfg-if", - "wasm-bindgen-macro", -] - -[[package]] -name = "wasm-bindgen-backend" -version = "0.2.79" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b21c0df030f5a177f3cba22e9bc4322695ec43e7257d865302900290bcdedca" -dependencies = [ - "bumpalo", - "lazy_static", - "log", - "proc-macro2", - "quote", - "syn", - "wasm-bindgen-shared", -] - -[[package]] -name = "wasm-bindgen-futures" -version = "0.4.29" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2eb6ec270a31b1d3c7e266b999739109abce8b6c87e4b31fcfcd788b65267395" -dependencies = [ - "cfg-if", - "js-sys", - "wasm-bindgen", - "web-sys", -] - -[[package]] -name = "wasm-bindgen-macro" -version = "0.2.79" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f4203d69e40a52ee523b2529a773d5ffc1dc0071801c87b3d270b471b80ed01" -dependencies = [ - "quote", - "wasm-bindgen-macro-support", -] - -[[package]] -name = "wasm-bindgen-macro-support" -version = "0.2.79" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfa8a30d46208db204854cadbb5d4baf5fcf8071ba5bf48190c3e59937962ebc" -dependencies = [ - "proc-macro2", - "quote", - "syn", - "wasm-bindgen-backend", - "wasm-bindgen-shared", -] - -[[package]] -name = "wasm-bindgen-shared" -version = "0.2.79" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d958d035c4438e28c70e4321a2911302f10135ce78a9c7834c0cab4123d06a2" - -[[package]] -name = "web-sys" -version = "0.3.56" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c060b319f29dd25724f09a2ba1418f142f539b2be99fbf4d2d5a8f7330afb8eb" -dependencies = [ - "js-sys", - "wasm-bindgen", -] - -[[package]] -name = "wepoll-ffi" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d743fdedc5c64377b5fc2bc036b01c7fd642205a0d96356034ae3404d49eb7fb" -dependencies = [ - "cc", -] - -[[package]] -name = "winapi" -version = "0.3.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" -dependencies = [ - "winapi-i686-pc-windows-gnu", - "winapi-x86_64-pc-windows-gnu", -] - -[[package]] -name = "winapi-i686-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" - -[[package]] -name = "winapi-util" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" -dependencies = [ - "winapi", -] - -[[package]] -name = "winapi-x86_64-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" diff --git a/Cargo.toml b/Cargo.toml deleted file mode 100644 index 823b4a3..0000000 --- a/Cargo.toml +++ /dev/null @@ -1,16 +0,0 @@ -[package] -name = "velnet_server" -version = "0.2.0" -edition = "2021" - -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - -[dependencies] -chrono = "*" -serde = { version = "1.0", features = ["derive"] } -serde_json = "1.0" -async-std = { version = "1.6", features = ["attributes"]} -futures = "*" -async-notify = "*" -simplelog = "^0.12.0" -log = "*" \ No newline at end of file diff --git a/config.json b/config.json deleted file mode 100644 index 4b32a32..0000000 --- a/config.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "port": 5000, - "tcp_timeout": 30, - "log_file": "server.log" -} diff --git a/control-panel/.gitignore b/control-panel/.gitignore deleted file mode 100644 index 25e2461..0000000 --- a/control-panel/.gitignore +++ /dev/null @@ -1,7 +0,0 @@ -/target -.vscode -main -main.exe -main.pdb -.idea/ -onefetch.out diff --git a/control-panel/Cargo.toml b/control-panel/Cargo.toml index 118ad7d..0e5b5ce 100644 --- a/control-panel/Cargo.toml +++ b/control-panel/Cargo.toml @@ -6,7 +6,7 @@ edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -actix-web = "4" +actix-web = "4.1.0" handlebars = { version = "4.2.1", features = ["dir_source"] } serde_json = "1.0" serde = { version = "1.0", features = ["derive"] } diff --git a/src/main.rs b/src/main.rs deleted file mode 100644 index 37b5f43..0000000 --- a/src/main.rs +++ /dev/null @@ -1,993 +0,0 @@ -use async_std::prelude::*; -use async_std::future; -use async_std::net::TcpListener; -use async_std::net::TcpStream; -use async_std::net::UdpSocket; -use async_notify::Notify; -use futures::stream::StreamExt; -use futures::join; -use futures::select; -use futures::pin_mut; -use futures::future::FutureExt; -use async_std::net::{IpAddr, SocketAddr}; -use std::collections::HashMap; -use std::rc::{Rc}; -use std::cell::{RefCell}; -use std::fs; -use chrono::Local; -use std::time::Duration; -use serde::{Serialize, Deserialize}; -use std::error::Error; -use std::fs::OpenOptions; -use std::io::BufReader; -use std::ptr; -use simplelog::*; - -enum ToClientTCPMessageType { - LoggedIn = 0, - RoomList = 1, - PlayerJoined = 2, - DataMessage = 3, - MasterMessage = 4, - YouJoined = 5, - PlayerLeft = 6, - YouLeft = 7, - RoomData = 8, -} - -enum FromClientTCPMessageType { - LogIn = 0, - GetRooms = 1, - JoinRoom = 2, - SendMessageOthersUnbuffered = 3, - SendMessageAllUnbuffered = 4, - SendMessageGroupUnbuffered = 5, - CreateGroup = 6, - SendMessageOthersBuffered = 7, - SendMessageAllBuffered = 8, - GetRoomData = 9, -} - -enum ToClientUDPMessageType { - Connected = 0, - DataMessage = ToClientTCPMessageType::DataMessage as isize, -} - -enum FromClientUDPMessageType { - Connect = 0, - SendMessageOthersUnbuffered = FromClientTCPMessageType::SendMessageOthersUnbuffered as isize, - SendMessageAllUnbuffered = FromClientTCPMessageType::SendMessageAllUnbuffered as isize, - SendMessageGroupUnbuffered = FromClientTCPMessageType::SendMessageGroupUnbuffered as isize, -} - -struct Client { - logged_in: bool, - id: u32, - username: String, - room_name: String, - application: String, - groups: HashMap>>>, - ip: IpAddr, - udp_port: u16, - message_queue: Vec, - message_queue_udp: Vec>, - notify: Rc, - notify_udp: Rc, - is_master: bool, -} - -struct Room { - name: String, - clients: HashMap>>, - master_client: Rc>, -} - -#[derive(Serialize, Deserialize)] -struct VelNetConfig { - port: u16, - tcp_timeout: u64, - log_file: String, -} - - -#[async_std::main] -async fn main() { - let config = read_config_file().unwrap(); - - let f = OpenOptions::new() - .write(true) - .append(true) - .create(true) - .open(config.log_file) - .unwrap(); - - CombinedLogger::init( - vec![ - TermLogger::new(LevelFilter::Info, Config::default(), TerminalMode::Mixed, ColorChoice::Auto), - WriteLogger::new(LevelFilter::Debug, Config::default(), f), - ] - ).unwrap(); - - log::info!("----------------------"); - log::info!("VelNet Server Starting"); - - // read the config file - let foo = fs::read_to_string("config.json").unwrap(); - let config: VelNetConfig = serde_json::from_str(&foo).unwrap(); - log::info!("Running on port: {}", config.port); - - let tcp_listener = TcpListener::bind(format!("0.0.0.0:{}", config.port)).await.unwrap(); - let udp_socket = Rc::new(RefCell::new(UdpSocket::bind(format!("0.0.0.0:{}", config.port)).await.unwrap())); - - let clients: Rc>>>> = Rc::new(RefCell::new(HashMap::new())); - let rooms: Rc>>>> = Rc::new(RefCell::new(HashMap::new())); - let last_client_id = Rc::new(RefCell::new(0)); - - let tcp_future = tcp_listener - .incoming() - .for_each_concurrent(None, |tcpstream| process_client(tcpstream.unwrap(), udp_socket.clone(), clients.clone(), rooms.clone(), last_client_id.clone(), &config)); - let udp_future = process_udp(udp_socket.clone(), clients.clone(), rooms.clone()); - join!(tcp_future,udp_future); -} - - -fn read_config_file() -> Result> { - // Open the file in read-only mode with buffer. - let file = fs::File::open("config.json")?; - let reader = BufReader::new(file); - - let config = serde_json::from_reader(reader)?; - - Ok(config) -} - -async fn process_client(socket: TcpStream, udp_socket: Rc>, clients: Rc>>>>, rooms: Rc>>>>, last_client_id: Rc>, config: &VelNetConfig) { - log::info!("Started TCP"); - - match socket.set_nodelay(true) { - Ok(_) => {} - Err(_) => { - log::error!("Could not set no delay"); - return; - } - } - //socket.set_read_timeout(Some(time::Duration::new(config.tcp_timeout,0))).unwrap(); - //socket.set_write_timeout(Some(time::Duration::new(config.tcp_timeout,0))).unwrap(); - - let my_id; - { - let mut reference = last_client_id.borrow_mut(); - *reference = *reference + 1; - my_id = *reference; - } - - - let client_notify = Rc::new(Notify::new()); - let client_notify_udp = Rc::new(Notify::new()); - - let ip; - - match socket.peer_addr() { - Ok(p) => ip = p.ip(), - Err(_) => { return; } - } - - let client = Rc::new(RefCell::new(Client { - id: my_id, - username: String::from(""), - logged_in: false, - room_name: String::from(""), - application: String::from(""), - groups: HashMap::new(), - ip: ip, - udp_port: 0 as u16, - message_queue: vec![], - message_queue_udp: vec![], - notify: client_notify.clone(), - notify_udp: client_notify_udp.clone(), - is_master: false, - })); - - - log::info!("Spawned client handler = {}", my_id); - - { - let temp_client = client.clone(); - let mut clients_temp = clients.borrow_mut(); - clients_temp.insert(my_id, temp_client); - } - - - let read_async = client_read(client.clone(), socket.clone(), clients.clone(), rooms.clone(), config.tcp_timeout * 1000).fuse(); - let write_async = client_write(client.clone(), socket, client_notify.clone(), config.tcp_timeout * 1000).fuse(); - let write_async_udp = client_write_udp(client.clone(), udp_socket.clone(), client_notify_udp.clone()).fuse(); - - pin_mut!(read_async,write_async,write_async_udp); //not sure why this is necessary, since select - - select! { // - () = read_async => log::debug!("read async ended"), - () = write_async => log::debug!("write async ended"), - () = write_async_udp => log::debug!("write async udp ended") - } - - { - client_leave_room(client.clone(), false, rooms.clone()); - let mut clients_temp = clients.borrow_mut(); - clients_temp.remove(&client.borrow().id); - } - { - log::info!("Client {} left", client.borrow().id); - } -} - -async fn read_timeout(mut socket: &TcpStream, buf: &mut [u8], duration: u64) -> Result> { - - //this is a read exact function. The buffer passed should be the exact size wanted - - let num_to_read = buf.len(); - - let mut num_read = 0; - - while num_read < num_to_read { - match future::timeout(Duration::from_millis(duration), socket.read(&mut buf[num_read..])).await { - Ok(r) => { - match r { - Ok(n) if n == 0 => { - return Err(format!("{}", "no bytes read"))?; - } - Ok(n) => { - num_read += n; - } - Err(e) => { return Err(format!("{}", e.to_string()))?; } - } - } - - Err(e) => { return Err(format!("{}", e.to_string()))?; } - } - } - - return Ok(num_read); -} - -async fn client_read(client: Rc>, mut socket: TcpStream, clients: Rc>>>>, rooms: Rc>>>>, duration: u64) { - let mut buf = [0; 1]; - - loop { - match read_timeout(&mut socket, &mut buf, duration).await { - Ok(_) => { - let t = buf[0]; - if t == FromClientTCPMessageType::LogIn as u8 { //[0:u8][username.length():u8][username:shortstring][password.length():u8][password:shortstring] - match read_login_message(socket.clone(), client.clone(), duration).await { - Ok(_) => (), - Err(_) => { - log::error!("failed to read from socket"); - return; - } - }; - } else if t == FromClientTCPMessageType::GetRooms as u8 {//[1:u8] - match read_rooms_message(socket.clone(), client.clone(), rooms.clone()).await { - Ok(_) => (), - Err(_) => { - log::error!("failed to read from socket"); - return; - } - }; - } else if t == FromClientTCPMessageType::GetRoomData as u8 { - match read_roomdata_message(socket.clone(), client.clone(), rooms.clone(), duration).await { - Ok(_) => (), - Err(_) => { - log::error!("failed to read from socket"); - return; - } - }; - } else if t == FromClientTCPMessageType::JoinRoom as u8 {//[2:u8][roomname.length():u8][roomname:shortstring] - match read_join_message(socket.clone(), client.clone(), rooms.clone(), duration).await { - Ok(_) => (), - Err(_) => { - log::error!("failed to read from socket"); - return; - } - }; - } else if t == FromClientTCPMessageType::SendMessageOthersUnbuffered as u8 || - t == FromClientTCPMessageType::SendMessageAllUnbuffered as u8 || - t == FromClientTCPMessageType::SendMessageGroupUnbuffered as u8 || - t == FromClientTCPMessageType::SendMessageOthersBuffered as u8 || - t == FromClientTCPMessageType::SendMessageAllBuffered as u8 { //others,all,group[t:u8][message.length():i32][message:u8array] - match read_send_message(socket.clone(), client.clone(), rooms.clone(), t, duration).await { - Ok(_) => (), - Err(_) => { - log::error!("failed to read from socket"); - return; - } - }; - } else if t == FromClientTCPMessageType::CreateGroup as u8 { //[t:u8][list.lengthbytes:i32][clients:i32array] - match read_group_message(socket.clone(), client.clone(), clients.clone(), duration).await { - Ok(_) => (), - Err(_) => { - log::error!("failed to read from socket"); - return; - } - }; - } else { - //die...not correct protocol - log::error!("Incorrect protocol, killing"); - return; - } - } - Err(e) => { - log::error!("failed to read from socket; err = {:?}", e); - //remove the client - return; - } - }; - } -} - - -async fn write_timeout(mut socket: &TcpStream, buf: &[u8], duration: u64) -> Result> { - return match future::timeout(Duration::from_millis(duration), socket.write(buf)).await { - Ok(r) => { - match r { - Ok(n) => { - Ok(n) - } - Err(e) => { Err(format!("{}", e.to_string()))? } - } - } - - Err(e) => { Err(format!("{}", e.to_string()))? } - }; -} - - -async fn client_write(client: Rc>, mut socket: TcpStream, notify: Rc, duration: u64) { - - //wait on messages in my queue - loop { - notify.notified().await; //there is something to write - - let mut to_write = vec![]; - { - let client_ref = client.borrow(); - to_write.extend_from_slice(&client_ref.message_queue); //must do this so that the borrow ends - } - - { - let mut client_ref = client.borrow_mut(); - client_ref.message_queue.clear(); - } - - match write_timeout(&mut socket, &to_write, duration).await { - Ok(_) => (), - Err(_) => { - log::error!("failed to write to the tcp socket"); - return; - } - } - } -} - -async fn client_write_udp(client: Rc>, socket: Rc>, notify: Rc) { - loop { - notify.notified().await; //there is something to write - - let ip; - let port; - let mut messages = vec![]; - { - let mut client_ref = client.borrow_mut(); - ip = client_ref.ip; - port = client_ref.udp_port; - for msg in client_ref.message_queue_udp.iter() { - messages.push(msg.clone()); - } - client_ref.message_queue_udp.clear(); - } - - for msg in messages.iter() { - let socket = socket.borrow(); - match socket.send_to(&msg, SocketAddr::new(ip, port)).await { - Ok(_) => (), - Err(_) => { - log::error!("failed to write to the udp socket"); - return; - } - } - } - } -} - -async fn process_udp(socket: Rc>, clients: Rc>>>>, rooms: Rc>>>>) { - let mut buf = [0u8; 1024]; - loop { - let socket = socket.borrow(); - let res = socket.recv_from(&mut buf).await; - - match res { - Ok(_) => (), - Err(_) => continue - } - - let (packet_size, addr) = res.unwrap(); - let t = buf[0]; - if packet_size >= 5 { - //get the client id, which has to be sent with every udp message, because you don't know where udp messages are coming from - let client_id_bytes = [buf[1], buf[2], buf[3], buf[4]]; - let client_id = u32::from_be_bytes(client_id_bytes); - - - if t == FromClientUDPMessageType::Connect as u8 { //1 byte, 0. Nothing else. This is just to establish the udp port, Echos back the same thing sent - //connect message, respond back - - - let clients = clients.borrow(); - if clients.contains_key(&client_id) { - let mut client = clients.get(&client_id).unwrap().borrow_mut(); - client.udp_port = addr.port(); //set the udp port to send data to - client.message_queue_udp.push(vec![0]); - client.notify_udp.notify(); - } - } else if t == FromClientUDPMessageType::SendMessageOthersUnbuffered as u8 { //[3:u8][from:i32][contents:u8array] note that it must fit into the packet of 1024 bytes - - - let clients = clients.borrow(); - if clients.contains_key(&client_id) { - let client = clients.get(&client_id).unwrap().borrow(); - let rooms_ref = rooms.borrow(); - if client.room_name != "" { - let room = rooms_ref[&client.room_name].borrow(); - buf[0] = ToClientUDPMessageType::DataMessage as u8; //technically unecessary, unless we change this number - for (_k, v) in room.clients.iter() { - if *_k != client_id { - let mut msg = vec![]; - let mut v_ref = v.borrow_mut(); - msg.extend_from_slice(&buf[0..packet_size]); - v_ref.message_queue_udp.push(msg); - v_ref.notify_udp.notify(); - } - } - } - } - } else if t == FromClientUDPMessageType::SendMessageAllUnbuffered as u8 { //see above - let clients = clients.borrow(); - if clients.contains_key(&client_id) { - let mut client = clients.get(&client_id).unwrap().borrow_mut(); - let rooms_ref = rooms.borrow(); - if client.room_name != "" { - let room = rooms_ref[&client.room_name].borrow(); - buf[0] = ToClientUDPMessageType::DataMessage as u8; //technically unecessary, unless we change this number - for (_k, v) in room.clients.iter() { - if *_k != client_id { - let mut msg = vec![]; - let mut v_ref = v.borrow_mut(); - msg.extend_from_slice(&buf[0..packet_size]); - v_ref.message_queue_udp.push(msg); - v_ref.notify_udp.notify(); - } else { - let mut msg = vec![]; - msg.extend_from_slice(&buf[0..packet_size]); - client.message_queue_udp.push(msg); - client.notify_udp.notify(); - } - } - } - } - } else if t == FromClientUDPMessageType::SendMessageGroupUnbuffered as u8 { //[5:byte][from:i32][group.length():u8][message:u8array] - //this one is a little different, because we don't send the group in the message, so we have to formulate another message (like a 3 message) - //send a message to a group - //read the group name - - let group_name_size = buf[5]; - let message_vec = buf[6..packet_size].to_vec(); - let (group_name_bytes, message_bytes) = message_vec.split_at(group_name_size as usize); - - let res = String::from_utf8(group_name_bytes.to_vec()); - match res { - Ok(_) => {} - Err(_) => { - log::error!("Could not convert group name"); - return; - } - } - - let group_name = res.unwrap(); - - let clients = clients.borrow(); - - let mut message_to_send = vec![]; - message_to_send.push(ToClientUDPMessageType::DataMessage as u8); - message_to_send.extend([buf[1], buf[2], buf[3], buf[4]]); - message_to_send.extend(message_bytes); - - let mut send_to_client = false; - if clients.contains_key(&client_id) { - { - { - let client = clients.get(&client_id).unwrap().borrow(); - if client.groups.contains_key(&group_name) { - let clients = client.groups.get(&group_name).unwrap(); - //we need to form a new message without the group name - - - for v in clients.iter() { - let mut skip_client = false; - - { - let v_ref = v.borrow(); - if v_ref.id == client.id { - skip_client = true; - send_to_client = true; - } - } - if !skip_client { - let mut v_ref = v.borrow_mut(); - v_ref.message_queue_udp.push(message_to_send.clone()); - v_ref.notify_udp.notify(); - } - } - } - } - if send_to_client { - let mut client = clients.get(&client_id).unwrap().borrow_mut(); - client.message_queue_udp.push(message_to_send.clone()); - client.notify_udp.notify(); - } - } - } - } - } - } -} - -//this is in response to someone asking to login (this is where usernames and passwords would be processed, in theory) -async fn read_login_message(mut stream: TcpStream, client: Rc>, duration: u64) -> Result<(), Box> { - //byte,shortstring,byte,shortstring - - let username = read_short_string(&mut stream, duration).await?; - let application = read_short_string(&mut stream, duration).await?; - log::info!("{}: Got application {} and userid {}", Local::now().format("%Y-%m-%d %H:%M:%S"), application, username); - { - let mut client = client.borrow_mut(); - client.username = username; - client.application = application; - client.logged_in = true; - } - - - { - let mut client = client.borrow_mut(); - let mut write_buf = vec![]; - write_buf.push(ToClientTCPMessageType::LoggedIn as u8); - write_buf.extend_from_slice(&(client.id).to_be_bytes()); //send the client the id - client.message_queue.extend(write_buf); - client.notify.notify(); - } - return Ok(()); -} - -async fn read_rooms_message(mut _stream: TcpStream, client: Rc>, rooms: Rc>>>>) -> Result<(), Box> { - let mut write_buf = vec![]; - write_buf.push(ToClientTCPMessageType::RoomList as u8); - //first we need to get the room names - - let rooms = rooms.borrow(); - let mut client = client.borrow_mut(); - let mut rooms_vec = vec![]; - for (k, v) in rooms.iter() { - if !k.starts_with(&client.application.to_string()) { - continue; - } - let mut iter = k.chars(); - - iter.by_ref().nth(client.application.len()); - let application_stripped_room = iter.as_str(); - - let room_string = format!("{}:{}", application_stripped_room, v.borrow().clients.len()); - rooms_vec.push(room_string); - } - - let rooms_message = rooms_vec.join(","); - let message_bytes = rooms_message.as_bytes(); - let message_len = message_bytes.len() as u32; - write_buf.extend_from_slice(&(message_len).to_be_bytes()); - write_buf.extend_from_slice(message_bytes); - client.message_queue.extend_from_slice(&write_buf); - client.notify.notify(); - return Ok(()); -} - -async fn read_join_message(mut stream: TcpStream, client: Rc>, rooms: Rc>>>>, duration: u64) -> Result<(), Box> { - //byte,shortstring - - let short_room_name = read_short_string(&mut stream, duration).await?; - let extended_room_name; - let mut leave_room = false; - { - let client_ref = client.borrow(); - extended_room_name = format!("{}_{}", client_ref.application, short_room_name); - if client_ref.room_name != "" { - leave_room = true; - } - } - if leave_room { - //todo - client_leave_room(client.clone(), true, rooms.clone()); - } - - let mut client_ref = client.borrow_mut(); - let mut rooms_ref = rooms.borrow_mut(); - - if short_room_name.trim() == "" || short_room_name == "-1" { - return Ok(()); - } - - if !rooms_ref.contains_key(&extended_room_name) { //new room, must create it - let map: HashMap>> = HashMap::new(); - let r = Rc::new(RefCell::new(Room { - name: extended_room_name.to_string(), - clients: map, - master_client: client.clone(), //client is the master, since they joined first - })); - client_ref.is_master = true; - rooms_ref.insert(String::from(&extended_room_name), r); - log::info!("{}: {}: New room {} created", Local::now().format("%Y-%m-%d %H:%M:%S"), client_ref.application, &extended_room_name); - } else { - client_ref.is_master = false; - } - - //the room is guaranteed to exist now, so this call can't fail - let mut room_to_join = rooms_ref[&extended_room_name].borrow_mut(); - room_to_join.clients.insert(client_ref.id, client.clone()); - log::info!("{}: {}: Client {} joined {}", Local::now().format("%Y-%m-%d %H:%M:%S"), client_ref.application, client_ref.id, &extended_room_name); - - client_ref.room_name = extended_room_name; //we create an option and assign it back to the room - - //send a join message to everyone in the room (except the client) - for (_k, v) in room_to_join.clients.iter() { - if *_k != client_ref.id { - send_client_join_message(v, client_ref.id, &short_room_name); - } - } - - //send a join message to the client that has all of the ids in the room - let mut ids_in_room = vec![]; - for (_k, _v) in room_to_join.clients.iter() { - ids_in_room.push(*_k); - } - send_you_joined_message(&mut *client_ref, ids_in_room, &short_room_name); - - if client_ref.is_master { - let temp = client_ref.id; - send_client_master_message(&mut *client_ref, temp); - } else { - send_client_master_message(&mut *client_ref, room_to_join.master_client.borrow().id); - } - - return Ok(()); -} - -async fn read_roomdata_message(mut stream: TcpStream, client: Rc>, rooms: Rc>>>>, duration: u64) -> Result<(), Box> { - //type, room_name - //will respond with type, numclients u32, id1 u32, name_len u8, name_bytes ... - - //read the room name and append the client application - - - - let short_room_name = read_short_string(&mut stream, duration).await?; - let mut client_ref = client.borrow_mut(); - let room_name = format!("{}_{}", client_ref.application, short_room_name); - - //we need to access the rooms list - let rooms_ref = rooms.borrow(); - if rooms_ref.contains_key(&room_name) { - let room = rooms_ref.get(&room_name).unwrap(); - //form and send the message - let mut write_buf = vec![]; - write_buf.push(ToClientTCPMessageType::RoomData as u8); - - - let roomname_bytes = short_room_name.as_bytes(); - write_buf.push(roomname_bytes.len() as u8); - write_buf.extend_from_slice(&roomname_bytes); - - let clients = &room.borrow().clients; - write_buf.extend_from_slice(&(clients.len() as u32).to_be_bytes()); - for (_k, c) in clients.iter() { - write_buf.extend_from_slice(&(_k).to_be_bytes()); - - if *_k != client_ref.id { - let c_ref = c.borrow(); - let username_bytes = c_ref.username.as_bytes(); - write_buf.push(username_bytes.len() as u8); - write_buf.extend_from_slice(&username_bytes); - } else { - let username_bytes = client_ref.username.as_bytes(); - write_buf.push(username_bytes.len() as u8); - write_buf.extend_from_slice(&username_bytes); - } - } - client_ref.message_queue.extend_from_slice(&write_buf); - client_ref.notify.notify(); - } - - return Ok(()); -} - -async fn read_send_message(mut stream: TcpStream, client: Rc>, rooms: Rc>>>>, message_type: u8, duration: u64) -> Result<(), Box> { - //4 byte length, array - //this is a message for everyone in the room (maybe) - let to_send = read_vec(&mut stream, duration).await?; - if message_type == FromClientTCPMessageType::SendMessageOthersUnbuffered as u8 { - send_room_message(client, &to_send, rooms.clone(), false, false); - } else if message_type == FromClientTCPMessageType::SendMessageAllUnbuffered as u8 { - send_room_message(client, &to_send, rooms.clone(), true, false); - } else if message_type == FromClientTCPMessageType::SendMessageOthersBuffered as u8 { //ordered - send_room_message(client, &to_send, rooms.clone(), false, true); - } else if message_type == FromClientTCPMessageType::SendMessageAllBuffered as u8 { //ordered - send_room_message(client, &to_send, rooms.clone(), true, true); - } else if message_type == FromClientTCPMessageType::SendMessageGroupUnbuffered as u8 { - let group = read_short_string(&mut stream, duration).await?; - send_group_message(client, &to_send, &group); - } - return Ok(()); -} - -async fn read_group_message(mut stream: TcpStream, client: Rc>, clients: Rc>>>>, duration: u64) -> Result<(), Box> { - let group = read_short_string(&mut stream, duration).await?; - let id_bytes = read_vec(&mut stream, duration).await?; - let num = id_bytes.len(); - - let mut client_ref = client.borrow_mut(); - - let clients_ref = clients.borrow(); - let mut group_clients = vec![]; - let mut i = 0; - loop { - if i >= num { - break; - } - let mut slice = [0u8; 4]; - slice[0] = id_bytes[i]; - slice[1] = id_bytes[i + 1]; - slice[2] = id_bytes[i + 2]; - slice[3] = id_bytes[i + 3]; //probably a better way to do this - let id = u32::from_be_bytes(slice); - - - match clients_ref.get(&id) { - Some(client) => { group_clients.push(client.clone()); } - None => () //not there, so don't add it - } - - i = i + 4; - } - - //delete the group if it exists - if client_ref.groups.contains_key(&group) { - client_ref.groups.remove(&group); //ensures the client references go away - } - - client_ref.groups.insert(group.clone(), group_clients); - - return Ok(()); -} - -fn client_leave_room(client: Rc>, send_to_client: bool, rooms: Rc>>>>) { - //first remove the client from the room they are in - - { - let mut client_ref = client.borrow_mut(); - let roomname = String::from(client_ref.room_name.clone()); - - if roomname == "" { //client not in room, leave - return; - } - let mut new_master_id = 0; - { - log::info!("{}: {}: Client {} in room, leaving", Local::now().format("%Y-%m-%d %H:%M:%S"), client_ref.application, client_ref.id); - } - - - let mut destroy_room = false; - { - let rooms_ref = rooms.borrow_mut(); - let mut room_ref = rooms_ref.get(&roomname).unwrap().borrow_mut(); - - for (_k, v) in room_ref.clients.iter() { - if *_k != client_ref.id { - send_client_left_message(v, client_ref.id, &roomname); - } - } - - if send_to_client && client_ref.room_name != "" { - send_you_left_message(&mut *client_ref, &roomname); - } - - room_ref.clients.remove(&client_ref.id); //remove the client from that list in the room - if room_ref.clients.len() == 0 { - destroy_room = true; - } - } - //if the room is empty, destroy it as well - let mut rooms_ref = rooms.borrow_mut(); - if destroy_room { - rooms_ref.remove(&roomname); - log::info!("{}: {}: Destroyed room {}", Local::now().format("%Y-%m-%d %H:%M:%S"), client_ref.application, &roomname) - } else if client_ref.is_master { //we need to change the master! - let mut room_ref = rooms_ref.get(&roomname).unwrap().borrow_mut(); - for (_k, v) in room_ref.clients.iter() { - if *_k != client_ref.id { - new_master_id = v.borrow().id; - break; - } - } - - log::info!("{}: {}: Changing master to {}", Local::now().format("%Y-%m-%d %H:%M:%S"), client_ref.application, new_master_id); - - for (_k, v) in room_ref.clients.iter() { - let mut c = v.borrow_mut(); - send_client_master_message(&mut *c, new_master_id); - } - room_ref.master_client = room_ref.clients.get(&new_master_id).unwrap().clone(); - room_ref.master_client.borrow_mut().is_master = true; - client_ref.is_master = false; - } - } - let mut client_ref = client.borrow_mut(); - client_ref.room_name = String::from(""); -} - -fn send_you_left_message(client_ref: &mut Client, room: &str) { - let mut write_buf = vec![]; - write_buf.push(ToClientTCPMessageType::YouLeft as u8); - write_buf.push(room.as_bytes().len() as u8); - write_buf.extend_from_slice(room.as_bytes()); - client_ref.message_queue.extend_from_slice(&write_buf); - client_ref.notify.notify(); -} - -fn send_client_left_message(to: &Rc>, from: u32, room: &str) { - let mut write_buf = vec![]; - write_buf.push(ToClientTCPMessageType::PlayerLeft as u8); - write_buf.extend_from_slice(&(from).to_be_bytes()); //send everyone that the client id left the room - write_buf.push(room.as_bytes().len() as u8); - write_buf.extend_from_slice(room.as_bytes()); - let mut client_ref = to.borrow_mut(); - client_ref.message_queue.extend_from_slice(&write_buf); - client_ref.notify.notify(); -} - -fn send_client_join_message(to: &Rc>, from: u32, room: &str) { - //2u8, person_id_u32, room_name_len_u8, room_name_bytes - let mut write_buf = vec![]; - write_buf.push(ToClientTCPMessageType::PlayerJoined as u8); - write_buf.extend_from_slice(&(from).to_be_bytes()); //send everyone that the client id joined the room - write_buf.push(room.as_bytes().len() as u8); - write_buf.extend_from_slice(room.as_bytes()); - let mut client_ref = to.borrow_mut(); - client_ref.message_queue.extend_from_slice(&write_buf); - client_ref.notify.notify(); -} - -fn send_you_joined_message(client_ref: &mut Client, in_room: Vec, room: &str) { - //you_joined_u8, ids_len_u32, id_list_array_u32, room_name_len_u8, room_name_bytes - let mut write_buf = vec![]; - write_buf.push(ToClientTCPMessageType::YouJoined as u8); - write_buf.extend_from_slice(&(in_room.len() as u32).to_be_bytes()); - for id in in_room { - write_buf.extend_from_slice(&(id).to_be_bytes()); - } - write_buf.push(room.as_bytes().len() as u8); - write_buf.extend_from_slice(room.as_bytes()); - client_ref.message_queue.extend_from_slice(&write_buf); - client_ref.notify.notify(); -} - -fn send_client_master_message(client_ref: &mut Client, master_id: u32) { - //2u8, person_id_u32, room_name_len_u8, room_name_bytes - let mut write_buf = vec![]; - write_buf.push(ToClientTCPMessageType::MasterMessage as u8); - write_buf.extend_from_slice(&(master_id).to_be_bytes()); //send everyone that the client id joined the room - client_ref.message_queue.extend_from_slice(&write_buf); - client_ref.notify.notify(); -} - -fn send_room_message(sender: Rc>, message: &Vec, rooms: Rc>>>>, include_sender: bool, _ordered: bool) { - //this message is 3u8, sender_id_u32, message_len_u32, message_bytes - - let mut write_buf = vec![]; - - - let mut sender_ref = sender.borrow_mut(); - write_buf.push(ToClientTCPMessageType::DataMessage as u8); - write_buf.extend_from_slice(&sender_ref.id.to_be_bytes()); - write_buf.extend_from_slice(&(message.len() as u32).to_be_bytes()); - write_buf.extend_from_slice(message); - - - if sender_ref.room_name == "" { - return; - } - - - if include_sender { - sender_ref.message_queue.extend_from_slice(&write_buf); - sender_ref.notify.notify(); - } - - let rooms_ref = rooms.borrow(); - let room_ref = rooms_ref[&sender_ref.room_name].borrow(); - - for (_k, v) in room_ref.clients.iter() { - if *_k != sender_ref.id { - let mut temp_mut = v.borrow_mut(); - temp_mut.message_queue.extend_from_slice(&write_buf); - temp_mut.notify.notify(); - } - } -} - -fn send_group_message(sender: Rc>, message: &Vec, group: &String) { - let mut write_buf = vec![]; - let mut sender_ref = sender.borrow_mut(); - write_buf.push(ToClientTCPMessageType::DataMessage as u8); - write_buf.extend_from_slice(&sender_ref.id.to_be_bytes()); - write_buf.extend_from_slice(&(message.len() as u32).to_be_bytes()); - write_buf.extend_from_slice(message); - - //get the list of client ids for this group - let mut send_to_client = false; - if sender_ref.groups.contains_key(group) { - let group = sender_ref.groups.get(group).unwrap(); - for c in group { - if ptr::eq(sender.as_ref(), c.as_ref()) { - send_to_client = true; - } else { - let mut temp_mut = c.borrow_mut(); - temp_mut.message_queue.extend_from_slice(&write_buf); - temp_mut.notify.notify(); - } - } - } - - if send_to_client { - sender_ref.message_queue.extend_from_slice(&write_buf); - sender_ref.notify.notify(); - } -} - -async fn read_u8(stream: &mut TcpStream, duration: u64) -> Result> { - let mut buf = [0; 1]; - read_timeout(stream, &mut buf, duration).await?; - return Ok(buf[0]); -} - -async fn read_u32(stream: &mut TcpStream, duration: u64) -> Result> { - let mut buf: [u8; 4] = [0; 4]; - read_timeout(stream, &mut buf, duration).await?; - let size = u32::from_be_bytes(buf); - return Ok(size); -} - -async fn _read_string(stream: &mut TcpStream, duration: u64) -> Result> { - let size = read_u32(stream, duration).await?; - let mut string_bytes = vec![0; size as usize]; - read_timeout(stream, &mut string_bytes, duration).await?; - return Ok(String::from_utf8(string_bytes)?); -} - -async fn read_short_string(stream: &mut TcpStream, duration: u64) -> Result> { - let size = read_u8(stream, duration).await?; - let mut string_bytes = vec![0; size as usize]; - read_timeout(stream, &mut string_bytes, duration).await?; - return Ok(String::from_utf8(string_bytes)?); -} - -async fn read_vec(stream: &mut TcpStream, duration: u64) -> Result, Box> { - let message_size = read_u32(stream, duration).await?; - let mut message = vec![0u8; message_size as usize]; - read_timeout(stream, &mut message, duration).await?; - return Ok(message); -} -