diff --git a/src/test/java/com/projectswg/holocore/headless/awareness.kt b/src/test/java/com/projectswg/holocore/headless/awareness.kt
new file mode 100644
index 000000000..202378931
--- /dev/null
+++ b/src/test/java/com/projectswg/holocore/headless/awareness.kt
@@ -0,0 +1,33 @@
+/***********************************************************************************
+ * Copyright (c) 2025 /// Project SWG /// www.projectswg.com *
+ * *
+ * ProjectSWG is an emulation project for Star Wars Galaxies founded on *
+ * July 7th, 2011 after SOE announced the official shutdown of Star Wars Galaxies. *
+ * Our goal is to create one or more emulators which will provide servers for *
+ * players to continue playing a game similar to the one they used to play. *
+ * *
+ * This file is part of Holocore. *
+ * *
+ * --------------------------------------------------------------------------------*
+ * *
+ * Holocore is free software: you can redistribute it and/or modify *
+ * it under the terms of the GNU Affero General Public License as *
+ * published by the Free Software Foundation, either version 3 of the *
+ * License, or (at your option) any later version. *
+ * *
+ * Holocore 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 Affero General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU Affero General Public License *
+ * along with Holocore. If not, see . *
+ ***********************************************************************************/
+package com.projectswg.holocore.headless
+
+import com.projectswg.common.network.packets.swg.zone.SceneDestroyObject
+import java.util.concurrent.TimeUnit
+
+fun ZonedInCharacter.waitUntilObjectDestroyed(objectId: Long) {
+ player.waitForNextPacket(SceneDestroyObject::class.java, 1, TimeUnit.SECONDS) { it.objectId == objectId }
+}
\ No newline at end of file
diff --git a/src/test/java/com/projectswg/holocore/services/gameplay/player/TipCreditsTest.kt b/src/test/java/com/projectswg/holocore/services/gameplay/player/TipCreditsTest.kt
index 8cc4f8244..73571dd3f 100644
--- a/src/test/java/com/projectswg/holocore/services/gameplay/player/TipCreditsTest.kt
+++ b/src/test/java/com/projectswg/holocore/services/gameplay/player/TipCreditsTest.kt
@@ -1,11 +1,10 @@
/***********************************************************************************
- * Copyright (c) 2024 /// Project SWG /// www.projectswg.com *
+ * Copyright (c) 2025 /// Project SWG /// www.projectswg.com *
* *
- * ProjectSWG is the first NGE emulator for Star Wars Galaxies founded on *
+ * ProjectSWG is an emulation project for Star Wars Galaxies founded on *
* July 7th, 2011 after SOE announced the official shutdown of Star Wars Galaxies. *
- * Our goal is to create an emulator which will provide a server for players to *
- * continue playing a game similar to the one they used to play. We are basing *
- * it on the final publish of the game prior to end-game events. *
+ * Our goal is to create one or more emulators which will provide servers for *
+ * players to continue playing a game similar to the one they used to play. *
* *
* This file is part of Holocore. *
* *
@@ -125,6 +124,7 @@ class TipCreditsTest : AcceptanceTest() {
y = zonedInCharacter1.player.creatureObject.y,
z = zonedInCharacter1.player.creatureObject.z
)
+ zonedInCharacter1.waitUntilObjectDestroyed(zonedInCharacter2.player.creatureObject.objectId)
val suiWindow = zonedInCharacter1.tip(zonedInCharacter2.player.creatureObject, 100)
@@ -141,6 +141,7 @@ class TipCreditsTest : AcceptanceTest() {
y = zonedInCharacter1.player.creatureObject.y,
z = zonedInCharacter1.player.creatureObject.z
)
+ zonedInCharacter1.waitUntilObjectDestroyed(zonedInCharacter2.player.creatureObject.objectId)
val suiWindow = zonedInCharacter1.tip(zonedInCharacter2.player.creatureObject, 100)
diff --git a/src/test/java/com/projectswg/holocore/test/resources/GenericPlayer.java b/src/test/java/com/projectswg/holocore/test/resources/GenericPlayer.java
index dd1217af5..cdcafab2a 100644
--- a/src/test/java/com/projectswg/holocore/test/resources/GenericPlayer.java
+++ b/src/test/java/com/projectswg/holocore/test/resources/GenericPlayer.java
@@ -1,5 +1,5 @@
/***********************************************************************************
- * Copyright (c) 2024 /// Project SWG /// www.projectswg.com *
+ * Copyright (c) 2025 /// Project SWG /// www.projectswg.com *
* *
* ProjectSWG is an emulation project for Star Wars Galaxies founded on *
* July 7th, 2011 after SOE announced the official shutdown of Star Wars Galaxies. *
@@ -55,6 +55,7 @@ import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;
+import java.util.function.Function;
import static org.junit.jupiter.api.Assertions.*;
@@ -172,6 +173,11 @@ public class GenericPlayer extends Player {
@Nullable
public T waitForNextPacket(Class type, long timeout, TimeUnit unit) {
+ return waitForNextPacket(type, timeout, unit, p -> true);
+ }
+
+ @Nullable
+ public T waitForNextPacket(Class type, long timeout, TimeUnit unit, Function filter) {
packetLock.lock();
try {
long startTime = System.nanoTime();
@@ -180,7 +186,11 @@ public class GenericPlayer extends Player {
SWGPacket next = it.next();
if (type.isInstance(next)) {
it.remove();
- return type.cast(next);
+ T packet = type.cast(next);
+ Boolean match = filter.apply(packet);
+ if (match) {
+ return packet;
+ }
}
}
try {
@@ -197,33 +207,8 @@ public class GenericPlayer extends Player {
}
@Nullable
public DeltasMessage waitForNextObjectDelta(long objectId, int num, int update, long timeout, TimeUnit unit) {
- Class extends SWGPacket> type = DeltasMessage.class;
- packetLock.lock();
- try {
- long startTime = System.nanoTime();
- while (System.nanoTime() - startTime < unit.toNanos(timeout)) {
- for (Iterator it = packets.iterator(); it.hasNext(); ) {
- SWGPacket next = it.next();
- if (type.isInstance(next)) {
- it.remove();
- DeltasMessage deltasMessage = (DeltasMessage) next;
-
- if (deltasMessage.getObjectId() == objectId && deltasMessage.getNum() == num && deltasMessage.getUpdate() == update) {
- return deltasMessage;
- }
- }
- }
- try {
- //noinspection ResultOfMethodCallIgnored
- packetLockCondition.awaitNanos(unit.toNanos(timeout) - (System.nanoTime() - startTime));
- } catch (InterruptedException e) {
- return null;
- }
- }
- } finally {
- packetLock.unlock();
- }
- return null;
+ Function deltaPacketFilter = p -> p.getObjectId() == objectId && p.getNum() == num && p.getUpdate() == update;
+ return waitForNextPacket(DeltasMessage.class, timeout, unit, deltaPacketFilter);
}
@Nullable