Scroll/libserver/src/session/mod.rs
2025-04-01 02:42:53 +03:00

118 lines
3.7 KiB
Rust

use rand::RngCore;
use save::PlayerSaveData;
use crate::{
allocator,
logic::{
avatar::LogicClientAvatar,
data::{LogicDataTables, LogicNpcData},
math::LogicLong,
mode::LogicGameMode,
},
network::{message::PiranhaMessage, Messaging},
resources,
};
mod handlers;
mod protocol_util;
mod save;
pub struct PlayerSession {
messaging: Messaging,
pub account_id: Option<LogicLong>,
pub player_save_data: Option<PlayerSaveData>,
pub logic_game_mode: Option<&'static mut LogicGameMode>,
}
impl PlayerSession {
pub fn new(messaging: Messaging) -> Self {
Self {
messaging,
account_id: None,
player_save_data: None,
logic_game_mode: None,
}
}
pub fn send_message<T>(&self, message: *const T) {
self.messaging.send(message);
}
pub fn go_home(&mut self) {
self.destruct_game_mode();
let player_save_data = self.player_save_data.as_ref().unwrap();
let logic_client_home = player_save_data.get_logic_client_home();
let logic_client_avatar = player_save_data.get_logic_client_avatar();
let random_seed = rand::rng().next_u32() as i32;
let own_home_data_message =
protocol_util::build_own_home_data(logic_client_home, logic_client_avatar, random_seed);
let logic_game_mode = LogicGameMode::new(false);
logic_game_mode.load_home_state(logic_client_home, logic_client_avatar, 0, -1, random_seed);
self.logic_game_mode = Some(logic_game_mode);
self.send_message(own_home_data_message);
}
pub fn start_mission(&mut self, npc: &'static LogicNpcData) {
const TRAINING_ARENA_ID: i32 = 54000001;
self.destruct_game_mode();
resources::prepare_location_data(npc.location);
let arena = LogicDataTables::get_data_by_id(TRAINING_ARENA_ID).unwrap();
let player_save_data = self.player_save_data.as_ref().unwrap();
let player_avatar = player_save_data.get_logic_client_avatar();
let player_deck = player_save_data.get_spell_deck();
let npc_deck = player_deck.clone();
let npc_avatar = LogicClientAvatar::new();
npc_avatar.id.set(-1, -1);
npc_avatar.account_id.set(-1, -1);
npc_avatar.home_id.set(-1, -1);
npc_avatar.arena = arena;
npc_avatar.level = player_avatar.level;
let battle_mode = LogicGameMode::new(true);
let battle = battle_mode.battle.get_mut().unwrap();
battle.set_location(npc.location, false, 0);
battle.battle_type = 1;
battle.npc_data = npc;
battle.arena_data = arena;
battle.set_spell_decks(player_deck, npc_deck);
battle_mode.add_player(player_avatar);
battle_mode.add_player(npc_avatar);
let sector_state_message = protocol_util::build_sector_state(battle_mode, player_avatar);
self.logic_game_mode = Some(battle_mode);
self.send_message(sector_state_message);
}
pub fn destruct_game_mode(&mut self) {
if let Some(logic_game_mode) = self.logic_game_mode.take() {
logic_game_mode.destruct();
allocator::free(logic_game_mode);
}
}
pub fn work_until_disconnect(&mut self) {
while self.messaging.get_connection().is_connected {
self.messaging.on_receive(self.messaging.get_connection());
while let Some(message) = self.messaging.next_message() {
self.receive_message(message);
}
}
}
fn receive_message(&mut self, message: &PiranhaMessage) {
handlers::handle_message(self, message);
self.messaging.on_wakeup(self.messaging.get_connection());
}
}