RHCP Classmemory

Get help with using AutoHotkey (v1.1 and older) and its commands and hotkeys
Galaxis
Posts: 73
Joined: 04 Feb 2016, 20:09

RHCP Classmemory

27 Jun 2019, 15:14

My problem is the Autohotkey tooltip is only displaying the letter "M" when I want it to display ALL of that text outlined in BLUE.
The length is set to 1000, so it should show all of that. What's the problem here, and how do i fix it?

Function:
Exile := poe.readString(0x7FFB69C3AE78, length := 1000, encoding := ""utf-8"")

I want to force the function to read all that text:

matches the one supplied on a handle that's active. open the opration requires an inactive closed handle.
The operation must be restarted... etc.


I need the function to read all of that.
Please advise, thanks.

Image

Below is an example of the function working as intended. The tooltip shows up to 1000 chars, as I specified by length.

Image
Last edited by Galaxis on 28 Jun 2019, 16:32, edited 1 time in total.
User avatar
rommmcek
Posts: 1473
Joined: 15 Aug 2014, 15:18

Re: RHCP Classmemory

27 Jun 2019, 21:43

It seems you encountered "null terminated string" problem. So you should consider other methods to parse your data.
If you don't have other options try e.g. something like this:

Code: Select all

Mf:="A_Full_Valid_Script_Path_And_Name"

if FileExist(mF)
	FileRead, mData, % "*c " mF
else {
    MsgBox File doesn't exist!
    ExitApp
}

ePtr:=StrLen(mData), sPtr:=mPtr:=&mData, cmPtr:=2*ePtr

while (mPtr-sPtr<=cmPtr)
        if ((Character:=*mPtr++)!=0)
            variable.=Chr(Character)

MsgBox % variable
It skips binary zeros, will work only for ANSI (not Unicode!), and its quick adaptation form an other script - hence no guaranty!
RHCP
Posts: 202
Joined: 30 Sep 2013, 10:59

Re: RHCP Classmemory

28 Jun 2019, 00:18

The first string is unicode.
Try:

Code: Select all

Exile := poe.readString(0x7FFB69C3AE78,, encoding := "UTF-16")
Galaxis
Posts: 73
Joined: 04 Feb 2016, 20:09

Re: RHCP Classmemory

28 Jun 2019, 15:28

RHCP wrote:
28 Jun 2019, 00:18
The first string is unicode.
Try:

Code: Select all

Exile := poe.readString(0x7FFB69C3AE78,, encoding := "UTF-16")
What is this supposed to do, besides change the English text to look like Japanese characters instead? UFT-8 I understand as English, and reads perfectly for what I'm trying to accomplish.

It still refuses to show text beyond the first encountered null.

This is my code for the AOB scan to find the bytes for Hotbar.dat

Code: Select all

Hotbar:= XIV.hexStringtoPattern("48 4F 54 42 41 52 2E 44 41 54 00 00 01 00 00 00 70")
I'll save the address starting at HOTBAR.DAT. and then read subsequent text up to 1000 characters
which will cover all the skills/keybinds on the hotbars.
Reading all these hotkeys, quite simply informs the program I'm writing, what all the keybinds are and what to press for said abilities.

In this example here, I simply want to read all the Abilities on my Final Fantasy 14 hotbar?
Image

Lol, I don't understand why that Length size is there is null completely negates it.


AHK will absolutely display the string HOTBAR.DAT with the readString(address,, encoding :="UTF-8") function. Japanese if its UTF-16.
However, it will not read beyond the 0 byte after that.

So what's the point of specifying length?

Is it possible to read all the hotkey text, even across the encountered nulls between the skills?
AOB scan isn't optimal, because it won't read changes to the hotbar in real-time.
People change hotkeys and move skills around all the time. The pattern won't be the same, and the bot will press wrong buttons.


What other function ignores nulls, reads between a range of addresses, and obeys specified byte length?
AOB scans take too damn long, because I have to write AOB patters for every single spell/skill keybind in Final Fantasy.

@rommmcek
Currently, I am using an increment of =+1 from the base address to read all the bytes individually and parse each character/letter in order, and paste all that text file, and read from file.

But that's so exhausting. If only it can read it all.
A readstring function that ignores the nulls and obeys the length would be simple, if it exists.

@RHCP
Any solution you can give just to read text across the range of 2 specified addresses would be invaluable. Please HALP! Thanks
RHCP
Posts: 202
Joined: 30 Sep 2013, 10:59

