Initial commit

This commit is contained in:
SantianDev
2026-03-03 15:05:55 +03:00
commit a9c89f027a
37 changed files with 3256 additions and 0 deletions

View File

@@ -0,0 +1,165 @@
package bedrock
import (
"encoding/base64"
"encoding/binary"
"encoding/json"
"strings"
"github.com/cubexteam/Frodding/net/info"
"github.com/cubexteam/Frodding/net/packets"
"github.com/google/uuid"
)
type LoginPacket struct {
*packets.Packet
Protocol int32
Username string
ClientUUID uuid.UUID
ClientXUID string
ClientID int64
ServerAddr string
Language string
SkinID string
SkinData []byte
CapeData []byte
GeometryName string
GeometryData string
}
func NewLoginPacket() *LoginPacket {
return &LoginPacket{
Packet: packets.NewPacket(info.IDLogin),
ClientUUID: uuid.New(),
}
}
func (pk *LoginPacket) Encode() {}
func (pk *LoginPacket) Decode() {
pk.Protocol = pk.GetInt()
pk.GetByte()
totalLen := int(pk.GetUVarInt())
if totalLen <= 0 || totalLen > pk.Remaining() {
pk.Username = "Player"
return
}
blob := pk.GetBytes(totalLen)
if len(blob) < 4 {
pk.Username = "Player"
return
}
chainLen := int(binary.LittleEndian.Uint32(blob[:4]))
if chainLen <= 0 || 4+chainLen > len(blob) {
pk.Username = "Player"
return
}
var chainData struct {
Chain []string `json:"chain"`
}
if err := json.Unmarshal(blob[4:4+chainLen], &chainData); err == nil {
for _, raw := range chainData.Chain {
pk.parseChain(raw)
}
}
offset := 4 + chainLen
if offset+4 > len(blob) {
if pk.Username == "" {
pk.Username = "Player"
}
return
}
clientLen := int(binary.LittleEndian.Uint32(blob[offset : offset+4]))
offset += 4
if clientLen > 0 && offset+clientLen <= len(blob) {
pk.parseClientData(string(blob[offset : offset+clientLen]))
}
if pk.Username == "" {
pk.Username = "Player"
}
}
func decodeJWTPayload(s string) ([]byte, error) {
b, err := base64.RawURLEncoding.DecodeString(s)
if err != nil {
switch len(s) % 4 {
case 2:
s += "=="
case 3:
s += "="
}
b, err = base64.URLEncoding.DecodeString(s)
}
return b, err
}
func (pk *LoginPacket) parseChain(raw string) {
parts := strings.Split(raw, ".")
if len(parts) < 2 {
return
}
payload, err := decodeJWTPayload(parts[1])
if err != nil {
return
}
var data struct {
ExtraData map[string]interface{} `json:"extraData"`
}
if err := json.Unmarshal(payload, &data); err != nil || data.ExtraData == nil {
return
}
if v, ok := data.ExtraData["displayName"]; ok {
if name, _ := v.(string); name != "" {
pk.Username = name
}
}
if v, ok := data.ExtraData["identity"]; ok {
if idStr, _ := v.(string); idStr != "" {
if u, err := uuid.Parse(idStr); err == nil {
pk.ClientUUID = u
}
}
}
if v, ok := data.ExtraData["XUID"]; ok {
pk.ClientXUID, _ = v.(string)
}
}
func (pk *LoginPacket) parseClientData(raw string) {
parts := strings.Split(raw, ".")
if len(parts) < 2 {
return
}
payload, err := decodeJWTPayload(parts[1])
if err != nil {
return
}
var data struct {
ClientRandomID int64 `json:"ClientRandomId"`
ServerAddress string `json:"ServerAddress"`
LanguageCode string `json:"LanguageCode"`
SkinID string `json:"SkinId"`
SkinData string `json:"SkinData"`
CapeData string `json:"CapeData"`
SkinGeomName string `json:"SkinGeometryName"`
SkinGeomData string `json:"SkinGeometry"`
}
if err := json.Unmarshal(payload, &data); err != nil {
return
}
pk.ClientID = data.ClientRandomID
pk.ServerAddr = data.ServerAddress
pk.Language = data.LanguageCode
if pk.Language == "" {
pk.Language = "en_US"
}
pk.SkinID = data.SkinID
pk.GeometryName = data.SkinGeomName
pk.SkinData, _ = base64.RawStdEncoding.DecodeString(data.SkinData)
pk.CapeData, _ = base64.RawStdEncoding.DecodeString(data.CapeData)
geomBytes, _ := base64.RawStdEncoding.DecodeString(data.SkinGeomData)
pk.GeometryData = string(geomBytes)
for len(pk.SkinData) < 8192 {
pk.SkinData = append(pk.SkinData, 0x00)
}
}