diff --git a/internal/packets/ls_structs/BadLanguageFilter.go b/internal/packets/ls_structs/BadLanguageFilter.go deleted file mode 100644 index 6023306..0000000 --- a/internal/packets/ls_structs/BadLanguageFilter.go +++ /dev/null @@ -1,12 +0,0 @@ -package ls_structs - -import "eq2emu/internal/common" - -type BadLanguageFilterWord struct { - Word common.EQ2String16 `eq2:"string16"` -} - -type BadLanguageFilter struct { - NumWords uint16 `eq2:"int16,oversized=255"` - WordsArray []BadLanguageFilterWord `eq2:"array,arraysize=NumWords"` -} diff --git a/internal/packets/ls_structs/CharSelectProfile.go b/internal/packets/ls_structs/CharSelectProfile.go deleted file mode 100644 index 9fdbf69..0000000 --- a/internal/packets/ls_structs/CharSelectProfile.go +++ /dev/null @@ -1,411 +0,0 @@ -package ls_structs - -import "eq2emu/internal/common" - -// CharSelectProfile for client version 1 -type CharSelectProfileV1 struct { - CharID uint32 `eq2:"int32"` - ServerID uint32 `eq2:"int32"` - Name common.EQ2String16 `eq2:"string16"` - Race uint8 `eq2:"int8"` - Class uint8 `eq2:"int8"` - Level uint32 `eq2:"int32"` - Zone common.EQ2String16 `eq2:"string16"` - Unknown1 uint32 `eq2:"int32"` - Unknown2 uint32 `eq2:"int32"` - CreatedDate uint32 `eq2:"int32"` - LastPlayed uint32 `eq2:"int32"` - Unknown3 uint32 `eq2:"int32"` - Unknown4 uint32 `eq2:"int32"` - Zonename2 common.EQ2String16 `eq2:"string16"` - Zonedesc common.EQ2String16 `eq2:"string16"` - Version uint8 `eq2:"int8"` - RaceType uint16 `eq2:"int16"` - SkinColor []int8 `eq2:"sint8,len=3"` - EyeColor []int8 `eq2:"sint8,len=3"` - Equip []common.EQ2EquipmentItem `eq2:"equipment,len=21"` - HairType uint16 `eq2:"int16"` - HairTypeColor []int8 `eq2:"sint8,len=3"` - HairTypeHighlightColor []int8 `eq2:"sint8,len=3"` - HairFaceType uint16 `eq2:"int16"` - HairFaceColor []int8 `eq2:"sint8,len=3"` - HairFaceHighlightColor []int8 `eq2:"sint8,len=3"` - ChestType uint16 `eq2:"int16"` - ShirtColor []int8 `eq2:"sint8,len=3"` - UnknownChestColor []int8 `eq2:"sint8,len=3"` - LegsType uint16 `eq2:"int16"` - PantsColor []int8 `eq2:"sint8,len=3"` - UnknownLegsColor []int8 `eq2:"sint8,len=3"` - Unknown9 []int8 `eq2:"sint8,len=3"` - EyeType []int8 `eq2:"sint8,len=3"` - EarType []int8 `eq2:"sint8,len=3"` - EyeBrowType []int8 `eq2:"sint8,len=3"` - CheekType []int8 `eq2:"sint8,len=3"` - LipType []int8 `eq2:"sint8,len=3"` - ChinType []int8 `eq2:"sint8,len=3"` - NoseType []int8 `eq2:"sint8,len=3"` - BodySize int8 `eq2:"sint8"` - BumpScale int8 `eq2:"sint8"` - Mount uint16 `eq2:"int16"` - MountColor1 []int8 `eq2:"sint8,len=3"` - MountColor2 []int8 `eq2:"sint8,len=3"` - HairColor1 []int8 `eq2:"sint8,len=3"` - HairColor2 []int8 `eq2:"sint8,len=3"` - HairColor3 []int8 `eq2:"sint8,len=3"` - Flags uint8 `eq2:"int8"` -} - -// CharSelectProfile for client version 373 (same as V1) -type CharSelectProfileV373 struct { - CharID uint32 `eq2:"int32"` - ServerID uint32 `eq2:"int32"` - Name common.EQ2String16 `eq2:"string16"` - Race uint8 `eq2:"int8"` - Class uint8 `eq2:"int8"` - Level uint32 `eq2:"int32"` - Zone common.EQ2String16 `eq2:"string16"` - Unknown1 uint32 `eq2:"int32"` - Unknown2 uint32 `eq2:"int32"` - CreatedDate uint32 `eq2:"int32"` - LastPlayed uint32 `eq2:"int32"` - Unknown3 uint32 `eq2:"int32"` - Unknown4 uint32 `eq2:"int32"` - Zonename2 common.EQ2String16 `eq2:"string16"` - Zonedesc common.EQ2String16 `eq2:"string16"` - Version uint8 `eq2:"int8"` - RaceType uint16 `eq2:"int16"` - SkinColor []int8 `eq2:"sint8,len=3"` - EyeColor []int8 `eq2:"sint8,len=3"` - Equip []common.EQ2EquipmentItem `eq2:"equipment,len=21"` - HairType uint16 `eq2:"int16"` - HairTypeColor []int8 `eq2:"sint8,len=3"` - HairTypeHighlightColor []int8 `eq2:"sint8,len=3"` - HairFaceType uint16 `eq2:"int16"` - HairFaceColor []int8 `eq2:"sint8,len=3"` - HairFaceHighlightColor []int8 `eq2:"sint8,len=3"` - ChestType uint16 `eq2:"int16"` - ShirtColor []int8 `eq2:"sint8,len=3"` - UnknownChestColor []int8 `eq2:"sint8,len=3"` - LegsType uint16 `eq2:"int16"` - PantsColor []int8 `eq2:"sint8,len=3"` - UnknownLegsColor []int8 `eq2:"sint8,len=3"` - Unknown9 []int8 `eq2:"sint8,len=3"` - EyeType []int8 `eq2:"sint8,len=3"` - EarType []int8 `eq2:"sint8,len=3"` - EyeBrowType []int8 `eq2:"sint8,len=3"` - CheekType []int8 `eq2:"sint8,len=3"` - LipType []int8 `eq2:"sint8,len=3"` - ChinType []int8 `eq2:"sint8,len=3"` - NoseType []int8 `eq2:"sint8,len=3"` - BodySize int8 `eq2:"sint8"` - BumpScale int8 `eq2:"sint8"` - Mount uint16 `eq2:"int16"` - MountColor1 []int8 `eq2:"sint8,len=3"` - MountColor2 []int8 `eq2:"sint8,len=3"` - HairColor1 []int8 `eq2:"sint8,len=3"` - HairColor2 []int8 `eq2:"sint8,len=3"` - HairColor3 []int8 `eq2:"sint8,len=3"` - Flags uint8 `eq2:"int8"` -} - -// CharSelectProfile for client version 546 -type CharSelectProfileV546 struct { - CharID uint32 `eq2:"int32"` - ServerID uint32 `eq2:"int32"` - Name common.EQ2String16 `eq2:"string16"` - Race uint8 `eq2:"int8"` - Class uint8 `eq2:"int8"` - Gender uint8 `eq2:"int8"` - Level uint32 `eq2:"int32"` - Zone common.EQ2String16 `eq2:"string16"` - Unknown1 uint32 `eq2:"int32"` - Unknown2 uint32 `eq2:"int32"` - CreatedDate uint32 `eq2:"int32"` - LastPlayed uint32 `eq2:"int32"` - Unknown3 uint32 `eq2:"int32"` - Unknown4 uint32 `eq2:"int32"` - Zonename2 common.EQ2String16 `eq2:"string16"` - Zonedesc common.EQ2String16 `eq2:"string16"` - Unknown5 uint32 `eq2:"int32"` - Version uint8 `eq2:"int8"` - RaceType uint16 `eq2:"int16"` - SkinColor []int8 `eq2:"sint8,len=3"` - EyeColor []int8 `eq2:"sint8,len=3"` - Equip []common.EQ2EquipmentItem `eq2:"equipment,len=23"` - HairType uint16 `eq2:"int16"` - HairTypeColor []int8 `eq2:"sint8,len=3"` - HairTypeHighlightColor []int8 `eq2:"sint8,len=3"` - HairFaceType uint16 `eq2:"int16"` - HairFaceColor []int8 `eq2:"sint8,len=3"` - HairFaceHighlightColor []int8 `eq2:"sint8,len=3"` - ChestType uint16 `eq2:"int16"` - ShirtColor []int8 `eq2:"sint8,len=3"` - UnknownChestColor []int8 `eq2:"sint8,len=3"` - LegsType uint16 `eq2:"int16"` - PantsColor []int8 `eq2:"sint8,len=3"` - UnknownLegsColor []int8 `eq2:"sint8,len=3"` - Unknown9 []int8 `eq2:"sint8,len=3"` - EyeType []int8 `eq2:"sint8,len=3"` - EarType []int8 `eq2:"sint8,len=3"` - EyeBrowType []int8 `eq2:"sint8,len=3"` - CheekType []int8 `eq2:"sint8,len=3"` - LipType []int8 `eq2:"sint8,len=3"` - ChinType []int8 `eq2:"sint8,len=3"` - NoseType []int8 `eq2:"sint8,len=3"` - BodySize int8 `eq2:"sint8"` - BumpScale int8 `eq2:"sint8"` - Mount uint16 `eq2:"int16"` - MountColor1 []int8 `eq2:"sint8,len=3"` - MountColor2 []int8 `eq2:"sint8,len=3"` - HairColor1 []int8 `eq2:"sint8,len=3"` - HairColor2 []int8 `eq2:"sint8,len=3"` - HairColor3 []int8 `eq2:"sint8,len=3"` - Unknown11 []uint8 `eq2:"int8,len=10"` - SogaRaceType uint16 `eq2:"int16"` - SogaSkinColorx common.EQ2Color `eq2:"color"` - SogaEyeColor common.EQ2Color `eq2:"color"` - Unknown12 []uint8 `eq2:"int8,len=3"` - SogaEyeType []int8 `eq2:"sint8,len=3"` - SogaEarType []int8 `eq2:"sint8,len=3"` - SogaEyeBrowType []int8 `eq2:"sint8,len=3"` - SogaCheekType []int8 `eq2:"sint8,len=3"` - SogaLipType []int8 `eq2:"sint8,len=3"` - SogaChinType []int8 `eq2:"sint8,len=3"` - SogaNoseType []int8 `eq2:"sint8,len=3"` - SogaHairColor1 common.EQ2Color `eq2:"color"` - SogaChestType uint16 `eq2:"int16"` - SogaHairColor2 common.EQ2Color `eq2:"color"` - SogaHairColor3 common.EQ2Color `eq2:"color"` - SogaHairType uint16 `eq2:"int16"` - SogaHairTypeColor common.EQ2Color `eq2:"color"` - SogaHairTypeHighlightColor common.EQ2Color `eq2:"color"` - SogaHairFaceType uint16 `eq2:"int16"` - SogaHairFaceColor common.EQ2Color `eq2:"color"` - SogaHairFaceHighlightColor common.EQ2Color `eq2:"color"` -} - -// CharSelectProfile for client version 562 -type CharSelectProfileV562 struct { - Version uint32 `eq2:"int32"` - CharID uint32 `eq2:"int32"` - ServerID uint32 `eq2:"int32"` - Name common.EQ2String16 `eq2:"string16"` - Unknown uint8 `eq2:"int8"` - Race uint8 `eq2:"int8"` - Class uint8 `eq2:"int8"` - Gender uint8 `eq2:"int8"` - Level uint32 `eq2:"int32"` - Zone common.EQ2String16 `eq2:"string16"` - Unknown1 uint32 `eq2:"int32"` - Unknown2 uint32 `eq2:"int32"` - CreatedDate uint32 `eq2:"int32"` - LastPlayed uint32 `eq2:"int32"` - Unknown3 uint32 `eq2:"int32"` - Unknown4 uint32 `eq2:"int32"` - Zonename2 common.EQ2String16 `eq2:"string16"` - Zonedesc common.EQ2String16 `eq2:"string16"` - Unknown5 uint32 `eq2:"int32"` - ServerName common.EQ2String16 `eq2:"string16"` - AccountID uint32 `eq2:"int32"` - Unknown6 []uint8 `eq2:"int8,len=2"` - Unknown7 uint32 `eq2:"int32"` - Unknown8 uint8 `eq2:"int8"` - RaceType uint16 `eq2:"int16"` - SkinColor common.EQ2Color `eq2:"color"` - EyeColor common.EQ2Color `eq2:"color"` - Equip []common.EQ2EquipmentItem `eq2:"equipment,len=25"` - HairType uint16 `eq2:"int16"` - HairTypeColor common.EQ2Color `eq2:"color"` - HairTypeHighlightColor common.EQ2Color `eq2:"color"` - HairFaceType uint16 `eq2:"int16"` - HairFaceColor common.EQ2Color `eq2:"color"` - HairFaceHighlightColor common.EQ2Color `eq2:"color"` - ChestType uint16 `eq2:"int16"` - ShirtColor common.EQ2Color `eq2:"color"` - UnknownChestColor common.EQ2Color `eq2:"color"` - LegsType uint16 `eq2:"int16"` - PantsColor common.EQ2Color `eq2:"color"` - UnknownLegsColor common.EQ2Color `eq2:"color"` - Unknown9 common.EQ2Color `eq2:"color"` - EyeType []int8 `eq2:"sint8,len=3"` - EarType []int8 `eq2:"sint8,len=3"` - EyeBrowType []int8 `eq2:"sint8,len=3"` - CheekType []int8 `eq2:"sint8,len=3"` - LipType []int8 `eq2:"sint8,len=3"` - ChinType []int8 `eq2:"sint8,len=3"` - NoseType []int8 `eq2:"sint8,len=3"` - BodySize int8 `eq2:"sint8"` - Unknown10 []uint8 `eq2:"int8,len=9"` - HairColor1 common.EQ2Color `eq2:"color"` - HairColor2 common.EQ2Color `eq2:"color"` - Unknown11 []uint8 `eq2:"int8,len=13"` - Unknown15 []uint8 `eq2:"int8,len=7"` -} - -// CharSelectProfile for client version 887 -type CharSelectProfileV887 struct { - Version uint32 `eq2:"int32"` - CharID uint32 `eq2:"int32"` - ServerID uint32 `eq2:"int32"` - Name common.EQ2String16 `eq2:"string16"` - Unknown uint8 `eq2:"int8"` - Race uint8 `eq2:"int8"` - Class uint8 `eq2:"int8"` - Gender uint8 `eq2:"int8"` - Level uint32 `eq2:"int32"` - Zone common.EQ2String16 `eq2:"string16"` - Unknown1 uint32 `eq2:"int32"` - Unknown2 uint32 `eq2:"int32"` - CreatedDate uint32 `eq2:"int32"` - LastPlayed uint32 `eq2:"int32"` - Unknown3 uint32 `eq2:"int32"` - Unknown4 uint32 `eq2:"int32"` - Zonename2 common.EQ2String16 `eq2:"string16"` - Zonedesc common.EQ2String16 `eq2:"string16"` - Unknown5 uint32 `eq2:"int32"` - ServerName common.EQ2String16 `eq2:"string16"` - AccountID uint32 `eq2:"int32"` - Unknown6 []uint8 `eq2:"int8,len=2"` - Unknown7 uint32 `eq2:"int32"` - TradeskillClass uint8 `eq2:"int8"` - TradeskillLevel uint32 `eq2:"int32"` - Unknown8 uint8 `eq2:"int8"` - RaceType uint16 `eq2:"int16"` - SkinColor common.EQ2Color `eq2:"color"` - EyeColor common.EQ2Color `eq2:"color"` - Equip []common.EQ2EquipmentItem `eq2:"equipment,len=25"` - HairType uint16 `eq2:"int16"` - HairTypeColor common.EQ2Color `eq2:"color"` - HairTypeHighlightColor common.EQ2Color `eq2:"color"` - HairFaceType uint16 `eq2:"int16"` - HairFaceColor common.EQ2Color `eq2:"color"` - HairFaceHighlightColor common.EQ2Color `eq2:"color"` - WingType uint16 `eq2:"int16"` - WingColor1 common.EQ2Color `eq2:"color"` - WingColor2 common.EQ2Color `eq2:"color"` - ChestType uint16 `eq2:"int16"` - ShirtColor common.EQ2Color `eq2:"color"` - UnknownChestColor common.EQ2Color `eq2:"color"` - LegsType uint16 `eq2:"int16"` - PantsColor common.EQ2Color `eq2:"color"` - UnknownLegsColor common.EQ2Color `eq2:"color"` - Unknown9 common.EQ2Color `eq2:"color"` - EyeType []int8 `eq2:"sint8,len=3"` - EarType []int8 `eq2:"sint8,len=3"` - EyeBrowType []int8 `eq2:"sint8,len=3"` - CheekType []int8 `eq2:"sint8,len=3"` - LipType []int8 `eq2:"sint8,len=3"` - ChinType []int8 `eq2:"sint8,len=3"` - NoseType []int8 `eq2:"sint8,len=3"` - BodySize int8 `eq2:"sint8"` - Unknown10 []uint8 `eq2:"int8,len=9"` - HairColor1 common.EQ2Color `eq2:"color"` - HairColor2 common.EQ2Color `eq2:"color"` - Unknown11 []uint8 `eq2:"int8,len=13"` - SogaRaceType uint16 `eq2:"int16"` - SogaSkinColor common.EQ2Color `eq2:"color"` - SogaEyeColor common.EQ2Color `eq2:"color"` - Unknown12 []uint8 `eq2:"int8,len=3"` - SogaEyeType []int8 `eq2:"sint8,len=3"` - SogaEarType []int8 `eq2:"sint8,len=3"` - SogaEyeBrowType []int8 `eq2:"sint8,len=3"` - SogaCheekType []int8 `eq2:"sint8,len=3"` - SogaLipType []int8 `eq2:"sint8,len=3"` - SogaChinType []int8 `eq2:"sint8,len=3"` - SogaNoseType []int8 `eq2:"sint8,len=3"` - Unknown13 uint16 `eq2:"int16"` - SogaHairColor1 common.EQ2Color `eq2:"color"` - SogaHairColor2 common.EQ2Color `eq2:"color"` - Unknown14 common.EQ2Color `eq2:"color"` - SogaHairType uint16 `eq2:"int16"` - SogaHairTypeColor common.EQ2Color `eq2:"color"` - SogaHairTypeHighlightColor common.EQ2Color `eq2:"color"` - SogaHairFaceType uint16 `eq2:"int16"` - SogaHairFaceColor common.EQ2Color `eq2:"color"` - SogaHairFaceHighlightColor common.EQ2Color `eq2:"color"` - Unknown15 []uint8 `eq2:"int8,len=7"` -} - -// CharSelectProfile for client version 60085 (same as 887) -type CharSelectProfileV60085 struct { - Version uint32 `eq2:"int32"` - CharID uint32 `eq2:"int32"` - ServerID uint32 `eq2:"int32"` - Name common.EQ2String16 `eq2:"string16"` - Unknown uint8 `eq2:"int8"` - Race uint8 `eq2:"int8"` - Class uint8 `eq2:"int8"` - Gender uint8 `eq2:"int8"` - Level uint32 `eq2:"int32"` - Zone common.EQ2String16 `eq2:"string16"` - Unknown1 uint32 `eq2:"int32"` - Unknown2 uint32 `eq2:"int32"` - CreatedDate uint32 `eq2:"int32"` - LastPlayed uint32 `eq2:"int32"` - Unknown3 uint32 `eq2:"int32"` - Unknown4 uint32 `eq2:"int32"` - Zonename2 common.EQ2String16 `eq2:"string16"` - Zonedesc common.EQ2String16 `eq2:"string16"` - Unknown5 uint32 `eq2:"int32"` - ServerName common.EQ2String16 `eq2:"string16"` - AccountID uint32 `eq2:"int32"` - Unknown6 []uint8 `eq2:"int8,len=2"` - Unknown7 uint32 `eq2:"int32"` - TradeskillClass uint8 `eq2:"int8"` - TradeskillLevel uint32 `eq2:"int32"` - Unknown8 uint8 `eq2:"int8"` - RaceType uint16 `eq2:"int16"` - SkinColor common.EQ2Color `eq2:"color"` - EyeColor common.EQ2Color `eq2:"color"` - Equip []common.EQ2EquipmentItem `eq2:"equipment,len=25"` - HairType uint16 `eq2:"int16"` - HairTypeColor common.EQ2Color `eq2:"color"` - HairTypeHighlightColor common.EQ2Color `eq2:"color"` - HairFaceType uint16 `eq2:"int16"` - HairFaceColor common.EQ2Color `eq2:"color"` - HairFaceHighlightColor common.EQ2Color `eq2:"color"` - WingType uint16 `eq2:"int16"` - WingColor1 common.EQ2Color `eq2:"color"` - WingColor2 common.EQ2Color `eq2:"color"` - ChestType uint16 `eq2:"int16"` - ShirtColor common.EQ2Color `eq2:"color"` - UnknownChestColor common.EQ2Color `eq2:"color"` - LegsType uint16 `eq2:"int16"` - PantsColor common.EQ2Color `eq2:"color"` - UnknownLegsColor common.EQ2Color `eq2:"color"` - Unknown9 common.EQ2Color `eq2:"color"` - EyeType []int8 `eq2:"sint8,len=3"` - EarType []int8 `eq2:"sint8,len=3"` - EyeBrowType []int8 `eq2:"sint8,len=3"` - CheekType []int8 `eq2:"sint8,len=3"` - LipType []int8 `eq2:"sint8,len=3"` - ChinType []int8 `eq2:"sint8,len=3"` - NoseType []int8 `eq2:"sint8,len=3"` - BodySize int8 `eq2:"sint8"` - Unknown10 []uint8 `eq2:"int8,len=9"` - HairColor1 common.EQ2Color `eq2:"color"` - HairColor2 common.EQ2Color `eq2:"color"` - Unknown11 []uint8 `eq2:"int8,len=13"` - SogaRaceType uint16 `eq2:"int16"` - SogaSkinColor common.EQ2Color `eq2:"color"` - SogaEyeColor common.EQ2Color `eq2:"color"` - Unknown12 []uint8 `eq2:"int8,len=3"` - SogaEyeType []int8 `eq2:"sint8,len=3"` - SogaEarType []int8 `eq2:"sint8,len=3"` - SogaEyeBrowType []int8 `eq2:"sint8,len=3"` - SogaCheekType []int8 `eq2:"sint8,len=3"` - SogaLipType []int8 `eq2:"sint8,len=3"` - SogaChinType []int8 `eq2:"sint8,len=3"` - SogaNoseType []int8 `eq2:"sint8,len=3"` - Unknown13 uint16 `eq2:"int16"` - SogaHairColor1 common.EQ2Color `eq2:"color"` - SogaHairColor2 common.EQ2Color `eq2:"color"` - Unknown14 common.EQ2Color `eq2:"color"` - SogaHairType uint16 `eq2:"int16"` - SogaHairTypeColor common.EQ2Color `eq2:"color"` - SogaHairTypeHighlightColor common.EQ2Color `eq2:"color"` - SogaHairFaceType uint16 `eq2:"int16"` - SogaHairFaceColor common.EQ2Color `eq2:"color"` - SogaHairFaceHighlightColor common.EQ2Color `eq2:"color"` - Unknown15 []uint8 `eq2:"int8,len=7"` -} diff --git a/internal/packets/ls_structs/CreateCharacter.go b/internal/packets/ls_structs/CreateCharacter.go deleted file mode 100644 index 61891af..0000000 --- a/internal/packets/ls_structs/CreateCharacter.go +++ /dev/null @@ -1,767 +0,0 @@ -package ls_structs - -import "eq2emu/internal/common" - -// CreateCharacter for client version 1 -type CreateCharacterV1 struct { - AccountID uint32 `eq2:"int32"` - ServerID uint32 `eq2:"int32"` - Name common.EQ2String16 `eq2:"string16"` - Race uint8 `eq2:"int8"` - Gender uint8 `eq2:"int8"` - Deity uint8 `eq2:"int8"` - Class uint8 `eq2:"int8"` - Level uint8 `eq2:"int8"` - StartingZone uint8 `eq2:"int8"` - Unknown1 []uint8 `eq2:"int8,len=2"` - RaceFile common.EQ2String16 `eq2:"string16"` - SkinColor []float32 `eq2:"float,len=3"` - EyeColor []float32 `eq2:"float,len=3"` - HairColor1 []float32 `eq2:"float,len=3"` - HairColor2 []float32 `eq2:"float,len=3"` - HairHighlight []float32 `eq2:"float,len=3"` - Unknown2 []uint8 `eq2:"int8,len=26"` - HairFile common.EQ2String16 `eq2:"string16"` - HairTypeColor []float32 `eq2:"float,len=3"` - HairTypeHighlightColor []float32 `eq2:"float,len=3"` - FaceFile common.EQ2String16 `eq2:"string16"` - HairFaceColor []float32 `eq2:"float,len=3"` - HairFaceHighlightColor []float32 `eq2:"float,len=3"` - ChestFile common.EQ2String16 `eq2:"string16"` - ShirtColor []float32 `eq2:"float,len=3"` - UnknownChestColor []float32 `eq2:"float,len=3"` - LegsFile common.EQ2String16 `eq2:"string16"` - PantsColor []float32 `eq2:"float,len=3"` - UnknownLegsColor []float32 `eq2:"float,len=3"` - Unknown9 []float32 `eq2:"float,len=3"` - Eyes2 []float32 `eq2:"float,len=3"` - Ears []float32 `eq2:"float,len=3"` - EyeBrows []float32 `eq2:"float,len=3"` - Cheeks []float32 `eq2:"float,len=3"` - Lips []float32 `eq2:"float,len=3"` - Chin []float32 `eq2:"float,len=3"` - Nose []float32 `eq2:"float,len=3"` - BodySize float32 `eq2:"float"` - BodyAge float32 `eq2:"float"` -} - -// CreateCharacter for client version 373 -type CreateCharacterV373 struct { - Unknown0 uint32 `eq2:"int32"` - AccountID uint32 `eq2:"int32"` - ServerID uint32 `eq2:"int32"` - Name common.EQ2String16 `eq2:"string16"` - Race uint8 `eq2:"int8"` - Gender uint8 `eq2:"int8"` - Deity uint8 `eq2:"int8"` - Class uint8 `eq2:"int8"` - Level uint8 `eq2:"int8"` - StartingZone uint8 `eq2:"int8"` - Unknown1 []uint8 `eq2:"int8,len=2"` - RaceFile common.EQ2String16 `eq2:"string16"` - SkinColor []float32 `eq2:"float,len=3"` - EyeColor []float32 `eq2:"float,len=3"` - HairColor1 []float32 `eq2:"float,len=3"` - HairColor2 []float32 `eq2:"float,len=3"` - HairHighlight []float32 `eq2:"float,len=3"` - Unknown2 []uint8 `eq2:"int8,len=26"` - HairFile common.EQ2String16 `eq2:"string16"` - HairTypeColor []float32 `eq2:"float,len=3"` - HairTypeHighlightColor []float32 `eq2:"float,len=3"` - FaceFile common.EQ2String16 `eq2:"string16"` - HairFaceColor []float32 `eq2:"float,len=3"` - HairFaceHighlightColor []float32 `eq2:"float,len=3"` - ChestFile common.EQ2String16 `eq2:"string16"` - ShirtColor []float32 `eq2:"float,len=3"` - UnknownChestColor []float32 `eq2:"float,len=3"` - LegsFile common.EQ2String16 `eq2:"string16"` - PantsColor []float32 `eq2:"float,len=3"` - UnknownLegsColor []float32 `eq2:"float,len=3"` - Unknown9 []float32 `eq2:"float,len=3"` - Eyes2 []float32 `eq2:"float,len=3"` - Ears []float32 `eq2:"float,len=3"` - EyeBrows []float32 `eq2:"float,len=3"` - Cheeks []float32 `eq2:"float,len=3"` - Lips []float32 `eq2:"float,len=3"` - Chin []float32 `eq2:"float,len=3"` - Nose []float32 `eq2:"float,len=3"` - BodySize float32 `eq2:"float"` - BodyAge float32 `eq2:"float"` -} - -// CreateCharacter for client version 546 -type CreateCharacterV546 struct { - Unknown0 uint8 `eq2:"int8"` - Unknown1 uint32 `eq2:"int32"` - AccountID uint32 `eq2:"int32"` - ServerID uint32 `eq2:"int32"` - Name common.EQ2String16 `eq2:"string16"` - Race uint8 `eq2:"int8"` - Gender uint8 `eq2:"int8"` - Deity uint8 `eq2:"int8"` - Class uint8 `eq2:"int8"` - Level uint8 `eq2:"int8"` - StartingZone uint8 `eq2:"int8"` - CcUnknown0 uint8 `eq2:"int8"` - Version uint8 `eq2:"int8"` - RaceFile common.EQ2String16 `eq2:"string16"` - SkinColor []float32 `eq2:"float,len=3"` - EyeColor []float32 `eq2:"float,len=3"` - HairColor1 []float32 `eq2:"float,len=3"` - HairColor2 []float32 `eq2:"float,len=3"` - HairHighlight []float32 `eq2:"float,len=3"` - Unknown2 []uint8 `eq2:"int8,len=26"` - HairFile common.EQ2String16 `eq2:"string16"` - HairTypeColor []float32 `eq2:"float,len=3"` - HairTypeHighlightColor []float32 `eq2:"float,len=3"` - FaceFile common.EQ2String16 `eq2:"string16"` - HairFaceColor []float32 `eq2:"float,len=3"` - HairFaceHighlightColor []float32 `eq2:"float,len=3"` - ChestFile common.EQ2String16 `eq2:"string16"` - ShirtColor []float32 `eq2:"float,len=3"` - UnknownChestColor []float32 `eq2:"float,len=3"` - LegsFile common.EQ2String16 `eq2:"string16"` - PantsColor []float32 `eq2:"float,len=3"` - UnknownLegsColor []float32 `eq2:"float,len=3"` - Unknown9 []float32 `eq2:"float,len=3"` - Eyes2 []float32 `eq2:"float,len=3"` - Ears []float32 `eq2:"float,len=3"` - EyeBrows []float32 `eq2:"float,len=3"` - Cheeks []float32 `eq2:"float,len=3"` - Lips []float32 `eq2:"float,len=3"` - Chin []float32 `eq2:"float,len=3"` - Nose []float32 `eq2:"float,len=3"` - BodySize float32 `eq2:"float"` - BodyAge float32 `eq2:"float"` -} - -// CreateCharacter for client version 561 -type CreateCharacterV561 struct { - Unknown0 uint8 `eq2:"int8"` - Unknown1 uint32 `eq2:"int32"` - AccountID uint32 `eq2:"int32"` - ServerID uint32 `eq2:"int32"` - Name common.EQ2String16 `eq2:"string16"` - Race uint8 `eq2:"int8"` - Gender uint8 `eq2:"int8"` - Deity uint8 `eq2:"int8"` - Class uint8 `eq2:"int8"` - Level uint8 `eq2:"int8"` - StartingZone uint8 `eq2:"int8"` - Version uint8 `eq2:"int8"` - RaceFile common.EQ2String16 `eq2:"string16"` - SkinColor []float32 `eq2:"float,len=3"` - EyeColor []float32 `eq2:"float,len=3"` - HairColor1 []float32 `eq2:"float,len=3"` - HairColor2 []float32 `eq2:"float,len=3"` - HairHighlight []float32 `eq2:"float,len=3"` - Unknown2 []uint8 `eq2:"int8,len=26"` - HairFile common.EQ2String16 `eq2:"string16"` - HairTypeColor []float32 `eq2:"float,len=3"` - HairTypeHighlightColor []float32 `eq2:"float,len=3"` - FaceFile common.EQ2String16 `eq2:"string16"` - HairFaceColor []float32 `eq2:"float,len=3"` - HairFaceHighlightColor []float32 `eq2:"float,len=3"` - ChestFile common.EQ2String16 `eq2:"string16"` - ShirtColor []float32 `eq2:"float,len=3"` - UnknownChestColor []float32 `eq2:"float,len=3"` - LegsFile common.EQ2String16 `eq2:"string16"` - PantsColor []float32 `eq2:"float,len=3"` - UnknownLegsColor []float32 `eq2:"float,len=3"` - Unknown9 []float32 `eq2:"float,len=3"` - Eyes2 []float32 `eq2:"float,len=3"` - Ears []float32 `eq2:"float,len=3"` - EyeBrows []float32 `eq2:"float,len=3"` - Cheeks []float32 `eq2:"float,len=3"` - Lips []float32 `eq2:"float,len=3"` - Chin []float32 `eq2:"float,len=3"` - Nose []float32 `eq2:"float,len=3"` - BodySize float32 `eq2:"float"` - BodyAge float32 `eq2:"float"` -} - -// CreateCharacter for client version 562 -type CreateCharacterV562 struct { - Unknown0 uint8 `eq2:"int8"` - Unknown1 uint32 `eq2:"int32"` - AccountID uint32 `eq2:"int32"` - Unknown3 uint8 `eq2:"int8"` - ServerID uint32 `eq2:"int32"` - Name common.EQ2String16 `eq2:"string16"` - Race uint8 `eq2:"int8"` - Gender uint8 `eq2:"int8"` - Deity uint8 `eq2:"int8"` - Class uint8 `eq2:"int8"` - Level uint8 `eq2:"int8"` - StartingZone uint8 `eq2:"int8"` - Version uint8 `eq2:"int8"` - RaceFile common.EQ2String16 `eq2:"string16"` - SkinColor common.EQ2Color `eq2:"color"` - SkinColor2 common.EQ2Color `eq2:"color"` - EyeColor common.EQ2Color `eq2:"color"` - HairColor1 common.EQ2Color `eq2:"color"` - HairColor2 common.EQ2Color `eq2:"color"` - Unknown8 []uint8 `eq2:"int8,len=26"` - HairFile common.EQ2String16 `eq2:"string16"` - HairTypeColor common.EQ2Color `eq2:"color"` - HairTypeHighlightColor common.EQ2Color `eq2:"color"` - FaceFile common.EQ2String16 `eq2:"string16"` - HairFaceColor common.EQ2Color `eq2:"color"` - HairFaceHighlightColor common.EQ2Color `eq2:"color"` - WingFile common.EQ2String16 `eq2:"string16"` - WingColor1 common.EQ2Color `eq2:"color"` - WingColor2 common.EQ2Color `eq2:"color"` - ChestFile common.EQ2String16 `eq2:"string16"` - ShirtColor common.EQ2Color `eq2:"color"` - UnknownChestColor common.EQ2Color `eq2:"color"` - LegsFile common.EQ2String16 `eq2:"string16"` - PantsColor common.EQ2Color `eq2:"color"` - UnknownLegsColor common.EQ2Color `eq2:"color"` - Unknown9 common.EQ2Color `eq2:"color"` - Eyes2 []float32 `eq2:"float,len=3"` - Ears []float32 `eq2:"float,len=3"` - EyeBrows []float32 `eq2:"float,len=3"` - Cheeks []float32 `eq2:"float,len=3"` - Lips []float32 `eq2:"float,len=3"` - Chin []float32 `eq2:"float,len=3"` - Nose []float32 `eq2:"float,len=3"` - BodySize float32 `eq2:"float"` - BodyAge float32 `eq2:"float"` - SogaVersion uint8 `eq2:"int8"` - SogaRaceFile common.EQ2String16 `eq2:"string16"` - SogaSkinColor common.EQ2Color `eq2:"color"` - SogaEyeColor common.EQ2Color `eq2:"color"` - SogaHairColor1 common.EQ2Color `eq2:"color"` - SogaHairColor2 common.EQ2Color `eq2:"color"` - SogaHairHighlight common.EQ2Color `eq2:"color"` - SogaUnknown11 []uint8 `eq2:"int8,len=26"` - SogaHairFile common.EQ2String16 `eq2:"string16"` - SogaHairTypeColor common.EQ2Color `eq2:"color"` - SogaHairTypeHighlightColor common.EQ2Color `eq2:"color"` - SogaFaceFile common.EQ2String16 `eq2:"string16"` - SogaHairFaceColor common.EQ2Color `eq2:"color"` - SogaHairFaceHighlightColor common.EQ2Color `eq2:"color"` - SogaWingFile common.EQ2String16 `eq2:"string16"` - SogaWingColor1 common.EQ2Color `eq2:"color"` - SogaWingColor2 common.EQ2Color `eq2:"color"` - SogaChestFile common.EQ2String16 `eq2:"string16"` - SogaShirtColor common.EQ2Color `eq2:"color"` - SogaUnknownChestColor common.EQ2Color `eq2:"color"` - SogaLegsFile common.EQ2String16 `eq2:"string16"` - SogaPantsColor common.EQ2Color `eq2:"color"` - SogaUnknownLegsColor common.EQ2Color `eq2:"color"` - SogaUnknown12 common.EQ2Color `eq2:"color"` - SogaEyes2 []float32 `eq2:"float,len=3"` - SogaEars []float32 `eq2:"float,len=3"` - SogaEyeBrows []float32 `eq2:"float,len=3"` - SogaCheeks []float32 `eq2:"float,len=3"` - SogaLips []float32 `eq2:"float,len=3"` - SogaChin []float32 `eq2:"float,len=3"` - SogaNose []float32 `eq2:"float,len=3"` - SogaBodySize float32 `eq2:"float"` - SogaBodyAge float32 `eq2:"float"` -} - -// CreateCharacter for client version 869 -type CreateCharacterV869 struct { - Unknown0 uint8 `eq2:"int8"` - Unknown1 uint32 `eq2:"int32"` - AccountID uint32 `eq2:"int32"` - Unknown3 uint8 `eq2:"int8"` - ServerID uint32 `eq2:"int32"` - Name common.EQ2String16 `eq2:"string16"` - Race uint8 `eq2:"int8"` - Gender uint8 `eq2:"int8"` - Deity uint8 `eq2:"int8"` - Class uint8 `eq2:"int8"` - Level uint8 `eq2:"int8"` - StartingZone uint8 `eq2:"int8"` - Version uint8 `eq2:"int8"` - RaceFile common.EQ2String16 `eq2:"string16"` - SkinColor common.EQ2Color `eq2:"color"` - SkinColor2 common.EQ2Color `eq2:"color"` - EyeColor common.EQ2Color `eq2:"color"` - HairColor1 common.EQ2Color `eq2:"color"` - HairColor2 common.EQ2Color `eq2:"color"` - HairHighlight common.EQ2Color `eq2:"color"` - Unknown8 []uint8 `eq2:"int8,len=26"` - HairFile common.EQ2String16 `eq2:"string16"` - HairTypeColor common.EQ2Color `eq2:"color"` - HairTypeHighlightColor common.EQ2Color `eq2:"color"` - FaceFile common.EQ2String16 `eq2:"string16"` - HairFaceColor common.EQ2Color `eq2:"color"` - HairFaceHighlightColor common.EQ2Color `eq2:"color"` - WingFile common.EQ2String16 `eq2:"string16"` - WingColor1 common.EQ2Color `eq2:"color"` - WingColor2 common.EQ2Color `eq2:"color"` - ChestFile common.EQ2String16 `eq2:"string16"` - ShirtColor common.EQ2Color `eq2:"color"` - UnknownChestColor common.EQ2Color `eq2:"color"` - LegsFile common.EQ2String16 `eq2:"string16"` - PantsColor common.EQ2Color `eq2:"color"` - UnknownLegsColor common.EQ2Color `eq2:"color"` - Unknown9 common.EQ2Color `eq2:"color"` - Eyes2 []float32 `eq2:"float,len=3"` - Ears []float32 `eq2:"float,len=3"` - EyeBrows []float32 `eq2:"float,len=3"` - Cheeks []float32 `eq2:"float,len=3"` - Lips []float32 `eq2:"float,len=3"` - Chin []float32 `eq2:"float,len=3"` - Nose []float32 `eq2:"float,len=3"` - BodySize float32 `eq2:"float"` - BodyAge float32 `eq2:"float"` - SogaVersion uint8 `eq2:"int8"` - SogaRaceFile common.EQ2String16 `eq2:"string16"` - SogaSkinColor common.EQ2Color `eq2:"color"` - SogaEyeColor common.EQ2Color `eq2:"color"` - SogaHairColor1 common.EQ2Color `eq2:"color"` - SogaHairColor2 common.EQ2Color `eq2:"color"` - SogaHairHighlight common.EQ2Color `eq2:"color"` - SogaUnknownColor1 common.EQ2Color `eq2:"color"` - SogaUnknown11 []uint8 `eq2:"int8,len=26"` - SogaHairFile common.EQ2String16 `eq2:"string16"` - SogaHairTypeColor common.EQ2Color `eq2:"color"` - SogaHairTypeHighlightColor common.EQ2Color `eq2:"color"` - SogaFaceFile common.EQ2String16 `eq2:"string16"` - SogaHairFaceColor common.EQ2Color `eq2:"color"` - SogaHairFaceHighlightColor common.EQ2Color `eq2:"color"` - SogaWingFile common.EQ2String16 `eq2:"string16"` - SogaWingColor1 common.EQ2Color `eq2:"color"` - SogaWingColor2 common.EQ2Color `eq2:"color"` - SogaChestFile common.EQ2String16 `eq2:"string16"` - SogaShirtColor common.EQ2Color `eq2:"color"` - SogaUnknownChestColor common.EQ2Color `eq2:"color"` - SogaLegsFile common.EQ2String16 `eq2:"string16"` - SogaPantsColor common.EQ2Color `eq2:"color"` - SogaUnknownLegsColor common.EQ2Color `eq2:"color"` - SogaUnknown12 common.EQ2Color `eq2:"color"` - SogaEyes2 []float32 `eq2:"float,len=3"` - SogaEars []float32 `eq2:"float,len=3"` - SogaEyeBrows []float32 `eq2:"float,len=3"` - SogaCheeks []float32 `eq2:"float,len=3"` - SogaLips []float32 `eq2:"float,len=3"` - SogaChin []float32 `eq2:"float,len=3"` - SogaNose []float32 `eq2:"float,len=3"` - SogaBodySize float32 `eq2:"float"` - SogaBodyAge float32 `eq2:"float"` -} - -// CreateCharacter for client version 1096 (same as 869 but without SogaUnknownColor1) -type CreateCharacterV1096 struct { - Unknown0 uint8 `eq2:"int8"` - Unknown1 uint32 `eq2:"int32"` - AccountID uint32 `eq2:"int32"` - Unknown3 uint8 `eq2:"int8"` - ServerID uint32 `eq2:"int32"` - Name common.EQ2String16 `eq2:"string16"` - Race uint8 `eq2:"int8"` - Gender uint8 `eq2:"int8"` - Deity uint8 `eq2:"int8"` - Class uint8 `eq2:"int8"` - Level uint8 `eq2:"int8"` - StartingZone uint8 `eq2:"int8"` - Version uint8 `eq2:"int8"` - RaceFile common.EQ2String16 `eq2:"string16"` - SkinColor common.EQ2Color `eq2:"color"` - SkinColor2 common.EQ2Color `eq2:"color"` - EyeColor common.EQ2Color `eq2:"color"` - HairColor1 common.EQ2Color `eq2:"color"` - HairColor2 common.EQ2Color `eq2:"color"` - HairHighlight common.EQ2Color `eq2:"color"` - Unknown8 []uint8 `eq2:"int8,len=26"` - HairFile common.EQ2String16 `eq2:"string16"` - HairTypeColor common.EQ2Color `eq2:"color"` - HairTypeHighlightColor common.EQ2Color `eq2:"color"` - FaceFile common.EQ2String16 `eq2:"string16"` - HairFaceColor common.EQ2Color `eq2:"color"` - HairFaceHighlightColor common.EQ2Color `eq2:"color"` - WingFile common.EQ2String16 `eq2:"string16"` - WingColor1 common.EQ2Color `eq2:"color"` - WingColor2 common.EQ2Color `eq2:"color"` - ChestFile common.EQ2String16 `eq2:"string16"` - ShirtColor common.EQ2Color `eq2:"color"` - UnknownChestColor common.EQ2Color `eq2:"color"` - LegsFile common.EQ2String16 `eq2:"string16"` - PantsColor common.EQ2Color `eq2:"color"` - UnknownLegsColor common.EQ2Color `eq2:"color"` - Unknown9 common.EQ2Color `eq2:"color"` - Eyes2 []float32 `eq2:"float,len=3"` - Ears []float32 `eq2:"float,len=3"` - EyeBrows []float32 `eq2:"float,len=3"` - Cheeks []float32 `eq2:"float,len=3"` - Lips []float32 `eq2:"float,len=3"` - Chin []float32 `eq2:"float,len=3"` - Nose []float32 `eq2:"float,len=3"` - BodySize float32 `eq2:"float"` - BodyAge float32 `eq2:"float"` - SogaVersion uint8 `eq2:"int8"` - SogaRaceFile common.EQ2String16 `eq2:"string16"` - SogaSkinColor common.EQ2Color `eq2:"color"` - SogaEyeColor common.EQ2Color `eq2:"color"` - SogaHairColor1 common.EQ2Color `eq2:"color"` - SogaHairColor2 common.EQ2Color `eq2:"color"` - SogaHairHighlight common.EQ2Color `eq2:"color"` - SogaUnknownColor common.EQ2Color `eq2:"color"` - SogaUnknown11 []uint8 `eq2:"int8,len=26"` - SogaHairFile common.EQ2String16 `eq2:"string16"` - SogaHairTypeColor common.EQ2Color `eq2:"color"` - SogaHairTypeHighlightColor common.EQ2Color `eq2:"color"` - SogaFaceFile common.EQ2String16 `eq2:"string16"` - SogaHairFaceColor common.EQ2Color `eq2:"color"` - SogaHairFaceHighlightColor common.EQ2Color `eq2:"color"` - SogaWingFile common.EQ2String16 `eq2:"string16"` - SogaWingColor1 common.EQ2Color `eq2:"color"` - SogaWingColor2 common.EQ2Color `eq2:"color"` - SogaChestFile common.EQ2String16 `eq2:"string16"` - SogaShirtColor common.EQ2Color `eq2:"color"` - SogaUnknownChestColor common.EQ2Color `eq2:"color"` - SogaLegsFile common.EQ2String16 `eq2:"string16"` - SogaPantsColor common.EQ2Color `eq2:"color"` - SogaUnknownLegsColor common.EQ2Color `eq2:"color"` - SogaUnknown12 common.EQ2Color `eq2:"color"` - SogaEyes2 []float32 `eq2:"float,len=3"` - SogaEars []float32 `eq2:"float,len=3"` - SogaEyeBrows []float32 `eq2:"float,len=3"` - SogaCheeks []float32 `eq2:"float,len=3"` - SogaLips []float32 `eq2:"float,len=3"` - SogaChin []float32 `eq2:"float,len=3"` - SogaNose []float32 `eq2:"float,len=3"` - SogaBodySize float32 `eq2:"float"` - SogaBodyAge float32 `eq2:"float"` -} - -// CreateCharacter for client version 57080 -type CreateCharacterV57080 struct { - Unknown0 uint8 `eq2:"int8"` - Unknown1 uint32 `eq2:"int32"` - AccountID uint32 `eq2:"int32"` - Unknown3 uint8 `eq2:"int8"` - ServerID uint32 `eq2:"int32"` - Name common.EQ2String16 `eq2:"string16"` - Race uint8 `eq2:"int8"` - Gender uint8 `eq2:"int8"` - Deity uint8 `eq2:"int8"` - Class uint8 `eq2:"int8"` - Level uint8 `eq2:"int8"` - StartingZone uint8 `eq2:"int8"` - Version uint8 `eq2:"int8"` - Unknown10 uint16 `eq2:"int16"` - RaceFile common.EQ2String16 `eq2:"string16"` - SkinColor common.EQ2Color `eq2:"color"` - EyeColor common.EQ2Color `eq2:"color"` - UnknownSkinColor2 common.EQ2Color `eq2:"color"` - HairColor1 common.EQ2Color `eq2:"color"` - HairColor2 common.EQ2Color `eq2:"color"` - HairHighlight common.EQ2Color `eq2:"color"` - Unknown8 []uint8 `eq2:"int8,len=26"` - HairFile common.EQ2String16 `eq2:"string16"` - HairTypeColor common.EQ2Color `eq2:"color"` - HairTypeHighlightColor common.EQ2Color `eq2:"color"` - FaceFile common.EQ2String16 `eq2:"string16"` - HairFaceColor common.EQ2Color `eq2:"color"` - HairFaceHighlightColor common.EQ2Color `eq2:"color"` - WingFile common.EQ2String16 `eq2:"string16"` - WingColor1 common.EQ2Color `eq2:"color"` - WingColor2 common.EQ2Color `eq2:"color"` - ChestFile common.EQ2String16 `eq2:"string16"` - ShirtColor common.EQ2Color `eq2:"color"` - UnknownChestColor common.EQ2Color `eq2:"color"` - LegsFile common.EQ2String16 `eq2:"string16"` - PantsColor common.EQ2Color `eq2:"color"` - UnknownLegsColor common.EQ2Color `eq2:"color"` - Unknown9 common.EQ2Color `eq2:"color"` - Eyes2 []float32 `eq2:"float,len=3"` - Ears []float32 `eq2:"float,len=3"` - EyeBrows []float32 `eq2:"float,len=3"` - Cheeks []float32 `eq2:"float,len=3"` - Lips []float32 `eq2:"float,len=3"` - Chin []float32 `eq2:"float,len=3"` - Nose []float32 `eq2:"float,len=3"` - BodySize float32 `eq2:"float"` - BodyAge float32 `eq2:"float"` - SogaVersion uint8 `eq2:"int8"` - SogaRaceFile common.EQ2String16 `eq2:"string16"` - SogaSkinColor common.EQ2Color `eq2:"color"` - SogaEyeColor common.EQ2Color `eq2:"color"` - SogaHairColor1 common.EQ2Color `eq2:"color"` - SogaHairColor2 common.EQ2Color `eq2:"color"` - SogaHairHighlight common.EQ2Color `eq2:"color"` - SogaUnknownColor common.EQ2Color `eq2:"color"` - SogaUnknown11 []uint8 `eq2:"int8,len=26"` - SogaHairFile common.EQ2String16 `eq2:"string16"` - SogaHairTypeColor common.EQ2Color `eq2:"color"` - SogaHairTypeHighlightColor common.EQ2Color `eq2:"color"` - SogaFaceFile common.EQ2String16 `eq2:"string16"` - SogaHairFaceColor common.EQ2Color `eq2:"color"` - SogaHairFaceHighlightColor common.EQ2Color `eq2:"color"` - SogaWingFile common.EQ2String16 `eq2:"string16"` - SogaWingColor1 common.EQ2Color `eq2:"color"` - SogaWingColor2 common.EQ2Color `eq2:"color"` - SogaChestFile common.EQ2String16 `eq2:"string16"` - SogaShirtColor common.EQ2Color `eq2:"color"` - SogaUnknownChestColor common.EQ2Color `eq2:"color"` - SogaLegsFile common.EQ2String16 `eq2:"string16"` - SogaPantsColor common.EQ2Color `eq2:"color"` - SogaUnknownLegsColor common.EQ2Color `eq2:"color"` - SogaUnknown12 common.EQ2Color `eq2:"color"` - SogaEyes2 []float32 `eq2:"float,len=3"` - SogaEars []float32 `eq2:"float,len=3"` - SogaEyeBrows []float32 `eq2:"float,len=3"` - SogaCheeks []float32 `eq2:"float,len=3"` - SogaLips []float32 `eq2:"float,len=3"` - SogaChin []float32 `eq2:"float,len=3"` - SogaNose []float32 `eq2:"float,len=3"` - SogaBodySize float32 `eq2:"float"` - SogaBodyAge float32 `eq2:"float"` -} - -// CreateCharacter for client version 60085 (same as 57080) -type CreateCharacterV60085 struct { - Unknown0 uint8 `eq2:"int8"` - Unknown1 uint32 `eq2:"int32"` - AccountID uint32 `eq2:"int32"` - Unknown3 uint8 `eq2:"int8"` - ServerID uint32 `eq2:"int32"` - Name common.EQ2String16 `eq2:"string16"` - Race uint8 `eq2:"int8"` - Gender uint8 `eq2:"int8"` - Deity uint8 `eq2:"int8"` - Class uint8 `eq2:"int8"` - Level uint8 `eq2:"int8"` - StartingZone uint8 `eq2:"int8"` - Version uint8 `eq2:"int8"` - Unknown10 uint16 `eq2:"int16"` - RaceFile common.EQ2String16 `eq2:"string16"` - SkinColor common.EQ2Color `eq2:"color"` - EyeColor common.EQ2Color `eq2:"color"` - UnknownSkinColor2 common.EQ2Color `eq2:"color"` - HairColor1 common.EQ2Color `eq2:"color"` - HairColor2 common.EQ2Color `eq2:"color"` - HairHighlight common.EQ2Color `eq2:"color"` - Unknown8 []uint8 `eq2:"int8,len=26"` - HairFile common.EQ2String16 `eq2:"string16"` - HairTypeColor common.EQ2Color `eq2:"color"` - HairTypeHighlightColor common.EQ2Color `eq2:"color"` - FaceFile common.EQ2String16 `eq2:"string16"` - HairFaceColor common.EQ2Color `eq2:"color"` - HairFaceHighlightColor common.EQ2Color `eq2:"color"` - WingFile common.EQ2String16 `eq2:"string16"` - WingColor1 common.EQ2Color `eq2:"color"` - WingColor2 common.EQ2Color `eq2:"color"` - ChestFile common.EQ2String16 `eq2:"string16"` - ShirtColor common.EQ2Color `eq2:"color"` - UnknownChestColor common.EQ2Color `eq2:"color"` - LegsFile common.EQ2String16 `eq2:"string16"` - PantsColor common.EQ2Color `eq2:"color"` - UnknownLegsColor common.EQ2Color `eq2:"color"` - Unknown9 common.EQ2Color `eq2:"color"` - Eyes2 []float32 `eq2:"float,len=3"` - Ears []float32 `eq2:"float,len=3"` - EyeBrows []float32 `eq2:"float,len=3"` - Cheeks []float32 `eq2:"float,len=3"` - Lips []float32 `eq2:"float,len=3"` - Chin []float32 `eq2:"float,len=3"` - Nose []float32 `eq2:"float,len=3"` - BodySize float32 `eq2:"float"` - BodyAge float32 `eq2:"float"` - SogaVersion uint8 `eq2:"int8"` - SogaRaceFile common.EQ2String16 `eq2:"string16"` - SogaSkinColor common.EQ2Color `eq2:"color"` - SogaEyeColor common.EQ2Color `eq2:"color"` - SogaHairColor1 common.EQ2Color `eq2:"color"` - SogaHairColor2 common.EQ2Color `eq2:"color"` - SogaHairHighlight common.EQ2Color `eq2:"color"` - SogaUnknownColor common.EQ2Color `eq2:"color"` - SogaUnknown11 []uint8 `eq2:"int8,len=26"` - SogaHairFile common.EQ2String16 `eq2:"string16"` - SogaHairTypeColor common.EQ2Color `eq2:"color"` - SogaHairTypeHighlightColor common.EQ2Color `eq2:"color"` - SogaFaceFile common.EQ2String16 `eq2:"string16"` - SogaHairFaceColor common.EQ2Color `eq2:"color"` - SogaHairFaceHighlightColor common.EQ2Color `eq2:"color"` - SogaWingFile common.EQ2String16 `eq2:"string16"` - SogaWingColor1 common.EQ2Color `eq2:"color"` - SogaWingColor2 common.EQ2Color `eq2:"color"` - SogaChestFile common.EQ2String16 `eq2:"string16"` - SogaShirtColor common.EQ2Color `eq2:"color"` - SogaUnknownChestColor common.EQ2Color `eq2:"color"` - SogaLegsFile common.EQ2String16 `eq2:"string16"` - SogaPantsColor common.EQ2Color `eq2:"color"` - SogaUnknownLegsColor common.EQ2Color `eq2:"color"` - SogaUnknown12 common.EQ2Color `eq2:"color"` - SogaEyes2 []float32 `eq2:"float,len=3"` - SogaEars []float32 `eq2:"float,len=3"` - SogaEyeBrows []float32 `eq2:"float,len=3"` - SogaCheeks []float32 `eq2:"float,len=3"` - SogaLips []float32 `eq2:"float,len=3"` - SogaChin []float32 `eq2:"float,len=3"` - SogaNose []float32 `eq2:"float,len=3"` - SogaBodySize float32 `eq2:"float"` - SogaBodyAge float32 `eq2:"float"` -} - -// CreateCharacter for client version 64659 -type CreateCharacterV64659 struct { - Unknown0 uint8 `eq2:"int8"` - Unknown1 uint32 `eq2:"int32"` - AccountID uint32 `eq2:"int32"` - Unknown3 uint8 `eq2:"int8"` - ServerID uint32 `eq2:"int32"` - Name common.EQ2String16 `eq2:"string16"` - Race uint8 `eq2:"int8"` - Gender uint8 `eq2:"int8"` - Deity uint8 `eq2:"int8"` - Class uint8 `eq2:"int8"` - Level uint8 `eq2:"int8"` - StartingZone uint32 `eq2:"int32"` - Version uint8 `eq2:"int8"` - RaceFile common.EQ2String16 `eq2:"string16"` - SkinColor common.EQ2Color `eq2:"color"` - SkinColor2 common.EQ2Color `eq2:"color"` - EyeColor common.EQ2Color `eq2:"color"` - HairColor1 common.EQ2Color `eq2:"color"` - HairColor2 common.EQ2Color `eq2:"color"` - Unknown8 []uint8 `eq2:"int8,len=38"` - HairFile common.EQ2String16 `eq2:"string16"` - HairTypeColor common.EQ2Color `eq2:"color"` - HairTypeHighlightColor common.EQ2Color `eq2:"color"` - FaceFile common.EQ2String16 `eq2:"string16"` - HairFaceColor common.EQ2Color `eq2:"color"` - HairFaceHighlightColor common.EQ2Color `eq2:"color"` - WingFile common.EQ2String16 `eq2:"string16"` - WingColor1 common.EQ2Color `eq2:"color"` - WingColor2 common.EQ2Color `eq2:"color"` - ChestFile common.EQ2String16 `eq2:"string16"` - ShirtColor common.EQ2Color `eq2:"color"` - UnknownChestColor common.EQ2Color `eq2:"color"` - LegsFile common.EQ2String16 `eq2:"string16"` - PantsColor common.EQ2Color `eq2:"color"` - UnknownLegsColor common.EQ2Color `eq2:"color"` - Unknown9 common.EQ2Color `eq2:"color"` - Eyes2 []float32 `eq2:"float,len=3"` - Ears []float32 `eq2:"float,len=3"` - EyeBrows []float32 `eq2:"float,len=3"` - Cheeks []float32 `eq2:"float,len=3"` - Lips []float32 `eq2:"float,len=3"` - Chin []float32 `eq2:"float,len=3"` - Nose []float32 `eq2:"float,len=3"` - BodySize float32 `eq2:"float"` - BodyAge float32 `eq2:"float"` - SogaVersion uint8 `eq2:"int8"` - SogaRaceFile common.EQ2String16 `eq2:"string16"` - SogaSkinColor common.EQ2Color `eq2:"color"` - SogaEyeColor common.EQ2Color `eq2:"color"` - SogaHairColor1 common.EQ2Color `eq2:"color"` - SogaHairColor2 common.EQ2Color `eq2:"color"` - SogaHairHighlight common.EQ2Color `eq2:"color"` - SogaUnknown11 []uint8 `eq2:"int8,len=38"` - SogaHairFile common.EQ2String16 `eq2:"string16"` - SogaHairTypeColor common.EQ2Color `eq2:"color"` - SogaHairTypeHighlightColor common.EQ2Color `eq2:"color"` - SogaFaceFile common.EQ2String16 `eq2:"string16"` - SogaHairFaceColor common.EQ2Color `eq2:"color"` - SogaHairFaceHighlightColor common.EQ2Color `eq2:"color"` - SogaWingFile common.EQ2String16 `eq2:"string16"` - SogaWingColor1 common.EQ2Color `eq2:"color"` - SogaWingColor2 common.EQ2Color `eq2:"color"` - SogaChestFile common.EQ2String16 `eq2:"string16"` - SogaShirtColor common.EQ2Color `eq2:"color"` - SogaUnknownChestColor common.EQ2Color `eq2:"color"` - SogaLegsFile common.EQ2String16 `eq2:"string16"` - SogaPantsColor common.EQ2Color `eq2:"color"` - SogaUnknownLegsColor common.EQ2Color `eq2:"color"` - SogaUnknown12 common.EQ2Color `eq2:"color"` - SogaEyes2 []float32 `eq2:"float,len=3"` - SogaEars []float32 `eq2:"float,len=3"` - SogaEyeBrows []float32 `eq2:"float,len=3"` - SogaCheeks []float32 `eq2:"float,len=3"` - SogaLips []float32 `eq2:"float,len=3"` - SogaChin []float32 `eq2:"float,len=3"` - SogaNose []float32 `eq2:"float,len=3"` - SogaBodySize float32 `eq2:"float"` - SogaBodyAge float32 `eq2:"float"` - Unknown13 []uint8 `eq2:"int8,len=2"` -} - -// CreateCharacter for client version 65534 (same as 64659) -type CreateCharacterV65534 struct { - Unknown0 uint8 `eq2:"int8"` - Unknown1 uint32 `eq2:"int32"` - AccountID uint32 `eq2:"int32"` - Unknown3 uint8 `eq2:"int8"` - ServerID uint32 `eq2:"int32"` - Name common.EQ2String16 `eq2:"string16"` - Race uint8 `eq2:"int8"` - Gender uint8 `eq2:"int8"` - Deity uint8 `eq2:"int8"` - Class uint8 `eq2:"int8"` - Level uint8 `eq2:"int8"` - StartingZone uint32 `eq2:"int32"` - Version uint8 `eq2:"int8"` - RaceFile common.EQ2String16 `eq2:"string16"` - SkinColor common.EQ2Color `eq2:"color"` - SkinColor2 common.EQ2Color `eq2:"color"` - EyeColor common.EQ2Color `eq2:"color"` - HairColor1 common.EQ2Color `eq2:"color"` - HairColor2 common.EQ2Color `eq2:"color"` - Unknown8 []uint8 `eq2:"int8,len=38"` - HairFile common.EQ2String16 `eq2:"string16"` - HairTypeColor common.EQ2Color `eq2:"color"` - HairTypeHighlightColor common.EQ2Color `eq2:"color"` - FaceFile common.EQ2String16 `eq2:"string16"` - HairFaceColor common.EQ2Color `eq2:"color"` - HairFaceHighlightColor common.EQ2Color `eq2:"color"` - WingFile common.EQ2String16 `eq2:"string16"` - WingColor1 common.EQ2Color `eq2:"color"` - WingColor2 common.EQ2Color `eq2:"color"` - ChestFile common.EQ2String16 `eq2:"string16"` - ShirtColor common.EQ2Color `eq2:"color"` - UnknownChestColor common.EQ2Color `eq2:"color"` - LegsFile common.EQ2String16 `eq2:"string16"` - PantsColor common.EQ2Color `eq2:"color"` - UnknownLegsColor common.EQ2Color `eq2:"color"` - Unknown9 common.EQ2Color `eq2:"color"` - Eyes2 []float32 `eq2:"float,len=3"` - Ears []float32 `eq2:"float,len=3"` - EyeBrows []float32 `eq2:"float,len=3"` - Cheeks []float32 `eq2:"float,len=3"` - Lips []float32 `eq2:"float,len=3"` - Chin []float32 `eq2:"float,len=3"` - Nose []float32 `eq2:"float,len=3"` - BodySize float32 `eq2:"float"` - BodyAge float32 `eq2:"float"` - SogaVersion uint8 `eq2:"int8"` - SogaRaceFile common.EQ2String16 `eq2:"string16"` - SogaSkinColor common.EQ2Color `eq2:"color"` - SogaEyeColor common.EQ2Color `eq2:"color"` - SogaHairColor1 common.EQ2Color `eq2:"color"` - SogaHairColor2 common.EQ2Color `eq2:"color"` - SogaHairHighlight common.EQ2Color `eq2:"color"` - SogaUnknown11 []uint8 `eq2:"int8,len=38"` - SogaHairFile common.EQ2String16 `eq2:"string16"` - SogaHairTypeColor common.EQ2Color `eq2:"color"` - SogaHairTypeHighlightColor common.EQ2Color `eq2:"color"` - SogaFaceFile common.EQ2String16 `eq2:"string16"` - SogaHairFaceColor common.EQ2Color `eq2:"color"` - SogaHairFaceHighlightColor common.EQ2Color `eq2:"color"` - SogaWingFile common.EQ2String16 `eq2:"string16"` - SogaWingColor1 common.EQ2Color `eq2:"color"` - SogaWingColor2 common.EQ2Color `eq2:"color"` - SogaChestFile common.EQ2String16 `eq2:"string16"` - SogaShirtColor common.EQ2Color `eq2:"color"` - SogaUnknownChestColor common.EQ2Color `eq2:"color"` - SogaLegsFile common.EQ2String16 `eq2:"string16"` - SogaPantsColor common.EQ2Color `eq2:"color"` - SogaUnknownLegsColor common.EQ2Color `eq2:"color"` - SogaUnknown12 common.EQ2Color `eq2:"color"` - SogaEyes2 []float32 `eq2:"float,len=3"` - SogaEars []float32 `eq2:"float,len=3"` - SogaEyeBrows []float32 `eq2:"float,len=3"` - SogaCheeks []float32 `eq2:"float,len=3"` - SogaLips []float32 `eq2:"float,len=3"` - SogaChin []float32 `eq2:"float,len=3"` - SogaNose []float32 `eq2:"float,len=3"` - SogaBodySize float32 `eq2:"float"` - SogaBodyAge float32 `eq2:"float"` - Unknown13 []uint8 `eq2:"int8,len=2"` -} diff --git a/internal/packets/ls_structs/CreateCharacterReply.go b/internal/packets/ls_structs/CreateCharacterReply.go deleted file mode 100644 index 0be1dda..0000000 --- a/internal/packets/ls_structs/CreateCharacterReply.go +++ /dev/null @@ -1,26 +0,0 @@ -package ls_structs - -import "eq2emu/internal/common" - -// CreateCharacterReply for client version 1 -type CreateCharacterReplyV1 struct { - AccountID uint32 `eq2:"int32"` - Response uint8 `eq2:"int8"` - Name common.EQ2String16 `eq2:"string16"` -} - -// CreateCharacterReply for client version 1189 -type CreateCharacterReplyV1189 struct { - AccountID uint32 `eq2:"int32"` - Unknown uint32 `eq2:"int32"` - Response uint8 `eq2:"int8"` - Name common.EQ2String16 `eq2:"string16"` -} - -// CreateCharacterReply for client version 60085 -type CreateCharacterReplyV60085 struct { - AccountID uint32 `eq2:"int32"` - Unknown uint32 `eq2:"int32"` - Response uint8 `eq2:"int8"` - Name common.EQ2String16 `eq2:"string16"` -} diff --git a/internal/packets/ls_structs/DeleteCharacterRequest.go b/internal/packets/ls_structs/DeleteCharacterRequest.go deleted file mode 100644 index 604802f..0000000 --- a/internal/packets/ls_structs/DeleteCharacterRequest.go +++ /dev/null @@ -1,10 +0,0 @@ -package ls_structs - -import "eq2emu/internal/common" - -type DeleteCharacterRequest struct { - CharID uint32 `eq2:"int32"` - ServerID uint32 `eq2:"int32"` - Unknown uint32 `eq2:"int32"` - Name common.EQ2String16 `eq2:"string16"` -} diff --git a/internal/packets/ls_structs/DeleteCharacterResponse.go b/internal/packets/ls_structs/DeleteCharacterResponse.go deleted file mode 100644 index 6708574..0000000 --- a/internal/packets/ls_structs/DeleteCharacterResponse.go +++ /dev/null @@ -1,12 +0,0 @@ -package ls_structs - -import "eq2emu/internal/common" - -type DeleteCharacterResponse struct { - Response uint8 `eq2:"int8"` - ServerID uint32 `eq2:"int32"` - CharID uint32 `eq2:"int32"` - AccountID uint32 `eq2:"int32"` - Name common.EQ2String16 `eq2:"string16"` - MaxCharacters uint32 `eq2:"int32"` -} diff --git a/internal/packets/ls_structs/LoginByNumRequest.go b/internal/packets/ls_structs/LoginByNumRequest.go deleted file mode 100644 index b810ffd..0000000 --- a/internal/packets/ls_structs/LoginByNumRequest.go +++ /dev/null @@ -1,28 +0,0 @@ -package ls_structs - -// LoginByNumRequestV1 - Client Version 1 -type LoginByNumRequestV1 struct { - AccountID uint32 `eq2:"int32"` - AccessCode uint32 `eq2:"int32"` - Version uint16 `eq2:"int16"` - Unknown2 []uint32 `eq2:"int32,len=5"` -} - -// LoginByNumRequestV562 - Client Version 562 -type LoginByNumRequestV562 struct { - AccountID uint32 `eq2:"int32"` - AccessCode uint32 `eq2:"int32"` - Unknown uint32 `eq2:"int32"` - Version uint16 `eq2:"int16"` - Unknown2 []uint32 `eq2:"int32,len=5"` -} - -// LoginByNumRequestV1208 - Client Version 1208 -type LoginByNumRequestV1208 struct { - AccountID uint32 `eq2:"int32"` - AccessCode uint32 `eq2:"int32"` - Unknown1 uint32 `eq2:"int32"` - Unknown2 uint16 `eq2:"int16"` - Version uint16 `eq2:"int16"` - Unknown3 []uint32 `eq2:"int32,len=6"` -} diff --git a/internal/packets/ls_structs/LoginReplyMsg.go b/internal/packets/ls_structs/LoginReplyMsg.go deleted file mode 100644 index 6e07b4b..0000000 --- a/internal/packets/ls_structs/LoginReplyMsg.go +++ /dev/null @@ -1,341 +0,0 @@ -package ls_structs - -import "eq2emu/internal/common" - -// StartingItemV1 for older client versions (int16 model_id) -type StartingItemV1 struct { - ModelID uint16 `eq2:"int16"` - SlotID uint8 `eq2:"int8"` - UseColor uint8 `eq2:"int8"` - UseHighlightColor uint8 `eq2:"int8"` - ModelColor common.EQ2Color `eq2:"color"` - ModelHighlightColor common.EQ2Color `eq2:"color"` -} - -// ClassItem represents class-specific starting equipment -type ClassItem struct { - ClassID uint8 `eq2:"int8"` - NumItems uint8 `eq2:"int8"` - StartingItems []StartingItem `eq2:"array,arraysize=NumItems"` -} - -// ClassItemV1 for older client versions -type ClassItemV1 struct { - ClassID uint8 `eq2:"int8"` - NumItems uint8 `eq2:"int8"` - StartingItems []StartingItemV1 `eq2:"array,arraysize=NumItems"` -} - -// LoginReplyMsgV1 - Client version 1 -type LoginReplyMsgV1 struct { - LoginResponse uint8 `eq2:"int8"` - WorldName common.EQ2String16 `eq2:"string16"` - ParentalControlFlag uint8 `eq2:"int8"` - ParentalControlTimer []uint32 `eq2:"int32,len=2"` - ParentalControlNext uint32 `eq2:"int32"` - AccountID uint32 `eq2:"int32"` -} - -// LoginReplyMsgV284 - Client version 284 -type LoginReplyMsgV284 struct { - LoginResponse uint8 `eq2:"int8"` - Unknown common.EQ2String16 `eq2:"string16"` - ParentalControlFlag uint8 `eq2:"int8"` - ParentalControlTimer uint32 `eq2:"int32"` - Unknown2 []uint8 `eq2:"int8,len=8"` - CacheSettingAccountID uint32 `eq2:"int32"` - Unknown3 common.EQ2String16 `eq2:"string16"` - ResetAppearance uint8 `eq2:"int8"` - DoNotForceSoga uint8 `eq2:"int8"` - Unknown5 uint16 `eq2:"int16"` - Unknown6 uint8 `eq2:"int8"` - Unknown7 uint32 `eq2:"int32"` - Unknown8 []uint8 `eq2:"int8,len=2"` - Unknown10 uint8 `eq2:"int8"` - NumClassItems uint8 `eq2:"int8,ifvariableset=Unknown10"` - ClassItems []ClassItemV1 `eq2:"array,arraysize=NumClassItems,ifvariableset=Unknown10"` - UnknownArray2Size uint8 `eq2:"int8"` - UnknownArray2 []UnknownArray2Item `eq2:"array,arraysize=UnknownArray2Size"` -} - -// LS_LoginReplyMsgV843 - Client version 843 -type LoginReplyMsgV843 struct { - LoginResponse uint8 `eq2:"int8"` - Unknown common.EQ2String16 `eq2:"string16"` - ParentalControlFlag uint8 `eq2:"int8"` - ParentalControlTimer uint32 `eq2:"int32"` - Unknown2 []uint8 `eq2:"int8,len=8"` - AccountID uint32 `eq2:"int32"` - Unknown3 common.EQ2String16 `eq2:"string16"` - ResetAppearance uint8 `eq2:"int8"` - DoNotForceSoga uint8 `eq2:"int8"` - Unknown4 uint8 `eq2:"int8"` - Unknown5 uint16 `eq2:"int16"` - Unknown6 uint8 `eq2:"int8"` - Unknown7 uint32 `eq2:"int32"` - RaceUnknown uint8 `eq2:"int8"` - Unknown8 []uint8 `eq2:"int8,len=3"` - Unknown9 uint8 `eq2:"int8"` - Unknown10 uint8 `eq2:"int8"` - NumClassItems uint8 `eq2:"int8,ifvariableset=Unknown10"` - ClassItems []ClassItemV1 `eq2:"array,arraysize=NumClassItems,ifvariableset=Unknown10"` - UnknownArray2Size uint8 `eq2:"int8"` - UnknownArray2 []UnknownArray2Item `eq2:"array,arraysize=UnknownArray2Size"` -} - -// LS_LoginReplyMsgV1096 - Client version 1096 -type LoginReplyMsgV1096 struct { - LoginResponse uint8 `eq2:"int8"` - Unknown common.EQ2String16 `eq2:"string16"` - ParentalControlFlag uint8 `eq2:"int8"` - ParentalControlTimer uint32 `eq2:"int32"` - Unknown2 []uint8 `eq2:"int8,len=8"` - AccountID uint32 `eq2:"int32"` - Unknown3 common.EQ2String16 `eq2:"string16"` - ResetAppearance uint8 `eq2:"int8"` - DoNotForceSoga uint8 `eq2:"int8"` - Unknown4 uint8 `eq2:"int8"` - Unknown5 uint16 `eq2:"int16"` - Unknown6 []uint8 `eq2:"int8,len=5"` - Unknown7 uint32 `eq2:"int32"` - RaceUnknown uint8 `eq2:"int8"` - Unknown8 []uint8 `eq2:"int8,len=3"` - Unknown9 uint8 `eq2:"int8"` - Unknown10 uint8 `eq2:"int8"` - NumClassItems uint8 `eq2:"int8,ifvariableset=Unknown10"` - ClassItems []ClassItemV1 `eq2:"array,arraysize=NumClassItems,ifvariableset=Unknown10"` - UnknownArray2Size uint8 `eq2:"int8"` - UnknownArray2 []UnknownArray2Item `eq2:"array,arraysize=UnknownArray2Size"` - Unknown11 uint32 `eq2:"int32"` - SubLevel uint32 `eq2:"int32"` - RaceFlag uint32 `eq2:"int32"` - ClassFlag uint32 `eq2:"int32"` - Password common.EQ2String16 `eq2:"string16"` - Username common.EQ2String16 `eq2:"string16"` -} - -// LoginReplyMsgV1142 - Client version 1142 -type LoginReplyMsgV1142 struct { - LoginResponse uint8 `eq2:"int8"` - Unknown common.EQ2String16 `eq2:"string16"` - ParentalControlFlag uint8 `eq2:"int8"` - ParentalControlTimer uint32 `eq2:"int32"` - Unknown2 []uint8 `eq2:"int8,len=8"` - AccountID uint32 `eq2:"int32"` - Unknown3 common.EQ2String16 `eq2:"string16"` - ResetAppearance uint8 `eq2:"int8"` - DoNotForceSoga uint8 `eq2:"int8"` - Unknown4 uint8 `eq2:"int8"` - Unknown5 uint16 `eq2:"int16"` - Unknown6 []uint8 `eq2:"int8,len=5"` - Unknown7 uint32 `eq2:"int32"` - Unknown7a uint32 `eq2:"int32"` - RaceUnknown uint8 `eq2:"int8"` - Unknown8 []uint8 `eq2:"int8,len=3"` - Unknown9 uint8 `eq2:"int8"` - Unknown10 uint8 `eq2:"int8"` - NumClassItems uint8 `eq2:"int8,ifvariableset=Unknown10"` - ClassItems []ClassItemV1 `eq2:"array,arraysize=NumClassItems,ifvariableset=Unknown10"` - UnknownArray2Size uint8 `eq2:"int8"` - UnknownArray2 []UnknownArray2Item `eq2:"array,arraysize=UnknownArray2Size"` - Unknown11 uint32 `eq2:"int32"` - SubLevel uint32 `eq2:"int32"` - RaceFlag uint32 `eq2:"int32"` - ClassFlag uint32 `eq2:"int32"` - Password common.EQ2String16 `eq2:"string16"` - Username common.EQ2String16 `eq2:"string16"` -} - -// LoginReplyMsgV1188 - Client version 1188 -type LoginReplyMsgV1188 struct { - LoginResponse uint8 `eq2:"int8"` - Unknown common.EQ2String16 `eq2:"string16"` - ParentalControlFlag uint8 `eq2:"int8"` - ParentalControlTimer uint32 `eq2:"int32"` - Unknown2 []uint8 `eq2:"int8,len=8"` - AccountID uint32 `eq2:"int32"` - Unknown3 common.EQ2String16 `eq2:"string16"` - ResetAppearance uint8 `eq2:"int8"` - DoNotForceSoga uint8 `eq2:"int8"` - Unknown4 uint8 `eq2:"int8"` - Unknown5 uint16 `eq2:"int16"` - Unknown6 []uint8 `eq2:"int8,len=5"` - Unknown7 uint32 `eq2:"int32"` - Unknown7a uint32 `eq2:"int32"` - RaceUnknown uint8 `eq2:"int8"` - Unknown8 []uint8 `eq2:"int8,len=3"` - Unknown9 uint8 `eq2:"int8"` - Unknown10 uint8 `eq2:"int8"` - NumClassItems uint8 `eq2:"int8,ifvariableset=Unknown10"` - ClassItems []ClassItemV1 `eq2:"array,arraysize=NumClassItems,ifvariableset=Unknown10"` - UnknownArray2Size uint8 `eq2:"int8"` - UnknownArray2 []UnknownArray2Item `eq2:"array,arraysize=UnknownArray2Size"` - Unknown11 uint32 `eq2:"int32"` - SubLevel uint32 `eq2:"int32"` - RaceFlag uint32 `eq2:"int32"` - ClassFlag uint32 `eq2:"int32"` - Password common.EQ2String16 `eq2:"string16"` - Username common.EQ2String16 `eq2:"string16"` - Unknown12 common.EQ2String16 `eq2:"string16"` -} - -// LoginReplyMsgV57080 - Client version 57080 -type LoginReplyMsgV57080 struct { - LoginResponse uint8 `eq2:"int8"` - Unknown common.EQ2String16 `eq2:"string16"` - ParentalControlFlag uint8 `eq2:"int8"` - ParentalControlTimer uint32 `eq2:"int32"` - Unknown2 []uint8 `eq2:"int8,len=8"` - AccountID uint32 `eq2:"int32"` - Unknown3 common.EQ2String16 `eq2:"string16"` - ResetAppearance uint8 `eq2:"int8"` - DoNotForceSoga uint8 `eq2:"int8"` - Unknown4 uint8 `eq2:"int8"` - Unknown5 uint16 `eq2:"int16"` - Unknown6 []uint8 `eq2:"int8,len=5"` - Unknown7 uint32 `eq2:"int32"` - Unknown7a uint32 `eq2:"int32"` - RaceUnknown uint8 `eq2:"int8"` - Unknown8 []uint8 `eq2:"int8,len=3"` - Unknown9 uint8 `eq2:"int8"` - Unknown10 uint8 `eq2:"int8"` - NumClassItems uint8 `eq2:"int8,ifvariableset=Unknown10"` - ClassItems []ClassItem `eq2:"array,arraysize=NumClassItems,ifvariableset=Unknown10"` - UnknownArray2Size uint8 `eq2:"int8"` - UnknownArray2 []UnknownArray2Item `eq2:"array,arraysize=UnknownArray2Size"` - Unknown11 uint32 `eq2:"int32"` - SubLevel uint32 `eq2:"int32"` - RaceFlag uint32 `eq2:"int32"` - ClassFlag uint32 `eq2:"int32"` - Password common.EQ2String16 `eq2:"string16"` - Username common.EQ2String16 `eq2:"string16"` - Service common.EQ2String16 `eq2:"string16"` - Web1 common.EQ2String16 `eq2:"string16"` - Web2 common.EQ2String16 `eq2:"string16"` - Web3 common.EQ2String16 `eq2:"string16"` - Web4 common.EQ2String16 `eq2:"string16"` - Web5 common.EQ2String16 `eq2:"string16"` - Web6 common.EQ2String16 `eq2:"string16"` - Web7 common.EQ2String16 `eq2:"string16"` - Web8 common.EQ2String16 `eq2:"string16"` - Web9 common.EQ2String16 `eq2:"string16"` - Unknown12 uint8 `eq2:"int8"` - Lvl90NumClassItems uint8 `eq2:"int8,ifvariableset=Unknown10"` - Lvl90ClassItems []ClassItem `eq2:"array,arraysize=Lvl90NumClassItems,ifvariableset=Unknown10"` - Unknown13 []uint8 `eq2:"int8,len=5"` -} - -// LoginReplyMsgV60100 - Client version 60100 -type LoginReplyMsgV60100 struct { - LoginResponse uint8 `eq2:"int8"` - Unknown common.EQ2String16 `eq2:"string16"` - ParentalControlFlag uint8 `eq2:"int8"` - ParentalControlTimer uint32 `eq2:"int32"` - Unknown2 []uint8 `eq2:"int8,len=8"` - AccountID uint32 `eq2:"int32"` - Unknown3 common.EQ2String16 `eq2:"string16"` - ResetAppearance uint8 `eq2:"int8"` - DoNotForceSoga uint8 `eq2:"int8"` - Unknown5 uint64 `eq2:"int64"` - Unknown7 uint32 `eq2:"int32"` - Unknown7a uint16 `eq2:"int16"` - RaceUnknown uint8 `eq2:"int8"` - Unknown8 []uint8 `eq2:"int8,len=3"` - Unknown9 []uint8 `eq2:"int8,len=3"` - Unknown10 uint8 `eq2:"int8"` - NumClassItems uint8 `eq2:"int8,ifvariableset=Unknown10"` - ClassItems []ClassItem `eq2:"array,arraysize=NumClassItems,ifvariableset=Unknown10"` - UnknownArray2Size uint8 `eq2:"int8"` - UnknownArray2 []UnknownArray2Item `eq2:"array,arraysize=UnknownArray2Size"` - Unknown11 uint32 `eq2:"int32"` - SubLevel uint32 `eq2:"int32"` - RaceFlag uint32 `eq2:"int32"` - ClassFlag uint32 `eq2:"int32"` - Password common.EQ2String16 `eq2:"string16"` - Username common.EQ2String16 `eq2:"string16"` - Service common.EQ2String16 `eq2:"string16"` - Unknown12 uint8 `eq2:"int8"` - Lvl90NumClassItems uint8 `eq2:"int8,ifvariableset=Unknown12"` - Lvl90ClassItems []ClassItem `eq2:"array,arraysize=Lvl90NumClassItems,ifvariableset=Unknown12"` - Unknown13 uint8 `eq2:"int8"` - TimeLockedNumClassItems uint8 `eq2:"int8,ifvariableset=Unknown13"` - TimeLockedClassItems []ClassItem `eq2:"array,arraysize=TimeLockedNumClassItems,ifvariableset=Unknown13"` - Unknown14 []uint8 `eq2:"int8,len=13"` -} - -// LoginReplyMsgV63181 - Client version 63181 -type LoginReplyMsgV63181 struct { - LoginResponse uint8 `eq2:"int8"` - Unknown common.EQ2String16 `eq2:"string16"` - ParentalControlFlag uint8 `eq2:"int8"` - ParentalControlTimer uint32 `eq2:"int32"` - Unknown2 []uint8 `eq2:"int8,len=8"` - AccountID uint32 `eq2:"int32"` - Unknown3 common.EQ2String16 `eq2:"string16"` - ResetAppearance uint8 `eq2:"int8"` - DoNotForceSoga uint8 `eq2:"int8"` - Unknown4 uint8 `eq2:"int8"` - Unknown5 uint16 `eq2:"int16"` - Unknown6 []uint8 `eq2:"int8,len=5"` - Unknown6a []uint8 `eq2:"int8,len=8"` - Unknown7 uint32 `eq2:"int32"` - Unknown7a uint16 `eq2:"int16"` - RaceUnknown uint8 `eq2:"int8"` - Unknown8 []uint8 `eq2:"int8,len=3"` - Unknown9 []uint8 `eq2:"int8,len=3"` - Unknown10 uint8 `eq2:"int8"` - NumClassItems uint8 `eq2:"int8,ifvariableset=Unknown10"` - ClassItems []ClassItem `eq2:"array,arraysize=NumClassItems,ifvariableset=Unknown10"` - UnknownArray2Size uint8 `eq2:"int8"` - UnknownArray2 []UnknownArray2Item `eq2:"array,arraysize=UnknownArray2Size"` - Unknown11 uint32 `eq2:"int32"` - SubLevel uint32 `eq2:"int32"` - RaceFlag uint32 `eq2:"int32"` - ClassFlag uint32 `eq2:"int32"` - Password common.EQ2String16 `eq2:"string16"` - Username common.EQ2String16 `eq2:"string16"` - Service common.EQ2String16 `eq2:"string16"` - Unknown12 uint8 `eq2:"int8"` - Lvl90NumClassItems uint8 `eq2:"int8,ifvariableset=Unknown12"` - Lvl90ClassItems []ClassItem `eq2:"array,arraysize=Lvl90NumClassItems,ifvariableset=Unknown12"` - Unknown13 uint8 `eq2:"int8"` - TimeLockedNumClassItems uint8 `eq2:"int8,ifvariableset=Unknown13"` - TimeLockedClassItems []ClassItem `eq2:"array,arraysize=TimeLockedNumClassItems,ifvariableset=Unknown13"` - Unknown14 []uint8 `eq2:"int8,len=9"` -} - -// LoginReplyMsgV65534 - Client version 65534 (latest) -type LoginReplyMsgV65534 struct { - LoginResponse uint8 `eq2:"int8"` - WorldName common.EQ2String16 `eq2:"string16"` - ParentalControlFlag uint8 `eq2:"int8"` - ParentalControlTimer uint64 `eq2:"int64"` - Unknown2 uint32 `eq2:"int32"` - AccountID uint32 `eq2:"int32"` - Unknown3 common.EQ2String16 `eq2:"string16"` - ResetAppearance uint8 `eq2:"int8"` - DoNotForceSoga uint8 `eq2:"int8"` - Unknown4 common.EQ2String32 `eq2:"string32"` - Unknown7 common.EQ2String32 `eq2:"string32"` - RaceUnknown uint32 `eq2:"int32"` - Unknown8 uint8 `eq2:"int8"` - Unknown10 uint8 `eq2:"int8"` - NumClassItems uint8 `eq2:"int8,ifvariableset=Unknown10"` - ClassItems []ClassItem `eq2:"array,arraysize=NumClassItems,ifvariableset=Unknown10"` - UnknownArray2Size uint8 `eq2:"int8"` - UnknownArray2 []UnknownArray2Item `eq2:"array,arraysize=UnknownArray2Size,ifvariableset=UnknownArray2Size"` - Unknown11 uint32 `eq2:"int32"` - SubLevel uint32 `eq2:"int32"` - RaceFlag uint32 `eq2:"int32"` - ClassFlag uint32 `eq2:"int32"` - Password common.EQ2String16 `eq2:"string16"` - Username common.EQ2String16 `eq2:"string16"` - Service common.EQ2String16 `eq2:"string16"` - Unknown12 uint8 `eq2:"int8"` - Lvl90NumClassItems uint8 `eq2:"int8,ifvariableset=Unknown12"` - Lvl90ClassItems []ClassItem `eq2:"array,arraysize=Lvl90NumClassItems,ifvariableset=Unknown12"` - Unknown13 uint8 `eq2:"int8"` - TimeLockedNumClassItems uint8 `eq2:"int8,ifvariableset=Unknown13"` - TimeLockedClassItems []ClassItem `eq2:"array,arraysize=TimeLockedNumClassItems,ifvariableset=Unknown13"` - Unknown14 []uint8 `eq2:"int8,len=13"` -} diff --git a/internal/packets/ls_structs/LoginRequest.go b/internal/packets/ls_structs/LoginRequest.go deleted file mode 100644 index a2d6a1a..0000000 --- a/internal/packets/ls_structs/LoginRequest.go +++ /dev/null @@ -1,42 +0,0 @@ -package ls_structs - -import "eq2emu/internal/common" - -// LoginRequest for client version 1 -type LoginRequestV1 struct { - SessionID common.EQ2String16 `eq2:"string16"` - SessionRecycleToken common.EQ2String16 `eq2:"string16"` - Username common.EQ2String16 `eq2:"string16"` - Password common.EQ2String16 `eq2:"string16"` - AcctNum uint32 `eq2:"int32"` - PassCode uint32 `eq2:"int32"` - Version uint16 `eq2:"int16"` -} - -// LoginRequest for client version 562 -type LoginRequestV562 struct { - AccessCode common.EQ2String16 `eq2:"string16"` - Unknown1 common.EQ2String16 `eq2:"string16"` - Username common.EQ2String16 `eq2:"string16"` - Password common.EQ2String16 `eq2:"string16"` - Unknown2 []uint8 `eq2:"int8,len=8"` - Unknown3 []uint8 `eq2:"int8,len=2"` - Version uint32 `eq2:"int32"` - Unknown3b uint16 `eq2:"int16"` - Unknown4 uint32 `eq2:"int32"` -} - -// LoginRequest for client version 1208 -type LoginRequestV1208 struct { - AccessCode common.EQ2String16 `eq2:"string16"` - Unknown1 common.EQ2String16 `eq2:"string16"` - Username common.EQ2String16 `eq2:"string16"` - Password common.EQ2String16 `eq2:"string16"` - Unknown2 []uint8 `eq2:"int8,len=8"` - Unknown3 []uint8 `eq2:"int8,len=2"` - Version uint16 `eq2:"int16"` - Unknown4 uint8 `eq2:"int8"` - Unknown5 []uint32 `eq2:"int32,len=3"` - Unknown6 uint16 `eq2:"int16"` - Unknown7 common.EQ2String16 `eq2:"string16"` -} diff --git a/internal/packets/ls_structs/LoginResponse.go b/internal/packets/ls_structs/LoginResponse.go deleted file mode 100644 index 47b3ad9..0000000 --- a/internal/packets/ls_structs/LoginResponse.go +++ /dev/null @@ -1,180 +0,0 @@ -package ls_structs - -import "eq2emu/internal/common" - -// LoginResponse for client version 1 -type LoginResponseV1 struct { - ReplyCode uint8 `eq2:"int8"` - Unknown01 uint16 `eq2:"int16"` - Unknown02 uint8 `eq2:"int8"` - Unknown03 int32 `eq2:"sint32"` - Unknown04 int32 `eq2:"sint32"` - Unknown05 int32 `eq2:"sint32"` - AccountID uint32 `eq2:"int32"` - Unknown06 uint16 `eq2:"int16"` - Unknown07 uint8 `eq2:"int8"` - Unknown08 uint8 `eq2:"int8"` - Unknown09 uint32 `eq2:"int32"` - Unknown10 uint8 `eq2:"int8"` - Unknown11 uint32 `eq2:"int32"` - Unknown12 uint8 `eq2:"int8"` -} - -// LoginResponse for client version 546 -type LoginResponseV546 struct { - ReplyCode uint8 `eq2:"int8"` - Unknown uint16 `eq2:"int16"` - Unknown01 uint8 `eq2:"int8"` - Unknown03 int32 `eq2:"sint32"` - Unknown04 int32 `eq2:"sint32"` - Unknown15 []uint8 `eq2:"int8,len=11"` - Unknown02 uint8 `eq2:"int8"` -} - -// LoginResponse for client version 561 -type LoginResponseV561 struct { - ReplyCode uint8 `eq2:"int8"` - Unknown01 []uint8 `eq2:"int8,len=22"` - Unknown02 uint8 `eq2:"int8"` - Unknown03 int32 `eq2:"sint32"` - Unknown04 int32 `eq2:"sint32"` - Unknown05 int32 `eq2:"sint32"` - AccountID uint32 `eq2:"int32"` - Unknown06 []uint8 `eq2:"int8,len=7"` - Unknown07 uint32 `eq2:"int32"` - Unknown08 uint32 `eq2:"int32"` - Unknown09 uint32 `eq2:"int32"` - Unknown10 uint32 `eq2:"int32"` -} - -// LoginResponse for client version 1096 -type LoginResponseV1096 struct { - ReplyCode uint8 `eq2:"int8"` - Unknown01 []uint8 `eq2:"int8,len=22"` - Unknown02 uint8 `eq2:"int8"` - Unknown03 int32 `eq2:"sint32"` - Unknown04 int32 `eq2:"sint32"` - Unknown05 int32 `eq2:"sint32"` - AccountID uint32 `eq2:"int32"` - Unknown06 []uint8 `eq2:"int8,len=7"` - Unknown07 uint32 `eq2:"int32"` - Unknown08 uint32 `eq2:"int32"` - Unknown09 uint32 `eq2:"int32"` - Unknown10 uint32 `eq2:"int32"` -} - -// LoginResponse for client version 1144 -type LoginResponseV1144 struct { - ReplyCode uint8 `eq2:"int8"` - Unknown01 []uint8 `eq2:"int8,len=22"` - Unknown02 uint8 `eq2:"int8"` - Unknown03 int32 `eq2:"sint32"` - Unknown04 int32 `eq2:"sint32"` - Unknown05 int32 `eq2:"sint32"` - AccountID uint32 `eq2:"int32"` - Unknown06 []uint8 `eq2:"int8,len=15"` - Unknown07 uint32 `eq2:"int32"` - Unknown08 uint32 `eq2:"int32"` - Unknown09 uint32 `eq2:"int32"` - Unknown10 uint32 `eq2:"int32"` -} - -// LoginResponse for client version 1153 -type LoginResponseV1153 struct { - ReplyCode uint8 `eq2:"int8"` - Unknown01 []uint8 `eq2:"int8,len=22"` - Unknown02 uint8 `eq2:"int8"` - Unknown03 int32 `eq2:"sint32"` - Unknown04 int32 `eq2:"sint32"` - Unknown05 int32 `eq2:"sint32"` - AccountID uint32 `eq2:"int32"` - Unknown06 []uint8 `eq2:"int8,len=7"` - Unknown07 uint32 `eq2:"int32"` - Unknown08 uint32 `eq2:"int32"` - Unknown09 uint32 `eq2:"int32"` - Unknown10 uint32 `eq2:"int32"` - Unknown11 uint32 `eq2:"int32"` -} - -// LoginResponse for client version 1193 -type LoginResponseV1193 struct { - ReplyCode uint8 `eq2:"int8"` - Unknown01 []uint8 `eq2:"int8,len=22"` - Unknown02 uint8 `eq2:"int8"` - Unknown03 int32 `eq2:"sint32"` - Unknown04 int32 `eq2:"sint32"` - Unknown05 int32 `eq2:"sint32"` - AccountID uint32 `eq2:"int32"` - Unknown06 []uint8 `eq2:"int8,len=7"` - Unknown07 uint32 `eq2:"int32"` - Unknown08 uint32 `eq2:"int32"` - Unknown09 uint32 `eq2:"int32"` - Unknown10 uint32 `eq2:"int32"` - Unknown11 uint32 `eq2:"int32"` - Unknown12 uint16 `eq2:"int16"` -} - -// ClassItems represents class-specific starting items -type ClassItems struct { - ClassID uint8 `eq2:"int8"` - NumItems uint8 `eq2:"int8"` - StartingItems []StartingItem `eq2:"array,arraysize=NumItems"` -} - -// LoginResponse for client version 60100 - most complex version -type LoginResponseV60100 struct { - LoginResponse uint8 `eq2:"int8"` - Unknown common.EQ2String16 `eq2:"string16"` - ParentalControlFlag uint8 `eq2:"int8"` - ParentalControlTimer uint32 `eq2:"int32"` - Unknown2 []uint8 `eq2:"int8,len=8"` - AccountID uint32 `eq2:"int32"` - Unknown3 common.EQ2String16 `eq2:"string16"` - ResetAppearance uint8 `eq2:"int8"` - DoNotForceSoga uint8 `eq2:"int8"` - Unknown4 uint8 `eq2:"int8"` - Unknown5 uint16 `eq2:"int16"` - Unknown6 []uint8 `eq2:"int8,len=5"` - Unknown7 uint32 `eq2:"int32"` - Unknown7a uint16 `eq2:"int16"` - RaceUnknown uint8 `eq2:"int8"` - Unknown8 []uint8 `eq2:"int8,len=3"` - Unknown9 []uint8 `eq2:"int8,len=3"` - Unknown10 uint8 `eq2:"int8"` - NumClassItems uint8 `eq2:"int8,ifvariableset=Unknown10"` - ClassItems []ClassItems `eq2:"array,arraysize=NumClassItems,ifvariableset=Unknown10"` - UnknownArray2Size uint8 `eq2:"int8"` - UnknownArray2 []UnknownArray2Item `eq2:"array,arraysize=UnknownArray2Size"` - Unknown11 uint32 `eq2:"int32"` - SubLevel uint32 `eq2:"int32"` - RaceFlag uint32 `eq2:"int32"` - ClassFlag uint32 `eq2:"int32"` - Password common.EQ2String16 `eq2:"string16"` - Username common.EQ2String16 `eq2:"string16"` - Service common.EQ2String16 `eq2:"string16"` - Unknown12 uint8 `eq2:"int8"` - Lvl90NumClassItems uint8 `eq2:"int8,ifvariableset=Unknown12"` - Lvl90ClassItems []ClassItems `eq2:"array,arraysize=Lvl90NumClassItems,ifvariableset=Unknown12"` - Unknown13 uint8 `eq2:"int8"` - TimeLockedNumClassItems uint8 `eq2:"int8,ifvariableset=Unknown13"` - TimeLockedClassItems []ClassItems `eq2:"array,arraysize=TimeLockedNumClassItems,ifvariableset=Unknown13"` - Unknown14 []uint8 `eq2:"int8,len=13"` -} - -// LoginResponse for client version 57048 -type LoginResponseV57048 struct { - ReplyCode uint8 `eq2:"int8"` - Unknown01 []uint8 `eq2:"int8,len=22"` - Unknown02 uint8 `eq2:"int8"` - Unknown03 int32 `eq2:"sint32"` - Unknown04 int32 `eq2:"sint32"` - Unknown05 int32 `eq2:"sint32"` - AccountID uint32 `eq2:"int32"` - Unknown06 []uint8 `eq2:"int8,len=7"` - Unknown07 uint32 `eq2:"int32"` - Unknown08 uint32 `eq2:"int32"` - Unknown09 uint32 `eq2:"int32"` - Unknown10 uint32 `eq2:"int32"` - Unknown11 uint32 `eq2:"int32"` - Unknown12 []uint32 `eq2:"int32,len=5"` -} diff --git a/internal/packets/ls_structs/PlayRequest.go b/internal/packets/ls_structs/PlayRequest.go deleted file mode 100644 index 34a93e3..0000000 --- a/internal/packets/ls_structs/PlayRequest.go +++ /dev/null @@ -1,16 +0,0 @@ -package ls_structs - -import "eq2emu/internal/common" - -// PlayRequest for client version 1 -type PlayRequestV1 struct { - CharID uint32 `eq2:"int32"` - Name common.EQ2String16 `eq2:"string16"` -} - -// PlayRequest for client version 284 -type PlayRequestV284 struct { - CharID uint32 `eq2:"int32"` - ServerID uint32 `eq2:"int32"` - Unknown []uint8 `eq2:"int8,len=3"` -} diff --git a/internal/packets/ls_structs/PlayResponse.go b/internal/packets/ls_structs/PlayResponse.go deleted file mode 100644 index 22a0b66..0000000 --- a/internal/packets/ls_structs/PlayResponse.go +++ /dev/null @@ -1,42 +0,0 @@ -package ls_structs - -import "eq2emu/internal/common" - -// PlayResponse for client version 1 -type PlayResponseV1 struct { - Response uint8 `eq2:"int8"` - Server common.EQ2String8 `eq2:"string8"` - Port uint16 `eq2:"int16"` - AccountID uint32 `eq2:"int32"` - AccessCode uint32 `eq2:"int32"` -} - -// PlayResponse for client version 1096 -type PlayResponseV1096 struct { - Response uint8 `eq2:"int8"` - Unknown1 uint16 `eq2:"int16"` - Server common.EQ2String8 `eq2:"string8"` - Port uint16 `eq2:"int16"` - AccountID uint32 `eq2:"int32"` - AccessCode uint32 `eq2:"int32"` -} - -// PlayResponse for client version 60085 -type PlayResponseV60085 struct { - Response uint8 `eq2:"int8"` - Unknown1 []uint16 `eq2:"int16,len=3"` - Server common.EQ2String8 `eq2:"string8"` - Port uint16 `eq2:"int16"` - AccountID uint32 `eq2:"int32"` - AccessCode uint32 `eq2:"int32"` -} - -// PlayResponse for client version 60099 -type PlayResponseV60099 struct { - Response uint8 `eq2:"int8"` - Unknown1 []uint16 `eq2:"int16,len=3"` - Server common.EQ2String8 `eq2:"string8"` - Port uint16 `eq2:"int16"` - AccountID uint32 `eq2:"int32"` - AccessCode uint32 `eq2:"int32"` -} diff --git a/internal/packets/ls_structs/WorldList.go b/internal/packets/ls_structs/WorldList.go deleted file mode 100644 index 5b27a3c..0000000 --- a/internal/packets/ls_structs/WorldList.go +++ /dev/null @@ -1,131 +0,0 @@ -package ls_structs - -import "eq2emu/internal/common" - -// World for client version 1 -type WorldV1 struct { - ID uint32 `eq2:"int32"` - Name common.EQ2String16 `eq2:"string16"` - Online uint8 `eq2:"int8"` - Locked uint8 `eq2:"int8"` - Unknown2 uint8 `eq2:"int8"` - Unknown3 uint8 `eq2:"int8"` - Load uint8 `eq2:"int8"` -} - -// WorldList for client version 1 -type WorldListV1 struct { - NumWorlds uint8 `eq2:"int8"` - WorldList []WorldV1 `eq2:"array,arraysize=NumWorlds"` -} - -// World for client version 373 -type WorldV373 struct { - ID uint32 `eq2:"int32"` - Name common.EQ2String16 `eq2:"string16"` - Tag uint8 `eq2:"int8"` - Locked uint8 `eq2:"int8"` - Hidden uint8 `eq2:"int8"` - Unknown uint8 `eq2:"int8"` - NumPlayers uint16 `eq2:"int16"` - Load uint8 `eq2:"int8"` - NumberOnlineFlag uint8 `eq2:"int8"` - AllowedRaces uint32 `eq2:"int32"` -} - -// WorldList for client version 373 -type WorldListV373 struct { - NumWorlds uint8 `eq2:"int8"` - WorldList []WorldV373 `eq2:"array,arraysize=NumWorlds"` -} - -// World for client version 546 -type WorldV546 struct { - ID uint32 `eq2:"int32"` - Name common.EQ2String16 `eq2:"string16"` - Name2 common.EQ2String16 `eq2:"string16"` - Tag uint8 `eq2:"int8"` - Locked uint8 `eq2:"int8"` - Hidden uint8 `eq2:"int8"` - Unknown uint8 `eq2:"int8"` - NumPlayers uint16 `eq2:"int16"` - Load uint8 `eq2:"int8"` - NumberOnlineFlag uint8 `eq2:"int8"` - Unknown2 uint8 `eq2:"int8"` - AllowedRaces uint32 `eq2:"int32"` -} - -// WorldList for client version 546 -type WorldListV546 struct { - NumWorlds uint8 `eq2:"int8"` - WorldList []WorldV546 `eq2:"array,arraysize=NumWorlds"` -} - -// World for client version 562 -type WorldV562 struct { - ID uint32 `eq2:"int32"` - Name common.EQ2String16 `eq2:"string16"` - Name2 common.EQ2String16 `eq2:"string16"` - Tag uint8 `eq2:"int8"` - Locked uint8 `eq2:"int8"` - Hidden uint8 `eq2:"int8"` - Unknown uint8 `eq2:"int8"` - NumPlayers uint16 `eq2:"int16"` - Load uint8 `eq2:"int8"` - NumberOnlineFlag uint8 `eq2:"int8"` - FeatureSet []uint8 `eq2:"int8,len=2"` - AllowedRaces uint32 `eq2:"int32"` -} - -// WorldList for client version 562 -type WorldListV562 struct { - NumWorlds uint8 `eq2:"int8"` - WorldList []WorldV562 `eq2:"array,arraysize=NumWorlds"` - Unknown2 uint8 `eq2:"int8"` -} - -// World for client version 60114 -type WorldV60114 struct { - ID uint32 `eq2:"int32"` - Name common.EQ2String16 `eq2:"string16"` - Name2 common.EQ2String16 `eq2:"string16"` - Tag uint8 `eq2:"int8"` - Locked uint8 `eq2:"int8"` - Hidden uint8 `eq2:"int8"` - Unknown uint8 `eq2:"int8"` - NumPlayers uint16 `eq2:"int16"` - Load uint8 `eq2:"int8"` - NumberOnlineFlag uint8 `eq2:"int8"` - FeatureSet []uint8 `eq2:"int8,len=2"` - AllowedRaces uint32 `eq2:"int32"` -} - -// WorldList for client version 60114 -type WorldListV60114 struct { - NumWorlds uint8 `eq2:"int8"` - WorldList []WorldV60114 `eq2:"array,arraysize=NumWorlds"` - Unknown2 uint8 `eq2:"int8"` -} - -// World for client version 65534 -type WorldV65534 struct { - ID uint32 `eq2:"int32"` - Name common.EQ2String16 `eq2:"string16"` - Name2 common.EQ2String16 `eq2:"string16"` - Tag uint8 `eq2:"int8"` - Locked uint8 `eq2:"int8"` - Hidden uint8 `eq2:"int8"` - Unknown uint8 `eq2:"int8"` - NumPlayers uint16 `eq2:"int16"` - Load uint8 `eq2:"int8"` - NumberOnlineFlag uint8 `eq2:"int8"` - FeatureSet []uint8 `eq2:"int8,len=3"` - AllowedRaces uint32 `eq2:"int32"` -} - -// WorldList for client version 65534 -type WorldListV65534 struct { - NumWorlds uint8 `eq2:"int8"` - WorldList []WorldV65534 `eq2:"array,arraysize=NumWorlds"` - Unknown2 uint8 `eq2:"int8"` -} diff --git a/internal/packets/ls_structs/WorldUpdate.go b/internal/packets/ls_structs/WorldUpdate.go deleted file mode 100644 index 82ef9cb..0000000 --- a/internal/packets/ls_structs/WorldUpdate.go +++ /dev/null @@ -1,9 +0,0 @@ -package ls_structs - -type WorldUpdate struct { - ServerID uint32 `eq2:"int32"` - Up uint8 `eq2:"int8"` - Locked uint8 `eq2:"int8"` - Unknown1 uint8 `eq2:"int8"` - Unknown2 uint8 `eq2:"int8"` -} diff --git a/internal/packets/ls_structs/common.go b/internal/packets/ls_structs/common.go deleted file mode 100644 index e0a6bd1..0000000 --- a/internal/packets/ls_structs/common.go +++ /dev/null @@ -1,112 +0,0 @@ -package ls_structs - -import ( - "eq2emu/internal/common" - "eq2emu/internal/packets/parser" - "reflect" -) - -type UnknownArray2Item struct { - Array2Unknown uint32 `eq2:"int32"` -} - -// StartingItem represents equipment items for character creation -type StartingItem struct { - ModelID uint32 `eq2:"int32"` - SlotID uint8 `eq2:"int8"` - UseColor uint8 `eq2:"int8"` - UseHighlightColor uint8 `eq2:"int8"` - ModelColor common.EQ2Color `eq2:"color"` - ModelHighlightColor common.EQ2Color `eq2:"color"` -} - -func RegisterLoginServerStructs(registry *parser.VersionRegistry) { - // CreateCharacterReply - registry.RegisterStruct("CreateCharacterReply", "1", reflect.TypeOf(CreateCharacterReplyV1{})) - registry.RegisterStruct("CreateCharacterReply", "1189", reflect.TypeOf(CreateCharacterReplyV1189{})) - registry.RegisterStruct("CreateCharacterReply", "60085", reflect.TypeOf(CreateCharacterReplyV60085{})) - - // DeleteCharacterRequest - registry.RegisterStruct("DeleteCharacterRequest", "1", reflect.TypeOf(DeleteCharacterRequest{})) - - // DeleteCharacterResponse - registry.RegisterStruct("DeleteCharacterResponse", "1", reflect.TypeOf(DeleteCharacterResponse{})) - - // LoginRequest - registry.RegisterStruct("LoginRequest", "1", reflect.TypeOf(LoginRequestV1{})) - registry.RegisterStruct("LoginRequest", "562", reflect.TypeOf(LoginRequestV562{})) - registry.RegisterStruct("LoginRequest", "1208", reflect.TypeOf(LoginRequestV1208{})) - - // LoginResponse - registry.RegisterStruct("LoginResponse", "1", reflect.TypeOf(LoginResponseV1{})) - registry.RegisterStruct("LoginResponse", "546", reflect.TypeOf(LoginResponseV546{})) - registry.RegisterStruct("LoginResponse", "561", reflect.TypeOf(LoginResponseV561{})) - registry.RegisterStruct("LoginResponse", "1096", reflect.TypeOf(LoginResponseV1096{})) - registry.RegisterStruct("LoginResponse", "1144", reflect.TypeOf(LoginResponseV1144{})) - registry.RegisterStruct("LoginResponse", "1153", reflect.TypeOf(LoginResponseV1153{})) - registry.RegisterStruct("LoginResponse", "1193", reflect.TypeOf(LoginResponseV1193{})) - registry.RegisterStruct("LoginResponse", "57048", reflect.TypeOf(LoginResponseV57048{})) - registry.RegisterStruct("LoginResponse", "60100", reflect.TypeOf(LoginResponseV60100{})) - - // PlayRequest - registry.RegisterStruct("PlayRequest", "1", reflect.TypeOf(PlayRequestV1{})) - registry.RegisterStruct("PlayRequest", "284", reflect.TypeOf(PlayRequestV284{})) - - // PlayResponse - registry.RegisterStruct("PlayResponse", "1", reflect.TypeOf(PlayResponseV1{})) - registry.RegisterStruct("PlayResponse", "1096", reflect.TypeOf(PlayResponseV1096{})) - registry.RegisterStruct("PlayResponse", "60085", reflect.TypeOf(PlayResponseV60085{})) - registry.RegisterStruct("PlayResponse", "60099", reflect.TypeOf(PlayResponseV60099{})) - - // WorldList - registry.RegisterStruct("WorldList", "1", reflect.TypeOf(WorldListV1{})) - registry.RegisterStruct("WorldList", "373", reflect.TypeOf(WorldListV373{})) - registry.RegisterStruct("WorldList", "546", reflect.TypeOf(WorldListV546{})) - registry.RegisterStruct("WorldList", "562", reflect.TypeOf(WorldListV562{})) - registry.RegisterStruct("WorldList", "60114", reflect.TypeOf(WorldListV60114{})) - registry.RegisterStruct("WorldList", "65534", reflect.TypeOf(WorldListV65534{})) - - // WorldUpdate - registry.RegisterStruct("WorldUpdate", "1", reflect.TypeOf(WorldUpdate{})) - - // LoginReplyMsg - registry.RegisterStruct("LoginReplyMsg", "1", reflect.TypeOf(LoginReplyMsgV1{})) - registry.RegisterStruct("LoginReplyMsg", "284", reflect.TypeOf(LoginReplyMsgV284{})) - registry.RegisterStruct("LoginReplyMsg", "843", reflect.TypeOf(LoginReplyMsgV843{})) - registry.RegisterStruct("LoginReplyMsg", "1096", reflect.TypeOf(LoginReplyMsgV1096{})) - registry.RegisterStruct("LoginReplyMsg", "1142", reflect.TypeOf(LoginReplyMsgV1142{})) - registry.RegisterStruct("LoginReplyMsg", "1188", reflect.TypeOf(LoginReplyMsgV1188{})) - registry.RegisterStruct("LoginReplyMsg", "57080", reflect.TypeOf(LoginReplyMsgV57080{})) - registry.RegisterStruct("LoginReplyMsg", "60100", reflect.TypeOf(LoginReplyMsgV60100{})) - registry.RegisterStruct("LoginReplyMsg", "63181", reflect.TypeOf(LoginReplyMsgV63181{})) - registry.RegisterStruct("LoginReplyMsg", "65534", reflect.TypeOf(LoginReplyMsgV65534{})) - - // LoginByNumRequest - registry.RegisterStruct("LoginByNumRequest", "1", reflect.TypeOf(LoginByNumRequestV1{})) - registry.RegisterStruct("LoginByNumRequest", "562", reflect.TypeOf(LoginByNumRequestV562{})) - registry.RegisterStruct("LoginByNumRequest", "1208", reflect.TypeOf(LoginByNumRequestV1208{})) - - // BadLanguageFilter - registry.RegisterStruct("BadLanguageFilter", "1", reflect.TypeOf(BadLanguageFilter{})) - - // CharSelectProfile - registry.RegisterStruct("CharSelectProfile", "1", reflect.TypeOf(CharSelectProfileV1{})) - registry.RegisterStruct("CharSelectProfile", "373", reflect.TypeOf(CharSelectProfileV373{})) - registry.RegisterStruct("CharSelectProfile", "546", reflect.TypeOf(CharSelectProfileV546{})) - registry.RegisterStruct("CharSelectProfile", "562", reflect.TypeOf(CharSelectProfileV562{})) - registry.RegisterStruct("CharSelectProfile", "887", reflect.TypeOf(CharSelectProfileV887{})) - registry.RegisterStruct("CharSelectProfile", "60085", reflect.TypeOf(CharSelectProfileV60085{})) - - // CreateCharacter - registry.RegisterStruct("CreateCharacter", "1", reflect.TypeOf(CreateCharacterV1{})) - registry.RegisterStruct("CreateCharacter", "373", reflect.TypeOf(CreateCharacterV373{})) - registry.RegisterStruct("CreateCharacter", "546", reflect.TypeOf(CreateCharacterV546{})) - registry.RegisterStruct("CreateCharacter", "561", reflect.TypeOf(CreateCharacterV561{})) - registry.RegisterStruct("CreateCharacter", "562", reflect.TypeOf(CreateCharacterV562{})) - registry.RegisterStruct("CreateCharacter", "869", reflect.TypeOf(CreateCharacterV869{})) - registry.RegisterStruct("CreateCharacter", "1096", reflect.TypeOf(CreateCharacterV1096{})) - registry.RegisterStruct("CreateCharacter", "57080", reflect.TypeOf(CreateCharacterV57080{})) - registry.RegisterStruct("CreateCharacter", "60085", reflect.TypeOf(CreateCharacterV60085{})) - registry.RegisterStruct("CreateCharacter", "64659", reflect.TypeOf(CreateCharacterV64659{})) - registry.RegisterStruct("CreateCharacter", "65534", reflect.TypeOf(CreateCharacterV65534{})) -} diff --git a/internal/packets/ls_structs/ls_structs_test.go b/internal/packets/ls_structs/ls_structs_test.go deleted file mode 100644 index 43f7c98..0000000 --- a/internal/packets/ls_structs/ls_structs_test.go +++ /dev/null @@ -1,641 +0,0 @@ -package ls_structs - -import ( - "eq2emu/internal/packets/parser" - "testing" -) - -func TestDeleteCharacterRequest(t *testing.T) { - // CharID=12345, ServerID=1, Unknown=0, Name="TestChar" - data := []byte{ - 0x39, 0x30, 0x00, 0x00, // CharID = 12345 - 0x01, 0x00, 0x00, 0x00, // ServerID = 1 - 0x00, 0x00, 0x00, 0x00, // Unknown = 0 - 0x08, 0x00, 'T', 'e', 's', 't', 'C', 'h', 'a', 'r', // Name = "TestChar" - } - - parser := parser.NewParser(data) - var packet DeleteCharacterRequest - err := parser.ParseStruct(&packet) - if err != nil { - t.Fatalf("Parse error: %v", err) - } - - if packet.CharID != 12345 { - t.Errorf("Expected CharID=12345, got %d", packet.CharID) - } - if packet.ServerID != 1 { - t.Errorf("Expected ServerID=1, got %d", packet.ServerID) - } - if packet.Name.Data != "TestChar" { - t.Errorf("Expected Name='TestChar', got '%s'", packet.Name.Data) - } -} - -func TestDeleteCharacterResponse(t *testing.T) { - // Response=1, ServerID=1, CharID=12345, AccountID=54321, Name="TestChar", MaxCharacters=8 - data := []byte{ - 0x01, // Response = 1 - 0x01, 0x00, 0x00, 0x00, // ServerID = 1 - 0x39, 0x30, 0x00, 0x00, // CharID = 12345 - 0x31, 0xD4, 0x00, 0x00, // AccountID = 54321 - 0x08, 0x00, 'T', 'e', 's', 't', 'C', 'h', 'a', 'r', // Name = "TestChar" - 0x08, 0x00, 0x00, 0x00, // MaxCharacters = 8 - } - - parser := parser.NewParser(data) - var packet DeleteCharacterResponse - err := parser.ParseStruct(&packet) - if err != nil { - t.Fatalf("Parse error: %v", err) - } - - if packet.Response != 1 { - t.Errorf("Expected Response=1, got %d", packet.Response) - } - if packet.CharID != 12345 { - t.Errorf("Expected CharID=12345, got %d", packet.CharID) - } - if packet.AccountID != 54321 { - t.Errorf("Expected AccountID=54321, got %d", packet.AccountID) - } - if packet.MaxCharacters != 8 { - t.Errorf("Expected MaxCharacters=8, got %d", packet.MaxCharacters) - } -} - -func TestCreateCharacterReplyV1(t *testing.T) { - // AccountID=54321, Response=0, Name="NewChar" - data := []byte{ - 0x31, 0xD4, 0x00, 0x00, // AccountID = 54321 - 0x00, // Response = 0 - 0x07, 0x00, 'N', 'e', 'w', 'C', 'h', 'a', 'r', // Name = "NewChar" - } - - parser := parser.NewParser(data) - var packet CreateCharacterReplyV1 - err := parser.ParseStruct(&packet) - if err != nil { - t.Fatalf("Parse error: %v", err) - } - - if packet.AccountID != 54321 { - t.Errorf("Expected AccountID=54321, got %d", packet.AccountID) - } - if packet.Response != 0 { - t.Errorf("Expected Response=0, got %d", packet.Response) - } - if packet.Name.Data != "NewChar" { - t.Errorf("Expected Name='NewChar', got '%s'", packet.Name.Data) - } -} - -func TestCreateCharacterReplyV1189(t *testing.T) { - // AccountID=54321, Unknown=100, Response=0, Name="NewChar" - data := []byte{ - 0x31, 0xD4, 0x00, 0x00, // AccountID = 54321 - 0x64, 0x00, 0x00, 0x00, // Unknown = 100 - 0x00, // Response = 0 - 0x07, 0x00, 'N', 'e', 'w', 'C', 'h', 'a', 'r', // Name = "NewChar" - } - - parser := parser.NewParser(data) - var packet CreateCharacterReplyV1189 - err := parser.ParseStruct(&packet) - if err != nil { - t.Fatalf("Parse error: %v", err) - } - - if packet.AccountID != 54321 { - t.Errorf("Expected AccountID=54321, got %d", packet.AccountID) - } - if packet.Unknown != 100 { - t.Errorf("Expected Unknown=100, got %d", packet.Unknown) - } - if packet.Response != 0 { - t.Errorf("Expected Response=0, got %d", packet.Response) - } -} - -func TestLoginRequestV1(t *testing.T) { - data := []byte{ - // SessionID = "session123" - 0x0A, 0x00, 's', 'e', 's', 's', 'i', 'o', 'n', '1', '2', '3', - // SessionRecycleToken = "token456" - 0x08, 0x00, 't', 'o', 'k', 'e', 'n', '4', '5', '6', - // Username = "testuser" - 0x08, 0x00, 't', 'e', 's', 't', 'u', 's', 'e', 'r', - // Password = "testpass" - 0x08, 0x00, 't', 'e', 's', 't', 'p', 'a', 's', 's', - 0x31, 0xD4, 0x00, 0x00, // AcctNum = 54321 - 0x39, 0x30, 0x00, 0x00, // PassCode = 12345 - 0xDC, 0x05, // Version = 1500 - } - - parser := parser.NewParser(data) - var packet LoginRequestV1 - err := parser.ParseStruct(&packet) - if err != nil { - t.Fatalf("Parse error: %v", err) - } - - if packet.SessionID.Data != "session123" { - t.Errorf("Expected SessionID='session123', got '%s'", packet.SessionID.Data) - } - if packet.Username.Data != "testuser" { - t.Errorf("Expected Username='testuser', got '%s'", packet.Username.Data) - } - if packet.AcctNum != 54321 { - t.Errorf("Expected AcctNum=54321, got %d", packet.AcctNum) - } - if packet.Version != 1500 { - t.Errorf("Expected Version=1500, got %d", packet.Version) - } -} - -func TestLoginByNumRequestV1(t *testing.T) { - data := []byte{ - 0x31, 0xD4, 0x00, 0x00, // AccountID = 54321 - 0x39, 0x30, 0x00, 0x00, // AccessCode = 12345 - 0xDC, 0x05, // Version = 1500 - // Unknown2 = [1, 2, 3, 4, 5] - 0x01, 0x00, 0x00, 0x00, - 0x02, 0x00, 0x00, 0x00, - 0x03, 0x00, 0x00, 0x00, - 0x04, 0x00, 0x00, 0x00, - 0x05, 0x00, 0x00, 0x00, - } - - parser := parser.NewParser(data) - var packet LoginByNumRequestV1 - err := parser.ParseStruct(&packet) - if err != nil { - t.Fatalf("Parse error: %v", err) - } - - if packet.AccountID != 54321 { - t.Errorf("Expected AccountID=54321, got %d", packet.AccountID) - } - if packet.AccessCode != 12345 { - t.Errorf("Expected AccessCode=12345, got %d", packet.AccessCode) - } - if packet.Version != 1500 { - t.Errorf("Expected Version=1500, got %d", packet.Version) - } - if len(packet.Unknown2) != 5 { - t.Errorf("Expected Unknown2 length=5, got %d", len(packet.Unknown2)) - } - if packet.Unknown2[0] != 1 || packet.Unknown2[4] != 5 { - t.Errorf("Expected Unknown2=[1,2,3,4,5], got %v", packet.Unknown2) - } -} - -func TestPlayRequestV1(t *testing.T) { - data := []byte{ - 0x39, 0x30, 0x00, 0x00, // CharID = 12345 - 0x08, 0x00, 'T', 'e', 's', 't', 'C', 'h', 'a', 'r', // Name = "TestChar" - } - - parser := parser.NewParser(data) - var packet PlayRequestV1 - err := parser.ParseStruct(&packet) - if err != nil { - t.Fatalf("Parse error: %v", err) - } - - if packet.CharID != 12345 { - t.Errorf("Expected CharID=12345, got %d", packet.CharID) - } - if packet.Name.Data != "TestChar" { - t.Errorf("Expected Name='TestChar', got '%s'", packet.Name.Data) - } -} - -func TestPlayResponseV1(t *testing.T) { - data := []byte{ - 0x01, // Response = 1 - 0x09, '1', '2', '7', '.', '0', '.', '0', '.', '1', // Server = "127.0.0.1" - 0xC4, 0x09, // Port = 2500 - 0x31, 0xD4, 0x00, 0x00, // AccountID = 54321 - 0x39, 0x30, 0x00, 0x00, // AccessCode = 12345 - } - - parser := parser.NewParser(data) - var packet PlayResponseV1 - err := parser.ParseStruct(&packet) - if err != nil { - t.Fatalf("Parse error: %v", err) - } - - if packet.Response != 1 { - t.Errorf("Expected Response=1, got %d", packet.Response) - } - if packet.Server.Data != "127.0.0.1" { - t.Errorf("Expected Server='127.0.0.1', got '%s'", packet.Server.Data) - } - if packet.Port != 2500 { - t.Errorf("Expected Port=2500, got %d", packet.Port) - } - if packet.AccountID != 54321 { - t.Errorf("Expected AccountID=54321, got %d", packet.AccountID) - } -} - -func TestWorldListV1(t *testing.T) { - data := []byte{ - 0x02, // NumWorlds = 2 - // World 1 - 0x01, 0x00, 0x00, 0x00, // ID = 1 - 0x07, 0x00, 'A', 'n', 't', 'o', 'n', 'i', 'a', // Name = "Antonia" - 0x01, // Online = 1 - 0x00, // Locked = 0 - 0x00, // Unknown2 = 0 - 0x00, // Unknown3 = 0 - 0x32, // Load = 50 - // World 2 - 0x02, 0x00, 0x00, 0x00, // ID = 2 - 0x08, 0x00, 'N', 'a', 'g', 'a', 'f', 'e', 'n', ' ', // Name = "Nagafen " - 0x01, // Online = 1 - 0x01, // Locked = 1 - 0x00, // Unknown2 = 0 - 0x00, // Unknown3 = 0 - 0x64, // Load = 100 - } - - parser := parser.NewParser(data) - var packet WorldListV1 - err := parser.ParseStruct(&packet) - if err != nil { - t.Fatalf("Parse error: %v", err) - } - - if packet.NumWorlds != 2 { - t.Errorf("Expected NumWorlds=2, got %d", packet.NumWorlds) - } - if len(packet.WorldList) != 2 { - t.Errorf("Expected 2 worlds, got %d", len(packet.WorldList)) - } - if packet.WorldList[0].Name.Data != "Antonia" { - t.Errorf("Expected first world 'Antonia', got '%s'", packet.WorldList[0].Name.Data) - } - if packet.WorldList[0].Online != 1 { - t.Errorf("Expected first world online=1, got %d", packet.WorldList[0].Online) - } - if packet.WorldList[1].Locked != 1 { - t.Errorf("Expected second world locked=1, got %d", packet.WorldList[1].Locked) - } -} - -func TestWorldListV373(t *testing.T) { - data := []byte{ - 0x01, // NumWorlds = 1 - // World 1 - 0x01, 0x00, 0x00, 0x00, // ID = 1 - 0x07, 0x00, 'A', 'n', 't', 'o', 'n', 'i', 'a', // Name = "Antonia" - 0x01, // Tag = 1 - 0x00, // Locked = 0 - 0x00, // Hidden = 0 - 0x00, // Unknown = 0 - 0x64, 0x00, // NumPlayers = 100 - 0x32, // Load = 50 - 0x01, // NumberOnlineFlag = 1 - 0xFF, 0xFF, 0xFF, 0xFF, // AllowedRaces = 0xFFFFFFFF - } - - parser := parser.NewParser(data) - var packet WorldListV373 - err := parser.ParseStruct(&packet) - if err != nil { - t.Fatalf("Parse error: %v", err) - } - - if packet.NumWorlds != 1 { - t.Errorf("Expected NumWorlds=1, got %d", packet.NumWorlds) - } - if packet.WorldList[0].NumPlayers != 100 { - t.Errorf("Expected NumPlayers=100, got %d", packet.WorldList[0].NumPlayers) - } - if packet.WorldList[0].AllowedRaces != 0xFFFFFFFF { - t.Errorf("Expected AllowedRaces=0xFFFFFFFF, got %d", packet.WorldList[0].AllowedRaces) - } -} - -func TestLoginReplyMsgV1(t *testing.T) { - data := []byte{ - 0x00, // LoginResponse = 0 (success) - 0x07, 0x00, 'A', 'n', 't', 'o', 'n', 'i', 'a', // WorldName = "Antonia" - 0x00, // ParentalControlFlag = 0 - 0x00, 0x00, 0x00, 0x00, // ParentalControlTimer[0] = 0 - 0x00, 0x00, 0x00, 0x00, // ParentalControlTimer[1] = 0 - 0x00, 0x00, 0x00, 0x00, // ParentalControlNext = 0 - 0x31, 0xD4, 0x00, 0x00, // AccountID = 54321 - } - - parser := parser.NewParser(data) - var packet LoginReplyMsgV1 - err := parser.ParseStruct(&packet) - if err != nil { - t.Fatalf("Parse error: %v", err) - } - - if packet.LoginResponse != 0 { - t.Errorf("Expected LoginResponse=0, got %d", packet.LoginResponse) - } - if packet.WorldName.Data != "Antonia" { - t.Errorf("Expected WorldName='Antonia', got '%s'", packet.WorldName.Data) - } - if packet.AccountID != 54321 { - t.Errorf("Expected AccountID=54321, got %d", packet.AccountID) - } -} - -func TestLoginReplyMsgV284WithClassItems(t *testing.T) { - data := []byte{ - 0x00, // LoginResponse = 0 - 0x07, 0x00, 'A', 'n', 't', 'o', 'n', 'i', 'a', // Unknown = "Antonia" - 0x00, // ParentalControlFlag = 0 - 0x00, 0x00, 0x00, 0x00, // ParentalControlTimer = 0 - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Unknown2 (8 bytes) - 0x31, 0xD4, 0x00, 0x00, // CacheSettingAccountID = 54321 - 0x04, 0x00, 't', 'e', 's', 't', // Unknown3 = "test" - 0x00, // ResetAppearance = 0 - 0x00, // DoNotForceSoga = 0 - 0x00, 0x00, // Unknown5 = 0 - 0x00, // Unknown6 = 0 - 0x00, 0x00, 0x00, 0x00, // Unknown7 = 0 - 0x00, 0x00, // Unknown8 (2 bytes) - 0x01, // Unknown10 = 1 (truthy, so class items will be parsed) - 0x01, // NumClassItems = 1 - // ClassItem 1 - 0x05, // ClassID = 5 - 0x01, // NumItems = 1 - // StartingItem 1 - 0x64, 0x00, // ModelID = 100 - 0x01, // SlotID = 1 - 0x01, // UseColor = 1 - 0x01, // UseHighlightColor = 1 - 0xFF, 0x00, 0x00, // ModelColor = Red - 0x00, 0xFF, 0x00, // ModelHighlightColor = Green - 0x00, // UnknownArray2Size = 0 - } - - parser := parser.NewParser(data) - var packet LoginReplyMsgV284 - err := parser.ParseStruct(&packet) - if err != nil { - t.Fatalf("Parse error: %v", err) - } - - if packet.LoginResponse != 0 { - t.Errorf("Expected LoginResponse=0, got %d", packet.LoginResponse) - } - if packet.CacheSettingAccountID != 54321 { - t.Errorf("Expected CacheSettingAccountID=54321, got %d", packet.CacheSettingAccountID) - } - if packet.Unknown10 != 1 { - t.Errorf("Expected Unknown10=1, got %d", packet.Unknown10) - } - if packet.NumClassItems != 1 { - t.Errorf("Expected NumClassItems=1, got %d", packet.NumClassItems) - } - if len(packet.ClassItems) != 1 { - t.Errorf("Expected 1 class item, got %d", len(packet.ClassItems)) - } - if packet.ClassItems[0].ClassID != 5 { - t.Errorf("Expected ClassID=5, got %d", packet.ClassItems[0].ClassID) - } - if len(packet.ClassItems[0].StartingItems) != 1 { - t.Errorf("Expected 1 starting item, got %d", len(packet.ClassItems[0].StartingItems)) - } - if packet.ClassItems[0].StartingItems[0].ModelID != 100 { - t.Errorf("Expected ModelID=100, got %d", packet.ClassItems[0].StartingItems[0].ModelID) - } -} - -func TestLoginReplyMsgV284WithoutClassItems(t *testing.T) { - data := []byte{ - 0x00, // LoginResponse = 0 - 0x07, 0x00, 'A', 'n', 't', 'o', 'n', 'i', 'a', // Unknown = "Antonia" - 0x00, // ParentalControlFlag = 0 - 0x00, 0x00, 0x00, 0x00, // ParentalControlTimer = 0 - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Unknown2 (8 bytes) - 0x31, 0xD4, 0x00, 0x00, // CacheSettingAccountID = 54321 - 0x04, 0x00, 't', 'e', 's', 't', // Unknown3 = "test" - 0x00, // ResetAppearance = 0 - 0x00, // DoNotForceSoga = 0 - 0x00, 0x00, // Unknown5 = 0 - 0x00, // Unknown6 = 0 - 0x00, 0x00, 0x00, 0x00, // Unknown7 = 0 - 0x00, 0x00, // Unknown8 (2 bytes) - 0x00, // Unknown10 = 0 (falsy, so class items will be skipped) - 0x00, // UnknownArray2Size = 0 - } - - parser := parser.NewParser(data) - var packet LoginReplyMsgV284 - err := parser.ParseStruct(&packet) - if err != nil { - t.Fatalf("Parse error: %v", err) - } - - if packet.Unknown10 != 0 { - t.Errorf("Expected Unknown10=0, got %d", packet.Unknown10) - } - if packet.NumClassItems != 0 { - t.Errorf("Expected NumClassItems=0 (should be skipped), got %d", packet.NumClassItems) - } - if len(packet.ClassItems) != 0 { - t.Errorf("Expected 0 class items (should be skipped), got %d", len(packet.ClassItems)) - } -} - -func TestVersionRegistryWithLoginReplyMsg(t *testing.T) { - registry := parser.NewVersionRegistry() - RegisterLoginServerStructs(registry) - - // Test data for LoginReplyMsgV1 - data := []byte{ - 0x00, // LoginResponse = 0 - 0x07, 0x00, 'A', 'n', 't', 'o', 'n', 'i', 'a', // WorldName = "Antonia" - 0x00, // ParentalControlFlag = 0 - 0x00, 0x00, 0x00, 0x00, // ParentalControlTimer[0] = 0 - 0x00, 0x00, 0x00, 0x00, // ParentalControlTimer[1] = 0 - 0x00, 0x00, 0x00, 0x00, // ParentalControlNext = 0 - 0x31, 0xD4, 0x00, 0x00, // AccountID = 54321 - } - - parser := parser.NewParser(data) - result, err := parser.ParseWithVersion(registry, "LoginReplyMsg", "1") - if err != nil { - t.Fatalf("Parse with version error: %v", err) - } - - packet, ok := result.(LoginReplyMsgV1) - if !ok { - t.Fatal("Expected LoginReplyMsgV1 type") - } - - if packet.LoginResponse != 0 { - t.Errorf("Expected LoginResponse=0, got %d", packet.LoginResponse) - } - if packet.WorldName.Data != "Antonia" { - t.Errorf("Expected WorldName='Antonia', got '%s'", packet.WorldName.Data) - } -} - -func TestVersionRegistryFallback(t *testing.T) { - registry := parser.NewVersionRegistry() - RegisterLoginServerStructs(registry) - - data := []byte{ - 0x39, 0x30, 0x00, 0x00, // CharID = 12345 - 0x08, 0x00, 'T', 'e', 's', 't', 'C', 'h', 'a', 'r', // Name = "TestChar" - } - - parser := parser.NewParser(data) - - // Request version 150 (doesn't exist), should fall back to version 1 - result, err := parser.ParseWithVersion(registry, "PlayRequest", "150") - if err != nil { - t.Fatalf("Parse with fallback error: %v", err) - } - - // Should get PlayRequestV1 (nearest lower version) - packet, ok := result.(PlayRequestV1) - if !ok { - t.Error("Expected fallback to PlayRequestV1") - } - - if packet.CharID != 12345 { - t.Errorf("Expected CharID=12345, got %d", packet.CharID) - } -} - -func TestWorldUpdate(t *testing.T) { - data := []byte{ - 0x01, 0x00, 0x00, 0x00, // ServerID = 1 - 0x01, // Up = 1 - 0x00, // Locked = 0 - 0x00, // Unknown1 = 0 - 0x32, // Unknown2 = 50 - } - - parser := parser.NewParser(data) - var packet WorldUpdate - err := parser.ParseStruct(&packet) - if err != nil { - t.Fatalf("Parse error: %v", err) - } - - if packet.ServerID != 1 { - t.Errorf("Expected ServerID=1, got %d", packet.ServerID) - } - if packet.Up != 1 { - t.Errorf("Expected Up=1, got %d", packet.Up) - } - if packet.Locked != 0 { - t.Errorf("Expected Locked=0, got %d", packet.Locked) - } -} - -func TestLoginResponseV60100WithComplexArrays(t *testing.T) { - data := []byte{ - 0x00, // LoginResponse = 0 - 0x07, 0x00, 'A', 'n', 't', 'o', 'n', 'i', 'a', // Unknown = "Antonia" - 0x00, // ParentalControlFlag = 0 - 0x00, 0x00, 0x00, 0x00, // ParentalControlTimer = 0 - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Unknown2 (8 bytes) - 0x21, 0xD4, 0x00, 0x00, // AccountID = 54321 - 0x04, 0x00, 't', 'e', 's', 't', // Unknown3 = "test" - 0x00, // ResetAppearance = 0 - 0x00, // DoNotForceSoga = 0 - 0x00, // Unknown4 = 0 - 0x00, 0x00, // Unknown5 = 0 - 0x00, 0x00, 0x00, 0x00, 0x00, // Unknown6 (5 bytes) - 0x00, 0x00, 0x00, 0x00, // Unknown7 = 0 - 0x00, 0x00, // Unknown7a = 0 - 0x00, // RaceUnknown = 0 - 0x00, 0x00, 0x00, // Unknown8 (3 bytes) - 0x00, 0x00, 0x00, // Unknown9 (3 bytes) - 0x01, // Unknown10 = 1 (enables class items) - 0x01, // NumClassItems = 1 - // ClassItem 1 - 0x05, // ClassID = 5 - 0x01, // NumItems = 1 - // StartingItem 1 - 0x64, 0x00, 0x00, 0x00, // ModelID = 100 (int32 in newer versions) - 0x01, // SlotID = 1 - 0x01, // UseColor = 1 - 0x01, // UseHighlightColor = 1 - 0xFF, 0x00, 0x00, // ModelColor = Red - 0x00, 0xFF, 0x00, // ModelHighlightColor = Green - 0x00, // UnknownArray2Size = 0 - 0x00, 0x00, 0x00, 0x00, // Unknown11 = 0 - 0x00, 0x00, 0x00, 0x00, // SubLevel = 0 - 0xFF, 0xFF, 0xFF, 0xFF, // RaceFlag = 0xFFFFFFFF - 0xFF, 0xFF, 0xFF, 0xFF, // ClassFlag = 0xFFFFFFFF - 0x08, 0x00, 't', 'e', 's', 't', 'p', 'a', 's', 's', // Password = "testpass" - 0x08, 0x00, 't', 'e', 's', 't', 'u', 's', 'e', 'r', // Username = "testuser" - 0x07, 0x00, 's', 'e', 'r', 'v', 'i', 'c', 'e', // Service = "service" - 0x01, // Unknown12 = 1 (enables Lvl90 class items) - 0x01, // Lvl90NumClassItems = 1 - // Lvl90 ClassItem 1 - 0x06, // ClassID = 6 - 0x01, // NumItems = 1 - // StartingItem 1 - 0x65, 0x00, 0x00, 0x00, // ModelID = 101 - 0x02, // SlotID = 2 - 0x01, // UseColor = 1 - 0x01, // UseHighlightColor = 1 - 0x00, 0xFF, 0x00, // ModelColor = Green - 0xFF, 0x00, 0x00, // ModelHighlightColor = Red - 0x01, // Unknown13 = 1 (enables TimeLocked class items) - 0x01, // TimeLockedNumClassItems = 1 - // TimeLocked ClassItem 1 - 0x07, // ClassID = 7 - 0x01, // NumItems = 1 - // StartingItem 1 - 0x66, 0x00, 0x00, 0x00, // ModelID = 102 - 0x03, // SlotID = 3 - 0x00, // UseColor = 0 - 0x00, // UseHighlightColor = 0 - 0x80, 0x80, 0x80, // ModelColor = Gray - 0x40, 0x40, 0x40, // ModelHighlightColor = Dark gray - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Unknown14 (13 bytes) - } - - parser := parser.NewParser(data) - var packet LoginResponseV60100 - err := parser.ParseStruct(&packet) - if err != nil { - t.Fatalf("Parse error: %v", err) - } - - // Test main class items - if len(packet.ClassItems) != 1 { - t.Errorf("Expected 1 class item, got %d", len(packet.ClassItems)) - } - if packet.ClassItems[0].ClassID != 5 { - t.Errorf("Expected ClassID=5, got %d", packet.ClassItems[0].ClassID) - } - - // Test Lvl90 class items - if len(packet.Lvl90ClassItems) != 1 { - t.Errorf("Expected 1 Lvl90 class item, got %d", len(packet.Lvl90ClassItems)) - } - if packet.Lvl90ClassItems[0].ClassID != 6 { - t.Errorf("Expected Lvl90 ClassID=6, got %d", packet.Lvl90ClassItems[0].ClassID) - } - - // Test TimeLocked class items - if len(packet.TimeLockedClassItems) != 1 { - t.Errorf("Expected 1 TimeLocked class item, got %d", len(packet.TimeLockedClassItems)) - } - if packet.TimeLockedClassItems[0].ClassID != 7 { - t.Errorf("Expected TimeLocked ClassID=7, got %d", packet.TimeLockedClassItems[0].ClassID) - } - - if packet.RaceFlag != 0xFFFFFFFF { - t.Errorf("Expected RaceFlag=0xFFFFFFFF, got %d", packet.RaceFlag) - } -} diff --git a/internal/packets/parser/DOCS.md b/internal/packets/parser/DOCS.md deleted file mode 100644 index 067e6c5..0000000 --- a/internal/packets/parser/DOCS.md +++ /dev/null @@ -1,250 +0,0 @@ -# EQ2 Packet Parser - -A dead-simple way to turn EverQuest 2's binary packet data into Go structs. Just add some tags to your struct fields and let reflection do the heavy lifting. - -## How it works - -```go -// Your packet structure -type LoginPacket struct { - UserID uint32 `eq2:"int32"` - Username common.EQ2String16 `eq2:"string16"` - Level uint8 `eq2:"int8"` -} - -// Parse some bytes -data := []byte{...} // whatever bytes you got -parser := parser.NewParser(data) - -var packet LoginPacket -err := parser.ParseStruct(&packet) -// boom, packet is now filled with data -``` - -## Tag Syntax - -Just slap `eq2:"type,options"` on your fields and you're good to go. - -### The usual suspects -```go -PlayerID uint32 `eq2:"int32"` // 32-bit integer -Health uint16 `eq2:"int16"` // 16-bit integer -Alive uint8 `eq2:"int8"` // 8-bit integer -Damage float32 `eq2:"float"` // 32-bit float -Name common.EQ2String16 `eq2:"string16"` // EQ2's weird string format -Color common.EQ2Color `eq2:"color"` // RGB color -``` - -### Arrays (because everything's an array in EQ2) -```go -// Fixed size - always 5 items -Stats []uint16 `eq2:"int16,len=5"` - -// Dynamic size - read ItemCount first, then that many items -ItemCount uint8 `eq2:"int8"` -Items []Item `eq2:"array,arraysize=ItemCount"` -``` - -### Conditionals (the fun stuff) -```go -// Only parse this if Channel equals 1 -MessageType uint8 `eq2:"int8,if=Channel==1"` - -// Only parse if HasRewards is truthy -HasRewards uint8 `eq2:"int8"` -RewardData *RewardInfo `eq2:"substruct,ifvariableset=HasRewards"` - -// Only parse if we set the "has_equipment" flag -Equipment []Equipment `eq2:"equipment,ifflag=has_equipment"` - -// Array index variables - access specific array elements -ModCount uint8 `eq2:"int8"` -Mods []Mod `eq2:"array,arraysize=ModCount"` -// This checks if Mods[0] exists and is truthy -ExtraData []byte `eq2:"char,len=10,ifvariableset=header_info_mod_need_0"` - -// Dynamic array index using %i (replaced with current array index) -StatTypes []uint8 `eq2:"int8,len=5"` -StatValues []any `eq2:"int32,type2=float,type2criteria=stat_type_%i!=6"` -``` - -### Comma-separated conditions -Multiple variables can be checked in a single condition using comma-separated lists: - -```go -// Parse only if NONE of the listed variables are set -NumEffects uint8 `eq2:"int8,ifvariablenotset=header_info_header_unknown_0_0,header_unknown_0"` - -// Parse if ANY of the listed variables are set -BonusData []byte `eq2:"char,len=20,ifvariableset=has_bonus,has_special,has_extra"` - -// Parse if ANY of the listed flags are set -OptionalField uint32 `eq2:"int32,ifflag=debug_mode,test_mode,dev_mode"` - -// Parse if ALL of the listed flags are NOT set -ProductionData []byte `eq2:"char,len=50,ifflagnotset=debug_mode,test_mode"` - -// Multiple equals conditions (ANY must be true) -TypeData any `eq2:"int32,ifequals=type=1,category=special"` - -// Multiple not-equals conditions (ALL must be true) -Value uint16 `eq2:"int16,ifnotequals=status=disabled,flag=hidden"` -``` - -**Comma-separated logic rules:** -- `ifvariableset` - TRUE if ANY variable is set -- `ifvariablenotset` - TRUE if ALL variables are NOT set -- `ifflag` - TRUE if ANY flag is set -- `ifflagnotset` - TRUE if ALL flags are NOT set -- `ifequals` - TRUE if ANY condition matches -- `ifnotequals` - TRUE if ALL conditions are true (none match) - -### Type switching (when EQ2 reuses the same bytes for different things) -```go -// Normally parse as int32, but if StatType != 6, parse as float instead -StatType uint8 `eq2:"int8"` -StatValue any `eq2:"int32,type2=float,type2criteria=StatType!=6"` - -// String length operators for type switching -NameLength uint8 `eq2:"int8"` -Name string `eq2:"string16,type2=string8,type2criteria=stat_name!>10"` -``` - -### String length operators -Use `!>`, `!<`, `!>=`, `!<=`, `!=` for string length comparisons: -```go -// Switch to string8 if name length > 10 characters -Name string `eq2:"string16,type2=string8,type2criteria=player_name!>10"` - -// Only parse if description is not empty -HasDesc uint8 `eq2:"int8"` -Description string `eq2:"string16,ifvariableset=HasDesc,if=description!>0"` -``` - -### Size limits (because EQ2 packets can get weird) -```go -// If the data is bigger than 1000 bytes, just truncate it -DataSize uint16 `eq2:"int16"` -Data []byte `eq2:"char,len=DataSize,maxsize=1000,skipoversized"` -``` - -## Multiple client versions - -EQ2 has like 50 different client versions, each with slightly different packet layouts. Handle it like this: - -```go -registry := parser.NewVersionRegistry() -registry.RegisterStruct("LoginReply", "1.0", reflect.TypeOf(LoginReplyV1{})) -registry.RegisterStruct("LoginReply", "2.0", reflect.TypeOf(LoginReplyV2{})) - -// Parser picks the right version (or falls back to closest match) -result, err := parser.ParseWithVersion(registry, "LoginReply", clientVersion) -``` - -## Real example - -```go -type CharacterData struct { - // Basic stuff - CharID uint32 `eq2:"int32"` - Name common.EQ2String16 `eq2:"string16"` - Level uint8 `eq2:"int8"` - - // Guild info (only if they're in a guild) - HasGuild uint8 `eq2:"int8"` - GuildID uint32 `eq2:"int32,ifvariableset=HasGuild"` - - // Variable number of items - ItemCount uint16 `eq2:"int16"` - Items []InventoryItem `eq2:"array,arraysize=ItemCount"` - - // Nested stuff - Stats PlayerStats `eq2:"substruct"` - - // Array index access example - BuffCount uint8 `eq2:"int8"` - Buffs []BuffData `eq2:"array,arraysize=BuffCount"` - // Only parse extended data if first buff exists - ExtendedBuffData []byte `eq2:"char,len=20,ifvariableset=buffs_0"` - - // Comma-separated conditions example - HeaderFlags uint8 `eq2:"int8"` - // Parse effects only if neither unknown field is set - NumEffects uint8 `eq2:"int8,ifvariablenotset=header_info_header_unknown_0_0,header_unknown_0"` - Effects []EffectData `eq2:"array,arraysize=NumEffects"` -} - -type InventoryItem struct { - ItemID uint32 `eq2:"int32"` - Quantity uint16 `eq2:"int16"` - Color common.EQ2Color `eq2:"color"` - - // Type switching based on string length - NameType uint8 `eq2:"int8"` - Name any `eq2:"string16,type2=string8,type2criteria=item_name!<=8"` -} - -type PlayerStats struct { - Health uint32 `eq2:"int32"` - Mana uint32 `eq2:"int32"` - Stamina uint32 `eq2:"int32"` -} - -type BuffData struct { - BuffID uint32 `eq2:"int32"` - Duration uint16 `eq2:"int16"` -} - -type EffectData struct { - Effect common.EQ2String16 `eq2:"string16"` - Percentage uint8 `eq2:"int8"` -} -``` - -## Advanced conditional patterns - -```go -type ComplexPacket struct { - // Array with per-element conditionals using %i - StatCount uint8 `eq2:"int8"` - StatTypes []uint8 `eq2:"int8,len=StatCount"` - StatValues []any `eq2:"int32,type2=float,type2criteria=stat_type_%i!=6"` - - // Array index access for conditionals - ModCount uint8 `eq2:"int8"` - Mods []Mod `eq2:"array,arraysize=ModCount"` - // Parse only if specific array elements exist - Bonus1 uint32 `eq2:"int32,ifvariableset=header_info_mod_need_0"` - Bonus2 uint32 `eq2:"int32,ifvariableset=header_info_mod_need_1"` - - // String length conditionals - PlayerName string `eq2:"string16"` - ShortName string `eq2:"string8,if=player_name!<=8"` - LongDesc string `eq2:"string32,if=player_name!>15"` - - // Comma-separated multi-condition examples - DebugInfo []byte `eq2:"char,len=100,ifflag=debug_mode,test_mode,dev_mode"` - ProdData []byte `eq2:"char,len=50,ifflagnotset=debug_mode,test_mode,dev_mode"` - - // Multiple variable checks - OptionalData []byte `eq2:"char,len=20,ifvariableset=has_optional,has_extended"` - CleanupData []byte `eq2:"char,len=10,ifvariablenotset=dirty_flag,temp_flag,cache_flag"` -} -``` - -## Converting from XML - -If you've got EQ2's XML packet definitions, the conversion is pretty straightforward: - -| XML | Go Tag | -|-----|--------| -| `Type="int32"` | `eq2:"int32"` | -| `ArraySizeVariable="count"` | `arraysize=Count` | -| `IfVariableSet="flag"` | `ifvariableset=Flag` | -| `IfVariableNotSet="var1,var2"` | `ifvariablenotset=var1,var2` | -| `IfFlag="flag1,flag2"` | `ifflag=flag1,flag2` | -| `Size="5"` | `len=5` | -| `Type2Criteria="field!=value"` | `type2criteria=Field!=value` | -| `Type2Criteria="name!>10"` | `type2criteria=name!>10` | -| Array index access | `ifvariableset=array_name_0` | -| Dynamic index patterns | `type2criteria=field_%i!=value` | \ No newline at end of file diff --git a/internal/packets/parser/array_parser.go b/internal/packets/parser/array_parser.go deleted file mode 100644 index 1930c24..0000000 --- a/internal/packets/parser/array_parser.go +++ /dev/null @@ -1,214 +0,0 @@ -package parser - -import ( - "fmt" - "reflect" -) - -// readArray handles array parsing with full substruct support -func (p *Parser) readArray(field reflect.Value, fieldTag *FieldTag) error { - var arraySize int - if fieldTag.ArraySizeVar != "" { - arraySize = p.getDynamicLength(fieldTag.ArraySizeVar) - } else { - size, err := p.readUint32() - if err != nil { - return err - } - arraySize = int(size) - } - - if arraySize == 0 { - return nil - } - - if field.Kind() == reflect.Slice { - elemType := field.Type().Elem() - slice := reflect.MakeSlice(field.Type(), arraySize, arraySize) - - p.arrayStack = append(p.arrayStack, ArrayContext{ - elementType: elemType, - totalSize: arraySize, - sizeVariable: fieldTag.ArraySizeVar, - }) - - for i := 0; i < arraySize; i++ { - p.arrayStack[len(p.arrayStack)-1].currentIndex = i - elem := slice.Index(i) - - if elemType.Kind() == reflect.Struct { - if err := p.parseStructElement(elem, elemType); err != nil { - p.arrayStack = p.arrayStack[:len(p.arrayStack)-1] - return fmt.Errorf("array element %d: %w", i, err) - } - } else { - if err := p.readPrimitiveArrayElement(elem, elemType); err != nil { - p.arrayStack = p.arrayStack[:len(p.arrayStack)-1] - return fmt.Errorf("array element %d: %w", i, err) - } - } - } - - p.arrayStack = p.arrayStack[:len(p.arrayStack)-1] - field.Set(slice) - } - - return nil -} - -// readSubstruct handles substruct parsing -func (p *Parser) readSubstruct(field reflect.Value, length int) error { - if field.Kind() == reflect.Slice { - elemType := field.Type().Elem() - slice := reflect.MakeSlice(field.Type(), length, length) - - for i := range length { - elem := slice.Index(i) - if err := p.parseStructElement(elem, elemType); err != nil { - return fmt.Errorf("substruct element %d: %w", i, err) - } - } - - field.Set(slice) - return nil - } else if field.Kind() == reflect.Struct { - return p.parseStructElement(field, field.Type()) - } else if field.Kind() == reflect.Ptr && field.Type().Elem().Kind() == reflect.Struct { - structType := field.Type().Elem() - newStruct := reflect.New(structType) - if err := p.parseStructElement(newStruct.Elem(), structType); err != nil { - return err - } - field.Set(newStruct) - return nil - } - - return fmt.Errorf("substruct field must be struct, slice of structs, or pointer to struct") -} - -// parseStructElement parses a single struct element -func (p *Parser) parseStructElement(elem reflect.Value, elemType reflect.Type) error { - oldStruct := p.currentStruct - oldCache := p.fieldCache - - p.currentStruct = elem - p.fieldCache = make(map[string]any) - p.structStack = append(p.structStack, elem) - - for i := range elem.NumField() { - field := elem.Field(i) - fieldType := elemType.Field(i) - - if !field.CanSet() { - continue - } - - tag := fieldType.Tag.Get("eq2") - if tag == "" || tag == "-" { - continue - } - - if err := p.parseField(field, tag); err != nil { - p.structStack = p.structStack[:len(p.structStack)-1] - p.currentStruct = oldStruct - p.fieldCache = oldCache - return fmt.Errorf("field %s: %w", fieldType.Name, err) - } - - if field.CanInterface() { - p.fieldCache[fieldType.Name] = field.Interface() - } - } - - p.structStack = p.structStack[:len(p.structStack)-1] - p.currentStruct = oldStruct - p.fieldCache = oldCache - - return nil -} - -// readPrimitiveArrayElement reads primitive array elements -func (p *Parser) readPrimitiveArrayElement(elem reflect.Value, elemType reflect.Type) error { - switch elemType.Kind() { - case reflect.Uint8: - val, err := p.readUint8() - if err != nil { - return err - } - elem.SetUint(uint64(val)) - case reflect.Uint16: - val, err := p.readUint16() - if err != nil { - return err - } - elem.SetUint(uint64(val)) - case reflect.Uint32: - val, err := p.readUint32() - if err != nil { - return err - } - elem.SetUint(uint64(val)) - case reflect.Uint64: - val, err := p.readUint64() - if err != nil { - return err - } - elem.SetUint(val) - case reflect.Int8: - val, err := p.readUint8() - if err != nil { - return err - } - elem.SetInt(int64(int8(val))) - case reflect.Int16: - val, err := p.readUint16() - if err != nil { - return err - } - elem.SetInt(int64(int16(val))) - case reflect.Int32: - val, err := p.readUint32() - if err != nil { - return err - } - elem.SetInt(int64(int32(val))) - case reflect.Int64: - val, err := p.readUint64() - if err != nil { - return err - } - elem.SetInt(int64(val)) - case reflect.Float32: - val, err := p.readFloat32() - if err != nil { - return err - } - elem.SetFloat(float64(val)) - case reflect.Float64: - val, err := p.readFloat64() - if err != nil { - return err - } - elem.SetFloat(val) - default: - return fmt.Errorf("unsupported primitive array element type: %v", elemType.Kind()) - } - - return nil -} - -// GetCurrentArrayIndex returns current array index for nested parsing -func (p *Parser) GetCurrentArrayIndex() int { - if len(p.arrayStack) > 0 { - return p.arrayStack[len(p.arrayStack)-1].currentIndex - } - return -1 -} - -// GetCurrentArraySize returns current array size -func (p *Parser) GetCurrentArraySize() int { - if len(p.arrayStack) > 0 { - return p.arrayStack[len(p.arrayStack)-1].totalSize - } - return 0 -} diff --git a/internal/packets/parser/conditions.go b/internal/packets/parser/conditions.go deleted file mode 100644 index 9c2a200..0000000 --- a/internal/packets/parser/conditions.go +++ /dev/null @@ -1,355 +0,0 @@ -package parser - -import ( - "reflect" - "strconv" - "strings" -) - -// evaluateAllConditions checks all conditional logic -func (p *Parser) evaluateAllConditions(fieldTag *FieldTag, _ reflect.Value) bool { - if fieldTag.Condition != nil && !p.evaluateCondition(fieldTag.Condition) { - return false - } - - if fieldTag.IfVariableSet != "" && !p.evaluateVariableSetCondition(fieldTag.IfVariableSet) { - return false - } - - if fieldTag.IfVariableNotSet != "" && !p.evaluateVariableNotSetCondition(fieldTag.IfVariableNotSet) { - return false - } - - if fieldTag.IfFlag != "" && !p.evaluateFlagCondition(fieldTag.IfFlag) { - return false - } - - if fieldTag.IfFlagNotSet != "" && !p.evaluateFlagNotSetCondition(fieldTag.IfFlagNotSet) { - return false - } - - if fieldTag.IfEquals != "" { - if !p.evaluateEqualsConditions(fieldTag.IfEquals) { - return false - } - } - - if fieldTag.IfNotEquals != "" { - if !p.evaluateNotEqualsConditions(fieldTag.IfNotEquals) { - return false - } - } - - return true -} - -// evaluateVariableSetCondition handles comma-separated variable set conditions -func (p *Parser) evaluateVariableSetCondition(variables string) bool { - varList := p.splitCommaSeparated(variables) - // Return true if ANY variable is set - for _, variable := range varList { - if p.isVariableSet(variable) { - return true - } - } - return false -} - -// evaluateVariableNotSetCondition handles comma-separated variable not set conditions -func (p *Parser) evaluateVariableNotSetCondition(variables string) bool { - varList := p.splitCommaSeparated(variables) - // Return true if ALL variables are not set - for _, variable := range varList { - if p.isVariableSet(variable) { - return false - } - } - return true -} - -// evaluateFlagCondition handles comma-separated flag conditions -func (p *Parser) evaluateFlagCondition(flags string) bool { - flagList := p.splitCommaSeparated(flags) - // Return true if ANY flag is set - for _, flag := range flagList { - if p.flags[flag] { - return true - } - } - return false -} - -// evaluateFlagNotSetCondition handles comma-separated flag not set conditions -func (p *Parser) evaluateFlagNotSetCondition(flags string) bool { - flagList := p.splitCommaSeparated(flags) - // Return true if ALL flags are not set - for _, flag := range flagList { - if p.flags[flag] { - return false - } - } - return true -} - -// evaluateEqualsConditions handles comma-separated equals conditions -func (p *Parser) evaluateEqualsConditions(conditions string) bool { - conditionList := p.splitCommaSeparated(conditions) - // Return true if ANY condition is true - for _, condition := range conditionList { - parts := strings.Split(condition, "=") - if len(parts) == 2 && p.evaluateEqualsCondition(strings.TrimSpace(parts[0]), strings.TrimSpace(parts[1])) { - return true - } - } - return false -} - -// evaluateNotEqualsConditions handles comma-separated not equals conditions -func (p *Parser) evaluateNotEqualsConditions(conditions string) bool { - conditionList := p.splitCommaSeparated(conditions) - // Return true if ALL conditions are true (all not equal) - for _, condition := range conditionList { - parts := strings.Split(condition, "=") - if len(parts) == 2 { - if p.evaluateEqualsCondition(strings.TrimSpace(parts[0]), strings.TrimSpace(parts[1])) { - return false // This condition is false (they are equal) - } - } - } - return true -} - -// splitCommaSeparated splits a comma-separated string and trims whitespace -func (p *Parser) splitCommaSeparated(input string) []string { - if input == "" { - return []string{} - } - - parts := strings.Split(input, ",") - result := make([]string, len(parts)) - for i, part := range parts { - result[i] = strings.TrimSpace(part) - } - return result -} - -// evaluateCondition evaluates conditions for conditional fields -func (p *Parser) evaluateCondition(condition *FieldCondition) bool { - if condition.Type == "simple" { - return p.isVariableSet(condition.Variable) - } - - cachedValue, exists := p.resolveVariable(condition.Variable) - if !exists { - return false - } - - compareValue, err := p.convertValue(condition.Value, cachedValue) - if err != nil { - return false - } - - return p.compareValues(cachedValue, compareValue, condition.Operator) -} - -// isVariableSet checks if a variable exists and has a truthy value -func (p *Parser) isVariableSet(variable string) bool { - cachedValue, exists := p.resolveVariable(variable) - if !exists { - return false - } - return p.isTruthy(cachedValue) -} - -// evaluateEqualsCondition checks field equality -func (p *Parser) evaluateEqualsCondition(variable, value string) bool { - cachedValue, exists := p.resolveVariable(variable) - if !exists { - return false - } - - compareValue, err := p.convertValue(value, cachedValue) - if err != nil { - return false - } - - return p.compareValues(cachedValue, compareValue, "==") -} - -// evaluateType2Criteria evaluates type2 criteria for alternative types with string length support -func (p *Parser) evaluateType2Criteria(criteria string) bool { - // String length operators: !>, !<, !>=, !<=, != - stringLengthOps := []string{"!>=", "!<=", "!>", "!<", "!="} - - for _, op := range stringLengthOps { - if idx := strings.Index(criteria, op); idx > 0 { - fieldName := strings.TrimSpace(criteria[:idx]) - valueStr := strings.TrimSpace(criteria[idx+len(op):]) - - cachedValue, exists := p.resolveVariable(fieldName) - if !exists { - return false - } - - return p.evaluateStringLengthCondition(cachedValue, valueStr, op) - } - } - - // Standard comparison operators - operators := []string{">=", "<=", ">", "<", "=="} - - for _, op := range operators { - if idx := strings.Index(criteria, op); idx > 0 { - fieldName := strings.TrimSpace(criteria[:idx]) - valueStr := strings.TrimSpace(criteria[idx+len(op):]) - - cachedValue, exists := p.resolveVariable(fieldName) - if !exists { - return false - } - - compareValue, err := p.convertValue(valueStr, cachedValue) - if err != nil { - return false - } - - return p.compareValues(cachedValue, compareValue, op) - } - } - - return false -} - -// evaluateStringLengthCondition evaluates string length conditions -func (p *Parser) evaluateStringLengthCondition(value any, lengthStr, operator string) bool { - var stringVal string - - // Extract string value from various types - switch v := value.(type) { - case string: - stringVal = v - default: - // Try to get string representation from struct fields - if reflect.TypeOf(value).Kind() == reflect.Struct { - val := reflect.ValueOf(value) - if dataField := val.FieldByName("Data"); dataField.IsValid() && dataField.Kind() == reflect.String { - stringVal = dataField.String() - } else { - return false - } - } else { - return false - } - } - - targetLength, err := strconv.Atoi(lengthStr) - if err != nil { - return false - } - - stringLength := len(stringVal) - - switch operator { - case "!>": - return stringLength > targetLength - case "!<": - return stringLength < targetLength - case "!>=": - return stringLength >= targetLength - case "!<=": - return stringLength <= targetLength - case "!=": - return stringLength != targetLength - default: - return false - } -} - -// resolveVariable resolves variables with support for array indices and complex patterns -func (p *Parser) resolveVariable(variable string) (any, bool) { - // Handle %i patterns by replacing with current array index - if strings.Contains(variable, "%i") { - currentIndex := p.GetCurrentArrayIndex() - if currentIndex >= 0 { - variable = strings.ReplaceAll(variable, "%i", strconv.Itoa(currentIndex)) - } - } - - // Check field cache first - if cachedValue, exists := p.fieldCache[variable]; exists { - return cachedValue, true - } - - // Handle array index patterns like "header_info_mod_need_0" - if strings.Contains(variable, "_") { - if value, exists := p.resolveArrayIndexVariable(variable); exists { - return value, true - } - } - - // Check current struct - if p.currentStruct.IsValid() { - if field := p.currentStruct.FieldByName(variable); field.IsValid() { - return field.Interface(), true - } - } - - // Check struct stack for nested resolution - for i := len(p.structStack) - 1; i >= 0; i-- { - if field := p.structStack[i].FieldByName(variable); field.IsValid() { - return field.Interface(), true - } - } - - return nil, false -} - -// resolveArrayIndexVariable handles variables with array index suffixes -func (p *Parser) resolveArrayIndexVariable(variable string) (any, bool) { - parts := strings.Split(variable, "_") - if len(parts) < 2 { - return nil, false - } - - // Try to extract index from last part - lastPart := parts[len(parts)-1] - if index, err := strconv.Atoi(lastPart); err == nil { - // Reconstruct base variable name without index - baseVar := strings.Join(parts[:len(parts)-1], "_") - - // Look for array/slice field with this base name - if cachedValue, exists := p.fieldCache[baseVar]; exists { - return p.getArrayElement(cachedValue, index) - } - - // Check current struct for array field - if p.currentStruct.IsValid() { - if field := p.currentStruct.FieldByName(baseVar); field.IsValid() { - return p.getArrayElement(field.Interface(), index) - } - } - - // Check struct stack - for i := len(p.structStack) - 1; i >= 0; i-- { - if field := p.structStack[i].FieldByName(baseVar); field.IsValid() { - return p.getArrayElement(field.Interface(), index) - } - } - } - - return nil, false -} - -// getArrayElement safely extracts element from array/slice -func (p *Parser) getArrayElement(value any, index int) (any, bool) { - val := reflect.ValueOf(value) - - switch val.Kind() { - case reflect.Slice, reflect.Array: - if index >= 0 && index < val.Len() { - return val.Index(index).Interface(), true - } - } - - return nil, false -} diff --git a/internal/packets/parser/field_tag.go b/internal/packets/parser/field_tag.go deleted file mode 100644 index 2bcceb4..0000000 --- a/internal/packets/parser/field_tag.go +++ /dev/null @@ -1,137 +0,0 @@ -package parser - -import ( - "strconv" - "strings" -) - -// FieldTag represents parsed tag parameters -type FieldTag struct { - Type string - Length int - DynamicLen string - Condition *FieldCondition - MaxSize int - SkipOversized bool - OversizedValue int - OversizedByte byte - Type2 string - Type2Criteria string - ArraySizeVar string - IfVariableSet string - IfVariableNotSet string - IfFlag string - IfFlagNotSet string - IfEquals string - IfNotEquals string - Optional bool -} - -// FieldCondition represents XML conditional logic -type FieldCondition struct { - Type string // "if_set", "if_not_set", "if_flag", etc. - Variable string - Value string - Operator string -} - -// parseFieldTag extracts all tag parameters -func (p *Parser) parseFieldTag(tag string) *FieldTag { - parts := strings.Split(tag, ",") - fieldTag := &FieldTag{ - Type: parts[0], - Length: 1, - MaxSize: -1, - OversizedValue: -1, - OversizedByte: 127, - } - - for _, part := range parts[1:] { - p.parseTagParameter(fieldTag, part) - } - - return fieldTag -} - -// parseTagParameter processes individual tag parameters -func (p *Parser) parseTagParameter(fieldTag *FieldTag, part string) { - switch { - case strings.HasPrefix(part, "len="): - lenVal := part[4:] - if l, err := strconv.Atoi(lenVal); err == nil { - fieldTag.Length = l - } else { - fieldTag.DynamicLen = lenVal - } - case strings.HasPrefix(part, "if="): - fieldTag.Condition = p.parseCondition(part[3:]) - case strings.HasPrefix(part, "maxsize="): - if m, err := strconv.Atoi(part[8:]); err == nil { - fieldTag.MaxSize = m - } - case part == "skipoversized": - fieldTag.SkipOversized = true - case strings.HasPrefix(part, "oversized="): - if o, err := strconv.Atoi(part[10:]); err == nil { - fieldTag.OversizedValue = o - } - case strings.HasPrefix(part, "oversizedbyte="): - if o, err := strconv.Atoi(part[14:]); err == nil { - fieldTag.OversizedByte = byte(o) - } - case strings.HasPrefix(part, "type2="): - fieldTag.Type2 = part[6:] - case strings.HasPrefix(part, "type2criteria="): - fieldTag.Type2Criteria = part[14:] - case strings.HasPrefix(part, "arraysize="): - fieldTag.ArraySizeVar = part[10:] - case strings.HasPrefix(part, "ifvariableset="): - fieldTag.IfVariableSet = part[14:] - case strings.HasPrefix(part, "ifvariablenotset="): - fieldTag.IfVariableNotSet = part[17:] - case strings.HasPrefix(part, "ifflag="): - fieldTag.IfFlag = part[7:] - case strings.HasPrefix(part, "ifflagnotset="): - fieldTag.IfFlagNotSet = part[13:] - case strings.HasPrefix(part, "ifequals="): - fieldTag.IfEquals = part[9:] - case strings.HasPrefix(part, "ifnotequals="): - fieldTag.IfNotEquals = part[12:] - case part == "optional": - fieldTag.Optional = true - } -} - -// parseCondition creates FieldCondition from condition string with enhanced operator support -func (p *Parser) parseCondition(condition string) *FieldCondition { - // String length operators must be checked first due to overlapping patterns - stringLengthOps := []string{"!>=", "!<=", "!>", "!<", "!="} - - for _, op := range stringLengthOps { - if idx := strings.Index(condition, op); idx > 0 { - return &FieldCondition{ - Variable: strings.TrimSpace(condition[:idx]), - Value: strings.TrimSpace(condition[idx+len(op):]), - Operator: op, - } - } - } - - // Standard comparison operators - operators := []string{">=", "<=", ">", "<", "==", "&", "|"} - - for _, op := range operators { - if idx := strings.Index(condition, op); idx > 0 { - return &FieldCondition{ - Variable: strings.TrimSpace(condition[:idx]), - Value: strings.TrimSpace(condition[idx+len(op):]), - Operator: op, - } - } - } - - return &FieldCondition{ - Type: "simple", - Variable: condition, - } -} diff --git a/internal/packets/parser/helpers.go b/internal/packets/parser/helpers.go deleted file mode 100644 index 324db0a..0000000 --- a/internal/packets/parser/helpers.go +++ /dev/null @@ -1,375 +0,0 @@ -package parser - -import ( - "reflect" - "strconv" - "strings" -) - -// getDynamicLength gets length from another field with stack support and array index resolution -func (p *Parser) getDynamicLength(fieldName string) int { - // Handle %i patterns by replacing with current array index - if strings.Contains(fieldName, "%i") { - currentIndex := p.GetCurrentArrayIndex() - if currentIndex >= 0 { - fieldName = strings.ReplaceAll(fieldName, "%i", strconv.Itoa(currentIndex)) - } - } - - // Check field cache first - if cachedValue, exists := p.fieldCache[fieldName]; exists { - return p.valueToInt(cachedValue) - } - - // Handle array index patterns like "header_info_mod_need_0" - if strings.Contains(fieldName, "_") { - if value, exists := p.resolveArrayIndexVariableForLength(fieldName); exists { - return p.valueToInt(value) - } - } - - // Check current struct - if p.currentStruct.IsValid() { - if field := p.currentStruct.FieldByName(fieldName); field.IsValid() { - return p.valueToInt(field.Interface()) - } - } - - // Check struct stack for nested resolution - for i := len(p.structStack) - 1; i >= 0; i-- { - if field := p.structStack[i].FieldByName(fieldName); field.IsValid() { - return p.valueToInt(field.Interface()) - } - } - - return 0 -} - -// resolveArrayIndexVariableForLength handles array index variable resolution for length calculations -func (p *Parser) resolveArrayIndexVariableForLength(variable string) (any, bool) { - parts := strings.Split(variable, "_") - if len(parts) < 2 { - return nil, false - } - - // Try to extract index from last part - lastPart := parts[len(parts)-1] - if index, err := strconv.Atoi(lastPart); err == nil { - // Reconstruct base variable name without index - baseVar := strings.Join(parts[:len(parts)-1], "_") - - // Look for array/slice field with this base name - if cachedValue, exists := p.fieldCache[baseVar]; exists { - return p.getArrayElementSafe(cachedValue, index) - } - - // Check current struct for array field - if p.currentStruct.IsValid() { - if field := p.currentStruct.FieldByName(baseVar); field.IsValid() { - return p.getArrayElementSafe(field.Interface(), index) - } - } - - // Check struct stack - for i := len(p.structStack) - 1; i >= 0; i-- { - if field := p.structStack[i].FieldByName(baseVar); field.IsValid() { - return p.getArrayElementSafe(field.Interface(), index) - } - } - } - - return nil, false -} - -// getArrayElementSafe safely extracts element from array/slice with bounds checking -func (p *Parser) getArrayElementSafe(value any, index int) (any, bool) { - val := reflect.ValueOf(value) - - switch val.Kind() { - case reflect.Slice, reflect.Array: - if index >= 0 && index < val.Len() { - return val.Index(index).Interface(), true - } - } - - return nil, false -} - -// convertValue converts string to appropriate type for comparison with enhanced string support -func (p *Parser) convertValue(valueStr string, reference any) (any, error) { - switch reference.(type) { - case uint8, int8: - if val, err := strconv.ParseInt(valueStr, 0, 8); err == nil { - return uint8(val), nil - } - case uint16, int16: - if val, err := strconv.ParseInt(valueStr, 0, 16); err == nil { - return uint16(val), nil - } - case uint32, int32: - if val, err := strconv.ParseInt(valueStr, 0, 32); err == nil { - return uint32(val), nil - } - case uint64, int64: - if val, err := strconv.ParseInt(valueStr, 0, 64); err == nil { - return uint64(val), nil - } - case float32: - if val, err := strconv.ParseFloat(valueStr, 32); err == nil { - return float32(val), nil - } - case float64: - if val, err := strconv.ParseFloat(valueStr, 64); err == nil { - return val, nil - } - case string: - return valueStr, nil - } - - // Handle struct types with Data field (EQ2String types) - if reflect.TypeOf(reference).Kind() == reflect.Struct { - refVal := reflect.ValueOf(reference) - if dataField := refVal.FieldByName("Data"); dataField.IsValid() && dataField.Kind() == reflect.String { - return valueStr, nil - } - } - - if val, err := strconv.ParseInt(valueStr, 0, 32); err == nil { - return int(val), nil - } - - return valueStr, nil -} - -// compareValues performs comparison between two values with enhanced string support -func (p *Parser) compareValues(a, b any, op string) bool { - // Handle string comparisons first - if p.isStringValue(a) && p.isStringValue(b) { - aStr := p.extractStringValue(a) - bStr := p.extractStringValue(b) - return p.compareStrings(aStr, bStr, op) - } - - // Fall back to numeric comparison - aVal := p.valueToInt64(a) - bVal := p.valueToInt64(b) - - switch op { - case "==": - return aVal == bVal - case "!=": - return aVal != bVal - case ">": - return aVal > bVal - case ">=": - return aVal >= bVal - case "<": - return aVal < bVal - case "<=": - return aVal <= bVal - case "&": - return (aVal & bVal) != 0 - case "|": - return (aVal | bVal) != 0 - } - - return false -} - -// isStringValue checks if a value is or contains a string -func (p *Parser) isStringValue(value any) bool { - switch value.(type) { - case string: - return true - default: - if reflect.TypeOf(value).Kind() == reflect.Struct { - val := reflect.ValueOf(value) - if dataField := val.FieldByName("Data"); dataField.IsValid() && dataField.Kind() == reflect.String { - return true - } - } - return false - } -} - -// extractStringValue extracts string from value or struct Data field -func (p *Parser) extractStringValue(value any) string { - switch v := value.(type) { - case string: - return v - default: - if reflect.TypeOf(value).Kind() == reflect.Struct { - val := reflect.ValueOf(value) - if dataField := val.FieldByName("Data"); dataField.IsValid() && dataField.Kind() == reflect.String { - return dataField.String() - } - } - return "" - } -} - -// compareStrings performs string comparison operations -func (p *Parser) compareStrings(a, b, op string) bool { - switch op { - case "==": - return a == b - case "!=": - return a != b - case ">": - return a > b - case ">=": - return a >= b - case "<": - return a < b - case "<=": - return a <= b - default: - return false - } -} - -// valueToInt converts various types to int with enhanced type support -func (p *Parser) valueToInt(v any) int { - switch val := v.(type) { - case uint8: - return int(val) - case int8: - return int(val) - case uint16: - return int(val) - case int16: - return int(val) - case uint32: - return int(val) - case int32: - return int(val) - case uint64: - return int(val) - case int64: - return int(val) - case int: - return val - case bool: - if val { - return 1 - } - return 0 - default: - // Handle struct types that might have numeric fields - if reflect.TypeOf(v).Kind() == reflect.Struct { - refVal := reflect.ValueOf(v) - // Try common numeric field names - for _, fieldName := range []string{"Value", "Size", "Length", "Count"} { - if field := refVal.FieldByName(fieldName); field.IsValid() { - return p.valueToInt(field.Interface()) - } - } - } - } - return 0 -} - -// valueToInt64 converts various types to int64 for comparison with enhanced support -func (p *Parser) valueToInt64(v any) int64 { - switch val := v.(type) { - case uint8: - return int64(val) - case int8: - return int64(val) - case uint16: - return int64(val) - case int16: - return int64(val) - case uint32: - return int64(val) - case int32: - return int64(val) - case uint64: - return int64(val) - case int64: - return val - case int: - return int64(val) - case float32: - return int64(val) - case float64: - return int64(val) - case bool: - if val { - return 1 - } - return 0 - default: - // Handle struct types that might have numeric fields - if reflect.TypeOf(v).Kind() == reflect.Struct { - refVal := reflect.ValueOf(v) - // Try common numeric field names - for _, fieldName := range []string{"Value", "Size", "Length", "Count"} { - if field := refVal.FieldByName(fieldName); field.IsValid() { - return p.valueToInt64(field.Interface()) - } - } - } - } - return 0 -} - -// isTruthy checks if a value is truthy with enhanced type support -func (p *Parser) isTruthy(v any) bool { - switch val := v.(type) { - case bool: - return val - case uint8, int8, uint16, int16, uint32, int32, uint64, int64, int: - return p.valueToInt64(val) != 0 - case string: - return val != "" - default: - // Handle struct types - if reflect.TypeOf(v).Kind() == reflect.Struct { - refVal := reflect.ValueOf(v) - // Check for Data field (string types) - if dataField := refVal.FieldByName("Data"); dataField.IsValid() && dataField.Kind() == reflect.String { - return dataField.String() != "" - } - // Check for numeric fields - for _, fieldName := range []string{"Value", "Size", "Length", "Count"} { - if field := refVal.FieldByName(fieldName); field.IsValid() { - return p.valueToInt64(field.Interface()) != 0 - } - } - } - } - return false -} - -// handleOversizedField handles fields that exceed their oversized value -func (p *Parser) handleOversizedField(field reflect.Value, oversizedByte byte, length int) error { - if field.Kind() == reflect.Slice { - slice := reflect.MakeSlice(field.Type(), 1, 1) - if slice.Len() > 0 { - elem := slice.Index(0) - if elem.CanSet() { - switch elem.Kind() { - case reflect.Uint8: - elem.SetUint(uint64(oversizedByte)) - case reflect.Int8: - elem.SetInt(int64(int8(oversizedByte))) - default: - elem.SetUint(uint64(oversizedByte)) - } - } - } - field.Set(slice) - } else { - switch field.Kind() { - case reflect.Uint8: - field.SetUint(uint64(oversizedByte)) - case reflect.Int8: - field.SetInt(int64(int8(oversizedByte))) - default: - field.SetUint(uint64(oversizedByte)) - } - } - - return nil -} diff --git a/internal/packets/parser/parser.go b/internal/packets/parser/parser.go deleted file mode 100644 index 3580703..0000000 --- a/internal/packets/parser/parser.go +++ /dev/null @@ -1,243 +0,0 @@ -package parser - -import ( - "encoding/binary" - "fmt" - "io" - "reflect" - "unsafe" -) - -// Parser handles reading EQ2 packet data into structs -type Parser struct { - data []byte - offset int - endian binary.ByteOrder - fieldCache map[string]any - currentStruct reflect.Value - flags map[string]bool - structStack []reflect.Value - arrayStack []ArrayContext -} - -// ArrayContext tracks array parsing state -type ArrayContext struct { - elementType reflect.Type - currentIndex int - totalSize int - sizeVariable string -} - -// NewParser creates a new EQ2 packet parser -func NewParser(data []byte) *Parser { - return &Parser{ - data: data, - offset: 0, - endian: binary.LittleEndian, - fieldCache: make(map[string]any), - flags: make(map[string]bool), - structStack: make([]reflect.Value, 0), - arrayStack: make([]ArrayContext, 0), - } -} - -// SetFlag sets a flag for conditional parsing -func (p *Parser) SetFlag(name string, value bool) { - p.flags[name] = value -} - -// ParseStruct reads data into a struct using reflection and tags -func (p *Parser) ParseStruct(v any) error { - val := reflect.ValueOf(v) - if val.Kind() != reflect.Ptr || val.Elem().Kind() != reflect.Struct { - return fmt.Errorf("target must be pointer to struct") - } - - elem := val.Elem() - typ := elem.Type() - p.currentStruct = elem - p.fieldCache = make(map[string]any) - - for i := 0; i < elem.NumField(); i++ { - field := elem.Field(i) - fieldType := typ.Field(i) - - if !field.CanSet() { - continue - } - - tag := fieldType.Tag.Get("eq2") - if tag == "" || tag == "-" { - continue - } - - if err := p.parseField(field, tag); err != nil { - return fmt.Errorf("field %s: %w", fieldType.Name, err) - } - - if field.CanInterface() { - p.fieldCache[fieldType.Name] = field.Interface() - } - } - - return nil -} - -// parseField processes individual struct fields based on their tags -func (p *Parser) parseField(field reflect.Value, tag string) error { - fieldTag := p.parseFieldTag(tag) - - if !p.evaluateAllConditions(fieldTag, field) { - return nil - } - - length := fieldTag.Length - if fieldTag.DynamicLen != "" { - if dynLen := p.getDynamicLength(fieldTag.DynamicLen); dynLen > 0 { - length = dynLen - if fieldTag.MaxSize > 0 && length > fieldTag.MaxSize { - if fieldTag.SkipOversized { - length = fieldTag.MaxSize - } else { - return fmt.Errorf("length %d exceeds maximum %d", length, fieldTag.MaxSize) - } - } - } - } - - if fieldTag.OversizedValue > 0 && length > fieldTag.OversizedValue { - if fieldTag.SkipOversized { - length = fieldTag.OversizedValue - } else { - return p.handleOversizedField(field, fieldTag.OversizedByte, length) - } - } - - actualType := fieldTag.Type - if fieldTag.Type2 != "" && fieldTag.Type2Criteria != "" { - if p.evaluateType2Criteria(fieldTag.Type2Criteria) { - actualType = fieldTag.Type2 - } - } - - return p.parseFieldByType(field, actualType, length, fieldTag) -} - -// parseFieldByType handles type-specific parsing -func (p *Parser) parseFieldByType(field reflect.Value, fieldType string, length int, fieldTag *FieldTag) error { - switch fieldType { - case "int8": - return p.readInt8(field, length) - case "int16": - return p.readInt16(field, length) - case "int32": - return p.readInt32(field, length) - case "int64": - return p.readInt64(field, length) - case "sint8": - return p.readSInt8(field, length) - case "sint16": - return p.readSInt16(field, length) - case "sint32": - return p.readSInt32(field, length) - case "sint64": - return p.readSInt64(field, length) - case "char": - return p.readChar(field, length) - case "float": - return p.readFloat(field, length) - case "double": - return p.readDouble(field, length) - case "string8", "EQ2_8BitString", "EQ2_8Bit_String": - return p.readString8(field) - case "string16", "EQ2_16BitString", "EQ2_16Bit_String": - return p.readString16(field) - case "string32", "EQ2_32BitString", "EQ2_32Bit_String": - return p.readString32(field) - case "color", "EQ2_Color": - return p.readColor(field, length) - case "equipment", "EQ2_EquipmentItem": - return p.readEquipment(field, length) - case "array": - return p.readArray(field, fieldTag) - case "substruct": - return p.readSubstruct(field, length) - default: - return fmt.Errorf("unknown type: %s", fieldType) - } -} - -// Low-level read methods -func (p *Parser) readUint8() (uint8, error) { - if p.offset >= len(p.data) { - return 0, io.EOF - } - val := p.data[p.offset] - p.offset++ - return val, nil -} - -func (p *Parser) readUint16() (uint16, error) { - if p.offset+2 > len(p.data) { - return 0, io.EOF - } - val := p.endian.Uint16(p.data[p.offset:]) - p.offset += 2 - return val, nil -} - -func (p *Parser) readUint32() (uint32, error) { - if p.offset+4 > len(p.data) { - return 0, io.EOF - } - val := p.endian.Uint32(p.data[p.offset:]) - p.offset += 4 - return val, nil -} - -func (p *Parser) readUint64() (uint64, error) { - if p.offset+8 > len(p.data) { - return 0, io.EOF - } - val := p.endian.Uint64(p.data[p.offset:]) - p.offset += 8 - return val, nil -} - -func (p *Parser) readFloat32() (float32, error) { - val, err := p.readUint32() - if err != nil { - return 0, err - } - return *(*float32)(unsafe.Pointer(&val)), nil -} - -func (p *Parser) readFloat64() (float64, error) { - val, err := p.readUint64() - if err != nil { - return 0, err - } - return *(*float64)(unsafe.Pointer(&val)), nil -} - -func (p *Parser) readBytes(buf []byte) error { - if p.offset+len(buf) > len(p.data) { - return io.EOF - } - copy(buf, p.data[p.offset:]) - p.offset += len(buf) - return nil -} - -// Position tracking -func (p *Parser) Offset() int { - return p.offset -} - -func (p *Parser) SetOffset(offset int) { - p.offset = offset -} - -func (p *Parser) Remaining() int { - return len(p.data) - p.offset -} diff --git a/internal/packets/parser/parser_test.go b/internal/packets/parser/parser_test.go deleted file mode 100644 index 2d2f854..0000000 --- a/internal/packets/parser/parser_test.go +++ /dev/null @@ -1,424 +0,0 @@ -package parser - -import ( - "eq2emu/internal/common" - "reflect" - "testing" -) - -type BasicPacket struct { - Channel uint8 `eq2:"int8"` - Count uint16 `eq2:"int16"` - MessageType uint8 `eq2:"int8,if=Channel==1"` -} - -type ArrayPacket struct { - ItemCount uint16 `eq2:"int16"` - Items []ItemDescription `eq2:"array,arraysize=ItemCount"` -} - -type ItemDescription struct { - InfoHeader WS_ExamineInfoHeader `eq2:"substruct"` - Info BaseItemDescription `eq2:"substruct"` - ItemType uint8 `eq2:"int8"` -} - -type WS_ExamineInfoHeader struct { - Unknown1 uint32 `eq2:"int32"` - Unknown2 uint16 `eq2:"int16"` -} - -type BaseItemDescription struct { - Name common.EQ2String16 `eq2:"string16"` - Category common.EQ2String8 `eq2:"string8"` -} - -type ConditionalPacket struct { - HasRewards uint8 `eq2:"int8"` - RewardData *RewardInfo `eq2:"substruct,ifvariableset=HasRewards"` - CompleteFlag uint8 `eq2:"int8"` - ClassicSound uint8 `eq2:"int8,ifvariableset=CompleteFlag"` -} - -type RewardInfo struct { - RewardType uint8 `eq2:"int8"` - Amount uint32 `eq2:"int32"` -} - -type OversizedPacket struct { - LargeDataCount uint16 `eq2:"int16"` - LargeData []byte `eq2:"char,len=LargeDataCount,maxsize=10,skipoversized"` -} - -type TypeSwitchPacket struct { - StatType uint8 `eq2:"int8"` - StatValue any `eq2:"int32,type2=float,type2criteria=StatType!=6"` -} - -type FlagPacket struct { - Equipment []common.EQ2EquipmentItem `eq2:"equipment,len=2,ifflag=has_equipment"` - Colors []common.EQ2Color `eq2:"color,len=3,ifflagnotset=no_colors"` -} - -type ComplexPacket struct { - GroupCount uint8 `eq2:"int8"` - Groups []Group `eq2:"array,arraysize=GroupCount"` -} - -type Group struct { - MemberCount uint16 `eq2:"int16"` - Members []Member `eq2:"array,arraysize=MemberCount"` -} - -type Member struct { - Name common.EQ2String16 `eq2:"string16"` - Level uint8 `eq2:"int8"` - Class uint8 `eq2:"int8"` -} - -// Version-specific structs -type PacketV1 struct { - Field1 uint8 `eq2:"int8"` - Field2 uint16 `eq2:"int16"` -} - -type PacketV2 struct { - Field1 uint8 `eq2:"int8"` - Field2 uint16 `eq2:"int16"` - NewField uint32 `eq2:"int32"` -} - -func TestBasicParsing(t *testing.T) { - // Basic packet: Channel=1, Count=100, MessageType=5 - data := []byte{0x01, 0x64, 0x00, 0x05} - parser := NewParser(data) - - var packet BasicPacket - err := parser.ParseStruct(&packet) - if err != nil { - t.Fatalf("Parse error: %v", err) - } - - if packet.Channel != 1 { - t.Errorf("Expected Channel=1, got %d", packet.Channel) - } - if packet.Count != 100 { - t.Errorf("Expected Count=100, got %d", packet.Count) - } - if packet.MessageType != 5 { - t.Errorf("Expected MessageType=5, got %d", packet.MessageType) - } -} - -func TestConditionalSkip(t *testing.T) { - // Channel=2 (not 1), so MessageType should be skipped - data := []byte{0x02, 0x64, 0x00} - parser := NewParser(data) - - var packet BasicPacket - err := parser.ParseStruct(&packet) - if err != nil { - t.Fatalf("Parse error: %v", err) - } - - if packet.Channel != 2 { - t.Errorf("Expected Channel=2, got %d", packet.Channel) - } - if packet.MessageType != 0 { - t.Errorf("Expected MessageType=0 (skipped), got %d", packet.MessageType) - } -} - -func TestArrayParsing(t *testing.T) { - // ItemCount=2, then 2 items - data := []byte{ - 0x02, 0x00, // ItemCount = 2 - // Item 1 - 0x01, 0x00, 0x00, 0x00, // InfoHeader.Unknown1 = 1 - 0x02, 0x00, // InfoHeader.Unknown2 = 2 - 0x04, 0x00, 't', 'e', 's', 't', // Name: "test" - 0x03, 'c', 'a', 't', // Category: "cat" - 0x05, // ItemType = 5 - // Item 2 - 0x03, 0x00, 0x00, 0x00, // InfoHeader.Unknown1 = 3 - 0x04, 0x00, // InfoHeader.Unknown2 = 4 - 0x05, 0x00, 'i', 't', 'e', 'm', '2', // Name: "item2" - 0x04, 't', 'y', 'p', 'e', // Category: "type" - 0x06, // ItemType = 6 - } - - parser := NewParser(data) - var packet ArrayPacket - err := parser.ParseStruct(&packet) - if err != nil { - t.Fatalf("Parse error: %v", err) - } - - if packet.ItemCount != 2 { - t.Errorf("Expected ItemCount=2, got %d", packet.ItemCount) - } - if len(packet.Items) != 2 { - t.Errorf("Expected 2 items, got %d", len(packet.Items)) - } - - if packet.Items[0].Info.Name.Data != "test" { - t.Errorf("Expected first item name 'test', got '%s'", packet.Items[0].Info.Name.Data) - } - if packet.Items[1].ItemType != 6 { - t.Errorf("Expected second item type 6, got %d", packet.Items[1].ItemType) - } -} - -func TestConditionalFields(t *testing.T) { - // HasRewards=1, RewardData present, CompleteFlag=1, ClassicSound present - data := []byte{ - 0x01, // HasRewards = 1 - 0x02, // RewardType = 2 - 0x64, 0x00, 0x00, 0x00, // Amount = 100 - 0x01, // CompleteFlag = 1 - 0x05, // ClassicSound = 5 - } - - parser := NewParser(data) - var packet ConditionalPacket - err := parser.ParseStruct(&packet) - if err != nil { - t.Fatalf("Parse error: %v", err) - } - - if packet.HasRewards != 1 { - t.Errorf("Expected HasRewards=1, got %d", packet.HasRewards) - } - if packet.RewardData == nil { - t.Error("Expected RewardData to be present") - } else { - if packet.RewardData.RewardType != 2 { - t.Errorf("Expected RewardType=2, got %d", packet.RewardData.RewardType) - } - if packet.RewardData.Amount != 100 { - t.Errorf("Expected Amount=100, got %d", packet.RewardData.Amount) - } - } - if packet.ClassicSound != 5 { - t.Errorf("Expected ClassicSound=5, got %d", packet.ClassicSound) - } -} - -func TestOversizedHandling(t *testing.T) { - // LargeDataCount=15 (exceeds maxsize=10), should be truncated - data := []byte{ - 0x0F, 0x00, // LargeDataCount = 15 - 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, - 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, // 15 bytes of data - } - - parser := NewParser(data) - var packet OversizedPacket - err := parser.ParseStruct(&packet) - if err != nil { - t.Fatalf("Parse error: %v", err) - } - - if packet.LargeDataCount != 15 { - t.Errorf("Expected LargeDataCount=15, got %d", packet.LargeDataCount) - } - if len(packet.LargeData) != 10 { - t.Errorf("Expected LargeData length=10 (truncated), got %d", len(packet.LargeData)) - } -} - -func TestTypeSwitching(t *testing.T) { - // StatType=3 (not 6), so StatValue should be parsed as float - data := []byte{ - 0x03, // StatType = 3 - 0x00, 0x00, 0x80, 0x3F, // float32: 1.0 - } - - parser := NewParser(data) - var packet TypeSwitchPacket - err := parser.ParseStruct(&packet) - if err != nil { - t.Fatalf("Parse error: %v", err) - } - - if packet.StatType != 3 { - t.Errorf("Expected StatType=3, got %d", packet.StatType) - } - - // Should be parsed as float32 since StatType != 6 - floatVal, ok := packet.StatValue.(float32) - if !ok { - t.Errorf("Expected StatValue to be float32, got %T", packet.StatValue) - } else if floatVal != 1.0 { - t.Errorf("Expected StatValue=1.0, got %f", floatVal) - } -} - -func TestFlagBasedConditionals(t *testing.T) { - // Equipment data (2 items) - data := []byte{ - // Equipment item 1 - 0x01, 0x00, // Type = 1 - 0xFF, 0x00, 0x00, // Color: Red=255, Green=0, Blue=0 - 0x00, 0xFF, 0x00, // Highlight: Red=0, Green=255, Blue=0 - // Equipment item 2 - 0x02, 0x00, // Type = 2 - 0x00, 0x00, 0xFF, // Color: Red=0, Green=0, Blue=255 - 0xFF, 0xFF, 0x00, // Highlight: Red=255, Green=255, Blue=0 - // Colors (3 items) - 0x80, 0x80, 0x80, // Color 1: Gray - 0x40, 0x40, 0x40, // Color 2: Dark gray - 0xC0, 0xC0, 0xC0, // Color 3: Light gray - } - - parser := NewParser(data) - parser.SetFlag("has_equipment", true) - // no_colors flag is not set, so colors should be parsed - - var packet FlagPacket - err := parser.ParseStruct(&packet) - if err != nil { - t.Fatalf("Parse error: %v", err) - } - - if len(packet.Equipment) != 2 { - t.Errorf("Expected 2 equipment items, got %d", len(packet.Equipment)) - } - if len(packet.Colors) != 3 { - t.Errorf("Expected 3 colors, got %d", len(packet.Colors)) - } - - if packet.Equipment[0].Type != 1 { - t.Errorf("Expected first equipment type 1, got %d", packet.Equipment[0].Type) - } - if packet.Colors[0].Red != 0x80 { - t.Errorf("Expected first color red=128, got %d", packet.Colors[0].Red) - } -} - -func TestComplexNestedArrays(t *testing.T) { - // GroupCount=1, Group has MemberCount=2 - data := []byte{ - 0x01, // GroupCount = 1 - 0x02, 0x00, // MemberCount = 2 - // Member 1 - 0x05, 0x00, 'A', 'l', 'i', 'c', 'e', // Name: "Alice" - 0x0A, // Level = 10 - 0x01, // Class = 1 - // Member 2 - 0x03, 0x00, 'B', 'o', 'b', // Name: "Bob" - 0x0F, // Level = 15 - 0x02, // Class = 2 - } - - parser := NewParser(data) - var packet ComplexPacket - err := parser.ParseStruct(&packet) - if err != nil { - t.Fatalf("Parse error: %v", err) - } - - if packet.GroupCount != 1 { - t.Errorf("Expected GroupCount=1, got %d", packet.GroupCount) - } - if len(packet.Groups) != 1 { - t.Errorf("Expected 1 group, got %d", len(packet.Groups)) - } - if len(packet.Groups[0].Members) != 2 { - t.Errorf("Expected 2 members, got %d", len(packet.Groups[0].Members)) - } - - if packet.Groups[0].Members[0].Name.Data != "Alice" { - t.Errorf("Expected first member 'Alice', got '%s'", packet.Groups[0].Members[0].Name.Data) - } - if packet.Groups[0].Members[1].Level != 15 { - t.Errorf("Expected second member level 15, got %d", packet.Groups[0].Members[1].Level) - } -} - -func TestVersionRegistry(t *testing.T) { - registry := NewVersionRegistry() - - // Register different versions - registry.RegisterStruct("TestPacket", "1.0", reflect.TypeOf(PacketV1{})) - registry.RegisterStruct("TestPacket", "2.0", reflect.TypeOf(PacketV2{})) - - // Test version 1.0 - data1 := []byte{0x01, 0x64, 0x00} // Field1=1, Field2=100 - parser1 := NewParser(data1) - - result1, err := parser1.ParseWithVersion(registry, "TestPacket", "1.0") - if err != nil { - t.Fatalf("Parse v1.0 error: %v", err) - } - - v1Packet, ok := result1.(PacketV1) - if !ok { - t.Fatal("Expected PacketV1 type") - } - if v1Packet.Field1 != 1 || v1Packet.Field2 != 100 { - t.Errorf("V1 packet values incorrect: Field1=%d, Field2=%d", v1Packet.Field1, v1Packet.Field2) - } - - // Test version 2.0 - data2 := []byte{0x02, 0xC8, 0x00, 0x90, 0x01, 0x00, 0x00} // Field1=2, Field2=200, NewField=400 - parser2 := NewParser(data2) - - result2, err := parser2.ParseWithVersion(registry, "TestPacket", "2.0") - if err != nil { - t.Fatalf("Parse v2.0 error: %v", err) - } - - v2Packet, ok := result2.(PacketV2) - if !ok { - t.Fatal("Expected PacketV2 type") - } - if v2Packet.Field1 != 2 || v2Packet.Field2 != 200 || v2Packet.NewField != 400 { - t.Errorf("V2 packet values incorrect: Field1=%d, Field2=%d, NewField=%d", - v2Packet.Field1, v2Packet.Field2, v2Packet.NewField) - } -} - -func TestVersionFallback(t *testing.T) { - registry := NewVersionRegistry() - registry.RegisterStruct("TestPacket", "1.0", reflect.TypeOf(PacketV1{})) - registry.RegisterStruct("TestPacket", "2.0", reflect.TypeOf(PacketV2{})) - - // Request version 1.5 (doesn't exist), should fall back to 1.0 - data := []byte{0x01, 0x64, 0x00} - parser := NewParser(data) - - result, err := parser.ParseWithVersion(registry, "TestPacket", "1.5") - if err != nil { - t.Fatalf("Parse with fallback error: %v", err) - } - - // Should get v1.0 (nearest lower version) - _, ok := result.(PacketV1) - if !ok { - t.Error("Expected fallback to PacketV1") - } -} - -func TestParserPosition(t *testing.T) { - data := []byte{0x01, 0x02, 0x03, 0x04} - parser := NewParser(data) - - if parser.Offset() != 0 { - t.Errorf("Initial offset should be 0, got %d", parser.Offset()) - } - - parser.readUint8() // Read one byte - if parser.Offset() != 1 { - t.Errorf("After reading 1 byte, offset should be 1, got %d", parser.Offset()) - } - - if parser.Remaining() != 3 { - t.Errorf("After reading 1 byte, remaining should be 3, got %d", parser.Remaining()) - } - - parser.SetOffset(2) - if parser.Offset() != 2 { - t.Errorf("After SetOffset(2), offset should be 2, got %d", parser.Offset()) - } -} diff --git a/internal/packets/parser/type_readers.go b/internal/packets/parser/type_readers.go deleted file mode 100644 index ba3f92f..0000000 --- a/internal/packets/parser/type_readers.go +++ /dev/null @@ -1,434 +0,0 @@ -package parser - -import ( - "eq2emu/internal/common" - "reflect" -) - -func (p *Parser) readInt8(field reflect.Value, length int) error { - if length == 1 { - val, err := p.readUint8() - if err != nil { - return err - } - field.SetUint(uint64(val)) - return nil - } - - slice := make([]uint8, length) - for i := range length { - val, err := p.readUint8() - if err != nil { - return err - } - slice[i] = val - } - field.Set(reflect.ValueOf(slice)) - return nil -} - -func (p *Parser) readInt16(field reflect.Value, length int) error { - if length == 1 { - val, err := p.readUint16() - if err != nil { - return err - } - field.SetUint(uint64(val)) - return nil - } - - slice := make([]uint16, length) - for i := range length { - val, err := p.readUint16() - if err != nil { - return err - } - slice[i] = val - } - field.Set(reflect.ValueOf(slice)) - return nil -} - -func (p *Parser) readInt32(field reflect.Value, length int) error { - if length == 1 { - val, err := p.readUint32() - if err != nil { - return err - } - - // Handle interface{} fields - if field.Kind() == reflect.Interface { - field.Set(reflect.ValueOf(val)) - } else { - field.SetUint(uint64(val)) - } - return nil - } - - slice := make([]uint32, length) - for i := range length { - val, err := p.readUint32() - if err != nil { - return err - } - slice[i] = val - } - field.Set(reflect.ValueOf(slice)) - return nil -} - -func (p *Parser) readInt64(field reflect.Value, length int) error { - if length == 1 { - val, err := p.readUint64() - if err != nil { - return err - } - field.SetUint(val) - return nil - } - - slice := make([]uint64, length) - for i := range length { - val, err := p.readUint64() - if err != nil { - return err - } - slice[i] = val - } - field.Set(reflect.ValueOf(slice)) - return nil -} - -func (p *Parser) readSInt8(field reflect.Value, length int) error { - if length == 1 { - val, err := p.readUint8() - if err != nil { - return err - } - field.SetInt(int64(int8(val))) - return nil - } - - slice := make([]int8, length) - for i := range length { - val, err := p.readUint8() - if err != nil { - return err - } - slice[i] = int8(val) - } - field.Set(reflect.ValueOf(slice)) - return nil -} - -func (p *Parser) readSInt16(field reflect.Value, length int) error { - if length == 1 { - val, err := p.readUint16() - if err != nil { - return err - } - field.SetInt(int64(int16(val))) - return nil - } - - slice := make([]int16, length) - for i := range length { - val, err := p.readUint16() - if err != nil { - return err - } - slice[i] = int16(val) - } - field.Set(reflect.ValueOf(slice)) - return nil -} - -func (p *Parser) readSInt32(field reflect.Value, length int) error { - if length == 1 { - val, err := p.readUint32() - if err != nil { - return err - } - field.SetInt(int64(int32(val))) - return nil - } - - slice := make([]int32, length) - for i := range length { - val, err := p.readUint32() - if err != nil { - return err - } - slice[i] = int32(val) - } - field.Set(reflect.ValueOf(slice)) - return nil -} - -func (p *Parser) readSInt64(field reflect.Value, length int) error { - if length == 1 { - val, err := p.readUint64() - if err != nil { - return err - } - field.SetInt(int64(val)) - return nil - } - - slice := make([]int64, length) - for i := 0; i < length; i++ { - val, err := p.readUint64() - if err != nil { - return err - } - slice[i] = int64(val) - } - field.Set(reflect.ValueOf(slice)) - return nil -} - -func (p *Parser) readChar(field reflect.Value, length int) error { - if length == 1 { - val, err := p.readUint8() - if err != nil { - return err - } - field.SetUint(uint64(val)) - return nil - } - - slice := make([]byte, length) - err := p.readBytes(slice) - if err != nil { - return err - } - field.SetBytes(slice) - return nil -} - -func (p *Parser) readFloat(field reflect.Value, length int) error { - if length == 1 { - val, err := p.readFloat32() - if err != nil { - return err - } - - // Handle interface{} fields - if field.Kind() == reflect.Interface { - field.Set(reflect.ValueOf(val)) - } else { - field.SetFloat(float64(val)) - } - return nil - } - - slice := make([]float32, length) - for i := range length { - val, err := p.readFloat32() - if err != nil { - return err - } - slice[i] = val - } - field.Set(reflect.ValueOf(slice)) - return nil -} - -func (p *Parser) readDouble(field reflect.Value, length int) error { - if length == 1 { - val, err := p.readFloat64() - if err != nil { - return err - } - field.SetFloat(val) - return nil - } - - slice := make([]float64, length) - for i := range length { - val, err := p.readFloat64() - if err != nil { - return err - } - slice[i] = val - } - field.Set(reflect.ValueOf(slice)) - return nil -} - -func (p *Parser) readString8(field reflect.Value) error { - size, err := p.readUint8() - if err != nil { - return err - } - - data := make([]byte, size) - err = p.readBytes(data) - if err != nil { - return err - } - - str8 := common.EQ2String8{ - Size: size, - Data: string(data), - } - field.Set(reflect.ValueOf(str8)) - return nil -} - -func (p *Parser) readString16(field reflect.Value) error { - size, err := p.readUint16() - if err != nil { - return err - } - - data := make([]byte, size) - err = p.readBytes(data) - if err != nil { - return err - } - - str16 := common.EQ2String16{ - Size: size, - Data: string(data), - } - field.Set(reflect.ValueOf(str16)) - return nil -} - -func (p *Parser) readString32(field reflect.Value) error { - size, err := p.readUint32() - if err != nil { - return err - } - - data := make([]byte, size) - err = p.readBytes(data) - if err != nil { - return err - } - - str32 := common.EQ2String32{ - Size: size, - Data: string(data), - } - field.Set(reflect.ValueOf(str32)) - return nil -} - -func (p *Parser) readColor(field reflect.Value, length int) error { - if length == 1 { - color := common.EQ2Color{} - var err error - color.Red, err = p.readUint8() - if err != nil { - return err - } - color.Green, err = p.readUint8() - if err != nil { - return err - } - color.Blue, err = p.readUint8() - if err != nil { - return err - } - field.Set(reflect.ValueOf(color)) - return nil - } - - slice := make([]common.EQ2Color, length) - for i := range length { - var err error - slice[i].Red, err = p.readUint8() - if err != nil { - return err - } - slice[i].Green, err = p.readUint8() - if err != nil { - return err - } - slice[i].Blue, err = p.readUint8() - if err != nil { - return err - } - } - field.Set(reflect.ValueOf(slice)) - return nil -} - -func (p *Parser) readEquipment(field reflect.Value, length int) error { - if length == 1 { - equipment := common.EQ2EquipmentItem{} - var err error - equipment.Type, err = p.readUint16() - if err != nil { - return err - } - - equipment.Color.Red, err = p.readUint8() - if err != nil { - return err - } - equipment.Color.Green, err = p.readUint8() - if err != nil { - return err - } - equipment.Color.Blue, err = p.readUint8() - if err != nil { - return err - } - - equipment.Highlight.Red, err = p.readUint8() - if err != nil { - return err - } - equipment.Highlight.Green, err = p.readUint8() - if err != nil { - return err - } - equipment.Highlight.Blue, err = p.readUint8() - if err != nil { - return err - } - - field.Set(reflect.ValueOf(equipment)) - return nil - } - - slice := make([]common.EQ2EquipmentItem, length) - for i := range length { - var err error - slice[i].Type, err = p.readUint16() - if err != nil { - return err - } - - slice[i].Color.Red, err = p.readUint8() - if err != nil { - return err - } - slice[i].Color.Green, err = p.readUint8() - if err != nil { - return err - } - slice[i].Color.Blue, err = p.readUint8() - if err != nil { - return err - } - - slice[i].Highlight.Red, err = p.readUint8() - if err != nil { - return err - } - slice[i].Highlight.Green, err = p.readUint8() - if err != nil { - return err - } - slice[i].Highlight.Blue, err = p.readUint8() - if err != nil { - return err - } - } - field.Set(reflect.ValueOf(slice)) - return nil -} diff --git a/internal/packets/parser/version_registry.go b/internal/packets/parser/version_registry.go deleted file mode 100644 index 2a8759f..0000000 --- a/internal/packets/parser/version_registry.go +++ /dev/null @@ -1,71 +0,0 @@ -package parser - -import ( - "fmt" - "reflect" -) - -// VersionRegistry manages version-specific struct types -type VersionRegistry struct { - structs map[string]map[string]reflect.Type // [structName][version] = Type -} - -// NewVersionRegistry creates a new version registry -func NewVersionRegistry() *VersionRegistry { - return &VersionRegistry{ - structs: make(map[string]map[string]reflect.Type), - } -} - -// RegisterStruct registers a struct type for a specific version -func (vr *VersionRegistry) RegisterStruct(name, version string, structType reflect.Type) { - if vr.structs[name] == nil { - vr.structs[name] = make(map[string]reflect.Type) - } - vr.structs[name][version] = structType -} - -// GetStruct returns the appropriate struct type for a version -func (vr *VersionRegistry) GetStruct(name, version string) (reflect.Type, bool) { - if versions, exists := vr.structs[name]; exists { - if structType, exists := versions[version]; exists { - return structType, true - } - return vr.findNearestVersion(name, version) - } - return nil, false -} - -// findNearestVersion finds the closest version <= requested version -func (vr *VersionRegistry) findNearestVersion(name, targetVersion string) (reflect.Type, bool) { - versions := vr.structs[name] - var bestVersion string - var bestType reflect.Type - - for version, structType := range versions { - if version <= targetVersion && version > bestVersion { - bestVersion = version - bestType = structType - } - } - - return bestType, bestVersion != "" -} - -// ParseWithVersion parses using version-specific struct -func (p *Parser) ParseWithVersion(registry *VersionRegistry, structName, version string) (any, error) { - structType, exists := registry.GetStruct(structName, version) - if !exists { - return nil, fmt.Errorf("no struct found for %s version %s", structName, version) - } - - ptr := reflect.New(structType) - elem := ptr.Elem() - - err := p.ParseStruct(ptr.Interface()) - if err != nil { - return nil, err - } - - return elem.Interface(), nil -} diff --git a/internal/packets/substructs/AASpellInfo.go b/internal/packets/substructs/AASpellInfo.go deleted file mode 100644 index 3bbac32..0000000 --- a/internal/packets/substructs/AASpellInfo.go +++ /dev/null @@ -1,67 +0,0 @@ -package substructs - -import "eq2emu/internal/common" - -// AASpellInfo client version 1193 -type AASpellInfo struct { - ID uint32 `eq2:"int32"` - Icon uint16 `eq2:"int16"` - Icon2 uint16 `eq2:"int16"` - IconType uint16 `eq2:"int16"` - Version uint16 `eq2:"int16"` - SubVersion uint16 `eq2:"int16"` - Type uint8 `eq2:"int8"` - ClassSkill uint32 `eq2:"int32"` - MasterySkill uint32 `eq2:"int32"` - MinClassSkillReq uint16 `eq2:"int16,oversized=127,oversizedbyte=127"` - SpellTextColor uint32 `eq2:"int32"` - Unknown605MJ3 uint8 `eq2:"int8"` - Tier uint8 `eq2:"int8"` - HealthReq uint16 `eq2:"int16,oversized=127,oversizedbyte=127"` - HealthUpkeep uint16 `eq2:"int16,oversized=127,oversizedbyte=127"` - PowerReq uint16 `eq2:"int16,oversized=127,oversizedbyte=127"` - PowerUpkeep uint16 `eq2:"int16,oversized=127,oversizedbyte=127"` - ReqConcentration uint16 `eq2:"int16"` - Unknown uint16 `eq2:"int16"` - CastTime uint16 `eq2:"int16,oversized=127,oversizedbyte=127"` - Recovery uint16 `eq2:"int16,oversized=127,oversizedbyte=127"` - Recast float32 `eq2:"float"` - Radius float32 `eq2:"float"` - MaxAoeTargets uint16 `eq2:"int16"` - FriendlySpell uint8 `eq2:"int8"` - NumReagents uint8 `eq2:"int8"` - ReagentArray []AASpellReagent `eq2:"array,arraysize=NumReagents"` - NumEffects uint8 `eq2:"int8"` - EffectArray []AASpellEffect `eq2:"array,arraysize=NumEffects"` - DisplaySpellTier uint8 `eq2:"int8"` - Unknown1 uint8 `eq2:"int8"` - MinimumRange float32 `eq2:"float"` - Range float32 `eq2:"float"` - Duration1 uint32 `eq2:"int32"` - Duration2 uint32 `eq2:"int32"` - Unknown9 uint8 `eq2:"int8"` - DurationFlag uint8 `eq2:"int8"` - Target uint8 `eq2:"int8"` - CanEffectRaid uint8 `eq2:"int8"` - AffectOnlyGroupMembers uint8 `eq2:"int8"` - GroupSpell uint8 `eq2:"int8"` - Resistibility float32 `eq2:"float"` - Unknown11 []uint8 `eq2:"int8,len=7"` - HitBonus float32 `eq2:"float"` - Unknown12 uint8 `eq2:"int8"` - Name common.EQ2String8 `eq2:"string8"` - Description common.EQ2String16 `eq2:"string16"` - Unknown605MJ6 uint8 `eq2:"int8"` -} - -type AASpellReagent struct { - Reagent common.EQ2String8 `eq2:"string8"` - Consumed uint8 `eq2:"int8"` - QtyRequired uint32 `eq2:"int32"` -} - -type AASpellEffect struct { - SubBulletFlag uint8 `eq2:"int8"` - Effect common.EQ2String16 `eq2:"string16"` - Percentage uint8 `eq2:"int8"` -} diff --git a/internal/packets/substructs/BaseItemDescription.go b/internal/packets/substructs/BaseItemDescription.go deleted file mode 100644 index 02e5b00..0000000 --- a/internal/packets/substructs/BaseItemDescription.go +++ /dev/null @@ -1,304 +0,0 @@ -package substructs - -import "eq2emu/internal/common" - -// BaseItemDescription Version 1 -type BaseItemDescriptionV1 struct { - CreatorFlag uint8 `eq2:"int8"` - Creator common.EQ2String16 `eq2:"string16"` - UniqueID uint32 `eq2:"int32"` - Icon uint16 `eq2:"int16"` - FlagNames common.EQ2String8 `eq2:"string8"` - Unknown81 []uint8 `eq2:"int8,len=17"` - StatCount uint8 `eq2:"int8"` - StatArray []BaseItemStat `eq2:"array,arraysize=StatCount"` - StatStringCount uint8 `eq2:"int8"` - StatStringArray []BaseItemStatString `eq2:"array,arraysize=StatStringCount"` - Condition uint8 `eq2:"int8"` - Weight uint16 `eq2:"int16,oversized=127,oversizedbyte=127"` - SkillReq1 uint32 `eq2:"int32"` - SkillMin uint16 `eq2:"int16,oversized=127,oversizedbyte=127"` - SkillRecommended uint16 `eq2:"int16,oversized=127,oversizedbyte=127"` - SlotCount uint8 `eq2:"int8"` - SlotArray []uint8 `eq2:"array,arraysize=SlotCount"` -} - -// BaseItemDescription Version 373 -type BaseItemDescriptionV373 struct { - CreatorFlag uint8 `eq2:"int8"` - Creator common.EQ2String16 `eq2:"string16"` - UniqueID uint32 `eq2:"int32"` - Icon uint16 `eq2:"int16"` - Tier uint8 `eq2:"int8"` - FlagNames common.EQ2String8 `eq2:"string8"` - Unknown81 []uint8 `eq2:"int8,len=17"` - StatCount uint8 `eq2:"int8"` - StatArray []BaseItemStat `eq2:"array,arraysize=StatCount"` - StatStringCount uint8 `eq2:"int8"` - StatStringArray []BaseItemStatString `eq2:"array,arraysize=StatStringCount"` - Condition uint8 `eq2:"int8"` - Weight uint16 `eq2:"int16,oversized=127,oversizedbyte=127"` - SkillReq1 uint32 `eq2:"int32"` - SkillReq2 uint32 `eq2:"int32"` - SkillMin uint16 `eq2:"int16,oversized=127,oversizedbyte=127"` - SkillRecommended uint16 `eq2:"int16,oversized=127,oversizedbyte=127"` - SlotCount uint8 `eq2:"int8"` - SlotArray []uint8 `eq2:"array,arraysize=SlotCount"` -} - -// BaseItemDescription Version 546 -type BaseItemDescriptionV546 struct { - Creator common.EQ2String8 `eq2:"string8"` - UniqueID uint32 `eq2:"int32"` - BrokerItemID uint64 `eq2:"int64"` - Icon uint16 `eq2:"int16"` - Tier uint8 `eq2:"int8"` - Flags uint32 `eq2:"int32"` - Unknown81 []uint8 `eq2:"int8,len=15"` - StatCount uint8 `eq2:"int8"` - StatArray []BaseItemStatV546 `eq2:"array,arraysize=StatCount"` - StatStringCount uint8 `eq2:"int8"` - StatStringArray []BaseItemStatStringV546 `eq2:"array,arraysize=StatStringCount"` - Condition uint8 `eq2:"int8"` - Weight uint16 `eq2:"int16,oversized=127,oversizedbyte=127"` - SkillReq1 uint32 `eq2:"int32"` - SkillReq2 uint32 `eq2:"int32"` - SkillMin uint16 `eq2:"int16,oversized=127,oversizedbyte=127"` - ClassCount uint8 `eq2:"int8"` - ClassArray []BaseItemClass `eq2:"array,arraysize=ClassCount"` - SlotCount uint8 `eq2:"int8"` - SlotArray []uint8 `eq2:"array,arraysize=SlotCount"` - FooterType uint32 `eq2:"int32"` -} - -// BaseItemDescription Version 1096 -type BaseItemDescriptionV1096 struct { - CreatorFlag uint8 `eq2:"int8"` - Creator common.EQ2String8 `eq2:"string8"` - UniqueID uint32 `eq2:"int32"` - BrokerItemID uint64 `eq2:"int64"` - ItemID int32 `eq2:"sint32"` - ItemCRC int32 `eq2:"sint32"` - Icon uint16 `eq2:"int16"` - Tier uint8 `eq2:"int8"` - Flags uint16 `eq2:"int16"` - Flags2 uint16 `eq2:"int16"` - Unknown81096 []uint8 `eq2:"int8,len=17"` - StatCount uint8 `eq2:"int8"` - StatArray []BaseItemStatV1096 `eq2:"array,arraysize=StatCount"` - StatUnknown uint8 `eq2:"int8"` - StatStringCount uint8 `eq2:"int8"` - StatStringArray []BaseItemStatStringV1096 `eq2:"array,arraysize=StatStringCount"` - Unknown19 uint16 `eq2:"int16"` - Unknown20 uint16 `eq2:"int16"` - Condition uint8 `eq2:"int8"` - Weight uint32 `eq2:"int32"` - SkillReq1 uint32 `eq2:"int32"` - SkillReq2 uint32 `eq2:"int32"` - SkillMin uint16 `eq2:"int16,oversized=127,oversizedbyte=127"` - ClassCount uint8 `eq2:"int8"` - ClassArray []BaseItemClass `eq2:"array,arraysize=ClassCount"` - SlotCount uint8 `eq2:"int8"` - SlotArray []uint8 `eq2:"array,arraysize=SlotCount"` - FooterType uint32 `eq2:"int32"` -} - -// BaseItemDescription Version 1188 -type BaseItemDescriptionV1188 struct { - CreatorFlag uint8 `eq2:"int8"` - Creator common.EQ2String8 `eq2:"string8"` - UniqueID uint32 `eq2:"int32"` - BrokerItemID uint64 `eq2:"int64"` - ItemID int32 `eq2:"sint32"` - ItemCRC int32 `eq2:"sint32"` - Icon uint16 `eq2:"int16"` - Tier uint8 `eq2:"int8"` - Flags uint16 `eq2:"int16"` - Flags2 uint16 `eq2:"int16"` - Unknown81188 []uint8 `eq2:"int8,len=17"` - StatCount uint8 `eq2:"int8"` - StatArray []BaseItemStatV1188 `eq2:"array,arraysize=StatCount"` - StatUnknown uint8 `eq2:"int8"` - StatStringCount uint8 `eq2:"int8"` - StatStringArray []BaseItemStatStringV1188 `eq2:"array,arraysize=StatStringCount"` - Unknown19 uint16 `eq2:"int16"` - Unknown20 uint16 `eq2:"int16"` - Condition uint8 `eq2:"int8"` - Weight uint32 `eq2:"int32"` - SkillReq1 uint32 `eq2:"int32"` - SkillReq2 uint32 `eq2:"int32"` - SkillMin uint16 `eq2:"int16,oversized=127,oversizedbyte=127"` - ClassCount uint8 `eq2:"int8"` - ClassArray []BaseItemClass `eq2:"array,arraysize=ClassCount"` - SlotCount uint8 `eq2:"int8"` - SlotArray []uint8 `eq2:"array,arraysize=SlotCount"` - FooterType uint32 `eq2:"int32"` -} - -// BaseItemDescription Version 1208 -type BaseItemDescriptionV1208 struct { - CreatorFlag uint8 `eq2:"int8"` - Creator common.EQ2String8 `eq2:"string8"` - UniqueID uint32 `eq2:"int32"` - BrokerItemID uint64 `eq2:"int64"` - ItemID int32 `eq2:"sint32"` - ItemCRC int32 `eq2:"sint32"` - Icon uint16 `eq2:"int16"` - Tier uint8 `eq2:"int8"` - Flags uint16 `eq2:"int16"` - Flags2 uint16 `eq2:"int16"` - Unknown81208 []uint8 `eq2:"int8,len=17"` - StatCount uint8 `eq2:"int8"` - StatArray []BaseItemStatV1208 `eq2:"array,arraysize=StatCount"` - StatUnknown uint8 `eq2:"int8"` - StatStringCount uint8 `eq2:"int8"` - StatStringArray []BaseItemStatStringV1208 `eq2:"array,arraysize=StatStringCount"` - Unknown19 uint16 `eq2:"int16"` - Unknown20 uint16 `eq2:"int16"` - Condition uint8 `eq2:"int8"` - Weight uint32 `eq2:"int32"` - SkillReq1 uint32 `eq2:"int32"` - SkillReq2 uint32 `eq2:"int32"` - SkillMin uint16 `eq2:"int16,oversized=127,oversizedbyte=127"` - ClassCount uint8 `eq2:"int8"` - ClassArray []BaseItemClass `eq2:"array,arraysize=ClassCount"` - SlotCount uint8 `eq2:"int8"` - SlotArray []uint8 `eq2:"array,arraysize=SlotCount"` - FooterType uint32 `eq2:"int32"` -} - -// BaseItemDescription Version 63119 -type BaseItemDescriptionV63119 struct { - CreatorFlag uint8 `eq2:"int8"` - Creator common.EQ2String8 `eq2:"string8"` - UniqueID uint32 `eq2:"int32"` - BrokerItemID uint64 `eq2:"int64"` - ItemID int32 `eq2:"sint32"` - ItemCRC int32 `eq2:"sint32"` - Icon uint16 `eq2:"int16"` - Tier uint8 `eq2:"int8"` - Flags uint16 `eq2:"int16"` - Flags2 uint16 `eq2:"int16"` - Unknown863119 []uint8 `eq2:"int8,len=17"` - StatUnknown uint8 `eq2:"int8"` - StatStringCount uint8 `eq2:"int8"` - StatStringArray []BaseItemStatStringV63119 `eq2:"array,arraysize=StatStringCount"` - Unknown19 uint16 `eq2:"int16"` - StatCount uint8 `eq2:"int8"` - StatArray []BaseItemStatV63119 `eq2:"array,arraysize=StatCount"` - Unknown20 uint8 `eq2:"int8"` - ModCount uint8 `eq2:"int8"` - ModArray []BaseItemMod `eq2:"array,arraysize=ModCount"` - Unknown21 []uint8 `eq2:"int8,len=4"` - Condition uint8 `eq2:"int8"` - Weight uint32 `eq2:"int32"` - SkillReq1 uint32 `eq2:"int32"` - SkillReq2 uint32 `eq2:"int32"` - SkillMin uint16 `eq2:"int16,oversized=127,oversizedbyte=127"` - ClassCount uint8 `eq2:"int8"` - ClassArray []BaseItemClass `eq2:"array,arraysize=ClassCount"` - SlotCount uint8 `eq2:"int8"` - SlotArray []uint8 `eq2:"array,arraysize=SlotCount"` - FooterType uint32 `eq2:"int32"` -} - -// Common nested structs for BaseItemDescription -type BaseItemStat struct { - StatType uint16 `eq2:"int16,oversized=127,oversizedbyte=127"` - StatSubtype int16 `eq2:"sint16,oversized=127,oversizedbyte=127"` - Value int16 `eq2:"sint16,oversized=127,oversizedbyte=127"` - StatName common.EQ2String8 `eq2:"string8"` -} - -type BaseItemStatV546 struct { - StatType uint8 `eq2:"int8"` - StatSubtype int16 `eq2:"sint16,oversized=127,oversizedbyte=127"` - Value int16 `eq2:"sint16,oversized=127,oversizedbyte=127"` - StatName common.EQ2String8 `eq2:"string8"` -} - -type BaseItemStatV1096 struct { - StatType uint16 `eq2:"int16,oversized=127,oversizedbyte=127"` - StatSubtype int16 `eq2:"sint16,oversized=127,oversizedbyte=127"` - Value any `eq2:"float,type2=sint16,type2criteria=stat_type!=6,oversized=127,oversizedbyte=127"` - StatName common.EQ2String8 `eq2:"string8"` -} - -type BaseItemStatV1188 struct { - StatType uint16 `eq2:"int16,oversized=127,oversizedbyte=127"` - StatSubtype int16 `eq2:"sint16,oversized=127,oversizedbyte=127,ifnotequals=stat_type_%i"` - Value any `eq2:"float,type2=sint16,type2criteria=stat_type!=6,oversized=127,oversizedbyte=127"` - StatUnknown uint8 `eq2:"int8,ifequals=stat_type_%i"` - StatName common.EQ2String8 `eq2:"string8"` - StatLevel uint8 `eq2:"int8"` -} - -type BaseItemStatV1208 struct { - StatType uint16 `eq2:"int16,oversized=127,oversizedbyte=127"` - StatSubtype int16 `eq2:"sint16,oversized=127,oversizedbyte=127,ifnotequals=stat_type_%i"` - Value any `eq2:"float,type2=sint16,type2criteria=stat_type!=6,oversized=127,oversizedbyte=127"` - StatUnknown uint8 `eq2:"int8,ifequals=stat_type_%i"` - StatName common.EQ2String8 `eq2:"string8"` - StatLevel any `eq2:"int16,type2=int8,type2criteria=stat_name!>2"` -} - -type BaseItemStatV63119 struct { - StatType uint16 `eq2:"int16,oversized=127,oversizedbyte=127"` - StatSubtype int16 `eq2:"sint16,oversized=127,oversizedbyte=127,ifnotequals=stat_type_%i"` - Value any `eq2:"float,type2=sint32,type2criteria=stat_type!=6,oversized=127,oversizedbyte=127"` - StatName common.EQ2String8 `eq2:"string8"` - StatLevel any `eq2:"int16,type2=int8,type2criteria=stat_name!>2"` - Value2 any `eq2:"float,type2=sint32,type2criteria=stat_type!=6,oversized=127,oversizedbyte=127"` -} - -type BaseItemStatString struct { - StatString common.EQ2String8 `eq2:"string8"` - AdornmentFlag uint8 `eq2:"int8"` - AdornmentArray []AdornmentUnknown `eq2:"array,arraysize=AdornmentFlag"` - StatDescription common.EQ2String16 `eq2:"string16"` -} - -type BaseItemStatStringV546 struct { - StatString common.EQ2String8 `eq2:"string8"` -} - -type BaseItemStatStringV1096 struct { - StatString common.EQ2String8 `eq2:"string8"` - StatDescription common.EQ2String16 `eq2:"string16"` - StatStringUnknown uint8 `eq2:"int8"` -} - -type BaseItemStatStringV1188 struct { - StatString common.EQ2String8 `eq2:"string8"` - StatStringUnknown uint8 `eq2:"int8"` - StatDescription common.EQ2String16 `eq2:"string16"` -} - -type BaseItemStatStringV1208 struct { - StatString common.EQ2String8 `eq2:"string8"` - StatStringUnknown uint8 `eq2:"int8"` - StatDescription common.EQ2String16 `eq2:"string16"` -} - -type BaseItemStatStringV63119 struct { - StatString common.EQ2String8 `eq2:"string8"` - StatStringUnknown uint8 `eq2:"int8"` - StatDescription common.EQ2String16 `eq2:"string16"` -} - -type AdornmentUnknown struct { - AdornmentUnknown uint8 `eq2:"int8"` -} - -type BaseItemClass struct { - AdventureClass uint8 `eq2:"int8"` - TradeskillClass uint8 `eq2:"int8"` - Level uint16 `eq2:"int16"` -} - -type BaseItemMod struct { - ModString common.EQ2String8 `eq2:"string8"` - ModNeed uint8 `eq2:"int8"` - ModHave uint8 `eq2:"int8,ifvariableset=header_info_mod_need_0"` - ModUnknown []uint8 `eq2:"int8,len=2"` -} diff --git a/internal/packets/substructs/BaseItemDescriptionGeneric.go b/internal/packets/substructs/BaseItemDescriptionGeneric.go deleted file mode 100644 index c6bd74c..0000000 --- a/internal/packets/substructs/BaseItemDescriptionGeneric.go +++ /dev/null @@ -1,26 +0,0 @@ -package substructs - -import "eq2emu/internal/common" - -// BaseItemDescriptionGeneric Version 373 -type BaseItemDescriptionGeneric struct { - CreatorFlag uint8 `eq2:"int8"` - Creator common.EQ2String16 `eq2:"string16"` - UniqueID uint32 `eq2:"int32"` - Icon uint16 `eq2:"int16"` - Tier uint8 `eq2:"int8"` - FlagNames common.EQ2String8 `eq2:"string8"` - Unknown81 []uint8 `eq2:"int8,len=17"` - StatCount uint8 `eq2:"int8"` - StatArray []BaseItemStat `eq2:"array,arraysize=StatCount"` - StatStringCount uint8 `eq2:"int8"` - StatStringArray []BaseItemStatString `eq2:"array,arraysize=StatStringCount"` - Condition uint8 `eq2:"int8"` - Weight uint16 `eq2:"int16,oversized=127,oversizedbyte=127"` - SkillReq1 uint32 `eq2:"int32"` - SkillReq2 uint32 `eq2:"int32"` - SkillMin uint16 `eq2:"int16,oversized=127,oversizedbyte=127"` - SkillRecommended uint16 `eq2:"int16,oversized=127,oversizedbyte=127"` - SlotCount uint8 `eq2:"int8"` - SlotArray []uint8 `eq2:"array,arraysize=SlotCount"` -} diff --git a/internal/packets/substructs/BaseItemDescriptionInspect.go b/internal/packets/substructs/BaseItemDescriptionInspect.go deleted file mode 100644 index 609afd3..0000000 --- a/internal/packets/substructs/BaseItemDescriptionInspect.go +++ /dev/null @@ -1,21 +0,0 @@ -package substructs - -import "eq2emu/internal/common" - -// BaseItemDescriptionInspect Version 373 -type BaseItemDescriptionInspect struct { - CreatorFlag uint8 `eq2:"int8"` - Creator common.EQ2String16 `eq2:"string16"` - UniqueID uint32 `eq2:"int32"` - Icon uint16 `eq2:"int16"` - Tier uint8 `eq2:"int8"` - FlagNames common.EQ2String8 `eq2:"string8"` - Unknown81 []uint8 `eq2:"int8,len=17"` - StatCount uint8 `eq2:"int8"` - StatArray []BaseItemStat `eq2:"array,arraysize=StatCount"` - StatStringCount uint8 `eq2:"int8"` - StatStringArray []BaseItemStatString `eq2:"array,arraysize=StatStringCount"` - Condition uint8 `eq2:"int8"` - Weight uint16 `eq2:"int16,oversized=127,oversizedbyte=127"` - Unknown []uint8 `eq2:"int8,len=9"` -} diff --git a/internal/packets/substructs/BaseMerchantItemDescription.go b/internal/packets/substructs/BaseMerchantItemDescription.go deleted file mode 100644 index 2d2542d..0000000 --- a/internal/packets/substructs/BaseMerchantItemDescription.go +++ /dev/null @@ -1,161 +0,0 @@ -package substructs - -import "eq2emu/internal/common" - -// BaseMerchantItemDescription Version 1 -type BaseMerchantItemDescriptionV1 struct { - CreatorFlag uint8 `eq2:"int8"` - Creator common.EQ2String8 `eq2:"string8"` - Adornment common.EQ2String16 `eq2:"string16"` - Unknown3 uint32 `eq2:"int32"` - FirstDesc common.EQ2String16 `eq2:"string16"` - UniqueID uint32 `eq2:"int32"` - ItemID int32 `eq2:"sint32"` - Icon uint16 `eq2:"int16"` - Tier uint8 `eq2:"int8"` - Flags uint32 `eq2:"int32"` - Unknown81M []uint8 `eq2:"int8,len=17"` - StatCount uint8 `eq2:"int8"` - StatArray []BaseItemStat `eq2:"array,arraysize=StatCount"` - StatStringCount uint8 `eq2:"int8"` - StatStringArray []BaseItemStatString `eq2:"array,arraysize=StatStringCount"` - Condition uint8 `eq2:"int8"` - Weight uint32 `eq2:"int32"` - SkillReq1 uint32 `eq2:"int32"` - SkillReq2 uint32 `eq2:"int32"` - SkillMin uint16 `eq2:"int16,oversized=127,oversizedbyte=127"` - ClassCount uint8 `eq2:"int8"` - ClassArray []BaseItemClass `eq2:"array,arraysize=ClassCount"` - SlotCount uint8 `eq2:"int8"` - SlotArray []uint8 `eq2:"array,arraysize=SlotCount"` - FooterType uint32 `eq2:"int32"` -} - -// BaseMerchantItemDescription Version 860 -type BaseMerchantItemDescriptionV860 struct { - CreatorFlag uint8 `eq2:"int8"` - Creator common.EQ2String8 `eq2:"string8"` - Adornment common.EQ2String16 `eq2:"string16"` - Unknown3 []uint32 `eq2:"int32,len=2"` - AdornmentDesc common.EQ2String16 `eq2:"string16"` - UnknownDesc common.EQ2String16 `eq2:"string16"` - FirstDesc common.EQ2String16 `eq2:"string16"` - UniqueID uint32 `eq2:"int32"` - ItemID int32 `eq2:"sint32"` - Icon uint16 `eq2:"int16"` - Tier uint8 `eq2:"int8"` - Flags uint32 `eq2:"int32"` - Unknown8860M []uint8 `eq2:"int8,len=17"` - StatCount uint8 `eq2:"int8"` - StatArray []BaseItemStatMerchant860 `eq2:"array,arraysize=StatCount"` - StatStringCount uint8 `eq2:"int8"` - StatStringArray []BaseItemStatString `eq2:"array,arraysize=StatStringCount"` - Condition uint8 `eq2:"int8"` - Weight uint32 `eq2:"int32"` - SkillReq1 uint32 `eq2:"int32"` - SkillReq2 uint32 `eq2:"int32"` - SkillMin uint16 `eq2:"int16,oversized=127,oversizedbyte=127"` - ClassCount uint8 `eq2:"int8"` - ClassArray []BaseItemClass `eq2:"array,arraysize=ClassCount"` - SlotCount uint8 `eq2:"int8"` - SlotArray []uint8 `eq2:"array,arraysize=SlotCount"` - FooterType uint32 `eq2:"int32"` -} - -// BaseMerchantItemDescription Version 1096 -type BaseMerchantItemDescriptionV1096 struct { - CreatorFlag uint8 `eq2:"int8"` - Creator common.EQ2String8 `eq2:"string8"` - UniqueID uint32 `eq2:"int32"` - ItemID int32 `eq2:"sint32"` - ItemCRC int32 `eq2:"sint32"` - Icon uint16 `eq2:"int16"` - Tier uint8 `eq2:"int8"` - Flags uint16 `eq2:"int16"` - Flags2 uint16 `eq2:"int16"` - Unknown81096M []uint8 `eq2:"int8,len=17"` - StatCount uint8 `eq2:"int8"` - StatArray []BaseItemStatMerchant1096 `eq2:"array,arraysize=StatCount"` - StatUnknown uint8 `eq2:"int8"` - StatStringCount uint8 `eq2:"int8"` - StatStringArray []BaseItemStatStringMerchant1096 `eq2:"array,arraysize=StatStringCount"` - Unknown19 uint16 `eq2:"int16"` - Unknown20 uint16 `eq2:"int16"` - Condition uint8 `eq2:"int8"` - Weight uint32 `eq2:"int32"` - SkillReq1 uint32 `eq2:"int32"` - SkillReq2 uint32 `eq2:"int32"` - SkillMin uint16 `eq2:"int16,oversized=127,oversizedbyte=127"` - ClassCount uint8 `eq2:"int8"` - ClassArray []BaseItemClass `eq2:"array,arraysize=ClassCount"` - SlotCount uint8 `eq2:"int8"` - SlotArray []uint8 `eq2:"array,arraysize=SlotCount"` - FooterType uint32 `eq2:"int32"` -} - -// BaseMerchantItemDescription Version 63119 -type BaseMerchantItemDescriptionV63119 struct { - CreatorFlag uint8 `eq2:"int8"` - Creator common.EQ2String8 `eq2:"string8"` - UniqueID uint32 `eq2:"int32"` - ItemID int32 `eq2:"sint32"` - ItemCRC int32 `eq2:"sint32"` - Icon uint16 `eq2:"int16"` - Tier uint8 `eq2:"int8"` - Flags uint16 `eq2:"int16"` - Flags2 uint16 `eq2:"int16"` - Unknown8 []uint8 `eq2:"int8,len=21"` - StatCount uint8 `eq2:"int8"` - StatArray []BaseItemStatMerchant63119 `eq2:"array,arraysize=StatCount"` - StatUnknown uint8 `eq2:"int8"` - StatStringCount uint8 `eq2:"int8"` - StatStringArray []BaseItemStatStringMerchant63119 `eq2:"array,arraysize=StatStringCount"` - Unknown19 uint16 `eq2:"int16"` - Unknown20 uint16 `eq2:"int16"` - Condition uint8 `eq2:"int8"` - Weight uint32 `eq2:"int32"` - SkillReq1 uint32 `eq2:"int32"` - SkillReq2 uint32 `eq2:"int32"` - SkillMin uint16 `eq2:"int16,oversized=127,oversizedbyte=127"` - ClassCount uint8 `eq2:"int8"` - ClassArray []BaseItemClass `eq2:"array,arraysize=ClassCount"` - SlotCount uint8 `eq2:"int8"` - SlotArray []uint8 `eq2:"array,arraysize=SlotCount"` - FooterType uint32 `eq2:"int32"` -} - -// Merchant-specific stat structs -type BaseItemStatMerchant860 struct { - StatType uint16 `eq2:"int16,oversized=127,oversizedbyte=127"` - StatSubtype int16 `eq2:"sint16,oversized=127,oversizedbyte=127"` - Value int16 `eq2:"sint16,oversized=127,oversizedbyte=127"` - StatName common.EQ2String8 `eq2:"string8"` -} - -type BaseItemStatMerchant1096 struct { - StatType uint16 `eq2:"int16,oversized=127,oversizedbyte=127"` - StatSubtype int16 `eq2:"sint16,oversized=127,oversizedbyte=127"` - Value any `eq2:"float,type2=sint16,type2criteria=stat_type!=6,oversized=127,oversizedbyte=127"` - StatName common.EQ2String8 `eq2:"string8"` -} - -type BaseItemStatMerchant63119 struct { - StatType uint16 `eq2:"int16,oversized=127,oversizedbyte=127"` - StatSubtype int16 `eq2:"sint16,oversized=127,oversizedbyte=127,ifnotequals=stat_type_%i"` - Value any `eq2:"float,type2=sint32,type2criteria=stat_type!=6"` - StatName common.EQ2String8 `eq2:"string8"` - StatLevel any `eq2:"int16,type2=int8,type2criteria=stat_name!>2"` - Value2 float32 `eq2:"float"` -} - -type BaseItemStatStringMerchant1096 struct { - StatString common.EQ2String8 `eq2:"string8"` - StatDescription common.EQ2String16 `eq2:"string16"` - StatStringUnknown uint8 `eq2:"int8"` -} - -type BaseItemStatStringMerchant63119 struct { - StatString common.EQ2String8 `eq2:"string8"` - StatStringUnknown uint8 `eq2:"int8"` - StatDescription common.EQ2String16 `eq2:"string16"` -} diff --git a/internal/packets/substructs/GroupMember.go b/internal/packets/substructs/GroupMember.go deleted file mode 100644 index 3527d50..0000000 --- a/internal/packets/substructs/GroupMember.go +++ /dev/null @@ -1,193 +0,0 @@ -package substructs - -// GroupMember Version 1 -type GroupMemberV1 struct { - ZoneStatus uint8 `eq2:"int8"` - Name []byte `eq2:"char,len=16"` - SpawnID uint32 `eq2:"int32"` - PetID uint32 `eq2:"int32"` - LevelCurrent uint16 `eq2:"int16"` - RaceID uint8 `eq2:"int8"` - ClassID uint8 `eq2:"int8"` - HPMax int32 `eq2:"sint32"` - HPCurrent int32 `eq2:"sint32"` - PowerMax int32 `eq2:"sint32"` - PowerCurrent int32 `eq2:"sint32"` - TraumaCount uint8 `eq2:"int8"` - ArcaneCount uint8 `eq2:"int8"` - NoxiousCount uint8 `eq2:"int8"` - ElementalCount uint8 `eq2:"int8"` -} - -// GroupMember Version 373 -type GroupMemberV373 struct { - ZoneStatus uint8 `eq2:"int8"` - Name []byte `eq2:"char,len=16"` - SpawnID uint32 `eq2:"int32"` - PetID uint32 `eq2:"int32"` - LevelCurrent uint16 `eq2:"int16"` - LevelMax uint16 `eq2:"int16"` - RaceID uint8 `eq2:"int8"` - ClassID uint8 `eq2:"int8"` - HPCurrent int32 `eq2:"sint32"` - HPMax int32 `eq2:"sint32"` - PowerCurrent int32 `eq2:"sint32"` - PowerMax int32 `eq2:"sint32"` - TraumaCount uint8 `eq2:"int8"` - ArcaneCount uint8 `eq2:"int8"` - NoxiousCount uint8 `eq2:"int8"` - ElementalCount uint8 `eq2:"int8"` -} - -// GroupMember Version 546 -type GroupMemberV546 struct { - ZoneStatus uint8 `eq2:"int8"` - Name []byte `eq2:"char,len=41"` - SpawnID uint32 `eq2:"int32"` - PetID uint32 `eq2:"int32"` - LevelCurrent uint16 `eq2:"int16"` - LevelMax uint16 `eq2:"int16"` - RaceID uint8 `eq2:"int8"` - ClassID uint8 `eq2:"int8"` - HPCurrent int32 `eq2:"sint32"` - HPMax int32 `eq2:"sint32"` - PowerCurrent int32 `eq2:"sint32"` - PowerMax int32 `eq2:"sint32"` - TraumaCount uint8 `eq2:"int8"` - ArcaneCount uint8 `eq2:"int8"` - NoxiousCount uint8 `eq2:"int8"` - ElementalCount uint8 `eq2:"int8"` - Zone []byte `eq2:"char,len=60"` - Instance uint8 `eq2:"int8"` -} - -// GroupMember Version 562 -type GroupMemberV562 struct { - SpawnID uint32 `eq2:"int32"` - PetID uint32 `eq2:"int32"` - HPCurrent int32 `eq2:"sint32"` - HPMax int32 `eq2:"sint32"` - PowerCurrent int32 `eq2:"sint32"` - PowerMax int32 `eq2:"sint32"` - LevelCurrent uint16 `eq2:"int16"` - LevelMax uint16 `eq2:"int16"` - Name []byte `eq2:"char,len=41"` - Zone []byte `eq2:"char,len=60"` - Instance uint8 `eq2:"int8"` - ZoneStatus uint8 `eq2:"int8"` - Unknown4 uint16 `eq2:"int16"` - RaceID uint8 `eq2:"int8"` - ClassID uint8 `eq2:"int8"` - TraumaCount uint8 `eq2:"int8"` - ArcaneCount uint8 `eq2:"int8"` - NoxiousCount uint8 `eq2:"int8"` - ElementalCount uint8 `eq2:"int8"` - CurseCount uint8 `eq2:"int8"` - Unknown5 []uint8 `eq2:"int8,len=2"` -} - -// GroupMember Version 1188 -type GroupMemberV1188 struct { - SpawnID uint32 `eq2:"int32"` - PetID uint32 `eq2:"int32"` - HPCurrent int32 `eq2:"sint32"` - HPMax int32 `eq2:"sint32"` - PowerCurrent int32 `eq2:"sint32"` - PowerMax int32 `eq2:"sint32"` - LevelCurrent uint16 `eq2:"int16"` - LevelMax uint16 `eq2:"int16"` - Name []byte `eq2:"char,len=41"` - Zone []byte `eq2:"char,len=60"` - Instance uint8 `eq2:"int8"` - ZoneStatus uint8 `eq2:"int8"` - Unknown4 uint16 `eq2:"int16"` - RaceID uint8 `eq2:"int8"` - ClassID uint8 `eq2:"int8"` - TraumaCount uint8 `eq2:"int8"` - ArcaneCount uint8 `eq2:"int8"` - NoxiousCount uint8 `eq2:"int8"` - ElementalCount uint8 `eq2:"int8"` - CurseCount uint8 `eq2:"int8"` - Unknown5 []uint8 `eq2:"int8,len=2"` - CoEUnknown []uint8 `eq2:"int8,len=9"` -} - -// GroupMember Version 57048 -type GroupMemberV57048 struct { - SpawnID uint32 `eq2:"int32"` - PetID uint32 `eq2:"int32"` - HPCurrent int64 `eq2:"sint64"` - HPMax int64 `eq2:"sint64"` - PowerCurrent int32 `eq2:"sint32"` - PowerMax int32 `eq2:"sint32"` - LevelCurrent uint16 `eq2:"int16"` - LevelMax uint16 `eq2:"int16"` - Name []byte `eq2:"char,len=41"` - Zone []byte `eq2:"char,len=60"` - Instance uint8 `eq2:"int8"` - ZoneStatus uint8 `eq2:"int8"` - Unknown4 uint16 `eq2:"int16"` - RaceID uint8 `eq2:"int8"` - ClassID uint8 `eq2:"int8"` - TraumaCount uint8 `eq2:"int8"` - ArcaneCount uint8 `eq2:"int8"` - NoxiousCount uint8 `eq2:"int8"` - ElementalCount uint8 `eq2:"int8"` - CurseCount uint8 `eq2:"int8"` - Unknown5 []uint8 `eq2:"int8,len=2"` - CoEUnknown []uint8 `eq2:"int8,len=9"` -} - -// GroupMember Version 61532 -type GroupMemberV61532 struct { - SpawnID uint32 `eq2:"int32"` - PetID uint32 `eq2:"int32"` - HPCurrent int64 `eq2:"sint64"` - HPCurrent2 int64 `eq2:"sint64"` - HPMax int32 `eq2:"sint32"` - HPMax2 int32 `eq2:"sint32"` - PowerCurrent int32 `eq2:"sint32"` - PowerMax int32 `eq2:"sint32"` - LevelCurrent uint16 `eq2:"int16"` - LevelMax uint16 `eq2:"int16"` - Name []byte `eq2:"char,len=41"` - Zone []byte `eq2:"char,len=60"` - Instance uint8 `eq2:"int8"` - ZoneStatus uint8 `eq2:"int8"` - Unknown4 uint16 `eq2:"int16"` - RaceID uint8 `eq2:"int8"` - ClassID uint8 `eq2:"int8"` - TraumaCount uint8 `eq2:"int8"` - ArcaneCount uint8 `eq2:"int8"` - NoxiousCount uint8 `eq2:"int8"` - ElementalCount uint8 `eq2:"int8"` - CurseCount uint8 `eq2:"int8"` - Unknown5 []uint8 `eq2:"int8,len=2"` - CoEUnknown []uint8 `eq2:"int8,len=9"` -} - -// GroupMember Version 63167 -type GroupMemberV63167 struct { - SpawnID uint32 `eq2:"int32"` - PetID uint32 `eq2:"int32"` - HPCurrent int64 `eq2:"sint64"` - HPMax int64 `eq2:"sint64"` - PowerCurrent int32 `eq2:"sint32"` - PowerMax int32 `eq2:"sint32"` - LevelCurrent uint16 `eq2:"int16"` - LevelMax uint16 `eq2:"int16"` - Name []byte `eq2:"char,len=41"` - Zone []byte `eq2:"char,len=60"` - Instance uint8 `eq2:"int8"` - ZoneStatus uint8 `eq2:"int8"` - Unknown4 uint16 `eq2:"int16"` - RaceID uint8 `eq2:"int8"` - ClassID uint8 `eq2:"int8"` - TraumaCount uint8 `eq2:"int8"` - ArcaneCount uint8 `eq2:"int8"` - NoxiousCount uint8 `eq2:"int8"` - ElementalCount uint8 `eq2:"int8"` - CurseCount uint8 `eq2:"int8"` - Unknown5 []uint8 `eq2:"int8,len=2"` - CoEUnknown []uint8 `eq2:"int8,len=9"` -} diff --git a/internal/packets/substructs/InfoTemplate.go b/internal/packets/substructs/InfoTemplate.go deleted file mode 100644 index aa95d12..0000000 --- a/internal/packets/substructs/InfoTemplate.go +++ /dev/null @@ -1,20 +0,0 @@ -package substructs - -// InfoTemplate Version 63119 -type InfoTemplate struct { - NumTabs uint16 `eq2:"int16"` - TabTemplateArray []TabTemplate `eq2:"array,arraysize=NumTabs"` -} - -type TabTemplate struct { - TabNumber uint16 `eq2:"int16"` - TabUnknown1 uint32 `eq2:"int32"` - TemplateSize uint16 `eq2:"int16"` - TemplateArray []TemplateData `eq2:"array,arraysize=TemplateSize"` -} - -type TemplateData struct { - TemplatePos uint16 `eq2:"int16"` - TemplateUnknown3 uint16 `eq2:"int16"` - TemplateID uint32 `eq2:"int32"` -} diff --git a/internal/packets/substructs/Item.go b/internal/packets/substructs/Item.go deleted file mode 100644 index 373281e..0000000 --- a/internal/packets/substructs/Item.go +++ /dev/null @@ -1,207 +0,0 @@ -package substructs - -// Item Version 1 -type ItemV1 struct { - UniqueID uint32 `eq2:"int32"` - BagID uint32 `eq2:"int32"` - InvSlotID uint32 `eq2:"int32"` - MenuType uint32 `eq2:"int32"` - SlotID uint8 `eq2:"int8"` - Index uint16 `eq2:"int16"` - Icon uint16 `eq2:"int16"` - Count uint8 `eq2:"int8"` - Unknown uint8 `eq2:"int8"` - Level uint8 `eq2:"int8"` - Tier uint8 `eq2:"int8"` - NumSlots uint8 `eq2:"int8"` - ItemID int32 `eq2:"sint32"` - Name []byte `eq2:"char,len=81"` -} - -// Item Version 373 -type ItemV373 struct { - UniqueID uint32 `eq2:"int32"` - BagID uint32 `eq2:"int32"` - InvSlotID uint32 `eq2:"int32"` - MenuType uint32 `eq2:"int32"` - SlotID uint8 `eq2:"int8"` - Index uint16 `eq2:"int16"` - Icon uint16 `eq2:"int16"` - Count uint8 `eq2:"int8"` - Level uint8 `eq2:"int8"` - Tier uint8 `eq2:"int8"` - NumSlots uint8 `eq2:"int8"` - ItemID int32 `eq2:"sint32"` - Name []byte `eq2:"char,len=64"` - Unknown6 []uint8 `eq2:"int8,len=17"` -} - -// Item Version 562 -type ItemV562 struct { - UniqueID uint32 `eq2:"int32"` - BagID uint32 `eq2:"int32"` - InvSlotID uint32 `eq2:"int32"` - MenuType uint32 `eq2:"int32"` - Index uint16 `eq2:"int16"` - Icon uint16 `eq2:"int16"` - SlotID uint8 `eq2:"int8"` - Count uint8 `eq2:"int8"` - Unknown4 uint8 `eq2:"int8"` - Tier uint8 `eq2:"int8"` - NumSlots uint8 `eq2:"int8"` - ItemID int32 `eq2:"sint32"` - Name []byte `eq2:"char,len=64"` - Unknown6 []uint8 `eq2:"int8,len=17"` -} - -// Item Version 893 -type ItemV893 struct { - UniqueID uint32 `eq2:"int32"` - BagID uint32 `eq2:"int32"` - InvSlotID uint32 `eq2:"int32"` - MenuType uint32 `eq2:"int32"` - Unknown3b uint32 `eq2:"int32"` - Index uint16 `eq2:"int16"` - Icon uint16 `eq2:"int16"` - SlotID uint8 `eq2:"int8"` - Count uint8 `eq2:"int8"` - Unknown4 uint8 `eq2:"int8"` - Tier uint8 `eq2:"int8"` - NumSlots uint8 `eq2:"int8"` - ItemID int32 `eq2:"sint32"` - Name []byte `eq2:"char,len=64"` - Unknown6 []uint8 `eq2:"int8,len=17"` -} - -// Item Version 1193 -type ItemV1193 struct { - UniqueID uint32 `eq2:"int32"` - BagID uint32 `eq2:"int32"` - InvSlotID uint32 `eq2:"int32"` - MenuType uint32 `eq2:"int32"` - Unknown3b uint32 `eq2:"int32"` - Index uint16 `eq2:"int16"` - Icon uint16 `eq2:"int16"` - SlotID uint8 `eq2:"int8"` - Count uint8 `eq2:"int8"` - Unknown4 uint8 `eq2:"int8"` - Tier uint8 `eq2:"int8"` - NumSlots uint8 `eq2:"int8"` - ItemID int32 `eq2:"sint32"` - Name []byte `eq2:"char,len=64"` - Unknown6 []uint8 `eq2:"int8,len=18"` -} - -// Item Version 1205 -type ItemV1205 struct { - UniqueID uint32 `eq2:"int32"` - BagID uint32 `eq2:"int32"` - InvSlotID uint32 `eq2:"int32"` - MenuType uint32 `eq2:"int32"` - Unknown3b uint32 `eq2:"int32"` - Index uint16 `eq2:"int16"` - Icon uint16 `eq2:"int16"` - SlotID uint8 `eq2:"int8"` - Count uint8 `eq2:"int8"` - Unknown4 uint8 `eq2:"int8"` - Tier uint8 `eq2:"int8"` - NumSlots uint8 `eq2:"int8"` - Unknown5 []uint8 `eq2:"int8,len=2"` - ItemID int32 `eq2:"sint32"` - Name []byte `eq2:"char,len=64"` - Unknown6 []uint8 `eq2:"int8,len=17"` -} - -// Item Version 57048 -type ItemV57048 struct { - UniqueID uint32 `eq2:"int32"` - BagID uint32 `eq2:"int32"` - InvSlotID uint32 `eq2:"int32"` - MenuType uint32 `eq2:"int32"` - Unknown3b uint32 `eq2:"int32"` - Index uint16 `eq2:"int16"` - Icon uint16 `eq2:"int16"` - SlotID uint8 `eq2:"int8"` - Count uint16 `eq2:"int16"` - Unknown4b uint8 `eq2:"int8"` - Unknown4c uint8 `eq2:"int8"` - ItemLevel uint8 `eq2:"int8"` - Tier uint8 `eq2:"int8"` - NumSlots uint8 `eq2:"int8"` - Unknown5 []uint8 `eq2:"int8,len=2"` - ItemID int32 `eq2:"sint32"` - Name []byte `eq2:"char,len=64"` - Unknown6 []uint8 `eq2:"int8,len=17"` -} - -// Item Version 57107 -type ItemV57107 struct { - UniqueID uint32 `eq2:"int32"` - BagID uint32 `eq2:"int32"` - InvSlotID uint32 `eq2:"int32"` - MenuType uint32 `eq2:"int32"` - Unknown3b uint32 `eq2:"int32"` - Index uint16 `eq2:"int16"` - Icon uint16 `eq2:"int16"` - SlotID uint8 `eq2:"int8"` - Count uint16 `eq2:"int16"` - Unknown4b uint8 `eq2:"int8"` - Unknown4c uint8 `eq2:"int8"` - ItemLevel uint8 `eq2:"int8"` - Tier uint8 `eq2:"int8"` - NumSlots uint8 `eq2:"int8"` - Unknown5 []uint8 `eq2:"int8,len=2"` - ItemID int32 `eq2:"sint32"` - BrokerID uint64 `eq2:"int64"` - Name []byte `eq2:"char,len=64"` - Unknown6 []uint8 `eq2:"int8,len=17"` -} - -// Item Version 63119 -type ItemV63119 struct { - UniqueID uint32 `eq2:"int32"` - BagID uint32 `eq2:"int32"` - InvSlotID uint32 `eq2:"int32"` - MenuType uint32 `eq2:"int32"` - Unknown3 uint32 `eq2:"int32"` - Index uint16 `eq2:"int16"` - Icon uint16 `eq2:"int16"` - SlotID uint8 `eq2:"int8"` - Count uint16 `eq2:"int16"` - Unknown4b uint8 `eq2:"int8"` - Unknown4c uint8 `eq2:"int8"` - ItemLevel uint8 `eq2:"int8"` - Tier uint8 `eq2:"int8"` - NumSlots uint8 `eq2:"int8"` - EmptySlots uint8 `eq2:"int8"` - Unknown52 uint8 `eq2:"int8"` - Unknown53 uint8 `eq2:"int8"` - ItemID int32 `eq2:"sint32"` - BrokerID uint64 `eq2:"int64"` - Name []byte `eq2:"char,len=64"` - Unknown6 []uint8 `eq2:"int8,len=17"` -} - -// Item Version 63214 (latest) -type ItemV63214 struct { - UniqueID uint32 `eq2:"int32"` - BagID uint32 `eq2:"int32"` - InvSlotID uint32 `eq2:"int32"` - MenuType uint32 `eq2:"int32"` - Unknown3 uint32 `eq2:"int32"` - Index uint16 `eq2:"int16"` - Icon uint16 `eq2:"int16"` - SlotID uint8 `eq2:"int8"` - Count uint16 `eq2:"int16"` - Unknown4b uint8 `eq2:"int8"` - Unknown4c uint8 `eq2:"int8"` - ItemLevel uint8 `eq2:"int8"` - Tier uint8 `eq2:"int8"` - NumSlots uint8 `eq2:"int8"` - EmptySlots uint8 `eq2:"int8"` - Unknown52 uint8 `eq2:"int8"` - ItemID int32 `eq2:"sint32"` - BrokerID uint64 `eq2:"int64"` - Name []byte `eq2:"char,len=64"` - Unknown6 []uint8 `eq2:"int8,len=17"` -} diff --git a/internal/packets/substructs/ItemDescription.go b/internal/packets/substructs/ItemDescription.go deleted file mode 100644 index 99a5afc..0000000 --- a/internal/packets/substructs/ItemDescription.go +++ /dev/null @@ -1,59 +0,0 @@ -package substructs - -// ItemDescription Version 1 -type ItemDescriptionV1 struct { - InfoHeader WSExamineInfoHeader `eq2:"substruct"` - Info BaseItemDescriptionV1 `eq2:"substruct"` - ItemType uint8 `eq2:"int8"` -} - -// ItemDescription Version 373 -type ItemDescriptionV373 struct { - InfoHeader WSExamineInfoHeader `eq2:"substruct"` - Info BaseItemDescriptionV373 `eq2:"substruct"` - ItemType uint8 `eq2:"int8"` -} - -// ItemDescription Version 546 -type ItemDescriptionV546 struct { - InfoHeader WSExamineInfoHeader `eq2:"substruct"` - Info BaseItemDescriptionV546 `eq2:"substruct"` - ItemType uint8 `eq2:"int8"` -} - -// ItemDescription Version 1096 -type ItemDescriptionV1096 struct { - InfoHeader WSExamineInfoHeader `eq2:"substruct"` - Info BaseItemDescriptionV1096 `eq2:"substruct"` - ItemType uint8 `eq2:"int8"` -} - -// ItemDescription Version 1188 -type ItemDescriptionV1188 struct { - InfoHeader WSExamineInfoHeader `eq2:"substruct"` - Info BaseItemDescriptionV1188 `eq2:"substruct"` - ItemType uint8 `eq2:"int8"` -} - -// ItemDescription Version 1208 -type ItemDescriptionV1208 struct { - InfoHeader WSExamineInfoHeader `eq2:"substruct"` - Info BaseItemDescriptionV1208 `eq2:"substruct"` - ItemType uint8 `eq2:"int8"` -} - -// ItemDescription Version 63119 -type ItemDescriptionV63119 struct { - InfoHeader WSExamineInfoHeader `eq2:"substruct"` - Info BaseItemDescriptionV63119 `eq2:"substruct"` - ItemType uint8 `eq2:"int8"` -} - -// WSExamineInfoHeader - referenced by ItemDescription structs -// This struct definition needs to be provided based on the actual WS_ExamineInfoHeader definition -type WSExamineInfoHeader struct { - // Fields need to be defined based on actual WS_ExamineInfoHeader structure - // Placeholder - replace with actual fields - Unknown1 uint32 `eq2:"int32"` - Unknown2 uint16 `eq2:"int16"` -} diff --git a/internal/packets/substructs/ItemDescriptionGeneric.go b/internal/packets/substructs/ItemDescriptionGeneric.go deleted file mode 100644 index 92287d4..0000000 --- a/internal/packets/substructs/ItemDescriptionGeneric.go +++ /dev/null @@ -1,8 +0,0 @@ -package substructs - -// ItemDescriptionGeneric Version 373 -type ItemDescriptionGeneric struct { - InfoHeader WSExamineInfoHeader `eq2:"substruct"` - Info BaseItemDescriptionGeneric `eq2:"substruct"` - ItemType uint8 `eq2:"int8"` -} diff --git a/internal/packets/substructs/ItemDescriptionInspect.go b/internal/packets/substructs/ItemDescriptionInspect.go deleted file mode 100644 index cd39ecc..0000000 --- a/internal/packets/substructs/ItemDescriptionInspect.go +++ /dev/null @@ -1,8 +0,0 @@ -package substructs - -// ItemDescriptionInspect Version 373 -type ItemDescriptionInspect struct { - InfoHeader WSExamineInfoHeader `eq2:"substruct"` - Info BaseItemDescriptionInspect `eq2:"substruct"` - ItemType uint8 `eq2:"int8"` -} diff --git a/internal/packets/substructs/ItemFooter.go b/internal/packets/substructs/ItemFooter.go deleted file mode 100644 index 9a7c67d..0000000 --- a/internal/packets/substructs/ItemFooter.go +++ /dev/null @@ -1,818 +0,0 @@ -package substructs - -import "eq2emu/internal/common" - -// Supporting structs for nested arrays -type EffectItem struct { - SubBulletFlag uint8 `eq2:"int8"` - Effect common.EQ2String16 `eq2:"string16"` -} - -type EffectItemV546 struct { - SubBulletFlag uint8 `eq2:"int8"` - Effect common.EQ2String16 `eq2:"string16"` - Percentage uint8 `eq2:"int8"` -} - -type SetStatItem struct { - SetStatType uint8 `eq2:"int8"` - SetStatSubtype uint8 `eq2:"int8"` - SetValue int16 `eq2:"sint16,oversized=127,oversizedbyte=127"` - SetStatName common.EQ2String8 `eq2:"string8"` -} - -type SetStatItemV1188 struct { - SetStatType uint16 `eq2:"int16,oversized=127,oversizedbyte=127"` - SetStatSubtype uint16 `eq2:"int16,oversized=127,oversizedbyte=127,ifnotequals=set_stat_type_%i"` - SetValue any `eq2:"float,type2=sint16,type2criteria=set_stat_type!=6,oversized=127,oversizedbyte=127"` - SetStatName common.EQ2String8 `eq2:"string8"` - SetStatUnknown uint8 `eq2:"int8"` -} - -type SetStatItemV63119 struct { - SetStatType uint16 `eq2:"int16,oversized=127,oversizedbyte=127"` - SetStatSubtype uint16 `eq2:"int16,oversized=127,oversizedbyte=127,ifnotequals=set_stat_type_%i"` - SetValue any `eq2:"float,type2=sint32,type2criteria=set_stat_type!=6"` - SetStatName common.EQ2String8 `eq2:"string8"` - SetStatUnknown uint32 `eq2:"int32"` - SetStatUnknownMJ uint16 `eq2:"int16"` -} - -type SetEffectItem struct { - SetSubBulletFlag uint8 `eq2:"int8"` - SetEffect common.EQ2String16 `eq2:"string16"` - SetPercentage uint8 `eq2:"int8"` -} - -type SetBonusItem struct { - SetNumNeeded uint8 `eq2:"int8"` - SetStatCount uint8 `eq2:"int8"` - SetStatArray []SetStatItem `eq2:"array,arraysize=SetStatCount"` - NumSetEffects uint8 `eq2:"int8"` - SetEffectArray []SetEffectItem `eq2:"array,arraysize=NumSetEffects"` -} - -type SetBonusItemV1188 struct { - SetBonusItemsNeeded uint8 `eq2:"int8"` - SetBonusStatsCount uint8 `eq2:"int8"` - SetBonusStatsArray []SetStatItemV1188 `eq2:"array,arraysize=SetBonusStatsCount"` - SetBonusEffectsCount uint8 `eq2:"int8"` - SetBonusEffectsArray []SetBonusEffectItem `eq2:"array,arraysize=SetBonusEffectsCount"` -} - -type SetBonusItemV63119 struct { - SetBonusItemsNeeded uint8 `eq2:"int8"` - SetBonusStatsCount uint8 `eq2:"int8"` - SetBonusStatsArray []SetStatItemV63119 `eq2:"array,arraysize=SetBonusStatsCount"` - SetBonusEffectsCount uint8 `eq2:"int8"` - SetBonusEffectsArray []SetBonusEffectItem `eq2:"array,arraysize=SetBonusEffectsCount"` -} - -type SetBonusEffectItem struct { - SetBonusEffectSubBulletFlag uint8 `eq2:"int8"` - SetBonusEffectText common.EQ2String16 `eq2:"string16"` - SetBonusEffectPercentage uint8 `eq2:"int8"` -} - -type SetItemsItem struct { - SetItemsUnknown1 uint8 `eq2:"int8"` - SetItemsUnknown2 uint8 `eq2:"int8"` - SetItemName common.EQ2String16 `eq2:"string16"` -} - -type AdornItem struct { - AdornSlot uint8 `eq2:"int8"` - AdornUnknown uint32 `eq2:"int32"` - AdornName common.EQ2String16 `eq2:"string16"` - AdornTimeLeft float32 `eq2:"float"` -} - -type AdornItemV1188 struct { - AdornUnknown1 uint8 `eq2:"int8"` - AdornSlot uint8 `eq2:"int8"` - AdornUnknown2 []uint8 `eq2:"int8,len=2"` - AdornItemID uint32 `eq2:"int32"` - AdornName common.EQ2String16 `eq2:"string16"` - AdornTimeLeft float32 `eq2:"float"` - AdornUnknown3 uint32 `eq2:"int32"` -} - -type AdornItemV63119 struct { - AdornSlot uint8 `eq2:"int8"` - AdornUnknown1 uint8 `eq2:"int8"` - AdornUnknown2 []uint8 `eq2:"int8,len=2"` - AdornItemID uint32 `eq2:"int32"` - AdornName common.EQ2String16 `eq2:"string16"` - AdornTimeLeft float32 `eq2:"float"` - AdornUnknown3 uint32 `eq2:"int32"` -} - -type AdornStatItem struct { - AdornStatType uint16 `eq2:"int16,oversized=127,oversizedbyte=127"` - AdornStatSubtype int16 `eq2:"sint16,oversized=127,oversizedbyte=127,ifnotequals=adorn_stat_type_%i_%i"` - AdornValue any `eq2:"float,type2=sint16,type2criteria=stat_type!=6,oversized=127,oversizedbyte=127"` - AdornStatName common.EQ2String8 `eq2:"string8"` - AdornStatLevel uint8 `eq2:"int8"` -} - -type AdornStatItemV63119 struct { - AdornStatType uint16 `eq2:"int16,oversized=127,oversizedbyte=127"` - AdornStatSubtype int16 `eq2:"sint16,oversized=127,oversizedbyte=127,ifnotequals=adorn_stat_type_%i_%i"` - AdornValue any `eq2:"float,type2=sint32,type2criteria=adorn_stat_type!=6,oversized=127,oversizedbyte=127"` - AdornStatName common.EQ2String8 `eq2:"string8"` - AdornStatLevel uint8 `eq2:"int8"` - AdornStatUnknown1 []uint8 `eq2:"int8,len=5"` -} - -type AdornLevelItem struct { - NumAdornStats uint32 `eq2:"int32"` - AdornStatsArray []AdornStatItem `eq2:"array,arraysize=NumAdornStats"` -} - -type AdornLevelItemV63119 struct { - NumAdornStats uint32 `eq2:"int32"` - AdornStatsArray []AdornStatItemV63119 `eq2:"array,arraysize=NumAdornStats"` -} - -type TierlineItem struct { - Addon common.EQ2String16 `eq2:"string16"` - TierlineUnknown []uint8 `eq2:"int8,len=5"` -} - -// Version structs -type SubstructItemFooterV1 struct { - Name common.EQ2String8 `eq2:"string8"` - Description common.EQ2String16 `eq2:"string16"` -} - -type SubstructItemFooterV373 struct { - NumEffects uint8 `eq2:"int8,ifflagnotset=loot"` - EffectArray []EffectItem `eq2:"array,arraysize=NumEffects,ifflagnotset=loot"` - Name common.EQ2String8 `eq2:"string8"` - Description common.EQ2String16 `eq2:"string16"` -} - -type SubstructItemFooterV546 struct { - NumEffects uint8 `eq2:"int8,ifflagnotset=loot"` - EffectArray []EffectItemV546 `eq2:"array,arraysize=NumEffects,ifflagnotset=loot"` - Name common.EQ2String8 `eq2:"string8"` - Description common.EQ2String16 `eq2:"string16"` -} - -type SubstructItemFooterV562 struct { - // NOTE: Parser needs enhancement for comma-separated conditions - // Original: IfVariableNotSet="header_info_header_unknown_0_0,header_unknown_0" - NumEffects uint8 `eq2:"int8,ifvariablenotset=header_info_header_unknown_0_0"` - EffectArray []EffectItemV546 `eq2:"array,arraysize=NumEffects"` - RequiredClasses uint64 `eq2:"int64"` - RecommendedLevel uint8 `eq2:"int8"` - StackSize uint8 `eq2:"int8"` - SetName common.EQ2String8 `eq2:"string8"` - NumSets uint8 `eq2:"int8,ifvariableset=footer_set_name_0"` - SetArray []SetBonusItem `eq2:"array,arraysize=NumSets"` - NumItemsInSet uint8 `eq2:"int8,ifvariableset=footer_set_name_0"` - SetItemsArray []SetItemsItem `eq2:"array,arraysize=NumItemsInSet"` - Collectable uint8 `eq2:"int8,ifvariablenotset=footer_set_name_0"` - CollectionNeeded uint8 `eq2:"int8,ifvariableset=footer_collectable_0"` - OffersQuest common.EQ2String8 `eq2:"string8,ifvariablenotset=footer_set_name_0"` - PartOfQuest common.EQ2String8 `eq2:"string8,ifvariablenotset=footer_set_name_0"` - OffersQuestColor uint8 `eq2:"int8,ifvariableset=footer_offers_quest_0"` - PartOfQuestColor uint8 `eq2:"int8,ifvariableset=footer_part_of_quest_0"` - UnknownSetData1 uint8 `eq2:"int8,ifvariableset=footer_set_name_0"` - Charges uint8 `eq2:"int8,ifvariablenotset=footer_set_name_0"` - TotalCharges uint16 `eq2:"int16,ifvariableset=footer_charges_0"` - ChargesLeft uint16 `eq2:"int16,ifvariableset=footer_charges_0"` - UnknownSetInfo uint32 `eq2:"int32,ifvariableset=footer_set_name_0"` - UnknownSetInfo2 uint8 `eq2:"int8,ifvariableset=footer_set_name_0"` - UnknownSetInfo3 uint32 `eq2:"int32,ifvariableset=footer_unknown_set_info2_0"` - DisplayCharges uint8 `eq2:"int8"` - CraftingFlag uint8 `eq2:"int8"` - TransmutedFlag uint8 `eq2:"int8"` - Name common.EQ2String8 `eq2:"string8"` - Description common.EQ2String16 `eq2:"string16"` -} - -type SubstructItemFooterV860 struct { - NumEffects uint8 `eq2:"int8,ifvariablenotset=header_info_header_unknown_0_0"` - EffectArray []EffectItemV546 `eq2:"array,arraysize=NumEffects"` - RequiredClasses uint64 `eq2:"int64"` - RecommendedLevel uint8 `eq2:"int8"` - StackSize uint8 `eq2:"int8"` - SetName common.EQ2String8 `eq2:"string8"` - NumSets uint8 `eq2:"int8,ifvariableset=footer_set_name_0"` - SetArray []SetBonusItem `eq2:"array,arraysize=NumSets"` - NumItemsInSet uint8 `eq2:"int8,ifvariableset=footer_set_name_0"` - SetItemsArray []SetItemsItem `eq2:"array,arraysize=NumItemsInSet"` - Collectable uint8 `eq2:"int8,ifvariablenotset=footer_set_name_0"` - CollectionNeeded uint8 `eq2:"int8,ifvariableset=footer_collectable_0"` - OffersQuest common.EQ2String8 `eq2:"string8,ifvariablenotset=footer_set_name_0"` - PartOfQuest common.EQ2String8 `eq2:"string8,ifvariablenotset=footer_set_name_0"` - OffersQuestColor uint8 `eq2:"int8,ifvariableset=footer_offers_quest_0"` - PartOfQuestColor uint8 `eq2:"int8,ifvariableset=footer_part_of_quest_0"` - UnknownSetData1 uint8 `eq2:"int8,ifvariableset=footer_set_name_0"` - Charges uint8 `eq2:"int8,ifvariablenotset=footer_set_name_0"` - TotalCharges uint16 `eq2:"int16,ifvariableset=footer_charges_0"` - ChargesLeft uint16 `eq2:"int16,ifvariableset=footer_charges_0"` - UnknownSetInfo uint32 `eq2:"int32,ifvariableset=footer_set_name_0"` - UnknownSetInfo2 uint8 `eq2:"int8,ifvariableset=footer_set_name_0"` - UnknownSetInfo3 uint32 `eq2:"int32,ifvariableset=footer_unknown_set_info2_0"` - FooterUnknown5 uint8 `eq2:"int8"` - DisplayCharges uint8 `eq2:"int8"` - CraftingFlag uint8 `eq2:"int8"` - TransmutedFlag uint8 `eq2:"int8"` - Name common.EQ2String8 `eq2:"string8"` - Description common.EQ2String16 `eq2:"string16"` -} - -type SubstructItemFooterV893 struct { - NumEffects uint8 `eq2:"int8,ifvariablenotset=header_info_header_unknown_0_0"` - EffectArray []EffectItemV546 `eq2:"array,arraysize=NumEffects"` - RequiredClasses uint64 `eq2:"int64"` - RecommendedLevel uint8 `eq2:"int8"` - RequiredLevel uint8 `eq2:"int8"` - StackSize uint8 `eq2:"int8"` - FooterUnknown3 uint8 `eq2:"int8"` - SetName common.EQ2String8 `eq2:"string8"` - NumSets uint8 `eq2:"int8,ifvariableset=footer_set_name_0"` - SetArray []SetBonusItem `eq2:"array,arraysize=NumSets"` - NumItemsInSet uint8 `eq2:"int8,ifvariableset=footer_set_name_0"` - SetItemsArray []SetItemsItem `eq2:"array,arraysize=NumItemsInSet"` - Collectable uint8 `eq2:"int8,ifvariablenotset=footer_set_name_0"` - CollectionNeeded uint8 `eq2:"int8,ifvariableset=footer_collectable_0"` - OffersQuest common.EQ2String8 `eq2:"string8,ifvariablenotset=footer_set_name_0"` - PartOfQuest common.EQ2String8 `eq2:"string8,ifvariablenotset=footer_set_name_0"` - OffersQuestColor uint8 `eq2:"int8,ifvariableset=footer_offers_quest_0"` - PartOfQuestColor uint8 `eq2:"int8,ifvariableset=footer_part_of_quest_0"` - UnknownSetData1 uint8 `eq2:"int8,ifvariableset=footer_set_name_0"` - Charges uint8 `eq2:"int8,ifvariablenotset=footer_set_name_0"` - TotalCharges uint16 `eq2:"int16,ifvariableset=footer_charges_0"` - ChargesLeft uint16 `eq2:"int16,ifvariableset=footer_charges_0"` - UnknownSetInfo uint32 `eq2:"int32,ifvariableset=footer_set_name_0"` - UnknownSetInfo2 uint8 `eq2:"int8,ifvariableset=footer_set_name_0"` - UnknownSetInfo3 uint32 `eq2:"int32,ifvariableset=footer_unknown_set_info2_0"` - FooterUnknown5 uint8 `eq2:"int8"` - DisplayCharges uint8 `eq2:"int8"` - CraftingFlag uint8 `eq2:"int8"` - TransmutedFlag uint8 `eq2:"int8"` - Name common.EQ2String8 `eq2:"string8"` - Description common.EQ2String16 `eq2:"string16"` -} - -type SubstructItemFooterV927 struct { - NumEffects uint8 `eq2:"int8,ifvariablenotset=header_info_header_unknown_0_0"` - EffectArray []EffectItemV546 `eq2:"array,arraysize=NumEffects"` - RequiredClasses uint64 `eq2:"int64"` - RecommendedLevel uint8 `eq2:"int8"` - RequiredLevel uint8 `eq2:"int8"` - StackSize uint8 `eq2:"int8"` - FooterUnknown3 uint8 `eq2:"int8"` - SetName common.EQ2String8 `eq2:"string8"` - NumSets uint8 `eq2:"int8,ifvariableset=footer_set_name_0"` - SetArray []SetBonusItem `eq2:"array,arraysize=NumSets"` - NumItemsInSet uint8 `eq2:"int8,ifvariableset=footer_set_name_0"` - SetItemsArray []SetItemsItem `eq2:"array,arraysize=NumItemsInSet"` - FooterUnknown4 uint8 `eq2:"int8"` - Collectable uint8 `eq2:"int8,ifvariablenotset=footer_set_name_0"` - CollectionNeeded uint8 `eq2:"int8,ifvariableset=footer_collectable_0"` - OffersQuest common.EQ2String8 `eq2:"string8,ifvariablenotset=footer_set_name_0"` - PartOfQuest common.EQ2String8 `eq2:"string8,ifvariablenotset=footer_set_name_0"` - OffersQuestColor uint8 `eq2:"int8,ifvariableset=footer_offers_quest_0"` - PartOfQuestColor uint8 `eq2:"int8,ifvariableset=footer_part_of_quest_0"` - UnknownSetData1 uint8 `eq2:"int8,ifvariableset=footer_set_name_0"` - Charges uint8 `eq2:"int8,ifvariablenotset=footer_set_name_0"` - TotalCharges uint16 `eq2:"int16,ifvariableset=footer_charges_0"` - ChargesLeft uint16 `eq2:"int16,ifvariableset=footer_charges_0"` - UnknownSetInfo uint32 `eq2:"int32,ifvariableset=footer_set_name_0"` - UnknownSetInfo2 uint8 `eq2:"int8,ifvariableset=footer_set_name_0"` - UnknownSetInfo3 uint32 `eq2:"int32,ifvariableset=footer_unknown_set_info2_0"` - FooterUnknown5 uint8 `eq2:"int8"` - DisplayCharges uint8 `eq2:"int8"` - CraftingFlag uint8 `eq2:"int8"` - TransmutedFlag uint8 `eq2:"int8"` - Name common.EQ2String8 `eq2:"string8"` - Description common.EQ2String16 `eq2:"string16"` -} - -type SubstructItemFooterV1027 struct { - NumEffects uint8 `eq2:"int8,ifvariablenotset=header_info_header_unknown_0_0"` - EffectArray []EffectItemV546 `eq2:"array,arraysize=NumEffects"` - RequiredClasses uint64 `eq2:"int64"` - RecommendedLevel uint8 `eq2:"int8"` - RequiredLevel uint8 `eq2:"int8"` - StackSize uint8 `eq2:"int8"` - FooterUnknown3 []uint8 `eq2:"int8,len=2"` - SetName common.EQ2String8 `eq2:"string8"` - NumSets uint8 `eq2:"int8,ifvariableset=footer_set_name_0"` - SetArray []SetBonusItem `eq2:"array,arraysize=NumSets"` - NumItemsInSet uint8 `eq2:"int8,ifvariableset=footer_set_name_0"` - SetItemsArray []SetItemsItem `eq2:"array,arraysize=NumItemsInSet"` - FooterUnknown4 []uint8 `eq2:"int8,len=4"` - Collectable uint8 `eq2:"int8,ifvariablenotset=footer_set_name_0"` - CollectionNeeded uint8 `eq2:"int8,ifvariableset=footer_collectable_0"` - OffersQuest common.EQ2String8 `eq2:"string8,ifvariablenotset=footer_set_name_0"` - PartOfQuest common.EQ2String8 `eq2:"string8,ifvariablenotset=footer_set_name_0"` - OffersQuestColor uint8 `eq2:"int8,ifvariableset=footer_offers_quest_0"` - PartOfQuestColor uint8 `eq2:"int8,ifvariableset=footer_part_of_quest_0"` - UnknownSetData1 uint8 `eq2:"int8,ifvariableset=footer_set_name_0"` - Charges uint8 `eq2:"int8,ifvariablenotset=footer_set_name_0"` - TotalCharges uint16 `eq2:"int16,ifvariableset=footer_charges_0"` - ChargesLeft uint16 `eq2:"int16,ifvariableset=footer_charges_0"` - UnknownSetInfo uint32 `eq2:"int32,ifvariableset=footer_set_name_0"` - UnknownSetInfo2 uint8 `eq2:"int8,ifvariableset=footer_set_name_0"` - UnknownSetInfo3 uint32 `eq2:"int32,ifvariableset=footer_unknown_set_info2_0"` - FooterUnknown5 []uint8 `eq2:"int8,len=2"` - DisplayCharges uint8 `eq2:"int8"` - CraftingFlag uint8 `eq2:"int8"` - TransmutedFlag uint8 `eq2:"int8"` - Name common.EQ2String8 `eq2:"string8"` - Description common.EQ2String16 `eq2:"string16"` -} - -type SubstructItemFooterV1096 struct { - NumEffects uint8 `eq2:"int8,ifvariablenotset=header_info_header_unknown_0_0"` - EffectArray []EffectItemV546 `eq2:"array,arraysize=NumEffects"` - RequiredClasses uint64 `eq2:"int64"` - RecommendedLevel uint8 `eq2:"int8"` - RequiredLevel uint8 `eq2:"int8"` - StackSize uint8 `eq2:"int8"` - AdornFlag uint8 `eq2:"int8"` - FooterUnknown3 uint8 `eq2:"int8"` - FooterUnknown3A uint8 `eq2:"int8"` - FooterUnknown3B uint8 `eq2:"int8"` - FooterUnknown3C uint8 `eq2:"int8"` - SetName common.EQ2String8 `eq2:"string8"` - NumSets uint8 `eq2:"int8,ifvariableset=footer_set_name_0"` - SetArray []SetBonusItem `eq2:"array,arraysize=NumSets"` - NumItemsInSet uint8 `eq2:"int8,ifvariableset=footer_set_name_0"` - SetItemsArray []SetItemsItem `eq2:"array,arraysize=NumItemsInSet"` - TransmutedFlag uint8 `eq2:"int8"` - Collectable uint8 `eq2:"int8,ifvariablenotset=footer_set_name_0"` - CollectionNeeded uint8 `eq2:"int8,ifvariableset=footer_collectable_0"` - OffersQuest common.EQ2String8 `eq2:"string8"` - PartOfQuest common.EQ2String8 `eq2:"string8"` - OffersQuestColor uint8 `eq2:"int8,ifvariableset=footer_offers_quest_0"` - PartOfQuestColor uint8 `eq2:"int8,ifvariableset=footer_part_of_quest_0"` - UnknownSetData1 uint8 `eq2:"int8,ifvariableset=footer_set_name_0"` - Charges uint8 `eq2:"int8"` - TotalCharges uint16 `eq2:"int16,ifvariableset=footer_charges_0"` - ChargesLeft uint16 `eq2:"int16,ifvariableset=footer_charges_0"` - UnknownSetInfo2 uint8 `eq2:"int8,ifvariableset=footer_set_name_0"` - StatusItem uint8 `eq2:"int8"` - FooterUnknown7 uint8 `eq2:"int8"` - CraftingFlag uint8 `eq2:"int8"` - TransmutedFlagXXX uint8 `eq2:"int8"` - AdornCount uint8 `eq2:"int8,ifvariablenotset=footer_set_name_0"` - AdornArray []AdornItem `eq2:"array,arraysize=AdornCount"` - LockedFlag uint8 `eq2:"int8"` - Name common.EQ2String8 `eq2:"string8"` - Description common.EQ2String16 `eq2:"string16"` -} - -type SubstructItemFooterV1188 struct { - NumEffects uint8 `eq2:"int8,ifvariablenotset=header_info_header_unknown_0_0"` - EffectArray []EffectItemV546 `eq2:"array,arraysize=NumEffects"` - RequiredClasses uint64 `eq2:"int64"` - RecommendedLevel uint8 `eq2:"int8"` - RequiredLevel uint8 `eq2:"int8"` - StackSize uint16 `eq2:"int16"` - AdornSlots []uint8 `eq2:"int8,len=6"` - SetName common.EQ2String8 `eq2:"string8"` - SetBonusListCount uint8 `eq2:"int8,ifvariableset=footer_set_name_0"` - SetBonusListArray []SetBonusItemV1188 `eq2:"array,arraysize=SetBonusListCount"` - NumItemsInSet uint8 `eq2:"int8,ifvariableset=footer_set_name_0"` - SetItemsArray []SetItemsItem `eq2:"array,arraysize=NumItemsInSet"` - TotalSetItemsEquipped uint8 `eq2:"int8,ifvariableset=footer_set_name_0"` - TotalSetItemsInSet uint8 `eq2:"int8,ifvariableset=footer_set_name_0"` - AdornFlag uint8 `eq2:"int8"` - AdornStatsActive uint8 `eq2:"int8,ifvariableset=footer_adorn_flag_0"` - AdornStatsTotal uint8 `eq2:"int8,ifvariableset=footer_adorn_flag_0"` - AdornName common.EQ2String16 `eq2:"string16,ifvariableset=footer_adorn_flag_0"` - NumAdornLevels uint32 `eq2:"int32,ifvariableset=footer_adorn_flag_0"` - AdornStatsUnknown1 uint32 `eq2:"int32,ifvariableset=footer_adorn_flag_0"` - AdornLevelArray []AdornLevelItem `eq2:"array,arraysize=NumAdornLevels"` - FooterUnknown4 uint8 `eq2:"int8"` - FooterUnknown4A uint8 `eq2:"int8,ifvariableset=footer_footer_unknown4_0"` - Collectable uint8 `eq2:"int8,ifvariablenotset=footer_set_name_0"` - CollectionNeeded uint8 `eq2:"int8,ifvariableset=footer_collectable_0"` - OffersQuest common.EQ2String8 `eq2:"string8,ifvariablenotset=footer_set_name_0"` - PartOfQuest common.EQ2String8 `eq2:"string8,ifvariablenotset=footer_set_name_0"` - OffersQuestColor uint8 `eq2:"int8,ifvariableset=footer_offers_quest_0"` - PartOfQuestColor uint8 `eq2:"int8,ifvariableset=footer_part_of_quest_0"` - UnknownSetData1 []uint8 `eq2:"int8,len=2,ifvariableset=footer_set_name_0"` - Charges uint8 `eq2:"int8,ifvariablenotset=footer_set_name_0"` - TotalCharges uint16 `eq2:"int16,ifvariableset=footer_charges_0"` - ChargesLeft uint16 `eq2:"int16,ifvariableset=footer_charges_0"` - UnknownSetInfo2 []uint8 `eq2:"int8,len=3,ifvariableset=footer_set_name_0"` - StatusItem []uint8 `eq2:"int8,len=2"` - CraftingFlag uint8 `eq2:"int8"` - TransmutedFlag uint8 `eq2:"int8"` - AdornCount uint8 `eq2:"int8,ifvariablenotset=footer_set_name_0"` - AdornArray []AdornItemV1188 `eq2:"array,arraysize=AdornCount"` - LockedFlag uint8 `eq2:"int8"` - AccountRestricted uint8 `eq2:"int8"` - FooterUnknown6 uint8 `eq2:"int8"` - Name common.EQ2String8 `eq2:"string8"` - Description common.EQ2String16 `eq2:"string16"` - FooterUnknown7 uint8 `eq2:"int8"` -} - -type SubstructItemFooterV57048 struct { - NumEffects uint8 `eq2:"int8,ifvariablenotset=header_info_header_unknown_0_0"` - EffectArray []EffectItemV546 `eq2:"array,arraysize=NumEffects"` - RequiredClasses uint64 `eq2:"int64"` - RequiredClasses2 uint64 `eq2:"int64"` - RecommendedLevel uint8 `eq2:"int8"` - RequiredLevel uint8 `eq2:"int8"` - StackSize uint16 `eq2:"int16"` - AdornSlots []uint8 `eq2:"int8,len=6"` - SetName common.EQ2String8 `eq2:"string8"` - SetBonusListCount uint8 `eq2:"int8,ifvariableset=footer_set_name_0"` - SetBonusListArray []SetBonusItemV1188 `eq2:"array,arraysize=SetBonusListCount"` - NumItemsInSet uint8 `eq2:"int8,ifvariableset=footer_set_name_0"` - SetItemsArray []SetItemsItem `eq2:"array,arraysize=NumItemsInSet"` - TotalSetItemsEquipped uint8 `eq2:"int8,ifvariableset=footer_set_name_0"` - TotalSetItemsInSet uint8 `eq2:"int8,ifvariableset=footer_set_name_0"` - AdornFlag uint8 `eq2:"int8"` - AdornStatsActive uint8 `eq2:"int8,ifvariableset=footer_adorn_flag_0"` - AdornStatsTotal uint8 `eq2:"int8,ifvariableset=footer_adorn_flag_0"` - AdornName common.EQ2String16 `eq2:"string16,ifvariableset=footer_adorn_flag_0"` - NumAdornLevels uint32 `eq2:"int32,ifvariableset=footer_adorn_flag_0"` - AdornStatsUnknown1 uint32 `eq2:"int32,ifvariableset=footer_adorn_flag_0"` - AdornLevelArray []AdornLevelItem `eq2:"array,arraysize=NumAdornLevels"` - FooterUnknown4 uint8 `eq2:"int8"` - Collectable uint8 `eq2:"int8,ifvariablenotset=footer_set_name_0"` - CollectionNeeded uint8 `eq2:"int8,ifvariableset=footer_collectable_0"` - OffersQuest common.EQ2String8 `eq2:"string8,ifvariablenotset=footer_set_name_0"` - PartOfQuest common.EQ2String8 `eq2:"string8,ifvariablenotset=footer_set_name_0"` - OffersQuestColor uint8 `eq2:"int8,ifvariableset=footer_offers_quest_0"` - PartOfQuestColor uint8 `eq2:"int8,ifvariableset=footer_part_of_quest_0"` - UnknownSetData1 []uint8 `eq2:"int8,len=2,ifvariableset=footer_set_name_0"` - Charges uint8 `eq2:"int8,ifvariablenotset=footer_set_name_0"` - TotalCharges uint16 `eq2:"int16,ifvariableset=footer_charges_0"` - ChargesLeft uint16 `eq2:"int16,ifvariableset=footer_charges_0"` - UnknownSetInfo2 uint8 `eq2:"int8,ifvariableset=footer_set_name_0"` - UnknownSetInfo3 uint8 `eq2:"int8,ifvariableset=footer_set_name_0"` - UnknownSetInfo3A uint32 `eq2:"int32,ifvariableset=footer_unknown_set_info3_0"` - UnknownSetInfo4 uint8 `eq2:"int8,ifvariableset=footer_set_name_0"` - StatusItem []uint8 `eq2:"int8,len=2"` - CraftingFlag uint8 `eq2:"int8"` - TransmutedFlag uint8 `eq2:"int8"` - AdornCount uint8 `eq2:"int8,ifvariablenotset=footer_set_name_0"` - AdornArray []AdornItemV1188 `eq2:"array,arraysize=AdornCount"` - LockedFlag uint8 `eq2:"int8"` - AccountRestricted uint8 `eq2:"int8"` - FooterUnknown6 []uint8 `eq2:"int8,len=13"` - Name common.EQ2String8 `eq2:"string8"` - Description common.EQ2String16 `eq2:"string16"` - FooterUnknown7 uint8 `eq2:"int8"` -} - -type SubstructItemFooterV58571 struct { - NumEffects uint8 `eq2:"int8,ifvariablenotset=header_info_header_unknown_0_0"` - EffectArray []EffectItemV546 `eq2:"array,arraysize=NumEffects"` - RequiredClasses uint64 `eq2:"int64"` - RequiredClasses2 uint64 `eq2:"int64"` - RecommendedLevel uint8 `eq2:"int8"` - RequiredLevel uint8 `eq2:"int8"` - StackSize uint16 `eq2:"int16"` - AdornSlots []uint8 `eq2:"int8,len=11"` - SetName common.EQ2String8 `eq2:"string8"` - SetBonusListCount uint8 `eq2:"int8,ifvariableset=footer_set_name_0"` - SetBonusListArray []SetBonusItemV1188 `eq2:"array,arraysize=SetBonusListCount"` - NumItemsInSet uint8 `eq2:"int8,ifvariableset=footer_set_name_0"` - SetItemsArray []SetItemsItem `eq2:"array,arraysize=NumItemsInSet"` - TotalSetItemsEquipped uint8 `eq2:"int8,ifvariableset=footer_set_name_0"` - TotalSetItemsInSet uint8 `eq2:"int8,ifvariableset=footer_set_name_0"` - AdornFlag uint8 `eq2:"int8"` - AdornStatsActive uint8 `eq2:"int8,ifvariableset=footer_adorn_flag_0"` - AdornStatsTotal uint8 `eq2:"int8,ifvariableset=footer_adorn_flag_0"` - AdornName common.EQ2String16 `eq2:"string16,ifvariableset=footer_adorn_flag_0"` - NumAdornLevels uint32 `eq2:"int32,ifvariableset=footer_adorn_flag_0"` - AdornStatsUnknown1 uint32 `eq2:"int32,ifvariableset=footer_adorn_flag_0"` - AdornLevelArray []AdornLevelItem `eq2:"array,arraysize=NumAdornLevels"` - FooterUnknown4 uint8 `eq2:"int8"` - Collectable uint8 `eq2:"int8,ifvariablenotset=footer_set_name_0"` - CollectionNeeded uint8 `eq2:"int8,ifvariableset=footer_collectable_0"` - OffersQuest common.EQ2String8 `eq2:"string8,ifvariablenotset=footer_set_name_0"` - PartOfQuest common.EQ2String8 `eq2:"string8,ifvariablenotset=footer_set_name_0"` - OffersQuestColor uint8 `eq2:"int8,ifvariableset=footer_offers_quest_0"` - PartOfQuestColor uint8 `eq2:"int8,ifvariableset=footer_part_of_quest_0"` - UnknownSetData1 []uint8 `eq2:"int8,len=2,ifvariableset=footer_set_name_0"` - Charges uint8 `eq2:"int8,ifvariablenotset=footer_set_name_0"` - TotalCharges uint16 `eq2:"int16,ifvariableset=footer_charges_0"` - ChargesLeft uint16 `eq2:"int16,ifvariableset=footer_charges_0"` - UnknownSetInfo2 uint8 `eq2:"int8,ifvariableset=footer_set_name_0"` - UnknownSetInfo3 uint8 `eq2:"int8,ifvariableset=footer_set_name_0"` - UnknownSetInfo3A uint32 `eq2:"int32,ifvariableset=footer_unknown_set_info3_0"` - UnknownSetInfo4 uint8 `eq2:"int8,ifvariableset=footer_set_name_0"` - StatusItem []uint8 `eq2:"int8,len=2"` - CraftingFlag uint8 `eq2:"int8"` - TransmutedFlag uint8 `eq2:"int8"` - AdornCount uint8 `eq2:"int8,ifvariablenotset=footer_set_name_0"` - AdornArray []AdornItemV1188 `eq2:"array,arraysize=AdornCount"` - LockedFlag uint8 `eq2:"int8"` - AccountRestricted uint8 `eq2:"int8"` - FooterUnknown6 []uint8 `eq2:"int8,len=15"` - Name common.EQ2String8 `eq2:"string8"` - Description common.EQ2String16 `eq2:"string16"` - FooterUnknownVer58571 uint8 `eq2:"int8"` -} - -type SubstructItemFooterV58617 struct { - NumEffects uint8 `eq2:"int8,ifvariablenotset=header_info_header_unknown_0_0"` - EffectArray []EffectItemV546 `eq2:"array,arraysize=NumEffects"` - RequiredClasses uint64 `eq2:"int64"` - RequiredClasses2 uint64 `eq2:"int64"` - RecommendedLevel uint8 `eq2:"int8"` - RequiredLevel uint8 `eq2:"int8"` - StackSize uint16 `eq2:"int16"` - AdornSlots []uint8 `eq2:"int8,len=11"` - SetName common.EQ2String8 `eq2:"string8"` - SetBonusListCount uint8 `eq2:"int8,ifvariableset=footer_set_name_0"` - SetBonusListArray []SetBonusItemV1188 `eq2:"array,arraysize=SetBonusListCount"` - NumItemsInSet uint8 `eq2:"int8,ifvariableset=footer_set_name_0"` - SetItemsArray []SetItemsItem `eq2:"array,arraysize=NumItemsInSet"` - TotalSetItemsEquipped uint8 `eq2:"int8,ifvariableset=footer_set_name_0"` - TotalSetItemsInSet uint8 `eq2:"int8,ifvariableset=footer_set_name_0"` - AdornFlag uint8 `eq2:"int8"` - AdornStatsActive uint8 `eq2:"int8,ifvariableset=footer_adorn_flag_0"` - AdornStatsTotal uint8 `eq2:"int8,ifvariableset=footer_adorn_flag_0"` - AdornName common.EQ2String16 `eq2:"string16,ifvariableset=footer_adorn_flag_0"` - NumAdornLevels uint32 `eq2:"int32,ifvariableset=footer_adorn_flag_0"` - AdornStatsUnknown1 uint32 `eq2:"int32,ifvariableset=footer_adorn_flag_0"` - AdornLevelArray []AdornLevelItem `eq2:"array,arraysize=NumAdornLevels"` - FooterUnknown4 uint8 `eq2:"int8"` - Collectable uint8 `eq2:"int8,ifvariablenotset=footer_set_name_0"` - CollectionNeeded uint8 `eq2:"int8,ifvariableset=footer_collectable_0"` - OffersQuest common.EQ2String8 `eq2:"string8,ifvariablenotset=footer_set_name_0"` - PartOfQuest common.EQ2String8 `eq2:"string8,ifvariablenotset=footer_set_name_0"` - OffersQuestColor uint8 `eq2:"int8,ifvariableset=footer_offers_quest_0"` - PartOfQuestColor uint8 `eq2:"int8,ifvariableset=footer_part_of_quest_0"` - UnknownSetData1 []uint8 `eq2:"int8,len=2,ifvariableset=footer_set_name_0"` - Charges uint8 `eq2:"int8"` // Note: XML comment indicates removing ifvariablenotset condition - TotalCharges uint16 `eq2:"int16,ifvariableset=footer_charges_0"` - ChargesLeft uint16 `eq2:"int16,ifvariableset=footer_charges_0"` - UnknownSetInfo2 uint8 `eq2:"int8,ifvariableset=footer_set_name_0"` - UnknownSetInfo3 uint8 `eq2:"int8,ifvariableset=footer_set_name_0"` - UnknownSetInfo3A uint32 `eq2:"int32,ifvariableset=footer_unknown_set_info3_0"` - UnknownSetInfo4 uint8 `eq2:"int8,ifvariableset=footer_set_name_0"` - StatusItem []uint8 `eq2:"int8,len=2"` - CraftingFlag uint8 `eq2:"int8"` - TransmutedFlag uint8 `eq2:"int8"` - Unknown58617_1_MJ uint8 `eq2:"int8"` - AdornCount uint8 `eq2:"int8,ifvariablenotset=footer_set_name_0"` - AdornArray []AdornItemV1188 `eq2:"array,arraysize=AdornCount"` - LockedFlag uint8 `eq2:"int8"` - AccountRestricted uint8 `eq2:"int8"` - FooterUnknown6 []uint8 `eq2:"int8,len=17"` - Name common.EQ2String8 `eq2:"string8"` - Description common.EQ2String16 `eq2:"string16"` - FooterUnknownVer58617 uint8 `eq2:"int8"` -} - -type SubstructItemFooterV60024 struct { - NumEffects uint8 `eq2:"int8,ifvariablenotset=header_info_header_unknown_0_0"` - EffectArray []EffectItemV546 `eq2:"array,arraysize=NumEffects"` - RequiredClasses uint64 `eq2:"int64"` - RequiredClasses2 uint64 `eq2:"int64"` - RecommendedLevel uint8 `eq2:"int8"` - RequiredLevel uint8 `eq2:"int8"` - StackSize uint16 `eq2:"int16"` - AdornSlots []uint8 `eq2:"int8,len=11"` - SetName common.EQ2String8 `eq2:"string8"` - SetBonusListCount uint8 `eq2:"int8,ifvariableset=footer_set_name_0"` - SetBonusListArray []SetBonusItemV1188 `eq2:"array,arraysize=SetBonusListCount"` - NumItemsInSet uint8 `eq2:"int8,ifvariableset=footer_set_name_0"` - SetItemsArray []SetItemsItem `eq2:"array,arraysize=NumItemsInSet"` - TotalSetItemsEquipped uint8 `eq2:"int8,ifvariableset=footer_set_name_0"` - TotalSetItemsInSet uint8 `eq2:"int8,ifvariableset=footer_set_name_0"` - AdornFlag uint8 `eq2:"int8"` - AdornStatsActive uint8 `eq2:"int8,ifvariableset=footer_adorn_flag_0"` - AdornStatsTotal uint8 `eq2:"int8,ifvariableset=footer_adorn_flag_0"` - AdornName common.EQ2String16 `eq2:"string16,ifvariableset=footer_adorn_flag_0"` - NumAdornLevels uint32 `eq2:"int32,ifvariableset=footer_adorn_flag_0"` - AdornStatsUnknown1 uint32 `eq2:"int32,ifvariableset=footer_adorn_flag_0"` - AdornLevelArray []AdornLevelItem `eq2:"array,arraysize=NumAdornLevels"` - FooterUnknown4 uint8 `eq2:"int8"` - Collectable uint8 `eq2:"int8,ifvariablenotset=footer_set_name_0"` - CollectionNeeded uint8 `eq2:"int8,ifvariableset=footer_collectable_0"` - OffersQuest common.EQ2String8 `eq2:"string8,ifvariablenotset=footer_set_name_0"` - PartOfQuest common.EQ2String8 `eq2:"string8,ifvariablenotset=footer_set_name_0"` - OffersQuestColor uint8 `eq2:"int8,ifvariableset=footer_offers_quest_0"` - PartOfQuestColor uint8 `eq2:"int8,ifvariableset=footer_part_of_quest_0"` - UnknownSetData1 []uint8 `eq2:"int8,len=2,ifvariableset=footer_set_name_0"` - Charges uint8 `eq2:"int8,ifvariablenotset=footer_set_name_0"` - TotalCharges uint16 `eq2:"int16,ifvariableset=footer_charges_0"` - ChargesLeft uint16 `eq2:"int16,ifvariableset=footer_charges_0"` - UnknownSetInfo2 uint8 `eq2:"int8,ifvariableset=footer_set_name_0"` - UnknownSetInfo3 uint8 `eq2:"int8,ifvariableset=footer_set_name_0"` - UnknownSetInfo3A uint32 `eq2:"int32,ifvariableset=footer_unknown_set_info3_0"` - UnknownSetInfo4 uint8 `eq2:"int8,ifvariableset=footer_set_name_0"` - StatusItem uint8 `eq2:"int8"` - Unknown60024A uint8 `eq2:"int8"` - Unknown60024B []uint8 `eq2:"int8,len=4,ifvariableset=footer_unknown60024a_0"` - CraftingFlag uint8 `eq2:"int8"` - TransmutedFlag uint8 `eq2:"int8"` - AdornCount uint8 `eq2:"int8,ifvariablenotset=footer_set_name_0"` - AdornArray []AdornItemV1188 `eq2:"array,arraysize=AdornCount"` - LockedFlag uint8 `eq2:"int8"` - AccountRestricted uint8 `eq2:"int8"` - FooterUnknown6 []uint8 `eq2:"int8,len=18"` - Name common.EQ2String8 `eq2:"string8"` - Description common.EQ2String16 `eq2:"string16"` - FooterUnknown7 uint8 `eq2:"int8"` -} - -type SubstructItemFooterV60055 struct { - NumEffects uint8 `eq2:"int8,ifvariablenotset=header_info_header_unknown_0_0"` - EffectArray []EffectItemV546 `eq2:"array,arraysize=NumEffects"` - RequiredClasses uint64 `eq2:"int64"` - RequiredClasses2 uint64 `eq2:"int64"` - RecommendedLevel uint8 `eq2:"int8"` - RequiredLevel uint8 `eq2:"int8"` - StackSize uint16 `eq2:"int16"` - AdornSlots []uint8 `eq2:"int8,len=11"` - SetName common.EQ2String8 `eq2:"string8"` - SetBonusListCount uint8 `eq2:"int8,ifvariableset=footer_set_name_0"` - SetBonusListArray []SetBonusItemV1188 `eq2:"array,arraysize=SetBonusListCount"` - NumItemsInSet uint8 `eq2:"int8,ifvariableset=footer_set_name_0"` - SetItemsArray []SetItemsItem `eq2:"array,arraysize=NumItemsInSet"` - TotalSetItemsEquipped uint8 `eq2:"int8,ifvariableset=footer_set_name_0"` - TotalSetItemsInSet uint8 `eq2:"int8,ifvariableset=footer_set_name_0"` - AdornFlag uint8 `eq2:"int8"` - AdornStatsActive uint8 `eq2:"int8,ifvariableset=footer_adorn_flag_0"` - AdornStatsTotal uint8 `eq2:"int8,ifvariableset=footer_adorn_flag_0"` - AdornName common.EQ2String16 `eq2:"string16,ifvariableset=footer_adorn_flag_0"` - NumAdornLevels uint32 `eq2:"int32,ifvariableset=footer_adorn_flag_0"` - AdornStatsUnknown1 uint32 `eq2:"int32,ifvariableset=footer_adorn_flag_0"` - AdornLevelArray []AdornLevelItem `eq2:"array,arraysize=NumAdornLevels"` - FooterUnknown4 uint8 `eq2:"int8"` - Unknown60055ZA uint8 `eq2:"int8,ifvariablenotset=footer_set_name_0"` - Collectable uint8 `eq2:"int8,ifvariablenotset=footer_set_name_0"` - CollectionNeeded uint8 `eq2:"int8,ifvariableset=footer_collectable_0"` - Unknown60055Z uint8 `eq2:"int8,ifvariablenotset=footer_set_name_0"` - OffersQuest common.EQ2String8 `eq2:"string8,ifvariablenotset=footer_set_name_0"` - PartOfQuest common.EQ2String8 `eq2:"string8,ifvariablenotset=footer_set_name_0"` - OffersQuestColor uint8 `eq2:"int8,ifvariableset=footer_offers_quest_0"` - PartOfQuestColor uint8 `eq2:"int8,ifvariableset=footer_part_of_quest_0"` - UnknownSetData1 []uint8 `eq2:"int8,len=2,ifvariableset=footer_set_name_0"` - Charges uint8 `eq2:"int8,ifvariablenotset=footer_set_name_0"` - TotalCharges uint16 `eq2:"int16,ifvariableset=footer_charges_0"` - ChargesLeft uint16 `eq2:"int16,ifvariableset=footer_charges_0"` - UnknownSetInfo2 uint8 `eq2:"int8,ifvariableset=footer_set_name_0"` - UnknownSetInfo3 uint8 `eq2:"int8,ifvariableset=footer_set_name_0"` - UnknownSetInfo3A uint32 `eq2:"int32,ifvariableset=footer_unknown_set_info3_0"` - UnknownSetInfo4 uint8 `eq2:"int8,ifvariableset=footer_set_name_0"` - UnknownEmem1 uint8 `eq2:"int8"` - UnknownEmem2 uint8 `eq2:"int8"` - UnknownEmem3 uint8 `eq2:"int8"` - UnknownEmem4 uint8 `eq2:"int8"` - StatusItem uint32 `eq2:"int32"` - CraftingFlag uint8 `eq2:"int8"` - TransmutedFlag uint8 `eq2:"int8"` - AdornCount uint8 `eq2:"int8,ifvariablenotset=footer_set_name_0"` - AdornArray []AdornItemV1188 `eq2:"array,arraysize=AdornCount"` - LockedFlag uint8 `eq2:"int8"` - AccountRestricted uint8 `eq2:"int8"` - FooterUnknown6A uint8 `eq2:"int8"` - FooterUnknown6B uint8 `eq2:"int8"` - FooterUnknown6C uint8 `eq2:"int8"` - FooterUnknown6D uint8 `eq2:"int8"` - FooterUnknown6E uint8 `eq2:"int8"` - FooterUnknown6F uint8 `eq2:"int8"` - FooterUnknown6G uint8 `eq2:"int8"` - FooterUnknown6H uint8 `eq2:"int8"` - FooterUnknown6I uint8 `eq2:"int8"` - FooterUnknown6J uint8 `eq2:"int8"` - FooterUnknown6K uint8 `eq2:"int8"` - FooterUnknown6L uint8 `eq2:"int8"` - FooterUnknown6M uint8 `eq2:"int8"` - FooterUnknown6N uint8 `eq2:"int8"` - FooterUnknown6O uint8 `eq2:"int8"` - FooterUnknown6 []uint8 `eq2:"int8,len=2"` - Name common.EQ2String8 `eq2:"string8"` - Description common.EQ2String16 `eq2:"string16"` - FooterUnknown7 uint8 `eq2:"int8"` -} - -type SubstructItemFooterV60174 struct { - NumEffects uint8 `eq2:"int8,ifvariablenotset=header_info_header_unknown_0_0"` - EffectArray []EffectItemV546 `eq2:"array,arraysize=NumEffects"` - FooterUnknown2 uint8 `eq2:"int8"` - RequiredClasses uint64 `eq2:"int64"` - RequiredClasses2 uint64 `eq2:"int64"` - RecommendedLevel uint8 `eq2:"int8"` - RequiredLevel uint8 `eq2:"int8"` - StackSize uint16 `eq2:"int16"` - AdornSlots []uint8 `eq2:"int8,len=11"` - SetName common.EQ2String8 `eq2:"string8"` - SetBonusListCount uint8 `eq2:"int8,ifvariableset=footer_set_name_0"` - SetBonusListArray []SetBonusItemV1188 `eq2:"array,arraysize=SetBonusListCount"` - NumItemsInSet uint8 `eq2:"int8,ifvariableset=footer_set_name_0"` - SetItemsArray []SetItemsItem `eq2:"array,arraysize=NumItemsInSet"` - TotalSetItemsEquipped uint8 `eq2:"int8,ifvariableset=footer_set_name_0"` - TotalSetItemsInSet uint8 `eq2:"int8,ifvariableset=footer_set_name_0"` - AdornFlag uint8 `eq2:"int8"` - AdornStatsActive uint8 `eq2:"int8,ifvariableset=footer_adorn_flag_0"` - AdornStatsTotal uint8 `eq2:"int8,ifvariableset=footer_adorn_flag_0"` - AdornName common.EQ2String16 `eq2:"string16,ifvariableset=footer_adorn_flag_0"` - NumAdornLevels uint32 `eq2:"int32,ifvariableset=footer_adorn_flag_0"` - AdornStatsUnknown1 uint32 `eq2:"int32,ifvariableset=footer_adorn_flag_0"` - AdornLevelArray []AdornLevelItem `eq2:"array,arraysize=NumAdornLevels"` - FooterUnknown4 uint8 `eq2:"int8"` - Unknown60055ZA uint8 `eq2:"int8,ifvariablenotset=footer_set_name_0"` - Collectable uint8 `eq2:"int8,ifvariablenotset=footer_set_name_0"` - CollectionNeeded uint8 `eq2:"int8,ifvariableset=footer_collectable_0"` - Unknown60055Z uint8 `eq2:"int8,ifvariablenotset=footer_set_name_0"` - OffersQuest common.EQ2String8 `eq2:"string8,ifvariablenotset=footer_set_name_0"` - PartOfQuest common.EQ2String8 `eq2:"string8,ifvariablenotset=footer_set_name_0"` - OffersQuestColor uint8 `eq2:"int8,ifvariableset=footer_offers_quest_0"` - PartOfQuestColor uint8 `eq2:"int8,ifvariableset=footer_part_of_quest_0"` - UnknownSetData1 []uint8 `eq2:"int8,len=2,ifvariableset=footer_set_name_0"` - Charges uint8 `eq2:"int8,ifvariablenotset=footer_set_name_0"` - TotalCharges uint16 `eq2:"int16,ifvariableset=footer_charges_0"` - ChargesLeft uint16 `eq2:"int16,ifvariableset=footer_charges_0"` - UnknownSetInfo2 uint8 `eq2:"int8,ifvariableset=footer_set_name_0"` - UnknownSetInfo3 uint8 `eq2:"int8,ifvariableset=footer_set_name_0"` - UnknownSetInfo3A uint32 `eq2:"int32,ifvariableset=footer_unknown_set_info3_0"` - UnknownSetInfo4 uint8 `eq2:"int8,ifvariableset=footer_set_name_0"` - StatusItem uint32 `eq2:"int32"` - Unknown60024A uint8 `eq2:"int8"` - TransmutedFlag uint8 `eq2:"int8"` - AdornCount uint8 `eq2:"int8,ifvariablenotset=footer_set_name_0"` - AdornArray []AdornItemV1188 `eq2:"array,arraysize=AdornCount"` - LockedFlag uint8 `eq2:"int8"` - AccountRestricted uint8 `eq2:"int8"` - FooterUnknown6A uint8 `eq2:"int8"` - CraftingFlag uint8 `eq2:"int8"` - FooterUnknown6B []uint8 `eq2:"int8,len=21"` - Name common.EQ2String8 `eq2:"string8"` - Description common.EQ2String16 `eq2:"string16"` - FooterUnknown7 uint8 `eq2:"int8"` -} - -type SubstructItemFooterV63119 struct { - NumEffects uint8 `eq2:"int8,ifvariablenotset=header_info_header_unknown_0_0"` - EffectArray []EffectItemV546 `eq2:"array,arraysize=NumEffects"` - Tierline uint8 `eq2:"int8"` - TierlineArray []TierlineItem `eq2:"array,arraysize=Tierline"` - RequiredClasses uint64 `eq2:"int64"` - RequiredClasses2 uint64 `eq2:"int64"` - RecommendedLevel uint8 `eq2:"int8"` - RequiredLevel uint8 `eq2:"int8"` - StackSize uint16 `eq2:"int16"` - AdornSlots []uint8 `eq2:"int8,len=11"` - FooterUnknown3MJ1 uint8 `eq2:"int8"` - SetName common.EQ2String8 `eq2:"string8"` - SetBonusListCount uint8 `eq2:"int8,ifvariableset=footer_set_name_0"` - SetBonusListArray []SetBonusItemV63119 `eq2:"array,arraysize=SetBonusListCount"` - NumItemsInSet uint8 `eq2:"int8,ifvariableset=footer_set_name_0"` - SetItemsArray []SetItemsItem `eq2:"array,arraysize=NumItemsInSet"` - TotalSetItemsEquipped uint8 `eq2:"int8,ifvariableset=footer_set_name_0"` - TotalSetItemsInSet uint8 `eq2:"int8,ifvariableset=footer_set_name_0"` - AdornFlag uint8 `eq2:"int8"` - AdornUnknown64A uint8 `eq2:"int8,ifvariableset=footer_adorn_flag_0"` - AdornUnknown64B uint8 `eq2:"int8,ifvariableset=footer_adorn_flag_0"` - AdornStatsActive uint8 `eq2:"int8,ifvariableset=footer_adorn_flag_0"` - AdornStatsTotal uint8 `eq2:"int8,ifvariableset=footer_adorn_flag_0"` - AdornName common.EQ2String16 `eq2:"string16,ifvariableset=footer_adorn_flag_0"` - NumAdornLevels uint32 `eq2:"int32,ifvariableset=footer_adorn_flag_0"` - AdornStatsUnknown1 uint32 `eq2:"int32,ifvariableset=footer_adorn_flag_0"` - AdornLevelArray []AdornLevelItemV63119 `eq2:"array,arraysize=NumAdornLevels"` - FooterUnknown4 uint8 `eq2:"int8"` - Unknown60055ZA uint8 `eq2:"int8,ifvariableset=foot_set_name_0"` - Collectable uint8 `eq2:"int8"` - CollectionNeeded uint8 `eq2:"int8,ifvariableset=footer_collectable_0"` - Unknown60055Z uint8 `eq2:"int8"` - OffersQuest common.EQ2String8 `eq2:"string8"` - PartOfQuest common.EQ2String8 `eq2:"string8"` - OffersQuestColor uint8 `eq2:"int8,ifvariableset=footer_offers_quest_0"` - PartOfQuestColor uint8 `eq2:"int8,ifvariableset=footer_part_of_quest_0"` - UnknownSetData1 []uint8 `eq2:"int8,len=2,ifvariableset=footer_set_name_0"` - Charges uint8 `eq2:"int8"` - TotalCharges uint16 `eq2:"int16,ifvariableset=footer_charges_0"` - ChargesLeft uint16 `eq2:"int16,ifvariableset=footer_charges_0"` - UnknownSetInfo2 uint8 `eq2:"int8,ifvariableset=footer_set_name_0"` - UnknownSetInfo3 uint8 `eq2:"int8,ifvariableset=footer_set_name_0"` - UnknownSetInfo3A uint32 `eq2:"int32,ifvariableset=footer_unknown_set_info3_0"` - UnknownSetInfo4 uint8 `eq2:"int8,ifvariableset=footer_set_name_0"` - UnknownEmem1 []uint8 `eq2:"int8,len=4"` - StatusItem uint32 `eq2:"int32"` - Unknown60024B uint8 `eq2:"int8"` - TransmutedFlag uint8 `eq2:"int8"` - UnknownMJ38A uint8 `eq2:"int8"` - UnknownMJ38B uint8 `eq2:"int8"` - CraftingFlag uint8 `eq2:"int8"` - UnknownMJ38D uint8 `eq2:"int8"` - AdornCount uint8 `eq2:"int8"` - AdornArray []AdornItemV63119 `eq2:"array,arraysize=AdornCount"` - LockedFlag uint8 `eq2:"int8"` - UnknownMJ38C uint8 `eq2:"int8"` - AccountRestricted uint8 `eq2:"int8"` - FooterUnknown6B []uint8 `eq2:"int8,len=7"` - FooterUnknown6C uint32 `eq2:"int32,ifvariablenotset=footer_set_name_0"` - FooterUnknown6D uint8 `eq2:"int8,ifvariablenotset=footer_set_name_0"` - Name common.EQ2String8 `eq2:"string8"` - Description common.EQ2String16 `eq2:"string16"` - FooterUnknown7 uint8 `eq2:"int8"` -} diff --git a/internal/packets/substructs/ItemInfo.go b/internal/packets/substructs/ItemInfo.go deleted file mode 100644 index 5cf201d..0000000 --- a/internal/packets/substructs/ItemInfo.go +++ /dev/null @@ -1,12 +0,0 @@ -package substructs - -// ItemInfo Version 63119 -type ItemInfo struct { - NumItems uint16 `eq2:"int16"` - ItemsArray []ItemIndex `eq2:"array,arraysize=NumItems"` -} - -type ItemIndex struct { - ItemIndex uint16 `eq2:"int16"` - TabUnknown2 uint32 `eq2:"int32"` -}