Golang中resp.Insert操作问题求解
Golang中resp.Insert操作问题求解 你好,
我正在开发一款游戏,遇到了一个问题。 我找不到索引插入的顺序,过去一周这让我非常困扰。 请提供任何帮助,我将不胜感激。
这是第一个代码片段:
在这个函数中,resp.Insert 用于 TITLE 的部分工作正常:
func (c *Character) SpawnCharacter() ([]byte, error) {
if c == nil {
return nil, nil
}
if c.Socket == nil || c.Socket.Stats == nil {
return nil, nil
}
resp := CHARACTER_SPAWNED
index := 6
resp.Insert(utils.IntToBytes(uint64(c.PseudoID), 2, true), index) // character pseudo id
index += 2
resp.Insert([]byte{0xee, 0x22, 0x00, 0x00}, index)
index += 4
if c.IsActive {
resp.Insert([]byte{0x03, 0x00, 0x00, 0x00, 0x00}, index)
} else {
resp.Insert([]byte{0x04, 0x00, 0x00, 0x00, 0x00}, index)
}
index += 5
if c.DuelID > 0 {
resp.Overwrite(utils.IntToBytes(500, 2, true), 13) // duel state
}
resp.Insert(utils.IntToBytes(uint64(len(c.Name)), 1, true), index)
index++
resp.Insert([]byte(c.Name), index) // character name
index += len(c.Name)
resp.Insert(utils.IntToBytes(uint64(c.Level), 4, true), index)
index += 4
resp.Insert([]byte{byte(c.Type), byte(c.Class)}, index) // character type-class
index += 2
resp.Insert([]byte{0x01, 0x00, 0x20, 0x1c, 0x00, 0x00, 0x00}, index)
index += 7
coordinate := ConvertPointToLocation(c.Coordinate)
resp.Insert(utils.FloatToBytes(coordinate.X, 4, true), index) // coordinate-x
index += 4
resp.Insert(utils.FloatToBytes(coordinate.Y, 4, true), index) // coordinate-y
index += 4
resp.Insert([]byte{0x00, 0x00, 0x60, 0x41}, index)
index += 4
resp.Insert(utils.FloatToBytes(coordinate.X, 4, true), index) // coordinate-x
index += 4
resp.Insert(utils.FloatToBytes(coordinate.Y, 4, true), index) // coordinate-y
index += 4
resp.Insert([]byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff}, index)
index += 10
resp.Insert(utils.IntToBytes(uint64(c.Socket.Stats.Honor), 4, true), index) // HONOR
index += 4
resp.Insert([]byte{0xc8, 0x00, 0x00, 0x00}, index)
index += 4
resp.Insert(utils.IntToBytes(uint64(c.Socket.Stats.HP), 4, true), index) // hp
index += 4
resp.Insert([]byte{0x00, 0x00, 0x00, 0x00, 0x00}, index)
index += 5
resp.Insert(utils.IntToBytes(uint64(c.WeaponSlot), 1, true), index)
index++
resp.Insert([]byte{0xf2, 0x03}, index)
index += 2
resp.Insert(utils.IntToBytes(uint64(c.BattleMode), 1, true), index) //battle mode
index++
resp.Insert([]byte{0x00, 0x00, 0x05}, index)
index += 3
if c.Morphed {
resp.Insert(utils.IntToBytes(uint64(c.MorphedNPCID), 4, true), index)
index += 4
} else {
resp.Insert([]byte{0x00, 0x00, 0x00, 0x00}, index)
index += 4
}
//index += 5
**resp.Insert(utils.IntToBytes(uint64(c.HonorRank), 4, true), index) // TITLE **
index += 4
resp.Insert(utils.IntToBytes(uint64(c.Type), 1, true), index)
index++
resp.Insert(utils.IntToBytes(uint64(c.GuildID), 4, true), index) // guild id
index += 4
resp.Insert([]byte{0x01, 0x00, 0x00, 0x00}, index)
index += 4
resp.Insert([]byte{byte(c.Faction)}, index) // character faction
index++
resp.Insert([]byte{0x00, 0x00, 0x00, 0x00, 0x64, 0xff, 0xff, 0xff, 0xff}, index)
index += 9
items, err := c.ShowItemsByCharacter()
if err != nil {
return nil, err
}
itemsData := items
sale := FindSale(c.PseudoID)
if sale != nil {
itemsData = []byte{0x05, 0xAA, 0x45, 0xF1, 0x00, 0x00, 0x00, 0xA1, 0x00, 0x00, 0x00, 0x00, 0xB4, 0x6C, 0xF1, 0x00, 0x01, 0x00, 0xA1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
}
//myString := hex.EncodeToString(itemsData)
//log.Print("String:", myString)
resp.Insert(itemsData, index)
index += len(itemsData)
if sale != nil {
resp.Insert([]byte{0x02}, index) // sale indicator
index++
resp.Insert([]byte{byte(len(sale.Name))}, index) // sale name length
index++
resp.Insert([]byte(sale.Name), index) // sale name
index += len(sale.Name)
resp.Insert([]byte{0x00}, index)
index++
}
resp.SetLength(int16(binary.Size(resp) - 6))
dataItems, _ := c.ShowItems()
resp.Concat(dataItems) // FIX => workaround for weapon slot
if c.GuildID > 0 {
guild, err := FindGuildByID(c.GuildID)
if err == nil && guild != nil {
resp.Concat(guild.GetInfo())
}
}
STYLE_MENU := utils.Packet{0xaa, 0x55, 0x0d, 0x00, 0x01, 0xb5, 0x0a, 0x00, 0x00, 0x55, 0xaa}
styleresp := STYLE_MENU
styleresp[8] = byte(0x02)
index = 9
headitem, ok := GetItemInfo(c.HeadStyle)
if !ok || headitem == nil {
c.HeadStyle = 0
}
faceitem, ok := GetItemInfo(c.FaceStyle)
if !ok || faceitem == nil {
c.FaceStyle = 0
}
styleresp.Insert(utils.IntToBytes(uint64(c.HeadStyle), 4, true), index)
index += 4
styleresp.Insert(utils.IntToBytes(uint64(c.FaceStyle), 4, true), index)
index += 4
resp.Concat(styleresp)
c.DeleteAura()
return resp, nil
}
然而,当我尝试在这个简化版本中实现它时,它告诉我顺序错误,游戏就会出现问题:
func (c *Character) SpawnCharacter() ([]byte, error) {
if c == nil {
return nil, nil
}
resp := CHARACTER_SPAWNED
resp.Insert(utils.IntToBytes(uint64(c.PseudoID), 2, true), 6) // character pseudo id
if c.IsActive {
resp[12] = 3
} else {
resp[12] = 4
}
/*
if c.DuelID > 0 {
resp.Overwrite(utils.IntToBytes(500, 2, true), 13) // duel state
}
*/
resp[17] = byte(len(c.Name)) // character name length
resp.Insert([]byte(c.Name), 18) // character name
index := len(c.Name) + 18 + 4
resp[index] = byte(c.Type) // character type
index += 1
index += 8
coordinate := ConvertPointToLocation(c.Coordinate)
resp.Insert(utils.FloatToBytes(coordinate.X, 4, true), index) // coordinate-x
index += 4
resp.Insert(utils.FloatToBytes(coordinate.Y, 4, true), index) // coordinate-y
index += 8
resp.Insert(utils.FloatToBytes(coordinate.X, 4, true), index) // coordinate-x
index += 4
resp.Insert(utils.FloatToBytes(coordinate.Y, 4, true), index) // coordinate-y
index += 4
index += 18
resp.Overwrite(utils.IntToBytes(uint64(c.Socket.Stats.HP), 4, true), index) // hp
index += 9
resp[index] = byte(c.WeaponSlot) // weapon slot
index += 16
resp.Insert(utils.IntToBytes(uint64(c.GuildID), 4, true), index) // guild id
index += 8
**resp.Insert(utils.IntToBytes(uint64(c.HonorRank), 4, true), index) // TITLE**
index += 4
resp[index] = byte(c.Faction) // character faction
index += 10
items, err := c.ShowItems()
if err != nil {
return nil, err
}
itemsData := items[11 : len(items)-2]
sale := FindSale(c.PseudoID)
if sale != nil {
itemsData = []byte{0x05, 0xAA, 0x45, 0xF1, 0x00, 0x00, 0x00, 0xA1, 0x00, 0x00, 0x00, 0x00, 0xB4, 0x6C, 0xF1, 0x00, 0x01, 0x00, 0xA1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
}
resp.Insert(itemsData, index)
index += len(itemsData)
length := int16(len(itemsData) + len(c.Name) + 111)
if sale != nil {
resp.Insert([]byte{0x02}, index) // sale indicator
index++
resp.Insert([]byte{byte(len(sale.Name))}, index) // sale name length
index++
resp.Insert([]byte(sale.Name), index) // sale name
index += len(sale.Name)
resp.Insert([]byte{0x00}, index)
index++
length += int16(len(sale.Name) + 3)
}
resp.SetLength(length)
resp.Concat(items) // FIX => workaround for weapon slot
if c.GuildID > 0 {
guild, err := FindGuildByID(c.GuildID)
if err == nil && guild != nil {
resp.Concat(guild.GetInfo())
}
}
return resp, nil
}
更多关于Golang中resp.Insert操作问题求解的实战教程也可以访问 https://www.itying.com/category-94-b0.html
1 回复
更多关于Golang中resp.Insert操作问题求解的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
问题在于第二个简化版本中的索引计算不准确,导致数据插入位置错误。resp.Insert 操作需要精确的字节偏移量,而硬编码的索引值在数据结构变化时容易出错。
以下是修复后的关键部分,使用动态索引跟踪:
func (c *Character) SpawnCharacter() ([]byte, error) {
if c == nil {
return nil, nil
}
resp := CHARACTER_SPAWNED
index := 6
// 伪ID
resp.Insert(utils.IntToBytes(uint64(c.PseudoID), 2, true), index)
index += 2
// 状态标志
resp.Insert([]byte{0xee, 0x22, 0x00, 0x00}, index)
index += 4
// 活动状态
if c.IsActive {
resp.Insert([]byte{0x03, 0x00, 0x00, 0x00, 0x00}, index)
} else {
resp.Insert([]byte{0x04, 0x00, 0x00, 0x00, 0x00}, index)
}
index += 5
// 名称
resp.Insert(utils.IntToBytes(uint64(len(c.Name)), 1, true), index)
index++
resp.Insert([]byte(c.Name), index)
index += len(c.Name)
// 等级和类型
resp.Insert(utils.IntToBytes(uint64(c.Level), 4, true), index)
index += 4
resp.Insert([]byte{byte(c.Type), byte(c.Class)}, index)
index += 2
// 固定字节
resp.Insert([]byte{0x01, 0x00, 0x20, 0x1c, 0x00, 0x00, 0x00}, index)
index += 7
// 坐标
coordinate := ConvertPointToLocation(c.Coordinate)
resp.Insert(utils.FloatToBytes(coordinate.X, 4, true), index)
index += 4
resp.Insert(utils.FloatToBytes(coordinate.Y, 4, true), index)
index += 4
resp.Insert([]byte{0x00, 0x00, 0x60, 0x41}, index)
index += 4
resp.Insert(utils.FloatToBytes(coordinate.X, 4, true), index)
index += 4
resp.Insert(utils.FloatToBytes(coordinate.Y, 4, true), index)
index += 4
// 固定字节
resp.Insert([]byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff}, index)
index += 10
// 荣誉
resp.Insert(utils.IntToBytes(uint64(c.Socket.Stats.Honor), 4, true), index)
index += 4
resp.Insert([]byte{0xc8, 0x00, 0x00, 0x00}, index)
index += 4
// HP
resp.Insert(utils.IntToBytes(uint64(c.Socket.Stats.HP), 4, true), index)
index += 4
resp.Insert([]byte{0x00, 0x00, 0x00, 0x00, 0x00}, index)
index += 5
// 武器槽和战斗模式
resp.Insert(utils.IntToBytes(uint64(c.WeaponSlot), 1, true), index)
index++
resp.Insert([]byte{0xf2, 0x03}, index)
index += 2
resp.Insert(utils.IntToBytes(uint64(c.BattleMode), 1, true), index)
index++
resp.Insert([]byte{0x00, 0x00, 0x05}, index)
index += 3
// 变形状态
if c.Morphed {
resp.Insert(utils.IntToBytes(uint64(c.MorphedNPCID), 4, true), index)
} else {
resp.Insert([]byte{0x00, 0x00, 0x00, 0x00}, index)
}
index += 4
// 荣誉等级(TITLE)- 关键修复
resp.Insert(utils.IntToBytes(uint64(c.HonorRank), 4, true), index)
index += 4
// 类型和公会ID
resp.Insert(utils.IntToBytes(uint64(c.Type), 1, true), index)
index++
resp.Insert(utils.IntToBytes(uint64(c.GuildID), 4, true), index)
index += 4
resp.Insert([]byte{0x01, 0x00, 0x00, 0x00}, index)
index += 4
// 阵营
resp.Insert([]byte{byte(c.Faction)}, index)
index++
resp.Insert([]byte{0x00, 0x00, 0x00, 0x00, 0x64, 0xff, 0xff, 0xff, 0xff}, index)
index += 9
// 物品数据
items, err := c.ShowItemsByCharacter()
if err != nil {
return nil, err
}
itemsData := items
sale := FindSale(c.PseudoID)
if sale != nil {
itemsData = []byte{0x05, 0xAA, 0x45, 0xF1, 0x00, 0x00, 0x00, 0xA1, 0x00, 0x00, 0x00, 0x00, 0xB4, 0x6C, 0xF1, 0x00, 0x01, 0x00, 0xA1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
}
resp.Insert(itemsData, index)
index += len(itemsData)
if sale != nil {
resp.Insert([]byte{0x02}, index)
index++
resp.Insert([]byte{byte(len(sale.Name))}, index)
index++
resp.Insert([]byte(sale.Name), index)
index += len(sale.Name)
resp.Insert([]byte{0x00}, index)
index++
}
resp.SetLength(int16(binary.Size(resp) - 6))
dataItems, _ := c.ShowItems()
resp.Concat(dataItems)
if c.GuildID > 0 {
guild, err := FindGuildByID(c.GuildID)
if err == nil && guild != nil {
resp.Concat(guild.GetInfo())
}
}
return resp, nil
}
主要修复点:
- 使用动态
index变量跟踪当前位置,避免硬编码偏移 - 确保每个数据字段插入后正确更新索引
- 保持与原始工作版本相同的字段顺序和大小
- 荣誉等级(TITLE)字段在正确的位置插入(在变形状态之后,类型之前)
这种动态索引方法比硬编码偏移更可靠,特别是在数据结构可能变化的情况下。

