diff --git a/connector/pom.xml b/connector/pom.xml index 25ef50730..190cd4e3b 100644 --- a/connector/pom.xml +++ b/connector/pom.xml @@ -66,6 +66,12 @@ 8.3.1 compile + + com.nukkitx.fastutil + fastutil-long-boolean-maps + 8.3.1 + compile + com.nukkitx.fastutil fastutil-object-long-maps diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/java/world/JavaUpdateTimeTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/java/world/JavaUpdateTimeTranslator.java index ccb69856c..314814f8c 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/java/world/JavaUpdateTimeTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/java/world/JavaUpdateTimeTranslator.java @@ -25,6 +25,10 @@ package org.geysermc.connector.network.translators.java.world; +import com.nukkitx.protocol.bedrock.data.GameRuleData; +import com.nukkitx.protocol.bedrock.packet.GameRulesChangedPacket; +import it.unimi.dsi.fastutil.longs.Long2BooleanMap; +import it.unimi.dsi.fastutil.longs.Long2BooleanOpenHashMap; import org.geysermc.connector.network.session.GeyserSession; import org.geysermc.connector.network.translators.PacketTranslator; import org.geysermc.connector.network.translators.Translator; @@ -35,11 +39,38 @@ import com.nukkitx.protocol.bedrock.packet.SetTimePacket; @Translator(packet = ServerUpdateTimePacket.class) public class JavaUpdateTimeTranslator extends PacketTranslator { + // doDaylightCycle per-player for multi-world support + static Long2BooleanMap daylightCycles = new Long2BooleanOpenHashMap(); + @Override public void translate(ServerUpdateTimePacket packet, GeyserSession session) { + + boolean doDayLightCycle = daylightCycles.getOrDefault(session.getPlayerEntity().getEntityId(), true); + long time = packet.getTime(); + + if ((!doDayLightCycle && time > 0) || (doDayLightCycle && time < 0)) { + // doDaylightCycle is different than the client and we don't know + // Time is set either way as a reference point for the current time + setTime(time, session); + setDoDayLightGamerule(session, !doDayLightCycle); + } else if (time > 0) { + // doDaylightCycle is true and we know + setTime(time, session); + } + } + + private void setTime(long time, GeyserSession session) { // https://minecraft.gamepedia.com/Day-night_cycle#24-hour_Minecraft_day SetTimePacket setTimePacket = new SetTimePacket(); - setTimePacket.setTime((int) Math.abs(packet.getTime()) % 24000); + setTimePacket.setTime((int) Math.abs(time) % 24000); session.getUpstream().sendPacket(setTimePacket); } + + private void setDoDayLightGamerule(GeyserSession session, boolean doCycle) { + GameRulesChangedPacket gameRulesChangedPacket = new GameRulesChangedPacket(); + gameRulesChangedPacket.getGameRules().add(new GameRuleData<>("dodaylightcycle", doCycle)); + session.getUpstream().sendPacket(gameRulesChangedPacket); + daylightCycles.put(session.getPlayerEntity().getEntityId(), doCycle); + } + }