summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authortroido <troido@protonmail.com>2019-01-24 19:47:20 +0100
committertroido <troido@protonmail.com>2019-01-24 19:47:20 +0100
commit864335ea6007dbfebe87ff717aeec8478ca10ec5 (patch)
treeadd9e380a9d83cc8380dc59d6ab1583751012abf
parentd4d03e2f6c495858faeb1560754a6f34a62e76d1 (diff)
made gameserver its own file
-rwxr-xr-xclient.py1
-rw-r--r--src/gameserver.rs147
-rw-r--r--src/main.rs163
-rw-r--r--src/server/tcpserver.rs5
-rw-r--r--src/server/unixserver.rs5
5 files changed, 159 insertions, 162 deletions
diff --git a/client.py b/client.py
index f1f6867..2e4a4c4 100755
--- a/client.py
+++ b/client.py
@@ -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();