HenryEx

updateStructFromMonoClass

Aug 18th, 2026
4,577
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 4.92 KB | Source Code | 0 0
  1. --- Update existing CE structure with with new offset / fields from a Mono class
  2. -- Allows you to update structure offsets wtihout losing changes to existing fields
  3. -- like structure pointers and local structures
  4. -- @param idx_struct: integer index of CE Structure you want updated
  5. -- @param className: string containing the mono class you want to take fields from
  6. -- @param doDelete: Optional bool, deletes struct entries that don't correspond to current class fields
  7. -- @param verbose: Optional integer; >0 prints info on structure changes, >1 prints all actions
  8. -- @return true if structure was changed, false if not
  9.  
  10. function updateStructFromMonoClass( idx_struct, className, doDelete, verbose )
  11.   if not idx_struct or not className then error('ERROR updateStructFromMonoClass: arguments malformed or missing!') end
  12.   if idx_struct + 1 > getStructureCount() then error('ERROR updateStructFromMonoClass: structure index out of bounds!') end
  13.   local classId = mono_findClass('', className)
  14.   if not classId then error('ERROR updateStructFromMonoClass: no class ID found for given class name!') end
  15.   verbose = type(verbose) == 'number' and verbose or 0
  16.   local ver1 = verbose > 0 and true or false
  17.   local ver2 = verbose > 1 and true or false
  18.   local changed = false
  19.   local st = getStructure(idx_struct)
  20.   local st_name = st.getName()
  21.   if ver1 then print( string.format('== Updating structure %s with mono class %s ==',st_name, className) ) end
  22.   local st_count = st.Count
  23.   local st_entry = {}
  24.  
  25.  
  26.   for i = 1, st_count do st_entry[i] = st.getElement(i-1) end
  27.  
  28.   local st2 = monoform_exportStructInternal(createStructure(''), classId, true --[[recursive]], false --[[not static]], {'some struct map thing'}, false --[[not global]])
  29.   local st2_count = st2.Count
  30.   local st2_entry = {}
  31.   for i = 1, st2_count do st2_entry[i] = st2.getElement(i-1) end
  32.  
  33.   local st2_tName = {}
  34.   local st2_tOffset = {}
  35.  
  36.   for i = 1, st2_count do st2_tName[ st2_entry[i].Name ] = st2_entry[i].Offset end
  37.   for i = 1, st2_count do st2_tOffset[ st2_entry[i].Offset ] = st2_entry[i].Name end
  38.  
  39.   -- simple offset adjust for existing fields
  40.   st.beginUpdate()
  41.   for i = 1, st_count do
  42.     local ename = st_entry[i].Name
  43.     if st2_tName[ename] then
  44.       local newoff = st2_tName[ename]
  45.       if st_entry[i].Offset ~= newoff then
  46.         if ver1 then print( string.format('Updated offset of %s from %X to %X',ename,st_entry[i].Offset,newoff) ) end
  47.         st_entry[i].Offset = newoff
  48.         changed = true
  49.       else
  50.         if ver2 then print( string.format('Offset of %s unchanged from %X',ename,newoff) ) end
  51.       end
  52.     elseif doDelete then
  53.       if ver1 then print( string.format( 'Entry %s not found, removed from structure', ename ) ) end
  54.       st_entry[i].destroy()
  55.     else
  56.       if ver1 then print( string.format( 'Entry %s not found in new field list', ename ) ) end
  57.     end
  58.   end
  59.   st.endUpdate()
  60.  
  61.   if st.Count ~= st_count then -- refresh if struct changed
  62.     if ver2 then print('> Structure size changed, updating tables') end
  63.     st_entry = {}
  64.     st_count = st.Count
  65.     for i = 1, st_count do st_entry[i] = st.getElement(i-1) end
  66.     changed = true
  67.   end
  68.  
  69.  
  70.   local st_tName = {}
  71.   for i = 1, st_count do st_tName[ st_entry[i].Name ] = st_entry[i].Offset end
  72.  
  73.   st.beginUpdate()
  74.   for _,v in ipairs(st2_entry) do
  75.     if not st_tName[v.Name] then -- check if new entry is in old struct
  76.       if ver1 then print( string.format('Field %s not found, adding as new entry',v.Name) ) end
  77.       local e = st.addElement()
  78.       e.setName( v.getName() )
  79.       e.setOffset( v.getOffset() )
  80.       e.setVartype( v.getVartype() )
  81.       e.setBytesize( v.getBytesize() )
  82.       changed = true
  83.     end
  84.   end
  85.   st.endUpdate()
  86.  
  87.   return changed
  88.  
  89. end
  90.  
  91. --- Bonus function to update all structures at once.
  92. -- @param doDelete: Optional bool, deletes struct entries that don't correspond to current class fields
  93. -- @param verbose: Optional integer; >0 prints info on structure changes, >1 prints all actions
  94. function updateAllMonoStructs( doDelete, verbose )
  95.   verbose = type(verbose) == 'number' and verbose or 0
  96.   local numStructs = getStructureCount()
  97.   local numMonos = 0
  98.   local numChanged = 0
  99.   for i=0, numStructs-1 do
  100.     repeat  -- workaround to continue for loop on break
  101.       local stName = getStructure(i).Name
  102.       local classId = mono_findClass('', stName)
  103.       if not classId or stName == 'String' then break end
  104.       numMonos = numMonos + 1
  105.       local changed = updateStructFromMonoClass(i, stName, doDelete, verbose)
  106.       if changed then
  107.         numChanged = numChanged + 1
  108.         if verbose > 0 then print(string.format('CHANGED: %s\n',stName)) end
  109.       else
  110.         if verbose > 0 then print(string.format('UNCHANGED: %s\n',stName)) end
  111.       end
  112.     until true
  113.   end
  114.   if verbose > 0 then print('Number of Mono Structures found:', numMonos) end
  115.   if verbose > 0 then print('Number of Structures updated:', numChanged) end
  116. end
Advertisement
Add Comment
Please, Sign In to add comment