diff --git a/README.md b/README.md index b250b14c..6c3979b9 100644 --- a/README.md +++ b/README.md @@ -1,16 +1,251 @@ -### Warning +# Cheat Utils + +## Warning + If you use download button on github, repository will not work since it is using git submodules. To download repository with submodules use below command: `git clone --recurse-submodules https://github.com/Zergatul/cheatutils.git` -### Build +## Build + To build mod by yourself go to Forge or Fabric directory and run `gradlew build`. -### Debugging/Customizing Web App +## Debugging/Customizing Web App + Download repo (or just `/common/resources/web` directory), and add JVM argument in Minecraft launcher like this: -``` + +```bat -Dcheatutils.web.dir=C:\full\path\to\web\directory ``` -Now local website uses static files from this directory instead of mod resources. \ No newline at end of file + +Now local website uses static files from this directory instead of mod resources. + +## Code Examples :- + +### Adding a module to the mod :- + +#### Step 1 + +Create your main class file. +This is where most of your modules code will be written. + +First, navigate to the modules folder located in `common/java/com/zergatul/cheatutils/modules`. +Select the folder that best fits your module type. +from here on, we will refer to a theoretical module named "AutoPearl", however you should follow the same naming conventions + +Create a new file : `"AutoPearl.java"`. + +the class should be in this format: + +```java +import com.zergatul.cheatutils.modules.Module; + +public class AutoPearl implements Module { + public static final AutoPearl instance = new AutoPearl(); + AutoPearl(){ + + } +} +``` + +#### Step 2 + +For the purposes of this explaination, it is assumed your module is named as "AutoPearl" +Register your module in the mod. +Navigate to `Modules.java` in the same directory. +Add your module to the following function + +```java +public static void register() { + register(AutoPearl.instance); +} +``` + +Make sure you place it in the right position, modules are initialized in the order listed here. This includes the order of their events added to EventsApi + +#### Step 3 + +Add your configuration class + +Navigate to `common/java/com/zergatul/cheatutils/configs` + +create a new file `AutoPearlConfig.java` + +```java +package com.zergatul.cheatutils.configs; + +public class AutoPearlConfig extends ModuleConfig implements ValidatableConfig { + + AutoPearlConfig() { + + } + + @Override + public void validate() { + return; + } +} +``` + +add your config validation inside the `validate()` function, this is where you will add limits to your variables, for example clampign the range of a value. +If your API will be accessible from the scripting, it is highly recomended to include validation for any variables. + +>[!NOTE] +> In case if your module does not require validation, you can skip `implements ValidatableConfig` and the overriden `public void validate()` function. When doing this, also skip adding validation to [`Root.java`](#adding-a-module-to-the-mod--) +> +> If your module does not require enable / disable, you can skip `extends ModuleConfig` as well. This also means you cannot use the `enabled` boolean or the `isEnabled()` inherited functions. Keep this in mind when creating the website / code for it. + +you can also add any more functions or values to change here. +for example: + +```java +public boolean bl1; +public double db1; +``` + +and so on. These must be public, you can also use functions internally, however functions will not work with the website API. +The API directly changes variables. + +an example of a minimal config which does not need validation or enable variable: + +```java + public class AutoPearlConfig {} +``` + +Next, navigate to `Config.java`, located in the same directory. + +Add your config to the class + +```java + public AutoPearlConfig classNameConfig = new AutoPearlConfig(); +``` + +Now, navigate to `configStore.java`, located in the same directory and add these lines + +```java + private void onConfigLoaded() { + config.classNameConfig.validate(); +``` + +#### Step 4 + +Adding the module API for the website to work with. +Navigate to `common/java/com/zergatul/cheatutils/scripting/modules/` +make a new file `AutoPearlConfig.java` + +add these lines + +```java +package com.zergatul.cheatutils.scripting.modules; + +import com.zergatul.cheatutils.configs.AutoPearlConfig; +import com.zergatul.cheatutils.configs.ConfigStore; + +public class AutoPearlApi extends ModuleApi { + + + @Override + protected AutoPearlConfig getConfig() { + return ConfigStore.instance.getConfig().classNameconfig; + } +} +``` + +#### Step 5 + +Allow the API to be accessed from scripting tools (this refers to user side scripting) + +Navigate to `common/java/com/zergatul/cheatutils/scripting/Root.java` + +Add the following lines inside the Root class. + +```java +public static AutoPearlApi className = new AutoPearlApi(); +``` + +This step is OPTIONAL and not required for module to function. +If you want your module configuration to be accessed from scripting +However, it is recomended to do this step + +#### Step 6 + +Adding your module to the website + +Navigate to `common/resources/web/modules.js` + +Add your module under line 21 with the following format: + +```javascript +module({ + group: 'automation', + name: 'Display Name', + component: 'AutoPearl', + path: 'class-name', + tags: ['search', 'terms', 'identifers'] +}); +``` + +Make sure you add your module to the correct section with the rest of its group +There are the following groups that can be used: + +```javascript +`automation` +`esp` +`hacks` +`visuals` +`scripting` +`utility` +``` + +In our example, we used `'automation'`, you can change this to match your module type + +now navigate to `common/resources/web/components` +next, navigate to the relevant folder for your module from the available folders. This is mapped to the groups used, so ensure you use the same folder. + +Create 2 new files: + +* AutoPearl.js +* AutoPearl.html + +inside the javascript file, add the following: + +```javascript +import { createSimpleComponent } from '/components/SimpleModule.js'; + +export function createComponent(template) { + return createSimpleComponent('/api/class-name', template); +} + +``` + +if you use any new components as listed in `common/resources/web/components.js` in your html, make sure to include them in your javascript file + +for example: + +```javascript +import { createSimpleComponent } from '/components/SimpleModule.js' + +export function createComponent(template) { + return createSimpleComponent('/api/class-name', template, { + components: ['CodeBlock', 'ColorBox'] + }); +} +``` + +##### How to make your html file + +This guide will focus on the working, for style and other formatting / component usage, look at the html of other modules already implemented + +your html file should look like this: + +```html +
+ +
+``` + +all components can be found at `common/resources/web/components/common` + +[Refer to this Document for more information and examples](./common/\/resources/web/Web%20Examples.md) diff --git a/common/java/com/zergatul/cheatutils/common/Events.java b/common/java/com/zergatul/cheatutils/common/Events.java index 868baec9..774987a0 100644 --- a/common/java/com/zergatul/cheatutils/common/Events.java +++ b/common/java/com/zergatul/cheatutils/common/Events.java @@ -2,6 +2,7 @@ import com.zergatul.cheatutils.common.events.*; import com.zergatul.cheatutils.controllers.SnapshotChunk; +import net.minecraft.WorldVersion; import net.minecraft.client.DeltaTracker; import net.minecraft.core.BlockPos; import net.minecraft.network.Connection; @@ -11,6 +12,8 @@ import net.minecraft.world.level.chunk.LevelChunk; import org.joml.Vector2ic; +import java.util.function.Consumer; + public class Events { // to better understand sequence of events they are ordered in trigger order @@ -45,10 +48,6 @@ public class Events { public static final SimpleEventHandler ClientTickEnd = new SimpleEventHandler(); - - - - public static final ParameterizedEventHandler ClientPlayerLoggingIn = new ParameterizedEventHandler<>(); public static final SimpleEventHandler ClientPlayerLoggingOut = new SimpleEventHandler(); public static final ParameterizedEventHandler RawChunkLoaded = new ParameterizedEventHandler<>(); @@ -59,7 +58,6 @@ public class Events { public static final ParameterizedEventHandler BlockUpdated = new ParameterizedEventHandler<>(); - public static final CancelableEventHandler PreRenderGuiOverlay = new CancelableEventHandler<>(); public static final CancelableEventHandler MouseScroll = new CancelableEventHandler<>(); @@ -74,7 +72,7 @@ public class Events { public static final SimpleEventHandler PostRenderTooltip = new SimpleEventHandler(); public static final ParameterizedEventHandler AfterScreenRendered = new ParameterizedEventHandler<>(); public static final CancelableEventHandler SendChat = new CancelableEventHandler<>(); - public static final CancelableEventHandler BeforeAttack = new CancelableEventHandler<>(); + public static final ParameterizedEventHandler EntityInteract = new ParameterizedEventHandler<>(); public static final ParameterizedEventHandler BeforeInstaMine = new ParameterizedEventHandler<>(); public static final SimpleEventHandler WindowResize = new SimpleEventHandler(); @@ -85,4 +83,27 @@ public class Events { public static final CancelableEventHandler PlayerReleaseUsingItem = new CancelableEventHandler<>(); public static final CancelableEventHandler PlayerTurnByMouse = new CancelableEventHandler<>(); public static final ParameterizedEventHandler PlayerInfoUpdated = new ParameterizedEventHandler<>(); + + //Attack Events ====================== + public static final CancelableEventHandler BeforeAttack = new CancelableEventHandler<>(); + public static final SimpleEventHandler AfterAttack = new SimpleEventHandler(); + public static final SimpleEventHandler BeforeStartAttack = new SimpleEventHandler(); + public static final SimpleEventHandler AfterStartAttack = new SimpleEventHandler(); + //===================================== + /** + * binds 2 functions to the beforeAttack and afterAttack event respectively. + * Tries to ensure that the order of module execution is preserved
+ * Example:
+ * if there are 2 actions bound: + *

+ * breachSwap and criticals, it should function like this: + *

+ * {@code BreachSwapBefore -> CriticalsBefore -> Vanilla code -> CriticalsAfter -> BreachSwapAfter}
+ * This ensures that the cleanup for each module always gets the same state as its initial condition + */ + + public static void AttackEventHandler(Consumer beforeAttackFunction, Runnable afterAttackFunction, int priority) { + BeforeAttack.add(beforeAttackFunction, priority); + AfterAttack.add(afterAttackFunction, -priority); + } } \ No newline at end of file diff --git a/common/java/com/zergatul/cheatutils/common/events/CancelableEventHandler.java b/common/java/com/zergatul/cheatutils/common/events/CancelableEventHandler.java index 53dd8f15..aa159e21 100644 --- a/common/java/com/zergatul/cheatutils/common/events/CancelableEventHandler.java +++ b/common/java/com/zergatul/cheatutils/common/events/CancelableEventHandler.java @@ -1,19 +1,42 @@ package com.zergatul.cheatutils.common.events; +import org.jetbrains.annotations.NotNull; + import java.util.ArrayList; +import java.util.Collections; import java.util.List; import java.util.function.Consumer; public class CancelableEventHandler { + private final List> entries = new ArrayList<>(); private final List> handlers = new ArrayList<>(); + private int counter; public void add(Consumer handler) { - handlers.add(handler); + add(handler, 0); + } + + /** + * + * @param handler Passed function that is added to the Event list + * @param priority Defaults to 0 when not passed. + * Events are executed in ascending order of their priority. + * If multiple functions have the same priority, it follows the order it was added
+ *
+ * Example execution order: + * {@code Priority 1 -> Priority 2} + */ + public void add(Consumer handler, int priority) { + entries.add(new Entry<>(handler, priority, counter++)); + Collections.sort(entries); + + handlers.clear(); + entries.stream().map(entry -> entry.handler).forEach(handlers::add); } public boolean trigger(T parameter) { - for (Consumer handler: handlers) { + for (Consumer handler : handlers) { handler.accept(parameter); if (parameter.isCanceled()) { return true; @@ -21,4 +44,16 @@ public boolean trigger(T parameter) { } return false; } + + private record Entry(Consumer handler, int priority1, int priority2) implements Comparable> { + @Override + public int compareTo(@NotNull Entry other) { + int result = Integer.compare(priority1, other.priority1); + if (result != 0) { + return result; + } else { + return Integer.compare(priority2, other.priority2); + } + } + } } \ No newline at end of file diff --git a/common/java/com/zergatul/cheatutils/common/events/ParameterizedEventHandler.java b/common/java/com/zergatul/cheatutils/common/events/ParameterizedEventHandler.java index 2a50de91..18c315af 100644 --- a/common/java/com/zergatul/cheatutils/common/events/ParameterizedEventHandler.java +++ b/common/java/com/zergatul/cheatutils/common/events/ParameterizedEventHandler.java @@ -1,20 +1,56 @@ package com.zergatul.cheatutils.common.events; +import org.jetbrains.annotations.NotNull; + import java.util.ArrayList; +import java.util.Collections; import java.util.List; import java.util.function.Consumer; public class ParameterizedEventHandler { + private final List> entries = new ArrayList<>(); private final List> handlers = new ArrayList<>(); + private int counter; public void add(Consumer handler) { - handlers.add(handler); + add(handler, 0); + } + + /** + * + * @param handler Passed function that is added to the Event list + * @param priority Defaults to 0 when not passed. + * Events are executed in ascending order of their priority. + * If multiple functions have the same priority, it follows the order it was added
+ *
+ * Example execution order: + * {@code Priority 1 -> Priority 2} + */ + public void add(Consumer handler, int priority) { + entries.add(new Entry<>(handler, priority, counter++)); + Collections.sort(entries); + + handlers.clear(); + entries.stream().map(entry -> entry.handler).forEach(handlers::add); } + public void trigger(T parameter) { - for (Consumer handler: handlers) { + for (Consumer handler : handlers) { handler.accept(parameter); } } + + private record Entry(Consumer handler, int priority1, int priority2) implements Comparable> { + @Override + public int compareTo(@NotNull Entry other) { + int result = Integer.compare(priority1, other.priority1); + if (result != 0) { + return result; + } else { + return Integer.compare(priority2, other.priority2); + } + } + } } \ No newline at end of file diff --git a/common/java/com/zergatul/cheatutils/common/events/SimpleEventHandler.java b/common/java/com/zergatul/cheatutils/common/events/SimpleEventHandler.java index 3c7d34c5..eff90ed4 100644 --- a/common/java/com/zergatul/cheatutils/common/events/SimpleEventHandler.java +++ b/common/java/com/zergatul/cheatutils/common/events/SimpleEventHandler.java @@ -16,6 +16,16 @@ public void add(Runnable handler) { add(handler, 0); } + /** + * + * @param handler Passed function that is added to the Event list + * @param priority Defaults to 0 when not passed. + * Events are executed in ascending order of their priority. + * If multiple functions have the same priority, it follows the order it was added
+ *
+ * Example execution order: + * {@code Priority 1 -> Priority 2} + */ public void add(Runnable handler, int priority) { entries.add(new Entry(handler, priority, counter++)); Collections.sort(entries); @@ -25,14 +35,14 @@ public void add(Runnable handler, int priority) { } public void trigger() { - for (Runnable handler: handlers) { + for (Runnable handler : handlers) { handler.run(); } } private record Entry(Runnable handler, int priority1, int priority2) implements Comparable { @Override - public int compareTo(@NotNull SimpleEventHandler.Entry other) { + public int compareTo(@NotNull Entry other) { int result = Integer.compare(priority1, other.priority1); if (result != 0) { return result; diff --git a/common/java/com/zergatul/cheatutils/configs/AutoStunnerConfig.java b/common/java/com/zergatul/cheatutils/configs/AutoStunnerConfig.java new file mode 100644 index 00000000..b2256505 --- /dev/null +++ b/common/java/com/zergatul/cheatutils/configs/AutoStunnerConfig.java @@ -0,0 +1,4 @@ +package com.zergatul.cheatutils.configs; + +public class AutoStunnerConfig extends ModuleConfig { +} \ No newline at end of file diff --git a/common/java/com/zergatul/cheatutils/configs/BreachSwapConfig.java b/common/java/com/zergatul/cheatutils/configs/BreachSwapConfig.java index adfd2a69..ab1467d8 100644 --- a/common/java/com/zergatul/cheatutils/configs/BreachSwapConfig.java +++ b/common/java/com/zergatul/cheatutils/configs/BreachSwapConfig.java @@ -1,16 +1,4 @@ package com.zergatul.cheatutils.configs; -public class BreachSwapConfig extends ModuleConfig implements ValidatableConfig { - public boolean useAxe; - public boolean breakShield; - - BreachSwapConfig() { - useAxe = false; - breakShield = false; - } - - @Override - public void validate() { - return; - } +public class BreachSwapConfig extends ModuleConfig { } \ No newline at end of file diff --git a/common/java/com/zergatul/cheatutils/configs/Config.java b/common/java/com/zergatul/cheatutils/configs/Config.java index 57ee00bf..780f2c83 100644 --- a/common/java/com/zergatul/cheatutils/configs/Config.java +++ b/common/java/com/zergatul/cheatutils/configs/Config.java @@ -52,6 +52,8 @@ public class Config { public BobHurtConfig bobHurtConfig = new BobHurtConfig(); public AutoAttackConfig autoAttackConfig = new AutoAttackConfig(); public BreachSwapConfig breachSwapConfig = new BreachSwapConfig(); + public SpearRangeConfig spearRangeConfig = new SpearRangeConfig(); + public AutoStunnerConfig autoStunnerConfig = new AutoStunnerConfig(); public NoWeatherConfig noWeatherConfig = new NoWeatherConfig(); public FakeWeatherConfig fakeWeatherConfig = new FakeWeatherConfig(); public ChatUtilitiesConfig chatUtilitiesConfig = new ChatUtilitiesConfig(); diff --git a/common/java/com/zergatul/cheatutils/configs/ConfigStore.java b/common/java/com/zergatul/cheatutils/configs/ConfigStore.java index 9b492351..92bf3efb 100644 --- a/common/java/com/zergatul/cheatutils/configs/ConfigStore.java +++ b/common/java/com/zergatul/cheatutils/configs/ConfigStore.java @@ -136,7 +136,6 @@ private void onConfigLoaded() { config.keyBindingsConfig.validate(); config.worldMarkersConfig.validate(); config.autoAttackConfig.validate(); - config.breachSwapConfig.validate(); config.projectilePathConfig.validate(); config.chatUtilitiesConfig.validate(); config.areaMineConfig.validate(); diff --git a/common/java/com/zergatul/cheatutils/configs/SpearRangeConfig.java b/common/java/com/zergatul/cheatutils/configs/SpearRangeConfig.java new file mode 100644 index 00000000..13c2f997 --- /dev/null +++ b/common/java/com/zergatul/cheatutils/configs/SpearRangeConfig.java @@ -0,0 +1,5 @@ +package com.zergatul.cheatutils.configs; + +public class SpearRangeConfig extends ModuleConfig { + public boolean lungeWithoutTarget; +} \ No newline at end of file diff --git a/common/java/com/zergatul/cheatutils/extensions/MultiPlayerGameModeExtension.java b/common/java/com/zergatul/cheatutils/extensions/MultiPlayerGameModeExtension.java new file mode 100644 index 00000000..e6dd4db9 --- /dev/null +++ b/common/java/com/zergatul/cheatutils/extensions/MultiPlayerGameModeExtension.java @@ -0,0 +1,17 @@ +package com.zergatul.cheatutils.extensions; + +import net.minecraft.world.entity.Entity; +import net.minecraft.world.entity.player.Player; + +public interface MultiPlayerGameModeExtension { + /** + * A vanilla implementation of the + * {@code void attack(Player player, Entity entity)} + * method.
+ * This method will NOT trigger automations / events from the regular method.
+ * intended to only be used internally to make modules that trigger on beforeAttackMethod + * Should be used in this format:
+ * {@code ((MultiPlayerGameModeExtension) mc.gameMode).attackClone(mc.player, entity);} + **/ + void attackClone_CU(Player player, Entity entity); +} diff --git a/common/java/com/zergatul/cheatutils/mixins/common/MixinLocalPlayer.java b/common/java/com/zergatul/cheatutils/mixins/common/MixinLocalPlayer.java index 624674fa..18aa4aca 100644 --- a/common/java/com/zergatul/cheatutils/mixins/common/MixinLocalPlayer.java +++ b/common/java/com/zergatul/cheatutils/mixins/common/MixinLocalPlayer.java @@ -2,7 +2,10 @@ import com.mojang.authlib.GameProfile; import com.zergatul.cheatutils.common.Events; -import com.zergatul.cheatutils.configs.*; +import com.zergatul.cheatutils.configs.ConfigStore; +import com.zergatul.cheatutils.configs.MovementHackConfig; +import com.zergatul.cheatutils.configs.ReachConfig; +import com.zergatul.cheatutils.configs.StepUpConfig; import com.zergatul.cheatutils.modules.hacks.ElytraFly; import com.zergatul.mixin.ExecuteAfterIfElseCondition; import com.zergatul.mixin.ModifyMethodReturnValue; diff --git a/common/java/com/zergatul/cheatutils/mixins/common/MixinMinecraft.java b/common/java/com/zergatul/cheatutils/mixins/common/MixinMinecraft.java index 171b5ad6..0698bdf5 100644 --- a/common/java/com/zergatul/cheatutils/mixins/common/MixinMinecraft.java +++ b/common/java/com/zergatul/cheatutils/mixins/common/MixinMinecraft.java @@ -2,11 +2,11 @@ import com.zergatul.cheatutils.common.Events; import com.zergatul.cheatutils.configs.ConfigStore; -import com.zergatul.cheatutils.modules.hacks.AirPlace; -import com.zergatul.cheatutils.modules.scripting.BlockAutomation; import com.zergatul.cheatutils.modules.automation.VillagerRoller; import com.zergatul.cheatutils.modules.esp.EntityEsp; +import com.zergatul.cheatutils.modules.hacks.AirPlace; import com.zergatul.cheatutils.modules.hacks.InvMove; +import com.zergatul.cheatutils.modules.scripting.BlockAutomation; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.screens.Screen; import net.minecraft.client.multiplayer.ClientLevel; @@ -37,6 +37,19 @@ public abstract class MixinMinecraft { @Shadow public abstract boolean isGameLoadFinished(); + + //Start Attack method, event triggers ================================== + @Inject(at = @At("HEAD"), method = "startAttack") + private void onBeforeStartAttack(CallbackInfoReturnable cir) { + Events.BeforeStartAttack.trigger(); + } + + @Inject(at = @At("RETURN"), method = "startAttack") + private void onAfterStartAttack(CallbackInfoReturnable cir) { + Events.AfterStartAttack.trigger(); + } + //======================================================================== + @Inject(at = @At("HEAD"), method = "shouldEntityAppearGlowing(Lnet/minecraft/world/entity/Entity;)Z", cancellable = true) public void onShouldEntityAppearGlowing(Entity entity, CallbackInfoReturnable info) { if (EntityEsp.instance.shouldEntityGlow(entity)) { @@ -67,6 +80,7 @@ private void onCreateTitle(CallbackInfoReturnable info) { } } + @Inject(at = @At("HEAD"), method = "tick()V") private void onBeforeTick(CallbackInfo info) { if (this.isGameLoadFinished()) { diff --git a/common/java/com/zergatul/cheatutils/mixins/common/MixinMultiPlayerGameMode.java b/common/java/com/zergatul/cheatutils/mixins/common/MixinMultiPlayerGameMode.java index d52bad98..c7cf703f 100644 --- a/common/java/com/zergatul/cheatutils/mixins/common/MixinMultiPlayerGameMode.java +++ b/common/java/com/zergatul/cheatutils/mixins/common/MixinMultiPlayerGameMode.java @@ -5,19 +5,24 @@ import com.zergatul.cheatutils.common.events.PlayerReleaseUsingItemEvent; import com.zergatul.cheatutils.configs.ConfigStore; import com.zergatul.cheatutils.configs.FastBreakConfig; +import com.zergatul.cheatutils.extensions.MultiPlayerGameModeExtension; +import net.minecraft.client.multiplayer.ClientPacketListener; import net.minecraft.client.multiplayer.MultiPlayerGameMode; import net.minecraft.client.player.LocalPlayer; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; +import net.minecraft.network.protocol.game.ServerboundInteractPacket; import net.minecraft.world.InteractionHand; import net.minecraft.world.InteractionResult; import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.player.Player; +import net.minecraft.world.level.GameType; import net.minecraft.world.level.block.BedBlock; import net.minecraft.world.level.block.Blocks; import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.phys.BlockHitResult; import net.minecraft.world.phys.EntityHitResult; +import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.injection.At; @@ -26,11 +31,43 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; @Mixin(MultiPlayerGameMode.class) -public abstract class MixinMultiPlayerGameMode { +public abstract class MixinMultiPlayerGameMode implements MultiPlayerGameModeExtension { @Shadow private int destroyDelay; + + @Shadow + private GameType localPlayerMode; + + @Shadow + protected abstract void ensureHasSentCarriedItem(); + + @Shadow + @Final + private ClientPacketListener connection; + + /** + * A vanilla implementation of the + * {@code void attack(Player player, Entity entity)} + * method.
+ * This method will NOT trigger automations / events from the regular method.
+ * intended to only be used internally to make modules that trigger on beforeAttackMethod.
+ * Should be used in this format:
+ * {@code ((MultiPlayerGameModeExtension) mc.gameMode).attackClone(mc.player, entity);} + *

+ * If you see this comment, you are not using the correct syntax. Make sure to cast the call first! + **/ + public void attackClone_CU(Player player, Entity entity) { + this.ensureHasSentCarriedItem(); + + this.connection.send(ServerboundInteractPacket.createAttackPacket(entity, player.isShiftKeyDown())); + if (this.localPlayerMode != GameType.SPECTATOR) { + player.attack(entity); + player.resetAttackStrengthTicker(); + } + } + @Inject(at = @At("HEAD"), method = "releaseUsingItem(Lnet/minecraft/world/entity/player/Player;)V", cancellable = true) private void onReleaseUsingItem(Player player, CallbackInfo info) { if (Events.PlayerReleaseUsingItem.trigger(new PlayerReleaseUsingItemEvent())) { @@ -76,5 +113,10 @@ private void onAttack(Player player, Entity entity, CallbackInfo ci) { ci.cancel(); } } + + @Inject(at = @At("TAIL"), method = "attack", cancellable = false) + private void afterAttack(Player player, Entity entity, CallbackInfo ci) { + Events.AfterAttack.trigger(); + } } diff --git a/common/java/com/zergatul/cheatutils/mixins/common/accessors/MinecraftAccessor.java b/common/java/com/zergatul/cheatutils/mixins/common/accessors/MinecraftAccessor.java index 85d6882a..601252b3 100644 --- a/common/java/com/zergatul/cheatutils/mixins/common/accessors/MinecraftAccessor.java +++ b/common/java/com/zergatul/cheatutils/mixins/common/accessors/MinecraftAccessor.java @@ -11,6 +11,15 @@ public interface MinecraftAccessor { @Invoker("startUseItem") void startUseItem_CU(); + /** + * This method will trigger automations / events from the regular method.
+ * intended to only be used internally to make modules that trigger on beforeAttackStartMethod.
+ * Should be used in this format:
+ * {@code ((MinecraftExtension) mc).runStartAttack_CU();} + **/ + @Invoker("startAttack") + boolean startAttack_CU(); + @Accessor("clientTickCount") long getClientTickCount_CU(); } \ No newline at end of file diff --git a/common/java/com/zergatul/cheatutils/modules/Modules.java b/common/java/com/zergatul/cheatutils/modules/Modules.java index 80766cbb..fa14c4c6 100644 --- a/common/java/com/zergatul/cheatutils/modules/Modules.java +++ b/common/java/com/zergatul/cheatutils/modules/Modules.java @@ -9,8 +9,12 @@ import com.zergatul.cheatutils.modules.automation.*; import com.zergatul.cheatutils.modules.esp.*; import com.zergatul.cheatutils.modules.hacks.*; -import com.zergatul.cheatutils.modules.scripting.*; -import com.zergatul.cheatutils.modules.utilities.*; +import com.zergatul.cheatutils.modules.scripting.BlockAutomation; +import com.zergatul.cheatutils.modules.scripting.Containers; +import com.zergatul.cheatutils.modules.scripting.Exec; +import com.zergatul.cheatutils.modules.scripting.StatusOverlay; +import com.zergatul.cheatutils.modules.utilities.LockInputs; +import com.zergatul.cheatutils.modules.utilities.RenderUtilities; import com.zergatul.cheatutils.modules.visuals.*; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; @@ -20,6 +24,12 @@ public class Modules { private static final Logger LOGGER = LogManager.getLogger(Modules.class); public static void register() { + + //Order dependent modules -> legacy method, use Event.event.add(function, priority) for new modules, use the priority value instead + //========================== + + //=========================== + register(FakeRotation.instance); register(BlockEventsProcessor.instance); register(NetworkPacketsController.instance); @@ -62,7 +72,7 @@ public static void register() { register(ArmorOverlay.instance); register(Fog.instance); register(AutoAttack.instance); - register(BreachSwap.instance); + register(Exec.instance); register(VillagerRoller.instance); register(AutoHotbar.instance); @@ -79,18 +89,23 @@ public static void register() { register(AutoTool.instance); register(AirPlace.instance); - // should be after everything so "Don't Attack on Item Use" can work better - register(KillAura.instance); register(TickEndExecutor.instance); // new order independent modules + //========================================== register(AfterPlayerAiStepExecutor.instance); register(AfterSendPlayerPosExecutor.instance); + register(KillAura.instance); FontBackendHolders.add(StatusOverlay.instance); FontBackendHolders.add(EntityTitle.instance); FontBackendHolders.add(WorldMarkers.instance); + + register(SpearRange.instance); + register(AutoStunner.instance); + register(BreachSwap.instance); + //=========================================== } public static void registerKeyBindings() { diff --git a/common/java/com/zergatul/cheatutils/modules/automation/AutoAttack.java b/common/java/com/zergatul/cheatutils/modules/automation/AutoAttack.java index 31355287..ad485e1a 100644 --- a/common/java/com/zergatul/cheatutils/modules/automation/AutoAttack.java +++ b/common/java/com/zergatul/cheatutils/modules/automation/AutoAttack.java @@ -3,11 +3,9 @@ import com.zergatul.cheatutils.common.Events; import com.zergatul.cheatutils.configs.AutoAttackConfig; import com.zergatul.cheatutils.configs.ConfigStore; +import com.zergatul.cheatutils.mixins.common.accessors.MinecraftAccessor; import com.zergatul.cheatutils.modules.Module; import net.minecraft.client.Minecraft; -import net.minecraft.world.InteractionHand; -import net.minecraft.world.entity.Entity; -import net.minecraft.world.phys.EntityHitResult; import net.minecraft.world.phys.HitResult; public class AutoAttack implements Module { @@ -55,9 +53,7 @@ private void onClientTickEnd() { nextExtraTicks = Integer.MIN_VALUE; - Entity entity = ((EntityHitResult) mc.hitResult).getEntity(); - mc.gameMode.attack(mc.player, entity); - mc.player.swing(InteractionHand.MAIN_HAND); + ((MinecraftAccessor) mc).startAttack_CU(); } private void calculateNextExtraTicksIfRequired(AutoAttackConfig config) { diff --git a/common/java/com/zergatul/cheatutils/modules/automation/AutoStunner.java b/common/java/com/zergatul/cheatutils/modules/automation/AutoStunner.java new file mode 100644 index 00000000..b3b6d99e --- /dev/null +++ b/common/java/com/zergatul/cheatutils/modules/automation/AutoStunner.java @@ -0,0 +1,75 @@ +package com.zergatul.cheatutils.modules.automation; + +import com.zergatul.cheatutils.common.Events; +import com.zergatul.cheatutils.common.events.BeforeAttackEvent; +import com.zergatul.cheatutils.configs.ConfigStore; +import com.zergatul.cheatutils.extensions.MultiPlayerGameModeExtension; +import com.zergatul.cheatutils.modules.Module; +import net.minecraft.client.Minecraft; +import net.minecraft.tags.ItemTags; +import net.minecraft.world.entity.Entity; +import net.minecraft.world.entity.LivingEntity; +import net.minecraft.world.entity.player.Inventory; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.phys.EntityHitResult; +import net.minecraft.world.phys.HitResult; +import net.minecraft.world.phys.Vec3; + +public class AutoStunner implements Module { + public static final AutoStunner instance = new AutoStunner(); + private final Minecraft mc = Minecraft.getInstance(); + + AutoStunner() { + Events.BeforeAttack.add(this::onBeforeAttack, 1); + } + + private void onBeforeAttack(BeforeAttackEvent event) { + if (!ConfigStore.instance.getConfig().autoStunnerConfig.enabled) return; + + if (mc.player == null) return; + + if (mc.hitResult == null) return; + + if (mc.hitResult.getType() != HitResult.Type.ENTITY) return; + + Entity entity = ((EntityHitResult) mc.hitResult).getEntity(); + if (!isUsingShield(entity)) return; + + Inventory inventory = mc.player.getInventory(); + + int axe = -1; + for (int i = 0; i < 9; i++) { + ItemStack item = inventory.getItem(i); + if (item.getTags().anyMatch(tag -> tag == ItemTags.AXES)) { + axe = i; + break; + } + } + if (axe == -1) return; + + int prevSelectedSlot = inventory.getSelectedSlot(); + inventory.setSelectedSlot(axe); + + assert mc.gameMode != null; + ((MultiPlayerGameModeExtension) mc.gameMode).attackClone_CU(mc.player, entity); + + inventory.setSelectedSlot(prevSelectedSlot); + } + + + private boolean isUsingShield(Entity entity) { + if (entity instanceof LivingEntity living) { + if (living.isBlocking()) { + // Calculate if target is looking at us + // Shields only block a 180 degree slice of a cylinder + Vec3 shield = living.calculateViewVector(0.0F, living.getYHeadRot()); + assert mc.player != null; + Vec3 player = mc.player.position().subtract(living.position()); + player = (new Vec3(player.x, 0D, player.z)); + double dotProduct = player.dot(shield); + return dotProduct >= 0; + } + } + return false; + } +} diff --git a/common/java/com/zergatul/cheatutils/modules/automation/BreachSwap.java b/common/java/com/zergatul/cheatutils/modules/automation/BreachSwap.java index 7877c13e..98c401ed 100644 --- a/common/java/com/zergatul/cheatutils/modules/automation/BreachSwap.java +++ b/common/java/com/zergatul/cheatutils/modules/automation/BreachSwap.java @@ -2,140 +2,68 @@ import com.zergatul.cheatutils.common.Events; import com.zergatul.cheatutils.common.events.BeforeAttackEvent; -import com.zergatul.cheatutils.configs.BreachSwapConfig; import com.zergatul.cheatutils.configs.ConfigStore; import com.zergatul.cheatutils.modules.Module; -import com.zergatul.cheatutils.modules.hacks.AutoCriticals; import net.minecraft.client.Minecraft; -import net.minecraft.tags.ItemTags; -import net.minecraft.world.InteractionHand; -import net.minecraft.world.entity.Entity; -import net.minecraft.world.entity.LivingEntity; import net.minecraft.world.entity.player.Inventory; import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.enchantment.EnchantmentEffectComponents; -import net.minecraft.world.phys.EntityHitResult; import net.minecraft.world.phys.HitResult; -import net.minecraft.world.phys.Vec3; public class BreachSwap implements Module { public static final BreachSwap instance = new BreachSwap(); private final Minecraft mc = Minecraft.getInstance(); + private Inventory inventory; + + private int prevSelectedSlot = -1; private BreachSwap() { - Events.BeforeAttack.add(this::onBeforeAttack); - handling = false; + Events.AttackEventHandler(this::onBeforeAttack, this::onAfterAttack, 2); } + private void onBeforeAttack(BeforeAttackEvent event) { - private static boolean handling; - - public void onBeforeAttack(BeforeAttackEvent event) { - if (handling) { + if (!ConfigStore.instance.getConfig().breachSwapConfig.enabled) { return; } - BreachSwapConfig config = ConfigStore.instance.getConfig().breachSwapConfig; - if (config.enabled) { - if (instance.attack(config.useAxe, config.breakShield)) { - event.cancel(); - } - } - } - - public boolean attack(boolean useAxe, boolean breakShield) { - handling = true; - boolean returnVal = instance.run(useAxe, breakShield); - handling = false; - return returnVal; - } - - private boolean run(boolean useAxe, boolean breakShield) { + prevSelectedSlot = -1; if (mc.player == null) { - return false; + return; } if (mc.hitResult == null) { - return false; + return; } if (mc.hitResult.getType() != HitResult.Type.ENTITY) { - return false; + return; } - Entity entity = ((EntityHitResult) mc.hitResult).getEntity(); - double reach = mc.player.entityInteractionRange(); - if (reach * reach < mc.player.getEyePosition().distanceToSqr(mc.hitResult.getLocation())) { - return false; - } - //Find position of axe, sword and mace - //Should only run when inventory is updated ideally - int axe = -1; - int sword = -1; int mace = -1; - int weapon; - Inventory inventory = mc.player.getInventory(); + inventory = mc.player.getInventory(); + for (int i = 0; i < 9; i++) { ItemStack item = inventory.getItem(i); - if (item.getTags().anyMatch(tag -> tag == ItemTags.SWORDS)) sword = i; - else if (item.getTags().anyMatch(tag -> tag == ItemTags.AXES)) axe = i; - else if (item.getEnchantments().keySet().stream().anyMatch(enchantment -> + + if (item.getEnchantments().keySet().stream().anyMatch(enchantment -> enchantment.value().effects().keySet().contains(EnchantmentEffectComponents.ARMOR_EFFECTIVENESS))) mace = i; } if (mace == -1) { - return false; - } - - if (axe == -1 && sword == -1) { - return false; - } - - if (useAxe) {//Prefer Axe to sword - if (axe != -1) { - weapon = axe; - } else { - weapon = sword; - } - } else {//Prefer sword to axe - if (sword != -1) { - weapon = sword; - } else { - weapon = axe; - } - } - - if (breakShield) { - boolean isUsingShield = false; - if (entity instanceof LivingEntity living) { - if (living.isBlocking()) { - // Calculate if target is looking at us - // Shields only block a 180 degree slice of a cylinder - Vec3 shield = living.calculateViewVector(0.0F, living.getYHeadRot()); - Vec3 player = mc.player.position().subtract(living.position()); - player = (new Vec3(player.x, 0D, player.z)).normalize(); - double dotProduct = player.dot(shield); - isUsingShield = dotProduct >= 0; - } - } - - - if (isUsingShield && axe != -1) { - AutoCriticals.instance.skipAttack(); - inventory.setSelectedSlot(axe); - mc.gameMode.attack(mc.player, entity); - mc.player.swing(InteractionHand.MAIN_HAND); - - } + return; } - + prevSelectedSlot = inventory.getSelectedSlot(); inventory.setSelectedSlot(mace); - mc.gameMode.attack(mc.player, entity); - mc.player.swing(InteractionHand.MAIN_HAND); - inventory.setSelectedSlot(weapon); - return true; + } + private void onAfterAttack() { + if (!ConfigStore.instance.getConfig().breachSwapConfig.enabled) return; + if (prevSelectedSlot == -1) return; + inventory.setSelectedSlot(prevSelectedSlot); } + + } \ No newline at end of file diff --git a/common/java/com/zergatul/cheatutils/modules/automation/SpearRange.java b/common/java/com/zergatul/cheatutils/modules/automation/SpearRange.java new file mode 100644 index 00000000..a8819240 --- /dev/null +++ b/common/java/com/zergatul/cheatutils/modules/automation/SpearRange.java @@ -0,0 +1,122 @@ +package com.zergatul.cheatutils.modules.automation; + +import com.zergatul.cheatutils.common.Events; +import com.zergatul.cheatutils.configs.ConfigStore; +import com.zergatul.cheatutils.modules.Module; +import net.minecraft.client.Minecraft; +import net.minecraft.world.entity.player.Inventory; +import net.minecraft.world.entity.projectile.ProjectileUtil; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.level.ClipContext; +import net.minecraft.world.phys.*; + +import static net.minecraft.core.component.DataComponents.ATTACK_RANGE; + +public class SpearRange implements Module { + public static final SpearRange instance = new SpearRange(); + private final Minecraft mc = Minecraft.getInstance(); + private int prevSelectedSlot = -1; + + + private SpearRange() { + Events.BeforeStartAttack.add(this::onBeforeStartAttack, 0); + Events.AfterStartAttack.add(this::onAfterStartAttack, 0); + } + + public void onBeforeStartAttack() { + if (!ConfigStore.instance.getConfig().spearRangeConfig.enabled) return; + prevSelectedSlot = -1; + if (mc.player == null) return; + if (mc.player.isSpectator()) return; + if (mc.hitResult == null) return; + if (mc.hitResult.getType() != HitResult.Type.MISS) return; + + Inventory inventory = mc.player.getInventory(); + int spear = spearPos(inventory); + if (spear == -1) return; + + //Check for valid target before executing + if (!ConfigStore.instance.getConfig().spearRangeConfig.lungeWithoutTarget) { + if (!hasValidTarget(inventory.getItem(spear))) { + return; + } + } + + prevSelectedSlot = inventory.getSelectedSlot(); + inventory.setSelectedSlot(spear); + } + + public void onAfterStartAttack() { + if (!ConfigStore.instance.getConfig().spearRangeConfig.enabled) return; + if (mc.player == null) return; + if (prevSelectedSlot == -1) return; + mc.player.getInventory().setSelectedSlot(prevSelectedSlot); + prevSelectedSlot = -1; + } + + /** + * + * @param inventory player inventory + * @return returns position of spear in the hotbar. If no spear is present, returns -1 + */ + private int spearPos(Inventory inventory) { + if (inventory.getSelectedItem().getComponents().has(ATTACK_RANGE)) { + return -1; + } + int spear = -1; + for (int i = 0; i < 9; i++) { + ItemStack item = inventory.getItem(i); + if (item.getComponents().has(ATTACK_RANGE)) { + spear = i; + break; + } + } + return spear; + } + + private boolean hasValidTarget(ItemStack spear) { + assert mc.level != null; + assert mc.player != null; + double maxDist = spear.getComponents().get(ATTACK_RANGE).effectiveMaxRange(mc.player); + double maxDistSqr = maxDist * maxDist; + + Vec3 origin = mc.player.getEyePosition(); + Vec3 point = mc.player.getLookAngle().scale(maxDist).add(origin); + + ClipContext levelClip = new ClipContext( + origin, + point, + ClipContext.Block.COLLIDER, + ClipContext.Fluid.NONE, + mc.player + ); + + BlockHitResult blockHit = mc.level.clip(levelClip); + + if (blockHit.getType() != HitResult.Type.MISS) { + maxDistSqr = blockHit.getLocation().distanceToSqr(origin);//Limit max range after + } //to compare with entity hit test + + AABB searchBox = mc.player.getBoundingBox().expandTowards(point.subtract(origin)).inflate(1); + + EntityHitResult entityHit = ProjectileUtil.getEntityHitResult( + mc.player, + origin, + point, + searchBox, + e -> e != mc.player && e != mc.player.getVehicle(), + maxDistSqr + ); + + if (entityHit == null) { + return false; + } + + if (entityHit.getType() != EntityHitResult.Type.MISS) { + //Only accept point if block collision is further than entity collision + return true; + } + return false; + } + +} diff --git a/common/java/com/zergatul/cheatutils/modules/hacks/AutoCriticals.java b/common/java/com/zergatul/cheatutils/modules/hacks/AutoCriticals.java index f5d03acc..53958a27 100644 --- a/common/java/com/zergatul/cheatutils/modules/hacks/AutoCriticals.java +++ b/common/java/com/zergatul/cheatutils/modules/hacks/AutoCriticals.java @@ -15,27 +15,14 @@ public class AutoCriticals { public static final AutoCriticals instance = new AutoCriticals(); private final Minecraft mc = Minecraft.getInstance(); - private boolean skip; - - public void skipAttack() { - skip = true; - } - private AutoCriticals() { - skip = false; - Events.BeforeAttack.add(this::onBeforeAttack); + Events.BeforeAttack.add(this::onBeforeAttack, -1); } private void onBeforeAttack(BeforeAttackEvent event) { AutoCriticalsConfig config = ConfigStore.instance.getConfig().autoCriticalsConfig; - //This needs to come before enable check, else it will queue this for future situation incorrectly - if (skip) { - skip = false; - return; - } - if (config.enabled) { if (mc.level == null) { return; @@ -47,14 +34,17 @@ private void onBeforeAttack(BeforeAttackEvent event) { if (config.onlyOnGround && !mc.player.onGround()) { return; } - - if (mc.player.isSprinting()) {// This will not critical anyways, so don't interfere - return; - } - - if (mc.player.fallDistance != 0 || mc.player.isFallFlying()) {//If player already falling - return; - } + // Hard Conditions not met, cannot do anything about it + // Refer to `Player.class` -> boolean canCriticalAttack(Entity entity) + // Refer to `Player.class` -> void attack(Entity entity) + if (!((mc.player.getAttackStrengthScale(0.5F) > 0.9F) && + (!mc.player.onClimbable() + && !mc.player.isInWater() && !mc.player.isMobilityRestricted() && !mc.player.isPassenger() + && mc.player.getLivingEntity().isAlive() && !mc.player.isSprinting())) + ) return; + + // Soft Conditions we can cheat to validate, do nothing if its already valid case + if (!(mc.player.fallDistance > 0 && !mc.player.onGround())) return; Vec3 PrevPos = mc.player.position(); diff --git a/common/java/com/zergatul/cheatutils/modules/hacks/KillAura.java b/common/java/com/zergatul/cheatutils/modules/hacks/KillAura.java index ed04bece..6e286bec 100644 --- a/common/java/com/zergatul/cheatutils/modules/hacks/KillAura.java +++ b/common/java/com/zergatul/cheatutils/modules/hacks/KillAura.java @@ -35,11 +35,14 @@ public class KillAura implements Module { private KillAuraFunction script; private KillAura() { - Events.AfterPlayerAiStep.add(this::onAfterPlayerAiStep); - Events.AfterSendPlayerPos.add(this::onAfterSendPlayerPos); - Events.ClientTickStart.add(this::onClientTickStart); - Events.ClientPlayerLoggingIn.add(this::onPlayerLoggingIn); - Events.DimensionChange.add(this::onDimensionChange); + + // should be after everything so "Don't Attack on Item Use" can work better + int priority = 1000; + Events.AfterPlayerAiStep.add(this::onAfterPlayerAiStep, priority); + Events.AfterSendPlayerPos.add(this::onAfterSendPlayerPos, priority); + Events.ClientTickStart.add(this::onClientTickStart, priority); + Events.ClientPlayerLoggingIn.add(this::onPlayerLoggingIn, priority); + Events.DimensionChange.add(this::onDimensionChange, priority); } public void onEnabled() { diff --git a/common/java/com/zergatul/cheatutils/scripting/Root.java b/common/java/com/zergatul/cheatutils/scripting/Root.java index 951269fe..f63936bc 100644 --- a/common/java/com/zergatul/cheatutils/scripting/Root.java +++ b/common/java/com/zergatul/cheatutils/scripting/Root.java @@ -16,6 +16,9 @@ public class Root { public static AutoHotbarApi autoHotbar = new AutoHotbarApi(); public static AutoToolApi autoTool = new AutoToolApi(); public static AutoAttackApi autoAttack = new AutoAttackApi(); + public static AutoStunnerApi autoStunner = new AutoStunnerApi(); + public static BreachSwapApi breachSwap = new BreachSwapApi(); + public static SpearRangeApi spearRange = new SpearRangeApi(); // ESP public static BlocksApi blocks = new BlocksApi(); @@ -43,7 +46,6 @@ public class Root { public static AreaMineApi areaMine = new AreaMineApi(); public static StepUpApi stepUp = new StepUpApi(); public static AimAssistApi aimAssist = new AimAssistApi(); - public static BreachSwapApi breachSwap = new BreachSwapApi(); public static AirPlaceApi airPlace = new AirPlaceApi(); // visuals diff --git a/common/java/com/zergatul/cheatutils/scripting/modules/AutoStunnerApi.java b/common/java/com/zergatul/cheatutils/scripting/modules/AutoStunnerApi.java new file mode 100644 index 00000000..6054eab5 --- /dev/null +++ b/common/java/com/zergatul/cheatutils/scripting/modules/AutoStunnerApi.java @@ -0,0 +1,12 @@ +package com.zergatul.cheatutils.scripting.modules; + +import com.zergatul.cheatutils.configs.AutoStunnerConfig; +import com.zergatul.cheatutils.configs.ConfigStore; + +public class AutoStunnerApi extends ModuleApi { + + @Override + protected AutoStunnerConfig getConfig() { + return ConfigStore.instance.getConfig().autoStunnerConfig; + } +} \ No newline at end of file diff --git a/common/java/com/zergatul/cheatutils/scripting/modules/BreachSwapApi.java b/common/java/com/zergatul/cheatutils/scripting/modules/BreachSwapApi.java index 64b2b0fa..2282e9c3 100644 --- a/common/java/com/zergatul/cheatutils/scripting/modules/BreachSwapApi.java +++ b/common/java/com/zergatul/cheatutils/scripting/modules/BreachSwapApi.java @@ -7,10 +7,6 @@ import com.zergatul.cheatutils.scripting.ApiVisibility; public class BreachSwapApi extends ModuleApi { - @ApiVisibility(ApiType.ACTION) - public void attack(boolean useAxe, boolean breakShield) { - BreachSwap.instance.attack(useAxe, breakShield); - } @Override protected BreachSwapConfig getConfig() { diff --git a/common/java/com/zergatul/cheatutils/scripting/modules/PlayerApi.java b/common/java/com/zergatul/cheatutils/scripting/modules/PlayerApi.java index f3c12284..b47f2523 100644 --- a/common/java/com/zergatul/cheatutils/scripting/modules/PlayerApi.java +++ b/common/java/com/zergatul/cheatutils/scripting/modules/PlayerApi.java @@ -4,17 +4,12 @@ import com.zergatul.cheatutils.controllers.SpeedCounterController; import com.zergatul.cheatutils.mixins.common.accessors.LocalPlayerAccessor; import com.zergatul.cheatutils.mixins.common.accessors.MultiPlayerGameModeAccessor; -import com.zergatul.cheatutils.scripting.ApiVisibility; import com.zergatul.cheatutils.scripting.ApiType; +import com.zergatul.cheatutils.scripting.ApiVisibility; +import com.zergatul.cheatutils.scripting.types.BlockPosWrapper; import com.zergatul.cheatutils.scripting.types.HitResultWrapper; import com.zergatul.cheatutils.scripting.types.Position3d; -import com.zergatul.cheatutils.scripting.types.BlockPosWrapper; -import com.zergatul.cheatutils.utils.InputBuilder; -import com.zergatul.cheatutils.utils.NearbyBlockEnumerator; -import com.zergatul.cheatutils.utils.RayCast; -import com.zergatul.cheatutils.utils.Rotation; -import com.zergatul.cheatutils.utils.RotationUtils; -import com.zergatul.cheatutils.scripting.modules.GameApi; +import com.zergatul.cheatutils.utils.*; import com.zergatul.scripting.MethodDescription; import net.minecraft.client.Minecraft; import net.minecraft.client.player.LocalPlayer; @@ -36,15 +31,12 @@ import net.minecraft.world.level.Level; import net.minecraft.world.level.biome.Biome; import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.level.levelgen.structure.BoundingBox; import net.minecraft.world.phys.BlockHitResult; import net.minecraft.world.phys.EntityHitResult; import net.minecraft.world.phys.HitResult; import net.minecraft.world.phys.Vec3; -import net.minecraft.world.phys.AABB; import java.util.Comparator; -import java.util.List; import java.util.Locale; import java.util.stream.Stream; import java.util.stream.StreamSupport; diff --git a/common/java/com/zergatul/cheatutils/scripting/modules/SpearRangeApi.java b/common/java/com/zergatul/cheatutils/scripting/modules/SpearRangeApi.java new file mode 100644 index 00000000..34bdffbf --- /dev/null +++ b/common/java/com/zergatul/cheatutils/scripting/modules/SpearRangeApi.java @@ -0,0 +1,13 @@ +package com.zergatul.cheatutils.scripting.modules; + +import com.zergatul.cheatutils.configs.ConfigStore; +import com.zergatul.cheatutils.configs.SpearRangeConfig; + +public class SpearRangeApi extends ModuleApi { + + + @Override + protected SpearRangeConfig getConfig() { + return ConfigStore.instance.getConfig().spearRangeConfig; + } +} \ No newline at end of file diff --git a/common/java/com/zergatul/cheatutils/utils/RayCast.java b/common/java/com/zergatul/cheatutils/utils/RayCast.java index 10471b2b..cfb02ac2 100644 --- a/common/java/com/zergatul/cheatutils/utils/RayCast.java +++ b/common/java/com/zergatul/cheatutils/utils/RayCast.java @@ -119,18 +119,18 @@ private static boolean isValidPosition(Entity target, double range, Vec3 origin, maxDistSqr = blockHit.getLocation().distanceToSqr(origin);//Limit max range after } //to compare with entity hit test - Vec3 end = point.subtract(origin).normalize().scale(range).add(origin);//Calculate a ray in that direction, with length range + Vec3 end = point.subtract(origin).normalize().scale(range);//Calculate a ray in that direction, with length range //This is required, otherwise point remains on entity surface and never contains the target entity in searchBox - AABB searchBox = new AABB(origin, end); + AABB searchBox = mc.player.getBoundingBox().expandTowards(end).inflate(1); EntityHitResult entityHit = ProjectileUtil.getEntityHitResult( mc.player, origin, - end, + end.add(origin), searchBox, e -> e != mc.player && e != mc.player.getVehicle(), - range + maxDistSqr ); if (entityHit == null) { @@ -138,10 +138,7 @@ private static boolean isValidPosition(Entity target, double range, Vec3 origin, } if (entityHit.getEntity() == target) { - //Only accept point if block collision is further then entity collision - if (entityHit.getLocation().distanceToSqr(origin) <= maxDistSqr) { - return true; - } + return true; } return false; } diff --git a/common/java/com/zergatul/cheatutils/webui/ApiHandler.java b/common/java/com/zergatul/cheatutils/webui/ApiHandler.java index 451aacdc..7832e984 100644 --- a/common/java/com/zergatul/cheatutils/webui/ApiHandler.java +++ b/common/java/com/zergatul/cheatutils/webui/ApiHandler.java @@ -700,6 +700,18 @@ protected void setConfig(BreachSwapConfig config) { ConfigStore.instance.getConfig().breachSwapConfig = config; } }); + apis.add(new SimpleConfigApi<>("auto-stunner", AutoStunnerConfig.class) { + @Override + protected AutoStunnerConfig getConfig() { + return ConfigStore.instance.getConfig().autoStunnerConfig; + } + + @Override + protected void setConfig(AutoStunnerConfig config) { + ConfigStore.instance.getConfig().autoStunnerConfig = config; + } + }); + apis.add(new SimpleConfigApi<>("no-weather", NoWeatherConfig.class) { @Override protected NoWeatherConfig getConfig() { @@ -712,6 +724,18 @@ protected void setConfig(NoWeatherConfig config) { } }); + apis.add(new SimpleConfigApi<>("spear-range", SpearRangeConfig.class) { + @Override + protected SpearRangeConfig getConfig() { + return ConfigStore.instance.getConfig().spearRangeConfig; + } + + @Override + protected void setConfig(SpearRangeConfig config) { + ConfigStore.instance.getConfig().spearRangeConfig = config; + } + }); + apis.add(new SimpleConfigApi<>("fake-weather", FakeWeatherConfig.class) { @Override protected FakeWeatherConfig getConfig() { diff --git a/common/resources/web/Web Examples.md b/common/resources/web/Web Examples.md new file mode 100644 index 00000000..cdfb42d8 --- /dev/null +++ b/common/resources/web/Web Examples.md @@ -0,0 +1,27 @@ +# Website components + +## Explanation:- + +- `v-model="config.VariableName"` This defines the variable to be modified. + +- `@change="update()"` This defines the function to be run on value change + +### [Website uses Vue components](https://vuejs.org/guide/introduction.html) + +## Component Examples:- + +### Switch + +```html +Enabled +``` + +#### boolean output + +### Text Box + +```html + +``` + +#### Parses output to the variable type diff --git a/common/resources/web/components/automation/AutoStunner.html b/common/resources/web/components/automation/AutoStunner.html new file mode 100644 index 00000000..c81c768b --- /dev/null +++ b/common/resources/web/components/automation/AutoStunner.html @@ -0,0 +1,12 @@ +

+
+ Automatically disables shield if you have an axe available and the target is holding a shield that would block your attack
+ Module accounts for target look direction +
+ +
+
+ Enabled +
+
+
\ No newline at end of file diff --git a/common/resources/web/components/automation/AutoStunner.js b/common/resources/web/components/automation/AutoStunner.js new file mode 100644 index 00000000..d70b5490 --- /dev/null +++ b/common/resources/web/components/automation/AutoStunner.js @@ -0,0 +1,5 @@ +import { createSimpleComponent } from '/components/SimpleModule.js'; + +export function createComponent(template) { + return createSimpleComponent('/api/auto-stunner', template); +} \ No newline at end of file diff --git a/common/resources/web/components/automation/BreachSwap.html b/common/resources/web/components/automation/BreachSwap.html index 7d770e0a..5d7496ba 100644 --- a/common/resources/web/components/automation/BreachSwap.html +++ b/common/resources/web/components/automation/BreachSwap.html @@ -1,39 +1,10 @@
- Breach Swap makes it so that attacking swaps sword and mace to perform a Breach Swap attack, - Penetrating armor with breach while using base damage and cooldown of a sword or axe. + Looks for a breach mace in your hotbar, if you have a breach mace, it will perform an attribute swap with your currently held item and the breach mace
Enabled
-
- - Weapon Options - -
- Prefer Axe - Break shield automatically - -
-
-
- Use Axe option tells module to prefer using axe or sword. - Module always chooses valid weapon closest to the right of the taskbar.
- If the preferred weapon is not in hotbar, module uses the other weapon if available.
- Example: When "Prefer Axe" option is true but you do not have an axe in the hotbar, the module will - automatically use a sword instead.
- If no weapons are present or no mace (with breach) is present, module does nothing
- Break Shield option allows module to automatically break a shield if your attack would be blocked by its - shield. - This allows you to do damage while falling, even if target uses their shield. -
-
- Module can also be run from code. Here is a simple example to use with keybinds:
- -
-
\ No newline at end of file diff --git a/common/resources/web/components/automation/BreachSwap.js b/common/resources/web/components/automation/BreachSwap.js index fd119490..6e131a56 100644 --- a/common/resources/web/components/automation/BreachSwap.js +++ b/common/resources/web/components/automation/BreachSwap.js @@ -1,7 +1,5 @@ import { createSimpleComponent } from '/components/SimpleModule.js' export function createComponent(template) { - return createSimpleComponent('/api/breach-swap', template, { - components: ['CodeBlock'] - }); + return createSimpleComponent('/api/breach-swap', template); } \ No newline at end of file diff --git a/common/resources/web/components/automation/SpearRange.html b/common/resources/web/components/automation/SpearRange.html new file mode 100644 index 00000000..44bcf7a1 --- /dev/null +++ b/common/resources/web/components/automation/SpearRange.html @@ -0,0 +1,18 @@ +
+
+ Uses the spear to extend your reach with weapons. +
+
+
+ Enabled
+
+
+ + Lunge Without Target + +
+ When Enabled, allows you to use the spear to lunge without having a target. This allows bypassing the cooldown of the spear. +
+
+
+
\ No newline at end of file diff --git a/common/resources/web/components/automation/SpearRange.js b/common/resources/web/components/automation/SpearRange.js new file mode 100644 index 00000000..f11b4955 --- /dev/null +++ b/common/resources/web/components/automation/SpearRange.js @@ -0,0 +1,5 @@ +import { createSimpleComponent } from '/components/SimpleModule.js'; + +export function createComponent(template) { + return createSimpleComponent('/api/spear-range', template); +} \ No newline at end of file diff --git a/common/resources/web/modules.js b/common/resources/web/modules.js index 2320cd63..a1e982bc 100644 --- a/common/resources/web/modules.js +++ b/common/resources/web/modules.js @@ -17,7 +17,7 @@ const module = (params) => { params.componentRef = getComponent(`${params.group}/${params.component}`); modules[params.group][params.component] = params; }; - +//Automation Modules ================= module({ group: 'automation', name: 'Auto Disconnect', @@ -116,6 +116,23 @@ module({ path: 'auto-tool', tags: ['auto', 'tool'] }); +module({ + group: 'automation', + name: 'Spear Range', + component: 'SpearRange', + path: 'spear-range', + tags: ['spear', 'reach', 'range'] +}); + +module({ + group: 'automation', + name: 'Shield breaker', + component: 'AutoStunner', + path: 'auto-stunner', + tags: ['stun', 'shield', 'break', 'auto'] +}); + +//ESP modules ====================== module({ group: 'esp', @@ -181,6 +198,8 @@ module({ tags: ['entity', 'title', 'health'] }); +// Hacks Modules ========================== + module({ group: 'hacks', name: 'Kill Aura', @@ -350,6 +369,8 @@ module({ tags: ['air', 'place', 'airplace', 'scaffold'] }); +//Visuals Modules ============================ + module({ group: 'visuals', name: 'Full Bright', @@ -470,6 +491,8 @@ module({ tags: ['block', 'entity', 'chest', 'render'] }); +//Scripting Modules ====================== + module({ group: 'scripting', name: 'Key Bindings',