From 9c3fd897fe5cd3fa812c805ff94e85fc2a3ac532 Mon Sep 17 00:00:00 2001 From: Roman Danilov Date: Sat, 25 Apr 2026 02:57:58 +0500 Subject: [PATCH 01/27] Init beta --- build.gradle.kts | 2 + .../java/com/nekiplay/neoscripts/Main.java | 107 ------ .../nekiplay/neoscripts/annotations/Init.java | 2 - .../neoscripts/events/player/TravelEvent.java | 33 ++ .../neoscripts/mixins/TailRenderMixin.java | 1 - .../neoscripts/mixins/WindowMixin.java | 1 - .../entity/MixinFireworkRocketEntity.java | 20 +- .../mixins/entity/MixinLivingEntity.java | 51 +-- .../entity/MixinLivingEntityRenderer.java | 51 +-- .../mixins/entity/MixinLocalPlayer.java | 74 +--- .../neoscripts/mixins/entity/MixinPlayer.java | 31 +- .../mixins/firmament/ModAnnouncerMixin.java | 1 - .../minecraft/ClientConnectionMixin.java | 49 ++- .../neoscripts/utils/NEURepoManager.java | 1 - .../neoscripts/utils/data/JsonData.java | 1 - .../neoscripts/utils/trackers/PetCache.java | 1 - .../kotlin/com/nekiplay/neoscripts/Main.kt | 126 ++++++ .../neoscripts/events/ApplyInputEvent.kt | 5 + .../events/ExtractRenderStateEvent.kt | 7 + .../nekiplay/neoscripts/events/PacketEvent.kt | 11 + .../neoscripts/events/PlayerTickEvent.kt | 5 + .../neoscripts/events/RaycastHitEvent.kt | 5 + .../nekiplay/neoscripts/events/RenderEvent.kt | 6 + .../neoscripts/events/SyncPosEvent.kt | 5 + .../nekiplay/neoscripts/events/TravelEvent.kt | 5 + .../neoscripts/events/main/Callback.kt | 3 + .../events/main/CancellableEvent.kt | 5 + .../events/main/DoubleCancellableEvent.kt | 5 + .../neoscripts/events/main/DoubleEvent.kt | 3 + .../nekiplay/neoscripts/events/main/Event.kt | 3 + .../neoscripts/events/main/EventBus.kt | 67 ++++ .../lua/objects/player/PlayerObject.kt | 14 +- .../com/nekiplay/neoscripts/utils/MathUtil.kt | 34 ++ .../nekiplay/neoscripts/utils/ServerUtil.kt | 96 +++++ .../utils/aiming/RotationManager.kt | 363 ++++++++++++++++++ .../neoscripts/utils/aiming/Rotations.kt | 10 + .../utils/animation/AnimationUtil.kt | 9 + .../neoscripts/utils/game/InputUtil.kt | 202 ++++++++++ src/main/resources/fabric.mod.json | 5 +- src/main/resources/neoscripts.accesswidener | 10 + 40 files changed, 1138 insertions(+), 292 deletions(-) delete mode 100644 src/main/java/com/nekiplay/neoscripts/Main.java create mode 100644 src/main/java/com/nekiplay/neoscripts/events/player/TravelEvent.java create mode 100644 src/main/kotlin/com/nekiplay/neoscripts/Main.kt create mode 100644 src/main/kotlin/com/nekiplay/neoscripts/events/ApplyInputEvent.kt create mode 100644 src/main/kotlin/com/nekiplay/neoscripts/events/ExtractRenderStateEvent.kt create mode 100644 src/main/kotlin/com/nekiplay/neoscripts/events/PacketEvent.kt create mode 100644 src/main/kotlin/com/nekiplay/neoscripts/events/PlayerTickEvent.kt create mode 100644 src/main/kotlin/com/nekiplay/neoscripts/events/RaycastHitEvent.kt create mode 100644 src/main/kotlin/com/nekiplay/neoscripts/events/RenderEvent.kt create mode 100644 src/main/kotlin/com/nekiplay/neoscripts/events/SyncPosEvent.kt create mode 100644 src/main/kotlin/com/nekiplay/neoscripts/events/TravelEvent.kt create mode 100644 src/main/kotlin/com/nekiplay/neoscripts/events/main/Callback.kt create mode 100644 src/main/kotlin/com/nekiplay/neoscripts/events/main/CancellableEvent.kt create mode 100644 src/main/kotlin/com/nekiplay/neoscripts/events/main/DoubleCancellableEvent.kt create mode 100644 src/main/kotlin/com/nekiplay/neoscripts/events/main/DoubleEvent.kt create mode 100644 src/main/kotlin/com/nekiplay/neoscripts/events/main/Event.kt create mode 100644 src/main/kotlin/com/nekiplay/neoscripts/events/main/EventBus.kt create mode 100644 src/main/kotlin/com/nekiplay/neoscripts/utils/MathUtil.kt create mode 100644 src/main/kotlin/com/nekiplay/neoscripts/utils/ServerUtil.kt create mode 100644 src/main/kotlin/com/nekiplay/neoscripts/utils/aiming/RotationManager.kt create mode 100644 src/main/kotlin/com/nekiplay/neoscripts/utils/aiming/Rotations.kt create mode 100644 src/main/kotlin/com/nekiplay/neoscripts/utils/animation/AnimationUtil.kt create mode 100644 src/main/kotlin/com/nekiplay/neoscripts/utils/game/InputUtil.kt diff --git a/build.gradle.kts b/build.gradle.kts index 747c87be..3f06f7e6 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -82,6 +82,8 @@ dependencies { // Legacy Item DFU (https://maven.azureaaron.net/releases/net/azureaaron/legacy-item-dfu) include(implementation("net.azureaaron:legacy-item-dfu:${property("legacy_item_dfu_version")}")!!) + include(implementation("io.github.classgraph:classgraph:4.8.184")!!) + // ImGUI val imguiVersion = property("imgui_version") as String implementation("io.github.spair:imgui-java-binding:$imguiVersion") diff --git a/src/main/java/com/nekiplay/neoscripts/Main.java b/src/main/java/com/nekiplay/neoscripts/Main.java deleted file mode 100644 index 4fe2a178..00000000 --- a/src/main/java/com/nekiplay/neoscripts/Main.java +++ /dev/null @@ -1,107 +0,0 @@ -package com.nekiplay.neoscripts; - -import com.google.gson.Gson; -import com.google.gson.GsonBuilder; -import com.nekiplay.neoscripts.annotations.Init; -import com.nekiplay.neoscripts.features.commands.impl.LuaCommand; -import com.nekiplay.neoscripts.features.lua.LuaScript; -import com.nekiplay.neoscripts.features.modules.ModuleManager; -import com.nekiplay.neoscripts.utils.Rotations; -import com.nekiplay.neoscripts.utils.Utils; -import com.nekiplay.neoscripts.utils.scheduler.Scheduler; -import com.nekiplay.neoscripts.features.lua.LuaManager; -import net.fabricmc.api.ClientModInitializer; -import net.fabricmc.fabric.api.client.command.v2.ClientCommandRegistrationCallback; -import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents; -import net.fabricmc.loader.api.FabricLoader; -import net.minecraft.ChatFormatting; -import net.minecraft.client.Minecraft; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.io.File; -import java.nio.file.Path; -import java.util.ArrayList; - -public class Main implements ClientModInitializer { - public static final String MOD_ID = "neoscripts"; - public static final Logger LOGGER = LoggerFactory.getLogger(MOD_ID); - public static LuaManager LUA_MANAGER; - public static final Path CONFIG_DIR = FabricLoader.getInstance().getConfigDir().resolve(MOD_ID); - - public static final String PREFIX = ChatFormatting.GRAY + "[" + ChatFormatting.GOLD + "Neo Scripts" + ChatFormatting.GRAY + "] " + ChatFormatting.RESET; - public static final String LOG_PREFIX = "[Neo Scripts] "; - - public static File neuDir; - public static Minecraft mc = Minecraft.getInstance(); - private static Main INSTANCE; - - public static final Gson GSON = new GsonBuilder().setPrettyPrinting().create(); - public static final Gson GSON_COMPACT = new GsonBuilder().create(); - - /** - * Do not instantiate this class. Use {@link #getInstance()} instead. - */ - @Deprecated - public Main() { - INSTANCE = this; - } - - public static Main getInstance() { - return INSTANCE; - } - - public static void saveConfig() { - for (LuaScript script : LUA_MANAGER.getLoadedScripts()) { - LUA_MANAGER.unloadScript(script.getScriptName()); - } - } - - @Override - public void onInitializeClient() { - - neuDir = FabricLoader.getInstance().getConfigDir().resolve("neoscripts").toFile(); - neuDir.mkdirs(); - LUA_MANAGER = new LuaManager(); - File scriptsDir = new File(neuDir, "scripts"); - if (!scriptsDir.exists()) { - scriptsDir.mkdir(); - } - File libsDir = new File(scriptsDir, "libs"); - if (!libsDir.exists()) { - libsDir.mkdir(); - } - - Runtime.getRuntime().addShutdownHook(new Thread(Main::saveConfig)); - - ClientTickEvents.END_CLIENT_TICK.register(this::tick); - ClientCommandRegistrationCallback.EVENT.register(LuaCommand.INSTANCE::register); - - init(); - - ModuleManager.INSTANCE.registerInbuilt(); - - Scheduler.INSTANCE.scheduleCyclic(Utils::update, 20); - Rotations.init(); - } - - /** - * Ticks the scheduler. Called once at the end of every client tick through - * {@link ClientTickEvents#END_CLIENT_TICK}. - * - * @param client the Minecraft client. - */ - public void tick(Minecraft client) { - Scheduler.INSTANCE.tick(); - } - - /** - * This method is responsible for initializing all classes. - * To have your class initialized you must annotate its initializer method with the {@code @Init} annotation. - * At compile time, ASM completely overwrites the content of this method, so adding a call here will do nothing. - * - * @see Init - */ - private static void init() { - } -} diff --git a/src/main/java/com/nekiplay/neoscripts/annotations/Init.java b/src/main/java/com/nekiplay/neoscripts/annotations/Init.java index f991f657..925500db 100644 --- a/src/main/java/com/nekiplay/neoscripts/annotations/Init.java +++ b/src/main/java/com/nekiplay/neoscripts/annotations/Init.java @@ -1,7 +1,5 @@ package com.nekiplay.neoscripts.annotations; -import com.nekiplay.neoscripts.Main; - import java.lang.annotation.*; /** diff --git a/src/main/java/com/nekiplay/neoscripts/events/player/TravelEvent.java b/src/main/java/com/nekiplay/neoscripts/events/player/TravelEvent.java new file mode 100644 index 00000000..bf697111 --- /dev/null +++ b/src/main/java/com/nekiplay/neoscripts/events/player/TravelEvent.java @@ -0,0 +1,33 @@ +package com.nekiplay.neoscripts.events.player; + +import net.fabricmc.fabric.api.event.Event; +import net.fabricmc.fabric.api.event.EventFactory; +import net.minecraft.world.InteractionResult; +import net.minecraft.world.phys.Vec3; + +public class TravelEvent { + public static final Event EVENT = EventFactory.createArrayBacked( + TravelEventCallback.class, + (listeners) -> (event) -> { + for (TravelEventCallback listener : listeners) { + InteractionResult result = listener.update(event); + + if(result != InteractionResult.PASS) { + return result; + } + } + + return InteractionResult.PASS; + } + ); + + public boolean traveled; + + public TravelEvent(boolean traveled) { + this.traveled = traveled; + } + + public interface TravelEventCallback { + InteractionResult update(TravelEvent event); + } +} \ No newline at end of file diff --git a/src/main/java/com/nekiplay/neoscripts/mixins/TailRenderMixin.java b/src/main/java/com/nekiplay/neoscripts/mixins/TailRenderMixin.java index 719a34b2..26a6f565 100644 --- a/src/main/java/com/nekiplay/neoscripts/mixins/TailRenderMixin.java +++ b/src/main/java/com/nekiplay/neoscripts/mixins/TailRenderMixin.java @@ -1,7 +1,6 @@ package com.nekiplay.neoscripts.mixins; import com.mojang.blaze3d.systems.RenderSystem; -import com.nekiplay.neoscripts.Main; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; diff --git a/src/main/java/com/nekiplay/neoscripts/mixins/WindowMixin.java b/src/main/java/com/nekiplay/neoscripts/mixins/WindowMixin.java index 935d1ddb..0034d15f 100644 --- a/src/main/java/com/nekiplay/neoscripts/mixins/WindowMixin.java +++ b/src/main/java/com/nekiplay/neoscripts/mixins/WindowMixin.java @@ -1,7 +1,6 @@ package com.nekiplay.neoscripts.mixins; import com.mojang.blaze3d.platform.Window; -import com.nekiplay.neoscripts.Main; import net.minecraft.client.Minecraft; import net.minecraft.client.main.GameConfig; import org.spongepowered.asm.mixin.Final; diff --git a/src/main/java/com/nekiplay/neoscripts/mixins/entity/MixinFireworkRocketEntity.java b/src/main/java/com/nekiplay/neoscripts/mixins/entity/MixinFireworkRocketEntity.java index ae9aa72c..bcea2f11 100644 --- a/src/main/java/com/nekiplay/neoscripts/mixins/entity/MixinFireworkRocketEntity.java +++ b/src/main/java/com/nekiplay/neoscripts/mixins/entity/MixinFireworkRocketEntity.java @@ -2,6 +2,7 @@ import com.llamalad7.mixinextras.injector.ModifyExpressionValue; import com.nekiplay.neoscripts.utils.Rotations; +import com.nekiplay.neoscripts.utils.aiming.RotationManager; import net.minecraft.client.Minecraft; import net.minecraft.world.entity.LivingEntity; import net.minecraft.world.entity.projectile.FireworkRocketEntity; @@ -9,22 +10,21 @@ import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Redirect; @Mixin(FireworkRocketEntity.class) public abstract class MixinFireworkRocketEntity { - @Shadow - private LivingEntity attachedToEntity; + @Redirect(method = "tick", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/entity/LivingEntity;getLookAngle()Lnet/minecraft/world/phys/Vec3;")) + private Vec3 getLookAngleHook(LivingEntity instance) { + if (!Rotations.movementCorrection) { - @ModifyExpressionValue(method = "tick", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/entity/LivingEntity;getLookAngle()Lnet/minecraft/world/phys/Vec3;")) - private Vec3 getRotationVector(Vec3 original) { - if (attachedToEntity != Minecraft.getInstance().player) { - return original; - } + return instance.calculateViewVector( + RotationManager.INSTANCE.getCurrentPitch(), + RotationManager.INSTANCE.getCurrentYaw() + ); - if (!Rotations.rotating || !Rotations.movementCorrection) { - return original; } - return Vec3.directionFromRotation(Rotations.serverPitch, Rotations.serverYaw); + return instance.getLookAngle(); } } \ No newline at end of file diff --git a/src/main/java/com/nekiplay/neoscripts/mixins/entity/MixinLivingEntity.java b/src/main/java/com/nekiplay/neoscripts/mixins/entity/MixinLivingEntity.java index a7de7b26..fbaa18bb 100644 --- a/src/main/java/com/nekiplay/neoscripts/mixins/entity/MixinLivingEntity.java +++ b/src/main/java/com/nekiplay/neoscripts/mixins/entity/MixinLivingEntity.java @@ -2,53 +2,30 @@ import com.llamalad7.mixinextras.injector.ModifyExpressionValue; import com.nekiplay.neoscripts.utils.Rotations; +import com.nekiplay.neoscripts.utils.aiming.RotationManager; import net.minecraft.client.Minecraft; import net.minecraft.util.Mth; import net.minecraft.world.entity.LivingEntity; import net.minecraft.world.phys.Vec3; import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Unique; import org.spongepowered.asm.mixin.injection.At; +import static com.nekiplay.neoscripts.Main.mc; + @Mixin(LivingEntity.class) public abstract class MixinLivingEntity extends MixinEntity { - @ModifyExpressionValue(method = "jumpFromGround", at = @At(value = "NEW", target = "(DDD)Lnet/minecraft/world/phys/Vec3;")) - private Vec3 hookFixRotation(Vec3 original) { - if ((Object) this != Minecraft.getInstance().player) { - return original; - } - - if (!Rotations.rotating || !Rotations.movementCorrection) { - return original; - } - - float yaw = Rotations.serverYaw * Mth.DEG_TO_RAD; - - return new Vec3(-Mth.sin(yaw) * 0.2F, 0.0, Mth.cos(yaw) * 0.2F); - } - - @ModifyExpressionValue(method = "updateFallFlyingMovement", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/entity/LivingEntity;getXRot()F")) - private float hookModifyFallFlyingPitch(float original) { - if ((Object) this != Minecraft.getInstance().player) { - return original; + @Unique + private final LivingEntity me = (LivingEntity) ((Object) this); + + @ModifyExpressionValue(method = "jumpFromGround", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/entity/LivingEntity;getYRot()F")) + private float getYRot(float original) { + if (me == mc.player) { + if (!Float.isNaN(RotationManager.INSTANCE.getYaw())) { + return RotationManager.INSTANCE.getYaw(); + } } - - if (!Rotations.rotating || !Rotations.movementCorrection) { - return original; - } - - return Rotations.serverPitch; + return original; } - @ModifyExpressionValue(method = "updateFallFlyingMovement", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/entity/LivingEntity;getLookAngle()Lnet/minecraft/world/phys/Vec3;")) - private Vec3 hookModifyFallFlyingRotationVector(Vec3 original) { - if ((Object) this != Minecraft.getInstance().player) { - return original; - } - - if (!Rotations.rotating || !Rotations.movementCorrection) { - return original; - } - - return Vec3.directionFromRotation(Rotations.serverYaw, Rotations.serverPitch); - } } diff --git a/src/main/java/com/nekiplay/neoscripts/mixins/entity/MixinLivingEntityRenderer.java b/src/main/java/com/nekiplay/neoscripts/mixins/entity/MixinLivingEntityRenderer.java index 02415d76..33fe5f12 100644 --- a/src/main/java/com/nekiplay/neoscripts/mixins/entity/MixinLivingEntityRenderer.java +++ b/src/main/java/com/nekiplay/neoscripts/mixins/entity/MixinLivingEntityRenderer.java @@ -1,6 +1,8 @@ package com.nekiplay.neoscripts.mixins.entity; import com.llamalad7.mixinextras.injector.ModifyExpressionValue; +import com.nekiplay.neoscripts.events.ExtractRenderStateEvent; +import com.nekiplay.neoscripts.events.main.EventBus; import com.nekiplay.neoscripts.utils.Rotations; import net.minecraft.client.Minecraft; import net.minecraft.client.model.EntityModel; @@ -10,47 +12,28 @@ import net.minecraft.world.entity.LivingEntity; import org.jspecify.annotations.NullMarked; import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Unique; import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.ModifyArgs; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; +import org.spongepowered.asm.mixin.injection.invoke.arg.Args; -@NullMarked @Mixin(LivingEntityRenderer.class) -public abstract class MixinLivingEntityRenderer> { - @ModifyExpressionValue(method = "extractRenderState(Lnet/minecraft/world/entity/LivingEntity;Lnet/minecraft/client/renderer/entity/state/LivingEntityRenderState;F)V", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/renderer/entity/LivingEntityRenderer;solveBodyRot(Lnet/minecraft/world/entity/LivingEntity;FF)F")) - private float hookBodyYaw(float original, LivingEntity entity, S state, float tickDelta) { - if (entity != Minecraft.getInstance().player) { - return original; - } +public class MixinLivingEntityRenderer> { - if (Rotations.rotating) { - return Mth.rotLerp(tickDelta, Rotations.serverYaw, Rotations.serverYaw); - } + @Unique + private T lastEntity; - return original; + @Inject(method = "extractRenderState(Lnet/minecraft/world/entity/LivingEntity;Lnet/minecraft/client/renderer/entity/state/LivingEntityRenderState;F)V", at = @At("HEAD")) + public void extractRenderStateHook(T livingEntity, S livingEntityRenderState, float f, CallbackInfo ci) { + lastEntity = livingEntity; + EventBus.INSTANCE.send(new ExtractRenderStateEvent(true, livingEntity, livingEntityRenderState, f)); } - @ModifyExpressionValue(method = "extractRenderState(Lnet/minecraft/world/entity/LivingEntity;Lnet/minecraft/client/renderer/entity/state/LivingEntityRenderState;F)V", at = @At(value = "INVOKE", target = "Lnet/minecraft/util/Mth;rotLerp(FFF)F")) - private float hookHeadYaw(float original, LivingEntity entity, S state, float tickDelta) { - if (entity != Minecraft.getInstance().player) { - return original; - } - - if (Rotations.rotating) { - return Mth.rotLerp(tickDelta, Rotations.serverYaw, Rotations.serverYaw); - } - - return original; + @Inject(method = "extractRenderState(Lnet/minecraft/world/entity/LivingEntity;Lnet/minecraft/client/renderer/entity/state/LivingEntityRenderState;F)V", at = @At("TAIL")) + public void extractRenderStatePostHook(T livingEntity, S livingEntityRenderState, float f, CallbackInfo ci) { + EventBus.INSTANCE.send(new ExtractRenderStateEvent(false, livingEntity, livingEntityRenderState, f)); } - @ModifyExpressionValue(method = "extractRenderState(Lnet/minecraft/world/entity/LivingEntity;Lnet/minecraft/client/renderer/entity/state/LivingEntityRenderState;F)V", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/entity/LivingEntity;getXRot(F)F")) - private float hookPitch(float original, LivingEntity entity, S state, float tickDelta) { - if (entity != Minecraft.getInstance().player) { - return original; - } - - if (Rotations.rotating) { - return Mth.rotLerp(tickDelta, Rotations.serverPitch, Rotations.serverPitch); - } - - return original; - } } \ No newline at end of file diff --git a/src/main/java/com/nekiplay/neoscripts/mixins/entity/MixinLocalPlayer.java b/src/main/java/com/nekiplay/neoscripts/mixins/entity/MixinLocalPlayer.java index dbcf0b59..d241f22c 100644 --- a/src/main/java/com/nekiplay/neoscripts/mixins/entity/MixinLocalPlayer.java +++ b/src/main/java/com/nekiplay/neoscripts/mixins/entity/MixinLocalPlayer.java @@ -2,7 +2,8 @@ import com.llamalad7.mixinextras.injector.ModifyExpressionValue; import com.mojang.authlib.GameProfile; -import com.nekiplay.neoscripts.events.SendMovementPacketsEvent; +import com.nekiplay.neoscripts.events.*; +import com.nekiplay.neoscripts.events.main.EventBus; import com.nekiplay.neoscripts.utils.RaycastUtils; import com.nekiplay.neoscripts.utils.Rotations; import net.minecraft.client.Minecraft; @@ -20,6 +21,7 @@ import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.ModifyVariable; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; @Mixin(LocalPlayer.class) public abstract class MixinLocalPlayer extends AbstractClientPlayer { @@ -32,70 +34,28 @@ public MixinLocalPlayer(ClientLevel world, GameProfile profile) { super(world, profile); } - // Rotations + @Inject(method = "tick", at = @At("HEAD")) + private void tickHook(CallbackInfo ci) { + EventBus.INSTANCE.send(new PlayerTickEvent()); + } @Inject(method = "sendPosition", at = @At("HEAD")) - private void onSendMovementPacketsHead(CallbackInfo ci) { - SendMovementPacketsEvent.PRE.invoker().onSendMovementPacketsPre(getYRot(), getXRot()); + private void sendPositionHook(CallbackInfo ci) { + EventBus.INSTANCE.send(new SyncPosEvent(true)); } @Inject(method = "sendPosition", at = @At("RETURN")) - private void onSendMovementPacketsTail(CallbackInfo info) { - SendMovementPacketsEvent.POST.invoker().onSendMovementPacketsPost(); - } - - @ModifyExpressionValue(method = "pick(Lnet/minecraft/world/entity/Entity;DDF)Lnet/minecraft/world/phys/HitResult;", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/entity/Entity;pick(DFZ)Lnet/minecraft/world/phys/HitResult;")) - private static HitResult hookRaycast(HitResult original, Entity camera, double blockInteractionRange, double entityInteractionRange, float tickDelta) { - if (camera != Minecraft.getInstance().player) { - return original; - - } - - if (Rotations.rotating) { - return RaycastUtils.findCrosshairTarget(camera, - camera.getEyePosition(), - Rotations.serverYaw, - Rotations.serverPitch, - ((Player) camera).blockInteractionRange(), - ((Player) camera).entityInteractionRange() - ); - } - else { - return original; - } + private void sendPostPositionHook(CallbackInfo ci) { + EventBus.INSTANCE.send(new SyncPosEvent(false)); } - @ModifyExpressionValue(method = "pick(Lnet/minecraft/world/entity/Entity;DDF)Lnet/minecraft/world/phys/HitResult;", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/entity/Entity;getViewVector(F)Lnet/minecraft/world/phys/Vec3;")) - private static Vec3 hookRotationVector(Vec3 original, Entity camera, double blockInteractionRange, double entityInteractionRange, float tickDelta) { - if (camera != Minecraft.getInstance().player) { - return original; - } - - if (Rotations.rotating) { - return Vec3.directionFromRotation(Rotations.serverYaw, Rotations.serverPitch); - } - else { - return original; - } + @Inject(method = "applyInput", at = @At("HEAD"), cancellable = true) + private void applyInputHook(CallbackInfo ci) { + if (EventBus.INSTANCE.sendCancellable(new ApplyInputEvent())) ci.cancel(); } - @ModifyExpressionValue(method = {"sendPosition", - "tick"}, at = @At(value = "INVOKE", target = "Lnet/minecraft/client/player/LocalPlayer;getYRot()F")) - private float hookSilentRotationYaw(float original) { - if (!Rotations.rotating) { - return original; - } - - return Rotations.serverYaw; - } - - @ModifyExpressionValue(method = {"sendPosition", - "tick"}, at = @At(value = "INVOKE", target = "Lnet/minecraft/client/player/LocalPlayer;getXRot()F")) - private float hookSilentRotationPitch(float original) { - if (!Rotations.rotating) { - return original; - } - - return Rotations.serverPitch; + @Inject(method = "raycastHitResult", at = @At("RETURN")) + private void raycastPostHitResultHook(float f, Entity entity, CallbackInfoReturnable cir) { + EventBus.INSTANCE.send(new RaycastHitEvent(false)); } } \ No newline at end of file diff --git a/src/main/java/com/nekiplay/neoscripts/mixins/entity/MixinPlayer.java b/src/main/java/com/nekiplay/neoscripts/mixins/entity/MixinPlayer.java index c811bcce..f8c869ad 100644 --- a/src/main/java/com/nekiplay/neoscripts/mixins/entity/MixinPlayer.java +++ b/src/main/java/com/nekiplay/neoscripts/mixins/entity/MixinPlayer.java @@ -1,26 +1,31 @@ package com.nekiplay.neoscripts.mixins.entity; -import com.llamalad7.mixinextras.injector.ModifyExpressionValue; -import com.nekiplay.neoscripts.utils.Rotations; -import net.minecraft.client.Minecraft; +import com.nekiplay.neoscripts.events.TravelEvent; +import com.nekiplay.neoscripts.events.main.EventBus; import net.minecraft.world.entity.player.Player; +import net.minecraft.world.phys.Vec3; import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Unique; import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +import static com.nekiplay.neoscripts.Main.mc; @Mixin(Player.class) public abstract class MixinPlayer { - @ModifyExpressionValue(method = {"causeExtraKnockback", - "doSweepAttack"}, at = @At(value = "INVOKE", target = "Lnet/minecraft/world/entity/player/Player;getYRot()F")) - private float hookFixRotation(float original) { - if ((Object) this != Minecraft.getInstance().player) { - return original; - } + @Unique + private final Player me = (Player) ((Object) this); + - if (!Rotations.rotating || !Rotations.movementCorrection) { - return original; - } + @Inject(method = "travel", at = @At("HEAD")) + private void travelHook(Vec3 vec3, CallbackInfo ci) { + if (me == mc.player) EventBus.INSTANCE.send(new TravelEvent(true)); + } - return Rotations.serverYaw; + @Inject(method = "travel", at = @At("RETURN")) + private void travelPostHook(Vec3 vec3, CallbackInfo ci) { + if (me == mc.player) EventBus.INSTANCE.send(new TravelEvent(false)); } } diff --git a/src/main/java/com/nekiplay/neoscripts/mixins/firmament/ModAnnouncerMixin.java b/src/main/java/com/nekiplay/neoscripts/mixins/firmament/ModAnnouncerMixin.java index f18d96eb..eaec6921 100644 --- a/src/main/java/com/nekiplay/neoscripts/mixins/firmament/ModAnnouncerMixin.java +++ b/src/main/java/com/nekiplay/neoscripts/mixins/firmament/ModAnnouncerMixin.java @@ -2,7 +2,6 @@ import com.llamalad7.mixinextras.injector.wrapmethod.WrapMethod; import com.llamalad7.mixinextras.injector.wrapoperation.Operation; -import com.nekiplay.neoscripts.Main; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Pseudo; import org.spongepowered.asm.mixin.injection.Coerce; diff --git a/src/main/java/com/nekiplay/neoscripts/mixins/minecraft/ClientConnectionMixin.java b/src/main/java/com/nekiplay/neoscripts/mixins/minecraft/ClientConnectionMixin.java index 9d783fd8..16b6f9ec 100644 --- a/src/main/java/com/nekiplay/neoscripts/mixins/minecraft/ClientConnectionMixin.java +++ b/src/main/java/com/nekiplay/neoscripts/mixins/minecraft/ClientConnectionMixin.java @@ -1,38 +1,57 @@ package com.nekiplay.neoscripts.mixins.minecraft; -import com.nekiplay.neoscripts.events.network.PacketEvent; +import com.nekiplay.neoscripts.events.PacketEvent; +import com.nekiplay.neoscripts.events.main.EventBus; +import com.nekiplay.neoscripts.utils.ServerUtil; import io.netty.channel.ChannelFutureListener; import io.netty.channel.ChannelHandlerContext; +import net.fabricmc.fabric.api.entity.FakePlayer; import net.minecraft.network.Connection; import net.minecraft.network.protocol.Packet; +import net.minecraft.network.protocol.game.ClientboundSetEntityDataPacket; import net.minecraft.world.InteractionResult; +import net.minecraft.world.entity.Entity; import org.jetbrains.annotations.Nullable; import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; +import static com.nekiplay.neoscripts.Main.mc; + @Mixin(Connection.class) public abstract class ClientConnectionMixin { - @Inject(method = "channelRead0(Lio/netty/channel/ChannelHandlerContext;Lnet/minecraft/network/protocol/Packet;)V", - at = @At(value = "INVOKE", target = "Lnet/minecraft/network/Connection;genericsFtw(Lnet/minecraft/network/protocol/Packet;Lnet/minecraft/network/PacketListener;)V", shift = At.Shift.BEFORE), cancellable = true) - private void onHandlePacket(ChannelHandlerContext channelHandlerContext, Packet packet, CallbackInfo ci) { - InteractionResult result = PacketEvent.RECEIVE.invoker().update(new PacketEvent(packet, (Connection) (Object) this)); - if (result == InteractionResult.FAIL) { + + @Shadow + public abstract void send(Packet packet, @Nullable ChannelFutureListener channelFutureListener, boolean bl); + + @Inject(method = "send(Lnet/minecraft/network/protocol/Packet;Lio/netty/channel/ChannelFutureListener;)V", at = @At("HEAD"), cancellable = true) + private void onSend(Packet packet, ChannelFutureListener listener, CallbackInfo ci) { + PacketEvent.Send event = new PacketEvent.Send(packet, false); + if (ServerUtil.INSTANCE.getSilentPackets().contains(packet)) { + ServerUtil.INSTANCE.getSilentPackets().remove(packet); + } else if (EventBus.INSTANCE.sendCancellable(event)) { + ci.cancel(); + } else if (event.getModified()) { ci.cancel(); + this.send(event.getPacket(), listener, true); } + } - @Inject(at = @At("HEAD"), method = "send(Lnet/minecraft/network/protocol/Packet;Lio/netty/channel/ChannelFutureListener;)V", cancellable = true) - private void onSendPacketHead(Packet packet, ChannelFutureListener channelFutureListener, CallbackInfo ci) { - InteractionResult result = PacketEvent.SEND.invoker().update(new PacketEvent(packet, (Connection) (Object) this)); - if (result == InteractionResult.FAIL) { - ci.cancel(); + @Inject(method = "channelRead0(Lio/netty/channel/ChannelHandlerContext;Lnet/minecraft/network/protocol/Packet;)V", at = @At("HEAD"), cancellable = true) + private void onChannelRead(ChannelHandlerContext channelHandlerContext, Packet packet, CallbackInfo ci) { + if (packet instanceof ClientboundSetEntityDataPacket entityDataPacket) { + if (mc.level == null) return; + + Entity entity = mc.level.getEntity(entityDataPacket.id()); + if (entity instanceof FakePlayer) { + ci.cancel(); + return; + } } - } - @Inject(method = "send(Lnet/minecraft/network/protocol/Packet;Lio/netty/channel/ChannelFutureListener;)V", at = @At("TAIL")) - private void onSendPacketTail(Packet packet, @Nullable ChannelFutureListener channelFutureListener, CallbackInfo ci) { - PacketEvent.SENT.invoker().update(new PacketEvent(packet, (Connection) (Object) this)); + if (EventBus.INSTANCE.sendCancellable(new PacketEvent.Receive(packet, false))) ci.cancel(); } } diff --git a/src/main/java/com/nekiplay/neoscripts/utils/NEURepoManager.java b/src/main/java/com/nekiplay/neoscripts/utils/NEURepoManager.java index 5f40887b..276ab1e7 100644 --- a/src/main/java/com/nekiplay/neoscripts/utils/NEURepoManager.java +++ b/src/main/java/com/nekiplay/neoscripts/utils/NEURepoManager.java @@ -3,7 +3,6 @@ import com.google.common.collect.HashMultimap; import com.google.common.collect.Multimap; import com.google.common.collect.Multimaps; -import com.nekiplay.neoscripts.Main; import com.nekiplay.neoscripts.annotations.Init; import com.nekiplay.neoscripts.utils.scheduler.Scheduler; import io.github.moulberry.repo.NEUConstants; diff --git a/src/main/java/com/nekiplay/neoscripts/utils/data/JsonData.java b/src/main/java/com/nekiplay/neoscripts/utils/data/JsonData.java index 83379d3f..7fa7cabe 100644 --- a/src/main/java/com/nekiplay/neoscripts/utils/data/JsonData.java +++ b/src/main/java/com/nekiplay/neoscripts/utils/data/JsonData.java @@ -4,7 +4,6 @@ import com.mojang.serialization.Codec; import com.mojang.serialization.JsonOps; import com.mojang.serialization.codecs.RecordCodecBuilder; -import com.nekiplay.neoscripts.Main; import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientLifecycleEvents; import net.minecraft.util.StringRepresentable; import org.jetbrains.annotations.Nullable; diff --git a/src/main/java/com/nekiplay/neoscripts/utils/trackers/PetCache.java b/src/main/java/com/nekiplay/neoscripts/utils/trackers/PetCache.java index c2a02711..8569150e 100644 --- a/src/main/java/com/nekiplay/neoscripts/utils/trackers/PetCache.java +++ b/src/main/java/com/nekiplay/neoscripts/utils/trackers/PetCache.java @@ -1,6 +1,5 @@ package com.nekiplay.neoscripts.utils.trackers; -import com.nekiplay.neoscripts.Main; import com.nekiplay.neoscripts.annotations.Init; import com.nekiplay.neoscripts.utils.ItemUtils; import com.nekiplay.neoscripts.utils.RegexUtils; diff --git a/src/main/kotlin/com/nekiplay/neoscripts/Main.kt b/src/main/kotlin/com/nekiplay/neoscripts/Main.kt new file mode 100644 index 00000000..e2c1a8cc --- /dev/null +++ b/src/main/kotlin/com/nekiplay/neoscripts/Main.kt @@ -0,0 +1,126 @@ +package com.nekiplay.neoscripts + +import com.google.gson.Gson +import com.google.gson.GsonBuilder +import com.nekiplay.neoscripts.events.main.EventBus +import com.nekiplay.neoscripts.features.commands.impl.LuaCommand +import com.nekiplay.neoscripts.features.lua.LuaManager +import com.nekiplay.neoscripts.features.modules.ModuleManager.registerInbuilt +import com.nekiplay.neoscripts.utils.Utils +import com.nekiplay.neoscripts.utils.scheduler.Scheduler +import io.github.classgraph.ClassGraph +import net.fabricmc.api.ModInitializer +import net.fabricmc.fabric.api.client.command.v2.ClientCommandRegistrationCallback +import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents +import net.fabricmc.loader.api.FabricLoader +import net.minecraft.ChatFormatting +import net.minecraft.client.Minecraft +import org.slf4j.Logger +import org.slf4j.LoggerFactory +import java.io.File +import java.nio.file.Path + +object Main : ModInitializer { + const val MOD_ID: String = "neoscripts" + val LOGGER: Logger? = LoggerFactory.getLogger(MOD_ID) + var LUA_MANAGER: LuaManager? = null + val CONFIG_DIR: Path = FabricLoader.getInstance().getConfigDir().resolve(MOD_ID) + + val PREFIX: String = + ChatFormatting.GRAY.toString() + "[" + ChatFormatting.GOLD + "Neo Scripts" + ChatFormatting.GRAY + "] " + ChatFormatting.RESET + const val LOG_PREFIX: String = "[Neo Scripts] " + var neuDir: File? = null + @JvmField + var mc: Minecraft = Minecraft.getInstance() + var INSTANCE: Main? = null + val GSON: Gson = GsonBuilder().setPrettyPrinting().create() + val GSON_COMPACT: Gson = GsonBuilder().create() + + /** + * Do not instantiate this class. Use [.getInstance] instead. + */ + @Deprecated("") + fun Main() { + INSTANCE = this + } + + fun getInstance(): Main? { + return INSTANCE + } + + fun saveConfig(){ + for (script in LUA_MANAGER!!.getLoadedScripts()) { + LUA_MANAGER!!.unloadScript(script.scriptName) + } + } + + override fun onInitialize() { + neuDir = FabricLoader.getInstance().getConfigDir().resolve("neoscripts").toFile() + neuDir!!.mkdirs() + LUA_MANAGER = LuaManager() + val scriptsDir: File = File(neuDir, "scripts") + if (!scriptsDir.exists()) { + scriptsDir.mkdir() + } + val libsDir = File(scriptsDir, "libs") + if (!libsDir.exists()) { + libsDir.mkdir() + } + + Runtime.getRuntime().addShutdownHook(Thread(Runnable { saveConfig() })) + + ClientTickEvents.END_CLIENT_TICK.register(ClientTickEvents.EndTick { client: Minecraft? -> this.tick(client) }) + ClientCommandRegistrationCallback.EVENT.register { dispatcher, registryAccess -> + LuaCommand.register(dispatcher, registryAccess) + } + + init() + + registerInbuilt() + + Scheduler.INSTANCE.scheduleCyclic(Runnable { Utils.update() }, 20) + + val classes = HashSet>() + + ClassGraph() + .enableClassInfo() + .enableMethodInfo() + .enableAnnotationInfo() + .ignoreClassVisibility() + .ignoreMethodVisibility() + .ignoreFieldVisibility() + .acceptPackages("com.nekiplay.neoscripts") + .rejectPackages("com.nekiplay.neoscripts.mixins") + .scan() + .use { result -> + + for (classInfo in result.allClasses) { + if (!classInfo.isStandardClass) continue + classes.add(classInfo.loadClass()) + } + + } + + EventBus.init(classes) + } + + /** + * Ticks the scheduler. Called once at the end of every client tick through + * [ClientTickEvents.END_CLIENT_TICK]. + * + * @param client the Minecraft client. + */ + fun tick(client: Minecraft?) { + Scheduler.INSTANCE.tick() + } + + /** + * This method is responsible for initializing all classes. + * To have your class initialized you must annotate its initializer method with the `@Init` annotation. + * At compile time, ASM completely overwrites the content of this method, so adding a call here will do nothing. + * + * @see Init + */ + private fun init() { + } +} \ No newline at end of file diff --git a/src/main/kotlin/com/nekiplay/neoscripts/events/ApplyInputEvent.kt b/src/main/kotlin/com/nekiplay/neoscripts/events/ApplyInputEvent.kt new file mode 100644 index 00000000..b4707919 --- /dev/null +++ b/src/main/kotlin/com/nekiplay/neoscripts/events/ApplyInputEvent.kt @@ -0,0 +1,5 @@ +package com.nekiplay.neoscripts.events + +import com.nekiplay.neoscripts.events.main.CancellableEvent + +class ApplyInputEvent : CancellableEvent() \ No newline at end of file diff --git a/src/main/kotlin/com/nekiplay/neoscripts/events/ExtractRenderStateEvent.kt b/src/main/kotlin/com/nekiplay/neoscripts/events/ExtractRenderStateEvent.kt new file mode 100644 index 00000000..1fb24743 --- /dev/null +++ b/src/main/kotlin/com/nekiplay/neoscripts/events/ExtractRenderStateEvent.kt @@ -0,0 +1,7 @@ +package com.nekiplay.neoscripts.events + +import com.nekiplay.neoscripts.events.main.DoubleEvent +import net.minecraft.client.renderer.entity.state.LivingEntityRenderState +import net.minecraft.world.entity.LivingEntity + +class ExtractRenderStateEvent(pre: Boolean, val entity : LivingEntity, val renderEntityState : LivingEntityRenderState, val f : Float) : DoubleEvent(pre) \ No newline at end of file diff --git a/src/main/kotlin/com/nekiplay/neoscripts/events/PacketEvent.kt b/src/main/kotlin/com/nekiplay/neoscripts/events/PacketEvent.kt new file mode 100644 index 00000000..a618e349 --- /dev/null +++ b/src/main/kotlin/com/nekiplay/neoscripts/events/PacketEvent.kt @@ -0,0 +1,11 @@ +package com.nekiplay.neoscripts.events + +import com.nekiplay.neoscripts.events.main.CancellableEvent +import net.minecraft.network.protocol.Packet + +class PacketEvent { + + class Send(var packet : Packet<*>, var modified : Boolean = false) : CancellableEvent() + class Receive(var packet : Packet<*>, var modified : Boolean = false) : CancellableEvent() + +} \ No newline at end of file diff --git a/src/main/kotlin/com/nekiplay/neoscripts/events/PlayerTickEvent.kt b/src/main/kotlin/com/nekiplay/neoscripts/events/PlayerTickEvent.kt new file mode 100644 index 00000000..db3b54b7 --- /dev/null +++ b/src/main/kotlin/com/nekiplay/neoscripts/events/PlayerTickEvent.kt @@ -0,0 +1,5 @@ +package com.nekiplay.neoscripts.events + +import com.nekiplay.neoscripts.events.main.Event + +class PlayerTickEvent : Event() \ No newline at end of file diff --git a/src/main/kotlin/com/nekiplay/neoscripts/events/RaycastHitEvent.kt b/src/main/kotlin/com/nekiplay/neoscripts/events/RaycastHitEvent.kt new file mode 100644 index 00000000..f7dac313 --- /dev/null +++ b/src/main/kotlin/com/nekiplay/neoscripts/events/RaycastHitEvent.kt @@ -0,0 +1,5 @@ +package com.nekiplay.neoscripts.events + +import com.nekiplay.neoscripts.events.main.DoubleEvent + +class RaycastHitEvent(pre: Boolean) : DoubleEvent(pre) \ No newline at end of file diff --git a/src/main/kotlin/com/nekiplay/neoscripts/events/RenderEvent.kt b/src/main/kotlin/com/nekiplay/neoscripts/events/RenderEvent.kt new file mode 100644 index 00000000..82fa5282 --- /dev/null +++ b/src/main/kotlin/com/nekiplay/neoscripts/events/RenderEvent.kt @@ -0,0 +1,6 @@ +package com.nekiplay.neoscripts.events + +import com.nekiplay.neoscripts.events.main.Event +import org.joml.Matrix4fStack + +class RenderEvent(val matrix : Matrix4fStack, val mouseX : Double, val mouseY : Double) : Event() \ No newline at end of file diff --git a/src/main/kotlin/com/nekiplay/neoscripts/events/SyncPosEvent.kt b/src/main/kotlin/com/nekiplay/neoscripts/events/SyncPosEvent.kt new file mode 100644 index 00000000..d1f2794f --- /dev/null +++ b/src/main/kotlin/com/nekiplay/neoscripts/events/SyncPosEvent.kt @@ -0,0 +1,5 @@ +package com.nekiplay.neoscripts.events + +import com.nekiplay.neoscripts.events.main.DoubleEvent + +class SyncPosEvent(pre: Boolean) : DoubleEvent(pre) \ No newline at end of file diff --git a/src/main/kotlin/com/nekiplay/neoscripts/events/TravelEvent.kt b/src/main/kotlin/com/nekiplay/neoscripts/events/TravelEvent.kt new file mode 100644 index 00000000..41606a0e --- /dev/null +++ b/src/main/kotlin/com/nekiplay/neoscripts/events/TravelEvent.kt @@ -0,0 +1,5 @@ +package com.nekiplay.neoscripts.events + +import com.nekiplay.neoscripts.events.main.DoubleEvent + +class TravelEvent(pre: Boolean) : DoubleEvent(pre) \ No newline at end of file diff --git a/src/main/kotlin/com/nekiplay/neoscripts/events/main/Callback.kt b/src/main/kotlin/com/nekiplay/neoscripts/events/main/Callback.kt new file mode 100644 index 00000000..a80151ba --- /dev/null +++ b/src/main/kotlin/com/nekiplay/neoscripts/events/main/Callback.kt @@ -0,0 +1,3 @@ +package com.nekiplay.neoscripts.events.main + +annotation class Callback(val priority : Short = 0) \ No newline at end of file diff --git a/src/main/kotlin/com/nekiplay/neoscripts/events/main/CancellableEvent.kt b/src/main/kotlin/com/nekiplay/neoscripts/events/main/CancellableEvent.kt new file mode 100644 index 00000000..a364a74e --- /dev/null +++ b/src/main/kotlin/com/nekiplay/neoscripts/events/main/CancellableEvent.kt @@ -0,0 +1,5 @@ +package com.nekiplay.neoscripts.events.main + +abstract class CancellableEvent : Event() { + var cancelled : Boolean = false +} \ No newline at end of file diff --git a/src/main/kotlin/com/nekiplay/neoscripts/events/main/DoubleCancellableEvent.kt b/src/main/kotlin/com/nekiplay/neoscripts/events/main/DoubleCancellableEvent.kt new file mode 100644 index 00000000..37937aed --- /dev/null +++ b/src/main/kotlin/com/nekiplay/neoscripts/events/main/DoubleCancellableEvent.kt @@ -0,0 +1,5 @@ +package com.nekiplay.neoscripts.events.main + +abstract class DoubleCancellableEvent(pre : Boolean) : DoubleEvent(pre) { + var cancelled : Boolean = false +} \ No newline at end of file diff --git a/src/main/kotlin/com/nekiplay/neoscripts/events/main/DoubleEvent.kt b/src/main/kotlin/com/nekiplay/neoscripts/events/main/DoubleEvent.kt new file mode 100644 index 00000000..aa2ba740 --- /dev/null +++ b/src/main/kotlin/com/nekiplay/neoscripts/events/main/DoubleEvent.kt @@ -0,0 +1,3 @@ +package com.nekiplay.neoscripts.events.main + +abstract class DoubleEvent(val pre : Boolean) : Event() \ No newline at end of file diff --git a/src/main/kotlin/com/nekiplay/neoscripts/events/main/Event.kt b/src/main/kotlin/com/nekiplay/neoscripts/events/main/Event.kt new file mode 100644 index 00000000..efa1696e --- /dev/null +++ b/src/main/kotlin/com/nekiplay/neoscripts/events/main/Event.kt @@ -0,0 +1,3 @@ +package com.nekiplay.neoscripts.events.main + +abstract class Event \ No newline at end of file diff --git a/src/main/kotlin/com/nekiplay/neoscripts/events/main/EventBus.kt b/src/main/kotlin/com/nekiplay/neoscripts/events/main/EventBus.kt new file mode 100644 index 00000000..98a28066 --- /dev/null +++ b/src/main/kotlin/com/nekiplay/neoscripts/events/main/EventBus.kt @@ -0,0 +1,67 @@ +package com.nekiplay.neoscripts.events.main + +import java.awt.Color +import java.io.BufferedWriter +import java.io.File +import java.io.FileWriter +import java.lang.reflect.Method +import java.lang.reflect.Modifier +import java.time.LocalDate +import java.util.concurrent.atomic.AtomicReference +import kotlin.collections.get + +object EventBus { + + val callbacks = HashMap, MutableList>() + + fun init(classes : Set>) { + for (clazz in classes) { + if ( + clazz.isInterface || Modifier.isAbstract(clazz.modifiers) || clazz.isAnnotation + ) continue + val classInstance = clazz.kotlin.objectInstance + if (classInstance != null) register(classInstance) + } + } + + fun register(instance : Any) { + for (method in instance.javaClass.methods) { + val annotation = method.getAnnotation(Callback::class.java) ?: continue + val priority = annotation.priority + if (method.parameterCount != 1) throw RuntimeException("Parameters is empty. In: ${instance.javaClass.name}, method: ${method.name}") + val eventType = method.parameterTypes.first() + if (!Event::class.java.isAssignableFrom(eventType)) throw RuntimeException("Cannot find event in parameters. In: ${instance.javaClass.name}, method: ${method.name}, parameters: ${method.parameterTypes.map { it.simpleName }}") + callbacks.getOrPut(eventType as Class) { ArrayList() } .add(CallbackMethod(method, instance, priority, false)) + callbacks[eventType]?.sortWith(Comparator { o1, o2 -> return@Comparator o2.priority - o1.priority }) + } + } + + fun send(event : Event) { + val lastMethod = AtomicReference() + + try { + callbacks[event.javaClass]?.forEach { + lastMethod.set(it) + it.method.invoke(it.instance, event) + } + } catch (e : Exception) { + e.printStackTrace() + } + } + + fun setIgnore(value : Boolean, type : Class, vararg instances : Any) { + val list = callbacks[type] ?: return + + for (callback in list) { + if (instances.isEmpty() || instances.contains(callback.instance)) callback.ignored = value + } + } + + fun sendCancellable(event : CancellableEvent) : Boolean { + send(event) + return event.cancelled + } + + data class CallbackMethod(val method : Method, val instance : Any, val priority : Short, var ignored : Boolean) + +} \ No newline at end of file diff --git a/src/main/kotlin/com/nekiplay/neoscripts/features/lua/objects/player/PlayerObject.kt b/src/main/kotlin/com/nekiplay/neoscripts/features/lua/objects/player/PlayerObject.kt index ada68d37..5c04cc46 100644 --- a/src/main/kotlin/com/nekiplay/neoscripts/features/lua/objects/player/PlayerObject.kt +++ b/src/main/kotlin/com/nekiplay/neoscripts/features/lua/objects/player/PlayerObject.kt @@ -15,6 +15,7 @@ import com.nekiplay.neoscripts.utils.RaycastUtils import com.nekiplay.neoscripts.utils.Rotations import com.nekiplay.neoscripts.utils.StatusBarTracker import com.nekiplay.neoscripts.utils.Utils +import com.nekiplay.neoscripts.utils.aiming.RotationManager import com.nekiplay.neoscripts.utils.trackers.ColdTracker import com.nekiplay.neoscripts.utils.trackers.PetCache import net.minecraft.client.Minecraft @@ -69,7 +70,6 @@ class PlayerObject : LuaValue() { "getPos", "getPosition" -> GetPlayerPosFunction() "getRotation" -> GetPlayerRotationFunction() "getSilentRotation", "getServerRotation" -> GetPlayerSilentRotationFunction() - "isSilentRotationg" -> GetPlayerSilentIsRotationFunction() "setRotation" -> SetPlayerRotationFunction() "setSilentRotation", "setServerRotation" -> SetPlayerSilentRotationFunction() "getName" -> GetPlayerNameFunction() @@ -475,7 +475,7 @@ class PlayerObject : LuaValue() { silentMovementCorrection = arg4?.optboolean(false) ?: false } - Rotations.rotate(yaw, pitch, movementCorrection, silentMovementCorrection) + RotationManager.rotateTo(yaw.toFloat(), pitch.toFloat(), 1, 1, movementCorrection, silentMovementCorrection) return TRUE } return FALSE @@ -509,20 +509,14 @@ class PlayerObject : LuaValue() { } } - private inner class GetPlayerSilentIsRotationFunction : ZeroArgFunction() { - override fun call(): LuaValue { - return valueOf(Rotations.rotating) - } - } - private inner class GetPlayerSilentRotationFunction : ZeroArgFunction() { override fun call(): LuaValue { val player = mc.player; return if (player != null) { val table = tableOf() if (Rotations.rotating) { - table.set("yaw", valueOf(Rotations.serverYaw.toDouble())) - table.set("pitch", valueOf(Rotations.serverPitch.toDouble())) + table.set("yaw", valueOf(RotationManager.getCurrentYaw().toDouble())) + table.set("pitch", valueOf(RotationManager.getCurrentPitch().toDouble())) } else { table.set("yaw", valueOf(player.yRot.toDouble())) diff --git a/src/main/kotlin/com/nekiplay/neoscripts/utils/MathUtil.kt b/src/main/kotlin/com/nekiplay/neoscripts/utils/MathUtil.kt new file mode 100644 index 00000000..ef98110e --- /dev/null +++ b/src/main/kotlin/com/nekiplay/neoscripts/utils/MathUtil.kt @@ -0,0 +1,34 @@ +package com.nekiplay.neoscripts.utils + +import com.nekiplay.neoscripts.Main.mc +import kotlin.math.pow +import kotlin.math.roundToInt + +object MathUtil { + + fun wrapDegrees(degrees : Float) : Float { + var i = degrees % 360 + if (i >= 180F) i -= 360F + if (i < -180F) i += 360F + return i + } + + fun getGCD() = ((mc.options.sensitivity().get() * 0.6 + 0.2).pow(3.0)) * 1.2 + + fun applyGCD(current: Float, previous: Float): Float { + val gcd = getGCD() + + val delta = current - previous + val mousePixels = (delta / gcd).roundToInt() + + return (previous + mousePixels * gcd).toFloat() + } + + fun limitAngle(current : Float, intended : Float, factor : Float) : Float { + var change = wrapDegrees(intended - current) + if (change > factor) change = factor + if (change < -factor) change = -factor + return current + change + } + +} \ No newline at end of file diff --git a/src/main/kotlin/com/nekiplay/neoscripts/utils/ServerUtil.kt b/src/main/kotlin/com/nekiplay/neoscripts/utils/ServerUtil.kt new file mode 100644 index 00000000..fecb205f --- /dev/null +++ b/src/main/kotlin/com/nekiplay/neoscripts/utils/ServerUtil.kt @@ -0,0 +1,96 @@ +package com.nekiplay.neoscripts.utils + +import com.nekiplay.neoscripts.Main.mc +import com.nekiplay.neoscripts.events.PacketEvent +import com.nekiplay.neoscripts.events.PlayerTickEvent +import com.nekiplay.neoscripts.events.main.Callback +import net.minecraft.network.protocol.Packet +import net.minecraft.network.protocol.game.ClientboundPlayerPositionPacket +import net.minecraft.network.protocol.game.ClientboundSetHeldSlotPacket +import net.minecraft.network.protocol.game.ServerboundMovePlayerPacket +import net.minecraft.network.protocol.game.ServerboundSetCarriedItemPacket + +object ServerUtil { + + var slot = 0 + private set + var yaw = 0F + private set + var pitch = 0F + private set + + val silentPackets = ArrayList>() + private val delayedPackets = ArrayList() + + @Callback + fun onTick(event : PlayerTickEvent) { + ArrayList(delayedPackets).forEach { + it.ticks-- + if (it.ticks <= 0) { + sendPacket(it.packet) + delayedPackets.remove(it) + } + } + } + + @Callback(-10) + fun onPacketSend(event : PacketEvent.Send) { + + if (event.cancelled) return + + if (event.packet is ServerboundSetCarriedItemPacket) { + if ((event.packet as ServerboundSetCarriedItemPacket).slot == slot) event.cancelled = true + slot = (event.packet as ServerboundSetCarriedItemPacket).slot + } else if (event.packet is ServerboundMovePlayerPacket) { + yaw = (event.packet as ServerboundMovePlayerPacket).getYRot(yaw) + pitch = (event.packet as ServerboundMovePlayerPacket).getXRot(pitch) + } + + } + + @Callback(-10) + fun onPacketReceive(event : PacketEvent.Receive) { + + if (event.cancelled) return + + if (event.packet is ClientboundSetHeldSlotPacket) { + slot = (event.packet as ClientboundSetHeldSlotPacket).slot + } else if (event.packet is ClientboundPlayerPositionPacket) { + val change = (event.packet as ClientboundPlayerPositionPacket).change + + yaw = change.yRot + pitch = change.xRot + } + + } + + fun getSequence() : Int { + mc.level?.blockStatePredictionHandler?.startPredicting() + mc.level?.blockStatePredictionHandler?.close() + return mc.level?.blockStatePredictionHandler?.currentSequence() ?: 0 + } + + fun sendPacket(packet : Packet<*>) { + player.connection.connection.send(packet) + } + + @Deprecated(message = "Ignores absolutely all callbacks. Use EventBus.setIgnore(value : Boolean, type : Class, instance : Any?)") + fun sendPacketSilently(packet : Packet<*>) { + silentPackets.add(packet) + player.connection.connection.send(packet) + } + + fun sendPacket(packet : Packet<*>, delay : Int) { + if (delay <= 0) sendPacket(packet) + else delayedPackets.add(DelayedPacket(packet, delay)) + } + + fun mainHandItem() : ItemStack = inventory.getItem(slot) + + fun getPing() : Int { + return player.connection.getPlayerInfo(player.uuid)?.latency ?: 0 + } + + private data class DelayedPacket(val packet : Packet<*>, var ticks : Int) + +} \ No newline at end of file diff --git a/src/main/kotlin/com/nekiplay/neoscripts/utils/aiming/RotationManager.kt b/src/main/kotlin/com/nekiplay/neoscripts/utils/aiming/RotationManager.kt new file mode 100644 index 00000000..e8815c13 --- /dev/null +++ b/src/main/kotlin/com/nekiplay/neoscripts/utils/aiming/RotationManager.kt @@ -0,0 +1,363 @@ +package com.nekiplay.neoscripts.utils.aiming + +import com.nekiplay.neoscripts.Main.mc +import com.nekiplay.neoscripts.events.ApplyInputEvent +import com.nekiplay.neoscripts.events.ExtractRenderStateEvent +import com.nekiplay.neoscripts.events.PacketEvent +import com.nekiplay.neoscripts.events.PlayerTickEvent +import com.nekiplay.neoscripts.events.RaycastHitEvent +import com.nekiplay.neoscripts.events.RenderEvent +import com.nekiplay.neoscripts.events.SyncPosEvent +import com.nekiplay.neoscripts.events.main.Callback +import com.nekiplay.neoscripts.events.TravelEvent +import com.nekiplay.neoscripts.utils.MathUtil +import com.nekiplay.neoscripts.utils.ServerUtil +import com.nekiplay.neoscripts.utils.animation.AnimationUtil +import com.nekiplay.neoscripts.utils.game.InputUtil +import net.minecraft.network.protocol.game.ServerboundUseItemPacket +import net.minecraft.world.entity.player.Input +import net.minecraft.world.level.block.Rotation +import net.minecraft.world.phys.Vec2 +import kotlin.math.abs +import kotlin.math.atan2 +import kotlin.math.sign + +object RotationManager { + var yaw = Float.NaN + private set + var pitch = Float.NaN + private set + var currentPriority = -1 + private set + var ticks = -1 + private set + + private var rotationSet = false + + private var bodyYaw = Float.NaN + + private var lastYaw = Float.NaN + private var lastPitch = Float.NaN + private var lastBodyYaw = Float.NaN + + private var originalSyncYaw = Float.NaN + private var originalSyncPitch = Float.NaN + + private var originalTravelYaw = Float.NaN + private var originalTravelPitch = Float.NaN + + private var originalCrosshairYaw = Float.NaN + private var originalCrosshairPitch = Float.NaN + + private var originalRenderYaw = Float.NaN + private var originalRenderLastYaw = Float.NaN + private var originalRenderBodyYaw = Float.NaN + private var originalRenderLastBodyYaw = Float.NaN + private var originalRenderPitch = Float.NaN + private var originalRenderLastPitch = Float.NaN + + fun getCurrentYaw() = if (yaw.isNaN()) mc.player?.yRot ?: 0f else yaw + fun getCurrentLastYaw() = if (lastYaw.isNaN()) mc.player?.yRotO ?: 0f else lastYaw + fun getCurrentPitch() = if (pitch.isNaN()) mc.player?.xRot ?: 0f else pitch + fun getCurrentLastPitch() = if (lastPitch.isNaN()) mc.player?.xRotO ?: 0f else lastPitch + + fun rotateTo(yaw : Float, pitch : Float, ticks : Int = 0, priority : Int = 0, correction: Boolean = true, silentCorrection: Boolean = false) { + Rotations.moveFix = correction + Rotations.moveFixSilent = silentCorrection + + + if (Rotations.pauseInInventory && mc.screen != null) return + + if (priority >= currentPriority) { + if (yaw.isNaN() && pitch.isNaN()) resetRotate(priority) + else { + val fixedYaw = MathUtil.applyGCD(MathUtil.limitAngle(getCurrentYaw(), yaw, 180F), getCurrentYaw()) + val fixedPitch = MathUtil.applyGCD(pitch, getCurrentPitch()).coerceIn(-90F, 90F) + + this.yaw = fixedYaw + this.pitch = fixedPitch + this.ticks = ticks.coerceAtLeast(0) + this.currentPriority = priority + this.rotationSet = true + } + } + } + + fun rotateToWithoutFixAndCheck(yaw : Float, pitch : Float, ticks : Int = 0, priority : Int = 0) { + if (priority >= currentPriority) { + if (yaw.isNaN() && pitch.isNaN()) resetRotate(priority) + else { + val fixedYaw = MathUtil.limitAngle(getCurrentYaw(), yaw, 180F) + val fixedPitch = pitch.coerceIn(-90F, 90F) + + this.yaw = fixedYaw + this.pitch = fixedPitch + this.ticks = ticks.coerceAtLeast(0) + this.currentPriority = priority + this.rotationSet = true + } + } + } + + @Callback + fun onRender(event : RenderEvent) { + if (!Rotations.clientLook) return + + if (!yaw.isNaN()) mc.player?.yRot = AnimationUtil.lerp(getCurrentLastYaw(), yaw, mc.deltaTracker.getGameTimeDeltaPartialTick(false)) + if (!pitch.isNaN()) mc.player?.xRot = AnimationUtil.lerp(getCurrentLastPitch(), pitch, mc.deltaTracker.getGameTimeDeltaPartialTick(false)) + } + + @Callback(10) + fun onTick(event : PlayerTickEvent) { + lastYaw = if (!yaw.isNaN()) yaw else mc.player?.yRot ?: Float.NaN + lastPitch = if (!pitch.isNaN()) pitch else mc.player?.xRot ?: Float.NaN + } + + @Callback + fun onApplyInput(event : ApplyInputEvent) { + if (Rotations.moveFix || !Rotations.moveFixSilent) return + + if (!yaw.isNaN()) { + val moveInput = InputUtil.calculateCorrectedKeys( + + mc.player?.input?.keyPresses?.forward ?: false, mc.player?.input?.keyPresses?.backward ?: false, mc.player?.input?.keyPresses?.left ?: false, mc.player?.input?.keyPresses?.right ?: false, + mc.player?.yRot ?: 0f, yaw ?: 0f) + + if (mc.player?.isSprinting == true && !moveInput.forward) mc.player?.isSprinting = false + + mc.player?.input?.moveVector = Vec2( + InputUtil.calculateImpulse(moveInput.left, moveInput.right), + InputUtil.calculateImpulse(moveInput.forward, moveInput.back) + ) + mc.player?.input?.keyPresses = Input( + moveInput.forward, + moveInput.back, + moveInput.left, + moveInput.right, + mc.player?.input?.keyPresses?.jump ?: false, + mc.player?.input?.keyPresses?.shift ?: false, + mc.player?.input?.keyPresses?.sprint ?: false + ) + } + } + + @Callback + fun onPacketSend(event : PacketEvent.Send) { + if (!Rotations.hookCrosshairTarget) return + + if (event.packet is ServerboundUseItemPacket) { + val packet = event.packet as ServerboundUseItemPacket + + if (packet.yRot != getCurrentYaw() || packet.xRot != getCurrentPitch()) { + packet.yRot = getCurrentYaw() + packet.xRot = getCurrentPitch() + + event.modified = true + } + + + } + } + + @Callback + fun onSyncPosition(event: SyncPosEvent) { + val player = mc.player ?: return + if (event.pre) { + if (!yaw.isNaN()) { + originalSyncYaw = player.yRot + player.yRot = yaw + if (ServerUtil.yaw != yaw && player.yRotO != originalSyncYaw) player.yRotO = originalSyncYaw + } + if (!pitch.isNaN()) { + originalSyncPitch = player.xRot + player.xRot = pitch + if (ServerUtil.pitch != pitch && player.xRotO != originalSyncPitch) player.xRotO = originalSyncPitch + } + } else { + lastBodyYaw = if (!bodyYaw.isNaN()) bodyYaw else player.yBodyRot + bodyYaw = calcBodyYaw() + if (!originalSyncYaw.isNaN()) { + player.yRot = originalSyncYaw + originalSyncYaw = Float.NaN + } + if (!originalSyncPitch.isNaN()) { + player.xRot = originalSyncPitch + originalSyncPitch = Float.NaN + } + val shouldReset = !(Rotations.pauseInInventory && mc.screen != null) + if (shouldReset) { + if (rotationSet) { + rotationSet = false + } else { + if (!yaw.isNaN()) { + if (ticks > 0) ticks-- + else resetRotate(currentPriority) + } + } + } + } + } + + @Callback + fun onTravel(event : TravelEvent) { + if (!Rotations.moveFix) return + + if (event.pre) { + if (!yaw.isNaN()) { + originalTravelYaw = mc.player?.yRot ?: Float.NaN + mc.player?.yRot = yaw + } + if (!pitch.isNaN()) { + originalTravelPitch = mc.player?.xRot ?: Float.NaN + mc.player?.xRot = pitch + } + } else { + if (!originalTravelYaw.isNaN()) { + mc.player?.yRot = originalTravelYaw + originalTravelYaw = Float.NaN + } + if (!originalTravelPitch.isNaN()) { + mc.player?.xRot = originalTravelPitch + originalTravelPitch = Float.NaN + } + } + } + + @Callback + fun onRaycastHit(event : RaycastHitEvent) { + if (!Rotations.hookCrosshairTarget) return + + if (event.pre) { + if (!yaw.isNaN()) { + originalCrosshairYaw = mc.player?.yRot ?: Float.NaN + mc.player?.yRot = yaw + } + if (!pitch.isNaN()) { + originalCrosshairPitch = mc.player?.xRot ?: Float.NaN + mc.player?.xRot = pitch + } + } else { + if (!originalCrosshairYaw.isNaN()) { + mc.player?.yRot = originalCrosshairYaw + originalCrosshairYaw = Float.NaN + } + if (!originalCrosshairPitch.isNaN()) { + mc.player?.xRot = originalCrosshairPitch + originalCrosshairPitch = Float.NaN + } + } + } + + @Callback + fun onExtractRenderState(event : ExtractRenderStateEvent) { + if (event.entity == mc.player) { + if (event.pre) { + val currentYaw = if (!yaw.isNaN()) yaw else mc.player?.yRot ?: Float.NaN + val previousYaw = if (!lastYaw.isNaN()) lastYaw else mc.player?.yRotO ?: Float.NaN + + val currentPitch = if (!pitch.isNaN()) pitch else mc.player?.xRot ?: Float.NaN + val previousPitch = if (!lastPitch.isNaN()) lastPitch else mc.player?.xRotO ?: Float.NaN + + val currentBody = if (!bodyYaw.isNaN()) bodyYaw else mc.player?.yBodyRot ?: Float.NaN + val previousBody = if (!lastBodyYaw.isNaN()) lastBodyYaw else mc.player?.yBodyRotO ?: Float.NaN + + originalRenderYaw = mc.player?.yRot ?: Float.NaN + originalRenderLastYaw = mc.player?.yRotO ?: Float.NaN + originalRenderPitch = mc.player?.xRot ?: Float.NaN + originalRenderLastPitch = mc.player?.xRotO ?: Float.NaN + originalRenderBodyYaw = mc.player?.yBodyRot ?: Float.NaN + originalRenderLastBodyYaw = mc.player?.yBodyRotO ?: Float.NaN + + mc.player?.yRot = currentYaw + mc.player?.yRotO = previousYaw + + mc.player?.yHeadRot = currentYaw + mc.player?.yHeadRotO = previousYaw + + mc.player?.xRot = currentPitch + mc.player?.xRotO = previousPitch + + mc.player?.yBodyRot = currentBody + mc.player?.yBodyRotO = previousBody + + } else { + if (!originalRenderYaw.isNaN()) { + mc.player?.yRot = originalRenderYaw + mc.player?.yHeadRot = originalRenderYaw + originalRenderYaw = Float.NaN + } + if (!originalRenderLastYaw.isNaN()) { + mc.player?.yRotO = originalRenderLastYaw + mc.player?.yHeadRotO = originalRenderLastYaw + originalRenderLastYaw = Float.NaN + } + if (!originalRenderPitch.isNaN()) { + mc.player?.xRot = originalRenderPitch + originalRenderPitch = Float.NaN + } + if (!originalRenderLastPitch.isNaN()) { + mc.player?.xRotO = originalRenderLastPitch + originalRenderLastPitch = Float.NaN + } + if (!originalRenderBodyYaw.isNaN()) { + mc.player?.yBodyRot = originalRenderBodyYaw + originalRenderBodyYaw = Float.NaN + } + if (!originalRenderLastBodyYaw.isNaN()) { + mc.player?.yBodyRotO = originalRenderLastBodyYaw + originalRenderLastBodyYaw = Float.NaN + } + } + } + } + + private fun calcBodyYaw(): Float { + val player = mc.player ?: return 0f + val headYaw = when { + !yaw.isNaN() -> yaw + !player.yRot.isNaN() -> player.yRot + else -> 0f + } + var renderYaw = if (!bodyYaw.isNaN()) bodyYaw else player.yBodyRot + if (renderYaw.isNaN()) renderYaw = headYaw + var offset = renderYaw + val dx = player.x - player.xOld + val dz = player.z - player.zOld + if (dx * dx + dz * dz > 0.0025000002) { + var moveAngle = (atan2(dz, dx) * 57.295776 - 90.0).toFloat() + val diff = abs(MathUtil.wrapDegrees(headYaw - moveAngle)) + if (diff > 95.0f && diff < 265.0f) moveAngle -= 180.0f + offset = moveAngle + } + player.attackAnim?.let { + if (it > 0.0f) offset = headYaw + } + var proposedBodyYaw = renderYaw + MathUtil.wrapDegrees(offset - renderYaw) * 0.3f + val headDiff = MathUtil.wrapDegrees(headYaw - proposedBodyYaw) + if (abs(headDiff) > 50.0f) { + proposedBodyYaw += headDiff - sign(headDiff) * 50.0f + } + return if (proposedBodyYaw.isNaN() || !proposedBodyYaw.isFinite()) headYaw + else MathUtil.wrapDegrees(proposedBodyYaw) + } + + fun resetRotate(priority: Int = 0) { + if (priority >= currentPriority) { + val player = mc.player ?: return + if (!yaw.isNaN()) { + val diff = MathUtil.wrapDegrees(player.yRot - yaw) + if (abs(player.yRot - yaw) > 180F) { + val finalYaw = yaw + diff + player.yRot = finalYaw + player.yBob += (player.yRot - player.yBob) + player.yBobO = player.yBob + } + } + yaw = Float.NaN + pitch = Float.NaN + currentPriority = -1 + rotationSet = false + } + } + +} \ No newline at end of file diff --git a/src/main/kotlin/com/nekiplay/neoscripts/utils/aiming/Rotations.kt b/src/main/kotlin/com/nekiplay/neoscripts/utils/aiming/Rotations.kt new file mode 100644 index 00000000..a349fecf --- /dev/null +++ b/src/main/kotlin/com/nekiplay/neoscripts/utils/aiming/Rotations.kt @@ -0,0 +1,10 @@ +package com.nekiplay.neoscripts.utils.aiming + +object Rotations { + + val clientLook = false + var moveFix = true + val moveFixSilent = true + val hookCrosshairTarget = true + val pauseInInventory = true +} \ No newline at end of file diff --git a/src/main/kotlin/com/nekiplay/neoscripts/utils/animation/AnimationUtil.kt b/src/main/kotlin/com/nekiplay/neoscripts/utils/animation/AnimationUtil.kt new file mode 100644 index 00000000..f949638f --- /dev/null +++ b/src/main/kotlin/com/nekiplay/neoscripts/utils/animation/AnimationUtil.kt @@ -0,0 +1,9 @@ +package com.nekiplay.neoscripts.utils.animation + +object AnimationUtil { + + fun lerp(oldValue : Double, newValue : Double, interpolationValue : Double) = (oldValue + (newValue - oldValue) * interpolationValue) + fun lerp(oldValue : Float, newValue : Float, interpolationValue : Double) = ((oldValue + (newValue - oldValue) * interpolationValue).toFloat()) + fun lerp(oldValue : Float, newValue : Float, interpolationValue : Float) = (oldValue + (newValue - oldValue) * interpolationValue) + +} \ No newline at end of file diff --git a/src/main/kotlin/com/nekiplay/neoscripts/utils/game/InputUtil.kt b/src/main/kotlin/com/nekiplay/neoscripts/utils/game/InputUtil.kt new file mode 100644 index 00000000..2f14b93e --- /dev/null +++ b/src/main/kotlin/com/nekiplay/neoscripts/utils/game/InputUtil.kt @@ -0,0 +1,202 @@ +package com.nekiplay.neoscripts.utils.game + +import com.nekiplay.neoscripts.Main.mc +import com.nekiplay.neoscripts.events.PlayerTickEvent +import com.nekiplay.neoscripts.events.main.Callback +import com.nekiplay.neoscripts.events.main.EventBus +import net.minecraft.client.KeyMapping +import org.lwjgl.glfw.GLFW +import java.lang.reflect.Modifier +import kotlin.math.cos +import kotlin.math.sin + +object InputUtil { + + private val keyMap = HashMap() + val stringMap = HashMap() + + private val forwardKey by lazy { Key(mc.options.keyUp) } + private val backwardKey by lazy { Key(mc.options.keyDown) } + private val leftKey by lazy { Key(mc.options.keyLeft) } + private val rightKey by lazy { Key(mc.options.keyRight) } + private val spaceKey by lazy { Key(mc.options.keyJump) } + private val sprintKey by lazy { Key(mc.options.keySprint) } + + init { + for (field in GLFW::class.java.fields) { + if (Modifier.isStatic(field.modifiers) && (field.name.startsWith("GLFW_KEY_") || field.name.startsWith("GLFW_MOUSE_BUTTON_"))) { + try { + val code = field.getInt(null) + var name = field.name.substring( + if (field.name.startsWith("GLFW_KEY_")) 9 else 5 + ).replace("_", " ").replace("BUTTON ", "").lowercase() + keyMap[code] = name + stringMap[name] = code + } catch (e: Exception) { + e.printStackTrace() + } + } + } + } + + fun getStringKey(key : Int) : String { + if (key < 0) return "N/A" + val glfw = GLFW.glfwGetKeyName(key, 0) + + val str = + if (glfw != null) glfw + else keyMap.getOrDefault(key, "N/A") + + return str + } + + fun getKey(name : String) : Int { + return stringMap[name] ?: GLFW.GLFW_KEY_UNKNOWN + } + + fun getKeyOrNull(name : String) : Int? { + return stringMap[name] + } + + fun isPressed(key : Int, handle : Long) : Boolean { + if (key == GLFW.GLFW_KEY_UNKNOWN) return false + if (key <= GLFW.GLFW_MOUSE_BUTTON_LAST) return GLFW.glfwGetMouseButton(handle, key) == GLFW.GLFW_TRUE + return GLFW.glfwGetKey(handle, key) == GLFW.GLFW_TRUE + } + + fun isPressed(key : Int) : Boolean { + return isPressed(key, mc.window.handle()) + } + + fun calculateCorrectedKeys( + pressedW : Boolean, + pressedS : Boolean, + pressedA : Boolean, + pressedD : Boolean, + viewYaw : Float, + targetYaw : Float + ): MoveInput { + val forward = (if (pressedW) 1.0 else 0.0) - (if (pressedS) 1.0 else 0.0) + val strafe = (if (pressedA) 1.0 else 0.0) - (if (pressedD) 1.0 else 0.0) + + if (forward == 0.0 && strafe == 0.0) return MoveInput() + + val diffYaw = Math.toRadians((targetYaw - viewYaw).toDouble()) + + val cos = cos(diffYaw) + val sin = sin(diffYaw) + + val fixedForward = forward * cos - strafe * sin + val fixedStrafe = strafe * cos + forward * sin + + val threshold = 0.3 + + return MoveInput( + forward = fixedForward > threshold, + back = fixedForward < -threshold, + left = fixedStrafe > threshold, + right = fixedStrafe < -threshold + ) + } + + fun calculateImpulse(positive : Boolean, negative : Boolean): Float { + return if (positive == negative) 0.0f + else { + if (positive) 1.0f else -1.0f + } + } + + fun setForward(value : Boolean, ticks : Int = 0, priority : Int = 0) { + forwardKey.set(value, ticks, priority) + } + + fun setBackward(value : Boolean, ticks : Int = 0, priority : Int = 0) { + backwardKey.set(value, ticks, priority) + } + + fun setLeft(value : Boolean, ticks : Int = 0, priority : Int = 0) { + leftKey.set(value, ticks, priority) + } + + fun setRight(value : Boolean, ticks : Int = 0, priority : Int = 0) { + rightKey.set(value, ticks, priority) + } + + fun setSpace(value : Boolean, ticks : Int = 0, priority : Int = 0) { + spaceKey.set(value, ticks, priority) + } + + fun setSprint(value : Boolean, ticks : Int = 0, priority : Int = 0) { + sprintKey.set(value, ticks, priority) + } + + fun setAllMovement(value : Boolean, ticks : Int = 0, priority : Int = 0) { + forwardKey.set(value, ticks, priority) + backwardKey.set(value, ticks, priority) + leftKey.set(value, ticks, priority) + rightKey.set(value, ticks, priority) + spaceKey.set(value, ticks, priority) + sprintKey.set(value, ticks, priority) + } + + class Key(val key : KeyMapping) { + + var value = false + private set + var priority = -1 + private set + var ticks = -1 + private set + + private var set = false + private var lastValue = false + + init { + EventBus.register(this) + } + + fun set(value : Boolean, ticks : Int = 0, priority : Int = 0) { + if (priority >= this.priority) { + + this.lastValue = key.isDown + this.value = value + this.ticks = ticks + + this.set = true + this.priority = priority + } + } + + @Callback(-10) + fun onTick(event : PlayerTickEvent) { + + if (set) { + key.isDown = value + mc.player?.input?.tick() + } + + if (ticks >= 0) { + when { + ticks > 0 -> ticks-- + set -> set = false + else -> { + value = false + priority = -1 + ticks = -1 + set = false + key.isDown = isPressed(key.key.value) + mc.player?.input?.tick() + } + } + } + } + } + + data class MoveInput( + var forward : Boolean = false, + var back : Boolean = false, + var left : Boolean = false, + var right : Boolean = false + ) + +} \ No newline at end of file diff --git a/src/main/resources/fabric.mod.json b/src/main/resources/fabric.mod.json index 047c7de3..7eadd04e 100644 --- a/src/main/resources/fabric.mod.json +++ b/src/main/resources/fabric.mod.json @@ -19,7 +19,10 @@ "environment": "client", "entrypoints": { "client": [ - "com.nekiplay.neoscripts.Main" + { + "value": "com.nekiplay.neoscripts.Main", + "adapter": "kotlin" + } ] }, "mixins": [ diff --git a/src/main/resources/neoscripts.accesswidener b/src/main/resources/neoscripts.accesswidener index 7440d360..c862df6a 100644 --- a/src/main/resources/neoscripts.accesswidener +++ b/src/main/resources/neoscripts.accesswidener @@ -7,6 +7,16 @@ accessible field net/minecraft/world/level/saveddata/maps/MapItemSavedData track accessible field net/minecraft/world/level/saveddata/maps/MapItemSavedData frameMarkers Ljava/util/Map; accessible method net/minecraft/client/player/KeyboardInput calculateImpulse (ZZ)F +accessible field net/minecraft/client/KeyMapping key Lcom/mojang/blaze3d/platform/InputConstants$Key; +accessible field net/minecraft/client/player/ClientInput moveVector Lnet/minecraft/world/phys/Vec2; +accessible field net/minecraft/network/protocol/game/ServerboundUseItemPacket yRot F +mutable field net/minecraft/network/protocol/game/ServerboundUseItemPacket yRot F +accessible field net/minecraft/network/protocol/game/ServerboundUseItemPacket xRot F +mutable field net/minecraft/network/protocol/game/ServerboundUseItemPacket xRot F +accessible field net/minecraft/client/multiplayer/ClientLevel blockStatePredictionHandler Lnet/minecraft/client/multiplayer/prediction/BlockStatePredictionHandler; +accessible field net/minecraft/client/player/LocalPlayer yRotLast F +accessible field net/minecraft/client/player/LocalPlayer xRotLast F + accessible class net/minecraft/client/Minecraft$GameLoadCookie accessible field net/minecraft/client/gui/components/BossHealthOverlay events Ljava/util/Map; \ No newline at end of file From 67a67e0c67c96753239ba79b5522aa215dc98eec Mon Sep 17 00:00:00 2001 From: Roman Danilov Date: Sat, 25 Apr 2026 02:58:35 +0500 Subject: [PATCH 02/27] Update Rotations.kt --- .../kotlin/com/nekiplay/neoscripts/utils/aiming/Rotations.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/kotlin/com/nekiplay/neoscripts/utils/aiming/Rotations.kt b/src/main/kotlin/com/nekiplay/neoscripts/utils/aiming/Rotations.kt index a349fecf..1bf6a2f7 100644 --- a/src/main/kotlin/com/nekiplay/neoscripts/utils/aiming/Rotations.kt +++ b/src/main/kotlin/com/nekiplay/neoscripts/utils/aiming/Rotations.kt @@ -4,7 +4,7 @@ object Rotations { val clientLook = false var moveFix = true - val moveFixSilent = true + var moveFixSilent = true val hookCrosshairTarget = true val pauseInInventory = true } \ No newline at end of file From 2e6f4a8b7a17e2ea6e2312c604112ed0c3f3673f Mon Sep 17 00:00:00 2001 From: Roman Danilov Date: Sat, 25 Apr 2026 03:15:28 +0500 Subject: [PATCH 03/27] Fixes --- .../neoscripts/features/lua/LuaScript.kt | 66 +++++++++---------- .../features/modules/impl/misc/LuaEvents.kt | 46 ++++++------- .../nekiplay/neoscripts/utils/ServerUtil.kt | 10 +-- 3 files changed, 61 insertions(+), 61 deletions(-) diff --git a/src/main/kotlin/com/nekiplay/neoscripts/features/lua/LuaScript.kt b/src/main/kotlin/com/nekiplay/neoscripts/features/lua/LuaScript.kt index 20548570..84b85219 100644 --- a/src/main/kotlin/com/nekiplay/neoscripts/features/lua/LuaScript.kt +++ b/src/main/kotlin/com/nekiplay/neoscripts/features/lua/LuaScript.kt @@ -632,7 +632,7 @@ class LuaScript(val scriptName: String, private val luaManager: LuaManager) { message.append(args.arg(i).tojstring()) } val messageStr = message.toString() - Main.LOGGER.info(Main.LOG_PREFIX + messageStr) + Main.LOGGER?.info(Main.LOG_PREFIX + messageStr) return NIL } }) @@ -704,11 +704,11 @@ class LuaScript(val scriptName: String, private val luaManager: LuaManager) { commandDispatchers[commandName] = fabricDispatcher actualRegister(fabricDispatcher, commandName) - Main.LOGGER.info("${Main.LOG_PREFIX}Registered Minecraft command: /$commandName") + Main.LOGGER?.info("${Main.LOG_PREFIX}Registered Minecraft command: /$commandName") } } } catch (e: Exception) { - Main.LOGGER.error("${Main.LOG_PREFIX}Failed to register Minecraft command: /$commandName", e) + Main.LOGGER?.error("${Main.LOG_PREFIX}Failed to register Minecraft command: /$commandName", e) } } @@ -768,9 +768,9 @@ class LuaScript(val scriptName: String, private val luaManager: LuaManager) { dispatcher.register(commandBuilder) if (dispatcher.root.getChild(commandName) == null) { - Main.LOGGER.error("Failed to inject node into dispatcher root!") + Main.LOGGER?.error("Failed to inject node into dispatcher root!") } else { - Main.LOGGER.info("Successfully injected command: $commandName with suggestions: ${suggestionsCallback != null}") + Main.LOGGER?.info("Successfully injected command: $commandName with suggestions: ${suggestionsCallback != null}") } } @@ -825,7 +825,7 @@ class LuaScript(val scriptName: String, private val luaManager: LuaManager) { builder.suggest(result.tojstring()) } } catch (e: Exception) { - Main.LOGGER.error("${Main.LOG_PREFIX}Error getting suggestions for command /$commandName", e) + Main.LOGGER?.error("${Main.LOG_PREFIX}Error getting suggestions for command /$commandName", e) } builder.build() } @@ -853,7 +853,7 @@ class LuaScript(val scriptName: String, private val luaManager: LuaManager) { map.remove(commandName) } catch (e: NoSuchFieldException) { // Если вдруг библиотека Brigadier в вашей среде имеет другие названия полей - Main.LOGGER.warn("Field $fieldName not found in CommandNode") + Main.LOGGER?.warn("Field $fieldName not found in CommandNode") } } @@ -861,9 +861,9 @@ class LuaScript(val scriptName: String, private val luaManager: LuaManager) { commandDispatchers.remove(commandName) commandCallbacks.remove(commandName) - Main.LOGGER.info("${Main.LOG_PREFIX}Successfully unregistered Lua command: /$commandName") + Main.LOGGER?.info("${Main.LOG_PREFIX}Successfully unregistered Lua command: /$commandName") } catch (e: Exception) { - Main.LOGGER.error("${Main.LOG_PREFIX}Failed to unregister command /$commandName", e) + Main.LOGGER?.error("${Main.LOG_PREFIX}Failed to unregister command /$commandName", e) } } @@ -875,7 +875,7 @@ class LuaScript(val scriptName: String, private val luaManager: LuaManager) { val argsTable = LuaValue.listOf(args.map { LuaValue.valueOf(it) }.toTypedArray()) callback.call(LuaValue.valueOf(commandName), argsTable, LuaValue.valueOf(source?.player?.name?.string ?: "")) } catch (e: Exception) { - Main.LOGGER.error("${Main.LOG_PREFIX}Error executing Lua command: /$commandName", e) + Main.LOGGER?.error("${Main.LOG_PREFIX}Error executing Lua command: /$commandName", e) source?.sendError(Component.literal("Error executing command: ${e.message}")) } } @@ -907,7 +907,7 @@ class LuaScript(val scriptName: String, private val luaManager: LuaManager) { callback.call(t) } catch (e: Exception) { - Main.LOGGER.error("${Main.LOG_PREFIX}Error in slot click callback in ${scriptName}", e) + Main.LOGGER?.error("${Main.LOG_PREFIX}Error in slot click callback in ${scriptName}", e) } } } @@ -925,7 +925,7 @@ class LuaScript(val scriptName: String, private val luaManager: LuaManager) { allow = false } } catch (e: Exception) { - Main.LOGGER.error("${Main.LOG_PREFIX}Error in inventory add item callback in ${scriptName}", e) + Main.LOGGER?.error("${Main.LOG_PREFIX}Error in inventory add item callback in ${scriptName}", e) } } return allow @@ -953,7 +953,7 @@ class LuaScript(val scriptName: String, private val luaManager: LuaManager) { allow = false } } catch (e: Exception) { - Main.LOGGER.error("${Main.LOG_PREFIX}Error in on send player movement callback in ${scriptName}", e) + Main.LOGGER?.error("${Main.LOG_PREFIX}Error in on send player movement callback in ${scriptName}", e) } } return allow @@ -979,7 +979,7 @@ class LuaScript(val scriptName: String, private val luaManager: LuaManager) { allow = false } } catch (e: Exception) { - Main.LOGGER.error("${Main.LOG_PREFIX}Error in sound play callback in ${scriptName}", e) + Main.LOGGER?.error("${Main.LOG_PREFIX}Error in sound play callback in ${scriptName}", e) } } return allow @@ -1004,7 +1004,7 @@ class LuaScript(val scriptName: String, private val luaManager: LuaManager) { allow = false } } catch (e: Exception) { - Main.LOGGER.error("${Main.LOG_PREFIX}Error in attack block callback in ${scriptName}", e) + Main.LOGGER?.error("${Main.LOG_PREFIX}Error in attack block callback in ${scriptName}", e) } } return allow @@ -1026,7 +1026,7 @@ class LuaScript(val scriptName: String, private val luaManager: LuaManager) { allow = false } } catch (e: Exception) { - Main.LOGGER.error("${Main.LOG_PREFIX}Error in use block callback in ${scriptName}", e) + Main.LOGGER?.error("${Main.LOG_PREFIX}Error in use block callback in ${scriptName}", e) } } return allow @@ -1041,7 +1041,7 @@ class LuaScript(val scriptName: String, private val luaManager: LuaManager) { try { callback.call() } catch (e: Exception) { - Main.LOGGER.error("${Main.LOG_PREFIX}Error in client tick callback in ${scriptName}", e) + Main.LOGGER?.error("${Main.LOG_PREFIX}Error in client tick callback in ${scriptName}", e) } } } @@ -1055,7 +1055,7 @@ class LuaScript(val scriptName: String, private val luaManager: LuaManager) { try { callback.call() } catch (e: Exception) { - Main.LOGGER.error("${Main.LOG_PREFIX}Error in client pre tick callback in ${scriptName}", e) + Main.LOGGER?.error("${Main.LOG_PREFIX}Error in client pre tick callback in ${scriptName}", e) } } } @@ -1069,7 +1069,7 @@ class LuaScript(val scriptName: String, private val luaManager: LuaManager) { try { callback.call(context) } catch (e: Exception) { - Main.LOGGER.error("${Main.LOG_PREFIX}Error in world render callback in ${scriptName}: ${e.message}") + Main.LOGGER?.error("${Main.LOG_PREFIX}Error in world render callback in ${scriptName}: ${e.message}") } } } @@ -1084,7 +1084,7 @@ class LuaScript(val scriptName: String, private val luaManager: LuaManager) { try { callback.call(renderContext) } catch (e: Exception) { - Main.LOGGER.error("${Main.LOG_PREFIX}Error in 2D render callback in ${scriptName}: ${e.message}") + Main.LOGGER?.error("${Main.LOG_PREFIX}Error in 2D render callback in ${scriptName}: ${e.message}") } } } @@ -1103,7 +1103,7 @@ class LuaScript(val scriptName: String, private val luaManager: LuaManager) { } } } catch (e: Exception) { - Main.LOGGER.error("${Main.LOG_PREFIX}Error in key callback in ${scriptName}: ${e.message}") + Main.LOGGER?.error("${Main.LOG_PREFIX}Error in key callback in ${scriptName}: ${e.message}") } } return allow @@ -1123,7 +1123,7 @@ class LuaScript(val scriptName: String, private val luaManager: LuaManager) { } } } catch (e: Exception) { - Main.LOGGER.error("${Main.LOG_PREFIX}Error in message callback in ${scriptName}: ${e.message}") + Main.LOGGER?.error("${Main.LOG_PREFIX}Error in message callback in ${scriptName}: ${e.message}") } } return allow @@ -1143,7 +1143,7 @@ class LuaScript(val scriptName: String, private val luaManager: LuaManager) { } } } catch (e: Exception) { - Main.LOGGER.error("${Main.LOG_PREFIX}Error in send message callback in ${scriptName}: ${e.message}") + Main.LOGGER?.error("${Main.LOG_PREFIX}Error in send message callback in ${scriptName}: ${e.message}") } } return allow @@ -1163,7 +1163,7 @@ class LuaScript(val scriptName: String, private val luaManager: LuaManager) { } } } catch (e: Exception) { - Main.LOGGER.error("${Main.LOG_PREFIX}Error in send command callback in ${scriptName}: ${e.message}") + Main.LOGGER?.error("${Main.LOG_PREFIX}Error in send command callback in ${scriptName}: ${e.message}") } } return allow @@ -1183,7 +1183,7 @@ class LuaScript(val scriptName: String, private val luaManager: LuaManager) { } } } catch (e: Exception) { - Main.LOGGER.error("${Main.LOG_PREFIX}Error in block update callback in ${scriptName}: ${e.message}") + Main.LOGGER?.error("${Main.LOG_PREFIX}Error in block update callback in ${scriptName}: ${e.message}") } } return allow @@ -1198,7 +1198,7 @@ class LuaScript(val scriptName: String, private val luaManager: LuaManager) { try { callback.call(LuaValue.valueOf(location.toString())) } catch (e: Exception) { - Main.LOGGER.error("${Main.LOG_PREFIX}Error in location change callback in ${scriptName}: ${e.message}") + Main.LOGGER?.error("${Main.LOG_PREFIX}Error in location change callback in ${scriptName}: ${e.message}") } } return true @@ -1213,7 +1213,7 @@ class LuaScript(val scriptName: String, private val luaManager: LuaManager) { try { callback.call() } catch (e: Exception) { - Main.LOGGER.error("${Main.LOG_PREFIX}Error in imgui callback in ${scriptName}: ${e.message}") + Main.LOGGER?.error("${Main.LOG_PREFIX}Error in imgui callback in ${scriptName}: ${e.message}") } } return true @@ -1240,7 +1240,7 @@ class LuaScript(val scriptName: String, private val luaManager: LuaManager) { try { callback.call(t) } catch (e: Exception) { - Main.LOGGER.error("${Main.LOG_PREFIX}Error in particle callback in ${scriptName}: ${e.message}") + Main.LOGGER?.error("${Main.LOG_PREFIX}Error in particle callback in ${scriptName}: ${e.message}") } } } @@ -1260,7 +1260,7 @@ class LuaScript(val scriptName: String, private val luaManager: LuaManager) { } } } catch (e: Exception) { - Main.LOGGER.error("${Main.LOG_PREFIX}Error in server side rotation callback in ${scriptName}: ${e.message}") + Main.LOGGER?.error("${Main.LOG_PREFIX}Error in server side rotation callback in ${scriptName}: ${e.message}") } } return allow @@ -1275,7 +1275,7 @@ class LuaScript(val scriptName: String, private val luaManager: LuaManager) { try { callback.call(LuaValue.valueOf(dayTime), LuaValue.valueOf(gameTime), LuaValue.valueOf(tickDayTime)) } catch (e: Exception) { - Main.LOGGER.error("${Main.LOG_PREFIX}Error in server side time callback in ${scriptName}: ${e.message}") + Main.LOGGER?.error("${Main.LOG_PREFIX}Error in server side time callback in ${scriptName}: ${e.message}") } } } @@ -1386,7 +1386,7 @@ class LuaScript(val scriptName: String, private val luaManager: LuaManager) { } } } catch (e: Exception) { - Main.LOGGER.error("${Main.LOG_PREFIX}Error in server side rotation callback in ${scriptName}: ${e.message}") + Main.LOGGER?.error("${Main.LOG_PREFIX}Error in server side rotation callback in ${scriptName}: ${e.message}") } } return allow @@ -1401,7 +1401,7 @@ class LuaScript(val scriptName: String, private val luaManager: LuaManager) { try { callback.call() } catch (e: Exception) { - Main.LOGGER.error("${Main.LOG_PREFIX}Error in imgui init callback in ${scriptName}: ${e.message}") + Main.LOGGER?.error("${Main.LOG_PREFIX}Error in imgui init callback in ${scriptName}: ${e.message}") } } } @@ -1413,7 +1413,7 @@ class LuaScript(val scriptName: String, private val luaManager: LuaManager) { try { callback.call() } catch (e: Exception) { - Main.LOGGER.error("${Main.LOG_PREFIX}Error in script unload callback in ${scriptName}", e) + Main.LOGGER?.error("${Main.LOG_PREFIX}Error in script unload callback in ${scriptName}", e) } } diff --git a/src/main/kotlin/com/nekiplay/neoscripts/features/modules/impl/misc/LuaEvents.kt b/src/main/kotlin/com/nekiplay/neoscripts/features/modules/impl/misc/LuaEvents.kt index 0d5edb65..7b66fdae 100644 --- a/src/main/kotlin/com/nekiplay/neoscripts/features/modules/impl/misc/LuaEvents.kt +++ b/src/main/kotlin/com/nekiplay/neoscripts/features/modules/impl/misc/LuaEvents.kt @@ -48,7 +48,7 @@ import org.luaj.vm2.LuaValue object LuaEvents : ClientModule() { override fun init() { ClientTickEvents.END_CLIENT_TICK.register { _ -> - LUA_MANAGER.scripts.values.forEach { script -> + LUA_MANAGER?.scripts?.values?.forEach { script -> try { script.onClientTick() } catch (e: Exception) { @@ -58,7 +58,7 @@ object LuaEvents : ClientModule() { } ClientTickEvents.START_CLIENT_TICK.register { _ -> - LUA_MANAGER.scripts.values.forEach { script -> + LUA_MANAGER?.scripts?.values?.forEach { script -> try { script.onClientTickPre() } catch (e: Exception) { @@ -69,7 +69,7 @@ object LuaEvents : ClientModule() { WorldRenderExtractionCallback.EVENT.register({ context: PrimitiveCollector? -> val renderContext = WorldRendererObject(context) - LUA_MANAGER.scripts.values.forEach { script -> + LUA_MANAGER?.scripts?.values?.forEach { script -> try { script.onRenderTick(renderContext) } catch (e: Exception) { @@ -80,7 +80,7 @@ object LuaEvents : ClientModule() { KeyEvent.EVENT.register(KeyEvent.KeyCallback { keyEvent -> var allow = true - LUA_MANAGER.scripts.values.forEach { script -> + LUA_MANAGER?.scripts?.values?.forEach { script -> try { if (!script.onKeyEvent(keyEvent.key, keyEvent.action)) { allow = false @@ -98,7 +98,7 @@ object LuaEvents : ClientModule() { MouseButtonEvent.EVENT.register(MouseButtonEvent.KeyCallback { mouseButtonEvent -> var allow = true - LUA_MANAGER.scripts.values.forEach { script -> + LUA_MANAGER?.scripts?.values?.forEach { script -> try { if (!script.onKeyEvent(mouseButtonEvent.button, mouseButtonEvent.action)) { allow = false @@ -117,7 +117,7 @@ object LuaEvents : ClientModule() { UseBlockCallback.EVENT.register(UseBlockCallback { player: Player, world: Level, hand: InteractionHand, hitResult: BlockHitResult -> var allow = true if (hitResult.type == HitResult.Type.BLOCK || hitResult.type == HitResult.Type.MISS) { - LUA_MANAGER.scripts.values.forEach { script -> + LUA_MANAGER?.scripts?.values?.forEach { script -> try { if (!script.onUseBlock(hitResult.blockPos, hand)) { allow = false @@ -137,7 +137,7 @@ object LuaEvents : ClientModule() { AttackBlockCallback.EVENT.register(AttackBlockCallback { player: Player, world: Level, hand: InteractionHand, pos: BlockPos, direction: Direction -> var allow = true - LUA_MANAGER.scripts.values.forEach { script -> + LUA_MANAGER?.scripts?.values?.forEach { script -> try { if (!script.onAttackBlock(pos, direction, hand)) { allow = false @@ -156,7 +156,7 @@ object LuaEvents : ClientModule() { ClientReceiveMessageEvents.ALLOW_GAME.register(ClientReceiveMessageEvents.AllowGame { text, overlay -> var allow = true - LUA_MANAGER.scripts.values.forEach { script -> + LUA_MANAGER?.scripts?.values?.forEach { script -> try { if (!script.onChatMessageEvent(text.getFormattedString(), overlay, text.getJsonString())) { allow = false @@ -170,7 +170,7 @@ object LuaEvents : ClientModule() { ClientSendMessageEvents.ALLOW_CHAT.register(ClientSendMessageEvents.AllowChat { text -> var allow = true - LUA_MANAGER.scripts.values.forEach { script -> + LUA_MANAGER?.scripts?.values?.forEach { script -> try { if (!script.onSendChatMessageEvent(text)) { allow = false @@ -185,7 +185,7 @@ object LuaEvents : ClientModule() { ClientSendMessageEvents.ALLOW_COMMAND.register { command -> var allow = true val cmdName = command.split(" ")[0] - LUA_MANAGER.scripts.values.forEach { script -> + LUA_MANAGER?.scripts?.values?.forEach { script -> try { if (!script.onSendChatCommandEvent(command)) { allow = false @@ -197,7 +197,7 @@ object LuaEvents : ClientModule() { if (allow) { var founded = false - LUA_MANAGER.scripts.values.forEach { script -> + LUA_MANAGER?.scripts?.values?.forEach { script -> if (script.commandCallbacks.containsKey(cmdName) && script.commandDispatchers.containsKey(cmdName)) { founded = true player?.let { @@ -209,7 +209,7 @@ object LuaEvents : ClientModule() { @Suppress("UNCHECKED_CAST") val result = (dispatcher as CommandDispatcher).execute(command, source) if (result >= 1) { - Main.LOGGER.info("${Main.LOG_PREFIX}Executing command: $command") + Main.LOGGER?.info("${Main.LOG_PREFIX}Executing command: $command") return@register false } @@ -228,7 +228,7 @@ object LuaEvents : ClientModule() { } HudRenderCallback.EVENT.register(HudRenderCallback { context, _ -> - LUA_MANAGER.scripts.values.forEach { script -> + LUA_MANAGER?.scripts?.values?.forEach { script -> try { script.on2DRenderTick(context) } catch (e: Exception) { @@ -238,7 +238,7 @@ object LuaEvents : ClientModule() { }) SkyblockEvents.LOCATION_CHANGE.register { location -> - LUA_MANAGER.scripts.values.forEach { script -> + LUA_MANAGER?.scripts?.values?.forEach { script -> try { script.onLocationChangeEvent(location) } catch (e: Exception) { @@ -251,7 +251,7 @@ object LuaEvents : ClientModule() { is ServerboundMovePlayerPacket -> { val packet = event.packet as ServerboundMovePlayerPacket var allowed = true - LUA_MANAGER.scripts.values.forEach { script -> + LUA_MANAGER?.scripts?.values?.forEach { script -> if (!script.onPlayerSendMovement( packet.hasPosition(), packet.getX(0.0), @@ -276,7 +276,7 @@ object LuaEvents : ClientModule() { is ServerboundMovePlayerPacket -> { val packet = event.packet as ServerboundMovePlayerPacket var allowed = true - LUA_MANAGER.scripts.values.forEach { script -> + LUA_MANAGER?.scripts?.values?.forEach { script -> if (!script.onPlayerSendMovement( packet.hasPosition(), packet.getX(0.0), @@ -301,7 +301,7 @@ object LuaEvents : ClientModule() { is ClientboundLevelParticlesPacket -> { val packet = event.packet as ClientboundLevelParticlesPacket - LUA_MANAGER.scripts.values.forEach { script -> + LUA_MANAGER?.scripts?.values?.forEach { script -> script.onSpawnParticleEvent( BuiltInRegistries.PARTICLE_TYPE.getId(packet.particle.type), packet.x, @@ -319,7 +319,7 @@ object LuaEvents : ClientModule() { is ClientboundSetTimePacket -> { val packet = event.packet as ClientboundSetTimePacket - LUA_MANAGER.scripts.values.forEach { script -> + LUA_MANAGER?.scripts?.values?.forEach { script -> script.onServerSideSetTimeEvent(packet.dayTime, packet.gameTime, packet.tickDayTime) } } @@ -327,7 +327,7 @@ object LuaEvents : ClientModule() { is ClientboundSoundPacket -> { val packet = event.packet as ClientboundSoundPacket - LUA_MANAGER.scripts.values.forEach { script -> + LUA_MANAGER?.scripts?.values?.forEach { script -> script.onSoundPlay(packet.sound, packet.x, packet.y, packet.z, packet.pitch.toDouble(), packet.volume.toDouble()) } } @@ -335,7 +335,7 @@ object LuaEvents : ClientModule() { val allow = when (val packet = event.packet) { is ClientboundPlayerRotationPacket -> { var rotationAllowed = true - LUA_MANAGER.scripts.values.forEach { script -> + LUA_MANAGER?.scripts?.values?.forEach { script -> if (!script.onServerSideRotationEvent(packet.xRot, packet.yRot)) { rotationAllowed = false } @@ -358,7 +358,7 @@ object LuaEvents : ClientModule() { table.set("new", LuaBlockState(packet.blockState)) } - LUA_MANAGER.scripts.values.forEach { script -> + LUA_MANAGER?.scripts?.values?.forEach { script -> if (!script.onBlockUpdateEvent(table)) { allowedBlockUpdate = false } @@ -371,7 +371,7 @@ object LuaEvents : ClientModule() { var rotationAllowed = true var teleportAllowed = true - LUA_MANAGER.scripts.values.forEach { script -> + LUA_MANAGER?.scripts?.values?.forEach { script -> if (!script.onServerSideRotationEvent(packet.change.xRot(), packet.change.yRot())) { rotationAllowed = false } @@ -395,7 +395,7 @@ object LuaEvents : ClientModule() { } AddItemInventoryEvent.EVENT.register { event -> var allow = true - LUA_MANAGER.scripts.values.forEach { script -> + LUA_MANAGER?.scripts?.values?.forEach { script -> try { if (!script.onInventoryItemAChange(event.slot, event.item)) { allow = false diff --git a/src/main/kotlin/com/nekiplay/neoscripts/utils/ServerUtil.kt b/src/main/kotlin/com/nekiplay/neoscripts/utils/ServerUtil.kt index fecb205f..15f84875 100644 --- a/src/main/kotlin/com/nekiplay/neoscripts/utils/ServerUtil.kt +++ b/src/main/kotlin/com/nekiplay/neoscripts/utils/ServerUtil.kt @@ -9,6 +9,8 @@ import net.minecraft.network.protocol.game.ClientboundPlayerPositionPacket import net.minecraft.network.protocol.game.ClientboundSetHeldSlotPacket import net.minecraft.network.protocol.game.ServerboundMovePlayerPacket import net.minecraft.network.protocol.game.ServerboundSetCarriedItemPacket +import net.minecraft.world.item.ItemStack +import net.minecraft.world.item.Items object ServerUtil { @@ -71,13 +73,13 @@ object ServerUtil { } fun sendPacket(packet : Packet<*>) { - player.connection.connection.send(packet) + mc.player?.connection?.connection?.send(packet) } @Deprecated(message = "Ignores absolutely all callbacks. Use EventBus.setIgnore(value : Boolean, type : Class, instance : Any?)") fun sendPacketSilently(packet : Packet<*>) { silentPackets.add(packet) - player.connection.connection.send(packet) + mc.player?.connection?.connection?.send(packet) } fun sendPacket(packet : Packet<*>, delay : Int) { @@ -85,10 +87,8 @@ object ServerUtil { else delayedPackets.add(DelayedPacket(packet, delay)) } - fun mainHandItem() : ItemStack = inventory.getItem(slot) - fun getPing() : Int { - return player.connection.getPlayerInfo(player.uuid)?.latency ?: 0 + return mc.player?.connection?.getPlayerInfo(mc.player?.uuid)?.latency ?: 0 } private data class DelayedPacket(val packet : Packet<*>, var ticks : Int) From c093c508f51c06273c8081781ef212eaf0f94b67 Mon Sep 17 00:00:00 2001 From: Roman Danilov Date: Sat, 25 Apr 2026 03:18:45 +0500 Subject: [PATCH 04/27] Fixes #2 --- .../features/commands/impl/LuaCommand.kt | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/main/kotlin/com/nekiplay/neoscripts/features/commands/impl/LuaCommand.kt b/src/main/kotlin/com/nekiplay/neoscripts/features/commands/impl/LuaCommand.kt index 48da6ca0..1e3e10ba 100644 --- a/src/main/kotlin/com/nekiplay/neoscripts/features/commands/impl/LuaCommand.kt +++ b/src/main/kotlin/com/nekiplay/neoscripts/features/commands/impl/LuaCommand.kt @@ -140,7 +140,7 @@ object LuaCommand { private fun toggleScript(source: FabricClientCommandSource, name: String) { val luaManager = Main.LUA_MANAGER - val loadedScripts = luaManager.getLoadedScripts() + val loadedScripts = luaManager?.getLoadedScripts() ?: emptyList() // 1. Пытаемся найти уже загруженный скрипт по имени val loadedInstance = loadedScripts.find { it.scriptName.equals(name, ignoreCase = true) } @@ -148,7 +148,7 @@ object LuaCommand { if (loadedInstance != null) { // Если скрипт загружен — ВЫГРУЖАЕМ try { - luaManager.unloadScript(loadedInstance.scriptName) + luaManager?.unloadScript(loadedInstance.scriptName) source.sendFeedback(Component.literal("${Main.PREFIX}§7Script §a${loadedInstance.scriptName} §7has been §cunloaded§7.")) } catch (e: Exception) { source.sendFeedback(Component.literal("${Main.PREFIX}§cError unloading script: ${e.message}")) @@ -165,7 +165,7 @@ object LuaCommand { if (scriptFile.exists()) { try { // Предполагается, что в LuaManager есть метод loadScript(File) - luaManager.executeScript(scriptFile) + luaManager?.executeScript(scriptFile) source.sendFeedback(Component.literal("${Main.PREFIX}§7Script §a$name §7is now §aloaded§7.")) } catch (e: Exception) { source.sendFeedback(Component.literal("${Main.PREFIX}§cFailed to load script §e$name§c: ${e.message}")) @@ -222,7 +222,7 @@ object LuaCommand { private fun suggestLoadedScripts(builder: SuggestionsBuilder): CompletableFuture { val luaManager = Main.LUA_MANAGER - val loadedScripts = luaManager.getLoadedScripts() + val loadedScripts = luaManager?.getLoadedScripts() ?: emptyList() val input = builder.remainingLowerCase loadedScripts.forEach { scriptName -> @@ -253,12 +253,12 @@ object LuaCommand { try { // Сначала выгружаем существующий скрипт, если он загружен - val wasLoaded = luaManager.unloadScript(scriptFile.nameWithoutExtension) + val wasLoaded = luaManager?.unloadScript(scriptFile.nameWithoutExtension) // Затем загружаем скрипт - val result = luaManager.executeScript(scriptFile) + val result = luaManager?.executeScript(scriptFile) - if (wasLoaded) { + if (wasLoaded == true) { source.sendFeedback(Component.literal(Main.PREFIX + "§aScript '${scriptFile.nameWithoutExtension}' restarted successfully, result: '${result}'")) } else { source.sendFeedback(Component.literal(Main.PREFIX + "§aScript '${scriptFile.nameWithoutExtension}' executed successfully, result: '${result}'")) @@ -289,7 +289,7 @@ object LuaCommand { } - if (luaManager.unloadScript(scriptName)) { + if (luaManager?.unloadScript(scriptName) == true) { source.sendFeedback(Component.literal(Main.PREFIX + "§aScript '$scriptName' unloaded successfully")) @@ -324,7 +324,7 @@ object LuaCommand { private fun listLoadedScripts(source: FabricClientCommandSource, targetName: String?) { val luaManager = Main.LUA_MANAGER - val loadedScripts = luaManager.getLoadedScripts() + val loadedScripts = luaManager?.getLoadedScripts() ?: emptyList() if (loadedScripts.isEmpty()) { source.sendFeedback(Component.literal("${Main.PREFIX}§7No scripts currently loaded")) From 9ceabd756a654feca56731375541c247851cff40 Mon Sep 17 00:00:00 2001 From: Roman Danilov Date: Sat, 25 Apr 2026 03:24:30 +0500 Subject: [PATCH 05/27] Fixes #3 --- .../features/lua/objects/datatypes/LuaEntity.kt | 14 +++++++++----- .../features/lua/objects/modules/ModulesObject.kt | 4 ++-- .../features/lua/objects/world/WorldObject.kt | 2 +- .../com/nekiplay/neoscripts/utils/ServerUtil.kt | 4 ---- 4 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/main/kotlin/com/nekiplay/neoscripts/features/lua/objects/datatypes/LuaEntity.kt b/src/main/kotlin/com/nekiplay/neoscripts/features/lua/objects/datatypes/LuaEntity.kt index 0bab102f..9f8103e5 100644 --- a/src/main/kotlin/com/nekiplay/neoscripts/features/lua/objects/datatypes/LuaEntity.kt +++ b/src/main/kotlin/com/nekiplay/neoscripts/features/lua/objects/datatypes/LuaEntity.kt @@ -276,11 +276,15 @@ class LuaEntity(val entity: Entity): LuaUserdata(entity) { } } "nbt" -> { - val registryLookup = Utils.getRegistryWrapperLookup() - val reporter = ProblemReporter.ScopedCollector(Main.LOGGER) - val output = TagValueOutput.createWithContext(reporter, registryLookup) - entity.saveWithoutId(output) - valueOf(output.buildResult().toString()) + val logger = Main.LOGGER + if (logger != null) { + val registryLookup = Utils.getRegistryWrapperLookup() + val reporter = ProblemReporter.ScopedCollector(Main.LOGGER) + val output = TagValueOutput.createWithContext(reporter, registryLookup) + entity.saveWithoutId(output) + valueOf(output.buildResult().toString()) + } + else { NIL } } "teleport" -> TeleportFunction() else -> super.get(key) diff --git a/src/main/kotlin/com/nekiplay/neoscripts/features/lua/objects/modules/ModulesObject.kt b/src/main/kotlin/com/nekiplay/neoscripts/features/lua/objects/modules/ModulesObject.kt index b29d927c..da0cd8d8 100644 --- a/src/main/kotlin/com/nekiplay/neoscripts/features/lua/objects/modules/ModulesObject.kt +++ b/src/main/kotlin/com/nekiplay/neoscripts/features/lua/objects/modules/ModulesObject.kt @@ -41,7 +41,7 @@ class ModulesObject: LuaValue() { var index = 1 // 1. Находим объект скрипта в менеджере - val scriptObject = LUA_MANAGER.getLoadedScripts().find { it.scriptName == scriptName } + val scriptObject = LUA_MANAGER?.getLoadedScripts()?.find { it.scriptName == scriptName } // 2. Если нашли, берем его граф зависимостей // Предполагаем, что localDependencyGraph: Map> @@ -61,7 +61,7 @@ class ModulesObject: LuaValue() { override fun call(): LuaValue { val table = tableOf() var index = 1 - for (script in LUA_MANAGER.getLoadedScripts()) { + for (script in LUA_MANAGER?.getLoadedScripts() ?: emptyList()) { table.set(index, script.scriptName) index++ } diff --git a/src/main/kotlin/com/nekiplay/neoscripts/features/lua/objects/world/WorldObject.kt b/src/main/kotlin/com/nekiplay/neoscripts/features/lua/objects/world/WorldObject.kt index ef6f50f4..fcfe41d9 100644 --- a/src/main/kotlin/com/nekiplay/neoscripts/features/lua/objects/world/WorldObject.kt +++ b/src/main/kotlin/com/nekiplay/neoscripts/features/lua/objects/world/WorldObject.kt @@ -334,7 +334,7 @@ class WorldObject : LuaValue() { if (state != null) { targetBlocks.add(state.block) } else { - Main.LOGGER.warn("No block found for ID: $id") + Main.LOGGER?.warn("No block found for ID: $id") } } } diff --git a/src/main/kotlin/com/nekiplay/neoscripts/utils/ServerUtil.kt b/src/main/kotlin/com/nekiplay/neoscripts/utils/ServerUtil.kt index 15f84875..59492358 100644 --- a/src/main/kotlin/com/nekiplay/neoscripts/utils/ServerUtil.kt +++ b/src/main/kotlin/com/nekiplay/neoscripts/utils/ServerUtil.kt @@ -87,10 +87,6 @@ object ServerUtil { else delayedPackets.add(DelayedPacket(packet, delay)) } - fun getPing() : Int { - return mc.player?.connection?.getPlayerInfo(mc.player?.uuid)?.latency ?: 0 - } - private data class DelayedPacket(val packet : Packet<*>, var ticks : Int) } \ No newline at end of file From 253b28ff293e426286da2e77ba1a8c2ff90ede69 Mon Sep 17 00:00:00 2001 From: Roman Danilov Date: Sat, 25 Apr 2026 03:36:17 +0500 Subject: [PATCH 06/27] Fixes #4 --- .../java/com/nekiplay/neoscripts/mixins/TailRenderMixin.java | 2 ++ src/main/java/com/nekiplay/neoscripts/mixins/WindowMixin.java | 1 + .../neoscripts/mixins/firmament/ModAnnouncerMixin.java | 1 + .../java/com/nekiplay/neoscripts/utils/NEURepoManager.java | 1 + src/main/java/com/nekiplay/neoscripts/utils/Utils.java | 3 +-- src/main/java/com/nekiplay/neoscripts/utils/data/JsonData.java | 1 + .../java/com/nekiplay/neoscripts/utils/trackers/PetCache.java | 1 + src/main/kotlin/com/nekiplay/neoscripts/Main.kt | 3 +++ 8 files changed, 11 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/nekiplay/neoscripts/mixins/TailRenderMixin.java b/src/main/java/com/nekiplay/neoscripts/mixins/TailRenderMixin.java index 26a6f565..895015c4 100644 --- a/src/main/java/com/nekiplay/neoscripts/mixins/TailRenderMixin.java +++ b/src/main/java/com/nekiplay/neoscripts/mixins/TailRenderMixin.java @@ -1,6 +1,7 @@ package com.nekiplay.neoscripts.mixins; import com.mojang.blaze3d.systems.RenderSystem; +import com.nekiplay.neoscripts.Main; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; @@ -10,6 +11,7 @@ public class TailRenderMixin { @Inject(at = @At(value = "INVOKE", target = "Lorg/lwjgl/glfw/GLFW;glfwSwapBuffers(J)V"), method="flipFrame") private static void runTickTail(CallbackInfo ci) { + assert Main.LUA_MANAGER != null; Main.LUA_MANAGER.getScripts().forEach((name, script) -> { if (script.getImguiLib() != null) { script.getImguiLib().onFrameRender(); diff --git a/src/main/java/com/nekiplay/neoscripts/mixins/WindowMixin.java b/src/main/java/com/nekiplay/neoscripts/mixins/WindowMixin.java index 0034d15f..935d1ddb 100644 --- a/src/main/java/com/nekiplay/neoscripts/mixins/WindowMixin.java +++ b/src/main/java/com/nekiplay/neoscripts/mixins/WindowMixin.java @@ -1,6 +1,7 @@ package com.nekiplay.neoscripts.mixins; import com.mojang.blaze3d.platform.Window; +import com.nekiplay.neoscripts.Main; import net.minecraft.client.Minecraft; import net.minecraft.client.main.GameConfig; import org.spongepowered.asm.mixin.Final; diff --git a/src/main/java/com/nekiplay/neoscripts/mixins/firmament/ModAnnouncerMixin.java b/src/main/java/com/nekiplay/neoscripts/mixins/firmament/ModAnnouncerMixin.java index eaec6921..f18d96eb 100644 --- a/src/main/java/com/nekiplay/neoscripts/mixins/firmament/ModAnnouncerMixin.java +++ b/src/main/java/com/nekiplay/neoscripts/mixins/firmament/ModAnnouncerMixin.java @@ -2,6 +2,7 @@ import com.llamalad7.mixinextras.injector.wrapmethod.WrapMethod; import com.llamalad7.mixinextras.injector.wrapoperation.Operation; +import com.nekiplay.neoscripts.Main; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Pseudo; import org.spongepowered.asm.mixin.injection.Coerce; diff --git a/src/main/java/com/nekiplay/neoscripts/utils/NEURepoManager.java b/src/main/java/com/nekiplay/neoscripts/utils/NEURepoManager.java index 276ab1e7..5f40887b 100644 --- a/src/main/java/com/nekiplay/neoscripts/utils/NEURepoManager.java +++ b/src/main/java/com/nekiplay/neoscripts/utils/NEURepoManager.java @@ -3,6 +3,7 @@ import com.google.common.collect.HashMultimap; import com.google.common.collect.Multimap; import com.google.common.collect.Multimaps; +import com.nekiplay.neoscripts.Main; import com.nekiplay.neoscripts.annotations.Init; import com.nekiplay.neoscripts.utils.scheduler.Scheduler; import io.github.moulberry.repo.NEUConstants; diff --git a/src/main/java/com/nekiplay/neoscripts/utils/Utils.java b/src/main/java/com/nekiplay/neoscripts/utils/Utils.java index d4bde817..5f4841e9 100644 --- a/src/main/java/com/nekiplay/neoscripts/utils/Utils.java +++ b/src/main/java/com/nekiplay/neoscripts/utils/Utils.java @@ -42,12 +42,11 @@ import java.io.IOException; import java.net.URI; import java.net.URISyntaxException; -import java.util.Collections; import java.util.UUID; import java.util.regex.Matcher; import java.util.regex.Pattern; -import static com.nekiplay.neoscripts.Main.LOGGER; +import static com.nekiplay.neoscripts.utils.itemlist.recipes.SkyblockRecipe.LOGGER; public class Utils { public static final ObjectArrayList STRING_SCOREBOARD = new ObjectArrayList<>(); diff --git a/src/main/java/com/nekiplay/neoscripts/utils/data/JsonData.java b/src/main/java/com/nekiplay/neoscripts/utils/data/JsonData.java index 7fa7cabe..83379d3f 100644 --- a/src/main/java/com/nekiplay/neoscripts/utils/data/JsonData.java +++ b/src/main/java/com/nekiplay/neoscripts/utils/data/JsonData.java @@ -4,6 +4,7 @@ import com.mojang.serialization.Codec; import com.mojang.serialization.JsonOps; import com.mojang.serialization.codecs.RecordCodecBuilder; +import com.nekiplay.neoscripts.Main; import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientLifecycleEvents; import net.minecraft.util.StringRepresentable; import org.jetbrains.annotations.Nullable; diff --git a/src/main/java/com/nekiplay/neoscripts/utils/trackers/PetCache.java b/src/main/java/com/nekiplay/neoscripts/utils/trackers/PetCache.java index 8569150e..c2a02711 100644 --- a/src/main/java/com/nekiplay/neoscripts/utils/trackers/PetCache.java +++ b/src/main/java/com/nekiplay/neoscripts/utils/trackers/PetCache.java @@ -1,5 +1,6 @@ package com.nekiplay.neoscripts.utils.trackers; +import com.nekiplay.neoscripts.Main; import com.nekiplay.neoscripts.annotations.Init; import com.nekiplay.neoscripts.utils.ItemUtils; import com.nekiplay.neoscripts.utils.RegexUtils; diff --git a/src/main/kotlin/com/nekiplay/neoscripts/Main.kt b/src/main/kotlin/com/nekiplay/neoscripts/Main.kt index e2c1a8cc..ef99e055 100644 --- a/src/main/kotlin/com/nekiplay/neoscripts/Main.kt +++ b/src/main/kotlin/com/nekiplay/neoscripts/Main.kt @@ -23,7 +23,9 @@ import java.nio.file.Path object Main : ModInitializer { const val MOD_ID: String = "neoscripts" val LOGGER: Logger? = LoggerFactory.getLogger(MOD_ID) + @JvmField var LUA_MANAGER: LuaManager? = null + @JvmField val CONFIG_DIR: Path = FabricLoader.getInstance().getConfigDir().resolve(MOD_ID) val PREFIX: String = @@ -33,6 +35,7 @@ object Main : ModInitializer { @JvmField var mc: Minecraft = Minecraft.getInstance() var INSTANCE: Main? = null + @JvmField val GSON: Gson = GsonBuilder().setPrettyPrinting().create() val GSON_COMPACT: Gson = GsonBuilder().create() From 5e4ab97d118c62bf3dae834b2a5a0a61ada3a56d Mon Sep 17 00:00:00 2001 From: Roman Danilov Date: Sat, 25 Apr 2026 03:38:08 +0500 Subject: [PATCH 07/27] Update Main.kt --- src/main/kotlin/com/nekiplay/neoscripts/Main.kt | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/kotlin/com/nekiplay/neoscripts/Main.kt b/src/main/kotlin/com/nekiplay/neoscripts/Main.kt index ef99e055..716e0b2d 100644 --- a/src/main/kotlin/com/nekiplay/neoscripts/Main.kt +++ b/src/main/kotlin/com/nekiplay/neoscripts/Main.kt @@ -31,6 +31,7 @@ object Main : ModInitializer { val PREFIX: String = ChatFormatting.GRAY.toString() + "[" + ChatFormatting.GOLD + "Neo Scripts" + ChatFormatting.GRAY + "] " + ChatFormatting.RESET const val LOG_PREFIX: String = "[Neo Scripts] " + @JvmField var neuDir: File? = null @JvmField var mc: Minecraft = Minecraft.getInstance() From 1ecb30d1b1f8a7ba897d88f3554f3a2a6194c51e Mon Sep 17 00:00:00 2001 From: Roman Danilov Date: Sat, 25 Apr 2026 03:38:23 +0500 Subject: [PATCH 08/27] Update WindowMixin.java --- src/main/java/com/nekiplay/neoscripts/mixins/WindowMixin.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/main/java/com/nekiplay/neoscripts/mixins/WindowMixin.java b/src/main/java/com/nekiplay/neoscripts/mixins/WindowMixin.java index 935d1ddb..ec3323cb 100644 --- a/src/main/java/com/nekiplay/neoscripts/mixins/WindowMixin.java +++ b/src/main/java/com/nekiplay/neoscripts/mixins/WindowMixin.java @@ -7,6 +7,7 @@ import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.Unique; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; @@ -22,12 +23,14 @@ public class WindowMixin { @Final private Window window; + @Unique private final ArrayList startUpScriptNames = new ArrayList() {{ add("autoload.lua"); add("startup.lua"); add("init.lua"); }}; + @Unique private void loadStartupScripts(File dir) { // Автозагрузка скриптов при старте for (String name : startUpScriptNames) { From d5162d766ed793b92c55a44499294200a0ade7cd Mon Sep 17 00:00:00 2001 From: Roman Danilov Date: Sat, 25 Apr 2026 03:41:33 +0500 Subject: [PATCH 09/27] Modify --- .../mixins/minecraft/MouseHandlerMixin.java | 30 +++++++++++++++++++ src/main/resources/mixins.neoscripts.json | 1 + 2 files changed, 31 insertions(+) create mode 100644 src/main/java/com/nekiplay/neoscripts/mixins/minecraft/MouseHandlerMixin.java diff --git a/src/main/java/com/nekiplay/neoscripts/mixins/minecraft/MouseHandlerMixin.java b/src/main/java/com/nekiplay/neoscripts/mixins/minecraft/MouseHandlerMixin.java new file mode 100644 index 00000000..296f7ad2 --- /dev/null +++ b/src/main/java/com/nekiplay/neoscripts/mixins/minecraft/MouseHandlerMixin.java @@ -0,0 +1,30 @@ +package com.nekiplay.neoscripts.mixins.minecraft; + +import com.nekiplay.neoscripts.utils.aiming.RotationManager; +import com.nekiplay.neoscripts.utils.aiming.Rotations; +import net.minecraft.client.MouseHandler; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +@Mixin(MouseHandler.class) +public class MouseHandlerMixin { + + @Shadow + public double xpos; + + @Shadow + public double ypos; + + + @Inject(method = "turnPlayer", at = @At("HEAD"), cancellable = true) + private void turnPlayerHook(double d, CallbackInfo ci) { + if (Rotations.INSTANCE.getClientLook()) { + if (!Float.isNaN(RotationManager.INSTANCE.getYaw()) && !Float.isNaN(RotationManager.INSTANCE.getPitch())) { + ci.cancel(); + } + } + } +} \ No newline at end of file diff --git a/src/main/resources/mixins.neoscripts.json b/src/main/resources/mixins.neoscripts.json index e2924075..68e0f3a8 100644 --- a/src/main/resources/mixins.neoscripts.json +++ b/src/main/resources/mixins.neoscripts.json @@ -22,6 +22,7 @@ "minecraft.GamemodeAccessor", "minecraft.MixinKeyboardInput", "minecraft.MixinServerboundUseItemPacket", + "minecraft.MouseHandlerMixin", "minecraft.item.MixinItem", "packets.ServerboundMovePlayerPacketAccessor", "renderer.GameRendererAccessor" From dc44fbde5f8f806e1a07cfda4cfa99d6c6aa3bd0 Mon Sep 17 00:00:00 2001 From: Roman Danilov Date: Sat, 25 Apr 2026 03:41:56 +0500 Subject: [PATCH 10/27] Fix --- src/main/kotlin/com/nekiplay/neoscripts/Main.kt | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/kotlin/com/nekiplay/neoscripts/Main.kt b/src/main/kotlin/com/nekiplay/neoscripts/Main.kt index 716e0b2d..f58dbcfb 100644 --- a/src/main/kotlin/com/nekiplay/neoscripts/Main.kt +++ b/src/main/kotlin/com/nekiplay/neoscripts/Main.kt @@ -22,6 +22,7 @@ import java.nio.file.Path object Main : ModInitializer { const val MOD_ID: String = "neoscripts" + @JvmField val LOGGER: Logger? = LoggerFactory.getLogger(MOD_ID) @JvmField var LUA_MANAGER: LuaManager? = null From b2082c0b4b7ae16e4b8b7ee4c31da58a14f27fc3 Mon Sep 17 00:00:00 2001 From: Roman Danilov Date: Sat, 25 Apr 2026 03:48:46 +0500 Subject: [PATCH 11/27] Fix --- .../kotlin/com/nekiplay/neoscripts/Main.kt | 45 +++++++++---------- 1 file changed, 22 insertions(+), 23 deletions(-) diff --git a/src/main/kotlin/com/nekiplay/neoscripts/Main.kt b/src/main/kotlin/com/nekiplay/neoscripts/Main.kt index f58dbcfb..78d00626 100644 --- a/src/main/kotlin/com/nekiplay/neoscripts/Main.kt +++ b/src/main/kotlin/com/nekiplay/neoscripts/Main.kt @@ -9,7 +9,7 @@ import com.nekiplay.neoscripts.features.modules.ModuleManager.registerInbuilt import com.nekiplay.neoscripts.utils.Utils import com.nekiplay.neoscripts.utils.scheduler.Scheduler import io.github.classgraph.ClassGraph -import net.fabricmc.api.ModInitializer +import net.fabricmc.api.ClientModInitializer import net.fabricmc.fabric.api.client.command.v2.ClientCommandRegistrationCallback import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents import net.fabricmc.loader.api.FabricLoader @@ -20,7 +20,7 @@ import org.slf4j.LoggerFactory import java.io.File import java.nio.file.Path -object Main : ModInitializer { +object Main : ClientModInitializer { const val MOD_ID: String = "neoscripts" @JvmField val LOGGER: Logger? = LoggerFactory.getLogger(MOD_ID) @@ -58,8 +58,27 @@ object Main : ModInitializer { LUA_MANAGER!!.unloadScript(script.scriptName) } } + /** + * Ticks the scheduler. Called once at the end of every client tick through + * [ClientTickEvents.END_CLIENT_TICK]. + * + * @param client the Minecraft client. + */ + fun tick(client: Minecraft?) { + Scheduler.INSTANCE.tick() + } + + /** + * This method is responsible for initializing all classes. + * To have your class initialized you must annotate its initializer method with the `@Init` annotation. + * At compile time, ASM completely overwrites the content of this method, so adding a call here will do nothing. + * + * @see Init + */ + private fun init() { + } - override fun onInitialize() { + override fun onInitializeClient() { neuDir = FabricLoader.getInstance().getConfigDir().resolve("neoscripts").toFile() neuDir!!.mkdirs() LUA_MANAGER = LuaManager() @@ -108,24 +127,4 @@ object Main : ModInitializer { EventBus.init(classes) } - - /** - * Ticks the scheduler. Called once at the end of every client tick through - * [ClientTickEvents.END_CLIENT_TICK]. - * - * @param client the Minecraft client. - */ - fun tick(client: Minecraft?) { - Scheduler.INSTANCE.tick() - } - - /** - * This method is responsible for initializing all classes. - * To have your class initialized you must annotate its initializer method with the `@Init` annotation. - * At compile time, ASM completely overwrites the content of this method, so adding a call here will do nothing. - * - * @see Init - */ - private fun init() { - } } \ No newline at end of file From d57c9f97b1439a87d7307d8ecf8f9430400658f8 Mon Sep 17 00:00:00 2001 From: Roman Danilov Date: Sat, 25 Apr 2026 04:00:48 +0500 Subject: [PATCH 12/27] Fixes --- build.gradle.kts | 3 +-- .../kotlin/com/nekiplay/neoscripts/Main.kt | 23 +------------------ 2 files changed, 2 insertions(+), 24 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index 3f06f7e6..9cbec883 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -3,10 +3,9 @@ val lwjgl_version: String by project plugins { java `maven-publish` - id("fabric-loom") version "1.15-SNAPSHOT" + id("fabric-loom-remap") version "1.15-SNAPSHOT" id("org.jetbrains.kotlin.jvm") version "2.2.21" id("org.jetbrains.kotlin.plugin.serialization") version "2.2.21" - id("com.nekiplay.neoscripts.annotation-processor") id("com.gradleup.shadow") version "9.3.0" } diff --git a/src/main/kotlin/com/nekiplay/neoscripts/Main.kt b/src/main/kotlin/com/nekiplay/neoscripts/Main.kt index 78d00626..0200f4b6 100644 --- a/src/main/kotlin/com/nekiplay/neoscripts/Main.kt +++ b/src/main/kotlin/com/nekiplay/neoscripts/Main.kt @@ -27,7 +27,7 @@ object Main : ClientModInitializer { @JvmField var LUA_MANAGER: LuaManager? = null @JvmField - val CONFIG_DIR: Path = FabricLoader.getInstance().getConfigDir().resolve(MOD_ID) + val CONFIG_DIR: Path = FabricLoader.getInstance().configDir.resolve(MOD_ID) val PREFIX: String = ChatFormatting.GRAY.toString() + "[" + ChatFormatting.GOLD + "Neo Scripts" + ChatFormatting.GRAY + "] " + ChatFormatting.RESET @@ -58,25 +58,6 @@ object Main : ClientModInitializer { LUA_MANAGER!!.unloadScript(script.scriptName) } } - /** - * Ticks the scheduler. Called once at the end of every client tick through - * [ClientTickEvents.END_CLIENT_TICK]. - * - * @param client the Minecraft client. - */ - fun tick(client: Minecraft?) { - Scheduler.INSTANCE.tick() - } - - /** - * This method is responsible for initializing all classes. - * To have your class initialized you must annotate its initializer method with the `@Init` annotation. - * At compile time, ASM completely overwrites the content of this method, so adding a call here will do nothing. - * - * @see Init - */ - private fun init() { - } override fun onInitializeClient() { neuDir = FabricLoader.getInstance().getConfigDir().resolve("neoscripts").toFile() @@ -98,8 +79,6 @@ object Main : ClientModInitializer { LuaCommand.register(dispatcher, registryAccess) } - init() - registerInbuilt() Scheduler.INSTANCE.scheduleCyclic(Runnable { Utils.update() }, 20) From dcf63af6d4e9e15280143ec29d269949b5b13bb7 Mon Sep 17 00:00:00 2001 From: Roman Danilov Date: Sat, 25 Apr 2026 04:01:05 +0500 Subject: [PATCH 13/27] Fixes --- buildSrc/build.gradle.kts | 37 ------ .../com/nekiplay/neoscripts/Processor.java | 111 ------------------ .../init/InitInjectingClassVisitor.java | 41 ------- .../neoscripts/init/InitProcessor.java | 72 ------------ .../init/InitReadingClassVisitor.java | 71 ----------- 5 files changed, 332 deletions(-) delete mode 100644 buildSrc/build.gradle.kts delete mode 100644 buildSrc/src/main/java/com/nekiplay/neoscripts/Processor.java delete mode 100644 buildSrc/src/main/java/com/nekiplay/neoscripts/init/InitInjectingClassVisitor.java delete mode 100644 buildSrc/src/main/java/com/nekiplay/neoscripts/init/InitProcessor.java delete mode 100644 buildSrc/src/main/java/com/nekiplay/neoscripts/init/InitReadingClassVisitor.java diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts deleted file mode 100644 index 1e8ffed5..00000000 --- a/buildSrc/build.gradle.kts +++ /dev/null @@ -1,37 +0,0 @@ -plugins { - `java-gradle-plugin` - `java-library` - `kotlin-dsl` -} - -repositories { - mavenCentral() - gradlePluginPortal() -} - -val asmVersion = "9.7" - -dependencies { - implementation("org.ow2.asm:asm:$asmVersion") - implementation("org.ow2.asm:asm-tree:$asmVersion") - implementation(gradleApi()) - implementation(gradleKotlinDsl()) - implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.9.22") - implementation("org.jetbrains:annotations:24.0.1") -} - -gradlePlugin { - plugins { - create("annotationProcessor") { - id = "com.nekiplay.neoscripts.annotation-processor" - implementationClass = "com.nekiplay.neoscripts.Processor" - } - } -} - -java { - toolchain { - languageVersion.set(JavaLanguageVersion.of(21)) - } - withSourcesJar() -} \ No newline at end of file diff --git a/buildSrc/src/main/java/com/nekiplay/neoscripts/Processor.java b/buildSrc/src/main/java/com/nekiplay/neoscripts/Processor.java deleted file mode 100644 index 51778846..00000000 --- a/buildSrc/src/main/java/com/nekiplay/neoscripts/Processor.java +++ /dev/null @@ -1,111 +0,0 @@ -package com.nekiplay.neoscripts; - -import com.nekiplay.neoscripts.init.InitProcessor; -import org.gradle.api.Plugin; -import org.gradle.api.Project; -import org.gradle.api.logging.Logger; -import org.gradle.api.logging.Logging; -import org.gradle.api.tasks.compile.JavaCompile; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; -import org.objectweb.asm.ClassReader; - -import java.io.File; -import java.io.IOException; -import java.io.InputStream; -import java.nio.file.FileVisitResult; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.SimpleFileVisitor; -import java.nio.file.attribute.BasicFileAttributes; -import java.util.Objects; -import java.util.function.Consumer; - -public class Processor implements Plugin { - - public static final Logger logger = Logging.getLogger(Processor.class); - public static File classesDir; - - @Override - public void apply(@NotNull Project project) { - // https://docs.gradle.org/current/userguide/task_configuration_avoidance.html - // This only configures the `compileJava` task and not other `JavaCompile` tasks such as `compileTestJava`. https://stackoverflow.com/a/77047012 - project.getTasks().withType(JavaCompile.class).named("compileJava").get().doLast(task -> { - JavaCompile javaCompile = (JavaCompile) task; - classesDir = javaCompile.getDestinationDirectory().get().getAsFile(); - - new InitProcessor().apply(javaCompile); - }); - } - - public static void forEachClass(@NotNull File directory, final Consumer consumer) { - try { - Files.walkFileTree(directory.toPath(), new SimpleFileVisitor<>() { - @Override - public FileVisitResult visitFile(Path path, BasicFileAttributes attrs) { - if (!path.toString().endsWith(".class")) return FileVisitResult.CONTINUE; - try (InputStream inputStream = Files.newInputStream(path)) { - consumer.accept(inputStream); - } catch (IOException e) { - logger.error("Failed to run consumer on class {}", path, e); - - } - - return FileVisitResult.CONTINUE; - } - }); - } catch (IOException e) { - logger.error("Failed to walk classes", e); - } - } - - public static void forEachClass(final Consumer consumer) { - forEachClass(classesDir, consumer); - } - - public static @Nullable File findClass(File directory, String className) { - if (!className.endsWith(".class")) className += ".class"; - - if (!directory.isDirectory()) throw new IllegalArgumentException("Not a directory"); - - for (File file : Objects.requireNonNull(directory.listFiles())) { - if (file.isDirectory()) { - File foundFile = findClass(file, className); - - if (foundFile != null) return foundFile; - } else if (file.getName().equals(className)) { - return file; - } - } - return null; - } - - public static @Nullable File findClass(String className) { - return findClass(classesDir, className); - } - - /** - * Pretty much [child instanceof superClass] - *

- * Classes are full name. Example: de/hysky/skyblocker/SkyblockerMod - * @param child the class to test - * @param superClass super - * @return if child is an instance of superclass - */ - public static boolean instanceOf(String child, String superClass) { - Path start = classesDir.toPath(); - String sup = child; - while (sup != null) { - if (sup.equals(superClass)) return true; - Path resolve = start.resolve(sup + ".class"); - try (InputStream stream = Files.newInputStream(resolve)) { - ClassReader classReader = new ClassReader(stream); - sup = classReader.getSuperName(); - } catch (IOException e) { - logger.error("Failed to read class {}", resolve, e); - return false; - } - } - return false; - } -} \ No newline at end of file diff --git a/buildSrc/src/main/java/com/nekiplay/neoscripts/init/InitInjectingClassVisitor.java b/buildSrc/src/main/java/com/nekiplay/neoscripts/init/InitInjectingClassVisitor.java deleted file mode 100644 index 509d8b11..00000000 --- a/buildSrc/src/main/java/com/nekiplay/neoscripts/init/InitInjectingClassVisitor.java +++ /dev/null @@ -1,41 +0,0 @@ -package com.nekiplay.neoscripts.init; - -import org.objectweb.asm.ClassVisitor; -import org.objectweb.asm.MethodVisitor; -import org.objectweb.asm.Opcodes; -import org.objectweb.asm.tree.MethodNode; - -import java.util.List; - -public class InitInjectingClassVisitor extends ClassVisitor { - private final List methodSignatures; - - public InitInjectingClassVisitor(ClassVisitor classVisitor, List methodSignatures) { - super(Opcodes.ASM9, classVisitor); - this.methodSignatures = methodSignatures; - } - - @Override - public MethodVisitor visitMethod(int access, String name, String descriptor, String signature, String[] exceptions) { - MethodVisitor methodVisitor = super.visitMethod(access, name, descriptor, signature, exceptions); - - // Limit replacing to the init method which is private, static, named init, has no args, and has a void return type - if ((access & Opcodes.ACC_PRIVATE) != 0 && (access & Opcodes.ACC_STATIC) != 0 && name.equals("init") && descriptor.equals("()V")) { - // Method node that we will overwrite the init method with - MethodNode methodNode = new MethodNode(Opcodes.ASM9, access, name, descriptor, signature, exceptions); - - // Inject calls to each found @Init annotated method - for (InitProcessor.MethodReference methodCall : methodSignatures) { - methodNode.visitMethodInsn(Opcodes.INVOKESTATIC, methodCall.className(), methodCall.methodName(), methodCall.descriptor(), methodCall.itf()); - } - - // Return from the method - methodNode.visitInsn(Opcodes.RETURN); - - // Apply our new method node to the visitor to replace the original one - methodNode.accept(methodVisitor); - } - - return methodVisitor; - } -} \ No newline at end of file diff --git a/buildSrc/src/main/java/com/nekiplay/neoscripts/init/InitProcessor.java b/buildSrc/src/main/java/com/nekiplay/neoscripts/init/InitProcessor.java deleted file mode 100644 index ad73ef63..00000000 --- a/buildSrc/src/main/java/com/nekiplay/neoscripts/init/InitProcessor.java +++ /dev/null @@ -1,72 +0,0 @@ -package com.nekiplay.neoscripts.init; - -import com.nekiplay.neoscripts.Processor; -import org.gradle.api.tasks.compile.JavaCompile; -import org.objectweb.asm.*; - -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.nio.file.Files; -import java.nio.file.Path; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Objects; - -@SuppressWarnings("unused") -public class InitProcessor { - public void apply(JavaCompile task) { - long start = System.currentTimeMillis(); - Map methodSignatures = new HashMap<>(); - - //Find all methods with the @Init annotation - findInitMethods(methodSignatures); - - //Sort the methods by their priority. It's also converted to a list because the priority values are useless from here on - List sortedMethodSignatures = methodSignatures.entrySet() - .stream() - .sorted(Map.Entry.comparingByValue().thenComparing(entry -> entry.getKey().className())) - .map(Map.Entry::getKey) - .toList(); - - //Inject calls to the @Init annotated methods in the SkyblockerMod class - injectInitCalls(sortedMethodSignatures); - - System.out.println("Injecting init methods took: " + (System.currentTimeMillis() - start) + "ms"); - } - - public void findInitMethods(Map methodSignatures) { - Processor.forEachClass(inputStream -> { - try { - ClassReader classReader = new ClassReader(inputStream); - classReader.accept(new InitReadingClassVisitor(classReader, methodSignatures), ClassReader.SKIP_CODE | ClassReader.SKIP_DEBUG | ClassReader.SKIP_FRAMES); - } catch (IOException e) { - throw new RuntimeException(e); - } - }); - } - - public void injectInitCalls(List methodSignatures) { - Path mainClassFile = Objects.requireNonNull(Processor.findClass("Main.class"), "Main class wasn't found :(").toPath(); - - try (InputStream inputStream = Files.newInputStream(mainClassFile)) { - ClassReader classReader = new ClassReader(inputStream); - ClassWriter classWriter = new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS); - classReader.accept(new InitInjectingClassVisitor(classWriter, methodSignatures), 0); - try (OutputStream outputStream = Files.newOutputStream(mainClassFile)) { - outputStream.write(classWriter.toByteArray()); - } - } catch (Exception e) { - e.printStackTrace(); - } - } - - /** - * @param className the class name (e.g. de/hysky/skyblocker/skyblock/ChestValue) - * @param methodName the method's name (e.g. init) - * @param descriptor the method's descriptor (only ()V for now) - * @param itf whether the target class is an {@code interface} or not - */ - public record MethodReference(String className, String methodName, String descriptor, boolean itf) {} -} \ No newline at end of file diff --git a/buildSrc/src/main/java/com/nekiplay/neoscripts/init/InitReadingClassVisitor.java b/buildSrc/src/main/java/com/nekiplay/neoscripts/init/InitReadingClassVisitor.java deleted file mode 100644 index a2db5511..00000000 --- a/buildSrc/src/main/java/com/nekiplay/neoscripts/init/InitReadingClassVisitor.java +++ /dev/null @@ -1,71 +0,0 @@ -package com.nekiplay.neoscripts.init; - -import org.jetbrains.annotations.NotNull; -import org.objectweb.asm.*; - -import java.util.Map; - -public class InitReadingClassVisitor extends ClassVisitor { - private final Map methodSignatures; - private final ClassReader classReader; - - public InitReadingClassVisitor(ClassReader classReader, Map methodSignatures) { - super(Opcodes.ASM9); - this.classReader = classReader; - this.methodSignatures = methodSignatures; - } - - @Override - public MethodVisitor visitMethod(int access, String methodName, String descriptor, String signature, String[] exceptions) { - return new MethodVisitor(Opcodes.ASM9) { - @Override - public AnnotationVisitor visitAnnotation(String desc, boolean visible) { - //This method visitor checks all methods and only acts upon those with the Init annotation. - //This lets us warn the user about invalid init methods and misuse of the annotation - if (!desc.equals("Lcom/nekiplay/neoscripts/annotations/Init;")) return super.visitAnnotation(desc, visible); - - //Delegates adding the method call to the map to the InitAnnotationVisitor since we don't have a value to put in the map here - return new InitAnnotationVisitor(methodSignatures, getMethodCall()); - } - - private @NotNull InitProcessor.MethodReference getMethodCall() { - String className = classReader.getClassName(); - String methodCallString = className + "." + methodName; - if ((access & Opcodes.ACC_PUBLIC) == 0) throw new IllegalStateException(methodCallString + ": Initializer methods must be public"); - if ((access & Opcodes.ACC_STATIC) == 0) throw new IllegalStateException(methodCallString + ": Initializer methods must be static"); - if (!descriptor.equals("()V")) throw new IllegalStateException(methodCallString + ": Initializer methods must have no args and a void return type"); - - //Interface static methods need special handling, so we add a special marker for that - boolean itf = (classReader.getAccess() & Opcodes.ACC_INTERFACE) != 0; - - return new InitProcessor.MethodReference(className, methodName, descriptor, itf); - } - }; - } - - static class InitAnnotationVisitor extends AnnotationVisitor { - private final Map methodSignatures; - private final InitProcessor.MethodReference methodCall; - - protected InitAnnotationVisitor(Map methodSignatures, InitProcessor.MethodReference methodCall) { - super(Opcodes.ASM9); - this.methodSignatures = methodSignatures; - this.methodCall = methodCall; - } - - @Override - public void visitEnd() { - //Annotations that use the default value for the priority field will not be called by the visit method, so we have to handle them here. - methodSignatures.putIfAbsent(methodCall, 0); - super.visitEnd(); - } - - @Override - public void visit(String name, Object value) { - if (name.equals("priority")) { - methodSignatures.put(methodCall, (int) value); - } - super.visit(name, value); - } - } -} \ No newline at end of file From 85ec5cdffdd5bd4c28d6c50585d3c788e48cdcde Mon Sep 17 00:00:00 2001 From: Roman Danilov Date: Sat, 25 Apr 2026 04:03:58 +0500 Subject: [PATCH 14/27] Update build.gradle.kts --- build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle.kts b/build.gradle.kts index 9cbec883..7f643ad5 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -3,7 +3,7 @@ val lwjgl_version: String by project plugins { java `maven-publish` - id("fabric-loom-remap") version "1.15-SNAPSHOT" + id("fabric-loom") version "1.15-SNAPSHOT" id("org.jetbrains.kotlin.jvm") version "2.2.21" id("org.jetbrains.kotlin.plugin.serialization") version "2.2.21" id("com.gradleup.shadow") version "9.3.0" From 8426e7686f12cc9d6cc45ff512f1a3056844cdbd Mon Sep 17 00:00:00 2001 From: Roman Danilov Date: Sat, 25 Apr 2026 04:09:07 +0500 Subject: [PATCH 15/27] Fixes --- src/main/java/com/nekiplay/neoscripts/utils/Utils.java | 1 + src/main/kotlin/com/nekiplay/neoscripts/Main.kt | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/nekiplay/neoscripts/utils/Utils.java b/src/main/java/com/nekiplay/neoscripts/utils/Utils.java index 5f4841e9..23d23658 100644 --- a/src/main/java/com/nekiplay/neoscripts/utils/Utils.java +++ b/src/main/java/com/nekiplay/neoscripts/utils/Utils.java @@ -19,6 +19,7 @@ import net.azureaaron.hmapi.network.packet.s2c.HypixelS2CPacket; import net.azureaaron.hmapi.network.packet.v1.s2c.LocationUpdateS2CPacket; import net.azureaaron.hmapi.network.packet.v1.s2c.PlayerInfoS2CPacket; +import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents; import net.fabricmc.fabric.api.client.message.v1.ClientReceiveMessageEvents; import net.fabricmc.loader.api.FabricLoader; import net.minecraft.ChatFormatting; diff --git a/src/main/kotlin/com/nekiplay/neoscripts/Main.kt b/src/main/kotlin/com/nekiplay/neoscripts/Main.kt index 0200f4b6..abc50b1c 100644 --- a/src/main/kotlin/com/nekiplay/neoscripts/Main.kt +++ b/src/main/kotlin/com/nekiplay/neoscripts/Main.kt @@ -74,7 +74,6 @@ object Main : ClientModInitializer { Runtime.getRuntime().addShutdownHook(Thread(Runnable { saveConfig() })) - ClientTickEvents.END_CLIENT_TICK.register(ClientTickEvents.EndTick { client: Minecraft? -> this.tick(client) }) ClientCommandRegistrationCallback.EVENT.register { dispatcher, registryAccess -> LuaCommand.register(dispatcher, registryAccess) } From 1aba37a6754bdad30d79916014d2380582ab335a Mon Sep 17 00:00:00 2001 From: Roman Danilov Date: Sat, 25 Apr 2026 05:11:33 +0500 Subject: [PATCH 16/27] Test --- .../events/player/MovementInputEvent.java | 37 --- .../entity/MixinFireworkRocketEntity.java | 7 +- .../mixins/entity/MixinLivingEntity.java | 4 - .../entity/MixinLivingEntityRenderer.java | 7 - .../mixins/entity/MixinLocalPlayer.java | 7 - .../minecraft/ClientConnectionMixin.java | 1 - .../mixins/minecraft/MixinKeyboardInput.java | 38 +-- .../MixinServerboundUseItemPacket.java | 10 +- .../mixins/minecraft/item/MixinItem.java | 1 - .../nekiplay/neoscripts/utils/Rotations.java | 239 ------------------ .../neoscripts/events/MovementInputEvent.kt | 10 + .../nekiplay/neoscripts/events/main/Event.kt | 7 +- .../lua/objects/player/PlayerObject.kt | 3 - .../features/lua/objects/world/WorldObject.kt | 2 - .../com/nekiplay/neoscripts/sugar/Entity.kt | 1 - .../neoscripts/sugar/MultiPlayerGameMode.kt | 1 - .../neoscripts/utils/DirectionalInput.kt | 25 +- 17 files changed, 59 insertions(+), 341 deletions(-) delete mode 100644 src/main/java/com/nekiplay/neoscripts/events/player/MovementInputEvent.java delete mode 100644 src/main/java/com/nekiplay/neoscripts/utils/Rotations.java create mode 100644 src/main/kotlin/com/nekiplay/neoscripts/events/MovementInputEvent.kt diff --git a/src/main/java/com/nekiplay/neoscripts/events/player/MovementInputEvent.java b/src/main/java/com/nekiplay/neoscripts/events/player/MovementInputEvent.java deleted file mode 100644 index c32eb0ec..00000000 --- a/src/main/java/com/nekiplay/neoscripts/events/player/MovementInputEvent.java +++ /dev/null @@ -1,37 +0,0 @@ -package com.nekiplay.neoscripts.events.player; - -import com.nekiplay.neoscripts.utils.DirectionalInput; -import net.fabricmc.fabric.api.event.Event; -import net.fabricmc.fabric.api.event.EventFactory; -import net.minecraft.world.InteractionResult; - -public class MovementInputEvent { - public static final Event EVENT = EventFactory.createArrayBacked( - MovementInput.class, - (listeners) -> (event) -> { - for (MovementInput listener : listeners) { - InteractionResult result = listener.update(event); - - if(result != InteractionResult.PASS) { - return result; - } - } - - return InteractionResult.PASS; - } - ); - - public DirectionalInput directionalInput; - public boolean jump; - public boolean shift; - - public MovementInputEvent(DirectionalInput directionalInput, boolean jump, boolean shift) { - this.directionalInput = directionalInput; - this.jump = jump; - this.shift = shift; - } - - public interface MovementInput { - InteractionResult update(MovementInputEvent event); - } -} \ No newline at end of file diff --git a/src/main/java/com/nekiplay/neoscripts/mixins/entity/MixinFireworkRocketEntity.java b/src/main/java/com/nekiplay/neoscripts/mixins/entity/MixinFireworkRocketEntity.java index bcea2f11..dba183c9 100644 --- a/src/main/java/com/nekiplay/neoscripts/mixins/entity/MixinFireworkRocketEntity.java +++ b/src/main/java/com/nekiplay/neoscripts/mixins/entity/MixinFireworkRocketEntity.java @@ -1,14 +1,11 @@ package com.nekiplay.neoscripts.mixins.entity; -import com.llamalad7.mixinextras.injector.ModifyExpressionValue; -import com.nekiplay.neoscripts.utils.Rotations; import com.nekiplay.neoscripts.utils.aiming.RotationManager; -import net.minecraft.client.Minecraft; +import com.nekiplay.neoscripts.utils.aiming.Rotations; import net.minecraft.world.entity.LivingEntity; import net.minecraft.world.entity.projectile.FireworkRocketEntity; import net.minecraft.world.phys.Vec3; import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Redirect; @@ -16,7 +13,7 @@ public abstract class MixinFireworkRocketEntity { @Redirect(method = "tick", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/entity/LivingEntity;getLookAngle()Lnet/minecraft/world/phys/Vec3;")) private Vec3 getLookAngleHook(LivingEntity instance) { - if (!Rotations.movementCorrection) { + if (!Rotations.INSTANCE.getMoveFix()) { return instance.calculateViewVector( RotationManager.INSTANCE.getCurrentPitch(), diff --git a/src/main/java/com/nekiplay/neoscripts/mixins/entity/MixinLivingEntity.java b/src/main/java/com/nekiplay/neoscripts/mixins/entity/MixinLivingEntity.java index fbaa18bb..ef85c32f 100644 --- a/src/main/java/com/nekiplay/neoscripts/mixins/entity/MixinLivingEntity.java +++ b/src/main/java/com/nekiplay/neoscripts/mixins/entity/MixinLivingEntity.java @@ -1,12 +1,8 @@ package com.nekiplay.neoscripts.mixins.entity; import com.llamalad7.mixinextras.injector.ModifyExpressionValue; -import com.nekiplay.neoscripts.utils.Rotations; import com.nekiplay.neoscripts.utils.aiming.RotationManager; -import net.minecraft.client.Minecraft; -import net.minecraft.util.Mth; import net.minecraft.world.entity.LivingEntity; -import net.minecraft.world.phys.Vec3; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Unique; import org.spongepowered.asm.mixin.injection.At; diff --git a/src/main/java/com/nekiplay/neoscripts/mixins/entity/MixinLivingEntityRenderer.java b/src/main/java/com/nekiplay/neoscripts/mixins/entity/MixinLivingEntityRenderer.java index 33fe5f12..7515ccf2 100644 --- a/src/main/java/com/nekiplay/neoscripts/mixins/entity/MixinLivingEntityRenderer.java +++ b/src/main/java/com/nekiplay/neoscripts/mixins/entity/MixinLivingEntityRenderer.java @@ -1,23 +1,16 @@ package com.nekiplay.neoscripts.mixins.entity; -import com.llamalad7.mixinextras.injector.ModifyExpressionValue; import com.nekiplay.neoscripts.events.ExtractRenderStateEvent; import com.nekiplay.neoscripts.events.main.EventBus; -import com.nekiplay.neoscripts.utils.Rotations; -import net.minecraft.client.Minecraft; import net.minecraft.client.model.EntityModel; import net.minecraft.client.renderer.entity.LivingEntityRenderer; import net.minecraft.client.renderer.entity.state.LivingEntityRenderState; -import net.minecraft.util.Mth; import net.minecraft.world.entity.LivingEntity; -import org.jspecify.annotations.NullMarked; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Unique; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.ModifyArgs; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; -import org.spongepowered.asm.mixin.injection.invoke.arg.Args; @Mixin(LivingEntityRenderer.class) public class MixinLivingEntityRenderer> { diff --git a/src/main/java/com/nekiplay/neoscripts/mixins/entity/MixinLocalPlayer.java b/src/main/java/com/nekiplay/neoscripts/mixins/entity/MixinLocalPlayer.java index d241f22c..e30fdd07 100644 --- a/src/main/java/com/nekiplay/neoscripts/mixins/entity/MixinLocalPlayer.java +++ b/src/main/java/com/nekiplay/neoscripts/mixins/entity/MixinLocalPlayer.java @@ -1,25 +1,18 @@ package com.nekiplay.neoscripts.mixins.entity; -import com.llamalad7.mixinextras.injector.ModifyExpressionValue; import com.mojang.authlib.GameProfile; import com.nekiplay.neoscripts.events.*; import com.nekiplay.neoscripts.events.main.EventBus; -import com.nekiplay.neoscripts.utils.RaycastUtils; -import com.nekiplay.neoscripts.utils.Rotations; -import net.minecraft.client.Minecraft; import net.minecraft.client.multiplayer.ClientLevel; import net.minecraft.client.player.AbstractClientPlayer; import net.minecraft.client.player.ClientInput; import net.minecraft.client.player.LocalPlayer; import net.minecraft.world.entity.Entity; -import net.minecraft.world.entity.player.Player; import net.minecraft.world.phys.HitResult; -import net.minecraft.world.phys.Vec3; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.ModifyVariable; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; diff --git a/src/main/java/com/nekiplay/neoscripts/mixins/minecraft/ClientConnectionMixin.java b/src/main/java/com/nekiplay/neoscripts/mixins/minecraft/ClientConnectionMixin.java index 16b6f9ec..b152c80d 100644 --- a/src/main/java/com/nekiplay/neoscripts/mixins/minecraft/ClientConnectionMixin.java +++ b/src/main/java/com/nekiplay/neoscripts/mixins/minecraft/ClientConnectionMixin.java @@ -44,7 +44,6 @@ private void onSend(Packet packet, ChannelFutureListener listener, CallbackIn private void onChannelRead(ChannelHandlerContext channelHandlerContext, Packet packet, CallbackInfo ci) { if (packet instanceof ClientboundSetEntityDataPacket entityDataPacket) { if (mc.level == null) return; - Entity entity = mc.level.getEntity(entityDataPacket.id()); if (entity instanceof FakePlayer) { ci.cancel(); diff --git a/src/main/java/com/nekiplay/neoscripts/mixins/minecraft/MixinKeyboardInput.java b/src/main/java/com/nekiplay/neoscripts/mixins/minecraft/MixinKeyboardInput.java index acf08c7c..6b46ca67 100644 --- a/src/main/java/com/nekiplay/neoscripts/mixins/minecraft/MixinKeyboardInput.java +++ b/src/main/java/com/nekiplay/neoscripts/mixins/minecraft/MixinKeyboardInput.java @@ -1,9 +1,11 @@ package com.nekiplay.neoscripts.mixins.minecraft; import com.llamalad7.mixinextras.injector.ModifyExpressionValue; -import com.nekiplay.neoscripts.events.player.MovementInputEvent; +import com.nekiplay.neoscripts.events.MovementInputEvent; +import com.nekiplay.neoscripts.events.main.EventBus; import com.nekiplay.neoscripts.utils.DirectionalInput; -import com.nekiplay.neoscripts.utils.Rotations; +import com.nekiplay.neoscripts.utils.aiming.RotationManager; +import com.nekiplay.neoscripts.utils.aiming.Rotations; import net.minecraft.client.Minecraft; import net.minecraft.client.Options; import net.minecraft.client.player.KeyboardInput; @@ -28,19 +30,19 @@ public abstract class MixinKeyboardInput { @ModifyExpressionValue(method = "tick", at = @At(value = "NEW", target = "(ZZZZZZZ)Lnet/minecraft/world/entity/player/Input;")) private Input modifyInput(Input original) { var event = new MovementInputEvent(new DirectionalInput(original), original.jump(), original.shift()); - MovementInputEvent.EVENT.invoker().update(event); - var untransformedDirectionalInput = event.directionalInput; - var directionalInput = transformDirection(untransformedDirectionalInput); - - return new Input( - directionalInput.getForwards(), - directionalInput.getBackwards(), - directionalInput.getLeft(), - directionalInput.getRight(), - event.jump, - event.shift, - original.sprint() - ); + EventBus.INSTANCE.send(event); + + DirectionalInput directionalInput = transformDirection(event.getDirectionalInput()); + + int forward2 = directionalInput.getForwardValue(); // положительное = вперёд, отрицательное = назад + int sideways2 = directionalInput.getSidewaysValue(); // положительное = вправо, отрицательное = влево + + boolean forwards = forward2 > 0; + boolean backwards = forward2 < 0; + boolean left = sideways2 < 0; + boolean right = sideways2 > 0; + + return new Input(forwards, backwards, left, right, event.getJump(), event.getShift(), original.sprint()); } @Unique @@ -50,12 +52,12 @@ private DirectionalInput transformDirection(DirectionalInput input) { float z = KeyboardInput.calculateImpulse(input.getForwards(), input.getBackwards()); float x = KeyboardInput.calculateImpulse(input.getLeft(), input.getRight()); - if (!Rotations.rotating || !Rotations.movementCorrection - || !Rotations.silentMovementCorrection || player == null) { + if (Float.isNaN(RotationManager.INSTANCE.getCurrentYaw()) || !Rotations.INSTANCE.getMoveFix() + || !Rotations.INSTANCE.getMoveFixSilent() || player == null) { return input; } - float deltaYaw = player.getYRot() - Rotations.serverYaw; + float deltaYaw = player.getYRot() - RotationManager.INSTANCE.getCurrentYaw(); float newX = x * Mth.cos(deltaYaw * DEG_TO_RAD) - z * Mth.sin(deltaYaw * DEG_TO_RAD); diff --git a/src/main/java/com/nekiplay/neoscripts/mixins/minecraft/MixinServerboundUseItemPacket.java b/src/main/java/com/nekiplay/neoscripts/mixins/minecraft/MixinServerboundUseItemPacket.java index 191b467a..4c0ba305 100644 --- a/src/main/java/com/nekiplay/neoscripts/mixins/minecraft/MixinServerboundUseItemPacket.java +++ b/src/main/java/com/nekiplay/neoscripts/mixins/minecraft/MixinServerboundUseItemPacket.java @@ -1,9 +1,9 @@ package com.nekiplay.neoscripts.mixins.minecraft; -import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation; -import com.nekiplay.neoscripts.utils.Rotations; +import com.nekiplay.neoscripts.utils.aiming.RotationManager; import net.minecraft.network.protocol.game.ServerboundUseItemPacket; import net.minecraft.world.InteractionHand; +import net.minecraft.world.level.block.Rotation; import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Mutable; @@ -27,11 +27,11 @@ public abstract class MixinServerboundUseItemPacket { @Inject(method = "(Lnet/minecraft/world/InteractionHand;IFF)V", at = @At("RETURN")) private void modifyRotation(InteractionHand hand, int sequence, float yaw, float pitch, CallbackInfo ci) { - if (!Rotations.rotating) { + if (Float.isNaN(RotationManager.INSTANCE.getCurrentYaw())) { return; } - this.yRot = Rotations.serverYaw; - this.xRot = Rotations.serverPitch; + this.yRot = RotationManager.INSTANCE.getCurrentYaw(); + this.xRot = RotationManager.INSTANCE.getCurrentPitch(); } } \ No newline at end of file diff --git a/src/main/java/com/nekiplay/neoscripts/mixins/minecraft/item/MixinItem.java b/src/main/java/com/nekiplay/neoscripts/mixins/minecraft/item/MixinItem.java index 69125f69..fbdc3f74 100644 --- a/src/main/java/com/nekiplay/neoscripts/mixins/minecraft/item/MixinItem.java +++ b/src/main/java/com/nekiplay/neoscripts/mixins/minecraft/item/MixinItem.java @@ -1,7 +1,6 @@ package com.nekiplay.neoscripts.mixins.minecraft.item; import com.llamalad7.mixinextras.injector.ModifyExpressionValue; -import com.nekiplay.neoscripts.utils.Rotations; import net.minecraft.client.Minecraft; import net.minecraft.world.entity.player.Player; import net.minecraft.world.item.Item; diff --git a/src/main/java/com/nekiplay/neoscripts/utils/Rotations.java b/src/main/java/com/nekiplay/neoscripts/utils/Rotations.java deleted file mode 100644 index 82d6dd7e..00000000 --- a/src/main/java/com/nekiplay/neoscripts/utils/Rotations.java +++ /dev/null @@ -1,239 +0,0 @@ -package com.nekiplay.neoscripts.utils; - -import com.nekiplay.neoscripts.annotations.Init; -import com.nekiplay.neoscripts.events.SendMovementPacketsEvent; -import com.nekiplay.neoscripts.events.player.PlayerVelocityStrafeEvent; -import com.nekiplay.neoscripts.events.world.TickEvent; -import com.nekiplay.neoscripts.utils.misc.Pool; -import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents; -import net.minecraft.client.Minecraft; -import net.minecraft.core.BlockPos; -import net.minecraft.network.protocol.game.ClientboundPlayerPositionPacket; -import net.minecraft.network.protocol.game.ServerboundMovePlayerPacket; -import net.minecraft.util.Mth; -import net.minecraft.world.InteractionResult; -import net.minecraft.world.entity.Entity; -import net.minecraft.world.phys.Vec3; - -import java.util.ArrayList; -import java.util.List; - -import static com.nekiplay.neoscripts.Main.mc; - -public class Rotations { - public static double getYaw(Entity entity) { - return mc.player.getYRot() + Mth.wrapDegrees((float) Math.toDegrees(Math.atan2(entity.getZ() - mc.player.getZ(), entity.getX() - mc.player.getX())) - 90f - mc.player.getYRot()); - } - - public static double getYaw(Vec3 pos) { - return mc.player.getYRot() + Mth.wrapDegrees((float) Math.toDegrees(Math.atan2(pos.z() - mc.player.getZ(), pos.x() - mc.player.getX())) - 90f - mc.player.getYRot()); - } - - public static double getPitch(Vec3 pos) { - double diffX = pos.x() - mc.player.getX(); - double diffY = pos.y() - (mc.player.getY() + mc.player.getEyeHeight(mc.player.getPose())); - double diffZ = pos.z() - mc.player.getZ(); - - double diffXZ = Math.sqrt(diffX * diffX + diffZ * diffZ); - - return mc.player.getXRot() + Mth.wrapDegrees((float) -Math.toDegrees(Math.atan2(diffY, diffXZ)) - mc.player.getXRot()); - } - - public static Vec3 getDirectionFromYawPitch(float yaw, float pitch) { - // Конвертируем градусы в радианы - float yawRad = (float) Math.toRadians(yaw); - float pitchRad = (float) Math.toRadians(pitch); - - // Вычисляем компоненты вектора - double x = -Mth.sin(yawRad) * Mth.cos(pitchRad); - double y = -Mth.sin(pitchRad); - double z = Mth.cos(yawRad) * Mth.cos(pitchRad); - - return new Vec3(x, y, z).normalize(); - } - - public static void rotate(double yaw, double pitch, int priority, boolean clientSide, boolean movementCorrection, Runnable callback) { - Rotation rotation = rotationPool.get(); - rotation.set(yaw, pitch, priority, clientSide, callback); - Rotations.movementCorrection = movementCorrection; - int i = 0; - for (; i < rotations.size(); i++) { - if (priority > rotations.get(i).priority) break; - } - - rotations.add(i, rotation); - } - - public static void rotate(double yaw, double pitch, int priority, boolean movementCorrection, Runnable callback) { - rotate(yaw, pitch, priority, false, movementCorrection, callback); - } - - public static void rotate(double yaw, double pitch, boolean movementCorrection, Runnable callback) { - rotate(yaw, pitch, 0, movementCorrection, callback); - } - - public static void rotate(double yaw, double pitch, int priority, boolean movementCorrection) { - rotate(yaw, pitch, priority, movementCorrection, null); - } - - public static void rotate(double yaw, double pitch, boolean movementCorrection, boolean silentMovementCorrection) { - Rotations.silentMovementCorrection = silentMovementCorrection; - rotate(yaw, pitch, 0, movementCorrection, null); - } - - public static boolean movementCorrection = true; - public static boolean silentMovementCorrection = true; - // From Meteor Client - private static final Pool rotationPool = new Pool<>(Rotation::new); - private static final List rotations = new ArrayList<>(); - public static float serverYaw; - public static float serverPitch; - public static int rotationTimer; - private static float preYaw, prePitch; - private static int i = 0; - - private static Rotation lastRotation; - private static int lastRotationTimer; - private static boolean sentLastRotation; - public static boolean rotating = false; - - private static void resetLastRotation() { - if (lastRotation != null) { - rotationPool.free(lastRotation); - - lastRotation = null; - lastRotationTimer = 0; - } - } - - private static void setupMovementPacketRotation(Rotation rotation) { - setClientRotation(rotation); - setCamRotation(rotation.yaw, rotation.pitch); - } - - public static void setCamRotation(double yaw, double pitch) { - serverYaw = (float) yaw; - serverPitch = (float) pitch; - rotationTimer = 0; - } - - private static void setClientRotation(Rotation rotation) { - assert mc.player != null; - preYaw = mc.player.yRotO; - prePitch = mc.player.xRotO; - - mc.player.setYRot((float) rotation.yaw); - mc.player.setXRot((float) rotation.pitch); - } - - private static void resetPreRotation() { - assert mc.player != null; - mc.player.setYRot(preYaw); - mc.player.setXRot(prePitch); - } - - public static void init() { - SendMovementPacketsEvent.POST.register(Rotations::onSendMovementPacketsPost); - SendMovementPacketsEvent.PRE.register(Rotations::onSendMovementPacketsPre); - ClientTickEvents.START_CLIENT_TICK.register(Rotations::onTick); - PlayerVelocityStrafeEvent.EVENT.register(Rotations::playerVelocity); - } - - private static InteractionResult playerVelocity(PlayerVelocityStrafeEvent event) { - if (rotating && movementCorrection) { - event.velocity = Entity.getInputVector( - event.movementInput, - event.speed, - serverYaw - ); - } - return InteractionResult.PASS; - } - - private static void onSendMovementPacketsPre(float v, float v1) { - if (mc.getCameraEntity() != mc.player) return; - sentLastRotation = false; - - if (!rotations.isEmpty()) { - rotating = true; - resetLastRotation(); - - Rotation rotation = rotations.get(i); - setupMovementPacketRotation(rotation); - - if (rotations.size() > 1) rotationPool.free(rotation); - - i++; - } else if (lastRotation != null) { - if (lastRotationTimer >= 1) { - resetLastRotation(); - rotating = false; - } else { - setupMovementPacketRotation(lastRotation); - sentLastRotation = true; - - lastRotationTimer++; - } - } - } - - private static void onTick(Minecraft minecraft) { - rotationTimer++; - } - - private static void onSendMovementPacketsPost() { - if (!rotations.isEmpty()) { - if (mc.getCameraEntity() == mc.player) { - rotations.get(i - 1).runCallback(); - - if (rotations.size() == 1) lastRotation = rotations.get(i - 1); - - resetPreRotation(); - } - - for (; i < rotations.size(); i++) { - Rotation rotation = rotations.get(i); - - setCamRotation(rotation.yaw, rotation.pitch); - if (rotation.clientSide) setClientRotation(rotation); - rotation.sendPacket(); - if (rotation.clientSide) resetPreRotation(); - - if (i == rotations.size() - 1) lastRotation = rotation; - else rotationPool.free(rotation); - } - - rotations.clear(); - i = 0; - } else if (sentLastRotation) { - resetPreRotation(); - } - } - - - private static class Rotation { - public double yaw, pitch; - public int priority; - public boolean clientSide; - public Runnable callback; - - public void set(double yaw, double pitch, int priority, boolean clientSide, Runnable callback) { - this.yaw = yaw; - this.pitch = pitch; - this.priority = priority; - this.clientSide = clientSide; - this.callback = callback; - } - - public void sendPacket() { - //if (Rotations.rotating) { - mc.getConnection().send(new ServerboundMovePlayerPacket.Rot((float) yaw, (float) pitch, mc.player.onGround(), mc.player.horizontalCollision)); - runCallback(); - //} - } - - public void runCallback() { - if (callback != null) callback.run(); - } - } -} diff --git a/src/main/kotlin/com/nekiplay/neoscripts/events/MovementInputEvent.kt b/src/main/kotlin/com/nekiplay/neoscripts/events/MovementInputEvent.kt new file mode 100644 index 00000000..4b3383f5 --- /dev/null +++ b/src/main/kotlin/com/nekiplay/neoscripts/events/MovementInputEvent.kt @@ -0,0 +1,10 @@ +package com.nekiplay.neoscripts.events + +import com.nekiplay.neoscripts.events.main.Event +import com.nekiplay.neoscripts.utils.DirectionalInput + +class MovementInputEvent( + override var directionalInput: DirectionalInput, + val jump: Boolean, + val shift: Boolean +) : Event() diff --git a/src/main/kotlin/com/nekiplay/neoscripts/events/main/Event.kt b/src/main/kotlin/com/nekiplay/neoscripts/events/main/Event.kt index efa1696e..6332354c 100644 --- a/src/main/kotlin/com/nekiplay/neoscripts/events/main/Event.kt +++ b/src/main/kotlin/com/nekiplay/neoscripts/events/main/Event.kt @@ -1,3 +1,8 @@ package com.nekiplay.neoscripts.events.main -abstract class Event \ No newline at end of file +import com.nekiplay.neoscripts.utils.DirectionalInput + +abstract class Event { + @JvmField + open var directionalInput: DirectionalInput = TODO("initialize me") +} \ No newline at end of file diff --git a/src/main/kotlin/com/nekiplay/neoscripts/features/lua/objects/player/PlayerObject.kt b/src/main/kotlin/com/nekiplay/neoscripts/features/lua/objects/player/PlayerObject.kt index 5c04cc46..11b116f5 100644 --- a/src/main/kotlin/com/nekiplay/neoscripts/features/lua/objects/player/PlayerObject.kt +++ b/src/main/kotlin/com/nekiplay/neoscripts/features/lua/objects/player/PlayerObject.kt @@ -12,18 +12,15 @@ import com.nekiplay.neoscripts.sugar.getScorebordLines import com.nekiplay.neoscripts.sugar.getTab import com.nekiplay.neoscripts.utils.PlayerUtils import com.nekiplay.neoscripts.utils.RaycastUtils -import com.nekiplay.neoscripts.utils.Rotations import com.nekiplay.neoscripts.utils.StatusBarTracker import com.nekiplay.neoscripts.utils.Utils import com.nekiplay.neoscripts.utils.aiming.RotationManager import com.nekiplay.neoscripts.utils.trackers.ColdTracker import com.nekiplay.neoscripts.utils.trackers.PetCache import net.minecraft.client.Minecraft -import net.minecraft.client.gui.components.BossHealthOverlay import net.minecraft.client.gui.components.LerpingBossEvent import net.minecraft.client.gui.components.toasts.SystemToast import net.minecraft.network.chat.Component -import java.lang.reflect.Field import net.minecraft.world.InteractionHand import net.minecraft.world.level.block.Block import net.minecraft.world.phys.Vec3 diff --git a/src/main/kotlin/com/nekiplay/neoscripts/features/lua/objects/world/WorldObject.kt b/src/main/kotlin/com/nekiplay/neoscripts/features/lua/objects/world/WorldObject.kt index fcfe41d9..9bcc157c 100644 --- a/src/main/kotlin/com/nekiplay/neoscripts/features/lua/objects/world/WorldObject.kt +++ b/src/main/kotlin/com/nekiplay/neoscripts/features/lua/objects/world/WorldObject.kt @@ -11,9 +11,7 @@ import com.nekiplay.neoscripts.features.lua.objects.datatypes.core.LuaVector3d import com.nekiplay.neoscripts.features.lua.objects.datatypes.phys.LuaRaycast import com.nekiplay.neoscripts.mixins.minecraft.LevelRendererAccessor import com.nekiplay.neoscripts.utils.RaycastUtils -import com.nekiplay.neoscripts.utils.Rotations import net.minecraft.client.multiplayer.ClientLevel -import net.minecraft.client.resources.sounds.SoundInstance import net.minecraft.core.BlockPos import net.minecraft.resources.Identifier import net.minecraft.sounds.SoundEvent diff --git a/src/main/kotlin/com/nekiplay/neoscripts/sugar/Entity.kt b/src/main/kotlin/com/nekiplay/neoscripts/sugar/Entity.kt index 3a79c7af..94c3a103 100644 --- a/src/main/kotlin/com/nekiplay/neoscripts/sugar/Entity.kt +++ b/src/main/kotlin/com/nekiplay/neoscripts/sugar/Entity.kt @@ -1,7 +1,6 @@ package com.nekiplay.neoscripts.sugar import com.nekiplay.neoscripts.Main.mc -import com.nekiplay.neoscripts.utils.Rotations import net.minecraft.world.entity.Entity fun Entity.getRotation(): Pair { diff --git a/src/main/kotlin/com/nekiplay/neoscripts/sugar/MultiPlayerGameMode.kt b/src/main/kotlin/com/nekiplay/neoscripts/sugar/MultiPlayerGameMode.kt index 6c7ce064..fb88fab1 100644 --- a/src/main/kotlin/com/nekiplay/neoscripts/sugar/MultiPlayerGameMode.kt +++ b/src/main/kotlin/com/nekiplay/neoscripts/sugar/MultiPlayerGameMode.kt @@ -3,7 +3,6 @@ package com.nekiplay.neoscripts.sugar import com.nekiplay.neoscripts.Main.mc import com.nekiplay.neoscripts.mixins.ClientPlayerInteractionManagerAccessor import com.nekiplay.neoscripts.utils.RaycastUtils -import com.nekiplay.neoscripts.utils.Rotations import net.minecraft.client.Minecraft import net.minecraft.client.multiplayer.MultiPlayerGameMode import net.minecraft.client.multiplayer.prediction.PredictiveAction diff --git a/src/main/kotlin/com/nekiplay/neoscripts/utils/DirectionalInput.kt b/src/main/kotlin/com/nekiplay/neoscripts/utils/DirectionalInput.kt index 1ea64fdc..6b5c7dfe 100644 --- a/src/main/kotlin/com/nekiplay/neoscripts/utils/DirectionalInput.kt +++ b/src/main/kotlin/com/nekiplay/neoscripts/utils/DirectionalInput.kt @@ -23,17 +23,24 @@ data class DirectionalInput( right = movementSideways < 0.0 ) - fun invert(): DirectionalInput { - return DirectionalInput( - forwards = backwards, - backwards = forwards, - left = right, - right = left - ) + fun getForwardValue(): Int = when { + forwards -> 1 + backwards -> -1 + else -> 0 } - val isMoving: Boolean - get() = forwards != backwards || left != right + fun getSidewaysValue(): Int = when { + right -> 1 + left -> -1 + else -> 0 + } + + fun invert(): DirectionalInput = DirectionalInput( + forwards = backwards, + backwards = forwards, + left = right, + right = left + ) companion object { @JvmField From e1d562a24b797346384883ec020eacdac1a2754a Mon Sep 17 00:00:00 2001 From: Roman Danilov Date: Sat, 25 Apr 2026 05:24:39 +0500 Subject: [PATCH 17/27] Fixes --- .../neoscripts/utils/RotationuUtils.java | 40 +++++++++++++++++++ .../lua/objects/player/PlayerObject.kt | 17 ++++---- .../features/lua/objects/world/WorldObject.kt | 9 +++-- .../neoscripts/sugar/MultiPlayerGameMode.kt | 12 +++--- 4 files changed, 61 insertions(+), 17 deletions(-) create mode 100644 src/main/java/com/nekiplay/neoscripts/utils/RotationuUtils.java diff --git a/src/main/java/com/nekiplay/neoscripts/utils/RotationuUtils.java b/src/main/java/com/nekiplay/neoscripts/utils/RotationuUtils.java new file mode 100644 index 00000000..fc6ba955 --- /dev/null +++ b/src/main/java/com/nekiplay/neoscripts/utils/RotationuUtils.java @@ -0,0 +1,40 @@ +package com.nekiplay.neoscripts.utils; + +import net.minecraft.util.Mth; +import net.minecraft.world.entity.Entity; +import net.minecraft.world.phys.Vec3; + +import static com.nekiplay.neoscripts.Main.mc; + +public class RotationuUtils { + public static double getYaw(Entity entity) { + return mc.player.getYRot() + Mth.wrapDegrees((float) Math.toDegrees(Math.atan2(entity.getZ() - mc.player.getZ(), entity.getX() - mc.player.getX())) - 90f - mc.player.getYRot()); + } + + public static double getYaw(Vec3 pos) { + return mc.player.getYRot() + Mth.wrapDegrees((float) Math.toDegrees(Math.atan2(pos.z() - mc.player.getZ(), pos.x() - mc.player.getX())) - 90f - mc.player.getYRot()); + } + + public static double getPitch(Vec3 pos) { + double diffX = pos.x() - mc.player.getX(); + double diffY = pos.y() - (mc.player.getY() + mc.player.getEyeHeight(mc.player.getPose())); + double diffZ = pos.z() - mc.player.getZ(); + + double diffXZ = Math.sqrt(diffX * diffX + diffZ * diffZ); + + return mc.player.getXRot() + Mth.wrapDegrees((float) -Math.toDegrees(Math.atan2(diffY, diffXZ)) - mc.player.getXRot()); + } + + public static Vec3 getDirectionFromYawPitch(float yaw, float pitch) { + // Конвертируем градусы в радианы + float yawRad = (float) Math.toRadians(yaw); + float pitchRad = (float) Math.toRadians(pitch); + + // Вычисляем компоненты вектора + double x = -Mth.sin(yawRad) * Mth.cos(pitchRad); + double y = -Mth.sin(pitchRad); + double z = Mth.cos(yawRad) * Mth.cos(pitchRad); + + return new Vec3(x, y, z).normalize(); + } +} diff --git a/src/main/kotlin/com/nekiplay/neoscripts/features/lua/objects/player/PlayerObject.kt b/src/main/kotlin/com/nekiplay/neoscripts/features/lua/objects/player/PlayerObject.kt index 11b116f5..13478473 100644 --- a/src/main/kotlin/com/nekiplay/neoscripts/features/lua/objects/player/PlayerObject.kt +++ b/src/main/kotlin/com/nekiplay/neoscripts/features/lua/objects/player/PlayerObject.kt @@ -12,6 +12,7 @@ import com.nekiplay.neoscripts.sugar.getScorebordLines import com.nekiplay.neoscripts.sugar.getTab import com.nekiplay.neoscripts.utils.PlayerUtils import com.nekiplay.neoscripts.utils.RaycastUtils +import com.nekiplay.neoscripts.utils.RotationuUtils import com.nekiplay.neoscripts.utils.StatusBarTracker import com.nekiplay.neoscripts.utils.Utils import com.nekiplay.neoscripts.utils.aiming.RotationManager @@ -287,7 +288,7 @@ class PlayerObject : LuaValue() { override fun call(arg1: LuaValue, arg2: LuaValue): LuaValue? { if (arg1.isnumber() && arg2.isnumber()) { val table = tableOf() - val rotations = Rotations.getDirectionFromYawPitch(arg1.tofloat(), arg2.tofloat()) + val rotations = RotationuUtils.getDirectionFromYawPitch(arg1.tofloat(), arg2.tofloat()) table.set("direction", LuaVector3d(rotations)) return table } @@ -322,12 +323,12 @@ class PlayerObject : LuaValue() { return NIL } - val hitResult = if (Rotations.rotating) { + val hitResult = if (!RotationManager.getCurrentLastYaw().isNaN()) { RaycastUtils.rayTrace( mc.cameraEntity, 4.5, - Rotations.serverYaw, - Rotations.serverPitch, + RotationManager.getCurrentLastYaw(), + RotationManager.getCurrentPitch(), targetBlocks ) } @@ -356,12 +357,12 @@ class PlayerObject : LuaValue() { ): LuaValue? { if (arg1?.isnumber() == true) { val player = mc.player ?: return NIL - val hitResult = if (Rotations.rotating) { + val hitResult = if (!RotationManager.getCurrentYaw().isNaN()) { RaycastUtils.findCrosshairTarget( mc.cameraEntity, player.eyePosition, - Rotations.serverYaw, - Rotations.serverPitch, + RotationManager.getCurrentYaw(), + RotationManager.getCurrentPitch(), arg1.todouble(), arg1.todouble() ) @@ -511,7 +512,7 @@ class PlayerObject : LuaValue() { val player = mc.player; return if (player != null) { val table = tableOf() - if (Rotations.rotating) { + if (!RotationManager.getCurrentYaw().isNaN()) { table.set("yaw", valueOf(RotationManager.getCurrentYaw().toDouble())) table.set("pitch", valueOf(RotationManager.getCurrentPitch().toDouble())) } diff --git a/src/main/kotlin/com/nekiplay/neoscripts/features/lua/objects/world/WorldObject.kt b/src/main/kotlin/com/nekiplay/neoscripts/features/lua/objects/world/WorldObject.kt index 9bcc157c..fa5191f0 100644 --- a/src/main/kotlin/com/nekiplay/neoscripts/features/lua/objects/world/WorldObject.kt +++ b/src/main/kotlin/com/nekiplay/neoscripts/features/lua/objects/world/WorldObject.kt @@ -11,6 +11,7 @@ import com.nekiplay.neoscripts.features.lua.objects.datatypes.core.LuaVector3d import com.nekiplay.neoscripts.features.lua.objects.datatypes.phys.LuaRaycast import com.nekiplay.neoscripts.mixins.minecraft.LevelRendererAccessor import com.nekiplay.neoscripts.utils.RaycastUtils +import com.nekiplay.neoscripts.utils.RotationuUtils import net.minecraft.client.multiplayer.ClientLevel import net.minecraft.core.BlockPos import net.minecraft.resources.Identifier @@ -358,8 +359,8 @@ class WorldObject : LuaValue() { arg3: LuaValue? ): LuaValue? { return if (arg1?.isnumber() == true && arg2?.isnumber() == true && arg3?.isnumber() == true) { - val yaw = Rotations.getYaw(Vec3(arg1.todouble(), arg2.todouble(), arg3.todouble())) - val pitch = Rotations.getPitch(Vec3(arg1.todouble(), arg2.todouble(), arg3.todouble())) + val yaw = RotationuUtils.getYaw(Vec3(arg1.todouble(), arg2.todouble(), arg3.todouble())) + val pitch = RotationuUtils.getPitch(Vec3(arg1.todouble(), arg2.todouble(), arg3.todouble())) val table = tableOf() table.set("yaw", valueOf(yaw)) table.set("pitch", valueOf(pitch)) @@ -368,8 +369,8 @@ class WorldObject : LuaValue() { else if (arg1?.isuserdata() == true && arg1.touserdata() is LuaBlockPos) { val pos = arg1.touserdata() as LuaBlockPos - val yaw = Rotations.getYaw(Vec3(pos.pos.x.toDouble(), pos.pos.y.toDouble(), pos.pos.z.toDouble())) - val pitch = Rotations.getPitch(Vec3(pos.pos.x.toDouble(), pos.pos.y.toDouble(), pos.pos.z.toDouble())) + val yaw = RotationuUtils.getYaw(Vec3(pos.pos.x.toDouble(), pos.pos.y.toDouble(), pos.pos.z.toDouble())) + val pitch = RotationuUtils.getPitch(Vec3(pos.pos.x.toDouble(), pos.pos.y.toDouble(), pos.pos.z.toDouble())) val table = tableOf() table.set("yaw", valueOf(yaw)) table.set("pitch", valueOf(pitch)) diff --git a/src/main/kotlin/com/nekiplay/neoscripts/sugar/MultiPlayerGameMode.kt b/src/main/kotlin/com/nekiplay/neoscripts/sugar/MultiPlayerGameMode.kt index fb88fab1..a4ef92cd 100644 --- a/src/main/kotlin/com/nekiplay/neoscripts/sugar/MultiPlayerGameMode.kt +++ b/src/main/kotlin/com/nekiplay/neoscripts/sugar/MultiPlayerGameMode.kt @@ -3,11 +3,13 @@ package com.nekiplay.neoscripts.sugar import com.nekiplay.neoscripts.Main.mc import com.nekiplay.neoscripts.mixins.ClientPlayerInteractionManagerAccessor import com.nekiplay.neoscripts.utils.RaycastUtils +import com.nekiplay.neoscripts.utils.aiming.RotationManager import net.minecraft.client.Minecraft import net.minecraft.client.multiplayer.MultiPlayerGameMode import net.minecraft.client.multiplayer.prediction.PredictiveAction import net.minecraft.core.BlockPos import net.minecraft.core.Direction +import net.minecraft.core.Rotations import net.minecraft.world.InteractionHand import net.minecraft.world.InteractionResult import net.minecraft.world.phys.BlockHitResult @@ -17,11 +19,11 @@ import net.minecraft.world.phys.Vec3 fun MultiPlayerGameMode.getRotationRaycast(): HitResult { - var yaw: Float = mc.player?.yRot ?: Rotations.serverYaw - var pitch: Float = mc.player?.xRot ?: Rotations.serverPitch - if (Rotations.rotating) { - yaw = Rotations.serverYaw - pitch = Rotations.serverPitch + var yaw: Float = mc.player?.yRot ?: RotationManager.getCurrentYaw() + var pitch: Float = mc.player?.xRot ?: RotationManager.getCurrentPitch() + if (!RotationManager.getCurrentYaw().isNaN()) { + yaw = RotationManager.getCurrentYaw() + pitch = RotationManager.getCurrentPitch() } val hitResult = RaycastUtils.findCrosshairTarget(mc.cameraEntity, mc.player?.eyePosition, yaw, pitch, mc.player?.blockInteractionRange() ?: 4.5, mc.player?.entityInteractionRange() ?: 3.0) return hitResult From ce9508fdd7b810021375a7cbf03bcbf80a5366d2 Mon Sep 17 00:00:00 2001 From: Roman Danilov Date: Sat, 25 Apr 2026 05:27:10 +0500 Subject: [PATCH 18/27] Update MixinFireworkRocketEntity.java --- .../neoscripts/mixins/entity/MixinFireworkRocketEntity.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/nekiplay/neoscripts/mixins/entity/MixinFireworkRocketEntity.java b/src/main/java/com/nekiplay/neoscripts/mixins/entity/MixinFireworkRocketEntity.java index dba183c9..12e4d421 100644 --- a/src/main/java/com/nekiplay/neoscripts/mixins/entity/MixinFireworkRocketEntity.java +++ b/src/main/java/com/nekiplay/neoscripts/mixins/entity/MixinFireworkRocketEntity.java @@ -13,7 +13,7 @@ public abstract class MixinFireworkRocketEntity { @Redirect(method = "tick", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/entity/LivingEntity;getLookAngle()Lnet/minecraft/world/phys/Vec3;")) private Vec3 getLookAngleHook(LivingEntity instance) { - if (!Rotations.INSTANCE.getMoveFix()) { + if (Rotations.INSTANCE.getMoveFix() && !Float.isNaN(RotationManager.INSTANCE.getCurrentYaw())) { return instance.calculateViewVector( RotationManager.INSTANCE.getCurrentPitch(), From 1eb28e61cd2b35e283bb9dd1378d16128628d787 Mon Sep 17 00:00:00 2001 From: Roman Danilov Date: Sat, 25 Apr 2026 05:28:30 +0500 Subject: [PATCH 19/27] Update Entity.kt --- src/main/kotlin/com/nekiplay/neoscripts/sugar/Entity.kt | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/main/kotlin/com/nekiplay/neoscripts/sugar/Entity.kt b/src/main/kotlin/com/nekiplay/neoscripts/sugar/Entity.kt index 94c3a103..26d1838b 100644 --- a/src/main/kotlin/com/nekiplay/neoscripts/sugar/Entity.kt +++ b/src/main/kotlin/com/nekiplay/neoscripts/sugar/Entity.kt @@ -1,11 +1,12 @@ package com.nekiplay.neoscripts.sugar import com.nekiplay.neoscripts.Main.mc +import com.nekiplay.neoscripts.utils.aiming.RotationManager import net.minecraft.world.entity.Entity fun Entity.getRotation(): Pair { - return if (this == mc.player && Rotations.rotating) { - Pair(Rotations.serverYaw, Rotations.serverPitch) + return if (this == mc.player && !RotationManager.getCurrentYaw().isNaN()) { + Pair(RotationManager.getCurrentYaw(), RotationManager.getCurrentPitch()) } else { Pair(this.yRot, this.xRotO) From ea17034e8e0fcd88eb732527ffffa13e01e347fd Mon Sep 17 00:00:00 2001 From: Roman Danilov Date: Sat, 25 Apr 2026 05:35:29 +0500 Subject: [PATCH 20/27] Update Event.kt --- src/main/kotlin/com/nekiplay/neoscripts/events/main/Event.kt | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/main/kotlin/com/nekiplay/neoscripts/events/main/Event.kt b/src/main/kotlin/com/nekiplay/neoscripts/events/main/Event.kt index 6332354c..4c82bd5a 100644 --- a/src/main/kotlin/com/nekiplay/neoscripts/events/main/Event.kt +++ b/src/main/kotlin/com/nekiplay/neoscripts/events/main/Event.kt @@ -2,7 +2,4 @@ package com.nekiplay.neoscripts.events.main import com.nekiplay.neoscripts.utils.DirectionalInput -abstract class Event { - @JvmField - open var directionalInput: DirectionalInput = TODO("initialize me") -} \ No newline at end of file +abstract class Event {} \ No newline at end of file From c4ad9c9143aa821959234c8b88498d8fa2c46f5b Mon Sep 17 00:00:00 2001 From: Roman Danilov Date: Sat, 25 Apr 2026 05:38:36 +0500 Subject: [PATCH 21/27] Update MovementInputEvent.kt --- .../kotlin/com/nekiplay/neoscripts/events/MovementInputEvent.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/kotlin/com/nekiplay/neoscripts/events/MovementInputEvent.kt b/src/main/kotlin/com/nekiplay/neoscripts/events/MovementInputEvent.kt index 4b3383f5..212d17f7 100644 --- a/src/main/kotlin/com/nekiplay/neoscripts/events/MovementInputEvent.kt +++ b/src/main/kotlin/com/nekiplay/neoscripts/events/MovementInputEvent.kt @@ -4,7 +4,7 @@ import com.nekiplay.neoscripts.events.main.Event import com.nekiplay.neoscripts.utils.DirectionalInput class MovementInputEvent( - override var directionalInput: DirectionalInput, + var directionalInput: DirectionalInput, val jump: Boolean, val shift: Boolean ) : Event() From 06a3cd51a66d67ef9e01ab46417792a4c3b6ac11 Mon Sep 17 00:00:00 2001 From: Roman Danilov Date: Sat, 25 Apr 2026 05:40:42 +0500 Subject: [PATCH 22/27] Update MixinItem.java --- .../nekiplay/neoscripts/mixins/minecraft/item/MixinItem.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/nekiplay/neoscripts/mixins/minecraft/item/MixinItem.java b/src/main/java/com/nekiplay/neoscripts/mixins/minecraft/item/MixinItem.java index fbdc3f74..a3861319 100644 --- a/src/main/java/com/nekiplay/neoscripts/mixins/minecraft/item/MixinItem.java +++ b/src/main/java/com/nekiplay/neoscripts/mixins/minecraft/item/MixinItem.java @@ -1,6 +1,7 @@ package com.nekiplay.neoscripts.mixins.minecraft.item; import com.llamalad7.mixinextras.injector.ModifyExpressionValue; +import com.nekiplay.neoscripts.utils.aiming.RotationManager; import net.minecraft.client.Minecraft; import net.minecraft.world.entity.player.Player; import net.minecraft.world.item.Item; @@ -17,8 +18,8 @@ public abstract class MixinItem { target = "Lnet/minecraft/world/entity/player/Player;calculateViewVector(FF)Lnet/minecraft/world/phys/Vec3;")) private static Vec3 hookFixRotation(Vec3 original, Level world, Player player, ClipContext.Fluid fluidHandling) { if (player == Minecraft.getInstance().player) { - if (Rotations.rotating) { - return Vec3.directionFromRotation(Rotations.serverPitch, Rotations.serverYaw); + if (!Float.isNaN(RotationManager.INSTANCE.getCurrentYaw())) { + return Vec3.directionFromRotation(RotationManager.INSTANCE.getCurrentPitch(), RotationManager.INSTANCE.getCurrentYaw()); } } return original; From 01d928bdaeafce859a3d077de2424643115ab4e6 Mon Sep 17 00:00:00 2001 From: Roman Danilov Date: Sat, 25 Apr 2026 05:59:31 +0500 Subject: [PATCH 23/27] Update MixinLocalPlayer.java --- .../mixins/entity/MixinLocalPlayer.java | 40 +++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/src/main/java/com/nekiplay/neoscripts/mixins/entity/MixinLocalPlayer.java b/src/main/java/com/nekiplay/neoscripts/mixins/entity/MixinLocalPlayer.java index e30fdd07..e32cbadd 100644 --- a/src/main/java/com/nekiplay/neoscripts/mixins/entity/MixinLocalPlayer.java +++ b/src/main/java/com/nekiplay/neoscripts/mixins/entity/MixinLocalPlayer.java @@ -1,14 +1,20 @@ package com.nekiplay.neoscripts.mixins.entity; +import com.llamalad7.mixinextras.injector.ModifyExpressionValue; import com.mojang.authlib.GameProfile; import com.nekiplay.neoscripts.events.*; import com.nekiplay.neoscripts.events.main.EventBus; +import com.nekiplay.neoscripts.utils.RaycastUtils; +import com.nekiplay.neoscripts.utils.aiming.RotationManager; +import net.minecraft.client.Minecraft; import net.minecraft.client.multiplayer.ClientLevel; import net.minecraft.client.player.AbstractClientPlayer; import net.minecraft.client.player.ClientInput; import net.minecraft.client.player.LocalPlayer; import net.minecraft.world.entity.Entity; +import net.minecraft.world.entity.player.Player; import net.minecraft.world.phys.HitResult; +import net.minecraft.world.phys.Vec3; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.injection.At; @@ -51,4 +57,38 @@ private void applyInputHook(CallbackInfo ci) { private void raycastPostHitResultHook(float f, Entity entity, CallbackInfoReturnable cir) { EventBus.INSTANCE.send(new RaycastHitEvent(false)); } + @ModifyExpressionValue(method = "pick(Lnet/minecraft/world/entity/Entity;DDF)Lnet/minecraft/world/phys/HitResult;", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/entity/Entity;pick(DFZ)Lnet/minecraft/world/phys/HitResult;")) + private static HitResult hookRaycast(HitResult original, Entity camera, double blockInteractionRange, double entityInteractionRange, float tickDelta) { + if (camera != Minecraft.getInstance().player) { + return original; + + } + + if (Float.isNaN(RotationManager.INSTANCE.getCurrentYaw())) { + return RaycastUtils.findCrosshairTarget(camera, + camera.getEyePosition(), + RotationManager.INSTANCE.getCurrentYaw(), + RotationManager.INSTANCE.getCurrentPitch(), + ((Player) camera).blockInteractionRange(), + ((Player) camera).entityInteractionRange() + ); + } + else { + return original; + } + } + + @ModifyExpressionValue(method = "pick(Lnet/minecraft/world/entity/Entity;DDF)Lnet/minecraft/world/phys/HitResult;", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/entity/Entity;getViewVector(F)Lnet/minecraft/world/phys/Vec3;")) + private static Vec3 hookRotationVector(Vec3 original, Entity camera, double blockInteractionRange, double entityInteractionRange, float tickDelta) { + if (camera != Minecraft.getInstance().player) { + return original; + } + + if (Float.isNaN(RotationManager.INSTANCE.getCurrentYaw())) { + return Vec3.directionFromRotation(RotationManager.INSTANCE.getCurrentYaw(), RotationManager.INSTANCE.getCurrentPitch()); + } + else { + return original; + } + } } \ No newline at end of file From c5b47dc71a0d7c38c8655552448f3da81bcae76b Mon Sep 17 00:00:00 2001 From: Roman Danilov Date: Sat, 25 Apr 2026 06:00:03 +0500 Subject: [PATCH 24/27] Update MixinLocalPlayer.java --- .../nekiplay/neoscripts/mixins/entity/MixinLocalPlayer.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/nekiplay/neoscripts/mixins/entity/MixinLocalPlayer.java b/src/main/java/com/nekiplay/neoscripts/mixins/entity/MixinLocalPlayer.java index e32cbadd..b5208893 100644 --- a/src/main/java/com/nekiplay/neoscripts/mixins/entity/MixinLocalPlayer.java +++ b/src/main/java/com/nekiplay/neoscripts/mixins/entity/MixinLocalPlayer.java @@ -64,7 +64,7 @@ private static HitResult hookRaycast(HitResult original, Entity camera, double b } - if (Float.isNaN(RotationManager.INSTANCE.getCurrentYaw())) { + if (!Float.isNaN(RotationManager.INSTANCE.getCurrentYaw())) { return RaycastUtils.findCrosshairTarget(camera, camera.getEyePosition(), RotationManager.INSTANCE.getCurrentYaw(), @@ -84,7 +84,7 @@ private static Vec3 hookRotationVector(Vec3 original, Entity camera, double bloc return original; } - if (Float.isNaN(RotationManager.INSTANCE.getCurrentYaw())) { + if (!Float.isNaN(RotationManager.INSTANCE.getCurrentYaw())) { return Vec3.directionFromRotation(RotationManager.INSTANCE.getCurrentYaw(), RotationManager.INSTANCE.getCurrentPitch()); } else { From 2029e38c8ec806af8e7770c7f90a507c1f230a0a Mon Sep 17 00:00:00 2001 From: Roman Danilov Date: Sat, 25 Apr 2026 06:17:29 +0500 Subject: [PATCH 25/27] Fix Events --- .../events/network/PacketEvent.java | 80 ----- .../features/modules/impl/misc/LuaEvents.kt | 280 ++++++++---------- 2 files changed, 131 insertions(+), 229 deletions(-) delete mode 100644 src/main/java/com/nekiplay/neoscripts/events/network/PacketEvent.java diff --git a/src/main/java/com/nekiplay/neoscripts/events/network/PacketEvent.java b/src/main/java/com/nekiplay/neoscripts/events/network/PacketEvent.java deleted file mode 100644 index fc6d5308..00000000 --- a/src/main/java/com/nekiplay/neoscripts/events/network/PacketEvent.java +++ /dev/null @@ -1,80 +0,0 @@ -package com.nekiplay.neoscripts.events.network; - -import net.fabricmc.fabric.api.event.Event; -import net.fabricmc.fabric.api.event.EventFactory; -import net.minecraft.network.Connection; -import net.minecraft.network.protocol.Packet; -import net.minecraft.world.InteractionResult; - -public class PacketEvent { - public static final Event RECEIVE = EventFactory.createArrayBacked( - PacketEvent.PacketEventReciveCallback.class, - (listeners) -> (event) -> { - for (PacketEvent.PacketEventReciveCallback listener : listeners) { - InteractionResult result = listener.update(event); - - if(result != InteractionResult.PASS) { - return result; - } - } - - return InteractionResult.PASS; - } - ); - - public static final Event SEND = EventFactory.createArrayBacked( - PacketEvent.PacketEventSendCallback.class, - (listeners) -> (event) -> { - for (PacketEvent.PacketEventSendCallback listener : listeners) { - InteractionResult result = listener.update(event); - - if(result != InteractionResult.PASS) { - return result; - } - } - - return InteractionResult.PASS; - } - ); - - public static final Event SENT = EventFactory.createArrayBacked( - PacketEvent.PacketEventSentCallback.class, - (listeners) -> (event) -> { - for (PacketEvent.PacketEventSentCallback listener : listeners) { - InteractionResult result = listener.update(event); - - if(result != InteractionResult.PASS) { - return result; - } - } - - return InteractionResult.PASS; - } - ); - - private Packet packet; - private Connection connection; - - public PacketEvent(Packet packet, Connection connection) { - this.packet = packet; - this.connection = connection; - } - - public Packet getPacket() { - return packet; - } - - public Connection getConnection() { - return connection; - } - - public interface PacketEventReciveCallback { - InteractionResult update(PacketEvent event); - } - public interface PacketEventSendCallback { - InteractionResult update(PacketEvent event); - } - public interface PacketEventSentCallback { - InteractionResult update(PacketEvent event); - } -} diff --git a/src/main/kotlin/com/nekiplay/neoscripts/features/modules/impl/misc/LuaEvents.kt b/src/main/kotlin/com/nekiplay/neoscripts/features/modules/impl/misc/LuaEvents.kt index 7b66fdae..079819f7 100644 --- a/src/main/kotlin/com/nekiplay/neoscripts/features/modules/impl/misc/LuaEvents.kt +++ b/src/main/kotlin/com/nekiplay/neoscripts/features/modules/impl/misc/LuaEvents.kt @@ -6,14 +6,15 @@ import com.nekiplay.neoscripts.Main.LUA_MANAGER import com.nekiplay.neoscripts.Main.mc import com.nekiplay.neoscripts.events.KeyEvent import com.nekiplay.neoscripts.events.MouseButtonEvent +import com.nekiplay.neoscripts.events.PacketEvent +import com.nekiplay.neoscripts.events.RenderEvent import com.nekiplay.neoscripts.events.SkyblockEvents -import com.nekiplay.neoscripts.events.network.PacketEvent +import com.nekiplay.neoscripts.events.main.Callback import com.nekiplay.neoscripts.events.player.AddItemInventoryEvent import com.nekiplay.neoscripts.features.lua.objects.datatypes.LuaBlockState import com.nekiplay.neoscripts.features.lua.objects.datatypes.core.LuaBlockPos import com.nekiplay.neoscripts.features.lua.objects.render.WorldRendererObject import com.nekiplay.neoscripts.features.modules.ClientModule -import com.nekiplay.neoscripts.mixins.packets.ServerboundMovePlayerPacketAccessor import com.nekiplay.neoscripts.sugar.getFormattedString import com.nekiplay.neoscripts.sugar.getJsonString import com.nekiplay.neoscripts.utils.render.WorldRenderExtractionCallback @@ -46,6 +47,134 @@ import org.luaj.vm2.LuaValue object LuaEvents : ClientModule() { + + @Callback + fun onSendPacket(event : PacketEvent.Send) { + val allow = when (event.packet) { + is ServerboundMovePlayerPacket -> { + val packet = event.packet as ServerboundMovePlayerPacket + var allowed = true + LUA_MANAGER?.scripts?.values?.forEach { script -> + if (!script.onPlayerSendMovement( + packet.hasPosition(), + packet.getX(0.0), + packet.getY(0.0), + packet.getZ(0.0), + packet.hasPosition(), + packet.getYRot(0f), + packet.getXRot(0f), + packet.isOnGround + )) { + allowed = false + } + } + allowed + } + else -> true + } + if (!allow) event.cancelled = true + } + + @Callback + fun onRecivePacket(event : PacketEvent.Send) { + when (event.packet) { + is ClientboundLevelParticlesPacket -> { + val packet = event.packet as ClientboundLevelParticlesPacket + + LUA_MANAGER?.scripts?.values?.forEach { script -> + script.onSpawnParticleEvent( + BuiltInRegistries.PARTICLE_TYPE.getId(packet.particle.type), + packet.x, + packet.y, + packet.z, + packet.xDist, + packet.yDist, + packet.zDist, + packet.maxSpeed, + packet.count + ) + } + } + + is ClientboundSetTimePacket -> { + val packet = event.packet as ClientboundSetTimePacket + + LUA_MANAGER?.scripts?.values?.forEach { script -> + script.onServerSideSetTimeEvent(packet.dayTime, packet.gameTime, packet.tickDayTime) + } + } + + is ClientboundSoundPacket -> { + val packet = event.packet as ClientboundSoundPacket + + LUA_MANAGER?.scripts?.values?.forEach { script -> + script.onSoundPlay(packet.sound, packet.x, packet.y, packet.z, packet.pitch.toDouble(), packet.volume.toDouble()) + } + } + } + val allow = when (val packet = event.packet) { + is ClientboundPlayerRotationPacket -> { + var rotationAllowed = true + LUA_MANAGER?.scripts?.values?.forEach { script -> + if (!script.onServerSideRotationEvent(packet.xRot, packet.yRot)) { + rotationAllowed = false + } + } + rotationAllowed + } + + is ClientboundBlockUpdatePacket -> { + var allowedBlockUpdate = true + val packet = event.packet as ClientboundBlockUpdatePacket + + val table = LuaValue.tableOf() + + table.set("position", LuaBlockPos(packet.pos)) + val oldState = mc.level?.getBlockState(packet.pos) + if (oldState != null) { + table.set("old", LuaBlockState(oldState)) + } + if (packet.blockState != null) { + table.set("new", LuaBlockState(packet.blockState)) + } + + LUA_MANAGER?.scripts?.values?.forEach { script -> + if (!script.onBlockUpdateEvent(table)) { + allowedBlockUpdate = false + } + } + + allowedBlockUpdate + } + + is ClientboundPlayerPositionPacket -> { + var rotationAllowed = true + var teleportAllowed = true + + LUA_MANAGER?.scripts?.values?.forEach { script -> + if (!script.onServerSideRotationEvent(packet.change.xRot(), packet.change.yRot())) { + rotationAllowed = false + } + if (!script.onServerSideTeleportEvent( + packet.change.position.x, + packet.change.position.y, + packet.change.position.z + ) + ) { + teleportAllowed = false + } + } + + rotationAllowed && teleportAllowed + } + + else -> true + } + + if (!allow) event.cancelled = true + } + + override fun init() { ClientTickEvents.END_CLIENT_TICK.register { _ -> LUA_MANAGER?.scripts?.values?.forEach { script -> @@ -246,153 +375,6 @@ object LuaEvents : ClientModule() { } } } - PacketEvent.SEND.register { event -> - val allow = when (event.packet) { - is ServerboundMovePlayerPacket -> { - val packet = event.packet as ServerboundMovePlayerPacket - var allowed = true - LUA_MANAGER?.scripts?.values?.forEach { script -> - if (!script.onPlayerSendMovement( - packet.hasPosition(), - packet.getX(0.0), - packet.getY(0.0), - packet.getZ(0.0), - packet.hasPosition(), - packet.getYRot(0f), - packet.getXRot(0f), - packet.isOnGround - )) { - allowed = false - } - } - allowed - } - else -> true - } - if (allow) InteractionResult.PASS else InteractionResult.FAIL - } - PacketEvent.SENT.register { event -> - val allow = when (event.packet) { - is ServerboundMovePlayerPacket -> { - val packet = event.packet as ServerboundMovePlayerPacket - var allowed = true - LUA_MANAGER?.scripts?.values?.forEach { script -> - if (!script.onPlayerSendMovement( - packet.hasPosition(), - packet.getX(0.0), - packet.getY(0.0), - packet.getZ(0.0), - packet.hasPosition(), - packet.getYRot(0f), - packet.getXRot(0f), - packet.isOnGround - )) { - allowed = false - } - } - allowed - } - else -> true - } - if (allow) InteractionResult.PASS else InteractionResult.FAIL - } - PacketEvent.RECEIVE.register { event -> - when (event.packet) { - is ClientboundLevelParticlesPacket -> { - val packet = event.packet as ClientboundLevelParticlesPacket - - LUA_MANAGER?.scripts?.values?.forEach { script -> - script.onSpawnParticleEvent( - BuiltInRegistries.PARTICLE_TYPE.getId(packet.particle.type), - packet.x, - packet.y, - packet.z, - packet.xDist, - packet.yDist, - packet.zDist, - packet.maxSpeed, - packet.count - ) - } - } - - is ClientboundSetTimePacket -> { - val packet = event.packet as ClientboundSetTimePacket - - LUA_MANAGER?.scripts?.values?.forEach { script -> - script.onServerSideSetTimeEvent(packet.dayTime, packet.gameTime, packet.tickDayTime) - } - } - - is ClientboundSoundPacket -> { - val packet = event.packet as ClientboundSoundPacket - - LUA_MANAGER?.scripts?.values?.forEach { script -> - script.onSoundPlay(packet.sound, packet.x, packet.y, packet.z, packet.pitch.toDouble(), packet.volume.toDouble()) - } - } - } - val allow = when (val packet = event.packet) { - is ClientboundPlayerRotationPacket -> { - var rotationAllowed = true - LUA_MANAGER?.scripts?.values?.forEach { script -> - if (!script.onServerSideRotationEvent(packet.xRot, packet.yRot)) { - rotationAllowed = false - } - } - rotationAllowed - } - - is ClientboundBlockUpdatePacket -> { - var allowedBlockUpdate = true - val packet = event.packet as ClientboundBlockUpdatePacket - - val table = LuaValue.tableOf() - - table.set("position", LuaBlockPos(packet.pos)) - val oldState = mc.level?.getBlockState(packet.pos) - if (oldState != null) { - table.set("old", LuaBlockState(oldState)) - } - if (packet.blockState != null) { - table.set("new", LuaBlockState(packet.blockState)) - } - - LUA_MANAGER?.scripts?.values?.forEach { script -> - if (!script.onBlockUpdateEvent(table)) { - allowedBlockUpdate = false - } - } - - allowedBlockUpdate - } - - is ClientboundPlayerPositionPacket -> { - var rotationAllowed = true - var teleportAllowed = true - - LUA_MANAGER?.scripts?.values?.forEach { script -> - if (!script.onServerSideRotationEvent(packet.change.xRot(), packet.change.yRot())) { - rotationAllowed = false - } - if (!script.onServerSideTeleportEvent( - packet.change.position.x, - packet.change.position.y, - packet.change.position.z - ) - ) { - teleportAllowed = false - } - } - - rotationAllowed && teleportAllowed - } - - else -> true - } - - if (allow) InteractionResult.PASS else InteractionResult.FAIL - } AddItemInventoryEvent.EVENT.register { event -> var allow = true LUA_MANAGER?.scripts?.values?.forEach { script -> From 1c62f306e9a71a425e2d77c571808c56538b1702 Mon Sep 17 00:00:00 2001 From: Roman Danilov Date: Sat, 25 Apr 2026 06:33:10 +0500 Subject: [PATCH 26/27] Fix events --- .../neoscripts/features/modules/impl/misc/LuaEvents.kt | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/main/kotlin/com/nekiplay/neoscripts/features/modules/impl/misc/LuaEvents.kt b/src/main/kotlin/com/nekiplay/neoscripts/features/modules/impl/misc/LuaEvents.kt index 079819f7..c8a3fdf5 100644 --- a/src/main/kotlin/com/nekiplay/neoscripts/features/modules/impl/misc/LuaEvents.kt +++ b/src/main/kotlin/com/nekiplay/neoscripts/features/modules/impl/misc/LuaEvents.kt @@ -7,7 +7,6 @@ import com.nekiplay.neoscripts.Main.mc import com.nekiplay.neoscripts.events.KeyEvent import com.nekiplay.neoscripts.events.MouseButtonEvent import com.nekiplay.neoscripts.events.PacketEvent -import com.nekiplay.neoscripts.events.RenderEvent import com.nekiplay.neoscripts.events.SkyblockEvents import com.nekiplay.neoscripts.events.main.Callback import com.nekiplay.neoscripts.events.player.AddItemInventoryEvent @@ -35,7 +34,6 @@ import net.minecraft.network.protocol.game.ClientboundPlayerPositionPacket import net.minecraft.network.protocol.game.ClientboundPlayerRotationPacket import net.minecraft.network.protocol.game.ClientboundSetTimePacket import net.minecraft.network.protocol.game.ClientboundSoundPacket -import net.minecraft.network.protocol.game.ServerboundContainerClickPacket import net.minecraft.network.protocol.game.ServerboundMovePlayerPacket import net.minecraft.world.InteractionHand import net.minecraft.world.InteractionResult @@ -76,7 +74,7 @@ object LuaEvents : ClientModule() { } @Callback - fun onRecivePacket(event : PacketEvent.Send) { + fun onRecivePacket(event : PacketEvent.Receive) { when (event.packet) { is ClientboundLevelParticlesPacket -> { val packet = event.packet as ClientboundLevelParticlesPacket From fe6fd2543d5590b618411097a87be0fa5d3b648c Mon Sep 17 00:00:00 2001 From: Roman Danilov Date: Sun, 26 Apr 2026 02:30:42 +0500 Subject: [PATCH 27/27] New variables for Items --- gradle.properties | 2 +- .../lua/objects/datatypes/LuaItemStack.kt | 48 +++++++++++++++++++ src/main/resources/fabric.mod.json | 2 +- 3 files changed, 50 insertions(+), 2 deletions(-) diff --git a/gradle.properties b/gradle.properties index 30823bec..896c121f 100644 --- a/gradle.properties +++ b/gradle.properties @@ -6,7 +6,7 @@ yarn_mappings=1.21.11+build.4 loader_version=0.18.4 # Mod Properties -mod_version=1.21.11_1.2.1.6.4 +mod_version=1.21.11_1.2.1.6.5 maven_group=com.nekiplay.neoscripts archives_base_name=neo-scripts diff --git a/src/main/kotlin/com/nekiplay/neoscripts/features/lua/objects/datatypes/LuaItemStack.kt b/src/main/kotlin/com/nekiplay/neoscripts/features/lua/objects/datatypes/LuaItemStack.kt index 08bc63db..81ece12f 100644 --- a/src/main/kotlin/com/nekiplay/neoscripts/features/lua/objects/datatypes/LuaItemStack.kt +++ b/src/main/kotlin/com/nekiplay/neoscripts/features/lua/objects/datatypes/LuaItemStack.kt @@ -16,8 +16,16 @@ import net.minecraft.core.registries.BuiltInRegistries import net.minecraft.core.component.DataComponents import net.minecraft.nbt.NbtOps import net.minecraft.network.chat.Component +import net.minecraft.tags.ItemTags +import net.minecraft.world.item.BlockItem +import net.minecraft.world.item.FishingRodItem +import net.minecraft.world.item.InstrumentItem import net.minecraft.world.item.ItemStack +import net.minecraft.world.item.MaceItem import net.minecraft.world.item.MapItem +import net.minecraft.world.item.ShearsItem +import net.minecraft.world.item.ShieldItem +import net.minecraft.world.item.TridentItem import net.minecraft.world.item.component.ItemLore import net.minecraft.world.level.block.Block import org.luaj.vm2.LuaDouble @@ -49,6 +57,46 @@ class LuaItemStack(val stack: ItemStack) : LuaUserdata(stack) { "is_enchanted" -> valueOf(stack.isEnchanted) "uuid" -> valueOf(stack.getItemUuid()) + "is_sword" -> { + valueOf(stack.`is`(ItemTags.SWORDS)) + } + "is_pickaxe" -> { + valueOf(stack.`is`(ItemTags.PICKAXES)) + } + "is_axe" -> { + valueOf(stack.`is`(ItemTags.AXES)) + } + "is_hoe" -> { + valueOf(stack.`is`(ItemTags.HOES)) + } + "is_shovel" -> { + valueOf(stack.`is`(ItemTags.SHOVELS)) + } + "is_map" -> { + valueOf(stack.item is MapItem) + } + "is_trident" -> { + valueOf(stack.item is TridentItem) + } + "is_instrument" -> { + valueOf(stack.item is InstrumentItem) + } + "is_shield" -> { + valueOf(stack.item is ShieldItem) + } + "is_shears" -> { + valueOf(stack.item is ShearsItem) + } + "is_mace" -> { + valueOf(stack.item is MaceItem) + } + "is_fishing_rod" -> { + valueOf(stack.item is FishingRodItem) + } + "is_block" -> { + valueOf(stack.item is BlockItem) + } + "map" -> { if (stack.item is MapItem && mc.level != null) { val level = mc.level ?: return NIL diff --git a/src/main/resources/fabric.mod.json b/src/main/resources/fabric.mod.json index 7eadd04e..ec56cf25 100644 --- a/src/main/resources/fabric.mod.json +++ b/src/main/resources/fabric.mod.json @@ -1,7 +1,7 @@ { "schemaVersion": 1, "id": "neoscripts", - "version": "1.2.1.6.4", + "version": "1.2.1.6.5", "name": "Neo Scripts", "description": "", "authors": [