├── .gitignore ├── images └── logo.png ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── src └── main │ ├── resources │ ├── farmhelper │ │ ├── icon-mod │ │ │ ├── icon.png │ │ │ └── rat.png │ │ ├── sounds │ │ │ ├── loud_buzz.wav │ │ │ ├── AAAAAAAAAA.wav │ │ │ ├── metal_pipe.wav │ │ │ └── staff_check_voice_notification.wav │ │ ├── textures │ │ │ └── gui │ │ │ │ ├── bps.png │ │ │ │ ├── enw.png │ │ │ │ ├── mnw.png │ │ │ │ ├── cropie.png │ │ │ │ ├── ecane.png │ │ │ │ ├── emelon.png │ │ │ │ ├── eseeds.png │ │ │ │ ├── profit.png │ │ │ │ ├── squash.png │ │ │ │ ├── test.png │ │ │ │ ├── ecactus.png │ │ │ │ ├── ecarrot.png │ │ │ │ ├── ehaybale.png │ │ │ │ ├── epotato.png │ │ │ │ ├── epumpkin.png │ │ │ │ ├── fermento.png │ │ │ │ ├── profithr.png │ │ │ │ ├── runtime.png │ │ │ │ ├── ecocoabeans.png │ │ │ │ ├── eredmushroom.png │ │ │ │ ├── burrowingspores.png │ │ │ │ └── ebrownmushroom.png │ │ └── movrec │ │ │ ├── ITEM_CHANGE_4.movement │ │ │ ├── ITEM_CHANGE_1.movement │ │ │ ├── ROTATION_CHECK_Continue_1.movement │ │ │ └── ITEM_CHANGE_2.movement │ ├── mcmod.info │ └── mixins.farmhelperv2.json │ └── java │ └── com │ └── jelly │ └── farmhelperv2 │ ├── remote │ ├── command │ │ ├── commands │ │ │ ├── Command.java │ │ │ └── impl │ │ │ │ ├── DisconnectCommand.java │ │ │ │ ├── ReconnectCommand.java │ │ │ │ ├── InfoCommand.java │ │ │ │ ├── AutoSellCommand.java │ │ │ │ ├── ScreenshotCommand.java │ │ │ │ ├── ToggleCommand.java │ │ │ │ └── SendCommandCommand.java │ │ └── discordCommands │ │ │ ├── Option.java │ │ │ ├── impl │ │ │ ├── Help.java │ │ │ ├── Toggle.java │ │ │ ├── AutoSell.java │ │ │ ├── SetSpeed.java │ │ │ ├── SendCommand.java │ │ │ ├── Disconnect.java │ │ │ └── Screenshot.java │ │ │ └── DiscordCommand.java │ ├── util │ │ └── RemoteUtils.java │ ├── struct │ │ ├── RemoteMessage.java │ │ ├── WebsocketClient.java │ │ └── WebsocketServer.java │ ├── waiter │ │ ├── Waiter.java │ │ └── WaiterHandler.java │ └── event │ │ ├── InteractionAutoComplete.java │ │ └── InteractionCreate.java │ ├── event │ ├── MillisecondEvent.java │ ├── SendPacketEvent.java │ ├── ReceivePacketEvent.java │ ├── UpdateScoreboardLineEvent.java │ ├── DrawScreenAfterEvent.java │ ├── UpdateTablistFooterEvent.java │ ├── InventoryInputEvent.java │ ├── UpdateTablistEvent.java │ ├── ChunkServerLoadEvent.java │ ├── PlayerDestroyBlockEvent.java │ ├── ClickedBlockEvent.java │ ├── UpdateScoreboardListEvent.java │ ├── BlockChangeEvent.java │ ├── MotionUpdateEvent.java │ ├── SpawnObjectEvent.java │ └── SpawnParticleEvent.java │ ├── mixin │ ├── block │ │ ├── IBlockAccessor.java │ │ ├── MixinBlockCrops.java │ │ ├── MixinBlockNetherWart.java │ │ ├── MixinBlockCocoa.java │ │ ├── MixinBlockMushroom.java │ │ └── MixinBlockRendererDispatcher.java │ ├── client │ │ ├── EntityPlayerAccessor.java │ │ ├── MinecraftAccessor.java │ │ ├── EntityPlayerSPAccessor.java │ │ ├── MixinChunk.java │ │ ├── MixinSoundManager.java │ │ ├── MixinMouse.java │ │ ├── MixinKeyBinding.java │ │ ├── MixinEntity.java │ │ ├── MixinEntityPlayerSP.java │ │ ├── MixinScoreboard.java │ │ └── MixinPlayerControllerMP.java │ ├── gui │ │ ├── IGuiPlayerTabOverlayAccessor.java │ │ ├── AccessorGuiEditSign.java │ │ ├── MixinGuiContainer.java │ │ ├── MixinGuiMainMenu.java │ │ └── MixinGuiMultiplayer.java │ ├── pathfinder │ │ ├── PathfinderAccessor.java │ │ └── MixinChunkProviderClient.java │ ├── render │ │ ├── MixinEffectRenderer.java │ │ ├── MixinActiveRenderInfo.java │ │ ├── MixinRenderManager.java │ │ ├── MixinModelBiped.java │ │ └── MixinEntityRenderer.java │ └── fml │ │ └── MixinFMLHandshakeMessage.java │ ├── util │ ├── AvatarUtils.java │ ├── helper │ │ ├── BaritoneEventListener.java │ │ ├── Rotation.java │ │ ├── SignUtils.java │ │ ├── TickTask.java │ │ ├── Timer.java │ │ ├── Target.java │ │ ├── Clock.java │ │ └── RotationConfiguration.java │ ├── APIUtils.java │ ├── ReflectionUtils.java │ ├── TablistUtils.java │ ├── MarkdownFormatter.java │ ├── OldRotationUtils.java │ └── ScoreboardUtils.java │ ├── transformer │ ├── FMLCore.java │ ├── Tweaker.java │ └── NetworkManagerTransformer.java │ ├── feature │ ├── IFeature.java │ └── impl │ │ ├── PerformanceMode.java │ │ ├── Proxy.java │ │ ├── UngrabMouse.java │ │ ├── LeaveTimer.java │ │ └── RancherSpeedSetter.java │ ├── config │ ├── struct │ │ └── Rewarp.java │ └── page │ │ └── CustomFailsafeMessagesPage.java │ ├── failsafe │ ├── Failsafe.java │ └── impl │ │ └── DisconnectFailsafe.java │ ├── hud │ └── UsageStatsHUD.java │ ├── command │ └── RewarpCommand.java │ ├── pathfinder │ └── FlyNodeProcessor.java │ └── handler │ └── BaritoneHandler.java ├── gradle.properties ├── .github └── dependabot.yml ├── settings.gradle.kts ├── gradlew.bat └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | .idea/ 2 | .vscode/ 3 | run/ 4 | build/ 5 | .gradle/ 6 | *.swp -------------------------------------------------------------------------------- /images/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JellyLabScripts/FarmHelper/HEAD/images/logo.png -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JellyLabScripts/FarmHelper/HEAD/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /src/main/resources/farmhelper/icon-mod/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JellyLabScripts/FarmHelper/HEAD/src/main/resources/farmhelper/icon-mod/icon.png -------------------------------------------------------------------------------- /src/main/resources/farmhelper/icon-mod/rat.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JellyLabScripts/FarmHelper/HEAD/src/main/resources/farmhelper/icon-mod/rat.png -------------------------------------------------------------------------------- /src/main/resources/farmhelper/sounds/loud_buzz.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JellyLabScripts/FarmHelper/HEAD/src/main/resources/farmhelper/sounds/loud_buzz.wav -------------------------------------------------------------------------------- /src/main/resources/farmhelper/textures/gui/bps.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JellyLabScripts/FarmHelper/HEAD/src/main/resources/farmhelper/textures/gui/bps.png -------------------------------------------------------------------------------- /src/main/resources/farmhelper/textures/gui/enw.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JellyLabScripts/FarmHelper/HEAD/src/main/resources/farmhelper/textures/gui/enw.png -------------------------------------------------------------------------------- /src/main/resources/farmhelper/textures/gui/mnw.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JellyLabScripts/FarmHelper/HEAD/src/main/resources/farmhelper/textures/gui/mnw.png -------------------------------------------------------------------------------- /src/main/resources/farmhelper/sounds/AAAAAAAAAA.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JellyLabScripts/FarmHelper/HEAD/src/main/resources/farmhelper/sounds/AAAAAAAAAA.wav -------------------------------------------------------------------------------- /src/main/resources/farmhelper/sounds/metal_pipe.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JellyLabScripts/FarmHelper/HEAD/src/main/resources/farmhelper/sounds/metal_pipe.wav -------------------------------------------------------------------------------- /src/main/resources/farmhelper/textures/gui/cropie.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JellyLabScripts/FarmHelper/HEAD/src/main/resources/farmhelper/textures/gui/cropie.png -------------------------------------------------------------------------------- /src/main/resources/farmhelper/textures/gui/ecane.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JellyLabScripts/FarmHelper/HEAD/src/main/resources/farmhelper/textures/gui/ecane.png -------------------------------------------------------------------------------- /src/main/resources/farmhelper/textures/gui/emelon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JellyLabScripts/FarmHelper/HEAD/src/main/resources/farmhelper/textures/gui/emelon.png -------------------------------------------------------------------------------- /src/main/resources/farmhelper/textures/gui/eseeds.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JellyLabScripts/FarmHelper/HEAD/src/main/resources/farmhelper/textures/gui/eseeds.png -------------------------------------------------------------------------------- /src/main/resources/farmhelper/textures/gui/profit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JellyLabScripts/FarmHelper/HEAD/src/main/resources/farmhelper/textures/gui/profit.png -------------------------------------------------------------------------------- /src/main/resources/farmhelper/textures/gui/squash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JellyLabScripts/FarmHelper/HEAD/src/main/resources/farmhelper/textures/gui/squash.png -------------------------------------------------------------------------------- /src/main/resources/farmhelper/textures/gui/test.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JellyLabScripts/FarmHelper/HEAD/src/main/resources/farmhelper/textures/gui/test.png -------------------------------------------------------------------------------- /src/main/resources/farmhelper/textures/gui/ecactus.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JellyLabScripts/FarmHelper/HEAD/src/main/resources/farmhelper/textures/gui/ecactus.png -------------------------------------------------------------------------------- /src/main/resources/farmhelper/textures/gui/ecarrot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JellyLabScripts/FarmHelper/HEAD/src/main/resources/farmhelper/textures/gui/ecarrot.png -------------------------------------------------------------------------------- /src/main/resources/farmhelper/textures/gui/ehaybale.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JellyLabScripts/FarmHelper/HEAD/src/main/resources/farmhelper/textures/gui/ehaybale.png -------------------------------------------------------------------------------- /src/main/resources/farmhelper/textures/gui/epotato.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JellyLabScripts/FarmHelper/HEAD/src/main/resources/farmhelper/textures/gui/epotato.png -------------------------------------------------------------------------------- /src/main/resources/farmhelper/textures/gui/epumpkin.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JellyLabScripts/FarmHelper/HEAD/src/main/resources/farmhelper/textures/gui/epumpkin.png -------------------------------------------------------------------------------- /src/main/resources/farmhelper/textures/gui/fermento.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JellyLabScripts/FarmHelper/HEAD/src/main/resources/farmhelper/textures/gui/fermento.png -------------------------------------------------------------------------------- /src/main/resources/farmhelper/textures/gui/profithr.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JellyLabScripts/FarmHelper/HEAD/src/main/resources/farmhelper/textures/gui/profithr.png -------------------------------------------------------------------------------- /src/main/resources/farmhelper/textures/gui/runtime.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JellyLabScripts/FarmHelper/HEAD/src/main/resources/farmhelper/textures/gui/runtime.png -------------------------------------------------------------------------------- /src/main/resources/farmhelper/textures/gui/ecocoabeans.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JellyLabScripts/FarmHelper/HEAD/src/main/resources/farmhelper/textures/gui/ecocoabeans.png -------------------------------------------------------------------------------- /src/main/resources/farmhelper/textures/gui/eredmushroom.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JellyLabScripts/FarmHelper/HEAD/src/main/resources/farmhelper/textures/gui/eredmushroom.png -------------------------------------------------------------------------------- /src/main/resources/farmhelper/textures/gui/burrowingspores.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JellyLabScripts/FarmHelper/HEAD/src/main/resources/farmhelper/textures/gui/burrowingspores.png -------------------------------------------------------------------------------- /src/main/resources/farmhelper/textures/gui/ebrownmushroom.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JellyLabScripts/FarmHelper/HEAD/src/main/resources/farmhelper/textures/gui/ebrownmushroom.png -------------------------------------------------------------------------------- /src/main/resources/farmhelper/sounds/staff_check_voice_notification.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JellyLabScripts/FarmHelper/HEAD/src/main/resources/farmhelper/sounds/staff_check_voice_notification.wav -------------------------------------------------------------------------------- /gradle.properties: -------------------------------------------------------------------------------- 1 | loom.platform=forge 2 | org.gradle.jvmargs=-Xmx2g 3 | baseGroup=com.jelly.farmhelperv2 4 | mcVersion=1.8.9 5 | modid=farmhelperv2 6 | modName=FarmHelper 7 | version=2.9.7-pre6 8 | shouldRelease=true 9 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.3-bin.zip 4 | networkTimeout=10000 5 | validateDistributionUrl=true 6 | zipStoreBase=GRADLE_USER_HOME 7 | zipStorePath=wrapper/dists 8 | hotspotTag=jdk8u102-b31 9 | -------------------------------------------------------------------------------- /src/main/java/com/jelly/farmhelperv2/remote/command/commands/Command.java: -------------------------------------------------------------------------------- 1 | package com.jelly.farmhelperv2.remote.command.commands; 2 | 3 | import java.lang.annotation.Retention; 4 | import java.lang.annotation.RetentionPolicy; 5 | 6 | @Retention(RetentionPolicy.RUNTIME) 7 | public @interface Command { 8 | String label(); 9 | } 10 | -------------------------------------------------------------------------------- /src/main/java/com/jelly/farmhelperv2/event/MillisecondEvent.java: -------------------------------------------------------------------------------- 1 | package com.jelly.farmhelperv2.event; 2 | 3 | import net.minecraftforge.fml.common.eventhandler.Event; 4 | 5 | public class MillisecondEvent extends Event { 6 | public long timestamp; 7 | 8 | public MillisecondEvent() { 9 | timestamp = System.currentTimeMillis(); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/main/java/com/jelly/farmhelperv2/mixin/block/IBlockAccessor.java: -------------------------------------------------------------------------------- 1 | package com.jelly.farmhelperv2.mixin.block; 2 | 3 | import net.minecraft.block.Block; 4 | import org.spongepowered.asm.mixin.Mixin; 5 | import org.spongepowered.asm.mixin.gen.Accessor; 6 | 7 | @Mixin(Block.class) 8 | public interface IBlockAccessor { 9 | @Accessor 10 | void setMaxY(double maxY); 11 | } -------------------------------------------------------------------------------- /src/main/java/com/jelly/farmhelperv2/event/SendPacketEvent.java: -------------------------------------------------------------------------------- 1 | package com.jelly.farmhelperv2.event; 2 | 3 | import net.minecraft.network.Packet; 4 | import net.minecraftforge.fml.common.eventhandler.Event; 5 | 6 | public class SendPacketEvent extends Event { 7 | public Packet packet; 8 | 9 | public SendPacketEvent(Packet packet) { 10 | this.packet = packet; 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/main/java/com/jelly/farmhelperv2/event/ReceivePacketEvent.java: -------------------------------------------------------------------------------- 1 | package com.jelly.farmhelperv2.event; 2 | 3 | import net.minecraft.network.Packet; 4 | import net.minecraftforge.fml.common.eventhandler.Event; 5 | 6 | public class ReceivePacketEvent extends Event { 7 | public Packet packet; 8 | 9 | public ReceivePacketEvent(Packet packet) { 10 | this.packet = packet; 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/main/java/com/jelly/farmhelperv2/mixin/client/EntityPlayerAccessor.java: -------------------------------------------------------------------------------- 1 | package com.jelly.farmhelperv2.mixin.client; 2 | 3 | import net.minecraft.entity.player.EntityPlayer; 4 | import org.spongepowered.asm.mixin.Mixin; 5 | import org.spongepowered.asm.mixin.gen.Accessor; 6 | 7 | @Mixin(EntityPlayer.class) 8 | public interface EntityPlayerAccessor { 9 | @Accessor 10 | int getFlyToggleTimer(); 11 | } 12 | -------------------------------------------------------------------------------- /src/main/java/com/jelly/farmhelperv2/event/UpdateScoreboardLineEvent.java: -------------------------------------------------------------------------------- 1 | package com.jelly.farmhelperv2.event; 2 | 3 | import lombok.Getter; 4 | import net.minecraftforge.fml.common.eventhandler.Event; 5 | 6 | @Getter 7 | public class UpdateScoreboardLineEvent extends Event { 8 | private final String line; 9 | 10 | public UpdateScoreboardLineEvent(String line) { 11 | this.line = line; 12 | } 13 | 14 | } 15 | -------------------------------------------------------------------------------- /src/main/java/com/jelly/farmhelperv2/util/AvatarUtils.java: -------------------------------------------------------------------------------- 1 | package com.jelly.farmhelperv2.util; 2 | 3 | public class AvatarUtils { 4 | public static String getAvatarUrl(String uuid) { 5 | return "https://api.mineatar.io/face/" + uuid + "?scale=32"; 6 | } 7 | 8 | public static String getFullBodyUrl(String uuid) { 9 | return "https://api.mineatar.io/body/full/" + uuid + "?scale=32"; 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/main/java/com/jelly/farmhelperv2/event/DrawScreenAfterEvent.java: -------------------------------------------------------------------------------- 1 | package com.jelly.farmhelperv2.event; 2 | 3 | import net.minecraft.client.gui.GuiScreen; 4 | import net.minecraftforge.fml.common.eventhandler.Event; 5 | 6 | public class DrawScreenAfterEvent extends Event { 7 | public GuiScreen guiScreen; 8 | 9 | public DrawScreenAfterEvent(GuiScreen guiScreen) { 10 | this.guiScreen = guiScreen; 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/main/java/com/jelly/farmhelperv2/event/UpdateTablistFooterEvent.java: -------------------------------------------------------------------------------- 1 | package com.jelly.farmhelperv2.event; 2 | 3 | import net.minecraftforge.fml.common.eventhandler.Event; 4 | 5 | import java.util.List; 6 | 7 | public class UpdateTablistFooterEvent extends Event { 8 | public final List footer; 9 | 10 | public UpdateTablistFooterEvent(List footer) { 11 | this.footer = footer; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/main/java/com/jelly/farmhelperv2/remote/util/RemoteUtils.java: -------------------------------------------------------------------------------- 1 | package com.jelly.farmhelperv2.remote.util; 2 | 3 | import java.util.ArrayList; 4 | import java.util.Optional; 5 | import java.util.function.Predicate; 6 | 7 | public class RemoteUtils { 8 | public static Optional getCommand(ArrayList commands, Predicate predicate) { 9 | return commands.stream().filter(predicate).findFirst(); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/main/resources/mcmod.info: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "modid": "${modid}", 4 | "name": "FarmHelper V2", 5 | "description": "A helper for every farmer", 6 | "version": "${version}", 7 | "mcversion": "${mcversion}", 8 | "url": "", 9 | "updateUrl": "", 10 | "authorList": [ 11 | "You" 12 | ], 13 | "credits": "", 14 | "logoFile": "", 15 | "screenshots": [], 16 | "dependencies": [] 17 | } 18 | ] -------------------------------------------------------------------------------- /src/main/java/com/jelly/farmhelperv2/util/helper/BaritoneEventListener.java: -------------------------------------------------------------------------------- 1 | package com.jelly.farmhelperv2.util.helper; 2 | 3 | import baritone.api.behavior.IBehavior; 4 | import baritone.api.event.events.PathEvent; 5 | 6 | public class BaritoneEventListener implements IBehavior { 7 | public static PathEvent pathEvent; 8 | @Override 9 | public void onPathEvent(PathEvent event) { 10 | pathEvent = event; 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/main/java/com/jelly/farmhelperv2/event/InventoryInputEvent.java: -------------------------------------------------------------------------------- 1 | package com.jelly.farmhelperv2.event; 2 | 3 | import lombok.Getter; 4 | import net.minecraftforge.fml.common.eventhandler.Event; 5 | 6 | @Getter 7 | public class InventoryInputEvent extends Event { 8 | private final int keyCode; 9 | private final char typedChar; 10 | 11 | public InventoryInputEvent(int keyCode, char typedChar) { 12 | this.keyCode = keyCode; 13 | this.typedChar = typedChar; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/main/java/com/jelly/farmhelperv2/event/UpdateTablistEvent.java: -------------------------------------------------------------------------------- 1 | package com.jelly.farmhelperv2.event; 2 | 3 | import net.minecraftforge.fml.common.eventhandler.Event; 4 | 5 | import java.util.List; 6 | 7 | public class UpdateTablistEvent extends Event { 8 | public final List tablist; 9 | public final long timestamp; 10 | 11 | public UpdateTablistEvent(List tablist, long timestamp) { 12 | this.tablist = tablist; 13 | this.timestamp = timestamp; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/main/java/com/jelly/farmhelperv2/mixin/client/MinecraftAccessor.java: -------------------------------------------------------------------------------- 1 | package com.jelly.farmhelperv2.mixin.client; 2 | 3 | import net.minecraft.client.Minecraft; 4 | import net.minecraft.util.Timer; 5 | import org.spongepowered.asm.mixin.Mixin; 6 | import org.spongepowered.asm.mixin.gen.Accessor; 7 | 8 | @Mixin(Minecraft.class) 9 | public interface MinecraftAccessor { 10 | @Accessor("timer") 11 | Timer getTimer(); 12 | 13 | @Accessor("leftClickCounter") 14 | void setLeftClickCounter(int leftClickCounter); 15 | } -------------------------------------------------------------------------------- /src/main/java/com/jelly/farmhelperv2/mixin/gui/IGuiPlayerTabOverlayAccessor.java: -------------------------------------------------------------------------------- 1 | package com.jelly.farmhelperv2.mixin.gui; 2 | 3 | import net.minecraft.client.gui.GuiPlayerTabOverlay; 4 | import net.minecraft.util.IChatComponent; 5 | import org.spongepowered.asm.mixin.Mixin; 6 | import org.spongepowered.asm.mixin.gen.Accessor; 7 | 8 | @Mixin(GuiPlayerTabOverlay.class) 9 | public interface IGuiPlayerTabOverlayAccessor { 10 | @Accessor 11 | IChatComponent getFooter(); 12 | 13 | @Accessor 14 | IChatComponent getHeader(); 15 | } 16 | -------------------------------------------------------------------------------- /src/main/java/com/jelly/farmhelperv2/event/ChunkServerLoadEvent.java: -------------------------------------------------------------------------------- 1 | package com.jelly.farmhelperv2.event; 2 | 3 | import lombok.Getter; 4 | import net.minecraft.world.chunk.Chunk; 5 | import net.minecraftforge.fml.common.eventhandler.Event; 6 | 7 | @Getter 8 | public class ChunkServerLoadEvent extends Event { 9 | public int x; 10 | public int z; 11 | public Chunk chunk; 12 | 13 | public ChunkServerLoadEvent(int x, int z, Chunk c) { 14 | this.x = x; 15 | this.z = z; 16 | this.chunk = c; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | # To get started with Dependabot version updates, you'll need to specify which 2 | # package ecosystems to update and where the package manifests are located. 3 | # Please see the documentation for all configuration options: 4 | # https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates 5 | 6 | version: 2 7 | updates: 8 | - package-ecosystem: "gradle" # See documentation for possible values 9 | directory: "/" # Location of package manifests 10 | schedule: 11 | interval: "weekly" 12 | -------------------------------------------------------------------------------- /src/main/java/com/jelly/farmhelperv2/mixin/client/EntityPlayerSPAccessor.java: -------------------------------------------------------------------------------- 1 | package com.jelly.farmhelperv2.mixin.client; 2 | 3 | import net.minecraft.client.entity.EntityPlayerSP; 4 | import org.spongepowered.asm.mixin.Mixin; 5 | import org.spongepowered.asm.mixin.gen.Accessor; 6 | 7 | @Mixin(EntityPlayerSP.class) 8 | public interface EntityPlayerSPAccessor { 9 | @Accessor 10 | float getLastReportedYaw(); 11 | 12 | @Accessor 13 | void setLastReportedYaw(float lastReportedYaw); 14 | 15 | @Accessor 16 | float getLastReportedPitch(); 17 | 18 | @Accessor 19 | void setLastReportedPitch(float lastReportedPitch); 20 | } 21 | -------------------------------------------------------------------------------- /src/main/java/com/jelly/farmhelperv2/mixin/pathfinder/PathfinderAccessor.java: -------------------------------------------------------------------------------- 1 | package com.jelly.farmhelperv2.mixin.pathfinder; 2 | 3 | import net.minecraft.entity.Entity; 4 | import net.minecraft.pathfinding.PathEntity; 5 | import net.minecraft.pathfinding.PathFinder; 6 | import net.minecraft.world.IBlockAccess; 7 | import org.spongepowered.asm.mixin.Mixin; 8 | import org.spongepowered.asm.mixin.gen.Invoker; 9 | 10 | @Mixin(PathFinder.class) 11 | public interface PathfinderAccessor { 12 | @Invoker("createEntityPathTo") 13 | public abstract PathEntity createPath(IBlockAccess blockaccess, Entity entityIn, double x, double y, double z, float distance); 14 | } 15 | -------------------------------------------------------------------------------- /src/main/java/com/jelly/farmhelperv2/event/PlayerDestroyBlockEvent.java: -------------------------------------------------------------------------------- 1 | package com.jelly.farmhelperv2.event; 2 | 3 | import net.minecraft.block.Block; 4 | import net.minecraft.util.BlockPos; 5 | import net.minecraft.util.EnumFacing; 6 | import net.minecraftforge.fml.common.eventhandler.Event; 7 | 8 | public class PlayerDestroyBlockEvent extends Event { 9 | public final BlockPos pos; 10 | public final EnumFacing facing; 11 | public final Block block; 12 | 13 | public PlayerDestroyBlockEvent(BlockPos pos, EnumFacing facing, Block block) { 14 | this.pos = pos; 15 | this.facing = facing; 16 | this.block = block; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/main/java/com/jelly/farmhelperv2/mixin/gui/AccessorGuiEditSign.java: -------------------------------------------------------------------------------- 1 | package com.jelly.farmhelperv2.mixin.gui; 2 | 3 | import net.minecraft.client.gui.GuiButton; 4 | import net.minecraft.client.gui.inventory.GuiEditSign; 5 | import net.minecraft.tileentity.TileEntitySign; 6 | import org.spongepowered.asm.mixin.Mixin; 7 | import org.spongepowered.asm.mixin.gen.Accessor; 8 | import org.spongepowered.asm.mixin.gen.Invoker; 9 | 10 | @Mixin(GuiEditSign.class) 11 | public interface AccessorGuiEditSign { 12 | @Accessor("tileSign") 13 | TileEntitySign getTileSign(); 14 | 15 | @Invoker("actionPerformed") 16 | void invokeActionPerformed(GuiButton button); 17 | } 18 | -------------------------------------------------------------------------------- /src/main/java/com/jelly/farmhelperv2/event/ClickedBlockEvent.java: -------------------------------------------------------------------------------- 1 | package com.jelly.farmhelperv2.event; 2 | 3 | import lombok.Getter; 4 | import net.minecraft.block.Block; 5 | import net.minecraft.util.BlockPos; 6 | import net.minecraft.util.EnumFacing; 7 | import net.minecraftforge.fml.common.eventhandler.Event; 8 | 9 | @Getter 10 | public class ClickedBlockEvent extends Event { 11 | private final BlockPos pos; 12 | private final EnumFacing facing; 13 | private final Block block; 14 | 15 | public ClickedBlockEvent(BlockPos pos, EnumFacing facing, Block block) { 16 | this.pos = pos; 17 | this.facing = facing; 18 | this.block = block; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /settings.gradle.kts: -------------------------------------------------------------------------------- 1 | pluginManagement { 2 | repositories { 3 | maven("https://repo.polyfrost.cc/releases") 4 | mavenCentral() 5 | gradlePluginPortal() 6 | maven("https://oss.sonatype.org/content/repositories/snapshots") 7 | maven("https://maven.architectury.dev/") 8 | maven("https://maven.fabricmc.net") 9 | maven("https://maven.minecraftforge.net/") 10 | maven("https://repo.spongepowered.org/maven/") 11 | maven("https://repo.sk1er.club/repository/maven-releases/") 12 | maven("https://repo.essential.gg/repository/maven-public/") 13 | maven("https://jitpack.io/") 14 | } 15 | } 16 | 17 | rootProject.name = "FarmHelperV2" -------------------------------------------------------------------------------- /src/main/java/com/jelly/farmhelperv2/event/UpdateScoreboardListEvent.java: -------------------------------------------------------------------------------- 1 | package com.jelly.farmhelperv2.event; 2 | 3 | import net.minecraftforge.fml.common.eventhandler.Event; 4 | 5 | import java.util.List; 6 | 7 | public class UpdateScoreboardListEvent extends Event { 8 | public final List scoreboardLines; 9 | public final List cleanScoreboardLines; 10 | public final long timestamp; 11 | 12 | public UpdateScoreboardListEvent(List scoreboardLines, List cleanScoreboardLines, long timestamp) { 13 | this.scoreboardLines = scoreboardLines; 14 | this.cleanScoreboardLines = cleanScoreboardLines; 15 | this.timestamp = timestamp; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/main/java/com/jelly/farmhelperv2/remote/command/discordCommands/Option.java: -------------------------------------------------------------------------------- 1 | package com.jelly.farmhelperv2.remote.command.discordCommands; 2 | 3 | import net.dv8tion.jda.api.interactions.commands.OptionType; 4 | 5 | public class Option { 6 | public OptionType type; 7 | public String name; 8 | public String description; 9 | public boolean required; 10 | public boolean autocomplete; 11 | 12 | public Option(OptionType type, String name, String description, boolean required, boolean autocomplete) { 13 | this.type = type; 14 | this.name = name; 15 | this.description = description; 16 | this.required = required; 17 | this.autocomplete = autocomplete; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/main/java/com/jelly/farmhelperv2/remote/struct/RemoteMessage.java: -------------------------------------------------------------------------------- 1 | package com.jelly.farmhelperv2.remote.struct; 2 | 3 | import com.google.gson.JsonObject; 4 | import com.google.gson.annotations.Expose; 5 | 6 | public class RemoteMessage { 7 | @Expose 8 | public String command; 9 | @Expose 10 | public JsonObject args; 11 | @Expose 12 | public String embed; 13 | 14 | public RemoteMessage(String command, JsonObject args) { 15 | this.command = command; 16 | this.args = args; 17 | } 18 | 19 | public RemoteMessage(String command, JsonObject args, String embed) { 20 | this.command = command; 21 | this.args = args; 22 | this.embed = embed; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/main/java/com/jelly/farmhelperv2/event/BlockChangeEvent.java: -------------------------------------------------------------------------------- 1 | package com.jelly.farmhelperv2.event; 2 | 3 | import net.minecraft.block.state.IBlockState; 4 | import net.minecraft.util.BlockPos; 5 | import net.minecraft.world.IBlockAccess; 6 | import net.minecraftforge.fml.common.eventhandler.Event; 7 | import org.jetbrains.annotations.NotNull; 8 | 9 | public class BlockChangeEvent extends Event { 10 | public BlockPos pos; 11 | public IBlockState old; 12 | public IBlockState update; 13 | public IBlockAccess world; 14 | 15 | public BlockChangeEvent(@NotNull BlockPos pos, @NotNull IBlockState old, @NotNull IBlockState update, @NotNull IBlockAccess world) { 16 | this.pos = pos; 17 | this.old = old; 18 | this.update = update; 19 | this.world = world; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/main/java/com/jelly/farmhelperv2/transformer/FMLCore.java: -------------------------------------------------------------------------------- 1 | package com.jelly.farmhelperv2.transformer; 2 | 3 | import net.minecraftforge.fml.relauncher.IFMLLoadingPlugin; 4 | 5 | import java.util.Map; 6 | 7 | public class FMLCore implements IFMLLoadingPlugin { 8 | public FMLCore() { 9 | } 10 | 11 | @Override 12 | public String[] getASMTransformerClass() { 13 | return new String[]{NetworkManagerTransformer.class.getName()}; 14 | } 15 | 16 | @Override 17 | public String getModContainerClass() { 18 | return null; 19 | } 20 | 21 | @Override 22 | public String getSetupClass() { 23 | return null; 24 | } 25 | 26 | @Override 27 | public void injectData(Map data) { 28 | } 29 | 30 | @Override 31 | public String getAccessTransformerClass() { 32 | return null; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/main/java/com/jelly/farmhelperv2/util/helper/Rotation.java: -------------------------------------------------------------------------------- 1 | package com.jelly.farmhelperv2.util.helper; 2 | 3 | import lombok.Getter; 4 | import lombok.Setter; 5 | 6 | @Getter 7 | @Setter 8 | public class Rotation { 9 | private float yaw; 10 | private float pitch; 11 | 12 | public Rotation(float yaw, float pitch) { 13 | this.yaw = yaw; 14 | this.pitch = pitch; 15 | } 16 | 17 | public void setRotation(Rotation rotation) { 18 | this.yaw = rotation.getYaw(); 19 | this.pitch = rotation.getPitch(); 20 | } 21 | 22 | public float getValue() { 23 | return Math.abs(this.yaw) + Math.abs(this.pitch); 24 | } 25 | 26 | @Override 27 | public String toString() { 28 | return "Rotation{" + 29 | "yaw=" + yaw + 30 | ", pitch=" + pitch + 31 | '}'; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/main/java/com/jelly/farmhelperv2/event/MotionUpdateEvent.java: -------------------------------------------------------------------------------- 1 | package com.jelly.farmhelperv2.event; 2 | 3 | import net.minecraftforge.fml.common.eventhandler.Cancelable; 4 | import net.minecraftforge.fml.common.eventhandler.Event; 5 | 6 | @Cancelable 7 | public class MotionUpdateEvent extends Event { 8 | public float yaw; 9 | public float pitch; 10 | 11 | protected MotionUpdateEvent(float yaw, float pitch) { 12 | this.yaw = yaw; 13 | this.pitch = pitch; 14 | } 15 | 16 | @Cancelable 17 | public static class Pre extends MotionUpdateEvent { 18 | public Pre(final float yaw, final float pitch) { 19 | super(yaw, pitch); 20 | } 21 | } 22 | 23 | @Cancelable 24 | public static class Post extends MotionUpdateEvent { 25 | public Post(final float yaw, final float pitch) { 26 | super(yaw, pitch); 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/main/java/com/jelly/farmhelperv2/mixin/render/MixinEffectRenderer.java: -------------------------------------------------------------------------------- 1 | package com.jelly.farmhelperv2.mixin.render; 2 | 3 | import com.jelly.farmhelperv2.handler.MacroHandler; 4 | import net.minecraft.block.state.IBlockState; 5 | import net.minecraft.client.particle.EffectRenderer; 6 | import net.minecraft.util.BlockPos; 7 | import org.spongepowered.asm.mixin.Mixin; 8 | import org.spongepowered.asm.mixin.injection.At; 9 | import org.spongepowered.asm.mixin.injection.Inject; 10 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; 11 | 12 | @Mixin(EffectRenderer.class) 13 | public class MixinEffectRenderer { 14 | 15 | @Inject(method = "addBlockDestroyEffects", at = @At("HEAD"), cancellable = true) 16 | private void addBlockDestroyEffects(BlockPos pos, IBlockState state, CallbackInfo ci) { 17 | if (MacroHandler.getInstance().isMacroToggled()) { 18 | ci.cancel(); 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/main/java/com/jelly/farmhelperv2/feature/IFeature.java: -------------------------------------------------------------------------------- 1 | package com.jelly.farmhelperv2.feature; 2 | 3 | import com.jelly.farmhelperv2.util.LogUtils; 4 | 5 | public interface IFeature { 6 | String getName(); 7 | 8 | boolean isRunning(); 9 | 10 | boolean shouldPauseMacroExecution(); 11 | 12 | boolean shouldStartAtMacroStart(); 13 | 14 | default void start() { 15 | if (!shouldPauseMacroExecution()) return; 16 | LogUtils.sendDebug("Enabled pausing feature: " + getName()); 17 | FeatureManager.getInstance().getPauseExecutionFeatures().add(this); 18 | } 19 | 20 | default void resume() {} 21 | 22 | default void stop() { 23 | if (!shouldPauseMacroExecution()) return; 24 | FeatureManager.getInstance().getPauseExecutionFeatures().remove(this); 25 | } 26 | 27 | void resetStatesAfterMacroDisabled(); 28 | 29 | boolean isToggled(); 30 | 31 | boolean shouldCheckForFailsafes(); 32 | } 33 | -------------------------------------------------------------------------------- /src/main/java/com/jelly/farmhelperv2/event/SpawnObjectEvent.java: -------------------------------------------------------------------------------- 1 | package com.jelly.farmhelperv2.event; 2 | 3 | import net.minecraft.util.Vec3; 4 | import net.minecraftforge.fml.common.eventhandler.Event; 5 | 6 | public class SpawnObjectEvent extends Event { 7 | public int entityId; 8 | public double x; 9 | public double y; 10 | public double z; 11 | public Vec3 pos; 12 | public double speedX; 13 | public double speedY; 14 | public double speedZ; 15 | public float yaw; 16 | public float pitch; 17 | public int type; 18 | 19 | public SpawnObjectEvent(int entityId, double x, double y, double z, double speedX, double speedY, double speedZ, float yaw, float pitch, int type) { 20 | this.entityId = entityId; 21 | this.x = x; 22 | this.y = y; 23 | this.z = z; 24 | this.pos = new Vec3(x, y, z); 25 | this.speedX = speedX; 26 | this.speedY = speedY; 27 | this.speedZ = speedZ; 28 | this.yaw = yaw; 29 | this.pitch = pitch; 30 | this.type = type; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/main/java/com/jelly/farmhelperv2/remote/waiter/Waiter.java: -------------------------------------------------------------------------------- 1 | package com.jelly.farmhelperv2.remote.waiter; 2 | 3 | 4 | import com.jelly.farmhelperv2.remote.struct.RemoteMessage; 5 | import lombok.Getter; 6 | import lombok.Setter; 7 | import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent; 8 | 9 | import java.util.function.Consumer; 10 | 11 | @Getter 12 | public class Waiter { 13 | private final Integer timeout; 14 | private final String command; 15 | private final Consumer action; 16 | private final Consumer timeoutAction; 17 | public final SlashCommandInteractionEvent event; 18 | @Setter 19 | private boolean answeredAtLeastOnce = false; 20 | 21 | public Waiter(Integer timeout, String command, Consumer action, Consumer timeoutAction, SlashCommandInteractionEvent event) { 22 | this.timeout = timeout; 23 | this.command = command; 24 | this.action = action; 25 | this.timeoutAction = timeoutAction; 26 | this.event = event; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/main/java/com/jelly/farmhelperv2/mixin/pathfinder/MixinChunkProviderClient.java: -------------------------------------------------------------------------------- 1 | package com.jelly.farmhelperv2.mixin.pathfinder; 2 | 3 | import com.jelly.farmhelperv2.event.ChunkServerLoadEvent; 4 | import net.minecraft.client.multiplayer.ChunkProviderClient; 5 | import net.minecraft.world.chunk.Chunk; 6 | import net.minecraftforge.common.MinecraftForge; 7 | import org.spongepowered.asm.mixin.Mixin; 8 | import org.spongepowered.asm.mixin.injection.At; 9 | import org.spongepowered.asm.mixin.injection.Inject; 10 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; 11 | 12 | @Mixin(ChunkProviderClient.class) 13 | public class MixinChunkProviderClient { 14 | @Inject(method = "loadChunk(II)Lnet/minecraft/world/chunk/Chunk;", at = @At("RETURN")) 15 | private void onLoadChunk(int x, int z, CallbackInfoReturnable cir) { 16 | Chunk chunk = cir.getReturnValue(); 17 | if (!chunk.isLoaded()) return; 18 | ChunkServerLoadEvent event = new ChunkServerLoadEvent(x, z, chunk); 19 | MinecraftForge.EVENT_BUS.post(event); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/main/java/com/jelly/farmhelperv2/mixin/render/MixinActiveRenderInfo.java: -------------------------------------------------------------------------------- 1 | package com.jelly.farmhelperv2.mixin.render; 2 | 3 | import com.jelly.farmhelperv2.feature.impl.Freelook; 4 | import net.minecraft.client.renderer.ActiveRenderInfo; 5 | import net.minecraft.entity.player.EntityPlayer; 6 | import org.spongepowered.asm.mixin.Mixin; 7 | import org.spongepowered.asm.mixin.injection.At; 8 | import org.spongepowered.asm.mixin.injection.Redirect; 9 | 10 | @Mixin(ActiveRenderInfo.class) 11 | public abstract class MixinActiveRenderInfo { 12 | @Redirect(method = "updateRenderInfo", at = @At(value = "FIELD", target = "Lnet/minecraft/entity/player/EntityPlayer;rotationPitch:F")) 13 | private static float modifyPitch(EntityPlayer player) { 14 | return Freelook.getInstance().getPitch(player.rotationPitch); 15 | } 16 | 17 | @Redirect(method = "updateRenderInfo", at = @At(value = "FIELD", target = "Lnet/minecraft/entity/player/EntityPlayer;rotationYaw:F")) 18 | private static float modifyYaw(EntityPlayer player) { 19 | return Freelook.getInstance().getYaw(player.rotationYaw); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/main/java/com/jelly/farmhelperv2/mixin/block/MixinBlockCrops.java: -------------------------------------------------------------------------------- 1 | package com.jelly.farmhelperv2.mixin.block; 2 | 3 | import com.jelly.farmhelperv2.util.CropUtils; 4 | import net.minecraft.block.BlockBush; 5 | import net.minecraft.block.BlockCrops; 6 | import net.minecraft.util.AxisAlignedBB; 7 | import net.minecraft.util.BlockPos; 8 | import net.minecraft.util.MovingObjectPosition; 9 | import net.minecraft.util.Vec3; 10 | import net.minecraft.world.World; 11 | import org.spongepowered.asm.mixin.Mixin; 12 | 13 | @Mixin(BlockCrops.class) 14 | public abstract class MixinBlockCrops extends BlockBush { 15 | 16 | @Override 17 | public AxisAlignedBB getSelectedBoundingBox(World worldIn, BlockPos pos) { 18 | CropUtils.updateCropsMaxY(worldIn, pos, worldIn.getBlockState(pos).getBlock()); 19 | return super.getSelectedBoundingBox(worldIn, pos); 20 | } 21 | 22 | @Override 23 | public MovingObjectPosition collisionRayTrace(World worldIn, BlockPos pos, Vec3 start, Vec3 end) { 24 | CropUtils.updateCropsMaxY(worldIn, pos, worldIn.getBlockState(pos).getBlock()); 25 | return super.collisionRayTrace(worldIn, pos, start, end); 26 | } 27 | } -------------------------------------------------------------------------------- /src/main/java/com/jelly/farmhelperv2/mixin/fml/MixinFMLHandshakeMessage.java: -------------------------------------------------------------------------------- 1 | package com.jelly.farmhelperv2.mixin.fml; 2 | 3 | import net.minecraft.client.Minecraft; 4 | import net.minecraftforge.fml.common.ModContainer; 5 | import net.minecraftforge.fml.common.network.handshake.FMLHandshakeMessage; 6 | import org.spongepowered.asm.mixin.Mixin; 7 | import org.spongepowered.asm.mixin.Shadow; 8 | import org.spongepowered.asm.mixin.injection.At; 9 | import org.spongepowered.asm.mixin.injection.Inject; 10 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; 11 | 12 | import java.util.List; 13 | import java.util.Map; 14 | 15 | @Mixin(value = FMLHandshakeMessage.ModList.class, remap = false, priority = Integer.MAX_VALUE) 16 | public abstract class MixinFMLHandshakeMessage { 17 | @Shadow(remap = false) 18 | private Map modTags; 19 | 20 | @Inject(method = "(Ljava/util/List;)V", at = @At("RETURN"), remap = false) 21 | private void init(List modList, CallbackInfo ci) { 22 | if (Minecraft.getMinecraft().isIntegratedServerRunning()) return; 23 | modTags.keySet().removeIf(s -> s.contains("farmhelper")); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/main/java/com/jelly/farmhelperv2/mixin/block/MixinBlockNetherWart.java: -------------------------------------------------------------------------------- 1 | package com.jelly.farmhelperv2.mixin.block; 2 | 3 | import com.jelly.farmhelperv2.util.CropUtils; 4 | import net.minecraft.block.BlockBush; 5 | import net.minecraft.block.BlockNetherWart; 6 | import net.minecraft.util.AxisAlignedBB; 7 | import net.minecraft.util.BlockPos; 8 | import net.minecraft.util.MovingObjectPosition; 9 | import net.minecraft.util.Vec3; 10 | import net.minecraft.world.World; 11 | import org.spongepowered.asm.mixin.Mixin; 12 | 13 | @Mixin(BlockNetherWart.class) 14 | public abstract class MixinBlockNetherWart extends BlockBush { 15 | 16 | @Override 17 | public AxisAlignedBB getSelectedBoundingBox(World worldIn, BlockPos pos) { 18 | CropUtils.updateWartMaxY(worldIn, pos, worldIn.getBlockState(pos).getBlock()); 19 | return super.getSelectedBoundingBox(worldIn, pos); 20 | } 21 | 22 | @Override 23 | public MovingObjectPosition collisionRayTrace(World worldIn, BlockPos pos, Vec3 start, Vec3 end) { 24 | CropUtils.updateWartMaxY(worldIn, pos, worldIn.getBlockState(pos).getBlock()); 25 | return super.collisionRayTrace(worldIn, pos, start, end); 26 | } 27 | } -------------------------------------------------------------------------------- /src/main/java/com/jelly/farmhelperv2/mixin/client/MixinChunk.java: -------------------------------------------------------------------------------- 1 | package com.jelly.farmhelperv2.mixin.client; 2 | 3 | import com.jelly.farmhelperv2.event.BlockChangeEvent; 4 | import net.minecraft.block.state.IBlockState; 5 | import net.minecraft.util.BlockPos; 6 | import net.minecraft.world.chunk.Chunk; 7 | import net.minecraftforge.common.MinecraftForge; 8 | import org.spongepowered.asm.mixin.Mixin; 9 | import org.spongepowered.asm.mixin.Shadow; 10 | import org.spongepowered.asm.mixin.injection.At; 11 | import org.spongepowered.asm.mixin.injection.Inject; 12 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; 13 | 14 | @Mixin(Chunk.class) 15 | public abstract class MixinChunk { 16 | @Shadow 17 | public abstract IBlockState getBlockState(BlockPos paramBlockPos); 18 | 19 | 20 | @Inject(method = {"setBlockState"}, at = @At("HEAD")) 21 | public void onBlockSet(BlockPos pos, IBlockState state, CallbackInfoReturnable cir) { 22 | IBlockState old = getBlockState(pos); 23 | if (state != old) 24 | MinecraftForge.EVENT_BUS.post(new BlockChangeEvent(pos, old, state, ((Chunk) (Object) this).getWorld())); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/main/java/com/jelly/farmhelperv2/util/helper/SignUtils.java: -------------------------------------------------------------------------------- 1 | package com.jelly.farmhelperv2.util.helper; 2 | 3 | import com.jelly.farmhelperv2.mixin.gui.AccessorGuiEditSign; 4 | import net.minecraft.client.Minecraft; 5 | import net.minecraft.client.gui.inventory.GuiEditSign; 6 | import net.minecraft.util.ChatComponentText; 7 | 8 | public class SignUtils { 9 | private static final Minecraft mc = Minecraft.getMinecraft(); 10 | 11 | public static void setTextToWriteOnString(String text) { 12 | if (!(mc.currentScreen instanceof GuiEditSign)) return; 13 | AccessorGuiEditSign guiEditSign = (AccessorGuiEditSign) mc.currentScreen; 14 | if (guiEditSign.getTileSign() == null || guiEditSign.getTileSign().signText[0].getUnformattedText().equals(text)) 15 | return; 16 | 17 | guiEditSign.getTileSign().signText[0] = new ChatComponentText(text); 18 | } 19 | 20 | public static void confirmSign() { 21 | if (!(mc.currentScreen instanceof GuiEditSign)) return; 22 | AccessorGuiEditSign guiEditSign = (AccessorGuiEditSign) mc.currentScreen; 23 | guiEditSign.getTileSign().markDirty(); 24 | mc.displayGuiScreen(null); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/main/java/com/jelly/farmhelperv2/config/struct/Rewarp.java: -------------------------------------------------------------------------------- 1 | package com.jelly.farmhelperv2.config.struct; 2 | 3 | import com.google.gson.annotations.Expose; 4 | import lombok.Getter; 5 | import net.minecraft.util.BlockPos; 6 | 7 | @Getter 8 | public class Rewarp { 9 | @Expose 10 | public int x; 11 | @Expose 12 | public int y; 13 | @Expose 14 | public int z; 15 | 16 | public Rewarp(int x, int y, int z) { 17 | this.x = x; 18 | this.y = y; 19 | this.z = z; 20 | } 21 | 22 | public Rewarp(BlockPos blockPos) { 23 | this.x = blockPos.getX(); 24 | this.y = blockPos.getY(); 25 | this.z = blockPos.getZ(); 26 | } 27 | 28 | public double getDistance(BlockPos to) { 29 | return Math.sqrt(Math.pow(to.getX() - x, 2) + Math.pow(to.getY() - y, 2) + Math.pow(to.getZ() - z, 2)); 30 | } 31 | 32 | public boolean isTheSameAs(BlockPos blockPos) { 33 | return x == blockPos.getX() && y == blockPos.getY() && z == blockPos.getZ(); 34 | } 35 | 36 | @Override 37 | public String toString() { 38 | return "Rewarp{" + 39 | "x=" + x + 40 | ", y=" + y + 41 | ", z=" + z + 42 | '}'; 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/main/java/com/jelly/farmhelperv2/util/helper/TickTask.java: -------------------------------------------------------------------------------- 1 | package com.jelly.farmhelperv2.util.helper; 2 | 3 | import cc.polyfrost.oneconfig.utils.Multithreading; 4 | import lombok.Getter; 5 | import lombok.Setter; 6 | import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; 7 | import net.minecraftforge.fml.common.gameevent.TickEvent; 8 | 9 | import java.util.concurrent.TimeUnit; 10 | 11 | @Getter 12 | public class TickTask { 13 | private static TickTask instance; 14 | @Setter 15 | private Runnable task; 16 | @Setter 17 | private Runnable callback; 18 | 19 | public static TickTask getInstance() { 20 | if (instance == null) { 21 | instance = new TickTask(); 22 | } 23 | return instance; 24 | } 25 | 26 | public void schedule(int delay, Runnable task) { 27 | Multithreading.schedule(() -> this.task = task, delay, TimeUnit.MILLISECONDS); 28 | } 29 | 30 | @SubscribeEvent 31 | public void onTick(TickEvent.ClientTickEvent event) { 32 | if (task != null) { 33 | task.run(); 34 | if (callback != null) { 35 | task = callback; 36 | callback = null; 37 | } else { 38 | task = null; 39 | } 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/main/java/com/jelly/farmhelperv2/mixin/gui/MixinGuiContainer.java: -------------------------------------------------------------------------------- 1 | package com.jelly.farmhelperv2.mixin.gui; 2 | 3 | import com.jelly.farmhelperv2.event.DrawScreenAfterEvent; 4 | import com.jelly.farmhelperv2.event.InventoryInputEvent; 5 | import com.jelly.farmhelperv2.util.InventoryUtils; 6 | import net.minecraft.client.Minecraft; 7 | import net.minecraft.client.gui.inventory.GuiContainer; 8 | import net.minecraftforge.common.MinecraftForge; 9 | import org.spongepowered.asm.mixin.Mixin; 10 | import org.spongepowered.asm.mixin.injection.At; 11 | import org.spongepowered.asm.mixin.injection.Inject; 12 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; 13 | 14 | @Mixin(GuiContainer.class) 15 | public class MixinGuiContainer { 16 | 17 | @Inject(method = "drawScreen", at = @At("RETURN")) 18 | public void drawScreen_after(int mouseX, int mouseY, float partialTicks, CallbackInfo ci) { 19 | String name = InventoryUtils.getInventoryName(); 20 | MinecraftForge.EVENT_BUS.post(new DrawScreenAfterEvent(Minecraft.getMinecraft().currentScreen)); 21 | } 22 | 23 | @Inject(method = "keyTyped", at = @At("RETURN"), cancellable = true) 24 | public void keyTyped_after(char typedChar, int keyCode, CallbackInfo ci) { 25 | if (MinecraftForge.EVENT_BUS.post(new InventoryInputEvent(keyCode, typedChar))) { 26 | ci.cancel(); 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/main/java/com/jelly/farmhelperv2/event/SpawnParticleEvent.java: -------------------------------------------------------------------------------- 1 | package com.jelly.farmhelperv2.event; 2 | 3 | import lombok.Getter; 4 | import net.minecraft.util.EnumParticleTypes; 5 | import net.minecraft.util.Vec3; 6 | import net.minecraftforge.fml.common.eventhandler.Cancelable; 7 | import net.minecraftforge.fml.common.eventhandler.Event; 8 | 9 | @Cancelable 10 | @Getter 11 | public class SpawnParticleEvent extends Event { 12 | 13 | EnumParticleTypes particleTypes; 14 | boolean isLongDistance; 15 | double xCoord; 16 | double yCoord; 17 | double zCoord; 18 | 19 | double xOffset; 20 | double yOffset; 21 | double zOffset; 22 | int[] params; 23 | 24 | public SpawnParticleEvent( 25 | EnumParticleTypes particleTypes, 26 | boolean isLongDistance, 27 | double xCoord, double yCoord, double zCoord, 28 | double xOffset, double yOffset, double zOffset, 29 | int[] params 30 | ) { 31 | this.particleTypes = particleTypes; 32 | this.isLongDistance = isLongDistance; 33 | this.xCoord = xCoord; 34 | this.yCoord = yCoord; 35 | this.zCoord = zCoord; 36 | this.xOffset = xOffset; 37 | this.yOffset = yOffset; 38 | this.zOffset = zOffset; 39 | this.params = params; 40 | } 41 | 42 | public Vec3 getPos() { 43 | return new Vec3(xCoord, yCoord, zCoord); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/main/java/com/jelly/farmhelperv2/mixin/client/MixinSoundManager.java: -------------------------------------------------------------------------------- 1 | package com.jelly.farmhelperv2.mixin.client; 2 | 3 | import com.jelly.farmhelperv2.config.FarmHelperConfig; 4 | import com.jelly.farmhelperv2.failsafe.FailsafeManager; 5 | import com.jelly.farmhelperv2.handler.MacroHandler; 6 | import com.jelly.farmhelperv2.util.helper.AudioManager; 7 | import net.minecraft.client.audio.ISound; 8 | import net.minecraft.client.audio.SoundCategory; 9 | import net.minecraft.client.audio.SoundManager; 10 | import net.minecraft.client.audio.SoundPoolEntry; 11 | import org.spongepowered.asm.mixin.Mixin; 12 | import org.spongepowered.asm.mixin.injection.At; 13 | import org.spongepowered.asm.mixin.injection.Inject; 14 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; 15 | 16 | @Mixin(SoundManager.class) 17 | public class MixinSoundManager { 18 | @Inject(method = "getNormalizedVolume", at = @At("RETURN"), cancellable = true) 19 | private void getNormalizedVolume(ISound sound, SoundPoolEntry entry, SoundCategory category, CallbackInfoReturnable cir) { 20 | if (MacroHandler.getInstance().isMacroToggled() && FarmHelperConfig.muteTheGame && !AudioManager.getInstance().isSoundPlaying() && !FailsafeManager.getInstance().getChooseEmergencyDelay().isScheduled() && !FailsafeManager.getInstance().triggeredFailsafe.isPresent()) { 21 | cir.setReturnValue(0f); 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/main/java/com/jelly/farmhelperv2/util/APIUtils.java: -------------------------------------------------------------------------------- 1 | package com.jelly.farmhelperv2.util; 2 | 3 | import com.google.gson.JsonObject; 4 | import com.google.gson.JsonParser; 5 | 6 | import javax.net.ssl.HttpsURLConnection; 7 | import java.io.BufferedReader; 8 | import java.io.InputStreamReader; 9 | import java.net.URL; 10 | 11 | public class APIUtils { 12 | static JsonParser jsonParser = new JsonParser(); 13 | 14 | public static JsonObject readJsonFromUrl(String urlToRead, String requestKey, String requestValue) throws Exception { 15 | try { 16 | StringBuilder result = new StringBuilder(); 17 | URL url = new URL(urlToRead); 18 | 19 | HttpsURLConnection conn = (HttpsURLConnection) url.openConnection(); 20 | 21 | if (requestKey != null && requestValue != null) { 22 | conn.setRequestProperty(requestKey, requestValue); 23 | } 24 | 25 | conn.setRequestMethod("GET"); 26 | 27 | try (BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream()))) { 28 | for (String line; (line = reader.readLine()) != null; ) { 29 | result.append(line); 30 | } 31 | } 32 | 33 | return (JsonObject) jsonParser.parse(result.toString()); 34 | } catch (Exception e) { 35 | e.printStackTrace(); 36 | return null; 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/main/java/com/jelly/farmhelperv2/mixin/client/MixinMouse.java: -------------------------------------------------------------------------------- 1 | package com.jelly.farmhelperv2.mixin.client; 2 | 3 | import com.jelly.farmhelperv2.feature.impl.Freelook; 4 | import com.jelly.farmhelperv2.handler.MacroHandler; 5 | import net.minecraft.client.Minecraft; 6 | import net.minecraft.client.gui.GuiChat; 7 | import org.lwjgl.input.Mouse; 8 | import org.spongepowered.asm.mixin.Mixin; 9 | import org.spongepowered.asm.mixin.injection.At; 10 | import org.spongepowered.asm.mixin.injection.Inject; 11 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; 12 | 13 | @Mixin(value = Mouse.class, priority = Integer.MAX_VALUE, remap = false) 14 | public class MixinMouse { 15 | @Inject(method = "getEventDWheel()I", at = @At("RETURN"), remap = false, cancellable = true) 16 | private static void getEventDWheel(CallbackInfoReturnable cir) { 17 | if (Minecraft.getMinecraft().currentScreen != null) return; 18 | if (Freelook.getInstance().isRunning()) { 19 | Freelook.getInstance().setDistance(Math.min(20, Math.max(1, Freelook.getInstance().getDistance() - (cir.getReturnValue() / 120f)))); 20 | cir.setReturnValue(0); 21 | return; 22 | } 23 | if (MacroHandler.getInstance().getCurrentMacro().isPresent() && MacroHandler.getInstance().isMacroToggled() && !(Minecraft.getMinecraft().currentScreen instanceof GuiChat)) { 24 | cir.setReturnValue(0); 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/main/java/com/jelly/farmhelperv2/util/helper/Timer.java: -------------------------------------------------------------------------------- 1 | package com.jelly.farmhelperv2.util.helper; 2 | 3 | public class Timer { 4 | public long startedAt = 0; 5 | public long pausedAt = 0; 6 | public boolean paused = false; 7 | 8 | public boolean hasPassed(long ms) { 9 | return System.currentTimeMillis() - startedAt > ms; 10 | } 11 | 12 | public void reset() { 13 | startedAt = 0; 14 | pausedAt = 0; 15 | paused = false; 16 | } 17 | 18 | public void schedule() { 19 | startedAt = System.currentTimeMillis(); 20 | pausedAt = 0; 21 | paused = false; 22 | } 23 | 24 | public void pause() { 25 | if (startedAt != 0 && !paused) { 26 | pausedAt = System.currentTimeMillis(); 27 | paused = true; 28 | } 29 | } 30 | 31 | public void resume() { 32 | if (startedAt != 0 && paused) { 33 | startedAt += System.currentTimeMillis() - pausedAt; 34 | paused = false; 35 | } 36 | } 37 | 38 | public boolean isScheduled() { 39 | return startedAt != 0; 40 | } 41 | 42 | public long getElapsedTime() { 43 | if (startedAt == 0) { 44 | return 0; 45 | } 46 | if (paused) { 47 | return pausedAt - startedAt; 48 | } 49 | return System.currentTimeMillis() - startedAt; 50 | } 51 | 52 | public Timer() { 53 | reset(); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /src/main/java/com/jelly/farmhelperv2/mixin/client/MixinKeyBinding.java: -------------------------------------------------------------------------------- 1 | package com.jelly.farmhelperv2.mixin.client; 2 | 3 | import com.jelly.farmhelperv2.handler.MacroHandler; 4 | import net.minecraft.client.Minecraft; 5 | import net.minecraft.client.settings.KeyBinding; 6 | import org.spongepowered.asm.mixin.Mixin; 7 | import org.spongepowered.asm.mixin.Shadow; 8 | import org.spongepowered.asm.mixin.injection.At; 9 | import org.spongepowered.asm.mixin.injection.Inject; 10 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; 11 | 12 | import java.util.Arrays; 13 | 14 | @Mixin(value = KeyBinding.class, priority = Integer.MAX_VALUE) 15 | public class MixinKeyBinding { 16 | @Shadow 17 | private int keyCode; 18 | 19 | @Shadow 20 | private int pressTime; 21 | 22 | @Shadow 23 | private boolean pressed; 24 | 25 | @Inject(method = "isPressed", at = @At("HEAD"), cancellable = true) 26 | private void isPressed(CallbackInfoReturnable cir) { 27 | if (!MacroHandler.getInstance().isMacroToggled() || MacroHandler.getInstance().isCurrentMacroPaused()) return; 28 | 29 | if (Arrays.stream(Minecraft.getMinecraft().gameSettings.keyBindsHotbar).anyMatch(keyBinding -> keyBinding.getKeyCode() == this.keyCode) || keyCode == Minecraft.getMinecraft().gameSettings.keyBindDrop.getKeyCode()) { 30 | cir.setReturnValue(false); 31 | pressTime = 0; 32 | pressed = false; 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/main/java/com/jelly/farmhelperv2/util/helper/Target.java: -------------------------------------------------------------------------------- 1 | package com.jelly.farmhelperv2.util.helper; 2 | 3 | import lombok.Getter; 4 | import lombok.Setter; 5 | import lombok.experimental.Accessors; 6 | import net.minecraft.client.Minecraft; 7 | import net.minecraft.entity.Entity; 8 | import net.minecraft.util.BlockPos; 9 | import net.minecraft.util.Vec3; 10 | 11 | import java.util.Optional; 12 | 13 | public class Target { 14 | private Vec3 vec; 15 | @Getter 16 | private Entity entity; 17 | @Getter 18 | private BlockPos blockPos; 19 | @Accessors(fluent = true) 20 | @Setter 21 | @Getter 22 | private float additionalY; 23 | 24 | public Target(Vec3 vec) { 25 | this.vec = vec; 26 | } 27 | 28 | public Target(Entity entity) { 29 | this.entity = entity; 30 | } 31 | 32 | public Target(BlockPos blockPos) { 33 | this.blockPos = blockPos; 34 | } 35 | 36 | public Optional getTarget() { 37 | if (vec != null) { 38 | return Optional.of(vec.addVector(0, this.additionalY, 0)); 39 | } else if (entity != null) { 40 | return Optional.of(entity.getPositionVector().add(new Vec3(0, Minecraft.getMinecraft().thePlayer.eyeHeight + this.additionalY, 0))); 41 | } else if (blockPos != null) { 42 | return Optional.of(new Vec3(blockPos.getX(), blockPos.getY() + this.additionalY, blockPos.getZ())); 43 | } else { 44 | return Optional.empty(); 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/main/resources/mixins.farmhelperv2.json: -------------------------------------------------------------------------------- 1 | { 2 | "package": "com.jelly.farmhelperv2.mixin", 3 | "refmap": "mixins.${modid}.refmap.json", 4 | "minVersion": "0.7", 5 | "compatibilityLevel": "JAVA_8", 6 | "mixins": [ 7 | "block.IBlockAccessor", 8 | "block.MixinBlockCocoa", 9 | "block.MixinBlockCrops", 10 | "block.MixinBlockMushroom", 11 | "block.MixinBlockNetherWart", 12 | "client.EntityPlayerAccessor", 13 | "client.MixinChunk", 14 | "client.MixinEntity", 15 | "client.MixinMouse", 16 | "client.MixinScoreboard", 17 | "fml.MixinFMLHandshakeMessage", 18 | "network.MixinNetworkManager", 19 | "pathfinder.MixinChunkProviderClient", 20 | "pathfinder.PathfinderAccessor" 21 | ], 22 | "client": [ 23 | "block.MixinBlockRendererDispatcher", 24 | "client.EntityPlayerSPAccessor", 25 | "client.MinecraftAccessor", 26 | "client.MixinEntityPlayerSP", 27 | "client.MixinKeyBinding", 28 | "client.MixinMinecraft", 29 | "client.MixinPlayerControllerMP", 30 | "client.MixinSoundManager", 31 | "gui.AccessorGuiEditSign", 32 | "gui.IGuiPlayerTabOverlayAccessor", 33 | "gui.MixinGuiContainer", 34 | "gui.MixinGuiDisconnected", 35 | "gui.MixinGuiMainMenu", 36 | "gui.MixinGuiMultiplayer", 37 | "network.MixinNetHandlerPlayClient", 38 | "render.MixinActiveRenderInfo", 39 | "render.MixinEffectRenderer", 40 | "render.MixinEntityRenderer", 41 | "render.MixinModelBiped", 42 | "render.MixinRenderManager" 43 | ] 44 | } 45 | -------------------------------------------------------------------------------- /src/main/java/com/jelly/farmhelperv2/mixin/block/MixinBlockCocoa.java: -------------------------------------------------------------------------------- 1 | package com.jelly.farmhelperv2.mixin.block; 2 | 3 | import com.jelly.farmhelperv2.util.CropUtils; 4 | import net.minecraft.block.BlockCocoa; 5 | import net.minecraft.block.BlockDirectional; 6 | import net.minecraft.block.material.Material; 7 | import net.minecraft.util.AxisAlignedBB; 8 | import net.minecraft.util.BlockPos; 9 | import net.minecraft.util.MovingObjectPosition; 10 | import net.minecraft.util.Vec3; 11 | import net.minecraft.world.IBlockAccess; 12 | import net.minecraft.world.World; 13 | import org.spongepowered.asm.mixin.Mixin; 14 | 15 | @Mixin(value = BlockCocoa.class, priority = 2000) 16 | public abstract class MixinBlockCocoa extends BlockDirectional { 17 | protected MixinBlockCocoa() { 18 | super(Material.plants); 19 | } 20 | 21 | @Override 22 | public void setBlockBoundsBasedOnState(IBlockAccess worldIn, BlockPos pos) { 23 | CropUtils.updateCocoaBeansHitbox(worldIn.getBlockState(pos)); 24 | } 25 | 26 | @Override 27 | public AxisAlignedBB getSelectedBoundingBox(World worldIn, BlockPos pos) { 28 | CropUtils.updateCocoaBeansHitbox(worldIn.getBlockState(pos)); 29 | return super.getSelectedBoundingBox(worldIn, pos); 30 | } 31 | 32 | @Override 33 | public MovingObjectPosition collisionRayTrace(World worldIn, BlockPos pos, Vec3 start, Vec3 end) { 34 | CropUtils.updateCocoaBeansHitbox(worldIn.getBlockState(pos)); 35 | return super.collisionRayTrace(worldIn, pos, start, end); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/main/java/com/jelly/farmhelperv2/remote/command/commands/impl/DisconnectCommand.java: -------------------------------------------------------------------------------- 1 | package com.jelly.farmhelperv2.remote.command.commands.impl; 2 | 3 | import cc.polyfrost.oneconfig.utils.Multithreading; 4 | import com.google.gson.JsonObject; 5 | import com.jelly.farmhelperv2.handler.MacroHandler; 6 | import com.jelly.farmhelperv2.remote.command.commands.ClientCommand; 7 | import com.jelly.farmhelperv2.remote.command.commands.Command; 8 | import com.jelly.farmhelperv2.remote.struct.RemoteMessage; 9 | import net.minecraft.util.ChatComponentText; 10 | 11 | import java.util.concurrent.TimeUnit; 12 | 13 | @Command(label = "disconnect") 14 | public class DisconnectCommand extends ClientCommand { 15 | 16 | @Override 17 | public void execute(RemoteMessage event) { 18 | if (MacroHandler.getInstance().isMacroToggled()) 19 | MacroHandler.getInstance().disableMacro(); 20 | try { 21 | mc.getNetHandler().getNetworkManager().closeChannel(new ChatComponentText("Disconnected through Discord Remote Control bot")); 22 | } catch (Exception e) { 23 | e.printStackTrace(); 24 | } 25 | Multithreading.schedule(() -> { 26 | JsonObject data = new JsonObject(); 27 | data.addProperty("username", mc.getSession().getUsername()); 28 | data.addProperty("image", getScreenshot()); 29 | data.addProperty("uuid", mc.getSession().getPlayerID()); 30 | RemoteMessage response = new RemoteMessage(label, data); 31 | send(response); 32 | }, 1_500, TimeUnit.MILLISECONDS); 33 | } 34 | } -------------------------------------------------------------------------------- /src/main/java/com/jelly/farmhelperv2/mixin/gui/MixinGuiMainMenu.java: -------------------------------------------------------------------------------- 1 | package com.jelly.farmhelperv2.mixin.gui; 2 | 3 | import com.jelly.farmhelperv2.FarmHelper; 4 | import com.jelly.farmhelperv2.config.FarmHelperConfig; 5 | import com.jelly.farmhelperv2.gui.AutoUpdaterGUI; 6 | import com.jelly.farmhelperv2.gui.WelcomeGUI; 7 | import net.minecraft.client.gui.GuiMainMenu; 8 | import org.spongepowered.asm.mixin.Final; 9 | import org.spongepowered.asm.mixin.Mixin; 10 | import org.spongepowered.asm.mixin.Shadow; 11 | import org.spongepowered.asm.mixin.injection.At; 12 | import org.spongepowered.asm.mixin.injection.Inject; 13 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; 14 | 15 | @Mixin(GuiMainMenu.class) 16 | public class MixinGuiMainMenu { 17 | @Shadow 18 | private String splashText; 19 | 20 | @Final 21 | @Inject(method = "updateScreen", at = @At("RETURN")) 22 | private void initGui(CallbackInfo ci) { 23 | if (FarmHelper.isDebug) { 24 | this.splashText = "Fix Farm Helper <3"; 25 | return; 26 | } 27 | if (!FarmHelperConfig.shownWelcomeGUI) { 28 | WelcomeGUI.showGUI(); 29 | } 30 | if (!AutoUpdaterGUI.checkedForUpdates) { 31 | AutoUpdaterGUI.checkedForUpdates = true; 32 | AutoUpdaterGUI.getLatestVersion(); 33 | if (AutoUpdaterGUI.isOutdated) { 34 | AutoUpdaterGUI.showGUI(); 35 | } 36 | } 37 | if (AutoUpdaterGUI.isOutdated && !FarmHelperConfig.streamerMode) 38 | this.splashText = "Update Farm Helper <3"; 39 | } 40 | } -------------------------------------------------------------------------------- /src/main/java/com/jelly/farmhelperv2/mixin/gui/MixinGuiMultiplayer.java: -------------------------------------------------------------------------------- 1 | package com.jelly.farmhelperv2.mixin.gui; 2 | 3 | import com.jelly.farmhelperv2.gui.ProxyManagerGUI; 4 | import net.minecraft.client.Minecraft; 5 | import net.minecraft.client.gui.GuiButton; 6 | import net.minecraft.client.gui.GuiMultiplayer; 7 | import net.minecraft.client.gui.GuiScreen; 8 | import net.minecraft.util.ChatComponentText; 9 | import org.spongepowered.asm.mixin.Mixin; 10 | import org.spongepowered.asm.mixin.injection.At; 11 | import org.spongepowered.asm.mixin.injection.Inject; 12 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; 13 | 14 | @Mixin(GuiMultiplayer.class) 15 | public class MixinGuiMultiplayer extends GuiScreen { 16 | 17 | @Inject(method = "initGui", at = @At("RETURN")) 18 | public void initGui(CallbackInfo ci) { 19 | this.buttonList.add(new GuiButton(2137, 8, 8, 130, 20, "FH - Proxy")); 20 | } 21 | 22 | @Inject(method = "actionPerformed", at = @At("HEAD"), cancellable = true) 23 | public void actionPerformed(GuiButton button, CallbackInfo ci) { 24 | if (button.id == 2137) { 25 | this.mc.displayGuiScreen(new ProxyManagerGUI(this)); 26 | ci.cancel(); 27 | } 28 | } 29 | 30 | @Inject(method = "connectToServer", at = @At(value = "HEAD")) 31 | public void connectToServer(CallbackInfo callbackInfo) { 32 | Minecraft minecraft = Minecraft.getMinecraft(); 33 | if (minecraft.getNetHandler() != null) { 34 | minecraft.getNetHandler().getNetworkManager().closeChannel(new ChatComponentText("")); 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/main/java/com/jelly/farmhelperv2/mixin/render/MixinRenderManager.java: -------------------------------------------------------------------------------- 1 | package com.jelly.farmhelperv2.mixin.render; 2 | 3 | import com.jelly.farmhelperv2.feature.impl.Freelook; 4 | import net.minecraft.client.renderer.entity.RenderManager; 5 | import net.minecraft.entity.Entity; 6 | import org.spongepowered.asm.mixin.Mixin; 7 | import org.spongepowered.asm.mixin.injection.At; 8 | import org.spongepowered.asm.mixin.injection.Redirect; 9 | 10 | @Mixin(RenderManager.class) 11 | public abstract class MixinRenderManager { 12 | @Redirect(method = "cacheActiveRenderInfo", at = @At(value = "FIELD", target = "Lnet/minecraft/entity/Entity;rotationPitch:F")) 13 | private float modifyPitch(Entity entity) { 14 | return Freelook.getInstance().getPitch(entity.rotationPitch); 15 | } 16 | 17 | @Redirect(method = "cacheActiveRenderInfo", at = @At(value = "FIELD", target = "Lnet/minecraft/entity/Entity;rotationYaw:F")) 18 | private float modifyYaw(Entity entity) { 19 | return Freelook.getInstance().getYaw(entity.rotationYaw); 20 | } 21 | 22 | @Redirect(method = "cacheActiveRenderInfo", at = @At(value = "FIELD", target = "Lnet/minecraft/entity/Entity;prevRotationPitch:F")) 23 | private float modifyPrevPitch(Entity entity) { 24 | return Freelook.getInstance().getPrevPitch(entity.prevRotationPitch); 25 | } 26 | 27 | @Redirect(method = "cacheActiveRenderInfo", at = @At(value = "FIELD", target = "Lnet/minecraft/entity/Entity;prevRotationYaw:F")) 28 | private float modifyPrevYaw(Entity entity) { 29 | return Freelook.getInstance().getPrevYaw(entity.prevRotationYaw); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/main/java/com/jelly/farmhelperv2/remote/event/InteractionAutoComplete.java: -------------------------------------------------------------------------------- 1 | package com.jelly.farmhelperv2.remote.event; 2 | 3 | import com.jelly.farmhelperv2.remote.WebsocketHandler; 4 | import net.dv8tion.jda.api.events.interaction.command.CommandAutoCompleteInteractionEvent; 5 | import net.dv8tion.jda.api.hooks.ListenerAdapter; 6 | import net.dv8tion.jda.api.interactions.commands.Command; 7 | import org.java_websocket.WebSocket; 8 | import org.jetbrains.annotations.NotNull; 9 | 10 | import java.util.ArrayList; 11 | import java.util.HashMap; 12 | import java.util.List; 13 | import java.util.stream.Collectors; 14 | import java.util.stream.Stream; 15 | 16 | public class InteractionAutoComplete extends ListenerAdapter { 17 | 18 | @Override 19 | public void onCommandAutoCompleteInteraction(@NotNull CommandAutoCompleteInteractionEvent event) { 20 | if (!event.getFocusedOption().getName().equals("ign")) return; 21 | HashMap instances = WebsocketHandler.getInstance().getWebsocketServer().minecraftInstances; 22 | List usernames = new ArrayList<>(); 23 | for (WebSocket socket : instances.keySet()) { 24 | usernames.add(instances.get(socket)); 25 | } 26 | List options = Stream.of(usernames.toArray(new String[0])) 27 | .filter(word -> word.toLowerCase() 28 | .startsWith(event.getFocusedOption().getValue().toLowerCase())) 29 | .map(word -> new Command.Choice(word, word)) 30 | .collect(Collectors.toList()); 31 | event.replyChoices(options).queue(); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/main/java/com/jelly/farmhelperv2/remote/event/InteractionCreate.java: -------------------------------------------------------------------------------- 1 | package com.jelly.farmhelperv2.remote.event; 2 | 3 | 4 | import com.jelly.farmhelperv2.remote.DiscordBotHandler; 5 | import com.jelly.farmhelperv2.remote.command.discordCommands.DiscordCommand; 6 | import com.jelly.farmhelperv2.util.LogUtils; 7 | import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent; 8 | import net.dv8tion.jda.api.hooks.ListenerAdapter; 9 | 10 | import java.util.ArrayList; 11 | import java.util.Arrays; 12 | import java.util.Optional; 13 | 14 | public class InteractionCreate extends ListenerAdapter { 15 | 16 | @Override 17 | public void onSlashCommandInteraction(SlashCommandInteractionEvent event) { 18 | String command = event.getName(); 19 | ArrayList commands = DiscordBotHandler.getInstance().getCommands(); 20 | 21 | Optional optionalCommand = commands.stream().filter(cmd -> cmd.name.equalsIgnoreCase(command)).findFirst(); 22 | if (optionalCommand.isPresent()) { 23 | DiscordCommand cmd = optionalCommand.get(); 24 | try { 25 | LogUtils.sendDebug("[Remote Control] Executing command " + cmd.name); 26 | cmd.execute(event); 27 | } catch (Exception e) { 28 | e.printStackTrace(); 29 | } 30 | return; 31 | } 32 | 33 | LogUtils.sendDebug("[Remote Control] Command not found: " + command); 34 | LogUtils.sendDebug("[Remote Control] Commands list: " + Arrays.toString(commands.toArray())); 35 | event.reply("Command not found").queue(); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/main/java/com/jelly/farmhelperv2/remote/command/commands/impl/ReconnectCommand.java: -------------------------------------------------------------------------------- 1 | package com.jelly.farmhelperv2.remote.command.commands.impl; 2 | 3 | import cc.polyfrost.oneconfig.utils.Multithreading; 4 | import com.google.gson.JsonObject; 5 | import com.jelly.farmhelperv2.feature.impl.AutoReconnect; 6 | import com.jelly.farmhelperv2.remote.command.commands.ClientCommand; 7 | import com.jelly.farmhelperv2.remote.command.commands.Command; 8 | import com.jelly.farmhelperv2.remote.struct.RemoteMessage; 9 | 10 | import java.util.concurrent.TimeUnit; 11 | 12 | @Command(label = "reconnect") 13 | public class ReconnectCommand extends ClientCommand { 14 | public static boolean isEnabled = false; 15 | 16 | 17 | @Override 18 | public void execute(RemoteMessage event) { 19 | JsonObject args = event.args; 20 | int delay; 21 | if (args.has("delay")) { 22 | delay = args.get("delay").getAsInt(); 23 | } else { 24 | delay = 5_000; 25 | } 26 | AutoReconnect.getInstance().getReconnectDelay().schedule(delay); 27 | AutoReconnect.getInstance().start(); 28 | isEnabled = true; 29 | Multithreading.schedule(() -> { 30 | JsonObject data = new JsonObject(); 31 | data.addProperty("username", mc.getSession().getUsername()); 32 | data.addProperty("image", getScreenshot()); 33 | data.addProperty("delay", delay); 34 | data.addProperty("uuid", mc.getSession().getPlayerID()); 35 | RemoteMessage response = new RemoteMessage(label, data); 36 | send(response); 37 | }, 1_500, TimeUnit.MILLISECONDS); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/main/java/com/jelly/farmhelperv2/remote/command/commands/impl/InfoCommand.java: -------------------------------------------------------------------------------- 1 | package com.jelly.farmhelperv2.remote.command.commands.impl; 2 | 3 | import com.google.gson.JsonObject; 4 | import com.jelly.farmhelperv2.feature.impl.ProfitCalculator; 5 | import com.jelly.farmhelperv2.handler.MacroHandler; 6 | import com.jelly.farmhelperv2.remote.command.commands.ClientCommand; 7 | import com.jelly.farmhelperv2.remote.command.commands.Command; 8 | import com.jelly.farmhelperv2.remote.struct.RemoteMessage; 9 | import com.jelly.farmhelperv2.util.LogUtils; 10 | 11 | @Command(label = "info") 12 | public class InfoCommand extends ClientCommand { 13 | @Override 14 | public void execute(RemoteMessage message) { 15 | JsonObject data = new JsonObject(); 16 | 17 | data.addProperty("username", mc.getSession().getUsername()); 18 | data.addProperty("runtime", LogUtils.getRuntimeFormat()); 19 | data.addProperty("totalProfit", ProfitCalculator.getInstance().getRealProfitString()); 20 | data.addProperty("profitPerHour", ProfitCalculator.getInstance().getProfitPerHourString()); 21 | data.addProperty("cropType", String.valueOf(MacroHandler.getInstance().getCrop() == null ? "None" : MacroHandler.getInstance().getCrop())); 22 | data.addProperty("currentState", String.valueOf(!MacroHandler.getInstance().getCurrentMacro().isPresent() ? "Macro is not running" : MacroHandler.getInstance().getCurrentMacro().get().getCurrentState())); 23 | data.addProperty("uuid", mc.getSession().getPlayerID()); 24 | data.addProperty("image", getScreenshot()); 25 | 26 | RemoteMessage response = new RemoteMessage(label, data); 27 | send(response); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/main/resources/farmhelper/movrec/ITEM_CHANGE_4.movement: -------------------------------------------------------------------------------- 1 | false;false;false;false;false;false;false;false;false;360.7761;4.8157363;0 2 | false;false;false;false;false;false;false;false;false;361.6043;-1.2181629;1 3 | false;false;false;false;false;false;false;false;false;347.17026;-39.78779;1 4 | false;false;false;false;false;false;false;false;false;340.78143;-74.33482;1 5 | false;false;false;false;false;false;false;false;false;343.14764;-88.76885;1 6 | false;false;false;false;false;false;false;false;false;343.38425;-77.647545;1 7 | false;false;false;false;false;false;false;false;false;359.35632;-50.19922;1 8 | false;false;false;false;false;false;false;false;false;380.41586;-24.762194;1 9 | false;false;false;false;false;false;false;false;false;372.9622;-11.629589;1 10 | false;false;false;false;false;false;false;false;false;355.80704;-8.790108;1 11 | false;false;false;false;false;false;false;false;false;338.41522;-7.60699;1 12 | false;false;false;false;false;false;false;false;false;331.31653;-6.542184;1 13 | false;false;false;false;false;false;false;false;false;330.60663;-4.5308843;1 14 | false;false;false;false;false;false;false;false;false;332.26306;-2.0463376;1 15 | false;false;false;false;false;false;false;false;false;332.4997;-2.0463376;39 16 | false;false;false;false;false;false;false;false;false;333.80112;-2.0463376;1 17 | false;false;false;false;false;false;false;false;false;345.0407;-1.4547788;1 18 | false;false;false;false;false;false;false;false;false;356.75357;-0.62659645;1 19 | false;false;false;false;false;false;false;false;false;360.77618;-0.38997293;1 20 | false;false;false;false;false;false;false;false;false;361.6044;-0.38997293;1 21 | false;false;false;false;false;false;false;false;false;362.07767;-0.38997293;0 22 | -------------------------------------------------------------------------------- /src/main/java/com/jelly/farmhelperv2/remote/command/discordCommands/impl/Help.java: -------------------------------------------------------------------------------- 1 | package com.jelly.farmhelperv2.remote.command.discordCommands.impl; 2 | 3 | import com.jelly.farmhelperv2.remote.DiscordBotHandler; 4 | import com.jelly.farmhelperv2.remote.command.discordCommands.DiscordCommand; 5 | import net.dv8tion.jda.api.EmbedBuilder; 6 | import net.dv8tion.jda.api.entities.MessageEmbed; 7 | import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent; 8 | 9 | public class Help extends DiscordCommand { 10 | public static final String name = "help"; 11 | public static final String description = "Get information about commands"; 12 | 13 | public Help() { 14 | super(Help.name, Help.description); 15 | } 16 | 17 | @Override 18 | public void execute(SlashCommandInteractionEvent event) { 19 | event.deferReply().queue(); 20 | EmbedBuilder builder = new EmbedBuilder(); 21 | builder.setTitle("FarmHelper Remote Control"); 22 | builder.setDescription("Commands list"); 23 | for (DiscordCommand command : DiscordBotHandler.getInstance().getCommands()) { 24 | builder.addField(command.name, command.description, false); 25 | } 26 | int random = (int) (Math.random() * 0xFFFFFF); 27 | builder.setColor(random); 28 | builder.setFooter("-> FarmHelper Remote Control", "https://cdn.discordapp.com/attachments/861700235890130986/1144673641951395982/icon.png"); 29 | MessageEmbed embed = builder.build(); 30 | try { 31 | event.getHook().sendMessageEmbeds(embed).queue(); 32 | } catch (Exception e) { 33 | event.getChannel().sendMessageEmbeds(embed).queue(); 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/main/java/com/jelly/farmhelperv2/transformer/Tweaker.java: -------------------------------------------------------------------------------- 1 | package com.jelly.farmhelperv2.transformer; 2 | 3 | import net.minecraft.launchwrapper.ITweaker; 4 | import net.minecraft.launchwrapper.Launch; 5 | import net.minecraft.launchwrapper.LaunchClassLoader; 6 | import org.spongepowered.asm.launch.MixinBootstrap; 7 | import org.spongepowered.asm.mixin.MixinEnvironment; 8 | import org.spongepowered.asm.mixin.Mixins; 9 | import org.spongepowered.tools.obfuscation.mcp.ObfuscationServiceMCP; 10 | 11 | import java.io.File; 12 | import java.util.List; 13 | 14 | public class Tweaker implements ITweaker { 15 | 16 | @Override 17 | public void acceptOptions(List args, File gameDir, File assetsDir, String profile) { 18 | 19 | } 20 | 21 | @Override 22 | public void injectIntoClassLoader(LaunchClassLoader classLoader) { 23 | MixinBootstrap.init(); 24 | 25 | // noinspection unchecked 26 | List tweakClasses = (List) Launch.blackboard.get("TweakClasses"); 27 | String obfuscation = ObfuscationServiceMCP.NOTCH; 28 | 29 | if (tweakClasses.stream().anyMatch(s -> s.contains("net.minecraftforge.fml.common.launcher"))) { 30 | obfuscation = ObfuscationServiceMCP.SEARGE; 31 | } 32 | 33 | MixinEnvironment.getDefaultEnvironment().setSide(MixinEnvironment.Side.CLIENT); 34 | MixinEnvironment.getDefaultEnvironment().setObfuscationContext(obfuscation); 35 | 36 | Mixins.addConfiguration("mixins.baritone.json"); 37 | } 38 | 39 | @Override 40 | public String getLaunchTarget() { 41 | return null; 42 | } 43 | 44 | @Override 45 | public String[] getLaunchArguments() { 46 | return new String[0]; 47 | } 48 | } -------------------------------------------------------------------------------- /src/main/java/com/jelly/farmhelperv2/util/ReflectionUtils.java: -------------------------------------------------------------------------------- 1 | package com.jelly.farmhelperv2.util; 2 | 3 | import net.minecraft.client.Minecraft; 4 | 5 | import java.lang.reflect.Field; 6 | import java.lang.reflect.Method; 7 | import java.nio.file.Path; 8 | import java.util.Arrays; 9 | 10 | public class ReflectionUtils { 11 | 12 | public static boolean invoke(Object object, String methodName) { 13 | try { 14 | final Method method = object.getClass().getDeclaredMethod(methodName); 15 | method.setAccessible(true); 16 | method.invoke(object); 17 | return true; 18 | } catch (Exception ignored) { 19 | } 20 | return false; 21 | } 22 | 23 | public static Object field(Object object, String name) { 24 | try { 25 | Field field = object.getClass().getDeclaredField(name); 26 | field.setAccessible(true); 27 | return field.get(object); 28 | } catch (Exception ignored) { 29 | } 30 | return null; 31 | } 32 | 33 | public static boolean hasPackageInstalled(String name) { 34 | Package[] packages = Package.getPackages(); 35 | 36 | for (Package pack : packages) { 37 | if (pack.getName().contains(name)) { 38 | return true; 39 | } 40 | } 41 | return false; 42 | } 43 | 44 | public static boolean hasModFile(String name) { 45 | Path modsDir = Minecraft.getMinecraft().mcDataDir.toPath().resolve("mods"); 46 | String[] modFiles = modsDir.toFile().list(); 47 | return modFiles != null && Arrays.stream(modFiles).anyMatch(modFile -> modFile.toLowerCase().contains(name.toLowerCase()) && !modFile.toLowerCase().endsWith(".disabled")); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/main/java/com/jelly/farmhelperv2/remote/command/commands/impl/AutoSellCommand.java: -------------------------------------------------------------------------------- 1 | package com.jelly.farmhelperv2.remote.command.commands.impl; 2 | 3 | import com.google.gson.JsonObject; 4 | import com.jelly.farmhelperv2.feature.impl.AutoSell; 5 | import com.jelly.farmhelperv2.handler.GameStateHandler; 6 | import com.jelly.farmhelperv2.remote.command.commands.ClientCommand; 7 | import com.jelly.farmhelperv2.remote.command.commands.Command; 8 | import com.jelly.farmhelperv2.remote.struct.RemoteMessage; 9 | 10 | @Command(label = "autosell") 11 | public class AutoSellCommand extends ClientCommand { 12 | 13 | @Override 14 | public void execute(RemoteMessage message) { 15 | JsonObject data = new JsonObject(); 16 | data.addProperty("username", mc.getSession().getUsername()); 17 | data.addProperty("uuid", mc.getSession().getPlayerID()); 18 | data.addProperty("toggled", !AutoSell.getInstance().isEnabled()); 19 | 20 | if (GameStateHandler.getInstance().getCookieBuffState() != GameStateHandler.BuffState.ACTIVE) 21 | data.addProperty("info", "You don't have cookie buff active!"); 22 | else if (GameStateHandler.getInstance().getServerClosingSeconds().isPresent()) 23 | data.addProperty("info", "Server is closing in " + GameStateHandler.getInstance().getServerClosingSeconds().get() + " seconds!"); 24 | else if (GameStateHandler.getInstance().getLocation() != GameStateHandler.Location.GARDEN) 25 | data.addProperty("info", "You are not in the garden!"); 26 | else { 27 | AutoSell.getInstance().enable(true); 28 | data.addProperty("info", "AutoSell enabled"); 29 | } 30 | 31 | RemoteMessage response = new RemoteMessage(label, data); 32 | send(response); 33 | } 34 | } -------------------------------------------------------------------------------- /src/main/java/com/jelly/farmhelperv2/failsafe/Failsafe.java: -------------------------------------------------------------------------------- 1 | package com.jelly.farmhelperv2.failsafe; 2 | 3 | import com.jelly.farmhelperv2.event.BlockChangeEvent; 4 | import com.jelly.farmhelperv2.event.ReceivePacketEvent; 5 | import net.minecraft.client.Minecraft; 6 | import net.minecraftforge.client.event.ClientChatReceivedEvent; 7 | import net.minecraftforge.event.world.WorldEvent; 8 | import net.minecraftforge.fml.common.gameevent.TickEvent; 9 | import net.minecraftforge.fml.common.network.FMLNetworkEvent; 10 | 11 | public abstract class Failsafe { 12 | public final Minecraft mc = Minecraft.getMinecraft(); 13 | 14 | public abstract int getPriority(); 15 | 16 | public abstract FailsafeManager.EmergencyType getType(); 17 | 18 | public abstract boolean shouldSendNotification(); 19 | 20 | public abstract boolean shouldPlaySound(); 21 | 22 | public abstract boolean shouldTagEveryone(); 23 | 24 | public abstract boolean shouldAltTab(); 25 | 26 | public void onBlockChange(BlockChangeEvent event) { 27 | } 28 | 29 | public void onReceivedPacketDetection(ReceivePacketEvent event) { 30 | } 31 | 32 | public void onTickDetection(TickEvent.ClientTickEvent event) { 33 | } 34 | 35 | public void onChatDetection(ClientChatReceivedEvent event) { 36 | } 37 | 38 | public void onWorldUnloadDetection(WorldEvent.Unload event) { 39 | } 40 | 41 | public void onDisconnectDetection(FMLNetworkEvent.ClientDisconnectionFromServerEvent event) { 42 | } 43 | 44 | public abstract void duringFailsafeTrigger(); 45 | 46 | public abstract void endOfFailsafeTrigger(); 47 | 48 | private void possibleDetectionOfCheck() { 49 | FailsafeManager.getInstance().possibleDetection(this); 50 | } 51 | 52 | public void resetStates() { 53 | } 54 | } -------------------------------------------------------------------------------- /src/main/java/com/jelly/farmhelperv2/util/helper/Clock.java: -------------------------------------------------------------------------------- 1 | package com.jelly.farmhelperv2.util.helper; 2 | 3 | import lombok.Getter; 4 | 5 | public class Clock { 6 | private long remainingTime; 7 | @Getter 8 | private boolean paused; 9 | @Getter 10 | private boolean scheduled; 11 | @Getter 12 | private long endTime; 13 | 14 | public void schedule(long milliseconds) { 15 | this.endTime = System.currentTimeMillis() + milliseconds; 16 | this.remainingTime = milliseconds; 17 | this.scheduled = true; 18 | this.paused = false; 19 | } 20 | 21 | public void schedule(double milliseconds) { 22 | this.endTime = (System.currentTimeMillis() + (long) milliseconds); 23 | this.remainingTime = (long) milliseconds; 24 | this.scheduled = true; 25 | this.paused = false; 26 | } 27 | 28 | public long getRemainingTime() { 29 | if (paused) { 30 | return remainingTime; 31 | } 32 | if (endTime - System.currentTimeMillis() < 0) { 33 | return 0; 34 | } 35 | return endTime - System.currentTimeMillis(); 36 | } 37 | 38 | public boolean passed() { 39 | return System.currentTimeMillis() >= endTime; 40 | } 41 | 42 | public void pause() { 43 | if (scheduled && !paused) { 44 | remainingTime = endTime - System.currentTimeMillis(); 45 | paused = true; 46 | } 47 | } 48 | 49 | public void resume() { 50 | if (scheduled && paused) { 51 | endTime = System.currentTimeMillis() + remainingTime; 52 | paused = false; 53 | } 54 | } 55 | 56 | public void reset() { 57 | scheduled = false; 58 | paused = false; 59 | endTime = 0; 60 | remainingTime = 0; 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /src/main/java/com/jelly/farmhelperv2/mixin/client/MixinEntity.java: -------------------------------------------------------------------------------- 1 | package com.jelly.farmhelperv2.mixin.client; 2 | 3 | import com.jelly.farmhelperv2.config.FarmHelperConfig; 4 | import com.jelly.farmhelperv2.pathfinder.FlyPathFinderExecutor; 5 | import net.minecraft.client.Minecraft; 6 | import net.minecraft.entity.Entity; 7 | import org.spongepowered.asm.mixin.Mixin; 8 | import org.spongepowered.asm.mixin.Shadow; 9 | import org.spongepowered.asm.mixin.Unique; 10 | import org.spongepowered.asm.mixin.injection.At; 11 | import org.spongepowered.asm.mixin.injection.Inject; 12 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; 13 | 14 | @Mixin(value = Entity.class, priority = 2000) 15 | public abstract class MixinEntity { 16 | @Shadow 17 | public float rotationYaw; 18 | 19 | @Shadow 20 | public abstract void moveFlying(float strafe, float forward, float friction); 21 | 22 | @Unique 23 | public boolean farmHelperV2$secondCall; 24 | 25 | @Inject(method = "moveFlying", at = @At("HEAD"), cancellable = true) 26 | private void moveFlyingHead(float strafe, float forward, float friction, CallbackInfo ci) { 27 | if (!FlyPathFinderExecutor.getInstance().isPathingOrDecelerating() || FlyPathFinderExecutor.getInstance().getNeededYaw() == Integer.MIN_VALUE) 28 | return; 29 | if ((Object) this != Minecraft.getMinecraft().thePlayer) return; 30 | if (farmHelperV2$secondCall) { 31 | farmHelperV2$secondCall = false; 32 | return; 33 | } 34 | float cachedYawM = rotationYaw; 35 | rotationYaw = !FarmHelperConfig.flyPathfinderOringoCompatible ? FlyPathFinderExecutor.getInstance().getNeededYaw() : this.rotationYaw; 36 | farmHelperV2$secondCall = true; 37 | moveFlying(strafe, forward, friction); 38 | rotationYaw = cachedYawM; 39 | ci.cancel(); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/main/java/com/jelly/farmhelperv2/util/TablistUtils.java: -------------------------------------------------------------------------------- 1 | package com.jelly.farmhelperv2.util; 2 | 3 | import com.google.common.collect.ComparisonChain; 4 | import com.google.common.collect.Ordering; 5 | import net.minecraft.client.network.NetworkPlayerInfo; 6 | import net.minecraft.scoreboard.ScorePlayerTeam; 7 | import net.minecraft.world.WorldSettings; 8 | import net.minecraftforge.fml.relauncher.Side; 9 | import net.minecraftforge.fml.relauncher.SideOnly; 10 | 11 | import java.util.Comparator; 12 | import java.util.List; 13 | import java.util.concurrent.CopyOnWriteArrayList; 14 | 15 | public class TablistUtils { 16 | 17 | public static final Ordering playerOrdering = Ordering.from(new PlayerComparator()); 18 | 19 | private static final CopyOnWriteArrayList cachedTablist = new CopyOnWriteArrayList<>(); 20 | 21 | public static List getTabList() { 22 | return cachedTablist; 23 | } 24 | 25 | public static void setCachedTablist(List tablist) { 26 | cachedTablist.clear(); 27 | cachedTablist.addAll(tablist); 28 | } 29 | 30 | @SideOnly(Side.CLIENT) 31 | static class PlayerComparator implements Comparator { 32 | private PlayerComparator() { 33 | } 34 | 35 | public int compare(NetworkPlayerInfo o1, NetworkPlayerInfo o2) { 36 | ScorePlayerTeam team1 = o1.getPlayerTeam(); 37 | ScorePlayerTeam team2 = o2.getPlayerTeam(); 38 | return ComparisonChain.start().compareTrueFirst( 39 | o1.getGameType() != WorldSettings.GameType.SPECTATOR, 40 | o2.getGameType() != WorldSettings.GameType.SPECTATOR 41 | ) 42 | .compare( 43 | team1 != null ? team1.getRegisteredName() : "", 44 | team2 != null ? team2.getRegisteredName() : "" 45 | ) 46 | .compare(o1.getGameProfile().getName(), o2.getGameProfile().getName()).result(); 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/main/java/com/jelly/farmhelperv2/mixin/block/MixinBlockMushroom.java: -------------------------------------------------------------------------------- 1 | package com.jelly.farmhelperv2.mixin.block; 2 | 3 | import com.jelly.farmhelperv2.config.FarmHelperConfig; 4 | import net.minecraft.block.Block; 5 | import net.minecraft.block.BlockBush; 6 | import net.minecraft.block.BlockMushroom; 7 | import net.minecraft.client.Minecraft; 8 | import net.minecraft.init.Blocks; 9 | import net.minecraft.util.AxisAlignedBB; 10 | import net.minecraft.util.BlockPos; 11 | import net.minecraft.util.MovingObjectPosition; 12 | import net.minecraft.util.Vec3; 13 | import net.minecraft.world.World; 14 | import org.spongepowered.asm.mixin.Mixin; 15 | import org.spongepowered.asm.mixin.Unique; 16 | 17 | @Mixin(value = {BlockMushroom.class}, priority = 2000) 18 | public class MixinBlockMushroom extends BlockBush { 19 | @Override 20 | public AxisAlignedBB getSelectedBoundingBox(World worldIn, BlockPos pos) { 21 | Block block = Minecraft.getMinecraft().theWorld.getBlockState(pos).getBlock(); 22 | if (block.equals(Blocks.brown_mushroom) || block.equals(Blocks.red_mushroom)) { 23 | farmHelperV2$setMushroomBoundings(worldIn, pos); 24 | } 25 | return super.getSelectedBoundingBox(worldIn, pos); 26 | } 27 | 28 | @Override 29 | public MovingObjectPosition collisionRayTrace(World worldIn, BlockPos pos, Vec3 start, Vec3 end) { 30 | Block block = Minecraft.getMinecraft().theWorld.getBlockState(pos).getBlock(); 31 | if (block.equals(Blocks.brown_mushroom) || block.equals(Blocks.red_mushroom)) { 32 | farmHelperV2$setMushroomBoundings(worldIn, pos); 33 | } 34 | return super.collisionRayTrace(worldIn, pos, start, end); 35 | } 36 | 37 | @Unique 38 | private void farmHelperV2$setMushroomBoundings(World worldIn, BlockPos pos) { 39 | if (FarmHelperConfig.increasedMushrooms) 40 | worldIn.getBlockState(pos).getBlock().setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 0.5f, 1.0F); 41 | else 42 | worldIn.getBlockState(pos).getBlock().setBlockBounds(0.3F, 0.0F, 0.3F, 0.7F, 0.5f, 0.7F); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/main/java/com/jelly/farmhelperv2/remote/waiter/WaiterHandler.java: -------------------------------------------------------------------------------- 1 | package com.jelly.farmhelperv2.remote.waiter; 2 | 3 | import com.jelly.farmhelperv2.remote.struct.RemoteMessage; 4 | import com.jelly.farmhelperv2.util.LogUtils; 5 | import net.minecraft.util.Tuple; 6 | 7 | import java.util.HashMap; 8 | import java.util.Set; 9 | import java.util.Timer; 10 | import java.util.TimerTask; 11 | 12 | public class WaiterHandler { 13 | private static final HashMap waiterMap = new HashMap<>(); 14 | 15 | public static void register(Waiter waiterToRegister) { 16 | waiterMap.put(waiterToRegister, waiterToRegister.getTimeout()); 17 | Timer timer = new Timer(); 18 | timer.schedule(new TimerTask() { 19 | @Override 20 | public void run() { 21 | Tuple waiterTuple = null; 22 | for (Waiter waiter : waiterMap.keySet()) { 23 | if (waiter == waiterToRegister) { 24 | waiterTuple = new Tuple<>(waiter, waiterMap.get(waiter)); 25 | } 26 | } 27 | if (waiterTuple != null && waiterTuple.getSecond() != null && !waiterTuple.getFirst().isAnsweredAtLeastOnce()) { //if waiter was in the list && there is a timeoutAction 28 | waiterToRegister.getTimeoutAction().accept(null); 29 | } else if (waiterTuple != null && waiterTuple.getFirst().isAnsweredAtLeastOnce()) { 30 | waiterMap.remove(waiterTuple.getFirst()); 31 | } 32 | } 33 | }, waiterToRegister.getTimeout()); 34 | } 35 | 36 | public static void onMessage(RemoteMessage websocketMessage) { 37 | String command = websocketMessage.command; 38 | LogUtils.sendDebug("Received message: " + command); 39 | Set waiters = waiterMap.keySet(); 40 | for (Waiter waiter : waiters) { 41 | if (waiter.getCommand().equalsIgnoreCase(command)) { 42 | waiter.getAction().accept(websocketMessage); 43 | waiter.setAnsweredAtLeastOnce(true); 44 | return; 45 | } 46 | } 47 | LogUtils.sendDebug("No waiter found for command: " + command); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/main/java/com/jelly/farmhelperv2/mixin/client/MixinEntityPlayerSP.java: -------------------------------------------------------------------------------- 1 | package com.jelly.farmhelperv2.mixin.client; 2 | 3 | import com.jelly.farmhelperv2.event.MotionUpdateEvent; 4 | import com.jelly.farmhelperv2.feature.impl.Freelook; 5 | import com.mojang.authlib.GameProfile; 6 | import net.minecraft.client.entity.AbstractClientPlayer; 7 | import net.minecraft.client.entity.EntityPlayerSP; 8 | import net.minecraft.util.MathHelper; 9 | import net.minecraft.world.World; 10 | import net.minecraftforge.common.MinecraftForge; 11 | import org.spongepowered.asm.mixin.Mixin; 12 | import org.spongepowered.asm.mixin.injection.At; 13 | import org.spongepowered.asm.mixin.injection.Inject; 14 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; 15 | 16 | @Mixin(value = EntityPlayerSP.class, priority = Integer.MAX_VALUE) 17 | public abstract class MixinEntityPlayerSP extends AbstractClientPlayer { 18 | public MixinEntityPlayerSP(World worldIn, GameProfile playerProfile) { 19 | super(worldIn, playerProfile); 20 | } 21 | 22 | @Override 23 | public void setAngles(float yaw, float pitch) { 24 | if (Freelook.getInstance().isRunning()) { 25 | Freelook.getInstance().setCameraPrevYaw(Freelook.getInstance().getCameraYaw()); 26 | Freelook.getInstance().setCameraPrevPitch(Freelook.getInstance().getCameraPitch()); 27 | Freelook.getInstance().setCameraYaw((float) (Freelook.getInstance().getCameraYaw() + (yaw * 0.15))); 28 | Freelook.getInstance().setCameraPitch((float) (Freelook.getInstance().getCameraPitch() + (pitch * -0.15))); 29 | Freelook.getInstance().setCameraPitch(MathHelper.clamp_float(Freelook.getInstance().getCameraPitch(), -90.0F, 90.0F)); 30 | } else { 31 | super.setAngles(yaw, pitch); 32 | } 33 | } 34 | 35 | @Inject(method = "onUpdateWalkingPlayer", at = @At("HEAD")) 36 | public void onUpdateWalkingPlayer(CallbackInfo ci) { 37 | MinecraftForge.EVENT_BUS.post(new MotionUpdateEvent.Pre(this.rotationYaw, this.rotationPitch)); 38 | } 39 | 40 | @Inject(method = "onUpdateWalkingPlayer", at = @At("RETURN")) 41 | public void onUpdateWalkingPlayerReturn(CallbackInfo ci) { 42 | MinecraftForge.EVENT_BUS.post(new MotionUpdateEvent.Post(this.rotationYaw, this.rotationPitch)); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/main/java/com/jelly/farmhelperv2/remote/struct/WebsocketClient.java: -------------------------------------------------------------------------------- 1 | package com.jelly.farmhelperv2.remote.struct; 2 | 3 | import com.jelly.farmhelperv2.FarmHelper; 4 | import com.jelly.farmhelperv2.remote.WebsocketHandler; 5 | import com.jelly.farmhelperv2.remote.command.commands.ClientCommand; 6 | import com.jelly.farmhelperv2.remote.util.RemoteUtils; 7 | import com.jelly.farmhelperv2.util.LogUtils; 8 | import org.java_websocket.client.WebSocketClient; 9 | import org.java_websocket.handshake.ServerHandshake; 10 | 11 | import java.net.URI; 12 | import java.util.Optional; 13 | 14 | public class WebsocketClient extends WebSocketClient { 15 | public WebsocketClient(URI serverUri) { 16 | super(serverUri); 17 | } 18 | 19 | @Override 20 | public void onOpen(ServerHandshake handshakedata) { 21 | LogUtils.sendSuccess("Connected to websocket server"); 22 | } 23 | 24 | @Override 25 | public void onMessage(String message) { 26 | try { 27 | RemoteMessage remoteMessage = FarmHelper.gson.fromJson(message, RemoteMessage.class); 28 | String command = remoteMessage.command; 29 | LogUtils.sendDebug("Command: " + command); 30 | 31 | Optional commandInstance = RemoteUtils.getCommand(WebsocketHandler.commands, (cmd) -> cmd.label.equalsIgnoreCase(command)); 32 | commandInstance.ifPresent(clientCommand -> clientCommand.execute(remoteMessage)); 33 | } catch (Exception ex) { 34 | ex.printStackTrace(); 35 | } 36 | } 37 | 38 | @Override 39 | public void onClose(int code, String reason, boolean remote) { 40 | if (code == -1) { 41 | LogUtils.sendDebug("Server doesn't exist"); 42 | return; 43 | } 44 | if (code == 4169) { 45 | LogUtils.sendDebug("Server doesn't have auth header"); 46 | return; 47 | } 48 | if (code == 4069) { 49 | LogUtils.sendDebug("Server already has client with this name"); 50 | return; 51 | } 52 | LogUtils.sendError("Disconnected from websocket server"); 53 | LogUtils.sendDebug("Reason: " + reason + " Code: " + code + " Remote: " + remote); 54 | } 55 | 56 | @Override 57 | public void onError(Exception ex) { 58 | ex.printStackTrace(); 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /src/main/java/com/jelly/farmhelperv2/hud/UsageStatsHUD.java: -------------------------------------------------------------------------------- 1 | package com.jelly.farmhelperv2.hud; 2 | 3 | import cc.polyfrost.oneconfig.config.core.OneColor; 4 | import cc.polyfrost.oneconfig.hud.TextHud; 5 | import com.jelly.farmhelperv2.config.FarmHelperConfig; 6 | import com.jelly.farmhelperv2.feature.impl.UsageStatsTracker; 7 | import com.jelly.farmhelperv2.handler.GameStateHandler; 8 | 9 | import java.util.List; 10 | 11 | public class UsageStatsHUD extends TextHud { 12 | 13 | public UsageStatsHUD() { 14 | super(true, 1f, 10f, 0.9f, true, true, 15 | 4, 5, 5, new OneColor(0,0,0,150), 16 | false, 2, new OneColor(0,0,0,127)); 17 | } 18 | 19 | @Override 20 | protected void getLines(List lines, boolean example) { 21 | if (FarmHelperConfig.showStatsTitle) { 22 | lines.add("§lFH Usage Stats"); 23 | } 24 | if (FarmHelperConfig.showStats24H) { 25 | String colour = ""; 26 | if (FarmHelperConfig.colourCode24H) { 27 | double hrs = UsageStatsTracker.getInstance().getTodayMillis() / 3_600_000.0; 28 | if (hrs < 3.5) colour = "§a"; 29 | else if (hrs < 7.0) colour = "§6"; 30 | else colour = "§c"; 31 | } 32 | lines.add("24 hour: " + colour + UsageStatsTracker.getInstance().getTodayString()); 33 | } 34 | if (FarmHelperConfig.showStats7D) { 35 | lines.add("7 day: §a" + UsageStatsTracker.getInstance().get7dString()); 36 | } 37 | if (FarmHelperConfig.showStats30D) { 38 | lines.add("30 day: §a" + UsageStatsTracker.getInstance().get30dString()); 39 | } 40 | if (FarmHelperConfig.showStatsLifetime) { 41 | lines.add("lifetime: §a" + UsageStatsTracker.getInstance().getTotalString()); 42 | } 43 | if (!FarmHelperConfig.showStatsTitle &&!FarmHelperConfig.showStats24H && !FarmHelperConfig.showStats7D && !FarmHelperConfig.showStats30D && !FarmHelperConfig.showStatsLifetime) { 44 | lines.add("§cEnable usage stats in the HUD config menu"); 45 | } 46 | } 47 | 48 | @Override 49 | protected boolean shouldShow() { 50 | return super.shouldShow() 51 | && !FarmHelperConfig.streamerMode 52 | && GameStateHandler.getInstance().inGarden(); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /src/main/java/com/jelly/farmhelperv2/feature/impl/PerformanceMode.java: -------------------------------------------------------------------------------- 1 | package com.jelly.farmhelperv2.feature.impl; 2 | 3 | import com.jelly.farmhelperv2.config.FarmHelperConfig; 4 | import com.jelly.farmhelperv2.feature.IFeature; 5 | import net.minecraft.client.Minecraft; 6 | 7 | public class PerformanceMode implements IFeature { 8 | private final Minecraft mc = Minecraft.getMinecraft(); 9 | private static PerformanceMode instance; 10 | 11 | public static PerformanceMode getInstance() { 12 | if (instance == null) { 13 | instance = new PerformanceMode(); 14 | } 15 | return instance; 16 | } 17 | 18 | private int renderDistanceBefore = 0; 19 | private int maxFpsBefore = 0; 20 | 21 | private boolean enabled = false; 22 | 23 | @Override 24 | public String getName() { 25 | return "Performance Mode"; 26 | } 27 | 28 | @Override 29 | public boolean isRunning() { 30 | return enabled; 31 | } 32 | 33 | @Override 34 | public boolean shouldPauseMacroExecution() { 35 | return false; 36 | } 37 | 38 | @Override 39 | public boolean shouldStartAtMacroStart() { 40 | return isToggled(); 41 | } 42 | 43 | @Override 44 | public void start() { 45 | enabled = true; 46 | renderDistanceBefore = mc.gameSettings.renderDistanceChunks; 47 | maxFpsBefore = mc.gameSettings.limitFramerate; 48 | mc.gameSettings.renderDistanceChunks = 1; 49 | mc.gameSettings.limitFramerate = FarmHelperConfig.performanceModeMaxFPS; 50 | mc.addScheduledTask(() -> mc.renderGlobal.loadRenderers()); 51 | IFeature.super.start(); 52 | } 53 | 54 | @Override 55 | public void stop() { 56 | enabled = false; 57 | mc.gameSettings.renderDistanceChunks = renderDistanceBefore; 58 | mc.gameSettings.limitFramerate = maxFpsBefore; 59 | renderDistanceBefore = 0; 60 | maxFpsBefore = 0; 61 | mc.addScheduledTask(() -> mc.renderGlobal.loadRenderers()); 62 | IFeature.super.stop(); 63 | } 64 | 65 | @Override 66 | public void resetStatesAfterMacroDisabled() { 67 | 68 | } 69 | 70 | @Override 71 | public boolean isToggled() { 72 | return FarmHelperConfig.performanceMode; 73 | } 74 | 75 | @Override 76 | public boolean shouldCheckForFailsafes() { 77 | return false; 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /src/main/java/com/jelly/farmhelperv2/command/RewarpCommand.java: -------------------------------------------------------------------------------- 1 | package com.jelly.farmhelperv2.command; 2 | 3 | import com.jelly.farmhelperv2.config.FarmHelperConfig; 4 | import com.jelly.farmhelperv2.util.LogUtils; 5 | import net.minecraft.command.CommandBase; 6 | import net.minecraft.command.ICommand; 7 | import net.minecraft.command.ICommandSender; 8 | import net.minecraft.util.BlockPos; 9 | import org.jetbrains.annotations.NotNull; 10 | 11 | import java.util.ArrayList; 12 | import java.util.List; 13 | 14 | public class RewarpCommand extends CommandBase { 15 | @Override 16 | public String getCommandName() { 17 | return "fhrewarp"; 18 | } 19 | 20 | @Override 21 | public String getCommandUsage(ICommandSender sender) { 22 | return "/fhrewarp [add|remove|removeall]"; 23 | } 24 | 25 | @Override 26 | public List getCommandAliases() { 27 | return new ArrayList<>(); 28 | } 29 | 30 | @Override 31 | public void processCommand(ICommandSender sender, String[] args) { 32 | if (args.length != 1) { 33 | LogUtils.sendError("Invalid arguments. Use " + getCommandUsage(sender)); 34 | return; 35 | } 36 | 37 | switch (args[0]) { 38 | case "add": { 39 | FarmHelperConfig.addRewarp(); 40 | break; 41 | } 42 | case "remove": { 43 | FarmHelperConfig.removeRewarp(); 44 | break; 45 | } 46 | case "removeall": { 47 | FarmHelperConfig.removeAllRewarps(); 48 | break; 49 | } 50 | default: { 51 | LogUtils.sendError("Invalid argument. Use " + getCommandUsage(sender)); 52 | break; 53 | } 54 | } 55 | } 56 | 57 | @Override 58 | public boolean canCommandSenderUseCommand(ICommandSender sender) { 59 | return true; 60 | } 61 | 62 | @Override 63 | public List addTabCompletionOptions(ICommandSender sender, String[] args, BlockPos pos) { 64 | return null; 65 | } 66 | 67 | @Override 68 | public boolean isUsernameIndex(String[] args, int index) { 69 | return false; 70 | } 71 | 72 | @Override 73 | public int compareTo(@NotNull ICommand o) { 74 | return 0; 75 | } 76 | 77 | @Override 78 | public int getRequiredPermissionLevel() { 79 | return -1; 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /src/main/java/com/jelly/farmhelperv2/mixin/block/MixinBlockRendererDispatcher.java: -------------------------------------------------------------------------------- 1 | package com.jelly.farmhelperv2.mixin.block; 2 | 3 | 4 | import com.google.common.collect.Sets; 5 | import com.jelly.farmhelperv2.config.FarmHelperConfig; 6 | import com.jelly.farmhelperv2.handler.MacroHandler; 7 | import net.minecraft.block.Block; 8 | import net.minecraft.block.state.IBlockState; 9 | import net.minecraft.client.Minecraft; 10 | import net.minecraft.client.renderer.BlockRendererDispatcher; 11 | import net.minecraft.client.renderer.WorldRenderer; 12 | import net.minecraft.init.Blocks; 13 | import net.minecraft.util.BlockPos; 14 | import net.minecraft.world.IBlockAccess; 15 | import org.spongepowered.asm.mixin.Mixin; 16 | import org.spongepowered.asm.mixin.Unique; 17 | import org.spongepowered.asm.mixin.injection.At; 18 | import org.spongepowered.asm.mixin.injection.Inject; 19 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; 20 | 21 | import java.util.Set; 22 | 23 | 24 | @Mixin(BlockRendererDispatcher.class) 25 | public class MixinBlockRendererDispatcher { 26 | private Minecraft mc = Minecraft.getMinecraft(); 27 | @Unique 28 | private static final Set cropBlocks = Sets.newHashSet( 29 | Blocks.cocoa, 30 | Blocks.reeds, 31 | Blocks.nether_wart, 32 | Blocks.wheat, 33 | Blocks.carrots, 34 | Blocks.potatoes, 35 | Blocks.pumpkin, 36 | Blocks.pumpkin_stem, 37 | Blocks.melon_block, 38 | Blocks.melon_stem, 39 | Blocks.brown_mushroom, 40 | Blocks.red_mushroom, 41 | Blocks.cactus 42 | ); 43 | 44 | @Inject(method = "renderBlock", at = @At("HEAD"), cancellable = true) 45 | private void renderBlock(IBlockState state, BlockPos pos, IBlockAccess blockAccess, WorldRenderer worldRendererIn, CallbackInfoReturnable cir) { 46 | if (FarmHelperConfig.performanceMode && (MacroHandler.getInstance().isMacroToggled())) { 47 | if (FarmHelperConfig.fastRender) { 48 | BlockPos playerPos = new BlockPos(mc.thePlayer.posX, mc.thePlayer.posY, mc.thePlayer.posZ); 49 | if (playerPos.distanceSq(pos) > 25 && FarmHelperConfig.fastRender) { 50 | cir.setReturnValue(false); 51 | } 52 | } else if (cropBlocks.contains(state.getBlock())) { 53 | cir.setReturnValue(false); 54 | } 55 | } 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /src/main/java/com/jelly/farmhelperv2/pathfinder/FlyNodeProcessor.java: -------------------------------------------------------------------------------- 1 | package com.jelly.farmhelperv2.pathfinder; 2 | 3 | import cc.polyfrost.oneconfig.libs.checker.nullness.qual.Nullable; 4 | import com.jelly.farmhelperv2.util.BlockUtils; 5 | import net.minecraft.client.Minecraft; 6 | import net.minecraft.entity.Entity; 7 | import net.minecraft.pathfinding.PathPoint; 8 | import net.minecraft.util.EnumFacing; 9 | import net.minecraft.util.MathHelper; 10 | import net.minecraft.world.pathfinder.NodeProcessor; 11 | 12 | public class FlyNodeProcessor extends NodeProcessor { 13 | 14 | @Override 15 | public PathPoint getPathPointTo(Entity entityIn) { 16 | return this.openPoint(MathHelper.floor_double(entityIn.getEntityBoundingBox().minX), MathHelper.floor_double(entityIn.getEntityBoundingBox().minY + 0.5D), MathHelper.floor_double(entityIn.getEntityBoundingBox().minZ)); 17 | } 18 | 19 | @Override 20 | public PathPoint getPathPointToCoords(Entity entityIn, double x, double y, double z) { 21 | return this.openPoint(MathHelper.floor_double(x - (entityIn.width / 2.0D)), MathHelper.floor_double(y - (entityIn.height / 2.0D)), MathHelper.floor_double(z - (entityIn.width / 2.0D))); 22 | } 23 | 24 | @Override 25 | public int findPathOptions(PathPoint[] pathOptions, Entity entityIn, PathPoint currentPoint, PathPoint targetPoint, float maxDistance) { 26 | int i = 0; 27 | for (EnumFacing enumfacing : EnumFacing.values()) { 28 | PathPoint pathpoint = this.getAirNode(currentPoint.xCoord + enumfacing.getFrontOffsetX(), currentPoint.yCoord + enumfacing.getFrontOffsetY(), currentPoint.zCoord + enumfacing.getFrontOffsetZ()); 29 | if (pathpoint != null && !pathpoint.visited && pathpoint.distanceTo(targetPoint) < maxDistance) 30 | pathOptions[i++] = pathpoint; 31 | } 32 | return i; 33 | } 34 | 35 | @Nullable 36 | private PathPoint getAirNode(int startX, int startY, int startZ) { 37 | for (int x = startX; x < startX + entitySizeX; ++x) { 38 | for (int y = startY; y < startY + entitySizeY; ++y) { 39 | for (int z = startZ; z < startZ + entitySizeZ; ++z) { 40 | if (!BlockUtils.isFree(x, y, z, Minecraft.getMinecraft().theWorld != null ? Minecraft.getMinecraft().theWorld : blockaccess)) { 41 | return null; 42 | } 43 | } 44 | } 45 | } 46 | return this.openPoint(startX, startY, startZ); 47 | } 48 | } -------------------------------------------------------------------------------- /src/main/java/com/jelly/farmhelperv2/transformer/NetworkManagerTransformer.java: -------------------------------------------------------------------------------- 1 | package com.jelly.farmhelperv2.transformer; 2 | 3 | import net.minecraft.launchwrapper.IClassTransformer; 4 | import org.objectweb.asm.ClassReader; 5 | import org.objectweb.asm.ClassWriter; 6 | import org.objectweb.asm.tree.AbstractInsnNode; 7 | import org.objectweb.asm.tree.ClassNode; 8 | import org.objectweb.asm.tree.MethodInsnNode; 9 | import org.objectweb.asm.tree.TypeInsnNode; 10 | 11 | public class NetworkManagerTransformer implements IClassTransformer { 12 | @Override 13 | public byte[] transform(String name, String transformedName, byte[] basicClass) { 14 | if (!name.equals("com.jelly.farmhelperv2.mixin.network.MixinNetworkManager")) { 15 | return basicClass; 16 | } 17 | try { 18 | final ClassReader reader = new ClassReader(basicClass); 19 | final ClassNode classNode = new ClassNode(); 20 | reader.accept(classNode, 0); 21 | 22 | classNode.methods.stream().filter(methodNode -> methodNode.name.equals("createNetworkManagerAndConnect")).forEach(methodNode -> { 23 | for (int i = 0; i < methodNode.instructions.size(); ++i) { 24 | final AbstractInsnNode abstractInsnNode = methodNode.instructions.get(i); 25 | if (abstractInsnNode instanceof TypeInsnNode) { 26 | TypeInsnNode tin = (TypeInsnNode) abstractInsnNode; 27 | if (tin.desc.equals("com/jelly/farmhelperv2/mixin/network/MixinNetworkManager$1")) { 28 | ((TypeInsnNode) abstractInsnNode).desc = "net/minecraft/network/NetworkManager$5"; 29 | } 30 | } else if (abstractInsnNode instanceof MethodInsnNode) { 31 | MethodInsnNode min = (MethodInsnNode) abstractInsnNode; 32 | if (min.owner.equals("com/jelly/farmhelperv2/mixin/network/MixinNetworkManager$1") && min.name.equals("")) { 33 | min.owner = "net/minecraft/network/NetworkManager$5"; 34 | } 35 | } 36 | } 37 | }); 38 | 39 | final ClassWriter writer = new ClassWriter(ClassWriter.COMPUTE_MAXS); 40 | classNode.accept(writer); 41 | return writer.toByteArray(); 42 | } catch (final Throwable throwable) { 43 | throwable.printStackTrace(); 44 | } 45 | 46 | return basicClass; 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/main/java/com/jelly/farmhelperv2/util/MarkdownFormatter.java: -------------------------------------------------------------------------------- 1 | package com.jelly.farmhelperv2.util; 2 | 3 | import java.util.regex.Matcher; 4 | import java.util.regex.Pattern; 5 | 6 | public class MarkdownFormatter { 7 | 8 | public static String format(String markdownText) { 9 | // Bold formatting 10 | markdownText = markdownText.replaceAll("\\*\\*(.*?)\\*\\*", "\u00A7l$1\u00A7r"); 11 | 12 | // Italic formatting 13 | markdownText = markdownText.replaceAll("\\*(.*?)\\*", "\u00A7o$1\u00A7r"); 14 | 15 | // Heading formatting 16 | markdownText = markdownText.replaceAll("(?m)^#{1,6}\\s+(.*?)$", "\u00A7n$1\u00A7r"); 17 | 18 | // Link formatting (Display text)(URL) 19 | Pattern linkPattern = Pattern.compile("\\[([^\\]]+)\\]\\(([^\\)]+)\\)"); 20 | Matcher linkMatcher = linkPattern.matcher(markdownText); 21 | StringBuffer linkFormattedText = new StringBuffer(); 22 | while (linkMatcher.find()) { 23 | String linkDisplayText = linkMatcher.group(1); 24 | String linkURL = linkMatcher.group(2); 25 | linkMatcher.appendReplacement(linkFormattedText, "\u00A7b" + linkDisplayText + "\u00A7r"); 26 | linkFormattedText.append(" (").append(linkURL).append(")"); 27 | } 28 | linkMatcher.appendTail(linkFormattedText); 29 | markdownText = linkFormattedText.toString(); 30 | 31 | // Code block formatting (``` code ```) 32 | markdownText = markdownText.replaceAll("```([^`]+)```", "\u00A77\u00A7o$1\u00A77\u00A7r"); 33 | 34 | // Unordered list formatting 35 | markdownText = markdownText.replaceAll("(?m)^\\*\\s+(.*?)$", "\u2022 $1"); 36 | markdownText = markdownText.replaceAll("(?m)^(\\s*\\*)\\s+(.*?)$", " \u25E6 $2"); 37 | 38 | // Ordered list formatting 39 | Pattern orderedListPattern = Pattern.compile("(?m)^(\\d+)\\.\\s+(.*?)$"); 40 | Matcher orderedListMatcher = orderedListPattern.matcher(markdownText); 41 | StringBuffer orderedListFormattedText = new StringBuffer(); 42 | while (orderedListMatcher.find()) { 43 | String listItemNumber = orderedListMatcher.group(1); 44 | String listItemText = orderedListMatcher.group(2); 45 | orderedListMatcher.appendReplacement(orderedListFormattedText, "\u00A7l" + listItemNumber + ".\u00A7r " + listItemText); 46 | } 47 | orderedListMatcher.appendTail(orderedListFormattedText); 48 | markdownText = orderedListFormattedText.toString(); 49 | 50 | return markdownText; 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /src/main/java/com/jelly/farmhelperv2/remote/command/discordCommands/DiscordCommand.java: -------------------------------------------------------------------------------- 1 | package com.jelly.farmhelperv2.remote.command.discordCommands; 2 | 3 | import com.google.gson.JsonObject; 4 | import com.jelly.farmhelperv2.FarmHelper; 5 | import com.jelly.farmhelperv2.remote.WebsocketHandler; 6 | import com.jelly.farmhelperv2.remote.command.commands.Command; 7 | import com.jelly.farmhelperv2.remote.struct.RemoteMessage; 8 | import com.jelly.farmhelperv2.remote.util.RemoteUtils; 9 | import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent; 10 | import net.dv8tion.jda.api.interactions.commands.build.Commands; 11 | import net.dv8tion.jda.api.interactions.commands.build.SlashCommandData; 12 | import org.java_websocket.WebSocket; 13 | 14 | public class DiscordCommand { 15 | public String name; 16 | public String description; 17 | public Option[] options = null; 18 | 19 | public DiscordCommand(String name, String description) { 20 | this.name = name; 21 | this.description = description; 22 | } 23 | 24 | public void addOptions(Option... options) { 25 | this.options = options; 26 | } 27 | 28 | public void execute(SlashCommandInteractionEvent event) { 29 | throw new UnsupportedOperationException("Unimplemented method 'execute'"); 30 | } 31 | 32 | public SlashCommandData getSlashCommand() { 33 | if (name.isEmpty() || description.isEmpty()) { 34 | throw new UnsupportedOperationException("Unimplemented method 'getSlashCommand'"); 35 | } 36 | SlashCommandData data = Commands.slash(name, description); 37 | if (options != null) { 38 | for (Option option : options) { 39 | data.addOption(option.type, option.name, option.description, option.required, option.autocomplete); 40 | } 41 | } 42 | return data; 43 | } 44 | 45 | protected void sendMessage(WebSocket webSocket) { 46 | sendMessage(webSocket, new JsonObject()); 47 | } 48 | 49 | protected void sendMessage(WebSocket webSocket, JsonObject args) { 50 | RemoteMessage message = new RemoteMessage(name, args); 51 | if (webSocket == null) { 52 | RemoteUtils.getCommand( 53 | WebsocketHandler.commands, 54 | (cmd) -> cmd.getClass().getAnnotation(Command.class).label().equalsIgnoreCase(name)) 55 | .ifPresent(cmd -> cmd.execute(message)); 56 | return; 57 | } 58 | webSocket.send(FarmHelper.gson.toJson(message)); 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /src/main/java/com/jelly/farmhelperv2/mixin/client/MixinScoreboard.java: -------------------------------------------------------------------------------- 1 | package com.jelly.farmhelperv2.mixin.client; 2 | 3 | import net.minecraft.scoreboard.ScoreObjective; 4 | import net.minecraft.scoreboard.ScorePlayerTeam; 5 | import net.minecraft.scoreboard.Scoreboard; 6 | import org.spongepowered.asm.mixin.Mixin; 7 | import org.spongepowered.asm.mixin.Shadow; 8 | import org.spongepowered.asm.mixin.injection.At; 9 | import org.spongepowered.asm.mixin.injection.Inject; 10 | import org.spongepowered.asm.mixin.injection.Redirect; 11 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; 12 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; 13 | 14 | import java.util.Map; 15 | 16 | // Patcher's fix for the scoreboard log spam 17 | 18 | @Mixin(Scoreboard.class) 19 | public abstract class MixinScoreboard { 20 | @Shadow 21 | public abstract ScorePlayerTeam getTeam(String p_96508_1_); 22 | 23 | @Inject(method = "removeTeam", at = @At("HEAD"), cancellable = true) 24 | private void patcher$checkIfTeamIsNull(ScorePlayerTeam team, CallbackInfo ci) { 25 | if (team == null) ci.cancel(); 26 | } 27 | 28 | @Redirect(method = "removeTeam", at = @At(value = "INVOKE", target = "Ljava/util/Map;remove(Ljava/lang/Object;)Ljava/lang/Object;", ordinal = 0, remap = false)) 29 | private V patcher$checkIfRegisteredNameIsNull(Map instance, K o) { 30 | if (o != null) return instance.remove(o); 31 | return null; 32 | } 33 | 34 | @Inject(method = "removeObjective", at = @At("HEAD"), cancellable = true) 35 | private void patcher$checkIfObjectiveIsNull(ScoreObjective objective, CallbackInfo ci) { 36 | if (objective == null) ci.cancel(); 37 | } 38 | 39 | @Redirect(method = "removeObjective", at = @At(value = "INVOKE", target = "Ljava/util/Map;remove(Ljava/lang/Object;)Ljava/lang/Object;", ordinal = 0, remap = false)) 40 | private V patcher$checkIfNameIsNull(Map instance, K o) { 41 | if (o != null) return instance.remove(o); 42 | return null; 43 | } 44 | 45 | @Inject(method = "createTeam", at = @At(value = "CONSTANT", args = "stringValue=A team with the name '"), cancellable = true) 46 | private void patcher$returnExistingTeam(String name, CallbackInfoReturnable cir) { 47 | cir.setReturnValue(this.getTeam(name)); 48 | } 49 | 50 | @Inject(method = "removePlayerFromTeam", at = @At(value = "CONSTANT", args = "stringValue=Player is either on another team or not on any team. Cannot remove from team '"), cancellable = true) 51 | private void patcher$silenceException(CallbackInfo ci) { 52 | ci.cancel(); 53 | } 54 | } -------------------------------------------------------------------------------- /src/main/resources/farmhelper/movrec/ITEM_CHANGE_1.movement: -------------------------------------------------------------------------------- 1 | false;false;false;false;false;false;false;false;false;359.00204;9.193268;0 2 | false;false;false;false;false;false;false;false;false;361.25;8.72002;1 3 | false;false;false;false;false;false;false;false;false;366.45572;10.139761;1 4 | false;false;false;false;false;false;false;false;false;368.94028;17.356777;1 5 | false;false;false;false;false;false;false;false;false;369.29523;20.314571;7 6 | false;false;false;false;false;false;false;false;false;366.57404;21.02444;1 7 | false;false;false;false;false;false;false;false;false;354.26962;23.74561;1 8 | false;false;false;false;false;false;false;false;false;335.2214;24.928724;1 9 | false;false;false;false;false;false;false;false;false;326.58463;25.165346;3 10 | false;false;false;false;false;false;false;false;false;328.95087;24.928724;1 11 | false;false;false;false;false;false;false;false;false;350.01035;23.272362;1 12 | false;false;false;false;false;false;false;false;false;388.34335;21.616;0 13 | false;false;false;false;true;false;false;false;false;388.34335;21.616;0 14 | false;false;false;false;true;false;false;false;false;401.83093;21.024445;0 15 | false;false;true;false;true;false;false;false;false;401.83093;21.024445;2 16 | false;false;true;false;true;false;false;false;false;401.5943;20.906134;1 17 | false;false;true;false;true;false;false;false;false;388.46173;13.689118;0 18 | false;false;false;false;true;false;false;false;false;388.46173;13.689118;0 19 | false;false;false;false;true;false;false;false;false;365.391;-0.15335688;1 20 | false;false;false;false;true;false;false;false;false;360.6585;-4.294268;1 21 | false;false;false;false;true;false;false;false;false;361.72336;-5.240762;5 22 | false;false;false;false;true;false;false;false;false;361.13177;-5.240762;1 23 | false;false;false;false;true;false;false;false;false;360.5402;-5.240762;11 24 | false;false;false;false;true;false;false;false;false;360.6585;-5.004139;1 25 | false;false;false;false;true;false;false;false;false;365.391;-1.3364749;1 26 | false;false;false;false;true;false;false;false;false;374.73764;8.128466;1 27 | false;false;false;false;true;false;false;false;false;380.41663;18.066652;0 28 | true;false;false;false;true;false;false;false;false;380.41663;18.066652;0 29 | true;false;false;false;true;false;false;false;false;381.83643;22.444185;1 30 | true;false;false;false;true;false;false;false;false;381.24484;23.745611;1 31 | true;false;false;false;true;false;false;false;false;378.87857;26.46678;1 32 | true;false;false;false;true;false;false;false;false;377.45877;28.359766;1 33 | true;false;false;false;true;false;false;false;false;376.51224;30.134443;0 34 | false;false;false;false;false;false;false;false;false;376.51224;30.134443;0 35 | false;false;false;false;false;false;false;false;false;376.39392;30.371065;0 36 | -------------------------------------------------------------------------------- /src/main/java/com/jelly/farmhelperv2/mixin/render/MixinModelBiped.java: -------------------------------------------------------------------------------- 1 | package com.jelly.farmhelperv2.mixin.render; 2 | 3 | import com.jelly.farmhelperv2.handler.RotationHandler; 4 | import com.jelly.farmhelperv2.mixin.client.EntityPlayerSPAccessor; 5 | import com.jelly.farmhelperv2.mixin.client.MinecraftAccessor; 6 | import com.jelly.farmhelperv2.util.helper.RotationConfiguration; 7 | import net.minecraft.client.Minecraft; 8 | import net.minecraft.client.model.ModelBiped; 9 | import net.minecraft.client.model.ModelRenderer; 10 | import net.minecraft.entity.Entity; 11 | import net.minecraft.util.MathHelper; 12 | import org.spongepowered.asm.mixin.Mixin; 13 | import org.spongepowered.asm.mixin.Shadow; 14 | import org.spongepowered.asm.mixin.Unique; 15 | import org.spongepowered.asm.mixin.injection.At; 16 | import org.spongepowered.asm.mixin.injection.Inject; 17 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; 18 | 19 | @Mixin(value = ModelBiped.class, priority = Integer.MAX_VALUE) 20 | public class MixinModelBiped { 21 | @Unique 22 | private final Minecraft farmHelperV2$mc = Minecraft.getMinecraft(); 23 | @Shadow 24 | public ModelRenderer bipedHead; 25 | 26 | @Inject(method = {"setRotationAngles"}, at = {@At(value = "FIELD", target = "Lnet/minecraft/client/model/ModelBiped;swingProgress:F")}) 27 | public void onSetRotationAngles(float limbSwing, float limbSwingAmount, float ageInTicks, float netHeadYaw, float headPitch, float scaleFactor, Entity entityIn, CallbackInfo ci) { 28 | if (!RotationHandler.getInstance().isRotating() || RotationHandler.getInstance().getConfiguration() != null && RotationHandler.getInstance().getConfiguration().rotationType() != RotationConfiguration.RotationType.SERVER) 29 | return; 30 | 31 | if (entityIn != null && entityIn.equals(Minecraft.getMinecraft().thePlayer)) { 32 | this.bipedHead.rotateAngleX = ((EntityPlayerSPAccessor) entityIn).getLastReportedPitch() / 57.295776f; 33 | float partialTicks = ((MinecraftAccessor) farmHelperV2$mc).getTimer().renderPartialTicks; 34 | float yawOffset = farmHelperV2$interpolateRotation(farmHelperV2$mc.thePlayer.prevRenderYawOffset, farmHelperV2$mc.thePlayer.renderYawOffset, partialTicks); 35 | float fakeHead = ((EntityPlayerSPAccessor) entityIn).getLastReportedYaw(); 36 | float calcNetHead = fakeHead - yawOffset; 37 | calcNetHead = MathHelper.wrapAngleTo180_float(calcNetHead); 38 | 39 | bipedHead.rotateAngleY = calcNetHead / 57.295776f; 40 | } 41 | } 42 | 43 | @Unique 44 | protected float farmHelperV2$interpolateRotation(float par1, float par2, float par3) { 45 | float f; 46 | 47 | for (f = par2 - par1; f < -180.0F; f += 360.0F) { 48 | } 49 | 50 | while (f >= 180.0F) { 51 | f -= 360.0F; 52 | } 53 | 54 | return par1 + par3 * f; 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /src/main/java/com/jelly/farmhelperv2/util/OldRotationUtils.java: -------------------------------------------------------------------------------- 1 | package com.jelly.farmhelperv2.util; 2 | 3 | import net.minecraft.client.Minecraft; 4 | import org.apache.commons.lang3.tuple.MutablePair; 5 | 6 | import static cc.polyfrost.oneconfig.libs.universal.UMath.wrapAngleTo180; 7 | 8 | public class OldRotationUtils { 9 | private final static Minecraft mc = Minecraft.getMinecraft(); 10 | public boolean rotating; 11 | public boolean completed; 12 | 13 | private long startTime; 14 | private long endTime; 15 | 16 | MutablePair start = new MutablePair<>(0f, 0f); 17 | MutablePair target = new MutablePair<>(0f, 0f); 18 | MutablePair difference = new MutablePair<>(0f, 0f); 19 | 20 | public void easeTo(float yaw, float pitch, long time) { 21 | completed = false; 22 | rotating = true; 23 | startTime = System.currentTimeMillis(); 24 | endTime = System.currentTimeMillis() + time; 25 | start.setLeft(mc.thePlayer.rotationYaw); 26 | start.setRight(mc.thePlayer.rotationPitch); 27 | MutablePair neededChange = getNeededChange(start, new MutablePair<>(yaw, pitch)); 28 | target.setLeft(start.left + neededChange.left); 29 | target.setRight(start.right + neededChange.right); 30 | getDifference(); 31 | } 32 | 33 | public static MutablePair getNeededChange(MutablePair startRot, MutablePair endRot) { 34 | float yawDiff = (float) (wrapAngleTo180(endRot.getLeft()) - wrapAngleTo180(startRot.getLeft())); 35 | 36 | yawDiff = AngleUtils.normalizeAngle(yawDiff); 37 | 38 | return new MutablePair<>(yawDiff, endRot.getRight() - startRot.right); 39 | } 40 | 41 | public void update() { 42 | if (System.currentTimeMillis() <= endTime) { 43 | mc.thePlayer.rotationYaw = interpolate(start.getLeft(), target.getLeft()); 44 | mc.thePlayer.rotationPitch = interpolate(start.getRight(), target.getRight()); 45 | } 46 | else if (!completed) { 47 | mc.thePlayer.rotationYaw = target.left; 48 | mc.thePlayer.rotationPitch = target.right; 49 | completed = true; 50 | rotating = false; 51 | } 52 | } 53 | 54 | public void reset() { 55 | completed = false; 56 | rotating = false; 57 | } 58 | 59 | private void getDifference() { 60 | difference.setLeft(AngleUtils.smallestAngleDifference(AngleUtils.get360RotationYaw(), target.left)); 61 | difference.setRight(target.right - start.right); 62 | } 63 | 64 | private float interpolate(float start, float end) { 65 | return (end - start) * easeOutCubic((float) (System.currentTimeMillis() - startTime) / (endTime - startTime)) + start; 66 | } 67 | 68 | public float easeOutCubic(double number) { 69 | return (float) Math.max(0, Math.min(1, 1 - Math.pow(1 - number, 3))); 70 | } 71 | } -------------------------------------------------------------------------------- /src/main/java/com/jelly/farmhelperv2/mixin/render/MixinEntityRenderer.java: -------------------------------------------------------------------------------- 1 | package com.jelly.farmhelperv2.mixin.render; 2 | 3 | import com.jelly.farmhelperv2.feature.impl.Freelook; 4 | import net.minecraft.client.renderer.EntityRenderer; 5 | import net.minecraft.entity.Entity; 6 | import net.minecraft.util.Vec3; 7 | import org.spongepowered.asm.mixin.Mixin; 8 | import org.spongepowered.asm.mixin.Shadow; 9 | import org.spongepowered.asm.mixin.injection.At; 10 | import org.spongepowered.asm.mixin.injection.Redirect; 11 | 12 | @Mixin(value = EntityRenderer.class, priority = Integer.MAX_VALUE) 13 | public class MixinEntityRenderer { 14 | @Shadow 15 | private float thirdPersonDistanceTemp; 16 | 17 | @Redirect(method = "orientCamera", at = @At(value = "FIELD", target = "Lnet/minecraft/entity/Entity;rotationPitch:F")) 18 | private float modifyPitch(Entity entity) { 19 | if (entity == null) return 0F; 20 | return Freelook.getInstance().getPitch(entity.rotationPitch); 21 | } 22 | 23 | @Redirect(method = "orientCamera", at = @At(value = "FIELD", target = "Lnet/minecraft/entity/Entity;rotationYaw:F")) 24 | private float modifyYaw(Entity entity) { 25 | if (entity == null) return 0F; 26 | return Freelook.getInstance().getYaw(entity.rotationYaw); 27 | } 28 | 29 | @Redirect(method = "orientCamera", at = @At(value = "FIELD", target = "Lnet/minecraft/entity/Entity;prevRotationPitch:F")) 30 | private float modifyPrevPitch(Entity entity) { 31 | if (entity == null) return 0F; 32 | return Freelook.getInstance().getPrevPitch(entity.prevRotationPitch); 33 | } 34 | 35 | @Redirect(method = "orientCamera", at = @At(value = "FIELD", target = "Lnet/minecraft/entity/Entity;prevRotationYaw:F")) 36 | private float modifyPrevYaw(Entity entity) { 37 | if (entity == null) return 0F; 38 | return Freelook.getInstance().getPrevYaw(entity.prevRotationYaw); 39 | } 40 | 41 | @Redirect(method = "orientCamera", at = @At(value = "INVOKE", target = "Lnet/minecraft/util/Vec3;distanceTo(Lnet/minecraft/util/Vec3;)D")) 42 | public double onCamera(Vec3 instance, Vec3 vec) { 43 | if (Freelook.getInstance().isRunning()) return 999D; 44 | return instance.distanceTo(vec); 45 | } 46 | 47 | @Redirect(method = "orientCamera", at = @At(value = "FIELD", target = "Lnet/minecraft/client/renderer/EntityRenderer;thirdPersonDistanceTemp:F")) 48 | private float modifyDistance(EntityRenderer entityRenderer) { 49 | if (Freelook.getInstance().isRunning()) return Freelook.getInstance().getDistance(); 50 | return thirdPersonDistanceTemp; 51 | } 52 | 53 | @Redirect(method = "orientCamera", at = @At(value = "FIELD", target = "Lnet/minecraft/client/renderer/EntityRenderer;thirdPersonDistance:F")) 54 | private float modifyDistance2(EntityRenderer entityRenderer) { 55 | if (Freelook.getInstance().isRunning()) return Freelook.getInstance().getDistance(); 56 | return thirdPersonDistanceTemp; 57 | } 58 | 59 | } 60 | -------------------------------------------------------------------------------- /src/main/resources/farmhelper/movrec/ROTATION_CHECK_Continue_1.movement: -------------------------------------------------------------------------------- 1 | false;false;false;false;false;false;false;false;false;371.07153;9.429881;0 2 | false;false;false;false;false;false;false;false;false;372.37296;8.956634;1 3 | false;false;false;false;false;false;false;false;false;378.64352;8.483386;1 4 | false;false;false;false;false;false;false;false;false;381.7197;8.601698;1 5 | false;false;false;false;false;false;false;false;false;386.57047;7.7735147;1 6 | false;false;false;false;false;false;false;false;false;394.02414;6.945332;1 7 | false;false;false;false;false;false;false;false;false;406.09192;7.6552024;1 8 | false;false;false;false;false;false;false;false;false;424.66684;8.128449;1 9 | false;false;false;false;false;false;false;false;false;430.3458;7.0636435;1 10 | false;false;false;false;false;false;false;false;false;430.58243;7.0636435;1 11 | false;false;false;false;false;false;false;false;false;431.29233;6.9453316;1 12 | false;false;false;false;false;false;false;false;false;432.35718;6.708708;1 13 | false;false;false;false;false;false;false;false;false;434.6051;5.8805256;1 14 | false;false;false;false;false;false;false;false;false;437.44458;5.170655;3 15 | false;false;false;false;false;false;false;false;false;438.2728;4.579096;1 16 | false;false;false;false;false;false;false;false;false;441.7038;1.9762377;1 17 | false;false;false;false;false;false;false;false;false;447.61935;-1.8097383;1 18 | false;false;false;false;false;false;false;false;false;456.72934;-5.3590903;1 19 | false;false;false;false;false;false;false;false;false;462.40833;-7.015455;1 20 | false;false;false;false;false;false;false;false;false;462.52664;-7.015455;5 21 | false;false;false;false;false;false;false;false;false;459.80545;-6.897143;1 22 | false;false;false;false;false;false;false;false;false;447.0278;-8.790131;1 23 | false;false;false;false;false;false;false;false;false;436.0248;-12.457792;1 24 | false;false;false;false;false;false;false;false;false;429.5176;-16.125454;1 25 | false;false;false;false;false;false;false;false;false;427.6246;-16.71701;1 26 | false;false;false;false;false;false;false;false;false;427.38797;-16.71701;1 27 | false;false;false;false;false;false;false;false;false;425.61322;-16.362078;1 28 | false;false;false;false;false;false;false;false;false;422.30045;-15.770521;1 29 | false;false;false;false;false;false;false;false;false;412.8355;-10.32818;1 30 | false;false;false;false;false;false;false;false;false;402.18744;-1.3364881;1 31 | false;false;false;false;false;false;false;false;false;396.15353;1.7396175;1 32 | false;false;false;false;false;false;false;false;false;395.32532;2.331176;3 33 | false;false;false;false;false;false;false;false;false;393.314;3.9875405;1 34 | false;false;false;false;false;false;false;false;false;381.60114;8.246763;1 35 | false;false;false;false;false;false;false;false;false;368.35022;12.151051;1 36 | false;false;false;false;false;false;false;false;false;364.44595;12.860922;1 37 | false;false;false;false;false;false;false;false;false;364.32764;12.860922;3 38 | false;false;false;false;false;false;false;false;false;364.20932;12.860922;0 39 | -------------------------------------------------------------------------------- /src/main/java/com/jelly/farmhelperv2/feature/impl/Proxy.java: -------------------------------------------------------------------------------- 1 | package com.jelly.farmhelperv2.feature.impl; 2 | 3 | import com.jelly.farmhelperv2.FarmHelper; 4 | import com.jelly.farmhelperv2.config.FarmHelperConfig; 5 | import io.netty.bootstrap.ChannelFactory; 6 | import io.netty.channel.socket.oio.OioSocketChannel; 7 | 8 | import java.net.*; 9 | import java.util.Objects; 10 | 11 | public class Proxy { 12 | private static Proxy instance; 13 | 14 | public static Proxy getInstance() { 15 | if (instance == null) { 16 | instance = new Proxy(); 17 | } 18 | return instance; 19 | } 20 | 21 | public enum ProxyType { 22 | SOCKS, 23 | HTTP, 24 | } 25 | 26 | public void setProxy(boolean enabled, String host, ProxyType type, String username, String password) { 27 | FarmHelperConfig.proxyEnabled = enabled; 28 | FarmHelperConfig.proxyAddress = host; 29 | FarmHelperConfig.proxyType = type; 30 | if (!Objects.equals(username, "Username")) 31 | FarmHelperConfig.proxyUsername = username; 32 | if (!Objects.equals(password, "Password")) 33 | FarmHelperConfig.proxyPassword = password; 34 | FarmHelper.config.save(); 35 | } 36 | 37 | public java.net.Proxy getProxy() { 38 | if (!FarmHelperConfig.proxyEnabled) return null; 39 | String addressStr = FarmHelperConfig.proxyAddress.split(":")[0]; 40 | int port = Integer.parseInt(FarmHelperConfig.proxyAddress.split(":")[1]); 41 | InetSocketAddress address; 42 | try { 43 | address = new InetSocketAddress(InetAddress.getByName(addressStr), port); 44 | } catch (UnknownHostException e) { 45 | e.printStackTrace(); 46 | return null; 47 | } 48 | 49 | if (FarmHelperConfig.proxyUsername != null && FarmHelperConfig.proxyPassword != null) 50 | Authenticator.setDefault(new Authenticator() { 51 | @Override 52 | protected PasswordAuthentication getPasswordAuthentication() { 53 | return new PasswordAuthentication(FarmHelperConfig.proxyUsername, FarmHelperConfig.proxyPassword.toCharArray()); 54 | } 55 | }); 56 | 57 | switch (FarmHelperConfig.proxyType) { 58 | case SOCKS: 59 | return new java.net.Proxy(java.net.Proxy.Type.SOCKS, address); 60 | case HTTP: 61 | return new java.net.Proxy(java.net.Proxy.Type.HTTP, address); 62 | default: 63 | return null; 64 | } 65 | } 66 | 67 | public static class ProxyOioChannelFactory implements ChannelFactory { 68 | 69 | private final java.net.Proxy proxy; 70 | 71 | public ProxyOioChannelFactory(java.net.Proxy proxy) { 72 | this.proxy = proxy; 73 | } 74 | 75 | @Override 76 | public OioSocketChannel newChannel() { 77 | return new OioSocketChannel(new Socket(proxy)); 78 | } 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /src/main/java/com/jelly/farmhelperv2/remote/command/commands/impl/ScreenshotCommand.java: -------------------------------------------------------------------------------- 1 | package com.jelly.farmhelperv2.remote.command.commands.impl; 2 | 3 | import cc.polyfrost.oneconfig.utils.Multithreading; 4 | import com.google.gson.JsonObject; 5 | import com.jelly.farmhelperv2.handler.MacroHandler; 6 | import com.jelly.farmhelperv2.remote.command.commands.ClientCommand; 7 | import com.jelly.farmhelperv2.remote.command.commands.Command; 8 | import com.jelly.farmhelperv2.remote.struct.RemoteMessage; 9 | import com.jelly.farmhelperv2.util.InventoryUtils; 10 | import com.jelly.farmhelperv2.util.PlayerUtils; 11 | import net.minecraft.client.gui.inventory.GuiInventory; 12 | 13 | import java.util.concurrent.TimeUnit; 14 | 15 | @Command(label = "screenshot") 16 | 17 | public class ScreenshotCommand extends ClientCommand { 18 | 19 | @Override 20 | public void execute(RemoteMessage message) { 21 | JsonObject args = message.args; 22 | try { 23 | boolean inventory = args.get("inventory").getAsBoolean(); 24 | if (!inventory) { 25 | screenshot(); 26 | } else { 27 | inventory(); 28 | } 29 | 30 | } catch (Exception e) { 31 | e.printStackTrace(); 32 | screenshot(); 33 | } 34 | } 35 | 36 | public void screenshot() { 37 | JsonObject data = new JsonObject(); 38 | data.addProperty("username", mc.getSession().getUsername()); 39 | data.addProperty("image", getScreenshot()); 40 | data.addProperty("uuid", mc.getSession().getPlayerID()); 41 | RemoteMessage response = new RemoteMessage(label, data); 42 | send(response); 43 | } 44 | 45 | public void inventory() { 46 | JsonObject data = new JsonObject(); 47 | 48 | boolean wasMacroing; 49 | if (MacroHandler.getInstance().isMacroToggled()) { 50 | wasMacroing = true; 51 | MacroHandler.getInstance().pauseMacro(); 52 | } else { 53 | wasMacroing = false; 54 | } 55 | 56 | Multithreading.schedule(() -> { 57 | try { 58 | if (mc.currentScreen == null) 59 | InventoryUtils.openInventory(); 60 | Thread.sleep(1000); 61 | String screenshot = getScreenshot(); 62 | Thread.sleep(1000); 63 | if (mc.currentScreen instanceof GuiInventory) 64 | PlayerUtils.closeScreen(); 65 | if (wasMacroing) { 66 | MacroHandler.getInstance().resumeMacro(); 67 | } 68 | 69 | data.addProperty("username", mc.getSession().getUsername()); 70 | data.addProperty("image", screenshot); 71 | data.addProperty("uuid", mc.getSession().getPlayerID()); 72 | RemoteMessage response = new RemoteMessage(label, data); 73 | send(response); 74 | } catch (InterruptedException e) { 75 | e.printStackTrace(); 76 | } 77 | }, 0, TimeUnit.MILLISECONDS); 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /gradlew.bat: -------------------------------------------------------------------------------- 1 | @rem 2 | @rem Copyright 2015 the original author or authors. 3 | @rem 4 | @rem Licensed under the Apache License, Version 2.0 (the "License"); 5 | @rem you may not use this file except in compliance with the License. 6 | @rem You may obtain a copy of the License at 7 | @rem 8 | @rem https://www.apache.org/licenses/LICENSE-2.0 9 | @rem 10 | @rem Unless required by applicable law or agreed to in writing, software 11 | @rem distributed under the License is distributed on an "AS IS" BASIS, 12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | @rem See the License for the specific language governing permissions and 14 | @rem limitations under the License. 15 | @rem 16 | 17 | @if "%DEBUG%"=="" @echo off 18 | @rem ########################################################################## 19 | @rem 20 | @rem Gradle startup script for Windows 21 | @rem 22 | @rem ########################################################################## 23 | 24 | @rem Set local scope for the variables with windows NT shell 25 | if "%OS%"=="Windows_NT" setlocal 26 | 27 | set DIRNAME=%~dp0 28 | if "%DIRNAME%"=="" set DIRNAME=. 29 | @rem This is normally unused 30 | set APP_BASE_NAME=%~n0 31 | set APP_HOME=%DIRNAME% 32 | 33 | @rem Resolve any "." and ".." in APP_HOME to make it shorter. 34 | for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi 35 | 36 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 37 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" 38 | 39 | @rem Find java.exe 40 | if defined JAVA_HOME goto findJavaFromJavaHome 41 | 42 | set JAVA_EXE=java.exe 43 | %JAVA_EXE% -version >NUL 2>&1 44 | if %ERRORLEVEL% equ 0 goto execute 45 | 46 | echo. 47 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 48 | echo. 49 | echo Please set the JAVA_HOME variable in your environment to match the 50 | echo location of your Java installation. 51 | 52 | goto fail 53 | 54 | :findJavaFromJavaHome 55 | set JAVA_HOME=%JAVA_HOME:"=% 56 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 57 | 58 | if exist "%JAVA_EXE%" goto execute 59 | 60 | echo. 61 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 62 | echo. 63 | echo Please set the JAVA_HOME variable in your environment to match the 64 | echo location of your Java installation. 65 | 66 | goto fail 67 | 68 | :execute 69 | @rem Setup the command line 70 | 71 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 72 | 73 | 74 | @rem Execute Gradle 75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* 76 | 77 | :end 78 | @rem End local scope for the variables with windows NT shell 79 | if %ERRORLEVEL% equ 0 goto mainEnd 80 | 81 | :fail 82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 83 | rem the _cmd.exe /c_ return code! 84 | set EXIT_CODE=%ERRORLEVEL% 85 | if %EXIT_CODE% equ 0 set EXIT_CODE=1 86 | if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% 87 | exit /b %EXIT_CODE% 88 | 89 | :mainEnd 90 | if "%OS%"=="Windows_NT" endlocal 91 | 92 | :omega 93 | -------------------------------------------------------------------------------- /src/main/java/com/jelly/farmhelperv2/remote/struct/WebsocketServer.java: -------------------------------------------------------------------------------- 1 | package com.jelly.farmhelperv2.remote.struct; 2 | 3 | import com.google.gson.JsonObject; 4 | import com.jelly.farmhelperv2.FarmHelper; 5 | import com.jelly.farmhelperv2.remote.waiter.WaiterHandler; 6 | import com.jelly.farmhelperv2.util.LogUtils; 7 | import net.minecraft.client.Minecraft; 8 | import org.java_websocket.WebSocket; 9 | import org.java_websocket.handshake.ClientHandshake; 10 | import org.java_websocket.server.WebSocketServer; 11 | 12 | import java.net.InetSocketAddress; 13 | import java.util.HashMap; 14 | 15 | public class WebsocketServer extends WebSocketServer { 16 | public HashMap minecraftInstances = new HashMap<>(); 17 | public WebsocketServerState websocketServerState; 18 | 19 | public WebsocketServer(int port) { 20 | super(new InetSocketAddress(port)); 21 | minecraftInstances.clear(); 22 | websocketServerState = WebsocketServerState.CONNECTING; 23 | minecraftInstances.put(null, Minecraft.getMinecraft().getSession().getUsername()); 24 | } 25 | 26 | @Override 27 | public void onOpen(WebSocket conn, ClientHandshake handshake) { 28 | if (!handshake.hasFieldValue("auth")) { 29 | conn.close(4169); 30 | return; 31 | } 32 | LogUtils.sendDebug("[Remote Control] Client connected: " + conn.getRemoteSocketAddress().getAddress()); 33 | try { 34 | String base64Header = handshake.getFieldValue("auth"); 35 | JsonObject decoded = FarmHelper.gson.fromJson(base64Header, JsonObject.class); 36 | if (minecraftInstances.containsValue(decoded.get("name").getAsString())) { 37 | conn.close(4069); 38 | } 39 | minecraftInstances.put(conn, decoded.get("name").getAsString()); 40 | } catch (Exception ex) { 41 | ex.printStackTrace(); 42 | conn.close(); 43 | } 44 | } 45 | 46 | @Override 47 | public void onClose(WebSocket conn, int code, String reason, boolean remote) { 48 | LogUtils.sendDebug("[Remote Control] Client disconnected: " + conn.getRemoteSocketAddress().getAddress()); 49 | minecraftInstances.remove(conn); 50 | } 51 | 52 | @Override 53 | public void onMessage(WebSocket conn, String message) { 54 | System.out.println("[Remote Control] Message: " + message); 55 | RemoteMessage remoteMessage = FarmHelper.gson.fromJson(message, RemoteMessage.class); 56 | WaiterHandler.onMessage(remoteMessage); 57 | } 58 | 59 | @Override 60 | public void onError(WebSocket conn, Exception ex) { 61 | ex.printStackTrace(); 62 | LogUtils.sendDebug("[Remote Control] Websocket server error with client: " + ex.getMessage()); 63 | } 64 | 65 | @Override 66 | public void onStart() { 67 | websocketServerState = WebsocketServerState.CONNECTED; 68 | LogUtils.sendSuccess("[Remote Control] Websocket server started on port " + getPort()); 69 | } 70 | 71 | public enum WebsocketServerState { 72 | NOT_CONNECTED, 73 | CONNECTING, 74 | CONNECTED 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /src/main/java/com/jelly/farmhelperv2/mixin/client/MixinPlayerControllerMP.java: -------------------------------------------------------------------------------- 1 | package com.jelly.farmhelperv2.mixin.client; 2 | 3 | import com.jelly.farmhelperv2.config.FarmHelperConfig; 4 | import com.jelly.farmhelperv2.event.ClickedBlockEvent; 5 | import com.jelly.farmhelperv2.event.PlayerDestroyBlockEvent; 6 | import com.jelly.farmhelperv2.handler.MacroHandler; 7 | import net.minecraft.block.Block; 8 | import net.minecraft.block.BlockCactus; 9 | import net.minecraft.client.Minecraft; 10 | import net.minecraft.client.multiplayer.PlayerControllerMP; 11 | import net.minecraft.init.Blocks; 12 | import net.minecraft.item.ItemStack; 13 | import net.minecraft.util.BlockPos; 14 | import net.minecraft.util.EnumFacing; 15 | import net.minecraftforge.common.MinecraftForge; 16 | import org.spongepowered.asm.mixin.Final; 17 | import org.spongepowered.asm.mixin.Mixin; 18 | import org.spongepowered.asm.mixin.Shadow; 19 | import org.spongepowered.asm.mixin.injection.At; 20 | import org.spongepowered.asm.mixin.injection.Inject; 21 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; 22 | 23 | @Mixin({PlayerControllerMP.class}) 24 | public class MixinPlayerControllerMP { 25 | @Shadow 26 | private float curBlockDamageMP; 27 | 28 | @Shadow 29 | private float stepSoundTickCounter; 30 | 31 | @Shadow 32 | private int blockHitDelay; 33 | 34 | @Shadow 35 | @Final 36 | private Minecraft mc; 37 | 38 | @Inject(method = {"clickBlock"}, at = {@At(value = "HEAD")}) 39 | public void clickBlock(BlockPos loc, EnumFacing face, CallbackInfoReturnable cir) { 40 | Block block = this.mc.theWorld.getBlockState(loc).getBlock(); 41 | if (!FarmHelperConfig.pinglessCactus || !MacroHandler.getInstance().getCrop().equals(FarmHelperConfig.CropEnum.CACTUS)) { 42 | ClickedBlockEvent event = new ClickedBlockEvent(loc, face, block); 43 | MinecraftForge.EVENT_BUS.post(event); 44 | } 45 | if (!(block instanceof BlockCactus)) return; 46 | ItemStack currentItem = this.mc.thePlayer.inventory.getCurrentItem(); 47 | if (currentItem != null && currentItem.getDisplayName().contains("Cactus Knife") && block.equals(Blocks.cactus)) { 48 | PlayerDestroyBlockEvent event = new PlayerDestroyBlockEvent(loc, face, block); 49 | MinecraftForge.EVENT_BUS.post(event); 50 | if (FarmHelperConfig.pinglessCactus) { 51 | this.mc.theWorld.setBlockToAir(loc); 52 | // this.curBlockDamageMP = 0.0F; 53 | // this.stepSoundTickCounter = 0.0F; 54 | ClickedBlockEvent event2 = new ClickedBlockEvent(loc, face, Blocks.cactus); 55 | MinecraftForge.EVENT_BUS.post(event2); 56 | } 57 | } 58 | } 59 | 60 | @Inject(method = {"onPlayerDestroyBlock"}, at = {@At(value = "HEAD")}) 61 | public void onPlayerDestroyBlock(BlockPos pos, EnumFacing side, CallbackInfoReturnable cir) { 62 | Block block = this.mc.theWorld.getBlockState(pos).getBlock(); 63 | PlayerDestroyBlockEvent event = new PlayerDestroyBlockEvent(pos, side, block); 64 | MinecraftForge.EVENT_BUS.post(event); 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /src/main/java/com/jelly/farmhelperv2/feature/impl/UngrabMouse.java: -------------------------------------------------------------------------------- 1 | package com.jelly.farmhelperv2.feature.impl; 2 | 3 | import com.jelly.farmhelperv2.config.FarmHelperConfig; 4 | import com.jelly.farmhelperv2.feature.IFeature; 5 | import net.minecraft.client.Minecraft; 6 | import net.minecraft.util.MouseHelper; 7 | import org.lwjgl.input.Mouse; 8 | 9 | public class UngrabMouse implements IFeature { 10 | private final Minecraft mc = Minecraft.getMinecraft(); 11 | private static UngrabMouse instance; 12 | 13 | public static UngrabMouse getInstance() { 14 | if (instance == null) { 15 | instance = new UngrabMouse(); 16 | } 17 | return instance; 18 | } 19 | 20 | private boolean mouseUngrabbed; 21 | private MouseHelper oldMouseHelper; 22 | 23 | public void ungrabMouse() { 24 | if (!Mouse.isGrabbed() || mouseUngrabbed) return; 25 | mc.gameSettings.pauseOnLostFocus = false; 26 | oldMouseHelper = mc.mouseHelper; 27 | oldMouseHelper.ungrabMouseCursor(); 28 | mc.inGameHasFocus = true; 29 | mc.mouseHelper = new MouseHelper() { 30 | @Override 31 | public void mouseXYChange() { 32 | } 33 | 34 | @Override 35 | public void grabMouseCursor() { 36 | } 37 | 38 | @Override 39 | public void ungrabMouseCursor() { 40 | } 41 | }; 42 | mouseUngrabbed = true; 43 | } 44 | 45 | public void regrabMouse() { 46 | regrabMouse(false); 47 | } 48 | 49 | public void regrabMouse(boolean force) { 50 | if (!mouseUngrabbed && !force) return; 51 | mc.mouseHelper = oldMouseHelper; 52 | if (mc.currentScreen == null || force) { 53 | mc.mouseHelper.grabMouseCursor(); 54 | } 55 | mouseUngrabbed = false; 56 | } 57 | 58 | @Override 59 | public String getName() { 60 | return "Ungrab Mouse"; 61 | } 62 | 63 | @Override 64 | public boolean isRunning() { 65 | return false; 66 | } 67 | 68 | @Override 69 | public boolean shouldPauseMacroExecution() { 70 | return false; 71 | } 72 | 73 | @Override 74 | public boolean shouldStartAtMacroStart() { 75 | return isToggled(); 76 | } 77 | 78 | @Override 79 | public void start() { 80 | try { 81 | ungrabMouse(); 82 | } catch (Exception e) { 83 | e.printStackTrace(); 84 | } 85 | IFeature.super.start(); 86 | } 87 | 88 | @Override 89 | public void stop() { 90 | try { 91 | regrabMouse(); 92 | } catch (Exception e) { 93 | e.printStackTrace(); 94 | } 95 | IFeature.super.stop(); 96 | } 97 | 98 | @Override 99 | public void resetStatesAfterMacroDisabled() { 100 | 101 | } 102 | 103 | @Override 104 | public boolean isToggled() { 105 | return FarmHelperConfig.autoUngrabMouse; 106 | } 107 | 108 | @Override 109 | public boolean shouldCheckForFailsafes() { 110 | return false; 111 | } 112 | } 113 | -------------------------------------------------------------------------------- /src/main/resources/farmhelper/movrec/ITEM_CHANGE_2.movement: -------------------------------------------------------------------------------- 1 | false;false;false;false;false;false;false;false;false;359.35727;7.8918476;0 2 | false;false;false;false;false;false;false;false;false;363.97144;5.170677;1 3 | false;false;false;false;false;false;false;false;false;365.86444;-1.6914043;1 4 | false;false;false;false;false;false;false;false;false;381.24496;-16.716995;1 5 | false;false;false;false;false;false;false;false;false;390.4733;-20.857908;1 6 | false;false;false;false;false;false;false;false;false;388.81686;-19.43817;1 7 | false;false;false;false;false;false;false;false;false;388.9352;-14.705699;0 8 | false;false;true;false;false;false;false;false;false;388.9352;-14.705699;0 9 | false;false;true;false;false;false;false;false;false;390.94653;-4.885824;1 10 | false;false;true;false;false;false;false;false;false;387.16055;3.041063;0 11 | false;false;false;false;false;false;false;false;false;387.16055;3.041063;0 12 | false;false;false;false;false;false;false;false;false;386.45068;3.5143101;3 13 | false;false;false;false;false;false;false;false;false;386.80563;3.5143101;1 14 | false;false;false;false;false;false;false;false;false;379.5886;8.365091;1 15 | false;false;false;false;false;false;false;false;false;372.13495;15.227172;1 16 | false;false;false;false;false;false;false;false;false;368.8222;16.173666;1 17 | false;false;false;false;false;false;false;false;false;368.23062;19.249773;1 18 | false;false;false;false;false;false;false;false;false;370.36026;20.906136;1 19 | false;false;false;false;false;false;false;false;false;375.44766;23.627304;0 20 | true;false;false;false;false;false;false;false;false;375.44766;23.627304;0 21 | true;false;false;false;false;false;false;false;false;375.92093;23.627304;1 22 | true;false;false;false;false;false;false;false;false;375.32935;23.627304;0 23 | false;false;false;false;false;false;false;false;false;375.32935;23.627304;0 24 | false;false;false;false;false;false;false;false;false;368.9405;27.413279;1 25 | false;false;false;false;false;false;false;false;false;366.10098;32.14575;1 26 | false;false;false;false;false;false;false;false;false;365.39108;38.061337;1 27 | false;false;false;false;false;false;false;false;false;363.14307;42.675495;1 28 | false;false;false;false;false;false;false;false;false;359.47537;44.568485;1 29 | false;false;false;false;false;false;false;false;false;358.52884;43.858612;1 30 | false;false;false;false;false;false;false;false;false;356.6358;40.42757;1 31 | false;false;false;false;false;false;false;false;false;353.5597;32.145752;1 32 | false;false;false;false;false;false;false;false;false;350.83844;21.379383;1 33 | false;false;false;false;false;false;false;false;false;352.49484;17.356781;1 34 | false;false;false;false;false;false;false;false;false;353.67798;16.055353;0 35 | true;false;false;false;false;false;false;false;false;353.67798;16.055353;0 36 | true;false;false;false;false;false;false;false;false;353.9146;15.7004175;0 37 | false;false;false;false;false;false;false;false;false;353.9146;15.7004175;0 38 | false;false;false;false;false;false;false;false;false;354.15125;15.582106;1 39 | false;false;false;false;false;false;false;false;false;354.38788;15.463794;1 40 | false;false;false;false;false;false;false;false;false;354.6245;15.463794;1 41 | false;false;false;false;false;false;false;false;false;354.74283;15.345482;0 42 | -------------------------------------------------------------------------------- /src/main/java/com/jelly/farmhelperv2/config/page/CustomFailsafeMessagesPage.java: -------------------------------------------------------------------------------- 1 | package com.jelly.farmhelperv2.config.page; 2 | 3 | import cc.polyfrost.oneconfig.config.annotations.Slider; 4 | import cc.polyfrost.oneconfig.config.annotations.Text; 5 | 6 | /* 7 | Credits to Yuro for this superb class 8 | */ 9 | public class CustomFailsafeMessagesPage { 10 | @Text( 11 | name = "Custom messages sent during Jacob's Contest", 12 | description = "The messages to send to the chat when the failsafe has been triggered and you are during Jacob's Contest (use '|' to split the messages)", 13 | placeholder = "Leave empty to disable", 14 | multiline = true 15 | ) 16 | public static String customJacobMessages = ""; 17 | @Slider( 18 | name = "Custom Jacob's Contest message chance", 19 | description = "The chance that the custom Jacob's Contest message will be sent to the chat", 20 | min = 0, 21 | max = 100 22 | ) 23 | public static int customJacobChance = 50; 24 | 25 | @Text( 26 | name = "Custom continue messages", 27 | description = "The messages to send to the chat when the failsafe has been triggered and you want to ask if you can continue (use '|' to split the messages)", 28 | placeholder = "Leave empty to use a random message", 29 | multiline = true 30 | ) 31 | public static String customContinueMessages = ""; 32 | @Text( 33 | name = "Rotation failsafe messages", 34 | description = "The messages to send to the chat when the rotation failsafe has been triggered (use '|' to split the messages)", 35 | placeholder = "Leave empty to use a random message", 36 | multiline = true 37 | ) 38 | public static String customRotationMessages = ""; 39 | @Text( 40 | name = "Teleportation failsafe messages", 41 | description = "The messages to send to the chat when the teleportation failsafe has been triggered (use '|' to split the messages)", 42 | placeholder = "Leave empty to use a random message", 43 | multiline = true 44 | ) 45 | public static String customTeleportationMessages = ""; 46 | @Text( 47 | name = "Knockback failsafe messages", 48 | description = "The messages to send to the chat when the knockback failsafe has been triggered (use '|' to split the messages)", 49 | placeholder = "Leave empty to use a random message", 50 | multiline = true 51 | ) 52 | public static String customKnockbackMessages = ""; 53 | 54 | @Text( 55 | name = "Bedrock failsafe messages", 56 | description = "The messages to send to the chat when the bedrock failsafe has been triggered (use '|' to split the messages)", 57 | placeholder = "Leave empty to use a random message", 58 | multiline = true 59 | ) 60 | public static String customBedrockMessages = ""; 61 | 62 | @Text( 63 | name = "Dirt failsafe messages", 64 | description = "The messages to send to the chat when the dirt failsafe has been triggered (use '|' to split the messages)", 65 | placeholder = "Leave empty to use a random message", 66 | multiline = true 67 | ) 68 | public static String customDirtMessages = ""; 69 | } 70 | -------------------------------------------------------------------------------- /src/main/java/com/jelly/farmhelperv2/feature/impl/LeaveTimer.java: -------------------------------------------------------------------------------- 1 | package com.jelly.farmhelperv2.feature.impl; 2 | 3 | import cc.polyfrost.oneconfig.utils.Multithreading; 4 | import com.jelly.farmhelperv2.config.FarmHelperConfig; 5 | import com.jelly.farmhelperv2.failsafe.FailsafeManager; 6 | import com.jelly.farmhelperv2.feature.FeatureManager; 7 | import com.jelly.farmhelperv2.feature.IFeature; 8 | import com.jelly.farmhelperv2.handler.MacroHandler; 9 | import com.jelly.farmhelperv2.util.LogUtils; 10 | import com.jelly.farmhelperv2.util.helper.AudioManager; 11 | import com.jelly.farmhelperv2.util.helper.Clock; 12 | import net.minecraft.client.Minecraft; 13 | import net.minecraft.util.ChatComponentText; 14 | import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; 15 | import net.minecraftforge.fml.common.gameevent.TickEvent; 16 | 17 | import java.util.concurrent.TimeUnit; 18 | 19 | /* 20 | Credits to Yuro for this superb class 21 | */ 22 | public class LeaveTimer implements IFeature { 23 | private final Minecraft mc = Minecraft.getMinecraft(); 24 | private static LeaveTimer instance; 25 | 26 | public static LeaveTimer getInstance() { 27 | if (instance == null) { 28 | instance = new LeaveTimer(); 29 | } 30 | return instance; 31 | } 32 | 33 | public static final Clock leaveClock = new Clock(); 34 | 35 | @Override 36 | public String getName() { 37 | return "Leave Timer"; 38 | } 39 | 40 | @Override 41 | public boolean isRunning() { 42 | return leaveClock.isScheduled(); 43 | } 44 | 45 | @Override 46 | public boolean shouldPauseMacroExecution() { 47 | return false; 48 | } 49 | 50 | @Override 51 | public boolean shouldStartAtMacroStart() { 52 | return isToggled(); 53 | } 54 | 55 | @Override 56 | public void start() { 57 | leaveClock.schedule(FarmHelperConfig.leaveTime * 60 * 1000L); 58 | IFeature.super.start(); 59 | } 60 | 61 | @Override 62 | public void stop() { 63 | leaveClock.reset(); 64 | IFeature.super.stop(); 65 | } 66 | 67 | @Override 68 | public void resetStatesAfterMacroDisabled() { 69 | leaveClock.reset(); 70 | } 71 | 72 | @Override 73 | public boolean isToggled() { 74 | return FarmHelperConfig.leaveTimer; 75 | } 76 | 77 | @Override 78 | public boolean shouldCheckForFailsafes() { 79 | return false; 80 | } 81 | 82 | @SubscribeEvent 83 | public void onTick(TickEvent.ClientTickEvent event) { 84 | if (mc.thePlayer == null || mc.theWorld == null) return; 85 | if (!isRunning()) return; 86 | if (FailsafeManager.getInstance().triggeredFailsafe.isPresent()) return; 87 | if (FeatureManager.getInstance().isAnyOtherFeatureEnabled(this)) return; 88 | if (leaveClock.isScheduled() && leaveClock.passed()) { 89 | LogUtils.sendDebug("Leave timer has ended."); 90 | leaveClock.reset(); 91 | MacroHandler.getInstance().disableMacro(); 92 | Multithreading.schedule(() -> { 93 | try { 94 | mc.getNetHandler().getNetworkManager().closeChannel(new ChatComponentText("The timer has ended")); 95 | AudioManager.getInstance().resetSound(); 96 | } catch (Exception e) { 97 | e.printStackTrace(); 98 | } 99 | }, 500, TimeUnit.MILLISECONDS); 100 | } 101 | } 102 | } 103 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

2 | 3 | 4 | 5 | 6 | release 7 | 8 | 9 | downloads 10 | 11 | 12 | discord 13 | 14 |

15 | 16 |
17 |
18 | 19 | Logo 20 | 21 | 22 |

FarmHelper V2

23 |

24 | Report Bug 25 | · 26 | Request Feature 27 |

28 |
29 | 30 | ## About The Project 31 | 32 | Imagine not having to stare at your computer for 12 hours a day just to press the A and D keys. Imagine, being able to skip all the repetitive processes of farming and do other things simultaneously. Farm Helper is a highly customizable skyblock quality of life (QOL) mod that automates boring farming processes, freeing up your time for other activities. 33 | 34 | Revolutionizing the farming meta of Hypixel skyblock, Farm Helper has already been downloaded over 30,000 times. Start your QOL journey by joining the Jellylab community! 35 | 36 | ## Contributing 37 | 38 | Contributions are what make the open source community such an amazing place to learn, inspire, and create. Any contributions you make are **greatly appreciated**. 39 | 40 | If you have a suggestion that would make this better, please fork the repo and create a pull request. 41 | Don't forget to give the project a star! Thanks again! 42 | 43 | 1. Fork the Project 44 | 2. Create your Feature Branch (`git checkout -b feature/AmazingFeature`) 45 | 3. Commit your Changes (`git commit -m 'Add some AmazingFeature'`) 46 | 4. Push to the Branch (`git push origin feature/AmazingFeature`) 47 | 5. Open a Pull Request 48 | 49 | ## License 50 | 51 | Distributed under a custom license. See `LICENSE` for more information. 52 | 53 | [contributors-shield]: https://img.shields.io/github/contributors/JellyLabScripts/FarmHelper.svg?style=for-the-badge 54 | [contributors-url]: https://github.com/JellyLabScripts/FarmHelper/graphs/contributors 55 | [forks-shield]: https://img.shields.io/github/forks/JellyLabScripts/FarmHelper.svg?style=for-the-badge 56 | [forks-url]: https://github.com/JellyLabScripts/FarmHelper/network/members 57 | [stars-shield]: https://img.shields.io/github/stars/JellyLabScripts/FarmHelper.svg?style=for-the-badge 58 | [stars-url]: https://github.com/JellyLabScripts/FarmHelper/stargazers 59 | [issues-shield]: https://img.shields.io/github/issues/JellyLabScripts/FarmHelper.svg?style=for-the-badge 60 | [issues-url]: https://github.com/JellyLabScripts/FarmHelper/issues 61 | [license-shield]: https://img.shields.io/github/license/JellyLabScripts/FarmHelper.svg?style=for-the-badge 62 | [license-url]: https://github.com/JellyLabScripts/FarmHelper/blob/master/LICENSE 63 | [downloads-shield]: https://img.shields.io/github/downloads/JellyLabScripts/FarmHelper/total.svg?style=for-the-badge 64 | -------------------------------------------------------------------------------- /src/main/java/com/jelly/farmhelperv2/remote/command/commands/impl/ToggleCommand.java: -------------------------------------------------------------------------------- 1 | package com.jelly.farmhelperv2.remote.command.commands.impl; 2 | 3 | import com.google.gson.JsonObject; 4 | import com.jelly.farmhelperv2.failsafe.FailsafeManager; 5 | import com.jelly.farmhelperv2.handler.GameStateHandler; 6 | import com.jelly.farmhelperv2.handler.MacroHandler; 7 | import com.jelly.farmhelperv2.remote.command.commands.ClientCommand; 8 | import com.jelly.farmhelperv2.remote.command.commands.Command; 9 | import com.jelly.farmhelperv2.remote.struct.RemoteMessage; 10 | 11 | @Command(label = "toggle") 12 | public class ToggleCommand extends ClientCommand { 13 | 14 | @Override 15 | public void execute(RemoteMessage message) { 16 | JsonObject data = new JsonObject(); 17 | data.addProperty("username", mc.getSession().getUsername()); 18 | data.addProperty("uuid", mc.getSession().getPlayerID()); 19 | data.addProperty("toggled", !MacroHandler.getInstance().isMacroToggled()); 20 | 21 | if (GameStateHandler.getInstance().getLocation() == GameStateHandler.Location.LOBBY && !MacroHandler.getInstance().isMacroToggled()) { 22 | data.addProperty("info", "You are in the lobby! Teleporting"); 23 | mc.thePlayer.sendChatMessage("/skyblock"); 24 | new Thread(() -> { 25 | try { 26 | Thread.sleep(2500); 27 | } catch (InterruptedException e) { 28 | e.printStackTrace(); 29 | } 30 | if (!GameStateHandler.getInstance().inGarden()) { 31 | MacroHandler.getInstance().triggerWarpGarden(true, false); 32 | } 33 | 34 | try { 35 | Thread.sleep(2500); 36 | } catch (InterruptedException e) { 37 | e.printStackTrace(); 38 | } 39 | if (!GameStateHandler.getInstance().inGarden()) { 40 | data.addProperty("info", "Can't teleport to the garden!"); 41 | } else { 42 | MacroHandler.getInstance().toggleMacro(); 43 | data.addProperty("info", "You are in garden! Macroing"); 44 | } 45 | RemoteMessage response = new RemoteMessage(label, data); 46 | send(response); 47 | }).start(); 48 | return; 49 | } else if (!GameStateHandler.getInstance().inGarden() && !MacroHandler.getInstance().isMacroToggled()) { 50 | data.addProperty("info", "You are outside the garden! Teleporting"); 51 | MacroHandler.getInstance().triggerWarpGarden(true, false); 52 | new Thread(() -> { 53 | try { 54 | Thread.sleep(2500); 55 | } catch (InterruptedException e) { 56 | e.printStackTrace(); 57 | } 58 | if (!GameStateHandler.getInstance().inGarden()) { 59 | data.addProperty("info", "Can't teleport to the garden!"); 60 | } else { 61 | MacroHandler.getInstance().toggleMacro(); 62 | data.addProperty("info", "You are in garden! Macroing"); 63 | } 64 | RemoteMessage response = new RemoteMessage(label, data); 65 | send(response); 66 | }).start(); 67 | return; 68 | } else { 69 | if (FailsafeManager.getInstance().isHadEmergency()) { 70 | FailsafeManager.getInstance().setHadEmergency(false); 71 | FailsafeManager.getInstance().getRestartMacroAfterFailsafeDelay().reset(); 72 | } 73 | MacroHandler.getInstance().toggleMacro(); 74 | } 75 | 76 | 77 | RemoteMessage response = new RemoteMessage(label, data); 78 | send(response); 79 | } 80 | } -------------------------------------------------------------------------------- /src/main/java/com/jelly/farmhelperv2/remote/command/discordCommands/impl/Toggle.java: -------------------------------------------------------------------------------- 1 | package com.jelly.farmhelperv2.remote.command.discordCommands.impl; 2 | 3 | import com.jelly.farmhelperv2.remote.WebsocketHandler; 4 | import com.jelly.farmhelperv2.remote.command.discordCommands.DiscordCommand; 5 | import com.jelly.farmhelperv2.remote.command.discordCommands.Option; 6 | import com.jelly.farmhelperv2.remote.waiter.Waiter; 7 | import com.jelly.farmhelperv2.remote.waiter.WaiterHandler; 8 | import com.jelly.farmhelperv2.util.AvatarUtils; 9 | import net.dv8tion.jda.api.EmbedBuilder; 10 | import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent; 11 | import net.dv8tion.jda.api.interactions.commands.OptionType; 12 | 13 | import java.util.Objects; 14 | 15 | public class Toggle extends DiscordCommand { 16 | public static final String name = "toggle"; 17 | public static final String description = "Toggle the bot"; 18 | 19 | public Toggle() { 20 | super(Toggle.name, Toggle.description); 21 | Option ign = new Option(OptionType.STRING, "ign", "The IGN of the player you want to toggle this account", false, true); 22 | addOptions(ign); 23 | } 24 | 25 | @Override 26 | public void execute(SlashCommandInteractionEvent event) { 27 | event.deferReply().queue(); 28 | WaiterHandler.register(new Waiter( 29 | 5000, 30 | name, 31 | action -> { 32 | String username = action.args.get("username").getAsString(); 33 | boolean toggled = action.args.get("toggled").getAsBoolean(); 34 | String uuid = action.args.get("uuid").getAsString(); 35 | boolean error = action.args.has("info"); 36 | 37 | EmbedBuilder embedBuilder = new EmbedBuilder(); 38 | embedBuilder.addField("Username", username, false); 39 | if (error) { 40 | embedBuilder.addField("Info", action.args.get("info").getAsString(), false); 41 | } 42 | embedBuilder.addField("Turned macro", (toggled && !error) ? "On" : "Off", false); 43 | int random = (int) (Math.random() * 0xFFFFFF); 44 | embedBuilder.setColor(random); 45 | embedBuilder.setFooter("-> FarmHelper Remote Control", "https://cdn.discordapp.com/attachments/861700235890130986/1144673641951395982/icon.png"); 46 | String avatar = AvatarUtils.getAvatarUrl(uuid); 47 | embedBuilder.setAuthor("Instance name -> " + username, avatar, avatar); 48 | 49 | try { 50 | event.getHook().sendMessageEmbeds(embedBuilder.build()).queue(); 51 | } catch (Exception e) { 52 | event.getChannel().sendMessageEmbeds(embedBuilder.build()).queue(); 53 | } 54 | }, 55 | timeoutAction -> event.getHook().sendMessage("Can't toggle the bot").queue(), 56 | event 57 | )); 58 | 59 | if (event.getOption("ign") != null) { 60 | String ign = Objects.requireNonNull(event.getOption("ign")).getAsString(); 61 | if (WebsocketHandler.getInstance().getWebsocketServer().minecraftInstances.containsValue(ign)) { 62 | WebsocketHandler.getInstance().getWebsocketServer().minecraftInstances.forEach((webSocket, s) -> { 63 | if (s.equals(ign)) { 64 | sendMessage(webSocket); 65 | } 66 | }); 67 | } else { 68 | event.getHook().sendMessage("There isn't any instances connected with that IGN").queue(); 69 | } 70 | } else { 71 | WebsocketHandler.getInstance().getWebsocketServer().minecraftInstances.forEach((webSocket, s) -> sendMessage(webSocket)); 72 | } 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /src/main/java/com/jelly/farmhelperv2/remote/command/discordCommands/impl/AutoSell.java: -------------------------------------------------------------------------------- 1 | package com.jelly.farmhelperv2.remote.command.discordCommands.impl; 2 | 3 | import com.jelly.farmhelperv2.remote.WebsocketHandler; 4 | import com.jelly.farmhelperv2.remote.command.discordCommands.DiscordCommand; 5 | import com.jelly.farmhelperv2.remote.command.discordCommands.Option; 6 | import com.jelly.farmhelperv2.remote.waiter.Waiter; 7 | import com.jelly.farmhelperv2.remote.waiter.WaiterHandler; 8 | import com.jelly.farmhelperv2.util.AvatarUtils; 9 | import net.dv8tion.jda.api.EmbedBuilder; 10 | import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent; 11 | import net.dv8tion.jda.api.interactions.commands.OptionType; 12 | 13 | import java.util.Objects; 14 | 15 | public class AutoSell extends DiscordCommand { 16 | public static final String name = "autosell"; 17 | public static final String description = "Trigger the AutoSell feature"; 18 | 19 | public AutoSell() { 20 | super(AutoSell.name, AutoSell.description); 21 | Option ign = new Option(OptionType.STRING, "ign", "The IGN of the player you want to toggle this account", false, true); 22 | addOptions(ign); 23 | } 24 | 25 | @Override 26 | public void execute(SlashCommandInteractionEvent event) { 27 | event.deferReply().queue(); 28 | WaiterHandler.register(new Waiter( 29 | 5000, 30 | name, 31 | action -> { 32 | String username = action.args.get("username").getAsString(); 33 | String uuid = action.args.get("uuid").getAsString(); 34 | boolean toggled = action.args.get("toggled").getAsBoolean(); 35 | boolean error = action.args.has("info"); 36 | 37 | EmbedBuilder embedBuilder = new EmbedBuilder(); 38 | embedBuilder.addField("Username", username, false); 39 | if (error) { 40 | embedBuilder.addField("Info", action.args.get("info").getAsString(), false); 41 | } 42 | embedBuilder.addField("Turned AutoSell", (toggled && !error) ? "On" : "Off", false); 43 | int random = (int) (Math.random() * 0xFFFFFF); 44 | embedBuilder.setColor(random); 45 | embedBuilder.setFooter("-> FarmHelper Remote Control", "https://cdn.discordapp.com/attachments/861700235890130986/1144673641951395982/icon.png"); 46 | String avatar = AvatarUtils.getAvatarUrl(uuid); 47 | embedBuilder.setAuthor("Instance name -> " + username, avatar, avatar); 48 | 49 | try { 50 | event.getHook().sendMessageEmbeds(embedBuilder.build()).queue(); 51 | } catch (Exception e) { 52 | event.getChannel().sendMessageEmbeds(embedBuilder.build()).queue(); 53 | } 54 | }, 55 | timeoutAction -> event.getHook().sendMessage("Can't toggle the bot").queue(), 56 | event 57 | )); 58 | 59 | if (event.getOption("ign") != null) { 60 | String ign = Objects.requireNonNull(event.getOption("ign")).getAsString(); 61 | if (WebsocketHandler.getInstance().getWebsocketServer().minecraftInstances.containsValue(ign)) { 62 | WebsocketHandler.getInstance().getWebsocketServer().minecraftInstances.forEach((webSocket, s) -> { 63 | if (s.equals(ign)) { 64 | sendMessage(webSocket); 65 | } 66 | }); 67 | } else { 68 | event.getHook().sendMessage("There isn't any instances connected with that IGN").queue(); 69 | } 70 | } else { 71 | WebsocketHandler.getInstance().getWebsocketServer().minecraftInstances.forEach((webSocket, s) -> sendMessage(webSocket)); 72 | } 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /src/main/java/com/jelly/farmhelperv2/util/ScoreboardUtils.java: -------------------------------------------------------------------------------- 1 | package com.jelly.farmhelperv2.util; 2 | 3 | import com.google.common.collect.Iterables; 4 | import com.google.common.collect.Lists; 5 | import com.jelly.farmhelperv2.event.UpdateScoreboardListEvent; 6 | import net.minecraft.client.Minecraft; 7 | import net.minecraft.scoreboard.Score; 8 | import net.minecraft.scoreboard.ScoreObjective; 9 | import net.minecraft.scoreboard.ScorePlayerTeam; 10 | import net.minecraft.scoreboard.Scoreboard; 11 | import net.minecraft.util.StringUtils; 12 | import net.minecraftforge.common.MinecraftForge; 13 | import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; 14 | import net.minecraftforge.fml.common.gameevent.TickEvent; 15 | 16 | import java.util.ArrayList; 17 | import java.util.Collection; 18 | import java.util.List; 19 | import java.util.stream.Collectors; 20 | 21 | public class ScoreboardUtils { 22 | private static final Minecraft mc = Minecraft.getMinecraft(); 23 | public static List cachedScoreboardLines = new ArrayList<>(); 24 | public static List cachedCleanScoreboardLines = new ArrayList<>(); 25 | 26 | public static List getScoreboardLines(boolean clean) { 27 | return (clean ? cachedCleanScoreboardLines : cachedScoreboardLines); 28 | } 29 | 30 | public static String getScoreboardTitle() { 31 | if (mc.theWorld == null) return ""; 32 | Scoreboard scoreboard = mc.theWorld.getScoreboard(); 33 | if (scoreboard == null) return ""; 34 | 35 | ScoreObjective objective = scoreboard.getObjectiveInDisplaySlot(1); 36 | if (objective == null) return ""; 37 | 38 | return StringUtils.stripControlCodes(objective.getDisplayName()); 39 | } 40 | 41 | private final List previousScoreboard = new ArrayList<>(); 42 | 43 | @SubscribeEvent 44 | public void onTick(TickEvent.PlayerTickEvent event) { 45 | if (mc.theWorld == null) return; 46 | long currentTime = System.currentTimeMillis(); 47 | Scoreboard scoreboard = Minecraft.getMinecraft().theWorld.getScoreboard(); 48 | List cleanScoreboardLines = new ArrayList<>(); 49 | List scoreboardLines = new ArrayList<>(); 50 | ScoreObjective objective = scoreboard.getObjectiveInDisplaySlot(1); 51 | Collection scores = scoreboard.getSortedScores(objective); 52 | List list = scores.stream() 53 | .filter(input -> input != null && input.getPlayerName() != null && !input.getPlayerName() 54 | .startsWith("#")) 55 | .collect(Collectors.toList()); 56 | 57 | if (list.size() > 15) { 58 | scores = Lists.newArrayList(Iterables.skip(list, scores.size() - 15)); 59 | } else { 60 | scores = list; 61 | } 62 | 63 | 64 | for (Score score : scores) { 65 | ScorePlayerTeam team = scoreboard.getPlayersTeam(score.getPlayerName()); 66 | String playerName = ScorePlayerTeam.formatPlayerName(team, score.getPlayerName()); 67 | scoreboardLines.add(playerName); 68 | cleanScoreboardLines.add(cleanSB(playerName)); 69 | } 70 | 71 | if (previousScoreboard.equals(cleanScoreboardLines)) return; 72 | 73 | previousScoreboard.clear(); 74 | previousScoreboard.addAll(cleanScoreboardLines); 75 | cachedScoreboardLines = scoreboardLines; 76 | cachedCleanScoreboardLines = cleanScoreboardLines; 77 | MinecraftForge.EVENT_BUS.post(new UpdateScoreboardListEvent(scoreboardLines, cleanScoreboardLines, currentTime)); 78 | } 79 | 80 | private static String cleanSB(String scoreboard) { 81 | StringBuilder cleaned = new StringBuilder(); 82 | 83 | for (char c : StringUtils.stripControlCodes(scoreboard).toCharArray()) { 84 | if (c >= 32 && c < 127 || c == 'ൠ') { 85 | cleaned.append(c); 86 | } 87 | } 88 | 89 | return cleaned.toString(); 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /src/main/java/com/jelly/farmhelperv2/failsafe/impl/DisconnectFailsafe.java: -------------------------------------------------------------------------------- 1 | package com.jelly.farmhelperv2.failsafe.impl; 2 | 3 | import com.jelly.farmhelperv2.config.FarmHelperConfig; 4 | import com.jelly.farmhelperv2.config.page.FailsafeNotificationsPage; 5 | import com.jelly.farmhelperv2.failsafe.Failsafe; 6 | import com.jelly.farmhelperv2.failsafe.FailsafeManager; 7 | import com.jelly.farmhelperv2.feature.impl.AutoReconnect; 8 | import com.jelly.farmhelperv2.feature.impl.BanInfoWS; 9 | import com.jelly.farmhelperv2.feature.impl.Scheduler; 10 | import com.jelly.farmhelperv2.feature.impl.Scheduler.SchedulerState; 11 | import com.jelly.farmhelperv2.handler.MacroHandler; 12 | import com.jelly.farmhelperv2.util.LogUtils; 13 | import net.minecraftforge.fml.common.network.FMLNetworkEvent; 14 | 15 | public class DisconnectFailsafe extends Failsafe { 16 | private static DisconnectFailsafe instance; 17 | 18 | public static DisconnectFailsafe getInstance() { 19 | if (instance == null) { 20 | instance = new DisconnectFailsafe(); 21 | } 22 | return instance; 23 | } 24 | 25 | @Override 26 | public int getPriority() { 27 | return 1; 28 | } 29 | 30 | @Override 31 | public FailsafeManager.EmergencyType getType() { 32 | return FailsafeManager.EmergencyType.DISCONNECT; 33 | } 34 | 35 | @Override 36 | public boolean shouldSendNotification() { 37 | return FailsafeNotificationsPage.notifyOnDisconnectFailsafe; 38 | } 39 | 40 | @Override 41 | public boolean shouldPlaySound() { 42 | return FailsafeNotificationsPage.alertOnDisconnectFailsafe; 43 | } 44 | 45 | @Override 46 | public boolean shouldTagEveryone() { 47 | return FailsafeNotificationsPage.tagEveryoneOnDisconnectFailsafe; 48 | } 49 | 50 | @Override 51 | public boolean shouldAltTab() { 52 | return FailsafeNotificationsPage.autoAltTabOnDisconnectFailsafe; 53 | } 54 | 55 | @Override 56 | public void onDisconnectDetection(FMLNetworkEvent.ClientDisconnectionFromServerEvent event) { 57 | // if (MacroHandler.getInstance().isTeleporting()) return; 58 | if (BanInfoWS.getInstance().isBanwave() && FarmHelperConfig.enableLeavePauseOnBanwave && !FarmHelperConfig.banwaveAction) { 59 | return; 60 | } 61 | 62 | if (Scheduler.getInstance().isRunning() && Scheduler.getInstance().getSchedulerState() == SchedulerState.BREAK && FarmHelperConfig.schedulerDisconnectDuringBreak){ 63 | return; 64 | } 65 | 66 | FailsafeManager.getInstance().possibleDetection(this); 67 | } 68 | 69 | @Override 70 | public void duringFailsafeTrigger() { 71 | if (!AutoReconnect.getInstance().isRunning() && AutoReconnect.getInstance().isToggled()) { 72 | System.out.println("[Reconnect] Disconnected from server! Trying to reconnect..."); 73 | LogUtils.sendNotification("Farm Helper", "Disconnected from server! Trying to reconnect..."); 74 | AutoReconnect.getInstance().getReconnectDelay().schedule(5_000); 75 | AutoReconnect.getInstance().start(); 76 | } else if (!AutoReconnect.getInstance().isRunning() && !AutoReconnect.getInstance().isToggled()) { 77 | System.out.println("[Reconnect] Disconnected from server! Stopping macro..."); 78 | LogUtils.sendNotification("Farm Helper", "Disconnected from server! Stopping macro..."); 79 | MacroHandler.getInstance().disableMacro(); 80 | FailsafeManager.getInstance().stopFailsafes(); 81 | } else if (AutoReconnect.getInstance().isRunning()) { 82 | System.out.println("[Reconnect] Disconnected from server! Reconnect is already running!"); 83 | LogUtils.sendNotification("Farm Helper", "Disconnected from server! Reconnect is already running!"); 84 | FailsafeManager.getInstance().stopFailsafes(); 85 | } 86 | } 87 | 88 | @Override 89 | public void endOfFailsafeTrigger() { 90 | 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /src/main/java/com/jelly/farmhelperv2/remote/command/discordCommands/impl/SetSpeed.java: -------------------------------------------------------------------------------- 1 | package com.jelly.farmhelperv2.remote.command.discordCommands.impl; 2 | 3 | import com.google.gson.JsonObject; 4 | import com.jelly.farmhelperv2.remote.WebsocketHandler; 5 | import com.jelly.farmhelperv2.remote.command.discordCommands.DiscordCommand; 6 | import com.jelly.farmhelperv2.remote.command.discordCommands.Option; 7 | import com.jelly.farmhelperv2.remote.waiter.Waiter; 8 | import com.jelly.farmhelperv2.remote.waiter.WaiterHandler; 9 | import com.jelly.farmhelperv2.util.AvatarUtils; 10 | import net.dv8tion.jda.api.EmbedBuilder; 11 | import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent; 12 | import net.dv8tion.jda.api.interactions.commands.OptionType; 13 | 14 | import java.util.Objects; 15 | 16 | public class SetSpeed extends DiscordCommand { 17 | public static final String name = "setspeed"; 18 | public static final String description = "Set speed of rancher boots"; 19 | 20 | public SetSpeed() { 21 | super(name, description); 22 | addOptions(new Option(OptionType.INTEGER, "speed", "The speed of the rancher boots", true, false), 23 | new Option(OptionType.STRING, "ign", "The IGN of the instance", false, true) 24 | ); 25 | } 26 | 27 | @Override 28 | public void execute(SlashCommandInteractionEvent event) { 29 | event.deferReply().queue(); 30 | WaiterHandler.register(new Waiter( 31 | 15000, 32 | name, 33 | action -> { 34 | String username = action.args.get("username").getAsString(); 35 | String speed = action.args.get("speed").getAsString(); 36 | String uuid = action.args.get("uuid").getAsString(); 37 | boolean error = action.args.has("error"); 38 | 39 | EmbedBuilder embedBuilder = new EmbedBuilder(); 40 | embedBuilder.addField("Username", username, false); 41 | if (error) { 42 | embedBuilder.addField("Error", action.args.get("error").getAsString(), false); 43 | } else { 44 | embedBuilder.addField("Set speed to", speed, false); 45 | } 46 | int random = (int) (Math.random() * 0xFFFFFF); 47 | embedBuilder.setColor(random); 48 | embedBuilder.setFooter("-> FarmHelper Remote Control", "https://cdn.discordapp.com/attachments/861700235890130986/1144673641951395982/icon.png"); 49 | String avatar = AvatarUtils.getAvatarUrl(uuid); 50 | embedBuilder.setAuthor("Instance name -> " + username, avatar, avatar); 51 | 52 | try { 53 | event.getHook().sendMessageEmbeds(embedBuilder.build()).queue(); 54 | } catch (Exception e) { 55 | event.getChannel().sendMessageEmbeds(embedBuilder.build()).queue(); 56 | } 57 | }, 58 | timeoutAction -> event.getHook().sendMessage("Can't set speed").queue(), 59 | event 60 | )); 61 | 62 | int speed = Objects.requireNonNull(event.getOption("speed")).getAsInt(); 63 | JsonObject args = new JsonObject(); 64 | args.addProperty("speed", speed); 65 | if (event.getOption("ign") != null) { 66 | String ign = Objects.requireNonNull(event.getOption("ign")).getAsString(); 67 | if (WebsocketHandler.getInstance().getWebsocketServer().minecraftInstances.containsValue(ign)) { 68 | WebsocketHandler.getInstance().getWebsocketServer().minecraftInstances.forEach((webSocket, s) -> { 69 | if (s.equals(ign)) { 70 | sendMessage(webSocket, args); 71 | } 72 | }); 73 | } else { 74 | event.getHook().sendMessage("There isn't any instances connected with that IGN").queue(); 75 | } 76 | } else { 77 | WebsocketHandler.getInstance().getWebsocketServer().minecraftInstances.forEach((webSocket, s) -> sendMessage(webSocket, args)); 78 | } 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /src/main/java/com/jelly/farmhelperv2/remote/command/discordCommands/impl/SendCommand.java: -------------------------------------------------------------------------------- 1 | package com.jelly.farmhelperv2.remote.command.discordCommands.impl; 2 | 3 | import com.google.gson.JsonObject; 4 | import com.jelly.farmhelperv2.remote.WebsocketHandler; 5 | import com.jelly.farmhelperv2.remote.command.discordCommands.DiscordCommand; 6 | import com.jelly.farmhelperv2.remote.command.discordCommands.Option; 7 | import com.jelly.farmhelperv2.remote.waiter.Waiter; 8 | import com.jelly.farmhelperv2.remote.waiter.WaiterHandler; 9 | import com.jelly.farmhelperv2.util.AvatarUtils; 10 | import net.dv8tion.jda.api.EmbedBuilder; 11 | import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent; 12 | import net.dv8tion.jda.api.interactions.commands.OptionType; 13 | 14 | import java.util.Objects; 15 | 16 | public class SendCommand extends DiscordCommand { 17 | public static final String name = "sendcommand"; 18 | public static final String description = "Run a minecraft command"; 19 | 20 | public SendCommand() { 21 | super(name, description); 22 | addOptions(new Option(OptionType.STRING, "command", "The command WITHOUT THE SLASH", true, false), 23 | new Option(OptionType.STRING, "ign", "The IGN of the instance", false, true) 24 | ); 25 | } 26 | 27 | @Override 28 | public void execute(SlashCommandInteractionEvent event) { 29 | event.deferReply().queue(); 30 | WaiterHandler.register(new Waiter( 31 | 15000, 32 | name, 33 | action -> { 34 | String username = action.args.get("username").getAsString(); 35 | String cmd = action.args.get("command").getAsString(); 36 | String uuid = action.args.get("uuid").getAsString(); 37 | boolean error = action.args.has("error"); 38 | 39 | EmbedBuilder embedBuilder = new EmbedBuilder(); 40 | embedBuilder.addField("Username", username, false); 41 | if (error) { 42 | embedBuilder.addField("Error", action.args.get("error").getAsString(), false); 43 | } else { 44 | embedBuilder.addField("Ran command:", cmd, false); 45 | } 46 | int random = (int) (Math.random() * 0xFFFFFF); 47 | embedBuilder.setColor(random); 48 | embedBuilder.setFooter("-> FarmHelper Remote Control", "https://cdn.discordapp.com/attachments/861700235890130986/1144673641951395982/icon.png"); 49 | String avatar = AvatarUtils.getAvatarUrl(uuid); 50 | embedBuilder.setAuthor("Instance name -> " + username, avatar, avatar); 51 | 52 | try { 53 | event.getHook().sendMessageEmbeds(embedBuilder.build()).queue(); 54 | } catch (Exception e) { 55 | event.getChannel().sendMessageEmbeds(embedBuilder.build()).queue(); 56 | } 57 | }, 58 | timeoutAction -> event.getHook().sendMessage("Can't run command").queue(), 59 | event 60 | )); 61 | 62 | int cmd = Objects.requireNonNull(event.getOption("command")).getAsInt(); 63 | JsonObject args = new JsonObject(); 64 | args.addProperty("command", cmd); 65 | if (event.getOption("ign") != null) { 66 | String ign = Objects.requireNonNull(event.getOption("ign")).getAsString(); 67 | if (WebsocketHandler.getInstance().getWebsocketServer().minecraftInstances.containsValue(ign)) { 68 | WebsocketHandler.getInstance().getWebsocketServer().minecraftInstances.forEach((webSocket, s) -> { 69 | if (s.equals(ign)) { 70 | sendMessage(webSocket, args); 71 | } 72 | }); 73 | } else { 74 | event.getHook().sendMessage("There isn't any instances connected with that IGN").queue(); 75 | } 76 | } else { 77 | WebsocketHandler.getInstance().getWebsocketServer().minecraftInstances.forEach((webSocket, s) -> sendMessage(webSocket, args)); 78 | } 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /src/main/java/com/jelly/farmhelperv2/remote/command/discordCommands/impl/Disconnect.java: -------------------------------------------------------------------------------- 1 | package com.jelly.farmhelperv2.remote.command.discordCommands.impl; 2 | 3 | import com.google.gson.JsonObject; 4 | import com.jelly.farmhelperv2.remote.WebsocketHandler; 5 | import com.jelly.farmhelperv2.remote.command.discordCommands.DiscordCommand; 6 | import com.jelly.farmhelperv2.remote.command.discordCommands.Option; 7 | import com.jelly.farmhelperv2.remote.waiter.Waiter; 8 | import com.jelly.farmhelperv2.remote.waiter.WaiterHandler; 9 | import com.jelly.farmhelperv2.util.AvatarUtils; 10 | import net.dv8tion.jda.api.EmbedBuilder; 11 | import net.dv8tion.jda.api.entities.MessageEmbed; 12 | import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent; 13 | import net.dv8tion.jda.api.interactions.commands.OptionType; 14 | import net.dv8tion.jda.api.utils.FileUpload; 15 | 16 | import java.util.Base64; 17 | import java.util.Objects; 18 | 19 | public class Disconnect extends DiscordCommand { 20 | public static final String name = "disconnect"; 21 | public static final String description = "Disconnect from the server"; 22 | 23 | public Disconnect() { 24 | super(name, description); 25 | addOptions(new Option(OptionType.STRING, "ign", "The IGN of the instance", false, true)); 26 | } 27 | 28 | @Override 29 | public void execute(SlashCommandInteractionEvent event) { 30 | event.deferReply().queue(); 31 | int timeout = 5000; 32 | WaiterHandler.register(new Waiter( 33 | timeout, 34 | name, 35 | action -> { 36 | String username = action.args.get("username").getAsString(); 37 | String image = action.args.get("image").getAsString(); 38 | EmbedBuilder embedBuilder = new EmbedBuilder(); 39 | embedBuilder.addField("Username", username, true); 40 | embedBuilder.setImage("attachment://image.png"); 41 | int random = (int) (Math.random() * 0xFFFFFF); 42 | embedBuilder.setColor(random); 43 | embedBuilder.setFooter("-> FarmHelper Remote Control", "https://cdn.discordapp.com/attachments/861700235890130986/1144673641951395982/icon.png"); 44 | String avatar = AvatarUtils.getAvatarUrl(action.args.get("uuid").getAsString()); 45 | embedBuilder.setAuthor("Instance name -> " + username, avatar, avatar); 46 | 47 | MessageEmbed em = embedBuilder.build(); 48 | try { 49 | event.getHook().sendMessageEmbeds(em).addFiles(FileUpload.fromData(Base64.getDecoder().decode(image), "image.png")).queue(); 50 | } catch (Exception e) { 51 | event.getChannel().sendMessageEmbeds(em).addFiles(FileUpload.fromData(Base64.getDecoder().decode(image), "image.png")).queue(); 52 | } 53 | }, 54 | timeoutAction -> { 55 | try { 56 | event.getHook().sendMessage("Can't invoke the Disconnect").queue(); 57 | } catch (Exception e) { 58 | event.getChannel().sendMessage("Can't invoke the Disconnect").queue(); 59 | } 60 | }, 61 | event 62 | )); 63 | JsonObject args = new JsonObject(); 64 | if (event.getOption("ign") != null) { 65 | String ign = Objects.requireNonNull(event.getOption("ign")).getAsString(); 66 | if (WebsocketHandler.getInstance().getWebsocketServer().minecraftInstances.containsValue(ign)) { 67 | WebsocketHandler.getInstance().getWebsocketServer().minecraftInstances.forEach((webSocket, s) -> { 68 | if (s.equals(ign)) { 69 | sendMessage(webSocket, args); 70 | } 71 | }); 72 | } else { 73 | event.getHook().sendMessage("There isn't any instances connected with that IGN").queue(); 74 | } 75 | } else { 76 | WebsocketHandler.getInstance().getWebsocketServer().minecraftInstances.forEach((webSocket, s) -> sendMessage(webSocket, args)); 77 | } 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /src/main/java/com/jelly/farmhelperv2/remote/command/discordCommands/impl/Screenshot.java: -------------------------------------------------------------------------------- 1 | package com.jelly.farmhelperv2.remote.command.discordCommands.impl; 2 | 3 | import com.google.gson.JsonObject; 4 | import com.jelly.farmhelperv2.remote.WebsocketHandler; 5 | import com.jelly.farmhelperv2.remote.command.discordCommands.DiscordCommand; 6 | import com.jelly.farmhelperv2.remote.command.discordCommands.Option; 7 | import com.jelly.farmhelperv2.remote.waiter.Waiter; 8 | import com.jelly.farmhelperv2.remote.waiter.WaiterHandler; 9 | import com.jelly.farmhelperv2.util.AvatarUtils; 10 | import net.dv8tion.jda.api.EmbedBuilder; 11 | import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent; 12 | import net.dv8tion.jda.api.interactions.commands.OptionType; 13 | import net.dv8tion.jda.api.utils.FileUpload; 14 | 15 | import java.util.Base64; 16 | import java.util.Objects; 17 | 18 | public class Screenshot extends DiscordCommand { 19 | public static final String name = "screenshot"; 20 | public static final String description = "Take a screenshot"; 21 | 22 | public Screenshot() { 23 | super(name, description); 24 | addOptions( 25 | new Option(OptionType.STRING, "ign", "The IGN of the instance", false, true), 26 | new Option(OptionType.BOOLEAN, "inventory", "Take a screenshot of the inventory", false, false) 27 | ); 28 | } 29 | 30 | @Override 31 | public void execute(SlashCommandInteractionEvent event) { 32 | event.deferReply().queue(); 33 | WaiterHandler.register(new Waiter( 34 | 5000, 35 | name, 36 | action -> { 37 | String username = action.args.get("username").getAsString(); 38 | String uuid = action.args.get("uuid").getAsString(); 39 | String image = action.args.get("image").getAsString(); 40 | 41 | EmbedBuilder embedBuilder = new EmbedBuilder(); 42 | embedBuilder.addField("Username", username, true); 43 | embedBuilder.setImage("attachment://image.png"); 44 | int random = (int) (Math.random() * 0xFFFFFF); 45 | embedBuilder.setColor(random); 46 | embedBuilder.setFooter("-> FarmHelper Remote Control", "https://cdn.discordapp.com/attachments/861700235890130986/1144673641951395982/icon.png"); 47 | String avatar = AvatarUtils.getAvatarUrl(uuid); 48 | embedBuilder.setAuthor("Instance name -> " + username, avatar, avatar); 49 | 50 | try { 51 | event.getHook().sendMessageEmbeds(embedBuilder.build()).addFiles(FileUpload.fromData(Base64.getDecoder().decode(image), "image.png")).queue(); 52 | } catch (Exception e) { 53 | event.getChannel().sendMessageEmbeds(embedBuilder.build()).addFiles(FileUpload.fromData(Base64.getDecoder().decode(image), "image.png")).queue(); 54 | } 55 | }, 56 | timeoutAction -> event.getHook().sendMessage("Can't take a screenshot").queue(), 57 | event 58 | )); 59 | 60 | boolean inventory = event.getOption("inventory") != null && Objects.requireNonNull(event.getOption("inventory")).getAsBoolean(); 61 | JsonObject args = new JsonObject(); 62 | args.addProperty("inventory", inventory); 63 | if (event.getOption("ign") != null) { 64 | String ign = Objects.requireNonNull(event.getOption("ign")).getAsString(); 65 | if (WebsocketHandler.getInstance().getWebsocketServer().minecraftInstances.containsValue(ign)) { 66 | WebsocketHandler.getInstance().getWebsocketServer().minecraftInstances.forEach((webSocket, s) -> { 67 | if (s.equals(ign)) { 68 | sendMessage(webSocket, args); 69 | } 70 | }); 71 | } else { 72 | event.getHook().sendMessage("There isn't any instances connected with that IGN").queue(); 73 | } 74 | } else { 75 | WebsocketHandler.getInstance().getWebsocketServer().minecraftInstances.forEach((webSocket, s) -> sendMessage(webSocket, args)); 76 | } 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /src/main/java/com/jelly/farmhelperv2/remote/command/commands/impl/SendCommandCommand.java: -------------------------------------------------------------------------------- 1 | package com.jelly.farmhelperv2.remote.command.commands.impl; 2 | 3 | import com.google.gson.JsonObject; 4 | import com.jelly.farmhelperv2.handler.MacroHandler; 5 | import com.jelly.farmhelperv2.remote.command.commands.ClientCommand; 6 | import com.jelly.farmhelperv2.remote.command.commands.Command; 7 | import com.jelly.farmhelperv2.remote.struct.RemoteMessage; 8 | import com.jelly.farmhelperv2.util.InventoryUtils; 9 | import com.jelly.farmhelperv2.util.LogUtils; 10 | import com.jelly.farmhelperv2.util.PlayerUtils; 11 | import com.jelly.farmhelperv2.util.helper.Clock; 12 | import com.jelly.farmhelperv2.util.helper.SignUtils; 13 | import net.minecraftforge.event.world.WorldEvent; 14 | import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; 15 | import net.minecraftforge.fml.common.gameevent.TickEvent; 16 | 17 | @Command(label = "sendcommand") 18 | public class SendCommandCommand extends ClientCommand { 19 | private static final Clock clock = new Clock(); 20 | private static String cmd = ""; 21 | private static JsonObject data; 22 | private static boolean enabled = false; 23 | private static State currentState = State.NONE; 24 | boolean wasMacroing = false; 25 | 26 | @Override 27 | public void execute(RemoteMessage message) { 28 | JsonObject args = message.args; 29 | cmd = args.get("command").getAsString(); 30 | data = new JsonObject(); 31 | data.addProperty("username", mc.getSession().getUsername()); 32 | data.addProperty("uuid", mc.getSession().getPlayerID()); 33 | data.addProperty("command", cmd); 34 | 35 | try { 36 | enabled = true; 37 | currentState = State.START; 38 | return; 39 | } catch (Exception e) { 40 | e.printStackTrace(); 41 | } 42 | 43 | 44 | RemoteMessage response = new RemoteMessage(label, data); 45 | send(response); 46 | } 47 | 48 | @SubscribeEvent 49 | public void onTick(TickEvent.ClientTickEvent event) { 50 | if (!enabled) return; 51 | if (ClientCommand.mc.thePlayer == null || ClientCommand.mc.theWorld == null) return; 52 | if (clock.isScheduled() && !clock.passed()) return; 53 | 54 | switch (currentState) { 55 | case NONE: 56 | clock.reset(); 57 | enabled = false; 58 | break; 59 | case START: 60 | wasMacroing = MacroHandler.getInstance().isMacroToggled(); 61 | if (wasMacroing) { 62 | MacroHandler.getInstance().pauseMacro(); 63 | } 64 | currentState = State.TYPE_COMMAND; 65 | clock.schedule(200); 66 | break; 67 | case TYPE_COMMAND: 68 | mc.thePlayer.sendChatMessage("/" + cmd); 69 | currentState = State.END; 70 | clock.schedule(100); 71 | break; 72 | case END: 73 | if (wasMacroing) { 74 | MacroHandler.getInstance().resumeMacro(); 75 | } 76 | LogUtils.sendSuccess("Command sent: " + cmd); 77 | currentState = State.NONE; 78 | clock.reset(); 79 | enabled = false; 80 | RemoteMessage response = new RemoteMessage(label, data); 81 | send(response); 82 | break; 83 | } 84 | } 85 | 86 | private void disableWithError(String message) { 87 | currentState = State.NONE; 88 | clock.reset(); 89 | enabled = false; 90 | LogUtils.sendError(message); 91 | data.addProperty("error", message); 92 | RemoteMessage response = new RemoteMessage(label, data); 93 | send(response); 94 | } 95 | 96 | @SubscribeEvent 97 | public void onWorldChange(WorldEvent.Unload event) { 98 | if (enabled) { 99 | disableWithError("World change detected! Disabling..."); 100 | } 101 | } 102 | 103 | public enum State { 104 | NONE, 105 | START, 106 | TYPE_COMMAND, 107 | END 108 | } 109 | } 110 | -------------------------------------------------------------------------------- /src/main/java/com/jelly/farmhelperv2/handler/BaritoneHandler.java: -------------------------------------------------------------------------------- 1 | package com.jelly.farmhelperv2.handler; 2 | 3 | import baritone.api.BaritoneAPI; 4 | import baritone.api.event.events.PathEvent; 5 | import baritone.api.pathing.goals.Goal; 6 | import baritone.api.pathing.goals.GoalBlock; 7 | import baritone.api.pathing.goals.GoalNear; 8 | import baritone.api.process.PathingCommand; 9 | import baritone.api.process.PathingCommandType; 10 | import com.jelly.farmhelperv2.util.helper.BaritoneEventListener; 11 | import net.minecraft.client.Minecraft; 12 | import net.minecraft.util.BlockPos; 13 | 14 | public class BaritoneHandler { 15 | private static final Minecraft mc = Minecraft.getMinecraft(); 16 | 17 | public static boolean pathing = false; 18 | 19 | public static boolean isPathing() { 20 | if (pathing) { 21 | return BaritoneEventListener.pathEvent != PathEvent.AT_GOAL 22 | && BaritoneEventListener.pathEvent != PathEvent.CALC_FAILED 23 | && BaritoneEventListener.pathEvent != PathEvent.NEXT_CALC_FAILED 24 | && BaritoneEventListener.pathEvent != PathEvent.CANCELED; 25 | } 26 | return false; 27 | } 28 | 29 | public static boolean isWalkingToGoalBlock() { 30 | return isWalkingToGoalBlock(0.75); 31 | } 32 | 33 | public static boolean isWalkingToGoalBlock(double nearGoalDistance) { 34 | if (pathing) { 35 | if (!mc.thePlayer.onGround) return true; 36 | double distance; 37 | Goal goal = BaritoneAPI.getProvider().getPrimaryBaritone().getPathingBehavior().getGoal(); 38 | if (goal instanceof GoalBlock) { 39 | GoalBlock goal1 = (GoalBlock) BaritoneAPI.getProvider().getPrimaryBaritone().getPathingBehavior().getGoal(); 40 | distance = mc.thePlayer.getDistance(goal1.getGoalPos().getX() + 0.5f, mc.thePlayer.posY, goal1.getGoalPos().getZ() + 0.5); 41 | } else if (goal instanceof GoalNear) { 42 | GoalNear goal1 = (GoalNear) BaritoneAPI.getProvider().getPrimaryBaritone().getPathingBehavior().getGoal(); 43 | distance = mc.thePlayer.getDistance(goal1.getGoalPos().getX() + 0.5f, mc.thePlayer.posY, goal1.getGoalPos().getZ() + 0.5); 44 | } else { 45 | distance = goal.isInGoal(mc.thePlayer.getPosition()) ? 0 : goal.heuristic(); 46 | } 47 | // System.out.println("Pathing result: " + BaritoneEventListener.pathEvent); 48 | // System.out.println("Distance: " + distance); 49 | // System.out.println("Goal: " + goal); 50 | if (distance <= nearGoalDistance || BaritoneEventListener.pathEvent == PathEvent.AT_GOAL) { 51 | BaritoneAPI.getProvider().getPrimaryBaritone().getPathingBehavior().cancelEverything(); 52 | pathing = false; 53 | return false; 54 | } 55 | return BaritoneEventListener.pathEvent != PathEvent.CANCELED; 56 | } 57 | return false; 58 | } 59 | 60 | public static boolean hasFailed() { 61 | if (BaritoneEventListener.pathEvent == PathEvent.CALC_FAILED 62 | || BaritoneEventListener.pathEvent == PathEvent.NEXT_CALC_FAILED) { 63 | BaritoneAPI.getProvider().getPrimaryBaritone().getPathingBehavior().cancelEverything(); 64 | pathing = false; 65 | return true; 66 | } 67 | return false; 68 | } 69 | 70 | public static void walkToBlockPos(BlockPos blockPos) { 71 | PathingCommand pathingCommand = new PathingCommand(new GoalBlock(blockPos), PathingCommandType.REVALIDATE_GOAL_AND_PATH); 72 | BaritoneAPI.getProvider().getPrimaryBaritone().getPathingBehavior().secretInternalSetGoalAndPath(pathingCommand); 73 | pathing = true; 74 | } 75 | 76 | public static void walkCloserToBlockPos(BlockPos blockPos, int range) { 77 | PathingCommand pathingCommand = new PathingCommand(new GoalNear(blockPos, range), PathingCommandType.REVALIDATE_GOAL_AND_PATH); 78 | BaritoneAPI.getProvider().getPrimaryBaritone().getPathingBehavior().secretInternalSetGoalAndPath(pathingCommand); 79 | pathing = true; 80 | } 81 | 82 | public static void stopPathing() { 83 | BaritoneAPI.getProvider().getPrimaryBaritone().getPathingBehavior().cancelEverything(); 84 | pathing = false; 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /src/main/java/com/jelly/farmhelperv2/feature/impl/RancherSpeedSetter.java: -------------------------------------------------------------------------------- 1 | package com.jelly.farmhelperv2.feature.impl; 2 | 3 | import cc.polyfrost.oneconfig.utils.Multithreading; 4 | import com.jelly.farmhelperv2.config.FarmHelperConfig; 5 | import com.jelly.farmhelperv2.handler.MacroHandler; 6 | import com.jelly.farmhelperv2.util.InventoryUtils; 7 | import com.jelly.farmhelperv2.util.LogUtils; 8 | import com.jelly.farmhelperv2.util.PlayerUtils; 9 | import com.jelly.farmhelperv2.util.helper.Clock; 10 | import com.jelly.farmhelperv2.util.helper.SignUtils; 11 | import net.minecraft.client.Minecraft; 12 | import net.minecraftforge.common.MinecraftForge; 13 | import net.minecraftforge.event.world.WorldEvent; 14 | import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; 15 | import net.minecraftforge.fml.common.gameevent.TickEvent; 16 | import java.util.concurrent.TimeUnit; 17 | 18 | 19 | public final class RancherSpeedSetter { 20 | /** @return true if need to change speed (async started), false otherwise */ 21 | public static boolean runIfNeeded(Runnable after) { 22 | if (!FarmHelperConfig.customFarmingSpeed) return false; 23 | 24 | int current = InventoryUtils.getRancherBootSpeed(); 25 | if (current == -1) return false; 26 | if (current == FarmHelperConfig.farmingSpeed) return false; 27 | 28 | INSTANCE.start(after); 29 | return true; 30 | } 31 | 32 | private enum Stage { NONE, START, INPUT, CONFIRM, END } 33 | 34 | private static final RancherSpeedSetter INSTANCE = new RancherSpeedSetter(); 35 | 36 | private final Minecraft mc = Minecraft.getMinecraft(); 37 | private final Clock clock = new Clock(); 38 | private Stage stage = Stage.NONE; 39 | private Runnable callback; 40 | private boolean enabled; 41 | private boolean worldChanging; 42 | 43 | private RancherSpeedSetter() {} 44 | 45 | private void start(Runnable after) { 46 | if (enabled) return; 47 | this.callback = after; 48 | this.stage = Stage.START; 49 | this.enabled = true; 50 | this.worldChanging = false; 51 | clock.reset(); 52 | MinecraftForge.EVENT_BUS.register(this); 53 | LogUtils.sendDebug("[Rancher Speed Setter]: starting (target " + FarmHelperConfig.farmingSpeed + ")"); 54 | } 55 | 56 | @SubscribeEvent 57 | public void onWorldUnload(WorldEvent.Unload e) { worldChanging = true; } 58 | 59 | @SubscribeEvent 60 | public void onTick(TickEvent.ClientTickEvent e) { 61 | if (!enabled || e.phase == TickEvent.Phase.END) return; 62 | if (mc.thePlayer == null || mc.theWorld == null || worldChanging) { finish(); return; } 63 | if (clock.isScheduled() && !clock.passed()) return; 64 | 65 | switch (stage) { 66 | case START: { 67 | mc.thePlayer.sendChatMessage("/setmaxspeed"); 68 | stage = Stage.INPUT; 69 | clock.schedule(750); 70 | break; 71 | } 72 | case INPUT: { 73 | if (mc.currentScreen == null) break; 74 | SignUtils.setTextToWriteOnString(String.valueOf(FarmHelperConfig.farmingSpeed)); 75 | stage = Stage.CONFIRM; 76 | clock.schedule(750); 77 | break; 78 | } 79 | case CONFIRM: { 80 | if (mc.currentScreen == null) break; 81 | SignUtils.confirmSign(); 82 | stage = Stage.END; 83 | clock.schedule(750); 84 | break; 85 | } 86 | case END: { 87 | LogUtils.sendSuccess("Rancher's Boots Speed set to " + FarmHelperConfig.farmingSpeed + "."); 88 | PlayerUtils.getFarmingTool(MacroHandler.getInstance().getCrop(), false, false); 89 | finish(); 90 | break; 91 | } 92 | default: break; 93 | } 94 | } 95 | 96 | private void finish() { 97 | enabled = false; 98 | stage = Stage.NONE; 99 | clock.reset(); 100 | MinecraftForge.EVENT_BUS.unregister(this); 101 | if (callback != null) { 102 | Runnable run = callback; 103 | callback = null; 104 | Multithreading.schedule(run, 0, TimeUnit.MILLISECONDS); 105 | } 106 | } 107 | } -------------------------------------------------------------------------------- /src/main/java/com/jelly/farmhelperv2/util/helper/RotationConfiguration.java: -------------------------------------------------------------------------------- 1 | package com.jelly.farmhelperv2.util.helper; 2 | 3 | import com.jelly.farmhelperv2.handler.RotationHandler; 4 | import lombok.Getter; 5 | import lombok.Setter; 6 | import lombok.experimental.Accessors; 7 | import net.minecraft.client.Minecraft; 8 | 9 | import java.util.Optional; 10 | 11 | 12 | @Getter 13 | @Setter 14 | @Accessors(fluent = true) 15 | public class RotationConfiguration { 16 | private final Minecraft mc = Minecraft.getMinecraft(); 17 | private Rotation from; 18 | private Optional to = Optional.empty(); 19 | private Optional target = Optional.empty(); 20 | private long time; 21 | private Optional callback; 22 | private boolean goingBackToClientSide = false; 23 | private boolean followTarget = false; 24 | private RotationType rotationType = RotationType.CLIENT; 25 | private boolean easeOutBack = false; 26 | private boolean randomness = false; 27 | 28 | public RotationConfiguration(Rotation from, Rotation to, long time, RotationType rotationType, Runnable callback) { 29 | this.from = from; 30 | this.to = Optional.ofNullable(to); 31 | this.time = time; 32 | this.rotationType = rotationType; 33 | this.callback = Optional.ofNullable(callback); 34 | } 35 | 36 | public RotationConfiguration(Rotation from, Target target, long time, RotationType rotationType, Runnable callback) { 37 | this.from = from; 38 | this.time = time; 39 | this.target = Optional.ofNullable(target); 40 | this.rotationType = rotationType; 41 | this.callback = Optional.ofNullable(callback); 42 | } 43 | 44 | public RotationConfiguration(Rotation to, long time, Runnable callback) { 45 | this.from = RotationHandler.getInstance().getConfiguration() != null && RotationHandler.getInstance().getConfiguration().goingBackToClientSide() ? new Rotation(RotationHandler.getInstance().getServerSideYaw(), RotationHandler.getInstance().getServerSidePitch()) : new Rotation(mc.thePlayer.rotationYaw, mc.thePlayer.rotationPitch); 46 | this.to = Optional.ofNullable(to); 47 | this.time = time; 48 | this.callback = Optional.ofNullable(callback); 49 | } 50 | 51 | public RotationConfiguration(Rotation to, long time, RotationType rotationType, Runnable callback) { 52 | this.from = RotationHandler.getInstance().getConfiguration() != null && RotationHandler.getInstance().getConfiguration().goingBackToClientSide() ? new Rotation(RotationHandler.getInstance().getServerSideYaw(), RotationHandler.getInstance().getServerSidePitch()) : new Rotation(mc.thePlayer.rotationYaw, mc.thePlayer.rotationPitch); 53 | this.to = Optional.ofNullable(to); 54 | this.time = time; 55 | this.rotationType = rotationType; 56 | this.callback = Optional.ofNullable(callback); 57 | } 58 | 59 | public RotationConfiguration(Target target, long time, Runnable callback) { 60 | this.from = RotationHandler.getInstance().getConfiguration() != null && RotationHandler.getInstance().getConfiguration().goingBackToClientSide() ? new Rotation(RotationHandler.getInstance().getServerSideYaw(), RotationHandler.getInstance().getServerSidePitch()) : new Rotation(mc.thePlayer.rotationYaw, mc.thePlayer.rotationPitch); 61 | this.time = time; 62 | this.target = Optional.ofNullable(target); 63 | this.callback = Optional.ofNullable(callback); 64 | } 65 | 66 | public RotationConfiguration(Target target, long time, RotationType rotationType, Runnable callback) { 67 | this.from = RotationHandler.getInstance().getConfiguration() != null && RotationHandler.getInstance().getConfiguration().goingBackToClientSide() ? new Rotation(RotationHandler.getInstance().getServerSideYaw(), RotationHandler.getInstance().getServerSidePitch()) : new Rotation(mc.thePlayer.rotationYaw, mc.thePlayer.rotationPitch); 68 | this.time = time; 69 | this.target = Optional.ofNullable(target); 70 | this.rotationType = rotationType; 71 | this.callback = Optional.ofNullable(callback); 72 | } 73 | 74 | public enum RotationType { 75 | SERVER, 76 | CLIENT 77 | } 78 | 79 | @Override 80 | public Object clone() { 81 | try { 82 | return super.clone(); 83 | } catch (CloneNotSupportedException e) { 84 | throw new RuntimeException(e); 85 | } 86 | } 87 | } 88 | --------------------------------------------------------------------------------