Upload folder via GUI - src
This commit is contained in:
@@ -774,8 +774,31 @@ public class StatusAPI extends Plugin implements Runnable {
|
|||||||
boolean escape = false;
|
boolean escape = false;
|
||||||
while (i < json.length()) {
|
while (i < json.length()) {
|
||||||
char ch = json.charAt(i++);
|
char ch = json.charAt(i++);
|
||||||
if (escape) { sb.append(ch); escape = false; }
|
if (escape) {
|
||||||
else {
|
switch (ch) {
|
||||||
|
case 'n': sb.append('\n'); break;
|
||||||
|
case 'r': sb.append('\r'); break;
|
||||||
|
case 't': sb.append('\t'); break;
|
||||||
|
case '"': sb.append('"'); break;
|
||||||
|
case '\\': sb.append('\\'); break;
|
||||||
|
case '/': sb.append('/'); break;
|
||||||
|
case 'b': sb.append('\b'); break;
|
||||||
|
case 'f': sb.append('\f'); break;
|
||||||
|
case 'u':
|
||||||
|
if (i + 4 <= json.length()) {
|
||||||
|
try {
|
||||||
|
int cp = Integer.parseInt(json.substring(i, i + 4), 16);
|
||||||
|
sb.append((char) cp);
|
||||||
|
i += 4;
|
||||||
|
} catch (NumberFormatException ignored) {
|
||||||
|
sb.append("\\u");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default: sb.append(ch); break;
|
||||||
|
}
|
||||||
|
escape = false;
|
||||||
|
} else {
|
||||||
if (ch == '\\') escape = true;
|
if (ch == '\\') escape = true;
|
||||||
else if (ch == '"') break;
|
else if (ch == '"') break;
|
||||||
else sb.append(ch);
|
else sb.append(ch);
|
||||||
@@ -947,4 +970,4 @@ public class StatusAPI extends Plugin implements Runnable {
|
|||||||
String e = event.trim().toLowerCase(Locale.ROOT);
|
String e = event.trim().toLowerCase(Locale.ROOT);
|
||||||
return e.contains("ip_rate") || e.contains("vpn") || e.contains("learning_threshold_block") || e.contains("block");
|
return e.contains("ip_rate") || e.contains("vpn") || e.contains("learning_threshold_block") || e.contains("block");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -3,6 +3,9 @@ package net.viper.status.modules.broadcast;
|
|||||||
import net.md_5.bungee.api.ChatColor;
|
import net.md_5.bungee.api.ChatColor;
|
||||||
import net.md_5.bungee.api.plugin.Plugin;
|
import net.md_5.bungee.api.plugin.Plugin;
|
||||||
import net.md_5.bungee.api.connection.ProxiedPlayer;
|
import net.md_5.bungee.api.connection.ProxiedPlayer;
|
||||||
|
import net.md_5.bungee.api.chat.BaseComponent;
|
||||||
|
import net.md_5.bungee.api.chat.ClickEvent;
|
||||||
|
import net.md_5.bungee.api.chat.ComponentBuilder;
|
||||||
import net.md_5.bungee.api.chat.TextComponent;
|
import net.md_5.bungee.api.chat.TextComponent;
|
||||||
import net.md_5.bungee.api.plugin.Listener;
|
import net.md_5.bungee.api.plugin.Listener;
|
||||||
import net.viper.status.module.Module;
|
import net.viper.status.module.Module;
|
||||||
@@ -20,6 +23,9 @@ import java.util.concurrent.TimeUnit;
|
|||||||
* Fixes:
|
* Fixes:
|
||||||
* - loadSchedules(): ID-Split nutzt jetzt indexOf/lastIndexOf statt split("\\.") mit length==2-Check.
|
* - loadSchedules(): ID-Split nutzt jetzt indexOf/lastIndexOf statt split("\\.") mit length==2-Check.
|
||||||
* Damit werden auch clientScheduleIds die Punkte enthalten korrekt geladen. (Bug #2)
|
* Damit werden auch clientScheduleIds die Punkte enthalten korrekt geladen. (Bug #2)
|
||||||
|
* - handleBroadcast(): &-Farbcodes werden jetzt auch in der Nachricht selbst übersetzt. (Bug #3)
|
||||||
|
* - handleBroadcast(): Literal \n in der Nachricht wird als echter Zeilenumbruch gerendert. (Bug #4)
|
||||||
|
* - handleBroadcast(): URLs (http/https) werden als anklickbare TextComponents eingebettet. (Bug #5)
|
||||||
*/
|
*/
|
||||||
public class BroadcastModule implements Module, Listener {
|
public class BroadcastModule implements Module, Listener {
|
||||||
|
|
||||||
@@ -115,24 +121,83 @@ public class BroadcastModule implements Module, Listener {
|
|||||||
finalPrefix = prefixColorCode + usedPrefix + ChatColor.RESET;
|
finalPrefix = prefixColorCode + usedPrefix + ChatColor.RESET;
|
||||||
}
|
}
|
||||||
|
|
||||||
String coloredMessage = (messageColorCode.isEmpty() ? "" : messageColorCode) + message;
|
// FIX #1: &-Farbcodes auch in der Nachricht selbst übersetzen
|
||||||
|
String translatedMessage = ChatColor.translateAlternateColorCodes('&', message);
|
||||||
|
String coloredMessage = (messageColorCode.isEmpty() ? "" : messageColorCode) + translatedMessage;
|
||||||
|
|
||||||
String out = format
|
String out = format
|
||||||
.replace("%name%", sourceName)
|
.replace("%name%", sourceName)
|
||||||
.replace("%prefix%", finalPrefix)
|
.replace("%prefix%", finalPrefix)
|
||||||
.replace("%prefixColored%", finalPrefix)
|
.replace("%prefixColored%", finalPrefix)
|
||||||
.replace("%message%", message)
|
.replace("%message%", translatedMessage)
|
||||||
.replace("%messageColored%",coloredMessage)
|
.replace("%messageColored%",coloredMessage)
|
||||||
.replace("%type%", type);
|
.replace("%type%", type);
|
||||||
|
|
||||||
TextComponent tc = new TextComponent(out);
|
// FIX #2: \r entfernen (Windows CRLF -> nur LF), Literal \\n als Fallback
|
||||||
|
out = out.replace("\r\n", "\n").replace("\r", "").replace("\\n", "\n");
|
||||||
|
|
||||||
|
// FIX #3: Nachricht mit anklickbaren URLs aufbauen
|
||||||
|
BaseComponent[] components = buildClickableComponents(out);
|
||||||
int sent = 0;
|
int sent = 0;
|
||||||
for (ProxiedPlayer p : plugin.getProxy().getPlayers()) {
|
for (ProxiedPlayer p : plugin.getProxy().getPlayers()) {
|
||||||
try { p.sendMessage(tc); sent++; } catch (Throwable ignored) {}
|
try { p.sendMessage(components); sent++; } catch (Throwable ignored) {}
|
||||||
}
|
}
|
||||||
plugin.getLogger().info("[BroadcastModule] Broadcast gesendet (Empfänger=" + sent + "): " + message);
|
plugin.getLogger().info("[BroadcastModule] Broadcast gesendet (Empfänger=" + sent + "): " + message);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Baut ein BaseComponent-Array aus einem formatierten String.
|
||||||
|
* URLs (http/https) werden als anklickbare TextComponents eingebettet.
|
||||||
|
* Unterstützt auch echte Newlines (\n) als Zeilenumbruch.
|
||||||
|
*/
|
||||||
|
private BaseComponent[] buildClickableComponents(String text) {
|
||||||
|
// Regex für URLs
|
||||||
|
java.util.regex.Pattern urlPattern = java.util.regex.Pattern.compile(
|
||||||
|
"(https?://[^\\s\\n]+)", java.util.regex.Pattern.CASE_INSENSITIVE);
|
||||||
|
|
||||||
|
ComponentBuilder builder = new ComponentBuilder("");
|
||||||
|
|
||||||
|
// Zeilenweise aufteilen (echte \n)
|
||||||
|
String[] lines = text.split("\n", -1);
|
||||||
|
for (int li = 0; li < lines.length; li++) {
|
||||||
|
if (li > 0) {
|
||||||
|
// Zeilenumbruch als eigene Komponente
|
||||||
|
builder.append(TextComponent.fromLegacyText("\n"));
|
||||||
|
}
|
||||||
|
|
||||||
|
String line = lines[li];
|
||||||
|
java.util.regex.Matcher matcher = urlPattern.matcher(line);
|
||||||
|
int lastEnd = 0;
|
||||||
|
|
||||||
|
while (matcher.find()) {
|
||||||
|
// Text vor der URL (mit Minecraft-Farbcodes)
|
||||||
|
if (matcher.start() > lastEnd) {
|
||||||
|
String before = line.substring(lastEnd, matcher.start());
|
||||||
|
builder.append(TextComponent.fromLegacyText(before));
|
||||||
|
}
|
||||||
|
|
||||||
|
// URL selbst: anklickbar + unterstrichen
|
||||||
|
String url = matcher.group(1);
|
||||||
|
TextComponent urlComponent = new TextComponent(url);
|
||||||
|
urlComponent.setClickEvent(new ClickEvent(ClickEvent.Action.OPEN_URL, url));
|
||||||
|
// Farbe der URL auf Cyan setzen damit sie sich abhebt
|
||||||
|
urlComponent.setColor(ChatColor.AQUA);
|
||||||
|
urlComponent.setUnderlined(true);
|
||||||
|
builder.append(urlComponent, ComponentBuilder.FormatRetention.NONE);
|
||||||
|
|
||||||
|
lastEnd = matcher.end();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Restlicher Text nach der letzten URL
|
||||||
|
if (lastEnd < line.length()) {
|
||||||
|
builder.append(TextComponent.fromLegacyText(line.substring(lastEnd)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return builder.create();
|
||||||
|
}
|
||||||
|
|
||||||
private String normalizeColorCode(String code) {
|
private String normalizeColorCode(String code) {
|
||||||
if (code == null) return "";
|
if (code == null) return "";
|
||||||
code = code.trim();
|
code = code.trim();
|
||||||
@@ -310,4 +375,4 @@ public class BroadcastModule implements Module, Listener {
|
|||||||
this.recur = recur == null ? "none" : recur;
|
this.recur = recur == null ? "none" : recur;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user