Updated to Discord4J v3, permission injection, improvements #99

Merged
NorbiPeti merged 25 commits from dev into master 2019-06-06 20:45:22 +00:00
7 changed files with 88 additions and 70 deletions
Showing only changes of commit 4881f6bdd2 - Show all commits

View file

@ -46,7 +46,7 @@ public final class DPUtils {
return sanitizedString.toString();
}
public static String escape(String message) {
private static String escape(String message) {
return message.replaceAll("([*_~])", Matcher.quoteReplacement("\\") + "$1");
}
@ -69,15 +69,18 @@ public final class DPUtils {
}, ch -> ch.getId().asLong()); //We can afford to search for the channel in the cache once (instead of using mainServer)
}
public static ConfigData<Role> roleData(IHaveConfig config, String key, String defName) {
return roleData(config, key, defName, DiscordPlugin.mainServer);
public static ConfigData<Mono<Role>> roleData(IHaveConfig config, String key, String defName) {
return roleData(config, key, defName, Mono.just(DiscordPlugin.mainServer));
}
public static ConfigData<Role> roleData(IHaveConfig config, String key, String defName, Guild guild) {
/**
* Needs to be a {@link ConfigData} for checking if it's set
*/
public static ConfigData<Mono<Role>> roleData(IHaveConfig config, String key, String defName, Mono<Guild> guild) {
return config.getDataPrimDef(key, defName, name -> {
if (!(name instanceof String)) return null;
return guild.getRoles().filter(r -> r.getName().equals(name)).blockFirst();
}, r -> r.getId().asLong());
if (!(name instanceof String)) return Mono.empty();
return guild.flatMapMany(Guild::getRoles).filter(r -> r.getName().equals(name)).last();
}, r -> defName);
}
/**

View file

@ -16,6 +16,7 @@ import buttondevteam.lib.TBMCCoreAPI;
import buttondevteam.lib.architecture.ButtonPlugin;
import buttondevteam.lib.architecture.Component;
import buttondevteam.lib.architecture.ConfigData;
import buttondevteam.lib.architecture.IHaveConfig;
import buttondevteam.lib.player.ChromaGamerBase;
import com.google.common.io.Files;
import discord4j.core.DiscordClient;
@ -36,16 +37,17 @@ import org.bukkit.Bukkit;
import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.entity.Player;
import org.bukkit.plugin.RegisteredServiceProvider;
import reactor.core.publisher.Mono;
import java.awt.*;
import java.io.File;
import java.nio.charset.StandardCharsets;
import java.time.Duration;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.stream.Collectors;
@ButtonPlugin.ConfigOpts(disableConfigGen = true)
public class DiscordPlugin extends ButtonPlugin {
public static DiscordClient dc;
public static DiscordPlugin plugin;
@ -53,7 +55,7 @@ public class DiscordPlugin extends ButtonPlugin {
@Getter
private Command2DC manager;
public ConfigData<Character> Prefix() {
private ConfigData<Character> Prefix() {
return getIConfig().getData("prefix", '/', str -> ((String) str).charAt(0), Object::toString);
}
@ -62,7 +64,7 @@ public class DiscordPlugin extends ButtonPlugin {
return plugin.Prefix().get();
}
public ConfigData<Guild> MainServer() {
private ConfigData<Guild> MainServer() {
return getIConfig().getDataPrimDef("mainServer", 219529124321034241L, id -> dc.getGuildById(Snowflake.of((long) id)).block(), g -> g.getId().asLong());
}
@ -70,7 +72,7 @@ public class DiscordPlugin extends ButtonPlugin {
return DPUtils.channelData(getIConfig(), "commandChannel", 239519012529111040L);
}
public ConfigData<Role> ModRole() {
public ConfigData<Mono<Role>> ModRole() {
return DPUtils.roleData(getIConfig(), "modRole", "Moderator");
}
@ -193,6 +195,8 @@ public class DiscordPlugin extends ButtonPlugin {
ChromaGamerBase.addConverter(sender -> Optional.ofNullable(sender instanceof DiscordSenderBase
? ((DiscordSenderBase) sender).getChromaUser() : null));
setupProviders();
IHaveConfig.pregenConfig(this, null);
} catch (Exception e) {
TBMCCoreAPI.SendException("An error occured while enabling DiscordPlugin!", e);
}
@ -220,7 +224,7 @@ public class DiscordPlugin extends ButtonPlugin {
+ (Bukkit.getOnlinePlayers().size() == 1 ? " was " : " were ")
+ "kicked the hell out.") //TODO: Make configurable
: ""); //If 'restart' is disabled then this isn't shown even if joinleave is enabled
}).block(Duration.ofSeconds(5)), ChannelconBroadcast.RESTART, false);
}).block(), ChannelconBroadcast.RESTART, false);
ChromaBot.getInstance().updatePlayerList();
}

View file

@ -3,6 +3,8 @@ package buttondevteam.discordplugin.commands;
import buttondevteam.discordplugin.DiscordPlugin;
import buttondevteam.lib.chat.Command2;
import java.lang.reflect.Method;
public class Command2DC extends Command2<ICommand2DC, Command2DCSender> {
@Override
public void registerCommand(ICommand2DC command) {
@ -10,7 +12,7 @@ public class Command2DC extends Command2<ICommand2DC, Command2DCSender> {
}
@Override
public boolean hasPermission(Command2DCSender sender, ICommand2DC command) {
public boolean hasPermission(Command2DCSender sender, ICommand2DC command, Method method) {
//return !command.isModOnly() || sender.getMessage().getAuthor().hasRole(DiscordPlugin.plugin.ModRole().get()); //TODO: ModRole may be null; more customisable way?
return true;
}

View file

@ -12,7 +12,8 @@ public class DebugCommand extends ICommand2DC {
@Command2.Subcommand
public boolean def(Command2DCSender sender, String args) {
sender.getMessage().getAuthorAsMember()
.map(m -> m.getRoleIds().stream().anyMatch(r -> r.equals(DiscordPlugin.plugin.ModRole().get().getId())))
.flatMap(m -> DiscordPlugin.plugin.ModRole().get()
.map(mr -> m.getRoleIds().stream().anyMatch(r -> r.equals(mr.getId()))))
.subscribe(success -> {
if (success)
sender.sendMessage("debug " + (CommonListeners.debug() ? "enabled" : "disabled"));

View file

@ -15,6 +15,7 @@ import org.apache.commons.lang.exception.ExceptionUtils;
import org.bukkit.Bukkit;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import reactor.core.publisher.Mono;
import java.util.ArrayList;
import java.util.Arrays;
@ -22,51 +23,58 @@ import java.util.List;
import java.util.stream.Collectors;
public class ExceptionListenerModule extends Component<DiscordPlugin> implements Listener {
private List<Throwable> lastthrown = new ArrayList<>();
private List<String> lastsourcemsg = new ArrayList<>();
private List<Throwable> lastthrown = new ArrayList<>();
private List<String> lastsourcemsg = new ArrayList<>();
@EventHandler
public void onException(TBMCExceptionEvent e) {
if (DiscordPlugin.SafeMode || !ComponentManager.isEnabled(getClass()))
return;
if (lastthrown.stream()
.anyMatch(ex -> Arrays.equals(e.getException().getStackTrace(), ex.getStackTrace())
&& (e.getException().getMessage() == null ? ex.getMessage() == null
: e.getException().getMessage().equals(ex.getMessage()))) // e.Exception.Message==ex.Message
&& lastsourcemsg.contains(e.getSourceMessage()))
return;
SendException(e.getException(), e.getSourceMessage());
if (lastthrown.size() >= 10)
lastthrown.remove(0);
if (lastsourcemsg.size() >= 10)
lastsourcemsg.remove(0);
lastthrown.add(e.getException());
lastsourcemsg.add(e.getSourceMessage());
e.setHandled();
}
@EventHandler
public void onException(TBMCExceptionEvent e) {
if (DiscordPlugin.SafeMode || !ComponentManager.isEnabled(getClass()))
return;
if (lastthrown.stream()
.anyMatch(ex -> Arrays.equals(e.getException().getStackTrace(), ex.getStackTrace())
&& (e.getException().getMessage() == null ? ex.getMessage() == null
: e.getException().getMessage().equals(ex.getMessage()))) // e.Exception.Message==ex.Message
&& lastsourcemsg.contains(e.getSourceMessage()))
return;
SendException(e.getException(), e.getSourceMessage());
if (lastthrown.size() >= 10)
lastthrown.remove(0);
if (lastsourcemsg.size() >= 10)
lastsourcemsg.remove(0);
lastthrown.add(e.getException());
lastsourcemsg.add(e.getSourceMessage());
e.setHandled();
}
private static void SendException(Throwable e, String sourcemessage) {
private static void SendException(Throwable e, String sourcemessage) {
if (instance == null) return;
try {
try {
MessageChannel channel = getChannel();
assert channel != null;
Role coderRole = instance.pingRole(((GuildChannel) channel).getGuild().block()).get();
StringBuilder sb = TBMCCoreAPI.IsTestServer() ? new StringBuilder()
: new StringBuilder(coderRole == null ? "" : coderRole.getMention()).append("\n");
sb.append(sourcemessage).append("\n");
sb.append("```").append("\n");
String stackTrace = Arrays.stream(ExceptionUtils.getStackTrace(e).split("\\n"))
.filter(s -> !s.contains("\tat ") || s.contains("\tat buttondevteam."))
.collect(Collectors.joining("\n"));
if (sb.length() + stackTrace.length() >= 2000)
stackTrace = stackTrace.substring(0, 1999 - sb.length());
sb.append(stackTrace).append("\n");
sb.append("```");
channel.createMessage(sb.toString()).subscribe();
} catch (Exception ex) {
ex.printStackTrace();
}
}
assert channel != null;
Mono<Role> coderRole;
if (channel instanceof GuildChannel)
coderRole = instance.pingRole(((GuildChannel) channel).getGuild()).get();
else
coderRole = Mono.empty();
coderRole.map(role -> TBMCCoreAPI.IsTestServer() ? new StringBuilder()
: new StringBuilder(role.getMention()).append("\n"))
.defaultIfEmpty(new StringBuilder())
.flatMap(sb -> {
sb.append(sourcemessage).append("\n");
sb.append("```").append("\n");
String stackTrace = Arrays.stream(ExceptionUtils.getStackTrace(e).split("\\n"))
.filter(s -> !s.contains("\tat ") || s.contains("\tat buttondevteam."))
.collect(Collectors.joining("\n"));
if (sb.length() + stackTrace.length() >= 2000)
stackTrace = stackTrace.substring(0, 1999 - sb.length());
sb.append(stackTrace).append("\n");
sb.append("```");
return channel.createMessage(sb.toString());
}).subscribe();
} catch (Exception ex) {
ex.printStackTrace();
}
}
private static ExceptionListenerModule instance;
@ -79,7 +87,7 @@ public class ExceptionListenerModule extends Component<DiscordPlugin> implements
return DPUtils.channelData(getConfig(), "channel", 239519012529111040L);
}
private ConfigData<Role> pingRole(Guild guild) {
private ConfigData<Mono<Role>> pingRole(Mono<Guild> guild) {
return DPUtils.roleData(getConfig(), "pingRole", "Coder", guild);
}

View file

@ -15,6 +15,7 @@ import org.bukkit.Bukkit;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerJoinEvent;
import reactor.core.publisher.Mono;
import java.util.ArrayList;
import java.util.Arrays;
@ -114,7 +115,7 @@ public class FunModule extends Component<DiscordPlugin> implements Listener {
ListC = 0;
}
private ConfigData<Role> fullHouseDevRole(Guild guild) {
private ConfigData<Mono<Role>> fullHouseDevRole(Mono<Guild> guild) {
return DPUtils.roleData(getConfig(), "fullHouseDevRole", "Developer", guild);
}
@ -131,20 +132,21 @@ public class FunModule extends Component<DiscordPlugin> implements Listener {
if (fm == null) return;
val channel = fm.fullHouseChannel().get();
if (channel == null) return;
val devrole = fm.fullHouseDevRole(((GuildChannel) channel).getGuild().block()).get();
if (!(channel instanceof GuildChannel)) return;
val devrole = fm.fullHouseDevRole(((GuildChannel) channel).getGuild()).get();
if (devrole == null) return;
if (event.getOld().map(p -> p.getStatus().equals(Status.OFFLINE)).orElse(false)
&& !event.getCurrent().getStatus().equals(Status.OFFLINE)
&& event.getMember().flatMap(m -> m.getRoles()
.any(r -> r.getId().asLong() == devrole.getId().asLong())).block()
&& event.getGuild().flatMap(g -> g.getMembers().filter(m -> m.getRoleIds().stream().anyMatch(s -> s.equals(devrole.getId())))
&& event.getMember().flatMap(m -> devrole.flatMap(dr -> m.getRoles()
.any(r -> r.getId().asLong() == dr.getId().asLong()))).block()
&& event.getGuild().flatMap(g -> devrole.flatMapMany(dr -> g.getMembers().filter(m -> m.getRoleIds().stream().anyMatch(s -> s.equals(dr.getId()))))
.flatMap(Member::getPresence).all(pr -> !pr.getStatus().equals(Status.OFFLINE))).block()
&& lasttime + 10 < TimeUnit.NANOSECONDS.toHours(System.nanoTime())
&& Calendar.getInstance().get(Calendar.DAY_OF_MONTH) % 5 == 0) {
channel.createMessage(mcs -> mcs.setContent("Full house!").setEmbed(ecs ->
ecs.setImage(
"https://cdn.discordapp.com/attachments/249295547263877121/249687682618359808/poker-hand-full-house-aces-kings-playing-cards-15553791.png")
));
)).subscribe();
lasttime = TimeUnit.NANOSECONDS.toHours(System.nanoTime());
}
}

View file

@ -1,13 +1,11 @@
package buttondevteam.discordplugin.mcchat;
import buttondevteam.discordplugin.*;
import buttondevteam.lib.TBMCCoreAPI;
import buttondevteam.lib.TBMCSystemChatEvent;
import buttondevteam.lib.architecture.ConfigData;
import buttondevteam.lib.player.*;
import com.earth2me.essentials.CommandSource;
import discord4j.core.object.entity.Role;
import discord4j.core.object.entity.User;
import discord4j.core.object.util.Snowflake;
import lombok.RequiredArgsConstructor;
import lombok.val;
@ -101,13 +99,13 @@ class MCListener implements Listener {
MCChatUtils.forAllowedCustomAndAllMCChat(MCChatUtils.send(msg), base, ChannelconBroadcast.AFK, false);
}
private ConfigData<Role> muteRole() {
private ConfigData<Mono<Role>> muteRole() {
return DPUtils.roleData(module.getConfig(), "muteRole", "Muted");
}
@EventHandler
public void onPlayerMute(MuteStatusChangeEvent e) {
final Role role = muteRole().get();
final Mono<Role> role = muteRole().get();
if (role == null) return;
final CommandSource source = e.getAffected().getSource();
if (!source.isPlayer())
@ -117,18 +115,18 @@ class MCListener implements Listener {
if (p == null) return;
DiscordPlugin.dc.getUserById(Snowflake.of(p.getDiscordID()))
.flatMap(user -> user.asMember(DiscordPlugin.mainServer.getId()))
.flatMap(user -> {
.flatMap(user -> role.flatMap(r -> {
if (e.getValue())
user.addRole(role.getId());
user.addRole(r.getId());
else
user.removeRole(role.getId());
user.removeRole(r.getId());
val modlog = module.modlogChannel().get();
String msg = (e.getValue() ? "M" : "Unm") + "uted user: " + user.getUsername() + "#" + user.getDiscriminator();
DPUtils.getLogger().info(msg);
if (modlog != null)
return modlog.createMessage(msg);
return Mono.empty();
}).subscribe();
})).subscribe();
}
@EventHandler