Add new /forge entity list command for displaying a list of all entities in world.
As well as tracking down chunks with large amounts of entities.
This commit is contained in:
parent
21e4803947
commit
303a775fc3
|
@ -572,7 +572,7 @@ public class GameData
|
|||
RegistryEvent.MissingMappings<?> event = reg.getMissingEvent(name, m.getValue());
|
||||
MinecraftForge.EVENT_BUS.post(event);
|
||||
|
||||
List<MissingMappings.Mapping<?>> lst = event.getAllMappings().stream().filter(e -> e.getAction() == MissingMappings.Action.DEFAULT).collect(Collectors.toList());
|
||||
List<MissingMappings.Mapping<?>> lst = event.getAllMappings().stream().filter(e -> e.getAction() == MissingMappings.Action.DEFAULT).sorted((a, b) -> a.toString().compareTo(b.toString())).collect(Collectors.toList());
|
||||
if (!lst.isEmpty())
|
||||
{
|
||||
FMLLog.log.error("Unidentified mapping from registry {}", name);
|
||||
|
|
|
@ -23,16 +23,30 @@ import java.text.DecimalFormat;
|
|||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import org.apache.commons.lang3.tuple.MutablePair;
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
|
||||
import com.google.common.collect.Maps;
|
||||
|
||||
import net.minecraft.command.CommandBase;
|
||||
import net.minecraft.command.CommandException;
|
||||
import net.minecraft.command.ICommandSender;
|
||||
import net.minecraft.command.WrongUsageException;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.EntityList;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.ChunkPos;
|
||||
import net.minecraft.util.text.TextComponentString;
|
||||
import net.minecraft.util.text.TextComponentTranslation;
|
||||
import net.minecraft.world.WorldServer;
|
||||
import net.minecraftforge.common.DimensionManager;
|
||||
import net.minecraftforge.common.WorldWorkerManager;
|
||||
import net.minecraftforge.server.ForgeTimeTracker;
|
||||
|
@ -86,6 +100,10 @@ public class ForgeCommand extends CommandBase {
|
|||
{
|
||||
handleGen(server, sender, args);
|
||||
}
|
||||
else if ("entity".equals(args[0]))
|
||||
{
|
||||
handleEntity(server, sender, args);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new WrongUsageException("commands.forge.usage");
|
||||
|
@ -96,7 +114,7 @@ public class ForgeCommand extends CommandBase {
|
|||
public List<String> getTabCompletions(MinecraftServer server, ICommandSender sender, String[] args, @Nullable BlockPos targetPos)
|
||||
{
|
||||
if (args.length <= 1)
|
||||
return getListOfStringsMatchingLastWord(args, new String[] {"help", "tps", "track", "gen"});
|
||||
return getListOfStringsMatchingLastWord(args, "help", "tps", "track", "gen", "entity");
|
||||
|
||||
switch (args[0].toLowerCase(Locale.ENGLISH))
|
||||
{
|
||||
|
@ -108,6 +126,12 @@ public class ForgeCommand extends CommandBase {
|
|||
if (args.length == 6) // Dimension, Add support for names? Get list of ids? Meh
|
||||
return Collections.emptyList();
|
||||
break;
|
||||
case "entity":
|
||||
if (args.length == 2)
|
||||
return getListOfStringsMatchingLastWord(args, "help", "list");
|
||||
if (args.length == 3)
|
||||
return getListOfStringsMatchingLastWord(args,EntityList.getEntityNameList().stream().map(e -> e.toString()).sorted().toArray(String[]::new));
|
||||
break;
|
||||
}
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
@ -199,4 +223,78 @@ public class ForgeCommand extends CommandBase {
|
|||
|
||||
return sum / values.length;
|
||||
}
|
||||
|
||||
private void handleEntity(MinecraftServer server, ICommandSender sender, String[] args) throws CommandException
|
||||
{
|
||||
if (args.length < 2 || args[1].toLowerCase(Locale.ENGLISH).equals("help"))
|
||||
throw new WrongUsageException("commands.forge.entity.usage");
|
||||
|
||||
switch (args[1].toLowerCase(Locale.ENGLISH))
|
||||
{
|
||||
case "list":
|
||||
String filter = "*";
|
||||
if (args.length > 2)
|
||||
{
|
||||
if (args[2].toLowerCase(Locale.ENGLISH).equals("help"))
|
||||
throw new WrongUsageException("commands.forge.entity.list.usage");
|
||||
filter = args[2];
|
||||
}
|
||||
final String cleanfilter = filter.replace("?", ".?").replace("*", ".*?");
|
||||
Set<ResourceLocation> names = EntityList.getEntityNameList().stream().filter(n -> n.toString().matches(cleanfilter)).collect(Collectors.toSet());
|
||||
|
||||
if (names.isEmpty())
|
||||
throw new WrongUsageException("commands.forge.entity.list.invalid");
|
||||
|
||||
int dim = args.length > 3 ? parseInt(args[3]) : sender.getEntityWorld().provider.getDimension();
|
||||
|
||||
Map<ResourceLocation, MutablePair<Integer, Map<ChunkPos, Integer>>> list = Maps.newHashMap();
|
||||
WorldServer world = DimensionManager.getWorld(dim);
|
||||
if (world == null)
|
||||
throw new WrongUsageException("commands.forge.entity.list.invalidworld", dim);
|
||||
|
||||
List<Entity> entities = world.getLoadedEntityList();
|
||||
entities.forEach(e -> {
|
||||
ResourceLocation key = EntityList.getKey(e);
|
||||
|
||||
MutablePair<Integer, Map<ChunkPos, Integer>> info = list.get(key);
|
||||
if (info == null)
|
||||
{
|
||||
info = MutablePair.of(0, Maps.newHashMap());
|
||||
list.put(key, info);
|
||||
}
|
||||
ChunkPos chunk = new ChunkPos(e.getPosition());
|
||||
info.left++;
|
||||
info.right.put(chunk, info.right.getOrDefault(chunk, 0) + 1);
|
||||
});
|
||||
|
||||
if (names.size() == 1)
|
||||
{
|
||||
ResourceLocation name = names.iterator().next();
|
||||
Pair<Integer, Map<ChunkPos, Integer>> info = list.get(name);
|
||||
if (info == null)
|
||||
throw new WrongUsageException("commands.forge.entity.list.none");
|
||||
sender.sendMessage(new TextComponentTranslation("commands.forge.entity.list.single.header", name, info.getLeft()));
|
||||
info.getRight().entrySet().stream()
|
||||
.sorted((a,b) -> a.getValue() != b.getValue() ? b.getValue() - a.getValue() : a.getKey().toString().compareTo(b.getKey().toString()))
|
||||
.limit(10).forEach(e -> sender.sendMessage(new TextComponentString(" " + e.getValue() + ": " + e.getKey().x + ", " + e.getKey().z)));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
List<Pair<ResourceLocation, 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() != b.getRight() ? b.getRight() - a.getRight() : a.getKey().toString().compareTo(b.getKey().toString()))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
if (info == null || info.size() == 0)
|
||||
throw new WrongUsageException("commands.forge.entity.list.none");
|
||||
|
||||
int count = info.stream().mapToInt(a -> a.getRight()).sum();
|
||||
sender.sendMessage(new TextComponentTranslation("commands.forge.entity.list.multiple.header", count));
|
||||
info.forEach(e -> sender.sendMessage(new TextComponentString(" " + e.getValue() + ": " + e.getKey())));
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,6 +6,13 @@ commands.forge.gen.dim_fail=Failed to load world for dimension %d, Task terminat
|
|||
commands.forge.gen.progress=Generation Progress: %d/%d
|
||||
commands.forge.gen.complete=Finished generating %d new chunks (out of %d) for dimension %d.
|
||||
commands.forge.gen.start=Starting to generate %d chunks in a spiral around %d, %d in dimension %d.
|
||||
commands.forge.entity.usage=Use /forge entity [list] help for more infomration on a specific command.
|
||||
commands.forge.entity.list.usage=Use /forge entity list [filter] [dim] to get entity info that matches the optional filter.
|
||||
commands.forge.entity.list.invalid=Invalid filter, does not match any entities. Use /forge entity list for a proper list
|
||||
commands.forge.entity.list.invalidworld=Could not load world for dimension %d. Please select a valid dimension.
|
||||
commands.forge.entity.list.none=No entities found.
|
||||
commands.forge.entity.list.single.header=Entity: %s Total: %d
|
||||
commands.forge.entity.list.multiple.header=Total: %d
|
||||
|
||||
commands.forge.tracking.te.enabled=Tile Entity tracking enabled for %d seconds.
|
||||
commands.tree_base.invalid_cmd=Invalid subcommand '%s'!
|
||||
|
|
Loading…
Reference in New Issue