From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Ivan Pekov Date: Tue, 22 Sep 2020 10:09:08 +0300 Subject: [PATCH] Optimize whitelist command for multiple additions / removals Previously the whitelist command was adding players 1 by 1. This caused massive overload when you were adding multiple players due to the fact it saves every time a player was added. These changes aim to reduce that load whenever you are using the /whitelist command. diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java index 0ca3e2d7366ee295d369e87b7ce2edd84df68ab5..a317cd679a840d8e5c5a6f08ad760c53ebaf3edf 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java @@ -2117,6 +2117,7 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant commanddispatcher) { commanddispatcher.register((LiteralArgumentBuilder) ((LiteralArgumentBuilder) ((LiteralArgumentBuilder) ((LiteralArgumentBuilder) ((LiteralArgumentBuilder) ((LiteralArgumentBuilder) ((LiteralArgumentBuilder) net.minecraft.commands.CommandDispatcher.a("whitelist").requires((commandlistenerwrapper) -> { @@ -36,11 +36,25 @@ public class CommandWhitelist { }))).then(net.minecraft.commands.CommandDispatcher.a("add").then(net.minecraft.commands.CommandDispatcher.a("targets", (ArgumentType) ArgumentProfile.a()).suggests((commandcontext, suggestionsbuilder) -> { PlayerList playerlist = ((CommandListenerWrapper) commandcontext.getSource()).getServer().getPlayerList(); + // Yatopia start - optimize this + /* return ICompletionProvider.b(playerlist.getPlayers().stream().filter((entityplayer) -> { return !playerlist.getWhitelist().isWhitelisted(entityplayer.getProfile()); }).map((entityplayer) -> { return entityplayer.getProfile().getName(); }), suggestionsbuilder); + */ + for (net.minecraft.server.level.EntityPlayer player : playerlist.getPlayers()) { + if (!playerlist.getWhitelist().isWhitelisted(player.getProfile())) { + String remaining = suggestionsbuilder.getRemainingLowercase(); + String playerName = player.getName(); + if (ICompletionProvider.a(remaining, player.getNameLowercase())) { + suggestionsbuilder.suggest(playerName); + } + } + } + return suggestionsbuilder.buildFuture(); + // Yatopia end }).executes((commandcontext) -> { return a((CommandListenerWrapper) commandcontext.getSource(), ArgumentProfile.a(commandcontext, "targets")); })))).then(net.minecraft.commands.CommandDispatcher.a("remove").then(net.minecraft.commands.CommandDispatcher.a("targets", (ArgumentType) ArgumentProfile.a()).suggests((commandcontext, suggestionsbuilder) -> { @@ -61,6 +75,8 @@ public class CommandWhitelist { private static int a(CommandListenerWrapper commandlistenerwrapper, Collection collection) throws CommandSyntaxException { WhiteList whitelist = commandlistenerwrapper.getServer().getPlayerList().getWhitelist(); + // Yatopia start - rewrite this + /* int i = 0; Iterator iterator = collection.iterator(); @@ -81,10 +97,27 @@ public class CommandWhitelist { } else { return i; } + */ + java.util.List toAdd = new java.util.ArrayList<>(); + for (GameProfile profile : collection) { + if (!whitelist.isWhitelisted(profile)) { + toAdd.add(new WhiteListEntry(profile)); + commandlistenerwrapper.sendMessage(new ChatMessage("commands.whitelist.add.success", ChatComponentUtils.a(profile)), true); + } + } + if (toAdd.isEmpty()) { + throw CommandWhitelist.ADD_FAILED.create(); + } else { + whitelist.addAll(toAdd); + return toAdd.size(); + } + // Yatopia end } private static int b(CommandListenerWrapper commandlistenerwrapper, Collection collection) throws CommandSyntaxException { WhiteList whitelist = commandlistenerwrapper.getServer().getPlayerList().getWhitelist(); + // Yatopia start - rewrite this + /* int i = 0; Iterator iterator = collection.iterator(); @@ -106,6 +139,22 @@ public class CommandWhitelist { commandlistenerwrapper.getServer().a(commandlistenerwrapper); return i; } + */ + java.util.List> toRemove = new java.util.ArrayList<>(); + for (GameProfile profile : collection) { + if (whitelist.isWhitelisted(profile)) { + toRemove.add(new WhiteListEntry(profile)); + commandlistenerwrapper.sendMessage(new ChatMessage("commands.whitelist.remove.success", ChatComponentUtils.a(profile)), true); + } + } + if (toRemove.isEmpty()) { + throw CommandWhitelist.REMOVE_FAILED.create(); + } else { + whitelist.removeAll(toRemove); + commandlistenerwrapper.getServer().kickNotWhitelisted(commandlistenerwrapper); + return toRemove.size(); + } + // Yatopia end } private static int b(CommandListenerWrapper commandlistenerwrapper) throws CommandSyntaxException { diff --git a/src/main/java/net/minecraft/server/players/JsonList.java b/src/main/java/net/minecraft/server/players/JsonList.java index 96fbb1a3d216302aa937e07bf88fdb19c6ccc764..0521fa09488ef501cc5bcdf6c3134ac920a2e94a 100644 --- a/src/main/java/net/minecraft/server/players/JsonList.java +++ b/src/main/java/net/minecraft/server/players/JsonList.java @@ -66,6 +66,20 @@ public abstract class JsonList> { } + // Yatopia start + public void addAll(Iterable values) { + for (V value : values) { + d.put(getMappingKey(value.getKey()), value); + } + + try { + this.save(); + } catch (IOException io) { + JsonList.LOGGER.warn("Could not save the list after adding a user.", io); + } + } + // Yatopia end + @Nullable public V get(K k0) { // Paper start @@ -96,6 +110,20 @@ public abstract class JsonList> { this.remove(jsonlistentry.getKey()); } + // Yatopia start + public void removeAll(Iterable> values) { + for (JsonListEntry entry : values) { + this.d.remove(getMappingKey(entry.getKey())); + } + + try { + this.save(); + } catch (IOException io) { + JsonList.LOGGER.warn("Could not save the list after removing a user.", io); + } + } + // Yatopia end + public String[] getEntries() { return (String[]) this.d.keySet().toArray(new String[this.d.size()]); } diff --git a/src/main/java/net/minecraft/world/entity/player/EntityHuman.java b/src/main/java/net/minecraft/world/entity/player/EntityHuman.java index 89d6bfe81c9fb33e2ba51b9e215d79fac6245d16..4e1289be9302b010d3803783904eef07e604f3e8 100644 --- a/src/main/java/net/minecraft/world/entity/player/EntityHuman.java +++ b/src/main/java/net/minecraft/world/entity/player/EntityHuman.java @@ -176,6 +176,7 @@ public abstract class EntityHuman extends EntityLiving { // CraftBukkit start public boolean fauxSleeping; public int oldLevel = -1; + private String nameLowercase = null; // Yatopia @Override public CraftHumanEntity getBukkitEntity() { @@ -2028,6 +2029,15 @@ public abstract class EntityHuman extends EntityLiving { return this.getProfile().getName(); } + // Yatopia start + public String getNameLowercase() { + if (nameLowercase == null) { + nameLowercase = getProfile().getName().toLowerCase(java.util.Locale.ROOT); + } + return nameLowercase; + } + // Yatopia end + @Override public float b(EntityPose entitypose, EntitySize entitysize) { switch (entitypose) {