274 lines
12 KiB
Java
274 lines
12 KiB
Java
package carpet.commands;
|
|
|
|
import carpet.CarpetSettings;
|
|
import carpet.fakes.SpawnGroupInterface;
|
|
import carpet.helpers.HopperCounter;
|
|
import carpet.helpers.TickSpeed;
|
|
import carpet.settings.SettingsManager;
|
|
import carpet.utils.Messenger;
|
|
import carpet.utils.SpawnReporter;
|
|
import com.mojang.brigadier.CommandDispatcher;
|
|
import com.mojang.brigadier.arguments.BoolArgumentType;
|
|
import com.mojang.brigadier.builder.LiteralArgumentBuilder;
|
|
import com.mojang.brigadier.exceptions.CommandSyntaxException;
|
|
import com.mojang.brigadier.exceptions.SimpleCommandExceptionType;
|
|
import java.util.Arrays;
|
|
import java.util.Locale;
|
|
import java.util.stream.Collectors;
|
|
import net.minecraft.commands.CommandSourceStack;
|
|
import net.minecraft.commands.arguments.DimensionArgument;
|
|
import net.minecraft.commands.arguments.coordinates.BlockPosArgument;
|
|
import net.minecraft.core.BlockPos;
|
|
import net.minecraft.server.level.ServerLevel;
|
|
import net.minecraft.server.level.ServerPlayer;
|
|
import net.minecraft.world.entity.MobCategory;
|
|
import net.minecraft.world.item.DyeColor;
|
|
|
|
import static com.mojang.brigadier.arguments.IntegerArgumentType.getInteger;
|
|
import static com.mojang.brigadier.arguments.IntegerArgumentType.integer;
|
|
import static com.mojang.brigadier.arguments.StringArgumentType.getString;
|
|
import static com.mojang.brigadier.arguments.StringArgumentType.string;
|
|
import static com.mojang.brigadier.arguments.StringArgumentType.word;
|
|
import static net.minecraft.commands.Commands.argument;
|
|
import static net.minecraft.commands.Commands.literal;
|
|
import static net.minecraft.commands.SharedSuggestionProvider.suggest;
|
|
|
|
|
|
public class SpawnCommand
|
|
{
|
|
public static void register(CommandDispatcher<CommandSourceStack> dispatcher)
|
|
{
|
|
LiteralArgumentBuilder<CommandSourceStack> literalargumentbuilder = literal("spawn").
|
|
requires((player) -> SettingsManager.canUseCommand(player, CarpetSettings.commandSpawn));
|
|
|
|
literalargumentbuilder.
|
|
then(literal("list").
|
|
then(argument("pos", BlockPosArgument.blockPos()).
|
|
executes( (c) -> listSpawns(c.getSource(), BlockPosArgument.getSpawnablePos(c, "pos"))))).
|
|
then(literal("tracking").
|
|
executes( (c) -> printTrackingReport(c.getSource())).
|
|
then(literal("start").
|
|
executes( (c) -> startTracking(c.getSource(), null, null)).
|
|
then(argument("from", BlockPosArgument.blockPos()).
|
|
then(argument("to", BlockPosArgument.blockPos()).
|
|
executes( (c) -> startTracking(
|
|
c.getSource(),
|
|
BlockPosArgument.getSpawnablePos(c, "from"),
|
|
BlockPosArgument.getSpawnablePos(c, "to")))))).
|
|
then(literal("stop").
|
|
executes( (c) -> stopTracking(c.getSource()))).
|
|
then(argument("type", word()).
|
|
suggests( (c, b) -> suggest(Arrays.stream(MobCategory.values()).map(MobCategory::getName),b)).
|
|
executes( (c) -> recentSpawnsForType(c.getSource(), getString(c, "type"))))).
|
|
then(literal("test").
|
|
executes( (c)-> runTest(c.getSource(), 72000, null)).
|
|
then(argument("ticks", integer(10)).
|
|
executes( (c)-> runTest(
|
|
c.getSource(),
|
|
getInteger(c, "ticks"),
|
|
null)).
|
|
then(argument("counter", word()).
|
|
suggests( (c, b) -> suggest(Arrays.stream(DyeColor.values()).map(DyeColor::toString),b)).
|
|
executes((c)-> runTest(
|
|
c.getSource(),
|
|
getInteger(c, "ticks"),
|
|
getString(c, "counter")))))).
|
|
then(literal("mocking").
|
|
then(argument("to do or not to do?", BoolArgumentType.bool()).
|
|
executes( (c) -> toggleMocking(c.getSource(), BoolArgumentType.getBool(c, "to do or not to do?"))))).
|
|
then(literal("rates").
|
|
executes( (c) -> generalMobcaps(c.getSource())).
|
|
then(literal("reset").
|
|
executes( (c) -> resetSpawnRates(c.getSource()))).
|
|
then(argument("type", word()).
|
|
suggests( (c, b) -> suggest(Arrays.stream(MobCategory.values()).map(MobCategory::getName),b)).
|
|
then(argument("rounds", integer(0)).
|
|
suggests( (c, b) -> suggest(new String[]{"1"},b)).
|
|
executes( (c) -> setSpawnRates(
|
|
c.getSource(),
|
|
getString(c, "type"),
|
|
getInteger(c, "rounds")))))).
|
|
then(literal("mobcaps").
|
|
executes( (c) -> generalMobcaps(c.getSource())).
|
|
then(literal("set").
|
|
then(argument("cap (hostile)", integer(1,1400)).
|
|
executes( (c) -> setMobcaps(c.getSource(), getInteger(c, "cap (hostile)"))))).
|
|
then(argument("dimension", DimensionArgument.dimension()).
|
|
executes( (c)-> mobcapsForDimension(c.getSource(), DimensionArgument.getDimension(c, "dimension"))))).
|
|
then(literal("entities").
|
|
executes( (c) -> generalMobcaps(c.getSource()) ).
|
|
then(argument("type", string()).
|
|
suggests( (c, b)->suggest(Arrays.stream(MobCategory.values()).map(MobCategory::getName), b)).
|
|
executes( (c) -> listEntitiesOfType(c.getSource(), getString(c, "type"), false)).
|
|
then(literal("all").executes( (c) -> listEntitiesOfType(c.getSource(), getString(c, "type"), true)))));
|
|
|
|
dispatcher.register(literalargumentbuilder);
|
|
}
|
|
|
|
private static MobCategory getCategory(String string) throws CommandSyntaxException
|
|
{
|
|
if (!Arrays.stream(MobCategory.values()).map(MobCategory::getName).collect(Collectors.toSet()).contains(string))
|
|
{
|
|
throw new SimpleCommandExceptionType(Messenger.c("r Wrong mob type: "+string+" should be "+ Arrays.stream(MobCategory.values()).map(MobCategory::getName).collect(Collectors.joining(", ")))).create();
|
|
}
|
|
return MobCategory.byName(string.toLowerCase(Locale.ROOT));
|
|
}
|
|
|
|
|
|
private static int listSpawns(CommandSourceStack source, BlockPos pos)
|
|
{
|
|
Messenger.send(source, SpawnReporter.report(pos, source.getLevel()));
|
|
return 1;
|
|
}
|
|
|
|
private static int printTrackingReport(CommandSourceStack source)
|
|
{
|
|
Messenger.send(source, SpawnReporter.tracking_report(source.getLevel()));
|
|
return 1;
|
|
}
|
|
|
|
private static int startTracking(CommandSourceStack source, BlockPos a, BlockPos b)
|
|
{
|
|
if (SpawnReporter.track_spawns != 0L)
|
|
{
|
|
Messenger.m(source, "r You are already tracking spawning.");
|
|
return 0;
|
|
}
|
|
BlockPos lsl = null;
|
|
BlockPos usl = null;
|
|
if (a != null && b != null)
|
|
{
|
|
lsl = new BlockPos(
|
|
Math.min(a.getX(), b.getX()),
|
|
Math.min(a.getY(), b.getY()),
|
|
Math.min(a.getZ(), b.getZ()) );
|
|
usl = new BlockPos(
|
|
Math.max(a.getX(), b.getX()),
|
|
Math.max(a.getY(), b.getY()),
|
|
Math.max(a.getZ(), b.getZ()) );
|
|
}
|
|
SpawnReporter.reset_spawn_stats(source.getServer(), false);
|
|
SpawnReporter.track_spawns = (long) source.getServer().getTickCount();
|
|
SpawnReporter.lower_spawning_limit = lsl;
|
|
SpawnReporter.upper_spawning_limit = usl;
|
|
Messenger.m(source, "gi Spawning tracking started.");
|
|
return 1;
|
|
}
|
|
|
|
private static int stopTracking(CommandSourceStack source)
|
|
{
|
|
Messenger.send(source, SpawnReporter.tracking_report(source.getLevel()));
|
|
SpawnReporter.reset_spawn_stats(source.getServer(),false);
|
|
SpawnReporter.track_spawns = 0L;
|
|
SpawnReporter.lower_spawning_limit = null;
|
|
SpawnReporter.upper_spawning_limit = null;
|
|
Messenger.m(source, "gi Spawning tracking stopped.");
|
|
return 1;
|
|
}
|
|
|
|
private static int recentSpawnsForType(CommandSourceStack source, String mob_type) throws CommandSyntaxException
|
|
{
|
|
MobCategory cat = getCategory(mob_type);
|
|
Messenger.send(source, SpawnReporter.recent_spawns(source.getLevel(), cat));
|
|
return 1;
|
|
}
|
|
|
|
private static int runTest(CommandSourceStack source, int ticks, String counter)
|
|
{
|
|
//stop tracking
|
|
SpawnReporter.reset_spawn_stats(source.getServer(),false);
|
|
//start tracking
|
|
SpawnReporter.track_spawns = (long) source.getServer().getTickCount();
|
|
//counter reset
|
|
if (counter == null)
|
|
{
|
|
HopperCounter.resetAll(source.getServer(), false);
|
|
}
|
|
else
|
|
{
|
|
HopperCounter hCounter = HopperCounter.getCounter(counter);
|
|
if (hCounter != null)
|
|
hCounter.reset(source.getServer());
|
|
}
|
|
|
|
|
|
// tick warp 0
|
|
TickSpeed.tickrate_advance(null, 0, null, null);
|
|
// tick warp given player
|
|
CommandSourceStack csource = null;
|
|
ServerPlayer player = null;
|
|
try
|
|
{
|
|
player = source.getPlayerOrException();
|
|
csource = source;
|
|
}
|
|
catch (CommandSyntaxException ignored)
|
|
{
|
|
}
|
|
TickSpeed.tickrate_advance(player, ticks, null, csource);
|
|
Messenger.m(source, String.format("gi Started spawn test for %d ticks", ticks));
|
|
return 1;
|
|
}
|
|
|
|
private static int toggleMocking(CommandSourceStack source, boolean domock)
|
|
{
|
|
if (domock)
|
|
{
|
|
SpawnReporter.initialize_mocking();
|
|
Messenger.m(source, "gi Mob spawns will now be mocked.");
|
|
}
|
|
else
|
|
{
|
|
SpawnReporter.stop_mocking();
|
|
Messenger.m(source, "gi Normal mob spawning.");
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
private static int generalMobcaps(CommandSourceStack source)
|
|
{
|
|
Messenger.send(source, SpawnReporter.printMobcapsForDimension(source.getLevel(), true));
|
|
return 1;
|
|
}
|
|
|
|
private static int resetSpawnRates(CommandSourceStack source)
|
|
{
|
|
for (MobCategory s: SpawnReporter.spawn_tries.keySet())
|
|
{
|
|
SpawnReporter.spawn_tries.put(s,1);
|
|
}
|
|
Messenger.m(source, "gi Spawn rates brought to 1 round per tick for all groups.");
|
|
|
|
return 1;
|
|
}
|
|
|
|
private static int setSpawnRates(CommandSourceStack source, String mobtype, int rounds) throws CommandSyntaxException
|
|
{
|
|
MobCategory cat = getCategory(mobtype);
|
|
SpawnReporter.spawn_tries.put(cat, rounds);
|
|
Messenger.m(source, "gi "+mobtype+" mobs will now spawn "+rounds+" times per tick");
|
|
return 1;
|
|
}
|
|
|
|
private static int setMobcaps(CommandSourceStack source, int hostile_cap)
|
|
{
|
|
double desired_ratio = (double)hostile_cap/ ((SpawnGroupInterface)(Object)MobCategory.MONSTER).getInitialSpawnCap();
|
|
SpawnReporter.mobcap_exponent = 4.0*Math.log(desired_ratio)/Math.log(2.0);
|
|
Messenger.m(source, String.format("gi Mobcaps for hostile mobs changed to %d, other groups will follow", hostile_cap));
|
|
return 1;
|
|
}
|
|
|
|
private static int mobcapsForDimension(CommandSourceStack source, ServerLevel world)
|
|
{
|
|
Messenger.send(source, SpawnReporter.printMobcapsForDimension(world, true));
|
|
return 1;
|
|
}
|
|
|
|
private static int listEntitiesOfType(CommandSourceStack source, String mobtype, boolean all) throws CommandSyntaxException
|
|
{
|
|
MobCategory cat = getCategory(mobtype);
|
|
Messenger.send(source, SpawnReporter.printEntitiesByType(cat, source.getLevel(), all));
|
|
return 1;
|
|
}
|
|
}
|