Re: RHCP Classmemory

29 Jun 2019, 14:14

Galaxis wrote: What is this supposed to do, besides change the English text to look like Japanese characters instead? UFT-8 I understand as English, and reads perfectly for what I'm trying to accomplish.

It still refuses to show text beyond the first encountered null.
The first picture you posted shows Unicode (UTF-16) text. Each character is represented by two bytes with the higher byte being 0 (in most cases... at least for English). I assume the reason you got Japanese like text was you tried reading an ASCII or UTF-8 string (e.g. from your second picture) as UTF-16.
Galaxis wrote:
28 Jun 2019, 15:28
Lol, I don't understand why that Length size is there is null completely negates it.


AHK will absolutely display the string HOTBAR.DAT with the readString(address,, encoding :="UTF-8") function. Japanese if its UTF-16.
However, it will not read beyond the 0 byte after that.

So what's the point of specifying length?
The point of the length parameter is to allow you to read strings that do not contain null characters or to read part of a larger string (which doesn't include the null terminator). Also, it's much faster when specifying a length.

Just so you understand, when the length parameter is 0 readString() will only read up to the null terminator (inclusive).
When you specify a length then readString() reads that number of bytes, but the AHK strget() function (that converts the bytes to a string) will always stop the converting at the null terminator...as that's how null terminated strings are meant to work.

As for you final fantasy issue, that's something you will have to solve. All part of the process :)
I can't tell what exactly you need to extract from that screeshot.... is it just the text "Heavy Shot [1]" and "Stormbite [2]" etc? or are there other letters you need?
If it helps, it looks like each of those skills are 0xDA bytes away from the previous one i.e. the 's' in Stormbite is 0xDA bytes away from the 'H' in heavy Shot. You could probably just work out where the first one is and then read each string using the offset.

Otherwise, you will need to do something like rommmcek pointed out.
Or read use readRaw() to read the entire memory area as binary, then manually loop through and replace the null bytes ( using numget() / numput()) with another value and then convert the entire thing to a string using strget().... but then you will have a whole heap of weird characters between each section that you're interested in.
Galaxis
Posts: 73
Joined: 04 Feb 2016, 20:09

Re: RHCP Classmemory

30 Jun 2019, 08:09

RHCP wrote:
29 Jun 2019, 14:14
Galaxis wrote: What is this supposed to do, besides change the English text to look like Japanese characters instead? UFT-8 I understand as English, and reads perfectly for what I'm trying to accomplish.

It still refuses to show text beyond the first encountered null.
Otherwise, you will need to do something like rommmcek pointed out.
Or read use readRaw() to read the entire memory area as binary, then manually loop through and replace the null bytes ( using numget() / numput()) with another value and then convert the entire thing to a string using strget().... but then you will have a whole heap of weird characters between each section that you're interested in.
@RHCP

Correct, I need only the text.
HeavyShot and Stormbite are bound to Hotbar keys 1 and 2. That's the information I need for every skill from 0 - 9 and [Shift+ 0-9] and [Ctrl+ 0-9].
The byte information following HOTBAR.dat contains what my program needs to read.
The colorful image to the left of that just illustrates the actual skills in the game.

Yeah, my original script already uses Rommmcek's method of running the +=1 increment as the offset from the inital address where HOTBAR.dat (aob pattern) is found to read all hotbar keybinds. I was just hoping for a much cleaner way of reading it all. Either way, I really appreciate that library RHCP. Thanks for the response, your hard work, and have a great day!
User avatar
rommmcek
Posts: 1473
Joined: 15 Aug 2014, 15:18

Re: RHCP Classmemory

02 Jul 2019, 05:20

Obviously I can't give you such profound advices as RHCP and you alone seem to be ahead of me!
Nevertheless here is my second thought. If you know where to fish:

Code: Select all

while (mPtr-sPtr<=cmPtr && A_Index<0x7ffb69c3b3ee) ; addresses taken from your pic above
        if ((Character:=*mPtr++)!=0 && A_Index>0x7ffb69c3ae76)
            variable.=Chr(Character)
The output'll be more concise.

P.s.: If you don't already do, don't forget to use SetBatchLines, -1 at start of the script.

Return to “Ask for Help (v1)”

Who is online

Users browsing this forum: Descolada and 302 guests