Skip to content
This repository has been archived by the owner on Aug 24, 2024. It is now read-only.

Commit

Permalink
Added Discord Chat Relay
Browse files Browse the repository at this point in the history
  • Loading branch information
AS1100K committed Aug 13, 2024
1 parent 5f4babf commit bf33f52
Show file tree
Hide file tree
Showing 9 changed files with 230 additions and 34 deletions.
14 changes: 13 additions & 1 deletion aether-core/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,18 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [Unreleased] 0.3.0-rc.1

### Added
- Added Discord Chat Relay
- Added Discord Notifications for important events

### Changed
- Upgrade dependency `serde_json`

### Removed
- Removed azalea patch i.e. [`better-1.20.6`](https://github.com/as1100k-forks/azalea.git)

## [0.3.0-beta.1] 07-08-2024

### Added
Expand All @@ -19,4 +31,4 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Removed
- Removed Integration with `azalea_discord` [#22](https://github.com/AS1100K/aether/pull/22)

_For previous Changelog, you need to do `git blame`_
_For previous Changelog, you need to do `git blame`_
14 changes: 7 additions & 7 deletions aether-core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,18 +20,18 @@ panic = "abort"
[dependencies]
anyhow = "1.0.83"
azalea = { package = "multi-azalea", path = "../multi-azalea" }
azalea-task-manager = { path = "../plugins/task-manager", features = ["anti-afk"] }
azalea-task-manager = { path = "../plugins/task-manager", features = [
"anti-afk",
] }
azalea-anti-afk = { path = "../plugins/anti-afk" }
azalea-utility = { path = "../plugins/utility" }
# TODO: Migrate to bevy_discord
#azalea-discord = { git = "https://github.com/as1100k/aether", tag = "azalea-discord@v0.1.0", features = ["chat-bridge", "log-bridge"] }
bevy-discord = { git = "https://github.com/as1100k/bevy-discord", rev = "c554e1d", features = [
"full",
] }
serde = { version = "1.0.203", features = ["derive"] }
serde_json = "1.0.117"
serde_json = "1.0.124"
tokio = { version = "1.37.0", features = ["macros"] }
parking_lot = "0.12.2"
tracing = "0.1.40"
rand = "0.8.5"
regex = "1.10.4"

[patch."https://github.com/azalea-rs/azalea.git"]
azalea = { git = "https://github.com/as1100k-forks/azalea.git", branch = "better-1.20.6" }
9 changes: 7 additions & 2 deletions aether-core/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,14 @@

This bot is created to server the main purpose of loading the pearl on 2b2t.

## Discord Bot

For the discord bot to be working you need to turn on `Message Content Intent` under the `Bot` Page.
To add the bot to your discord server, visit this url: `https://discord.com/api/oauth2/authorize?client_id=<APPLICATION ID>`

## TODOs

- [ ] Migrate to bevy-discord
- [x] Migrate to bevy-discord
- [ ] Add Bots via discord with certain roles
- [ ] Add More Roles like `Storage Manager`, `AFK at Farms`, etc.
- [ ] Update `config.json` via commands
- [ ] Update `config.json` via commands
11 changes: 6 additions & 5 deletions aether-core/config.example.json
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
{
"server": "10.9.12.13",
"members": [
"AS1100K"
],
"members": ["AS1100K"],
"discord_bot_token": "<your discord application token>",
"bots": [
{
"username": "_aether",
Expand All @@ -16,7 +15,9 @@
"owner": "AS1100K",
"cords": [376, 71, 83]
}
]
],
"chat_relay_channel_id": "<Channel ID for the channel you want the bot to send messages>",
"channel_id": "<Channel ID where the bot will send important notification and receive commands>"
},
{
"username": "_aether_2",
Expand All @@ -25,4 +26,4 @@
}
],
"version": 2
}
}
68 changes: 59 additions & 9 deletions aether-core/src/chat.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,24 @@ use std::time::Instant;

