From 486a204f1d0018fdf15af3287d7fa1735a13b4a6 Mon Sep 17 00:00:00 2001 From: ByteDice Date: Fri, 27 Feb 2026 18:11:15 +0100 Subject: [PATCH] the basis for wwrps is done (may add ranks) --- data/defaults/cfg_default.toml | 6 +-- data/lang/en.json | 8 ++++ src/cmds/wwrps.rs | 68 +++++++++++++++++++++++++++++----- src/gen.rs | 4 +- src/main.rs | 2 +- 5 files changed, 73 insertions(+), 15 deletions(-) diff --git a/data/defaults/cfg_default.toml b/data/defaults/cfg_default.toml index ec5ee70..1b6dd08 100644 --- a/data/defaults/cfg_default.toml +++ b/data/defaults/cfg_default.toml @@ -34,9 +34,9 @@ add_post = ["weekly_art", "weekly"] # Disabled selected command categories. All commands and their categories can be viewed in the README. disabled_categories = [ # "fun", - # "help" - # "re" - # "debug" + # "help", + # "re", + # "debug", # "db" ] diff --git a/data/lang/en.json b/data/lang/en.json index 8f5bad2..cd384e4 100644 --- a/data/lang/en.json +++ b/data/lang/en.json @@ -58,6 +58,14 @@ "dc_msg_update_removing_old": "{0}Removing old posts (threshold: {1}d)...", "dc_msg_update_removing": "{0}Removing removed posts...", "dc_msg_whoami": "**Bot \"owner\":** {0}\n**BK moderator:** {1}", + "dc_msg_wwrps_already_submitted": "You can't compete against yourself! Please wait until another player has submitted their RPS.", + "dc_msg_wwrps_anon": "[Anonymous]", + "dc_msg_wwrps_draw": "DRAW", + "dc_msg_wwrps_fight": "### {0} (P1) vs {1} (P2)...\n## {2}\n**P1:** {3}\n**P2:** {4}", + "dc_msg_wwrps_not_in_data": "Could not find `wwrps_channel` in data!\nHint: Run `/database WWRPSChannel` in a channel (requires administrator permission).", + "dc_msg_wwrps_p1_win": "P1 WINS", + "dc_msg_wwrps_p2_win": "P2 WINS", + "dc_msg_wwrps_submitting": "Submitting your RPS... Please wait for another contestant to compete against you.", "log_lang_load_success": "Successfully loaded the english language file!", "none": "None", "py_re_response_suffix": "^(I am not an AI, I am just a bot. This action was performed automatically by the way. You can report bugs and view my source code [here](https://github.com/ByteDice/ByteDiceAssistant)!)", diff --git a/src/cmds/wwrps.rs b/src/cmds/wwrps.rs index cae1282..2a41707 100644 --- a/src/cmds/wwrps.rs +++ b/src/cmds/wwrps.rs @@ -1,9 +1,12 @@ -use poise::serenity_prelude::User; +use std::fmt::Display; -use crate::{Context, Error, data::get_mutex_data, lang, messages::send_msg}; +use poise::serenity_prelude::{ChannelId, Mentionable, User}; +use tokio::sync::MutexGuard; + +use crate::{Context, Error, data::get_mutex_data, lang, messages::{http_send_msg, send_msg}}; -#[derive(poise::ChoiceParameter, PartialEq, Clone)] +#[derive(poise::ChoiceParameter, PartialEq, Clone, Debug)] #[repr(u8)] pub enum RPS { Paper = 0, @@ -23,6 +26,17 @@ pub struct RPSGame { } +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 { @@ -30,12 +44,13 @@ impl RPSGame { } } - pub fn add_player(&mut self, player: RPSPlayer) -> Result<(), Error> { + /// 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(()); } - else if self.players[1].is_none() { self.players[1] = Some(player); return Ok(()); } + 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!")); } } @@ -81,15 +96,48 @@ pub async fn cmd( if c_o.is_none() { send_msg(ctx, lang!("dc_msg_wwrps_not_in_data"), true, true).await; return Ok(()); } let c = c_o.unwrap(); + + send_msg(ctx, lang!("dc_msg_wwrps_submitting"), true, true).await; + + let mut game = ctx.data().rps_game.lock().await; - let mut game = &ctx.data().rps_game; - - if !game.is_full_lobby() { game.add_player(RPSPlayer { selection, user: ctx.author().clone(), anonymous }); } + if !game.is_full_lobby() { + let r = game.add_player( + RPSPlayer { selection, user: ctx.author().clone(), anonymous }); + + if let Err(_) = r + { send_msg(ctx, lang!("dc_msg_wwrps_already_submitted"), true, true).await; return Ok(()); } + + let full = r.unwrap(); + if !full { return Ok(()); } + + let r_text = results_text(&game); + game.clear(); + + http_send_msg(ctx.http(), ChannelId::new(c), r_text).await; + } return Ok(()); } +fn results_text(game: &MutexGuard<'_, RPSGame>) -> String { + let winner = game.get_winner(); + let winner_text: String; + + if let Some(w) = winner + { winner_text = if w == 0 { lang!("dc_msg_wwrps_p1_win") } else { lang!("dc_msg_wwrps_p2_win") }; } + else { winner_text = lang!("dc_msg_wwrps_draw"); } + + let p1 = game.players[0].as_ref().unwrap(); + let p2 = game.players[1].as_ref().unwrap(); + let p1_n = if !p1.anonymous { p1.user.mention().to_string() } else { lang!("dc_msg_wwrps_anon") }; + let p2_n = if !p2.anonymous { p2.user.mention().to_string() } else { lang!("dc_msg_wwrps_anon") }; + + return lang!("dc_msg_wwrps_fight", p1.selection.clone(), p2.selection.clone(), winner_text, p1_n, p2_n); +} + + async fn get_wwrps_channel(ctx: Context<'_>) -> Option { let d = get_mutex_data(&ctx.data().discord_data).await.unwrap(); @@ -98,7 +146,7 @@ async fn get_wwrps_channel(ctx: Context<'_>) -> Option { if !is_guild { return Some(ctx.channel_id().get()); } let Some(servers) = d.get("servers") else { return None; }; - let Some(s) = servers.get(ctx.guild_id().unwrap().get() as usize) else { return None; }; + let Some(s) = servers.get(ctx.guild_id().unwrap().get().to_string()) else { return None; }; let Some(c_id) = s.get("wwrps_channel") else { return None; }; return Some(c_id.as_u64().unwrap()); diff --git a/src/gen.rs b/src/gen.rs index 311c45a..de34e51 100644 --- a/src/gen.rs +++ b/src/gen.rs @@ -3,6 +3,7 @@ use std::{collections::HashSet, process}; use poise::serenity_prelude::{ActivityData, UserId}; use poise::serenity_prelude as serenity; use poise::serenity_prelude::Client; +use tokio::sync::Mutex; use toml::Value; use crate::cmds::wwrps::RPSGame; @@ -27,7 +28,7 @@ pub async fn gen_data(args: Args, owners: Vec) -> Data { let data = Data { owners, ball_prompts: [ball_classic, ball_quirk], - rps_game: RPSGame::new(), + rps_game: Mutex::new(RPSGame::new()), bk_mods: mods_vec_u64, reddit_data: None.into(), discord_data: None.into(), @@ -88,6 +89,7 @@ async fn make_cmd_vec(data: &Data) -> Vec { // GENERIC cmds::help::cmd(), cmds::eight_ball::cmd(), + cmds::wwrps::cmd(), // REDDIT re_cmds::add::cmd(), re_cmds::approve::cmd(), diff --git a/src/main.rs b/src/main.rs index b409755..5512535 100644 --- a/src/main.rs +++ b/src/main.rs @@ -97,7 +97,7 @@ type Cmd = Command>; struct Data { owners: Vec, ball_prompts: [Vec; 2], - rps_game: RPSGame, + rps_game: Mutex, reddit_data: Mutex>, discord_data: Mutex>, cfg: Mutex>,