diff --git a/build.gradle b/build.gradle index 2365ba5c..49776f52 100755 --- a/build.gradle +++ b/build.gradle @@ -155,6 +155,9 @@ dependencies { } testImplementation 'junit:junit:4.12' + + compileOnly 'org.projectlombok:lombok:1.18.12' + annotationProcessor 'org.projectlombok:lombok:1.18.12' } mixin { diff --git a/src/api/java/baritone/api/Settings.java b/src/api/java/baritone/api/Settings.java index 7fb9c53b..b461736e 100644 --- a/src/api/java/baritone/api/Settings.java +++ b/src/api/java/baritone/api/Settings.java @@ -830,6 +830,11 @@ public final class Settings { */ public final Setting mineScanDroppedItems = new Setting<>(true); + /** + * Hyritone: Detect ore locations with a separate world seed. + */ + public final Setting mineWithSeed = new Setting<>(false); + /** * While mining, wait this number of milliseconds after mining an ore to see if it will drop an item * instead of immediately going onto the next one diff --git a/src/api/java/baritone/api/event/listener/AbstractGameEventListener.java b/src/api/java/baritone/api/event/listener/AbstractGameEventListener.java index 9eac8de4..d5775752 100644 --- a/src/api/java/baritone/api/event/listener/AbstractGameEventListener.java +++ b/src/api/java/baritone/api/event/listener/AbstractGameEventListener.java @@ -18,6 +18,7 @@ package baritone.api.event.listener; import baritone.api.event.events.*; +import net.minecraft.util.math.BlockPos; /** * An implementation of {@link IGameEventListener} that has all methods @@ -71,4 +72,7 @@ public interface AbstractGameEventListener extends IGameEventListener { @Override default void onPathEvent(PathEvent event) {} + + @Override + default void onBlockBreak(BlockPos pos) {} } diff --git a/src/api/java/baritone/api/event/listener/IGameEventListener.java b/src/api/java/baritone/api/event/listener/IGameEventListener.java index 21474fb5..4b449b00 100644 --- a/src/api/java/baritone/api/event/listener/IGameEventListener.java +++ b/src/api/java/baritone/api/event/listener/IGameEventListener.java @@ -20,10 +20,10 @@ package baritone.api.event.listener; import baritone.api.event.events.*; import net.minecraft.client.Minecraft; import net.minecraft.client.entity.player.ClientPlayerEntity; -import net.minecraft.client.gui.screen.DeathScreen; import net.minecraft.client.gui.screen.Screen; import net.minecraft.client.world.ClientWorld; import net.minecraft.entity.Entity; +import net.minecraft.util.math.BlockPos; /** * @author Brady @@ -137,4 +137,11 @@ public interface IGameEventListener { * @param event The event */ void onPathEvent(PathEvent event); + + /** + * This is called when the player breaks blocks. + * + * @param pos Block position + */ + void onBlockBreak(BlockPos pos); } diff --git a/src/launch/java/baritone/launch/LaunchTesting.java b/src/launch/java/baritone/launch/LaunchTesting.java index 21607ae3..7a99819c 100644 --- a/src/launch/java/baritone/launch/LaunchTesting.java +++ b/src/launch/java/baritone/launch/LaunchTesting.java @@ -57,6 +57,9 @@ public class LaunchTesting { attemptLogin(arguments, System.getenv("username"), System.getenv("password")); } + // Unify username + arguments.put("username", "TestUser"); + List argsArray = new ArrayList<>(); arguments.forEach((k, v) -> { argsArray.add("--" + k); diff --git a/src/launch/java/baritone/launch/mixins/MixinMouse.java b/src/launch/java/baritone/launch/mixins/MixinMouse.java new file mode 100644 index 00000000..e54a4fc4 --- /dev/null +++ b/src/launch/java/baritone/launch/mixins/MixinMouse.java @@ -0,0 +1,99 @@ +/* + * This file is part of Baritone. + * + * Baritone is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Baritone is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Baritone. If not, see . + */ + +package baritone.launch.mixins; + +import baritone.utils.accessor.IMouse; +import net.minecraft.client.Minecraft; +import net.minecraft.client.MouseHelper; +import org.spongepowered.asm.mixin.Final; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +import static org.hydev.hyritone.utils.MiscUtils.sleep; + +/** + * Mixin to control mouse operations + *

+ * Class created by the HyDEV Team on 2020-02-21! + * + * @author HyDEV Team (https://github.com/HyDevelop) + * @author Hykilpikonna (https://github.com/hykilpikonna) + * @author Vanilla (https://github.com/VergeDX) + * @since 2020-02-21 13:54 + */ +@Mixin(MouseHelper.class) +public abstract class MixinMouse implements IMouse +{ + @Shadow + protected abstract void mouseButtonCallback(long window, int button, int action, int mods); + + @Shadow @Final private Minecraft minecraft; + + @Inject(method = "mouseButtonCallback", at = @At("HEAD"), cancellable = true) + private void inject(long window, int button, int action, int mods, CallbackInfo info) + { + System.out.println(window + " | " + button + " | " + action + " | " + mods + " | " + System.currentTimeMillis()); + } + + public void rightClick() + { + new Thread(() -> + { + rightHold(); + sleep((long) (70 + Math.random() * 10)); + rightRelease(); + }).start(); + } + + public void leftClick() + { + new Thread(() -> + { + leftHold(); + sleep((long) (70 + Math.random() * 10)); + leftRelease(); + }).start(); + } + + @Override + public void rightHold() + { + mouseButtonCallback(minecraft.getMainWindow().getHandle(), 1, 1, 0); + } + + @Override + public void rightRelease() + { + mouseButtonCallback(minecraft.getMainWindow().getHandle(), 1, 0, 0); + } + + @Override + public void leftHold() + { + mouseButtonCallback(minecraft.getMainWindow().getHandle(), 0, 1, 0); + } + + @Override + public void leftRelease() + { + mouseButtonCallback(minecraft.getMainWindow().getHandle(), 0, 0, 0); + } +} diff --git a/src/launch/java/baritone/launch/mixins/MixinPlayerController.java b/src/launch/java/baritone/launch/mixins/MixinPlayerController.java index 071cbc9a..e9eb1762 100644 --- a/src/launch/java/baritone/launch/mixins/MixinPlayerController.java +++ b/src/launch/java/baritone/launch/mixins/MixinPlayerController.java @@ -17,16 +17,28 @@ package baritone.launch.mixins; +import baritone.api.BaritoneAPI; +import baritone.api.IBaritone; import baritone.utils.accessor.IPlayerControllerMP; +import net.minecraft.client.Minecraft; import net.minecraft.client.multiplayer.PlayerController; import net.minecraft.util.math.BlockPos; +import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.gen.Accessor; import org.spongepowered.asm.mixin.gen.Invoker; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; @Mixin(PlayerController.class) public abstract class MixinPlayerController implements IPlayerControllerMP { + @Shadow + @Final + private Minecraft mc; + @Accessor @Override public abstract void setIsHittingBlock(boolean isHittingBlock); @@ -38,4 +50,20 @@ public abstract class MixinPlayerController implements IPlayerControllerMP { @Invoker @Override public abstract void callSyncCurrentPlayItem(); + + @Inject( + method = "onPlayerDestroyBlock", + at = @At(value = "TAIL") + ) + public void onPlayerDestroyBlock(BlockPos pos, CallbackInfoReturnable cir) + { + // Check if the block is broken + if (!cir.getReturnValue()) return; + + // Call event + IBaritone baritone = BaritoneAPI.getProvider().getBaritoneForPlayer(this.mc.player); + if (baritone != null) { + baritone.getGameEventHandler().onBlockBreak(pos); + } + } } diff --git a/src/main/java/baritone/Baritone.java b/src/main/java/baritone/Baritone.java index 4b9944d8..634d01b3 100755 --- a/src/main/java/baritone/Baritone.java +++ b/src/main/java/baritone/Baritone.java @@ -25,12 +25,13 @@ import baritone.api.utils.Helper; import baritone.api.utils.IPlayerContext; import baritone.behavior.*; import baritone.cache.WorldProvider; +import baritone.command.manager.CommandManager; import baritone.event.GameEventHandler; import baritone.process.*; import baritone.selection.SelectionManager; import baritone.utils.*; -import baritone.command.manager.CommandManager; import baritone.utils.player.PrimaryPlayerContext; +import org.hydev.hyritone.Hyritone; import net.minecraft.client.Minecraft; import java.io.File; @@ -87,6 +88,8 @@ public class Baritone implements IBaritone { public BlockStateInterface bsi; + public Hyritone hyritone; + Baritone() { this.gameEventHandler = new GameEventHandler(this); @@ -121,6 +124,9 @@ public class Baritone implements IBaritone { if (BaritoneAutoTest.ENABLE_AUTO_TEST) { this.gameEventHandler.registerEventListener(BaritoneAutoTest.INSTANCE); } + + // Hyritone + this.hyritone = new Hyritone(this); } @Override diff --git a/src/main/java/baritone/command/defaults/DefaultCommands.java b/src/main/java/baritone/command/defaults/DefaultCommands.java index 67555ed5..07737aa9 100644 --- a/src/main/java/baritone/command/defaults/DefaultCommands.java +++ b/src/main/java/baritone/command/defaults/DefaultCommands.java @@ -19,6 +19,7 @@ package baritone.command.defaults; import baritone.api.IBaritone; import baritone.api.command.ICommand; +import org.hydev.hyritone.seedxray.SeedXrayCommand; import java.util.*; @@ -64,7 +65,10 @@ public final class DefaultCommands { new WaypointsCommand(baritone), new CommandAlias(baritone, "sethome", "Sets your home waypoint", "waypoints save home"), new CommandAlias(baritone, "home", "Set goal to your home waypoint", "waypoints goal home"), - new SelCommand(baritone) + new SelCommand(baritone), + + // Hyritone + new SeedXrayCommand(baritone) )); ExecutionControlCommands prc = new ExecutionControlCommands(baritone); commands.add(prc.pauseCommand); diff --git a/src/main/java/baritone/event/GameEventHandler.java b/src/main/java/baritone/event/GameEventHandler.java index ba40f1b6..5cedc54e 100644 --- a/src/main/java/baritone/event/GameEventHandler.java +++ b/src/main/java/baritone/event/GameEventHandler.java @@ -25,6 +25,7 @@ import baritone.api.event.listener.IGameEventListener; import baritone.api.utils.Helper; import baritone.cache.WorldProvider; import baritone.utils.BlockStateInterface; +import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; import net.minecraft.world.chunk.Chunk; @@ -161,4 +162,9 @@ public final class GameEventHandler implements IEventBus, Helper { public final void registerEventListener(IGameEventListener listener) { this.listeners.add(listener); } + + public final void onBlockBreak(BlockPos blockPos) + { + listeners.forEach(l -> l.onBlockBreak(blockPos)); + } } diff --git a/src/main/java/baritone/process/MineProcess.java b/src/main/java/baritone/process/MineProcess.java index 148dc72c..da0c8b90 100644 --- a/src/main/java/baritone/process/MineProcess.java +++ b/src/main/java/baritone/process/MineProcess.java @@ -36,6 +36,7 @@ import net.minecraft.entity.Entity; import net.minecraft.entity.item.ItemEntity; import net.minecraft.item.ItemStack; import net.minecraft.util.math.BlockPos; +import org.hydev.hyritone.Hyritone; import java.util.*; import java.util.stream.Collectors; @@ -319,39 +320,53 @@ public final class MineProcess extends BaritoneProcessHelper implements IMinePro public static List searchWorld(CalculationContext ctx, BlockOptionalMetaLookup filter, int max, List alreadyKnown, List blacklist, List dropped) { List locs = new ArrayList<>(); List untracked = new ArrayList<>(); - for (BlockOptionalMeta bom : filter.blocks()) { - Block block = bom.getBlock(); - if (CachedChunk.BLOCKS_TO_KEEP_TRACK_OF.contains(block)) { - BetterBlockPos pf = ctx.baritone.getPlayerContext().playerFeet(); - // maxRegionDistanceSq 2 means adjacent directly or adjacent diagonally; nothing further than that - locs.addAll(ctx.worldData.getCachedWorld().getLocationsOf( + // Check mine with seed + if (!Baritone.settings().mineWithSeed.value) + { + // Search the actual world + for (BlockOptionalMeta bom : filter.blocks()) { + Block block = bom.getBlock(); + if (CachedChunk.BLOCKS_TO_KEEP_TRACK_OF.contains(block)) { + BetterBlockPos pf = ctx.baritone.getPlayerContext().playerFeet(); + + // maxRegionDistanceSq 2 means adjacent directly or adjacent diagonally; nothing further than that + locs.addAll(ctx.worldData.getCachedWorld().getLocationsOf( BlockUtils.blockToString(block), Baritone.settings().maxCachedWorldScanCount.value, pf.x, pf.z, 2 - )); - } else { - untracked.add(block); + )); + } else { + untracked.add(block); + } } - } - locs = prune(ctx, locs, filter, max, blacklist, dropped); + locs = prune(ctx, locs, filter, max, blacklist, dropped); - if (!untracked.isEmpty() || (Baritone.settings().extendCacheOnThreshold.value && locs.size() < max)) { - locs.addAll(WorldScanner.INSTANCE.scanChunkRadius( + if (!untracked.isEmpty() || (Baritone.settings().extendCacheOnThreshold.value && locs.size() < max)) { + locs.addAll(WorldScanner.INSTANCE.scanChunkRadius( ctx.getBaritone().getPlayerContext(), filter, max, 10, 32 - )); // maxSearchRadius is NOT sq + )); // maxSearchRadius is NOT sq + } + + locs.addAll(alreadyKnown); + + return prune(ctx, locs, filter, max, blacklist, dropped); + } + else + { + // Add seed ores + locs.addAll(Hyritone.seedServerCache.cacheBlocks); + locs = prune(ctx, locs, filter, max, blacklist, dropped); } - locs.addAll(alreadyKnown); - - return prune(ctx, locs, filter, max, blacklist, dropped); + return locs; } private void addNearby() { @@ -392,7 +407,10 @@ public final class MineProcess extends BaritoneProcessHelper implements IMinePro .distinct() // remove any that are within loaded chunks that aren't actually what we want - .filter(pos -> !ctx.bsi.worldContainsLoadedChunk(pos.getX(), pos.getZ()) || filter.has(ctx.get(pos.getX(), pos.getY(), pos.getZ())) || dropped.contains(pos)) + .filter(pos -> Baritone.settings().mineWithSeed.value || !ctx.bsi.worldContainsLoadedChunk(pos.getX(), pos.getZ()) || filter.has(ctx.get(pos.getX(), pos.getY(), pos.getZ())) || dropped.contains(pos)) + + // Hyritone: remove air + .filter(pos -> !Baritone.settings().mineWithSeed.value || !ctx.get(pos).isAir() || dropped.contains(pos)) // remove any that are implausible to mine (encased in bedrock, or touching lava) .filter(pos -> MineProcess.plausibleToBreak(ctx, pos)) @@ -425,11 +443,15 @@ public final class MineProcess extends BaritoneProcessHelper implements IMinePro @Override public void mine(int quantity, BlockOptionalMetaLookup filter) { this.filter = filter; - if (filter != null && !Baritone.settings().allowBreak.value) { + + // Hyritone start - #1: Users are not idiots, if they disabled allow break, it's not for mining. + /*if (filter != null && !settings().allowBreak.value) { logDirect("Unable to mine when allowBreak is false!"); this.mine(quantity, (BlockOptionalMetaLookup) null); return; - } + }*/ + // Hyritone end + this.desiredQuantity = quantity; this.knownOreLocations = new ArrayList<>(); this.blacklist = new ArrayList<>(); diff --git a/src/main/java/baritone/utils/BlockStateInterface.java b/src/main/java/baritone/utils/BlockStateInterface.java index 6e4e36e2..c4c330ae 100644 --- a/src/main/java/baritone/utils/BlockStateInterface.java +++ b/src/main/java/baritone/utils/BlockStateInterface.java @@ -33,6 +33,9 @@ import net.minecraft.world.World; import net.minecraft.world.chunk.Chunk; import net.minecraft.world.chunk.ChunkSection; import net.minecraft.world.chunk.ChunkStatus; +import org.hydev.hyritone.Hyritone; + +import static org.hydev.hyritone.utils.MiscUtils.posId; /** * Wraps get for chuck caching capability @@ -103,6 +106,16 @@ public class BlockStateInterface { return AIR; } + // Hyritone: Replace the block with seed block + if (Baritone.settings().mineWithSeed.value) + { + String key = posId(new BlockPos(x, y, z)); + if (Hyritone.seedServerCache.blocksMap.containsKey(key)) + { + return Hyritone.seedServerCache.blocksMap.get(key); + } + } + if (useTheRealWorld) { Chunk cached = prev; // there's great cache locality in block state lookups diff --git a/src/main/java/baritone/utils/PathRenderer.java b/src/main/java/baritone/utils/PathRenderer.java index 48fc21b6..d0d9f4db 100644 --- a/src/main/java/baritone/utils/PathRenderer.java +++ b/src/main/java/baritone/utils/PathRenderer.java @@ -34,7 +34,6 @@ import net.minecraft.entity.Entity; import net.minecraft.util.ResourceLocation; import net.minecraft.util.math.AxisAlignedBB; import net.minecraft.util.math.BlockPos; -import net.minecraft.util.math.MathHelper; import net.minecraft.util.math.shapes.VoxelShape; import net.minecraft.util.math.shapes.VoxelShapes; @@ -220,7 +219,7 @@ public final class PathRenderer implements IRenderer, Helper { double minZ, maxZ; double minY, maxY; double y1, y2; - double y = MathHelper.cos((float) (((float) ((System.nanoTime() / 100000L) % 20000L)) / 20000F * Math.PI * 2)); + double y = 1; if (goal instanceof IGoalRenderPos) { BlockPos goalPos = ((IGoalRenderPos) goal).getGoalPos(); minX = goalPos.getX() + 0.002 - renderPosX; diff --git a/src/main/java/baritone/utils/accessor/IMouse.java b/src/main/java/baritone/utils/accessor/IMouse.java new file mode 100644 index 00000000..3e95b8ce --- /dev/null +++ b/src/main/java/baritone/utils/accessor/IMouse.java @@ -0,0 +1,39 @@ +/* + * This file is part of Baritone. + * + * Baritone is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Baritone is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Baritone. If not, see . + */ + +package baritone.utils.accessor; + +/** + * Duck interface for the mixin that controls mouse operations. + *

+ * Class created by the HyDEV Team on 2020-02-21! + * + * @author HyDEV Team (https://github.com/HyDevelop) + * @author Hykilpikonna (https://github.com/hykilpikonna) + * @author Vanilla (https://github.com/VergeDX) + * @since 2020-02-21 13:53 + */ +public interface IMouse +{ + void rightClick(); + void rightHold(); + void rightRelease(); + + void leftClick(); + void leftHold(); + void leftRelease(); +} diff --git a/src/main/java/org/hydev/hyritone/Hyritone.java b/src/main/java/org/hydev/hyritone/Hyritone.java new file mode 100644 index 00000000..e4e6b1c9 --- /dev/null +++ b/src/main/java/org/hydev/hyritone/Hyritone.java @@ -0,0 +1,44 @@ +/* + * This file is part of Baritone. + * + * Baritone is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Baritone is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Baritone. If not, see . + */ + +package org.hydev.hyritone; + +import baritone.Baritone; +import org.hydev.hyritone.seedxray.SeedServerCache; +import org.hydev.hyritone.task.TaskManager; + +/** + * TODO: Write a description for this class! + *

+ * Class created by the HyDEV Team on 2020-02-19! + * + * @author HyDEV Team (https://github.com/HyDevelop) + * @author Hykilpikonna (https://github.com/hykilpikonna) + * @author Vanilla (https://github.com/VergeDX) + * @since 2020-02-19 13:42 + */ +public class Hyritone +{ + public static SeedServerCache seedServerCache; + public static TaskManager taskManager; + + public Hyritone(Baritone baritone) + { + seedServerCache = new SeedServerCache(baritone); + taskManager = new TaskManager(); + } +} diff --git a/src/main/java/org/hydev/hyritone/seedxray/SeedServerCache.java b/src/main/java/org/hydev/hyritone/seedxray/SeedServerCache.java new file mode 100644 index 00000000..b2a36aae --- /dev/null +++ b/src/main/java/org/hydev/hyritone/seedxray/SeedServerCache.java @@ -0,0 +1,198 @@ +/* + * This file is part of Baritone. + * + * Baritone is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Baritone is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Baritone. If not, see . + */ + +package org.hydev.hyritone.seedxray; + +import baritone.Baritone; +import baritone.api.event.events.RenderEvent; +import baritone.api.event.events.TickEvent; +import baritone.api.utils.BetterBlockPos; +import baritone.api.utils.Helper; +import baritone.behavior.Behavior; +import baritone.utils.PathRenderer; +import com.google.gson.JsonArray; +import com.google.gson.JsonObject; +import com.google.gson.JsonParser; +import net.minecraft.block.BlockState; +import net.minecraft.block.Blocks; +import net.minecraft.util.math.BlockPos; +import org.apache.commons.io.IOUtils; +import org.apache.http.client.methods.CloseableHttpResponse; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.impl.client.CloseableHttpClient; +import org.apache.http.impl.client.HttpClients; + +import java.awt.*; +import java.io.IOException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import static baritone.api.utils.Helper.mc; +import static java.nio.charset.StandardCharsets.UTF_8; +import static java.util.stream.Collectors.toList; +import static org.hydev.hyritone.utils.MiscUtils.debug; +import static org.hydev.hyritone.utils.MiscUtils.posId; + +/** + * TODO: Write a description for this class! + *

+ * Class created by the HyDEV Team on 2020-02-19! + * + * @author HyDEV Team (https://github.com/HyDevelop) + * @author Hykilpikonna (https://github.com/hykilpikonna) + * @author Vanilla (https://github.com/VergeDX) + * @since 2020-02-19 12:35 + */ +public class SeedServerCache extends Behavior +{ + public static CloseableHttpClient http = HttpClients.createDefault(); + + public BetterBlockPos cacheLocation; + public List cacheBlocks = new ArrayList<>(); + public Map blocksMap = new HashMap<>(); + + public boolean enabled = false; + public boolean updating = false; + + // Properties + public SeedXrayProperties properties = SeedXrayProperties.DIAMOND; + public int max = 64; + + public int ticks = 100; + + public SeedServerCache(Baritone baritone) + { + super(baritone); + } + + /** + * Check for updates every tick + * + * @param event Tick event + */ + @Override + public void onTick(TickEvent event) + { + if (mc.player == null) return; + if (updating || !enabled) return; + + // Update cache every 5 seconds (5 * 20 = 100 ticks) + ticks ++; + + if (ticks > 100) + { + ticks = 0; + new Thread(this::updateCache).start(); + } + } + + /** + * Update cached blocks + */ + public void updateCache() + { + // Prevent duplicate calls to update + updating = true; + + cacheLocation = new BetterBlockPos(mc.player.getPositionVec().x, mc.player.getPositionVec().y + 0.1251, mc.player.getPositionVec().z); + + // Get request + HttpGet get = new HttpGet("http://localhost:12255/api/get-locations-of"); + get.setHeader("world", "world"); + get.setHeader("block", properties.blockToFind); + get.setHeader("maximum", "" + max); + get.setHeader("center-x", "" + cacheLocation.getX()); + get.setHeader("center-y", "" + cacheLocation.getY()); + get.setHeader("center-z", "" + cacheLocation.getZ()); + get.setHeader("max-search-rad", "64"); + get.setHeader("y-min", "" + properties.yMin); + get.setHeader("y-max", "" + properties.yMax); + + debug("=============================================="); + debug("Getting block data from seed exploit server..."); + + try (CloseableHttpResponse response = http.execute(get)) + { + // Exited + if (mc.world == null) return; + + ArrayList blocks = new ArrayList<>(); + JsonArray array = new JsonParser().parse(IOUtils.toString(response.getEntity().getContent(), UTF_8)).getAsJsonArray(); + array.forEach(j -> + { + JsonObject obj = j.getAsJsonObject(); + blocks.add(new BlockPos(obj.get("x").getAsInt(), obj.get("y").getAsInt(), obj.get("z").getAsInt())); + }); + + // Only add it if it is not air in the client world + cacheBlocks = blocks.stream().filter(b -> !mc.world.getBlockState(b).isAir()).collect(toList()); + + // Update blocks map + Map map = new HashMap<>(); + cacheBlocks.forEach(b -> map.put(posId(b), Blocks.DIAMOND_ORE.getDefaultState())); + blocksMap = map; + + debug("Found " + cacheBlocks.size() + " valid ores."); + } + catch (IOException e) + { + e.printStackTrace(); + } + + updating = false; + } + + @Override + public void onRenderPass(RenderEvent event) + { + if (!enabled) return; + + // Render xray + PathRenderer.drawManySelectionBoxes(Helper.mc.getRenderViewEntity(), cacheBlocks, Color.cyan); + } + + @Override + public void onBlockBreak(BlockPos pos) + { + // Remove block from list + if (!cacheBlocks.removeIf(b -> posId(b).equals(posId(pos)))) return; + + // Remove block from map + blocksMap.remove(posId(pos)); + + // Remove block from server + HttpGet get = new HttpGet("http://localhost:12255/api/remove-block"); + get.setHeader("world", "world"); + get.setHeader("x", "" + pos.getX()); + get.setHeader("y", "" + pos.getY()); + get.setHeader("z", "" + pos.getZ()); + + new Thread(() -> + { + try (CloseableHttpResponse response = http.execute(get)) + { + System.out.println(IOUtils.toString(response.getEntity().getContent(), UTF_8)); + } + catch (IOException e) + { + e.printStackTrace(); + } + }).start(); + } +} diff --git a/src/main/java/org/hydev/hyritone/seedxray/SeedXrayCommand.java b/src/main/java/org/hydev/hyritone/seedxray/SeedXrayCommand.java new file mode 100644 index 00000000..51279bb7 --- /dev/null +++ b/src/main/java/org/hydev/hyritone/seedxray/SeedXrayCommand.java @@ -0,0 +1,107 @@ +/* + * This file is part of Baritone. + * + * Baritone is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Baritone is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Baritone. If not, see . + */ + +package org.hydev.hyritone.seedxray; + +import baritone.Baritone; +import baritone.api.IBaritone; +import baritone.api.command.Command; +import baritone.api.command.argument.IArgConsumer; +import baritone.api.command.exception.CommandException; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.stream.Stream; + +import static org.hydev.hyritone.Hyritone.seedServerCache; +import static org.hydev.hyritone.utils.MiscUtils.print; + +/** + * TODO: Write a description for this class! + *

+ * Class created by the HyDEV Team on 2020-02-19! + * + * @author HyDEV Team (https://github.com/HyDevelop) + * @author Hykilpikonna (https://github.com/hykilpikonna) + * @author Vanilla (https://github.com/VergeDX) + * @since 2020-02-19 12:29 + */ +public class SeedXrayCommand extends Command +{ + public SeedXrayCommand(IBaritone baritone) { + super(baritone, "seedxray"); + } + + @Override + public void execute(String label, IArgConsumer args) throws CommandException + { + if (Baritone.settings().mineWithSeed.value = seedServerCache.enabled = !seedServerCache.enabled) + { + // Set args + args.requireMin(1); + args.requireMax(2); + + // Ore + if (!args.hasAny()) return; + String ore = args.getString(); + SeedXrayProperties properties = SeedXrayProperties.byName(ore); + seedServerCache.properties = properties; + + // Max + if (args.hasAny()) + { + seedServerCache.max = args.getAs(Integer.class); + } + + print("Seed xray enabled"); + } + else + { + // Reset status + seedServerCache.ticks = 100; + seedServerCache.blocksMap = new HashMap<>(); + seedServerCache.cacheLocation = null; + seedServerCache.cacheBlocks = new ArrayList<>(); + seedServerCache.updating = false; + seedServerCache.max = 64; + + print("Seed xray disabled"); + } + } + + @Override + public Stream tabComplete(String label, IArgConsumer args) { + return Stream.empty(); + } + + @Override + public String getShortDesc() { + return "Hyritone: Find ores from the seed server"; + } + + @Override + public List getLongDesc() { + return Arrays.asList( + "This function draws ESP boxes around the ores that exists in the seed server that are not mined.", + "", + "Usage:", + "> seedxray (max)" + ); + } +} diff --git a/src/main/java/org/hydev/hyritone/seedxray/SeedXrayProperties.java b/src/main/java/org/hydev/hyritone/seedxray/SeedXrayProperties.java new file mode 100644 index 00000000..93064990 --- /dev/null +++ b/src/main/java/org/hydev/hyritone/seedxray/SeedXrayProperties.java @@ -0,0 +1,62 @@ +/* + * This file is part of Baritone. + * + * Baritone is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Baritone is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Baritone. If not, see . + */ + +package org.hydev.hyritone.seedxray; + +import lombok.AllArgsConstructor; + +/** + * TODO: Write a description for this class! + *

+ * Class created by the HyDEV Team on 2020-02-23! + * + * @author HyDEV Team (https://github.com/HyDevelop) + * @author Hykilpikonna (https://github.com/hykilpikonna) + * @author Vanilla (https://github.com/VergeDX) + * @since 2020-02-23 11:32 + */ +@AllArgsConstructor +public enum SeedXrayProperties +{ + DIAMOND("diamond", "diamond_ore", 3, 16), + IRON("iron", "iron_ore", 20, 60), + REDSTONE("redstone", "redstone_ore", 3, 16), + LAPIS("lapis", "lapis_lazuri_ore", 5, 30), + GOLD("gold", "gold_ore", 5, 30), + GOLD_BADLANDS("gold_badlands", "gold_ore", 32, 70), + EMERALD("emerald", "emerald_ore", 5, 30); + + public String name; + public String blockToFind; + public int yMin; + public int yMax; + + public static SeedXrayProperties byName(String name) + { + name = name.toLowerCase().replace("-", "_"); + + for (SeedXrayProperties value : SeedXrayProperties.values()) + { + if (value.name.equals(name) || value.blockToFind.equals(name)) + { + return value; + } + } + + return null; + } +} diff --git a/src/main/java/org/hydev/hyritone/task/Task.java b/src/main/java/org/hydev/hyritone/task/Task.java new file mode 100644 index 00000000..c19982a6 --- /dev/null +++ b/src/main/java/org/hydev/hyritone/task/Task.java @@ -0,0 +1,27 @@ +package org.hydev.hyritone.task; + +/** + * A task waiting to be executed. + *

+ * Class created by the HyDEV Team on 2020-01-24! + * + * @author HyDEV Team (https://github.com/HyDevelop) + * @author Hykilpikonna (https://github.com/hykilpikonna) + * @author Vanilla (https://github.com/VergeDX) + * @since 2020-01-24 18:06 + */ +public interface Task +{ + /** + * Execute the task + */ + void execute(TaskRunState state); + + /** + * Stop the task + */ + default void stop() + { + // Default nothing to do + } +} diff --git a/src/main/java/org/hydev/hyritone/task/TaskCommand.java b/src/main/java/org/hydev/hyritone/task/TaskCommand.java new file mode 100644 index 00000000..dd8ddf7d --- /dev/null +++ b/src/main/java/org/hydev/hyritone/task/TaskCommand.java @@ -0,0 +1,82 @@ +/* + * This file is part of Baritone. + * + * Baritone is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Baritone is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Baritone. If not, see . + */ + +package org.hydev.hyritone.task; + +import baritone.api.IBaritone; +import baritone.api.command.Command; +import baritone.api.command.argument.IArgConsumer; +import baritone.api.command.exception.CommandException; +import org.hydev.hyritone.Hyritone; + +import java.util.Arrays; +import java.util.List; +import java.util.stream.Stream; + +/** + * TODO: Write a description for this class! + *

+ * Class created by the HyDEV Team on 2020-02-21! + * + * @author HyDEV Team (https://github.com/HyDevelop) + * @author Hykilpikonna (https://github.com/hykilpikonna) + * @author Vanilla (https://github.com/VergeDX) + * @since 2020-02-21 19:47 + */ +public class TaskCommand extends Command +{ + /** + * Creates a new Baritone control command. + * + * @param baritone + * @param names The names of this command. This is what you put after the command prefix. + */ + public TaskCommand(IBaritone baritone, String... names) + { + super(baritone, "task"); + } + + @Override + public void execute(String label, IArgConsumer args) throws CommandException + { + if (Hyritone.taskManager.getRunState() != null) Hyritone.taskManager.stop(); + else Hyritone.taskManager.run(TaskPresets.presets.get("AutoEmeralds")); + } + + @Override + public Stream tabComplete(String label, IArgConsumer args) throws CommandException + { + return Stream.empty(); + } + + @Override + public String getShortDesc() + { + return "Manage tasks"; + } + + @Override + public List getLongDesc() + { + return Arrays.asList( + "Manage tasks.", + "", + "Usage:", + "> task " + ); + } +} diff --git a/src/main/java/org/hydev/hyritone/task/TaskList.java b/src/main/java/org/hydev/hyritone/task/TaskList.java new file mode 100644 index 00000000..e37122ef --- /dev/null +++ b/src/main/java/org/hydev/hyritone/task/TaskList.java @@ -0,0 +1,28 @@ +package org.hydev.hyritone.task; + +import lombok.AllArgsConstructor; + +import java.util.ArrayList; +import java.util.Collections; + +/** + * Instances of this class contains lists of tasks to be executed in order. + *

+ * Class created by the HyDEV Team on 2020-01-24! + * + * @author HyDEV Team (https://github.com/HyDevelop) + * @author Hykilpikonna (https://github.com/hykilpikonna) + * @author Vanilla (https://github.com/VergeDX) + * @since 2020-01-24 18:05 + */ +@AllArgsConstructor +public class TaskList extends ArrayList +{ + public final String name; + + public TaskList(String name, Task... tasks) + { + this(name); + Collections.addAll(this, tasks); + } +} diff --git a/src/main/java/org/hydev/hyritone/task/TaskManager.java b/src/main/java/org/hydev/hyritone/task/TaskManager.java new file mode 100644 index 00000000..abf39386 --- /dev/null +++ b/src/main/java/org/hydev/hyritone/task/TaskManager.java @@ -0,0 +1,96 @@ +package org.hydev.hyritone.task; + +import lombok.Getter; + +import static org.hydev.hyritone.utils.MiscUtils.debug; + +/** + * This class is used to manage tasks. + *

+ * Class created by the HyDEV Team on 2020-01-24! + * + * @author HyDEV Team (https://github.com/HyDevelop) + * @author Hykilpikonna (https://github.com/hykilpikonna) + * @author Vanilla (https://github.com/VergeDX) + * @since 2020-01-24 19:03 + */ +@Getter +public class TaskManager +{ + private TaskRunState runState = null; + + /** + * Run a task list + * + * @param list Task list + * @return Successfully started or not + */ + public boolean run(TaskList list) + { + // Check already started + if (runState != null) + { + stop(); + } + + // Reset values + runState = new TaskRunState(null, list, 0); + + /* // Execute task + Baritone.getExecutor().execute(() -> + { + // Execute step by step + while (runState.step < list.size()) + { + list.get(runState.step).execute(runState); + runState.step++; + } + + // Finished + stop(); + });*/ + + // Create thread + runState.thread = new Thread(() -> + { + // Execute step by step + while (runState.step < list.size()) + { + debug("Running step " + runState); + list.get(runState.step).execute(runState); + runState.step++; + } + + // Finished + stop(); + }, "Hyritone Task"); + + // Start async + runState.thread.start(); + + // Success + return true; + } + + /** + * Stop the task list + */ + public void stop() + { + // Not started + if (runState == null) return; + + // Stop thread + runState.thread.interrupt(); + + // Stop task + if (runState.getStep() < runState.getTaskList().size()) + { + runState.getTaskList().get(runState.getStep()).stop(); + } + + runState = null; + } + + // TODO: pause +} diff --git a/src/main/java/org/hydev/hyritone/task/TaskPresets.java b/src/main/java/org/hydev/hyritone/task/TaskPresets.java new file mode 100644 index 00000000..ae48888c --- /dev/null +++ b/src/main/java/org/hydev/hyritone/task/TaskPresets.java @@ -0,0 +1,95 @@ +package org.hydev.hyritone.task; + +import com.google.gson.Gson; +import lombok.SneakyThrows; +import org.apache.commons.io.FileUtils; + +import java.io.File; +import java.io.IOException; +import java.io.UncheckedIOException; +import java.nio.charset.StandardCharsets; +import java.nio.file.FileVisitOption; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.HashMap; +import java.util.Map; + +import static baritone.api.utils.Helper.mc; + +/** + * This class contains preset tasks + * TODO: Make a UI for task list! + *

+ * Class created by the HyDEV Team on 2020-01-24! + * + * @author HyDEV Team (https://github.com/HyDevelop) + * @author Hykilpikonna (https://github.com/hykilpikonna) + * @author Vanilla (https://github.com/VergeDX) + * @since 2020-01-24 18:23 + */ +public class TaskPresets +{ + // Map + public static Map presets = new HashMap<>(); + + /** + * Register a task list + * + * @param list Task list + */ + public static void register(TaskList list) + { + presets.put(list.name.toLowerCase(), list); + } + + /** + * Get preset by name + * + * @param name Lowercase name + * @return Task list by name, null if not found + */ + public static TaskList getPreset(String name) + { + if (presets.containsKey(name.toLowerCase())) + { + return presets.get(name.toLowerCase()); + } + return null; + } + + /** + * Load presets from file + */ + @SneakyThrows + public static void reloadPresets() + { + Path filePath = new File(mc.gameDir, "./Hyritone/").toPath(); + Files.createDirectories(filePath); + + presets.clear(); + + try + { + Files.walk(filePath, FileVisitOption.FOLLOW_LINKS) + .filter(Files::isRegularFile) + .forEach(path -> + { + try + { + String json = FileUtils.readFileToString(path.toFile(), StandardCharsets.UTF_8); + TaskList list = new Gson().fromJson(json, TaskList.class); + presets.put(list.name.toLowerCase(), list); + } + catch (IOException e) + { + throw new UncheckedIOException(e); + } + }); + } + catch (IOException | UncheckedIOException e) + { + System.err.println("Error when loading org.hydev.hyritone json."); + e.printStackTrace(); + } + } +} diff --git a/src/main/java/org/hydev/hyritone/task/TaskRunState.java b/src/main/java/org/hydev/hyritone/task/TaskRunState.java new file mode 100644 index 00000000..390a2c0e --- /dev/null +++ b/src/main/java/org/hydev/hyritone/task/TaskRunState.java @@ -0,0 +1,30 @@ +package org.hydev.hyritone.task; + +import lombok.AllArgsConstructor; +import lombok.Data; + +/** + * TODO: Write a description for this class! + *

+ * Class created by the HyDEV Team on 2020-01-24! + * + * @author HyDEV Team (https://github.com/HyDevelop) + * @author Hykilpikonna (https://github.com/hykilpikonna) + * @author Vanilla (https://github.com/VergeDX) + * @since 2020-01-24 20:38 + */ +@Data +@AllArgsConstructor +public class TaskRunState +{ + public Thread thread; + public TaskList taskList; + public int step; + + @Override + public String toString() + { + return "Task " + thread.getId() + " is executing step " + step + " of " + taskList.size() + " " + + "| Current Task: " + taskList.get(step).getClass().getSimpleName(); + } +} diff --git a/src/main/java/org/hydev/hyritone/task/TaskTestCommand.java b/src/main/java/org/hydev/hyritone/task/TaskTestCommand.java new file mode 100644 index 00000000..2194249e --- /dev/null +++ b/src/main/java/org/hydev/hyritone/task/TaskTestCommand.java @@ -0,0 +1,174 @@ +/* + * This file is part of Baritone. + * + * Baritone is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Baritone is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Baritone. If not, see . + */ + +package org.hydev.hyritone.task; + +import baritone.api.IBaritone; +import baritone.api.command.Command; +import baritone.api.command.argument.IArgConsumer; +import baritone.api.command.exception.CommandException; +import baritone.api.utils.Rotation; +import net.minecraft.inventory.container.ChestContainer; +import net.minecraft.inventory.container.MerchantContainer; +import org.hydev.hyritone.task.defaults.*; +import org.hydev.hyritone.utils.PlayerUtils; + +import java.util.Arrays; +import java.util.Collections; +import java.util.HashSet; +import java.util.List; +import java.util.stream.Stream; + +import static java.lang.Long.MAX_VALUE; +import static net.minecraft.inventory.container.ClickType.*; +import static net.minecraft.item.Items.BOOK; +import static net.minecraft.item.Items.BOOKSHELF; +import static org.hydev.hyritone.utils.PlayerUtils.*; + +/** + * TODO: Write a description for this class! + *

+ * Class created by the HyDEV Team on 2020-02-21! + * + * @author HyDEV Team (https://github.com/HyDevelop) + * @author Hykilpikonna (https://github.com/hykilpikonna) + * @author Vanilla (https://github.com/VergeDX) + * @since 2020-02-21 19:48 + */ +public class TaskTestCommand extends Command +{ + /** + * Creates a new Baritone control command. + * + * @param baritone + * @param names The names of this command. This is what you put after the command prefix. + */ + public TaskTestCommand(IBaritone baritone, String... names) + { + super(baritone, "tasktest"); + } + + @Override + public void execute(String label, IArgConsumer args) throws CommandException + { + TaskList test = new TaskList("AutoEmeralds", + // 等待时间在 2000 (8:00) 和 9000 (15:00) 之间w + new TaskWaitFor(s -> ticks() > 2000 && ticks() < 9000).timeout(MAX_VALUE), + + // 转向村民 + s -> PlayerUtils.rotate(new Rotation(-90, 0)), // 转向村民w + new TaskDelay(10), // 等w + + // 打开村民交易w + s -> mouse().rightClick(), // 点击村民w + new TaskWaitFor(s -> player().openContainer instanceof MerchantContainer) // 等点击完成w + .onTimeout(new TaskReplayRelative(1)), // 如果失败就重来w + + // 和村民交易w (绿宝石 -> 书架) + s -> controller().windowClick(containerId(), 36, 0, PICKUP, player()), // 拿起绿宝石w + new TaskDelay(1000), // 等w + s -> controller().windowClick(containerId(), 0, 0, PICKUP, player()), // 把书放到交易框w + new TaskDelay(1000), // 等w + s -> controller().windowClick(containerId(), 2, 0, QUICK_MOVE, player()), // 把书架移到 8 + new TaskDelay(1000), // 等w + s -> player().closeScreen(), // 关掉界面w + + // 把书架转换回书w + s -> PlayerUtils.rotate(new Rotation(90, 0)), // 转到后面面向黑曜石w + s -> player().inventory.currentItem = 8, // 选择 1: 书架w + s -> mouse().rightClick(), // 放书架w + new TaskDelay(1000), // 等w + s -> player().inventory.currentItem = 0, // 选择 0: 斧子w + s -> PlayerUtils.dig(getLookingAtBlock()), // 挖掉w + new TaskDelay(1000), // 等w + new TaskCondition(s -> !player().inventory.hasAny(new HashSet<>(Collections.singletonList(BOOKSHELF)))) + .taskElse(new TaskReplayRelative(5 + 2)), // 如果没有书架了就继续, 有的话就回到 5 步之前w + + // 转向村民 + s -> PlayerUtils.rotate(new Rotation(-90, 0)), // 转向村民w + new TaskDelay(10), // 等w + + // 打开村民交易w + s -> mouse().rightClick(), // 点击村民w + new TaskWaitFor(s -> player().openContainer instanceof MerchantContainer) // 等点击完成w + .onTimeout(new TaskReplayRelative(1)), // 如果失败就重来w + + // 和村民交易w (书 -> 绿宝石) + s -> controller().windowClick(containerId(), 31, 0, PICKUP, player()), // 拿起书 + s -> controller().windowClick(containerId(), 0, 0, PICKUP, player()), // 把书放到交易框w + new TaskDelay(1000), // 等w + s -> controller().windowClick(containerId(), 2, 0, QUICK_MOVE, player()), // 把绿宝石移到 8 + new TaskDelay(1000), // 等w + s -> controller().windowClick(containerId(), 0, 0, PICKUP, player()), // 拿起剩下的书 + s -> controller().windowClick(containerId(), 31, 0, PICKUP, player()), // 在 1 放下书 + new TaskDelay(1000), // 等w + s -> player().closeScreen(), // 关掉界面w + new TaskDelay(5000), // 等村民补充w + new TaskCondition(s -> player().inventory.hasAny(new HashSet<>(Collections.singletonList(BOOK)))) + .taskElse(new TaskReplayRelative(9 + 3)), // 如果没有书了就继续, 有的话就回到 10 步之前w + + // 转向箱子w + s -> PlayerUtils.rotate(new Rotation(180, 0)), // 转向箱子w + new TaskDelay(10), // 等w + + // 打开箱子w + s -> mouse().rightClick(), // 点击箱子w + new TaskWaitFor(s -> player().openContainer instanceof ChestContainer) // 等点击完成w + .onTimeout(new TaskReplayRelative(1)), // 如果失败就重来w + + // 把多余的绿宝石放到箱子里w + s -> controller().windowClick(containerId(), 89, 0, PICKUP, player()), // 拿起 36 个绿宝石w + s -> controller().windowClick(containerId(), -999, 0, QUICK_CRAFT, player()), // 开始快速合成w + s -> controller().windowClick(containerId(), 89, 1, QUICK_CRAFT, player()), // 在 8 放 1/3 + s -> controller().windowClick(containerId(), 88, 1, QUICK_CRAFT, player()), // 在 7 放 1/3 + s -> controller().windowClick(containerId(), 87, 1, QUICK_CRAFT, player()), // 在 6 放 1/3 + s -> controller().windowClick(containerId(), -999, 2, QUICK_CRAFT, player()), // 结束快速合成w + s -> controller().windowClick(containerId(), 88, 0, QUICK_MOVE, player()), // 把 7 的绿宝石移到箱子里w + s -> controller().windowClick(containerId(), 89, 0, QUICK_MOVE, player()), // 把 8 的绿宝石移到箱子里w + s -> player().closeScreen(), // 关闭箱子w + + // 从头开始w + new TaskReplay(0) + ); + + TaskPresets.presets.clear(); + TaskPresets.presets.put("AutoEmeralds", test); + } + + @Override + public Stream tabComplete(String label, IArgConsumer args) throws CommandException + { + return Stream.empty(); + } + + @Override + public String getShortDesc() + { + return "Add testing task"; + } + + @Override + public List getLongDesc() + { + return Arrays.asList( + "Add testing task.", + "", + "Usage:", + "> tasktest " + ); + } +} diff --git a/src/main/java/org/hydev/hyritone/task/defaults/TaskCondition.java b/src/main/java/org/hydev/hyritone/task/defaults/TaskCondition.java new file mode 100644 index 00000000..7caad579 --- /dev/null +++ b/src/main/java/org/hydev/hyritone/task/defaults/TaskCondition.java @@ -0,0 +1,47 @@ +package org.hydev.hyritone.task.defaults; + +import lombok.AllArgsConstructor; +import lombok.RequiredArgsConstructor; +import lombok.Setter; +import lombok.experimental.Accessors; +import org.hydev.hyritone.task.Task; +import org.hydev.hyritone.task.TaskRunState; + +import java.util.function.Function; + +/** + * Run task if condition is met + *

+ * Class created by the HyDEV Team on 2020-01-25! + * + * @author HyDEV Team (https://github.com/HyDevelop) + * @author Hykilpikonna (https://github.com/hykilpikonna) + * @author Vanilla (https://github.com/VergeDX) + * o@since 2020-01-25 17:44 + */ +@Setter +@Accessors(fluent = true) +@AllArgsConstructor +@RequiredArgsConstructor +public class TaskCondition implements Task +{ + private final Function condition; + private Task taskThen; + private Task taskElse; + + @Override + public void execute(TaskRunState state) + { + if (condition.apply(state)) + { + if (taskThen != null) + { + taskThen.execute(state); + } + } + else if (taskElse != null) + { + taskElse.execute(state); + } + } +} diff --git a/src/main/java/org/hydev/hyritone/task/defaults/TaskDelay.java b/src/main/java/org/hydev/hyritone/task/defaults/TaskDelay.java new file mode 100644 index 00000000..73e84311 --- /dev/null +++ b/src/main/java/org/hydev/hyritone/task/defaults/TaskDelay.java @@ -0,0 +1,31 @@ +package org.hydev.hyritone.task.defaults; + +import lombok.AllArgsConstructor; +import org.hydev.hyritone.task.Task; +import org.hydev.hyritone.task.TaskRunState; + +/** + * Task to delay for some seconds + *

+ * Class created by the HyDEV Team on 2020-01-24! + * + * @author HyDEV Team (https://github.com/HyDevelop) + * @author Hykilpikonna (https://github.com/hykilpikonna) + * @author Vanilla (https://github.com/VergeDX) + * @since 2020-01-24 18:21 + */ +@AllArgsConstructor +public class TaskDelay implements Task +{ + private final long delay; + + @Override + public void execute(TaskRunState state) + { + try + { + Thread.sleep(delay); + } + catch (InterruptedException ignored) {} + } +} diff --git a/src/main/java/org/hydev/hyritone/task/defaults/TaskInteract.java b/src/main/java/org/hydev/hyritone/task/defaults/TaskInteract.java new file mode 100644 index 00000000..f87d2dd8 --- /dev/null +++ b/src/main/java/org/hydev/hyritone/task/defaults/TaskInteract.java @@ -0,0 +1,31 @@ +package org.hydev.hyritone.task.defaults; + +import lombok.AllArgsConstructor; +import net.minecraft.util.math.BlockPos; +import org.hydev.hyritone.task.Task; +import org.hydev.hyritone.task.TaskRunState; +import org.hydev.hyritone.utils.PlayerUtils; + +/** + * Interact with blocks (Eg. chests) + *

+ * Class created by the HyDEV Team on 2020-01-24! + * + * @author HyDEV Team (https://github.com/HyDevelop) + * @author Hykilpikonna (https://github.com/hykilpikonna) + * @author Vanilla (https://github.com/VergeDX) + * @since 2020-01-24 23:10 + */ +@AllArgsConstructor +public class TaskInteract implements Task +{ + private final long x; + private final long y; + private final long z; + + @Override + public void execute(TaskRunState state) + { + PlayerUtils.interact(new BlockPos(x, y, z)); + } +} diff --git a/src/main/java/org/hydev/hyritone/task/defaults/TaskReplay.java b/src/main/java/org/hydev/hyritone/task/defaults/TaskReplay.java new file mode 100644 index 00000000..1895c486 --- /dev/null +++ b/src/main/java/org/hydev/hyritone/task/defaults/TaskReplay.java @@ -0,0 +1,27 @@ +package org.hydev.hyritone.task.defaults; + +import lombok.AllArgsConstructor; +import org.hydev.hyritone.task.Task; +import org.hydev.hyritone.task.TaskRunState; + +/** + * Replay from some index + *

+ * Class created by the HyDEV Team on 2020-01-24! + * + * @author HyDEV Team (https://github.com/HyDevelop) + * @author Hykilpikonna (https://github.com/hykilpikonna) + * @author Vanilla (https://github.com/VergeDX) + * @since 2020-01-24 20:37 + */ +@AllArgsConstructor +public class TaskReplay implements Task +{ + private final int step; + + @Override + public void execute(TaskRunState state) + { + state.step = step - 1; + } +} diff --git a/src/main/java/org/hydev/hyritone/task/defaults/TaskReplayRelative.java b/src/main/java/org/hydev/hyritone/task/defaults/TaskReplayRelative.java new file mode 100644 index 00000000..3b01a457 --- /dev/null +++ b/src/main/java/org/hydev/hyritone/task/defaults/TaskReplayRelative.java @@ -0,0 +1,27 @@ +package org.hydev.hyritone.task.defaults; + +import lombok.AllArgsConstructor; +import org.hydev.hyritone.task.Task; +import org.hydev.hyritone.task.TaskRunState; + +/** + * Replay from some index + *

+ * Class created by the HyDEV Team on 2020-01-24! + * + * @author HyDEV Team (https://github.com/HyDevelop) + * @author Hykilpikonna (https://github.com/hykilpikonna) + * @author Vanilla (https://github.com/VergeDX) + * @since 2020-01-24 20:37 + */ +@AllArgsConstructor +public class TaskReplayRelative implements Task +{ + private final int stepOffset; + + @Override + public void execute(TaskRunState state) + { + state.step -= stepOffset + 1; + } +} diff --git a/src/main/java/org/hydev/hyritone/task/defaults/TaskWaitFor.java b/src/main/java/org/hydev/hyritone/task/defaults/TaskWaitFor.java new file mode 100644 index 00000000..f7c22a0b --- /dev/null +++ b/src/main/java/org/hydev/hyritone/task/defaults/TaskWaitFor.java @@ -0,0 +1,58 @@ +package org.hydev.hyritone.task.defaults; + +import lombok.AllArgsConstructor; +import lombok.RequiredArgsConstructor; +import lombok.Setter; +import lombok.experimental.Accessors; +import org.hydev.hyritone.task.Task; +import org.hydev.hyritone.task.TaskRunState; + +import java.util.function.Function; + +import static org.hydev.hyritone.utils.MiscUtils.sleep; + +/** + * Wait for a condition to complete + *

+ * Class created by the HyDEV Team on 2020-01-25! + * + * @author HyDEV Team (https://github.com/HyDevelop) + * @author Hykilpikonna (https://github.com/hykilpikonna) + * @author Vanilla (https://github.com/VergeDX) + * @since 2020-01-25 12:29 + */ +@Accessors(fluent = true) +@Setter +@AllArgsConstructor +@RequiredArgsConstructor +public class TaskWaitFor implements Task +{ + private final Function condition; + private Task onTimeout; + private long timeout = 10 * 60 * 1000; + private long interval = 100; + + @Override + public void execute(TaskRunState state) + { + // Timeout detection + long startTime = System.currentTimeMillis(); + + // Run + while (true) + { + if (condition.apply(state)) return; + sleep(interval); + + if (System.currentTimeMillis() - startTime > timeout) + { + // Timeout callback + if (onTimeout != null) + { + onTimeout.execute(state); + } + return; + } + } + } +} diff --git a/src/main/java/org/hydev/hyritone/utils/MiscUtils.java b/src/main/java/org/hydev/hyritone/utils/MiscUtils.java new file mode 100644 index 00000000..9ca56ae2 --- /dev/null +++ b/src/main/java/org/hydev/hyritone/utils/MiscUtils.java @@ -0,0 +1,77 @@ +/* + * This file is part of Baritone. + * + * Baritone is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Baritone is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Baritone. If not, see . + */ + +package org.hydev.hyritone.utils; + +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.text.StringTextComponent; + +import static baritone.api.utils.Helper.mc; + +/** + * TODO: Write a description for this class! + *

+ * Class created by the HyDEV Team on 2020-02-19! + * + * @author HyDEV Team (https://github.com/HyDevelop) + * @author Hykilpikonna (https://github.com/hykilpikonna) + * @author Vanilla (https://github.com/VergeDX) + * @since 2020-02-19 13:28 + */ +public class MiscUtils +{ + public static void print(String text) + { + if (mc.player == null) return; + + mc.player.sendMessage(new StringTextComponent("§3§l[§bHyritone§3§l] §r" + text)); + System.out.println("Log: " + text); + } + + public static void debug(String text) + { + print("§8[§7Debug§8]§7 " + text); + } + + /** + * Get an identifier for a block pos that's unique for each xyz + * + * @param pos Block position + * @return Stringify + */ + public static String posId(BlockPos pos) + { + return String.format("[%s,%s,%s]", pos.getX(), pos.getY(), pos.getZ()); + } + + /** + * Sleep without exceptions + * + * @param ms Time in ms + */ + public static void sleep(long ms) + { + try + { + Thread.sleep(ms); + } + catch (InterruptedException e) + { + e.printStackTrace(); + } + } +} diff --git a/src/main/java/org/hydev/hyritone/utils/PlayerUtils.java b/src/main/java/org/hydev/hyritone/utils/PlayerUtils.java new file mode 100644 index 00000000..0ce4de01 --- /dev/null +++ b/src/main/java/org/hydev/hyritone/utils/PlayerUtils.java @@ -0,0 +1,230 @@ +package org.hydev.hyritone.utils; + +import baritone.api.utils.Rotation; +import baritone.utils.accessor.IMouse; +import net.minecraft.block.BlockState; +import net.minecraft.client.entity.player.ClientPlayerEntity; +import net.minecraft.client.multiplayer.PlayerController; +import net.minecraft.client.world.ClientWorld; +import net.minecraft.network.play.client.CAnimateHandPacket; +import net.minecraft.util.Direction; +import net.minecraft.util.Hand; +import net.minecraft.util.math.*; + +import static baritone.api.utils.Helper.mc; +import static net.minecraft.util.math.RayTraceContext.BlockMode.OUTLINE; +import static net.minecraft.util.math.RayTraceContext.FluidMode.NONE; +import static net.minecraft.util.math.RayTraceResult.Type.BLOCK; + +/** + * Utils for controlling the player. + *

+ * Class created by the HyDEV Team on 2020-01-24! + * + * @author HyDEV Team (https://github.com/HyDevelop) + * @author Hykilpikonna (https://github.com/hykilpikonna) + * @author Vanilla (https://github.com/VergeDX) + * @since 2020-01-24 22:34 + */ +public class PlayerUtils +{ + public static ClientPlayerEntity player() { return mc.player; } + public static ClientWorld world() { return mc.world; } + public static IMouse mouse() { return (IMouse) mc.mouseHelper; } + public static PlayerController controller() { return mc.playerController; } + public static int containerId() { return player().openContainer.windowId; } + + /** + * Get player's eye vector + * + * @return Eye vector + * @author Wurst7 https://github.com/Wurst-Imperium/Wurst7 + */ + public static Vec3d getEyesPos() + { + assert player() != null; + + return new Vec3d(player().getPosX(), + player().getPosY() + player().getEyeHeight(player().getPose()), + player().getPosZ()); + } + + /** + * Get what does it take to rotate to a direction + * + * @param vec Final direction + * @return Rotation required + * @author Wurst7 https://github.com/Wurst-Imperium/Wurst7 + */ + public static Rotation getNeededRotations(Vec3d vec) + { + Vec3d eyesPos = getEyesPos(); + + double diffX = vec.x - eyesPos.x; + double diffY = vec.y - eyesPos.y; + double diffZ = vec.z - eyesPos.z; + + double diffXZ = Math.sqrt(diffX * diffX + diffZ * diffZ); + + float yaw = (float)Math.toDegrees(Math.atan2(diffZ, diffX)) - 90F; + float pitch = (float)-Math.toDegrees(Math.atan2(diffY, diffXZ)); + + return new Rotation(yaw, pitch); + } + + /** + * Rotate + * + * @param rotation Relative rotation + */ + public static void rotate(Rotation rotation) + { + player().rotationYaw = rotation.getYaw(); + player().rotationPitch = rotation.getPitch(); + } + + /** + * Rotate to face one block + * + * @param pos Block position + * @return Direction + * @author Wurst7 https://github.com/Wurst-Imperium/Wurst7 + */ + public static Direction rotateToBlock(BlockPos pos) + { + Direction side = null; + Direction[] sides = Direction.values(); + + Vec3d eyesPos = getEyesPos(); + Vec3d relCenter = world().getBlockState(pos).getShape(world(), pos).getBoundingBox().getCenter(); + Vec3d center = new Vec3d(pos).add(relCenter); + + Vec3d[] hitVecs = new Vec3d[sides.length]; + for (int i = 0; i < sides.length; i++) + { + Vec3i dirVec = sides[i].getDirectionVec(); + Vec3d relHitVec = new Vec3d(relCenter.x * dirVec.getX(), + relCenter.y * dirVec.getY(), relCenter.z * dirVec.getZ()); + hitVecs[i] = center.add(relHitVec); + } + + BlockState state = world().getBlockState(pos); + for (int i = 0; i < sides.length; i++) + { + // check line of sight + if (world().rayTraceBlocks(eyesPos, hitVecs[i], pos, state.getShape(world(), pos), state) != null) + { + continue; + } + + side = sides[i]; + break; + } + + if (side == null) + { + double distanceSqToCenter = eyesPos.squareDistanceTo(center); + for (int i = 0; i < sides.length; i++) + { + // check if side is facing towards player + if (eyesPos.squareDistanceTo(hitVecs[i]) >= distanceSqToCenter) + { + continue; + } + + side = sides[i]; + break; + } + } + + // player is inside of block, side doesn't matter + if (side == null) + { + side = sides[0]; + } + + // Rotate + rotate(getNeededRotations(hitVecs[side.ordinal()])); + + return side; + } + + public static BlockPos getLookingAtBlock() + { + Vec3d cameraPos = player().getEyePosition(1); + Vec3d rotation = player().getLook(1); + Vec3d combined = cameraPos.add(rotation.x * 5, rotation.y * 5, rotation.z * 5); + + BlockRayTraceResult result = mc.world.rayTraceBlocks(new RayTraceContext(cameraPos, combined, OUTLINE, NONE, player())); + + if (result.getType() == BLOCK) + { + return result.getPos(); + } + else return null; + } + + /** + * Interact + * + * @param pos Block + */ + public static void interact(BlockPos pos) + { + rotateToBlock(pos); + mouse().rightClick(); + } + + /** + * Dig the block at direction + * + * @param pos Block position + * @param side Direction + * @return Dig success or not + * @author Wurst7 https://github.com/Wurst-Imperium/Wurst7 + */ + public static boolean dig(BlockPos pos, Direction side) + { + // damage block + if (!controller().onPlayerDamageBlock(pos, side)) + { + return false; + } + + // swing arm + player().connection.sendPacket(new CAnimateHandPacket(Hand.MAIN_HAND)); + + return true; + } + + /** + * Dig the block at direction + * + * @param pos Block position + * @return Dig success or not + */ + public static boolean dig(BlockPos pos) + { + return dig(pos, rotateToBlock(pos)); + } + + /** + * Delay between swapping items from inv to chest. + * + * @return Delay between 80 to 120 + */ + public static int chestDelay() + { + return (int) (80 + Math.random() * 40); + } + + /** + * Return ticks of day + * + * @return Ticks of day + */ + public static long ticks() + { + return world().getDayTime() % 24000; + } +}