ProjectAres/Commons/bukkit/src/main/java/tc/oc/commons/bukkit/chat/UserTextComponent.java

70 lines
2.4 KiB
Java

package tc.oc.commons.bukkit.chat;
import java.util.Optional;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import net.md_5.bungee.api.ChatColor;
import net.md_5.bungee.api.chat.ClickEvent;
import net.md_5.bungee.api.chat.TextComponent;
import tc.oc.commons.bukkit.nick.Identity;
import tc.oc.commons.core.chat.Component;
/**
* Subclass of {@link TextComponent} used to display user-entered text.
*
* Current features:
* - Autolinking
*
* Also stores the {@link Identity} of the author, but we currently don't
* use that for anything.
*
* TODO: Possible future features include linking/decorating player names,
* masking offensive language, markdown formatting.
*/
public class UserTextComponent extends TextComponent {
// Source: http://stackoverflow.com/a/5713866/6342
private static final Pattern URL = Pattern.compile("(?:^|[\\W])(https?://|www\\.)" +
"(([\\w\\-]+\\.)+?([\\w\\-.~]+/?)*" +
"[\\p{Alnum}.,%_=?&#\\-+()\\[\\]\\*$~@!:/{};']*)",
Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
final Optional<Identity> author;
final Component rendered = new Component();
public UserTextComponent(Optional<Identity> author, String text) {
super(text);
this.author = author;
final Matcher matcher = URL.matcher(text);
int textStart = 0;
while(matcher.find()) {
final int linkStart = matcher.start(1);
final int linkEnd = matcher.end();
if(linkStart > textStart) {
rendered.extra(text.substring(textStart, linkStart));
}
final String link = text.substring(linkStart, linkEnd);
final String url = link.startsWith("http") ? link
: "http://" + link;
rendered.extra(new Component(link, ChatColor.BLUE, ChatColor.UNDERLINE).clickEvent(ClickEvent.Action.OPEN_URL, url));
textStart = linkEnd;
}
if(textStart < text.length()) {
rendered.extra(text.substring(textStart));
}
}
public UserTextComponent(Identity author, String text) {
this(Optional.of(author), text);
}
public UserTextComponent(String text) {
this(Optional.empty(), text);
}
}