Merge pull request #43 from TBMCPlugins/dev

Crash detect, chat channels, fixed mcchat, improvements
This commit is contained in:
Norbi Peti 2017-08-17 18:27:26 +02:00 committed by GitHub
commit 6d40949ddd
8 changed files with 244 additions and 64 deletions

View file

@ -36,7 +36,7 @@
<plugins> <plugins>
<plugin> <plugin>
<artifactId>maven-compiler-plugin</artifactId> <artifactId>maven-compiler-plugin</artifactId>
<version>3.3</version> <version>3.6.2</version>
<configuration> <configuration>
<source>1.8</source> <source>1.8</source>
<target>1.8</target> <target>1.8</target>

View file

@ -12,8 +12,8 @@ public class DiscordConnectedPlayer extends DiscordFakePlayer implements IMCPlay
private static int nextEntityId = 10000; private static int nextEntityId = 10000;
private @Getter VanillaCommandListener<DiscordConnectedPlayer> vanillaCmdListener; private @Getter VanillaCommandListener<DiscordConnectedPlayer> vanillaCmdListener;
public DiscordConnectedPlayer(IUser user, IChannel channel, UUID uuid) { public DiscordConnectedPlayer(IUser user, IChannel channel, UUID uuid, String mcname) {
super(user, channel, nextEntityId++, uuid); super(user, channel, nextEntityId++, uuid, mcname);
vanillaCmdListener = new VanillaCommandListener<>(this); vanillaCmdListener = new VanillaCommandListener<>(this);
} }

View file

