Public Macros Accessing Character Information from a Spawn
Reply
Accessing Character Information from a Spawn
So, I've written a whole suite of macros. One thing that really annoys me is Targeting for information. There seems to be a delay with accessing members of a target, something like 400 milliseconds. It ends up taking longer to wait for this delay, than it does to run an entire loop of the script. It's also really frustrating when you're trying to take control of an automated character; it's always targeting about finding things, scanning, checking for buffs, HPs etc.

My question is: Is there any way to access character information from a spawn, so that I don't have to use Target? I know that a group member is a character, but I can only access them as a spawn. I think this is because targeting requests information internally about a character, but previous to this, it is private (?). The documentation talks about type-casting, but I can't find a use for it. I would think if I know an object is a character, I should be able to do something like ${NearestSpawn[${n}(character)].PctHPs}, but this seems to segfault.

Any pointers here, all-knowing Maudigan?

Edit: I should mention that I am familiar with and use MQ2NetBots. It is a wonderful plugin, and helps immensely for clients connected to my local host. But this is something more. I want to be able to buff and heal third party clients... Random people I raid with, friends, etc.
Wed Oct 25, 2017 12:38 am
Hmm have not played in a long time, could you use Raid and raidmember which has access to spawn for something like
Macro
More +
${Raid.Member[Soandso].PctHPs}


I'll dig through my macro's and see if I can find something but 112% of the time I was on servers where you basically played solo and boxed so not sure if I have any workable example's of raid use that does not involve targeting.
_________________
To be continued...
Wed Oct 25, 2017 5:13 am
Listen to This Guy
Typecasting a spawn as a character wouldn’t help unfortunately. The information just isn’t there.

So think of a spawn as a list of numbers and values relating to that spawn. Like these two spawns below. In memory they’ll be butted up just like this, or some other unrelated value may be butted up after them.

Maudigan
44
102.33
95.2
59.3
Monk
Warmonger
45
383.4
938.6
24.3
Warrior

So the spawn structure looks something like this:

Name
Level
X coord
Y coord
Z coord
Class

And a character structure might have extra values, like this:

Name
Level
X coord
Y coord
Z coord
Class
Surname

So, it’s just an extra value tagged on the end of a spawn object. So if you typcasted Maudigan as a character and try to print his Surname it would print “warmonger” since that’s what’s sitting in that spot. That or it would error/crash.

Maudigan
44
102.33
95.2
59.3
Monk
Warmonger
45
383.4
938.6
24.3
Warrior

In short, typecasting doesn’t really change an object, it just lets you treat it as if it’s that object. Like, if I told you to pretend like I had a helmet on and told you to punch me in my helmet. The pretending doesn’t create a helmet, it just results in a bloody nose. Those extra values just don’t exist in the client anywhere.

I’m not getting why targeting gives that info though... I thought Target was a spawn type, not a character. Maybe that’s changed, it’s been a long time since I wrote a Macro. Are you maybe referring to how stale the data is on spawns other than your target? Like the Spawn[] for one of your characters reporting 55% life, but when your target him and use the Target variable, it jumps up to 100%. I think that has to do with how the server prioritizes update packets. It doesn’t update non-target information very frequently, but targets get lots of updates.

Either way, there’s not a whole lot to be done about it outside of using Netbots. Honestly netbots is probably more accurate than using Target anyway. Netbots updates really quickly and efficiently.

Maybe ask on some other forums too, maybe someone has a clever solution.
Thu Oct 26, 2017 5:44 pm
Project Lead
My solution when I played was we all connected to each others EQBC so the raid member data was available but I know a lot of people either don't know how or wouldn't want to do that.
Sat Oct 28, 2017 9:04 pm
Listen to This Guy
Maudigan,

I find it pretty god damn amazing that MQ2 is able to hijack virtual memory space by the byte and sort it into structs such as spawns and characters. Whoever made this stuff is brilliant. Perhaps more rhetorical than actually asking, but I certainly wonder how MQ2 even gets into the clients address space without seg faulting... Lots of the Windows version of MMAP? I suppose windows uses handles though, which I think are accessible globally, and probably have named identifiers?

So, you're right. A target is a spawn, and healing with NearestNPC should be a cinch, since HP information is available via spawn. But something peculiar about Target, is that it is indeed not a character, but you can access .Buff, which is not available under spawn. So Target is an exception to the inheritance rule.

Warmonger,

Both good ideas. Thank you. The remote server is probably the best idea, because I can get buff information. I thought this was a possibility, since my EQBCS is setup as local host. It's a wonderful idea that would solve all me problems. I imagine I would need to forward the port that the server is listening on, and give my IP to my friends?
Sun Oct 29, 2017 5:39 pm
Rodger that, set a port forward and have people connect to the IP. Honestly can't recall if domain name would work, I know at that time I had a DDNS setup.

Besides having important information available to you for Netbots, we all had copies of each other's macros so if someone had to go on a extended AFK the other person (or designated person in multi player situations) could activate the macro they preferred on the AFK person.
Tue Oct 31, 2017 1:22 pm
Listen to This Guy
It’s been awhile since I read it, but I believe this book has a section on DLL injection

https://www.amazon.com/Exploiting-Online-Games-Massively-Distributed/dp/0132271915/ref=sr_1_6?s=books&ie=UTF8&qid=1509678099&sr=1-6

If I’m remembering right it even lays out some generic c++ code for injecting into a running process.

As far as finding the data in the client, cheat engine is handy. It lets you search a processed memory for a series of bytes. So for example you can scan for all DWORDs. Then you can cast “shrink” on yourself, and then tell cheat engine to research your result set for anything that got smaller. Then cast “grow” and research for anything that got bigger, etc. eventually you can find where your model size is stored. That can get you on the right track to finding your spawn structure and the functions that read/write to it. Getting just a little familiar with the way c++ compiles into assembly helps with that—it doesn’t take much familiarity mostly just the calling conventions. Working off the existing road map (all the offsets and function names in MQ) makes it a lot easier.... it’s hard to imagine how the guys who started this did so from scratch... it’s pretty mind boggling.

If your interested in this stuff that book is an okay starting place. “reversing: secrets of reverse engineering” by eldad eilam, and the “IDA Pro Book” are good, the first walks you through converting assembly code into c++ structures and classes, and the second is basically a users manual for IDA pro. Pretty boring reading, but effective.
Thu Nov 02, 2017 9:23 pm
Project Lead
Public Macros Accessing Character Information from a Spawn
Reply