From 322c7c08e1bca2219c2d89cb6ffafc66e4828101 Mon Sep 17 00:00:00 2001 From: Ivan Pekov Date: Tue, 22 Sep 2020 10:17:38 +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. --- PATCHES.md | 1 + ...st-command-for-multiple-additions-re.patch | 198 ++++++++++++++++++ 2 files changed, 199 insertions(+) create mode 100644 patches/server/0050-Optimize-whitelist-command-for-multiple-additions-re.patch diff --git a/PATCHES.md b/PATCHES.md index 06448fc8..808a713d 100644 --- a/PATCHES.md +++ b/PATCHES.md @@ -81,6 +81,7 @@ # Patches | server | Optimize Villagers | Ivan Pekov | | | server | Optimize inventory API item handling | Phoenix616 | | | server | Optimize player loops around weather | MrIvanPlays | | +| server | Optimize whitelist command for multiple additions / removals | Ivan Pekov | | | server | Option for simpler Villagers | tr7zw | | | server | Option to toggle milk curing bad omen | William Blake Galbreath | | | server | Origami Server Config | Phoenix616 | | diff --git a/patches/server/0050-Optimize-whitelist-command-for-multiple-additions-re.patch b/patches/server/0050-Optimize-whitelist-command-for-multiple-additions-re.patch new file mode 100644 index 00000000..35808703 --- /dev/null +++ b/patches/server/0050-Optimize-whitelist-command-for-multiple-additions-re.patch @@ -0,0 +1,198 @@ +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/CommandWhitelist.java b/src/main/java/net/minecraft/server/CommandWhitelist.java +index 893d2c1c74ed28dcdb83b71762ccdcbfd50a8f9d..107091a4cae0e4eaba93f69ae91239ab891a90d9 100644 +--- a/src/main/java/net/minecraft/server/CommandWhitelist.java ++++ b/src/main/java/net/minecraft/server/CommandWhitelist.java +@@ -12,8 +12,8 @@ public class CommandWhitelist { + + private static final SimpleCommandExceptionType a = new SimpleCommandExceptionType(new ChatMessage("commands.whitelist.alreadyOn")); + private static final SimpleCommandExceptionType b = new SimpleCommandExceptionType(new ChatMessage("commands.whitelist.alreadyOff")); +- private static final SimpleCommandExceptionType c = new SimpleCommandExceptionType(new ChatMessage("commands.whitelist.add.failed")); +- private static final SimpleCommandExceptionType d = new SimpleCommandExceptionType(new ChatMessage("commands.whitelist.remove.failed")); ++ private static final SimpleCommandExceptionType c = new SimpleCommandExceptionType(new ChatMessage("commands.whitelist.add.failed")); private static final SimpleCommandExceptionType ADD_FAILED = c; // Yatopia - OBFHELPER ++ private static final SimpleCommandExceptionType d = new SimpleCommandExceptionType(new ChatMessage("commands.whitelist.remove.failed")); private static final SimpleCommandExceptionType REMOVE_FAILED = d; // Yatopia - OBFHELPER + + public static void a(com.mojang.brigadier.CommandDispatcher com_mojang_brigadier_commanddispatcher) { + com_mojang_brigadier_commanddispatcher.register((LiteralArgumentBuilder) ((LiteralArgumentBuilder) ((LiteralArgumentBuilder) ((LiteralArgumentBuilder) ((LiteralArgumentBuilder) ((LiteralArgumentBuilder) ((LiteralArgumentBuilder) CommandDispatcher.a("whitelist").requires((commandlistenerwrapper) -> { +@@ -27,11 +27,25 @@ public class CommandWhitelist { + }))).then(CommandDispatcher.a("add").then(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 (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(CommandDispatcher.a("remove").then(CommandDispatcher.a("targets", (ArgumentType) ArgumentProfile.a()).suggests((commandcontext, suggestionsbuilder) -> { +@@ -52,6 +66,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(); + +@@ -72,10 +88,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(); + +@@ -97,6 +130,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/EntityHuman.java b/src/main/java/net/minecraft/server/EntityHuman.java +index 6ae35c96978b6d16bc45d3eff435f35647fd1555..a64683d1d21c282b249e2dd07cbb497721f1052d 100644 +--- a/src/main/java/net/minecraft/server/EntityHuman.java ++++ b/src/main/java/net/minecraft/server/EntityHuman.java +@@ -77,6 +77,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() { +@@ -1892,6 +1893,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) { +diff --git a/src/main/java/net/minecraft/server/JsonList.java b/src/main/java/net/minecraft/server/JsonList.java +index 596815d70e69fd645bec5b6e8c1ebc7b2fa5345a..121504fc93781c78bc236e05ed91ee3541168c6e 100644 +--- a/src/main/java/net/minecraft/server/JsonList.java ++++ b/src/main/java/net/minecraft/server/JsonList.java +@@ -64,6 +64,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 +@@ -94,6 +108,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/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java +index 5274dcde8b06200357b11b77cc72ec415d4e47e4..8e4cdad1b76c24f4e459077c5a2b4b08e0a7134f 100644 +--- a/src/main/java/net/minecraft/server/MinecraftServer.java ++++ b/src/main/java/net/minecraft/server/MinecraftServer.java +@@ -1960,6 +1960,7 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant