diff options
| author | troido <troido@protonmail.com> | 2019-01-24 19:47:20 +0100 |
|---|---|---|
| committer | troido <troido@protonmail.com> | 2019-01-24 19:47:20 +0100 |
| commit | 864335ea6007dbfebe87ff717aeec8478ca10ec5 (patch) | |
| tree | add9e380a9d83cc8380dc59d6ab1583751012abf | |
| parent | d4d03e2f6c495858faeb1560754a6f34a62e76d1 (diff) | |
made gameserver its own file
| -rwxr-xr-x | client.py | 1 | ||||
| -rw-r--r-- | src/gameserver.rs | 147 | ||||
| -rw-r--r-- | src/main.rs | 163 | ||||
| -rw-r--r-- | src/server/tcpserver.rs | 5 | ||||
| -rw-r--r-- | src/server/unixserver.rs | 5 |
5 files changed, 159 insertions, 162 deletions
@@ -49,6 +49,7 @@ if len(sys.argv) >= 2: name = sys.argv[1] else: name = "~" + getpass.getuser() +print(name) send(sock, bytes(json.dumps(["name", name]), "utf-8")) diff --git a/src/gameserver.rs b/src/gameserver.rs new file mode 100644 index 0000000..76ffbd6 --- /dev/null +++ b/src/gameserver.rs @@ -0,0 +1,147 @@ + + +use std::collections::HashMap; +use std::io; + +use json; +use json::JsonValue; + +use super::server::Server; + + +pub enum Message { + Name(String), + Chat(String), + Input, + Invalid(String) +} + +pub struct GameServer<T: Server> { + players: HashMap<usize, String>, + connections: HashMap<String, usize>, + server: T +} + +impl<T: Server> GameServer<T> { + pub fn new(server: T) -> GameServer<T> { + GameServer { + players: HashMap::new(), + connections: HashMap::new(), + server + } + } + + pub fn update(&mut self) { + self.accept_connections(); + self.receive_messages(); + } + + fn accept_connections(&mut self) { + let _joined = self.server.accept_pending_connections(); + } + + fn receive_messages(&mut self) { + + let (messages, left) = self.server.recv_pending_messages(); + for (id, message) in messages { + self.handle_message(id, parse_message(&message)); + } + for id in left { + self.remove_connection(id); + } + } + + fn send_error(&mut self, id: usize, errname: &str, err_text: &str) -> Result<(), io::Error>{ + self.server.send(id, &json::stringify(json::array!["error", errname, err_text])) + } + + pub fn broadcast_message(&mut self, text: &str){ + println!("{}", text); + let jsontext = json::stringify(json::array!["message", text]); + for (id, _name) in &self.players { + let _ = self.server.send(*id, &jsontext); + } + } + + pub fn handle_message(&mut self, id: usize, msg: Message) { + match msg { + Message::Name(name) => { + let (firstchar, username) = name.split_at(1); + if firstchar == "~"{ + if Some(username.to_string()) != self.server.get_name(id) { + let _ = self.send_error(id, "invalidname", &format!("A tilde name must match your username")); + return; + } + } + if self.players.contains_key(&id) { + let _ = self.send_error(id, "invalidaction", &format!("You can not change your name")); + return; + } + if self.connections.contains_key(&name) { + let _ = self.send_error(id, "nametaken", &format!("Another connections to this player exists already")); + return; + } + self.broadcast_message(&format!("{} connected", name)); + self.players.insert(id, name.clone()); + self.connections.insert(name, id); + } + Message::Chat(text) => { + if let Some(name) = self.players.get(&id) { + self.broadcast_message(&format!("{}: {}", name, text)); + } else { + let _ = self.send_error(id, "invalidaction", &format!("Set a name before you send other messages")); + } + } + Message::Input => { () } + Message::Invalid(text) => { + let _ = self.send_error(id, "invalidmessage", &format!("Invalid: {}", text)); + } + } + } + + pub fn remove_connection(&mut self, id: usize) { + if let Some(name) = self.players.remove(&id){ + self.connections.remove(&name); + self.broadcast_message(&format!("{} disconnected", name)); + } + } +} + + + +fn parse_message(msg: &str) -> Message { + if let Ok(data) = json::parse(msg) { + if let JsonValue::Array(arr) = data { + if arr.len() < 2 { + return Message::Invalid("array not long enough".to_string()); + } + if let Some(msgtype) = arr[0].as_str() { + match msgtype { + "name" => { + if let Some(name) = arr[1].as_str(){ + Message::Name(name.to_string()) + } else { + Message::Invalid("name is not a string".to_string()) + } + } + "chat" => { + if let Some(text) = arr[1].as_str(){ + Message::Chat(text.to_string()) + } else { + Message::Invalid("chat text is not a string".to_string()) + } + + } + "input" => { + Message::Input + } + _ => { + 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("not json array".to_string()) } + } else { Message::Invalid("not json message".to_string()) } +} + + diff --git a/src/main.rs b/src/main.rs index 37a298f..ff60460 100644 --- a/src/main.rs +++ b/src/main.rs @@ -3,85 +3,13 @@ use std::thread::sleep; use std::time::Duration; use std::path::Path; -use std::collections::HashMap; -use std::io; - -use json; -use json::JsonValue; pub mod server; -use self::server::Server; -// use self::server::tcpserver::TcpServer; -use self::server::unixserver::UnixServer; - - -enum Message { - Name(String), - Chat(String), - Input, - Invalid(String) -} +pub mod gameserver; -struct GameServer<T: Server> { - players: HashMap<usize, String>, - server: T -} +use self::gameserver::GameServer; +use self::server::unixserver::UnixServer; -impl<T: Server> GameServer<T> { - pub fn new(server: T) -> GameServer<T> { - GameServer { - players: HashMap::new(), - server - } - } - - fn send_error(&mut self, id: usize, err_text: &str) -> Result<(), io::Error>{ - self.server.send(id, err_text) - } - - pub fn broadcast_message(&mut self, text: &str){ - for (id, _name) in &self.players { - let _ = self.server.send(*id, text); - } - } - - pub fn handle_message(&mut self, id: usize, msg: Message) { - match msg { - Message::Name(name) => { - let (firstchar, username) = name.split_at(1); - if firstchar == "~"{ - if Some(username.to_string()) != self.server.get_name(id) { - let _ = self.send_error(id, &format!("A tilde name must match your username")); - } - } else { - if let Some(oldname) = self.players.get(&id) { - self.broadcast_message(&format!("{} is now known as {}", oldname, name)); - } else { - self.broadcast_message(&format!("{} connected", name)); - } - self.players.insert(id, name); - } - } - Message::Chat(text) => { - if let Some(name) = self.players.get(&id) { - self.broadcast_message(&format!("{}: {}", name, text)); - } else { - let _ = self.send_error(id, &format!("Set a name before you send other messages")); - } - } - Message::Input => { () } - Message::Invalid(text) => { - let _ = self.send_error(id, &format!("Invalid: {}", text)); - } - } - } - - pub fn remove_connection(&mut self, id: usize) { - if let Some(name) = self.players.remove(&id){ - self.broadcast_message(&format!("{} disconnected", name)); - } - } -} fn main() { @@ -89,7 +17,7 @@ fn main() { let addr = Path::new("\0rustifarm"); - let mut socketserver = UnixServer::new(&addr).expect("binding server failed"); + let socketserver = UnixServer::new(&addr).expect("binding server failed"); let mut gameserver = GameServer::new(socketserver); @@ -98,90 +26,9 @@ fn main() { // let mut players: HashMap<usize, String> = HashMap::new(); loop { - let _joined = server.accept_pending_connections(); -// for id in joined { -// // let name = server.get_name(id).expect("Unable to get name"); -// gameserver.broadcast_message(&format!("{} connected", id)); -// } - let (messages, left) = server.recv_pending_messages(); - for (id, message) in messages { - -// let name = server.get_name(id).expect("Unable to get name"); - gameserver.handle_message(parse_message(&message[..])); -// match parse_message(&message[..]) { -// Message::Name(name) => { -// let (firstchar, username) = name.split_at(1); -// if firstchar == "~"{ -// if Some(username.to_string()) != server.get_name(id) { -// let _ = server.send(id, &format!("A tilde name must match your username")); -// } -// } else { -// if let Some(oldname) = players.get(&id) { -// server.broadcast(&format!("{} is now known as {}", oldname, name)); -// } else { -// server.broadcast(&format!("{} connected", name)); -// } -// players.insert(id, name); -// } -// } -// Message::Chat(text) => { -// if let Some(name) = players.get(&id) { -// server.broadcast(&format!("{}: {}", name, text)); -// } else { -// let _ = server.send(id, &format!("Set a name before you send other messages")); -// } -// } -// Message::Input => { () } -// Message::Invalid(text) => { -// let _ = server.send(id, &format!("Invalid: {}", text)); -// } -// }; - println!("{}: {}", id, message); - } - for id in left { - gameserver.remove_connection(id); -// if let Some(name) = players.remove(&id){ -// server.broadcast(&format!("{} disconnected", name)); -// } - } + gameserver.update(); sleep(Duration::from_millis(100)); } } -fn parse_message(msg: &str) -> Message { - if let Ok(data) = json::parse(msg) { - if let JsonValue::Array(arr) = data { - if arr.len() < 2 { - return Message::Invalid("array not long enough".to_string()); - } - if let Some(msgtype) = arr[0].as_str() { - match msgtype { - "name" => { - if let Some(name) = arr[1].as_str(){ - Message::Name(name.to_string()) - } else { - Message::Invalid("name is not a string".to_string()) - } - } - "chat" => { - if let Some(text) = arr[1].as_str(){ - Message::Chat(text.to_string()) - } else { - Message::Invalid("chat text is not a string".to_string()) - } - - } - "input" => { - Message::Input - } - _ => { - 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("not json array".to_string()) } - } else { Message::Invalid("not json message".to_string()) } -} - - diff --git a/src/server/tcpserver.rs b/src/server/tcpserver.rs index b411634..924d1e5 100644 --- a/src/server/tcpserver.rs +++ b/src/server/tcpserver.rs @@ -5,7 +5,8 @@ use std::net::SocketAddr; use mio::net::{TcpListener, TcpStream}; use slab::Slab; -use self::super::streamconnection::StreamConnection; +use super::streamconnection::StreamConnection; +use super::Server; pub struct TcpServer { @@ -24,7 +25,7 @@ impl TcpServer { } } -impl super::Server for TcpServer { +impl Server for TcpServer { fn accept_pending_connections(&mut self) -> Vec<usize> { let mut new_connections = Vec::new(); diff --git a/src/server/unixserver.rs b/src/server/unixserver.rs index dc9feab..f3181de 100644 --- a/src/server/unixserver.rs +++ b/src/server/unixserver.rs @@ -9,7 +9,8 @@ use nix::sys::socket::getsockopt; use nix::sys::socket::sockopt; use users; -use self::super::streamconnection::StreamConnection; +use super::streamconnection::StreamConnection; +use super::Server; pub struct UnixServer { @@ -30,7 +31,7 @@ impl UnixServer { } -impl super::Server for UnixServer { +impl Server for UnixServer { fn accept_pending_connections(&mut self) -> Vec<usize> { let mut new_connections = Vec::new(); |
