forked from projectmoon/tenebrous-dicebot
Allow up to 50 commands per message.
If the amount of commands in a single message is greater, the bot will now return an error. Includes slight refactoring of command execution code to make use of streams for async iter-like mapping of the command list. Fixes #24.
This commit is contained in:
parent
3faca6a2df
commit
7512ca0694
31
src/bot.rs
31
src/bot.rs
|
@ -6,9 +6,9 @@ use crate::error::BotError;
|
||||||
use crate::matrix;
|
use crate::matrix;
|
||||||
use crate::state::DiceBotState;
|
use crate::state::DiceBotState;
|
||||||
use dirs;
|
use dirs;
|
||||||
|
use futures::stream::{self, StreamExt};
|
||||||
use log::info;
|
use log::info;
|
||||||
use matrix_sdk::{self, identifiers::RoomId, Client, ClientConfig, JoinedRoom, SyncSettings};
|
use matrix_sdk::{self, identifiers::RoomId, Client, ClientConfig, JoinedRoom, SyncSettings};
|
||||||
//use matrix_sdk_common_macros::async_trait;
|
|
||||||
use std::clone::Clone;
|
use std::clone::Clone;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
use std::sync::{Arc, RwLock};
|
use std::sync::{Arc, RwLock};
|
||||||
|
@ -16,6 +16,10 @@ use url::Url;
|
||||||
|
|
||||||
pub mod event_handlers;
|
pub mod event_handlers;
|
||||||
|
|
||||||
|
/// How many commands can be in one message. If the amount is higher
|
||||||
|
/// than this, we reject execution.
|
||||||
|
const MAX_COMMANDS_PER_MESSAGE: usize = 50;
|
||||||
|
|
||||||
/// The DiceBot struct represents an active dice bot. The bot is not
|
/// The DiceBot struct represents an active dice bot. The bot is not
|
||||||
/// connected to Matrix until its run() function is called.
|
/// connected to Matrix until its run() function is called.
|
||||||
pub struct DiceBot {
|
pub struct DiceBot {
|
||||||
|
@ -153,25 +157,34 @@ impl DiceBot {
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn execute_commands(&self, room: &JoinedRoom, sender_username: &str, msg_body: &str) {
|
async fn execute_commands(&self, room: &JoinedRoom, sender_username: &str, msg_body: &str) {
|
||||||
let room_name = room.display_name().await.ok().unwrap_or_default();
|
let room_name: &str = &room.display_name().await.ok().unwrap_or_default();
|
||||||
let room_id = room.room_id().clone();
|
let room_id = room.room_id().clone();
|
||||||
|
|
||||||
let mut results: Vec<(&str, CommandResult)> = Vec::with_capacity(msg_body.lines().count());
|
let commands: Vec<&str> = msg_body
|
||||||
|
.lines()
|
||||||
|
.filter(|line| line.starts_with("!"))
|
||||||
|
.collect();
|
||||||
|
|
||||||
let commands = msg_body.trim().lines().filter(|line| line.starts_with("!"));
|
//Up to 50 commands allowed, otherwise we send back an error.
|
||||||
|
let results: Vec<(&str, CommandResult)> = if commands.len() < MAX_COMMANDS_PER_MESSAGE {
|
||||||
for command in commands {
|
stream::iter(commands)
|
||||||
|
.then(|command| async move {
|
||||||
let ctx = Context {
|
let ctx = Context {
|
||||||
db: self.db.clone(),
|
db: self.db.clone(),
|
||||||
matrix_client: &self.client,
|
matrix_client: &self.client,
|
||||||
room: RoomContext::new_with_name(&room, &room_name),
|
room: RoomContext::new_with_name(&room, room_name),
|
||||||
username: &sender_username,
|
username: &sender_username,
|
||||||
message_body: &command,
|
message_body: &command,
|
||||||
};
|
};
|
||||||
|
|
||||||
let cmd_result = execute_command(&ctx).await;
|
let cmd_result = execute_command(&ctx).await;
|
||||||
results.push((&command, cmd_result));
|
(command, cmd_result)
|
||||||
}
|
})
|
||||||
|
.collect()
|
||||||
|
.await
|
||||||
|
} else {
|
||||||
|
vec![("", Err(ExecutionError(BotError::MessageTooLarge)))]
|
||||||
|
};
|
||||||
|
|
||||||
if results.len() >= 1 {
|
if results.len() >= 1 {
|
||||||
if results.len() == 1 {
|
if results.len() == 1 {
|
||||||
|
|
|
@ -46,7 +46,7 @@ impl Execution {
|
||||||
/// provides formatting for successfully executed commands.
|
/// provides formatting for successfully executed commands.
|
||||||
#[derive(Error, Debug)]
|
#[derive(Error, Debug)]
|
||||||
#[error("{0}")]
|
#[error("{0}")]
|
||||||
pub struct ExecutionError(#[from] BotError);
|
pub struct ExecutionError(#[from] pub BotError);
|
||||||
|
|
||||||
impl From<crate::db::errors::DataError> for ExecutionError {
|
impl From<crate::db::errors::DataError> for ExecutionError {
|
||||||
fn from(error: crate::db::errors::DataError) -> Self {
|
fn from(error: crate::db::errors::DataError) -> Self {
|
||||||
|
|
|
@ -69,6 +69,9 @@ pub enum BotError {
|
||||||
|
|
||||||
#[error("database error")]
|
#[error("database error")]
|
||||||
DatabaseErrror(#[from] sled::Error),
|
DatabaseErrror(#[from] sled::Error),
|
||||||
|
|
||||||
|
#[error("too many commands or message was too large")]
|
||||||
|
MessageTooLarge,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Error, Debug)]
|
#[derive(Error, Debug)]
|
||||||
|
|
Loading…
Reference in New Issue