From da63439d53706f5902793519a754501d3d1dad78 Mon Sep 17 00:00:00 2001 From: medievalshell Date: Sun, 31 May 2026 00:03:39 +0200 Subject: [PATCH] fix(bans): persist client machine fingerprint so machine/super bans work The Nitro client already sends a strong machine fingerprint (Thumbmark, "IID-") via the UniqueID packet (header 2490 -> MachineIDEvent), but the emulator only stored it on the GameClient and never copied it onto the Habbo's HabboInfo, so it was never written to users.machine_id. As a result machine/super bans (which read users.machine_id) matched nobody. - MachineIDEvent: when the fingerprint arrives and the Habbo is already loaded, copy it onto HabboInfo and persist (run the Habbo save). - SecureLoginEvent: if the fingerprint arrived before login, copy it onto HabboInfo right before the login save. This makes machine/super bans effective without changing the client. --- .../messages/incoming/handshake/MachineIDEvent.java | 10 ++++++++++ .../messages/incoming/handshake/SecureLoginEvent.java | 6 ++++++ 2 files changed, 16 insertions(+) diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/handshake/MachineIDEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/handshake/MachineIDEvent.java index 477fc3c6..64696bf7 100644 --- a/Emulator/src/main/java/com/eu/habbo/messages/incoming/handshake/MachineIDEvent.java +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/handshake/MachineIDEvent.java @@ -1,5 +1,6 @@ package com.eu.habbo.messages.incoming.handshake; +import com.eu.habbo.Emulator; import com.eu.habbo.messages.NoAuthMessage; import com.eu.habbo.messages.incoming.MessageHandler; import org.slf4j.Logger; @@ -24,6 +25,15 @@ public class MachineIDEvent extends MessageHandler { this.client.setMachineId(storedMachineId); + // Persist the machine fingerprint onto the user so machine/super bans can + // target it (createOfflineUserBan copies users.machine_id). The Nitro client + // sends this UniqueID packet right after the SSO ticket, so the Habbo is + // normally already loaded by the time we get here. + if (!storedMachineId.isEmpty() && this.client.getHabbo() != null && this.client.getHabbo().getHabboInfo() != null) { + this.client.getHabbo().getHabboInfo().setMachineID(storedMachineId); + Emulator.getThreading().run(this.client.getHabbo()); + } + LOGGER.debug("Setting client MachineId to {}", storedMachineId); } } \ No newline at end of file diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/handshake/SecureLoginEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/handshake/SecureLoginEvent.java index 7c7dcf3c..cdebe27d 100644 --- a/Emulator/src/main/java/com/eu/habbo/messages/incoming/handshake/SecureLoginEvent.java +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/handshake/SecureLoginEvent.java @@ -161,6 +161,12 @@ public class SecureLoginEvent extends MessageHandler { throw new NullPointerException(habbo.getHabboInfo().getUsername() + " has a NON EXISTING RANK!"); } + // If the machine fingerprint already arrived (UniqueID before login), + // persist it so machine/super bans can target this user. + if (this.client.getMachineId() != null && !this.client.getMachineId().isEmpty()) { + this.client.getHabbo().getHabboInfo().setMachineID(this.client.getMachineId()); + } + Emulator.getThreading().run(habbo); Emulator.getGameEnvironment().getHabboManager().addHabbo(habbo); } catch (Exception e) {