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 


Need some1 familiar with registering types

 
Post new topic   Reply to topic    Cheat Engine Forum Index -> Cheat Engine Lua Scripting
View previous topic :: View next topic  
Author Message
zxuiji
Advanced Cheater
Reputation: 1

Joined: 26 Sep 2016
Posts: 70

PostPosted: Mon Jan 15, 2018 7:59 am    Post subject: Need some1 familiar with registering types Reply with quote

I got part way there but given the poor resource I managed to locate I'm certain I did something wrong so I'd like someone to take a look at my code and point out my mistakes:
Code:

function EP2BYTES_78563412( B0, B2, B2, B3 )
  local bytes = '0x' ..
    zNum2Hex( B3 ) .. zNum2Hex( B2 ) ..
    zNum2Hex( B1 ) .. zNum2Hex( B0 )
  return zMathEv( bytes .. ' / 2000' )
end
function BYTES2EP_78563412( VAL )
         VAL = zMathEv( '' .. VAL .. ' * 2000' )
         VAL = zNum2Hex( VAL, 8 )
         local B0 = VAL[7] + VAL[8]
         local B1 = VAL[5] + VAL[6]
         local B2 = VAL[3] + VAL[4]
         local B3 = VAL[1] + VAL[2]
         return { B0, B1, B2, B3 }
end
registerCustomTypeLua( 'EP_t', 4, EP2BYTES_78563412, BYTES2EP_78563412 )

To be clear I want this type to be available via the table

_________________
Those who do not trust in christ to save them from their sins will only experience hell when their soul is released from it's earthly vessel.
Back to top
View user's profile Send private message
FreeER
Grandmaster Cheater Supreme
Reputation: 53

Joined: 09 Aug 2013
Posts: 1091

PostPosted: Mon Jan 15, 2018 10:46 am    Post subject: Reply with quote

It adds it, beyond that you may want to actually explain what it's supposed to do, what it's doing instead, and make sure you've provided _all_ the code (z* functions for example)...



hm looks like a simple /2000 * 2000 script in which case it's as simple as:

Code:
local function fromBytes(...) return byteTableToDword({...}) / 2000 end
local function toBytes(num) return unpack(dwordToByteTable(num*2000)) end
registerCustomTypeLua( 'EP_t', 4, fromBytes, toBytes)


note that unpack causes toBytes to return individual values, not a table.
Back to top
View user's profile Send private message
zxuiji
Advanced Cheater
Reputation: 1

Joined: 26 Sep 2016
Posts: 70

PostPosted: Mon Jan 15, 2018 12:48 pm    Post subject: Reply with quote

That's along the lines I'm looking for, thanks :) For reference are the 2 & 8 byte variations word and qword?
_________________
Those who do not trust in christ to save them from their sins will only experience hell when their soul is released from it's earthly vessel.
Back to top
View user's profile Send private message
FreeER
Grandmaster Cheater Supreme
Reputation: 53

Joined: 09 Aug 2013
Posts: 1091

PostPosted: Mon Jan 15, 2018 12:55 pm    Post subject: Reply with quote

