mirror of
https://github.com/GeyserMC/Geyser.git
synced 2024-08-14 23:57:35 +00:00
Support Java 1.20.2 (#4112)
* Initial pass for 1.20.2, compiling * Remove unused level events * handle null GameProfile in ClientboundPlayerInfoUpdatePacket * Handle level events BRUSH_BLOCK_COMPLETE and EGG_CRACK * Account for null tag in DecoratedPotBlockEntityTranslator * Explicitly show that 1.20.31 is supported
This commit is contained in:
parent
5276a1e2ba
commit
c2cd99c829
28 changed files with 243 additions and 167 deletions
|
@ -14,7 +14,7 @@ The ultimate goal of this project is to allow Minecraft: Bedrock Edition users t
|
||||||
|
|
||||||
Special thanks to the DragonProxy project for being a trailblazer in protocol translation and for all the team members who have joined us here!
|
Special thanks to the DragonProxy project for being a trailblazer in protocol translation and for all the team members who have joined us here!
|
||||||
|
|
||||||
### Currently supporting Minecraft Bedrock 1.20.0 - 1.20.30 and Minecraft Java 1.20/1.20.1.
|
### Currently supporting Minecraft Bedrock 1.20.0 - 1.20.31 and Minecraft Java 1.20/1.20.1.
|
||||||
|
|
||||||
## Setting Up
|
## Setting Up
|
||||||
Take a look [here](https://wiki.geysermc.org/geyser/setup/) for how to set up Geyser.
|
Take a look [here](https://wiki.geysermc.org/geyser/setup/) for how to set up Geyser.
|
||||||
|
|
|
@ -71,7 +71,6 @@ import org.geysermc.geyser.level.WorldManager;
|
||||||
import org.geysermc.geyser.network.netty.GeyserServer;
|
import org.geysermc.geyser.network.netty.GeyserServer;
|
||||||
import org.geysermc.geyser.registry.BlockRegistries;
|
import org.geysermc.geyser.registry.BlockRegistries;
|
||||||
import org.geysermc.geyser.registry.Registries;
|
import org.geysermc.geyser.registry.Registries;
|
||||||
import org.geysermc.geyser.registry.loader.RegistryLoaders;
|
|
||||||
import org.geysermc.geyser.scoreboard.ScoreboardUpdater;
|
import org.geysermc.geyser.scoreboard.ScoreboardUpdater;
|
||||||
import org.geysermc.geyser.session.GeyserSession;
|
import org.geysermc.geyser.session.GeyserSession;
|
||||||
import org.geysermc.geyser.session.PendingMicrosoftAuthentication;
|
import org.geysermc.geyser.session.PendingMicrosoftAuthentication;
|
||||||
|
|
|
@ -52,11 +52,6 @@ public class GeyserAdvancement {
|
||||||
return this.advancement.getId();
|
return this.advancement.getId();
|
||||||
}
|
}
|
||||||
|
|
||||||
@NonNull
|
|
||||||
public List<String> getCriteria() {
|
|
||||||
return this.advancement.getCriteria();
|
|
||||||
}
|
|
||||||
|
|
||||||
@NonNull
|
@NonNull
|
||||||
public List<List<String>> getRequirements() {
|
public List<List<String>> getRequirements() {
|
||||||
return this.advancement.getRequirements();
|
return this.advancement.getRequirements();
|
||||||
|
|
|
@ -46,7 +46,9 @@ public final class GameProtocol {
|
||||||
* Default Bedrock codec that should act as a fallback. Should represent the latest available
|
* Default Bedrock codec that should act as a fallback. Should represent the latest available
|
||||||
* release of the game that Geyser supports.
|
* release of the game that Geyser supports.
|
||||||
*/
|
*/
|
||||||
public static final BedrockCodec DEFAULT_BEDROCK_CODEC = Bedrock_v618.CODEC;
|
public static final BedrockCodec DEFAULT_BEDROCK_CODEC = Bedrock_v618.CODEC.toBuilder()
|
||||||
|
.minecraftVersion("1.20.31")
|
||||||
|
.build();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A list of all supported Bedrock versions that can join Geyser
|
* A list of all supported Bedrock versions that can join Geyser
|
||||||
|
@ -66,7 +68,9 @@ public final class GameProtocol {
|
||||||
SUPPORTED_BEDROCK_CODECS.add(Bedrock_v594.CODEC.toBuilder()
|
SUPPORTED_BEDROCK_CODECS.add(Bedrock_v594.CODEC.toBuilder()
|
||||||
.minecraftVersion("1.20.10/1.20.15")
|
.minecraftVersion("1.20.10/1.20.15")
|
||||||
.build());
|
.build());
|
||||||
SUPPORTED_BEDROCK_CODECS.add(DEFAULT_BEDROCK_CODEC);
|
SUPPORTED_BEDROCK_CODECS.add(DEFAULT_BEDROCK_CODEC.toBuilder()
|
||||||
|
.minecraftVersion("1.20.30/1.20.31")
|
||||||
|
.build());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -27,6 +27,7 @@ package org.geysermc.geyser.registry;
|
||||||
|
|
||||||
import com.github.steveice10.mc.protocol.packet.ingame.clientbound.ClientboundDelimiterPacket;
|
import com.github.steveice10.mc.protocol.packet.ingame.clientbound.ClientboundDelimiterPacket;
|
||||||
import com.github.steveice10.mc.protocol.packet.ingame.clientbound.ClientboundTabListPacket;
|
import com.github.steveice10.mc.protocol.packet.ingame.clientbound.ClientboundTabListPacket;
|
||||||
|
import com.github.steveice10.mc.protocol.packet.ingame.clientbound.level.ClientboundChunkBatchStartPacket;
|
||||||
import com.github.steveice10.mc.protocol.packet.ingame.clientbound.level.ClientboundLightUpdatePacket;
|
import com.github.steveice10.mc.protocol.packet.ingame.clientbound.level.ClientboundLightUpdatePacket;
|
||||||
import io.netty.channel.EventLoop;
|
import io.netty.channel.EventLoop;
|
||||||
import org.geysermc.geyser.GeyserImpl;
|
import org.geysermc.geyser.GeyserImpl;
|
||||||
|
@ -43,9 +44,10 @@ public class PacketTranslatorRegistry<T> extends AbstractMappedRegistry<Class<?
|
||||||
private static final Set<Class<?>> IGNORED_PACKETS = Collections.newSetFromMap(new IdentityHashMap<>());
|
private static final Set<Class<?>> IGNORED_PACKETS = Collections.newSetFromMap(new IdentityHashMap<>());
|
||||||
|
|
||||||
static {
|
static {
|
||||||
|
IGNORED_PACKETS.add(ClientboundChunkBatchStartPacket.class); // we don't track chunk batch sizes/periods
|
||||||
|
IGNORED_PACKETS.add(ClientboundDelimiterPacket.class); // Not implemented, spams logs
|
||||||
IGNORED_PACKETS.add(ClientboundLightUpdatePacket.class); // Light is handled on Bedrock for us
|
IGNORED_PACKETS.add(ClientboundLightUpdatePacket.class); // Light is handled on Bedrock for us
|
||||||
IGNORED_PACKETS.add(ClientboundTabListPacket.class); // Cant be implemented in Bedrock
|
IGNORED_PACKETS.add(ClientboundTabListPacket.class); // Cant be implemented in Bedrock
|
||||||
IGNORED_PACKETS.add(ClientboundDelimiterPacket.class); // Not implemented, spams logs
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected PacketTranslatorRegistry() {
|
protected PacketTranslatorRegistry() {
|
||||||
|
|
|
@ -45,15 +45,15 @@ import com.github.steveice10.mc.protocol.data.game.setting.ChatVisibility;
|
||||||
import com.github.steveice10.mc.protocol.data.game.setting.SkinPart;
|
import com.github.steveice10.mc.protocol.data.game.setting.SkinPart;
|
||||||
import com.github.steveice10.mc.protocol.data.game.statistic.CustomStatistic;
|
import com.github.steveice10.mc.protocol.data.game.statistic.CustomStatistic;
|
||||||
import com.github.steveice10.mc.protocol.data.game.statistic.Statistic;
|
import com.github.steveice10.mc.protocol.data.game.statistic.Statistic;
|
||||||
|
import com.github.steveice10.mc.protocol.packet.common.serverbound.ServerboundClientInformationPacket;
|
||||||
import com.github.steveice10.mc.protocol.packet.handshake.serverbound.ClientIntentionPacket;
|
import com.github.steveice10.mc.protocol.packet.handshake.serverbound.ClientIntentionPacket;
|
||||||
import com.github.steveice10.mc.protocol.packet.ingame.serverbound.ServerboundChatCommandPacket;
|
import com.github.steveice10.mc.protocol.packet.ingame.serverbound.ServerboundChatCommandPacket;
|
||||||
import com.github.steveice10.mc.protocol.packet.ingame.serverbound.ServerboundChatPacket;
|
import com.github.steveice10.mc.protocol.packet.ingame.serverbound.ServerboundChatPacket;
|
||||||
import com.github.steveice10.mc.protocol.packet.ingame.serverbound.ServerboundClientInformationPacket;
|
|
||||||
import com.github.steveice10.mc.protocol.packet.ingame.serverbound.player.ServerboundMovePlayerPosPacket;
|
import com.github.steveice10.mc.protocol.packet.ingame.serverbound.player.ServerboundMovePlayerPosPacket;
|
||||||
import com.github.steveice10.mc.protocol.packet.ingame.serverbound.player.ServerboundPlayerAbilitiesPacket;
|
import com.github.steveice10.mc.protocol.packet.ingame.serverbound.player.ServerboundPlayerAbilitiesPacket;
|
||||||
import com.github.steveice10.mc.protocol.packet.ingame.serverbound.player.ServerboundPlayerActionPacket;
|
import com.github.steveice10.mc.protocol.packet.ingame.serverbound.player.ServerboundPlayerActionPacket;
|
||||||
import com.github.steveice10.mc.protocol.packet.ingame.serverbound.player.ServerboundUseItemPacket;
|
import com.github.steveice10.mc.protocol.packet.ingame.serverbound.player.ServerboundUseItemPacket;
|
||||||
import com.github.steveice10.mc.protocol.packet.login.serverbound.ServerboundCustomQueryPacket;
|
import com.github.steveice10.mc.protocol.packet.login.serverbound.ServerboundCustomQueryAnswerPacket;
|
||||||
import com.github.steveice10.packetlib.BuiltinFlags;
|
import com.github.steveice10.packetlib.BuiltinFlags;
|
||||||
import com.github.steveice10.packetlib.Session;
|
import com.github.steveice10.packetlib.Session;
|
||||||
import com.github.steveice10.packetlib.event.session.ConnectedEvent;
|
import com.github.steveice10.packetlib.event.session.ConnectedEvent;
|
||||||
|
@ -292,7 +292,7 @@ public class GeyserSession implements GeyserConnection, GeyserCommandSource {
|
||||||
private Vector2i lastChunkPosition = null;
|
private Vector2i lastChunkPosition = null;
|
||||||
@Setter
|
@Setter
|
||||||
private int clientRenderDistance = -1;
|
private int clientRenderDistance = -1;
|
||||||
private int serverRenderDistance;
|
private int serverRenderDistance = -1;
|
||||||
|
|
||||||
// Exposed for GeyserConnect usage
|
// Exposed for GeyserConnect usage
|
||||||
protected boolean sentSpawnPacket;
|
protected boolean sentSpawnPacket;
|
||||||
|
@ -1665,7 +1665,8 @@ public class GeyserSession implements GeyserConnection, GeyserCommandSource {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void sendDownstreamPacket0(Packet packet) {
|
private void sendDownstreamPacket0(Packet packet) {
|
||||||
if (protocol.getState().equals(ProtocolState.GAME) || packet.getClass() == ServerboundCustomQueryPacket.class) {
|
ProtocolState state = protocol.getState();
|
||||||
|
if (state == ProtocolState.GAME || state == ProtocolState.CONFIGURATION || packet.getClass() == ServerboundCustomQueryAnswerPacket.class) {
|
||||||
downstream.sendPacket(packet);
|
downstream.sendPacket(packet);
|
||||||
} else {
|
} else {
|
||||||
geyser.getLogger().debug("Tried to send downstream packet " + packet.getClass().getSimpleName() + " before connected to the server");
|
geyser.getLogger().debug("Tried to send downstream packet " + packet.getClass().getSimpleName() + " before connected to the server");
|
||||||
|
@ -1824,9 +1825,12 @@ public class GeyserSession implements GeyserConnection, GeyserCommandSource {
|
||||||
if (clientRenderDistance != -1) {
|
if (clientRenderDistance != -1) {
|
||||||
// The client has sent a render distance
|
// The client has sent a render distance
|
||||||
return clientRenderDistance;
|
return clientRenderDistance;
|
||||||
}
|
} else if (serverRenderDistance != -1) {
|
||||||
|
// only known once ClientboundLoginPacket is received
|
||||||
return serverRenderDistance;
|
return serverRenderDistance;
|
||||||
}
|
}
|
||||||
|
return 2; // unfortunate default until we got more info
|
||||||
|
}
|
||||||
|
|
||||||
// We need to send our skin parts to the server otherwise java sees us with no hat, jacket etc
|
// We need to send our skin parts to the server otherwise java sees us with no hat, jacket etc
|
||||||
private static final List<SkinPart> SKIN_PARTS = Arrays.asList(SkinPart.values());
|
private static final List<SkinPart> SKIN_PARTS = Arrays.asList(SkinPart.values());
|
||||||
|
|
|
@ -25,9 +25,10 @@
|
||||||
|
|
||||||
package org.geysermc.geyser.session.cache;
|
package org.geysermc.geyser.session.cache;
|
||||||
|
|
||||||
import com.github.steveice10.mc.protocol.packet.ingame.clientbound.ClientboundUpdateTagsPacket;
|
import com.github.steveice10.mc.protocol.packet.common.clientbound.ClientboundUpdateTagsPacket;
|
||||||
import it.unimi.dsi.fastutil.ints.IntList;
|
import it.unimi.dsi.fastutil.ints.IntList;
|
||||||
import it.unimi.dsi.fastutil.ints.IntLists;
|
import it.unimi.dsi.fastutil.ints.IntLists;
|
||||||
|
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||||
import org.geysermc.geyser.GeyserLogger;
|
import org.geysermc.geyser.GeyserLogger;
|
||||||
import org.geysermc.geyser.inventory.GeyserItemStack;
|
import org.geysermc.geyser.inventory.GeyserItemStack;
|
||||||
import org.geysermc.geyser.item.type.Item;
|
import org.geysermc.geyser.item.type.Item;
|
||||||
|
@ -112,7 +113,7 @@ public class TagCache {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private IntList load(int[] tags) {
|
private IntList load(int @Nullable[] tags) {
|
||||||
if (tags == null) {
|
if (tags == null) {
|
||||||
return IntLists.EMPTY_LIST;
|
return IntLists.EMPTY_LIST;
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,6 +41,10 @@ public class DecoratedPotBlockEntityTranslator extends BlockEntityTranslator {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void translateTag(NbtMapBuilder builder, CompoundTag tag, int blockState) {
|
public void translateTag(NbtMapBuilder builder, CompoundTag tag, int blockState) {
|
||||||
|
if (tag == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// exact same format
|
// exact same format
|
||||||
if (tag.get("sherds") instanceof ListTag sherds) {
|
if (tag.get("sherds") instanceof ListTag sherds) {
|
||||||
List<String> translated = new ArrayList<>(4);
|
List<String> translated = new ArrayList<>(4);
|
||||||
|
|
|
@ -25,7 +25,7 @@
|
||||||
|
|
||||||
package org.geysermc.geyser.translator.protocol.bedrock;
|
package org.geysermc.geyser.translator.protocol.bedrock;
|
||||||
|
|
||||||
import com.github.steveice10.mc.protocol.packet.ingame.serverbound.ServerboundKeepAlivePacket;
|
import com.github.steveice10.mc.protocol.packet.common.serverbound.ServerboundKeepAlivePacket;
|
||||||
import org.cloudburstmc.protocol.bedrock.data.AttributeData;
|
import org.cloudburstmc.protocol.bedrock.data.AttributeData;
|
||||||
import org.cloudburstmc.protocol.bedrock.packet.NetworkStackLatencyPacket;
|
import org.cloudburstmc.protocol.bedrock.packet.NetworkStackLatencyPacket;
|
||||||
import org.cloudburstmc.protocol.bedrock.packet.UpdateAttributesPacket;
|
import org.cloudburstmc.protocol.bedrock.packet.UpdateAttributesPacket;
|
||||||
|
|
|
@ -25,8 +25,8 @@
|
||||||
|
|
||||||
package org.geysermc.geyser.translator.protocol.java;
|
package org.geysermc.geyser.translator.protocol.java;
|
||||||
|
|
||||||
import com.github.steveice10.mc.protocol.packet.ingame.clientbound.ClientboundCustomPayloadPacket;
|
import com.github.steveice10.mc.protocol.packet.common.clientbound.ClientboundCustomPayloadPacket;
|
||||||
import com.github.steveice10.mc.protocol.packet.ingame.serverbound.ServerboundCustomPayloadPacket;
|
import com.github.steveice10.mc.protocol.packet.common.serverbound.ServerboundCustomPayloadPacket;
|
||||||
import com.google.common.base.Charsets;
|
import com.google.common.base.Charsets;
|
||||||
import org.cloudburstmc.protocol.bedrock.packet.TransferPacket;
|
import org.cloudburstmc.protocol.bedrock.packet.TransferPacket;
|
||||||
import org.cloudburstmc.protocol.bedrock.packet.UnknownPacket;
|
import org.cloudburstmc.protocol.bedrock.packet.UnknownPacket;
|
||||||
|
|
|
@ -26,7 +26,7 @@
|
||||||
package org.geysermc.geyser.translator.protocol.java;
|
package org.geysermc.geyser.translator.protocol.java;
|
||||||
|
|
||||||
import com.github.steveice10.mc.protocol.packet.login.clientbound.ClientboundCustomQueryPacket;
|
import com.github.steveice10.mc.protocol.packet.login.clientbound.ClientboundCustomQueryPacket;
|
||||||
import com.github.steveice10.mc.protocol.packet.login.serverbound.ServerboundCustomQueryPacket;
|
import com.github.steveice10.mc.protocol.packet.login.serverbound.ServerboundCustomQueryAnswerPacket;
|
||||||
import org.geysermc.geyser.session.GeyserSession;
|
import org.geysermc.geyser.session.GeyserSession;
|
||||||
import org.geysermc.geyser.translator.protocol.PacketTranslator;
|
import org.geysermc.geyser.translator.protocol.PacketTranslator;
|
||||||
import org.geysermc.geyser.translator.protocol.Translator;
|
import org.geysermc.geyser.translator.protocol.Translator;
|
||||||
|
@ -41,7 +41,7 @@ public class JavaCustomQueryTranslator extends PacketTranslator<ClientboundCusto
|
||||||
// A vanilla client doesn't know any PluginMessage in the Login state, so we don't know any either.
|
// A vanilla client doesn't know any PluginMessage in the Login state, so we don't know any either.
|
||||||
// Note: Fabric Networking API v1 will not let the client log in without sending this
|
// Note: Fabric Networking API v1 will not let the client log in without sending this
|
||||||
session.sendDownstreamPacket(
|
session.sendDownstreamPacket(
|
||||||
new ServerboundCustomQueryPacket(packet.getMessageId(), null)
|
new ServerboundCustomQueryAnswerPacket(packet.getMessageId(), null)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,7 +25,7 @@
|
||||||
|
|
||||||
package org.geysermc.geyser.translator.protocol.java;
|
package org.geysermc.geyser.translator.protocol.java;
|
||||||
|
|
||||||
import com.github.steveice10.mc.protocol.packet.ingame.clientbound.ClientboundDisconnectPacket;
|
import com.github.steveice10.mc.protocol.packet.common.clientbound.ClientboundDisconnectPacket;
|
||||||
import org.geysermc.geyser.session.GeyserSession;
|
import org.geysermc.geyser.session.GeyserSession;
|
||||||
import org.geysermc.geyser.translator.protocol.PacketTranslator;
|
import org.geysermc.geyser.translator.protocol.PacketTranslator;
|
||||||
import org.geysermc.geyser.translator.protocol.Translator;
|
import org.geysermc.geyser.translator.protocol.Translator;
|
||||||
|
|
|
@ -26,6 +26,7 @@
|
||||||
package org.geysermc.geyser.translator.protocol.java;
|
package org.geysermc.geyser.translator.protocol.java;
|
||||||
|
|
||||||
import com.github.steveice10.mc.auth.data.GameProfile;
|
import com.github.steveice10.mc.auth.data.GameProfile;
|
||||||
|
import com.github.steveice10.mc.protocol.packet.common.serverbound.ServerboundCustomPayloadPacket;
|
||||||
import com.github.steveice10.mc.protocol.packet.login.clientbound.ClientboundGameProfilePacket;
|
import com.github.steveice10.mc.protocol.packet.login.clientbound.ClientboundGameProfilePacket;
|
||||||
import org.geysermc.geyser.api.network.AuthType;
|
import org.geysermc.geyser.api.network.AuthType;
|
||||||
import org.geysermc.geyser.entity.type.player.PlayerEntity;
|
import org.geysermc.geyser.entity.type.player.PlayerEntity;
|
||||||
|
@ -33,7 +34,11 @@ import org.geysermc.geyser.session.GeyserSession;
|
||||||
import org.geysermc.geyser.skin.SkinManager;
|
import org.geysermc.geyser.skin.SkinManager;
|
||||||
import org.geysermc.geyser.translator.protocol.PacketTranslator;
|
import org.geysermc.geyser.translator.protocol.PacketTranslator;
|
||||||
import org.geysermc.geyser.translator.protocol.Translator;
|
import org.geysermc.geyser.translator.protocol.Translator;
|
||||||
|
import org.geysermc.geyser.util.PluginMessageUtils;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ClientboundGameProfilePacket triggers protocol change LOGIN -> CONFIGURATION
|
||||||
|
*/
|
||||||
@Translator(packet = ClientboundGameProfilePacket.class)
|
@Translator(packet = ClientboundGameProfilePacket.class)
|
||||||
public class JavaGameProfileTranslator extends PacketTranslator<ClientboundGameProfilePacket> {
|
public class JavaGameProfileTranslator extends PacketTranslator<ClientboundGameProfilePacket> {
|
||||||
|
|
||||||
|
@ -65,5 +70,9 @@ public class JavaGameProfileTranslator extends PacketTranslator<ClientboundGameP
|
||||||
// We no longer need these variables; they're just taking up space in memory now
|
// We no longer need these variables; they're just taking up space in memory now
|
||||||
session.setCertChainData(null);
|
session.setCertChainData(null);
|
||||||
session.getClientData().setOriginalString(null);
|
session.getClientData().setOriginalString(null);
|
||||||
|
|
||||||
|
// configuration phase stuff that the vanilla client replies with after receiving the GameProfilePacket
|
||||||
|
session.sendDownstreamPacket(new ServerboundCustomPayloadPacket("minecraft:brand", PluginMessageUtils.getGeyserBrandData()));
|
||||||
|
session.sendJavaClientSettings();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,7 +25,7 @@
|
||||||
|
|
||||||
package org.geysermc.geyser.translator.protocol.java;
|
package org.geysermc.geyser.translator.protocol.java;
|
||||||
|
|
||||||
import com.github.steveice10.mc.protocol.packet.ingame.clientbound.ClientboundKeepAlivePacket;
|
import com.github.steveice10.mc.protocol.packet.common.clientbound.ClientboundKeepAlivePacket;
|
||||||
import org.cloudburstmc.protocol.bedrock.packet.NetworkStackLatencyPacket;
|
import org.cloudburstmc.protocol.bedrock.packet.NetworkStackLatencyPacket;
|
||||||
import org.geysermc.geyser.session.GeyserSession;
|
import org.geysermc.geyser.session.GeyserSession;
|
||||||
import org.geysermc.geyser.translator.protocol.PacketTranslator;
|
import org.geysermc.geyser.translator.protocol.PacketTranslator;
|
||||||
|
|
|
@ -25,31 +25,22 @@
|
||||||
|
|
||||||
package org.geysermc.geyser.translator.protocol.java;
|
package org.geysermc.geyser.translator.protocol.java;
|
||||||
|
|
||||||
|
import com.github.steveice10.mc.protocol.data.game.entity.player.PlayerSpawnInfo;
|
||||||
|
import com.github.steveice10.mc.protocol.packet.common.serverbound.ServerboundCustomPayloadPacket;
|
||||||
import com.github.steveice10.mc.protocol.packet.ingame.clientbound.ClientboundLoginPacket;
|
import com.github.steveice10.mc.protocol.packet.ingame.clientbound.ClientboundLoginPacket;
|
||||||
import com.github.steveice10.mc.protocol.packet.ingame.serverbound.ServerboundCustomPayloadPacket;
|
|
||||||
import com.github.steveice10.opennbt.tag.builtin.CompoundTag;
|
|
||||||
import com.github.steveice10.opennbt.tag.builtin.IntTag;
|
|
||||||
import org.cloudburstmc.protocol.bedrock.data.GameRuleData;
|
import org.cloudburstmc.protocol.bedrock.data.GameRuleData;
|
||||||
import org.cloudburstmc.protocol.bedrock.packet.GameRulesChangedPacket;
|
import org.cloudburstmc.protocol.bedrock.packet.GameRulesChangedPacket;
|
||||||
import org.cloudburstmc.protocol.bedrock.packet.SetPlayerGameTypePacket;
|
import org.cloudburstmc.protocol.bedrock.packet.SetPlayerGameTypePacket;
|
||||||
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
|
|
||||||
import org.geysermc.floodgate.pluginmessage.PluginMessageChannels;
|
import org.geysermc.floodgate.pluginmessage.PluginMessageChannels;
|
||||||
import org.geysermc.geyser.api.network.AuthType;
|
import org.geysermc.geyser.api.network.AuthType;
|
||||||
import org.geysermc.geyser.entity.type.player.SessionPlayerEntity;
|
import org.geysermc.geyser.entity.type.player.SessionPlayerEntity;
|
||||||
import org.geysermc.geyser.erosion.GeyserboundHandshakePacketHandler;
|
import org.geysermc.geyser.erosion.GeyserboundHandshakePacketHandler;
|
||||||
import org.geysermc.geyser.level.JavaDimension;
|
|
||||||
import org.geysermc.geyser.session.GeyserSession;
|
import org.geysermc.geyser.session.GeyserSession;
|
||||||
import org.geysermc.geyser.text.TextDecoration;
|
|
||||||
import org.geysermc.geyser.translator.level.BiomeTranslator;
|
|
||||||
import org.geysermc.geyser.translator.protocol.PacketTranslator;
|
import org.geysermc.geyser.translator.protocol.PacketTranslator;
|
||||||
import org.geysermc.geyser.translator.protocol.Translator;
|
import org.geysermc.geyser.translator.protocol.Translator;
|
||||||
import org.geysermc.geyser.util.ChunkUtils;
|
import org.geysermc.geyser.util.ChunkUtils;
|
||||||
import org.geysermc.geyser.util.DimensionUtils;
|
import org.geysermc.geyser.util.DimensionUtils;
|
||||||
import org.geysermc.geyser.util.EntityUtils;
|
import org.geysermc.geyser.util.EntityUtils;
|
||||||
import org.geysermc.geyser.util.JavaCodecUtil;
|
|
||||||
import org.geysermc.geyser.util.PluginMessageUtils;
|
|
||||||
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
@Translator(packet = ClientboundLoginPacket.class)
|
@Translator(packet = ClientboundLoginPacket.class)
|
||||||
public class JavaLoginTranslator extends PacketTranslator<ClientboundLoginPacket> {
|
public class JavaLoginTranslator extends PacketTranslator<ClientboundLoginPacket> {
|
||||||
|
@ -64,42 +55,22 @@ public class JavaLoginTranslator extends PacketTranslator<ClientboundLoginPacket
|
||||||
session.setErosionHandler(new GeyserboundHandshakePacketHandler(session));
|
session.setErosionHandler(new GeyserboundHandshakePacketHandler(session));
|
||||||
}
|
}
|
||||||
|
|
||||||
Map<String, JavaDimension> dimensions = session.getDimensions();
|
PlayerSpawnInfo spawnInfo = packet.getCommonPlayerSpawnInfo();
|
||||||
dimensions.clear();
|
|
||||||
|
|
||||||
JavaDimension.load(packet.getRegistry(), dimensions);
|
|
||||||
|
|
||||||
Int2ObjectMap<TextDecoration> chatTypes = session.getChatTypes();
|
|
||||||
chatTypes.clear();
|
|
||||||
for (CompoundTag tag : JavaCodecUtil.iterateAsTag(packet.getRegistry().get("minecraft:chat_type"))) {
|
|
||||||
// The ID is NOT ALWAYS THE SAME! ViaVersion as of 1.19 adds two registry entries that do NOT match vanilla.
|
|
||||||
int id = ((IntTag) tag.get("id")).getValue();
|
|
||||||
CompoundTag element = tag.get("element");
|
|
||||||
CompoundTag chat = element.get("chat");
|
|
||||||
TextDecoration textDecoration = null;
|
|
||||||
if (chat != null) {
|
|
||||||
textDecoration = new TextDecoration(chat);
|
|
||||||
}
|
|
||||||
chatTypes.put(id, textDecoration);
|
|
||||||
}
|
|
||||||
|
|
||||||
// If the player is already initialized and a join game packet is sent, they
|
// If the player is already initialized and a join game packet is sent, they
|
||||||
// are swapping servers
|
// are swapping servers
|
||||||
if (session.isSpawned()) {
|
if (session.isSpawned()) {
|
||||||
String fakeDim = DimensionUtils.getTemporaryDimension(session.getDimension(), packet.getDimension());
|
String fakeDim = DimensionUtils.getTemporaryDimension(session.getDimension(), spawnInfo.getDimension());
|
||||||
DimensionUtils.switchDimension(session, fakeDim);
|
DimensionUtils.switchDimension(session, fakeDim);
|
||||||
|
|
||||||
session.getWorldCache().removeScoreboard();
|
session.getWorldCache().removeScoreboard();
|
||||||
}
|
}
|
||||||
session.setWorldName(packet.getWorldName());
|
session.setWorldName(spawnInfo.getWorldName());
|
||||||
session.setLevels(packet.getWorldNames());
|
session.setLevels(packet.getWorldNames());
|
||||||
|
|
||||||
BiomeTranslator.loadServerBiomes(session, packet.getRegistry());
|
session.setGameMode(spawnInfo.getGameMode());
|
||||||
session.getTagCache().clear();
|
|
||||||
|
|
||||||
session.setGameMode(packet.getGameMode());
|
String newDimension = spawnInfo.getDimension();
|
||||||
|
|
||||||
String newDimension = packet.getDimension();
|
|
||||||
|
|
||||||
boolean needsSpawnPacket = !session.isSentSpawnPacket();
|
boolean needsSpawnPacket = !session.isSentSpawnPacket();
|
||||||
if (needsSpawnPacket) {
|
if (needsSpawnPacket) {
|
||||||
|
@ -114,11 +85,11 @@ public class JavaLoginTranslator extends PacketTranslator<ClientboundLoginPacket
|
||||||
|
|
||||||
if (!needsSpawnPacket) {
|
if (!needsSpawnPacket) {
|
||||||
SetPlayerGameTypePacket playerGameTypePacket = new SetPlayerGameTypePacket();
|
SetPlayerGameTypePacket playerGameTypePacket = new SetPlayerGameTypePacket();
|
||||||
playerGameTypePacket.setGamemode(EntityUtils.toBedrockGamemode(packet.getGameMode()).ordinal());
|
playerGameTypePacket.setGamemode(EntityUtils.toBedrockGamemode(spawnInfo.getGameMode()).ordinal());
|
||||||
session.sendUpstreamPacket(playerGameTypePacket);
|
session.sendUpstreamPacket(playerGameTypePacket);
|
||||||
}
|
}
|
||||||
|
|
||||||
entity.setLastDeathPosition(packet.getLastDeathPos());
|
entity.setLastDeathPosition(spawnInfo.getLastDeathPos());
|
||||||
|
|
||||||
entity.updateBedrockMetadata();
|
entity.updateBedrockMetadata();
|
||||||
|
|
||||||
|
@ -131,16 +102,10 @@ public class JavaLoginTranslator extends PacketTranslator<ClientboundLoginPacket
|
||||||
|
|
||||||
session.setServerRenderDistance(packet.getViewDistance());
|
session.setServerRenderDistance(packet.getViewDistance());
|
||||||
|
|
||||||
// TODO customize
|
// send this again now that we know the server render distance
|
||||||
|
// as the bedrock client isn't required to send a render distance
|
||||||
session.sendJavaClientSettings();
|
session.sendJavaClientSettings();
|
||||||
|
|
||||||
session.sendDownstreamPacket(new ServerboundCustomPayloadPacket("minecraft:brand", PluginMessageUtils.getGeyserBrandData()));
|
|
||||||
|
|
||||||
// TODO don't send two packets
|
|
||||||
// if (true) {
|
|
||||||
// session.sendDownstreamPacket(new ServerboundCustomPayloadPacket("minecraft:register", Constants.PLUGIN_MESSAGE.getBytes(StandardCharsets.UTF_8)));
|
|
||||||
// }
|
|
||||||
// register the plugin messaging channels used in Floodgate
|
|
||||||
if (session.remoteServer().authType() == AuthType.FLOODGATE) {
|
if (session.remoteServer().authType() == AuthType.FLOODGATE) {
|
||||||
session.sendDownstreamPacket(new ServerboundCustomPayloadPacket("minecraft:register", PluginMessageChannels.getFloodgateRegisterData()));
|
session.sendDownstreamPacket(new ServerboundCustomPayloadPacket("minecraft:register", PluginMessageChannels.getFloodgateRegisterData()));
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,8 +25,8 @@
|
||||||
|
|
||||||
package org.geysermc.geyser.translator.protocol.java;
|
package org.geysermc.geyser.translator.protocol.java;
|
||||||
|
|
||||||
import com.github.steveice10.mc.protocol.packet.ingame.clientbound.ClientboundPingPacket;
|
import com.github.steveice10.mc.protocol.packet.common.clientbound.ClientboundPingPacket;
|
||||||
import com.github.steveice10.mc.protocol.packet.ingame.serverbound.ServerboundPongPacket;
|
import com.github.steveice10.mc.protocol.packet.common.serverbound.ServerboundPongPacket;
|
||||||
import org.geysermc.geyser.session.GeyserSession;
|
import org.geysermc.geyser.session.GeyserSession;
|
||||||
import org.geysermc.geyser.translator.protocol.PacketTranslator;
|
import org.geysermc.geyser.translator.protocol.PacketTranslator;
|
||||||
import org.geysermc.geyser.translator.protocol.Translator;
|
import org.geysermc.geyser.translator.protocol.Translator;
|
||||||
|
|
|
@ -0,0 +1,67 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2019-2023 GeyserMC. http://geysermc.org
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*
|
||||||
|
* @author GeyserMC
|
||||||
|
* @link https://github.com/GeyserMC/Geyser
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.geysermc.geyser.translator.protocol.java;
|
||||||
|
|
||||||
|
import com.github.steveice10.mc.protocol.packet.configuration.clientbound.ClientboundRegistryDataPacket;
|
||||||
|
import com.github.steveice10.opennbt.tag.builtin.CompoundTag;
|
||||||
|
import com.github.steveice10.opennbt.tag.builtin.IntTag;
|
||||||
|
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
|
||||||
|
import org.geysermc.geyser.level.JavaDimension;
|
||||||
|
import org.geysermc.geyser.session.GeyserSession;
|
||||||
|
import org.geysermc.geyser.text.TextDecoration;
|
||||||
|
import org.geysermc.geyser.translator.level.BiomeTranslator;
|
||||||
|
import org.geysermc.geyser.translator.protocol.PacketTranslator;
|
||||||
|
import org.geysermc.geyser.translator.protocol.Translator;
|
||||||
|
import org.geysermc.geyser.util.JavaCodecUtil;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
@Translator(packet = ClientboundRegistryDataPacket.class)
|
||||||
|
public class JavaRegistryDataTranslator extends PacketTranslator<ClientboundRegistryDataPacket> {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void translate(GeyserSession session, ClientboundRegistryDataPacket packet) {
|
||||||
|
Map<String, JavaDimension> dimensions = session.getDimensions();
|
||||||
|
dimensions.clear();
|
||||||
|
JavaDimension.load(packet.getRegistry(), dimensions);
|
||||||
|
|
||||||
|
Int2ObjectMap<TextDecoration> chatTypes = session.getChatTypes();
|
||||||
|
chatTypes.clear();
|
||||||
|
for (CompoundTag tag : JavaCodecUtil.iterateAsTag(packet.getRegistry().get("minecraft:chat_type"))) {
|
||||||
|
// The ID is NOT ALWAYS THE SAME! ViaVersion as of 1.19 adds two registry entries that do NOT match vanilla.
|
||||||
|
int id = ((IntTag) tag.get("id")).getValue();
|
||||||
|
CompoundTag element = tag.get("element");
|
||||||
|
CompoundTag chat = element.get("chat");
|
||||||
|
TextDecoration textDecoration = null;
|
||||||
|
if (chat != null) {
|
||||||
|
textDecoration = new TextDecoration(chat);
|
||||||
|
}
|
||||||
|
chatTypes.put(id, textDecoration);
|
||||||
|
}
|
||||||
|
|
||||||
|
BiomeTranslator.loadServerBiomes(session, packet.getRegistry());
|
||||||
|
}
|
||||||
|
}
|
|
@ -25,6 +25,7 @@
|
||||||
|
|
||||||
package org.geysermc.geyser.translator.protocol.java;
|
package org.geysermc.geyser.translator.protocol.java;
|
||||||
|
|
||||||
|
import com.github.steveice10.mc.protocol.data.game.entity.player.PlayerSpawnInfo;
|
||||||
import com.github.steveice10.mc.protocol.packet.ingame.clientbound.ClientboundRespawnPacket;
|
import com.github.steveice10.mc.protocol.packet.ingame.clientbound.ClientboundRespawnPacket;
|
||||||
import org.cloudburstmc.math.vector.Vector3f;
|
import org.cloudburstmc.math.vector.Vector3f;
|
||||||
import org.cloudburstmc.protocol.bedrock.data.LevelEvent;
|
import org.cloudburstmc.protocol.bedrock.data.LevelEvent;
|
||||||
|
@ -46,6 +47,7 @@ public class JavaRespawnTranslator extends PacketTranslator<ClientboundRespawnPa
|
||||||
@Override
|
@Override
|
||||||
public void translate(GeyserSession session, ClientboundRespawnPacket packet) {
|
public void translate(GeyserSession session, ClientboundRespawnPacket packet) {
|
||||||
SessionPlayerEntity entity = session.getPlayerEntity();
|
SessionPlayerEntity entity = session.getPlayerEntity();
|
||||||
|
PlayerSpawnInfo spawnInfo = packet.getCommonPlayerSpawnInfo();
|
||||||
|
|
||||||
session.setSpawned(false);
|
session.setSpawned(false);
|
||||||
|
|
||||||
|
@ -56,13 +58,13 @@ public class JavaRespawnTranslator extends PacketTranslator<ClientboundRespawnPa
|
||||||
session.setOpenInventory(null);
|
session.setOpenInventory(null);
|
||||||
session.setClosingInventory(false);
|
session.setClosingInventory(false);
|
||||||
|
|
||||||
entity.setLastDeathPosition(packet.getLastDeathPos());
|
entity.setLastDeathPosition(spawnInfo.getLastDeathPos());
|
||||||
entity.updateBedrockMetadata();
|
entity.updateBedrockMetadata();
|
||||||
|
|
||||||
SetPlayerGameTypePacket playerGameTypePacket = new SetPlayerGameTypePacket();
|
SetPlayerGameTypePacket playerGameTypePacket = new SetPlayerGameTypePacket();
|
||||||
playerGameTypePacket.setGamemode(EntityUtils.toBedrockGamemode(packet.getGamemode()).ordinal());
|
playerGameTypePacket.setGamemode(EntityUtils.toBedrockGamemode(spawnInfo.getGameMode()).ordinal());
|
||||||
session.sendUpstreamPacket(playerGameTypePacket);
|
session.sendUpstreamPacket(playerGameTypePacket);
|
||||||
session.setGameMode(packet.getGamemode());
|
session.setGameMode(spawnInfo.getGameMode());
|
||||||
|
|
||||||
if (session.isRaining()) {
|
if (session.isRaining()) {
|
||||||
LevelEventPacket stopRainPacket = new LevelEventPacket();
|
LevelEventPacket stopRainPacket = new LevelEventPacket();
|
||||||
|
@ -82,14 +84,14 @@ public class JavaRespawnTranslator extends PacketTranslator<ClientboundRespawnPa
|
||||||
session.setThunder(false);
|
session.setThunder(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
String newDimension = packet.getDimension();
|
String newDimension = spawnInfo.getDimension();
|
||||||
if (!session.getDimension().equals(newDimension) || !packet.getWorldName().equals(session.getWorldName())) {
|
if (!session.getDimension().equals(newDimension) || !spawnInfo.getWorldName().equals(session.getWorldName())) {
|
||||||
// Switching to a new world (based off the world name change or new dimension); send a fake dimension change
|
// Switching to a new world (based off the world name change or new dimension); send a fake dimension change
|
||||||
if (DimensionUtils.javaToBedrock(session.getDimension()) == DimensionUtils.javaToBedrock(newDimension)) {
|
if (DimensionUtils.javaToBedrock(session.getDimension()) == DimensionUtils.javaToBedrock(newDimension)) {
|
||||||
String fakeDim = DimensionUtils.getTemporaryDimension(session.getDimension(), newDimension);
|
String fakeDim = DimensionUtils.getTemporaryDimension(session.getDimension(), newDimension);
|
||||||
DimensionUtils.switchDimension(session, fakeDim);
|
DimensionUtils.switchDimension(session, fakeDim);
|
||||||
}
|
}
|
||||||
session.setWorldName(packet.getWorldName());
|
session.setWorldName(spawnInfo.getWorldName());
|
||||||
DimensionUtils.switchDimension(session, newDimension);
|
DimensionUtils.switchDimension(session, newDimension);
|
||||||
|
|
||||||
ChunkUtils.loadDimension(session);
|
ChunkUtils.loadDimension(session);
|
||||||
|
|
|
@ -25,7 +25,7 @@
|
||||||
|
|
||||||
package org.geysermc.geyser.translator.protocol.java;
|
package org.geysermc.geyser.translator.protocol.java;
|
||||||
|
|
||||||
import com.github.steveice10.mc.protocol.packet.ingame.clientbound.ClientboundUpdateTagsPacket;
|
import com.github.steveice10.mc.protocol.packet.common.clientbound.ClientboundUpdateTagsPacket;
|
||||||
import org.geysermc.geyser.session.GeyserSession;
|
import org.geysermc.geyser.session.GeyserSession;
|
||||||
import org.geysermc.geyser.translator.protocol.PacketTranslator;
|
import org.geysermc.geyser.translator.protocol.PacketTranslator;
|
||||||
import org.geysermc.geyser.translator.protocol.Translator;
|
import org.geysermc.geyser.translator.protocol.Translator;
|
||||||
|
|
|
@ -42,8 +42,9 @@ public class JavaUpdateMobEffectTranslator extends PacketTranslator<ClientboundU
|
||||||
if (entity == session.getPlayerEntity()) {
|
if (entity == session.getPlayerEntity()) {
|
||||||
session.getEffectCache().setEffect(packet.getEffect(), packet.getAmplifier());
|
session.getEffectCache().setEffect(packet.getEffect(), packet.getAmplifier());
|
||||||
}
|
}
|
||||||
if (entity == null)
|
if (entity == null) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
int duration = packet.getDuration();
|
int duration = packet.getDuration();
|
||||||
if (duration < 0) {
|
if (duration < 0) {
|
||||||
|
|
|
@ -29,6 +29,7 @@ import com.github.steveice10.mc.auth.data.GameProfile;
|
||||||
import com.github.steveice10.mc.protocol.data.game.PlayerListEntry;
|
import com.github.steveice10.mc.protocol.data.game.PlayerListEntry;
|
||||||
import com.github.steveice10.mc.protocol.data.game.PlayerListEntryAction;
|
import com.github.steveice10.mc.protocol.data.game.PlayerListEntryAction;
|
||||||
import com.github.steveice10.mc.protocol.packet.ingame.clientbound.ClientboundPlayerInfoUpdatePacket;
|
import com.github.steveice10.mc.protocol.packet.ingame.clientbound.ClientboundPlayerInfoUpdatePacket;
|
||||||
|
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||||
import org.cloudburstmc.math.vector.Vector3f;
|
import org.cloudburstmc.math.vector.Vector3f;
|
||||||
import org.cloudburstmc.protocol.bedrock.packet.PlayerListPacket;
|
import org.cloudburstmc.protocol.bedrock.packet.PlayerListPacket;
|
||||||
import org.geysermc.geyser.GeyserImpl;
|
import org.geysermc.geyser.GeyserImpl;
|
||||||
|
@ -41,6 +42,7 @@ import org.geysermc.geyser.translator.protocol.Translator;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
@Translator(packet = ClientboundPlayerInfoUpdatePacket.class)
|
@Translator(packet = ClientboundPlayerInfoUpdatePacket.class)
|
||||||
public class JavaPlayerInfoUpdateTranslator extends PacketTranslator<ClientboundPlayerInfoUpdatePacket> {
|
public class JavaPlayerInfoUpdateTranslator extends PacketTranslator<ClientboundPlayerInfoUpdatePacket> {
|
||||||
|
@ -50,13 +52,24 @@ public class JavaPlayerInfoUpdateTranslator extends PacketTranslator<Clientbound
|
||||||
|
|
||||||
if (actions.contains(PlayerListEntryAction.ADD_PLAYER)) {
|
if (actions.contains(PlayerListEntryAction.ADD_PLAYER)) {
|
||||||
for (PlayerListEntry entry : packet.getEntries()) {
|
for (PlayerListEntry entry : packet.getEntries()) {
|
||||||
GameProfile profile = entry.getProfile();
|
@Nullable GameProfile profile = entry.getProfile();
|
||||||
PlayerEntity playerEntity;
|
|
||||||
boolean self = profile.getId().equals(session.getPlayerEntity().getUuid());
|
UUID id = entry.getProfileId();
|
||||||
|
String name = null;
|
||||||
|
String texturesProperty = null;
|
||||||
|
|
||||||
|
if (profile != null) {
|
||||||
|
name = profile.getName();
|
||||||
|
|
||||||
GameProfile.Property textures = profile.getProperty("textures");
|
GameProfile.Property textures = profile.getProperty("textures");
|
||||||
String texturesProperty = textures == null ? null : textures.getValue();
|
if (textures != null) {
|
||||||
|
texturesProperty = textures.getValue();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean self = id.equals(session.getPlayerEntity().getUuid());
|
||||||
|
|
||||||
|
PlayerEntity playerEntity;
|
||||||
if (self) {
|
if (self) {
|
||||||
// Entity is ourself
|
// Entity is ourself
|
||||||
playerEntity = session.getPlayerEntity();
|
playerEntity = session.getPlayerEntity();
|
||||||
|
@ -66,17 +79,17 @@ public class JavaPlayerInfoUpdateTranslator extends PacketTranslator<Clientbound
|
||||||
session,
|
session,
|
||||||
-1,
|
-1,
|
||||||
session.getEntityCache().getNextEntityId().incrementAndGet(),
|
session.getEntityCache().getNextEntityId().incrementAndGet(),
|
||||||
profile.getId(),
|
id,
|
||||||
Vector3f.ZERO,
|
Vector3f.ZERO,
|
||||||
Vector3f.ZERO,
|
Vector3f.ZERO,
|
||||||
0, 0, 0,
|
0, 0, 0,
|
||||||
profile.getName(),
|
name,
|
||||||
texturesProperty
|
texturesProperty
|
||||||
);
|
);
|
||||||
|
|
||||||
session.getEntityCache().addPlayerEntity(playerEntity);
|
session.getEntityCache().addPlayerEntity(playerEntity);
|
||||||
}
|
}
|
||||||
playerEntity.setUsername(profile.getName());
|
playerEntity.setUsername(name);
|
||||||
playerEntity.setTexturesProperty(texturesProperty);
|
playerEntity.setTexturesProperty(texturesProperty);
|
||||||
|
|
||||||
if (self) {
|
if (self) {
|
||||||
|
|
|
@ -31,11 +31,14 @@ import com.github.steveice10.mc.protocol.data.game.entity.object.ProjectileData;
|
||||||
import com.github.steveice10.mc.protocol.data.game.entity.type.EntityType;
|
import com.github.steveice10.mc.protocol.data.game.entity.type.EntityType;
|
||||||
import com.github.steveice10.mc.protocol.packet.ingame.clientbound.entity.spawn.ClientboundAddEntityPacket;
|
import com.github.steveice10.mc.protocol.packet.ingame.clientbound.entity.spawn.ClientboundAddEntityPacket;
|
||||||
import org.cloudburstmc.math.vector.Vector3f;
|
import org.cloudburstmc.math.vector.Vector3f;
|
||||||
|
import org.geysermc.geyser.GeyserImpl;
|
||||||
import org.geysermc.geyser.entity.EntityDefinition;
|
import org.geysermc.geyser.entity.EntityDefinition;
|
||||||
import org.geysermc.geyser.entity.type.*;
|
import org.geysermc.geyser.entity.type.*;
|
||||||
import org.geysermc.geyser.entity.type.player.PlayerEntity;
|
import org.geysermc.geyser.entity.type.player.PlayerEntity;
|
||||||
import org.geysermc.geyser.registry.Registries;
|
import org.geysermc.geyser.registry.Registries;
|
||||||
import org.geysermc.geyser.session.GeyserSession;
|
import org.geysermc.geyser.session.GeyserSession;
|
||||||
|
import org.geysermc.geyser.skin.SkinManager;
|
||||||
|
import org.geysermc.geyser.text.GeyserLocale;
|
||||||
import org.geysermc.geyser.translator.protocol.PacketTranslator;
|
import org.geysermc.geyser.translator.protocol.PacketTranslator;
|
||||||
import org.geysermc.geyser.translator.protocol.Translator;
|
import org.geysermc.geyser.translator.protocol.Translator;
|
||||||
|
|
||||||
|
@ -44,15 +47,44 @@ public class JavaAddEntityTranslator extends PacketTranslator<ClientboundAddEnti
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void translate(GeyserSession session, ClientboundAddEntityPacket packet) {
|
public void translate(GeyserSession session, ClientboundAddEntityPacket packet) {
|
||||||
|
EntityDefinition<?> definition = Registries.ENTITY_DEFINITIONS.get(packet.getType());
|
||||||
|
if (definition == null) {
|
||||||
|
session.getGeyser().getLogger().warning("Could not find an entity definition with type " + packet.getType());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
Vector3f position = Vector3f.from(packet.getX(), packet.getY(), packet.getZ());
|
Vector3f position = Vector3f.from(packet.getX(), packet.getY(), packet.getZ());
|
||||||
Vector3f motion = Vector3f.from(packet.getMotionX(), packet.getMotionY(), packet.getMotionZ());
|
Vector3f motion = Vector3f.from(packet.getMotionX(), packet.getMotionY(), packet.getMotionZ());
|
||||||
float yaw = packet.getYaw();
|
float yaw = packet.getYaw();
|
||||||
float pitch = packet.getPitch();
|
float pitch = packet.getPitch();
|
||||||
float headYaw = packet.getHeadYaw();
|
float headYaw = packet.getHeadYaw();
|
||||||
|
|
||||||
EntityDefinition<?> definition = Registries.ENTITY_DEFINITIONS.get(packet.getType());
|
if (packet.getType() == EntityType.PLAYER) {
|
||||||
if (definition == null) {
|
|
||||||
session.getGeyser().getLogger().warning("Could not find an entity definition with type " + packet.getType());
|
PlayerEntity entity;
|
||||||
|
if (packet.getUuid().equals(session.getPlayerEntity().getUuid())) {
|
||||||
|
// Server is sending a fake version of the current player
|
||||||
|
entity = new PlayerEntity(session, packet.getEntityId(), session.getEntityCache().getNextEntityId().incrementAndGet(),
|
||||||
|
session.getPlayerEntity().getUuid(), position, motion, yaw, pitch, headYaw, session.getPlayerEntity().getUsername(),
|
||||||
|
session.getPlayerEntity().getTexturesProperty());
|
||||||
|
} else {
|
||||||
|
entity = session.getEntityCache().getPlayerEntity(packet.getUuid());
|
||||||
|
if (entity == null) {
|
||||||
|
GeyserImpl.getInstance().getLogger().error(GeyserLocale.getLocaleStringLog("geyser.entity.player.failed_list", packet.getUuid()));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
entity.setEntityId(packet.getEntityId());
|
||||||
|
entity.setPosition(position);
|
||||||
|
entity.setYaw(yaw);
|
||||||
|
entity.setPitch(pitch);
|
||||||
|
entity.setHeadYaw(headYaw);
|
||||||
|
entity.setMotion(motion);
|
||||||
|
}
|
||||||
|
session.getEntityCache().cacheEntity(entity);
|
||||||
|
|
||||||
|
entity.sendPlayer();
|
||||||
|
SkinManager.requestAndHandleSkinAndCape(entity, session, null);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,72 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2019-2022 GeyserMC. http://geysermc.org
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
|
||||||
* in the Software without restriction, including without limitation the rights
|
|
||||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
* copies of the Software, and to permit persons to whom the Software is
|
|
||||||
* furnished to do so, subject to the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be included in
|
|
||||||
* all copies or substantial portions of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
||||||
* THE SOFTWARE.
|
|
||||||
*
|
|
||||||
* @author GeyserMC
|
|
||||||
* @link https://github.com/GeyserMC/Geyser
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.geysermc.geyser.translator.protocol.java.entity.spawn;
|
|
||||||
|
|
||||||
import com.github.steveice10.mc.protocol.packet.ingame.clientbound.entity.spawn.ClientboundAddPlayerPacket;
|
|
||||||
import org.cloudburstmc.math.vector.Vector3f;
|
|
||||||
import org.geysermc.geyser.GeyserImpl;
|
|
||||||
import org.geysermc.geyser.entity.type.player.PlayerEntity;
|
|
||||||
import org.geysermc.geyser.session.GeyserSession;
|
|
||||||
import org.geysermc.geyser.skin.SkinManager;
|
|
||||||
import org.geysermc.geyser.text.GeyserLocale;
|
|
||||||
import org.geysermc.geyser.translator.protocol.PacketTranslator;
|
|
||||||
import org.geysermc.geyser.translator.protocol.Translator;
|
|
||||||
|
|
||||||
@Translator(packet = ClientboundAddPlayerPacket.class)
|
|
||||||
public class JavaAddPlayerTranslator extends PacketTranslator<ClientboundAddPlayerPacket> {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void translate(GeyserSession session, ClientboundAddPlayerPacket packet) {
|
|
||||||
Vector3f position = Vector3f.from(packet.getX(), packet.getY(), packet.getZ());
|
|
||||||
float yaw = packet.getYaw();
|
|
||||||
float pitch = packet.getPitch();
|
|
||||||
float headYaw = packet.getYaw();
|
|
||||||
|
|
||||||
PlayerEntity entity;
|
|
||||||
if (packet.getUuid().equals(session.getPlayerEntity().getUuid())) {
|
|
||||||
// Server is sending a fake version of the current player
|
|
||||||
entity = new PlayerEntity(session, packet.getEntityId(), session.getEntityCache().getNextEntityId().incrementAndGet(),
|
|
||||||
session.getPlayerEntity().getUuid(), position, Vector3f.ZERO, yaw, pitch, headYaw, session.getPlayerEntity().getUsername(),
|
|
||||||
session.getPlayerEntity().getTexturesProperty());
|
|
||||||
} else {
|
|
||||||
entity = session.getEntityCache().getPlayerEntity(packet.getUuid());
|
|
||||||
if (entity == null) {
|
|
||||||
GeyserImpl.getInstance().getLogger().error(GeyserLocale.getLocaleStringLog("geyser.entity.player.failed_list", packet.getUuid()));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
entity.setEntityId(packet.getEntityId());
|
|
||||||
entity.setPosition(position);
|
|
||||||
entity.setYaw(yaw);
|
|
||||||
entity.setPitch(pitch);
|
|
||||||
entity.setHeadYaw(headYaw);
|
|
||||||
}
|
|
||||||
session.getEntityCache().cacheEntity(entity);
|
|
||||||
|
|
||||||
entity.sendPlayer();
|
|
||||||
SkinManager.requestAndHandleSkinAndCape(entity, session, null);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,44 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2019-2023 GeyserMC. http://geysermc.org
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*
|
||||||
|
* @author GeyserMC
|
||||||
|
* @link https://github.com/GeyserMC/Geyser
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.geysermc.geyser.translator.protocol.java.level;
|
||||||
|
|
||||||
|
import com.github.steveice10.mc.protocol.packet.ingame.clientbound.level.ClientboundChunkBatchFinishedPacket;
|
||||||
|
import com.github.steveice10.mc.protocol.packet.ingame.serverbound.level.ServerboundChunkBatchReceivedPacket;
|
||||||
|
import org.geysermc.geyser.session.GeyserSession;
|
||||||
|
import org.geysermc.geyser.translator.protocol.PacketTranslator;
|
||||||
|
import org.geysermc.geyser.translator.protocol.Translator;
|
||||||
|
|
||||||
|
@Translator(packet = ClientboundChunkBatchFinishedPacket.class)
|
||||||
|
public class JavaChunkBatchFinishedTranslator extends PacketTranslator<ClientboundChunkBatchFinishedPacket> {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void translate(GeyserSession session, ClientboundChunkBatchFinishedPacket packet) {
|
||||||
|
// server just sent a batch of LevelChunkWithLightPackets
|
||||||
|
// the vanilla client uses a ChunkBatchSizeCalculator to calculate the desiredChunksPerTick,
|
||||||
|
// but currently we just send an arbitrary value. server clamps the value between 0.01 and 64.
|
||||||
|
session.sendDownstreamPacket(new ServerboundChunkBatchReceivedPacket(20));
|
||||||
|
}
|
||||||
|
}
|
|
@ -31,6 +31,7 @@ import com.github.steveice10.mc.protocol.packet.ingame.clientbound.level.Clientb
|
||||||
import org.cloudburstmc.math.vector.Vector3f;
|
import org.cloudburstmc.math.vector.Vector3f;
|
||||||
import org.cloudburstmc.math.vector.Vector3i;
|
import org.cloudburstmc.math.vector.Vector3i;
|
||||||
import org.cloudburstmc.nbt.NbtMap;
|
import org.cloudburstmc.nbt.NbtMap;
|
||||||
|
import org.cloudburstmc.protocol.bedrock.data.ParticleType;
|
||||||
import org.cloudburstmc.protocol.bedrock.data.SoundEvent;
|
import org.cloudburstmc.protocol.bedrock.data.SoundEvent;
|
||||||
import org.cloudburstmc.protocol.bedrock.packet.LevelEventGenericPacket;
|
import org.cloudburstmc.protocol.bedrock.packet.LevelEventGenericPacket;
|
||||||
import org.cloudburstmc.protocol.bedrock.packet.LevelEventPacket;
|
import org.cloudburstmc.protocol.bedrock.packet.LevelEventPacket;
|
||||||
|
@ -103,6 +104,10 @@ public class JavaLevelEventTranslator extends PacketTranslator<ClientboundLevelE
|
||||||
effectPacket.setPosition(pos);
|
effectPacket.setPosition(pos);
|
||||||
effectPacket.setData(0);
|
effectPacket.setData(0);
|
||||||
switch (levelEvent) {
|
switch (levelEvent) {
|
||||||
|
case BRUSH_BLOCK_COMPLETE -> {
|
||||||
|
effectPacket.setType(ParticleType.BRUSH_DUST);
|
||||||
|
session.playSoundEvent(SoundEvent.BRUSH_COMPLETED, pos); // todo 1.20.2 verify this
|
||||||
|
}
|
||||||
case COMPOSTER -> {
|
case COMPOSTER -> {
|
||||||
effectPacket.setType(org.cloudburstmc.protocol.bedrock.data.LevelEvent.PARTICLE_CROP_GROWTH);
|
effectPacket.setType(org.cloudburstmc.protocol.bedrock.data.LevelEvent.PARTICLE_CROP_GROWTH);
|
||||||
|
|
||||||
|
@ -224,6 +229,7 @@ public class JavaLevelEventTranslator extends PacketTranslator<ClientboundLevelE
|
||||||
BonemealGrowEventData growEventData = (BonemealGrowEventData) packet.getData();
|
BonemealGrowEventData growEventData = (BonemealGrowEventData) packet.getData();
|
||||||
effectPacket.setData(growEventData.getParticleCount());
|
effectPacket.setData(growEventData.getParticleCount());
|
||||||
}
|
}
|
||||||
|
case EGG_CRACK -> effectPacket.setType(ParticleType.VILLAGER_HAPPY); // both the lil green sparkle
|
||||||
case ENDERDRAGON_FIREBALL_EXPLODE -> {
|
case ENDERDRAGON_FIREBALL_EXPLODE -> {
|
||||||
effectPacket.setType(org.cloudburstmc.protocol.bedrock.data.LevelEvent.PARTICLE_EYE_OF_ENDER_DEATH); // TODO
|
effectPacket.setType(org.cloudburstmc.protocol.bedrock.data.LevelEvent.PARTICLE_EYE_OF_ENDER_DEATH); // TODO
|
||||||
|
|
||||||
|
|
|
@ -25,7 +25,7 @@
|
||||||
|
|
||||||
package org.geysermc.geyser.util;
|
package org.geysermc.geyser.util;
|
||||||
|
|
||||||
import com.github.steveice10.mc.protocol.packet.ingame.serverbound.ServerboundCustomPayloadPacket;
|
import com.github.steveice10.mc.protocol.packet.common.serverbound.ServerboundCustomPayloadPacket;
|
||||||
import com.google.common.base.Charsets;
|
import com.google.common.base.Charsets;
|
||||||
import org.geysermc.geyser.GeyserImpl;
|
import org.geysermc.geyser.GeyserImpl;
|
||||||
import org.geysermc.geyser.session.GeyserSession;
|
import org.geysermc.geyser.session.GeyserSession;
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
Subproject commit 587220aafb55e80f2a70d6eac2d4b89dc0a005bd
|
Subproject commit 31ce17e12e991bd841270b99f461641093f42564
|
|
@ -14,7 +14,7 @@ protocol-connection = "3.0.0.Beta1-20230908.171156-105"
|
||||||
raknet = "1.0.0.CR1-20230703.195238-9"
|
raknet = "1.0.0.CR1-20230703.195238-9"
|
||||||
blockstateupdater="1.20.30-20230918.203831-4"
|
blockstateupdater="1.20.30-20230918.203831-4"
|
||||||
mcauthlib = "d9d773e"
|
mcauthlib = "d9d773e"
|
||||||
mcprotocollib = "1.20-2-20230827.192136-1"
|
mcprotocollib = "1.20.2-1-20230926.224810-3"
|
||||||
adventure = "4.14.0"
|
adventure = "4.14.0"
|
||||||
adventure-platform = "4.3.0"
|
adventure-platform = "4.3.0"
|
||||||
junit = "5.9.2"
|
junit = "5.9.2"
|
||||||
|
|
Loading…
Reference in a new issue