html terminal
bendn 2023-08-19
parent be47ba9 · commit 4c0b7e7
-rw-r--r--src/bot/bans.rs2
-rw-r--r--src/bot/mod.rs67
-rw-r--r--src/process.rs7
-rw-r--r--src/server.rs16
-rw-r--r--src/webhook.rs13
5 files changed, 67 insertions, 38 deletions
diff --git a/src/bot/bans.rs b/src/bot/bans.rs
index aa11440..e0b65d3 100644
--- a/src/bot/bans.rs
+++ b/src/bot/bans.rs
@@ -51,7 +51,7 @@ pub async fn kick(
#[poise::command(
slash_command,
category = "Control",
- rename = "ban",
+ rename = "ban_raw",
required_permissions = "ADMINISTRATOR",
default_member_permissions = "ADMINISTRATOR"
)]
diff --git a/src/bot/mod.rs b/src/bot/mod.rs
index 15acd71..a6d02e6 100644
--- a/src/bot/mod.rs
+++ b/src/bot/mod.rs
@@ -45,7 +45,7 @@ macro_rules! send_ctx {
}
#[cfg(not(debug_assertions))]
-const PFX: &'static str = ">";
+const PFX: &str = ">";
#[cfg(debug_assertions)]
const PFX: &str = "-";
@@ -56,12 +56,12 @@ const DISABLED: (u8, u8, u8) = (112, 128, 144);
pub struct Bot;
impl Bot {
pub async fn spawn(stdout: broadcast::Receiver<String>, stdin: broadcast::Sender<String>) {
+ 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()
.options(poise::FrameworkOptions {
commands: vec![
raw(),
- say(),
bans::add(),
bans::remove(),
bans::add_raw(),
@@ -83,10 +83,53 @@ impl Bot {
end(),
help(),
],
+ event_handler: |c, e, _, d| {
+ Box::pin(async move {
+ match e {
+ poise::Event::Ready { .. } => {
+ println!("bot ready");
+ }
+ poise::Event::Message { new_message } => {
+ if [1142100900442296441, 1003092765581787279]
+ .contains(new_message.channel_id.as_u64())
+ && !new_message.content.starts_with("!")
+ && !new_message.content.starts_with(PFX)
+ && !new_message.author.bot
+ {
+ if send!(
+ d.stdin,
+ "say [royal][] [scarlet][[{}]:[] {}",
+ new_message
+ .author_nick(&c.http)
+ .await
+ .unwrap_or_else(|| new_message.author.name.clone()),
+ new_message.content_safe(&c.cache).replace("\n", "; ")
+ )
+ .is_err()
+ {
+ return Ok(());
+ };
+ new_message
+ .react(
+ &c.http,
+ c.http
+ .get_emoji(1003092764919091282, 1142290560275718194)
+ .await
+ .unwrap(),
+ )
+ .await
+ .unwrap();
+ }
+ }
+ _ => {}
+ };
+ Ok(())
+ })
+ },
on_error: |e| Box::pin(on_error(e)),
prefix_options: poise::PrefixFrameworkOptions {
edit_tracker: Some(poise::EditTracker::for_timespan(
- std::time::Duration::from_secs(5 * 60),
+ std::time::Duration::from_secs(2 * 60),
)),
prefix: Some(PFX.to_string()),
..Default::default()
@@ -94,9 +137,10 @@ impl Bot {
..Default::default()
})
.token(tok)
- .intents(GatewayIntents::GUILD_MESSAGES | GatewayIntents::MESSAGE_CONTENT)
+ .intents(GatewayIntents::all())
.setup(|ctx, _ready, framework| {
Box::pin(async move {
+ println!("registering");
poise::builtins::register_globally(ctx, &framework.options().commands).await?;
println!("registered");
Ok(Data {
@@ -130,8 +174,7 @@ async fn on_error(error: poise::FrameworkError<'_, Data, anyhow::Error>) {
msg = format!("e: `{}`", chain.next().unwrap());
for mut source in chain {
write!(msg, "from: `{source}`").unwrap();
- loop {
- let Some(next) = source.source() else { break };
+ while let Some(next) = source.source() {
write!(msg, "from: `{next}`").unwrap();
source = next;
}
@@ -200,18 +243,6 @@ async fn get_nextblock() -> String {
.unwrap_or("._?".to_string())
}
-#[poise::command(
- slash_command,
- category = "Control",
- default_member_permissions = "ADMINISTRATOR",
- required_permissions = "ADMINISTRATOR"
-)]
-/// say something as the server
-async fn say(ctx: Context<'_>, #[description = "Message"] message: String) -> Result<()> {
- ctx.data().stdin.send(format!("say {message}"))?;
- return_next!(ctx)
-}
-
pub fn strip_colors(from: &str) -> String {
let mut result = String::new();
result.reserve(from.len());
diff --git a/src/process.rs b/src/process.rs
index c13332c..6950297 100644
--- a/src/process.rs
+++ b/src/process.rs
@@ -46,8 +46,7 @@ impl Process {
match input.try_recv() {
Err(e) => match e {
TryRecvError::Closed => fail!("closed"),
- TryRecvError::Lagged(_) => continue,
- TryRecvError::Empty => {}
+ _ => sleep(Duration::from_millis(100)).await,
},
Ok(mut s) => {
input!("{s}");
@@ -60,7 +59,7 @@ impl Process {
let string = {
let n = tokio::select! {
n = self.inner.read(&mut stdout) => n.unwrap(),
- _ = sleep(Duration::from_millis(500)) => continue,
+ _ = sleep(Duration::from_millis(100)) => continue,
};
String::from_utf8_lossy(&strip_ansi_escapes::strip(&stdout[..n])).into_owned()
};
@@ -68,7 +67,7 @@ impl Process {
output!("{line}");
}
output.send(string).unwrap();
- sleep(Duration::from_millis(500)).await;
+ sleep(Duration::from_millis(100)).await;
}
})
}
diff --git a/src/server.rs b/src/server.rs
index 5596564..218bf84 100644
--- a/src/server.rs
+++ b/src/server.rs
@@ -82,23 +82,23 @@ impl Server {
});
let stdout = state.stdout.clone();
tokio::spawn(async move {
+ let mut process_handle: Option<JoinHandle<()>> = None;
+ let mut backoff = 1u64;
macro_rules! backoff {
- ($backoff:expr) => {
- $backoff <<= 1;
- println!("process died; waiting {}s", $backoff);
- sleep(Duration::from_secs($backoff)).await;
+ () => {
+ backoff <<= 1;
+ sleep(Duration::from_secs(backoff)).await;
continue;
};
}
- let mut process_handle: Option<JoinHandle<()>> = None;
- let mut backoff = 1u64;
loop {
if let Some(h) = process_handle {
let _ = h.await;
process_handle = None;
+ println!("process died; waiting {}s", backoff << 2);
}
let Ok(spawn) = Process::spawn().await else {
- backoff!(backoff);
+ backoff!();
};
process_handle = Some(
spawn
@@ -109,7 +109,7 @@ impl Server {
if backoff == 1 {
continue;
}
- backoff!(backoff);
+ backoff!();
}
});
Bot::spawn(state.stdout.subscribe(), state.stdin.clone()).await;
diff --git a/src/webhook.rs b/src/webhook.rs
index d524f97..6fc2195 100644
--- a/src/webhook.rs
+++ b/src/webhook.rs
@@ -64,7 +64,7 @@ impl<'a> Webhook<'a> {
match out {
Err(e) => match e {
TryRecvError::Closed => fail!("closed"),
- _ => sleep(Duration::from_millis(20)).await,
+ _ => sleep(Duration::from_millis(100)).await,
},
Ok(m) => {
if self
@@ -73,10 +73,9 @@ impl<'a> Webhook<'a> {
.is_ok()
{
input!("{m} < skipped");
- match self.skipped.send(m) {
- Err(e) => eprintln!("err skipping: {e}"),
- Ok(_) => {}
- };
+ if let Err(e) = self.skipped.send(m) {
+ eprintln!("err skipping: {e}");
+ }
continue;
}
for line in m.lines() {
@@ -84,7 +83,7 @@ impl<'a> Webhook<'a> {
}
}
}
- sleep(Duration::from_millis(20)).await;
+ sleep(Duration::from_millis(100)).await;
}
}
@@ -134,7 +133,7 @@ fn get(line: &str) -> Option<Message> {
if let Some((u, c)) = line.split(": ").map(unify).collect_tuple() {
let u = u.trim_start_matches('<');
let c = c.trim_end_matches('>');
- if !(u.is_empty() || c.is_empty() || HAS_UUID.is_match(c)) {
+ if !(u.is_empty() || c.is_empty() || HAS_UUID.is_match(c) || HAS_UUID.is_match(u)) {
return Some(Message::Chat {
player: u.to_owned(),
content: c.to_owned(),