dzura/server/src/app/mod.rs
2024-08-19 12:53:39 -07:00

202 lines
6.6 KiB
Rust

#![allow(dead_code)]
use sparse::Sparse;
use pool::Pool;
use trie::Trie;
use crate::{
system::filesystem::FileSystem,
util::Chain,
protocol::QRPacket,
};
pub mod connection; use connection::Connection;
pub mod user; use user::User;
pub mod authentication; use authentication::Authentication;
pub mod session; use session::{Session, SessionToken};
pub mod context;
pub struct App {
pub filesystem:FileSystem,
pub connections:Pool<Connection>,
pub users:Pool<User>,
pub user_id:Sparse<usize>,
pub user_handle:Trie<u32>,
pub salts:Sparse<[u8; 16]>,
pub auths:Trie<Authentication>,
pub sessions:Trie<Session>,
pub session_time:Chain<SessionToken>,
}
impl App {
pub fn init() -> Result<Self, ()>
{
if let Ok(mut filesystem) = FileSystem::init() {
// Load salts
println!("Loading salts..");
let mut salts = Sparse::new();
let salt_count = filesystem.salt_count()?;
for id in 0..salt_count {
let salt = filesystem.salt_fetch(id as u32).unwrap();
salts.set(id as isize, salt);
}
// Load handles
println!("Loading handles..");
let mut user_handle = Trie::new();
let handle_count = filesystem.handle_count()?;
for id in 0..handle_count {
let (handle, user_id) = filesystem.handle_fetch(id as u32).unwrap();
user_handle.set(handle.as_bytes(), user_id);
}
// Load users
println!("Loading users..");
let mut users = Pool::new();
let mut user_id = Sparse::new();
let user_count = filesystem.user_count()?;
for id in 0..user_count {
let user = filesystem.user_fetch(id as u32).unwrap();
let user_local_id = users.add(user);
user_id.set(user_local_id as isize, id);
}
// Load sessions
println!("Loading sessions..");
let mut sessions = Trie::new();
let mut times = Vec::<(u64, SessionToken)>::new();
let session_count = filesystem.session_count()?;
for id in 0..session_count {
let mut session = filesystem.session_fetch(id as u32).unwrap();
times.push((session.time, session.token.clone()));
// Load session history
if let Ok(history) = filesystem.session_history_fetch(id as u32) {
session.game.apply_history(&history).ok();
}
sessions.set(&session.token.clone(), session);
}
// Organize sessions by most recent
let mut session_time = Chain::new();
times.sort_by(|(a, _), (b, _)| {
if a > b { std::cmp::Ordering::Greater } else { std::cmp::Ordering::Less }
});
for (_, token) in times {
let id = session_time.add(token);
sessions.get_mut(&token).unwrap().chain_id = id;
}
println!("App data ready.");
Ok(Self {
filesystem:filesystem,
connections:Pool::new(),
users,
user_id,
user_handle,
salts,
auths:Trie::new(),
sessions,
session_time,
})
} else {
Err(())
}
}
pub fn get_user_by_id(&self, id:u32) -> Option<&User>
{
if let Some(uid) = self.user_id.get(id as isize) {
self.users.get(*uid)
} else { None }
}
pub async fn send_response(&mut self, response:QRPacket)
{
use crate::protocol::*;
use tokio_tungstenite::tungstenite::Message;
use futures::SinkExt;
fn encode_response(code:u16, data:Vec<u8>) -> Vec<u8>
{
[
crate::util::pack::pack_u16(code),
data,
].concat()
}
if match response.data { QRPacketData::None => false, _ => true } {
if let Some(conn) = self.connections.get_mut(response.id as usize) {
let mut socket = conn.stream.write().await;
match response.data {
QRPacketData::RRegister(response) => {
socket.send(Message::Binary(
encode_response(CODE_REGISTER, response.encode())
)).await.ok();
}
QRPacketData::RAuth(response) => {
socket.send(Message::Binary(
encode_response(CODE_AUTH, response.encode())
)).await.ok();
}
QRPacketData::RAuthResume(response) => {
socket.send(Message::Binary(
encode_response(CODE_AUTH_RESUME, response.encode())
)).await.ok();
}
QRPacketData::RSessionList(response) => {
socket.send(Message::Binary(
encode_response(CODE_SESSION_LIST, response.encode())
)).await.ok();
}
QRPacketData::RSessionCreate(response) => {
socket.send(Message::Binary(
encode_response(CODE_SESSION_CREATE, response.encode())
)).await.ok();
}
QRPacketData::RSessionJoin(response) => {
socket.send(Message::Binary(
encode_response(CODE_SESSION_JOIN, response.encode())
)).await.ok();
}
QRPacketData::RGameState(response) => {
socket.send(Message::Binary(
encode_response(CODE_GAME_STATE, response.encode())
)).await.ok();
}
QRPacketData::QGamePlay(response) => {
socket.send(Message::Binary(
encode_response(CODE_GAME_PLAY, response.encode())
)).await.ok();
}
QRPacketData::RGameHistory(response) => {
socket.send(Message::Binary(
encode_response(CODE_GAME_HISTORY, response.encode())
)).await.ok();
}
_ => { }
}
}
}
}
}