diff --git a/client/src/main/java/client/Client.java b/client/src/main/java/client/Client.java index 11a33185..352ff638 100755 --- a/client/src/main/java/client/Client.java +++ b/client/src/main/java/client/Client.java @@ -285,6 +285,7 @@ public class Client implements IThreadListener { private final class WorldClient extends World { public WorldClient(Dimension dim) { super(dim, true); + this.daytime = dim.getTimeOffset(); this.calculateInitialSkylight(); this.calculateInitialWeather(); this.updatePhysics(); diff --git a/common/src/main/java/common/dimension/Dimension.java b/common/src/main/java/common/dimension/Dimension.java index dae96c1d..434c9aac 100755 --- a/common/src/main/java/common/dimension/Dimension.java +++ b/common/src/main/java/common/dimension/Dimension.java @@ -92,6 +92,7 @@ public abstract class Dimension extends Section { private long seed = 0L; private boolean exterminated = false; private long timeExisted = 0L; + private long timeOffset = 0L; private Weather weather = this.defaultWeather; protected Dimension(boolean custom) { @@ -113,6 +114,10 @@ public abstract class Dimension extends Section { this.timeExisted = time; } + public final void setTimeOffset(long time) { + this.timeOffset = time; + } + public final void setCurrentWeather(Weather weather) { this.weather = weather; } @@ -130,6 +135,10 @@ public abstract class Dimension extends Section { return this.timeExisted; } + public final long getTimeOffset() { + return this.timeOffset; + } + public final Weather getCurrentWeather() { return this.weather; } @@ -435,10 +444,11 @@ public abstract class Dimension extends Section { return dim; } - public final TagObject writeData(boolean send) { + public final TagObject writeData(boolean send, long offset) { TagObject tag = new TagObject(); tag.setLong("Seed", this.seed); tag.setLong("Time", this.timeExisted); + tag.setLong("Offset", offset); if(this == Space.INSTANCE) return tag; tag.setBool("Exterminated", this.exterminated); @@ -452,6 +462,7 @@ public abstract class Dimension extends Section { public final void readData(TagObject tag) { this.seed = tag.getLong("Seed"); this.timeExisted = tag.getLong("Time"); + this.timeOffset = tag.getLong("Offset"); if(this == Space.INSTANCE) return; this.exterminated = tag.getBool("Exterminated"); diff --git a/common/src/main/java/common/packet/SPacketJoinGame.java b/common/src/main/java/common/packet/SPacketJoinGame.java index 9c00beff..01abb013 100755 --- a/common/src/main/java/common/packet/SPacketJoinGame.java +++ b/common/src/main/java/common/packet/SPacketJoinGame.java @@ -14,8 +14,8 @@ public class SPacketJoinGame extends SPacketRespawn { } @Serverside - public SPacketJoinGame(int id, Dimension dim, String name, int type, boolean editor) { - super(dim, name, type, editor); + public SPacketJoinGame(int id, Dimension dim, long time, String name, int type, boolean editor) { + super(dim, time, name, type, editor); this.entityId = id; } diff --git a/common/src/main/java/common/packet/SPacketRespawn.java b/common/src/main/java/common/packet/SPacketRespawn.java index 167d5858..c6db024e 100755 --- a/common/src/main/java/common/packet/SPacketRespawn.java +++ b/common/src/main/java/common/packet/SPacketRespawn.java @@ -27,10 +27,10 @@ public class SPacketRespawn implements Packet { } @Serverside - public SPacketRespawn(Dimension dim, String name, int type, boolean editor) { + public SPacketRespawn(Dimension dim, long time, String name, int type, boolean editor) { if(dim != null) { this.dimType = dim.getType(); - this.dimData = dim.writeData(true); + this.dimData = dim.writeData(true, time); if(this.dimType == DimType.PLANET || this.dimType == DimType.MOON) { this.sunColor = dim.getSunColor(); this.moonColors = dim.getMoonColors(); diff --git a/server/src/main/java/server/Server.java b/server/src/main/java/server/Server.java index 1e8d8dd3..ccbe1192 100755 --- a/server/src/main/java/server/Server.java +++ b/server/src/main/java/server/Server.java @@ -344,9 +344,8 @@ public final class Server implements IThreadListener, Executor { tag.setList("Dimensions", list); } - private void saveServerConfig(long time) { + private void saveServerConfig() { TagObject tag = new TagObject(); - tag.setLong("Time", time); tag.setLong("LastAccess", System.currentTimeMillis()); tag.setString("Version", Util.VERSION); TagObject cfg = new TagObject(); @@ -375,7 +374,7 @@ public final class Server implements IThreadListener, Executor { } } - private long loadServerConfig() { + private void loadServerConfig() { File file = new File("server.cdt"); if(!file.exists()) file = new File("server.cdt.tmp"); @@ -392,9 +391,7 @@ public final class Server implements IThreadListener, Executor { long lastPlayed = tag.getLong("LastAccess"); String version = tag.hasString("Version") ? tag.getString("Version") : null; version = version != null && version.isEmpty() ? "" : version; - long time = tag.hasLong("Time") ? tag.getLong("Time") : World.START_TIME; Log.IO.info("Config-Version: %s", version); - Log.IO.info("Weltzeit: %d Ticks / %d Sekunden", time, time / 20L); Log.IO.info("Zuletzt geladen: %s", new SimpleDateFormat("dd.MM.yyyy HH:mm:ss").format(new Date(lastPlayed))); if(System.getProperty("server.regenkey") == null && tag.hasByteArray("PrivateKey") && tag.hasByteArray("PublicKey")) { PrivateKey key = EncryptUtil.decodePrivateKey(tag.getByteArray("PrivateKey")); @@ -402,7 +399,7 @@ public final class Server implements IThreadListener, Executor { if(key != null && pubkey != null) this.keyPair = new KeyPair(pubkey, key); } - return time; + return; } catch(Exception e) { Log.IO.error(e, "Fehler beim Lesen von " + file); @@ -412,7 +409,6 @@ public final class Server implements IThreadListener, Executor { } } Log.IO.info("Erstelle neue Welt und Konfiguration"); - return World.START_TIME; } private void loadDimension(Dimension dim) { @@ -437,7 +433,7 @@ public final class Server implements IThreadListener, Executor { } private void saveDimension(Dimension dim) { - TagObject tag = dim.writeData(false); + TagObject tag = dim.writeData(false, dim == Space.INSTANCE ? this.space.getDayTime() : dim.getTimeOffset()); File file = new File(new File(new File("chunk"), UniverseRegistry.getName(dim)), "data.cdt"); try { file.getParentFile().mkdirs(); @@ -598,7 +594,7 @@ public final class Server implements IThreadListener, Executor { } public void saveWorldInfo() { - this.saveServerConfig(this.space.getDayTime()); + this.saveServerConfig(); for(Dimension dim : UniverseRegistry.getDimensions()) { this.saveDimension(dim); } @@ -678,7 +674,7 @@ public final class Server implements IThreadListener, Executor { public void run(long time) { Region.loadMap(); - long wtime = this.loadServerConfig(); + this.loadServerConfig(); for(Dimension dim : UniverseRegistry.getDimensions()) { this.loadDimension(dim); } @@ -688,7 +684,7 @@ public final class Server implements IThreadListener, Executor { this.keyPair = EncryptUtil.createKeypair(); } User.loadDatabase(this.users); - this.worlds.add(this.space = new WorldServer(this, wtime, Space.INSTANCE, UniverseRegistry.getGenerator(Space.INSTANCE))); + this.worlds.add(this.space = new WorldServer(this, 0L, Space.INSTANCE, UniverseRegistry.getGenerator(Space.INSTANCE))); this.dimensions.put(UniverseRegistry.getId(this.space.dimension), this.space); new File("players").mkdirs(); this.setTpsTarget(20.0f); @@ -809,7 +805,7 @@ public final class Server implements IThreadListener, Executor { } if(++this.syncTimer == 20) { for(Player conn : this.players) { - this.sendPacket(new SPacketTimeUpdate(this.space.getDayTime(), Dimensions.formatTime(conn.getPresentEntity() == null ? this.space : (WorldServer)conn.getPresentEntity().worldObj, conn.getPresentEntity(), true), this.getInfo())); + this.sendPacket(new SPacketTimeUpdate((conn.getPresentEntity() == null ? this.space : conn.getPresentEntity().worldObj).getDayTime(), Dimensions.formatTime(conn.getPresentEntity() == null ? this.space : (WorldServer)conn.getPresentEntity().worldObj, conn.getPresentEntity(), true), this.getInfo())); } this.syncTimer = 0; } @@ -1016,7 +1012,7 @@ public final class Server implements IThreadListener, Executor { } conn.sendPacket(new SPacketServerConfig(vars)); conn.sendPacket(new SPacketDimensions(Dimensions.getDimensionData())); - conn.sendPacket(new SPacketJoinGame(player.getId(), world.dimension, UniverseRegistry.getName(world.dimension), EntityRegistry.getEntityID(player), tag == null)); + conn.sendPacket(new SPacketJoinGame(player.getId(), world.dimension, world.getDayTime(), UniverseRegistry.getName(world.dimension), EntityRegistry.getEntityID(player), tag == null)); conn.sendPacket(new SPacketHeldItemChange(player.getSelectedIndex())); this.sendPacket(new SPacketPlayerListItem(false, conn)); @@ -1151,7 +1147,7 @@ public final class Server implements IThreadListener, Executor { nplayer.setPosition(nplayer.posX, nplayer.posY + 1.0D, nplayer.posZ); } } - conn.sendPacket(new SPacketRespawn(world.dimension != oldWorld.dimension ? world.dimension : null, world.dimension != oldWorld.dimension ? UniverseRegistry.getName(world.dimension) : null, EntityRegistry.getEntityID(nplayer), conn.isInEditor())); + conn.sendPacket(new SPacketRespawn(world.dimension != oldWorld.dimension ? world.dimension : null, world.getDayTime(), world.dimension != oldWorld.dimension ? UniverseRegistry.getName(world.dimension) : null, EntityRegistry.getEntityID(nplayer), conn.isInEditor())); conn.setPlayerLocation(nplayer.posX, nplayer.posY, nplayer.posZ, nplayer.rotYaw, nplayer.rotPitch); conn.sendPacket(new SPacketSetExperience(nplayer.experience, nplayer.experienceTotal, nplayer.experienceLevel)); this.updateTimeAndWeatherForPlayer(conn, world); @@ -1193,7 +1189,7 @@ public final class Server implements IThreadListener, Executor { world.loadChunk((int)nplayer.posX >> 4, (int)nplayer.posZ >> 4); world.addPlayer(nplayer); world.spawnEntityInWorld(nplayer); - conn.sendPacket(new SPacketRespawn(world.dimension != oldWorld.dimension ? world.dimension : null, world.dimension != oldWorld.dimension ? UniverseRegistry.getName(world.dimension) : null, EntityRegistry.getEntityID(nplayer), conn.isInEditor())); + conn.sendPacket(new SPacketRespawn(world.dimension != oldWorld.dimension ? world.dimension : null, world.getDayTime(), world.dimension != oldWorld.dimension ? UniverseRegistry.getName(world.dimension) : null, EntityRegistry.getEntityID(nplayer), conn.isInEditor())); conn.sendPacket(new SPacketSkin(nplayer.getId(), nplayer.getSkin())); // , nplayer.getModel())); conn.setPlayerLocation(nplayer.posX, nplayer.posY, nplayer.posZ, nplayer.rotYaw, nplayer.rotPitch); conn.sendPacket(new SPacketSetExperience(nplayer.experience, nplayer.experienceTotal, nplayer.experienceLevel)); @@ -1211,7 +1207,7 @@ public final class Server implements IThreadListener, Executor { public void transferToDimension(EntityNPC player, Dimension dimension, BlockPos pos, float yaw, float pitch, PortalType portal) { WorldServer oldWorld = (WorldServer)player.getServerWorld(); // this.getWorld(player.dimension); WorldServer newWorld = this.getWorld(dimension); - player.connection.sendPacket(new SPacketRespawn(newWorld.dimension, UniverseRegistry.getName(newWorld.dimension), EntityRegistry.getEntityID(player), player.connection.isInEditor())); + player.connection.sendPacket(new SPacketRespawn(newWorld.dimension, newWorld.getDayTime(), UniverseRegistry.getName(newWorld.dimension), EntityRegistry.getEntityID(player), player.connection.isInEditor())); oldWorld.removePlayerEntityDangerously(player); player.dead = false; this.placeInDimension(player, oldWorld, newWorld, pos, portal); diff --git a/server/src/main/java/server/command/commands/CommandTime.java b/server/src/main/java/server/command/commands/CommandTime.java index ac3222c2..f028b229 100644 --- a/server/src/main/java/server/command/commands/CommandTime.java +++ b/server/src/main/java/server/command/commands/CommandTime.java @@ -1,12 +1,13 @@ package server.command.commands; import common.dimension.Dimension; -import common.util.Position; +import common.dimension.Space; import server.command.Command; import server.command.CommandEnvironment; import server.command.Executor; import server.command.RunException; import server.dimension.Dimensions; +import server.init.UniverseRegistry; import server.network.Player; import server.world.WorldServer; @@ -15,9 +16,11 @@ public class CommandTime extends Command { super("time"); this.addString("time", false, "day", "night", "noon", "midnight", "sunrise", "sunset"); + this.addWorld("dim", true); this.setParamsOptional(); this.addFlag("absolute", 'a'); + this.addFlag("global", 'g'); } private long parseInt(String input, long max) { @@ -69,9 +72,7 @@ public class CommandTime extends Command { return t * this.parseInt(arg, Long.MAX_VALUE); } - public Object exec(CommandEnvironment env, Executor exec, String timeStr, boolean absolute) { - Position pos = exec.getExecPos(); - WorldServer world = pos == null ? env.getServer().getSpace() : env.getServer().getWorld(pos.getDimension()); + public Object exec(CommandEnvironment env, Executor exec, String timeStr, WorldServer world, boolean absolute, boolean global) { long time = absolute ? 0L : world.getDayTime(); long fwd = parseDayTime(world.dimension, timeStr); if(fwd >= 0L) { @@ -87,11 +88,29 @@ public class CommandTime extends Command { else { time += parseTime(world.dimension, timeStr); } - for(WorldServer dim : env.getServer().getWorlds()) { - dim.setDayTime(time); - dim.resetWeather(); + if(global) { + for(Dimension dim : UniverseRegistry.getDimensions()) { + dim.setTimeOffset(dim != Space.INSTANCE ? 0L : time); + } + for(WorldServer wld : env.getServer().getWorlds()) { + wld.setDayTime(time); + wld.resetWeather(); + } } - exec.log("Zeit auf %s gesetzt", Dimensions.formatTime(world, exec.isPlayer() ? ((Player)exec).getPresentEntity() : null, false)); + else { + if(world.dimension == Space.INSTANCE) { + long diff = time - world.getDayTime(); + for(Dimension dim : UniverseRegistry.getDimensions()) { + dim.setTimeOffset(dim != Space.INSTANCE ? dim.getTimeOffset() - diff : time); + } + } + else { + world.dimension.setTimeOffset(time - env.getServer().getSpace().getDayTime()); + } + world.setDayTime(time); + world.resetWeather(); + } + exec.log("Zeit " + (global ? "aller Dimensionen (relativ zu %s)" : "in %s") + " auf %s gesetzt", world.dimension.getDisplay(), Dimensions.formatTime(world, exec.isPlayer() ? ((Player)exec).getPresentEntity() : null, false)); return time; } } diff --git a/server/src/main/java/server/world/WorldServer.java b/server/src/main/java/server/world/WorldServer.java index 039005cc..abaebcd3 100755 --- a/server/src/main/java/server/world/WorldServer.java +++ b/server/src/main/java/server/world/WorldServer.java @@ -253,7 +253,7 @@ public final class WorldServer extends AWorldServer { super(dim); this.server = server; // this.time = time; - this.daytime = dtime; + this.daytime = dtime + this.dimension.getTimeOffset(); this.gen = gen; this.updateViewRadius(); this.chunkDir = new File(new File("chunk"), UniverseRegistry.getName(dim));