diff --git a/bootstrap/pom.xml b/bootstrap/pom.xml index a5ad53cb5..a6a2a86de 100644 --- a/bootstrap/pom.xml +++ b/bootstrap/pom.xml @@ -22,7 +22,7 @@ sponge-repo - https://repo.spongepowered.org/maven + https://repo.spongepowered.org/repository/maven-public/ bungeecord-repo diff --git a/bootstrap/spigot/pom.xml b/bootstrap/spigot/pom.xml index 93eebc3d2..d1cba8aea 100644 --- a/bootstrap/spigot/pom.xml +++ b/bootstrap/spigot/pom.xml @@ -30,9 +30,9 @@ provided - org.geysermc.adapters + org.geysermc.geyser.adapters spigot-all - 1.0-SNAPSHOT + 1.1-SNAPSHOT diff --git a/bootstrap/spigot/src/main/java/org/geysermc/platform/spigot/GeyserSpigotPlugin.java b/bootstrap/spigot/src/main/java/org/geysermc/platform/spigot/GeyserSpigotPlugin.java index 86247300a..5296af1b0 100644 --- a/bootstrap/spigot/src/main/java/org/geysermc/platform/spigot/GeyserSpigotPlugin.java +++ b/bootstrap/spigot/src/main/java/org/geysermc/platform/spigot/GeyserSpigotPlugin.java @@ -28,7 +28,6 @@ package org.geysermc.platform.spigot; import com.github.steveice10.mc.protocol.MinecraftConstants; import org.bukkit.Bukkit; import org.bukkit.plugin.java.JavaPlugin; -import org.geysermc.adapters.spigot.SpigotAdapters; import org.geysermc.common.PlatformType; import org.geysermc.connector.GeyserConnector; import org.geysermc.connector.bootstrap.GeyserBootstrap; @@ -40,6 +39,7 @@ import org.geysermc.connector.ping.GeyserLegacyPingPassthrough; import org.geysermc.connector.ping.IGeyserPingPassthrough; import org.geysermc.connector.utils.FileUtils; import org.geysermc.connector.utils.LanguageUtils; +import org.geysermc.geyser.adapters.spigot.SpigotAdapters; import org.geysermc.platform.spigot.command.GeyserSpigotCommandExecutor; import org.geysermc.platform.spigot.command.GeyserSpigotCommandManager; import org.geysermc.platform.spigot.command.SpigotCommandSender; @@ -70,6 +70,11 @@ public class GeyserSpigotPlugin extends JavaPlugin implements GeyserBootstrap { private GeyserConnector connector; + /** + * The Minecraft server version, formatted as 1.#.# + */ + private String minecraftVersion; + @Override public void onEnable() { // This is manually done instead of using Bukkit methods to save the config because otherwise comments get removed @@ -119,6 +124,9 @@ public class GeyserSpigotPlugin extends JavaPlugin implements GeyserBootstrap { geyserConfig.loadFloodgate(this); + // Turn "(MC: 1.16.4)" into 1.16.4. + this.minecraftVersion = Bukkit.getServer().getVersion().split("\\(MC: ")[1].split("\\)")[0]; + this.connector = GeyserConnector.start(PlatformType.SPIGOT, this); if (geyserConfig.isLegacyPingPassthrough()) { @@ -245,6 +253,11 @@ public class GeyserSpigotPlugin extends JavaPlugin implements GeyserBootstrap { return new GeyserSpigotDumpInfo(); } + @Override + public String getMinecraftServerVersion() { + return this.minecraftVersion; + } + public boolean isCompatible(String version, String whichVersion) { int[] currentVersion = parseVersion(version); int[] otherVersion = parseVersion(whichVersion); @@ -283,10 +296,7 @@ public class GeyserSpigotPlugin extends JavaPlugin implements GeyserBootstrap { * @return the server version before ViaVersion finishes initializing */ public ProtocolVersion getServerProtocolVersion() { - String bukkitVersion = Bukkit.getServer().getVersion(); - // Turn "(MC: 1.16.4)" into 1.16.4. - String version = bukkitVersion.split("\\(MC: ")[1].split("\\)")[0]; - return ProtocolVersion.getClosest(version); + return ProtocolVersion.getClosest(this.minecraftVersion); } /** diff --git a/bootstrap/spigot/src/main/java/org/geysermc/platform/spigot/world/manager/GeyserSpigot1_12NativeWorldManager.java b/bootstrap/spigot/src/main/java/org/geysermc/platform/spigot/world/manager/GeyserSpigot1_12NativeWorldManager.java index f67fd944b..02347f5de 100644 --- a/bootstrap/spigot/src/main/java/org/geysermc/platform/spigot/world/manager/GeyserSpigot1_12NativeWorldManager.java +++ b/bootstrap/spigot/src/main/java/org/geysermc/platform/spigot/world/manager/GeyserSpigot1_12NativeWorldManager.java @@ -28,10 +28,10 @@ package org.geysermc.platform.spigot.world.manager; import org.bukkit.Bukkit; import org.bukkit.entity.Player; import org.bukkit.plugin.Plugin; -import org.geysermc.adapters.spigot.SpigotAdapters; -import org.geysermc.adapters.spigot.SpigotWorldAdapter; import org.geysermc.connector.network.session.GeyserSession; import org.geysermc.connector.network.translators.world.block.BlockTranslator; +import org.geysermc.geyser.adapters.spigot.SpigotAdapters; +import org.geysermc.geyser.adapters.spigot.SpigotWorldAdapter; import us.myles.ViaVersion.api.Via; import us.myles.ViaVersion.protocols.protocol1_13to1_12_2.storage.BlockStorage; diff --git a/bootstrap/spigot/src/main/java/org/geysermc/platform/spigot/world/manager/GeyserSpigot1_12WorldManager.java b/bootstrap/spigot/src/main/java/org/geysermc/platform/spigot/world/manager/GeyserSpigot1_12WorldManager.java index 987bd4406..a28eef5b4 100644 --- a/bootstrap/spigot/src/main/java/org/geysermc/platform/spigot/world/manager/GeyserSpigot1_12WorldManager.java +++ b/bootstrap/spigot/src/main/java/org/geysermc/platform/spigot/world/manager/GeyserSpigot1_12WorldManager.java @@ -76,6 +76,10 @@ public class GeyserSpigot1_12WorldManager extends GeyserSpigotWorldManager { if (player == null) { return BlockTranslator.JAVA_AIR_ID; } + if (!player.getWorld().isChunkLoaded(x >> 4, z >> 4)) { + // Prevent nasty async errors if a player is loading in + return BlockTranslator.JAVA_AIR_ID; + } // Get block entity storage BlockStorage storage = Via.getManager().getConnection(player.getUniqueId()).get(BlockStorage.class); Block block = player.getWorld().getBlockAt(x, y, z); diff --git a/bootstrap/spigot/src/main/java/org/geysermc/platform/spigot/world/manager/GeyserSpigotNativeWorldManager.java b/bootstrap/spigot/src/main/java/org/geysermc/platform/spigot/world/manager/GeyserSpigotNativeWorldManager.java index 6576d93a8..cc9d5bddc 100644 --- a/bootstrap/spigot/src/main/java/org/geysermc/platform/spigot/world/manager/GeyserSpigotNativeWorldManager.java +++ b/bootstrap/spigot/src/main/java/org/geysermc/platform/spigot/world/manager/GeyserSpigotNativeWorldManager.java @@ -28,10 +28,10 @@ package org.geysermc.platform.spigot.world.manager; import org.bukkit.Bukkit; import org.bukkit.entity.Player; import org.bukkit.plugin.Plugin; -import org.geysermc.adapters.spigot.SpigotAdapters; -import org.geysermc.adapters.spigot.SpigotWorldAdapter; import org.geysermc.connector.network.session.GeyserSession; import org.geysermc.connector.network.translators.world.block.BlockTranslator; +import org.geysermc.geyser.adapters.spigot.SpigotAdapters; +import org.geysermc.geyser.adapters.spigot.SpigotWorldAdapter; public class GeyserSpigotNativeWorldManager extends GeyserSpigotWorldManager { protected final SpigotWorldAdapter adapter; diff --git a/bootstrap/sponge/src/main/java/org/geysermc/platform/sponge/GeyserSpongePlugin.java b/bootstrap/sponge/src/main/java/org/geysermc/platform/sponge/GeyserSpongePlugin.java index 5b8bf54b2..142d48d29 100644 --- a/bootstrap/sponge/src/main/java/org/geysermc/platform/sponge/GeyserSpongePlugin.java +++ b/bootstrap/sponge/src/main/java/org/geysermc/platform/sponge/GeyserSpongePlugin.java @@ -163,4 +163,9 @@ public class GeyserSpongePlugin implements GeyserBootstrap { public BootstrapDumpInfo getDumpInfo() { return new GeyserSpongeDumpInfo(); } + + @Override + public String getMinecraftServerVersion() { + return Sponge.getPlatform().getMinecraftVersion().getName(); + } } diff --git a/connector/src/main/java/org/geysermc/connector/GeyserConnector.java b/connector/src/main/java/org/geysermc/connector/GeyserConnector.java index d1059627a..4ec87d7b6 100644 --- a/connector/src/main/java/org/geysermc/connector/GeyserConnector.java +++ b/connector/src/main/java/org/geysermc/connector/GeyserConnector.java @@ -244,6 +244,20 @@ public class GeyserConnector { } return valueMap; })); + + String minecraftVersion = bootstrap.getMinecraftServerVersion(); + if (minecraftVersion != null) { + Map> versionMap = new HashMap<>(); + Map platformMap = new HashMap<>(); + platformMap.put(platformType.getPlatformName(), 1); + versionMap.put(minecraftVersion, platformMap); + + metrics.addCustomChart(new Metrics.DrilldownPie("minecraftServerVersion", () -> { + // By the end, we should return, for example: + // 1.16.5 => (Spigot, 1) + return versionMap; + })); + } } boolean isGui = false; diff --git a/connector/src/main/java/org/geysermc/connector/bootstrap/GeyserBootstrap.java b/connector/src/main/java/org/geysermc/connector/bootstrap/GeyserBootstrap.java index 7308fb674..59dc58c2b 100644 --- a/connector/src/main/java/org/geysermc/connector/bootstrap/GeyserBootstrap.java +++ b/connector/src/main/java/org/geysermc/connector/bootstrap/GeyserBootstrap.java @@ -33,6 +33,7 @@ import org.geysermc.connector.command.CommandManager; import org.geysermc.connector.network.translators.world.GeyserWorldManager; import org.geysermc.connector.network.translators.world.WorldManager; +import javax.annotation.Nullable; import java.nio.file.Path; public interface GeyserBootstrap { @@ -99,4 +100,18 @@ public interface GeyserBootstrap { * @return The info about the bootstrap */ BootstrapDumpInfo getDumpInfo(); + + /** + * Returns the Minecraft version currently being used on the server. This should be only be implemented on platforms + * that have direct server access - platforms such as proxies always have to be on their latest version to support + * the newest Minecraft version, but older servers can use ViaVersion to enable newer versions to join. + *
+ * If used, this should not be null before {@link org.geysermc.connector.GeyserConnector} initialization. + * + * @return the Minecraft version being used on the server, or null if not applicable + */ + @Nullable + default String getMinecraftServerVersion() { + return null; + } } diff --git a/connector/src/main/java/org/geysermc/connector/metrics/Metrics.java b/connector/src/main/java/org/geysermc/connector/metrics/Metrics.java index 25ae5a36c..1457780b1 100644 --- a/connector/src/main/java/org/geysermc/connector/metrics/Metrics.java +++ b/connector/src/main/java/org/geysermc/connector/metrics/Metrics.java @@ -36,6 +36,7 @@ import java.io.ByteArrayOutputStream; import java.io.DataOutputStream; import java.io.IOException; import java.net.URL; +import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.List; import java.util.Map; @@ -75,7 +76,7 @@ public class Metrics { private final static ObjectMapper mapper = new ObjectMapper(); - private GeyserConnector connector; + private final GeyserConnector connector; /** * Class constructor. @@ -156,6 +157,7 @@ public class Metrics { String osName = System.getProperty("os.name"); String osArch = System.getProperty("os.arch"); String osVersion = System.getProperty("os.version"); + String javaVersion = System.getProperty("java.version"); int coreCount = Runtime.getRuntime().availableProcessors(); ObjectNode data = mapper.createObjectNode(); @@ -163,6 +165,7 @@ public class Metrics { data.put("serverUUID", serverUUID); data.put("playerAmount", playerAmount); + data.put("javaVersion", javaVersion); data.put("osName", osName); data.put("osArch", osArch); data.put("osVersion", osVersion); @@ -241,7 +244,7 @@ public class Metrics { } ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); GZIPOutputStream gzip = new GZIPOutputStream(outputStream); - gzip.write(str.getBytes("UTF-8")); + gzip.write(str.getBytes(StandardCharsets.UTF_8)); gzip.close(); return outputStream.toByteArray(); } diff --git a/connector/src/main/java/org/geysermc/connector/network/translators/world/block/entity/EndGatewayBlockEntityTranslator.java b/connector/src/main/java/org/geysermc/connector/network/translators/world/block/entity/EndGatewayBlockEntityTranslator.java index 5280124c1..d580e3d21 100644 --- a/connector/src/main/java/org/geysermc/connector/network/translators/world/block/entity/EndGatewayBlockEntityTranslator.java +++ b/connector/src/main/java/org/geysermc/connector/network/translators/world/block/entity/EndGatewayBlockEntityTranslator.java @@ -27,6 +27,8 @@ package org.geysermc.connector.network.translators.world.block.entity; import com.github.steveice10.opennbt.tag.builtin.CompoundTag; import com.github.steveice10.opennbt.tag.builtin.IntTag; +import com.github.steveice10.opennbt.tag.builtin.LongTag; +import com.github.steveice10.opennbt.tag.builtin.Tag; import com.nukkitx.nbt.NbtList; import com.nukkitx.nbt.NbtMapBuilder; import com.nukkitx.nbt.NbtType; @@ -39,7 +41,10 @@ import java.util.LinkedHashMap; public class EndGatewayBlockEntityTranslator extends BlockEntityTranslator { @Override public void translateTag(NbtMapBuilder builder, CompoundTag tag, int blockState) { - builder.put("Age", (int) ((long) tag.get("Age").getValue())); + Tag ageTag = tag.get("Age"); + if (ageTag instanceof LongTag) { + builder.put("Age", (int) ((long) ageTag.getValue())); + } // Java sometimes does not provide this tag, but Bedrock crashes if it doesn't exist // Linked coordinates IntList tagsList = new IntArrayList();