|
|
@ -1,9 +1,13 @@
|
|
|
|
use crate::dictionary::lookup;
|
|
|
|
use crate::DatabaseCreationError;
|
|
|
|
|
|
|
|
use crate::lookup;
|
|
|
|
|
|
|
|
use crate::Word;
|
|
|
|
|
|
|
|
use crate::Database;
|
|
|
|
|
|
|
|
|
|
|
|
use simple_websockets::{Event, Responder, Message, EventHub};
|
|
|
|
use simple_websockets::{Event, Responder, Message, EventHub};
|
|
|
|
use std::collections::HashMap;
|
|
|
|
use std::collections::HashMap;
|
|
|
|
use serde::Serialize;
|
|
|
|
use serde::Serialize;
|
|
|
|
use wana_kana::{ConvertJapanese, IsJapaneseStr};
|
|
|
|
use wana_kana::{ConvertJapanese, IsJapaneseStr};
|
|
|
|
|
|
|
|
use derive_more::From;
|
|
|
|
|
|
|
|
|
|
|
|
#[derive(Serialize)]
|
|
|
|
#[derive(Serialize)]
|
|
|
|
struct MessageResponse {
|
|
|
|
struct MessageResponse {
|
|
|
@ -25,10 +29,12 @@ enum MessageResponseData {
|
|
|
|
},
|
|
|
|
},
|
|
|
|
Word {
|
|
|
|
Word {
|
|
|
|
author: u64,
|
|
|
|
author: u64,
|
|
|
|
word: String,
|
|
|
|
word: Word,
|
|
|
|
reading: Option<String>,
|
|
|
|
|
|
|
|
next_char: char,
|
|
|
|
next_char: char,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
|
|
|
|
History {
|
|
|
|
|
|
|
|
words: Vec<Word>,
|
|
|
|
|
|
|
|
},
|
|
|
|
PlayerCount {
|
|
|
|
PlayerCount {
|
|
|
|
players: u64,
|
|
|
|
players: u64,
|
|
|
|
},
|
|
|
|
},
|
|
|
@ -42,6 +48,7 @@ impl MessageResponseData {
|
|
|
|
String::from(match self {
|
|
|
|
String::from(match self {
|
|
|
|
Self::Greeting { .. } => "greeting",
|
|
|
|
Self::Greeting { .. } => "greeting",
|
|
|
|
Self::Word { .. } => "word",
|
|
|
|
Self::Word { .. } => "word",
|
|
|
|
|
|
|
|
Self::History { .. } => "history",
|
|
|
|
Self::PlayerCount { .. } => "playerCount",
|
|
|
|
Self::PlayerCount { .. } => "playerCount",
|
|
|
|
Self::Error { .. } => "error",
|
|
|
|
Self::Error { .. } => "error",
|
|
|
|
})
|
|
|
|
})
|
|
|
@ -61,29 +68,43 @@ impl MessageResponseData {
|
|
|
|
|
|
|
|
|
|
|
|
pub struct Server {
|
|
|
|
pub struct Server {
|
|
|
|
event_hub: EventHub,
|
|
|
|
event_hub: EventHub,
|
|
|
|
|
|
|
|
database: Database,
|
|
|
|
clients: HashMap<u64, Responder>,
|
|
|
|
clients: HashMap<u64, Responder>,
|
|
|
|
next_char: Option<char>,
|
|
|
|
next_char: Option<char>,
|
|
|
|
last_response: Option<MessageResponse>,
|
|
|
|
|
|
|
|
last_client_id: Option<u64>,
|
|
|
|
last_client_id: Option<u64>,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#[derive(From, Debug)]
|
|
|
|
|
|
|
|
pub enum ServerCreationError {
|
|
|
|
|
|
|
|
SimpleWebsocketsError(simple_websockets::Error),
|
|
|
|
|
|
|
|
DatabaseCreationError(DatabaseCreationError),
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#[derive(From, Debug)]
|
|
|
|
|
|
|
|
pub enum ServerError {
|
|
|
|
|
|
|
|
DatabaseError(rusqlite::Error),
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
impl Server {
|
|
|
|
impl Server {
|
|
|
|
pub fn new(port: u16) -> Result<Self, simple_websockets::Error> {
|
|
|
|
pub fn new(port: u16, testing: bool) -> Result<Self, ServerCreationError> {
|
|
|
|
Ok(Server {
|
|
|
|
Ok(Server {
|
|
|
|
event_hub: simple_websockets::launch(port)?,
|
|
|
|
event_hub: simple_websockets::launch(port)?,
|
|
|
|
|
|
|
|
database: Database::new(testing)?,
|
|
|
|
clients: HashMap::new(),
|
|
|
|
clients: HashMap::new(),
|
|
|
|
next_char: None,
|
|
|
|
next_char: None,
|
|
|
|
last_response: None,
|
|
|
|
|
|
|
|
last_client_id: None,
|
|
|
|
last_client_id: None,
|
|
|
|
})
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
pub fn run(&mut self) {
|
|
|
|
pub fn run(&mut self) {
|
|
|
|
loop {
|
|
|
|
loop {
|
|
|
|
match self.event_hub.poll_event() {
|
|
|
|
match match self.event_hub.poll_event() {
|
|
|
|
Event::Connect(client_id, responder) => self.handle_connection(client_id, responder),
|
|
|
|
Event::Connect(client_id, responder) => self.handle_connection(client_id, responder),
|
|
|
|
Event::Disconnect(client_id) => self.handle_disconnection(client_id),
|
|
|
|
Event::Disconnect(client_id) => self.handle_disconnection(client_id),
|
|
|
|
Event::Message(client_id, message) => self.handle_message(client_id, message),
|
|
|
|
Event::Message(client_id, message) => self.handle_message(client_id, message),
|
|
|
|
|
|
|
|
} {
|
|
|
|
|
|
|
|
Ok(()) => {},
|
|
|
|
|
|
|
|
Err(error) => println!("{:?}", error),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -95,27 +116,31 @@ impl Server {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
fn handle_connection(&mut self, client_id: u64, responder: Responder) {
|
|
|
|
fn handle_connection(&mut self, client_id: u64, responder: Responder) -> Result<(), ServerError> {
|
|
|
|
println!("A client connected with id #{}", client_id);
|
|
|
|
println!("A client connected with id #{}", client_id);
|
|
|
|
responder.send(MessageResponseData::Greeting { id: client_id }.into_message());
|
|
|
|
responder.send(MessageResponseData::Greeting {
|
|
|
|
if let Some(ref last_response) = self.last_response {
|
|
|
|
id: client_id
|
|
|
|
responder.send(last_response.to_message());
|
|
|
|
}.into_message());
|
|
|
|
}
|
|
|
|
responder.send(MessageResponseData::History {
|
|
|
|
|
|
|
|
words: self.database.load_words_before(self.database.last_word_id + 1)?
|
|
|
|
|
|
|
|
}.into_message());
|
|
|
|
self.clients.insert(client_id, responder);
|
|
|
|
self.clients.insert(client_id, responder);
|
|
|
|
self.broadcast_player_count();
|
|
|
|
self.broadcast_player_count();
|
|
|
|
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
fn handle_disconnection(&mut self, client_id: u64) {
|
|
|
|
fn handle_disconnection(&mut self, client_id: u64) -> Result<(), ServerError> {
|
|
|
|
println!("Client #{} disconnected.", client_id);
|
|
|
|
println!("Client #{} disconnected.", client_id);
|
|
|
|
self.clients.remove(&client_id);
|
|
|
|
self.clients.remove(&client_id);
|
|
|
|
self.broadcast_player_count();
|
|
|
|
self.broadcast_player_count();
|
|
|
|
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
fn handle_message(&mut self, client_id: u64, message: Message) {
|
|
|
|
fn handle_message(&mut self, client_id: u64, message: Message) -> Result<(), ServerError> {
|
|
|
|
// Ignore binary messages
|
|
|
|
// Ignore binary messages
|
|
|
|
let message = match message {
|
|
|
|
let message = match message {
|
|
|
|
Message::Text(message) => message,
|
|
|
|
Message::Text(message) => message,
|
|
|
|
Message::Binary(_) => return,
|
|
|
|
Message::Binary(_) => return Ok(()),
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
// Debug
|
|
|
|
// Debug
|
|
|
@ -144,10 +169,11 @@ impl Server {
|
|
|
|
final_char
|
|
|
|
final_char
|
|
|
|
}.to_string().to_hiragana().chars().next().unwrap())
|
|
|
|
}.to_string().to_hiragana().chars().next().unwrap())
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
let word: Word = entry.clone().into();
|
|
|
|
|
|
|
|
self.database.add_word(&word)?;
|
|
|
|
MessageResponseData::Word {
|
|
|
|
MessageResponseData::Word {
|
|
|
|
author: client_id,
|
|
|
|
author: client_id,
|
|
|
|
word: entry.kanji.to_owned(),
|
|
|
|
word,
|
|
|
|
reading: Some(entry.reading.to_owned()),
|
|
|
|
|
|
|
|
next_char: self.next_char.unwrap(),
|
|
|
|
next_char: self.next_char.unwrap(),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
@ -172,10 +198,9 @@ impl Server {
|
|
|
|
for (_client, responder) in self.clients.iter() {
|
|
|
|
for (_client, responder) in self.clients.iter() {
|
|
|
|
responder.send(response.to_message());
|
|
|
|
responder.send(response.to_message());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
self.last_response = Some(response);
|
|
|
|
|
|
|
|
self.last_client_id = Some(client_id);
|
|
|
|
self.last_client_id = Some(client_id);
|
|
|
|
},
|
|
|
|
},
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|