|
Cheat Engine The Official Site of Cheat Engine
|
View previous topic :: View next topic |
Author |
Message |
cooleko Grandmaster Cheater Reputation: 11
Joined: 04 May 2016 Posts: 717
|
Posted: Mon Jun 06, 2016 12:55 pm Post subject: Questions on starting lua and any tips to convert asm code |
|
|
So I attempted to use lua in my lastest script, but was unable to make much progress beyond building a timer that would allow my useless code to loop.
I ran into an issue when trying to use D2H, DTH, or vice versa (functions to convert between decimal and hex) because they dont actually exist in main.lua
So I attempted to make my own D2H but example code all needed the math library. (require "math" maybe? I gave up when it errored just one more time)
Code: | function DEC_HEX(IN)
local B,K,OUT,I,D=16,"0123456789ABCDEF","",0
while IN>0 do
I=I+1
IN,D=math.floor(IN/B),math.mod(IN,B)+1
OUT=string.sub(K,D,D)..OUT
end
return OUT
end |
I tried to use the cheat table lua script but that just caused errors with unexpected "[" "{" "|" " " or w/e new or non-existant symbol it threw at me.
I tried to use AA scripts with the {lua} designation, and they worked a little better, but this is backwards so I abandoned it to do it properly (or not at all)
Lastly, I made the cheat table lua script have activation and deactivation functions, which I called in an AA script with luacall so that the cheat table would start and stop when desired, but the scripts would activate on table startup (I'm guessing now that the table auto runs every function call in the cheat table lua script even if the enables are tied up in a function)
This caused the timer to stop and start, but it still started on table load.
The final effort looked like this:
Lua Cheat Table Script:
Code: |
LastShip = 0
CurrShip = 0
address = 0
function CheckShipStatus(t)
CurrShip = readInteger(getAddress("myShip"))
if (CurrShip ~= LastShip) and (CurrShip ~= 0) and (CurrShip ~= nil) then
print("Current Ship: " .. CurrShip .. " & Last Ship: " .. LastShip)
address = readInteger("CurrShip" +40)
print("First Pointer: " .. address)
LastShip = CurrShip
end
end
function ActivateTimer()
t=createTimer(nil)
t.OnTimer=CheckShipStatus
t.Interval=3000
t.Enabled=true
end
function DeActivateTimer()
t.Enabled=false
t.Destroy()
end |
Activation Script: Code: |
[enable]
luacall(ActivateTimer())
[disable]
luacall(DeActivateTimer()) |
I couldnt find any way to "debug" the lua code. In ASM, if something isnt working properly, I can just break and trace, find where the actual execution deviates from my vision, and correct the error. In lua, I found I was just using print() everywhere, but that started to get messed up because you cant print certain variables (perhaps when they memory read failed it is nil?). How do you recommend debugging lua?
At this point, in frustration, I just coded the script in asm, because at least it works
Is there a default D2H function call hiding away somewhere in CE? If so, how do i require its library so that I can use it?
Do you have any tips on converting my ASM script below to lua?
I'm thinking a timer that runs an interval every 3000 to accomodate for the sleep, and then using the D2H to get the memoryreads into the proper format at each pointer calculation. Of course, the loops are trivial in lua, even if somewhat annoying in ASM.
I think if the code was written in lua, it would be substantially shorter and easier to build. However, I'm new to lua so failed miserably.
I know the post was long, more of a rant about how poorly my first foray into lua went, but I would appreciate any assistance you can offer to make my next attempt better!
Btw, in case it matters, the game is x64 (it mattered in the asm!).
Code: | [enable]
alloc(UpgradeShip,4096)
registersymbol(UpgradeShip)
alloc(lastShip, 8)
alloc(CounterValue, 8)
alloc(CountToValue, 8)
alloc(aItem, 8)
alloc(cItem, 8)
alloc(EndToggle, 8)
registersymbol(lastShip)
registersymbol(CounterValue)
registersymbol(CountToValue)
registersymbol(aItem)
registersymbol(cItem)
registersymbol(EndToggle)
alloc(UpgradeShip,4096)
label(notToday)
label(Loop1)
label(Loop2)
label(NoReloadCorrection)
CREATETHREAD(UpgradeShip);
UpgradeShip:
push eax
push ebx
push ecx
sub rsp,20
mov eax, [myShip]
cmp eax, [lastShip]
je notToday //Has the ship identifier changed
mov [lastShip], eax //Set myShip into last ship to prevent running code too frequently
mov eax, [myShip]//[[[[["myShip"+40]+40]+68]+10]+18] for counter value
add eax, 40
mov eax, [eax]
mov eax, [eax+40]
mov eax, [eax+68]
mov [aItem], eax //Store the current Item List pointer
mov eax, [eax+18] //Number of parts, save this value
mov [CountToValue], eax
mov [CounterValue], 20
Loop1: //We need to loop until CountToValue is 0
dec [CountToValue]
mov eax, [aItem]
add eax, [CounterValue]
mov eax, [eax]
mov eax, [eax+28]
mov eax, [eax+20] //access mysubsystems (aka base values)
or eax,eax
je notToday //Test pointer before writing
mov [eax+20], 1 //Set weight to 1
mov [eax+24], 0 //Set health to 0
mov [eax+28], 0 //Set armor to 0
mov [eax+2c], 0 //Set shield to 0
mov [eax+30], 0 //Set rotate to 0
mov [eax+34], 0 //Set speed to 0
mov [eax+38], 0 //Set reactor to 0
mov [eax+3c], 0 //Set capacitor to 0
mov eax, [aItem]
add eax, [CounterValue]
mov eax, [eax]
mov eax, [eax+28]
mov eax, [eax+28] //access myBoosts (aka bonus values)
or eax,eax
je notToday //Test pointer before writing
mov [eax+20], 0 //Set Bonus weight to 0
mov [eax+24], (int)1000 //Set Bonus health to 1000*perkbonus
mov [eax+28], (int)1000 //Set Bonus armor to 1000*perkbonus
mov [eax+2c], (int)1000 //Set Bonus shield to 1000*perkbonus
mov ebx, [CountToValue]
shl ebx, 1
mov [eax+30], ebx //Set Bonus rotate to 1
mov [eax+34], ebx //Set Bonus speed to 3
mov [eax+38], (int)1000 //Set Bonus reactor to 1000*perkbonus
mov [eax+3c], (int)1000 //Set Bonus capacitor to 1000*perkbonus
add [CounterValue], 8
cmp [CountToValue], 0 //While Items are still in the list, increment the item pointer value and decrement the counter
jg Loop1
//At this point, every attachment should be upgraded
//Now to do weapons
mov eax, [myShip]//[[[[["myShip"+40]+40]+68]+10]+18] for counter value
add eax, 40
mov eax, [eax]
mov eax, [eax+B8]
mov eax, [eax+10]
mov [aItem], eax //Store the current Item List pointer
mov eax, [eax+18] //Number of parts, save this value
mov [CountToValue], eax
mov [CounterValue], 20
Loop2: //We need to loop until CountToValue is 0
dec [CountToValue]
mov eax, [aItem]
add eax, [CounterValue]
mov eax, [eax]
mov eax, [eax+20]
mov eax, [eax+20] //access Item[2] (Emitter, Missile, or Projectile Weapons) (aka base values)
or eax,eax
je notToday //Test pointer before writing
mov ebx, [eax+7c]
shl ebx, 1
mov [eax+7c], ebx //Set Burst to 2x original value
fld dword ptr [eax+78]
mov ebx, (float).25
fld dword ptr [ebx]
fmul st(0), st(1)
fstp [eax+78] //Set reload time to 1/4 original value, floor it at 1 second
cmp dword ptr [eax+78], (float)1
jg NoReloadCorrection
mov [eax+78], (float)1
NoReloadCorrection:
mov [eax+90], (float)9999999 //Set Damage per shot to 10 million -1
mov [eax+bc], (float)20 //Set damage multiplier to 20
add [CounterValue], 8
cmp [CountToValue], 0 //While Items are still in the list, increment the item pointer value and decrement the counter
jg Loop2
notToday:
mov ecx, #3000
call sleep
cmp [EndToggle],1
pop eax
pop ebx
pop ecx
add rsp,20
jne UpgradeShip
ret
EndToggle:
dd 0
[disable]
dealloc(lastShip)
dealloc(CounterValue)
dealloc(CountToValue)
dealloc(aItem)
dealloc(cItem)
dealloc(EndToggle)
unregistersymbol(lastShip)
unregistersymbol(CounterValue)
unregistersymbol(CountToValue)
unregistersymbol(aItem)
unregistersymbol(cItem)
unregistersymbol(EndToggle)
EndToggle:
dd 1 |
|
|
Back to top |
|
|
ParkourPenguin I post too much Reputation: 138
Joined: 06 Jul 2014 Posts: 4275
|
Posted: Mon Jun 06, 2016 3:10 pm Post subject: |
|
|
cooleko wrote: | I ran into an issue when trying to use D2H, DTH, or vice versa |
The concept of a base is generally irrelevant when talking about integers, as mathematical operations done to integers will be the same regardless of what base they're in: 10+10(decimal) == 0xA + 0xA (hex). The only thing that changes is how they're displayed, so I'll assume you're only talking about a number's string representation.
CE doesn't need to implement anything new because Lua already has ways to translate from deicmal to hex and vise versa.
Code: | local num1 = 10000
print("num1 dec:", num1)
print(string.format("num1 hex: %X", num1))
local num2 = "4BC"
print("num2 dec:", tonumber(num2, 16))
print("num2 hex:", num2)
local num3 = 0x123
print("num3 dec:", num3)
print(string.format("num3 hex: %X",num3)) |
cooleko wrote: | I tried to use the cheat table lua script but that just caused errors with unexpected "[" "{" "|" " " or w/e new or non-existant symbol it threw at me. |
If CE tells you there's an error, then odds are there's an error somewhere in your code.
cooleko wrote: | The scripts would activate on table startup (I'm guessing now that the table auto runs every function call in the cheat table lua script even if the enables are tied up in a function). |
CE does a syntax check of AA scripts when you modify a script or when you load a table. You can skip it if you want by checking for it:
Code: | -- have this near the beginning of a {$lua} block; just make sure your code is correct
if syntaxcheck then return end |
cooleko wrote: | Lua Cheat Table Script:
...
Activation Script:
... |
"CurrShip" +40 isn't a valid address. Literally interpreting it as a binary mathematical operator operating on a string and a number doesn't make any sense either.
Since you're in a 64-bit process, all addresses should be treated as qwords (64-bits) instead of dwords (aka integer; 32-bits). Use readPointer(address) if you're uncertain.
Lua script:
Code: | local lastShip
myTimer = createTimer(nil, false)
myTimer.Interval = 3000
myTimer.OnTimer = function(t)
local currShip = readPointer("myShip") -- make sure "myShip" is a registered symbol
if currShip and currShip ~= lastShip then
print(string.format("Current ship: %X\tLast ship: %X", currShip, lastShip))
address = readPointer(currShip+40) -- should that be 0x40 instead?
print(string.format("First Pointer: %X", address))
lastShip = currShip
end
end |
AA script:
Code: | {$lua}
if syntaxcheck then return end
[ENABLE] -- CE will recognize these tokens even after a lua tag
myTimer.Enabled = true
[DISABLE]
myTimer.Enabled = false |
Quote: | How do you recommend debugging lua? | print(...) is a useful function. print(tostring(nil)) will print "nil". You can also use the simple debugger in the Lua engine window (click on the line number to set a breakpoint).
Quote: | Code: | mov eax, [myShip]//[[[[["myShip"+40]+40]+68]+10]+18] for counter value |
|
The pointer path would actually be [[[[[[myShip]+40]+... if that asm works. Otherwise, the correct instruction would be mov eax,[myShip+40]
A useful shortcut when dealing with pointers in Lua is that pointer path strings are a valid argument for an address parameter. Just make sure you don't get confused along the way. Using the example I just talked about previously:
Code: | local counterValue = readInteger("[[[[[myShip]+40]+40]+68]+10]+18") |
_________________
I don't know where I'm going, but I'll figure it out when I get there. |
|
Back to top |
|
|
cooleko Grandmaster Cheater Reputation: 11
Joined: 04 May 2016 Posts: 717
|
Posted: Mon Jun 06, 2016 3:38 pm Post subject: |
|
|
All of your advice worked, except for the activate script:
Using the code below, the Activation script couldn't be toggled.
Code: | {$lua}
if syntaxcheck then return end
[ENABLE] -- CE will recognize these tokens even after a lua tag
myTimer.Enabled = true
[DISABLE]
myTimer.Enabled = false |
Do you have any recommendations?
|
|
Back to top |
|
|
ParkourPenguin I post too much Reputation: 138
Joined: 06 Jul 2014 Posts: 4275
|
Posted: Mon Jun 06, 2016 3:42 pm Post subject: |
|
|
Remove the comment after [ENABLE].
Code: | {$lua}
if syntaxcheck then return end
[ENABLE]
myTimer.Enabled = true
[DISABLE]
myTimer.Enabled = false |
_________________
I don't know where I'm going, but I'll figure it out when I get there. |
|
Back to top |
|
|
cooleko Grandmaster Cheater Reputation: 11
Joined: 04 May 2016 Posts: 717
|
Posted: Mon Jun 06, 2016 3:47 pm Post subject: |
|
|
Got it, I'll finish converting the asm to lua sometime and then post it so that anyone else finding this thread can see a full example of a conversion.
I appreciate the help.
|
|
Back to top |
|
|
cooleko Grandmaster Cheater Reputation: 11
Joined: 04 May 2016 Posts: 717
|
Posted: Mon Jul 11, 2016 6:02 pm Post subject: |
|
|
It was so easy to rewrite into lua, but i forgot to actually post it here.
This isnt the same code as my example above, but it does the exact same thing in a different game, it reads the table size and steps down through the table entries editing a desired value.
Code: | myTimer.OnTimer = function(t)
currShip = readPointer("myShip")
if currShip ~= nil then
counterValue = readInteger("[[[[myShip]+48]+100]+10]+18")
for _o=1, counterValue do
_o= 32 + 8*(_o-1)
writeFloat("[[[[[myShip]+48]+100]+10]+"..string.format("%X",_o).."]+54",99)
writeFloat("[[[[[myShip]+48]+100]+10]+"..string.format("%X",_o).."]+68",99)
end
end
end |
|
|
Back to top |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum You cannot attach files in this forum You can download files in this forum
|
|