diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/FurnitureTextProvider.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/FurnitureTextProvider.java index ae7e501b..b72823af 100644 --- a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/FurnitureTextProvider.java +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/FurnitureTextProvider.java @@ -69,15 +69,30 @@ public class FurnitureTextProvider { return Files.exists(legacy) ? legacy : null; } - /** Build a fresh sanitized index from the given entries and swap it in atomically. */ - public void reindex(List entries) { + /** + * Build a fresh sanitized index, swap it in atomically, and return the + * changed/added entries (sanitized) as the delta versus the previous index. + */ + public java.util.List reindex(java.util.List entries) { Map next = new HashMap<>(Math.max(16, entries.size() * 2)); for (FurnidataEntry e : entries) { String key = baseKey(e.classname()); if (key == null) continue; next.put(key, new FurniText(e.id(), e.type(), sanitize(e.name()), sanitize(e.description()))); } + + Map prev = this.index; + java.util.List delta = new java.util.ArrayList<>(); + for (Map.Entry en : next.entrySet()) { + FurniText cur = en.getValue(); + FurniText old = prev.get(en.getKey()); + if (old == null || !old.name().equals(cur.name()) || !old.description().equals(cur.description())) { + delta.add(new FurnidataEntry(cur.id(), en.getKey(), cur.type(), cur.name(), cur.description())); + } + } + this.index = next; // atomic reference swap + return delta; } /** Returns the sanitized display name for a DB classname, or null if absent/disabled. */ diff --git a/Emulator/src/test/java/com/eu/habbo/habbohotel/items/FurnitureTextProviderDeltaTest.java b/Emulator/src/test/java/com/eu/habbo/habbohotel/items/FurnitureTextProviderDeltaTest.java new file mode 100644 index 00000000..356a5498 --- /dev/null +++ b/Emulator/src/test/java/com/eu/habbo/habbohotel/items/FurnitureTextProviderDeltaTest.java @@ -0,0 +1,40 @@ +package com.eu.habbo.habbohotel.items; + +import org.junit.jupiter.api.Test; + +import java.util.List; + +import static org.junit.jupiter.api.Assertions.*; + +class FurnitureTextProviderDeltaTest { + + @Test + void firstReindexReturnsAllAsDelta() { + FurnitureTextProvider p = new FurnitureTextProvider(true); + List delta = p.reindex(List.of( + new FurnidataEntry(1, "chair", FurnitureType.FLOOR, "Chair", "Sit"))); + assertEquals(1, delta.size()); + assertEquals("Chair", delta.get(0).name()); + } + + @Test + void unchangedReindexReturnsEmptyDelta() { + FurnitureTextProvider p = new FurnitureTextProvider(true); + List first = List.of(new FurnidataEntry(1, "chair", FurnitureType.FLOOR, "Chair", "Sit")); + p.reindex(first); + List delta = p.reindex(first); + assertTrue(delta.isEmpty(), "no change => empty delta"); + } + + @Test + void changedNameAppearsInDeltaWithSanitizedValue() { + FurnitureTextProvider p = new FurnitureTextProvider(true); + p.reindex(List.of(new FurnidataEntry(1, "chair", FurnitureType.FLOOR, "Chair", "Sit"))); + List delta = p.reindex(List.of( + new FurnidataEntry(1, "chair", FurnitureType.FLOOR, "New %x%", "Sit"))); + assertEquals(1, delta.size()); + assertFalse(delta.get(0).name().contains("%"), "delta carries the sanitized name"); + assertEquals(1, delta.get(0).id()); + assertEquals(FurnitureType.FLOOR, delta.get(0).type()); + } +}