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