diff --git a/Cargo.lock b/Cargo.lock index c26924a..9a25e63 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -43,6 +43,12 @@ version = "2.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8f68f53c83ab957f72c32642f3868eec03eb974d1fb82e453128456482613d36" +[[package]] +name = "byteorder" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" + [[package]] name = "cfg-if" version = "1.0.0" @@ -182,6 +188,7 @@ dependencies = [ "log", "regex", "rhai", + "rhai-rand", "simple_logger", ] @@ -266,6 +273,15 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" 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]] name = "proc-macro2" version = "1.0.93" @@ -284,6 +300,36 @@ dependencies = [ "proc-macro2", ] +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "libc", + "rand_chacha", + "rand_core", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom", +] + [[package]] name = "regex" version = "1.11.1" @@ -331,6 +377,18 @@ dependencies = [ "thin-vec", ] +[[package]] +name = "rhai-rand" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4314e7e2a1f5d5de224ae3bc9ce2af4c0146d07d3c3aadf9840f08d80ef28800" +dependencies = [ + "rand", + "rhai", + "serde", + "serde_json", +] + [[package]] name = "rhai_codegen" version = "2.2.0" @@ -342,6 +400,12 @@ dependencies = [ "syn", ] +[[package]] +name = "ryu" +version = "1.0.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ea1a2d0a644769cc99faa24c3ad26b379b786fe7c36fd3c546254801650e6dd" + [[package]] name = "serde" version = "1.0.218" @@ -362,6 +426,18 @@ dependencies = [ "syn", ] +[[package]] +name = "serde_json" +version = "1.0.140" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "20068b6e96dc6c9bd23e01df8827e6c7e1f2fddd43c21810382803c136b99373" +dependencies = [ + "itoa", + "memchr", + "ryu", + "serde", +] + [[package]] name = "simple_logger" version = "5.0.0" @@ -625,6 +701,7 @@ version = "0.7.35" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" dependencies = [ + "byteorder", "zerocopy-derive", ] diff --git a/Cargo.toml b/Cargo.toml index 46ca842..29dc578 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -8,6 +8,7 @@ ctrlc = "3.4.5" flate2 = "1.0.30" log = "0.4.26" regex = "1.11.1" +rhai-rand = "0.1.6" [dependencies.simple_logger] version = "5.0.0" diff --git a/src/command.rs b/src/command.rs index 6276027..25ccc45 100644 --- a/src/command.rs +++ b/src/command.rs @@ -71,38 +71,47 @@ pub fn handle_command( } _ => { let mut vectorized_command_object: Vec = Vec::new(); - for arg in &vectorized_command { vectorized_command_object.push(arg.to_string()); } - let found = match extensions.run_command( - vectorized_command[0].to_string(), - client_number, - vectorized_command_object, - stream, - ) { - 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(()); + let extensions_clone = Arc::clone(extensions); + let players_clone = Arc::clone(players_arc_clone); + let command_key = vectorized_command[0].to_string(); + let client_number_copy = client_number; + + // Async thread commands + std::thread::spawn(move || { + let result = extensions_clone.run_command( + command_key, + client_number_copy, + vectorized_command_object, + ); + + match result { + Ok(found) => { + if !found { + let mut players = players_clone.lock().unwrap(); + let player = &mut players[client_number_copy as usize]; + player.outgoing_data.extend_from_slice(&send_chat_message( + SpecialPlayers::SelfPlayer as u8, + "".to_string(), + "&cUnknown command!".to_string(), + )); + } + } + Err(err) => { + error!("Command error: {}", err); + let mut players = players_clone.lock().unwrap(); + let player = &mut players[client_number_copy as usize]; + player.outgoing_data.extend_from_slice(&send_chat_message( + SpecialPlayers::SelfPlayer as u8, + "".to_string(), + "&cCommand failed".to_string(), + )); + } } - }; - - if found { - return Ok(()); - } - - let _ = &mut stream.write(&send_chat_message( - SpecialPlayers::SelfPlayer as u8, - "".to_string(), - "&cUnkown command!".to_string(), - )); + }); } } Ok(()) diff --git a/src/extensions.rs b/src/extensions.rs index 2301709..2d28ccd 100644 --- a/src/extensions.rs +++ b/src/extensions.rs @@ -1,11 +1,11 @@ use log::{debug, error, info, warn}; use regex::Regex; -use rhai::{CustomType, Engine, EvalAltResult, FnPtr, Scope, TypeBuilder, AST}; +use rhai::{packages::Package, CustomType, Engine, EvalAltResult, FnPtr, Scope, TypeBuilder, AST}; +use rhai_rand::RandomPackage; use std::{ collections::HashMap, ffi::OsStr, fmt, fs, - net::TcpStream, path::Path, sync::{Arc, Mutex}, }; @@ -19,6 +19,7 @@ use crate::{ pub struct Extensions { extensions: Vec, + players: PlayersWrapper, } impl Extensions { @@ -27,7 +28,6 @@ impl Extensions { key: String, player: u8, argv: Vec, - stream: &mut TcpStream, ) -> Result { // Here I'm calling write_chat_stream multiple times. This is because the stock minecraft // chat has a length limit of 64 characters, which is pathetically small. There is a @@ -39,51 +39,46 @@ impl Extensions { // Reserve extension listing command if &key == "extensions" { - let _ = write_chat_stream(stream, "Extension listing".to_string()); + let mut res_data: Vec = Vec::new(); + res_data.extend_from_slice(&write_chat_stream("Extension listing".to_string())); for extension in &self.extensions { - let _ = write_chat_stream( - stream, - format!( - "&a{} &bv{}", - extension.metadata.name, extension.metadata.version - ), - ); + res_data.extend_from_slice(&write_chat_stream(format!( + "&a{} &bv{}", + extension.metadata.name, extension.metadata.version + ))); } + self.players.0.lock().unwrap()[player as usize] + .outgoing_data + .extend_from_slice(&res_data); + return Ok(true); } // Reserve command listing command if &key == "help" { - let _ = write_chat_stream(stream, "Command listing".to_string()); + let mut res_data: Vec = Vec::new(); - let _ = write_chat_stream( - stream, - format!("&c{} &a[{}]", "help", "Builtin"), - ); - let _ = write_chat_stream( - stream, - format!("&c{} &a[{}]", "extensions", "Builtin"), - ); - let _ = write_chat_stream( - stream, - format!("&c{} &a[{}]", "kick", "Builtin"), - ); - let _ = write_chat_stream( - stream, - format!("&c{} &a[{}]", "tp", "Builtin"), - ); + res_data.extend_from_slice(&write_chat_stream("Command listing".to_string())); + + res_data.extend_from_slice(&write_chat_stream(format!("&c{} &a[{}]", "help", "Builtin"))); + res_data.extend_from_slice(&write_chat_stream(format!("&c{} &a[{}]", "extensions", "Builtin"))); + res_data.extend_from_slice(&write_chat_stream(format!("&c{} &a[{}]", "kick", "Builtin"))); + res_data.extend_from_slice(&write_chat_stream(format!("&c{} &a[{}]", "tp", "Builtin"))); for extension in &self.extensions { for command in extension.commands.keys() { - let _ = write_chat_stream( - stream, + res_data.extend_from_slice(&write_chat_stream( format!("&c{} &a[{}]", command, extension.metadata.name), - ); + )); } } + self.players.0.lock().unwrap()[player as usize] + .outgoing_data + .extend_from_slice(&res_data); + return Ok(true); } @@ -450,6 +445,7 @@ impl Extensions { let mut extensions = Extensions { extensions: Vec::new(), + players: players.clone(), }; for extension in extensions_listing { @@ -461,6 +457,8 @@ impl Extensions { info!("Loading extension {}", extension_path.display()); let mut engine = Engine::new(); + let random = RandomPackage::new(); + random.register_into_engine(&mut engine); engine.set_max_expr_depths(50, 50); engine.build_type::(); engine.build_type::(); diff --git a/src/extensions/fill.rhai b/src/extensions/fill.rhai index 521008f..aff9326 100644 --- a/src/extensions/fill.rhai +++ b/src/extensions/fill.rhai @@ -77,6 +77,7 @@ fn init(players, world) { if playerData[event.player.to_string()] != () { playerData[event.player.to_string()].command_step = 0; } + event }); ctx diff --git a/src/utils.rs b/src/utils.rs index d6ab66a..cd119dd 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -123,12 +123,12 @@ pub fn send_chat_message( ret_val } -pub fn write_chat_stream(stream: &mut TcpStream, message: String) { - let _ = stream.write(&send_chat_message( +pub fn write_chat_stream(message: String) -> Vec { + send_chat_message( SpecialPlayers::SelfPlayer as u8, "".to_string(), message, - )); + ) } pub fn set_position_and_orientation(