add import/load command
This commit is contained in:
parent
96fb940087
commit
614e859146
9 changed files with 178 additions and 32 deletions
|
@ -10,9 +10,11 @@ import common.log.Log;
|
|||
import common.rng.PerlinGen;
|
||||
import common.rng.Random;
|
||||
import common.util.BlockPos;
|
||||
import common.util.Displayable;
|
||||
import common.util.ExtMath;
|
||||
import common.util.Identifyable;
|
||||
|
||||
public enum Biome {
|
||||
public enum Biome implements Identifyable, Displayable {
|
||||
NONE(0, "none", "<Keins>", 0x000000),
|
||||
PLAINS(1, "plains", "Ebene", 0x8db360, 12.0f, 40.0f),
|
||||
DESERT(2, "desert", "Wüste", 0xfa9418, 60.0f, 0.0f),
|
||||
|
@ -232,4 +234,12 @@ public enum Biome {
|
|||
double d1 = (double)ExtMath.clampf(this.humidity * 0.01f, 0.0F, 1.0F);
|
||||
return Colorizer.getFoliageColor(d0, d1);
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return this.name;
|
||||
}
|
||||
|
||||
public String getDisplay() {
|
||||
return this.display;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -92,6 +92,7 @@ public abstract class UniverseRegistry {
|
|||
Dimension dim = Dimension.getByTag(list.get(z));
|
||||
if(!REGISTRY.containsKey(dim.getDimensionId()) && !ALIASES.containsKey(dim.getDimensionName()))
|
||||
register(dim);
|
||||
nextDimId = dim.getDimensionId() + 1 > nextDimId ? dim.getDimensionId() + 1 : nextDimId;
|
||||
}
|
||||
|
||||
list = tag.getList("Names");
|
||||
|
@ -253,6 +254,7 @@ public abstract class UniverseRegistry {
|
|||
|
||||
public static Planet registerPlanet(String star, String name, String custom, int sky, int fog, int clouds, long orbit, long rotation,
|
||||
float offset, float gravity, float temperature, int brightness) {
|
||||
star = star == null ? new Random().pick(Lists.newArrayList(STAR_MAP.keySet())).getDimensionName() : star;
|
||||
if(!ALIASES.containsKey(star) || ALIASES.get(star).getType() != DimType.STAR || ALIASES.containsKey(name))
|
||||
return null;
|
||||
Planet dim = new Planet(nextDimId++, name, sky, fog, clouds, orbit, rotation, offset, gravity, temperature, brightness);
|
||||
|
|
|
@ -103,7 +103,6 @@ import server.network.Player;
|
|||
import server.network.User;
|
||||
import server.vars.SVar;
|
||||
import server.vars.SVars;
|
||||
import server.world.Converter;
|
||||
import server.world.Region;
|
||||
import server.world.WorldServer;
|
||||
|
||||
|
@ -405,7 +404,6 @@ public final class Server implements IThreadListener, Executor {
|
|||
|
||||
public void run(long time) {
|
||||
Region.loadMap();
|
||||
Converter.convert("terra");
|
||||
long wtime = this.loadServerConfig();
|
||||
if(this.keyPair == null) {
|
||||
Log.SYSTEM.info("Generiere neues Schlüsselpaar");
|
||||
|
|
|
@ -6,6 +6,10 @@ import java.util.List;
|
|||
import common.collect.Lists;
|
||||
|
||||
public abstract class ArgumentParser {
|
||||
public static String escape(String str) {
|
||||
return str.replace("\\", "\\\\").replace(" ", "\\ ").replace("\"", "\\\"").replace(";", "\\;");
|
||||
}
|
||||
|
||||
public static String[][] splitString(String str) {
|
||||
// if(str.isEmpty()) {
|
||||
// return new String[0];
|
||||
|
|
|
@ -120,6 +120,22 @@ public abstract class Command implements Executable {
|
|||
return this.addParameter(new IntParser(name, false, def, min, max, def));
|
||||
}
|
||||
|
||||
protected Command addLong(String name, char shortName, long min, long max, long def) {
|
||||
return this.addParameter(shortName, new LongParser(name, def, min, max, def));
|
||||
}
|
||||
|
||||
protected Command addLong(String name, long min, long max, long def) {
|
||||
return this.addParameter(new LongParser(name, def, min, max, def));
|
||||
}
|
||||
|
||||
protected Command addColor(String name, char shortName, int def) {
|
||||
return this.addParameter(shortName, new ColorParser(name, def));
|
||||
}
|
||||
|
||||
protected Command addColor(String name, int def) {
|
||||
return this.addParameter(new ColorParser(name, def));
|
||||
}
|
||||
|
||||
protected Command addDouble(String name, char shortName, double min, double max, double def) {
|
||||
return this.addParameter(shortName, new DoubleParser(name, def, min, max, false, def));
|
||||
}
|
||||
|
@ -240,6 +256,14 @@ public abstract class Command implements Executable {
|
|||
return this.addParameter(new StringParser(name, null, allowEmpty, null, null, null, completions));
|
||||
}
|
||||
|
||||
protected Command addString(String name, char shortName, boolean allowEmpty, Object ... completions) {
|
||||
return this.addParameter(shortName, new StringParser(name, null, allowEmpty, null, null, null, completions));
|
||||
}
|
||||
|
||||
protected Command addString(String name, char shortName, boolean allowEmpty, StringCompleter completer) {
|
||||
return this.addParameter(shortName, new StringParser(name, null, allowEmpty, null, null, null, completer));
|
||||
}
|
||||
|
||||
protected Command addString(String name, boolean allowEmpty, StringCompleter completer) {
|
||||
return this.addParameter(new StringParser(name, null, allowEmpty, null, null, null, completer));
|
||||
}
|
||||
|
|
|
@ -270,5 +270,6 @@ public class CommandEnvironment {
|
|||
this.registerExecutable(new CommandMore());
|
||||
this.registerExecutable(new CommandReturn());
|
||||
this.registerExecutable(new CommandDeathspot());
|
||||
this.registerExecutable(new CommandLoad());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,96 @@
|
|||
package server.command.commands;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.Arrays;
|
||||
|
||||
import common.biome.Biome;
|
||||
import common.collect.Iterables;
|
||||
import common.collect.Lists;
|
||||
import common.color.TextColor;
|
||||
import common.dimension.Planet;
|
||||
import common.dimension.Star;
|
||||
import common.init.UniverseRegistry;
|
||||
import server.command.ArgumentParser;
|
||||
import server.command.Command;
|
||||
import server.command.CommandEnvironment;
|
||||
import server.command.Executor;
|
||||
import server.command.RunException;
|
||||
import server.network.Player;
|
||||
import server.world.Converter;
|
||||
|
||||
public class CommandLoad extends Command {
|
||||
private static final File IMPORTS_DIR = new File("import");
|
||||
|
||||
private String loadingDim;
|
||||
|
||||
public CommandLoad() {
|
||||
super("load");
|
||||
|
||||
this.addString("name", false, null, null, ch -> (ch >= 'a' && ch <= 'z') || (ch >= '0' && ch <= '9') || ch == '_');
|
||||
this.addString("display", false);
|
||||
this.setParamsOptional();
|
||||
this.addString("star", false);
|
||||
this.addEnum("biome", Biome.DEF_BIOME, Biome.class, Biome.values());
|
||||
this.addString("convert", 'c', false, (env, last) -> {
|
||||
File[] list = IMPORTS_DIR.listFiles(file -> file.isDirectory());
|
||||
if(list != null)
|
||||
Arrays.sort(list);
|
||||
return list == null ? Lists.newArrayList() : Lists.newArrayList(Iterables.transform(Lists.newArrayList(list), file -> ArgumentParser.escape(file.getName())));
|
||||
});
|
||||
this.addFlag("teleport", 't');
|
||||
this.addColor("sky", 's', 0xffffffff);
|
||||
this.addColor("fog", 'f', 0xc0d8ff);
|
||||
this.addColor("clouds", 'w', 0xffffff);
|
||||
this.addLong("orbit", 'o', 1L, 1000000000000L, UniverseRegistry.EARTH_YEAR);
|
||||
this.addLong("rotation", 'r', 1L, 1000000000000L, 24000L);
|
||||
this.addDouble("offset", 'm', 0.0, 100000.0, 0.0);
|
||||
this.addDouble("gravity", 'g', 0.0, 100000.0, 9.81);
|
||||
this.addDouble("temperature", 'k', 0.0, 100000.0, 259.15);
|
||||
this.addInt("brightness", 'b', 0, 15, 0);
|
||||
}
|
||||
|
||||
public void exec(CommandEnvironment env, Executor exec, String name, String display, String star, Biome biome, String convert, boolean teleport, int sky, int fog, int clouds,
|
||||
long orbit, long rotation, double offset, double gravity, double temperature, int brightness) {
|
||||
if(teleport && !exec.isPlayer())
|
||||
throw new RunException("Nur Spieler können teleportiert werden");
|
||||
if(UniverseRegistry.getDimension(name) != null)
|
||||
throw new RunException("Dimension '%s' existiert bereits", name);
|
||||
if(name.equals(this.loadingDim))
|
||||
throw new RunException("Dimension '%s' wird gerade geladen", name);
|
||||
if(star != null && !(UniverseRegistry.getDimension(star) instanceof Star))
|
||||
throw new RunException("'%s' ist kein Stern", star);
|
||||
if(convert != null) {
|
||||
File dir = new File(IMPORTS_DIR, convert);
|
||||
if(!IMPORTS_DIR.equals(dir.getParentFile()))
|
||||
throw new RunException("Welt %s muss ein direkter Unterordner von %s/ sein", convert, IMPORTS_DIR);
|
||||
if(!dir.exists()) {
|
||||
IMPORTS_DIR.mkdirs();
|
||||
throw new RunException("Welt %s existiert nicht", dir);
|
||||
}
|
||||
this.loadingDim = name;
|
||||
if(Converter.convert(dir, name, pos -> env.getServer().schedule(() -> {
|
||||
Planet planet = UniverseRegistry.registerPlanet(star, name, display, sky, fog, clouds, orbit, rotation, (float)offset, (float)gravity, (float)temperature, brightness);
|
||||
planet.setBiome(biome);
|
||||
this.loadingDim = null;
|
||||
exec.log(TextColor.GREEN + "Welt %s wurde erfolgreich in Dimension '%s' konvertiert", dir, display);
|
||||
if(teleport && pos != null) {
|
||||
Player player = env.getServer().getPlayer(((Player)exec).getUser());
|
||||
if(player != null && player.getPresentEntity() != null)
|
||||
player.getPresentEntity().teleport(CommandWorld.adjust(env.getServer().getWorld(planet.getDimensionId()), pos), planet.getDimensionId());
|
||||
}
|
||||
})) == null) {
|
||||
this.loadingDim = null;
|
||||
throw new RunException("Welt %s konnte nicht konvertiert werden", dir);
|
||||
}
|
||||
else {
|
||||
exec.log(TextColor.ACID + "Welt %s wird in Dimension '%s' konvertiert ...", dir, display);
|
||||
}
|
||||
return;
|
||||
}
|
||||
Planet planet = UniverseRegistry.registerPlanet(star, name, display, sky, fog, clouds, orbit, rotation, (float)offset, (float)gravity, (float)temperature, brightness);
|
||||
planet.setBiome(biome);
|
||||
exec.log(TextColor.GREEN + "Dimension '%s' wurde registriert", display);
|
||||
if(teleport && ((Player)exec).getPresentEntity() != null)
|
||||
((Player)exec).getPresentEntity().teleport(CommandWorld.adjust(env.getServer().getWorld(planet.getDimensionId()), ((Player)exec).getPresentEntity().getPosition()), planet.getDimensionId());
|
||||
}
|
||||
}
|
|
@ -21,20 +21,24 @@ public class CommandWorld extends Command {
|
|||
|
||||
public Object exec(CommandEnvironment env, Executor exec, WorldServer world, List<Entity> entities) {
|
||||
for(Entity entity : entities) {
|
||||
BlockPos pos = entity.getPosition();
|
||||
pos = pos.getY() < 0 ? new BlockPos(pos.getX(), 0, pos.getZ()) : pos;
|
||||
if(world.getState(pos).getBlock().getMaterial().blocksMovement() || world.getState(pos).getBlock().getMaterial().isLiquid()) {
|
||||
while((world.getState(pos).getBlock().getMaterial().blocksMovement() || world.getState(pos).getBlock().getMaterial().isLiquid()) && pos.getY() < 511)
|
||||
pos = pos.up();
|
||||
}
|
||||
else {
|
||||
while(!(world.getState(pos).getBlock().getMaterial().blocksMovement() || world.getState(pos).getBlock().getMaterial().isLiquid()) && pos.getY() > 0)
|
||||
pos = pos.down();
|
||||
pos = pos.up();
|
||||
}
|
||||
BlockPos pos = adjust(world, entity.getPosition());
|
||||
entity.teleport(pos, world.dimension.getDimensionId());
|
||||
exec.log("%s nach %d, %d, %d in %s teleportiert", entity.getCommandName(), pos.getX(), pos.getY(), pos.getZ(), world.dimension.getFormattedName(false));
|
||||
}
|
||||
return entities.size();
|
||||
}
|
||||
|
||||
public static BlockPos adjust(WorldServer world, BlockPos pos) {
|
||||
pos = pos.getY() < 0 ? new BlockPos(pos.getX(), 0, pos.getZ()) : pos;
|
||||
if(world.getState(pos).getBlock().getMaterial().blocksMovement() || world.getState(pos).getBlock().getMaterial().isLiquid()) {
|
||||
while((world.getState(pos).getBlock().getMaterial().blocksMovement() || world.getState(pos).getBlock().getMaterial().isLiquid()) && pos.getY() < 511)
|
||||
pos = pos.up();
|
||||
}
|
||||
else {
|
||||
while(!(world.getState(pos).getBlock().getMaterial().blocksMovement() || world.getState(pos).getBlock().getMaterial().isLiquid()) && pos.getY() > 0)
|
||||
pos = pos.down();
|
||||
pos = pos.up();
|
||||
}
|
||||
return pos;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,6 +13,7 @@ import java.util.ArrayList;
|
|||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.zip.GZIPInputStream;
|
||||
import java.util.zip.InflaterInputStream;
|
||||
|
||||
|
@ -2034,12 +2035,12 @@ public abstract class Converter {
|
|||
return start;
|
||||
}
|
||||
|
||||
public static BlockPos convert(String dest) {
|
||||
if(new File("server.cdt").exists())
|
||||
public static BlockPos convert(File dir, String dest, Consumer<BlockPos> finish) {
|
||||
if(new File(dir, "server.cdt").exists())
|
||||
return null;
|
||||
File ldat = new File("level.dat");
|
||||
File ldat = new File(dir, "level.dat");
|
||||
if(!ldat.exists())
|
||||
ldat = new File("level.dat_old");
|
||||
ldat = new File(dir, "level.dat_old");
|
||||
if(!ldat.exists())
|
||||
return null;
|
||||
Log.IO.info("Welt wird konvertiert ...");
|
||||
|
@ -2073,7 +2074,7 @@ public abstract class Converter {
|
|||
Log.IO.warn("Konvertiere keine Chunk-Daten, da Version zu neu (%s)", ver);
|
||||
return null;
|
||||
}
|
||||
File regionDir = new File("region");
|
||||
File regionDir = new File(dir, "region");
|
||||
if(!regionDir.exists()) {
|
||||
Log.IO.info("Kein Ordner region/ gefunden");
|
||||
return null;
|
||||
|
@ -2093,19 +2094,25 @@ public abstract class Converter {
|
|||
if(ver == SaveVersion.RELEASE_1_9)
|
||||
Log.IO.warn("Konvertiere von neuerer Version, dies wird Blöcke entfernen ...");
|
||||
chunkDir.mkdirs();
|
||||
int progress = 0;
|
||||
long time = System.currentTimeMillis();
|
||||
long start = postProgress(time, 0);
|
||||
for(File file : files) {
|
||||
int percent = (int)Math.round(100.0D * (double)progress / (double)files.length);
|
||||
Log.IO.info("Konvertiere Chunk-Daten: " + file.getName() + " (" + progress + "/" + files.length + ")");
|
||||
start = convertChunks(chunkDir, file, start, progress, files.length);
|
||||
++progress;
|
||||
start = postProgress(start, percent);
|
||||
}
|
||||
time = System.currentTimeMillis() - time;
|
||||
Log.IO.info("Fertig. Konversion dauerte " + ((time / 60000L) > 0 ? ((time / 60000L) + " Minuten und ") : "") + ((time / 1000L) % 60L) + " Sekunden.");
|
||||
BlockPos pos = new BlockPos(tag.getInt("SpawnX"), tag.getInt("SpawnY"), tag.getInt("SpawnZ"));
|
||||
new Thread(new Runnable() {
|
||||
public void run() {
|
||||
int progress = 0;
|
||||
long time = System.currentTimeMillis();
|
||||
long start = postProgress(time, 0);
|
||||
for(File file : files) {
|
||||
int percent = (int)Math.round(100.0D * (double)progress / (double)files.length);
|
||||
Log.IO.info("Konvertiere Chunk-Daten: " + file.getName() + " (" + progress + "/" + files.length + ")");
|
||||
start = convertChunks(chunkDir, file, start, progress, files.length);
|
||||
++progress;
|
||||
start = postProgress(start, percent);
|
||||
}
|
||||
time = System.currentTimeMillis() - time;
|
||||
Log.IO.info("Fertig. Konversion dauerte " + ((time / 60000L) > 0 ? ((time / 60000L) + " Minuten und ") : "") + ((time / 1000L) % 60L) + " Sekunden.");
|
||||
finish.accept(pos);
|
||||
}
|
||||
}, "Chunk converter " + dest + " thread").start();
|
||||
Log.IO.info("Einstiegspunkt: /tele %d %d %d %s", tag.getInt("SpawnX"), tag.getInt("SpawnY"), tag.getInt("SpawnZ"), dest);
|
||||
return new BlockPos(tag.getInt("SpawnX"), tag.getInt("SpawnY"), tag.getInt("SpawnZ"));
|
||||
return pos;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue