summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Cargo.toml6
-rw-r--r--src/gameserver.rs33
-rw-r--r--src/main.rs41
-rw-r--r--src/room.rs68
4 files changed, 102 insertions, 46 deletions
diff --git a/Cargo.toml b/Cargo.toml
index bbe5690..979981d 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -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()})
+ }
+}