You've already forked Arcturus-Morningstar-Extended
mirror of
https://github.com/duckietm/Arcturus-Morningstar-Extended.git
synced 2026-06-19 06:56:19 +00:00
fix(session): separate forced disconnects from resume parking
Add a forced dispose path for bans, RCON disconnects, logout/account endpoints, plugin-cancelled login, duplicate login replacement, and late MAC-ban enforcement. Soft channel closes still park a session for reconnect, while security-driven closes now bypass session resume. Also null-guard client/channel disposal and cover the contract with focused tests.
This commit is contained in:
@@ -149,6 +149,10 @@ public class GameClient {
|
||||
}
|
||||
|
||||
public void dispose() {
|
||||
this.dispose(true);
|
||||
}
|
||||
|
||||
public void dispose(boolean allowSessionResume) {
|
||||
try {
|
||||
this.channel.close();
|
||||
|
||||
@@ -161,7 +165,7 @@ public class GameClient {
|
||||
// appena ripristinata (era la causa del "Bye"/kick al 2° reconnect).
|
||||
if (this.habbo.getClient() == this && this.habbo.isOnline()) {
|
||||
// Try to park the habbo in the grace period instead of immediate disconnect
|
||||
boolean parked = SessionResumeManager.getInstance().parkHabbo(this.habbo, this.ssoTicket);
|
||||
boolean parked = allowSessionResume && SessionResumeManager.getInstance().parkHabbo(this.habbo, this.ssoTicket);
|
||||
|
||||
if (!parked) {
|
||||
// No grace period configured — immediate disconnect as before
|
||||
@@ -177,4 +181,4 @@ public class GameClient {
|
||||
LOGGER.error("Caught exception", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -43,14 +43,34 @@ public class GameClientManager {
|
||||
|
||||
|
||||
public void disposeClient(GameClient client) {
|
||||
this.disposeClient(client.getChannel());
|
||||
if (client == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.disposeClient(client.getChannel(), true);
|
||||
}
|
||||
|
||||
public void forceDisposeClient(GameClient client) {
|
||||
if (client == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.disposeClient(client.getChannel(), false);
|
||||
}
|
||||
|
||||
private void disposeClient(Channel channel) {
|
||||
this.disposeClient(channel, true);
|
||||
}
|
||||
|
||||
private void disposeClient(Channel channel, boolean allowSessionResume) {
|
||||
if (channel == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
GameClient client = channel.attr(GameServerAttributes.CLIENT).get();
|
||||
|
||||
if (client != null) {
|
||||
client.dispose();
|
||||
client.dispose(allowSessionResume);
|
||||
}
|
||||
channel.deregister();
|
||||
channel.attr(GameServerAttributes.CLIENT).set(null);
|
||||
@@ -190,4 +210,4 @@ public class GameClientManager {
|
||||
CFKeepAlive();
|
||||
}, 30000);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -111,7 +111,7 @@ public class HabboManager {
|
||||
habbo = this.cloneCheck(userId);
|
||||
if (habbo != null) {
|
||||
habbo.alert(Emulator.getTexts().getValue("loggedin.elsewhere"));
|
||||
Emulator.getGameServer().getGameClientManager().disposeClient(habbo.getClient());
|
||||
Emulator.getGameServer().getGameClientManager().forceDisposeClient(habbo.getClient());
|
||||
habbo = null;
|
||||
}
|
||||
|
||||
|
||||
@@ -37,10 +37,10 @@ public class MachineIDEvent extends MessageHandler {
|
||||
// SSO ticket), so Habbo.connect() may have skipped the MAC-ban check for
|
||||
// lack of a machineId. Enforce it now that the fingerprint is known.
|
||||
if (Emulator.getGameEnvironment().getModToolManager().hasMACBan(this.client)) {
|
||||
Emulator.getGameServer().getGameClientManager().disposeClient(this.client);
|
||||
Emulator.getGameServer().getGameClientManager().forceDisposeClient(this.client);
|
||||
}
|
||||
}
|
||||
|
||||
LOGGER.debug("Setting client MachineId to {}", storedMachineId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -306,7 +306,7 @@ public class SecureLoginEvent extends MessageHandler {
|
||||
Emulator.getPluginManager().fireEvent(userLoginEvent);
|
||||
|
||||
if(userLoginEvent.isCancelled()) {
|
||||
Emulator.getGameServer().getGameClientManager().disposeClient(this.client);
|
||||
Emulator.getGameServer().getGameClientManager().forceDisposeClient(this.client);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -29,7 +29,7 @@ public class DisconnectUser extends RCONMessage<DisconnectUser.DisconnectUserJSO
|
||||
return;
|
||||
}
|
||||
|
||||
Emulator.getGameServer().getGameClientManager().disposeClient(target.getClient());
|
||||
Emulator.getGameServer().getGameClientManager().forceDisposeClient(target.getClient());
|
||||
this.message = Emulator.getTexts().getValue("commands.succes.cmd_disconnect.disconnected").replace("%user%", target.getHabboInfo().getUsername());
|
||||
}
|
||||
|
||||
@@ -40,4 +40,4 @@ public class DisconnectUser extends RCONMessage<DisconnectUser.DisconnectUserJSO
|
||||
|
||||
public String username;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -467,7 +467,7 @@ final class AccountChangeEndpoints {
|
||||
com.eu.habbo.habbohotel.users.Habbo habbo =
|
||||
Emulator.getGameServer().getGameClientManager().getHabbo(userId);
|
||||
if (habbo != null && habbo.getClient() != null) {
|
||||
Emulator.getGameServer().getGameClientManager().disposeClient(habbo.getClient());
|
||||
Emulator.getGameServer().getGameClientManager().forceDisposeClient(habbo.getClient());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -69,7 +69,7 @@ final class SessionEndpoints {
|
||||
com.eu.habbo.habbohotel.users.Habbo habbo =
|
||||
Emulator.getGameServer().getGameClientManager().getHabbo(userId);
|
||||
if (habbo != null && habbo.getClient() != null) {
|
||||
Emulator.getGameServer().getGameClientManager().disposeClient(habbo.getClient());
|
||||
Emulator.getGameServer().getGameClientManager().forceDisposeClient(habbo.getClient());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
package com.eu.habbo.habbohotel.gameclients;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
|
||||
|
||||
class GameClientManagerContractTest {
|
||||
|
||||
@Test
|
||||
void exposesExplicitForcedDisposePath() {
|
||||
assertDoesNotThrow(() -> GameClient.class.getDeclaredMethod("dispose", boolean.class));
|
||||
assertDoesNotThrow(() -> GameClientManager.class.getDeclaredMethod("forceDisposeClient", GameClient.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void disposeMethodsIgnoreNullClient() {
|
||||
GameClientManager manager = new GameClientManager();
|
||||
|
||||
assertDoesNotThrow(() -> manager.disposeClient(null));
|
||||
assertDoesNotThrow(() -> manager.forceDisposeClient(null));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user