Performance improvements (user data)
CommandSender (DiscordSenderBase) level of caching implemented (not perfect but much better than before) Various mcchat improvements
This commit is contained in:
parent
9e827d14d0
commit
7d624816f2
5 changed files with 42 additions and 79 deletions
|
@ -38,6 +38,7 @@ import java.awt.*;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Optional;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
import java.util.concurrent.TimeoutException;
|
import java.util.concurrent.TimeoutException;
|
||||||
|
@ -149,7 +150,6 @@ public class DiscordPlugin extends JavaPlugin implements IListener<ReadyEvent> {
|
||||||
val mcch = Channel.getChannels().stream().filter(ch -> ch.ID.equals(chcon.getString("mcchid"))).findAny();
|
val mcch = Channel.getChannels().stream().filter(ch -> ch.ID.equals(chcon.getString("mcchid"))).findAny();
|
||||||
val ch = dc.getChannelByID(chcon.getLong("chid"));
|
val ch = dc.getChannelByID(chcon.getLong("chid"));
|
||||||
val did = chcon.getLong("did");
|
val did = chcon.getLong("did");
|
||||||
val dp = DiscordPlayer.getUser(Long.toString(did), DiscordPlayer.class);
|
|
||||||
val user = dc.fetchUser(did);
|
val user = dc.fetchUser(did);
|
||||||
val dcp = new DiscordConnectedPlayer(user, ch, UUID.fromString(chcon.getString("mcuid")), chcon.getString("mcname"));
|
val dcp = new DiscordConnectedPlayer(user, ch, UUID.fromString(chcon.getString("mcuid")), chcon.getString("mcname"));
|
||||||
val groupid = chcon.getString("groupid");
|
val groupid = chcon.getString("groupid");
|
||||||
|
@ -221,6 +221,8 @@ public class DiscordPlugin extends JavaPlugin implements IListener<ReadyEvent> {
|
||||||
TBMCCoreAPI.RegisterEventsForExceptions(new MCListener(), this);
|
TBMCCoreAPI.RegisterEventsForExceptions(new MCListener(), this);
|
||||||
TBMCChatAPI.AddCommands(this, DiscordMCCommandBase.class);
|
TBMCChatAPI.AddCommands(this, DiscordMCCommandBase.class);
|
||||||
TBMCCoreAPI.RegisterUserClass(DiscordPlayer.class);
|
TBMCCoreAPI.RegisterUserClass(DiscordPlayer.class);
|
||||||
|
ChromaGamerBase.addConverter(sender -> Optional.ofNullable(sender instanceof DiscordSenderBase
|
||||||
|
? ((DiscordSenderBase) sender).getChromaUser() : null));
|
||||||
new Thread(this::AnnouncementGetterThreadMethod).start();
|
new Thread(this::AnnouncementGetterThreadMethod).start();
|
||||||
setupProviders();
|
setupProviders();
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
|
|
|
@ -1,26 +1,18 @@
|
||||||
package buttondevteam.discordplugin;
|
package buttondevteam.discordplugin;
|
||||||
|
|
||||||
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 org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.scheduler.BukkitTask;
|
import org.bukkit.scheduler.BukkitTask;
|
||||||
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;
|
||||||
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
|
||||||
public abstract class DiscordSenderBase implements IDiscordSender {
|
public abstract class DiscordSenderBase implements IDiscordSender {
|
||||||
/**
|
/**
|
||||||
* May be null.
|
* May be null.
|
||||||
*/
|
*/
|
||||||
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;
|
||||||
|
@ -43,6 +35,18 @@ public abstract class DiscordSenderBase implements IDiscordSender {
|
||||||
return channel;
|
return channel;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private DiscordPlayer chromaUser;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Loads the user data on first query.
|
||||||
|
*
|
||||||
|
* @return A Chroma user of Discord or a Discord user of Chroma
|
||||||
|
*/
|
||||||
|
public DiscordPlayer getChromaUser() {
|
||||||
|
if (chromaUser == null) chromaUser = DiscordPlayer.getUser(user.getStringID(), DiscordPlayer.class);
|
||||||
|
return chromaUser;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void sendMessage(String message) {
|
public void sendMessage(String message) {
|
||||||
try {
|
try {
|
||||||
|
@ -65,6 +69,6 @@ public abstract class DiscordSenderBase implements IDiscordSender {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void sendMessage(String[] messages) {
|
public void sendMessage(String[] messages) {
|
||||||
sendMessage(Arrays.stream(messages).collect(Collectors.joining("\n")));
|
sendMessage(String.join("\n", messages));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
package buttondevteam.discordplugin.listeners;
|
package buttondevteam.discordplugin.listeners;
|
||||||
|
|
||||||
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;
|
||||||
|
@ -99,8 +98,7 @@ public class CommandListener {
|
||||||
&& !(event.getMessage().getContent().startsWith("/")
|
&& !(event.getMessage().getContent().startsWith("/")
|
||||||
&& event.getChannel().getStringID().equals(DiscordPlugin.botchannel.getStringID()))) //
|
&& event.getChannel().getStringID().equals(DiscordPlugin.botchannel.getStringID()))) //
|
||||||
return;
|
return;
|
||||||
if (DiscordPlayer.getUser(event.getAuthor().getStringID(), DiscordPlayer.class)
|
if (MCChatListener.isMinecraftChatEnabled(event.getAuthor().toString()))
|
||||||
.isMinecraftChatEnabled())
|
|
||||||
if (!event.getMessage().getContent().equalsIgnoreCase("mcchat"))
|
if (!event.getMessage().getContent().equalsIgnoreCase("mcchat"))
|
||||||
return;
|
return;
|
||||||
if (event.getMessage().getAuthor().isBot())
|
if (event.getMessage().getAuthor().isBot())
|
||||||
|
|
|
@ -7,6 +7,7 @@ import buttondevteam.lib.chat.Channel;
|
||||||
import buttondevteam.lib.chat.ChatMessage;
|
import buttondevteam.lib.chat.ChatMessage;
|
||||||
import buttondevteam.lib.chat.ChatRoom;
|
import buttondevteam.lib.chat.ChatRoom;
|
||||||
import buttondevteam.lib.chat.TBMCChatAPI;
|
import buttondevteam.lib.chat.TBMCChatAPI;
|
||||||
|
import buttondevteam.lib.player.PlayerData;
|
||||||
import buttondevteam.lib.player.TBMCPlayer;
|
import buttondevteam.lib.player.TBMCPlayer;
|
||||||
import com.vdurmont.emoji.EmojiParser;
|
import com.vdurmont.emoji.EmojiParser;
|
||||||
import io.netty.util.collection.LongObjectHashMap;
|
import io.netty.util.collection.LongObjectHashMap;
|
||||||
|
@ -403,28 +404,24 @@ public class MCChatListener implements Listener, IListener<MessageReceivedEvent>
|
||||||
public static void forAllowedCustomAndAllMCChat(Consumer<IChannel> action, @Nullable CommandSender sender, @Nullable ChannelconBroadcast toggle, boolean hookmsg) {
|
public static void forAllowedCustomAndAllMCChat(Consumer<IChannel> action, @Nullable CommandSender sender, @Nullable ChannelconBroadcast toggle, boolean hookmsg) {
|
||||||
if (!DiscordPlugin.hooked || !hookmsg)
|
if (!DiscordPlugin.hooked || !hookmsg)
|
||||||
forAllMCChat(action);
|
forAllMCChat(action);
|
||||||
lastmsgCustom.stream().filter(clmd -> {
|
forAllowedCustomMCChat(action, sender, toggle); //TODO: Use getScore and getGroupID in fake event constructor - This should also send error messages on channel connect
|
||||||
if (toggle != null && (clmd.toggles & toggle.flag) == 0)
|
|
||||||
return false; //If null then allow
|
|
||||||
if (sender == null)
|
|
||||||
return true;
|
|
||||||
val e = new TBMCChannelConnectFakeEvent(sender, clmd.mcchannel);
|
|
||||||
return clmd.groupID.equals(e.getGroupID(sender));
|
|
||||||
}).forEach(cc -> action.accept(cc.channel)); //TODO: Use getScore and getGroupID in fake event constructor - This should also send error messages on channel connect
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Consumer<IChannel> send(String message) {
|
public static Consumer<IChannel> send(String message) {
|
||||||
return ch -> DiscordPlugin.sendMessageToChannel(ch, DPUtils.sanitizeString(message));
|
return ch -> DiscordPlugin.sendMessageToChannel(ch, DPUtils.sanitizeString(message));
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void forAllowedMCChat(Consumer<IChannel> action, TBMCSystemChatEvent event) {
|
public static void forAllowedMCChat(Consumer<IChannel> action, TBMCSystemChatEvent event) { //TODO
|
||||||
if (Channel.GlobalChat.ID.equals(event.getChannel().ID))
|
if (Channel.GlobalChat.ID.equals(event.getChannel().ID))
|
||||||
action.accept(DiscordPlugin.chatchannel);
|
action.accept(DiscordPlugin.chatchannel);
|
||||||
for (LastMsgData data : lastmsgPerUser)
|
for (LastMsgData data : lastmsgPerUser)
|
||||||
if (event.shouldSendTo(getSender(data.channel, data.user)))
|
if (event.shouldSendTo(getSender(data.channel, data.user)))
|
||||||
action.accept(data.channel);
|
action.accept(data.channel);
|
||||||
lastmsgCustom.stream().filter(data -> event.shouldSendTo(data.dcp))
|
lastmsgCustom.stream().filter(clmd -> {
|
||||||
.map(data -> data.channel).forEach(action);
|
if ((clmd.toggles & ChannelconBroadcast.BROADCAST.flag) == 0)
|
||||||
|
return false;
|
||||||
|
return event.shouldSendTo(clmd.dcp);
|
||||||
|
}).map(clmd -> clmd.channel).forEach(action);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -504,10 +501,10 @@ public class MCChatListener implements Listener, IListener<MessageReceivedEvent>
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
val sender = event.getMessage().getAuthor();
|
val sender = event.getMessage().getAuthor();
|
||||||
val user = DiscordPlayer.getUser(sender.getStringID(), DiscordPlayer.class);
|
|
||||||
String dmessage = event.getMessage().getContent();
|
String dmessage = event.getMessage().getContent();
|
||||||
try {
|
try {
|
||||||
final DiscordSenderBase dsender = getSender(event.getMessage().getChannel(), sender);
|
final DiscordSenderBase dsender = getSender(event.getMessage().getChannel(), sender);
|
||||||
|
val user = dsender.getChromaUser();
|
||||||
|
|
||||||
for (IUser u : event.getMessage().getMentions()) {
|
for (IUser u : event.getMessage().getMentions()) {
|
||||||
dmessage = dmessage.replace(u.mention(false), "@" + u.getName()); // TODO: IG Formatting
|
dmessage = dmessage.replace(u.mention(false), "@" + u.getName()); // TODO: IG Formatting
|
||||||
|
@ -523,7 +520,7 @@ public class MCChatListener implements Listener, IListener<MessageReceivedEvent>
|
||||||
|
|
||||||
Function<String, String> getChatMessage = msg -> //
|
Function<String, String> getChatMessage = msg -> //
|
||||||
msg + (event.getMessage().getAttachments().size() > 0 ? "\n" + event.getMessage()
|
msg + (event.getMessage().getAttachments().size() > 0 ? "\n" + event.getMessage()
|
||||||
.getAttachments().stream().map(a -> a.getUrl()).collect(Collectors.joining("\n"))
|
.getAttachments().stream().map(IMessage.Attachment::getUrl).collect(Collectors.joining("\n"))
|
||||||
: "");
|
: "");
|
||||||
|
|
||||||
CustomLMD clmd = getCustomChat(event.getChannel());
|
CustomLMD clmd = getCustomChat(event.getChannel());
|
||||||
|
@ -535,7 +532,6 @@ public class MCChatListener implements Listener, IListener<MessageReceivedEvent>
|
||||||
if (!event.getMessage().isDeleted() && !event.getChannel().isPrivate())
|
if (!event.getMessage().isDeleted() && !event.getChannel().isPrivate())
|
||||||
event.getMessage().delete();
|
event.getMessage().delete();
|
||||||
});
|
});
|
||||||
//preprocessChat(dsender, dmessage); - Same is done below
|
|
||||||
final String cmd = dmessage.substring(1);
|
final String cmd = dmessage.substring(1);
|
||||||
final String cmdlowercased = cmd.toLowerCase();
|
final String cmdlowercased = cmd.toLowerCase();
|
||||||
if (dsender instanceof DiscordSender && Arrays.stream(UnconnectedCmds)
|
if (dsender instanceof DiscordSender && Arrays.stream(UnconnectedCmds)
|
||||||
|
@ -581,24 +577,25 @@ public class MCChatListener implements Listener, IListener<MessageReceivedEvent>
|
||||||
else {
|
else {
|
||||||
if (spi == -1) // Switch channels
|
if (spi == -1) // Switch channels
|
||||||
{
|
{
|
||||||
val oldch = dsender.getMcchannel();
|
final PlayerData<Channel> channel = dsender.getChromaUser().channel();
|
||||||
|
val oldch = channel.get();
|
||||||
if (oldch instanceof ChatRoom)
|
if (oldch instanceof ChatRoom)
|
||||||
((ChatRoom) oldch).leaveRoom(dsender);
|
((ChatRoom) oldch).leaveRoom(dsender);
|
||||||
if (!oldch.ID.equals(chc.ID)) {
|
if (!oldch.ID.equals(chc.ID)) {
|
||||||
dsender.setMcchannel(chc);
|
channel.set(chc);
|
||||||
if (chc instanceof ChatRoom)
|
if (chc instanceof ChatRoom)
|
||||||
((ChatRoom) chc).joinRoom(dsender);
|
((ChatRoom) chc).joinRoom(dsender);
|
||||||
} else
|
} else
|
||||||
dsender.setMcchannel(Channel.GlobalChat);
|
channel.set(Channel.GlobalChat);
|
||||||
dsender.sendMessage("You're now talking in: "
|
dsender.sendMessage("You're now talking in: "
|
||||||
+ DPUtils.sanitizeString(dsender.getMcchannel().DisplayName));
|
+ DPUtils.sanitizeString(channel.get().DisplayName));
|
||||||
} else { // Send single message
|
} else { // Send single message
|
||||||
final String msg = cmd.substring(spi + 1);
|
final String msg = cmd.substring(spi + 1);
|
||||||
val cmb = ChatMessage.builder(chc, dsender, user, getChatMessage.apply(msg)).fromCommand(true);
|
val cmb = ChatMessage.builder(dsender, user, getChatMessage.apply(msg)).fromCommand(true);
|
||||||
if (clmd == null)
|
if (clmd == null)
|
||||||
TBMCChatAPI.SendChatMessage(cmb.build());
|
TBMCChatAPI.SendChatMessage(cmb.build(), chc);
|
||||||
else
|
else
|
||||||
TBMCChatAPI.SendChatMessage(cmb.permCheck(clmd.dcp).build());
|
TBMCChatAPI.SendChatMessage(cmb.permCheck(clmd.dcp).build(), chc);
|
||||||
react = true;
|
react = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -612,9 +609,9 @@ public class MCChatListener implements Listener, IListener<MessageReceivedEvent>
|
||||||
(dsender instanceof Player ? ((Player) dsender).getDisplayName()
|
(dsender instanceof Player ? ((Player) dsender).getDisplayName()
|
||||||
: dsender.getName()) + " pinned a message on Discord.");
|
: dsender.getName()) + " pinned a message on Discord.");
|
||||||
else {
|
else {
|
||||||
val cmb = ChatMessage.builder(dsender.getMcchannel(), dsender, user, getChatMessage.apply(dmessage)).fromCommand(false);
|
val cmb = ChatMessage.builder(dsender, user, getChatMessage.apply(dmessage)).fromCommand(false);
|
||||||
if (clmd != null)
|
if (clmd != null)
|
||||||
TBMCChatAPI.SendChatMessage(cmb.channel(clmd.mcchannel).permCheck(clmd.dcp).build());
|
TBMCChatAPI.SendChatMessage(cmb.permCheck(clmd.dcp).build(), clmd.mcchannel);
|
||||||
else
|
else
|
||||||
TBMCChatAPI.SendChatMessage(cmb.build());
|
TBMCChatAPI.SendChatMessage(cmb.build());
|
||||||
react = true;
|
react = true;
|
||||||
|
@ -638,55 +635,17 @@ public class MCChatListener implements Listener, IListener<MessageReceivedEvent>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean preprocessChat(DiscordSenderBase dsender, String dmessage) {
|
|
||||||
if (dmessage.length() < 2)
|
|
||||||
return false;
|
|
||||||
int index = dmessage.indexOf(" ");
|
|
||||||
String cmd;
|
|
||||||
if (index == -1) { // Only the command is run
|
|
||||||
cmd = dmessage;
|
|
||||||
for (Channel channel : Channel.getChannels()) {
|
|
||||||
if (cmd.equalsIgnoreCase(channel.ID) || (channel.IDs != null && Arrays.stream(channel.IDs).anyMatch(cmd::equalsIgnoreCase))) {
|
|
||||||
Channel oldch = dsender.getMcchannel();
|
|
||||||
if (oldch instanceof ChatRoom)
|
|
||||||
((ChatRoom) oldch).leaveRoom(dsender);
|
|
||||||
if (oldch.equals(channel))
|
|
||||||
dsender.setMcchannel(Channel.GlobalChat);
|
|
||||||
else {
|
|
||||||
dsender.setMcchannel(channel);
|
|
||||||
if (channel instanceof ChatRoom)
|
|
||||||
((ChatRoom) channel).joinRoom(dsender);
|
|
||||||
}
|
|
||||||
dsender.sendMessage("You are now talking in: " + dsender.getMcchannel().DisplayName);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else { // We have arguments
|
|
||||||
cmd = dmessage.substring(0, index);
|
|
||||||
for (Channel channel : Channel.getChannels()) {
|
|
||||||
if (cmd.equalsIgnoreCase(channel.ID) || (channel.IDs != null && Arrays.stream(channel.IDs).anyMatch(cmd::equalsIgnoreCase))) {
|
|
||||||
val dp = DiscordPlayer.getUser(dsender.getUser().getStringID(), DiscordPlayer.class);
|
|
||||||
TBMCChatAPI.SendChatMessage(ChatMessage.builder(channel, dsender, dp, dmessage.substring(index + 1)).build());
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// TODO: Target selectors
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 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 static DiscordSenderBase getSender(IChannel channel, final IUser author) {
|
private static DiscordSenderBase getSender(IChannel channel, final IUser author) {
|
||||||
val key = author.getStringID();
|
//noinspection OptionalGetWithoutIsPresent
|
||||||
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(getSender(OnlineSenders, channel, author)), // Find first non-null
|
() -> 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(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.ofNullable(getSender(OnlineSenders, channel, author)), //
|
||||||
return Optional.of(addSender(UnconnectedSenders, author,
|
() -> Optional.of(addSender(UnconnectedSenders, author,
|
||||||
new DiscordSender(author, channel)));
|
new DiscordSender(author, channel)))).map(Supplier::get).filter(Optional::isPresent).map(Optional::get).findFirst().get();
|
||||||
}).map(Supplier::get).filter(Optional::isPresent).map(Optional::get).findFirst().get();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@FunctionalInterface
|
@FunctionalInterface
|
||||||
|
|
|
@ -151,7 +151,7 @@ public class MCListener implements Listener {
|
||||||
|
|
||||||
@EventHandler
|
@EventHandler
|
||||||
public void onChatSystemMessage(TBMCSystemChatEvent event) {
|
public void onChatSystemMessage(TBMCSystemChatEvent event) {
|
||||||
MCChatListener.forCustomAndAllMCChat(ch -> DiscordPlugin.sendMessageToChannel(ch, event.getMessage()), ChannelconBroadcast.BROADCAST, false);
|
MCChatListener.forAllowedMCChat(MCChatListener.send(event.getMessage()), event);
|
||||||
}
|
}
|
||||||
|
|
||||||
@EventHandler
|
@EventHandler
|
||||||
|
|
Loading…
Reference in a new issue