Mirror von
https://github.com/GeyserMC/Geyser.git
synchronisiert 2024-09-08 20:43:04 +02:00
Don't store GameProfile class of players
This stores repetitive information, and also we don't currently use the signature, so it's wasted memory.
Dieser Commit ist enthalten in:
Ursprung
7a5321b78f
Commit
2a05dd57ff
@ -25,7 +25,6 @@
|
|||||||
|
|
||||||
package org.geysermc.geyser.entity.type.player;
|
package org.geysermc.geyser.entity.type.player;
|
||||||
|
|
||||||
import com.github.steveice10.mc.auth.data.GameProfile;
|
|
||||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata;
|
import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata;
|
||||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.Pose;
|
import com.github.steveice10.mc.protocol.data.game.entity.metadata.Pose;
|
||||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.Position;
|
import com.github.steveice10.mc.protocol.data.game.entity.metadata.Position;
|
||||||
@ -61,15 +60,21 @@ import org.geysermc.geyser.translator.text.MessageTranslator;
|
|||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
import java.util.UUID;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
@Getter @Setter
|
@Getter @Setter
|
||||||
public class PlayerEntity extends LivingEntity {
|
public class PlayerEntity extends LivingEntity {
|
||||||
public static final float SNEAKING_POSE_HEIGHT = 1.5f;
|
public static final float SNEAKING_POSE_HEIGHT = 1.5f;
|
||||||
|
|
||||||
private GameProfile profile;
|
|
||||||
private String username;
|
private String username;
|
||||||
private boolean playerList = true; // Player is in the player list
|
private boolean playerList = true; // Player is in the player list
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The textures property from the GameProfile.
|
||||||
|
*/
|
||||||
|
@Nullable
|
||||||
|
private String texturesProperty;
|
||||||
|
|
||||||
private Vector3i bedPosition;
|
private Vector3i bedPosition;
|
||||||
|
|
||||||
@ -82,11 +87,12 @@ public class PlayerEntity extends LivingEntity {
|
|||||||
*/
|
*/
|
||||||
private ParrotEntity rightParrot;
|
private ParrotEntity rightParrot;
|
||||||
|
|
||||||
public PlayerEntity(GeyserSession session, int entityId, long geyserId, GameProfile gameProfile, Vector3f position, Vector3f motion, float yaw, float pitch, float headYaw) {
|
public PlayerEntity(GeyserSession session, int entityId, long geyserId, UUID uuid, Vector3f position,
|
||||||
super(session, entityId, geyserId, gameProfile.getId(), EntityDefinitions.PLAYER, position, motion, yaw, pitch, headYaw);
|
Vector3f motion, float yaw, float pitch, float headYaw, String username, @Nullable String texturesProperty) {
|
||||||
|
super(session, entityId, geyserId, uuid, EntityDefinitions.PLAYER, position, motion, yaw, pitch, headYaw);
|
||||||
|
|
||||||
profile = gameProfile;
|
this.username = username;
|
||||||
username = gameProfile.getName();
|
this.texturesProperty = texturesProperty;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -25,7 +25,6 @@
|
|||||||
|
|
||||||
package org.geysermc.geyser.entity.type.player;
|
package org.geysermc.geyser.entity.type.player;
|
||||||
|
|
||||||
import com.github.steveice10.mc.auth.data.GameProfile;
|
|
||||||
import com.github.steveice10.mc.protocol.data.game.entity.attribute.Attribute;
|
import com.github.steveice10.mc.protocol.data.game.entity.attribute.Attribute;
|
||||||
import com.github.steveice10.mc.protocol.data.game.entity.attribute.AttributeType;
|
import com.github.steveice10.mc.protocol.data.game.entity.attribute.AttributeType;
|
||||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.Pose;
|
import com.github.steveice10.mc.protocol.data.game.entity.metadata.Pose;
|
||||||
@ -71,7 +70,7 @@ public class SessionPlayerEntity extends PlayerEntity {
|
|||||||
private int fakeTradeXp;
|
private int fakeTradeXp;
|
||||||
|
|
||||||
public SessionPlayerEntity(GeyserSession session) {
|
public SessionPlayerEntity(GeyserSession session) {
|
||||||
super(session, -1, 1, new GameProfile(UUID.randomUUID(), "unknown"), Vector3f.ZERO, Vector3f.ZERO, 0, 0, 0);
|
super(session, -1, 1, UUID.randomUUID(), Vector3f.ZERO, Vector3f.ZERO, 0, 0, 0, "unknown", null);
|
||||||
|
|
||||||
valid = true;
|
valid = true;
|
||||||
}
|
}
|
||||||
|
@ -25,7 +25,6 @@
|
|||||||
|
|
||||||
package org.geysermc.geyser.entity.type.player;
|
package org.geysermc.geyser.entity.type.player;
|
||||||
|
|
||||||
import com.github.steveice10.mc.auth.data.GameProfile;
|
|
||||||
import com.nukkitx.math.vector.Vector3f;
|
import com.nukkitx.math.vector.Vector3f;
|
||||||
import com.nukkitx.math.vector.Vector3i;
|
import com.nukkitx.math.vector.Vector3i;
|
||||||
import com.nukkitx.protocol.bedrock.data.PlayerPermission;
|
import com.nukkitx.protocol.bedrock.data.PlayerPermission;
|
||||||
@ -36,6 +35,8 @@ import com.nukkitx.protocol.bedrock.packet.AddPlayerPacket;
|
|||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import org.geysermc.geyser.session.GeyserSession;
|
import org.geysermc.geyser.session.GeyserSession;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A wrapper to handle skulls more effectively - skulls have to be treated as entities since there are no
|
* A wrapper to handle skulls more effectively - skulls have to be treated as entities since there are no
|
||||||
* custom player skulls in Bedrock.
|
* custom player skulls in Bedrock.
|
||||||
@ -48,8 +49,8 @@ public class SkullPlayerEntity extends PlayerEntity {
|
|||||||
@Getter
|
@Getter
|
||||||
private final int blockState;
|
private final int blockState;
|
||||||
|
|
||||||
public SkullPlayerEntity(GeyserSession session, long geyserId, GameProfile gameProfile, Vector3f position, float rotation, int blockState) {
|
public SkullPlayerEntity(GeyserSession session, long geyserId, Vector3f position, float rotation, int blockState, String texturesProperty) {
|
||||||
super(session, 0, geyserId, gameProfile, position, Vector3f.ZERO, rotation, 0, rotation);
|
super(session, 0, geyserId, UUID.randomUUID(), position, Vector3f.ZERO, rotation, 0, rotation, "", texturesProperty);
|
||||||
this.blockState = blockState;
|
this.blockState = blockState;
|
||||||
setPlayerList(false);
|
setPlayerList(false);
|
||||||
}
|
}
|
||||||
|
@ -25,7 +25,6 @@
|
|||||||
|
|
||||||
package org.geysermc.geyser.skin;
|
package org.geysermc.geyser.skin;
|
||||||
|
|
||||||
import com.github.steveice10.mc.auth.data.GameProfile;
|
|
||||||
import com.github.steveice10.opennbt.tag.builtin.CompoundTag;
|
import com.github.steveice10.opennbt.tag.builtin.CompoundTag;
|
||||||
import com.google.common.cache.CacheBuilder;
|
import com.google.common.cache.CacheBuilder;
|
||||||
import com.google.common.cache.CacheLoader;
|
import com.google.common.cache.CacheLoader;
|
||||||
@ -106,7 +105,7 @@ public class FakeHeadProvider {
|
|||||||
|
|
||||||
session.getPlayerWithCustomHeads().add(entity.getUuid());
|
session.getPlayerWithCustomHeads().add(entity.getUuid());
|
||||||
|
|
||||||
GameProfile.Property texturesProperty = entity.getProfile().getProperty("textures");
|
String texturesProperty = entity.getTexturesProperty();
|
||||||
|
|
||||||
SkinProvider.EXECUTOR_SERVICE.execute(() -> {
|
SkinProvider.EXECUTOR_SERVICE.execute(() -> {
|
||||||
try {
|
try {
|
||||||
@ -182,7 +181,7 @@ public class FakeHeadProvider {
|
|||||||
@Getter
|
@Getter
|
||||||
@Setter
|
@Setter
|
||||||
private static class FakeHeadEntry {
|
private static class FakeHeadEntry {
|
||||||
private final GameProfile.Property texturesProperty;
|
private final String texturesProperty;
|
||||||
private final String fakeHeadSkinUrl;
|
private final String fakeHeadSkinUrl;
|
||||||
private PlayerEntity entity;
|
private PlayerEntity entity;
|
||||||
|
|
||||||
@ -192,18 +191,7 @@ public class FakeHeadProvider {
|
|||||||
if (this == o) return true;
|
if (this == o) return true;
|
||||||
if (o == null || getClass() != o.getClass()) return false;
|
if (o == null || getClass() != o.getClass()) return false;
|
||||||
FakeHeadEntry that = (FakeHeadEntry) o;
|
FakeHeadEntry that = (FakeHeadEntry) o;
|
||||||
return equals(texturesProperty, that.texturesProperty) && Objects.equals(fakeHeadSkinUrl, that.fakeHeadSkinUrl);
|
return Objects.equals(texturesProperty, that.texturesProperty) && Objects.equals(fakeHeadSkinUrl, that.fakeHeadSkinUrl);
|
||||||
}
|
|
||||||
|
|
||||||
private boolean equals(GameProfile.Property a, GameProfile.Property b) {
|
|
||||||
//TODO actually fix this in MCAuthLib
|
|
||||||
if (a == b) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (a == null || b == null) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return Objects.equals(a.getName(), b.getName()) && Objects.equals(a.getValue(), b.getValue()) && Objects.equals(a.getSignature(), b.getSignature());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -26,7 +26,6 @@
|
|||||||
package org.geysermc.geyser.skin;
|
package org.geysermc.geyser.skin;
|
||||||
|
|
||||||
import com.fasterxml.jackson.databind.JsonNode;
|
import com.fasterxml.jackson.databind.JsonNode;
|
||||||
import com.github.steveice10.mc.auth.data.GameProfile;
|
|
||||||
import com.github.steveice10.opennbt.tag.builtin.CompoundTag;
|
import com.github.steveice10.opennbt.tag.builtin.CompoundTag;
|
||||||
import com.github.steveice10.opennbt.tag.builtin.ListTag;
|
import com.github.steveice10.opennbt.tag.builtin.ListTag;
|
||||||
import com.github.steveice10.opennbt.tag.builtin.StringTag;
|
import com.github.steveice10.opennbt.tag.builtin.StringTag;
|
||||||
@ -34,9 +33,9 @@ import com.nukkitx.protocol.bedrock.data.skin.ImageData;
|
|||||||
import com.nukkitx.protocol.bedrock.data.skin.SerializedSkin;
|
import com.nukkitx.protocol.bedrock.data.skin.SerializedSkin;
|
||||||
import com.nukkitx.protocol.bedrock.packet.PlayerListPacket;
|
import com.nukkitx.protocol.bedrock.packet.PlayerListPacket;
|
||||||
import org.geysermc.geyser.GeyserImpl;
|
import org.geysermc.geyser.GeyserImpl;
|
||||||
import org.geysermc.geyser.session.auth.AuthType;
|
|
||||||
import org.geysermc.geyser.entity.type.player.PlayerEntity;
|
import org.geysermc.geyser.entity.type.player.PlayerEntity;
|
||||||
import org.geysermc.geyser.session.GeyserSession;
|
import org.geysermc.geyser.session.GeyserSession;
|
||||||
|
import org.geysermc.geyser.session.auth.AuthType;
|
||||||
import org.geysermc.geyser.session.auth.BedrockClientData;
|
import org.geysermc.geyser.session.auth.BedrockClientData;
|
||||||
import org.geysermc.geyser.text.GeyserLocale;
|
import org.geysermc.geyser.text.GeyserLocale;
|
||||||
|
|
||||||
@ -54,7 +53,7 @@ public class SkinManager {
|
|||||||
* Builds a Bedrock player list entry from our existing, cached Bedrock skin information
|
* Builds a Bedrock player list entry from our existing, cached Bedrock skin information
|
||||||
*/
|
*/
|
||||||
public static PlayerListPacket.Entry buildCachedEntry(GeyserSession session, PlayerEntity playerEntity) {
|
public static PlayerListPacket.Entry buildCachedEntry(GeyserSession session, PlayerEntity playerEntity) {
|
||||||
GameProfileData data = GameProfileData.from(playerEntity.getProfile());
|
GameProfileData data = GameProfileData.from(playerEntity);
|
||||||
SkinProvider.Cape cape = SkinProvider.getCachedCape(data.capeUrl());
|
SkinProvider.Cape cape = SkinProvider.getCachedCape(data.capeUrl());
|
||||||
SkinProvider.SkinGeometry geometry = SkinProvider.SkinGeometry.getLegacy(data.isAlex());
|
SkinProvider.SkinGeometry geometry = SkinProvider.SkinGeometry.getLegacy(data.isAlex());
|
||||||
|
|
||||||
@ -65,8 +64,8 @@ public class SkinManager {
|
|||||||
|
|
||||||
return buildEntryManually(
|
return buildEntryManually(
|
||||||
session,
|
session,
|
||||||
playerEntity.getProfile().getId(),
|
playerEntity.getUuid(),
|
||||||
playerEntity.getProfile().getName(),
|
playerEntity.getUsername(),
|
||||||
playerEntity.getGeyserId(),
|
playerEntity.getGeyserId(),
|
||||||
skin.getTextureUrl(),
|
skin.getTextureUrl(),
|
||||||
skin.getSkinData(),
|
skin.getSkinData(),
|
||||||
@ -227,31 +226,31 @@ public class SkinManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generate the GameProfileData from the given GameProfile
|
* Generate the GameProfileData from the given player entity
|
||||||
*
|
*
|
||||||
* @param profile GameProfile to build the GameProfileData from
|
* @param entity entity to build the GameProfileData from
|
||||||
* @return The built GameProfileData
|
* @return The built GameProfileData
|
||||||
*/
|
*/
|
||||||
public static GameProfileData from(GameProfile profile) {
|
public static GameProfileData from(PlayerEntity entity) {
|
||||||
try {
|
try {
|
||||||
GameProfile.Property skinProperty = profile.getProperty("textures");
|
String texturesProperty = entity.getTexturesProperty();
|
||||||
|
|
||||||
if (skinProperty == null) {
|
if (texturesProperty == null) {
|
||||||
// Likely offline mode
|
// Likely offline mode
|
||||||
return loadBedrockOrOfflineSkin(profile);
|
return loadBedrockOrOfflineSkin(entity);
|
||||||
}
|
}
|
||||||
GameProfileData data = loadFromJson(skinProperty.getValue());
|
GameProfileData data = loadFromJson(texturesProperty);
|
||||||
if (data != null) {
|
if (data != null) {
|
||||||
return data;
|
return data;
|
||||||
} else {
|
} else {
|
||||||
return loadBedrockOrOfflineSkin(profile);
|
return loadBedrockOrOfflineSkin(entity);
|
||||||
}
|
}
|
||||||
} catch (IOException exception) {
|
} catch (IOException exception) {
|
||||||
GeyserImpl.getInstance().getLogger().debug("Something went wrong while processing skin for " + profile.getName());
|
GeyserImpl.getInstance().getLogger().debug("Something went wrong while processing skin for " + entity.getUsername());
|
||||||
if (GeyserImpl.getInstance().getConfig().isDebugMode()) {
|
if (GeyserImpl.getInstance().getConfig().isDebugMode()) {
|
||||||
exception.printStackTrace();
|
exception.printStackTrace();
|
||||||
}
|
}
|
||||||
return loadBedrockOrOfflineSkin(profile);
|
return loadBedrockOrOfflineSkin(entity);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -280,14 +279,15 @@ public class SkinManager {
|
|||||||
* @return default skin with default cape when texture data is invalid, or the Bedrock player's skin if this
|
* @return default skin with default cape when texture data is invalid, or the Bedrock player's skin if this
|
||||||
* is a Bedrock player.
|
* is a Bedrock player.
|
||||||
*/
|
*/
|
||||||
private static GameProfileData loadBedrockOrOfflineSkin(GameProfile profile) {
|
private static GameProfileData loadBedrockOrOfflineSkin(PlayerEntity entity) {
|
||||||
// Fallback to the offline mode of working it out
|
// Fallback to the offline mode of working it out
|
||||||
boolean isAlex = (Math.abs(profile.getId().hashCode() % 2) == 1);
|
UUID uuid = entity.getUuid();
|
||||||
|
boolean isAlex = (Math.abs(uuid.hashCode() % 2) == 1);
|
||||||
|
|
||||||
String skinUrl = isAlex ? SkinProvider.EMPTY_SKIN_ALEX.getTextureUrl() : SkinProvider.EMPTY_SKIN.getTextureUrl();
|
String skinUrl = isAlex ? SkinProvider.EMPTY_SKIN_ALEX.getTextureUrl() : SkinProvider.EMPTY_SKIN.getTextureUrl();
|
||||||
String capeUrl = SkinProvider.EMPTY_CAPE.getTextureUrl();
|
String capeUrl = SkinProvider.EMPTY_CAPE.getTextureUrl();
|
||||||
if (("steve".equals(skinUrl) || "alex".equals(skinUrl)) && GeyserImpl.getInstance().getConfig().getRemote().getAuthType() != AuthType.ONLINE) {
|
if (("steve".equals(skinUrl) || "alex".equals(skinUrl)) && GeyserImpl.getInstance().getConfig().getRemote().getAuthType() != AuthType.ONLINE) {
|
||||||
GeyserSession session = GeyserImpl.getInstance().connectionByUuid(profile.getId());
|
GeyserSession session = GeyserImpl.getInstance().connectionByUuid(uuid);
|
||||||
|
|
||||||
if (session != null) {
|
if (session != null) {
|
||||||
skinUrl = session.getClientData().getSkinId();
|
skinUrl = session.getClientData().getSkinId();
|
||||||
|
@ -27,7 +27,6 @@ package org.geysermc.geyser.skin;
|
|||||||
|
|
||||||
import com.fasterxml.jackson.databind.JsonNode;
|
import com.fasterxml.jackson.databind.JsonNode;
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
import com.github.steveice10.mc.auth.data.GameProfile;
|
|
||||||
import com.github.steveice10.opennbt.tag.builtin.CompoundTag;
|
import com.github.steveice10.opennbt.tag.builtin.CompoundTag;
|
||||||
import com.github.steveice10.opennbt.tag.builtin.IntArrayTag;
|
import com.github.steveice10.opennbt.tag.builtin.IntArrayTag;
|
||||||
import com.github.steveice10.opennbt.tag.builtin.Tag;
|
import com.github.steveice10.opennbt.tag.builtin.Tag;
|
||||||
@ -53,7 +52,6 @@ import java.io.IOException;
|
|||||||
import java.net.HttpURLConnection;
|
import java.net.HttpURLConnection;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.util.List;
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.concurrent.*;
|
import java.util.concurrent.*;
|
||||||
import java.util.function.Predicate;
|
import java.util.function.Predicate;
|
||||||
@ -157,7 +155,7 @@ public class SkinProvider {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static CompletableFuture<SkinProvider.SkinData> requestSkinData(PlayerEntity entity) {
|
public static CompletableFuture<SkinProvider.SkinData> requestSkinData(PlayerEntity entity) {
|
||||||
SkinManager.GameProfileData data = SkinManager.GameProfileData.from(entity.getProfile());
|
SkinManager.GameProfileData data = SkinManager.GameProfileData.from(entity);
|
||||||
|
|
||||||
return requestSkinAndCape(entity.getUuid(), data.skinUrl(), data.capeUrl())
|
return requestSkinAndCape(entity.getUuid(), data.skinUrl(), data.capeUrl())
|
||||||
.thenApplyAsync(skinAndCape -> {
|
.thenApplyAsync(skinAndCape -> {
|
||||||
@ -546,12 +544,11 @@ public class SkinProvider {
|
|||||||
* @param skullOwner the CompoundTag of the skull with no textures
|
* @param skullOwner the CompoundTag of the skull with no textures
|
||||||
* @return a completable GameProfile with textures included
|
* @return a completable GameProfile with textures included
|
||||||
*/
|
*/
|
||||||
public static CompletableFuture<GameProfile> requestTexturesFromUsername(CompoundTag skullOwner) {
|
public static CompletableFuture<String> requestTexturesFromUsername(CompoundTag skullOwner) {
|
||||||
return CompletableFuture.supplyAsync(() -> {
|
return CompletableFuture.supplyAsync(() -> {
|
||||||
Tag uuidTag = skullOwner.get("Id");
|
Tag uuidTag = skullOwner.get("Id");
|
||||||
String uuidToString = "";
|
String uuidToString = "";
|
||||||
JsonNode node;
|
JsonNode node;
|
||||||
GameProfile gameProfile = new GameProfile(UUID.randomUUID(), "");
|
|
||||||
boolean retrieveUuidFromInternet = !(uuidTag instanceof IntArrayTag); // also covers null check
|
boolean retrieveUuidFromInternet = !(uuidTag instanceof IntArrayTag); // also covers null check
|
||||||
|
|
||||||
if (!retrieveUuidFromInternet) {
|
if (!retrieveUuidFromInternet) {
|
||||||
@ -577,15 +574,12 @@ public class SkinProvider {
|
|||||||
|
|
||||||
// Get textures from UUID
|
// Get textures from UUID
|
||||||
node = WebUtils.getJson("https://sessionserver.mojang.com/session/minecraft/profile/" + uuidToString);
|
node = WebUtils.getJson("https://sessionserver.mojang.com/session/minecraft/profile/" + uuidToString);
|
||||||
List<GameProfile.Property> profileProperties = new ArrayList<>();
|
|
||||||
JsonNode properties = node.get("properties");
|
JsonNode properties = node.get("properties");
|
||||||
if (properties == null) {
|
if (properties == null) {
|
||||||
GeyserImpl.getInstance().getLogger().debug("No properties found in Mojang response for " + uuidToString);
|
GeyserImpl.getInstance().getLogger().debug("No properties found in Mojang response for " + uuidToString);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
profileProperties.add(new GameProfile.Property("textures", node.get("properties").get(0).get("value").asText()));
|
return node.get("properties").get(0).get("value").asText();
|
||||||
gameProfile.setProperties(profileProperties);
|
|
||||||
return gameProfile;
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
if (GeyserImpl.getInstance().getConfig().isDebugMode()) {
|
if (GeyserImpl.getInstance().getConfig().isDebugMode()) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
|
@ -50,7 +50,7 @@ public class SkullSkinManager extends SkinManager {
|
|||||||
|
|
||||||
public static void requestAndHandleSkin(PlayerEntity entity, GeyserSession session,
|
public static void requestAndHandleSkin(PlayerEntity entity, GeyserSession session,
|
||||||
Consumer<SkinProvider.Skin> skinConsumer) {
|
Consumer<SkinProvider.Skin> skinConsumer) {
|
||||||
GameProfileData data = GameProfileData.from(entity.getProfile());
|
GameProfileData data = GameProfileData.from(entity);
|
||||||
|
|
||||||
SkinProvider.requestSkin(entity.getUuid(), data.skinUrl(), true)
|
SkinProvider.requestSkin(entity.getUuid(), data.skinUrl(), true)
|
||||||
.whenCompleteAsync((skin, throwable) -> {
|
.whenCompleteAsync((skin, throwable) -> {
|
||||||
|
@ -25,7 +25,6 @@
|
|||||||
|
|
||||||
package org.geysermc.geyser.translator.level.block.entity;
|
package org.geysermc.geyser.translator.level.block.entity;
|
||||||
|
|
||||||
import com.github.steveice10.mc.auth.data.GameProfile;
|
|
||||||
import com.github.steveice10.mc.protocol.data.game.level.block.BlockEntityType;
|
import com.github.steveice10.mc.protocol.data.game.level.block.BlockEntityType;
|
||||||
import com.github.steveice10.opennbt.tag.builtin.CompoundTag;
|
import com.github.steveice10.opennbt.tag.builtin.CompoundTag;
|
||||||
import com.github.steveice10.opennbt.tag.builtin.ListTag;
|
import com.github.steveice10.opennbt.tag.builtin.ListTag;
|
||||||
@ -35,15 +34,12 @@ import com.nukkitx.math.vector.Vector3i;
|
|||||||
import com.nukkitx.nbt.NbtMapBuilder;
|
import com.nukkitx.nbt.NbtMapBuilder;
|
||||||
import com.nukkitx.protocol.bedrock.data.entity.EntityFlag;
|
import com.nukkitx.protocol.bedrock.data.entity.EntityFlag;
|
||||||
import org.geysermc.geyser.entity.type.player.SkullPlayerEntity;
|
import org.geysermc.geyser.entity.type.player.SkullPlayerEntity;
|
||||||
import org.geysermc.geyser.session.GeyserSession;
|
|
||||||
import org.geysermc.geyser.level.block.BlockStateValues;
|
import org.geysermc.geyser.level.block.BlockStateValues;
|
||||||
|
import org.geysermc.geyser.session.GeyserSession;
|
||||||
import org.geysermc.geyser.skin.SkinProvider;
|
import org.geysermc.geyser.skin.SkinProvider;
|
||||||
import org.geysermc.geyser.skin.SkullSkinManager;
|
import org.geysermc.geyser.skin.SkullSkinManager;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.LinkedHashMap;
|
import java.util.LinkedHashMap;
|
||||||
import java.util.List;
|
|
||||||
import java.util.UUID;
|
|
||||||
import java.util.concurrent.CompletableFuture;
|
import java.util.concurrent.CompletableFuture;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
@ -62,7 +58,7 @@ public class SkullBlockEntityTranslator extends BlockEntityTranslator implements
|
|||||||
builder.put("SkullType", skullVariant);
|
builder.put("SkullType", skullVariant);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static CompletableFuture<GameProfile> getProfile(CompoundTag tag) {
|
private static CompletableFuture<String> getTextures(CompoundTag tag) {
|
||||||
CompoundTag owner = tag.get("SkullOwner");
|
CompoundTag owner = tag.get("SkullOwner");
|
||||||
if (owner != null) {
|
if (owner != null) {
|
||||||
CompoundTag properties = owner.get("Properties");
|
CompoundTag properties = owner.get("Properties");
|
||||||
@ -73,13 +69,7 @@ public class SkullBlockEntityTranslator extends BlockEntityTranslator implements
|
|||||||
ListTag textures = properties.get("textures");
|
ListTag textures = properties.get("textures");
|
||||||
LinkedHashMap<?,?> tag1 = (LinkedHashMap<?,?>) textures.get(0).getValue();
|
LinkedHashMap<?,?> tag1 = (LinkedHashMap<?,?>) textures.get(0).getValue();
|
||||||
StringTag texture = (StringTag) tag1.get("Value");
|
StringTag texture = (StringTag) tag1.get("Value");
|
||||||
|
return CompletableFuture.completedFuture(texture.getValue());
|
||||||
List<GameProfile.Property> profileProperties = new ArrayList<>();
|
|
||||||
|
|
||||||
GameProfile gameProfile = new GameProfile(UUID.randomUUID(), "");
|
|
||||||
profileProperties.add(new GameProfile.Property("textures", texture.getValue()));
|
|
||||||
gameProfile.setProperties(profileProperties);
|
|
||||||
return CompletableFuture.completedFuture(gameProfile);
|
|
||||||
}
|
}
|
||||||
return CompletableFuture.completedFuture(null);
|
return CompletableFuture.completedFuture(null);
|
||||||
}
|
}
|
||||||
@ -108,21 +98,21 @@ public class SkullBlockEntityTranslator extends BlockEntityTranslator implements
|
|||||||
Vector3i blockPosition = Vector3i.from(posX, posY, posZ);
|
Vector3i blockPosition = Vector3i.from(posX, posY, posZ);
|
||||||
Vector3f entityPosition = Vector3f.from(x, y, z);
|
Vector3f entityPosition = Vector3f.from(x, y, z);
|
||||||
|
|
||||||
getProfile(tag).whenComplete((gameProfile, throwable) -> {
|
getTextures(tag).whenComplete((texturesProperty, throwable) -> {
|
||||||
if (gameProfile == null) {
|
if (texturesProperty == null) {
|
||||||
session.getGeyser().getLogger().debug("Custom skull with invalid SkullOwner tag: " + blockPosition + " " + tag);
|
session.getGeyser().getLogger().debug("Custom skull with invalid SkullOwner tag: " + blockPosition + " " + tag);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (session.getEventLoop().inEventLoop()) {
|
if (session.getEventLoop().inEventLoop()) {
|
||||||
spawnPlayer(session, gameProfile, blockPosition, entityPosition, rotation, blockState);
|
spawnPlayer(session, texturesProperty, blockPosition, entityPosition, rotation, blockState);
|
||||||
} else {
|
} else {
|
||||||
session.executeInEventLoop(() -> spawnPlayer(session, gameProfile, blockPosition, entityPosition, rotation, blockState));
|
session.executeInEventLoop(() -> spawnPlayer(session, texturesProperty, blockPosition, entityPosition, rotation, blockState));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void spawnPlayer(GeyserSession session, GameProfile profile, Vector3i blockPosition,
|
private static void spawnPlayer(GeyserSession session, String texturesProperty, Vector3i blockPosition,
|
||||||
Vector3f entityPosition, float rotation, int blockState) {
|
Vector3f entityPosition, float rotation, int blockState) {
|
||||||
long geyserId = session.getEntityCache().getNextEntityId().incrementAndGet();
|
long geyserId = session.getEntityCache().getNextEntityId().incrementAndGet();
|
||||||
|
|
||||||
@ -132,7 +122,7 @@ public class SkullBlockEntityTranslator extends BlockEntityTranslator implements
|
|||||||
existingSkull.despawnEntity(blockPosition);
|
existingSkull.despawnEntity(blockPosition);
|
||||||
}
|
}
|
||||||
|
|
||||||
SkullPlayerEntity player = new SkullPlayerEntity(session, geyserId, profile, entityPosition, rotation, blockState);
|
SkullPlayerEntity player = new SkullPlayerEntity(session, geyserId, entityPosition, rotation, blockState, texturesProperty);
|
||||||
|
|
||||||
// Cache entity
|
// Cache entity
|
||||||
session.getSkullCache().put(blockPosition, player);
|
session.getSkullCache().put(blockPosition, player);
|
||||||
|
@ -25,6 +25,7 @@
|
|||||||
|
|
||||||
package org.geysermc.geyser.translator.protocol.java.entity.player;
|
package org.geysermc.geyser.translator.protocol.java.entity.player;
|
||||||
|
|
||||||
|
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.ClientboundPlayerInfoPacket;
|
import com.github.steveice10.mc.protocol.packet.ingame.clientbound.ClientboundPlayerInfoPacket;
|
||||||
@ -50,31 +51,38 @@ public class JavaPlayerInfoTranslator extends PacketTranslator<ClientboundPlayer
|
|||||||
for (PlayerListEntry entry : packet.getEntries()) {
|
for (PlayerListEntry entry : packet.getEntries()) {
|
||||||
switch (packet.getAction()) {
|
switch (packet.getAction()) {
|
||||||
case ADD_PLAYER -> {
|
case ADD_PLAYER -> {
|
||||||
|
GameProfile profile = entry.getProfile();
|
||||||
PlayerEntity playerEntity;
|
PlayerEntity playerEntity;
|
||||||
boolean self = entry.getProfile().getId().equals(session.getPlayerEntity().getUuid());
|
boolean self = profile.getId().equals(session.getPlayerEntity().getUuid());
|
||||||
|
|
||||||
if (self) {
|
if (self) {
|
||||||
// Entity is ourself
|
// Entity is ourself
|
||||||
playerEntity = session.getPlayerEntity();
|
playerEntity = session.getPlayerEntity();
|
||||||
} else {
|
} else {
|
||||||
playerEntity = session.getEntityCache().getPlayerEntity(entry.getProfile().getId());
|
playerEntity = session.getEntityCache().getPlayerEntity(profile.getId());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GameProfile.Property textures = profile.getProperty("textures");
|
||||||
|
String texturesProperty = textures == null ? null : textures.getValue();
|
||||||
|
|
||||||
if (playerEntity == null) {
|
if (playerEntity == null) {
|
||||||
// It's a new player
|
// It's a new player
|
||||||
playerEntity = new PlayerEntity(
|
playerEntity = new PlayerEntity(
|
||||||
session,
|
session,
|
||||||
-1,
|
-1,
|
||||||
session.getEntityCache().getNextEntityId().incrementAndGet(),
|
session.getEntityCache().getNextEntityId().incrementAndGet(),
|
||||||
entry.getProfile(),
|
profile.getId(),
|
||||||
Vector3f.ZERO,
|
Vector3f.ZERO,
|
||||||
Vector3f.ZERO,
|
Vector3f.ZERO,
|
||||||
0, 0, 0
|
0, 0, 0,
|
||||||
|
profile.getName(),
|
||||||
|
texturesProperty
|
||||||
);
|
);
|
||||||
|
|
||||||
session.getEntityCache().addPlayerEntity(playerEntity);
|
session.getEntityCache().addPlayerEntity(playerEntity);
|
||||||
} else {
|
} else {
|
||||||
playerEntity.setProfile(entry.getProfile());
|
playerEntity.setUsername(profile.getName());
|
||||||
|
playerEntity.setTexturesProperty(texturesProperty);
|
||||||
}
|
}
|
||||||
|
|
||||||
playerEntity.setPlayerList(true);
|
playerEntity.setPlayerList(true);
|
||||||
|
@ -48,7 +48,9 @@ public class JavaAddPlayerTranslator extends PacketTranslator<ClientboundAddPlay
|
|||||||
PlayerEntity entity;
|
PlayerEntity entity;
|
||||||
if (packet.getUuid().equals(session.getPlayerEntity().getUuid())) {
|
if (packet.getUuid().equals(session.getPlayerEntity().getUuid())) {
|
||||||
// Server is sending a fake version of the current player
|
// Server is sending a fake version of the current player
|
||||||
entity = new PlayerEntity(session, packet.getEntityId(), session.getEntityCache().getNextEntityId().incrementAndGet(), session.getPlayerEntity().getProfile(), position, Vector3f.ZERO, yaw, pitch, headYaw);
|
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 {
|
} else {
|
||||||
entity = session.getEntityCache().getPlayerEntity(packet.getUuid());
|
entity = session.getEntityCache().getPlayerEntity(packet.getUuid());
|
||||||
if (entity == null) {
|
if (entity == null) {
|
||||||
|
Laden…
In neuem Issue referenzieren
Einen Benutzer sperren