Skip to content

Commit

Permalink
Add option to generate commands.json report
Browse files Browse the repository at this point in the history
  • Loading branch information
misode committed Sep 26, 2024
1 parent 983e014 commit 9b7b8d5
Show file tree
Hide file tree
Showing 2 changed files with 70 additions and 6 deletions.
71 changes: 65 additions & 6 deletions src/main/java/io/github/misode/packtest/PackTest.java
Original file line number Diff line number Diff line change
@@ -1,16 +1,37 @@
package io.github.misode.packtest;

import com.google.gson.JsonObject;
import com.google.gson.stream.JsonWriter;
import com.mojang.brigadier.CommandDispatcher;
import io.github.misode.packtest.commands.*;
import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap;
import net.fabricmc.api.ModInitializer;
import net.fabricmc.fabric.api.command.v2.CommandRegistrationCallback;
import net.minecraft.FileUtil;
import net.minecraft.Util;
import net.minecraft.commands.CommandBuildContext;
import net.minecraft.commands.CommandSourceStack;
import net.minecraft.commands.Commands;
import net.minecraft.commands.synchronization.ArgumentUtils;
import net.minecraft.core.BlockPos;
import net.minecraft.data.registries.VanillaRegistries;
import net.minecraft.gametest.framework.GameTestServer;
import net.minecraft.server.packs.repository.PackRepository;
import net.minecraft.util.GsonHelper;
import net.minecraft.world.level.storage.LevelStorageSource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Comparator;
import java.util.List;
import java.util.function.ToIntFunction;

public class PackTest implements ModInitializer {
public static final Logger LOGGER = LoggerFactory.getLogger(PackTest.class);
Expand All @@ -27,15 +48,53 @@ public static boolean isAnnotationsEnabled() {
return isAutoEnabled() && System.getProperty("packtest.auto.annotations") != null;
}

public static boolean shouldGenerateCommands() {
return System.getProperty("packtest.generate.commands") != null;
}

@Override
public void onInitialize() {
CommandRegistrationCallback.EVENT.register((dispatcher, buildContext, environment) -> {
AssertCommand.register(dispatcher, buildContext);
AwaitCommand.register(dispatcher, buildContext);
FailCommand.register(dispatcher, buildContext);
DummyCommand.register(dispatcher);
SucceedCommand.register(dispatcher);
CommandRegistrationCallback.EVENT.register((dispatcher, buildContext, environment) ->
registerCommands(dispatcher, buildContext)
);
}

public static void generateCommandsReport() {
Path path = Paths.get("generated", "reports", "commands.json");
CommandDispatcher<CommandSourceStack> dispatcher = new CommandDispatcher<>();
registerCommands(dispatcher, Commands.createValidationContext(VanillaRegistries.createLookup()));
JsonObject data = ArgumentUtils.serializeNodeToJson(dispatcher, dispatcher.getRoot());
ToIntFunction<String> fixedOrderFields = Util.make(new Object2IntOpenHashMap<>(), map -> {
map.put("type", 0);
map.put("parser", 1);
map.put("properties", 2);
map.put("executable", 3);
map.put("redirect", 4);
map.put("children", 5);
map.defaultReturnValue(6);
});
Comparator<String> keyComparator = Comparator.comparingInt(fixedOrderFields).thenComparing(string -> string);
try {
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
try (JsonWriter writer = new JsonWriter(new OutputStreamWriter(outputStream, StandardCharsets.UTF_8))) {
writer.setSerializeNulls(false);
writer.setIndent(" ");
GsonHelper.writeValue(writer, data, keyComparator);
}
FileUtil.createDirectoriesSafe(path.getParent());
Files.write(path, outputStream.toByteArray());
LOGGER.info("Saved file to {}", path);
} catch (IOException e) {
LOGGER.error("Failed to save file to {}", path, e);
}
}

private static void registerCommands(CommandDispatcher<CommandSourceStack> dispatcher, CommandBuildContext buildContext) {
AssertCommand.register(dispatcher, buildContext);
AwaitCommand.register(dispatcher, buildContext);
FailCommand.register(dispatcher, buildContext);
DummyCommand.register(dispatcher);
SucceedCommand.register(dispatcher);
}

public static void runHeadlessServer(LevelStorageSource.LevelStorageAccess storage, PackRepository packRepository) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,13 @@
public class MainMixin {
@Inject(method = "main", cancellable = true, at = @At(value = "INVOKE_ASSIGN", target = "Lnet/minecraft/server/packs/repository/ServerPacksSource;createPackRepository(Lnet/minecraft/world/level/storage/LevelStorageSource$LevelStorageAccess;)Lnet/minecraft/server/packs/repository/PackRepository;", shift = At.Shift.AFTER))
private static void mainStartServer(String[] args, CallbackInfo ci, @Local LevelStorageSource.LevelStorageAccess storage, @Local PackRepository packRepository) {
if (PackTest.shouldGenerateCommands()) {
PackTest.generateCommandsReport();
}
if (PackTest.isAutoEnabled()) {
PackTest.runHeadlessServer(storage, packRepository);
}
if (PackTest.shouldGenerateCommands() || PackTest.isAutoEnabled()) {
ci.cancel();
}
}
Expand Down

0 comments on commit 9b7b8d5

Please sign in to comment.