View Full Version : access method for previous global var
Well instead of looking around a lot and tring to find the proper
variable/class, can someone please let me know the new way to
access the old global array m_spawns[x].
Looks like spawnshell now. I would mainly like to obtain the
spawn data for xID where as it used to be m_spawns[id].
Do I need to do a findID now?
Thanks.
Yendor
01-05-2002, 10:34 AM
Yeah I had the same problem. It doesn't appear you can access it globally now, you have to access it through a spawnshell instance as the actual list is private to that class. I wish they hadn't done that, would have liked to be able access the current spawnlist globally. I haven't looked too closely, maybe it is kept seperately for each map and that is why it is no longer global.
Makes it a little harder to put in some of my logging/database functions I want to play with at a low level. For instance from packet.cpp I can no longer look up a spawnid to find the spawn name. Something I wanted to do for my extra logging, I found I could stick it higher up in the emits to spawnshell but I really didn't want to do that (means modifying more files and I wanted to keep my changes very localized).
I could be wrong, I didn't look too carefully at how it is all put together now.
I'd have to look at how spawnshell class is used, and maybe some methods could be added to achieve my desired use.
For now I just changed how my project will work and I like it better and I no longer need to look up spawn names in that
fashion.
Zaphod
01-05-2002, 03:35 PM
The "old global array m_spawns[x]" doesn't exist any more (which wasn't really global anways). There was an array in the Map class and a QList in the EQPacket class both with data that replicated what was in the SpawnShell and each other (this duplication of data really added a lot of bloat to ShowEQ's memory usage). The SpawnShell manages an STL map of Spawn data in a format independent of the network transfer format.
To retrieve information on a specific spawn by id, you can retrieve it using the SpawnShell's findID() method with a type of tSpawn which returns a pointer to the const Item base class of the Spawn object as such:
const Item* item = m_spawnShell->findID(tSpawn, spawnId);
where spawnId is the number of the spawn you are requesting.
You can coerce this to the const Spawn type using either the safe spawnType inilne function (which will only do the conversion if you actually have an instance of the Spawn class) and returns NULL otherwise, for example:
const Spawn* spawn = spawnType(item);
if (spawn != NULL)
{
// whatever read access you wanted to make to the Spawn object
}
Or if your usage of findID always passes the tSpawn itemType and you wanna play fast and loose you can just cast it to the const Spawn type as follows:
const Spawn* spawn = (const Spawn*)item;
If for some odd reason you need to get an iterator over the map of spawns you can do the following:
[const]
// retrieve a const reference to the map that the spawns are stored in.
const ItemMap& itemMap = m_spawnShell->spawns();
// declare an iterator over the set of spawns
ItemConstIterator it;
// variable to store the pointer to the Item base class
const Item* item;
// variable to store the pointer to the Spawn class
const Spawn* spawn;
// iterate over the spawns
for (it = itemMap.begin(); it != itemMap.end(); ++it)
{
// retrieve a pointer to the item
item = it->second;
// coerce it to the Spawn type
spawn = (const Spawn*)item;
// perform whatever read accesses you need on the spawn object.
}
[/code]
These are not globablly accessible in a non-const fashion because it protects the SpawnShell from people accidentally deleting or modifying the Spawn data in an uncontrolled fashion thus creating hard to track down bugs. The only class that should be modifying the Spawn's data is the SpawnShell. There used to be a lot of bugs/problems caused by the uncontrolled modification of these data structures and the data passed into notifications.
As to Yendors comment, the spawn logging stuff should never have been hacked into the EQPacket class in the first place. It is easy enough to create an object that receives all the correct notifications to do the logging elsewhere. As to finding a spawns name by id, I'd suggest looking at the SpawnShell class (see the methods I listed above). One of my running projects is to migrate ShowEQ to a variant of the logging that SINS does (which would add back the spawn logging).
Enjoy,
Zaphod (dohpaZ)
Yendor
01-05-2002, 03:58 PM
Aye, I just like logging stuff at the lowest level possible for some of what I am doing. I agree that the general logging should all be done elsewhere. Will need to learn some Qt to do that, never done anything with Qt before (all the slot/signal stuff in particular).
Been thinking I might just work off the raw logs that you can still generate now I think and then I don't have to modify showeq at all (which would be better, I hate putting in special case code that I have to maintain seperately with patches).
Yendor
01-05-2002, 04:21 PM
Just looked, can't use the raw log as you don't log the decoded ZoneEntry.
Maybe this already exists somewhere, in which case correct me, but otherwise would you be interested in a patch that did:
Selectively logs all packets in a quasi human readable form based on a variable set in showeq conf (a bitmask flagging each opcode to be logged or not). The output form being:
<flag> <opcode> <field0> <field1> <field2> ...
Where if field is known i print it out int he known format, if it is unknown I print it out as a hex string. (strings printed out between []). Its enough information to use, or to reconstruct the original packet if desired. Basically thats the form I use, so if its of general use I can make it available sooner or later. Currently I only am logging a few opcodes I am interested in, but I could do more. (oh and flag is a little meaningless, I had it in there to differentiate it from other things being logged in my log file).
Well, just an idear, not sure if anyone would find it useful as its more for fiddling at the packet level than anything. I am feeding the data into a database to build a zone and spawn database and maybe help determine some of the fields that are currently unknown (just for kicks... already have an idea on a few).
Or I can just keep it to myself. Its just a few lines in packet.cpp and an extra file (logger.cpp, with a function to format the data structure for each opcode).
Woot, nice information gang. Exactly what I was looking for.
Thank you all for your time and information, sure was easier
posting and logging on to play til someone posted. : ) now to
try a few compiles and see if I can get it to work.
Thanks for the informative postings.
Yendor,
That would be a great addition. If you can put it in a patch and slap it up into the patch section, it would be great.
Yendor
01-06-2002, 07:47 PM
Ratt,
Ok I rewrote what I had into a framework that is more general. It would take some time to write the pretty printer for each opcode, so the question is do you want a patch with the framework and a few opcodes logged or wait until more logger functions are written?
Also the logging control is pretty unfriendly, a 96bit hex string (well 65 bits needed) that you have to assemble from knowledge of the masks used in the new logger.h. A more friendly version could be written where you can list opcodes by name on the preferences line is envisioned, just not high on my list.
I am still deciding a few details, think I will add a timestamp to each entry, and add an option to log the encrypted packets prior to decryption as well as after (and log the key used).
Also will include the perl regex to parse each opcode log format in a comment in the source code. It's so much easier to use perl to pick these packets apart than to write C code.
Hope it turns out to be useful to the other developers. If you have any requests let me know.
Powered by vBulletin® Version 4.1.11 Copyright © 2024 vBulletin Solutions, Inc. All rights reserved.