diff --git a/common/src/main/java/net/lionarius/skinrestorer/mixin/PlayerListMixin.java b/common/src/main/java/net/lionarius/skinrestorer/mixin/PlayerListMixin.java index df4c5ef..ccaed02 100644 --- a/common/src/main/java/net/lionarius/skinrestorer/mixin/PlayerListMixin.java +++ b/common/src/main/java/net/lionarius/skinrestorer/mixin/PlayerListMixin.java @@ -50,7 +50,7 @@ public abstract class PlayerListMixin { var actualPlayer = server.getPlayerList().getPlayer(uuid); if (actualPlayer != null) skinrestorer$tryApplySkin(server, actualPlayer); - }, delay); + }, delay, uuid); } } diff --git a/common/src/main/java/net/lionarius/skinrestorer/util/TickedScheduler.java b/common/src/main/java/net/lionarius/skinrestorer/util/TickedScheduler.java index 12954be..048a452 100644 --- a/common/src/main/java/net/lionarius/skinrestorer/util/TickedScheduler.java +++ b/common/src/main/java/net/lionarius/skinrestorer/util/TickedScheduler.java @@ -4,36 +4,52 @@ import com.google.common.collect.Queues; import net.minecraft.server.MinecraftServer; import org.jetbrains.annotations.NotNull; +import java.util.Map; import java.util.Queue; +import java.util.concurrent.ConcurrentHashMap; public class TickedScheduler implements Runnable { private final MinecraftServer server; private final Queue queue = Queues.newPriorityBlockingQueue(); + private final Map idMap = new ConcurrentHashMap<>(); public TickedScheduler(MinecraftServer server) { this.server = server; } public void schedule(Runnable task, int delay) { - this.queue.add(new TickTask(this.server.getTickCount() + delay, task)); + this.schedule(task, delay, task); + } + + public void schedule(Runnable task, int delay, Object id) { + var taskId = id.hashCode(); + var serverTick = this.server.getTickCount(); + this.idMap.merge(taskId, serverTick, Integer::max); + this.queue.add(new TickTask(serverTick, serverTick + delay, taskId, task)); } @Override public void run() { TickTask nextTask; while ((nextTask = this.queue.peek()) != null) { - if (nextTask.tick() > this.server.getTickCount()) + if (nextTask.runOnTick() > this.server.getTickCount()) break; var tickTask = this.queue.remove(); - tickTask.task().run(); + var lastTaskScheduledOnTick = this.idMap.get(tickTask.id()); + + if (lastTaskScheduledOnTick != null && lastTaskScheduledOnTick <= tickTask.scheduledOnTick()) { + this.idMap.remove(tickTask.id()); + if (tickTask.task() != null) + tickTask.task().run(); + } } } - private record TickTask(int tick, Runnable task) implements Comparable { + private record TickTask(int scheduledOnTick, int runOnTick, int id, Runnable task) implements Comparable { @Override public int compareTo(@NotNull TickedScheduler.TickTask other) { - return Integer.compare(this.tick, other.tick); + return Integer.compare(this.runOnTick, other.runOnTick); } } }