feat: add suggestions, other minor bugfixes
This commit is contained in:
parent
efd28daf30
commit
6371ab1886
6 changed files with 107 additions and 10 deletions
|
|
@ -11,6 +11,8 @@ Clone this repository with `git clone --recursive https://git.sad.ovh/sophie/cop
|
||||||
- 2 billion note per second parser with all modern midi features supported
|
- 2 billion note per second parser with all modern midi features supported
|
||||||
- Full economy system written using `sqlx` and postgres
|
- Full economy system written using `sqlx` and postgres
|
||||||
- Lots of generic MPP bot features such as following, moving between rooms, et cetera
|
- Lots of generic MPP bot features such as following, moving between rooms, et cetera
|
||||||
|
- Suggestions via NTFY
|
||||||
|
- Very good argument system
|
||||||
|
|
||||||
## Todo
|
## Todo
|
||||||
- No todo :3
|
- No todo :3
|
||||||
|
|
|
||||||
|
|
@ -409,7 +409,7 @@ impl Command for FishCommand {
|
||||||
tokio::spawn(async move {
|
tokio::spawn(async move {
|
||||||
tokio::time::sleep(std::time::Duration::from_secs(timeout_secs as u64)).await;
|
tokio::time::sleep(std::time::Duration::from_secs(timeout_secs as u64)).await;
|
||||||
client_clone
|
client_clone
|
||||||
.dm(format!("🎣 You can fish again now!"), player._id)
|
.dm("🎣 You can fish again now!", player._id.as_str())
|
||||||
.await;
|
.await;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,3 @@
|
||||||
use crate::submods;
|
use crate::submods;
|
||||||
|
|
||||||
submods!(follow, help, launch, test, translate, about, rank);
|
submods!(follow, help, launch, test, translate, about, rank, suggest);
|
||||||
|
|
|
||||||
95
src/commands/system/suggest.rs
Normal file
95
src/commands/system/suggest.rs
Normal file
|
|
@ -0,0 +1,95 @@
|
||||||
|
use crate::Configuration;
|
||||||
|
use crate::User;
|
||||||
|
use crate::client::Client;
|
||||||
|
use crate::client::ClientEvent;
|
||||||
|
use crate::client::Player;
|
||||||
|
use crate::commands::Command;
|
||||||
|
use crate::commands::argument::{ArgumentSpec, ArgumentType, ParsedArgument, ParsedArguments};
|
||||||
|
|
||||||
|
use async_trait::async_trait;
|
||||||
|
|
||||||
|
pub struct SuggestCommand {
|
||||||
|
conf: Configuration,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl SuggestCommand {
|
||||||
|
pub fn new(conf: Configuration) -> Self {
|
||||||
|
Self { conf }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[async_trait]
|
||||||
|
impl Command for SuggestCommand {
|
||||||
|
fn name(&self) -> &'static str {
|
||||||
|
"suggest"
|
||||||
|
}
|
||||||
|
fn aliases(&self) -> &[&'static str] {
|
||||||
|
&["suggestion", "sg"]
|
||||||
|
}
|
||||||
|
fn category(&self) -> &'static str {
|
||||||
|
"system"
|
||||||
|
}
|
||||||
|
fn description(&self) -> &'static str {
|
||||||
|
"Suggest something to the bot owner."
|
||||||
|
}
|
||||||
|
fn argument_spec(&self) -> &'static [ArgumentSpec] {
|
||||||
|
&[ArgumentSpec {
|
||||||
|
name: "text",
|
||||||
|
arg_type: ArgumentType::GreedyString,
|
||||||
|
required: true,
|
||||||
|
default: None,
|
||||||
|
children: &[],
|
||||||
|
}]
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn constructed(&mut self, _: Client) {}
|
||||||
|
|
||||||
|
async fn event(&mut self, _: Client, _: ClientEvent) {}
|
||||||
|
|
||||||
|
async fn execute(&mut self, client: Client, player: Player, args: ParsedArguments, _: User) {
|
||||||
|
let suggestion = match args.get("text") {
|
||||||
|
Some(ParsedArgument::GreedyString(s)) if !s.is_empty() => s,
|
||||||
|
_ => {
|
||||||
|
client.message("Please provide a suggestion.").await;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let ntfy_url = self.conf.commands.ntfy.clone();
|
||||||
|
|
||||||
|
if ntfy_url.is_none() {
|
||||||
|
client.message("Suggestions are currently disabled.").await;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let username = player.name.clone();
|
||||||
|
let player_id_short = player._id.chars().take(6).collect::<String>();
|
||||||
|
let message_body = format!("{} ({}): {}", username, player_id_short, suggestion);
|
||||||
|
|
||||||
|
let res = reqwest::Client::new()
|
||||||
|
.post(ntfy_url.unwrap())
|
||||||
|
.header("Priority", "1")
|
||||||
|
.header("Title", "New Copper suggestion")
|
||||||
|
.body(message_body)
|
||||||
|
.send()
|
||||||
|
.await;
|
||||||
|
|
||||||
|
match res {
|
||||||
|
Ok(resp) if resp.status().is_success() => {
|
||||||
|
client
|
||||||
|
.message("Your suggestion has been sent. Thank you!")
|
||||||
|
.await;
|
||||||
|
}
|
||||||
|
Ok(resp) => {
|
||||||
|
client
|
||||||
|
.message(format!("Failed to send suggestion: HTTP {}", resp.status()))
|
||||||
|
.await;
|
||||||
|
}
|
||||||
|
Err(e) => {
|
||||||
|
client
|
||||||
|
.message(format!("Failed to send suggestion: {}", e))
|
||||||
|
.await;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
10
src/main.rs
10
src/main.rs
|
|
@ -114,27 +114,28 @@ macro_rules! register_all {
|
||||||
)+
|
)+
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
#[derive(Deserialize, Clone)]
|
#[derive(Deserialize, Clone, Debug)]
|
||||||
pub struct Configuration {
|
pub struct Configuration {
|
||||||
database: DatabaseConfig,
|
database: DatabaseConfig,
|
||||||
commands: CommandsConfig,
|
commands: CommandsConfig,
|
||||||
client: ClientConfig,
|
client: ClientConfig,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Deserialize, Clone)]
|
#[derive(Deserialize, Clone, Debug)]
|
||||||
struct DatabaseConfig {
|
struct DatabaseConfig {
|
||||||
url: String,
|
url: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Deserialize, Clone)]
|
#[derive(Deserialize, Clone, Debug)]
|
||||||
struct CommandsConfig {
|
struct CommandsConfig {
|
||||||
prefix: String,
|
prefix: String,
|
||||||
name: String,
|
name: String,
|
||||||
|
ntfy: Option<String>,
|
||||||
copyparty: String,
|
copyparty: String,
|
||||||
playlists: HashMap<String, Vec<String>>,
|
playlists: HashMap<String, Vec<String>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Deserialize, Clone)]
|
#[derive(Deserialize, Clone, Debug)]
|
||||||
struct ClientConfig {
|
struct ClientConfig {
|
||||||
token: String,
|
token: String,
|
||||||
ws: String,
|
ws: String,
|
||||||
|
|
@ -171,6 +172,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
|
||||||
[
|
[
|
||||||
StopCommand::new(midi_state.clone()),
|
StopCommand::new(midi_state.clone()),
|
||||||
PlaylistCommand::new(midi_state.clone(), conf.clone()),
|
PlaylistCommand::new(midi_state.clone(), conf.clone()),
|
||||||
|
SuggestCommand::new(conf.clone()),
|
||||||
QueueCommand::new(midi_state.clone()),
|
QueueCommand::new(midi_state.clone()),
|
||||||
SkipCommand::new(midi_state.clone()),
|
SkipCommand::new(midi_state.clone()),
|
||||||
LaunchCommand,
|
LaunchCommand,
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,6 @@
|
||||||
use flume::Sender;
|
use flume::Sender;
|
||||||
use midiplayer_rs::midi::loader::load_midi_file;
|
use midiplayer_rs::midi::loader::load_midi_file;
|
||||||
use midiplayer_rs::midi::player::ParsedMidi;
|
|
||||||
use midiplayer_rs::midi::player::parse_midi_events;
|
use midiplayer_rs::midi::player::parse_midi_events;
|
||||||
use midiplayer_rs::midi::player::play_parsed_events;
|
|
||||||
use midiplayer_rs::midi::utils::get_time_100ns;
|
use midiplayer_rs::midi::utils::get_time_100ns;
|
||||||
use midiplayer_rs::midi::utils::unpack_event;
|
use midiplayer_rs::midi::utils::unpack_event;
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
|
|
@ -29,7 +27,7 @@ pub enum MidiEvent {
|
||||||
seconds: u128,
|
seconds: u128,
|
||||||
millis: u128,
|
millis: u128,
|
||||||
parse_time: Duration,
|
parse_time: Duration,
|
||||||
entry: QueueEntry,
|
entry: Box<QueueEntry>,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -69,7 +67,7 @@ pub async fn play_midi(
|
||||||
minutes,
|
minutes,
|
||||||
seconds,
|
seconds,
|
||||||
millis,
|
millis,
|
||||||
entry,
|
entry: Box::new(entry),
|
||||||
parse_time: start.elapsed(),
|
parse_time: start.elapsed(),
|
||||||
})
|
})
|
||||||
.await;
|
.await;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue