Refactor: extract MacroPacketObserve from MacroExecutor (upstream #4)

Move the timed one-shot listener machinery, fire/drain observers and
the onPacketSent/Received/Observed entry points verbatim into
MacroPacketObserve. OneShotPacketListener and awaitReceive/awaitSend
stay reachable via MacroExecutor delegates for external callers.
Shared members referenced as MacroExecutor.xxx (mechanical
qualification only). All bodies verified identical against HEAD
modulo that qualification.
This commit is contained in:
sectersion 2026-10-11 16:37:02 +01:00
parent 3ac299c1d5
commit 295688beda
3 changed files with 248 additions and 211 deletions

View file

@ -522,7 +522,7 @@ public class MacroExecutor {
ACTIVE_RUN_LIST = java.util.List.copyOf(ACTIVE_RUNS.values()); ACTIVE_RUN_LIST = java.util.List.copyOf(ACTIVE_RUNS.values());
} }
private static java.util.List<RunState> activeRunSnapshot() { static java.util.List<RunState> activeRunSnapshot() {
return ACTIVE_RUN_LIST; return ACTIVE_RUN_LIST;
} }
@ -918,7 +918,7 @@ public class MacroExecutor {
backgroundMoves.clear(); backgroundMoves.clear();
reconcilePersistentInput(Minecraft.getInstance()); reconcilePersistentInput(Minecraft.getInstance());
MacroConditionRegistry.cancelAll(); MacroConditionRegistry.cancelAll();
drainOneShotListeners(); MacroPacketObserve.drainOneShotListeners();
isWaitingForChat.set(false); isWaitingForChat.set(false);
isWaitingForPacket.set(false); isWaitingForPacket.set(false);
synchronized (packetWaitLock) { synchronized (packetWaitLock) {
@ -976,10 +976,10 @@ public class MacroExecutor {
return isRunning.get() return isRunning.get()
|| activePacketFuture != null || activePacketFuture != null
|| isWaitingForPacket.get() || isWaitingForPacket.get()
|| !ONE_SHOT_RECV.isEmpty() || !MacroPacketObserve.ONE_SHOT_RECV.isEmpty()
|| !ONE_SHOT_SEND.isEmpty() || !MacroPacketObserve.ONE_SHOT_SEND.isEmpty()
|| !TIMED_ONE_SHOT_RECV.isEmpty() || !MacroPacketObserve.TIMED_ONE_SHOT_RECV.isEmpty()
|| !TIMED_ONE_SHOT_SEND.isEmpty(); || !MacroPacketObserve.TIMED_ONE_SHOT_SEND.isEmpty();
} }
public static boolean isMacroRunning(String macroName) { public static boolean isMacroRunning(String macroName) {
@ -1121,7 +1121,7 @@ public class MacroExecutor {
} }
} }
private static final long ONE_SHOT_EXPIRE_NANOS = java.util.concurrent.TimeUnit.MINUTES.toNanos(10); static final long ONE_SHOT_EXPIRE_NANOS = java.util.concurrent.TimeUnit.MINUTES.toNanos(10);
public static final class OneShotPacketListener { public static final class OneShotPacketListener {
public final java.util.concurrent.CompletableFuture<Packet<?>> future = new java.util.concurrent.CompletableFuture<>(); public final java.util.concurrent.CompletableFuture<Packet<?>> future = new java.util.concurrent.CompletableFuture<>();
@ -1153,217 +1153,30 @@ public class MacroExecutor {
} }
} }
static final class TimedOneShotPacketListener {
public final java.util.concurrent.CompletableFuture<MacroEvent> future = new java.util.concurrent.CompletableFuture<>();
private final java.util.List<TimedOneShotPacketListener> registry;
private final TimedPacketMatch match;
private final long expireAtNanos;
TimedOneShotPacketListener(java.util.List<TimedOneShotPacketListener> registry, TimedPacketMatch match) {
this.registry = registry;
this.match = match;
this.expireAtNanos = System.nanoTime() + ONE_SHOT_EXPIRE_NANOS;
registry.add(this);
}
boolean offer(MacroEvent event) {
if (future.isDone()) return true;
if (event.nanoTime() - expireAtNanos >= 0L) { future.cancel(true); return true; }
if (match.test(event.packet(), event.direction(), event.nanoTime())) {
future.complete(event);
return true;
}
return false;
}
public void cancel() {
registry.remove(this);
if (!future.isDone()) future.cancel(true);
}
}
interface TimedPacketMatch {
boolean test(Packet<?> packet, String direction, long nanoTime);
}
private static final java.util.List<OneShotPacketListener> ONE_SHOT_RECV =
new java.util.concurrent.CopyOnWriteArrayList<>();
private static final java.util.List<OneShotPacketListener> ONE_SHOT_SEND =
new java.util.concurrent.CopyOnWriteArrayList<>();
private static final java.util.List<TimedOneShotPacketListener> TIMED_ONE_SHOT_RECV =
new java.util.concurrent.CopyOnWriteArrayList<>();
private static final java.util.List<TimedOneShotPacketListener> TIMED_ONE_SHOT_SEND =
new java.util.concurrent.CopyOnWriteArrayList<>();
public static OneShotPacketListener awaitReceive(java.util.function.Predicate<Packet<?>> match) { public static OneShotPacketListener awaitReceive(java.util.function.Predicate<Packet<?>> match) {
return new OneShotPacketListener(ONE_SHOT_RECV, match); return MacroPacketObserve.awaitReceive(match);
} }
public static OneShotPacketListener awaitSend(java.util.function.Predicate<Packet<?>> match) { public static OneShotPacketListener awaitSend(java.util.function.Predicate<Packet<?>> match) {
return new OneShotPacketListener(ONE_SHOT_SEND, match); return MacroPacketObserve.awaitSend(match);
}
static TimedOneShotPacketListener awaitTimedReceive(TimedPacketMatch match) {
return new TimedOneShotPacketListener(TIMED_ONE_SHOT_RECV, match);
}
static TimedOneShotPacketListener awaitTimedSend(java.util.function.Predicate<Packet<?>> match) {
return awaitTimedSend((packet, direction, nanoTime) -> match.test(packet));
}
static TimedOneShotPacketListener awaitTimedSend(TimedPacketMatch match) {
return new TimedOneShotPacketListener(TIMED_ONE_SHOT_SEND, match);
}
private static void fireOneShotObservers(java.util.List<OneShotPacketListener> list, Packet<?> packet) {
if (list.isEmpty()) return;
long now = System.nanoTime();
java.util.ArrayList<OneShotPacketListener> matched = null;
for (OneShotPacketListener listener : list) {
boolean drop;
try { drop = listener.offer(packet, now); }
catch (Throwable ignored) { drop = true; }
if (drop) {
if (matched == null) matched = new java.util.ArrayList<>(4);
matched.add(listener);
}
}
if (matched != null) list.removeAll(matched);
}
private static void fireTimedObservers(java.util.List<TimedOneShotPacketListener> list, MacroEvent event) {
if (list.isEmpty()) return;
java.util.ArrayList<TimedOneShotPacketListener> matched = null;
for (TimedOneShotPacketListener listener : list) {
boolean drop;
try { drop = listener.offer(event); }
catch (Throwable ignored) { drop = true; }
if (drop) {
if (matched == null) matched = new java.util.ArrayList<>(4);
matched.add(listener);
}
}
if (matched != null) list.removeAll(matched);
}
private static void drainOneShotListeners() {
for (OneShotPacketListener listener : ONE_SHOT_RECV) listener.cancel();
for (OneShotPacketListener listener : ONE_SHOT_SEND) listener.cancel();
for (TimedOneShotPacketListener listener : TIMED_ONE_SHOT_RECV) listener.cancel();
for (TimedOneShotPacketListener listener : TIMED_ONE_SHOT_SEND) listener.cancel();
} }
public static String oneShotCensus() { public static String oneShotCensus() {
return "runs=" + getActiveRunCount() return MacroPacketObserve.oneShotCensus();
+ " recv=" + ONE_SHOT_RECV.size()
+ " send=" + ONE_SHOT_SEND.size()
+ " timedRecv=" + TIMED_ONE_SHOT_RECV.size()
+ " timedSend=" + TIMED_ONE_SHOT_SEND.size();
} }
public static void onPacketSent(Packet<?> packet) { public static void onPacketSent(Packet<?> packet) {
if (PackHideState.isHardLocked()) return; MacroPacketObserve.onPacketSent(packet);
if (!TIMED_ONE_SHOT_SEND.isEmpty()) {
fireTimedObservers(TIMED_ONE_SHOT_SEND, new MacroEvent(packet, "C2S", System.nanoTime(), null));
}
fireOneShotObservers(ONE_SHOT_SEND, packet);
onPacketObserved(packet, "C2S");
} }
public static void onPacketReceived(Packet<?> packet) { public static void onPacketReceived(Packet<?> packet) {
if (PackHideState.isHardLocked()) return; MacroPacketObserve.onPacketReceived(packet);
if (!TIMED_ONE_SHOT_RECV.isEmpty()) {
fireTimedObservers(TIMED_ONE_SHOT_RECV, new MacroEvent(packet, "S2C", System.nanoTime(), null));
}
fireOneShotObservers(ONE_SHOT_RECV, packet);
if (packet instanceof net.minecraft.network.protocol.game.ClientboundRespawnPacket
|| packet instanceof net.minecraft.network.protocol.game.ClientboundLoginPacket) {
MacroConditionRegistry.onRespawnPacket();
}
if (packet instanceof net.minecraft.network.protocol.game.ClientboundPlayerPositionPacket) {
MacroConditionRegistry.onTeleportPacket();
}
onPacketObserved(packet, "S2C");
} }
public static void onPacketObserved(Packet<?> packet, String direction) { public static void onPacketObserved(Packet<?> packet, String direction) {
if (PackHideState.isHardLocked()) return; MacroPacketObserve.onPacketObserved(packet, direction);
MacroChatObserve.syncRecentChatServerContext();
java.util.List<RunState> runs = activeRunSnapshot();
boolean s2c = "S2C".equals(direction);
boolean chatWork = false;
boolean mineWork = false;
boolean packetWork = false;
for (int i = 0; i < runs.size(); i++) {
RunState run = runs.get(i);
if (!run.running.get()) continue;
if (run.waitingForChat.get()) chatWork = true;
if (run.activeMineTracker != null) mineWork = true;
if (run.waitingForPacket.get()) packetWork = true;
} }
if (s2c && (chatWork || isWaitingForChat.get())) {
ChatCapture capture = MacroChatObserve.extractIncomingChat(packet);
if (capture != null && capture.message() != null && !capture.message().isBlank()) {
for (RunState run : runs) {
var matched = run.running.get() && run.waitingForChat.get()
? MacroChatObserve.captureChatAction(run.waitingChatAction, capture, run.variables)
: java.util.Optional.<java.util.Map<String, MacroValue>>empty();
if (matched.isPresent()) {
run.stagedCaptures.put(run.waitingChatAction, matched.get());
CompletableFuture<Void> f = run.chatFuture;
if (f != null) f.complete(null);
}
}
if (isCurrentRunActive() && isWaitingForChat.get() && MacroChatObserve.matchesWaitingChat(capture)) {
lastMatchedChat.set(capture.displayText());
CompletableFuture<Void> f = activeChatFuture;
if (f != null) f.complete(null);
}
}
}
if (s2c && mineWork) {
Minecraft mc = Minecraft.getInstance();
for (RunState run : runs) {
MacroWorldActions.MineProgressTracker tracker = run.running.get() ? run.activeMineTracker : null;
if (tracker != null) tracker.observePacket(mc, packet);
}
}
if (!isCurrentRunActive()) return;
if (packetWork) {
for (RunState run : runs) {
if (!run.running.get() || !run.waitingForPacket.get()) continue;
CompletableFuture<Void> f = null;
synchronized (run.packetWaitLock) {
if (run.waitingForPacket.get() && MacroPacketWait.matchesPacketTarget(run.waitingPacketName.get(), packet, direction)) {
run.lastMatchedPacket = packet;
run.lastMatchedPacketDirection = direction;
f = run.packetFuture;
}
}
if (f != null) f.complete(null);
}
}
if (isWaitingForPacket.get()) {
CompletableFuture<Void> f = null;
synchronized (packetWaitLock) {
if (!isWaitingForPacket.get()) return;
String target = waitingPacketName.get();
if (MacroPacketWait.matchesPacketTarget(target, packet, direction)) {
lastReceivedPacket.set(direction + " " + AutismPacketNamer.getFriendlyName(packet, direction));
f = activePacketFuture;
}
}
if (f != null) f.complete(null);
}
}
public static void observeIncomingChat(Packet<?> packet) { public static void observeIncomingChat(Packet<?> packet) {
MacroChatObserve.observeIncomingChat(packet); MacroChatObserve.observeIncomingChat(packet);

View file

@ -0,0 +1,224 @@
package autismclient.util.macro;
import autismclient.modules.PackHideState;
import autismclient.util.AutismPacketNamer;
import net.minecraft.client.Minecraft;
import net.minecraft.network.protocol.Packet;
import java.util.concurrent.CompletableFuture;
final class MacroPacketObserve {
private MacroPacketObserve() {
}
static final class TimedOneShotPacketListener {
public final java.util.concurrent.CompletableFuture<MacroExecutor.MacroEvent> future = new java.util.concurrent.CompletableFuture<>();
private final java.util.List<TimedOneShotPacketListener> registry;
private final TimedPacketMatch match;
private final long expireAtNanos;
TimedOneShotPacketListener(java.util.List<TimedOneShotPacketListener> registry, TimedPacketMatch match) {
this.registry = registry;
this.match = match;
this.expireAtNanos = System.nanoTime() + MacroExecutor.ONE_SHOT_EXPIRE_NANOS;
registry.add(this);
}
boolean offer(MacroExecutor.MacroEvent event) {
if (future.isDone()) return true;
if (event.nanoTime() - expireAtNanos >= 0L) { future.cancel(true); return true; }
if (match.test(event.packet(), event.direction(), event.nanoTime())) {
future.complete(event);
return true;
}
return false;
}
public void cancel() {
registry.remove(this);
if (!future.isDone()) future.cancel(true);
}
}
interface TimedPacketMatch {
boolean test(Packet<?> packet, String direction, long nanoTime);
}
static final java.util.List<MacroExecutor.OneShotPacketListener> ONE_SHOT_RECV =
new java.util.concurrent.CopyOnWriteArrayList<>();
static final java.util.List<MacroExecutor.OneShotPacketListener> ONE_SHOT_SEND =
new java.util.concurrent.CopyOnWriteArrayList<>();
static final java.util.List<TimedOneShotPacketListener> TIMED_ONE_SHOT_RECV =
new java.util.concurrent.CopyOnWriteArrayList<>();
static final java.util.List<TimedOneShotPacketListener> TIMED_ONE_SHOT_SEND =
new java.util.concurrent.CopyOnWriteArrayList<>();
public static MacroExecutor.OneShotPacketListener awaitReceive(java.util.function.Predicate<Packet<?>> match) {
return new MacroExecutor.OneShotPacketListener(ONE_SHOT_RECV, match);
}
public static MacroExecutor.OneShotPacketListener awaitSend(java.util.function.Predicate<Packet<?>> match) {
return new MacroExecutor.OneShotPacketListener(ONE_SHOT_SEND, match);
}
static TimedOneShotPacketListener awaitTimedReceive(TimedPacketMatch match) {
return new TimedOneShotPacketListener(TIMED_ONE_SHOT_RECV, match);
}
static TimedOneShotPacketListener awaitTimedSend(java.util.function.Predicate<Packet<?>> match) {
return awaitTimedSend((packet, direction, nanoTime) -> match.test(packet));
}
static TimedOneShotPacketListener awaitTimedSend(TimedPacketMatch match) {
return new TimedOneShotPacketListener(TIMED_ONE_SHOT_SEND, match);
}
private static void fireOneShotObservers(java.util.List<MacroExecutor.OneShotPacketListener> list, Packet<?> packet) {
if (list.isEmpty()) return;
long now = System.nanoTime();
java.util.ArrayList<MacroExecutor.OneShotPacketListener> matched = null;
for (MacroExecutor.OneShotPacketListener listener : list) {
boolean drop;
try { drop = listener.offer(packet, now); }
catch (Throwable ignored) { drop = true; }
if (drop) {
if (matched == null) matched = new java.util.ArrayList<>(4);
matched.add(listener);
}
}
if (matched != null) list.removeAll(matched);
}
private static void fireTimedObservers(java.util.List<TimedOneShotPacketListener> list, MacroExecutor.MacroEvent event) {
if (list.isEmpty()) return;
java.util.ArrayList<TimedOneShotPacketListener> matched = null;
for (TimedOneShotPacketListener listener : list) {
boolean drop;
try { drop = listener.offer(event); }
catch (Throwable ignored) { drop = true; }
if (drop) {
if (matched == null) matched = new java.util.ArrayList<>(4);
matched.add(listener);
}
}
if (matched != null) list.removeAll(matched);
}
public static void drainOneShotListeners() {
for (MacroExecutor.OneShotPacketListener listener : ONE_SHOT_RECV) listener.cancel();
for (MacroExecutor.OneShotPacketListener listener : ONE_SHOT_SEND) listener.cancel();
for (TimedOneShotPacketListener listener : TIMED_ONE_SHOT_RECV) listener.cancel();
for (TimedOneShotPacketListener listener : TIMED_ONE_SHOT_SEND) listener.cancel();
}
public static String oneShotCensus() {
return "runs=" + MacroExecutor.getActiveRunCount()
+ " recv=" + ONE_SHOT_RECV.size()
+ " send=" + ONE_SHOT_SEND.size()
+ " timedRecv=" + TIMED_ONE_SHOT_RECV.size()
+ " timedSend=" + TIMED_ONE_SHOT_SEND.size();
}
public static void onPacketSent(Packet<?> packet) {
if (PackHideState.isHardLocked()) return;
if (!TIMED_ONE_SHOT_SEND.isEmpty()) {
fireTimedObservers(TIMED_ONE_SHOT_SEND, new MacroExecutor.MacroEvent(packet, "C2S", System.nanoTime(), null));
}
fireOneShotObservers(ONE_SHOT_SEND, packet);
onPacketObserved(packet, "C2S");
}
public static void onPacketReceived(Packet<?> packet) {
if (PackHideState.isHardLocked()) return;
if (!TIMED_ONE_SHOT_RECV.isEmpty()) {
fireTimedObservers(TIMED_ONE_SHOT_RECV, new MacroExecutor.MacroEvent(packet, "S2C", System.nanoTime(), null));
}
fireOneShotObservers(ONE_SHOT_RECV, packet);
if (packet instanceof net.minecraft.network.protocol.game.ClientboundRespawnPacket
|| packet instanceof net.minecraft.network.protocol.game.ClientboundLoginPacket) {
MacroConditionRegistry.onRespawnPacket();
}
if (packet instanceof net.minecraft.network.protocol.game.ClientboundPlayerPositionPacket) {
MacroConditionRegistry.onTeleportPacket();
}
onPacketObserved(packet, "S2C");
}
public static void onPacketObserved(Packet<?> packet, String direction) {
if (PackHideState.isHardLocked()) return;
MacroChatObserve.syncRecentChatServerContext();
java.util.List<MacroExecutor.RunState> runs = MacroExecutor.activeRunSnapshot();
boolean s2c = "S2C".equals(direction);
boolean chatWork = false;
boolean mineWork = false;
boolean packetWork = false;
for (int i = 0; i < runs.size(); i++) {
MacroExecutor.RunState run = runs.get(i);
if (!run.running.get()) continue;
if (run.waitingForChat.get()) chatWork = true;
if (run.activeMineTracker != null) mineWork = true;
if (run.waitingForPacket.get()) packetWork = true;
}
if (s2c && (chatWork || MacroExecutor.isWaitingForChat.get())) {
MacroExecutor.ChatCapture capture = MacroChatObserve.extractIncomingChat(packet);
if (capture != null && capture.message() != null && !capture.message().isBlank()) {
for (MacroExecutor.RunState run : runs) {
var matched = run.running.get() && run.waitingForChat.get()
? MacroChatObserve.captureChatAction(run.waitingChatAction, capture, run.variables)
: java.util.Optional.<java.util.Map<String, MacroValue>>empty();
if (matched.isPresent()) {
run.stagedCaptures.put(run.waitingChatAction, matched.get());
CompletableFuture<Void> f = run.chatFuture;
if (f != null) f.complete(null);
}
}
if (MacroExecutor.isCurrentRunActive() && MacroExecutor.isWaitingForChat.get() && MacroChatObserve.matchesWaitingChat(capture)) {
MacroExecutor.lastMatchedChat.set(capture.displayText());
CompletableFuture<Void> f = MacroExecutor.activeChatFuture;
if (f != null) f.complete(null);
}
}
}
if (s2c && mineWork) {
Minecraft mc = Minecraft.getInstance();
for (MacroExecutor.RunState run : runs) {
MacroWorldActions.MineProgressTracker tracker = run.running.get() ? run.activeMineTracker : null;
if (tracker != null) tracker.observePacket(mc, packet);
}
}
if (!MacroExecutor.isCurrentRunActive()) return;
if (packetWork) {
for (MacroExecutor.RunState run : runs) {
if (!run.running.get() || !run.waitingForPacket.get()) continue;
CompletableFuture<Void> f = null;
synchronized (run.packetWaitLock) {
if (run.waitingForPacket.get() && MacroPacketWait.matchesPacketTarget(run.waitingPacketName.get(), packet, direction)) {
run.lastMatchedPacket = packet;
run.lastMatchedPacketDirection = direction;
f = run.packetFuture;
}
}
if (f != null) f.complete(null);
}
}
if (MacroExecutor.isWaitingForPacket.get()) {
CompletableFuture<Void> f = null;
synchronized (MacroExecutor.packetWaitLock) {
if (!MacroExecutor.isWaitingForPacket.get()) return;
String target = MacroExecutor.waitingPacketName.get();
if (MacroPacketWait.matchesPacketTarget(target, packet, direction)) {
MacroExecutor.lastReceivedPacket.set(direction + " " + AutismPacketNamer.getFriendlyName(packet, direction));
f = MacroExecutor.activePacketFuture;
}
}
if (f != null) f.complete(null);
}
}
}

View file

@ -517,21 +517,21 @@ final class MacroRace {
private static CompletableFuture<MacroExecutor.MacroEvent> startActionAnchorFuture(MacroAction action) { private static CompletableFuture<MacroExecutor.MacroEvent> startActionAnchorFuture(MacroAction action) {
if (action instanceof PacketClickAction) { if (action instanceof PacketClickAction) {
return MacroExecutor.awaitTimedSend(packet -> packet instanceof ServerboundContainerClickPacket).future; return MacroPacketObserve.awaitTimedSend(packet -> packet instanceof ServerboundContainerClickPacket).future;
} }
if (action instanceof ItemAction) { if (action instanceof ItemAction) {
return MacroExecutor.awaitTimedSend(packet -> packet instanceof ServerboundContainerClickPacket).future; return MacroPacketObserve.awaitTimedSend(packet -> packet instanceof ServerboundContainerClickPacket).future;
} }
if (action instanceof CloseGuiAction) { if (action instanceof CloseGuiAction) {
return MacroExecutor.awaitTimedSend(packet -> packet instanceof net.minecraft.network.protocol.game.ServerboundContainerClosePacket).future; return MacroPacketObserve.awaitTimedSend(packet -> packet instanceof net.minecraft.network.protocol.game.ServerboundContainerClosePacket).future;
} }
if (action instanceof SendChatAction) { if (action instanceof SendChatAction) {
return MacroExecutor.awaitTimedSend(packet -> packet instanceof net.minecraft.network.protocol.game.ServerboundChatPacket return MacroPacketObserve.awaitTimedSend(packet -> packet instanceof net.minecraft.network.protocol.game.ServerboundChatPacket
|| packet instanceof net.minecraft.network.protocol.game.ServerboundChatCommandPacket || packet instanceof net.minecraft.network.protocol.game.ServerboundChatCommandPacket
|| packet instanceof net.minecraft.network.protocol.game.ServerboundChatCommandSignedPacket).future; || packet instanceof net.minecraft.network.protocol.game.ServerboundChatCommandSignedPacket).future;
} }
if (action instanceof SendPacketAction || action instanceof PayloadAction) { if (action instanceof SendPacketAction || action instanceof PayloadAction) {
return MacroExecutor.awaitTimedSend(packet -> true).future; return MacroPacketObserve.awaitTimedSend(packet -> true).future;
} }
return null; return null;
} }
@ -597,7 +597,7 @@ final class MacroRace {
MacroVariableContext context = MacroExecutor.currentVariableContext(); MacroVariableContext context = MacroExecutor.currentVariableContext();
java.util.concurrent.atomic.AtomicReference<java.util.Map<String, MacroValue>> captures = java.util.concurrent.atomic.AtomicReference<java.util.Map<String, MacroValue>> captures =
new java.util.concurrent.atomic.AtomicReference<>(java.util.Map.of()); new java.util.concurrent.atomic.AtomicReference<>(java.util.Map.of());
MacroExecutor.TimedOneShotPacketListener listener = MacroExecutor.awaitTimedReceive((packet, direction, now) -> { MacroPacketObserve.TimedOneShotPacketListener listener = MacroPacketObserve.awaitTimedReceive((packet, direction, now) -> {
MacroExecutor.ChatCapture capture = MacroChatObserve.extractIncomingChat(packet); MacroExecutor.ChatCapture capture = MacroChatObserve.extractIncomingChat(packet);
var matched = MacroChatObserve.captureChatAction(chat, capture, context); var matched = MacroChatObserve.captureChatAction(chat, capture, context);
matched.ifPresent(captures::set); matched.ifPresent(captures::set);
@ -616,14 +616,14 @@ final class MacroRace {
if (trigger instanceof WaitForPacketAction packetAction) { if (trigger instanceof WaitForPacketAction packetAction) {
java.util.List<String> targets = packetAction.effectiveList(); java.util.List<String> targets = packetAction.effectiveList();
CompletableFuture<MacroExecutor.MacroEvent> matched = new CompletableFuture<>(); CompletableFuture<MacroExecutor.MacroEvent> matched = new CompletableFuture<>();
MacroExecutor.TimedOneShotPacketListener recv = MacroExecutor.awaitTimedReceive((packet, direction, now) -> { MacroPacketObserve.TimedOneShotPacketListener recv = MacroPacketObserve.awaitTimedReceive((packet, direction, now) -> {
if (targets.isEmpty()) return true; if (targets.isEmpty()) return true;
for (String target : targets) { for (String target : targets) {
if (MacroPacketWait.matchesPacketTarget(target, packet, "S2C")) return true; if (MacroPacketWait.matchesPacketTarget(target, packet, "S2C")) return true;
} }
return false; return false;
}); });
MacroExecutor.TimedOneShotPacketListener send = MacroExecutor.awaitTimedSend((packet, direction, now) -> { MacroPacketObserve.TimedOneShotPacketListener send = MacroPacketObserve.awaitTimedSend((packet, direction, now) -> {
if (targets.isEmpty()) return true; if (targets.isEmpty()) return true;
for (String target : targets) { for (String target : targets) {
if (MacroPacketWait.matchesPacketTarget(target, packet, "C2S")) return true; if (MacroPacketWait.matchesPacketTarget(target, packet, "C2S")) return true;
@ -641,7 +641,7 @@ final class MacroRace {
if (trigger instanceof WaitForWorldChangeAction world) { if (trigger instanceof WaitForWorldChangeAction world) {
CompletableFuture<MacroExecutor.MacroEvent> done = new CompletableFuture<>(); CompletableFuture<MacroExecutor.MacroEvent> done = new CompletableFuture<>();
CompletableFuture<Void> tickFuture = MacroConditionRegistry.waitForWorldChange(world); CompletableFuture<Void> tickFuture = MacroConditionRegistry.waitForWorldChange(world);
MacroExecutor.TimedOneShotPacketListener worldListener = MacroExecutor.awaitTimedReceive((packet, direction, now) -> isWorldTransitionPacket(packet)); MacroPacketObserve.TimedOneShotPacketListener worldListener = MacroPacketObserve.awaitTimedReceive((packet, direction, now) -> isWorldTransitionPacket(packet));
tickFuture.whenComplete((v, e) -> { tickFuture.whenComplete((v, e) -> {
if (e != null) { if (e != null) {
if (!done.isDone()) done.cancel(true); if (!done.isDone()) done.cancel(true);
@ -667,7 +667,7 @@ final class MacroRace {
if (trigger instanceof WaitForTeleportAction teleport) { if (trigger instanceof WaitForTeleportAction teleport) {
net.minecraft.world.phys.Vec3 origin = mc.player == null ? net.minecraft.world.phys.Vec3.ZERO : mc.player.position(); net.minecraft.world.phys.Vec3 origin = mc.player == null ? net.minecraft.world.phys.Vec3.ZERO : mc.player.position();
CompletableFuture<MacroExecutor.MacroEvent> done = new CompletableFuture<>(); CompletableFuture<MacroExecutor.MacroEvent> done = new CompletableFuture<>();
MacroExecutor.TimedOneShotPacketListener teleListener = MacroExecutor.awaitTimedReceive((packet, direction, now) -> MacroPacketObserve.TimedOneShotPacketListener teleListener = MacroPacketObserve.awaitTimedReceive((packet, direction, now) ->
packet instanceof ClientboundPlayerPositionPacket || isWorldTransitionPacket(packet)); packet instanceof ClientboundPlayerPositionPacket || isWorldTransitionPacket(packet));
teleListener.future.whenComplete((event, error) -> { teleListener.future.whenComplete((event, error) -> {
teleListener.cancel(); teleListener.cancel();