smol bot
update serenity
bendn 2024-01-03
parent fa4522e · commit 099ff4b
-rw-r--r--Cargo.toml9
-rw-r--r--src/bot/logic.rs29
-rw-r--r--src/bot/map.rs5
-rw-r--r--src/bot/mod.rs99
-rw-r--r--src/bot/schematic.rs43
5 files changed, 94 insertions, 91 deletions
diff --git a/Cargo.toml b/Cargo.toml
index 3089b2d..a28b874 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -12,15 +12,13 @@ tokio = { version = "1.28.2", features = [
"parking_lot",
], default-features = false }
clipline = "0.1.2"
-serenity = { version = "0.11.5", features = [
+serenity = { version = "0.12", features = [
"builder",
"client",
"rustls_backend",
"gateway",
], default-features = false }
-poise = { version = "0.5.5", default-features = false, features = [
- "handle_panics",
-] }
+poise = { git = "https://github.com/serenity-rs/poise" }
anyhow = "1.0.75"
regex = { version = "1.8.4", features = ["std"], default-features = false }
btparse = "0.1.1"
@@ -46,3 +44,6 @@ debug-assertions = false
[profile.dev.package.fimg]
opt-level = 3
debug-assertions = false
+
+[patch.crates-io]
+serenity = { git = "https://github.com/bend-n/serenity", branch = "opt" }
diff --git a/src/bot/logic.rs b/src/bot/logic.rs
index 3175e7e..10d5034 100644
--- a/src/bot/logic.rs
+++ b/src/bot/logic.rs
@@ -1,7 +1,6 @@
use super::{Context, Result};
use lemu::Executor;
-use poise::{serenity_prelude::AttachmentType, CodeBlock, KeyValueArgs};
-use std::borrow::Cow;
+use poise::{serenity_prelude::*, CodeBlock, KeyValueArgs};
#[poise::command(prefix_command, track_edits, rename = "eval")]
pub async fn run(
@@ -33,10 +32,11 @@ pub async fn run(
{
Ok(o) => o,
Err(e) => {
- ctx.send(|c| {
- c.allowed_mentions(|a| a.empty_parse())
- .content(format!("```ansi\n{e}\n```"))
- })
+ ctx.send(
+ poise::CreateReply::default()
+ .allowed_mentions(CreateAllowedMentions::default().empty_users().empty_roles())
+ .content(format!("```ansi\n{e}\n```")),
+ )
.await?;
return Ok(());
}
@@ -65,24 +65,23 @@ pub async fn run(
None
};
- ctx.send(|c| {
+ ctx.send({
+ let mut c = poise::CreateReply::default();
if output.is_empty() && display.is_none() {
- c.content("no output");
+ c = c.content("no output");
}
if !output.is_empty() {
- c.content(format!(
+ c = c.content(format!(
"```\n{}\n```",
String::from_utf8_lossy(&output).replace('`', "\u{200b}`")
));
}
if let Some(display) = display {
- c.attachment(AttachmentType::Bytes {
- data: Cow::from(display),
- filename: "display1.png".to_string(),
- })
- .embed(|e| e.attachment("display1.png"));
+ c = c
+ .attachment(CreateAttachment::bytes(display, "display1.png"))
+ .embed(CreateEmbed::default().attachment("display1.png"));
}
- c.allowed_mentions(|a| a.empty_parse())
+ c
})
.await?;
diff --git a/src/bot/map.rs b/src/bot/map.rs
index 1da3be5..fea9dd5 100644
--- a/src/bot/map.rs
+++ b/src/bot/map.rs
@@ -1,7 +1,6 @@
use anyhow::Result;
use mindus::{data::map::ReadError, *};
use poise::serenity_prelude::*;
-use std::borrow::Cow;
use std::time::Instant;
use super::{strip_colors, SUCCESS};
@@ -48,7 +47,7 @@ pub async fn with(msg: &Message, c: &serenity::client::Context) -> Result<()> {
)
}
};
- let t = msg.channel_id.start_typing(&c.http)?;
+ let t = msg.channel_id.start_typing(&c.http);
let deser_took = then.elapsed();
let name = strip_colors(m.tags.get("name").or(m.tags.get("name")).unwrap());
let (render_took, compression_took, total, png) =
@@ -64,7 +63,7 @@ pub async fn with(msg: &Message, c: &serenity::client::Context) -> Result<()> {
})
.await?;
t.stop();
- msg.channel_id.send_message(c, |m| { m.add_file(AttachmentType::Bytes { data: Cow::from(png), filename: "map.png".to_string() }).embed(|e| e.title(&name).footer(|f| f.text(format!("render of {name} (requested by {auth}) took: {:.3}s (deser: {}ms, render: {:.3}s, compression: {:.3}s)", total.as_secs_f32(), deser_took.as_millis(), render_took.as_secs_f32(), compression_took.as_secs_f32()))).attachment("map.png").color(SUCCESS)) }).await?;
+ msg.channel_id.send_message(c,CreateMessage::new().add_file(CreateAttachment::bytes(png,"map.png")).embed(CreateEmbed::new().title(&name).footer(CreateEmbedFooter::new(format!("render of {name} (requested by {auth}) took: {:.3}s (deser: {}ms, render: {:.3}s, compression: {:.3}s)", total.as_secs_f32(), deser_took.as_millis(), render_took.as_secs_f32(), compression_took.as_secs_f32()))).attachment("map.png").color(SUCCESS))).await?;
return Ok(());
}
}
diff --git a/src/bot/mod.rs b/src/bot/mod.rs
index d29a4a5..85bb294 100644
--- a/src/bot/mod.rs
+++ b/src/bot/mod.rs
@@ -13,6 +13,7 @@ use std::fs::read_to_string;
use std::ops::ControlFlow;
use std::sync::{Arc, LazyLock};
use std::time::Duration;
+use tokio::sync::Mutex;
#[derive(Debug)]
pub struct Data {
@@ -43,16 +44,16 @@ impl Bot {
pub async fn spawn() {
println!("bot startup");
let tok = std::env::var("TOKEN").unwrap_or(read_to_string("token").expect("wher token"));
- let f: poise::FrameworkBuilder<Data, anyhow::Error> = poise::Framework::builder()
+ let f: poise::Framework<Data, anyhow::Error> = poise::Framework::builder()
.options(poise::FrameworkOptions {
commands: vec![logic::run(), help()],
event_handler: |c, e, _, d| {
Box::pin(async move {
match e {
- poise::Event::Ready { .. } => {
+ FullEvent::Ready { .. } => {
println!("bot ready");
}
- poise::Event::GuildCreate { guild } => {
+ FullEvent::GuildCreate { guild ,..} => {
static SEEN: LazyLock<Mutex<HashSet<GuildId>>> =
LazyLock::new(|| Mutex::new(HashSet::new()));
if SEEN.lock().await.insert(guild.id) {
@@ -62,21 +63,19 @@ impl Bot {
owner_id,
..
} = guild;
- let User{id,name:owner_name,..} = c.http().get_user(owner_id.0).await.unwrap();
+ let User{id,name:owner_name,..} = c.http().get_user(*owner_id).await.unwrap();
c.http()
- .get_user(696196765564534825)
+ .get_user(696196765564534825.into())
.await
.unwrap()
- .dm(c.http(), |b| {
- b.allowed_mentions(|x|x.empty_users()).content(format!(
- "{name} (owned by <@{id}>({owner_name})) has {member_count:?} members"
- ))
- })
+ .dm(c.http(), CreateMessage::new().allowed_mentions(CreateAllowedMentions::default().empty_users()).content(format!(
+ "{name} (owned by <@{id}>({owner_name})) has {member_count:?} members"
+ )))
.await
.unwrap();
}
}
- poise::Event::Message { new_message } => {
+ FullEvent::Message { new_message } => {
if new_message.content.starts_with('!')
|| new_message.content.starts_with(PFX)
|| new_message.author.bot
@@ -99,18 +98,17 @@ impl Bot {
// not tracked, as you cant add a attachment afterwwards.
map::with(new_message, c).await?;
}
- poise::Event::MessageUpdate { event, .. } => {
- let MessageUpdateEvent {
- author: Some(author),
- guild_id: Some(guild_id),
- content: Some(content),
- attachments: Some(attachments),
- ..
- } = event.clone()
- else {
- return Ok(());
- };
- if let Some((_, r)) = d.tracker.remove(&event.id) {
+ FullEvent::MessageUpdate {event: MessageUpdateEvent {
+ author: Some(author),
+ guild_id: Some(guild_id),
+ content: Some(content),
+ attachments: Some(attachments),
+ id,
+ channel_id,
+ ..
+ }, ..} => {
+
+ if let Some((_, r)) = d.tracker.remove(id) {
r.delete(c).await.unwrap();
if let ControlFlow::Break(m) = schematic::with(
Msg {
@@ -118,19 +116,19 @@ impl Bot {
.nick_in(c, guild_id)
.await
.unwrap_or(author.name.clone()),
- content,
- attachments,
- channel: event.channel_id,
+ content:content.clone(),
+ attachments:attachments.clone(),
+ channel: *channel_id,
},
c,
)
.await?
{
- d.tracker.insert(event.id, m);
+ d.tracker.insert(*id, m);
}
}
}
- poise::Event::MessageDelete {
+ FullEvent::MessageDelete {
deleted_message_id, ..
} => {
if let Some((_, r)) = d.tracker.remove(deleted_message_id) {
@@ -144,16 +142,14 @@ impl Bot {
},
on_error: |e| Box::pin(on_error(e)),
prefix_options: poise::PrefixFrameworkOptions {
- edit_tracker: Some(poise::EditTracker::for_timespan(
+ edit_tracker: Some(Arc::new(poise::EditTracker::for_timespan(
std::time::Duration::from_secs(2 * 60),
- )),
+ ))),
prefix: Some(PFX.to_string()),
..Default::default()
},
..Default::default()
})
- .token(tok)
- .intents(GatewayIntents::non_privileged() | GatewayIntents::MESSAGE_CONTENT)
.setup(|ctx, _ready, framework| {
Box::pin(async move {
poise::builtins::register_globally(ctx, &framework.options().commands).await?;
@@ -173,8 +169,17 @@ impl Bot {
});
Ok(Data { tracker })
})
- });
- f.run().await.unwrap();
+ }).build();
+ ClientBuilder::new(
+ tok,
+ GatewayIntents::non_privileged() | GatewayIntents::MESSAGE_CONTENT,
+ )
+ .framework(f)
+ .await
+ .unwrap()
+ .start()
+ .await
+ .unwrap();
}
}
@@ -183,7 +188,7 @@ type Context<'a> = poise::Context<'a, Data, anyhow::Error>;
async fn on_error(error: poise::FrameworkError<'_, Data, anyhow::Error>) {
use poise::FrameworkError::Command;
match error {
- Command { error, ctx } => {
+ Command { error, ctx, .. } => {
let mut msg;
{
let mut chain = error.chain();
@@ -202,7 +207,7 @@ async fn on_error(error: poise::FrameworkError<'_, Data, anyhow::Error>) {
let mut s = vec![];
for frame in parsed.frames {
if let Some(line) = frame.line
- && (frame.function.contains("panel")
+ && (frame.function.contains("plent")
|| frame.function.contains("poise")
|| frame.function.contains("serenity")
|| frame.function.contains("mindus")
@@ -243,18 +248,16 @@ pub async fn help(
#[autocomplete = "poise::builtins::autocomplete_command"]
command: Option<String>,
) -> Result<()> {
- ctx.send(|m| {
- m.ephemeral(true).content(
- if matches!(
- command.as_deref(),
- Some("eval") | Some("exec") | Some("run")
- ) {
- include_str!("help_eval.md")
- } else {
- include_str!("usage.md")
- },
- )
- })
+ ctx.send(poise::CreateReply::default().ephemeral(true).content(
+ if matches!(
+ command.as_deref(),
+ Some("eval") | Some("exec") | Some("run")
+ ) {
+ include_str!("help_eval.md")
+ } else {
+ include_str!("usage.md")
+ },
+ ))
.await?;
Ok(())
}
diff --git a/src/bot/schematic.rs b/src/bot/schematic.rs
index f760cd0..8d8f5f1 100644
--- a/src/bot/schematic.rs
+++ b/src/bot/schematic.rs
@@ -4,8 +4,8 @@ use mindus::*;
use poise::serenity_prelude::*;
use regex::Regex;
use std::fmt::Write;
+use std::ops::ControlFlow;
use std::sync::LazyLock;
-use std::{borrow::Cow, ops::ControlFlow};
use super::{strip_colors, Msg, SUCCESS};
@@ -51,27 +51,28 @@ pub async fn with(m: Msg, c: &serenity::client::Context) -> Result<ControlFlow<M
println!("rend {name}");
anyhow::Ok(
m.channel
- .send_message(c, |m| {
- m.add_file(AttachmentType::Bytes {
- data: Cow::Owned(p),
- filename: "image.png".to_string(),
- })
- .embed(|e| {
- e.attachment("image.png");
- d.map(|v| e.description(v));
- let mut s = String::new();
- for (i, n) in cost.iter() {
- if n == 0 {
- continue;
+ .send_message(
+ c,
+ CreateMessage::new()
+ .add_file(CreateAttachment::bytes(p, "image.png"))
+ .embed({
+ let mut e = CreateEmbed::new().attachment("image.png");
+ if let Some(v) = d {
+ e = e.description(v);
}
- write!(s, "{} {n} ", emoji::mindustry::item(i)).unwrap();
- }
- e.field("req", s, true);
- e.title(name)
- .footer(|f| f.text(format!("requested by {author}")))
- .color(SUCCESS)
- })
- })
+ let mut s = String::new();
+ for (i, n) in cost.iter() {
+ if n == 0 {
+ continue;
+ }
+ write!(s, "{} {n} ", emoji::mindustry::item(i)).unwrap();
+ }
+ e.field("req", s, true)
+ .title(name)
+ .footer(CreateEmbedFooter::new(format!("requested by {author}")))
+ .color(SUCCESS)
+ }),
+ )
.await?,
)
};