Advanced Combat Tracker Forum Index Advanced Combat Tracker
Advanced Combat Tracker Forums
Alternate Forums



Welcome
Welcome to Advanced Combat Tracker.

You are currently viewing our boards as a guest, which allows you to view posts but you cannot start threads or post on current discussions. By joining our free community, you will have access to post topics, communicate privately with other members (PM), respond to polls, upload content, and access many other special features. Registration is fast, simple, and absolutely free, so please, join our community today!

Using plugins to parse other games?

 
Post new topic   Reply to topic    Advanced Combat Tracker Forum Index -> Plugin Development
View previous topic :: View next topic  
urizen



Joined: 06 Jan 2008
Posts: 3

 PostPosted: Sun Jan 06, 2008 6:13 am    Post subject: Using plugins to parse other games? Reply with quote Back to top

Quick question on plugin development: is the plugin interface powerful enough to allow one to do parsing on logs from a game other than EQ2? While I was playing EQ2, loved ACT, and wish there was a similar tool for CoH (the only game I'm currently playing). If the plugin interface will allow it, might just have to sit down and write a plugin to allow ACT to deal with CoH
 
Aditu
Site Admin


Joined: 27 Nov 2007
Posts: 255

 PostPosted: Sun Jan 06, 2008 8:03 pm    Post subject: Reply with quote Back to top

I suppose it is possible if the games are similar enough. You would just need to hook into the ActGlobals.oFormActMain.OnLogLineRead event and do your own log line parsing. There isn't currently a public method to just feed data into and everything will sort itself out... but you are given access to the master zone list, which you can add new zones to and feed data directly into them(through AddCombatAction). You will have to do management of new zones and new encounters. The data objects are not responsible for spawning new siblings under any conditions. A somewhat harder problem is that ACT's interface won't know when to refresh itself since you are not simulating combat as much as feeding data into memory. I could make the inCombat flag public, I suppose.

If this were something you were really serious about, I could make a number of things public which would allow you to have ACT handle the creation of new ZoneData and EncounterData objects instead of you creating the objects yourself. This would allow ACT to do things like Selective Parsing automatically, not to mention update the UI correctly.
 
urizen



Joined: 06 Jan 2008
Posts: 3

 PostPosted: Mon Jan 07, 2008 3:20 pm    Post subject: Reply with quote Back to top

Aditu wrote:
I suppose it is possible if the games are similar enough.


Well, at a low enough enough level, all games work pretty much the same as far as combat Smile

Aditu wrote:
You would just need to hook into the ActGlobals.oFormActMain.OnLogLineRead event and do your own log line parsing. There isn't currently a public method to just feed data into and everything will sort itself out... but you are given access to the master zone list, which you can add new zones to and feed data directly into them(through AddCombatAction). You will have to do management of new zones and new encounters. The data objects are not responsible for spawning new siblings under any conditions. A somewhat harder problem is that ACT's interface won't know when to refresh itself since you are not simulating combat as much as feeding data into memory. I could make the inCombat flag public, I suppose.


For CoX, the zone information isn't all that necessary, as most combat happens in random instanced zones (sort of like LDoN dungeons from EQ1). As for encounters, how is this currently done? Since I'll have to do some log mangling anyway, simulating what it expects from EQ2 might not be too difficult.

Aditu wrote:
If this were something you were really serious about, I could make a number of things public which would allow you to have ACT handle the creation of new ZoneData and EncounterData objects instead of you creating the objects yourself. This would allow ACT to do things like Selective Parsing automatically, not to mention update the UI correctly.


Well, let me take a look at the .NET interfaces, and see what I think. A possible goal to think about might be splitting it into two parts: a generic stat/graphing/etc. engine, and a separate, plugin based, game processing engine, that feeds the main engine the data from a specific game. No idea how huge an undertaking that might be Smile
 
Aditu
Site Admin


Joined: 27 Nov 2007
Posts: 255

 PostPosted: Tue Jan 08, 2008 7:18 am    Post subject: Reply with quote Back to top

Take a look at the API documentation, if you haven't. It's a 7z file on a sticky... I don't have 10 MB to host the API docs on my free setup that I use.

Essentially the top level of the memory structure is a List<ZoneData> collection. (Can be accessed from ActGlobals.oFormActMain.ZoneList) Let's just pretend that we have the plugin able to parse log lines and we can feed ACT data. You must have a ZoneData object existing in the List<ZoneData> before or when combat starts. So just create one put it in the collection. You also need an EncounterData object existing when combat starts. A ZoneData object's Items property is a List<EncounterData> collection. So create an EncounterData object, and add it to the collection, and also set the ZoneData.ActiveEncounter as it. From there you use ZoneData.AddCombatAction() to add data to the encounter. It's encapsulated to the point that you don't need to care what the method does with the data... but the data reference will be passed down to many child objects which are automatically created... organized in the same way as when you expand nodes on the TreeView. Once you're done adding data to that encounter, you call EncounterData.EndCombat(). It's not completely necessary for normal encounters to have this called, but if you're using the zonewide All encounter, the duration won't be calculated correctly if you don't.

The object you give AddCombatAction is the poorly named MasterSwing class. But I already released the API, so no renaming it CombatAction or whatever. It holds everything ACT knows about the event... The child objects are created in response to the data within. The parent to child order is as follows: ZoneData, EncounterData, CombatantData, DamageTypeData, AttackType, MasterSwing. Each parent holds a collection of the next child type.
 
urizen



Joined: 06 Jan 2008
Posts: 3

 PostPosted: Tue Jan 08, 2008 7:22 pm    Post subject: Reply with quote Back to top

Aditu wrote:
Take a look at the API documentation, if you haven't. It's a 7z file on a sticky... I don't have 10 MB to host the API docs on my free setup that I use.


Yeah, been looking through it. A class diagram might be a useful addition, so one can see at a glance relationships. Also, something about those pages don't seem to quite like Firefox (no scroll bars, and searching ends up with the result slightly below the bottom of the window). Not a big problem, just an FYI.

Aditu wrote:
Essentially the top level of the memory structure is a List<ZoneData> collection. (Can be accessed from ActGlobals.oFormActMain.ZoneList) Let's just pretend that we have the plugin able to parse log lines and we can feed ACT data.


Aye, there's the rub. Unfortunately, in a quick test, looks like the OnLogLineRead handler never gets called unless the parsing engine can parse the file already. Looks like what I'd really need for this is something like an OnPreParse event, called before the line is passed to the parsing engine, allowing the line to be mangled as desired, probably through a public property somewhere.

Another possibility would be to create an IParser interface, a Parser property on FormActMain, defaulting to an EQ2 implementation. A plugin could then could do something along the lines of:

Code:

class FooParser : IParser {
...
};

class FooPlugin : IActPluginV1 {
  private IParser mOldParser;
...
  public void InitPlugin(TabPage page, Label status) {
    FooParser parser = new FooParser(...);
    mOldParser = ActGlobals.oFormActMain.Parser;  // store it so we can restore it when plugin terminates
    ActGlobals.oFormActMain.Parser = parser;
    ...
  }
  public void DeInitPlugin() {
    ActGlobals.oFormActMain.Parser = mOldParser;  // restore the previous parser
    ...
  }
};


Obviously this would require more work on your end, but does make it easy to support most games (since I personally think ACT is the best log parser I've seen for any game, I think this would be a good thing Smile )

Another potential issue I see is damage types. To what extent are they hard coded?
 
Aditu
Site Admin


Joined: 27 Nov 2007
Posts: 255

 PostPosted: Wed Jan 09, 2008 1:04 am    Post subject: Reply with quote Back to top

Quote:
Also, something about those pages don't seem to quite like Firefox (no scroll bars, and searching ends up with the result slightly below the bottom of the window). Not a big problem, just an FYI.
I haven't a clue why it happens... FF is rendering the page wrong somehow. You can scroll to the right and see the scrollbars are indeed there, but FF was hiding them. I however figured that computer programmers could figure out how to use keyboard arrow keys or mouse scrolling to go up and down. I personally have three different ways to scroll down on my mouse.

Quote:
Aye, there's the rub. Unfortunately, in a quick test, looks like the OnLogLineRead handler never gets called unless the parsing engine can parse the file already. Looks like what I'd really need for this is something like an OnPreParse event, called before the line is passed to the parsing engine, allowing the line to be mangled as desired, probably through a public property somewhere.
That's not true... here is a simplified version of the ReadLog() method...
Code:
while (!readThreadAborting)
{
   logLine = sReader.ReadLine();
   if (!String.IsNullOrEmpty(logLine))
   {
       logMatched = 0;
       for (int i = 0; i < regExArr.Length; i++)
       {
          // Iterate through the regex collection to find a matching pattern
       }
       if (logMatched > 0)  // If a pattern was matched
       {
          // Do parsing on the log line
       }
       if (OnLogLineRead != null)
       {
           OnLogLineRead(false, new LogLineEventArgs(logLine, logMatched, LastKnownTime, currentZone, inCombat));
       }
   }
}
As you can see, the OnLogLineRead event will fire regardless of anything except the log line being null, or there is nothing subscribed to the event.


Quote:
Another possibility would be to create an IParser interface, a Parser property on FormActMain, defaulting to an EQ2 implementation.
I suppose that's an interesting idea. There's a bunch of stuff that relies on the timestamp format in EQ2 that slows down plugin parsers. Even if you set log file input language to (None), it still attempts to parse timestamps. Custom Triggers also expect the timestamp to be there, but that's sort of off-topic.
 
Aditu
Site Admin


Joined: 27 Nov 2007
Posts: 255

 PostPosted: Wed Jan 09, 2008 12:24 pm    Post subject: Reply with quote Back to top

Quote:
Another potential issue I see is damage types. To what extent are they hard coded?
As far as I can recall, not very. There is a Resists Report which has them hard-coded... but that's been useless since SoE removed mob immunities. There is also a "Resists" sort graphing method for the pie chart graph which populates the wedges by mitigation type... those are hard coded. Most people probably don't know the graph can do that though. Nothing will stop you from using whatever as damage types... after all, ACT already uses English, German and Russian localized damage types equally. It's the parser's responsibility to do tense conversion and such(like crush to crushing) before putting the data into data classes.

Avoidance is ever so slightly more hard-coded. As in, there are hits... hits that inflict no damage... misses... and every thing else. The every thing else used to be hard coded(resist/parry/etc), but now it's just marked a failed attack with a custom string that ACT displays in tables. There are also "Death" attacks... which should be marked a "Killing" AttackType. Some of ACT's reports will look for such, and as long as they are sorted correctly, killing blows will not affect hit counts. (Killing someone isn't an attack in itself, but a result)
 
NewBody



Joined: 18 Dec 2007
Posts: 5

 PostPosted: Fri Jan 25, 2008 7:19 am    Post subject: Reply with quote Back to top

If it's city of heroes, why not just use herostats? It's been a long time since I played CoX. I don't even remember if the game provided logging functions to a file.

http://www.herostats.org/screenshots.html

Does all that and more, especially for CoX when I did play. Screen overlay to show what incoming damage you were taking as well as buff timers for just about everything ingame was perfect made for that game. I don't think it keeps track of teammate/group tho, like what ACT does.

There is a fundamentally different approach that it uses as oppose to ACT tho. Here is just a log/text parser. HeroStats actually reads memory from the CoX client to get it's information. It's a whole can of worms that most mmo 3rd party authors avoid. From what I remember, ncsoft knows about this and allows it's use. There are quite a bit of posts on their official forums about herostats, including help and technical support for running it under vista. I could have sworn I remember an official statement to the community saying it's allowed (as well as the old vid map packs and badge trackers) but I haven't played in a very very long time so things may have changed since then.
 
Display posts from previous:   
Post new topic   Reply to topic    Advanced Combat Tracker Forum Index -> Plugin Development All times are GMT
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You cannot download files in this forum

Community Chest