Skip to content

Commit

Permalink
add 'player entity skins' lang doc
Browse files Browse the repository at this point in the history
  • Loading branch information
mcmonkey4eva committed Dec 15, 2020
1 parent 656634f commit 42571f1
Show file tree
Hide file tree
Showing 4 changed files with 47 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,41 @@ public void setPlayerSkin(Player player, String name) {
updatePlayer(player, true);
}
}
// <--[language]
// @name Player Entity Skins (Skin Blobs)
// @group Minecraft Logic
// @description
// Player entities (that is, both real players and player-type NPCs), in addition to Player_Head items,
// use something called a "skin blob" to determine what skin to show.
// A skin blob consists of an identifier (usually the player's UUID, sometimes the name), a "texture", and a "signature".
//
// The "texture" portion, despite the name, does not contain actual texture data - it contains a Base64 encoding of a JSON section that contains outlinks to real skin data.
// That might be a bit confusing, so here's an example:
//
// The raw "texture" data for "mcmonkey4eva"'s skin is:
// eyJ0aW1lc3RhbXAiOjE1NjU1NjUyNDA4NTMsInByb2ZpbGVJZCI6IjQ2MGU5NmI5N2EwZTQxNmRiMmMzNDUwODE2NGI4YjFiIiwicHJvZmlsZU5hbWUiOiJtY21vbmtleTRldmEiLCJzaWduYXR1cmVSZXF1aXJlZCI6dHJ1ZSwidGV4dH
// VyZXMiOnsiU0tJTiI6eyJ1cmwiOiJodHRwOi8vdGV4dHVyZXMubWluZWNyYWZ0Lm5ldC90ZXh0dXJlL2ZkMzRiM2UyN2EzZmU1MzgyN2IzN2FkNTk1NmFjY2EwOGYyODYzYzY5MjZjYzk3MTE2ZGRhMzM0ODY5N2E1YTkifX19
//
// This is base64 encoding, which is just a way of controlling the format of binary data. When passed through a Base64 decoder, that says:
// {"timestamp":1565565240853,"profileId":"460e96b97a0e416db2c34508164b8b1b","profileName":"mcmonkey4eva","signatureRequired":true,
// "textures":{"SKIN":{"url":"http://textures.minecraft.net/texture/fd34b3e27a3fe53827b37ad5956acca08f2863c6926cc97116dda3348697a5a9"}}}
//
// As you can see, it contains: the timestamp of when the skin was added, the UUID and name, and a link to the actual skin file on Mojang's servers.
//
// The "signature" portion is a digitally encrypted signature that is used to verify a skin really was generated by Mojang.
// It is also represented as Base64, but cannot be decoded to anything readable.
// The "signature" is required for Player entity skins, but can generally be left off from Player_Head items (meaning, you can generate your own Player_Head items by base64 encoding your own JSON).
//
// The website <@link url https://mineskin.org/> can be used to generate full texture+signature data from any skin file
// (it does this by automatically uploading the skin image to Mojang's servers for processing and signing, using a donated Minecraft account).
//
// In terms of general actual usage, skin blobs are generally meant to be read from tags and applied with mechanisms, never directly written out or read by a human, due to their complexity.
//
// A skin_blob always represents a single actual skin, as opposed to a player name/uuid, where the account owner might choose to change their skin.
//
// It should be noted that any time a skin is applied to a Player, NPC, Or Player_Head item using just a name or UUID, the server must contact Mojang's servers to requst the skin blob for that given name/uuid.
// With a skin blob, however, the server does not need to make any remote calls, and can apply the skin directly (However note that the client will still download the image from Mojang's servers).
// -->

