General Structures and Remote Windows - nt153133/RebornBuddy-Tutorials GitHub Wiki
General structures:
The base structure/class of most objects in reborn is RemoteObject, basically it’s anything object that has a direct pointer to it which is the base of Characters, BattleCharacters, RemoteWindows, AgentInterface etc. Main attributes are that it has the properties: Pointer, VTable, IsValid. Which means if you need the pointer of a certain RemoteWindow you can do ContentsFinderMenu.Pointer or same for Core.Me.Pointer.
RemoteWindows
First I’ll focus on RemoteWindows. They are the ones most often needing to be reversed. One of the main reasons to reverse part of a remote window is to be able to use SendAction to press a certain button or simulate clicking on a part of the window. While you can just randomly try parameters to use sendaction on there is an easier way using Cheat Engine.
First you’ll need the current offset of the SendAction function for the current client version, these offsets only change when client updates are released. For simplicity's sake you can run this command in reborn console to get the an offset in the SendAction function that I use to set a breakpoint. This is not the SendAction offset RB uses, it calls a function that calls this function of which this memory offset is at a line after it handles the stack
ClearLog();
var patternFinder = new GreyMagic.PatternFinder(Core.Memory);
IntPtr SendActionBreakpoint = patternFinder.Find("48 85 C0 74 ? 48 89 18 4C 8D 70 ? 49 8B C6 48 85 DB 74 ? 89 30");
string address = string.Format("{0:X}",Core.Memory.GetRelative(SendActionBreakpoint).ToInt64());
Log("ffxiv_dx11.exe+" + address);
That will give you a result such as ffxiv_dx11.exe+4F177D
.
Now load up CheatEngine, Attach it to ffxiv_dx11.exe and add a new address manually and for the address paste in the result from the above command so for this version it's ffxiv_dx11.exe+4F177D
Then right click that address and hit disassemble this memory region. This is the line you'll want to set a breakpoint on. Don't set the breakpoint yet.
Now a lot of things trigger this function including some mouse over and almost every mouse click so at this point it's important to have the window open that you want to get the info on. Once the window is open in the client right click that line in CE and
Set Breakpoint (F5)
. Then click the button you want in the client. For this example i'm going to use the trust window and click the Register for Duty button. The game will freeze and cheat engine will move to the break screen.
Notice the list of registers on the right side, while CE still has the game paused right click RDI
and click Show in hexview which will change the bottom left panel. This is basically the stack version of the array of parameters that were passed in along with the window information. At this point your best bet is to hit Print Screen on your keyboard and paste the screenshot into paint because if you leave FFxiv paused too long you'll be kicked from the server. So screenshot it, untoggle the breakpoint and click run.
It's important to note that these parameters are always in pairs, there will ALWAYS be an even amount of them. In this case it's 1 pair...2 numbers, 0x03 and 0x0E. Most of the time it'll be the pairs listed then all zeros, some times there's info directly after but you're looking for one or more pairs of numbers in the first 4 bytes of each line of the stack. If the whole line contains bytes then you've gone too far like the last line in the green box. 80% of the time the first number of the pair will be 0-3 so it's fairly easy to tell.
Another example from the trust window would be this one from clicking Alisaie (the 2nd npc)
In this case there are 2 pairs (3,0xC,4,1) and as is the case with a lot of UI elements which repeat one of the parameters is basically an index. Here it's the 4th value. If you check the parameters when clicking on the first npc you'll see it's (3,0xC,4,0), 3rd is (3,0xC,4,2) etc. So using that fact you could create a function which clicks set npcs
public void PressNpcSelection(int npc)
{
if (WindowByName != null && npc < 6) WindowByName.SendAction(2, 3, 12, 4, (ulong) npc);
}
In LlamaLibrary I created an abstract class to inherit for RemoteWindows which I'll have to make documentation for but at least for me it simplifies a lot of repeat remotewindow code: It includes the ___Elements code, a wrapper for SendAction which makes sure the window is open, get the agent ID and the default close().
The ___Elements array will have to be another whole section, I have a UIChecker botbase which is a mess of random testing but you can click Settings, then Refresh, then select a window and click Select. That will give the list of elements in the window. Ignore the aptly named Buttons 4-7, UI is not my favorite thing to do so most of the time I make a new default button when needing to test something. The botbase isn't really meant for public consumption but someone might find it useful.