Make channels default to 0, profile URL config

Fix URL not-escaping
Made the plugin only attempt to access channels that are not set to 0
#110
This commit is contained in:
Norbi Peti 2019-11-16 01:52:49 +01:00
parent 02f60c2162
commit 19463963e3
No known key found for this signature in database
GPG key ID: DBA4C4549A927E56
8 changed files with 40 additions and 18 deletions

View file

@ -18,9 +18,7 @@ import javax.annotation.Nullable;
import java.util.Comparator; import java.util.Comparator;
import java.util.Optional; import java.util.Optional;
import java.util.TreeSet; import java.util.TreeSet;
import java.util.function.Function;
import java.util.logging.Logger; import java.util.logging.Logger;
import java.util.regex.MatchResult;
import java.util.regex.Pattern; import java.util.regex.Pattern;
public final class DPUtils { public final class DPUtils {
@ -65,11 +63,19 @@ public final class DPUtils {
while (matcher.find()) while (matcher.find())
ts.add(new int[]{matcher.start(), matcher.end()}); ts.add(new int[]{matcher.start(), matcher.end()});
matcher = FORMAT_PATTERN.matcher(message); matcher = FORMAT_PATTERN.matcher(message);
Function<MatchResult, String> aFunctionalInterface = result -> /*Function<MatchResult, String> aFunctionalInterface = result ->
Optional.ofNullable(ts.floor(new int[]{result.start(), 0})).map(a -> a[1]).orElse(0) < result.start() Optional.ofNullable(ts.floor(new int[]{result.start(), 0})).map(a -> a[1]).orElse(0) < result.start()
? "\\\\" + result.group() : result.group(); ? "\\\\" + result.group() : result.group();
return matcher.replaceAll(aFunctionalInterface); //Find nearest URL match and if it's not reaching to the char then escape return matcher.replaceAll(aFunctionalInterface); //Find nearest URL match and if it's not reaching to the char then escape*/
} //TODO: Java 11 method overload, not present in Java 8 StringBuffer sb = new StringBuffer();
while (matcher.find()) {
matcher.appendReplacement(sb, Optional.ofNullable(ts.floor(new int[]{matcher.start(), 0})) //Find a URL start <= our start
.map(a -> a[1]).orElse(-1) < matcher.start() //Check if URL end < our start
? "\\\\" + matcher.group() : matcher.group());
}
matcher.appendTail(sb);
return sb.toString();
}
public static Logger getLogger() { public static Logger getLogger() {
if (DiscordPlugin.plugin == null || DiscordPlugin.plugin.getLogger() == null) if (DiscordPlugin.plugin == null || DiscordPlugin.plugin.getLogger() == null)
@ -77,8 +83,8 @@ public final class DPUtils {
return DiscordPlugin.plugin.getLogger(); return DiscordPlugin.plugin.getLogger();
} }
public static ReadOnlyConfigData<Mono<MessageChannel>> channelData(IHaveConfig config, String key, long defID) { public static ReadOnlyConfigData<Mono<MessageChannel>> channelData(IHaveConfig config, String key) {
return config.getReadOnlyDataPrimDef(key, defID, id -> getMessageChannel(key, Snowflake.of((Long) id)), ch -> defID); //We can afford to search for the channel in the cache once (instead of using mainServer) return config.getReadOnlyDataPrimDef(key, 0L, id -> getMessageChannel(key, Snowflake.of((Long) id)), ch -> 0L); //We can afford to search for the channel in the cache once (instead of using mainServer)
} }
public static ReadOnlyConfigData<Mono<Role>> roleData(IHaveConfig config, String key, String defName) { public static ReadOnlyConfigData<Mono<Role>> roleData(IHaveConfig config, String key, String defName) {
@ -169,7 +175,15 @@ public final class DPUtils {
return "<#" + channelId.asString() + ">"; return "<#" + channelId.asString() + ">";
} }
/**
* Gets a message channel for a config. Returns empty for ID 0.
*
* @param key The config key
* @param id The channel ID
* @return A message channel
*/
public static Mono<MessageChannel> getMessageChannel(String key, Snowflake id) { public static Mono<MessageChannel> getMessageChannel(String key, Snowflake id) {
if (id.asLong() == 0L) return Mono.empty();
return DiscordPlugin.dc.getChannelById(id).onErrorResume(e -> { return DiscordPlugin.dc.getChannelById(id).onErrorResume(e -> {
getLogger().warning("Failed to get channel data for " + key + "=" + id + " - " + e.getMessage()); getLogger().warning("Failed to get channel data for " + key + "=" + id + " - " + e.getMessage());
return Mono.empty(); return Mono.empty();

View file

@ -201,7 +201,7 @@ public class DiscordPlugin extends ButtonPlugin {
"Won't load because we're in testing mode and not using a separate account.", "Won't load because we're in testing mode and not using a separate account.",
new Exception( new Exception(
"The plugin refuses to load until you change the token to a testing account. (The account needs to have \"test\" in its name.)" "The plugin refuses to load until you change the token to a testing account. (The account needs to have \"test\" in its name.)"
+ "\nYou can disable test mode in ThorpeCore config.")); + "\nYou can disable test mode in ChromaCore config."));
Bukkit.getPluginManager().disablePlugin(this); Bukkit.getPluginManager().disablePlugin(this);
} }
TBMCCoreAPI.SendUnsentExceptions(); TBMCCoreAPI.SendUnsentExceptions();

View file

@ -26,14 +26,14 @@ public class AnnouncerModule extends Component<DiscordPlugin> {
* Channel to post new posts. * Channel to post new posts.
*/ */
public ReadOnlyConfigData<Mono<MessageChannel>> channel() { public ReadOnlyConfigData<Mono<MessageChannel>> channel() {
return DPUtils.channelData(getConfig(), "channel", 239519012529111040L); return DPUtils.channelData(getConfig(), "channel");
} }
/** /**
* Channel where distinguished (moderator) posts go. * Channel where distinguished (moderator) posts go.
*/ */
public ReadOnlyConfigData<Mono<MessageChannel>> modChannel() { public ReadOnlyConfigData<Mono<MessageChannel>> modChannel() {
return DPUtils.channelData(getConfig(), "modChannel", 239519012529111040L); return DPUtils.channelData(getConfig(), "modChannel");
} }
/** /**

View file

@ -85,7 +85,7 @@ public class ExceptionListenerModule extends Component<DiscordPlugin> implements
} }
private ReadOnlyConfigData<Mono<MessageChannel>> channel() { private ReadOnlyConfigData<Mono<MessageChannel>> channel() {
return DPUtils.channelData(getConfig(), "channel", 239519012529111040L); return DPUtils.channelData(getConfig(), "channel");
} }
private ConfigData<Mono<Role>> pingRole(Mono<Guild> guild) { private ConfigData<Mono<Role>> pingRole(Mono<Guild> guild) {

View file

@ -125,7 +125,7 @@ public class FunModule extends Component<DiscordPlugin> implements Listener {
private ReadOnlyConfigData<Mono<MessageChannel>> fullHouseChannel() { private ReadOnlyConfigData<Mono<MessageChannel>> fullHouseChannel() {
return DPUtils.channelData(getConfig(), "fullHouseChannel", 219626707458457603L); return DPUtils.channelData(getConfig(), "fullHouseChannel");
} }
private static long lasttime = 0; private static long lasttime = 0;

View file

@ -84,13 +84,14 @@ public class MCChatListener implements Listener {
final Consumer<EmbedCreateSpec> embed = ecs -> { final Consumer<EmbedCreateSpec> embed = ecs -> {
ecs.setDescription(e.getMessage()).setColor(new Color(color.getRed(), ecs.setDescription(e.getMessage()).setColor(new Color(color.getRed(),
color.getGreen(), color.getBlue())); color.getGreen(), color.getBlue()));
String url = module.profileURL().get();
if (e.getSender() instanceof Player) if (e.getSender() instanceof Player)
DPUtils.embedWithHead(ecs, authorPlayer, e.getSender().getName(), DPUtils.embedWithHead(ecs, authorPlayer, e.getSender().getName(),
"https://tbmcplugins.github.io/profile.html?type=minecraft&id=" url.length() > 0 ? url + "?type=minecraft&id="
+ ((Player) e.getSender()).getUniqueId()); + ((Player) e.getSender()).getUniqueId() : null);
else if (e.getSender() instanceof DiscordSenderBase) else if (e.getSender() instanceof DiscordSenderBase)
ecs.setAuthor(authorPlayer, "https://tbmcplugins.github.io/profile.html?type=discord&id=" // TODO: Constant/method to get URLs like this ecs.setAuthor(authorPlayer, url.length() > 0 ? url + "?type=discord&id="
+ ((DiscordSenderBase) e.getSender()).getUser().getId().asString(), + ((DiscordSenderBase) e.getSender()).getUser().getId().asString() : null,
((DiscordSenderBase) e.getSender()).getUser().getAvatarUrl()); ((DiscordSenderBase) e.getSender()).getUser().getAvatarUrl());
else else
DPUtils.embedWithHead(ecs, authorPlayer, e.getSender().getName(), null); DPUtils.embedWithHead(ecs, authorPlayer, e.getSender().getName(), null);

View file

@ -58,7 +58,7 @@ public class MinecraftChatModule extends Component<DiscordPlugin> {
* The channel where the plugin can log when it mutes a player on Discord because of a Minecraft mute * The channel where the plugin can log when it mutes a player on Discord because of a Minecraft mute
*/ */
public ReadOnlyConfigData<Mono<MessageChannel>> modlogChannel() { public ReadOnlyConfigData<Mono<MessageChannel>> modlogChannel() {
return DPUtils.channelData(getConfig(), "modlogChannel", 283840717275791360L); return DPUtils.channelData(getConfig(), "modlogChannel");
} }
/** /**
@ -104,6 +104,13 @@ public class MinecraftChatModule extends Component<DiscordPlugin> {
return getConfig().getData("allowPrivateChat", true); return getConfig().getData("allowPrivateChat", true);
} }
/**
* If set, message authors appearing on Discord will link to this URL. A 'type' and 'id' parameter will be added with the user's platform (Discord, Minecraft, ...) and ID.
*/
public ConfigData<String> profileURL() {
return getConfig().getData("profileURL", "");
}
@Override @Override
protected void enable() { protected void enable() {
if (DPUtils.disableIfConfigErrorRes(this, chatChannel(), chatChannelMono())) if (DPUtils.disableIfConfigErrorRes(this, chatChannel(), chatChannelMono()))

View file

@ -36,7 +36,7 @@ public class GameRoleModule extends Component<DiscordPlugin> {
} }
private ReadOnlyConfigData<Mono<MessageChannel>> logChannel() { private ReadOnlyConfigData<Mono<MessageChannel>> logChannel() {
return DPUtils.channelData(getConfig(), "logChannel", 239519012529111040L); return DPUtils.channelData(getConfig(), "logChannel");
} }
public static void handleRoleEvent(RoleEvent roleEvent) { public static void handleRoleEvent(RoleEvent roleEvent) {