202 lines
6.6 KiB
Rust
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();
|
|
}
|
|
|
|
_ => { }
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|