mc_bot v1
This commit is contained in:
parent
866ddec07f
commit
5145ff871a
12 changed files with 1831 additions and 182 deletions
4
.idea/ZMP-bot.iml
generated
4
.idea/ZMP-bot.iml
generated
|
@ -3,9 +3,9 @@
|
|||
<component name="NewModuleRootManager">
|
||||
<content url="file://$MODULE_DIR$">
|
||||
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/commands/T/src" isTestSource="false" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/src/commands/T/target" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/discord/commands/T/src" isTestSource="false" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/target" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/src/discord/commands/T/target" />
|
||||
</content>
|
||||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
|
|
1658
Cargo.lock
generated
1658
Cargo.lock
generated
File diff suppressed because it is too large
Load diff
10
Cargo.toml
10
Cargo.toml
|
@ -6,10 +6,14 @@ edition = "2021"
|
|||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
poise = "0.6.1"
|
||||
azalea = { git = "https://github.com/azalea-rs/azalea.git" }
|
||||
serenity = { version = "0.12.0", default-features = false, features = ["client", "gateway", "model", "rustls_backend", "utils", "framework"] }
|
||||
tokio = { version = "1.21.2", features = ["macros", "rt-multi-thread", "rt"] }
|
||||
poise = "0.6.1"
|
||||
tokio = { version = "1.36.0", features = ["parking_lot", "macros", "rt-multi-thread", "rt"] }
|
||||
|
||||
parking_lot = "0.12.1"
|
||||
anyhow = { version = "1.0.79", features = [] }
|
||||
env_logger = "0.11.2"
|
||||
anyhow = "1.0.75"
|
||||
tracing = "0.1.40"
|
||||
regex = "1.10.2"
|
||||
bevy_log = "0.13.0"
|
93
src/discord.rs
Normal file
93
src/discord.rs
Normal file
|
@ -0,0 +1,93 @@
|
|||
mod commands;
|
||||
|
||||
use poise::{async_trait, serenity_prelude as serenity};
|
||||
use serenity::{client::EventHandler, model::id::UserId, FullEvent};
|
||||
use std::collections::HashSet;
|
||||
use std::convert::Into;
|
||||
|
||||
struct Data {} // User data, which is stored and accessible in all command invocations
|
||||
type Error = Box<dyn std::error::Error + Send + Sync>;
|
||||
type Context<'a> = poise::Context<'a, Data, Error>;
|
||||
struct ReadyHandler;
|
||||
|
||||
#[async_trait]
|
||||
impl EventHandler for ReadyHandler {
|
||||
async fn ready(
|
||||
&self,
|
||||
_: poise::serenity_prelude::Context,
|
||||
ready: poise::serenity_prelude::Ready,
|
||||
) {
|
||||
println!("{} is connected!", ready.user.id);
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) async fn main() {
|
||||
let options = poise::FrameworkOptions {
|
||||
commands: vec![
|
||||
commands::lfg::lfg(),
|
||||
commands::xd::xd(),
|
||||
commands::helpstart::helpstart(),
|
||||
commands::bots::bots(),
|
||||
],
|
||||
manual_cooldowns: true,
|
||||
prefix_options: poise::PrefixFrameworkOptions {
|
||||
prefix: Some("~".into()),
|
||||
..Default::default()
|
||||
},
|
||||
on_error: |error| {
|
||||
Box::pin(async move {
|
||||
match error {
|
||||
poise::FrameworkError::ArgumentParse { error, .. } => {
|
||||
if let Some(error) = error.downcast_ref::<serenity::RoleParseError>() {
|
||||
println!("Found a RoleParseError: {:?}", error);
|
||||
} else {
|
||||
println!("Not a RoleParseError :(");
|
||||
}
|
||||
}
|
||||
other => poise::builtins::on_error(other).await.unwrap(),
|
||||
}
|
||||
})
|
||||
},
|
||||
owners: { HashSet::from([UserId::new(449579075531440128_u64)]) },
|
||||
event_handler: |_ctx, event, _framework, _data| {
|
||||
Box::pin(event_handler(_ctx, event, _framework, _data))
|
||||
},
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
let framework = poise::Framework::builder()
|
||||
.options(options)
|
||||
.setup(move |ctx, _ready, framework| {
|
||||
Box::pin(async move {
|
||||
poise::builtins::register_globally(ctx, &framework.options().commands).await?;
|
||||
Ok(Data {})
|
||||
})
|
||||
})
|
||||
.build();
|
||||
|
||||
let token = std::env::var("DISCORD_TOKEN").unwrap();
|
||||
let intents =
|
||||
serenity::GatewayIntents::non_privileged() | serenity::GatewayIntents::MESSAGE_CONTENT;
|
||||
|
||||
let client = serenity::ClientBuilder::new(token, intents)
|
||||
.framework(framework)
|
||||
.await;
|
||||
if let Err(why) = client.unwrap().start().await
|
||||
{
|
||||
println!("Error starting serenity framework: {:?}", why)
|
||||
};
|
||||
}
|
||||
async fn event_handler(
|
||||
_ctx: &serenity::Context,
|
||||
event: &FullEvent,
|
||||
_framework: poise::FrameworkContext<'_, Data, Error>,
|
||||
_data: &Data,
|
||||
) -> Result<(), Error> {
|
||||
match event {
|
||||
FullEvent::Ready { data_about_bot, .. } => {
|
||||
println!("Logged in as {}", data_about_bot.user.name);
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
Ok(())
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
use crate::commands::{command_helper, helpstart};
|
||||
use crate::{Context, Error};
|
||||
use crate::discord::commands::{command_helper, helpstart};
|
||||
use crate::discord::{Context, Error};
|
||||
use std::string::String;
|
||||
|
||||
#[poise::command(slash_command, guild_only)]
|
|
@ -1,4 +1,4 @@
|
|||
use crate::{Context, Error};
|
||||
use crate::discord::{Context, Error};
|
||||
use serenity::all::CreateAllowedMentions;
|
||||
use std::time::Duration;
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
use crate::commands::command_helper;
|
||||
use crate::{Context, Error};
|
||||
use crate::discord::commands::command_helper;
|
||||
use crate::discord::{Context, Error};
|
||||
|
||||
static mut BOTS_AVAILABLE: u8 = 0;
|
||||
|
|
@ -1,11 +1,10 @@
|
|||
//
|
||||
use crate::commands::lfg::Difficulty::Normal;
|
||||
use crate::commands::lfg::Map::*;
|
||||
use crate::commands::lfg::Mode::*;
|
||||
//from main.rs
|
||||
use crate::{Context, Error};
|
||||
use crate::discord::commands::lfg::Difficulty::Normal;
|
||||
use crate::discord::commands::lfg::Map::*;
|
||||
use crate::discord::commands::lfg::Mode::*;
|
||||
use crate::discord::{Context, Error};
|
||||
//
|
||||
use crate::commands::command_helper;
|
||||
use crate::discord::commands::command_helper;
|
||||
use poise::ChoiceParameter;
|
||||
use serenity::model::mention::Mention;
|
||||
use serenity::model::mention::Mention::Role;
|
|
@ -1,4 +1,4 @@
|
|||
use crate::{Context, Error};
|
||||
use crate::discord::{Context, Error};
|
||||
|
||||
const XD:&str = "⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿\n⣿⣿⣿⡿⠿⠿⠿⠿⠿⠿⠿⢿⣿⣿⣿⣿⡿⠿⠿⠿⠿⠿⠿⠿⢿⡿⠿⠿⠿⠿⠿⠿⠿⠿⠿⠿⠿⠿⠿⢿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿\n⣿⣿⣿⣧⣄⡀⠀⠀⠀⢀⣠⣼⣿⣿⣿⣿⣧⣄⡀⠀⠀⠀⣀⣤⣼⣷⣦⣤⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠉⠛⢿⣿⣿⣿⣿⣿⣿\n⣿⣿⣿⣿⣿⣿⣦⠀⠀⠀⠻⣿⣿⣿⣿⣿⣿⠟⠀⠀⢀⣼⣿⣿⣿⣿⣿⣿⡇⠀⠀⢸⣿⣿⣿⣿⣿⣿⣶⣦⣄⡀⠀⠀⠙⢿⣿⣿⣿⣿\n⣿⣿⣿⣿⣿⣿⣿⣷⡀⠀⠀⠙⣿⣿⣿⣿⠋⠀⠀⣠⣾⣿⣿⣿⣿⣿⣿⣿⡇⠀⠀⢸⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣄⠀⠀⠈⢿⣿⣿⣿\n⣿⣿⣿⣿⣿⣿⣿⣿⣿⣄⠀⠀⠈⢿⡿⠁⠀⠀⣴⣿⣿⣿⣿⣿⣿⣿⣿⣿⡇⠀⠀⢸⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡆⠀⠀⢸⣿⣿⣿\n⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣦⡀⠀⠀⠀⠀⢠⣾⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡇⠀⠀⢸⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡇⠀⠀⠀⣿⣿⣿\n⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡗⠀⠀⠀⠐⢿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡇⠀⠀⢸⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡏⠀⠀⠀⣿⣿⣿\n⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠏⠀⠀⣠⡀⠀⠀⠻⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡇⠀⠀⢸⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡇⠀⠀⢸⣿⣿⣿\n⣿⣿⣿⣿⣿⣿⣿⣿⡿⠃⠀⠀⣰⣿⣷⡄⠀⠀⠘⢿⣿⣿⣿⣿⣿⣿⣿⣿⡇⠀⠀⢸⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡿⠀⠀⠀⣾⣿⣿⣿\n⣿⣿⣿⣿⣿⣿⣿⡟⠁⠀⢀⣼⣿⣿⣿⣿⣆⠀⠀⠈⠻⣿⣿⣿⣿⣿⣿⣿⡇⠀⠀⢸⣿⣿⣿⣿⣿⣿⣿⣿⣿⠟⠁⠀⢀⣼⣿⣿⣿⣿\n⣿⣿⣿⣿⣿⣿⠋⠀⠀⢠⣾⣿⣿⣿⣿⣿⣿⣷⡀⠀⠀⠙⣿⣿⣿⣿⣿⣿⡇⠀⠀⢸⣿⣿⣿⣿⣿⣿⠿⠛⠁⠀⠀⣠⣾⣿⣿⣿⣿⣿\n⣿⣿⣿⠿⠛⠁⠀⠀⠀⠙⠻⣿⣿⣿⣿⣿⡿⠟⠋⠀⠀⠀⠈⠛⠻⡿⠟⠛⠁⠀⠀⠈⠉⠉⠉⠉⠀⠀⠀⠀⣀⣴⣾⣿⣿⣿⣿⣿⣿⣿\n⣿⣿⣿⣶⣶⣶⣶⣶⣶⣶⣶⣿⣿⣿⣿⣿⣷⣶⣶⣶⣶⣶⣶⣶⣶⣷⣶⣶⣶⣶⣶⣶⣶⣶⣶⣶⣶⣶⣾⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿\n⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿\n";
|
||||
|
109
src/main.rs
109
src/main.rs
|
@ -1,91 +1,32 @@
|
|||
mod commands;
|
||||
|
||||
use poise::{async_trait, serenity_prelude as serenity};
|
||||
use serenity::{client::EventHandler, model::id::UserId, FullEvent};
|
||||
use std::collections::HashSet;
|
||||
use std::convert::Into;
|
||||
|
||||
struct Data {} // User data, which is stored and accessible in all command invocations
|
||||
type Error = Box<dyn std::error::Error + Send + Sync>;
|
||||
type Context<'a> = poise::Context<'a, Data, Error>;
|
||||
struct ReadyHandler;
|
||||
|
||||
#[async_trait]
|
||||
impl EventHandler for ReadyHandler {
|
||||
async fn ready(
|
||||
&self,
|
||||
_: poise::serenity_prelude::Context,
|
||||
ready: poise::serenity_prelude::Ready,
|
||||
) {
|
||||
println!("{} is connected!", ready.user.id);
|
||||
}
|
||||
}
|
||||
|
||||
mod minecraft;
|
||||
mod discord;
|
||||
#[tokio::main]
|
||||
async fn main() {
|
||||
let options = poise::FrameworkOptions {
|
||||
commands: vec![
|
||||
commands::lfg::lfg(),
|
||||
commands::xd::xd(),
|
||||
commands::helpstart::helpstart(),
|
||||
commands::bots::bots(),
|
||||
],
|
||||
manual_cooldowns: true,
|
||||
prefix_options: poise::PrefixFrameworkOptions {
|
||||
prefix: Some("~".into()),
|
||||
..Default::default()
|
||||
},
|
||||
on_error: |error| {
|
||||
Box::pin(async move {
|
||||
match error {
|
||||
poise::FrameworkError::ArgumentParse { error, .. } => {
|
||||
if let Some(error) = error.downcast_ref::<serenity::RoleParseError>() {
|
||||
println!("Found a RoleParseError: {:?}", error);
|
||||
} else {
|
||||
println!("Not a RoleParseError :(");
|
||||
/*
|
||||
{
|
||||
use parking_lot::deadlock;
|
||||
use std::thread;
|
||||
use std::time::Duration;
|
||||
|
||||
// Create a background thread which checks for deadlocks every 10s
|
||||
thread::spawn(move || loop {
|
||||
thread::sleep(Duration::from_secs(10));
|
||||
let deadlocks = deadlock::check_deadlock();
|
||||
if deadlocks.is_empty() {
|
||||
continue;
|
||||
}
|
||||
|
||||
println!("{} deadlocks detected", deadlocks.len());
|
||||
for (i, threads) in deadlocks.iter().enumerate() {
|
||||
println!("Deadlock #{i}");
|
||||
for t in threads {
|
||||
println!("Thread Id {:#?}", t.thread_id());
|
||||
println!("{:#?}", t.backtrace());
|
||||
}
|
||||
}
|
||||
other => poise::builtins::on_error(other).await.unwrap(),
|
||||
});
|
||||
}
|
||||
})
|
||||
},
|
||||
owners: { HashSet::from([UserId::new(449579075531440128_u64)]) },
|
||||
event_handler: |_ctx, event, _framework, _data| {
|
||||
Box::pin(event_handler(_ctx, event, _framework, _data))
|
||||
},
|
||||
..Default::default()
|
||||
};
|
||||
*/
|
||||
|
||||
let framework = poise::Framework::builder()
|
||||
.options(options)
|
||||
.setup(move |ctx, _ready, framework| {
|
||||
Box::pin(async move {
|
||||
poise::builtins::register_globally(ctx, &framework.options().commands).await?;
|
||||
Ok(Data {})
|
||||
})
|
||||
})
|
||||
.build();
|
||||
|
||||
let token = std::env::var("DISCORD_TOKEN").unwrap();
|
||||
let intents =
|
||||
serenity::GatewayIntents::non_privileged() | serenity::GatewayIntents::MESSAGE_CONTENT;
|
||||
|
||||
let client = serenity::ClientBuilder::new(token, intents)
|
||||
.framework(framework)
|
||||
.await;
|
||||
client.unwrap().start().await.unwrap()
|
||||
}
|
||||
async fn event_handler(
|
||||
_ctx: &serenity::Context,
|
||||
event: &FullEvent,
|
||||
_framework: poise::FrameworkContext<'_, Data, Error>,
|
||||
_data: &Data,
|
||||
) -> Result<(), Error> {
|
||||
match event {
|
||||
FullEvent::Ready { data_about_bot, .. } => {
|
||||
println!("Logged in as {}", data_about_bot.user.name);
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
Ok(())
|
||||
let (_dc, _mc) = tokio::join!(discord::main(), minecraft::main());
|
||||
}
|
110
src/minecraft.rs
Normal file
110
src/minecraft.rs
Normal file
|
@ -0,0 +1,110 @@
|
|||
use std::sync::{Arc, Mutex};
|
||||
use std::time::Duration;
|
||||
use azalea::{swarm::prelude::*, protocol::ServerAddress, ClientInformation, prelude::*, DefaultPlugins, DefaultBotPlugins};
|
||||
use azalea::app::PluginGroup;
|
||||
use azalea::protocol::packets::configuration::serverbound_client_information_packet::{ChatVisibility, HumanoidArm, ModelCustomization};
|
||||
use azalea::swarm::DefaultSwarmPlugins;
|
||||
|
||||
pub(crate) async fn main() {
|
||||
let account = Account::microsoft(std::env::var("MINECRAFT_MAIL").unwrap().as_str())
|
||||
.await
|
||||
.unwrap();
|
||||
let address = ServerAddress::try_from("mc.hypixel.net:25565").unwrap();
|
||||
|
||||
let swarm_builder = SwarmBuilder::new_without_plugins()
|
||||
.add_plugins((
|
||||
DefaultPlugins,//.build().disable::<bevy_log::LogPlugin>(),
|
||||
DefaultBotPlugins,
|
||||
DefaultSwarmPlugins
|
||||
|
||||
))
|
||||
.set_handler(handle)
|
||||
.set_swarm_handler(swarm_handle)
|
||||
.set_swarm_state(SwarmState)
|
||||
.add_account_with_state(
|
||||
account,
|
||||
State {
|
||||
..Default::default()
|
||||
},
|
||||
);
|
||||
if let Err(why) = swarm_builder.start(address).await {
|
||||
println!("minecraft error{:?}", why)
|
||||
};
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq, Default)]
|
||||
pub enum BotTask {
|
||||
#[default]
|
||||
None,
|
||||
}
|
||||
|
||||
#[derive(Component, Clone)]
|
||||
pub struct State {
|
||||
pub task: Arc<Mutex<BotTask>>,
|
||||
}
|
||||
|
||||
impl Default for State {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
task: Arc::new(Mutex::new(BotTask::None)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async fn handle(bot: Client, event: Event, state: State) -> anyhow::Result<()> {
|
||||
match event {
|
||||
Event::Init => {
|
||||
bot.set_client_information(ClientInformation {
|
||||
language: "en_US".to_string(),
|
||||
view_distance: 2,
|
||||
chat_visibility: ChatVisibility::Full,
|
||||
chat_colors: true,
|
||||
model_customization: ModelCustomization {
|
||||
cape: true,
|
||||
jacket: true,
|
||||
left_sleeve: true,
|
||||
right_sleeve: true,
|
||||
left_pants: true,
|
||||
right_pants: true,
|
||||
hat: true,
|
||||
},
|
||||
main_hand: HumanoidArm::Right,
|
||||
text_filtering_enabled: false,
|
||||
allows_listing: false,
|
||||
}).await?
|
||||
},
|
||||
Event::Login => {
|
||||
println!("Logged in as {}", bot.profile.name.clone());
|
||||
},
|
||||
_ => {
|
||||
}
|
||||
};
|
||||
match state {
|
||||
_ => {}
|
||||
};
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[derive(Resource, Default, Clone)]
|
||||
struct SwarmState;
|
||||
|
||||
async fn swarm_handle(
|
||||
mut swarm: Swarm,
|
||||
event: SwarmEvent,
|
||||
_state: SwarmState,
|
||||
) -> anyhow::Result<()> {
|
||||
match &event {
|
||||
SwarmEvent::Disconnect(account) => {
|
||||
println!("bot got kicked! {}", account.username);
|
||||
tokio::time::sleep(Duration::from_secs(5)).await;
|
||||
swarm.add_and_retry_forever(account, State::default()).await;
|
||||
},
|
||||
SwarmEvent::Chat(chat) => println!("{}", chat.message().to_ansi()),
|
||||
SwarmEvent::Init => {
|
||||
println!("Swarm initialised")
|
||||
},
|
||||
_ => {}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
Loading…
Add table
Reference in a new issue