Cheat Engine Forum Index Cheat Engine
The Official Site of Cheat Engine
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 


Questions on starting lua and any tips to convert asm code

 
Post new topic   Reply to topic    Cheat Engine Forum Index -> Cheat Engine Lua Scripting
View previous topic :: View next topic  
Author Message
cooleko
Grandmaster Cheater
Reputation: 11

Joined: 04 May 2016
Posts: 717

PostPosted: Mon Jun 06, 2016 12:55 pm    Post subject: Questions on starting lua and any tips to convert asm code Reply with quote

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
View user's profile Send private message
ParkourPenguin
I post too much
Reputation: 138

Joined: 06 Jul 2014
Posts: 4275

PostPosted: Mon Jun 06, 2016 3:10 pm    Post subject: Reply with quote

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
View user's profile Send private message
cooleko
Grandmaster Cheater
Reputation: 11

Joined: 04 May 2016
Posts: 717

PostPosted: Mon Jun 06, 2016 3:38 pm    Post subject: Reply with quote

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
View user's profile Send private message
ParkourPenguin
I post too much
Reputation: 138

Joined: 06 Jul 2014
Posts: 4275

PostPosted: Mon Jun 06, 2016 3:42 pm    Post subject: Reply with quote

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
View user's profile Send private message
cooleko
Grandmaster Cheater
Reputation: 11

Joined: 04 May 2016
Posts: 717

PostPosted: Mon Jun 06, 2016 3:47 pm    Post subject: Reply with quote

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
View user's profile Send private message
cooleko
Grandmaster Cheater
Reputation: 11

Joined: 04 May 2016
Posts: 717

PostPosted: Mon Jul 11, 2016 6:02 pm    Post subject: Reply with quote

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
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic    Cheat Engine Forum Index -> Cheat Engine Lua Scripting All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
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


Powered by phpBB © 2001, 2005 phpBB Group

CE Wiki   IRC (#CEF)   Twitter
Third party websites