Merge pull request #918 from Zbob750/port/entity-list-command

Add command for listing entities in a world
This commit is contained in:
Zach 2017-10-15 19:07:03 -04:00 committed by GitHub
commit 5209f4b1fe
4 changed files with 223 additions and 39 deletions

View File

@ -1,4 +1,4 @@
From a954e3db87c50573a0e8397e3dd7a58023396295 Mon Sep 17 00:00:00 2001
From cb7d77b69a13ca1dfe6edd5e2eb97502481e66e4 Mon Sep 17 00:00:00 2001
From: Zach Brown <zach.brown@destroystokyo.com>
Date: Mon, 29 Feb 2016 21:02:09 -0600
Subject: [PATCH] Paper config files
@ -6,45 +6,74 @@ Subject: [PATCH] Paper config files
diff --git a/src/main/java/com/destroystokyo/paper/PaperCommand.java b/src/main/java/com/destroystokyo/paper/PaperCommand.java
new file mode 100644
index 000000000..5cdf4bbf4
index 00000000..ecd1c65a
--- /dev/null
+++ b/src/main/java/com/destroystokyo/paper/PaperCommand.java
@@ -0,0 +1,75 @@
@@ -0,0 +1,193 @@
+package com.destroystokyo.paper;
+
+import net.minecraft.server.MinecraftServer;
+import net.minecraft.server.WorldServer;
+import com.google.common.collect.Maps;
+import net.minecraft.server.*;
+import org.apache.commons.lang3.tuple.MutablePair;
+import org.apache.commons.lang3.tuple.Pair;
+import org.bukkit.Bukkit;
+import org.bukkit.ChatColor;
+import org.bukkit.Location;
+import org.bukkit.World;
+import org.bukkit.command.Command;
+import org.bukkit.command.CommandSender;
+import org.bukkit.craftbukkit.CraftServer;
+import org.bukkit.craftbukkit.CraftWorld;
+import org.bukkit.entity.Player;
+
+import java.io.File;
+import java.time.LocalDateTime;
+import java.time.format.DateTimeFormatter;
+import java.util.*;
+import java.util.stream.Collectors;
+
+public class PaperCommand extends Command {
+
+ public PaperCommand(String name) {
+ super(name);
+ this.description = "Paper related commands";
+ this.usageMessage = "/paper [heap | reload | version]";
+ this.usageMessage = "/paper [heap | entity | reload | version]";
+ this.setPermission("bukkit.command.paper");
+ }
+
+ @Override
+ public List<String> tabComplete(CommandSender sender, String alias, String[] args, Location location) throws IllegalArgumentException {
+ if (args.length <= 1)
+ return CommandAbstract.getListMatchingLast(args, "heap", "entity", "reload", "version");
+
+ switch (args[0].toLowerCase(Locale.ENGLISH))
+ {
+ case "entity":
+ if (args.length == 2)
+ return CommandAbstract.getListMatchingLast(args, "help", "list");
+ if (args.length == 3)
+ return CommandAbstract.getListMatchingLast(args, EntityTypes.getEntityNameList().stream().map(MinecraftKey::toString).sorted().toArray(String[]::new));
+ break;
+ }
+ return Collections.emptyList();
+ }
+
+ @Override
+ public boolean execute(CommandSender sender, String commandLabel, String[] args) {
+ if (!testPermission(sender)) return true;
+
+ if (args.length != 1) {
+ if (args.length == 0) {
+ sender.sendMessage(ChatColor.RED + "Usage: " + usageMessage);
+ return false;
+ }
+
+ switch (args[0]) {
+ switch (args[0].toLowerCase(Locale.ENGLISH)) {
+ case "heap":
+ dumpHeap(sender);
+ break;
+ case "entity":
+ listEntities(sender, args);
+ break;
+ case "reload":
+ doReload(sender);
+ break;
@ -60,6 +89,95 @@ index 000000000..5cdf4bbf4
+ return true;
+ }
+
+ /*
+ * Ported from MinecraftForge - author: LexManos <LexManos@gmail.com> - License: LGPLv2.1
+ */
+ private void listEntities(CommandSender sender, String[] args) {
+ if (args.length < 2 || args[1].toLowerCase(Locale.ENGLISH).equals("help")) {
+ sender.sendMessage(ChatColor.RED + "Use /paper entity [list] help for more information on a specific command.");
+ return;
+ }
+
+ switch (args[1].toLowerCase(Locale.ENGLISH)) {
+ case "list":
+ String filter = "*";
+ if (args.length > 2) {
+ if (args[2].toLowerCase(Locale.ENGLISH).equals("help")) {
+ sender.sendMessage(ChatColor.RED + "Use /paper entity list [filter] [worldName] to get entity info that matches the optional filter.");
+ return;
+ }
+ filter = args[2];
+ }
+ final String cleanfilter = filter.replace("?", ".?").replace("*", ".*?");
+ Set<MinecraftKey> names = EntityTypes.getEntityNameList().stream()
+ .filter(n -> n.toString().matches(cleanfilter))
+ .collect(Collectors.toSet());
+
+ if (names.isEmpty()) {
+ sender.sendMessage(ChatColor.RED + "Invalid filter, does not match any entities. Use /paper entity list for a proper list");
+ return;
+ }
+
+ String worldName;
+ if (args.length > 3) {
+ worldName = args[3];
+ } else if (sender instanceof Player) {
+ worldName = ((Player) sender).getWorld().getName();
+ } else {
+ sender.sendMessage(ChatColor.RED + "Please specify the name of a world");
+ sender.sendMessage(ChatColor.RED + "To do so without a filter, specify '*' as the filter");
+ return;
+ }
+
+ Map<MinecraftKey, MutablePair<Integer, Map<ChunkCoordIntPair, Integer>>> list = Maps.newHashMap();
+ World bukkitWorld = Bukkit.getWorld(worldName);
+ if (bukkitWorld == null) {
+ sender.sendMessage(ChatColor.RED + "Could not load world for " + worldName + ". Please select a valid world.");
+ return;
+ }
+ WorldServer world = ((CraftWorld) Bukkit.getWorld(worldName)).getHandle();
+
+ List<Entity> entities = world.entityList;
+ entities.forEach(e -> {
+ MinecraftKey key = EntityTypes.getKey(e);
+
+ MutablePair<Integer, Map<ChunkCoordIntPair, Integer>> info = list.computeIfAbsent(key, k -> MutablePair.of(0, Maps.newHashMap()));
+ ChunkCoordIntPair chunk = new ChunkCoordIntPair(e.getChunkX(), e.getChunkZ());
+ info.left++;
+ info.right.put(chunk, info.right.getOrDefault(chunk, 0) + 1);
+ });
+
+ if (names.size() == 1) {
+ MinecraftKey name = names.iterator().next();
+ Pair<Integer, Map<ChunkCoordIntPair, Integer>> info = list.get(name);
+ if (info == null) {
+ sender.sendMessage(ChatColor.RED + "No entities found.");
+ return;
+ }
+ sender.sendMessage("Entity: " + name + " Total: " + info.getLeft());
+ info.getRight().entrySet().stream()
+ .sorted((a, b) -> !a.getValue().equals(b.getValue()) ? b.getValue() - a.getValue() : a.getKey().toString().compareTo(b.getKey().toString()))
+ .limit(10).forEach(e -> sender.sendMessage(" " + e.getValue() + ": " + e.getKey().x + ", " + e.getKey().z));
+ } else {
+ List<Pair<MinecraftKey, Integer>> info = list.entrySet().stream()
+ .filter(e -> names.contains(e.getKey()))
+ .map(e -> Pair.of(e.getKey(), e.getValue().left))
+ .sorted((a, b) -> !a.getRight().equals(b.getRight()) ? b.getRight() - a.getRight() : a.getKey().toString().compareTo(b.getKey().toString()))
+ .collect(Collectors.toList());
+
+ if (info == null || info.size() == 0) {
+ sender.sendMessage(ChatColor.RED + "No entities found.");
+ return;
+ }
+
+ int count = info.stream().mapToInt(Pair::getRight).sum();
+ sender.sendMessage("Total: " + count);
+ info.forEach(e -> sender.sendMessage(" " + e.getValue() + ": " + e.getKey()));
+ }
+ break;
+ }
+ }
+
+ private void dumpHeap(CommandSender sender) {
+ File file = new File(new File(new File("."), "dumps"),
+ "heap-dump-" + DateTimeFormatter.ofPattern("yyyy-MM-dd_HH.mm.ss").format(LocalDateTime.now()) + "-server.hprof");
@ -87,7 +205,7 @@ index 000000000..5cdf4bbf4
+}
diff --git a/src/main/java/com/destroystokyo/paper/PaperConfig.java b/src/main/java/com/destroystokyo/paper/PaperConfig.java
new file mode 100644
index 000000000..3d8ee9ed3
index 00000000..3d8ee9ed
--- /dev/null
+++ b/src/main/java/com/destroystokyo/paper/PaperConfig.java
@@ -0,0 +1,173 @@
@ -266,7 +384,7 @@ index 000000000..3d8ee9ed3
+}
diff --git a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
new file mode 100644
index 000000000..621bf7051
index 00000000..621bf705
--- /dev/null
+++ b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
@@ -0,0 +1,66 @@
@ -336,8 +454,20 @@ index 000000000..621bf7051
+ return config.getString("world-settings." + worldName + "." + path, config.getString("world-settings.default." + path));
+ }
+}
diff --git a/src/main/java/net/minecraft/server/CommandAbstract.java b/src/main/java/net/minecraft/server/CommandAbstract.java
index 76501e29..76bf04f5 100644
--- a/src/main/java/net/minecraft/server/CommandAbstract.java
+++ b/src/main/java/net/minecraft/server/CommandAbstract.java
@@ -634,6 +634,7 @@ public abstract class CommandAbstract implements ICommand {
return s1.regionMatches(true, 0, s, 0, s.length());
}
+ public static List<String> getListMatchingLast(String[] args, String... matches) { return a(args, matches); } // Paper - OBFHELPER
public static List<String> a(String[] astring, String... astring1) {
return a(astring, (Collection) Arrays.asList(astring1));
}
diff --git a/src/main/java/net/minecraft/server/DedicatedServer.java b/src/main/java/net/minecraft/server/DedicatedServer.java
index 46b264227..6f63a5a1d 100644
index 8c5361d6..e1cb96a8 100644
--- a/src/main/java/net/minecraft/server/DedicatedServer.java
+++ b/src/main/java/net/minecraft/server/DedicatedServer.java
@@ -184,6 +184,10 @@ public class DedicatedServer extends MinecraftServer implements IMinecraftServer
@ -351,8 +481,45 @@ index 46b264227..6f63a5a1d 100644
DedicatedServer.LOGGER.info("Generating keypair");
this.a(MinecraftEncryption.b());
diff --git a/src/main/java/net/minecraft/server/Entity.java b/src/main/java/net/minecraft/server/Entity.java
index c2da96ea..8181ab2f 100644
--- a/src/main/java/net/minecraft/server/Entity.java
+++ b/src/main/java/net/minecraft/server/Entity.java
@@ -122,9 +122,9 @@ public abstract class Entity implements ICommandListener {
private static final DataWatcherObject<Boolean> aD = DataWatcher.a(Entity.class, DataWatcherRegistry.h);
private static final DataWatcherObject<Boolean> aE = DataWatcher.a(Entity.class, DataWatcherRegistry.h);
public boolean aa;
- public int ab;
- public int ac;
- public int ad;
+ public int ab; public int getChunkX() { return ab; } // Paper - OBFHELPER
+ public int ac; public int getChunkY() { return ac; } // Paper - OBFHELPER
+ public int ad; public int getChunkZ() { return ad; } // Paper - OBFHELPER
public boolean ah;
public boolean impulse;
public int portalCooldown;
diff --git a/src/main/java/net/minecraft/server/EntityTypes.java b/src/main/java/net/minecraft/server/EntityTypes.java
index eb6a955e..77b81a57 100644
--- a/src/main/java/net/minecraft/server/EntityTypes.java
+++ b/src/main/java/net/minecraft/server/EntityTypes.java
@@ -21,6 +21,7 @@ public class EntityTypes {
public static final Set<MinecraftKey> d = Sets.newHashSet();
private static final List<String> g = Lists.newArrayList();
+ @Nullable public static MinecraftKey getKey(Entity entity) { return a(entity); } // Paper - OBFHELPER
@Nullable
public static MinecraftKey a(Entity entity) {
return getName(entity.getClass());
@@ -78,6 +79,7 @@ public class EntityTypes {
return entity;
}
+ public static Set<MinecraftKey> getEntityNameList() { return a(); } // Paper - OBFHELPER
public static Set<MinecraftKey> a() {
return EntityTypes.d;
}
diff --git a/src/main/java/net/minecraft/server/World.java b/src/main/java/net/minecraft/server/World.java
index e1833f376..1096c6c66 100644
index f62e7d9e..dbfed7c6 100644
--- a/src/main/java/net/minecraft/server/World.java
+++ b/src/main/java/net/minecraft/server/World.java
@@ -129,6 +129,8 @@ public abstract class World implements IBlockAccess {
@ -373,7 +540,7 @@ index e1833f376..1096c6c66 100644
this.world = new CraftWorld((WorldServer) this, gen, env);
this.ticksPerAnimalSpawns = this.getServer().getTicksPerAnimalSpawns(); // CraftBukkit
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
index 814be6ee5..37e3c14fd 100644
index 814be6ee..37e3c14f 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
@@ -702,6 +702,7 @@ public final class CraftServer implements Server {
@ -428,7 +595,7 @@ index 814be6ee5..37e3c14fd 100644
+ // Paper end
}
diff --git a/src/main/java/org/bukkit/craftbukkit/Main.java b/src/main/java/org/bukkit/craftbukkit/Main.java
index a151451d5..0c5862a3f 100644
index a151451d..0c5862a3 100644
--- a/src/main/java/org/bukkit/craftbukkit/Main.java
+++ b/src/main/java/org/bukkit/craftbukkit/Main.java
@@ -126,6 +126,14 @@ public class Main {
@ -447,7 +614,7 @@ index a151451d5..0c5862a3f 100644
};
diff --git a/src/main/java/org/spigotmc/SpigotWorldConfig.java b/src/main/java/org/spigotmc/SpigotWorldConfig.java
index 01e73eb89..0b66f5e35 100644
index 01e73eb8..0b66f5e3 100644
--- a/src/main/java/org/spigotmc/SpigotWorldConfig.java
+++ b/src/main/java/org/spigotmc/SpigotWorldConfig.java
@@ -39,31 +39,31 @@ public class SpigotWorldConfig
@ -488,5 +655,5 @@ index 01e73eb89..0b66f5e35 100644
config.addDefault( "world-settings.default." + path, def );
return config.getString( "world-settings." + worldName + "." + path, config.getString( "world-settings.default." + path ) );
--
2.14.1.windows.1
2.14.2.windows.2

View File

@ -1,11 +1,11 @@
From f44918d9a3c234a2be57605bd9752b9908e12784 Mon Sep 17 00:00:00 2001
From b9b1f576225aa45f5638304a76b5764f5c4c85f5 Mon Sep 17 00:00:00 2001
From: Aikar <aikar@aikar.co>
Date: Wed, 30 Mar 2016 19:36:20 -0400
Subject: [PATCH] MC Dev fixes
diff --git a/src/main/java/net/minecraft/server/BaseBlockPosition.java b/src/main/java/net/minecraft/server/BaseBlockPosition.java
index d4f412742..d55e180d7 100644
index d4f41274..d55e180d 100644
--- a/src/main/java/net/minecraft/server/BaseBlockPosition.java
+++ b/src/main/java/net/minecraft/server/BaseBlockPosition.java
@@ -89,7 +89,7 @@ public class BaseBlockPosition implements Comparable<BaseBlockPosition> {
@ -18,7 +18,7 @@ index d4f412742..d55e180d7 100644
}
}
diff --git a/src/main/java/net/minecraft/server/BiomeBase.java b/src/main/java/net/minecraft/server/BiomeBase.java
index 62a9c92f8..1b7599769 100644
index 62a9c92f..1b759976 100644
--- a/src/main/java/net/minecraft/server/BiomeBase.java
+++ b/src/main/java/net/minecraft/server/BiomeBase.java
@@ -46,7 +46,7 @@ public abstract class BiomeBase {
@ -31,7 +31,7 @@ index 62a9c92f8..1b7599769 100644
@Nullable
diff --git a/src/main/java/net/minecraft/server/BlockStateEnum.java b/src/main/java/net/minecraft/server/BlockStateEnum.java
index 71524f2cd..288c52c55 100644
index 71524f2c..288c52c5 100644
--- a/src/main/java/net/minecraft/server/BlockStateEnum.java
+++ b/src/main/java/net/minecraft/server/BlockStateEnum.java
@@ -29,7 +29,7 @@ public class BlockStateEnum<T extends Enum<T> & INamable> extends BlockState<T>
@ -44,7 +44,7 @@ index 71524f2cd..288c52c55 100644
}
diff --git a/src/main/java/net/minecraft/server/CommandAbstract.java b/src/main/java/net/minecraft/server/CommandAbstract.java
index 76501e299..67cadecbb 100644
index 76bf04f5..a99d0f87 100644
--- a/src/main/java/net/minecraft/server/CommandAbstract.java
+++ b/src/main/java/net/minecraft/server/CommandAbstract.java
@@ -231,7 +231,7 @@ public abstract class CommandAbstract implements ICommand {
@ -74,7 +74,7 @@ index 76501e299..67cadecbb 100644
}
public static String a(Object[] aobject) {
@@ -692,7 +692,7 @@ public abstract class CommandAbstract implements ICommand {
@@ -693,7 +693,7 @@ public abstract class CommandAbstract implements ICommand {
return this.getCommand().compareTo(icommand.getCommand());
}
@ -83,8 +83,30 @@ index 76501e299..67cadecbb 100644
return this.a((ICommand) object);
}
diff --git a/src/main/java/net/minecraft/server/EntityTypes.java b/src/main/java/net/minecraft/server/EntityTypes.java
index 77b81a57..ba461ad4 100644
--- a/src/main/java/net/minecraft/server/EntityTypes.java
+++ b/src/main/java/net/minecraft/server/EntityTypes.java
@@ -34,7 +34,7 @@ public class EntityTypes {
@Nullable
public static String b(Entity entity) {
- int i = EntityTypes.b.a((Object) entity.getClass());
+ int i = EntityTypes.b.a(entity.getClass()); // Paper - Decompile fix
return i == -1 ? null : (String) EntityTypes.g.get(i);
}
@@ -254,7 +254,7 @@ public class EntityTypes {
EntityTypes.d.add(minecraftkey);
while (EntityTypes.g.size() <= i) {
- EntityTypes.g.add((Object) null);
+ EntityTypes.g.add(null); // Paper - Decompile fix
}
EntityTypes.g.set(i, s1);
diff --git a/src/main/java/net/minecraft/server/RegistryBlockID.java b/src/main/java/net/minecraft/server/RegistryBlockID.java
index 58f47d0de..8860a0129 100644
index 58f47d0d..8860a012 100644
--- a/src/main/java/net/minecraft/server/RegistryBlockID.java
+++ b/src/main/java/net/minecraft/server/RegistryBlockID.java
@@ -8,7 +8,7 @@ import java.util.Iterator;
@ -106,7 +128,7 @@ index 58f47d0de..8860a0129 100644
this.b.set(i, t0);
diff --git a/src/test/java/org/bukkit/craftbukkit/inventory/ItemFactoryTest.java b/src/test/java/org/bukkit/craftbukkit/inventory/ItemFactoryTest.java
index f5bcbdbe1..3190cadfc 100644
index f5bcbdbe..3190cadf 100644
--- a/src/test/java/org/bukkit/craftbukkit/inventory/ItemFactoryTest.java
+++ b/src/test/java/org/bukkit/craftbukkit/inventory/ItemFactoryTest.java
@@ -20,7 +20,7 @@ public class ItemFactoryTest extends AbstractTestingBase {
@ -119,5 +141,5 @@ index f5bcbdbe1..3190cadfc 100644
for (ZipEntry clazzEntry; (clazzEntry = nmsZipStream.getNextEntry()) != null; ) {
final String entryName = clazzEntry.getName();
--
2.14.2
2.14.2.windows.2

View File

@ -1,30 +1,24 @@
From b3a51f2ce44e39c2fb185c5eb0020b9a767f5a79 Mon Sep 17 00:00:00 2001
From 99c9149f9e4fd8ef73bd16d37af7c41a70ff316b Mon Sep 17 00:00:00 2001
From: Joseph Hirschfeld <joe@ibj.io>
Date: Thu, 3 Mar 2016 02:39:54 -0600
Subject: [PATCH] Change implementation of (tile)entity removal list
diff --git a/src/main/java/net/minecraft/server/Entity.java b/src/main/java/net/minecraft/server/Entity.java
index 3486451b3..26ecf2c70 100644
index ba779727..5ef4978d 100644
--- a/src/main/java/net/minecraft/server/Entity.java
+++ b/src/main/java/net/minecraft/server/Entity.java
@@ -122,10 +122,10 @@ public abstract class Entity implements ICommandListener {
@@ -122,7 +122,7 @@ public abstract class Entity implements ICommandListener {
private static final DataWatcherObject<Boolean> aC = DataWatcher.a(Entity.class, DataWatcherRegistry.h);
private static final DataWatcherObject<Boolean> aD = DataWatcher.a(Entity.class, DataWatcherRegistry.h);
private static final DataWatcherObject<Boolean> aE = DataWatcher.a(Entity.class, DataWatcherRegistry.h);
- public boolean aa;
- public int ab;
- public int ac;
- public int ad;
+ public boolean aa; public boolean isAddedToChunk() { return aa; } // Paper - OBFHELPER
+ public int ab; public int getChunkX() { return ab; } // Paper - OBFHELPER
+ public int ac; public int getChunkY() { return ac; } // Paper - OBFHELPER
+ public int ad; public int getChunkZ() { return ad; } // Paper - OBFHELPER
public boolean ah;
public boolean impulse;
public int portalCooldown;
public int ab; public int getChunkX() { return ab; } // Paper - OBFHELPER
public int ac; public int getChunkY() { return ac; } // Paper - OBFHELPER
public int ad; public int getChunkZ() { return ad; } // Paper - OBFHELPER
diff --git a/src/main/java/net/minecraft/server/World.java b/src/main/java/net/minecraft/server/World.java
index df8b330a5..1bb2a1a56 100644
index 41a0f5a6..6d801019 100644
--- a/src/main/java/net/minecraft/server/World.java
+++ b/src/main/java/net/minecraft/server/World.java
@@ -31,6 +31,11 @@ import org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason;
@ -84,5 +78,5 @@ index df8b330a5..1bb2a1a56 100644
this.f.clear();
this.l();
--
2.13.3.windows.1
2.14.2.windows.2

View File

@ -65,6 +65,7 @@ import DefinedStructure
import EntityLlama
import EULA
import EntitySquid
import EntityTypes
import EntityWaterAnimal
import FileIOThread
import IHopper