From 5ad9b20df6175c93ea54bd2961d30ab256b25235 Mon Sep 17 00:00:00 2001 From: Thinkofdeath Date: Sun, 1 Dec 2013 10:33:55 +0000 Subject: [PATCH] Fix links in chat diff --git a/src/main/java/org/bukkit/craftbukkit/util/CraftChatMessage.java b/src/main/java/org/bukkit/craftbukkit/util/CraftChatMessage.java index cc8e715..5607df1 100644 --- a/src/main/java/org/bukkit/craftbukkit/util/CraftChatMessage.java +++ b/src/main/java/org/bukkit/craftbukkit/util/CraftChatMessage.java @@ -3,11 +3,15 @@ package org.bukkit.craftbukkit.util; import java.util.ArrayList; import java.util.List; import java.util.Map; +import java.util.regex.Matcher; +import java.util.regex.Pattern; import net.minecraft.server.ChatComponentText; import net.minecraft.server.ChatModifier; import net.minecraft.server.EnumChatFormat; import net.minecraft.server.IChatBaseComponent; +import net.minecraft.server.ChatClickable; +import net.minecraft.server.EnumClickAction; import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableMap.Builder; @@ -29,6 +33,8 @@ public final class CraftChatMessage { private ChatModifier modifier = new ChatModifier(); private StringBuilder builder = new StringBuilder(); private final IChatBaseComponent[] output; + private static final Pattern url = Pattern.compile("^(\u00A7.)*?((?:(https?)://)?([-\\w_\\.]{2,}\\.[a-z]{2,4})(/\\S*?)?)(\u00A7.)*?$"); + private int lastWord = 0; private FromString(String message) { if (message == null) { @@ -38,10 +44,14 @@ public final class CraftChatMessage { list.add(currentChatComponent); EnumChatFormat format = null; + Matcher matcher = url.matcher(message); + lastWord = 0; for (int i = 0; i < message.length(); i++) { char currentChar = message.charAt(i); if (currentChar == '\u00A7' && (i < (message.length() - 1)) && (format = formatMap.get(message.charAt(i + 1))) != null) { + checkUrl(matcher, message, i); + lastWord++; if (builder.length() > 0) { appendNewComponent(); } @@ -73,11 +83,18 @@ public final class CraftChatMessage { } i++; } else if (currentChar == '\n') { + checkUrl(matcher, message, i); + lastWord = i + 1; if (builder.length() > 0) { appendNewComponent(); } currentChatComponent = null; } else { + if (currentChar == ' ' || i == message.length() - 1) { + if (checkUrl(matcher, message, i)) { + break; + } + } builder.append(currentChar); } } @@ -89,6 +106,31 @@ public final class CraftChatMessage { output = list.toArray(new IChatBaseComponent[0]); } + private boolean checkUrl(Matcher matcher, String message, int i) { + Matcher urlMatcher = matcher.region(lastWord, i == message.length() - 1 ? message.length() : i); + lastWord = i + 1; + if (urlMatcher.find()) { + String fullUrl = urlMatcher.group(2); + String protocol = urlMatcher.group(3); + String url = urlMatcher.group(4); + String path = urlMatcher.group(5); + builder.delete(builder.length() - fullUrl.length() + (i == message.length() - 1 ? 1 : 0), builder.length()); + if (builder.length() > 0) { + appendNewComponent(); + } + builder.append(fullUrl); + ChatClickable link = new ChatClickable(EnumClickAction.OPEN_URL, + (protocol!=null?protocol:"http") + "://" + url + (path!=null?path:"")); + modifier.a(link); + appendNewComponent(); + modifier.a((ChatClickable) null); + if (i == message.length() - 1) { + return true; + } + } + return false; + } + private void appendNewComponent() { IChatBaseComponent addition = new ChatComponentText(builder.toString()).setChatModifier(modifier); builder = new StringBuilder(); -- 1.8.3.2