This commit is contained in:
moonleay 2024-02-17 02:28:24 +01:00
commit 9dad9bbda3
Signed by: moonleay
GPG key ID: 82667543CCD715FB
9 changed files with 2152 additions and 0 deletions

3
.gitignore vendored Normal file
View file

@ -0,0 +1,3 @@
/target
/data
config.json

5
.vscode/settings.json vendored Normal file
View file

@ -0,0 +1,5 @@
{
"rust-analyzer.linkedProjects": [
".\\Cargo.toml"
]
}

2006
Cargo.lock generated Normal file

File diff suppressed because it is too large Load diff

15
Cargo.toml Normal file
View file

@ -0,0 +1,15 @@
[package]
name = "rustendo"
version = "0.1.0"
authors = ["moonleay <contact@moonleay.net>"]
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
serenity = "0.12"
tokio = { version = "1.36", features = ["macros", "rt-multi-thread"] }
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
confy = "0.6.0"

1
src/commands/mod.rs Normal file
View file

@ -0,0 +1 @@
pub mod ping;

10
src/commands/ping.rs Normal file
View file

@ -0,0 +1,10 @@
use serenity::builder::CreateCommand;
use serenity::model::application::ResolvedOption;
pub fn run(_options: &[ResolvedOption]) -> String {
"Hey, I'm alive!".to_string()
}
pub fn register() -> CreateCommand {
CreateCommand::new("ping").description("A ping command")
}

78
src/main.rs Normal file
View file

@ -0,0 +1,78 @@
mod commands;
mod util;
use serenity::all::OnlineStatus;
use serenity::async_trait;
use serenity::builder::{CreateInteractionResponse, CreateInteractionResponseMessage};
use serenity::gateway::ActivityData;
use serenity::model::application::{Command, Interaction};
use serenity::model::gateway::Ready;
use serenity::prelude::*;
use util::config;
struct Handler;
#[async_trait]
impl EventHandler for Handler {
async fn interaction_create(&self, ctx: Context, interaction: Interaction) {
if let Interaction::Command(command) = interaction {
println!("Received command interaction: {command:#?}");
let content = match command.data.name.as_str() {
"ping" => Some(commands::ping::run(&command.data.options())),
_ => Some("not implemented :(".to_string()),
};
if let Some(content) = content {
let data = CreateInteractionResponseMessage::new().content(content);
let builder = CreateInteractionResponse::Message(data);
if let Err(why) = command.create_response(&ctx.http, builder).await {
println!("Cannot respond to slash command: {why}");
}
}
}
}
async fn ready(&self, ctx: Context, ready: Ready) {
println!("{} is connected!", ready.user.name);
let _guild_command =
Command::create_global_command(&ctx.http, commands::ping::register())
.await;
println!("Created all public / commands");
}
}
#[tokio::main]
async fn main() {
println!(r"__________ __ .___
\______ \__ __ _______/ |_ ____ ____ __| _/____
| _/ | | ___/\ __\_/ __ \ / \ / __ |/ _ \
| | \ | |___ \ | | \ ___/ | | | /_/ ( <_> )
|____|_ /____/____ > |__| \___ >|___| |____ |\____/
\/ \/ \/ \/ \/
");
let config = config::load().unwrap();
let status = OnlineStatus::DoNotDisturb;
let activity = ActivityData::streaming("music", "https://twitch.tv/moonleaytv").unwrap();
// Build our client.
let mut client = Client::builder(config.discord_token, GatewayIntents::empty())
.event_handler(Handler)
.status(status)
.activity(activity)
.await
.expect("Error creating client");
// Finally, start a single shard, and start listening to events.
//
// Shards will automatically attempt to reconnect, and will perform exponential backoff until
// it reconnects.
if let Err(why) = client.start().await {
println!("Client error: {why:?}");
}
}

33
src/util/config.rs Normal file
View file

@ -0,0 +1,33 @@
use std::{fs, io::Write};
use serde::{Deserialize, Serialize};
use std::error::Error;
#[derive(Deserialize, Serialize)]
pub struct Config {
pub discord_token: String
}
const CONFIG_FILE: &str = "./data/config.json";
pub fn load() -> Result<Config, Box<dyn Error>> {
// TODO: load config, create empty config if there is no config, stop if there is no complete config
let config_file = match fs::File::open(CONFIG_FILE) {
Ok(file) => file,
Err(_) => create_empty()
};
let config_file = serde_json::from_reader(config_file).unwrap();
Ok(config_file)
}
fn create_empty() -> fs::File{
let example_config = Config {
discord_token: "paste_your_config".to_string()
};
let mut config_file = fs::File::create(CONFIG_FILE).unwrap();
let file_content = serde_json::to_string(&example_config).unwrap();
config_file.write_all(&file_content.as_bytes()).unwrap();
panic!("There is no config. But now there is a template.")
}

1
src/util/mod.rs Normal file
View file

@ -0,0 +1 @@
pub mod config;