152 lines
4.0 KiB
Rust
152 lines
4.0 KiB
Rust
use std::sync::Arc;
|
|
|
|
use serenity::prelude::{Mutex, TypeMapKey};
|
|
use std::fs::File;
|
|
use std::io::{Read, Write};
|
|
|
|
use crate::config::{BotConfig, GameConfig};
|
|
use crate::error::{Result, WoxlfError};
|
|
use crate::game::game_state::GameState;
|
|
use crate::game::Phase;
|
|
use crate::imgur::{get_album_images, Image};
|
|
use crate::messages::MessageTemplates;
|
|
use chrono::Duration;
|
|
|
|
#[derive(Debug, Clone)]
|
|
pub struct GlobalData {
|
|
pub cfg: BotConfig,
|
|
pub game_cfg: Option<GameConfig>,
|
|
pub templates: Option<MessageTemplates>,
|
|
pub game_state: Option<GameState>,
|
|
}
|
|
|
|
impl GlobalData {
|
|
pub fn new(cfg: BotConfig) -> Self {
|
|
Self {
|
|
cfg,
|
|
game_cfg: None,
|
|
templates: None,
|
|
game_state: None,
|
|
}
|
|
}
|
|
|
|
pub fn start_game(
|
|
&mut self,
|
|
game_name: &str,
|
|
starting_phase: Phase,
|
|
starting_phase_duration: Duration,
|
|
) -> Result<()> {
|
|
let game_config = self.cfg.get_game_config(game_name).unwrap();
|
|
|
|
self.templates = Some(MessageTemplates::try_from(game_config.messages.clone())?);
|
|
self.game_cfg = Some(game_config);
|
|
self.game_state = Some(GameState::new(
|
|
starting_phase,
|
|
starting_phase_duration,
|
|
game_name,
|
|
));
|
|
|
|
Ok(())
|
|
}
|
|
|
|
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)?);
|
|
|
|
let game_config = self
|
|
.cfg
|
|
.get_game_config(&self.game_state.as_ref().unwrap().game_name)
|
|
.unwrap();
|
|
|
|
self.templates = Some(MessageTemplates::try_from(game_config.messages.clone())?);
|
|
self.game_cfg = Some(game_config);
|
|
|
|
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 templates(&self) -> Result<&MessageTemplates> {
|
|
match &self.templates {
|
|
None => Err(WoxlfError::GameNotInProgress),
|
|
Some(templates) => Ok(templates),
|
|
}
|
|
}
|
|
|
|
pub fn game_cfg(&self) -> Result<&GameConfig> {
|
|
match &self.game_cfg {
|
|
None => Err(WoxlfError::GameNotInProgress),
|
|
Some(game_config) => Ok(game_config),
|
|
}
|
|
}
|
|
pub fn clear_game_state(&mut self) -> Result<()> {
|
|
self.game_state = None;
|
|
self.game_cfg = None;
|
|
self.templates = None;
|
|
|
|
if self.game_state_exists() {
|
|
std::fs::remove_file(self.cfg.get_game_state_path())?;
|
|
}
|
|
|
|
Ok(())
|
|
}
|
|
|
|
pub async fn get_profile_pic_album(&self) -> Result<Vec<Image>> {
|
|
Ok(get_album_images(
|
|
&self.cfg.imgur_client_id,
|
|
&self.game_cfg()?.profile_album_hash,
|
|
)
|
|
.await?)
|
|
}
|
|
|
|
pub fn get_phase_name(&self) -> Result<String> {
|
|
let game_cfg = self.game_cfg()?;
|
|
let state = self.game_state()?;
|
|
|
|
Ok(if state.current_phase == Phase::Day {
|
|
game_cfg.vote_phase_name.clone()
|
|
} else {
|
|
game_cfg.enemy_phase_name.clone()
|
|
})
|
|
}
|
|
}
|
|
|
|
impl TypeMapKey for GlobalData {
|
|
type Value = Arc<Mutex<GlobalData>>;
|
|
}
|