Implement message types and lobby join

master^2
bel 2020-05-03 08:14:29 -06:00
parent 8971426dcd
commit 247e29ce13
9 changed files with 270 additions and 7 deletions

View File

@ -44,6 +44,12 @@ dependencies = [
"wasi", "wasi",
] ]
[[package]]
name = "json"
version = "0.12.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "078e285eafdfb6c4b434e0d31e8cfcb5115b651496faca5749b88fafd4f23bfd"
[[package]] [[package]]
name = "lazy_static" name = "lazy_static"
version = "1.4.0" version = "1.4.0"
@ -114,6 +120,7 @@ name = "secert-hitler"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"crossbeam-channel", "crossbeam-channel",
"json",
"rand", "rand",
] ]

View File

@ -9,3 +9,4 @@ edition = "2018"
[dependencies] [dependencies]
rand = "*" rand = "*"
crossbeam-channel = "*" crossbeam-channel = "*"
json = "*"

View File

@ -1,3 +1,4 @@
/*
use super::super::super::model::state::room::Room; use super::super::super::model::state::room::Room;
pub struct GameMaster { pub struct GameMaster {
@ -10,6 +11,24 @@ impl GameMaster {
room: room, room: room,
} }
} }
fn run(&self) -> Result<String, String> {
self.run_lobby()?;
self.run_game_setup()?;
self.run_game()
}
fn run_lobby(&self) -> Result<String, String> {
Err("not impl".to_string())
}
fn run_game_setup(&self) -> Result<String, String> {
Err("not impl".to_string())
}
fn run_game(&self) -> Result<String, String> {
Err("not impl".to_string())
}
} }
#[cfg(test)] #[cfg(test)]
@ -36,11 +55,29 @@ mod tests {
let _ = GameMaster::new(r); let _ = GameMaster::new(r);
} }
#[test] #[test]
fn new_mockrooms() { fn new_mockrooms() {
let mut mrs = MockRooms::new(); let mut mrs = MockRooms::new();
let r = mrs.create(); let r = mrs.create();
let _ = GameMaster::new(r); let _ = GameMaster::new(r);
} }
#[test]
fn gm_run_lobby_fail() {
let gm = GameMaster::new(Box::new(MockRoom::create()));
panic!("not impl");
}
#[test]
fn gm_run_game_setup_fail() {
let gm = GameMaster::new(Box::new(MockRoom::create()));
panic!("not impl");
}
#[test]
fn gm_run_game_fail() {
let gm = GameMaster::new(Box::new(MockRoom::create()));
panic!("not impl");
}
} }
*/

View File

