146 lines
		
	
	
	
		
			5.3 KiB
		
	
	
	
		
			Java
		
	
	
	
	
	
			
		
		
	
	
			146 lines
		
	
	
	
		
			5.3 KiB
		
	
	
	
		
			Java
		
	
	
	
	
	
| package net.minecraft.gametest.framework;
 | |
| 
 | |
| import com.mojang.logging.LogUtils;
 | |
| import java.io.File;
 | |
| import java.io.IOException;
 | |
| import java.nio.file.Files;
 | |
| import java.nio.file.LinkOption;
 | |
| import java.nio.file.Path;
 | |
| import java.nio.file.Paths;
 | |
| import java.util.Optional;
 | |
| import java.util.function.Consumer;
 | |
| import java.util.stream.Stream;
 | |
| import joptsimple.OptionParser;
 | |
| import joptsimple.OptionSet;
 | |
| import joptsimple.OptionSpec;
 | |
| import net.minecraft.SuppressForbidden;
 | |
| import net.minecraft.Util;
 | |
| import net.minecraft.server.Bootstrap;
 | |
| import net.minecraft.server.MinecraftServer;
 | |
| import net.minecraft.server.packs.repository.PackRepository;
 | |
| import net.minecraft.server.packs.repository.ServerPacksSource;
 | |
| import net.minecraft.world.level.storage.LevelStorageSource;
 | |
| import org.apache.commons.io.FileUtils;
 | |
| import org.slf4j.Logger;
 | |
| 
 | |
