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::GameHandlerMessage::*;
|
||||
use crate::SendUserMessage::*;
|
||||
use crate::Sender;
|
||||
use crate::UserHandlerMessage::*;
|
||||
use axum::extract::ws::Message;
|
||||
use lib::*;
|
||||
use serde_json::to_string;
|
||||
use std::{collections::HashMap, net::SocketAddr, sync::Arc};
|
||||
use tokio::sync::mpsc::Sender;
|
||||
|
||||
/// For interacting with the game handler
|
||||
pub enum GameHandlerMessage {
|
||||
|
|
|
@ -5,8 +5,7 @@ use crate::UserHandlerMessage::*;
|
|||
use axum::extract::ws::{CloseFrame, Message};
|
||||
use lib::*;
|
||||
use serde_json::{from_str, to_string};
|
||||
use std::net::SocketAddr;
|
||||
use std::sync::Arc;
|
||||
use std::{net::SocketAddr, sync::Arc};
|
||||
|
||||
/// Handles incoming messages
|
||||
pub struct IncomingMessageHandler {
|
||||
|
|
|
@ -1,11 +1,9 @@
|
|||
#![feature(if_let_guard)]
|
||||
|
||||
use crate::game_handler::*;
|
||||
use anyhow::{Context, Result};
|
||||
use axum::extract::ws::Message;
|
||||
use lib::*;
|
||||
use std::{
|
||||
collections::{HashMap, HashSet},
|
||||
collections::HashMap,
|
||||
net::SocketAddr,
|
||||
sync::{Arc, RwLock},
|
||||
};
|
||||
|
@ -17,6 +15,7 @@ pub mod card_loader;
|
|||
pub mod game;
|
||||
pub mod game_handler;
|
||||
pub mod incoming_message_handler;
|
||||
pub mod name_generator;
|
||||
pub mod user_handler;
|
||||
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::DmUserMethod::*;
|
||||
use crate::GameHandlerMessage;
|
||||
use crate::SendUserMessage::*;
|
||||
use crate::User;
|
||||
use crate::UserHandlerMessage::*;
|
||||
use crate::*;
|
||||
use rand::prelude::SliceRandom;
|
||||
use axum::extract::ws::Message;
|
||||
use lib::*;
|
||||
use serde_json::to_string;
|
||||
use std::{
|
||||
fs::File,
|
||||
io::{BufRead, BufReader},
|
||||
collections::{HashMap, HashSet},
|
||||
net::SocketAddr,
|
||||
sync::{Arc, RwLock},
|
||||
};
|
||||
use tokio::sync::mpsc::Sender;
|
||||
|
||||
// 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
|
||||
pub struct UserHandler {
|
||||
/// Pointer to global state
|
||||
state: Arc<AppState>,
|
||||
users_by_id: HashMap<String, Arc<RwLock<User>>>,
|
||||
first_names: Vec<String>,
|
||||
last_names: Vec<String>,
|
||||
name_generator: NameGenerator,
|
||||
reserved_names: HashSet<String>,
|
||||
}
|
||||
|
||||
|
@ -66,9 +53,8 @@ impl UserHandler {
|
|||
UserHandler {
|
||||
state,
|
||||
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(),
|
||||
name_generator: NameGenerator::new(),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -143,41 +129,26 @@ impl UserHandler {
|
|||
|
||||
/// Create, register, and hydrate new user
|
||||
async fn set_up_new_user(&mut self, dm_tx: Sender<Message>, addr: SocketAddr) {
|
||||
// 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 !self.reserved_names.contains(&name) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
let name = self.name_generator.generate(&self.reserved_names);
|
||||
|
||||
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
|
||||
self.users_by_id
|
||||
.insert(new_user.read().unwrap().uuid.clone(), new_user.clone());
|
||||
|
||||
// Register online using `addr` as key until something longer lived exists
|
||||
self.state
|
||||
.online_users
|
||||
.write()
|
||||
.unwrap()
|
||||
.insert(addr, new_user.clone());
|
||||
self.set_user_online(addr, new_user.clone());
|
||||
|
||||
// Hydrate client
|
||||
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
|
||||
.state
|
||||
.tx_game_handler
|
||||
|
@ -187,6 +158,7 @@ impl UserHandler {
|
|||
tracing::error!("Error contacing game handler {}", e)
|
||||
}
|
||||
|
||||
// Send card packs for new game form
|
||||
if let Err(e) = self
|
||||
.state
|
||||
.tx_game_handler
|
||||
|
@ -195,6 +167,8 @@ impl UserHandler {
|
|||
{
|
||||
tracing::error!("Error contacing game handler {}", e)
|
||||
}
|
||||
} else {
|
||||
self.user_cleanup(addr);
|
||||
}
|
||||
|
||||
// Broadcast new user's existence
|
||||
|
@ -398,15 +372,7 @@ impl UserHandler {
|
|||
});
|
||||
|
||||
// Move user to offline
|
||||
self.state.offline_users.write().unwrap().insert(
|
||||
user_name,
|
||||
self.state
|
||||
.online_users
|
||||
.write()
|
||||
.unwrap()
|
||||
.remove(&addr)
|
||||
.unwrap(),
|
||||
);
|
||||
self.set_user_offline(user_name, &addr);
|
||||
|
||||
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
|
||||
|
|
Loading…
Add table
Reference in a new issue