Merge pull request #86 from TBMCPlugins/dev
Reorganized lots of stuff (components)
This commit is contained in:
commit
db743dcd50
31 changed files with 1159 additions and 873 deletions
35
pom.xml
35
pom.xml
|
@ -106,6 +106,9 @@
|
|||
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<branch>
|
||||
master
|
||||
</branch> <!-- Should be master if building ButtonCore locally - the CI will overwrite it (see below) -->
|
||||
</properties>
|
||||
|
||||
<repositories>
|
||||
|
@ -159,11 +162,16 @@
|
|||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<!-- https://mvnrepository.com/artifact/com.discord4j/Discord4J -->
|
||||
<dependency>
|
||||
<groupId>com.discord4j</groupId>
|
||||
<artifactId>Discord4J</artifactId>
|
||||
<version>2.10.1</version>
|
||||
</dependency>
|
||||
<!-- <dependency>
|
||||
<groupId>com.discord4j</groupId>
|
||||
<artifactId>Discord4J</artifactId>
|
||||
<version>2.10.1</version>
|
||||
</dependency> -->
|
||||
<dependency>
|
||||
<groupId>com.github.SizableShrimp</groupId>
|
||||
<artifactId>Discord4J</artifactId>
|
||||
<version>httprequestchange-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<!-- https://mvnrepository.com/artifact/org.slf4j/slf4j-jdk14 -->
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
|
@ -173,7 +181,7 @@
|
|||
<dependency>
|
||||
<groupId>com.github.TBMCPlugins.ButtonCore</groupId>
|
||||
<artifactId>ButtonCore</artifactId>
|
||||
<version>master-SNAPSHOT</version>
|
||||
<version>${branch}-SNAPSHOT</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
|
@ -225,4 +233,19 @@
|
|||
<version>4.0.0</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<profiles>
|
||||
<profile>
|
||||
<id>ci</id>
|
||||
<activation>
|
||||
<property>
|
||||
<name>env.TRAVIS_BRANCH</name>
|
||||
</property>
|
||||
</activation>
|
||||
<properties>
|
||||
<!-- Override only if necessary -->
|
||||
<branch>${env.TRAVIS_BRANCH}</branch>
|
||||
</properties>
|
||||
</profile>
|
||||
</profiles>
|
||||
</project>
|
||||
|
|
|
@ -0,0 +1,27 @@
|
|||
package buttondevteam.discordplugin;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.Setter;
|
||||
import org.bukkit.event.Cancellable;
|
||||
import org.bukkit.event.Event;
|
||||
import org.bukkit.event.HandlerList;
|
||||
|
||||
@RequiredArgsConstructor
|
||||
public class AsyncDiscordEvent<T extends sx.blah.discord.api.events.Event> extends Event implements Cancellable {
|
||||
private final @Getter T event;
|
||||
@Getter
|
||||
@Setter
|
||||
private boolean cancelled;
|
||||
|
||||
private static final HandlerList handlers = new HandlerList();
|
||||
|
||||
@Override
|
||||
public HandlerList getHandlers() {
|
||||
return handlers;
|
||||
}
|
||||
|
||||
public static HandlerList getHandlerList() {
|
||||
return handlers;
|
||||
}
|
||||
}
|
|
@ -1,8 +1,7 @@
|
|||
package buttondevteam.discordplugin;
|
||||
|
||||
import buttondevteam.discordplugin.listeners.MCChatListener;
|
||||
import buttondevteam.discordplugin.mcchat.MCChatUtils;
|
||||
import lombok.Getter;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.scheduler.BukkitScheduler;
|
||||
import sx.blah.discord.api.internal.json.objects.EmbedObject;
|
||||
|
@ -11,8 +10,6 @@ import sx.blah.discord.util.EmbedBuilder;
|
|||
|
||||
import javax.annotation.Nullable;
|
||||
import java.awt.*;
|
||||
import java.util.Arrays;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class ChromaBot {
|
||||
/**
|
||||
|
@ -43,7 +40,7 @@ public class ChromaBot {
|
|||
* The message to send, duh
|
||||
*/
|
||||
public void sendMessage(String message) {
|
||||
MCChatListener.forAllMCChat(ch -> DiscordPlugin.sendMessageToChannel(ch, message));
|
||||
MCChatUtils.forAllMCChat(ch -> DiscordPlugin.sendMessageToChannel(ch, message));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -55,7 +52,7 @@ public class ChromaBot {
|
|||
* Custom fancy stuff, use {@link EmbedBuilder} to create one
|
||||
*/
|
||||
public void sendMessage(String message, EmbedObject embed) {
|
||||
MCChatListener.forAllMCChat(ch -> DiscordPlugin.sendMessageToChannel(ch, message, embed));
|
||||
MCChatUtils.forAllMCChat(ch -> DiscordPlugin.sendMessageToChannel(ch, message, embed));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -66,7 +63,7 @@ public class ChromaBot {
|
|||
* @param toggle The toggle type for channelcon
|
||||
*/
|
||||
public void sendMessageCustomAsWell(String message, EmbedObject embed, @Nullable ChannelconBroadcast toggle) {
|
||||
MCChatListener.forCustomAndAllMCChat(ch -> DiscordPlugin.sendMessageToChannel(ch, message, embed), toggle, false);
|
||||
MCChatUtils.forCustomAndAllMCChat(ch -> DiscordPlugin.sendMessageToChannel(ch, message, embed), toggle, false);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -92,7 +89,7 @@ public class ChromaBot {
|
|||
* The color of the line before the text
|
||||
*/
|
||||
public void sendMessage(String message, Color color) {
|
||||
MCChatListener.forAllMCChat(ch -> DiscordPlugin.sendMessageToChannel(ch, message,
|
||||
MCChatUtils.forAllMCChat(ch -> DiscordPlugin.sendMessageToChannel(ch, message,
|
||||
new EmbedBuilder().withTitle(message).withColor(color).build()));
|
||||
}
|
||||
|
||||
|
@ -107,7 +104,7 @@ public class ChromaBot {
|
|||
* The name of the Minecraft player who is the author of this message
|
||||
*/
|
||||
public void sendMessage(String message, Color color, String mcauthor) {
|
||||
MCChatListener.forAllMCChat(ch -> DiscordPlugin.sendMessageToChannel(ch, message,
|
||||
MCChatUtils.forAllMCChat(ch -> DiscordPlugin.sendMessageToChannel(ch, message,
|
||||
DPUtils.embedWithHead(new EmbedBuilder().withTitle(message).withColor(color), mcauthor).build()));
|
||||
}
|
||||
|
||||
|
@ -124,7 +121,7 @@ public class ChromaBot {
|
|||
* The URL of the avatar image for this message's author
|
||||
*/
|
||||
public void sendMessage(String message, Color color, String authorname, String authorimg) {
|
||||
MCChatListener.forAllMCChat(ch -> DiscordPlugin.sendMessageToChannel(ch, message, new EmbedBuilder()
|
||||
MCChatUtils.forAllMCChat(ch -> DiscordPlugin.sendMessageToChannel(ch, message, new EmbedBuilder()
|
||||
.withTitle(message).withColor(color).withAuthorName(authorname).withAuthorIcon(authorimg).build()));
|
||||
}
|
||||
|
||||
|
@ -139,20 +136,11 @@ public class ChromaBot {
|
|||
* The player who sends this message
|
||||
*/
|
||||
public void sendMessage(String message, Color color, Player sender) {
|
||||
MCChatListener.forAllMCChat(ch -> DiscordPlugin.sendMessageToChannel(ch, message, DPUtils
|
||||
MCChatUtils.forAllMCChat(ch -> DiscordPlugin.sendMessageToChannel(ch, message, DPUtils
|
||||
.embedWithHead(new EmbedBuilder().withTitle(message).withColor(color), sender.getName()).build()));
|
||||
}
|
||||
|
||||
public void updatePlayerList() {
|
||||
DPUtils.performNoWait(() -> {
|
||||
String[] s = DiscordPlugin.chatchannel.getTopic().split("\\n----\\n");
|
||||
if (s.length < 3)
|
||||
return;
|
||||
s[0] = Bukkit.getOnlinePlayers().size() + " player" + (Bukkit.getOnlinePlayers().size() != 1 ? "s" : "")
|
||||
+ " online";
|
||||
s[s.length - 1] = "Players: " + Bukkit.getOnlinePlayers().stream()
|
||||
.map(p -> DPUtils.sanitizeString(p.getDisplayName())).collect(Collectors.joining(", "));
|
||||
DiscordPlugin.chatchannel.changeTopic(Arrays.stream(s).collect(Collectors.joining("\n----\n")));
|
||||
});
|
||||
MCChatUtils.updatePlayerList();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,6 +9,7 @@ import sx.blah.discord.util.RequestBuffer.IVoidRequest;
|
|||
import javax.annotation.Nullable;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
import java.util.logging.Logger;
|
||||
import java.util.regex.Matcher;
|
||||
|
||||
public final class DPUtils {
|
||||
|
@ -96,4 +97,10 @@ public final class DPUtils {
|
|||
return message.replaceAll("([*_~])", Matcher.quoteReplacement("\\")+"$1");
|
||||
}
|
||||
|
||||
public static Logger getLogger() {
|
||||
if (DiscordPlugin.plugin == null || DiscordPlugin.plugin.getLogger() == null)
|
||||
return Logger.getLogger("DiscordPlugin");
|
||||
return DiscordPlugin.plugin.getLogger();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
package buttondevteam.discordplugin;
|
||||
|
||||
import buttondevteam.discordplugin.listeners.MCChatListener;
|
||||
import buttondevteam.discordplugin.mcchat.MCChatPrivate;
|
||||
import buttondevteam.lib.player.ChromaGamerBase;
|
||||
import buttondevteam.lib.player.UserClass;
|
||||
|
||||
|
@ -20,9 +20,9 @@ public class DiscordPlayer extends ChromaGamerBase {
|
|||
|
||||
/**
|
||||
* Returns true if player has the private Minecraft chat enabled. For setting the value, see
|
||||
* {@link MCChatListener#privateMCChat(sx.blah.discord.handle.obj.IChannel, boolean, sx.blah.discord.handle.obj.IUser, DiscordPlayer)}
|
||||
* {@link MCChatPrivate#privateMCChat(sx.blah.discord.handle.obj.IChannel, boolean, sx.blah.discord.handle.obj.IUser, DiscordPlayer)}
|
||||
*/
|
||||
public boolean isMinecraftChatEnabled() {
|
||||
return MCChatListener.isMinecraftChatEnabled(this);
|
||||
return MCChatPrivate.isMinecraftChatEnabled(this);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,13 +1,17 @@
|
|||
package buttondevteam.discordplugin;
|
||||
|
||||
import buttondevteam.discordplugin.broadcaster.GeneralEventBroadcasterModule;
|
||||
import buttondevteam.discordplugin.commands.DiscordCommandBase;
|
||||
import buttondevteam.discordplugin.listeners.CommandListener;
|
||||
import buttondevteam.discordplugin.listeners.ExceptionListener;
|
||||
import buttondevteam.discordplugin.listeners.MCChatListener;
|
||||
import buttondevteam.discordplugin.exceptions.ExceptionListenerModule;
|
||||
import buttondevteam.discordplugin.listeners.CommonListeners;
|
||||
import buttondevteam.discordplugin.listeners.MCListener;
|
||||
import buttondevteam.discordplugin.mcchat.*;
|
||||
import buttondevteam.discordplugin.mccommands.DiscordMCCommandBase;
|
||||
import buttondevteam.discordplugin.mccommands.ResetMCCommand;
|
||||
import buttondevteam.lib.TBMCCoreAPI;
|
||||
import buttondevteam.lib.architecture.ButtonPlugin;
|
||||
import buttondevteam.lib.architecture.Component;
|
||||
import buttondevteam.lib.architecture.ConfigData;
|
||||
import buttondevteam.lib.chat.Channel;
|
||||
import buttondevteam.lib.chat.TBMCChatAPI;
|
||||
import buttondevteam.lib.player.ChromaGamerBase;
|
||||
|
@ -20,9 +24,7 @@ import lombok.val;
|
|||
import net.milkbowl.vault.permission.Permission;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.player.PlayerQuitEvent;
|
||||
import org.bukkit.plugin.RegisteredServiceProvider;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
import org.bukkit.scheduler.BukkitTask;
|
||||
import sx.blah.discord.api.ClientBuilder;
|
||||
import sx.blah.discord.api.IDiscordClient;
|
||||
|
@ -44,29 +46,28 @@ import java.util.concurrent.TimeUnit;
|
|||
import java.util.concurrent.TimeoutException;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class DiscordPlugin extends JavaPlugin implements IListener<ReadyEvent> {
|
||||
public class DiscordPlugin extends ButtonPlugin implements IListener<ReadyEvent> {
|
||||
private static final String SubredditURL = "https://www.reddit.com/r/ChromaGamers";
|
||||
private static boolean stop = false;
|
||||
public static IDiscordClient dc;
|
||||
public static DiscordPlugin plugin;
|
||||
public static boolean SafeMode = true;
|
||||
public static List<String> GameRoles;
|
||||
public static boolean hooked = false;
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public ConfigData<Character> Prefix() {
|
||||
return getData("prefix", '/');
|
||||
}
|
||||
|
||||
public static char getPrefix() {
|
||||
if (plugin == null) return '/';
|
||||
return plugin.Prefix().get();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onEnable() {
|
||||
public void pluginEnable() {
|
||||
stop = false; //If not the first time
|
||||
try {
|
||||
Bukkit.getLogger().info("Initializing DiscordPlugin...");
|
||||
try {
|
||||
PlayerListWatcher.hookUp();
|
||||
hooked = true;
|
||||
Bukkit.getLogger().info("Finished hooking into the player list");
|
||||
} catch (Throwable e) {
|
||||
e.printStackTrace();
|
||||
Bukkit.getLogger().warning("Couldn't hook into the player list!");
|
||||
}
|
||||
plugin = this;
|
||||
lastannouncementtime = getConfig().getLong("lastannouncementtime");
|
||||
lastseentime = getConfig().getLong("lastseentime");
|
||||
|
@ -156,7 +157,7 @@ public class DiscordPlugin extends JavaPlugin implements IListener<ReadyEvent> {
|
|||
val toggles = chcon.getInt("toggles");
|
||||
if (!mcch.isPresent() || ch == null || user == null || groupid == null)
|
||||
continue;
|
||||
MCChatListener.addCustomChat(ch, groupid, mcch.get(), user, dcp, toggles);
|
||||
MCChatCustom.addCustomChat(ch, groupid, mcch.get(), user, dcp, toggles);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -212,21 +213,16 @@ public class DiscordPlugin extends JavaPlugin implements IListener<ReadyEvent> {
|
|||
}*/
|
||||
}
|
||||
}, 0, 10);
|
||||
for (IListener<?> listener : CommandListener.getListeners())
|
||||
for (IListener<?> listener : CommonListeners.getListeners())
|
||||
dc.getDispatcher().registerListener(listener);
|
||||
MCChatListener mcchat = new MCChatListener();
|
||||
dc.getDispatcher().registerListener(mcchat);
|
||||
TBMCCoreAPI.RegisterEventsForExceptions(mcchat, this);
|
||||
Bukkit.getPluginManager().registerEvents(new ExceptionListener(), this);
|
||||
Component.registerComponent(this, new GeneralEventBroadcasterModule());
|
||||
Component.registerComponent(this, new MinecraftChatModule());
|
||||
Component.registerComponent(this, new ExceptionListenerModule());
|
||||
TBMCCoreAPI.RegisterEventsForExceptions(new MCListener(), this);
|
||||
TBMCChatAPI.AddCommands(this, DiscordMCCommandBase.class);
|
||||
TBMCCoreAPI.RegisterUserClass(DiscordPlayer.class);
|
||||
ChromaGamerBase.addConverter(sender -> {
|
||||
//System.out.println("Discord converter queried: "+sender+" "+sender.getName()); - TODO: Remove
|
||||
//System.out.println(((DiscordSenderBase) sender).getChromaUser().channel().get().ID); //TODO: TMP
|
||||
return Optional.ofNullable(sender instanceof DiscordSenderBase
|
||||
? ((DiscordSenderBase) sender).getChromaUser() : null);
|
||||
});
|
||||
ChromaGamerBase.addConverter(sender -> Optional.ofNullable(sender instanceof DiscordSenderBase
|
||||
? ((DiscordSenderBase) sender).getChromaUser() : null));
|
||||
new Thread(this::AnnouncementGetterThreadMethod).start();
|
||||
setupProviders();
|
||||
} catch (Exception e) {
|
||||
|
@ -248,17 +244,14 @@ public class DiscordPlugin extends JavaPlugin implements IListener<ReadyEvent> {
|
|||
public static boolean Restart;
|
||||
|
||||
@Override
|
||||
public void onDisable() {
|
||||
public void pluginDisable() {
|
||||
stop = true;
|
||||
for (val entry : MCChatListener.ConnectedSenders.entrySet())
|
||||
for (val valueEntry : entry.getValue().entrySet())
|
||||
MCListener.callEventExcludingSome(new PlayerQuitEvent(valueEntry.getValue(), ""));
|
||||
MCChatListener.ConnectedSenders.clear();
|
||||
MCChatPrivate.logoutAll();
|
||||
getConfig().set("lastannouncementtime", lastannouncementtime);
|
||||
getConfig().set("lastseentime", lastseentime);
|
||||
getConfig().set("serverup", false);
|
||||
|
||||
val chcons = MCChatListener.getCustomChats();
|
||||
val chcons = MCChatCustom.getCustomChats();
|
||||
val chconsc = getConfig().createSection("chcons");
|
||||
for (val chcon : chcons) {
|
||||
val chconc = chconsc.createSection(chcon.channel.getStringID());
|
||||
|
@ -287,7 +280,7 @@ public class DiscordPlugin extends JavaPlugin implements IListener<ReadyEvent> {
|
|||
+ "kicked the hell out.") //TODO: Make configurable
|
||||
: "") //If 'restart' is disabled then this isn't shown even if joinleave is enabled
|
||||
.build();
|
||||
MCChatListener.forCustomAndAllMCChat(ch -> {
|
||||
MCChatUtils.forCustomAndAllMCChat(ch -> {
|
||||
try {
|
||||
DiscordPlugin.sendMessageToChannelWait(ch, "",
|
||||
embed, 5, TimeUnit.SECONDS);
|
||||
|
@ -299,16 +292,6 @@ public class DiscordPlugin extends JavaPlugin implements IListener<ReadyEvent> {
|
|||
try {
|
||||
SafeMode = true; // Stop interacting with Discord
|
||||
MCChatListener.stop(true);
|
||||
try {
|
||||
if (PlayerListWatcher.hookDown())
|
||||
System.out.println("Finished unhooking the player list!");
|
||||
else
|
||||
System.out.println("Didn't have the player list hooked.");
|
||||
hooked = false;
|
||||
} catch (Throwable e) {
|
||||
e.printStackTrace();
|
||||
Bukkit.getLogger().warning("Couldn't unhook the player list!");
|
||||
}
|
||||
ChromaBot.delete();
|
||||
dc.changePresence(StatusType.IDLE, ActivityType.PLAYING, "Chromacraft"); //No longer using the same account for testing
|
||||
dc.logout();
|
||||
|
@ -424,7 +407,7 @@ public class DiscordPlugin extends JavaPlugin implements IListener<ReadyEvent> {
|
|||
.warning("Message was too long to send to discord and got truncated. In " + channel.getName());
|
||||
}
|
||||
try {
|
||||
MCChatListener.resetLastMessage(channel); // If this is a chat message, it'll be set again
|
||||
MCChatUtils.resetLastMessage(channel); // If this is a chat message, it'll be set again
|
||||
final String content = message;
|
||||
RequestBuffer.IRequest<IMessage> r = () -> embed == null ? channel.sendMessage(content)
|
||||
: channel.sendMessage(content, embed, false);
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
package buttondevteam.discordplugin;
|
||||
|
||||
import buttondevteam.lib.TBMCCoreAPI;
|
||||
import buttondevteam.lib.chat.IDiscordSender;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.scheduler.BukkitTask;
|
||||
import sx.blah.discord.handle.obj.IChannel;
|
||||
import sx.blah.discord.handle.obj.IUser;
|
||||
|
||||
public abstract class DiscordSenderBase implements IDiscordSender {
|
||||
public abstract class DiscordSenderBase implements CommandSender {
|
||||
/**
|
||||
* May be null.
|
||||
*/
|
||||
|
@ -51,6 +51,7 @@ public abstract class DiscordSenderBase implements IDiscordSender {
|
|||
public void sendMessage(String message) {
|
||||
try {
|
||||
final boolean broadcast = new Exception().getStackTrace()[2].getMethodName().contains("broadcast");
|
||||
//if (broadcast && DiscordPlugin.hooked) - TODO: What should happen if unhooked
|
||||
if (broadcast)
|
||||
return;
|
||||
final String sendmsg = DPUtils.sanitizeString(message);
|
||||
|
|
|
@ -0,0 +1,35 @@
|
|||
package buttondevteam.discordplugin.broadcaster;
|
||||
|
||||
import buttondevteam.discordplugin.DPUtils;
|
||||
import buttondevteam.lib.TBMCCoreAPI;
|
||||
import buttondevteam.lib.architecture.Component;
|
||||
import lombok.Getter;
|
||||
import org.bukkit.Bukkit;
|
||||
|
||||
public class GeneralEventBroadcasterModule extends Component {
|
||||
private static @Getter boolean hooked = false;
|
||||
|
||||
@Override
|
||||
protected void enable() {
|
||||
try {
|
||||
PlayerListWatcher.hookUp();
|
||||
Bukkit.getLogger().info("Finished hooking into the player list");
|
||||
hooked = true;
|
||||
} catch (Exception e) {
|
||||
TBMCCoreAPI.SendException("Error while hacking the player list!", e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void disable() {
|
||||
try {
|
||||
if (PlayerListWatcher.hookDown())
|
||||
DPUtils.getLogger().info("Finished unhooking the player list!");
|
||||
else
|
||||
DPUtils.getLogger().info("Didn't have the player list hooked.");
|
||||
hooked = false;
|
||||
} catch (Exception e) {
|
||||
TBMCCoreAPI.SendException("Error while hacking the player list!", e);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,6 +1,6 @@
|
|||
package buttondevteam.discordplugin;
|
||||
package buttondevteam.discordplugin.broadcaster;
|
||||
|
||||
import buttondevteam.discordplugin.listeners.MCChatListener;
|
||||
import buttondevteam.discordplugin.mcchat.MCChatUtils;
|
||||
import buttondevteam.lib.TBMCCoreAPI;
|
||||
import com.mojang.authlib.GameProfile;
|
||||
import lombok.val;
|
||||
|
@ -30,7 +30,7 @@ public class PlayerListWatcher extends DedicatedPlayerList {
|
|||
if (packet instanceof PacketPlayOutChat) {
|
||||
Field msgf = PacketPlayOutChat.class.getDeclaredField("a");
|
||||
msgf.setAccessible(true);
|
||||
MCChatListener.forAllMCChat(MCChatListener.send(((IChatBaseComponent) msgf.get(packet)).toPlainText()));
|
||||
MCChatUtils.forAllMCChat(MCChatUtils.send(((IChatBaseComponent) msgf.get(packet)).toPlainText()));
|
||||
}
|
||||
} catch (Exception e) {
|
||||
TBMCCoreAPI.SendException("Failed to broadcast message sent to all players - hacking failed.", e);
|
||||
|
@ -53,52 +53,43 @@ public class PlayerListWatcher extends DedicatedPlayerList {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void sendMessage(IChatBaseComponent[] iChatBaseComponents) { // Needed so it calls the overriden method
|
||||
public void sendMessage(IChatBaseComponent[] iChatBaseComponents) { // Needed so it calls the overridden method
|
||||
for (IChatBaseComponent component : iChatBaseComponents) {
|
||||
sendMessage(component, true);
|
||||
}
|
||||
}
|
||||
|
||||
public static void hookUp() {
|
||||
try {
|
||||
Field conf = CraftServer.class.getDeclaredField("console");
|
||||
conf.setAccessible(true);
|
||||
val server = (MinecraftServer) conf.get(Bukkit.getServer());
|
||||
val plw = new ObjenesisStd().newInstance(PlayerListWatcher.class); // Cannot call super constructor
|
||||
plw.plist = (DedicatedPlayerList) server.getPlayerList();
|
||||
plw.maxPlayers = plw.plist.getMaxPlayers();
|
||||
Field plf = plw.getClass().getField("players");
|
||||
plf.setAccessible(true);
|
||||
Field modf = plf.getClass().getDeclaredField("modifiers");
|
||||
modf.setAccessible(true);
|
||||
modf.set(plf, plf.getModifiers() & ~Modifier.FINAL);
|
||||
plf.set(plw, plw.plist.players);
|
||||
server.a(plw);
|
||||
Field pllf = CraftServer.class.getDeclaredField("playerList");
|
||||
pllf.setAccessible(true);
|
||||
pllf.set(Bukkit.getServer(), plw);
|
||||
} catch (Exception e) {
|
||||
TBMCCoreAPI.SendException("Error while hacking the player list!", e);
|
||||
}
|
||||
static void hookUp() throws Exception {
|
||||
Field conf = CraftServer.class.getDeclaredField("console");
|
||||
conf.setAccessible(true);
|
||||
val server = (MinecraftServer) conf.get(Bukkit.getServer());
|
||||
val plw = new ObjenesisStd().newInstance(PlayerListWatcher.class); // Cannot call super constructor
|
||||
plw.plist = (DedicatedPlayerList) server.getPlayerList();
|
||||
plw.maxPlayers = plw.plist.getMaxPlayers();
|
||||
Field plf = plw.getClass().getField("players");
|
||||
plf.setAccessible(true);
|
||||
Field modf = plf.getClass().getDeclaredField("modifiers");
|
||||
modf.setAccessible(true);
|
||||
modf.set(plf, plf.getModifiers() & ~Modifier.FINAL);
|
||||
plf.set(plw, plw.plist.players);
|
||||
server.a(plw);
|
||||
Field pllf = CraftServer.class.getDeclaredField("playerList");
|
||||
pllf.setAccessible(true);
|
||||
pllf.set(Bukkit.getServer(), plw);
|
||||
}
|
||||
|
||||
public static boolean hookDown() {
|
||||
try {
|
||||
Field conf = CraftServer.class.getDeclaredField("console");
|
||||
conf.setAccessible(true);
|
||||
val server = (MinecraftServer) conf.get(Bukkit.getServer());
|
||||
val plist = (DedicatedPlayerList) server.getPlayerList();
|
||||
if (!(plist instanceof PlayerListWatcher))
|
||||
return false;
|
||||
server.a(((PlayerListWatcher) plist).plist);
|
||||
Field pllf = CraftServer.class.getDeclaredField("playerList");
|
||||
pllf.setAccessible(true);
|
||||
pllf.set(Bukkit.getServer(), ((PlayerListWatcher) plist).plist);
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
TBMCCoreAPI.SendException("Error while hacking the player list!", e);
|
||||
return true;
|
||||
}
|
||||
static boolean hookDown() throws Exception {
|
||||
Field conf = CraftServer.class.getDeclaredField("console");
|
||||
conf.setAccessible(true);
|
||||
val server = (MinecraftServer) conf.get(Bukkit.getServer());
|
||||
val plist = (DedicatedPlayerList) server.getPlayerList();
|
||||
if (!(plist instanceof PlayerListWatcher))
|
||||
return false;
|
||||
server.a(((PlayerListWatcher) plist).plist);
|
||||
Field pllf = CraftServer.class.getDeclaredField("playerList");
|
||||
pllf.setAccessible(true);
|
||||
pllf.set(Bukkit.getServer(), ((PlayerListWatcher) plist).plist);
|
||||
return true;
|
||||
}
|
||||
|
||||
public void a(EntityHuman entityhuman, IChatBaseComponent ichatbasecomponent) {
|
|
@ -3,7 +3,8 @@ package buttondevteam.discordplugin.commands;
|
|||
import buttondevteam.discordplugin.ChannelconBroadcast;
|
||||
import buttondevteam.discordplugin.DiscordConnectedPlayer;
|
||||
import buttondevteam.discordplugin.DiscordPlayer;
|
||||
import buttondevteam.discordplugin.listeners.MCChatListener;
|
||||
import buttondevteam.discordplugin.DiscordPlugin;
|
||||
import buttondevteam.discordplugin.mcchat.MCChatCustom;
|
||||
import buttondevteam.lib.chat.Channel;
|
||||
import buttondevteam.lib.player.TBMCPlayer;
|
||||
import lombok.val;
|
||||
|
@ -30,16 +31,16 @@ public class ChannelconCommand extends DiscordCommandBase {
|
|||
message.reply("you need to have manage permissions for this channel!");
|
||||
return true;
|
||||
}
|
||||
if (MCChatListener.hasCustomChat(message.getChannel())) {
|
||||
if (MCChatCustom.hasCustomChat(message.getChannel())) {
|
||||
if (args.toLowerCase().startsWith("remove")) {
|
||||
if (MCChatListener.removeCustomChat(message.getChannel()))
|
||||
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 = MCChatListener.getCustomChat(message.getChannel());
|
||||
val cc = MCChatCustom.getCustomChat(message.getChannel());
|
||||
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) {
|
||||
|
@ -88,7 +89,7 @@ public class ChannelconCommand extends DiscordCommandBase {
|
|||
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?
|
||||
MCChatListener.addCustomChat(message.getChannel(), groupid, chan.get(), message.getAuthor(), dcp, 0);
|
||||
MCChatCustom.addCustomChat(message.getChannel(), groupid, chan.get(), message.getAuthor(), dcp, 0);
|
||||
message.reply("alright, connection made to group `" + groupid + "`!");
|
||||
return true;
|
||||
}
|
||||
|
@ -99,10 +100,12 @@ public class ChannelconCommand extends DiscordCommandBase {
|
|||
"---- 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: @ChromaBot channelcon <mcchannel>", //
|
||||
"You also need to have your Minecraft account connected. In #bot 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 / prefix only works in #bot.", //
|
||||
"Mentioning the bot is needed in this case because the " + DiscordPlugin.getPrefix() + " prefix only works in #bot.", //
|
||||
"Invite link: <https://discordapp.com/oauth2/authorize?client_id=226443037893591041&scope=bot&permissions=268509264>" //
|
||||
};
|
||||
}
|
||||
|
|
|
@ -30,7 +30,7 @@ public class ConnectCommand extends DiscordCommandBase {
|
|||
return false;
|
||||
if (args.contains(" ")) {
|
||||
DiscordPlugin.sendMessageToChannel(message.getChannel(),
|
||||
"Too many arguments.\nUsage: connect <Minecraftname>");
|
||||
"Too many arguments.\nUsage: " + DiscordPlugin.getPrefix() + "connect <Minecraftname>");
|
||||
return true;
|
||||
}
|
||||
if (WaitingToConnect.inverse().containsKey(message.getAuthor().getStringID())) {
|
||||
|
@ -68,8 +68,8 @@ public class ConnectCommand extends DiscordCommandBase {
|
|||
public String[] getHelpText() {
|
||||
return new String[] { //
|
||||
"---- Connect command ----", //
|
||||
"This commands let's you connect your acoount with a Minecraft account. This'd allow using the Minecraft chat and other things.", //
|
||||
"Usage: connect <Minecraftname>" //
|
||||
"This command lets you connect your account with a Minecraft account. This allows using the Minecraft chat and other things.", //
|
||||
"Usage: /connect <Minecraftname>" //
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
package buttondevteam.discordplugin.commands;
|
||||
|
||||
import buttondevteam.discordplugin.DiscordPlugin;
|
||||
import buttondevteam.discordplugin.listeners.CommandListener;
|
||||
import buttondevteam.discordplugin.listeners.CommonListeners;
|
||||
import sx.blah.discord.handle.obj.IMessage;
|
||||
|
||||
public class DebugCommand extends DiscordCommandBase {
|
||||
|
@ -13,7 +13,7 @@ public class DebugCommand extends DiscordCommandBase {
|
|||
@Override
|
||||
public boolean run(IMessage message, String args) {
|
||||
if (message.getAuthor().hasRole(DiscordPlugin.mainServer.getRoleByID(126030201472811008L)))
|
||||
message.reply("Debug " + (CommandListener.debug() ? "enabled" : "disabled"));
|
||||
message.reply("Debug " + (CommonListeners.debug() ? "enabled" : "disabled"));
|
||||
else
|
||||
message.reply("You need to be a moderator to use this command.");
|
||||
return true;
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package buttondevteam.discordplugin.commands;
|
||||
|
||||
import buttondevteam.discordplugin.DiscordPlugin;
|
||||
import buttondevteam.discordplugin.mcchat.MCChatCommand;
|
||||
import buttondevteam.lib.TBMCCoreAPI;
|
||||
import sx.blah.discord.handle.obj.IMessage;
|
||||
|
||||
|
@ -8,7 +9,7 @@ import java.util.Arrays;
|
|||
import java.util.HashMap;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static buttondevteam.discordplugin.listeners.CommandListener.debug;
|
||||
import static buttondevteam.discordplugin.listeners.CommonListeners.debug;
|
||||
|
||||
public abstract class DiscordCommandBase {
|
||||
public abstract String getCommandName();
|
||||
|
|
|
@ -3,7 +3,6 @@ package buttondevteam.discordplugin.commands;
|
|||
import buttondevteam.discordplugin.DiscordPlugin;
|
||||
import sx.blah.discord.handle.obj.IMessage;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class HelpCommand extends DiscordCommandBase {
|
||||
|
@ -19,11 +18,11 @@ public class HelpCommand extends DiscordCommandBase {
|
|||
if (args.length() == 0)
|
||||
DiscordPlugin.sendMessageToChannel(message.getChannel(),
|
||||
"Available commands:\n" + DiscordCommandBase.commands.values().stream()
|
||||
.map(dc -> dc.getCommandName()).collect(Collectors.joining("\n")));
|
||||
.map(dc -> DiscordPlugin.getPrefix() + dc.getCommandName()).collect(Collectors.joining("\n")));
|
||||
else
|
||||
DiscordPlugin.sendMessageToChannel(message.getChannel(),
|
||||
(argdc = DiscordCommandBase.commands.get(args)) == null ? "Command not found: " + args
|
||||
: Arrays.stream(argdc.getHelpText()).collect(Collectors.joining("\n")));
|
||||
: String.join("\n", argdc.getHelpText()));
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -32,7 +31,7 @@ public class HelpCommand extends DiscordCommandBase {
|
|||
return new String[] { //
|
||||
"---- Help command ----", //
|
||||
"Shows some info about a command or lists the available commands.", //
|
||||
"Usage: help [command]"//
|
||||
"Usage: " + DiscordPlugin.getPrefix() + "help [command]"//
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -86,7 +86,7 @@ public class RoleCommand extends DiscordCommandBase {
|
|||
public String[] getHelpText() {
|
||||
return new String[]{ //
|
||||
"Add or remove game roles from yourself.", //
|
||||
"Usage: role add|remove <name> or role list", //
|
||||
"Usage: " + DiscordPlugin.getPrefix() + "role add|remove <name> or role list", //
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -91,7 +91,8 @@ public class UserinfoCommand extends DiscordCommandBase {
|
|||
"---- 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: userinfo [username/nickname[#tag]/ping]\nExamples:\nuserinfo ChromaBot\nuserinfo ChromaBot#6338\nuserinfo @ChromaBot#6338" //
|
||||
"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,4 +1,4 @@
|
|||
package buttondevteam.discordplugin.listeners;
|
||||
package buttondevteam.discordplugin.exceptions;
|
||||
|
||||
import buttondevteam.discordplugin.DiscordPlugin;
|
||||
import buttondevteam.lib.TBMCDebugMessageEvent;
|
|
@ -1,9 +1,12 @@
|
|||
package buttondevteam.discordplugin.listeners;
|
||||
package buttondevteam.discordplugin.exceptions;
|
||||
|
||||
import buttondevteam.core.ComponentManager;
|
||||
import buttondevteam.discordplugin.DiscordPlugin;
|
||||
import buttondevteam.lib.TBMCCoreAPI;
|
||||
import buttondevteam.lib.TBMCExceptionEvent;
|
||||
import buttondevteam.lib.architecture.Component;
|
||||
import org.apache.commons.lang.exception.ExceptionUtils;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.Listener;
|
||||
import sx.blah.discord.handle.obj.IRole;
|
||||
|
@ -13,13 +16,13 @@ import java.util.Arrays;
|
|||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class ExceptionListener implements Listener {
|
||||
public class ExceptionListenerModule extends Component implements Listener {
|
||||
private List<Throwable> lastthrown = new ArrayList<>();
|
||||
private List<String> lastsourcemsg = new ArrayList<>();
|
||||
|
||||
@EventHandler
|
||||
public void onException(TBMCExceptionEvent e) {
|
||||
if (DiscordPlugin.SafeMode)
|
||||
if (DiscordPlugin.SafeMode || !ComponentManager.isEnabled(getClass()))
|
||||
return;
|
||||
if (lastthrown.stream()
|
||||
.anyMatch(ex -> Arrays.equals(e.getException().getStackTrace(), ex.getStackTrace())
|
||||
|
@ -59,4 +62,15 @@ public class ExceptionListener implements Listener {
|
|||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void enable() {
|
||||
Bukkit.getPluginManager().registerEvents(new ExceptionListenerModule(), getPlugin());
|
||||
TBMCCoreAPI.RegisterEventsForExceptions(new DebugMessageListener(), getPlugin());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void disable() {
|
||||
|
||||
}
|
||||
}
|
86
src/main/java/buttondevteam/discordplugin/fun/FunModule.java
Normal file
86
src/main/java/buttondevteam/discordplugin/fun/FunModule.java
Normal file
|
@ -0,0 +1,86 @@
|
|||
package buttondevteam.discordplugin.fun;
|
||||
|
||||
import buttondevteam.core.ComponentManager;
|
||||
import buttondevteam.discordplugin.DiscordPlugin;
|
||||
import buttondevteam.lib.TBMCCoreAPI;
|
||||
import buttondevteam.lib.architecture.Component;
|
||||
import buttondevteam.lib.architecture.ConfigData;
|
||||
import sx.blah.discord.handle.obj.IMessage;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
|
||||
public class FunModule extends Component {
|
||||
private static FunModule mod;
|
||||
|
||||
private static final String[] serverReadyStrings = new String[]{"In one week from now", // Ali
|
||||
"Between now and the heat-death of the universe.", // Ghostise
|
||||
"Soon™", "Ask again this time next month", // Ghostise
|
||||
"In about 3 seconds", // Nicolai
|
||||
"After we finish 8 plugins", // Ali
|
||||
"Tomorrow.", // Ali
|
||||
"After one tiiiny feature", // Ali
|
||||
"Next commit", // Ali
|
||||
"After we finish strangling Towny", // Ali
|
||||
"When we kill every *fucking* bug", // Ali
|
||||
"Once the server stops screaming.", // Ali
|
||||
"After HL3 comes out", // Ali
|
||||
"Next time you ask", // Ali
|
||||
"When will *you* be open?" // Ali
|
||||
};
|
||||
|
||||
private ConfigData<Boolean> serverReady() {
|
||||
return getData("serverReady", true);
|
||||
}
|
||||
|
||||
private ConfigData<List<String>> serverReadyAnswers() {
|
||||
return getData("serverReadyAnswers", Arrays.asList(serverReadyStrings),
|
||||
data -> (List<String>) data, data -> data); //TODO: Test
|
||||
}
|
||||
|
||||
private static final String[] serverReadyQuestions = new String[]{"when will the server be open",
|
||||
"when will the server be ready", "when will the server be done", "when will the server be complete",
|
||||
"when will the server be finished", "when's the server ready", "when's the server open",
|
||||
"Vhen vill ze server be open?"};
|
||||
|
||||
private static final Random serverReadyRandom = new Random();
|
||||
private static final ArrayList<Short> usableServerReadyStrings = new ArrayList<Short>(serverReadyStrings.length) {
|
||||
private static final long serialVersionUID = 2213771460909848770L;
|
||||
|
||||
{
|
||||
createUsableServerReadyStrings(this);
|
||||
}
|
||||
};
|
||||
|
||||
private static void createUsableServerReadyStrings(ArrayList<Short> list) {
|
||||
for (short i = 0; i < serverReadyStrings.length; i++)
|
||||
list.add(i);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void enable() {
|
||||
mod = this;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void disable() {
|
||||
}
|
||||
|
||||
public static boolean executeMemes(IMessage message) {
|
||||
if (!ComponentManager.isEnabled(FunModule.class)) return false;
|
||||
if (mod.serverReady().get()) {
|
||||
if (!TBMCCoreAPI.IsTestServer()
|
||||
&& Arrays.stream(serverReadyQuestions).anyMatch(s -> message.getContent().toLowerCase().contains(s))) {
|
||||
int next;
|
||||
if (usableServerReadyStrings.size() == 0)
|
||||
createUsableServerReadyStrings(usableServerReadyStrings);
|
||||
next = usableServerReadyStrings.remove(serverReadyRandom.nextInt(usableServerReadyStrings.size()));
|
||||
DiscordPlugin.sendMessageToChannel(message.getChannel(), serverReadyStrings[next]);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
279
src/main/java/buttondevteam/discordplugin/listeners/CommandListener.java
Executable file → Normal file
279
src/main/java/buttondevteam/discordplugin/listeners/CommandListener.java
Executable file → Normal file
|
@ -2,226 +2,71 @@ package buttondevteam.discordplugin.listeners;
|
|||
|
||||
import buttondevteam.discordplugin.DiscordPlugin;
|
||||
import buttondevteam.discordplugin.commands.DiscordCommandBase;
|
||||
import buttondevteam.lib.TBMCCoreAPI;
|
||||
import lombok.val;
|
||||
import org.bukkit.Bukkit;
|
||||
import sx.blah.discord.api.events.IListener;
|
||||
import sx.blah.discord.handle.impl.events.guild.channel.message.MentionEvent;
|
||||
import sx.blah.discord.handle.impl.events.guild.channel.message.MessageReceivedEvent;
|
||||
import sx.blah.discord.handle.impl.events.guild.role.RoleCreateEvent;
|
||||
import sx.blah.discord.handle.impl.events.guild.role.RoleDeleteEvent;
|
||||
import sx.blah.discord.handle.impl.events.guild.role.RoleUpdateEvent;
|
||||
import sx.blah.discord.handle.impl.events.user.PresenceUpdateEvent;
|
||||
import sx.blah.discord.handle.obj.IChannel;
|
||||
import sx.blah.discord.handle.obj.IMessage;
|
||||
import sx.blah.discord.handle.obj.StatusType;
|
||||
import sx.blah.discord.util.EmbedBuilder;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Calendar;
|
||||
import java.util.Random;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import sx.blah.discord.handle.obj.IRole;
|
||||
|
||||
public class CommandListener {
|
||||
/**
|
||||
* Runs a ChromaBot command. If mentionedonly is false, it will only execute the command if it was in #bot with the correct prefix or in private.
|
||||
*
|
||||
* @param message The Discord message
|
||||
* @param mentionedonly Only run the command if ChromaBot is mentioned at the start of the message
|
||||
* @return Whether it ran the command
|
||||
*/
|
||||
public static boolean runCommand(IMessage message, boolean mentionedonly) {
|
||||
if (message.getContent().length() == 0)
|
||||
return false; //Pin messages and such, let the mcchat listener deal with it
|
||||
final IChannel channel = message.getChannel();
|
||||
if (!mentionedonly) { //mentionedonly conditions are in CommonListeners
|
||||
if (!message.getChannel().isPrivate()
|
||||
&& !(message.getContent().charAt(0) == DiscordPlugin.getPrefix()
|
||||
&& channel.getStringID().equals(DiscordPlugin.botchannel.getStringID()))) //
|
||||
return false;
|
||||
message.getChannel().setTypingStatus(true); // Fun
|
||||
}
|
||||
final StringBuilder cmdwithargs = new StringBuilder(message.getContent());
|
||||
final String mention = DiscordPlugin.dc.getOurUser().mention(false);
|
||||
final String mentionNick = DiscordPlugin.dc.getOurUser().mention(true);
|
||||
boolean gotmention = checkanddeletemention(cmdwithargs, mention, message);
|
||||
gotmention = checkanddeletemention(cmdwithargs, mentionNick, message) || gotmention;
|
||||
for (String mentionRole : (Iterable<String>) message.getRoleMentions().stream().filter(r -> DiscordPlugin.dc.getOurUser().hasRole(r)).map(IRole::mention)::iterator)
|
||||
gotmention = checkanddeletemention(cmdwithargs, mentionRole, message) || gotmention; // Delete all mentions
|
||||
if (mentionedonly && !gotmention) {
|
||||
message.getChannel().setTypingStatus(false);
|
||||
return false;
|
||||
}
|
||||
message.getChannel().setTypingStatus(true);
|
||||
String cmdwithargsString = cmdwithargs.toString().trim(); //Remove spaces between mention and command
|
||||
int index = cmdwithargsString.indexOf(" ");
|
||||
String cmd;
|
||||
String args;
|
||||
if (index == -1) {
|
||||
cmd = cmdwithargsString;
|
||||
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);
|
||||
return true;
|
||||
}
|
||||
|
||||
private static final String[] serverReadyStrings = new String[]{"In one week from now", // Ali
|
||||
"Between now and the heat-death of the universe.", // Ghostise
|
||||
"Soon™", "Ask again this time next month", // Ghostise
|
||||
"In about 3 seconds", // Nicolai
|
||||
"After we finish 8 plugins", // Ali
|
||||
"Tomorrow.", // Ali
|
||||
"After one tiiiny feature", // Ali
|
||||
"Next commit", // Ali
|
||||
"After we finish strangling Towny", // Ali
|
||||
"When we kill every *fucking* bug", // Ali
|
||||
"Once the server stops screaming.", // Ali
|
||||
"After HL3 comes out", // Ali
|
||||
"Next time you ask", // Ali
|
||||
"When will *you* be open?" // Ali
|
||||
};
|
||||
|
||||
private static final String[] serverReadyQuestions = new String[]{"when will the server be open",
|
||||
"when will the server be ready", "when will the server be done", "when will the server be complete",
|
||||
"when will the server be finished", "when's the server ready", "when's the server open",
|
||||
"Vhen vill ze server be open?"};
|
||||
|
||||
private static final Random serverReadyRandom = new Random();
|
||||
private static final ArrayList<Short> usableServerReadyStrings = new ArrayList<Short>(serverReadyStrings.length) {
|
||||
private static final long serialVersionUID = 2213771460909848770L;
|
||||
|
||||
{
|
||||
createUsableServerReadyStrings(this);
|
||||
}
|
||||
};
|
||||
|
||||
private static void createUsableServerReadyStrings(ArrayList<Short> list) {
|
||||
for (short i = 0; i < serverReadyStrings.length; i++)
|
||||
list.add(i);
|
||||
}
|
||||
|
||||
private static long lasttime = 0;
|
||||
|
||||
public static IListener<?>[] getListeners() {
|
||||
return new IListener[]{new IListener<MentionEvent>() {
|
||||
@Override
|
||||
public void handle(MentionEvent event) {
|
||||
if (DiscordPlugin.SafeMode)
|
||||
return;
|
||||
if (event.getMessage().getAuthor().isBot())
|
||||
return;
|
||||
final IChannel channel = event.getMessage().getChannel();
|
||||
if (!channel.getStringID().equals(DiscordPlugin.botchannel.getStringID())
|
||||
&& (!event.getMessage().getContent().contains("channelcon") || MCChatListener.hasCustomChat(channel))) //Allow channelcon in other servers but avoid double handling when it's enabled
|
||||
return;
|
||||
if (channel.getStringID().equals(DiscordPlugin.chatchannel.getStringID()))
|
||||
return; // The chat code already handles this - Right now while testing botchannel is the same as chatchannel
|
||||
event.getMessage().getChannel().setTypingStatus(true); // Fun
|
||||
runCommand(event.getMessage(), true);
|
||||
}
|
||||
}, new IListener<MessageReceivedEvent>() {
|
||||
@Override
|
||||
public void handle(MessageReceivedEvent event) {
|
||||
if (DiscordPlugin.SafeMode)
|
||||
return;
|
||||
final String msglowercase = event.getMessage().getContent().toLowerCase();
|
||||
if (!TBMCCoreAPI.IsTestServer()
|
||||
&& Arrays.stream(serverReadyQuestions).anyMatch(s -> msglowercase.contains(s))) {
|
||||
int next;
|
||||
if (usableServerReadyStrings.size() == 0)
|
||||
createUsableServerReadyStrings(usableServerReadyStrings);
|
||||
next = usableServerReadyStrings.remove(serverReadyRandom.nextInt(usableServerReadyStrings.size()));
|
||||
DiscordPlugin.sendMessageToChannel(event.getMessage().getChannel(), serverReadyStrings[next]);
|
||||
return;
|
||||
}
|
||||
if (!event.getMessage().getChannel().isPrivate()
|
||||
&& !(event.getMessage().getContent().startsWith("/")
|
||||
&& event.getChannel().getStringID().equals(DiscordPlugin.botchannel.getStringID()))) //
|
||||
return;
|
||||
if (MCChatListener.isMinecraftChatEnabled(event.getAuthor().toString()))
|
||||
if (!event.getMessage().getContent().equalsIgnoreCase("mcchat"))
|
||||
return;
|
||||
if (event.getMessage().getAuthor().isBot())
|
||||
return;
|
||||
runCommand(event.getMessage(), false);
|
||||
}
|
||||
}, new IListener<sx.blah.discord.handle.impl.events.user.PresenceUpdateEvent>() {
|
||||
@Override
|
||||
public void handle(PresenceUpdateEvent event) {
|
||||
if (DiscordPlugin.SafeMode)
|
||||
return;
|
||||
val devrole = DiscordPlugin.devServer.getRolesByName("Developer").get(0);
|
||||
if (event.getOldPresence().getStatus().equals(StatusType.OFFLINE)
|
||||
&& !event.getNewPresence().getStatus().equals(StatusType.OFFLINE)
|
||||
&& event.getUser().getRolesForGuild(DiscordPlugin.devServer).stream()
|
||||
.anyMatch(r -> r.getLongID() == devrole.getLongID())
|
||||
&& DiscordPlugin.devServer.getUsersByRole(devrole).stream()
|
||||
.noneMatch(u -> u.getPresence().getStatus().equals(StatusType.OFFLINE))
|
||||
&& lasttime + 10 < TimeUnit.NANOSECONDS.toHours(System.nanoTime())
|
||||
&& Calendar.getInstance().get(Calendar.DAY_OF_MONTH) % 5 == 0) {
|
||||
DiscordPlugin.sendMessageToChannel(DiscordPlugin.devofficechannel, "Full house!",
|
||||
new EmbedBuilder()
|
||||
.withImage(
|
||||
"https://cdn.discordapp.com/attachments/249295547263877121/249687682618359808/poker-hand-full-house-aces-kings-playing-cards-15553791.png")
|
||||
.build());
|
||||
lasttime = TimeUnit.NANOSECONDS.toHours(System.nanoTime());
|
||||
}
|
||||
}
|
||||
}, (IListener<RoleCreateEvent>) event -> {
|
||||
Bukkit.getScheduler().runTaskLaterAsynchronously(DiscordPlugin.plugin, () -> {
|
||||
if (event.getRole().isDeleted() || !DiscordPlugin.plugin.isGameRole(event.getRole()))
|
||||
return; //Deleted or not a game role
|
||||
DiscordPlugin.GameRoles.add(event.getRole().getName());
|
||||
DiscordPlugin.sendMessageToChannel(DiscordPlugin.modlogchannel, "Added " + event.getRole().getName() + " as game role. If you don't want this, change the role's color from the default.");
|
||||
}, 100);
|
||||
}, (IListener<RoleDeleteEvent>) event -> {
|
||||
if (DiscordPlugin.GameRoles.remove(event.getRole().getName()))
|
||||
DiscordPlugin.sendMessageToChannel(DiscordPlugin.modlogchannel, "Removed " + event.getRole().getName() + " as a game role.");
|
||||
}, (IListener<RoleUpdateEvent>) event -> { //Role update event
|
||||
if (!DiscordPlugin.plugin.isGameRole(event.getNewRole())) {
|
||||
if (DiscordPlugin.GameRoles.remove(event.getOldRole().getName()))
|
||||
DiscordPlugin.sendMessageToChannel(DiscordPlugin.modlogchannel, "Removed " + event.getOldRole().getName() + " as a game role because it's color changed.");
|
||||
} else {
|
||||
if (DiscordPlugin.GameRoles.contains(event.getOldRole().getName()) && event.getOldRole().getName().equals(event.getNewRole().getName()))
|
||||
return;
|
||||
boolean removed = DiscordPlugin.GameRoles.remove(event.getOldRole().getName()); //Regardless of whether it was a game role
|
||||
DiscordPlugin.GameRoles.add(event.getNewRole().getName()); //Add it because it has no color
|
||||
if (removed)
|
||||
DiscordPlugin.sendMessageToChannel(DiscordPlugin.modlogchannel, "Changed game role from " + event.getOldRole().getName() + " to " + event.getNewRole().getName() + ".");
|
||||
else
|
||||
DiscordPlugin.sendMessageToChannel(DiscordPlugin.modlogchannel, "Added " + event.getNewRole().getName() + " as game role because it has the default color.");
|
||||
}
|
||||
}};
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs a ChromaBot command.
|
||||
*
|
||||
* @param message The Discord message
|
||||
* @param mentionedonly Only run the command if ChromaBot is mentioned at the start of the message
|
||||
* @return Whether it ran the command (always true if mentionedonly is false)
|
||||
*/
|
||||
public static boolean runCommand(IMessage message, boolean mentionedonly) {
|
||||
debug("A");
|
||||
if (DiscordPlugin.SafeMode)
|
||||
return true;
|
||||
debug("B");
|
||||
final StringBuilder cmdwithargs = new StringBuilder(message.getContent());
|
||||
final String mention = DiscordPlugin.dc.getOurUser().mention(false);
|
||||
final String mentionNick = DiscordPlugin.dc.getOurUser().mention(true);
|
||||
boolean gotmention = checkanddeletemention(cmdwithargs, mention, message);
|
||||
gotmention = checkanddeletemention(cmdwithargs, mentionNick, message) || gotmention;
|
||||
for (String mentionRole : (Iterable<String>) message.getRoleMentions().stream().filter(r -> DiscordPlugin.dc.getOurUser().hasRole(r)).map(r -> r.mention())::iterator)
|
||||
gotmention = checkanddeletemention(cmdwithargs, mentionRole, message) || gotmention; // Delete all mentions
|
||||
debug("C");
|
||||
if (mentionedonly && !gotmention) {
|
||||
message.getChannel().setTypingStatus(false);
|
||||
return false;
|
||||
}
|
||||
debug("D");
|
||||
message.getChannel().setTypingStatus(true);
|
||||
String cmdwithargsString = cmdwithargs.toString().trim(); //Remove spaces between mention and command
|
||||
int index = cmdwithargsString.indexOf(" ");
|
||||
String cmd;
|
||||
String args;
|
||||
if (index == -1) {
|
||||
cmd = cmdwithargsString;
|
||||
args = "";
|
||||
} else {
|
||||
cmd = cmdwithargsString.substring(0, index);
|
||||
args = cmdwithargsString.substring(index + 1).trim(); //In case there are multiple spaces
|
||||
}
|
||||
debug("E");
|
||||
DiscordCommandBase.runCommand(cmd.toLowerCase(), args, message);
|
||||
message.getChannel().setTypingStatus(false);
|
||||
return true;
|
||||
}
|
||||
|
||||
private static boolean debug = false;
|
||||
|
||||
public static void debug(String debug) {
|
||||
if (CommandListener.debug) //Debug
|
||||
System.out.println(debug);
|
||||
}
|
||||
|
||||
public static boolean debug() {
|
||||
return debug = !debug;
|
||||
}
|
||||
|
||||
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 (cmdwithargs.length() > mention.length() + 1)
|
||||
cmdwithargs.delete(0,
|
||||
cmdwithargs.charAt(mention.length()) == ' ' ? mention.length() + 1 : mention.length());
|
||||
else
|
||||
cmdwithargs.replace(0, cmdwithargs.length(), "help");
|
||||
else {
|
||||
if (cmdwithargs.length() > 0 && cmdwithargs.charAt(0) == '/')
|
||||
cmdwithargs.deleteCharAt(0); //Don't treat / as mention, mentions can be used in public mcchat
|
||||
return false;
|
||||
}
|
||||
if (cmdwithargs.length() == 0)
|
||||
cmdwithargs.replace(0, cmdwithargs.length(), "help");
|
||||
return true;
|
||||
}
|
||||
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 (cmdwithargs.length() > mention.length() + 1)
|
||||
cmdwithargs.delete(0,
|
||||
cmdwithargs.charAt(mention.length()) == ' ' ? mention.length() + 1 : mention.length());
|
||||
else
|
||||
cmdwithargs.replace(0, cmdwithargs.length(), "help");
|
||||
else {
|
||||
if (cmdwithargs.length() > 0 && cmdwithargs.charAt(0) == '/')
|
||||
cmdwithargs.deleteCharAt(0); //Don't treat / as mention, mentions can be used in public mcchat
|
||||
return false;
|
||||
}
|
||||
if (cmdwithargs.length() == 0)
|
||||
cmdwithargs.replace(0, cmdwithargs.length(), "help");
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
128
src/main/java/buttondevteam/discordplugin/listeners/CommonListeners.java
Executable file
128
src/main/java/buttondevteam/discordplugin/listeners/CommonListeners.java
Executable file
|
@ -0,0 +1,128 @@
|
|||
package buttondevteam.discordplugin.listeners;
|
||||
|
||||
import buttondevteam.discordplugin.DPUtils;
|
||||
import buttondevteam.discordplugin.DiscordPlugin;
|
||||
import buttondevteam.discordplugin.mcchat.MinecraftChatModule;
|
||||
import buttondevteam.lib.architecture.Component;
|
||||
import lombok.val;
|
||||
import org.bukkit.Bukkit;
|
||||
import sx.blah.discord.api.events.IListener;
|
||||
import sx.blah.discord.handle.impl.events.guild.channel.message.MessageReceivedEvent;
|
||||
import sx.blah.discord.handle.impl.events.guild.role.RoleCreateEvent;
|
||||
import sx.blah.discord.handle.impl.events.guild.role.RoleDeleteEvent;
|
||||
import sx.blah.discord.handle.impl.events.guild.role.RoleUpdateEvent;
|
||||
import sx.blah.discord.handle.impl.events.user.PresenceUpdateEvent;
|
||||
import sx.blah.discord.handle.obj.StatusType;
|
||||
import sx.blah.discord.util.EmbedBuilder;
|
||||
|
||||
import java.util.Calendar;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
public class CommonListeners {
|
||||
|
||||
/*private static ArrayList<Object> dcListeners=new ArrayList<>();
|
||||
|
||||
public static void registerDiscordListener(DiscordListener listener) {
|
||||
//Step 1: Get all events that are handled by us
|
||||
//Step 2: Find methods that handle these
|
||||
//...or just simply call the methods in the right order
|
||||
}
|
||||
|
||||
private static void callDiscordEvent(Event event) {
|
||||
String name=event.getClass().getSimpleName();
|
||||
name=Character.toLowerCase(name.charAt(0))+name.substring(1);
|
||||
for (Object listener : dcListeners) {
|
||||
listener.getClass().getMethods(name, AsyncDiscordEvent.class);
|
||||
}
|
||||
}*/
|
||||
|
||||
private static long lasttime = 0;
|
||||
|
||||
/*
|
||||
MentionEvent:
|
||||
- CommandListener (starts with mention, only 'channelcon' and not in #bot)
|
||||
|
||||
MessageReceivedEvent:
|
||||
- v CommandListener (starts with mention, in #bot or a connected chat)
|
||||
- Minecraft chat (is enabled in the channel and message isn't [/]mcchat)
|
||||
- CommandListener (with the correct prefix in #bot, or in private)
|
||||
*/
|
||||
public static IListener<?>[] getListeners() {
|
||||
return new IListener[]{new IListener<MessageReceivedEvent>() {
|
||||
@Override
|
||||
public void handle(MessageReceivedEvent event) {
|
||||
if (DiscordPlugin.SafeMode)
|
||||
return;
|
||||
if (event.getMessage().getAuthor().isBot())
|
||||
return;
|
||||
boolean handled = false;
|
||||
if (event.getChannel().getLongID() == DiscordPlugin.botchannel.getLongID() //If mentioned, that's higher than chat
|
||||
|| event.getMessage().getContent().contains("channelcon")) //Only 'channelcon' is allowed in other channels
|
||||
handled = CommandListener.runCommand(event.getMessage(), true); //#bot is handled here
|
||||
if (handled) return;
|
||||
val mcchat = Component.getComponents().get(MinecraftChatModule.class);
|
||||
if (mcchat != null && mcchat.isEnabled()) //ComponentManager.isEnabled() searches the component again
|
||||
handled = ((MinecraftChatModule) mcchat).getListener().handleDiscord(event); //Also runs Discord commands in chat channels
|
||||
if (!handled)
|
||||
handled = CommandListener.runCommand(event.getMessage(), false);
|
||||
}
|
||||
}, new IListener<sx.blah.discord.handle.impl.events.user.PresenceUpdateEvent>() {
|
||||
@Override
|
||||
public void handle(PresenceUpdateEvent event) {
|
||||
if (DiscordPlugin.SafeMode)
|
||||
return;
|
||||
val devrole = DiscordPlugin.devServer.getRolesByName("Developer").get(0);
|
||||
if (event.getOldPresence().getStatus().equals(StatusType.OFFLINE)
|
||||
&& !event.getNewPresence().getStatus().equals(StatusType.OFFLINE)
|
||||
&& event.getUser().getRolesForGuild(DiscordPlugin.devServer).stream()
|
||||
.anyMatch(r -> r.getLongID() == devrole.getLongID())
|
||||
&& DiscordPlugin.devServer.getUsersByRole(devrole).stream()
|
||||
.noneMatch(u -> u.getPresence().getStatus().equals(StatusType.OFFLINE))
|
||||
&& lasttime + 10 < TimeUnit.NANOSECONDS.toHours(System.nanoTime())
|
||||
&& Calendar.getInstance().get(Calendar.DAY_OF_MONTH) % 5 == 0) {
|
||||
DiscordPlugin.sendMessageToChannel(DiscordPlugin.devofficechannel, "Full house!",
|
||||
new EmbedBuilder()
|
||||
.withImage(
|
||||
"https://cdn.discordapp.com/attachments/249295547263877121/249687682618359808/poker-hand-full-house-aces-kings-playing-cards-15553791.png")
|
||||
.build());
|
||||
lasttime = TimeUnit.NANOSECONDS.toHours(System.nanoTime());
|
||||
}
|
||||
}
|
||||
}, (IListener<RoleCreateEvent>) event -> {
|
||||
Bukkit.getScheduler().runTaskLaterAsynchronously(DiscordPlugin.plugin, () -> {
|
||||
if (event.getRole().isDeleted() || !DiscordPlugin.plugin.isGameRole(event.getRole()))
|
||||
return; //Deleted or not a game role
|
||||
DiscordPlugin.GameRoles.add(event.getRole().getName());
|
||||
DiscordPlugin.sendMessageToChannel(DiscordPlugin.modlogchannel, "Added " + event.getRole().getName() + " as game role. If you don't want this, change the role's color from the default.");
|
||||
}, 100);
|
||||
}, (IListener<RoleDeleteEvent>) event -> {
|
||||
if (DiscordPlugin.GameRoles.remove(event.getRole().getName()))
|
||||
DiscordPlugin.sendMessageToChannel(DiscordPlugin.modlogchannel, "Removed " + event.getRole().getName() + " as a game role.");
|
||||
}, (IListener<RoleUpdateEvent>) event -> { //Role update event
|
||||
if (!DiscordPlugin.plugin.isGameRole(event.getNewRole())) {
|
||||
if (DiscordPlugin.GameRoles.remove(event.getOldRole().getName()))
|
||||
DiscordPlugin.sendMessageToChannel(DiscordPlugin.modlogchannel, "Removed " + event.getOldRole().getName() + " as a game role because it's color changed.");
|
||||
} else {
|
||||
if (DiscordPlugin.GameRoles.contains(event.getOldRole().getName()) && event.getOldRole().getName().equals(event.getNewRole().getName()))
|
||||
return;
|
||||
boolean removed = DiscordPlugin.GameRoles.remove(event.getOldRole().getName()); //Regardless of whether it was a game role
|
||||
DiscordPlugin.GameRoles.add(event.getNewRole().getName()); //Add it because it has no color
|
||||
if (removed)
|
||||
DiscordPlugin.sendMessageToChannel(DiscordPlugin.modlogchannel, "Changed game role from " + event.getOldRole().getName() + " to " + event.getNewRole().getName() + ".");
|
||||
else
|
||||
DiscordPlugin.sendMessageToChannel(DiscordPlugin.modlogchannel, "Added " + event.getNewRole().getName() + " as game role because it has the default color.");
|
||||
}
|
||||
}};
|
||||
}
|
||||
|
||||
private static boolean debug = false;
|
||||
|
||||
public static void debug(String debug) {
|
||||
if (CommonListeners.debug) //Debug
|
||||
DPUtils.getLogger().info(debug);
|
||||
}
|
||||
|
||||
public static boolean debug() {
|
||||
return debug = !debug;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,4 @@
|
|||
package buttondevteam.discordplugin.listeners;
|
||||
|
||||
public interface DiscordListener {
|
||||
}
|
|
@ -1,98 +1,24 @@
|
|||
package buttondevteam.discordplugin.listeners;
|
||||
|
||||
import buttondevteam.discordplugin.*;
|
||||
import buttondevteam.discordplugin.commands.ConnectCommand;
|
||||
import buttondevteam.lib.TBMCCoreAPI;
|
||||
import buttondevteam.lib.TBMCSystemChatEvent;
|
||||
import buttondevteam.lib.player.*;
|
||||
import com.earth2me.essentials.CommandSource;
|
||||
import buttondevteam.discordplugin.DiscordPlayer;
|
||||
import buttondevteam.discordplugin.DiscordPlugin;
|
||||
import buttondevteam.lib.player.TBMCPlayerGetInfoEvent;
|
||||
import lombok.val;
|
||||
import net.ess3.api.events.AfkStatusChangeEvent;
|
||||
import net.ess3.api.events.MuteStatusChangeEvent;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.*;
|
||||
import org.bukkit.event.entity.PlayerDeathEvent;
|
||||
import org.bukkit.event.player.PlayerJoinEvent;
|
||||
import org.bukkit.event.player.PlayerKickEvent;
|
||||
import org.bukkit.event.player.PlayerLoginEvent;
|
||||
import org.bukkit.event.player.PlayerLoginEvent.Result;
|
||||
import org.bukkit.event.player.PlayerQuitEvent;
|
||||
import org.bukkit.event.server.BroadcastMessageEvent;
|
||||
import org.bukkit.event.Event;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.HandlerList;
|
||||
import org.bukkit.event.Listener;
|
||||
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.IRole;
|
||||
import sx.blah.discord.handle.obj.IUser;
|
||||
import sx.blah.discord.util.DiscordException;
|
||||
import sx.blah.discord.util.MissingPermissionsException;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.logging.Level;
|
||||
|
||||
public class MCListener implements Listener {
|
||||
@EventHandler(priority = EventPriority.HIGHEST)
|
||||
public void onPlayerLogin(PlayerLoginEvent e) {
|
||||
if (e.getResult() != Result.ALLOWED)
|
||||
return;
|
||||
MCChatListener.ConnectedSenders.values().stream().flatMap(v -> v.values().stream()) //Only private mcchat should be in ConnectedSenders
|
||||
.filter(s -> s.getUniqueId().equals(e.getPlayer().getUniqueId())).findAny()
|
||||
.ifPresent(dcp -> callEventExcludingSome(new PlayerQuitEvent(dcp, "")));
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.LOWEST)
|
||||
public void onPlayerJoin(TBMCPlayerJoinEvent e) {
|
||||
if (e.getPlayer() instanceof DiscordConnectedPlayer)
|
||||
return; // Don't show the joined message for the fake player
|
||||
Bukkit.getScheduler().runTaskAsynchronously(DiscordPlugin.plugin, () -> {
|
||||
final Player p = e.getPlayer();
|
||||
DiscordPlayer dp = e.GetPlayer().getAs(DiscordPlayer.class);
|
||||
if (dp != null) {
|
||||
val user = DiscordPlugin.dc.getUserByID(Long.parseLong(dp.getDiscordID()));
|
||||
MCChatListener.addSender(MCChatListener.OnlineSenders, dp.getDiscordID(),
|
||||
new DiscordPlayerSender(user, user.getOrCreatePMChannel(), p));
|
||||
MCChatListener.addSender(MCChatListener.OnlineSenders, dp.getDiscordID(),
|
||||
new DiscordPlayerSender(user, DiscordPlugin.chatchannel, p)); //Stored per-channel
|
||||
}
|
||||
if (ConnectCommand.WaitingToConnect.containsKey(e.GetPlayer().PlayerName().get())) {
|
||||
IUser user = DiscordPlugin.dc
|
||||
.getUserByID(Long.parseLong(ConnectCommand.WaitingToConnect.get(e.GetPlayer().PlayerName().get())));
|
||||
p.sendMessage("§bTo connect with the Discord account @" + user.getName() + "#" + user.getDiscriminator()
|
||||
+ " do /discord accept");
|
||||
p.sendMessage("§bIf it wasn't you, do /discord decline");
|
||||
}
|
||||
final String message = e.GetPlayer().PlayerName().get() + " joined the game";
|
||||
MCChatListener.forAllowedCustomAndAllMCChat(MCChatListener.send(message), e.getPlayer(), ChannelconBroadcast.JOINLEAVE, true);
|
||||
//System.out.println("Does this appear more than once?"); //No
|
||||
MCChatListener.ListC = 0;
|
||||
ChromaBot.getInstance().updatePlayerList();
|
||||
});
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.HIGHEST)
|
||||
public void onPlayerLeave(TBMCPlayerQuitEvent e) {
|
||||
if (e.getPlayer() instanceof DiscordConnectedPlayer)
|
||||
return; // Only care about real users
|
||||
MCChatListener.OnlineSenders.entrySet()
|
||||
.removeIf(entry -> entry.getValue().entrySet().stream().anyMatch(p -> p.getValue().getUniqueId().equals(e.getPlayer().getUniqueId())));
|
||||
Bukkit.getScheduler().runTask(DiscordPlugin.plugin,
|
||||
() -> MCChatListener.ConnectedSenders.values().stream().flatMap(v -> v.values().stream())
|
||||
.filter(s -> s.getUniqueId().equals(e.getPlayer().getUniqueId())).findAny()
|
||||
.ifPresent(dcp -> callEventExcludingSome(new PlayerJoinEvent(dcp, ""))));
|
||||
Bukkit.getScheduler().runTaskLaterAsynchronously(DiscordPlugin.plugin,
|
||||
ChromaBot.getInstance()::updatePlayerList, 5);
|
||||
final String message = e.GetPlayer().PlayerName().get() + " left the game";
|
||||
MCChatListener.forAllowedCustomAndAllMCChat(MCChatListener.send(message), e.getPlayer(), ChannelconBroadcast.JOINLEAVE, true);
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.HIGHEST)
|
||||
public void onPlayerKick(PlayerKickEvent e) {
|
||||
/*if (!DiscordPlugin.hooked && !e.getReason().equals("The server is restarting")
|
||||
&& !e.getReason().equals("Server closed")) // The leave messages errored with the previous setup, I could make it wait since I moved it here, but instead I have a special
|
||||
MCChatListener.forAllowedCustomAndAllMCChat(e.getPlayer().getName() + " left the game"); // message for this - Oh wait this doesn't even send normally because of the hook*/
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onGetInfo(TBMCPlayerGetInfoEvent e) {
|
||||
if (DiscordPlugin.SafeMode)
|
||||
|
@ -107,125 +33,71 @@ public class MCListener implements Listener {
|
|||
e.addInfo(user.getPresence().getActivity().get() + ": " + user.getPresence().getText().get());
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.LOW)
|
||||
public void onPlayerDeath(PlayerDeathEvent e) {
|
||||
MCChatListener.forAllowedCustomAndAllMCChat(MCChatListener.send(e.getDeathMessage()), e.getEntity(), ChannelconBroadcast.DEATH, true);
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onPlayerAFK(AfkStatusChangeEvent e) {
|
||||
final Player base = e.getAffected().getBase();
|
||||
if (e.isCancelled() || !base.isOnline())
|
||||
return;
|
||||
final String msg = base.getDisplayName()
|
||||
+ " is " + (e.getValue() ? "now" : "no longer") + " AFK.";
|
||||
MCChatListener.forAllowedCustomAndAllMCChat(MCChatListener.send(msg), base, ChannelconBroadcast.AFK, false);
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onServerCommand(ServerCommandEvent e) {
|
||||
DiscordPlugin.Restart = !e.getCommand().equalsIgnoreCase("stop"); // The variable is always true except if stopped
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onPlayerMute(MuteStatusChangeEvent e) {
|
||||
try {
|
||||
DPUtils.performNoWait(() -> {
|
||||
final IRole role = DiscordPlugin.dc.getRoleByID(164090010461667328L);
|
||||
final CommandSource source = e.getAffected().getSource();
|
||||
if (!source.isPlayer())
|
||||
return;
|
||||
final IUser user = DiscordPlugin.dc.getUserByID(
|
||||
Long.parseLong(TBMCPlayerBase.getPlayer(source.getPlayer().getUniqueId(), TBMCPlayer.class)
|
||||
.getAs(DiscordPlayer.class).getDiscordID()));
|
||||
if (e.getValue())
|
||||
user.addRole(role);
|
||||
else
|
||||
user.removeRole(role);
|
||||
});
|
||||
} catch (DiscordException | MissingPermissionsException ex) {
|
||||
TBMCCoreAPI.SendException("Failed to give/take Muted role to player " + e.getAffected().getName() + "!",
|
||||
ex);
|
||||
}
|
||||
}
|
||||
private static final String[] EXCLUDED_PLUGINS = {"ProtocolLib", "LibsDisguises", "JourneyMapServer"}; //TODO: Make configurable
|
||||
|
||||
@EventHandler
|
||||
public void onChatSystemMessage(TBMCSystemChatEvent event) {
|
||||
MCChatListener.forAllowedMCChat(MCChatListener.send(event.getMessage()), event);
|
||||
}
|
||||
public static void callEventExcludingSome(Event event) {
|
||||
callEventExcluding(event, false, EXCLUDED_PLUGINS);
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onBroadcastMessage(BroadcastMessageEvent event) {
|
||||
MCChatListener.forCustomAndAllMCChat(MCChatListener.send(event.getMessage()), ChannelconBroadcast.BROADCAST, false);
|
||||
}
|
||||
/**
|
||||
* 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
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()
|
||||
: event.getSender().getName();
|
||||
//Channel channel = ChromaGamerBase.getFromSender(event.getSender()).channel().get(); - TODO
|
||||
MCChatListener.forAllMCChat(MCChatListener.send(name + " <:YEEHAW:" + DiscordPlugin.mainServer.getEmojiByName("YEEHAW").getStringID() + ">s"));
|
||||
}
|
||||
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();
|
||||
|
||||
private static final String[] EXCLUDED_PLUGINS = {"ProtocolLib", "LibsDisguises"};
|
||||
for (RegisteredListener registration : listeners) {
|
||||
if (!registration.getPlugin().isEnabled()
|
||||
|| Arrays.stream(plugins).anyMatch(p -> only ^ p.equalsIgnoreCase(registration.getPlugin().getName())))
|
||||
continue; // Modified to exclude plugins
|
||||
|
||||
public static void callEventExcludingSome(Event event) {
|
||||
callEventExcluding(event, EXCLUDED_PLUGINS);
|
||||
}
|
||||
try {
|
||||
registration.callEvent(event);
|
||||
} catch (AuthorNagException ex) {
|
||||
Plugin plugin = registration.getPlugin();
|
||||
|
||||
/**
|
||||
* Calls an event with the given details.
|
||||
* <p>
|
||||
* This method only synchronizes when the event is not asynchronous.
|
||||
*
|
||||
* @param event Event details
|
||||
* @param plugins The plugins to exclude. Not case sensitive.
|
||||
*/
|
||||
private static void callEventExcluding(Event event, 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, plugins);
|
||||
} else {
|
||||
synchronized (Bukkit.getPluginManager()) {
|
||||
fireEventExcluding(event, plugins);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (plugin.isNaggable()) {
|
||||
plugin.setNaggable(false);
|
||||
|
||||
private static void fireEventExcluding(Event event, 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 -> 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
package buttondevteam.discordplugin.commands;
|
||||
package buttondevteam.discordplugin.mcchat;
|
||||
|
||||
import buttondevteam.discordplugin.DiscordPlayer;
|
||||
import buttondevteam.discordplugin.DiscordPlugin;
|
||||
import buttondevteam.discordplugin.listeners.MCChatListener;
|
||||
import buttondevteam.discordplugin.commands.DiscordCommandBase;
|
||||
import buttondevteam.lib.TBMCCoreAPI;
|
||||
import sx.blah.discord.handle.obj.IMessage;
|
||||
|
||||
|
@ -13,7 +13,7 @@ public class MCChatCommand extends DiscordCommandBase {
|
|||
return "mcchat";
|
||||
}
|
||||
|
||||
@Override
|
||||
@Override //TODO: Only register if module is enabled
|
||||
public boolean run(IMessage message, String args) {
|
||||
if (!message.getChannel().isPrivate()) {
|
||||
DiscordPlugin.sendMessageToChannel(message.getChannel(),
|
||||
|
@ -22,10 +22,10 @@ public class MCChatCommand extends DiscordCommandBase {
|
|||
}
|
||||
try (final DiscordPlayer user = DiscordPlayer.getUser(message.getAuthor().getStringID(), DiscordPlayer.class)) {
|
||||
boolean mcchat = !user.isMinecraftChatEnabled();
|
||||
MCChatListener.privateMCChat(message.getChannel(), mcchat, message.getAuthor(), user);
|
||||
MCChatPrivate.privateMCChat(message.getChannel(), mcchat, message.getAuthor(), user);
|
||||
DiscordPlugin.sendMessageToChannel(message.getChannel(),
|
||||
"Minecraft chat " + (mcchat //
|
||||
? "enabled. Use '/mcchat' again to turn it off." //
|
||||
? "enabled. Use '" + DiscordPlugin.getPrefix() + "mcchat' again to turn it off." //
|
||||
: "disabled."));
|
||||
} catch (Exception e) {
|
||||
TBMCCoreAPI.SendException("Error while setting mcchat for user" + message.getAuthor().getName(), e);
|
||||
|
@ -36,8 +36,9 @@ public class MCChatCommand extends DiscordCommandBase {
|
|||
@Override
|
||||
public String[] getHelpText() {
|
||||
return new String[] { //
|
||||
"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 a private channel." //
|
||||
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
|
||||
}
|
||||
|
|
@ -0,0 +1,59 @@
|
|||
package buttondevteam.discordplugin.mcchat;
|
||||
|
||||
import buttondevteam.discordplugin.DiscordConnectedPlayer;
|
||||
import buttondevteam.lib.chat.Channel;
|
||||
import lombok.NonNull;
|
||||
import lombok.val;
|
||||
import sx.blah.discord.handle.obj.IChannel;
|
||||
import sx.blah.discord.handle.obj.IUser;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
public class MCChatCustom {
|
||||
/**
|
||||
* Used for town or nation chats or anything else
|
||||
*/
|
||||
static ArrayList<CustomLMD> lastmsgCustom = new ArrayList<>();
|
||||
|
||||
public static void addCustomChat(IChannel channel, String groupid, Channel mcchannel, IUser user, DiscordConnectedPlayer dcp, int toggles) {
|
||||
val lmd = new CustomLMD(channel, user, groupid, mcchannel, dcp, toggles);
|
||||
lastmsgCustom.add(lmd);
|
||||
}
|
||||
|
||||
public static boolean hasCustomChat(IChannel channel) {
|
||||
return lastmsgCustom.stream().anyMatch(lmd -> lmd.channel.getLongID() == channel.getLongID());
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static CustomLMD getCustomChat(IChannel channel) {
|
||||
return lastmsgCustom.stream().filter(lmd -> lmd.channel.getLongID() == channel.getLongID()).findAny().orElse(null);
|
||||
}
|
||||
|
||||
public static boolean removeCustomChat(IChannel channel) {
|
||||
MCChatUtils.lastmsgfromd.remove(channel.getLongID());
|
||||
return lastmsgCustom.removeIf(lmd -> lmd.channel.getLongID() == channel.getLongID());
|
||||
}
|
||||
|
||||
public static List<CustomLMD> getCustomChats() {
|
||||
return Collections.unmodifiableList(lastmsgCustom);
|
||||
}
|
||||
|
||||
public static class CustomLMD extends MCChatUtils.LastMsgData {
|
||||
public final String groupID;
|
||||
public final Channel mcchannel;
|
||||
public final DiscordConnectedPlayer dcp;
|
||||
public int toggles;
|
||||
|
||||
private CustomLMD(@NonNull IChannel channel, @NonNull IUser user,
|
||||
@NonNull String groupid, @NonNull Channel mcchannel, @NonNull DiscordConnectedPlayer dcp, int toggles) {
|
||||
super(channel, user);
|
||||
groupID = groupid;
|
||||
this.mcchannel = mcchannel;
|
||||
this.dcp = dcp;
|
||||
this.toggles = toggles;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,56 +1,48 @@
|
|||
package buttondevteam.discordplugin.listeners;
|
||||
package buttondevteam.discordplugin.mcchat;
|
||||
|
||||
import buttondevteam.discordplugin.*;
|
||||
import buttondevteam.core.ComponentManager;
|
||||
import buttondevteam.discordplugin.DPUtils;
|
||||
import buttondevteam.discordplugin.DiscordPlugin;
|
||||
import buttondevteam.discordplugin.DiscordSender;
|
||||
import buttondevteam.discordplugin.DiscordSenderBase;
|
||||
import buttondevteam.discordplugin.listeners.CommandListener;
|
||||
import buttondevteam.discordplugin.playerfaker.VanillaCommandListener;
|
||||
import buttondevteam.lib.TBMCChatEvent;
|
||||
import buttondevteam.lib.TBMCChatPreprocessEvent;
|
||||
import buttondevteam.lib.TBMCCoreAPI;
|
||||
import buttondevteam.lib.TBMCSystemChatEvent;
|
||||
import buttondevteam.lib.chat.Channel;
|
||||
import buttondevteam.lib.chat.ChatMessage;
|
||||
import buttondevteam.lib.chat.ChatRoom;
|
||||
import buttondevteam.lib.chat.TBMCChatAPI;
|
||||
import buttondevteam.lib.player.TBMCPlayer;
|
||||
import com.vdurmont.emoji.EmojiParser;
|
||||
import io.netty.util.collection.LongObjectHashMap;
|
||||
import lombok.NonNull;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.experimental.var;
|
||||
import lombok.val;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.player.PlayerJoinEvent;
|
||||
import org.bukkit.event.player.PlayerQuitEvent;
|
||||
import org.bukkit.scheduler.BukkitTask;
|
||||
import sx.blah.discord.api.events.IListener;
|
||||
import sx.blah.discord.api.internal.json.objects.EmbedObject;
|
||||
import sx.blah.discord.handle.impl.events.guild.channel.message.MessageReceivedEvent;
|
||||
import sx.blah.discord.handle.obj.IChannel;
|
||||
import sx.blah.discord.handle.obj.IMessage;
|
||||
import sx.blah.discord.handle.obj.IPrivateChannel;
|
||||
import sx.blah.discord.handle.obj.IUser;
|
||||
import sx.blah.discord.util.DiscordException;
|
||||
import sx.blah.discord.util.EmbedBuilder;
|
||||
import sx.blah.discord.util.MissingPermissionsException;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.awt.*;
|
||||
import java.time.Instant;
|
||||
import java.util.*;
|
||||
import java.util.List;
|
||||
import java.util.AbstractMap;
|
||||
import java.util.Arrays;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.LinkedBlockingQueue;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.function.Supplier;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
public class MCChatListener implements Listener, IListener<MessageReceivedEvent> {
|
||||
public class MCChatListener implements Listener {
|
||||
private BukkitTask sendtask;
|
||||
private LinkedBlockingQueue<AbstractMap.SimpleEntry<TBMCChatEvent, Instant>> sendevents = new LinkedBlockingQueue<>();
|
||||
private Runnable sendrunnable;
|
||||
|
@ -58,7 +50,7 @@ public class MCChatListener implements Listener, IListener<MessageReceivedEvent>
|
|||
|
||||
@EventHandler // Minecraft
|
||||
public void onMCChat(TBMCChatEvent ev) {
|
||||
if (DiscordPlugin.SafeMode || ev.isCancelled()) //SafeMode: Needed so it doesn't restart after server shutdown
|
||||
if (!ComponentManager.isEnabled(MinecraftChatModule.class) || ev.isCancelled()) //SafeMode: Needed so it doesn't restart after server shutdown
|
||||
return;
|
||||
sendevents.add(new AbstractMap.SimpleEntry<>(ev, Instant.now()));
|
||||
if (sendtask != null)
|
||||
|
@ -81,7 +73,7 @@ public class MCChatListener implements Listener, IListener<MessageReceivedEvent>
|
|||
time = se.getValue();
|
||||
|
||||
final String authorPlayer = "[" + DPUtils.sanitizeStringNoEscape(e.getChannel().DisplayName) + "] " //
|
||||
+ (e.getSender() instanceof DiscordSenderBase ? "[D]" : "") //
|
||||
+ ("Minecraft".equals(e.getOrigin()) ? "" : "[" + e.getOrigin().substring(0, 1) + "]") //
|
||||
+ (DPUtils.sanitizeStringNoEscape(e.getSender() instanceof Player //
|
||||
? ((Player) e.getSender()).getDisplayName() //
|
||||
: e.getSender().getName()));
|
||||
|
@ -102,7 +94,7 @@ public class MCChatListener implements Listener, IListener<MessageReceivedEvent>
|
|||
// embed.withFooterText(e.getChannel().DisplayName);
|
||||
embed.withTimestamp(time);
|
||||
final long nanoTime = System.nanoTime();
|
||||
InterruptibleConsumer<LastMsgData> doit = lastmsgdata -> {
|
||||
InterruptibleConsumer<MCChatUtils.LastMsgData> doit = lastmsgdata -> {
|
||||
final EmbedObject embedObject = embed.build();
|
||||
if (lastmsgdata.message == null || lastmsgdata.message.isDeleted()
|
||||
|| !authorPlayer.equals(lastmsgdata.message.getEmbeds().get(0).getAuthor().getName())
|
||||
|
@ -117,7 +109,7 @@ public class MCChatListener implements Listener, IListener<MessageReceivedEvent>
|
|||
try {
|
||||
lastmsgdata.content = embedObject.description = lastmsgdata.content + "\n"
|
||||
+ embedObject.description;// The message object doesn't get updated
|
||||
final LastMsgData _lastmsgdata = lastmsgdata;
|
||||
final MCChatUtils.LastMsgData _lastmsgdata = lastmsgdata;
|
||||
DPUtils.perform(() -> _lastmsgdata.message.edit("", embedObject));
|
||||
} catch (MissingPermissionsException | DiscordException e1) {
|
||||
TBMCCoreAPI.SendException("An error occurred while editing chat message!", e1);
|
||||
|
@ -129,21 +121,21 @@ public class MCChatListener implements Listener, IListener<MessageReceivedEvent>
|
|||
|| ((DiscordSenderBase) e.getSender()).getChannel().getLongID() != ch.getLongID();
|
||||
|
||||
if (e.getChannel().isGlobal()
|
||||
&& (e.isFromcmd() || isdifferentchannel.test(DiscordPlugin.chatchannel)))
|
||||
doit.accept(lastmsgdata == null
|
||||
? lastmsgdata = new LastMsgData(DiscordPlugin.chatchannel, null)
|
||||
: lastmsgdata);
|
||||
&& (e.isFromCommand() || isdifferentchannel.test(DiscordPlugin.chatchannel)))
|
||||
doit.accept(MCChatUtils.lastmsgdata == null
|
||||
? MCChatUtils.lastmsgdata = new MCChatUtils.LastMsgData(DiscordPlugin.chatchannel, null)
|
||||
: MCChatUtils.lastmsgdata);
|
||||
|
||||
for (LastMsgData data : lastmsgPerUser) {
|
||||
if ((e.isFromcmd() || isdifferentchannel.test(data.channel))
|
||||
&& e.shouldSendTo(getSender(data.channel, data.user)))
|
||||
for (MCChatUtils.LastMsgData data : MCChatPrivate.lastmsgPerUser) {
|
||||
if ((e.isFromCommand() || isdifferentchannel.test(data.channel))
|
||||
&& e.shouldSendTo(MCChatUtils.getSender(data.channel, data.user)))
|
||||
doit.accept(data);
|
||||
}
|
||||
|
||||
val iterator = lastmsgCustom.iterator();
|
||||
val iterator = MCChatCustom.lastmsgCustom.iterator();
|
||||
while (iterator.hasNext()) {
|
||||
val lmd = iterator.next();
|
||||
if ((e.isFromcmd() || isdifferentchannel.test(lmd.channel)) //Test if msg is from Discord
|
||||
if ((e.isFromCommand() || isdifferentchannel.test(lmd.channel)) //Test if msg is from Discord
|
||||
&& e.getChannel().ID.equals(lmd.mcchannel.ID) //If it's from a command, the command msg has been deleted, so we need to send it
|
||||
&& e.getGroupID().equals(lmd.groupID)) { //Check if this is the group we want to test - #58
|
||||
if (e.shouldSendTo(lmd.dcp)) //Check original user's permissions
|
||||
|
@ -162,32 +154,6 @@ public class MCChatListener implements Listener, IListener<MessageReceivedEvent>
|
|||
}
|
||||
}
|
||||
|
||||
@RequiredArgsConstructor
|
||||
public static class LastMsgData {
|
||||
public IMessage message;
|
||||
public long time;
|
||||
public String content;
|
||||
public final IChannel channel;
|
||||
public Channel mcchannel;
|
||||
public final IUser user;
|
||||
}
|
||||
|
||||
public static class CustomLMD extends LastMsgData {
|
||||
public final String groupID;
|
||||
public final Channel mcchannel;
|
||||
public final DiscordConnectedPlayer dcp;
|
||||
public int toggles;
|
||||
|
||||
private CustomLMD(@NonNull IChannel channel, @NonNull IUser user,
|
||||
@NonNull String groupid, @NonNull Channel mcchannel, @NonNull DiscordConnectedPlayer dcp, int toggles) {
|
||||
super(channel, user);
|
||||
groupID = groupid;
|
||||
this.mcchannel = mcchannel;
|
||||
this.dcp = dcp;
|
||||
this.toggles = toggles;
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onChatPreprocess(TBMCChatPreprocessEvent event) {
|
||||
int start = -1;
|
||||
|
@ -211,72 +177,8 @@ public class MCChatListener implements Listener, IListener<MessageReceivedEvent>
|
|||
private static final String[] UnconnectedCmds = new String[]{"list", "u", "shrug", "tableflip", "unflip", "mwiki",
|
||||
"yeehaw", "lenny", "rp", "plugins"};
|
||||
|
||||
private static LastMsgData lastmsgdata;
|
||||
private static short lastlist = 0;
|
||||
private static short lastlistp = 0;
|
||||
/**
|
||||
* Used for messages in PMs (mcchat).
|
||||
*/
|
||||
private static ArrayList<LastMsgData> lastmsgPerUser = new ArrayList<LastMsgData>();
|
||||
/**
|
||||
* Used for town or nation chats or anything else
|
||||
*/
|
||||
private static ArrayList<CustomLMD> lastmsgCustom = new ArrayList<>();
|
||||
private static LongObjectHashMap<IMessage> lastmsgfromd = new LongObjectHashMap<>(); // Last message sent by a Discord user, used for clearing checkmarks
|
||||
|
||||
public static boolean privateMCChat(IChannel channel, boolean start, IUser user, DiscordPlayer dp) {
|
||||
TBMCPlayer mcp = dp.getAs(TBMCPlayer.class);
|
||||
if (mcp != null) { // If the accounts aren't connected, can't make a connected sender
|
||||
val p = Bukkit.getPlayer(mcp.getUUID());
|
||||
val op = Bukkit.getOfflinePlayer(mcp.getUUID());
|
||||
if (start) {
|
||||
val sender = new DiscordConnectedPlayer(user, channel, mcp.getUUID(), op.getName());
|
||||
addSender(ConnectedSenders, user, sender);
|
||||
if (p == null)// Player is offline - If the player is online, that takes precedence
|
||||
MCListener.callEventExcludingSome(new PlayerJoinEvent(sender, ""));
|
||||
} else {
|
||||
val sender = removeSender(ConnectedSenders, channel, user);
|
||||
if (p == null)// Player is offline - If the player is online, that takes precedence
|
||||
MCListener.callEventExcludingSome(new PlayerQuitEvent(sender, ""));
|
||||
}
|
||||
}
|
||||
if (!start)
|
||||
lastmsgfromd.remove(channel.getLongID());
|
||||
return start //
|
||||
? lastmsgPerUser.add(new LastMsgData(channel, user)) // Doesn't support group DMs
|
||||
: lastmsgPerUser.removeIf(lmd -> lmd.channel.getLongID() == channel.getLongID());
|
||||
}
|
||||
|
||||
public static <T extends DiscordSenderBase> T addSender(HashMap<String, HashMap<IChannel, T>> senders,
|
||||
IUser user, T sender) {
|
||||
return addSender(senders, user.getStringID(), sender);
|
||||
}
|
||||
|
||||
public static <T extends DiscordSenderBase> T addSender(HashMap<String, HashMap<IChannel, T>> senders,
|
||||
String did, T sender) {
|
||||
var map = senders.get(did);
|
||||
if (map == null)
|
||||
map = new HashMap<>();
|
||||
map.put(sender.getChannel(), sender);
|
||||
senders.put(did, map);
|
||||
return sender;
|
||||
}
|
||||
|
||||
public static <T extends DiscordSenderBase> T getSender(HashMap<String, HashMap<IChannel, T>> senders,
|
||||
IChannel channel, IUser user) {
|
||||
var map = senders.get(user.getStringID());
|
||||
if (map != null)
|
||||
return map.get(channel);
|
||||
return null;
|
||||
}
|
||||
|
||||
public static <T extends DiscordSenderBase> T removeSender(HashMap<String, HashMap<IChannel, T>> senders,
|
||||
IChannel channel, IUser user) {
|
||||
var map = senders.get(user.getStringID());
|
||||
if (map != null)
|
||||
return map.remove(channel);
|
||||
return null;
|
||||
}
|
||||
|
||||
// ......................DiscordSender....DiscordConnectedPlayer.DiscordPlayerSender
|
||||
// Offline public chat......x............................................
|
||||
|
@ -289,143 +191,8 @@ public class MCChatListener implements Listener, IListener<MessageReceivedEvent>
|
|||
// If online and disabling private chat, don't logout
|
||||
// The maps may not contain the senders for UnconnectedSenders
|
||||
|
||||
public static boolean isMinecraftChatEnabled(DiscordPlayer dp) {
|
||||
return isMinecraftChatEnabled(dp.getDiscordID());
|
||||
}
|
||||
|
||||
public static boolean isMinecraftChatEnabled(String did) { // Don't load the player data just for this
|
||||
return lastmsgPerUser.stream()
|
||||
.anyMatch(lmd -> ((IPrivateChannel) lmd.channel).getRecipient().getStringID().equals(did));
|
||||
}
|
||||
|
||||
public static void addCustomChat(IChannel channel, String groupid, Channel mcchannel, IUser user, DiscordConnectedPlayer dcp, int toggles) {
|
||||
val lmd = new CustomLMD(channel, user, groupid, mcchannel, dcp, toggles);
|
||||
lastmsgCustom.add(lmd);
|
||||
}
|
||||
|
||||
public static boolean hasCustomChat(IChannel channel) {
|
||||
return lastmsgCustom.stream().anyMatch(lmd -> lmd.channel.getLongID() == channel.getLongID());
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static CustomLMD getCustomChat(IChannel channel) {
|
||||
return lastmsgCustom.stream().filter(lmd -> lmd.channel.getLongID() == channel.getLongID()).findAny().orElse(null);
|
||||
}
|
||||
|
||||
public static boolean removeCustomChat(IChannel channel) {
|
||||
lastmsgfromd.remove(channel.getLongID());
|
||||
return lastmsgCustom.removeIf(lmd -> lmd.channel.getLongID() == channel.getLongID());
|
||||
}
|
||||
|
||||
public static List<CustomLMD> getCustomChats() {
|
||||
return Collections.unmodifiableList(lastmsgCustom);
|
||||
}
|
||||
|
||||
/**
|
||||
* May contain P<DiscordID> as key for public chat
|
||||
*/
|
||||
public static final HashMap<String, HashMap<IChannel, DiscordSender>> UnconnectedSenders = new HashMap<>();
|
||||
public static final HashMap<String, HashMap<IChannel, DiscordConnectedPlayer>> ConnectedSenders = new HashMap<>();
|
||||
/**
|
||||
* May contain P<DiscordID> as key for public chat
|
||||
*/
|
||||
public static final HashMap<String, HashMap<IChannel, DiscordPlayerSender>> OnlineSenders = new HashMap<>();
|
||||
public static short ListC = 0;
|
||||
|
||||
/**
|
||||
* Resets the last message, so it will start a new one instead of appending to it.
|
||||
* This is used when someone (even the bot) sends a message to the channel.
|
||||
*
|
||||
* @param channel The channel to reset in - the process is slightly different for the public, private and custom chats
|
||||
*/
|
||||
public static void resetLastMessage(IChannel channel) {
|
||||
if (channel.getLongID() == DiscordPlugin.chatchannel.getLongID()) {
|
||||
(lastmsgdata == null ? lastmsgdata = new LastMsgData(DiscordPlugin.chatchannel, null)
|
||||
: lastmsgdata).message = null;
|
||||
return;
|
||||
} // Don't set the whole object to null, the player and channel information should be preserved
|
||||
for (LastMsgData data : channel.isPrivate() ? lastmsgPerUser : lastmsgCustom) {
|
||||
if (data.channel.getLongID() == channel.getLongID()) {
|
||||
data.message = null;
|
||||
return;
|
||||
}
|
||||
}
|
||||
//If it gets here, it's sending a message to a non-chat channel
|
||||
}
|
||||
|
||||
public static void forAllMCChat(Consumer<IChannel> action) {
|
||||
action.accept(DiscordPlugin.chatchannel);
|
||||
for (LastMsgData data : lastmsgPerUser)
|
||||
action.accept(data.channel);
|
||||
// lastmsgCustom.forEach(cc -> action.accept(cc.channel)); - Only send relevant messages to custom chat
|
||||
}
|
||||
|
||||
/**
|
||||
* For custom and all MC chat
|
||||
*
|
||||
* @param action The action to act
|
||||
* @param toggle The toggle to check
|
||||
* @param hookmsg Whether the message is also sent from the hook
|
||||
*/
|
||||
public static void forCustomAndAllMCChat(Consumer<IChannel> action, @Nullable ChannelconBroadcast toggle, boolean hookmsg) {
|
||||
if (!DiscordPlugin.hooked || !hookmsg)
|
||||
forAllMCChat(action);
|
||||
final Consumer<CustomLMD> customLMDConsumer = cc -> action.accept(cc.channel);
|
||||
if (toggle == null)
|
||||
lastmsgCustom.forEach(customLMDConsumer);
|
||||
else
|
||||
lastmsgCustom.stream().filter(cc -> (cc.toggles & toggle.flag) != 0).forEach(customLMDConsumer);
|
||||
}
|
||||
|
||||
/**
|
||||
* Do the {@code action} for each custom chat the {@code sender} have access to and has that broadcast type enabled.
|
||||
*
|
||||
* @param action The action to do
|
||||
* @param sender The sender to check perms of or null to send to all that has it toggled
|
||||
* @param toggle The toggle to check or null to send to all allowed
|
||||
*/
|
||||
public static void forAllowedCustomMCChat(Consumer<IChannel> action, @Nullable CommandSender sender, @Nullable ChannelconBroadcast toggle) {
|
||||
lastmsgCustom.stream().filter(clmd -> {
|
||||
//new TBMCChannelConnectFakeEvent(sender, clmd.mcchannel).shouldSendTo(clmd.dcp) - Thought it was this simple hehe - Wait, it *should* be this simple
|
||||
if (toggle != null && (clmd.toggles & toggle.flag) == 0)
|
||||
return false; //If null then allow
|
||||
if (sender == null)
|
||||
return true;
|
||||
return clmd.groupID.equals(clmd.mcchannel.getGroupID(sender));
|
||||
}).forEach(cc -> action.accept(cc.channel)); //TODO: Send error messages on channel connect
|
||||
}
|
||||
|
||||
/**
|
||||
* Do the {@code action} for each custom chat the {@code sender} have access to and has that broadcast type enabled.
|
||||
*
|
||||
* @param action The action to do
|
||||
* @param sender The sender to check perms of or null to send to all that has it toggled
|
||||
* @param toggle The toggle to check or null to send to all allowed
|
||||
* @param hookmsg Whether the message is also sent from the hook
|
||||
*/
|
||||
public static void forAllowedCustomAndAllMCChat(Consumer<IChannel> action, @Nullable CommandSender sender, @Nullable ChannelconBroadcast toggle, boolean hookmsg) {
|
||||
if (!DiscordPlugin.hooked || !hookmsg)
|
||||
forAllMCChat(action);
|
||||
forAllowedCustomMCChat(action, sender, toggle);
|
||||
}
|
||||
|
||||
public static Consumer<IChannel> send(String message) {
|
||||
return ch -> DiscordPlugin.sendMessageToChannel(ch, DPUtils.sanitizeString(message));
|
||||
}
|
||||
|
||||
public static void forAllowedMCChat(Consumer<IChannel> action, TBMCSystemChatEvent event) {
|
||||
if (event.getChannel().isGlobal())
|
||||
action.accept(DiscordPlugin.chatchannel);
|
||||
for (LastMsgData data : lastmsgPerUser)
|
||||
if (event.shouldSendTo(getSender(data.channel, data.user)))
|
||||
action.accept(data.channel);
|
||||
lastmsgCustom.stream().filter(clmd -> {
|
||||
if ((clmd.toggles & ChannelconBroadcast.BROADCAST.flag) == 0)
|
||||
return false;
|
||||
return event.shouldSendTo(clmd.dcp);
|
||||
}).map(clmd -> clmd.channel).forEach(action);
|
||||
}
|
||||
|
||||
/**
|
||||
* Stop the listener. Any calls to onMCChat will restart it as long as we're not in safe mode.
|
||||
*
|
||||
|
@ -445,13 +212,13 @@ public class MCChatListener implements Listener, IListener<MessageReceivedEvent>
|
|||
if (wait)
|
||||
recthread.join(5000);
|
||||
}
|
||||
lastmsgdata = null;
|
||||
lastmsgPerUser.clear();
|
||||
lastmsgCustom.clear();
|
||||
lastmsgfromd.clear();
|
||||
ConnectedSenders.clear();
|
||||
MCChatUtils.lastmsgdata = null;
|
||||
MCChatPrivate.lastmsgPerUser.clear();
|
||||
MCChatCustom.lastmsgCustom.clear();
|
||||
MCChatUtils.lastmsgfromd.clear();
|
||||
MCChatUtils.ConnectedSenders.clear();
|
||||
lastlist = lastlistp = ListC = 0;
|
||||
UnconnectedSenders.clear();
|
||||
MCChatUtils.UnconnectedSenders.clear();
|
||||
recthread = sendthread = null;
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace(); //This thread shouldn't be interrupted
|
||||
|
@ -463,27 +230,28 @@ public class MCChatListener implements Listener, IListener<MessageReceivedEvent>
|
|||
private Runnable recrun;
|
||||
private static Thread recthread;
|
||||
|
||||
@Override // Discord
|
||||
public void handle(MessageReceivedEvent ev) {
|
||||
if (DiscordPlugin.SafeMode)
|
||||
return;
|
||||
// Discord
|
||||
public boolean handleDiscord(MessageReceivedEvent ev) {
|
||||
if (!ComponentManager.isEnabled(MinecraftChatModule.class))
|
||||
return false;
|
||||
val author = ev.getMessage().getAuthor();
|
||||
if (author.isBot())
|
||||
return;
|
||||
final boolean hasCustomChat = hasCustomChat(ev.getChannel());
|
||||
if (!ev.getMessage().getChannel().getStringID().equals(DiscordPlugin.chatchannel.getStringID())
|
||||
&& !(ev.getMessage().getChannel().isPrivate() && isMinecraftChatEnabled(author.getStringID()))
|
||||
final boolean hasCustomChat = MCChatCustom.hasCustomChat(ev.getChannel());
|
||||
if (ev.getMessage().getChannel().getLongID() != DiscordPlugin.chatchannel.getLongID()
|
||||
&& !(ev.getMessage().getChannel().isPrivate() && MCChatPrivate.isMinecraftChatEnabled(author.getStringID()))
|
||||
&& !hasCustomChat)
|
||||
return;
|
||||
if (ev.getMessage().getContent().equalsIgnoreCase("mcchat"))
|
||||
return; // Race condition: If it gets here after it enabled mcchat it says it - I might as well allow disabling with this (CommandListener)
|
||||
return false; //Chat isn't enabled on this channel
|
||||
if (ev.getMessage().getChannel().isPrivate() //Only in private chat
|
||||
&& ev.getMessage().getContent().length() < "/mcchat<>".length()
|
||||
&& ev.getMessage().getContent().replace("/", "")
|
||||
.equalsIgnoreCase("mcchat")) //Either mcchat or /mcchat
|
||||
return false; //Allow disabling the chat if needed
|
||||
if (CommandListener.runCommand(ev.getMessage(), true))
|
||||
return;
|
||||
resetLastMessage(ev.getChannel());
|
||||
return true; //Allow running commands in chat channels
|
||||
MCChatUtils.resetLastMessage(ev.getChannel());
|
||||
lastlist++;
|
||||
recevents.add(ev);
|
||||
if (rectask != null)
|
||||
return;
|
||||
return true;
|
||||
recrun = () -> { //Don't return in a while loop next time
|
||||
recthread = Thread.currentThread();
|
||||
processDiscordToMC();
|
||||
|
@ -491,6 +259,7 @@ public class MCChatListener implements Listener, IListener<MessageReceivedEvent>
|
|||
rectask = Bukkit.getScheduler().runTaskAsynchronously(DiscordPlugin.plugin, recrun); //Continue message processing
|
||||
};
|
||||
rectask = Bukkit.getScheduler().runTaskAsynchronously(DiscordPlugin.plugin, recrun); //Start message processing
|
||||
return true;
|
||||
}
|
||||
|
||||
private void processDiscordToMC() {
|
||||
|
@ -505,7 +274,7 @@ public class MCChatListener implements Listener, IListener<MessageReceivedEvent>
|
|||
val sender = event.getMessage().getAuthor();
|
||||
String dmessage = event.getMessage().getContent();
|
||||
try {
|
||||
final DiscordSenderBase dsender = getSender(event.getMessage().getChannel(), sender);
|
||||
final DiscordSenderBase dsender = MCChatUtils.getSender(event.getMessage().getChannel(), sender);
|
||||
val user = dsender.getChromaUser();
|
||||
|
||||
for (IUser u : event.getMessage().getMentions()) {
|
||||
|
@ -525,7 +294,7 @@ public class MCChatListener implements Listener, IListener<MessageReceivedEvent>
|
|||
.getAttachments().stream().map(IMessage.Attachment::getUrl).collect(Collectors.joining("\n"))
|
||||
: "");
|
||||
|
||||
CustomLMD clmd = getCustomChat(event.getChannel());
|
||||
MCChatCustom.CustomLMD clmd = MCChatCustom.getCustomChat(event.getChannel());
|
||||
|
||||
boolean react = false;
|
||||
|
||||
|
@ -570,18 +339,13 @@ public class MCChatListener implements Listener, IListener<MessageReceivedEvent>
|
|||
() -> { //TODO: Better handling...
|
||||
val channel = user.channel();
|
||||
val chtmp = channel.get();
|
||||
//System.out.println("1: "+chtmp.ID);
|
||||
//System.out.println("clmd: "+clmd);
|
||||
if (clmd != null) {
|
||||
channel.set(clmd.mcchannel); //Hack to send command in the channel
|
||||
//System.out.println("clmd chan: "+clmd.mcchannel.ID);
|
||||
} //TODO: Permcheck isn't implemented for commands
|
||||
//System.out.println("2: "+channel.get().ID);
|
||||
VanillaCommandListener.runBukkitOrVanillaCommand(dsender, cmd);
|
||||
Bukkit.getLogger().info(dsender.getName() + " issued command from Discord: /" + cmdlowercased);
|
||||
if (clmd != null)
|
||||
channel.set(chtmp);
|
||||
//System.out.println("3: "+channel.get().ID); - TODO: Remove
|
||||
});
|
||||
else {
|
||||
Channel chc = ch.get();
|
||||
|
@ -619,8 +383,9 @@ public class MCChatListener implements Listener, IListener<MessageReceivedEvent>
|
|||
} else {// Not a command
|
||||
if (dmessage.length() == 0 && event.getMessage().getAttachments().size() == 0
|
||||
&& !event.getChannel().isPrivate() && event.getMessage().isSystemMessage()) {
|
||||
val rtr = clmd != null ? clmd.mcchannel.filteranderrormsg.apply(clmd.dcp) : dsender.getChromaUser().channel().get().filteranderrormsg.apply(dsender);
|
||||
TBMCChatAPI.SendSystemMessage(clmd != null ? clmd.mcchannel : dsender.getChromaUser().channel().get(), rtr.score, rtr.groupID,
|
||||
val rtr = clmd != null ? clmd.mcchannel.getRTR(clmd.dcp)
|
||||
: dsender.getChromaUser().channel().get().getRTR(dsender);
|
||||
TBMCChatAPI.SendSystemMessage(clmd != null ? clmd.mcchannel : dsender.getChromaUser().channel().get(), rtr,
|
||||
(dsender instanceof Player ? ((Player) dsender).getDisplayName()
|
||||
: dsender.getName()) + " pinned a message on Discord.");
|
||||
}
|
||||
|
@ -635,7 +400,7 @@ public class MCChatListener implements Listener, IListener<MessageReceivedEvent>
|
|||
}
|
||||
if (react) {
|
||||
try {
|
||||
val lmfd = lastmsgfromd.get(event.getChannel().getLongID());
|
||||
val lmfd = MCChatUtils.lastmsgfromd.get(event.getChannel().getLongID());
|
||||
if (lmfd != null) {
|
||||
DPUtils.perform(() -> lmfd.removeReaction(DiscordPlugin.dc.getOurUser(),
|
||||
DiscordPlugin.DELIVERED_REACTION)); // Remove it no matter what, we know it's there 99.99% of the time
|
||||
|
@ -643,7 +408,7 @@ public class MCChatListener implements Listener, IListener<MessageReceivedEvent>
|
|||
} catch (Exception e) {
|
||||
TBMCCoreAPI.SendException("An error occured while removing reactions from chat!", e);
|
||||
}
|
||||
lastmsgfromd.put(event.getChannel().getLongID(), event.getMessage());
|
||||
MCChatUtils.lastmsgfromd.put(event.getChannel().getLongID(), event.getMessage());
|
||||
DPUtils.perform(() -> event.getMessage().addReaction(DiscordPlugin.DELIVERED_REACTION));
|
||||
}
|
||||
} catch (Exception e) {
|
||||
|
@ -651,19 +416,6 @@ public class MCChatListener implements Listener, IListener<MessageReceivedEvent>
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This method will find the best sender to use: if the player is online, use that, if not but connected then use that etc.
|
||||
*/
|
||||
private static DiscordSenderBase getSender(IChannel channel, final IUser author) {
|
||||
//noinspection OptionalGetWithoutIsPresent
|
||||
return Stream.<Supplier<Optional<DiscordSenderBase>>>of( // https://stackoverflow.com/a/28833677/2703239
|
||||
() -> Optional.ofNullable(getSender(OnlineSenders, channel, author)), // Find first non-null
|
||||
() -> Optional.ofNullable(getSender(ConnectedSenders, channel, author)), // This doesn't support the public chat, but it'll always return null for it
|
||||
() -> Optional.ofNullable(getSender(OnlineSenders, channel, author)), //
|
||||
() -> Optional.of(addSender(UnconnectedSenders, author,
|
||||
new DiscordSender(author, channel)))).map(Supplier::get).filter(Optional::isPresent).map(Optional::get).findFirst().get();
|
||||
}
|
||||
|
||||
@FunctionalInterface
|
||||
private interface InterruptibleConsumer<T> {
|
||||
void accept(T value) throws TimeoutException, InterruptedException;
|
|
@ -0,0 +1,69 @@
|
|||
package buttondevteam.discordplugin.mcchat;
|
||||
|
||||
import buttondevteam.discordplugin.DiscordConnectedPlayer;
|
||||
import buttondevteam.discordplugin.DiscordPlayer;
|
||||
import buttondevteam.discordplugin.DiscordPlugin;
|
||||
import buttondevteam.lib.player.TBMCPlayer;
|
||||
import lombok.val;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.event.Event;
|
||||
import org.bukkit.event.player.PlayerJoinEvent;
|
||||
import org.bukkit.event.player.PlayerQuitEvent;
|
||||
import sx.blah.discord.handle.obj.IChannel;
|
||||
import sx.blah.discord.handle.obj.IPrivateChannel;
|
||||
import sx.blah.discord.handle.obj.IUser;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import static buttondevteam.discordplugin.listeners.MCListener.callEventExcludingSome;
|
||||
|
||||
public class MCChatPrivate {
|
||||
|
||||
/**
|
||||
* Used for messages in PMs (mcchat).
|
||||
*/
|
||||
static ArrayList<MCChatUtils.LastMsgData> lastmsgPerUser = new ArrayList<>();
|
||||
|
||||
public static boolean privateMCChat(IChannel channel, boolean start, IUser user, DiscordPlayer dp) {
|
||||
TBMCPlayer mcp = dp.getAs(TBMCPlayer.class);
|
||||
if (mcp != null) { // If the accounts aren't connected, can't make a connected sender
|
||||
val p = Bukkit.getPlayer(mcp.getUUID());
|
||||
val op = Bukkit.getOfflinePlayer(mcp.getUUID());
|
||||
if (start) {
|
||||
val sender = new DiscordConnectedPlayer(user, channel, mcp.getUUID(), op.getName());
|
||||
MCChatUtils.addSender(MCChatUtils.ConnectedSenders, user, sender);
|
||||
if (p == null)// Player is offline - If the player is online, that takes precedence
|
||||
callEventSync(new PlayerJoinEvent(sender, ""));
|
||||
} else {
|
||||
val sender = MCChatUtils.removeSender(MCChatUtils.ConnectedSenders, channel, user);
|
||||
if (p == null)// Player is offline - If the player is online, that takes precedence
|
||||
callEventSync(new PlayerQuitEvent(sender, ""));
|
||||
}
|
||||
} // ---- PermissionsEx warning is normal on logout ----
|
||||
if (!start)
|
||||
MCChatUtils.lastmsgfromd.remove(channel.getLongID());
|
||||
return start //
|
||||
? lastmsgPerUser.add(new MCChatUtils.LastMsgData(channel, user)) // Doesn't support group DMs
|
||||
: lastmsgPerUser.removeIf(lmd -> lmd.channel.getLongID() == channel.getLongID());
|
||||
}
|
||||
|
||||
public static boolean isMinecraftChatEnabled(DiscordPlayer dp) {
|
||||
return isMinecraftChatEnabled(dp.getDiscordID());
|
||||
}
|
||||
|
||||
public static boolean isMinecraftChatEnabled(String did) { // Don't load the player data just for this
|
||||
return lastmsgPerUser.stream()
|
||||
.anyMatch(lmd -> ((IPrivateChannel) lmd.channel).getRecipient().getStringID().equals(did));
|
||||
}
|
||||
|
||||
public static void logoutAll() {
|
||||
for (val entry : MCChatUtils.ConnectedSenders.entrySet())
|
||||
for (val valueEntry : entry.getValue().entrySet())
|
||||
callEventExcludingSome(new PlayerQuitEvent(valueEntry.getValue(), "")); //This is sync
|
||||
MCChatUtils.ConnectedSenders.clear();
|
||||
}
|
||||
|
||||
private static void callEventSync(Event event) {
|
||||
Bukkit.getScheduler().runTask(DiscordPlugin.plugin, () -> callEventExcludingSome(event));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,218 @@
|
|||
package buttondevteam.discordplugin.mcchat;
|
||||
|
||||
import buttondevteam.core.ComponentManager;
|
||||
import buttondevteam.discordplugin.*;
|
||||
import buttondevteam.discordplugin.broadcaster.GeneralEventBroadcasterModule;
|
||||
import buttondevteam.lib.TBMCSystemChatEvent;
|
||||
import buttondevteam.lib.chat.Channel;
|
||||
import io.netty.util.collection.LongObjectHashMap;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.experimental.var;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import sx.blah.discord.handle.obj.IChannel;
|
||||
import sx.blah.discord.handle.obj.IMessage;
|
||||
import sx.blah.discord.handle.obj.IUser;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.HashMap;
|
||||
import java.util.Optional;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Supplier;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
public class MCChatUtils {
|
||||
/**
|
||||
* May contain P<DiscordID> as key for public chat
|
||||
*/
|
||||
public static final HashMap<String, HashMap<IChannel, DiscordSender>> UnconnectedSenders = new HashMap<>();
|
||||
public static final HashMap<String, HashMap<IChannel, DiscordConnectedPlayer>> ConnectedSenders = new HashMap<>();
|
||||
/**
|
||||
* May contain P<DiscordID> as key for public chat
|
||||
*/
|
||||
public static final HashMap<String, HashMap<IChannel, DiscordPlayerSender>> OnlineSenders = new HashMap<>();
|
||||
static @Nullable LastMsgData lastmsgdata;
|
||||
static LongObjectHashMap<IMessage> lastmsgfromd = new LongObjectHashMap<>(); // Last message sent by a Discord user, used for clearing checkmarks
|
||||
|
||||
public static void updatePlayerList() {
|
||||
if (notEnabled()) return;
|
||||
DPUtils.performNoWait(() -> {
|
||||
if (lastmsgdata != null)
|
||||
updatePL(lastmsgdata);
|
||||
MCChatCustom.lastmsgCustom.forEach(MCChatUtils::updatePL);
|
||||
});
|
||||
}
|
||||
|
||||
private static boolean notEnabled() {
|
||||
return !ComponentManager.isEnabled(MinecraftChatModule.class);
|
||||
}
|
||||
|
||||
private static void updatePL(LastMsgData lmd) {
|
||||
String topic = lmd.channel.getTopic();
|
||||
if (topic == null || topic.length() == 0)
|
||||
topic = ".\n----\nMinecraft chat\n----\n.";
|
||||
String[] s = topic.split("\\n----\\n");
|
||||
if (s.length < 3)
|
||||
return;
|
||||
s[0] = Bukkit.getOnlinePlayers().size() + " player" + (Bukkit.getOnlinePlayers().size() != 1 ? "s" : "")
|
||||
+ " online";
|
||||
s[s.length - 1] = "Players: " + Bukkit.getOnlinePlayers().stream()
|
||||
.map(p -> DPUtils.sanitizeString(p.getDisplayName())).collect(Collectors.joining(", "));
|
||||
lmd.channel.changeTopic(String.join("\n----\n", s));
|
||||
}
|
||||
|
||||
public static <T extends DiscordSenderBase> T addSender(HashMap<String, HashMap<IChannel, T>> senders,
|
||||
IUser user, T sender) {
|
||||
return addSender(senders, user.getStringID(), sender);
|
||||
}
|
||||
|
||||
public static <T extends DiscordSenderBase> T addSender(HashMap<String, HashMap<IChannel, T>> senders,
|
||||
String did, T sender) {
|
||||
var map = senders.get(did);
|
||||
if (map == null)
|
||||
map = new HashMap<>();
|
||||
map.put(sender.getChannel(), sender);
|
||||
senders.put(did, map);
|
||||
return sender;
|
||||
}
|
||||
|
||||
public static <T extends DiscordSenderBase> T getSender(HashMap<String, HashMap<IChannel, T>> senders,
|
||||
IChannel channel, IUser user) {
|
||||
var map = senders.get(user.getStringID());
|
||||
if (map != null)
|
||||
return map.get(channel);
|
||||
return null;
|
||||
}
|
||||
|
||||
public static <T extends DiscordSenderBase> T removeSender(HashMap<String, HashMap<IChannel, T>> senders,
|
||||
IChannel channel, IUser user) {
|
||||
var map = senders.get(user.getStringID());
|
||||
if (map != null)
|
||||
return map.remove(channel);
|
||||
return null;
|
||||
}
|
||||
|
||||
public static void forAllMCChat(Consumer<IChannel> action) {
|
||||
if (notEnabled()) return;
|
||||
action.accept(DiscordPlugin.chatchannel);
|
||||
for (LastMsgData data : MCChatPrivate.lastmsgPerUser)
|
||||
action.accept(data.channel);
|
||||
// lastmsgCustom.forEach(cc -> action.accept(cc.channel)); - Only send relevant messages to custom chat
|
||||
}
|
||||
|
||||
/**
|
||||
* For custom and all MC chat
|
||||
*
|
||||
* @param action The action to act
|
||||
* @param toggle The toggle to check
|
||||
* @param hookmsg Whether the message is also sent from the hook
|
||||
*/
|
||||
public static void forCustomAndAllMCChat(Consumer<IChannel> action, @Nullable ChannelconBroadcast toggle, boolean hookmsg) {
|
||||
if (notEnabled()) return;
|
||||
if (!GeneralEventBroadcasterModule.isHooked() || !hookmsg)
|
||||
forAllMCChat(action);
|
||||
final Consumer<MCChatCustom.CustomLMD> customLMDConsumer = cc -> action.accept(cc.channel);
|
||||
if (toggle == null)
|
||||
MCChatCustom.lastmsgCustom.forEach(customLMDConsumer);
|
||||
else
|
||||
MCChatCustom.lastmsgCustom.stream().filter(cc -> (cc.toggles & toggle.flag) != 0).forEach(customLMDConsumer);
|
||||
}
|
||||
|
||||
/**
|
||||
* Do the {@code action} for each custom chat the {@code sender} have access to and has that broadcast type enabled.
|
||||
*
|
||||
* @param action The action to do
|
||||
* @param sender The sender to check perms of or null to send to all that has it toggled
|
||||
* @param toggle The toggle to check or null to send to all allowed
|
||||
*/
|
||||
public static void forAllowedCustomMCChat(Consumer<IChannel> action, @Nullable CommandSender sender, @Nullable ChannelconBroadcast toggle) {
|
||||
if (notEnabled()) return;
|
||||
MCChatCustom.lastmsgCustom.stream().filter(clmd -> {
|
||||
//new TBMCChannelConnectFakeEvent(sender, clmd.mcchannel).shouldSendTo(clmd.dcp) - Thought it was this simple hehe - Wait, it *should* be this simple
|
||||
if (toggle != null && (clmd.toggles & toggle.flag) == 0)
|
||||
return false; //If null then allow
|
||||
if (sender == null)
|
||||
return true;
|
||||
return clmd.groupID.equals(clmd.mcchannel.getGroupID(sender));
|
||||
}).forEach(cc -> action.accept(cc.channel)); //TODO: Send error messages on channel connect
|
||||
}
|
||||
|
||||
/**
|
||||
* Do the {@code action} for each custom chat the {@code sender} have access to and has that broadcast type enabled.
|
||||
*
|
||||
* @param action The action to do
|
||||
* @param sender The sender to check perms of or null to send to all that has it toggled
|
||||
* @param toggle The toggle to check or null to send to all allowed
|
||||
* @param hookmsg Whether the message is also sent from the hook
|
||||
*/
|
||||
public static void forAllowedCustomAndAllMCChat(Consumer<IChannel> action, @Nullable CommandSender sender, @Nullable ChannelconBroadcast toggle, boolean hookmsg) {
|
||||
if (notEnabled()) return;
|
||||
if (!GeneralEventBroadcasterModule.isHooked() || !hookmsg)
|
||||
forAllMCChat(action);
|
||||
forAllowedCustomMCChat(action, sender, toggle);
|
||||
}
|
||||
|
||||
public static Consumer<IChannel> send(String message) {
|
||||
return ch -> DiscordPlugin.sendMessageToChannel(ch, DPUtils.sanitizeString(message));
|
||||
}
|
||||
|
||||
public static void forAllowedMCChat(Consumer<IChannel> action, TBMCSystemChatEvent event) {
|
||||
if (notEnabled()) return;
|
||||
if (event.getChannel().isGlobal())
|
||||
action.accept(DiscordPlugin.chatchannel);
|
||||
for (LastMsgData data : MCChatPrivate.lastmsgPerUser)
|
||||
if (event.shouldSendTo(getSender(data.channel, data.user)))
|
||||
action.accept(data.channel);
|
||||
MCChatCustom.lastmsgCustom.stream().filter(clmd -> {
|
||||
if ((clmd.toggles & ChannelconBroadcast.BROADCAST.flag) == 0)
|
||||
return false;
|
||||
return event.shouldSendTo(clmd.dcp);
|
||||
}).map(clmd -> clmd.channel).forEach(action);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method will find the best sender to use: if the player is online, use that, if not but connected then use that etc.
|
||||
*/
|
||||
static DiscordSenderBase getSender(IChannel channel, final IUser author) {
|
||||
//noinspection OptionalGetWithoutIsPresent
|
||||
return Stream.<Supplier<Optional<DiscordSenderBase>>>of( // https://stackoverflow.com/a/28833677/2703239
|
||||
() -> Optional.ofNullable(getSender(OnlineSenders, channel, author)), // Find first non-null
|
||||
() -> Optional.ofNullable(getSender(ConnectedSenders, channel, author)), // This doesn't support the public chat, but it'll always return null for it
|
||||
() -> Optional.ofNullable(getSender(UnconnectedSenders, channel, author)), //
|
||||
() -> Optional.of(addSender(UnconnectedSenders, author,
|
||||
new DiscordSender(author, channel)))).map(Supplier::get).filter(Optional::isPresent).map(Optional::get).findFirst().get();
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets the last message, so it will start a new one instead of appending to it.
|
||||
* This is used when someone (even the bot) sends a message to the channel.
|
||||
*
|
||||
* @param channel The channel to reset in - the process is slightly different for the public, private and custom chats
|
||||
*/
|
||||
public static void resetLastMessage(IChannel channel) {
|
||||
if (notEnabled()) return;
|
||||
if (channel.getLongID() == DiscordPlugin.chatchannel.getLongID()) {
|
||||
(lastmsgdata == null ? lastmsgdata = new LastMsgData(DiscordPlugin.chatchannel, null)
|
||||
: lastmsgdata).message = null;
|
||||
return;
|
||||
} // Don't set the whole object to null, the player and channel information should be preserved
|
||||
for (LastMsgData data : channel.isPrivate() ? MCChatPrivate.lastmsgPerUser : MCChatCustom.lastmsgCustom) {
|
||||
if (data.channel.getLongID() == channel.getLongID()) {
|
||||
data.message = null;
|
||||
return;
|
||||
}
|
||||
}
|
||||
//If it gets here, it's sending a message to a non-chat channel
|
||||
}
|
||||
|
||||
@RequiredArgsConstructor
|
||||
public static class LastMsgData {
|
||||
public IMessage message;
|
||||
public long time;
|
||||
public String content;
|
||||
public final IChannel channel;
|
||||
public Channel mcchannel;
|
||||
public final IUser user;
|
||||
}
|
||||
}
|
153
src/main/java/buttondevteam/discordplugin/mcchat/MCListener.java
Normal file
153
src/main/java/buttondevteam/discordplugin/mcchat/MCListener.java
Normal file
|
@ -0,0 +1,153 @@
|
|||
package buttondevteam.discordplugin.mcchat;
|
||||
|
||||
import buttondevteam.discordplugin.*;
|
||||
import buttondevteam.discordplugin.commands.ConnectCommand;
|
||||
import buttondevteam.lib.TBMCCoreAPI;
|
||||
import buttondevteam.lib.TBMCSystemChatEvent;
|
||||
import buttondevteam.lib.player.*;
|
||||
import com.earth2me.essentials.CommandSource;
|
||||
import lombok.val;
|
||||
import net.ess3.api.events.AfkStatusChangeEvent;
|
||||
import net.ess3.api.events.MuteStatusChangeEvent;
|
||||
import net.ess3.api.events.NickChangeEvent;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.entity.PlayerDeathEvent;
|
||||
import org.bukkit.event.player.PlayerJoinEvent;
|
||||
import org.bukkit.event.player.PlayerKickEvent;
|
||||
import org.bukkit.event.player.PlayerLoginEvent;
|
||||
import org.bukkit.event.player.PlayerLoginEvent.Result;
|
||||
import org.bukkit.event.player.PlayerQuitEvent;
|
||||
import org.bukkit.event.server.BroadcastMessageEvent;
|
||||
import sx.blah.discord.handle.obj.IRole;
|
||||
import sx.blah.discord.handle.obj.IUser;
|
||||
import sx.blah.discord.util.DiscordException;
|
||||
import sx.blah.discord.util.MissingPermissionsException;
|
||||
|
||||
class MCListener implements Listener {
|
||||
@EventHandler(priority = EventPriority.HIGHEST)
|
||||
public void onPlayerLogin(PlayerLoginEvent e) {
|
||||
if (e.getResult() != Result.ALLOWED)
|
||||
return;
|
||||
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()
|
||||
.ifPresent(dcp -> buttondevteam.discordplugin.listeners.MCListener.callEventExcludingSome(new PlayerQuitEvent(dcp, "")));
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.LOWEST)
|
||||
public void onPlayerJoin(TBMCPlayerJoinEvent e) {
|
||||
if (e.getPlayer() instanceof DiscordConnectedPlayer)
|
||||
return; // Don't show the joined message for the fake player
|
||||
Bukkit.getScheduler().runTaskAsynchronously(DiscordPlugin.plugin, () -> {
|
||||
final Player p = e.getPlayer();
|
||||
DiscordPlayer dp = e.GetPlayer().getAs(DiscordPlayer.class);
|
||||
if (dp != null) {
|
||||
val user = DiscordPlugin.dc.getUserByID(Long.parseLong(dp.getDiscordID()));
|
||||
MCChatUtils.addSender(MCChatUtils.OnlineSenders, dp.getDiscordID(),
|
||||
new DiscordPlayerSender(user, user.getOrCreatePMChannel(), p));
|
||||
MCChatUtils.addSender(MCChatUtils.OnlineSenders, dp.getDiscordID(),
|
||||
new DiscordPlayerSender(user, DiscordPlugin.chatchannel, p)); //Stored per-channel
|
||||
}
|
||||
if (ConnectCommand.WaitingToConnect.containsKey(e.GetPlayer().PlayerName().get())) {
|
||||
IUser user = DiscordPlugin.dc
|
||||
.getUserByID(Long.parseLong(ConnectCommand.WaitingToConnect.get(e.GetPlayer().PlayerName().get())));
|
||||
p.sendMessage("§bTo connect with the Discord account @" + user.getName() + "#" + user.getDiscriminator()
|
||||
+ " do /discord accept");
|
||||
p.sendMessage("§bIf it wasn't you, do /discord decline");
|
||||
}
|
||||
final String message = e.GetPlayer().PlayerName().get() + " joined the game";
|
||||
MCChatUtils.forAllowedCustomAndAllMCChat(MCChatUtils.send(message), e.getPlayer(), ChannelconBroadcast.JOINLEAVE, true);
|
||||
MCChatListener.ListC = 0;
|
||||
ChromaBot.getInstance().updatePlayerList();
|
||||
});
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.HIGHEST)
|
||||
public void onPlayerLeave(TBMCPlayerQuitEvent e) {
|
||||
if (e.getPlayer() instanceof DiscordConnectedPlayer)
|
||||
return; // Only care about real users
|
||||
MCChatUtils.OnlineSenders.entrySet()
|
||||
.removeIf(entry -> entry.getValue().entrySet().stream().anyMatch(p -> p.getValue().getUniqueId().equals(e.getPlayer().getUniqueId())));
|
||||
Bukkit.getScheduler().runTask(DiscordPlugin.plugin,
|
||||
() -> MCChatUtils.ConnectedSenders.values().stream().flatMap(v -> v.values().stream())
|
||||
.filter(s -> s.getUniqueId().equals(e.getPlayer().getUniqueId())).findAny()
|
||||
.ifPresent(dcp -> buttondevteam.discordplugin.listeners.MCListener.callEventExcludingSome(new PlayerJoinEvent(dcp, ""))));
|
||||
Bukkit.getScheduler().runTaskLaterAsynchronously(DiscordPlugin.plugin,
|
||||
ChromaBot.getInstance()::updatePlayerList, 5);
|
||||
final String message = e.GetPlayer().PlayerName().get() + " left the game";
|
||||
MCChatUtils.forAllowedCustomAndAllMCChat(MCChatUtils.send(message), e.getPlayer(), ChannelconBroadcast.JOINLEAVE, true);
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.HIGHEST)
|
||||
public void onPlayerKick(PlayerKickEvent e) {
|
||||
/*if (!DiscordPlugin.hooked && !e.getReason().equals("The server is restarting")
|
||||
&& !e.getReason().equals("Server closed")) // The leave messages errored with the previous setup, I could make it wait since I moved it here, but instead I have a special
|
||||
MCChatListener.forAllowedCustomAndAllMCChat(e.getPlayer().getName() + " left the game"); // message for this - Oh wait this doesn't even send normally because of the hook*/
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.LOW)
|
||||
public void onPlayerDeath(PlayerDeathEvent e) {
|
||||
MCChatUtils.forAllowedCustomAndAllMCChat(MCChatUtils.send(e.getDeathMessage()), e.getEntity(), ChannelconBroadcast.DEATH, true);
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onPlayerAFK(AfkStatusChangeEvent e) {
|
||||
final Player base = e.getAffected().getBase();
|
||||
if (e.isCancelled() || !base.isOnline())
|
||||
return;
|
||||
final String msg = base.getDisplayName()
|
||||
+ " is " + (e.getValue() ? "now" : "no longer") + " AFK.";
|
||||
MCChatUtils.forAllowedCustomAndAllMCChat(MCChatUtils.send(msg), base, ChannelconBroadcast.AFK, false);
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onPlayerMute(MuteStatusChangeEvent e) {
|
||||
try {
|
||||
DPUtils.performNoWait(() -> {
|
||||
final IRole role = DiscordPlugin.dc.getRoleByID(164090010461667328L);
|
||||
final CommandSource source = e.getAffected().getSource();
|
||||
if (!source.isPlayer())
|
||||
return;
|
||||
final DiscordPlayer p = TBMCPlayerBase.getPlayer(source.getPlayer().getUniqueId(), TBMCPlayer.class)
|
||||
.getAs(DiscordPlayer.class);
|
||||
if (p == null) return;
|
||||
final IUser user = DiscordPlugin.dc.getUserByID(
|
||||
Long.parseLong(p.getDiscordID()));
|
||||
if (e.getValue())
|
||||
user.addRole(role);
|
||||
else
|
||||
user.removeRole(role);
|
||||
DiscordPlugin.sendMessageToChannel(DiscordPlugin.modlogchannel, (e.getValue() ? "M" : "Unm") + "uted user: " + user.getName());
|
||||
});
|
||||
} catch (DiscordException | MissingPermissionsException ex) {
|
||||
TBMCCoreAPI.SendException("Failed to give/take Muted role to player " + e.getAffected().getName() + "!",
|
||||
ex);
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onChatSystemMessage(TBMCSystemChatEvent event) {
|
||||
MCChatUtils.forAllowedMCChat(MCChatUtils.send(event.getMessage()), event);
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onBroadcastMessage(BroadcastMessageEvent event) {
|
||||
MCChatUtils.forCustomAndAllMCChat(MCChatUtils.send(event.getMessage()), ChannelconBroadcast.BROADCAST, false);
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
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()
|
||||
: event.getSender().getName();
|
||||
//Channel channel = ChromaGamerBase.getFromSender(event.getSender()).channel().get(); - TODO
|
||||
MCChatUtils.forAllMCChat(MCChatUtils.send(name + " <:YEEHAW:" + DiscordPlugin.mainServer.getEmojiByName("YEEHAW").getStringID() + ">s"));
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onNickChange(NickChangeEvent event) {
|
||||
MCChatUtils.updatePlayerList();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
package buttondevteam.discordplugin.mcchat;
|
||||
|
||||
import buttondevteam.discordplugin.DiscordPlugin;
|
||||
import buttondevteam.lib.TBMCCoreAPI;
|
||||
import buttondevteam.lib.architecture.Component;
|
||||
import lombok.Getter;
|
||||
|
||||
public class MinecraftChatModule extends Component {
|
||||
private @Getter MCChatListener listener;
|
||||
|
||||
public MCChatListener getListener() { //It doesn't want to generate
|
||||
return listener;
|
||||
}
|
||||
@Override
|
||||
protected void enable() {
|
||||
listener = new MCChatListener();
|
||||
DiscordPlugin.dc.getDispatcher().registerListener(listener);
|
||||
TBMCCoreAPI.RegisterEventsForExceptions(listener, getPlugin());
|
||||
TBMCCoreAPI.RegisterEventsForExceptions(new MCListener(), getPlugin());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void disable() {
|
||||
//These get undone if restarting/resetting - it will ignore events if disabled
|
||||
} //TODO: Use ComponentManager.isEnabled() at other places too, instead of SafeMode
|
||||
}
|
|
@ -2,7 +2,7 @@ package buttondevteam.discordplugin.mccommands;
|
|||
|
||||
import buttondevteam.discordplugin.DiscordPlayer;
|
||||
import buttondevteam.discordplugin.commands.ConnectCommand;
|
||||
import buttondevteam.discordplugin.listeners.MCChatListener;
|
||||
import buttondevteam.discordplugin.mcchat.MCChatUtils;
|
||||
import buttondevteam.lib.chat.CommandClass;
|
||||
import buttondevteam.lib.player.ChromaGamerBase;
|
||||
import buttondevteam.lib.player.TBMCPlayer;
|
||||
|
@ -35,7 +35,7 @@ public class AcceptMCCommand extends DiscordMCCommandBase {
|
|||
dp.save();
|
||||
mcp.save();
|
||||
ConnectCommand.WaitingToConnect.remove(player.getName());
|
||||
MCChatListener.UnconnectedSenders.remove(did); //Remove all unconnected, will be recreated where needed
|
||||
MCChatUtils.UnconnectedSenders.remove(did); //Remove all unconnected, will be recreated where needed
|
||||
player.sendMessage("§bAccounts connected.");
|
||||
return true;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue