Mirror von
https://github.com/GeyserMC/Geyser.git
synchronisiert 2024-12-28 09:00:11 +01:00
Merge branch 'master' of https://github.com/GeyserMC/Geyser into floodgate-2.0
Dieser Commit ist enthalten in:
Commit
c937a8a31b
@ -52,6 +52,8 @@ Take a look [here](https://github.com/GeyserMC/Geyser/wiki#Setup) for how to set
|
|||||||
The following things can't be fixed because of Bedrock limitations. They might be fixable in the future, but not as of now.
|
The following things can't be fixed because of Bedrock limitations. They might be fixable in the future, but not as of now.
|
||||||
|
|
||||||
- Custom heads in inventories
|
- Custom heads in inventories
|
||||||
|
- Clickable links in chat
|
||||||
|
- Glowing effect
|
||||||
|
|
||||||
## Compiling
|
## Compiling
|
||||||
1. Clone the repo to your computer
|
1. Clone the repo to your computer
|
||||||
|
@ -44,6 +44,7 @@ import org.geysermc.connector.network.session.GeyserSession;
|
|||||||
import org.geysermc.connector.network.translators.BiomeTranslator;
|
import org.geysermc.connector.network.translators.BiomeTranslator;
|
||||||
import org.geysermc.connector.network.translators.EntityIdentifierRegistry;
|
import org.geysermc.connector.network.translators.EntityIdentifierRegistry;
|
||||||
import org.geysermc.connector.network.translators.PacketTranslatorRegistry;
|
import org.geysermc.connector.network.translators.PacketTranslatorRegistry;
|
||||||
|
import org.geysermc.connector.network.translators.collision.CollisionTranslator;
|
||||||
import org.geysermc.connector.network.translators.effect.EffectRegistry;
|
import org.geysermc.connector.network.translators.effect.EffectRegistry;
|
||||||
import org.geysermc.connector.network.translators.item.ItemRegistry;
|
import org.geysermc.connector.network.translators.item.ItemRegistry;
|
||||||
import org.geysermc.connector.network.translators.item.ItemTranslator;
|
import org.geysermc.connector.network.translators.item.ItemTranslator;
|
||||||
@ -54,7 +55,6 @@ import org.geysermc.connector.network.translators.sound.SoundRegistry;
|
|||||||
import org.geysermc.connector.network.translators.world.WorldManager;
|
import org.geysermc.connector.network.translators.world.WorldManager;
|
||||||
import org.geysermc.connector.network.translators.world.block.BlockTranslator;
|
import org.geysermc.connector.network.translators.world.block.BlockTranslator;
|
||||||
import org.geysermc.connector.network.translators.world.block.entity.BlockEntityTranslator;
|
import org.geysermc.connector.network.translators.world.block.entity.BlockEntityTranslator;
|
||||||
import org.geysermc.connector.network.translators.collision.CollisionTranslator;
|
|
||||||
import org.geysermc.connector.network.translators.world.block.entity.SkullBlockEntityTranslator;
|
import org.geysermc.connector.network.translators.world.block.entity.SkullBlockEntityTranslator;
|
||||||
import org.geysermc.connector.utils.DimensionUtils;
|
import org.geysermc.connector.utils.DimensionUtils;
|
||||||
import org.geysermc.connector.utils.LanguageUtils;
|
import org.geysermc.connector.utils.LanguageUtils;
|
||||||
@ -72,10 +72,7 @@ import java.net.InetSocketAddress;
|
|||||||
import java.net.UnknownHostException;
|
import java.net.UnknownHostException;
|
||||||
import java.security.Key;
|
import java.security.Key;
|
||||||
import java.text.DecimalFormat;
|
import java.text.DecimalFormat;
|
||||||
import java.util.ArrayList;
|
import java.util.*;
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.concurrent.CompletableFuture;
|
import java.util.concurrent.CompletableFuture;
|
||||||
import java.util.concurrent.Executors;
|
import java.util.concurrent.Executors;
|
||||||
import java.util.concurrent.ScheduledExecutorService;
|
import java.util.concurrent.ScheduledExecutorService;
|
||||||
@ -344,6 +341,38 @@ public class GeyserConnector {
|
|||||||
players.remove(player);
|
players.remove(player);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets a player by their current UUID
|
||||||
|
*
|
||||||
|
* @param uuid the uuid
|
||||||
|
* @return the player or <code>null</code> if there is no player online with this UUID
|
||||||
|
*/
|
||||||
|
public GeyserSession getPlayerByUuid(UUID uuid) {
|
||||||
|
for (GeyserSession session : players) {
|
||||||
|
if (session.getPlayerEntity().getUuid().equals(uuid)) {
|
||||||
|
return session;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets a player by their Xbox user identifier
|
||||||
|
*
|
||||||
|
* @param xuid the Xbox user identifier
|
||||||
|
* @return the player or <code>null</code> if there is no player online with this xuid
|
||||||
|
*/
|
||||||
|
public GeyserSession getPlayerByXuid(String xuid) {
|
||||||
|
for (GeyserSession session : players) {
|
||||||
|
if (session.getAuthData() != null && session.getAuthData().getXboxUUID().equals(xuid)) {
|
||||||
|
return session;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
public static GeyserConnector start(PlatformType platformType, GeyserBootstrap bootstrap) {
|
public static GeyserConnector start(PlatformType platformType, GeyserBootstrap bootstrap) {
|
||||||
return new GeyserConnector(platformType, bootstrap);
|
return new GeyserConnector(platformType, bootstrap);
|
||||||
}
|
}
|
||||||
|
@ -38,7 +38,7 @@ public class BedrockTextTranslator extends PacketTranslator<TextPacket> {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void translate(TextPacket packet, GeyserSession session) {
|
public void translate(TextPacket packet, GeyserSession session) {
|
||||||
String message = packet.getMessage().replaceAll("^\\.", "/").trim();
|
String message = packet.getMessage();
|
||||||
|
|
||||||
if (MessageTranslator.isTooLong(message, session)) {
|
if (MessageTranslator.isTooLong(message, session)) {
|
||||||
return;
|
return;
|
||||||
|
@ -45,8 +45,39 @@ import java.util.stream.Collectors;
|
|||||||
|
|
||||||
@ItemRemapper
|
@ItemRemapper
|
||||||
public class BannerTranslator extends ItemTranslator {
|
public class BannerTranslator extends ItemTranslator {
|
||||||
|
/**
|
||||||
|
* Holds what a Java ominous banner pattern looks like.
|
||||||
|
*
|
||||||
|
* Translating the patterns over to Bedrock does not work effectively, but Bedrock has a dedicated type for
|
||||||
|
* ominous banners that we set instead. This variable is used to detect Java ominous banner patterns, and apply
|
||||||
|
* the correct ominous banner pattern if Bedrock pulls the item from creative.
|
||||||
|
*/
|
||||||
|
public static final ListTag OMINOUS_BANNER_PATTERN;
|
||||||
|
|
||||||
private final List<ItemEntry> appliedItems;
|
private final List<ItemEntry> appliedItems;
|
||||||
|
|
||||||
|
static {
|
||||||
|
OMINOUS_BANNER_PATTERN = new ListTag("Patterns");
|
||||||
|
// Construct what an ominous banner is supposed to look like
|
||||||
|
OMINOUS_BANNER_PATTERN.add(getPatternTag("mr", 9));
|
||||||
|
OMINOUS_BANNER_PATTERN.add(getPatternTag("bs", 8));
|
||||||
|
OMINOUS_BANNER_PATTERN.add(getPatternTag("cs", 7));
|
||||||
|
OMINOUS_BANNER_PATTERN.add(getPatternTag("bo", 8));
|
||||||
|
OMINOUS_BANNER_PATTERN.add(getPatternTag("ms", 15));
|
||||||
|
OMINOUS_BANNER_PATTERN.add(getPatternTag("hh", 8));
|
||||||
|
OMINOUS_BANNER_PATTERN.add(getPatternTag("mc", 8));
|
||||||
|
OMINOUS_BANNER_PATTERN.add(getPatternTag("bo", 15));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static CompoundTag getPatternTag(String pattern, int color) {
|
||||||
|
StringTag patternType = new StringTag("Pattern", pattern);
|
||||||
|
IntTag colorTag = new IntTag("Color", color);
|
||||||
|
CompoundTag tag = new CompoundTag("");
|
||||||
|
tag.put(patternType);
|
||||||
|
tag.put(colorTag);
|
||||||
|
return tag;
|
||||||
|
}
|
||||||
|
|
||||||
public BannerTranslator() {
|
public BannerTranslator() {
|
||||||
appliedItems = ItemRegistry.ITEM_ENTRIES.values()
|
appliedItems = ItemRegistry.ITEM_ENTRIES.values()
|
||||||
.stream()
|
.stream()
|
||||||
@ -62,7 +93,7 @@ public class BannerTranslator extends ItemTranslator {
|
|||||||
*/
|
*/
|
||||||
public static NbtList<NbtMap> convertBannerPattern(ListTag patterns) {
|
public static NbtList<NbtMap> convertBannerPattern(ListTag patterns) {
|
||||||
List<NbtMap> tagsList = new ArrayList<>();
|
List<NbtMap> tagsList = new ArrayList<>();
|
||||||
for (com.github.steveice10.opennbt.tag.builtin.Tag patternTag : patterns.getValue()) {
|
for (Tag patternTag : patterns.getValue()) {
|
||||||
NbtMap newPatternTag = getBedrockBannerPattern((CompoundTag) patternTag);
|
NbtMap newPatternTag = getBedrockBannerPattern((CompoundTag) patternTag);
|
||||||
if (newPatternTag != null) {
|
if (newPatternTag != null) {
|
||||||
tagsList.add(newPatternTag);
|
tagsList.add(newPatternTag);
|
||||||
@ -134,7 +165,13 @@ public class BannerTranslator extends ItemTranslator {
|
|||||||
ListTag patterns = blockEntityTag.get("Patterns");
|
ListTag patterns = blockEntityTag.get("Patterns");
|
||||||
|
|
||||||
NbtMapBuilder builder = itemData.getTag().toBuilder();
|
NbtMapBuilder builder = itemData.getTag().toBuilder();
|
||||||
builder.put("Patterns", convertBannerPattern(patterns));
|
if (patterns.equals(OMINOUS_BANNER_PATTERN)) {
|
||||||
|
// Remove the current patterns and set the ominous banner type
|
||||||
|
builder.remove("Patterns");
|
||||||
|
builder.putInt("Type", 1);
|
||||||
|
} else {
|
||||||
|
builder.put("Patterns", convertBannerPattern(patterns));
|
||||||
|
}
|
||||||
|
|
||||||
itemData = ItemData.of(itemData.getId(), itemData.getDamage(), itemData.getCount(), builder.build());
|
itemData = ItemData.of(itemData.getId(), itemData.getDamage(), itemData.getCount(), builder.build());
|
||||||
}
|
}
|
||||||
@ -151,7 +188,14 @@ public class BannerTranslator extends ItemTranslator {
|
|||||||
ItemStack itemStack = super.translateToJava(itemData, itemEntry);
|
ItemStack itemStack = super.translateToJava(itemData, itemEntry);
|
||||||
|
|
||||||
NbtMap nbtTag = itemData.getTag();
|
NbtMap nbtTag = itemData.getTag();
|
||||||
if (nbtTag.containsKey("Patterns", NbtType.COMPOUND)) {
|
if (nbtTag.containsKey("Type", NbtType.INT) && nbtTag.getInt("Type") == 1) {
|
||||||
|
// Ominous banner pattern
|
||||||
|
itemStack.getNbt().remove("Type");
|
||||||
|
CompoundTag blockEntityTag = new CompoundTag("BlockEntityTag");
|
||||||
|
blockEntityTag.put(OMINOUS_BANNER_PATTERN);
|
||||||
|
|
||||||
|
itemStack.getNbt().put(blockEntityTag);
|
||||||
|
} else if (nbtTag.containsKey("Patterns", NbtType.COMPOUND)) {
|
||||||
List<NbtMap> patterns = nbtTag.getList("Patterns", NbtType.COMPOUND);
|
List<NbtMap> patterns = nbtTag.getList("Patterns", NbtType.COMPOUND);
|
||||||
|
|
||||||
CompoundTag blockEntityTag = new CompoundTag("BlockEntityTag");
|
CompoundTag blockEntityTag = new CompoundTag("BlockEntityTag");
|
||||||
|
@ -52,9 +52,14 @@ public class JavaDeclareCommandsTranslator extends PacketTranslator<ServerDeclar
|
|||||||
public void translate(ServerDeclareCommandsPacket packet, GeyserSession session) {
|
public void translate(ServerDeclareCommandsPacket packet, GeyserSession session) {
|
||||||
// Don't send command suggestions if they are disabled
|
// Don't send command suggestions if they are disabled
|
||||||
if (!session.getConnector().getConfig().isCommandSuggestions()) {
|
if (!session.getConnector().getConfig().isCommandSuggestions()) {
|
||||||
session.getConnector().getLogger().debug("Not sending command suggestions as they are disabled.");
|
session.getConnector().getLogger().debug("Not sending translated command suggestions as they are disabled.");
|
||||||
|
|
||||||
|
// Send an empty packet so Bedrock doesn't override /help with its own, built-in help command.
|
||||||
|
AvailableCommandsPacket emptyPacket = new AvailableCommandsPacket();
|
||||||
|
session.sendUpstreamPacket(emptyPacket);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
List<CommandData> commandData = new ArrayList<>();
|
List<CommandData> commandData = new ArrayList<>();
|
||||||
Int2ObjectMap<String> commands = new Int2ObjectOpenHashMap<>();
|
Int2ObjectMap<String> commands = new Int2ObjectOpenHashMap<>();
|
||||||
Int2ObjectMap<List<CommandNode>> commandArgs = new Int2ObjectOpenHashMap<>();
|
Int2ObjectMap<List<CommandNode>> commandArgs = new Int2ObjectOpenHashMap<>();
|
||||||
@ -83,14 +88,14 @@ public class JavaDeclareCommandsTranslator extends PacketTranslator<ServerDeclar
|
|||||||
}
|
}
|
||||||
|
|
||||||
// The command flags, not sure what these do apart from break things
|
// The command flags, not sure what these do apart from break things
|
||||||
List<CommandData.Flag> flags = new ArrayList<>();
|
List<CommandData.Flag> flags = Collections.emptyList();
|
||||||
|
|
||||||
// Loop through all the found commands
|
// Loop through all the found commands
|
||||||
for (int commandID : commands.keySet()) {
|
for (int commandID : commands.keySet()) {
|
||||||
String commandName = commands.get(commandID);
|
String commandName = commands.get(commandID);
|
||||||
|
|
||||||
// Create a basic alias
|
// Create a basic alias
|
||||||
CommandEnumData aliases = new CommandEnumData( commandName + "Aliases", new String[] { commandName.toLowerCase() }, false);
|
CommandEnumData aliases = new CommandEnumData(commandName + "Aliases", new String[] { commandName.toLowerCase() }, false);
|
||||||
|
|
||||||
// Get and parse all params
|
// Get and parse all params
|
||||||
CommandParamData[][] params = getParams(packet.getNodes()[commandID], packet.getNodes());
|
CommandParamData[][] params = getParams(packet.getNodes()[commandID], packet.getNodes());
|
||||||
@ -102,9 +107,7 @@ public class JavaDeclareCommandsTranslator extends PacketTranslator<ServerDeclar
|
|||||||
|
|
||||||
// Add our commands to the AvailableCommandsPacket for the bedrock client
|
// Add our commands to the AvailableCommandsPacket for the bedrock client
|
||||||
AvailableCommandsPacket availableCommandsPacket = new AvailableCommandsPacket();
|
AvailableCommandsPacket availableCommandsPacket = new AvailableCommandsPacket();
|
||||||
for (CommandData data : commandData) {
|
availableCommandsPacket.getCommands().addAll(commandData);
|
||||||
availableCommandsPacket.getCommands().add(data);
|
|
||||||
}
|
|
||||||
|
|
||||||
GeyserConnector.getInstance().getLogger().debug("Sending command packet of " + commandData.size() + " commands");
|
GeyserConnector.getInstance().getLogger().debug("Sending command packet of " + commandData.size() + " commands");
|
||||||
|
|
||||||
|
@ -47,7 +47,13 @@ public class BannerBlockEntityTranslator extends BlockEntityTranslator implement
|
|||||||
|
|
||||||
if (tag.contains("Patterns")) {
|
if (tag.contains("Patterns")) {
|
||||||
ListTag patterns = tag.get("Patterns");
|
ListTag patterns = tag.get("Patterns");
|
||||||
builder.put("Patterns", BannerTranslator.convertBannerPattern(patterns));
|
if (patterns.equals(BannerTranslator.OMINOUS_BANNER_PATTERN)) {
|
||||||
|
// This is an ominous banner; don't try to translate the raw patterns (it doesn't translate correctly)
|
||||||
|
// and tell the Bedrock client that this is an ominous banner
|
||||||
|
builder.putInt("Type", 1);
|
||||||
|
} else {
|
||||||
|
builder.put("Patterns", BannerTranslator.convertBannerPattern(patterns));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tag.contains("CustomName")) {
|
if (tag.contains("CustomName")) {
|
||||||
|
@ -81,11 +81,10 @@ public class SkinManager {
|
|||||||
|
|
||||||
// This attempts to find the xuid of the player so profile images show up for xbox accounts
|
// This attempts to find the xuid of the player so profile images show up for xbox accounts
|
||||||
String xuid = "";
|
String xuid = "";
|
||||||
for (GeyserSession player : GeyserConnector.getInstance().getPlayers()) {
|
GeyserSession player = GeyserConnector.getInstance().getPlayerByUuid(uuid);
|
||||||
if (player.getPlayerEntity().getUuid().equals(uuid)) {
|
|
||||||
xuid = player.getAuthData().getXboxUUID();
|
if (player != null) {
|
||||||
break;
|
xuid = player.getAuthData().getXboxUUID();
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
PlayerListPacket.Entry entry;
|
PlayerListPacket.Entry entry;
|
||||||
@ -268,11 +267,10 @@ public class SkinManager {
|
|||||||
// return default skin with default cape when texture data is invalid
|
// return default skin with default cape when texture data is invalid
|
||||||
String skinUrl = isAlex ? SkinProvider.EMPTY_SKIN_ALEX.getTextureUrl() : SkinProvider.EMPTY_SKIN.getTextureUrl();
|
String skinUrl = isAlex ? SkinProvider.EMPTY_SKIN_ALEX.getTextureUrl() : SkinProvider.EMPTY_SKIN.getTextureUrl();
|
||||||
if ("steve".equals(skinUrl) || "alex".equals(skinUrl)) {
|
if ("steve".equals(skinUrl) || "alex".equals(skinUrl)) {
|
||||||
for (GeyserSession session : GeyserConnector.getInstance().getPlayers()) {
|
GeyserSession session = GeyserConnector.getInstance().getPlayerByUuid(profile.getId());
|
||||||
if (session.getPlayerEntity().getUuid().equals(profile.getId())) {
|
|
||||||
skinUrl = session.getClientData().getSkinId();
|
if (session != null) {
|
||||||
break;
|
skinUrl = session.getClientData().getSkinId();
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return new GameProfileData(skinUrl, SkinProvider.EMPTY_CAPE.getTextureUrl(), isAlex);
|
return new GameProfileData(skinUrl, SkinProvider.EMPTY_CAPE.getTextureUrl(), isAlex);
|
||||||
|
@ -144,12 +144,10 @@ public class SkinProvider {
|
|||||||
String newSkinUrl = skinUrl;
|
String newSkinUrl = skinUrl;
|
||||||
|
|
||||||
if ("steve".equals(skinUrl) || "alex".equals(skinUrl)) {
|
if ("steve".equals(skinUrl) || "alex".equals(skinUrl)) {
|
||||||
// TODO: Don't have a for loop for this? Have a proper map?
|
GeyserSession session = GeyserConnector.getInstance().getPlayerByUuid(playerId);
|
||||||
for (GeyserSession session : GeyserConnector.getInstance().getPlayers()) {
|
|
||||||
if (session.getPlayerEntity().getUuid().equals(playerId)) {
|
if (session != null) {
|
||||||
newSkinUrl = session.getClientData().getSkinId();
|
newSkinUrl = session.getClientData().getSkinId();
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Laden…
In neuem Issue referenzieren
Einen Benutzer sperren