mirror of
https://github.com/GeyserMC/Geyser.git
synced 2025-12-19 14:59:27 +00:00
Fix: "Invalid skin length" issue, code-of-conduct screen not appearing correctly on server switching, InputMode / UiProfile not being read correctly
Fixes https://github.com/GeyserMC/Geyser/issues/5995, fixes https://github.com/GeyserMC/Geyser/issues/5994
This commit is contained in:
@@ -747,6 +747,7 @@ public class GeyserSession implements GeyserConnection, GeyserCommandSource {
|
|||||||
private boolean allowVibrantVisuals = true;
|
private boolean allowVibrantVisuals = true;
|
||||||
|
|
||||||
@Accessors(fluent = true)
|
@Accessors(fluent = true)
|
||||||
|
@Setter
|
||||||
private boolean hasAcceptedCodeOfConduct = false;
|
private boolean hasAcceptedCodeOfConduct = false;
|
||||||
|
|
||||||
@Accessors(fluent = true)
|
@Accessors(fluent = true)
|
||||||
|
|||||||
@@ -46,6 +46,7 @@ import org.geysermc.floodgate.util.UiProfile;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.lang.reflect.Type;
|
import java.lang.reflect.Type;
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.util.Base64;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
@Getter
|
@Getter
|
||||||
@@ -62,7 +63,8 @@ public final class BedrockClientData {
|
|||||||
@SerializedName(value = "SkinId")
|
@SerializedName(value = "SkinId")
|
||||||
private String skinId;
|
private String skinId;
|
||||||
@SerializedName(value = "SkinData")
|
@SerializedName(value = "SkinData")
|
||||||
private String skinData;
|
@JsonAdapter(value = StringToByteDeserializer.class)
|
||||||
|
private byte[] skinData;
|
||||||
@SerializedName(value = "SkinImageHeight")
|
@SerializedName(value = "SkinImageHeight")
|
||||||
private int skinImageHeight;
|
private int skinImageHeight;
|
||||||
@SerializedName(value = "SkinImageWidth")
|
@SerializedName(value = "SkinImageWidth")
|
||||||
@@ -79,9 +81,11 @@ public final class BedrockClientData {
|
|||||||
@SerializedName(value = "CapeOnClassicSkin")
|
@SerializedName(value = "CapeOnClassicSkin")
|
||||||
private boolean capeOnClassicSkin;
|
private boolean capeOnClassicSkin;
|
||||||
@SerializedName(value = "SkinResourcePatch")
|
@SerializedName(value = "SkinResourcePatch")
|
||||||
private String geometryName;
|
@JsonAdapter(value = StringToByteDeserializer.class)
|
||||||
|
private byte[] geometryName;
|
||||||
@SerializedName(value = "SkinGeometryData")
|
@SerializedName(value = "SkinGeometryData")
|
||||||
private String geometryData;
|
@JsonAdapter(value = StringToByteDeserializer.class)
|
||||||
|
private byte[] geometryData;
|
||||||
@SerializedName(value = "PersonaSkin")
|
@SerializedName(value = "PersonaSkin")
|
||||||
private boolean personaSkin;
|
private boolean personaSkin;
|
||||||
@SerializedName(value = "PremiumSkin")
|
@SerializedName(value = "PremiumSkin")
|
||||||
@@ -95,12 +99,15 @@ public final class BedrockClientData {
|
|||||||
@JsonAdapter(value = IntToEnumTypeFactory.class)
|
@JsonAdapter(value = IntToEnumTypeFactory.class)
|
||||||
private DeviceOs deviceOs;
|
private DeviceOs deviceOs;
|
||||||
@SerializedName(value = "UIProfile")
|
@SerializedName(value = "UIProfile")
|
||||||
|
@JsonAdapter(value = IntToEnumTypeFactory.class)
|
||||||
private UiProfile uiProfile;
|
private UiProfile uiProfile;
|
||||||
@SerializedName(value = "GuiScale")
|
@SerializedName(value = "GuiScale")
|
||||||
private int guiScale;
|
private int guiScale;
|
||||||
@SerializedName(value = "CurrentInputMode")
|
@SerializedName(value = "CurrentInputMode")
|
||||||
|
@JsonAdapter(value = IntToEnumTypeFactory.class)
|
||||||
private InputMode currentInputMode;
|
private InputMode currentInputMode;
|
||||||
@SerializedName(value = "DefaultInputMode")
|
@SerializedName(value = "DefaultInputMode")
|
||||||
|
@JsonAdapter(value = IntToEnumTypeFactory.class)
|
||||||
private InputMode defaultInputMode;
|
private InputMode defaultInputMode;
|
||||||
@SerializedName("PlatformOnlineId")
|
@SerializedName("PlatformOnlineId")
|
||||||
private String platformOnlineId;
|
private String platformOnlineId;
|
||||||
@@ -144,7 +151,7 @@ public final class BedrockClientData {
|
|||||||
private static final class StringToByteDeserializer implements JsonDeserializer<byte[]> {
|
private static final class StringToByteDeserializer implements JsonDeserializer<byte[]> {
|
||||||
@Override
|
@Override
|
||||||
public byte[] deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
|
public byte[] deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
|
||||||
return json.getAsString().getBytes(StandardCharsets.UTF_8);
|
return Base64.getDecoder().decode(json.getAsString().getBytes(StandardCharsets.UTF_8));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -29,8 +29,6 @@ import com.google.common.cache.Cache;
|
|||||||
import com.google.common.cache.CacheBuilder;
|
import com.google.common.cache.CacheBuilder;
|
||||||
import com.google.gson.JsonObject;
|
import com.google.gson.JsonObject;
|
||||||
import com.google.gson.JsonPrimitive;
|
import com.google.gson.JsonPrimitive;
|
||||||
import com.google.common.cache.Cache;
|
|
||||||
import com.google.common.cache.CacheBuilder;
|
|
||||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||||
import org.cloudburstmc.nbt.NbtMap;
|
import org.cloudburstmc.nbt.NbtMap;
|
||||||
import org.cloudburstmc.nbt.NbtType;
|
import org.cloudburstmc.nbt.NbtType;
|
||||||
@@ -312,11 +310,11 @@ public class SkinManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
byte[] skinBytes = Base64.getDecoder().decode(clientData.getSkinData().getBytes(StandardCharsets.UTF_8));
|
byte[] skinBytes = clientData.getSkinData();
|
||||||
byte[] capeBytes = clientData.getCapeData();
|
byte[] capeBytes = clientData.getCapeData();
|
||||||
|
|
||||||
byte[] geometryNameBytes = Base64.getDecoder().decode(clientData.getGeometryName().getBytes(StandardCharsets.UTF_8));
|
byte[] geometryNameBytes = clientData.getGeometryName();
|
||||||
byte[] geometryBytes = Base64.getDecoder().decode(clientData.getGeometryData().getBytes(StandardCharsets.UTF_8));
|
byte[] geometryBytes = clientData.getGeometryData();
|
||||||
|
|
||||||
if (skinBytes.length <= (128 * 128 * 4) && !clientData.isPersonaSkin()) {
|
if (skinBytes.length <= (128 * 128 * 4) && !clientData.isPersonaSkin()) {
|
||||||
SkinProvider.storeBedrockSkin(playerEntity.getUuid(), clientData.getSkinId(), skinBytes);
|
SkinProvider.storeBedrockSkin(playerEntity.getUuid(), clientData.getSkinId(), skinBytes);
|
||||||
|
|||||||
@@ -74,6 +74,9 @@ public class JavaLoginFinishedTranslator extends PacketTranslator<ClientboundLog
|
|||||||
session.setToken(null);
|
session.setToken(null);
|
||||||
session.getClientData().setOriginalString(null);
|
session.getClientData().setOriginalString(null);
|
||||||
|
|
||||||
|
// Reset code of conduct accepted state, mirrors Java Edition
|
||||||
|
session.hasAcceptedCodeOfConduct(false);
|
||||||
|
|
||||||
// configuration phase stuff that the vanilla client replies with after receiving the GameProfilePacket
|
// configuration phase stuff that the vanilla client replies with after receiving the GameProfilePacket
|
||||||
session.sendDownstreamPacket(new ServerboundCustomPayloadPacket(Key.key("brand"), PluginMessageUtils.getGeyserBrandData()), ProtocolState.CONFIGURATION);
|
session.sendDownstreamPacket(new ServerboundCustomPayloadPacket(Key.key("brand"), PluginMessageUtils.getGeyserBrandData()), ProtocolState.CONFIGURATION);
|
||||||
session.sendJavaClientSettings();
|
session.sendJavaClientSettings();
|
||||||
|
|||||||
@@ -44,6 +44,9 @@ public class JavaStartConfigurationTranslator extends PacketTranslator<Clientbou
|
|||||||
erosionHandler.close();
|
erosionHandler.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Reset code of conduct being accepted
|
||||||
|
session.hasAcceptedCodeOfConduct(false);
|
||||||
|
|
||||||
ChunkUtils.sendEmptyChunks(session, session.getPlayerEntity().position().toInt(), session.getServerRenderDistance(), false);
|
ChunkUtils.sendEmptyChunks(session, session.getPlayerEntity().position().toInt(), session.getServerRenderDistance(), false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user