Compare commits

..

No commits in common. "fbaf386ebb65b5fe55e0cdc096e264cd47054b53" and "09c5fe3d8b57d9e305f14045d776dd10b8f6ff51" have entirely different histories.

4 changed files with 18 additions and 136 deletions

34
Cargo.lock generated
View File

@ -2,15 +2,6 @@
# It is not intended for manual editing. # It is not intended for manual editing.
version = 3 version = 3
[[package]]
name = "aho-corasick"
version = "0.7.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b4f55bd91a0978cbfd91c457a164bab8b4001c833b7f323132c0a4e1922dd44e"
dependencies = [
"memchr",
]
[[package]] [[package]]
name = "autocfg" name = "autocfg"
version = "1.1.0" version = "1.1.0"
@ -171,8 +162,6 @@ dependencies = [
name = "hexland-server" name = "hexland-server"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"rand",
"regex",
"sha2", "sha2",
"tungstenite", "tungstenite",
] ]
@ -240,12 +229,6 @@ dependencies = [
"cfg-if", "cfg-if",
] ]
[[package]]
name = "memchr"
version = "2.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d"
[[package]] [[package]]
name = "native-tls" name = "native-tls"
version = "0.2.10" version = "0.2.10"
@ -390,23 +373,6 @@ dependencies = [
"bitflags", "bitflags",
] ]
[[package]]
name = "regex"
version = "1.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4c4eb3267174b8c6c2f654116623910a0fef09c4753f8dd83db29c48a0df988b"
dependencies = [
"aho-corasick",
"memchr",
"regex-syntax",
]
[[package]]
name = "regex-syntax"
version = "0.6.27"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a3f87b73ce11b1619a3c6332f45341e0047173771e8b8b73f87bfeefb7b56244"
[[package]] [[package]]
name = "remove_dir_all" name = "remove_dir_all"
version = "0.5.3" version = "0.5.3"

View File

@ -7,6 +7,4 @@ edition = "2021"
[dependencies] [dependencies]
tungstenite = { version = "0.17.3", features = ["native-tls"] } tungstenite = { version = "0.17.3", features = ["native-tls"] }
sha2 = "0.10.6" sha2 = "0.10.6"
rand = "0.8.5"
regex = "1.6.0"

View File

@ -1,61 +1,42 @@
use std::net::TcpListener; use std::net::TcpListener;
use std::thread; use std::thread;
use std::sync::{Arc, Mutex}; use std::sync::{Arc, Mutex};
use std::collections::HashMap;
mod message; use tungstenite::protocol::Message;
use message::Message;
use rand::RngCore;
use tungstenite::protocol::Message as WsMessage;
use sha2::{Sha256, Digest}; use sha2::{Sha256, Digest};
fn main() { fn main() {
let code_generator = Arc::new(Mutex::new(CodeGenerator::default())); let code_generator = Arc::new(Mutex::new(CodeGenerator {
counter: 0,
salt: [0; 32], // TODO have this be randomized on startup
}));
let server = TcpListener::bind("127.0.0.1:8080").unwrap(); let server = TcpListener::bind("127.0.0.1:8080").unwrap();
let rooms = Arc::new(Mutex::new(HashMap::new()));
for stream in server.incoming() { for stream in server.incoming() {
let code_generator = Arc::clone(&code_generator); thread::spawn ( { let code_generator = Arc::clone(&code_generator); move || {
let rooms = Arc::clone(&rooms);
thread::spawn (move || {
let mut ws = tungstenite::accept(stream.unwrap()).unwrap(); let mut ws = tungstenite::accept(stream.unwrap()).unwrap();
println!("New client!"); println!("New client!");
ws.write_message(WsMessage::Text("HOSTJOIN:".to_string())).unwrap(); ws.write_message(Message::Text("HOSTJOIN:".to_string())).unwrap();
loop { loop {
let message = ws.read_message(); let message = ws.read_message();
println!("{:?}", message); println!("{:?}", message);
match message { match message {
Err(_) => break, Err(_) => break,
Ok(WsMessage::Close(_)) => break, Ok(Message::Text(msg)) =>
Ok(WsMessage::Text(msg)) => { match msg.as_str().trim() {
let msg = Message::parse(msg.as_str().trim()); "HOST:" => {
match msg { ws.write_message(Message::Text(code_generator.lock().unwrap().generate())).unwrap();
Ok(msg) => },
match msg.command { _ => unimplemented!(),
"HOST" => { },
let code = code_generator.lock().unwrap().generate();
let mut room = Room::default();
let player = Player { name: "Guest".to_string() };
room.players.push(player);
rooms.lock().unwrap().insert(code.clone(), room);
ws.write_message(WsMessage::Text(code)).unwrap();
}
_ => todo!(),
}
Err(_) => todo!(),
}
}
_ => unimplemented!(), _ => unimplemented!(),
} }
} }
}); }});
} }
} }
#[derive(Default)]
struct Room { struct Room {
players: Vec<Player>, players: Vec<Player>,
} }
@ -81,15 +62,3 @@ impl CodeGenerator {
format!("{:x}", hasher.finalize())[..6].to_string() format!("{:x}", hasher.finalize())[..6].to_string()
} }
} }
impl Default for CodeGenerator {
fn default() -> Self {
let mut salt = [0; 32];
rand::thread_rng().fill_bytes(&mut salt);
CodeGenerator {
counter: 0,
salt,
}
}
}

View File

@ -1,51 +0,0 @@
#[derive(PartialEq, Debug)]
pub struct Message<'a> {
pub command: &'a str,
pub args: Vec<&'a str>,
}
pub type Result<T> = std::result::Result<T, Error>;
#[repr(u8)]
#[derive(PartialEq, Debug)]
pub enum Error {
BadParse,
UnknownCommand,
}
impl<'a> Message<'a> {
pub fn parse(text: &'a str) -> Result<Message<'a>> {
let re = regex::Regex::new(r"^([A-Z_]+):\s*(.*)").unwrap();
match re.captures(text) {
Some(captures) => {
if captures.len() < 3 {
Err(Error::BadParse)
} else {
let command = captures.get(1).unwrap().as_str();
let args = captures.get(2).unwrap().as_str()
.split(',')
.map(|s| s.trim())
.collect();
Ok(Message { command, args })
}
}
None => Err(Error::BadParse),
}
}
}
#[cfg(test)]
mod test {
use super::*;
#[test]
fn test_parse() -> Result<()> {
let text = "COMMAND: arg1, arg2";
let msg = Message::parse(text)?;
assert_eq!(Message {
command: "COMMAND",
args: vec!["arg1", "arg2"],
}, msg);
Ok(())
}
}