update deps, fix stuff and add some comments

This commit is contained in:
Rusty Striker 2025-06-14 19:53:23 +03:00
parent dbeda509fc
commit 3cfabcc39f
Signed by: RustyStriker
GPG key ID: 87E4D691632DFF15
5 changed files with 477 additions and 466 deletions

View file

@ -1,7 +1,11 @@
use std::collections::HashMap;
use api::game_actions::SpawnToken;
use game::{chat_message::ChatMessage, entry::{ActionDefinition, DiceRoll}, Game, GameImpl};
use game::{
Game, GameImpl,
chat_message::ChatMessage,
entry::{ActionDefinition, DiceRoll},
};
use serde::{Deserialize, Serialize};
use tokio::sync::{broadcast, mpsc};
@ -14,35 +18,39 @@ pub mod user;
pub struct GameServer {
game: Game<pathfinder2r_impl::Pathfinder2rCharacterSheet, pathfinder2r_impl::entry::Entry>,
chat: Vec<(String, ChatMessage)>,
#[serde(skip)] // we dont want to save the logged users as it will always be empty when the server restarts
// we dont want to save the logged users as it will always be empty when the server restarts
#[serde(skip)]
/// Logged in users, bool value used to know if the user is an admin or not
users: HashMap<String, bool>,
// TODO: JEESH REPLACE THIS WITH A DATABASE AND PROPER SECURITY ONCE ITS DONE PLEASE GOD
// TODO: JEESH REPLACE THIS WITH A DATABASE AND PROPER SECURITY ONCE ITS DONE PLEASE GOD
creds: HashMap<String, String>,
}
impl GameServer {
pub fn new() -> Self {
let mut creds = HashMap::new();
creds.insert("rusty".to_string(), String::new());
creds.insert("artist".to_string(), "artist".to_string());
creds.insert("dragonfly".to_string(), "cool".to_string());
creds.insert("rusty".to_string(), "rusty".to_string());
creds.insert("test".to_string(), "test".to_string());
creds.insert("dragonfly".to_string(), "dragonfly".to_string());
Self {
game: Game::new(),
chat: vec![
(
"Server".to_string(),
ChatMessage::new("a weapon description".to_string())
.id(1)
.character(Some("Sword or something".to_string()))
.with_action(
ActionDefinition::new("weapon/attack".to_string())
chat: vec![(
"Server".to_string(),
ChatMessage::new("a weapon description".to_string())
.id(1)
.character(Some("Sword or something".to_string()))
.with_action(
ActionDefinition::new("weapon/attack".to_string())
.display_name(Some("Attack +7".to_string()))
.with_roll(DiceRoll::new("Pierce".to_string(), 12, 1).constant(1))
.with_roll(DiceRoll::new("Fire".to_string(), 4, 2))
)
.with_action(ActionDefinition::new("Attack +3".to_string()).with_roll(DiceRoll::new("Base".to_string(), 20, 1)))
.with_action(ActionDefinition::new("Attack -1".to_string()))
)
],
.with_roll(DiceRoll::new("Fire".to_string(), 4, 2)),
)
.with_action(ActionDefinition::new("Attack +3".to_string()).with_roll(DiceRoll::new(
"Base".to_string(),
20,
1,
)))
.with_action(ActionDefinition::new("Attack -1".to_string())),
)],
users: HashMap::new(),
creds,
}
@ -63,20 +71,34 @@ impl GameServer {
api::Request::Error => {}
api::Request::Login(login) => {
println!("login req from {}: {:?}", &id, &login);
if !self.users.contains_key(&login.username) && self.creds.get(&login.username).map(|p| p == &login.password).unwrap_or(false) {
if !self.users.contains_key(&login.username) &&
self.creds
.get(&login.username)
.map(|p| p == &login.password)
.unwrap_or(false)
{
self.users.insert(login.username.clone(), login.username == "rusty"); // rusty will be admin for now :)
_ = broadcast.send((Some(id), api::Response::Login(api::login::LoginResult { success: true, username: login.username })));
}
else {
_ = broadcast.send((Some(id.clone()), api::Response::Login(api::login::LoginResult { success: false, username: login.username })));
_ = broadcast.send((
Some(id),
api::Response::Login(api::login::LoginResult {
success: true,
username: login.username,
}),
));
} else {
_ = broadcast.send((
Some(id.clone()),
api::Response::Login(api::login::LoginResult {
success: false,
username: login.username,
}),
));
}
}
api::Request::Message(mut msg) => {
if msg.id == 0 || msg.id > self.chat.len() {
msg.id = self.chat.len() + 1; // set the message id, 0 is invalid
}
// TODO: check if the editor is an admin as well
else if id == self.chat[msg.id - 1].0 {
} else if id == self.chat[msg.id - 1].0 || *self.users.get(&id).unwrap_or(&false) {
self.chat[msg.id - 1] = (id.clone(), msg.clone());
} else {
// if its an edit message and editor is not the owner, skip
@ -116,46 +138,65 @@ impl GameServer {
} else {
self.chat.len() - amount
};
let history: Vec<ChatMessage> =
self.chat.iter().skip(start).map(|m| m.1.clone()).collect();
let history: Vec<ChatMessage> = self.chat.iter().skip(start).map(|m| m.1.clone()).collect();
_ = broadcast.send((Some(id), api::Response::GetChatHistory(history)));
},
}
api::Request::GetTokens { scene } => {
for token_id in self.game.available_tokens(scene) {
if let Some(ti) = self.game.token_info(0, token_id) {
let bits = std::fs::read(&ti.img_source).expect("FAILED READING TOKEN IMAGE");
let img = base64::Engine::encode(&base64::prelude::BASE64_STANDARD, &bits);
_ = broadcast.send((Some(id.clone()), api::Response::SpawnToken(SpawnToken { token_id: token_id, x: ti.x, y: ti.y, img })));
_ = broadcast.send((
Some(id.clone()),
api::Response::SpawnToken(SpawnToken {
token_id: token_id,
x: ti.x,
y: ti.y,
img,
}),
));
}
}
},
api::Request::SpawnToken { map_id, character, x, y, img_path } => {
}
api::Request::SpawnToken {
map_id,
character,
x,
y,
img_path,
} => {
let token_id = self.game.create_token(map_id, character, img_path.clone(), x, y);
let bits = std::fs::read(&img_path).expect("FAILED READING TOKEN IMAGE");
let img = base64::Engine::encode(&base64::prelude::BASE64_STANDARD, &bits);
_ = broadcast.send((Some(id.clone()), api::Response::SpawnToken(SpawnToken { token_id, x, y, img })));
},
_ = broadcast.send((
Some(id.clone()),
api::Response::SpawnToken(SpawnToken { token_id, x, y, img }),
));
}
api::Request::MoveToken { token_id, x, y } => {
// TODO: add check to make sure the actor is authorized to move the token
if self.game.move_token(0, token_id, x, y) {
// TODO: maybe chage move_token to return optional x,y values if succeeded to make sure the token is where it was going to be
_ = broadcast.send((None, api::Response::MoveToken { token_id, x, y }));
}
},
}
api::Request::ActionResult(result) => {
let msg = ChatMessage::new(
result.results.iter()
result
.results
.iter()
// .map(|d| &d.result_text)
.fold(String::new(), |a,b| a + &format!("{}: {} = {}\n", &b.name, &b.result_text, b.result))
)
.character(Some(result.name))
.source(id.clone())
.targets(Some(result.targets))
.id(self.chat.len() + 1);
.fold(String::new(), |a, b| {
a + &format!("{}: {} = {}\n", &b.name, &b.result_text, b.result)
}),
)
.character(Some(result.name))
.source(id.clone())
.targets(Some(result.targets))
.id(self.chat.len() + 1);
self.chat.push((id, msg.clone()));
_ = broadcast.send((None, api::Response::Message(msg)));
},
}
api::Request::CreateCharacter => {
// check if user is admin
if self.users.get(&id).map(|a| *a).unwrap_or(false) {
@ -163,13 +204,13 @@ impl GameServer {
// return the new id with the character i think
_ = broadcast.send((Some(id), api::Response::CharacterCreated(new_id)));
}
},
}
api::Request::Quit => {
if self.users.contains_key(&id) {
self.users.remove(&id);
}
_ = broadcast.send((None, api::Response::Quit { id }));
},
}
api::Request::Kick(id) => {
if self.users.contains_key(&id) {
self.users.remove(&id);