Merge pull request #92 from TBMCPlugins/dev
Supporting clean installs, broadcast toggles, command improvements
This commit is contained in:
commit
42b561bca4
32 changed files with 1238 additions and 1098 deletions
8
pom.xml
8
pom.xml
|
@ -124,10 +124,10 @@
|
||||||
<id>jitpack.io</id>
|
<id>jitpack.io</id>
|
||||||
<url>https://jitpack.io</url>
|
<url>https://jitpack.io</url>
|
||||||
</repository>
|
</repository>
|
||||||
<repository>
|
<!-- <repository>
|
||||||
<id>vault-repo</id>
|
<id>vault-repo</id>
|
||||||
<url>http://nexus.hc.to/content/repositories/pub_releases</url>
|
<url>http://nexus.hc.to/content/repositories/pub_releases</url>
|
||||||
</repository>
|
</repository> -->
|
||||||
<repository>
|
<repository>
|
||||||
<id>Essentials</id>
|
<id>Essentials</id>
|
||||||
<url>http://repo.ess3.net/content/repositories/essrel/</url>
|
<url>http://repo.ess3.net/content/repositories/essrel/</url>
|
||||||
|
|
|
@ -1,9 +1,13 @@
|
||||||
package buttondevteam.discordplugin;
|
package buttondevteam.discordplugin;
|
||||||
|
|
||||||
|
import buttondevteam.lib.TBMCCoreAPI;
|
||||||
|
import buttondevteam.lib.architecture.Component;
|
||||||
import buttondevteam.lib.architecture.ConfigData;
|
import buttondevteam.lib.architecture.ConfigData;
|
||||||
import buttondevteam.lib.architecture.IHaveConfig;
|
import buttondevteam.lib.architecture.IHaveConfig;
|
||||||
|
import lombok.val;
|
||||||
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.IGuild;
|
||||||
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.handle.obj.IRole;
|
||||||
import sx.blah.discord.util.EmbedBuilder;
|
import sx.blah.discord.util.EmbedBuilder;
|
||||||
|
@ -58,7 +62,7 @@ public final class DPUtils {
|
||||||
return null;
|
return null;
|
||||||
if (Bukkit.isPrimaryThread()) // TODO: Ignore shutdown message <--
|
if (Bukkit.isPrimaryThread()) // TODO: Ignore shutdown message <--
|
||||||
// throw new RuntimeException("Tried to wait for a Discord request on the main thread. This could cause lag.");
|
// throw new RuntimeException("Tried to wait for a Discord request on the main thread. This could cause lag.");
|
||||||
Bukkit.getLogger().warning("Waiting for a Discord request on the main thread!");
|
getLogger().warning("Waiting for a Discord request on the main thread!");
|
||||||
return RequestBuffer.request(action).get(timeout, unit); // Let the pros handle this
|
return RequestBuffer.request(action).get(timeout, unit); // Let the pros handle this
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -71,7 +75,7 @@ public final class DPUtils {
|
||||||
return null;
|
return null;
|
||||||
if (Bukkit.isPrimaryThread()) // TODO: Ignore shutdown message <--
|
if (Bukkit.isPrimaryThread()) // TODO: Ignore shutdown message <--
|
||||||
// throw new RuntimeException("Tried to wait for a Discord request on the main thread. This could cause lag.");
|
// throw new RuntimeException("Tried to wait for a Discord request on the main thread. This could cause lag.");
|
||||||
Bukkit.getLogger().warning("Waiting for a Discord request on the main thread!");
|
getLogger().warning("Waiting for a Discord request on the main thread!");
|
||||||
return RequestBuffer.request(action).get(); // Let the pros handle this
|
return RequestBuffer.request(action).get(); // Let the pros handle this
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -112,8 +116,16 @@ 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) {
|
public static ConfigData<IRole> roleData(IHaveConfig config, String key, String defName) {
|
||||||
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)
|
return roleData(config, key, defName, DiscordPlugin.mainServer);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ConfigData<IRole> roleData(IHaveConfig config, String key, String defName, IGuild guild) {
|
||||||
|
return config.getDataPrimDef(key, defName, name -> {
|
||||||
|
if (!(name instanceof String)) return null;
|
||||||
|
val roles = guild.getRolesByName((String) name);
|
||||||
|
return roles.size() > 0 ? roles.get(0) : null;
|
||||||
|
}, IIDLinkedObject::getLongID);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -122,8 +134,38 @@ public final class DPUtils {
|
||||||
* @return The string for mentioning the channel
|
* @return The string for mentioning the channel
|
||||||
*/
|
*/
|
||||||
public static String botmention() {
|
public static String botmention() {
|
||||||
if (DiscordPlugin.plugin == null) return "#bot";
|
IChannel channel;
|
||||||
return DiscordPlugin.plugin.CommandChannel().get().mention();
|
if (DiscordPlugin.plugin == null
|
||||||
|
|| (channel = DiscordPlugin.plugin.CommandChannel().get()) == null) return "#bot";
|
||||||
|
return channel.mention();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Disables the component if one of the given configs return null. Useful for channel/role configs.
|
||||||
|
*
|
||||||
|
* @param component The component to disable if needed
|
||||||
|
* @param configs The configs to check for null
|
||||||
|
* @return Whether the component got disabled and a warning logged
|
||||||
|
*/
|
||||||
|
public static boolean disableIfConfigError(@Nullable Component<DiscordPlugin> component, ConfigData<?>... configs) {
|
||||||
|
for (val config : configs) {
|
||||||
|
if (config.get() == null) {
|
||||||
|
String path = null;
|
||||||
|
try {
|
||||||
|
if (component != null)
|
||||||
|
Component.setComponentEnabled(component, false);
|
||||||
|
val f = ConfigData.class.getDeclaredField("path");
|
||||||
|
f.setAccessible(true); //Hacking my own plugin
|
||||||
|
path = (String) f.get(config);
|
||||||
|
} catch (Exception e) {
|
||||||
|
TBMCCoreAPI.SendException("Failed to disable component after config error!", e);
|
||||||
|
}
|
||||||
|
getLogger().warning("The config value " + path + " isn't set correctly " + (component == null ? "in global settings!" : "for component " + component.getClass().getSimpleName() + "!"));
|
||||||
|
getLogger().warning("Set the correct ID in the config" + (component == null ? "" : " or disable this component") + " to remove this message.");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,10 @@
|
||||||
package buttondevteam.discordplugin;
|
package buttondevteam.discordplugin;
|
||||||
|
|
||||||
|
import buttondevteam.discordplugin.announcer.AnnouncerModule;
|
||||||
import buttondevteam.discordplugin.broadcaster.GeneralEventBroadcasterModule;
|
import buttondevteam.discordplugin.broadcaster.GeneralEventBroadcasterModule;
|
||||||
import buttondevteam.discordplugin.commands.DiscordCommandBase;
|
import buttondevteam.discordplugin.commands.*;
|
||||||
import buttondevteam.discordplugin.exceptions.ExceptionListenerModule;
|
import buttondevteam.discordplugin.exceptions.ExceptionListenerModule;
|
||||||
|
import buttondevteam.discordplugin.fun.FunModule;
|
||||||
import buttondevteam.discordplugin.listeners.CommonListeners;
|
import buttondevteam.discordplugin.listeners.CommonListeners;
|
||||||
import buttondevteam.discordplugin.listeners.MCListener;
|
import buttondevteam.discordplugin.listeners.MCListener;
|
||||||
import buttondevteam.discordplugin.mcchat.MCChatPrivate;
|
import buttondevteam.discordplugin.mcchat.MCChatPrivate;
|
||||||
|
@ -18,9 +20,11 @@ import buttondevteam.lib.architecture.ConfigData;
|
||||||
import buttondevteam.lib.chat.TBMCChatAPI;
|
import buttondevteam.lib.chat.TBMCChatAPI;
|
||||||
import buttondevteam.lib.player.ChromaGamerBase;
|
import buttondevteam.lib.player.ChromaGamerBase;
|
||||||
import com.google.common.io.Files;
|
import com.google.common.io.Files;
|
||||||
|
import lombok.Getter;
|
||||||
import lombok.val;
|
import lombok.val;
|
||||||
import net.milkbowl.vault.permission.Permission;
|
import net.milkbowl.vault.permission.Permission;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.configuration.file.YamlConfiguration;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
import org.bukkit.plugin.RegisteredServiceProvider;
|
import org.bukkit.plugin.RegisteredServiceProvider;
|
||||||
import org.bukkit.scheduler.BukkitTask;
|
import org.bukkit.scheduler.BukkitTask;
|
||||||
|
@ -40,12 +44,15 @@ import java.nio.charset.StandardCharsets;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
import java.util.concurrent.TimeoutException;
|
import java.util.concurrent.TimeoutException;
|
||||||
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
public class DiscordPlugin extends ButtonPlugin implements IListener<ReadyEvent> {
|
public class DiscordPlugin extends ButtonPlugin implements IListener<ReadyEvent> {
|
||||||
public static IDiscordClient dc;
|
public static IDiscordClient dc;
|
||||||
public static DiscordPlugin plugin;
|
public static DiscordPlugin plugin;
|
||||||
public static boolean SafeMode = true;
|
public static boolean SafeMode = true;
|
||||||
|
@Getter
|
||||||
|
private Command2DC manager;
|
||||||
|
|
||||||
public ConfigData<Character> Prefix() {
|
public ConfigData<Character> Prefix() {
|
||||||
return getIConfig().getData("prefix", '/', str -> ((String) str).charAt(0), Object::toString);
|
return getIConfig().getData("prefix", '/', str -> ((String) str).charAt(0), Object::toString);
|
||||||
|
@ -64,13 +71,35 @@ public class DiscordPlugin extends ButtonPlugin implements IListener<ReadyEvent>
|
||||||
return DPUtils.channelData(getIConfig(), "commandChannel", 239519012529111040L);
|
return DPUtils.channelData(getIConfig(), "commandChannel", 239519012529111040L);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public ConfigData<IRole> ModRole() {
|
||||||
|
return DPUtils.roleData(getIConfig(), "modRole", "Moderator");
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void pluginEnable() {
|
public void pluginEnable() {
|
||||||
try {
|
try {
|
||||||
Bukkit.getLogger().info("Initializing DiscordPlugin...");
|
getLogger().info("Initializing...");
|
||||||
plugin = this;
|
plugin = this;
|
||||||
|
manager = new Command2DC();
|
||||||
ClientBuilder cb = new ClientBuilder();
|
ClientBuilder cb = new ClientBuilder();
|
||||||
cb.withToken(Files.readFirstLine(new File("TBMC", "Token.txt"), StandardCharsets.UTF_8));
|
File tokenFile = new File("TBMC", "Token.txt");
|
||||||
|
if (tokenFile.exists()) //Legacy support
|
||||||
|
//noinspection UnstableApiUsage
|
||||||
|
cb.withToken(Files.readFirstLine(tokenFile, StandardCharsets.UTF_8));
|
||||||
|
else {
|
||||||
|
File privateFile = new File(getDataFolder(), "private.yml");
|
||||||
|
val conf = YamlConfiguration.loadConfiguration(privateFile);
|
||||||
|
String token = conf.getString("token");
|
||||||
|
if (token == null) {
|
||||||
|
conf.set("token", "Token goes here");
|
||||||
|
conf.save(privateFile);
|
||||||
|
|
||||||
|
getLogger().severe("Token not found! Set it in private.yml");
|
||||||
|
Bukkit.getPluginManager().disablePlugin(this);
|
||||||
|
return;
|
||||||
|
} else
|
||||||
|
cb.withToken(token);
|
||||||
|
}
|
||||||
dc = cb.login();
|
dc = cb.login();
|
||||||
dc.getDispatcher().registerListener(this);
|
dc.getDispatcher().registerListener(this);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
|
@ -79,20 +108,7 @@ public class DiscordPlugin extends ButtonPlugin implements IListener<ReadyEvent>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static IChannel botchannel; //Can be removed
|
|
||||||
public static IChannel annchannel;
|
|
||||||
public static IChannel genchannel;
|
|
||||||
public static IChannel chatchannel;
|
|
||||||
public static IChannel botroomchannel;
|
|
||||||
public static IChannel modlogchannel;
|
|
||||||
/**
|
|
||||||
* Don't send messages, just receive, the same channel is used when testing
|
|
||||||
*/
|
|
||||||
public static IChannel officechannel;
|
|
||||||
public static IChannel updatechannel;
|
|
||||||
public static IChannel devofficechannel;
|
|
||||||
public static IGuild mainServer;
|
public static IGuild mainServer;
|
||||||
public static IGuild devServer;
|
|
||||||
|
|
||||||
private static volatile BukkitTask task;
|
private static volatile BukkitTask task;
|
||||||
private static volatile boolean sent = false;
|
private static volatile boolean sent = false;
|
||||||
|
@ -101,51 +117,49 @@ public class DiscordPlugin extends ButtonPlugin implements IListener<ReadyEvent>
|
||||||
public void handle(ReadyEvent event) {
|
public void handle(ReadyEvent event) {
|
||||||
try {
|
try {
|
||||||
dc.changePresence(StatusType.DND, ActivityType.PLAYING, "booting");
|
dc.changePresence(StatusType.DND, ActivityType.PLAYING, "booting");
|
||||||
|
val tries = new AtomicInteger();
|
||||||
task = Bukkit.getScheduler().runTaskTimerAsynchronously(this, () -> {
|
task = Bukkit.getScheduler().runTaskTimerAsynchronously(this, () -> {
|
||||||
if (mainServer == null || devServer == null) {
|
tries.incrementAndGet();
|
||||||
mainServer = event.getClient().getGuildByID(125813020357165056L);
|
if (tries.get() > 10) { //5 seconds
|
||||||
devServer = event.getClient().getGuildByID(219529124321034241L);
|
task.cancel();
|
||||||
}
|
getLogger().severe("Main server not found! Invite the bot and do /discord reset");
|
||||||
if (mainServer == null || devServer == null)
|
//getIConfig().getConfig().set("mainServer", 219529124321034241L); //Needed because it won't save as long as it's null - made it save
|
||||||
return; // Retry
|
saveConfig(); //Put default there
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
mainServer = MainServer().get(); //Shouldn't change afterwards
|
||||||
|
if (mainServer == null) {
|
||||||
|
val guilds = dc.getGuilds();
|
||||||
|
if (guilds.size() == 0)
|
||||||
|
return; //If there are no guilds in cache, retry
|
||||||
|
mainServer = guilds.get(0);
|
||||||
|
getLogger().warning("Main server set to first one: " + mainServer.getName());
|
||||||
|
MainServer().set(mainServer); //Save in config
|
||||||
|
}
|
||||||
if (!TBMCCoreAPI.IsTestServer()) { //Don't change conditions here, see mainServer=devServer=null in onDisable()
|
if (!TBMCCoreAPI.IsTestServer()) { //Don't change conditions here, see mainServer=devServer=null in onDisable()
|
||||||
botchannel = mainServer.getChannelByID(209720707188260864L); // bot
|
dc.changePresence(StatusType.ONLINE, ActivityType.PLAYING, "Minecraft");
|
||||||
annchannel = mainServer.getChannelByID(126795071927353344L); // announcements
|
|
||||||
genchannel = mainServer.getChannelByID(125813020357165056L); // general
|
|
||||||
chatchannel = mainServer.getChannelByID(249663564057411596L); // minecraft_chat
|
|
||||||
botroomchannel = devServer.getChannelByID(239519012529111040L); // bot-room
|
|
||||||
officechannel = devServer.getChannelByID(219626707458457603L); // developers-office
|
|
||||||
updatechannel = devServer.getChannelByID(233724163519414272L); // server-updates
|
|
||||||
devofficechannel = officechannel; // developers-office
|
|
||||||
modlogchannel = mainServer.getChannelByID(283840717275791360L); // modlog
|
|
||||||
dc.changePresence(StatusType.ONLINE, ActivityType.PLAYING, "Chromacraft");
|
|
||||||
} else {
|
} else {
|
||||||
botchannel = devServer.getChannelByID(239519012529111040L); // bot-room
|
|
||||||
annchannel = botchannel; // bot-room
|
|
||||||
genchannel = botchannel; // bot-room
|
|
||||||
botroomchannel = botchannel;// bot-room
|
|
||||||
chatchannel = botchannel;// bot-room
|
|
||||||
officechannel = devServer.getChannelByID(219626707458457603L); // developers-office
|
|
||||||
updatechannel = botchannel;
|
|
||||||
devofficechannel = botchannel;// bot-room
|
|
||||||
modlogchannel = botchannel; // bot-room
|
|
||||||
dc.changePresence(StatusType.ONLINE, ActivityType.PLAYING, "testing");
|
dc.changePresence(StatusType.ONLINE, ActivityType.PLAYING, "testing");
|
||||||
}
|
}
|
||||||
if (botchannel == null || annchannel == null || genchannel == null || botroomchannel == null
|
|
||||||
|| chatchannel == null || officechannel == null || updatechannel == null)
|
|
||||||
return; // Retry
|
|
||||||
SafeMode = false;
|
SafeMode = false;
|
||||||
if (task != null)
|
if (task != null)
|
||||||
task.cancel();
|
task.cancel();
|
||||||
if (!sent) {
|
if (!sent) {
|
||||||
|
DPUtils.disableIfConfigError(null, CommandChannel(), ModRole()); //Won't disable, just prints the warning here
|
||||||
|
|
||||||
Component.registerComponent(this, new GeneralEventBroadcasterModule());
|
Component.registerComponent(this, new GeneralEventBroadcasterModule());
|
||||||
Component.registerComponent(this, new MinecraftChatModule());
|
Component.registerComponent(this, new MinecraftChatModule());
|
||||||
Component.registerComponent(this, new ExceptionListenerModule());
|
Component.registerComponent(this, new ExceptionListenerModule());
|
||||||
Component.registerComponent(this, new GameRoleModule()); //Needs the mainServer to be set
|
Component.registerComponent(this, new GameRoleModule()); //Needs the mainServer to be set
|
||||||
Component.registerComponent(this, new AnnouncerModule());
|
Component.registerComponent(this, new AnnouncerModule());
|
||||||
|
Component.registerComponent(this, new FunModule());
|
||||||
new ChromaBot(this).updatePlayerList(); //Initialize ChromaBot - The MCCHatModule is tested to be enabled
|
new ChromaBot(this).updatePlayerList(); //Initialize ChromaBot - The MCCHatModule is tested to be enabled
|
||||||
|
|
||||||
DiscordCommandBase.registerCommands();
|
getManager().registerCommand(new VersionCommand());
|
||||||
|
getManager().registerCommand(new UserinfoCommand());
|
||||||
|
getManager().registerCommand(new HelpCommand());
|
||||||
|
getManager().registerCommand(new DebugCommand());
|
||||||
|
getManager().registerCommand(new ConnectCommand());
|
||||||
if (ResetMCCommand.resetting) //These will only execute if the chat is enabled
|
if (ResetMCCommand.resetting) //These will only execute if the chat is enabled
|
||||||
ChromaBot.getInstance().sendMessageCustomAsWell("", new EmbedBuilder().withColor(Color.CYAN)
|
ChromaBot.getInstance().sendMessageCustomAsWell("", new EmbedBuilder().withColor(Color.CYAN)
|
||||||
.withTitle("Discord plugin restarted - chat connected.").build(), ChannelconBroadcast.RESTART); //Really important to note the chat, hmm
|
.withTitle("Discord plugin restarted - chat connected.").build(), ChannelconBroadcast.RESTART); //Really important to note the chat, hmm
|
||||||
|
@ -196,6 +210,7 @@ public class DiscordPlugin extends ButtonPlugin implements IListener<ReadyEvent>
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void pluginPreDisable() {
|
public void pluginPreDisable() {
|
||||||
|
if (ChromaBot.getInstance() == null) return; //Failed to load
|
||||||
EmbedObject embed;
|
EmbedObject embed;
|
||||||
if (ResetMCCommand.resetting)
|
if (ResetMCCommand.resetting)
|
||||||
embed = new EmbedBuilder().withColor(Color.ORANGE).withTitle("Discord plugin restarting").build();
|
embed = new EmbedBuilder().withColor(Color.ORANGE).withTitle("Discord plugin restarting").build();
|
||||||
|
@ -226,6 +241,7 @@ public class DiscordPlugin extends ButtonPlugin implements IListener<ReadyEvent>
|
||||||
public void pluginDisable() {
|
public void pluginDisable() {
|
||||||
MCChatPrivate.logoutAll();
|
MCChatPrivate.logoutAll();
|
||||||
getConfig().set("serverup", false);
|
getConfig().set("serverup", false);
|
||||||
|
if (ChromaBot.getInstance() == null) return; //Failed to load
|
||||||
|
|
||||||
saveConfig();
|
saveConfig();
|
||||||
try {
|
try {
|
||||||
|
@ -233,7 +249,7 @@ public class DiscordPlugin extends ButtonPlugin implements IListener<ReadyEvent>
|
||||||
ChromaBot.delete();
|
ChromaBot.delete();
|
||||||
dc.changePresence(StatusType.IDLE, ActivityType.PLAYING, "Chromacraft"); //No longer using the same account for testing
|
dc.changePresence(StatusType.IDLE, ActivityType.PLAYING, "Chromacraft"); //No longer using the same account for testing
|
||||||
dc.logout();
|
dc.logout();
|
||||||
mainServer = devServer = null; //Fetch servers and channels again
|
//Configs are emptied so channels and servers are fetched again
|
||||||
sent = false;
|
sent = false;
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
TBMCCoreAPI.SendException("An error occured while disabling DiscordPlugin!", e);
|
TBMCCoreAPI.SendException("An error occured while disabling DiscordPlugin!", e);
|
||||||
|
@ -273,7 +289,7 @@ public class DiscordPlugin extends ButtonPlugin implements IListener<ReadyEvent>
|
||||||
private static IMessage sendMessageToChannel(IChannel channel, String message, EmbedObject embed, boolean wait, long timeout, TimeUnit unit) throws TimeoutException, InterruptedException {
|
private static IMessage sendMessageToChannel(IChannel channel, String message, EmbedObject embed, boolean wait, long timeout, TimeUnit unit) throws TimeoutException, InterruptedException {
|
||||||
if (message.length() > 1980) {
|
if (message.length() > 1980) {
|
||||||
message = message.substring(0, 1980);
|
message = message.substring(0, 1980);
|
||||||
Bukkit.getLogger()
|
DPUtils.getLogger()
|
||||||
.warning("Message was too long to send to discord and got truncated. In " + channel.getName());
|
.warning("Message was too long to send to discord and got truncated. In " + channel.getName());
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
|
@ -296,7 +312,7 @@ public class DiscordPlugin extends ButtonPlugin implements IListener<ReadyEvent>
|
||||||
} catch (TimeoutException | InterruptedException e) {
|
} catch (TimeoutException | InterruptedException e) {
|
||||||
throw e;
|
throw e;
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
Bukkit.getLogger().warning(
|
DPUtils.getLogger().warning(
|
||||||
"Failed to deliver message to Discord! Channel: " + channel.getName() + " Message: " + message);
|
"Failed to deliver message to Discord! Channel: " + channel.getName() + " Message: " + message);
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,8 @@
|
||||||
package buttondevteam.discordplugin;
|
package buttondevteam.discordplugin.announcer;
|
||||||
|
|
||||||
|
import buttondevteam.discordplugin.DPUtils;
|
||||||
|
import buttondevteam.discordplugin.DiscordPlayer;
|
||||||
|
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;
|
||||||
|
@ -16,7 +19,7 @@ import sx.blah.discord.handle.obj.IMessage;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public class AnnouncerModule extends Component {
|
public class AnnouncerModule extends Component<DiscordPlugin> {
|
||||||
public ConfigData<IChannel> channel() {
|
public ConfigData<IChannel> channel() {
|
||||||
return DPUtils.channelData(getConfig(), "channel", 239519012529111040L);
|
return DPUtils.channelData(getConfig(), "channel", 239519012529111040L);
|
||||||
}
|
}
|
||||||
|
@ -45,6 +48,7 @@ public class AnnouncerModule extends Component {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void enable() {
|
protected void enable() {
|
||||||
|
if (DPUtils.disableIfConfigError(this, channel(), modChannel())) return;
|
||||||
stop = false; //If not the first time
|
stop = false; //If not the first time
|
||||||
DPUtils.performNoWait(() -> {
|
DPUtils.performNoWait(() -> {
|
||||||
try {
|
try {
|
|
@ -1,19 +1,19 @@
|
||||||
package buttondevteam.discordplugin.broadcaster;
|
package buttondevteam.discordplugin.broadcaster;
|
||||||
|
|
||||||
import buttondevteam.discordplugin.DPUtils;
|
import buttondevteam.discordplugin.DPUtils;
|
||||||
|
import buttondevteam.discordplugin.DiscordPlugin;
|
||||||
import buttondevteam.lib.TBMCCoreAPI;
|
import buttondevteam.lib.TBMCCoreAPI;
|
||||||
import buttondevteam.lib.architecture.Component;
|
import buttondevteam.lib.architecture.Component;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import org.bukkit.Bukkit;
|
|
||||||
|
|
||||||
public class GeneralEventBroadcasterModule extends Component {
|
public class GeneralEventBroadcasterModule extends Component<DiscordPlugin> {
|
||||||
private static @Getter boolean hooked = false;
|
private static @Getter boolean hooked = false;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void enable() {
|
protected void enable() {
|
||||||
try {
|
try {
|
||||||
PlayerListWatcher.hookUp();
|
PlayerListWatcher.hookUp();
|
||||||
Bukkit.getLogger().info("Finished hooking into the player list");
|
DPUtils.getLogger().info("Finished hooking into the player list");
|
||||||
hooked = true;
|
hooked = true;
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
TBMCCoreAPI.SendException("Error while hacking the player list!", e);
|
TBMCCoreAPI.SendException("Error while hacking the player list!", e);
|
||||||
|
|
|
@ -1,110 +0,0 @@
|
||||||
package buttondevteam.discordplugin.commands;
|
|
||||||
|
|
||||||
import buttondevteam.core.component.channel.Channel;
|
|
||||||
import buttondevteam.discordplugin.*;
|
|
||||||
import buttondevteam.discordplugin.mcchat.MCChatCustom;
|
|
||||||
import buttondevteam.lib.player.TBMCPlayer;
|
|
||||||
import lombok.val;
|
|
||||||
import org.bukkit.Bukkit;
|
|
||||||
import sx.blah.discord.handle.obj.IMessage;
|
|
||||||
import sx.blah.discord.handle.obj.Permissions;
|
|
||||||
import sx.blah.discord.util.PermissionUtils;
|
|
||||||
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.function.Supplier;
|
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
|
||||||
public class ChannelconCommand extends DiscordCommandBase {
|
|
||||||
@Override
|
|
||||||
public String getCommandName() {
|
|
||||||
return "channelcon";
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean run(IMessage message, String args) {
|
|
||||||
if (args.length() == 0)
|
|
||||||
return false;
|
|
||||||
if (!PermissionUtils.hasPermissions(message.getChannel(), message.getAuthor(), Permissions.MANAGE_CHANNEL)) {
|
|
||||||
message.reply("you need to have manage permissions for this channel!");
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (MCChatCustom.hasCustomChat(message.getChannel())) {
|
|
||||||
if (args.toLowerCase().startsWith("remove")) {
|
|
||||||
if (MCChatCustom.removeCustomChat(message.getChannel()))
|
|
||||||
message.reply("channel connection removed.");
|
|
||||||
else
|
|
||||||
message.reply("wait what, couldn't remove channel connection.");
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (args.toLowerCase().startsWith("toggle")) {
|
|
||||||
val cc = MCChatCustom.getCustomChat(message.getChannel());
|
|
||||||
assert cc != null; //It's not null
|
|
||||||
Supplier<String> togglesString = () -> Arrays.stream(ChannelconBroadcast.values()).map(t -> t.toString().toLowerCase() + ": " + ((cc.toggles & t.flag) == 0 ? "disabled" : "enabled")).collect(Collectors.joining("\n"));
|
|
||||||
String[] argsa = args.split(" ");
|
|
||||||
if (argsa.length < 2) {
|
|
||||||
message.reply("toggles:\n" + togglesString.get());
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
String arg = argsa[1].toUpperCase();
|
|
||||||
val b = Arrays.stream(ChannelconBroadcast.values()).filter(t -> t.toString().equals(arg)).findAny();
|
|
||||||
if (!b.isPresent()) {
|
|
||||||
message.reply("cannot find toggle. Toggles:\n" + togglesString.get());
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
//A B | F
|
|
||||||
//------- A: original - B: mask - F: new
|
|
||||||
//0 0 | 0
|
|
||||||
//0 1 | 1
|
|
||||||
//1 0 | 1
|
|
||||||
//1 1 | 0
|
|
||||||
// XOR
|
|
||||||
cc.toggles ^= b.get().flag;
|
|
||||||
message.reply("'" + b.get().toString().toLowerCase() + "' " + ((cc.toggles & b.get().flag) == 0 ? "disabled" : "enabled"));
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
message.reply("this channel is already connected to a Minecraft channel. Use `@ChromaBot channelcon remove` to remove it.");
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
val chan = Channel.getChannels().filter(ch -> ch.ID.equalsIgnoreCase(args) || (Arrays.stream(ch.IDs().get()).anyMatch(cid -> cid.equalsIgnoreCase(args)))).findAny();
|
|
||||||
if (!chan.isPresent()) { //TODO: Red embed that disappears over time (kinda like the highlight messages in OW)
|
|
||||||
message.reply("MC channel with ID '" + args + "' not found! The ID is the command for it without the /.");
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
val dp = DiscordPlayer.getUser(message.getAuthor().getStringID(), DiscordPlayer.class);
|
|
||||||
val chp = dp.getAs(TBMCPlayer.class);
|
|
||||||
if (chp == null) {
|
|
||||||
message.reply("you need to connect your Minecraft account. On our server in " + DPUtils.botmention() + " do " + DiscordPlugin.getPrefix() + "connect <MCname>");
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
DiscordConnectedPlayer dcp = new DiscordConnectedPlayer(message.getAuthor(), message.getChannel(), chp.getUUID(), Bukkit.getOfflinePlayer(chp.getUUID()).getName());
|
|
||||||
//Using a fake player with no login/logout, should be fine for this event
|
|
||||||
String groupid = chan.get().getGroupID(dcp);
|
|
||||||
if (groupid == null) {
|
|
||||||
message.reply("sorry, that didn't work. You cannot use that Minecraft channel.");
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
/*if (MCChatListener.getCustomChats().stream().anyMatch(cc -> cc.groupID.equals(groupid) && cc.mcchannel.ID.equals(chan.get().ID))) {
|
|
||||||
message.reply("sorry, this MC chat is already connected to a different channel, multiple channels are not supported atm.");
|
|
||||||
return true;
|
|
||||||
}*/ //TODO: "Channel admins" that can connect channels?
|
|
||||||
MCChatCustom.addCustomChat(message.getChannel(), groupid, chan.get(), message.getAuthor(), dcp, 0);
|
|
||||||
message.reply("alright, connection made to group `" + groupid + "`!");
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String[] getHelpText() {
|
|
||||||
return new String[]{ //
|
|
||||||
"---- Channel connect ---", //
|
|
||||||
"This command allows you to connect a Minecraft channel to a Discord channel (just like how the global chat is connected to #minecraft-chat).", //
|
|
||||||
"You need to have access to the MC channel and have manage permissions on the Discord channel.", //
|
|
||||||
"You also need to have your Minecraft account connected. In " + DPUtils.botmention() + " use " + DiscordPlugin.getPrefix() + "connect <mcname>.", //
|
|
||||||
"Call this command from the channel you want to use.", //
|
|
||||||
"Usage: @" + DiscordPlugin.dc.getOurUser().getName() + " channelcon <mcchannel>", //
|
|
||||||
"Use the ID (command) of the channel, for example `g` for the global chat.", //
|
|
||||||
"To remove a connection use @ChromaBot channelcon remove in the channel.", //
|
|
||||||
"Mentioning the bot is needed in this case because the " + DiscordPlugin.getPrefix() + " prefix only works in " + DPUtils.botmention() + ".", //
|
|
||||||
"Invite link: <https://discordapp.com/oauth2/authorize?client_id=226443037893591041&scope=bot&permissions=268509264>" //
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,17 @@
|
||||||
|
package buttondevteam.discordplugin.commands;
|
||||||
|
|
||||||
|
import buttondevteam.discordplugin.DiscordPlugin;
|
||||||
|
import buttondevteam.lib.chat.Command2;
|
||||||
|
|
||||||
|
public class Command2DC extends Command2<ICommand2DC, Command2DCSender> {
|
||||||
|
@Override
|
||||||
|
public void registerCommand(ICommand2DC command) {
|
||||||
|
super.registerCommand(command, DiscordPlugin.getPrefix()); //Needs to be configurable for the helps
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean hasPermission(Command2DCSender sender, ICommand2DC command) {
|
||||||
|
//return !command.isModOnly() || sender.getMessage().getAuthor().hasRole(DiscordPlugin.plugin.ModRole().get()); //TODO: ModRole may be null; more customisable way?
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,25 @@
|
||||||
|
package buttondevteam.discordplugin.commands;
|
||||||
|
|
||||||
|
import buttondevteam.discordplugin.DPUtils;
|
||||||
|
import buttondevteam.lib.chat.Command2Sender;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import sx.blah.discord.handle.obj.IMessage;
|
||||||
|
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
public class Command2DCSender implements Command2Sender {
|
||||||
|
private final @Getter IMessage message;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void sendMessage(String message) {
|
||||||
|
if (message.length() == 0) return;
|
||||||
|
message = DPUtils.sanitizeString(message);
|
||||||
|
message = Character.toLowerCase(message.charAt(0)) + message.substring(1);
|
||||||
|
this.message.reply(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void sendMessage(String[] message) {
|
||||||
|
sendMessage(String.join("\n", message));
|
||||||
|
}
|
||||||
|
}
|
|
@ -3,20 +3,21 @@ package buttondevteam.discordplugin.commands;
|
||||||
import buttondevteam.discordplugin.DiscordPlayer;
|
import buttondevteam.discordplugin.DiscordPlayer;
|
||||||
import buttondevteam.discordplugin.DiscordPlugin;
|
import buttondevteam.discordplugin.DiscordPlugin;
|
||||||
import buttondevteam.lib.TBMCCoreAPI;
|
import buttondevteam.lib.TBMCCoreAPI;
|
||||||
|
import buttondevteam.lib.chat.Command2;
|
||||||
|
import buttondevteam.lib.chat.CommandClass;
|
||||||
import buttondevteam.lib.player.TBMCPlayer;
|
import buttondevteam.lib.player.TBMCPlayer;
|
||||||
import buttondevteam.lib.player.TBMCPlayerBase;
|
import buttondevteam.lib.player.TBMCPlayerBase;
|
||||||
import com.google.common.collect.HashBiMap;
|
import com.google.common.collect.HashBiMap;
|
||||||
|
import lombok.val;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.OfflinePlayer;
|
import org.bukkit.OfflinePlayer;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
import sx.blah.discord.handle.obj.IMessage;
|
|
||||||
|
|
||||||
public class ConnectCommand extends DiscordCommandBase {
|
@CommandClass(helpText = {
|
||||||
|
"Connect command", //
|
||||||
@Override
|
"This command lets you connect your account with a Minecraft account. This allows using the Minecraft chat and other things.", //
|
||||||
public String getCommandName() {
|
})
|
||||||
return "connect";
|
public class ConnectCommand extends ICommand2DC {
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Key: Minecraft name<br>
|
* Key: Minecraft name<br>
|
||||||
|
@ -24,22 +25,16 @@ public class ConnectCommand extends DiscordCommandBase {
|
||||||
*/
|
*/
|
||||||
public static HashBiMap<String, String> WaitingToConnect = HashBiMap.create();
|
public static HashBiMap<String, String> WaitingToConnect = HashBiMap.create();
|
||||||
|
|
||||||
@Override
|
@Command2.Subcommand
|
||||||
public boolean run(IMessage message, String args) {
|
public boolean def(Command2DCSender sender, String Minecraftname) {
|
||||||
if (args.length() == 0)
|
val message = sender.getMessage();
|
||||||
return false;
|
|
||||||
if (args.contains(" ")) {
|
|
||||||
DiscordPlugin.sendMessageToChannel(message.getChannel(),
|
|
||||||
"Too many arguments.\nUsage: " + DiscordPlugin.getPrefix() + "connect <Minecraftname>");
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (WaitingToConnect.inverse().containsKey(message.getAuthor().getStringID())) {
|
if (WaitingToConnect.inverse().containsKey(message.getAuthor().getStringID())) {
|
||||||
DiscordPlugin.sendMessageToChannel(message.getChannel(),
|
DiscordPlugin.sendMessageToChannel(message.getChannel(),
|
||||||
"Replacing " + WaitingToConnect.inverse().get(message.getAuthor().getStringID()) + " with " + args);
|
"Replacing " + WaitingToConnect.inverse().get(message.getAuthor().getStringID()) + " with " + Minecraftname);
|
||||||
WaitingToConnect.inverse().remove(message.getAuthor().getStringID());
|
WaitingToConnect.inverse().remove(message.getAuthor().getStringID());
|
||||||
}
|
}
|
||||||
@SuppressWarnings("deprecation")
|
@SuppressWarnings("deprecation")
|
||||||
OfflinePlayer p = Bukkit.getOfflinePlayer(args);
|
OfflinePlayer p = Bukkit.getOfflinePlayer(Minecraftname);
|
||||||
if (p == null) {
|
if (p == null) {
|
||||||
DiscordPlugin.sendMessageToChannel(message.getChannel(), "The specified Minecraft player cannot be found");
|
DiscordPlugin.sendMessageToChannel(message.getChannel(), "The specified Minecraft player cannot be found");
|
||||||
return true;
|
return true;
|
||||||
|
@ -56,7 +51,7 @@ public class ConnectCommand extends DiscordCommandBase {
|
||||||
}
|
}
|
||||||
WaitingToConnect.put(p.getName(), message.getAuthor().getStringID());
|
WaitingToConnect.put(p.getName(), message.getAuthor().getStringID());
|
||||||
DiscordPlugin.sendMessageToChannel(message.getChannel(),
|
DiscordPlugin.sendMessageToChannel(message.getChannel(),
|
||||||
"Alright! Now accept the connection in Minecraft from the account " + args
|
"Alright! Now accept the connection in Minecraft from the account " + Minecraftname
|
||||||
+ " before the next server restart. You can also adjust the Minecraft name you want to connect to with the same command.");
|
+ " before the next server restart. You can also adjust the Minecraft name you want to connect to with the same command.");
|
||||||
if (p.isOnline())
|
if (p.isOnline())
|
||||||
((Player) p).sendMessage("§bTo connect with the Discord account " + message.getAuthor().getName() + "#"
|
((Player) p).sendMessage("§bTo connect with the Discord account " + message.getAuthor().getName() + "#"
|
||||||
|
@ -64,13 +59,4 @@ public class ConnectCommand extends DiscordCommandBase {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public String[] getHelpText() {
|
|
||||||
return new String[] { //
|
|
||||||
"---- Connect command ----", //
|
|
||||||
"This command lets you connect your account with a Minecraft account. This allows using the Minecraft chat and other things.", //
|
|
||||||
"Usage: /connect <Minecraftname>" //
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,25 +2,19 @@ package buttondevteam.discordplugin.commands;
|
||||||
|
|
||||||
import buttondevteam.discordplugin.DiscordPlugin;
|
import buttondevteam.discordplugin.DiscordPlugin;
|
||||||
import buttondevteam.discordplugin.listeners.CommonListeners;
|
import buttondevteam.discordplugin.listeners.CommonListeners;
|
||||||
import sx.blah.discord.handle.obj.IMessage;
|
import buttondevteam.lib.chat.Command2;
|
||||||
|
import buttondevteam.lib.chat.CommandClass;
|
||||||
|
|
||||||
public class DebugCommand extends DiscordCommandBase {
|
@CommandClass(helpText = {
|
||||||
@Override
|
"Switches debug mode."
|
||||||
public String getCommandName() {
|
})
|
||||||
return "debug";
|
public class DebugCommand extends ICommand2DC {
|
||||||
}
|
@Command2.Subcommand
|
||||||
|
public boolean def(Command2DCSender sender, String args) {
|
||||||
@Override
|
if (sender.getMessage().getAuthor().hasRole(DiscordPlugin.plugin.ModRole().get()))
|
||||||
public boolean run(IMessage message, String args) {
|
sender.sendMessage("debug " + (CommonListeners.debug() ? "enabled" : "disabled"));
|
||||||
if (message.getAuthor().hasRole(DiscordPlugin.mainServer.getRoleByID(126030201472811008L)))
|
|
||||||
message.reply("Debug " + (CommonListeners.debug() ? "enabled" : "disabled"));
|
|
||||||
else
|
else
|
||||||
message.reply("You need to be a moderator to use this command.");
|
sender.sendMessage("you need to be a moderator to use this command.");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public String[] getHelpText() {
|
|
||||||
return new String[]{"Switches debug mode."};
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,62 +0,0 @@
|
||||||
package buttondevteam.discordplugin.commands;
|
|
||||||
|
|
||||||
import buttondevteam.discordplugin.DiscordPlugin;
|
|
||||||
import buttondevteam.discordplugin.mcchat.MCChatCommand;
|
|
||||||
import buttondevteam.lib.TBMCCoreAPI;
|
|
||||||
import sx.blah.discord.handle.obj.IMessage;
|
|
||||||
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
|
||||||
import static buttondevteam.discordplugin.listeners.CommonListeners.debug;
|
|
||||||
|
|
||||||
public abstract class DiscordCommandBase {
|
|
||||||
public abstract String getCommandName();
|
|
||||||
|
|
||||||
public abstract boolean run(IMessage message, String args);
|
|
||||||
|
|
||||||
public abstract String[] getHelpText();
|
|
||||||
|
|
||||||
static final HashMap<String, DiscordCommandBase> commands = new HashMap<String, DiscordCommandBase>();
|
|
||||||
|
|
||||||
public static void registerCommands() {
|
|
||||||
commands.put("connect", new ConnectCommand()); // TODO: API for adding commands?
|
|
||||||
commands.put("userinfo", new UserinfoCommand());
|
|
||||||
commands.put("help", new HelpCommand());
|
|
||||||
commands.put("mcchat", new MCChatCommand());
|
|
||||||
commands.put("channelcon", new ChannelconCommand());
|
|
||||||
commands.put("debug", new DebugCommand());
|
|
||||||
commands.put("version", new VersionCommand());
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void runCommand(String cmd, String args, IMessage message) {
|
|
||||||
debug("F"); //Not sure if needed
|
|
||||||
DiscordCommandBase command = commands.get(cmd);
|
|
||||||
if (command == null) {
|
|
||||||
DiscordPlugin.sendMessageToChannel(message.getChannel(),
|
|
||||||
"Unknown command: " + cmd + " with args: " + args + "\nDo '"
|
|
||||||
+ (message.getChannel().isPrivate() ? "" : message.getClient().getOurUser().mention() + " ")
|
|
||||||
+ "help' for help");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
debug("G");
|
|
||||||
try {
|
|
||||||
if (!command.run(message, args))
|
|
||||||
DiscordPlugin.sendMessageToChannel(message.getChannel(), Arrays.stream(command.getHelpText()).collect(Collectors.joining("\n")));
|
|
||||||
} catch (Exception e) {
|
|
||||||
TBMCCoreAPI.SendException("An error occured while executing command " + cmd + "!", e);
|
|
||||||
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.");
|
|
||||||
}
|
|
||||||
debug("H");
|
|
||||||
}
|
|
||||||
|
|
||||||
protected String[] splitargs(String args) {
|
|
||||||
return args.split("\\s+");
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void registerCommand(String name, DiscordCommandBase dcb) {
|
|
||||||
commands.put(name, dcb);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,38 +1,18 @@
|
||||||
package buttondevteam.discordplugin.commands;
|
package buttondevteam.discordplugin.commands;
|
||||||
|
|
||||||
import buttondevteam.discordplugin.DiscordPlugin;
|
import buttondevteam.lib.chat.CommandClass;
|
||||||
import sx.blah.discord.handle.obj.IMessage;
|
|
||||||
|
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
|
||||||
public class HelpCommand extends DiscordCommandBase {
|
|
||||||
|
|
||||||
|
@CommandClass(helpText = {
|
||||||
|
"Help command", //
|
||||||
|
"Shows some info about a command or lists the available commands.", //
|
||||||
|
})
|
||||||
|
public class HelpCommand extends ICommand2DC {
|
||||||
@Override
|
@Override
|
||||||
public String getCommandName() {
|
public boolean def(Command2DCSender sender, String args) {
|
||||||
return "help";
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean run(IMessage message, String args) {
|
|
||||||
DiscordCommandBase argdc;
|
|
||||||
if (args.length() == 0)
|
if (args.length() == 0)
|
||||||
DiscordPlugin.sendMessageToChannel(message.getChannel(),
|
sender.sendMessage(getManager().getCommandsText());
|
||||||
"Available commands:\n" + DiscordCommandBase.commands.values().stream()
|
|
||||||
.map(dc -> DiscordPlugin.getPrefix() + dc.getCommandName()).collect(Collectors.joining("\n")));
|
|
||||||
else
|
else
|
||||||
DiscordPlugin.sendMessageToChannel(message.getChannel(),
|
sender.sendMessage("Soon:tm:"); //TODO
|
||||||
(argdc = DiscordCommandBase.commands.get(args)) == null ? "Command not found: " + args
|
|
||||||
: String.join("\n", argdc.getHelpText()));
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public String[] getHelpText() {
|
|
||||||
return new String[] { //
|
|
||||||
"---- Help command ----", //
|
|
||||||
"Shows some info about a command or lists the available commands.", //
|
|
||||||
"Usage: " + DiscordPlugin.getPrefix() + "help [command]"//
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,20 @@
|
||||||
|
package buttondevteam.discordplugin.commands;
|
||||||
|
|
||||||
|
import buttondevteam.discordplugin.DiscordPlugin;
|
||||||
|
import buttondevteam.lib.chat.CommandClass;
|
||||||
|
import buttondevteam.lib.chat.ICommand2;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.val;
|
||||||
|
|
||||||
|
public abstract class ICommand2DC extends ICommand2<Command2DCSender> {
|
||||||
|
public <T extends ICommand2> ICommand2DC() {
|
||||||
|
super(DiscordPlugin.plugin.getManager());
|
||||||
|
val ann = getClass().getAnnotation(CommandClass.class);
|
||||||
|
if (ann == null)
|
||||||
|
modOnly = false;
|
||||||
|
else
|
||||||
|
modOnly = ann.modOnly();
|
||||||
|
}
|
||||||
|
|
||||||
|
private final @Getter boolean modOnly;
|
||||||
|
}
|
|
@ -3,8 +3,11 @@ package buttondevteam.discordplugin.commands;
|
||||||
import buttondevteam.discordplugin.DiscordPlayer;
|
import buttondevteam.discordplugin.DiscordPlayer;
|
||||||
import buttondevteam.discordplugin.DiscordPlugin;
|
import buttondevteam.discordplugin.DiscordPlugin;
|
||||||
import buttondevteam.lib.TBMCCoreAPI;
|
import buttondevteam.lib.TBMCCoreAPI;
|
||||||
|
import buttondevteam.lib.chat.Command2;
|
||||||
|
import buttondevteam.lib.chat.CommandClass;
|
||||||
import buttondevteam.lib.player.ChromaGamerBase;
|
import buttondevteam.lib.player.ChromaGamerBase;
|
||||||
import buttondevteam.lib.player.ChromaGamerBase.InfoTarget;
|
import buttondevteam.lib.player.ChromaGamerBase.InfoTarget;
|
||||||
|
import lombok.val;
|
||||||
import sx.blah.discord.handle.obj.IMessage;
|
import sx.blah.discord.handle.obj.IMessage;
|
||||||
import sx.blah.discord.handle.obj.IUser;
|
import sx.blah.discord.handle.obj.IUser;
|
||||||
|
|
||||||
|
@ -12,29 +15,29 @@ import java.util.List;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
public class UserinfoCommand extends DiscordCommandBase {
|
@CommandClass(helpText = {
|
||||||
|
"User information", //
|
||||||
@Override
|
"Shows some information about users, from Discord, from Minecraft or from Reddit if they have these accounts connected.", //
|
||||||
public String getCommandName() {
|
"If used without args, shows your info.", //
|
||||||
return "userinfo";
|
})
|
||||||
}
|
public class UserinfoCommand extends ICommand2DC {
|
||||||
|
@Command2.Subcommand
|
||||||
@Override
|
public boolean def(Command2DCSender sender, @Command2.OptionalArg @Command2.TextArg String user) {
|
||||||
public boolean run(IMessage message, String args) {
|
val message = sender.getMessage();
|
||||||
IUser target = null;
|
IUser target = null;
|
||||||
if (args.length() == 0)
|
if (user == null || user.length() == 0)
|
||||||
target = message.getAuthor();
|
target = message.getAuthor();
|
||||||
else {
|
else {
|
||||||
final Optional<IUser> firstmention = message.getMentions().stream()
|
final Optional<IUser> firstmention = message.getMentions().stream()
|
||||||
.filter(m -> !m.getStringID().equals(DiscordPlugin.dc.getOurUser().getStringID())).findFirst();
|
.filter(m -> !m.getStringID().equals(DiscordPlugin.dc.getOurUser().getStringID())).findFirst();
|
||||||
if (firstmention.isPresent())
|
if (firstmention.isPresent())
|
||||||
target = firstmention.get();
|
target = firstmention.get();
|
||||||
else if (args.contains("#")) {
|
else if (user.contains("#")) {
|
||||||
String[] targettag = args.split("#");
|
String[] targettag = user.split("#");
|
||||||
final List<IUser> targets = getUsers(message, targettag[0]);
|
final List<IUser> targets = getUsers(message, targettag[0]);
|
||||||
if (targets.size() == 0) {
|
if (targets.size() == 0) {
|
||||||
DiscordPlugin.sendMessageToChannel(message.getChannel(),
|
DiscordPlugin.sendMessageToChannel(message.getChannel(),
|
||||||
"The user cannot be found (by name): " + args);
|
"The user cannot be found (by name): " + user);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
for (IUser ptarget : targets) {
|
for (IUser ptarget : targets) {
|
||||||
|
@ -45,15 +48,15 @@ public class UserinfoCommand extends DiscordCommandBase {
|
||||||
}
|
}
|
||||||
if (target == null) {
|
if (target == null) {
|
||||||
DiscordPlugin.sendMessageToChannel(message.getChannel(),
|
DiscordPlugin.sendMessageToChannel(message.getChannel(),
|
||||||
"The user cannot be found (by discriminator): " + args + "(Found " + targets.size()
|
"The user cannot be found (by discriminator): " + user + "(Found " + targets.size()
|
||||||
+ " users with the name.)");
|
+ " users with the name.)");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
final List<IUser> targets = getUsers(message, args);
|
final List<IUser> targets = getUsers(message, user);
|
||||||
if (targets.size() == 0) {
|
if (targets.size() == 0) {
|
||||||
DiscordPlugin.sendMessageToChannel(message.getChannel(),
|
DiscordPlugin.sendMessageToChannel(message.getChannel(),
|
||||||
"The user cannot be found on Discord: " + args);
|
"The user cannot be found on Discord: " + user);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (targets.size() > 1) {
|
if (targets.size() > 1) {
|
||||||
|
@ -85,15 +88,4 @@ public class UserinfoCommand extends DiscordCommandBase {
|
||||||
return targets;
|
return targets;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public String[] getHelpText() {
|
|
||||||
return new String[] { //
|
|
||||||
"---- User information ----", //
|
|
||||||
"Shows some information about users, from Discord, from Minecraft or from Reddit if they have these accounts connected.", //
|
|
||||||
"If used without args, shows your info.", //
|
|
||||||
"Usage: " + DiscordPlugin.getPrefix() + "userinfo [username/nickname[#tag]/ping]", //
|
|
||||||
"Examples:\n" + DiscordPlugin.getPrefix() + "userinfo ChromaBot\n" + DiscordPlugin.getPrefix() + "userinfo ChromaBot#6338\n" + DiscordPlugin.getPrefix() + "userinfo @ChromaBot#6338" //
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,26 +1,21 @@
|
||||||
package buttondevteam.discordplugin.commands;
|
package buttondevteam.discordplugin.commands;
|
||||||
|
|
||||||
import buttondevteam.discordplugin.DiscordPlugin;
|
import buttondevteam.discordplugin.DiscordPlugin;
|
||||||
|
import buttondevteam.lib.chat.Command2;
|
||||||
|
import buttondevteam.lib.chat.CommandClass;
|
||||||
import lombok.val;
|
import lombok.val;
|
||||||
import sx.blah.discord.handle.obj.IMessage;
|
|
||||||
|
|
||||||
public class VersionCommand extends DiscordCommandBase {
|
@CommandClass(helpText = {
|
||||||
@Override
|
"Version",
|
||||||
public String getCommandName() {
|
"Returns the plugin's version"
|
||||||
return "version";
|
})
|
||||||
}
|
public class VersionCommand extends ICommand2DC {
|
||||||
|
@Command2.Subcommand
|
||||||
@Override
|
public boolean def(Command2DCSender sender) {
|
||||||
public boolean run(IMessage message, String args) {
|
sender.sendMessage(getVersion());
|
||||||
DiscordPlugin.sendMessageToChannel(message.getChannel(), String.join("\n", getVersion()));
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public String[] getHelpText() {
|
|
||||||
return VersionCommand.getVersion(); //Heh
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String[] getVersion() {
|
public static String[] getVersion() {
|
||||||
val desc = DiscordPlugin.plugin.getDescription();
|
val desc = DiscordPlugin.plugin.getDescription();
|
||||||
return new String[]{ //
|
return new String[]{ //
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
package buttondevteam.discordplugin.exceptions;
|
package buttondevteam.discordplugin.exceptions;
|
||||||
|
|
||||||
|
import buttondevteam.core.ComponentManager;
|
||||||
import buttondevteam.discordplugin.DiscordPlugin;
|
import buttondevteam.discordplugin.DiscordPlugin;
|
||||||
import buttondevteam.lib.TBMCDebugMessageEvent;
|
import buttondevteam.lib.TBMCDebugMessageEvent;
|
||||||
import org.bukkit.event.EventHandler;
|
import org.bukkit.event.EventHandler;
|
||||||
|
@ -13,7 +14,7 @@ public class DebugMessageListener implements Listener{
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void SendMessage(String message) {
|
private static void SendMessage(String message) {
|
||||||
if (DiscordPlugin.SafeMode)
|
if (DiscordPlugin.SafeMode || !ComponentManager.isEnabled(ExceptionListenerModule.class))
|
||||||
return;
|
return;
|
||||||
try {
|
try {
|
||||||
StringBuilder sb = new StringBuilder();
|
StringBuilder sb = new StringBuilder();
|
||||||
|
@ -22,7 +23,7 @@ public class DebugMessageListener implements Listener{
|
||||||
message = message.substring(0, 2000);
|
message = message.substring(0, 2000);
|
||||||
sb.append(message).append("\n");
|
sb.append(message).append("\n");
|
||||||
sb.append("```");
|
sb.append("```");
|
||||||
DiscordPlugin.sendMessageToChannel(DiscordPlugin.botroomchannel, sb.toString());
|
DiscordPlugin.sendMessageToChannel(ExceptionListenerModule.getChannel(), sb.toString());
|
||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
ex.printStackTrace();
|
ex.printStackTrace();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,14 +1,18 @@
|
||||||
package buttondevteam.discordplugin.exceptions;
|
package buttondevteam.discordplugin.exceptions;
|
||||||
|
|
||||||
import buttondevteam.core.ComponentManager;
|
import buttondevteam.core.ComponentManager;
|
||||||
|
import buttondevteam.discordplugin.DPUtils;
|
||||||
import buttondevteam.discordplugin.DiscordPlugin;
|
import buttondevteam.discordplugin.DiscordPlugin;
|
||||||
import buttondevteam.lib.TBMCCoreAPI;
|
import buttondevteam.lib.TBMCCoreAPI;
|
||||||
import buttondevteam.lib.TBMCExceptionEvent;
|
import buttondevteam.lib.TBMCExceptionEvent;
|
||||||
import buttondevteam.lib.architecture.Component;
|
import buttondevteam.lib.architecture.Component;
|
||||||
|
import buttondevteam.lib.architecture.ConfigData;
|
||||||
import org.apache.commons.lang.exception.ExceptionUtils;
|
import org.apache.commons.lang.exception.ExceptionUtils;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.event.EventHandler;
|
import org.bukkit.event.EventHandler;
|
||||||
import org.bukkit.event.Listener;
|
import org.bukkit.event.Listener;
|
||||||
|
import sx.blah.discord.handle.obj.IChannel;
|
||||||
|
import sx.blah.discord.handle.obj.IGuild;
|
||||||
import sx.blah.discord.handle.obj.IRole;
|
import sx.blah.discord.handle.obj.IRole;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
@ -16,7 +20,7 @@ import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
public class ExceptionListenerModule extends Component implements Listener {
|
public class ExceptionListenerModule extends Component<DiscordPlugin> implements Listener {
|
||||||
private List<Throwable> lastthrown = new ArrayList<>();
|
private List<Throwable> lastthrown = new ArrayList<>();
|
||||||
private List<String> lastsourcemsg = new ArrayList<>();
|
private List<String> lastsourcemsg = new ArrayList<>();
|
||||||
|
|
||||||
|
@ -40,14 +44,14 @@ public class ExceptionListenerModule extends Component implements Listener {
|
||||||
e.setHandled();
|
e.setHandled();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static IRole coderRole;
|
|
||||||
|
|
||||||
private static void SendException(Throwable e, String sourcemessage) {
|
private static void SendException(Throwable e, String sourcemessage) {
|
||||||
|
if (instance == null) return;
|
||||||
try {
|
try {
|
||||||
if (coderRole == null)
|
IChannel channel = getChannel();
|
||||||
coderRole = DiscordPlugin.devServer.getRolesByName("Coder").get(0);
|
assert channel != null;
|
||||||
|
IRole coderRole = instance.pingRole(channel.getGuild()).get();
|
||||||
StringBuilder sb = TBMCCoreAPI.IsTestServer() ? new StringBuilder()
|
StringBuilder sb = TBMCCoreAPI.IsTestServer() ? new StringBuilder()
|
||||||
: new StringBuilder(coderRole.mention()).append("\n");
|
: new StringBuilder(coderRole == null ? "" : coderRole.mention()).append("\n");
|
||||||
sb.append(sourcemessage).append("\n");
|
sb.append(sourcemessage).append("\n");
|
||||||
sb.append("```").append("\n");
|
sb.append("```").append("\n");
|
||||||
String stackTrace = Arrays.stream(ExceptionUtils.getStackTrace(e).split("\\n"))
|
String stackTrace = Arrays.stream(ExceptionUtils.getStackTrace(e).split("\\n"))
|
||||||
|
@ -57,20 +61,37 @@ public class ExceptionListenerModule extends Component implements Listener {
|
||||||
stackTrace = stackTrace.substring(0, 1800);
|
stackTrace = stackTrace.substring(0, 1800);
|
||||||
sb.append(stackTrace).append("\n");
|
sb.append(stackTrace).append("\n");
|
||||||
sb.append("```");
|
sb.append("```");
|
||||||
DiscordPlugin.sendMessageToChannel(DiscordPlugin.botroomchannel, sb.toString());
|
DiscordPlugin.sendMessageToChannel(channel, sb.toString()); //Instance isn't null here
|
||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
ex.printStackTrace();
|
ex.printStackTrace();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static ExceptionListenerModule instance;
|
||||||
|
|
||||||
|
public static IChannel getChannel() {
|
||||||
|
if (instance != null) return instance.channel().get();
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private ConfigData<IChannel> channel() {
|
||||||
|
return DPUtils.channelData(getConfig(), "channel", 239519012529111040L);
|
||||||
|
}
|
||||||
|
|
||||||
|
private ConfigData<IRole> pingRole(IGuild guild) {
|
||||||
|
return DPUtils.roleData(getConfig(), "pingRole", "Coder", guild);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void enable() {
|
protected void enable() {
|
||||||
|
if (DPUtils.disableIfConfigError(this, channel())) return;
|
||||||
|
instance = this;
|
||||||
Bukkit.getPluginManager().registerEvents(new ExceptionListenerModule(), getPlugin());
|
Bukkit.getPluginManager().registerEvents(new ExceptionListenerModule(), getPlugin());
|
||||||
TBMCCoreAPI.RegisterEventsForExceptions(new DebugMessageListener(), getPlugin());
|
TBMCCoreAPI.RegisterEventsForExceptions(new DebugMessageListener(), getPlugin());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void disable() {
|
protected void disable() {
|
||||||
|
instance = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package buttondevteam.discordplugin.fun;
|
package buttondevteam.discordplugin.fun;
|
||||||
|
|
||||||
import buttondevteam.core.ComponentManager;
|
import buttondevteam.core.ComponentManager;
|
||||||
|
import buttondevteam.discordplugin.DPUtils;
|
||||||
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;
|
||||||
|
@ -12,9 +13,7 @@ import org.bukkit.event.EventHandler;
|
||||||
import org.bukkit.event.Listener;
|
import org.bukkit.event.Listener;
|
||||||
import org.bukkit.event.player.PlayerJoinEvent;
|
import org.bukkit.event.player.PlayerJoinEvent;
|
||||||
import sx.blah.discord.handle.impl.events.user.PresenceUpdateEvent;
|
import sx.blah.discord.handle.impl.events.user.PresenceUpdateEvent;
|
||||||
import sx.blah.discord.handle.obj.IMessage;
|
import sx.blah.discord.handle.obj.*;
|
||||||
import sx.blah.discord.handle.obj.IRole;
|
|
||||||
import sx.blah.discord.handle.obj.StatusType;
|
|
||||||
import sx.blah.discord.util.EmbedBuilder;
|
import sx.blah.discord.util.EmbedBuilder;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
@ -24,9 +23,7 @@ import java.util.Random;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
import java.util.stream.IntStream;
|
import java.util.stream.IntStream;
|
||||||
|
|
||||||
public class FunModule extends Component implements Listener {
|
public class FunModule extends Component<DiscordPlugin> implements Listener {
|
||||||
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
|
||||||
"Between now and the heat-death of the universe.", // Ghostise
|
"Between now and the heat-death of the universe.", // Ghostise
|
||||||
"Soon™", "Ask again this time next month", // Ghostise
|
"Soon™", "Ask again this time next month", // Ghostise
|
||||||
|
@ -66,7 +63,6 @@ public class FunModule extends Component implements Listener {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void enable() {
|
protected void enable() {
|
||||||
mod = this;
|
|
||||||
registerListener(this);
|
registerListener(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -97,7 +93,7 @@ public class FunModule extends Component implements Listener {
|
||||||
return true; //Handled
|
return true; //Handled
|
||||||
}
|
}
|
||||||
lastlistp = (short) Bukkit.getOnlinePlayers().size(); //Didn't handle
|
lastlistp = (short) Bukkit.getOnlinePlayers().size(); //Didn't handle
|
||||||
if (mod.serverReady().get()) {
|
if (fm.serverReady().get()) {
|
||||||
if (!TBMCCoreAPI.IsTestServer()
|
if (!TBMCCoreAPI.IsTestServer()
|
||||||
&& Arrays.stream(serverReadyQuestions).anyMatch(msglowercased::contains)) {
|
&& Arrays.stream(serverReadyQuestions).anyMatch(msglowercased::contains)) {
|
||||||
int next;
|
int next;
|
||||||
|
@ -116,11 +112,13 @@ public class FunModule extends Component implements Listener {
|
||||||
ListC = 0;
|
ListC = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
private ConfigData<IRole> fullHouseDevRole() {
|
private ConfigData<IRole> fullHouseDevRole(IGuild guild) {
|
||||||
return getConfig().getDataPrimDef("fullHouseDevRole", "Developer", name -> {
|
return DPUtils.roleData(getConfig(), "fullHouseDevRole", "Developer", guild);
|
||||||
val list = DiscordPlugin.devServer.getRolesByName((String) name);
|
}
|
||||||
return list.size() > 0 ? list.get(0) : null;
|
|
||||||
}, IRole::getName);
|
|
||||||
|
private ConfigData<IChannel> fullHouseChannel() {
|
||||||
|
return DPUtils.channelData(getConfig(), "fullHouseChannel", 219626707458457603L);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static long lasttime = 0;
|
private static long lasttime = 0;
|
||||||
|
@ -128,17 +126,19 @@ public class FunModule extends Component implements Listener {
|
||||||
public static void handleFullHouse(PresenceUpdateEvent event) {
|
public static void handleFullHouse(PresenceUpdateEvent event) {
|
||||||
val fm = ComponentManager.getIfEnabled(FunModule.class);
|
val fm = ComponentManager.getIfEnabled(FunModule.class);
|
||||||
if (fm == null) return;
|
if (fm == null) return;
|
||||||
val devrole = fm.fullHouseDevRole().get();
|
val channel = fm.fullHouseChannel().get();
|
||||||
|
if (channel == null) return;
|
||||||
|
val devrole = fm.fullHouseDevRole(channel.getGuild()).get();
|
||||||
if (devrole == null) return;
|
if (devrole == null) return;
|
||||||
if (event.getOldPresence().getStatus().equals(StatusType.OFFLINE)
|
if (event.getOldPresence().getStatus().equals(StatusType.OFFLINE)
|
||||||
&& !event.getNewPresence().getStatus().equals(StatusType.OFFLINE)
|
&& !event.getNewPresence().getStatus().equals(StatusType.OFFLINE)
|
||||||
&& event.getUser().getRolesForGuild(DiscordPlugin.devServer).stream()
|
&& event.getUser().getRolesForGuild(channel.getGuild()).stream()
|
||||||
.anyMatch(r -> r.getLongID() == devrole.getLongID())
|
.anyMatch(r -> r.getLongID() == devrole.getLongID())
|
||||||
&& DiscordPlugin.devServer.getUsersByRole(devrole).stream()
|
&& channel.getGuild().getUsersByRole(devrole).stream()
|
||||||
.noneMatch(u -> u.getPresence().getStatus().equals(StatusType.OFFLINE))
|
.noneMatch(u -> u.getPresence().getStatus().equals(StatusType.OFFLINE))
|
||||||
&& lasttime + 10 < TimeUnit.NANOSECONDS.toHours(System.nanoTime())
|
&& lasttime + 10 < TimeUnit.NANOSECONDS.toHours(System.nanoTime())
|
||||||
&& Calendar.getInstance().get(Calendar.DAY_OF_MONTH) % 5 == 0) {
|
&& Calendar.getInstance().get(Calendar.DAY_OF_MONTH) % 5 == 0) {
|
||||||
DiscordPlugin.sendMessageToChannel(DiscordPlugin.devofficechannel, "Full house!",
|
DiscordPlugin.sendMessageToChannel(channel, "Full house!",
|
||||||
new EmbedBuilder()
|
new EmbedBuilder()
|
||||||
.withImage(
|
.withImage(
|
||||||
"https://cdn.discordapp.com/attachments/249295547263877121/249687682618359808/poker-hand-full-house-aces-kings-playing-cards-15553791.png")
|
"https://cdn.discordapp.com/attachments/249295547263877121/249687682618359808/poker-hand-full-house-aces-kings-playing-cards-15553791.png")
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
package buttondevteam.discordplugin.listeners;
|
package buttondevteam.discordplugin.listeners;
|
||||||
|
|
||||||
import buttondevteam.discordplugin.DiscordPlugin;
|
import buttondevteam.discordplugin.DiscordPlugin;
|
||||||
import buttondevteam.discordplugin.commands.DiscordCommandBase;
|
import buttondevteam.discordplugin.commands.Command2DCSender;
|
||||||
|
import buttondevteam.lib.TBMCCoreAPI;
|
||||||
import sx.blah.discord.handle.obj.IChannel;
|
import sx.blah.discord.handle.obj.IChannel;
|
||||||
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;
|
||||||
|
@ -20,7 +21,7 @@ public class CommandListener {
|
||||||
final IChannel channel = message.getChannel();
|
final IChannel channel = message.getChannel();
|
||||||
if (!mentionedonly) { //mentionedonly conditions are in CommonListeners
|
if (!mentionedonly) { //mentionedonly conditions are in CommonListeners
|
||||||
if (!message.getChannel().isPrivate()
|
if (!message.getChannel().isPrivate()
|
||||||
&& !(message.getContent().charAt(0) == DiscordPlugin.getPrefix()
|
&& !(message.getContent().charAt(0) == DiscordPlugin.getPrefix()
|
||||||
&& channel.getStringID().equals(DiscordPlugin.plugin.CommandChannel().get().getStringID()))) //
|
&& channel.getStringID().equals(DiscordPlugin.plugin.CommandChannel().get().getStringID()))) //
|
||||||
return false;
|
return false;
|
||||||
message.getChannel().setTypingStatus(true); // Fun
|
message.getChannel().setTypingStatus(true); // Fun
|
||||||
|
@ -37,36 +38,36 @@ public class CommandListener {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
message.getChannel().setTypingStatus(true);
|
message.getChannel().setTypingStatus(true);
|
||||||
String cmdwithargsString = cmdwithargs.toString().trim(); //Remove spaces between mention and command
|
String cmdwithargsString = cmdwithargs.toString();
|
||||||
int index = cmdwithargsString.indexOf(" ");
|
try {
|
||||||
String cmd;
|
if (!DiscordPlugin.plugin.getManager().handleCommand(new Command2DCSender(message), cmdwithargsString))
|
||||||
String args;
|
message.reply("Unknown command. Do " + DiscordPlugin.getPrefix() + "help for help.\n" + cmdwithargsString);
|
||||||
if (index == -1) {
|
} catch (Exception e) {
|
||||||
cmd = cmdwithargsString;
|
TBMCCoreAPI.SendException("Failed to process Discord command: " + cmdwithargsString, e);
|
||||||
args = "";
|
|
||||||
} else {
|
|
||||||
cmd = cmdwithargsString.substring(0, index);
|
|
||||||
args = cmdwithargsString.substring(index + 1).trim(); //In case there are multiple spaces
|
|
||||||
}
|
}
|
||||||
DiscordCommandBase.runCommand(cmd.toLowerCase(), args, message);
|
|
||||||
message.getChannel().setTypingStatus(false);
|
message.getChannel().setTypingStatus(false);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean checkanddeletemention(StringBuilder cmdwithargs, String mention, IMessage message) {
|
private static boolean checkanddeletemention(StringBuilder cmdwithargs, String mention, IMessage message) {
|
||||||
if (message.getContent().startsWith(mention)) // TODO: Resolve mentions: Compound arguments, either a mention or text
|
if (message.getContent().startsWith(mention)) // TODO: Resolve mentions: Compound arguments, either a mention or text
|
||||||
if (cmdwithargs.length() > mention.length() + 1)
|
if (cmdwithargs.length() > mention.length() + 1) {
|
||||||
cmdwithargs.delete(0,
|
int i = cmdwithargs.indexOf(" ", mention.length());
|
||||||
cmdwithargs.charAt(mention.length()) == ' ' ? mention.length() + 1 : mention.length());
|
if (i == -1)
|
||||||
else
|
i = mention.length();
|
||||||
cmdwithargs.replace(0, cmdwithargs.length(), "help");
|
else
|
||||||
|
//noinspection StatementWithEmptyBody
|
||||||
|
for (; i < cmdwithargs.length() && cmdwithargs.charAt(i) == ' '; i++)
|
||||||
|
; //Removes any space before the command
|
||||||
|
cmdwithargs.delete(0, i);
|
||||||
|
cmdwithargs.insert(0, DiscordPlugin.getPrefix()); //Always use the prefix for processing
|
||||||
|
} else
|
||||||
|
cmdwithargs.replace(0, cmdwithargs.length(), DiscordPlugin.getPrefix() + "help");
|
||||||
else {
|
else {
|
||||||
if (cmdwithargs.length() > 0 && cmdwithargs.charAt(0) == '/')
|
return false; //Don't treat / as mention, mentions can be used in public mcchat
|
||||||
cmdwithargs.deleteCharAt(0); //Don't treat / as mention, mentions can be used in public mcchat
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
if (cmdwithargs.length() == 0)
|
if (cmdwithargs.length() == 0)
|
||||||
cmdwithargs.replace(0, cmdwithargs.length(), "help");
|
cmdwithargs.replace(0, cmdwithargs.length(), DiscordPlugin.getPrefix() + "help");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,7 @@ import buttondevteam.discordplugin.DiscordPlugin;
|
||||||
import buttondevteam.discordplugin.fun.FunModule;
|
import buttondevteam.discordplugin.fun.FunModule;
|
||||||
import buttondevteam.discordplugin.mcchat.MinecraftChatModule;
|
import buttondevteam.discordplugin.mcchat.MinecraftChatModule;
|
||||||
import buttondevteam.discordplugin.role.GameRoleModule;
|
import buttondevteam.discordplugin.role.GameRoleModule;
|
||||||
|
import buttondevteam.lib.TBMCCoreAPI;
|
||||||
import buttondevteam.lib.architecture.Component;
|
import buttondevteam.lib.architecture.Component;
|
||||||
import lombok.val;
|
import lombok.val;
|
||||||
import sx.blah.discord.api.events.IListener;
|
import sx.blah.discord.api.events.IListener;
|
||||||
|
@ -35,16 +36,21 @@ public class CommonListeners {
|
||||||
return;
|
return;
|
||||||
if (FunModule.executeMemes(event.getMessage()))
|
if (FunModule.executeMemes(event.getMessage()))
|
||||||
return;
|
return;
|
||||||
boolean handled = false;
|
try {
|
||||||
if (event.getChannel().getLongID() == DiscordPlugin.plugin.CommandChannel().get().getLongID() //If mentioned, that's higher than chat
|
boolean handled = false;
|
||||||
|
val commandChannel = DiscordPlugin.plugin.CommandChannel().get();
|
||||||
|
if ((commandChannel != null && event.getChannel().getLongID() == commandChannel.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
|
||||||
handled = CommandListener.runCommand(event.getMessage(), true); //#bot is handled here
|
handled = CommandListener.runCommand(event.getMessage(), true); //#bot is handled here
|
||||||
if (handled) return;
|
if (handled) return;
|
||||||
val mcchat = Component.getComponents().get(MinecraftChatModule.class);
|
val mcchat = Component.getComponents().get(MinecraftChatModule.class);
|
||||||
if (mcchat != null && mcchat.isEnabled()) //ComponentManager.isEnabled() searches the component again
|
if (mcchat != null && mcchat.isEnabled()) //ComponentManager.isEnabled() searches the component again
|
||||||
handled = ((MinecraftChatModule) mcchat).getListener().handleDiscord(event); //Also runs Discord commands in chat channels
|
handled = ((MinecraftChatModule) mcchat).getListener().handleDiscord(event); //Also runs Discord commands in chat channels
|
||||||
if (!handled)
|
if (!handled)
|
||||||
handled = CommandListener.runCommand(event.getMessage(), false);
|
handled = CommandListener.runCommand(event.getMessage(), false);
|
||||||
|
} catch (Exception e) {
|
||||||
|
TBMCCoreAPI.SendException("An error occured while handling a message!", e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}, new IListener<sx.blah.discord.handle.impl.events.user.PresenceUpdateEvent>() {
|
}, new IListener<sx.blah.discord.handle.impl.events.user.PresenceUpdateEvent>() {
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -5,21 +5,11 @@ import buttondevteam.discordplugin.DiscordPlugin;
|
||||||
import buttondevteam.discordplugin.commands.ConnectCommand;
|
import buttondevteam.discordplugin.commands.ConnectCommand;
|
||||||
import buttondevteam.lib.player.TBMCPlayerGetInfoEvent;
|
import buttondevteam.lib.player.TBMCPlayerGetInfoEvent;
|
||||||
import buttondevteam.lib.player.TBMCPlayerJoinEvent;
|
import buttondevteam.lib.player.TBMCPlayerJoinEvent;
|
||||||
import lombok.val;
|
|
||||||
import org.bukkit.Bukkit;
|
|
||||||
import org.bukkit.event.Event;
|
|
||||||
import org.bukkit.event.EventHandler;
|
import org.bukkit.event.EventHandler;
|
||||||
import org.bukkit.event.HandlerList;
|
|
||||||
import org.bukkit.event.Listener;
|
import org.bukkit.event.Listener;
|
||||||
import org.bukkit.event.server.ServerCommandEvent;
|
import org.bukkit.event.server.ServerCommandEvent;
|
||||||
import org.bukkit.plugin.AuthorNagException;
|
|
||||||
import org.bukkit.plugin.Plugin;
|
|
||||||
import org.bukkit.plugin.RegisteredListener;
|
|
||||||
import sx.blah.discord.handle.obj.IUser;
|
import sx.blah.discord.handle.obj.IUser;
|
||||||
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.logging.Level;
|
|
||||||
|
|
||||||
public class MCListener implements Listener {
|
public class MCListener implements Listener {
|
||||||
@EventHandler
|
@EventHandler
|
||||||
public void onPlayerJoin(TBMCPlayerJoinEvent e) {
|
public void onPlayerJoin(TBMCPlayerJoinEvent e) {
|
||||||
|
@ -50,67 +40,4 @@ public class MCListener implements Listener {
|
||||||
public void onServerCommand(ServerCommandEvent e) {
|
public void onServerCommand(ServerCommandEvent e) {
|
||||||
DiscordPlugin.Restart = !e.getCommand().equalsIgnoreCase("stop"); // The variable is always true except if stopped
|
DiscordPlugin.Restart = !e.getCommand().equalsIgnoreCase("stop"); // The variable is always true except if stopped
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final String[] EXCLUDED_PLUGINS = {"ProtocolLib", "LibsDisguises", "JourneyMapServer"}; //TODO: Make configurable
|
|
||||||
|
|
||||||
public static void callEventExcludingSome(Event event) {
|
|
||||||
callEventExcluding(event, false, EXCLUDED_PLUGINS);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Calls an event with the given details.
|
|
||||||
* <p>
|
|
||||||
* This method only synchronizes when the event is not asynchronous.
|
|
||||||
*
|
|
||||||
* @param event Event details
|
|
||||||
* @param only Flips the operation and <b>includes</b> the listed plugins
|
|
||||||
* @param plugins The plugins to exclude. Not case sensitive.
|
|
||||||
*/
|
|
||||||
public static void callEventExcluding(Event event, boolean only, String... plugins) { // Copied from Spigot-API and modified a bit
|
|
||||||
if (event.isAsynchronous()) {
|
|
||||||
if (Thread.holdsLock(Bukkit.getPluginManager())) {
|
|
||||||
throw new IllegalStateException(
|
|
||||||
event.getEventName() + " cannot be triggered asynchronously from inside synchronized code.");
|
|
||||||
}
|
|
||||||
if (Bukkit.getServer().isPrimaryThread()) {
|
|
||||||
throw new IllegalStateException(
|
|
||||||
event.getEventName() + " cannot be triggered asynchronously from primary server thread.");
|
|
||||||
}
|
|
||||||
fireEventExcluding(event, only, plugins);
|
|
||||||
} else {
|
|
||||||
synchronized (Bukkit.getPluginManager()) {
|
|
||||||
fireEventExcluding(event, only, plugins);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void fireEventExcluding(Event event, boolean only, String... plugins) {
|
|
||||||
HandlerList handlers = event.getHandlers(); // Code taken from SimplePluginManager in Spigot-API
|
|
||||||
RegisteredListener[] listeners = handlers.getRegisteredListeners();
|
|
||||||
val server = Bukkit.getServer();
|
|
||||||
|
|
||||||
for (RegisteredListener registration : listeners) {
|
|
||||||
if (!registration.getPlugin().isEnabled()
|
|
||||||
|| Arrays.stream(plugins).anyMatch(p -> only ^ p.equalsIgnoreCase(registration.getPlugin().getName())))
|
|
||||||
continue; // Modified to exclude plugins
|
|
||||||
|
|
||||||
try {
|
|
||||||
registration.callEvent(event);
|
|
||||||
} catch (AuthorNagException ex) {
|
|
||||||
Plugin plugin = registration.getPlugin();
|
|
||||||
|
|
||||||
if (plugin.isNaggable()) {
|
|
||||||
plugin.setNaggable(false);
|
|
||||||
|
|
||||||
server.getLogger().log(Level.SEVERE,
|
|
||||||
String.format("Nag author(s): '%s' of '%s' about the following: %s",
|
|
||||||
plugin.getDescription().getAuthors(), plugin.getDescription().getFullName(),
|
|
||||||
ex.getMessage()));
|
|
||||||
}
|
|
||||||
} catch (Throwable ex) {
|
|
||||||
server.getLogger().log(Level.SEVERE, "Could not pass event " + event.getEventName() + " to "
|
|
||||||
+ registration.getPlugin().getDescription().getFullName(), ex);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,150 @@
|
||||||
|
package buttondevteam.discordplugin.mcchat;
|
||||||
|
|
||||||
|
import buttondevteam.core.component.channel.Channel;
|
||||||
|
import buttondevteam.core.component.channel.ChatRoom;
|
||||||
|
import buttondevteam.discordplugin.*;
|
||||||
|
import buttondevteam.discordplugin.commands.Command2DCSender;
|
||||||
|
import buttondevteam.discordplugin.commands.ICommand2DC;
|
||||||
|
import buttondevteam.lib.TBMCSystemChatEvent;
|
||||||
|
import buttondevteam.lib.chat.Command2;
|
||||||
|
import buttondevteam.lib.chat.CommandClass;
|
||||||
|
import buttondevteam.lib.player.TBMCPlayer;
|
||||||
|
import lombok.val;
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
import sx.blah.discord.handle.obj.IMessage;
|
||||||
|
import sx.blah.discord.handle.obj.Permissions;
|
||||||
|
import sx.blah.discord.util.PermissionUtils;
|
||||||
|
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.function.Supplier;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
@CommandClass(helpText = {"Channel connect", //
|
||||||
|
"This command allows you to connect a Minecraft channel to a Discord channel (just like how the global chat is connected to #minecraft-chat).", //
|
||||||
|
"You need to have access to the MC channel and have manage permissions on the Discord channel.", //
|
||||||
|
"You also need to have your Minecraft account connected. In #bot use /connect <mcname>.", //
|
||||||
|
"Call this command from the channel you want to use.", //
|
||||||
|
"Usage: @Bot channelcon <mcchannel>", //
|
||||||
|
"Use the ID (command) of the channel, for example `g` for the global chat.", //
|
||||||
|
"To remove a connection use @ChromaBot channelcon remove in the channel.", //
|
||||||
|
"Mentioning the bot is needed in this case because the / prefix only works in #bot.", //
|
||||||
|
"Invite link: <https://discordapp.com/oauth2/authorize?client_id=226443037893591041&scope=bot&permissions=268509264>" //
|
||||||
|
})
|
||||||
|
public class ChannelconCommand extends ICommand2DC {
|
||||||
|
@Command2.Subcommand
|
||||||
|
public boolean remove(Command2DCSender sender) {
|
||||||
|
val message = sender.getMessage();
|
||||||
|
if (checkPerms(message)) return true;
|
||||||
|
if (MCChatCustom.removeCustomChat(message.getChannel()))
|
||||||
|
message.reply("channel connection removed.");
|
||||||
|
else
|
||||||
|
message.reply("this channel isn't connected.");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Command2.Subcommand
|
||||||
|
public boolean toggle(Command2DCSender sender, @Command2.OptionalArg String toggle) {
|
||||||
|
val message = sender.getMessage();
|
||||||
|
if (checkPerms(message)) return true;
|
||||||
|
val cc = MCChatCustom.getCustomChat(message.getChannel());
|
||||||
|
if (cc == null)
|
||||||
|
return respond(sender, "this channel isn't connected.");
|
||||||
|
Supplier<String> togglesString = () -> Arrays.stream(ChannelconBroadcast.values()).map(t -> t.toString().toLowerCase() + ": " + ((cc.toggles & t.flag) == 0 ? "disabled" : "enabled")).collect(Collectors.joining("\n"))
|
||||||
|
+ "\n\n" + TBMCSystemChatEvent.BroadcastTarget.stream().map(target -> target.getName() + ": " + (cc.brtoggles.contains(target) ? "enabled" : "disabled")).collect(Collectors.joining("\n"));
|
||||||
|
if (toggle == null) {
|
||||||
|
message.reply("toggles:\n" + togglesString.get());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
String arg = toggle.toUpperCase();
|
||||||
|
val b = Arrays.stream(ChannelconBroadcast.values()).filter(t -> t.toString().equals(arg)).findAny();
|
||||||
|
if (!b.isPresent()) {
|
||||||
|
val bt = TBMCSystemChatEvent.BroadcastTarget.get(arg);
|
||||||
|
if (bt == null) {
|
||||||
|
message.reply("cannot find toggle. Toggles:\n" + togglesString.get());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
final boolean add;
|
||||||
|
if (add = !cc.brtoggles.contains(bt))
|
||||||
|
cc.brtoggles.add(bt);
|
||||||
|
else
|
||||||
|
cc.brtoggles.remove(bt);
|
||||||
|
return respond(sender, "'" + bt.getName() + "' " + (add ? "en" : "dis") + "abled");
|
||||||
|
}
|
||||||
|
//A B | F
|
||||||
|
//------- A: original - B: mask - F: new
|
||||||
|
//0 0 | 0
|
||||||
|
//0 1 | 1
|
||||||
|
//1 0 | 1
|
||||||
|
//1 1 | 0
|
||||||
|
// XOR
|
||||||
|
cc.toggles ^= b.get().flag;
|
||||||
|
message.reply("'" + b.get().toString().toLowerCase() + "' " + ((cc.toggles & b.get().flag) == 0 ? "disabled" : "enabled"));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Command2.Subcommand
|
||||||
|
public boolean def(Command2DCSender sender, String channelID) {
|
||||||
|
val message = sender.getMessage();
|
||||||
|
if (checkPerms(message)) return true;
|
||||||
|
if (MCChatCustom.hasCustomChat(message.getChannel()))
|
||||||
|
return respond(sender, "this channel is already connected to a Minecraft channel. Use `@ChromaBot channelcon remove` to remove it.");
|
||||||
|
val chan = Channel.getChannels().filter(ch -> ch.ID.equalsIgnoreCase(channelID) || (Arrays.stream(ch.IDs().get()).anyMatch(cid -> cid.equalsIgnoreCase(channelID)))).findAny();
|
||||||
|
if (!chan.isPresent()) { //TODO: Red embed that disappears over time (kinda like the highlight messages in OW)
|
||||||
|
message.reply("MC channel with ID '" + channelID + "' not found! The ID is the command for it without the /.");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
val dp = DiscordPlayer.getUser(message.getAuthor().getStringID(), DiscordPlayer.class);
|
||||||
|
val chp = dp.getAs(TBMCPlayer.class);
|
||||||
|
if (chp == null) {
|
||||||
|
message.reply("you need to connect your Minecraft account. On our server in " + DPUtils.botmention() + " do " + DiscordPlugin.getPrefix() + "connect <MCname>");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
DiscordConnectedPlayer dcp = new DiscordConnectedPlayer(message.getAuthor(), message.getChannel(), chp.getUUID(), Bukkit.getOfflinePlayer(chp.getUUID()).getName());
|
||||||
|
//Using a fake player with no login/logout, should be fine for this event
|
||||||
|
String groupid = chan.get().getGroupID(dcp);
|
||||||
|
if (groupid == null && !(chan.get() instanceof ChatRoom)) { //ChatRooms don't allow it unless the user joins, which happens later
|
||||||
|
message.reply("sorry, you cannot use that Minecraft channel.");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (chan.get() instanceof ChatRoom) { //ChatRooms don't work well
|
||||||
|
message.reply("chat rooms are not supported yet.");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
/*if (MCChatListener.getCustomChats().stream().anyMatch(cc -> cc.groupID.equals(groupid) && cc.mcchannel.ID.equals(chan.get().ID))) {
|
||||||
|
message.reply("sorry, this MC chat is already connected to a different channel, multiple channels are not supported atm.");
|
||||||
|
return true;
|
||||||
|
}*/ //TODO: "Channel admins" that can connect channels?
|
||||||
|
MCChatCustom.addCustomChat(message.getChannel(), groupid, chan.get(), message.getAuthor(), dcp, 0, new HashSet<>());
|
||||||
|
if (chan.get() instanceof ChatRoom)
|
||||||
|
message.reply("alright, connection made to the room!");
|
||||||
|
else
|
||||||
|
message.reply("alright, connection made to group `" + groupid + "`!");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean checkPerms(IMessage message) {
|
||||||
|
if (!PermissionUtils.hasPermissions(message.getChannel(), message.getAuthor(), Permissions.MANAGE_CHANNEL)) {
|
||||||
|
message.reply("you need to have manage permissions for this channel!");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String[] getHelpText(Method method, Command2.Subcommand ann) {
|
||||||
|
return new String[]{ //
|
||||||
|
"Channel connect", //
|
||||||
|
"This command allows you to connect a Minecraft channel to a Discord channel (just like how the global chat is connected to #minecraft-chat).", //
|
||||||
|
"You need to have access to the MC channel and have manage permissions on the Discord channel.", //
|
||||||
|
"You also need to have your Minecraft account connected. In " + DPUtils.botmention() + " use " + DiscordPlugin.getPrefix() + "connect <mcname>.", //
|
||||||
|
"Call this command from the channel you want to use.", //
|
||||||
|
"Usage: @" + DiscordPlugin.dc.getOurUser().getName() + " channelcon <mcchannel>", //
|
||||||
|
"Use the ID (command) of the channel, for example `g` for the global chat.", //
|
||||||
|
"To remove a connection use @ChromaBot channelcon remove in the channel.", //
|
||||||
|
"Mentioning the bot is needed in this case because the " + DiscordPlugin.getPrefix() + " prefix only works in " + DPUtils.botmention() + ".", //
|
||||||
|
"Invite link: <https://discordapp.com/oauth2/authorize?client_id=226443037893591041&scope=bot&permissions=268509264>" // TODO: Set correct client ID
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
|
@ -2,44 +2,38 @@ package buttondevteam.discordplugin.mcchat;
|
||||||
|
|
||||||
import buttondevteam.discordplugin.DiscordPlayer;
|
import buttondevteam.discordplugin.DiscordPlayer;
|
||||||
import buttondevteam.discordplugin.DiscordPlugin;
|
import buttondevteam.discordplugin.DiscordPlugin;
|
||||||
import buttondevteam.discordplugin.commands.DiscordCommandBase;
|
import buttondevteam.discordplugin.commands.Command2DCSender;
|
||||||
|
import buttondevteam.discordplugin.commands.ICommand2DC;
|
||||||
import buttondevteam.lib.TBMCCoreAPI;
|
import buttondevteam.lib.TBMCCoreAPI;
|
||||||
import sx.blah.discord.handle.obj.IMessage;
|
import buttondevteam.lib.chat.Command2;
|
||||||
|
import buttondevteam.lib.chat.CommandClass;
|
||||||
|
import lombok.val;
|
||||||
|
|
||||||
public class MCChatCommand extends DiscordCommandBase {
|
@CommandClass(helpText = {
|
||||||
|
"MC Chat",
|
||||||
|
"This command enables or disables the Minecraft chat in private messages.", //
|
||||||
|
"It can be useful if you don't want your messages to be visible, for example when talking in a private channel.", //
|
||||||
|
"You can also run all of the ingame commands you have access to using this command, if you have your accounts connected." //
|
||||||
|
})
|
||||||
|
public class MCChatCommand extends ICommand2DC {
|
||||||
|
|
||||||
@Override
|
@Command2.Subcommand
|
||||||
public String getCommandName() {
|
public boolean def(Command2DCSender sender) {
|
||||||
return "mcchat";
|
val message = sender.getMessage();
|
||||||
}
|
|
||||||
|
|
||||||
@Override //TODO: Only register if module is enabled
|
|
||||||
public boolean run(IMessage message, String args) {
|
|
||||||
if (!message.getChannel().isPrivate()) {
|
if (!message.getChannel().isPrivate()) {
|
||||||
DiscordPlugin.sendMessageToChannel(message.getChannel(),
|
message.reply("this command can only be issued in a direct message with the bot.");
|
||||||
"This command can only be issued in a direct message with the bot.");
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
try (final DiscordPlayer user = DiscordPlayer.getUser(message.getAuthor().getStringID(), DiscordPlayer.class)) {
|
try (final DiscordPlayer user = DiscordPlayer.getUser(message.getAuthor().getStringID(), DiscordPlayer.class)) {
|
||||||
boolean mcchat = !user.isMinecraftChatEnabled();
|
boolean mcchat = !user.isMinecraftChatEnabled();
|
||||||
MCChatPrivate.privateMCChat(message.getChannel(), mcchat, message.getAuthor(), user);
|
MCChatPrivate.privateMCChat(message.getChannel(), mcchat, message.getAuthor(), user);
|
||||||
DiscordPlugin.sendMessageToChannel(message.getChannel(),
|
message.reply("Minecraft chat " + (mcchat //
|
||||||
"Minecraft chat " + (mcchat //
|
? "enabled. Use '" + DiscordPlugin.getPrefix() + "mcchat' again to turn it off." //
|
||||||
? "enabled. Use '" + DiscordPlugin.getPrefix() + "mcchat' again to turn it off." //
|
: "disabled."));
|
||||||
: "disabled."));
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
TBMCCoreAPI.SendException("Error while setting mcchat for user" + message.getAuthor().getName(), e);
|
TBMCCoreAPI.SendException("Error while setting mcchat for user" + message.getAuthor().getName(), e);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
} // TODO: Pin channel switching to indicate the current channel
|
||||||
|
|
||||||
@Override
|
|
||||||
public String[] getHelpText() {
|
|
||||||
return new String[] { //
|
|
||||||
DiscordPlugin.getPrefix() + "mcchat enables or disables the Minecraft chat in private messages.", //
|
|
||||||
"It can be useful if you don't want your messages to be visible, for example when talking in a private channel.", //
|
|
||||||
"You can also run all of the ingame commands you have access to using this command, if you have your accounts connected." //
|
|
||||||
}; // TODO: Pin channel switching to indicate the current channel
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,9 @@
|
||||||
package buttondevteam.discordplugin.mcchat;
|
package buttondevteam.discordplugin.mcchat;
|
||||||
|
|
||||||
import buttondevteam.core.component.channel.Channel;
|
import buttondevteam.core.component.channel.Channel;
|
||||||
|
import buttondevteam.core.component.channel.ChatRoom;
|
||||||
import buttondevteam.discordplugin.DiscordConnectedPlayer;
|
import buttondevteam.discordplugin.DiscordConnectedPlayer;
|
||||||
|
import buttondevteam.lib.TBMCSystemChatEvent;
|
||||||
import lombok.NonNull;
|
import lombok.NonNull;
|
||||||
import lombok.val;
|
import lombok.val;
|
||||||
import sx.blah.discord.handle.obj.IChannel;
|
import sx.blah.discord.handle.obj.IChannel;
|
||||||
|
@ -11,6 +13,7 @@ import javax.annotation.Nullable;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
public class MCChatCustom {
|
public class MCChatCustom {
|
||||||
/**
|
/**
|
||||||
|
@ -18,8 +21,12 @@ public class MCChatCustom {
|
||||||
*/
|
*/
|
||||||
static ArrayList<CustomLMD> lastmsgCustom = new ArrayList<>();
|
static ArrayList<CustomLMD> lastmsgCustom = new ArrayList<>();
|
||||||
|
|
||||||
public static void addCustomChat(IChannel channel, String groupid, Channel mcchannel, IUser user, DiscordConnectedPlayer dcp, int toggles) {
|
public static void addCustomChat(IChannel channel, String groupid, Channel mcchannel, IUser user, DiscordConnectedPlayer dcp, int toggles, Set<TBMCSystemChatEvent.BroadcastTarget> brtoggles) {
|
||||||
val lmd = new CustomLMD(channel, user, groupid, mcchannel, dcp, toggles);
|
if (mcchannel instanceof ChatRoom) {
|
||||||
|
((ChatRoom) mcchannel).joinRoom(dcp);
|
||||||
|
if (groupid == null) groupid = mcchannel.getGroupID(dcp);
|
||||||
|
}
|
||||||
|
val lmd = new CustomLMD(channel, user, groupid, mcchannel, dcp, toggles, brtoggles);
|
||||||
lastmsgCustom.add(lmd);
|
lastmsgCustom.add(lmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -34,7 +41,13 @@ public class MCChatCustom {
|
||||||
|
|
||||||
public static boolean removeCustomChat(IChannel channel) {
|
public static boolean removeCustomChat(IChannel channel) {
|
||||||
MCChatUtils.lastmsgfromd.remove(channel.getLongID());
|
MCChatUtils.lastmsgfromd.remove(channel.getLongID());
|
||||||
return lastmsgCustom.removeIf(lmd -> lmd.channel.getLongID() == channel.getLongID());
|
return lastmsgCustom.removeIf(lmd -> {
|
||||||
|
if (lmd.channel.getLongID() != channel.getLongID())
|
||||||
|
return false;
|
||||||
|
if (lmd.mcchannel instanceof ChatRoom)
|
||||||
|
((ChatRoom) lmd.mcchannel).leaveRoom(lmd.dcp);
|
||||||
|
return true;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public static List<CustomLMD> getCustomChats() {
|
public static List<CustomLMD> getCustomChats() {
|
||||||
|
@ -46,14 +59,16 @@ public class MCChatCustom {
|
||||||
public final Channel mcchannel;
|
public final Channel mcchannel;
|
||||||
public final DiscordConnectedPlayer dcp;
|
public final DiscordConnectedPlayer dcp;
|
||||||
public int toggles;
|
public int toggles;
|
||||||
|
public Set<TBMCSystemChatEvent.BroadcastTarget> brtoggles;
|
||||||
|
|
||||||
private CustomLMD(@NonNull IChannel channel, @NonNull IUser user,
|
private CustomLMD(@NonNull IChannel channel, @NonNull IUser user,
|
||||||
@NonNull String groupid, @NonNull Channel mcchannel, @NonNull DiscordConnectedPlayer dcp, int toggles) {
|
@NonNull String groupid, @NonNull Channel mcchannel, @NonNull DiscordConnectedPlayer dcp, int toggles, Set<TBMCSystemChatEvent.BroadcastTarget> brtoggles) {
|
||||||
super(channel, user);
|
super(channel, user);
|
||||||
groupID = groupid;
|
groupID = groupid;
|
||||||
this.mcchannel = mcchannel;
|
this.mcchannel = mcchannel;
|
||||||
this.dcp = dcp;
|
this.dcp = dcp;
|
||||||
this.toggles = toggles;
|
this.toggles = toggles;
|
||||||
|
this.brtoggles = brtoggles;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,10 +9,7 @@ import buttondevteam.discordplugin.DiscordSender;
|
||||||
import buttondevteam.discordplugin.DiscordSenderBase;
|
import buttondevteam.discordplugin.DiscordSenderBase;
|
||||||
import buttondevteam.discordplugin.listeners.CommandListener;
|
import buttondevteam.discordplugin.listeners.CommandListener;
|
||||||
import buttondevteam.discordplugin.playerfaker.VanillaCommandListener;
|
import buttondevteam.discordplugin.playerfaker.VanillaCommandListener;
|
||||||
import buttondevteam.lib.TBMCChatEvent;
|
import buttondevteam.lib.*;
|
||||||
import buttondevteam.lib.TBMCChatPreprocessEvent;
|
|
||||||
import buttondevteam.lib.TBMCCommandPreprocessEvent;
|
|
||||||
import buttondevteam.lib.TBMCCoreAPI;
|
|
||||||
import buttondevteam.lib.chat.ChatMessage;
|
import buttondevteam.lib.chat.ChatMessage;
|
||||||
import buttondevteam.lib.chat.TBMCChatAPI;
|
import buttondevteam.lib.chat.TBMCChatAPI;
|
||||||
import buttondevteam.lib.player.TBMCPlayer;
|
import buttondevteam.lib.player.TBMCPlayer;
|
||||||
|
@ -377,7 +374,7 @@ public class MCChatListener implements Listener {
|
||||||
: dsender.getChromaUser().channel().get().getRTR(dsender);
|
: dsender.getChromaUser().channel().get().getRTR(dsender);
|
||||||
TBMCChatAPI.SendSystemMessage(clmd != null ? clmd.mcchannel : dsender.getChromaUser().channel().get(), rtr,
|
TBMCChatAPI.SendSystemMessage(clmd != null ? clmd.mcchannel : dsender.getChromaUser().channel().get(), rtr,
|
||||||
(dsender instanceof Player ? ((Player) dsender).getDisplayName()
|
(dsender instanceof Player ? ((Player) dsender).getDisplayName()
|
||||||
: dsender.getName()) + " pinned a message on Discord.");
|
: dsender.getName()) + " pinned a message on Discord.", TBMCSystemChatEvent.BroadcastTarget.ALL);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
val cmb = ChatMessage.builder(dsender, user, getChatMessage.apply(dmessage)).fromCommand(false);
|
val cmb = ChatMessage.builder(dsender, user, getChatMessage.apply(dmessage)).fromCommand(false);
|
||||||
|
|
|
@ -15,8 +15,6 @@ import sx.blah.discord.handle.obj.IUser;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
|
||||||
import static buttondevteam.discordplugin.listeners.MCListener.callEventExcludingSome;
|
|
||||||
|
|
||||||
public class MCChatPrivate {
|
public class MCChatPrivate {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -60,11 +58,11 @@ public class MCChatPrivate {
|
||||||
for (val entry : MCChatUtils.ConnectedSenders.entrySet())
|
for (val entry : MCChatUtils.ConnectedSenders.entrySet())
|
||||||
for (val valueEntry : entry.getValue().entrySet())
|
for (val valueEntry : entry.getValue().entrySet())
|
||||||
if (MCChatUtils.getSender(MCChatUtils.OnlineSenders, valueEntry.getKey(), valueEntry.getValue().getUser()) == null) //If the player is online then the fake player was already logged out
|
if (MCChatUtils.getSender(MCChatUtils.OnlineSenders, valueEntry.getKey(), valueEntry.getValue().getUser()) == null) //If the player is online then the fake player was already logged out
|
||||||
callEventExcludingSome(new PlayerQuitEvent(valueEntry.getValue(), "")); //This is sync
|
MCChatUtils.callEventExcludingSome(new PlayerQuitEvent(valueEntry.getValue(), "")); //This is sync
|
||||||
MCChatUtils.ConnectedSenders.clear();
|
MCChatUtils.ConnectedSenders.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void callEventSync(Event event) {
|
private static void callEventSync(Event event) {
|
||||||
Bukkit.getScheduler().runTask(DiscordPlugin.plugin, () -> callEventExcludingSome(event));
|
Bukkit.getScheduler().runTask(DiscordPlugin.plugin, () -> MCChatUtils.callEventExcludingSome(event));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,17 +8,25 @@ import buttondevteam.lib.TBMCSystemChatEvent;
|
||||||
import io.netty.util.collection.LongObjectHashMap;
|
import io.netty.util.collection.LongObjectHashMap;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import lombok.experimental.var;
|
import lombok.experimental.var;
|
||||||
|
import lombok.val;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.command.CommandSender;
|
import org.bukkit.command.CommandSender;
|
||||||
|
import org.bukkit.event.Event;
|
||||||
|
import org.bukkit.event.HandlerList;
|
||||||
|
import org.bukkit.plugin.AuthorNagException;
|
||||||
|
import org.bukkit.plugin.Plugin;
|
||||||
|
import org.bukkit.plugin.RegisteredListener;
|
||||||
import sx.blah.discord.handle.obj.IChannel;
|
import sx.blah.discord.handle.obj.IChannel;
|
||||||
import sx.blah.discord.handle.obj.IMessage;
|
import sx.blah.discord.handle.obj.IMessage;
|
||||||
import sx.blah.discord.handle.obj.IUser;
|
import sx.blah.discord.handle.obj.IUser;
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
import java.util.function.Supplier;
|
import java.util.function.Supplier;
|
||||||
|
import java.util.logging.Level;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
|
@ -172,7 +180,7 @@ public class MCChatUtils {
|
||||||
if (event.shouldSendTo(getSender(data.channel, data.user)))
|
if (event.shouldSendTo(getSender(data.channel, data.user)))
|
||||||
action.accept(data.channel);
|
action.accept(data.channel);
|
||||||
MCChatCustom.lastmsgCustom.stream().filter(clmd -> {
|
MCChatCustom.lastmsgCustom.stream().filter(clmd -> {
|
||||||
if ((clmd.toggles & ChannelconBroadcast.BROADCAST.flag) == 0)
|
if (!clmd.brtoggles.contains(event.getTarget()))
|
||||||
return false;
|
return false;
|
||||||
return event.shouldSendTo(clmd.dcp);
|
return event.shouldSendTo(clmd.dcp);
|
||||||
}).map(clmd -> clmd.channel).forEach(action);
|
}).map(clmd -> clmd.channel).forEach(action);
|
||||||
|
@ -213,6 +221,69 @@ public class MCChatUtils {
|
||||||
//If it gets here, it's sending a message to a non-chat channel
|
//If it gets here, it's sending a message to a non-chat channel
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void callEventExcludingSome(Event event) {
|
||||||
|
if (notEnabled()) return;
|
||||||
|
callEventExcluding(event, false, module.excludedPlugins().get());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calls an event with the given details.
|
||||||
|
* <p>
|
||||||
|
* This method only synchronizes when the event is not asynchronous.
|
||||||
|
*
|
||||||
|
* @param event Event details
|
||||||
|
* @param only Flips the operation and <b>includes</b> the listed plugins
|
||||||
|
* @param plugins The plugins to exclude. Not case sensitive.
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("WeakerAccess")
|
||||||
|
public static void callEventExcluding(Event event, boolean only, String... plugins) { // Copied from Spigot-API and modified a bit
|
||||||
|
if (event.isAsynchronous()) {
|
||||||
|
if (Thread.holdsLock(Bukkit.getPluginManager())) {
|
||||||
|
throw new IllegalStateException(
|
||||||
|
event.getEventName() + " cannot be triggered asynchronously from inside synchronized code.");
|
||||||
|
}
|
||||||
|
if (Bukkit.getServer().isPrimaryThread()) {
|
||||||
|
throw new IllegalStateException(
|
||||||
|
event.getEventName() + " cannot be triggered asynchronously from primary server thread.");
|
||||||
|
}
|
||||||
|
fireEventExcluding(event, only, plugins);
|
||||||
|
} else {
|
||||||
|
synchronized (Bukkit.getPluginManager()) {
|
||||||
|
fireEventExcluding(event, only, plugins);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void fireEventExcluding(Event event, boolean only, String... plugins) {
|
||||||
|
HandlerList handlers = event.getHandlers(); // Code taken from SimplePluginManager in Spigot-API
|
||||||
|
RegisteredListener[] listeners = handlers.getRegisteredListeners();
|
||||||
|
val server = Bukkit.getServer();
|
||||||
|
|
||||||
|
for (RegisteredListener registration : listeners) {
|
||||||
|
if (!registration.getPlugin().isEnabled()
|
||||||
|
|| Arrays.stream(plugins).anyMatch(p -> only ^ p.equalsIgnoreCase(registration.getPlugin().getName())))
|
||||||
|
continue; // Modified to exclude plugins
|
||||||
|
|
||||||
|
try {
|
||||||
|
registration.callEvent(event);
|
||||||
|
} catch (AuthorNagException ex) {
|
||||||
|
Plugin plugin = registration.getPlugin();
|
||||||
|
|
||||||
|
if (plugin.isNaggable()) {
|
||||||
|
plugin.setNaggable(false);
|
||||||
|
|
||||||
|
server.getLogger().log(Level.SEVERE,
|
||||||
|
String.format("Nag author(s): '%s' of '%s' about the following: %s",
|
||||||
|
plugin.getDescription().getAuthors(), plugin.getDescription().getFullName(),
|
||||||
|
ex.getMessage()));
|
||||||
|
}
|
||||||
|
} catch (Throwable ex) {
|
||||||
|
server.getLogger().log(Level.SEVERE, "Could not pass event " + event.getEventName() + " to "
|
||||||
|
+ registration.getPlugin().getDescription().getFullName(), ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
public static class LastMsgData {
|
public static class LastMsgData {
|
||||||
public IMessage message;
|
public IMessage message;
|
||||||
|
|
|
@ -3,8 +3,10 @@ package buttondevteam.discordplugin.mcchat;
|
||||||
import buttondevteam.discordplugin.*;
|
import buttondevteam.discordplugin.*;
|
||||||
import buttondevteam.lib.TBMCCoreAPI;
|
import buttondevteam.lib.TBMCCoreAPI;
|
||||||
import buttondevteam.lib.TBMCSystemChatEvent;
|
import buttondevteam.lib.TBMCSystemChatEvent;
|
||||||
|
import buttondevteam.lib.architecture.ConfigData;
|
||||||
import buttondevteam.lib.player.*;
|
import buttondevteam.lib.player.*;
|
||||||
import com.earth2me.essentials.CommandSource;
|
import com.earth2me.essentials.CommandSource;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
import lombok.val;
|
import lombok.val;
|
||||||
import net.ess3.api.events.AfkStatusChangeEvent;
|
import net.ess3.api.events.AfkStatusChangeEvent;
|
||||||
import net.ess3.api.events.MuteStatusChangeEvent;
|
import net.ess3.api.events.MuteStatusChangeEvent;
|
||||||
|
@ -26,14 +28,17 @@ import sx.blah.discord.handle.obj.IUser;
|
||||||
import sx.blah.discord.util.DiscordException;
|
import sx.blah.discord.util.DiscordException;
|
||||||
import sx.blah.discord.util.MissingPermissionsException;
|
import sx.blah.discord.util.MissingPermissionsException;
|
||||||
|
|
||||||
|
@RequiredArgsConstructor
|
||||||
class MCListener implements Listener {
|
class MCListener implements Listener {
|
||||||
|
private final MinecraftChatModule module;
|
||||||
|
|
||||||
@EventHandler(priority = EventPriority.HIGHEST)
|
@EventHandler(priority = EventPriority.HIGHEST)
|
||||||
public void onPlayerLogin(PlayerLoginEvent e) {
|
public void onPlayerLogin(PlayerLoginEvent e) {
|
||||||
if (e.getResult() != Result.ALLOWED)
|
if (e.getResult() != Result.ALLOWED)
|
||||||
return;
|
return;
|
||||||
MCChatUtils.ConnectedSenders.values().stream().flatMap(v -> v.values().stream()) //Only private mcchat should be in ConnectedSenders
|
MCChatUtils.ConnectedSenders.values().stream().flatMap(v -> v.values().stream()) //Only private mcchat should be in ConnectedSenders
|
||||||
.filter(s -> s.getUniqueId().equals(e.getPlayer().getUniqueId())).findAny()
|
.filter(s -> s.getUniqueId().equals(e.getPlayer().getUniqueId())).findAny()
|
||||||
.ifPresent(dcp -> buttondevteam.discordplugin.listeners.MCListener.callEventExcludingSome(new PlayerQuitEvent(dcp, "")));
|
.ifPresent(dcp -> MCChatUtils.callEventExcludingSome(new PlayerQuitEvent(dcp, "")));
|
||||||
}
|
}
|
||||||
|
|
||||||
@EventHandler(priority = EventPriority.LOWEST)
|
@EventHandler(priority = EventPriority.LOWEST)
|
||||||
|
@ -46,9 +51,9 @@ class MCListener implements Listener {
|
||||||
if (dp != null) {
|
if (dp != null) {
|
||||||
val user = DiscordPlugin.dc.getUserByID(Long.parseLong(dp.getDiscordID()));
|
val user = DiscordPlugin.dc.getUserByID(Long.parseLong(dp.getDiscordID()));
|
||||||
MCChatUtils.addSender(MCChatUtils.OnlineSenders, dp.getDiscordID(),
|
MCChatUtils.addSender(MCChatUtils.OnlineSenders, dp.getDiscordID(),
|
||||||
new DiscordPlayerSender(user, user.getOrCreatePMChannel(), p));
|
new DiscordPlayerSender(user, user.getOrCreatePMChannel(), p));
|
||||||
MCChatUtils.addSender(MCChatUtils.OnlineSenders, dp.getDiscordID(),
|
MCChatUtils.addSender(MCChatUtils.OnlineSenders, dp.getDiscordID(),
|
||||||
new DiscordPlayerSender(user, DiscordPlugin.chatchannel, p)); //Stored per-channel
|
new DiscordPlayerSender(user, module.chatChannel().get(), p)); //Stored per-channel
|
||||||
}
|
}
|
||||||
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);
|
||||||
|
@ -61,13 +66,13 @@ class MCListener implements Listener {
|
||||||
if (e.getPlayer() instanceof DiscordConnectedPlayer)
|
if (e.getPlayer() instanceof DiscordConnectedPlayer)
|
||||||
return; // Only care about real users
|
return; // Only care about real users
|
||||||
MCChatUtils.OnlineSenders.entrySet()
|
MCChatUtils.OnlineSenders.entrySet()
|
||||||
.removeIf(entry -> entry.getValue().entrySet().stream().anyMatch(p -> p.getValue().getUniqueId().equals(e.getPlayer().getUniqueId())));
|
.removeIf(entry -> entry.getValue().entrySet().stream().anyMatch(p -> p.getValue().getUniqueId().equals(e.getPlayer().getUniqueId())));
|
||||||
Bukkit.getScheduler().runTask(DiscordPlugin.plugin,
|
Bukkit.getScheduler().runTask(DiscordPlugin.plugin,
|
||||||
() -> MCChatUtils.ConnectedSenders.values().stream().flatMap(v -> v.values().stream())
|
() -> MCChatUtils.ConnectedSenders.values().stream().flatMap(v -> v.values().stream())
|
||||||
.filter(s -> s.getUniqueId().equals(e.getPlayer().getUniqueId())).findAny()
|
.filter(s -> s.getUniqueId().equals(e.getPlayer().getUniqueId())).findAny()
|
||||||
.ifPresent(dcp -> buttondevteam.discordplugin.listeners.MCListener.callEventExcludingSome(new PlayerJoinEvent(dcp, ""))));
|
.ifPresent(dcp -> MCChatUtils.callEventExcludingSome(new PlayerJoinEvent(dcp, ""))));
|
||||||
Bukkit.getScheduler().runTaskLaterAsynchronously(DiscordPlugin.plugin,
|
Bukkit.getScheduler().runTaskLaterAsynchronously(DiscordPlugin.plugin,
|
||||||
ChromaBot.getInstance()::updatePlayerList, 5);
|
ChromaBot.getInstance()::updatePlayerList, 5);
|
||||||
final String message = e.GetPlayer().PlayerName().get() + " left the game";
|
final String message = e.GetPlayer().PlayerName().get() + " left the game";
|
||||||
MCChatUtils.forAllowedCustomAndAllMCChat(MCChatUtils.send(message), e.getPlayer(), ChannelconBroadcast.JOINLEAVE, true);
|
MCChatUtils.forAllowedCustomAndAllMCChat(MCChatUtils.send(message), e.getPlayer(), ChannelconBroadcast.JOINLEAVE, true);
|
||||||
}
|
}
|
||||||
|
@ -90,32 +95,41 @@ class MCListener implements Listener {
|
||||||
if (e.isCancelled() || !base.isOnline())
|
if (e.isCancelled() || !base.isOnline())
|
||||||
return;
|
return;
|
||||||
final String msg = base.getDisplayName()
|
final String msg = base.getDisplayName()
|
||||||
+ " is " + (e.getValue() ? "now" : "no longer") + " AFK.";
|
+ " is " + (e.getValue() ? "now" : "no longer") + " AFK.";
|
||||||
MCChatUtils.forAllowedCustomAndAllMCChat(MCChatUtils.send(msg), base, ChannelconBroadcast.AFK, false);
|
MCChatUtils.forAllowedCustomAndAllMCChat(MCChatUtils.send(msg), base, ChannelconBroadcast.AFK, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private ConfigData<IRole> muteRole() {
|
||||||
|
return DPUtils.roleData(module.getConfig(), "muteRole", "Muted");
|
||||||
|
}
|
||||||
|
|
||||||
@EventHandler
|
@EventHandler
|
||||||
public void onPlayerMute(MuteStatusChangeEvent e) {
|
public void onPlayerMute(MuteStatusChangeEvent e) {
|
||||||
try {
|
try {
|
||||||
DPUtils.performNoWait(() -> {
|
DPUtils.performNoWait(() -> {
|
||||||
final IRole role = DiscordPlugin.dc.getRoleByID(164090010461667328L); //TODO: Config
|
final IRole role = muteRole().get();
|
||||||
|
if (role == null) return;
|
||||||
final CommandSource source = e.getAffected().getSource();
|
final CommandSource source = e.getAffected().getSource();
|
||||||
if (!source.isPlayer())
|
if (!source.isPlayer())
|
||||||
return;
|
return;
|
||||||
final DiscordPlayer p = TBMCPlayerBase.getPlayer(source.getPlayer().getUniqueId(), TBMCPlayer.class)
|
final DiscordPlayer p = TBMCPlayerBase.getPlayer(source.getPlayer().getUniqueId(), TBMCPlayer.class)
|
||||||
.getAs(DiscordPlayer.class);
|
.getAs(DiscordPlayer.class);
|
||||||
if (p == null) return;
|
if (p == null) return;
|
||||||
final IUser user = DiscordPlugin.dc.getUserByID(
|
final IUser user = DiscordPlugin.dc.getUserByID(
|
||||||
Long.parseLong(p.getDiscordID()));
|
Long.parseLong(p.getDiscordID()));
|
||||||
if (e.getValue())
|
if (e.getValue())
|
||||||
user.addRole(role);
|
user.addRole(role);
|
||||||
else
|
else
|
||||||
user.removeRole(role);
|
user.removeRole(role);
|
||||||
DiscordPlugin.sendMessageToChannel(DiscordPlugin.modlogchannel, (e.getValue() ? "M" : "Unm") + "uted user: " + user.getName());
|
val modlog = module.modlogChannel().get();
|
||||||
|
String msg = (e.getValue() ? "M" : "Unm") + "uted user: " + user.getName();
|
||||||
|
if (modlog != null)
|
||||||
|
DiscordPlugin.sendMessageToChannel(modlog, msg);
|
||||||
|
DPUtils.getLogger().info(msg);
|
||||||
});
|
});
|
||||||
} catch (DiscordException | MissingPermissionsException ex) {
|
} catch (DiscordException | MissingPermissionsException ex) {
|
||||||
TBMCCoreAPI.SendException("Failed to give/take Muted role to player " + e.getAffected().getName() + "!",
|
TBMCCoreAPI.SendException("Failed to give/take Muted role to player " + e.getAffected().getName() + "!",
|
||||||
ex);
|
ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -132,9 +146,10 @@ class MCListener implements Listener {
|
||||||
@EventHandler
|
@EventHandler
|
||||||
public void onYEEHAW(TBMCYEEHAWEvent event) { //TODO: Inherit from the chat event base to have channel support
|
public void onYEEHAW(TBMCYEEHAWEvent event) { //TODO: Inherit from the chat event base to have channel support
|
||||||
String name = event.getSender() instanceof Player ? ((Player) event.getSender()).getDisplayName()
|
String name = event.getSender() instanceof Player ? ((Player) event.getSender()).getDisplayName()
|
||||||
: event.getSender().getName();
|
: event.getSender().getName();
|
||||||
//Channel channel = ChromaGamerBase.getFromSender(event.getSender()).channel().get(); - TODO
|
//Channel channel = ChromaGamerBase.getFromSender(event.getSender()).channel().get(); - TODO
|
||||||
MCChatUtils.forAllMCChat(MCChatUtils.send(name + " <:YEEHAW:" + DiscordPlugin.mainServer.getEmojiByName("YEEHAW").getStringID() + ">s"));
|
val yeehaw = DiscordPlugin.mainServer.getEmojiByName("YEEHAW");
|
||||||
|
MCChatUtils.forAllMCChat(MCChatUtils.send(name + (yeehaw != null ? " <:YEEHAW:" + yeehaw.getStringID() + ">s" : " YEEHAWs")));
|
||||||
}
|
}
|
||||||
|
|
||||||
@EventHandler
|
@EventHandler
|
||||||
|
|
|
@ -5,6 +5,7 @@ import buttondevteam.discordplugin.DPUtils;
|
||||||
import buttondevteam.discordplugin.DiscordConnectedPlayer;
|
import buttondevteam.discordplugin.DiscordConnectedPlayer;
|
||||||
import buttondevteam.discordplugin.DiscordPlugin;
|
import buttondevteam.discordplugin.DiscordPlugin;
|
||||||
import buttondevteam.lib.TBMCCoreAPI;
|
import buttondevteam.lib.TBMCCoreAPI;
|
||||||
|
import buttondevteam.lib.TBMCSystemChatEvent;
|
||||||
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 com.google.common.collect.Lists;
|
||||||
|
@ -14,30 +15,58 @@ import org.bukkit.Bukkit;
|
||||||
import sx.blah.discord.handle.obj.IChannel;
|
import sx.blah.discord.handle.obj.IChannel;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Objects;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
public class MinecraftChatModule extends Component {
|
/**
|
||||||
|
* Provides Minecraft chat connection to Discord. Commands may be used either in a public chat (limited) or in a DM.
|
||||||
|
*/
|
||||||
|
public class MinecraftChatModule extends Component<DiscordPlugin> {
|
||||||
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A list of commands that can be used in public chats - Warning: Some plugins will treat players as OPs, always test before allowing a command!
|
||||||
|
*/
|
||||||
public ConfigData<ArrayList<String>> whitelistedCommands() {
|
public ConfigData<ArrayList<String>> whitelistedCommands() {
|
||||||
return getConfig().getData("whitelistedCommands", () -> Lists.newArrayList("list", "u", "shrug", "tableflip", "unflip", "mwiki",
|
return getConfig().getData("whitelistedCommands", () -> Lists.newArrayList("list", "u", "shrug", "tableflip", "unflip", "mwiki",
|
||||||
"yeehaw", "lenny", "rp", "plugins"));
|
"yeehaw", "lenny", "rp", "plugins"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The channel to use as the public Minecraft chat - everything public gets broadcasted here
|
||||||
|
*/
|
||||||
public ConfigData<IChannel> chatChannel() {
|
public ConfigData<IChannel> chatChannel() {
|
||||||
return DPUtils.channelData(getConfig(), "chatChannel", 239519012529111040L);
|
return DPUtils.channelData(getConfig(), "chatChannel", 239519012529111040L);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The channel where the plugin can log when it mutes a player on Discord because of a Minecraft mute
|
||||||
|
*/
|
||||||
|
public ConfigData<IChannel> modlogChannel() {
|
||||||
|
return DPUtils.channelData(getConfig(), "modlogChannel", 283840717275791360L);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 0 * The plugins to exclude from fake player events used for the 'mcchat' command - some plugins may crash, add them here
|
||||||
|
*/
|
||||||
|
public ConfigData<String[]> excludedPlugins() {
|
||||||
|
return getConfig().getData("excludedPlugins", new String[]{"ProtocolLib", "LibsDisguises", "JourneyMapServer"});
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void enable() {
|
protected void enable() {
|
||||||
|
if (DPUtils.disableIfConfigError(this, chatChannel())) return;
|
||||||
listener = new MCChatListener(this);
|
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());//These get undone if restarting/resetting - it will ignore events if disabled
|
TBMCCoreAPI.RegisterEventsForExceptions(new MCListener(this), getPlugin());//These get undone if restarting/resetting - it will ignore events if disabled
|
||||||
|
getPlugin().getManager().registerCommand(new MCChatCommand());
|
||||||
|
getPlugin().getManager().registerCommand(new ChannelconCommand());
|
||||||
|
|
||||||
val chcons = getConfig().getConfig().getConfigurationSection("chcons");
|
val chcons = getConfig().getConfig().getConfigurationSection("chcons");
|
||||||
if (chcons == null) //Fallback to old place
|
if (chcons == null) //Fallback to old place
|
||||||
|
@ -52,11 +81,12 @@ public class MinecraftChatModule extends Component {
|
||||||
val user = DiscordPlugin.dc.fetchUser(did);
|
val user = DiscordPlugin.dc.fetchUser(did);
|
||||||
val groupid = chcon.getString("groupid");
|
val groupid = chcon.getString("groupid");
|
||||||
val toggles = chcon.getInt("toggles");
|
val toggles = chcon.getInt("toggles");
|
||||||
|
val brtoggles = chcon.getStringList("brtoggles");
|
||||||
if (!mcch.isPresent() || ch == null || user == null || groupid == null)
|
if (!mcch.isPresent() || ch == null || user == null || groupid == null)
|
||||||
continue;
|
continue;
|
||||||
Bukkit.getScheduler().runTask(getPlugin(), () -> { //<-- Needed because of occasional ConcurrentModificationExceptions when creating the player (PermissibleBase)
|
Bukkit.getScheduler().runTask(getPlugin(), () -> { //<-- Needed because of occasional ConcurrentModificationExceptions when creating the player (PermissibleBase)
|
||||||
val dcp = new DiscordConnectedPlayer(user, ch, UUID.fromString(chcon.getString("mcuid")), chcon.getString("mcname"));
|
val dcp = new DiscordConnectedPlayer(user, ch, UUID.fromString(chcon.getString("mcuid")), chcon.getString("mcname"));
|
||||||
MCChatCustom.addCustomChat(ch, groupid, mcch.get(), user, dcp, toggles);
|
MCChatCustom.addCustomChat(ch, groupid, mcch.get(), user, dcp, toggles, brtoggles.stream().map(TBMCSystemChatEvent.BroadcastTarget::get).filter(Objects::nonNull).collect(Collectors.toSet()));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -75,7 +105,8 @@ public class MinecraftChatModule extends Component {
|
||||||
chconc.set("mcname", chcon.dcp.getName());
|
chconc.set("mcname", chcon.dcp.getName());
|
||||||
chconc.set("groupid", chcon.groupID);
|
chconc.set("groupid", chcon.groupID);
|
||||||
chconc.set("toggles", chcon.toggles);
|
chconc.set("toggles", chcon.toggles);
|
||||||
|
chconc.set("brtoggles", chcon.brtoggles.stream().map(TBMCSystemChatEvent.BroadcastTarget::getName).collect(Collectors.toList()));
|
||||||
}
|
}
|
||||||
MCChatListener.stop(true);
|
MCChatListener.stop(true);
|
||||||
} //TODO: Use ComponentManager.isEnabled() at other places too, instead of SafeMode
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,26 @@
|
||||||
|
package buttondevteam.discordplugin.mccommands;
|
||||||
|
|
||||||
|
import buttondevteam.discordplugin.DiscordPlugin;
|
||||||
|
import buttondevteam.lib.chat.CommandClass;
|
||||||
|
import buttondevteam.lib.chat.TBMCCommandBase;
|
||||||
|
import org.bukkit.command.CommandSender;
|
||||||
|
|
||||||
|
@CommandClass(path = "discord reload")
|
||||||
|
public class ReloadMCCommand extends TBMCCommandBase {
|
||||||
|
@Override
|
||||||
|
public boolean OnCommand(CommandSender sender, String alias, String[] args) {
|
||||||
|
if (DiscordPlugin.plugin.tryReloadConfig())
|
||||||
|
sender.sendMessage("§bConfig reloaded."); //TODO: Convert to new command system
|
||||||
|
else
|
||||||
|
sender.sendMessage("§cFailed to reload config.");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String[] GetHelpText(String alias) {
|
||||||
|
return new String[]{
|
||||||
|
"Reload",
|
||||||
|
"Reloads the config. To apply some changes, you may need to also run /discord reset."
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
|
@ -3,7 +3,6 @@ package buttondevteam.discordplugin.role;
|
||||||
import buttondevteam.core.ComponentManager;
|
import buttondevteam.core.ComponentManager;
|
||||||
import buttondevteam.discordplugin.DPUtils;
|
import buttondevteam.discordplugin.DPUtils;
|
||||||
import buttondevteam.discordplugin.DiscordPlugin;
|
import buttondevteam.discordplugin.DiscordPlugin;
|
||||||
import buttondevteam.discordplugin.commands.DiscordCommandBase;
|
|
||||||
import buttondevteam.lib.architecture.Component;
|
import buttondevteam.lib.architecture.Component;
|
||||||
import buttondevteam.lib.architecture.ConfigData;
|
import buttondevteam.lib.architecture.ConfigData;
|
||||||
import lombok.val;
|
import lombok.val;
|
||||||
|
@ -19,12 +18,12 @@ import java.awt.*;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
public class GameRoleModule extends Component {
|
public class GameRoleModule extends Component<DiscordPlugin> {
|
||||||
public List<String> GameRoles;
|
public List<String> GameRoles;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void enable() {
|
protected void enable() {
|
||||||
DiscordCommandBase.registerCommand("role", new RoleCommand(this));
|
getPlugin().getManager().registerCommand(new RoleCommand(this));
|
||||||
GameRoles = DiscordPlugin.mainServer.getRoles().stream().filter(this::isGameRole).map(IRole::getName).collect(Collectors.toList());
|
GameRoles = DiscordPlugin.mainServer.getRoles().stream().filter(this::isGameRole).map(IRole::getName).collect(Collectors.toList());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -41,30 +40,34 @@ public class GameRoleModule extends Component {
|
||||||
val grm = ComponentManager.getIfEnabled(GameRoleModule.class);
|
val grm = ComponentManager.getIfEnabled(GameRoleModule.class);
|
||||||
if (grm == null) return;
|
if (grm == null) return;
|
||||||
val GameRoles = grm.GameRoles;
|
val GameRoles = grm.GameRoles;
|
||||||
|
val logChannel = grm.logChannel().get();
|
||||||
if (roleEvent instanceof RoleCreateEvent) {
|
if (roleEvent instanceof RoleCreateEvent) {
|
||||||
Bukkit.getScheduler().runTaskLaterAsynchronously(DiscordPlugin.plugin, () -> {
|
Bukkit.getScheduler().runTaskLaterAsynchronously(DiscordPlugin.plugin, () -> {
|
||||||
if (roleEvent.getRole().isDeleted() || !grm.isGameRole(roleEvent.getRole()))
|
if (roleEvent.getRole().isDeleted() || !grm.isGameRole(roleEvent.getRole()))
|
||||||
return; //Deleted or not a game role
|
return; //Deleted or not a game role
|
||||||
GameRoles.add(roleEvent.getRole().getName());
|
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.");
|
if (logChannel != null)
|
||||||
|
DiscordPlugin.sendMessageToChannel(logChannel, "Added " + roleEvent.getRole().getName() + " as game role. If you don't want this, change the role's color from the default.");
|
||||||
}, 100);
|
}, 100);
|
||||||
} else if (roleEvent instanceof RoleDeleteEvent) {
|
} else if (roleEvent instanceof RoleDeleteEvent) {
|
||||||
if (GameRoles.remove(roleEvent.getRole().getName()))
|
if (GameRoles.remove(roleEvent.getRole().getName()) && logChannel != null)
|
||||||
DiscordPlugin.sendMessageToChannel(grm.logChannel().get(), "Removed " + roleEvent.getRole().getName() + " as a game role.");
|
DiscordPlugin.sendMessageToChannel(logChannel, "Removed " + roleEvent.getRole().getName() + " as a game role.");
|
||||||
} else if (roleEvent instanceof RoleUpdateEvent) {
|
} else if (roleEvent instanceof RoleUpdateEvent) {
|
||||||
val event = (RoleUpdateEvent) roleEvent;
|
val event = (RoleUpdateEvent) roleEvent;
|
||||||
if (!grm.isGameRole(event.getNewRole())) {
|
if (!grm.isGameRole(event.getNewRole())) {
|
||||||
if (GameRoles.remove(event.getOldRole().getName()))
|
if (GameRoles.remove(event.getOldRole().getName()) && logChannel != null)
|
||||||
DiscordPlugin.sendMessageToChannel(grm.logChannel().get(), "Removed " + event.getOldRole().getName() + " as a game role because it's color changed.");
|
DiscordPlugin.sendMessageToChannel(logChannel, "Removed " + event.getOldRole().getName() + " as a game role because it's color changed.");
|
||||||
} else {
|
} else {
|
||||||
if (GameRoles.contains(event.getOldRole().getName()) && event.getOldRole().getName().equals(event.getNewRole().getName()))
|
if (GameRoles.contains(event.getOldRole().getName()) && event.getOldRole().getName().equals(event.getNewRole().getName()))
|
||||||
return;
|
return;
|
||||||
boolean removed = GameRoles.remove(event.getOldRole().getName()); //Regardless of whether it was a game role
|
boolean removed = GameRoles.remove(event.getOldRole().getName()); //Regardless of whether it was a game role
|
||||||
GameRoles.add(event.getNewRole().getName()); //Add it because it has no color
|
GameRoles.add(event.getNewRole().getName()); //Add it because it has no color
|
||||||
if (removed)
|
if (logChannel != null) {
|
||||||
DiscordPlugin.sendMessageToChannel(grm.logChannel().get(), "Changed game role from " + event.getOldRole().getName() + " to " + event.getNewRole().getName() + ".");
|
if (removed)
|
||||||
else
|
DiscordPlugin.sendMessageToChannel(logChannel, "Changed game role from " + event.getOldRole().getName() + " to " + event.getNewRole().getName() + ".");
|
||||||
DiscordPlugin.sendMessageToChannel(grm.logChannel().get(), "Added " + event.getNewRole().getName() + " as game role because it has the default color.");
|
else
|
||||||
|
DiscordPlugin.sendMessageToChannel(logChannel, "Added " + event.getNewRole().getName() + " as game role because it has the default color.");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -74,6 +77,7 @@ public class GameRoleModule extends Component {
|
||||||
return false; //Only allow on the main server
|
return false; //Only allow on the main server
|
||||||
val rc = new Color(149, 165, 166, 0);
|
val rc = new Color(149, 165, 166, 0);
|
||||||
return r.getColor().equals(rc)
|
return r.getColor().equals(rc)
|
||||||
&& r.getPosition() < DiscordPlugin.mainServer.getRoleByID(234343495735836672L).getPosition(); //Below the ChromaBot role
|
&& DiscordPlugin.dc.getOurUser().getRolesForGuild(DiscordPlugin.mainServer)
|
||||||
|
.stream().anyMatch(or -> r.getPosition() < or.getPosition()); //Below one of our roles
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,15 +2,18 @@ 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.discordplugin.commands.Command2DCSender;
|
||||||
|
import buttondevteam.discordplugin.commands.ICommand2DC;
|
||||||
import buttondevteam.lib.TBMCCoreAPI;
|
import buttondevteam.lib.TBMCCoreAPI;
|
||||||
import sx.blah.discord.handle.obj.IMessage;
|
import buttondevteam.lib.chat.Command2;
|
||||||
|
import buttondevteam.lib.chat.CommandClass;
|
||||||
import sx.blah.discord.handle.obj.IRole;
|
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 { //TODO: Use Command2's parser
|
@CommandClass
|
||||||
|
public class RoleCommand extends ICommand2DC {
|
||||||
|
|
||||||
private GameRoleModule grm;
|
private GameRoleModule grm;
|
||||||
|
|
||||||
|
@ -18,83 +21,64 @@ public class RoleCommand extends DiscordCommandBase { //TODO: Use Command2's par
|
||||||
this.grm = grm;
|
this.grm = grm;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Command2.Subcommand(helpText = {
|
||||||
public String getCommandName() {
|
"Add role",
|
||||||
return "role";
|
"This command adds a role to your account."
|
||||||
|
})
|
||||||
|
public boolean add(Command2DCSender sender, @Command2.TextArg String rolename) {
|
||||||
|
final IRole role = checkAndGetRole(sender, rolename);
|
||||||
|
if (role == null)
|
||||||
|
return true;
|
||||||
|
try {
|
||||||
|
DPUtils.perform(() -> sender.getMessage().getAuthor().addRole(role));
|
||||||
|
sender.sendMessage("added role.");
|
||||||
|
} catch (Exception e) {
|
||||||
|
TBMCCoreAPI.SendException("Error while adding role!", e);
|
||||||
|
sender.sendMessage("an error occured while adding the role.");
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Command2.Subcommand(helpText = {
|
||||||
|
"Remove role",
|
||||||
|
"This command removes a role from your account."
|
||||||
|
})
|
||||||
|
public boolean remove(Command2DCSender sender, @Command2.TextArg String rolename) {
|
||||||
|
final IRole role = checkAndGetRole(sender, rolename);
|
||||||
|
if (role == null)
|
||||||
|
return true;
|
||||||
|
try {
|
||||||
|
DPUtils.perform(() -> sender.getMessage().getAuthor().removeRole(role));
|
||||||
|
sender.sendMessage("removed role.");
|
||||||
|
} catch (Exception e) {
|
||||||
|
TBMCCoreAPI.SendException("Error while removing role!", e);
|
||||||
|
sender.sendMessage("an error occured while removing the role.");
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Command2.Subcommand
|
||||||
|
public void list(Command2DCSender sender) {
|
||||||
|
sender.sendMessage("list of roles:\n" + grm.GameRoles.stream().sorted().collect(Collectors.joining("\n")));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
private IRole checkAndGetRole(Command2DCSender sender, String rolename) {
|
||||||
public boolean run(IMessage message, String args) {
|
if (!grm.GameRoles.contains(rolename)) {
|
||||||
if (args.length() == 0)
|
sender.sendMessage("that role cannot be found.");
|
||||||
return false;
|
list(sender);
|
||||||
String[] argsa = splitargs(args);
|
|
||||||
if (argsa[0].equalsIgnoreCase("add")) {
|
|
||||||
final IRole role = checkAndGetRole(message, argsa, "This command adds a role to your account.");
|
|
||||||
if (role == null)
|
|
||||||
return true;
|
|
||||||
try {
|
|
||||||
DPUtils.perform(() -> message.getAuthor().addRole(role));
|
|
||||||
DiscordPlugin.sendMessageToChannel(message.getChannel(), "Added role.");
|
|
||||||
} catch (Exception e) {
|
|
||||||
TBMCCoreAPI.SendException("Error while adding role!", e);
|
|
||||||
DiscordPlugin.sendMessageToChannel(message.getChannel(), "An error occured while adding the role.");
|
|
||||||
}
|
|
||||||
} else if (argsa[0].equalsIgnoreCase("remove")) {
|
|
||||||
final IRole role = checkAndGetRole(message, argsa, "This command removes a role from your account.");
|
|
||||||
if (role == null)
|
|
||||||
return true;
|
|
||||||
try {
|
|
||||||
DPUtils.perform(() -> message.getAuthor().removeRole(role));
|
|
||||||
DiscordPlugin.sendMessageToChannel(message.getChannel(), "Removed role.");
|
|
||||||
} catch (Exception e) {
|
|
||||||
TBMCCoreAPI.SendException("Error while removing role!", e);
|
|
||||||
DiscordPlugin.sendMessageToChannel(message.getChannel(), "An error occured while removing the role.");
|
|
||||||
}
|
|
||||||
} else if (argsa[0].equalsIgnoreCase("list")) {
|
|
||||||
listRoles(message);
|
|
||||||
} else return false;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void listRoles(IMessage message) {
|
|
||||||
DiscordPlugin.sendMessageToChannel(message.getChannel(),
|
|
||||||
"List of roles:\n" + grm.GameRoles.stream().sorted().collect(Collectors.joining("\n")));
|
|
||||||
}
|
|
||||||
|
|
||||||
private IRole checkAndGetRole(IMessage message, String[] argsa, String usage) {
|
|
||||||
if (argsa.length < 2) {
|
|
||||||
DiscordPlugin.sendMessageToChannel(message.getChannel(), usage + "\nUsage: " + argsa[0] + " <rolename>");
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
StringBuilder rolename = new StringBuilder(argsa[1]);
|
final List<IRole> roles = DiscordPlugin.mainServer.getRolesByName(rolename);
|
||||||
for (int i = 2; i < argsa.length; i++)
|
|
||||||
rolename.append(" ").append(argsa[i]);
|
|
||||||
if (!grm.GameRoles.contains(rolename.toString())) {
|
|
||||||
DiscordPlugin.sendMessageToChannel(message.getChannel(), "That role cannot be found.");
|
|
||||||
listRoles(message);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
final List<IRole> roles = DiscordPlugin.mainServer.getRolesByName(rolename.toString());
|
|
||||||
if (roles.size() == 0) {
|
if (roles.size() == 0) {
|
||||||
DiscordPlugin.sendMessageToChannel(message.getChannel(),
|
sender.sendMessage("the specified role cannot be found on Discord! Removing from the list.");
|
||||||
"The specified role cannot be found on Discord! Removing from the list.");
|
grm.GameRoles.remove(rolename);
|
||||||
grm.GameRoles.remove(rolename.toString());
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
if (roles.size() > 1) {
|
if (roles.size() > 1) {
|
||||||
DiscordPlugin.sendMessageToChannel(message.getChannel(),
|
sender.sendMessage("there are multiple roles with this name. Why are there multiple roles with this name?");
|
||||||
"There are more roles with this name. Why are there more roles with this name?");
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return roles.get(0);
|
return roles.get(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public String[] getHelpText() {
|
|
||||||
return new String[]{ //
|
|
||||||
"Add or remove roles from yourself.", //
|
|
||||||
"Usage: " + DiscordPlugin.getPrefix() + "role add|remove <name> or role list", //
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue