Added commands + persistence
+ `say`: used by the host to speak in the game chat + `end`: ends the game and cleans up + `broadcast`: Send an important game message that that is pinned in each channel + Persistent allows games to continue across bot restarts + clippy + fmtmsg_refactor
parent
fd878c3721
commit
e72d603149
|
@ -1,3 +1,4 @@
|
||||||
/target
|
/target
|
||||||
config.toml
|
config.toml
|
||||||
|
wOxlf_data.toml
|
||||||
.idea
|
.idea
|
||||||
|
|
|
@ -1729,6 +1729,7 @@ dependencies = [
|
||||||
"serenity",
|
"serenity",
|
||||||
"structopt",
|
"structopt",
|
||||||
"tokio",
|
"tokio",
|
||||||
|
"toml",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
|
@ -11,6 +11,7 @@ structopt = "0.3.26"
|
||||||
chrono = "0.4.19"
|
chrono = "0.4.19"
|
||||||
serde = "1.0.136"
|
serde = "1.0.136"
|
||||||
rand = "0.8.5"
|
rand = "0.8.5"
|
||||||
|
toml = "0.5.8"
|
||||||
|
|
||||||
[dependencies.serenity]
|
[dependencies.serenity]
|
||||||
version = "0.10.10"
|
version = "0.10.10"
|
||||||
|
|
154
src/commands.rs
154
src/commands.rs
|
@ -1,18 +1,19 @@
|
||||||
use serenity::prelude::Context;
|
use crate::data::{BotConfig, GlobalData, MessageSource, PlayerData};
|
||||||
use serenity::model::prelude::{Message, UserId};
|
use crate::helper::{clear_game_state, save_game_state, send_msg_to_player_channels};
|
||||||
use serenity::framework::standard::{CommandResult, Args};
|
|
||||||
use serenity::framework::StandardFramework;
|
|
||||||
use serenity::framework::standard::macros::{command, group};
|
|
||||||
use crate::data::{GlobalData, BotConfig, PlayerData};
|
|
||||||
use rand::Rng;
|
use rand::Rng;
|
||||||
use serenity::model::guild::{Member, Guild};
|
use serenity::framework::standard::macros::{command, group};
|
||||||
use serenity::model::id::ChannelId;
|
use serenity::framework::standard::{Args, CommandResult};
|
||||||
use serenity::model::Permissions;
|
use serenity::framework::StandardFramework;
|
||||||
use serenity::model::channel::{PermissionOverwrite, PermissionOverwriteType};
|
use serenity::model::channel::{PermissionOverwrite, PermissionOverwriteType};
|
||||||
|
use serenity::model::guild::{Guild, Member};
|
||||||
|
use serenity::model::id::ChannelId;
|
||||||
|
use serenity::model::prelude::{Message, UserId};
|
||||||
|
use serenity::model::Permissions;
|
||||||
|
use serenity::prelude::Context;
|
||||||
use serenity::utils::MessageBuilder;
|
use serenity::utils::MessageBuilder;
|
||||||
|
|
||||||
#[group]
|
#[group]
|
||||||
#[commands(start)]
|
#[commands(start, say, end, broadcast)]
|
||||||
struct Host;
|
struct Host;
|
||||||
|
|
||||||
fn generate_codename(config: &BotConfig) -> String {
|
fn generate_codename(config: &BotConfig) -> String {
|
||||||
|
@ -24,21 +25,28 @@ fn generate_codename(config: &BotConfig) -> String {
|
||||||
format!("{} {}", adj, occupation)
|
format!("{} {}", adj, occupation)
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn add_user_to_game(ctx: &Context, guild: &Guild, global_data: &mut GlobalData, discord_user: &Member) {
|
async fn add_user_to_game(
|
||||||
|
ctx: &Context,
|
||||||
|
guild: &Guild,
|
||||||
|
global_data: &mut GlobalData,
|
||||||
|
discord_user: &Member,
|
||||||
|
) -> CommandResult {
|
||||||
let mut codename = generate_codename(&global_data.cfg);
|
let mut codename = generate_codename(&global_data.cfg);
|
||||||
|
|
||||||
while global_data.game_state.codename_exists(&mut codename) {
|
while global_data.game_state.codename_exists(&codename) {
|
||||||
codename = generate_codename(&global_data.cfg);
|
codename = generate_codename(&global_data.cfg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let channel = guild
|
||||||
|
.create_channel(&ctx.http, |c| {
|
||||||
|
c.category(&ChannelId::from(global_data.cfg.category))
|
||||||
|
.name(format!("{}'s Channel", discord_user.display_name()))
|
||||||
|
})
|
||||||
|
.await?;
|
||||||
|
|
||||||
let channel = guild.create_channel(&ctx.http, |c| {
|
let allow = Permissions::SEND_MESSAGES
|
||||||
c
|
| Permissions::READ_MESSAGE_HISTORY
|
||||||
.category(&ChannelId::from(global_data.cfg.category))
|
| Permissions::READ_MESSAGE_HISTORY;
|
||||||
.name(format!("{}'s Channel", discord_user.display_name()))
|
|
||||||
}).await.unwrap();
|
|
||||||
|
|
||||||
let allow = Permissions::SEND_MESSAGES | Permissions::READ_MESSAGE_HISTORY | Permissions::READ_MESSAGE_HISTORY;
|
|
||||||
|
|
||||||
let overwrite = PermissionOverwrite {
|
let overwrite = PermissionOverwrite {
|
||||||
allow,
|
allow,
|
||||||
|
@ -46,7 +54,7 @@ async fn add_user_to_game(ctx: &Context, guild: &Guild, global_data: &mut Global
|
||||||
kind: PermissionOverwriteType::Member(discord_user.user.id),
|
kind: PermissionOverwriteType::Member(discord_user.user.id),
|
||||||
};
|
};
|
||||||
|
|
||||||
channel.create_permission(&ctx.http, &overwrite).await.unwrap();
|
channel.create_permission(&ctx.http, &overwrite).await?;
|
||||||
|
|
||||||
let msg = channel.send_message(&ctx.http, |m| {
|
let msg = channel.send_message(&ctx.http, |m| {
|
||||||
m.content(MessageBuilder::new()
|
m.content(MessageBuilder::new()
|
||||||
|
@ -59,18 +67,20 @@ async fn add_user_to_game(ctx: &Context, guild: &Guild, global_data: &mut Global
|
||||||
.push("SUBJECT CODENAME: ")
|
.push("SUBJECT CODENAME: ")
|
||||||
.push_line(&codename)
|
.push_line(&codename)
|
||||||
)
|
)
|
||||||
}).await.unwrap();
|
}).await?;
|
||||||
|
|
||||||
channel.pin(&ctx.http, msg.id).await.unwrap();
|
channel.pin(&ctx.http, msg.id).await?;
|
||||||
|
|
||||||
let player_data = PlayerData {
|
let player_data = PlayerData {
|
||||||
|
channel: channel.id.0,
|
||||||
discord_id: discord_user.user.id.0,
|
discord_id: discord_user.user.id.0,
|
||||||
codename: codename
|
codename,
|
||||||
};
|
};
|
||||||
|
|
||||||
global_data.game_state.player_channels.insert(channel.id.0, player_data);
|
global_data.game_state.player_data.push(player_data);
|
||||||
}
|
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
#[command]
|
#[command]
|
||||||
#[only_in(guilds)]
|
#[only_in(guilds)]
|
||||||
|
@ -78,33 +88,99 @@ async fn add_user_to_game(ctx: &Context, guild: &Guild, global_data: &mut Global
|
||||||
async fn start(ctx: &Context, msg: &Message, mut args: Args) -> CommandResult {
|
async fn start(ctx: &Context, msg: &Message, mut args: Args) -> CommandResult {
|
||||||
msg.channel_id.say(&ctx.http, "Starting game").await?;
|
msg.channel_id.say(&ctx.http, "Starting game").await?;
|
||||||
|
|
||||||
let mut data = ctx.data.write().await;
|
let mut data = ctx.data.write().await;
|
||||||
let global_data = data.get_mut::<GlobalData>().unwrap();
|
let global_data = data.get_mut::<GlobalData>().unwrap();
|
||||||
let guild = msg.guild(&ctx.cache).await.unwrap();
|
let guild = msg.guild(&ctx.cache).await.unwrap();
|
||||||
|
|
||||||
let mut global_data = global_data.lock().await;
|
let mut global_data = global_data.lock().await;
|
||||||
|
|
||||||
global_data.game_state.clear();
|
clear_game_state(&mut global_data).unwrap();
|
||||||
|
|
||||||
for player in args.iter::<u64>() {
|
for player in args.iter::<u64>().flatten() {
|
||||||
if let Ok(player) = player {
|
if let Some(discord_user) = guild.members.get(&UserId::from(player)) {
|
||||||
if let Some(discord_user) = guild.members.get(&UserId::from(player)) {
|
add_user_to_game(ctx, &guild, &mut global_data, discord_user).await?;
|
||||||
add_user_to_game(ctx, &guild, &mut global_data, &discord_user).await;
|
} else {
|
||||||
}
|
msg.reply(
|
||||||
else {
|
&ctx.http,
|
||||||
msg.reply(&ctx.http,format!("User {} is invalid or not in this server!", player)).await.unwrap();
|
format!("User {} is invalid or not in this server!", player),
|
||||||
break;
|
)
|
||||||
}
|
.await?;
|
||||||
|
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
save_game_state(&global_data).unwrap();
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[command]
|
||||||
|
#[only_in(guilds)]
|
||||||
|
#[allowed_roles("wolfx host")]
|
||||||
|
async fn end(ctx: &Context, msg: &Message, mut _args: Args) -> CommandResult {
|
||||||
|
let mut data = ctx.data.write().await;
|
||||||
|
let global_data = data.get_mut::<GlobalData>().unwrap();
|
||||||
|
let guild = msg.guild(&ctx.cache).await.unwrap();
|
||||||
|
|
||||||
|
let mut global_data = global_data.lock().await;
|
||||||
|
|
||||||
|
for player_data in &global_data.game_state.player_data {
|
||||||
|
let channel = guild
|
||||||
|
.channels
|
||||||
|
.get(&ChannelId::from(player_data.channel))
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
channel.delete(&ctx.http).await?;
|
||||||
|
}
|
||||||
|
|
||||||
|
clear_game_state(&mut global_data).unwrap();
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[command]
|
||||||
|
#[only_in(guilds)]
|
||||||
|
#[allowed_roles("wolfx host")]
|
||||||
|
async fn say(ctx: &Context, msg: &Message, args: Args) -> CommandResult {
|
||||||
|
let data = ctx.data.read().await;
|
||||||
|
let global_data = data.get::<GlobalData>().unwrap();
|
||||||
|
let guild = msg.guild(&ctx.cache).await.unwrap();
|
||||||
|
|
||||||
|
let global_data = global_data.lock().await;
|
||||||
|
|
||||||
|
let msg = format!("**wOxlf **> {}", args.rest());
|
||||||
|
|
||||||
|
send_msg_to_player_channels(ctx, &guild, &global_data, MessageSource::Host, &msg, false).await;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[command]
|
||||||
|
#[only_in(guilds)]
|
||||||
|
#[allowed_roles("wolfx host")]
|
||||||
|
async fn broadcast(ctx: &Context, msg: &Message, args: Args) -> CommandResult {
|
||||||
|
let data = ctx.data.read().await;
|
||||||
|
let global_data = data.get::<GlobalData>().unwrap();
|
||||||
|
let guild = msg.guild(&ctx.cache).await.unwrap();
|
||||||
|
|
||||||
|
let global_data = global_data.lock().await;
|
||||||
|
|
||||||
|
let msg = MessageBuilder::new()
|
||||||
|
.push_bold_line("\\*\\*IMPORTANT wOxlf SYSTEM MESSAGE\\*\\*")
|
||||||
|
.push_line("")
|
||||||
|
.push_line(args.rest())
|
||||||
|
.push_line("")
|
||||||
|
.push_bold_line("\\*\\*END OF SYSTEM MESSAGE\\*\\*")
|
||||||
|
.build();
|
||||||
|
|
||||||
|
send_msg_to_player_channels(ctx, &guild, &global_data, MessageSource::Host, &msg, true).await;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn command_framework() -> StandardFramework {
|
pub fn command_framework() -> StandardFramework {
|
||||||
StandardFramework::new()
|
StandardFramework::new()
|
||||||
.configure(|c| {
|
.configure(|c| c.prefix("!"))
|
||||||
c.prefix("!")
|
|
||||||
})
|
|
||||||
.group(&HOST_GROUP)
|
.group(&HOST_GROUP)
|
||||||
}
|
}
|
||||||
|
|
42
src/data.rs
42
src/data.rs
|
@ -1,17 +1,16 @@
|
||||||
use config::{Config, File};
|
use config::{Config, File};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use std::path::Path;
|
|
||||||
use std::collections::HashMap;
|
|
||||||
use serenity::prelude::TypeMapKey;
|
use serenity::prelude::TypeMapKey;
|
||||||
use std::sync::Arc;
|
use std::path::Path;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
|
use std::sync::Arc;
|
||||||
use structopt::StructOpt;
|
use structopt::StructOpt;
|
||||||
use tokio::sync::Mutex;
|
use tokio::sync::Mutex;
|
||||||
|
|
||||||
#[derive(Debug, StructOpt)]
|
#[derive(Debug, StructOpt)]
|
||||||
#[structopt(name = "WOXlf", about = "WOXlf discord bot")]
|
#[structopt(name = "WOXlf", about = "WOXlf discord bot")]
|
||||||
pub struct Args {
|
pub struct Args {
|
||||||
pub cfg_path: PathBuf
|
pub cfg_path: PathBuf,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Deserialize, Serialize, Clone)]
|
#[derive(Debug, Deserialize, Serialize, Clone)]
|
||||||
|
@ -20,8 +19,9 @@ pub struct BotConfig {
|
||||||
pub app_id: u64,
|
pub app_id: u64,
|
||||||
pub host_channel: u64,
|
pub host_channel: u64,
|
||||||
pub category: u64,
|
pub category: u64,
|
||||||
|
pub game_state_dir: PathBuf,
|
||||||
pub occupation: Vec<String>,
|
pub occupation: Vec<String>,
|
||||||
pub adjective: Vec<String>
|
pub adjective: Vec<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl BotConfig {
|
impl BotConfig {
|
||||||
|
@ -32,12 +32,16 @@ impl BotConfig {
|
||||||
|
|
||||||
cfg.try_deserialize()
|
cfg.try_deserialize()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn get_game_state_path(&self) -> PathBuf {
|
||||||
|
self.game_state_dir.join("wOxlf_data.toml")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Deserialize, Serialize, Clone)]
|
#[derive(Debug, Deserialize, Serialize, Clone)]
|
||||||
pub enum Phase {
|
pub enum Phase {
|
||||||
Day,
|
Day,
|
||||||
Night
|
Night,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for Phase {
|
impl Default for Phase {
|
||||||
|
@ -48,41 +52,45 @@ impl Default for Phase {
|
||||||
|
|
||||||
#[derive(Debug, Deserialize, Serialize, Clone, Default, Hash)]
|
#[derive(Debug, Deserialize, Serialize, Clone, Default, Hash)]
|
||||||
pub struct PlayerData {
|
pub struct PlayerData {
|
||||||
|
pub channel: u64,
|
||||||
pub discord_id: u64,
|
pub discord_id: u64,
|
||||||
pub codename: String,
|
pub codename: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Deserialize, Serialize, Clone, Default)]
|
#[derive(Debug, Deserialize, Serialize, Clone, Default)]
|
||||||
pub struct GameState {
|
pub struct GameState {
|
||||||
pub player_channels: HashMap<u64, PlayerData>,
|
|
||||||
pub current_phase: Phase,
|
pub current_phase: Phase,
|
||||||
|
pub player_data: Vec<PlayerData>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl GameState {
|
impl GameState {
|
||||||
pub fn codename_exists(&self, codename: &str) -> bool {
|
pub fn codename_exists(&self, codename: &str) -> bool {
|
||||||
self.player_channels.iter().any(|(_, data)| {
|
self.player_data
|
||||||
data.codename.to_lowercase() == codename
|
.iter()
|
||||||
})
|
.any(|data| data.codename.to_lowercase() == codename)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn clear(&mut self) {
|
pub fn clear(&mut self) {
|
||||||
self.player_channels.clear();
|
self.player_data.clear();
|
||||||
self.current_phase = Phase::Night;
|
self.current_phase = Phase::Night;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn get_player_from_channel(&self, channel_id: u64) -> Option<&PlayerData> {
|
||||||
|
self.player_data.iter().find(|p| p.channel == channel_id)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Deserialize, Serialize, Clone)]
|
#[derive(Debug, Deserialize, Serialize, Clone)]
|
||||||
pub struct GlobalData {
|
pub struct GlobalData {
|
||||||
pub cfg: BotConfig,
|
pub cfg: BotConfig,
|
||||||
pub game_state: GameState
|
pub game_state: GameState,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
impl GlobalData {
|
impl GlobalData {
|
||||||
pub fn new(cfg: BotConfig) -> Self {
|
pub fn new(cfg: BotConfig) -> Self {
|
||||||
Self {
|
Self {
|
||||||
cfg,
|
cfg,
|
||||||
game_state: GameState::default()
|
game_state: GameState::default(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -91,3 +99,9 @@ impl TypeMapKey for GlobalData {
|
||||||
type Value = Arc<Mutex<GlobalData>>;
|
type Value = Arc<Mutex<GlobalData>>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Deserialize, Serialize, Clone)]
|
||||||
|
pub enum MessageSource {
|
||||||
|
Player(u64),
|
||||||
|
Host,
|
||||||
|
Automated,
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,99 @@
|
||||||
|
use crate::data::{GlobalData, MessageSource};
|
||||||
|
use serenity::model::id::UserId;
|
||||||
|
use serenity::model::prelude::ChannelId;
|
||||||
|
use serenity::model::prelude::Guild;
|
||||||
|
use serenity::prelude::Context;
|
||||||
|
use std::fs::File;
|
||||||
|
use std::io::prelude::*;
|
||||||
|
|
||||||
|
pub async fn send_msg_to_player_channels(
|
||||||
|
ctx: &Context,
|
||||||
|
guild: &Guild,
|
||||||
|
global_data: &GlobalData,
|
||||||
|
msg_source: MessageSource,
|
||||||
|
msg: &str,
|
||||||
|
pin: bool,
|
||||||
|
) {
|
||||||
|
for player_data in &global_data.game_state.player_data {
|
||||||
|
if let MessageSource::Player(channel_id) = msg_source {
|
||||||
|
if channel_id == player_data.channel {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let channel = guild
|
||||||
|
.channels
|
||||||
|
.get(&ChannelId::from(player_data.channel))
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
let msg = channel
|
||||||
|
.send_message(&ctx.http, |m| m.content(&msg))
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
if pin {
|
||||||
|
// pin system messages
|
||||||
|
msg.pin(&ctx.http).await.unwrap();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let host_channel = guild
|
||||||
|
.channels
|
||||||
|
.get(&ChannelId::from(global_data.cfg.host_channel))
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
let source = match msg_source {
|
||||||
|
MessageSource::Player(channel_id) => {
|
||||||
|
let discord_id = global_data
|
||||||
|
.game_state
|
||||||
|
.get_player_from_channel(channel_id)
|
||||||
|
.unwrap()
|
||||||
|
.discord_id;
|
||||||
|
let name = guild
|
||||||
|
.members
|
||||||
|
.get(&UserId::from(discord_id))
|
||||||
|
.unwrap()
|
||||||
|
.display_name();
|
||||||
|
|
||||||
|
name.to_string()
|
||||||
|
}
|
||||||
|
MessageSource::Host => "Host".to_string(),
|
||||||
|
MessageSource::Automated => "Automated".to_string(),
|
||||||
|
};
|
||||||
|
|
||||||
|
host_channel
|
||||||
|
.send_message(&ctx.http, |m| m.content(format!("({}): {}", source, msg)))
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn save_game_state(global_data: &GlobalData) -> std::io::Result<()> {
|
||||||
|
let s = toml::to_string_pretty(&global_data.game_state).unwrap();
|
||||||
|
|
||||||
|
let mut file = File::create(global_data.cfg.get_game_state_path())?;
|
||||||
|
|
||||||
|
file.write_all(s.as_bytes())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_game_state(global_data: &mut GlobalData) -> std::io::Result<()> {
|
||||||
|
let mut file = File::open(global_data.cfg.get_game_state_path())?;
|
||||||
|
|
||||||
|
let mut data = String::new();
|
||||||
|
|
||||||
|
file.read_to_string(&mut data)?;
|
||||||
|
|
||||||
|
global_data.game_state = toml::from_str(&data).unwrap();
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn clear_game_state(global_data: &mut GlobalData) -> std::io::Result<()> {
|
||||||
|
global_data.game_state.clear();
|
||||||
|
|
||||||
|
let state_path = global_data.cfg.get_game_state_path();
|
||||||
|
if state_path.exists() {
|
||||||
|
std::fs::remove_file(global_data.cfg.get_game_state_path())?;
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
63
src/main.rs
63
src/main.rs
|
@ -1,15 +1,16 @@
|
||||||
mod data;
|
|
||||||
mod commands;
|
mod commands;
|
||||||
|
mod data;
|
||||||
|
mod helper;
|
||||||
|
|
||||||
use serenity::prelude::*;
|
|
||||||
use serenity::model::prelude::{Message, Ready};
|
|
||||||
use std::sync::Arc;
|
|
||||||
use serenity::client::bridge::gateway::GatewayIntents;
|
|
||||||
use crate::data::{GlobalData, Args, BotConfig};
|
|
||||||
use serenity::async_trait;
|
|
||||||
use crate::commands::command_framework;
|
use crate::commands::command_framework;
|
||||||
|
use crate::data::{Args, BotConfig, GlobalData, MessageSource};
|
||||||
|
use crate::helper::{get_game_state, send_msg_to_player_channels};
|
||||||
|
use serenity::async_trait;
|
||||||
|
use serenity::client::bridge::gateway::GatewayIntents;
|
||||||
|
use serenity::model::prelude::{Message, Ready};
|
||||||
|
use serenity::prelude::*;
|
||||||
|
use std::sync::Arc;
|
||||||
use structopt::StructOpt;
|
use structopt::StructOpt;
|
||||||
use serenity::model::id::ChannelId;
|
|
||||||
|
|
||||||
struct Handler {}
|
struct Handler {}
|
||||||
|
|
||||||
|
@ -20,36 +21,32 @@ impl EventHandler for Handler {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if msg.content.starts_with('!') {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
let data = ctx.data.read().await;
|
let data = ctx.data.read().await;
|
||||||
|
|
||||||
let game_data = data.get::<GlobalData>().unwrap();
|
let game_data = data.get::<GlobalData>().unwrap();
|
||||||
|
|
||||||
let game_data = game_data.lock().await;
|
let game_data = game_data.lock().await;
|
||||||
|
|
||||||
|
if let Some(player_data) = game_data
|
||||||
if let Some(player_data) = game_data.game_state.player_channels.get(&msg.channel_id.0) {
|
.game_state
|
||||||
|
.get_player_from_channel(msg.channel_id.0)
|
||||||
|
{
|
||||||
let guild = msg.guild(&ctx.cache).await.unwrap();
|
let guild = msg.guild(&ctx.cache).await.unwrap();
|
||||||
let user_msg = format!("{} > {}", player_data.codename, msg.content);
|
let user_msg = format!("{} > {}", player_data.codename, msg.content);
|
||||||
|
|
||||||
for (channel, _) in &game_data.game_state.player_channels {
|
send_msg_to_player_channels(
|
||||||
if *channel == msg.channel_id.0 {
|
&ctx,
|
||||||
continue;
|
&guild,
|
||||||
}
|
&game_data,
|
||||||
|
MessageSource::Player(msg.channel_id.0),
|
||||||
let channel = guild.channels.get(&ChannelId::from(*channel)).unwrap();
|
&user_msg,
|
||||||
|
false,
|
||||||
channel.send_message(&ctx.http, |m| {
|
)
|
||||||
m
|
.await;
|
||||||
.content(&user_msg)
|
|
||||||
}).await.unwrap();
|
|
||||||
}
|
|
||||||
|
|
||||||
let host_channel = guild.channels.get(&ChannelId::from(game_data.cfg.host_channel)).unwrap();
|
|
||||||
|
|
||||||
host_channel.send_message(&ctx.http, |m| {
|
|
||||||
m
|
|
||||||
.content(&user_msg)
|
|
||||||
}).await.unwrap();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -64,11 +61,17 @@ async fn main() {
|
||||||
|
|
||||||
let bot_cfg: BotConfig = BotConfig::new(&args.cfg_path).expect("Unable to parse cfg");
|
let bot_cfg: BotConfig = BotConfig::new(&args.cfg_path).expect("Unable to parse cfg");
|
||||||
|
|
||||||
|
let mut global_data = GlobalData::new(bot_cfg.clone());
|
||||||
|
|
||||||
|
if get_game_state(&mut global_data).is_ok() {
|
||||||
|
println!("Resuming game...")
|
||||||
|
}
|
||||||
|
|
||||||
let mut client = Client::builder(&bot_cfg.token)
|
let mut client = Client::builder(&bot_cfg.token)
|
||||||
.event_handler(Handler {})
|
.event_handler(Handler {})
|
||||||
.framework(command_framework())
|
.framework(command_framework())
|
||||||
.intents(GatewayIntents::all())
|
.intents(GatewayIntents::all())
|
||||||
.type_map_insert::<GlobalData>(Arc::new(Mutex::new(GlobalData::new(bot_cfg))))
|
.type_map_insert::<GlobalData>(Arc::new(Mutex::new(global_data)))
|
||||||
.await
|
.await
|
||||||
.expect("Err creating client");
|
.expect("Err creating client");
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue