func esPlayerModelAdd(p *playerModelComponent, pl PlayerComponent) { uuid := pl.UUID() info := Client.playerList.info[uuid] if info == nil { Client.network.SignalClose(errors.New("missing player info")) return } skin := info.skin p.skin = info.skinHash cape := info.cape p.cape = info.capeHash if p.skin != "" { render.RefSkin(p.skin) } if p.cape != "" { render.RefSkin(p.cape) } var hverts []*render.StaticVertex if p.hasHead { hverts = appendBox(hverts, -4/16.0, 0, -4/16.0, 8/16.0, 8/16.0, 8/16.0, [6]render.TextureInfo{ direction.North: skin.Sub(8, 8, 8, 8), direction.South: skin.Sub(24, 8, 8, 8), direction.East: skin.Sub(0, 8, 8, 8), direction.West: skin.Sub(16, 8, 8, 8), direction.Up: skin.Sub(8, 0, 8, 8), direction.Down: skin.Sub(16, 0, 8, 8), }) hverts = appendBox(hverts, -4.2/16.0, -.2/16.0, -4.2/16.0, 8.4/16.0, 8.4/16.0, 8.4/16.0, [6]render.TextureInfo{ direction.North: skin.Sub(8+32, 8, 8, 8), direction.South: skin.Sub(24+32, 8, 8, 8), direction.East: skin.Sub(0+32, 8, 8, 8), direction.West: skin.Sub(16+32, 8, 8, 8), direction.Up: skin.Sub(8+32, 0, 8, 8), direction.Down: skin.Sub(16+32, 0, 8, 8), }) } var cverts []*render.StaticVertex if p.cape != "" { cverts = appendBox(cverts, -5/16.0, -16/16.0, 0, 10/16.0, 16/16.0, 1/16.0, [6]render.TextureInfo{ direction.North: cape.Sub(11, 1, 10, 16), direction.South: cape.Sub(1, 1, 10, 16), direction.West: cape.Sub(0, 1, 1, 16), direction.East: cape.Sub(21, 1, 1, 16), direction.Up: cape.Sub(1, 0, 10, 1), direction.Down: cape.Sub(11, 0, 10, 1), }) } bverts := appendBox(nil, -4/16.0, -6/16.0, -2/16.0, 8/16.0, 12/16.0, 4/16.0, [6]render.TextureInfo{ direction.North: skin.Sub(20, 20, 8, 12), direction.South: skin.Sub(32, 20, 8, 12), direction.West: skin.Sub(16, 20, 4, 12), direction.East: skin.Sub(28, 20, 4, 12), direction.Up: skin.Sub(20, 16, 8, 4), direction.Down: skin.Sub(28, 16, 8, 4), }) bverts = appendBox(bverts, -4.2/16.0, -6.2/16.0, -2.2/16.0, 8.4/16.0, 12.4/16.0, 4.4/16.0, [6]render.TextureInfo{ direction.North: skin.Sub(20, 20+16, 8, 12), direction.South: skin.Sub(32, 20+16, 8, 12), direction.West: skin.Sub(16, 20+16, 4, 12), direction.East: skin.Sub(28, 20+16, 4, 12), direction.Up: skin.Sub(20, 16+16, 8, 4), direction.Down: skin.Sub(28, 16+16, 8, 4), }) var lverts [4][]*render.StaticVertex for i, off := range [][4]int{ {0, 16, 0, 32}, {16, 48, 0, 48}, {32, 48, 48, 48}, {40, 16, 40, 32}, } { ox, oy := off[0], off[1] lverts[i] = appendBox(nil, -2/16.0, -12/16.0, -2/16.0, 4/16.0, 12/16.0, 4/16.0, [6]render.TextureInfo{ direction.North: skin.Sub(ox+4, oy+4, 4, 12), direction.South: skin.Sub(ox+12, oy+4, 4, 12), direction.West: skin.Sub(ox+0, oy+4, 4, 12), direction.East: skin.Sub(ox+8, oy+4, 4, 12), direction.Up: skin.Sub(ox+4, oy, 4, 4), direction.Down: skin.Sub(ox+8, oy, 4, 4), }) ox, oy = off[2], off[3] lverts[i] = appendBox(lverts[i], -2.2/16.0, -12.2/16.0, -2.2/16.0, 4.4/16.0, 12.4/16.0, 4.4/16.0, [6]render.TextureInfo{ direction.North: skin.Sub(ox+4, oy+4, 4, 12), direction.South: skin.Sub(ox+12, oy+4, 4, 12), direction.West: skin.Sub(ox+0, oy+4, 4, 12), direction.East: skin.Sub(ox+8, oy+4, 4, 12), direction.Up: skin.Sub(ox+4, oy, 4, 4), direction.Down: skin.Sub(ox+8, oy, 4, 4), }) } var nverts []*render.StaticVertex if p.hasNameTag { nverts = createNameTag(info.name) } model := render.NewStaticModel([][]*render.StaticVertex{ playerModelHead: hverts, playerModelBody: bverts, playerModelLegRight: lverts[0], playerModelLegLeft: lverts[1], playerModelArmRight: lverts[2], playerModelArmLeft: lverts[3], playerModelCape: cverts, playerModelNameTag: nverts, }) p.model = model model.Radius = 3 }
func (handler) PlayerListInfo(p *protocol.PlayerInfo) { playerList := Client.playerList.info for _, pl := range p.Players { if _, ok := playerList[pl.UUID]; (!ok && p.Action != 0) || (ok && p.Action == 0) { continue } switch p.Action { case 0: // Add i := &playerInfo{ name: pl.Name, uuid: pl.UUID, displayName: pl.DisplayName, gameMode: gameMode(pl.GameMode), ping: int(pl.Ping), } for _, prop := range pl.Properties { if prop.Name == "textures" { if !prop.IsSigned { Client.network.SignalClose(errors.New("Missing signature from textures")) return } data, err := base64.StdEncoding.DecodeString(prop.Value) if err != nil { Client.network.SignalClose(err) continue } sig, err := base64.StdEncoding.DecodeString(prop.Signature) if err != nil { Client.network.SignalClose(err) continue } if err := verifySkinSignature([]byte(prop.Value), sig); err != nil { Client.network.SignalClose(err) return } var blob skinBlob err = json.Unmarshal(data, &blob) if err != nil { Client.network.SignalClose(err) continue } url := blob.Textures.Skin.Url if strings.HasPrefix(url, "http://textures.minecraft.net/texture/") { i.skinHash = url[len("http://textures.minecraft.net/texture/"):] render.RefSkin(i.skinHash) i.skin = render.Skin(i.skinHash) } url = blob.Textures.Cape.Url if strings.HasPrefix(url, "http://textures.minecraft.net/texture/") { i.capeHash = url[len("http://textures.minecraft.net/texture/"):] render.RefSkin(i.capeHash) i.cape = render.Skin(i.capeHash) } } } if i.skin == nil { i.skin = render.GetTexture("entity/steve") } i.skin = render.RelativeTexture(i.skin, 64, 64) playerList[pl.UUID] = i // Special case for self if !Client.entityAdded && i.uuid == Client.entity.UUID() { Client.entities.container.AddEntity(Client.entity) Client.entityAdded = true } case 1: // Update gamemode playerList[pl.UUID].gameMode = gameMode(pl.GameMode) case 2: // Update ping playerList[pl.UUID].ping = int(pl.Ping) case 3: // Update display name playerList[pl.UUID].displayName = pl.DisplayName case 4: // Remove i := playerList[pl.UUID] if i.skinHash != "" { render.FreeSkin(i.skinHash) } delete(playerList, pl.UUID) } } }
func (s *skullComponent) Deserilize(tag *nbt.Compound) { t, ok := tag.Items["SkullType"].(int8) if !ok { return } s.SkullType = skullType(t) rot, ok := tag.Items["Rot"].(int8) if !ok { return } s.Rotation = int(rot) if s.SkullType != skullPlayer { s.free() s.create() return } owner, ok := tag.Items["Owner"].(*nbt.Compound) if !ok { return } props, ok := owner.Items["Properties"].(*nbt.Compound) if !ok { return } tex, ok := props.Items["textures"].(*nbt.List) if !ok || tex.Type != nbt.TagCompound || len(tex.Elements) < 1 { return } texP := tex.Elements[0].(*nbt.Compound) value := texP.Items["Value"].(string) sigV, hasSig := texP.Items["Signature"].(string) data, err := base64.StdEncoding.DecodeString(value) if err != nil { return } if hasSig { sig, err := base64.StdEncoding.DecodeString(sigV) if err != nil { return } if err := verifySkinSignature([]byte(value), sig); err != nil { return } } var blob skinBlob err = json.Unmarshal(data, &blob) if err != nil { return } url := blob.Textures.Skin.Url // We can only handle textures from textures.minecraft.net currently, // luckily these are the only ones we really see in practice and // mojang seemed to have blocked other urls if strings.HasPrefix(url, "http://textures.minecraft.net/texture/") { s.free() s.Owner = url[len("http://textures.minecraft.net/texture/"):] render.RefSkin(s.Owner) s.OwnerSkin = render.Skin(s.Owner) s.create() } }