Skip to content

Commit

Permalink
Merge pull request #101 from approvers/uo
Browse files Browse the repository at this point in the history
feat: uo
  • Loading branch information
kawaemon authored Nov 20, 2024
2 parents 80484fe + 2289dce commit 88f227f
Show file tree
Hide file tree
Showing 7 changed files with 149 additions and 11 deletions.
4 changes: 4 additions & 0 deletions src/bot/gh/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -319,7 +319,11 @@ mod test {
let output = output.into();

struct Msg(&'static str);
#[async_trait]
impl Message for Msg {
async fn reply(&self, _msg: &str) -> Result<()> {
unimplemented!()
}
fn author(&self) -> &dyn User {
unimplemented!()
}
Expand Down
5 changes: 3 additions & 2 deletions src/bot/meigen/mod.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
use {
crate::bot::{parse_command, ui, BotService, Context, IsUpdated, Message},
crate::bot::{
parse_command, ui, BotService, Context, IsUpdated, Message, KAWAEMON_DISCORD_USER_ID,
},
anyhow::{Context as _, Result},
async_trait::async_trait,
model::{Meigen, MeigenId},
Expand Down Expand Up @@ -220,7 +222,6 @@ impl<D: MeigenDatabase> MeigenBot<D> {
}

async fn delete(&self, caller: u64, id: MeigenId) -> Result<String> {
const KAWAEMON_DISCORD_USER_ID: u64 = 391857452360007680;
if caller != KAWAEMON_DISCORD_USER_ID {
return Ok("名言削除はかわえもんにしか出来ません".into());
}
Expand Down
5 changes: 5 additions & 0 deletions src/bot/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ use {
std::{future::Future, pin::Pin},
};

const KAWAEMON_DISCORD_USER_ID: u64 = 391857452360007680;

/// 変更が生じた場合 true
pub type IsUpdated = bool;

Expand All @@ -12,9 +14,12 @@ pub mod auth;
pub mod genkai_point;
pub mod gh;
pub mod meigen;
pub mod uo;
pub mod vc_diff;

#[async_trait]
pub(crate) trait Message: Send + Sync {
async fn reply(&self, msg: &str) -> Result<()>;
fn author(&self) -> &dyn User;
fn content(&self) -> &str;
fn attachments(&self) -> &[&dyn Attachment];
Expand Down
86 changes: 86 additions & 0 deletions src/bot/uo/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
use crate::bot::{parse_command, ui, BotService, Context, Message, KAWAEMON_DISCORD_USER_ID};
use anyhow::{Context as _, Result};
use async_trait::async_trait;
use tokio::sync::Mutex;

const NAME: &str = "rusty_ponyo::bot::uo";
const PREFIX: &str = "g!uo";
const UO: &str = "ウーォ";

ui! {
/// ランダムでウーォと言います
struct Ui {
name: NAME,
prefix: PREFIX,
command: Command,
}
}

#[derive(Debug, clap::Subcommand)]
enum Command {
Status,
Reroll,
}

pub(crate) struct UoBot {
prob_percent: Mutex<u8>,
}

impl UoBot {
pub fn new() -> Self {
Self {
prob_percent: Mutex::new(3),
}
}

async fn reroll(&self) {
*self.prob_percent.lock().await = 1 + (rand::random::<u8>() % 10);
}
}

#[async_trait]
impl BotService for UoBot {
fn name(&self) -> &'static str {
NAME
}

async fn on_message(&self, msg: &dyn Message, ctx: &dyn Context) -> Result<()> {
{
let p = *self.prob_percent.lock().await;
if rand::random::<f64>() < (p as f64 / 100.0) {
msg.reply(UO).await?;
}
}

if !msg.content().starts_with(PREFIX) {
return Ok(());
}

let Some(parsed) = parse_command::<Ui>(msg.content(), ctx).await? else {
return Ok(());
};

use Command::*;

let msg = match parsed.command {
Status => {
let prob = self.prob_percent.lock().await;
format!("```{UO}確率: {prob}%```")
}
Reroll => {
if msg.author().id() == KAWAEMON_DISCORD_USER_ID {
self.reroll().await;
"振り直しました".to_owned()
} else {
"かわえもんでないとこの処理はできません".to_owned()
}
}
};

ctx.send_text_message(&msg)
.await
.context("failed to send message")?;

Ok(())
}
}
15 changes: 15 additions & 0 deletions src/client/console.rs
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,8 @@ impl<'a> ConsoleClient<'a> {
};

let message = ConsoleMessage {
service_name: service.name(),
begin,
content: content.clone(),
attachments: attachments.clone(),
user: ConsoleUser {
Expand All @@ -105,12 +107,25 @@ impl<'a> ConsoleClient<'a> {
}

struct ConsoleMessage<'a> {
service_name: &'a str,
begin: Instant,
content: String,
attachments: Vec<&'a dyn Attachment>,
user: ConsoleUser<'a>,
}

#[async_trait]
impl Message for ConsoleMessage<'_> {
async fn reply(&self, content: &str) -> Result<()> {
println!(
"({}, reply, {}ms): {}",
self.service_name,
self.begin.elapsed().as_millis(),
content
);
Ok(())
}

fn content(&self) -> &str {
&self.content
}
Expand Down
23 changes: 17 additions & 6 deletions src/client/discord.rs
Original file line number Diff line number Diff line change
Expand Up @@ -332,11 +332,12 @@ impl EventHandler for EvHandler {
.insert(message.author.id, message.author.name.clone());

let converted_message = DiscordMessage {
content: message.content.clone(),
ctx: &ctx,
message: &message,
attachments: converted_attachments.iter().map(|x| x as _).collect(),
author: DiscordAuthor {
id: message.author.id.get(),
name: message.author.name,
name: &message.author.name,
ctx: &ctx,
},
};
Expand All @@ -360,14 +361,24 @@ struct NicknameCache(HashMap<SerenityUserId, String>);
struct IsBotCache(HashMap<SerenityUserId, bool>);

struct DiscordMessage<'a> {
content: String,
ctx: &'a SerenityContext,
message: &'a SerenityMessage,
attachments: Vec<&'a dyn Attachment>,
author: DiscordAuthor<'a>,
}

#[async_trait]
impl Message for DiscordMessage<'_> {
async fn reply(&self, text: &str) -> Result<()> {
self.message
.reply_ping(&self.ctx.http, text)
.await
.context("failed to reply with discord feature")?;
Ok(())
}

fn content(&self) -> &str {
&self.content
&self.message.content
}

fn attachments(&self) -> &[&dyn Attachment] {
Expand All @@ -382,7 +393,7 @@ impl Message for DiscordMessage<'_> {
struct DiscordAuthor<'a> {
id: u64,
#[allow(unused)]
name: String,
name: &'a str,
ctx: &'a SerenityContext,
}

Expand All @@ -393,7 +404,7 @@ impl<'a> User for DiscordAuthor<'a> {
}

fn name(&self) -> &str {
&self.name
self.name
}

async fn dm(&self, msg: SendMessage<'_>) -> Result<()> {
Expand Down
22 changes: 19 additions & 3 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ use {
vc_diff::VcDiffBot,
},
anyhow::{Context as _, Result},
bot::meigen::MeigenBot,
bot::{meigen::MeigenBot, uo::UoBot},
};

assert_one_feature!("discord_client", "console_client");
Expand Down Expand Up @@ -68,9 +68,25 @@ async fn async_main() -> Result<()> {
.add_service(VcDiffBot::new());

#[cfg(feature = "console_client")]
client.run().await?;
{
client.add_service(UoBot::new());
client.run().await?;
}
#[cfg(feature = "discord_client")]
client.run(&env_var("DISCORD_TOKEN")?).await?;
{
let token = env_var("DISCORD_TOKEN")?;
let base = tokio::spawn(async move { client.run(&token).await });

let token = env_var("DISCORD_UO_TOKEN")?;
let mut uo_client = crate::client::discord::DiscordClient::new();
uo_client.add_service(UoBot::new());
let uo = tokio::spawn(async move { uo_client.run(&token).await });

tokio::select! {
r = base => r??,
r = uo => r??,
}
}

Ok(())
}
Expand Down

0 comments on commit 88f227f

Please sign in to comment.