Jump to content
  • 0

Lua Script: How to get utf-8 characters from memory and alert


dolphinorca
 Share

Question

I've finally come to understand the Lua language a bit.

So I decided to make a Lua script as a trial, but my work situation got stuck.

The GG reference does not have an API to get the utf-8 string from the address.

So I got the bytes, but I didn't have lua to convert from hexadecimal to utf-8.

(It really was, but I don't know how to use it, and probably not in Game Guardian)

Do you know how to get utf-8 from an address or convert from hexadecimal to utf-8?

(Use google translate)

Edited by dolphinorca
Link to comment
Share on other sites

10 answers to this question

Recommended Posts

  • 0

U can just search the utf-8 for example:

 

gg.searchNumber(":(text here)", gg.TYPE_BYTE, false, gg.SIGN_EQUAL, 0, -1, 0) 
gg.clearResults() 

 

If you're not sure you can use the "record script" function in GG.  Which you can find it here:

1450885348_Screenshot_20220612-112436_X8Sandbox.thumb.jpg.a8dcc85cf9f71a8103a6ae76fd1dd5e7.jpg

Edited by SAGEPAPI
Link to comment
Share on other sites

  • 0

thank you! I will try it at a later date!

56 minutes ago, SAGEPAPI said:

U can just search the utf-8 for example:

 

gg.searchNumber(":(text here)", gg.TYPE_BYTE, false, gg.SIGN_EQUAL, 0, -1, 0) 
gg.clearResults() 

 

If you're not sure you can use the "record script" function in GG.  Which you can find it here:

1450885348_Screenshot_20220612-112436_X8Sandbox.thumb.jpg.a8dcc85cf9f71a8103a6ae76fd1dd5e7.jpg

thank you! I will try it at a later date!

Link to comment
Share on other sites

  • 0
22 hours ago, SAGEPAPI said:

U can just search the utf-8 for example:

 

gg.searchNumber(":(text here)", gg.TYPE_BYTE, false, gg.SIGN_EQUAL, 0, -1, 0) 
gg.clearResults() 

 

If you're not sure you can use the "record script" function in GG.  Which you can find it here:

1450885348_Screenshot_20220612-112436_X8Sandbox.thumb.jpg.a8dcc85cf9f71a8103a6ae76fd1dd5e7.jpg

Hmm ... Sorry it seems different from what I had imagined.

I searched using that code, but the result was a byte display instead of a letter.
The reason why I am particular about UTF-8 is to get Japanese.
image.thumb.png.1d3192fe1e02d5b71f01c43eeadba9fd.png

I'll put the script I'm writing here.

minhaya Scripts.lua

Link to comment
Share on other sites

  • 0

To output a string Lua implementation in GG treats it as UTF-8 (by themselves Lua strings are just byte arrays), so reading bytes from memory to Lua string and passing the string to a function that outputs it ("print", "gg.alert", "gg.toast", etc) should be enough to achieve desired result in your case.

Here is an example of function for reading bytes from memory and constructing string from them: 

function readBytesToString(address, length)
  local values = {}
  for i = 0, length - 1 do
    values[i] = {address = address + i, flags = gg.TYPE_BYTE}
  end
  values = gg.getValues(values)
  local bytes = {}
  for i, v in ipairs(values) do
    bytes[i] = v.value & 0xFF
  end
  return string.char(table.unpack(bytes))
end

Call it with address to read from as first argument and amount of bytes to read as second argument, for example: 

local startAddress = 0x12340000
local bytesToRead = 20
local result = readBytesToString(startAddress, bytesToRead)
print(result)
Link to comment
Share on other sites

  • 0
6 hours ago, CmP said:

To output a string Lua implementation in GG treats it as UTF-8 (by themselves Lua strings are just byte arrays), so reading bytes from memory to Lua string and passing the string to a function that outputs it ("print", "gg.alert", "gg.toast", etc) should be enough to achieve desired result in your case.

Here is an example of function for reading bytes from memory and constructing string from them: 

function readBytesToString(address, length)
  local values = {}
  for i = 0, length - 1 do
    values[i] = {address = address + i, flags = gg.TYPE_BYTE}
  end
  values = gg.getValues(values)
  local bytes = {}
  for i, v in ipairs(values) do
    bytes[i] = v.value & 0xFF
  end
  return string.char(table.unpack(bytes))
end

Call it with address to read from as first argument and amount of bytes to read as second argument, for example: 

local startAddress = 0x12340000
local bytesToRead = 20
local result = readBytesToString(startAddress, bytesToRead)
print(result)

It worked as I expected and the result was as I expected! Thank you!!! 
I don't know how it works, but I don't care.
image.thumb.png.57c31ceceb76ac263909edfafaceca67.png

Put the script that actually worked here.

minhaya Scripts.lua

So ... will it be solved automatically here?

Link to comment
Share on other sites

  • 0

You should also consider refactoring the code to make it simpler and cleaner. For example, your "MENU1" function can be refactored to something like the following: 

function MENU1()
  gg.setRanges(gg.REGION_ANONYMOUS)
  gg.clearResults()
  gg.searchNumber(':","answer":"', gg.TYPE_BYTE)
  local count = gg.getResultsCount()
  local results = gg.getResults(count)
  local answers = {}
  for i = 1, count, 12 do
    local address = results[i].address + 12
    local maxLength = 1024
    local answer = readBytesToString(address, maxLength)
    answer = answer:match('[^"]*') -- match part up to first quote character
    table.insert(answers, answer)
  end
  for number, answer in ipairs(answers) do
    print(string.format("Answer #%d:", number), answer)
  end
  gg.alert("Answer See [ON]")
end

Let me know, if the code above works for you.

Link to comment
Share on other sites

  • 0
1 minute ago, CmP said:

You should also consider refactoring the code to make it simpler and cleaner. For example, your "MENU1" function can be refactored to something like the following: 

function MENU1()
  gg.setRanges(gg.REGION_ANONYMOUS)
  gg.clearResults()
  gg.searchNumber(':","answer":"', gg.TYPE_BYTE)
  local count = gg.getResultsCount()
  local results = gg.getResults(count)
  local answers = {}
  for i = 1, count, 12 do
    local address = results[i].address + 12
    local maxLength = 1024
    local answer = readBytesToString(address, maxLength)
    answer = answer:match('[^"]*') -- match part up to first quote character
    table.insert(answers, answer)
  end
  for number, answer in ipairs(answers) do
    print(string.format("Answer #%d:", number), answer)
  end
  gg.alert("Answer See [ON]")
end

Let me know, if the code above works for you.

sorry. I'm confused if it's not my own code, and because of the 1024 byte limit(How to raise the limit, how to get one byte at a time, I don't know which is faster.), I use my own code. Thank you for the simplified code. I will refer to it.

So, I was told the code, but I couldn't get it normally. (You can fix it by changing "local address = results[i].address + 12" to +11. I've noticed it in advance and I don't know why I subtract 1.)

image.thumb.png.e324c7c496169fc24237b1990af70b59.png

Link to comment
Share on other sites

  • 0
13 minutes ago, dolphinorca said:

and because of the 1024 byte limit

The idea is to read enough bytes at once and then trim the string to first occurrence of quote character instead of reading one byte at a time until quote character is encountered. Generally, first approach should be better in terms of performance, because each read from memory takes significantly more time than several Lua operations, even if just one byte needs to be read.

25 minutes ago, dolphinorca said:

So, I was told the code, but I couldn't get it normally. (You can fix it by changing "local address = results[i].address + 12" to +11. I've noticed it in advance and I don't know why I subtract 1.)

I thought to add 12 to get position of first byte of the answer that is the next one after last quote character in searched string. I don't immediately see why it doesn't work as expected, but it seems that there is a mistake somewhere and it's fixed by your correction to use "+ 11" instead of "+ 12".

Link to comment
Share on other sites

  • 0
13 hours ago, CmP said:

The idea is to read enough bytes at once and then trim the string to first occurrence of quote character instead of reading one byte at a time until quote character is encountered. Generally, first approach should be better in terms of performance, because each read from memory takes significantly more time than several Lua operations, even if just one byte needs to be read.

I thought to add 12 to get position of first byte of the answer that is the next one after last quote character in searched string. I don't immediately see why it doesn't work as expected, but it seems that there is a mistake somewhere and it's fixed by your correction to use "+ 11" instead of "+ 12".

I will use the faster method that you have taught me.  thank you very much!

Link to comment
Share on other sites

  • 0
On 6/14/2022 at 7:38 PM, CmP said:

The idea is to read enough bytes at once and then trim the string to first occurrence of quote character instead of reading one byte at a time until quote character is encountered. Generally, first approach should be better in terms of performance, because each read from memory takes significantly more time than several Lua operations, even if just one byte needs to be read.

I thought to add 12 to get position of first byte of the answer that is the next one after last quote character in searched string. I don't immediately see why it doesn't work as expected, but it seems that there is a mistake somewhere and it's fixed by your correction to use "+ 11" instead of "+ 12".

I'm still waiting for approval, but I've uploaded the script!

minnade hayaoshi quiz(みんなで早押しクイズ) Script Cheating EXAM V1.5 (#dx8430vl)

And the execution speed is obviously faster. Here is a script that can compare speeds.

minhaya Scripts fix.lua

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.