Compare commits
9 Commits
18d594c02c
..
main
| Author | SHA1 | Date | |
|---|---|---|---|
| 990eb72753 | |||
| 89a49e2d58 | |||
| 5c94367584 | |||
| b9869c57f2 | |||
| 6a6b92a549 | |||
| 8637b89668 | |||
| 431aae4f62 | |||
| 2fba8b6299 | |||
| 39aeecad1a |
@@ -11,20 +11,25 @@ jobs:
|
||||
runs-on: ubuntu-24.04
|
||||
steps:
|
||||
- name: checkout repository
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v4.2.2
|
||||
|
||||
- name: validate gradle wrapper
|
||||
uses: gradle/actions/wrapper-validation@v4
|
||||
uses: gradle/actions/wrapper-validation@v4.3.1
|
||||
|
||||
- name: setup jdk
|
||||
uses: actions/setup-java@v4
|
||||
uses: actions/setup-java@v4.7.1
|
||||
with:
|
||||
java-version: '25'
|
||||
distribution: 'microsoft'
|
||||
java-version: "25"
|
||||
distribution: "microsoft"
|
||||
|
||||
- name: make gradle wrapper executable
|
||||
run: chmod +x ./gradlew
|
||||
|
||||
- name: build
|
||||
run: ./gradlew build
|
||||
|
||||
- name: capture build artifacts
|
||||
uses: actions/upload-artifact@v4
|
||||
uses: actions/upload-artifact@v3.1.3
|
||||
with:
|
||||
name: Artifacts
|
||||
path: build/libs/
|
||||
|
||||
@@ -6,17 +6,20 @@ import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents;
|
||||
import net.fabricmc.fabric.api.client.keybinding.v1.KeyBindingHelper;
|
||||
import net.fabricmc.fabric.api.client.networking.v1.ClientPlayConnectionEvents;
|
||||
import net.fabricmc.fabric.api.client.rendering.v1.world.WorldRenderEvents;
|
||||
import net.fabricmc.fabric.api.event.client.player.ClientPlayerBlockBreakEvents;
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
import net.minecraft.client.option.KeyBinding;
|
||||
import net.minecraft.client.util.InputUtil;
|
||||
import net.minecraft.util.Identifier;
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
import org.lwjgl.glfw.GLFW;
|
||||
|
||||
import skybot.commands.CommandManager;
|
||||
import skybot.controller.Controller;
|
||||
import skybot.controller.task.TaskQueue;
|
||||
import skybot.farmers.Farmer;
|
||||
import skybot.task.TaskQueue;
|
||||
import skybot.utilities.ChatMenu;
|
||||
import skybot.utilities.TickScheduler;
|
||||
|
||||
public class SkybotClient implements ClientModInitializer {
|
||||
|
||||
@@ -24,16 +27,44 @@ public class SkybotClient implements ClientModInitializer {
|
||||
private static volatile Farmer activeFarmer = null;
|
||||
private static volatile boolean botEnabled = false;
|
||||
|
||||
private static long tickCount = 0;
|
||||
private static final long HEALTHCHECK_INTERVAL_TICKS = 40;
|
||||
|
||||
private static volatile long lastBreakTime = 0;
|
||||
|
||||
private static volatile long lastMoveTime = 0;
|
||||
private static Vec3d lastPosition = null;
|
||||
private static final double MOVE_EPSILON_SQUARED = 1.0;
|
||||
|
||||
private static final KeyBinding.Category GENERAL_CATEGORY = KeyBinding.Category
|
||||
.create(Identifier.of("skybot", "general"));
|
||||
|
||||
private static final KeyBinding STOP_KEY = new KeyBinding(
|
||||
"key.skybot.stop",
|
||||
InputUtil.Type.KEYSYM,
|
||||
GLFW.GLFW_KEY_CAPS_LOCK,
|
||||
KeyBinding.Category.create(Identifier.of("skybot", "general")));
|
||||
GENERAL_CATEGORY);
|
||||
|
||||
public static boolean isBotEnabled() {
|
||||
return botEnabled;
|
||||
}
|
||||
|
||||
public static long getLastBreakTime() {
|
||||
return lastBreakTime;
|
||||
}
|
||||
|
||||
public static long getLastMoveTime() {
|
||||
return lastMoveTime;
|
||||
}
|
||||
|
||||
public static String botStatus() {
|
||||
if (!botEnabled) {
|
||||
return "§cIdle";
|
||||
}
|
||||
|
||||
return "§aRunning";
|
||||
}
|
||||
|
||||
public static void stopBot() {
|
||||
activeFarmer = null;
|
||||
botEnabled = false;
|
||||
@@ -51,6 +82,9 @@ public class SkybotClient implements ClientModInitializer {
|
||||
|
||||
activeFarmer = strategy;
|
||||
botEnabled = true;
|
||||
lastBreakTime = System.currentTimeMillis();
|
||||
lastMoveTime = System.currentTimeMillis();
|
||||
lastPosition = null;
|
||||
|
||||
activeFarmer.enqueue(TASK_QUEUE);
|
||||
ChatMenu.send("§aFarmer started successfully.§r");
|
||||
@@ -60,6 +94,10 @@ public class SkybotClient implements ClientModInitializer {
|
||||
@Override
|
||||
public void onInitializeClient() {
|
||||
KeyBindingHelper.registerKeyBinding(STOP_KEY);
|
||||
TickScheduler.register();
|
||||
|
||||
ClientPlayerBlockBreakEvents.AFTER
|
||||
.register((world, player, pos, state) -> lastBreakTime = System.currentTimeMillis());
|
||||
|
||||
WorldRenderEvents.END_MAIN.register(context -> {
|
||||
MinecraftClient client = MinecraftClient.getInstance();
|
||||
@@ -80,12 +118,29 @@ public class SkybotClient implements ClientModInitializer {
|
||||
if (client.world != null && !client.isPaused()) {
|
||||
Controller.tick(client);
|
||||
|
||||
if (client.player != null) {
|
||||
Vec3d pos = client.player.getEntityPos();
|
||||
if (lastPosition == null) {
|
||||
lastPosition = pos;
|
||||
lastMoveTime = System.currentTimeMillis();
|
||||
} else if (lastPosition.squaredDistanceTo(pos) > MOVE_EPSILON_SQUARED) {
|
||||
lastMoveTime = System.currentTimeMillis();
|
||||
lastPosition = pos;
|
||||
}
|
||||
}
|
||||
|
||||
while (STOP_KEY.wasPressed()) {
|
||||
if (botEnabled) {
|
||||
ChatMenu.send("§cBot stopped via hotkey.§r");
|
||||
stopBot();
|
||||
}
|
||||
}
|
||||
|
||||
tickCount++;
|
||||
if (botEnabled && tickCount % HEALTHCHECK_INTERVAL_TICKS == 0 && !activeFarmer.healthcheck()) {
|
||||
ChatMenu.send("§cHealthcheck failed, stopping bot.§r");
|
||||
stopBot();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -7,7 +7,10 @@ import net.fabricmc.fabric.api.client.command.v2.FabricClientCommandSource;
|
||||
import net.minecraft.command.CommandRegistryAccess;
|
||||
import skybot.SkybotClient;
|
||||
import skybot.farmers.CarrotFarmer;
|
||||
import skybot.farmers.NetherwartFarmer;
|
||||
import skybot.farmers.PotatoFarmer;
|
||||
import skybot.farmers.TestFarmer;
|
||||
import skybot.farmers.WheatFarmer;
|
||||
import skybot.utilities.ChatMenu;
|
||||
|
||||
public class CommandManager {
|
||||
@@ -23,17 +26,34 @@ public class CommandManager {
|
||||
}
|
||||
return 1;
|
||||
}))
|
||||
.then(literal("carrots").executes(context -> {
|
||||
.then(literal("carrot").executes(context -> {
|
||||
if (SkybotClient.startBot(new CarrotFarmer())) {
|
||||
ChatMenu.send("§aStarting Carrot Farmer...§r");
|
||||
}
|
||||
return 1;
|
||||
}))
|
||||
.then(literal("netherwart").executes(context -> {
|
||||
if (SkybotClient.startBot(new NetherwartFarmer())) {
|
||||
ChatMenu.send("§aStarting Netherwart Farmer...§r");
|
||||
}
|
||||
return 1;
|
||||
}))
|
||||
.then(literal("wheat").executes(context -> {
|
||||
if (SkybotClient.startBot(new WheatFarmer())) {
|
||||
ChatMenu.send("§aStarting Wheat Farmer...§r");
|
||||
}
|
||||
return 1;
|
||||
}))
|
||||
.then(literal("potato").executes(context -> {
|
||||
if (SkybotClient.startBot(new PotatoFarmer())) {
|
||||
ChatMenu.send("§aStarting Potato Farmer...§r");
|
||||
}
|
||||
return 1;
|
||||
})));
|
||||
|
||||
dispatcher.register(literal("skybot")
|
||||
.then(literal("status").executes(context -> {
|
||||
String msg = SkybotClient.isBotEnabled() ? "§aRunning" : "§cIdle";
|
||||
ChatMenu.send("Status: " + msg);
|
||||
ChatMenu.send("Status: " + SkybotClient.botStatus());
|
||||
return 1;
|
||||
}))
|
||||
.then(literal("stop").executes(context -> {
|
||||
|
||||
@@ -1,54 +1,56 @@
|
||||
package skybot.farmers;
|
||||
|
||||
import net.minecraft.client.util.InputUtil;
|
||||
import skybot.SkybotClient;
|
||||
import skybot.controller.Controller;
|
||||
import skybot.controller.task.ClickButtonTask;
|
||||
import skybot.controller.task.HoldKeyTask;
|
||||
import skybot.controller.task.PauseTask;
|
||||
import skybot.controller.task.PressButtonTask;
|
||||
import skybot.controller.task.ReleaseButtonTask;
|
||||
import skybot.controller.task.TaskQueue;
|
||||
import skybot.task.HoldKeyTask;
|
||||
import skybot.task.PressButtonTask;
|
||||
import skybot.task.ReleaseButtonTask;
|
||||
import skybot.task.RunCommandTask;
|
||||
import skybot.task.TaskQueue;
|
||||
|
||||
public class CarrotFarmer implements Farmer {
|
||||
|
||||
private static final long HEALTHCHECK_TIMEOUT_MILLIS = 4500;
|
||||
private static final long MOVEMENT_TIMEOUT_MILLIS = 5000;
|
||||
|
||||
@Override
|
||||
public boolean healthcheck() {
|
||||
long now = System.currentTimeMillis();
|
||||
boolean brokeRecently = now - SkybotClient.getLastBreakTime() < HEALTHCHECK_TIMEOUT_MILLIS;
|
||||
boolean movedRecently = now - SkybotClient.getLastMoveTime() < MOVEMENT_TIMEOUT_MILLIS;
|
||||
return brokeRecently && movedRecently;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void enqueue(TaskQueue queue) {
|
||||
queue.clear();
|
||||
|
||||
queue.add(new PauseTask(1998));
|
||||
queue.add(new ClickButtonTask(Controller.key(InputUtil.GLFW_KEY_KP_7)));
|
||||
queue.add(new RunCommandTask("warp garden"), 1998);
|
||||
|
||||
int EPOCHS = 2;
|
||||
|
||||
for (int i = 0; i < EPOCHS; i++) {
|
||||
queue.add(new PauseTask(2021));
|
||||
|
||||
queue.add(new PressButtonTask(Controller::setLeftClick));
|
||||
queue.add(new PressButtonTask(Controller::setLeftClick), 2021);
|
||||
queue.add(new HoldKeyTask(Controller::setLeft, 119555));
|
||||
queue.add(new ReleaseButtonTask(Controller::setLeftClick));
|
||||
queue.add(new PauseTask(2015));
|
||||
|
||||
queue.add(new PressButtonTask(Controller::setLeftClick));
|
||||
queue.add(new PressButtonTask(Controller::setLeftClick), 2015);
|
||||
queue.add(new HoldKeyTask(Controller::setRight, 119402));
|
||||
queue.add(new ReleaseButtonTask(Controller::setLeftClick));
|
||||
queue.add(new PauseTask(1998));
|
||||
|
||||
queue.add(new PressButtonTask(Controller::setLeftClick));
|
||||
queue.add(new PressButtonTask(Controller::setLeftClick), 1998);
|
||||
queue.add(new HoldKeyTask(Controller::setLeft, 119223));
|
||||
queue.add(new ReleaseButtonTask(Controller::setLeftClick));
|
||||
queue.add(new PauseTask(2203));
|
||||
|
||||
queue.add(new PressButtonTask(Controller::setLeftClick));
|
||||
queue.add(new PressButtonTask(Controller::setLeftClick), 2203);
|
||||
queue.add(new HoldKeyTask(Controller::setRight, 119198));
|
||||
queue.add(new ReleaseButtonTask(Controller::setLeftClick));
|
||||
queue.add(new PauseTask(1998));
|
||||
|
||||
queue.add(new PressButtonTask(Controller::setLeftClick));
|
||||
queue.add(new PressButtonTask(Controller::setLeftClick), 1998);
|
||||
queue.add(new HoldKeyTask(Controller::setLeft, 120155));
|
||||
queue.add(new ReleaseButtonTask(Controller::setLeftClick));
|
||||
queue.add(new PauseTask(2126));
|
||||
|
||||
queue.add(new ClickButtonTask(Controller.key(InputUtil.GLFW_KEY_KP_7)));
|
||||
queue.add(new RunCommandTask("warp garden"), 2126);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,12 @@
|
||||
package skybot.farmers;
|
||||
|
||||
import skybot.controller.task.TaskQueue;
|
||||
import skybot.task.TaskQueue;
|
||||
|
||||
public interface Farmer {
|
||||
void enqueue(TaskQueue queue);
|
||||
|
||||
/** Periodic sanity check while this farmer is running. Returning false stops the bot. */
|
||||
default boolean healthcheck() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,56 @@
|
||||
package skybot.farmers;
|
||||
|
||||
import skybot.SkybotClient;
|
||||
import skybot.controller.Controller;
|
||||
import skybot.task.HoldKeyTask;
|
||||
import skybot.task.PressButtonTask;
|
||||
import skybot.task.ReleaseButtonTask;
|
||||
import skybot.task.RunCommandTask;
|
||||
import skybot.task.TaskQueue;
|
||||
|
||||
public class NetherwartFarmer implements Farmer {
|
||||
|
||||
private static final long HEALTHCHECK_TIMEOUT_MILLIS = 4500;
|
||||
private static final long MOVEMENT_TIMEOUT_MILLIS = 5000;
|
||||
|
||||
@Override
|
||||
public boolean healthcheck() {
|
||||
long now = System.currentTimeMillis();
|
||||
boolean brokeRecently = now - SkybotClient.getLastBreakTime() < HEALTHCHECK_TIMEOUT_MILLIS;
|
||||
boolean movedRecently = now - SkybotClient.getLastMoveTime() < MOVEMENT_TIMEOUT_MILLIS;
|
||||
return brokeRecently && movedRecently;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void enqueue(TaskQueue queue) {
|
||||
queue.clear();
|
||||
|
||||
queue.add(new RunCommandTask("warp garden"), 1998);
|
||||
|
||||
int EPOCHS = 2;
|
||||
|
||||
for (int i = 0; i < EPOCHS; i++) {
|
||||
queue.add(new PressButtonTask(Controller::setLeftClick), 2021);
|
||||
queue.add(new HoldKeyTask(Controller::setLeft, 119555));
|
||||
queue.add(new ReleaseButtonTask(Controller::setLeftClick));
|
||||
|
||||
queue.add(new PressButtonTask(Controller::setLeftClick), 2015);
|
||||
queue.add(new HoldKeyTask(Controller::setRight, 119402));
|
||||
queue.add(new ReleaseButtonTask(Controller::setLeftClick));
|
||||
|
||||
queue.add(new PressButtonTask(Controller::setLeftClick), 1998);
|
||||
queue.add(new HoldKeyTask(Controller::setLeft, 119223));
|
||||
queue.add(new ReleaseButtonTask(Controller::setLeftClick));
|
||||
|
||||
queue.add(new PressButtonTask(Controller::setLeftClick), 2203);
|
||||
queue.add(new HoldKeyTask(Controller::setRight, 119198));
|
||||
queue.add(new ReleaseButtonTask(Controller::setLeftClick));
|
||||
|
||||
queue.add(new PressButtonTask(Controller::setLeftClick), 1998);
|
||||
queue.add(new HoldKeyTask(Controller::setLeft, 120155));
|
||||
queue.add(new ReleaseButtonTask(Controller::setLeftClick));
|
||||
|
||||
queue.add(new RunCommandTask("warp garden"), 2126);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
package skybot.farmers;
|
||||
|
||||
import skybot.SkybotClient;
|
||||
import skybot.controller.Controller;
|
||||
import skybot.task.HoldKeyTask;
|
||||
import skybot.task.PressButtonTask;
|
||||
import skybot.task.ReleaseButtonTask;
|
||||
import skybot.task.RunCommandTask;
|
||||
import skybot.task.TaskQueue;
|
||||
|
||||
public class PotatoFarmer implements Farmer {
|
||||
|
||||
private static final long HEALTHCHECK_TIMEOUT_MILLIS = 4500;
|
||||
private static final long MOVEMENT_TIMEOUT_MILLIS = 5000;
|
||||
|
||||
@Override
|
||||
public boolean healthcheck() {
|
||||
long now = System.currentTimeMillis();
|
||||
boolean brokeRecently = now - SkybotClient.getLastBreakTime() < HEALTHCHECK_TIMEOUT_MILLIS;
|
||||
boolean movedRecently = now - SkybotClient.getLastMoveTime() < MOVEMENT_TIMEOUT_MILLIS;
|
||||
return brokeRecently && movedRecently;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void enqueue(TaskQueue queue) {
|
||||
queue.clear();
|
||||
|
||||
queue.add(new RunCommandTask("warp garden"), 1998);
|
||||
|
||||
int EPOCHS = 2;
|
||||
|
||||
for (int i = 0; i < EPOCHS; i++) {
|
||||
queue.add(new PressButtonTask(Controller::setLeftClick), 2021);
|
||||
queue.add(new HoldKeyTask(Controller::setRight, 119555));
|
||||
queue.add(new ReleaseButtonTask(Controller::setLeftClick));
|
||||
|
||||
queue.add(new PressButtonTask(Controller::setLeftClick), 2015);
|
||||
queue.add(new HoldKeyTask(Controller::setLeft, 119402));
|
||||
queue.add(new ReleaseButtonTask(Controller::setLeftClick));
|
||||
|
||||
queue.add(new PressButtonTask(Controller::setLeftClick), 1998);
|
||||
queue.add(new HoldKeyTask(Controller::setRight, 119223));
|
||||
queue.add(new ReleaseButtonTask(Controller::setLeftClick));
|
||||
|
||||
queue.add(new PressButtonTask(Controller::setLeftClick), 2203);
|
||||
queue.add(new HoldKeyTask(Controller::setLeft, 119198));
|
||||
queue.add(new ReleaseButtonTask(Controller::setLeftClick));
|
||||
|
||||
queue.add(new PressButtonTask(Controller::setLeftClick), 1998);
|
||||
queue.add(new HoldKeyTask(Controller::setRight, 120155));
|
||||
queue.add(new ReleaseButtonTask(Controller::setLeftClick));
|
||||
|
||||
queue.add(new RunCommandTask("warp garden"), 2126);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2,9 +2,9 @@ package skybot.farmers;
|
||||
|
||||
import net.minecraft.client.util.InputUtil;
|
||||
import skybot.controller.Controller;
|
||||
import skybot.controller.task.ClickButtonTask;
|
||||
import skybot.controller.task.PauseTask;
|
||||
import skybot.controller.task.TaskQueue;
|
||||
import skybot.task.ClickButtonTask;
|
||||
import skybot.task.PauseTask;
|
||||
import skybot.task.TaskQueue;
|
||||
|
||||
public class TestFarmer implements Farmer {
|
||||
|
||||
|
||||
@@ -0,0 +1,56 @@
|
||||
package skybot.farmers;
|
||||
|
||||
import skybot.SkybotClient;
|
||||
import skybot.controller.Controller;
|
||||
import skybot.task.HoldKeyTask;
|
||||
import skybot.task.PressButtonTask;
|
||||
import skybot.task.ReleaseButtonTask;
|
||||
import skybot.task.RunCommandTask;
|
||||
import skybot.task.TaskQueue;
|
||||
|
||||
public class WheatFarmer implements Farmer {
|
||||
|
||||
private static final long HEALTHCHECK_TIMEOUT_MILLIS = 4500;
|
||||
private static final long MOVEMENT_TIMEOUT_MILLIS = 5000;
|
||||
|
||||
@Override
|
||||
public boolean healthcheck() {
|
||||
long now = System.currentTimeMillis();
|
||||
boolean brokeRecently = now - SkybotClient.getLastBreakTime() < HEALTHCHECK_TIMEOUT_MILLIS;
|
||||
boolean movedRecently = now - SkybotClient.getLastMoveTime() < MOVEMENT_TIMEOUT_MILLIS;
|
||||
return brokeRecently && movedRecently;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void enqueue(TaskQueue queue) {
|
||||
queue.clear();
|
||||
|
||||
queue.add(new RunCommandTask("warp garden"), 1998);
|
||||
|
||||
int EPOCHS = 2;
|
||||
|
||||
for (int i = 0; i < EPOCHS; i++) {
|
||||
queue.add(new PressButtonTask(Controller::setLeftClick), 2021);
|
||||
queue.add(new HoldKeyTask(Controller::setRight, 119555));
|
||||
queue.add(new ReleaseButtonTask(Controller::setLeftClick));
|
||||
|
||||
queue.add(new PressButtonTask(Controller::setLeftClick), 2015);
|
||||
queue.add(new HoldKeyTask(Controller::setLeft, 119402));
|
||||
queue.add(new ReleaseButtonTask(Controller::setLeftClick));
|
||||
|
||||
queue.add(new PressButtonTask(Controller::setLeftClick), 1998);
|
||||
queue.add(new HoldKeyTask(Controller::setRight, 119223));
|
||||
queue.add(new ReleaseButtonTask(Controller::setLeftClick));
|
||||
|
||||
queue.add(new PressButtonTask(Controller::setLeftClick), 2203);
|
||||
queue.add(new HoldKeyTask(Controller::setLeft, 119198));
|
||||
queue.add(new ReleaseButtonTask(Controller::setLeftClick));
|
||||
|
||||
queue.add(new PressButtonTask(Controller::setLeftClick), 1998);
|
||||
queue.add(new HoldKeyTask(Controller::setRight, 120155));
|
||||
queue.add(new ReleaseButtonTask(Controller::setLeftClick));
|
||||
|
||||
queue.add(new RunCommandTask("warp garden"), 2126);
|
||||
}
|
||||
}
|
||||
}
|
||||
+5
-2
@@ -1,9 +1,12 @@
|
||||
package skybot.controller.task;
|
||||
package skybot.task;
|
||||
|
||||
import java.util.concurrent.ThreadLocalRandom;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
/** Clicks a button (press then release) held for a log-normally distributed duration. */
|
||||
/**
|
||||
* Clicks a button (press then release) held for a log-normally distributed
|
||||
* duration.
|
||||
*/
|
||||
public class ClickButtonTask implements Task {
|
||||
private final Consumer<Boolean> setter;
|
||||
private long endTime;
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
package skybot.controller.task;
|
||||
package skybot.task;
|
||||
|
||||
import java.util.function.Consumer;
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
package skybot.controller.task;
|
||||
package skybot.task;
|
||||
|
||||
/**
|
||||
* Does nothing for a fixed duration; leaves whatever keys were already released
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
package skybot.controller.task;
|
||||
package skybot.task;
|
||||
|
||||
import java.util.function.Consumer;
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
package skybot.controller.task;
|
||||
package skybot.task;
|
||||
|
||||
import java.util.function.Consumer;
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
package skybot.controller.task;
|
||||
package skybot.task;
|
||||
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
|
||||
+5
-2
@@ -1,4 +1,4 @@
|
||||
package skybot.controller.task;
|
||||
package skybot.task;
|
||||
|
||||
public interface Task {
|
||||
/** Called once, the tick this task becomes active. */
|
||||
@@ -10,7 +10,10 @@ public interface Task {
|
||||
|
||||
boolean isDone();
|
||||
|
||||
/** Called once, right after isDone() first returns true, before the next task starts. */
|
||||
/**
|
||||
* Called once, right after isDone() first returns true, before the next task
|
||||
* starts.
|
||||
*/
|
||||
default void stop() {
|
||||
}
|
||||
|
||||
+7
-1
@@ -1,4 +1,4 @@
|
||||
package skybot.controller.task;
|
||||
package skybot.task;
|
||||
|
||||
import java.util.ArrayDeque;
|
||||
import java.util.Deque;
|
||||
@@ -27,6 +27,12 @@ public class TaskQueue {
|
||||
return this;
|
||||
}
|
||||
|
||||
public TaskQueue add(Task task, long delayMs) {
|
||||
pending.add(new PauseTask(delayMs));
|
||||
pending.add(task);
|
||||
return this;
|
||||
}
|
||||
|
||||
public void tick() {
|
||||
if (current != null && current.isDone()) {
|
||||
current.stop();
|
||||
@@ -0,0 +1,35 @@
|
||||
package skybot.utilities;
|
||||
|
||||
import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents;
|
||||
|
||||
import java.util.concurrent.ConcurrentLinkedQueue;
|
||||
|
||||
public class TickScheduler {
|
||||
private record Task(Runnable action, int ticksRemaining) {
|
||||
}
|
||||
|
||||
private static final ConcurrentLinkedQueue<Task> tasks = new ConcurrentLinkedQueue<>();
|
||||
|
||||
public static void register() {
|
||||
ClientTickEvents.END_CLIENT_TICK.register(client -> tick());
|
||||
}
|
||||
|
||||
public static void schedule(Runnable action, int delayTicks) {
|
||||
tasks.add(new Task(action, delayTicks));
|
||||
}
|
||||
|
||||
private static void tick() {
|
||||
int size = tasks.size();
|
||||
for (int i = 0; i < size; i++) {
|
||||
Task t = tasks.poll();
|
||||
if (t == null)
|
||||
break;
|
||||
int remaining = t.ticksRemaining() - 1;
|
||||
if (remaining <= 0) {
|
||||
t.action().run();
|
||||
} else {
|
||||
tasks.add(new Task(t.action(), remaining));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user