| public class GameTestMainUtil {
 | |
| 	private static final Logger LOGGER = LogUtils.getLogger();
 | |
| 	private static final String DEFAULT_UNIVERSE_DIR = "gametestserver";
 | |
| 	private static final String LEVEL_NAME = "gametestworld";
 | |
| 	private static final OptionParser parser = new OptionParser();
 | |
| 	private static final OptionSpec<String> universe = parser.accepts(
 | |
| 			"universe", "The path to where the test server world will be created. Any existing folder will be replaced."
 | |
| 		)
 | |
| 		.withRequiredArg()
 | |
| 		.defaultsTo("gametestserver");
 | |
| 	private static final OptionSpec<File> report = parser.accepts("report", "Exports results in a junit-like XML report at the given path.")
 | |
| 		.withRequiredArg()
 | |
| 		.ofType(File.class);
 | |
| 	private static final OptionSpec<String> tests = parser.accepts("tests", "Which test(s) to run (namespaced ID selector using wildcards). Empty means run all.")
 | |
| 		.withRequiredArg();
 | |
| 	private static final OptionSpec<Boolean> verify = parser.accepts(
 | |
| 			"verify", "Runs the tests specified with `test` or `testNamespace` 100 times for each 90 degree rotation step"
 | |
| 		)
 | |
| 		.withRequiredArg()
 | |
| 		.<Boolean>ofType(Boolean.class)
 | |
| 		.defaultsTo(false);
 | |
| 	private static final OptionSpec<String> packs = parser.accepts("packs", "A folder of datapacks to include in the world").withRequiredArg();
 | |
| 	private static final OptionSpec<Void> help = parser.accepts("help").forHelp();
 | |
| 
 | |
| 	@SuppressForbidden(
 | |
| 		reason = "Using System.err due to no bootstrap"
 | |
| 	)
 | |
| 	public static void runGameTestServer(String[] args, Consumer<String> universeOutput) throws Exception {
 | |
| 		parser.allowsUnrecognizedOptions();
 | |
| 		OptionSet optionSet = parser.parse(args);
 | |
| 		if (optionSet.has(help)) {
 | |
| 			parser.printHelpOn(System.err);
 | |
| 		} else {
 | |
| 			if (optionSet.valueOf(verify) && !optionSet.has(tests)) {
 | |
| 				LOGGER.error("Please specify a test selection to run the verify option. For example: --verify --tests example:test_something_*");
 | |
| 				System.exit(-1);
 | |
| 			}
 | |
| 
 | |
| 			LOGGER.info("Running GameTestMain with cwd '{}', universe path '{}'", System.getProperty("user.dir"), optionSet.valueOf(universe));
 | |
| 			if (optionSet.has(report)) {
 | |
| 				GlobalTestReporter.replaceWith(new JUnitLikeTestReporter(report.value(optionSet)));
 | |
| 			}
 | |
| 
 | |
| 			Bootstrap.bootStrap();
 | |
| 			Util.startTimerHackThread();
 | |
| 			String string = optionSet.valueOf(universe);
 | |
| 			createOrResetDir(string);
 | |
| 			universeOutput.accept(string);
 | |
| 			if (optionSet.has(packs)) {
 | |
| 				String string2 = optionSet.valueOf(packs);
 | |
| 				copyPacks(string, string2);
 | |
| 			}
 | |
| 
 | |
| 			LevelStorageSource.LevelStorageAccess levelStorageAccess = LevelStorageSource.createDefault(Paths.get(string)).createAccess("gametestworld");
 | |
| 			PackRepository packRepository = ServerPacksSource.createPackRepository(levelStorageAccess);
 | |
| 			MinecraftServer.spin(
 | |
| 				thread -> {
 | |
| 					GameTestServer gameTestServer = GameTestServer.create(
 | |
| 						thread, levelStorageAccess, packRepository, optionalFromOption(optionSet, tests), optionSet.has(verify)
 | |
| 					);
 | |
| 					GameTestTicker.SINGLETON.startTicking();
 | |
| 					return gameTestServer;
 | |
| 				}
 | |
| 			);
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	private static Optional<String> optionalFromOption(OptionSet options, OptionSpec<String> option) {
 | |
| 		return options.has(option) ? Optional.of(options.valueOf(option)) : Optional.empty();
 | |
| 	}
 | |
| 
 | |
| 	private static void createOrResetDir(String dir) throws IOException {
 | |
| 		Path path = Paths.get(dir);
 | |
| 		if (Files.exists(path, new LinkOption[0])) {
 | |
| 			FileUtils.deleteDirectory(path.toFile());
 | |
| 		}
 | |
| 
 | |
| 		Files.createDirectories(path);
 | |
| 	}
 | |
| 
 | |
| 	private static void copyPacks(String universe, String packs) throws IOException {
 | |
| 		Path path = Paths.get(universe).resolve("gametestworld").resolve("datapacks");
 | |
| 		if (!Files.exists(path, new LinkOption[0])) {
 | |
| 			Files.createDirectories(path);
 | |
| 		}
 | |
| 
 | |
| 		Path path2 = Paths.get(packs);
 | |
| 		if (Files.exists(path2, new LinkOption[0])) {
 | |
| 			Stream<Path> stream = Files.list(path2);
 | |
| 
 | |
| 			try {
 | |
| 				for (Path path3 : stream.toList()) {
 | |
| 					Path path4 = path.resolve(path3.getFileName());
 | |
| 					if (Files.isDirectory(path3, new LinkOption[0])) {
 | |
| 						if (Files.isRegularFile(path3.resolve("pack.mcmeta"), new LinkOption[0])) {
 | |
| 							FileUtils.copyDirectory(path3.toFile(), path4.toFile());
 | |
| 							LOGGER.info("Included folder pack {}", path3.getFileName());
 | |
| 						}
 | |
| 					} else if (path3.toString().endsWith(".zip")) {
 | |
| 						Files.copy(path3, path4);
 | |
| 						LOGGER.info("Included zip pack {}", path3.getFileName());
 | |
| 					}
 | |
| 				}
 | |
| 			} catch (Throwable var9) {
 | |
| 				if (stream != null) {
 | |
| 					try {
 | |
| 						stream.close();
 | |
| 					} catch (Throwable var8) {
 | |
| 						var9.addSuppressed(var8);
 | |
| 					}
 | |
| 				}
 | |
| 
 | |
| 				throw var9;
 | |
| 			}
 | |
| 
 | |
| 			if (stream != null) {
 | |
| 				stream.close();
 | |
| 			}
 | |
| 		}
 | |
| 	}
 | |
| }
 |