Compare commits

...

5 Commits

12 changed files with 105 additions and 50 deletions

10
Cargo.lock generated
View File

@ -593,14 +593,6 @@ dependencies = [
"uuid",
]
[[package]]
name = "azalea-hax"
version = "0.1.0"
source = "git+https://github.com/azalea-rs/azalea-hax#2af9e0759aded7df01770b717f207b3c1083f942"
dependencies = [
"azalea",
]
[[package]]
name = "azalea-inventory"
version = "0.11.0+mc1.21.4"
@ -1749,7 +1741,6 @@ version = "0.2.0"
dependencies = [
"anyhow",
"azalea",
"azalea-hax",
"bevy_app",
"bevy_ecs",
"bevy_log",
@ -2971,6 +2962,7 @@ version = "0.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e27119e566a60f5681eb8d05f51ef10862dd9af611ac6c6e0dc9aa9bf3bcc493"
dependencies = [
"anyhow",
"anymap2",
"aquamarine",
"as_variant",

View File

@ -21,7 +21,6 @@ built = { git = "https://github.com/lukaslueg/built", features = ["git2"] }
[dependencies]
anyhow = "1"
azalea = { git = "https://github.com/azalea-rs/azalea" }
azalea-hax = { git = "https://github.com/azalea-rs/azalea-hax" }
bevy_app = "0"
bevy_ecs = "0"
bevy_log = "0"
@ -35,7 +34,7 @@ http-body-util = "0"
hyper = { version = "1", features = ["server"] }
hyper-util = "0"
log = { version = "0" }
matrix-sdk = { version = "0", optional = true }
matrix-sdk = { version = "0", features = ["anyhow"], optional = true }
mimalloc = { version = "0", optional = true }
mlua = { version = "0", features = ["async", "luajit", "send"] }
ncr = { version = "0", features = ["cfb8", "ecb", "gcm"] }

View File

@ -304,7 +304,7 @@ where
let data = data.clone();
tokio::spawn(async move {
if let Err(error) = callback.call_async::<()>(data).await {
error!("failed to call lua event listener {id} for {event_type}: {error:?}");
error!("failed to call lua event listener {id} for {event_type}: {error}");
}
});
}

View File

@ -0,0 +1,20 @@
use azalea::{
Vec3,
movement::{KnockbackEvent, KnockbackType},
prelude::Component,
};
use bevy_ecs::{event::EventMutator, query::With, system::Query};
#[derive(Component)]
pub struct AntiKnockback;
pub fn anti_knockback(
mut events: EventMutator<KnockbackEvent>,
entity_query: Query<(), With<AntiKnockback>>,
) {
for event in events.read() {
if entity_query.get(event.entity).is_ok() {
event.knockback = KnockbackType::Add(Vec3::default());
}
}
}

21
src/hacks/mod.rs Normal file
View File

@ -0,0 +1,21 @@
#![allow(clippy::needless_pass_by_value)]
pub mod anti_knockback;
use anti_knockback::anti_knockback;
use azalea::{movement::handle_knockback, packet_handling::game::process_packet_events};
use bevy_app::{App, Plugin, PreUpdate};
use bevy_ecs::schedule::IntoSystemConfigs;
pub struct HacksPlugin;
impl Plugin for HacksPlugin {
fn build(&self, app: &mut App) {
app.add_systems(
PreUpdate,
anti_knockback
.after(process_packet_events)
.before(handle_knockback),
);
}
}

View File

@ -12,27 +12,30 @@ pub async fn serve(
request: Request<Incoming>,
state: State,
) -> Result<Response<BoxBody<Bytes, Error>>, Error> {
macro_rules! handle_code {
($handler:ident) => {
match std::str::from_utf8(&request.into_body().collect().await?.to_bytes()) {
Ok(code) => Response::new(full(format!(
"{:#?}",
$handler(&state.lua, code, None).await
))),
Err(error) => status_code_response(
StatusCode::BAD_REQUEST,
full(format!("invalid utf-8 data received: {error:?}")),
),
}
};
}
Ok(match (request.method(), request.uri().path()) {
(&Method::POST, "/reload") => {
Response::new(full(format!("{:#?}", reload(&state.lua, None))))
}
(&Method::POST, "/eval") => handle_code!(eval),
(&Method::POST, "/exec") => handle_code!(exec),
(&Method::POST, "/eval") => match eval(
&state.lua,
&String::from_utf8_lossy(&request.into_body().collect().await?.to_bytes()),
None,
)
.await
{
Ok(value) => status_code_response(StatusCode::OK, full(value.to_string())),
Err(error) => status_code_response(StatusCode::BAD_REQUEST, full(error.to_string())),
},
(&Method::POST, "/exec") => match exec(
&state.lua,
&String::from_utf8_lossy(&request.into_body().collect().await?.to_bytes()),
None,
)
.await
{
Ok(()) => status_code_response(StatusCode::OK, empty()),
Err(error) => status_code_response(StatusCode::BAD_REQUEST, full(error.to_string())),
},
(&Method::GET, "/ping") => Response::new(full("pong!")),
_ => status_code_response(StatusCode::NOT_FOUND, empty()),
})

View File

@ -1,3 +1,5 @@
use crate::hacks::anti_knockback::AntiKnockback;
use super::Client;
use azalea::{
ClientInformation,
@ -5,7 +7,6 @@ use azalea::{
pathfinder::PathfinderDebugParticles,
protocol::common::client_information::ModelCustomization,
};
use azalea_hax::AntiKnockback;
use mlua::{Error, Lua, Result, Table, UserDataRef};
pub fn air_supply(_lua: &Lua, client: &Client) -> Result<i32> {

View File

@ -8,7 +8,6 @@ use mlua::{Lua, Result, Table};
pub fn best_tool_for_block(lua: &Lua, client: &Client, block_state: u16) -> Result<Table> {
let result = client.best_tool_in_hotbar_for_block(BlockState { id: block_state });
let table = lua.create_table()?;
table.set("index", result.index)?;
table.set("percentage_per_tick", result.percentage_per_tick)?;

View File

@ -15,10 +15,12 @@ pub mod matrix;
use crate::{ListenerMap, build_info::built};
use mlua::{Lua, Table};
use std::io;
use std::{
fmt::{self, Display, Formatter},
io,
};
#[derive(Debug)]
#[allow(dead_code)]
pub enum Error {
CreateEnv(mlua::Error),
EvalChunk(mlua::Error),
@ -28,6 +30,23 @@ pub enum Error {
ReadFile(io::Error),
}
impl Display for Error {
fn fmt(&self, formatter: &mut Formatter<'_>) -> fmt::Result {
write!(
formatter,
"failed to {}",
match self {
Error::CreateEnv(error) => format!("create environment: {error}"),
Error::EvalChunk(error) => format!("evaluate chunk: {error}"),
Error::ExecChunk(error) => format!("execute chunk: {error}"),
Error::LoadChunk(error) => format!("load chunk: {error}"),
Error::MissingPath(error) => format!("get SCRIPT_PATH global: {error}"),
Error::ReadFile(error) => format!("read script file: {error}"),
}
)
}
}
pub fn register_globals(
lua: &Lua,
globals: &Table,

View File

@ -4,6 +4,7 @@ mod arguments;
mod build_info;
mod commands;
mod events;
mod hacks;
mod http;
mod lua;
mod particle;
@ -17,7 +18,6 @@ use arguments::Arguments;
use azalea::{
DefaultBotPlugins, DefaultPlugins, brigadier::prelude::CommandDispatcher, prelude::*,
};
use azalea_hax::HaxPlugin;
use bevy_app::PluginGroup;
use bevy_log::{
LogPlugin,
@ -27,6 +27,7 @@ use clap::Parser;
use commands::{CommandSource, register};
use futures::lock::Mutex;
use futures_locks::RwLock;
use hacks::HacksPlugin;
use log::debug;
use mlua::{Function, Lua, Table};
use replay::{plugin::RecordPlugin, recorder::Recorder};
@ -130,7 +131,7 @@ async fn main() -> anyhow::Result<()> {
let Err(error) = ClientBuilder::new_without_plugins()
.add_plugins(DefaultBotPlugins)
.add_plugins(HaxPlugin)
.add_plugins(HacksPlugin)
.add_plugins(default_plugins)
.add_plugins(record_plugin)
.set_handler(events::handle_event)

View File

@ -1,4 +1,4 @@
use super::MatrixContext;
use super::Context;
use crate::{
events::call_listeners,
lua::{self, matrix::room::Room as LuaRoom},
@ -19,7 +19,7 @@ use tokio::time::sleep;
pub async fn on_regular_room_message(
event: OriginalSyncRoomMessageEvent,
room: Room,
ctx: Ctx<MatrixContext>,
ctx: Ctx<Context>,
) -> Result<()> {
if room.state() != RoomState::Joined {
return Ok(());
@ -49,16 +49,16 @@ pub async fn on_regular_room_message(
match split.0.unwrap_or(body).to_lowercase().as_str() {
"reload" => output = Some(format!("{:#?}", lua::reload(&ctx.state.lua, None))),
"eval" if let Some(code) = code => {
output = Some(format!(
"{:#?}",
lua::eval(&ctx.state.lua, code, None).await
));
output = Some(match lua::eval(&ctx.state.lua, code, None).await {
Ok(value) => value.to_string(),
Err(error) => error.to_string(),
});
}
"exec" if let Some(code) = code => {
output = Some(format!(
"{:#?}",
lua::exec(&ctx.state.lua, code, None).await
));
output = Some(match lua::exec(&ctx.state.lua, code, None).await {
Ok(()) => String::from("ok"),
Err(error) => error.to_string(),
});
}
"ping" => {
room.send(RoomMessageEventContent::text_plain("pong!"))
@ -90,7 +90,7 @@ pub async fn on_stripped_state_member(
member: StrippedRoomMemberEvent,
client: Client,
room: Room,
ctx: Ctx<MatrixContext>,
ctx: Ctx<Context>,
) -> Result<()> {
if let Some(user_id) = client.user_id()
&& member.state_key == user_id

View File

@ -2,7 +2,7 @@ mod bot;
mod verification;
use crate::{State, lua::matrix::client::Client as LuaClient};
use anyhow::{Context, Result};
use anyhow::{Context as _, Result};
use bot::{on_regular_room_message, on_stripped_state_member};
use log::{error, warn};
use matrix_sdk::{
@ -15,7 +15,7 @@ use tokio::fs;
use verification::{on_device_key_verification_request, on_room_message_verification_request};
#[derive(Clone)]
pub struct MatrixContext {
pub struct Context {
state: State,
name: String,
}
@ -62,8 +62,8 @@ pub async fn login(
let client = builder.build().await?;
let mut new_session;
let session_file = root_dir.join("session.json");
let mut sync_settings = SyncSettings::default();
let session_file = root_dir.join("session.json");
if let Some(session) = fs::read_to_string(&session_file)
.await
.ok()
@ -88,7 +88,7 @@ pub async fn login(
fs::write(&session_file, serde_json::to_string(&new_session)?).await?;
}
client.add_event_handler_context(MatrixContext { state, name });
client.add_event_handler_context(Context { state, name });
client.add_event_handler(on_stripped_state_member);
loop {
match client.sync_once(sync_settings.clone()).await {