Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- --- Update existing CE structure with with new offset / fields from a Mono class
- -- Allows you to update structure offsets wtihout losing changes to existing fields
- -- like structure pointers and local structures
- -- @param idx_struct: integer index of CE Structure you want updated
- -- @param className: string containing the mono class you want to take fields from
- -- @param doDelete: Optional bool, deletes struct entries that don't correspond to current class fields
- -- @param verbose: Optional integer; >0 prints info on structure changes, >1 prints all actions
- -- @return true if structure was changed, false if not
- function updateStructFromMonoClass( idx_struct, className, doDelete, verbose )
- if not idx_struct or not className then error('ERROR updateStructFromMonoClass: arguments malformed or missing!') end
- if idx_struct + 1 > getStructureCount() then error('ERROR updateStructFromMonoClass: structure index out of bounds!') end
- local classId = mono_findClass('', className)
- if not classId then error('ERROR updateStructFromMonoClass: no class ID found for given class name!') end
- verbose = type(verbose) == 'number' and verbose or 0
- local ver1 = verbose > 0 and true or false
- local ver2 = verbose > 1 and true or false
- local changed = false
- local st = getStructure(idx_struct)
- local st_name = st.getName()
- if ver1 then print( string.format('== Updating structure %s with mono class %s ==',st_name, className) ) end
- local st_count = st.Count
- local st_entry = {}
- for i = 1, st_count do st_entry[i] = st.getElement(i-1) end
- local st2 = monoform_exportStructInternal(createStructure(''), classId, true --[[recursive]], false --[[not static]], {'some struct map thing'}, false --[[not global]])
- local st2_count = st2.Count
- local st2_entry = {}
- for i = 1, st2_count do st2_entry[i] = st2.getElement(i-1) end
- local st2_tName = {}
- local st2_tOffset = {}
- for i = 1, st2_count do st2_tName[ st2_entry[i].Name ] = st2_entry[i].Offset end
- for i = 1, st2_count do st2_tOffset[ st2_entry[i].Offset ] = st2_entry[i].Name end
- -- simple offset adjust for existing fields
- st.beginUpdate()
- for i = 1, st_count do
- local ename = st_entry[i].Name
- if st2_tName[ename] then
- local newoff = st2_tName[ename]
- if st_entry[i].Offset ~= newoff then
- if ver1 then print( string.format('Updated offset of %s from %X to %X',ename,st_entry[i].Offset,newoff) ) end
- st_entry[i].Offset = newoff
- changed = true
- else
- if ver2 then print( string.format('Offset of %s unchanged from %X',ename,newoff) ) end
- end
- elseif doDelete then
- if ver1 then print( string.format( 'Entry %s not found, removed from structure', ename ) ) end
- st_entry[i].destroy()
- else
- if ver1 then print( string.format( 'Entry %s not found in new field list', ename ) ) end
- end
- end
- st.endUpdate()
- if st.Count ~= st_count then -- refresh if struct changed
- if ver2 then print('> Structure size changed, updating tables') end
- st_entry = {}
- st_count = st.Count
- for i = 1, st_count do st_entry[i] = st.getElement(i-1) end
- changed = true
- end
- local st_tName = {}
- for i = 1, st_count do st_tName[ st_entry[i].Name ] = st_entry[i].Offset end
- st.beginUpdate()
- for _,v in ipairs(st2_entry) do
- if not st_tName[v.Name] then -- check if new entry is in old struct
- if ver1 then print( string.format('Field %s not found, adding as new entry',v.Name) ) end
- local e = st.addElement()
- e.setName( v.getName() )
- e.setOffset( v.getOffset() )
- e.setVartype( v.getVartype() )
- e.setBytesize( v.getBytesize() )
- changed = true
- end
- end
- st.endUpdate()
- return changed
- end
- --- Bonus function to update all structures at once.
- -- @param doDelete: Optional bool, deletes struct entries that don't correspond to current class fields
- -- @param verbose: Optional integer; >0 prints info on structure changes, >1 prints all actions
- function updateAllMonoStructs( doDelete, verbose )
- verbose = type(verbose) == 'number' and verbose or 0
- local numStructs = getStructureCount()
- local numMonos = 0
- local numChanged = 0
- for i=0, numStructs-1 do
- repeat -- workaround to continue for loop on break
- local stName = getStructure(i).Name
- local classId = mono_findClass('', stName)
- if not classId or stName == 'String' then break end
- numMonos = numMonos + 1
- local changed = updateStructFromMonoClass(i, stName, doDelete, verbose)
- if changed then
- numChanged = numChanged + 1
- if verbose > 0 then print(string.format('CHANGED: %s\n',stName)) end
- else
- if verbose > 0 then print(string.format('UNCHANGED: %s\n',stName)) end
- end
- until true
- end
- if verbose > 0 then print('Number of Mono Structures found:', numMonos) end
- if verbose > 0 then print('Number of Structures updated:', numChanged) end
- end
Advertisement
Add Comment
Please, Sign In to add comment