5636 lines
160 KiB
Go
5636 lines
160 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)
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.AccountId))
|
|
offset += 4
|
|
dest[offset] = byte(p.Response)
|
|
offset++
|
|
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)
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.AccountId))
|
|
offset += 4
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.Unknown))
|
|
offset += 4
|
|
dest[offset] = byte(p.Response)
|
|
offset++
|
|
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)
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.AccountId))
|
|
offset += 4
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.Unknown))
|
|
offset += 4
|
|
dest[offset] = byte(p.Response)
|
|
offset++
|
|
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)
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.CharId))
|
|
offset += 4
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.ServerId))
|
|
offset += 4
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.Unknown))
|
|
offset += 4
|
|
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)
|
|
dest[offset] = byte(p.Response)
|
|
offset++
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.ServerId))
|
|
offset += 4
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.CharId))
|
|
offset += 4
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.AccountId))
|
|
offset += 4
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(len(p.Name)))
|
|
offset += 2
|
|
copy(dest[offset:], []byte(p.Name))
|
|
offset += uint32(len(p.Name))
|
|
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)
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(len(p.SessionID)))
|
|
offset += 2
|
|
copy(dest[offset:], []byte(p.SessionID))
|
|
offset += uint32(len(p.SessionID))
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(len(p.SessionRecycleToken)))
|
|
offset += 2
|
|
copy(dest[offset:], []byte(p.SessionRecycleToken))
|
|
offset += uint32(len(p.SessionRecycleToken))
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(len(p.Username)))
|
|
offset += 2
|
|
copy(dest[offset:], []byte(p.Username))
|
|
offset += uint32(len(p.Username))
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(len(p.Password)))
|
|
offset += 2
|
|
copy(dest[offset:], []byte(p.Password))
|
|
offset += uint32(len(p.Password))
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.AcctNum))
|
|
offset += 4
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.PassCode))
|
|
offset += 4
|
|
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)
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(len(p.Accesscode)))
|
|
offset += 2
|
|
copy(dest[offset:], []byte(p.Accesscode))
|
|
offset += uint32(len(p.Accesscode))
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(len(p.Unknown1)))
|
|
offset += 2
|
|
copy(dest[offset:], []byte(p.Unknown1))
|
|
offset += uint32(len(p.Unknown1))
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(len(p.Username)))
|
|
offset += 2
|
|
copy(dest[offset:], []byte(p.Username))
|
|
offset += uint32(len(p.Username))
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(len(p.Password)))
|
|
offset += 2
|
|
copy(dest[offset:], []byte(p.Password))
|
|
offset += uint32(len(p.Password))
|
|
for i := 0; i < 8; i++ {
|
|
dest[offset] = p.Unknown2[i]
|
|
offset++
|
|
}
|
|
for i := 0; i < 2; i++ {
|
|
dest[offset] = p.Unknown3[i]
|
|
offset++
|
|
}
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.Version))
|
|
offset += 4
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(p.Unknown4))
|
|
offset += 2
|
|
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 += uint32(8)
|
|
size += uint32(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)
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(len(p.Accesscode)))
|
|
offset += 2
|
|
copy(dest[offset:], []byte(p.Accesscode))
|
|
offset += uint32(len(p.Accesscode))
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(len(p.Unknown1)))
|
|
offset += 2
|
|
copy(dest[offset:], []byte(p.Unknown1))
|
|
offset += uint32(len(p.Unknown1))
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(len(p.Username)))
|
|
offset += 2
|
|
copy(dest[offset:], []byte(p.Username))
|
|
offset += uint32(len(p.Username))
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(len(p.Password)))
|
|
offset += 2
|
|
copy(dest[offset:], []byte(p.Password))
|
|
offset += uint32(len(p.Password))
|
|
for i := 0; i < 8; i++ {
|
|
dest[offset] = p.Unknown2[i]
|
|
offset++
|
|
}
|
|
for i := 0; i < 2; i++ {
|
|
dest[offset] = p.Unknown3[i]
|
|
offset++
|
|
}
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(p.Version))
|
|
offset += 2
|
|
dest[offset] = byte(p.Unknown4)
|
|
offset++
|
|
for i := 0; i < 3; i++ {
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.Unknown5[i]))
|
|
offset += 4
|
|
}
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(p.Unknown6))
|
|
offset += 2
|
|
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 += uint32(8)
|
|
size += uint32(2)
|
|
size += 2
|
|
size += 1
|
|
size += uint32(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)
|
|
dest[offset] = byte(p.NumWorlds)
|
|
offset++
|
|
for _, elem := range p.WorldList {
|
|
binary.LittleEndian.PutUint32(dest[offset:], elem.Id)
|
|
offset += 4
|
|
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
|
|
for _, elem := range p.WorldList {
|
|
_ = elem
|
|
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)
|
|
dest[offset] = byte(p.NumWorlds)
|
|
offset++
|
|
for _, elem := range p.WorldList {
|
|
binary.LittleEndian.PutUint32(dest[offset:], elem.Id)
|
|
offset += 4
|
|
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
|
|
for _, elem := range p.WorldList {
|
|
_ = elem
|
|
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)
|
|
dest[offset] = byte(p.NumWorlds)
|
|
offset++
|
|
for _, elem := range p.WorldList {
|
|
binary.LittleEndian.PutUint32(dest[offset:], elem.Id)
|
|
offset += 4
|
|
dest[offset] = byte(len(elem.Name))
|
|
offset++
|
|
copy(dest[offset:], []byte(elem.Name))
|
|
offset += uint32(len(elem.Name))
|
|
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
|
|
for _, elem := range p.WorldList {
|
|
_ = elem
|
|
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)
|
|
dest[offset] = byte(p.NumWorlds)
|
|
offset++
|
|
for _, elem := range p.WorldList {
|
|
binary.LittleEndian.PutUint32(dest[offset:], elem.Id)
|
|
offset += 4
|
|
dest[offset] = byte(len(elem.Name))
|
|
offset++
|
|
copy(dest[offset:], []byte(elem.Name))
|
|
offset += uint32(len(elem.Name))
|
|
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++
|
|
for i := 0; i < 2; i++ {
|
|
dest[offset] = byte(elem.FeatureSet[i])
|
|
offset++
|
|
}
|
|
binary.LittleEndian.PutUint32(dest[offset:], elem.AllowedRaces)
|
|
offset += 4
|
|
}
|
|
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
|
|
for _, elem := range p.WorldList {
|
|
_ = elem
|
|
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 += uint32(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)
|
|
dest[offset] = byte(p.NumWorlds)
|
|
offset++
|
|
for _, elem := range p.WorldList {
|
|
binary.LittleEndian.PutUint32(dest[offset:], elem.Id)
|
|
offset += 4
|
|
dest[offset] = byte(len(elem.Name))
|
|
offset++
|
|
copy(dest[offset:], []byte(elem.Name))
|
|
offset += uint32(len(elem.Name))
|
|
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++
|
|
for i := 0; i < 2; i++ {
|
|
dest[offset] = byte(elem.FeatureSet[i])
|
|
offset++
|
|
}
|
|
binary.LittleEndian.PutUint32(dest[offset:], elem.AllowedRaces)
|
|
offset += 4
|
|
}
|
|
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
|
|
for _, elem := range p.WorldList {
|
|
_ = elem
|
|
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 += uint32(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)
|
|
dest[offset] = byte(p.NumWorlds)
|
|
offset++
|
|
for _, elem := range p.WorldList {
|
|
binary.LittleEndian.PutUint32(dest[offset:], elem.Id)
|
|
offset += 4
|
|
dest[offset] = byte(len(elem.Name))
|
|
offset++
|
|
copy(dest[offset:], []byte(elem.Name))
|
|
offset += uint32(len(elem.Name))
|
|
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++
|
|
for i := 0; i < 3; i++ {
|
|
dest[offset] = byte(elem.FeatureSet[i])
|
|
offset++
|
|
}
|
|
binary.LittleEndian.PutUint32(dest[offset:], elem.AllowedRaces)
|
|
offset += 4
|
|
}
|
|
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
|
|
for _, elem := range p.WorldList {
|
|
_ = elem
|
|
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 += uint32(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)
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.ServerId))
|
|
offset += 4
|
|
dest[offset] = byte(p.Up)
|
|
offset++
|
|
dest[offset] = byte(p.Locked)
|
|
offset++
|
|
dest[offset] = byte(p.Unknown1)
|
|
offset++
|
|
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)
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.CharId))
|
|
offset += 4
|
|
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)
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.CharId))
|
|
offset += 4
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.ServerId))
|
|
offset += 4
|
|
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 += uint32(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)
|
|
dest[offset] = byte(p.Response)
|
|
offset++
|
|
dest[offset] = byte(len(p.Server))
|
|
offset++
|
|
copy(dest[offset:], []byte(p.Server))
|
|
offset += uint32(len(p.Server))
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(p.Port))
|
|
offset += 2
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.AccountId))
|
|
offset += 4
|
|
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)
|
|
dest[offset] = byte(p.Response)
|
|
offset++
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(p.Unknown1))
|
|
offset += 2
|
|
dest[offset] = byte(len(p.Server))
|
|
offset++
|
|
copy(dest[offset:], []byte(p.Server))
|
|
offset += uint32(len(p.Server))
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(p.Port))
|
|
offset += 2
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.AccountId))
|
|
offset += 4
|
|
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)
|
|
dest[offset] = byte(p.Response)
|
|
offset++
|
|
for i := 0; i < 3; i++ {
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(p.Unknown1[i]))
|
|
offset += 2
|
|
}
|
|
dest[offset] = byte(len(p.Server))
|
|
offset++
|
|
copy(dest[offset:], []byte(p.Server))
|
|
offset += uint32(len(p.Server))
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(p.Port))
|
|
offset += 2
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.AccountId))
|
|
offset += 4
|
|
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 += uint32(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)
|
|
dest[offset] = byte(p.Response)
|
|
offset++
|
|
for i := 0; i < 3; i++ {
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(p.Unknown1[i]))
|
|
offset += 2
|
|
}
|
|
dest[offset] = byte(len(p.Server))
|
|
offset++
|
|
copy(dest[offset:], []byte(p.Server))
|
|
offset += uint32(len(p.Server))
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(p.Port))
|
|
offset += 2
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.AccountId))
|
|
offset += 4
|
|
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 += uint32(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)
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.Charid))
|
|
offset += 4
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.ServerId))
|
|
offset += 4
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(len(p.Name)))
|
|
offset += 2
|
|
copy(dest[offset:], []byte(p.Name))
|
|
offset += uint32(len(p.Name))
|
|
dest[offset] = byte(p.Race)
|
|
offset++
|
|
dest[offset] = byte(p.Class)
|
|
offset++
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.Level))
|
|
offset += 4
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(len(p.Zone)))
|
|
offset += 2
|
|
copy(dest[offset:], []byte(p.Zone))
|
|
offset += uint32(len(p.Zone))
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.Unknown1))
|
|
offset += 4
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.Unknown2))
|
|
offset += 4
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.CreatedDate))
|
|
offset += 4
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.LastPlayed))
|
|
offset += 4
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.Unknown3))
|
|
offset += 4
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.Unknown4))
|
|
offset += 4
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(len(p.Zonename2)))
|
|
offset += 2
|
|
copy(dest[offset:], []byte(p.Zonename2))
|
|
offset += uint32(len(p.Zonename2))
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(len(p.Zonedesc)))
|
|
offset += 2
|
|
copy(dest[offset:], []byte(p.Zonedesc))
|
|
offset += uint32(len(p.Zonedesc))
|
|
dest[offset] = byte(p.Version)
|
|
offset++
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(p.RaceType))
|
|
offset += 2
|
|
for i := 0; i < 3; i++ {
|
|
dest[offset] = byte(p.SkinColor[i])
|
|
offset++
|
|
}
|
|
for i := 0; i < 3; i++ {
|
|
dest[offset] = byte(p.EyeColor[i])
|
|
offset++
|
|
}
|
|
for i := 0; i < 21; i++ {
|
|
binary.LittleEndian.PutUint16(dest[offset:], p.Equip[i].Type)
|
|
offset += 2
|
|
dest[offset] = p.Equip[i].Color.R
|
|
dest[offset+1] = p.Equip[i].Color.G
|
|
dest[offset+2] = p.Equip[i].Color.B
|
|
offset += 3
|
|
dest[offset] = p.Equip[i].Highlight.R
|
|
dest[offset+1] = p.Equip[i].Highlight.G
|
|
dest[offset+2] = p.Equip[i].Highlight.B
|
|
offset += 3
|
|
}
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(p.HairType))
|
|
offset += 2
|
|
for i := 0; i < 3; i++ {
|
|
dest[offset] = byte(p.HairTypeColor[i])
|
|
offset++
|
|
}
|
|
for i := 0; i < 3; i++ {
|
|
dest[offset] = byte(p.HairTypeHighlightColor[i])
|
|
offset++
|
|
}
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(p.HairFaceType))
|
|
offset += 2
|
|
for i := 0; i < 3; i++ {
|
|
dest[offset] = byte(p.HairFaceColor[i])
|
|
offset++
|
|
}
|
|
for i := 0; i < 3; i++ {
|
|
dest[offset] = byte(p.HairFaceHighlightColor[i])
|
|
offset++
|
|
}
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(p.ChestType))
|
|
offset += 2
|
|
for i := 0; i < 3; i++ {
|
|
dest[offset] = byte(p.ShirtColor[i])
|
|
offset++
|
|
}
|
|
for i := 0; i < 3; i++ {
|
|
dest[offset] = byte(p.UnknownChestColor[i])
|
|
offset++
|
|
}
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(p.LegsType))
|
|
offset += 2
|
|
for i := 0; i < 3; i++ {
|
|
dest[offset] = byte(p.PantsColor[i])
|
|
offset++
|
|
}
|
|
for i := 0; i < 3; i++ {
|
|
dest[offset] = byte(p.UnknownLegsColor[i])
|
|
offset++
|
|
}
|
|
for i := 0; i < 3; i++ {
|
|
dest[offset] = byte(p.Unknown9[i])
|
|
offset++
|
|
}
|
|
for i := 0; i < 3; i++ {
|
|
dest[offset] = byte(p.EyeType[i])
|
|
offset++
|
|
}
|
|
for i := 0; i < 3; i++ {
|
|
dest[offset] = byte(p.EarType[i])
|
|
offset++
|
|
}
|
|
for i := 0; i < 3; i++ {
|
|
dest[offset] = byte(p.EyeBrowType[i])
|
|
offset++
|
|
}
|
|
for i := 0; i < 3; i++ {
|
|
dest[offset] = byte(p.CheekType[i])
|
|
offset++
|
|
}
|
|
for i := 0; i < 3; i++ {
|
|
dest[offset] = byte(p.LipType[i])
|
|
offset++
|
|
}
|
|
for i := 0; i < 3; i++ {
|
|
dest[offset] = byte(p.ChinType[i])
|
|
offset++
|
|
}
|
|
for i := 0; i < 3; i++ {
|
|
dest[offset] = byte(p.NoseType[i])
|
|
offset++
|
|
}
|
|
dest[offset] = byte(p.BodySize)
|
|
offset++
|
|
dest[offset] = byte(p.BumpScale)
|
|
offset++
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(p.Mount))
|
|
offset += 2
|
|
for i := 0; i < 3; i++ {
|
|
dest[offset] = byte(p.MountColor1[i])
|
|
offset++
|
|
}
|
|
for i := 0; i < 3; i++ {
|
|
dest[offset] = byte(p.MountColor2[i])
|
|
offset++
|
|
}
|
|
for i := 0; i < 3; i++ {
|
|
dest[offset] = byte(p.HairColor1[i])
|
|
offset++
|
|
}
|
|
for i := 0; i < 3; i++ {
|
|
dest[offset] = byte(p.HairColor2[i])
|
|
offset++
|
|
}
|
|
for i := 0; i < 3; i++ {
|
|
dest[offset] = byte(p.HairColor3[i])
|
|
offset++
|
|
}
|
|
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 += uint32(3)
|
|
size += uint32(3)
|
|
size += uint32(21) * 8
|
|
size += 2
|
|
size += uint32(3)
|
|
size += uint32(3)
|
|
size += 2
|
|
size += uint32(3)
|
|
size += uint32(3)
|
|
size += 2
|
|
size += uint32(3)
|
|
size += uint32(3)
|
|
size += 2
|
|
size += uint32(3)
|
|
size += uint32(3)
|
|
size += uint32(3)
|
|
size += uint32(3)
|
|
size += uint32(3)
|
|
size += uint32(3)
|
|
size += uint32(3)
|
|
size += uint32(3)
|
|
size += uint32(3)
|
|
size += uint32(3)
|
|
size += 1
|
|
size += 1
|
|
size += 2
|
|
size += uint32(3)
|
|
size += uint32(3)
|
|
size += uint32(3)
|
|
size += uint32(3)
|
|
size += uint32(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)
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.Charid))
|
|
offset += 4
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.ServerId))
|
|
offset += 4
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(len(p.Name)))
|
|
offset += 2
|
|
copy(dest[offset:], []byte(p.Name))
|
|
offset += uint32(len(p.Name))
|
|
dest[offset] = byte(p.Race)
|
|
offset++
|
|
dest[offset] = byte(p.Class)
|
|
offset++
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.Level))
|
|
offset += 4
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(len(p.Zone)))
|
|
offset += 2
|
|
copy(dest[offset:], []byte(p.Zone))
|
|
offset += uint32(len(p.Zone))
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.Unknown1))
|
|
offset += 4
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.Unknown2))
|
|
offset += 4
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.CreatedDate))
|
|
offset += 4
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.LastPlayed))
|
|
offset += 4
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.Unknown3))
|
|
offset += 4
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.Unknown4))
|
|
offset += 4
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(len(p.Zonename2)))
|
|
offset += 2
|
|
copy(dest[offset:], []byte(p.Zonename2))
|
|
offset += uint32(len(p.Zonename2))
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(len(p.Zonedesc)))
|
|
offset += 2
|
|
copy(dest[offset:], []byte(p.Zonedesc))
|
|
offset += uint32(len(p.Zonedesc))
|
|
dest[offset] = byte(p.Version)
|
|
offset++
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(p.RaceType))
|
|
offset += 2
|
|
for i := 0; i < 3; i++ {
|
|
dest[offset] = byte(p.SkinColor[i])
|
|
offset++
|
|
}
|
|
for i := 0; i < 3; i++ {
|
|
dest[offset] = byte(p.EyeColor[i])
|
|
offset++
|
|
}
|
|
for i := 0; i < 21; i++ {
|
|
binary.LittleEndian.PutUint16(dest[offset:], p.Equip[i].Type)
|
|
offset += 2
|
|
dest[offset] = p.Equip[i].Color.R
|
|
dest[offset+1] = p.Equip[i].Color.G
|
|
dest[offset+2] = p.Equip[i].Color.B
|
|
offset += 3
|
|
dest[offset] = p.Equip[i].Highlight.R
|
|
dest[offset+1] = p.Equip[i].Highlight.G
|
|
dest[offset+2] = p.Equip[i].Highlight.B
|
|
offset += 3
|
|
}
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(p.HairType))
|
|
offset += 2
|
|
for i := 0; i < 3; i++ {
|
|
dest[offset] = byte(p.HairTypeColor[i])
|
|
offset++
|
|
}
|
|
for i := 0; i < 3; i++ {
|
|
dest[offset] = byte(p.HairTypeHighlightColor[i])
|
|
offset++
|
|
}
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(p.HairFaceType))
|
|
offset += 2
|
|
for i := 0; i < 3; i++ {
|
|
dest[offset] = byte(p.HairFaceColor[i])
|
|
offset++
|
|
}
|
|
for i := 0; i < 3; i++ {
|
|
dest[offset] = byte(p.HairFaceHighlightColor[i])
|
|
offset++
|
|
}
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(p.ChestType))
|
|
offset += 2
|
|
for i := 0; i < 3; i++ {
|
|
dest[offset] = byte(p.ShirtColor[i])
|
|
offset++
|
|
}
|
|
for i := 0; i < 3; i++ {
|
|
dest[offset] = byte(p.UnknownChestColor[i])
|
|
offset++
|
|
}
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(p.LegsType))
|
|
offset += 2
|
|
for i := 0; i < 3; i++ {
|
|
dest[offset] = byte(p.PantsColor[i])
|
|
offset++
|
|
}
|
|
for i := 0; i < 3; i++ {
|
|
dest[offset] = byte(p.UnknownLegsColor[i])
|
|
offset++
|
|
}
|
|
for i := 0; i < 3; i++ {
|
|
dest[offset] = byte(p.Unknown9[i])
|
|
offset++
|
|
}
|
|
for i := 0; i < 3; i++ {
|
|
dest[offset] = byte(p.EyeType[i])
|
|
offset++
|
|
}
|
|
for i := 0; i < 3; i++ {
|
|
dest[offset] = byte(p.EarType[i])
|
|
offset++
|
|
}
|
|
for i := 0; i < 3; i++ {
|
|
dest[offset] = byte(p.EyeBrowType[i])
|
|
offset++
|
|
}
|
|
for i := 0; i < 3; i++ {
|
|
dest[offset] = byte(p.CheekType[i])
|
|
offset++
|
|
}
|
|
for i := 0; i < 3; i++ {
|
|
dest[offset] = byte(p.LipType[i])
|
|
offset++
|
|
}
|
|
for i := 0; i < 3; i++ {
|
|
dest[offset] = byte(p.ChinType[i])
|
|
offset++
|
|
}
|
|
for i := 0; i < 3; i++ {
|
|
dest[offset] = byte(p.NoseType[i])
|
|
offset++
|
|
}
|
|
dest[offset] = byte(p.BodySize)
|
|
offset++
|
|
dest[offset] = byte(p.BumpScale)
|
|
offset++
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(p.Mount))
|
|
offset += 2
|
|
for i := 0; i < 3; i++ {
|
|
dest[offset] = byte(p.MountColor1[i])
|
|
offset++
|
|
}
|
|
for i := 0; i < 3; i++ {
|
|
dest[offset] = byte(p.MountColor2[i])
|
|
offset++
|
|
}
|
|
for i := 0; i < 3; i++ {
|
|
dest[offset] = byte(p.HairColor1[i])
|
|
offset++
|
|
}
|
|
for i := 0; i < 3; i++ {
|
|
dest[offset] = byte(p.HairColor2[i])
|
|
offset++
|
|
}
|
|
for i := 0; i < 3; i++ {
|
|
dest[offset] = byte(p.HairColor3[i])
|
|
offset++
|
|
}
|
|
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 += uint32(3)
|
|
size += uint32(3)
|
|
size += uint32(21) * 8
|
|
size += 2
|
|
size += uint32(3)
|
|
size += uint32(3)
|
|
size += 2
|
|
size += uint32(3)
|
|
size += uint32(3)
|
|
size += 2
|
|
size += uint32(3)
|
|
size += uint32(3)
|
|
size += 2
|
|
size += uint32(3)
|
|
size += uint32(3)
|
|
size += uint32(3)
|
|
size += uint32(3)
|
|
size += uint32(3)
|
|
size += uint32(3)
|
|
size += uint32(3)
|
|
size += uint32(3)
|
|
size += uint32(3)
|
|
size += uint32(3)
|
|
size += 1
|
|
size += 1
|
|
size += 2
|
|
size += uint32(3)
|
|
size += uint32(3)
|
|
size += uint32(3)
|
|
size += uint32(3)
|
|
size += uint32(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)
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.Charid))
|
|
offset += 4
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.ServerId))
|
|
offset += 4
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(len(p.Name)))
|
|
offset += 2
|
|
copy(dest[offset:], []byte(p.Name))
|
|
offset += uint32(len(p.Name))
|
|
dest[offset] = byte(p.Race)
|
|
offset++
|
|
dest[offset] = byte(p.Class)
|
|
offset++
|
|
dest[offset] = byte(p.Gender)
|
|
offset++
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.Level))
|
|
offset += 4
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(len(p.Zone)))
|
|
offset += 2
|
|
copy(dest[offset:], []byte(p.Zone))
|
|
offset += uint32(len(p.Zone))
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.Unknown1))
|
|
offset += 4
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.Unknown2))
|
|
offset += 4
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.CreatedDate))
|
|
offset += 4
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.LastPlayed))
|
|
offset += 4
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.Unknown3))
|
|
offset += 4
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.Unknown4))
|
|
offset += 4
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(len(p.Zonename2)))
|
|
offset += 2
|
|
copy(dest[offset:], []byte(p.Zonename2))
|
|
offset += uint32(len(p.Zonename2))
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(len(p.Zonedesc)))
|
|
offset += 2
|
|
copy(dest[offset:], []byte(p.Zonedesc))
|
|
offset += uint32(len(p.Zonedesc))
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.Unknown5))
|
|
offset += 4
|
|
dest[offset] = byte(p.Version)
|
|
offset++
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(p.RaceType))
|
|
offset += 2
|
|
for i := 0; i < 3; i++ {
|
|
dest[offset] = byte(p.SkinColor[i])
|
|
offset++
|
|
}
|
|
for i := 0; i < 3; i++ {
|
|
dest[offset] = byte(p.EyeColor[i])
|
|
offset++
|
|
}
|
|
for i := 0; i < 23; i++ {
|
|
binary.LittleEndian.PutUint16(dest[offset:], p.Equip[i].Type)
|
|
offset += 2
|
|
dest[offset] = p.Equip[i].Color.R
|
|
dest[offset+1] = p.Equip[i].Color.G
|
|
dest[offset+2] = p.Equip[i].Color.B
|
|
offset += 3
|
|
dest[offset] = p.Equip[i].Highlight.R
|
|
dest[offset+1] = p.Equip[i].Highlight.G
|
|
dest[offset+2] = p.Equip[i].Highlight.B
|
|
offset += 3
|
|
}
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(p.HairType))
|
|
offset += 2
|
|
for i := 0; i < 3; i++ {
|
|
dest[offset] = byte(p.HairTypeColor[i])
|
|
offset++
|
|
}
|
|
for i := 0; i < 3; i++ {
|
|
dest[offset] = byte(p.HairTypeHighlightColor[i])
|
|
offset++
|
|
}
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(p.HairFaceType))
|
|
offset += 2
|
|
for i := 0; i < 3; i++ {
|
|
dest[offset] = byte(p.HairFaceColor[i])
|
|
offset++
|
|
}
|
|
for i := 0; i < 3; i++ {
|
|
dest[offset] = byte(p.HairFaceHighlightColor[i])
|
|
offset++
|
|
}
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(p.ChestType))
|
|
offset += 2
|
|
for i := 0; i < 3; i++ {
|
|
dest[offset] = byte(p.ShirtColor[i])
|
|
offset++
|
|
}
|
|
for i := 0; i < 3; i++ {
|
|
dest[offset] = byte(p.UnknownChestColor[i])
|
|
offset++
|
|
}
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(p.LegsType))
|
|
offset += 2
|
|
for i := 0; i < 3; i++ {
|
|
dest[offset] = byte(p.PantsColor[i])
|
|
offset++
|
|
}
|
|
for i := 0; i < 3; i++ {
|
|
dest[offset] = byte(p.UnknownLegsColor[i])
|
|
offset++
|
|
}
|
|
for i := 0; i < 3; i++ {
|
|
dest[offset] = byte(p.Unknown9[i])
|
|
offset++
|
|
}
|
|
for i := 0; i < 3; i++ {
|
|
dest[offset] = byte(p.EyeType[i])
|
|
offset++
|
|
}
|
|
for i := 0; i < 3; i++ {
|
|
dest[offset] = byte(p.EarType[i])
|
|
offset++
|
|
}
|
|
for i := 0; i < 3; i++ {
|
|
dest[offset] = byte(p.EyeBrowType[i])
|
|
offset++
|
|
}
|
|
for i := 0; i < 3; i++ {
|
|
dest[offset] = byte(p.CheekType[i])
|
|
offset++
|
|
}
|
|
for i := 0; i < 3; i++ {
|
|
dest[offset] = byte(p.LipType[i])
|
|
offset++
|
|
}
|
|
for i := 0; i < 3; i++ {
|
|
dest[offset] = byte(p.ChinType[i])
|
|
offset++
|
|
}
|
|
for i := 0; i < 3; i++ {
|
|
dest[offset] = byte(p.NoseType[i])
|
|
offset++
|
|
}
|
|
dest[offset] = byte(p.BodySize)
|
|
offset++
|
|
dest[offset] = byte(p.BumpScale)
|
|
offset++
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(p.Mount))
|
|
offset += 2
|
|
for i := 0; i < 3; i++ {
|
|
dest[offset] = byte(p.MountColor1[i])
|
|
offset++
|
|
}
|
|
for i := 0; i < 3; i++ {
|
|
dest[offset] = byte(p.MountColor2[i])
|
|
offset++
|
|
}
|
|
for i := 0; i < 3; i++ {
|
|
dest[offset] = byte(p.HairColor1[i])
|
|
offset++
|
|
}
|
|
for i := 0; i < 3; i++ {
|
|
dest[offset] = byte(p.HairColor2[i])
|
|
offset++
|
|
}
|
|
for i := 0; i < 3; i++ {
|
|
dest[offset] = byte(p.HairColor3[i])
|
|
offset++
|
|
}
|
|
for i := 0; i < 10; i++ {
|
|
dest[offset] = p.Unknown11[i]
|
|
offset++
|
|
}
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(p.SogaRaceType))
|
|
offset += 2
|
|
dest[offset] = p.SogaSkinColorx.R
|
|
dest[offset+1] = p.SogaSkinColorx.G
|
|
dest[offset+2] = p.SogaSkinColorx.B
|
|
offset += 3
|
|
dest[offset] = p.SogaEyeColor.R
|
|
dest[offset+1] = p.SogaEyeColor.G
|
|
dest[offset+2] = p.SogaEyeColor.B
|
|
offset += 3
|
|
for i := 0; i < 3; i++ {
|
|
dest[offset] = p.Unknown12[i]
|
|
offset++
|
|
}
|
|
for i := 0; i < 3; i++ {
|
|
dest[offset] = byte(p.SogaEyeType[i])
|
|
offset++
|
|
}
|
|
for i := 0; i < 3; i++ {
|
|
dest[offset] = byte(p.SogaEarType[i])
|
|
offset++
|
|
}
|
|
for i := 0; i < 3; i++ {
|
|
dest[offset] = byte(p.SogaEyeBrowType[i])
|
|
offset++
|
|
}
|
|
for i := 0; i < 3; i++ {
|
|
dest[offset] = byte(p.SogaCheekType[i])
|
|
offset++
|
|
}
|
|
for i := 0; i < 3; i++ {
|
|
dest[offset] = byte(p.SogaLipType[i])
|
|
offset++
|
|
}
|
|
for i := 0; i < 3; i++ {
|
|
dest[offset] = byte(p.SogaChinType[i])
|
|
offset++
|
|
}
|
|
for i := 0; i < 3; i++ {
|
|
dest[offset] = byte(p.SogaNoseType[i])
|
|
offset++
|
|
}
|
|
dest[offset] = p.SogaHairColor1.R
|
|
dest[offset+1] = p.SogaHairColor1.G
|
|
dest[offset+2] = p.SogaHairColor1.B
|
|
offset += 3
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(p.SogaChestType))
|
|
offset += 2
|
|
dest[offset] = p.SogaHairColor2.R
|
|
dest[offset+1] = p.SogaHairColor2.G
|
|
dest[offset+2] = p.SogaHairColor2.B
|
|
offset += 3
|
|
dest[offset] = p.SogaHairColor3.R
|
|
dest[offset+1] = p.SogaHairColor3.G
|
|
dest[offset+2] = p.SogaHairColor3.B
|
|
offset += 3
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(p.SogaHairType))
|
|
offset += 2
|
|
dest[offset] = p.SogaHairTypeColor.R
|
|
dest[offset+1] = p.SogaHairTypeColor.G
|
|
dest[offset+2] = p.SogaHairTypeColor.B
|
|
offset += 3
|
|
dest[offset] = p.SogaHairTypeHighlightColor.R
|
|
dest[offset+1] = p.SogaHairTypeHighlightColor.G
|
|
dest[offset+2] = p.SogaHairTypeHighlightColor.B
|
|
offset += 3
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(p.SogaHairFaceType))
|
|
offset += 2
|
|
dest[offset] = p.SogaHairFaceColor.R
|
|
dest[offset+1] = p.SogaHairFaceColor.G
|
|
dest[offset+2] = p.SogaHairFaceColor.B
|
|
offset += 3
|
|
dest[offset] = p.SogaHairFaceHighlightColor.R
|
|
dest[offset+1] = p.SogaHairFaceHighlightColor.G
|
|
dest[offset+2] = p.SogaHairFaceHighlightColor.B
|
|
offset += 3
|
|
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 += uint32(3)
|
|
size += uint32(3)
|
|
size += uint32(23) * 8
|
|
size += 2
|
|
size += uint32(3)
|
|
size += uint32(3)
|
|
size += 2
|
|
size += uint32(3)
|
|
size += uint32(3)
|
|
size += 2
|
|
size += uint32(3)
|
|
size += uint32(3)
|
|
size += 2
|
|
size += uint32(3)
|
|
size += uint32(3)
|
|
size += uint32(3)
|
|
size += uint32(3)
|
|
size += uint32(3)
|
|
size += uint32(3)
|
|
size += uint32(3)
|
|
size += uint32(3)
|
|
size += uint32(3)
|
|
size += uint32(3)
|
|
size += 1
|
|
size += 1
|
|
size += 2
|
|
size += uint32(3)
|
|
size += uint32(3)
|
|
size += uint32(3)
|
|
size += uint32(3)
|
|
size += uint32(3)
|
|
size += uint32(10)
|
|
size += 2
|
|
size += 3
|
|
size += 3
|
|
size += uint32(3)
|
|
size += uint32(3)
|
|
size += uint32(3)
|
|
size += uint32(3)
|
|
size += uint32(3)
|
|
size += uint32(3)
|
|
size += uint32(3)
|
|
size += uint32(3)
|
|
size += 3
|
|
size += 2
|
|
size += 3
|
|
size += 3
|
|
size += 2
|
|
size += 3
|
|
size += 3
|
|
size += 2
|
|
size += 3
|
|
size += 3
|
|
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)
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.Version))
|
|
offset += 4
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.Charid))
|
|
offset += 4
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.ServerId))
|
|
offset += 4
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(len(p.Name)))
|
|
offset += 2
|
|
copy(dest[offset:], []byte(p.Name))
|
|
offset += uint32(len(p.Name))
|
|
dest[offset] = byte(p.Unknown)
|
|
offset++
|
|
dest[offset] = byte(p.Race)
|
|
offset++
|
|
dest[offset] = byte(p.Class)
|
|
offset++
|
|
dest[offset] = byte(p.Gender)
|
|
offset++
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.Level))
|
|
offset += 4
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(len(p.Zone)))
|
|
offset += 2
|
|
copy(dest[offset:], []byte(p.Zone))
|
|
offset += uint32(len(p.Zone))
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.Unknown1))
|
|
offset += 4
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.Unknown2))
|
|
offset += 4
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.CreatedDate))
|
|
offset += 4
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.LastPlayed))
|
|
offset += 4
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.Unknown3))
|
|
offset += 4
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.Unknown4))
|
|
offset += 4
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(len(p.Zonename2)))
|
|
offset += 2
|
|
copy(dest[offset:], []byte(p.Zonename2))
|
|
offset += uint32(len(p.Zonename2))
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(len(p.Zonedesc)))
|
|
offset += 2
|
|
copy(dest[offset:], []byte(p.Zonedesc))
|
|
offset += uint32(len(p.Zonedesc))
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.Unknown5))
|
|
offset += 4
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(len(p.ServerName)))
|
|
offset += 2
|
|
copy(dest[offset:], []byte(p.ServerName))
|
|
offset += uint32(len(p.ServerName))
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.AccountId))
|
|
offset += 4
|
|
for i := 0; i < 2; i++ {
|
|
dest[offset] = p.Unknown6[i]
|
|
offset++
|
|
}
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.Unknown7))
|
|
offset += 4
|
|
dest[offset] = byte(p.Unknown8)
|
|
offset++
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(p.RaceType))
|
|
offset += 2
|
|
dest[offset] = p.SkinColor.R
|
|
dest[offset+1] = p.SkinColor.G
|
|
dest[offset+2] = p.SkinColor.B
|
|
offset += 3
|
|
dest[offset] = p.EyeColor.R
|
|
dest[offset+1] = p.EyeColor.G
|
|
dest[offset+2] = p.EyeColor.B
|
|
offset += 3
|
|
for i := 0; i < 25; i++ {
|
|
binary.LittleEndian.PutUint16(dest[offset:], p.Equip[i].Type)
|
|
offset += 2
|
|
dest[offset] = p.Equip[i].Color.R
|
|
dest[offset+1] = p.Equip[i].Color.G
|
|
dest[offset+2] = p.Equip[i].Color.B
|
|
offset += 3
|
|
dest[offset] = p.Equip[i].Highlight.R
|
|
dest[offset+1] = p.Equip[i].Highlight.G
|
|
dest[offset+2] = p.Equip[i].Highlight.B
|
|
offset += 3
|
|
}
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(p.HairType))
|
|
offset += 2
|
|
dest[offset] = p.HairTypeColor.R
|
|
dest[offset+1] = p.HairTypeColor.G
|
|
dest[offset+2] = p.HairTypeColor.B
|
|
offset += 3
|
|
dest[offset] = p.HairTypeHighlightColor.R
|
|
dest[offset+1] = p.HairTypeHighlightColor.G
|
|
dest[offset+2] = p.HairTypeHighlightColor.B
|
|
offset += 3
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(p.HairFaceType))
|
|
offset += 2
|
|
dest[offset] = p.HairFaceColor.R
|
|
dest[offset+1] = p.HairFaceColor.G
|
|
dest[offset+2] = p.HairFaceColor.B
|
|
offset += 3
|
|
dest[offset] = p.HairFaceHighlightColor.R
|
|
dest[offset+1] = p.HairFaceHighlightColor.G
|
|
dest[offset+2] = p.HairFaceHighlightColor.B
|
|
offset += 3
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(p.ChestType))
|
|
offset += 2
|
|
dest[offset] = p.ShirtColor.R
|
|
dest[offset+1] = p.ShirtColor.G
|
|
dest[offset+2] = p.ShirtColor.B
|
|
offset += 3
|
|
dest[offset] = p.UnknownChestColor.R
|
|
dest[offset+1] = p.UnknownChestColor.G
|
|
dest[offset+2] = p.UnknownChestColor.B
|
|
offset += 3
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(p.LegsType))
|
|
offset += 2
|
|
dest[offset] = p.PantsColor.R
|
|
dest[offset+1] = p.PantsColor.G
|
|
dest[offset+2] = p.PantsColor.B
|
|
offset += 3
|
|
dest[offset] = p.UnknownLegsColor.R
|
|
dest[offset+1] = p.UnknownLegsColor.G
|
|
dest[offset+2] = p.UnknownLegsColor.B
|
|
offset += 3
|
|
dest[offset] = p.Unknown9.R
|
|
dest[offset+1] = p.Unknown9.G
|
|
dest[offset+2] = p.Unknown9.B
|
|
offset += 3
|
|
for i := 0; i < 3; i++ {
|
|
dest[offset] = byte(p.EyeType[i])
|
|
offset++
|
|
}
|
|
for i := 0; i < 3; i++ {
|
|
dest[offset] = byte(p.EarType[i])
|
|
offset++
|
|
}
|
|
for i := 0; i < 3; i++ {
|
|
dest[offset] = byte(p.EyeBrowType[i])
|
|
offset++
|
|
}
|
|
for i := 0; i < 3; i++ {
|
|
dest[offset] = byte(p.CheekType[i])
|
|
offset++
|
|
}
|
|
for i := 0; i < 3; i++ {
|
|
dest[offset] = byte(p.LipType[i])
|
|
offset++
|
|
}
|
|
for i := 0; i < 3; i++ {
|
|
dest[offset] = byte(p.ChinType[i])
|
|
offset++
|
|
}
|
|
for i := 0; i < 3; i++ {
|
|
dest[offset] = byte(p.NoseType[i])
|
|
offset++
|
|
}
|
|
dest[offset] = byte(p.BodySize)
|
|
offset++
|
|
for i := 0; i < 9; i++ {
|
|
dest[offset] = p.Unknown10[i]
|
|
offset++
|
|
}
|
|
dest[offset] = p.HairColor1.R
|
|
dest[offset+1] = p.HairColor1.G
|
|
dest[offset+2] = p.HairColor1.B
|
|
offset += 3
|
|
dest[offset] = p.HairColor2.R
|
|
dest[offset+1] = p.HairColor2.G
|
|
dest[offset+2] = p.HairColor2.B
|
|
offset += 3
|
|
for i := 0; i < 13; i++ {
|
|
dest[offset] = p.Unknown11[i]
|
|
offset++
|
|
}
|
|
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 += uint32(2)
|
|
size += 4
|
|
size += 1
|
|
size += 2
|
|
size += 3
|
|
size += 3
|
|
size += uint32(25) * 8
|
|
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 += uint32(3)
|
|
size += uint32(3)
|
|
size += uint32(3)
|
|
size += uint32(3)
|
|
size += uint32(3)
|
|
size += uint32(3)
|
|
size += uint32(3)
|
|
size += 1
|
|
size += uint32(9)
|
|
size += 3
|
|
size += 3
|
|
size += uint32(13)
|
|
size += uint32(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)
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.Version))
|
|
offset += 4
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.Charid))
|
|
offset += 4
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.ServerId))
|
|
offset += 4
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(len(p.Name)))
|
|
offset += 2
|
|
copy(dest[offset:], []byte(p.Name))
|
|
offset += uint32(len(p.Name))
|
|
dest[offset] = byte(p.Unknown)
|
|
offset++
|
|
dest[offset] = byte(p.Race)
|
|
offset++
|
|
dest[offset] = byte(p.Class)
|
|
offset++
|
|
dest[offset] = byte(p.Gender)
|
|
offset++
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.Level))
|
|
offset += 4
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(len(p.Zone)))
|
|
offset += 2
|
|
copy(dest[offset:], []byte(p.Zone))
|
|
offset += uint32(len(p.Zone))
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.Unknown1))
|
|
offset += 4
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.Unknown2))
|
|
offset += 4
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.CreatedDate))
|
|
offset += 4
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.LastPlayed))
|
|
offset += 4
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.Unknown3))
|
|
offset += 4
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.Unknown4))
|
|
offset += 4
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(len(p.Zonename2)))
|
|
offset += 2
|
|
copy(dest[offset:], []byte(p.Zonename2))
|
|
offset += uint32(len(p.Zonename2))
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(len(p.Zonedesc)))
|
|
offset += 2
|
|
copy(dest[offset:], []byte(p.Zonedesc))
|
|
offset += uint32(len(p.Zonedesc))
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.Unknown5))
|
|
offset += 4
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(len(p.ServerName)))
|
|
offset += 2
|
|
copy(dest[offset:], []byte(p.ServerName))
|
|
offset += uint32(len(p.ServerName))
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.AccountId))
|
|
offset += 4
|
|
for i := 0; i < 2; i++ {
|
|
dest[offset] = p.Unknown6[i]
|
|
offset++
|
|
}
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.Unknown7))
|
|
offset += 4
|
|
dest[offset] = byte(p.TradeskillClass)
|
|
offset++
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.TradeskillLevel))
|
|
offset += 4
|
|
dest[offset] = byte(p.Unknown8)
|
|
offset++
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(p.RaceType))
|
|
offset += 2
|
|
dest[offset] = p.SkinColor.R
|
|
dest[offset+1] = p.SkinColor.G
|
|
dest[offset+2] = p.SkinColor.B
|
|
offset += 3
|
|
dest[offset] = p.EyeColor.R
|
|
dest[offset+1] = p.EyeColor.G
|
|
dest[offset+2] = p.EyeColor.B
|
|
offset += 3
|
|
for i := 0; i < 25; i++ {
|
|
binary.LittleEndian.PutUint16(dest[offset:], p.Equip[i].Type)
|
|
offset += 2
|
|
dest[offset] = p.Equip[i].Color.R
|
|
dest[offset+1] = p.Equip[i].Color.G
|
|
dest[offset+2] = p.Equip[i].Color.B
|
|
offset += 3
|
|
dest[offset] = p.Equip[i].Highlight.R
|
|
dest[offset+1] = p.Equip[i].Highlight.G
|
|
dest[offset+2] = p.Equip[i].Highlight.B
|
|
offset += 3
|
|
}
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(p.HairType))
|
|
offset += 2
|
|
dest[offset] = p.HairTypeColor.R
|
|
dest[offset+1] = p.HairTypeColor.G
|
|
dest[offset+2] = p.HairTypeColor.B
|
|
offset += 3
|
|
dest[offset] = p.HairTypeHighlightColor.R
|
|
dest[offset+1] = p.HairTypeHighlightColor.G
|
|
dest[offset+2] = p.HairTypeHighlightColor.B
|
|
offset += 3
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(p.HairFaceType))
|
|
offset += 2
|
|
dest[offset] = p.HairFaceColor.R
|
|
dest[offset+1] = p.HairFaceColor.G
|
|
dest[offset+2] = p.HairFaceColor.B
|
|
offset += 3
|
|
dest[offset] = p.HairFaceHighlightColor.R
|
|
dest[offset+1] = p.HairFaceHighlightColor.G
|
|
dest[offset+2] = p.HairFaceHighlightColor.B
|
|
offset += 3
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(p.WingType))
|
|
offset += 2
|
|
dest[offset] = p.WingColor1.R
|
|
dest[offset+1] = p.WingColor1.G
|
|
dest[offset+2] = p.WingColor1.B
|
|
offset += 3
|
|
dest[offset] = p.WingColor2.R
|
|
dest[offset+1] = p.WingColor2.G
|
|
dest[offset+2] = p.WingColor2.B
|
|
offset += 3
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(p.ChestType))
|
|
offset += 2
|
|
dest[offset] = p.ShirtColor.R
|
|
dest[offset+1] = p.ShirtColor.G
|
|
dest[offset+2] = p.ShirtColor.B
|
|
offset += 3
|
|
dest[offset] = p.UnknownChestColor.R
|
|
dest[offset+1] = p.UnknownChestColor.G
|
|
dest[offset+2] = p.UnknownChestColor.B
|
|
offset += 3
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(p.LegsType))
|
|
offset += 2
|
|
dest[offset] = p.PantsColor.R
|
|
dest[offset+1] = p.PantsColor.G
|
|
dest[offset+2] = p.PantsColor.B
|
|
offset += 3
|
|
dest[offset] = p.UnknownLegsColor.R
|
|
dest[offset+1] = p.UnknownLegsColor.G
|
|
dest[offset+2] = p.UnknownLegsColor.B
|
|
offset += 3
|
|
dest[offset] = p.Unknown9.R
|
|
dest[offset+1] = p.Unknown9.G
|
|
dest[offset+2] = p.Unknown9.B
|
|
offset += 3
|
|
for i := 0; i < 3; i++ {
|
|
dest[offset] = byte(p.EyeType[i])
|
|
offset++
|
|
}
|
|
for i := 0; i < 3; i++ {
|
|
dest[offset] = byte(p.EarType[i])
|
|
offset++
|
|
}
|
|
for i := 0; i < 3; i++ {
|
|
dest[offset] = byte(p.EyeBrowType[i])
|
|
offset++
|
|
}
|
|
for i := 0; i < 3; i++ {
|
|
dest[offset] = byte(p.CheekType[i])
|
|
offset++
|
|
}
|
|
for i := 0; i < 3; i++ {
|
|
dest[offset] = byte(p.LipType[i])
|
|
offset++
|
|
}
|
|
for i := 0; i < 3; i++ {
|
|
dest[offset] = byte(p.ChinType[i])
|
|
offset++
|
|
}
|
|
for i := 0; i < 3; i++ {
|
|
dest[offset] = byte(p.NoseType[i])
|
|
offset++
|
|
}
|
|
dest[offset] = byte(p.BodySize)
|
|
offset++
|
|
for i := 0; i < 9; i++ {
|
|
dest[offset] = p.Unknown10[i]
|
|
offset++
|
|
}
|
|
dest[offset] = p.HairColor1.R
|
|
dest[offset+1] = p.HairColor1.G
|
|
dest[offset+2] = p.HairColor1.B
|
|
offset += 3
|
|
dest[offset] = p.HairColor2.R
|
|
dest[offset+1] = p.HairColor2.G
|
|
dest[offset+2] = p.HairColor2.B
|
|
offset += 3
|
|
for i := 0; i < 13; i++ {
|
|
dest[offset] = p.Unknown11[i]
|
|
offset++
|
|
}
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(p.SogaRaceType))
|
|
offset += 2
|
|
dest[offset] = p.SogaSkinColor.R
|
|
dest[offset+1] = p.SogaSkinColor.G
|
|
dest[offset+2] = p.SogaSkinColor.B
|
|
offset += 3
|
|
dest[offset] = p.SogaEyeColor.R
|
|
dest[offset+1] = p.SogaEyeColor.G
|
|
dest[offset+2] = p.SogaEyeColor.B
|
|
offset += 3
|
|
for i := 0; i < 3; i++ {
|
|
dest[offset] = p.Unknown12[i]
|
|
offset++
|
|
}
|
|
for i := 0; i < 3; i++ {
|
|
dest[offset] = byte(p.SogaEyeType[i])
|
|
offset++
|
|
}
|
|
for i := 0; i < 3; i++ {
|
|
dest[offset] = byte(p.SogaEarType[i])
|
|
offset++
|
|
}
|
|
for i := 0; i < 3; i++ {
|
|
dest[offset] = byte(p.SogaEyeBrowType[i])
|
|
offset++
|
|
}
|
|
for i := 0; i < 3; i++ {
|
|
dest[offset] = byte(p.SogaCheekType[i])
|
|
offset++
|
|
}
|
|
for i := 0; i < 3; i++ {
|
|
dest[offset] = byte(p.SogaLipType[i])
|
|
offset++
|
|
}
|
|
for i := 0; i < 3; i++ {
|
|
dest[offset] = byte(p.SogaChinType[i])
|
|
offset++
|
|
}
|
|
for i := 0; i < 3; i++ {
|
|
dest[offset] = byte(p.SogaNoseType[i])
|
|
offset++
|
|
}
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(p.Unknown13))
|
|
offset += 2
|
|
dest[offset] = p.SogaHairColor1.R
|
|
dest[offset+1] = p.SogaHairColor1.G
|
|
dest[offset+2] = p.SogaHairColor1.B
|
|
offset += 3
|
|
dest[offset] = p.SogaHairColor2.R
|
|
dest[offset+1] = p.SogaHairColor2.G
|
|
dest[offset+2] = p.SogaHairColor2.B
|
|
offset += 3
|
|
dest[offset] = p.Unknown14.R
|
|
dest[offset+1] = p.Unknown14.G
|
|
dest[offset+2] = p.Unknown14.B
|
|
offset += 3
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(p.SogaHairType))
|
|
offset += 2
|
|
dest[offset] = p.SogaHairTypeColor.R
|
|
dest[offset+1] = p.SogaHairTypeColor.G
|
|
dest[offset+2] = p.SogaHairTypeColor.B
|
|
offset += 3
|
|
dest[offset] = p.SogaHairTypeHighlightColor.R
|
|
dest[offset+1] = p.SogaHairTypeHighlightColor.G
|
|
dest[offset+2] = p.SogaHairTypeHighlightColor.B
|
|
offset += 3
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(p.SogaHairFaceType))
|
|
offset += 2
|
|
dest[offset] = p.SogaHairFaceColor.R
|
|
dest[offset+1] = p.SogaHairFaceColor.G
|
|
dest[offset+2] = p.SogaHairFaceColor.B
|
|
offset += 3
|
|
dest[offset] = p.SogaHairFaceHighlightColor.R
|
|
dest[offset+1] = p.SogaHairFaceHighlightColor.G
|
|
dest[offset+2] = p.SogaHairFaceHighlightColor.B
|
|
offset += 3
|
|
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 += uint32(2)
|
|
size += 4
|
|
size += 1
|
|
size += 4
|
|
size += 1
|
|
size += 2
|
|
size += 3
|
|
size += 3
|
|
size += uint32(25) * 8
|
|
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 += 2
|
|
size += 3
|
|
size += 3
|
|
size += 3
|
|
size += uint32(3)
|
|
size += uint32(3)
|
|
size += uint32(3)
|
|
size += uint32(3)
|
|
size += uint32(3)
|
|
size += uint32(3)
|
|
size += uint32(3)
|
|
size += 1
|
|
size += uint32(9)
|
|
size += 3
|
|
size += 3
|
|
size += uint32(13)
|
|
size += 2
|
|
size += 3
|
|
size += 3
|
|
size += uint32(3)
|
|
size += uint32(3)
|
|
size += uint32(3)
|
|
size += uint32(3)
|
|
size += uint32(3)
|
|
size += uint32(3)
|
|
size += uint32(3)
|
|
size += uint32(3)
|
|
size += 2
|
|
size += 3
|
|
size += 3
|
|
size += 3
|
|
size += 2
|
|
size += 3
|
|
size += 3
|
|
size += 2
|
|
size += 3
|
|
size += 3
|
|
size += uint32(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)
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.Version))
|
|
offset += 4
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.Charid))
|
|
offset += 4
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.ServerId))
|
|
offset += 4
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(len(p.Name)))
|
|
offset += 2
|
|
copy(dest[offset:], []byte(p.Name))
|
|
offset += uint32(len(p.Name))
|
|
dest[offset] = byte(p.Unknown)
|
|
offset++
|
|
dest[offset] = byte(p.Race)
|
|
offset++
|
|
dest[offset] = byte(p.Class)
|
|
offset++
|
|
dest[offset] = byte(p.Gender)
|
|
offset++
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.Level))
|
|
offset += 4
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(len(p.Zone)))
|
|
offset += 2
|
|
copy(dest[offset:], []byte(p.Zone))
|
|
offset += uint32(len(p.Zone))
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.Unknown1))
|
|
offset += 4
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.Unknown2))
|
|
offset += 4
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.CreatedDate))
|
|
offset += 4
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.LastPlayed))
|
|
offset += 4
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.Unknown3))
|
|
offset += 4
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.Unknown4))
|
|
offset += 4
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(len(p.Zonename2)))
|
|
offset += 2
|
|
copy(dest[offset:], []byte(p.Zonename2))
|
|
offset += uint32(len(p.Zonename2))
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(len(p.Zonedesc)))
|
|
offset += 2
|
|
copy(dest[offset:], []byte(p.Zonedesc))
|
|
offset += uint32(len(p.Zonedesc))
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.Unknown5))
|
|
offset += 4
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(len(p.ServerName)))
|
|
offset += 2
|
|
copy(dest[offset:], []byte(p.ServerName))
|
|
offset += uint32(len(p.ServerName))
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.AccountId))
|
|
offset += 4
|
|
for i := 0; i < 2; i++ {
|
|
dest[offset] = p.Unknown6[i]
|
|
offset++
|
|
}
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.Unknown7))
|
|
offset += 4
|
|
dest[offset] = byte(p.TradeskillClass)
|
|
offset++
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.TradeskillLevel))
|
|
offset += 4
|
|
dest[offset] = byte(p.Unknown8)
|
|
offset++
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(p.RaceType))
|
|
offset += 2
|
|
dest[offset] = p.SkinColor.R
|
|
dest[offset+1] = p.SkinColor.G
|
|
dest[offset+2] = p.SkinColor.B
|
|
offset += 3
|
|
dest[offset] = p.EyeColor.R
|
|
dest[offset+1] = p.EyeColor.G
|
|
dest[offset+2] = p.EyeColor.B
|
|
offset += 3
|
|
for i := 0; i < 25; i++ {
|
|
binary.LittleEndian.PutUint16(dest[offset:], p.Equip[i].Type)
|
|
offset += 2
|
|
dest[offset] = p.Equip[i].Color.R
|
|
dest[offset+1] = p.Equip[i].Color.G
|
|
dest[offset+2] = p.Equip[i].Color.B
|
|
offset += 3
|
|
dest[offset] = p.Equip[i].Highlight.R
|
|
dest[offset+1] = p.Equip[i].Highlight.G
|
|
dest[offset+2] = p.Equip[i].Highlight.B
|
|
offset += 3
|
|
}
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(p.HairType))
|
|
offset += 2
|
|
dest[offset] = p.HairTypeColor.R
|
|
dest[offset+1] = p.HairTypeColor.G
|
|
dest[offset+2] = p.HairTypeColor.B
|
|
offset += 3
|
|
dest[offset] = p.HairTypeHighlightColor.R
|
|
dest[offset+1] = p.HairTypeHighlightColor.G
|
|
dest[offset+2] = p.HairTypeHighlightColor.B
|
|
offset += 3
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(p.HairFaceType))
|
|
offset += 2
|
|
dest[offset] = p.HairFaceColor.R
|
|
dest[offset+1] = p.HairFaceColor.G
|
|
dest[offset+2] = p.HairFaceColor.B
|
|
offset += 3
|
|
dest[offset] = p.HairFaceHighlightColor.R
|
|
dest[offset+1] = p.HairFaceHighlightColor.G
|
|
dest[offset+2] = p.HairFaceHighlightColor.B
|
|
offset += 3
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(p.WingType))
|
|
offset += 2
|
|
dest[offset] = p.WingColor1.R
|
|
dest[offset+1] = p.WingColor1.G
|
|
dest[offset+2] = p.WingColor1.B
|
|
offset += 3
|
|
dest[offset] = p.WingColor2.R
|
|
dest[offset+1] = p.WingColor2.G
|
|
dest[offset+2] = p.WingColor2.B
|
|
offset += 3
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(p.ChestType))
|
|
offset += 2
|
|
dest[offset] = p.ShirtColor.R
|
|
dest[offset+1] = p.ShirtColor.G
|
|
dest[offset+2] = p.ShirtColor.B
|
|
offset += 3
|
|
dest[offset] = p.UnknownChestColor.R
|
|
dest[offset+1] = p.UnknownChestColor.G
|
|
dest[offset+2] = p.UnknownChestColor.B
|
|
offset += 3
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(p.LegsType))
|
|
offset += 2
|
|
dest[offset] = p.PantsColor.R
|
|
dest[offset+1] = p.PantsColor.G
|
|
dest[offset+2] = p.PantsColor.B
|
|
offset += 3
|
|
dest[offset] = p.UnknownLegsColor.R
|
|
dest[offset+1] = p.UnknownLegsColor.G
|
|
dest[offset+2] = p.UnknownLegsColor.B
|
|
offset += 3
|
|
dest[offset] = p.Unknown9.R
|
|
dest[offset+1] = p.Unknown9.G
|
|
dest[offset+2] = p.Unknown9.B
|
|
offset += 3
|
|
for i := 0; i < 3; i++ {
|
|
dest[offset] = byte(p.EyeType[i])
|
|
offset++
|
|
}
|
|
for i := 0; i < 3; i++ {
|
|
dest[offset] = byte(p.EarType[i])
|
|
offset++
|
|
}
|
|
for i := 0; i < 3; i++ {
|
|
dest[offset] = byte(p.EyeBrowType[i])
|
|
offset++
|
|
}
|
|
for i := 0; i < 3; i++ {
|
|
dest[offset] = byte(p.CheekType[i])
|
|
offset++
|
|
}
|
|
for i := 0; i < 3; i++ {
|
|
dest[offset] = byte(p.LipType[i])
|
|
offset++
|
|
}
|
|
for i := 0; i < 3; i++ {
|
|
dest[offset] = byte(p.ChinType[i])
|
|
offset++
|
|
}
|
|
for i := 0; i < 3; i++ {
|
|
dest[offset] = byte(p.NoseType[i])
|
|
offset++
|
|
}
|
|
dest[offset] = byte(p.BodySize)
|
|
offset++
|
|
for i := 0; i < 9; i++ {
|
|
dest[offset] = p.Unknown10[i]
|
|
offset++
|
|
}
|
|
dest[offset] = p.HairColor1.R
|
|
dest[offset+1] = p.HairColor1.G
|
|
dest[offset+2] = p.HairColor1.B
|
|
offset += 3
|
|
dest[offset] = p.HairColor2.R
|
|
dest[offset+1] = p.HairColor2.G
|
|
dest[offset+2] = p.HairColor2.B
|
|
offset += 3
|
|
for i := 0; i < 13; i++ {
|
|
dest[offset] = p.Unknown11[i]
|
|
offset++
|
|
}
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(p.SogaRaceType))
|
|
offset += 2
|
|
dest[offset] = p.SogaSkinColor.R
|
|
dest[offset+1] = p.SogaSkinColor.G
|
|
dest[offset+2] = p.SogaSkinColor.B
|
|
offset += 3
|
|
dest[offset] = p.SogaEyeColor.R
|
|
dest[offset+1] = p.SogaEyeColor.G
|
|
dest[offset+2] = p.SogaEyeColor.B
|
|
offset += 3
|
|
for i := 0; i < 3; i++ {
|
|
dest[offset] = p.Unknown12[i]
|
|
offset++
|
|
}
|
|
for i := 0; i < 3; i++ {
|
|
dest[offset] = byte(p.SogaEyeType[i])
|
|
offset++
|
|
}
|
|
for i := 0; i < 3; i++ {
|
|
dest[offset] = byte(p.SogaEarType[i])
|
|
offset++
|
|
}
|
|
for i := 0; i < 3; i++ {
|
|
dest[offset] = byte(p.SogaEyeBrowType[i])
|
|
offset++
|
|
}
|
|
for i := 0; i < 3; i++ {
|
|
dest[offset] = byte(p.SogaCheekType[i])
|
|
offset++
|
|
}
|
|
for i := 0; i < 3; i++ {
|
|
dest[offset] = byte(p.SogaLipType[i])
|
|
offset++
|
|
}
|
|
for i := 0; i < 3; i++ {
|
|
dest[offset] = byte(p.SogaChinType[i])
|
|
offset++
|
|
}
|
|
for i := 0; i < 3; i++ {
|
|
dest[offset] = byte(p.SogaNoseType[i])
|
|
offset++
|
|
}
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(p.Unknown13))
|
|
offset += 2
|
|
dest[offset] = p.SogaHairColor1.R
|
|
dest[offset+1] = p.SogaHairColor1.G
|
|
dest[offset+2] = p.SogaHairColor1.B
|
|
offset += 3
|
|
dest[offset] = p.SogaHairColor2.R
|
|
dest[offset+1] = p.SogaHairColor2.G
|
|
dest[offset+2] = p.SogaHairColor2.B
|
|
offset += 3
|
|
dest[offset] = p.Unknown14.R
|
|
dest[offset+1] = p.Unknown14.G
|
|
dest[offset+2] = p.Unknown14.B
|
|
offset += 3
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(p.SogaHairType))
|
|
offset += 2
|
|
dest[offset] = p.SogaHairTypeColor.R
|
|
dest[offset+1] = p.SogaHairTypeColor.G
|
|
dest[offset+2] = p.SogaHairTypeColor.B
|
|
offset += 3
|
|
dest[offset] = p.SogaHairTypeHighlightColor.R
|
|
dest[offset+1] = p.SogaHairTypeHighlightColor.G
|
|
dest[offset+2] = p.SogaHairTypeHighlightColor.B
|
|
offset += 3
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(p.SogaHairFaceType))
|
|
offset += 2
|
|
dest[offset] = p.SogaHairFaceColor.R
|
|
dest[offset+1] = p.SogaHairFaceColor.G
|
|
dest[offset+2] = p.SogaHairFaceColor.B
|
|
offset += 3
|
|
dest[offset] = p.SogaHairFaceHighlightColor.R
|
|
dest[offset+1] = p.SogaHairFaceHighlightColor.G
|
|
dest[offset+2] = p.SogaHairFaceHighlightColor.B
|
|
offset += 3
|
|
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 += uint32(2)
|
|
size += 4
|
|
size += 1
|
|
size += 4
|
|
size += 1
|
|
size += 2
|
|
size += 3
|
|
size += 3
|
|
size += uint32(25) * 8
|
|
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 += 2
|
|
size += 3
|
|
size += 3
|
|
size += 3
|
|
size += uint32(3)
|
|
size += uint32(3)
|
|
size += uint32(3)
|
|
size += uint32(3)
|
|
size += uint32(3)
|
|
size += uint32(3)
|
|
size += uint32(3)
|
|
size += 1
|
|
size += uint32(9)
|
|
size += 3
|
|
size += 3
|
|
size += uint32(13)
|
|
size += 2
|
|
size += 3
|
|
size += 3
|
|
size += uint32(3)
|
|
size += uint32(3)
|
|
size += uint32(3)
|
|
size += uint32(3)
|
|
size += uint32(3)
|
|
size += uint32(3)
|
|
size += uint32(3)
|
|
size += uint32(3)
|
|
size += 2
|
|
size += 3
|
|
size += 3
|
|
size += 3
|
|
size += 2
|
|
size += 3
|
|
size += 3
|
|
size += 2
|
|
size += 3
|
|
size += 3
|
|
size += uint32(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)
|
|
dest[offset] = byte(p.LoginResponse)
|
|
offset++
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(len(p.WorldName)))
|
|
offset += 2
|
|
copy(dest[offset:], []byte(p.WorldName))
|
|
offset += uint32(len(p.WorldName))
|
|
dest[offset] = byte(p.ParentalControlFlag)
|
|
offset++
|
|
for i := 0; i < 2; i++ {
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.ParentalControlTimer[i]))
|
|
offset += 4
|
|
}
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.ParentalControlNext))
|
|
offset += 4
|
|
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 += uint32(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)
|
|
dest[offset] = byte(p.LoginResponse)
|
|
offset++
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(len(p.Unknown)))
|
|
offset += 2
|
|
copy(dest[offset:], []byte(p.Unknown))
|
|
offset += uint32(len(p.Unknown))
|
|
dest[offset] = byte(p.ParentalControlFlag)
|
|
offset++
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.ParentalControlTimer))
|
|
offset += 4
|
|
for i := 0; i < 8; i++ {
|
|
dest[offset] = p.Unknown2[i]
|
|
offset++
|
|
}
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.CacheSettingAccountId))
|
|
offset += 4
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(len(p.Unknown3)))
|
|
offset += 2
|
|
copy(dest[offset:], []byte(p.Unknown3))
|
|
offset += uint32(len(p.Unknown3))
|
|
dest[offset] = byte(p.ResetAppearance)
|
|
offset++
|
|
dest[offset] = byte(p.DoNotForceSoga)
|
|
offset++
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(p.Unknown5))
|
|
offset += 2
|
|
dest[offset] = byte(p.Unknown6)
|
|
offset++
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.Unknown7))
|
|
offset += 4
|
|
for i := 0; i < 2; i++ {
|
|
dest[offset] = p.Unknown8[i]
|
|
offset++
|
|
}
|
|
dest[offset] = byte(p.Unknown10)
|
|
offset++
|
|
if p.Unknown10 != 0 {
|
|
dest[offset] = byte(p.NumClassItems)
|
|
offset++
|
|
}
|
|
if p.Unknown10 != 0 {
|
|
for _, elem := range p.ClassItems {
|
|
dest[offset] = elem.ClassId
|
|
offset++
|
|
dest[offset] = elem.NumItems
|
|
offset++
|
|
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++
|
|
dest[offset] = nestedElem.ModelColor.R
|
|
dest[offset+1] = nestedElem.ModelColor.G
|
|
dest[offset+2] = nestedElem.ModelColor.B
|
|
offset += 3
|
|
dest[offset] = nestedElem.ModelHighlightColor.R
|
|
dest[offset+1] = nestedElem.ModelHighlightColor.G
|
|
dest[offset+2] = nestedElem.ModelHighlightColor.B
|
|
offset += 3
|
|
}
|
|
}
|
|
}
|
|
dest[offset] = byte(p.UnknownArray2Size)
|
|
offset++
|
|
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 += uint32(8)
|
|
size += 4
|
|
size += 2 + uint32(len(p.Unknown3))
|
|
size += 1
|
|
size += 1
|
|
size += 2
|
|
size += 1
|
|
size += 4
|
|
size += uint32(2)
|
|
size += 1
|
|
if p.Unknown10 != 0 {
|
|
size += 1
|
|
}
|
|
if p.Unknown10 != 0 {
|
|
for _, elem := range p.ClassItems {
|
|
_ = elem
|
|
size += 1
|
|
size += 1
|
|
for _, nestedElem := range elem.StartingItems {
|
|
_ = nestedElem
|
|
size += 2
|
|
size += 1
|
|
size += 1
|
|
size += 1
|
|
size += 3
|
|
size += 3
|
|
|
|
}
|
|
|
|
}
|
|
}
|
|
size += 1
|
|
for _, elem := range p.UnknownArray2 {
|
|
_ = elem
|
|
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)
|
|
dest[offset] = byte(p.LoginResponse)
|
|
offset++
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(len(p.Unknown)))
|
|
offset += 2
|
|
copy(dest[offset:], []byte(p.Unknown))
|
|
offset += uint32(len(p.Unknown))
|
|
dest[offset] = byte(p.ParentalControlFlag)
|
|
offset++
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.ParentalControlTimer))
|
|
offset += 4
|
|
for i := 0; i < 8; i++ {
|
|
dest[offset] = p.Unknown2[i]
|
|
offset++
|
|
}
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.AccountId))
|
|
offset += 4
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(len(p.Unknown3)))
|
|
offset += 2
|
|
copy(dest[offset:], []byte(p.Unknown3))
|
|
offset += uint32(len(p.Unknown3))
|
|
dest[offset] = byte(p.ResetAppearance)
|
|
offset++
|
|
dest[offset] = byte(p.DoNotForceSoga)
|
|
offset++
|
|
dest[offset] = byte(p.Unknown4)
|
|
offset++
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(p.Unknown5))
|
|
offset += 2
|
|
dest[offset] = byte(p.Unknown6)
|
|
offset++
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.Unknown7))
|
|
offset += 4
|
|
dest[offset] = byte(p.RaceUnknown)
|
|
offset++
|
|
for i := 0; i < 3; i++ {
|
|
dest[offset] = p.Unknown8[i]
|
|
offset++
|
|
}
|
|
dest[offset] = byte(p.Unknown9)
|
|
offset++
|
|
dest[offset] = byte(p.Unknown10)
|
|
offset++
|
|
if p.Unknown10 != 0 {
|
|
dest[offset] = byte(p.NumClassItems)
|
|
offset++
|
|
}
|
|
if p.Unknown10 != 0 {
|
|
for _, elem := range p.ClassItems {
|
|
dest[offset] = elem.ClassId
|
|
offset++
|
|
dest[offset] = elem.NumItems
|
|
offset++
|
|
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++
|
|
dest[offset] = nestedElem.ModelColor.R
|
|
dest[offset+1] = nestedElem.ModelColor.G
|
|
dest[offset+2] = nestedElem.ModelColor.B
|
|
offset += 3
|
|
dest[offset] = nestedElem.ModelHighlightColor.R
|
|
dest[offset+1] = nestedElem.ModelHighlightColor.G
|
|
dest[offset+2] = nestedElem.ModelHighlightColor.B
|
|
offset += 3
|
|
}
|
|
}
|
|
}
|
|
dest[offset] = byte(p.UnknownArray2Size)
|
|
offset++
|
|
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 += uint32(8)
|
|
size += 4
|
|
size += 2 + uint32(len(p.Unknown3))
|
|
size += 1
|
|
size += 1
|
|
size += 1
|
|
size += 2
|
|
size += 1
|
|
size += 4
|
|
size += 1
|
|
size += uint32(3)
|
|
size += 1
|
|
size += 1
|
|
if p.Unknown10 != 0 {
|
|
size += 1
|
|
}
|
|
if p.Unknown10 != 0 {
|
|
for _, elem := range p.ClassItems {
|
|
_ = elem
|
|
size += 1
|
|
size += 1
|
|
for _, nestedElem := range elem.StartingItems {
|
|
_ = nestedElem
|
|
size += 2
|
|
size += 1
|
|
size += 1
|
|
size += 1
|
|
size += 3
|
|
size += 3
|
|
|
|
}
|
|
|
|
}
|
|
}
|
|
size += 1
|
|
for _, elem := range p.UnknownArray2 {
|
|
_ = elem
|
|
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)
|
|
dest[offset] = byte(p.LoginResponse)
|
|
offset++
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(len(p.Unknown)))
|
|
offset += 2
|
|
copy(dest[offset:], []byte(p.Unknown))
|
|
offset += uint32(len(p.Unknown))
|
|
dest[offset] = byte(p.ParentalControlFlag)
|
|
offset++
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.ParentalControlTimer))
|
|
offset += 4
|
|
for i := 0; i < 8; i++ {
|
|
dest[offset] = p.Unknown2[i]
|
|
offset++
|
|
}
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.AccountId))
|
|
offset += 4
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(len(p.Unknown3)))
|
|
offset += 2
|
|
copy(dest[offset:], []byte(p.Unknown3))
|
|
offset += uint32(len(p.Unknown3))
|
|
dest[offset] = byte(p.ResetAppearance)
|
|
offset++
|
|
dest[offset] = byte(p.DoNotForceSoga)
|
|
offset++
|
|
dest[offset] = byte(p.Unknown4)
|
|
offset++
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(p.Unknown5))
|
|
offset += 2
|
|
for i := 0; i < 5; i++ {
|
|
dest[offset] = p.Unknown6[i]
|
|
offset++
|
|
}
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.Unknown7))
|
|
offset += 4
|
|
dest[offset] = byte(p.RaceUnknown)
|
|
offset++
|
|
for i := 0; i < 3; i++ {
|
|
dest[offset] = p.Unknown8[i]
|
|
offset++
|
|
}
|
|
dest[offset] = byte(p.Unknown9)
|
|
offset++
|
|
dest[offset] = byte(p.Unknown10)
|
|
offset++
|
|
if p.Unknown10 != 0 {
|
|
dest[offset] = byte(p.NumClassItems)
|
|
offset++
|
|
}
|
|
if p.Unknown10 != 0 {
|
|
for _, elem := range p.ClassItems {
|
|
dest[offset] = elem.ClassId
|
|
offset++
|
|
dest[offset] = elem.NumItems
|
|
offset++
|
|
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++
|
|
dest[offset] = nestedElem.ModelColor.R
|
|
dest[offset+1] = nestedElem.ModelColor.G
|
|
dest[offset+2] = nestedElem.ModelColor.B
|
|
offset += 3
|
|
dest[offset] = nestedElem.ModelHighlightColor.R
|
|
dest[offset+1] = nestedElem.ModelHighlightColor.G
|
|
dest[offset+2] = nestedElem.ModelHighlightColor.B
|
|
offset += 3
|
|
}
|
|
}
|
|
}
|
|
dest[offset] = byte(p.UnknownArray2Size)
|
|
offset++
|
|
for _, elem := range p.UnknownArray2 {
|
|
binary.LittleEndian.PutUint32(dest[offset:], elem.Array2Unknown)
|
|
offset += 4
|
|
}
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.Unknown11))
|
|
offset += 4
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.SubLevel))
|
|
offset += 4
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.RaceFlag))
|
|
offset += 4
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.ClassFlag))
|
|
offset += 4
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(len(p.Password)))
|
|
offset += 2
|
|
copy(dest[offset:], []byte(p.Password))
|
|
offset += uint32(len(p.Password))
|
|
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 += uint32(8)
|
|
size += 4
|
|
size += 2 + uint32(len(p.Unknown3))
|
|
size += 1
|
|
size += 1
|
|
size += 1
|
|
size += 2
|
|
size += uint32(5)
|
|
size += 4
|
|
size += 1
|
|
size += uint32(3)
|
|
size += 1
|
|
size += 1
|
|
if p.Unknown10 != 0 {
|
|
size += 1
|
|
}
|
|
if p.Unknown10 != 0 {
|
|
for _, elem := range p.ClassItems {
|
|
_ = elem
|
|
size += 1
|
|
size += 1
|
|
for _, nestedElem := range elem.StartingItems {
|
|
_ = nestedElem
|
|
size += 2
|
|
size += 1
|
|
size += 1
|
|
size += 1
|
|
size += 3
|
|
size += 3
|
|
|
|
}
|
|
|
|
}
|
|
}
|
|
size += 1
|
|
for _, elem := range p.UnknownArray2 {
|
|
_ = elem
|
|
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)
|
|
dest[offset] = byte(p.LoginResponse)
|
|
offset++
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(len(p.Unknown)))
|
|
offset += 2
|
|
copy(dest[offset:], []byte(p.Unknown))
|
|
offset += uint32(len(p.Unknown))
|
|
dest[offset] = byte(p.ParentalControlFlag)
|
|
offset++
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.ParentalControlTimer))
|
|
offset += 4
|
|
for i := 0; i < 8; i++ {
|
|
dest[offset] = p.Unknown2[i]
|
|
offset++
|
|
}
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.AccountId))
|
|
offset += 4
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(len(p.Unknown3)))
|
|
offset += 2
|
|
copy(dest[offset:], []byte(p.Unknown3))
|
|
offset += uint32(len(p.Unknown3))
|
|
dest[offset] = byte(p.ResetAppearance)
|
|
offset++
|
|
dest[offset] = byte(p.DoNotForceSoga)
|
|
offset++
|
|
dest[offset] = byte(p.Unknown4)
|
|
offset++
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(p.Unknown5))
|
|
offset += 2
|
|
for i := 0; i < 5; i++ {
|
|
dest[offset] = p.Unknown6[i]
|
|
offset++
|
|
}
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.Unknown7))
|
|
offset += 4
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.Unknown7a))
|
|
offset += 4
|
|
dest[offset] = byte(p.RaceUnknown)
|
|
offset++
|
|
for i := 0; i < 3; i++ {
|
|
dest[offset] = p.Unknown8[i]
|
|
offset++
|
|
}
|
|
dest[offset] = byte(p.Unknown9)
|
|
offset++
|
|
dest[offset] = byte(p.Unknown10)
|
|
offset++
|
|
if p.Unknown10 != 0 {
|
|
dest[offset] = byte(p.NumClassItems)
|
|
offset++
|
|
}
|
|
if p.Unknown10 != 0 {
|
|
for _, elem := range p.ClassItems {
|
|
dest[offset] = elem.ClassId
|
|
offset++
|
|
dest[offset] = elem.NumItems
|
|
offset++
|
|
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++
|
|
dest[offset] = nestedElem.ModelColor.R
|
|
dest[offset+1] = nestedElem.ModelColor.G
|
|
dest[offset+2] = nestedElem.ModelColor.B
|
|
offset += 3
|
|
dest[offset] = nestedElem.ModelHighlightColor.R
|
|
dest[offset+1] = nestedElem.ModelHighlightColor.G
|
|
dest[offset+2] = nestedElem.ModelHighlightColor.B
|
|
offset += 3
|
|
}
|
|
}
|
|
}
|
|
dest[offset] = byte(p.UnknownArray2Size)
|
|
offset++
|
|
for _, elem := range p.UnknownArray2 {
|
|
binary.LittleEndian.PutUint32(dest[offset:], elem.Array2Unknown)
|
|
offset += 4
|
|
}
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.Unknown11))
|
|
offset += 4
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.SubLevel))
|
|
offset += 4
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.RaceFlag))
|
|
offset += 4
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.ClassFlag))
|
|
offset += 4
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(len(p.Password)))
|
|
offset += 2
|
|
copy(dest[offset:], []byte(p.Password))
|
|
offset += uint32(len(p.Password))
|
|
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 += uint32(8)
|
|
size += 4
|
|
size += 2 + uint32(len(p.Unknown3))
|
|
size += 1
|
|
size += 1
|
|
size += 1
|
|
size += 2
|
|
size += uint32(5)
|
|
size += 4
|
|
size += 4
|
|
size += 1
|
|
size += uint32(3)
|
|
size += 1
|
|
size += 1
|
|
if p.Unknown10 != 0 {
|
|
size += 1
|
|
}
|
|
if p.Unknown10 != 0 {
|
|
for _, elem := range p.ClassItems {
|
|
_ = elem
|
|
size += 1
|
|
size += 1
|
|
for _, nestedElem := range elem.StartingItems {
|
|
_ = nestedElem
|
|
size += 2
|
|
size += 1
|
|
size += 1
|
|
size += 1
|
|
size += 3
|
|
size += 3
|
|
|
|
}
|
|
|
|
}
|
|
}
|
|
size += 1
|
|
for _, elem := range p.UnknownArray2 {
|
|
_ = elem
|
|
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)
|
|
dest[offset] = byte(p.LoginResponse)
|
|
offset++
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(len(p.Unknown)))
|
|
offset += 2
|
|
copy(dest[offset:], []byte(p.Unknown))
|
|
offset += uint32(len(p.Unknown))
|
|
dest[offset] = byte(p.ParentalControlFlag)
|
|
offset++
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.ParentalControlTimer))
|
|
offset += 4
|
|
for i := 0; i < 8; i++ {
|
|
dest[offset] = p.Unknown2[i]
|
|
offset++
|
|
}
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.AccountId))
|
|
offset += 4
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(len(p.Unknown3)))
|
|
offset += 2
|
|
copy(dest[offset:], []byte(p.Unknown3))
|
|
offset += uint32(len(p.Unknown3))
|
|
dest[offset] = byte(p.ResetAppearance)
|
|
offset++
|
|
dest[offset] = byte(p.DoNotForceSoga)
|
|
offset++
|
|
dest[offset] = byte(p.Unknown4)
|
|
offset++
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(p.Unknown5))
|
|
offset += 2
|
|
for i := 0; i < 5; i++ {
|
|
dest[offset] = p.Unknown6[i]
|
|
offset++
|
|
}
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.Unknown7))
|
|
offset += 4
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.Unknown7a))
|
|
offset += 4
|
|
dest[offset] = byte(p.RaceUnknown)
|
|
offset++
|
|
for i := 0; i < 3; i++ {
|
|
dest[offset] = p.Unknown8[i]
|
|
offset++
|
|
}
|
|
dest[offset] = byte(p.Unknown9)
|
|
offset++
|
|
dest[offset] = byte(p.Unknown10)
|
|
offset++
|
|
if p.Unknown10 != 0 {
|
|
dest[offset] = byte(p.NumClassItems)
|
|
offset++
|
|
}
|
|
if p.Unknown10 != 0 {
|
|
for _, elem := range p.ClassItems {
|
|
dest[offset] = elem.ClassId
|
|
offset++
|
|
dest[offset] = elem.NumItems
|
|
offset++
|
|
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++
|
|
dest[offset] = nestedElem.ModelColor.R
|
|
dest[offset+1] = nestedElem.ModelColor.G
|
|
dest[offset+2] = nestedElem.ModelColor.B
|
|
offset += 3
|
|
dest[offset] = nestedElem.ModelHighlightColor.R
|
|
dest[offset+1] = nestedElem.ModelHighlightColor.G
|
|
dest[offset+2] = nestedElem.ModelHighlightColor.B
|
|
offset += 3
|
|
}
|
|
}
|
|
}
|
|
dest[offset] = byte(p.UnknownArray2Size)
|
|
offset++
|
|
for _, elem := range p.UnknownArray2 {
|
|
binary.LittleEndian.PutUint32(dest[offset:], elem.Array2Unknown)
|
|
offset += 4
|
|
}
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.Unknown11))
|
|
offset += 4
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.SubLevel))
|
|
offset += 4
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.RaceFlag))
|
|
offset += 4
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.ClassFlag))
|
|
offset += 4
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(len(p.Password)))
|
|
offset += 2
|
|
copy(dest[offset:], []byte(p.Password))
|
|
offset += uint32(len(p.Password))
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(len(p.Username)))
|
|
offset += 2
|
|
copy(dest[offset:], []byte(p.Username))
|
|
offset += uint32(len(p.Username))
|
|
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 += uint32(8)
|
|
size += 4
|
|
size += 2 + uint32(len(p.Unknown3))
|
|
size += 1
|
|
size += 1
|
|
size += 1
|
|
size += 2
|
|
size += uint32(5)
|
|
size += 4
|
|
size += 4
|
|
size += 1
|
|
size += uint32(3)
|
|
size += 1
|
|
size += 1
|
|
if p.Unknown10 != 0 {
|
|
size += 1
|
|
}
|
|
if p.Unknown10 != 0 {
|
|
for _, elem := range p.ClassItems {
|
|
_ = elem
|
|
size += 1
|
|
size += 1
|
|
for _, nestedElem := range elem.StartingItems {
|
|
_ = nestedElem
|
|
size += 2
|
|
size += 1
|
|
size += 1
|
|
size += 1
|
|
size += 3
|
|
size += 3
|
|
|
|
}
|
|
|
|
}
|
|
}
|
|
size += 1
|
|
for _, elem := range p.UnknownArray2 {
|
|
_ = elem
|
|
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)
|
|
dest[offset] = byte(p.LoginResponse)
|
|
offset++
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(len(p.Unknown)))
|
|
offset += 2
|
|
copy(dest[offset:], []byte(p.Unknown))
|
|
offset += uint32(len(p.Unknown))
|
|
dest[offset] = byte(p.ParentalControlFlag)
|
|
offset++
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.ParentalControlTimer))
|
|
offset += 4
|
|
for i := 0; i < 8; i++ {
|
|
dest[offset] = p.Unknown2[i]
|
|
offset++
|
|
}
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.AccountId))
|
|
offset += 4
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(len(p.Unknown3)))
|
|
offset += 2
|
|
copy(dest[offset:], []byte(p.Unknown3))
|
|
offset += uint32(len(p.Unknown3))
|
|
dest[offset] = byte(p.ResetAppearance)
|
|
offset++
|
|
dest[offset] = byte(p.DoNotForceSoga)
|
|
offset++
|
|
dest[offset] = byte(p.Unknown4)
|
|
offset++
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(p.Unknown5))
|
|
offset += 2
|
|
for i := 0; i < 5; i++ {
|
|
dest[offset] = p.Unknown6[i]
|
|
offset++
|
|
}
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.Unknown7))
|
|
offset += 4
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.Unknown7a))
|
|
offset += 4
|
|
dest[offset] = byte(p.RaceUnknown)
|
|
offset++
|
|
for i := 0; i < 3; i++ {
|
|
dest[offset] = p.Unknown8[i]
|
|
offset++
|
|
}
|
|
dest[offset] = byte(p.Unknown9)
|
|
offset++
|
|
dest[offset] = byte(p.Unknown10)
|
|
offset++
|
|
if p.Unknown10 != 0 {
|
|
dest[offset] = byte(p.NumClassItems)
|
|
offset++
|
|
}
|
|
if p.Unknown10 != 0 {
|
|
for _, elem := range p.ClassItems {
|
|
dest[offset] = elem.ClassId
|
|
offset++
|
|
dest[offset] = elem.NumItems
|
|
offset++
|
|
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++
|
|
dest[offset] = nestedElem.ModelColor.R
|
|
dest[offset+1] = nestedElem.ModelColor.G
|
|
dest[offset+2] = nestedElem.ModelColor.B
|
|
offset += 3
|
|
dest[offset] = nestedElem.ModelHighlightColor.R
|
|
dest[offset+1] = nestedElem.ModelHighlightColor.G
|
|
dest[offset+2] = nestedElem.ModelHighlightColor.B
|
|
offset += 3
|
|
}
|
|
}
|
|
}
|
|
dest[offset] = byte(p.UnknownArray2Size)
|
|
offset++
|
|
for _, elem := range p.UnknownArray2 {
|
|
binary.LittleEndian.PutUint32(dest[offset:], elem.Array2Unknown)
|
|
offset += 4
|
|
}
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.Unknown11))
|
|
offset += 4
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.SubLevel))
|
|
offset += 4
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.RaceFlag))
|
|
offset += 4
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.ClassFlag))
|
|
offset += 4
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(len(p.Password)))
|
|
offset += 2
|
|
copy(dest[offset:], []byte(p.Password))
|
|
offset += uint32(len(p.Password))
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(len(p.Username)))
|
|
offset += 2
|
|
copy(dest[offset:], []byte(p.Username))
|
|
offset += uint32(len(p.Username))
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(len(p.Service)))
|
|
offset += 2
|
|
copy(dest[offset:], []byte(p.Service))
|
|
offset += uint32(len(p.Service))
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(len(p.Web1)))
|
|
offset += 2
|
|
copy(dest[offset:], []byte(p.Web1))
|
|
offset += uint32(len(p.Web1))
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(len(p.Web2)))
|
|
offset += 2
|
|
copy(dest[offset:], []byte(p.Web2))
|
|
offset += uint32(len(p.Web2))
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(len(p.Web3)))
|
|
offset += 2
|
|
copy(dest[offset:], []byte(p.Web3))
|
|
offset += uint32(len(p.Web3))
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(len(p.Web4)))
|
|
offset += 2
|
|
copy(dest[offset:], []byte(p.Web4))
|
|
offset += uint32(len(p.Web4))
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(len(p.Web5)))
|
|
offset += 2
|
|
copy(dest[offset:], []byte(p.Web5))
|
|
offset += uint32(len(p.Web5))
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(len(p.Web6)))
|
|
offset += 2
|
|
copy(dest[offset:], []byte(p.Web6))
|
|
offset += uint32(len(p.Web6))
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(len(p.Web7)))
|
|
offset += 2
|
|
copy(dest[offset:], []byte(p.Web7))
|
|
offset += uint32(len(p.Web7))
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(len(p.Web8)))
|
|
offset += 2
|
|
copy(dest[offset:], []byte(p.Web8))
|
|
offset += uint32(len(p.Web8))
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(len(p.Web9)))
|
|
offset += 2
|
|
copy(dest[offset:], []byte(p.Web9))
|
|
offset += uint32(len(p.Web9))
|
|
dest[offset] = byte(p.Unknown12)
|
|
offset++
|
|
if p.Unknown10 != 0 {
|
|
dest[offset] = byte(p.Lvl90NumClassItems)
|
|
offset++
|
|
}
|
|
if p.Unknown10 != 0 {
|
|
for _, elem := range p.Lvl90ClassItems {
|
|
dest[offset] = elem.ClassId
|
|
offset++
|
|
dest[offset] = elem.NumItems
|
|
offset++
|
|
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++
|
|
dest[offset] = nestedElem.ModelColor.R
|
|
dest[offset+1] = nestedElem.ModelColor.G
|
|
dest[offset+2] = nestedElem.ModelColor.B
|
|
offset += 3
|
|
dest[offset] = nestedElem.ModelHighlightColor.R
|
|
dest[offset+1] = nestedElem.ModelHighlightColor.G
|
|
dest[offset+2] = nestedElem.ModelHighlightColor.B
|
|
offset += 3
|
|
}
|
|
}
|
|
}
|
|
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 += uint32(8)
|
|
size += 4
|
|
size += 2 + uint32(len(p.Unknown3))
|
|
size += 1
|
|
size += 1
|
|
size += 1
|
|
size += 2
|
|
size += uint32(5)
|
|
size += 4
|
|
size += 4
|
|
size += 1
|
|
size += uint32(3)
|
|
size += 1
|
|
size += 1
|
|
if p.Unknown10 != 0 {
|
|
size += 1
|
|
}
|
|
if p.Unknown10 != 0 {
|
|
for _, elem := range p.ClassItems {
|
|
_ = elem
|
|
size += 1
|
|
size += 1
|
|
for _, nestedElem := range elem.StartingItems {
|
|
_ = nestedElem
|
|
size += 4
|
|
size += 1
|
|
size += 1
|
|
size += 1
|
|
size += 3
|
|
size += 3
|
|
|
|
}
|
|
|
|
}
|
|
}
|
|
size += 1
|
|
for _, elem := range p.UnknownArray2 {
|
|
_ = elem
|
|
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
|
|
if p.Unknown10 != 0 {
|
|
size += 1
|
|
}
|
|
if p.Unknown10 != 0 {
|
|
for _, elem := range p.Lvl90ClassItems {
|
|
_ = elem
|
|
size += 1
|
|
size += 1
|
|
for _, nestedElem := range elem.StartingItems {
|
|
_ = nestedElem
|
|
size += 4
|
|
size += 1
|
|
size += 1
|
|
size += 1
|
|
size += 3
|
|
size += 3
|
|
|
|
}
|
|
|
|
}
|
|
}
|
|
size += uint32(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)
|
|
dest[offset] = byte(p.LoginResponse)
|
|
offset++
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(len(p.Unknown)))
|
|
offset += 2
|
|
copy(dest[offset:], []byte(p.Unknown))
|
|
offset += uint32(len(p.Unknown))
|
|
dest[offset] = byte(p.ParentalControlFlag)
|
|
offset++
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.ParentalControlTimer))
|
|
offset += 4
|
|
for i := 0; i < 8; i++ {
|
|
dest[offset] = p.Unknown2[i]
|
|
offset++
|
|
}
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.AccountId))
|
|
offset += 4
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(len(p.Unknown3)))
|
|
offset += 2
|
|
copy(dest[offset:], []byte(p.Unknown3))
|
|
offset += uint32(len(p.Unknown3))
|
|
dest[offset] = byte(p.ResetAppearance)
|
|
offset++
|
|
dest[offset] = byte(p.DoNotForceSoga)
|
|
offset++
|
|
binary.LittleEndian.PutUint64(dest[offset:], uint64(p.Unknown5))
|
|
offset += 8
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.Unknown7))
|
|
offset += 4
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(p.Unknown7a))
|
|
offset += 2
|
|
dest[offset] = byte(p.RaceUnknown)
|
|
offset++
|
|
for i := 0; i < 3; i++ {
|
|
dest[offset] = p.Unknown8[i]
|
|
offset++
|
|
}
|
|
for i := 0; i < 3; i++ {
|
|
dest[offset] = p.Unknown9[i]
|
|
offset++
|
|
}
|
|
dest[offset] = byte(p.Unknown10)
|
|
offset++
|
|
if p.Unknown10 != 0 {
|
|
dest[offset] = byte(p.NumClassItems)
|
|
offset++
|
|
}
|
|
if p.Unknown10 != 0 {
|
|
for _, elem := range p.ClassItems {
|
|
dest[offset] = elem.ClassId
|
|
offset++
|
|
dest[offset] = elem.NumItems
|
|
offset++
|
|
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++
|
|
dest[offset] = nestedElem.ModelColor.R
|
|
dest[offset+1] = nestedElem.ModelColor.G
|
|
dest[offset+2] = nestedElem.ModelColor.B
|
|
offset += 3
|
|
dest[offset] = nestedElem.ModelHighlightColor.R
|
|
dest[offset+1] = nestedElem.ModelHighlightColor.G
|
|
dest[offset+2] = nestedElem.ModelHighlightColor.B
|
|
offset += 3
|
|
}
|
|
}
|
|
}
|
|
dest[offset] = byte(p.UnknownArray2Size)
|
|
offset++
|
|
for _, elem := range p.UnknownArray2 {
|
|
binary.LittleEndian.PutUint32(dest[offset:], elem.Array2Unknown)
|
|
offset += 4
|
|
}
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.Unknown11))
|
|
offset += 4
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.SubLevel))
|
|
offset += 4
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.RaceFlag))
|
|
offset += 4
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.ClassFlag))
|
|
offset += 4
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(len(p.Password)))
|
|
offset += 2
|
|
copy(dest[offset:], []byte(p.Password))
|
|
offset += uint32(len(p.Password))
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(len(p.Username)))
|
|
offset += 2
|
|
copy(dest[offset:], []byte(p.Username))
|
|
offset += uint32(len(p.Username))
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(len(p.Service)))
|
|
offset += 2
|
|
copy(dest[offset:], []byte(p.Service))
|
|
offset += uint32(len(p.Service))
|
|
dest[offset] = byte(p.Unknown12)
|
|
offset++
|
|
if p.Unknown12 != 0 {
|
|
dest[offset] = byte(p.Lvl90NumClassItems)
|
|
offset++
|
|
}
|
|
if p.Unknown12 != 0 {
|
|
for _, elem := range p.Lvl90ClassItems {
|
|
dest[offset] = elem.ClassId
|
|
offset++
|
|
dest[offset] = elem.NumItems
|
|
offset++
|
|
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++
|
|
dest[offset] = nestedElem.ModelColor.R
|
|
dest[offset+1] = nestedElem.ModelColor.G
|
|
dest[offset+2] = nestedElem.ModelColor.B
|
|
offset += 3
|
|
dest[offset] = nestedElem.ModelHighlightColor.R
|
|
dest[offset+1] = nestedElem.ModelHighlightColor.G
|
|
dest[offset+2] = nestedElem.ModelHighlightColor.B
|
|
offset += 3
|
|
}
|
|
}
|
|
}
|
|
dest[offset] = byte(p.Unknown13)
|
|
offset++
|
|
if p.Unknown13 != 0 {
|
|
dest[offset] = byte(p.TimeLockedNumClassItems)
|
|
offset++
|
|
}
|
|
if p.Unknown13 != 0 {
|
|
for _, elem := range p.TimeLockedClassItems {
|
|
dest[offset] = elem.ClassId
|
|
offset++
|
|
dest[offset] = elem.NumItems
|
|
offset++
|
|
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++
|
|
dest[offset] = nestedElem.ModelColor.R
|
|
dest[offset+1] = nestedElem.ModelColor.G
|
|
dest[offset+2] = nestedElem.ModelColor.B
|
|
offset += 3
|
|
dest[offset] = nestedElem.ModelHighlightColor.R
|
|
dest[offset+1] = nestedElem.ModelHighlightColor.G
|
|
dest[offset+2] = nestedElem.ModelHighlightColor.B
|
|
offset += 3
|
|
}
|
|
}
|
|
}
|
|
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 += uint32(8)
|
|
size += 4
|
|
size += 2 + uint32(len(p.Unknown3))
|
|
size += 1
|
|
size += 1
|
|
size += 8
|
|
size += 4
|
|
size += 2
|
|
size += 1
|
|
size += uint32(3)
|
|
size += uint32(3)
|
|
size += 1
|
|
if p.Unknown10 != 0 {
|
|
size += 1
|
|
}
|
|
if p.Unknown10 != 0 {
|
|
for _, elem := range p.ClassItems {
|
|
_ = elem
|
|
size += 1
|
|
size += 1
|
|
for _, nestedElem := range elem.StartingItems {
|
|
_ = nestedElem
|
|
size += 4
|
|
size += 1
|
|
size += 1
|
|
size += 1
|
|
size += 3
|
|
size += 3
|
|
|
|
}
|
|
|
|
}
|
|
}
|
|
size += 1
|
|
for _, elem := range p.UnknownArray2 {
|
|
_ = elem
|
|
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
|
|
if p.Unknown12 != 0 {
|
|
size += 1
|
|
}
|
|
if p.Unknown12 != 0 {
|
|
for _, elem := range p.Lvl90ClassItems {
|
|
_ = elem
|
|
size += 1
|
|
size += 1
|
|
for _, nestedElem := range elem.StartingItems {
|
|
_ = nestedElem
|
|
size += 4
|
|
size += 1
|
|
size += 1
|
|
size += 1
|
|
size += 3
|
|
size += 3
|
|
|
|
}
|
|
|
|
}
|
|
}
|
|
size += 1
|
|
if p.Unknown13 != 0 {
|
|
size += 1
|
|
}
|
|
if p.Unknown13 != 0 {
|
|
for _, elem := range p.TimeLockedClassItems {
|
|
_ = elem
|
|
size += 1
|
|
size += 1
|
|
for _, nestedElem := range elem.StartingItems {
|
|
_ = nestedElem
|
|
size += 4
|
|
size += 1
|
|
size += 1
|
|
size += 1
|
|
size += 3
|
|
size += 3
|
|
|
|
}
|
|
|
|
}
|
|
}
|
|
size += uint32(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)
|
|
dest[offset] = byte(p.LoginResponse)
|
|
offset++
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(len(p.Unknown)))
|
|
offset += 2
|
|
copy(dest[offset:], []byte(p.Unknown))
|
|
offset += uint32(len(p.Unknown))
|
|
dest[offset] = byte(p.ParentalControlFlag)
|
|
offset++
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.ParentalControlTimer))
|
|
offset += 4
|
|
for i := 0; i < 8; i++ {
|
|
dest[offset] = p.Unknown2[i]
|
|
offset++
|
|
}
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.AccountId))
|
|
offset += 4
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(len(p.Unknown3)))
|
|
offset += 2
|
|
copy(dest[offset:], []byte(p.Unknown3))
|
|
offset += uint32(len(p.Unknown3))
|
|
dest[offset] = byte(p.ResetAppearance)
|
|
offset++
|
|
dest[offset] = byte(p.DoNotForceSoga)
|
|
offset++
|
|
dest[offset] = byte(p.Unknown4)
|
|
offset++
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(p.Unknown5))
|
|
offset += 2
|
|
for i := 0; i < 5; i++ {
|
|
dest[offset] = p.Unknown6[i]
|
|
offset++
|
|
}
|
|
for i := 0; i < 8; i++ {
|
|
dest[offset] = p.Unknown6a[i]
|
|
offset++
|
|
}
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.Unknown7))
|
|
offset += 4
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(p.Unknown7a))
|
|
offset += 2
|
|
dest[offset] = byte(p.RaceUnknown)
|
|
offset++
|
|
for i := 0; i < 3; i++ {
|
|
dest[offset] = p.Unknown8[i]
|
|
offset++
|
|
}
|
|
for i := 0; i < 3; i++ {
|
|
dest[offset] = p.Unknown9[i]
|
|
offset++
|
|
}
|
|
dest[offset] = byte(p.Unknown10)
|
|
offset++
|
|
if p.Unknown10 != 0 {
|
|
dest[offset] = byte(p.NumClassItems)
|
|
offset++
|
|
}
|
|
if p.Unknown10 != 0 {
|
|
for _, elem := range p.ClassItems {
|
|
dest[offset] = elem.ClassId
|
|
offset++
|
|
dest[offset] = elem.NumItems
|
|
offset++
|
|
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++
|
|
dest[offset] = nestedElem.ModelColor.R
|
|
dest[offset+1] = nestedElem.ModelColor.G
|
|
dest[offset+2] = nestedElem.ModelColor.B
|
|
offset += 3
|
|
dest[offset] = nestedElem.ModelHighlightColor.R
|
|
dest[offset+1] = nestedElem.ModelHighlightColor.G
|
|
dest[offset+2] = nestedElem.ModelHighlightColor.B
|
|
offset += 3
|
|
}
|
|
}
|
|
}
|
|
dest[offset] = byte(p.UnknownArray2Size)
|
|
offset++
|
|
for _, elem := range p.UnknownArray2 {
|
|
binary.LittleEndian.PutUint32(dest[offset:], elem.Array2Unknown)
|
|
offset += 4
|
|
}
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.Unknown11))
|
|
offset += 4
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.SubLevel))
|
|
offset += 4
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.RaceFlag))
|
|
offset += 4
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.ClassFlag))
|
|
offset += 4
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(len(p.Password)))
|
|
offset += 2
|
|
copy(dest[offset:], []byte(p.Password))
|
|
offset += uint32(len(p.Password))
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(len(p.Username)))
|
|
offset += 2
|
|
copy(dest[offset:], []byte(p.Username))
|
|
offset += uint32(len(p.Username))
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(len(p.Service)))
|
|
offset += 2
|
|
copy(dest[offset:], []byte(p.Service))
|
|
offset += uint32(len(p.Service))
|
|
dest[offset] = byte(p.Unknown12)
|
|
offset++
|
|
if p.Unknown12 != 0 {
|
|
dest[offset] = byte(p.Lvl90NumClassItems)
|
|
offset++
|
|
}
|
|
if p.Unknown12 != 0 {
|
|
for _, elem := range p.Lvl90ClassItems {
|
|
dest[offset] = elem.ClassId
|
|
offset++
|
|
dest[offset] = elem.NumItems
|
|
offset++
|
|
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++
|
|
dest[offset] = nestedElem.ModelColor.R
|
|
dest[offset+1] = nestedElem.ModelColor.G
|
|
dest[offset+2] = nestedElem.ModelColor.B
|
|
offset += 3
|
|
dest[offset] = nestedElem.ModelHighlightColor.R
|
|
dest[offset+1] = nestedElem.ModelHighlightColor.G
|
|
dest[offset+2] = nestedElem.ModelHighlightColor.B
|
|
offset += 3
|
|
}
|
|
}
|
|
}
|
|
dest[offset] = byte(p.Unknown13)
|
|
offset++
|
|
if p.Unknown13 != 0 {
|
|
dest[offset] = byte(p.TimeLockedNumClassItems)
|
|
offset++
|
|
}
|
|
if p.Unknown13 != 0 {
|
|
for _, elem := range p.TimeLockedClassItems {
|
|
dest[offset] = elem.ClassId
|
|
offset++
|
|
dest[offset] = elem.NumItems
|
|
offset++
|
|
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++
|
|
dest[offset] = nestedElem.ModelColor.R
|
|
dest[offset+1] = nestedElem.ModelColor.G
|
|
dest[offset+2] = nestedElem.ModelColor.B
|
|
offset += 3
|
|
dest[offset] = nestedElem.ModelHighlightColor.R
|
|
dest[offset+1] = nestedElem.ModelHighlightColor.G
|
|
dest[offset+2] = nestedElem.ModelHighlightColor.B
|
|
offset += 3
|
|
}
|
|
}
|
|
}
|
|
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 += uint32(8)
|
|
size += 4
|
|
size += 2 + uint32(len(p.Unknown3))
|
|
size += 1
|
|
size += 1
|
|
size += 1
|
|
size += 2
|
|
size += uint32(5)
|
|
size += uint32(8)
|
|
size += 4
|
|
size += 2
|
|
size += 1
|
|
size += uint32(3)
|
|
size += uint32(3)
|
|
size += 1
|
|
if p.Unknown10 != 0 {
|
|
size += 1
|
|
}
|
|
if p.Unknown10 != 0 {
|
|
for _, elem := range p.ClassItems {
|
|
_ = elem
|
|
size += 1
|
|
size += 1
|
|
for _, nestedElem := range elem.StartingItems {
|
|
_ = nestedElem
|
|
size += 4
|
|
size += 1
|
|
size += 1
|
|
size += 1
|
|
size += 3
|
|
size += 3
|
|
|
|
}
|
|
|
|
}
|
|
}
|
|
size += 1
|
|
for _, elem := range p.UnknownArray2 {
|
|
_ = elem
|
|
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
|
|
if p.Unknown12 != 0 {
|
|
size += 1
|
|
}
|
|
if p.Unknown12 != 0 {
|
|
for _, elem := range p.Lvl90ClassItems {
|
|
_ = elem
|
|
size += 1
|
|
size += 1
|
|
for _, nestedElem := range elem.StartingItems {
|
|
_ = nestedElem
|
|
size += 4
|
|
size += 1
|
|
size += 1
|
|
size += 1
|
|
size += 3
|
|
size += 3
|
|
|
|
}
|
|
|
|
}
|
|
}
|
|
size += 1
|
|
if p.Unknown13 != 0 {
|
|
size += 1
|
|
}
|
|
if p.Unknown13 != 0 {
|
|
for _, elem := range p.TimeLockedClassItems {
|
|
_ = elem
|
|
size += 1
|
|
size += 1
|
|
for _, nestedElem := range elem.StartingItems {
|
|
_ = nestedElem
|
|
size += 4
|
|
size += 1
|
|
size += 1
|
|
size += 1
|
|
size += 3
|
|
size += 3
|
|
|
|
}
|
|
|
|
}
|
|
}
|
|
size += uint32(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)
|
|
dest[offset] = byte(p.LoginResponse)
|
|
offset++
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(len(p.WorldName)))
|
|
offset += 2
|
|
copy(dest[offset:], []byte(p.WorldName))
|
|
offset += uint32(len(p.WorldName))
|
|
dest[offset] = byte(p.ParentalControlFlag)
|
|
offset++
|
|
binary.LittleEndian.PutUint64(dest[offset:], uint64(p.ParentalControlTimer))
|
|
offset += 8
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.Unknown2))
|
|
offset += 4
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.AccountId))
|
|
offset += 4
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(len(p.Unknown3)))
|
|
offset += 2
|
|
copy(dest[offset:], []byte(p.Unknown3))
|
|
offset += uint32(len(p.Unknown3))
|
|
dest[offset] = byte(p.ResetAppearance)
|
|
offset++
|
|
dest[offset] = byte(p.DoNotForceSoga)
|
|
offset++
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(len(p.Unknown4)))
|
|
offset += 4
|
|
copy(dest[offset:], []byte(p.Unknown4))
|
|
offset += uint32(len(p.Unknown4))
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(len(p.Unknown7)))
|
|
offset += 4
|
|
copy(dest[offset:], []byte(p.Unknown7))
|
|
offset += uint32(len(p.Unknown7))
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.RaceUnknown))
|
|
offset += 4
|
|
dest[offset] = byte(p.Unknown8)
|
|
offset++
|
|
dest[offset] = byte(p.Unknown10)
|
|
offset++
|
|
if p.Unknown10 != 0 {
|
|
dest[offset] = byte(p.NumClassItems)
|
|
offset++
|
|
}
|
|
if p.Unknown10 != 0 {
|
|
for _, elem := range p.ClassItems {
|
|
dest[offset] = elem.ClassId
|
|
offset++
|
|
dest[offset] = elem.NumItems
|
|
offset++
|
|
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++
|
|
dest[offset] = nestedElem.ModelColor.R
|
|
dest[offset+1] = nestedElem.ModelColor.G
|
|
dest[offset+2] = nestedElem.ModelColor.B
|
|
offset += 3
|
|
dest[offset] = nestedElem.ModelHighlightColor.R
|
|
dest[offset+1] = nestedElem.ModelHighlightColor.G
|
|
dest[offset+2] = nestedElem.ModelHighlightColor.B
|
|
offset += 3
|
|
}
|
|
}
|
|
}
|
|
dest[offset] = byte(p.UnknownArray2Size)
|
|
offset++
|
|
if p.UnknownArray2Size != 0 {
|
|
for _, elem := range p.UnknownArray2 {
|
|
binary.LittleEndian.PutUint32(dest[offset:], elem.Array2Unknown)
|
|
offset += 4
|
|
}
|
|
}
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.Unknown11))
|
|
offset += 4
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.SubLevel))
|
|
offset += 4
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.RaceFlag))
|
|
offset += 4
|
|
binary.LittleEndian.PutUint32(dest[offset:], uint32(p.ClassFlag))
|
|
offset += 4
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(len(p.Password)))
|
|
offset += 2
|
|
copy(dest[offset:], []byte(p.Password))
|
|
offset += uint32(len(p.Password))
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(len(p.Username)))
|
|
offset += 2
|
|
copy(dest[offset:], []byte(p.Username))
|
|
offset += uint32(len(p.Username))
|
|
binary.LittleEndian.PutUint16(dest[offset:], uint16(len(p.Service)))
|
|
offset += 2
|
|
copy(dest[offset:], []byte(p.Service))
|
|
offset += uint32(len(p.Service))
|
|
dest[offset] = byte(p.Unknown12)
|
|
offset++
|
|
if p.Unknown12 != 0 {
|
|
dest[offset] = byte(p.Lvl90NumClassItems)
|
|
offset++
|
|
}
|
|
if p.Unknown12 != 0 {
|
|
for _, elem := range p.Lvl90ClassItems {
|
|
dest[offset] = elem.ClassId
|
|
offset++
|
|
dest[offset] = elem.NumItems
|
|
offset++
|
|
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++
|
|
dest[offset] = nestedElem.ModelColor.R
|
|
dest[offset+1] = nestedElem.ModelColor.G
|
|
dest[offset+2] = nestedElem.ModelColor.B
|
|
offset += 3
|
|
dest[offset] = nestedElem.ModelHighlightColor.R
|
|
dest[offset+1] = nestedElem.ModelHighlightColor.G
|
|
dest[offset+2] = nestedElem.ModelHighlightColor.B
|
|
offset += 3
|
|
}
|
|
}
|
|
}
|
|
dest[offset] = byte(p.Unknown13)
|
|
offset++
|
|
if p.Unknown13 != 0 {
|
|
dest[offset] = byte(p.TimeLockedNumClassItems)
|
|
offset++
|
|
}
|
|
if p.Unknown13 != 0 {
|
|
for _, elem := range p.TimeLockedClassItems {
|
|
dest[offset] = elem.ClassId
|
|
offset++
|
|
dest[offset] = elem.NumItems
|
|
offset++
|
|
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++
|
|
dest[offset] = nestedElem.ModelColor.R
|
|
dest[offset+1] = nestedElem.ModelColor.G
|
|
dest[offset+2] = nestedElem.ModelColor.B
|
|
offset += 3
|
|
dest[offset] = nestedElem.ModelHighlightColor.R
|
|
dest[offset+1] = nestedElem.ModelHighlightColor.G
|
|
dest[offset+2] = nestedElem.ModelHighlightColor.B
|
|
offset += 3
|
|
}
|
|
}
|
|
}
|
|
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
|
|
if p.Unknown10 != 0 {
|
|
size += 1
|
|
}
|
|
if p.Unknown10 != 0 {
|
|
for _, elem := range p.ClassItems {
|
|
_ = elem
|
|
size += 1
|
|
size += 1
|
|
for _, nestedElem := range elem.StartingItems {
|
|
_ = nestedElem
|
|
size += 4
|
|
size += 1
|
|
size += 1
|
|
size += 1
|
|
size += 3
|
|
size += 3
|
|
|
|
}
|
|
|
|
}
|
|
}
|
|
size += 1
|
|
if p.UnknownArray2Size != 0 {
|
|
for _, elem := range p.UnknownArray2 {
|
|
_ = elem
|
|
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
|
|
if p.Unknown12 != 0 {
|
|
size += 1
|
|
}
|
|
if p.Unknown12 != 0 {
|
|
for _, elem := range p.Lvl90ClassItems {
|
|
_ = elem
|
|
size += 1
|
|
size += 1
|
|
for _, nestedElem := range elem.StartingItems {
|
|
_ = nestedElem
|
|
size += 4
|
|
size += 1
|
|
size += 1
|
|
size += 1
|
|
size += 3
|
|
size += 3
|
|
|
|
}
|
|
|
|
}
|
|
}
|
|
size += 1
|
|
if p.Unknown13 != 0 {
|
|
size += 1
|
|
}
|
|
if p.Unknown13 != 0 {
|
|
for _, elem := range p.TimeLockedClassItems {
|
|
_ = elem
|
|
size += 1
|
|
size += 1
|
|
for _, nestedElem := range elem.StartingItems {
|
|
_ = nestedElem
|
|
size += 4
|
|
size += 1
|
|
size += 1
|
|
size += 1
|
|
size += 3
|
|
size += 3
|
|
|
|
}
|
|
|
|
}
|
|
}
|
|
size += uint32(13)
|
|
return size
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|