use azalea::app::{App, Plugin};
use azalea::chat::{ChatReceivedEvent, SendChatEvent};
use azalea::ecs::prelude::*;
use azalea::entity::metadata::Player;
use azalea::entity::LocalEntity;
use azalea::prelude::*;
use azalea::ecs::prelude::*;
use azalea_anti_afk::config::AntiAFKConfig;
use azalea_anti_afk::AntiAFK;
use azalea_utility::auto_eat::{StartAutoEat, StopAutoEat};
use azalea_utility::auto_totem::AutoTotem;
use bevy_discord::bot::serenity::all::ChannelId;
use bevy_discord::bot::DiscordBotRes;
use bevy_discord::runtime::tokio_runtime;
use serde_json::json;
use tracing::error;

use crate::command::AetherCommand;
use crate::commands::pearl::load::LoadPearl;
use crate::config::{Bot, Config};
use crate::discord::{DiscordChannelId, DiscordChatRelay};
use crate::utils::{parse_chat_content, InWorld};

pub struct ChatPlugin;
Expand All @@ -25,15 +31,16 @@ impl Plugin for ChatPlugin {
}

#[allow(clippy::complexity)]
fn handle_chat(
pub fn handle_chat(
mut events: EventReader<ChatReceivedEvent>,
query: Query<(&Bot, Option<&InWorld>), (With<Player>, With<LocalEntity>)>,
config: Res<Config>,
discord_bot_res: Option<Res<DiscordBotRes>>,
mut commands: Commands,
mut send_chat_event: EventWriter<SendChatEvent>,
mut load_pearl: EventWriter<LoadPearl>,
mut start_auto_eat: EventWriter<StartAutoEat>,
mut stop_auto_eat: EventWriter<StopAutoEat>
mut stop_auto_eat: EventWriter<StopAutoEat>,
) {
for ChatReceivedEvent { entity, packet } in events.read() {
for (state, in_world) in query.iter() {
Expand Down Expand Up @@ -87,13 +94,56 @@ fn handle_chat(
});
commands.entity(*entity).insert(AutoTotem);
start_auto_eat.send(StartAutoEat {
use_inventory: true
use_inventory: true,
});
} else if content == "You have lost connection to the server" {
commands.entity(*entity).remove::<InWorld>();
commands.entity(*entity).remove::<AntiAFK>();
commands.entity(*entity).remove::<AutoTotem>();
stop_auto_eat.send(StopAutoEat);

if let Some(discord_bot) = &discord_bot_res {
if let Some(chat_relay_channel_id) = state.chat_relay_channel_id {
// Add `DiscordChatRelay` Component
commands.entity(*entity).insert(DiscordChatRelay {
channel_id: ChannelId::new(chat_relay_channel_id),
});
}

if let Some(channel_id) = state.channel_id
&& let Some(http) = discord_bot.get_http()
{
// Add `DiscordChannelId` Component
commands.entity(*entity).insert(DiscordChannelId {
channel_id: ChannelId::new(channel_id),
});

// Send a Notification that bot has joined
let channel_id_clone = channel_id.clone();
let state_clone = state.clone();
tokio_runtime().spawn(async move {
if let Err(e) = http
.send_message(
ChannelId::new(channel_id_clone),
Vec::new(),
&json!({
"embeds": [
{
"title": "Bot Connected!",
"description": format!("Username: {} \n Role: {:?}", &state_clone.username, &state_clone.role)
}
]
}),
)
.await
{
error!("Unable to send joined notification to discord, {:?}", e);
}
});
}
} else if content == "You have lost connection to the server" {
commands.entity(*entity).remove::<InWorld>();
commands.entity(*entity).remove::<AntiAFK>();
commands.entity(*entity).remove::<AutoTotem>();
stop_auto_eat.send(StopAutoEat);
commands.entity(*entity).remove::<DiscordChatRelay>();
commands.entity(*entity).remove::<DiscordChannelId>();
}
}
}
}
Expand Down
11 changes: 11 additions & 0 deletions aether-core/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ pub struct Config {
pub server: String,
pub members: Vec<String>,
pub bots: HashMap<String, Bot>,
pub discord_bot_token: Option<String>,
}

#[derive(Serialize, Deserialize)]
Expand All @@ -18,6 +19,7 @@ struct RawConfig {
members: Vec<String>,
bots: Vec<RawBot>,
version: u8,
discord_bot_token: Option<String>,
}

#[derive(Serialize, Deserialize)]
Expand Down Expand Up @@ -52,6 +54,8 @@ struct RawBot {
pearl_locations: Option<Vec<RawLocation>>,
chat_bridge: Option<String>,
queue_bridge: Option<String>,
chat_relay_channel_id: Option<u64>,
channel_id: Option<u64>,
}

