Fixed channelcon echo

The senders are now stored per-channel
#56
This one took a bit to track down
This commit is contained in:
Norbi Peti 2018-07-22 13:11:24 +02:00
parent d22b6dec80
commit 4507cf38a9
No known key found for this signature in database
GPG key ID: DBA4C4549A927E56
6 changed files with 593 additions and 559 deletions

1
lombok.config Normal file
View file

@ -0,0 +1 @@
lombok.var.flagUsage = ALLOW

View file

@ -242,7 +242,8 @@ public class DiscordPlugin extends JavaPlugin implements IListener<ReadyEvent> {
public void onDisable() { public void onDisable() {
stop = true; stop = true;
for (val entry : MCChatListener.ConnectedSenders.entrySet()) for (val entry : MCChatListener.ConnectedSenders.entrySet())
MCListener.callEventExcludingSome(new PlayerQuitEvent(entry.getValue(), "")); for (val valueEntry : entry.getValue().entrySet())
MCListener.callEventExcludingSome(new PlayerQuitEvent(valueEntry.getValue(), ""));
MCChatListener.ConnectedSenders.clear(); MCChatListener.ConnectedSenders.clear();
getConfig().set("lastannouncementtime", lastannouncementtime); getConfig().set("lastannouncementtime", lastannouncementtime);
getConfig().set("lastseentime", lastseentime); getConfig().set("lastseentime", lastseentime);

View file

@ -12,6 +12,7 @@ import com.vdurmont.emoji.EmojiParser;
import io.netty.util.collection.LongObjectHashMap; import io.netty.util.collection.LongObjectHashMap;
import lombok.NonNull; import lombok.NonNull;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.experimental.var;
import lombok.val; import lombok.val;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
@ -225,11 +226,11 @@ public class MCChatListener implements Listener, IListener<MessageReceivedEvent>
val op = Bukkit.getOfflinePlayer(mcp.getUUID()); val op = Bukkit.getOfflinePlayer(mcp.getUUID());
if (start) { if (start) {
val sender = new DiscordConnectedPlayer(user, channel, mcp.getUUID(), op.getName()); val sender = new DiscordConnectedPlayer(user, channel, mcp.getUUID(), op.getName());
ConnectedSenders.put(user.getStringID(), sender); addSender(ConnectedSenders, user, 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
MCListener.callEventExcludingSome(new PlayerJoinEvent(sender, "")); MCListener.callEventExcludingSome(new PlayerJoinEvent(sender, ""));
} else { } else {
val sender = ConnectedSenders.remove(user.getStringID()); val sender = removeSender(ConnectedSenders, channel, user);
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
MCListener.callEventExcludingSome(new PlayerQuitEvent(sender, "")); MCListener.callEventExcludingSome(new PlayerQuitEvent(sender, ""));
} }
@ -241,6 +242,37 @@ public class MCChatListener implements Listener, IListener<MessageReceivedEvent>
: lastmsgPerUser.removeIf(lmd -> lmd.channel.getLongID() == channel.getLongID()); : 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 // ......................DiscordSender....DiscordConnectedPlayer.DiscordPlayerSender
// Offline public chat......x............................................ // Offline public chat......x............................................
// Online public chat.......x...........................................x // Online public chat.......x...........................................x
@ -286,12 +318,12 @@ public class MCChatListener implements Listener, IListener<MessageReceivedEvent>
/** /**
* May contain P&lt;DiscordID&gt; as key for public chat * May contain P&lt;DiscordID&gt; as key for public chat
*/ */
public static final HashMap<String, DiscordSender> UnconnectedSenders = new HashMap<>(); public static final HashMap<String, HashMap<IChannel, DiscordSender>> UnconnectedSenders = new HashMap<>();
public static final HashMap<String, DiscordConnectedPlayer> ConnectedSenders = new HashMap<>(); public static final HashMap<String, HashMap<IChannel, DiscordConnectedPlayer>> ConnectedSenders = new HashMap<>();
/** /**
* May contain P&lt;DiscordID&gt; as key for public chat * May contain P&lt;DiscordID&gt; as key for public chat
*/ */
public static final HashMap<String, DiscordPlayerSender> OnlineSenders = new HashMap<>(); public static final HashMap<String, HashMap<IChannel, DiscordPlayerSender>> OnlineSenders = new HashMap<>();
public static short ListC = 0; public static short ListC = 0;
public static void resetLastMessage() { public static void resetLastMessage() {
@ -606,14 +638,13 @@ 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 static DiscordSenderBase getSender(IChannel channel, final IUser author) { private static DiscordSenderBase getSender(IChannel channel, final IUser author) {
val key = (channel.isPrivate() ? "" : "P") + author.getStringID(); val key = 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(getSender(OnlineSenders, channel, author)), // Find first non-null
() -> Optional.ofNullable(ConnectedSenders.get(key)), // 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(UnconnectedSenders.get(key)), () -> { () -> Optional.ofNullable(getSender(OnlineSenders, channel, author)), () -> {
val dsender = new DiscordSender(author, channel); return Optional.of(addSender(UnconnectedSenders, author,
UnconnectedSenders.put(key, dsender); new DiscordSender(author, channel)));
return Optional.of(dsender);
}).map(Supplier::get).filter(Optional::isPresent).map(Optional::get).findFirst().get(); }).map(Supplier::get).filter(Optional::isPresent).map(Optional::get).findFirst().get();
} }

View file

@ -36,7 +36,7 @@ public class MCListener implements Listener {
public void onPlayerLogin(PlayerLoginEvent e) { public void onPlayerLogin(PlayerLoginEvent e) {
if (e.getResult() != Result.ALLOWED) if (e.getResult() != Result.ALLOWED)
return; return;
MCChatListener.ConnectedSenders.values().stream() 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() .filter(s -> s.getUniqueId().equals(e.getPlayer().getUniqueId())).findAny()
.ifPresent(dcp -> callEventExcludingSome(new PlayerQuitEvent(dcp, ""))); .ifPresent(dcp -> callEventExcludingSome(new PlayerQuitEvent(dcp, "")));
} }
@ -50,10 +50,10 @@ public class MCListener implements Listener {
DiscordPlayer dp = e.GetPlayer().getAs(DiscordPlayer.class); DiscordPlayer dp = e.GetPlayer().getAs(DiscordPlayer.class);
if (dp != null) { if (dp != null) {
val user = DiscordPlugin.dc.getUserByID(Long.parseLong(dp.getDiscordID())); val user = DiscordPlugin.dc.getUserByID(Long.parseLong(dp.getDiscordID()));
MCChatListener.OnlineSenders.put(dp.getDiscordID(), MCChatListener.addSender(MCChatListener.OnlineSenders, dp.getDiscordID(),
new DiscordPlayerSender(user, user.getOrCreatePMChannel(), p)); new DiscordPlayerSender(user, user.getOrCreatePMChannel(), p));
MCChatListener.OnlineSenders.put("P" + dp.getDiscordID(), MCChatListener.addSender(MCChatListener.OnlineSenders, dp.getDiscordID(),
new DiscordPlayerSender(user, DiscordPlugin.chatchannel, p)); new DiscordPlayerSender(user, DiscordPlugin.chatchannel, p)); //Stored per-channel
} }
if (ConnectCommand.WaitingToConnect.containsKey(e.GetPlayer().PlayerName().get())) { if (ConnectCommand.WaitingToConnect.containsKey(e.GetPlayer().PlayerName().get())) {
IUser user = DiscordPlugin.dc IUser user = DiscordPlugin.dc
@ -76,9 +76,9 @@ public class MCListener implements Listener {
if (e.getPlayer() instanceof DiscordConnectedPlayer) if (e.getPlayer() instanceof DiscordConnectedPlayer)
return; // Only care about real users return; // Only care about real users
MCChatListener.OnlineSenders.entrySet() MCChatListener.OnlineSenders.entrySet()
.removeIf(entry -> entry.getValue().getUniqueId().equals(e.getPlayer().getUniqueId())); .removeIf(entry -> entry.getValue().entrySet().stream().anyMatch(p -> p.getValue().getUniqueId().equals(e.getPlayer().getUniqueId())));
Bukkit.getScheduler().runTask(DiscordPlugin.plugin, Bukkit.getScheduler().runTask(DiscordPlugin.plugin,
() -> MCChatListener.ConnectedSenders.values().stream() () -> MCChatListener.ConnectedSenders.values().stream().flatMap(v -> v.values().stream())
.filter(s -> s.getUniqueId().equals(e.getPlayer().getUniqueId())).findAny() .filter(s -> s.getUniqueId().equals(e.getPlayer().getUniqueId())).findAny()
.ifPresent(dcp -> callEventExcludingSome(new PlayerJoinEvent(dcp, "")))); .ifPresent(dcp -> callEventExcludingSome(new PlayerJoinEvent(dcp, ""))));
Bukkit.getScheduler().runTaskLaterAsynchronously(DiscordPlugin.plugin, Bukkit.getScheduler().runTaskLaterAsynchronously(DiscordPlugin.plugin,

View file

@ -35,7 +35,7 @@ public class AcceptMCCommand extends DiscordMCCommandBase {
dp.save(); dp.save();
mcp.save(); mcp.save();
ConnectCommand.WaitingToConnect.remove(player.getName()); ConnectCommand.WaitingToConnect.remove(player.getName());
MCChatListener.UnconnectedSenders.remove(did); MCChatListener.UnconnectedSenders.remove(did); //Remove all unconnected, will be recreated where needed
player.sendMessage("§bAccounts connected."); player.sendMessage("§bAccounts connected.");
return true; return true;
} }