You've already forked Arcturus-Morningstar-Extended
mirror of
https://github.com/duckietm/Arcturus-Morningstar-Extended.git
synced 2026-06-20 07:26:18 +00:00
Compare commits
13 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| fadec887cd | |||
| e614c1d64f | |||
| e7deea7d9d | |||
| 44ea3abd4e | |||
| 609cd20ab2 | |||
| 717a7f184f | |||
| 2862446686 | |||
| e97e680006 | |||
| 7e59dca192 | |||
| 1109d53720 | |||
| f12363a5b7 | |||
| 7d4ffec74e | |||
| 9f36d95dbc |
@@ -1,24 +1,74 @@
|
|||||||
CREATE TABLE IF NOT EXISTS `habbo_mentions` (
|
CREATE TABLE IF NOT EXISTS `habbo_mentions` (
|
||||||
`id` INT NOT NULL AUTO_INCREMENT,
|
`id` INT(11) NOT NULL AUTO_INCREMENT,
|
||||||
`target_user_id` INT NOT NULL,
|
`target_user_id` INT(11) NOT NULL,
|
||||||
`sender_user_id` INT NOT NULL,
|
`sender_user_id` INT(11) NOT NULL,
|
||||||
`sender_username` VARCHAR(64) NOT NULL DEFAULT '',
|
`sender_username` VARCHAR(64) NOT NULL DEFAULT '',
|
||||||
`room_id` INT NOT NULL,
|
`room_id` INT(11) NOT NULL DEFAULT 0,
|
||||||
`room_name` VARCHAR(255) NOT NULL DEFAULT '',
|
`room_name` VARCHAR(64) NOT NULL DEFAULT '',
|
||||||
`message` VARCHAR(255) NOT NULL DEFAULT '',
|
`message` VARCHAR(255) NOT NULL DEFAULT '',
|
||||||
`mention_type` TINYINT NOT NULL DEFAULT 0,
|
`mention_type` TINYINT(1) NOT NULL DEFAULT 0 COMMENT '0 = direct (@nick), 1 = broadcast (@all/@friends/@room)',
|
||||||
`timestamp` INT NOT NULL DEFAULT 0,
|
`timestamp` INT(11) NOT NULL DEFAULT 0,
|
||||||
`read` TINYINT NOT NULL DEFAULT 0,
|
`read` TINYINT(1) NOT NULL DEFAULT 0,
|
||||||
PRIMARY KEY (`id`),
|
PRIMARY KEY (`id`),
|
||||||
INDEX `idx_target_read` (`target_user_id`, `read`)
|
KEY `idx_target_id` (`target_user_id`, `id`),
|
||||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
KEY `idx_target_unread` (`target_user_id`, `read`),
|
||||||
|
KEY `idx_target_timestamp` (`target_user_id`, `timestamp`)
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||||
|
|
||||||
INSERT IGNORE INTO `emulator_settings` (`key`, `value`) VALUES
|
|
||||||
('mentions.enabled', '1'),
|
|
||||||
('mentions.room.aliases', 'amici,friends,all,everyone,tutti,room,stanza'),
|
|
||||||
('mentions.max.targets', '50'),
|
INSERT INTO `permission_definitions`
|
||||||
('mentions.cooldown.ms', '3000'),
|
(`permission_key`, `max_value`, `comment`,
|
||||||
('mentions.store.limit', '50');
|
`rank_1`, `rank_2`, `rank_3`, `rank_4`, `rank_5`, `rank_6`, `rank_7`, `rank_8`)
|
||||||
|
VALUES
|
||||||
|
('acc_mention_everyone', 1,
|
||||||
|
'Allow sending @all / @everyone / @tutti broadcast mentions (hotel-wide).',
|
||||||
|
0, 0, 0, 0, 1, 1, 1, 1),
|
||||||
|
('acc_mention_friends', 1,
|
||||||
|
'Allow sending @friends / @amici broadcast mentions (sender''s online buddies).',
|
||||||
|
0, 0, 0, 0, 1, 1, 1, 1),
|
||||||
|
('cmd_disablementions', 1,
|
||||||
|
'Allow toggling :disablementions to stop receiving any @mention notifications.',
|
||||||
|
1, 1, 1, 1, 1, 1, 1, 1),
|
||||||
|
('cmd_disablemassmentions', 1,
|
||||||
|
'Allow toggling :disablemassmentions to stop receiving broadcast mentions (direct @nick still works).',
|
||||||
|
1, 1, 1, 1, 1, 1, 1, 1)
|
||||||
|
ON DUPLICATE KEY UPDATE
|
||||||
|
`comment` = VALUES(`comment`);
|
||||||
|
|
||||||
|
|
||||||
|
-- ----------------------------------------------------------------------------
|
||||||
|
-- 3. Emulator settings: cooldowns, caps and alias lists
|
||||||
|
--
|
||||||
|
-- Only inserted when missing - existing tuned values are preserved.
|
||||||
|
-- ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
INSERT IGNORE INTO `emulator_settings` (`key`, `value`, `comment`) VALUES
|
||||||
|
('mentions.enabled', '1',
|
||||||
|
'Master switch. 1 = process @mentions, 0 = disable the feature entirely.'),
|
||||||
|
('mentions.max.targets', '50',
|
||||||
|
'Hard cap on how many users a single broadcast (@all / @friends / @room) can fan out to.'),
|
||||||
|
('mentions.cooldown.ms', '3000',
|
||||||
|
'Per-sender cooldown between any two mentions, in milliseconds.'),
|
||||||
|
('mentions.room.cooldown.ms', '15000',
|
||||||
|
'Extra per-sender cooldown for broadcast mentions (@all / @friends / @room) on top of mentions.cooldown.ms.'),
|
||||||
|
('mentions.store.limit', '50',
|
||||||
|
'Number of mentions returned in the initial RequestMentionsList response.'),
|
||||||
|
('mentions.request.cooldown.ms', '2000',
|
||||||
|
'Per-user cooldown between RequestMentionsList packets.'),
|
||||||
|
('mentions.markread.cooldown.ms', '500',
|
||||||
|
'Per-user cooldown between mark-single-as-read packets.'),
|
||||||
|
('mentions.markall.cooldown.ms', '5000',
|
||||||
|
'Per-user cooldown between mark-all-as-read packets (bulk DB update).'),
|
||||||
|
('mentions.delete.cooldown.ms', '500',
|
||||||
|
'Per-user cooldown between delete-mention packets.'),
|
||||||
|
('mentions.everyone.aliases', 'all,everyone,tutti',
|
||||||
|
'Comma-separated aliases that trigger an @everyone broadcast (requires acc_mention_everyone).'),
|
||||||
|
('mentions.friends.aliases', 'friends,amici',
|
||||||
|
'Comma-separated aliases that trigger an @friends broadcast (requires acc_mention_friends).'),
|
||||||
|
('mentions.room.aliases', 'room,stanza',
|
||||||
|
'Comma-separated aliases that trigger an @room broadcast (no permission required, room scope only).');
|
||||||
|
|
||||||
|
|
||||||
ALTER TABLE `wordfilter`
|
ALTER TABLE `wordfilter`
|
||||||
|
|||||||
+1
-1
@@ -6,7 +6,7 @@
|
|||||||
|
|
||||||
<groupId>com.eu.habbo</groupId>
|
<groupId>com.eu.habbo</groupId>
|
||||||
<artifactId>Habbo</artifactId>
|
<artifactId>Habbo</artifactId>
|
||||||
<version>4.2.31</version>
|
<version>4.2.35</version>
|
||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
|
|||||||
@@ -191,6 +191,8 @@ public class CommandHandler {
|
|||||||
addCommand(new CreditsCommand());
|
addCommand(new CreditsCommand());
|
||||||
addCommand(new DanceCommand());
|
addCommand(new DanceCommand());
|
||||||
addCommand(new DiagonalCommand());
|
addCommand(new DiagonalCommand());
|
||||||
|
addCommand(new DisableMassMentionsCommand());
|
||||||
|
addCommand(new DisableMentionsCommand());
|
||||||
addCommand(new DisconnectCommand());
|
addCommand(new DisconnectCommand());
|
||||||
addCommand(new EjectAllCommand());
|
addCommand(new EjectAllCommand());
|
||||||
addCommand(new EmptyInventoryCommand());
|
addCommand(new EmptyInventoryCommand());
|
||||||
|
|||||||
@@ -17,7 +17,22 @@ public class CommandsCommand extends Command {
|
|||||||
message.append("(").append(commands.size()).append("):\r\n");
|
message.append("(").append(commands.size()).append("):\r\n");
|
||||||
|
|
||||||
for (Command c : commands) {
|
for (Command c : commands) {
|
||||||
message.append(Emulator.getTexts().getValue("commands.description." + c.permission, "commands.description." + c.permission)).append("\r");
|
String textKey = "commands.description." + c.permission;
|
||||||
|
String commandText = Emulator.getTexts().getValue(textKey, "");
|
||||||
|
String commandLine = ":" + c.keys[0];
|
||||||
|
String description = "";
|
||||||
|
|
||||||
|
if (commandText.startsWith(":")) {
|
||||||
|
commandLine = commandText;
|
||||||
|
} else if (!commandText.isEmpty() && !commandText.equals(textKey)) {
|
||||||
|
description = commandText;
|
||||||
|
}
|
||||||
|
|
||||||
|
message.append(commandLine).append("\r");
|
||||||
|
|
||||||
|
if (!description.isEmpty()) {
|
||||||
|
message.append(description).append("\r");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
gameClient.getHabbo().alert(new String[]{message.toString()});
|
gameClient.getHabbo().alert(new String[]{message.toString()});
|
||||||
|
|||||||
+25
@@ -0,0 +1,25 @@
|
|||||||
|
package com.eu.habbo.habbohotel.commands;
|
||||||
|
|
||||||
|
import com.eu.habbo.habbohotel.gameclients.GameClient;
|
||||||
|
import com.eu.habbo.habbohotel.users.Habbo;
|
||||||
|
|
||||||
|
public class DisableMassMentionsCommand extends Command {
|
||||||
|
public DisableMassMentionsCommand() {
|
||||||
|
super("cmd_disablemassmentions", new String[]{"disablemassmentions", "togglemassmentions"});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean handle(GameClient gameClient, String[] params) throws Exception {
|
||||||
|
if (gameClient == null) return true;
|
||||||
|
Habbo habbo = gameClient.getHabbo();
|
||||||
|
if (habbo == null || habbo.getHabboStats() == null) return true;
|
||||||
|
|
||||||
|
boolean newState = !habbo.getHabboStats().massMentionsEnabled();
|
||||||
|
habbo.getHabboStats().setMassMentionsEnabled(newState);
|
||||||
|
|
||||||
|
habbo.whisper(newState
|
||||||
|
? "Broadcast mentions (@all / @friends / @room) are now ENABLED for you."
|
||||||
|
: "Broadcast mentions (@all / @friends / @room) are now DISABLED for you. Direct @nick mentions still work.");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
package com.eu.habbo.habbohotel.commands;
|
||||||
|
|
||||||
|
import com.eu.habbo.habbohotel.gameclients.GameClient;
|
||||||
|
import com.eu.habbo.habbohotel.users.Habbo;
|
||||||
|
|
||||||
|
public class DisableMentionsCommand extends Command {
|
||||||
|
public DisableMentionsCommand() {
|
||||||
|
super("cmd_disablementions", new String[]{"disablementions", "togglementions"});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean handle(GameClient gameClient, String[] params) throws Exception {
|
||||||
|
if (gameClient == null) return true;
|
||||||
|
Habbo habbo = gameClient.getHabbo();
|
||||||
|
if (habbo == null || habbo.getHabboStats() == null) return true;
|
||||||
|
|
||||||
|
boolean newState = !habbo.getHabboStats().mentionsEnabled();
|
||||||
|
habbo.getHabboStats().setMentionsEnabled(newState);
|
||||||
|
|
||||||
|
habbo.whisper(newState
|
||||||
|
? "@mention notifications are now ENABLED for you."
|
||||||
|
: "@mention notifications are now DISABLED for you. You will not receive direct or broadcast mentions.");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,9 +1,11 @@
|
|||||||
package com.eu.habbo.habbohotel.mentions;
|
package com.eu.habbo.habbohotel.mentions;
|
||||||
|
|
||||||
import com.eu.habbo.Emulator;
|
import com.eu.habbo.Emulator;
|
||||||
|
import com.eu.habbo.habbohotel.messenger.MessengerBuddy;
|
||||||
import com.eu.habbo.habbohotel.rooms.Room;
|
import com.eu.habbo.habbohotel.rooms.Room;
|
||||||
import com.eu.habbo.habbohotel.rooms.RoomChatType;
|
import com.eu.habbo.habbohotel.rooms.RoomChatType;
|
||||||
import com.eu.habbo.habbohotel.users.Habbo;
|
import com.eu.habbo.habbohotel.users.Habbo;
|
||||||
|
import com.eu.habbo.habbohotel.users.HabboManager;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
@@ -14,8 +16,10 @@ import java.sql.SQLException;
|
|||||||
import java.sql.Statement;
|
import java.sql.Statement;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
|
import java.util.Iterator;
|
||||||
import java.util.LinkedHashSet;
|
import java.util.LinkedHashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
|
||||||
@@ -23,15 +27,36 @@ public class MentionManager {
|
|||||||
|
|
||||||
private static final Logger LOGGER = LoggerFactory.getLogger(MentionManager.class);
|
private static final Logger LOGGER = LoggerFactory.getLogger(MentionManager.class);
|
||||||
|
|
||||||
|
private static final int ROOM_NAME_MAX_LENGTH = 64;
|
||||||
|
private static final int MESSAGE_MAX_LENGTH = 255;
|
||||||
private final ConcurrentHashMap<Integer, Long> cooldowns = new ConcurrentHashMap<>();
|
private final ConcurrentHashMap<Integer, Long> cooldowns = new ConcurrentHashMap<>();
|
||||||
|
private final ConcurrentHashMap<Integer, Long> roomBroadcastCooldowns = new ConcurrentHashMap<>();
|
||||||
|
private final ConcurrentHashMap<Integer, Long> requestListCooldowns = new ConcurrentHashMap<>();
|
||||||
|
private final ConcurrentHashMap<Integer, Long> markReadCooldowns = new ConcurrentHashMap<>();
|
||||||
|
private final ConcurrentHashMap<Integer, Long> markAllCooldowns = new ConcurrentHashMap<>();
|
||||||
|
private final ConcurrentHashMap<Integer, Long> deleteCooldowns = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
|
private volatile long lastPrune = System.currentTimeMillis();
|
||||||
|
private static final long PRUNE_INTERVAL_MS = 5 * 60_000L;
|
||||||
|
|
||||||
public boolean isEnabled() {
|
public boolean isEnabled() {
|
||||||
return Emulator.getConfig().getInt("mentions.enabled", 1) == 1;
|
return Emulator.getConfig().getInt("mentions.enabled", 1) == 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Set<String> roomAliases() {
|
/** Broadcast category resolved from a mention alias. */
|
||||||
|
public enum BroadcastScope {
|
||||||
|
NONE,
|
||||||
|
ROOM,
|
||||||
|
FRIENDS,
|
||||||
|
EVERYONE
|
||||||
|
}
|
||||||
|
|
||||||
|
public static final String PERMISSION_EVERYONE = "acc_mention_everyone";
|
||||||
|
public static final String PERMISSION_FRIENDS = "acc_mention_friends";
|
||||||
|
|
||||||
|
private Set<String> parseAliases(String configKey, String defaultValue) {
|
||||||
Set<String> aliases = new HashSet<>();
|
Set<String> aliases = new HashSet<>();
|
||||||
String raw = Emulator.getConfig().getValue("mentions.room.aliases", "amici,friends,all,everyone,tutti,room,stanza");
|
String raw = Emulator.getConfig().getValue(configKey, defaultValue);
|
||||||
for (String alias : raw.split(",")) {
|
for (String alias : raw.split(",")) {
|
||||||
String trimmed = alias.trim().toLowerCase();
|
String trimmed = alias.trim().toLowerCase();
|
||||||
if (!trimmed.isEmpty()) {
|
if (!trimmed.isEmpty()) {
|
||||||
@@ -41,6 +66,29 @@ public class MentionManager {
|
|||||||
return aliases;
|
return aliases;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Set<String> roomAliases() {
|
||||||
|
return parseAliases("mentions.room.aliases", "room,stanza");
|
||||||
|
}
|
||||||
|
|
||||||
|
private Set<String> friendsAliases() {
|
||||||
|
return parseAliases("mentions.friends.aliases", "friends,amici");
|
||||||
|
}
|
||||||
|
|
||||||
|
private Set<String> everyoneAliases() {
|
||||||
|
return parseAliases("mentions.everyone.aliases", "all,everyone,tutti");
|
||||||
|
}
|
||||||
|
|
||||||
|
private BroadcastScope classifyAlias(String alias,
|
||||||
|
Set<String> everyone,
|
||||||
|
Set<String> friends,
|
||||||
|
Set<String> room) {
|
||||||
|
if (alias.isEmpty()) return BroadcastScope.NONE;
|
||||||
|
if (everyone.contains(alias)) return BroadcastScope.EVERYONE;
|
||||||
|
if (friends.contains(alias)) return BroadcastScope.FRIENDS;
|
||||||
|
if (room.contains(alias)) return BroadcastScope.ROOM;
|
||||||
|
return BroadcastScope.NONE;
|
||||||
|
}
|
||||||
|
|
||||||
public void process(Habbo sender, Room room, String message, RoomChatType type) {
|
public void process(Habbo sender, Room room, String message, RoomChatType type) {
|
||||||
try {
|
try {
|
||||||
if (!this.isEnabled()) {
|
if (!this.isEnabled()) {
|
||||||
@@ -63,8 +111,11 @@ public class MentionManager {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Set<String> aliases = this.roomAliases();
|
Set<String> roomAliases = this.roomAliases();
|
||||||
boolean roomBroadcast = false;
|
Set<String> friendsAliases = this.friendsAliases();
|
||||||
|
Set<String> everyoneAliases = this.everyoneAliases();
|
||||||
|
|
||||||
|
BroadcastScope broadcastScope = BroadcastScope.NONE;
|
||||||
LinkedHashSet<String> directTokens = new LinkedHashSet<>();
|
LinkedHashSet<String> directTokens = new LinkedHashSet<>();
|
||||||
|
|
||||||
for (String token : message.split("\\s+")) {
|
for (String token : message.split("\\s+")) {
|
||||||
@@ -75,40 +126,64 @@ public class MentionManager {
|
|||||||
String raw = token.substring(1);
|
String raw = token.substring(1);
|
||||||
String aliasCandidate = trimTrailingPunctuation(raw).toLowerCase();
|
String aliasCandidate = trimTrailingPunctuation(raw).toLowerCase();
|
||||||
|
|
||||||
if (!aliasCandidate.isEmpty() && aliases.contains(aliasCandidate)) {
|
BroadcastScope scope = this.classifyAlias(aliasCandidate, everyoneAliases, friendsAliases, roomAliases);
|
||||||
roomBroadcast = true;
|
|
||||||
|
if (scope != BroadcastScope.NONE) {
|
||||||
|
if (scope.ordinal() > broadcastScope.ordinal()) {
|
||||||
|
broadcastScope = scope;
|
||||||
|
}
|
||||||
} else if (!raw.isEmpty()) {
|
} else if (!raw.isEmpty()) {
|
||||||
directTokens.add(raw);
|
directTokens.add(raw);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!roomBroadcast && directTokens.isEmpty()) {
|
if (broadcastScope == BroadcastScope.EVERYONE && !sender.hasPermission(PERMISSION_EVERYONE)) {
|
||||||
|
broadcastScope = BroadcastScope.NONE;
|
||||||
|
} else if (broadcastScope == BroadcastScope.FRIENDS && !sender.hasPermission(PERMISSION_FRIENDS)) {
|
||||||
|
broadcastScope = BroadcastScope.NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (broadcastScope == BroadcastScope.NONE && directTokens.isEmpty()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (broadcastScope != BroadcastScope.NONE) {
|
||||||
|
long roomCooldownMs = Emulator.getConfig().getInt("mentions.room.cooldown.ms", 15000);
|
||||||
|
Long lastRoom = this.roomBroadcastCooldowns.get(senderId);
|
||||||
|
if (lastRoom != null && (now - lastRoom) < roomCooldownMs) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int maxTargets = Emulator.getConfig().getInt("mentions.max.targets", 50);
|
int maxTargets = Emulator.getConfig().getInt("mentions.max.targets", 50);
|
||||||
|
if (maxTargets <= 0) maxTargets = 1;
|
||||||
|
int maxDirectTokens = Math.min(directTokens.size(), maxTargets);
|
||||||
|
|
||||||
List<Habbo> targets = new ArrayList<>();
|
List<Habbo> targets = new ArrayList<>();
|
||||||
Set<Integer> seen = new HashSet<>();
|
Set<Integer> seen = new HashSet<>();
|
||||||
|
|
||||||
if (roomBroadcast) {
|
switch (broadcastScope) {
|
||||||
for (Habbo habbo : room.getHabbos()) {
|
case EVERYONE:
|
||||||
if (habbo == null || habbo.getHabboInfo().getId() == senderId) {
|
this.collectEveryoneTargets(senderId, targets, seen, maxTargets);
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (seen.add(habbo.getHabboInfo().getId())) {
|
|
||||||
targets.add(habbo);
|
|
||||||
}
|
|
||||||
if (targets.size() >= maxTargets) {
|
|
||||||
break;
|
break;
|
||||||
}
|
case FRIENDS:
|
||||||
}
|
this.collectFriendsTargets(sender, senderId, targets, seen, maxTargets);
|
||||||
} else {
|
break;
|
||||||
|
case ROOM:
|
||||||
|
this.collectRoomTargets(room, senderId, targets, seen, maxTargets, true);
|
||||||
|
break;
|
||||||
|
case NONE:
|
||||||
|
default:
|
||||||
|
int processed = 0;
|
||||||
for (String token : directTokens) {
|
for (String token : directTokens) {
|
||||||
|
if (processed++ >= maxDirectTokens) break;
|
||||||
Habbo habbo = this.resolveHabbo(room, token);
|
Habbo habbo = this.resolveHabbo(room, token);
|
||||||
if (habbo == null || habbo.getHabboInfo().getId() == senderId) {
|
if (habbo == null || habbo.getHabboInfo().getId() == senderId) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
if (!acceptsMention(habbo, false)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
if (seen.add(habbo.getHabboInfo().getId())) {
|
if (seen.add(habbo.getHabboInfo().getId())) {
|
||||||
targets.add(habbo);
|
targets.add(habbo);
|
||||||
}
|
}
|
||||||
@@ -116,6 +191,7 @@ public class MentionManager {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (targets.isEmpty()) {
|
if (targets.isEmpty()) {
|
||||||
@@ -123,15 +199,13 @@ public class MentionManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
this.cooldowns.put(senderId, now);
|
this.cooldowns.put(senderId, now);
|
||||||
|
if (broadcastScope != BroadcastScope.NONE) this.roomBroadcastCooldowns.put(senderId, now);
|
||||||
|
this.pruneCooldownsIfDue(now);
|
||||||
|
|
||||||
int mentionType = roomBroadcast ? HabboMention.TYPE_ROOM : HabboMention.TYPE_DIRECT;
|
int mentionType = (broadcastScope != BroadcastScope.NONE) ? HabboMention.TYPE_ROOM : HabboMention.TYPE_DIRECT;
|
||||||
int timestamp = Emulator.getIntUnixTimestamp();
|
int timestamp = Emulator.getIntUnixTimestamp();
|
||||||
String roomName = room.getName();
|
String roomName = truncate(room.getName(), ROOM_NAME_MAX_LENGTH);
|
||||||
|
String storedMessage = truncate(message, MESSAGE_MAX_LENGTH);
|
||||||
String storedMessage = message;
|
|
||||||
if (storedMessage.length() > 255) {
|
|
||||||
storedMessage = storedMessage.substring(0, 255);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (Habbo target : targets) {
|
for (Habbo target : targets) {
|
||||||
this.store(target, sender, room, storedMessage, mentionType, timestamp, roomName);
|
this.store(target, sender, room, storedMessage, mentionType, timestamp, roomName);
|
||||||
@@ -141,6 +215,46 @@ public class MentionManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void collectRoomTargets(Room room, int senderId, List<Habbo> targets, Set<Integer> seen, int maxTargets, boolean isBroadcast) {
|
||||||
|
for (Habbo habbo : room.getHabbos()) {
|
||||||
|
if (habbo == null || habbo.getHabboInfo().getId() == senderId) continue;
|
||||||
|
if (!acceptsMention(habbo, isBroadcast)) continue;
|
||||||
|
if (seen.add(habbo.getHabboInfo().getId())) targets.add(habbo);
|
||||||
|
if (targets.size() >= maxTargets) break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void collectFriendsTargets(Habbo sender, int senderId, List<Habbo> targets, Set<Integer> seen, int maxTargets) {
|
||||||
|
if (sender.getMessenger() == null) return;
|
||||||
|
HabboManager habboManager = Emulator.getGameEnvironment().getHabboManager();
|
||||||
|
for (MessengerBuddy buddy : sender.getMessenger().getFriends().values()) {
|
||||||
|
if (buddy == null) continue;
|
||||||
|
int buddyId = buddy.getId();
|
||||||
|
if (buddyId == senderId) continue;
|
||||||
|
Habbo online = habboManager.getHabbo(buddyId);
|
||||||
|
if (online == null) continue;
|
||||||
|
if (!acceptsMention(online, true)) continue;
|
||||||
|
if (seen.add(buddyId)) targets.add(online);
|
||||||
|
if (targets.size() >= maxTargets) break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void collectEveryoneTargets(int senderId, List<Habbo> targets, Set<Integer> seen, int maxTargets) {
|
||||||
|
for (Habbo habbo : Emulator.getGameEnvironment().getHabboManager().getOnlineHabbos().values()) {
|
||||||
|
if (habbo == null || habbo.getHabboInfo().getId() == senderId) continue;
|
||||||
|
if (!acceptsMention(habbo, true)) continue;
|
||||||
|
if (seen.add(habbo.getHabboInfo().getId())) targets.add(habbo);
|
||||||
|
if (targets.size() >= maxTargets) break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean acceptsMention(Habbo recipient, boolean isBroadcast) {
|
||||||
|
if (recipient == null || recipient.getHabboStats() == null) return true;
|
||||||
|
if (!recipient.getHabboStats().mentionsEnabled()) return false;
|
||||||
|
if (isBroadcast && !recipient.getHabboStats().massMentionsEnabled()) return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
private void store(Habbo target, Habbo sender, Room room, String message, int mentionType, int timestamp, String roomName) {
|
private void store(Habbo target, Habbo sender, Room room, String message, int mentionType, int timestamp, String roomName) {
|
||||||
try (Connection connection = Emulator.getDatabase().getDataSource().getConnection();
|
try (Connection connection = Emulator.getDatabase().getDataSource().getConnection();
|
||||||
PreparedStatement statement = connection.prepareStatement(
|
PreparedStatement statement = connection.prepareStatement(
|
||||||
@@ -163,6 +277,10 @@ public class MentionManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (generatedId <= 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
HabboMention mention = new HabboMention(target.getHabboInfo().getId(), generatedId, sender, room, roomName, message, mentionType, timestamp);
|
HabboMention mention = new HabboMention(target.getHabboInfo().getId(), generatedId, sender, room, roomName, message, mentionType, timestamp);
|
||||||
|
|
||||||
if (target.getClient() != null) {
|
if (target.getClient() != null) {
|
||||||
@@ -175,6 +293,8 @@ public class MentionManager {
|
|||||||
|
|
||||||
public List<HabboMention> getMentions(int userId, int limit) {
|
public List<HabboMention> getMentions(int userId, int limit) {
|
||||||
List<HabboMention> mentions = new ArrayList<>();
|
List<HabboMention> mentions = new ArrayList<>();
|
||||||
|
if (limit <= 0) limit = 50;
|
||||||
|
if (limit > 200) limit = 200;
|
||||||
try (Connection connection = Emulator.getDatabase().getDataSource().getConnection();
|
try (Connection connection = Emulator.getDatabase().getDataSource().getConnection();
|
||||||
PreparedStatement statement = connection.prepareStatement(
|
PreparedStatement statement = connection.prepareStatement(
|
||||||
"SELECT * FROM habbo_mentions WHERE target_user_id = ? ORDER BY id DESC LIMIT ?")) {
|
"SELECT * FROM habbo_mentions WHERE target_user_id = ? ORDER BY id DESC LIMIT ?")) {
|
||||||
@@ -192,9 +312,12 @@ public class MentionManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void markRead(int userId, int mode, int mentionId) {
|
public void markRead(int userId, int mode, int mentionId) {
|
||||||
|
if (mode != 0 && mode != 1) return;
|
||||||
|
if (mode == 1 && mentionId <= 0) return;
|
||||||
|
|
||||||
String query = mode == 1
|
String query = mode == 1
|
||||||
? "UPDATE habbo_mentions SET `read` = 1 WHERE target_user_id = ? AND id = ?"
|
? "UPDATE habbo_mentions SET `read` = 1 WHERE target_user_id = ? AND id = ? AND `read` = 0"
|
||||||
: "UPDATE habbo_mentions SET `read` = 1 WHERE target_user_id = ?";
|
: "UPDATE habbo_mentions SET `read` = 1 WHERE target_user_id = ? AND `read` = 0";
|
||||||
try (Connection connection = Emulator.getDatabase().getDataSource().getConnection();
|
try (Connection connection = Emulator.getDatabase().getDataSource().getConnection();
|
||||||
PreparedStatement statement = connection.prepareStatement(query)) {
|
PreparedStatement statement = connection.prepareStatement(query)) {
|
||||||
statement.setInt(1, userId);
|
statement.setInt(1, userId);
|
||||||
@@ -208,6 +331,7 @@ public class MentionManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void delete(int userId, int mentionId) {
|
public void delete(int userId, int mentionId) {
|
||||||
|
if (mentionId <= 0) return;
|
||||||
try (Connection connection = Emulator.getDatabase().getDataSource().getConnection();
|
try (Connection connection = Emulator.getDatabase().getDataSource().getConnection();
|
||||||
PreparedStatement statement = connection.prepareStatement(
|
PreparedStatement statement = connection.prepareStatement(
|
||||||
"DELETE FROM habbo_mentions WHERE target_user_id = ? AND id = ?")) {
|
"DELETE FROM habbo_mentions WHERE target_user_id = ? AND id = ?")) {
|
||||||
@@ -219,6 +343,70 @@ public class MentionManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean tryAcquireRequestList(int userId) {
|
||||||
|
long cooldownMs = Emulator.getConfig().getInt("mentions.request.cooldown.ms", 2000);
|
||||||
|
return tryAcquire(this.requestListCooldowns, userId, cooldownMs);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean tryAcquireMarkRead(int userId, int mode) {
|
||||||
|
long cooldownMs;
|
||||||
|
ConcurrentHashMap<Integer, Long> bucket;
|
||||||
|
if (mode == 1) {
|
||||||
|
cooldownMs = Emulator.getConfig().getInt("mentions.markread.cooldown.ms", 500);
|
||||||
|
bucket = this.markReadCooldowns;
|
||||||
|
} else {
|
||||||
|
cooldownMs = Emulator.getConfig().getInt("mentions.markall.cooldown.ms", 5000);
|
||||||
|
bucket = this.markAllCooldowns;
|
||||||
|
}
|
||||||
|
return tryAcquire(bucket, userId, cooldownMs);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean tryAcquireDelete(int userId) {
|
||||||
|
long cooldownMs = Emulator.getConfig().getInt("mentions.delete.cooldown.ms", 500);
|
||||||
|
return tryAcquire(this.deleteCooldowns, userId, cooldownMs);
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean tryAcquire(ConcurrentHashMap<Integer, Long> bucket, int userId, long cooldownMs) {
|
||||||
|
long now = System.currentTimeMillis();
|
||||||
|
Long last = bucket.get(userId);
|
||||||
|
if (last != null && (now - last) < cooldownMs) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
bucket.put(userId, now);
|
||||||
|
this.pruneCooldownsIfDue(now);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void pruneCooldownsIfDue(long now) {
|
||||||
|
if (now - this.lastPrune < PRUNE_INTERVAL_MS) return;
|
||||||
|
this.lastPrune = now;
|
||||||
|
|
||||||
|
long mentionWindow = Emulator.getConfig().getInt("mentions.cooldown.ms", 3000);
|
||||||
|
long roomWindow = Emulator.getConfig().getInt("mentions.room.cooldown.ms", 15000);
|
||||||
|
long requestWindow = Emulator.getConfig().getInt("mentions.request.cooldown.ms", 2000);
|
||||||
|
long markReadWindow = Emulator.getConfig().getInt("mentions.markread.cooldown.ms", 500);
|
||||||
|
long markAllWindow = Emulator.getConfig().getInt("mentions.markall.cooldown.ms", 5000);
|
||||||
|
long deleteWindow = Emulator.getConfig().getInt("mentions.delete.cooldown.ms", 500);
|
||||||
|
|
||||||
|
prune(this.cooldowns, now, mentionWindow);
|
||||||
|
prune(this.roomBroadcastCooldowns, now, roomWindow);
|
||||||
|
prune(this.requestListCooldowns, now, requestWindow);
|
||||||
|
prune(this.markReadCooldowns, now, markReadWindow);
|
||||||
|
prune(this.markAllCooldowns, now, markAllWindow);
|
||||||
|
prune(this.deleteCooldowns, now, deleteWindow);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void prune(ConcurrentHashMap<Integer, Long> bucket, long now, long windowMs) {
|
||||||
|
Iterator<Map.Entry<Integer, Long>> it = bucket.entrySet().iterator();
|
||||||
|
while (it.hasNext()) {
|
||||||
|
Map.Entry<Integer, Long> entry = it.next();
|
||||||
|
Long value = entry.getValue();
|
||||||
|
if (value == null || (now - value) >= windowMs) {
|
||||||
|
it.remove();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private static final String TRAILING_PUNCTUATION = ".,!?;:)]}\"'";
|
private static final String TRAILING_PUNCTUATION = ".,!?;:)]}\"'";
|
||||||
|
|
||||||
private static String trimTrailingPunctuation(String value) {
|
private static String trimTrailingPunctuation(String value) {
|
||||||
@@ -229,12 +417,12 @@ public class MentionManager {
|
|||||||
return value.substring(0, end);
|
return value.substring(0, end);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
private static String truncate(String value, int max) {
|
||||||
* Resolve a present room occupant from a raw mention token. Tries the token
|
if (value == null) return "";
|
||||||
* verbatim first (so usernames containing allowed punctuation such as '-',
|
if (value.length() <= max) return value;
|
||||||
* '.', '!' still match), then falls back to a trailing-punctuation-trimmed
|
return value.substring(0, max);
|
||||||
* form so a mention written as "@Bob!" still resolves the user "Bob".
|
}
|
||||||
*/
|
|
||||||
private Habbo resolveHabbo(Room room, String rawToken) {
|
private Habbo resolveHabbo(Room room, String rawToken) {
|
||||||
Habbo habbo = room.getHabbo(rawToken);
|
Habbo habbo = room.getHabbo(rawToken);
|
||||||
if (habbo != null) {
|
if (habbo != null) {
|
||||||
|
|||||||
@@ -94,6 +94,8 @@ public class HabboStats implements Runnable {
|
|||||||
public boolean hasGottenDefaultSavedSearches;
|
public boolean hasGottenDefaultSavedSearches;
|
||||||
private HabboInfo habboInfo;
|
private HabboInfo habboInfo;
|
||||||
private boolean allowTrade;
|
private boolean allowTrade;
|
||||||
|
private boolean mentionsEnabled;
|
||||||
|
private boolean massMentionsEnabled;
|
||||||
private int clubExpireTimestamp;
|
private int clubExpireTimestamp;
|
||||||
private int muteEndTime;
|
private int muteEndTime;
|
||||||
public int maxFriends;
|
public int maxFriends;
|
||||||
@@ -131,6 +133,8 @@ public class HabboStats implements Runnable {
|
|||||||
this.guilds = new ArrayList<>();
|
this.guilds = new ArrayList<>();
|
||||||
this.tags = set.getString("tags").split(";");
|
this.tags = set.getString("tags").split(";");
|
||||||
this.allowTrade = set.getString("can_trade").equals("1");
|
this.allowTrade = set.getString("can_trade").equals("1");
|
||||||
|
this.mentionsEnabled = "1".equals(safeColumnString(set, "mentions_enabled", "1"));
|
||||||
|
this.massMentionsEnabled = "1".equals(safeColumnString(set, "mass_mentions_enabled", "1"));
|
||||||
this.votedRooms = new TIntArrayStack();
|
this.votedRooms = new TIntArrayStack();
|
||||||
this.clubExpireTimestamp = set.getInt("club_expire_timestamp");
|
this.clubExpireTimestamp = set.getInt("club_expire_timestamp");
|
||||||
this.loginStreak = set.getInt("login_streak");
|
this.loginStreak = set.getInt("login_streak");
|
||||||
@@ -749,13 +753,6 @@ public class HabboStats implements Runnable {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Ignore an user.
|
|
||||||
*
|
|
||||||
* @param gameClient The client to which this HabboStats instance belongs.
|
|
||||||
* @param userId The user to ignore.
|
|
||||||
* @return true if successfully ignored, false otherwise.
|
|
||||||
*/
|
|
||||||
public boolean ignoreUser(GameClient gameClient, int userId) {
|
public boolean ignoreUser(GameClient gameClient, int userId) {
|
||||||
final Habbo target = Emulator.getGameEnvironment().getHabboManager().getHabbo(userId);
|
final Habbo target = Emulator.getGameEnvironment().getHabboManager().getHabbo(userId);
|
||||||
|
|
||||||
@@ -805,6 +802,44 @@ public class HabboStats implements Runnable {
|
|||||||
else return this.allowTrade;
|
else return this.allowTrade;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean mentionsEnabled() {
|
||||||
|
return this.mentionsEnabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean massMentionsEnabled() {
|
||||||
|
return this.massMentionsEnabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMentionsEnabled(boolean enabled) {
|
||||||
|
this.mentionsEnabled = enabled;
|
||||||
|
persistFlag("mentions_enabled", enabled);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMassMentionsEnabled(boolean enabled) {
|
||||||
|
this.massMentionsEnabled = enabled;
|
||||||
|
persistFlag("mass_mentions_enabled", enabled);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void persistFlag(String column, boolean enabled) {
|
||||||
|
try (Connection connection = Emulator.getDatabase().getDataSource().getConnection();
|
||||||
|
PreparedStatement statement = connection.prepareStatement("UPDATE users_settings SET `" + column + "` = ? WHERE user_id = ? LIMIT 1")) {
|
||||||
|
statement.setString(1, enabled ? "1" : "0");
|
||||||
|
statement.setInt(2, this.habboInfo.getId());
|
||||||
|
statement.executeUpdate();
|
||||||
|
} catch (SQLException e) {
|
||||||
|
LOGGER.error("Failed to persist users_settings.{} for user {}", column, this.habboInfo.getId(), e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String safeColumnString(ResultSet set, String column, String defaultValue) {
|
||||||
|
try {
|
||||||
|
String value = set.getString(column);
|
||||||
|
return value == null ? defaultValue : value;
|
||||||
|
} catch (SQLException e) {
|
||||||
|
return defaultValue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void setAllowTrade(boolean allowTrade) {
|
public void setAllowTrade(boolean allowTrade) {
|
||||||
this.allowTrade = allowTrade;
|
this.allowTrade = allowTrade;
|
||||||
}
|
}
|
||||||
|
|||||||
+14
-1
@@ -1,14 +1,27 @@
|
|||||||
package com.eu.habbo.messages.incoming.mentions;
|
package com.eu.habbo.messages.incoming.mentions;
|
||||||
|
|
||||||
import com.eu.habbo.Emulator;
|
import com.eu.habbo.Emulator;
|
||||||
|
import com.eu.habbo.habbohotel.mentions.MentionManager;
|
||||||
import com.eu.habbo.messages.incoming.MessageHandler;
|
import com.eu.habbo.messages.incoming.MessageHandler;
|
||||||
|
|
||||||
public class DeleteMentionEvent extends MessageHandler {
|
public class DeleteMentionEvent extends MessageHandler {
|
||||||
@Override
|
@Override
|
||||||
public void handle() throws Exception {
|
public void handle() throws Exception {
|
||||||
|
if (this.client == null || this.client.getHabbo() == null) return;
|
||||||
|
|
||||||
int userId = this.client.getHabbo().getHabboInfo().getId();
|
int userId = this.client.getHabbo().getHabboInfo().getId();
|
||||||
int mentionId = this.packet.readInt();
|
int mentionId = this.packet.readInt();
|
||||||
|
|
||||||
Emulator.getGameEnvironment().getMentionManager().delete(userId, mentionId);
|
if (mentionId <= 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
MentionManager manager = Emulator.getGameEnvironment().getMentionManager();
|
||||||
|
|
||||||
|
if (!manager.tryAcquireDelete(userId)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
manager.delete(userId, mentionId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+21
-1
@@ -1,15 +1,35 @@
|
|||||||
package com.eu.habbo.messages.incoming.mentions;
|
package com.eu.habbo.messages.incoming.mentions;
|
||||||
|
|
||||||
import com.eu.habbo.Emulator;
|
import com.eu.habbo.Emulator;
|
||||||
|
import com.eu.habbo.habbohotel.mentions.MentionManager;
|
||||||
import com.eu.habbo.messages.incoming.MessageHandler;
|
import com.eu.habbo.messages.incoming.MessageHandler;
|
||||||
|
|
||||||
public class MarkMentionsReadEvent extends MessageHandler {
|
public class MarkMentionsReadEvent extends MessageHandler {
|
||||||
@Override
|
@Override
|
||||||
public void handle() throws Exception {
|
public void handle() throws Exception {
|
||||||
|
if (this.client == null || this.client.getHabbo() == null) return;
|
||||||
|
|
||||||
int userId = this.client.getHabbo().getHabboInfo().getId();
|
int userId = this.client.getHabbo().getHabboInfo().getId();
|
||||||
int mode = this.packet.readInt();
|
int mode = this.packet.readInt();
|
||||||
int mentionId = this.packet.readInt();
|
int mentionId = this.packet.readInt();
|
||||||
|
|
||||||
Emulator.getGameEnvironment().getMentionManager().markRead(userId, mode, mentionId);
|
// Only mode 0 (mark-all) and mode 1 (mark-single) are valid. Reject
|
||||||
|
// anything else so a crafted packet can't fall into the mark-all branch
|
||||||
|
// by accident.
|
||||||
|
if (mode != 0 && mode != 1) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mode == 1 && mentionId <= 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
MentionManager manager = Emulator.getGameEnvironment().getMentionManager();
|
||||||
|
|
||||||
|
if (!manager.tryAcquireMarkRead(userId, mode)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
manager.markRead(userId, mode, mentionId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+11
-1
@@ -2,6 +2,7 @@ package com.eu.habbo.messages.incoming.mentions;
|
|||||||
|
|
||||||
import com.eu.habbo.Emulator;
|
import com.eu.habbo.Emulator;
|
||||||
import com.eu.habbo.habbohotel.mentions.HabboMention;
|
import com.eu.habbo.habbohotel.mentions.HabboMention;
|
||||||
|
import com.eu.habbo.habbohotel.mentions.MentionManager;
|
||||||
import com.eu.habbo.messages.incoming.MessageHandler;
|
import com.eu.habbo.messages.incoming.MessageHandler;
|
||||||
import com.eu.habbo.messages.outgoing.mentions.MentionsListComposer;
|
import com.eu.habbo.messages.outgoing.mentions.MentionsListComposer;
|
||||||
|
|
||||||
@@ -10,10 +11,19 @@ import java.util.List;
|
|||||||
public class RequestMentionsEvent extends MessageHandler {
|
public class RequestMentionsEvent extends MessageHandler {
|
||||||
@Override
|
@Override
|
||||||
public void handle() throws Exception {
|
public void handle() throws Exception {
|
||||||
|
if (this.client == null || this.client.getHabbo() == null) return;
|
||||||
|
|
||||||
int userId = this.client.getHabbo().getHabboInfo().getId();
|
int userId = this.client.getHabbo().getHabboInfo().getId();
|
||||||
|
|
||||||
|
MentionManager manager = Emulator.getGameEnvironment().getMentionManager();
|
||||||
|
|
||||||
|
if (!manager.tryAcquireRequestList(userId)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
int limit = Emulator.getConfig().getInt("mentions.store.limit", 50);
|
int limit = Emulator.getConfig().getInt("mentions.store.limit", 50);
|
||||||
|
|
||||||
List<HabboMention> mentions = Emulator.getGameEnvironment().getMentionManager().getMentions(userId, limit);
|
List<HabboMention> mentions = manager.getMentions(userId, limit);
|
||||||
this.client.sendResponse(new MentionsListComposer(mentions));
|
this.client.sendResponse(new MentionsListComposer(mentions));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user