mirror of
https://github.com/GeyserMC/Geyser.git
synced 2025-12-19 14:59:27 +00:00
Translate custom skull items if the profile is resolved
This commit is contained in:
@@ -31,7 +31,6 @@ import net.kyori.adventure.text.Component;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
import org.cloudburstmc.math.vector.Vector3f;
|
||||
import org.cloudburstmc.math.vector.Vector3i;
|
||||
import org.cloudburstmc.nbt.NbtMap;
|
||||
import org.cloudburstmc.protocol.bedrock.data.Ability;
|
||||
import org.cloudburstmc.protocol.bedrock.data.AbilityLayer;
|
||||
import org.cloudburstmc.protocol.bedrock.data.GameType;
|
||||
@@ -180,8 +179,8 @@ public class PlayerEntity extends LivingEntity implements GeyserPlayerEntity {
|
||||
this.initializeMetadata();
|
||||
|
||||
// Explicitly reset all metadata not handled by initializeMetadata
|
||||
setParrot(null, true);
|
||||
setParrot(null, false);
|
||||
setParrot(OptionalInt.empty(), true);
|
||||
setParrot(OptionalInt.empty(), false);
|
||||
}
|
||||
|
||||
public void sendPlayer() {
|
||||
|
||||
@@ -30,9 +30,11 @@ import org.geysermc.geyser.item.TooltipOptions;
|
||||
import org.geysermc.geyser.item.components.Rarity;
|
||||
import org.geysermc.geyser.level.block.type.Block;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
import org.geysermc.geyser.skin.SkinManager;
|
||||
import org.geysermc.geyser.text.ChatColor;
|
||||
import org.geysermc.geyser.text.MinecraftLocale;
|
||||
import org.geysermc.geyser.translator.item.BedrockItemBuilder;
|
||||
import org.geysermc.mcprotocollib.auth.GameProfile;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.player.ResolvableProfile;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponentTypes;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponents;
|
||||
@@ -49,21 +51,25 @@ public class PlayerHeadItem extends BlockItem {
|
||||
// Use the correct color, determined by the rarity of the item
|
||||
char rarity = Rarity.fromId(components.getOrDefault(DataComponentTypes.RARITY, Rarity.COMMON.ordinal())).getColor();
|
||||
|
||||
// Ideally we'd resolve the profile here and show the resolved name if it's a dynamic profile
|
||||
// but, resolving is done async, which isn't really possible here
|
||||
// TODO FIXME 1.21.9? also see comment in ItemTranslator
|
||||
ResolvableProfile profile = components.get(DataComponentTypes.PROFILE);
|
||||
if (profile != null) {
|
||||
String name = profile.getProfile().getName();
|
||||
if (name != null) {
|
||||
// Add correct name of player skull
|
||||
String displayName = ChatColor.RESET + ChatColor.ESCAPE + rarity +
|
||||
// Ideally we'd update the item once the profile is resolved,
|
||||
// but there's no good way of doing this as we don't know where the item is in an inventory after we have translated it
|
||||
// So, we request a resolve here, and if the profile has already been resolved it will be returned instantly from cache.
|
||||
// If not, the next time the item will be translated the profile will probably have been resolved
|
||||
GameProfile resolved = SkinManager.resolveProfile(profile).getNow(null);
|
||||
if (resolved != null) {
|
||||
String name = resolved.getName();
|
||||
if (name != null) {
|
||||
// Add correct name of player skull
|
||||
String displayName = ChatColor.RESET + ChatColor.ESCAPE + rarity +
|
||||
MinecraftLocale.getLocaleString("block.minecraft.player_head.named", session.locale()).replace("%s", name);
|
||||
builder.setCustomName(displayName);
|
||||
} else {
|
||||
// No name found so default to "Player Head"
|
||||
builder.setCustomName(ChatColor.RESET + ChatColor.ESCAPE + rarity +
|
||||
builder.setCustomName(displayName);
|
||||
} else {
|
||||
// No name found so default to "Player Head"
|
||||
builder.setCustomName(ChatColor.RESET + ChatColor.ESCAPE + rarity +
|
||||
MinecraftLocale.getLocaleString("block.minecraft.player_head", session.locale()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -38,6 +38,7 @@ import org.cloudburstmc.nbt.NbtMapBuilder;
|
||||
import org.cloudburstmc.protocol.bedrock.data.definitions.BlockDefinition;
|
||||
import org.cloudburstmc.protocol.bedrock.data.definitions.ItemDefinition;
|
||||
import org.cloudburstmc.protocol.bedrock.data.inventory.ItemData;
|
||||
import org.geysermc.geyser.GeyserImpl;
|
||||
import org.geysermc.geyser.api.block.custom.CustomBlockData;
|
||||
import org.geysermc.geyser.entity.attribute.GeyserAttributeType;
|
||||
import org.geysermc.geyser.inventory.GeyserItemStack;
|
||||
@@ -53,11 +54,13 @@ import org.geysermc.geyser.registry.Registries;
|
||||
import org.geysermc.geyser.registry.type.CustomSkull;
|
||||
import org.geysermc.geyser.registry.type.ItemMapping;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
import org.geysermc.geyser.skin.SkinManager;
|
||||
import org.geysermc.geyser.text.ChatColor;
|
||||
import org.geysermc.geyser.text.MinecraftLocale;
|
||||
import org.geysermc.geyser.translator.text.MessageTranslator;
|
||||
import org.geysermc.geyser.util.InventoryUtils;
|
||||
import org.geysermc.geyser.util.MinecraftKey;
|
||||
import org.geysermc.mcprotocollib.auth.GameProfile;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.Effect;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.attribute.AttributeType;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.attribute.ModifierOperation;
|
||||
@@ -625,32 +628,32 @@ public final class ItemTranslator {
|
||||
return null;
|
||||
}
|
||||
|
||||
// TODO FIXME 1.21.9 - maybe if dynamic first send vanilla player head, then once resolved resend the proper player head??
|
||||
// TODO could also work with the head name (see PlayerHeadItem)
|
||||
/*
|
||||
Map<TextureType, Texture> textures;
|
||||
// Ideally we'd update the item once the profile has been resolved, but this isn't really possible,
|
||||
// also see comments in PlayerHeadItem for full explanation
|
||||
GameProfile resolved = SkinManager.resolveProfile(profile).getNow(null);
|
||||
if (resolved == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
Map<GameProfile.TextureType, GameProfile.Texture> textures;
|
||||
try {
|
||||
textures = profile.getTextures(false);
|
||||
textures = resolved.getTextures(false);
|
||||
} catch (IllegalStateException e) {
|
||||
GeyserImpl.getInstance().getLogger().debug("Could not decode player head from profile %s, got: %s".formatted(profile, e.getMessage()));
|
||||
GeyserImpl.getInstance().getLogger().debug("Could not decode player head from profile %s, got: %s".formatted(resolved, e.getMessage()));
|
||||
return null;
|
||||
}
|
||||
|
||||
if (textures == null || textures.isEmpty()) {
|
||||
// TODO the java client looks up the texture properties here and updates the item
|
||||
return null;
|
||||
}
|
||||
|
||||
Texture skinTexture = textures.get(TextureType.SKIN);
|
||||
|
||||
GameProfile.Texture skinTexture = textures.get(GameProfile.TextureType.SKIN);
|
||||
if (skinTexture == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
String skinHash = skinTexture.getURL().substring(skinTexture.getURL().lastIndexOf('/') + 1);
|
||||
return BlockRegistries.CUSTOM_SKULLS.get(skinHash);
|
||||
*/
|
||||
return null;
|
||||
}
|
||||
|
||||
private static void translatePlayerHead(GeyserSession session, ResolvableProfile profile, ItemData.Builder builder) {
|
||||
|
||||
Reference in New Issue
Block a user