summaryrefslogtreecommitdiffstats
path: root/src/main
diff options
context:
space:
mode:
authorThinkofdeath <thinkofdeath@spigotmc.org>2014-12-13 10:26:06 +0000
committerThinkofdeath <thinkofdeath@spigotmc.org>2014-12-13 10:27:26 +0000
commitd5ede3bd6dc19f645864f251d501a1765ed505f7 (patch)
tree4178f710b1a5d9eb917580b781998b96053bf665 /src/main
parent5f2a9eadde3aa899b554a1c8a65e6ae2e86af98e (diff)
downloadcraftbukkit-d5ede3bd6dc19f645864f251d501a1765ed505f7.tar
craftbukkit-d5ede3bd6dc19f645864f251d501a1765ed505f7.tar.gz
craftbukkit-d5ede3bd6dc19f645864f251d501a1765ed505f7.tar.lz
craftbukkit-d5ede3bd6dc19f645864f251d501a1765ed505f7.tar.xz
craftbukkit-d5ede3bd6dc19f645864f251d501a1765ed505f7.zip
Rework the vanilla link fix so that hover/click events aren't lost
Diffstat (limited to 'src/main')
-rw-r--r--src/main/java/org/bukkit/craftbukkit/util/CraftChatMessage.java86
1 files changed, 84 insertions, 2 deletions
diff --git a/src/main/java/org/bukkit/craftbukkit/util/CraftChatMessage.java b/src/main/java/org/bukkit/craftbukkit/util/CraftChatMessage.java
index c3f27f1f..d2b41c30 100644
--- a/src/main/java/org/bukkit/craftbukkit/util/CraftChatMessage.java
+++ b/src/main/java/org/bukkit/craftbukkit/util/CraftChatMessage.java
@@ -15,11 +15,14 @@ import net.minecraft.server.IChatBaseComponent;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableMap.Builder;
+import net.minecraft.server.ChatMessage;
public final class CraftChatMessage {
+
+ private static final Pattern LINK_PATTERN = Pattern.compile("((?:(?:https?):\\/\\/)?(?:[-\\w_\\.]{2,}\\.[a-z]{2,4}.*?(?=[\\.\\?!,;:]?(?:[" + String.valueOf(org.bukkit.ChatColor.COLOR_CHAR) + " \\n]|$))))");
private static class StringMessage {
private static final Map<Character, EnumChatFormat> formatMap;
- private static final Pattern INCREMENTAL_PATTERN = Pattern.compile("(" + String.valueOf(org.bukkit.ChatColor.COLOR_CHAR) + "[0-9a-fk-or])|(\\n)|(?:(https?://[^ ][^ ]*?)(?=[\\.\\?!,;:]?(?:[ \\n]|$)))", Pattern.CASE_INSENSITIVE);
+ private static final Pattern INCREMENTAL_PATTERN = Pattern.compile("(" + String.valueOf(org.bukkit.ChatColor.COLOR_CHAR) + "[0-9a-fk-or])|(\\n)|((?:(?:https?):\\/\\/)?(?:[-\\w_\\.]{2,}\\.[a-z]{2,4}.*?(?=[\\.\\?!,;:]?(?:[" + String.valueOf(org.bukkit.ChatColor.COLOR_CHAR) + " \\n]|$))))", Pattern.CASE_INSENSITIVE);
static {
Builder<Character, EnumChatFormat> builder = ImmutableMap.builder();
@@ -89,6 +92,9 @@ public final class CraftChatMessage {
}
break;
case 3:
+ if ( !( match.startsWith( "http://" ) || match.startsWith( "https://" ) ) ) {
+ match = "http://" + match;
+ }
modifier.setChatClickable(new ChatClickable(EnumClickAction.OPEN_URL, match));
appendNewComponent(matcher.end(groupId));
modifier.setChatClickable((ChatClickable) null);
@@ -100,7 +106,7 @@ public final class CraftChatMessage {
appendNewComponent(message.length());
}
- output = list.toArray(new IChatBaseComponent[0]);
+ output = list.toArray(new IChatBaseComponent[list.size()]);
}
private void appendNewComponent(int index) {
@@ -161,6 +167,82 @@ public final class CraftChatMessage {
return out.toString().replaceFirst("^(" + defaultColor + ")*", "");
}
+ public static IChatBaseComponent fixComponent(IChatBaseComponent component) {
+ Matcher matcher = LINK_PATTERN.matcher("");
+ return fixComponent(component, matcher);
+ }
+
+ private static IChatBaseComponent fixComponent(IChatBaseComponent component, Matcher matcher) {
+ if (component instanceof ChatComponentText) {
+ ChatComponentText text = ((ChatComponentText) component);
+ String msg = text.g();
+ if (matcher.reset(msg).find()) {
+ matcher.reset();
+
+ ChatModifier modifier = text.getChatModifier() != null ?
+ text.getChatModifier() : new ChatModifier();
+ List<IChatBaseComponent> extras = new ArrayList<IChatBaseComponent>();
+ List<IChatBaseComponent> extrasOld = new ArrayList<IChatBaseComponent>(text.a());
+ component = text = new ChatComponentText("");
+
+ int pos = 0;
+ while (matcher.find()) {
+ String match = matcher.group();
+
+ if ( !( match.startsWith( "http://" ) || match.startsWith( "https://" ) ) ) {
+ match = "http://" + match;
+ }
+
+ ChatComponentText prev = new ChatComponentText(msg.substring(pos, matcher.start()));
+ prev.setChatModifier(modifier);
+ extras.add(prev);
+
+ ChatComponentText link = new ChatComponentText(matcher.group());
+ ChatModifier linkModi = modifier.clone();
+ linkModi.setChatClickable(new ChatClickable(EnumClickAction.OPEN_URL, match));
+ link.setChatModifier(linkModi);
+ extras.add(link);
+
+ pos = matcher.end();
+ }
+
+ ChatComponentText prev = new ChatComponentText(msg.substring(pos));
+ prev.setChatModifier(modifier);
+ extras.add(prev);
+ extras.addAll(extrasOld);
+
+ for (IChatBaseComponent c : extras) {
+ text.addSibling(c);
+ }
+ }
+ }
+
+ List extras = component.a();
+ for (int i = 0; i < extras.size(); i++) {
+ IChatBaseComponent comp = (IChatBaseComponent) extras.get(i);
+ if (comp.getChatModifier() != null && comp.getChatModifier().h() == null) {
+ extras.set(i, fixComponent(comp, matcher));
+ }
+ }
+
+ if (component instanceof ChatMessage) {
+ Object[] subs = ((ChatMessage) component).j();
+ for (int i = 0; i < subs.length; i++) {
+ Object comp = subs[i];
+ if (comp instanceof IChatBaseComponent) {
+ IChatBaseComponent c = (IChatBaseComponent) comp;
+ if (c.getChatModifier() != null && c.getChatModifier().h() == null) {
+ subs[i] = fixComponent(c, matcher);
+ }
+ } else if (comp instanceof String && matcher.reset((String)comp).find()) {
+ subs[i] = fixComponent(new ChatComponentText((String) comp), matcher);
+ }
+ }
+ }
+
+ return component;
+ }
+
private CraftChatMessage() {
}
}