@ -9,6 +9,7 @@ import java.util.List;
import java.util.Random; import java.util.Random;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.event.player.PlayerQuitEvent;
import org.bukkit.plugin.RegisteredServiceProvider; import org.bukkit.plugin.RegisteredServiceProvider;
import org.bukkit.plugin.java.JavaPlugin; import org.bukkit.plugin.java.JavaPlugin;
import org.bukkit.scheduler.BukkitTask; import org.bukkit.scheduler.BukkitTask;
@ -20,6 +21,8 @@ import buttondevteam.discordplugin.listeners.*;
import buttondevteam.discordplugin.mccommands.DiscordMCCommandBase; import buttondevteam.discordplugin.mccommands.DiscordMCCommandBase;
import buttondevteam.lib.TBMCCoreAPI; import buttondevteam.lib.TBMCCoreAPI;
import buttondevteam.lib.chat.TBMCChatAPI; import buttondevteam.lib.chat.TBMCChatAPI;
import buttondevteam.lib.player.ChromaGamerBase;
import lombok.val;
import net.milkbowl.vault.permission.Permission; import net.milkbowl.vault.permission.Permission;
import sx.blah.discord.api.*; import sx.blah.discord.api.*;
import sx.blah.discord.api.events.IListener; import sx.blah.discord.api.events.IListener;
@ -67,6 +70,7 @@ public class DiscordPlugin extends JavaPlugin implements IListener<ReadyEvent> {
*/ */
public static IChannel officechannel; public static IChannel officechannel;
public static IChannel updatechannel; public static IChannel updatechannel;
public static IChannel devofficechannel;
public static IGuild mainServer; public static IGuild mainServer;
public static IGuild devServer; public static IGuild devServer;
@ -91,6 +95,7 @@ public class DiscordPlugin extends JavaPlugin implements IListener<ReadyEvent> {
botroomchannel = devServer.getChannelByID(239519012529111040L); // bot-room botroomchannel = devServer.getChannelByID(239519012529111040L); // bot-room
officechannel = devServer.getChannelByID(219626707458457603L); // developers-office officechannel = devServer.getChannelByID(219626707458457603L); // developers-office
updatechannel = devServer.getChannelByID(233724163519414272L); // server-updates updatechannel = devServer.getChannelByID(233724163519414272L); // server-updates
devofficechannel = officechannel; // developers-office
dc.online("on TBMC"); dc.online("on TBMC");
} else { } else {
botchannel = devServer.getChannelByID(239519012529111040L); // bot-room botchannel = devServer.getChannelByID(239519012529111040L); // bot-room
@ -100,6 +105,7 @@ public class DiscordPlugin extends JavaPlugin implements IListener<ReadyEvent> {
chatchannel = botchannel;// bot-room chatchannel = botchannel;// bot-room
officechannel = devServer.getChannelByID(219626707458457603L); // developers-office officechannel = devServer.getChannelByID(219626707458457603L); // developers-office
updatechannel = botchannel; updatechannel = botchannel;
devofficechannel = botchannel;// bot-room
dc.online("testing"); dc.online("testing");
} }
if (botchannel == null || annchannel == null || genchannel == null || botroomchannel == null if (botchannel == null || annchannel == null || genchannel == null || botroomchannel == null
@ -109,17 +115,26 @@ public class DiscordPlugin extends JavaPlugin implements IListener<ReadyEvent> {
if (task != null) if (task != null)
task.cancel(); task.cancel();
if (!sent) { if (!sent) {
if (getConfig().getBoolean("serverup", false)) {
sendMessageToChannel(chatchannel, "", new EmbedBuilder().withColor(Color.YELLOW)
.withTitle("Server recovered from a crash - chat connected.").build());
TBMCCoreAPI.SendException("The server crashed!", new Throwable(
"The server shut down unexpectedly. See the log of the previous run for more details."));
} else
sendMessageToChannel(chatchannel, "", new EmbedBuilder().withColor(Color.GREEN) sendMessageToChannel(chatchannel, "", new EmbedBuilder().withColor(Color.GREEN)
.withTitle("Server started - chat connected.").build()); .withTitle("Server started - chat connected.").build());
getConfig().set("serverup", true);
saveConfig();
perform(() -> {
try { try {
List<IMessage> msgs = genchannel.getPinnedMessages(); List<IMessage> msgs = genchannel.getPinnedMessages();
for (int i = msgs.size() - 1; i >= 10; i--) { // Unpin all pinned messages except the newest 10 for (int i = msgs.size() - 1; i >= 10; i--) { // Unpin all pinned messages except the newest 10
genchannel.unpin(msgs.get(i)); genchannel.unpin(msgs.get(i));
Thread.sleep(10); Thread.sleep(10);
} }
} catch (Exception e) { } catch (InterruptedException e) {
TBMCCoreAPI.SendException("Error occured while unpinning messages!", e);
} }
});
sent = true; sent = true;
} }
}, 0, 10); }, 0, 10);
@ -169,9 +184,12 @@ public class DiscordPlugin extends JavaPlugin implements IListener<ReadyEvent> {
@Override @Override
public void onDisable() { public void onDisable() {
stop = true; stop = true;
for(val entry : MCChatListener.ConnectedSenders.entrySet())
MCListener.callEventExcluding(new PlayerQuitEvent(entry.getValue(), ""), "ProtocolLib");
getConfig().set("lastannouncementtime", lastannouncementtime); getConfig().set("lastannouncementtime", lastannouncementtime);
getConfig().set("lastseentime", lastseentime); getConfig().set("lastseentime", lastseentime);
getConfig().set("gameroles", GameRoles); getConfig().set("gameroles", GameRoles);
getConfig().set("serverup", false);
saveConfig(); saveConfig();
sendMessageToChannel(chatchannel, "", new EmbedBuilder().withColor(Restart ? Color.ORANGE : Color.RED) sendMessageToChannel(chatchannel, "", new EmbedBuilder().withColor(Restart ? Color.ORANGE : Color.RED)
.withTitle(Restart ? "Server restarting" : "Server stopping").build()); .withTitle(Restart ? "Server restarting" : "Server stopping").build());
@ -215,6 +233,17 @@ public class DiscordPlugin extends JavaPlugin implements IListener<ReadyEvent> {
if (date > lastseentime) if (date > lastseentime)
lastseentime = date; lastseentime = date;
else if (date > lastannouncementtime) { else if (date > lastannouncementtime) {
do {
val reddituserclass = ChromaGamerBase.getTypeForFolder("reddit");
if (reddituserclass == null)
break;
val user = ChromaGamerBase.getUser(author, reddituserclass);
String id = user.getConnectedID(DiscordPlayer.class);
if (id != null)
author = "<@" + id + ">";
} while (false);
if (!author.startsWith("<"))
author = "/u/" + author;
(distinguished != null && distinguished.equals("moderator") ? modmsgsb : msgsb) (distinguished != null && distinguished.equals("moderator") ? modmsgsb : msgsb)
.append("A new post was submitted to the subreddit by ").append(author).append("\n") .append("A new post was submitted to the subreddit by ").append(author).append("\n")
.append(permalink).append("\n"); .append(permalink).append("\n");

View file

@ -9,7 +9,11 @@ import org.bukkit.Bukkit;
import org.bukkit.scheduler.BukkitTask; import org.bukkit.scheduler.BukkitTask;
import buttondevteam.lib.TBMCCoreAPI; import buttondevteam.lib.TBMCCoreAPI;
import buttondevteam.lib.chat.Channel;
import buttondevteam.lib.chat.IDiscordSender; import buttondevteam.lib.chat.IDiscordSender;
import lombok.Getter;
import lombok.NonNull;
import lombok.Setter;
import sx.blah.discord.handle.obj.IChannel; import sx.blah.discord.handle.obj.IChannel;
import sx.blah.discord.handle.obj.IUser; import sx.blah.discord.handle.obj.IUser;
@ -19,6 +23,7 @@ public abstract class DiscordSenderBase implements IDiscordSender {
*/ */
protected IUser user; protected IUser user;
protected IChannel channel; protected IChannel channel;
private @Getter @Setter @NonNull Channel mcchannel = Channel.GlobalChat;
protected DiscordSenderBase(IUser user, IChannel channel) { protected DiscordSenderBase(IUser user, IChannel channel) {
this.user = user; this.user = user;

View file

@ -8,11 +8,15 @@ import buttondevteam.discordplugin.DiscordPlayer;
import buttondevteam.discordplugin.DiscordPlugin; import buttondevteam.discordplugin.DiscordPlugin;
import buttondevteam.discordplugin.commands.DiscordCommandBase; import buttondevteam.discordplugin.commands.DiscordCommandBase;
import buttondevteam.lib.TBMCCoreAPI; import buttondevteam.lib.TBMCCoreAPI;
import lombok.val;
import sx.blah.discord.api.events.IListener; 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.MentionEvent;
import sx.blah.discord.handle.impl.events.guild.channel.message.MessageReceivedEvent; import sx.blah.discord.handle.impl.events.guild.channel.message.MessageReceivedEvent;
import sx.blah.discord.handle.impl.events.user.PresenceUpdateEvent;
import sx.blah.discord.handle.obj.IChannel; import sx.blah.discord.handle.obj.IChannel;
import sx.blah.discord.handle.obj.IMessage; import sx.blah.discord.handle.obj.IMessage;
import sx.blah.discord.handle.obj.StatusType;
import sx.blah.discord.util.EmbedBuilder;
public class CommandListener { public class CommandListener {
@ -89,6 +93,22 @@ public class CommandListener {
return; return;
runCommand(event.getMessage(), false); runCommand(event.getMessage(), false);
} }
}, new IListener<sx.blah.discord.handle.impl.events.user.PresenceUpdateEvent>() {
@Override
public void handle(PresenceUpdateEvent event) {
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)))
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());
}
} }; } };
} }
@ -126,7 +146,7 @@ public class CommandListener {
cmd = cmdwithargs.substring(0, index); cmd = cmdwithargs.substring(0, index);
args = cmdwithargs.substring(index + 1); args = cmdwithargs.substring(index + 1);
} }
DiscordCommandBase.runCommand(cmd, args, message); DiscordCommandBase.runCommand(cmd.toLowerCase(), args, message);
message.getChannel().setTypingStatus(false); message.getChannel().setTypingStatus(false);
return true; return true;
} }

