my computer is dying
This commit is contained in:
parent
d3e6467c6c
commit
d98e56d413
240
Cargo.lock
generated
240
Cargo.lock
generated
@ -8,18 +8,41 @@ version = "2.0.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627"
|
checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "ahash"
|
||||||
|
version = "0.8.11"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if",
|
||||||
|
"const-random",
|
||||||
|
"getrandom",
|
||||||
|
"once_cell",
|
||||||
|
"version_check",
|
||||||
|
"zerocopy",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "aho-corasick"
|
||||||
|
version = "1.1.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916"
|
||||||
|
dependencies = [
|
||||||
|
"memchr",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "autocfg"
|
||||||
|
version = "1.4.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bitflags"
|
name = "bitflags"
|
||||||
version = "2.8.0"
|
version = "2.8.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "8f68f53c83ab957f72c32642f3868eec03eb974d1fb82e453128456482613d36"
|
checksum = "8f68f53c83ab957f72c32642f3868eec03eb974d1fb82e453128456482613d36"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "byteorder"
|
|
||||||
version = "1.5.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cfg-if"
|
name = "cfg-if"
|
||||||
version = "1.0.0"
|
version = "1.0.0"
|
||||||
@ -42,6 +65,26 @@ dependencies = [
|
|||||||
"windows-sys 0.59.0",
|
"windows-sys 0.59.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "const-random"
|
||||||
|
version = "0.1.18"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "87e00182fe74b066627d63b85fd550ac2998d4b0bd86bfed477a0ae4c7c71359"
|
||||||
|
dependencies = [
|
||||||
|
"const-random-macro",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "const-random-macro"
|
||||||
|
version = "0.1.16"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f9d839f2a20b0aee515dc581a6172f2321f96cab76c1a38a4c584a194955390e"
|
||||||
|
dependencies = [
|
||||||
|
"getrandom",
|
||||||
|
"once_cell",
|
||||||
|
"tiny-keccak",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "crc32fast"
|
name = "crc32fast"
|
||||||
version = "1.4.2"
|
version = "1.4.2"
|
||||||
@ -51,6 +94,12 @@ dependencies = [
|
|||||||
"cfg-if",
|
"cfg-if",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "crunchy"
|
||||||
|
version = "0.2.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "43da5946c66ffcc7745f48db692ffbb10a83bfe0afd96235c5c2a4fb23994929"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ctrlc"
|
name = "ctrlc"
|
||||||
version = "3.4.5"
|
version = "3.4.5"
|
||||||
@ -91,6 +140,15 @@ dependencies = [
|
|||||||
"wasi",
|
"wasi",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "instant"
|
||||||
|
version = "0.1.13"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e0242819d153cba4b4b05a5a8f2a7e9bbf97b6055b2a002b395c96b5ff3c0222"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "itoa"
|
name = "itoa"
|
||||||
version = "1.0.14"
|
version = "1.0.14"
|
||||||
@ -119,15 +177,20 @@ checksum = "30bde2b3dc3671ae49d8e2e9f044c7c005836e7a023ee57cffa25ab82764bb9e"
|
|||||||
name = "mcrizzledizzle"
|
name = "mcrizzledizzle"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"colored",
|
|
||||||
"ctrlc",
|
"ctrlc",
|
||||||
"flate2",
|
"flate2",
|
||||||
"lazy_static",
|
|
||||||
"log",
|
"log",
|
||||||
"rand",
|
"regex",
|
||||||
|
"rhai",
|
||||||
"simple_logger",
|
"simple_logger",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "memchr"
|
||||||
|
version = "2.7.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "miniz_oxide"
|
name = "miniz_oxide"
|
||||||
version = "0.8.5"
|
version = "0.8.5"
|
||||||
@ -149,12 +212,30 @@ dependencies = [
|
|||||||
"libc",
|
"libc",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "no-std-compat"
|
||||||
|
version = "0.4.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b93853da6d84c2e3c7d730d6473e8817692dd89be387eb01b94d7f108ecb5b8c"
|
||||||
|
dependencies = [
|
||||||
|
"spin",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "num-conv"
|
name = "num-conv"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9"
|
checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "num-traits"
|
||||||
|
version = "0.2.19"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841"
|
||||||
|
dependencies = [
|
||||||
|
"autocfg",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "num_threads"
|
name = "num_threads"
|
||||||
version = "0.1.7"
|
version = "0.1.7"
|
||||||
@ -164,21 +245,27 @@ dependencies = [
|
|||||||
"libc",
|
"libc",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "once_cell"
|
||||||
|
version = "1.20.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "945462a4b81e43c4e3ba96bd7b49d834c6f61198356aa858733bc4acf3cbe62e"
|
||||||
|
dependencies = [
|
||||||
|
"portable-atomic",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "portable-atomic"
|
||||||
|
version = "1.11.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "350e9b48cbc6b0e028b0473b114454c6316e57336ee184ceab6e53f72c178b3e"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "powerfmt"
|
name = "powerfmt"
|
||||||
version = "0.2.0"
|
version = "0.2.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391"
|
checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "ppv-lite86"
|
|
||||||
version = "0.2.20"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "77957b295656769bb8ad2b6a6b09d897d94f05c41b069aede1fcdaa675eaea04"
|
|
||||||
dependencies = [
|
|
||||||
"zerocopy",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "proc-macro2"
|
name = "proc-macro2"
|
||||||
version = "1.0.93"
|
version = "1.0.93"
|
||||||
@ -198,33 +285,61 @@ dependencies = [
|
|||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rand"
|
name = "regex"
|
||||||
|
version = "1.11.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191"
|
||||||
|
dependencies = [
|
||||||
|
"aho-corasick",
|
||||||
|
"memchr",
|
||||||
|
"regex-automata",
|
||||||
|
"regex-syntax",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "regex-automata"
|
||||||
|
version = "0.4.9"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908"
|
||||||
|
dependencies = [
|
||||||
|
"aho-corasick",
|
||||||
|
"memchr",
|
||||||
|
"regex-syntax",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "regex-syntax"
|
||||||
version = "0.8.5"
|
version = "0.8.5"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
|
checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rhai"
|
||||||
|
version = "1.21.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ce4d759a4729a655ddfdbb3ff6e77fb9eadd902dae12319455557796e435d2a6"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"libc",
|
"ahash",
|
||||||
"rand_chacha",
|
"bitflags",
|
||||||
"rand_core",
|
"instant",
|
||||||
|
"no-std-compat",
|
||||||
|
"num-traits",
|
||||||
|
"once_cell",
|
||||||
|
"rhai_codegen",
|
||||||
|
"smallvec",
|
||||||
|
"smartstring",
|
||||||
|
"thin-vec",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rand_chacha"
|
name = "rhai_codegen"
|
||||||
version = "0.3.1"
|
version = "2.2.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
|
checksum = "a5a11a05ee1ce44058fa3d5961d05194fdbe3ad6b40f904af764d81b86450e6b"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"ppv-lite86",
|
"proc-macro2",
|
||||||
"rand_core",
|
"quote",
|
||||||
]
|
"syn",
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "rand_core"
|
|
||||||
version = "0.6.4"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
|
|
||||||
dependencies = [
|
|
||||||
"getrandom",
|
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -259,6 +374,35 @@ dependencies = [
|
|||||||
"windows-sys 0.48.0",
|
"windows-sys 0.48.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "smallvec"
|
||||||
|
version = "1.14.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7fcf8323ef1faaee30a44a340193b1ac6814fd9b7b4e88e9d4519a3e4abe1cfd"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "smartstring"
|
||||||
|
version = "1.0.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "3fb72c633efbaa2dd666986505016c32c3044395ceaf881518399d2f4127ee29"
|
||||||
|
dependencies = [
|
||||||
|
"autocfg",
|
||||||
|
"static_assertions",
|
||||||
|
"version_check",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "spin"
|
||||||
|
version = "0.5.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "static_assertions"
|
||||||
|
version = "1.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "syn"
|
name = "syn"
|
||||||
version = "2.0.98"
|
version = "2.0.98"
|
||||||
@ -270,6 +414,12 @@ dependencies = [
|
|||||||
"unicode-ident",
|
"unicode-ident",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "thin-vec"
|
||||||
|
version = "0.2.13"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a38c90d48152c236a3ab59271da4f4ae63d678c5d7ad6b7714d7cb9760be5e4b"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "time"
|
name = "time"
|
||||||
version = "0.3.37"
|
version = "0.3.37"
|
||||||
@ -303,12 +453,27 @@ dependencies = [
|
|||||||
"time-core",
|
"time-core",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tiny-keccak"
|
||||||
|
version = "2.0.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "2c9d3793400a45f954c52e73d068316d76b6f4e36977e3fcebb13a2721e80237"
|
||||||
|
dependencies = [
|
||||||
|
"crunchy",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "unicode-ident"
|
name = "unicode-ident"
|
||||||
version = "1.0.17"
|
version = "1.0.17"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "00e2473a93778eb0bad35909dff6a10d28e63f792f16ed15e404fca9d5eeedbe"
|
checksum = "00e2473a93778eb0bad35909dff6a10d28e63f792f16ed15e404fca9d5eeedbe"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "version_check"
|
||||||
|
version = "0.9.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wasi"
|
name = "wasi"
|
||||||
version = "0.11.0+wasi-snapshot-preview1"
|
version = "0.11.0+wasi-snapshot-preview1"
|
||||||
@ -460,7 +625,6 @@ version = "0.7.35"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0"
|
checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"byteorder",
|
|
||||||
"zerocopy-derive",
|
"zerocopy-derive",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -4,13 +4,15 @@ version = "0.1.0"
|
|||||||
edition = "2021"
|
edition = "2021"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
colored = "2.1.0"
|
|
||||||
ctrlc = "3.4.5"
|
ctrlc = "3.4.5"
|
||||||
flate2 = "1.0.30"
|
flate2 = "1.0.30"
|
||||||
lazy_static = "1.4.0"
|
|
||||||
log = "0.4.26"
|
log = "0.4.26"
|
||||||
rand = "0.8.5"
|
regex = "1.11.1"
|
||||||
|
|
||||||
[dependencies.simple_logger]
|
[dependencies.simple_logger]
|
||||||
version = "5.0.0"
|
version = "5.0.0"
|
||||||
features = ["threads", "nightly"]
|
features = ["threads", "nightly"]
|
||||||
|
|
||||||
|
[dependencies.rhai]
|
||||||
|
version = "1.21.0"
|
||||||
|
features = ["sync"]
|
||||||
|
82
src/command.rs
Normal file
82
src/command.rs
Normal file
@ -0,0 +1,82 @@
|
|||||||
|
use log::error;
|
||||||
|
use std::io::prelude::*;
|
||||||
|
use std::net::TcpStream;
|
||||||
|
use std::sync::{Arc, Mutex};
|
||||||
|
|
||||||
|
use crate::error::AppError;
|
||||||
|
use crate::extensions::Extensions;
|
||||||
|
use crate::player::{Player, SpecialPlayers};
|
||||||
|
use crate::utils::*;
|
||||||
|
|
||||||
|
pub fn handle_command(
|
||||||
|
stream: &mut TcpStream,
|
||||||
|
client_number: u8,
|
||||||
|
players_arc_clone: &Arc<Mutex<[Player; 255]>>,
|
||||||
|
extensions: &Arc<Extensions>,
|
||||||
|
command_string: &String,
|
||||||
|
) -> Result<(), AppError> {
|
||||||
|
let vectorized_command = command_string.split(" ").collect::<Vec<&str>>();
|
||||||
|
match vectorized_command[0] {
|
||||||
|
"kick" => {
|
||||||
|
let mut players = players_arc_clone
|
||||||
|
.lock()
|
||||||
|
.map_err(|e| AppError::MutexPoisoned(e.to_string()))?;
|
||||||
|
for i in 0..players.len() {
|
||||||
|
if players[i].id != 255 {
|
||||||
|
if players[i].username == vectorized_command[1] {
|
||||||
|
let _ = &mut players[i]
|
||||||
|
.outgoing_data
|
||||||
|
.extend_from_slice(&client_disconnect("KICKED!"));
|
||||||
|
players[i].id = 255;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"tp" => {
|
||||||
|
let players = players_arc_clone
|
||||||
|
.lock()
|
||||||
|
.map_err(|e| AppError::MutexPoisoned(e.to_string()))?;
|
||||||
|
for i in 0..players.len() {
|
||||||
|
if players[i].id != 255 {
|
||||||
|
if players[i].username == vectorized_command[1] {
|
||||||
|
let _ = &mut stream.write(&set_position_and_orientation(
|
||||||
|
SpecialPlayers::SelfPlayer as u8,
|
||||||
|
players[i].position_x,
|
||||||
|
players[i].position_y,
|
||||||
|
players[i].position_z,
|
||||||
|
players[i].yaw,
|
||||||
|
players[i].pitch,
|
||||||
|
));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
let found = match extensions.run_command(vectorized_command[0].to_string(), client_number) {
|
||||||
|
Ok(result) => result,
|
||||||
|
Err(error) => {
|
||||||
|
error!("Rhai plugin error: {}", error);
|
||||||
|
let _ = &mut stream.write(&send_chat_message(
|
||||||
|
SpecialPlayers::SelfPlayer as u8,
|
||||||
|
"".to_string(),
|
||||||
|
"&cAn internal error occured while processing this command".to_string(),
|
||||||
|
));
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
if found {
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
|
||||||
|
let _ = &mut stream.write(&send_chat_message(
|
||||||
|
SpecialPlayers::SelfPlayer as u8,
|
||||||
|
"".to_string(),
|
||||||
|
"&cUnkown command!".to_string(),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
54
src/error.rs
54
src/error.rs
@ -1,16 +1,34 @@
|
|||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
use std::num::{ParseIntError, ParseFloatError, TryFromIntError};
|
||||||
|
use std::sync::PoisonError;
|
||||||
|
|
||||||
|
use rhai::EvalAltResult;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum AppError {
|
pub enum AppError {
|
||||||
IoError(std::io::Error),
|
IoError(std::io::Error),
|
||||||
|
RegexError(regex::Error),
|
||||||
|
ParseIntError(ParseIntError),
|
||||||
|
ParseFloatError(ParseFloatError),
|
||||||
|
TryFromIntError(TryFromIntError),
|
||||||
|
RhaiError(Box<EvalAltResult>),
|
||||||
|
MutexPoisoned(String),
|
||||||
InvalidWorldFile,
|
InvalidWorldFile,
|
||||||
|
// InvalidExtensionVersion,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl fmt::Display for AppError {
|
impl fmt::Display for AppError {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
match self {
|
match self {
|
||||||
AppError::IoError(err) => write!(f, "IO Error: {}", err),
|
AppError::IoError(err) => write!(f, "IO Error: {}", err),
|
||||||
|
AppError::RegexError(err) => write!(f, "Extension Regex Error: {}", err),
|
||||||
|
AppError::ParseIntError(err) => write!(f, "Parse int error: {}", err),
|
||||||
|
AppError::ParseFloatError(err) => write!(f, "Parse float error: {}", err),
|
||||||
|
AppError::TryFromIntError(err) => write!(f, "Integer conversion error: {}", err),
|
||||||
|
AppError::RhaiError(err) => write!(f, "Rhai compilation error: {}", err),
|
||||||
|
AppError::MutexPoisoned(err) => write!(f, "Poisoned mutex: {}", err),
|
||||||
AppError::InvalidWorldFile => write!(f, "Invalid world file"),
|
AppError::InvalidWorldFile => write!(f, "Invalid world file"),
|
||||||
|
// AppError::InvalidExtensionVersion => write!(f, "Invalid extension version"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -20,3 +38,39 @@ impl From<std::io::Error> for AppError {
|
|||||||
AppError::IoError(err)
|
AppError::IoError(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl From<regex::Error> for AppError {
|
||||||
|
fn from(err: regex::Error) -> Self {
|
||||||
|
AppError::RegexError(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<ParseIntError> for AppError {
|
||||||
|
fn from(err: ParseIntError) -> Self {
|
||||||
|
AppError::ParseIntError(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<ParseFloatError> for AppError {
|
||||||
|
fn from(err: ParseFloatError) -> Self {
|
||||||
|
AppError::ParseFloatError(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<TryFromIntError> for AppError {
|
||||||
|
fn from(err: TryFromIntError) -> Self {
|
||||||
|
AppError::TryFromIntError(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<Box<EvalAltResult>> for AppError {
|
||||||
|
fn from(err: Box<EvalAltResult>) -> Self {
|
||||||
|
AppError::RhaiError(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> From<PoisonError<T>> for AppError {
|
||||||
|
fn from(err: PoisonError<T>) -> Self {
|
||||||
|
AppError::MutexPoisoned(err.to_string())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
271
src/extensions.rs
Normal file
271
src/extensions.rs
Normal file
@ -0,0 +1,271 @@
|
|||||||
|
use log::{error, info};
|
||||||
|
use regex::Regex;
|
||||||
|
use rhai::{CustomType, Engine, EvalAltResult, FnPtr, Scope, TypeBuilder, AST};
|
||||||
|
use std::{
|
||||||
|
collections::HashMap,
|
||||||
|
ffi::OsStr,
|
||||||
|
fs,
|
||||||
|
path::Path,
|
||||||
|
sync::{Arc, Mutex},
|
||||||
|
};
|
||||||
|
|
||||||
|
use crate::{error::AppError, player::Player, utils::send_chat_message};
|
||||||
|
|
||||||
|
pub struct Extensions {
|
||||||
|
extensions: Vec<Extension>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Extensions {
|
||||||
|
pub fn run_command(&self, key: String, player: u8) -> Result<bool, AppError> {
|
||||||
|
// Bool success
|
||||||
|
for extension in &self.extensions {
|
||||||
|
if let Some(key_value) = extension.commands.get(&key) {
|
||||||
|
key_value.call::<()>(&extension.engine, &extension.ast, (player,))?;
|
||||||
|
return Ok(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct Extension {
|
||||||
|
ast: AST,
|
||||||
|
engine: Engine,
|
||||||
|
commands: HashMap<String, FnPtr>,
|
||||||
|
metadata: ExtensionMetadata,
|
||||||
|
}
|
||||||
|
|
||||||
|
////// BEGIN RHAI DEFINITIONS //////
|
||||||
|
#[derive(Debug, Clone, Eq, PartialEq, CustomType)]
|
||||||
|
#[rhai_type(name = "Version", extra = Self::build_extra)]
|
||||||
|
struct Version {
|
||||||
|
major: u16,
|
||||||
|
minor: u16,
|
||||||
|
patch: u16,
|
||||||
|
prerelease: String,
|
||||||
|
build: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Version {
|
||||||
|
pub fn display(&self) -> String {
|
||||||
|
let mut base = format!("{}.{}.{}", self.major, self.minor, self.patch);
|
||||||
|
|
||||||
|
if !self.prerelease.is_empty() {
|
||||||
|
base.push_str(&format!("-{}", self.prerelease).to_string());
|
||||||
|
}
|
||||||
|
|
||||||
|
if !self.build.is_empty() {
|
||||||
|
base.push_str(&format!("+{}", self.build).to_string());
|
||||||
|
}
|
||||||
|
|
||||||
|
base
|
||||||
|
}
|
||||||
|
|
||||||
|
fn parse(version_string: String) -> Result<Self, Box<EvalAltResult>> {
|
||||||
|
let Ok(re) = Regex::new(
|
||||||
|
r"^(?P<major>0|[1-9]\d*)\.(?P<minor>0|[1-9]\d*)\.(?P<patch>0|[1-9]\d*)(?:-(?P<prerelease>(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+(?P<buildmetadata>[0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$",
|
||||||
|
) else {
|
||||||
|
return Err("Failed to create regex".into());
|
||||||
|
};
|
||||||
|
|
||||||
|
let Some(version_parts) = re.captures(&version_string) else {
|
||||||
|
return Err("Invalid Extension Version".into());
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut prerelease: String = "".to_string();
|
||||||
|
let mut build: String = "".to_string();
|
||||||
|
|
||||||
|
if version_parts.name("prerelease").is_some() {
|
||||||
|
prerelease = version_parts["prerelease"].to_string();
|
||||||
|
}
|
||||||
|
if version_parts.name("buildmetadata").is_some() {
|
||||||
|
build = version_parts["buildmetadata"].to_string();
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(Version {
|
||||||
|
major: version_parts["major"].parse::<u16>().unwrap(),
|
||||||
|
minor: version_parts["minor"].parse::<u16>().unwrap(),
|
||||||
|
patch: version_parts["patch"].parse::<u16>().unwrap(),
|
||||||
|
prerelease,
|
||||||
|
build,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn build_extra(builder: &mut TypeBuilder<Self>) {
|
||||||
|
// Register constructor function
|
||||||
|
builder.with_fn("Version", Self::parse);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Eq, PartialEq, CustomType)]
|
||||||
|
#[rhai_type(name = "Metadata", extra = Self::build_extra)]
|
||||||
|
struct ExtensionMetadata {
|
||||||
|
name: String,
|
||||||
|
version: Version,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ExtensionMetadata {
|
||||||
|
fn new(name: String, version: Version) -> Self {
|
||||||
|
Self { name, version }
|
||||||
|
}
|
||||||
|
|
||||||
|
fn build_extra(builder: &mut TypeBuilder<Self>) {
|
||||||
|
// Register constructor function
|
||||||
|
builder.with_fn("Metadata", Self::new);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, CustomType)]
|
||||||
|
#[rhai_type(name = "Player")]
|
||||||
|
struct RhaiPlayer {
|
||||||
|
id: u8,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, CustomType)]
|
||||||
|
#[rhai_type(name = "PlayersWrapper")]
|
||||||
|
pub struct PlayersWrapper(Arc<Mutex<[Player; 255]>>);
|
||||||
|
|
||||||
|
impl PlayersWrapper {
|
||||||
|
pub fn new(players: Arc<Mutex<[Player; 255]>>) -> Self {
|
||||||
|
Self(players)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn send_message(&self, player: RhaiPlayer, message: String) -> Result<(), Box<EvalAltResult>> {
|
||||||
|
let mut players = self.0.lock().unwrap();
|
||||||
|
|
||||||
|
players[player.id as usize]
|
||||||
|
.outgoing_data
|
||||||
|
.extend_from_slice(&send_chat_message(255, "".to_string(), message));
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, CustomType)]
|
||||||
|
#[rhai_type(name = "Context", extra = Self::build_extra)]
|
||||||
|
struct Context {
|
||||||
|
#[rhai_type(skip)]
|
||||||
|
commands: HashMap<String, FnPtr>,
|
||||||
|
#[rhai_type(skip)]
|
||||||
|
players: PlayersWrapper,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Context {
|
||||||
|
fn new(players: PlayersWrapper) -> Self {
|
||||||
|
Self {
|
||||||
|
commands: HashMap::new(),
|
||||||
|
players,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn players(&mut self) -> PlayersWrapper {
|
||||||
|
self.players.clone()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn register_command(&mut self, name: String, callback: FnPtr) {
|
||||||
|
self.commands.insert(name, callback);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn build_extra(builder: &mut TypeBuilder<Self>) {
|
||||||
|
builder.with_fn("Context", Self::new);
|
||||||
|
builder.with_fn("register_command", Self::register_command);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
////// END RHAI DEFINITIONS //////
|
||||||
|
|
||||||
|
impl Extensions {
|
||||||
|
pub fn init(players: PlayersWrapper) -> Result<Extensions, AppError> {
|
||||||
|
if !Path::new("./extensions/").exists() {
|
||||||
|
let _ = fs::create_dir("./extensions/");
|
||||||
|
}
|
||||||
|
|
||||||
|
let extensions_listing = fs::read_dir("./extensions")?;
|
||||||
|
|
||||||
|
let mut extensions = Extensions {
|
||||||
|
extensions: Vec::new(),
|
||||||
|
};
|
||||||
|
|
||||||
|
for extension in extensions_listing {
|
||||||
|
let extension_path = extension?.path();
|
||||||
|
|
||||||
|
if extension_path.extension() != Some(OsStr::new("rhai")) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
info!("Loading extension {}", extension_path.display());
|
||||||
|
|
||||||
|
let mut engine = Engine::new();
|
||||||
|
engine.build_type::<Version>();
|
||||||
|
engine.build_type::<ExtensionMetadata>();
|
||||||
|
engine.build_type::<RhaiPlayer>();
|
||||||
|
engine.build_type::<PlayersWrapper>();
|
||||||
|
engine.build_type::<Context>();
|
||||||
|
|
||||||
|
let ast = engine.compile_file(extension_path.clone().into())?;
|
||||||
|
let mut scope = Scope::new();
|
||||||
|
|
||||||
|
let extension_metadata =
|
||||||
|
match engine.call_fn::<ExtensionMetadata>(&mut scope, &ast, "metadata", ()) {
|
||||||
|
Ok(result) => result,
|
||||||
|
Err(error) => {
|
||||||
|
error!(
|
||||||
|
"Rhai plugin with path {} missing critical section metadata! {}",
|
||||||
|
extension_path.display(),
|
||||||
|
error
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut current_extension = Extension {
|
||||||
|
ast,
|
||||||
|
engine,
|
||||||
|
commands: HashMap::new(),
|
||||||
|
metadata: extension_metadata,
|
||||||
|
};
|
||||||
|
|
||||||
|
let ctx = match current_extension.engine.call_fn::<Context>(
|
||||||
|
&mut scope,
|
||||||
|
¤t_extension.ast,
|
||||||
|
"init",
|
||||||
|
(PlayersWrapper::new(players.0.clone()),)
|
||||||
|
) {
|
||||||
|
Ok(result) => result,
|
||||||
|
Err(error) => {
|
||||||
|
error!(
|
||||||
|
"Plugin {} failed to init: {}",
|
||||||
|
current_extension.metadata.name, error
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
for (key, value) in ctx.commands.iter() {
|
||||||
|
current_extension
|
||||||
|
.commands
|
||||||
|
.insert(key.to_string(), value.clone());
|
||||||
|
}
|
||||||
|
|
||||||
|
info!(
|
||||||
|
"Loaded {} v{}",
|
||||||
|
current_extension.metadata.name,
|
||||||
|
current_extension.metadata.version.display()
|
||||||
|
);
|
||||||
|
|
||||||
|
extensions.extensions.push(current_extension);
|
||||||
|
}
|
||||||
|
|
||||||
|
for extension in &extensions.extensions {
|
||||||
|
for command_name in extension.commands.keys() {
|
||||||
|
info!(
|
||||||
|
"Extension {} v{} has reserved command: {}",
|
||||||
|
extension.metadata.name,
|
||||||
|
extension.metadata.version.display(),
|
||||||
|
command_name
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(extensions)
|
||||||
|
}
|
||||||
|
}
|
11
src/extensions/jimmy.rhai
Normal file
11
src/extensions/jimmy.rhai
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
fn metadata() {
|
||||||
|
Metadata("jimmy", Version("2.0.0-balls+tweaking"))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn init(players) {
|
||||||
|
let ctx = Context(players);
|
||||||
|
ctx.register_command("jimmy", |player| {
|
||||||
|
players.send_message("He's dead")
|
||||||
|
});
|
||||||
|
ctx
|
||||||
|
}
|
10
src/extensions/ping-pong.rhai
Normal file
10
src/extensions/ping-pong.rhai
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
fn metadata() {
|
||||||
|
Metadata("ping pong", Version("1.0.0"))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn init() {
|
||||||
|
let ctx = Context();
|
||||||
|
ctx.register_command("ping", |player| player.sendMessage("Pong! (you smell)"));
|
||||||
|
ctx.register_command("test", |player| player.sendMessage("test"));
|
||||||
|
ctx
|
||||||
|
}
|
18
src/main.rs
18
src/main.rs
@ -3,13 +3,16 @@ use simple_logger::SimpleLogger;
|
|||||||
use std::net::{SocketAddr, TcpListener};
|
use std::net::{SocketAddr, TcpListener};
|
||||||
use std::sync::{Arc, Mutex};
|
use std::sync::{Arc, Mutex};
|
||||||
|
|
||||||
|
mod command;
|
||||||
mod error;
|
mod error;
|
||||||
|
mod extensions;
|
||||||
mod network;
|
mod network;
|
||||||
mod player;
|
mod player;
|
||||||
mod utils;
|
mod utils;
|
||||||
mod world;
|
mod world;
|
||||||
|
|
||||||
use error::AppError;
|
use error::AppError;
|
||||||
|
use extensions::{Extensions, PlayersWrapper};
|
||||||
use network::handle_client;
|
use network::handle_client;
|
||||||
use player::{Player, SpecialPlayers};
|
use player::{Player, SpecialPlayers};
|
||||||
use world::World;
|
use world::World;
|
||||||
@ -39,15 +42,26 @@ fn run() -> Result<(), AppError> {
|
|||||||
ctrlc::set_handler(move || {
|
ctrlc::set_handler(move || {
|
||||||
println!("");
|
println!("");
|
||||||
info!("SAVING");
|
info!("SAVING");
|
||||||
let _ = World::save(world_arc_clone_main_thread.clone()); // Fortnite save the world
|
let _ = World::save(world_arc_clone_main_thread.clone()).unwrap(); // Fortnite save the world
|
||||||
std::process::exit(0);
|
std::process::exit(0);
|
||||||
})
|
})
|
||||||
.expect("Error handling control C, save on exit will not work");
|
.expect("Error handling control C, save on exit will not work");
|
||||||
|
|
||||||
|
let extensions = Arc::new(Extensions::init(PlayersWrapper::new(players_arc.clone()))?);
|
||||||
|
|
||||||
|
info!("Server listening on {}", 25565);
|
||||||
|
|
||||||
for stream in listener.incoming() {
|
for stream in listener.incoming() {
|
||||||
let players_arc_clone = Arc::clone(&players_arc);
|
let players_arc_clone = Arc::clone(&players_arc);
|
||||||
let world_arc_clone = Arc::clone(&world_arc);
|
let world_arc_clone = Arc::clone(&world_arc);
|
||||||
handle_client(stream?, thread_number, players_arc_clone, world_arc_clone);
|
let extensions_arc_clone = Arc::clone(&extensions);
|
||||||
|
handle_client(
|
||||||
|
stream?,
|
||||||
|
thread_number,
|
||||||
|
players_arc_clone,
|
||||||
|
world_arc_clone,
|
||||||
|
extensions_arc_clone,
|
||||||
|
);
|
||||||
thread_number = thread_number.wrapping_add(1);
|
thread_number = thread_number.wrapping_add(1);
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -1,20 +1,23 @@
|
|||||||
use std::net::TcpStream;
|
|
||||||
use std::io::prelude::*;
|
|
||||||
use std::sync::{Arc, Mutex};
|
|
||||||
use log::{info, warn};
|
use log::{info, warn};
|
||||||
|
use std::io::prelude::*;
|
||||||
|
use std::net::TcpStream;
|
||||||
|
use std::sync::{Arc, Mutex};
|
||||||
use std::thread;
|
use std::thread;
|
||||||
use std::thread::sleep;
|
use std::thread::sleep;
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
|
|
||||||
use crate::player::{Player, SpecialPlayers, PlayerStatus};
|
use crate::command::handle_command;
|
||||||
use crate::world::World;
|
use crate::extensions::Extensions;
|
||||||
|
use crate::player::{Player, PlayerStatus, SpecialPlayers};
|
||||||
use crate::utils::*;
|
use crate::utils::*;
|
||||||
|
use crate::world::World;
|
||||||
|
|
||||||
pub fn handle_client(
|
pub fn handle_client(
|
||||||
mut stream: TcpStream,
|
mut stream: TcpStream,
|
||||||
client_number: u8,
|
client_number: u8,
|
||||||
players_arc_clone: Arc<Mutex<[Player; 255]>>,
|
players_arc_clone: Arc<Mutex<[Player; 255]>>,
|
||||||
world_arc_clone: Arc<Mutex<World>>,
|
world_arc_clone: Arc<Mutex<World>>,
|
||||||
|
extensions: Arc<Extensions>,
|
||||||
) {
|
) {
|
||||||
thread::spawn(move || {
|
thread::spawn(move || {
|
||||||
info!("Thread initialized with player ID: {}", client_number);
|
info!("Thread initialized with player ID: {}", client_number);
|
||||||
@ -90,7 +93,7 @@ pub fn handle_client(
|
|||||||
current_player.pitch = 0;
|
current_player.pitch = 0;
|
||||||
current_player.operator = true;
|
current_player.operator = true;
|
||||||
|
|
||||||
bomb_server_details(&mut stream, ¤t_player, &world_arc_clone);
|
let _ = bomb_server_details(&mut stream, ¤t_player, &world_arc_clone);
|
||||||
|
|
||||||
for i in 0..immediate_join.len() {
|
for i in 0..immediate_join.len() {
|
||||||
if immediate_join[i] {
|
if immediate_join[i] {
|
||||||
@ -207,49 +210,13 @@ pub fn handle_client(
|
|||||||
// Uh oh, command time
|
// Uh oh, command time
|
||||||
info!("{}", message_string);
|
info!("{}", message_string);
|
||||||
let remaning_command = String::from_iter(&message[1..message.len()]);
|
let remaning_command = String::from_iter(&message[1..message.len()]);
|
||||||
let vectorized_command = remaning_command.split(" ").collect::<Vec<&str>>();
|
let _ = handle_command(
|
||||||
match vectorized_command[0] {
|
&mut stream,
|
||||||
"kick" => {
|
client_number,
|
||||||
let mut players = players_arc_clone.lock().unwrap();
|
&players_arc_clone,
|
||||||
for i in 0..players.len() {
|
&extensions,
|
||||||
if players[i].id != 255 {
|
&remaning_command,
|
||||||
if players[i].username == vectorized_command[1] {
|
);
|
||||||
let _ = &mut players[i]
|
|
||||||
.outgoing_data
|
|
||||||
.extend_from_slice(&client_disconnect("KICKED!"));
|
|
||||||
players[i].id = 255;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
"tp" => {
|
|
||||||
let players = players_arc_clone.lock().unwrap();
|
|
||||||
for i in 0..players.len() {
|
|
||||||
if players[i].id != 255 {
|
|
||||||
if players[i].username == vectorized_command[1] {
|
|
||||||
let _ =
|
|
||||||
&mut stream.write(&set_position_and_orientation(
|
|
||||||
SpecialPlayers::SelfPlayer as u8,
|
|
||||||
players[i].position_x,
|
|
||||||
players[i].position_y,
|
|
||||||
players[i].position_z,
|
|
||||||
players[i].yaw,
|
|
||||||
players[i].pitch,
|
|
||||||
));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_ => {
|
|
||||||
let _ = &mut stream.write(&send_chat_message(
|
|
||||||
SpecialPlayers::SelfPlayer as u8,
|
|
||||||
"".to_string(),
|
|
||||||
"&cUnkown command!".to_string(),
|
|
||||||
));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
let mut players = players_arc_clone.lock().unwrap();
|
let mut players = players_arc_clone.lock().unwrap();
|
||||||
let sender: u8 = players[client_number as usize].id;
|
let sender: u8 = players[client_number as usize].id;
|
||||||
@ -344,4 +311,3 @@ pub fn handle_client(
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
26
src/utils.rs
26
src/utils.rs
@ -5,6 +5,7 @@ use std::io::prelude::*;
|
|||||||
use std::net::TcpStream;
|
use std::net::TcpStream;
|
||||||
use std::sync::{Arc, Mutex};
|
use std::sync::{Arc, Mutex};
|
||||||
|
|
||||||
|
use crate::error::AppError;
|
||||||
use crate::World;
|
use crate::World;
|
||||||
use crate::SpecialPlayers;
|
use crate::SpecialPlayers;
|
||||||
use crate::Player;
|
use crate::Player;
|
||||||
@ -63,17 +64,17 @@ pub fn init_level() -> Vec<u8> {
|
|||||||
vec![0x02]
|
vec![0x02]
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn finalize_level(world_arc_clone: &Arc<Mutex<World>>) -> Vec<u8> {
|
pub fn finalize_level(world_arc_clone: &Arc<Mutex<World>>) -> Result<Vec<u8>, AppError> {
|
||||||
let mut ret_val: Vec<u8> = vec![];
|
let mut ret_val: Vec<u8> = vec![];
|
||||||
ret_val.push(0x04);
|
ret_val.push(0x04);
|
||||||
|
|
||||||
let world_dat = world_arc_clone.lock().unwrap();
|
let world_dat = world_arc_clone.lock()?;
|
||||||
|
|
||||||
ret_val.append(&mut stream_write_short(world_dat.size_x).to_vec());
|
ret_val.append(&mut stream_write_short(world_dat.size_x).to_vec());
|
||||||
ret_val.append(&mut stream_write_short(world_dat.size_y).to_vec());
|
ret_val.append(&mut stream_write_short(world_dat.size_y).to_vec());
|
||||||
ret_val.append(&mut stream_write_short(world_dat.size_z).to_vec());
|
ret_val.append(&mut stream_write_short(world_dat.size_z).to_vec());
|
||||||
|
|
||||||
ret_val
|
Ok(ret_val)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn spawn_player(
|
pub fn spawn_player(
|
||||||
@ -140,9 +141,9 @@ pub fn set_position_and_orientation(
|
|||||||
ret_val
|
ret_val
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn send_level_data(world_arc_clone: &Arc<Mutex<World>>) -> Vec<u8> {
|
pub fn send_level_data(world_arc_clone: &Arc<Mutex<World>>) -> Result<Vec<u8>, AppError> {
|
||||||
let mut ret_val: Vec<u8> = vec![];
|
let mut ret_val: Vec<u8> = vec![];
|
||||||
let mut world_dat = world_arc_clone.lock().unwrap().data.clone();
|
let mut world_dat = world_arc_clone.lock()?.data.clone();
|
||||||
|
|
||||||
// Big endian fold lmao
|
// Big endian fold lmao
|
||||||
world_dat.insert(0, ((world_dat.len() & 0xFF) >> 0) as u8);
|
world_dat.insert(0, ((world_dat.len() & 0xFF) >> 0) as u8);
|
||||||
@ -154,7 +155,7 @@ pub fn send_level_data(world_arc_clone: &Arc<Mutex<World>>) -> Vec<u8> {
|
|||||||
|
|
||||||
let mut world_dat_compressor = GzEncoder::new(Vec::new(), Compression::fast());
|
let mut world_dat_compressor = GzEncoder::new(Vec::new(), Compression::fast());
|
||||||
let _ = world_dat_compressor.write_all(&world_dat);
|
let _ = world_dat_compressor.write_all(&world_dat);
|
||||||
let world_dat_gzipped = world_dat_compressor.finish().unwrap();
|
let world_dat_gzipped = world_dat_compressor.finish()?;
|
||||||
|
|
||||||
let number_of_chunks = ((world_dat_gzipped.len() as f32) / 1024.0_f32).ceil() as usize;
|
let number_of_chunks = ((world_dat_gzipped.len() as f32) / 1024.0_f32).ceil() as usize;
|
||||||
let mut current_chunk = 0;
|
let mut current_chunk = 0;
|
||||||
@ -177,7 +178,7 @@ pub fn send_level_data(world_arc_clone: &Arc<Mutex<World>>) -> Vec<u8> {
|
|||||||
percentage = 100;
|
percentage = 100;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret_val.push(percentage.try_into().unwrap());
|
ret_val.push(percentage.try_into()?);
|
||||||
|
|
||||||
current_chunk += 1;
|
current_chunk += 1;
|
||||||
}
|
}
|
||||||
@ -189,7 +190,7 @@ pub fn send_level_data(world_arc_clone: &Arc<Mutex<World>>) -> Vec<u8> {
|
|||||||
ret_val.push(0x03);
|
ret_val.push(0x03);
|
||||||
|
|
||||||
ret_val.append(&mut stream_write_short(
|
ret_val.append(&mut stream_write_short(
|
||||||
remaining_chunk_size.try_into().unwrap(),
|
remaining_chunk_size.try_into()?,
|
||||||
));
|
));
|
||||||
|
|
||||||
let mut remaining_data_buffer = [0u8; 1024];
|
let mut remaining_data_buffer = [0u8; 1024];
|
||||||
@ -205,23 +206,23 @@ pub fn send_level_data(world_arc_clone: &Arc<Mutex<World>>) -> Vec<u8> {
|
|||||||
"World transmission size: {}KiB",
|
"World transmission size: {}KiB",
|
||||||
ret_val.len() as f32 / 1024.0
|
ret_val.len() as f32 / 1024.0
|
||||||
);
|
);
|
||||||
ret_val
|
Ok(ret_val)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn bomb_server_details(
|
pub fn bomb_server_details(
|
||||||
stream: &mut TcpStream,
|
stream: &mut TcpStream,
|
||||||
current_player: &Player,
|
current_player: &Player,
|
||||||
world_arc_clone: &Arc<Mutex<World>>,
|
world_arc_clone: &Arc<Mutex<World>>,
|
||||||
) {
|
) -> Result<(), AppError> {
|
||||||
let mut compound_data: Vec<u8> = vec![];
|
let mut compound_data: Vec<u8> = vec![];
|
||||||
compound_data.append(&mut server_identification(current_player.operator));
|
compound_data.append(&mut server_identification(current_player.operator));
|
||||||
|
|
||||||
compound_data.append(&mut init_level());
|
compound_data.append(&mut init_level());
|
||||||
|
|
||||||
// info!("Send level data");
|
// info!("Send level data");
|
||||||
compound_data.append(&mut send_level_data(&world_arc_clone)); // Approaching Nirvana - Maw of the beast
|
compound_data.append(&mut send_level_data(&world_arc_clone)?); // Approaching Nirvana - Maw of the beast
|
||||||
|
|
||||||
compound_data.append(&mut finalize_level(&world_arc_clone));
|
compound_data.append(&mut finalize_level(&world_arc_clone)?);
|
||||||
|
|
||||||
info!("Spawning player: {}", ¤t_player.username);
|
info!("Spawning player: {}", ¤t_player.username);
|
||||||
compound_data.append(&mut spawn_player(
|
compound_data.append(&mut spawn_player(
|
||||||
@ -235,5 +236,6 @@ pub fn bomb_server_details(
|
|||||||
));
|
));
|
||||||
|
|
||||||
let _ = stream.write(&compound_data);
|
let _ = stream.write(&compound_data);
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -72,10 +72,11 @@ impl World {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn save(world_arc_clone: Arc<Mutex<World>>) -> std::io::Result<()> {
|
pub fn save(world_arc_clone: Arc<Mutex<World>>) -> Result<(), AppError> {
|
||||||
let mut to_write: Vec<u8> = Vec::new();
|
let mut to_write: Vec<u8> = Vec::new();
|
||||||
{
|
{
|
||||||
let mut world_dat = world_arc_clone.lock().unwrap();
|
let mut world_dat = world_arc_clone.lock().map_err(|e| AppError::MutexPoisoned(e.to_string()))?;
|
||||||
|
|
||||||
to_write.push((world_dat.size_x >> 8) as u8);
|
to_write.push((world_dat.size_x >> 8) as u8);
|
||||||
to_write.push((world_dat.size_x & 0xFF) as u8);
|
to_write.push((world_dat.size_x & 0xFF) as u8);
|
||||||
to_write.push((world_dat.size_y >> 8) as u8);
|
to_write.push((world_dat.size_y >> 8) as u8);
|
||||||
@ -86,6 +87,6 @@ impl World {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let mut file = File::create("world.wrld")?;
|
let mut file = File::create("world.wrld")?;
|
||||||
file.write_all(&to_write)
|
Ok(file.write_all(&to_write)?)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user