diff --git a/Cargo.lock b/Cargo.lock index e1825ec..c493e1c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1,6 +1,6 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. -version = 3 +version = 4 [[package]] name = "adler" @@ -8,12 +8,24 @@ version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" +[[package]] +name = "bitflags" +version = "2.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f68f53c83ab957f72c32642f3868eec03eb974d1fb82e453128456482613d36" + [[package]] name = "cfg-if" version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +[[package]] +name = "cfg_aliases" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" + [[package]] name = "colored" version = "2.1.0" @@ -21,7 +33,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cbf2150cce219b664a8a70df7a1f933836724b503f8a413af9365b4dcc4d90b8" dependencies = [ "lazy_static", - "windows-sys", + "windows-sys 0.48.0", ] [[package]] @@ -33,6 +45,16 @@ dependencies = [ "cfg-if", ] +[[package]] +name = "ctrlc" +version = "3.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90eeab0aa92f3f9b4e87f258c72b139c207d251f9cbc1080a0086b86a8870dd3" +dependencies = [ + "nix", + "windows-sys 0.59.0", +] + [[package]] name = "flate2" version = "1.0.30" @@ -71,6 +93,7 @@ name = "mcrizzledizzle" version = "0.1.0" dependencies = [ "colored", + "ctrlc", "flate2", "lazy_static", "rand", @@ -85,6 +108,18 @@ dependencies = [ "adler", ] +[[package]] +name = "nix" +version = "0.29.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "71e2746dc3a24dd78b3cfcb7be93368c6de9963d30f43a6a73998a9cf4b17b46" +dependencies = [ + "bitflags", + "cfg-if", + "cfg_aliases", + "libc", +] + [[package]] name = "ppv-lite86" version = "0.2.17" @@ -133,7 +168,16 @@ version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" dependencies = [ - "windows-targets", + "windows-targets 0.48.5", +] + +[[package]] +name = "windows-sys" +version = "0.59.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" +dependencies = [ + "windows-targets 0.52.6", ] [[package]] @@ -142,13 +186,29 @@ version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" dependencies = [ - "windows_aarch64_gnullvm", - "windows_aarch64_msvc", - "windows_i686_gnu", - "windows_i686_msvc", - "windows_x86_64_gnu", - "windows_x86_64_gnullvm", - "windows_x86_64_msvc", + "windows_aarch64_gnullvm 0.48.5", + "windows_aarch64_msvc 0.48.5", + "windows_i686_gnu 0.48.5", + "windows_i686_msvc 0.48.5", + "windows_x86_64_gnu 0.48.5", + "windows_x86_64_gnullvm 0.48.5", + "windows_x86_64_msvc 0.48.5", +] + +[[package]] +name = "windows-targets" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" +dependencies = [ + "windows_aarch64_gnullvm 0.52.6", + "windows_aarch64_msvc 0.52.6", + "windows_i686_gnu 0.52.6", + "windows_i686_gnullvm", + "windows_i686_msvc 0.52.6", + "windows_x86_64_gnu 0.52.6", + "windows_x86_64_gnullvm 0.52.6", + "windows_x86_64_msvc 0.52.6", ] [[package]] @@ -157,38 +217,86 @@ version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" + [[package]] name = "windows_aarch64_msvc" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" + [[package]] name = "windows_i686_gnu" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" +[[package]] +name = "windows_i686_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" + [[package]] name = "windows_i686_msvc" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" +[[package]] +name = "windows_i686_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" + [[package]] name = "windows_x86_64_gnu" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" + [[package]] name = "windows_x86_64_gnullvm" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" + [[package]] name = "windows_x86_64_msvc" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" diff --git a/Cargo.toml b/Cargo.toml index 2b4c683..5144dc0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -5,6 +5,7 @@ edition = "2021" [dependencies] colored = "2.1.0" +ctrlc = "3.4.5" flate2 = "1.0.30" lazy_static = "1.4.0" rand = "0.8.5" diff --git a/src/main.rs b/src/main.rs index 12e6e81..79edfcf 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,3 +1,4 @@ +use std::fs::{self, File}; use std::io::prelude::*; use std::net::{SocketAddr, TcpListener, TcpStream}; use std::thread::sleep; @@ -7,7 +8,6 @@ use std::thread; use std::sync::{Arc, Mutex}; use flate2::Compression; use flate2::write::GzEncoder; -use rand::prelude::*; use colored::Colorize; // #[macro_use] // extern crate lazy_static; @@ -63,15 +63,15 @@ struct World { } fn build_world(size_x: i16, size_y: i16, size_z: i16) -> Vec { - let mut rng = rand::thread_rng(); - let mut world_dat: Vec = Vec::new(); for y in 0..size_y { for _z in 0..size_z { for _x in 0..size_x { - if y == 0 { - world_dat.push(rng.gen()); // Bookshelf + if y < 15 { + world_dat.push(3); // Dirt + } else if y == 15 { + world_dat.push(2); // Grass } else { world_dat.push(0x00); // Air } @@ -170,7 +170,7 @@ fn handle_client(mut stream: TcpStream, client_number: u8, players_arc_clone: Ar current_player.position_z = 0; current_player.yaw = 0; current_player.pitch = 0; - current_player.operator = false; + current_player.operator = true; bomb_server_details(&mut stream, ¤t_player, &world_arc_clone); @@ -431,9 +431,9 @@ fn spawn_player(player_id: u8, name: &String, pos_x: i16, pos_y: i16, pos_z: i16 ret_val.push(player_id); ret_val.append(&mut to_mc_string(name).to_vec()); - ret_val.append(&mut stream_write_short(pos_x).to_vec()); - ret_val.append(&mut stream_write_short(pos_y).to_vec()); - ret_val.append(&mut stream_write_short(pos_z).to_vec()); + ret_val.append(&mut stream_write_short(pos_x << 5).to_vec()); // FShort + ret_val.append(&mut stream_write_short(pos_y << 5).to_vec()); + ret_val.append(&mut stream_write_short(pos_z << 5).to_vec()); ret_val.push(yaw); ret_val.push(pitch); @@ -547,6 +547,48 @@ fn send_level_data(world_arc_clone: &Arc>) -> Vec { return ret_val; } +fn save_world(world_arc_clone: Arc>) -> std::io::Result<()> { + let mut to_write: Vec = Vec::new(); + { + let mut world_dat = world_arc_clone.lock().unwrap(); + 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_y >> 8) as u8); + to_write.push((world_dat.size_y & 0xFF) as u8); + to_write.push((world_dat.size_z >> 8) as u8); + to_write.push((world_dat.size_z & 0xFF) as u8); + to_write.append(&mut world_dat.data); + } + + let mut file = File::create("world.wrld")?; + return file.write_all(&to_write); +} + +fn load_world() -> World { + if fs::metadata("world.wrld").is_ok() { + let mut world: World = World {size_x: 0, size_y: 0, size_z: 0, data: Vec::new()}; + let world_data_raw = fs::read("world.wrld").unwrap(); + if world_data_raw.len() < 6 { + println!("INVALID WORLD!"); + std::process::exit(1); + } + world.size_x = ((world_data_raw[0] as i16) << 8) + (world_data_raw[1] as i16); + world.size_y = ((world_data_raw[2] as i16) << 8) + (world_data_raw[3] as i16); + world.size_z = ((world_data_raw[4] as i16) << 8) + (world_data_raw[5] as i16); + + if world_data_raw.len() != (world.size_x as i32 * world.size_y as i32 * world.size_z as i32 + 6 as i32) as usize { + println!("Expected more bytes in world contents: {} (expected) != {} (actual)", world.size_x * world.size_y * world.size_z + 6, world_data_raw.len()); + std::process::exit(1); + } + + world.data = world_data_raw[6..world_data_raw.len()].to_vec(); + + return world; + } else { + return World {size_x: SIZE_X, size_y: SIZE_Y, size_z: SIZE_Z, data: build_world(SIZE_X, SIZE_Y, SIZE_Z)}; + } +} + fn bomb_server_details(stream: &mut TcpStream, current_player: &Player, world_arc_clone: &Arc>) { let mut compound_data: Vec = vec![]; println!("Server IDENT"); @@ -562,7 +604,7 @@ fn bomb_server_details(stream: &mut TcpStream, current_player: &Player, world_ar compound_data.append(&mut finalize_level(&world_arc_clone)); println!("Spawning player"); - compound_data.append(&mut spawn_player(SpecialPlayers::SelfPlayer as u8, ¤t_player.username, 64, 2, 64, 0, 0)); + compound_data.append(&mut spawn_player(SpecialPlayers::SelfPlayer as u8, ¤t_player.username, 32, 17, 32, 0, 0)); let _ = stream.write(&compound_data); } @@ -596,7 +638,7 @@ fn main() -> std::io::Result<()> { let players: [Player; 255] = core::array::from_fn(|_| Player::default()); let players_arc = Arc::new(Mutex::new(players)); - let world_instance: World = World {size_x: SIZE_X, size_y: SIZE_Y, size_z: SIZE_Z, data: build_world(SIZE_X, SIZE_Y, SIZE_Z)}; + let world_instance: World = load_world(); let world_arc = Arc::new(Mutex::new(world_instance)); let addr = SocketAddr::from(([0, 0, 0, 0], 25565)); @@ -605,6 +647,12 @@ fn main() -> std::io::Result<()> { let mut thread_number : u8 = 0; + let world_arc_clone_main_thread = Arc::clone(&world_arc); + ctrlc::set_handler(move || { + let _ = save_world(world_arc_clone_main_thread.clone()); // Fortnite save the world + std::process::exit(0); + }).expect("Error handling control C, save on exit will not work"); + for stream in listener.incoming() { let players_arc_clone = Arc::clone(&players_arc); let world_arc_clone = Arc::clone(&world_arc); diff --git a/src/world.wrld b/src/world.wrld new file mode 100644 index 0000000..18b527a Binary files /dev/null and b/src/world.wrld differ