bring in more common types from emu
This commit is contained in:
parent
d337309b17
commit
9c35904ecf
@ -2,32 +2,33 @@ package common
|
||||
|
||||
type EQ2DataType int
|
||||
|
||||
// Constants matching data_struct.hpp exactly
|
||||
const (
|
||||
TypeUint8 EQ2DataType = iota
|
||||
TypeUint16
|
||||
TypeUint32
|
||||
TypeUint64
|
||||
TypeNone EQ2DataType = iota
|
||||
TypeInt8
|
||||
TypeInt16
|
||||
TypeInt32
|
||||
TypeInt64
|
||||
TypeChar
|
||||
TypeFloat
|
||||
TypeDouble
|
||||
TypeColor
|
||||
TypeSInt8
|
||||
TypeSInt16
|
||||
TypeSInt32
|
||||
TypeChar
|
||||
TypeString8
|
||||
TypeString16
|
||||
TypeString32
|
||||
TypeColor
|
||||
TypeEquipment
|
||||
TypeItem
|
||||
TypeArray
|
||||
TypeItem
|
||||
TypeSInt64
|
||||
)
|
||||
|
||||
// Core EQ2 structures
|
||||
type EQ2Color struct {
|
||||
Red uint8
|
||||
Green uint8
|
||||
Blue uint8
|
||||
Red int8
|
||||
Green int8
|
||||
Blue int8
|
||||
}
|
||||
|
||||
type EQ2EquipmentItem struct {
|
||||
@ -37,16 +38,189 @@ type EQ2EquipmentItem struct {
|
||||
}
|
||||
|
||||
type EQ2String8 struct {
|
||||
Size uint8
|
||||
Size int8
|
||||
Data string
|
||||
}
|
||||
|
||||
type EQ2String16 struct {
|
||||
Size uint16
|
||||
Size int16
|
||||
Data string
|
||||
}
|
||||
|
||||
type EQ2String32 struct {
|
||||
Size uint32
|
||||
Size int32
|
||||
Data string
|
||||
}
|
||||
|
||||
const (
|
||||
SlotPrimary = iota
|
||||
SlotSecondary
|
||||
SlotHead
|
||||
SlotChest
|
||||
SlotShoulders
|
||||
SlotForearms
|
||||
SlotHands
|
||||
SlotLegs
|
||||
SlotFeet
|
||||
SlotLeftRing
|
||||
SlotRightRing
|
||||
SlotEars
|
||||
SlotNeck
|
||||
SlotLeftWrist
|
||||
SlotRightWrist
|
||||
SlotRanged
|
||||
SlotAmmo
|
||||
SlotWaist
|
||||
SlotActivate1
|
||||
SlotActivate2
|
||||
SlotTextures
|
||||
SlotHair
|
||||
SlotBeard
|
||||
SlotNakedChest
|
||||
SlotNakedLegs
|
||||
)
|
||||
|
||||
type EQ2Equipment struct {
|
||||
EquipID [25]int16 // Equipment item IDs for each slot
|
||||
Color [25]EQ2Color // Primary colors for each equipment slot
|
||||
Highlight [25]EQ2Color // Highlight colors for each equipment slot
|
||||
}
|
||||
|
||||
type CharFeatures struct {
|
||||
HairType int16 // Hair style type
|
||||
HairFaceType int16 // Facial hair type
|
||||
WingType int16 // Wing type (for races with wings)
|
||||
ChestType int16 // Chest appearance type
|
||||
LegsType int16 // Leg appearance type
|
||||
EyeType [3]int8 // Eye shape variations
|
||||
EarType [3]int8 // Ear shape variations
|
||||
EyeBrowType [3]int8 // Eyebrow shape variations
|
||||
CheekType [3]int8 // Cheek shape variations
|
||||
LipType [3]int8 // Lip shape variations
|
||||
ChinType [3]int8 // Chin shape variations
|
||||
NoseType [3]int8 // Nose shape variations
|
||||
BodySize int8 // Body size modifier
|
||||
BodyAge int8 // Body age appearance
|
||||
SogaEyeType [3]int8 // SOGA eye shape variations
|
||||
SogaEarType [3]int8 // SOGA ear shape variations
|
||||
SogaEyeBrowType [3]int8 // SOGA eyebrow shape variations
|
||||
SogaCheekType [3]int8 // SOGA cheek shape variations
|
||||
SogaChestType int16 // SOGA chest appearance type
|
||||
SogaLegsType int16 // SOGA leg appearance type
|
||||
SogaLipType [3]int8 // SOGA lip shape variations
|
||||
SogaChinType [3]int8 // SOGA chin shape variations
|
||||
SogaNoseType [3]int8 // SOGA nose shape variations
|
||||
SogaBodySize int8 // SOGA body size modifier
|
||||
SogaBodyAge int8 // SOGA body age appearance
|
||||
SogaHairType int16 // SOGA hair style type
|
||||
SogaHairFaceType int16 // SOGA facial hair type
|
||||
CombatVoice int16 // Combat voice type
|
||||
EmoteVoice int16 // Emote voice type
|
||||
MountModelType int16 // Mount model type
|
||||
|
||||
MountSaddleColor EQ2Color // Mount saddle color
|
||||
MountColor EQ2Color // Mount body color
|
||||
SkinColor EQ2Color // Skin color
|
||||
EyeColor EQ2Color // Eye color
|
||||
HairTypeColor EQ2Color // Primary hair color
|
||||
HairTypeHighlightColor EQ2Color // Hair highlight color
|
||||
HairFaceColor EQ2Color // Facial hair color
|
||||
HairFaceHighlightColor EQ2Color // Facial hair highlight color
|
||||
HairHighlightColor EQ2Color // Hair highlight color
|
||||
WingColor1 EQ2Color // Wing primary color
|
||||
WingColor2 EQ2Color // Wing secondary color
|
||||
ShirtColor EQ2Color // Shirt color
|
||||
PantsColor EQ2Color // Pants color
|
||||
HairColor1 EQ2Color // Hair primary color
|
||||
HairColor2 EQ2Color // Hair secondary color
|
||||
SogaSkinColor EQ2Color // SOGA skin color
|
||||
SogaEyeColor EQ2Color // SOGA eye color
|
||||
SogaHairColor1 EQ2Color // SOGA hair primary color
|
||||
SogaHairColor2 EQ2Color // SOGA hair secondary color
|
||||
SogaHairTypeColor EQ2Color // SOGA primary hair color
|
||||
SogaHairTypeHighlightColor EQ2Color // SOGA hair highlight color
|
||||
SogaHairFaceColor EQ2Color // SOGA facial hair color
|
||||
SogaHairFaceHighlightColor EQ2Color // SOGA facial hair highlight color
|
||||
SogaHairHighlightColor EQ2Color // SOGA hair highlight color
|
||||
ModelColor EQ2Color // Model color
|
||||
SogaModelColor EQ2Color // SOGA model color
|
||||
}
|
||||
|
||||
type PositionData struct {
|
||||
GridID int32 // Current grid identifier
|
||||
BadGridID int32 // Invalid grid identifier
|
||||
Speed1 int8 // Primary speed value
|
||||
Speed2 int8 // Secondary speed value
|
||||
Dir1 int16 // Primary direction
|
||||
Dir2 int16 // Secondary direction
|
||||
Pitch1 int16 // Primary pitch angle
|
||||
Pitch2 int16 // Secondary pitch angle
|
||||
Roll int16 // Roll angle
|
||||
X float32 // X coordinate
|
||||
Y float32 // Y coordinate
|
||||
Z float32 // Z coordinate
|
||||
X2 float32 // Secondary X coordinate
|
||||
Y2 float32 // Secondary Y coordinate
|
||||
Z2 float32 // Secondary Z coordinate
|
||||
X3 float32 // Tertiary X coordinate
|
||||
Y3 float32 // Tertiary Y coordinate
|
||||
Z3 float32 // Tertiary Z coordinate
|
||||
SpawnOrigX float32 // Original spawn X coordinate
|
||||
SpawnOrigY float32 // Original spawn Y coordinate
|
||||
SpawnOrigZ float32 // Original spawn Z coordinate
|
||||
SpawnOrigHeading float32 // Original spawn heading
|
||||
SpawnOrigPitch float32 // Original spawn pitch
|
||||
SpawnOrigRoll float32 // Original spawn roll
|
||||
SpeedX float32 // X-axis speed
|
||||
SpeedY float32 // Y-axis speed
|
||||
SpeedZ float32 // Z-axis speed
|
||||
SideSpeed float32 // Lateral movement speed
|
||||
VertSpeed float32 // Vertical movement speed
|
||||
ClientHeading1 float32 // Client-side heading (primary)
|
||||
ClientHeading2 float32 // Client-side heading (secondary)
|
||||
ClientPitch float32 // Client-side pitch
|
||||
CollisionRadius int16 // Collision detection radius
|
||||
State int16 // Current movement state
|
||||
}
|
||||
|
||||
type AppearanceData struct {
|
||||
Pos PositionData // Position and movement data
|
||||
ModelType int16 // 3D model type identifier
|
||||
SogaModelType int16 // SOGA model type identifier
|
||||
ActivityStatus int16 // Current activity status
|
||||
VisualState int16 // Visual state flags
|
||||
ActionState int16 // Action state flags
|
||||
MoodState int16 // Mood/emotion state
|
||||
EmoteState int16 // Current emote state
|
||||
Attackable int8 // Whether entity can be attacked
|
||||
Icon int8 // Icon type to display
|
||||
HideHood int8 // Whether to hide hood graphics
|
||||
ShowLevel int8 // Whether to show level
|
||||
LockedNoLoot int8 // Locked status with no loot
|
||||
QuestFlag int8 // Quest-related flag
|
||||
HeroicFlag int8 // Heroic opportunity flag
|
||||
ShowCommandIcon int8 // Whether to show command icon
|
||||
DisplayHandIcon int8 // Whether to show hand cursor icon
|
||||
PlayerFlag int8 // Player character flag
|
||||
Targetable int8 // Whether entity can be targeted
|
||||
DisplayName int8 // Whether to display name
|
||||
SubTitle [255]byte // Subtitle text (Guild name)
|
||||
DisplayHP int32 // Health percentage (0 = 100%)
|
||||
PowerLeft int32 // Power remaining (bar hidden if >=100)
|
||||
AdventureClass int8 // Adventure class identifier
|
||||
TradeskillClass int8 // Tradeskill class identifier
|
||||
Level int8 // Character level
|
||||
TradeskillLevel int8 // Tradeskill level
|
||||
MinLevel int8 // Minimum level for encounters
|
||||
MaxLevel int8 // Maximum level for encounters
|
||||
Difficulty int8 // Encounter difficulty rating
|
||||
Visible int16 // Visibility state (02 = normal, 15 = shadow)
|
||||
Name [128]byte // Entity name
|
||||
LastName [64]byte // Last name (for players)
|
||||
PrefixTitle [128]byte // Title prefix
|
||||
SuffixTitle [128]byte // Title suffix
|
||||
Race int8 // Race identifier
|
||||
Gender int8 // Gender identifier
|
||||
Randomize int32 // Randomization seed
|
||||
LuaRaceID int8 // Lua script race identifier
|
||||
}
|
||||
|
@ -26,6 +26,7 @@ func NewContext(data []byte, version uint32, flags uint64) *ParseContext {
|
||||
}
|
||||
}
|
||||
|
||||
// Unsigned integer readers
|
||||
func (ctx *ParseContext) readUint8() uint8 {
|
||||
val := ctx.data[ctx.offset]
|
||||
ctx.offset++
|
||||
@ -50,6 +51,32 @@ func (ctx *ParseContext) readUint64() uint64 {
|
||||
return val
|
||||
}
|
||||
|
||||
// Signed integer readers
|
||||
func (ctx *ParseContext) readSint8() int8 {
|
||||
val := int8(ctx.data[ctx.offset])
|
||||
ctx.offset++
|
||||
return val
|
||||
}
|
||||
|
||||
func (ctx *ParseContext) readSint16() int16 {
|
||||
val := int16(binary.LittleEndian.Uint16(ctx.data[ctx.offset:]))
|
||||
ctx.offset += 2
|
||||
return val
|
||||
}
|
||||
|
||||
func (ctx *ParseContext) readSint32() int32 {
|
||||
val := int32(binary.LittleEndian.Uint32(ctx.data[ctx.offset:]))
|
||||
ctx.offset += 4
|
||||
return val
|
||||
}
|
||||
|
||||
func (ctx *ParseContext) readSint64() int64 {
|
||||
val := int64(binary.LittleEndian.Uint64(ctx.data[ctx.offset:]))
|
||||
ctx.offset += 8
|
||||
return val
|
||||
}
|
||||
|
||||
// Oversized readers
|
||||
func (ctx *ParseContext) readOversizedUint8(threshold int) uint8 {
|
||||
if ctx.data[ctx.offset] == byte(threshold) {
|
||||
ctx.offset++
|
||||
@ -74,22 +101,17 @@ func (ctx *ParseContext) readOversizedUint32(threshold int) uint32 {
|
||||
return uint32(ctx.readUint16())
|
||||
}
|
||||
|
||||
func (ctx *ParseContext) readString8() string {
|
||||
length := ctx.readUint8()
|
||||
str := string(ctx.data[ctx.offset : ctx.offset+int(length)])
|
||||
ctx.offset += int(length)
|
||||
return str
|
||||
func (ctx *ParseContext) readOversizedSint16(threshold int) int16 {
|
||||
val := int8(ctx.data[ctx.offset])
|
||||
if val == int8(threshold) || val == int8(-threshold) {
|
||||
ctx.offset++
|
||||
return ctx.readSint16()
|
||||
}
|
||||
|
||||
func (ctx *ParseContext) readString16() string {
|
||||
length := ctx.readUint16()
|
||||
str := string(ctx.data[ctx.offset : ctx.offset+int(length)])
|
||||
ctx.offset += int(length)
|
||||
return str
|
||||
return int16(ctx.readSint8())
|
||||
}
|
||||
|
||||
func (ctx *ParseContext) readEQ2String8() common.EQ2String8 {
|
||||
size := ctx.readUint8()
|
||||
size := ctx.readSint8()
|
||||
data := string(ctx.data[ctx.offset : ctx.offset+int(size)])
|
||||
ctx.offset += int(size)
|
||||
return common.EQ2String8{
|
||||
@ -99,7 +121,7 @@ func (ctx *ParseContext) readEQ2String8() common.EQ2String8 {
|
||||
}
|
||||
|
||||
func (ctx *ParseContext) readEQ2String16() common.EQ2String16 {
|
||||
size := ctx.readUint16()
|
||||
size := ctx.readSint16()
|
||||
data := string(ctx.data[ctx.offset : ctx.offset+int(size)])
|
||||
ctx.offset += int(size)
|
||||
return common.EQ2String16{
|
||||
@ -109,7 +131,7 @@ func (ctx *ParseContext) readEQ2String16() common.EQ2String16 {
|
||||
}
|
||||
|
||||
func (ctx *ParseContext) readEQ2String32() common.EQ2String32 {
|
||||
size := ctx.readUint32()
|
||||
size := ctx.readSint32()
|
||||
data := string(ctx.data[ctx.offset : ctx.offset+int(size)])
|
||||
ctx.offset += int(size)
|
||||
return common.EQ2String32{
|
||||
@ -120,9 +142,9 @@ func (ctx *ParseContext) readEQ2String32() common.EQ2String32 {
|
||||
|
||||
func (ctx *ParseContext) readEQ2Color() common.EQ2Color {
|
||||
return common.EQ2Color{
|
||||
Red: ctx.readUint8(),
|
||||
Green: ctx.readUint8(),
|
||||
Blue: ctx.readUint8(),
|
||||
Red: ctx.readSint8(),
|
||||
Green: ctx.readSint8(),
|
||||
Blue: ctx.readSint8(),
|
||||
}
|
||||
}
|
||||
|
||||
@ -326,7 +348,7 @@ func (ctx *ParseContext) evaluateComparison(varName, valueStr, op string) bool {
|
||||
func (ctx *ParseContext) hasVar(name string) bool {
|
||||
if val, exists := ctx.vars[name]; exists {
|
||||
switch v := val.(type) {
|
||||
case uint8, uint16, uint32, uint64:
|
||||
case uint8, uint16, uint32, uint64, int8, int16, int32, int64:
|
||||
return ctx.getVarValue(name) != 0
|
||||
case string:
|
||||
return v != ""
|
||||
@ -354,6 +376,14 @@ func (ctx *ParseContext) getVarValue(name string) uint64 {
|
||||
return uint64(v)
|
||||
case uint64:
|
||||
return v
|
||||
case int8:
|
||||
return uint64(v)
|
||||
case int16:
|
||||
return uint64(v)
|
||||
case int32:
|
||||
return uint64(v)
|
||||
case int64:
|
||||
return uint64(v)
|
||||
}
|
||||
}
|
||||
return 0
|
||||
|
@ -55,16 +55,16 @@ type Parser struct {
|
||||
fieldNames []string
|
||||
}
|
||||
|
||||
// Type mapping for efficient lookup
|
||||
// Type mapping using corrected type constants
|
||||
var typeMap = map[string]common.EQ2DataType{
|
||||
"u8": common.TypeUint8,
|
||||
"u16": common.TypeUint16,
|
||||
"u32": common.TypeUint32,
|
||||
"u64": common.TypeUint64,
|
||||
"i8": common.TypeInt8,
|
||||
"i16": common.TypeInt16,
|
||||
"i32": common.TypeInt32,
|
||||
"i64": common.TypeInt64,
|
||||
"u8": common.TypeInt8,
|
||||
"u16": common.TypeInt16,
|
||||
"u32": common.TypeInt32,
|
||||
"u64": common.TypeInt64,
|
||||
"i8": common.TypeSInt8,
|
||||
"i16": common.TypeSInt16,
|
||||
"i32": common.TypeSInt32,
|
||||
"i64": common.TypeSInt64,
|
||||
"f32": common.TypeFloat,
|
||||
"f64": common.TypeDouble,
|
||||
"double": common.TypeDouble,
|
||||
@ -151,24 +151,24 @@ func getDataType(tag string) (common.EQ2DataType, bool) {
|
||||
case 'u':
|
||||
switch tag {
|
||||
case "u8":
|
||||
return common.TypeUint8, true
|
||||
return common.TypeInt8, true
|
||||
case "u16":
|
||||
return common.TypeUint16, true
|
||||
return common.TypeInt16, true
|
||||
case "u32":
|
||||
return common.TypeUint32, true
|
||||
return common.TypeInt32, true
|
||||
case "u64":
|
||||
return common.TypeUint64, true
|
||||
return common.TypeInt64, true
|
||||
}
|
||||
case 'i':
|
||||
switch tag {
|
||||
case "i8":
|
||||
return common.TypeInt8, true
|
||||
return common.TypeSInt8, true
|
||||
case "i16":
|
||||
return common.TypeInt16, true
|
||||
return common.TypeSInt16, true
|
||||
case "i32":
|
||||
return common.TypeInt32, true
|
||||
return common.TypeSInt32, true
|
||||
case "i64":
|
||||
return common.TypeInt64, true
|
||||
return common.TypeSInt64, true
|
||||
}
|
||||
case 's':
|
||||
switch tag {
|
||||
|
@ -47,23 +47,34 @@ func (def *PacketDef) parseStruct(ctx *ParseContext) (map[string]any, error) {
|
||||
|
||||
func (def *PacketDef) parseField(ctx *ParseContext, field FieldDesc, fieldType common.EQ2DataType, fieldName string) any {
|
||||
switch fieldType {
|
||||
case common.TypeInt8, common.TypeUint8:
|
||||
case common.TypeInt8:
|
||||
if field.Oversized > 0 {
|
||||
return ctx.readOversizedUint8(field.Oversized)
|
||||
}
|
||||
return ctx.readUint8()
|
||||
case common.TypeInt16, common.TypeUint16:
|
||||
case common.TypeInt16:
|
||||
if field.Oversized > 0 {
|
||||
return ctx.readOversizedUint16(field.Oversized)
|
||||
}
|
||||
return ctx.readUint16()
|
||||
case common.TypeInt32, common.TypeUint32:
|
||||
case common.TypeInt32:
|
||||
if field.Oversized > 0 {
|
||||
return ctx.readOversizedUint32(field.Oversized)
|
||||
}
|
||||
return ctx.readUint32()
|
||||
case common.TypeInt64, common.TypeUint64:
|
||||
case common.TypeInt64:
|
||||
return ctx.readUint64()
|
||||
case common.TypeSInt8:
|
||||
return ctx.readSint8()
|
||||
case common.TypeSInt16:
|
||||
if field.Oversized > 0 {
|
||||
return ctx.readOversizedSint16(field.Oversized)
|
||||
}
|
||||
return ctx.readSint16()
|
||||
case common.TypeSInt32:
|
||||
return ctx.readSint32()
|
||||
case common.TypeSInt64:
|
||||
return ctx.readSint64()
|
||||
case common.TypeString8:
|
||||
return ctx.readEQ2String8()
|
||||
case common.TypeString16:
|
||||
|
Loading…
x
Reference in New Issue
Block a user