diff --git a/src/cmds/generic/wwrps.rs b/src/cmds/generic/wwrps.rs index d72d2f2..48dd4de 100644 --- a/src/cmds/generic/wwrps.rs +++ b/src/cmds/generic/wwrps.rs @@ -1,83 +1,7 @@ -use std::fmt::Display; - -use poise::serenity_prelude::{ChannelId, Mentionable, User}; +use poise::serenity_prelude::{ChannelId, Mentionable}; use tokio::sync::MutexGuard; -use crate::{Context, Error, db::generic::get_json_mutex, lang, messages::{http_send_msg, send_msg}}; - - -#[derive(poise::ChoiceParameter, PartialEq, Clone, Debug)] -#[repr(u8)] -pub enum RPS { - Paper = 0, - Rock = 1, - Scissors = 2 -} - - -#[derive(Clone)] -pub struct RPSPlayer { - pub selection: RPS, - pub user: User, - pub wwrps_channel: ChannelId, - pub anonymous: bool -} -#[derive(Clone)] -pub struct RPSGame { - pub players: [Option; 2], -} - - -impl Display for RPS { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - return match self { - Self::Paper => write!(f, "Paper"), - Self::Rock => write!(f, "Rock"), - Self::Scissors => write!(f, "Scissors") - }; - } -} - - -impl RPSGame { - pub fn new() -> Self { - return RPSGame { - players: [None, None], - } - } - - /// Returns wether the lobby is filled or not - pub fn add_player(&mut self, player: RPSPlayer) -> Result { - if let Some(p1) = &self.players[0] - { if p1.user == player.user { return Err(Error::from("Cannot add player, it already exists!")); }} - - if self.players[0].is_none() { self.players[0] = Some(player); return Ok(false); } - else if self.players[1].is_none() { self.players[1] = Some(player); return Ok(true); } - else { return Err(Error::from("Cannot add player, list is full!")); } - } - - pub fn clear(&mut self) - { self.players = [None, None]; } - - - pub fn get_winner(&self) -> Option { - if self.players.iter().any(|i| i.is_none()) - { return None; } - - let Some(p1) = self.players[0].clone() else { return None; }; - let Some(p2) = self.players[1].clone() else { return None; }; - - let i1 = p1.selection as u8; - let i2 = p2.selection as u8; - - if i1 == i2 { return None; } - else if (i1 + 1) % 3 == i2 { return Some(0); } - else { return Some(1); } - } - - pub fn is_full_lobby(&self) -> bool - { return self.players.iter().all(|i| i.is_some()); } -} +use crate::{Context, Error, db::generic::get_json_mutex, games::wwrps::{RPS, RPSGame, RPSPlayer}, lang, messages::{http_send_msg, send_msg}}; #[poise::command( diff --git a/src/db.rs b/src/db.rs index 0936f4a..de3b182 100644 --- a/src/db.rs +++ b/src/db.rs @@ -1,4 +1,6 @@ +pub mod bot_data; pub mod cfg; +pub mod terminal_args; pub mod discord; pub mod generic; pub mod keys; diff --git a/src/db/bot_data.rs b/src/db/bot_data.rs new file mode 100644 index 0000000..6b36d0c --- /dev/null +++ b/src/db/bot_data.rs @@ -0,0 +1,18 @@ +use serde_json::Value; +use tokio::sync::Mutex; + +use crate::{db::terminal_args::Args, games::wwrps::RPSGame, lang::Lang}; + + +pub struct Data { + pub owners: Vec, + pub ball_prompts: [Vec; 2], + pub rps_game: Mutex, + pub reddit_data: Mutex>, + pub discord_data: Mutex>, + pub cfg: Mutex>, + pub bk_mods: Vec, + pub args: Args, + pub lang_name: Mutex, + pub lang: Mutex +} \ No newline at end of file diff --git a/src/db/terminal_args.rs b/src/db/terminal_args.rs new file mode 100644 index 0000000..a9a20de --- /dev/null +++ b/src/db/terminal_args.rs @@ -0,0 +1,30 @@ +use clap::Parser; +use serde::Serialize; + + +#[derive(Parser, Serialize, Clone)] +pub struct Args { + #[arg(short = 'p', long, default_value = "2920", help = "Sets the port number, e.g 2200.")] + pub port: u16, + + #[arg(long, help = "Runs only the Python part of the program.")] + pub py: bool, + + #[arg(long, help = "Runs only the Rust part of the program.")] + pub rs: bool, + + #[arg(short = 'd', long, help = "Enables dev mode. Dev mode shows more debug info and turns off certain security measures.")] + pub dev: bool, + + #[arg(short = 'w', long, help = "Wipes all data before running the program.")] + pub wipe: bool, + + #[arg(short = 't', long, help = "Makes the program use the ASSISTANT_TOKEN_TEST env var instead of ASSISTANT_TOKEN. This env var should hold the token of a non-production bot.")] + pub test: bool, + + #[arg(long, help = "Adds annoying prints when the websockets send a ping. Why though?")] + pub ping: bool, + + #[arg(long, help = "Makes the program not use the schedule system.")] + pub nosched: bool +} diff --git a/src/games.rs b/src/games.rs new file mode 100644 index 0000000..e95a30a --- /dev/null +++ b/src/games.rs @@ -0,0 +1 @@ +pub mod wwrps; \ No newline at end of file diff --git a/src/games/wwrps.rs b/src/games/wwrps.rs new file mode 100644 index 0000000..855620c --- /dev/null +++ b/src/games/wwrps.rs @@ -0,0 +1,79 @@ +use std::fmt::Display; + +use poise::serenity_prelude::{ChannelId, User}; + +use crate::Error; + + +#[derive(poise::ChoiceParameter, PartialEq, Clone, Debug)] +#[repr(u8)] +pub enum RPS { + Paper = 0, + Rock = 1, + Scissors = 2 +} + + +#[derive(Clone)] +pub struct RPSPlayer { + pub selection: RPS, + pub user: User, + pub wwrps_channel: ChannelId, + pub anonymous: bool +} +#[derive(Clone)] +pub struct RPSGame { + pub players: [Option; 2], +} + + +impl Display for RPS { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + return match self { + Self::Paper => write!(f, "Paper"), + Self::Rock => write!(f, "Rock"), + Self::Scissors => write!(f, "Scissors") + }; + } +} + + +impl RPSGame { + pub fn new() -> Self { + return RPSGame { + players: [None, None], + } + } + + /// Returns wether the lobby is filled or not + pub fn add_player(&mut self, player: RPSPlayer) -> Result { + if let Some(p1) = &self.players[0] + { if p1.user == player.user { return Err(Error::from("Cannot add player, it already exists!")); }} + + if self.players[0].is_none() { self.players[0] = Some(player); return Ok(false); } + else if self.players[1].is_none() { self.players[1] = Some(player); return Ok(true); } + else { return Err(Error::from("Cannot add player, list is full!")); } + } + + pub fn clear(&mut self) + { self.players = [None, None]; } + + + pub fn get_winner(&self) -> Option { + if self.players.iter().any(|i| i.is_none()) + { return None; } + + let Some(p1) = self.players[0].clone() else { return None; }; + let Some(p2) = self.players[1].clone() else { return None; }; + + let i1 = p1.selection as u8; + let i2 = p2.selection as u8; + + if i1 == i2 { return None; } + else if (i1 + 1) % 3 == i2 { return Some(0); } + else { return Some(1); } + } + + pub fn is_full_lobby(&self) -> bool + { return self.players.iter().all(|i| i.is_some()); } +} \ No newline at end of file diff --git a/src/gen.rs b/src/gen.rs index 3ca9b27..556ca5e 100644 --- a/src/gen.rs +++ b/src/gen.rs @@ -6,9 +6,9 @@ use poise::serenity_prelude::Client; use tokio::sync::Mutex; use toml::Value; -use crate::cmds::generic::wwrps::RPSGame; use crate::db::{cfg, discord, reddit}; use crate::db::generic::get_toml_mutex; +use crate::games::wwrps::RPSGame; use crate::lang::Lang; use crate::{Args, Cmd, Data, cmds, events, rs_println}; diff --git a/src/main.rs b/src/main.rs index d03f3a1..d6ed65f 100644 --- a/src/main.rs +++ b/src/main.rs @@ -11,73 +11,36 @@ mod macros; mod websocket; mod cmds; mod db; +mod games; mod schedule; mod gen; mod lang; + use std::process; use std::thread; use std::time::Duration; use std::vec; use std::error::Error as StdErr; -use clap::Parser; use r#gen::gen_bot; use r#gen::gen_data; use poise::Command; use schedule::run_schedules; -use serde::Serialize; -use serde_json::Value; use tokio::runtime::Runtime; -use tokio::sync::Mutex; use websocket::send_cmd_json; -use crate::cmds::generic::wwrps::RPSGame; +use crate::db::bot_data::Data; +use crate::db::terminal_args::Args; use crate::db::generic::get_toml_mutex; -use crate::lang::Lang; use crate::schedule::Schedule; -#[derive(Parser, Serialize, Clone)] -struct Args { - #[arg(short = 'p', long, default_value = "2920", help = "Sets the port number, e.g 2200.")] - port: u16, - #[arg(long, help = "Runs only the Python part of the program.")] - py: bool, - #[arg(long, help = "Runs only the Rust part of the program.")] - rs: bool, - #[arg(short = 'd', long, help = "Enables dev mode. Dev mode shows more debug info and turns off certain security measures.")] - dev: bool, - #[arg(short = 'w', long, help = "Wipes all data before running the program.")] - wipe: bool, - #[arg(short = 't', long, help = "Makes the program use the ASSISTANT_TOKEN_TEST env var instead of ASSISTANT_TOKEN. This env var should hold the token of a non-production bot.")] - test: bool, - #[arg(long, help = "Adds annoying prints when the websockets send a ping. Why though?")] - ping: bool, - #[arg(long, help = "Makes the program not use the schedule system.")] - nosched: bool -} - - type Error = Box; type Context<'a> = poise::Context<'a, Data, Error>; type Cmd = Command>; -struct Data { - owners: Vec, - ball_prompts: [Vec; 2], - rps_game: Mutex, - reddit_data: Mutex>, - discord_data: Mutex>, - cfg: Mutex>, - bk_mods: Vec, - args: Args, - lang_name: Mutex, - lang: Mutex -} - - #[tokio::main] async fn main() { let args = ::parse();