Make instance channel unbounFOO
This commit is contained in:
parent
38556a16dd
commit
9798136dc4
2 changed files with 94 additions and 68 deletions
|
|
@ -1,79 +1,82 @@
|
||||||
use std::time::Duration;
|
use std::{sync::Arc, time::Duration};
|
||||||
|
|
||||||
|
use async_trait::async_trait;
|
||||||
use euphoxide::{
|
use euphoxide::{
|
||||||
api::{Data, Message, Nick, Send},
|
api::{Data, Message, Nick, ParsedPacket, Send},
|
||||||
client::conn::ClientConnHandle,
|
client::{conn::ClientConnHandle, state::State},
|
||||||
};
|
};
|
||||||
use euphoxide_bot::{
|
use euphoxide_bot::{
|
||||||
bot::{Bot, BotEvent},
|
bot::Bot,
|
||||||
|
command::{
|
||||||
|
botrulez::{FullHelp, HasCommandInfos, HasStartTime, Ping, ShortHelp, Uptime},
|
||||||
|
Command, CommandExt, Commands, Context, Info, Propagate,
|
||||||
|
},
|
||||||
instance::ServerConfig,
|
instance::ServerConfig,
|
||||||
};
|
};
|
||||||
|
use jiff::Timestamp;
|
||||||
|
|
||||||
async fn set_nick(conn: &ClientConnHandle) -> anyhow::Result<()> {
|
struct Pyramid;
|
||||||
conn.send_only(Nick {
|
|
||||||
name: "examplebot".to_string(),
|
|
||||||
})
|
|
||||||
.await?;
|
|
||||||
|
|
||||||
Ok(())
|
#[async_trait]
|
||||||
}
|
impl Command<BotState> for Pyramid {
|
||||||
|
fn info(&self, _ctx: &Context) -> Info {
|
||||||
|
Info::new().with_description("build a pyramid")
|
||||||
|
}
|
||||||
|
|
||||||
async fn send_pong(conn: &ClientConnHandle, msg: Message) -> anyhow::Result<()> {
|
async fn execute(
|
||||||
conn.send_only(Send {
|
&self,
|
||||||
content: "Pong!".to_string(),
|
_arg: &str,
|
||||||
parent: Some(msg.id),
|
msg: &Message,
|
||||||
})
|
ctx: &Context,
|
||||||
.await?;
|
_bot: &BotState,
|
||||||
|
) -> euphoxide::Result<Propagate> {
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn send_pyramid(conn: &ClientConnHandle, msg: Message) -> anyhow::Result<()> {
|
|
||||||
let mut parent = msg.id;
|
let mut parent = msg.id;
|
||||||
|
|
||||||
for _ in 0..3 {
|
for _ in 0..3 {
|
||||||
let first = conn
|
let first = ctx.reply(parent, "brick").await?;
|
||||||
.send(Send {
|
ctx.reply_only(parent, "brick").await?;
|
||||||
content: "brick".to_string(),
|
|
||||||
parent: Some(parent),
|
|
||||||
})
|
|
||||||
.await?;
|
|
||||||
|
|
||||||
conn.send_only(Send {
|
|
||||||
content: "brick".to_string(),
|
|
||||||
parent: Some(parent),
|
|
||||||
})
|
|
||||||
.await?;
|
|
||||||
|
|
||||||
parent = first.await?.0.id;
|
parent = first.await?.0.id;
|
||||||
tokio::time::sleep(Duration::from_secs(1)).await;
|
tokio::time::sleep(Duration::from_secs(1)).await;
|
||||||
}
|
}
|
||||||
|
|
||||||
conn.send_only(Send {
|
ctx.reply_only(parent, "brick").await?;
|
||||||
content: "brick".to_string(),
|
Ok(Propagate::No)
|
||||||
parent: Some(parent),
|
}
|
||||||
})
|
|
||||||
.await?;
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn on_data(conn: ClientConnHandle, data: Data) {
|
#[derive(Clone)]
|
||||||
let result = match data {
|
struct BotState {
|
||||||
Data::SnapshotEvent(_) => set_nick(&conn).await,
|
start_time: Timestamp,
|
||||||
Data::SendEvent(event) if event.0.content == "!ping" => send_pong(&conn, event.0).await,
|
commands: Arc<Commands<Self>>,
|
||||||
Data::SendEvent(event) if event.0.content == "!pyramid" => {
|
}
|
||||||
send_pyramid(&conn, event.0).await
|
|
||||||
}
|
|
||||||
_ => Ok(()),
|
|
||||||
};
|
|
||||||
|
|
||||||
if let Err(err) = result {
|
impl HasStartTime for BotState {
|
||||||
println!("Error while responding: {err}");
|
fn start_time(&self) -> Timestamp {
|
||||||
|
self.start_time
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl HasCommandInfos for BotState {
|
||||||
|
fn command_infos(&self, ctx: &Context) -> Vec<Info> {
|
||||||
|
self.commands.infos(ctx)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn run() -> anyhow::Result<()> {
|
async fn run() -> anyhow::Result<()> {
|
||||||
|
let commands = Commands::new()
|
||||||
|
.then(Ping::default())
|
||||||
|
.then(Uptime)
|
||||||
|
.then(ShortHelp::new("/me demonstrates how to use euphoxide"))
|
||||||
|
.then(FullHelp::new())
|
||||||
|
.then(Pyramid.global("pyramid"));
|
||||||
|
|
||||||
|
let commands = Arc::new(commands);
|
||||||
|
|
||||||
|
let state = BotState {
|
||||||
|
start_time: Timestamp::now(),
|
||||||
|
commands: commands.clone(),
|
||||||
|
};
|
||||||
|
|
||||||
let mut bot = Bot::new();
|
let mut bot = Bot::new();
|
||||||
|
|
||||||
let config = ServerConfig::default()
|
let config = ServerConfig::default()
|
||||||
|
|
@ -83,10 +86,7 @@ async fn run() -> anyhow::Result<()> {
|
||||||
bot.add_instance(config);
|
bot.add_instance(config);
|
||||||
|
|
||||||
while let Some(event) = bot.recv().await {
|
while let Some(event) = bot.recv().await {
|
||||||
if let BotEvent::Packet { conn, packet, .. } = event {
|
commands.on_bot_event(event, &state).await?;
|
||||||
let data = packet.into_data()?;
|
|
||||||
tokio::task::spawn(on_data(conn, data));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,8 @@ pub mod clap;
|
||||||
use std::future::Future;
|
use std::future::Future;
|
||||||
|
|
||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
|
use bang::{General, Global, Specific};
|
||||||
|
use basic::{Described, Prefixed};
|
||||||
use euphoxide::{
|
use euphoxide::{
|
||||||
api::{self, Data, Message, MessageId, ParsedPacket, SendEvent, SendReply},
|
api::{self, Data, Message, MessageId, ParsedPacket, SendEvent, SendReply},
|
||||||
client::{
|
client::{
|
||||||
|
|
@ -108,7 +110,7 @@ pub enum Propagate {
|
||||||
|
|
||||||
#[allow(unused_variables)]
|
#[allow(unused_variables)]
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
pub trait Command<B, E> {
|
pub trait Command<B, E = euphoxide::Error> {
|
||||||
fn info(&self, ctx: &Context) -> Info {
|
fn info(&self, ctx: &Context) -> Info {
|
||||||
Info::default()
|
Info::default()
|
||||||
}
|
}
|
||||||
|
|
@ -122,6 +124,34 @@ pub trait Command<B, E> {
|
||||||
) -> Result<Propagate, E>;
|
) -> Result<Propagate, E>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub trait CommandExt<B, E>: Sized {
|
||||||
|
fn described(self) -> Described<Self> {
|
||||||
|
Described::new(self)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn hidden(self) -> Described<Self> {
|
||||||
|
Described::hidden(self)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn prefixed(self, prefix: impl ToString) -> Prefixed<Self> {
|
||||||
|
Prefixed::new(prefix, self)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn general(self, name: impl ToString) -> General<Self> {
|
||||||
|
General::new(name, self)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn global(self, name: impl ToString) -> Global<Self> {
|
||||||
|
Global::new(name, self)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn specific(self, name: impl ToString) -> Specific<Self> {
|
||||||
|
Specific::new(name, self)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<B, E, C: Command<B, E>> CommandExt<B, E> for C {}
|
||||||
|
|
||||||
pub struct Commands<B, E = euphoxide::Error> {
|
pub struct Commands<B, E = euphoxide::Error> {
|
||||||
commands: Vec<Box<dyn Command<B, E> + Sync + Send>>,
|
commands: Vec<Box<dyn Command<B, E> + Sync + Send>>,
|
||||||
}
|
}
|
||||||
|
|
@ -171,11 +201,7 @@ impl<B, E> Commands<B, E> {
|
||||||
Ok(Propagate::Yes)
|
Ok(Propagate::Yes)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn on_instance_event(
|
pub async fn on_instance_event(&self, event: InstanceEvent, bot: &B) -> Result<Propagate, E> {
|
||||||
&self,
|
|
||||||
event: InstanceEvent,
|
|
||||||
bot: &B,
|
|
||||||
) -> Result<Propagate, E> {
|
|
||||||
if let InstanceEvent::Packet {
|
if let InstanceEvent::Packet {
|
||||||
conn,
|
conn,
|
||||||
state,
|
state,
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue