Merge remote-tracking branch 'origin/master' into floodgate-2.0

# Conflicts:
#	common/src/main/java/org/geysermc/common/window/CustomFormWindow.java
#	common/src/main/java/org/geysermc/common/window/SimpleFormWindow.java
#	connector/src/main/java/org/geysermc/connector/network/UpstreamPacketHandler.java
#	connector/src/main/java/org/geysermc/connector/network/session/GeyserSession.java
#	connector/src/main/java/org/geysermc/connector/utils/LoginEncryptionUtils.java
#	connector/src/main/java/org/geysermc/connector/utils/SettingsUtils.java
This commit is contained in:
Tim203 2020-10-30 01:25:52 +01:00
commit 36419e5931
No known key found for this signature in database
GPG key ID: 064EE9F5BF7C3EE8
109 changed files with 2559 additions and 804 deletions

View file

@ -40,6 +40,7 @@ import org.geysermc.connector.utils.FileUtils;
import org.geysermc.connector.utils.LanguageUtils;
import org.geysermc.platform.spigot.command.GeyserSpigotCommandExecutor;
import org.geysermc.platform.spigot.command.GeyserSpigotCommandManager;
import org.geysermc.platform.spigot.command.SpigotCommandSender;
import org.geysermc.platform.spigot.world.GeyserSpigotBlockPlaceListener;
import org.geysermc.platform.spigot.world.GeyserSpigotWorldManager;
@ -130,6 +131,9 @@ public class GeyserSpigotPlugin extends JavaPlugin implements GeyserBootstrap {
geyserLogger.debug("Legacy version of Minecraft (1.15.2 or older) detected; not using 3D biomes.");
}
// Set if we need to use a different method for getting a player's locale
SpigotCommandSender.setUseLegacyLocaleMethod(!isCompatible(Bukkit.getServer().getVersion(), "1.12.0"));
this.geyserWorldManager = new GeyserSpigotWorldManager(isLegacy, use3dBiomes, isViaVersion);
GeyserSpigotBlockPlaceListener blockPlaceListener = new GeyserSpigotBlockPlaceListener(connector, isLegacy, isViaVersion);

View file

