You've already forked Arcturus-Morningstar-Extended
mirror of
https://github.com/duckietm/Arcturus-Morningstar-Extended.git
synced 2026-06-19 15:06:19 +00:00
fix(commands): enforce staff target ceilings
This commit is contained in:
@@ -32,6 +32,11 @@ public class AlertCommand extends Command {
|
||||
Habbo habbo = Emulator.getGameEnvironment().getHabboManager().getHabbo(targetUsername);
|
||||
|
||||
if (habbo != null) {
|
||||
if (!CommandTargetGuard.canTarget(gameClient.getHabbo(), habbo)) {
|
||||
gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.error.cmd_ban.target_rank_higher"), RoomChatMessageBubbles.ALERT);
|
||||
return true;
|
||||
}
|
||||
|
||||
habbo.alert(message + "\r\n -" + gameClient.getHabbo().getHabboInfo().getUsername());
|
||||
gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.succes.cmd_alert.message_send").replace("%user%", targetUsername), RoomChatMessageBubbles.ALERT);
|
||||
} else {
|
||||
|
||||
@@ -60,7 +60,7 @@ public class BanCommand extends Command {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (target.getRank().getId() >= gameClient.getHabbo().getHabboInfo().getRank().getId()) {
|
||||
if (!CommandTargetGuard.canTarget(gameClient.getHabbo(), target)) {
|
||||
gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.error.cmd_ban.target_rank_higher"), RoomChatMessageBubbles.ALERT);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
package com.eu.habbo.habbohotel.commands;
|
||||
|
||||
import com.eu.habbo.Emulator;
|
||||
import com.eu.habbo.habbohotel.permissions.Rank;
|
||||
import com.eu.habbo.habbohotel.users.Habbo;
|
||||
import com.eu.habbo.habbohotel.users.HabboInfo;
|
||||
|
||||
final class CommandTargetGuard {
|
||||
private CommandTargetGuard() {
|
||||
}
|
||||
|
||||
static boolean canTarget(Habbo moderator, Habbo target) {
|
||||
return target != null && canTarget(moderator, target.getHabboInfo());
|
||||
}
|
||||
|
||||
static boolean canTarget(Habbo moderator, HabboInfo target) {
|
||||
if (moderator == null || target == null || moderator.getHabboInfo().getId() == target.getId()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
int moderatorRankId = moderator.getHabboInfo().getRank().getId();
|
||||
int targetRankId = target.getRank().getId();
|
||||
|
||||
return targetRankId < moderatorRankId || isCoreRank(moderatorRankId) && targetRankId <= moderatorRankId;
|
||||
}
|
||||
|
||||
static boolean canAssignRank(Habbo moderator, Rank rank) {
|
||||
if (moderator == null || rank == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
int moderatorRankId = moderator.getHabboInfo().getRank().getId();
|
||||
int targetRankId = rank.getId();
|
||||
|
||||
return targetRankId < moderatorRankId || isCoreRank(moderatorRankId) && targetRankId <= moderatorRankId;
|
||||
}
|
||||
|
||||
private static boolean isCoreRank(int rankId) {
|
||||
int highestRankId = Emulator.getGameEnvironment().getPermissionsManager().getAllRanks().stream()
|
||||
.mapToInt(Rank::getId)
|
||||
.max()
|
||||
.orElse(0);
|
||||
|
||||
return highestRankId > 0 && rankId >= highestRankId;
|
||||
}
|
||||
}
|
||||
@@ -29,7 +29,7 @@ public class DisconnectCommand extends Command {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (target.getHabboInfo().getRank().getId() > gameClient.getHabbo().getHabboInfo().getRank().getId()) {
|
||||
if (!CommandTargetGuard.canTarget(gameClient.getHabbo(), target)) {
|
||||
gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.error.cmd_disconnect.higher_rank"), RoomChatMessageBubbles.ALERT);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -47,6 +47,11 @@ public class GivePrefixCommand extends Command {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!CommandTargetGuard.canTarget(gameClient.getHabbo(), target)) {
|
||||
gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.error.cmd_ban.target_rank_higher"), RoomChatMessageBubbles.ALERT);
|
||||
return true;
|
||||
}
|
||||
|
||||
UserPrefix prefix = new UserPrefix(target.getHabboInfo().getId(), text, color, icon, effect);
|
||||
prefix.run();
|
||||
target.getInventory().getPrefixesComponent().addPrefix(prefix);
|
||||
|
||||
@@ -36,7 +36,7 @@ public class GiveRankCommand extends Command {
|
||||
}
|
||||
|
||||
if (rank != null) {
|
||||
if (rank.getId() > gameClient.getHabbo().getHabboInfo().getRank().getId()) {
|
||||
if (!CommandTargetGuard.canAssignRank(gameClient.getHabbo(), rank)) {
|
||||
gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.error.cmd_give_rank.higher").replace("%username%", params[1]).replace("%id%", rank.getName()), RoomChatMessageBubbles.ALERT);
|
||||
return true;
|
||||
}
|
||||
@@ -44,7 +44,7 @@ public class GiveRankCommand extends Command {
|
||||
HabboInfo habbo = HabboManager.getOfflineHabboInfo(params[1]);
|
||||
|
||||
if (habbo != null) {
|
||||
if (habbo.getRank().getId() > gameClient.getHabbo().getHabboInfo().getRank().getId()) {
|
||||
if (!CommandTargetGuard.canTarget(gameClient.getHabbo(), habbo)) {
|
||||
gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.error.cmd_give_rank.higher.other").replace("%username%", params[1]).replace("%id%", rank.getName()), RoomChatMessageBubbles.ALERT);
|
||||
return true;
|
||||
}
|
||||
@@ -63,4 +63,4 @@ public class GiveRankCommand extends Command {
|
||||
gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.errors.cmd_give_rank.not_found").replace("%id%", params[2]).replace("%username%", params[1]), RoomChatMessageBubbles.ALERT);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -47,7 +47,7 @@ public class IPBanCommand extends Command {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (habbo.getRank().getId() >= gameClient.getHabbo().getHabboInfo().getRank().getId()) {
|
||||
if (!CommandTargetGuard.canTarget(gameClient.getHabbo(), habbo)) {
|
||||
gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.error.cmd_ban.target_rank_higher"), RoomChatMessageBubbles.ALERT);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -43,7 +43,7 @@ public class MachineBanCommand extends Command {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (habbo.getRank().getId() >= gameClient.getHabbo().getHabboInfo().getRank().getId()) {
|
||||
if (!CommandTargetGuard.canTarget(gameClient.getHabbo(), habbo)) {
|
||||
gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.error.cmd_ban.target_rank_higher"), RoomChatMessageBubbles.ALERT);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -29,6 +29,11 @@ public class MuteCommand extends Command {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!CommandTargetGuard.canTarget(gameClient.getHabbo(), habbo)) {
|
||||
gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.error.cmd_ban.target_rank_higher"), RoomChatMessageBubbles.ALERT);
|
||||
return true;
|
||||
}
|
||||
|
||||
int duration = Integer.MAX_VALUE;
|
||||
|
||||
if (params.length == 3) {
|
||||
|
||||
@@ -31,6 +31,11 @@ public class RemovePrefixCommand extends Command {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!CommandTargetGuard.canTarget(gameClient.getHabbo(), target)) {
|
||||
gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.error.cmd_ban.target_rank_higher"), RoomChatMessageBubbles.ALERT);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (prefixIdStr.equalsIgnoreCase("all")) {
|
||||
List<UserPrefix> prefixes = target.getInventory().getPrefixesComponent().getPrefixes();
|
||||
for (UserPrefix prefix : prefixes) {
|
||||
|
||||
@@ -41,7 +41,7 @@ public class SuperbanCommand extends Command {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (habbo.getRank().getId() >= gameClient.getHabbo().getHabboInfo().getRank().getId()) {
|
||||
if (!CommandTargetGuard.canTarget(gameClient.getHabbo(), habbo)) {
|
||||
gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.error.cmd_ban.target_rank_higher"), RoomChatMessageBubbles.ALERT);
|
||||
return true;
|
||||
}
|
||||
@@ -56,4 +56,4 @@ public class SuperbanCommand extends Command {
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,6 +23,11 @@ public class UnmuteCommand extends Command {
|
||||
gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.error.cmd_unmute.not_found").replace("%user%", params[1]), RoomChatMessageBubbles.ALERT);
|
||||
return true;
|
||||
} else {
|
||||
if (!CommandTargetGuard.canTarget(gameClient.getHabbo(), habbo)) {
|
||||
gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.error.cmd_ban.target_rank_higher"), RoomChatMessageBubbles.ALERT);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!habbo.getHabboStats().allowTalk() || (habbo.getHabboInfo().getCurrentRoom() != null && habbo.getHabboInfo().getCurrentRoom().isMuted(habbo))) {
|
||||
if (!habbo.getHabboStats().allowTalk()) {
|
||||
habbo.unMute();
|
||||
|
||||
+64
@@ -0,0 +1,64 @@
|
||||
package com.eu.habbo.habbohotel.commands;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.List;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
class CommandTargetGuardContractTest {
|
||||
@Test
|
||||
void highRiskUserCommandsUseCentralTargetGuard() throws Exception {
|
||||
Path base = Path.of("src/main/java/com/eu/habbo/habbohotel/commands");
|
||||
|
||||
for (String command : List.of(
|
||||
"AlertCommand.java",
|
||||
"BanCommand.java",
|
||||
"DisconnectCommand.java",
|
||||
"GivePrefixCommand.java",
|
||||
"GiveRankCommand.java",
|
||||
"IPBanCommand.java",
|
||||
"MachineBanCommand.java",
|
||||
"MuteCommand.java",
|
||||
"RemovePrefixCommand.java",
|
||||
"SuperbanCommand.java",
|
||||
"UnmuteCommand.java"
|
||||
)) {
|
||||
String source = Files.readString(base.resolve(command));
|
||||
|
||||
assertTrue(source.contains("CommandTargetGuard.canTarget"),
|
||||
command + " must use the central command target guard for staff/core rank handling");
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void rankGrantingUsesCentralAssignmentGuard() throws Exception {
|
||||
String source = Files.readString(Path.of("src/main/java/com/eu/habbo/habbohotel/commands/GiveRankCommand.java"));
|
||||
|
||||
assertTrue(source.contains("CommandTargetGuard.canAssignRank"),
|
||||
"GiveRankCommand must guard the assigned rank with the same core-rank semantics");
|
||||
}
|
||||
|
||||
@Test
|
||||
void targetGuardKeepsCorePeerOverrideCentralized() throws Exception {
|
||||
String source = Files.readString(Path.of("src/main/java/com/eu/habbo/habbohotel/commands/CommandTargetGuard.java"));
|
||||
String rule = "targetRankId < moderatorRankId || isCoreRank(moderatorRankId) && targetRankId <= moderatorRankId";
|
||||
|
||||
assertTrue(countOccurrences(source, rule) >= 2,
|
||||
"non-core command users must only target lower ranks while the highest/core rank may target peer ranks");
|
||||
}
|
||||
|
||||
private static int countOccurrences(String source, String needle) {
|
||||
int count = 0;
|
||||
int index = 0;
|
||||
|
||||
while ((index = source.indexOf(needle, index)) >= 0) {
|
||||
count++;
|
||||
index += needle.length();
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user