NPCRunTestsCommand.java
package com.hypixel.hytale.server.npc.commands;
import com.hypixel.hytale.component.Component;
import com.hypixel.hytale.component.ComponentType;
import com.hypixel.hytale.component.Ref;
import com.hypixel.hytale.component.RemoveReason;
import com.hypixel.hytale.component.Store;
import com.hypixel.hytale.function.consumer.TriConsumer;
import com.hypixel.hytale.math.vector.Vector3d;
import com.hypixel.hytale.math.vector.Vector3f;
import com.hypixel.hytale.server.core.Message;
import com.hypixel.hytale.server.core.asset.type.model.config.Model;
import com.hypixel.hytale.server.core.command.system.CommandContext;
import com.hypixel.hytale.server.core.command.system.arguments.system.FlagArg;
import com.hypixel.hytale.server.core.command.system.arguments.system.OptionalArg;
import com.hypixel.hytale.server.core.command.system.arguments.types.ArgTypes;
import com.hypixel.hytale.server.core.command.system.basecommands.AbstractPlayerCommand;
import com.hypixel.hytale.server.core.entity.UUIDComponent;
import com.hypixel.hytale.server.core.entity.group.EntityGroup;
import com.hypixel.hytale.server.core.modules.entity.component.TransformComponent;
import com.hypixel.hytale.server.core.universe.PlayerRef;
import com.hypixel.hytale.server.core.universe.world.World;
import com.hypixel.hytale.server.core.universe.world.storage.EntityStore;
import com.hypixel.hytale.server.flock.FlockPlugin;
import com.hypixel.hytale.server.npc.NPCPlugin;
import com.hypixel.hytale.server.npc.entities.NPCEntity;
import it.unimi.dsi.fastutil.Pair;
import it.unimi.dsi.fastutil.ints.IntArrayList;
import it.unimi.dsi.fastutil.ints.IntList;
import it.unimi.dsi.fastutil.ints.IntOpenHashSet;
import it.unimi.dsi.fastutil.ints.IntSet;
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
import java.util.UUID;
import java.util.logging.Level;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
public class NPCRunTestsCommand extends AbstractPlayerCommand {
@Nonnull
private static final Message MESSAGE_COMMANDS_NPC_RUN_TESTS_SPECIFY_ROLES = Message.translation("server.commands.npc.runtests.specifyroles");
@Nonnull
private final OptionalArg<String> rolesArg;
@Nonnull
private final FlagArg presetArg;
@Nonnull
private final FlagArg passArg;
@Nonnull
private final FlagArg failArg;
@Nonnull
private final FlagArg abortArg;
public NPCRunTestsCommand() {
super("runtests", "server.commands.npc.runtests.desc");
this.rolesArg = this.withOptionalArg("roles", "server.commands.npc.runtests.roles.desc", ArgTypes.STRING);
this.presetArg = this.withFlagArg("preset", "server.commands.npc.runtests.preset.desc");
this.passArg = this.withFlagArg("pass", "server.commands.npc.runtests.pass.desc");
this.failArg = this.withFlagArg("fail", "server.commands.npc.runtests.fail.desc");
this.abortArg = this.withFlagArg("abort", "server.commands.npc.runtests.abort.desc");
}
protected void execute(@Nonnull CommandContext context, @Nonnull Store<EntityStore> store, @Nonnull Ref<EntityStore> ref, @Nonnull PlayerRef playerRef, @Nonnull World world) {
NPCTestData testDataComponent = (NPCTestData)store.ensureAndGetComponent(ref, NPCRunTestsCommand.NPCTestData.getComponentType());
TransformComponent playerTransformComponent = (TransformComponent)store.getComponent(ref, TransformComponent.getComponentType());
assert playerTransformComponent != null;
if (!testDataComponent.npcRoles.isEmpty()) {
if ((Boolean)this.passArg.get(context)) {
setNextRole(testDataComponent, ref, store, world);
return;
}
if ((Boolean)this.failArg.get(context)) {
testDataComponent.failedRoles.add(testDataComponent.npcRoles.getInt(testDataComponent.index));
setNextRole(testDataComponent, ref, store, world);
return;
}
if ((Boolean)this.abortArg.get(context)) {
reportResults(ref, testDataComponent, store);
Ref<EntityStore> npcRef = world.getEntityRef(testDataComponent.targetUUID);
if (npcRef != null) {
cleanupNPC(npcRef, store);
}
store.removeComponent(ref, NPCRunTestsCommand.NPCTestData.getComponentType());
return;
}
}
String[] roles;
if ((Boolean)this.presetArg.get(context)) {
roles = NPCPlugin.get().getPresetCoverageTestNPCs();
} else {
if (!this.rolesArg.provided(context)) {
context.sendMessage(MESSAGE_COMMANDS_NPC_RUN_TESTS_SPECIFY_ROLES);
store.removeComponent(ref, NPCRunTestsCommand.NPCTestData.getComponentType());
return;
}
String roleString = (String)this.rolesArg.get(context);
if (roleString == null || roleString.isEmpty()) {
context.sendMessage(MESSAGE_COMMANDS_NPC_RUN_TESTS_SPECIFY_ROLES);
store.removeComponent(ref, NPCRunTestsCommand.NPCTestData.getComponentType());
return;
}
roles = roleString.split(",");
}
for(String role : roles) {
int flockSize;
try {
int idx = role.indexOf(35);
flockSize = idx < 0 ? 1 : Integer.parseInt(role.substring(idx + 1));
if (idx > 0) {
role = role.substring(0, idx);
}
} catch (NumberFormatException var15) {
context.sendMessage(Message.translation("server.commands.npc.runtests.invalidflocksize").param("role", role));
continue;
}
int builderIndex = NPCPlugin.get().getIndex(role);
if (builderIndex == -2147483648) {
context.sendMessage(Message.translation("server.commands.npc.spawn.templateNotFound").param("template", role));
} else {
testDataComponent.npcRoles.add(builderIndex);
testDataComponent.flockSizes.add(flockSize);
}
}
if (testDataComponent.targetUUID == null) {
spawnNPC(ref, testDataComponent, 0, playerTransformComponent.getPosition(), playerTransformComponent.getRotation(), store);
}
}
private static void setNextRole(@Nonnull NPCTestData testData, @Nonnull Ref<EntityStore> reference, @Nonnull Store<EntityStore> store, @Nonnull World world) {
Ref<EntityStore> npcReference = world.getEntityRef(testData.targetUUID);
++testData.index;
if (testData.index >= testData.npcRoles.size()) {
reportResults(reference, testData, store);
if (npcReference != null) {
cleanupNPC(npcReference, store);
}
store.removeComponent(reference, NPCRunTestsCommand.NPCTestData.getComponentType());
} else {
Vector3d position;
Vector3f rotation;
if (npcReference != null) {
TransformComponent npcTransformComponent = (TransformComponent)store.getComponent(npcReference, TransformComponent.getComponentType());
assert npcTransformComponent != null;
position = npcTransformComponent.getPosition();
rotation = npcTransformComponent.getRotation();
cleanupNPC(npcReference, store);
} else {
TransformComponent transformComponent = (TransformComponent)store.getComponent(reference, TransformComponent.getComponentType());
assert transformComponent != null;
position = transformComponent.getPosition();
rotation = transformComponent.getRotation();
}
spawnNPC(reference, testData, testData.index, position, rotation, store);
}
}
private static void cleanupNPC(@Nonnull Ref<EntityStore> ref, @Nonnull Store<EntityStore> store) {
Ref<EntityStore> flockReference = FlockPlugin.getFlockReference(ref, store);
if (flockReference != null) {
ObjectArrayList<Ref<EntityStore>> members = new ObjectArrayList<Ref<EntityStore>>();
EntityGroup entityGroupComponent = (EntityGroup)store.getComponent(flockReference, EntityGroup.getComponentType());
assert entityGroupComponent != null;
entityGroupComponent.forEachMember((index, memberx, list) -> list.add(memberx), members);
for(Ref<EntityStore> member : members) {
store.removeEntity(member, RemoveReason.REMOVE);
}
}
store.removeEntity(ref, RemoveReason.REMOVE);
}
private static void spawnNPC(@Nonnull Ref<EntityStore> playerReference, @Nonnull NPCTestData testData, int index, @Nonnull Vector3d position, @Nullable Vector3f rotation, @Nonnull Store<EntityStore> store) {
Pair<Ref<EntityStore>, NPCEntity> npcPair = NPCPlugin.get().spawnEntity(store, testData.npcRoles.getInt(index), position, rotation, (Model)null, (TriConsumer)null);
Ref<EntityStore> npcRef = npcPair.first();
NPCEntity npcComponent = npcPair.second();
int flockSize = testData.flockSizes.getInt(index);
if (flockSize > 1) {
TransformComponent npcTransformComponent = (TransformComponent)store.getComponent(npcRef, TransformComponent.getComponentType());
assert npcTransformComponent != null;
FlockPlugin.trySpawnFlock(npcRef, npcComponent, store, npcComponent.getRoleIndex(), npcTransformComponent.getPosition(), npcTransformComponent.getRotation(), flockSize, (TriConsumer)null);
}
String roleName = npcComponent.getRoleName();
PlayerRef playerRefComponent = (PlayerRef)store.getComponent(playerReference, PlayerRef.getComponentType());
assert playerRefComponent != null;
playerRefComponent.sendMessage(Message.translation("server.commands.npc.runtests.testing").param("role", roleName).insert("\n").insert(Message.translation("server.npc.tests." + roleName)));
UUIDComponent npcUUIDComponent = (UUIDComponent)store.getComponent(npcRef, UUIDComponent.getComponentType());
assert npcUUIDComponent != null;
testData.targetUUID = npcUUIDComponent.getUuid();
}
private static void reportResults(@Nonnull Ref<EntityStore> playerReference, @Nonnull NPCTestData testData, @Nonnull Store<EntityStore> store) {
NPCPlugin npcPlugin = NPCPlugin.get();
Message msg = Message.translation("server.commands.npc.runtests.results");
for(int i = 0; i < testData.npcRoles.size(); ++i) {
int index = testData.npcRoles.getInt(i);
String var10001 = npcPlugin.getName(index);
msg.insert(" " + var10001 + ": ");
String result = i >= testData.index ? "server.commands.npc.runtests.notrun" : (testData.failedRoles.contains(index) ? "server.commands.npc.runtests.fail" : "server.commands.npc.runtests.pass");
msg.insert(Message.translation(result));
msg.insert("\n");
}
PlayerRef playerRef = (PlayerRef)store.getComponent(playerReference, PlayerRef.getComponentType());
assert playerRef != null;
playerRef.sendMessage(msg);
npcPlugin.getLogger().at(Level.INFO).log(msg.getRawText());
}
public static class NPCTestData implements Component<EntityStore> {
private final IntList npcRoles = new IntArrayList();
private final IntList flockSizes = new IntArrayList();
private final IntSet failedRoles = new IntOpenHashSet();
private int index;
private UUID targetUUID;
public NPCTestData() {
}
public static ComponentType<EntityStore, NPCTestData> getComponentType() {
return NPCPlugin.get().getNpcTestDataComponentType();
}
@Nonnull
public Component<EntityStore> clone() {
NPCTestData data = new NPCTestData();
data.npcRoles.addAll(this.npcRoles);
data.index = this.index;
data.failedRoles.addAll(this.failedRoles);
return data;
}
}
}