@ -32,7 +32,6 @@ import org.bukkit.command.CommandSender;
import org.bukkit.command.TabExecutor;
import org.geysermc.connector.GeyserConnector;
import org.geysermc.connector.command.GeyserCommand;
import org.geysermc.connector.network.session.GeyserSession;
import org.geysermc.connector.utils.LanguageUtils;
import java.util.ArrayList;
@ -42,28 +41,24 @@ import java.util.List;
@AllArgsConstructor
public class GeyserSpigotCommandExecutor implements TabExecutor {
private GeyserConnector connector;
private final GeyserConnector connector;
@Override
public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
if (args.length > 0) {
if (getCommand(args[0]) != null) {
if (!sender.hasPermission(getCommand(args[0]).getPermission())) {
String message = "";
if (sender instanceof GeyserSession) {
message = LanguageUtils.getPlayerLocaleString("geyser.bootstrap.command.permission_fail", ((GeyserSession) sender).getClientData().getLanguageCode());
} else {
message = LanguageUtils.getLocaleStringLog("geyser.bootstrap.command.permission_fail");
}
SpigotCommandSender commandSender = new SpigotCommandSender(sender);
String message = LanguageUtils.getPlayerLocaleString("geyser.bootstrap.command.permission_fail", commandSender.getLocale());;
sender.sendMessage(ChatColor.RED + message);
commandSender.sendMessage(ChatColor.RED + message);
return true;
}
getCommand(args[0]).execute(new SpigotCommandSender(sender), args);
getCommand(args[0]).execute(new SpigotCommandSender(sender), args.length > 1 ? Arrays.copyOfRange(args, 1, args.length) : new String[0]);
return true;
}
} else {
getCommand("help").execute(new SpigotCommandSender(sender), args);
getCommand("help").execute(new SpigotCommandSender(sender), new String[0]);
return true;
}
return true;

View file

@ -25,15 +25,33 @@
package org.geysermc.platform.spigot.command;
import lombok.AllArgsConstructor;
import org.bukkit.command.ConsoleCommandSender;
import org.bukkit.entity.Player;
import org.geysermc.connector.GeyserConnector;
import org.geysermc.connector.command.CommandSender;
import org.geysermc.connector.utils.LanguageUtils;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
@AllArgsConstructor
public class SpigotCommandSender implements CommandSender {
private org.bukkit.command.CommandSender handle;
/**
* Whether to use {@code Player.getLocale()} or {@code Player.spigot().getLocale()}, depending on version.
* 1.12 or greater should not use the legacy method.
*/
private static boolean USE_LEGACY_METHOD = false;
private static Method LOCALE_METHOD;
private final org.bukkit.command.CommandSender handle;
private final String locale;
public SpigotCommandSender(org.bukkit.command.CommandSender handle) {
this.handle = handle;
this.locale = getSpigotLocale();
// Ensure even Java players' languages are loaded
LanguageUtils.loadGeyserLocale(locale);
}
@Override
public String getName() {
@ -49,4 +67,49 @@ public class SpigotCommandSender implements CommandSender {
public boolean isConsole() {
return handle instanceof ConsoleCommandSender;
}
@Override
public String getLocale() {
return locale;
}
/**
* Set if we are on pre-1.12, and therefore {@code player.getLocale()} doesn't exist and we have to get
* {@code player.spigot().getLocale()}.
*
* @param useLegacyMethod if we are running pre-1.12 and therefore need to use reflection to get the player locale
*/
public static void setUseLegacyLocaleMethod(boolean useLegacyMethod) {
USE_LEGACY_METHOD = useLegacyMethod;
if (USE_LEGACY_METHOD) {
try {
//noinspection JavaReflectionMemberAccess - of course it doesn't exist; that's why we're doing it
LOCALE_METHOD = Player.Spigot.class.getMethod("getLocale");
} catch (NoSuchMethodException e) {
GeyserConnector.getInstance().getLogger().debug("Player.Spigot.getLocale() doesn't exist? Not a big deal but if you're seeing this please report it to the developers!");
}
}
}
/**
* So we only have to do nasty reflection stuff once per command
*
* @return the locale of the Spigot player
*/
private String getSpigotLocale() {
if (handle instanceof Player) {
Player player = (Player) handle;
if (USE_LEGACY_METHOD) {
try {
// sigh
// This was the only option on older Spigot instances and now it's gone
return (String) LOCALE_METHOD.invoke(player.spigot());
} catch (IllegalAccessException | InvocationTargetException ignored) {
}
} else {
return player.getLocale();
}
}
return LanguageUtils.getDefaultLocale();
}
}

View file

@ -26,12 +26,14 @@
package org.geysermc.platform.spigot.world;
import com.fasterxml.jackson.databind.JsonNode;
import com.github.steveice10.mc.protocol.data.game.chunk.Chunk;
import it.unimi.dsi.fastutil.ints.Int2IntMap;
import it.unimi.dsi.fastutil.ints.Int2IntOpenHashMap;
import org.bukkit.Bukkit;
import org.bukkit.World;
import org.bukkit.block.Biome;
import org.bukkit.block.Block;
import org.bukkit.entity.Player;
import org.geysermc.connector.GeyserConnector;
import org.geysermc.connector.network.session.GeyserSession;
import org.geysermc.connector.network.translators.world.GeyserWorldManager;
@ -93,23 +95,32 @@ public class GeyserSpigotWorldManager extends GeyserWorldManager {
@Override
public int getBlockAt(GeyserSession session, int x, int y, int z) {
if (session.getPlayerEntity() == null) {
return BlockTranslator.AIR;
}
if (Bukkit.getPlayer(session.getPlayerEntity().getUsername()) == null) {
Player bukkitPlayer;
if ((this.isLegacy && !this.isViaVersion)
|| session.getPlayerEntity() == null
|| (bukkitPlayer = Bukkit.getPlayer(session.getPlayerEntity().getUsername())) == null) {
return BlockTranslator.AIR;
}
World world = bukkitPlayer.getWorld();
if (isLegacy) {
return getLegacyBlock(session, x, y, z, isViaVersion);
return getLegacyBlock(session, x, y, z, true);
}
//TODO possibly: detect server version for all versions and use ViaVersion for block state mappings like below
return BlockTranslator.getJavaIdBlockMap().getOrDefault(Bukkit.getPlayer(session.getPlayerEntity().getUsername()).getWorld().getBlockAt(x, y, z).getBlockData().getAsString(), 0);
return BlockTranslator.getJavaIdBlockMap().getOrDefault(world.getBlockAt(x, y, z).getBlockData().getAsString(), 0);
}
public static int getLegacyBlock(GeyserSession session, int x, int y, int z, boolean isViaVersion) {
if (isViaVersion) {
return getLegacyBlock(Bukkit.getPlayer(session.getPlayerEntity().getUsername()).getWorld(), x, y, z, true);
} else {
return BlockTranslator.AIR;
}
}
@SuppressWarnings("deprecation")
public static int getLegacyBlock(GeyserSession session, int x, int y, int z, boolean isViaVersion) {
public static int getLegacyBlock(World world, int x, int y, int z, boolean isViaVersion) {
if (isViaVersion) {
Block block = Bukkit.getPlayer(session.getPlayerEntity().getUsername()).getWorld().getBlockAt(x, y, z);
Block block = world.getBlockAt(x, y, z);
// Black magic that gets the old block state ID
int oldBlockId = (block.getType().getId() << 4) | (block.getData() & 0xF);
// Convert block state from old version -> 1.13 -> 1.13.1 -> 1.14 -> 1.15 -> 1.16 -> 1.16.2
@ -124,6 +135,42 @@ public class GeyserSpigotWorldManager extends GeyserWorldManager {
}
}
@Override
public void getBlocksInSection(GeyserSession session, int x, int y, int z, Chunk chunk) {
Player bukkitPlayer;
if ((this.isLegacy && !this.isViaVersion)
|| session.getPlayerEntity() == null
|| (bukkitPlayer = Bukkit.getPlayer(session.getPlayerEntity().getUsername())) == null) {
return;
}
World world = bukkitPlayer.getWorld();
if (this.isLegacy) {
for (int blockY = 0; blockY < 16; blockY++) { // Cache-friendly iteration order
for (int blockZ = 0; blockZ < 16; blockZ++) {
for (int blockX = 0; blockX < 16; blockX++) {
chunk.set(blockX, blockY, blockZ, getLegacyBlock(world, (x << 4) + blockX, (y << 4) + blockY, (z << 4) + blockZ, true));
}
}
}
} else {
//TODO: see above TODO in getBlockAt
for (int blockY = 0; blockY < 16; blockY++) { // Cache-friendly iteration order
for (int blockZ = 0; blockZ < 16; blockZ++) {
for (int blockX = 0; blockX < 16; blockX++) {
Block block = world.getBlockAt((x << 4) + blockX, (y << 4) + blockY, (z << 4) + blockZ);
int id = BlockTranslator.getJavaIdBlockMap().getOrDefault(block.getBlockData().getAsString(), 0);
chunk.set(blockX, blockY, blockZ, id);
}
}
}
}
}
@Override
public boolean hasMoreBlockDataThanChunkCache() {
return true;
}
@Override
@SuppressWarnings("deprecation")
public int[] getBiomeDataAt(GeyserSession session, int x, int z) {