ce吧 关注:194,518贴子:3,795,810
  • 7回复贴,共1

请问CE里面要怎么样高效的管理链表数据?

只看楼主收藏回复

某游戏的背包在内存中是链表形式存放的,想找后一个背包物品的就要先查一遍之前的所有项目。在CE里的体现就是第N个物品就要偏移N次,这数量一旦多起来,CE就动一下就卡半天
结构:

第一位物品:

第五个物品:

( 偏移次数 = 物品顺序 - 1 )


IP属地:广东1楼2021-05-30 16:14回复
    原本的CT文件才300kb,通过程序生成了背包里面700个栏目后,CT文件直接变成266MB了,同时CE里面非常的卡,根本没法用
    如果只通过“结构分析”,就很难管理后面的项目了,目前背包貌似已经有上百的物品了,游戏其他地方只记录“实例标识”(对应结构图的字段),如下图

    7FFF01BD,代表背包中第 1BD(hex) 个项目,即第445个物品,不可能在“结构分析”里面点四百多下吧


    IP属地:广东2楼2021-05-30 16:21
    回复
      for i=1, 700 do


      IP属地:湖北来自iPhone客户端3楼2021-05-30 22:18
      收起回复
        研究了以下lua脚本,确定了大概思路:
        1.初始化背包基址
        2.从第一项开始循环读取
        3.拿回数据,存入程序变量。
        4.根据过滤条件,筛选符合的项目再渲染到窗口上
        5.(拓展)将动态地址保存到特定区域,以便再CE列表中修改
        窗体设计

        列表

        感觉这种方式管理还行,就是有工程量有点大(才不是我懒)


        IP属地:广东4楼2021-06-02 02:01
        回复
          -- 存储背包数据
          items = {}
          -- 初始化标记
          isInit = false;
          function ItemEdit_f5_bottonClick(sender)
          --init
          address = readInteger("Tales of Zestiria.exe+1D3078C")
          address = readInteger(address + 0)
          address = readInteger(address + 0x9154)
          --获取最大值,由界面的滑块控制
          maxStrVal = trackbar_getPosition(ItemEdit_CETrackBar1)
          print("0 ~ " .. maxStrVal)
          -- 去重
          itemHave = {}
          items = {}
          for i=1,maxStrVal do
          -- print("|>>"..type(address)..":"..address)
          item = getItem(address)
          id = hex(item["ItemId"])
          -- print(hex(item["ItemId"]))
          -- 1199662880
          -- 0x47816720
          if( id == "47816720" or itemHave[id] ~= nil ) then
          --已到结尾
          break
          else
          -- 继续
          itemHave[id] = 1
          items[i] = item
          end
          address = item['nextItem']
          end
          -- 打印背包长度
          print("Len:"..#items)
          --[[
          ItemEdit_ListBox.clear()
          for ii in ipairs(items) do
          ItemEdit_ListBox.Items.Add(hex(items[ii]["ItemId"]).."|"..hex(items[ii]["addres"]))
          end
          ]]
          --过滤,渲染
          serachText()
          end
          -- 获取物品属性
          -- address:物品地址
          function getItem(address)
          --print(">>"..type(addres)..":"..addres)
          nextItem = readInteger(address)
          ItemId = readInteger(0 + address + 0x8)
          result = {
          addres = address,
          nextItem = nextItem,
          ItemId = ItemId
          }
          return result
          end
          function ItemEdit_CETrackBar1Change(sender)
          control_setCaption(ItemEdit_maxStr, "0 ~ "..trackbar_getPosition(ItemEdit_CETrackBar1) )
          end
          -- 十进制转十六进制
          function hex(num)
          return string.format("%02X", num)
          end
          --查询、过滤
          function serachText()
          serStr = ItemEdit_serStr.Text
          --[[
          print(string.find("0001","1"))
          print("serLen")
          print(ipairs(items))
          ]]
          ItemEdit_ListBox.clear()
          for i in ipairs(items) do
          item = items[i]
          id = hex(item["ItemId"])
          if(string.find(id,serStr) ~= nil) then
          --print(id)
          ItemEdit_ListBox.Items.Add(
          hex(item["ItemId"]).."|"..hex(item["addres"])
          )
          end
          end
          end
          function ItemEdit_Serach_bottonClick(sender)
          serachText()
          end
          function ItemEdit_ListBoxClick(sender)
          if(isInit == false)then
          ItemEdit_FormShow()
          end
          selectItemIndex = ItemEdit_ListBox.getItemIndex()
          if(selectItemIndex ~= -1)then
          item = ItemEdit_ListBox.getItems()[selectItemIndex]
          itemStr = Split(item,"|")
          ItemEdit_itemIdStr.Text = itemStr[1]
          ItemEdit_itemAddStr.Text = itemStr[2]
          -- 更新当前修改的物品的地址 Item_ChaneAddress
          writeInteger("Item_ChaneAddress","0x"..itemStr[2])
          end
          end
          -- 切分字符串
          -- from:https://www.cnblogs.com/AaronBlogs/p/7615877.html
          function Split(szFullString, szSeparator)
          local nFindStartIndex = 1
          local nSplitIndex = 1
          local nSplitArray = {}
          while true do
          local nFindLastIndex = string.find(szFullString, szSeparator, nFindStartIndex)
          if not nFindLastIndex then
          nSplitArray[nSplitIndex] = string.sub(szFullString, nFindStartIndex, string.len(szFullString))
          break
          end
          nSplitArray[nSplitIndex] = string.sub(szFullString, nFindStartIndex, nFindLastIndex - 1)
          nFindStartIndex = nFindLastIndex + string.len(szSeparator)
          nSplitIndex = nSplitIndex + 1
          end
          return nSplitArray
          end
          -- 初始化,申请内存符号,用户存储当前物品的地址
          function ItemEdit_FormShow(sender)
          init = [[
          //注册名称地址
          registersymbol(Item_ChaneAddress)
          //32位游戏申请4个字节,64位申请8个字节
          alloc(Item_ChaneAddress,8)
          ]]
          autoAssemble(init)
          isInit = true;
          end


          IP属地:广东5楼2021-06-02 02:06
          收起回复