wOxlf/src/game/global_data.rs

109 lines
2.9 KiB
Rust

use std::sync::Arc;
use serde::{Deserialize, Serialize};
use serenity::prelude::{Mutex, TypeMapKey};
use std::fs::File;
use std::io::{Read, Write};
use crate::config::BotConfig;
use crate::error::{Result, WoxlfError};
use crate::game::game_state::GameState;
use crate::game::Phase;
use chrono::Duration;
use serenity::utils::MessageBuilder;
#[derive(Debug, Deserialize, Serialize, Clone)]
pub struct GlobalData {
pub cfg: BotConfig,
pub game_state: Option<GameState>,
}
impl GlobalData {
pub fn new(cfg: BotConfig) -> Self {
Self {
cfg,
game_state: None,
}
}
pub fn start_game(&mut self, starting_phase: Phase, starting_phase_duration: Duration) {
self.game_state = Some(GameState::new(starting_phase, starting_phase_duration))
}
pub fn save_game_state(&mut self) -> Result<()> {
if let Some(game_state) = &mut self.game_state {
let s = toml::to_string_pretty(game_state)?;
let mut file = File::create(self.cfg.get_game_state_path())?;
file.write_all(s.as_bytes())?;
Ok(())
} else {
Err(WoxlfError::GameNotInProgress)
}
}
pub fn game_state_exists(&self) -> bool {
self.cfg.get_game_state_path().exists()
}
pub fn load_game_state(&mut self) -> Result<()> {
let mut file = File::open(self.cfg.get_game_state_path())?;
let mut data = String::new();
file.read_to_string(&mut data)?;
self.game_state = Some(toml::from_str(&data)?);
Ok(())
}
pub fn game_state_mut(&mut self) -> Result<&mut GameState> {
match &mut self.game_state {
None => Err(WoxlfError::GameNotInProgress),
Some(game_state) => Ok(game_state),
}
}
pub fn game_state(&self) -> Result<&GameState> {
match &self.game_state {
None => Err(WoxlfError::GameNotInProgress),
Some(game_state) => Ok(game_state),
}
}
pub fn clear_game_state(&mut self) -> Result<()> {
self.game_state = None;
if self.game_state_exists() {
std::fs::remove_file(self.cfg.get_game_state_path())?;
}
Ok(())
}
pub fn print_game_status(&self) -> String {
if let Some(game_state) = &self.game_state {
MessageBuilder::new()
.push_line(format!(
"CURRENT EXPERIMENT PHASE: {} {}",
game_state.current_phase, game_state.phase_number
))
.push_line(format!(
"PHASE END TIME: {}",
game_state.get_phase_end_time()
))
.push_line(format!("PHASE ENDING {}", game_state.get_phase_countdown()))
.build()
} else {
"Game not in progress.".to_string()
}
}
}
impl TypeMapKey for GlobalData {
type Value = Arc<Mutex<GlobalData>>;
}