From 8278880f0fedbf11870355a41dc352b66019b024 Mon Sep 17 00:00:00 2001 From: md_5 Date: Wed, 18 Dec 2013 20:41:42 +1100 Subject: [PATCH] Fall back to our own URL clicking method as it works with more cases. --- .../0078-Remove-Bukkit-URL-Clicking.patch | 138 ++++++++++++++++++ .../0079-Fix-links-in-chat.patch | 104 +++++++++++++ 2 files changed, 242 insertions(+) create mode 100644 CraftBukkit-Patches/0078-Remove-Bukkit-URL-Clicking.patch create mode 100644 CraftBukkit-Patches/0079-Fix-links-in-chat.patch diff --git a/CraftBukkit-Patches/0078-Remove-Bukkit-URL-Clicking.patch b/CraftBukkit-Patches/0078-Remove-Bukkit-URL-Clicking.patch new file mode 100644 index 000000000..8b2c3daaa --- /dev/null +++ b/CraftBukkit-Patches/0078-Remove-Bukkit-URL-Clicking.patch @@ -0,0 +1,138 @@ +From c885097ad616281a32bda406764809b460e1e175 Mon Sep 17 00:00:00 2001 +From: md_5 +Date: Wed, 18 Dec 2013 20:39:24 +1100 +Subject: [PATCH] Remove Bukkit URL Clicking + + +diff --git a/src/main/java/org/bukkit/craftbukkit/util/CraftChatMessage.java b/src/main/java/org/bukkit/craftbukkit/util/CraftChatMessage.java +index 66368f4..cc8e715 100644 +--- a/src/main/java/org/bukkit/craftbukkit/util/CraftChatMessage.java ++++ b/src/main/java/org/bukkit/craftbukkit/util/CraftChatMessage.java +@@ -3,28 +3,23 @@ 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.ChatClickable; + import net.minecraft.server.ChatComponentText; + import net.minecraft.server.ChatModifier; + import net.minecraft.server.EnumChatFormat; +-import net.minecraft.server.EnumClickAction; + import net.minecraft.server.IChatBaseComponent; + + import com.google.common.collect.ImmutableMap; + import com.google.common.collect.ImmutableMap.Builder; + + public final class CraftChatMessage { +- private static class StringMessage { ++ private static class FromString { + private static final Map 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); + + static { + Builder builder = ImmutableMap.builder(); + for (EnumChatFormat format : EnumChatFormat.values()) { +- builder.put(Character.toLowerCase(format.getChar()), format); ++ builder.put(format.getChar(), format); + } + formatMap = builder.build(); + } +@@ -32,29 +27,25 @@ public final class CraftChatMessage { + private final List list = new ArrayList(); + private IChatBaseComponent currentChatComponent = new ChatComponentText(""); + private ChatModifier modifier = new ChatModifier(); ++ private StringBuilder builder = new StringBuilder(); + private final IChatBaseComponent[] output; +- private int currentIndex; +- private final String message; + +- private StringMessage(String message) { +- this.message = message; ++ private FromString(String message) { + if (message == null) { + output = new IChatBaseComponent[] { currentChatComponent }; + return; + } + list.add(currentChatComponent); + +- Matcher matcher = INCREMENTAL_PATTERN.matcher(message); +- String match = null; +- while (matcher.find()) { +- int groupId = 0; +- while ((match = matcher.group(++groupId)) == null) { +- // NOOP +- } +- appendNewComponent(matcher.start(groupId)); +- switch (groupId) { +- case 1: +- EnumChatFormat format = formatMap.get(match.toLowerCase().charAt(1)); ++ EnumChatFormat format = null; ++ ++ 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) { ++ if (builder.length() > 0) { ++ appendNewComponent(); ++ } ++ + if (format == EnumChatFormat.RESET) { + modifier = new ChatModifier(); + } else if (format.isFormat()) { +@@ -80,31 +71,27 @@ public final class CraftChatMessage { + } else { // Color resets formatting + modifier = new ChatModifier().setColor(format); + } +- break; +- case 2: ++ i++; ++ } else if (currentChar == '\n') { ++ if (builder.length() > 0) { ++ appendNewComponent(); ++ } + currentChatComponent = null; +- break; +- case 3: +- modifier.a(new ChatClickable(EnumClickAction.OPEN_URL, match)); // Should be setChatClickable +- appendNewComponent(matcher.end(groupId)); +- modifier.a((ChatClickable) null); ++ } else { ++ builder.append(currentChar); + } +- currentIndex = matcher.end(groupId); + } + +- if (currentIndex < message.length()) { +- appendNewComponent(message.length()); ++ if (builder.length() > 0) { ++ appendNewComponent(); + } + + output = list.toArray(new IChatBaseComponent[0]); + } + +- private void appendNewComponent(int index) { +- if (index <= currentIndex) { +- return; +- } +- IChatBaseComponent addition = new ChatComponentText(message.substring(currentIndex, index)).setChatModifier(modifier); +- currentIndex = index; ++ private void appendNewComponent() { ++ IChatBaseComponent addition = new ChatComponentText(builder.toString()).setChatModifier(modifier); ++ builder = new StringBuilder(); + modifier = modifier.clone(); + if (currentChatComponent == null) { + currentChatComponent = new ChatComponentText(""); +@@ -119,7 +106,7 @@ public final class CraftChatMessage { + } + + public static IChatBaseComponent[] fromString(String message) { +- return new StringMessage(message).getOutput(); ++ return new FromString(message).getOutput(); + } + + private CraftChatMessage() { +-- +1.8.3.2 + diff --git a/CraftBukkit-Patches/0079-Fix-links-in-chat.patch b/CraftBukkit-Patches/0079-Fix-links-in-chat.patch new file mode 100644 index 000000000..38d1d28f1 --- /dev/null +++ b/CraftBukkit-Patches/0079-Fix-links-in-chat.patch @@ -0,0 +1,104 @@ +From a63d30df718add61b1e688de90e0dbda0849941b 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 +