Exemplo n.º 1
0
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)
		}
	}
}
Exemplo n.º 2
0
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()
	}
}