moving repos
fixed up the command regex
This commit is contained in:
parent
a2cc5ba5a3
commit
bad7b6ad30
18 changed files with 2403 additions and 12 deletions
12
.gitignore
vendored
12
.gitignore
vendored
|
@ -1,16 +1,4 @@
|
||||||
# ---> Rust
|
|
||||||
# Generated by Cargo
|
|
||||||
# will have compiled files and executables
|
|
||||||
debug/
|
debug/
|
||||||
target/
|
target/
|
||||||
|
|
||||||
# Remove Cargo.lock from gitignore if creating an executable, leave it for libraries
|
|
||||||
# More information here https://doc.rust-lang.org/cargo/guide/cargo-toml-vs-cargo-lock.html
|
|
||||||
Cargo.lock
|
|
||||||
|
|
||||||
# These are backup files generated by rustfmt
|
|
||||||
**/*.rs.bk
|
**/*.rs.bk
|
||||||
|
|
||||||
# MSVC Windows builds of rustc generate these, which store debugging information
|
|
||||||
*.pdb
|
*.pdb
|
||||||
|
|
||||||
|
|
2050
Cargo.lock
generated
Normal file
2050
Cargo.lock
generated
Normal file
File diff suppressed because it is too large
Load diff
29
Cargo.toml
Normal file
29
Cargo.toml
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
[package]
|
||||||
|
name = "nopalmo"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
|
||||||
|
[lib]
|
||||||
|
name = "nopalmo_lib"
|
||||||
|
path = "src/lib/lib.rs"
|
||||||
|
|
||||||
|
[[bin]]
|
||||||
|
name = "nopalmo"
|
||||||
|
path = "src/main.rs"
|
||||||
|
|
||||||
|
[workspace]
|
||||||
|
members = ["commands/info"]
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
phf = { version = "0.11.2", features = ["phf_macros"] }
|
||||||
|
rand = "0.8.5"
|
||||||
|
regex = "1.10.4"
|
||||||
|
# rs-cord = { git = "https://github.com/jay3332/rs-cord" }
|
||||||
|
serenity = "0.12.1"
|
||||||
|
tokio = { version = "1.37.0", features = ["full"] }
|
||||||
|
tracing = "0.1.40"
|
||||||
|
|
||||||
|
[features]
|
||||||
|
nsfw_features = []
|
||||||
|
premium_features = []
|
10
commands/info/Cargo.toml
Normal file
10
commands/info/Cargo.toml
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
[package]
|
||||||
|
name = "info"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
[lib]
|
||||||
|
crate-type = ["rlib"]
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
nopalmo = { path = "../../" }
|
0
commands/info/src/lib.rs
Normal file
0
commands/info/src/lib.rs
Normal file
0
commands/info/src/ping.rs
Normal file
0
commands/info/src/ping.rs
Normal file
1
rustfmt.toml
Normal file
1
rustfmt.toml
Normal file
|
@ -0,0 +1 @@
|
||||||
|
hard_tabs = true
|
1
src/bot_token.dev
Normal file
1
src/bot_token.dev
Normal file
|
@ -0,0 +1 @@
|
||||||
|
NzQwODk2NjQ2ODE2MjAyODAy.G-Bkrh.HO4Cv113YGmP0z1ZJ2kJ8JdCOuAammiRguwBqA
|
1
src/bot_token.prod
Normal file
1
src/bot_token.prod
Normal file
|
@ -0,0 +1 @@
|
||||||
|
MzUyMTgyNDc5Mzc0Nzc4Mzcw.GocWAH.xY9H0LsGUWWzJSxkdsZ6nOsia97OIkJ7beNSbg
|
1
src/constants.rs
Normal file
1
src/constants.rs
Normal file
|
@ -0,0 +1 @@
|
||||||
|
pub const GLOBAL_PREFIX: char = ';';
|
1
src/discord_token
Normal file
1
src/discord_token
Normal file
|
@ -0,0 +1 @@
|
||||||
|
NzQwODk2NjQ2ODE2MjAyODAy.GzrIZ-.1oEjcM_mvIWHeUQGTZ8FStrhlq4beHu5RX7KH8
|
3
src/lib/arguments/mod.rs
Normal file
3
src/lib/arguments/mod.rs
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
pub struct Argument {
|
||||||
|
|
||||||
|
}
|
3
src/lib/discord_permissions.rs
Normal file
3
src/lib/discord_permissions.rs
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
pub struct DiscordPermission {
|
||||||
|
|
||||||
|
}
|
54
src/lib/lib.rs
Normal file
54
src/lib/lib.rs
Normal file
|
@ -0,0 +1,54 @@
|
||||||
|
pub mod arguments;
|
||||||
|
pub mod discord_permissions;
|
||||||
|
|
||||||
|
use self::arguments::Argument;
|
||||||
|
use ::serenity::all::{Context, GuildId, Message};
|
||||||
|
use ::std::collections::HashMap;
|
||||||
|
use ::std::time::Duration;
|
||||||
|
use discord_permissions::DiscordPermission;
|
||||||
|
|
||||||
|
#[cfg(feature = "premium_features")]
|
||||||
|
pub enum PremiumLevel {
|
||||||
|
Free,
|
||||||
|
Tier1,
|
||||||
|
Tier2,
|
||||||
|
Tier3,
|
||||||
|
Super,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub enum CommandType {
|
||||||
|
General,
|
||||||
|
Moderation,
|
||||||
|
Fun,
|
||||||
|
Info,
|
||||||
|
Extra,
|
||||||
|
Unknown,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct Command<DMC: Sync + Send, GMC: Sync + Send, CommandReturn: Send + Sync> {
|
||||||
|
pub run_dm_command: Box<dyn Fn(&DMC, Context, Message) -> CommandReturn>,
|
||||||
|
pub run_guild_command: Box<dyn Fn(&GMC, Context, Message, GuildId) -> CommandReturn>,
|
||||||
|
pub aliases: Vec<String>,
|
||||||
|
pub name: String,
|
||||||
|
pub command_type: CommandType,
|
||||||
|
pub help: String,
|
||||||
|
pub usage: String,
|
||||||
|
pub timeout: Duration, // TODO make this dynamic?
|
||||||
|
|
||||||
|
pub arguments: HashMap<String, Argument>,
|
||||||
|
pub permissions: Vec<DiscordPermission>,
|
||||||
|
|
||||||
|
#[cfg(feature = "nsfw_features")]
|
||||||
|
pub is_nsfw: bool,
|
||||||
|
#[cfg(feature = "premium_features")]
|
||||||
|
pub premium_kind: PremiumLevel,
|
||||||
|
}
|
||||||
|
|
||||||
|
unsafe impl<DMC: Send + Sync, GMC: Send + Sync, CommandReturn: Send + Sync> Sync
|
||||||
|
for Command<DMC, GMC, CommandReturn>
|
||||||
|
{
|
||||||
|
}
|
||||||
|
unsafe impl<DMC: Send + Sync, GMC: Send + Sync, CommandReturn: Send + Sync> Send
|
||||||
|
for Command<DMC, GMC, CommandReturn>
|
||||||
|
{
|
||||||
|
}
|
208
src/main.rs
Normal file
208
src/main.rs
Normal file
|
@ -0,0 +1,208 @@
|
||||||
|
//#![feature(async_fn_traits)]
|
||||||
|
|
||||||
|
// mod commands;
|
||||||
|
// use nopalmo_lib;
|
||||||
|
|
||||||
|
mod constants;
|
||||||
|
mod permissions;
|
||||||
|
mod system_messages;
|
||||||
|
mod tasks;
|
||||||
|
|
||||||
|
use ::std::collections::hash_map::HashMap;
|
||||||
|
|
||||||
|
use std::error::Error;
|
||||||
|
use std::future::Future;
|
||||||
|
use std::pin::Pin;
|
||||||
|
use std::sync::atomic::AtomicBool;
|
||||||
|
use std::sync::Arc;
|
||||||
|
use std::time::Duration;
|
||||||
|
|
||||||
|
use nopalmo_lib::discord_permissions::DiscordPermission;
|
||||||
|
use nopalmo_lib::Command;
|
||||||
|
use serenity::all::GuildId;
|
||||||
|
// use commands::Command;
|
||||||
|
use serenity::model::channel::Message;
|
||||||
|
use serenity::model::gateway::Ready;
|
||||||
|
use serenity::prelude::*;
|
||||||
|
// use tokio::sync::mpsc;
|
||||||
|
|
||||||
|
// type DMCommandArguments = Handler;
|
||||||
|
// type GCommandArguments = Handler;
|
||||||
|
// pub type CommandReturn = Pin<Box<dyn Future<Output = ()>>>;
|
||||||
|
// pub type CommandReturn = ();
|
||||||
|
|
||||||
|
struct Handler {
|
||||||
|
// TODO use data field instead?
|
||||||
|
// system_sender: Mutex<mpsc::Sender<system_messages::SystemMessage>>,
|
||||||
|
// system_receiver: Mutex<mpsc::Receiver<system_messages::SystemMessage>>,
|
||||||
|
do_shutdown: AtomicBool,
|
||||||
|
// task_count: AtomicUsize,
|
||||||
|
// command_map: ::std::collections::hash_map::HashMap<
|
||||||
|
// String,
|
||||||
|
// Arc<Command<DMCommandArguments, GCommandArguments, CommandReturn>>,
|
||||||
|
// >,
|
||||||
|
}
|
||||||
|
|
||||||
|
unsafe impl Sync for Handler {}
|
||||||
|
unsafe impl Send for Handler {}
|
||||||
|
|
||||||
|
// unsafe impl Sync for CommandReturn {}
|
||||||
|
// unsafe impl Send for CommandReturn {}
|
||||||
|
|
||||||
|
#[serenity::async_trait]
|
||||||
|
impl EventHandler for Handler {
|
||||||
|
async fn message(&self, ctx: Context, msg: Message) {
|
||||||
|
let prefix_regex = format!(
|
||||||
|
r"^({}|{}|<@{}>)\s?",
|
||||||
|
constants::GLOBAL_PREFIX,
|
||||||
|
"NPO_PFX",
|
||||||
|
ctx.cache.current_user().id
|
||||||
|
);
|
||||||
|
let cmd_regex = format!(r"{}[A-Za-z0-9_\-]+", prefix_regex);
|
||||||
|
|
||||||
|
let result = match regex::Regex::new(cmd_regex.as_str())
|
||||||
|
.unwrap()
|
||||||
|
.find(&msg.content)
|
||||||
|
{
|
||||||
|
Some(result) => result,
|
||||||
|
None => return, // silently exit because not every message is meant for the bot
|
||||||
|
};
|
||||||
|
|
||||||
|
if self.do_shutdown.load(std::sync::atomic::Ordering::SeqCst) {
|
||||||
|
let _ = msg
|
||||||
|
.channel_id
|
||||||
|
.say(
|
||||||
|
&ctx.http,
|
||||||
|
"Sorry! Your request was cancelled because the bot is shutting down.",
|
||||||
|
)
|
||||||
|
.await;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let target_cmd_name = regex::Regex::new(prefix_regex.as_str())
|
||||||
|
.unwrap()
|
||||||
|
.replace(result.as_str(), "");
|
||||||
|
|
||||||
|
dbg!(&target_cmd_name);
|
||||||
|
|
||||||
|
msg.reply(&ctx.http, target_cmd_name.to_string())
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
//if let Some(command) = self.command_map.get(target_cmd_name) {
|
||||||
|
// if let Some(guild_id) = msg.guild_id {
|
||||||
|
// (command.run_guild_command)(&self, ctx, msg, guild_id);
|
||||||
|
// } else {
|
||||||
|
// (command.run_dm_command)(&self, ctx, msg);
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn ready(&self, _: Context, ready: Ready) {
|
||||||
|
println!("Shart `{}` is connected!", ready.shard.unwrap().id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[tokio::main]
|
||||||
|
async fn main() {
|
||||||
|
#[cfg(not(debug_assertions))]
|
||||||
|
let token = include_str!("bot_token.prod");
|
||||||
|
#[cfg(debug_assertions)]
|
||||||
|
let token = include_str!("bot_token.dev");
|
||||||
|
|
||||||
|
let intents = GatewayIntents::DIRECT_MESSAGES
|
||||||
|
| GatewayIntents::DIRECT_MESSAGE_REACTIONS
|
||||||
|
| GatewayIntents::GUILDS
|
||||||
|
| GatewayIntents::GUILD_MODERATION
|
||||||
|
// | GatewayIntents::GUILD_EMOJIS_AND_STICKERS
|
||||||
|
| GatewayIntents::GUILD_MEMBERS
|
||||||
|
| GatewayIntents::GUILD_MESSAGE_REACTIONS
|
||||||
|
| GatewayIntents::GUILD_MESSAGES
|
||||||
|
| GatewayIntents::MESSAGE_CONTENT;
|
||||||
|
|
||||||
|
// let (system_sender, system_receiver) = mpsc::channel(256);
|
||||||
|
// let system_sender = Mutex::new(system_sender);
|
||||||
|
// let system_receiver = Mutex::new(system_receiver);
|
||||||
|
|
||||||
|
// let mut command_map = HashMap::new();
|
||||||
|
|
||||||
|
// fn ping_dm_run(handler: &Handler, ctx: Context, msg: Message) -> () {}
|
||||||
|
// fn ping_guild_run(handler: &Handler, ctx: Context, msg: Message, guild_id: GuildId) -> () {
|
||||||
|
// // MessageChannel channel = blob.getChannel();
|
||||||
|
|
||||||
|
// channel
|
||||||
|
// .sendMessage("Pong!\n" + ctx. + "ms\n")
|
||||||
|
// .queue();
|
||||||
|
|
||||||
|
// // if (argumentMap.get("all") != null) {
|
||||||
|
|
||||||
|
// // channel.sendMessage("Gathering data. . .").queue(msg -> {
|
||||||
|
// // long timeToProcess = System.currentTimeMillis();
|
||||||
|
|
||||||
|
// // long jdaPing = blob.getJDA().getGatewayPing();
|
||||||
|
// // long googlePing = -1;
|
||||||
|
// // try {
|
||||||
|
// // googlePing = UptimePing.sendPing("www.google.com");
|
||||||
|
// // } catch (Exception e) {
|
||||||
|
// // e.printStackTrace();
|
||||||
|
// // }
|
||||||
|
// // long discordPing = -1;
|
||||||
|
// // try {
|
||||||
|
// // discordPing = UptimePing.sendPing("www.discord.com");
|
||||||
|
// // } catch (Exception e) {
|
||||||
|
// // e.printStackTrace();
|
||||||
|
// // }
|
||||||
|
|
||||||
|
// // String out = "Ping:\n"
|
||||||
|
// // + (googlePing > 0 ? "Google: " + googlePing + "ms\n" : "Could not connect to www.google.com\n")
|
||||||
|
// // + (discordPing > 0 ? "Discord: " + discordPing + "ms\n"
|
||||||
|
// // : "Could not connect to www.discord.com\n")
|
||||||
|
// // + "JDA-Discord heartbeat: " + jdaPing + "ms";
|
||||||
|
|
||||||
|
// // msg.editMessage(out + "\nTime to process: " + (System.currentTimeMillis() - timeToProcess) + "ms")
|
||||||
|
// // .queue();
|
||||||
|
// // });
|
||||||
|
// // }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// command_map.insert(
|
||||||
|
// "ping".to_owned(),
|
||||||
|
// Arc::new(Command {
|
||||||
|
// aliases: vec!["ping".to_owned()],
|
||||||
|
// arguments: HashMap::new(),
|
||||||
|
// command_type: nopalmo_lib::CommandType::General,
|
||||||
|
// help: "Some help info".to_owned(),
|
||||||
|
// name: "Ping".to_owned(),
|
||||||
|
// usage: "ping".to_owned(),
|
||||||
|
// permissions: vec![],
|
||||||
|
// timeout: Duration::from_secs(0),
|
||||||
|
// run_dm_command: Box::new(ping_dm_run),
|
||||||
|
// run_guild_command: Box::new(ping_guild_run),
|
||||||
|
// }),
|
||||||
|
// );
|
||||||
|
|
||||||
|
let mut client = match Client::builder(&token, intents)
|
||||||
|
.event_handler(Handler {
|
||||||
|
// system_receiver,
|
||||||
|
// system_sender,
|
||||||
|
do_shutdown: AtomicBool::new(false),
|
||||||
|
// task_count: AtomicUsize::new(0),
|
||||||
|
// command_map,
|
||||||
|
})
|
||||||
|
.await
|
||||||
|
{
|
||||||
|
Ok(client) => client,
|
||||||
|
Err(err) => panic!("Error starting client connection: `{err}`"),
|
||||||
|
};
|
||||||
|
|
||||||
|
let status_timer = tokio::spawn(tasks::status_timer(
|
||||||
|
client.shard_manager.runners.clone(),
|
||||||
|
client.cache.clone(),
|
||||||
|
));
|
||||||
|
|
||||||
|
if let Err(why) = client.start_shards(2).await {
|
||||||
|
println!("Client error: {why:?}");
|
||||||
|
}
|
||||||
|
|
||||||
|
status_timer.abort();
|
||||||
|
}
|
3
src/permissions.rs
Normal file
3
src/permissions.rs
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
pub struct Permission {
|
||||||
|
|
||||||
|
}
|
4
src/system_messages.rs
Normal file
4
src/system_messages.rs
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
|
||||||
|
pub enum SystemMessage {
|
||||||
|
|
||||||
|
}
|
34
src/tasks.rs
Normal file
34
src/tasks.rs
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
use crate::constants;
|
||||||
|
use std::{sync::Arc, time::Duration};
|
||||||
|
|
||||||
|
use ::std::collections::hash_map::HashMap;
|
||||||
|
use rand::{distributions::uniform::SampleRange, rngs::OsRng};
|
||||||
|
use serenity::all::{ActivityData, Cache, ShardId, ShardRunnerInfo};
|
||||||
|
use tokio::sync::Mutex;
|
||||||
|
|
||||||
|
pub async fn status_timer(
|
||||||
|
shard_runners: Arc<Mutex<HashMap<ShardId, ShardRunnerInfo>>>,
|
||||||
|
cache: Arc<Cache>,
|
||||||
|
) {
|
||||||
|
let mut rand = OsRng::default();
|
||||||
|
let activity_list = [
|
||||||
|
ActivityData::watching("my developer eat a watermelon whole."),
|
||||||
|
ActivityData::watching(format!(
|
||||||
|
"{} users in {} guilds.",
|
||||||
|
cache.user_count(),
|
||||||
|
cache.guild_count()
|
||||||
|
)),
|
||||||
|
ActivityData::watching(format!("for {}help", constants::GLOBAL_PREFIX)),
|
||||||
|
ActivityData::listening("Infected Mushroom"),
|
||||||
|
];
|
||||||
|
|
||||||
|
loop {
|
||||||
|
for (_shard_id, shard_info) in shard_runners.lock().await.iter() {
|
||||||
|
shard_info.runner_tx.set_activity(Some(
|
||||||
|
activity_list[SampleRange::sample_single(0..activity_list.len() - 1, &mut rand)]
|
||||||
|
.clone(),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
tokio::time::sleep(Duration::from_secs(20 * 60)).await;
|
||||||
|
}
|
||||||
|
}
|
Loading…
Add table
Reference in a new issue