#[derive(Component, Clone, Default, Debug)]
Expand All @@ -63,6 +67,8 @@ pub struct Bot {
pub role: Role,
pub afk_location: Option<BlockPos>,
pub pearl_locations: Option<HashMap<String, BlockPos>>,
pub chat_relay_channel_id: Option<u64>,
pub channel_id: Option<u64>,
}

impl Default for Config {
Expand Down Expand Up @@ -110,6 +116,8 @@ impl Default for Config {
role: raw_bots.role,
afk_location: Option::from(afk_location_block_pos),
pearl_locations: Option::from(pearl_locations_hash_map),
chat_relay_channel_id: raw_bots.chat_relay_channel_id,
channel_id: raw_bots.channel_id,
},
);
}
Expand All @@ -124,6 +132,8 @@ impl Default for Config {
role: raw_bots.role,
afk_location: None,
pearl_locations: None,
chat_relay_channel_id: raw_bots.chat_relay_channel_id,
channel_id: raw_bots.channel_id,
},
);
}
Expand All @@ -134,6 +144,7 @@ impl Default for Config {
server: raw_config.server,
members: raw_config.members,
bots,
discord_bot_token: raw_config.discord_bot_token,
}
}
}
Expand Down
97 changes: 97 additions & 0 deletions aether-core/src/discord.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
use azalea::app::{Plugin, Update};
use azalea::chat::{ChatPacketKind, ChatReceivedEvent, SendChatKindEvent};
use azalea::ecs::prelude::*;
use azalea::entity::metadata::Player;
use azalea::entity::LocalEntity;
use azalea::prelude::*;
use bevy_discord::bot::events::BMessage;
use bevy_discord::bot::serenity::all::ChannelId;
use bevy_discord::bot::DiscordBotRes;
use bevy_discord::runtime::tokio_runtime;
use serde_json::json;
use tracing::error;

use crate::chat::handle_chat;
use crate::config::Bot;

pub struct AetherDiscordPlugin;

/// Component present when `chat_relay` is turned on
#[derive(Component)]
pub struct DiscordChatRelay {
pub channel_id: ChannelId,
}

/// Component present when `channel_id` is passed in `config.json`
#[derive(Component)]
pub struct DiscordChannelId {
pub channel_id: ChannelId,
}

impl Plugin for AetherDiscordPlugin {
fn build(&self, app: &mut azalea::app::App) {
app.add_systems(
Update,
(handle_chat_relay, handle_discord_bridge)
.chain()
.after(handle_chat),
);
}
}

#[allow(clippy::complexity)]
fn handle_chat_relay(
mut events: EventReader<ChatReceivedEvent>,
query: Query<(&DiscordChatRelay, &Bot), (With<Player>, With<LocalEntity>)>,
discord_bot_res: Res<DiscordBotRes>,
) {
for ChatReceivedEvent { entity: _, packet } in events.read() {
for (DiscordChatRelay { channel_id }, state) in query.iter() {
let (sender, message) = packet.split_sender_and_content();
let sender = sender.unwrap_or("Server".to_string());

if sender != state.username
&& let Some(http) = discord_bot_res.get_http()
{
let channel_id_clone = channel_id.clone();
tokio_runtime().spawn(async move {
if http
.send_message(
channel_id_clone,
Vec::new(),
&json!({
"content": format!("{} -> {}", sender, message)
}),
)
.await
.is_err()
{
error!("Unable to send message on discord");
}
});
}
}
}
}

fn handle_discord_bridge(
mut events: EventReader<BMessage>,
query: Query<(&DiscordChatRelay, Entity), (With<Player>, With<LocalEntity>)>,
mut send_chat_kind_event: EventWriter<SendChatKindEvent>,
) {
for BMessage {
ctx: _,
new_message,
} in events.read()
{
for (DiscordChatRelay { channel_id }, entity) in query.iter() {
if !new_message.author.bot && &new_message.channel_id == channel_id {
send_chat_kind_event.send(SendChatKindEvent {
entity,
content: new_message.content.to_owned(),
kind: ChatPacketKind::Message,
});
}
}
}
}
Loading

0 comments on commit bf33f52

Please sign in to comment.