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
Merge pull request #229 from simoleo89/fix/commands-inputs
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);
|
Habbo habbo = Emulator.getGameEnvironment().getHabboManager().getHabbo(targetUsername);
|
||||||
|
|
||||||
if (habbo != null) {
|
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());
|
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);
|
gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.succes.cmd_alert.message_send").replace("%user%", targetUsername), RoomChatMessageBubbles.ALERT);
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -60,7 +60,7 @@ public class BanCommand extends Command {
|
|||||||
return true;
|
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);
|
gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.error.cmd_ban.target_rank_higher"), RoomChatMessageBubbles.ALERT);
|
||||||
return true;
|
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;
|
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);
|
gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.error.cmd_disconnect.higher_rank"), RoomChatMessageBubbles.ALERT);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -47,6 +47,11 @@ public class GivePrefixCommand extends Command {
|
|||||||
return true;
|
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);
|
UserPrefix prefix = new UserPrefix(target.getHabboInfo().getId(), text, color, icon, effect);
|
||||||
prefix.run();
|
prefix.run();
|
||||||
target.getInventory().getPrefixesComponent().addPrefix(prefix);
|
target.getInventory().getPrefixesComponent().addPrefix(prefix);
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ public class GiveRankCommand extends Command {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (rank != null) {
|
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);
|
gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.error.cmd_give_rank.higher").replace("%username%", params[1]).replace("%id%", rank.getName()), RoomChatMessageBubbles.ALERT);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -44,7 +44,7 @@ public class GiveRankCommand extends Command {
|
|||||||
HabboInfo habbo = HabboManager.getOfflineHabboInfo(params[1]);
|
HabboInfo habbo = HabboManager.getOfflineHabboInfo(params[1]);
|
||||||
|
|
||||||
if (habbo != null) {
|
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);
|
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;
|
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);
|
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;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ public class IPBanCommand extends Command {
|
|||||||
return true;
|
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);
|
gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.error.cmd_ban.target_rank_higher"), RoomChatMessageBubbles.ALERT);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ public class MachineBanCommand extends Command {
|
|||||||
return true;
|
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);
|
gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.error.cmd_ban.target_rank_higher"), RoomChatMessageBubbles.ALERT);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,6 +29,11 @@ public class MuteCommand extends Command {
|
|||||||
return true;
|
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;
|
int duration = Integer.MAX_VALUE;
|
||||||
|
|
||||||
if (params.length == 3) {
|
if (params.length == 3) {
|
||||||
|
|||||||
@@ -31,6 +31,11 @@ public class RemovePrefixCommand extends Command {
|
|||||||
return true;
|
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")) {
|
if (prefixIdStr.equalsIgnoreCase("all")) {
|
||||||
List<UserPrefix> prefixes = target.getInventory().getPrefixesComponent().getPrefixes();
|
List<UserPrefix> prefixes = target.getInventory().getPrefixesComponent().getPrefixes();
|
||||||
for (UserPrefix prefix : prefixes) {
|
for (UserPrefix prefix : prefixes) {
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ public class SuperbanCommand extends Command {
|
|||||||
return true;
|
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);
|
gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.error.cmd_ban.target_rank_higher"), RoomChatMessageBubbles.ALERT);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -56,4 +56,4 @@ public class SuperbanCommand extends Command {
|
|||||||
|
|
||||||
return true;
|
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);
|
gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.error.cmd_unmute.not_found").replace("%user%", params[1]), RoomChatMessageBubbles.ALERT);
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} 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.getHabboInfo().getCurrentRoom() != null && habbo.getHabboInfo().getCurrentRoom().isMuted(habbo))) {
|
||||||
if (!habbo.getHabboStats().allowTalk()) {
|
if (!habbo.getHabboStats().allowTalk()) {
|
||||||
habbo.unMute();
|
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