Fix some mcchat and a reset issue

Using ConcurrentHashMaps (#62)
Add custom /list to hide vanished players (#120)
Fixed /discord reset for non-Paper servers (#103)
This commit is contained in:
Norbi Peti 2020-10-08 00:02:49 +02:00
parent 56d13ebf9f
commit 891be91d69
No known key found for this signature in database
GPG key ID: DBA4C4549A927E56
6 changed files with 98 additions and 70 deletions

View file

@ -100,7 +100,7 @@ public class FunModule extends Component<DiscordPlugin> implements Listener {
ListC = 0;
lastlist = 0;
}
if (msglowercased.equals("list") && Bukkit.getOnlinePlayers().size() == lastlistp && ListC++ > 2) // Lowered already
if (msglowercased.equals("/list") && Bukkit.getOnlinePlayers().size() == lastlistp && ListC++ > 2) // Lowered already
{
DPUtils.reply(message, Mono.empty(), "stop it. You know the answer.").subscribe();
lastlist = 0;

View file

@ -20,9 +20,10 @@ public class MCChatCustom {
/**
* Used for town or nation chats or anything else
*/
static ArrayList<CustomLMD> lastmsgCustom = new ArrayList<>();
static final ArrayList<CustomLMD> lastmsgCustom = new ArrayList<>();
public static void addCustomChat(MessageChannel channel, String groupid, Channel mcchannel, User user, DiscordConnectedPlayer dcp, int toggles, Set<TBMCSystemChatEvent.BroadcastTarget> brtoggles) {
synchronized (lastmsgCustom) {
if (mcchannel instanceof ChatRoom) {
((ChatRoom) mcchannel).joinRoom(dcp);
if (groupid == null) groupid = mcchannel.getGroupID(dcp);
@ -30,6 +31,7 @@ public class MCChatCustom {
val lmd = new CustomLMD(channel, user, groupid, mcchannel, dcp, toggles, brtoggles);
lastmsgCustom.add(lmd);
}
}
public static boolean hasCustomChat(Snowflake channel) {
return lastmsgCustom.stream().anyMatch(lmd -> lmd.channel.getId().asLong() == channel.asLong());
@ -41,6 +43,7 @@ public class MCChatCustom {
}
public static boolean removeCustomChat(Snowflake channel) {
synchronized (lastmsgCustom) {
MCChatUtils.lastmsgfromd.remove(channel.asLong());
return lastmsgCustom.removeIf(lmd -> {
if (lmd.channel.getId().asLong() != channel.asLong())
@ -50,6 +53,7 @@ public class MCChatCustom {
return true;
});
}
}
public static List<CustomLMD> getCustomChats() {
return Collections.unmodifiableList(lastmsgCustom);

View file

@ -131,6 +131,7 @@ public class MCChatListener implements Listener {
doit.accept(data);
}
synchronized (MCChatCustom.lastmsgCustom) {
val iterator = MCChatCustom.lastmsgCustom.iterator();
while (iterator.hasNext()) {
val lmd = iterator.next();
@ -145,6 +146,7 @@ public class MCChatListener implements Listener {
}
}
}
}
} catch (InterruptedException ex) { //Stop if interrupted anywhere
sendtask.cancel();
sendtask = null;
@ -217,7 +219,7 @@ public class MCChatListener implements Listener {
}
private BukkitTask rectask;
private LinkedBlockingQueue<MessageCreateEvent> recevents = new LinkedBlockingQueue<>();
private final LinkedBlockingQueue<MessageCreateEvent> recevents = new LinkedBlockingQueue<>();
private Runnable recrun;
private static Thread recthread;
@ -368,6 +370,7 @@ public class MCChatListener implements Listener {
return true;
}
module.log(dsender.getName() + " ran from DC: /" + cmd);
if (runCustomCommand(dsender, cmdlowercased)) return true;
val channel = clmd == null ? user.channel().get() : clmd.mcchannel;
val ev = new TBMCCommandPreprocessEvent(dsender, channel, dmessage, clmd == null ? dsender : clmd.dcp);
Bukkit.getScheduler().runTask(DiscordPlugin.plugin, //Commands need to be run sync
@ -396,6 +399,17 @@ public class MCChatListener implements Listener {
return true;
}
private boolean runCustomCommand(DiscordSenderBase dsender, String cmdlowercased) {
if (cmdlowercased.startsWith("list")) {
var players = Bukkit.getOnlinePlayers();
dsender.sendMessage("There are " + players.size() + " out of " + Bukkit.getMaxPlayers() + " players online.");
dsender.sendMessage("Players: " + players.stream().filter(MCChatUtils::checkEssentials)
.map(Player::getDisplayName).collect(Collectors.joining(", ")));
return true;
}
return false;
}
@FunctionalInterface
private interface InterruptibleConsumer<T> {
void accept(T value) throws TimeoutException, InterruptedException;

View file

@ -20,6 +20,7 @@ public class MCChatPrivate {
static ArrayList<MCChatUtils.LastMsgData> lastmsgPerUser = new ArrayList<>();
public static boolean privateMCChat(MessageChannel channel, boolean start, User user, DiscordPlayer dp) {
synchronized (MCChatUtils.ConnectedSenders) {
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());
@ -47,6 +48,7 @@ public class MCChatPrivate {
? lastmsgPerUser.add(new MCChatUtils.LastMsgData(channel, user)) // Doesn't support group DMs
: lastmsgPerUser.removeIf(lmd -> lmd.channel.getId().asLong() == channel.getId().asLong());
}
}
public static boolean isMinecraftChatEnabled(DiscordPlayer dp) {
return isMinecraftChatEnabled(dp.getDiscordID());
@ -59,11 +61,13 @@ public class MCChatPrivate {
}
public static void logoutAll() {
synchronized (MCChatUtils.ConnectedSenders) {
for (val entry : MCChatUtils.ConnectedSenders.entrySet())
for (val valueEntry : entry.getValue().entrySet())
if (MCChatUtils.getSender(MCChatUtils.OnlineSenders, valueEntry.getKey(), valueEntry.getValue().getUser()) == null) //If the player is online then the fake player was already logged out
MCChatUtils.callLogoutEvent(valueEntry.getValue(), false); //This is sync
MCChatUtils.ConnectedSenders.clear();
}
}
}

View file

@ -34,6 +34,7 @@ import reactor.core.publisher.Mono;
import javax.annotation.Nullable;
import java.net.InetAddress;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Consumer;
import java.util.function.Supplier;
@ -45,13 +46,13 @@ public class MCChatUtils {
/**
* May contain P&lt;DiscordID&gt; as key for public chat
*/
public static final HashMap<String, HashMap<Snowflake, DiscordSender>> UnconnectedSenders = new HashMap<>();
public static final HashMap<String, HashMap<Snowflake, DiscordConnectedPlayer>> ConnectedSenders = new HashMap<>();
public static final ConcurrentHashMap<String, ConcurrentHashMap<Snowflake, DiscordSender>> UnconnectedSenders = new ConcurrentHashMap<>();
public static final ConcurrentHashMap<String, ConcurrentHashMap<Snowflake, DiscordConnectedPlayer>> ConnectedSenders = new ConcurrentHashMap<>();
/**
* May contain P&lt;DiscordID&gt; as key for public chat
*/
public static final HashMap<String, HashMap<Snowflake, DiscordPlayerSender>> OnlineSenders = new HashMap<>();
public static final HashMap<UUID, DiscordConnectedPlayer> LoggedInPlayers = new HashMap<>();
public static final ConcurrentHashMap<String, ConcurrentHashMap<Snowflake, DiscordPlayerSender>> OnlineSenders = new ConcurrentHashMap<>();
public static final ConcurrentHashMap<UUID, DiscordConnectedPlayer> LoggedInPlayers = new ConcurrentHashMap<>();
static @Nullable LastMsgData lastmsgdata;
static LongObjectHashMap<Message> lastmsgfromd = new LongObjectHashMap<>(); // Last message sent by a Discord user, used for clearing checkmarks
private static MinecraftChatModule module;
@ -104,28 +105,28 @@ public class MCChatUtils {
((TextChannel) lmd.channel).edit(tce -> tce.setTopic(String.join("\n----\n", s)).setReason("Player list update")).subscribe(); //Don't wait
}
private static boolean checkEssentials(Player p) {
static boolean checkEssentials(Player p) {
var ess = MainPlugin.ess;
if (ess == null) return true;
return !ess.getUser(p).isHidden();
}
public static <T extends DiscordSenderBase> T addSender(HashMap<String, HashMap<Snowflake, T>> senders,
public static <T extends DiscordSenderBase> T addSender(ConcurrentHashMap<String, ConcurrentHashMap<Snowflake, T>> senders,
User user, T sender) {
return addSender(senders, user.getId().asString(), sender);
}
public static <T extends DiscordSenderBase> T addSender(HashMap<String, HashMap<Snowflake, T>> senders,
public static <T extends DiscordSenderBase> T addSender(ConcurrentHashMap<String, ConcurrentHashMap<Snowflake, T>> senders,
String did, T sender) {
var map = senders.get(did);
if (map == null)
map = new HashMap<>();
map = new ConcurrentHashMap<>();
map.put(sender.getChannel().getId(), sender);
senders.put(did, map);
return sender;
}
public static <T extends DiscordSenderBase> T getSender(HashMap<String, HashMap<Snowflake, T>> senders,
public static <T extends DiscordSenderBase> T getSender(ConcurrentHashMap<String, ConcurrentHashMap<Snowflake, T>> senders,
Snowflake channel, User user) {
var map = senders.get(user.getId().asString());
if (map != null)
@ -133,7 +134,7 @@ public class MCChatUtils {
return null;
}
public static <T extends DiscordSenderBase> T removeSender(HashMap<String, HashMap<Snowflake, T>> senders,
public static <T extends DiscordSenderBase> T removeSender(ConcurrentHashMap<String, ConcurrentHashMap<Snowflake, T>> senders,
Snowflake channel, User user) {
var map = senders.get(user.getId().asString());
if (map != null)

View file

@ -74,7 +74,7 @@ public class DiscordMCCommand extends ICommand2MC {
"This command disables and then enables the plugin." //
})
public void reset(CommandSender sender) {
Bukkit.getScheduler().runTaskAsynchronously(DiscordPlugin.plugin, () -> {
Runnable task = () -> {
if (!DiscordPlugin.plugin.tryReloadConfig()) {
sender.sendMessage("§cFailed to reload config so not resetting. Check the console.");
return;
@ -87,7 +87,12 @@ public class DiscordMCCommand extends ICommand2MC {
Bukkit.getPluginManager().enablePlugin(DiscordPlugin.plugin);
if (!(sender instanceof DiscordSenderBase)) //Sending to Discord errors
sender.sendMessage("§bReset finished!");
});
};
if (!Bukkit.getName().equals("Paper")) {
getPlugin().getLogger().warning("Async plugin events are not supported by the server, running on main thread");
Bukkit.getScheduler().runTask(DiscordPlugin.plugin, task);
} else
Bukkit.getScheduler().runTaskAsynchronously(DiscordPlugin.plugin, task);
}
@Command2.Subcommand(helpText = {