Add /eval command
This commit is contained in:
parent
0837a65bf4
commit
d33a479f5c
3
.vscode/settings.json
vendored
3
.vscode/settings.json
vendored
@ -1,5 +1,6 @@
|
||||
{
|
||||
"rust-analyzer.linkedProjects": [
|
||||
"./Cargo.toml"
|
||||
]
|
||||
],
|
||||
"rust-analyzer.showUnlinkedFileNotification": false
|
||||
}
|
||||
|
1
Cargo.lock
generated
1
Cargo.lock
generated
@ -1146,6 +1146,7 @@ version = "0.1.0"
|
||||
dependencies = [
|
||||
"poise",
|
||||
"serenity 0.12.0",
|
||||
"tempfile",
|
||||
"tokio",
|
||||
"tracing",
|
||||
"tracing-subscriber",
|
||||
|
@ -8,6 +8,7 @@ edition = "2021"
|
||||
[dependencies]
|
||||
poise = "0.5.7"
|
||||
serenity = "0.12.0"
|
||||
tempfile = "3.8.1"
|
||||
tokio = { version = "1.34.0", features = ["macros", "signal", "rt-multi-thread"] }
|
||||
tracing = "0.1.40"
|
||||
tracing-subscriber = "0.3.18"
|
||||
|
56
src/commands/eval.rs
Normal file
56
src/commands/eval.rs
Normal file
@ -0,0 +1,56 @@
|
||||
use crate::Error;
|
||||
|
||||
use poise::serenity_prelude::UserId;
|
||||
use std::os::unix::fs::PermissionsExt;
|
||||
use std::process::Command;
|
||||
use std::io::Write;
|
||||
|
||||
const WHITELISTED_USERS: &[UserId] = &[
|
||||
poise::serenity_prelude::UserId(190407856527376384)
|
||||
];
|
||||
|
||||
/// Evaluate a piece of code
|
||||
#[poise::command(slash_command)]
|
||||
pub async fn eval(
|
||||
ctx: poise::Context<'_, (), Error>,
|
||||
#[description = "The Rust code to evaluate"] code: String
|
||||
) -> Result<(), Error> {
|
||||
if !WHITELISTED_USERS.contains(&ctx.author().id) {
|
||||
ctx.reply("Whitelisted users can only use this command!").await?;
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
// Create a temp directory
|
||||
let dir = tempfile::tempdir()?;
|
||||
let file_path = dir.path().join("temp.rs");
|
||||
|
||||
{
|
||||
let mut file = std::fs::File::create(&file_path)?;
|
||||
writeln!(file, "{}", code)?;
|
||||
}
|
||||
|
||||
// Compile
|
||||
let compiled_path = dir.path().join("temp");
|
||||
let output = Command::new("rustc").arg(&file_path).arg("-o").arg(&compiled_path).output()?;
|
||||
|
||||
if !output.status.success() {
|
||||
ctx.reply(format!("Compilation failed:\n```{}```", String::from_utf8_lossy(&output.stderr))).await?;
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
// Update binary's permissions before execution stage
|
||||
let permissions = std::fs::Permissions::from_mode(0o755);
|
||||
let compiled_path = dir.path().join("temp");
|
||||
std::fs::set_permissions(&compiled_path, permissions)?;
|
||||
|
||||
// If success, run it.
|
||||
let output = Command::new(compiled_path).output()?;
|
||||
|
||||
if !output.status.success() {
|
||||
ctx.reply(format!("Execution failed:\n```{}```", String::from_utf8_lossy(&output.stderr))).await?;
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
ctx.reply(format!("Code output:\n```rs\n{}```", String::from_utf8_lossy(&output.stdout))).await?;
|
||||
Ok(())
|
||||
}
|
@ -1 +1,2 @@
|
||||
pub mod ping;
|
||||
pub mod eval;
|
||||
|
@ -37,7 +37,8 @@ async fn main() {
|
||||
.intents(serenity::GatewayIntents::MESSAGE_CONTENT | serenity::GatewayIntents::GUILDS)
|
||||
.options(poise::FrameworkOptions {
|
||||
commands: vec![
|
||||
commands::ping::ping()
|
||||
commands::ping::ping(),
|
||||
commands::eval::eval()
|
||||
],
|
||||
pre_command: |ctx| {
|
||||
Box::pin(async move {
|
||||
|
Loading…
Reference in New Issue
Block a user