View file

@ -1,12 +1,8 @@
package buttondevteam.discordplugin.listeners; package buttondevteam.discordplugin.listeners;
import java.awt.Color; import java.awt.Color;
import java.util.ArrayList; import java.util.*;
import java.util.Arrays; import java.util.function.*;
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.Collectors;
import java.util.stream.Stream; import java.util.stream.Stream;
@ -21,8 +17,10 @@ import buttondevteam.discordplugin.*;
import buttondevteam.discordplugin.playerfaker.VanillaCommandListener; import buttondevteam.discordplugin.playerfaker.VanillaCommandListener;
import buttondevteam.lib.*; import buttondevteam.lib.*;
import buttondevteam.lib.chat.Channel; import buttondevteam.lib.chat.Channel;
import buttondevteam.lib.chat.ChatRoom;
import buttondevteam.lib.chat.TBMCChatAPI; import buttondevteam.lib.chat.TBMCChatAPI;
import buttondevteam.lib.player.TBMCPlayer; import buttondevteam.lib.player.TBMCPlayer;
import lombok.RequiredArgsConstructor;
import lombok.val; import lombok.val;
import sx.blah.discord.api.events.IListener; import sx.blah.discord.api.events.IListener;
import sx.blah.discord.api.internal.json.objects.EmbedObject; import sx.blah.discord.api.internal.json.objects.EmbedObject;
@ -35,8 +33,6 @@ public class MCChatListener implements Listener, IListener<MessageReceivedEvent>
public void onMCChat(TBMCChatEvent e) { public void onMCChat(TBMCChatEvent e) {
if (e.isCancelled()) if (e.isCancelled())
return; return;
if (e.getSender() instanceof DiscordSender || e.getSender() instanceof DiscordPlayerSender)
return;
Bukkit.getScheduler().runTaskAsynchronously(DiscordPlugin.plugin, () -> { Bukkit.getScheduler().runTaskAsynchronously(DiscordPlugin.plugin, () -> {
synchronized (this) { synchronized (this) {
final String authorPlayer = DiscordPlugin.sanitizeString(e.getSender() instanceof Player // final String authorPlayer = DiscordPlugin.sanitizeString(e.getSender() instanceof Player //
@ -46,8 +42,13 @@ public class MCChatListener implements Listener, IListener<MessageReceivedEvent>
.withDescription(e.getMessage()).withColor(new Color(e.getChannel().color.getRed(), .withDescription(e.getMessage()).withColor(new Color(e.getChannel().color.getRed(),
e.getChannel().color.getGreen(), e.getChannel().color.getBlue())); e.getChannel().color.getGreen(), e.getChannel().color.getBlue()));
if (e.getSender() instanceof Player) if (e.getSender() instanceof Player)
embed.withAuthorIcon( embed.withAuthorIcon("https://minotar.net/avatar/" + ((Player) e.getSender()).getName() + "/32.png")
"https://minotar.net/avatar/" + ((Player) e.getSender()).getName() + "/32.png"); .withAuthorUrl("https://tbmcplugins.github.io/profile.html?type=minecraft&id="
+ ((Player) e.getSender()).getUniqueId()); // TODO: Constant/method to get URLs like this
else if (e.getSender() instanceof DiscordSenderBase)
embed.withAuthorIcon(((DiscordSenderBase) e.getSender()).getUser().getAvatarURL())
.withAuthorUrl("https://tbmcplugins.github.io/profile.html?type=discord&id="
+ ((DiscordSenderBase) e.getSender()).getUser().getStringID()); // TODO: Constant/method to get URLs like this
final long nanoTime = System.nanoTime(); final long nanoTime = System.nanoTime();
Consumer<LastMsgData> doit = lastmsgdata -> { Consumer<LastMsgData> doit = lastmsgdata -> {
final EmbedObject embedObject = embed.build(); final EmbedObject embedObject = embed.build();
@ -71,31 +72,37 @@ public class MCChatListener implements Listener, IListener<MessageReceivedEvent>
TBMCCoreAPI.SendException("An error occured while editing chat message!", e1); TBMCCoreAPI.SendException("An error occured while editing chat message!", e1);
} }
}; };
if (e.getChannel().equals(Channel.GlobalChat)) Predicate<IChannel> isdifferentchannel = ch -> !(e.getSender() instanceof DiscordSenderBase)
doit.accept(lastmsgdata == null ? lastmsgdata = new LastMsgData(DiscordPlugin.chatchannel) || ((DiscordSenderBase) e.getSender()).getChannel().getLongID() != ch.getLongID();
: lastmsgdata);
if (e.getChannel().equals(Channel.GlobalChat) && isdifferentchannel.test(DiscordPlugin.chatchannel))
doit.accept(lastmsgdata == null
? lastmsgdata = new LastMsgData(DiscordPlugin.chatchannel, null, null) : lastmsgdata);
for (LastMsgData data : lastmsgPerUser) { for (LastMsgData data : lastmsgPerUser) {
final IUser iUser = data.channel.getUsersHere().stream() // System.out.println("Data: " + data);
.filter(u -> u.getLongID() != u.getClient().getOurUser().getLongID()).findFirst().get(); // Doesn't support group DMs // System.out.println("Data.channel: " + data.channel);
final DiscordPlayer user = DiscordPlayer.getUser(iUser.getStringID(), DiscordPlayer.class); // System.out.println("Sender: " + e.getSender());
if (user.isMinecraftChatEnabled() && e.shouldSendTo(getSender(data.channel, iUser, user))) // System.out.println("Sender channel: " + ((DiscordSenderBase) e.getSender()).getChannel()); // TODO
// System.out.println("Predicate: " + isdifferentchannel);
// System.out.println("DP: " + data.dp); - Didn't update the constructor
if (data.dp.isMinecraftChatEnabled() && isdifferentchannel.test(data.channel)
&& e.shouldSendTo(getSender(data.channel, data.user, data.dp)))
doit.accept(data); doit.accept(data);
} }
} }
}); // TODO: Author URL });
} }
@RequiredArgsConstructor
private static class LastMsgData { private static class LastMsgData {
public IMessage message; public IMessage message;
public long time; public long time;
public String content; public String content;
public IChannel channel; public final IChannel channel;
public Channel mcchannel; public Channel mcchannel;
public final IUser user;
public LastMsgData(IChannel channel) { public final DiscordPlayer dp;
this.channel = channel;
}
} }
@EventHandler @EventHandler
@ -134,19 +141,20 @@ public class MCChatListener implements Listener, IListener<MessageReceivedEvent>
TBMCPlayer mcp = dp.getAs(TBMCPlayer.class); TBMCPlayer mcp = dp.getAs(TBMCPlayer.class);
if (mcp != null) { // If the accounts aren't connected, can't make a connected sender if (mcp != null) { // If the accounts aren't connected, can't make a connected sender
val p = Bukkit.getPlayer(mcp.getUUID()); val p = Bukkit.getPlayer(mcp.getUUID());
val op = Bukkit.getOfflinePlayer(mcp.getUUID());
if (start) { if (start) {
val sender = new DiscordConnectedPlayer(user, channel, mcp.getUUID()); val sender = new DiscordConnectedPlayer(user, channel, mcp.getUUID(), op.getName());
ConnectedSenders.put(user.getStringID(), sender); ConnectedSenders.put(user.getStringID(), sender);
if (p == null)// Player is offline - If the player is online, that takes precedence if (p == null)// Player is offline - If the player is online, that takes precedence
Bukkit.getPluginManager().callEvent(new PlayerJoinEvent(sender, "")); MCListener.callEventExcluding(new PlayerJoinEvent(sender, ""), "ProtocolLib");
} else { } else {
val sender = ConnectedSenders.remove(user.getStringID()); val sender = ConnectedSenders.remove(user.getStringID());
if (p == null)// Player is offline - If the player is online, that takes precedence if (p == null)// Player is offline - If the player is online, that takes precedence
Bukkit.getPluginManager().callEvent(new PlayerQuitEvent(sender, "")); MCListener.callEventExcluding(new PlayerQuitEvent(sender, ""), "ProtocolLib");
} }
} }
return start // return start //
? lastmsgPerUser.add(new LastMsgData(channel)) // ? lastmsgPerUser.add(new LastMsgData(channel, user, dp)) // Doesn't support group DMs
: lastmsgPerUser.removeIf(lmd -> lmd.channel.getLongID() == channel.getLongID()); : lastmsgPerUser.removeIf(lmd -> lmd.channel.getLongID() == channel.getLongID());
} }
@ -178,15 +186,27 @@ public class MCChatListener implements Listener, IListener<MessageReceivedEvent>
public static short ListC = 0; public static short ListC = 0;
public static void resetLastMessage() { public static void resetLastMessage() {
(lastmsgdata == null ? lastmsgdata = new LastMsgData(DiscordPlugin.chatchannel) : lastmsgdata).message = null; // Don't set the whole object to null, the player and channel information should (lastmsgdata == null ? lastmsgdata = new LastMsgData(DiscordPlugin.chatchannel, null, null)
} // be preserved : lastmsgdata).message = null;
} // Don't set the whole object to null, the player and channel information should be preserved
/**
* This overload sends it to the global chat.
*/
public static void sendSystemMessageToChat(String msg) { public static void sendSystemMessageToChat(String msg) {
DiscordPlugin.sendMessageToChannel(DiscordPlugin.chatchannel, msg); DiscordPlugin.sendMessageToChannel(DiscordPlugin.chatchannel, msg);
for (LastMsgData data : lastmsgPerUser) for (LastMsgData data : lastmsgPerUser)
DiscordPlugin.sendMessageToChannel(data.channel, msg); DiscordPlugin.sendMessageToChannel(data.channel, msg);
} }
public static void sendSystemMessageToChat(TBMCSystemChatEvent event) {
if (Channel.GlobalChat.ID.equals(event.getChannel().ID))
DiscordPlugin.sendMessageToChannel(DiscordPlugin.chatchannel, event.getMessage());
for (LastMsgData data : lastmsgPerUser)
if (event.shouldSendTo(getSender(data.channel, data.user, data.dp)))
DiscordPlugin.sendMessageToChannel(data.channel, event.getMessage());
}
@Override // Discord @Override // Discord
public void handle(MessageReceivedEvent event) { public void handle(MessageReceivedEvent event) {
val author = event.getMessage().getAuthor(); val author = event.getMessage().getAuthor();
@ -212,7 +232,15 @@ public class MCChatListener implements Listener, IListener<MessageReceivedEvent>
dmessage = dmessage.replace(u.mention(true), "@" + (nick != null ? nick : u.getName())); dmessage = dmessage.replace(u.mention(true), "@" + (nick != null ? nick : u.getName()));
} }
if (dmessage.startsWith("/")) { BiConsumer<Channel, String> sendChatMessage = (channel, msg) -> TBMCChatAPI.SendChatMessage(channel,
dsender,
msg + (event.getMessage().getAttachments().size() > 0 ? "\n" + event.getMessage()
.getAttachments().stream().map(a -> a.getUrl()).collect(Collectors.joining("\n"))
: ""));
boolean react = false;
if (dmessage.startsWith("/")) { // Ingame command
DiscordPlugin.perform(() -> { DiscordPlugin.perform(() -> {
if (!event.getMessage().isDeleted() && !event.getChannel().isPrivate()) if (!event.getMessage().isDeleted() && !event.getChannel().isPrivate())
event.getMessage().delete(); event.getMessage().delete();
@ -238,20 +266,47 @@ public class MCChatListener implements Listener, IListener<MessageReceivedEvent>
{ {
dsender.sendMessage("Stop it. You know the answer."); dsender.sendMessage("Stop it. You know the answer.");
lastlist = 0; lastlist = 0;
} else
VanillaCommandListener.runBukkitOrVanillaCommand(dsender, cmd);
lastlistp = (short) Bukkit.getOnlinePlayers().size();
} else { } else {
if (dmessage.length() == 0 && event.getMessage().getAttachments().size() == 0) int spi = cmd.indexOf(' ');
final String topcmd = spi == -1 ? cmd : cmd.substring(0, spi);
Optional<Channel> ch = Channel.getChannels().stream().filter(c -> c.ID.equalsIgnoreCase(topcmd))
.findAny();
if (!ch.isPresent())
VanillaCommandListener.runBukkitOrVanillaCommand(dsender, cmd);
else {
Channel chc = ch.get();
if (!chc.ID.equals(Channel.GlobalChat.ID) && !event.getMessage().getChannel().isPrivate())
dsender.sendMessage(
"You can only talk in global in the public chat. DM `mcchat` to enable private chat to talk in the other channels.");
else {
if (spi == -1) // Switch channels
{
val oldch = dsender.getMcchannel();
if (oldch instanceof ChatRoom)
((ChatRoom) oldch).leaveRoom(dsender);
dsender.setMcchannel(chc);
if (chc instanceof ChatRoom)
((ChatRoom) chc).joinRoom(dsender);
dsender.sendMessage("You're now talking in: "
+ DiscordPlugin.sanitizeString(dsender.getMcchannel().DisplayName));
} else { // Send single message
sendChatMessage.accept(chc, cmd.substring(spi + 1));
react = true;
}
}
}
}
lastlistp = (short) Bukkit.getOnlinePlayers().size();
} else {// Not a command
if (dmessage.length() == 0 && event.getMessage().getAttachments().size() == 0
&& !event.getChannel().isPrivate())
TBMCChatAPI.SendChatMessage(Channel.GlobalChat, dsender, "pinned a message on Discord."); // TODO: Not chat message TBMCChatAPI.SendChatMessage(Channel.GlobalChat, dsender, "pinned a message on Discord."); // TODO: Not chat message
else else {
TBMCChatAPI sendChatMessage.accept(dsender.getMcchannel(), dmessage);
.SendChatMessage(Channel.GlobalChat, react = true;
dsender, dmessage }
+ (event.getMessage().getAttachments().size() > 0 }
? "\n" + event.getMessage().getAttachments().stream() if (react) {
.map(a -> a.getUrl()).collect(Collectors.joining("\n"))
: ""));
event.getMessage().getChannel().getMessageHistory().stream().forEach(m -> { event.getMessage().getChannel().getMessageHistory().stream().forEach(m -> {
try { try {
final IReaction reaction = m.getReactionByUnicode(DiscordPlugin.DELIVERED_REACTION); final IReaction reaction = m.getReactionByUnicode(DiscordPlugin.DELIVERED_REACTION);
@ -273,7 +328,7 @@ 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. * 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 DiscordSenderBase getSender(IChannel channel, final IUser author, DiscordPlayer dp) { private static DiscordSenderBase getSender(IChannel channel, final IUser author, DiscordPlayer dp) {
val key = (channel.isPrivate() ? "" : "P") + author.getStringID(); val key = (channel.isPrivate() ? "" : "P") + author.getStringID();
return Stream.<Supplier<Optional<DiscordSenderBase>>>of( // https://stackoverflow.com/a/28833677/2703239 return Stream.<Supplier<Optional<DiscordSenderBase>>>of( // https://stackoverflow.com/a/28833677/2703239
() -> Optional.ofNullable(OnlineSenders.get(key)), // Find first non-null () -> Optional.ofNullable(OnlineSenders.get(key)), // Find first non-null

View file

@ -1,14 +1,22 @@
package buttondevteam.discordplugin.listeners; package buttondevteam.discordplugin.listeners;
import java.util.Arrays;
import java.util.logging.Level;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.event.Event;
import org.bukkit.event.EventHandler; import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority; import org.bukkit.event.EventPriority;
import org.bukkit.event.HandlerList;
import org.bukkit.event.Listener; import org.bukkit.event.Listener;
import org.bukkit.event.entity.PlayerDeathEvent; import org.bukkit.event.entity.PlayerDeathEvent;
import org.bukkit.event.player.PlayerJoinEvent; import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.event.player.PlayerQuitEvent; import org.bukkit.event.player.PlayerQuitEvent;
import org.bukkit.event.server.ServerCommandEvent; import org.bukkit.event.server.ServerCommandEvent;
import org.bukkit.plugin.AuthorNagException;
import org.bukkit.plugin.Plugin;
import org.bukkit.plugin.RegisteredListener;
import com.earth2me.essentials.CommandSource; import com.earth2me.essentials.CommandSource;
@ -18,6 +26,7 @@ import buttondevteam.discordplugin.DiscordPlayerSender;
import buttondevteam.discordplugin.DiscordPlugin; import buttondevteam.discordplugin.DiscordPlugin;
import buttondevteam.discordplugin.commands.ConnectCommand; import buttondevteam.discordplugin.commands.ConnectCommand;
import buttondevteam.lib.TBMCCoreAPI; import buttondevteam.lib.TBMCCoreAPI;
import buttondevteam.lib.TBMCSystemChatEvent;
import buttondevteam.lib.player.*; import buttondevteam.lib.player.*;
import lombok.val; import lombok.val;
import net.ess3.api.events.*; import net.ess3.api.events.*;
@ -41,7 +50,7 @@ public class MCListener implements Listener {
new DiscordPlayerSender(user, DiscordPlugin.chatchannel, p)); new DiscordPlayerSender(user, DiscordPlugin.chatchannel, p));
MCChatListener.ConnectedSenders.values().stream() MCChatListener.ConnectedSenders.values().stream()
.filter(s -> s.getUniqueId().equals(e.getPlayer().getUniqueId())).findAny() .filter(s -> s.getUniqueId().equals(e.getPlayer().getUniqueId())).findAny()
.ifPresent(dcp -> Bukkit.getPluginManager().callEvent(new PlayerQuitEvent(dcp, ""))); .ifPresent(dcp -> callEventExcluding(new PlayerQuitEvent(dcp, ""), "ProtocolLib"));
} }
if (ConnectCommand.WaitingToConnect.containsKey(e.GetPlayer().PlayerName().get())) { if (ConnectCommand.WaitingToConnect.containsKey(e.GetPlayer().PlayerName().get())) {
IUser user = DiscordPlugin.dc IUser user = DiscordPlugin.dc
@ -62,7 +71,7 @@ public class MCListener implements Listener {
.removeIf(entry -> entry.getValue().getUniqueId().equals(e.getPlayer().getUniqueId())); .removeIf(entry -> entry.getValue().getUniqueId().equals(e.getPlayer().getUniqueId()));
MCChatListener.ConnectedSenders.values().stream() MCChatListener.ConnectedSenders.values().stream()
.filter(s -> s.getUniqueId().equals(e.getPlayer().getUniqueId())).findAny() .filter(s -> s.getUniqueId().equals(e.getPlayer().getUniqueId())).findAny()
.ifPresent(dcp -> Bukkit.getPluginManager().callEvent(new PlayerJoinEvent(dcp, ""))); .ifPresent(dcp -> callEventExcluding(new PlayerJoinEvent(dcp, ""), "ProtocolLib"));
MCChatListener.sendSystemMessageToChat(e.GetPlayer().PlayerName().get() + " left the game"); MCChatListener.sendSystemMessageToChat(e.GetPlayer().PlayerName().get() + " left the game");
} }
@ -121,4 +130,67 @@ public class MCListener implements Listener {
ex); ex);
} }
} }
@EventHandler
public void onChatSystemMessage(TBMCSystemChatEvent event) {
MCChatListener.sendSystemMessageToChat(event);
}
/**
* 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.
*/
public 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);
}
}
}
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);
}
}
}
} }

