From 216078f62c00c8d369c14ede61f8e26f76d949c1 Mon Sep 17 00:00:00 2001 From: simoleo89 Date: Sat, 13 Jun 2026 16:14:04 +0200 Subject: [PATCH] fix(messages): silence duplicate packet aliases PacketNames reflects public static final packet constants and warns when two names share the same header. RequestCatalogIndexEvent is a legacy alias for the active Builders Club catalog index header, and InClientLinkComposer shares the NUX link payload/header. Keep those aliases available to existing code while removing them from the reflected packet-name set, and add a contract test so future public final packet names stay unique. --- .../eu/habbo/messages/incoming/Incoming.java | 2 +- .../eu/habbo/messages/outgoing/Outgoing.java | 2 +- .../messages/PacketNamesContractTest.java | 51 +++++++++++++++++++ 3 files changed, 53 insertions(+), 2 deletions(-) create mode 100644 Emulator/src/test/java/com/eu/habbo/messages/PacketNamesContractTest.java diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/Incoming.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/Incoming.java index 43ab4d44..3a0bdf1a 100644 --- a/Emulator/src/main/java/com/eu/habbo/messages/incoming/Incoming.java +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/Incoming.java @@ -83,7 +83,7 @@ public class Incoming { public static final int GuildAcceptMembershipEvent = 3386; public static final int RequestRecylerLogicEvent = 398; public static final int RequestGuildJoinEvent = 998; - public static final int RequestCatalogIndexEvent = 2529; + public static int RequestCatalogIndexEvent = 2529; public static final int BuildersClubQueryFurniCountEvent = 2529; public static final int BuildersClubPlaceRoomItemEvent = 1051; public static final int BuildersClubPlaceWallItemEvent = 462; diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/Outgoing.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/Outgoing.java index 4db4519d..c52ef526 100644 --- a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/Outgoing.java +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/Outgoing.java @@ -514,7 +514,7 @@ public class Outgoing { public final static int WiredOpenComposer = 1830; public final static int UnknownCatalogPageOfferComposer = 1889; public final static int NuxAlertComposer = 2023; - public final static int InClientLinkComposer = 2023; + public static int InClientLinkComposer = NuxAlertComposer; public final static int HotelViewExpiringCatalogPageCommposer = 2515; public final static int UnknownHabboWayQuizComposer = 2772; public final static int PetLevelUpdatedComposer = 2824; diff --git a/Emulator/src/test/java/com/eu/habbo/messages/PacketNamesContractTest.java b/Emulator/src/test/java/com/eu/habbo/messages/PacketNamesContractTest.java new file mode 100644 index 00000000..9c4b02c3 --- /dev/null +++ b/Emulator/src/test/java/com/eu/habbo/messages/PacketNamesContractTest.java @@ -0,0 +1,51 @@ +package com.eu.habbo.messages; + +import com.eu.habbo.messages.incoming.Incoming; +import com.eu.habbo.messages.outgoing.Outgoing; +import org.junit.jupiter.api.Test; + +import java.lang.reflect.Field; +import java.lang.reflect.Modifier; +import java.util.HashMap; +import java.util.Map; + +import static org.junit.jupiter.api.Assertions.assertTrue; + +class PacketNamesContractTest { + @Test + void incomingPacketNameIdsAreUnique() throws Exception { + assertPublicFinalPacketIdsAreUnique(Incoming.class); + } + + @Test + void outgoingPacketNameIdsAreUnique() throws Exception { + assertPublicFinalPacketIdsAreUnique(Outgoing.class); + } + + private static void assertPublicFinalPacketIdsAreUnique(Class packetClass) throws Exception { + Map seen = new HashMap<>(); + Map duplicates = new HashMap<>(); + + for (Field field : packetClass.getFields()) { + int modifiers = field.getModifiers(); + if (!Modifier.isPublic(modifiers) + || !Modifier.isStatic(modifiers) + || !Modifier.isFinal(modifiers) + || field.getType() != int.class) { + continue; + } + + int packetId = field.getInt(null); + if (packetId <= 0) { + continue; + } + + String previous = seen.putIfAbsent(packetId, field.getName()); + if (previous != null) { + duplicates.put(packetId, previous + " / " + field.getName()); + } + } + + assertTrue(duplicates.isEmpty(), packetClass.getSimpleName() + " has duplicate packet IDs: " + duplicates); + } +}