diff --git a/api/src/main/java/com/rappytv/autofisher/FishingController.java b/api/src/main/java/com/rappytv/autofisher/FishingController.java new file mode 100644 index 0000000..d2e1c46 --- /dev/null +++ b/api/src/main/java/com/rappytv/autofisher/FishingController.java @@ -0,0 +1,22 @@ +package com.rappytv.autofisher; + +import net.labymod.api.reference.annotation.Referenceable; + +@Referenceable +public abstract class FishingController { + + private boolean manualRetraction = true; + + public abstract void castFishingRod(); + + public abstract void retractFishingRod(); + + public void setManualRetraction(boolean value) { + this.manualRetraction = value; + } + + public boolean isManualRetraction() { + return this.manualRetraction; + } + +} diff --git a/api/src/main/java/com/rappytv/autofisher/event/FishHookBiteEvent.java b/api/src/main/java/com/rappytv/autofisher/event/FishHookBiteEvent.java new file mode 100644 index 0000000..230bc3f --- /dev/null +++ b/api/src/main/java/com/rappytv/autofisher/event/FishHookBiteEvent.java @@ -0,0 +1,7 @@ +package com.rappytv.autofisher.event; + +import net.labymod.api.event.Event; + +public class FishHookBiteEvent implements Event { + +} diff --git a/api/src/main/java/com/rappytv/autofisher/event/FishHookRetractEvent.java b/api/src/main/java/com/rappytv/autofisher/event/FishHookRetractEvent.java new file mode 100644 index 0000000..80c1b3e --- /dev/null +++ b/api/src/main/java/com/rappytv/autofisher/event/FishHookRetractEvent.java @@ -0,0 +1,7 @@ +package com.rappytv.autofisher.event; + +import net.labymod.api.event.Event; + +public record FishHookRetractEvent(boolean manual) implements Event { + +} diff --git a/build.gradle.kts b/build.gradle.kts index da5e473..6b68168 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -9,27 +9,26 @@ group = "org.example" version = providers.environmentVariable("VERSION").getOrElse("1.0.0") labyMod { - defaultPackageName = "org.example" //change this to your main package name (used by all modules) + defaultPackageName = "com.rappytv.autofisher" + + addonInfo { + namespace = "autofisher" + displayName = "AutoFisher" + author = "RappyTV" + description = "Completely automate the way your fishing rod works" + minecraftVersion = "1.17.1<1.21.10" + version = rootProject.version.toString() + } minecraft { registerVersion(versions.toTypedArray()) { runs { getByName("client") { - // When the property is set to true, you can log in with a Minecraft account - // devLogin = true + devLogin = true } } } } - - addonInfo { - namespace = "example" - displayName = "ExampleAddon" - author = "Example Author" - description = "Example Description" - minecraftVersion = "*" - version = rootProject.version.toString() - } } subprojects { diff --git a/core/src/main/java/com/rappytv/autofisher/core/AutoFisherAddon.java b/core/src/main/java/com/rappytv/autofisher/core/AutoFisherAddon.java new file mode 100644 index 0000000..616f990 --- /dev/null +++ b/core/src/main/java/com/rappytv/autofisher/core/AutoFisherAddon.java @@ -0,0 +1,32 @@ +package com.rappytv.autofisher.core; + +import com.rappytv.autofisher.FishingController; +import com.rappytv.autofisher.api.generated.ReferenceStorage; +import com.rappytv.autofisher.core.listener.FishingListener; +import net.labymod.api.addon.LabyAddon; +import net.labymod.api.models.addon.annotation.AddonMain; + +@AddonMain +public class AutoFisherAddon extends LabyAddon { + + public static final String PERMISSION = "autofisher"; + private static AutoFisherAddon instance; + + @Override + protected void enable() { + instance = this; + + this.registerSettingCategory(); + this.registerListener(new FishingListener(this)); + this.labyAPI().permissionRegistry().register(PERMISSION, true, true); + } + + @Override + protected Class configurationClass() { + return AutoFisherConfig.class; + } + + public static FishingController fishingController() { + return ((ReferenceStorage) instance.referenceStorageAccessor()).fishingController(); + } +} diff --git a/core/src/main/java/com/rappytv/autofisher/core/AutoFisherConfig.java b/core/src/main/java/com/rappytv/autofisher/core/AutoFisherConfig.java new file mode 100644 index 0000000..6c4dc9c --- /dev/null +++ b/core/src/main/java/com/rappytv/autofisher/core/AutoFisherConfig.java @@ -0,0 +1,59 @@ +package com.rappytv.autofisher.core; + +import net.labymod.api.addon.AddonConfig; +import net.labymod.api.client.gui.screen.widget.widgets.input.SliderWidget.SliderSetting; +import net.labymod.api.client.gui.screen.widget.widgets.input.SwitchWidget.SwitchSetting; +import net.labymod.api.configuration.loader.annotation.SpriteSlot; +import net.labymod.api.configuration.loader.annotation.SpriteTexture; +import net.labymod.api.configuration.loader.property.ConfigProperty; +import net.labymod.api.configuration.settings.annotation.SettingRequires; +import net.labymod.api.configuration.settings.annotation.SettingSection; + +@SpriteTexture("settings.png") +public class AutoFisherConfig extends AddonConfig { + + @SpriteSlot + @SwitchSetting + private final ConfigProperty enabled = new ConfigProperty<>(true); + + @SpriteSlot(x = 1) + @SwitchSetting + private final ConfigProperty autoCast = new ConfigProperty<>(true); + + @SettingSection("delay") + @SpriteSlot(x = 2) + @SettingRequires("autoCast") + @SwitchSetting + private final ConfigProperty enableDelay = new ConfigProperty<>(true); + + @SpriteSlot(x = 3) + @SettingRequires("enableDelay") + @SwitchSetting + private final ConfigProperty randomDelay = new ConfigProperty<>(true); + + @SpriteSlot(x = 4) + @SettingRequires(value = "randomDelay", invert = true) + @SliderSetting(min = 1, max = 20) + private final ConfigProperty delay = new ConfigProperty<>(3); + + @Override + public ConfigProperty enabled() { + return this.enabled; + } + + public ConfigProperty autoCast() { + return this.autoCast; + } + + public ConfigProperty enableDelay() { + return this.enableDelay; + } + + public ConfigProperty randomDelay() { + return this.randomDelay; + } + + public ConfigProperty delay() { + return this.delay; + } +} diff --git a/core/src/main/java/com/rappytv/autofisher/core/listener/FishingListener.java b/core/src/main/java/com/rappytv/autofisher/core/listener/FishingListener.java new file mode 100644 index 0000000..f51ccb3 --- /dev/null +++ b/core/src/main/java/com/rappytv/autofisher/core/listener/FishingListener.java @@ -0,0 +1,57 @@ +package com.rappytv.autofisher.core.listener; + +import com.rappytv.autofisher.core.AutoFisherAddon; +import com.rappytv.autofisher.event.FishHookBiteEvent; +import com.rappytv.autofisher.event.FishHookRetractEvent; +import java.util.Random; +import java.util.concurrent.TimeUnit; +import net.labymod.api.Laby; +import net.labymod.api.event.Subscribe; +import net.labymod.api.util.concurrent.task.Task; + +public class FishingListener { + + private static final Random random = new Random(); + private static final Runnable retraction = AutoFisherAddon.fishingController()::castFishingRod; + + private final AutoFisherAddon addon; + + public FishingListener(AutoFisherAddon addon) { + this.addon = addon; + } + + @Subscribe + public void onFishBite(FishHookBiteEvent event) { + if (!this.isAllowed()) { + return; + } + AutoFisherAddon.fishingController().retractFishingRod(); + } + + @Subscribe + public void onHookRetract(FishHookRetractEvent event) { + if (!this.isAllowed() || !this.addon.configuration().autoCast().get() || !event.manual()) { + return; + } + + if (!this.addon.configuration().enableDelay().get()) { + retraction.run(); + return; + } + + int delay; + if (this.addon.configuration().randomDelay().get()) { + delay = random.nextInt(1, 6); + } else { + delay = this.addon.configuration().delay().get(); + } + + Task.builder(retraction).delay(delay, TimeUnit.SECONDS).build().execute(); + } + + @SuppressWarnings("all") + private boolean isAllowed() { + return Laby.labyAPI().permissionRegistry().isPermissionEnabled(AutoFisherAddon.PERMISSION); + } + +} diff --git a/core/src/main/java/org/example/core/ExampleAddon.java b/core/src/main/java/org/example/core/ExampleAddon.java deleted file mode 100644 index 47a4563..0000000 --- a/core/src/main/java/org/example/core/ExampleAddon.java +++ /dev/null @@ -1,25 +0,0 @@ -package org.example.core; - -import net.labymod.api.addon.LabyAddon; -import net.labymod.api.models.addon.annotation.AddonMain; -import org.example.core.commands.ExamplePingCommand; -import org.example.core.listener.ExampleGameTickListener; - -@AddonMain -public class ExampleAddon extends LabyAddon { - - @Override - protected void enable() { - this.registerSettingCategory(); - - this.registerListener(new ExampleGameTickListener(this)); - this.registerCommand(new ExamplePingCommand()); - - this.logger().info("Enabled the Addon"); - } - - @Override - protected Class configurationClass() { - return ExampleConfiguration.class; - } -} diff --git a/core/src/main/java/org/example/core/ExampleConfiguration.java b/core/src/main/java/org/example/core/ExampleConfiguration.java deleted file mode 100644 index 0faafb1..0000000 --- a/core/src/main/java/org/example/core/ExampleConfiguration.java +++ /dev/null @@ -1,18 +0,0 @@ -package org.example.core; - -import net.labymod.api.addon.AddonConfig; -import net.labymod.api.client.gui.screen.widget.widgets.input.SwitchWidget.SwitchSetting; -import net.labymod.api.configuration.loader.annotation.ConfigName; -import net.labymod.api.configuration.loader.property.ConfigProperty; - -@ConfigName("settings") -public class ExampleConfiguration extends AddonConfig { - - @SwitchSetting - private final ConfigProperty enabled = new ConfigProperty<>(true); - - @Override - public ConfigProperty enabled() { - return this.enabled; - } -} diff --git a/core/src/main/java/org/example/core/commands/ExamplePingCommand.java b/core/src/main/java/org/example/core/commands/ExamplePingCommand.java deleted file mode 100644 index 5952915..0000000 --- a/core/src/main/java/org/example/core/commands/ExamplePingCommand.java +++ /dev/null @@ -1,25 +0,0 @@ -package org.example.core.commands; - -import net.labymod.api.client.chat.command.Command; -import net.labymod.api.client.component.Component; -import net.labymod.api.client.component.format.NamedTextColor; - -public class ExamplePingCommand extends Command { - - public ExamplePingCommand() { - super("ping", "pong"); - - this.withSubCommand(new ExamplePingSubCommand()); - } - - @Override - public boolean execute(String prefix, String[] arguments) { - if (prefix.equalsIgnoreCase("ping")) { - this.displayMessage(Component.text("Ping!", NamedTextColor.AQUA)); - return false; - } - - this.displayMessage(Component.text("Pong!", NamedTextColor.GOLD)); - return true; - } -} diff --git a/core/src/main/java/org/example/core/commands/ExamplePingSubCommand.java b/core/src/main/java/org/example/core/commands/ExamplePingSubCommand.java deleted file mode 100644 index 8c6a981..0000000 --- a/core/src/main/java/org/example/core/commands/ExamplePingSubCommand.java +++ /dev/null @@ -1,18 +0,0 @@ -package org.example.core.commands; - -import net.labymod.api.client.chat.command.SubCommand; -import net.labymod.api.client.component.Component; -import net.labymod.api.client.component.format.NamedTextColor; - -public class ExamplePingSubCommand extends SubCommand { - - protected ExamplePingSubCommand() { - super("pong"); - } - - @Override - public boolean execute(String prefix, String[] arguments) { - this.displayMessage(Component.text("Ping Pong!", NamedTextColor.GRAY)); - return true; - } -} diff --git a/core/src/main/java/org/example/core/listener/ExampleGameTickListener.java b/core/src/main/java/org/example/core/listener/ExampleGameTickListener.java deleted file mode 100644 index b631b85..0000000 --- a/core/src/main/java/org/example/core/listener/ExampleGameTickListener.java +++ /dev/null @@ -1,24 +0,0 @@ -package org.example.core.listener; - -import net.labymod.api.event.Phase; -import net.labymod.api.event.Subscribe; -import net.labymod.api.event.client.lifecycle.GameTickEvent; -import org.example.core.ExampleAddon; - -public class ExampleGameTickListener { - - private final ExampleAddon addon; - - public ExampleGameTickListener(ExampleAddon addon) { - this.addon = addon; - } - - @Subscribe - public void onGameTick(GameTickEvent event) { - if (event.phase() != Phase.PRE) { - return; - } - - this.addon.logger().info(this.addon.configuration().enabled().get() ? "enabled" : "disabled"); - } -} diff --git a/core/src/main/resources/assets/autofisher/i18n/en_us.json b/core/src/main/resources/assets/autofisher/i18n/en_us.json new file mode 100644 index 0000000..f90d606 --- /dev/null +++ b/core/src/main/resources/assets/autofisher/i18n/en_us.json @@ -0,0 +1,30 @@ +{ + "autofisher": { + "settings": { + "header": { + "delay": { + "name": "Delay" + } + }, + "enabled": { + "name": "Enabled" + }, + "autoCast": { + "name": "Auto cast", + "description": "Automatically cast the fishing rod after retracting it" + }, + "enableDelay": { + "name": "Delay", + "description": "Enables a delay before a new reel is casted" + }, + "randomDelay": { + "name": "Random delay", + "description": "Picks a random delay between §b1 and 5 seconds§r." + }, + "delay": { + "name": "Delay in seconds", + "description": "Choose your own delay in seconds" + } + } + } +} diff --git a/core/src/main/resources/assets/autofisher/textures/icon.png b/core/src/main/resources/assets/autofisher/textures/icon.png new file mode 100644 index 0000000..0552f16 Binary files /dev/null and b/core/src/main/resources/assets/autofisher/textures/icon.png differ diff --git a/core/src/main/resources/assets/autofisher/themes/vanilla/textures/settings.png b/core/src/main/resources/assets/autofisher/themes/vanilla/textures/settings.png new file mode 100644 index 0000000..42d305a Binary files /dev/null and b/core/src/main/resources/assets/autofisher/themes/vanilla/textures/settings.png differ diff --git a/core/src/main/resources/assets/example/i18n/en_us.json b/core/src/main/resources/assets/example/i18n/en_us.json deleted file mode 100644 index 0850d97..0000000 --- a/core/src/main/resources/assets/example/i18n/en_us.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "example": { - "settings": { - "enabled": { - "name": "Enabled" - } - } - } -} diff --git a/game-runner/src/v1_17_1/java/com/rappytv/autofisher/v1_17_1/VersionedFishingController.java b/game-runner/src/v1_17_1/java/com/rappytv/autofisher/v1_17_1/VersionedFishingController.java new file mode 100644 index 0000000..77d4e8b --- /dev/null +++ b/game-runner/src/v1_17_1/java/com/rappytv/autofisher/v1_17_1/VersionedFishingController.java @@ -0,0 +1,75 @@ +package com.rappytv.autofisher.v1_17_1; + +import com.rappytv.autofisher.FishingController; +import com.rappytv.autofisher.core.AutoFisherAddon; +import javax.inject.Singleton; +import net.labymod.api.models.Implements; +import net.minecraft.client.Minecraft; +import net.minecraft.client.multiplayer.MultiPlayerGameMode; +import net.minecraft.world.InteractionHand; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.entity.projectile.FishingHook; +import net.minecraft.world.item.FishingRodItem; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +@Singleton +@Implements(FishingController.class) +public class VersionedFishingController extends FishingController { + + @Override + public void castFishingRod() { + Player player = Minecraft.getInstance().player; + if (player == null) { + return; + } + InteractionHand hand = this.getFishingRodHand(player); + if (hand != null) { + this.useItem(hand); + } + } + + @Override + public void retractFishingRod() { + Player player = Minecraft.getInstance().player; + if (player == null) { + return; + } + FishingHook hook = player.fishing; + if (hook == null) { + return; + } + + InteractionHand hand = this.getFishingRodHand(player); + if (hand != null) { + AutoFisherAddon.fishingController().setManualRetraction(false); + this.useItem(hand); + } + } + + @Nullable + private InteractionHand getFishingRodHand(@NotNull Player player) { + if (player.getMainHandItem().getItem() instanceof FishingRodItem) { + return InteractionHand.MAIN_HAND; + } else if (player.getOffhandItem().getItem() instanceof FishingRodItem) { + return InteractionHand.OFF_HAND; + } + + return null; + } + + private void useItem(@NotNull InteractionHand hand) { + Player player = Minecraft.getInstance().player; + if (player == null) { + return; + } + + MultiPlayerGameMode gameMode = Minecraft.getInstance().gameMode; + if (gameMode == null) { + return; + } + + gameMode.useItem(player, player.level, hand); + player.swing(hand); + } +} diff --git a/game-runner/src/v1_17_1/java/com/rappytv/autofisher/v1_17_1/mixins/MixinFishingHook.java b/game-runner/src/v1_17_1/java/com/rappytv/autofisher/v1_17_1/mixins/MixinFishingHook.java new file mode 100644 index 0000000..49762d6 --- /dev/null +++ b/game-runner/src/v1_17_1/java/com/rappytv/autofisher/v1_17_1/mixins/MixinFishingHook.java @@ -0,0 +1,52 @@ +package com.rappytv.autofisher.v1_17_1.mixins; + +import com.rappytv.autofisher.core.AutoFisherAddon; +import com.rappytv.autofisher.event.FishHookBiteEvent; +import com.rappytv.autofisher.event.FishHookRetractEvent; +import net.labymod.api.Laby; +import net.minecraft.network.syncher.EntityDataAccessor; +import net.minecraft.world.entity.projectile.FishingHook; +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.At.Shift; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +@Mixin(FishingHook.class) +public class MixinFishingHook { + + @Unique + private static final int PUTFIELD_OPCODE = 181; + + @Shadow + private boolean biting; + + @Inject( + method = "onClientRemoval", + at = @At("TAIL") + ) + private void onRemove(CallbackInfo ci) { + boolean manual = AutoFisherAddon.fishingController().isManualRetraction(); + Laby.fireEvent(new FishHookRetractEvent(manual)); + if (!manual) { + AutoFisherAddon.fishingController().setManualRetraction(true); + } + } + + @Inject( + method = "onSyncedDataUpdated", + at = @At( + value = "FIELD", + target = "Lnet/minecraft/world/entity/projectile/FishingHook;biting:Z", + opcode = PUTFIELD_OPCODE, + shift = Shift.AFTER + ) + ) + private void onFishBiting(EntityDataAccessor $$0, CallbackInfo ci) { + if (this.biting) { + Laby.fireEvent(new FishHookBiteEvent()); + } + } +} diff --git a/game-runner/src/v1_18_2/java/com/rappytv/autofisher/v1_18_2/VersionedFishingController.java b/game-runner/src/v1_18_2/java/com/rappytv/autofisher/v1_18_2/VersionedFishingController.java new file mode 100644 index 0000000..80e4853 --- /dev/null +++ b/game-runner/src/v1_18_2/java/com/rappytv/autofisher/v1_18_2/VersionedFishingController.java @@ -0,0 +1,75 @@ +package com.rappytv.autofisher.v1_18_2; + +import com.rappytv.autofisher.FishingController; +import com.rappytv.autofisher.core.AutoFisherAddon; +import javax.inject.Singleton; +import net.labymod.api.models.Implements; +import net.minecraft.client.Minecraft; +import net.minecraft.client.multiplayer.MultiPlayerGameMode; +import net.minecraft.world.InteractionHand; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.entity.projectile.FishingHook; +import net.minecraft.world.item.FishingRodItem; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +@Singleton +@Implements(FishingController.class) +public class VersionedFishingController extends FishingController { + + @Override + public void castFishingRod() { + Player player = Minecraft.getInstance().player; + if (player == null) { + return; + } + InteractionHand hand = this.getFishingRodHand(player); + if (hand != null) { + this.useItem(hand); + } + } + + @Override + public void retractFishingRod() { + Player player = Minecraft.getInstance().player; + if (player == null) { + return; + } + FishingHook hook = player.fishing; + if (hook == null) { + return; + } + + InteractionHand hand = this.getFishingRodHand(player); + if (hand != null) { + AutoFisherAddon.fishingController().setManualRetraction(false); + this.useItem(hand); + } + } + + @Nullable + private InteractionHand getFishingRodHand(@NotNull Player player) { + if (player.getMainHandItem().getItem() instanceof FishingRodItem) { + return InteractionHand.MAIN_HAND; + } else if (player.getOffhandItem().getItem() instanceof FishingRodItem) { + return InteractionHand.OFF_HAND; + } + + return null; + } + + private void useItem(@NotNull InteractionHand hand) { + Player player = Minecraft.getInstance().player; + if (player == null) { + return; + } + + MultiPlayerGameMode gameMode = Minecraft.getInstance().gameMode; + if (gameMode == null) { + return; + } + + gameMode.useItem(player, player.level, hand); + player.swing(hand); + } +} diff --git a/game-runner/src/v1_18_2/java/com/rappytv/autofisher/v1_18_2/mixins/MixinFishingHook.java b/game-runner/src/v1_18_2/java/com/rappytv/autofisher/v1_18_2/mixins/MixinFishingHook.java new file mode 100644 index 0000000..1819ebc --- /dev/null +++ b/game-runner/src/v1_18_2/java/com/rappytv/autofisher/v1_18_2/mixins/MixinFishingHook.java @@ -0,0 +1,52 @@ +package com.rappytv.autofisher.v1_18_2.mixins; + +import com.rappytv.autofisher.core.AutoFisherAddon; +import com.rappytv.autofisher.event.FishHookBiteEvent; +import com.rappytv.autofisher.event.FishHookRetractEvent; +import net.labymod.api.Laby; +import net.minecraft.network.syncher.EntityDataAccessor; +import net.minecraft.world.entity.projectile.FishingHook; +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.At.Shift; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +@Mixin(FishingHook.class) +public class MixinFishingHook { + + @Unique + private static final int PUTFIELD_OPCODE = 181; + + @Shadow + private boolean biting; + + @Inject( + method = "onClientRemoval", + at = @At("TAIL") + ) + private void onRemove(CallbackInfo ci) { + boolean manual = AutoFisherAddon.fishingController().isManualRetraction(); + Laby.fireEvent(new FishHookRetractEvent(manual)); + if (!manual) { + AutoFisherAddon.fishingController().setManualRetraction(true); + } + } + + @Inject( + method = "onSyncedDataUpdated", + at = @At( + value = "FIELD", + target = "Lnet/minecraft/world/entity/projectile/FishingHook;biting:Z", + opcode = PUTFIELD_OPCODE, + shift = Shift.AFTER + ) + ) + private void onFishBiting(EntityDataAccessor $$0, CallbackInfo ci) { + if (this.biting) { + Laby.fireEvent(new FishHookBiteEvent()); + } + } +} diff --git a/game-runner/src/v1_19_2/java/com/rappytv/autofisher/v1_19_2/VersionedFishingController.java b/game-runner/src/v1_19_2/java/com/rappytv/autofisher/v1_19_2/VersionedFishingController.java new file mode 100644 index 0000000..31f23d5 --- /dev/null +++ b/game-runner/src/v1_19_2/java/com/rappytv/autofisher/v1_19_2/VersionedFishingController.java @@ -0,0 +1,75 @@ +package com.rappytv.autofisher.v1_19_2; + +import com.rappytv.autofisher.FishingController; +import com.rappytv.autofisher.core.AutoFisherAddon; +import javax.inject.Singleton; +import net.labymod.api.models.Implements; +import net.minecraft.client.Minecraft; +import net.minecraft.client.multiplayer.MultiPlayerGameMode; +import net.minecraft.world.InteractionHand; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.entity.projectile.FishingHook; +import net.minecraft.world.item.FishingRodItem; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +@Singleton +@Implements(FishingController.class) +public class VersionedFishingController extends FishingController { + + @Override + public void castFishingRod() { + Player player = Minecraft.getInstance().player; + if (player == null) { + return; + } + InteractionHand hand = this.getFishingRodHand(player); + if (hand != null) { + this.useItem(hand); + } + } + + @Override + public void retractFishingRod() { + Player player = Minecraft.getInstance().player; + if (player == null) { + return; + } + FishingHook hook = player.fishing; + if (hook == null) { + return; + } + + InteractionHand hand = this.getFishingRodHand(player); + if (hand != null) { + AutoFisherAddon.fishingController().setManualRetraction(false); + this.useItem(hand); + } + } + + @Nullable + private InteractionHand getFishingRodHand(@NotNull Player player) { + if (player.getMainHandItem().getItem() instanceof FishingRodItem) { + return InteractionHand.MAIN_HAND; + } else if (player.getOffhandItem().getItem() instanceof FishingRodItem) { + return InteractionHand.OFF_HAND; + } + + return null; + } + + private void useItem(@NotNull InteractionHand hand) { + Player player = Minecraft.getInstance().player; + if (player == null) { + return; + } + + MultiPlayerGameMode gameMode = Minecraft.getInstance().gameMode; + if (gameMode == null) { + return; + } + + gameMode.useItem(player, hand); + player.swing(hand); + } +} diff --git a/game-runner/src/v1_19_2/java/com/rappytv/autofisher/v1_19_2/mixins/MixinFishingHook.java b/game-runner/src/v1_19_2/java/com/rappytv/autofisher/v1_19_2/mixins/MixinFishingHook.java new file mode 100644 index 0000000..f185990 --- /dev/null +++ b/game-runner/src/v1_19_2/java/com/rappytv/autofisher/v1_19_2/mixins/MixinFishingHook.java @@ -0,0 +1,52 @@ +package com.rappytv.autofisher.v1_19_2.mixins; + +import com.rappytv.autofisher.core.AutoFisherAddon; +import com.rappytv.autofisher.event.FishHookBiteEvent; +import com.rappytv.autofisher.event.FishHookRetractEvent; +import net.labymod.api.Laby; +import net.minecraft.network.syncher.EntityDataAccessor; +import net.minecraft.world.entity.projectile.FishingHook; +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.At.Shift; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +@Mixin(FishingHook.class) +public class MixinFishingHook { + + @Unique + private static final int PUTFIELD_OPCODE = 181; + + @Shadow + private boolean biting; + + @Inject( + method = "onClientRemoval", + at = @At("TAIL") + ) + private void onRemove(CallbackInfo ci) { + boolean manual = AutoFisherAddon.fishingController().isManualRetraction(); + Laby.fireEvent(new FishHookRetractEvent(manual)); + if (!manual) { + AutoFisherAddon.fishingController().setManualRetraction(true); + } + } + + @Inject( + method = "onSyncedDataUpdated", + at = @At( + value = "FIELD", + target = "Lnet/minecraft/world/entity/projectile/FishingHook;biting:Z", + opcode = PUTFIELD_OPCODE, + shift = Shift.AFTER + ) + ) + private void onFishBiting(EntityDataAccessor $$0, CallbackInfo ci) { + if (this.biting) { + Laby.fireEvent(new FishHookBiteEvent()); + } + } +} diff --git a/game-runner/src/v1_19_3/java/com/rappytv/autofisher/v1_19_3/VersionedFishingController.java b/game-runner/src/v1_19_3/java/com/rappytv/autofisher/v1_19_3/VersionedFishingController.java new file mode 100644 index 0000000..874e5f2 --- /dev/null +++ b/game-runner/src/v1_19_3/java/com/rappytv/autofisher/v1_19_3/VersionedFishingController.java @@ -0,0 +1,75 @@ +package com.rappytv.autofisher.v1_19_3; + +import com.rappytv.autofisher.FishingController; +import com.rappytv.autofisher.core.AutoFisherAddon; +import javax.inject.Singleton; +import net.labymod.api.models.Implements; +import net.minecraft.client.Minecraft; +import net.minecraft.client.multiplayer.MultiPlayerGameMode; +import net.minecraft.world.InteractionHand; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.entity.projectile.FishingHook; +import net.minecraft.world.item.FishingRodItem; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +@Singleton +@Implements(FishingController.class) +public class VersionedFishingController extends FishingController { + + @Override + public void castFishingRod() { + Player player = Minecraft.getInstance().player; + if (player == null) { + return; + } + InteractionHand hand = this.getFishingRodHand(player); + if (hand != null) { + this.useItem(hand); + } + } + + @Override + public void retractFishingRod() { + Player player = Minecraft.getInstance().player; + if (player == null) { + return; + } + FishingHook hook = player.fishing; + if (hook == null) { + return; + } + + InteractionHand hand = this.getFishingRodHand(player); + if (hand != null) { + AutoFisherAddon.fishingController().setManualRetraction(false); + this.useItem(hand); + } + } + + @Nullable + private InteractionHand getFishingRodHand(@NotNull Player player) { + if (player.getMainHandItem().getItem() instanceof FishingRodItem) { + return InteractionHand.MAIN_HAND; + } else if (player.getOffhandItem().getItem() instanceof FishingRodItem) { + return InteractionHand.OFF_HAND; + } + + return null; + } + + private void useItem(@NotNull InteractionHand hand) { + Player player = Minecraft.getInstance().player; + if (player == null) { + return; + } + + MultiPlayerGameMode gameMode = Minecraft.getInstance().gameMode; + if (gameMode == null) { + return; + } + + gameMode.useItem(player, hand); + player.swing(hand); + } +} diff --git a/game-runner/src/v1_19_3/java/com/rappytv/autofisher/v1_19_3/mixins/MixinFishingHook.java b/game-runner/src/v1_19_3/java/com/rappytv/autofisher/v1_19_3/mixins/MixinFishingHook.java new file mode 100644 index 0000000..d9fbda5 --- /dev/null +++ b/game-runner/src/v1_19_3/java/com/rappytv/autofisher/v1_19_3/mixins/MixinFishingHook.java @@ -0,0 +1,52 @@ +package com.rappytv.autofisher.v1_19_3.mixins; + +import com.rappytv.autofisher.core.AutoFisherAddon; +import com.rappytv.autofisher.event.FishHookBiteEvent; +import com.rappytv.autofisher.event.FishHookRetractEvent; +import net.labymod.api.Laby; +import net.minecraft.network.syncher.EntityDataAccessor; +import net.minecraft.world.entity.projectile.FishingHook; +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.At.Shift; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +@Mixin(FishingHook.class) +public class MixinFishingHook { + + @Unique + private static final int PUTFIELD_OPCODE = 181; + + @Shadow + private boolean biting; + + @Inject( + method = "onClientRemoval", + at = @At("TAIL") + ) + private void onRemove(CallbackInfo ci) { + boolean manual = AutoFisherAddon.fishingController().isManualRetraction(); + Laby.fireEvent(new FishHookRetractEvent(manual)); + if (!manual) { + AutoFisherAddon.fishingController().setManualRetraction(true); + } + } + + @Inject( + method = "onSyncedDataUpdated", + at = @At( + value = "FIELD", + target = "Lnet/minecraft/world/entity/projectile/FishingHook;biting:Z", + opcode = PUTFIELD_OPCODE, + shift = Shift.AFTER + ) + ) + private void onFishBiting(EntityDataAccessor $$0, CallbackInfo ci) { + if (this.biting) { + Laby.fireEvent(new FishHookBiteEvent()); + } + } +} diff --git a/game-runner/src/v1_19_4/java/com/rappytv/autofisher/v1_19_4/VersionedFishingController.java b/game-runner/src/v1_19_4/java/com/rappytv/autofisher/v1_19_4/VersionedFishingController.java new file mode 100644 index 0000000..4213da5 --- /dev/null +++ b/game-runner/src/v1_19_4/java/com/rappytv/autofisher/v1_19_4/VersionedFishingController.java @@ -0,0 +1,75 @@ +package com.rappytv.autofisher.v1_19_4; + +import com.rappytv.autofisher.FishingController; +import com.rappytv.autofisher.core.AutoFisherAddon; +import javax.inject.Singleton; +import net.labymod.api.models.Implements; +import net.minecraft.client.Minecraft; +import net.minecraft.client.multiplayer.MultiPlayerGameMode; +import net.minecraft.world.InteractionHand; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.entity.projectile.FishingHook; +import net.minecraft.world.item.FishingRodItem; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +@Singleton +@Implements(FishingController.class) +public class VersionedFishingController extends FishingController { + + @Override + public void castFishingRod() { + Player player = Minecraft.getInstance().player; + if (player == null) { + return; + } + InteractionHand hand = this.getFishingRodHand(player); + if (hand != null) { + this.useItem(hand); + } + } + + @Override + public void retractFishingRod() { + Player player = Minecraft.getInstance().player; + if (player == null) { + return; + } + FishingHook hook = player.fishing; + if (hook == null) { + return; + } + + InteractionHand hand = this.getFishingRodHand(player); + if (hand != null) { + AutoFisherAddon.fishingController().setManualRetraction(false); + this.useItem(hand); + } + } + + @Nullable + private InteractionHand getFishingRodHand(@NotNull Player player) { + if (player.getMainHandItem().getItem() instanceof FishingRodItem) { + return InteractionHand.MAIN_HAND; + } else if (player.getOffhandItem().getItem() instanceof FishingRodItem) { + return InteractionHand.OFF_HAND; + } + + return null; + } + + private void useItem(@NotNull InteractionHand hand) { + Player player = Minecraft.getInstance().player; + if (player == null) { + return; + } + + MultiPlayerGameMode gameMode = Minecraft.getInstance().gameMode; + if (gameMode == null) { + return; + } + + gameMode.useItem(player, hand); + player.swing(hand); + } +} diff --git a/game-runner/src/v1_19_4/java/com/rappytv/autofisher/v1_19_4/mixins/MixinFishingHook.java b/game-runner/src/v1_19_4/java/com/rappytv/autofisher/v1_19_4/mixins/MixinFishingHook.java new file mode 100644 index 0000000..82b2833 --- /dev/null +++ b/game-runner/src/v1_19_4/java/com/rappytv/autofisher/v1_19_4/mixins/MixinFishingHook.java @@ -0,0 +1,52 @@ +package com.rappytv.autofisher.v1_19_4.mixins; + +import com.rappytv.autofisher.core.AutoFisherAddon; +import com.rappytv.autofisher.event.FishHookBiteEvent; +import com.rappytv.autofisher.event.FishHookRetractEvent; +import net.labymod.api.Laby; +import net.minecraft.network.syncher.EntityDataAccessor; +import net.minecraft.world.entity.projectile.FishingHook; +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.At.Shift; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +@Mixin(FishingHook.class) +public class MixinFishingHook { + + @Unique + private static final int PUTFIELD_OPCODE = 181; + + @Shadow + private boolean biting; + + @Inject( + method = "onClientRemoval", + at = @At("TAIL") + ) + private void onRemove(CallbackInfo ci) { + boolean manual = AutoFisherAddon.fishingController().isManualRetraction(); + Laby.fireEvent(new FishHookRetractEvent(manual)); + if (!manual) { + AutoFisherAddon.fishingController().setManualRetraction(true); + } + } + + @Inject( + method = "onSyncedDataUpdated", + at = @At( + value = "FIELD", + target = "Lnet/minecraft/world/entity/projectile/FishingHook;biting:Z", + opcode = PUTFIELD_OPCODE, + shift = Shift.AFTER + ) + ) + private void onFishBiting(EntityDataAccessor $$0, CallbackInfo ci) { + if (this.biting) { + Laby.fireEvent(new FishHookBiteEvent()); + } + } +} diff --git a/game-runner/src/v1_20_1/java/com/rappytv/autofisher/v1_20_1/VersionedFishingController.java b/game-runner/src/v1_20_1/java/com/rappytv/autofisher/v1_20_1/VersionedFishingController.java new file mode 100644 index 0000000..5e92de3 --- /dev/null +++ b/game-runner/src/v1_20_1/java/com/rappytv/autofisher/v1_20_1/VersionedFishingController.java @@ -0,0 +1,75 @@ +package com.rappytv.autofisher.v1_20_1; + +import com.rappytv.autofisher.FishingController; +import com.rappytv.autofisher.core.AutoFisherAddon; +import javax.inject.Singleton; +import net.labymod.api.models.Implements; +import net.minecraft.client.Minecraft; +import net.minecraft.client.multiplayer.MultiPlayerGameMode; +import net.minecraft.world.InteractionHand; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.entity.projectile.FishingHook; +import net.minecraft.world.item.FishingRodItem; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +@Singleton +@Implements(FishingController.class) +public class VersionedFishingController extends FishingController { + + @Override + public void castFishingRod() { + Player player = Minecraft.getInstance().player; + if (player == null) { + return; + } + InteractionHand hand = this.getFishingRodHand(player); + if (hand != null) { + this.useItem(hand); + } + } + + @Override + public void retractFishingRod() { + Player player = Minecraft.getInstance().player; + if (player == null) { + return; + } + FishingHook hook = player.fishing; + if (hook == null) { + return; + } + + InteractionHand hand = this.getFishingRodHand(player); + if (hand != null) { + AutoFisherAddon.fishingController().setManualRetraction(false); + this.useItem(hand); + } + } + + @Nullable + private InteractionHand getFishingRodHand(@NotNull Player player) { + if (player.getMainHandItem().getItem() instanceof FishingRodItem) { + return InteractionHand.MAIN_HAND; + } else if (player.getOffhandItem().getItem() instanceof FishingRodItem) { + return InteractionHand.OFF_HAND; + } + + return null; + } + + private void useItem(@NotNull InteractionHand hand) { + Player player = Minecraft.getInstance().player; + if (player == null) { + return; + } + + MultiPlayerGameMode gameMode = Minecraft.getInstance().gameMode; + if (gameMode == null) { + return; + } + + gameMode.useItem(player, hand); + player.swing(hand); + } +} diff --git a/game-runner/src/v1_20_1/java/com/rappytv/autofisher/v1_20_1/mixins/MixinFishingHook.java b/game-runner/src/v1_20_1/java/com/rappytv/autofisher/v1_20_1/mixins/MixinFishingHook.java new file mode 100644 index 0000000..b401fa1 --- /dev/null +++ b/game-runner/src/v1_20_1/java/com/rappytv/autofisher/v1_20_1/mixins/MixinFishingHook.java @@ -0,0 +1,52 @@ +package com.rappytv.autofisher.v1_20_1.mixins; + +import com.rappytv.autofisher.core.AutoFisherAddon; +import com.rappytv.autofisher.event.FishHookBiteEvent; +import com.rappytv.autofisher.event.FishHookRetractEvent; +import net.labymod.api.Laby; +import net.minecraft.network.syncher.EntityDataAccessor; +import net.minecraft.world.entity.projectile.FishingHook; +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.At.Shift; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +@Mixin(FishingHook.class) +public class MixinFishingHook { + + @Unique + private static final int PUTFIELD_OPCODE = 181; + + @Shadow + private boolean biting; + + @Inject( + method = "onClientRemoval", + at = @At("TAIL") + ) + private void onRemove(CallbackInfo ci) { + boolean manual = AutoFisherAddon.fishingController().isManualRetraction(); + Laby.fireEvent(new FishHookRetractEvent(manual)); + if (!manual) { + AutoFisherAddon.fishingController().setManualRetraction(true); + } + } + + @Inject( + method = "onSyncedDataUpdated", + at = @At( + value = "FIELD", + target = "Lnet/minecraft/world/entity/projectile/FishingHook;biting:Z", + opcode = PUTFIELD_OPCODE, + shift = Shift.AFTER + ) + ) + private void onFishBiting(EntityDataAccessor $$0, CallbackInfo ci) { + if (this.biting) { + Laby.fireEvent(new FishHookBiteEvent()); + } + } +} diff --git a/game-runner/src/v1_20_2/java/com/rappytv/autofisher/v1_20_2/VersionedFishingController.java b/game-runner/src/v1_20_2/java/com/rappytv/autofisher/v1_20_2/VersionedFishingController.java new file mode 100644 index 0000000..bc3ac24 --- /dev/null +++ b/game-runner/src/v1_20_2/java/com/rappytv/autofisher/v1_20_2/VersionedFishingController.java @@ -0,0 +1,75 @@ +package com.rappytv.autofisher.v1_20_2; + +import com.rappytv.autofisher.FishingController; +import com.rappytv.autofisher.core.AutoFisherAddon; +import javax.inject.Singleton; +import net.labymod.api.models.Implements; +import net.minecraft.client.Minecraft; +import net.minecraft.client.multiplayer.MultiPlayerGameMode; +import net.minecraft.world.InteractionHand; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.entity.projectile.FishingHook; +import net.minecraft.world.item.FishingRodItem; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +@Singleton +@Implements(FishingController.class) +public class VersionedFishingController extends FishingController { + + @Override + public void castFishingRod() { + Player player = Minecraft.getInstance().player; + if (player == null) { + return; + } + InteractionHand hand = this.getFishingRodHand(player); + if (hand != null) { + this.useItem(hand); + } + } + + @Override + public void retractFishingRod() { + Player player = Minecraft.getInstance().player; + if (player == null) { + return; + } + FishingHook hook = player.fishing; + if (hook == null) { + return; + } + + InteractionHand hand = this.getFishingRodHand(player); + if (hand != null) { + AutoFisherAddon.fishingController().setManualRetraction(false); + this.useItem(hand); + } + } + + @Nullable + private InteractionHand getFishingRodHand(@NotNull Player player) { + if (player.getMainHandItem().getItem() instanceof FishingRodItem) { + return InteractionHand.MAIN_HAND; + } else if (player.getOffhandItem().getItem() instanceof FishingRodItem) { + return InteractionHand.OFF_HAND; + } + + return null; + } + + private void useItem(@NotNull InteractionHand hand) { + Player player = Minecraft.getInstance().player; + if (player == null) { + return; + } + + MultiPlayerGameMode gameMode = Minecraft.getInstance().gameMode; + if (gameMode == null) { + return; + } + + gameMode.useItem(player, hand); + player.swing(hand); + } +} diff --git a/game-runner/src/v1_20_2/java/com/rappytv/autofisher/v1_20_2/mixins/MixinFishingHook.java b/game-runner/src/v1_20_2/java/com/rappytv/autofisher/v1_20_2/mixins/MixinFishingHook.java new file mode 100644 index 0000000..7346764 --- /dev/null +++ b/game-runner/src/v1_20_2/java/com/rappytv/autofisher/v1_20_2/mixins/MixinFishingHook.java @@ -0,0 +1,52 @@ +package com.rappytv.autofisher.v1_20_2.mixins; + +import com.rappytv.autofisher.core.AutoFisherAddon; +import com.rappytv.autofisher.event.FishHookBiteEvent; +import com.rappytv.autofisher.event.FishHookRetractEvent; +import net.labymod.api.Laby; +import net.minecraft.network.syncher.EntityDataAccessor; +import net.minecraft.world.entity.projectile.FishingHook; +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.At.Shift; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +@Mixin(FishingHook.class) +public class MixinFishingHook { + + @Unique + private static final int PUTFIELD_OPCODE = 181; + + @Shadow + private boolean biting; + + @Inject( + method = "onClientRemoval", + at = @At("TAIL") + ) + private void onRemove(CallbackInfo ci) { + boolean manual = AutoFisherAddon.fishingController().isManualRetraction(); + Laby.fireEvent(new FishHookRetractEvent(manual)); + if (!manual) { + AutoFisherAddon.fishingController().setManualRetraction(true); + } + } + + @Inject( + method = "onSyncedDataUpdated", + at = @At( + value = "FIELD", + target = "Lnet/minecraft/world/entity/projectile/FishingHook;biting:Z", + opcode = PUTFIELD_OPCODE, + shift = Shift.AFTER + ) + ) + private void onFishBiting(EntityDataAccessor $$0, CallbackInfo ci) { + if (this.biting) { + Laby.fireEvent(new FishHookBiteEvent()); + } + } +} diff --git a/game-runner/src/v1_20_4/java/com/rappytv/autofisher/v1_20_4/VersionedFishingController.java b/game-runner/src/v1_20_4/java/com/rappytv/autofisher/v1_20_4/VersionedFishingController.java new file mode 100644 index 0000000..c545e32 --- /dev/null +++ b/game-runner/src/v1_20_4/java/com/rappytv/autofisher/v1_20_4/VersionedFishingController.java @@ -0,0 +1,75 @@ +package com.rappytv.autofisher.v1_20_4; + +import com.rappytv.autofisher.FishingController; +import com.rappytv.autofisher.core.AutoFisherAddon; +import javax.inject.Singleton; +import net.labymod.api.models.Implements; +import net.minecraft.client.Minecraft; +import net.minecraft.client.multiplayer.MultiPlayerGameMode; +import net.minecraft.world.InteractionHand; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.entity.projectile.FishingHook; +import net.minecraft.world.item.FishingRodItem; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +@Singleton +@Implements(FishingController.class) +public class VersionedFishingController extends FishingController { + + @Override + public void castFishingRod() { + Player player = Minecraft.getInstance().player; + if (player == null) { + return; + } + InteractionHand hand = this.getFishingRodHand(player); + if (hand != null) { + this.useItem(hand); + } + } + + @Override + public void retractFishingRod() { + Player player = Minecraft.getInstance().player; + if (player == null) { + return; + } + FishingHook hook = player.fishing; + if (hook == null) { + return; + } + + InteractionHand hand = this.getFishingRodHand(player); + if (hand != null) { + AutoFisherAddon.fishingController().setManualRetraction(false); + this.useItem(hand); + } + } + + @Nullable + private InteractionHand getFishingRodHand(@NotNull Player player) { + if (player.getMainHandItem().getItem() instanceof FishingRodItem) { + return InteractionHand.MAIN_HAND; + } else if (player.getOffhandItem().getItem() instanceof FishingRodItem) { + return InteractionHand.OFF_HAND; + } + + return null; + } + + private void useItem(@NotNull InteractionHand hand) { + Player player = Minecraft.getInstance().player; + if (player == null) { + return; + } + + MultiPlayerGameMode gameMode = Minecraft.getInstance().gameMode; + if (gameMode == null) { + return; + } + + gameMode.useItem(player, hand); + player.swing(hand); + } +} diff --git a/game-runner/src/v1_20_4/java/com/rappytv/autofisher/v1_20_4/mixins/MixinFishingHook.java b/game-runner/src/v1_20_4/java/com/rappytv/autofisher/v1_20_4/mixins/MixinFishingHook.java new file mode 100644 index 0000000..3d167d2 --- /dev/null +++ b/game-runner/src/v1_20_4/java/com/rappytv/autofisher/v1_20_4/mixins/MixinFishingHook.java @@ -0,0 +1,52 @@ +package com.rappytv.autofisher.v1_20_4.mixins; + +import com.rappytv.autofisher.core.AutoFisherAddon; +import com.rappytv.autofisher.event.FishHookBiteEvent; +import com.rappytv.autofisher.event.FishHookRetractEvent; +import net.labymod.api.Laby; +import net.minecraft.network.syncher.EntityDataAccessor; +import net.minecraft.world.entity.projectile.FishingHook; +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.At.Shift; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +@Mixin(FishingHook.class) +public class MixinFishingHook { + + @Unique + private static final int PUTFIELD_OPCODE = 181; + + @Shadow + private boolean biting; + + @Inject( + method = "onClientRemoval", + at = @At("TAIL") + ) + private void onRemove(CallbackInfo ci) { + boolean manual = AutoFisherAddon.fishingController().isManualRetraction(); + Laby.fireEvent(new FishHookRetractEvent(manual)); + if (!manual) { + AutoFisherAddon.fishingController().setManualRetraction(true); + } + } + + @Inject( + method = "onSyncedDataUpdated", + at = @At( + value = "FIELD", + target = "Lnet/minecraft/world/entity/projectile/FishingHook;biting:Z", + opcode = PUTFIELD_OPCODE, + shift = Shift.AFTER + ) + ) + private void onFishBiting(EntityDataAccessor $$0, CallbackInfo ci) { + if (this.biting) { + Laby.fireEvent(new FishHookBiteEvent()); + } + } +} diff --git a/game-runner/src/v1_20_5/java/com/rappytv/autofisher/v1_20_5/VersionedFishingController.java b/game-runner/src/v1_20_5/java/com/rappytv/autofisher/v1_20_5/VersionedFishingController.java new file mode 100644 index 0000000..811aad2 --- /dev/null +++ b/game-runner/src/v1_20_5/java/com/rappytv/autofisher/v1_20_5/VersionedFishingController.java @@ -0,0 +1,75 @@ +package com.rappytv.autofisher.v1_20_5; + +import com.rappytv.autofisher.FishingController; +import com.rappytv.autofisher.core.AutoFisherAddon; +import javax.inject.Singleton; +import net.labymod.api.models.Implements; +import net.minecraft.client.Minecraft; +import net.minecraft.client.multiplayer.MultiPlayerGameMode; +import net.minecraft.world.InteractionHand; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.entity.projectile.FishingHook; +import net.minecraft.world.item.FishingRodItem; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +@Singleton +@Implements(FishingController.class) +public class VersionedFishingController extends FishingController { + + @Override + public void castFishingRod() { + Player player = Minecraft.getInstance().player; + if (player == null) { + return; + } + InteractionHand hand = this.getFishingRodHand(player); + if (hand != null) { + this.useItem(hand); + } + } + + @Override + public void retractFishingRod() { + Player player = Minecraft.getInstance().player; + if (player == null) { + return; + } + FishingHook hook = player.fishing; + if (hook == null) { + return; + } + + InteractionHand hand = this.getFishingRodHand(player); + if (hand != null) { + AutoFisherAddon.fishingController().setManualRetraction(false); + this.useItem(hand); + } + } + + @Nullable + private InteractionHand getFishingRodHand(@NotNull Player player) { + if (player.getMainHandItem().getItem() instanceof FishingRodItem) { + return InteractionHand.MAIN_HAND; + } else if (player.getOffhandItem().getItem() instanceof FishingRodItem) { + return InteractionHand.OFF_HAND; + } + + return null; + } + + private void useItem(@NotNull InteractionHand hand) { + Player player = Minecraft.getInstance().player; + if (player == null) { + return; + } + + MultiPlayerGameMode gameMode = Minecraft.getInstance().gameMode; + if (gameMode == null) { + return; + } + + gameMode.useItem(player, hand); + player.swing(hand); + } +} diff --git a/game-runner/src/v1_20_5/java/com/rappytv/autofisher/v1_20_5/mixins/MixinFishingHook.java b/game-runner/src/v1_20_5/java/com/rappytv/autofisher/v1_20_5/mixins/MixinFishingHook.java new file mode 100644 index 0000000..b0606ea --- /dev/null +++ b/game-runner/src/v1_20_5/java/com/rappytv/autofisher/v1_20_5/mixins/MixinFishingHook.java @@ -0,0 +1,52 @@ +package com.rappytv.autofisher.v1_20_5.mixins; + +import com.rappytv.autofisher.core.AutoFisherAddon; +import com.rappytv.autofisher.event.FishHookBiteEvent; +import com.rappytv.autofisher.event.FishHookRetractEvent; +import net.labymod.api.Laby; +import net.minecraft.network.syncher.EntityDataAccessor; +import net.minecraft.world.entity.projectile.FishingHook; +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.At.Shift; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +@Mixin(FishingHook.class) +public class MixinFishingHook { + + @Unique + private static final int PUTFIELD_OPCODE = 181; + + @Shadow + private boolean biting; + + @Inject( + method = "onClientRemoval", + at = @At("TAIL") + ) + private void onRemove(CallbackInfo ci) { + boolean manual = AutoFisherAddon.fishingController().isManualRetraction(); + Laby.fireEvent(new FishHookRetractEvent(manual)); + if (!manual) { + AutoFisherAddon.fishingController().setManualRetraction(true); + } + } + + @Inject( + method = "onSyncedDataUpdated", + at = @At( + value = "FIELD", + target = "Lnet/minecraft/world/entity/projectile/FishingHook;biting:Z", + opcode = PUTFIELD_OPCODE, + shift = Shift.AFTER + ) + ) + private void onFishBiting(EntityDataAccessor $$0, CallbackInfo ci) { + if (this.biting) { + Laby.fireEvent(new FishHookBiteEvent()); + } + } +} diff --git a/game-runner/src/v1_20_6/java/com/rappytv/autofisher/v1_20_6/VersionedFishingController.java b/game-runner/src/v1_20_6/java/com/rappytv/autofisher/v1_20_6/VersionedFishingController.java new file mode 100644 index 0000000..0dbea09 --- /dev/null +++ b/game-runner/src/v1_20_6/java/com/rappytv/autofisher/v1_20_6/VersionedFishingController.java @@ -0,0 +1,75 @@ +package com.rappytv.autofisher.v1_20_6; + +import com.rappytv.autofisher.FishingController; +import com.rappytv.autofisher.core.AutoFisherAddon; +import javax.inject.Singleton; +import net.labymod.api.models.Implements; +import net.minecraft.client.Minecraft; +import net.minecraft.client.multiplayer.MultiPlayerGameMode; +import net.minecraft.world.InteractionHand; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.entity.projectile.FishingHook; +import net.minecraft.world.item.FishingRodItem; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +@Singleton +@Implements(FishingController.class) +public class VersionedFishingController extends FishingController { + + @Override + public void castFishingRod() { + Player player = Minecraft.getInstance().player; + if (player == null) { + return; + } + InteractionHand hand = this.getFishingRodHand(player); + if (hand != null) { + this.useItem(hand); + } + } + + @Override + public void retractFishingRod() { + Player player = Minecraft.getInstance().player; + if (player == null) { + return; + } + FishingHook hook = player.fishing; + if (hook == null) { + return; + } + + InteractionHand hand = this.getFishingRodHand(player); + if (hand != null) { + AutoFisherAddon.fishingController().setManualRetraction(false); + this.useItem(hand); + } + } + + @Nullable + private InteractionHand getFishingRodHand(@NotNull Player player) { + if (player.getMainHandItem().getItem() instanceof FishingRodItem) { + return InteractionHand.MAIN_HAND; + } else if (player.getOffhandItem().getItem() instanceof FishingRodItem) { + return InteractionHand.OFF_HAND; + } + + return null; + } + + private void useItem(@NotNull InteractionHand hand) { + Player player = Minecraft.getInstance().player; + if (player == null) { + return; + } + + MultiPlayerGameMode gameMode = Minecraft.getInstance().gameMode; + if (gameMode == null) { + return; + } + + gameMode.useItem(player, hand); + player.swing(hand); + } +} diff --git a/game-runner/src/v1_20_6/java/com/rappytv/autofisher/v1_20_6/mixins/MixinFishingHook.java b/game-runner/src/v1_20_6/java/com/rappytv/autofisher/v1_20_6/mixins/MixinFishingHook.java new file mode 100644 index 0000000..c01713b --- /dev/null +++ b/game-runner/src/v1_20_6/java/com/rappytv/autofisher/v1_20_6/mixins/MixinFishingHook.java @@ -0,0 +1,52 @@ +package com.rappytv.autofisher.v1_20_6.mixins; + +import com.rappytv.autofisher.core.AutoFisherAddon; +import com.rappytv.autofisher.event.FishHookBiteEvent; +import com.rappytv.autofisher.event.FishHookRetractEvent; +import net.labymod.api.Laby; +import net.minecraft.network.syncher.EntityDataAccessor; +import net.minecraft.world.entity.projectile.FishingHook; +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.At.Shift; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +@Mixin(FishingHook.class) +public class MixinFishingHook { + + @Unique + private static final int PUTFIELD_OPCODE = 181; + + @Shadow + private boolean biting; + + @Inject( + method = "onClientRemoval", + at = @At("TAIL") + ) + private void onRemove(CallbackInfo ci) { + boolean manual = AutoFisherAddon.fishingController().isManualRetraction(); + Laby.fireEvent(new FishHookRetractEvent(manual)); + if (!manual) { + AutoFisherAddon.fishingController().setManualRetraction(true); + } + } + + @Inject( + method = "onSyncedDataUpdated", + at = @At( + value = "FIELD", + target = "Lnet/minecraft/world/entity/projectile/FishingHook;biting:Z", + opcode = PUTFIELD_OPCODE, + shift = Shift.AFTER + ) + ) + private void onFishBiting(EntityDataAccessor $$0, CallbackInfo ci) { + if (this.biting) { + Laby.fireEvent(new FishHookBiteEvent()); + } + } +} diff --git a/game-runner/src/v1_21/java/com/rappytv/autofisher/v1_21/VersionedFishingController.java b/game-runner/src/v1_21/java/com/rappytv/autofisher/v1_21/VersionedFishingController.java new file mode 100644 index 0000000..fee1825 --- /dev/null +++ b/game-runner/src/v1_21/java/com/rappytv/autofisher/v1_21/VersionedFishingController.java @@ -0,0 +1,75 @@ +package com.rappytv.autofisher.v1_21; + +import com.rappytv.autofisher.FishingController; +import com.rappytv.autofisher.core.AutoFisherAddon; +import javax.inject.Singleton; +import net.labymod.api.models.Implements; +import net.minecraft.client.Minecraft; +import net.minecraft.client.multiplayer.MultiPlayerGameMode; +import net.minecraft.world.InteractionHand; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.entity.projectile.FishingHook; +import net.minecraft.world.item.FishingRodItem; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +@Singleton +@Implements(FishingController.class) +public class VersionedFishingController extends FishingController { + + @Override + public void castFishingRod() { + Player player = Minecraft.getInstance().player; + if (player == null) { + return; + } + InteractionHand hand = this.getFishingRodHand(player); + if (hand != null) { + this.useItem(hand); + } + } + + @Override + public void retractFishingRod() { + Player player = Minecraft.getInstance().player; + if (player == null) { + return; + } + FishingHook hook = player.fishing; + if (hook == null) { + return; + } + + InteractionHand hand = this.getFishingRodHand(player); + if (hand != null) { + AutoFisherAddon.fishingController().setManualRetraction(false); + this.useItem(hand); + } + } + + @Nullable + private InteractionHand getFishingRodHand(@NotNull Player player) { + if (player.getMainHandItem().getItem() instanceof FishingRodItem) { + return InteractionHand.MAIN_HAND; + } else if (player.getOffhandItem().getItem() instanceof FishingRodItem) { + return InteractionHand.OFF_HAND; + } + + return null; + } + + private void useItem(@NotNull InteractionHand hand) { + Player player = Minecraft.getInstance().player; + if (player == null) { + return; + } + + MultiPlayerGameMode gameMode = Minecraft.getInstance().gameMode; + if (gameMode == null) { + return; + } + + gameMode.useItem(player, hand); + player.swing(hand); + } +} diff --git a/game-runner/src/v1_21/java/com/rappytv/autofisher/v1_21/mixins/MixinFishingHook.java b/game-runner/src/v1_21/java/com/rappytv/autofisher/v1_21/mixins/MixinFishingHook.java new file mode 100644 index 0000000..6ad208a --- /dev/null +++ b/game-runner/src/v1_21/java/com/rappytv/autofisher/v1_21/mixins/MixinFishingHook.java @@ -0,0 +1,52 @@ +package com.rappytv.autofisher.v1_21.mixins; + +import com.rappytv.autofisher.core.AutoFisherAddon; +import com.rappytv.autofisher.event.FishHookBiteEvent; +import com.rappytv.autofisher.event.FishHookRetractEvent; +import net.labymod.api.Laby; +import net.minecraft.network.syncher.EntityDataAccessor; +import net.minecraft.world.entity.projectile.FishingHook; +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.At.Shift; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +@Mixin(FishingHook.class) +public class MixinFishingHook { + + @Unique + private static final int PUTFIELD_OPCODE = 181; + + @Shadow + private boolean biting; + + @Inject( + method = "onClientRemoval", + at = @At("TAIL") + ) + private void onRemove(CallbackInfo ci) { + boolean manual = AutoFisherAddon.fishingController().isManualRetraction(); + Laby.fireEvent(new FishHookRetractEvent(manual)); + if (!manual) { + AutoFisherAddon.fishingController().setManualRetraction(true); + } + } + + @Inject( + method = "onSyncedDataUpdated", + at = @At( + value = "FIELD", + target = "Lnet/minecraft/world/entity/projectile/FishingHook;biting:Z", + opcode = PUTFIELD_OPCODE, + shift = Shift.AFTER + ) + ) + private void onFishBiting(EntityDataAccessor $$0, CallbackInfo ci) { + if (this.biting) { + Laby.fireEvent(new FishHookBiteEvent()); + } + } +} diff --git a/game-runner/src/v1_21_1/java/com/rappytv/autofisher/v1_21_1/VersionedFishingController.java b/game-runner/src/v1_21_1/java/com/rappytv/autofisher/v1_21_1/VersionedFishingController.java new file mode 100644 index 0000000..c480186 --- /dev/null +++ b/game-runner/src/v1_21_1/java/com/rappytv/autofisher/v1_21_1/VersionedFishingController.java @@ -0,0 +1,75 @@ +package com.rappytv.autofisher.v1_21_1; + +import com.rappytv.autofisher.FishingController; +import com.rappytv.autofisher.core.AutoFisherAddon; +import javax.inject.Singleton; +import net.labymod.api.models.Implements; +import net.minecraft.client.Minecraft; +import net.minecraft.client.multiplayer.MultiPlayerGameMode; +import net.minecraft.world.InteractionHand; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.entity.projectile.FishingHook; +import net.minecraft.world.item.FishingRodItem; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +@Singleton +@Implements(FishingController.class) +public class VersionedFishingController extends FishingController { + + @Override + public void castFishingRod() { + Player player = Minecraft.getInstance().player; + if (player == null) { + return; + } + InteractionHand hand = this.getFishingRodHand(player); + if (hand != null) { + this.useItem(hand); + } + } + + @Override + public void retractFishingRod() { + Player player = Minecraft.getInstance().player; + if (player == null) { + return; + } + FishingHook hook = player.fishing; + if (hook == null) { + return; + } + + InteractionHand hand = this.getFishingRodHand(player); + if (hand != null) { + AutoFisherAddon.fishingController().setManualRetraction(false); + this.useItem(hand); + } + } + + @Nullable + private InteractionHand getFishingRodHand(@NotNull Player player) { + if (player.getMainHandItem().getItem() instanceof FishingRodItem) { + return InteractionHand.MAIN_HAND; + } else if (player.getOffhandItem().getItem() instanceof FishingRodItem) { + return InteractionHand.OFF_HAND; + } + + return null; + } + + private void useItem(@NotNull InteractionHand hand) { + Player player = Minecraft.getInstance().player; + if (player == null) { + return; + } + + MultiPlayerGameMode gameMode = Minecraft.getInstance().gameMode; + if (gameMode == null) { + return; + } + + gameMode.useItem(player, hand); + player.swing(hand); + } +} diff --git a/game-runner/src/v1_21_1/java/com/rappytv/autofisher/v1_21_1/mixins/MixinFishingHook.java b/game-runner/src/v1_21_1/java/com/rappytv/autofisher/v1_21_1/mixins/MixinFishingHook.java new file mode 100644 index 0000000..5b8e3c9 --- /dev/null +++ b/game-runner/src/v1_21_1/java/com/rappytv/autofisher/v1_21_1/mixins/MixinFishingHook.java @@ -0,0 +1,52 @@ +package com.rappytv.autofisher.v1_21_1.mixins; + +import com.rappytv.autofisher.core.AutoFisherAddon; +import com.rappytv.autofisher.event.FishHookBiteEvent; +import com.rappytv.autofisher.event.FishHookRetractEvent; +import net.labymod.api.Laby; +import net.minecraft.network.syncher.EntityDataAccessor; +import net.minecraft.world.entity.projectile.FishingHook; +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.At.Shift; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +@Mixin(FishingHook.class) +public class MixinFishingHook { + + @Unique + private static final int PUTFIELD_OPCODE = 181; + + @Shadow + private boolean biting; + + @Inject( + method = "onClientRemoval", + at = @At("TAIL") + ) + private void onRemove(CallbackInfo ci) { + boolean manual = AutoFisherAddon.fishingController().isManualRetraction(); + Laby.fireEvent(new FishHookRetractEvent(manual)); + if (!manual) { + AutoFisherAddon.fishingController().setManualRetraction(true); + } + } + + @Inject( + method = "onSyncedDataUpdated", + at = @At( + value = "FIELD", + target = "Lnet/minecraft/world/entity/projectile/FishingHook;biting:Z", + opcode = PUTFIELD_OPCODE, + shift = Shift.AFTER + ) + ) + private void onFishBiting(EntityDataAccessor $$0, CallbackInfo ci) { + if (this.biting) { + Laby.fireEvent(new FishHookBiteEvent()); + } + } +} diff --git a/game-runner/src/v1_21_10/java/com/rappytv/autofisher/v1_21_10/VersionedFishingController.java b/game-runner/src/v1_21_10/java/com/rappytv/autofisher/v1_21_10/VersionedFishingController.java new file mode 100644 index 0000000..01e48d3 --- /dev/null +++ b/game-runner/src/v1_21_10/java/com/rappytv/autofisher/v1_21_10/VersionedFishingController.java @@ -0,0 +1,75 @@ +package com.rappytv.autofisher.v1_21_10; + +import com.rappytv.autofisher.FishingController; +import com.rappytv.autofisher.core.AutoFisherAddon; +import javax.inject.Singleton; +import net.labymod.api.models.Implements; +import net.minecraft.client.Minecraft; +import net.minecraft.client.multiplayer.MultiPlayerGameMode; +import net.minecraft.world.InteractionHand; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.entity.projectile.FishingHook; +import net.minecraft.world.item.FishingRodItem; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +@Singleton +@Implements(FishingController.class) +public class VersionedFishingController extends FishingController { + + @Override + public void castFishingRod() { + Player player = Minecraft.getInstance().player; + if (player == null) { + return; + } + InteractionHand hand = this.getFishingRodHand(player); + if (hand != null) { + this.useItem(hand); + } + } + + @Override + public void retractFishingRod() { + Player player = Minecraft.getInstance().player; + if (player == null) { + return; + } + FishingHook hook = player.fishing; + if (hook == null) { + return; + } + + InteractionHand hand = this.getFishingRodHand(player); + if (hand != null) { + AutoFisherAddon.fishingController().setManualRetraction(false); + this.useItem(hand); + } + } + + @Nullable + private InteractionHand getFishingRodHand(@NotNull Player player) { + if (player.getMainHandItem().getItem() instanceof FishingRodItem) { + return InteractionHand.MAIN_HAND; + } else if (player.getOffhandItem().getItem() instanceof FishingRodItem) { + return InteractionHand.OFF_HAND; + } + + return null; + } + + private void useItem(@NotNull InteractionHand hand) { + Player player = Minecraft.getInstance().player; + if (player == null) { + return; + } + + MultiPlayerGameMode gameMode = Minecraft.getInstance().gameMode; + if (gameMode == null) { + return; + } + + gameMode.useItem(player, hand); + player.swing(hand); + } +} diff --git a/game-runner/src/v1_21_10/java/com/rappytv/autofisher/v1_21_10/mixins/MixinFishingHook.java b/game-runner/src/v1_21_10/java/com/rappytv/autofisher/v1_21_10/mixins/MixinFishingHook.java new file mode 100644 index 0000000..d692f12 --- /dev/null +++ b/game-runner/src/v1_21_10/java/com/rappytv/autofisher/v1_21_10/mixins/MixinFishingHook.java @@ -0,0 +1,52 @@ +package com.rappytv.autofisher.v1_21_10.mixins; + +import com.rappytv.autofisher.core.AutoFisherAddon; +import com.rappytv.autofisher.event.FishHookBiteEvent; +import com.rappytv.autofisher.event.FishHookRetractEvent; +import net.labymod.api.Laby; +import net.minecraft.network.syncher.EntityDataAccessor; +import net.minecraft.world.entity.projectile.FishingHook; +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.At.Shift; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +@Mixin(FishingHook.class) +public class MixinFishingHook { + + @Unique + private static final int PUTFIELD_OPCODE = 181; + + @Shadow + private boolean biting; + + @Inject( + method = "onClientRemoval", + at = @At("TAIL") + ) + private void onRemove(CallbackInfo ci) { + boolean manual = AutoFisherAddon.fishingController().isManualRetraction(); + Laby.fireEvent(new FishHookRetractEvent(manual)); + if (!manual) { + AutoFisherAddon.fishingController().setManualRetraction(true); + } + } + + @Inject( + method = "onSyncedDataUpdated", + at = @At( + value = "FIELD", + target = "Lnet/minecraft/world/entity/projectile/FishingHook;biting:Z", + opcode = PUTFIELD_OPCODE, + shift = Shift.AFTER + ) + ) + private void onFishBiting(EntityDataAccessor $$0, CallbackInfo ci) { + if (this.biting) { + Laby.fireEvent(new FishHookBiteEvent()); + } + } +} diff --git a/game-runner/src/v1_21_3/java/com/rappytv/autofisher/v1_21_3/VersionedFishingController.java b/game-runner/src/v1_21_3/java/com/rappytv/autofisher/v1_21_3/VersionedFishingController.java new file mode 100644 index 0000000..5469c4d --- /dev/null +++ b/game-runner/src/v1_21_3/java/com/rappytv/autofisher/v1_21_3/VersionedFishingController.java @@ -0,0 +1,75 @@ +package com.rappytv.autofisher.v1_21_3; + +import com.rappytv.autofisher.FishingController; +import com.rappytv.autofisher.core.AutoFisherAddon; +import javax.inject.Singleton; +import net.labymod.api.models.Implements; +import net.minecraft.client.Minecraft; +import net.minecraft.client.multiplayer.MultiPlayerGameMode; +import net.minecraft.world.InteractionHand; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.entity.projectile.FishingHook; +import net.minecraft.world.item.FishingRodItem; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +@Singleton +@Implements(FishingController.class) +public class VersionedFishingController extends FishingController { + + @Override + public void castFishingRod() { + Player player = Minecraft.getInstance().player; + if (player == null) { + return; + } + InteractionHand hand = this.getFishingRodHand(player); + if (hand != null) { + this.useItem(hand); + } + } + + @Override + public void retractFishingRod() { + Player player = Minecraft.getInstance().player; + if (player == null) { + return; + } + FishingHook hook = player.fishing; + if (hook == null) { + return; + } + + InteractionHand hand = this.getFishingRodHand(player); + if (hand != null) { + AutoFisherAddon.fishingController().setManualRetraction(false); + this.useItem(hand); + } + } + + @Nullable + private InteractionHand getFishingRodHand(@NotNull Player player) { + if (player.getMainHandItem().getItem() instanceof FishingRodItem) { + return InteractionHand.MAIN_HAND; + } else if (player.getOffhandItem().getItem() instanceof FishingRodItem) { + return InteractionHand.OFF_HAND; + } + + return null; + } + + private void useItem(@NotNull InteractionHand hand) { + Player player = Minecraft.getInstance().player; + if (player == null) { + return; + } + + MultiPlayerGameMode gameMode = Minecraft.getInstance().gameMode; + if (gameMode == null) { + return; + } + + gameMode.useItem(player, hand); + player.swing(hand); + } +} diff --git a/game-runner/src/v1_21_3/java/com/rappytv/autofisher/v1_21_3/mixins/MixinFishingHook.java b/game-runner/src/v1_21_3/java/com/rappytv/autofisher/v1_21_3/mixins/MixinFishingHook.java new file mode 100644 index 0000000..8e72d3b --- /dev/null +++ b/game-runner/src/v1_21_3/java/com/rappytv/autofisher/v1_21_3/mixins/MixinFishingHook.java @@ -0,0 +1,52 @@ +package com.rappytv.autofisher.v1_21_3.mixins; + +import com.rappytv.autofisher.core.AutoFisherAddon; +import com.rappytv.autofisher.event.FishHookBiteEvent; +import com.rappytv.autofisher.event.FishHookRetractEvent; +import net.labymod.api.Laby; +import net.minecraft.network.syncher.EntityDataAccessor; +import net.minecraft.world.entity.projectile.FishingHook; +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.At.Shift; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +@Mixin(FishingHook.class) +public class MixinFishingHook { + + @Unique + private static final int PUTFIELD_OPCODE = 181; + + @Shadow + private boolean biting; + + @Inject( + method = "onClientRemoval", + at = @At("TAIL") + ) + private void onRemove(CallbackInfo ci) { + boolean manual = AutoFisherAddon.fishingController().isManualRetraction(); + Laby.fireEvent(new FishHookRetractEvent(manual)); + if (!manual) { + AutoFisherAddon.fishingController().setManualRetraction(true); + } + } + + @Inject( + method = "onSyncedDataUpdated", + at = @At( + value = "FIELD", + target = "Lnet/minecraft/world/entity/projectile/FishingHook;biting:Z", + opcode = PUTFIELD_OPCODE, + shift = Shift.AFTER + ) + ) + private void onFishBiting(EntityDataAccessor $$0, CallbackInfo ci) { + if (this.biting) { + Laby.fireEvent(new FishHookBiteEvent()); + } + } +} diff --git a/game-runner/src/v1_21_4/java/com/rappytv/autofisher/v1_21_4/VersionedFishingController.java b/game-runner/src/v1_21_4/java/com/rappytv/autofisher/v1_21_4/VersionedFishingController.java new file mode 100644 index 0000000..f4ff59b --- /dev/null +++ b/game-runner/src/v1_21_4/java/com/rappytv/autofisher/v1_21_4/VersionedFishingController.java @@ -0,0 +1,75 @@ +package com.rappytv.autofisher.v1_21_4; + +import com.rappytv.autofisher.FishingController; +import com.rappytv.autofisher.core.AutoFisherAddon; +import javax.inject.Singleton; +import net.labymod.api.models.Implements; +import net.minecraft.client.Minecraft; +import net.minecraft.client.multiplayer.MultiPlayerGameMode; +import net.minecraft.world.InteractionHand; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.entity.projectile.FishingHook; +import net.minecraft.world.item.FishingRodItem; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +@Singleton +@Implements(FishingController.class) +public class VersionedFishingController extends FishingController { + + @Override + public void castFishingRod() { + Player player = Minecraft.getInstance().player; + if (player == null) { + return; + } + InteractionHand hand = this.getFishingRodHand(player); + if (hand != null) { + this.useItem(hand); + } + } + + @Override + public void retractFishingRod() { + Player player = Minecraft.getInstance().player; + if (player == null) { + return; + } + FishingHook hook = player.fishing; + if (hook == null) { + return; + } + + InteractionHand hand = this.getFishingRodHand(player); + if (hand != null) { + AutoFisherAddon.fishingController().setManualRetraction(false); + this.useItem(hand); + } + } + + @Nullable + private InteractionHand getFishingRodHand(@NotNull Player player) { + if (player.getMainHandItem().getItem() instanceof FishingRodItem) { + return InteractionHand.MAIN_HAND; + } else if (player.getOffhandItem().getItem() instanceof FishingRodItem) { + return InteractionHand.OFF_HAND; + } + + return null; + } + + private void useItem(@NotNull InteractionHand hand) { + Player player = Minecraft.getInstance().player; + if (player == null) { + return; + } + + MultiPlayerGameMode gameMode = Minecraft.getInstance().gameMode; + if (gameMode == null) { + return; + } + + gameMode.useItem(player, hand); + player.swing(hand); + } +} diff --git a/game-runner/src/v1_21_4/java/com/rappytv/autofisher/v1_21_4/mixins/MixinFishingHook.java b/game-runner/src/v1_21_4/java/com/rappytv/autofisher/v1_21_4/mixins/MixinFishingHook.java new file mode 100644 index 0000000..16626ec --- /dev/null +++ b/game-runner/src/v1_21_4/java/com/rappytv/autofisher/v1_21_4/mixins/MixinFishingHook.java @@ -0,0 +1,52 @@ +package com.rappytv.autofisher.v1_21_4.mixins; + +import com.rappytv.autofisher.core.AutoFisherAddon; +import com.rappytv.autofisher.event.FishHookBiteEvent; +import com.rappytv.autofisher.event.FishHookRetractEvent; +import net.labymod.api.Laby; +import net.minecraft.network.syncher.EntityDataAccessor; +import net.minecraft.world.entity.projectile.FishingHook; +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.At.Shift; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +@Mixin(FishingHook.class) +public class MixinFishingHook { + + @Unique + private static final int PUTFIELD_OPCODE = 181; + + @Shadow + private boolean biting; + + @Inject( + method = "onClientRemoval", + at = @At("TAIL") + ) + private void onRemove(CallbackInfo ci) { + boolean manual = AutoFisherAddon.fishingController().isManualRetraction(); + Laby.fireEvent(new FishHookRetractEvent(manual)); + if (!manual) { + AutoFisherAddon.fishingController().setManualRetraction(true); + } + } + + @Inject( + method = "onSyncedDataUpdated", + at = @At( + value = "FIELD", + target = "Lnet/minecraft/world/entity/projectile/FishingHook;biting:Z", + opcode = PUTFIELD_OPCODE, + shift = Shift.AFTER + ) + ) + private void onFishBiting(EntityDataAccessor $$0, CallbackInfo ci) { + if (this.biting) { + Laby.fireEvent(new FishHookBiteEvent()); + } + } +} diff --git a/game-runner/src/v1_21_5/java/com/rappytv/autofisher/v1_21_5/VersionedFishingController.java b/game-runner/src/v1_21_5/java/com/rappytv/autofisher/v1_21_5/VersionedFishingController.java new file mode 100644 index 0000000..843ea35 --- /dev/null +++ b/game-runner/src/v1_21_5/java/com/rappytv/autofisher/v1_21_5/VersionedFishingController.java @@ -0,0 +1,75 @@ +package com.rappytv.autofisher.v1_21_5; + +import com.rappytv.autofisher.FishingController; +import com.rappytv.autofisher.core.AutoFisherAddon; +import javax.inject.Singleton; +import net.labymod.api.models.Implements; +import net.minecraft.client.Minecraft; +import net.minecraft.client.multiplayer.MultiPlayerGameMode; +import net.minecraft.world.InteractionHand; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.entity.projectile.FishingHook; +import net.minecraft.world.item.FishingRodItem; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +@Singleton +@Implements(FishingController.class) +public class VersionedFishingController extends FishingController { + + @Override + public void castFishingRod() { + Player player = Minecraft.getInstance().player; + if (player == null) { + return; + } + InteractionHand hand = this.getFishingRodHand(player); + if (hand != null) { + this.useItem(hand); + } + } + + @Override + public void retractFishingRod() { + Player player = Minecraft.getInstance().player; + if (player == null) { + return; + } + FishingHook hook = player.fishing; + if (hook == null) { + return; + } + + InteractionHand hand = this.getFishingRodHand(player); + if (hand != null) { + AutoFisherAddon.fishingController().setManualRetraction(false); + this.useItem(hand); + } + } + + @Nullable + private InteractionHand getFishingRodHand(@NotNull Player player) { + if (player.getMainHandItem().getItem() instanceof FishingRodItem) { + return InteractionHand.MAIN_HAND; + } else if (player.getOffhandItem().getItem() instanceof FishingRodItem) { + return InteractionHand.OFF_HAND; + } + + return null; + } + + private void useItem(@NotNull InteractionHand hand) { + Player player = Minecraft.getInstance().player; + if (player == null) { + return; + } + + MultiPlayerGameMode gameMode = Minecraft.getInstance().gameMode; + if (gameMode == null) { + return; + } + + gameMode.useItem(player, hand); + player.swing(hand); + } +} diff --git a/game-runner/src/v1_21_5/java/com/rappytv/autofisher/v1_21_5/mixins/MixinFishingHook.java b/game-runner/src/v1_21_5/java/com/rappytv/autofisher/v1_21_5/mixins/MixinFishingHook.java new file mode 100644 index 0000000..3591183 --- /dev/null +++ b/game-runner/src/v1_21_5/java/com/rappytv/autofisher/v1_21_5/mixins/MixinFishingHook.java @@ -0,0 +1,52 @@ +package com.rappytv.autofisher.v1_21_5.mixins; + +import com.rappytv.autofisher.core.AutoFisherAddon; +import com.rappytv.autofisher.event.FishHookBiteEvent; +import com.rappytv.autofisher.event.FishHookRetractEvent; +import net.labymod.api.Laby; +import net.minecraft.network.syncher.EntityDataAccessor; +import net.minecraft.world.entity.projectile.FishingHook; +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.At.Shift; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +@Mixin(FishingHook.class) +public class MixinFishingHook { + + @Unique + private static final int PUTFIELD_OPCODE = 181; + + @Shadow + private boolean biting; + + @Inject( + method = "onClientRemoval", + at = @At("TAIL") + ) + private void onRemove(CallbackInfo ci) { + boolean manual = AutoFisherAddon.fishingController().isManualRetraction(); + Laby.fireEvent(new FishHookRetractEvent(manual)); + if (!manual) { + AutoFisherAddon.fishingController().setManualRetraction(true); + } + } + + @Inject( + method = "onSyncedDataUpdated", + at = @At( + value = "FIELD", + target = "Lnet/minecraft/world/entity/projectile/FishingHook;biting:Z", + opcode = PUTFIELD_OPCODE, + shift = Shift.AFTER + ) + ) + private void onFishBiting(EntityDataAccessor $$0, CallbackInfo ci) { + if (this.biting) { + Laby.fireEvent(new FishHookBiteEvent()); + } + } +} diff --git a/game-runner/src/v1_21_8/java/com/rappytv/autofisher/v1_21_8/VersionedFishingController.java b/game-runner/src/v1_21_8/java/com/rappytv/autofisher/v1_21_8/VersionedFishingController.java new file mode 100644 index 0000000..61d4f5e --- /dev/null +++ b/game-runner/src/v1_21_8/java/com/rappytv/autofisher/v1_21_8/VersionedFishingController.java @@ -0,0 +1,75 @@ +package com.rappytv.autofisher.v1_21_8; + +import com.rappytv.autofisher.FishingController; +import com.rappytv.autofisher.core.AutoFisherAddon; +import javax.inject.Singleton; +import net.labymod.api.models.Implements; +import net.minecraft.client.Minecraft; +import net.minecraft.client.multiplayer.MultiPlayerGameMode; +import net.minecraft.world.InteractionHand; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.entity.projectile.FishingHook; +import net.minecraft.world.item.FishingRodItem; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +@Singleton +@Implements(FishingController.class) +public class VersionedFishingController extends FishingController { + + @Override + public void castFishingRod() { + Player player = Minecraft.getInstance().player; + if (player == null) { + return; + } + InteractionHand hand = this.getFishingRodHand(player); + if (hand != null) { + this.useItem(hand); + } + } + + @Override + public void retractFishingRod() { + Player player = Minecraft.getInstance().player; + if (player == null) { + return; + } + FishingHook hook = player.fishing; + if (hook == null) { + return; + } + + InteractionHand hand = this.getFishingRodHand(player); + if (hand != null) { + AutoFisherAddon.fishingController().setManualRetraction(false); + this.useItem(hand); + } + } + + @Nullable + private InteractionHand getFishingRodHand(@NotNull Player player) { + if (player.getMainHandItem().getItem() instanceof FishingRodItem) { + return InteractionHand.MAIN_HAND; + } else if (player.getOffhandItem().getItem() instanceof FishingRodItem) { + return InteractionHand.OFF_HAND; + } + + return null; + } + + private void useItem(@NotNull InteractionHand hand) { + Player player = Minecraft.getInstance().player; + if (player == null) { + return; + } + + MultiPlayerGameMode gameMode = Minecraft.getInstance().gameMode; + if (gameMode == null) { + return; + } + + gameMode.useItem(player, hand); + player.swing(hand); + } +} diff --git a/game-runner/src/v1_21_8/java/com/rappytv/autofisher/v1_21_8/mixins/MixinFishingHook.java b/game-runner/src/v1_21_8/java/com/rappytv/autofisher/v1_21_8/mixins/MixinFishingHook.java new file mode 100644 index 0000000..508e297 --- /dev/null +++ b/game-runner/src/v1_21_8/java/com/rappytv/autofisher/v1_21_8/mixins/MixinFishingHook.java @@ -0,0 +1,52 @@ +package com.rappytv.autofisher.v1_21_8.mixins; + +import com.rappytv.autofisher.core.AutoFisherAddon; +import com.rappytv.autofisher.event.FishHookBiteEvent; +import com.rappytv.autofisher.event.FishHookRetractEvent; +import net.labymod.api.Laby; +import net.minecraft.network.syncher.EntityDataAccessor; +import net.minecraft.world.entity.projectile.FishingHook; +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.At.Shift; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +@Mixin(FishingHook.class) +public class MixinFishingHook { + + @Unique + private static final int PUTFIELD_OPCODE = 181; + + @Shadow + private boolean biting; + + @Inject( + method = "onClientRemoval", + at = @At("TAIL") + ) + private void onRemove(CallbackInfo ci) { + boolean manual = AutoFisherAddon.fishingController().isManualRetraction(); + Laby.fireEvent(new FishHookRetractEvent(manual)); + if (!manual) { + AutoFisherAddon.fishingController().setManualRetraction(true); + } + } + + @Inject( + method = "onSyncedDataUpdated", + at = @At( + value = "FIELD", + target = "Lnet/minecraft/world/entity/projectile/FishingHook;biting:Z", + opcode = PUTFIELD_OPCODE, + shift = Shift.AFTER + ) + ) + private void onFishBiting(EntityDataAccessor $$0, CallbackInfo ci) { + if (this.biting) { + Laby.fireEvent(new FishHookBiteEvent()); + } + } +} diff --git a/gradle.properties b/gradle.properties index 44dc10b..9243d49 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,2 +1,2 @@ org.gradle.jvmargs=-Xmx4096m -net.labymod.minecraft-versions=1.8.9;1.12.2;1.16.5;1.17.1;1.18.2;1.19.2;1.19.3;1.19.4;1.20.1;1.20.2;1.20.4;1.20.5;1.20.6;1.21;1.21.1;1.21.3;1.21.4;1.21.5 \ No newline at end of file +net.labymod.minecraft-versions=1.8.9;1.12.2;1.16.5;1.17.1;1.18.2;1.19.2;1.19.3;1.19.4;1.20.1;1.20.2;1.20.4;1.20.5;1.20.6;1.21;1.21.1;1.21.3;1.21.4;1.21.5;1.21.8;1.21.10 \ No newline at end of file diff --git a/readme.md b/readme.md new file mode 100644 index 0000000..971dce7 --- /dev/null +++ b/readme.md @@ -0,0 +1,11 @@ +# AutoFisher +![Downloads](https://labybadges-delta.vercel.app/api/downloads/autofisher/formatted)
+Completely automate the way your fishing rod works + +### 📦 Installation +1. Press `Win` + `R` +2. Paste this into the window that popped up: `%appdata%/.minecraft/LabyMod-neo/addons` and press enter +3. It should open your LabyMod addon directory; Paste the [AutoFisher.jar](https://github.com/RappyLabyAddons/AutoFisher/releases/latest/download/AutoFisher.jar) in there. +4. Launch your LabyMod client. + +ℹ️ If you have any problems with the addon/have update ideas, feel free to open an Issue [here](https://github.com/RappyLabyAddons/AutoFisher/issues/new)! \ No newline at end of file diff --git a/settings.gradle.kts b/settings.gradle.kts index 6a0b6df..209290c 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -1,4 +1,4 @@ -rootProject.name = "labymod4-addon-template" +rootProject.name = "autofisher" pluginManagement { val labyGradlePluginVersion = "0.5.9"