Yep Smile (checkout celua.txt in the install directory, or https://github.com/cheat-engine/cheat-engine no guarantees that everything makes it into the documentation lol)

For some reason the read/write functions use "[Small]Integer" rather than "[d]word" though. Trivial to create a local rename though
Back to top
View user's profile Send private message
zxuiji
Advanced Cheater
Reputation: 1

Joined: 26 Sep 2016
Posts: 70

PostPosted: Mon Jan 15, 2018 1:30 pm    Post subject: Reply with quote

Thanks, final question for this topic, is this the right way for converting to/from text?
Code:

local mulDay = 1080000000
local mulHour = 45000000
local mulMinute = 800000
function BYTES2WTIME(...)
  local t = byteTableToDword({...})
  local D = t / mulDay
  local H = (t / mulHour) % 24
  local M = (t % mulHour) / mulMinute
  return ('D:' .. D .. ' H:' .. H .. ' M:' .. M)
end
function WTIME2BYTES(str)
  str = str.split(' ')
  local D = str[1].split(':')[2]
  local H = str[2].split(':')[2]
  local M = str[3].split(':')[2]
  local t = (D * mulDay) + (H * mulHour) + (M * mulMinute)
  return unpack(dwordToByteTable(t))
end
registerCustomTypeLua( 'WTIME_t', 4, BYTES2WTIME, WTIME2BYTES )


Edit: I stand corrected, my true final question is how to unregister a custom type, finding duplicates of my type each time I execute a test run

_________________
Those who do not trust in christ to save them from their sins will only experience hell when their soul is released from it's earthly vessel.
Back to top
View user's profile Send private message
TheyCallMeTim13
Wiki Contributor
Reputation: 50

Joined: 24 Feb 2017
Posts: 976
Location: Pluto

PostPosted: Mon Jan 15, 2018 1:44 pm    Post subject: Reply with quote

To do it in pure Lua with an ASCII string, you could use string.byte and string.char. There is ways to do it in Unicode as well.

For string to bytes:
Code:
local str = 'some text.'
local bytes = { string.byte(str, 1, -1) }
bytes[#bytes + 1] = 0
print(table.concat(bytes, ', '))




Then bytes to string:
Code:
local bytes = { 115, 111, 109, 101, 32, 116, 101, 120, 116, 46, 0 }
local str = ''
for i = 1, #bytes do
    str = str .. string.char(bytes[i])
end
print(str)

_________________
Back to top
View user's profile Send private message Visit poster's website
FreeER
Grandmaster Cheater Supreme
Reputation: 53

Joined: 09 Aug 2013
Posts: 1091

PostPosted: Mon Jan 15, 2018 2:07 pm    Post subject: Reply with quote

Hm, I don't believe custom types work with strings (I've never tried), for one thing it seems to assume a constant number of bytes (eg. 4) for input and output and strings typically aren't going to have that....

I can't think of any good alternatives either... the only thing I can think of that might work is creating your own form that's separate from the address list to translate it. Hm... you could use OnGetDisplayValue to change how it's displayed in the address list eg.

Code:
local firstmr = getAddressList().getMemoryRecord(0)
firstmr.OnGetDisplayValue = function(mr,value)
  return true, BYTES2WTIME(unpack(dwordToByteTable(value)))
end


but that won't let you change it using a string, you'd still get the integer version when you go to change it....I suppose you could add a new menu item to the popupmenu when it's right clicked to change it using your own logic rather than CE's default but that'd require the user to know about the alternative method.

hm.... perhaps someone else will know another way however. If not you might create a new topic with it as a feature request for the next version.


edit: as for unregistering, um... close CE? I don't believe there is a way to do so. Hm, perhaps you could call destroy on the returned customType object (or the one from getCustomType('name')...)
edit2: destroy seems to work for the address list but the scan value type list doesn't seem to be updated unless a new type is registered Very Happy
edit3: well you can just delete it manually from the scan list and that works as expected (if it hasn't been destroyed already).
Back to top
View user's profile Send private message
zxuiji
Advanced Cheater
Reputation: 1

Joined: 26 Sep 2016
Posts: 70

PostPosted: Mon Jan 15, 2018 2:53 pm    Post subject: Reply with quote

FreeER wrote:
...edit: as for unregistering, um... close CE? I don't believe there is a way to do so. Hm, perhaps you could call destroy on the returned customType object (or the one from getCustomType('name')...)
edit2: destroy seems to work for the address list but the scan value type list doesn't seem to be updated unless a new type is registered Very Happy
edit3: well you can just delete it manually from the scan list and that works as expected (if it hasn't been destroyed already).


I've now implemented this:
Code:

function zCustomType( NAME, SIZE, BYTES2VAL, VAL2BYTES )
  local t = getCustomType( NAME )
  while t do t.destroy() t = getCustomType( NAME ) end
  t = registerCustomTypeLua( NAME, SIZE, BYTES2VAL, VAL2BYTES )
  return t
end

Which at the very least seems to be preventing duplicates, the functions definitely get updated though since I had accidentally left the EP ones there when I copied pasted so I had to fix those just to see how my value was coming out. I tried modifying the functions after that and got a infinite error, thankfully I had already saved the important changes and just had to reboot CE. Here's what I currently have:
Code:

local mulDay = 1080000000
local mulHour = 45000000
local mulMinute = 800000
function BYTES2WTIME(...)
  local t = byteTableToDword({...})
  local D = t / mulDay
  local H = (t / mulHour) % 24
  local M = (t % mulHour) / mulMinute
  return string.format( 'D:%d H:%d M:%d', D, H, M )
end
function WTIME2BYTES(str)
  str = str.split(' ')
  local D = str[1].split(':')[2]
  local H = str[2].split(':')[2]
  local M = str[3].split(':')[2]
  local t = (D * mulDay) + (H * mulHour) + (M * mulMinute)
  return unpack(dwordToByteTable(t))
end
zCustomType( 'WTIME_t', 4, BYTES2WTIME, WTIME2BYTES )

I'll think about how to use the advice TheyCallMeTim13 gave while you/you both take a look

_________________
Those who do not trust in christ to save them from their sins will only experience hell when their soul is released from it's earthly vessel.
Back to top
View user's profile Send private message
TheyCallMeTim13
Wiki Contributor
Reputation: 50

Joined: 24 Feb 2017
Posts: 976
Location: Pluto

PostPosted: Wed Jan 17, 2018 2:19 am    Post subject: Reply with quote

I was working on my MGSV table and came up with this to display a time string, thought it might help.

This holds the time in seconds.
Code:
[ptrTimeHook]+4C


Code:
{$lua}
if syntaxcheck then return end


------------------------------ ENABLE ------------------------------
[ENABLE]
MGSV_TIME_MR = nil
local text = 'MGSV - Time of Day'
local function setupMR()
  if memrec ~= nil then
    MGSV_TIME_MR = AddressList.getMemoryRecordByDescription(text)
    if MGSV_TIME_MR == nil then
      MGSV_TIME_MR = AddressList.createMemoryRecord()
    end
    MGSV_TIME_MR.Description = text
    MGSV_TIME_MR.Type = vtDword
    MGSV_TIME_MR.DontSave = true
    MGSV_TIME_MR.Address = '[ptrTimeHook]+4C'
    MGSV_TIME_MR.OnGetDisplayValue = function(memoryrecord, valuestring)
      if type(valuestring) == 'string' and tonumber(valuestring) ~= nil then
        local secs = tonumber(valuestring)
        local h = math.floor(secs / (60 * 60))
        local m = math.floor(secs / 60 % 60)
        local s = math.floor(secs % 60)
        return true, string.format("%.2d:%.2d:%.2d", h, m, s)
      else
        return false, valuestring
      end
    end
    MGSV_TIME_MR.appendToEntry(memrec)
  end
end
if syntaxcheck then return end
setupMR()
------------------------------ DISABLE ------------------------------
[DISABLE]
if syntaxcheck then return end
if MGSV_TIME_MR ~= nil then
  MGSV_TIME_MR.delete()
end


Quote:
a % b == a - math.floor(a/b)*b

_________________
Back to top
View user's profile Send private message Visit poster's website
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