You've already forked Arcturus-Morningstar-Extended
mirror of
https://github.com/duckietm/Arcturus-Morningstar-Extended.git
synced 2026-06-19 15:06:19 +00:00
Fix wired text capture and showmessage behavior
This commit is contained in:
+1
-1
@@ -82,7 +82,7 @@ public class WiredEffectBotTalk extends InteractionWiredEffect {
|
||||
|
||||
this.setDelay(delay);
|
||||
this.botName = data[0].substring(0, Math.min(data[0].length(), Emulator.getConfig().getInt("hotel.wired.message.max_length", 100)));
|
||||
this.message = data[1].substring(0, Math.min(data[1].length(), Emulator.getConfig().getInt("hotel.wired.message.max_length", 100)));
|
||||
this.message = data[1].substring(0, Math.min(data[1].length(), Emulator.getConfig().getInt("hotel.wired.bot.message.max_length", 100)));
|
||||
this.mode = mode;
|
||||
|
||||
return true;
|
||||
|
||||
+1
-1
@@ -105,7 +105,7 @@ public class WiredEffectBotTalkToHabbo extends InteractionWiredEffect {
|
||||
throw new WiredSaveException("Delay too long");
|
||||
|
||||
this.botName = data[0].substring(0, Math.min(data[0].length(), Emulator.getConfig().getInt("hotel.wired.message.max_length", 100)));
|
||||
this.message = data[1].substring(0, Math.min(data[1].length(), Emulator.getConfig().getInt("hotel.wired.message.max_length", 100)));
|
||||
this.message = data[1].substring(0, Math.min(data[1].length(), Emulator.getConfig().getInt("hotel.wired.bot.message.max_length", 100)));
|
||||
this.mode = mode;
|
||||
this.setDelay(delay);
|
||||
|
||||
|
||||
+38
-2
@@ -34,6 +34,8 @@ public class WiredEffectWhisper extends InteractionWiredEffect {
|
||||
private static final long DELIVERY_DEDUP_TTL_MS = 60_000L;
|
||||
private static final int DELIVERY_DEDUP_CLEANUP_THRESHOLD = 512;
|
||||
private static final ConcurrentHashMap<String, Long> DELIVERY_DEDUP = new ConcurrentHashMap<>();
|
||||
private static final int DEFAULT_SHOW_MESSAGE_MAX_LENGTH = 200;
|
||||
private static final int DEFAULT_SHOW_MESSAGE_MAX_LINES = 8;
|
||||
|
||||
protected String message = "";
|
||||
protected int userSource = WiredSourceUtil.SOURCE_TRIGGER;
|
||||
@@ -96,9 +98,12 @@ public class WiredEffectWhisper extends InteractionWiredEffect {
|
||||
|
||||
if(gameClient.getHabbo() == null || !gameClient.getHabbo().hasPermission(Permission.ACC_SUPERWIRED)) {
|
||||
message = Emulator.getGameEnvironment().getWordFilter().filter(message, null);
|
||||
message = message.substring(0, Math.min(message.length(), Emulator.getConfig().getInt("hotel.wired.message.max_length", 100)));
|
||||
}
|
||||
|
||||
int maxLength = Emulator.getConfig().getInt("hotel.wired.show_message.max_length", DEFAULT_SHOW_MESSAGE_MAX_LENGTH);
|
||||
int maxLines = Emulator.getConfig().getInt("hotel.wired.show_message.max_lines", DEFAULT_SHOW_MESSAGE_MAX_LINES);
|
||||
message = clampMessage(message, maxLength, maxLines);
|
||||
|
||||
int delay = settings.getDelay();
|
||||
|
||||
if(delay > Emulator.getConfig().getInt("hotel.wired.max_delay", 20))
|
||||
@@ -109,6 +114,35 @@ public class WiredEffectWhisper extends InteractionWiredEffect {
|
||||
return true;
|
||||
}
|
||||
|
||||
private static String clampMessage(String value, int maxLength, int maxLines) {
|
||||
if (value == null || value.isEmpty()) {
|
||||
return "";
|
||||
}
|
||||
|
||||
int safeMaxLength = Math.max(1, maxLength);
|
||||
int safeMaxLines = Math.max(1, maxLines);
|
||||
|
||||
String normalized = value.replace("\r\n", "\n").replace('\r', '\n');
|
||||
String[] lines = normalized.split("\n", -1);
|
||||
|
||||
StringBuilder builder = new StringBuilder();
|
||||
int linesToWrite = Math.min(lines.length, safeMaxLines);
|
||||
|
||||
for (int index = 0; index < linesToWrite; index++) {
|
||||
if (builder.length() > 0) {
|
||||
builder.append('\n');
|
||||
}
|
||||
|
||||
builder.append(lines[index]);
|
||||
}
|
||||
|
||||
if (builder.length() > safeMaxLength) {
|
||||
builder.setLength(safeMaxLength);
|
||||
}
|
||||
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
protected List<RoomUnit> resolveUsers(WiredContext ctx) {
|
||||
return WiredSourceUtil.resolveUsers(ctx, this.userSource);
|
||||
}
|
||||
@@ -212,7 +246,9 @@ public class WiredEffectWhisper extends InteractionWiredEffect {
|
||||
}
|
||||
|
||||
String msg = buildMessage(ctx, (sharedSourceHabbo != null) ? sharedSourceHabbo : habbo);
|
||||
habbo.getClient().sendResponse(new RoomUserWhisperComposer(new RoomChatMessage(msg, habbo, habbo, RoomChatMessageBubbles.getBubble(this.bubbleStyle))));
|
||||
habbo.getClient().sendResponse(new RoomUserWhisperComposer(
|
||||
new RoomChatMessage(msg, habbo.getRoomUnit(), RoomChatMessageBubbles.getBubble(this.bubbleStyle))
|
||||
));
|
||||
|
||||
if (habbo.getRoomUnit().isIdle()) {
|
||||
habbo.getRoomUnit().getRoom().unIdle(habbo);
|
||||
|
||||
+173
-7
@@ -64,8 +64,17 @@ public final class WiredTextInputCaptureSupport {
|
||||
return trigger.matches(stack.triggerItem(), event) ? CaptureResult.matched(new LinkedHashMap<>()) : CaptureResult.noMatch();
|
||||
}
|
||||
|
||||
MatchResult matchResult = matchTemplate(trigger, text, capturersByName);
|
||||
MatchResult matchResult = matchTemplate(trigger, text, capturersByName, room);
|
||||
if (!matchResult.matches) {
|
||||
if (WiredManager.isDebugEnabled()) {
|
||||
WiredManager.debug("[TextCapture] NO_MATCH room={} triggerId={} mode={} key='{}' text='{}' len={}",
|
||||
room.getId(),
|
||||
stack.triggerItem().getId(),
|
||||
trigger.getMatchMode(),
|
||||
safeForLog(trigger.getKey()),
|
||||
safeForLog(text),
|
||||
(text != null ? text.length() : 0));
|
||||
}
|
||||
return CaptureResult.noMatch();
|
||||
}
|
||||
|
||||
@@ -78,12 +87,28 @@ public final class WiredTextInputCaptureSupport {
|
||||
|
||||
Integer resolvedValue = capturer.resolveCapturedValue(room, capture.getValue());
|
||||
if (resolvedValue == null) {
|
||||
if (WiredManager.isDebugEnabled()) {
|
||||
WiredManager.debug("[TextCapture] RESOLVE_FAIL room={} triggerId={} capturer='{}' raw='{}' rawLen={}",
|
||||
room.getId(),
|
||||
stack.triggerItem().getId(),
|
||||
capture.getKey(),
|
||||
safeForLog(capture.getValue()),
|
||||
(capture.getValue() != null ? capture.getValue().length() : 0));
|
||||
}
|
||||
return CaptureResult.noMatch();
|
||||
}
|
||||
|
||||
capturedValues.put(capturer.getVariableItemId(), resolvedValue);
|
||||
}
|
||||
|
||||
if (WiredManager.isDebugEnabled()) {
|
||||
WiredManager.debug("[TextCapture] MATCH_OK room={} triggerId={} captures={} textLen={}",
|
||||
room.getId(),
|
||||
stack.triggerItem().getId(),
|
||||
capturedValues.size(),
|
||||
(text != null ? text.length() : 0));
|
||||
}
|
||||
|
||||
return CaptureResult.matched(capturedValues);
|
||||
}
|
||||
|
||||
@@ -108,12 +133,13 @@ public final class WiredTextInputCaptureSupport {
|
||||
return capturers;
|
||||
}
|
||||
|
||||
private static MatchResult matchTemplate(WiredTriggerHabboSaysKeyword trigger, String rawText, Map<String, WiredExtraTextInputVariable> capturersByName) {
|
||||
String text = rawText != null ? rawText.trim() : "";
|
||||
private static MatchResult matchTemplate(WiredTriggerHabboSaysKeyword trigger, String rawText, Map<String, WiredExtraTextInputVariable> capturersByName, Room room) {
|
||||
String text = rawText != null ? rawText : "";
|
||||
String normalizedText = text.trim();
|
||||
String template = trigger.getKey() != null ? trigger.getKey().trim() : "";
|
||||
|
||||
if (trigger.getMatchMode() == MATCH_ALL_WORDS && template.isEmpty()) {
|
||||
if (capturersByName.size() != 1 || text.isEmpty()) {
|
||||
if (capturersByName.size() != 1 || normalizedText.isEmpty()) {
|
||||
return MatchResult.noMatch();
|
||||
}
|
||||
|
||||
@@ -123,12 +149,24 @@ public final class WiredTextInputCaptureSupport {
|
||||
return MatchResult.matched(captures);
|
||||
}
|
||||
|
||||
MatchResult adjacentCaptureResult = matchAdjacentCapturers(template, rawText, capturersByName, room, trigger.getMatchMode());
|
||||
if (adjacentCaptureResult != null) {
|
||||
if (WiredManager.isDebugEnabled()) {
|
||||
WiredManager.debug("[TextCapture] ADJACENT mode used key='{}' textLen={} matched={}",
|
||||
safeForLog(template),
|
||||
(rawText != null ? rawText.length() : 0),
|
||||
adjacentCaptureResult.matches);
|
||||
}
|
||||
return adjacentCaptureResult;
|
||||
}
|
||||
|
||||
TemplatePattern pattern = buildPattern(template);
|
||||
if (pattern == null) {
|
||||
return MatchResult.noMatch();
|
||||
}
|
||||
|
||||
Matcher matcher = pattern.pattern.matcher(text);
|
||||
String matchText = pattern.placeholderNames.isEmpty() ? normalizedText : text;
|
||||
Matcher matcher = pattern.pattern.matcher(matchText);
|
||||
boolean matches = (trigger.getMatchMode() == MATCH_CONTAINS) ? matcher.find() : matcher.matches();
|
||||
if (!matches) {
|
||||
return MatchResult.noMatch();
|
||||
@@ -142,12 +180,136 @@ public final class WiredTextInputCaptureSupport {
|
||||
}
|
||||
|
||||
String capturedValue = matcher.group(index + 1);
|
||||
captures.put(placeholderName, capturedValue != null ? capturedValue.trim() : "");
|
||||
captures.put(placeholderName, normalizeCapturedValue(capturedValue));
|
||||
}
|
||||
|
||||
return MatchResult.matched(captures);
|
||||
}
|
||||
|
||||
private static MatchResult matchAdjacentCapturers(String template, String rawText, Map<String, WiredExtraTextInputVariable> capturersByName, Room room, int matchMode) {
|
||||
if (template == null || template.isEmpty() || rawText == null || capturersByName == null || capturersByName.isEmpty() || room == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
Matcher matcher = PLACEHOLDER_PATTERN.matcher(template);
|
||||
List<String> placeholderNames = new ArrayList<>();
|
||||
int cursor = 0;
|
||||
|
||||
while (matcher.find()) {
|
||||
if (matcher.start() != cursor) {
|
||||
return null;
|
||||
}
|
||||
|
||||
String placeholderName = matcher.group(1) != null ? matcher.group(1).trim().toLowerCase() : "";
|
||||
if (placeholderName.isEmpty() || !capturersByName.containsKey(placeholderName)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
placeholderNames.add(placeholderName);
|
||||
cursor = matcher.end();
|
||||
}
|
||||
|
||||
if (placeholderNames.isEmpty() || cursor != template.length()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
int placeholderCount = placeholderNames.size();
|
||||
int textLength = rawText.length();
|
||||
|
||||
boolean[][] reachable = new boolean[placeholderCount + 1][textLength + 1];
|
||||
int[][] previousIndex = new int[placeholderCount + 1][textLength + 1];
|
||||
String[][] capturedValues = new String[placeholderCount + 1][textLength + 1];
|
||||
|
||||
for (int placeholderIndex = 0; placeholderIndex <= placeholderCount; placeholderIndex++) {
|
||||
for (int textIndex = 0; textIndex <= textLength; textIndex++) {
|
||||
previousIndex[placeholderIndex][textIndex] = -1;
|
||||
}
|
||||
}
|
||||
|
||||
reachable[0][0] = true;
|
||||
|
||||
for (int placeholderIndex = 0; placeholderIndex < placeholderCount; placeholderIndex++) {
|
||||
String placeholderName = placeholderNames.get(placeholderIndex);
|
||||
WiredExtraTextInputVariable capturer = capturersByName.get(placeholderName);
|
||||
if (capturer == null) {
|
||||
return MatchResult.noMatch();
|
||||
}
|
||||
|
||||
for (int textIndex = 0; textIndex <= textLength; textIndex++) {
|
||||
if (!reachable[placeholderIndex][textIndex]) {
|
||||
continue;
|
||||
}
|
||||
|
||||
int minEndIndex = (textIndex < textLength) ? (textIndex + 1) : textIndex;
|
||||
for (int endIndex = minEndIndex; endIndex <= textLength; endIndex++) {
|
||||
if (reachable[placeholderIndex + 1][endIndex]) {
|
||||
continue;
|
||||
}
|
||||
|
||||
String candidate = rawText.substring(textIndex, endIndex);
|
||||
if (capturer.resolveCapturedValue(room, candidate) == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
reachable[placeholderIndex + 1][endIndex] = true;
|
||||
previousIndex[placeholderIndex + 1][endIndex] = textIndex;
|
||||
capturedValues[placeholderIndex + 1][endIndex] = candidate;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int resultEndIndex = -1;
|
||||
if (matchMode == MATCH_CONTAINS) {
|
||||
for (int endIndex = textLength; endIndex >= 0; endIndex--) {
|
||||
if (reachable[placeholderCount][endIndex]) {
|
||||
resultEndIndex = endIndex;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else if (reachable[placeholderCount][textLength]) {
|
||||
resultEndIndex = textLength;
|
||||
}
|
||||
|
||||
if (resultEndIndex < 0) {
|
||||
return MatchResult.noMatch();
|
||||
}
|
||||
|
||||
LinkedHashMap<String, String> captures = new LinkedHashMap<>();
|
||||
int backtrackTextIndex = resultEndIndex;
|
||||
for (int placeholderIndex = placeholderCount; placeholderIndex > 0; placeholderIndex--) {
|
||||
String placeholderName = placeholderNames.get(placeholderIndex - 1);
|
||||
String capturedValue = capturedValues[placeholderIndex][backtrackTextIndex];
|
||||
captures.put(placeholderName, capturedValue != null ? capturedValue : "");
|
||||
backtrackTextIndex = previousIndex[placeholderIndex][backtrackTextIndex];
|
||||
if (backtrackTextIndex < 0) {
|
||||
return MatchResult.noMatch();
|
||||
}
|
||||
}
|
||||
|
||||
return MatchResult.matched(captures);
|
||||
}
|
||||
|
||||
private static String normalizeCapturedValue(String value) {
|
||||
return value != null ? value : "";
|
||||
}
|
||||
|
||||
private static String safeForLog(String value) {
|
||||
if (value == null) {
|
||||
return "";
|
||||
}
|
||||
|
||||
String normalized = value
|
||||
.replace("\r", "\\r")
|
||||
.replace("\n", "\\n")
|
||||
.replace("\u00A0", "⍽");
|
||||
|
||||
if (normalized.length() > 180) {
|
||||
return normalized.substring(0, 180) + "...(" + normalized.length() + ")";
|
||||
}
|
||||
|
||||
return normalized;
|
||||
}
|
||||
|
||||
private static TemplatePattern buildPattern(String template) {
|
||||
if (template == null || template.isEmpty()) {
|
||||
return null;
|
||||
@@ -160,7 +322,7 @@ public final class WiredTextInputCaptureSupport {
|
||||
|
||||
while (matcher.find()) {
|
||||
regex.append(Pattern.quote(template.substring(cursor, matcher.start())));
|
||||
regex.append("(.+?)");
|
||||
regex.append(hasPlaceholderAfter(template, matcher.end()) ? "(.+?)" : "(.+)");
|
||||
|
||||
String placeholderName = matcher.group(1) != null ? matcher.group(1).trim().toLowerCase() : "";
|
||||
placeholderNames.add(placeholderName);
|
||||
@@ -176,6 +338,10 @@ public final class WiredTextInputCaptureSupport {
|
||||
return new TemplatePattern(Pattern.compile(regex.toString(), Pattern.CASE_INSENSITIVE | Pattern.UNICODE_CASE), placeholderNames);
|
||||
}
|
||||
|
||||
private static boolean hasPlaceholderAfter(String template, int cursor) {
|
||||
return PLACEHOLDER_PATTERN.matcher(template.substring(cursor)).find();
|
||||
}
|
||||
|
||||
public static void applyToContext(WiredContext ctx, Room room, CaptureResult captureResult) {
|
||||
if (ctx == null || room == null || captureResult == null || !captureResult.matches || captureResult.capturedValues.isEmpty()) {
|
||||
return;
|
||||
|
||||
Reference in New Issue
Block a user