Initial commit
commit
fb4e245034
|
@ -0,0 +1,2 @@
|
||||||
|
[registries.jojo-dev]
|
||||||
|
index = "https://git.jojodev.com/joeyahines/_cargo-index.git"
|
|
@ -0,0 +1,2 @@
|
||||||
|
/target
|
||||||
|
/.idea
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,21 @@
|
||||||
|
[package]
|
||||||
|
name = "rpb"
|
||||||
|
description = "Role Playing Bot!"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
poise = "0.6.1"
|
||||||
|
config = "0.14.0"
|
||||||
|
serde = "1.0.203"
|
||||||
|
structopt = "0.3.26"
|
||||||
|
log = "0.4.22"
|
||||||
|
env_logger = "0.11.3"
|
||||||
|
raas_types = {version = "0.0.9", registry = "jojo-dev"}
|
||||||
|
tonic = "0.11.0"
|
||||||
|
rpg-dice-rust = "1.1.0"
|
||||||
|
chrono = "0.4.38"
|
||||||
|
|
||||||
|
[dependencies.tokio]
|
||||||
|
version = "1.38.0"
|
||||||
|
features = ["rt-multi-thread"]
|
|
@ -0,0 +1,2 @@
|
||||||
|
bot_token = "NzEyNzE4NjQzNTkwNDYzNTIx.GWN1BZ.WqkDyZPB6OqZt1LL41lypjDKN0vPxDPZnkemZM"
|
||||||
|
raas_url = "http://158.69.121.46:12000"
|
|
@ -0,0 +1,118 @@
|
||||||
|
use crate::config::BotConfig;
|
||||||
|
use crate::context::Context;
|
||||||
|
use chrono::Utc;
|
||||||
|
use dicelib::solve_dice_expression;
|
||||||
|
use log::{debug, info};
|
||||||
|
use poise::serenity_prelude::{CreateAttachment, MessageBuilder};
|
||||||
|
use poise::CreateReply;
|
||||||
|
use raas_types::raas::bot::roll::{roll_response, Roll, RollCmd};
|
||||||
|
use raas_types::raas::resp::response::Resp;
|
||||||
|
use raas_types::raas::service::raas_client::RaasClient;
|
||||||
|
|
||||||
|
type Error = Box<dyn std::error::Error + Send + Sync>;
|
||||||
|
type BotContext<'a> = poise::Context<'a, Context, Error>;
|
||||||
|
|
||||||
|
#[poise::command(slash_command, help_text_fn = "roll_help")]
|
||||||
|
async fn roll(
|
||||||
|
ctx: BotContext<'_>,
|
||||||
|
#[description = "Dice String eg 1d20"] roll: String,
|
||||||
|
) -> Result<(), Error> {
|
||||||
|
let result = solve_dice_expression(&roll, None)?;
|
||||||
|
|
||||||
|
let mut msg = MessageBuilder::new();
|
||||||
|
|
||||||
|
msg.push("Result of: ");
|
||||||
|
msg.push_mono_line_safe(roll);
|
||||||
|
msg.push_bold_line_safe(result.to_string());
|
||||||
|
|
||||||
|
ctx.reply(msg.build()).await?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn roll_help() -> String {
|
||||||
|
"Example Usage:\n`/roll d20+2`".to_string()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[poise::command(slash_command, help_text_fn = "real_roll_help")]
|
||||||
|
async fn real_roll(ctx: BotContext<'_>) -> Result<(), Error> {
|
||||||
|
let addr = ctx.data().config.raas_url.clone();
|
||||||
|
|
||||||
|
let mut client = RaasClient::connect(addr).await?;
|
||||||
|
|
||||||
|
let rolls = 3;
|
||||||
|
|
||||||
|
let roll_request = raas_types::raas::cmd::Request {
|
||||||
|
timestamp: Utc::now().timestamp() as u64,
|
||||||
|
cmd: Some(raas_types::raas::cmd::request::Cmd::RollCmd(RollCmd {
|
||||||
|
cmd: Some(raas_types::raas::bot::roll::roll_cmd::Cmd::Roll(Roll {
|
||||||
|
rotations: rolls,
|
||||||
|
})),
|
||||||
|
})),
|
||||||
|
};
|
||||||
|
|
||||||
|
debug!("Request: {:?}", roll_request);
|
||||||
|
|
||||||
|
let grpc_request = tonic::Request::new(roll_request);
|
||||||
|
|
||||||
|
ctx.reply("Sending roll request, please hang on!").await?;
|
||||||
|
|
||||||
|
let response = client.send_request(grpc_request).await?;
|
||||||
|
|
||||||
|
let raas_response = response.into_inner();
|
||||||
|
|
||||||
|
debug!(
|
||||||
|
"Got RaaS: {} @ {}",
|
||||||
|
raas_response.id, raas_response.timestamp
|
||||||
|
);
|
||||||
|
|
||||||
|
match raas_response.resp.unwrap() {
|
||||||
|
Resp::RollResp(roll_resp) => {
|
||||||
|
if let roll_response::Response::RollImage(img) = roll_resp.response.unwrap() {
|
||||||
|
ctx.send(
|
||||||
|
CreateReply::default()
|
||||||
|
.content("Your roll:")
|
||||||
|
.attachment(CreateAttachment::bytes(img.img, "roll.jpg"))
|
||||||
|
.reply(true),
|
||||||
|
)
|
||||||
|
.await?;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Resp::Error(err) => {
|
||||||
|
ctx.reply(format!("Roll Bot encountered an error: `{}`", err.msg))
|
||||||
|
.await?;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn real_roll_help() -> String {
|
||||||
|
"Roll a real D20!".to_string()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn start_bot(config: BotConfig) {
|
||||||
|
info!("Starting bot!");
|
||||||
|
|
||||||
|
let intents = poise::serenity_prelude::GatewayIntents::non_privileged();
|
||||||
|
|
||||||
|
let token = config.bot_token.clone();
|
||||||
|
|
||||||
|
let framework = poise::Framework::builder()
|
||||||
|
.options(poise::FrameworkOptions {
|
||||||
|
commands: vec![roll(), real_roll()],
|
||||||
|
..Default::default()
|
||||||
|
})
|
||||||
|
.setup(|ctx, _ready, framework| {
|
||||||
|
Box::pin(async move {
|
||||||
|
poise::builtins::register_globally(ctx, &framework.options().commands).await?;
|
||||||
|
Ok(Context { config })
|
||||||
|
})
|
||||||
|
})
|
||||||
|
.build();
|
||||||
|
|
||||||
|
let client = poise::serenity_prelude::ClientBuilder::new(token, intents)
|
||||||
|
.framework(framework)
|
||||||
|
.await;
|
||||||
|
client.unwrap().start().await.unwrap();
|
||||||
|
}
|
|
@ -0,0 +1,25 @@
|
||||||
|
use config::{Config, File};
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
use std::path::{Path, PathBuf};
|
||||||
|
use structopt::StructOpt;
|
||||||
|
|
||||||
|
#[derive(Debug, StructOpt)]
|
||||||
|
pub struct Args {
|
||||||
|
pub config_path: PathBuf,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
|
pub struct BotConfig {
|
||||||
|
pub bot_token: String,
|
||||||
|
pub raas_url: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl BotConfig {
|
||||||
|
pub fn new(config_path: &Path) -> Result<Self, config::ConfigError> {
|
||||||
|
let cfg = Config::builder()
|
||||||
|
.add_source(File::from(config_path))
|
||||||
|
.build()?;
|
||||||
|
|
||||||
|
cfg.try_deserialize()
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,6 @@
|
||||||
|
use crate::config::BotConfig;
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub struct Context {
|
||||||
|
pub config: BotConfig,
|
||||||
|
}
|
|
@ -0,0 +1,26 @@
|
||||||
|
use crate::bot::start_bot;
|
||||||
|
use crate::config::{Args, BotConfig};
|
||||||
|
use log::{debug, error};
|
||||||
|
use structopt::StructOpt;
|
||||||
|
|
||||||
|
mod bot;
|
||||||
|
mod config;
|
||||||
|
mod context;
|
||||||
|
|
||||||
|
#[tokio::main]
|
||||||
|
async fn main() {
|
||||||
|
env_logger::init();
|
||||||
|
|
||||||
|
let args = Args::from_args();
|
||||||
|
debug!("Loading config at '{:?}'", args.config_path);
|
||||||
|
|
||||||
|
let config = match BotConfig::new(&args.config_path) {
|
||||||
|
Ok(c) => c,
|
||||||
|
Err(err) => {
|
||||||
|
error!("Error loading config: {}", err);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
start_bot(config).await;
|
||||||
|
}
|
Loading…
Reference in New Issue