add relative time

This commit is contained in:
Sen 2025-08-03 16:45:14 +02:00
parent 83082f4f3c
commit 2f9e7ba728
Signed by: sen
GPG key ID: 3AC50A6F47D1B722
7 changed files with 57 additions and 30 deletions

View file

@ -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();

View file

@ -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");

View file

@ -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;
}

View file

@ -27,10 +27,10 @@ public class SPacketRespawn implements Packet<IClientPlayer> {
}
@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();

View file

@ -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() ? "<unbekannt>" : 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);

View file

@ -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;
}
}

View file

@ -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));