Using modules more & calling preprocess event

Calling the command preprocess event
Added to FunModule (/list, full house)
Made whitelisted commands and other stuff configurable
Game role module
Name change
#51
This commit is contained in:
Norbi Peti 2019-01-28 23:21:17 +01:00
parent 5c7100bb69
commit 7c15495fab
No known key found for this signature in database
GPG key ID: DBA4C4549A927E56
10 changed files with 327 additions and 252 deletions

View file

@ -5,6 +5,7 @@ import buttondevteam.lib.architecture.IHaveConfig;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import sx.blah.discord.handle.obj.IChannel; import sx.blah.discord.handle.obj.IChannel;
import sx.blah.discord.handle.obj.IIDLinkedObject; import sx.blah.discord.handle.obj.IIDLinkedObject;
import sx.blah.discord.handle.obj.IRole;
import sx.blah.discord.util.EmbedBuilder; import sx.blah.discord.util.EmbedBuilder;
import sx.blah.discord.util.RequestBuffer; import sx.blah.discord.util.RequestBuffer;
import sx.blah.discord.util.RequestBuffer.IRequest; import sx.blah.discord.util.RequestBuffer.IRequest;
@ -111,6 +112,10 @@ public final class DPUtils {
return config.getDataPrimDef(key, defID, id -> DiscordPlugin.dc.getChannelByID((long) id), IIDLinkedObject::getLongID); //We can afford to search for the channel in the cache once (instead of using mainServer) return config.getDataPrimDef(key, defID, id -> DiscordPlugin.dc.getChannelByID((long) id), IIDLinkedObject::getLongID); //We can afford to search for the channel in the cache once (instead of using mainServer)
} }
public static ConfigData<IRole> roleData(IHaveConfig config, String key, long defID) {
return config.getDataPrimDef(key, defID, id -> DiscordPlugin.dc.getRoleByID((long) id), IIDLinkedObject::getLongID); //We can afford to search for the channel in the cache once (instead of using mainServer)
}
/** /**
* Mentions the <b>bot channel</b>. Useful for help texts. * Mentions the <b>bot channel</b>. Useful for help texts.
* *

View file

@ -1,59 +1,62 @@
package buttondevteam.discordplugin.commands; package buttondevteam.discordplugin.commands;
import buttondevteam.discordplugin.DiscordPlugin; import buttondevteam.discordplugin.DiscordPlugin;
import buttondevteam.discordplugin.mcchat.MCChatCommand; import buttondevteam.discordplugin.mcchat.MCChatCommand;
import buttondevteam.lib.TBMCCoreAPI; import buttondevteam.lib.TBMCCoreAPI;
import sx.blah.discord.handle.obj.IMessage; import sx.blah.discord.handle.obj.IMessage;
import java.util.Arrays; import java.util.Arrays;
import java.util.HashMap; import java.util.HashMap;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import static buttondevteam.discordplugin.listeners.CommonListeners.debug; import static buttondevteam.discordplugin.listeners.CommonListeners.debug;
public abstract class DiscordCommandBase { public abstract class DiscordCommandBase {
public abstract String getCommandName(); public abstract String getCommandName();
public abstract boolean run(IMessage message, String args); public abstract boolean run(IMessage message, String args);
public abstract String[] getHelpText(); public abstract String[] getHelpText();
static final HashMap<String, DiscordCommandBase> commands = new HashMap<String, DiscordCommandBase>(); static final HashMap<String, DiscordCommandBase> commands = new HashMap<String, DiscordCommandBase>();
public static void registerCommands() { public static void registerCommands() {
commands.put("connect", new ConnectCommand()); // TODO: API for adding commands? commands.put("connect", new ConnectCommand()); // TODO: API for adding commands?
commands.put("userinfo", new UserinfoCommand()); commands.put("userinfo", new UserinfoCommand());
commands.put("help", new HelpCommand()); commands.put("help", new HelpCommand());
commands.put("role", new RoleCommand()); commands.put("mcchat", new MCChatCommand());
commands.put("mcchat", new MCChatCommand()); commands.put("channelcon", new ChannelconCommand());
commands.put("channelcon", new ChannelconCommand()); commands.put("debug", new DebugCommand());
commands.put("debug", new DebugCommand()); commands.put("version", new VersionCommand());
commands.put("version", new VersionCommand()); }
}
public static void runCommand(String cmd, String args, IMessage message) {
public static void runCommand(String cmd, String args, IMessage message) { debug("F"); //Not sure if needed
debug("F"); //Not sure if needed DiscordCommandBase command = commands.get(cmd);
DiscordCommandBase command = commands.get(cmd); if (command == null) {
if (command == null) { DiscordPlugin.sendMessageToChannel(message.getChannel(),
DiscordPlugin.sendMessageToChannel(message.getChannel(), "Unknown command: " + cmd + " with args: " + args + "\nDo '"
"Unknown command: " + cmd + " with args: " + args + "\nDo '" + (message.getChannel().isPrivate() ? "" : message.getClient().getOurUser().mention() + " ")
+ (message.getChannel().isPrivate() ? "" : message.getClient().getOurUser().mention() + " ") + "help' for help");
+ "help' for help"); return;
return; }
} debug("G");
debug("G"); try {
try { if (!command.run(message, args))
if (!command.run(message, args)) DiscordPlugin.sendMessageToChannel(message.getChannel(), Arrays.stream(command.getHelpText()).collect(Collectors.joining("\n")));
DiscordPlugin.sendMessageToChannel(message.getChannel(), Arrays.stream(command.getHelpText()).collect(Collectors.joining("\n"))); } catch (Exception e) {
} catch (Exception e) { TBMCCoreAPI.SendException("An error occured while executing command " + cmd + "!", e);
TBMCCoreAPI.SendException("An error occured while executing command " + cmd + "!", e); DiscordPlugin.sendMessageToChannel(message.getChannel(),
DiscordPlugin.sendMessageToChannel(message.getChannel(), "An internal error occured while executing this command. For more technical details see the server-issues channel on the dev Discord.");
"An internal error occured while executing this command. For more technical details see the server-issues channel on the dev Discord."); }
} debug("H");
debug("H"); }
}
protected String[] splitargs(String args) {
protected String[] splitargs(String args) { return args.split("\\s+");
return args.split("\\s+"); }
}
} public static void registerCommand(String name, DiscordCommandBase dcb) {
commands.put(name, dcb);
}
}

View file

@ -5,14 +5,26 @@ import buttondevteam.discordplugin.DiscordPlugin;
import buttondevteam.lib.TBMCCoreAPI; import buttondevteam.lib.TBMCCoreAPI;
import buttondevteam.lib.architecture.Component; import buttondevteam.lib.architecture.Component;
import buttondevteam.lib.architecture.ConfigData; import buttondevteam.lib.architecture.ConfigData;
import com.google.common.collect.Lists;
import lombok.val;
import org.bukkit.Bukkit;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerJoinEvent;
import sx.blah.discord.handle.impl.events.user.PresenceUpdateEvent;
import sx.blah.discord.handle.obj.IMessage; import sx.blah.discord.handle.obj.IMessage;
import sx.blah.discord.handle.obj.IRole;
import sx.blah.discord.handle.obj.StatusType;
import sx.blah.discord.util.EmbedBuilder;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.List; import java.util.Calendar;
import java.util.Random; import java.util.Random;
import java.util.concurrent.TimeUnit;
import java.util.stream.IntStream;
public class FunModule extends Component { public class FunModule extends Component implements Listener {
private static FunModule mod; private static FunModule mod;
private static final String[] serverReadyStrings = new String[]{"In one week from now", // Ali private static final String[] serverReadyStrings = new String[]{"In one week from now", // Ali
@ -35,9 +47,8 @@ public class FunModule extends Component {
return getConfig().getData("serverReady", true); return getConfig().getData("serverReady", true);
} }
private ConfigData<List<String>> serverReadyAnswers() { private ConfigData<ArrayList<String>> serverReadyAnswers() {
return getConfig().getData("serverReadyAnswers", Arrays.asList(serverReadyStrings), return getConfig().getData("serverReadyAnswers", () -> Lists.newArrayList(serverReadyStrings)); //TODO: Test
data -> (List<String>) data, data -> data); //TODO: Test
} }
private static final String[] serverReadyQuestions = new String[]{"when will the server be open", private static final String[] serverReadyQuestions = new String[]{"when will the server be open",
@ -46,41 +57,93 @@ public class FunModule extends Component {
"Vhen vill ze server be open?"}; "Vhen vill ze server be open?"};
private static final Random serverReadyRandom = new Random(); private static final Random serverReadyRandom = new Random();
private static final ArrayList<Short> usableServerReadyStrings = new ArrayList<Short>(serverReadyStrings.length) { private static final ArrayList<Short> usableServerReadyStrings = new ArrayList<>(0);
private static final long serialVersionUID = 2213771460909848770L;
{ private void createUsableServerReadyStrings() {
createUsableServerReadyStrings(this); IntStream.range(0, serverReadyAnswers().get().size())
} .forEach(i -> FunModule.usableServerReadyStrings.add((short) i));
};
private static void createUsableServerReadyStrings(ArrayList<Short> list) {
for (short i = 0; i < serverReadyStrings.length; i++)
list.add(i);
} }
@Override @Override
protected void enable() { protected void enable() {
mod = this; mod = this;
registerListener(this);
} }
@Override @Override
protected void disable() { protected void disable() {
lastlist = lastlistp = ListC = 0;
} }
private static short lastlist = 0;
private static short lastlistp = 0;
private static short ListC = 0;
public static boolean executeMemes(IMessage message) { public static boolean executeMemes(IMessage message) {
if (!ComponentManager.isEnabled(FunModule.class)) return false; val fm = ComponentManager.getIfEnabled(FunModule.class);
if (fm == null) return false;
String msglowercased = message.getContent().toLowerCase();
lastlist++;
if (lastlist > 5) {
ListC = 0;
lastlist = 0;
}
if (msglowercased.equals("list") && Bukkit.getOnlinePlayers().size() == lastlistp && ListC++ > 2) // Lowered already
{
message.reply("Stop it. You know the answer.");
lastlist = 0;
lastlistp = (short) Bukkit.getOnlinePlayers().size();
return true; //Handled
}
lastlistp = (short) Bukkit.getOnlinePlayers().size(); //Didn't handle
if (mod.serverReady().get()) { if (mod.serverReady().get()) {
if (!TBMCCoreAPI.IsTestServer() if (!TBMCCoreAPI.IsTestServer()
&& Arrays.stream(serverReadyQuestions).anyMatch(s -> message.getContent().toLowerCase().contains(s))) { && Arrays.stream(serverReadyQuestions).anyMatch(msglowercased::contains)) {
int next; int next;
if (usableServerReadyStrings.size() == 0) if (usableServerReadyStrings.size() == 0)
createUsableServerReadyStrings(usableServerReadyStrings); fm.createUsableServerReadyStrings();
next = usableServerReadyStrings.remove(serverReadyRandom.nextInt(usableServerReadyStrings.size())); next = usableServerReadyStrings.remove(serverReadyRandom.nextInt(usableServerReadyStrings.size()));
DiscordPlugin.sendMessageToChannel(message.getChannel(), serverReadyStrings[next]); DiscordPlugin.sendMessageToChannel(message.getChannel(), serverReadyStrings[next]);
return true; return false; //Still process it as a command/mcchat if needed
} }
} }
return false; return false;
} }
@EventHandler
public void onPlayerJoin(PlayerJoinEvent event) {
ListC = 0;
}
private ConfigData<IRole> fullHouseDevRole() {
return getConfig().getDataPrimDef("fullHouseDevRole", "Developer", name -> {
val list = DiscordPlugin.devServer.getRolesByName((String) name);
return list.size() > 0 ? list.get(0) : null;
}, IRole::getName);
}
private static long lasttime = 0;
public static void handleFullHouse(PresenceUpdateEvent event) {
val fm = ComponentManager.getIfEnabled(FunModule.class);
if (fm == null) return;
val devrole = fm.fullHouseDevRole().get();
if (devrole == null) return;
if (event.getOldPresence().getStatus().equals(StatusType.OFFLINE)
&& !event.getNewPresence().getStatus().equals(StatusType.OFFLINE)
&& event.getUser().getRolesForGuild(DiscordPlugin.devServer).stream()
.anyMatch(r -> r.getLongID() == devrole.getLongID())
&& DiscordPlugin.devServer.getUsersByRole(devrole).stream()
.noneMatch(u -> u.getPresence().getStatus().equals(StatusType.OFFLINE))
&& lasttime + 10 < TimeUnit.NANOSECONDS.toHours(System.nanoTime())
&& Calendar.getInstance().get(Calendar.DAY_OF_MONTH) % 5 == 0) {
DiscordPlugin.sendMessageToChannel(DiscordPlugin.devofficechannel, "Full house!",
new EmbedBuilder()
.withImage(
"https://cdn.discordapp.com/attachments/249295547263877121/249687682618359808/poker-hand-full-house-aces-kings-playing-cards-15553791.png")
.build());
lasttime = TimeUnit.NANOSECONDS.toHours(System.nanoTime());
}
}
} }

View file

@ -2,42 +2,20 @@ package buttondevteam.discordplugin.listeners;
import buttondevteam.discordplugin.DPUtils; import buttondevteam.discordplugin.DPUtils;
import buttondevteam.discordplugin.DiscordPlugin; import buttondevteam.discordplugin.DiscordPlugin;
import buttondevteam.discordplugin.fun.FunModule;
import buttondevteam.discordplugin.mcchat.MinecraftChatModule; import buttondevteam.discordplugin.mcchat.MinecraftChatModule;
import buttondevteam.discordplugin.role.GameRoleModule;
import buttondevteam.lib.architecture.Component; import buttondevteam.lib.architecture.Component;
import lombok.val; import lombok.val;
import org.bukkit.Bukkit;
import sx.blah.discord.api.events.IListener; import sx.blah.discord.api.events.IListener;
import sx.blah.discord.handle.impl.events.guild.channel.message.MessageReceivedEvent; import sx.blah.discord.handle.impl.events.guild.channel.message.MessageReceivedEvent;
import sx.blah.discord.handle.impl.events.guild.role.RoleCreateEvent; import sx.blah.discord.handle.impl.events.guild.role.RoleCreateEvent;
import sx.blah.discord.handle.impl.events.guild.role.RoleDeleteEvent; import sx.blah.discord.handle.impl.events.guild.role.RoleDeleteEvent;
import sx.blah.discord.handle.impl.events.guild.role.RoleUpdateEvent; import sx.blah.discord.handle.impl.events.guild.role.RoleUpdateEvent;
import sx.blah.discord.handle.impl.events.user.PresenceUpdateEvent; import sx.blah.discord.handle.impl.events.user.PresenceUpdateEvent;
import sx.blah.discord.handle.obj.StatusType;
import sx.blah.discord.util.EmbedBuilder;
import java.util.Calendar;
import java.util.concurrent.TimeUnit;
public class CommonListeners { public class CommonListeners {
/*private static ArrayList<Object> dcListeners=new ArrayList<>();
public static void registerDiscordListener(DiscordListener listener) {
//Step 1: Get all events that are handled by us
//Step 2: Find methods that handle these
//...or just simply call the methods in the right order
}
private static void callDiscordEvent(Event event) {
String name=event.getClass().getSimpleName();
name=Character.toLowerCase(name.charAt(0))+name.substring(1);
for (Object listener : dcListeners) {
listener.getClass().getMethods(name, AsyncDiscordEvent.class);
}
}*/
private static long lasttime = 0;
/* /*
MentionEvent: MentionEvent:
- CommandListener (starts with mention, only 'channelcon' and not in #bot) - CommandListener (starts with mention, only 'channelcon' and not in #bot)
@ -55,6 +33,8 @@ public class CommonListeners {
return; return;
if (event.getMessage().getAuthor().isBot()) if (event.getMessage().getAuthor().isBot())
return; return;
if (FunModule.executeMemes(event.getMessage()))
return;
boolean handled = false; boolean handled = false;
if (event.getChannel().getLongID() == DiscordPlugin.plugin.CommandChannel().get().getLongID() //If mentioned, that's higher than chat if (event.getChannel().getLongID() == DiscordPlugin.plugin.CommandChannel().get().getLongID() //If mentioned, that's higher than chat
|| event.getMessage().getContent().contains("channelcon")) //Only 'channelcon' is allowed in other channels || event.getMessage().getContent().contains("channelcon")) //Only 'channelcon' is allowed in other channels
@ -71,48 +51,11 @@ public class CommonListeners {
public void handle(PresenceUpdateEvent event) { public void handle(PresenceUpdateEvent event) {
if (DiscordPlugin.SafeMode) if (DiscordPlugin.SafeMode)
return; return;
val devrole = DiscordPlugin.devServer.getRolesByName("Developer").get(0); FunModule.handleFullHouse(event);
if (event.getOldPresence().getStatus().equals(StatusType.OFFLINE)
&& !event.getNewPresence().getStatus().equals(StatusType.OFFLINE)
&& event.getUser().getRolesForGuild(DiscordPlugin.devServer).stream()
.anyMatch(r -> r.getLongID() == devrole.getLongID())
&& DiscordPlugin.devServer.getUsersByRole(devrole).stream()
.noneMatch(u -> u.getPresence().getStatus().equals(StatusType.OFFLINE))
&& lasttime + 10 < TimeUnit.NANOSECONDS.toHours(System.nanoTime())
&& Calendar.getInstance().get(Calendar.DAY_OF_MONTH) % 5 == 0) {
DiscordPlugin.sendMessageToChannel(DiscordPlugin.devofficechannel, "Full house!",
new EmbedBuilder()
.withImage(
"https://cdn.discordapp.com/attachments/249295547263877121/249687682618359808/poker-hand-full-house-aces-kings-playing-cards-15553791.png")
.build());
lasttime = TimeUnit.NANOSECONDS.toHours(System.nanoTime());
}
} }
}, (IListener<RoleCreateEvent>) event -> { }, (IListener<RoleCreateEvent>) GameRoleModule::handleRoleEvent, //
Bukkit.getScheduler().runTaskLaterAsynchronously(DiscordPlugin.plugin, () -> { (IListener<RoleDeleteEvent>) GameRoleModule::handleRoleEvent, //
if (event.getRole().isDeleted() || !DiscordPlugin.plugin.isGameRole(event.getRole())) (IListener<RoleUpdateEvent>) GameRoleModule::handleRoleEvent};
return; //Deleted or not a game role
DiscordPlugin.GameRoles.add(event.getRole().getName());
DiscordPlugin.sendMessageToChannel(DiscordPlugin.modlogchannel, "Added " + event.getRole().getName() + " as game role. If you don't want this, change the role's color from the default.");
}, 100);
}, (IListener<RoleDeleteEvent>) event -> {
if (DiscordPlugin.GameRoles.remove(event.getRole().getName()))
DiscordPlugin.sendMessageToChannel(DiscordPlugin.modlogchannel, "Removed " + event.getRole().getName() + " as a game role.");
}, (IListener<RoleUpdateEvent>) event -> { //Role update event
if (!DiscordPlugin.plugin.isGameRole(event.getNewRole())) {
if (DiscordPlugin.GameRoles.remove(event.getOldRole().getName()))
DiscordPlugin.sendMessageToChannel(DiscordPlugin.modlogchannel, "Removed " + event.getOldRole().getName() + " as a game role because it's color changed.");
} else {
if (DiscordPlugin.GameRoles.contains(event.getOldRole().getName()) && event.getOldRole().getName().equals(event.getNewRole().getName()))
return;
boolean removed = DiscordPlugin.GameRoles.remove(event.getOldRole().getName()); //Regardless of whether it was a game role
DiscordPlugin.GameRoles.add(event.getNewRole().getName()); //Add it because it has no color
if (removed)
DiscordPlugin.sendMessageToChannel(DiscordPlugin.modlogchannel, "Changed game role from " + event.getOldRole().getName() + " to " + event.getNewRole().getName() + ".");
else
DiscordPlugin.sendMessageToChannel(DiscordPlugin.modlogchannel, "Added " + event.getNewRole().getName() + " as game role because it has the default color.");
}
}};
} }
private static boolean debug = false; private static boolean debug = false;

View file

@ -11,6 +11,7 @@ import buttondevteam.discordplugin.listeners.CommandListener;
import buttondevteam.discordplugin.playerfaker.VanillaCommandListener; import buttondevteam.discordplugin.playerfaker.VanillaCommandListener;
import buttondevteam.lib.TBMCChatEvent; import buttondevteam.lib.TBMCChatEvent;
import buttondevteam.lib.TBMCChatPreprocessEvent; import buttondevteam.lib.TBMCChatPreprocessEvent;
import buttondevteam.lib.TBMCCommandPreprocessEvent;
import buttondevteam.lib.TBMCCoreAPI; import buttondevteam.lib.TBMCCoreAPI;
import buttondevteam.lib.chat.ChatMessage; import buttondevteam.lib.chat.ChatMessage;
import buttondevteam.lib.chat.TBMCChatAPI; import buttondevteam.lib.chat.TBMCChatAPI;
@ -47,8 +48,13 @@ public class MCChatListener implements Listener {
private LinkedBlockingQueue<AbstractMap.SimpleEntry<TBMCChatEvent, Instant>> sendevents = new LinkedBlockingQueue<>(); private LinkedBlockingQueue<AbstractMap.SimpleEntry<TBMCChatEvent, Instant>> sendevents = new LinkedBlockingQueue<>();
private Runnable sendrunnable; private Runnable sendrunnable;
private static Thread sendthread; private static Thread sendthread;
private final MinecraftChatModule module;
@EventHandler // Minecraft public MCChatListener(MinecraftChatModule minecraftChatModule) {
module = minecraftChatModule;
}
@EventHandler // Minecraft
public void onMCChat(TBMCChatEvent ev) { public void onMCChat(TBMCChatEvent ev) {
if (!ComponentManager.isEnabled(MinecraftChatModule.class) || ev.isCancelled()) //SafeMode: Needed so it doesn't restart after server shutdown if (!ComponentManager.isEnabled(MinecraftChatModule.class) || ev.isCancelled()) //SafeMode: Needed so it doesn't restart after server shutdown
return; return;
@ -175,12 +181,6 @@ public class MCChatListener implements Listener {
} }
} }
private static final String[] UnconnectedCmds = new String[]{"list", "u", "shrug", "tableflip", "unflip", "mwiki",
"yeehaw", "lenny", "rp", "plugins"};
private static short lastlist = 0;
private static short lastlistp = 0;
// ......................DiscordSender....DiscordConnectedPlayer.DiscordPlayerSender // ......................DiscordSender....DiscordConnectedPlayer.DiscordPlayerSender
// Offline public chat......x............................................ // Offline public chat......x............................................
// Online public chat.......x...........................................x // Online public chat.......x...........................................x
@ -192,8 +192,6 @@ public class MCChatListener implements Listener {
// If online and disabling private chat, don't logout // If online and disabling private chat, don't logout
// The maps may not contain the senders for UnconnectedSenders // The maps may not contain the senders for UnconnectedSenders
public static short ListC = 0;
/** /**
* Stop the listener. Any calls to onMCChat will restart it as long as we're not in safe mode. * Stop the listener. Any calls to onMCChat will restart it as long as we're not in safe mode.
* *
@ -218,7 +216,6 @@ public class MCChatListener implements Listener {
MCChatCustom.lastmsgCustom.clear(); MCChatCustom.lastmsgCustom.clear();
MCChatUtils.lastmsgfromd.clear(); MCChatUtils.lastmsgfromd.clear();
MCChatUtils.ConnectedSenders.clear(); MCChatUtils.ConnectedSenders.clear();
lastlist = lastlistp = ListC = 0;
MCChatUtils.UnconnectedSenders.clear(); MCChatUtils.UnconnectedSenders.clear();
recthread = sendthread = null; recthread = sendthread = null;
} catch (InterruptedException e) { } catch (InterruptedException e) {
@ -249,7 +246,6 @@ public class MCChatListener implements Listener {
if (CommandListener.runCommand(ev.getMessage(), true)) if (CommandListener.runCommand(ev.getMessage(), true))
return true; //Allow running commands in chat channels return true; //Allow running commands in chat channels
MCChatUtils.resetLastMessage(ev.getChannel()); MCChatUtils.resetLastMessage(ev.getChannel());
lastlist++;
recevents.add(ev); recevents.add(ev);
if (rectask != null) if (rectask != null)
return true; return true;
@ -300,87 +296,80 @@ public class MCChatListener implements Listener {
boolean react = false; boolean react = false;
if (dmessage.startsWith("/")) { // Ingame command if (dmessage.startsWith("/")) { // Ingame command
DPUtils.perform(() -> { DPUtils.perform(() -> {
if (!event.getMessage().isDeleted() && !event.getChannel().isPrivate()) if (!event.getMessage().isDeleted() && !event.getChannel().isPrivate())
event.getMessage().delete(); event.getMessage().delete();
}); });
final String cmd = dmessage.substring(1); final String cmd = dmessage.substring(1);
final String cmdlowercased = cmd.toLowerCase(); final String cmdlowercased = cmd.toLowerCase();
if (dsender instanceof DiscordSender && Arrays.stream(UnconnectedCmds) if (dsender instanceof DiscordSender && module.whitelistedCommands().get().stream()
.noneMatch(s -> cmdlowercased.equals(s) || cmdlowercased.startsWith(s + " "))) { .noneMatch(s -> cmdlowercased.equals(s) || cmdlowercased.startsWith(s + " "))) {
// Command not whitelisted // Command not whitelisted
dsender.sendMessage("Sorry, you can only access these commands:\n" dsender.sendMessage("Sorry, you can only access these commands:\n"
+ Arrays.stream(UnconnectedCmds).map(uc -> "/" + uc) + module.whitelistedCommands().get().stream().map(uc -> "/" + uc)
.collect(Collectors.joining(", ")) .collect(Collectors.joining(", "))
+ (user.getConnectedID(TBMCPlayer.class) == null + (user.getConnectedID(TBMCPlayer.class) == null
? "\nTo access your commands, first please connect your accounts, using /connect in " ? "\nTo access your commands, first please connect your accounts, using /connect in "
+ DPUtils.botmention() + DPUtils.botmention()
+ "\nThen y" + "\nThen y"
: "\nY") : "\nY")
+ "ou can access all of your regular commands (even offline) in private chat: DM me `mcchat`!"); + "ou can access all of your regular commands (even offline) in private chat: DM me `mcchat`!");
return; return;
} }
if (lastlist > 5) { val ev = new TBMCCommandPreprocessEvent(dsender, dmessage);
ListC = 0; Bukkit.getPluginManager().callEvent(ev);
lastlist = 0; if (ev.isCancelled())
} return;
if (cmdlowercased.equals("list") && Bukkit.getOnlinePlayers().size() == lastlistp && ListC++ > 2) // Lowered already int spi = cmdlowercased.indexOf(' ');
{ final String topcmd = spi == -1 ? cmdlowercased : cmdlowercased.substring(0, spi);
dsender.sendMessage("Stop it. You know the answer."); Optional<Channel> ch = Channel.getChannels()
lastlist = 0; .filter(c -> c.ID.equalsIgnoreCase(topcmd)
} else { || (c.IDs().get().length > 0
int spi = cmdlowercased.indexOf(' '); && Arrays.stream(c.IDs().get()).anyMatch(id -> id.equalsIgnoreCase(topcmd)))).findAny();
final String topcmd = spi == -1 ? cmdlowercased : cmdlowercased.substring(0, spi); if (!ch.isPresent()) //TODO: What if talking in the public chat while we have it on a different one
Optional<Channel> ch = Channel.getChannels() Bukkit.getScheduler().runTask(DiscordPlugin.plugin, //Commands need to be run sync
.filter(c -> c.ID.equalsIgnoreCase(topcmd) () -> { //TODO: Better handling...
|| (c.IDs().get().length > 0 val channel = user.channel();
&& Arrays.stream(c.IDs().get()).anyMatch(id -> id.equalsIgnoreCase(topcmd)))).findAny(); val chtmp = channel.get();
if (!ch.isPresent()) //TODO: What if talking in the public chat while we have it on a different one if (clmd != null) {
Bukkit.getScheduler().runTask(DiscordPlugin.plugin, //Commands need to be run sync channel.set(clmd.mcchannel); //Hack to send command in the channel
() -> { //TODO: Better handling... } //TODO: Permcheck isn't implemented for commands
val channel = user.channel(); VanillaCommandListener.runBukkitOrVanillaCommand(dsender, cmd);
val chtmp = channel.get(); Bukkit.getLogger().info(dsender.getName() + " issued command from Discord: /" + cmdlowercased);
if (clmd != null) { if (clmd != null)
channel.set(clmd.mcchannel); //Hack to send command in the channel channel.set(chtmp);
} //TODO: Permcheck isn't implemented for commands });
VanillaCommandListener.runBukkitOrVanillaCommand(dsender, cmd); else {
Bukkit.getLogger().info(dsender.getName() + " issued command from Discord: /" + cmdlowercased); Channel chc = ch.get();
if (clmd != null) if (!chc.isGlobal() && !event.getMessage().getChannel().isPrivate())
channel.set(chtmp); dsender.sendMessage(
}); "You can only talk in a public chat here. DM `mcchat` to enable private chat to talk in the other channels.");
else { else {
Channel chc = ch.get(); if (spi == -1) // Switch channels
if (!chc.isGlobal() && !event.getMessage().getChannel().isPrivate()) {
dsender.sendMessage( val channel = dsender.getChromaUser().channel();
"You can only talk in a public chat here. DM `mcchat` to enable private chat to talk in the other channels."); val oldch = channel.get();
else { if (oldch instanceof ChatRoom)
if (spi == -1) // Switch channels ((ChatRoom) oldch).leaveRoom(dsender);
{ if (!oldch.ID.equals(chc.ID)) {
val channel = dsender.getChromaUser().channel(); channel.set(chc);
val oldch = channel.get(); if (chc instanceof ChatRoom)
if (oldch instanceof ChatRoom) ((ChatRoom) chc).joinRoom(dsender);
((ChatRoom) oldch).leaveRoom(dsender); } else
if (!oldch.ID.equals(chc.ID)) { channel.set(Channel.GlobalChat);
channel.set(chc); dsender.sendMessage("You're now talking in: "
if (chc instanceof ChatRoom) + DPUtils.sanitizeString(channel.get().DisplayName().get()));
((ChatRoom) chc).joinRoom(dsender); } else { // Send single message
} else final String msg = cmd.substring(spi + 1);
channel.set(Channel.GlobalChat); val cmb = ChatMessage.builder(dsender, user, getChatMessage.apply(msg)).fromCommand(true);
dsender.sendMessage("You're now talking in: " if (clmd == null)
+ DPUtils.sanitizeString(channel.get().DisplayName().get())); TBMCChatAPI.SendChatMessage(cmb.build(), chc);
} else { // Send single message else
final String msg = cmd.substring(spi + 1); TBMCChatAPI.SendChatMessage(cmb.permCheck(clmd.dcp).build(), chc);
val cmb = ChatMessage.builder(dsender, user, getChatMessage.apply(msg)).fromCommand(true); react = true;
if (clmd == null) }
TBMCChatAPI.SendChatMessage(cmb.build(), chc); }
else }
TBMCChatAPI.SendChatMessage(cmb.permCheck(clmd.dcp).build(), chc);
react = true;
}
}
}
}
lastlistp = (short) Bukkit.getOnlinePlayers().size();
} else {// Not a command } else {// Not a command
if (dmessage.length() == 0 && event.getMessage().getAttachments().size() == 0 if (dmessage.length() == 0 && event.getMessage().getAttachments().size() == 0
&& !event.getChannel().isPrivate() && event.getMessage().isSystemMessage()) { && !event.getChannel().isPrivate() && event.getMessage().isSystemMessage()) {

View file

@ -60,7 +60,6 @@ class MCListener implements Listener {
} }
final String message = e.GetPlayer().PlayerName().get() + " joined the game"; final String message = e.GetPlayer().PlayerName().get() + " joined the game";
MCChatUtils.forAllowedCustomAndAllMCChat(MCChatUtils.send(message), e.getPlayer(), ChannelconBroadcast.JOINLEAVE, true); MCChatUtils.forAllowedCustomAndAllMCChat(MCChatUtils.send(message), e.getPlayer(), ChannelconBroadcast.JOINLEAVE, true);
MCChatListener.ListC = 0;
ChromaBot.getInstance().updatePlayerList(); ChromaBot.getInstance().updatePlayerList();
}); });
} }

View file

@ -3,17 +3,27 @@ package buttondevteam.discordplugin.mcchat;
import buttondevteam.discordplugin.DiscordPlugin; import buttondevteam.discordplugin.DiscordPlugin;
import buttondevteam.lib.TBMCCoreAPI; import buttondevteam.lib.TBMCCoreAPI;
import buttondevteam.lib.architecture.Component; import buttondevteam.lib.architecture.Component;
import buttondevteam.lib.architecture.ConfigData;
import com.google.common.collect.Lists;
import lombok.Getter; import lombok.Getter;
import java.util.ArrayList;
public class MinecraftChatModule extends Component { public class MinecraftChatModule extends Component {
private @Getter MCChatListener listener; private @Getter MCChatListener listener;
public MCChatListener getListener() { //It doesn't want to generate public MCChatListener getListener() { //It doesn't want to generate
return listener; return listener;
} }
public ConfigData<ArrayList<String>> whitelistedCommands() {
return getConfig().getData("whitelistedCommands", () -> Lists.newArrayList("list", "u", "shrug", "tableflip", "unflip", "mwiki",
"yeehaw", "lenny", "rp", "plugins"));
}
@Override @Override
protected void enable() { protected void enable() {
listener = new MCChatListener(); listener = new MCChatListener(this);
DiscordPlugin.dc.getDispatcher().registerListener(listener); DiscordPlugin.dc.getDispatcher().registerListener(listener);
TBMCCoreAPI.RegisterEventsForExceptions(listener, getPlugin()); TBMCCoreAPI.RegisterEventsForExceptions(listener, getPlugin());
TBMCCoreAPI.RegisterEventsForExceptions(new MCListener(), getPlugin()); TBMCCoreAPI.RegisterEventsForExceptions(new MCListener(), getPlugin());

View file

@ -0,0 +1,62 @@
package buttondevteam.discordplugin.role;
import buttondevteam.core.ComponentManager;
import buttondevteam.discordplugin.DPUtils;
import buttondevteam.discordplugin.DiscordPlugin;
import buttondevteam.discordplugin.commands.DiscordCommandBase;
import buttondevteam.lib.architecture.Component;
import buttondevteam.lib.architecture.ConfigData;
import lombok.val;
import org.bukkit.Bukkit;
import sx.blah.discord.handle.impl.events.guild.role.RoleCreateEvent;
import sx.blah.discord.handle.impl.events.guild.role.RoleDeleteEvent;
import sx.blah.discord.handle.impl.events.guild.role.RoleEvent;
import sx.blah.discord.handle.impl.events.guild.role.RoleUpdateEvent;
import sx.blah.discord.handle.obj.IChannel;
public class GameRoleModule extends Component {
@Override
protected void enable() {
DiscordCommandBase.registerCommand("role", new RoleCommand());
}
@Override
protected void disable() {
}
private ConfigData<IChannel> logChannel() {
return DPUtils.channelData(getConfig(), "logChannel", 239519012529111040L);
}
public static void handleRoleEvent(RoleEvent roleEvent) {
val grm = ComponentManager.getIfEnabled(GameRoleModule.class);
if (grm == null) return;
if (roleEvent instanceof RoleCreateEvent) {
Bukkit.getScheduler().runTaskLaterAsynchronously(DiscordPlugin.plugin, () -> {
if (roleEvent.getRole().isDeleted() || !DiscordPlugin.plugin.isGameRole(roleEvent.getRole()))
return; //Deleted or not a game role
DiscordPlugin.GameRoles.add(roleEvent.getRole().getName());
DiscordPlugin.sendMessageToChannel(grm.logChannel().get(), "Added " + roleEvent.getRole().getName() + " as game role. If you don't want this, change the role's color from the default.");
}, 100);
} else if (roleEvent instanceof RoleDeleteEvent) {
if (DiscordPlugin.GameRoles.remove(roleEvent.getRole().getName()))
DiscordPlugin.sendMessageToChannel(grm.logChannel().get(), "Removed " + roleEvent.getRole().getName() + " as a game role.");
} else if (roleEvent instanceof RoleUpdateEvent) {
val event = (RoleUpdateEvent) roleEvent;
if (!DiscordPlugin.plugin.isGameRole(event.getNewRole())) {
if (DiscordPlugin.GameRoles.remove(event.getOldRole().getName()))
DiscordPlugin.sendMessageToChannel(grm.logChannel().get(), "Removed " + event.getOldRole().getName() + " as a game role because it's color changed.");
} else {
if (DiscordPlugin.GameRoles.contains(event.getOldRole().getName()) && event.getOldRole().getName().equals(event.getNewRole().getName()))
return;
boolean removed = DiscordPlugin.GameRoles.remove(event.getOldRole().getName()); //Regardless of whether it was a game role
DiscordPlugin.GameRoles.add(event.getNewRole().getName()); //Add it because it has no color
if (removed)
DiscordPlugin.sendMessageToChannel(grm.logChannel().get(), "Changed game role from " + event.getOldRole().getName() + " to " + event.getNewRole().getName() + ".");
else
DiscordPlugin.sendMessageToChannel(grm.logChannel().get(), "Added " + event.getNewRole().getName() + " as game role because it has the default color.");
}
}
}
}

View file

@ -1,7 +1,8 @@
package buttondevteam.discordplugin.commands; package buttondevteam.discordplugin.role;
import buttondevteam.discordplugin.DPUtils; import buttondevteam.discordplugin.DPUtils;
import buttondevteam.discordplugin.DiscordPlugin; import buttondevteam.discordplugin.DiscordPlugin;
import buttondevteam.discordplugin.commands.DiscordCommandBase;
import buttondevteam.lib.TBMCCoreAPI; import buttondevteam.lib.TBMCCoreAPI;
import sx.blah.discord.handle.obj.IMessage; import sx.blah.discord.handle.obj.IMessage;
import sx.blah.discord.handle.obj.IRole; import sx.blah.discord.handle.obj.IRole;
@ -9,7 +10,7 @@ import sx.blah.discord.handle.obj.IRole;
import java.util.List; import java.util.List;
import java.util.stream.Collectors; import java.util.stream.Collectors;
public class RoleCommand extends DiscordCommandBase { public class RoleCommand extends DiscordCommandBase { //TODO: Use Command2's parser
@Override @Override
public String getCommandName() { public String getCommandName() {
@ -22,23 +23,23 @@ public class RoleCommand extends DiscordCommandBase {
return false; return false;
String[] argsa = splitargs(args); String[] argsa = splitargs(args);
if (argsa[0].equalsIgnoreCase("add")) { if (argsa[0].equalsIgnoreCase("add")) {
final IRole role = checkAndGetRole(message, argsa, "This command adds a game role to your account."); final IRole role = checkAndGetRole(message, argsa, "This command adds a role to your account.");
if (role == null) if (role == null)
return true; return true;
try { try {
DPUtils.perform(() -> message.getAuthor().addRole(role)); DPUtils.perform(() -> message.getAuthor().addRole(role));
DiscordPlugin.sendMessageToChannel(message.getChannel(), "Added game role."); DiscordPlugin.sendMessageToChannel(message.getChannel(), "Added role.");
} catch (Exception e) { } catch (Exception e) {
TBMCCoreAPI.SendException("Error while adding role!", e); TBMCCoreAPI.SendException("Error while adding role!", e);
DiscordPlugin.sendMessageToChannel(message.getChannel(), "An error occured while adding the role."); DiscordPlugin.sendMessageToChannel(message.getChannel(), "An error occured while adding the role.");
} }
} else if (argsa[0].equalsIgnoreCase("remove")) { } else if (argsa[0].equalsIgnoreCase("remove")) {
final IRole role = checkAndGetRole(message, argsa, "This command removes a game role from your account."); final IRole role = checkAndGetRole(message, argsa, "This command removes a role from your account.");
if (role == null) if (role == null)
return true; return true;
try { try {
DPUtils.perform(() -> message.getAuthor().removeRole(role)); DPUtils.perform(() -> message.getAuthor().removeRole(role));
DiscordPlugin.sendMessageToChannel(message.getChannel(), "Removed game role."); DiscordPlugin.sendMessageToChannel(message.getChannel(), "Removed role.");
} catch (Exception e) { } catch (Exception e) {
TBMCCoreAPI.SendException("Error while removing role!", e); TBMCCoreAPI.SendException("Error while removing role!", e);
DiscordPlugin.sendMessageToChannel(message.getChannel(), "An error occured while removing the role."); DiscordPlugin.sendMessageToChannel(message.getChannel(), "An error occured while removing the role.");
@ -51,7 +52,7 @@ public class RoleCommand extends DiscordCommandBase {
private void listRoles(IMessage message) { private void listRoles(IMessage message) {
DiscordPlugin.sendMessageToChannel(message.getChannel(), DiscordPlugin.sendMessageToChannel(message.getChannel(),
"List of game roles:\n" + DiscordPlugin.GameRoles.stream().sorted().collect(Collectors.joining("\n"))); "List of roles:\n" + DiscordPlugin.GameRoles.stream().sorted().collect(Collectors.joining("\n")));
} }
private IRole checkAndGetRole(IMessage message, String[] argsa, String usage) { private IRole checkAndGetRole(IMessage message, String[] argsa, String usage) {
@ -63,7 +64,7 @@ public class RoleCommand extends DiscordCommandBase {
for (int i = 2; i < argsa.length; i++) for (int i = 2; i < argsa.length; i++)
rolename.append(" ").append(argsa[i]); rolename.append(" ").append(argsa[i]);
if (!DiscordPlugin.GameRoles.contains(rolename.toString())) { if (!DiscordPlugin.GameRoles.contains(rolename.toString())) {
DiscordPlugin.sendMessageToChannel(message.getChannel(), "That game role cannot be found."); DiscordPlugin.sendMessageToChannel(message.getChannel(), "That role cannot be found.");
listRoles(message); listRoles(message);
return null; return null;
} }
@ -85,7 +86,7 @@ public class RoleCommand extends DiscordCommandBase {
@Override @Override
public String[] getHelpText() { public String[] getHelpText() {
return new String[]{ // return new String[]{ //
"Add or remove game roles from yourself.", // "Add or remove roles from yourself.", //
"Usage: " + DiscordPlugin.getPrefix() + "role add|remove <name> or role list", // "Usage: " + DiscordPlugin.getPrefix() + "role add|remove <name> or role list", //
}; };
} }

View file

@ -1,8 +1,8 @@
name: DiscordPlugin name: Thorpe-Discord
main: buttondevteam.discordplugin.DiscordPlugin main: buttondevteam.discordplugin.DiscordPlugin
version: 1.0 version: 1.0
author: NorbiPeti author: NorbiPeti
depend: [ButtonCore] depend: [ThorpeCore]
commands: commands:
discord: discord:
website: 'https://github.com/TBMCPlugins/DiscordPlugin' website: 'https://github.com/TBMCPlugins/DiscordPlugin'