From 746cd29a6d3be32ff40f18d240dd443df1c63113 Mon Sep 17 00:00:00 2001 From: DoctorMacc Date: Sun, 12 Apr 2020 21:13:51 -0400 Subject: [PATCH 1/7] Add doDaylightCycle gamerule support --- connector/pom.xml | 6 ++++ .../java/world/JavaUpdateTimeTranslator.java | 33 ++++++++++++++++++- 2 files changed, 38 insertions(+), 1 deletion(-) diff --git a/connector/pom.xml b/connector/pom.xml index 25ef5073..190cd4e3 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 ccb69856..314814f8 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); + } + } From daa1888c0959b2a94ae8542f4f26555483d4f413 Mon Sep 17 00:00:00 2001 From: DoctorMacc Date: Sun, 12 Apr 2020 21:33:51 -0400 Subject: [PATCH 2/7] Add some code in case of a rogue plugin --- .../java/world/JavaUpdateTimeTranslator.java | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) 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 314814f8..2db849dd 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 @@ -29,6 +29,8 @@ 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 it.unimi.dsi.fastutil.longs.Long2LongMap; +import it.unimi.dsi.fastutil.longs.Long2LongOpenHashMap; import org.geysermc.connector.network.session.GeyserSession; import org.geysermc.connector.network.translators.PacketTranslator; import org.geysermc.connector.network.translators.Translator; @@ -41,14 +43,17 @@ public class JavaUpdateTimeTranslator extends PacketTranslator 0) || (doDayLightCycle && time < 0)) { + if ((!doDayLightCycle && time > 0 && lastTime != time) || (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); @@ -56,6 +61,10 @@ public class JavaUpdateTimeTranslator extends PacketTranslator 0) { // doDaylightCycle is true and we know setTime(time, session); + } else if (time < 0) { + setTime(time, session); + // Only written to if negative to ease performance + lastRecordedTimes.put(session.getPlayerEntity().getEntityId(), time); } } From 5c62b47175aa156dce2b35590c53c0798cfe6ed4 Mon Sep 17 00:00:00 2001 From: DoctorMacc Date: Mon, 13 Apr 2020 10:46:13 -0400 Subject: [PATCH 3/7] Simplify logic --- connector/pom.xml | 6 --- .../java/world/JavaUpdateTimeTranslator.java | 37 ++++++++----------- 2 files changed, 16 insertions(+), 27 deletions(-) diff --git a/connector/pom.xml b/connector/pom.xml index 190cd4e3..25ef5073 100644 --- a/connector/pom.xml +++ b/connector/pom.xml @@ -66,12 +66,6 @@ 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 2db849dd..f6f9c892 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 @@ -42,44 +42,39 @@ import com.nukkitx.protocol.bedrock.packet.SetTimePacket; public class JavaUpdateTimeTranslator extends PacketTranslator { // doDaylightCycle per-player for multi-world support - static Long2BooleanMap daylightCycles = new Long2BooleanOpenHashMap(); + //static Long2BooleanMap daylightCycles = new Long2BooleanOpenHashMap(); // If negative, the last time is stored so we know it's not some plugin behavior doing weird things. + // Per-player for multi-world support static Long2LongMap lastRecordedTimes = new Long2LongOpenHashMap(); @Override public void translate(ServerUpdateTimePacket packet, GeyserSession session) { - boolean doDayLightCycle = daylightCycles.getOrDefault(session.getPlayerEntity().getEntityId(), true); + // Bedrock sends a GameRulesChangedPacket if there is no daylight cycle + // Java just sends a negative long if there is no daylight cycle + //boolean doDayLightCycle = daylightCycles.getOrDefault(session.getPlayerEntity().getEntityId(), true); long lastTime = lastRecordedTimes.getOrDefault(session.getPlayerEntity().getEntityId(), 0); long time = packet.getTime(); - if ((!doDayLightCycle && time > 0 && lastTime != time) || (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); - } else if (time < 0) { - setTime(time, session); - // Only written to if negative to ease performance + if (lastTime != time) { + // https://minecraft.gamepedia.com/Day-night_cycle#24-hour_Minecraft_day + SetTimePacket setTimePacket = new SetTimePacket(); + setTimePacket.setTime((int) Math.abs(time) % 24000); + session.getUpstream().sendPacket(setTimePacket); + // TODO: Performance efficient to always do this? lastRecordedTimes.put(session.getPlayerEntity().getEntityId(), time); } - } - - 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(time) % 24000); - session.getUpstream().sendPacket(setTimePacket); + if (lastTime < 0 && time > 0) { + setDoDayLightGamerule(session, true); + } else if (lastTime != time && time < 0) { + setDoDayLightGamerule(session, false); + } } 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); } } From d08c13a7e37c0949fdf6985cbd14e6a552590ec9 Mon Sep 17 00:00:00 2001 From: DoctorMacc Date: Mon, 13 Apr 2020 10:47:30 -0400 Subject: [PATCH 4/7] Remove old lines of code --- .../translators/java/world/JavaUpdateTimeTranslator.java | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) 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 f6f9c892..9646e329 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 @@ -40,9 +40,7 @@ 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(); + // If negative, the last time is stored so we know it's not some plugin behavior doing weird things. // Per-player for multi-world support static Long2LongMap lastRecordedTimes = new Long2LongOpenHashMap(); @@ -52,7 +50,6 @@ public class JavaUpdateTimeTranslator extends PacketTranslator Date: Mon, 13 Apr 2020 10:55:52 -0400 Subject: [PATCH 5/7] Remove unused imports --- .../translators/java/world/JavaUpdateTimeTranslator.java | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) 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 9646e329..2a972664 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 @@ -27,8 +27,6 @@ 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 it.unimi.dsi.fastutil.longs.Long2LongMap; import it.unimi.dsi.fastutil.longs.Long2LongOpenHashMap; import org.geysermc.connector.network.session.GeyserSession; @@ -40,7 +38,7 @@ import com.nukkitx.protocol.bedrock.packet.SetTimePacket; @Translator(packet = ServerUpdateTimePacket.class) public class JavaUpdateTimeTranslator extends PacketTranslator { - + // If negative, the last time is stored so we know it's not some plugin behavior doing weird things. // Per-player for multi-world support static Long2LongMap lastRecordedTimes = new Long2LongOpenHashMap(); From 35a16996b5b88d87ab794a6ee52b40241518b9e1 Mon Sep 17 00:00:00 2001 From: DoctorMacc Date: Mon, 13 Apr 2020 10:58:10 -0400 Subject: [PATCH 6/7] Small change --- .../translators/java/world/JavaUpdateTimeTranslator.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 2a972664..ab7ed8ae 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 @@ -59,7 +59,7 @@ public class JavaUpdateTimeTranslator extends PacketTranslator 0) { + if (lastTime < 0 && time >= 0) { setDoDayLightGamerule(session, true); } else if (lastTime != time && time < 0) { setDoDayLightGamerule(session, false); From 821f164b23c3973c73ca96ccb5b500e90028398b Mon Sep 17 00:00:00 2001 From: DoctorMacc Date: Mon, 13 Apr 2020 18:01:30 -0400 Subject: [PATCH 7/7] Fix requested changes --- .../java/world/JavaUpdateTimeTranslator.java | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) 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 ab7ed8ae..36533844 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 @@ -41,14 +41,14 @@ public class JavaUpdateTimeTranslator extends PacketTranslator= 0) { - setDoDayLightGamerule(session, true); + setDoDaylightCycleGamerule(session, true); } else if (lastTime != time && time < 0) { - setDoDayLightGamerule(session, false); + setDoDaylightCycleGamerule(session, false); } } - private void setDoDayLightGamerule(GeyserSession session, boolean doCycle) { + private void setDoDaylightCycleGamerule(GeyserSession session, boolean doCycle) { GameRulesChangedPacket gameRulesChangedPacket = new GameRulesChangedPacket(); gameRulesChangedPacket.getGameRules().add(new GameRuleData<>("dodaylightcycle", doCycle)); session.getUpstream().sendPacket(gameRulesChangedPacket);