manual-spawnpoints now works
This commit is contained in:
parent
278c168036
commit
0be54d1fcc
@ -6,6 +6,7 @@
|
||||
<attribute name="maven.pomderived" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="src" path="src/main/resources"/>
|
||||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8">
|
||||
<attributes>
|
||||
<attribute name="maven.pomderived" value="true"/>
|
||||
|
@ -7,6 +7,15 @@ org.eclipse.jdt.core.builder.resourceCopyExclusionFilter=*.launch
|
||||
org.eclipse.jdt.core.circularClasspath=error
|
||||
org.eclipse.jdt.core.classpath.exclusionPatterns=enabled
|
||||
org.eclipse.jdt.core.classpath.multipleOutputLocations=enabled
|
||||
org.eclipse.jdt.core.compiler.annotation.inheritNullAnnotations=disabled
|
||||
org.eclipse.jdt.core.compiler.annotation.missingNonNullByDefaultAnnotation=ignore
|
||||
org.eclipse.jdt.core.compiler.annotation.nonnull=org.eclipse.jdt.annotation.NonNull
|
||||
org.eclipse.jdt.core.compiler.annotation.nonnull.secondary=
|
||||
org.eclipse.jdt.core.compiler.annotation.nonnullbydefault=org.eclipse.jdt.annotation.NonNullByDefault
|
||||
org.eclipse.jdt.core.compiler.annotation.nonnullbydefault.secondary=
|
||||
org.eclipse.jdt.core.compiler.annotation.nullable=org.eclipse.jdt.annotation.Nullable
|
||||
org.eclipse.jdt.core.compiler.annotation.nullable.secondary=
|
||||
org.eclipse.jdt.core.compiler.annotation.nullanalysis=disabled
|
||||
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
|
||||
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
|
||||
org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
|
||||
@ -15,6 +24,7 @@ org.eclipse.jdt.core.compiler.debug.lineNumber=generate
|
||||
org.eclipse.jdt.core.compiler.debug.localVariable=generate
|
||||
org.eclipse.jdt.core.compiler.debug.sourceFile=generate
|
||||
org.eclipse.jdt.core.compiler.maxProblemPerUnit=100
|
||||
org.eclipse.jdt.core.compiler.problem.APILeak=warning
|
||||
org.eclipse.jdt.core.compiler.problem.annotationSuperInterface=warning
|
||||
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
|
||||
org.eclipse.jdt.core.compiler.problem.autoboxing=ignore
|
||||
@ -26,9 +36,10 @@ org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=
|
||||
org.eclipse.jdt.core.compiler.problem.discouragedReference=warning
|
||||
org.eclipse.jdt.core.compiler.problem.emptyStatement=warning
|
||||
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
|
||||
org.eclipse.jdt.core.compiler.problem.explicitlyClosedAutoCloseable=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.fallthroughCase=warning
|
||||
org.eclipse.jdt.core.compiler.problem.fatalOptionalError=disabled
|
||||
org.eclipse.jdt.core.compiler.problem.fieldHiding=warning
|
||||
org.eclipse.jdt.core.compiler.problem.fieldHiding=info
|
||||
org.eclipse.jdt.core.compiler.problem.finalParameterBound=warning
|
||||
org.eclipse.jdt.core.compiler.problem.finallyBlockNotCompletingNormally=warning
|
||||
org.eclipse.jdt.core.compiler.problem.forbiddenReference=error
|
||||
@ -39,7 +50,9 @@ org.eclipse.jdt.core.compiler.problem.incompleteEnumSwitch=warning
|
||||
org.eclipse.jdt.core.compiler.problem.indirectStaticAccess=warning
|
||||
org.eclipse.jdt.core.compiler.problem.localVariableHiding=warning
|
||||
org.eclipse.jdt.core.compiler.problem.methodWithConstructorName=warning
|
||||
org.eclipse.jdt.core.compiler.problem.missingDefaultCase=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.missingDeprecatedAnnotation=warning
|
||||
org.eclipse.jdt.core.compiler.problem.missingEnumCaseDespiteDefault=disabled
|
||||
org.eclipse.jdt.core.compiler.problem.missingHashCodeMethod=warning
|
||||
org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=warning
|
||||
org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotationForInterfaceMethodImplementation=enabled
|
||||
@ -48,12 +61,20 @@ org.eclipse.jdt.core.compiler.problem.missingSynchronizedOnInheritedMethod=warni
|
||||
org.eclipse.jdt.core.compiler.problem.noEffectAssignment=warning
|
||||
org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion=warning
|
||||
org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.nonnullParameterAnnotationDropped=warning
|
||||
org.eclipse.jdt.core.compiler.problem.nonnullTypeVariableFromLegacyInvocation=warning
|
||||
org.eclipse.jdt.core.compiler.problem.nullAnnotationInferenceConflict=error
|
||||
org.eclipse.jdt.core.compiler.problem.nullReference=warning
|
||||
org.eclipse.jdt.core.compiler.problem.nullSpecViolation=error
|
||||
org.eclipse.jdt.core.compiler.problem.nullUncheckedConversion=warning
|
||||
org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod=warning
|
||||
org.eclipse.jdt.core.compiler.problem.parameterAssignment=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.pessimisticNullAnalysisForFreeTypeVariables=warning
|
||||
org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.potentialNullReference=warning
|
||||
org.eclipse.jdt.core.compiler.problem.potentiallyUnclosedCloseable=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.rawTypeReference=warning
|
||||
org.eclipse.jdt.core.compiler.problem.redundantNullAnnotation=warning
|
||||
org.eclipse.jdt.core.compiler.problem.redundantNullCheck=warning
|
||||
org.eclipse.jdt.core.compiler.problem.redundantSpecificationOfTypeArguments=warning
|
||||
org.eclipse.jdt.core.compiler.problem.redundantSuperinterface=warning
|
||||
@ -63,19 +84,27 @@ org.eclipse.jdt.core.compiler.problem.specialParameterHidingField=enabled
|
||||
org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=warning
|
||||
org.eclipse.jdt.core.compiler.problem.suppressOptionalErrors=enabled
|
||||
org.eclipse.jdt.core.compiler.problem.suppressWarnings=enabled
|
||||
org.eclipse.jdt.core.compiler.problem.syntacticNullAnalysisForFields=disabled
|
||||
org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation=warning
|
||||
org.eclipse.jdt.core.compiler.problem.terminalDeprecation=warning
|
||||
org.eclipse.jdt.core.compiler.problem.typeParameterHiding=warning
|
||||
org.eclipse.jdt.core.compiler.problem.unavoidableGenericTypeProblems=disabled
|
||||
org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation=warning
|
||||
org.eclipse.jdt.core.compiler.problem.unclosedCloseable=warning
|
||||
org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=warning
|
||||
org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=warning
|
||||
org.eclipse.jdt.core.compiler.problem.unlikelyCollectionMethodArgumentType=warning
|
||||
org.eclipse.jdt.core.compiler.problem.unlikelyCollectionMethodArgumentTypeStrict=disabled
|
||||
org.eclipse.jdt.core.compiler.problem.unlikelyEqualsArgumentType=info
|
||||
org.eclipse.jdt.core.compiler.problem.unnecessaryElse=warning
|
||||
org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=warning
|
||||
org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.unstableAutoModuleName=warning
|
||||
org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=warning
|
||||
org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionExemptExceptionAndThrowable=enabled
|
||||
org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionIncludeDocCommentReference=enabled
|
||||
org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding=disabled
|
||||
org.eclipse.jdt.core.compiler.problem.unusedExceptionParameter=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.unusedImport=warning
|
||||
org.eclipse.jdt.core.compiler.problem.unusedLabel=warning
|
||||
org.eclipse.jdt.core.compiler.problem.unusedLocal=warning
|
||||
@ -85,6 +114,7 @@ org.eclipse.jdt.core.compiler.problem.unusedParameterIncludeDocCommentReference=
|
||||
org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract=disabled
|
||||
org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=disabled
|
||||
org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=warning
|
||||
org.eclipse.jdt.core.compiler.problem.unusedTypeParameter=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.unusedWarningToken=warning
|
||||
org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning
|
||||
org.eclipse.jdt.core.compiler.release=disabled
|
||||
|
7
pom.xml
7
pom.xml
@ -40,7 +40,7 @@
|
||||
<dependency>
|
||||
<groupId>commons-logging</groupId>
|
||||
<artifactId>commons-logging</artifactId>
|
||||
<version>1.1.1</version>
|
||||
<version>1.2</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
@ -48,6 +48,11 @@
|
||||
<artifactId>log4j-core</artifactId>
|
||||
<version>2.11.1</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.logging.log4j</groupId>
|
||||
<artifactId>log4j-jcl</artifactId>
|
||||
<version>2.11.1</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.joml</groupId>
|
||||
|
@ -1,6 +1,6 @@
|
||||
package morlok8k.MinecraftLandGenerator;
|
||||
|
||||
import java.nio.file.Files;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Path;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
@ -9,47 +9,33 @@ import java.util.stream.IntStream;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.apache.logging.log4j.Level;
|
||||
import org.apache.logging.log4j.core.config.Configurator;
|
||||
import org.joml.Vector2i;
|
||||
|
||||
import morlok8k.MinecraftLandGenerator.CommandLineMain.AutoSpawnpoints;
|
||||
import morlok8k.MinecraftLandGenerator.CommandLineMain.ManualSpawnpoints;
|
||||
import picocli.CommandLine;
|
||||
import picocli.CommandLine.Command;
|
||||
import picocli.CommandLine.Help.Visibility;
|
||||
import picocli.CommandLine.HelpCommand;
|
||||
import picocli.CommandLine.Option;
|
||||
import picocli.CommandLine.Parameters;
|
||||
import picocli.CommandLine.RunLast;
|
||||
|
||||
@Command(name = "mlg", subcommands = { HelpCommand.class })
|
||||
import picocli.CommandLine.ParentCommand;
|
||||
import picocli.CommandLine.RunAll;
|
||||
|
||||
@Command(name = "MinecraftLandGenerator",
|
||||
subcommands = { HelpCommand.class, ManualSpawnpoints.class, AutoSpawnpoints.class })
|
||||
public class CommandLineMain implements Runnable {
|
||||
|
||||
private static Log log = LogFactory.getLog(CommandLineMain.class);
|
||||
|
||||
@Option(names = { "-v", "--verbose" }, description = "Be verbose.")
|
||||
private boolean verbose = false;
|
||||
@Option(names = { "-r", "--region" }, description = "Regionfiles instead of chunks")
|
||||
private boolean regionFile = false;
|
||||
|
||||
@Option(names = { "-s", "--customspawn" }, description = "Customized SpawnPoints")
|
||||
private String[] customSpawnPoints;
|
||||
|
||||
@Option(names = "-i", description = "override the iteration spawn offset increment",
|
||||
defaultValue = "380", showDefaultValue = CommandLine.Help.Visibility.ALWAYS)
|
||||
private int increment = 380;
|
||||
|
||||
@Option(names = { "--x-offset", "-x" },
|
||||
description = "set the X offset to generate land around")
|
||||
private int xOffset = 0;
|
||||
|
||||
@Option(names = { "--y-offset", "-y" },
|
||||
description = "set the Z offset to generate land around")
|
||||
private int zOffset = 0;
|
||||
|
||||
@Parameters(index = "0", description = "X-coordinate")
|
||||
private int X;
|
||||
|
||||
@Parameters(index = "1", description = "Z-coordinate")
|
||||
private int Z;
|
||||
@Option(names = { "--debug-server" },
|
||||
description = "Print the Minecraft server log to stdout for debugging")
|
||||
private boolean debugServer = false;
|
||||
|
||||
@Option(names = { "-s", "--serverFile" }, description = "Path to the server's jar file.",
|
||||
defaultValue = "server.jar", showDefaultValue = Visibility.ALWAYS)
|
||||
@ -63,37 +49,117 @@ public class CommandLineMain implements Runnable {
|
||||
description = "Java command to launch the server. Defaults to `java -jar`.")
|
||||
private String[] javaOpts;
|
||||
|
||||
@Command(name = "auto-spawnpoints")
|
||||
public static class AutoSpawnpoints implements Runnable {
|
||||
|
||||
@ParentCommand
|
||||
private CommandLineMain parent;
|
||||
|
||||
@Option(names = "-i", description = "override the iteration spawn offset increment",
|
||||
defaultValue = "380", showDefaultValue = CommandLine.Help.Visibility.ALWAYS)
|
||||
private int increment = 380;
|
||||
|
||||
@Parameters(index = "0", description = "X-coordinate")
|
||||
private int x;
|
||||
@Parameters(index = "1", description = "Z-coordinate")
|
||||
private int z;
|
||||
@Parameters(index = "2", description = "Width")
|
||||
private int w;
|
||||
@Parameters(index = "3", description = "Height")
|
||||
private int h;
|
||||
|
||||
public AutoSpawnpoints() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
Server server = new Server(parent.debugServer, parent.javaOpts, parent.serverFile);
|
||||
World world;
|
||||
try {
|
||||
world = server.initWorld(parent.worldPath);
|
||||
} catch (IOException | InterruptedException e) {
|
||||
log.error("Could not initialize world", e);
|
||||
return;
|
||||
}
|
||||
|
||||
log.info("Generating world");
|
||||
server.runMinecraft(world, generateSpawnpoints(x, z, w, h, increment, 12));
|
||||
log.info("Cleaning up temporary files");
|
||||
try {
|
||||
world.resetSpawn();
|
||||
server.restoreWorld();
|
||||
} catch (IOException e) {
|
||||
log.warn(
|
||||
"Could not delete backup files (server.properties.bak and level.dat.bak). Please delete them manually",
|
||||
e);
|
||||
}
|
||||
log.info("Done.");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Command(name = "manual-spawnpoints")
|
||||
public static class ManualSpawnpoints implements Runnable {
|
||||
|
||||
@ParentCommand
|
||||
private CommandLineMain parent;
|
||||
|
||||
// @Option(names = { "-s", "--customspawn" }, description = "Customized SpawnPoints")
|
||||
// private String[] customSpawnPoints;
|
||||
|
||||
public ManualSpawnpoints() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
Server server = new Server(parent.debugServer, parent.javaOpts, parent.serverFile);
|
||||
World world;
|
||||
try {
|
||||
world = server.initWorld(parent.worldPath);
|
||||
} catch (IOException | InterruptedException e) {
|
||||
log.error("Could not initialize world", e);
|
||||
return;
|
||||
}
|
||||
List<Vector2i> spawnpoints = new ArrayList<>();
|
||||
spawnpoints.add(new Vector2i(100, 100));
|
||||
spawnpoints.add(new Vector2i(200, 100));
|
||||
spawnpoints.add(new Vector2i(300, 100));
|
||||
spawnpoints.add(new Vector2i(400, 100));
|
||||
log.info("Generating world");
|
||||
server.runMinecraft(world, spawnpoints);
|
||||
log.info("Cleaning up temporary files");
|
||||
try {
|
||||
world.resetSpawn();
|
||||
server.restoreWorld();
|
||||
} catch (IOException e) {
|
||||
log.warn(
|
||||
"Could not delete backup files (server.properties.bak and level.dat.bak). Please delete them manually",
|
||||
e);
|
||||
}
|
||||
log.info("Done.");
|
||||
}
|
||||
}
|
||||
|
||||
public CommandLineMain() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
Server server = new Server(javaOpts, serverFile);
|
||||
if (worldPath != null)
|
||||
server.setWorld(worldPath);
|
||||
else worldPath = server.getWorld();
|
||||
if (worldPath == null || !Files.exists(worldPath)) {
|
||||
log.warn(
|
||||
"No world was specified or the world at the given path does not exist. Starting the server once to create one...");
|
||||
server.runMinecraft();
|
||||
worldPath = server.getWorld();
|
||||
if (verbose) {
|
||||
Configurator.setRootLevel(Level.DEBUG);
|
||||
}
|
||||
if (worldPath == null || !Files.exists(worldPath)) {
|
||||
log.fatal("There is still no world, we cannot continue without world");
|
||||
return;
|
||||
}
|
||||
for (Vector2i spawn : generateSpawnpoints(startX, startZ, width, height, maxInc,
|
||||
generationRadius)) {
|
||||
server.setSpawn(level, spawn);
|
||||
server.runMinecraft();
|
||||
}
|
||||
server.restoreWorld();
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
/* Without this, JOML will print vectors out in scientific notation which isn't the most human readable thing in the world */
|
||||
System.setProperty("joml.format", "false");
|
||||
|
||||
args = new String[] { "-v", "--debug-server", "-s",
|
||||
"/home/piegames/Documents/GitHub/MinecraftLandGenerator/testserver/server.jar",
|
||||
"auto-spawnpoints", "200", "100", "200", "100" };
|
||||
CommandLine cli = new CommandLine(new CommandLineMain());
|
||||
cli.parseWithHandler(new RunLast(), args);
|
||||
cli.parseWithHandler(new RunAll(), args);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -8,35 +8,23 @@
|
||||
package morlok8k.MinecraftLandGenerator;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.PrintStream;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.NoSuchFileException;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.nio.file.StandardCopyOption;
|
||||
import java.nio.file.StandardOpenOption;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.joml.Vector2i;
|
||||
import org.joml.Vector3i;
|
||||
|
||||
import com.flowpowered.nbt.CompoundMap;
|
||||
import com.flowpowered.nbt.CompoundTag;
|
||||
import com.flowpowered.nbt.IntTag;
|
||||
import com.flowpowered.nbt.Tag;
|
||||
import com.flowpowered.nbt.stream.NBTInputStream;
|
||||
import com.flowpowered.nbt.stream.NBTOutputStream;
|
||||
|
||||
/**
|
||||
*
|
||||
@ -48,8 +36,10 @@ public class Server {
|
||||
|
||||
protected final ProcessBuilder builder;
|
||||
protected final Path workDir;
|
||||
protected final boolean debugServer;
|
||||
|
||||
public Server(String[] javaOpts, Path serverFile) {
|
||||
public Server(boolean debugServer, String[] javaOpts, Path serverFile) {
|
||||
this.debugServer = debugServer;
|
||||
List<String> opts = new ArrayList<>(
|
||||
Arrays.asList(javaOpts != null ? javaOpts : new String[] { "java", "-jar" }));
|
||||
opts.add(serverFile.toString());
|
||||
@ -60,6 +50,23 @@ public class Server {
|
||||
builder.directory(workDir.toFile());
|
||||
}
|
||||
|
||||
public World initWorld(Path worldPath) throws IOException, InterruptedException {
|
||||
if (worldPath != null)
|
||||
setWorld(worldPath);
|
||||
else worldPath = getWorld();
|
||||
if (worldPath == null || !Files.exists(worldPath)) {
|
||||
log.warn(
|
||||
"No world was specified or the world at the given path does not exist. Starting the server once to create one...");
|
||||
runMinecraft();
|
||||
worldPath = getWorld();
|
||||
if (!worldPath.isAbsolute()) worldPath = workDir.resolve(worldPath);
|
||||
}
|
||||
if (worldPath == null || !Files.exists(worldPath))
|
||||
throw new NoSuchFileException(String.valueOf(worldPath));
|
||||
log.debug("Using world path " + worldPath);
|
||||
return new World(worldPath);
|
||||
}
|
||||
|
||||
public void setWorld(Path worldPath) throws IOException {
|
||||
Path propsFile = workDir.resolve("server.properties");
|
||||
if (!Files.exists(propsFile)) {
|
||||
@ -79,83 +86,32 @@ public class Server {
|
||||
Properties props = new Properties();
|
||||
if (!Files.exists(propsFile)) return null;
|
||||
props.load(Files.newInputStream(propsFile));
|
||||
return Paths.get(props.getProperty("level-name"));
|
||||
if (!props.containsKey("level-name")) return null;
|
||||
log.info("Found level in server.properties: " + props.getProperty("level-name"));
|
||||
Path p = Paths.get(props.getProperty("level-name"));
|
||||
if (!p.isAbsolute()) p = workDir.resolve(p);
|
||||
return p;
|
||||
}
|
||||
|
||||
public void restoreWorld() throws IOException {
|
||||
Path propsFile = workDir.resolve("server.properties");
|
||||
Files.move(propsFile.resolveSibling("server.properties.bak"), propsFile,
|
||||
StandardCopyOption.REPLACE_EXISTING);
|
||||
if (Files.exists(propsFile.resolveSibling("server.properties.bak")))
|
||||
Files.move(propsFile.resolveSibling("server.properties.bak"), propsFile,
|
||||
StandardCopyOption.REPLACE_EXISTING);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param level
|
||||
* @return
|
||||
* @throws IOException
|
||||
* @author Corrodias
|
||||
*/
|
||||
protected static Vector3i getSpawn(final File level) throws IOException {
|
||||
try (NBTInputStream input = new NBTInputStream(new FileInputStream(level));) {
|
||||
final CompoundTag levelTag = (CompoundTag) input.readTag();
|
||||
final Map<String, Tag<?>> levelData =
|
||||
((CompoundTag) levelTag.getValue().get("Data")).getValue();
|
||||
|
||||
final IntTag spawnX = (IntTag) levelData.get("SpawnX");
|
||||
final IntTag spawnY = (IntTag) levelData.get("SpawnY");
|
||||
final IntTag spawnZ = (IntTag) levelData.get("SpawnZ");
|
||||
|
||||
return new Vector3i(spawnX.getValue(), spawnY.getValue(), spawnZ.getValue());
|
||||
} catch (final ClassCastException | NullPointerException ex) {
|
||||
throw new IOException("Invalid level format.");
|
||||
}
|
||||
}
|
||||
|
||||
protected static void setSpawn(Path world, Vector2i chunkSpawn) throws IOException {
|
||||
setSpawn(world.resolve("level.dat").toFile(),
|
||||
new Vector3i(chunkSpawn.x << 4 | 7, 64, chunkSpawn.y << 4 | 8));
|
||||
}
|
||||
|
||||
/**
|
||||
* Changes the spawn point in the given Alpha/Beta level to the given coordinates.<br>
|
||||
* Note that, in Minecraft levels, the Y coordinate is height.<br>
|
||||
* (We picture maps from above, but the game was made from a different perspective)
|
||||
*
|
||||
* @param level
|
||||
* the level file to change the spawn point in
|
||||
* @param xyz
|
||||
* the Coordinates of the spawn point
|
||||
* @throws IOException
|
||||
* if there are any problems reading/writing the file
|
||||
* @author Corrodias
|
||||
*/
|
||||
protected static void setSpawn(final File level, final Vector3i xyz) throws IOException {
|
||||
// TODO clean this up even more
|
||||
try (NBTInputStream input = new NBTInputStream(new FileInputStream(level));) {
|
||||
final CompoundTag originalTopLevelTag = (CompoundTag) input.readTag();
|
||||
input.close();
|
||||
|
||||
final Map<String, Tag<?>> originalData =
|
||||
((CompoundTag) originalTopLevelTag.getValue().get("Data")).getValue();
|
||||
// This is our map of data. It is an unmodifiable map, for some reason, so we have to make a copy.
|
||||
final Map<String, Tag<?>> newData = new LinkedHashMap<>(originalData);
|
||||
|
||||
newData.put("SpawnX", new IntTag("SpawnX", xyz.x)); // pulling the data out of the Coordinates,
|
||||
newData.put("SpawnY", new IntTag("SpawnY", xyz.y)); // and putting it into our IntTag's
|
||||
newData.put("SpawnZ", new IntTag("SpawnZ", xyz.z));
|
||||
|
||||
// Again, we can't modify the data map in the old Tag, so we have to make a new one.
|
||||
final CompoundTag newDataTag = new CompoundTag("Data", new CompoundMap(newData));
|
||||
final Map<String, Tag<?>> newTopLevelMap = new HashMap<>(1);
|
||||
newTopLevelMap.put("Data", newDataTag);
|
||||
final CompoundTag newTopLevelTag = new CompoundTag("", new CompoundMap(newTopLevelMap));
|
||||
|
||||
final NBTOutputStream output = new NBTOutputStream(new FileOutputStream(level));
|
||||
output.writeTag(newTopLevelTag);
|
||||
output.close();
|
||||
} catch (final ClassCastException ex) {
|
||||
throw new IOException("Invalid level format.");
|
||||
} catch (final NullPointerException ex) {
|
||||
throw new IOException("Invalid level format.");
|
||||
public void runMinecraft(World world, List<Vector2i> spawnpoints) {
|
||||
log.debug("All spawn points: " + spawnpoints);
|
||||
for (int i = 0; i < spawnpoints.size(); i++) {
|
||||
Vector2i spawn = spawnpoints.get(i);
|
||||
try {
|
||||
log.info("Processing " + i + "/" + spawnpoints.size() + ", spawn point " + spawn);
|
||||
world.setSpawn(spawn);
|
||||
runMinecraft();
|
||||
} catch (IOException | InterruptedException e) {
|
||||
log.warn("Could not process spawn point " + spawn
|
||||
+ " this part of the world don't be generated", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -168,6 +124,9 @@ public class Server {
|
||||
* @author Corrodias, Morlok8k, piegames
|
||||
*/
|
||||
public void runMinecraft() throws IOException, InterruptedException {
|
||||
log.debug("Setting EULA");
|
||||
Files.write(workDir.resolve("eula.txt"), "eula=true".getBytes(), StandardOpenOption.CREATE,
|
||||
StandardOpenOption.TRUNCATE_EXISTING, StandardOpenOption.WRITE);
|
||||
log.info("Starting server");
|
||||
final Process process = builder.start();
|
||||
|
||||
@ -175,7 +134,7 @@ public class Server {
|
||||
new BufferedReader(new InputStreamReader(process.getInputStream()));
|
||||
for (String line = pOut.readLine(); line != null; line = pOut.readLine()) {
|
||||
line = line.trim();
|
||||
if (log.isDebugEnabled()) log.debug(line);
|
||||
if (debugServer) System.out.println(line);
|
||||
|
||||
if (line.contains("Done")) {
|
||||
PrintStream out = new PrintStream(process.getOutputStream());
|
||||
|
90
src/main/java/morlok8k/MinecraftLandGenerator/World.java
Normal file
90
src/main/java/morlok8k/MinecraftLandGenerator/World.java
Normal file
@ -0,0 +1,90 @@
|
||||
package morlok8k.MinecraftLandGenerator;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.StandardCopyOption;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.joml.Vector2i;
|
||||
import org.joml.Vector3i;
|
||||
|
||||
import com.flowpowered.nbt.CompoundMap;
|
||||
import com.flowpowered.nbt.CompoundTag;
|
||||
import com.flowpowered.nbt.IntTag;
|
||||
import com.flowpowered.nbt.Tag;
|
||||
import com.flowpowered.nbt.stream.NBTInputStream;
|
||||
import com.flowpowered.nbt.stream.NBTOutputStream;
|
||||
|
||||
public class World {
|
||||
private static Log log = LogFactory.getLog(World.class);
|
||||
|
||||
public final Path world;
|
||||
|
||||
public World(Path world) throws IOException {
|
||||
this.world = Objects.requireNonNull(world);
|
||||
Files.copy(world.resolve("level.dat"), world.resolve("level.dat.bak"));
|
||||
}
|
||||
|
||||
public void resetSpawn() throws IOException {
|
||||
if (Files.exists(world.resolve("level.dat.bak"))) Files.move(world.resolve("level.dat.bak"),
|
||||
world.resolve("level.dat"), StandardCopyOption.REPLACE_EXISTING);
|
||||
}
|
||||
|
||||
public void setSpawn(Vector2i chunkSpawn) throws IOException {
|
||||
setSpawn(new Vector3i(chunkSpawn.x << 4 | 7, 64, chunkSpawn.y << 4 | 8));
|
||||
}
|
||||
|
||||
/**
|
||||
* Changes the spawn point in the given Alpha/Beta level to the given coordinates.<br>
|
||||
* Note that, in Minecraft levels, the Y coordinate is height.<br>
|
||||
* (We picture maps from above, but the game was made from a different perspective)
|
||||
*
|
||||
* @param level
|
||||
* the level file to change the spawn point in
|
||||
* @param xyz
|
||||
* the Coordinates of the spawn point
|
||||
* @throws IOException
|
||||
* if there are any problems reading/writing the file
|
||||
* @author Corrodias
|
||||
*/
|
||||
public void setSpawn(final Vector3i xyz) throws IOException {
|
||||
log.debug("Setting spawn to " + xyz);
|
||||
// TODO clean this up even more
|
||||
try (NBTInputStream input =
|
||||
new NBTInputStream(Files.newInputStream(world.resolve("level.dat")));) {
|
||||
final CompoundTag originalTopLevelTag = (CompoundTag) input.readTag();
|
||||
input.close();
|
||||
|
||||
final Map<String, Tag<?>> originalData =
|
||||
((CompoundTag) originalTopLevelTag.getValue().get("Data")).getValue();
|
||||
// This is our map of data. It is an unmodifiable map, for some reason, so we have to make a copy.
|
||||
final Map<String, Tag<?>> newData = new LinkedHashMap<>(originalData);
|
||||
|
||||
newData.put("SpawnX", new IntTag("SpawnX", xyz.x)); // pulling the data out of the Coordinates,
|
||||
newData.put("SpawnY", new IntTag("SpawnY", xyz.y)); // and putting it into our IntTag's
|
||||
newData.put("SpawnZ", new IntTag("SpawnZ", xyz.z));
|
||||
|
||||
// Again, we can't modify the data map in the old Tag, so we have to make a new one.
|
||||
final CompoundTag newDataTag = new CompoundTag("Data", new CompoundMap(newData));
|
||||
final Map<String, Tag<?>> newTopLevelMap = new HashMap<>(1);
|
||||
newTopLevelMap.put("Data", newDataTag);
|
||||
final CompoundTag newTopLevelTag = new CompoundTag("", new CompoundMap(newTopLevelMap));
|
||||
|
||||
try (NBTOutputStream output =
|
||||
new NBTOutputStream(Files.newOutputStream(world.resolve("level.dat")));) {
|
||||
output.writeTag(newTopLevelTag);
|
||||
output.close();
|
||||
}
|
||||
} catch (final ClassCastException ex) {
|
||||
throw new IOException("Invalid level format.");
|
||||
} catch (final NullPointerException ex) {
|
||||
throw new IOException("Invalid level format.");
|
||||
}
|
||||
}
|
||||
}
|
13
src/main/resources/log4j2.properties
Normal file
13
src/main/resources/log4j2.properties
Normal file
@ -0,0 +1,13 @@
|
||||
appenders=xyz
|
||||
|
||||
appender.xyz.type = Console
|
||||
appender.xyz.name = myOutput
|
||||
appender.xyz.layout.type = PatternLayout
|
||||
appender.xyz.layout.pattern = %d{yy-MM-dd HH:mm:ss} %-5p %c{1} [%L] - %m%n
|
||||
|
||||
rootLogger.level = info
|
||||
|
||||
rootLogger.appenderRefs = abc
|
||||
|
||||
rootLogger.appenderRef.abc.ref = myOutput
|
||||
|
Reference in New Issue
Block a user