7723 lines
180 KiB
Go
7723 lines
180 KiB
Go
// Code generated by codegen. DO NOT EDIT.
|
|
// Source: login.xml
|
|
|
|
package generated
|
|
|
|
import (
|
|
"encoding/binary"
|
|
"git.sharkk.net/EQ2/Protocol/types"
|
|
)
|
|
|
|
|
|
// LSCreateCharacterReply represents packet structure for OP_CreateCharacterReplyMsg
|
|
type LSCreateCharacterReply struct {
|
|
AccountId uint32 `eq2:"account_id"`
|
|
Response uint8 `eq2:"response"`
|
|
Name string `eq2:"name,type:str16"`
|
|
}
|
|
|
|
// Serialize writes the packet data to the provided buffer
|
|
func (p *LSCreateCharacterReply) Serialize(dest []byte) uint32 {
|
|
offset := uint32(0)
|
|
|
|
// Write AccountId
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.AccountId))
|
|
offset += 4
|
|
|
|
// Write Response
|
|
dest[offset] = byte(p.Response)
|
|
offset++
|
|
|
|
// Write Name as 16-bit length-prefixed string
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(len(p.Name)))
|
|
offset += 2
|
|
copy(dest[offset:], []byte(p.Name))
|
|
offset += uint32(len(p.Name))
|
|
|
|
return offset
|
|
}
|
|
|
|
// Size returns the serialized size of the packet
|
|
func (p *LSCreateCharacterReply) Size() uint32 {
|
|
size := uint32(0)
|
|
|
|
size += 4
|
|
|
|
size += 1
|
|
|
|
size += 2 + uint32(len(p.Name))
|
|
|
|
return size
|
|
}
|
|
|
|
// LSCreateCharacterReplyV1189 represents packet structure for OP_CreateCharacterReplyMsg
|
|
type LSCreateCharacterReplyV1189 struct {
|
|
AccountId uint32 `eq2:"account_id"`
|
|
Unknown uint32 `eq2:"unknown"` // TODO: Identify purpose
|
|
Response uint8 `eq2:"response"`
|
|
Name string `eq2:"name,type:str16"`
|
|
}
|
|
|
|
// Serialize writes the packet data to the provided buffer
|
|
func (p *LSCreateCharacterReplyV1189) Serialize(dest []byte) uint32 {
|
|
offset := uint32(0)
|
|
|
|
// Write AccountId
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.AccountId))
|
|
offset += 4
|
|
|
|
// Write Unknown
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.Unknown))
|
|
offset += 4
|
|
|
|
// Write Response
|
|
dest[offset] = byte(p.Response)
|
|
offset++
|
|
|
|
// Write Name as 16-bit length-prefixed string
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(len(p.Name)))
|
|
offset += 2
|
|
copy(dest[offset:], []byte(p.Name))
|
|
offset += uint32(len(p.Name))
|
|
|
|
return offset
|
|
}
|
|
|
|
// Size returns the serialized size of the packet
|
|
func (p *LSCreateCharacterReplyV1189) Size() uint32 {
|
|
size := uint32(0)
|
|
|
|
size += 4
|
|
|
|
size += 4
|
|
|
|
size += 1
|
|
|
|
size += 2 + uint32(len(p.Name))
|
|
|
|
return size
|
|
}
|
|
|
|
// LSCreateCharacterReplyV60085 represents packet structure for OP_CreateCharacterReplyMsg
|
|
type LSCreateCharacterReplyV60085 struct {
|
|
AccountId uint32 `eq2:"account_id"`
|
|
Unknown uint32 `eq2:"unknown"` // TODO: Identify purpose
|
|
Response uint8 `eq2:"response"`
|
|
Name string `eq2:"name,type:str16"`
|
|
}
|
|
|
|
// Serialize writes the packet data to the provided buffer
|
|
func (p *LSCreateCharacterReplyV60085) Serialize(dest []byte) uint32 {
|
|
offset := uint32(0)
|
|
|
|
// Write AccountId
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.AccountId))
|
|
offset += 4
|
|
|
|
// Write Unknown
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.Unknown))
|
|
offset += 4
|
|
|
|
// Write Response
|
|
dest[offset] = byte(p.Response)
|
|
offset++
|
|
|
|
// Write Name as 16-bit length-prefixed string
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(len(p.Name)))
|
|
offset += 2
|
|
copy(dest[offset:], []byte(p.Name))
|
|
offset += uint32(len(p.Name))
|
|
|
|
return offset
|
|
}
|
|
|
|
// Size returns the serialized size of the packet
|
|
func (p *LSCreateCharacterReplyV60085) Size() uint32 {
|
|
size := uint32(0)
|
|
|
|
size += 4
|
|
|
|
size += 4
|
|
|
|
size += 1
|
|
|
|
size += 2 + uint32(len(p.Name))
|
|
|
|
return size
|
|
}
|
|
|
|
// LSDeleteCharacterRequest represents packet structure for OP_DeleteCharacterRequestMsg
|
|
type LSDeleteCharacterRequest struct {
|
|
CharId uint32 `eq2:"char_id"`
|
|
ServerId uint32 `eq2:"server_id"`
|
|
Unknown uint32 `eq2:"unknown"` // TODO: Identify purpose
|
|
Name string `eq2:"name,type:str16"`
|
|
}
|
|
|
|
// Serialize writes the packet data to the provided buffer
|
|
func (p *LSDeleteCharacterRequest) Serialize(dest []byte) uint32 {
|
|
offset := uint32(0)
|
|
|
|
// Write CharId
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.CharId))
|
|
offset += 4
|
|
|
|
// Write ServerId
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.ServerId))
|
|
offset += 4
|
|
|
|
// Write Unknown
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.Unknown))
|
|
offset += 4
|
|
|
|
// Write Name as 16-bit length-prefixed string
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(len(p.Name)))
|
|
offset += 2
|
|
copy(dest[offset:], []byte(p.Name))
|
|
offset += uint32(len(p.Name))
|
|
|
|
return offset
|
|
}
|
|
|
|
// Size returns the serialized size of the packet
|
|
func (p *LSDeleteCharacterRequest) Size() uint32 {
|
|
size := uint32(0)
|
|
|
|
size += 4
|
|
|
|
size += 4
|
|
|
|
size += 4
|
|
|
|
size += 2 + uint32(len(p.Name))
|
|
|
|
return size
|
|
}
|
|
|
|
// LSDeleteCharacterResponse represents packet structure for OP_DeleteCharacterReplyMsg
|
|
type LSDeleteCharacterResponse struct {
|
|
Response uint8 `eq2:"response"`
|
|
ServerId uint32 `eq2:"server_id"`
|
|
CharId uint32 `eq2:"char_id"`
|
|
AccountId uint32 `eq2:"account_id"`
|
|
Name string `eq2:"name,type:str16"`
|
|
MaxCharacters uint32 `eq2:"max_characters"`
|
|
}
|
|
|
|
// Serialize writes the packet data to the provided buffer
|
|
func (p *LSDeleteCharacterResponse) Serialize(dest []byte) uint32 {
|
|
offset := uint32(0)
|
|
|
|
// Write Response
|
|
dest[offset] = byte(p.Response)
|
|
offset++
|
|
|
|
// Write ServerId
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.ServerId))
|
|
offset += 4
|
|
|
|
// Write CharId
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.CharId))
|
|
offset += 4
|
|
|
|
// Write AccountId
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.AccountId))
|
|
offset += 4
|
|
|
|
// Write Name as 16-bit length-prefixed string
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(len(p.Name)))
|
|
offset += 2
|
|
copy(dest[offset:], []byte(p.Name))
|
|
offset += uint32(len(p.Name))
|
|
|
|
// Write MaxCharacters
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.MaxCharacters))
|
|
offset += 4
|
|
|
|
return offset
|
|
}
|
|
|
|
// Size returns the serialized size of the packet
|
|
func (p *LSDeleteCharacterResponse) Size() uint32 {
|
|
size := uint32(0)
|
|
|
|
size += 1
|
|
|
|
size += 4
|
|
|
|
size += 4
|
|
|
|
size += 4
|
|
|
|
size += 2 + uint32(len(p.Name))
|
|
|
|
size += 4
|
|
|
|
return size
|
|
}
|
|
|
|
// LSLoginRequest represents packet structure for OP_LoginRequestMsg
|
|
type LSLoginRequest struct {
|
|
SessionID string `eq2:"sessionID,type:str16"`
|
|
SessionRecycleToken string `eq2:"sessionRecycleToken,type:str16"`
|
|
Username string `eq2:"username,type:str16"`
|
|
Password string `eq2:"password,type:str16"`
|
|
AcctNum uint32 `eq2:"acctNum"`
|
|
PassCode uint32 `eq2:"passCode"`
|
|
Version uint16 `eq2:"version"`
|
|
}
|
|
|
|
// Serialize writes the packet data to the provided buffer
|
|
func (p *LSLoginRequest) Serialize(dest []byte) uint32 {
|
|
offset := uint32(0)
|
|
|
|
// Write SessionID as 16-bit length-prefixed string
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(len(p.SessionID)))
|
|
offset += 2
|
|
copy(dest[offset:], []byte(p.SessionID))
|
|
offset += uint32(len(p.SessionID))
|
|
|
|
// Write SessionRecycleToken as 16-bit length-prefixed string
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(len(p.SessionRecycleToken)))
|
|
offset += 2
|
|
copy(dest[offset:], []byte(p.SessionRecycleToken))
|
|
offset += uint32(len(p.SessionRecycleToken))
|
|
|
|
// Write Username as 16-bit length-prefixed string
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(len(p.Username)))
|
|
offset += 2
|
|
copy(dest[offset:], []byte(p.Username))
|
|
offset += uint32(len(p.Username))
|
|
|
|
// Write Password as 16-bit length-prefixed string
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(len(p.Password)))
|
|
offset += 2
|
|
copy(dest[offset:], []byte(p.Password))
|
|
offset += uint32(len(p.Password))
|
|
|
|
// Write AcctNum
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.AcctNum))
|
|
offset += 4
|
|
|
|
// Write PassCode
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.PassCode))
|
|
offset += 4
|
|
|
|
// Write Version
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(p.Version))
|
|
offset += 2
|
|
|
|
return offset
|
|
}
|
|
|
|
// Size returns the serialized size of the packet
|
|
func (p *LSLoginRequest) Size() uint32 {
|
|
size := uint32(0)
|
|
|
|
size += 2 + uint32(len(p.SessionID))
|
|
|
|
size += 2 + uint32(len(p.SessionRecycleToken))
|
|
|
|
size += 2 + uint32(len(p.Username))
|
|
|
|
size += 2 + uint32(len(p.Password))
|
|
|
|
size += 4
|
|
|
|
size += 4
|
|
|
|
size += 2
|
|
|
|
return size
|
|
}
|
|
|
|
// LSLoginRequestV562 represents packet structure for OP_LoginRequestMsg
|
|
type LSLoginRequestV562 struct {
|
|
Accesscode string `eq2:"accesscode,type:str16"`
|
|
Unknown1 string `eq2:"unknown1,type:str16"` // TODO: Identify purpose
|
|
Username string `eq2:"username,type:str16"`
|
|
Password string `eq2:"password,type:str16"`
|
|
Unknown2 [8]uint8 `eq2:"unknown2,size:8"` // TODO: Identify purpose
|
|
Unknown3 [2]uint8 `eq2:"unknown3,size:2"` // TODO: Identify purpose
|
|
Version uint32 `eq2:"version"`
|
|
Unknown4 uint16 `eq2:"unknown4"` // TODO: Identify purpose
|
|
Unknown5 uint32 `eq2:"unknown5"` // TODO: Identify purpose
|
|
}
|
|
|
|
// Serialize writes the packet data to the provided buffer
|
|
func (p *LSLoginRequestV562) Serialize(dest []byte) uint32 {
|
|
offset := uint32(0)
|
|
|
|
// Write Accesscode as 16-bit length-prefixed string
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(len(p.Accesscode)))
|
|
offset += 2
|
|
copy(dest[offset:], []byte(p.Accesscode))
|
|
offset += uint32(len(p.Accesscode))
|
|
|
|
// Write Unknown1 as 16-bit length-prefixed string
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(len(p.Unknown1)))
|
|
offset += 2
|
|
copy(dest[offset:], []byte(p.Unknown1))
|
|
offset += uint32(len(p.Unknown1))
|
|
|
|
// Write Username as 16-bit length-prefixed string
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(len(p.Username)))
|
|
offset += 2
|
|
copy(dest[offset:], []byte(p.Username))
|
|
offset += uint32(len(p.Username))
|
|
|
|
// Write Password as 16-bit length-prefixed string
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(len(p.Password)))
|
|
offset += 2
|
|
copy(dest[offset:], []byte(p.Password))
|
|
offset += uint32(len(p.Password))
|
|
|
|
// Write Unknown2 array
|
|
for i := 0; i < 8; i++ {
|
|
dest[offset] = p.Unknown2[i]
|
|
offset++
|
|
}
|
|
|
|
// Write Unknown3 array
|
|
for i := 0; i < 2; i++ {
|
|
dest[offset] = p.Unknown3[i]
|
|
offset++
|
|
}
|
|
|
|
// Write Version
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.Version))
|
|
offset += 4
|
|
|
|
// Write Unknown4
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(p.Unknown4))
|
|
offset += 2
|
|
|
|
// Write Unknown5
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.Unknown5))
|
|
offset += 4
|
|
|
|
return offset
|
|
}
|
|
|
|
// Size returns the serialized size of the packet
|
|
func (p *LSLoginRequestV562) Size() uint32 {
|
|
size := uint32(0)
|
|
|
|
size += 2 + uint32(len(p.Accesscode))
|
|
|
|
size += 2 + uint32(len(p.Unknown1))
|
|
|
|
size += 2 + uint32(len(p.Username))
|
|
|
|
size += 2 + uint32(len(p.Password))
|
|
|
|
size += 8
|
|
|
|
size += 2
|
|
|
|
size += 4
|
|
|
|
size += 2
|
|
|
|
size += 4
|
|
|
|
return size
|
|
}
|
|
|
|
// LSLoginRequestV1208 represents packet structure for OP_LoginRequestMsg
|
|
type LSLoginRequestV1208 struct {
|
|
Accesscode string `eq2:"accesscode,type:str16"`
|
|
Unknown1 string `eq2:"unknown1,type:str16"` // TODO: Identify purpose
|
|
Username string `eq2:"username,type:str16"`
|
|
Password string `eq2:"password,type:str16"`
|
|
Unknown2 [8]uint8 `eq2:"unknown2,size:8"` // TODO: Identify purpose
|
|
Unknown3 [2]uint8 `eq2:"unknown3,size:2"` // TODO: Identify purpose
|
|
Version uint16 `eq2:"version"`
|
|
Unknown4 uint8 `eq2:"unknown4"` // TODO: Identify purpose
|
|
Unknown5 [3]uint32 `eq2:"unknown5,size:3"` // TODO: Identify purpose
|
|
Unknown6 uint16 `eq2:"unknown6"` // TODO: Identify purpose
|
|
Unknown7 string `eq2:"unknown7,type:str16"` // TODO: Identify purpose
|
|
}
|
|
|
|
// Serialize writes the packet data to the provided buffer
|
|
func (p *LSLoginRequestV1208) Serialize(dest []byte) uint32 {
|
|
offset := uint32(0)
|
|
|
|
// Write Accesscode as 16-bit length-prefixed string
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(len(p.Accesscode)))
|
|
offset += 2
|
|
copy(dest[offset:], []byte(p.Accesscode))
|
|
offset += uint32(len(p.Accesscode))
|
|
|
|
// Write Unknown1 as 16-bit length-prefixed string
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(len(p.Unknown1)))
|
|
offset += 2
|
|
copy(dest[offset:], []byte(p.Unknown1))
|
|
offset += uint32(len(p.Unknown1))
|
|
|
|
// Write Username as 16-bit length-prefixed string
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(len(p.Username)))
|
|
offset += 2
|
|
copy(dest[offset:], []byte(p.Username))
|
|
offset += uint32(len(p.Username))
|
|
|
|
// Write Password as 16-bit length-prefixed string
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(len(p.Password)))
|
|
offset += 2
|
|
copy(dest[offset:], []byte(p.Password))
|
|
offset += uint32(len(p.Password))
|
|
|
|
// Write Unknown2 array
|
|
for i := 0; i < 8; i++ {
|
|
dest[offset] = p.Unknown2[i]
|
|
offset++
|
|
}
|
|
|
|
// Write Unknown3 array
|
|
for i := 0; i < 2; i++ {
|
|
dest[offset] = p.Unknown3[i]
|
|
offset++
|
|
}
|
|
|
|
// Write Version
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(p.Version))
|
|
offset += 2
|
|
|
|
// Write Unknown4
|
|
dest[offset] = byte(p.Unknown4)
|
|
offset++
|
|
|
|
// Write Unknown5 array
|
|
for i := 0; i < 3; i++ {
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.Unknown5[i]))
|
|
offset += 4
|
|
}
|
|
|
|
// Write Unknown6
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(p.Unknown6))
|
|
offset += 2
|
|
|
|
// Write Unknown7 as 16-bit length-prefixed string
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(len(p.Unknown7)))
|
|
offset += 2
|
|
copy(dest[offset:], []byte(p.Unknown7))
|
|
offset += uint32(len(p.Unknown7))
|
|
|
|
return offset
|
|
}
|
|
|
|
// Size returns the serialized size of the packet
|
|
func (p *LSLoginRequestV1208) Size() uint32 {
|
|
size := uint32(0)
|
|
|
|
size += 2 + uint32(len(p.Accesscode))
|
|
|
|
size += 2 + uint32(len(p.Unknown1))
|
|
|
|
size += 2 + uint32(len(p.Username))
|
|
|
|
size += 2 + uint32(len(p.Password))
|
|
|
|
size += 8
|
|
|
|
size += 2
|
|
|
|
size += 2
|
|
|
|
size += 1
|
|
|
|
size += 3 * 4
|
|
|
|
size += 2
|
|
|
|
size += 2 + uint32(len(p.Unknown7))
|
|
|
|
return size
|
|
}
|
|
|
|
// LSWorldList represents packet structure for OP_WorldListMsg
|
|
type LSWorldList struct {
|
|
NumWorlds uint8 `eq2:"num_worlds"`
|
|
WorldList []struct {
|
|
Id uint32 `eq2:"id"`
|
|
Name string `eq2:"name,type:str16"`
|
|
Online uint8 `eq2:"online"`
|
|
Locked uint8 `eq2:"locked"`
|
|
Unknown2 uint8 `eq2:"unknown2"`
|
|
Unknown3 uint8 `eq2:"unknown3"`
|
|
Load uint8 `eq2:"load"`
|
|
} `eq2:"world_list,sizeVar:num_worlds"`
|
|
}
|
|
|
|
// Serialize writes the packet data to the provided buffer
|
|
func (p *LSWorldList) Serialize(dest []byte) uint32 {
|
|
offset := uint32(0)
|
|
|
|
// Write NumWorlds
|
|
dest[offset] = byte(p.NumWorlds)
|
|
offset++
|
|
|
|
// Write WorldList array (dynamic size)
|
|
for _, elem := range p.WorldList {
|
|
binary.LittleEndian.PutUint32(dest[offset:], elem.Id)
|
|
offset += 4
|
|
// Write Name string field
|
|
dest[offset] = byte(len(elem.Name))
|
|
offset++
|
|
copy(dest[offset:], []byte(elem.Name))
|
|
offset += uint32(len(elem.Name))
|
|
dest[offset] = elem.Online
|
|
offset++
|
|
dest[offset] = elem.Locked
|
|
offset++
|
|
dest[offset] = elem.Unknown2
|
|
offset++
|
|
dest[offset] = elem.Unknown3
|
|
offset++
|
|
dest[offset] = elem.Load
|
|
offset++
|
|
|
|
}
|
|
|
|
return offset
|
|
}
|
|
|
|
// Size returns the serialized size of the packet
|
|
func (p *LSWorldList) Size() uint32 {
|
|
size := uint32(0)
|
|
|
|
size += 1
|
|
|
|
// Dynamic array: WorldList
|
|
for _, elem := range p.WorldList {
|
|
_ = elem // Avoid unused variable warning
|
|
size += 4
|
|
size += 1 + uint32(len(elem.Name))
|
|
size += 1
|
|
size += 1
|
|
size += 1
|
|
size += 1
|
|
size += 1
|
|
|
|
}
|
|
|
|
return size
|
|
}
|
|
|
|
// LSWorldListV373 represents packet structure for OP_WorldListMsg
|
|
type LSWorldListV373 struct {
|
|
NumWorlds uint8 `eq2:"num_worlds"`
|
|
WorldList []struct {
|
|
Id uint32 `eq2:"id"`
|
|
Name string `eq2:"name,type:str16"`
|
|
Tag uint8 `eq2:"tag"`
|
|
Locked uint8 `eq2:"locked"`
|
|
Hidden uint8 `eq2:"hidden"`
|
|
Unknown uint8 `eq2:"unknown"`
|
|
NumPlayers uint16 `eq2:"num_players"`
|
|
Load uint8 `eq2:"load"`
|
|
NumberOnlineFlag uint8 `eq2:"number_online_flag"`
|
|
AllowedRaces uint32 `eq2:"allowed_races"`
|
|
} `eq2:"world_list,sizeVar:num_worlds"`
|
|
}
|
|
|
|
// Serialize writes the packet data to the provided buffer
|
|
func (p *LSWorldListV373) Serialize(dest []byte) uint32 {
|
|
offset := uint32(0)
|
|
|
|
// Write NumWorlds
|
|
dest[offset] = byte(p.NumWorlds)
|
|
offset++
|
|
|
|
// Write WorldList array (dynamic size)
|
|
for _, elem := range p.WorldList {
|
|
binary.LittleEndian.PutUint32(dest[offset:], elem.Id)
|
|
offset += 4
|
|
// Write Name string field
|
|
dest[offset] = byte(len(elem.Name))
|
|
offset++
|
|
copy(dest[offset:], []byte(elem.Name))
|
|
offset += uint32(len(elem.Name))
|
|
dest[offset] = elem.Tag
|
|
offset++
|
|
dest[offset] = elem.Locked
|
|
offset++
|
|
dest[offset] = elem.Hidden
|
|
offset++
|
|
dest[offset] = elem.Unknown
|
|
offset++
|
|
binary.LittleEndian.PutUint16(dest[offset:], elem.NumPlayers)
|
|
offset += 2
|
|
dest[offset] = elem.Load
|
|
offset++
|
|
dest[offset] = elem.NumberOnlineFlag
|
|
offset++
|
|
binary.LittleEndian.PutUint32(dest[offset:], elem.AllowedRaces)
|
|
offset += 4
|
|
|
|
}
|
|
|
|
return offset
|
|
}
|
|
|
|
// Size returns the serialized size of the packet
|
|
func (p *LSWorldListV373) Size() uint32 {
|
|
size := uint32(0)
|
|
|
|
size += 1
|
|
|
|
// Dynamic array: WorldList
|
|
for _, elem := range p.WorldList {
|
|
_ = elem // Avoid unused variable warning
|
|
size += 4
|
|
size += 1 + uint32(len(elem.Name))
|
|
size += 1
|
|
size += 1
|
|
size += 1
|
|
size += 1
|
|
size += 2
|
|
size += 1
|
|
size += 1
|
|
size += 4
|
|
|
|
}
|
|
|
|
return size
|
|
}
|
|
|
|
// LSWorldListV546 represents packet structure for OP_WorldListMsg
|
|
type LSWorldListV546 struct {
|
|
NumWorlds uint8 `eq2:"num_worlds"`
|
|
WorldList []struct {
|
|
Id uint32 `eq2:"id"`
|
|
Name string `eq2:"name,type:str16"`
|
|
Name2 string `eq2:"name2,type:str16"`
|
|
Tag uint8 `eq2:"tag"`
|
|
Locked uint8 `eq2:"locked"`
|
|
Hidden uint8 `eq2:"hidden"`
|
|
Unknown uint8 `eq2:"unknown"`
|
|
NumPlayers uint16 `eq2:"num_players"`
|
|
Load uint8 `eq2:"load"`
|
|
NumberOnlineFlag uint8 `eq2:"number_online_flag"`
|
|
Unknown2 uint8 `eq2:"unknown2"`
|
|
AllowedRaces uint32 `eq2:"allowed_races"`
|
|
} `eq2:"world_list,sizeVar:num_worlds"`
|
|
}
|
|
|
|
// Serialize writes the packet data to the provided buffer
|
|
func (p *LSWorldListV546) Serialize(dest []byte) uint32 {
|
|
offset := uint32(0)
|
|
|
|
// Write NumWorlds
|
|
dest[offset] = byte(p.NumWorlds)
|
|
offset++
|
|
|
|
// Write WorldList array (dynamic size)
|
|
for _, elem := range p.WorldList {
|
|
binary.LittleEndian.PutUint32(dest[offset:], elem.Id)
|
|
offset += 4
|
|
// Write Name string field
|
|
dest[offset] = byte(len(elem.Name))
|
|
offset++
|
|
copy(dest[offset:], []byte(elem.Name))
|
|
offset += uint32(len(elem.Name))
|
|
// Write Name2 string field
|
|
dest[offset] = byte(len(elem.Name2))
|
|
offset++
|
|
copy(dest[offset:], []byte(elem.Name2))
|
|
offset += uint32(len(elem.Name2))
|
|
dest[offset] = elem.Tag
|
|
offset++
|
|
dest[offset] = elem.Locked
|
|
offset++
|
|
dest[offset] = elem.Hidden
|
|
offset++
|
|
dest[offset] = elem.Unknown
|
|
offset++
|
|
binary.LittleEndian.PutUint16(dest[offset:], elem.NumPlayers)
|
|
offset += 2
|
|
dest[offset] = elem.Load
|
|
offset++
|
|
dest[offset] = elem.NumberOnlineFlag
|
|
offset++
|
|
dest[offset] = elem.Unknown2
|
|
offset++
|
|
binary.LittleEndian.PutUint32(dest[offset:], elem.AllowedRaces)
|
|
offset += 4
|
|
|
|
}
|
|
|
|
return offset
|
|
}
|
|
|
|
// Size returns the serialized size of the packet
|
|
func (p *LSWorldListV546) Size() uint32 {
|
|
size := uint32(0)
|
|
|
|
size += 1
|
|
|
|
// Dynamic array: WorldList
|
|
for _, elem := range p.WorldList {
|
|
_ = elem // Avoid unused variable warning
|
|
size += 4
|
|
size += 1 + uint32(len(elem.Name))
|
|
size += 1 + uint32(len(elem.Name2))
|
|
size += 1
|
|
size += 1
|
|
size += 1
|
|
size += 1
|
|
size += 2
|
|
size += 1
|
|
size += 1
|
|
size += 1
|
|
size += 4
|
|
|
|
}
|
|
|
|
return size
|
|
}
|
|
|
|
// LSWorldListV562 represents packet structure for OP_WorldListMsg
|
|
type LSWorldListV562 struct {
|
|
NumWorlds uint8 `eq2:"num_worlds"`
|
|
WorldList []struct {
|
|
Id uint32 `eq2:"id"`
|
|
Name string `eq2:"name,type:str16"`
|
|
Name2 string `eq2:"name2,type:str16"`
|
|
Tag uint8 `eq2:"tag"`
|
|
Locked uint8 `eq2:"locked"`
|
|
Hidden uint8 `eq2:"hidden"`
|
|
Unknown uint8 `eq2:"unknown"`
|
|
NumPlayers uint16 `eq2:"num_players"`
|
|
Load uint8 `eq2:"load"`
|
|
NumberOnlineFlag uint8 `eq2:"number_online_flag"`
|
|
FeatureSet [2]uint8 `eq2:"feature_set,size:2"`
|
|
AllowedRaces uint32 `eq2:"allowed_races"`
|
|
} `eq2:"world_list,sizeVar:num_worlds"`
|
|
Unknown2 uint8 `eq2:"unknown2"` // TODO: Identify purpose
|
|
}
|
|
|
|
// Serialize writes the packet data to the provided buffer
|
|
func (p *LSWorldListV562) Serialize(dest []byte) uint32 {
|
|
offset := uint32(0)
|
|
|
|
// Write NumWorlds
|
|
dest[offset] = byte(p.NumWorlds)
|
|
offset++
|
|
|
|
// Write WorldList array (dynamic size)
|
|
for _, elem := range p.WorldList {
|
|
binary.LittleEndian.PutUint32(dest[offset:], elem.Id)
|
|
offset += 4
|
|
// Write Name string field
|
|
dest[offset] = byte(len(elem.Name))
|
|
offset++
|
|
copy(dest[offset:], []byte(elem.Name))
|
|
offset += uint32(len(elem.Name))
|
|
// Write Name2 string field
|
|
dest[offset] = byte(len(elem.Name2))
|
|
offset++
|
|
copy(dest[offset:], []byte(elem.Name2))
|
|
offset += uint32(len(elem.Name2))
|
|
dest[offset] = elem.Tag
|
|
offset++
|
|
dest[offset] = elem.Locked
|
|
offset++
|
|
dest[offset] = elem.Hidden
|
|
offset++
|
|
dest[offset] = elem.Unknown
|
|
offset++
|
|
binary.LittleEndian.PutUint16(dest[offset:], elem.NumPlayers)
|
|
offset += 2
|
|
dest[offset] = elem.Load
|
|
offset++
|
|
dest[offset] = elem.NumberOnlineFlag
|
|
offset++
|
|
// Write FeatureSet array field
|
|
for i := 0; i < 2; i++ {
|
|
dest[offset] = byte(elem.FeatureSet[i])
|
|
offset++
|
|
}
|
|
binary.LittleEndian.PutUint32(dest[offset:], elem.AllowedRaces)
|
|
offset += 4
|
|
|
|
}
|
|
|
|
// Write Unknown2
|
|
dest[offset] = byte(p.Unknown2)
|
|
offset++
|
|
|
|
return offset
|
|
}
|
|
|
|
// Size returns the serialized size of the packet
|
|
func (p *LSWorldListV562) Size() uint32 {
|
|
size := uint32(0)
|
|
|
|
size += 1
|
|
|
|
// Dynamic array: WorldList
|
|
for _, elem := range p.WorldList {
|
|
_ = elem // Avoid unused variable warning
|
|
size += 4
|
|
size += 1 + uint32(len(elem.Name))
|
|
size += 1 + uint32(len(elem.Name2))
|
|
size += 1
|
|
size += 1
|
|
size += 1
|
|
size += 1
|
|
size += 2
|
|
size += 1
|
|
size += 1
|
|
size += 2
|
|
size += 4
|
|
|
|
}
|
|
|
|
size += 1
|
|
|
|
return size
|
|
}
|
|
|
|
// LSWorldListV60114 represents packet structure for OP_WorldListMsg
|
|
type LSWorldListV60114 struct {
|
|
NumWorlds uint8 `eq2:"num_worlds"`
|
|
WorldList []struct {
|
|
Id uint32 `eq2:"id"`
|
|
Name string `eq2:"name,type:str16"`
|
|
Name2 string `eq2:"name2,type:str16"`
|
|
Tag uint8 `eq2:"tag"`
|
|
Locked uint8 `eq2:"locked"`
|
|
Hidden uint8 `eq2:"hidden"`
|
|
Unknown uint8 `eq2:"unknown"`
|
|
NumPlayers uint16 `eq2:"num_players"`
|
|
Load uint8 `eq2:"load"`
|
|
NumberOnlineFlag uint8 `eq2:"number_online_flag"`
|
|
FeatureSet [2]uint8 `eq2:"feature_set,size:2"`
|
|
AllowedRaces uint32 `eq2:"allowed_races"`
|
|
} `eq2:"world_list,sizeVar:num_worlds"`
|
|
Unknown2 uint8 `eq2:"unknown2"` // TODO: Identify purpose
|
|
}
|
|
|
|
// Serialize writes the packet data to the provided buffer
|
|
func (p *LSWorldListV60114) Serialize(dest []byte) uint32 {
|
|
offset := uint32(0)
|
|
|
|
// Write NumWorlds
|
|
dest[offset] = byte(p.NumWorlds)
|
|
offset++
|
|
|
|
// Write WorldList array (dynamic size)
|
|
for _, elem := range p.WorldList {
|
|
binary.LittleEndian.PutUint32(dest[offset:], elem.Id)
|
|
offset += 4
|
|
// Write Name string field
|
|
dest[offset] = byte(len(elem.Name))
|
|
offset++
|
|
copy(dest[offset:], []byte(elem.Name))
|
|
offset += uint32(len(elem.Name))
|
|
// Write Name2 string field
|
|
dest[offset] = byte(len(elem.Name2))
|
|
offset++
|
|
copy(dest[offset:], []byte(elem.Name2))
|
|
offset += uint32(len(elem.Name2))
|
|
dest[offset] = elem.Tag
|
|
offset++
|
|
dest[offset] = elem.Locked
|
|
offset++
|
|
dest[offset] = elem.Hidden
|
|
offset++
|
|
dest[offset] = elem.Unknown
|
|
offset++
|
|
binary.LittleEndian.PutUint16(dest[offset:], elem.NumPlayers)
|
|
offset += 2
|
|
dest[offset] = elem.Load
|
|
offset++
|
|
dest[offset] = elem.NumberOnlineFlag
|
|
offset++
|
|
// Write FeatureSet array field
|
|
for i := 0; i < 2; i++ {
|
|
dest[offset] = byte(elem.FeatureSet[i])
|
|
offset++
|
|
}
|
|
binary.LittleEndian.PutUint32(dest[offset:], elem.AllowedRaces)
|
|
offset += 4
|
|
|
|
}
|
|
|
|
// Write Unknown2
|
|
dest[offset] = byte(p.Unknown2)
|
|
offset++
|
|
|
|
return offset
|
|
}
|
|
|
|
// Size returns the serialized size of the packet
|
|
func (p *LSWorldListV60114) Size() uint32 {
|
|
size := uint32(0)
|
|
|
|
size += 1
|
|
|
|
// Dynamic array: WorldList
|
|
for _, elem := range p.WorldList {
|
|
_ = elem // Avoid unused variable warning
|
|
size += 4
|
|
size += 1 + uint32(len(elem.Name))
|
|
size += 1 + uint32(len(elem.Name2))
|
|
size += 1
|
|
size += 1
|
|
size += 1
|
|
size += 1
|
|
size += 2
|
|
size += 1
|
|
size += 1
|
|
size += 2
|
|
size += 4
|
|
|
|
}
|
|
|
|
size += 1
|
|
|
|
return size
|
|
}
|
|
|
|
// LSWorldListV65534 represents packet structure for OP_WorldListMsg
|
|
type LSWorldListV65534 struct {
|
|
NumWorlds uint8 `eq2:"num_worlds"`
|
|
WorldList []struct {
|
|
Id uint32 `eq2:"id"`
|
|
Name string `eq2:"name,type:str16"`
|
|
Name2 string `eq2:"name2,type:str16"`
|
|
Tag uint8 `eq2:"tag"`
|
|
Locked uint8 `eq2:"locked"`
|
|
Hidden uint8 `eq2:"hidden"`
|
|
Unknown uint8 `eq2:"unknown"`
|
|
NumPlayers uint16 `eq2:"num_players"`
|
|
Load uint8 `eq2:"load"`
|
|
NumberOnlineFlag uint8 `eq2:"number_online_flag"`
|
|
FeatureSet [3]uint8 `eq2:"feature_set,size:3"`
|
|
AllowedRaces uint32 `eq2:"allowed_races"`
|
|
} `eq2:"world_list,sizeVar:num_worlds"`
|
|
Unknown2 uint8 `eq2:"unknown2"` // TODO: Identify purpose
|
|
}
|
|
|
|
// Serialize writes the packet data to the provided buffer
|
|
func (p *LSWorldListV65534) Serialize(dest []byte) uint32 {
|
|
offset := uint32(0)
|
|
|
|
// Write NumWorlds
|
|
dest[offset] = byte(p.NumWorlds)
|
|
offset++
|
|
|
|
// Write WorldList array (dynamic size)
|
|
for _, elem := range p.WorldList {
|
|
binary.LittleEndian.PutUint32(dest[offset:], elem.Id)
|
|
offset += 4
|
|
// Write Name string field
|
|
dest[offset] = byte(len(elem.Name))
|
|
offset++
|
|
copy(dest[offset:], []byte(elem.Name))
|
|
offset += uint32(len(elem.Name))
|
|
// Write Name2 string field
|
|
dest[offset] = byte(len(elem.Name2))
|
|
offset++
|
|
copy(dest[offset:], []byte(elem.Name2))
|
|
offset += uint32(len(elem.Name2))
|
|
dest[offset] = elem.Tag
|
|
offset++
|
|
dest[offset] = elem.Locked
|
|
offset++
|
|
dest[offset] = elem.Hidden
|
|
offset++
|
|
dest[offset] = elem.Unknown
|
|
offset++
|
|
binary.LittleEndian.PutUint16(dest[offset:], elem.NumPlayers)
|
|
offset += 2
|
|
dest[offset] = elem.Load
|
|
offset++
|
|
dest[offset] = elem.NumberOnlineFlag
|
|
offset++
|
|
// Write FeatureSet array field
|
|
for i := 0; i < 3; i++ {
|
|
dest[offset] = byte(elem.FeatureSet[i])
|
|
offset++
|
|
}
|
|
binary.LittleEndian.PutUint32(dest[offset:], elem.AllowedRaces)
|
|
offset += 4
|
|
|
|
}
|
|
|
|
// Write Unknown2
|
|
dest[offset] = byte(p.Unknown2)
|
|
offset++
|
|
|
|
return offset
|
|
}
|
|
|
|
// Size returns the serialized size of the packet
|
|
func (p *LSWorldListV65534) Size() uint32 {
|
|
size := uint32(0)
|
|
|
|
size += 1
|
|
|
|
// Dynamic array: WorldList
|
|
for _, elem := range p.WorldList {
|
|
_ = elem // Avoid unused variable warning
|
|
size += 4
|
|
size += 1 + uint32(len(elem.Name))
|
|
size += 1 + uint32(len(elem.Name2))
|
|
size += 1
|
|
size += 1
|
|
size += 1
|
|
size += 1
|
|
size += 2
|
|
size += 1
|
|
size += 1
|
|
size += 3
|
|
size += 4
|
|
|
|
}
|
|
|
|
size += 1
|
|
|
|
return size
|
|
}
|
|
|
|
// LSWorldUpdate represents packet structure for OP_WorldStatusChangeMsg
|
|
type LSWorldUpdate struct {
|
|
ServerId uint32 `eq2:"server_id"`
|
|
Up uint8 `eq2:"up"`
|
|
Locked uint8 `eq2:"locked"`
|
|
Unknown1 uint8 `eq2:"unknown1"` // TODO: Identify purpose
|
|
Unknown2 uint8 `eq2:"unknown2"` // TODO: Identify purpose
|
|
}
|
|
|
|
// Serialize writes the packet data to the provided buffer
|
|
func (p *LSWorldUpdate) Serialize(dest []byte) uint32 {
|
|
offset := uint32(0)
|
|
|
|
// Write ServerId
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.ServerId))
|
|
offset += 4
|
|
|
|
// Write Up
|
|
dest[offset] = byte(p.Up)
|
|
offset++
|
|
|
|
// Write Locked
|
|
dest[offset] = byte(p.Locked)
|
|
offset++
|
|
|
|
// Write Unknown1
|
|
dest[offset] = byte(p.Unknown1)
|
|
offset++
|
|
|
|
// Write Unknown2
|
|
dest[offset] = byte(p.Unknown2)
|
|
offset++
|
|
|
|
return offset
|
|
}
|
|
|
|
// Size returns the serialized size of the packet
|
|
func (p *LSWorldUpdate) Size() uint32 {
|
|
size := uint32(0)
|
|
|
|
size += 4
|
|
|
|
size += 1
|
|
|
|
size += 1
|
|
|
|
size += 1
|
|
|
|
size += 1
|
|
|
|
return size
|
|
}
|
|
|
|
// LSPlayRequest represents packet structure for OP_PlayCharacterRequestMsg
|
|
type LSPlayRequest struct {
|
|
CharId uint32 `eq2:"char_id"`
|
|
Name string `eq2:"name,type:str16"`
|
|
}
|
|
|
|
// Serialize writes the packet data to the provided buffer
|
|
func (p *LSPlayRequest) Serialize(dest []byte) uint32 {
|
|
offset := uint32(0)
|
|
|
|
// Write CharId
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.CharId))
|
|
offset += 4
|
|
|
|
// Write Name as 16-bit length-prefixed string
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(len(p.Name)))
|
|
offset += 2
|
|
copy(dest[offset:], []byte(p.Name))
|
|
offset += uint32(len(p.Name))
|
|
|
|
return offset
|
|
}
|
|
|
|
// Size returns the serialized size of the packet
|
|
func (p *LSPlayRequest) Size() uint32 {
|
|
size := uint32(0)
|
|
|
|
size += 4
|
|
|
|
size += 2 + uint32(len(p.Name))
|
|
|
|
return size
|
|
}
|
|
|
|
// LSPlayRequestV284 represents packet structure for OP_PlayCharacterRequestMsg
|
|
type LSPlayRequestV284 struct {
|
|
CharId uint32 `eq2:"char_id"`
|
|
ServerId uint32 `eq2:"server_id"`
|
|
Unknown [3]uint8 `eq2:"unknown,size:3"` // TODO: Identify purpose
|
|
}
|
|
|
|
// Serialize writes the packet data to the provided buffer
|
|
func (p *LSPlayRequestV284) Serialize(dest []byte) uint32 {
|
|
offset := uint32(0)
|
|
|
|
// Write CharId
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.CharId))
|
|
offset += 4
|
|
|
|
// Write ServerId
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.ServerId))
|
|
offset += 4
|
|
|
|
// Write Unknown array
|
|
for i := 0; i < 3; i++ {
|
|
dest[offset] = p.Unknown[i]
|
|
offset++
|
|
}
|
|
|
|
return offset
|
|
}
|
|
|
|
// Size returns the serialized size of the packet
|
|
func (p *LSPlayRequestV284) Size() uint32 {
|
|
size := uint32(0)
|
|
|
|
size += 4
|
|
|
|
size += 4
|
|
|
|
size += 3
|
|
|
|
return size
|
|
}
|
|
|
|
// LSPlayResponse represents packet structure for OP_PlayCharacterReplyMsg
|
|
type LSPlayResponse struct {
|
|
Response uint8 `eq2:"response"`
|
|
Server string `eq2:"server,type:str8"`
|
|
Port uint16 `eq2:"port"`
|
|
AccountId uint32 `eq2:"account_id"`
|
|
AccessCode uint32 `eq2:"access_code"`
|
|
}
|
|
|
|
// Serialize writes the packet data to the provided buffer
|
|
func (p *LSPlayResponse) Serialize(dest []byte) uint32 {
|
|
offset := uint32(0)
|
|
|
|
// Write Response
|
|
dest[offset] = byte(p.Response)
|
|
offset++
|
|
|
|
// Write Server as 8-bit length-prefixed string
|
|
dest[offset] = byte(len(p.Server))
|
|
offset++
|
|
copy(dest[offset:], []byte(p.Server))
|
|
offset += uint32(len(p.Server))
|
|
|
|
// Write Port
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(p.Port))
|
|
offset += 2
|
|
|
|
// Write AccountId
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.AccountId))
|
|
offset += 4
|
|
|
|
// Write AccessCode
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.AccessCode))
|
|
offset += 4
|
|
|
|
return offset
|
|
}
|
|
|
|
// Size returns the serialized size of the packet
|
|
func (p *LSPlayResponse) Size() uint32 {
|
|
size := uint32(0)
|
|
|
|
size += 1
|
|
|
|
size += 1 + uint32(len(p.Server))
|
|
|
|
size += 2
|
|
|
|
size += 4
|
|
|
|
size += 4
|
|
|
|
return size
|
|
}
|
|
|
|
// LSPlayResponseV1096 represents packet structure for OP_PlayCharacterReplyMsg
|
|
type LSPlayResponseV1096 struct {
|
|
Response uint8 `eq2:"response"`
|
|
Unknown1 uint16 `eq2:"unknown1"` // TODO: Identify purpose
|
|
Server string `eq2:"server,type:str8"`
|
|
Port uint16 `eq2:"port"`
|
|
AccountId uint32 `eq2:"account_id"`
|
|
AccessCode uint32 `eq2:"access_code"`
|
|
}
|
|
|
|
// Serialize writes the packet data to the provided buffer
|
|
func (p *LSPlayResponseV1096) Serialize(dest []byte) uint32 {
|
|
offset := uint32(0)
|
|
|
|
// Write Response
|
|
dest[offset] = byte(p.Response)
|
|
offset++
|
|
|
|
// Write Unknown1
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(p.Unknown1))
|
|
offset += 2
|
|
|
|
// Write Server as 8-bit length-prefixed string
|
|
dest[offset] = byte(len(p.Server))
|
|
offset++
|
|
copy(dest[offset:], []byte(p.Server))
|
|
offset += uint32(len(p.Server))
|
|
|
|
// Write Port
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(p.Port))
|
|
offset += 2
|
|
|
|
// Write AccountId
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.AccountId))
|
|
offset += 4
|
|
|
|
// Write AccessCode
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.AccessCode))
|
|
offset += 4
|
|
|
|
return offset
|
|
}
|
|
|
|
// Size returns the serialized size of the packet
|
|
func (p *LSPlayResponseV1096) Size() uint32 {
|
|
size := uint32(0)
|
|
|
|
size += 1
|
|
|
|
size += 2
|
|
|
|
size += 1 + uint32(len(p.Server))
|
|
|
|
size += 2
|
|
|
|
size += 4
|
|
|
|
size += 4
|
|
|
|
return size
|
|
}
|
|
|
|
// LSPlayResponseV60085 represents packet structure for OP_PlayCharacterReplyMsg
|
|
type LSPlayResponseV60085 struct {
|
|
Response uint8 `eq2:"response"`
|
|
Unknown1 [3]uint16 `eq2:"unknown1,size:3"` // TODO: Identify purpose
|
|
Server string `eq2:"server,type:str8"`
|
|
Port uint16 `eq2:"port"`
|
|
AccountId uint32 `eq2:"account_id"`
|
|
AccessCode uint32 `eq2:"access_code"`
|
|
}
|
|
|
|
// Serialize writes the packet data to the provided buffer
|
|
func (p *LSPlayResponseV60085) Serialize(dest []byte) uint32 {
|
|
offset := uint32(0)
|
|
|
|
// Write Response
|
|
dest[offset] = byte(p.Response)
|
|
offset++
|
|
|
|
// Write Unknown1 array
|
|
for i := 0; i < 3; i++ {
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(p.Unknown1[i]))
|
|
offset += 2
|
|
}
|
|
|
|
// Write Server as 8-bit length-prefixed string
|
|
dest[offset] = byte(len(p.Server))
|
|
offset++
|
|
copy(dest[offset:], []byte(p.Server))
|
|
offset += uint32(len(p.Server))
|
|
|
|
// Write Port
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(p.Port))
|
|
offset += 2
|
|
|
|
// Write AccountId
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.AccountId))
|
|
offset += 4
|
|
|
|
// Write AccessCode
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.AccessCode))
|
|
offset += 4
|
|
|
|
return offset
|
|
}
|
|
|
|
// Size returns the serialized size of the packet
|
|
func (p *LSPlayResponseV60085) Size() uint32 {
|
|
size := uint32(0)
|
|
|
|
size += 1
|
|
|
|
size += 3 * 2
|
|
|
|
size += 1 + uint32(len(p.Server))
|
|
|
|
size += 2
|
|
|
|
size += 4
|
|
|
|
size += 4
|
|
|
|
return size
|
|
}
|
|
|
|
// LSPlayResponseV60099 represents packet structure for OP_PlayCharacterReplyMsg
|
|
type LSPlayResponseV60099 struct {
|
|
Response uint8 `eq2:"response"`
|
|
Unknown1 [3]uint16 `eq2:"unknown1,size:3"` // TODO: Identify purpose
|
|
Server string `eq2:"server,type:str8"`
|
|
Port uint16 `eq2:"port"`
|
|
AccountId uint32 `eq2:"account_id"`
|
|
AccessCode uint32 `eq2:"access_code"`
|
|
}
|
|
|
|
// Serialize writes the packet data to the provided buffer
|
|
func (p *LSPlayResponseV60099) Serialize(dest []byte) uint32 {
|
|
offset := uint32(0)
|
|
|
|
// Write Response
|
|
dest[offset] = byte(p.Response)
|
|
offset++
|
|
|
|
// Write Unknown1 array
|
|
for i := 0; i < 3; i++ {
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(p.Unknown1[i]))
|
|
offset += 2
|
|
}
|
|
|
|
// Write Server as 8-bit length-prefixed string
|
|
dest[offset] = byte(len(p.Server))
|
|
offset++
|
|
copy(dest[offset:], []byte(p.Server))
|
|
offset += uint32(len(p.Server))
|
|
|
|
// Write Port
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(p.Port))
|
|
offset += 2
|
|
|
|
// Write AccountId
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.AccountId))
|
|
offset += 4
|
|
|
|
// Write AccessCode
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.AccessCode))
|
|
offset += 4
|
|
|
|
return offset
|
|
}
|
|
|
|
// Size returns the serialized size of the packet
|
|
func (p *LSPlayResponseV60099) Size() uint32 {
|
|
size := uint32(0)
|
|
|
|
size += 1
|
|
|
|
size += 3 * 2
|
|
|
|
size += 1 + uint32(len(p.Server))
|
|
|
|
size += 2
|
|
|
|
size += 4
|
|
|
|
size += 4
|
|
|
|
return size
|
|
}
|
|
|
|
// CharSelectProfile represents packet structure for client version 1
|
|
type CharSelectProfile struct {
|
|
Charid uint32 `eq2:"charid"`
|
|
ServerId uint32 `eq2:"server_id"`
|
|
Name string `eq2:"name,type:str16"`
|
|
Race uint8 `eq2:"race"`
|
|
Class uint8 `eq2:"class"`
|
|
Level uint32 `eq2:"level"`
|
|
Zone string `eq2:"zone,type:str16"`
|
|
Unknown1 uint32 `eq2:"unknown1"` // TODO: Identify purpose
|
|
Unknown2 uint32 `eq2:"unknown2"` // TODO: Identify purpose
|
|
CreatedDate uint32 `eq2:"created_date"`
|
|
LastPlayed uint32 `eq2:"last_played"`
|
|
Unknown3 uint32 `eq2:"unknown3"` // TODO: Identify purpose
|
|
Unknown4 uint32 `eq2:"unknown4"` // TODO: Identify purpose
|
|
Zonename2 string `eq2:"zonename2,type:str16"`
|
|
Zonedesc string `eq2:"zonedesc,type:str16"`
|
|
Version uint8 `eq2:"version"`
|
|
RaceType uint16 `eq2:"race_type"`
|
|
SkinColor [3]int8 `eq2:"skin_color,size:3"`
|
|
EyeColor [3]int8 `eq2:"eye_color,size:3"`
|
|
Equip [21]types.EquipmentItem `eq2:"equip,size:21"`
|
|
HairType uint16 `eq2:"hair_type"`
|
|
HairTypeColor [3]int8 `eq2:"hair_type_color,size:3"`
|
|
HairTypeHighlightColor [3]int8 `eq2:"hair_type_highlight_color,size:3"`
|
|
HairFaceType uint16 `eq2:"hair_face_type"`
|
|
HairFaceColor [3]int8 `eq2:"hair_face_color,size:3"`
|
|
HairFaceHighlightColor [3]int8 `eq2:"hair_face_highlight_color,size:3"`
|
|
ChestType uint16 `eq2:"chest_type"`
|
|
ShirtColor [3]int8 `eq2:"shirt_color,size:3"`
|
|
UnknownChestColor [3]int8 `eq2:"unknown_chest_color,size:3"` // TODO: Identify purpose
|
|
LegsType uint16 `eq2:"legs_type"`
|
|
PantsColor [3]int8 `eq2:"pants_color,size:3"`
|
|
UnknownLegsColor [3]int8 `eq2:"unknown_legs_color,size:3"` // TODO: Identify purpose
|
|
Unknown9 [3]int8 `eq2:"unknown9,size:3"` // TODO: Identify purpose
|
|
EyeType [3]int8 `eq2:"eye_type,size:3"`
|
|
EarType [3]int8 `eq2:"ear_type,size:3"`
|
|
EyeBrowType [3]int8 `eq2:"eye_brow_type,size:3"`
|
|
CheekType [3]int8 `eq2:"cheek_type,size:3"`
|
|
LipType [3]int8 `eq2:"lip_type,size:3"`
|
|
ChinType [3]int8 `eq2:"chin_type,size:3"`
|
|
NoseType [3]int8 `eq2:"nose_type,size:3"`
|
|
BodySize int8 `eq2:"body_size"`
|
|
BumpScale int8 `eq2:"bump_scale"`
|
|
Mount uint16 `eq2:"mount"`
|
|
MountColor1 [3]int8 `eq2:"mount_color1,size:3"`
|
|
MountColor2 [3]int8 `eq2:"mount_color2,size:3"`
|
|
HairColor1 [3]int8 `eq2:"hair_color1,size:3"`
|
|
HairColor2 [3]int8 `eq2:"hair_color2,size:3"`
|
|
HairColor3 [3]int8 `eq2:"hair_color3,size:3"`
|
|
Flags uint8 `eq2:"flags"`
|
|
}
|
|
|
|
// Serialize writes the packet data to the provided buffer
|
|
func (p *CharSelectProfile) Serialize(dest []byte) uint32 {
|
|
offset := uint32(0)
|
|
|
|
// Write Charid
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.Charid))
|
|
offset += 4
|
|
|
|
// Write ServerId
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.ServerId))
|
|
offset += 4
|
|
|
|
// Write Name as 16-bit length-prefixed string
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(len(p.Name)))
|
|
offset += 2
|
|
copy(dest[offset:], []byte(p.Name))
|
|
offset += uint32(len(p.Name))
|
|
|
|
// Write Race
|
|
dest[offset] = byte(p.Race)
|
|
offset++
|
|
|
|
// Write Class
|
|
dest[offset] = byte(p.Class)
|
|
offset++
|
|
|
|
// Write Level
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.Level))
|
|
offset += 4
|
|
|
|
// Write Zone as 16-bit length-prefixed string
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(len(p.Zone)))
|
|
offset += 2
|
|
copy(dest[offset:], []byte(p.Zone))
|
|
offset += uint32(len(p.Zone))
|
|
|
|
// Write Unknown1
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.Unknown1))
|
|
offset += 4
|
|
|
|
// Write Unknown2
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.Unknown2))
|
|
offset += 4
|
|
|
|
// Write CreatedDate
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.CreatedDate))
|
|
offset += 4
|
|
|
|
// Write LastPlayed
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.LastPlayed))
|
|
offset += 4
|
|
|
|
// Write Unknown3
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.Unknown3))
|
|
offset += 4
|
|
|
|
// Write Unknown4
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.Unknown4))
|
|
offset += 4
|
|
|
|
// Write Zonename2 as 16-bit length-prefixed string
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(len(p.Zonename2)))
|
|
offset += 2
|
|
copy(dest[offset:], []byte(p.Zonename2))
|
|
offset += uint32(len(p.Zonename2))
|
|
|
|
// Write Zonedesc as 16-bit length-prefixed string
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(len(p.Zonedesc)))
|
|
offset += 2
|
|
copy(dest[offset:], []byte(p.Zonedesc))
|
|
offset += uint32(len(p.Zonedesc))
|
|
|
|
// Write Version
|
|
dest[offset] = byte(p.Version)
|
|
offset++
|
|
|
|
// Write RaceType
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(p.RaceType))
|
|
offset += 2
|
|
|
|
// Write SkinColor array
|
|
for i := 0; i < 3; i++ {
|
|
dest[offset] = byte(p.SkinColor[i])
|
|
offset++
|
|
}
|
|
|
|
// Write EyeColor array
|
|
for i := 0; i < 3; i++ {
|
|
dest[offset] = byte(p.EyeColor[i])
|
|
offset++
|
|
}
|
|
|
|
// Write Equip array
|
|
for i := 0; i < 21; i++ {
|
|
binary.LittleEndian.PutUint16(dest[offset:], p.Equip[i].Type)
|
|
offset += 2
|
|
binary.LittleEndian.PutUint32(dest[offset:], p.Equip[i].Color.ToUint32())
|
|
offset += 4
|
|
}
|
|
|
|
// Write HairType
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(p.HairType))
|
|
offset += 2
|
|
|
|
// Write HairTypeColor array
|
|
for i := 0; i < 3; i++ {
|
|
dest[offset] = byte(p.HairTypeColor[i])
|
|
offset++
|
|
}
|
|
|
|
// Write HairTypeHighlightColor array
|
|
for i := 0; i < 3; i++ {
|
|
dest[offset] = byte(p.HairTypeHighlightColor[i])
|
|
offset++
|
|
}
|
|
|
|
// Write HairFaceType
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(p.HairFaceType))
|
|
offset += 2
|
|
|
|
// Write HairFaceColor array
|
|
for i := 0; i < 3; i++ {
|
|
dest[offset] = byte(p.HairFaceColor[i])
|
|
offset++
|
|
}
|
|
|
|
// Write HairFaceHighlightColor array
|
|
for i := 0; i < 3; i++ {
|
|
dest[offset] = byte(p.HairFaceHighlightColor[i])
|
|
offset++
|
|
}
|
|
|
|
// Write ChestType
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(p.ChestType))
|
|
offset += 2
|
|
|
|
// Write ShirtColor array
|
|
for i := 0; i < 3; i++ {
|
|
dest[offset] = byte(p.ShirtColor[i])
|
|
offset++
|
|
}
|
|
|
|
// Write UnknownChestColor array
|
|
for i := 0; i < 3; i++ {
|
|
dest[offset] = byte(p.UnknownChestColor[i])
|
|
offset++
|
|
}
|
|
|
|
// Write LegsType
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(p.LegsType))
|
|
offset += 2
|
|
|
|
// Write PantsColor array
|
|
for i := 0; i < 3; i++ {
|
|
dest[offset] = byte(p.PantsColor[i])
|
|
offset++
|
|
}
|
|
|
|
// Write UnknownLegsColor array
|
|
for i := 0; i < 3; i++ {
|
|
dest[offset] = byte(p.UnknownLegsColor[i])
|
|
offset++
|
|
}
|
|
|
|
// Write Unknown9 array
|
|
for i := 0; i < 3; i++ {
|
|
dest[offset] = byte(p.Unknown9[i])
|
|
offset++
|
|
}
|
|
|
|
// Write EyeType array
|
|
for i := 0; i < 3; i++ {
|
|
dest[offset] = byte(p.EyeType[i])
|
|
offset++
|
|
}
|
|
|
|
// Write EarType array
|
|
for i := 0; i < 3; i++ {
|
|
dest[offset] = byte(p.EarType[i])
|
|
offset++
|
|
}
|
|
|
|
// Write EyeBrowType array
|
|
for i := 0; i < 3; i++ {
|
|
dest[offset] = byte(p.EyeBrowType[i])
|
|
offset++
|
|
}
|
|
|
|
// Write CheekType array
|
|
for i := 0; i < 3; i++ {
|
|
dest[offset] = byte(p.CheekType[i])
|
|
offset++
|
|
}
|
|
|
|
// Write LipType array
|
|
for i := 0; i < 3; i++ {
|
|
dest[offset] = byte(p.LipType[i])
|
|
offset++
|
|
}
|
|
|
|
// Write ChinType array
|
|
for i := 0; i < 3; i++ {
|
|
dest[offset] = byte(p.ChinType[i])
|
|
offset++
|
|
}
|
|
|
|
// Write NoseType array
|
|
for i := 0; i < 3; i++ {
|
|
dest[offset] = byte(p.NoseType[i])
|
|
offset++
|
|
}
|
|
|
|
// Write BodySize
|
|
dest[offset] = byte(p.BodySize)
|
|
offset++
|
|
|
|
// Write BumpScale
|
|
dest[offset] = byte(p.BumpScale)
|
|
offset++
|
|
|
|
// Write Mount
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(p.Mount))
|
|
offset += 2
|
|
|
|
// Write MountColor1 array
|
|
for i := 0; i < 3; i++ {
|
|
dest[offset] = byte(p.MountColor1[i])
|
|
offset++
|
|
}
|
|
|
|
// Write MountColor2 array
|
|
for i := 0; i < 3; i++ {
|
|
dest[offset] = byte(p.MountColor2[i])
|
|
offset++
|
|
}
|
|
|
|
// Write HairColor1 array
|
|
for i := 0; i < 3; i++ {
|
|
dest[offset] = byte(p.HairColor1[i])
|
|
offset++
|
|
}
|
|
|
|
// Write HairColor2 array
|
|
for i := 0; i < 3; i++ {
|
|
dest[offset] = byte(p.HairColor2[i])
|
|
offset++
|
|
}
|
|
|
|
// Write HairColor3 array
|
|
for i := 0; i < 3; i++ {
|
|
dest[offset] = byte(p.HairColor3[i])
|
|
offset++
|
|
}
|
|
|
|
// Write Flags
|
|
dest[offset] = byte(p.Flags)
|
|
offset++
|
|
|
|
return offset
|
|
}
|
|
|
|
// Size returns the serialized size of the packet
|
|
func (p *CharSelectProfile) Size() uint32 {
|
|
size := uint32(0)
|
|
|
|
size += 4
|
|
|
|
size += 4
|
|
|
|
size += 2 + uint32(len(p.Name))
|
|
|
|
size += 1
|
|
|
|
size += 1
|
|
|
|
size += 4
|
|
|
|
size += 2 + uint32(len(p.Zone))
|
|
|
|
size += 4
|
|
|
|
size += 4
|
|
|
|
size += 4
|
|
|
|
size += 4
|
|
|
|
size += 4
|
|
|
|
size += 4
|
|
|
|
size += 2 + uint32(len(p.Zonename2))
|
|
|
|
size += 2 + uint32(len(p.Zonedesc))
|
|
|
|
size += 1
|
|
|
|
size += 2
|
|
|
|
size += 3
|
|
|
|
size += 3
|
|
|
|
size += 21 * 6
|
|
|
|
size += 2
|
|
|
|
size += 3
|
|
|
|
size += 3
|
|
|
|
size += 2
|
|
|
|
size += 3
|
|
|
|
size += 3
|
|
|
|
size += 2
|
|
|
|
size += 3
|
|
|
|
size += 3
|
|
|
|
size += 2
|
|
|
|
size += 3
|
|
|
|
size += 3
|
|
|
|
size += 3
|
|
|
|
size += 3
|
|
|
|
size += 3
|
|
|
|
size += 3
|
|
|
|
size += 3
|
|
|
|
size += 3
|
|
|
|
size += 3
|
|
|
|
size += 3
|
|
|
|
size += 1
|
|
|
|
size += 1
|
|
|
|
size += 2
|
|
|
|
size += 3
|
|
|
|
size += 3
|
|
|
|
size += 3
|
|
|
|
size += 3
|
|
|
|
size += 3
|
|
|
|
size += 1
|
|
|
|
return size
|
|
}
|
|
|
|
// CharSelectProfileV373 represents packet structure for client version 373
|
|
type CharSelectProfileV373 struct {
|
|
Charid uint32 `eq2:"charid"`
|
|
ServerId uint32 `eq2:"server_id"`
|
|
Name string `eq2:"name,type:str16"`
|
|
Race uint8 `eq2:"race"`
|
|
Class uint8 `eq2:"class"`
|
|
Level uint32 `eq2:"level"`
|
|
Zone string `eq2:"zone,type:str16"`
|
|
Unknown1 uint32 `eq2:"unknown1"` // TODO: Identify purpose
|
|
Unknown2 uint32 `eq2:"unknown2"` // TODO: Identify purpose
|
|
CreatedDate uint32 `eq2:"created_date"`
|
|
LastPlayed uint32 `eq2:"last_played"`
|
|
Unknown3 uint32 `eq2:"unknown3"` // TODO: Identify purpose
|
|
Unknown4 uint32 `eq2:"unknown4"` // TODO: Identify purpose
|
|
Zonename2 string `eq2:"zonename2,type:str16"`
|
|
Zonedesc string `eq2:"zonedesc,type:str16"`
|
|
Version uint8 `eq2:"version"`
|
|
RaceType uint16 `eq2:"race_type"`
|
|
SkinColor [3]int8 `eq2:"skin_color,size:3"`
|
|
EyeColor [3]int8 `eq2:"eye_color,size:3"`
|
|
Equip [21]types.EquipmentItem `eq2:"equip,size:21"`
|
|
HairType uint16 `eq2:"hair_type"`
|
|
HairTypeColor [3]int8 `eq2:"hair_type_color,size:3"`
|
|
HairTypeHighlightColor [3]int8 `eq2:"hair_type_highlight_color,size:3"`
|
|
HairFaceType uint16 `eq2:"hair_face_type"`
|
|
HairFaceColor [3]int8 `eq2:"hair_face_color,size:3"`
|
|
HairFaceHighlightColor [3]int8 `eq2:"hair_face_highlight_color,size:3"`
|
|
ChestType uint16 `eq2:"chest_type"`
|
|
ShirtColor [3]int8 `eq2:"shirt_color,size:3"`
|
|
UnknownChestColor [3]int8 `eq2:"unknown_chest_color,size:3"` // TODO: Identify purpose
|
|
LegsType uint16 `eq2:"legs_type"`
|
|
PantsColor [3]int8 `eq2:"pants_color,size:3"`
|
|
UnknownLegsColor [3]int8 `eq2:"unknown_legs_color,size:3"` // TODO: Identify purpose
|
|
Unknown9 [3]int8 `eq2:"unknown9,size:3"` // TODO: Identify purpose
|
|
EyeType [3]int8 `eq2:"eye_type,size:3"`
|
|
EarType [3]int8 `eq2:"ear_type,size:3"`
|
|
EyeBrowType [3]int8 `eq2:"eye_brow_type,size:3"`
|
|
CheekType [3]int8 `eq2:"cheek_type,size:3"`
|
|
LipType [3]int8 `eq2:"lip_type,size:3"`
|
|
ChinType [3]int8 `eq2:"chin_type,size:3"`
|
|
NoseType [3]int8 `eq2:"nose_type,size:3"`
|
|
BodySize int8 `eq2:"body_size"`
|
|
BumpScale int8 `eq2:"bump_scale"`
|
|
Mount uint16 `eq2:"mount"`
|
|
MountColor1 [3]int8 `eq2:"mount_color1,size:3"`
|
|
MountColor2 [3]int8 `eq2:"mount_color2,size:3"`
|
|
HairColor1 [3]int8 `eq2:"hair_color1,size:3"`
|
|
HairColor2 [3]int8 `eq2:"hair_color2,size:3"`
|
|
HairColor3 [3]int8 `eq2:"hair_color3,size:3"`
|
|
Flags uint8 `eq2:"flags"`
|
|
}
|
|
|
|
// Serialize writes the packet data to the provided buffer
|
|
func (p *CharSelectProfileV373) Serialize(dest []byte) uint32 {
|
|
offset := uint32(0)
|
|
|
|
// Write Charid
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.Charid))
|
|
offset += 4
|
|
|
|
// Write ServerId
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.ServerId))
|
|
offset += 4
|
|
|
|
// Write Name as 16-bit length-prefixed string
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(len(p.Name)))
|
|
offset += 2
|
|
copy(dest[offset:], []byte(p.Name))
|
|
offset += uint32(len(p.Name))
|
|
|
|
// Write Race
|
|
dest[offset] = byte(p.Race)
|
|
offset++
|
|
|
|
// Write Class
|
|
dest[offset] = byte(p.Class)
|
|
offset++
|
|
|
|
// Write Level
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.Level))
|
|
offset += 4
|
|
|
|
// Write Zone as 16-bit length-prefixed string
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(len(p.Zone)))
|
|
offset += 2
|
|
copy(dest[offset:], []byte(p.Zone))
|
|
offset += uint32(len(p.Zone))
|
|
|
|
// Write Unknown1
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.Unknown1))
|
|
offset += 4
|
|
|
|
// Write Unknown2
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.Unknown2))
|
|
offset += 4
|
|
|
|
// Write CreatedDate
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.CreatedDate))
|
|
offset += 4
|
|
|
|
// Write LastPlayed
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.LastPlayed))
|
|
offset += 4
|
|
|
|
// Write Unknown3
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.Unknown3))
|
|
offset += 4
|
|
|
|
// Write Unknown4
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.Unknown4))
|
|
offset += 4
|
|
|
|
// Write Zonename2 as 16-bit length-prefixed string
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(len(p.Zonename2)))
|
|
offset += 2
|
|
copy(dest[offset:], []byte(p.Zonename2))
|
|
offset += uint32(len(p.Zonename2))
|
|
|
|
// Write Zonedesc as 16-bit length-prefixed string
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(len(p.Zonedesc)))
|
|
offset += 2
|
|
copy(dest[offset:], []byte(p.Zonedesc))
|
|
offset += uint32(len(p.Zonedesc))
|
|
|
|
// Write Version
|
|
dest[offset] = byte(p.Version)
|
|
offset++
|
|
|
|
// Write RaceType
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(p.RaceType))
|
|
offset += 2
|
|
|
|
// Write SkinColor array
|
|
for i := 0; i < 3; i++ {
|
|
dest[offset] = byte(p.SkinColor[i])
|
|
offset++
|
|
}
|
|
|
|
// Write EyeColor array
|
|
for i := 0; i < 3; i++ {
|
|
dest[offset] = byte(p.EyeColor[i])
|
|
offset++
|
|
}
|
|
|
|
// Write Equip array
|
|
for i := 0; i < 21; i++ {
|
|
binary.LittleEndian.PutUint16(dest[offset:], p.Equip[i].Type)
|
|
offset += 2
|
|
binary.LittleEndian.PutUint32(dest[offset:], p.Equip[i].Color.ToUint32())
|
|
offset += 4
|
|
}
|
|
|
|
// Write HairType
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(p.HairType))
|
|
offset += 2
|
|
|
|
// Write HairTypeColor array
|
|
for i := 0; i < 3; i++ {
|
|
dest[offset] = byte(p.HairTypeColor[i])
|
|
offset++
|
|
}
|
|
|
|
// Write HairTypeHighlightColor array
|
|
for i := 0; i < 3; i++ {
|
|
dest[offset] = byte(p.HairTypeHighlightColor[i])
|
|
offset++
|
|
}
|
|
|
|
// Write HairFaceType
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(p.HairFaceType))
|
|
offset += 2
|
|
|
|
// Write HairFaceColor array
|
|
for i := 0; i < 3; i++ {
|
|
dest[offset] = byte(p.HairFaceColor[i])
|
|
offset++
|
|
}
|
|
|
|
// Write HairFaceHighlightColor array
|
|
for i := 0; i < 3; i++ {
|
|
dest[offset] = byte(p.HairFaceHighlightColor[i])
|
|
offset++
|
|
}
|
|
|
|
// Write ChestType
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(p.ChestType))
|
|
offset += 2
|
|
|
|
// Write ShirtColor array
|
|
for i := 0; i < 3; i++ {
|
|
dest[offset] = byte(p.ShirtColor[i])
|
|
offset++
|
|
}
|
|
|
|
// Write UnknownChestColor array
|
|
for i := 0; i < 3; i++ {
|
|
dest[offset] = byte(p.UnknownChestColor[i])
|
|
offset++
|
|
}
|
|
|
|
// Write LegsType
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(p.LegsType))
|
|
offset += 2
|
|
|
|
// Write PantsColor array
|
|
for i := 0; i < 3; i++ {
|
|
dest[offset] = byte(p.PantsColor[i])
|
|
offset++
|
|
}
|
|
|
|
// Write UnknownLegsColor array
|
|
for i := 0; i < 3; i++ {
|
|
dest[offset] = byte(p.UnknownLegsColor[i])
|
|
offset++
|
|
}
|
|
|
|
// Write Unknown9 array
|
|
for i := 0; i < 3; i++ {
|
|
dest[offset] = byte(p.Unknown9[i])
|
|
offset++
|
|
}
|
|
|
|
// Write EyeType array
|
|
for i := 0; i < 3; i++ {
|
|
dest[offset] = byte(p.EyeType[i])
|
|
offset++
|
|
}
|
|
|
|
// Write EarType array
|
|
for i := 0; i < 3; i++ {
|
|
dest[offset] = byte(p.EarType[i])
|
|
offset++
|
|
}
|
|
|
|
// Write EyeBrowType array
|
|
for i := 0; i < 3; i++ {
|
|
dest[offset] = byte(p.EyeBrowType[i])
|
|
offset++
|
|
}
|
|
|
|
// Write CheekType array
|
|
for i := 0; i < 3; i++ {
|
|
dest[offset] = byte(p.CheekType[i])
|
|
offset++
|
|
}
|
|
|
|
// Write LipType array
|
|
for i := 0; i < 3; i++ {
|
|
dest[offset] = byte(p.LipType[i])
|
|
offset++
|
|
}
|
|
|
|
// Write ChinType array
|
|
for i := 0; i < 3; i++ {
|
|
dest[offset] = byte(p.ChinType[i])
|
|
offset++
|
|
}
|
|
|
|
// Write NoseType array
|
|
for i := 0; i < 3; i++ {
|
|
dest[offset] = byte(p.NoseType[i])
|
|
offset++
|
|
}
|
|
|
|
// Write BodySize
|
|
dest[offset] = byte(p.BodySize)
|
|
offset++
|
|
|
|
// Write BumpScale
|
|
dest[offset] = byte(p.BumpScale)
|
|
offset++
|
|
|
|
// Write Mount
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(p.Mount))
|
|
offset += 2
|
|
|
|
// Write MountColor1 array
|
|
for i := 0; i < 3; i++ {
|
|
dest[offset] = byte(p.MountColor1[i])
|
|
offset++
|
|
}
|
|
|
|
// Write MountColor2 array
|
|
for i := 0; i < 3; i++ {
|
|
dest[offset] = byte(p.MountColor2[i])
|
|
offset++
|
|
}
|
|
|
|
// Write HairColor1 array
|
|
for i := 0; i < 3; i++ {
|
|
dest[offset] = byte(p.HairColor1[i])
|
|
offset++
|
|
}
|
|
|
|
// Write HairColor2 array
|
|
for i := 0; i < 3; i++ {
|
|
dest[offset] = byte(p.HairColor2[i])
|
|
offset++
|
|
}
|
|
|
|
// Write HairColor3 array
|
|
for i := 0; i < 3; i++ {
|
|
dest[offset] = byte(p.HairColor3[i])
|
|
offset++
|
|
}
|
|
|
|
// Write Flags
|
|
dest[offset] = byte(p.Flags)
|
|
offset++
|
|
|
|
return offset
|
|
}
|
|
|
|
// Size returns the serialized size of the packet
|
|
func (p *CharSelectProfileV373) Size() uint32 {
|
|
size := uint32(0)
|
|
|
|
size += 4
|
|
|
|
size += 4
|
|
|
|
size += 2 + uint32(len(p.Name))
|
|
|
|
size += 1
|
|
|
|
size += 1
|
|
|
|
size += 4
|
|
|
|
size += 2 + uint32(len(p.Zone))
|
|
|
|
size += 4
|
|
|
|
size += 4
|
|
|
|
size += 4
|
|
|
|
size += 4
|
|
|
|
size += 4
|
|
|
|
size += 4
|
|
|
|
size += 2 + uint32(len(p.Zonename2))
|
|
|
|
size += 2 + uint32(len(p.Zonedesc))
|
|
|
|
size += 1
|
|
|
|
size += 2
|
|
|
|
size += 3
|
|
|
|
size += 3
|
|
|
|
size += 21 * 6
|
|
|
|
size += 2
|
|
|
|
size += 3
|
|
|
|
size += 3
|
|
|
|
size += 2
|
|
|
|
size += 3
|
|
|
|
size += 3
|
|
|
|
size += 2
|
|
|
|
size += 3
|
|
|
|
size += 3
|
|
|
|
size += 2
|
|
|
|
size += 3
|
|
|
|
size += 3
|
|
|
|
size += 3
|
|
|
|
size += 3
|
|
|
|
size += 3
|
|
|
|
size += 3
|
|
|
|
size += 3
|
|
|
|
size += 3
|
|
|
|
size += 3
|
|
|
|
size += 3
|
|
|
|
size += 1
|
|
|
|
size += 1
|
|
|
|
size += 2
|
|
|
|
size += 3
|
|
|
|
size += 3
|
|
|
|
size += 3
|
|
|
|
size += 3
|
|
|
|
size += 3
|
|
|
|
size += 1
|
|
|
|
return size
|
|
}
|
|
|
|
// CharSelectProfileV546 represents packet structure for client version 546
|
|
type CharSelectProfileV546 struct {
|
|
Charid uint32 `eq2:"charid"`
|
|
ServerId uint32 `eq2:"server_id"`
|
|
Name string `eq2:"name,type:str16"`
|
|
Race uint8 `eq2:"race"`
|
|
Class uint8 `eq2:"class"`
|
|
Gender uint8 `eq2:"gender"`
|
|
Level uint32 `eq2:"level"`
|
|
Zone string `eq2:"zone,type:str16"`
|
|
Unknown1 uint32 `eq2:"unknown1"` // TODO: Identify purpose
|
|
Unknown2 uint32 `eq2:"unknown2"` // TODO: Identify purpose
|
|
CreatedDate uint32 `eq2:"created_date"`
|
|
LastPlayed uint32 `eq2:"last_played"`
|
|
Unknown3 uint32 `eq2:"unknown3"` // TODO: Identify purpose
|
|
Unknown4 uint32 `eq2:"unknown4"` // TODO: Identify purpose
|
|
Zonename2 string `eq2:"zonename2,type:str16"`
|
|
Zonedesc string `eq2:"zonedesc,type:str16"`
|
|
Unknown5 uint32 `eq2:"unknown5"` // TODO: Identify purpose
|
|
Version uint8 `eq2:"version"`
|
|
RaceType uint16 `eq2:"race_type"`
|
|
SkinColor [3]int8 `eq2:"skin_color,size:3"`
|
|
EyeColor [3]int8 `eq2:"eye_color,size:3"`
|
|
Equip [23]types.EquipmentItem `eq2:"equip,size:23"`
|
|
HairType uint16 `eq2:"hair_type"`
|
|
HairTypeColor [3]int8 `eq2:"hair_type_color,size:3"`
|
|
HairTypeHighlightColor [3]int8 `eq2:"hair_type_highlight_color,size:3"`
|
|
HairFaceType uint16 `eq2:"hair_face_type"`
|
|
HairFaceColor [3]int8 `eq2:"hair_face_color,size:3"`
|
|
HairFaceHighlightColor [3]int8 `eq2:"hair_face_highlight_color,size:3"`
|
|
ChestType uint16 `eq2:"chest_type"`
|
|
ShirtColor [3]int8 `eq2:"shirt_color,size:3"`
|
|
UnknownChestColor [3]int8 `eq2:"unknown_chest_color,size:3"` // TODO: Identify purpose
|
|
LegsType uint16 `eq2:"legs_type"`
|
|
PantsColor [3]int8 `eq2:"pants_color,size:3"`
|
|
UnknownLegsColor [3]int8 `eq2:"unknown_legs_color,size:3"` // TODO: Identify purpose
|
|
Unknown9 [3]int8 `eq2:"unknown9,size:3"` // TODO: Identify purpose
|
|
EyeType [3]int8 `eq2:"eye_type,size:3"`
|
|
EarType [3]int8 `eq2:"ear_type,size:3"`
|
|
EyeBrowType [3]int8 `eq2:"eye_brow_type,size:3"`
|
|
CheekType [3]int8 `eq2:"cheek_type,size:3"`
|
|
LipType [3]int8 `eq2:"lip_type,size:3"`
|
|
ChinType [3]int8 `eq2:"chin_type,size:3"`
|
|
NoseType [3]int8 `eq2:"nose_type,size:3"`
|
|
BodySize int8 `eq2:"body_size"`
|
|
BumpScale int8 `eq2:"bump_scale"`
|
|
Mount uint16 `eq2:"mount"`
|
|
MountColor1 [3]int8 `eq2:"mount_color1,size:3"`
|
|
MountColor2 [3]int8 `eq2:"mount_color2,size:3"`
|
|
HairColor1 [3]int8 `eq2:"hair_color1,size:3"`
|
|
HairColor2 [3]int8 `eq2:"hair_color2,size:3"`
|
|
HairColor3 [3]int8 `eq2:"hair_color3,size:3"`
|
|
Unknown11 [10]uint8 `eq2:"unknown11,size:10"` // TODO: Identify purpose
|
|
SogaRaceType uint16 `eq2:"soga_race_type"`
|
|
SogaSkinColorx types.Color `eq2:"soga_skin_colorx"`
|
|
SogaEyeColor types.Color `eq2:"soga_eye_color"`
|
|
Unknown12 [3]uint8 `eq2:"Unknown12,size:3"` // TODO: Identify purpose
|
|
SogaEyeType [3]int8 `eq2:"soga_eye_type,size:3"`
|
|
SogaEarType [3]int8 `eq2:"soga_ear_type,size:3"`
|
|
SogaEyeBrowType [3]int8 `eq2:"soga_eye_brow_type,size:3"`
|
|
SogaCheekType [3]int8 `eq2:"soga_cheek_type,size:3"`
|
|
SogaLipType [3]int8 `eq2:"soga_lip_type,size:3"`
|
|
SogaChinType [3]int8 `eq2:"soga_chin_type,size:3"`
|
|
SogaNoseType [3]int8 `eq2:"soga_nose_type,size:3"`
|
|
SogaHairColor1 types.Color `eq2:"soga_hair_color1"`
|
|
SogaChestType uint16 `eq2:"soga_chest_type"`
|
|
SogaHairColor2 types.Color `eq2:"soga_hair_color2"`
|
|
SogaHairColor3 types.Color `eq2:"soga_hair_color3"`
|
|
SogaHairType uint16 `eq2:"soga_hair_type"`
|
|
SogaHairTypeColor types.Color `eq2:"soga_hair_type_color"`
|
|
SogaHairTypeHighlightColor types.Color `eq2:"soga_hair_type_highlight_color"`
|
|
SogaHairFaceType uint16 `eq2:"soga_hair_face_type"`
|
|
SogaHairFaceColor types.Color `eq2:"soga_hair_face_color"`
|
|
SogaHairFaceHighlightColor types.Color `eq2:"soga_hair_face_highlight_color"`
|
|
}
|
|
|
|
// Serialize writes the packet data to the provided buffer
|
|
func (p *CharSelectProfileV546) Serialize(dest []byte) uint32 {
|
|
offset := uint32(0)
|
|
|
|
// Write Charid
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.Charid))
|
|
offset += 4
|
|
|
|
// Write ServerId
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.ServerId))
|
|
offset += 4
|
|
|
|
// Write Name as 16-bit length-prefixed string
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(len(p.Name)))
|
|
offset += 2
|
|
copy(dest[offset:], []byte(p.Name))
|
|
offset += uint32(len(p.Name))
|
|
|
|
// Write Race
|
|
dest[offset] = byte(p.Race)
|
|
offset++
|
|
|
|
// Write Class
|
|
dest[offset] = byte(p.Class)
|
|
offset++
|
|
|
|
// Write Gender
|
|
dest[offset] = byte(p.Gender)
|
|
offset++
|
|
|
|
// Write Level
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.Level))
|
|
offset += 4
|
|
|
|
// Write Zone as 16-bit length-prefixed string
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(len(p.Zone)))
|
|
offset += 2
|
|
copy(dest[offset:], []byte(p.Zone))
|
|
offset += uint32(len(p.Zone))
|
|
|
|
// Write Unknown1
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.Unknown1))
|
|
offset += 4
|
|
|
|
// Write Unknown2
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.Unknown2))
|
|
offset += 4
|
|
|
|
// Write CreatedDate
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.CreatedDate))
|
|
offset += 4
|
|
|
|
// Write LastPlayed
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.LastPlayed))
|
|
offset += 4
|
|
|
|
// Write Unknown3
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.Unknown3))
|
|
offset += 4
|
|
|
|
// Write Unknown4
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.Unknown4))
|
|
offset += 4
|
|
|
|
// Write Zonename2 as 16-bit length-prefixed string
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(len(p.Zonename2)))
|
|
offset += 2
|
|
copy(dest[offset:], []byte(p.Zonename2))
|
|
offset += uint32(len(p.Zonename2))
|
|
|
|
// Write Zonedesc as 16-bit length-prefixed string
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(len(p.Zonedesc)))
|
|
offset += 2
|
|
copy(dest[offset:], []byte(p.Zonedesc))
|
|
offset += uint32(len(p.Zonedesc))
|
|
|
|
// Write Unknown5
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.Unknown5))
|
|
offset += 4
|
|
|
|
// Write Version
|
|
dest[offset] = byte(p.Version)
|
|
offset++
|
|
|
|
// Write RaceType
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(p.RaceType))
|
|
offset += 2
|
|
|
|
// Write SkinColor array
|
|
for i := 0; i < 3; i++ {
|
|
dest[offset] = byte(p.SkinColor[i])
|
|
offset++
|
|
}
|
|
|
|
// Write EyeColor array
|
|
for i := 0; i < 3; i++ {
|
|
dest[offset] = byte(p.EyeColor[i])
|
|
offset++
|
|
}
|
|
|
|
// Write Equip array
|
|
for i := 0; i < 23; i++ {
|
|
binary.LittleEndian.PutUint16(dest[offset:], p.Equip[i].Type)
|
|
offset += 2
|
|
binary.LittleEndian.PutUint32(dest[offset:], p.Equip[i].Color.ToUint32())
|
|
offset += 4
|
|
}
|
|
|
|
// Write HairType
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(p.HairType))
|
|
offset += 2
|
|
|
|
// Write HairTypeColor array
|
|
for i := 0; i < 3; i++ {
|
|
dest[offset] = byte(p.HairTypeColor[i])
|
|
offset++
|
|
}
|
|
|
|
// Write HairTypeHighlightColor array
|
|
for i := 0; i < 3; i++ {
|
|
dest[offset] = byte(p.HairTypeHighlightColor[i])
|
|
offset++
|
|
}
|
|
|
|
// Write HairFaceType
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(p.HairFaceType))
|
|
offset += 2
|
|
|
|
// Write HairFaceColor array
|
|
for i := 0; i < 3; i++ {
|
|
dest[offset] = byte(p.HairFaceColor[i])
|
|
offset++
|
|
}
|
|
|
|
// Write HairFaceHighlightColor array
|
|
for i := 0; i < 3; i++ {
|
|
dest[offset] = byte(p.HairFaceHighlightColor[i])
|
|
offset++
|
|
}
|
|
|
|
// Write ChestType
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(p.ChestType))
|
|
offset += 2
|
|
|
|
// Write ShirtColor array
|
|
for i := 0; i < 3; i++ {
|
|
dest[offset] = byte(p.ShirtColor[i])
|
|
offset++
|
|
}
|
|
|
|
// Write UnknownChestColor array
|
|
for i := 0; i < 3; i++ {
|
|
dest[offset] = byte(p.UnknownChestColor[i])
|
|
offset++
|
|
}
|
|
|
|
// Write LegsType
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(p.LegsType))
|
|
offset += 2
|
|
|
|
// Write PantsColor array
|
|
for i := 0; i < 3; i++ {
|
|
dest[offset] = byte(p.PantsColor[i])
|
|
offset++
|
|
}
|
|
|
|
// Write UnknownLegsColor array
|
|
for i := 0; i < 3; i++ {
|
|
dest[offset] = byte(p.UnknownLegsColor[i])
|
|
offset++
|
|
}
|
|
|
|
// Write Unknown9 array
|
|
for i := 0; i < 3; i++ {
|
|
dest[offset] = byte(p.Unknown9[i])
|
|
offset++
|
|
}
|
|
|
|
// Write EyeType array
|
|
for i := 0; i < 3; i++ {
|
|
dest[offset] = byte(p.EyeType[i])
|
|
offset++
|
|
}
|
|
|
|
// Write EarType array
|
|
for i := 0; i < 3; i++ {
|
|
dest[offset] = byte(p.EarType[i])
|
|
offset++
|
|
}
|
|
|
|
// Write EyeBrowType array
|
|
for i := 0; i < 3; i++ {
|
|
dest[offset] = byte(p.EyeBrowType[i])
|
|
offset++
|
|
}
|
|
|
|
// Write CheekType array
|
|
for i := 0; i < 3; i++ {
|
|
dest[offset] = byte(p.CheekType[i])
|
|
offset++
|
|
}
|
|
|
|
// Write LipType array
|
|
for i := 0; i < 3; i++ {
|
|
dest[offset] = byte(p.LipType[i])
|
|
offset++
|
|
}
|
|
|
|
// Write ChinType array
|
|
for i := 0; i < 3; i++ {
|
|
dest[offset] = byte(p.ChinType[i])
|
|
offset++
|
|
}
|
|
|
|
// Write NoseType array
|
|
for i := 0; i < 3; i++ {
|
|
dest[offset] = byte(p.NoseType[i])
|
|
offset++
|
|
}
|
|
|
|
// Write BodySize
|
|
dest[offset] = byte(p.BodySize)
|
|
offset++
|
|
|
|
// Write BumpScale
|
|
dest[offset] = byte(p.BumpScale)
|
|
offset++
|
|
|
|
// Write Mount
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(p.Mount))
|
|
offset += 2
|
|
|
|
// Write MountColor1 array
|
|
for i := 0; i < 3; i++ {
|
|
dest[offset] = byte(p.MountColor1[i])
|
|
offset++
|
|
}
|
|
|
|
// Write MountColor2 array
|
|
for i := 0; i < 3; i++ {
|
|
dest[offset] = byte(p.MountColor2[i])
|
|
offset++
|
|
}
|
|
|
|
// Write HairColor1 array
|
|
for i := 0; i < 3; i++ {
|
|
dest[offset] = byte(p.HairColor1[i])
|
|
offset++
|
|
}
|
|
|
|
// Write HairColor2 array
|
|
for i := 0; i < 3; i++ {
|
|
dest[offset] = byte(p.HairColor2[i])
|
|
offset++
|
|
}
|
|
|
|
// Write HairColor3 array
|
|
for i := 0; i < 3; i++ {
|
|
dest[offset] = byte(p.HairColor3[i])
|
|
offset++
|
|
}
|
|
|
|
// Write Unknown11 array
|
|
for i := 0; i < 10; i++ {
|
|
dest[offset] = p.Unknown11[i]
|
|
offset++
|
|
}
|
|
|
|
// Write SogaRaceType
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(p.SogaRaceType))
|
|
offset += 2
|
|
|
|
// Write SogaSkinColorx
|
|
binary.LittleEndian.PutUint32(dest[offset:], p.SogaSkinColorx.ToUint32())
|
|
offset += 4
|
|
|
|
// Write SogaEyeColor
|
|
binary.LittleEndian.PutUint32(dest[offset:], p.SogaEyeColor.ToUint32())
|
|
offset += 4
|
|
|
|
// Write Unknown12 array
|
|
for i := 0; i < 3; i++ {
|
|
dest[offset] = p.Unknown12[i]
|
|
offset++
|
|
}
|
|
|
|
// Write SogaEyeType array
|
|
for i := 0; i < 3; i++ {
|
|
dest[offset] = byte(p.SogaEyeType[i])
|
|
offset++
|
|
}
|
|
|
|
// Write SogaEarType array
|
|
for i := 0; i < 3; i++ {
|
|
dest[offset] = byte(p.SogaEarType[i])
|
|
offset++
|
|
}
|
|
|
|
// Write SogaEyeBrowType array
|
|
for i := 0; i < 3; i++ {
|
|
dest[offset] = byte(p.SogaEyeBrowType[i])
|
|
offset++
|
|
}
|
|
|
|
// Write SogaCheekType array
|
|
for i := 0; i < 3; i++ {
|
|
dest[offset] = byte(p.SogaCheekType[i])
|
|
offset++
|
|
}
|
|
|
|
// Write SogaLipType array
|
|
for i := 0; i < 3; i++ {
|
|
dest[offset] = byte(p.SogaLipType[i])
|
|
offset++
|
|
}
|
|
|
|
// Write SogaChinType array
|
|
for i := 0; i < 3; i++ {
|
|
dest[offset] = byte(p.SogaChinType[i])
|
|
offset++
|
|
}
|
|
|
|
// Write SogaNoseType array
|
|
for i := 0; i < 3; i++ {
|
|
dest[offset] = byte(p.SogaNoseType[i])
|
|
offset++
|
|
}
|
|
|
|
// Write SogaHairColor1
|
|
binary.LittleEndian.PutUint32(dest[offset:], p.SogaHairColor1.ToUint32())
|
|
offset += 4
|
|
|
|
// Write SogaChestType
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(p.SogaChestType))
|
|
offset += 2
|
|
|
|
// Write SogaHairColor2
|
|
binary.LittleEndian.PutUint32(dest[offset:], p.SogaHairColor2.ToUint32())
|
|
offset += 4
|
|
|
|
// Write SogaHairColor3
|
|
binary.LittleEndian.PutUint32(dest[offset:], p.SogaHairColor3.ToUint32())
|
|
offset += 4
|
|
|
|
// Write SogaHairType
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(p.SogaHairType))
|
|
offset += 2
|
|
|
|
// Write SogaHairTypeColor
|
|
binary.LittleEndian.PutUint32(dest[offset:], p.SogaHairTypeColor.ToUint32())
|
|
offset += 4
|
|
|
|
// Write SogaHairTypeHighlightColor
|
|
binary.LittleEndian.PutUint32(dest[offset:], p.SogaHairTypeHighlightColor.ToUint32())
|
|
offset += 4
|
|
|
|
// Write SogaHairFaceType
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(p.SogaHairFaceType))
|
|
offset += 2
|
|
|
|
// Write SogaHairFaceColor
|
|
binary.LittleEndian.PutUint32(dest[offset:], p.SogaHairFaceColor.ToUint32())
|
|
offset += 4
|
|
|
|
// Write SogaHairFaceHighlightColor
|
|
binary.LittleEndian.PutUint32(dest[offset:], p.SogaHairFaceHighlightColor.ToUint32())
|
|
offset += 4
|
|
|
|
return offset
|
|
}
|
|
|
|
// Size returns the serialized size of the packet
|
|
func (p *CharSelectProfileV546) Size() uint32 {
|
|
size := uint32(0)
|
|
|
|
size += 4
|
|
|
|
size += 4
|
|
|
|
size += 2 + uint32(len(p.Name))
|
|
|
|
size += 1
|
|
|
|
size += 1
|
|
|
|
size += 1
|
|
|
|
size += 4
|
|
|
|
size += 2 + uint32(len(p.Zone))
|
|
|
|
size += 4
|
|
|
|
size += 4
|
|
|
|
size += 4
|
|
|
|
size += 4
|
|
|
|
size += 4
|
|
|
|
size += 4
|
|
|
|
size += 2 + uint32(len(p.Zonename2))
|
|
|
|
size += 2 + uint32(len(p.Zonedesc))
|
|
|
|
size += 4
|
|
|
|
size += 1
|
|
|
|
size += 2
|
|
|
|
size += 3
|
|
|
|
size += 3
|
|
|
|
size += 23 * 6
|
|
|
|
size += 2
|
|
|
|
size += 3
|
|
|
|
size += 3
|
|
|
|
size += 2
|
|
|
|
size += 3
|
|
|
|
size += 3
|
|
|
|
size += 2
|
|
|
|
size += 3
|
|
|
|
size += 3
|
|
|
|
size += 2
|
|
|
|
size += 3
|
|
|
|
size += 3
|
|
|
|
size += 3
|
|
|
|
size += 3
|
|
|
|
size += 3
|
|
|
|
size += 3
|
|
|
|
size += 3
|
|
|
|
size += 3
|
|
|
|
size += 3
|
|
|
|
size += 3
|
|
|
|
size += 1
|
|
|
|
size += 1
|
|
|
|
size += 2
|
|
|
|
size += 3
|
|
|
|
size += 3
|
|
|
|
size += 3
|
|
|
|
size += 3
|
|
|
|
size += 3
|
|
|
|
size += 10
|
|
|
|
size += 2
|
|
|
|
size += 4
|
|
|
|
size += 4
|
|
|
|
size += 3
|
|
|
|
size += 3
|
|
|
|
size += 3
|
|
|
|
size += 3
|
|
|
|
size += 3
|
|
|
|
size += 3
|
|
|
|
size += 3
|
|
|
|
size += 3
|
|
|
|
size += 4
|
|
|
|
size += 2
|
|
|
|
size += 4
|
|
|
|
size += 4
|
|
|
|
size += 2
|
|
|
|
size += 4
|
|
|
|
size += 4
|
|
|
|
size += 2
|
|
|
|
size += 4
|
|
|
|
size += 4
|
|
|
|
return size
|
|
}
|
|
|
|
// CharSelectProfileV562 represents packet structure for client version 562
|
|
type CharSelectProfileV562 struct {
|
|
Version uint32 `eq2:"version"`
|
|
Charid uint32 `eq2:"charid"`
|
|
ServerId uint32 `eq2:"server_id"`
|
|
Name string `eq2:"name,type:str16"`
|
|
Unknown uint8 `eq2:"unknown"` // TODO: Identify purpose
|
|
Race uint8 `eq2:"race"`
|
|
Class uint8 `eq2:"class"`
|
|
Gender uint8 `eq2:"gender"`
|
|
Level uint32 `eq2:"level"`
|
|
Zone string `eq2:"zone,type:str16"`
|
|
Unknown1 uint32 `eq2:"unknown1"` // TODO: Identify purpose
|
|
Unknown2 uint32 `eq2:"unknown2"` // TODO: Identify purpose
|
|
CreatedDate uint32 `eq2:"created_date"`
|
|
LastPlayed uint32 `eq2:"last_played"`
|
|
Unknown3 uint32 `eq2:"unknown3"` // TODO: Identify purpose
|
|
Unknown4 uint32 `eq2:"unknown4"` // TODO: Identify purpose
|
|
Zonename2 string `eq2:"zonename2,type:str16"`
|
|
Zonedesc string `eq2:"zonedesc,type:str16"`
|
|
Unknown5 uint32 `eq2:"unknown5"` // TODO: Identify purpose
|
|
ServerName string `eq2:"server_name,type:str16"`
|
|
AccountId uint32 `eq2:"account_id"`
|
|
Unknown6 [2]uint8 `eq2:"unknown6,size:2"` // TODO: Identify purpose
|
|
Unknown7 uint32 `eq2:"unknown7"` // TODO: Identify purpose
|
|
Unknown8 uint8 `eq2:"unknown8"` // TODO: Identify purpose
|
|
RaceType uint16 `eq2:"race_type"`
|
|
SkinColor types.Color `eq2:"skin_color"`
|
|
EyeColor types.Color `eq2:"eye_color"`
|
|
Equip [25]types.EquipmentItem `eq2:"equip,size:25"`
|
|
HairType uint16 `eq2:"hair_type"`
|
|
HairTypeColor types.Color `eq2:"hair_type_color"`
|
|
HairTypeHighlightColor types.Color `eq2:"hair_type_highlight_color"`
|
|
HairFaceType uint16 `eq2:"hair_face_type"`
|
|
HairFaceColor types.Color `eq2:"hair_face_color"`
|
|
HairFaceHighlightColor types.Color `eq2:"hair_face_highlight_color"`
|
|
ChestType uint16 `eq2:"chest_type"`
|
|
ShirtColor types.Color `eq2:"shirt_color"`
|
|
UnknownChestColor types.Color `eq2:"unknown_chest_color"` // TODO: Identify purpose
|
|
LegsType uint16 `eq2:"legs_type"`
|
|
PantsColor types.Color `eq2:"pants_color"`
|
|
UnknownLegsColor types.Color `eq2:"unknown_legs_color"` // TODO: Identify purpose
|
|
Unknown9 types.Color `eq2:"unknown9"` // TODO: Identify purpose
|
|
EyeType [3]int8 `eq2:"eye_type,size:3"`
|
|
EarType [3]int8 `eq2:"ear_type,size:3"`
|
|
EyeBrowType [3]int8 `eq2:"eye_brow_type,size:3"`
|
|
CheekType [3]int8 `eq2:"cheek_type,size:3"`
|
|
LipType [3]int8 `eq2:"lip_type,size:3"`
|
|
ChinType [3]int8 `eq2:"chin_type,size:3"`
|
|
NoseType [3]int8 `eq2:"nose_type,size:3"`
|
|
BodySize int8 `eq2:"body_size"`
|
|
Unknown10 [9]uint8 `eq2:"unknown10,size:9"` // TODO: Identify purpose
|
|
HairColor1 types.Color `eq2:"hair_color1"`
|
|
HairColor2 types.Color `eq2:"hair_color2"`
|
|
Unknown11 [13]uint8 `eq2:"unknown11,size:13"` // TODO: Identify purpose
|
|
Unknown15 [7]uint8 `eq2:"unknown15,size:7"` // TODO: Identify purpose
|
|
}
|
|
|
|
// Serialize writes the packet data to the provided buffer
|
|
func (p *CharSelectProfileV562) Serialize(dest []byte) uint32 {
|
|
offset := uint32(0)
|
|
|
|
// Write Version
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.Version))
|
|
offset += 4
|
|
|
|
// Write Charid
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.Charid))
|
|
offset += 4
|
|
|
|
// Write ServerId
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.ServerId))
|
|
offset += 4
|
|
|
|
// Write Name as 16-bit length-prefixed string
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(len(p.Name)))
|
|
offset += 2
|
|
copy(dest[offset:], []byte(p.Name))
|
|
offset += uint32(len(p.Name))
|
|
|
|
// Write Unknown
|
|
dest[offset] = byte(p.Unknown)
|
|
offset++
|
|
|
|
// Write Race
|
|
dest[offset] = byte(p.Race)
|
|
offset++
|
|
|
|
// Write Class
|
|
dest[offset] = byte(p.Class)
|
|
offset++
|
|
|
|
// Write Gender
|
|
dest[offset] = byte(p.Gender)
|
|
offset++
|
|
|
|
// Write Level
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.Level))
|
|
offset += 4
|
|
|
|
// Write Zone as 16-bit length-prefixed string
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(len(p.Zone)))
|
|
offset += 2
|
|
copy(dest[offset:], []byte(p.Zone))
|
|
offset += uint32(len(p.Zone))
|
|
|
|
// Write Unknown1
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.Unknown1))
|
|
offset += 4
|
|
|
|
// Write Unknown2
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.Unknown2))
|
|
offset += 4
|
|
|
|
// Write CreatedDate
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.CreatedDate))
|
|
offset += 4
|
|
|
|
// Write LastPlayed
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.LastPlayed))
|
|
offset += 4
|
|
|
|
// Write Unknown3
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.Unknown3))
|
|
offset += 4
|
|
|
|
// Write Unknown4
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.Unknown4))
|
|
offset += 4
|
|
|
|
// Write Zonename2 as 16-bit length-prefixed string
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(len(p.Zonename2)))
|
|
offset += 2
|
|
copy(dest[offset:], []byte(p.Zonename2))
|
|
offset += uint32(len(p.Zonename2))
|
|
|
|
// Write Zonedesc as 16-bit length-prefixed string
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(len(p.Zonedesc)))
|
|
offset += 2
|
|
copy(dest[offset:], []byte(p.Zonedesc))
|
|
offset += uint32(len(p.Zonedesc))
|
|
|
|
// Write Unknown5
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.Unknown5))
|
|
offset += 4
|
|
|
|
// Write ServerName as 16-bit length-prefixed string
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(len(p.ServerName)))
|
|
offset += 2
|
|
copy(dest[offset:], []byte(p.ServerName))
|
|
offset += uint32(len(p.ServerName))
|
|
|
|
// Write AccountId
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.AccountId))
|
|
offset += 4
|
|
|
|
// Write Unknown6 array
|
|
for i := 0; i < 2; i++ {
|
|
dest[offset] = p.Unknown6[i]
|
|
offset++
|
|
}
|
|
|
|
// Write Unknown7
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.Unknown7))
|
|
offset += 4
|
|
|
|
// Write Unknown8
|
|
dest[offset] = byte(p.Unknown8)
|
|
offset++
|
|
|
|
// Write RaceType
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(p.RaceType))
|
|
offset += 2
|
|
|
|
// Write SkinColor
|
|
binary.LittleEndian.PutUint32(dest[offset:], p.SkinColor.ToUint32())
|
|
offset += 4
|
|
|
|
// Write EyeColor
|
|
binary.LittleEndian.PutUint32(dest[offset:], p.EyeColor.ToUint32())
|
|
offset += 4
|
|
|
|
// Write Equip array
|
|
for i := 0; i < 25; i++ {
|
|
binary.LittleEndian.PutUint16(dest[offset:], p.Equip[i].Type)
|
|
offset += 2
|
|
binary.LittleEndian.PutUint32(dest[offset:], p.Equip[i].Color.ToUint32())
|
|
offset += 4
|
|
}
|
|
|
|
// Write HairType
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(p.HairType))
|
|
offset += 2
|
|
|
|
// Write HairTypeColor
|
|
binary.LittleEndian.PutUint32(dest[offset:], p.HairTypeColor.ToUint32())
|
|
offset += 4
|
|
|
|
// Write HairTypeHighlightColor
|
|
binary.LittleEndian.PutUint32(dest[offset:], p.HairTypeHighlightColor.ToUint32())
|
|
offset += 4
|
|
|
|
// Write HairFaceType
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(p.HairFaceType))
|
|
offset += 2
|
|
|
|
// Write HairFaceColor
|
|
binary.LittleEndian.PutUint32(dest[offset:], p.HairFaceColor.ToUint32())
|
|
offset += 4
|
|
|
|
// Write HairFaceHighlightColor
|
|
binary.LittleEndian.PutUint32(dest[offset:], p.HairFaceHighlightColor.ToUint32())
|
|
offset += 4
|
|
|
|
// Write ChestType
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(p.ChestType))
|
|
offset += 2
|
|
|
|
// Write ShirtColor
|
|
binary.LittleEndian.PutUint32(dest[offset:], p.ShirtColor.ToUint32())
|
|
offset += 4
|
|
|
|
// Write UnknownChestColor
|
|
binary.LittleEndian.PutUint32(dest[offset:], p.UnknownChestColor.ToUint32())
|
|
offset += 4
|
|
|
|
// Write LegsType
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(p.LegsType))
|
|
offset += 2
|
|
|
|
// Write PantsColor
|
|
binary.LittleEndian.PutUint32(dest[offset:], p.PantsColor.ToUint32())
|
|
offset += 4
|
|
|
|
// Write UnknownLegsColor
|
|
binary.LittleEndian.PutUint32(dest[offset:], p.UnknownLegsColor.ToUint32())
|
|
offset += 4
|
|
|
|
// Write Unknown9
|
|
binary.LittleEndian.PutUint32(dest[offset:], p.Unknown9.ToUint32())
|
|
offset += 4
|
|
|
|
// Write EyeType array
|
|
for i := 0; i < 3; i++ {
|
|
dest[offset] = byte(p.EyeType[i])
|
|
offset++
|
|
}
|
|
|
|
// Write EarType array
|
|
for i := 0; i < 3; i++ {
|
|
dest[offset] = byte(p.EarType[i])
|
|
offset++
|
|
}
|
|
|
|
// Write EyeBrowType array
|
|
for i := 0; i < 3; i++ {
|
|
dest[offset] = byte(p.EyeBrowType[i])
|
|
offset++
|
|
}
|
|
|
|
// Write CheekType array
|
|
for i := 0; i < 3; i++ {
|
|
dest[offset] = byte(p.CheekType[i])
|
|
offset++
|
|
}
|
|
|
|
// Write LipType array
|
|
for i := 0; i < 3; i++ {
|
|
dest[offset] = byte(p.LipType[i])
|
|
offset++
|
|
}
|
|
|
|
// Write ChinType array
|
|
for i := 0; i < 3; i++ {
|
|
dest[offset] = byte(p.ChinType[i])
|
|
offset++
|
|
}
|
|
|
|
// Write NoseType array
|
|
for i := 0; i < 3; i++ {
|
|
dest[offset] = byte(p.NoseType[i])
|
|
offset++
|
|
}
|
|
|
|
// Write BodySize
|
|
dest[offset] = byte(p.BodySize)
|
|
offset++
|
|
|
|
// Write Unknown10 array
|
|
for i := 0; i < 9; i++ {
|
|
dest[offset] = p.Unknown10[i]
|
|
offset++
|
|
}
|
|
|
|
// Write HairColor1
|
|
binary.LittleEndian.PutUint32(dest[offset:], p.HairColor1.ToUint32())
|
|
offset += 4
|
|
|
|
// Write HairColor2
|
|
binary.LittleEndian.PutUint32(dest[offset:], p.HairColor2.ToUint32())
|
|
offset += 4
|
|
|
|
// Write Unknown11 array
|
|
for i := 0; i < 13; i++ {
|
|
dest[offset] = p.Unknown11[i]
|
|
offset++
|
|
}
|
|
|
|
// Write Unknown15 array
|
|
for i := 0; i < 7; i++ {
|
|
dest[offset] = p.Unknown15[i]
|
|
offset++
|
|
}
|
|
|
|
return offset
|
|
}
|
|
|
|
// Size returns the serialized size of the packet
|
|
func (p *CharSelectProfileV562) Size() uint32 {
|
|
size := uint32(0)
|
|
|
|
size += 4
|
|
|
|
size += 4
|
|
|
|
size += 4
|
|
|
|
size += 2 + uint32(len(p.Name))
|
|
|
|
size += 1
|
|
|
|
size += 1
|
|
|
|
size += 1
|
|
|
|
size += 1
|
|
|
|
size += 4
|
|
|
|
size += 2 + uint32(len(p.Zone))
|
|
|
|
size += 4
|
|
|
|
size += 4
|
|
|
|
size += 4
|
|
|
|
size += 4
|
|
|
|
size += 4
|
|
|
|
size += 4
|
|
|
|
size += 2 + uint32(len(p.Zonename2))
|
|
|
|
size += 2 + uint32(len(p.Zonedesc))
|
|
|
|
size += 4
|
|
|
|
size += 2 + uint32(len(p.ServerName))
|
|
|
|
size += 4
|
|
|
|
size += 2
|
|
|
|
size += 4
|
|
|
|
size += 1
|
|
|
|
size += 2
|
|
|
|
size += 4
|
|
|
|
size += 4
|
|
|
|
size += 25 * 6
|
|
|
|
size += 2
|
|
|
|
size += 4
|
|
|
|
size += 4
|
|
|
|
size += 2
|
|
|
|
size += 4
|
|
|
|
size += 4
|
|
|
|
size += 2
|
|
|
|
size += 4
|
|
|
|
size += 4
|
|
|
|
size += 2
|
|
|
|
size += 4
|
|
|
|
size += 4
|
|
|
|
size += 4
|
|
|
|
size += 3
|
|
|
|
size += 3
|
|
|
|
size += 3
|
|
|
|
size += 3
|
|
|
|
size += 3
|
|
|
|
size += 3
|
|
|
|
size += 3
|
|
|
|
size += 1
|
|
|
|
size += 9
|
|
|
|
size += 4
|
|
|
|
size += 4
|
|
|
|
size += 13
|
|
|
|
size += 7
|
|
|
|
return size
|
|
}
|
|
|
|
// CharSelectProfileV887 represents packet structure for client version 887
|
|
type CharSelectProfileV887 struct {
|
|
Version uint32 `eq2:"version"`
|
|
Charid uint32 `eq2:"charid"`
|
|
ServerId uint32 `eq2:"server_id"`
|
|
Name string `eq2:"name,type:str16"`
|
|
Unknown uint8 `eq2:"unknown"` // TODO: Identify purpose
|
|
Race uint8 `eq2:"race"`
|
|
Class uint8 `eq2:"class"`
|
|
Gender uint8 `eq2:"gender"`
|
|
Level uint32 `eq2:"level"`
|
|
Zone string `eq2:"zone,type:str16"`
|
|
Unknown1 uint32 `eq2:"unknown1"` // TODO: Identify purpose
|
|
Unknown2 uint32 `eq2:"unknown2"` // TODO: Identify purpose
|
|
CreatedDate uint32 `eq2:"created_date"`
|
|
LastPlayed uint32 `eq2:"last_played"`
|
|
Unknown3 uint32 `eq2:"unknown3"` // TODO: Identify purpose
|
|
Unknown4 uint32 `eq2:"unknown4"` // TODO: Identify purpose
|
|
Zonename2 string `eq2:"zonename2,type:str16"`
|
|
Zonedesc string `eq2:"zonedesc,type:str16"`
|
|
Unknown5 uint32 `eq2:"unknown5"` // TODO: Identify purpose
|
|
ServerName string `eq2:"server_name,type:str16"`
|
|
AccountId uint32 `eq2:"account_id"`
|
|
Unknown6 [2]uint8 `eq2:"unknown6,size:2"` // TODO: Identify purpose
|
|
Unknown7 uint32 `eq2:"unknown7"` // TODO: Identify purpose
|
|
TradeskillClass uint8 `eq2:"tradeskill_class"`
|
|
TradeskillLevel uint32 `eq2:"tradeskill_level"`
|
|
Unknown8 uint8 `eq2:"unknown8"` // TODO: Identify purpose
|
|
RaceType uint16 `eq2:"race_type"`
|
|
SkinColor types.Color `eq2:"skin_color"`
|
|
EyeColor types.Color `eq2:"eye_color"`
|
|
Equip [25]types.EquipmentItem `eq2:"equip,size:25"`
|
|
HairType uint16 `eq2:"hair_type"`
|
|
HairTypeColor types.Color `eq2:"hair_type_color"`
|
|
HairTypeHighlightColor types.Color `eq2:"hair_type_highlight_color"`
|
|
HairFaceType uint16 `eq2:"hair_face_type"`
|
|
HairFaceColor types.Color `eq2:"hair_face_color"`
|
|
HairFaceHighlightColor types.Color `eq2:"hair_face_highlight_color"`
|
|
WingType uint16 `eq2:"wing_type"`
|
|
WingColor1 types.Color `eq2:"wing_color1"`
|
|
WingColor2 types.Color `eq2:"wing_color2"`
|
|
ChestType uint16 `eq2:"chest_type"`
|
|
ShirtColor types.Color `eq2:"shirt_color"`
|
|
UnknownChestColor types.Color `eq2:"unknown_chest_color"` // TODO: Identify purpose
|
|
LegsType uint16 `eq2:"legs_type"`
|
|
PantsColor types.Color `eq2:"pants_color"`
|
|
UnknownLegsColor types.Color `eq2:"unknown_legs_color"` // TODO: Identify purpose
|
|
Unknown9 types.Color `eq2:"unknown9"` // TODO: Identify purpose
|
|
EyeType [3]int8 `eq2:"eye_type,size:3"`
|
|
EarType [3]int8 `eq2:"ear_type,size:3"`
|
|
EyeBrowType [3]int8 `eq2:"eye_brow_type,size:3"`
|
|
CheekType [3]int8 `eq2:"cheek_type,size:3"`
|
|
LipType [3]int8 `eq2:"lip_type,size:3"`
|
|
ChinType [3]int8 `eq2:"chin_type,size:3"`
|
|
NoseType [3]int8 `eq2:"nose_type,size:3"`
|
|
BodySize int8 `eq2:"body_size"`
|
|
Unknown10 [9]uint8 `eq2:"unknown10,size:9"` // TODO: Identify purpose
|
|
HairColor1 types.Color `eq2:"hair_color1"`
|
|
HairColor2 types.Color `eq2:"hair_color2"`
|
|
Unknown11 [13]uint8 `eq2:"unknown11,size:13"` // TODO: Identify purpose
|
|
SogaRaceType uint16 `eq2:"soga_race_type"`
|
|
SogaSkinColor types.Color `eq2:"soga_skin_color"`
|
|
SogaEyeColor types.Color `eq2:"soga_eye_color"`
|
|
Unknown12 [3]uint8 `eq2:"Unknown12,size:3"` // TODO: Identify purpose
|
|
SogaEyeType [3]int8 `eq2:"soga_eye_type,size:3"`
|
|
SogaEarType [3]int8 `eq2:"soga_ear_type,size:3"`
|
|
SogaEyeBrowType [3]int8 `eq2:"soga_eye_brow_type,size:3"`
|
|
SogaCheekType [3]int8 `eq2:"soga_cheek_type,size:3"`
|
|
SogaLipType [3]int8 `eq2:"soga_lip_type,size:3"`
|
|
SogaChinType [3]int8 `eq2:"soga_chin_type,size:3"`
|
|
SogaNoseType [3]int8 `eq2:"soga_nose_type,size:3"`
|
|
Unknown13 uint16 `eq2:"unknown13"` // TODO: Identify purpose
|
|
SogaHairColor1 types.Color `eq2:"soga_hair_color1"`
|
|
SogaHairColor2 types.Color `eq2:"soga_hair_color2"`
|
|
Unknown14 types.Color `eq2:"unknown14"` // TODO: Identify purpose
|
|
SogaHairType uint16 `eq2:"soga_hair_type"`
|
|
SogaHairTypeColor types.Color `eq2:"soga_hair_type_color"`
|
|
SogaHairTypeHighlightColor types.Color `eq2:"soga_hair_type_highlight_color"`
|
|
SogaHairFaceType uint16 `eq2:"soga_hair_face_type"`
|
|
SogaHairFaceColor types.Color `eq2:"soga_hair_face_color"`
|
|
SogaHairFaceHighlightColor types.Color `eq2:"soga_hair_face_highlight_color"`
|
|
Unknown15 [7]uint8 `eq2:"unknown15,size:7"` // TODO: Identify purpose
|
|
}
|
|
|
|
// Serialize writes the packet data to the provided buffer
|
|
func (p *CharSelectProfileV887) Serialize(dest []byte) uint32 {
|
|
offset := uint32(0)
|
|
|
|
// Write Version
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.Version))
|
|
offset += 4
|
|
|
|
// Write Charid
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.Charid))
|
|
offset += 4
|
|
|
|
// Write ServerId
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.ServerId))
|
|
offset += 4
|
|
|
|
// Write Name as 16-bit length-prefixed string
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(len(p.Name)))
|
|
offset += 2
|
|
copy(dest[offset:], []byte(p.Name))
|
|
offset += uint32(len(p.Name))
|
|
|
|
// Write Unknown
|
|
dest[offset] = byte(p.Unknown)
|
|
offset++
|
|
|
|
// Write Race
|
|
dest[offset] = byte(p.Race)
|
|
offset++
|
|
|
|
// Write Class
|
|
dest[offset] = byte(p.Class)
|
|
offset++
|
|
|
|
// Write Gender
|
|
dest[offset] = byte(p.Gender)
|
|
offset++
|
|
|
|
// Write Level
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.Level))
|
|
offset += 4
|
|
|
|
// Write Zone as 16-bit length-prefixed string
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(len(p.Zone)))
|
|
offset += 2
|
|
copy(dest[offset:], []byte(p.Zone))
|
|
offset += uint32(len(p.Zone))
|
|
|
|
// Write Unknown1
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.Unknown1))
|
|
offset += 4
|
|
|
|
// Write Unknown2
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.Unknown2))
|
|
offset += 4
|
|
|
|
// Write CreatedDate
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.CreatedDate))
|
|
offset += 4
|
|
|
|
// Write LastPlayed
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.LastPlayed))
|
|
offset += 4
|
|
|
|
// Write Unknown3
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.Unknown3))
|
|
offset += 4
|
|
|
|
// Write Unknown4
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.Unknown4))
|
|
offset += 4
|
|
|
|
// Write Zonename2 as 16-bit length-prefixed string
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(len(p.Zonename2)))
|
|
offset += 2
|
|
copy(dest[offset:], []byte(p.Zonename2))
|
|
offset += uint32(len(p.Zonename2))
|
|
|
|
// Write Zonedesc as 16-bit length-prefixed string
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(len(p.Zonedesc)))
|
|
offset += 2
|
|
copy(dest[offset:], []byte(p.Zonedesc))
|
|
offset += uint32(len(p.Zonedesc))
|
|
|
|
// Write Unknown5
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.Unknown5))
|
|
offset += 4
|
|
|
|
// Write ServerName as 16-bit length-prefixed string
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(len(p.ServerName)))
|
|
offset += 2
|
|
copy(dest[offset:], []byte(p.ServerName))
|
|
offset += uint32(len(p.ServerName))
|
|
|
|
// Write AccountId
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.AccountId))
|
|
offset += 4
|
|
|
|
// Write Unknown6 array
|
|
for i := 0; i < 2; i++ {
|
|
dest[offset] = p.Unknown6[i]
|
|
offset++
|
|
}
|
|
|
|
// Write Unknown7
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.Unknown7))
|
|
offset += 4
|
|
|
|
// Write TradeskillClass
|
|
dest[offset] = byte(p.TradeskillClass)
|
|
offset++
|
|
|
|
// Write TradeskillLevel
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.TradeskillLevel))
|
|
offset += 4
|
|
|
|
// Write Unknown8
|
|
dest[offset] = byte(p.Unknown8)
|
|
offset++
|
|
|
|
// Write RaceType
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(p.RaceType))
|
|
offset += 2
|
|
|
|
// Write SkinColor
|
|
binary.LittleEndian.PutUint32(dest[offset:], p.SkinColor.ToUint32())
|
|
offset += 4
|
|
|
|
// Write EyeColor
|
|
binary.LittleEndian.PutUint32(dest[offset:], p.EyeColor.ToUint32())
|
|
offset += 4
|
|
|
|
// Write Equip array
|
|
for i := 0; i < 25; i++ {
|
|
binary.LittleEndian.PutUint16(dest[offset:], p.Equip[i].Type)
|
|
offset += 2
|
|
binary.LittleEndian.PutUint32(dest[offset:], p.Equip[i].Color.ToUint32())
|
|
offset += 4
|
|
}
|
|
|
|
// Write HairType
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(p.HairType))
|
|
offset += 2
|
|
|
|
// Write HairTypeColor
|
|
binary.LittleEndian.PutUint32(dest[offset:], p.HairTypeColor.ToUint32())
|
|
offset += 4
|
|
|
|
// Write HairTypeHighlightColor
|
|
binary.LittleEndian.PutUint32(dest[offset:], p.HairTypeHighlightColor.ToUint32())
|
|
offset += 4
|
|
|
|
// Write HairFaceType
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(p.HairFaceType))
|
|
offset += 2
|
|
|
|
// Write HairFaceColor
|
|
binary.LittleEndian.PutUint32(dest[offset:], p.HairFaceColor.ToUint32())
|
|
offset += 4
|
|
|
|
// Write HairFaceHighlightColor
|
|
binary.LittleEndian.PutUint32(dest[offset:], p.HairFaceHighlightColor.ToUint32())
|
|
offset += 4
|
|
|
|
// Write WingType
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(p.WingType))
|
|
offset += 2
|
|
|
|
// Write WingColor1
|
|
binary.LittleEndian.PutUint32(dest[offset:], p.WingColor1.ToUint32())
|
|
offset += 4
|
|
|
|
// Write WingColor2
|
|
binary.LittleEndian.PutUint32(dest[offset:], p.WingColor2.ToUint32())
|
|
offset += 4
|
|
|
|
// Write ChestType
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(p.ChestType))
|
|
offset += 2
|
|
|
|
// Write ShirtColor
|
|
binary.LittleEndian.PutUint32(dest[offset:], p.ShirtColor.ToUint32())
|
|
offset += 4
|
|
|
|
// Write UnknownChestColor
|
|
binary.LittleEndian.PutUint32(dest[offset:], p.UnknownChestColor.ToUint32())
|
|
offset += 4
|
|
|
|
// Write LegsType
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(p.LegsType))
|
|
offset += 2
|
|
|
|
// Write PantsColor
|
|
binary.LittleEndian.PutUint32(dest[offset:], p.PantsColor.ToUint32())
|
|
offset += 4
|
|
|
|
// Write UnknownLegsColor
|
|
binary.LittleEndian.PutUint32(dest[offset:], p.UnknownLegsColor.ToUint32())
|
|
offset += 4
|
|
|
|
// Write Unknown9
|
|
binary.LittleEndian.PutUint32(dest[offset:], p.Unknown9.ToUint32())
|
|
offset += 4
|
|
|
|
// Write EyeType array
|
|
for i := 0; i < 3; i++ {
|
|
dest[offset] = byte(p.EyeType[i])
|
|
offset++
|
|
}
|
|
|
|
// Write EarType array
|
|
for i := 0; i < 3; i++ {
|
|
dest[offset] = byte(p.EarType[i])
|
|
offset++
|
|
}
|
|
|
|
// Write EyeBrowType array
|
|
for i := 0; i < 3; i++ {
|
|
dest[offset] = byte(p.EyeBrowType[i])
|
|
offset++
|
|
}
|
|
|
|
// Write CheekType array
|
|
for i := 0; i < 3; i++ {
|
|
dest[offset] = byte(p.CheekType[i])
|
|
offset++
|
|
}
|
|
|
|
// Write LipType array
|
|
for i := 0; i < 3; i++ {
|
|
dest[offset] = byte(p.LipType[i])
|
|
offset++
|
|
}
|
|
|
|
// Write ChinType array
|
|
for i := 0; i < 3; i++ {
|
|
dest[offset] = byte(p.ChinType[i])
|
|
offset++
|
|
}
|
|
|
|
// Write NoseType array
|
|
for i := 0; i < 3; i++ {
|
|
dest[offset] = byte(p.NoseType[i])
|
|
offset++
|
|
}
|
|
|
|
// Write BodySize
|
|
dest[offset] = byte(p.BodySize)
|
|
offset++
|
|
|
|
// Write Unknown10 array
|
|
for i := 0; i < 9; i++ {
|
|
dest[offset] = p.Unknown10[i]
|
|
offset++
|
|
}
|
|
|
|
// Write HairColor1
|
|
binary.LittleEndian.PutUint32(dest[offset:], p.HairColor1.ToUint32())
|
|
offset += 4
|
|
|
|
// Write HairColor2
|
|
binary.LittleEndian.PutUint32(dest[offset:], p.HairColor2.ToUint32())
|
|
offset += 4
|
|
|
|
// Write Unknown11 array
|
|
for i := 0; i < 13; i++ {
|
|
dest[offset] = p.Unknown11[i]
|
|
offset++
|
|
}
|
|
|
|
// Write SogaRaceType
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(p.SogaRaceType))
|
|
offset += 2
|
|
|
|
// Write SogaSkinColor
|
|
binary.LittleEndian.PutUint32(dest[offset:], p.SogaSkinColor.ToUint32())
|
|
offset += 4
|
|
|
|
// Write SogaEyeColor
|
|
binary.LittleEndian.PutUint32(dest[offset:], p.SogaEyeColor.ToUint32())
|
|
offset += 4
|
|
|
|
// Write Unknown12 array
|
|
for i := 0; i < 3; i++ {
|
|
dest[offset] = p.Unknown12[i]
|
|
offset++
|
|
}
|
|
|
|
// Write SogaEyeType array
|
|
for i := 0; i < 3; i++ {
|
|
dest[offset] = byte(p.SogaEyeType[i])
|
|
offset++
|
|
}
|
|
|
|
// Write SogaEarType array
|
|
for i := 0; i < 3; i++ {
|
|
dest[offset] = byte(p.SogaEarType[i])
|
|
offset++
|
|
}
|
|
|
|
// Write SogaEyeBrowType array
|
|
for i := 0; i < 3; i++ {
|
|
dest[offset] = byte(p.SogaEyeBrowType[i])
|
|
offset++
|
|
}
|
|
|
|
// Write SogaCheekType array
|
|
for i := 0; i < 3; i++ {
|
|
dest[offset] = byte(p.SogaCheekType[i])
|
|
offset++
|
|
}
|
|
|
|
// Write SogaLipType array
|
|
for i := 0; i < 3; i++ {
|
|
dest[offset] = byte(p.SogaLipType[i])
|
|
offset++
|
|
}
|
|
|
|
// Write SogaChinType array
|
|
for i := 0; i < 3; i++ {
|
|
dest[offset] = byte(p.SogaChinType[i])
|
|
offset++
|
|
}
|
|
|
|
// Write SogaNoseType array
|
|
for i := 0; i < 3; i++ {
|
|
dest[offset] = byte(p.SogaNoseType[i])
|
|
offset++
|
|
}
|
|
|
|
// Write Unknown13
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(p.Unknown13))
|
|
offset += 2
|
|
|
|
// Write SogaHairColor1
|
|
binary.LittleEndian.PutUint32(dest[offset:], p.SogaHairColor1.ToUint32())
|
|
offset += 4
|
|
|
|
// Write SogaHairColor2
|
|
binary.LittleEndian.PutUint32(dest[offset:], p.SogaHairColor2.ToUint32())
|
|
offset += 4
|
|
|
|
// Write Unknown14
|
|
binary.LittleEndian.PutUint32(dest[offset:], p.Unknown14.ToUint32())
|
|
offset += 4
|
|
|
|
// Write SogaHairType
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(p.SogaHairType))
|
|
offset += 2
|
|
|
|
// Write SogaHairTypeColor
|
|
binary.LittleEndian.PutUint32(dest[offset:], p.SogaHairTypeColor.ToUint32())
|
|
offset += 4
|
|
|
|
// Write SogaHairTypeHighlightColor
|
|
binary.LittleEndian.PutUint32(dest[offset:], p.SogaHairTypeHighlightColor.ToUint32())
|
|
offset += 4
|
|
|
|
// Write SogaHairFaceType
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(p.SogaHairFaceType))
|
|
offset += 2
|
|
|
|
// Write SogaHairFaceColor
|
|
binary.LittleEndian.PutUint32(dest[offset:], p.SogaHairFaceColor.ToUint32())
|
|
offset += 4
|
|
|
|
// Write SogaHairFaceHighlightColor
|
|
binary.LittleEndian.PutUint32(dest[offset:], p.SogaHairFaceHighlightColor.ToUint32())
|
|
offset += 4
|
|
|
|
// Write Unknown15 array
|
|
for i := 0; i < 7; i++ {
|
|
dest[offset] = p.Unknown15[i]
|
|
offset++
|
|
}
|
|
|
|
return offset
|
|
}
|
|
|
|
// Size returns the serialized size of the packet
|
|
func (p *CharSelectProfileV887) Size() uint32 {
|
|
size := uint32(0)
|
|
|
|
size += 4
|
|
|
|
size += 4
|
|
|
|
size += 4
|
|
|
|
size += 2 + uint32(len(p.Name))
|
|
|
|
size += 1
|
|
|
|
size += 1
|
|
|
|
size += 1
|
|
|
|
size += 1
|
|
|
|
size += 4
|
|
|
|
size += 2 + uint32(len(p.Zone))
|
|
|
|
size += 4
|
|
|
|
size += 4
|
|
|
|
size += 4
|
|
|
|
size += 4
|
|
|
|
size += 4
|
|
|
|
size += 4
|
|
|
|
size += 2 + uint32(len(p.Zonename2))
|
|
|
|
size += 2 + uint32(len(p.Zonedesc))
|
|
|
|
size += 4
|
|
|
|
size += 2 + uint32(len(p.ServerName))
|
|
|
|
size += 4
|
|
|
|
size += 2
|
|
|
|
size += 4
|
|
|
|
size += 1
|
|
|
|
size += 4
|
|
|
|
size += 1
|
|
|
|
size += 2
|
|
|
|
size += 4
|
|
|
|
size += 4
|
|
|
|
size += 25 * 6
|
|
|
|
size += 2
|
|
|
|
size += 4
|
|
|
|
size += 4
|
|
|
|
size += 2
|
|
|
|
size += 4
|
|
|
|
size += 4
|
|
|
|
size += 2
|
|
|
|
size += 4
|
|
|
|
size += 4
|
|
|
|
size += 2
|
|
|
|
size += 4
|
|
|
|
size += 4
|
|
|
|
size += 2
|
|
|
|
size += 4
|
|
|
|
size += 4
|
|
|
|
size += 4
|
|
|
|
size += 3
|
|
|
|
size += 3
|
|
|
|
size += 3
|
|
|
|
size += 3
|
|
|
|
size += 3
|
|
|
|
size += 3
|
|
|
|
size += 3
|
|
|
|
size += 1
|
|
|
|
size += 9
|
|
|
|
size += 4
|
|
|
|
size += 4
|
|
|
|
size += 13
|
|
|
|
size += 2
|
|
|
|
size += 4
|
|
|
|
size += 4
|
|
|
|
size += 3
|
|
|
|
size += 3
|
|
|
|
size += 3
|
|
|
|
size += 3
|
|
|
|
size += 3
|
|
|
|
size += 3
|
|
|
|
size += 3
|
|
|
|
size += 3
|
|
|
|
size += 2
|
|
|
|
size += 4
|
|
|
|
size += 4
|
|
|
|
size += 4
|
|
|
|
size += 2
|
|
|
|
size += 4
|
|
|
|
size += 4
|
|
|
|
size += 2
|
|
|
|
size += 4
|
|
|
|
size += 4
|
|
|
|
size += 7
|
|
|
|
return size
|
|
}
|
|
|
|
// CharSelectProfileV60085 represents packet structure for client version 60085
|
|
type CharSelectProfileV60085 struct {
|
|
Version uint32 `eq2:"version"`
|
|
Charid uint32 `eq2:"charid"`
|
|
ServerId uint32 `eq2:"server_id"`
|
|
Name string `eq2:"name,type:str16"`
|
|
Unknown uint8 `eq2:"unknown"` // TODO: Identify purpose
|
|
Race uint8 `eq2:"race"`
|
|
Class uint8 `eq2:"class"`
|
|
Gender uint8 `eq2:"gender"`
|
|
Level uint32 `eq2:"level"`
|
|
Zone string `eq2:"zone,type:str16"`
|
|
Unknown1 uint32 `eq2:"unknown1"` // TODO: Identify purpose
|
|
Unknown2 uint32 `eq2:"unknown2"` // TODO: Identify purpose
|
|
CreatedDate uint32 `eq2:"created_date"`
|
|
LastPlayed uint32 `eq2:"last_played"`
|
|
Unknown3 uint32 `eq2:"unknown3"` // TODO: Identify purpose
|
|
Unknown4 uint32 `eq2:"unknown4"` // TODO: Identify purpose
|
|
Zonename2 string `eq2:"zonename2,type:str16"`
|
|
Zonedesc string `eq2:"zonedesc,type:str16"`
|
|
Unknown5 uint32 `eq2:"unknown5"` // TODO: Identify purpose
|
|
ServerName string `eq2:"server_name,type:str16"`
|
|
AccountId uint32 `eq2:"account_id"`
|
|
Unknown6 [2]uint8 `eq2:"unknown6,size:2"` // TODO: Identify purpose
|
|
Unknown7 uint32 `eq2:"unknown7"` // TODO: Identify purpose
|
|
TradeskillClass uint8 `eq2:"tradeskill_class"`
|
|
TradeskillLevel uint32 `eq2:"tradeskill_level"`
|
|
Unknown8 uint8 `eq2:"unknown8"` // TODO: Identify purpose
|
|
RaceType uint16 `eq2:"race_type"`
|
|
SkinColor types.Color `eq2:"skin_color"`
|
|
EyeColor types.Color `eq2:"eye_color"`
|
|
Equip [25]types.EquipmentItem `eq2:"equip,size:25"`
|
|
HairType uint16 `eq2:"hair_type"`
|
|
HairTypeColor types.Color `eq2:"hair_type_color"`
|
|
HairTypeHighlightColor types.Color `eq2:"hair_type_highlight_color"`
|
|
HairFaceType uint16 `eq2:"hair_face_type"`
|
|
HairFaceColor types.Color `eq2:"hair_face_color"`
|
|
HairFaceHighlightColor types.Color `eq2:"hair_face_highlight_color"`
|
|
WingType uint16 `eq2:"wing_type"`
|
|
WingColor1 types.Color `eq2:"wing_color1"`
|
|
WingColor2 types.Color `eq2:"wing_color2"`
|
|
ChestType uint16 `eq2:"chest_type"`
|
|
ShirtColor types.Color `eq2:"shirt_color"`
|
|
UnknownChestColor types.Color `eq2:"unknown_chest_color"` // TODO: Identify purpose
|
|
LegsType uint16 `eq2:"legs_type"`
|
|
PantsColor types.Color `eq2:"pants_color"`
|
|
UnknownLegsColor types.Color `eq2:"unknown_legs_color"` // TODO: Identify purpose
|
|
Unknown9 types.Color `eq2:"unknown9"` // TODO: Identify purpose
|
|
EyeType [3]int8 `eq2:"eye_type,size:3"`
|
|
EarType [3]int8 `eq2:"ear_type,size:3"`
|
|
EyeBrowType [3]int8 `eq2:"eye_brow_type,size:3"`
|
|
CheekType [3]int8 `eq2:"cheek_type,size:3"`
|
|
LipType [3]int8 `eq2:"lip_type,size:3"`
|
|
ChinType [3]int8 `eq2:"chin_type,size:3"`
|
|
NoseType [3]int8 `eq2:"nose_type,size:3"`
|
|
BodySize int8 `eq2:"body_size"`
|
|
Unknown10 [9]uint8 `eq2:"unknown10,size:9"` // TODO: Identify purpose
|
|
HairColor1 types.Color `eq2:"hair_color1"`
|
|
HairColor2 types.Color `eq2:"hair_color2"`
|
|
Unknown11 [13]uint8 `eq2:"unknown11,size:13"` // TODO: Identify purpose
|
|
SogaRaceType uint16 `eq2:"soga_race_type"`
|
|
SogaSkinColor types.Color `eq2:"soga_skin_color"`
|
|
SogaEyeColor types.Color `eq2:"soga_eye_color"`
|
|
Unknown12 [3]uint8 `eq2:"Unknown12,size:3"` // TODO: Identify purpose
|
|
SogaEyeType [3]int8 `eq2:"soga_eye_type,size:3"`
|
|
SogaEarType [3]int8 `eq2:"soga_ear_type,size:3"`
|
|
SogaEyeBrowType [3]int8 `eq2:"soga_eye_brow_type,size:3"`
|
|
SogaCheekType [3]int8 `eq2:"soga_cheek_type,size:3"`
|
|
SogaLipType [3]int8 `eq2:"soga_lip_type,size:3"`
|
|
SogaChinType [3]int8 `eq2:"soga_chin_type,size:3"`
|
|
SogaNoseType [3]int8 `eq2:"soga_nose_type,size:3"`
|
|
Unknown13 uint16 `eq2:"unknown13"` // TODO: Identify purpose
|
|
SogaHairColor1 types.Color `eq2:"soga_hair_color1"`
|
|
SogaHairColor2 types.Color `eq2:"soga_hair_color2"`
|
|
Unknown14 types.Color `eq2:"unknown14"` // TODO: Identify purpose
|
|
SogaHairType uint16 `eq2:"soga_hair_type"`
|
|
SogaHairTypeColor types.Color `eq2:"soga_hair_type_color"`
|
|
SogaHairTypeHighlightColor types.Color `eq2:"soga_hair_type_highlight_color"`
|
|
SogaHairFaceType uint16 `eq2:"soga_hair_face_type"`
|
|
SogaHairFaceColor types.Color `eq2:"soga_hair_face_color"`
|
|
SogaHairFaceHighlightColor types.Color `eq2:"soga_hair_face_highlight_color"`
|
|
Unknown15 [7]uint8 `eq2:"unknown15,size:7"` // TODO: Identify purpose
|
|
}
|
|
|
|
// Serialize writes the packet data to the provided buffer
|
|
func (p *CharSelectProfileV60085) Serialize(dest []byte) uint32 {
|
|
offset := uint32(0)
|
|
|
|
// Write Version
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.Version))
|
|
offset += 4
|
|
|
|
// Write Charid
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.Charid))
|
|
offset += 4
|
|
|
|
// Write ServerId
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.ServerId))
|
|
offset += 4
|
|
|
|
// Write Name as 16-bit length-prefixed string
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(len(p.Name)))
|
|
offset += 2
|
|
copy(dest[offset:], []byte(p.Name))
|
|
offset += uint32(len(p.Name))
|
|
|
|
// Write Unknown
|
|
dest[offset] = byte(p.Unknown)
|
|
offset++
|
|
|
|
// Write Race
|
|
dest[offset] = byte(p.Race)
|
|
offset++
|
|
|
|
// Write Class
|
|
dest[offset] = byte(p.Class)
|
|
offset++
|
|
|
|
// Write Gender
|
|
dest[offset] = byte(p.Gender)
|
|
offset++
|
|
|
|
// Write Level
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.Level))
|
|
offset += 4
|
|
|
|
// Write Zone as 16-bit length-prefixed string
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(len(p.Zone)))
|
|
offset += 2
|
|
copy(dest[offset:], []byte(p.Zone))
|
|
offset += uint32(len(p.Zone))
|
|
|
|
// Write Unknown1
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.Unknown1))
|
|
offset += 4
|
|
|
|
// Write Unknown2
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.Unknown2))
|
|
offset += 4
|
|
|
|
// Write CreatedDate
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.CreatedDate))
|
|
offset += 4
|
|
|
|
// Write LastPlayed
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.LastPlayed))
|
|
offset += 4
|
|
|
|
// Write Unknown3
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.Unknown3))
|
|
offset += 4
|
|
|
|
// Write Unknown4
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.Unknown4))
|
|
offset += 4
|
|
|
|
// Write Zonename2 as 16-bit length-prefixed string
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(len(p.Zonename2)))
|
|
offset += 2
|
|
copy(dest[offset:], []byte(p.Zonename2))
|
|
offset += uint32(len(p.Zonename2))
|
|
|
|
// Write Zonedesc as 16-bit length-prefixed string
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(len(p.Zonedesc)))
|
|
offset += 2
|
|
copy(dest[offset:], []byte(p.Zonedesc))
|
|
offset += uint32(len(p.Zonedesc))
|
|
|
|
// Write Unknown5
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.Unknown5))
|
|
offset += 4
|
|
|
|
// Write ServerName as 16-bit length-prefixed string
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(len(p.ServerName)))
|
|
offset += 2
|
|
copy(dest[offset:], []byte(p.ServerName))
|
|
offset += uint32(len(p.ServerName))
|
|
|
|
// Write AccountId
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.AccountId))
|
|
offset += 4
|
|
|
|
// Write Unknown6 array
|
|
for i := 0; i < 2; i++ {
|
|
dest[offset] = p.Unknown6[i]
|
|
offset++
|
|
}
|
|
|
|
// Write Unknown7
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.Unknown7))
|
|
offset += 4
|
|
|
|
// Write TradeskillClass
|
|
dest[offset] = byte(p.TradeskillClass)
|
|
offset++
|
|
|
|
// Write TradeskillLevel
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.TradeskillLevel))
|
|
offset += 4
|
|
|
|
// Write Unknown8
|
|
dest[offset] = byte(p.Unknown8)
|
|
offset++
|
|
|
|
// Write RaceType
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(p.RaceType))
|
|
offset += 2
|
|
|
|
// Write SkinColor
|
|
binary.LittleEndian.PutUint32(dest[offset:], p.SkinColor.ToUint32())
|
|
offset += 4
|
|
|
|
// Write EyeColor
|
|
binary.LittleEndian.PutUint32(dest[offset:], p.EyeColor.ToUint32())
|
|
offset += 4
|
|
|
|
// Write Equip array
|
|
for i := 0; i < 25; i++ {
|
|
binary.LittleEndian.PutUint16(dest[offset:], p.Equip[i].Type)
|
|
offset += 2
|
|
binary.LittleEndian.PutUint32(dest[offset:], p.Equip[i].Color.ToUint32())
|
|
offset += 4
|
|
}
|
|
|
|
// Write HairType
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(p.HairType))
|
|
offset += 2
|
|
|
|
// Write HairTypeColor
|
|
binary.LittleEndian.PutUint32(dest[offset:], p.HairTypeColor.ToUint32())
|
|
offset += 4
|
|
|
|
// Write HairTypeHighlightColor
|
|
binary.LittleEndian.PutUint32(dest[offset:], p.HairTypeHighlightColor.ToUint32())
|
|
offset += 4
|
|
|
|
// Write HairFaceType
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(p.HairFaceType))
|
|
offset += 2
|
|
|
|
// Write HairFaceColor
|
|
binary.LittleEndian.PutUint32(dest[offset:], p.HairFaceColor.ToUint32())
|
|
offset += 4
|
|
|
|
// Write HairFaceHighlightColor
|
|
binary.LittleEndian.PutUint32(dest[offset:], p.HairFaceHighlightColor.ToUint32())
|
|
offset += 4
|
|
|
|
// Write WingType
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(p.WingType))
|
|
offset += 2
|
|
|
|
// Write WingColor1
|
|
binary.LittleEndian.PutUint32(dest[offset:], p.WingColor1.ToUint32())
|
|
offset += 4
|
|
|
|
// Write WingColor2
|
|
binary.LittleEndian.PutUint32(dest[offset:], p.WingColor2.ToUint32())
|
|
offset += 4
|
|
|
|
// Write ChestType
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(p.ChestType))
|
|
offset += 2
|
|
|
|
// Write ShirtColor
|
|
binary.LittleEndian.PutUint32(dest[offset:], p.ShirtColor.ToUint32())
|
|
offset += 4
|
|
|
|
// Write UnknownChestColor
|
|
binary.LittleEndian.PutUint32(dest[offset:], p.UnknownChestColor.ToUint32())
|
|
offset += 4
|
|
|
|
// Write LegsType
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(p.LegsType))
|
|
offset += 2
|
|
|
|
// Write PantsColor
|
|
binary.LittleEndian.PutUint32(dest[offset:], p.PantsColor.ToUint32())
|
|
offset += 4
|
|
|
|
// Write UnknownLegsColor
|
|
binary.LittleEndian.PutUint32(dest[offset:], p.UnknownLegsColor.ToUint32())
|
|
offset += 4
|
|
|
|
// Write Unknown9
|
|
binary.LittleEndian.PutUint32(dest[offset:], p.Unknown9.ToUint32())
|
|
offset += 4
|
|
|
|
// Write EyeType array
|
|
for i := 0; i < 3; i++ {
|
|
dest[offset] = byte(p.EyeType[i])
|
|
offset++
|
|
}
|
|
|
|
// Write EarType array
|
|
for i := 0; i < 3; i++ {
|
|
dest[offset] = byte(p.EarType[i])
|
|
offset++
|
|
}
|
|
|
|
// Write EyeBrowType array
|
|
for i := 0; i < 3; i++ {
|
|
dest[offset] = byte(p.EyeBrowType[i])
|
|
offset++
|
|
}
|
|
|
|
// Write CheekType array
|
|
for i := 0; i < 3; i++ {
|
|
dest[offset] = byte(p.CheekType[i])
|
|
offset++
|
|
}
|
|
|
|
// Write LipType array
|
|
for i := 0; i < 3; i++ {
|
|
dest[offset] = byte(p.LipType[i])
|
|
offset++
|
|
}
|
|
|
|
// Write ChinType array
|
|
for i := 0; i < 3; i++ {
|
|
dest[offset] = byte(p.ChinType[i])
|
|
offset++
|
|
}
|
|
|
|
// Write NoseType array
|
|
for i := 0; i < 3; i++ {
|
|
dest[offset] = byte(p.NoseType[i])
|
|
offset++
|
|
}
|
|
|
|
// Write BodySize
|
|
dest[offset] = byte(p.BodySize)
|
|
offset++
|
|
|
|
// Write Unknown10 array
|
|
for i := 0; i < 9; i++ {
|
|
dest[offset] = p.Unknown10[i]
|
|
offset++
|
|
}
|
|
|
|
// Write HairColor1
|
|
binary.LittleEndian.PutUint32(dest[offset:], p.HairColor1.ToUint32())
|
|
offset += 4
|
|
|
|
// Write HairColor2
|
|
binary.LittleEndian.PutUint32(dest[offset:], p.HairColor2.ToUint32())
|
|
offset += 4
|
|
|
|
// Write Unknown11 array
|
|
for i := 0; i < 13; i++ {
|
|
dest[offset] = p.Unknown11[i]
|
|
offset++
|
|
}
|
|
|
|
// Write SogaRaceType
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(p.SogaRaceType))
|
|
offset += 2
|
|
|
|
// Write SogaSkinColor
|
|
binary.LittleEndian.PutUint32(dest[offset:], p.SogaSkinColor.ToUint32())
|
|
offset += 4
|
|
|
|
// Write SogaEyeColor
|
|
binary.LittleEndian.PutUint32(dest[offset:], p.SogaEyeColor.ToUint32())
|
|
offset += 4
|
|
|
|
// Write Unknown12 array
|
|
for i := 0; i < 3; i++ {
|
|
dest[offset] = p.Unknown12[i]
|
|
offset++
|
|
}
|
|
|
|
// Write SogaEyeType array
|
|
for i := 0; i < 3; i++ {
|
|
dest[offset] = byte(p.SogaEyeType[i])
|
|
offset++
|
|
}
|
|
|
|
// Write SogaEarType array
|
|
for i := 0; i < 3; i++ {
|
|
dest[offset] = byte(p.SogaEarType[i])
|
|
offset++
|
|
}
|
|
|
|
// Write SogaEyeBrowType array
|
|
for i := 0; i < 3; i++ {
|
|
dest[offset] = byte(p.SogaEyeBrowType[i])
|
|
offset++
|
|
}
|
|
|
|
// Write SogaCheekType array
|
|
for i := 0; i < 3; i++ {
|
|
dest[offset] = byte(p.SogaCheekType[i])
|
|
offset++
|
|
}
|
|
|
|
// Write SogaLipType array
|
|
for i := 0; i < 3; i++ {
|
|
dest[offset] = byte(p.SogaLipType[i])
|
|
offset++
|
|
}
|
|
|
|
// Write SogaChinType array
|
|
for i := 0; i < 3; i++ {
|
|
dest[offset] = byte(p.SogaChinType[i])
|
|
offset++
|
|
}
|
|
|
|
// Write SogaNoseType array
|
|
for i := 0; i < 3; i++ {
|
|
dest[offset] = byte(p.SogaNoseType[i])
|
|
offset++
|
|
}
|
|
|
|
// Write Unknown13
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(p.Unknown13))
|
|
offset += 2
|
|
|
|
// Write SogaHairColor1
|
|
binary.LittleEndian.PutUint32(dest[offset:], p.SogaHairColor1.ToUint32())
|
|
offset += 4
|
|
|
|
// Write SogaHairColor2
|
|
binary.LittleEndian.PutUint32(dest[offset:], p.SogaHairColor2.ToUint32())
|
|
offset += 4
|
|
|
|
// Write Unknown14
|
|
binary.LittleEndian.PutUint32(dest[offset:], p.Unknown14.ToUint32())
|
|
offset += 4
|
|
|
|
// Write SogaHairType
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(p.SogaHairType))
|
|
offset += 2
|
|
|
|
// Write SogaHairTypeColor
|
|
binary.LittleEndian.PutUint32(dest[offset:], p.SogaHairTypeColor.ToUint32())
|
|
offset += 4
|
|
|
|
// Write SogaHairTypeHighlightColor
|
|
binary.LittleEndian.PutUint32(dest[offset:], p.SogaHairTypeHighlightColor.ToUint32())
|
|
offset += 4
|
|
|
|
// Write SogaHairFaceType
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(p.SogaHairFaceType))
|
|
offset += 2
|
|
|
|
// Write SogaHairFaceColor
|
|
binary.LittleEndian.PutUint32(dest[offset:], p.SogaHairFaceColor.ToUint32())
|
|
offset += 4
|
|
|
|
// Write SogaHairFaceHighlightColor
|
|
binary.LittleEndian.PutUint32(dest[offset:], p.SogaHairFaceHighlightColor.ToUint32())
|
|
offset += 4
|
|
|
|
// Write Unknown15 array
|
|
for i := 0; i < 7; i++ {
|
|
dest[offset] = p.Unknown15[i]
|
|
offset++
|
|
}
|
|
|
|
return offset
|
|
}
|
|
|
|
// Size returns the serialized size of the packet
|
|
func (p *CharSelectProfileV60085) Size() uint32 {
|
|
size := uint32(0)
|
|
|
|
size += 4
|
|
|
|
size += 4
|
|
|
|
size += 4
|
|
|
|
size += 2 + uint32(len(p.Name))
|
|
|
|
size += 1
|
|
|
|
size += 1
|
|
|
|
size += 1
|
|
|
|
size += 1
|
|
|
|
size += 4
|
|
|
|
size += 2 + uint32(len(p.Zone))
|
|
|
|
size += 4
|
|
|
|
size += 4
|
|
|
|
size += 4
|
|
|
|
size += 4
|
|
|
|
size += 4
|
|
|
|
size += 4
|
|
|
|
size += 2 + uint32(len(p.Zonename2))
|
|
|
|
size += 2 + uint32(len(p.Zonedesc))
|
|
|
|
size += 4
|
|
|
|
size += 2 + uint32(len(p.ServerName))
|
|
|
|
size += 4
|
|
|
|
size += 2
|
|
|
|
size += 4
|
|
|
|
size += 1
|
|
|
|
size += 4
|
|
|
|
size += 1
|
|
|
|
size += 2
|
|
|
|
size += 4
|
|
|
|
size += 4
|
|
|
|
size += 25 * 6
|
|
|
|
size += 2
|
|
|
|
size += 4
|
|
|
|
size += 4
|
|
|
|
size += 2
|
|
|
|
size += 4
|
|
|
|
size += 4
|
|
|
|
size += 2
|
|
|
|
size += 4
|
|
|
|
size += 4
|
|
|
|
size += 2
|
|
|
|
size += 4
|
|
|
|
size += 4
|
|
|
|
size += 2
|
|
|
|
size += 4
|
|
|
|
size += 4
|
|
|
|
size += 4
|
|
|
|
size += 3
|
|
|
|
size += 3
|
|
|
|
size += 3
|
|
|
|
size += 3
|
|
|
|
size += 3
|
|
|
|
size += 3
|
|
|
|
size += 3
|
|
|
|
size += 1
|
|
|
|
size += 9
|
|
|
|
size += 4
|
|
|
|
size += 4
|
|
|
|
size += 13
|
|
|
|
size += 2
|
|
|
|
size += 4
|
|
|
|
size += 4
|
|
|
|
size += 3
|
|
|
|
size += 3
|
|
|
|
size += 3
|
|
|
|
size += 3
|
|
|
|
size += 3
|
|
|
|
size += 3
|
|
|
|
size += 3
|
|
|
|
size += 3
|
|
|
|
size += 2
|
|
|
|
size += 4
|
|
|
|
size += 4
|
|
|
|
size += 4
|
|
|
|
size += 2
|
|
|
|
size += 4
|
|
|
|
size += 4
|
|
|
|
size += 2
|
|
|
|
size += 4
|
|
|
|
size += 4
|
|
|
|
size += 7
|
|
|
|
return size
|
|
}
|
|
|
|
// LSLoginReplyMsg represents packet structure for OP_LoginReplyMsg
|
|
type LSLoginReplyMsg struct {
|
|
LoginResponse uint8 `eq2:"login_response"`
|
|
WorldName string `eq2:"worldName,type:str16"`
|
|
ParentalControlFlag uint8 `eq2:"parental_control_flag"`
|
|
ParentalControlTimer [2]uint32 `eq2:"parental_control_timer,size:2"`
|
|
ParentalControlNext uint32 `eq2:"parental_control_next"`
|
|
AccountId uint32 `eq2:"account_id"`
|
|
}
|
|
|
|
// Serialize writes the packet data to the provided buffer
|
|
func (p *LSLoginReplyMsg) Serialize(dest []byte) uint32 {
|
|
offset := uint32(0)
|
|
|
|
// Write LoginResponse
|
|
dest[offset] = byte(p.LoginResponse)
|
|
offset++
|
|
|
|
// Write WorldName as 16-bit length-prefixed string
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(len(p.WorldName)))
|
|
offset += 2
|
|
copy(dest[offset:], []byte(p.WorldName))
|
|
offset += uint32(len(p.WorldName))
|
|
|
|
// Write ParentalControlFlag
|
|
dest[offset] = byte(p.ParentalControlFlag)
|
|
offset++
|
|
|
|
// Write ParentalControlTimer array
|
|
for i := 0; i < 2; i++ {
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.ParentalControlTimer[i]))
|
|
offset += 4
|
|
}
|
|
|
|
// Write ParentalControlNext
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.ParentalControlNext))
|
|
offset += 4
|
|
|
|
// Write AccountId
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.AccountId))
|
|
offset += 4
|
|
|
|
return offset
|
|
}
|
|
|
|
// Size returns the serialized size of the packet
|
|
func (p *LSLoginReplyMsg) Size() uint32 {
|
|
size := uint32(0)
|
|
|
|
size += 1
|
|
|
|
size += 2 + uint32(len(p.WorldName))
|
|
|
|
size += 1
|
|
|
|
size += 2 * 4
|
|
|
|
size += 4
|
|
|
|
size += 4
|
|
|
|
return size
|
|
}
|
|
|
|
// LSLoginReplyMsgV284 represents packet structure for OP_LoginReplyMsg
|
|
type LSLoginReplyMsgV284 struct {
|
|
LoginResponse uint8 `eq2:"login_response"`
|
|
Unknown string `eq2:"unknown,type:str16"` // TODO: Identify purpose
|
|
ParentalControlFlag uint8 `eq2:"parental_control_flag"`
|
|
ParentalControlTimer uint32 `eq2:"parental_control_timer"`
|
|
Unknown2 [8]uint8 `eq2:"unknown2,size:8"` // TODO: Identify purpose
|
|
CacheSettingAccountId uint32 `eq2:"cache_setting_account_id"`
|
|
Unknown3 string `eq2:"unknown3,type:str16"` // TODO: Identify purpose
|
|
ResetAppearance uint8 `eq2:"reset_appearance"`
|
|
DoNotForceSoga uint8 `eq2:"do_not_force_soga"`
|
|
Unknown5 uint16 `eq2:"unknown5"` // TODO: Identify purpose
|
|
Unknown6 uint8 `eq2:"unknown6"` // TODO: Identify purpose
|
|
Unknown7 uint32 `eq2:"unknown7"` // TODO: Identify purpose
|
|
Unknown8 [2]uint8 `eq2:"unknown8,size:2"` // TODO: Identify purpose
|
|
Unknown10 uint8 `eq2:"unknown10"` // TODO: Identify purpose
|
|
NumClassItems uint8 `eq2:"num_class_items,ifSet:unknown10"`
|
|
ClassItems []struct {
|
|
ClassId uint8 `eq2:"class_id"`
|
|
NumItems uint8 `eq2:"num_items"`
|
|
StartingItems []struct {
|
|
ModelId uint16 `eq2:"model_id"`
|
|
SlotId uint8 `eq2:"slot_id"`
|
|
UseColor uint8 `eq2:"use_color"`
|
|
UseHighlightColor uint8 `eq2:"use_highlight_color"`
|
|
ModelColor types.Color `eq2:"model_color"`
|
|
ModelHighlightColor types.Color `eq2:"model_highlight_color"`
|
|
} `eq2:"starting_items"`
|
|
} `eq2:"class_items,sizeVar:num_class_items,ifSet:unknown10"`
|
|
UnknownArray2Size uint8 `eq2:"unknown_array2_size"` // TODO: Identify purpose
|
|
UnknownArray2 []struct {
|
|
Array2Unknown uint32 `eq2:"array2_unknown"`
|
|
} `eq2:"unknown_array2,sizeVar:unknown_array2_size"`
|
|
}
|
|
|
|
// Serialize writes the packet data to the provided buffer
|
|
func (p *LSLoginReplyMsgV284) Serialize(dest []byte) uint32 {
|
|
offset := uint32(0)
|
|
|
|
// Write LoginResponse
|
|
dest[offset] = byte(p.LoginResponse)
|
|
offset++
|
|
|
|
// Write Unknown as 16-bit length-prefixed string
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(len(p.Unknown)))
|
|
offset += 2
|
|
copy(dest[offset:], []byte(p.Unknown))
|
|
offset += uint32(len(p.Unknown))
|
|
|
|
// Write ParentalControlFlag
|
|
dest[offset] = byte(p.ParentalControlFlag)
|
|
offset++
|
|
|
|
// Write ParentalControlTimer
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.ParentalControlTimer))
|
|
offset += 4
|
|
|
|
// Write Unknown2 array
|
|
for i := 0; i < 8; i++ {
|
|
dest[offset] = p.Unknown2[i]
|
|
offset++
|
|
}
|
|
|
|
// Write CacheSettingAccountId
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.CacheSettingAccountId))
|
|
offset += 4
|
|
|
|
// Write Unknown3 as 16-bit length-prefixed string
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(len(p.Unknown3)))
|
|
offset += 2
|
|
copy(dest[offset:], []byte(p.Unknown3))
|
|
offset += uint32(len(p.Unknown3))
|
|
|
|
// Write ResetAppearance
|
|
dest[offset] = byte(p.ResetAppearance)
|
|
offset++
|
|
|
|
// Write DoNotForceSoga
|
|
dest[offset] = byte(p.DoNotForceSoga)
|
|
offset++
|
|
|
|
// Write Unknown5
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(p.Unknown5))
|
|
offset += 2
|
|
|
|
// Write Unknown6
|
|
dest[offset] = byte(p.Unknown6)
|
|
offset++
|
|
|
|
// Write Unknown7
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.Unknown7))
|
|
offset += 4
|
|
|
|
// Write Unknown8 array
|
|
for i := 0; i < 2; i++ {
|
|
dest[offset] = p.Unknown8[i]
|
|
offset++
|
|
}
|
|
|
|
// Write Unknown10
|
|
dest[offset] = byte(p.Unknown10)
|
|
offset++
|
|
|
|
// Write NumClassItems
|
|
dest[offset] = byte(p.NumClassItems)
|
|
offset++
|
|
|
|
// Write ClassItems array (dynamic size)
|
|
for _, elem := range p.ClassItems {
|
|
dest[offset] = elem.ClassId
|
|
offset++
|
|
dest[offset] = elem.NumItems
|
|
offset++
|
|
// Write nested StartingItems array
|
|
for _, nestedElem := range elem.StartingItems {
|
|
binary.LittleEndian.PutUint16(dest[offset:], nestedElem.ModelId)
|
|
offset += 2
|
|
dest[offset] = nestedElem.SlotId
|
|
offset++
|
|
dest[offset] = nestedElem.UseColor
|
|
offset++
|
|
dest[offset] = nestedElem.UseHighlightColor
|
|
offset++
|
|
binary.LittleEndian.PutUint32(dest[offset:], nestedElem.ModelColor.ToUint32())
|
|
offset += 4
|
|
binary.LittleEndian.PutUint32(dest[offset:], nestedElem.ModelHighlightColor.ToUint32())
|
|
offset += 4
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// Write UnknownArray2Size
|
|
dest[offset] = byte(p.UnknownArray2Size)
|
|
offset++
|
|
|
|
// Write UnknownArray2 array (dynamic size)
|
|
for _, elem := range p.UnknownArray2 {
|
|
binary.LittleEndian.PutUint32(dest[offset:], elem.Array2Unknown)
|
|
offset += 4
|
|
|
|
}
|
|
|
|
return offset
|
|
}
|
|
|
|
// Size returns the serialized size of the packet
|
|
func (p *LSLoginReplyMsgV284) Size() uint32 {
|
|
size := uint32(0)
|
|
|
|
size += 1
|
|
|
|
size += 2 + uint32(len(p.Unknown))
|
|
|
|
size += 1
|
|
|
|
size += 4
|
|
|
|
size += 8
|
|
|
|
size += 4
|
|
|
|
size += 2 + uint32(len(p.Unknown3))
|
|
|
|
size += 1
|
|
|
|
size += 1
|
|
|
|
size += 2
|
|
|
|
size += 1
|
|
|
|
size += 4
|
|
|
|
size += 2
|
|
|
|
size += 1
|
|
|
|
size += 1
|
|
|
|
// Dynamic array: ClassItems
|
|
for _, elem := range p.ClassItems {
|
|
_ = elem // Avoid unused variable warning
|
|
size += 1
|
|
size += 1
|
|
// Nested array: StartingItems
|
|
for _, nestedElem := range elem.StartingItems {
|
|
_ = nestedElem // Avoid unused variable
|
|
size += 2
|
|
size += 1
|
|
size += 1
|
|
size += 1
|
|
size += 4
|
|
size += 4
|
|
|
|
}
|
|
|
|
}
|
|
|
|
size += 1
|
|
|
|
// Dynamic array: UnknownArray2
|
|
for _, elem := range p.UnknownArray2 {
|
|
_ = elem // Avoid unused variable warning
|
|
size += 4
|
|
|
|
}
|
|
|
|
return size
|
|
}
|
|
|
|
// LSLoginReplyMsgV843 represents packet structure for OP_LoginReplyMsg
|
|
type LSLoginReplyMsgV843 struct {
|
|
LoginResponse uint8 `eq2:"login_response"`
|
|
Unknown string `eq2:"unknown,type:str16"` // TODO: Identify purpose
|
|
ParentalControlFlag uint8 `eq2:"parental_control_flag"`
|
|
ParentalControlTimer uint32 `eq2:"parental_control_timer"`
|
|
Unknown2 [8]uint8 `eq2:"unknown2,size:8"` // TODO: Identify purpose
|
|
AccountId uint32 `eq2:"account_id"`
|
|
Unknown3 string `eq2:"unknown3,type:str16"` // TODO: Identify purpose
|
|
ResetAppearance uint8 `eq2:"reset_appearance"`
|
|
DoNotForceSoga uint8 `eq2:"do_not_force_soga"`
|
|
Unknown4 uint8 `eq2:"unknown4"` // TODO: Identify purpose
|
|
Unknown5 uint16 `eq2:"unknown5"` // TODO: Identify purpose
|
|
Unknown6 uint8 `eq2:"unknown6"` // TODO: Identify purpose
|
|
Unknown7 uint32 `eq2:"unknown7"` // TODO: Identify purpose
|
|
RaceUnknown uint8 `eq2:"race_unknown"`
|
|
Unknown8 [3]uint8 `eq2:"unknown8,size:3"` // TODO: Identify purpose
|
|
Unknown9 uint8 `eq2:"unknown9"` // TODO: Identify purpose
|
|
Unknown10 uint8 `eq2:"unknown10"` // TODO: Identify purpose
|
|
NumClassItems uint8 `eq2:"num_class_items,ifSet:unknown10"`
|
|
ClassItems []struct {
|
|
ClassId uint8 `eq2:"class_id"`
|
|
NumItems uint8 `eq2:"num_items"`
|
|
StartingItems []struct {
|
|
ModelId uint16 `eq2:"model_id"`
|
|
SlotId uint8 `eq2:"slot_id"`
|
|
UseColor uint8 `eq2:"use_color"`
|
|
UseHighlightColor uint8 `eq2:"use_highlight_color"`
|
|
ModelColor types.Color `eq2:"model_color"`
|
|
ModelHighlightColor types.Color `eq2:"model_highlight_color"`
|
|
} `eq2:"starting_items"`
|
|
} `eq2:"class_items,sizeVar:num_class_items,ifSet:unknown10"`
|
|
UnknownArray2Size uint8 `eq2:"unknown_array2_size"` // TODO: Identify purpose
|
|
UnknownArray2 []struct {
|
|
Array2Unknown uint32 `eq2:"array2_unknown"`
|
|
} `eq2:"unknown_array2,sizeVar:unknown_array2_size"`
|
|
}
|
|
|
|
// Serialize writes the packet data to the provided buffer
|
|
func (p *LSLoginReplyMsgV843) Serialize(dest []byte) uint32 {
|
|
offset := uint32(0)
|
|
|
|
// Write LoginResponse
|
|
dest[offset] = byte(p.LoginResponse)
|
|
offset++
|
|
|
|
// Write Unknown as 16-bit length-prefixed string
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(len(p.Unknown)))
|
|
offset += 2
|
|
copy(dest[offset:], []byte(p.Unknown))
|
|
offset += uint32(len(p.Unknown))
|
|
|
|
// Write ParentalControlFlag
|
|
dest[offset] = byte(p.ParentalControlFlag)
|
|
offset++
|
|
|
|
// Write ParentalControlTimer
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.ParentalControlTimer))
|
|
offset += 4
|
|
|
|
// Write Unknown2 array
|
|
for i := 0; i < 8; i++ {
|
|
dest[offset] = p.Unknown2[i]
|
|
offset++
|
|
}
|
|
|
|
// Write AccountId
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.AccountId))
|
|
offset += 4
|
|
|
|
// Write Unknown3 as 16-bit length-prefixed string
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(len(p.Unknown3)))
|
|
offset += 2
|
|
copy(dest[offset:], []byte(p.Unknown3))
|
|
offset += uint32(len(p.Unknown3))
|
|
|
|
// Write ResetAppearance
|
|
dest[offset] = byte(p.ResetAppearance)
|
|
offset++
|
|
|
|
// Write DoNotForceSoga
|
|
dest[offset] = byte(p.DoNotForceSoga)
|
|
offset++
|
|
|
|
// Write Unknown4
|
|
dest[offset] = byte(p.Unknown4)
|
|
offset++
|
|
|
|
// Write Unknown5
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(p.Unknown5))
|
|
offset += 2
|
|
|
|
// Write Unknown6
|
|
dest[offset] = byte(p.Unknown6)
|
|
offset++
|
|
|
|
// Write Unknown7
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.Unknown7))
|
|
offset += 4
|
|
|
|
// Write RaceUnknown
|
|
dest[offset] = byte(p.RaceUnknown)
|
|
offset++
|
|
|
|
// Write Unknown8 array
|
|
for i := 0; i < 3; i++ {
|
|
dest[offset] = p.Unknown8[i]
|
|
offset++
|
|
}
|
|
|
|
// Write Unknown9
|
|
dest[offset] = byte(p.Unknown9)
|
|
offset++
|
|
|
|
// Write Unknown10
|
|
dest[offset] = byte(p.Unknown10)
|
|
offset++
|
|
|
|
// Write NumClassItems
|
|
dest[offset] = byte(p.NumClassItems)
|
|
offset++
|
|
|
|
// Write ClassItems array (dynamic size)
|
|
for _, elem := range p.ClassItems {
|
|
dest[offset] = elem.ClassId
|
|
offset++
|
|
dest[offset] = elem.NumItems
|
|
offset++
|
|
// Write nested StartingItems array
|
|
for _, nestedElem := range elem.StartingItems {
|
|
binary.LittleEndian.PutUint16(dest[offset:], nestedElem.ModelId)
|
|
offset += 2
|
|
dest[offset] = nestedElem.SlotId
|
|
offset++
|
|
dest[offset] = nestedElem.UseColor
|
|
offset++
|
|
dest[offset] = nestedElem.UseHighlightColor
|
|
offset++
|
|
binary.LittleEndian.PutUint32(dest[offset:], nestedElem.ModelColor.ToUint32())
|
|
offset += 4
|
|
binary.LittleEndian.PutUint32(dest[offset:], nestedElem.ModelHighlightColor.ToUint32())
|
|
offset += 4
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// Write UnknownArray2Size
|
|
dest[offset] = byte(p.UnknownArray2Size)
|
|
offset++
|
|
|
|
// Write UnknownArray2 array (dynamic size)
|
|
for _, elem := range p.UnknownArray2 {
|
|
binary.LittleEndian.PutUint32(dest[offset:], elem.Array2Unknown)
|
|
offset += 4
|
|
|
|
}
|
|
|
|
return offset
|
|
}
|
|
|
|
// Size returns the serialized size of the packet
|
|
func (p *LSLoginReplyMsgV843) Size() uint32 {
|
|
size := uint32(0)
|
|
|
|
size += 1
|
|
|
|
size += 2 + uint32(len(p.Unknown))
|
|
|
|
size += 1
|
|
|
|
size += 4
|
|
|
|
size += 8
|
|
|
|
size += 4
|
|
|
|
size += 2 + uint32(len(p.Unknown3))
|
|
|
|
size += 1
|
|
|
|
size += 1
|
|
|
|
size += 1
|
|
|
|
size += 2
|
|
|
|
size += 1
|
|
|
|
size += 4
|
|
|
|
size += 1
|
|
|
|
size += 3
|
|
|
|
size += 1
|
|
|
|
size += 1
|
|
|
|
size += 1
|
|
|
|
// Dynamic array: ClassItems
|
|
for _, elem := range p.ClassItems {
|
|
_ = elem // Avoid unused variable warning
|
|
size += 1
|
|
size += 1
|
|
// Nested array: StartingItems
|
|
for _, nestedElem := range elem.StartingItems {
|
|
_ = nestedElem // Avoid unused variable
|
|
size += 2
|
|
size += 1
|
|
size += 1
|
|
size += 1
|
|
size += 4
|
|
size += 4
|
|
|
|
}
|
|
|
|
}
|
|
|
|
size += 1
|
|
|
|
// Dynamic array: UnknownArray2
|
|
for _, elem := range p.UnknownArray2 {
|
|
_ = elem // Avoid unused variable warning
|
|
size += 4
|
|
|
|
}
|
|
|
|
return size
|
|
}
|
|
|
|
// LSLoginReplyMsgV1096 represents packet structure for OP_LoginReplyMsg
|
|
type LSLoginReplyMsgV1096 struct {
|
|
LoginResponse uint8 `eq2:"login_response"`
|
|
Unknown string `eq2:"unknown,type:str16"` // TODO: Identify purpose
|
|
ParentalControlFlag uint8 `eq2:"parental_control_flag"`
|
|
ParentalControlTimer uint32 `eq2:"parental_control_timer"`
|
|
Unknown2 [8]uint8 `eq2:"unknown2,size:8"` // TODO: Identify purpose
|
|
AccountId uint32 `eq2:"account_id"`
|
|
Unknown3 string `eq2:"unknown3,type:str16"` // TODO: Identify purpose
|
|
ResetAppearance uint8 `eq2:"reset_appearance"`
|
|
DoNotForceSoga uint8 `eq2:"do_not_force_soga"`
|
|
Unknown4 uint8 `eq2:"unknown4"` // TODO: Identify purpose
|
|
Unknown5 uint16 `eq2:"unknown5"` // TODO: Identify purpose
|
|
Unknown6 [5]uint8 `eq2:"unknown6,size:5"` // TODO: Identify purpose
|
|
Unknown7 uint32 `eq2:"unknown7"` // TODO: Identify purpose
|
|
RaceUnknown uint8 `eq2:"race_unknown"`
|
|
Unknown8 [3]uint8 `eq2:"unknown8,size:3"` // TODO: Identify purpose
|
|
Unknown9 uint8 `eq2:"unknown9"` // TODO: Identify purpose
|
|
Unknown10 uint8 `eq2:"unknown10"` // TODO: Identify purpose
|
|
NumClassItems uint8 `eq2:"num_class_items,ifSet:unknown10"`
|
|
ClassItems []struct {
|
|
ClassId uint8 `eq2:"class_id"`
|
|
NumItems uint8 `eq2:"num_items"`
|
|
StartingItems []struct {
|
|
ModelId uint16 `eq2:"model_id"`
|
|
SlotId uint8 `eq2:"slot_id"`
|
|
UseColor uint8 `eq2:"use_color"`
|
|
UseHighlightColor uint8 `eq2:"use_highlight_color"`
|
|
ModelColor types.Color `eq2:"model_color"`
|
|
ModelHighlightColor types.Color `eq2:"model_highlight_color"`
|
|
} `eq2:"starting_items"`
|
|
} `eq2:"class_items,sizeVar:num_class_items,ifSet:unknown10"`
|
|
UnknownArray2Size uint8 `eq2:"unknown_array2_size"` // TODO: Identify purpose
|
|
UnknownArray2 []struct {
|
|
Array2Unknown uint32 `eq2:"array2_unknown"`
|
|
} `eq2:"unknown_array2,sizeVar:unknown_array2_size"`
|
|
Unknown11 uint32 `eq2:"unknown11"` // TODO: Identify purpose
|
|
SubLevel uint32 `eq2:"sub_level"`
|
|
RaceFlag uint32 `eq2:"race_flag"`
|
|
ClassFlag uint32 `eq2:"class_flag"`
|
|
Password string `eq2:"password,type:str16"`
|
|
Username string `eq2:"username,type:str16"`
|
|
}
|
|
|
|
// Serialize writes the packet data to the provided buffer
|
|
func (p *LSLoginReplyMsgV1096) Serialize(dest []byte) uint32 {
|
|
offset := uint32(0)
|
|
|
|
// Write LoginResponse
|
|
dest[offset] = byte(p.LoginResponse)
|
|
offset++
|
|
|
|
// Write Unknown as 16-bit length-prefixed string
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(len(p.Unknown)))
|
|
offset += 2
|
|
copy(dest[offset:], []byte(p.Unknown))
|
|
offset += uint32(len(p.Unknown))
|
|
|
|
// Write ParentalControlFlag
|
|
dest[offset] = byte(p.ParentalControlFlag)
|
|
offset++
|
|
|
|
// Write ParentalControlTimer
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.ParentalControlTimer))
|
|
offset += 4
|
|
|
|
// Write Unknown2 array
|
|
for i := 0; i < 8; i++ {
|
|
dest[offset] = p.Unknown2[i]
|
|
offset++
|
|
}
|
|
|
|
// Write AccountId
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.AccountId))
|
|
offset += 4
|
|
|
|
// Write Unknown3 as 16-bit length-prefixed string
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(len(p.Unknown3)))
|
|
offset += 2
|
|
copy(dest[offset:], []byte(p.Unknown3))
|
|
offset += uint32(len(p.Unknown3))
|
|
|
|
// Write ResetAppearance
|
|
dest[offset] = byte(p.ResetAppearance)
|
|
offset++
|
|
|
|
// Write DoNotForceSoga
|
|
dest[offset] = byte(p.DoNotForceSoga)
|
|
offset++
|
|
|
|
// Write Unknown4
|
|
dest[offset] = byte(p.Unknown4)
|
|
offset++
|
|
|
|
// Write Unknown5
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(p.Unknown5))
|
|
offset += 2
|
|
|
|
// Write Unknown6 array
|
|
for i := 0; i < 5; i++ {
|
|
dest[offset] = p.Unknown6[i]
|
|
offset++
|
|
}
|
|
|
|
// Write Unknown7
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.Unknown7))
|
|
offset += 4
|
|
|
|
// Write RaceUnknown
|
|
dest[offset] = byte(p.RaceUnknown)
|
|
offset++
|
|
|
|
// Write Unknown8 array
|
|
for i := 0; i < 3; i++ {
|
|
dest[offset] = p.Unknown8[i]
|
|
offset++
|
|
}
|
|
|
|
// Write Unknown9
|
|
dest[offset] = byte(p.Unknown9)
|
|
offset++
|
|
|
|
// Write Unknown10
|
|
dest[offset] = byte(p.Unknown10)
|
|
offset++
|
|
|
|
// Write NumClassItems
|
|
dest[offset] = byte(p.NumClassItems)
|
|
offset++
|
|
|
|
// Write ClassItems array (dynamic size)
|
|
for _, elem := range p.ClassItems {
|
|
dest[offset] = elem.ClassId
|
|
offset++
|
|
dest[offset] = elem.NumItems
|
|
offset++
|
|
// Write nested StartingItems array
|
|
for _, nestedElem := range elem.StartingItems {
|
|
binary.LittleEndian.PutUint16(dest[offset:], nestedElem.ModelId)
|
|
offset += 2
|
|
dest[offset] = nestedElem.SlotId
|
|
offset++
|
|
dest[offset] = nestedElem.UseColor
|
|
offset++
|
|
dest[offset] = nestedElem.UseHighlightColor
|
|
offset++
|
|
binary.LittleEndian.PutUint32(dest[offset:], nestedElem.ModelColor.ToUint32())
|
|
offset += 4
|
|
binary.LittleEndian.PutUint32(dest[offset:], nestedElem.ModelHighlightColor.ToUint32())
|
|
offset += 4
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// Write UnknownArray2Size
|
|
dest[offset] = byte(p.UnknownArray2Size)
|
|
offset++
|
|
|
|
// Write UnknownArray2 array (dynamic size)
|
|
for _, elem := range p.UnknownArray2 {
|
|
binary.LittleEndian.PutUint32(dest[offset:], elem.Array2Unknown)
|
|
offset += 4
|
|
|
|
}
|
|
|
|
// Write Unknown11
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.Unknown11))
|
|
offset += 4
|
|
|
|
// Write SubLevel
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.SubLevel))
|
|
offset += 4
|
|
|
|
// Write RaceFlag
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.RaceFlag))
|
|
offset += 4
|
|
|
|
// Write ClassFlag
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.ClassFlag))
|
|
offset += 4
|
|
|
|
// Write Password as 16-bit length-prefixed string
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(len(p.Password)))
|
|
offset += 2
|
|
copy(dest[offset:], []byte(p.Password))
|
|
offset += uint32(len(p.Password))
|
|
|
|
// Write Username as 16-bit length-prefixed string
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(len(p.Username)))
|
|
offset += 2
|
|
copy(dest[offset:], []byte(p.Username))
|
|
offset += uint32(len(p.Username))
|
|
|
|
return offset
|
|
}
|
|
|
|
// Size returns the serialized size of the packet
|
|
func (p *LSLoginReplyMsgV1096) Size() uint32 {
|
|
size := uint32(0)
|
|
|
|
size += 1
|
|
|
|
size += 2 + uint32(len(p.Unknown))
|
|
|
|
size += 1
|
|
|
|
size += 4
|
|
|
|
size += 8
|
|
|
|
size += 4
|
|
|
|
size += 2 + uint32(len(p.Unknown3))
|
|
|
|
size += 1
|
|
|
|
size += 1
|
|
|
|
size += 1
|
|
|
|
size += 2
|
|
|
|
size += 5
|
|
|
|
size += 4
|
|
|
|
size += 1
|
|
|
|
size += 3
|
|
|
|
size += 1
|
|
|
|
size += 1
|
|
|
|
size += 1
|
|
|
|
// Dynamic array: ClassItems
|
|
for _, elem := range p.ClassItems {
|
|
_ = elem // Avoid unused variable warning
|
|
size += 1
|
|
size += 1
|
|
// Nested array: StartingItems
|
|
for _, nestedElem := range elem.StartingItems {
|
|
_ = nestedElem // Avoid unused variable
|
|
size += 2
|
|
size += 1
|
|
size += 1
|
|
size += 1
|
|
size += 4
|
|
size += 4
|
|
|
|
}
|
|
|
|
}
|
|
|
|
size += 1
|
|
|
|
// Dynamic array: UnknownArray2
|
|
for _, elem := range p.UnknownArray2 {
|
|
_ = elem // Avoid unused variable warning
|
|
size += 4
|
|
|
|
}
|
|
|
|
size += 4
|
|
|
|
size += 4
|
|
|
|
size += 4
|
|
|
|
size += 4
|
|
|
|
size += 2 + uint32(len(p.Password))
|
|
|
|
size += 2 + uint32(len(p.Username))
|
|
|
|
return size
|
|
}
|
|
|
|
// LSLoginReplyMsgV1142 represents packet structure for OP_LoginReplyMsg
|
|
type LSLoginReplyMsgV1142 struct {
|
|
LoginResponse uint8 `eq2:"login_response"`
|
|
Unknown string `eq2:"unknown,type:str16"` // TODO: Identify purpose
|
|
ParentalControlFlag uint8 `eq2:"parental_control_flag"`
|
|
ParentalControlTimer uint32 `eq2:"parental_control_timer"`
|
|
Unknown2 [8]uint8 `eq2:"unknown2,size:8"` // TODO: Identify purpose
|
|
AccountId uint32 `eq2:"account_id"`
|
|
Unknown3 string `eq2:"unknown3,type:str16"` // TODO: Identify purpose
|
|
ResetAppearance uint8 `eq2:"reset_appearance"`
|
|
DoNotForceSoga uint8 `eq2:"do_not_force_soga"`
|
|
Unknown4 uint8 `eq2:"unknown4"` // TODO: Identify purpose
|
|
Unknown5 uint16 `eq2:"unknown5"` // TODO: Identify purpose
|
|
Unknown6 [5]uint8 `eq2:"unknown6,size:5"` // TODO: Identify purpose
|
|
Unknown7 uint32 `eq2:"unknown7"` // TODO: Identify purpose
|
|
Unknown7a uint32 `eq2:"unknown7a"` // TODO: Identify purpose
|
|
RaceUnknown uint8 `eq2:"race_unknown"`
|
|
Unknown8 [3]uint8 `eq2:"unknown8,size:3"` // TODO: Identify purpose
|
|
Unknown9 uint8 `eq2:"unknown9"` // TODO: Identify purpose
|
|
Unknown10 uint8 `eq2:"unknown10"` // TODO: Identify purpose
|
|
NumClassItems uint8 `eq2:"num_class_items,ifSet:unknown10"`
|
|
ClassItems []struct {
|
|
ClassId uint8 `eq2:"class_id"`
|
|
NumItems uint8 `eq2:"num_items"`
|
|
StartingItems []struct {
|
|
ModelId uint16 `eq2:"model_id"`
|
|
SlotId uint8 `eq2:"slot_id"`
|
|
UseColor uint8 `eq2:"use_color"`
|
|
UseHighlightColor uint8 `eq2:"use_highlight_color"`
|
|
ModelColor types.Color `eq2:"model_color"`
|
|
ModelHighlightColor types.Color `eq2:"model_highlight_color"`
|
|
} `eq2:"starting_items"`
|
|
} `eq2:"class_items,sizeVar:num_class_items,ifSet:unknown10"`
|
|
UnknownArray2Size uint8 `eq2:"unknown_array2_size"` // TODO: Identify purpose
|
|
UnknownArray2 []struct {
|
|
Array2Unknown uint32 `eq2:"array2_unknown"`
|
|
} `eq2:"unknown_array2,sizeVar:unknown_array2_size"`
|
|
Unknown11 uint32 `eq2:"unknown11"` // TODO: Identify purpose
|
|
SubLevel uint32 `eq2:"sub_level"`
|
|
RaceFlag uint32 `eq2:"race_flag"`
|
|
ClassFlag uint32 `eq2:"class_flag"`
|
|
Password string `eq2:"password,type:str16"`
|
|
Username string `eq2:"username,type:str16"`
|
|
}
|
|
|
|
// Serialize writes the packet data to the provided buffer
|
|
func (p *LSLoginReplyMsgV1142) Serialize(dest []byte) uint32 {
|
|
offset := uint32(0)
|
|
|
|
// Write LoginResponse
|
|
dest[offset] = byte(p.LoginResponse)
|
|
offset++
|
|
|
|
// Write Unknown as 16-bit length-prefixed string
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(len(p.Unknown)))
|
|
offset += 2
|
|
copy(dest[offset:], []byte(p.Unknown))
|
|
offset += uint32(len(p.Unknown))
|
|
|
|
// Write ParentalControlFlag
|
|
dest[offset] = byte(p.ParentalControlFlag)
|
|
offset++
|
|
|
|
// Write ParentalControlTimer
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.ParentalControlTimer))
|
|
offset += 4
|
|
|
|
// Write Unknown2 array
|
|
for i := 0; i < 8; i++ {
|
|
dest[offset] = p.Unknown2[i]
|
|
offset++
|
|
}
|
|
|
|
// Write AccountId
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.AccountId))
|
|
offset += 4
|
|
|
|
// Write Unknown3 as 16-bit length-prefixed string
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(len(p.Unknown3)))
|
|
offset += 2
|
|
copy(dest[offset:], []byte(p.Unknown3))
|
|
offset += uint32(len(p.Unknown3))
|
|
|
|
// Write ResetAppearance
|
|
dest[offset] = byte(p.ResetAppearance)
|
|
offset++
|
|
|
|
// Write DoNotForceSoga
|
|
dest[offset] = byte(p.DoNotForceSoga)
|
|
offset++
|
|
|
|
// Write Unknown4
|
|
dest[offset] = byte(p.Unknown4)
|
|
offset++
|
|
|
|
// Write Unknown5
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(p.Unknown5))
|
|
offset += 2
|
|
|
|
// Write Unknown6 array
|
|
for i := 0; i < 5; i++ {
|
|
dest[offset] = p.Unknown6[i]
|
|
offset++
|
|
}
|
|
|
|
// Write Unknown7
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.Unknown7))
|
|
offset += 4
|
|
|
|
// Write Unknown7a
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.Unknown7a))
|
|
offset += 4
|
|
|
|
// Write RaceUnknown
|
|
dest[offset] = byte(p.RaceUnknown)
|
|
offset++
|
|
|
|
// Write Unknown8 array
|
|
for i := 0; i < 3; i++ {
|
|
dest[offset] = p.Unknown8[i]
|
|
offset++
|
|
}
|
|
|
|
// Write Unknown9
|
|
dest[offset] = byte(p.Unknown9)
|
|
offset++
|
|
|
|
// Write Unknown10
|
|
dest[offset] = byte(p.Unknown10)
|
|
offset++
|
|
|
|
// Write NumClassItems
|
|
dest[offset] = byte(p.NumClassItems)
|
|
offset++
|
|
|
|
// Write ClassItems array (dynamic size)
|
|
for _, elem := range p.ClassItems {
|
|
dest[offset] = elem.ClassId
|
|
offset++
|
|
dest[offset] = elem.NumItems
|
|
offset++
|
|
// Write nested StartingItems array
|
|
for _, nestedElem := range elem.StartingItems {
|
|
binary.LittleEndian.PutUint16(dest[offset:], nestedElem.ModelId)
|
|
offset += 2
|
|
dest[offset] = nestedElem.SlotId
|
|
offset++
|
|
dest[offset] = nestedElem.UseColor
|
|
offset++
|
|
dest[offset] = nestedElem.UseHighlightColor
|
|
offset++
|
|
binary.LittleEndian.PutUint32(dest[offset:], nestedElem.ModelColor.ToUint32())
|
|
offset += 4
|
|
binary.LittleEndian.PutUint32(dest[offset:], nestedElem.ModelHighlightColor.ToUint32())
|
|
offset += 4
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// Write UnknownArray2Size
|
|
dest[offset] = byte(p.UnknownArray2Size)
|
|
offset++
|
|
|
|
// Write UnknownArray2 array (dynamic size)
|
|
for _, elem := range p.UnknownArray2 {
|
|
binary.LittleEndian.PutUint32(dest[offset:], elem.Array2Unknown)
|
|
offset += 4
|
|
|
|
}
|
|
|
|
// Write Unknown11
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.Unknown11))
|
|
offset += 4
|
|
|
|
// Write SubLevel
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.SubLevel))
|
|
offset += 4
|
|
|
|
// Write RaceFlag
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.RaceFlag))
|
|
offset += 4
|
|
|
|
// Write ClassFlag
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.ClassFlag))
|
|
offset += 4
|
|
|
|
// Write Password as 16-bit length-prefixed string
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(len(p.Password)))
|
|
offset += 2
|
|
copy(dest[offset:], []byte(p.Password))
|
|
offset += uint32(len(p.Password))
|
|
|
|
// Write Username as 16-bit length-prefixed string
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(len(p.Username)))
|
|
offset += 2
|
|
copy(dest[offset:], []byte(p.Username))
|
|
offset += uint32(len(p.Username))
|
|
|
|
return offset
|
|
}
|
|
|
|
// Size returns the serialized size of the packet
|
|
func (p *LSLoginReplyMsgV1142) Size() uint32 {
|
|
size := uint32(0)
|
|
|
|
size += 1
|
|
|
|
size += 2 + uint32(len(p.Unknown))
|
|
|
|
size += 1
|
|
|
|
size += 4
|
|
|
|
size += 8
|
|
|
|
size += 4
|
|
|
|
size += 2 + uint32(len(p.Unknown3))
|
|
|
|
size += 1
|
|
|
|
size += 1
|
|
|
|
size += 1
|
|
|
|
size += 2
|
|
|
|
size += 5
|
|
|
|
size += 4
|
|
|
|
size += 4
|
|
|
|
size += 1
|
|
|
|
size += 3
|
|
|
|
size += 1
|
|
|
|
size += 1
|
|
|
|
size += 1
|
|
|
|
// Dynamic array: ClassItems
|
|
for _, elem := range p.ClassItems {
|
|
_ = elem // Avoid unused variable warning
|
|
size += 1
|
|
size += 1
|
|
// Nested array: StartingItems
|
|
for _, nestedElem := range elem.StartingItems {
|
|
_ = nestedElem // Avoid unused variable
|
|
size += 2
|
|
size += 1
|
|
size += 1
|
|
size += 1
|
|
size += 4
|
|
size += 4
|
|
|
|
}
|
|
|
|
}
|
|
|
|
size += 1
|
|
|
|
// Dynamic array: UnknownArray2
|
|
for _, elem := range p.UnknownArray2 {
|
|
_ = elem // Avoid unused variable warning
|
|
size += 4
|
|
|
|
}
|
|
|
|
size += 4
|
|
|
|
size += 4
|
|
|
|
size += 4
|
|
|
|
size += 4
|
|
|
|
size += 2 + uint32(len(p.Password))
|
|
|
|
size += 2 + uint32(len(p.Username))
|
|
|
|
return size
|
|
}
|
|
|
|
// LSLoginReplyMsgV1188 represents packet structure for OP_LoginReplyMsg
|
|
type LSLoginReplyMsgV1188 struct {
|
|
LoginResponse uint8 `eq2:"login_response"`
|
|
Unknown string `eq2:"unknown,type:str16"` // TODO: Identify purpose
|
|
ParentalControlFlag uint8 `eq2:"parental_control_flag"`
|
|
ParentalControlTimer uint32 `eq2:"parental_control_timer"`
|
|
Unknown2 [8]uint8 `eq2:"unknown2,size:8"` // TODO: Identify purpose
|
|
AccountId uint32 `eq2:"account_id"`
|
|
Unknown3 string `eq2:"unknown3,type:str16"` // TODO: Identify purpose
|
|
ResetAppearance uint8 `eq2:"reset_appearance"`
|
|
DoNotForceSoga uint8 `eq2:"do_not_force_soga"`
|
|
Unknown4 uint8 `eq2:"unknown4"` // TODO: Identify purpose
|
|
Unknown5 uint16 `eq2:"unknown5"` // TODO: Identify purpose
|
|
Unknown6 [5]uint8 `eq2:"unknown6,size:5"` // TODO: Identify purpose
|
|
Unknown7 uint32 `eq2:"unknown7"` // TODO: Identify purpose
|
|
Unknown7a uint32 `eq2:"unknown7a"` // TODO: Identify purpose
|
|
RaceUnknown uint8 `eq2:"race_unknown"`
|
|
Unknown8 [3]uint8 `eq2:"unknown8,size:3"` // TODO: Identify purpose
|
|
Unknown9 uint8 `eq2:"unknown9"` // TODO: Identify purpose
|
|
Unknown10 uint8 `eq2:"unknown10"` // TODO: Identify purpose
|
|
NumClassItems uint8 `eq2:"num_class_items,ifSet:unknown10"`
|
|
ClassItems []struct {
|
|
ClassId uint8 `eq2:"class_id"`
|
|
NumItems uint8 `eq2:"num_items"`
|
|
StartingItems []struct {
|
|
ModelId uint16 `eq2:"model_id"`
|
|
SlotId uint8 `eq2:"slot_id"`
|
|
UseColor uint8 `eq2:"use_color"`
|
|
UseHighlightColor uint8 `eq2:"use_highlight_color"`
|
|
ModelColor types.Color `eq2:"model_color"`
|
|
ModelHighlightColor types.Color `eq2:"model_highlight_color"`
|
|
} `eq2:"starting_items"`
|
|
} `eq2:"class_items,sizeVar:num_class_items,ifSet:unknown10"`
|
|
UnknownArray2Size uint8 `eq2:"unknown_array2_size"` // TODO: Identify purpose
|
|
UnknownArray2 []struct {
|
|
Array2Unknown uint32 `eq2:"array2_unknown"`
|
|
} `eq2:"unknown_array2,sizeVar:unknown_array2_size"`
|
|
Unknown11 uint32 `eq2:"unknown11"` // TODO: Identify purpose
|
|
SubLevel uint32 `eq2:"sub_level"`
|
|
RaceFlag uint32 `eq2:"race_flag"`
|
|
ClassFlag uint32 `eq2:"class_flag"`
|
|
Password string `eq2:"password,type:str16"`
|
|
Username string `eq2:"username,type:str16"`
|
|
Unknown12 string `eq2:"unknown12,type:str16"` // TODO: Identify purpose
|
|
}
|
|
|
|
// Serialize writes the packet data to the provided buffer
|
|
func (p *LSLoginReplyMsgV1188) Serialize(dest []byte) uint32 {
|
|
offset := uint32(0)
|
|
|
|
// Write LoginResponse
|
|
dest[offset] = byte(p.LoginResponse)
|
|
offset++
|
|
|
|
// Write Unknown as 16-bit length-prefixed string
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(len(p.Unknown)))
|
|
offset += 2
|
|
copy(dest[offset:], []byte(p.Unknown))
|
|
offset += uint32(len(p.Unknown))
|
|
|
|
// Write ParentalControlFlag
|
|
dest[offset] = byte(p.ParentalControlFlag)
|
|
offset++
|
|
|
|
// Write ParentalControlTimer
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.ParentalControlTimer))
|
|
offset += 4
|
|
|
|
// Write Unknown2 array
|
|
for i := 0; i < 8; i++ {
|
|
dest[offset] = p.Unknown2[i]
|
|
offset++
|
|
}
|
|
|
|
// Write AccountId
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.AccountId))
|
|
offset += 4
|
|
|
|
// Write Unknown3 as 16-bit length-prefixed string
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(len(p.Unknown3)))
|
|
offset += 2
|
|
copy(dest[offset:], []byte(p.Unknown3))
|
|
offset += uint32(len(p.Unknown3))
|
|
|
|
// Write ResetAppearance
|
|
dest[offset] = byte(p.ResetAppearance)
|
|
offset++
|
|
|
|
// Write DoNotForceSoga
|
|
dest[offset] = byte(p.DoNotForceSoga)
|
|
offset++
|
|
|
|
// Write Unknown4
|
|
dest[offset] = byte(p.Unknown4)
|
|
offset++
|
|
|
|
// Write Unknown5
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(p.Unknown5))
|
|
offset += 2
|
|
|
|
// Write Unknown6 array
|
|
for i := 0; i < 5; i++ {
|
|
dest[offset] = p.Unknown6[i]
|
|
offset++
|
|
}
|
|
|
|
// Write Unknown7
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.Unknown7))
|
|
offset += 4
|
|
|
|
// Write Unknown7a
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.Unknown7a))
|
|
offset += 4
|
|
|
|
// Write RaceUnknown
|
|
dest[offset] = byte(p.RaceUnknown)
|
|
offset++
|
|
|
|
// Write Unknown8 array
|
|
for i := 0; i < 3; i++ {
|
|
dest[offset] = p.Unknown8[i]
|
|
offset++
|
|
}
|
|
|
|
// Write Unknown9
|
|
dest[offset] = byte(p.Unknown9)
|
|
offset++
|
|
|
|
// Write Unknown10
|
|
dest[offset] = byte(p.Unknown10)
|
|
offset++
|
|
|
|
// Write NumClassItems
|
|
dest[offset] = byte(p.NumClassItems)
|
|
offset++
|
|
|
|
// Write ClassItems array (dynamic size)
|
|
for _, elem := range p.ClassItems {
|
|
dest[offset] = elem.ClassId
|
|
offset++
|
|
dest[offset] = elem.NumItems
|
|
offset++
|
|
// Write nested StartingItems array
|
|
for _, nestedElem := range elem.StartingItems {
|
|
binary.LittleEndian.PutUint16(dest[offset:], nestedElem.ModelId)
|
|
offset += 2
|
|
dest[offset] = nestedElem.SlotId
|
|
offset++
|
|
dest[offset] = nestedElem.UseColor
|
|
offset++
|
|
dest[offset] = nestedElem.UseHighlightColor
|
|
offset++
|
|
binary.LittleEndian.PutUint32(dest[offset:], nestedElem.ModelColor.ToUint32())
|
|
offset += 4
|
|
binary.LittleEndian.PutUint32(dest[offset:], nestedElem.ModelHighlightColor.ToUint32())
|
|
offset += 4
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// Write UnknownArray2Size
|
|
dest[offset] = byte(p.UnknownArray2Size)
|
|
offset++
|
|
|
|
// Write UnknownArray2 array (dynamic size)
|
|
for _, elem := range p.UnknownArray2 {
|
|
binary.LittleEndian.PutUint32(dest[offset:], elem.Array2Unknown)
|
|
offset += 4
|
|
|
|
}
|
|
|
|
// Write Unknown11
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.Unknown11))
|
|
offset += 4
|
|
|
|
// Write SubLevel
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.SubLevel))
|
|
offset += 4
|
|
|
|
// Write RaceFlag
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.RaceFlag))
|
|
offset += 4
|
|
|
|
// Write ClassFlag
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.ClassFlag))
|
|
offset += 4
|
|
|
|
// Write Password as 16-bit length-prefixed string
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(len(p.Password)))
|
|
offset += 2
|
|
copy(dest[offset:], []byte(p.Password))
|
|
offset += uint32(len(p.Password))
|
|
|
|
// Write Username as 16-bit length-prefixed string
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(len(p.Username)))
|
|
offset += 2
|
|
copy(dest[offset:], []byte(p.Username))
|
|
offset += uint32(len(p.Username))
|
|
|
|
// Write Unknown12 as 16-bit length-prefixed string
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(len(p.Unknown12)))
|
|
offset += 2
|
|
copy(dest[offset:], []byte(p.Unknown12))
|
|
offset += uint32(len(p.Unknown12))
|
|
|
|
return offset
|
|
}
|
|
|
|
// Size returns the serialized size of the packet
|
|
func (p *LSLoginReplyMsgV1188) Size() uint32 {
|
|
size := uint32(0)
|
|
|
|
size += 1
|
|
|
|
size += 2 + uint32(len(p.Unknown))
|
|
|
|
size += 1
|
|
|
|
size += 4
|
|
|
|
size += 8
|
|
|
|
size += 4
|
|
|
|
size += 2 + uint32(len(p.Unknown3))
|
|
|
|
size += 1
|
|
|
|
size += 1
|
|
|
|
size += 1
|
|
|
|
size += 2
|
|
|
|
size += 5
|
|
|
|
size += 4
|
|
|
|
size += 4
|
|
|
|
size += 1
|
|
|
|
size += 3
|
|
|
|
size += 1
|
|
|
|
size += 1
|
|
|
|
size += 1
|
|
|
|
// Dynamic array: ClassItems
|
|
for _, elem := range p.ClassItems {
|
|
_ = elem // Avoid unused variable warning
|
|
size += 1
|
|
size += 1
|
|
// Nested array: StartingItems
|
|
for _, nestedElem := range elem.StartingItems {
|
|
_ = nestedElem // Avoid unused variable
|
|
size += 2
|
|
size += 1
|
|
size += 1
|
|
size += 1
|
|
size += 4
|
|
size += 4
|
|
|
|
}
|
|
|
|
}
|
|
|
|
size += 1
|
|
|
|
// Dynamic array: UnknownArray2
|
|
for _, elem := range p.UnknownArray2 {
|
|
_ = elem // Avoid unused variable warning
|
|
size += 4
|
|
|
|
}
|
|
|
|
size += 4
|
|
|
|
size += 4
|
|
|
|
size += 4
|
|
|
|
size += 4
|
|
|
|
size += 2 + uint32(len(p.Password))
|
|
|
|
size += 2 + uint32(len(p.Username))
|
|
|
|
size += 2 + uint32(len(p.Unknown12))
|
|
|
|
return size
|
|
}
|
|
|
|
// LSLoginReplyMsgV57080 represents packet structure for OP_LoginReplyMsg
|
|
type LSLoginReplyMsgV57080 struct {
|
|
LoginResponse uint8 `eq2:"login_response"`
|
|
Unknown string `eq2:"unknown,type:str16"` // TODO: Identify purpose
|
|
ParentalControlFlag uint8 `eq2:"parental_control_flag"`
|
|
ParentalControlTimer uint32 `eq2:"parental_control_timer"`
|
|
Unknown2 [8]uint8 `eq2:"unknown2,size:8"` // TODO: Identify purpose
|
|
AccountId uint32 `eq2:"account_id"`
|
|
Unknown3 string `eq2:"unknown3,type:str16"` // TODO: Identify purpose
|
|
ResetAppearance uint8 `eq2:"reset_appearance"`
|
|
DoNotForceSoga uint8 `eq2:"do_not_force_soga"`
|
|
Unknown4 uint8 `eq2:"unknown4"` // TODO: Identify purpose
|
|
Unknown5 uint16 `eq2:"unknown5"` // TODO: Identify purpose
|
|
Unknown6 [5]uint8 `eq2:"unknown6,size:5"` // TODO: Identify purpose
|
|
Unknown7 uint32 `eq2:"unknown7"` // TODO: Identify purpose
|
|
Unknown7a uint32 `eq2:"unknown7a"` // TODO: Identify purpose
|
|
RaceUnknown uint8 `eq2:"race_unknown"`
|
|
Unknown8 [3]uint8 `eq2:"unknown8,size:3"` // TODO: Identify purpose
|
|
Unknown9 uint8 `eq2:"unknown9"` // TODO: Identify purpose
|
|
Unknown10 uint8 `eq2:"unknown10"` // TODO: Identify purpose
|
|
NumClassItems uint8 `eq2:"num_class_items,ifSet:unknown10"`
|
|
ClassItems []struct {
|
|
ClassId uint8 `eq2:"class_id"`
|
|
NumItems uint8 `eq2:"num_items"`
|
|
StartingItems []struct {
|
|
ModelId uint32 `eq2:"model_id"`
|
|
SlotId uint8 `eq2:"slot_id"`
|
|
UseColor uint8 `eq2:"use_color"`
|
|
UseHighlightColor uint8 `eq2:"use_highlight_color"`
|
|
ModelColor types.Color `eq2:"model_color"`
|
|
ModelHighlightColor types.Color `eq2:"model_highlight_color"`
|
|
} `eq2:"starting_items"`
|
|
} `eq2:"class_items,sizeVar:num_class_items,ifSet:unknown10"`
|
|
UnknownArray2Size uint8 `eq2:"unknown_array2_size"` // TODO: Identify purpose
|
|
UnknownArray2 []struct {
|
|
Array2Unknown uint32 `eq2:"array2_unknown"`
|
|
} `eq2:"unknown_array2,sizeVar:unknown_array2_size"`
|
|
Unknown11 uint32 `eq2:"unknown11"` // TODO: Identify purpose
|
|
SubLevel uint32 `eq2:"sub_level"`
|
|
RaceFlag uint32 `eq2:"race_flag"`
|
|
ClassFlag uint32 `eq2:"class_flag"`
|
|
Password string `eq2:"password,type:str16"`
|
|
Username string `eq2:"username,type:str16"`
|
|
Service string `eq2:"service,type:str16"`
|
|
Web1 string `eq2:"web1,type:str16"`
|
|
Web2 string `eq2:"web2,type:str16"`
|
|
Web3 string `eq2:"web3,type:str16"`
|
|
Web4 string `eq2:"web4,type:str16"`
|
|
Web5 string `eq2:"web5,type:str16"`
|
|
Web6 string `eq2:"web6,type:str16"`
|
|
Web7 string `eq2:"web7,type:str16"`
|
|
Web8 string `eq2:"web8,type:str16"`
|
|
Web9 string `eq2:"web9,type:str16"`
|
|
Unknown12 uint8 `eq2:"unknown12"` // TODO: Identify purpose
|
|
Lvl90NumClassItems uint8 `eq2:"lvl90_num_class_items,ifSet:unknown10"`
|
|
Lvl90ClassItems []struct {
|
|
ClassId uint8 `eq2:"class_id"`
|
|
NumItems uint8 `eq2:"num_items"`
|
|
StartingItems []struct {
|
|
ModelId uint32 `eq2:"model_id"`
|
|
SlotId uint8 `eq2:"slot_id"`
|
|
UseColor uint8 `eq2:"use_color"`
|
|
UseHighlightColor uint8 `eq2:"use_highlight_color"`
|
|
ModelColor types.Color `eq2:"model_color"`
|
|
ModelHighlightColor types.Color `eq2:"model_highlight_color"`
|
|
} `eq2:"starting_items"`
|
|
} `eq2:"lvl90_class_items,sizeVar:lvl90_num_class_items,ifSet:unknown10"`
|
|
Unknown13 [5]uint8 `eq2:"unknown13,size:5"` // TODO: Identify purpose
|
|
}
|
|
|
|
// Serialize writes the packet data to the provided buffer
|
|
func (p *LSLoginReplyMsgV57080) Serialize(dest []byte) uint32 {
|
|
offset := uint32(0)
|
|
|
|
// Write LoginResponse
|
|
dest[offset] = byte(p.LoginResponse)
|
|
offset++
|
|
|
|
// Write Unknown as 16-bit length-prefixed string
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(len(p.Unknown)))
|
|
offset += 2
|
|
copy(dest[offset:], []byte(p.Unknown))
|
|
offset += uint32(len(p.Unknown))
|
|
|
|
// Write ParentalControlFlag
|
|
dest[offset] = byte(p.ParentalControlFlag)
|
|
offset++
|
|
|
|
// Write ParentalControlTimer
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.ParentalControlTimer))
|
|
offset += 4
|
|
|
|
// Write Unknown2 array
|
|
for i := 0; i < 8; i++ {
|
|
dest[offset] = p.Unknown2[i]
|
|
offset++
|
|
}
|
|
|
|
// Write AccountId
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.AccountId))
|
|
offset += 4
|
|
|
|
// Write Unknown3 as 16-bit length-prefixed string
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(len(p.Unknown3)))
|
|
offset += 2
|
|
copy(dest[offset:], []byte(p.Unknown3))
|
|
offset += uint32(len(p.Unknown3))
|
|
|
|
// Write ResetAppearance
|
|
dest[offset] = byte(p.ResetAppearance)
|
|
offset++
|
|
|
|
// Write DoNotForceSoga
|
|
dest[offset] = byte(p.DoNotForceSoga)
|
|
offset++
|
|
|
|
// Write Unknown4
|
|
dest[offset] = byte(p.Unknown4)
|
|
offset++
|
|
|
|
// Write Unknown5
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(p.Unknown5))
|
|
offset += 2
|
|
|
|
// Write Unknown6 array
|
|
for i := 0; i < 5; i++ {
|
|
dest[offset] = p.Unknown6[i]
|
|
offset++
|
|
}
|
|
|
|
// Write Unknown7
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.Unknown7))
|
|
offset += 4
|
|
|
|
// Write Unknown7a
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.Unknown7a))
|
|
offset += 4
|
|
|
|
// Write RaceUnknown
|
|
dest[offset] = byte(p.RaceUnknown)
|
|
offset++
|
|
|
|
// Write Unknown8 array
|
|
for i := 0; i < 3; i++ {
|
|
dest[offset] = p.Unknown8[i]
|
|
offset++
|
|
}
|
|
|
|
// Write Unknown9
|
|
dest[offset] = byte(p.Unknown9)
|
|
offset++
|
|
|
|
// Write Unknown10
|
|
dest[offset] = byte(p.Unknown10)
|
|
offset++
|
|
|
|
// Write NumClassItems
|
|
dest[offset] = byte(p.NumClassItems)
|
|
offset++
|
|
|
|
// Write ClassItems array (dynamic size)
|
|
for _, elem := range p.ClassItems {
|
|
dest[offset] = elem.ClassId
|
|
offset++
|
|
dest[offset] = elem.NumItems
|
|
offset++
|
|
// Write nested StartingItems array
|
|
for _, nestedElem := range elem.StartingItems {
|
|
binary.LittleEndian.PutUint32(dest[offset:], nestedElem.ModelId)
|
|
offset += 4
|
|
dest[offset] = nestedElem.SlotId
|
|
offset++
|
|
dest[offset] = nestedElem.UseColor
|
|
offset++
|
|
dest[offset] = nestedElem.UseHighlightColor
|
|
offset++
|
|
binary.LittleEndian.PutUint32(dest[offset:], nestedElem.ModelColor.ToUint32())
|
|
offset += 4
|
|
binary.LittleEndian.PutUint32(dest[offset:], nestedElem.ModelHighlightColor.ToUint32())
|
|
offset += 4
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// Write UnknownArray2Size
|
|
dest[offset] = byte(p.UnknownArray2Size)
|
|
offset++
|
|
|
|
// Write UnknownArray2 array (dynamic size)
|
|
for _, elem := range p.UnknownArray2 {
|
|
binary.LittleEndian.PutUint32(dest[offset:], elem.Array2Unknown)
|
|
offset += 4
|
|
|
|
}
|
|
|
|
// Write Unknown11
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.Unknown11))
|
|
offset += 4
|
|
|
|
// Write SubLevel
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.SubLevel))
|
|
offset += 4
|
|
|
|
// Write RaceFlag
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.RaceFlag))
|
|
offset += 4
|
|
|
|
// Write ClassFlag
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.ClassFlag))
|
|
offset += 4
|
|
|
|
// Write Password as 16-bit length-prefixed string
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(len(p.Password)))
|
|
offset += 2
|
|
copy(dest[offset:], []byte(p.Password))
|
|
offset += uint32(len(p.Password))
|
|
|
|
// Write Username as 16-bit length-prefixed string
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(len(p.Username)))
|
|
offset += 2
|
|
copy(dest[offset:], []byte(p.Username))
|
|
offset += uint32(len(p.Username))
|
|
|
|
// Write Service as 16-bit length-prefixed string
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(len(p.Service)))
|
|
offset += 2
|
|
copy(dest[offset:], []byte(p.Service))
|
|
offset += uint32(len(p.Service))
|
|
|
|
// Write Web1 as 16-bit length-prefixed string
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(len(p.Web1)))
|
|
offset += 2
|
|
copy(dest[offset:], []byte(p.Web1))
|
|
offset += uint32(len(p.Web1))
|
|
|
|
// Write Web2 as 16-bit length-prefixed string
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(len(p.Web2)))
|
|
offset += 2
|
|
copy(dest[offset:], []byte(p.Web2))
|
|
offset += uint32(len(p.Web2))
|
|
|
|
// Write Web3 as 16-bit length-prefixed string
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(len(p.Web3)))
|
|
offset += 2
|
|
copy(dest[offset:], []byte(p.Web3))
|
|
offset += uint32(len(p.Web3))
|
|
|
|
// Write Web4 as 16-bit length-prefixed string
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(len(p.Web4)))
|
|
offset += 2
|
|
copy(dest[offset:], []byte(p.Web4))
|
|
offset += uint32(len(p.Web4))
|
|
|
|
// Write Web5 as 16-bit length-prefixed string
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(len(p.Web5)))
|
|
offset += 2
|
|
copy(dest[offset:], []byte(p.Web5))
|
|
offset += uint32(len(p.Web5))
|
|
|
|
// Write Web6 as 16-bit length-prefixed string
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(len(p.Web6)))
|
|
offset += 2
|
|
copy(dest[offset:], []byte(p.Web6))
|
|
offset += uint32(len(p.Web6))
|
|
|
|
// Write Web7 as 16-bit length-prefixed string
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(len(p.Web7)))
|
|
offset += 2
|
|
copy(dest[offset:], []byte(p.Web7))
|
|
offset += uint32(len(p.Web7))
|
|
|
|
// Write Web8 as 16-bit length-prefixed string
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(len(p.Web8)))
|
|
offset += 2
|
|
copy(dest[offset:], []byte(p.Web8))
|
|
offset += uint32(len(p.Web8))
|
|
|
|
// Write Web9 as 16-bit length-prefixed string
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(len(p.Web9)))
|
|
offset += 2
|
|
copy(dest[offset:], []byte(p.Web9))
|
|
offset += uint32(len(p.Web9))
|
|
|
|
// Write Unknown12
|
|
dest[offset] = byte(p.Unknown12)
|
|
offset++
|
|
|
|
// Write Lvl90NumClassItems
|
|
dest[offset] = byte(p.Lvl90NumClassItems)
|
|
offset++
|
|
|
|
// Write Lvl90ClassItems array (dynamic size)
|
|
for _, elem := range p.Lvl90ClassItems {
|
|
dest[offset] = elem.ClassId
|
|
offset++
|
|
dest[offset] = elem.NumItems
|
|
offset++
|
|
// Write nested StartingItems array
|
|
for _, nestedElem := range elem.StartingItems {
|
|
binary.LittleEndian.PutUint32(dest[offset:], nestedElem.ModelId)
|
|
offset += 4
|
|
dest[offset] = nestedElem.SlotId
|
|
offset++
|
|
dest[offset] = nestedElem.UseColor
|
|
offset++
|
|
dest[offset] = nestedElem.UseHighlightColor
|
|
offset++
|
|
binary.LittleEndian.PutUint32(dest[offset:], nestedElem.ModelColor.ToUint32())
|
|
offset += 4
|
|
binary.LittleEndian.PutUint32(dest[offset:], nestedElem.ModelHighlightColor.ToUint32())
|
|
offset += 4
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// Write Unknown13 array
|
|
for i := 0; i < 5; i++ {
|
|
dest[offset] = p.Unknown13[i]
|
|
offset++
|
|
}
|
|
|
|
return offset
|
|
}
|
|
|
|
// Size returns the serialized size of the packet
|
|
func (p *LSLoginReplyMsgV57080) Size() uint32 {
|
|
size := uint32(0)
|
|
|
|
size += 1
|
|
|
|
size += 2 + uint32(len(p.Unknown))
|
|
|
|
size += 1
|
|
|
|
size += 4
|
|
|
|
size += 8
|
|
|
|
size += 4
|
|
|
|
size += 2 + uint32(len(p.Unknown3))
|
|
|
|
size += 1
|
|
|
|
size += 1
|
|
|
|
size += 1
|
|
|
|
size += 2
|
|
|
|
size += 5
|
|
|
|
size += 4
|
|
|
|
size += 4
|
|
|
|
size += 1
|
|
|
|
size += 3
|
|
|
|
size += 1
|
|
|
|
size += 1
|
|
|
|
size += 1
|
|
|
|
// Dynamic array: ClassItems
|
|
for _, elem := range p.ClassItems {
|
|
_ = elem // Avoid unused variable warning
|
|
size += 1
|
|
size += 1
|
|
// Nested array: StartingItems
|
|
for _, nestedElem := range elem.StartingItems {
|
|
_ = nestedElem // Avoid unused variable
|
|
size += 4
|
|
size += 1
|
|
size += 1
|
|
size += 1
|
|
size += 4
|
|
size += 4
|
|
|
|
}
|
|
|
|
}
|
|
|
|
size += 1
|
|
|
|
// Dynamic array: UnknownArray2
|
|
for _, elem := range p.UnknownArray2 {
|
|
_ = elem // Avoid unused variable warning
|
|
size += 4
|
|
|
|
}
|
|
|
|
size += 4
|
|
|
|
size += 4
|
|
|
|
size += 4
|
|
|
|
size += 4
|
|
|
|
size += 2 + uint32(len(p.Password))
|
|
|
|
size += 2 + uint32(len(p.Username))
|
|
|
|
size += 2 + uint32(len(p.Service))
|
|
|
|
size += 2 + uint32(len(p.Web1))
|
|
|
|
size += 2 + uint32(len(p.Web2))
|
|
|
|
size += 2 + uint32(len(p.Web3))
|
|
|
|
size += 2 + uint32(len(p.Web4))
|
|
|
|
size += 2 + uint32(len(p.Web5))
|
|
|
|
size += 2 + uint32(len(p.Web6))
|
|
|
|
size += 2 + uint32(len(p.Web7))
|
|
|
|
size += 2 + uint32(len(p.Web8))
|
|
|
|
size += 2 + uint32(len(p.Web9))
|
|
|
|
size += 1
|
|
|
|
size += 1
|
|
|
|
// Dynamic array: Lvl90ClassItems
|
|
for _, elem := range p.Lvl90ClassItems {
|
|
_ = elem // Avoid unused variable warning
|
|
size += 1
|
|
size += 1
|
|
// Nested array: StartingItems
|
|
for _, nestedElem := range elem.StartingItems {
|
|
_ = nestedElem // Avoid unused variable
|
|
size += 4
|
|
size += 1
|
|
size += 1
|
|
size += 1
|
|
size += 4
|
|
size += 4
|
|
|
|
}
|
|
|
|
}
|
|
|
|
size += 5
|
|
|
|
return size
|
|
}
|
|
|
|
// LSLoginReplyMsgV60100 represents packet structure for OP_LoginReplyMsg
|
|
type LSLoginReplyMsgV60100 struct {
|
|
LoginResponse uint8 `eq2:"login_response"`
|
|
Unknown string `eq2:"unknown,type:str16"` // TODO: Identify purpose
|
|
ParentalControlFlag uint8 `eq2:"parental_control_flag"`
|
|
ParentalControlTimer uint32 `eq2:"parental_control_timer"`
|
|
Unknown2 [8]uint8 `eq2:"unknown2,size:8"` // TODO: Identify purpose
|
|
AccountId uint32 `eq2:"account_id"`
|
|
Unknown3 string `eq2:"unknown3,type:str16"` // TODO: Identify purpose
|
|
ResetAppearance uint8 `eq2:"reset_appearance"`
|
|
DoNotForceSoga uint8 `eq2:"do_not_force_soga"`
|
|
Unknown5 int64 `eq2:"unknown5"` // TODO: Identify purpose
|
|
Unknown7 uint32 `eq2:"unknown7"` // TODO: Identify purpose
|
|
Unknown7a uint16 `eq2:"unknown7a"` // TODO: Identify purpose
|
|
RaceUnknown uint8 `eq2:"race_unknown"`
|
|
Unknown8 [3]uint8 `eq2:"unknown8,size:3"` // TODO: Identify purpose
|
|
Unknown9 [3]uint8 `eq2:"unknown9,size:3"` // TODO: Identify purpose
|
|
Unknown10 uint8 `eq2:"unknown10"` // TODO: Identify purpose
|
|
NumClassItems uint8 `eq2:"num_class_items,ifSet:unknown10"`
|
|
ClassItems []struct {
|
|
ClassId uint8 `eq2:"class_id"`
|
|
NumItems uint8 `eq2:"num_items"`
|
|
StartingItems []struct {
|
|
ModelId uint32 `eq2:"model_id"`
|
|
SlotId uint8 `eq2:"slot_id"`
|
|
UseColor uint8 `eq2:"use_color"`
|
|
UseHighlightColor uint8 `eq2:"use_highlight_color"`
|
|
ModelColor types.Color `eq2:"model_color"`
|
|
ModelHighlightColor types.Color `eq2:"model_highlight_color"`
|
|
} `eq2:"starting_items"`
|
|
} `eq2:"class_items,sizeVar:num_class_items,ifSet:unknown10"`
|
|
UnknownArray2Size uint8 `eq2:"unknown_array2_size"` // TODO: Identify purpose
|
|
UnknownArray2 []struct {
|
|
Array2Unknown uint32 `eq2:"array2_unknown"`
|
|
} `eq2:"unknown_array2,sizeVar:unknown_array2_size"`
|
|
Unknown11 uint32 `eq2:"unknown11"` // TODO: Identify purpose
|
|
SubLevel uint32 `eq2:"sub_level"`
|
|
RaceFlag uint32 `eq2:"race_flag"`
|
|
ClassFlag uint32 `eq2:"class_flag"`
|
|
Password string `eq2:"password,type:str16"`
|
|
Username string `eq2:"username,type:str16"`
|
|
Service string `eq2:"service,type:str16"`
|
|
Unknown12 uint8 `eq2:"unknown12"` // TODO: Identify purpose
|
|
Lvl90NumClassItems uint8 `eq2:"lvl90_num_class_items,ifSet:unknown12"`
|
|
Lvl90ClassItems []struct {
|
|
ClassId uint8 `eq2:"class_id"`
|
|
NumItems uint8 `eq2:"num_items"`
|
|
StartingItems []struct {
|
|
ModelId uint32 `eq2:"model_id"`
|
|
SlotId uint8 `eq2:"slot_id"`
|
|
UseColor uint8 `eq2:"use_color"`
|
|
UseHighlightColor uint8 `eq2:"use_highlight_color"`
|
|
ModelColor types.Color `eq2:"model_color"`
|
|
ModelHighlightColor types.Color `eq2:"model_highlight_color"`
|
|
} `eq2:"starting_items"`
|
|
} `eq2:"lvl90_class_items,sizeVar:lvl90_num_class_items,ifSet:unknown12"`
|
|
Unknown13 uint8 `eq2:"unknown13"` // TODO: Identify purpose
|
|
TimeLockedNumClassItems uint8 `eq2:"time_locked_num_class_items,ifSet:unknown13"`
|
|
TimeLockedClassItems []struct {
|
|
ClassId uint8 `eq2:"class_id"`
|
|
NumItems uint8 `eq2:"num_items"`
|
|
StartingItems []struct {
|
|
ModelId uint32 `eq2:"model_id"`
|
|
SlotId uint8 `eq2:"slot_id"`
|
|
UseColor uint8 `eq2:"use_color"`
|
|
UseHighlightColor uint8 `eq2:"use_highlight_color"`
|
|
ModelColor types.Color `eq2:"model_color"`
|
|
ModelHighlightColor types.Color `eq2:"model_highlight_color"`
|
|
} `eq2:"starting_items"`
|
|
} `eq2:"time_locked_class_items,sizeVar:time_locked_num_class_items,ifSet:unknown13"`
|
|
Unknown14 [13]uint8 `eq2:"unknown14,size:13"` // TODO: Identify purpose
|
|
}
|
|
|
|
// Serialize writes the packet data to the provided buffer
|
|
func (p *LSLoginReplyMsgV60100) Serialize(dest []byte) uint32 {
|
|
offset := uint32(0)
|
|
|
|
// Write LoginResponse
|
|
dest[offset] = byte(p.LoginResponse)
|
|
offset++
|
|
|
|
// Write Unknown as 16-bit length-prefixed string
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(len(p.Unknown)))
|
|
offset += 2
|
|
copy(dest[offset:], []byte(p.Unknown))
|
|
offset += uint32(len(p.Unknown))
|
|
|
|
// Write ParentalControlFlag
|
|
dest[offset] = byte(p.ParentalControlFlag)
|
|
offset++
|
|
|
|
// Write ParentalControlTimer
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.ParentalControlTimer))
|
|
offset += 4
|
|
|
|
// Write Unknown2 array
|
|
for i := 0; i < 8; i++ {
|
|
dest[offset] = p.Unknown2[i]
|
|
offset++
|
|
}
|
|
|
|
// Write AccountId
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.AccountId))
|
|
offset += 4
|
|
|
|
// Write Unknown3 as 16-bit length-prefixed string
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(len(p.Unknown3)))
|
|
offset += 2
|
|
copy(dest[offset:], []byte(p.Unknown3))
|
|
offset += uint32(len(p.Unknown3))
|
|
|
|
// Write ResetAppearance
|
|
dest[offset] = byte(p.ResetAppearance)
|
|
offset++
|
|
|
|
// Write DoNotForceSoga
|
|
dest[offset] = byte(p.DoNotForceSoga)
|
|
offset++
|
|
|
|
// Write Unknown5
|
|
binary.LittleEndian.PutUint64(dest[offset:], uint64(p.Unknown5))
|
|
offset += 8
|
|
|
|
// Write Unknown7
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.Unknown7))
|
|
offset += 4
|
|
|
|
// Write Unknown7a
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(p.Unknown7a))
|
|
offset += 2
|
|
|
|
// Write RaceUnknown
|
|
dest[offset] = byte(p.RaceUnknown)
|
|
offset++
|
|
|
|
// Write Unknown8 array
|
|
for i := 0; i < 3; i++ {
|
|
dest[offset] = p.Unknown8[i]
|
|
offset++
|
|
}
|
|
|
|
// Write Unknown9 array
|
|
for i := 0; i < 3; i++ {
|
|
dest[offset] = p.Unknown9[i]
|
|
offset++
|
|
}
|
|
|
|
// Write Unknown10
|
|
dest[offset] = byte(p.Unknown10)
|
|
offset++
|
|
|
|
// Write NumClassItems
|
|
dest[offset] = byte(p.NumClassItems)
|
|
offset++
|
|
|
|
// Write ClassItems array (dynamic size)
|
|
for _, elem := range p.ClassItems {
|
|
dest[offset] = elem.ClassId
|
|
offset++
|
|
dest[offset] = elem.NumItems
|
|
offset++
|
|
// Write nested StartingItems array
|
|
for _, nestedElem := range elem.StartingItems {
|
|
binary.LittleEndian.PutUint32(dest[offset:], nestedElem.ModelId)
|
|
offset += 4
|
|
dest[offset] = nestedElem.SlotId
|
|
offset++
|
|
dest[offset] = nestedElem.UseColor
|
|
offset++
|
|
dest[offset] = nestedElem.UseHighlightColor
|
|
offset++
|
|
binary.LittleEndian.PutUint32(dest[offset:], nestedElem.ModelColor.ToUint32())
|
|
offset += 4
|
|
binary.LittleEndian.PutUint32(dest[offset:], nestedElem.ModelHighlightColor.ToUint32())
|
|
offset += 4
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// Write UnknownArray2Size
|
|
dest[offset] = byte(p.UnknownArray2Size)
|
|
offset++
|
|
|
|
// Write UnknownArray2 array (dynamic size)
|
|
for _, elem := range p.UnknownArray2 {
|
|
binary.LittleEndian.PutUint32(dest[offset:], elem.Array2Unknown)
|
|
offset += 4
|
|
|
|
}
|
|
|
|
// Write Unknown11
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.Unknown11))
|
|
offset += 4
|
|
|
|
// Write SubLevel
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.SubLevel))
|
|
offset += 4
|
|
|
|
// Write RaceFlag
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.RaceFlag))
|
|
offset += 4
|
|
|
|
// Write ClassFlag
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.ClassFlag))
|
|
offset += 4
|
|
|
|
// Write Password as 16-bit length-prefixed string
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(len(p.Password)))
|
|
offset += 2
|
|
copy(dest[offset:], []byte(p.Password))
|
|
offset += uint32(len(p.Password))
|
|
|
|
// Write Username as 16-bit length-prefixed string
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(len(p.Username)))
|
|
offset += 2
|
|
copy(dest[offset:], []byte(p.Username))
|
|
offset += uint32(len(p.Username))
|
|
|
|
// Write Service as 16-bit length-prefixed string
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(len(p.Service)))
|
|
offset += 2
|
|
copy(dest[offset:], []byte(p.Service))
|
|
offset += uint32(len(p.Service))
|
|
|
|
// Write Unknown12
|
|
dest[offset] = byte(p.Unknown12)
|
|
offset++
|
|
|
|
// Write Lvl90NumClassItems
|
|
dest[offset] = byte(p.Lvl90NumClassItems)
|
|
offset++
|
|
|
|
// Write Lvl90ClassItems array (dynamic size)
|
|
for _, elem := range p.Lvl90ClassItems {
|
|
dest[offset] = elem.ClassId
|
|
offset++
|
|
dest[offset] = elem.NumItems
|
|
offset++
|
|
// Write nested StartingItems array
|
|
for _, nestedElem := range elem.StartingItems {
|
|
binary.LittleEndian.PutUint32(dest[offset:], nestedElem.ModelId)
|
|
offset += 4
|
|
dest[offset] = nestedElem.SlotId
|
|
offset++
|
|
dest[offset] = nestedElem.UseColor
|
|
offset++
|
|
dest[offset] = nestedElem.UseHighlightColor
|
|
offset++
|
|
binary.LittleEndian.PutUint32(dest[offset:], nestedElem.ModelColor.ToUint32())
|
|
offset += 4
|
|
binary.LittleEndian.PutUint32(dest[offset:], nestedElem.ModelHighlightColor.ToUint32())
|
|
offset += 4
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// Write Unknown13
|
|
dest[offset] = byte(p.Unknown13)
|
|
offset++
|
|
|
|
// Write TimeLockedNumClassItems
|
|
dest[offset] = byte(p.TimeLockedNumClassItems)
|
|
offset++
|
|
|
|
// Write TimeLockedClassItems array (dynamic size)
|
|
for _, elem := range p.TimeLockedClassItems {
|
|
dest[offset] = elem.ClassId
|
|
offset++
|
|
dest[offset] = elem.NumItems
|
|
offset++
|
|
// Write nested StartingItems array
|
|
for _, nestedElem := range elem.StartingItems {
|
|
binary.LittleEndian.PutUint32(dest[offset:], nestedElem.ModelId)
|
|
offset += 4
|
|
dest[offset] = nestedElem.SlotId
|
|
offset++
|
|
dest[offset] = nestedElem.UseColor
|
|
offset++
|
|
dest[offset] = nestedElem.UseHighlightColor
|
|
offset++
|
|
binary.LittleEndian.PutUint32(dest[offset:], nestedElem.ModelColor.ToUint32())
|
|
offset += 4
|
|
binary.LittleEndian.PutUint32(dest[offset:], nestedElem.ModelHighlightColor.ToUint32())
|
|
offset += 4
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// Write Unknown14 array
|
|
for i := 0; i < 13; i++ {
|
|
dest[offset] = p.Unknown14[i]
|
|
offset++
|
|
}
|
|
|
|
return offset
|
|
}
|
|
|
|
// Size returns the serialized size of the packet
|
|
func (p *LSLoginReplyMsgV60100) Size() uint32 {
|
|
size := uint32(0)
|
|
|
|
size += 1
|
|
|
|
size += 2 + uint32(len(p.Unknown))
|
|
|
|
size += 1
|
|
|
|
size += 4
|
|
|
|
size += 8
|
|
|
|
size += 4
|
|
|
|
size += 2 + uint32(len(p.Unknown3))
|
|
|
|
size += 1
|
|
|
|
size += 1
|
|
|
|
size += 8
|
|
|
|
size += 4
|
|
|
|
size += 2
|
|
|
|
size += 1
|
|
|
|
size += 3
|
|
|
|
size += 3
|
|
|
|
size += 1
|
|
|
|
size += 1
|
|
|
|
// Dynamic array: ClassItems
|
|
for _, elem := range p.ClassItems {
|
|
_ = elem // Avoid unused variable warning
|
|
size += 1
|
|
size += 1
|
|
// Nested array: StartingItems
|
|
for _, nestedElem := range elem.StartingItems {
|
|
_ = nestedElem // Avoid unused variable
|
|
size += 4
|
|
size += 1
|
|
size += 1
|
|
size += 1
|
|
size += 4
|
|
size += 4
|
|
|
|
}
|
|
|
|
}
|
|
|
|
size += 1
|
|
|
|
// Dynamic array: UnknownArray2
|
|
for _, elem := range p.UnknownArray2 {
|
|
_ = elem // Avoid unused variable warning
|
|
size += 4
|
|
|
|
}
|
|
|
|
size += 4
|
|
|
|
size += 4
|
|
|
|
size += 4
|
|
|
|
size += 4
|
|
|
|
size += 2 + uint32(len(p.Password))
|
|
|
|
size += 2 + uint32(len(p.Username))
|
|
|
|
size += 2 + uint32(len(p.Service))
|
|
|
|
size += 1
|
|
|
|
size += 1
|
|
|
|
// Dynamic array: Lvl90ClassItems
|
|
for _, elem := range p.Lvl90ClassItems {
|
|
_ = elem // Avoid unused variable warning
|
|
size += 1
|
|
size += 1
|
|
// Nested array: StartingItems
|
|
for _, nestedElem := range elem.StartingItems {
|
|
_ = nestedElem // Avoid unused variable
|
|
size += 4
|
|
size += 1
|
|
size += 1
|
|
size += 1
|
|
size += 4
|
|
size += 4
|
|
|
|
}
|
|
|
|
}
|
|
|
|
size += 1
|
|
|
|
size += 1
|
|
|
|
// Dynamic array: TimeLockedClassItems
|
|
for _, elem := range p.TimeLockedClassItems {
|
|
_ = elem // Avoid unused variable warning
|
|
size += 1
|
|
size += 1
|
|
// Nested array: StartingItems
|
|
for _, nestedElem := range elem.StartingItems {
|
|
_ = nestedElem // Avoid unused variable
|
|
size += 4
|
|
size += 1
|
|
size += 1
|
|
size += 1
|
|
size += 4
|
|
size += 4
|
|
|
|
}
|
|
|
|
}
|
|
|
|
size += 13
|
|
|
|
return size
|
|
}
|
|
|
|
// LSLoginReplyMsgV63181 represents packet structure for OP_LoginReplyMsg
|
|
type LSLoginReplyMsgV63181 struct {
|
|
LoginResponse uint8 `eq2:"login_response"`
|
|
Unknown string `eq2:"unknown,type:str16"` // TODO: Identify purpose
|
|
ParentalControlFlag uint8 `eq2:"parental_control_flag"`
|
|
ParentalControlTimer uint32 `eq2:"parental_control_timer"`
|
|
Unknown2 [8]uint8 `eq2:"unknown2,size:8"` // TODO: Identify purpose
|
|
AccountId uint32 `eq2:"account_id"`
|
|
Unknown3 string `eq2:"unknown3,type:str16"` // TODO: Identify purpose
|
|
ResetAppearance uint8 `eq2:"reset_appearance"`
|
|
DoNotForceSoga uint8 `eq2:"do_not_force_soga"`
|
|
Unknown4 uint8 `eq2:"unknown4"` // TODO: Identify purpose
|
|
Unknown5 uint16 `eq2:"unknown5"` // TODO: Identify purpose
|
|
Unknown6 [5]uint8 `eq2:"unknown6,size:5"` // TODO: Identify purpose
|
|
Unknown6a [8]uint8 `eq2:"unknown6a,size:8"` // TODO: Identify purpose
|
|
Unknown7 uint32 `eq2:"unknown7"` // TODO: Identify purpose
|
|
Unknown7a uint16 `eq2:"unknown7a"` // TODO: Identify purpose
|
|
RaceUnknown uint8 `eq2:"race_unknown"`
|
|
Unknown8 [3]uint8 `eq2:"unknown8,size:3"` // TODO: Identify purpose
|
|
Unknown9 [3]uint8 `eq2:"unknown9,size:3"` // TODO: Identify purpose
|
|
Unknown10 uint8 `eq2:"unknown10"` // TODO: Identify purpose
|
|
NumClassItems uint8 `eq2:"num_class_items,ifSet:unknown10"`
|
|
ClassItems []struct {
|
|
ClassId uint8 `eq2:"class_id"`
|
|
NumItems uint8 `eq2:"num_items"`
|
|
StartingItems []struct {
|
|
ModelId uint32 `eq2:"model_id"`
|
|
SlotId uint8 `eq2:"slot_id"`
|
|
UseColor uint8 `eq2:"use_color"`
|
|
UseHighlightColor uint8 `eq2:"use_highlight_color"`
|
|
ModelColor types.Color `eq2:"model_color"`
|
|
ModelHighlightColor types.Color `eq2:"model_highlight_color"`
|
|
} `eq2:"starting_items"`
|
|
} `eq2:"class_items,sizeVar:num_class_items,ifSet:unknown10"`
|
|
UnknownArray2Size uint8 `eq2:"unknown_array2_size"` // TODO: Identify purpose
|
|
UnknownArray2 []struct {
|
|
Array2Unknown uint32 `eq2:"array2_unknown"`
|
|
} `eq2:"unknown_array2,sizeVar:unknown_array2_size"`
|
|
Unknown11 uint32 `eq2:"unknown11"` // TODO: Identify purpose
|
|
SubLevel uint32 `eq2:"sub_level"`
|
|
RaceFlag uint32 `eq2:"race_flag"`
|
|
ClassFlag uint32 `eq2:"class_flag"`
|
|
Password string `eq2:"password,type:str16"`
|
|
Username string `eq2:"username,type:str16"`
|
|
Service string `eq2:"service,type:str16"`
|
|
Unknown12 uint8 `eq2:"unknown12"` // TODO: Identify purpose
|
|
Lvl90NumClassItems uint8 `eq2:"lvl90_num_class_items,ifSet:unknown12"`
|
|
Lvl90ClassItems []struct {
|
|
ClassId uint8 `eq2:"class_id"`
|
|
NumItems uint8 `eq2:"num_items"`
|
|
StartingItems []struct {
|
|
ModelId uint32 `eq2:"model_id"`
|
|
SlotId uint8 `eq2:"slot_id"`
|
|
UseColor uint8 `eq2:"use_color"`
|
|
UseHighlightColor uint8 `eq2:"use_highlight_color"`
|
|
ModelColor types.Color `eq2:"model_color"`
|
|
ModelHighlightColor types.Color `eq2:"model_highlight_color"`
|
|
} `eq2:"starting_items"`
|
|
} `eq2:"lvl90_class_items,sizeVar:lvl90_num_class_items,ifSet:unknown12"`
|
|
Unknown13 uint8 `eq2:"unknown13"` // TODO: Identify purpose
|
|
TimeLockedNumClassItems uint8 `eq2:"time_locked_num_class_items,ifSet:unknown13"`
|
|
TimeLockedClassItems []struct {
|
|
ClassId uint8 `eq2:"class_id"`
|
|
NumItems uint8 `eq2:"num_items"`
|
|
StartingItems []struct {
|
|
ModelId uint32 `eq2:"model_id"`
|
|
SlotId uint8 `eq2:"slot_id"`
|
|
UseColor uint8 `eq2:"use_color"`
|
|
UseHighlightColor uint8 `eq2:"use_highlight_color"`
|
|
ModelColor types.Color `eq2:"model_color"`
|
|
ModelHighlightColor types.Color `eq2:"model_highlight_color"`
|
|
} `eq2:"starting_items"`
|
|
} `eq2:"time_locked_class_items,sizeVar:time_locked_num_class_items,ifSet:unknown13"`
|
|
Unknown14 [9]uint8 `eq2:"unknown14,size:9"` // TODO: Identify purpose
|
|
}
|
|
|
|
// Serialize writes the packet data to the provided buffer
|
|
func (p *LSLoginReplyMsgV63181) Serialize(dest []byte) uint32 {
|
|
offset := uint32(0)
|
|
|
|
// Write LoginResponse
|
|
dest[offset] = byte(p.LoginResponse)
|
|
offset++
|
|
|
|
// Write Unknown as 16-bit length-prefixed string
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(len(p.Unknown)))
|
|
offset += 2
|
|
copy(dest[offset:], []byte(p.Unknown))
|
|
offset += uint32(len(p.Unknown))
|
|
|
|
// Write ParentalControlFlag
|
|
dest[offset] = byte(p.ParentalControlFlag)
|
|
offset++
|
|
|
|
// Write ParentalControlTimer
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.ParentalControlTimer))
|
|
offset += 4
|
|
|
|
// Write Unknown2 array
|
|
for i := 0; i < 8; i++ {
|
|
dest[offset] = p.Unknown2[i]
|
|
offset++
|
|
}
|
|
|
|
// Write AccountId
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.AccountId))
|
|
offset += 4
|
|
|
|
// Write Unknown3 as 16-bit length-prefixed string
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(len(p.Unknown3)))
|
|
offset += 2
|
|
copy(dest[offset:], []byte(p.Unknown3))
|
|
offset += uint32(len(p.Unknown3))
|
|
|
|
// Write ResetAppearance
|
|
dest[offset] = byte(p.ResetAppearance)
|
|
offset++
|
|
|
|
// Write DoNotForceSoga
|
|
dest[offset] = byte(p.DoNotForceSoga)
|
|
offset++
|
|
|
|
// Write Unknown4
|
|
dest[offset] = byte(p.Unknown4)
|
|
offset++
|
|
|
|
// Write Unknown5
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(p.Unknown5))
|
|
offset += 2
|
|
|
|
// Write Unknown6 array
|
|
for i := 0; i < 5; i++ {
|
|
dest[offset] = p.Unknown6[i]
|
|
offset++
|
|
}
|
|
|
|
// Write Unknown6a array
|
|
for i := 0; i < 8; i++ {
|
|
dest[offset] = p.Unknown6a[i]
|
|
offset++
|
|
}
|
|
|
|
// Write Unknown7
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.Unknown7))
|
|
offset += 4
|
|
|
|
// Write Unknown7a
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(p.Unknown7a))
|
|
offset += 2
|
|
|
|
// Write RaceUnknown
|
|
dest[offset] = byte(p.RaceUnknown)
|
|
offset++
|
|
|
|
// Write Unknown8 array
|
|
for i := 0; i < 3; i++ {
|
|
dest[offset] = p.Unknown8[i]
|
|
offset++
|
|
}
|
|
|
|
// Write Unknown9 array
|
|
for i := 0; i < 3; i++ {
|
|
dest[offset] = p.Unknown9[i]
|
|
offset++
|
|
}
|
|
|
|
// Write Unknown10
|
|
dest[offset] = byte(p.Unknown10)
|
|
offset++
|
|
|
|
// Write NumClassItems
|
|
dest[offset] = byte(p.NumClassItems)
|
|
offset++
|
|
|
|
// Write ClassItems array (dynamic size)
|
|
for _, elem := range p.ClassItems {
|
|
dest[offset] = elem.ClassId
|
|
offset++
|
|
dest[offset] = elem.NumItems
|
|
offset++
|
|
// Write nested StartingItems array
|
|
for _, nestedElem := range elem.StartingItems {
|
|
binary.LittleEndian.PutUint32(dest[offset:], nestedElem.ModelId)
|
|
offset += 4
|
|
dest[offset] = nestedElem.SlotId
|
|
offset++
|
|
dest[offset] = nestedElem.UseColor
|
|
offset++
|
|
dest[offset] = nestedElem.UseHighlightColor
|
|
offset++
|
|
binary.LittleEndian.PutUint32(dest[offset:], nestedElem.ModelColor.ToUint32())
|
|
offset += 4
|
|
binary.LittleEndian.PutUint32(dest[offset:], nestedElem.ModelHighlightColor.ToUint32())
|
|
offset += 4
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// Write UnknownArray2Size
|
|
dest[offset] = byte(p.UnknownArray2Size)
|
|
offset++
|
|
|
|
// Write UnknownArray2 array (dynamic size)
|
|
for _, elem := range p.UnknownArray2 {
|
|
binary.LittleEndian.PutUint32(dest[offset:], elem.Array2Unknown)
|
|
offset += 4
|
|
|
|
}
|
|
|
|
// Write Unknown11
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.Unknown11))
|
|
offset += 4
|
|
|
|
// Write SubLevel
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.SubLevel))
|
|
offset += 4
|
|
|
|
// Write RaceFlag
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.RaceFlag))
|
|
offset += 4
|
|
|
|
// Write ClassFlag
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.ClassFlag))
|
|
offset += 4
|
|
|
|
// Write Password as 16-bit length-prefixed string
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(len(p.Password)))
|
|
offset += 2
|
|
copy(dest[offset:], []byte(p.Password))
|
|
offset += uint32(len(p.Password))
|
|
|
|
// Write Username as 16-bit length-prefixed string
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(len(p.Username)))
|
|
offset += 2
|
|
copy(dest[offset:], []byte(p.Username))
|
|
offset += uint32(len(p.Username))
|
|
|
|
// Write Service as 16-bit length-prefixed string
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(len(p.Service)))
|
|
offset += 2
|
|
copy(dest[offset:], []byte(p.Service))
|
|
offset += uint32(len(p.Service))
|
|
|
|
// Write Unknown12
|
|
dest[offset] = byte(p.Unknown12)
|
|
offset++
|
|
|
|
// Write Lvl90NumClassItems
|
|
dest[offset] = byte(p.Lvl90NumClassItems)
|
|
offset++
|
|
|
|
// Write Lvl90ClassItems array (dynamic size)
|
|
for _, elem := range p.Lvl90ClassItems {
|
|
dest[offset] = elem.ClassId
|
|
offset++
|
|
dest[offset] = elem.NumItems
|
|
offset++
|
|
// Write nested StartingItems array
|
|
for _, nestedElem := range elem.StartingItems {
|
|
binary.LittleEndian.PutUint32(dest[offset:], nestedElem.ModelId)
|
|
offset += 4
|
|
dest[offset] = nestedElem.SlotId
|
|
offset++
|
|
dest[offset] = nestedElem.UseColor
|
|
offset++
|
|
dest[offset] = nestedElem.UseHighlightColor
|
|
offset++
|
|
binary.LittleEndian.PutUint32(dest[offset:], nestedElem.ModelColor.ToUint32())
|
|
offset += 4
|
|
binary.LittleEndian.PutUint32(dest[offset:], nestedElem.ModelHighlightColor.ToUint32())
|
|
offset += 4
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// Write Unknown13
|
|
dest[offset] = byte(p.Unknown13)
|
|
offset++
|
|
|
|
// Write TimeLockedNumClassItems
|
|
dest[offset] = byte(p.TimeLockedNumClassItems)
|
|
offset++
|
|
|
|
// Write TimeLockedClassItems array (dynamic size)
|
|
for _, elem := range p.TimeLockedClassItems {
|
|
dest[offset] = elem.ClassId
|
|
offset++
|
|
dest[offset] = elem.NumItems
|
|
offset++
|
|
// Write nested StartingItems array
|
|
for _, nestedElem := range elem.StartingItems {
|
|
binary.LittleEndian.PutUint32(dest[offset:], nestedElem.ModelId)
|
|
offset += 4
|
|
dest[offset] = nestedElem.SlotId
|
|
offset++
|
|
dest[offset] = nestedElem.UseColor
|
|
offset++
|
|
dest[offset] = nestedElem.UseHighlightColor
|
|
offset++
|
|
binary.LittleEndian.PutUint32(dest[offset:], nestedElem.ModelColor.ToUint32())
|
|
offset += 4
|
|
binary.LittleEndian.PutUint32(dest[offset:], nestedElem.ModelHighlightColor.ToUint32())
|
|
offset += 4
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// Write Unknown14 array
|
|
for i := 0; i < 9; i++ {
|
|
dest[offset] = p.Unknown14[i]
|
|
offset++
|
|
}
|
|
|
|
return offset
|
|
}
|
|
|
|
// Size returns the serialized size of the packet
|
|
func (p *LSLoginReplyMsgV63181) Size() uint32 {
|
|
size := uint32(0)
|
|
|
|
size += 1
|
|
|
|
size += 2 + uint32(len(p.Unknown))
|
|
|
|
size += 1
|
|
|
|
size += 4
|
|
|
|
size += 8
|
|
|
|
size += 4
|
|
|
|
size += 2 + uint32(len(p.Unknown3))
|
|
|
|
size += 1
|
|
|
|
size += 1
|
|
|
|
size += 1
|
|
|
|
size += 2
|
|
|
|
size += 5
|
|
|
|
size += 8
|
|
|
|
size += 4
|
|
|
|
size += 2
|
|
|
|
size += 1
|
|
|
|
size += 3
|
|
|
|
size += 3
|
|
|
|
size += 1
|
|
|
|
size += 1
|
|
|
|
// Dynamic array: ClassItems
|
|
for _, elem := range p.ClassItems {
|
|
_ = elem // Avoid unused variable warning
|
|
size += 1
|
|
size += 1
|
|
// Nested array: StartingItems
|
|
for _, nestedElem := range elem.StartingItems {
|
|
_ = nestedElem // Avoid unused variable
|
|
size += 4
|
|
size += 1
|
|
size += 1
|
|
size += 1
|
|
size += 4
|
|
size += 4
|
|
|
|
}
|
|
|
|
}
|
|
|
|
size += 1
|
|
|
|
// Dynamic array: UnknownArray2
|
|
for _, elem := range p.UnknownArray2 {
|
|
_ = elem // Avoid unused variable warning
|
|
size += 4
|
|
|
|
}
|
|
|
|
size += 4
|
|
|
|
size += 4
|
|
|
|
size += 4
|
|
|
|
size += 4
|
|
|
|
size += 2 + uint32(len(p.Password))
|
|
|
|
size += 2 + uint32(len(p.Username))
|
|
|
|
size += 2 + uint32(len(p.Service))
|
|
|
|
size += 1
|
|
|
|
size += 1
|
|
|
|
// Dynamic array: Lvl90ClassItems
|
|
for _, elem := range p.Lvl90ClassItems {
|
|
_ = elem // Avoid unused variable warning
|
|
size += 1
|
|
size += 1
|
|
// Nested array: StartingItems
|
|
for _, nestedElem := range elem.StartingItems {
|
|
_ = nestedElem // Avoid unused variable
|
|
size += 4
|
|
size += 1
|
|
size += 1
|
|
size += 1
|
|
size += 4
|
|
size += 4
|
|
|
|
}
|
|
|
|
}
|
|
|
|
size += 1
|
|
|
|
size += 1
|
|
|
|
// Dynamic array: TimeLockedClassItems
|
|
for _, elem := range p.TimeLockedClassItems {
|
|
_ = elem // Avoid unused variable warning
|
|
size += 1
|
|
size += 1
|
|
// Nested array: StartingItems
|
|
for _, nestedElem := range elem.StartingItems {
|
|
_ = nestedElem // Avoid unused variable
|
|
size += 4
|
|
size += 1
|
|
size += 1
|
|
size += 1
|
|
size += 4
|
|
size += 4
|
|
|
|
}
|
|
|
|
}
|
|
|
|
size += 9
|
|
|
|
return size
|
|
}
|
|
|
|
// LSLoginReplyMsgV65534 represents packet structure for OP_LoginReplyMsg
|
|
type LSLoginReplyMsgV65534 struct {
|
|
LoginResponse uint8 `eq2:"login_response"`
|
|
WorldName string `eq2:"world_name,type:str16"`
|
|
ParentalControlFlag uint8 `eq2:"parental_control_flag"`
|
|
ParentalControlTimer int64 `eq2:"parental_control_timer"`
|
|
Unknown2 uint32 `eq2:"unknown2"` // TODO: Identify purpose
|
|
AccountId uint32 `eq2:"account_id"`
|
|
Unknown3 string `eq2:"unknown3,type:str16"` // TODO: Identify purpose
|
|
ResetAppearance uint8 `eq2:"reset_appearance"`
|
|
DoNotForceSoga uint8 `eq2:"do_not_force_soga"`
|
|
Unknown4 string `eq2:"unknown4,type:EQ2_32Bit_String"` // TODO: Identify purpose
|
|
Unknown7 string `eq2:"unknown7,type:EQ2_32Bit_String"` // TODO: Identify purpose
|
|
RaceUnknown uint32 `eq2:"race_unknown"`
|
|
Unknown8 uint8 `eq2:"unknown8"` // TODO: Identify purpose
|
|
Unknown10 uint8 `eq2:"unknown10"` // TODO: Identify purpose
|
|
NumClassItems uint8 `eq2:"num_class_items,ifSet:unknown10"`
|
|
ClassItems []struct {
|
|
ClassId uint8 `eq2:"class_id"`
|
|
NumItems uint8 `eq2:"num_items"`
|
|
StartingItems []struct {
|
|
ModelId uint32 `eq2:"model_id"`
|
|
SlotId uint8 `eq2:"slot_id"`
|
|
UseColor uint8 `eq2:"use_color"`
|
|
UseHighlightColor uint8 `eq2:"use_highlight_color"`
|
|
ModelColor types.Color `eq2:"model_color"`
|
|
ModelHighlightColor types.Color `eq2:"model_highlight_color"`
|
|
} `eq2:"starting_items"`
|
|
} `eq2:"class_items,sizeVar:num_class_items,ifSet:unknown10"`
|
|
UnknownArray2Size uint8 `eq2:"unknown_array2_size"` // TODO: Identify purpose
|
|
UnknownArray2 []struct {
|
|
Array2Unknown uint32 `eq2:"array2_unknown"`
|
|
} `eq2:"unknown_array2,sizeVar:unknown_array2_size,ifSet:unknown_array2_size"`
|
|
Unknown11 uint32 `eq2:"unknown11"` // TODO: Identify purpose
|
|
SubLevel uint32 `eq2:"sub_level"`
|
|
RaceFlag uint32 `eq2:"race_flag"`
|
|
ClassFlag uint32 `eq2:"class_flag"`
|
|
Password string `eq2:"password,type:str16"`
|
|
Username string `eq2:"username,type:str16"`
|
|
Service string `eq2:"service,type:str16"`
|
|
Unknown12 uint8 `eq2:"unknown12"` // TODO: Identify purpose
|
|
Lvl90NumClassItems uint8 `eq2:"lvl90_num_class_items,ifSet:unknown12"`
|
|
Lvl90ClassItems []struct {
|
|
ClassId uint8 `eq2:"class_id"`
|
|
NumItems uint8 `eq2:"num_items"`
|
|
StartingItems []struct {
|
|
ModelId uint32 `eq2:"model_id"`
|
|
SlotId uint8 `eq2:"slot_id"`
|
|
UseColor uint8 `eq2:"use_color"`
|
|
UseHighlightColor uint8 `eq2:"use_highlight_color"`
|
|
ModelColor types.Color `eq2:"model_color"`
|
|
ModelHighlightColor types.Color `eq2:"model_highlight_color"`
|
|
} `eq2:"starting_items"`
|
|
} `eq2:"lvl90_class_items,sizeVar:lvl90_num_class_items,ifSet:unknown12"`
|
|
Unknown13 uint8 `eq2:"unknown13"` // TODO: Identify purpose
|
|
TimeLockedNumClassItems uint8 `eq2:"time_locked_num_class_items,ifSet:unknown13"`
|
|
TimeLockedClassItems []struct {
|
|
ClassId uint8 `eq2:"class_id"`
|
|
NumItems uint8 `eq2:"num_items"`
|
|
StartingItems []struct {
|
|
ModelId uint32 `eq2:"model_id"`
|
|
SlotId uint8 `eq2:"slot_id"`
|
|
UseColor uint8 `eq2:"use_color"`
|
|
UseHighlightColor uint8 `eq2:"use_highlight_color"`
|
|
ModelColor types.Color `eq2:"model_color"`
|
|
ModelHighlightColor types.Color `eq2:"model_highlight_color"`
|
|
} `eq2:"starting_items"`
|
|
} `eq2:"time_locked_class_items,sizeVar:time_locked_num_class_items,ifSet:unknown13"`
|
|
Unknown14 [13]uint8 `eq2:"unknown14,size:13"` // TODO: Identify purpose
|
|
}
|
|
|
|
// Serialize writes the packet data to the provided buffer
|
|
func (p *LSLoginReplyMsgV65534) Serialize(dest []byte) uint32 {
|
|
offset := uint32(0)
|
|
|
|
// Write LoginResponse
|
|
dest[offset] = byte(p.LoginResponse)
|
|
offset++
|
|
|
|
// Write WorldName as 16-bit length-prefixed string
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(len(p.WorldName)))
|
|
offset += 2
|
|
copy(dest[offset:], []byte(p.WorldName))
|
|
offset += uint32(len(p.WorldName))
|
|
|
|
// Write ParentalControlFlag
|
|
dest[offset] = byte(p.ParentalControlFlag)
|
|
offset++
|
|
|
|
// Write ParentalControlTimer
|
|
binary.LittleEndian.PutUint64(dest[offset:], uint64(p.ParentalControlTimer))
|
|
offset += 8
|
|
|
|
// Write Unknown2
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.Unknown2))
|
|
offset += 4
|
|
|
|
// Write AccountId
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.AccountId))
|
|
offset += 4
|
|
|
|
// Write Unknown3 as 16-bit length-prefixed string
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(len(p.Unknown3)))
|
|
offset += 2
|
|
copy(dest[offset:], []byte(p.Unknown3))
|
|
offset += uint32(len(p.Unknown3))
|
|
|
|
// Write ResetAppearance
|
|
dest[offset] = byte(p.ResetAppearance)
|
|
offset++
|
|
|
|
// Write DoNotForceSoga
|
|
dest[offset] = byte(p.DoNotForceSoga)
|
|
offset++
|
|
|
|
// Write Unknown4 as 32-bit length-prefixed string
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(len(p.Unknown4)))
|
|
offset += 4
|
|
copy(dest[offset:], []byte(p.Unknown4))
|
|
offset += uint32(len(p.Unknown4))
|
|
|
|
// Write Unknown7 as 32-bit length-prefixed string
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(len(p.Unknown7)))
|
|
offset += 4
|
|
copy(dest[offset:], []byte(p.Unknown7))
|
|
offset += uint32(len(p.Unknown7))
|
|
|
|
// Write RaceUnknown
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.RaceUnknown))
|
|
offset += 4
|
|
|
|
// Write Unknown8
|
|
dest[offset] = byte(p.Unknown8)
|
|
offset++
|
|
|
|
// Write Unknown10
|
|
dest[offset] = byte(p.Unknown10)
|
|
offset++
|
|
|
|
// Write NumClassItems
|
|
dest[offset] = byte(p.NumClassItems)
|
|
offset++
|
|
|
|
// Write ClassItems array (dynamic size)
|
|
for _, elem := range p.ClassItems {
|
|
dest[offset] = elem.ClassId
|
|
offset++
|
|
dest[offset] = elem.NumItems
|
|
offset++
|
|
// Write nested StartingItems array
|
|
for _, nestedElem := range elem.StartingItems {
|
|
binary.LittleEndian.PutUint32(dest[offset:], nestedElem.ModelId)
|
|
offset += 4
|
|
dest[offset] = nestedElem.SlotId
|
|
offset++
|
|
dest[offset] = nestedElem.UseColor
|
|
offset++
|
|
dest[offset] = nestedElem.UseHighlightColor
|
|
offset++
|
|
binary.LittleEndian.PutUint32(dest[offset:], nestedElem.ModelColor.ToUint32())
|
|
offset += 4
|
|
binary.LittleEndian.PutUint32(dest[offset:], nestedElem.ModelHighlightColor.ToUint32())
|
|
offset += 4
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// Write UnknownArray2Size
|
|
dest[offset] = byte(p.UnknownArray2Size)
|
|
offset++
|
|
|
|
// Write UnknownArray2 array (dynamic size)
|
|
for _, elem := range p.UnknownArray2 {
|
|
binary.LittleEndian.PutUint32(dest[offset:], elem.Array2Unknown)
|
|
offset += 4
|
|
|
|
}
|
|
|
|
// Write Unknown11
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.Unknown11))
|
|
offset += 4
|
|
|
|
// Write SubLevel
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.SubLevel))
|
|
offset += 4
|
|
|
|
// Write RaceFlag
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.RaceFlag))
|
|
offset += 4
|
|
|
|
// Write ClassFlag
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.ClassFlag))
|
|
offset += 4
|
|
|
|
// Write Password as 16-bit length-prefixed string
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(len(p.Password)))
|
|
offset += 2
|
|
copy(dest[offset:], []byte(p.Password))
|
|
offset += uint32(len(p.Password))
|
|
|
|
// Write Username as 16-bit length-prefixed string
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(len(p.Username)))
|
|
offset += 2
|
|
copy(dest[offset:], []byte(p.Username))
|
|
offset += uint32(len(p.Username))
|
|
|
|
// Write Service as 16-bit length-prefixed string
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(len(p.Service)))
|
|
offset += 2
|
|
copy(dest[offset:], []byte(p.Service))
|
|
offset += uint32(len(p.Service))
|
|
|
|
// Write Unknown12
|
|
dest[offset] = byte(p.Unknown12)
|
|
offset++
|
|
|
|
// Write Lvl90NumClassItems
|
|
dest[offset] = byte(p.Lvl90NumClassItems)
|
|
offset++
|
|
|
|
// Write Lvl90ClassItems array (dynamic size)
|
|
for _, elem := range p.Lvl90ClassItems {
|
|
dest[offset] = elem.ClassId
|
|
offset++
|
|
dest[offset] = elem.NumItems
|
|
offset++
|
|
// Write nested StartingItems array
|
|
for _, nestedElem := range elem.StartingItems {
|
|
binary.LittleEndian.PutUint32(dest[offset:], nestedElem.ModelId)
|
|
offset += 4
|
|
dest[offset] = nestedElem.SlotId
|
|
offset++
|
|
dest[offset] = nestedElem.UseColor
|
|
offset++
|
|
dest[offset] = nestedElem.UseHighlightColor
|
|
offset++
|
|
binary.LittleEndian.PutUint32(dest[offset:], nestedElem.ModelColor.ToUint32())
|
|
offset += 4
|
|
binary.LittleEndian.PutUint32(dest[offset:], nestedElem.ModelHighlightColor.ToUint32())
|
|
offset += 4
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// Write Unknown13
|
|
dest[offset] = byte(p.Unknown13)
|
|
offset++
|
|
|
|
// Write TimeLockedNumClassItems
|
|
dest[offset] = byte(p.TimeLockedNumClassItems)
|
|
offset++
|
|
|
|
// Write TimeLockedClassItems array (dynamic size)
|
|
for _, elem := range p.TimeLockedClassItems {
|
|
dest[offset] = elem.ClassId
|
|
offset++
|
|
dest[offset] = elem.NumItems
|
|
offset++
|
|
// Write nested StartingItems array
|
|
for _, nestedElem := range elem.StartingItems {
|
|
binary.LittleEndian.PutUint32(dest[offset:], nestedElem.ModelId)
|
|
offset += 4
|
|
dest[offset] = nestedElem.SlotId
|
|
offset++
|
|
dest[offset] = nestedElem.UseColor
|
|
offset++
|
|
dest[offset] = nestedElem.UseHighlightColor
|
|
offset++
|
|
binary.LittleEndian.PutUint32(dest[offset:], nestedElem.ModelColor.ToUint32())
|
|
offset += 4
|
|
binary.LittleEndian.PutUint32(dest[offset:], nestedElem.ModelHighlightColor.ToUint32())
|
|
offset += 4
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// Write Unknown14 array
|
|
for i := 0; i < 13; i++ {
|
|
dest[offset] = p.Unknown14[i]
|
|
offset++
|
|
}
|
|
|
|
return offset
|
|
}
|
|
|
|
// Size returns the serialized size of the packet
|
|
func (p *LSLoginReplyMsgV65534) Size() uint32 {
|
|
size := uint32(0)
|
|
|
|
size += 1
|
|
|
|
size += 2 + uint32(len(p.WorldName))
|
|
|
|
size += 1
|
|
|
|
size += 8
|
|
|
|
size += 4
|
|
|
|
size += 4
|
|
|
|
size += 2 + uint32(len(p.Unknown3))
|
|
|
|
size += 1
|
|
|
|
size += 1
|
|
|
|
size += 4 + uint32(len(p.Unknown4))
|
|
|
|
size += 4 + uint32(len(p.Unknown7))
|
|
|
|
size += 4
|
|
|
|
size += 1
|
|
|
|
size += 1
|
|
|
|
size += 1
|
|
|
|
// Dynamic array: ClassItems
|
|
for _, elem := range p.ClassItems {
|
|
_ = elem // Avoid unused variable warning
|
|
size += 1
|
|
size += 1
|
|
// Nested array: StartingItems
|
|
for _, nestedElem := range elem.StartingItems {
|
|
_ = nestedElem // Avoid unused variable
|
|
size += 4
|
|
size += 1
|
|
size += 1
|
|
size += 1
|
|
size += 4
|
|
size += 4
|
|
|
|
}
|
|
|
|
}
|
|
|
|
size += 1
|
|
|
|
// Dynamic array: UnknownArray2
|
|
for _, elem := range p.UnknownArray2 {
|
|
_ = elem // Avoid unused variable warning
|
|
size += 4
|
|
|
|
}
|
|
|
|
size += 4
|
|
|
|
size += 4
|
|
|
|
size += 4
|
|
|
|
size += 4
|
|
|
|
size += 2 + uint32(len(p.Password))
|
|
|
|
size += 2 + uint32(len(p.Username))
|
|
|
|
size += 2 + uint32(len(p.Service))
|
|
|
|
size += 1
|
|
|
|
size += 1
|
|
|
|
// Dynamic array: Lvl90ClassItems
|
|
for _, elem := range p.Lvl90ClassItems {
|
|
_ = elem // Avoid unused variable warning
|
|
size += 1
|
|
size += 1
|
|
// Nested array: StartingItems
|
|
for _, nestedElem := range elem.StartingItems {
|
|
_ = nestedElem // Avoid unused variable
|
|
size += 4
|
|
size += 1
|
|
size += 1
|
|
size += 1
|
|
size += 4
|
|
size += 4
|
|
|
|
}
|
|
|
|
}
|
|
|
|
size += 1
|
|
|
|
size += 1
|
|
|
|
// Dynamic array: TimeLockedClassItems
|
|
for _, elem := range p.TimeLockedClassItems {
|
|
_ = elem // Avoid unused variable warning
|
|
size += 1
|
|
size += 1
|
|
// Nested array: StartingItems
|
|
for _, nestedElem := range elem.StartingItems {
|
|
_ = nestedElem // Avoid unused variable
|
|
size += 4
|
|
size += 1
|
|
size += 1
|
|
size += 1
|
|
size += 4
|
|
size += 4
|
|
|
|
}
|
|
|
|
}
|
|
|
|
size += 13
|
|
|
|
return size
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|