pikadick/commands/tic_tac_toe/
concede.rs1use crate::{
2 checks::ENABLED_CHECK,
3 database::model::TicTacToePlayer,
4 ClientDataKey,
5};
6use serenity::{
7 builder::{
8 CreateAttachment,
9 CreateMessage,
10 },
11 client::Context,
12 framework::standard::{
13 macros::command,
14 Args,
15 CommandResult,
16 },
17 model::prelude::*,
18};
19use tracing::error;
20
21#[command]
22#[description("Concede a game of Tic-Tac-Toe")]
23#[usage("")]
24#[example("")]
25#[min_args(0)]
26#[max_args(0)]
27#[checks(Enabled)]
28#[bucket("default")]
29pub async fn concede(ctx: &Context, msg: &Message, _args: Args) -> CommandResult {
30 let data_lock = ctx.data.read().await;
31 let client_data = data_lock
32 .get::<ClientDataKey>()
33 .expect("missing client data");
34 let tic_tac_toe_data = client_data.tic_tac_toe_data.clone();
35 let db = client_data.db.clone();
36 drop(data_lock);
37
38 let guild_id = msg.guild_id;
39 let author_id = msg.author.id;
40
41 let game = match db
42 .concede_tic_tac_toe_game(guild_id.into(), author_id)
43 .await
44 {
45 Ok(Some(game)) => game,
46 Ok(None) => {
47 let response = "Failed to concede as you have no games in this server".to_string();
48 msg.channel_id.say(&ctx.http, response).await?;
49 return Ok(());
50 }
51 Err(e) => {
52 error!("{:?}", e);
53 msg.channel_id.say(&ctx.http, "database error").await?;
54 return Ok(());
55 }
56 };
57
58 let opponent = game
59 .get_opponent(TicTacToePlayer::User(author_id))
60 .expect("author is not playing the game");
61
62 let file = match tic_tac_toe_data
63 .renderer
64 .render_board_async(game.board)
65 .await
66 {
67 Ok(file) => CreateAttachment::bytes(file, format!("ttt-{}.png", game.board.encode_u16())),
68 Err(error) => {
69 error!("failed to render Tic-Tac-Toe board: {error}");
70 msg.channel_id
71 .say(
72 &ctx.http,
73 format!("Failed to render Tic-Tac-Toe board: {error}"),
74 )
75 .await?;
76 return Ok(());
77 }
78 };
79
80 let content = format!(
81 "{} has conceded to {}.",
82 author_id.mention(),
83 opponent.mention()
84 );
85
86 let message_builder = CreateMessage::new().content(content).add_file(file);
87 msg.channel_id
88 .send_message(&ctx.http, message_builder)
89 .await?;
90
91 Ok(())
92}