more cleanup
This commit is contained in:
parent
d0ac4bb93b
commit
67be24707d
5 changed files with 97 additions and 61 deletions
|
@ -4,12 +4,12 @@ use crate::AppState;
|
||||||
use crate::DmUserMethod::*;
|
use crate::DmUserMethod::*;
|
||||||
use crate::GameHandlerMessage::*;
|
use crate::GameHandlerMessage::*;
|
||||||
use crate::SendUserMessage::*;
|
use crate::SendUserMessage::*;
|
||||||
use crate::Sender;
|
|
||||||
use crate::UserHandlerMessage::*;
|
use crate::UserHandlerMessage::*;
|
||||||
use axum::extract::ws::Message;
|
use axum::extract::ws::Message;
|
||||||
use lib::*;
|
use lib::*;
|
||||||
use serde_json::to_string;
|
use serde_json::to_string;
|
||||||
use std::{collections::HashMap, net::SocketAddr, sync::Arc};
|
use std::{collections::HashMap, net::SocketAddr, sync::Arc};
|
||||||
|
use tokio::sync::mpsc::Sender;
|
||||||
|
|
||||||
/// For interacting with the game handler
|
/// For interacting with the game handler
|
||||||
pub enum GameHandlerMessage {
|
pub enum GameHandlerMessage {
|
||||||
|
|
|
@ -5,8 +5,7 @@ use crate::UserHandlerMessage::*;
|
||||||
use axum::extract::ws::{CloseFrame, Message};
|
use axum::extract::ws::{CloseFrame, Message};
|
||||||
use lib::*;
|
use lib::*;
|
||||||
use serde_json::{from_str, to_string};
|
use serde_json::{from_str, to_string};
|
||||||
use std::net::SocketAddr;
|
use std::{net::SocketAddr, sync::Arc};
|
||||||
use std::sync::Arc;
|
|
||||||
|
|
||||||
/// Handles incoming messages
|
/// Handles incoming messages
|
||||||
pub struct IncomingMessageHandler {
|
pub struct IncomingMessageHandler {
|
||||||
|
|
|
@ -1,11 +1,9 @@
|
||||||
#![feature(if_let_guard)]
|
#![feature(if_let_guard)]
|
||||||
|
|
||||||
use crate::game_handler::*;
|
use crate::game_handler::*;
|
||||||
use anyhow::{Context, Result};
|
|
||||||
use axum::extract::ws::Message;
|
use axum::extract::ws::Message;
|
||||||
use lib::*;
|
|
||||||
use std::{
|
use std::{
|
||||||
collections::{HashMap, HashSet},
|
collections::HashMap,
|
||||||
net::SocketAddr,
|
net::SocketAddr,
|
||||||
sync::{Arc, RwLock},
|
sync::{Arc, RwLock},
|
||||||
};
|
};
|
||||||
|
@ -17,6 +15,7 @@ pub mod card_loader;
|
||||||
pub mod game;
|
pub mod game;
|
||||||
pub mod game_handler;
|
pub mod game_handler;
|
||||||
pub mod incoming_message_handler;
|
pub mod incoming_message_handler;
|
||||||
|
pub mod name_generator;
|
||||||
pub mod user_handler;
|
pub mod user_handler;
|
||||||
pub mod websocket;
|
pub mod websocket;
|
||||||
|
|
||||||
|
|
54
server/src/name_generator.rs
Normal file
54
server/src/name_generator.rs
Normal file
|
@ -0,0 +1,54 @@
|
||||||
|
use anyhow::{Context, Result};
|
||||||
|
use rand::prelude::SliceRandom;
|
||||||
|
use std::{
|
||||||
|
collections::HashSet,
|
||||||
|
fs::File,
|
||||||
|
io::{BufRead, BufReader},
|
||||||
|
};
|
||||||
|
|
||||||
|
pub struct NameGenerator {
|
||||||
|
first_names: Vec<String>,
|
||||||
|
last_names: Vec<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Parse name list
|
||||||
|
pub fn load_names(path: &str) -> Result<Vec<String>> {
|
||||||
|
let f = File::open(path).with_context(|| format!("Invalid names path: \"{}\"", path))?;
|
||||||
|
let f = BufReader::new(f);
|
||||||
|
|
||||||
|
let mut buf = vec![];
|
||||||
|
|
||||||
|
for line in f.lines() {
|
||||||
|
buf.push(line?)
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(buf)
|
||||||
|
}
|
||||||
|
|
||||||
|
impl NameGenerator {
|
||||||
|
pub fn new() -> Self {
|
||||||
|
NameGenerator {
|
||||||
|
first_names: load_names("data/first.txt").unwrap(),
|
||||||
|
last_names: load_names("data/last.txt").unwrap(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn generate(&mut self, reserved_names: &HashSet<String>) -> String {
|
||||||
|
// Roll for username and re-roll if taken
|
||||||
|
let mut name;
|
||||||
|
|
||||||
|
loop {
|
||||||
|
name = format!(
|
||||||
|
"{} {}",
|
||||||
|
self.first_names.choose(&mut rand::thread_rng()).unwrap(),
|
||||||
|
self.last_names.choose(&mut rand::thread_rng()).unwrap(),
|
||||||
|
);
|
||||||
|
|
||||||
|
if !reserved_names.contains(&name) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
name
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,41 +1,28 @@
|
||||||
|
use crate::name_generator::*;
|
||||||
use crate::AppState;
|
use crate::AppState;
|
||||||
use crate::DmUserMethod::*;
|
use crate::DmUserMethod::*;
|
||||||
|
use crate::GameHandlerMessage;
|
||||||
use crate::SendUserMessage::*;
|
use crate::SendUserMessage::*;
|
||||||
use crate::User;
|
use crate::User;
|
||||||
use crate::UserHandlerMessage::*;
|
use crate::UserHandlerMessage::*;
|
||||||
use crate::*;
|
use axum::extract::ws::Message;
|
||||||
use rand::prelude::SliceRandom;
|
use lib::*;
|
||||||
use serde_json::to_string;
|
use serde_json::to_string;
|
||||||
use std::{
|
use std::{
|
||||||
fs::File,
|
collections::{HashMap, HashSet},
|
||||||
io::{BufRead, BufReader},
|
|
||||||
net::SocketAddr,
|
net::SocketAddr,
|
||||||
sync::{Arc, RwLock},
|
sync::{Arc, RwLock},
|
||||||
};
|
};
|
||||||
|
use tokio::sync::mpsc::Sender;
|
||||||
|
|
||||||
// TODO: clean up all this tx/msg mess
|
// TODO: clean up all this tx/msg mess
|
||||||
|
|
||||||
/// Parse name list
|
|
||||||
pub fn load_names(path: &str) -> Result<Vec<String>> {
|
|
||||||
let f = File::open(path).with_context(|| format!("Invalid names path: \"{}\"", path))?;
|
|
||||||
let f = BufReader::new(f);
|
|
||||||
|
|
||||||
let mut buf = vec![];
|
|
||||||
|
|
||||||
for line in f.lines() {
|
|
||||||
buf.push(line?)
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(buf)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Handles users
|
/// Handles users
|
||||||
pub struct UserHandler {
|
pub struct UserHandler {
|
||||||
/// Pointer to global state
|
/// Pointer to global state
|
||||||
state: Arc<AppState>,
|
state: Arc<AppState>,
|
||||||
users_by_id: HashMap<String, Arc<RwLock<User>>>,
|
users_by_id: HashMap<String, Arc<RwLock<User>>>,
|
||||||
first_names: Vec<String>,
|
name_generator: NameGenerator,
|
||||||
last_names: Vec<String>,
|
|
||||||
reserved_names: HashSet<String>,
|
reserved_names: HashSet<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -66,9 +53,8 @@ impl UserHandler {
|
||||||
UserHandler {
|
UserHandler {
|
||||||
state,
|
state,
|
||||||
users_by_id: HashMap::<String, Arc<RwLock<User>>>::new(),
|
users_by_id: HashMap::<String, Arc<RwLock<User>>>::new(),
|
||||||
first_names: load_names("data/first.txt").unwrap(),
|
|
||||||
last_names: load_names("data/last.txt").unwrap(),
|
|
||||||
reserved_names: HashSet::<String>::new(),
|
reserved_names: HashSet::<String>::new(),
|
||||||
|
name_generator: NameGenerator::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -143,41 +129,26 @@ impl UserHandler {
|
||||||
|
|
||||||
/// Create, register, and hydrate new user
|
/// Create, register, and hydrate new user
|
||||||
async fn set_up_new_user(&mut self, dm_tx: Sender<Message>, addr: SocketAddr) {
|
async fn set_up_new_user(&mut self, dm_tx: Sender<Message>, addr: SocketAddr) {
|
||||||
// Roll for username and re-roll if taken
|
let name = self.name_generator.generate(&self.reserved_names);
|
||||||
let mut name;
|
|
||||||
|
|
||||||
loop {
|
|
||||||
name = format!(
|
|
||||||
"{} {}",
|
|
||||||
self.first_names.choose(&mut rand::thread_rng()).unwrap(),
|
|
||||||
self.last_names.choose(&mut rand::thread_rng()).unwrap(),
|
|
||||||
);
|
|
||||||
|
|
||||||
if !self.reserved_names.contains(&name) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let new_user = Arc::new(RwLock::new(User::new(name, dm_tx.clone())));
|
let new_user = Arc::new(RwLock::new(User::new(name, dm_tx.clone())));
|
||||||
|
|
||||||
// Notify client of new username
|
|
||||||
let tx = dm_tx.clone();
|
|
||||||
let msg = user_client_self_update(&new_user);
|
|
||||||
tokio::spawn(async move { tx.send(msg).await });
|
|
||||||
|
|
||||||
// Register uuid
|
// Register uuid
|
||||||
self.users_by_id
|
self.users_by_id
|
||||||
.insert(new_user.read().unwrap().uuid.clone(), new_user.clone());
|
.insert(new_user.read().unwrap().uuid.clone(), new_user.clone());
|
||||||
|
|
||||||
// Register online using `addr` as key until something longer lived exists
|
// Register online using `addr` as key until something longer lived exists
|
||||||
self.state
|
self.set_user_online(addr, new_user.clone());
|
||||||
.online_users
|
|
||||||
.write()
|
|
||||||
.unwrap()
|
|
||||||
.insert(addr, new_user.clone());
|
|
||||||
|
|
||||||
// Hydrate client
|
// Hydrate client
|
||||||
if !dm_tx.is_closed() {
|
if !dm_tx.is_closed() {
|
||||||
|
// Notify client of username
|
||||||
|
if let Err(e) = dm_tx.send(user_client_self_update(&new_user)).await {
|
||||||
|
tracing::error!("Error sending client update {}", e)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Send game update
|
||||||
|
// TODO: send single update instad of broadcasting to all users
|
||||||
if let Err(e) = self
|
if let Err(e) = self
|
||||||
.state
|
.state
|
||||||
.tx_game_handler
|
.tx_game_handler
|
||||||
|
@ -187,6 +158,7 @@ impl UserHandler {
|
||||||
tracing::error!("Error contacing game handler {}", e)
|
tracing::error!("Error contacing game handler {}", e)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Send card packs for new game form
|
||||||
if let Err(e) = self
|
if let Err(e) = self
|
||||||
.state
|
.state
|
||||||
.tx_game_handler
|
.tx_game_handler
|
||||||
|
@ -195,6 +167,8 @@ impl UserHandler {
|
||||||
{
|
{
|
||||||
tracing::error!("Error contacing game handler {}", e)
|
tracing::error!("Error contacing game handler {}", e)
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
self.user_cleanup(addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Broadcast new user's existence
|
// Broadcast new user's existence
|
||||||
|
@ -398,15 +372,7 @@ impl UserHandler {
|
||||||
});
|
});
|
||||||
|
|
||||||
// Move user to offline
|
// Move user to offline
|
||||||
self.state.offline_users.write().unwrap().insert(
|
self.set_user_offline(user_name, &addr);
|
||||||
user_name,
|
|
||||||
self.state
|
|
||||||
.online_users
|
|
||||||
.write()
|
|
||||||
.unwrap()
|
|
||||||
.remove(&addr)
|
|
||||||
.unwrap(),
|
|
||||||
);
|
|
||||||
|
|
||||||
self.broadcast_user_count();
|
self.broadcast_user_count();
|
||||||
|
|
||||||
|
@ -418,6 +384,24 @@ impl UserHandler {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Set user status to online
|
||||||
|
fn set_user_online(&self, addr: SocketAddr, user: Arc<RwLock<User>>) {
|
||||||
|
self.state.online_users.write().unwrap().insert(addr, user);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Set user status to offline
|
||||||
|
fn set_user_offline(&self, user_name: String, addr: &SocketAddr) {
|
||||||
|
self.state.offline_users.write().unwrap().insert(
|
||||||
|
user_name,
|
||||||
|
self.state
|
||||||
|
.online_users
|
||||||
|
.write()
|
||||||
|
.unwrap()
|
||||||
|
.remove(addr)
|
||||||
|
.unwrap(),
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Generate message to notify client of user changes
|
/// Generate message to notify client of user changes
|
||||||
|
|
Loading…
Add table
Reference in a new issue