package com.hypixel.hytale.server.npc.role; import com.hypixel.hytale.common.util.StringUtil; import java.util.EnumSet; import java.util.function.Supplier; import javax.annotation.Nonnull; import javax.annotation.Nullable; public enum RoleDebugFlags implements Supplier { TraceFail("Trace failed steps"), TraceSuccess("Trace matched steps"), TraceSensorFailures("Trace failing sensors"), Flock("Trace flock events"), FlockDamage("Trace flock damage events"), MotionControllerSteer("Trace steering activity of motion controllers"), Collisions("Trace collision information of motion controllers"), BlockCollisions("Trace collisions down to block level"), ProbeBlockCollisions("Trace collisions down to block level when probing"), MotionControllerMove("Trace movement activity of motion controllers"), ValidatePositions("Validate computed movement positions are not intersecting blocks"), SteeringRole("Debug blended steering behaviour from role like avoidance/separation"), DisplayState("Set display name to contents of state"), DisplayFlock("Set display name to flock state"), DisplayTime("Set display name to day time"), DisplayTarget("Set display name to locked target type"), DisplayAnim("Display animation state"), DisplayLightLevel("Display light levels"), DisplayCustom("Display custom debug information (generated by debug components)"), DisplayHP("Display NPC HP as numerical values"), DisplayStamina("Display NPC Stamina as numerical values"), Overlaps("Log overlapping blocks when validating position"), Pathfinder("Display pathfinder status"), DisplaySpeed("Display speed of entity"), DisplayFreeSlots("Display free inventory slots"), DisplayInternalId("Display the internal server ID for this entity"), DisplayName("Display the role name for this entity"), ValidateMath("Validate (some) math computations in movement"), VisAvoidance("Visualize avoidance vectors"), VisSeparation("Visualize separation vector"), BeaconMessages("Enable debugging of beacon message sending and receiving"); private static final RoleDebugFlags.RoleDebugPreset[] presets = new RoleDebugFlags.RoleDebugPreset[]{ new RoleDebugFlags.RoleDebugPreset("none", EnumSet.noneOf(RoleDebugFlags.class)), new RoleDebugFlags.RoleDebugPreset("all", EnumSet.allOf(RoleDebugFlags.class)), new RoleDebugFlags.RoleDebugPreset("move", EnumSet.of(MotionControllerMove, Collisions)), new RoleDebugFlags.RoleDebugPreset("steer", EnumSet.of(MotionControllerMove, MotionControllerSteer, Collisions)), new RoleDebugFlags.RoleDebugPreset("valid", EnumSet.of(MotionControllerMove, MotionControllerSteer, Collisions, ValidatePositions)), new RoleDebugFlags.RoleDebugPreset("block", EnumSet.of(MotionControllerMove, MotionControllerSteer, Collisions, BlockCollisions)), new RoleDebugFlags.RoleDebugPreset("visDist", EnumSet.of(VisAvoidance, VisSeparation)), new RoleDebugFlags.RoleDebugPreset( "display", EnumSet.of( DisplayState, DisplayFlock, DisplayTime, DisplayTarget, DisplayAnim, DisplayLightLevel, DisplayCustom, DisplayHP, DisplayStamina, DisplaySpeed, DisplayFreeSlots, DisplayInternalId, DisplayName ) ), new RoleDebugFlags.RoleDebugPreset("default", EnumSet.complementOf(EnumSet.of(ValidatePositions))) }; private final String description; private RoleDebugFlags(String description) { this.description = description; } public String get() { return this.description; } @Nonnull public static EnumSet getFlags(@Nonnull String[] args) { if (args.length == 0) { throw new IllegalArgumentException("Missing debug flags! " + getValidNameString()); } else { EnumSet flags = EnumSet.noneOf(RoleDebugFlags.class); for (String arg : args) { RoleDebugFlags debugFlag = StringUtil.parseEnum(RoleDebugFlags.class.getEnumConstants(), arg, StringUtil.MatchType.CASE_INSENSITIVE); if (debugFlag != null) { flags.add(debugFlag); } else { EnumSet preset = findPreset(arg); if (preset == null) { throw new IllegalArgumentException("Invalid flag/preset '" + arg + "'! " + getValidNameString()); } flags.addAll(preset); } } return flags; } } @Nonnull public static StringBuilder getListOfFlags(@Nonnull EnumSet flags, @Nonnull StringBuilder stringBuilder) { boolean comma = false; for (RoleDebugFlags flag : values()) { if (flags.contains(flag)) { if (comma) { stringBuilder.append(", "); } stringBuilder.append(flag); comma = true; } } return stringBuilder; } public static StringBuilder getListOfAllFlags(@Nonnull StringBuilder stringBuilder) { return getListOfFlags(EnumSet.allOf(RoleDebugFlags.class), stringBuilder); } public static StringBuilder getListOfAllPresets(@Nonnull StringBuilder stringBuilder) { boolean comma = false; for (RoleDebugFlags.RoleDebugPreset preset : presets) { if (comma) { stringBuilder.append(", "); } stringBuilder.append(preset.name); comma = true; } return stringBuilder; } @Nonnull public static EnumSet getPreset(String arg) { EnumSet preset = findPreset(arg); if (preset == null) { throw new IllegalArgumentException("Invalid flag/preset '" + arg + "'! " + getValidNameString()); } else { EnumSet flags = EnumSet.noneOf(RoleDebugFlags.class); flags.addAll(preset); return flags; } } @Nonnull private static String getValidNameString() { StringBuilder result = new StringBuilder(); result.append("Valid presets are: "); boolean comma = false; for (RoleDebugFlags.RoleDebugPreset preset : presets) { if (comma) { result.append(", "); } result.append(preset.name); comma = true; } result.append(". Valid flags are: "); getListOfFlags(EnumSet.allOf(RoleDebugFlags.class), result); return result.toString(); } @Nullable private static EnumSet findPreset(String name) { for (RoleDebugFlags.RoleDebugPreset preset : presets) { if (preset.name.equalsIgnoreCase(name)) { return preset.config; } } return null; } public static boolean havePreset(String name) { for (RoleDebugFlags.RoleDebugPreset preset : presets) { if (preset.name.equalsIgnoreCase(name)) { return true; } } return false; } private static class RoleDebugPreset { public String name; public EnumSet config; private RoleDebugPreset(String name, EnumSet config) { this.name = name; this.config = config; } } }