public void setPlayerSkinBlob(Player player, String blob) {
PlayerProfile profile = getFakeProfile(player);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -778,6 +778,7 @@ else if (attribute.startsWith("list", 2)) {
// @description
// Returns the NPC's custom skin blob, if any.
// In the format: "texture;signature" (two values separated by a semicolon).
// See also <@link language Player Entity Skins (Skin Blobs)>.
// -->
registerTag("skin_blob", (attribute, object) -> {
if (object.getCitizen().hasTrait(SkinTrait.class)) {
Expand All @@ -798,7 +799,7 @@ else if (attribute.startsWith("list", 2)) {
// @description
// Returns the NPC's current skin blob, formatted for input to a Player Skull item.
// In the format: "UUID|Texture" (two values separated by pipes).
// See also <@link tag NPCTag.skin_blob>.
// See also <@link language Player Entity Skins (Skin Blobs)>.
// -->
registerTag("skull_skin", (attribute, object) -> {
if (!object.getCitizen().hasTrait(SkinTrait.class)) {
Expand Down Expand Up @@ -1257,6 +1258,7 @@ public void adjust(Mechanism mechanism) {
// @description
// Sets the skin blob of an NPC, in the form of "texture;signature;name".
// Call with no value to clear the custom skin value.
// See also <@link language Player Entity Skins (Skin Blobs)>.
// @tags
// <NPCTag.skin>
// -->
Expand Down Expand Up @@ -1291,6 +1293,7 @@ public void adjust(Mechanism mechanism) {
// @description
// Sets the skin of an NPC by name.
// Call with no value to clear the custom skin value.
// See also <@link language Player Entity Skins (Skin Blobs)>.
// @tags
// <NPCTag.skin>
// -->
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1696,10 +1696,11 @@ else if (obj instanceof EntityTag) {
// <--[tag]
// @attribute <PlayerTag.skin_blob>
// @returns ElementTag
// @mechanism PlayerTag.skin_blob
// @description
// Returns the player's current skin blob.
// In the format: "texture;signature" (two values separated by a semicolon).
// @mechanism PlayerTag.skin_blob
// See also <@link language Player Entity Skins (Skin Blobs)>.
// -->
registerOnlineOnlyTag("skin_blob", (attribute, object) -> {
return new ElementTag(NMSHandler.getInstance().getProfileEditor().getPlayerSkinBlob(object.getPlayerEntity()));
Expand All @@ -1711,7 +1712,7 @@ else if (obj instanceof EntityTag) {
// @description
// Returns the player's current skin blob, formatted for input to a Player Skull item.
// In the format: "UUID|Texture|Name" (three values separated by pipes).
// See also <@link tag PlayerTag.skin_blob>.
// See also <@link language Player Entity Skins (Skin Blobs)>.
// -->
registerOnlineOnlyTag("skull_skin", (attribute, object) -> {
String skin = NMSHandler.getInstance().getProfileEditor().getPlayerSkinBlob(object.getPlayerEntity());
Expand Down Expand Up @@ -3419,6 +3420,7 @@ else if (split.length > 1) {
// @input ElementTag
// @description
// Changes the skin of the player to the skin of the given player name.
// See also <@link language Player Entity Skins (Skin Blobs)>.
// -->
if (mechanism.matches("skin")) {
String name = mechanism.getValue().asString();
Expand All @@ -3437,6 +3439,7 @@ else if (split.length > 1) {
// @description
// Changes the skin of the player to the specified blob.
// In the format: "texture;signature" (two values separated by a semicolon).
// See also <@link language Player Entity Skins (Skin Blobs)>.
// @tags
// <PlayerTag.skin_blob>
// -->
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ public ObjectTag getObjectAttribute(Attribute attribute) {
// Returns the UUID of the player whose skin a skull item uses.
// Note: Item must be a 'player_head' with a skin.
// In format: UUID|Texture|Name.
// See also <@link language Player Entity Skins (Skin Blobs)>.
// -->
if (attribute.startsWith("skull_skin")) {
String skin = getPropertyString();
Expand All @@ -80,6 +81,7 @@ public ObjectTag getObjectAttribute(Attribute attribute) {
// Returns the UUID of the player whose skin a skull item uses.
// Note: Item must be a 'player_head' with a skin.
// In format: UUID|Texture|Name.
// See also <@link language Player Entity Skins (Skin Blobs)>.
// -->
if (attribute.startsWith("skin")) {
String skin = getPropertyString();
Expand Down Expand Up @@ -144,6 +146,7 @@ public void adjust(Mechanism mechanism) {
// The first ElementTag is a UUID.
// Optionally, use the second ElementTag for the skin texture cache.
// Optionally, use the third ElementTag for a player name.
// See also <@link language Player Entity Skins (Skin Blobs)>.
// @tags
// <ItemTag.skull_skin>
// <ItemTag.skin>
Expand Down

0 comments on commit 42571f1

Please sign in to comment.