forked from JasonGoemaat/CheatEngineMonoHelper
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmonoimage.lua
180 lines (157 loc) · 4.65 KB
/
monoimage.lua
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
local MonoImage = mono.MonoImage
MonoImage.mt = {
__index = MonoImage,
__tostring = function(t)
return 'MonoImage '..tostring(t.name)
end
}
local MonoClass = mono.MonoClass
--[[
List names of images, a name can be passed to MonoImage.new()
or MonoImage(name) to create a MonoImage instance.
--]]
function MonoImage.enumerate()
local names = {}
mono_enumImages(function(img)
local name = mono_image_get_name(img)
table.insert(names, name)
end)
table.sort(names)
return names
end
--[[
Constructor doesn't do much, call :init(name, progress)
--]]
function MonoImage.new()
local obj = { }
setmetatable(obj, MonoImage.mt)
return obj
end
--[[
init() takes the image name and an optional callback for reporting progress
and when it is complete. The signature for this function is:
function progress(complete, image, message, processed, total)
This callback should be executed on the main CE thread.
--]]
function MonoImage:init(name, progress)
if monopipe == nil then
print('Launching mono data collector...')
LaunchMonoDataCollector()
end
self.domains = mono_enumDomains()
self.domain = self.domains[1]
self.classes = {} -- straight list of all classes
self.classesByName = {} -- dictionary for access by name
self.classesByLowerName = {} -- for access by lower case name
self.classesById = {} -- for access by id
self.ignoredClassesByName = {} -- for ignoring classes in searches, etc.
self.progress = progress
self.name = name or 'Assembly-CSharp' -- intelligent default for unity
-- get id
self.id = nil
mono_enumImages(function(img)
local foundName = mono_image_get_name(img)
if foundName == self.name then self.id = img end
end)
if not self.id then
print('NO ID!')
print('name is', name, self.name)
self:report(false, 'Error finding image named '..tostring(name))
self.progress = nil
self.total = nil
self.count = nil
return false
end
createThread(function(thread)
self.thread = thread
self:_init(thread)
end)
end
--[[
This is the function called by init() on another thread
--]]
function MonoImage:_init(thread)
--print('MonoImage:_init thread is', thread, 'self is', tostring(self))
self.thread = thread
local temp = mono_image_enumClasses(self.id)
-- thread.synchronize(function(th)
-- print('Image '..tostring(self.id)..' has classes: '..tostring(temp))
-- end)
self.classes = {}
self.classesByName = {}
self.classesByLowerName = {}
self.classesById = {}
self.missingNames = {}
self.total = #temp
self.count = 0
self.message = "Getting classes"
self:report(false, "Getting classes")
-- populate classes without much information first so we can
-- access our definitions when filling in parents, properties, etc.
for i,c in ipairs(temp) do
local class = MonoClass.new(self, c)
if class.lowerName ~= nil then
table.insert(self.classes, class)
self.classesByName[class.name] = class
self.classesByLowerName[class.lowerName] = class
self.classesById[class.id] = class
else
--print("Nil lowername for class", c.class)
end
self.count = i
if (i % 100 == 0 or i == #temp) then
self:report(false, 'Fetching classes')
end
end
table.sort(self.classes)
for i,class in ipairs(self.classes) do
class.parentId = mono_class_getParent(class.id)
class.parent = self.classesById[class.parentId]
self.count = i
if (i % 100 == 0 or i == #temp) then
self:report(false, 'Fetching parents')
end
end
self.count = 0
for i,class in ipairs(self.classes) do
class:initFields()
class:initMethods()
self.count = i
if (i % 100 == 0 or i == #temp) then
self:report(false, 'Initializing fields and methods')
end
end
self:report(true, 'Done')
end
--[[
Report progress on the main CE thread to do gui updates
--]]
function MonoImage:report(done, message)
if self.progress ~= nil and self.thread ~= nil then
self.thread.synchronize(function(thread)
self.progress(done, self, message, self.count, self.total)
end)
end
if done then
-- do cleanup here
self.count = nil
self.total = nil
self.progress = nil
self.thread = nil
end
end
--[[ Sample code... weird
--return util.pretty(mono.MonoImage.enumerate())
mi = mono.MonoImage.new()
print('mi is "'..tostring(mi)..'"')
mi:init('Assembly-CSharp', function(c, i, m, p, t)
print(m, p, t)
end)
--LaunchMonoDataCollector()
local thread = createThread(function(th)
TESTIMAGES = {}
mono_enumImages(function(img)
th.synchronize(function() print(img) end)
end)
end)
--]]