View file

@ -16,22 +16,21 @@ import org.bukkit.scoreboard.Scoreboard;
import buttondevteam.discordplugin.DiscordPlugin; import buttondevteam.discordplugin.DiscordPlugin;
import lombok.experimental.Delegate; import lombok.experimental.Delegate;
import lombok.Getter;
import sx.blah.discord.handle.obj.IChannel; import sx.blah.discord.handle.obj.IChannel;
import sx.blah.discord.handle.obj.IUser; import sx.blah.discord.handle.obj.IUser;
public class DiscordFakePlayer extends DiscordHumanEntity implements Player { public class DiscordFakePlayer extends DiscordHumanEntity implements Player {
protected DiscordFakePlayer(IUser user, IChannel channel, int entityId, UUID uuid) { protected DiscordFakePlayer(IUser user, IChannel channel, int entityId, UUID uuid, String mcname) {
super(user, channel, entityId, uuid); super(user, channel, entityId, uuid);
perm = new PermissibleBase(Bukkit.getOfflinePlayer(uuid)); perm = new PermissibleBase(Bukkit.getOfflinePlayer(uuid));
name = mcname;
} }
@Delegate @Delegate
private PermissibleBase perm; private PermissibleBase perm;
@Override private @Getter String name;
public String getName() {
return user.getName();
}
@Override @Override
public EntityType getType() { public EntityType getType() {