Architectural debt cleanup on top of the earlier V2 hardening pass.
Minigame:
- LockpickMiniGameState splits the overloaded targetSlot int into a
LockpickTargetKind enum + targetData int. Body-vs-furniture
dispatch is now a simple enum check; the NBT-tag nonce it
previously depended on is gone, along with the AIOOBE risk at
BodyRegionV2.values()[targetSlot].
- PacketLockpickAttempt.handleFurnitureLockpickSuccess takes the
entity and seat id as explicit parameters. Caller pre-validates
both before any side effect, so a corrupted ctx tag can no longer
produce a "Lock picked!" UI with a used lockpick and nothing
unlocked.
Package boundaries:
- client.gltf no longer imports v2.bondage. Render-layer attachment,
DataDrivenItemReloadListener, and GlbValidationReloadListener all
live in v2.client.V2ClientSetup.
- GlbValidationReloadListener moved to v2.bondage.client.diagnostic.
- Reload-listener ordering is preserved via EventPriority (HIGH for
the generic GLB cache clear in GltfClientSetup, LOW for bondage
consumers in V2ClientSetup).
- Removed the unused validateAgainstDefinition stub on GlbValidator.
Extractions from EntityFurniture:
- FurnitureSeatSyncCodec (pipe/semicolon serialization for the
SEAT_ASSIGNMENTS_SYNC entity data field), with 8 unit tests.
- FurnitureClientAnimator (client-only seat-pose kickoff, moved out
of the dual-side entity class).
- EntityFurniture drops ~100 lines with no behavior change.
Interface docs:
- ISeatProvider Javadoc narrowed to reflect that EntityFurniture is
the only implementation; callers that need animation state or
definition reference still downcast.
- FurnitureAuthPredicate.findOccupant uses the interface only.
- AnimationIdBuilder flagged as legacy JSON-era utility (NPC
fallback + MCA mixin).
Artist guide: corrected the "Monster Seat System (Planned)" section
to match the ISeatProvider single-impl reality.
89 lines
2.7 KiB
Java
89 lines
2.7 KiB
Java
package com.tiedup.remake.v2.furniture;
|
|
|
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
|
import static org.junit.jupiter.api.Assertions.assertTrue;
|
|
|
|
import java.util.LinkedHashMap;
|
|
import java.util.Map;
|
|
import java.util.UUID;
|
|
import org.junit.jupiter.api.DisplayName;
|
|
import org.junit.jupiter.api.Test;
|
|
|
|
class FurnitureSeatSyncCodecTest {
|
|
|
|
private static final UUID U1 = UUID.fromString(
|
|
"00000000-0000-0000-0000-000000000001"
|
|
);
|
|
private static final UUID U2 = UUID.fromString(
|
|
"00000000-0000-0000-0000-000000000002"
|
|
);
|
|
|
|
@Test
|
|
@DisplayName("empty map encodes to empty string")
|
|
void empty() {
|
|
assertEquals("", FurnitureSeatSyncCodec.encode(Map.of()));
|
|
assertTrue(FurnitureSeatSyncCodec.decode("").isEmpty());
|
|
}
|
|
|
|
@Test
|
|
@DisplayName("single entry round-trip")
|
|
void single() {
|
|
Map<UUID, String> m = new LinkedHashMap<>();
|
|
m.put(U1, "left");
|
|
String wire = FurnitureSeatSyncCodec.encode(m);
|
|
assertEquals(U1 + ";left", wire);
|
|
assertEquals(m, FurnitureSeatSyncCodec.decode(wire));
|
|
}
|
|
|
|
@Test
|
|
@DisplayName("multi entry round-trip preserves insertion order")
|
|
void multi() {
|
|
Map<UUID, String> m = new LinkedHashMap<>();
|
|
m.put(U1, "left");
|
|
m.put(U2, "right");
|
|
String wire = FurnitureSeatSyncCodec.encode(m);
|
|
Map<UUID, String> back = FurnitureSeatSyncCodec.decode(wire);
|
|
assertEquals(m, back);
|
|
}
|
|
|
|
@Test
|
|
@DisplayName("decode skips corrupt UUIDs and preserves valid entries")
|
|
void skipsCorrupt() {
|
|
String wire = "not-a-uuid;left|" + U2 + ";right";
|
|
Map<UUID, String> back = FurnitureSeatSyncCodec.decode(wire);
|
|
assertEquals(1, back.size());
|
|
assertEquals("right", back.get(U2));
|
|
}
|
|
|
|
@Test
|
|
@DisplayName("decode rejects entries with missing seat id")
|
|
void rejectsEmptySeatId() {
|
|
String wire = U1 + ";";
|
|
assertTrue(FurnitureSeatSyncCodec.decode(wire).isEmpty());
|
|
}
|
|
|
|
@Test
|
|
@DisplayName("decode tolerates null input")
|
|
void nullInput() {
|
|
assertTrue(FurnitureSeatSyncCodec.decode(null).isEmpty());
|
|
}
|
|
|
|
@Test
|
|
@DisplayName("decode skips entries with no separator")
|
|
void skipsNoSeparator() {
|
|
String wire = "abc|" + U1 + ";right";
|
|
Map<UUID, String> back = FurnitureSeatSyncCodec.decode(wire);
|
|
assertEquals(1, back.size());
|
|
assertEquals("right", back.get(U1));
|
|
}
|
|
|
|
@Test
|
|
@DisplayName("decode skips entries starting with separator")
|
|
void skipsLeadingSeparator() {
|
|
String wire = ";seat|" + U1 + ";right";
|
|
Map<UUID, String> back = FurnitureSeatSyncCodec.decode(wire);
|
|
assertEquals(1, back.size());
|
|
assertEquals("right", back.get(U1));
|
|
}
|
|
}
|