-
Notifications
You must be signed in to change notification settings - Fork 22
Expand file tree
/
Copy pathrandomizeSelected.lua
More file actions
165 lines (149 loc) · 4.99 KB
/
randomizeSelected.lua
File metadata and controls
165 lines (149 loc) · 4.99 KB
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
--##### Randomize Selected Addresslist Values for Cheat Engine
--##### Author: FreeER
--##### Github: https://github.com/FreeER
--##### Website: https://www.facebook.com/groups/CheatTheGame
--##### YouTube: https://www.youtube.com/channel/UCLy60mbqc3rSvh42jkpCDxw
--[[
Request from TwilightKillerX on Discord
Randomizes the values of selected addresses
]]
local function findMenu(mi)
while not mi.Menu do mi = mi.Parent end
return mi.Menu
end
local del_mi = MainForm.Deletethisrecord1
local del_menu = findMenu(del_mi)
local mi = createMenuItem(del_menu)
mi.Caption = 'Randomize Values'
local miPrompt = createMenuItem(del_menu)
miPrompt.Caption = 'Randomize Values (range prompt)'
function randomize(mr)
local types = {
[vtByte] = function() return math.random(0, 0xFF) end,
-- *smallInteger added in CE 6.7
[vtWord] = function() return math.random(0, 0xFFFF) end,
[vtDword] = function() return math.random(0, 0xFFFFFFFF) end,
[vtQword] = function() return math.random(0, 0x7FFFFFFFFFFFFFFF) * (math.random() > 0.5 and -1 or 1) end,
--[vtSingle] set outside, refers to vtDword
--[vtDouble] set outside, refers to vtQword
--[vtByteArray] set outside, refers to vtByte
-- unsupported
--[[
-- probably not the most _logical_ thing to do, but just as a demonstration of how it could be done
[vtString] = function(len)
local chars = {}
for i=0,len do
chars[#chars+1] = string.char(math.random(('a'):byte(1), ('z'):byte(1)))
end
return table.concat(chars,'')
end,
]]
--[vtGrouped],
--[vtBinary], -- probably simple enough just not certain
--[vtPointer], -- not a normal type, fix table to have 4/8?
--[vtCustom] -- no way to get size, getCustomType(name).scriptUsesFloat
-- exists for float/int but not size (other than parsing the script... not
-- too hard but I don't feel like it right now)
}
types[vtSingle] = function() return string.unpack('f',string.pack('I4',types[vtDword]())) end
types[vtDouble] = function() return string.unpack('d',string.pack('I8',types[vtQword]())) end
types[vtByteArray] = function(len)
local bytes = {}
for i=0, len do
bytes[#bytes+1] = ('%X'):format(types[vtByte]())
end
return table.concat(bytes,' ')
end
if mr.Type == vtByteArray then
return types[mr.Type](mr.Aob.Size)
elseif types[mr.Type] then
--print(mr.Description, types[mr.Type]())
return types[mr.Type]()
else
--print('unknown type', mr.Type)
return nil
end
end
mi.OnClick = function()
local al = getAddressList()
local records = al.getSelectedRecords()
if not records then return end
for k,v in pairs(records) do
if v.Type ~= vtAutoAssembler and not v.isGroupHeader then
local val = randomize(v)
if val then v.Value = val end
end
end
end
miPrompt.onClick = function()
local valid = {vtByte, vtWord, vtDword, vtQword, vtSingle, vtDouble}
local al = getAddressList()
local records = al.getSelectedRecords()
if not records then return end
min = inputQuery('min value', 'Min value:', 0)
max = inputQuery('max value', 'Max value:', 100)
min = tonumber(min)
max = tonumber(max)
if not min or not max then -- probably hit cancel
return
end
local success = pcall(math.random, min, max)
if not success then
showMessage('invalid range, math.random failed!')
return
end
for k,v in pairs(records) do
if valid[v.type] then
local success, val = pcall(math.random, min, max)
if success then
v.Value = v.ShowAsHex and ('%X'):format(val) or val
end
end
end
end
--[[
-- don't really want to prompt for every single record and
-- remembering values really only works for a single memory record huh...
local lastMinValues = {}
local lastMaxValues = {}
miPrompt.onClick = function()
local valid = {vtByte, vtWord, vtDword, vtQword, vtSingle, vtDouble}
local al = getAddressList()
local records = al.getSelectedRecords()
for k,v in pairs(records) do
if valid[v.type] then
local min = lastMinValues[mr.id] or 0
local max = lastMaxValues[mr.id] or 100
min = inputQuery('min value', 'Min value:', min)
max = inputQuery('max value', 'Max value:', max)
min = tonumber(min)
max = tonumber(max)
if min and max then
lastMinValues[mr.id] = min
lastMinValues[mr.id] = max
local success, val = pcall(math.random, min, max)
print('random:', val)
if success then mr.Value = val end
end
end
end
end
]]
del_menu.Items.insert(del_mi.MenuIndex, mi)
del_menu.Items.insert(del_mi.MenuIndex, miPrompt)
--[[
-- mr generation test
local address = 0x400290
local types = {
vtByte, vtWord, vtDword, vtQword, vtSingle, vtDouble, vtString, vtUnicodeString,
vtByteArray, vtBinary, vtAutoAssembler, vtPointer, vtCustom, vtGrouped
}
fullAccess(address, #types*0x10)
for _,t in ipairs(types) do
local mr = AddressList.CreateMemoryRecord()
mr.Address = ('%X'):format(address)
address = address + 0x10
mr.type = t
mr.Description = _
end
]]