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/
|
||||
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
|
||||
|
||||
# MSVC Windows builds of rustc generate these, which store debugging information
|
||||
*.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