@ -0,0 +1,70 @@
use super::player::Player;
use super::super::super::model::state::event::Event;
use std::collections::HashMap;
pub struct Lobby {
players: HashMap<String, Player>,
}
impl Lobby {
fn new() -> Lobby {
Lobby{
players: HashMap::new(),
}
}
fn eat(&mut self, message: Event) {
let j = message.join();
if j.is_none() {
return;
}
let id = j.unwrap();
self.players.insert(id.clone(), Player::new(id));
}
}
#[cfg(test)]
mod tests {
use super::*;
fn _dummy_event(m: &str) -> Event {
Event{
body: m.to_string(),
next: "a".to_string(),
sender: "b".to_string(),
}
}
#[test]
fn new_lobby() {
let _ = Lobby::new();
}
#[test]
fn eat_join() {
let mut l = Lobby::new();
let e = _dummy_event(r#"{"membership": "join", "displayname": "a"}"#);
let was = l.players.len();
l.eat(e);
assert!(was+1 == l.players.len(), "want {}, got {}: {:?}", was+1, l.players.len(), l.players);
}
#[test]
fn eat_join_malformatted() {
let mut l = Lobby::new();
let e = _dummy_event(r#"{"membership": "join"}"#);
let was = l.players.len();
l.eat(e);
assert!(was == l.players.len());
}
#[test]
fn eat_null() {
let mut l = Lobby::new();
let e = _dummy_event(r#"{"hello": "world"}"#);
let was = l.players.len();
l.eat(e);
assert!(was == l.players.len());
}
}

View File

@ -1 +1,3 @@
pub mod gamemaster; pub mod gamemaster;
pub mod player;
pub mod lobby;

View File

@ -0,0 +1,22 @@
#[derive(Clone, Debug)]
pub struct Player {
id: String,
}
impl Player {
pub fn new(id: String) -> Player {
Player {
id: id,
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn new_player() {
let _ = Player::new("id".to_string());
}
}

View File

@ -1,3 +1,5 @@
use json;
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub struct Event { pub struct Event {
pub sender: String, pub sender: String,
@ -5,15 +7,134 @@ pub struct Event {
pub next: String, pub next: String,
} }
#[derive(PartialEq, Eq, Debug)]
pub enum EventType {
Null,
Join,
Create,
Message,
}
impl Event {
pub fn mode(&self) -> EventType {
let d = json::parse(&self.body).unwrap();
if d["membership"].is_string() {
return match d["membership"].as_str().unwrap().to_string().as_ref() {
"join" => EventType::Join,
_ => EventType::Null,
};
}
if d["creator"].is_string() {
return EventType::Create;
}
if d["msgtype"].is_string() {
return match d["msgtype"].as_str().unwrap().to_string().as_ref() {
"m.text" => EventType::Message,
_ => EventType::Null,
};
}
EventType::Null
}
pub fn join(&self) -> Option<String> {
let d = json::parse(&self.body).unwrap();
match self.mode() {
EventType::Join => true,
_ => return None,
};
let o = d["displayname"].as_str();
if o.is_none() {
return None;
}
Some(o.unwrap().to_string())
}
}
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::*;
fn _dummy() -> Event {
Event{
sender: "sender".to_string(),
body: r#"{}"#.to_string(),
next: "next".to_string(),
}
}
#[test] #[test]
fn event() { fn event() {
let e = super::Event{ let e = Event{
sender: "sender".to_string(), sender: "sender".to_string(),
body: "body".to_string(), body: "body".to_string(),
next: "next".to_string(), next: "next".to_string(),
}; };
println!("{:?}", e); println!("{:?}", e);
} }
#[test]
fn mode_null() {
let mut e = _dummy();
e.body = r#"{
}"#.to_string();
assert!(e.mode() == EventType::Null);
}
#[test]
fn mode_create() {
let mut e = _dummy();
e.body = r#"{
"creator": "abc"
}"#.to_string();
assert!(e.mode() == EventType::Create);
}
#[test]
fn mode_msgtype() {
let mut e = _dummy();
e.body = r#"{
"msgtype": "m.text"
}"#.to_string();
assert!(e.mode() == EventType::Message);
}
#[test]
fn mode_join() {
let mut e = _dummy();
e.body = r#"{
"membership": "join"
}"#.to_string();
assert!(e.mode() == EventType::Join);
}
#[test]
fn join_some() {
let mut e = _dummy();
e.body = r#"{
"displayname": "hi",
"membership": "join"
}"#.to_string();
let j = e.join();
assert!(j.is_some());
}
#[test]
fn join_some_bad() {
let mut e = _dummy();
e.body = r#"{
"membership": "join"
}"#.to_string();
let j = e.join();
assert!(j.is_none());
}
#[test]
fn join_none() {
let mut e = _dummy();
e.body = r#"{
"a": "b"
}"#.to_string();
let j = e.join();
assert!(j.is_none());
}
} }

View File

@ -82,10 +82,12 @@ out="$(
-H 'content-type: application/json' \ -H 'content-type: application/json' \
-H 'Authorization: Bearer '"$access_token" \ -H 'Authorization: Bearer '"$access_token" \
| jq '{"timeline": .rooms.join[].timeline.events[], "next": .next_batch}' \ | jq '{"timeline": .rooms.join[].timeline.events[], "next": .next_batch}' \
| jq '{"content": .timeline.content.body, "sender": .timeline.sender, "next": .next}' | jq '{"content": .timeline.content, "sender": .timeline.sender, "next": .next}' \
)" )"
printf "%s\n" "$out" printf "%s\n" "$out" | jq .
since="$(echo "$out" | jq -r .next | tail -n 1)" since="$(
echo "$out" \
| jq -r .next | tail -n 1)"
# send new message # send new message
txid="$(cat /proc/sys/kernel/random/uuid)" txid="$(cat /proc/sys/kernel/random/uuid)"
@ -112,5 +114,6 @@ curl -sS "http://localhost:39487/_matrix/client/r0/sync?since=$since" \
-H 'content-type: application/json' \ -H 'content-type: application/json' \
-H 'Authorization: Bearer '"$access_token" \ -H 'Authorization: Bearer '"$access_token" \
| jq '{"timeline": .rooms.join[].timeline.events[], "next": .next_batch}' \ | jq '{"timeline": .rooms.join[].timeline.events[], "next": .next_batch}' \
| jq '{"content": .timeline.content.body, "sender": .timeline.sender, "next": .next}' | jq '{"content": .timeline.content, "sender": .timeline.sender, "next": .next}' \
| jq .

View File

@ -20,7 +20,7 @@ handlers:
file: file:
class: logging.handlers.RotatingFileHandler class: logging.handlers.RotatingFileHandler
formatter: precise formatter: precise
filename: /home/bel/Go/src/local/containers/secret-hitler-via-matrix/testdata/matrix-sandbox/homeserver.log filename: /tmp/synapse-test-real.log
maxBytes: 104857600 maxBytes: 104857600
backupCount: 10 backupCount: 10
filters: [context] filters: [context]