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 branch 'dev' into fix/wired-furni-selection-payloads
This commit is contained in:
@@ -166,6 +166,7 @@ public final class Emulator {
|
||||
Emulator.config.register("rcon.rate_limit.timeout_ms", "0");
|
||||
Emulator.config.register("rcon.execute_command.denied_permissions", "cmd_shutdown;cmd_give_rank");
|
||||
Emulator.config.register("rcon.execute_command.allowed_permissions", "");
|
||||
Emulator.config.register("rcon.max_payload_bytes", "65536");
|
||||
registerEarningsSettings();
|
||||
String hotelTimezoneId = Emulator.getConfig().getValue("hotel.timezone", java.time.ZoneId.systemDefault().getId());
|
||||
System.out.println(startupCard(hotelTimezoneId));
|
||||
|
||||
@@ -174,6 +174,14 @@ public class CatalogItem implements ISerialize, Runnable, Comparable<CatalogItem
|
||||
return this.offerId;
|
||||
}
|
||||
|
||||
public int getSearchOfferId() {
|
||||
if (this.offerId > 0) {
|
||||
return this.offerId;
|
||||
}
|
||||
|
||||
return haveOffer(this) ? this.id : -1;
|
||||
}
|
||||
|
||||
public boolean isLimited() {
|
||||
return this.limitedStack > 0;
|
||||
}
|
||||
|
||||
@@ -494,10 +494,11 @@ public class CatalogManager {
|
||||
item = new CatalogItem(set);
|
||||
page.addItem(item);
|
||||
|
||||
if (item.getOfferId() != -1) {
|
||||
page.addOfferId(item.getOfferId());
|
||||
int searchOfferId = item.getSearchOfferId();
|
||||
if (searchOfferId != -1) {
|
||||
page.addOfferId(searchOfferId);
|
||||
|
||||
this.offerDefs.put(item.getOfferId(), item.getId());
|
||||
this.offerDefs.put(searchOfferId, item.getId());
|
||||
}
|
||||
} else
|
||||
item.update(set);
|
||||
|
||||
@@ -58,6 +58,10 @@ public class MarketPlace {
|
||||
public static void takeBackItem(Habbo habbo, int offerId) {
|
||||
MarketPlaceOffer offer = habbo.getInventory().getOffer(offerId);
|
||||
|
||||
if (offer == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!Emulator.getPluginManager().fireEvent(new MarketPlaceItemCancelledEvent(offer)).isCancelled()) {
|
||||
takeBackItem(habbo, offer);
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -14,6 +14,7 @@ import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
public class GameClient {
|
||||
|
||||
@@ -24,6 +25,7 @@ public class GameClient {
|
||||
private final LatencyTracker latencyTracker;
|
||||
|
||||
private Habbo habbo;
|
||||
private final AtomicBoolean disposed = new AtomicBoolean(false);
|
||||
private boolean handshakeFinished;
|
||||
private String machineId = "";
|
||||
private String ssoTicket = "";
|
||||
@@ -153,6 +155,10 @@ public class GameClient {
|
||||
}
|
||||
|
||||
public void dispose(boolean allowSessionResume) {
|
||||
if (!this.disposed.compareAndSet(false, true)) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
this.channel.close();
|
||||
|
||||
|
||||
@@ -441,7 +441,7 @@ public class GuildManager {
|
||||
public int getGuildMembersCount(Guild guild, int page, int levelId, String query) {
|
||||
try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("SELECT COUNT(*) FROM guilds_members INNER JOIN users ON guilds_members.user_id = users.id WHERE guilds_members.guild_id = ? " + (rankQuery(levelId)) + " AND users.username LIKE ? ORDER BY level_id, member_since ASC")) {
|
||||
statement.setInt(1, guild.getId());
|
||||
statement.setString(2, "%" + query + "%");
|
||||
statement.setString(2, "%" + com.eu.habbo.util.SqlLikeEscaper.escape(query) + "%");
|
||||
|
||||
try (ResultSet set = statement.executeQuery()) {
|
||||
while (set.next()) {
|
||||
|
||||
@@ -45,7 +45,7 @@ public class Item implements ISerialize {
|
||||
}
|
||||
|
||||
public static boolean isPet(Item item) {
|
||||
return item.getName().toLowerCase().startsWith("a0 pet");
|
||||
return item != null && item.getName() != null && item.getName().toLowerCase().startsWith("a0 pet");
|
||||
}
|
||||
|
||||
public static boolean isBot(Item item) {
|
||||
@@ -121,26 +121,19 @@ public class Item implements ISerialize {
|
||||
this.customParams = set.getString("customparams");
|
||||
this.clothingOnWalk = set.getString("clothing_on_walk");
|
||||
|
||||
if (!set.getString("vending_ids").isEmpty()) {
|
||||
int[] vendingIds = ItemDataGuard.parsePositiveIntList(set.getString("vending_ids"));
|
||||
if (vendingIds.length > 0) {
|
||||
this.vendingItems = new TIntArrayList();
|
||||
String[] vendingIds = set.getString("vending_ids").replace(";", ",").replace(".", ",").split(",");
|
||||
for (String s : vendingIds) {
|
||||
this.vendingItems.add(Integer.parseInt(s.replace(" ", "")));
|
||||
for (int vendingId : vendingIds) {
|
||||
this.vendingItems.add(vendingId);
|
||||
}
|
||||
} else {
|
||||
this.vendingItems = new TIntArrayList();
|
||||
}
|
||||
|
||||
//if(this.interactionType.getType() == InteractionMultiHeight.class || this.interactionType.getType().isAssignableFrom(InteractionMultiHeight.class))
|
||||
{
|
||||
if (set.getString("multiheight").contains(";")) {
|
||||
String[] s = set.getString("multiheight").split(";");
|
||||
this.multiHeights = new double[s.length];
|
||||
|
||||
for (int i = 0; i < s.length; i++) {
|
||||
this.multiHeights[i] = Double.parseDouble(s[i]);
|
||||
}
|
||||
} else {
|
||||
this.multiHeights = new double[0];
|
||||
}
|
||||
this.multiHeights = ItemDataGuard.parseHeights(set.getString("multiheight"));
|
||||
}
|
||||
|
||||
this.rotations = 4;
|
||||
@@ -254,6 +247,10 @@ public class Item implements ISerialize {
|
||||
}
|
||||
|
||||
public int getRandomVendingItem() {
|
||||
if (this.vendingItems == null || this.vendingItems.isEmpty()) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return this.vendingItems.get(Emulator.getRandom().nextInt(this.vendingItems.size()));
|
||||
}
|
||||
|
||||
@@ -273,21 +270,23 @@ public class Item implements ISerialize {
|
||||
|
||||
@Override
|
||||
public void serialize(ServerMessage message) {
|
||||
message.appendString(this.type.code.toLowerCase());
|
||||
message.appendString(this.type == null ? "" : this.type.code.toLowerCase());
|
||||
|
||||
if (type == FurnitureType.BADGE) {
|
||||
message.appendString(this.customParams);
|
||||
message.appendString(ItemDataGuard.safeString(this.customParams));
|
||||
} else {
|
||||
message.appendInt(this.spriteId);
|
||||
|
||||
if (this.getName().contains("wallpaper_single") || this.getName().contains("floor_single") || this.getName().contains("landscape_single")) {
|
||||
message.appendString(this.name.split("_")[2]);
|
||||
String itemName = ItemDataGuard.safeString(this.getName());
|
||||
if (itemName.contains("wallpaper_single") || itemName.contains("floor_single") || itemName.contains("landscape_single")) {
|
||||
String[] nameParts = itemName.split("_");
|
||||
message.appendString(nameParts.length > 2 ? nameParts[2] : "");
|
||||
} else if (type == FurnitureType.ROBOT) {
|
||||
message.appendString(this.customParams);
|
||||
} else if (name.equalsIgnoreCase("poster")) {
|
||||
message.appendString(this.customParams);
|
||||
} else if (name.startsWith("SONG ")) {
|
||||
message.appendString(this.customParams);
|
||||
message.appendString(ItemDataGuard.safeString(this.customParams));
|
||||
} else if (itemName.equalsIgnoreCase("poster")) {
|
||||
message.appendString(ItemDataGuard.safeString(this.customParams));
|
||||
} else if (itemName.startsWith("SONG ")) {
|
||||
message.appendString(ItemDataGuard.safeString(this.customParams));
|
||||
} else {
|
||||
message.appendString("");
|
||||
}
|
||||
|
||||
@@ -0,0 +1,82 @@
|
||||
package com.eu.habbo.habbohotel.items;
|
||||
|
||||
final class ItemDataGuard {
|
||||
static final int MAX_EXTRA_DATA_LENGTH = 1000;
|
||||
|
||||
private ItemDataGuard() {
|
||||
}
|
||||
|
||||
static String safeString(String value) {
|
||||
return value == null ? "" : value;
|
||||
}
|
||||
|
||||
static String normalizeExtraData(String value) {
|
||||
String safe = safeString(value);
|
||||
return safe.length() > MAX_EXTRA_DATA_LENGTH ? safe.substring(0, MAX_EXTRA_DATA_LENGTH) : safe;
|
||||
}
|
||||
|
||||
static int parsePositiveInt(String value) {
|
||||
try {
|
||||
int parsed = Integer.parseInt(safeString(value).trim());
|
||||
return parsed > 0 ? parsed : 0;
|
||||
} catch (NumberFormatException e) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static int[] parsePositiveIntList(String value) {
|
||||
String safe = safeString(value).replace(";", ",").replace(".", ",");
|
||||
if (safe.isBlank()) {
|
||||
return new int[0];
|
||||
}
|
||||
|
||||
String[] parts = safe.split(",");
|
||||
int[] parsed = new int[parts.length];
|
||||
int count = 0;
|
||||
|
||||
for (String part : parts) {
|
||||
int id = parsePositiveInt(part);
|
||||
if (id > 0) {
|
||||
parsed[count++] = id;
|
||||
}
|
||||
}
|
||||
|
||||
if (count == parsed.length) {
|
||||
return parsed;
|
||||
}
|
||||
|
||||
int[] compact = new int[count];
|
||||
System.arraycopy(parsed, 0, compact, 0, count);
|
||||
return compact;
|
||||
}
|
||||
|
||||
static double[] parseHeights(String value) {
|
||||
String safe = safeString(value);
|
||||
if (safe.isBlank() || !safe.contains(";")) {
|
||||
return new double[0];
|
||||
}
|
||||
|
||||
String[] parts = safe.split(";");
|
||||
double[] parsed = new double[parts.length];
|
||||
int count = 0;
|
||||
|
||||
for (String part : parts) {
|
||||
try {
|
||||
double height = Double.parseDouble(part.trim());
|
||||
if (Double.isFinite(height)) {
|
||||
parsed[count++] = height;
|
||||
}
|
||||
} catch (NumberFormatException e) {
|
||||
// Ignore malformed DB values and keep the remaining heights usable.
|
||||
}
|
||||
}
|
||||
|
||||
if (count == parsed.length) {
|
||||
return parsed;
|
||||
}
|
||||
|
||||
double[] compact = new double[count];
|
||||
System.arraycopy(parsed, 0, compact, 0, count);
|
||||
return compact;
|
||||
}
|
||||
}
|
||||
@@ -566,6 +566,10 @@ public class ItemManager {
|
||||
|
||||
|
||||
public int calculateCrackState(int count, int max, Item baseItem) {
|
||||
if (count <= 0 || max <= 0 || baseItem == null || baseItem.getStateCount() <= 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return (int) Math.floor((1.0D / ((double) max / (double) count) * baseItem.getStateCount()));
|
||||
}
|
||||
|
||||
@@ -574,7 +578,8 @@ public class ItemManager {
|
||||
}
|
||||
|
||||
public Item getCrackableReward(int itemId) {
|
||||
return this.getItem(this.crackableRewards.get(itemId).getRandomReward());
|
||||
CrackableReward reward = this.crackableRewards.get(itemId);
|
||||
return reward == null ? null : this.getItem(reward.getRandomReward());
|
||||
}
|
||||
|
||||
|
||||
@@ -604,6 +609,12 @@ public class ItemManager {
|
||||
}
|
||||
|
||||
public HabboItem createItem(int habboId, Item item, int limitedStack, int limitedSells, String extraData) {
|
||||
if (habboId <= 0 || item == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
extraData = ItemDataGuard.normalizeExtraData(extraData);
|
||||
|
||||
try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement("INSERT INTO items (user_id, item_id, extra_data, limited_data) VALUES (?, ?, ?, ?)", Statement.RETURN_GENERATED_KEYS)) {
|
||||
statement.setInt(1, habboId);
|
||||
statement.setInt(2, item.getId());
|
||||
@@ -673,6 +684,12 @@ public class ItemManager {
|
||||
}
|
||||
|
||||
public HabboItem handleRecycle(Habbo habbo, String itemId) {
|
||||
int rewardItemId = ItemDataGuard.parsePositiveInt(itemId);
|
||||
if (habbo == null || habbo.getHabboInfo() == null || rewardItemId <= 0
|
||||
|| Emulator.getGameEnvironment().getCatalogManager().ecotronItem == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
String extradata = Calendar.getInstance().get(Calendar.DAY_OF_MONTH) + "-" + (Calendar.getInstance().get(Calendar.MONTH) + 1) + "-" + Calendar.getInstance().get(Calendar.YEAR);
|
||||
|
||||
HabboItem item = null;
|
||||
@@ -686,7 +703,7 @@ public class ItemManager {
|
||||
try (PreparedStatement preparedStatement = connection.prepareStatement("INSERT INTO items_presents (item_id, base_item_reward) VALUES (?, ?)")) {
|
||||
while (set.next() && item == null) {
|
||||
preparedStatement.setInt(1, set.getInt(1));
|
||||
preparedStatement.setInt(2, Integer.parseInt(itemId));
|
||||
preparedStatement.setInt(2, rewardItemId);
|
||||
preparedStatement.addBatch();
|
||||
item = new InteractionDefault(set.getInt(1), habbo.getHabboInfo().getId(), Emulator.getGameEnvironment().getCatalogManager().ecotronItem, extradata, 0, 0);
|
||||
}
|
||||
@@ -829,6 +846,10 @@ public class ItemManager {
|
||||
}
|
||||
|
||||
public HabboItem createGift(String username, Item item, String extraData, int limitedStack, int limitedSells) {
|
||||
if (username == null || username.isBlank() || item == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
Habbo habbo = Emulator.getGameEnvironment().getHabboManager().getHabbo(username);
|
||||
|
||||
int userId = 0;
|
||||
@@ -857,13 +878,13 @@ public class ItemManager {
|
||||
}
|
||||
|
||||
public HabboItem createGift(int userId, Item item, String extraData, int limitedStack, int limitedSells) {
|
||||
if (userId == 0)
|
||||
if (userId <= 0 || item == null)
|
||||
return null;
|
||||
|
||||
if (extraData.length() > 1000) {
|
||||
if (extraData != null && extraData.length() > ItemDataGuard.MAX_EXTRA_DATA_LENGTH) {
|
||||
LOGGER.error("Extradata exceeds maximum length of 1000 characters: {}", extraData);
|
||||
extraData = extraData.substring(0, 1000);
|
||||
}
|
||||
extraData = ItemDataGuard.normalizeExtraData(extraData);
|
||||
|
||||
HabboItem gift = this.createItem(userId, item, limitedStack, limitedSells, extraData);
|
||||
|
||||
@@ -879,7 +900,7 @@ public class ItemManager {
|
||||
}
|
||||
|
||||
public Item getItem(int itemId) {
|
||||
if (itemId < 0)
|
||||
if (itemId <= 0)
|
||||
return null;
|
||||
|
||||
return this.items.get(itemId);
|
||||
@@ -890,12 +911,16 @@ public class ItemManager {
|
||||
}
|
||||
|
||||
public Item getItem(String itemName) {
|
||||
if (itemName == null || itemName.isBlank()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
TIntObjectIterator<Item> item = this.items.iterator();
|
||||
|
||||
for (int i = this.items.size(); i-- > 0; ) {
|
||||
try {
|
||||
item.advance();
|
||||
if (item.value().getName().equalsIgnoreCase(itemName)) {
|
||||
if (item.value() != null && item.value().getName() != null && item.value().getName().equalsIgnoreCase(itemName)) {
|
||||
return item.value();
|
||||
}
|
||||
} catch (NoSuchElementException e) {
|
||||
|
||||
+6
-26
@@ -2,6 +2,7 @@ package com.eu.habbo.habbohotel.items.interactions;
|
||||
|
||||
import com.eu.habbo.Emulator;
|
||||
import com.eu.habbo.habbohotel.items.Item;
|
||||
import com.eu.habbo.habbohotel.items.interactions.wired.WiredInputGuard;
|
||||
import com.eu.habbo.habbohotel.items.interactions.wired.WiredSettings;
|
||||
import com.eu.habbo.habbohotel.rooms.Room;
|
||||
import com.eu.habbo.habbohotel.rooms.RoomUnit;
|
||||
@@ -230,39 +231,18 @@ public abstract class InteractionWired extends InteractionDefault {
|
||||
|
||||
public static WiredSettings readSettings(ClientMessage packet, boolean isEffect)
|
||||
{
|
||||
int intParamCount = packet.readInt();
|
||||
if (intParamCount < 0 || intParamCount > 100) {
|
||||
throw new IllegalArgumentException("Invalid intParamCount: " + intParamCount);
|
||||
}
|
||||
int[] intParams = new int[intParamCount];
|
||||
|
||||
for(int i = 0; i < intParamCount; i++)
|
||||
{
|
||||
intParams[i] = packet.readInt();
|
||||
}
|
||||
|
||||
String stringParam = packet.readString();
|
||||
|
||||
int itemCount = packet.readInt();
|
||||
int selectionLimit = Emulator.getConfig() != null ? Emulator.getConfig().getInt("hotel.wired.furni.selection.count", 5) : 5;
|
||||
if (itemCount < 0 || itemCount > selectionLimit * 20) {
|
||||
throw new IllegalArgumentException("Invalid itemCount: " + itemCount + " exceeds maximum allowed limit");
|
||||
}
|
||||
int[] itemIds = new int[itemCount];
|
||||
|
||||
for(int i = 0; i < itemCount; i++)
|
||||
{
|
||||
itemIds[i] = packet.readInt();
|
||||
}
|
||||
int[] intParams = WiredInputGuard.readIntParams(packet);
|
||||
String stringParam = WiredInputGuard.readStringParam(packet);
|
||||
int[] itemIds = WiredInputGuard.readFurniIds(packet);
|
||||
|
||||
WiredSettings settings = new WiredSettings(intParams, stringParam, itemIds, -1);
|
||||
|
||||
if(isEffect)
|
||||
{
|
||||
settings.setDelay(packet.readInt());
|
||||
settings.setDelay(WiredInputGuard.normalizeDelay(packet.readInt()));
|
||||
}
|
||||
|
||||
settings.setStuffTypeSelectionCode(packet.readInt());
|
||||
settings.setStuffTypeSelectionCode(WiredInputGuard.normalizeStuffSelectionCode(packet.readInt()));
|
||||
return settings;
|
||||
}
|
||||
}
|
||||
|
||||
+90
@@ -0,0 +1,90 @@
|
||||
package com.eu.habbo.habbohotel.items.interactions.wired;
|
||||
|
||||
import com.eu.habbo.Emulator;
|
||||
import com.eu.habbo.messages.ClientMessage;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
public final class WiredInputGuard {
|
||||
public static final int MAX_INT_PARAMS = 100;
|
||||
public static final int MAX_STRING_PARAM_LENGTH = 1024;
|
||||
public static final int MAX_ABSOLUTE_FURNI_IDS = 100;
|
||||
public static final int DEFAULT_MAX_DELAY = 20;
|
||||
public static final int MAX_ABSOLUTE_DELAY = 3600;
|
||||
public static final int MIN_STUFF_SELECTION_CODE = -1;
|
||||
public static final int MAX_STUFF_SELECTION_CODE = 2;
|
||||
|
||||
private WiredInputGuard() {
|
||||
}
|
||||
|
||||
public static int[] readIntParams(ClientMessage packet) {
|
||||
int count = packet.readInt();
|
||||
if (count < 0 || count > MAX_INT_PARAMS) {
|
||||
throw new IllegalArgumentException("Invalid wired int param count");
|
||||
}
|
||||
|
||||
int[] values = new int[count];
|
||||
for (int i = 0; i < count; i++) {
|
||||
values[i] = packet.readInt();
|
||||
}
|
||||
return values;
|
||||
}
|
||||
|
||||
public static String readStringParam(ClientMessage packet) {
|
||||
String value = packet.readString();
|
||||
if (value == null || value.isEmpty()) {
|
||||
return "";
|
||||
}
|
||||
|
||||
return value.length() > MAX_STRING_PARAM_LENGTH
|
||||
? value.substring(0, MAX_STRING_PARAM_LENGTH)
|
||||
: value;
|
||||
}
|
||||
|
||||
public static int[] readFurniIds(ClientMessage packet) {
|
||||
int count = packet.readInt();
|
||||
int maxCount = maxFurniSelectionCount();
|
||||
if (count < 0 || count > maxCount) {
|
||||
throw new IllegalArgumentException("Invalid wired furni selection count");
|
||||
}
|
||||
|
||||
int[] values = new int[count];
|
||||
int accepted = 0;
|
||||
for (int i = 0; i < count; i++) {
|
||||
int itemId = packet.readInt();
|
||||
if (itemId > 0) {
|
||||
values[accepted++] = itemId;
|
||||
}
|
||||
}
|
||||
|
||||
return accepted == values.length ? values : Arrays.copyOf(values, accepted);
|
||||
}
|
||||
|
||||
public static int normalizeDelay(int delay) {
|
||||
return Math.max(0, Math.min(delay, maxDelay()));
|
||||
}
|
||||
|
||||
public static int normalizeStuffSelectionCode(int code) {
|
||||
if (code < MIN_STUFF_SELECTION_CODE || code > MAX_STUFF_SELECTION_CODE) {
|
||||
return MIN_STUFF_SELECTION_CODE;
|
||||
}
|
||||
|
||||
return code;
|
||||
}
|
||||
|
||||
public static int maxFurniSelectionCount() {
|
||||
int selectionLimit = Emulator.getConfig() != null
|
||||
? Emulator.getConfig().getInt("hotel.wired.furni.selection.count", 5)
|
||||
: 5;
|
||||
selectionLimit = Math.max(1, selectionLimit);
|
||||
return Math.min(MAX_ABSOLUTE_FURNI_IDS, selectionLimit * 20);
|
||||
}
|
||||
|
||||
public static int maxDelay() {
|
||||
int configured = Emulator.getConfig() != null
|
||||
? Emulator.getConfig().getInt("hotel.wired.max_delay", DEFAULT_MAX_DELAY)
|
||||
: DEFAULT_MAX_DELAY;
|
||||
configured = Math.max(0, configured);
|
||||
return Math.min(MAX_ABSOLUTE_DELAY, configured);
|
||||
}
|
||||
}
|
||||
+48
@@ -0,0 +1,48 @@
|
||||
package com.eu.habbo.habbohotel.items.interactions.wired;
|
||||
|
||||
import com.eu.habbo.habbohotel.rooms.Room;
|
||||
import com.eu.habbo.habbohotel.users.HabboItem;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public final class WiredLegacyDataGuard {
|
||||
public static final int DEFAULT_MAX_DELAY = 20;
|
||||
|
||||
private WiredLegacyDataGuard() {
|
||||
}
|
||||
|
||||
public static int parseDelay(String value) {
|
||||
try {
|
||||
int parsed = Integer.parseInt(value == null ? "" : value.trim());
|
||||
return Math.max(0, Math.min(parsed, DEFAULT_MAX_DELAY));
|
||||
} catch (NumberFormatException e) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
public static List<HabboItem> parseRoomItems(String value, Room room) {
|
||||
List<HabboItem> items = new ArrayList<>();
|
||||
if (room == null || value == null || value.isBlank()) {
|
||||
return items;
|
||||
}
|
||||
|
||||
for (String part : value.split(";")) {
|
||||
try {
|
||||
int itemId = Integer.parseInt(part.trim());
|
||||
if (itemId <= 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
HabboItem item = room.getHabboItem(itemId);
|
||||
if (item != null) {
|
||||
items.add(item);
|
||||
}
|
||||
} catch (NumberFormatException e) {
|
||||
// Ignore malformed legacy ids and keep loading the remaining items.
|
||||
}
|
||||
}
|
||||
|
||||
return items;
|
||||
}
|
||||
}
|
||||
+38
@@ -0,0 +1,38 @@
|
||||
package com.eu.habbo.habbohotel.items.interactions.wired;
|
||||
|
||||
import com.eu.habbo.Emulator;
|
||||
|
||||
public final class WiredNumericInputGuard {
|
||||
public static final int DEFAULT_MAX_REWARD_AMOUNT = 1000;
|
||||
public static final int DEFAULT_MAX_RESPECT_AMOUNT = 100;
|
||||
public static final int MAX_ABSOLUTE_AMOUNT = 100000;
|
||||
|
||||
private WiredNumericInputGuard() {
|
||||
}
|
||||
|
||||
public static int parsePositiveAmount(String value, int maxAmount) {
|
||||
try {
|
||||
int parsed = Integer.parseInt(value == null ? "" : value.trim());
|
||||
if (parsed <= 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return Math.min(parsed, Math.max(1, Math.min(maxAmount, MAX_ABSOLUTE_AMOUNT)));
|
||||
} catch (NumberFormatException e) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
public static int maxRewardAmount() {
|
||||
return configuredMax("hotel.wired.reward.max_amount", DEFAULT_MAX_REWARD_AMOUNT);
|
||||
}
|
||||
|
||||
public static int maxRespectAmount() {
|
||||
return configuredMax("hotel.wired.respect.max_amount", DEFAULT_MAX_RESPECT_AMOUNT);
|
||||
}
|
||||
|
||||
private static int configuredMax(String key, int fallback) {
|
||||
int configured = Emulator.getConfig() != null ? Emulator.getConfig().getInt(key, fallback) : fallback;
|
||||
return Math.max(1, Math.min(configured, MAX_ABSOLUTE_AMOUNT));
|
||||
}
|
||||
}
|
||||
+45
@@ -0,0 +1,45 @@
|
||||
package com.eu.habbo.habbohotel.items.interactions.wired;
|
||||
|
||||
public final class WiredTimerInputGuard {
|
||||
public static final int MAX_TIMER_MS = 24 * 60 * 60 * 1000;
|
||||
|
||||
private WiredTimerInputGuard() {
|
||||
}
|
||||
|
||||
public static int fromClientUnits(int units, int stepMs, int minMs) {
|
||||
return fromClientUnits(units, stepMs, minMs, MAX_TIMER_MS);
|
||||
}
|
||||
|
||||
public static int fromClientUnits(int units, int stepMs, int minMs, int maxMs) {
|
||||
if (units < 1 || stepMs < 1) {
|
||||
return minMs;
|
||||
}
|
||||
|
||||
long value = (long) units * stepMs;
|
||||
return clamp(value, minMs, maxMs);
|
||||
}
|
||||
|
||||
public static int normalizeStoredMillis(Integer millis, int minMs, int fallbackMs) {
|
||||
return normalizeStoredMillis(millis, minMs, fallbackMs, MAX_TIMER_MS);
|
||||
}
|
||||
|
||||
public static int normalizeStoredMillis(Integer millis, int minMs, int fallbackMs, int maxMs) {
|
||||
if (millis == null || millis < minMs) {
|
||||
return fallbackMs;
|
||||
}
|
||||
|
||||
return clamp(millis.longValue(), minMs, maxMs);
|
||||
}
|
||||
|
||||
private static int clamp(long value, int minMs, int maxMs) {
|
||||
if (value < minMs) {
|
||||
return minMs;
|
||||
}
|
||||
|
||||
if (value > maxMs) {
|
||||
return maxMs;
|
||||
}
|
||||
|
||||
return (int) value;
|
||||
}
|
||||
}
|
||||
+10
-4
@@ -111,7 +111,13 @@ public class WiredConditionActorDir extends InteractionWiredCondition {
|
||||
}
|
||||
|
||||
if (wiredData.startsWith("{")) {
|
||||
JsonData data = WiredManager.getGson().fromJson(wiredData, JsonData.class);
|
||||
JsonData data;
|
||||
try {
|
||||
data = WiredManager.getGson().fromJson(wiredData, JsonData.class);
|
||||
} catch (RuntimeException exception) {
|
||||
this.onPickUp();
|
||||
return;
|
||||
}
|
||||
|
||||
if (data == null) {
|
||||
return;
|
||||
@@ -157,15 +163,15 @@ public class WiredConditionActorDir extends InteractionWiredCondition {
|
||||
return (this.directionMask & (1 << direction)) != 0;
|
||||
}
|
||||
|
||||
private int normalizeDirectionMask(int value) {
|
||||
int normalizeDirectionMask(int value) {
|
||||
return value & ALL_DIRECTIONS_MASK;
|
||||
}
|
||||
|
||||
private int normalizeUserSource(int value) {
|
||||
int normalizeUserSource(int value) {
|
||||
return WiredSourceUtil.isDefaultUserSource(value) ? value : WiredSourceUtil.SOURCE_TRIGGER;
|
||||
}
|
||||
|
||||
private int normalizeQuantifier(int value) {
|
||||
int normalizeQuantifier(int value) {
|
||||
return (value == QUANTIFIER_ANY) ? QUANTIFIER_ANY : QUANTIFIER_ALL;
|
||||
}
|
||||
|
||||
|
||||
+40
-13
@@ -111,19 +111,21 @@ public class WiredConditionCounterTimeMatches extends InteractionWiredCondition
|
||||
|
||||
@Override
|
||||
public void loadWiredData(ResultSet set, Room room) throws SQLException {
|
||||
this.items.clear();
|
||||
this.comparison = COMPARISON_EQUAL;
|
||||
this.minutes = 0;
|
||||
this.halfSecondSteps = 0;
|
||||
this.furniSource = WiredSourceUtil.SOURCE_TRIGGER;
|
||||
this.quantifier = QUANTIFIER_ALL;
|
||||
this.resetSettings();
|
||||
|
||||
String wiredData = set.getString("wired_data");
|
||||
if (wiredData == null || wiredData.isEmpty() || !wiredData.startsWith("{")) {
|
||||
return;
|
||||
}
|
||||
|
||||
JsonData data = WiredManager.getGson().fromJson(wiredData, JsonData.class);
|
||||
JsonData data;
|
||||
try {
|
||||
data = WiredManager.getGson().fromJson(wiredData, JsonData.class);
|
||||
} catch (RuntimeException exception) {
|
||||
this.resetSettings();
|
||||
return;
|
||||
}
|
||||
|
||||
if (data == null) {
|
||||
return;
|
||||
}
|
||||
@@ -131,7 +133,7 @@ public class WiredConditionCounterTimeMatches extends InteractionWiredCondition
|
||||
this.comparison = this.normalizeComparison(data.comparison);
|
||||
this.minutes = this.normalizeMinutes(data.minutes);
|
||||
this.halfSecondSteps = this.normalizeHalfSecondSteps(data.halfSecondSteps);
|
||||
this.furniSource = data.furniSource;
|
||||
this.furniSource = this.normalizeFurniSource(data.furniSource);
|
||||
this.quantifier = this.normalizeQuantifier(data.quantifier);
|
||||
|
||||
if (data.itemIds == null) {
|
||||
@@ -139,6 +141,10 @@ public class WiredConditionCounterTimeMatches extends InteractionWiredCondition
|
||||
}
|
||||
|
||||
for (Integer id : data.itemIds) {
|
||||
if (id == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
HabboItem item = room.getHabboItem(id);
|
||||
if (item instanceof InteractionGameUpCounter) {
|
||||
this.items.add(item);
|
||||
@@ -195,7 +201,7 @@ public class WiredConditionCounterTimeMatches extends InteractionWiredCondition
|
||||
this.comparison = (params.length > 0) ? this.normalizeComparison(params[0]) : COMPARISON_EQUAL;
|
||||
this.minutes = (params.length > 1) ? this.normalizeMinutes(params[1]) : 0;
|
||||
this.halfSecondSteps = (params.length > 2) ? this.normalizeHalfSecondSteps(params[2]) : 0;
|
||||
this.furniSource = (params.length > 3) ? params[3] : WiredSourceUtil.SOURCE_TRIGGER;
|
||||
this.furniSource = (params.length > 3) ? this.normalizeFurniSource(params[3]) : WiredSourceUtil.SOURCE_TRIGGER;
|
||||
this.quantifier = (params.length > 4) ? this.normalizeQuantifier(params[4]) : QUANTIFIER_ALL;
|
||||
|
||||
this.items.clear();
|
||||
@@ -224,6 +230,15 @@ public class WiredConditionCounterTimeMatches extends InteractionWiredCondition
|
||||
return true;
|
||||
}
|
||||
|
||||
private void resetSettings() {
|
||||
this.items.clear();
|
||||
this.comparison = COMPARISON_EQUAL;
|
||||
this.minutes = 0;
|
||||
this.halfSecondSteps = 0;
|
||||
this.furniSource = WiredSourceUtil.SOURCE_TRIGGER;
|
||||
this.quantifier = QUANTIFIER_ALL;
|
||||
}
|
||||
|
||||
private void refresh(Room room) {
|
||||
THashSet<HabboItem> remove = new THashSet<>();
|
||||
|
||||
@@ -256,7 +271,7 @@ public class WiredConditionCounterTimeMatches extends InteractionWiredCondition
|
||||
}
|
||||
}
|
||||
|
||||
private int normalizeComparison(int value) {
|
||||
int normalizeComparison(int value) {
|
||||
if (value < COMPARISON_LESS || value > COMPARISON_GREATER) {
|
||||
return COMPARISON_EQUAL;
|
||||
}
|
||||
@@ -264,18 +279,30 @@ public class WiredConditionCounterTimeMatches extends InteractionWiredCondition
|
||||
return value;
|
||||
}
|
||||
|
||||
private int normalizeMinutes(int value) {
|
||||
int normalizeMinutes(int value) {
|
||||
return Math.max(0, Math.min(MAX_MINUTES, value));
|
||||
}
|
||||
|
||||
private int normalizeHalfSecondSteps(int value) {
|
||||
int normalizeHalfSecondSteps(int value) {
|
||||
return Math.max(0, Math.min(MAX_HALF_SECOND_STEPS, value));
|
||||
}
|
||||
|
||||
private int normalizeQuantifier(int value) {
|
||||
int normalizeQuantifier(int value) {
|
||||
return (value == QUANTIFIER_ANY) ? QUANTIFIER_ANY : QUANTIFIER_ALL;
|
||||
}
|
||||
|
||||
int normalizeFurniSource(int value) {
|
||||
switch (value) {
|
||||
case WiredSourceUtil.SOURCE_SELECTED:
|
||||
case WiredSourceUtil.SOURCE_SELECTOR:
|
||||
case WiredSourceUtil.SOURCE_SIGNAL:
|
||||
case WiredSourceUtil.SOURCE_TRIGGER:
|
||||
return value;
|
||||
default:
|
||||
return WiredSourceUtil.SOURCE_TRIGGER;
|
||||
}
|
||||
}
|
||||
|
||||
static class JsonData {
|
||||
int comparison;
|
||||
int minutes;
|
||||
|
||||
+18
-6
@@ -53,8 +53,7 @@ public class WiredConditionDateRangeActive extends InteractionWiredCondition {
|
||||
@Override
|
||||
public boolean saveData(WiredSettings settings) {
|
||||
if(settings.getIntParams().length < 2) return false;
|
||||
this.startDate = settings.getIntParams()[0];
|
||||
this.endDate = settings.getIntParams()[1];
|
||||
this.applyRange(settings.getIntParams()[0], settings.getIntParams()[1]);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -81,19 +80,26 @@ public class WiredConditionDateRangeActive extends InteractionWiredCondition {
|
||||
@Override
|
||||
public void loadWiredData(ResultSet set, Room room) throws SQLException {
|
||||
String wiredData = set.getString("wired_data");
|
||||
if (wiredData == null || wiredData.isEmpty()) {
|
||||
this.applyRange(0, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
if (wiredData.startsWith("{")) {
|
||||
JsonData data = WiredManager.getGson().fromJson(wiredData, JsonData.class);
|
||||
this.startDate = data.startDate;
|
||||
this.endDate = data.endDate;
|
||||
if (data == null) {
|
||||
this.applyRange(0, 0);
|
||||
return;
|
||||
}
|
||||
this.applyRange(data.startDate, data.endDate);
|
||||
} else {
|
||||
String[] data = wiredData.split("\t");
|
||||
|
||||
if (data.length == 2) {
|
||||
try {
|
||||
this.startDate = Integer.parseInt(data[0]);
|
||||
this.endDate = Integer.parseInt(data[1]);
|
||||
this.applyRange(Integer.parseInt(data[0]), Integer.parseInt(data[1]));
|
||||
} catch (Exception e) {
|
||||
this.applyRange(0, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -105,6 +111,12 @@ public class WiredConditionDateRangeActive extends InteractionWiredCondition {
|
||||
this.endDate = 0;
|
||||
}
|
||||
|
||||
private void applyRange(int startDate, int endDate) {
|
||||
int[] range = WiredDateRangeInputGuard.normalizeRange(startDate, endDate);
|
||||
this.startDate = range[0];
|
||||
this.endDate = range[1];
|
||||
}
|
||||
|
||||
static class JsonData {
|
||||
int startDate;
|
||||
int endDate;
|
||||
|
||||
+8
-18
@@ -112,13 +112,10 @@ public class WiredConditionFurniHaveFurni extends InteractionWiredCondition {
|
||||
}
|
||||
|
||||
this.all = data.all;
|
||||
this.furniSource = this.normalizeFurniSource(data.furniSource);
|
||||
this.furniSource = WiredFurniConditionInputGuard.normalizeFurniSource(data.furniSource);
|
||||
|
||||
if (data.itemIds != null && room != null) {
|
||||
for (Integer id : data.itemIds) {
|
||||
if (id == null) {
|
||||
continue;
|
||||
}
|
||||
for(int id : WiredFurniConditionInputGuard.sanitizeItemIds(data.itemIds, WiredManager.MAXIMUM_FURNI_SELECTION)) {
|
||||
HabboItem item = room.getHabboItem(id);
|
||||
|
||||
HabboItem item = room.getHabboItem(id);
|
||||
if (item != null) {
|
||||
@@ -133,11 +130,8 @@ public class WiredConditionFurniHaveFurni extends InteractionWiredCondition {
|
||||
this.all = (data[0].equals("1"));
|
||||
|
||||
if (data.length == 2) {
|
||||
String[] items = data[1].split(";");
|
||||
|
||||
for (String s : items) {
|
||||
try {
|
||||
HabboItem item = room.getHabboItem(Integer.parseInt(s));
|
||||
for (int id : WiredFurniConditionInputGuard.parseLegacyItemIds(data[1], WiredManager.MAXIMUM_FURNI_SELECTION)) {
|
||||
HabboItem item = room.getHabboItem(id);
|
||||
|
||||
if (item != null)
|
||||
this.items.add(item);
|
||||
@@ -148,9 +142,7 @@ public class WiredConditionFurniHaveFurni extends InteractionWiredCondition {
|
||||
}
|
||||
this.furniSource = this.items.isEmpty() ? WiredSourceUtil.SOURCE_TRIGGER : WiredSourceUtil.SOURCE_SELECTED;
|
||||
}
|
||||
if (this.furniSource == WiredSourceUtil.SOURCE_TRIGGER && !this.items.isEmpty()) {
|
||||
this.furniSource = WiredSourceUtil.SOURCE_SELECTED;
|
||||
}
|
||||
this.furniSource = WiredFurniConditionInputGuard.selectedOrNormalizedFurniSource(this.furniSource, !this.items.isEmpty());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -194,14 +186,12 @@ public class WiredConditionFurniHaveFurni extends InteractionWiredCondition {
|
||||
|
||||
int[] params = settings.getIntParams();
|
||||
this.all = params[0] == 1;
|
||||
this.furniSource = (params.length > 1) ? this.normalizeFurniSource(params[1]) : WiredSourceUtil.SOURCE_TRIGGER;
|
||||
this.furniSource = (params.length > 1) ? WiredFurniConditionInputGuard.normalizeFurniSource(params[1]) : WiredSourceUtil.SOURCE_TRIGGER;
|
||||
|
||||
int count = settings.getFurniIds().length;
|
||||
if (count > Emulator.getConfig().getInt("hotel.wired.furni.selection.count")) return false;
|
||||
|
||||
if (count > 0 && this.furniSource == WiredSourceUtil.SOURCE_TRIGGER) {
|
||||
this.furniSource = WiredSourceUtil.SOURCE_SELECTED;
|
||||
}
|
||||
this.furniSource = WiredFurniConditionInputGuard.selectedOrNormalizedFurniSource(this.furniSource, count > 0);
|
||||
|
||||
this.items.clear();
|
||||
|
||||
|
||||
+10
-32
@@ -96,26 +96,12 @@ public class WiredConditionFurniHaveHabbo extends InteractionWiredCondition {
|
||||
}
|
||||
|
||||
if (wiredData.startsWith("{")) {
|
||||
JsonData data;
|
||||
try {
|
||||
data = WiredManager.getGson().fromJson(wiredData, JsonData.class);
|
||||
} catch (RuntimeException exception) {
|
||||
this.onPickUp();
|
||||
return;
|
||||
}
|
||||
|
||||
if (data == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.furniSource = this.normalizeFurniSource(data.furniSource);
|
||||
JsonData data = WiredManager.getGson().fromJson(wiredData, JsonData.class);
|
||||
this.furniSource = WiredFurniConditionInputGuard.normalizeFurniSource(data.furniSource);
|
||||
this.all = data.all;
|
||||
|
||||
if (data.itemIds != null && room != null) {
|
||||
for (Integer id : data.itemIds) {
|
||||
if (id == null) {
|
||||
continue;
|
||||
}
|
||||
for(int id : WiredFurniConditionInputGuard.sanitizeItemIds(data.itemIds, WiredManager.MAXIMUM_FURNI_SELECTION)) {
|
||||
HabboItem item = room.getHabboItem(id);
|
||||
|
||||
HabboItem item = room.getHabboItem(id);
|
||||
if (item != null) {
|
||||
@@ -126,13 +112,9 @@ public class WiredConditionFurniHaveHabbo extends InteractionWiredCondition {
|
||||
} else {
|
||||
String[] data = wiredData.split(":");
|
||||
|
||||
if (data.length >= 1) {
|
||||
|
||||
String[] items = data[1].split(";");
|
||||
|
||||
for (String s : items) {
|
||||
try {
|
||||
HabboItem item = room.getHabboItem(Integer.parseInt(s));
|
||||
if (data.length >= 2) {
|
||||
for (int id : WiredFurniConditionInputGuard.parseLegacyItemIds(data[1], WiredManager.MAXIMUM_FURNI_SELECTION)) {
|
||||
HabboItem item = room.getHabboItem(id);
|
||||
|
||||
if (item != null)
|
||||
this.items.add(item);
|
||||
@@ -143,9 +125,7 @@ public class WiredConditionFurniHaveHabbo extends InteractionWiredCondition {
|
||||
this.furniSource = this.items.isEmpty() ? WiredSourceUtil.SOURCE_TRIGGER : WiredSourceUtil.SOURCE_SELECTED;
|
||||
this.all = false;
|
||||
}
|
||||
if (this.furniSource == WiredSourceUtil.SOURCE_TRIGGER && !this.items.isEmpty()) {
|
||||
this.furniSource = WiredSourceUtil.SOURCE_SELECTED;
|
||||
}
|
||||
this.furniSource = WiredFurniConditionInputGuard.selectedOrNormalizedFurniSource(this.furniSource, !this.items.isEmpty());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -184,11 +164,9 @@ public class WiredConditionFurniHaveHabbo extends InteractionWiredCondition {
|
||||
|
||||
int[] params = settings.getIntParams();
|
||||
this.all = (params.length > 0) && (params[0] == 1);
|
||||
this.furniSource = (params.length > 1) ? this.normalizeFurniSource(params[1]) : ((params.length > 0 && params[0] > 1) ? this.normalizeFurniSource(params[0]) : WiredSourceUtil.SOURCE_TRIGGER);
|
||||
this.furniSource = (params.length > 1) ? WiredFurniConditionInputGuard.normalizeFurniSource(params[1]) : ((params.length > 0 && params[0] > 1) ? WiredFurniConditionInputGuard.normalizeFurniSource(params[0]) : WiredSourceUtil.SOURCE_TRIGGER);
|
||||
|
||||
if (count > 0 && this.furniSource == WiredSourceUtil.SOURCE_TRIGGER) {
|
||||
this.furniSource = WiredSourceUtil.SOURCE_SELECTED;
|
||||
}
|
||||
this.furniSource = WiredFurniConditionInputGuard.selectedOrNormalizedFurniSource(this.furniSource, count > 0);
|
||||
|
||||
this.items.clear();
|
||||
|
||||
|
||||
+22
-9
@@ -16,6 +16,7 @@ import java.sql.SQLException;
|
||||
|
||||
public class WiredConditionHabboCount extends InteractionWiredCondition {
|
||||
public static final WiredConditionType type = WiredConditionType.USER_COUNT;
|
||||
static final int MAX_USER_COUNT_LIMIT = 1000;
|
||||
|
||||
private int lowerLimit = 0;
|
||||
private int upperLimit = 50;
|
||||
@@ -31,6 +32,10 @@ public class WiredConditionHabboCount extends InteractionWiredCondition {
|
||||
|
||||
@Override
|
||||
public boolean evaluate(WiredContext ctx) {
|
||||
if (ctx == null || ctx.room() == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
int count = (this.userSource == WiredSourceUtil.SOURCE_TRIGGER)
|
||||
? ctx.room().getUserCount()
|
||||
: WiredSourceUtil.resolveUsers(ctx, this.userSource).size();
|
||||
@@ -55,26 +60,29 @@ public class WiredConditionHabboCount extends InteractionWiredCondition {
|
||||
|
||||
@Override
|
||||
public void loadWiredData(ResultSet set, Room room) throws SQLException {
|
||||
this.onPickUp();
|
||||
|
||||
String wiredData = set.getString("wired_data");
|
||||
if (wiredData == null || wiredData.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (wiredData.startsWith("{")) {
|
||||
JsonData data = WiredManager.getGson().fromJson(wiredData, JsonData.class);
|
||||
this.lowerLimit = data.lowerLimit;
|
||||
this.upperLimit = data.upperLimit;
|
||||
this.userSource = data.userSource;
|
||||
this.applyLimits(data.lowerLimit, data.upperLimit);
|
||||
this.userSource = WiredConditionInputGuard.normalizeUserSource(data.userSource);
|
||||
} else {
|
||||
String[] data = wiredData.split(":");
|
||||
|
||||
if (data.length >= 2) {
|
||||
try {
|
||||
this.lowerLimit = Integer.parseInt(data[0].trim());
|
||||
this.upperLimit = Integer.parseInt(data[1].trim());
|
||||
this.applyLimits(Integer.parseInt(data[0].trim()), Integer.parseInt(data[1].trim()));
|
||||
} catch (NumberFormatException ignored) {
|
||||
// malformed legacy data — keep the constructed defaults
|
||||
}
|
||||
}
|
||||
this.userSource = WiredSourceUtil.SOURCE_TRIGGER;
|
||||
}
|
||||
this.userSource = WiredSourceUtil.SOURCE_TRIGGER;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -110,14 +118,19 @@ public class WiredConditionHabboCount extends InteractionWiredCondition {
|
||||
@Override
|
||||
public boolean saveData(WiredSettings settings) {
|
||||
if(settings.getIntParams().length < 2) return false;
|
||||
this.lowerLimit = settings.getIntParams()[0];
|
||||
this.upperLimit = settings.getIntParams()[1];
|
||||
int[] params = settings.getIntParams();
|
||||
this.userSource = (params.length > 2) ? params[2] : WiredSourceUtil.SOURCE_TRIGGER;
|
||||
this.applyLimits(params[0], params[1]);
|
||||
this.userSource = (params.length > 2) ? WiredConditionInputGuard.normalizeUserSource(params[2]) : WiredSourceUtil.SOURCE_TRIGGER;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private void applyLimits(int lowerLimit, int upperLimit) {
|
||||
int[] limits = WiredConditionInputGuard.normalizeUserCountRange(lowerLimit, upperLimit);
|
||||
this.lowerLimit = limits[0];
|
||||
this.upperLimit = limits[1];
|
||||
}
|
||||
|
||||
static class JsonData {
|
||||
int lowerLimit;
|
||||
int upperLimit;
|
||||
|
||||
+34
-6
@@ -18,6 +18,7 @@ import java.util.List;
|
||||
public class WiredConditionHabboHasEffect extends InteractionWiredCondition {
|
||||
protected static final int QUANTIFIER_ALL = 0;
|
||||
protected static final int QUANTIFIER_ANY = 1;
|
||||
protected static final int MAX_EFFECT_ID = 10_000;
|
||||
|
||||
public static final WiredConditionType type = WiredConditionType.ACTOR_WEARS_EFFECT;
|
||||
|
||||
@@ -86,15 +87,34 @@ public class WiredConditionHabboHasEffect extends InteractionWiredCondition {
|
||||
|
||||
@Override
|
||||
public void loadWiredData(ResultSet set, Room room) throws SQLException {
|
||||
this.onPickUp();
|
||||
String wiredData = set.getString("wired_data");
|
||||
if (wiredData == null || wiredData.isEmpty()) {
|
||||
this.onPickUp();
|
||||
return;
|
||||
}
|
||||
|
||||
if (wiredData.startsWith("{")) {
|
||||
JsonData data = WiredManager.getGson().fromJson(wiredData, JsonData.class);
|
||||
this.effectId = data.effectId;
|
||||
this.userSource = data.userSource;
|
||||
JsonData data;
|
||||
try {
|
||||
data = WiredManager.getGson().fromJson(wiredData, JsonData.class);
|
||||
} catch (RuntimeException ignored) {
|
||||
this.onPickUp();
|
||||
return;
|
||||
}
|
||||
if (data == null) {
|
||||
this.onPickUp();
|
||||
return;
|
||||
}
|
||||
this.effectId = WiredUserConditionInputGuard.normalizeEffectId(data.effectId);
|
||||
this.userSource = WiredUserConditionInputGuard.normalizeUserSource(data.userSource);
|
||||
this.quantifier = this.normalizeQuantifier(data.quantifier, QUANTIFIER_ANY);
|
||||
} else {
|
||||
this.effectId = Integer.parseInt(wiredData);
|
||||
try {
|
||||
this.effectId = WiredUserConditionInputGuard.normalizeEffectId(Integer.parseInt(wiredData));
|
||||
} catch (NumberFormatException ignored) {
|
||||
this.effectId = 0;
|
||||
}
|
||||
this.userSource = WiredSourceUtil.SOURCE_TRIGGER;
|
||||
this.quantifier = QUANTIFIER_ANY;
|
||||
}
|
||||
@@ -134,8 +154,8 @@ public class WiredConditionHabboHasEffect extends InteractionWiredCondition {
|
||||
public boolean saveData(WiredSettings settings) {
|
||||
if(settings.getIntParams().length < 1) return false;
|
||||
int[] params = settings.getIntParams();
|
||||
this.effectId = params[0];
|
||||
this.userSource = (params.length > 1) ? params[1] : WiredSourceUtil.SOURCE_TRIGGER;
|
||||
this.effectId = WiredUserConditionInputGuard.normalizeEffectId(params[0]);
|
||||
this.userSource = (params.length > 1) ? WiredUserConditionInputGuard.normalizeUserSource(params[1]) : WiredSourceUtil.SOURCE_TRIGGER;
|
||||
this.quantifier = (params.length > 2) ? this.normalizeQuantifier(params[2], QUANTIFIER_ANY) : QUANTIFIER_ANY;
|
||||
|
||||
return true;
|
||||
@@ -153,6 +173,14 @@ public class WiredConditionHabboHasEffect extends InteractionWiredCondition {
|
||||
return (value == QUANTIFIER_ANY) ? QUANTIFIER_ANY : QUANTIFIER_ALL;
|
||||
}
|
||||
|
||||
protected int normalizeEffectId(int value) {
|
||||
return Math.max(0, Math.min(MAX_EFFECT_ID, value));
|
||||
}
|
||||
|
||||
protected int normalizeUserSource(int value) {
|
||||
return WiredSourceUtil.isDefaultUserSource(value) ? value : WiredSourceUtil.SOURCE_TRIGGER;
|
||||
}
|
||||
|
||||
static class JsonData {
|
||||
int effectId;
|
||||
int userSource;
|
||||
|
||||
+34
-22
@@ -10,17 +10,15 @@ import com.eu.habbo.habbohotel.wired.core.WiredManager;
|
||||
import com.eu.habbo.habbohotel.wired.core.WiredContext;
|
||||
import com.eu.habbo.habbohotel.wired.core.WiredSourceUtil;
|
||||
import com.eu.habbo.messages.ServerMessage;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.List;
|
||||
|
||||
public class WiredConditionHabboHasHandItem extends InteractionWiredCondition {
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(WiredConditionHabboHasHandItem.class);
|
||||
protected static final int QUANTIFIER_ALL = 0;
|
||||
protected static final int QUANTIFIER_ANY = 1;
|
||||
protected static final int MAX_HAND_ITEM_ID = 10_000;
|
||||
|
||||
public static final WiredConditionType type = WiredConditionType.ACTOR_HAS_HANDITEM;
|
||||
|
||||
@@ -62,9 +60,9 @@ public class WiredConditionHabboHasHandItem extends InteractionWiredCondition {
|
||||
@Override
|
||||
public boolean saveData(WiredSettings settings) {
|
||||
if(settings.getIntParams().length < 1) return false;
|
||||
this.handItem = this.normalizeHandItem(settings.getIntParams()[0]);
|
||||
this.handItem = WiredUserConditionInputGuard.normalizeHandItemId(settings.getIntParams()[0]);
|
||||
int[] params = settings.getIntParams();
|
||||
this.userSource = (params.length > 1) ? params[1] : WiredSourceUtil.SOURCE_TRIGGER;
|
||||
this.userSource = (params.length > 1) ? WiredUserConditionInputGuard.normalizeUserSource(params[1]) : WiredSourceUtil.SOURCE_TRIGGER;
|
||||
this.quantifier = (params.length > 2) ? this.normalizeQuantifier(params[2]) : QUANTIFIER_ALL;
|
||||
|
||||
return true;
|
||||
@@ -99,21 +97,35 @@ public class WiredConditionHabboHasHandItem extends InteractionWiredCondition {
|
||||
|
||||
@Override
|
||||
public void loadWiredData(ResultSet set, Room room) throws SQLException {
|
||||
try {
|
||||
String wiredData = set.getString("wired_data");
|
||||
String wiredData = set.getString("wired_data");
|
||||
if (wiredData == null || wiredData.isEmpty()) {
|
||||
this.onPickUp();
|
||||
return;
|
||||
}
|
||||
|
||||
if (wiredData.startsWith("{")) {
|
||||
JsonData data = WiredManager.getGson().fromJson(wiredData, JsonData.class);
|
||||
this.handItem = this.normalizeHandItem(data.handItemId);
|
||||
this.userSource = data.userSource;
|
||||
this.quantifier = this.normalizeQuantifier(data.quantifier);
|
||||
} else {
|
||||
this.handItem = this.normalizeHandItem(Integer.parseInt(wiredData));
|
||||
this.userSource = WiredSourceUtil.SOURCE_TRIGGER;
|
||||
this.quantifier = QUANTIFIER_ALL;
|
||||
if (wiredData.startsWith("{")) {
|
||||
JsonData data;
|
||||
try {
|
||||
data = WiredManager.getGson().fromJson(wiredData, JsonData.class);
|
||||
} catch (RuntimeException ignored) {
|
||||
this.onPickUp();
|
||||
return;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
LOGGER.error("Caught exception", e);
|
||||
if (data == null) {
|
||||
this.onPickUp();
|
||||
return;
|
||||
}
|
||||
this.handItem = WiredUserConditionInputGuard.normalizeHandItemId(data.handItemId);
|
||||
this.userSource = WiredUserConditionInputGuard.normalizeUserSource(data.userSource);
|
||||
this.quantifier = this.normalizeQuantifier(data.quantifier);
|
||||
} else {
|
||||
try {
|
||||
this.handItem = WiredUserConditionInputGuard.normalizeHandItemId(Integer.parseInt(wiredData));
|
||||
} catch (NumberFormatException ignored) {
|
||||
this.handItem = 0;
|
||||
}
|
||||
this.userSource = WiredSourceUtil.SOURCE_TRIGGER;
|
||||
this.quantifier = QUANTIFIER_ALL;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -156,14 +168,14 @@ public class WiredConditionHabboHasHandItem extends InteractionWiredCondition {
|
||||
return true;
|
||||
}
|
||||
|
||||
protected int normalizeHandItem(int value) {
|
||||
return Math.max(0, value);
|
||||
}
|
||||
|
||||
protected int normalizeQuantifier(int value) {
|
||||
return (value == QUANTIFIER_ANY) ? QUANTIFIER_ANY : QUANTIFIER_ALL;
|
||||
}
|
||||
|
||||
protected int normalizeUserSource(int value) {
|
||||
return WiredSourceUtil.isDefaultUserSource(value) ? value : WiredSourceUtil.SOURCE_TRIGGER;
|
||||
}
|
||||
|
||||
static class JsonData {
|
||||
int handItemId;
|
||||
int userSource;
|
||||
|
||||
+39
-6
@@ -20,6 +20,7 @@ import java.util.List;
|
||||
public class WiredConditionHabboWearsBadge extends InteractionWiredCondition {
|
||||
protected static final int QUANTIFIER_ALL = 0;
|
||||
protected static final int QUANTIFIER_ANY = 1;
|
||||
protected static final int MAX_BADGE_CODE_LENGTH = 64;
|
||||
|
||||
public static final WiredConditionType type = WiredConditionType.ACTOR_WEARS_BADGE;
|
||||
|
||||
@@ -37,6 +38,10 @@ public class WiredConditionHabboWearsBadge extends InteractionWiredCondition {
|
||||
|
||||
@Override
|
||||
public boolean evaluate(WiredContext ctx) {
|
||||
if (ctx == null || ctx.room() == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Room room = ctx.room();
|
||||
List<RoomUnit> targets = WiredSourceUtil.resolveUsers(ctx, this.userSource);
|
||||
if (targets.isEmpty()) return false;
|
||||
@@ -102,15 +107,30 @@ public class WiredConditionHabboWearsBadge extends InteractionWiredCondition {
|
||||
|
||||
@Override
|
||||
public void loadWiredData(ResultSet set, Room room) throws SQLException {
|
||||
this.onPickUp();
|
||||
String wiredData = set.getString("wired_data");
|
||||
if (wiredData == null) {
|
||||
this.onPickUp();
|
||||
return;
|
||||
}
|
||||
|
||||
if (wiredData.startsWith("{")) {
|
||||
JsonData data = WiredManager.getGson().fromJson(wiredData, JsonData.class);
|
||||
this.badge = data.badge;
|
||||
this.userSource = data.userSource;
|
||||
JsonData data;
|
||||
try {
|
||||
data = WiredManager.getGson().fromJson(wiredData, JsonData.class);
|
||||
} catch (RuntimeException ignored) {
|
||||
this.onPickUp();
|
||||
return;
|
||||
}
|
||||
if (data == null) {
|
||||
this.onPickUp();
|
||||
return;
|
||||
}
|
||||
this.badge = WiredUserConditionInputGuard.normalizeBadgeCode(data.badge);
|
||||
this.userSource = WiredUserConditionInputGuard.normalizeUserSource(data.userSource);
|
||||
this.quantifier = this.normalizeQuantifier(data.quantifier, QUANTIFIER_ANY);
|
||||
} else {
|
||||
this.badge = wiredData;
|
||||
this.badge = WiredUserConditionInputGuard.normalizeBadgeCode(wiredData);
|
||||
this.userSource = WiredSourceUtil.SOURCE_TRIGGER;
|
||||
this.quantifier = QUANTIFIER_ANY;
|
||||
}
|
||||
@@ -147,9 +167,9 @@ public class WiredConditionHabboWearsBadge extends InteractionWiredCondition {
|
||||
|
||||
@Override
|
||||
public boolean saveData(WiredSettings settings) {
|
||||
this.badge = settings.getStringParam();
|
||||
this.badge = WiredUserConditionInputGuard.normalizeBadgeCode(settings.getStringParam());
|
||||
int[] params = settings.getIntParams();
|
||||
this.userSource = (params.length > 0) ? params[0] : WiredSourceUtil.SOURCE_TRIGGER;
|
||||
this.userSource = (params.length > 0) ? WiredUserConditionInputGuard.normalizeUserSource(params[0]) : WiredSourceUtil.SOURCE_TRIGGER;
|
||||
this.quantifier = (params.length > 1) ? this.normalizeQuantifier(params[1], QUANTIFIER_ANY) : QUANTIFIER_ANY;
|
||||
|
||||
return true;
|
||||
@@ -167,6 +187,19 @@ public class WiredConditionHabboWearsBadge extends InteractionWiredCondition {
|
||||
return (value == QUANTIFIER_ANY) ? QUANTIFIER_ANY : QUANTIFIER_ALL;
|
||||
}
|
||||
|
||||
protected String normalizeBadge(String value) {
|
||||
if (value == null) {
|
||||
return "";
|
||||
}
|
||||
|
||||
String normalized = value.trim();
|
||||
return normalized.length() <= MAX_BADGE_CODE_LENGTH ? normalized : normalized.substring(0, MAX_BADGE_CODE_LENGTH);
|
||||
}
|
||||
|
||||
protected int normalizeUserSource(int value) {
|
||||
return WiredSourceUtil.isDefaultUserSource(value) ? value : WiredSourceUtil.SOURCE_TRIGGER;
|
||||
}
|
||||
|
||||
static class JsonData {
|
||||
String badge;
|
||||
int userSource;
|
||||
|
||||
+18
-7
@@ -97,7 +97,14 @@ public class WiredConditionHasAltitude extends InteractionWiredCondition {
|
||||
return;
|
||||
}
|
||||
|
||||
JsonData data = WiredManager.getGson().fromJson(wiredData, JsonData.class);
|
||||
JsonData data;
|
||||
try {
|
||||
data = WiredManager.getGson().fromJson(wiredData, JsonData.class);
|
||||
} catch (RuntimeException exception) {
|
||||
this.onPickUp();
|
||||
return;
|
||||
}
|
||||
|
||||
if (data == null) {
|
||||
return;
|
||||
}
|
||||
@@ -112,6 +119,10 @@ public class WiredConditionHasAltitude extends InteractionWiredCondition {
|
||||
}
|
||||
|
||||
for (Integer id : data.itemIds) {
|
||||
if (id == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
HabboItem item = room.getHabboItem(id);
|
||||
if (item != null) {
|
||||
this.items.add(item);
|
||||
@@ -225,7 +236,7 @@ public class WiredConditionHasAltitude extends InteractionWiredCondition {
|
||||
}
|
||||
}
|
||||
|
||||
private int normalizeComparison(int value) {
|
||||
int normalizeComparison(int value) {
|
||||
if (value < COMPARISON_LESS || value > COMPARISON_GREATER) {
|
||||
return COMPARISON_EQUAL;
|
||||
}
|
||||
@@ -233,11 +244,11 @@ public class WiredConditionHasAltitude extends InteractionWiredCondition {
|
||||
return value;
|
||||
}
|
||||
|
||||
private int normalizeQuantifier(int value) {
|
||||
int normalizeQuantifier(int value) {
|
||||
return (value == QUANTIFIER_ANY) ? QUANTIFIER_ANY : QUANTIFIER_ALL;
|
||||
}
|
||||
|
||||
private int normalizeFurniSource(int value) {
|
||||
int normalizeFurniSource(int value) {
|
||||
switch (value) {
|
||||
case WiredSourceUtil.SOURCE_SELECTED:
|
||||
case WiredSourceUtil.SOURCE_SELECTOR:
|
||||
@@ -249,12 +260,12 @@ public class WiredConditionHasAltitude extends InteractionWiredCondition {
|
||||
}
|
||||
}
|
||||
|
||||
private double normalizeAltitude(double value) {
|
||||
double normalizeAltitude(double value) {
|
||||
double clampedValue = Math.max(0.0D, Math.min(Room.MAXIMUM_FURNI_HEIGHT, value));
|
||||
return BigDecimal.valueOf(clampedValue).setScale(2, RoundingMode.HALF_UP).doubleValue();
|
||||
}
|
||||
|
||||
private double parseAltitudeOrDefault(String value) {
|
||||
double parseAltitudeOrDefault(String value) {
|
||||
if (value == null || value.trim().isEmpty()) {
|
||||
return 0.0D;
|
||||
}
|
||||
@@ -266,7 +277,7 @@ public class WiredConditionHasAltitude extends InteractionWiredCondition {
|
||||
}
|
||||
}
|
||||
|
||||
private String formatAltitude(double value) {
|
||||
String formatAltitude(double value) {
|
||||
BigDecimal decimal = BigDecimal.valueOf(this.normalizeAltitude(value)).stripTrailingZeros();
|
||||
return (decimal.scale() < 0 ? decimal.setScale(0, RoundingMode.DOWN) : decimal).toPlainString();
|
||||
}
|
||||
|
||||
+57
@@ -0,0 +1,57 @@
|
||||
package com.eu.habbo.habbohotel.items.interactions.wired.conditions;
|
||||
|
||||
import com.eu.habbo.habbohotel.games.GameTeamColors;
|
||||
import com.eu.habbo.habbohotel.wired.core.WiredSourceUtil;
|
||||
|
||||
public final class WiredConditionInputGuard {
|
||||
public static final int MAX_USER_COUNT_LIMIT = 1000;
|
||||
public static final int MAX_TIMER_CYCLES = 24 * 60 * 60 * 2;
|
||||
|
||||
private WiredConditionInputGuard() {
|
||||
}
|
||||
|
||||
public static GameTeamColors normalizeTeamColor(GameTeamColors value, GameTeamColors fallback) {
|
||||
return (value != null) ? value : fallback;
|
||||
}
|
||||
|
||||
public static GameTeamColors normalizeTeamColorType(int value, GameTeamColors fallback) {
|
||||
for (GameTeamColors color : GameTeamColors.values()) {
|
||||
if (color.type == value) {
|
||||
return color;
|
||||
}
|
||||
}
|
||||
|
||||
return fallback;
|
||||
}
|
||||
|
||||
public static int normalizeUserSource(int value) {
|
||||
return WiredSourceUtil.isDefaultUserSource(value) ? value : WiredSourceUtil.SOURCE_TRIGGER;
|
||||
}
|
||||
|
||||
public static int normalizeTimerCycles(int value) {
|
||||
if (value < 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return Math.min(value, MAX_TIMER_CYCLES);
|
||||
}
|
||||
|
||||
public static int[] normalizeUserCountRange(int lowerLimit, int upperLimit) {
|
||||
int lower = clampUserCount(lowerLimit);
|
||||
int upper = clampUserCount(upperLimit);
|
||||
|
||||
if (lower > upper) {
|
||||
return new int[]{upper, lower};
|
||||
}
|
||||
|
||||
return new int[]{lower, upper};
|
||||
}
|
||||
|
||||
private static int clampUserCount(int value) {
|
||||
if (value < 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return Math.min(value, MAX_USER_COUNT_LIMIT);
|
||||
}
|
||||
}
|
||||
+8
-3
@@ -52,12 +52,13 @@ public class WiredConditionLessTimeElapsed extends InteractionWiredCondition {
|
||||
try {
|
||||
if (wiredData.startsWith("{")) {
|
||||
JsonData data = WiredManager.getGson().fromJson(wiredData, JsonData.class);
|
||||
this.cycles = data.cycles;
|
||||
this.cycles = WiredConditionInputGuard.normalizeTimerCycles(data.cycles);
|
||||
} else {
|
||||
if (!wiredData.equals(""))
|
||||
this.cycles = Integer.parseInt(wiredData);
|
||||
this.cycles = WiredConditionInputGuard.normalizeTimerCycles(Integer.parseInt(wiredData));
|
||||
}
|
||||
} catch (Exception e) {
|
||||
this.cycles = 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -90,10 +91,14 @@ public class WiredConditionLessTimeElapsed extends InteractionWiredCondition {
|
||||
@Override
|
||||
public boolean saveData(WiredSettings settings) {
|
||||
if(settings.getIntParams().length < 1) return false;
|
||||
this.cycles = settings.getIntParams()[0];
|
||||
this.cycles = WiredConditionInputGuard.normalizeTimerCycles(settings.getIntParams()[0]);
|
||||
return true;
|
||||
}
|
||||
|
||||
int normalizeCycles(int value) {
|
||||
return Math.max(0, Math.min(WiredConditionMoreTimeElapsed.MAX_CYCLES, value));
|
||||
}
|
||||
|
||||
static class JsonData {
|
||||
int cycles;
|
||||
|
||||
|
||||
+33
-13
@@ -87,7 +87,7 @@ public class WiredConditionMatchStatePosition extends InteractionWiredCondition
|
||||
this.direction = params[1] == 1;
|
||||
this.position = params[2] == 1;
|
||||
this.altitude = (params.length > 3) && (params[3] == 1);
|
||||
this.furniSource = (params.length > 4) ? params[4] : ((params.length > 3 && params[3] > 1) ? params[3] : WiredSourceUtil.SOURCE_TRIGGER);
|
||||
this.furniSource = (params.length > 4) ? WiredMatchPositionInputGuard.normalizeFurniSource(params[4], false) : ((params.length > 3 && params[3] > 1) ? WiredMatchPositionInputGuard.normalizeFurniSource(params[3], false) : WiredSourceUtil.SOURCE_TRIGGER);
|
||||
this.quantifier = (params.length > 5) ? this.normalizeQuantifier(params[5]) : QUANTIFIER_ALL;
|
||||
|
||||
Room room = Emulator.getGameEnvironment().getRoomManager().getRoom(this.getRoomId());
|
||||
@@ -108,6 +108,8 @@ public class WiredConditionMatchStatePosition extends InteractionWiredCondition
|
||||
this.settings.add(new WiredMatchFurniSetting(item.getId(), item.getExtradata(), item.getRotation(), item.getX(), item.getY(), item.getZ()));
|
||||
}
|
||||
|
||||
this.furniSource = WiredMatchPositionInputGuard.normalizeFurniSource(this.furniSource, !this.settings.isEmpty());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -255,27 +257,23 @@ public class WiredConditionMatchStatePosition extends InteractionWiredCondition
|
||||
this.position = data.position;
|
||||
this.direction = data.direction;
|
||||
this.altitude = data.altitude;
|
||||
if (data.settings != null) {
|
||||
this.settings.addAll(data.settings);
|
||||
}
|
||||
this.furniSource = data.furniSource;
|
||||
this.settings.addAll(WiredMatchPositionInputGuard.sanitizeSettings(data.settings, room));
|
||||
this.furniSource = WiredMatchPositionInputGuard.normalizeFurniSource(data.furniSource, !this.settings.isEmpty());
|
||||
this.quantifier = this.normalizeQuantifier(data.quantifier);
|
||||
} else {
|
||||
String[] data = wiredData.split(":");
|
||||
|
||||
if (data.length >= 5) {
|
||||
try {
|
||||
int itemCount = Integer.parseInt(data[0]);
|
||||
int itemCount = Math.min(Integer.parseInt(data[0]), WiredManager.MAXIMUM_FURNI_SELECTION);
|
||||
|
||||
String[] items = data[1].split(";");
|
||||
|
||||
for (int i = 0; i < itemCount && i < items.length; i++) {
|
||||
String[] stuff = items[i].split("-");
|
||||
|
||||
if (stuff.length >= 6)
|
||||
this.settings.add(new WiredMatchFurniSetting(Integer.parseInt(stuff[0]), stuff[1], Integer.parseInt(stuff[2]), Integer.parseInt(stuff[3]), Integer.parseInt(stuff[4]), Double.parseDouble(stuff[5])));
|
||||
else if (stuff.length >= 5)
|
||||
this.settings.add(new WiredMatchFurniSetting(Integer.parseInt(stuff[0]), stuff[1], Integer.parseInt(stuff[2]), Integer.parseInt(stuff[3]), Integer.parseInt(stuff[4])));
|
||||
WiredMatchFurniSetting setting = this.parseLegacySetting(items[i], room);
|
||||
if (setting != null) {
|
||||
this.settings.add(setting);
|
||||
}
|
||||
}
|
||||
|
||||
this.state = data[2].equals("1");
|
||||
@@ -287,11 +285,33 @@ public class WiredConditionMatchStatePosition extends InteractionWiredCondition
|
||||
}
|
||||
|
||||
this.altitude = false;
|
||||
this.furniSource = this.settings.isEmpty() ? WiredSourceUtil.SOURCE_TRIGGER : WiredSourceUtil.SOURCE_SELECTED;
|
||||
this.furniSource = WiredMatchPositionInputGuard.normalizeFurniSource(WiredSourceUtil.SOURCE_TRIGGER, !this.settings.isEmpty());
|
||||
this.quantifier = QUANTIFIER_ALL;
|
||||
}
|
||||
}
|
||||
|
||||
private WiredMatchFurniSetting parseLegacySetting(String value, Room room) {
|
||||
String[] parts = value.split("-", 6);
|
||||
if (parts.length < 5) {
|
||||
return null;
|
||||
}
|
||||
|
||||
try {
|
||||
double z = (parts.length >= 6) ? Double.parseDouble(parts[5]) : 0.0D;
|
||||
return WiredMatchPositionInputGuard.sanitizeParts(
|
||||
Integer.parseInt(parts[0]),
|
||||
parts[1],
|
||||
Integer.parseInt(parts[2]),
|
||||
Integer.parseInt(parts[3]),
|
||||
Integer.parseInt(parts[4]),
|
||||
z,
|
||||
room
|
||||
);
|
||||
} catch (NumberFormatException ignored) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPickUp() {
|
||||
this.settings.clear();
|
||||
|
||||
+9
-3
@@ -16,6 +16,7 @@ import java.sql.SQLException;
|
||||
|
||||
public class WiredConditionMoreTimeElapsed extends InteractionWiredCondition {
|
||||
private static final WiredConditionType type = WiredConditionType.TIME_MORE_THAN;
|
||||
static final int MAX_CYCLES = 1_000_000;
|
||||
|
||||
private int cycles;
|
||||
|
||||
@@ -52,12 +53,13 @@ public class WiredConditionMoreTimeElapsed extends InteractionWiredCondition {
|
||||
try {
|
||||
if (wiredData.startsWith("{")) {
|
||||
JsonData data = WiredManager.getGson().fromJson(wiredData, JsonData.class);
|
||||
this.cycles = data.cycles;
|
||||
this.cycles = WiredConditionInputGuard.normalizeTimerCycles(data.cycles);
|
||||
} else {
|
||||
if (!wiredData.equals(""))
|
||||
this.cycles = Integer.parseInt(wiredData);
|
||||
this.cycles = WiredConditionInputGuard.normalizeTimerCycles(Integer.parseInt(wiredData));
|
||||
}
|
||||
} catch (Exception e) {
|
||||
this.cycles = 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -90,10 +92,14 @@ public class WiredConditionMoreTimeElapsed extends InteractionWiredCondition {
|
||||
@Override
|
||||
public boolean saveData(WiredSettings settings) {
|
||||
if(settings.getIntParams().length < 1) return false;
|
||||
this.cycles = settings.getIntParams()[0];
|
||||
this.cycles = WiredConditionInputGuard.normalizeTimerCycles(settings.getIntParams()[0]);
|
||||
return true;
|
||||
}
|
||||
|
||||
int normalizeCycles(int value) {
|
||||
return Math.max(0, Math.min(MAX_CYCLES, value));
|
||||
}
|
||||
|
||||
static class JsonData {
|
||||
int cycles;
|
||||
|
||||
|
||||
+7
-13
@@ -99,9 +99,9 @@ public class WiredConditionNotFurniHaveFurni extends InteractionWiredCondition {
|
||||
if (wiredData.startsWith("{")) {
|
||||
JsonData data = WiredManager.getGson().fromJson(wiredData, JsonData.class);
|
||||
this.all = data.all;
|
||||
this.furniSource = data.furniSource;
|
||||
this.furniSource = WiredFurniConditionInputGuard.normalizeFurniSource(data.furniSource);
|
||||
|
||||
for (int id : data.itemIds) {
|
||||
for (int id : WiredFurniConditionInputGuard.sanitizeItemIds(data.itemIds, WiredManager.MAXIMUM_FURNI_SELECTION)) {
|
||||
HabboItem item = room.getHabboItem(id);
|
||||
|
||||
if (item != null) {
|
||||
@@ -115,10 +115,8 @@ public class WiredConditionNotFurniHaveFurni extends InteractionWiredCondition {
|
||||
this.all = (data[0].equals("1"));
|
||||
|
||||
if (data.length == 2) {
|
||||
String[] items = data[1].split(";");
|
||||
|
||||
for (String s : items) {
|
||||
HabboItem item = room.getHabboItem(Integer.parseInt(s));
|
||||
for (int id : WiredFurniConditionInputGuard.parseLegacyItemIds(data[1], WiredManager.MAXIMUM_FURNI_SELECTION)) {
|
||||
HabboItem item = room.getHabboItem(id);
|
||||
|
||||
if (item != null)
|
||||
this.items.add(item);
|
||||
@@ -127,9 +125,7 @@ public class WiredConditionNotFurniHaveFurni extends InteractionWiredCondition {
|
||||
}
|
||||
this.furniSource = this.items.isEmpty() ? WiredSourceUtil.SOURCE_TRIGGER : WiredSourceUtil.SOURCE_SELECTED;
|
||||
}
|
||||
if (this.furniSource == WiredSourceUtil.SOURCE_TRIGGER && !this.items.isEmpty()) {
|
||||
this.furniSource = WiredSourceUtil.SOURCE_SELECTED;
|
||||
}
|
||||
this.furniSource = WiredFurniConditionInputGuard.selectedOrNormalizedFurniSource(this.furniSource, !this.items.isEmpty());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -172,14 +168,12 @@ public class WiredConditionNotFurniHaveFurni extends InteractionWiredCondition {
|
||||
if(settings.getIntParams().length < 1) return false;
|
||||
int[] params = settings.getIntParams();
|
||||
this.all = params[0] == 1;
|
||||
this.furniSource = (params.length > 1) ? params[1] : WiredSourceUtil.SOURCE_TRIGGER;
|
||||
this.furniSource = (params.length > 1) ? WiredFurniConditionInputGuard.normalizeFurniSource(params[1]) : WiredSourceUtil.SOURCE_TRIGGER;
|
||||
|
||||
int count = settings.getFurniIds().length;
|
||||
if (count > Emulator.getConfig().getInt("hotel.wired.furni.selection.count")) return false;
|
||||
|
||||
if (count > 0 && this.furniSource == WiredSourceUtil.SOURCE_TRIGGER) {
|
||||
this.furniSource = WiredSourceUtil.SOURCE_SELECTED;
|
||||
}
|
||||
this.furniSource = WiredFurniConditionInputGuard.selectedOrNormalizedFurniSource(this.furniSource, count > 0);
|
||||
|
||||
this.items.clear();
|
||||
|
||||
|
||||
+8
-14
@@ -95,10 +95,10 @@ public class WiredConditionNotFurniHaveHabbo extends InteractionWiredCondition {
|
||||
|
||||
if (wiredData.startsWith("{")) {
|
||||
WiredConditionFurniHaveHabbo.JsonData data = WiredManager.getGson().fromJson(wiredData, WiredConditionFurniHaveHabbo.JsonData.class);
|
||||
this.furniSource = data.furniSource;
|
||||
this.furniSource = WiredFurniConditionInputGuard.normalizeFurniSource(data.furniSource);
|
||||
this.all = data.all;
|
||||
|
||||
for(int id : data.itemIds) {
|
||||
for(int id : WiredFurniConditionInputGuard.sanitizeItemIds(data.itemIds, WiredManager.MAXIMUM_FURNI_SELECTION)) {
|
||||
HabboItem item = room.getHabboItem(id);
|
||||
|
||||
if (item != null) {
|
||||
@@ -108,11 +108,9 @@ public class WiredConditionNotFurniHaveHabbo extends InteractionWiredCondition {
|
||||
} else {
|
||||
String[] data = wiredData.split(":");
|
||||
|
||||
if (data.length >= 1) {
|
||||
String[] items = data[1].split(";");
|
||||
|
||||
for (String s : items) {
|
||||
HabboItem item = room.getHabboItem(Integer.parseInt(s));
|
||||
if (data.length >= 2) {
|
||||
for (int id : WiredFurniConditionInputGuard.parseLegacyItemIds(data[1], WiredManager.MAXIMUM_FURNI_SELECTION)) {
|
||||
HabboItem item = room.getHabboItem(id);
|
||||
|
||||
if (item != null)
|
||||
this.items.add(item);
|
||||
@@ -121,9 +119,7 @@ public class WiredConditionNotFurniHaveHabbo extends InteractionWiredCondition {
|
||||
this.furniSource = this.items.isEmpty() ? WiredSourceUtil.SOURCE_TRIGGER : WiredSourceUtil.SOURCE_SELECTED;
|
||||
this.all = false;
|
||||
}
|
||||
if (this.furniSource == WiredSourceUtil.SOURCE_TRIGGER && !this.items.isEmpty()) {
|
||||
this.furniSource = WiredSourceUtil.SOURCE_SELECTED;
|
||||
}
|
||||
this.furniSource = WiredFurniConditionInputGuard.selectedOrNormalizedFurniSource(this.furniSource, !this.items.isEmpty());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -161,11 +157,9 @@ public class WiredConditionNotFurniHaveHabbo extends InteractionWiredCondition {
|
||||
|
||||
int[] params = settings.getIntParams();
|
||||
this.all = (params.length > 0) && (params[0] == 1);
|
||||
this.furniSource = (params.length > 1) ? params[1] : ((params.length > 0 && params[0] > 1) ? params[0] : WiredSourceUtil.SOURCE_TRIGGER);
|
||||
this.furniSource = (params.length > 1) ? WiredFurniConditionInputGuard.normalizeFurniSource(params[1]) : ((params.length > 0 && params[0] > 1) ? WiredFurniConditionInputGuard.normalizeFurniSource(params[0]) : WiredSourceUtil.SOURCE_TRIGGER);
|
||||
|
||||
if (count > 0 && this.furniSource == WiredSourceUtil.SOURCE_TRIGGER) {
|
||||
this.furniSource = WiredSourceUtil.SOURCE_SELECTED;
|
||||
}
|
||||
this.furniSource = WiredFurniConditionInputGuard.selectedOrNormalizedFurniSource(this.furniSource, count > 0);
|
||||
|
||||
this.items.clear();
|
||||
|
||||
|
||||
+24
-12
@@ -6,8 +6,8 @@ import com.eu.habbo.habbohotel.items.interactions.wired.WiredSettings;
|
||||
import com.eu.habbo.habbohotel.rooms.Room;
|
||||
import com.eu.habbo.habbohotel.rooms.RoomUnit;
|
||||
import com.eu.habbo.habbohotel.wired.WiredConditionType;
|
||||
import com.eu.habbo.habbohotel.wired.core.WiredManager;
|
||||
import com.eu.habbo.habbohotel.wired.core.WiredContext;
|
||||
import com.eu.habbo.habbohotel.wired.core.WiredManager;
|
||||
import com.eu.habbo.habbohotel.wired.core.WiredSourceUtil;
|
||||
import com.eu.habbo.messages.ServerMessage;
|
||||
|
||||
@@ -31,6 +31,10 @@ public class WiredConditionNotHabboCount extends InteractionWiredCondition {
|
||||
|
||||
@Override
|
||||
public boolean evaluate(WiredContext ctx) {
|
||||
if (ctx == null || ctx.room() == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
int count = (this.userSource == WiredSourceUtil.SOURCE_TRIGGER)
|
||||
? ctx.room().getUserCount()
|
||||
: WiredSourceUtil.resolveUsers(ctx, this.userSource).size();
|
||||
@@ -55,31 +59,34 @@ public class WiredConditionNotHabboCount extends InteractionWiredCondition {
|
||||
|
||||
@Override
|
||||
public void loadWiredData(ResultSet set, Room room) throws SQLException {
|
||||
this.onPickUp();
|
||||
|
||||
String wiredData = set.getString("wired_data");
|
||||
if (wiredData == null || wiredData.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (wiredData.startsWith("{")) {
|
||||
WiredConditionHabboCount.JsonData data = WiredManager.getGson().fromJson(wiredData, WiredConditionHabboCount.JsonData.class);
|
||||
this.lowerLimit = data.lowerLimit;
|
||||
this.upperLimit = data.upperLimit;
|
||||
this.userSource = data.userSource;
|
||||
this.applyLimits(data.lowerLimit, data.upperLimit);
|
||||
this.userSource = WiredConditionInputGuard.normalizeUserSource(data.userSource);
|
||||
} else {
|
||||
String[] data = wiredData.split(":");
|
||||
if (data.length >= 2) {
|
||||
try {
|
||||
this.lowerLimit = Integer.parseInt(data[0].trim());
|
||||
this.upperLimit = Integer.parseInt(data[1].trim());
|
||||
this.applyLimits(Integer.parseInt(data[0].trim()), Integer.parseInt(data[1].trim()));
|
||||
} catch (NumberFormatException ignored) {
|
||||
// malformed legacy data — keep the constructed defaults
|
||||
}
|
||||
}
|
||||
this.userSource = WiredSourceUtil.SOURCE_TRIGGER;
|
||||
}
|
||||
this.userSource = WiredSourceUtil.SOURCE_TRIGGER;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPickUp() {
|
||||
this.upperLimit = 0;
|
||||
this.lowerLimit = 20;
|
||||
this.lowerLimit = 10;
|
||||
this.upperLimit = 20;
|
||||
this.userSource = WiredSourceUtil.SOURCE_TRIGGER;
|
||||
}
|
||||
|
||||
@@ -109,14 +116,19 @@ public class WiredConditionNotHabboCount extends InteractionWiredCondition {
|
||||
@Override
|
||||
public boolean saveData(WiredSettings settings) {
|
||||
if(settings.getIntParams().length < 2) return false;
|
||||
this.lowerLimit = settings.getIntParams()[0];
|
||||
this.upperLimit = settings.getIntParams()[1];
|
||||
int[] params = settings.getIntParams();
|
||||
this.userSource = (params.length > 2) ? params[2] : WiredSourceUtil.SOURCE_TRIGGER;
|
||||
this.applyLimits(params[0], params[1]);
|
||||
this.userSource = (params.length > 2) ? WiredConditionInputGuard.normalizeUserSource(params[2]) : WiredSourceUtil.SOURCE_TRIGGER;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private void applyLimits(int lowerLimit, int upperLimit) {
|
||||
int[] limits = WiredConditionInputGuard.normalizeUserCountRange(lowerLimit, upperLimit);
|
||||
this.lowerLimit = limits[0];
|
||||
this.upperLimit = limits[1];
|
||||
}
|
||||
|
||||
static class JsonData {
|
||||
int lowerLimit;
|
||||
int upperLimit;
|
||||
|
||||
+6
-1
@@ -29,6 +29,7 @@ abstract class WiredConditionTeamGameBase extends InteractionWiredCondition {
|
||||
protected static final int COMPARISON_EQUAL = 1;
|
||||
protected static final int COMPARISON_HIGHER = 2;
|
||||
protected static final int TEAM_TRIGGERER = 0;
|
||||
protected static final int MAX_SCORE = 1_000_000;
|
||||
|
||||
private static final GameTeamColors[] SUPPORTED_TEAM_COLORS = new GameTeamColors[] {
|
||||
GameTeamColors.RED,
|
||||
@@ -96,7 +97,11 @@ abstract class WiredConditionTeamGameBase extends InteractionWiredCondition {
|
||||
}
|
||||
|
||||
protected int normalizeScore(int value) {
|
||||
return Math.max(0, value);
|
||||
if (value < 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return Math.min(value, MAX_SCORE);
|
||||
}
|
||||
|
||||
protected int normalizeExplicitTeamType(int value) {
|
||||
|
||||
+7
-1
@@ -65,7 +65,13 @@ public class WiredConditionTeamHasRank extends WiredConditionTeamGameBase {
|
||||
return;
|
||||
}
|
||||
|
||||
JsonData data = WiredManager.getGson().fromJson(wiredData, JsonData.class);
|
||||
JsonData data;
|
||||
try {
|
||||
data = WiredManager.getGson().fromJson(wiredData, JsonData.class);
|
||||
} catch (RuntimeException ignored) {
|
||||
this.resetSettings();
|
||||
return;
|
||||
}
|
||||
if (data == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
+7
-1
@@ -66,7 +66,13 @@ public class WiredConditionTeamHasScore extends WiredConditionTeamGameBase {
|
||||
return;
|
||||
}
|
||||
|
||||
JsonData data = WiredManager.getGson().fromJson(wiredData, JsonData.class);
|
||||
JsonData data;
|
||||
try {
|
||||
data = WiredManager.getGson().fromJson(wiredData, JsonData.class);
|
||||
} catch (RuntimeException ignored) {
|
||||
this.resetSettings();
|
||||
return;
|
||||
}
|
||||
if (data == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
+5
-5
@@ -97,12 +97,12 @@ public class WiredConditionTeamMember extends InteractionWiredCondition {
|
||||
|
||||
if (wiredData.startsWith("{")) {
|
||||
JsonData data = WiredManager.getGson().fromJson(wiredData, JsonData.class);
|
||||
this.teamColor = data.teamColor;
|
||||
this.userSource = data.userSource;
|
||||
this.teamColor = WiredConditionInputGuard.normalizeTeamColor(data.teamColor, GameTeamColors.RED);
|
||||
this.userSource = WiredConditionInputGuard.normalizeUserSource(data.userSource);
|
||||
this.quantifier = this.normalizeQuantifier(data.quantifier, QUANTIFIER_ANY);
|
||||
} else {
|
||||
if (!wiredData.equals(""))
|
||||
this.teamColor = GameTeamColors.values()[Integer.parseInt(wiredData)];
|
||||
this.teamColor = WiredConditionInputGuard.normalizeTeamColorType(Integer.parseInt(wiredData), GameTeamColors.RED);
|
||||
this.userSource = WiredSourceUtil.SOURCE_TRIGGER;
|
||||
this.quantifier = QUANTIFIER_ANY;
|
||||
}
|
||||
@@ -147,8 +147,8 @@ public class WiredConditionTeamMember extends InteractionWiredCondition {
|
||||
public boolean saveData(WiredSettings settings) {
|
||||
if(settings.getIntParams().length < 1) return false;
|
||||
int[] params = settings.getIntParams();
|
||||
this.teamColor = GameTeamColors.values()[params[0]];
|
||||
this.userSource = (params.length > 1) ? params[1] : WiredSourceUtil.SOURCE_TRIGGER;
|
||||
this.teamColor = WiredConditionInputGuard.normalizeTeamColorType(params[0], GameTeamColors.RED);
|
||||
this.userSource = (params.length > 1) ? WiredConditionInputGuard.normalizeUserSource(params[1]) : WiredSourceUtil.SOURCE_TRIGGER;
|
||||
this.quantifier = (params.length > 2) ? this.normalizeQuantifier(params[2], QUANTIFIER_ALL) : QUANTIFIER_ANY;
|
||||
|
||||
return true;
|
||||
|
||||
+11
-32
@@ -115,27 +115,13 @@ public class WiredConditionTriggerOnFurni extends InteractionWiredCondition {
|
||||
}
|
||||
|
||||
if (wiredData.startsWith("{")) {
|
||||
JsonData data;
|
||||
try {
|
||||
data = WiredManager.getGson().fromJson(wiredData, JsonData.class);
|
||||
} catch (RuntimeException exception) {
|
||||
this.onPickUp();
|
||||
return;
|
||||
}
|
||||
|
||||
if (data == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.furniSource = this.normalizeFurniSource(data.furniSource);
|
||||
this.userSource = this.normalizeUserSource(data.userSource);
|
||||
JsonData data = WiredManager.getGson().fromJson(wiredData, JsonData.class);
|
||||
this.furniSource = WiredFurniConditionInputGuard.normalizeFurniSource(data.furniSource);
|
||||
this.userSource = WiredFurniConditionInputGuard.normalizeUserSource(data.userSource);
|
||||
this.quantifier = this.normalizeQuantifier(data.quantifier);
|
||||
|
||||
if (data.itemIds != null && room != null) {
|
||||
for (Integer id : data.itemIds) {
|
||||
if (id == null) {
|
||||
continue;
|
||||
}
|
||||
for(int id : WiredFurniConditionInputGuard.sanitizeItemIds(data.itemIds, WiredManager.MAXIMUM_FURNI_SELECTION)) {
|
||||
HabboItem item = room.getHabboItem(id);
|
||||
|
||||
HabboItem item = room.getHabboItem(id);
|
||||
if (item != null) {
|
||||
@@ -144,11 +130,8 @@ public class WiredConditionTriggerOnFurni extends InteractionWiredCondition {
|
||||
}
|
||||
}
|
||||
} else {
|
||||
String[] data = wiredData.split(";");
|
||||
|
||||
for (String s : data) {
|
||||
try {
|
||||
HabboItem item = room.getHabboItem(Integer.parseInt(s));
|
||||
for (int id : WiredFurniConditionInputGuard.parseLegacyItemIds(wiredData, WiredManager.MAXIMUM_FURNI_SELECTION)) {
|
||||
HabboItem item = room.getHabboItem(id);
|
||||
|
||||
if (item != null) {
|
||||
this.items.add(item);
|
||||
@@ -160,9 +143,7 @@ public class WiredConditionTriggerOnFurni extends InteractionWiredCondition {
|
||||
this.userSource = WiredSourceUtil.SOURCE_TRIGGER;
|
||||
this.quantifier = QUANTIFIER_ALL;
|
||||
}
|
||||
if (this.furniSource == WiredSourceUtil.SOURCE_TRIGGER && !this.items.isEmpty()) {
|
||||
this.furniSource = WiredSourceUtil.SOURCE_SELECTED;
|
||||
}
|
||||
this.furniSource = WiredFurniConditionInputGuard.selectedOrNormalizedFurniSource(this.furniSource, !this.items.isEmpty());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -208,13 +189,11 @@ public class WiredConditionTriggerOnFurni extends InteractionWiredCondition {
|
||||
if (count > Emulator.getConfig().getInt("hotel.wired.furni.selection.count")) return false;
|
||||
|
||||
int[] params = settings.getIntParams();
|
||||
this.furniSource = (params.length > 0) ? this.normalizeFurniSource(params[0]) : WiredSourceUtil.SOURCE_TRIGGER;
|
||||
this.userSource = (params.length > 1) ? this.normalizeUserSource(params[1]) : WiredSourceUtil.SOURCE_TRIGGER;
|
||||
this.furniSource = (params.length > 0) ? WiredFurniConditionInputGuard.normalizeFurniSource(params[0]) : WiredSourceUtil.SOURCE_TRIGGER;
|
||||
this.userSource = (params.length > 1) ? WiredFurniConditionInputGuard.normalizeUserSource(params[1]) : WiredSourceUtil.SOURCE_TRIGGER;
|
||||
this.quantifier = (params.length > 2) ? this.normalizeQuantifier(params[2]) : QUANTIFIER_ALL;
|
||||
|
||||
if (count > 0 && this.furniSource == WiredSourceUtil.SOURCE_TRIGGER) {
|
||||
this.furniSource = WiredSourceUtil.SOURCE_SELECTED;
|
||||
}
|
||||
this.furniSource = WiredFurniConditionInputGuard.selectedOrNormalizedFurniSource(this.furniSource, count > 0);
|
||||
|
||||
this.items.clear();
|
||||
|
||||
|
||||
+21
-8
@@ -33,6 +33,7 @@ public class WiredConditionTriggererMatch extends InteractionWiredCondition {
|
||||
protected static final int QUANTIFIER_ALL = 0;
|
||||
protected static final int QUANTIFIER_ANY = 1;
|
||||
protected static final int SOURCE_SPECIFIED_USERNAME = 101;
|
||||
protected static final int MAX_USERNAME_LENGTH = 64;
|
||||
|
||||
public static final WiredConditionType type = WiredConditionType.TRIGGERER_MATCH;
|
||||
|
||||
@@ -84,7 +85,14 @@ public class WiredConditionTriggererMatch extends InteractionWiredCondition {
|
||||
return;
|
||||
}
|
||||
|
||||
JsonData data = WiredManager.getGson().fromJson(wiredData, JsonData.class);
|
||||
JsonData data;
|
||||
try {
|
||||
data = WiredManager.getGson().fromJson(wiredData, JsonData.class);
|
||||
} catch (RuntimeException exception) {
|
||||
this.resetSettings();
|
||||
return;
|
||||
}
|
||||
|
||||
if (data == null) {
|
||||
return;
|
||||
}
|
||||
@@ -284,7 +292,7 @@ public class WiredConditionTriggererMatch extends InteractionWiredCondition {
|
||||
return "";
|
||||
}
|
||||
|
||||
private int normalizeEntityType(int value) {
|
||||
int normalizeEntityType(int value) {
|
||||
switch (value) {
|
||||
case ENTITY_HABBO:
|
||||
case ENTITY_PET:
|
||||
@@ -295,19 +303,19 @@ public class WiredConditionTriggererMatch extends InteractionWiredCondition {
|
||||
}
|
||||
}
|
||||
|
||||
private int normalizeAvatarMode(int value) {
|
||||
int normalizeAvatarMode(int value) {
|
||||
return (value == AVATAR_MODE_CERTAIN) ? AVATAR_MODE_CERTAIN : AVATAR_MODE_ANY;
|
||||
}
|
||||
|
||||
private int normalizeQuantifier(int value) {
|
||||
int normalizeQuantifier(int value) {
|
||||
return (value == QUANTIFIER_ANY) ? QUANTIFIER_ANY : QUANTIFIER_ALL;
|
||||
}
|
||||
|
||||
private int normalizePrimaryUserSource(int value) {
|
||||
int normalizePrimaryUserSource(int value) {
|
||||
return WiredSourceUtil.isDefaultUserSource(value) ? value : WiredSourceUtil.SOURCE_TRIGGER;
|
||||
}
|
||||
|
||||
private int normalizeCompareUserSource(int value) {
|
||||
int normalizeCompareUserSource(int value) {
|
||||
switch (value) {
|
||||
case WiredSourceUtil.SOURCE_CLICKED_USER:
|
||||
case SOURCE_SPECIFIED_USERNAME:
|
||||
@@ -317,8 +325,13 @@ public class WiredConditionTriggererMatch extends InteractionWiredCondition {
|
||||
}
|
||||
}
|
||||
|
||||
private String normalizeUsername(String value) {
|
||||
return (value == null) ? "" : value.trim();
|
||||
String normalizeUsername(String value) {
|
||||
if (value == null) {
|
||||
return "";
|
||||
}
|
||||
|
||||
String normalized = value.trim();
|
||||
return normalized.length() <= MAX_USERNAME_LENGTH ? normalized : normalized.substring(0, MAX_USERNAME_LENGTH);
|
||||
}
|
||||
|
||||
protected static class MatchResult {
|
||||
|
||||
+8
-2
@@ -87,7 +87,13 @@ public class WiredConditionUserPerformsAction extends InteractionWiredCondition
|
||||
return;
|
||||
}
|
||||
|
||||
JsonData data = WiredManager.getGson().fromJson(wiredData, JsonData.class);
|
||||
JsonData data;
|
||||
try {
|
||||
data = WiredManager.getGson().fromJson(wiredData, JsonData.class);
|
||||
} catch (RuntimeException ignored) {
|
||||
this.resetSettings();
|
||||
return;
|
||||
}
|
||||
|
||||
if (data == null) {
|
||||
return;
|
||||
@@ -253,7 +259,7 @@ public class WiredConditionUserPerformsAction extends InteractionWiredCondition
|
||||
}
|
||||
|
||||
long timestamp = (Long) timestampValue;
|
||||
if ((System.currentTimeMillis() - timestamp) > TRANSIENT_ACTION_WINDOW_MS) {
|
||||
if (!WiredUserActionInputGuard.isRecentTimestamp(timestamp, System.currentTimeMillis(), TRANSIENT_ACTION_WINDOW_MS)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
package com.eu.habbo.habbohotel.items.interactions.wired.conditions;
|
||||
|
||||
public final class WiredDateRangeInputGuard {
|
||||
private WiredDateRangeInputGuard() {
|
||||
}
|
||||
|
||||
public static int[] normalizeRange(int startDate, int endDate) {
|
||||
int start = normalizeTimestamp(startDate);
|
||||
int end = normalizeTimestamp(endDate);
|
||||
|
||||
if (start > end) {
|
||||
return new int[]{0, 0};
|
||||
}
|
||||
|
||||
return new int[]{start, end};
|
||||
}
|
||||
|
||||
public static int normalizeTimestamp(int value) {
|
||||
return Math.max(0, value);
|
||||
}
|
||||
}
|
||||
+76
@@ -0,0 +1,76 @@
|
||||
package com.eu.habbo.habbohotel.items.interactions.wired.conditions;
|
||||
|
||||
import com.eu.habbo.habbohotel.wired.core.WiredSourceUtil;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
public final class WiredFurniConditionInputGuard {
|
||||
private WiredFurniConditionInputGuard() {
|
||||
}
|
||||
|
||||
public static int normalizeFurniSource(int value) {
|
||||
switch (value) {
|
||||
case WiredSourceUtil.SOURCE_SELECTED:
|
||||
case WiredSourceUtil.SOURCE_SELECTOR:
|
||||
case WiredSourceUtil.SOURCE_SIGNAL:
|
||||
case WiredSourceUtil.SOURCE_TRIGGER:
|
||||
return value;
|
||||
default:
|
||||
return WiredSourceUtil.SOURCE_TRIGGER;
|
||||
}
|
||||
}
|
||||
|
||||
public static int normalizeUserSource(int value) {
|
||||
return WiredSourceUtil.isDefaultUserSource(value) ? value : WiredSourceUtil.SOURCE_TRIGGER;
|
||||
}
|
||||
|
||||
public static int selectedOrNormalizedFurniSource(int value, boolean hasSelectedItems) {
|
||||
int source = normalizeFurniSource(value);
|
||||
return (hasSelectedItems && source == WiredSourceUtil.SOURCE_TRIGGER)
|
||||
? WiredSourceUtil.SOURCE_SELECTED
|
||||
: source;
|
||||
}
|
||||
|
||||
public static List<Integer> sanitizeItemIds(Collection<Integer> itemIds, int maxCount) {
|
||||
List<Integer> result = new ArrayList<>();
|
||||
if (itemIds == null || maxCount < 1) {
|
||||
return result;
|
||||
}
|
||||
|
||||
for (Integer itemId : itemIds) {
|
||||
if (itemId == null || itemId < 1 || result.size() >= maxCount) {
|
||||
continue;
|
||||
}
|
||||
|
||||
result.add(itemId);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public static List<Integer> parseLegacyItemIds(String value, int maxCount) {
|
||||
List<Integer> result = new ArrayList<>();
|
||||
if (value == null || value.isBlank() || maxCount < 1) {
|
||||
return result;
|
||||
}
|
||||
|
||||
for (String part : value.split("[;,:\\t]")) {
|
||||
if (result.size() >= maxCount) {
|
||||
break;
|
||||
}
|
||||
|
||||
try {
|
||||
int id = Integer.parseInt(part.trim());
|
||||
if (id > 0) {
|
||||
result.add(id);
|
||||
}
|
||||
} catch (NumberFormatException ignored) {
|
||||
// Ignore malformed legacy item ids.
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
+92
@@ -0,0 +1,92 @@
|
||||
package com.eu.habbo.habbohotel.items.interactions.wired.conditions;
|
||||
|
||||
import com.eu.habbo.habbohotel.rooms.Room;
|
||||
import com.eu.habbo.habbohotel.users.HabboItem;
|
||||
import com.eu.habbo.habbohotel.wired.WiredMatchFurniSetting;
|
||||
import com.eu.habbo.habbohotel.wired.core.WiredManager;
|
||||
import com.eu.habbo.habbohotel.wired.core.WiredSourceUtil;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
public final class WiredMatchPositionInputGuard {
|
||||
public static final int MAX_STATE_LENGTH = 512;
|
||||
|
||||
private WiredMatchPositionInputGuard() {
|
||||
}
|
||||
|
||||
public static int normalizeFurniSource(int value, boolean hasSelectedSettings) {
|
||||
int source = switch (value) {
|
||||
case WiredSourceUtil.SOURCE_SELECTED, WiredSourceUtil.SOURCE_SELECTOR,
|
||||
WiredSourceUtil.SOURCE_SIGNAL, WiredSourceUtil.SOURCE_TRIGGER -> value;
|
||||
default -> WiredSourceUtil.SOURCE_TRIGGER;
|
||||
};
|
||||
|
||||
return (hasSelectedSettings && source == WiredSourceUtil.SOURCE_TRIGGER)
|
||||
? WiredSourceUtil.SOURCE_SELECTED
|
||||
: source;
|
||||
}
|
||||
|
||||
public static List<WiredMatchFurniSetting> sanitizeSettings(Collection<WiredMatchFurniSetting> settings, Room room) {
|
||||
List<WiredMatchFurniSetting> result = new ArrayList<>();
|
||||
if (settings == null || room == null) {
|
||||
return result;
|
||||
}
|
||||
|
||||
for (WiredMatchFurniSetting setting : settings) {
|
||||
WiredMatchFurniSetting normalized = sanitizeSetting(setting, room);
|
||||
if (normalized != null) {
|
||||
result.add(normalized);
|
||||
}
|
||||
|
||||
if (result.size() >= WiredManager.MAXIMUM_FURNI_SELECTION) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public static WiredMatchFurniSetting sanitizeSetting(WiredMatchFurniSetting setting, Room room) {
|
||||
if (setting == null || room == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return sanitizeParts(setting.item_id, setting.state, setting.rotation, setting.x, setting.y, setting.z, room);
|
||||
}
|
||||
|
||||
public static WiredMatchFurniSetting sanitizeParts(int itemId, String state, int rotation, int x, int y, double z, Room room) {
|
||||
if (itemId < 1 || room == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
HabboItem item = room.getHabboItem(itemId);
|
||||
if (item == null || rotation < 0 || rotation > 7 || !Double.isFinite(z)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (x < Short.MIN_VALUE || x > Short.MAX_VALUE || y < Short.MIN_VALUE || y > Short.MAX_VALUE) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (room.getLayout() != null && room.getLayout().getTile((short) x, (short) y) == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return new WiredMatchFurniSetting(itemId, normalizeState(state), rotation, x, y, z);
|
||||
}
|
||||
|
||||
public static String normalizeState(String state) {
|
||||
if (state == null) {
|
||||
return "";
|
||||
}
|
||||
|
||||
String normalized = state.replace('\t', ' ').replace('\r', ' ').replace('\n', ' ');
|
||||
if (normalized.length() > MAX_STATE_LENGTH) {
|
||||
return normalized.substring(0, MAX_STATE_LENGTH);
|
||||
}
|
||||
|
||||
return normalized;
|
||||
}
|
||||
}
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
package com.eu.habbo.habbohotel.items.interactions.wired.conditions;
|
||||
|
||||
public final class WiredUserActionInputGuard {
|
||||
private WiredUserActionInputGuard() {
|
||||
}
|
||||
|
||||
public static boolean isRecentTimestamp(long timestamp, long now, long windowMs) {
|
||||
if (timestamp < 1 || timestamp > now || windowMs < 1) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return (now - timestamp) <= windowMs;
|
||||
}
|
||||
}
|
||||
+45
@@ -0,0 +1,45 @@
|
||||
package com.eu.habbo.habbohotel.items.interactions.wired.conditions;
|
||||
|
||||
import com.eu.habbo.habbohotel.wired.core.WiredSourceUtil;
|
||||
|
||||
public final class WiredUserConditionInputGuard {
|
||||
public static final int MAX_BADGE_CODE_LENGTH = 64;
|
||||
public static final int MAX_EFFECT_ID = 10_000;
|
||||
public static final int MAX_HAND_ITEM_ID = 10_000;
|
||||
|
||||
private WiredUserConditionInputGuard() {
|
||||
}
|
||||
|
||||
public static String normalizeBadgeCode(String value) {
|
||||
if (value == null) {
|
||||
return "";
|
||||
}
|
||||
|
||||
String normalized = value.trim().replace('\t', ' ').replace('\r', ' ').replace('\n', ' ');
|
||||
if (normalized.length() > MAX_BADGE_CODE_LENGTH) {
|
||||
return normalized.substring(0, MAX_BADGE_CODE_LENGTH);
|
||||
}
|
||||
|
||||
return normalized;
|
||||
}
|
||||
|
||||
public static int normalizeUserSource(int value) {
|
||||
return WiredSourceUtil.isDefaultUserSource(value) ? value : WiredSourceUtil.SOURCE_TRIGGER;
|
||||
}
|
||||
|
||||
public static int normalizeEffectId(int value) {
|
||||
if (value < 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return Math.min(value, MAX_EFFECT_ID);
|
||||
}
|
||||
|
||||
public static int normalizeHandItemId(int value) {
|
||||
if (value < 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return Math.min(value, MAX_HAND_ITEM_ID);
|
||||
}
|
||||
}
|
||||
+4
-3
@@ -5,6 +5,7 @@ import com.eu.habbo.habbohotel.gameclients.GameClient;
|
||||
import com.eu.habbo.habbohotel.items.Item;
|
||||
import com.eu.habbo.habbohotel.items.interactions.InteractionWiredEffect;
|
||||
import com.eu.habbo.habbohotel.items.interactions.InteractionWiredTrigger;
|
||||
import com.eu.habbo.habbohotel.items.interactions.wired.WiredNumericInputGuard;
|
||||
import com.eu.habbo.habbohotel.items.interactions.wired.WiredSettings;
|
||||
import com.eu.habbo.habbohotel.rooms.Room;
|
||||
import com.eu.habbo.habbohotel.rooms.RoomUnit;
|
||||
@@ -72,11 +73,11 @@ public class WiredEffectGiveHotelviewBonusRarePoints extends InteractionWiredEff
|
||||
|
||||
@Override
|
||||
public boolean saveData(WiredSettings settings, GameClient gameClient) {
|
||||
try {
|
||||
this.amount = Integer.parseInt(settings.getStringParam());
|
||||
} catch (Exception e) {
|
||||
int nextAmount = WiredNumericInputGuard.parsePositiveAmount(settings.getStringParam(), WiredNumericInputGuard.maxRewardAmount());
|
||||
if (nextAmount <= 0) {
|
||||
return false;
|
||||
}
|
||||
this.amount = nextAmount;
|
||||
|
||||
int[] params = settings.getIntParams();
|
||||
this.userSource = (params.length > 0) ? params[0] : WiredSourceUtil.SOURCE_TRIGGER;
|
||||
|
||||
+4
-3
@@ -5,6 +5,7 @@ import com.eu.habbo.habbohotel.gameclients.GameClient;
|
||||
import com.eu.habbo.habbohotel.items.Item;
|
||||
import com.eu.habbo.habbohotel.items.interactions.InteractionWiredEffect;
|
||||
import com.eu.habbo.habbohotel.items.interactions.InteractionWiredTrigger;
|
||||
import com.eu.habbo.habbohotel.items.interactions.wired.WiredNumericInputGuard;
|
||||
import com.eu.habbo.habbohotel.items.interactions.wired.WiredSettings;
|
||||
import com.eu.habbo.habbohotel.rooms.Room;
|
||||
import com.eu.habbo.habbohotel.rooms.RoomUnit;
|
||||
@@ -71,11 +72,11 @@ public class WiredEffectGiveHotelviewHofPoints extends InteractionWiredEffect {
|
||||
|
||||
@Override
|
||||
public boolean saveData(WiredSettings settings, GameClient gameClient) {
|
||||
try {
|
||||
this.amount = Integer.parseInt(settings.getStringParam());
|
||||
} catch (Exception e) {
|
||||
int nextAmount = WiredNumericInputGuard.parsePositiveAmount(settings.getStringParam(), WiredNumericInputGuard.maxRewardAmount());
|
||||
if (nextAmount <= 0) {
|
||||
return false;
|
||||
}
|
||||
this.amount = nextAmount;
|
||||
|
||||
int[] params = settings.getIntParams();
|
||||
this.userSource = (params.length > 0) ? params[0] : WiredSourceUtil.SOURCE_TRIGGER;
|
||||
|
||||
+4
-3
@@ -6,6 +6,7 @@ import com.eu.habbo.habbohotel.gameclients.GameClient;
|
||||
import com.eu.habbo.habbohotel.items.Item;
|
||||
import com.eu.habbo.habbohotel.items.interactions.InteractionWiredEffect;
|
||||
import com.eu.habbo.habbohotel.items.interactions.InteractionWiredTrigger;
|
||||
import com.eu.habbo.habbohotel.items.interactions.wired.WiredNumericInputGuard;
|
||||
import com.eu.habbo.habbohotel.items.interactions.wired.WiredSettings;
|
||||
import com.eu.habbo.habbohotel.rooms.Room;
|
||||
import com.eu.habbo.habbohotel.rooms.RoomUnit;
|
||||
@@ -72,11 +73,11 @@ public class WiredEffectGiveRespect extends InteractionWiredEffect {
|
||||
|
||||
@Override
|
||||
public boolean saveData(WiredSettings settings, GameClient gameClient) {
|
||||
try {
|
||||
this.respects = Integer.parseInt(settings.getStringParam());
|
||||
} catch (Exception e) {
|
||||
int nextRespects = WiredNumericInputGuard.parsePositiveAmount(settings.getStringParam(), WiredNumericInputGuard.maxRespectAmount());
|
||||
if (nextRespects <= 0) {
|
||||
return false;
|
||||
}
|
||||
this.respects = nextRespects;
|
||||
|
||||
int[] params = settings.getIntParams();
|
||||
this.userSource = (params.length > 0) ? params[0] : WiredSourceUtil.SOURCE_TRIGGER;
|
||||
|
||||
+3
-7
@@ -5,6 +5,7 @@ import com.eu.habbo.habbohotel.gameclients.GameClient;
|
||||
import com.eu.habbo.habbohotel.items.Item;
|
||||
import com.eu.habbo.habbohotel.items.interactions.InteractionWiredEffect;
|
||||
import com.eu.habbo.habbohotel.items.interactions.InteractionWiredTrigger;
|
||||
import com.eu.habbo.habbohotel.items.interactions.wired.WiredLegacyDataGuard;
|
||||
import com.eu.habbo.habbohotel.items.interactions.wired.WiredSettings;
|
||||
import com.eu.habbo.habbohotel.pets.RideablePet;
|
||||
import com.eu.habbo.habbohotel.rooms.*;
|
||||
@@ -287,16 +288,11 @@ public class WiredEffectTeleport extends InteractionWiredEffect {
|
||||
String[] wiredDataOld = wiredData.split("\t");
|
||||
|
||||
if (wiredDataOld.length >= 1) {
|
||||
this.setDelay(Integer.parseInt(wiredDataOld[0]));
|
||||
this.setDelay(WiredLegacyDataGuard.parseDelay(wiredDataOld[0]));
|
||||
}
|
||||
if (wiredDataOld.length == 2) {
|
||||
if (wiredDataOld[1].contains(";")) {
|
||||
for (String s : wiredDataOld[1].split(";")) {
|
||||
HabboItem item = room.getHabboItem(Integer.parseInt(s));
|
||||
|
||||
if (item != null)
|
||||
this.items.add(item);
|
||||
}
|
||||
this.items.addAll(WiredLegacyDataGuard.parseRoomItems(wiredDataOld[1], room));
|
||||
}
|
||||
}
|
||||
this.fastTeleport = false;
|
||||
|
||||
+4
-6
@@ -15,6 +15,7 @@ import com.eu.habbo.habbohotel.items.interactions.games.freeze.InteractionFreeze
|
||||
import com.eu.habbo.habbohotel.items.interactions.games.tag.InteractionTagField;
|
||||
import com.eu.habbo.habbohotel.items.interactions.games.tag.InteractionTagPole;
|
||||
import com.eu.habbo.habbohotel.items.interactions.pets.*;
|
||||
import com.eu.habbo.habbohotel.items.interactions.wired.WiredLegacyDataGuard;
|
||||
import com.eu.habbo.habbohotel.items.interactions.wired.WiredSettings;
|
||||
import com.eu.habbo.habbohotel.rooms.Room;
|
||||
import com.eu.habbo.habbohotel.rooms.RoomUnit;
|
||||
@@ -274,18 +275,15 @@ public class WiredEffectToggleFurni extends InteractionWiredEffect {
|
||||
String[] wiredDataOld = wiredData.split("\t");
|
||||
|
||||
if (wiredDataOld.length >= 1) {
|
||||
this.setDelay(Integer.parseInt(wiredDataOld[0]));
|
||||
this.setDelay(WiredLegacyDataGuard.parseDelay(wiredDataOld[0]));
|
||||
}
|
||||
if (wiredDataOld.length == 2) {
|
||||
if (wiredDataOld[1].contains(";")) {
|
||||
for (String s : wiredDataOld[1].split(";")) {
|
||||
HabboItem item = room.getHabboItem(Integer.parseInt(s));
|
||||
|
||||
for (HabboItem item : WiredLegacyDataGuard.parseRoomItems(wiredDataOld[1], room)) {
|
||||
if (item instanceof InteractionFreezeBlock || item instanceof InteractionFreezeTile || item instanceof InteractionCrackable)
|
||||
continue;
|
||||
|
||||
if (item != null)
|
||||
this.items.add(item);
|
||||
this.items.add(item);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+15
-10
@@ -4,6 +4,7 @@ import com.eu.habbo.habbohotel.items.Item;
|
||||
import com.eu.habbo.habbohotel.items.interactions.InteractionWiredEffect;
|
||||
import com.eu.habbo.habbohotel.items.interactions.InteractionWiredTrigger;
|
||||
import com.eu.habbo.habbohotel.items.interactions.wired.WiredSettings;
|
||||
import com.eu.habbo.habbohotel.items.interactions.wired.WiredTimerInputGuard;
|
||||
import com.eu.habbo.habbohotel.items.interactions.wired.WiredTriggerReset;
|
||||
import com.eu.habbo.habbohotel.rooms.Room;
|
||||
import com.eu.habbo.habbohotel.rooms.RoomUnit;
|
||||
@@ -29,6 +30,9 @@ import java.util.List;
|
||||
*/
|
||||
public class WiredTriggerAtSetTime extends InteractionWiredTrigger implements WiredTickable, WiredTriggerReset {
|
||||
public static final WiredTriggerType type = WiredTriggerType.AT_GIVEN_TIME;
|
||||
private static final int STEP_MS = 500;
|
||||
private static final int MIN_DELAY = STEP_MS;
|
||||
private static final int LEGACY_FALLBACK_DELAY = 20 * STEP_MS;
|
||||
|
||||
/** The time in milliseconds until the trigger fires */
|
||||
public int executeTime;
|
||||
@@ -68,18 +72,19 @@ public class WiredTriggerAtSetTime extends InteractionWiredTrigger implements Wi
|
||||
public void loadWiredData(ResultSet set, Room room) throws SQLException {
|
||||
String wiredData = set.getString("wired_data");
|
||||
|
||||
if (wiredData.startsWith("{")) {
|
||||
JsonData data = WiredManager.getGson().fromJson(wiredData, JsonData.class);
|
||||
this.executeTime = data.executeTime;
|
||||
} else {
|
||||
if (wiredData.length() >= 1) {
|
||||
this.executeTime = (Integer.parseInt(wiredData));
|
||||
Integer storedExecuteTime = null;
|
||||
try {
|
||||
if (wiredData != null && wiredData.startsWith("{")) {
|
||||
JsonData data = WiredManager.getGson().fromJson(wiredData, JsonData.class);
|
||||
storedExecuteTime = data != null ? data.executeTime : null;
|
||||
} else if (wiredData != null && wiredData.length() >= 1) {
|
||||
storedExecuteTime = Integer.parseInt(wiredData);
|
||||
}
|
||||
} catch (RuntimeException ignored) {
|
||||
storedExecuteTime = null;
|
||||
}
|
||||
|
||||
if (this.executeTime < 500) {
|
||||
this.executeTime = 20 * 500;
|
||||
}
|
||||
this.executeTime = WiredTimerInputGuard.normalizeStoredMillis(storedExecuteTime, MIN_DELAY, LEGACY_FALLBACK_DELAY);
|
||||
|
||||
// Initialize for tick system - will be registered by RoomItemManager
|
||||
this.accumulatedTime = 0;
|
||||
@@ -134,7 +139,7 @@ public class WiredTriggerAtSetTime extends InteractionWiredTrigger implements Wi
|
||||
@Override
|
||||
public boolean saveData(WiredSettings settings) {
|
||||
if (settings.getIntParams().length < 1) return false;
|
||||
this.executeTime = settings.getIntParams()[0] * 500;
|
||||
this.executeTime = WiredTimerInputGuard.fromClientUnits(settings.getIntParams()[0], STEP_MS, MIN_DELAY);
|
||||
|
||||
this.resetTimer();
|
||||
|
||||
|
||||
+15
-10
@@ -4,6 +4,7 @@ import com.eu.habbo.habbohotel.items.Item;
|
||||
import com.eu.habbo.habbohotel.items.interactions.InteractionWiredEffect;
|
||||
import com.eu.habbo.habbohotel.items.interactions.InteractionWiredTrigger;
|
||||
import com.eu.habbo.habbohotel.items.interactions.wired.WiredSettings;
|
||||
import com.eu.habbo.habbohotel.items.interactions.wired.WiredTimerInputGuard;
|
||||
import com.eu.habbo.habbohotel.items.interactions.wired.WiredTriggerReset;
|
||||
import com.eu.habbo.habbohotel.rooms.Room;
|
||||
import com.eu.habbo.habbohotel.rooms.RoomUnit;
|
||||
@@ -29,6 +30,9 @@ import java.util.List;
|
||||
*/
|
||||
public class WiredTriggerAtTimeLong extends InteractionWiredTrigger implements WiredTickable, WiredTriggerReset {
|
||||
private static final WiredTriggerType type = WiredTriggerType.AT_GIVEN_TIME;
|
||||
private static final int STEP_MS = 500;
|
||||
private static final int MIN_DELAY = STEP_MS;
|
||||
private static final int LEGACY_FALLBACK_DELAY = 20 * STEP_MS;
|
||||
|
||||
/** The time in milliseconds until the trigger fires */
|
||||
private int executeTime;
|
||||
@@ -68,18 +72,19 @@ public class WiredTriggerAtTimeLong extends InteractionWiredTrigger implements W
|
||||
public void loadWiredData(ResultSet set, Room room) throws SQLException {
|
||||
String wiredData = set.getString("wired_data");
|
||||
|
||||
if (wiredData.startsWith("{")) {
|
||||
JsonData data = WiredManager.getGson().fromJson(wiredData, JsonData.class);
|
||||
this.executeTime = data.executeTime;
|
||||
} else {
|
||||
if (wiredData.length() >= 1) {
|
||||
this.executeTime = (Integer.parseInt(wiredData));
|
||||
Integer storedExecuteTime = null;
|
||||
try {
|
||||
if (wiredData != null && wiredData.startsWith("{")) {
|
||||
JsonData data = WiredManager.getGson().fromJson(wiredData, JsonData.class);
|
||||
storedExecuteTime = data != null ? data.executeTime : null;
|
||||
} else if (wiredData != null && wiredData.length() >= 1) {
|
||||
storedExecuteTime = Integer.parseInt(wiredData);
|
||||
}
|
||||
} catch (RuntimeException ignored) {
|
||||
storedExecuteTime = null;
|
||||
}
|
||||
|
||||
if (this.executeTime < 500) {
|
||||
this.executeTime = 20 * 500;
|
||||
}
|
||||
this.executeTime = WiredTimerInputGuard.normalizeStoredMillis(storedExecuteTime, MIN_DELAY, LEGACY_FALLBACK_DELAY);
|
||||
|
||||
// Initialize for tick system
|
||||
this.accumulatedTime = 0;
|
||||
@@ -134,7 +139,7 @@ public class WiredTriggerAtTimeLong extends InteractionWiredTrigger implements W
|
||||
@Override
|
||||
public boolean saveData(WiredSettings settings) {
|
||||
if (settings.getIntParams().length < 1) return false;
|
||||
this.executeTime = settings.getIntParams()[0] * 500;
|
||||
this.executeTime = WiredTimerInputGuard.fromClientUnits(settings.getIntParams()[0], STEP_MS, MIN_DELAY);
|
||||
|
||||
this.resetTimer();
|
||||
|
||||
|
||||
+15
-16
@@ -4,6 +4,7 @@ import com.eu.habbo.habbohotel.items.Item;
|
||||
import com.eu.habbo.habbohotel.items.interactions.InteractionWiredEffect;
|
||||
import com.eu.habbo.habbohotel.items.interactions.InteractionWiredTrigger;
|
||||
import com.eu.habbo.habbohotel.items.interactions.wired.WiredSettings;
|
||||
import com.eu.habbo.habbohotel.items.interactions.wired.WiredTimerInputGuard;
|
||||
import com.eu.habbo.habbohotel.items.interactions.wired.WiredTriggerReset;
|
||||
import com.eu.habbo.habbohotel.rooms.Room;
|
||||
import com.eu.habbo.habbohotel.rooms.RoomUnit;
|
||||
@@ -30,6 +31,9 @@ import java.util.List;
|
||||
public class WiredTriggerRepeater extends InteractionWiredTrigger implements WiredTickable, WiredTriggerReset {
|
||||
public static final WiredTriggerType type = WiredTriggerType.PERIODICALLY;
|
||||
public static final int DEFAULT_DELAY = 10 * 500; // 5 seconds default
|
||||
private static final int STEP_MS = 500;
|
||||
private static final int MIN_DELAY = STEP_MS;
|
||||
private static final int LEGACY_FALLBACK_DELAY = 20 * STEP_MS;
|
||||
|
||||
/** The interval in milliseconds between triggers */
|
||||
protected int repeatTime = DEFAULT_DELAY;
|
||||
@@ -63,18 +67,19 @@ public class WiredTriggerRepeater extends InteractionWiredTrigger implements Wir
|
||||
public void loadWiredData(ResultSet set, Room room) throws SQLException {
|
||||
String wiredData = set.getString("wired_data");
|
||||
|
||||
if (wiredData.startsWith("{")) {
|
||||
JsonData data = WiredManager.getGson().fromJson(wiredData, JsonData.class);
|
||||
this.repeatTime = data.repeatTime;
|
||||
} else {
|
||||
if (wiredData.length() >= 1) {
|
||||
this.repeatTime = (Integer.parseInt(wiredData));
|
||||
Integer storedRepeatTime = null;
|
||||
try {
|
||||
if (wiredData != null && wiredData.startsWith("{")) {
|
||||
JsonData data = WiredManager.getGson().fromJson(wiredData, JsonData.class);
|
||||
storedRepeatTime = data != null ? data.repeatTime : null;
|
||||
} else if (wiredData != null && wiredData.length() >= 1) {
|
||||
storedRepeatTime = Integer.parseInt(wiredData);
|
||||
}
|
||||
} catch (RuntimeException ignored) {
|
||||
storedRepeatTime = null;
|
||||
}
|
||||
|
||||
if (this.repeatTime < 500) {
|
||||
this.repeatTime = 20 * 500;
|
||||
}
|
||||
this.repeatTime = WiredTimerInputGuard.normalizeStoredMillis(storedRepeatTime, MIN_DELAY, LEGACY_FALLBACK_DELAY);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -123,13 +128,7 @@ public class WiredTriggerRepeater extends InteractionWiredTrigger implements Wir
|
||||
@Override
|
||||
public boolean saveData(WiredSettings settings) {
|
||||
if (settings.getIntParams().length < 1) return false;
|
||||
int newRepeatTime = settings.getIntParams()[0] * 500;
|
||||
|
||||
if (newRepeatTime < 500) {
|
||||
newRepeatTime = 500;
|
||||
}
|
||||
|
||||
this.repeatTime = newRepeatTime;
|
||||
this.repeatTime = WiredTimerInputGuard.fromClientUnits(settings.getIntParams()[0], STEP_MS, MIN_DELAY);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
+15
-14
@@ -4,6 +4,7 @@ import com.eu.habbo.habbohotel.items.Item;
|
||||
import com.eu.habbo.habbohotel.items.interactions.InteractionWiredEffect;
|
||||
import com.eu.habbo.habbohotel.items.interactions.InteractionWiredTrigger;
|
||||
import com.eu.habbo.habbohotel.items.interactions.wired.WiredSettings;
|
||||
import com.eu.habbo.habbohotel.items.interactions.wired.WiredTimerInputGuard;
|
||||
import com.eu.habbo.habbohotel.items.interactions.wired.WiredTriggerReset;
|
||||
import com.eu.habbo.habbohotel.rooms.Room;
|
||||
import com.eu.habbo.habbohotel.rooms.RoomUnit;
|
||||
@@ -29,6 +30,9 @@ import java.util.List;
|
||||
*/
|
||||
public class WiredTriggerRepeaterLong extends InteractionWiredTrigger implements WiredTickable, WiredTriggerReset {
|
||||
public static final int DEFAULT_DELAY = 10 * 5000; // 50 seconds default
|
||||
private static final int STEP_MS = 5000;
|
||||
private static final int MIN_DELAY = STEP_MS;
|
||||
private static final int LEGACY_FALLBACK_DELAY = 20 * STEP_MS;
|
||||
private static final WiredTriggerType type = WiredTriggerType.PERIODICALLY_LONG;
|
||||
|
||||
/** The interval in milliseconds between triggers */
|
||||
@@ -63,18 +67,19 @@ public class WiredTriggerRepeaterLong extends InteractionWiredTrigger implements
|
||||
public void loadWiredData(ResultSet set, Room room) throws SQLException {
|
||||
String wiredData = set.getString("wired_data");
|
||||
|
||||
if (wiredData.startsWith("{")) {
|
||||
JsonData data = WiredManager.getGson().fromJson(wiredData, JsonData.class);
|
||||
this.repeatTime = data.repeatTime;
|
||||
} else {
|
||||
if (wiredData.length() >= 1) {
|
||||
this.repeatTime = (Integer.parseInt(wiredData));
|
||||
Integer storedRepeatTime = null;
|
||||
try {
|
||||
if (wiredData != null && wiredData.startsWith("{")) {
|
||||
JsonData data = WiredManager.getGson().fromJson(wiredData, JsonData.class);
|
||||
storedRepeatTime = data != null ? data.repeatTime : null;
|
||||
} else if (wiredData != null && wiredData.length() >= 1) {
|
||||
storedRepeatTime = Integer.parseInt(wiredData);
|
||||
}
|
||||
} catch (RuntimeException ignored) {
|
||||
storedRepeatTime = null;
|
||||
}
|
||||
|
||||
if (this.repeatTime < 5000) {
|
||||
this.repeatTime = 20 * 5000;
|
||||
}
|
||||
this.repeatTime = WiredTimerInputGuard.normalizeStoredMillis(storedRepeatTime, MIN_DELAY, LEGACY_FALLBACK_DELAY);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -123,11 +128,7 @@ public class WiredTriggerRepeaterLong extends InteractionWiredTrigger implements
|
||||
@Override
|
||||
public boolean saveData(WiredSettings settings) {
|
||||
if (settings.getIntParams().length < 1) return false;
|
||||
int interval = settings.getIntParams()[0];
|
||||
if (interval < 1) {
|
||||
interval = 1;
|
||||
}
|
||||
this.repeatTime = interval * 5000;
|
||||
this.repeatTime = WiredTimerInputGuard.fromClientUnits(settings.getIntParams()[0], STEP_MS, MIN_DELAY);
|
||||
// No accumulated time reset needed - using global tick count
|
||||
return true;
|
||||
}
|
||||
|
||||
+2
-2
@@ -3,6 +3,7 @@ package com.eu.habbo.habbohotel.items.interactions.wired.triggers;
|
||||
import com.eu.habbo.habbohotel.items.Item;
|
||||
import com.eu.habbo.habbohotel.items.interactions.InteractionWiredEffect;
|
||||
import com.eu.habbo.habbohotel.items.interactions.wired.WiredSettings;
|
||||
import com.eu.habbo.habbohotel.items.interactions.wired.WiredTimerInputGuard;
|
||||
import com.eu.habbo.habbohotel.rooms.Room;
|
||||
import com.eu.habbo.habbohotel.wired.WiredTriggerType;
|
||||
import com.eu.habbo.habbohotel.wired.core.WiredManager;
|
||||
@@ -94,8 +95,7 @@ public class WiredTriggerRepeaterShort extends WiredTriggerRepeater {
|
||||
public boolean saveData(WiredSettings settings) {
|
||||
if (settings.getIntParams().length < 1) return false;
|
||||
|
||||
int newRepeatTime = settings.getIntParams()[0] * STEP_MS;
|
||||
this.repeatTime = clampRepeatTime(newRepeatTime);
|
||||
this.repeatTime = WiredTimerInputGuard.fromClientUnits(settings.getIntParams()[0], STEP_MS, MIN_DELAY, MAX_DELAY);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -11,6 +11,10 @@ public enum PermissionSetting {
|
||||
ROOM_OWNER;
|
||||
|
||||
public static PermissionSetting fromString(String value) {
|
||||
if (value == null) {
|
||||
return DISALLOWED;
|
||||
}
|
||||
|
||||
switch (value) {
|
||||
case "1":
|
||||
return ALLOWED;
|
||||
|
||||
@@ -11,6 +11,7 @@ import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.sql.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
@@ -65,35 +66,45 @@ public class PermissionsManager {
|
||||
}
|
||||
|
||||
private void loadPermissionsLegacy(Connection connection) throws SQLException {
|
||||
Set<Integer> loadedRankIds = new HashSet<>();
|
||||
|
||||
try (Statement statement = connection.createStatement(); ResultSet set = statement.executeQuery("SELECT * FROM permissions ORDER BY id ASC")) {
|
||||
while (set.next()) {
|
||||
int rankId = set.getInt("id");
|
||||
loadedRankIds.add(rankId);
|
||||
|
||||
Rank rank = null;
|
||||
if (!this.ranks.containsKey(set.getInt("id"))) {
|
||||
if (!this.ranks.containsKey(rankId)) {
|
||||
rank = new Rank(set);
|
||||
this.ranks.put(set.getInt("id"), rank);
|
||||
this.ranks.put(rankId, rank);
|
||||
} else {
|
||||
rank = this.ranks.get(set.getInt("id"));
|
||||
rank = this.ranks.get(rankId);
|
||||
rank.load(set);
|
||||
}
|
||||
|
||||
this.addBadgeMapping(rank);
|
||||
}
|
||||
}
|
||||
|
||||
this.pruneMissingRanks(loadedRankIds);
|
||||
}
|
||||
|
||||
private boolean loadPermissionsNormalized(Connection connection) throws SQLException {
|
||||
boolean hasRanks = false;
|
||||
List<Rank> loadedRanks = new ArrayList<>();
|
||||
Set<Integer> loadedRankIds = new HashSet<>();
|
||||
|
||||
try (Statement statement = connection.createStatement(); ResultSet set = statement.executeQuery("SELECT * FROM permission_ranks ORDER BY id ASC")) {
|
||||
while (set.next()) {
|
||||
hasRanks = true;
|
||||
int rankId = set.getInt("id");
|
||||
loadedRankIds.add(rankId);
|
||||
|
||||
Rank rank = this.ranks.get(set.getInt("id"));
|
||||
Rank rank = this.ranks.get(rankId);
|
||||
|
||||
if (rank == null) {
|
||||
rank = new Rank(set.getInt("id"));
|
||||
this.ranks.put(set.getInt("id"), rank);
|
||||
rank = new Rank(rankId);
|
||||
this.ranks.put(rankId, rank);
|
||||
}
|
||||
|
||||
rank.loadNormalizedMetadata(set);
|
||||
@@ -141,9 +152,18 @@ public class PermissionsManager {
|
||||
}
|
||||
}
|
||||
|
||||
this.pruneMissingRanks(loadedRankIds);
|
||||
return hasDefinitions;
|
||||
}
|
||||
|
||||
private void pruneMissingRanks(Set<Integer> loadedRankIds) {
|
||||
for (int rankId : this.ranks.keys()) {
|
||||
if (!loadedRankIds.contains(rankId)) {
|
||||
this.ranks.remove(rankId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void ensureNormalizedRankColumns(Connection connection, List<Rank> loadedRanks) throws SQLException {
|
||||
Set<String> availableColumns = new HashSet<>();
|
||||
|
||||
@@ -254,6 +274,10 @@ public class PermissionsManager {
|
||||
|
||||
|
||||
public boolean hasPermission(Habbo habbo, String permission, boolean withRoomRights) {
|
||||
if (habbo == null || habbo.getHabboInfo() == null || permission == null || permission.isBlank()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!this.hasPermission(habbo.getHabboInfo().getRank(), permission, withRoomRights)) {
|
||||
for (HabboPlugin plugin : Emulator.getPluginManager().getPlugins()) {
|
||||
if (plugin.hasPermission(habbo, permission)) {
|
||||
@@ -269,15 +293,16 @@ public class PermissionsManager {
|
||||
|
||||
|
||||
public boolean hasPermission(Rank rank, String permission, boolean withRoomRights) {
|
||||
return rank.hasPermission(permission, withRoomRights);
|
||||
return rank != null && permission != null && !permission.isBlank() && rank.hasPermission(permission, withRoomRights);
|
||||
}
|
||||
|
||||
public Set<String> getStaffBadges() {
|
||||
return this.badges.keySet();
|
||||
return Collections.unmodifiableSet(new HashSet<>(this.badges.keySet()));
|
||||
}
|
||||
|
||||
public List<Rank> getRanksByBadgeCode(String code) {
|
||||
return this.badges.get(code);
|
||||
List<Rank> ranks = this.badges.get(code);
|
||||
return ranks == null ? Collections.emptyList() : Collections.unmodifiableList(new ArrayList<>(ranks));
|
||||
}
|
||||
|
||||
public List<Rank> getAllRanks() {
|
||||
|
||||
@@ -114,6 +114,10 @@ public class Rank {
|
||||
}
|
||||
|
||||
public boolean hasPermission(String key, boolean isRoomOwner) {
|
||||
if (key == null || key.isBlank()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (this.permissions.containsKey(key)) {
|
||||
Permission permission = this.permissions.get(key);
|
||||
|
||||
|
||||
@@ -23,6 +23,7 @@ public class RoomTrade {
|
||||
//Configuration. Loaded from database & updated accordingly.
|
||||
public static boolean TRADING_ENABLED = true;
|
||||
public static boolean TRADING_REQUIRES_PERK = true;
|
||||
public static final int MAX_OFFERED_ITEMS = 100;
|
||||
|
||||
private final List<RoomTradeUser> users;
|
||||
private final Room room;
|
||||
@@ -58,7 +59,7 @@ public class RoomTrade {
|
||||
public synchronized void offerItem(Habbo habbo, HabboItem item) {
|
||||
RoomTradeUser user = this.getRoomTradeUserForHabbo(habbo);
|
||||
|
||||
if (user == null || item == null || user.getItems().contains(item))
|
||||
if (user == null || item == null || user.getItems().contains(item) || user.getItems().size() >= MAX_OFFERED_ITEMS)
|
||||
return;
|
||||
|
||||
habbo.getInventory().getItemsComponent().removeHabboItem(item);
|
||||
@@ -75,6 +76,9 @@ public class RoomTrade {
|
||||
return;
|
||||
|
||||
for (HabboItem item : items) {
|
||||
if (user.getItems().size() >= MAX_OFFERED_ITEMS)
|
||||
break;
|
||||
|
||||
if (!user.getItems().contains(item)) {
|
||||
habbo.getInventory().getItemsComponent().removeHabboItem(item);
|
||||
user.getItems().add(item);
|
||||
|
||||
+9
-4
@@ -12,10 +12,15 @@ public class CatalogSearchedItemEvent extends MessageHandler {
|
||||
public void handle() throws Exception {
|
||||
int offerId = this.packet.readInt();
|
||||
|
||||
int pageId = Emulator.getGameEnvironment().getCatalogManager().offerDefs.get(offerId);
|
||||
int catalogItemId = Emulator.getGameEnvironment().getCatalogManager().offerDefs.get(offerId);
|
||||
|
||||
if (pageId != 0) {
|
||||
CatalogPage page = Emulator.getGameEnvironment().getCatalogManager().getCatalogPage(Emulator.getGameEnvironment().getCatalogManager().getCatalogItem(pageId).getPageId());
|
||||
if (catalogItemId != 0) {
|
||||
CatalogItem requestedItem = Emulator.getGameEnvironment().getCatalogManager().getCatalogItem(catalogItemId);
|
||||
if (requestedItem == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
CatalogPage page = Emulator.getGameEnvironment().getCatalogManager().getCatalogPage(requestedItem.getPageId());
|
||||
|
||||
if (page != null) {
|
||||
TIntObjectIterator<CatalogItem> iterator = page.getCatalogItems().iterator();
|
||||
@@ -25,7 +30,7 @@ public class CatalogSearchedItemEvent extends MessageHandler {
|
||||
|
||||
CatalogItem item = iterator.value();
|
||||
|
||||
if (item.getOfferId() == offerId) {
|
||||
if (item.getSearchOfferId() == offerId) {
|
||||
this.client.sendResponse(new CatalogSearchResultComposer(item));
|
||||
return;
|
||||
}
|
||||
|
||||
+4
@@ -13,6 +13,10 @@ public class BuyItemEvent extends MessageHandler {
|
||||
public void handle() throws Exception {
|
||||
int offerId = this.packet.readInt();
|
||||
|
||||
if (!MarketplaceInputGuard.isPositiveId(offerId)) {
|
||||
return;
|
||||
}
|
||||
|
||||
MarketPlace.buyItem(offerId, this.client);
|
||||
}
|
||||
}
|
||||
|
||||
+47
@@ -0,0 +1,47 @@
|
||||
package com.eu.habbo.messages.incoming.catalog.marketplace;
|
||||
|
||||
import com.eu.habbo.habbohotel.catalog.marketplace.MarketPlace;
|
||||
|
||||
final class MarketplaceInputGuard {
|
||||
static final int MAX_SEARCH_LENGTH = 30;
|
||||
static final int DEFAULT_SORT = 1;
|
||||
static final int MIN_SORT = 1;
|
||||
static final int MAX_SORT = 6;
|
||||
|
||||
private MarketplaceInputGuard() {
|
||||
}
|
||||
|
||||
static boolean isPositiveId(int id) {
|
||||
return id > 0;
|
||||
}
|
||||
|
||||
static String normalizeSearch(String query) {
|
||||
if (query == null) {
|
||||
return "";
|
||||
}
|
||||
|
||||
String normalized = query.trim();
|
||||
return normalized.length() > MAX_SEARCH_LENGTH ? normalized.substring(0, MAX_SEARCH_LENGTH) : normalized;
|
||||
}
|
||||
|
||||
static int normalizeSort(int sort) {
|
||||
return sort >= MIN_SORT && sort <= MAX_SORT ? sort : DEFAULT_SORT;
|
||||
}
|
||||
|
||||
static int normalizeMinPrice(int minPrice) {
|
||||
if (minPrice == -1) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return Math.max(0, Math.min(minPrice, MarketPlace.MAXIMUM_LISTING_PRICE));
|
||||
}
|
||||
|
||||
static int normalizeMaxPrice(int maxPrice, int minPrice) {
|
||||
if (maxPrice == -1) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
int normalized = Math.max(0, Math.min(maxPrice, MarketPlace.MAXIMUM_LISTING_PRICE));
|
||||
return minPrice > 0 && normalized > 0 && normalized < minPrice ? minPrice : normalized;
|
||||
}
|
||||
}
|
||||
+4
@@ -9,6 +9,10 @@ public class RequestItemInfoEvent extends MessageHandler {
|
||||
this.packet.readInt();
|
||||
int id = this.packet.readInt();
|
||||
|
||||
if (!MarketplaceInputGuard.isPositiveId(id)) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.client.sendResponse(new MarketplaceItemInfoComposer(id));
|
||||
}
|
||||
}
|
||||
|
||||
+4
-8
@@ -20,14 +20,10 @@ public class RequestOffersEvent extends MessageHandler {
|
||||
|
||||
@Override
|
||||
public void handle() throws Exception {
|
||||
int min = this.packet.readInt();
|
||||
int max = this.packet.readInt();
|
||||
String query = this.packet.readString();
|
||||
int type = this.packet.readInt();
|
||||
|
||||
if (query.length() > 30) {
|
||||
query = query.substring(0, 30);
|
||||
}
|
||||
int min = MarketplaceInputGuard.normalizeMinPrice(this.packet.readInt());
|
||||
int max = MarketplaceInputGuard.normalizeMaxPrice(this.packet.readInt(), min);
|
||||
String query = MarketplaceInputGuard.normalizeSearch(this.packet.readString());
|
||||
int type = MarketplaceInputGuard.normalizeSort(this.packet.readInt());
|
||||
|
||||
|
||||
boolean tryCache = min == -1 && max == -1 && query.isEmpty();
|
||||
|
||||
+1
@@ -29,6 +29,7 @@ public class SellItemEvent extends MessageHandler {
|
||||
final int furniType = this.packet.readInt(); // 1 = FLOOR_TYPE, 2 = WALL_TYPE
|
||||
final int itemId = this.packet.readInt();
|
||||
|
||||
if (!MarketplaceInputGuard.isPositiveId(itemId)) return;
|
||||
if (furniType != 1 && furniType != 2) return;
|
||||
|
||||
HabboItem item = this.client.getHabbo().getInventory().getItemsComponent().getHabboItem(itemId);
|
||||
|
||||
+5
@@ -12,6 +12,11 @@ public class TakeBackItemEvent extends MessageHandler {
|
||||
@Override
|
||||
public void handle() throws Exception {
|
||||
int offerId = this.packet.readInt();
|
||||
|
||||
if (!MarketplaceInputGuard.isPositiveId(offerId)) {
|
||||
return;
|
||||
}
|
||||
|
||||
MarketPlace.takeBackItem(this.client.getHabbo(), offerId);
|
||||
}
|
||||
}
|
||||
|
||||
+5
-3
@@ -25,14 +25,16 @@ public class AcceptFriendRequestEvent extends MessageHandler {
|
||||
|
||||
@Override
|
||||
public void handle() throws Exception {
|
||||
int count = Math.min(this.packet.readInt(), 100);
|
||||
int count = this.packet.readInt();
|
||||
if (count <= 0 || count > 100) return;
|
||||
|
||||
int userId;
|
||||
|
||||
for (int i = 0; i < count; i++) {
|
||||
userId = this.packet.readInt();
|
||||
|
||||
if (userId == 0)
|
||||
return;
|
||||
if (userId <= 0)
|
||||
continue;
|
||||
|
||||
if (this.client.getHabbo().getMessenger().getFriends().containsKey(userId)) {
|
||||
this.client.getHabbo().getMessenger().deleteFriendRequests(userId, this.client.getHabbo().getHabboInfo().getId());
|
||||
|
||||
+10
-5
@@ -1,5 +1,6 @@
|
||||
package com.eu.habbo.messages.incoming.friends;
|
||||
|
||||
import com.eu.habbo.Emulator;
|
||||
import com.eu.habbo.habbohotel.messenger.MessengerBuddy;
|
||||
import com.eu.habbo.messages.incoming.MessageHandler;
|
||||
import com.eu.habbo.messages.outgoing.friends.UpdateFriendComposer;
|
||||
@@ -12,12 +13,16 @@ public class ChangeRelationEvent extends MessageHandler {
|
||||
int relationId = this.packet.readInt();
|
||||
|
||||
MessengerBuddy buddy = this.client.getHabbo().getMessenger().getFriends().get(userId);
|
||||
if (buddy != null && relationId >= 0 && relationId <= 3) {
|
||||
if (buddy != null && FriendInputGuard.isValidRelation(relationId)) {
|
||||
UserRelationShipEvent event = new UserRelationShipEvent(this.client.getHabbo(), buddy, relationId);
|
||||
if (!event.isCancelled()) {
|
||||
buddy.setRelation(event.relationShip);
|
||||
this.client.sendResponse(new UpdateFriendComposer(this.client.getHabbo(), buddy, 0));
|
||||
}
|
||||
if (Emulator.getPluginManager().fireEvent(event).isCancelled())
|
||||
return;
|
||||
|
||||
if (!FriendInputGuard.isValidRelation(event.relationShip))
|
||||
return;
|
||||
|
||||
buddy.setRelation(event.relationShip);
|
||||
this.client.sendResponse(new UpdateFriendComposer(this.client.getHabbo(), buddy, 0));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+4
-1
@@ -3,6 +3,8 @@ package com.eu.habbo.messages.incoming.friends;
|
||||
import com.eu.habbo.messages.incoming.MessageHandler;
|
||||
|
||||
public class DeclineFriendRequestEvent extends MessageHandler {
|
||||
private static final int MAX_BATCH_SIZE = 100;
|
||||
|
||||
@Override
|
||||
public void handle() throws Exception {
|
||||
boolean all = this.packet.readBoolean();
|
||||
@@ -11,10 +13,11 @@ public class DeclineFriendRequestEvent extends MessageHandler {
|
||||
this.client.getHabbo().getMessenger().deleteAllFriendRequests(this.client.getHabbo().getHabboInfo().getId());
|
||||
} else {
|
||||
int count = this.packet.readInt();
|
||||
if (count <= 0 || count > MAX_BATCH_SIZE) return;
|
||||
|
||||
for (int i = 0; i < count; i++) {
|
||||
this.client.getHabbo().getMessenger().deleteFriendRequests(this.packet.readInt(), this.client.getHabbo().getHabboInfo().getId());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
package com.eu.habbo.messages.incoming.friends;
|
||||
|
||||
final class FriendInputGuard {
|
||||
static final int MAX_USERNAME_LENGTH = 15;
|
||||
static final int MAX_MESSAGE_LENGTH = 255;
|
||||
static final int MAX_RELATION_ID = 3;
|
||||
|
||||
private FriendInputGuard() {
|
||||
}
|
||||
|
||||
static String normalizeUsername(String username) {
|
||||
return username == null ? "" : username.trim();
|
||||
}
|
||||
|
||||
static boolean isValidUsername(String username) {
|
||||
return username != null && !username.isBlank() && username.length() <= MAX_USERNAME_LENGTH;
|
||||
}
|
||||
|
||||
static String normalizeMessage(String message) {
|
||||
if (message == null) {
|
||||
return "";
|
||||
}
|
||||
|
||||
String normalized = message.trim();
|
||||
return normalized.length() > MAX_MESSAGE_LENGTH ? normalized.substring(0, MAX_MESSAGE_LENGTH) : normalized;
|
||||
}
|
||||
|
||||
static boolean isValidRelation(int relationId) {
|
||||
return relationId >= 0 && relationId <= MAX_RELATION_ID;
|
||||
}
|
||||
}
|
||||
+5
-3
@@ -9,7 +9,11 @@ public class FriendPrivateMessageEvent extends MessageHandler {
|
||||
@Override
|
||||
public void handle() throws Exception {
|
||||
int userId = this.packet.readInt();
|
||||
String message = this.packet.readString();
|
||||
String message = FriendInputGuard.normalizeMessage(this.packet.readString());
|
||||
|
||||
if (message.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!this.client.getHabbo().getHabboStats().allowTalk()) {
|
||||
return;
|
||||
@@ -25,8 +29,6 @@ public class FriendPrivateMessageEvent extends MessageHandler {
|
||||
if (buddy == null)
|
||||
return;
|
||||
|
||||
if (message.length() > 255) message = message.substring(0, 255);
|
||||
|
||||
UserFriendChatEvent event = new UserFriendChatEvent(this.client.getHabbo(), buddy, message);
|
||||
if (Emulator.getPluginManager().fireEvent(event).isCancelled())
|
||||
return;
|
||||
|
||||
+8
-2
@@ -26,9 +26,9 @@ public class FriendRequestEvent extends MessageHandler {
|
||||
|
||||
@Override
|
||||
public void handle() throws Exception {
|
||||
String username = this.packet.readString();
|
||||
String username = FriendInputGuard.normalizeUsername(this.packet.readString());
|
||||
|
||||
if (this.client == null || username == null || username.isEmpty())
|
||||
if (this.client == null || !FriendInputGuard.isValidUsername(username))
|
||||
return;
|
||||
|
||||
// TargetHabbo can be null if the Habbo is not online or when the Habbo doesn't exist
|
||||
@@ -62,6 +62,12 @@ public class FriendRequestEvent extends MessageHandler {
|
||||
if (targetId == this.client.getHabbo().getHabboInfo().getId())
|
||||
return;
|
||||
|
||||
if (this.client.getHabbo().getMessenger().getFriends().containsKey(targetId))
|
||||
return;
|
||||
|
||||
if (Messenger.friendRequested(targetId, this.client.getHabbo().getHabboInfo().getId()) || Messenger.friendRequested(this.client.getHabbo().getHabboInfo().getId(), targetId))
|
||||
return;
|
||||
|
||||
// Target Habbo exists
|
||||
// Check if Habbo is accepting friend requests
|
||||
if (targetBlocksFriendRequests) {
|
||||
|
||||
+6
-1
@@ -23,9 +23,14 @@ public class InviteFriendsEvent extends MessageHandler {
|
||||
userIds[i] = this.packet.readInt();
|
||||
}
|
||||
|
||||
String message = this.packet.readString();
|
||||
String message = FriendInputGuard.normalizeMessage(this.packet.readString());
|
||||
|
||||
if (message.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
message = Emulator.getGameEnvironment().getWordFilter().filter(message, this.client.getHabbo());
|
||||
message = FriendInputGuard.normalizeMessage(message);
|
||||
|
||||
for (int i : userIds) {
|
||||
if (i == 0)
|
||||
|
||||
@@ -8,6 +8,7 @@ import com.eu.habbo.messages.outgoing.friends.RemoveFriendComposer;
|
||||
import gnu.trove.list.array.TIntArrayList;
|
||||
|
||||
public class RemoveFriendEvent extends MessageHandler {
|
||||
private static final int MAX_BATCH_SIZE = 100;
|
||||
|
||||
private final TIntArrayList removedFriends;
|
||||
|
||||
@@ -18,8 +19,12 @@ public class RemoveFriendEvent extends MessageHandler {
|
||||
@Override
|
||||
public void handle() throws Exception {
|
||||
int count = this.packet.readInt();
|
||||
if (count <= 0 || count > MAX_BATCH_SIZE) return;
|
||||
|
||||
for (int i = 0; i < count; i++) {
|
||||
int habboId = this.packet.readInt();
|
||||
if (habboId <= 0) continue;
|
||||
|
||||
this.removedFriends.add(habboId);
|
||||
|
||||
Messenger.unfriend(this.client.getHabbo().getHabboInfo().getId(), habboId);
|
||||
|
||||
+10
-1
@@ -21,12 +21,21 @@ public class GuildChangeColorsEvent extends MessageHandler {
|
||||
|
||||
if (guild != null) {
|
||||
if (guild.getOwnerId() == this.client.getHabbo().getHabboInfo().getId() || this.client.getHabbo().hasPermission(Permission.ACC_GUILD_ADMIN)) {
|
||||
GuildChangedColorsEvent colorsEvent = new GuildChangedColorsEvent(guild, this.packet.readInt(), this.packet.readInt());
|
||||
int colorOne = this.packet.readInt();
|
||||
int colorTwo = this.packet.readInt();
|
||||
|
||||
if (!Emulator.getGameEnvironment().getGuildManager().symbolColor(colorOne) || !Emulator.getGameEnvironment().getGuildManager().backgroundColor(colorTwo))
|
||||
return;
|
||||
|
||||
GuildChangedColorsEvent colorsEvent = new GuildChangedColorsEvent(guild, colorOne, colorTwo);
|
||||
Emulator.getPluginManager().fireEvent(colorsEvent);
|
||||
|
||||
if (colorsEvent.isCancelled())
|
||||
return;
|
||||
|
||||
if (!Emulator.getGameEnvironment().getGuildManager().symbolColor(colorsEvent.colorOne) || !Emulator.getGameEnvironment().getGuildManager().backgroundColor(colorsEvent.colorTwo))
|
||||
return;
|
||||
|
||||
if (guild.getColorOne() != colorsEvent.colorOne || guild.getColorTwo() != colorsEvent.colorTwo) {
|
||||
guild.setColorOne(colorsEvent.colorOne);
|
||||
guild.setColorTwo(colorsEvent.colorTwo);
|
||||
|
||||
+5
-1
@@ -23,6 +23,10 @@ public class GuildChangeNameDescEvent extends MessageHandler {
|
||||
if (guild.getOwnerId() == this.client.getHabbo().getHabboInfo().getId() || this.client.getHabbo().hasPermission(Permission.ACC_GUILD_ADMIN)) {
|
||||
String newName = Emulator.getGameEnvironment().getWordFilter().filter(this.packet.readString(), this.client.getHabbo());
|
||||
String newDesc = Emulator.getGameEnvironment().getWordFilter().filter(this.packet.readString(), this.client.getHabbo());
|
||||
|
||||
if (!GuildInputLimits.isValidGuildName(newName) || !GuildInputLimits.isValidGuildDescription(newDesc))
|
||||
return;
|
||||
|
||||
GuildChangedNameEvent nameEvent = new GuildChangedNameEvent(guild, newName, newDesc);
|
||||
Emulator.getPluginManager().fireEvent(nameEvent);
|
||||
|
||||
@@ -32,7 +36,7 @@ public class GuildChangeNameDescEvent extends MessageHandler {
|
||||
if (guild.getName().equals(nameEvent.name) && guild.getDescription().equals(nameEvent.description))
|
||||
return;
|
||||
|
||||
if(nameEvent.name.length() > 29 || nameEvent.description.length() > 254)
|
||||
if (!GuildInputLimits.isValidGuildName(nameEvent.name) || !GuildInputLimits.isValidGuildDescription(nameEvent.description))
|
||||
return;
|
||||
|
||||
guild.setName(nameEvent.name);
|
||||
|
||||
+9
-1
@@ -40,12 +40,20 @@ public class GuildChangeSettingsEvent extends MessageHandler {
|
||||
|
||||
if (guild != null) {
|
||||
if (guild.getOwnerId() == this.client.getHabbo().getHabboInfo().getId() || this.client.getHabbo().hasPermission(Permission.ACC_GUILD_ADMIN)) {
|
||||
GuildChangedSettingsEvent settingsEvent = new GuildChangedSettingsEvent(guild, this.packet.readInt(), this.packet.readInt() == 0);
|
||||
int state = this.packet.readInt();
|
||||
|
||||
if (state < 0 || state >= GuildState.values().length)
|
||||
return;
|
||||
|
||||
GuildChangedSettingsEvent settingsEvent = new GuildChangedSettingsEvent(guild, state, this.packet.readInt() == 0);
|
||||
Emulator.getPluginManager().fireEvent(settingsEvent);
|
||||
|
||||
if (settingsEvent.isCancelled())
|
||||
return;
|
||||
|
||||
if (settingsEvent.state < 0 || settingsEvent.state >= GuildState.values().length)
|
||||
return;
|
||||
|
||||
guild.setState(GuildState.valueOf(settingsEvent.state));
|
||||
guild.setRights(settingsEvent.rights);
|
||||
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
package com.eu.habbo.messages.incoming.guilds;
|
||||
|
||||
final class GuildInputLimits {
|
||||
static final int MAX_GUILD_NAME_LENGTH = 29;
|
||||
static final int MAX_GUILD_DESCRIPTION_LENGTH = 254;
|
||||
|
||||
private GuildInputLimits() {
|
||||
}
|
||||
|
||||
static boolean isValidGuildName(String name) {
|
||||
return name != null && !name.isBlank() && name.length() <= MAX_GUILD_NAME_LENGTH;
|
||||
}
|
||||
|
||||
static boolean isValidGuildDescription(String description) {
|
||||
return description != null && description.length() <= MAX_GUILD_DESCRIPTION_LENGTH;
|
||||
}
|
||||
}
|
||||
+7
-2
@@ -31,11 +31,11 @@ public class RequestGuildBuyEvent extends MessageHandler {
|
||||
final String name = Emulator.getGameEnvironment().getWordFilter().filter(this.packet.readString(), this.client.getHabbo());
|
||||
final String description = Emulator.getGameEnvironment().getWordFilter().filter(this.packet.readString(), this.client.getHabbo());
|
||||
|
||||
if (name.length() == 0 || name.length() > 29) {
|
||||
if (!GuildInputLimits.isValidGuildName(name)) {
|
||||
this.client.sendResponse(new GuildEditFailComposer(GuildEditFailComposer.INVALID_GUILD_NAME));
|
||||
return;
|
||||
}
|
||||
if (description.length() > 254) {
|
||||
if (!GuildInputLimits.isValidGuildDescription(description)) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -68,6 +68,11 @@ public class RequestGuildBuyEvent extends MessageHandler {
|
||||
int colorOne = this.packet.readInt();
|
||||
int colorTwo = this.packet.readInt();
|
||||
|
||||
if (!Emulator.getGameEnvironment().getGuildManager().symbolColor(colorOne) || !Emulator.getGameEnvironment().getGuildManager().backgroundColor(colorTwo)) {
|
||||
this.client.sendResponse(new GuildEditFailComposer(GuildEditFailComposer.INVALID_GUILD_NAME));
|
||||
return;
|
||||
}
|
||||
|
||||
int count = this.packet.readInt();
|
||||
|
||||
String badge = GuildBadgeBuilder.readBadge(this.packet, count);
|
||||
|
||||
+7
@@ -9,6 +9,10 @@ import com.eu.habbo.messages.incoming.MessageHandler;
|
||||
import com.eu.habbo.messages.outgoing.guilds.GuildMembersComposer;
|
||||
|
||||
public class RequestGuildMembersEvent extends MessageHandler {
|
||||
private static final int MAX_PAGE_ID = 1000;
|
||||
private static final int MAX_QUERY_LENGTH = 32;
|
||||
private static final int MAX_LEVEL_ID = 2;
|
||||
|
||||
@Override
|
||||
public int getRatelimit() {
|
||||
return 500;
|
||||
@@ -20,6 +24,9 @@ public class RequestGuildMembersEvent extends MessageHandler {
|
||||
int pageId = this.packet.readInt();
|
||||
String query = this.packet.readString();
|
||||
int levelId = this.packet.readInt();
|
||||
if (pageId < 0 || pageId > MAX_PAGE_ID || levelId < 0 || levelId > MAX_LEVEL_ID || query == null || query.length() > MAX_QUERY_LENGTH) {
|
||||
return;
|
||||
}
|
||||
|
||||
Guild g = Emulator.getGameEnvironment().getGuildManager().getGuild(groupId);
|
||||
|
||||
|
||||
+6
@@ -8,6 +8,7 @@ import com.eu.habbo.messages.incoming.MessageHandler;
|
||||
import com.eu.habbo.messages.outgoing.generic.alerts.BubbleAlertComposer;
|
||||
import com.eu.habbo.messages.outgoing.generic.alerts.BubbleAlertKeys;
|
||||
import com.eu.habbo.messages.outgoing.guilds.forums.GuildForumDataComposer;
|
||||
import com.eu.habbo.messages.outgoing.handshake.ConnectionErrorComposer;
|
||||
|
||||
public class GuildForumDataEvent extends MessageHandler {
|
||||
@Override
|
||||
@@ -19,6 +20,11 @@ public class GuildForumDataEvent extends MessageHandler {
|
||||
public void handle() throws Exception {
|
||||
int guildId = packet.readInt();
|
||||
|
||||
if (!GuildForumInputGuard.isPositiveId(guildId)) {
|
||||
this.client.sendResponse(new ConnectionErrorComposer(400));
|
||||
return;
|
||||
}
|
||||
|
||||
Guild guild = Emulator.getGameEnvironment().getGuildManager().getGuild(guildId);
|
||||
|
||||
if (guild == null) return;
|
||||
|
||||
+5
@@ -2,6 +2,7 @@ package com.eu.habbo.messages.incoming.guilds.forums;
|
||||
|
||||
final class GuildForumInputGuard {
|
||||
static final int MAX_PAGE_LIMIT = 50;
|
||||
static final int MAX_THREAD_INDEX = 1000;
|
||||
static final int MAX_MARK_READ_BATCH = 50;
|
||||
|
||||
private GuildForumInputGuard() {
|
||||
@@ -19,6 +20,10 @@ final class GuildForumInputGuard {
|
||||
return index >= 0 && limit > 0 && limit <= MAX_PAGE_LIMIT;
|
||||
}
|
||||
|
||||
static boolean isValidThreadIndex(int index) {
|
||||
return index >= 0 && index <= MAX_THREAD_INDEX;
|
||||
}
|
||||
|
||||
static boolean isValidMarkReadBatch(int count) {
|
||||
return count > 0 && count <= MAX_MARK_READ_BATCH;
|
||||
}
|
||||
|
||||
+14
@@ -1,6 +1,9 @@
|
||||
package com.eu.habbo.messages.incoming.guilds.forums;
|
||||
|
||||
import com.eu.habbo.Emulator;
|
||||
import com.eu.habbo.habbohotel.guilds.Guild;
|
||||
import com.eu.habbo.habbohotel.guilds.GuildMember;
|
||||
import com.eu.habbo.habbohotel.permissions.Permission;
|
||||
import com.eu.habbo.messages.incoming.MessageHandler;
|
||||
import com.eu.habbo.messages.outgoing.guilds.forums.GuildForumDataComposer;
|
||||
import org.slf4j.Logger;
|
||||
@@ -37,6 +40,17 @@ public class GuildForumMarkAsReadEvent extends MessageHandler {
|
||||
continue;
|
||||
}
|
||||
|
||||
Guild guild = Emulator.getGameEnvironment().getGuildManager().getGuild(guildId);
|
||||
if (guild == null || !guild.hasForum()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
GuildMember member = Emulator.getGameEnvironment().getGuildManager().getGuildMember(guildId, userId);
|
||||
boolean staff = this.client.getHabbo().hasPermission(Permission.ACC_MODTOOL_TICKET_Q);
|
||||
if (!guild.canHabboReadForum(userId, member, staff)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
try (Connection connection = Emulator.getDatabase().getDataSource().getConnection(); PreparedStatement statement = connection.prepareStatement(
|
||||
"INSERT INTO `guild_forum_views` (`user_id`, `guild_id`, `timestamp`) VALUES (?, ?, ?) " +
|
||||
"ON DUPLICATE KEY UPDATE `timestamp` = ?"
|
||||
|
||||
+1
-1
@@ -22,7 +22,7 @@ public class GuildForumThreadsEvent extends MessageHandler {
|
||||
int guildId = packet.readInt();
|
||||
int index = packet.readInt();
|
||||
|
||||
if (!GuildForumInputGuard.isPositiveId(guildId) || index < 0) {
|
||||
if (!GuildForumInputGuard.isPositiveId(guildId) || !GuildForumInputGuard.isValidThreadIndex(index)) {
|
||||
this.client.sendResponse(new ConnectionErrorComposer(400));
|
||||
return;
|
||||
}
|
||||
|
||||
+6
-5
@@ -50,6 +50,7 @@ import java.util.Date;
|
||||
@NoAuthMessage
|
||||
public class SecureLoginEvent extends MessageHandler {
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(SecureLoginEvent.class);
|
||||
private static final int MAX_SSO_TICKET_LENGTH = 128;
|
||||
|
||||
@Override
|
||||
public int getRatelimit() {
|
||||
@@ -72,17 +73,17 @@ public class SecureLoginEvent extends MessageHandler {
|
||||
return;
|
||||
}
|
||||
|
||||
String sso = this.packet.readString().replace(" ", "");
|
||||
String sso = SecureLoginInputGuard.normalizeSsoTicket(this.packet.readString());
|
||||
|
||||
if (Emulator.getPluginManager().fireEvent(new SSOAuthenticationEvent(sso)).isCancelled()) {
|
||||
if (!SecureLoginInputGuard.isValidSsoTicket(sso)) {
|
||||
Emulator.getGameServer().getGameClientManager().disposeClient(this.client);
|
||||
LOGGER.info("SSO Authentication is cancelled by a plugin. Closed connection...");
|
||||
LOGGER.debug("Client is trying to connect with an invalid SSO ticket! Closed connection...");
|
||||
return;
|
||||
}
|
||||
|
||||
if (sso.isEmpty()) {
|
||||
if (sso.isEmpty() || sso.length() > MAX_SSO_TICKET_LENGTH) {
|
||||
Emulator.getGameServer().getGameClientManager().disposeClient(this.client);
|
||||
LOGGER.debug("Client is trying to connect without SSO ticket! Closed connection...");
|
||||
LOGGER.debug("Client is trying to connect with missing or invalid SSO ticket! Closed connection...");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
package com.eu.habbo.messages.incoming.handshake;
|
||||
|
||||
final class SecureLoginInputGuard {
|
||||
static final int MAX_SSO_TICKET_LENGTH = 512;
|
||||
|
||||
private SecureLoginInputGuard() {
|
||||
}
|
||||
|
||||
static String normalizeSsoTicket(String ticket) {
|
||||
if (ticket == null) {
|
||||
return "";
|
||||
}
|
||||
|
||||
return ticket.replace(" ", "");
|
||||
}
|
||||
|
||||
static boolean isValidSsoTicket(String ticket) {
|
||||
return ticket != null && !ticket.isEmpty() && ticket.length() <= MAX_SSO_TICKET_LENGTH;
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -14,7 +14,7 @@ public class ModToolAlertEvent extends MessageHandler {
|
||||
int userId = this.packet.readInt();
|
||||
String message = ModToolInputGuard.normalize(this.packet.readString());
|
||||
|
||||
if (!ModToolInputGuard.isSafeMessage(message)) {
|
||||
if (!ModToolTicketGuard.isPositiveId(userId) || !ModToolInputGuard.isSafeMessage(message)) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
+7
-1
@@ -10,7 +10,13 @@ public class ModToolChangeRoomSettingsEvent extends MessageHandler {
|
||||
@Override
|
||||
public void handle() throws Exception {
|
||||
if (this.client.getHabbo().hasPermission(Permission.ACC_SUPPORTTOOL)) {
|
||||
Room room = Emulator.getGameEnvironment().getRoomManager().getRoom(this.packet.readInt());
|
||||
int roomId = this.packet.readInt();
|
||||
|
||||
if (!ModToolTicketGuard.isPositiveId(roomId)) {
|
||||
return;
|
||||
}
|
||||
|
||||
Room room = Emulator.getGameEnvironment().getRoomManager().getRoom(roomId);
|
||||
|
||||
if (room != null) {
|
||||
final boolean lockDoor = this.packet.readInt() == 1;
|
||||
|
||||
+4
@@ -19,6 +19,10 @@ public class ModToolIssueDefaultSanctionEvent extends MessageHandler {
|
||||
this.packet.readInt();
|
||||
int category = this.packet.readInt();
|
||||
|
||||
if (!ModToolTicketGuard.isPositiveId(issueId) || !ModToolTicketGuard.isPositiveId(category)) {
|
||||
return;
|
||||
}
|
||||
|
||||
ModToolIssue issue = Emulator.getGameEnvironment().getModToolManager().getTicket(issueId);
|
||||
|
||||
if (issue == null) {
|
||||
|
||||
@@ -21,7 +21,7 @@ public class ModToolKickEvent extends MessageHandler {
|
||||
int userId = this.packet.readInt();
|
||||
String message = ModToolInputGuard.normalize(this.packet.readString());
|
||||
|
||||
if (!ModToolInputGuard.isSafeMessage(message)) {
|
||||
if (!ModToolTicketGuard.isPositiveId(userId) || !ModToolInputGuard.isSafeMessage(message)) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user