diff options
| author | troido <troido@protonmail.com> | 2020-01-28 18:32:17 +0100 |
|---|---|---|
| committer | troido <troido@protonmail.com> | 2020-01-28 18:32:17 +0100 |
| commit | 3280e0bf472f418f1b4f209b1355fcaa1db163c6 (patch) | |
| tree | f8fe39c1376f668070dd31bb6571d4842b95a104 | |
| parent | 88d7f30b452148963c8a4c3bb739b50d907a75f1 (diff) | |
added player entity; changed json library
| -rw-r--r-- | Cargo.toml | 6 | ||||
| -rw-r--r-- | src/gameserver.rs | 33 | ||||
| -rw-r--r-- | src/main.rs | 41 | ||||
| -rw-r--r-- | src/room.rs | 68 |
4 files changed, 102 insertions, 46 deletions
@@ -11,6 +11,6 @@ slab = "0.4.2" nix = "0.13" libc = "0.2" users = "0.8" -json = "0.12.1" -specs = { version = "0.15.1", features = ["specs-derive"] } -rand = "0.7.3" +specs = { version = "0.15", features = ["specs-derive"] } +rand = "0.7" +serde_json = "1.0" diff --git a/src/gameserver.rs b/src/gameserver.rs index 3a63dc4..bd9ed67 100644 --- a/src/gameserver.rs +++ b/src/gameserver.rs @@ -3,8 +3,9 @@ use std::collections::HashMap; use std::io; -use json; -use json::JsonValue; + + +use serde_json::{Value, json}; use super::server::Server; @@ -13,7 +14,7 @@ use super::server::Server; enum Message { Name(String), Chat(String), - Input(JsonValue), + Input(Value), Invalid(String) } @@ -21,7 +22,7 @@ enum Message { pub enum Action { Join(String), Leave(String), - Input(String, JsonValue) + Input(String, Value) } pub struct GameServer { @@ -69,26 +70,28 @@ impl GameServer { } fn send_error(&mut self, (serverid, connectionid): (usize, usize), errname: &str, err_text: &str) -> Result<(), io::Error>{ - self.servers[serverid].send(connectionid, &json::stringify(json::array!["error", errname, err_text])) + self.servers[serverid].send(connectionid, &json!(["error", errname, err_text]).to_string().as_str()) } pub fn broadcast_message(&mut self, text: &str){ println!("m {}", text); - self.broadcast_json(json::array!["message", text, ""]); + self.broadcast_json(json!(["message", text, ""])); + } + + pub fn broadcast_json(&mut self, value: Value){ + self.broadcast(value.to_string().as_str()); } - pub fn broadcast_json(&mut self, value: JsonValue){ - let jsontext = json::stringify(value); + pub fn broadcast(&mut self, txt: &str){ for ((serverid, id), _name) in &self.players { - let _ = self.servers[*serverid].send(*id, &jsontext); + let _ = self.servers[*serverid].send(*id, txt); } } - pub fn send(&mut self, playername: &str, value: JsonValue) -> Result<(), io::Error> { - let jsontext = json::stringify(value); + pub fn send(&mut self, playername: &str, value: Value) -> Result<(), io::Error> { match self.connections.get(playername) { Some((serverid, id)) => { - self.servers[*serverid].send(*id, &jsontext) + self.servers[*serverid].send(*id, value.to_string().as_str()) } None => Err(io::Error::new(io::ErrorKind::Other, "unknown player name")) } @@ -156,8 +159,8 @@ impl GameServer { fn parse_message(msg: &str) -> Message { - if let Ok(data) = json::parse(msg) { - if let JsonValue::Array(arr) = data { + if let Ok(data) = serde_json::from_str(msg) { + if let Value::Array(arr) = data { if arr.len() < 2 { return Message::Invalid("array not long enough".to_string()); } @@ -185,7 +188,7 @@ fn parse_message(msg: &str) -> Message { Message::Invalid(format!("unknown messsage type {:?}", msgtype).to_string()) } } - } else { Message::Invalid(format!("first array value not string: {:?}", arr[0].dump()).to_string()) } + } else { Message::Invalid(format!("first array value not string: {:?}", arr[0].to_string()).to_string()) } } else { Message::Invalid("not json array".to_string()) } } else { Message::Invalid("not json message".to_string()) } } diff --git a/src/main.rs b/src/main.rs index 97283d0..ca2947c 100644 --- a/src/main.rs +++ b/src/main.rs @@ -7,13 +7,15 @@ use std::path::Path; pub mod server; pub mod gameserver; pub mod room; +pub mod util; +// pub mod controls; -use self::gameserver::GameServer; +use self::gameserver::{GameServer, Action}; use self::server::unixserver::UnixServer; use self::server::tcpserver::TcpServer; use self::server::Server; -use json; +use serde_json; fn main() { @@ -33,30 +35,39 @@ fn main() { let mut room = room::Room::new((32, 32)); loop { - let _actions = gameserver.update(); + let actions = gameserver.update(); + for action in actions { + match action { + Action::Join(name) => {room.add_player(&name);} + Action::Leave(name) => {room.remove_player(&name);} + _ => {} + } + } room.update(); let (field, mapping) = room.view(); let updatemsg = create_update_message(room.get_size(), field, mapping); - let _ = gameserver.broadcast_json(updatemsg); + gameserver.broadcast(updatemsg.as_str()); sleep(Duration::from_millis(100)); } } -fn create_update_message((width, height): (i32, i32), field: Vec<usize>, mapping: Vec<Vec<String>>) -> json::JsonValue { - let mut updatemsg: json::JsonValue = json::array![ +fn create_update_message((width, height): (i32, i32), field: Vec<usize>, mapping: Vec<Vec<String>>) -> String { + let updatemsg= serde_json::json!([ "world", - json::array![ - json::array![ + [ + [ "field", - json::object!{ - "width" => width, - "height" => height, + { + "width": width, + "height": height, + "field": field, + "mapping": mapping } ] ] - ]; - updatemsg[1][0][1]["field"] = json::from(field); - updatemsg[1][0][1]["mapping"] = json::from(mapping); - updatemsg + ]); +// updatemsg[1][0][1]["field"] = json::from(field); +// updatemsg[1][0][1]["mapping"] = json::from(mapping); + updatemsg.to_string() } diff --git a/src/room.rs b/src/room.rs index 5268ce7..ad73e9f 100644 --- a/src/room.rs +++ b/src/room.rs @@ -13,7 +13,8 @@ use specs::{ DispatcherBuilder, Dispatcher, Write, - EntityBuilder + EntityBuilder, + Entity }; @@ -26,13 +27,19 @@ struct Position { y: i32 } -#[derive(Component, Debug)] +#[derive(Component, Debug, Clone)] #[storage(VecStorage)] struct Visible { sprite: String, height: f32 } +#[derive(Component, Debug)] +#[storage(VecStorage)] +struct InputController { + key: String +} + // Resources @@ -43,7 +50,7 @@ struct Size (i32, i32); struct TopView { width: i32, height: i32, - cells: HashMap<Position, Vec<String>> + cells: HashMap<Position, Vec<Visible>> } // Systems @@ -58,7 +65,8 @@ impl <'a> System<'a> for Draw { view.cells.clear(); for (pos, vis) in (&pos, &vis).join(){ if pos.x >= 0 && pos.y >= 0 && pos.x < view.width && pos.y < view.height { - view.cells.entry(*pos).or_insert(Vec::new()).push(vis.sprite.clone()); + view.cells.entry(*pos).or_insert(Vec::new()).push(vis.clone()); + view.cells.get_mut(pos).unwrap().sort_by(|a, b| b.height.partial_cmp(&a.height).unwrap()); } } } @@ -69,7 +77,9 @@ impl <'a> System<'a> for Draw { pub struct Room<'a, 'b> { world: World, - dispatcher: Dispatcher<'a, 'b> + dispatcher: Dispatcher<'a, 'b>, + spawn: (i32, i32), + players: HashMap<String, Entity> } impl <'a, 'b>Room<'a, 'b> { @@ -79,6 +89,7 @@ impl <'a, 'b>Room<'a, 'b> { let mut world = World::new(); world.register::<Position>(); world.register::<Visible>(); + world.register::<InputController>(); world.insert(Size(width, height)); world.insert(TopView{width: width, height: height, cells: HashMap::new()}); @@ -88,7 +99,9 @@ impl <'a, 'b>Room<'a, 'b> { let mut room = Room { world, - dispatcher + dispatcher, + spawn: (width / 2, height / 2), + players: HashMap::new() }; gen_room(&mut room); room @@ -103,8 +116,8 @@ impl <'a, 'b>Room<'a, 'b> { let mut mapping: Vec<Vec<String>> = Vec::with_capacity(size as usize); for y in 0..height { for x in 0..width { - let sprites = match tv.cells.get(&Position{x: x, y: y}) { - Some(sprites) => {sprites.to_vec()} + let sprites: Vec<String> = match tv.cells.get(&Position{x: x, y: y}) { + Some(sprites) => {sprites.iter().map(|v| v.sprite.clone()).collect()} None => {vec![]} }; values.push( @@ -133,8 +146,19 @@ impl <'a, 'b>Room<'a, 'b> { (width, height) } - pub fn add_obj(&mut self, template: &dyn Assemblage, (x, y): (i32, i32)) { - template.build(self.world.create_entity()).with(Position{x, y}).build(); + pub fn add_obj(&mut self, template: &dyn Assemblage, (x, y): (i32, i32)) -> Entity { + template.build(self.world.create_entity()).with(Position{x, y}).build() + } + + pub fn add_player(&mut self, name: &str) { + let ent = self.add_obj(&Player::new(name), self.spawn); + self.players.insert(name.to_string(), ent); + } + + pub fn remove_player(&mut self, name: &str){ + // todo: proper error handling + let ent = self.players.remove(name).expect("unknown player name"); + self.world.delete_entity(ent).expect("player in world does not have entity"); } } @@ -157,15 +181,17 @@ fn gen_room(room: &mut Room){ } - pub trait Assemblage { fn build<'a>(&self, builder: EntityBuilder<'a>) -> EntityBuilder<'a>; } + + +// Entity types + struct Wall; impl Assemblage for Wall { - fn build<'a>(&self, builder: EntityBuilder<'a>) -> EntityBuilder<'a>{ builder.with(Visible{sprite: "wall".to_string(), height: 2.0}) } @@ -184,8 +210,24 @@ impl Grass { } impl Assemblage for Grass { - fn build<'a>(&self, builder: EntityBuilder<'a>) -> EntityBuilder<'a>{ builder.with(Visible{sprite: self.sprite.to_string(), height: 0.1}) } } + + +struct Player { + name: String +} + +impl Player { + fn new(name: &str) -> Player { + Player { name: name.to_string()} + } +} + +impl Assemblage for Player { + fn build<'a>(&self, builder: EntityBuilder<'a>) -> EntityBuilder<'a>{ + builder.with(Visible{sprite: "player".to_string(), height: 1.0}).with(InputController{key: self.name.to_string()}) + } +} |
