Seems like ParserLib 1.1 has few problems to find all the Dammage logs with a french client.
In fact, SCT, KombatStats and Simple Combat Log (all of them use ParserLib) have the same bug : no dammage recorded.
fyi, parserlib works in tbc. Some strings are missing, but that's it.
As sctd works fine for most stuff, yea.
But as parsing events is one of the most CPU heavy function, it should be done in a better way than loop through table and try them.
Statistical and syntactical analysis should improve efficientcy:
- What's the chance that CHAT_MSG_COMBAT_PARTY_HITS matches COMBATHITOTHEROTHER ("%s hits %s for %d."). Use this data to reorder matching attempts.
- What are the keywords in a pattern? Are they unique for an event?
A log parser should minimize the amout of
- String.find's, without plain=true parameter.
- String.find's with plain=true. It's 10x faster than patterns, but still very slow compared to normal arithmetic.
(I'm off to porting any casting bar to WoW 2.0... default ui bar is bugged, it doesn't adjust time when you get hit while casting :/)
I dont know where you are at today and some of these posts are a month old. But I thought I'd try to join in the discussion.
Here's what I got from reading this thread:
The idea of mapping each parsed string to a unique event is a good one - similar to SAX in concept.
'I hit chicken for 4.'
Lets say that comes in via 2-3 different CHAT_MSG_COMBAT* events(if you are in a raid or party or solo), you would want to just register for one abstracted event, and let an intermediate library keep up to date on which message gets fired for what - abstracting the whole blizzard event system (for combat).
So when I register for Parser_HitSelfOther, the intermediate would register the 2-3 events needed. And I would always get Parser_HitSelfOther.
This would eliminate most of the if/then/else that goes on in e.g. sct.
if (info.type == "environment") then
elseif (info.type == "hit") then
... etc
Since LUA isnt a strongly typed language using separate callbacks rather than one allows you to preserve type inforomation in a sense.
sct has an additional challenge, it processes some of the blizzard events internally. It seems like you could add the abililty to recieve Pre* Events, and allow you to switch off event generation by the parser for that message and that addon ID.
If i register for PreHook__CHAT_MSG_COMBAT_SELF_HITS, i could somehow turn off the event which parserlib generates, but only for my addon. You could use an incremetal counter and assign every event a sequence number, then pass this to the prehook function, and provide it in the subsequent parserlib callback. Basically, in the PreHook the addon would save the sequence number, and then when parserlib generates the registered event, the client could use that to ignore the event. This way you can keep the client decoupled from the actual CHAT_MSG_COMBAT_* event.
The ideal case would have an addon like sct not register to listen to the actual blizzard events at all (at least the ones that parserlib handles) -
EDIT: I just realized that this post is off topic. =)
Statistical and syntactical analysis should improve efficientcy:
- What's the chance that CHAT_MSG_COMBAT_PARTY_HITS matches COMBATHITOTHEROTHER ("%s hits %s for %d."). Use this data to reorder matching attempts.
- What are the keywords in a pattern? Are they unique for an event?
For the first one, do you mean recording the frequency of each patterns, and reorder the pattern sequence with the recorded stats on real time? In that case, you need some mechanism to ensure that the reordered sequence doesn't result in the problem of getting the spell name "Greater Heal criticaly" by the pattern "%s's %s heals %s for %d." from message "A's Greater Heal critically heals B for 100."
If the approach is to analyze first (outside ParserLib), then decide the static pattern sequence in ParserLib. In that case it's already what ParserLib is currently doing.
About the keywords, I think there might be better approaches than the one ParserLib currently uses, but the approach must be optional, so that ParserLib doesn't fail when you don't have the preknowledge of pattern keywords of a localization. An optional 'pattern keyword table' is the easiest to implement so that's the one ParserLib currently uses. Got any better idea?
A log parser should minimize the amout of
- String.find's, without plain=true parameter.
- String.find's with plain=true. It's 10x faster than patterns, but still very slow compared to normal arithmetic.
I agree with that, but many things can't be done when you can't assume that you know about the pattern strings, if you want the parser to work on all localizations.
btw, I no longer have much free time to play wow (and modding), so if someone think the current ParserLib sucks and want to improve it, please do so. I'll try my best to help.
I personally feel performance wise that ParserLib is fine right now. Sure there may be a few minor areas of improvement, but overall its working perfectly fine for what all it has to be able to do.
For the short term I'd much rather we just get a TBC working version of it over worrying about trying to improve its performance.
I personally feel performance wise that ParserLib is fine right now. Sure there may be a few minor areas of improvement, but overall its working perfectly fine for what all it has to be able to do.
For the short term I'd much rather we just get a TBC working version of it over worrying about trying to improve its performance.
TBC version is pretty easy to do.
Detect if lua51. (see OneCore.lua from OneBag for detection mechanism).
do a: local string_gfind = lua51 and string.gmatch or string.gfind
and replace all string.gfind calls by string_gfind.
Also fix all the for x,y in blah do with pairs()
I did it in a local copy. But have to test in both retail and beta before I commit.
Someone sent me this as another needed change in order to get ranged/wand weapons working again. Not sure if its right, but he said it made it work:
At/around line 1728, in the "HitSelf" category, added SPELLLOGSELFOTHER and SPELLLOGCRITSELFOTHER.
At/around line 1763 (after above changes), in the "MissSelf" category, added SPELLMISSSELFOTHER.
I'm seeing an error with SCL and the new ParserLib:
SimpleCombatLog\core.lua:343: attempt to index field '?' (a nil value)
SimpleCombatLog\core.lua:343: in function `OnCombatEvent'
SimpleCombatLog\core.lua:588: in function `func'
ParserLib-1.1\ParserLib.lua:571: in function `NotifyClients'
ParserLib-1.1\ParserLib.lua:538: in function `OnEvent'
ParserLib-1.1\ParserLib.lua:304: in function <...terface\AddOns\ParserLib\ParserLib-1.1\ParserLib.lua:304>
The idea is that ParserLib notifies clients with info.type = 'unknown', info.message = [original message received] when ParserLib cannot find a matching pattern for the message.
Then you try to manually find out what pattern that message is, and add that pattern to the event's pattern list.
Btw, why would you register on wow-event types instead of info.type? I think most users would just know if something happened, like someone gained or lost an aura, but he doesn't care about what the original event type was.
And addListener takes 3 parameters, type, name and function.
An enemy casting bar mod in WoW 1.12 would register Cast (for bla Casts bla on target / bla Begins to Cast bla on target) and Interrupt (bla Interrupts target's Spell of Doom).
--
Optimizing ParserLib: I thought the patterns are rearranged based on they way you have to process them, in order to avoid X hits you for Y Fire damage to be caught by "%d hits You for %d", not on hit-rate.
Apparently, some people were using MCL/MCP for a long, long time after 'discontinuation' (read: it just works, and I got bored with Nurfed CL :P), so I'm going to do a cleanup and review on those two mods and rerelease them. It's nice to see how small a fully featured combatlog can be with just a parser and no other externals, the layout code is 13k and add another 5 for slash handlers.
Btw, why would you register on wow-event types instead of info.type? I think most users would just know if something happened, like someone gained or lost an aura, but he doesn't care about what the original event type was.
And addListener takes 3 parameters, type, name and function.
An enemy casting bar mod in WoW 1.12 would register Cast (for bla Casts bla on target / bla Begins to Cast bla on target) and Interrupt (bla Interrupts target's Spell of Doom).
Because type and WoW event is not one-on-one, and I didn't bother to create a type-event list in Parser-1.1.
That being said, I added such list to Parser-2.0, and the Parser-2.0 version in svn changed the API to make use of AceEvent-2.0:
MyAddon:RegisterEvent("Parser_Hit")
function MyAddon:Parser_Hit(source, skill, victim, damage, element)
print( source .. " hits " .. victim .. " with " .. skill .. " for " .. element .. " " .. damage );
end
Optimizing ParserLib: I thought the patterns are rearranged based on they way you have to process them, in order to avoid X hits you for Y Fire damage to be caught by "%d hits You for %d", not on hit-rate.
ParserLib did both. More common patterns are placed at the front of the list manually, and then the subsets are sorted individually to avoid the problem. This way I still have to manually make sure the result list doesn't cause the problem though (with a testing function).
Rollback Post to RevisionRollBack
To post a comment, please login or register a new account.
Seems like ParserLib 1.1 has few problems to find all the Dammage logs with a french client.
In fact, SCT, KombatStats and Simple Combat Log (all of them use ParserLib) have the same bug : no dammage recorded.
Could you have a look ?
Thanks.
As sctd works fine for most stuff, yea.
But as parsing events is one of the most CPU heavy function, it should be done in a better way than loop through table and try them.
Statistical and syntactical analysis should improve efficientcy:
- What's the chance that CHAT_MSG_COMBAT_PARTY_HITS matches COMBATHITOTHEROTHER ("%s hits %s for %d."). Use this data to reorder matching attempts.
- What are the keywords in a pattern? Are they unique for an event?
A log parser should minimize the amout of
- String.find's, without plain=true parameter.
- String.find's with plain=true. It's 10x faster than patterns, but still very slow compared to normal arithmetic.
(I'm off to porting any casting bar to WoW 2.0... default ui bar is bugged, it doesn't adjust time when you get hit while casting :/)
I dont know where you are at today and some of these posts are a month old. But I thought I'd try to join in the discussion.
Here's what I got from reading this thread:
The idea of mapping each parsed string to a unique event is a good one - similar to SAX in concept.
'I hit chicken for 4.'
Lets say that comes in via 2-3 different CHAT_MSG_COMBAT* events(if you are in a raid or party or solo), you would want to just register for one abstracted event, and let an intermediate library keep up to date on which message gets fired for what - abstracting the whole blizzard event system (for combat).
So when I register for Parser_HitSelfOther, the intermediate would register the 2-3 events needed. And I would always get Parser_HitSelfOther.
This would eliminate most of the if/then/else that goes on in e.g. sct.
if (info.type == "environment") then
elseif (info.type == "hit") then
... etc
Since LUA isnt a strongly typed language using separate callbacks rather than one allows you to preserve type inforomation in a sense.
sct has an additional challenge, it processes some of the blizzard events internally. It seems like you could add the abililty to recieve Pre* Events, and allow you to switch off event generation by the parser for that message and that addon ID.
If i register for PreHook__CHAT_MSG_COMBAT_SELF_HITS, i could somehow turn off the event which parserlib generates, but only for my addon. You could use an incremetal counter and assign every event a sequence number, then pass this to the prehook function, and provide it in the subsequent parserlib callback. Basically, in the PreHook the addon would save the sequence number, and then when parserlib generates the registered event, the client could use that to ignore the event. This way you can keep the client decoupled from the actual CHAT_MSG_COMBAT_* event.
The ideal case would have an addon like sct not register to listen to the actual blizzard events at all (at least the ones that parserlib handles) -
EDIT: I just realized that this post is off topic. =)
Cheers!
For the first one, do you mean recording the frequency of each patterns, and reorder the pattern sequence with the recorded stats on real time? In that case, you need some mechanism to ensure that the reordered sequence doesn't result in the problem of getting the spell name "Greater Heal criticaly" by the pattern "%s's %s heals %s for %d." from message "A's Greater Heal critically heals B for 100."
If the approach is to analyze first (outside ParserLib), then decide the static pattern sequence in ParserLib. In that case it's already what ParserLib is currently doing.
About the keywords, I think there might be better approaches than the one ParserLib currently uses, but the approach must be optional, so that ParserLib doesn't fail when you don't have the preknowledge of pattern keywords of a localization. An optional 'pattern keyword table' is the easiest to implement so that's the one ParserLib currently uses. Got any better idea?
I agree with that, but many things can't be done when you can't assume that you know about the pattern strings, if you want the parser to work on all localizations.
btw, I no longer have much free time to play wow (and modding), so if someone think the current ParserLib sucks and want to improve it, please do so. I'll try my best to help.
For the short term I'd much rather we just get a TBC working version of it over worrying about trying to improve its performance.
TBC version is pretty easy to do.
Detect if lua51. (see OneCore.lua from OneBag for detection mechanism).
do a: local string_gfind = lua51 and string.gmatch or string.gfind
and replace all string.gfind calls by string_gfind.
Also fix all the for x,y in blah do with pairs()
I did it in a local copy. But have to test in both retail and beta before I commit.
-Ammo
-Ammo
It should work fine in wow2.0 but a few events might be mismatched/missing.
-Ammo
http://www.wowace.com/forums/index.php?topic=2353.msg54709#msg54709
I'm seeing an error with SCL and the new ParserLib:
-Ammo
Then it's ok :)
-Ammo
I just tested SCL and WitchHunt and they both work fine.
-Ammo
I posted the procedure to add new patterns to ParserLib at http://www.wowace.com/forums/index.php?topic=2353.msg56171#msg56171
The idea is that ParserLib notifies clients with info.type = 'unknown', info.message = [original message received] when ParserLib cannot find a matching pattern for the message.
Then you try to manually find out what pattern that message is, and add that pattern to the event's pattern list.
And addListener takes 3 parameters, type, name and function.
An enemy casting bar mod in WoW 1.12 would register Cast (for bla Casts bla on target / bla Begins to Cast bla on target) and Interrupt (bla Interrupts target's Spell of Doom).
--
Optimizing ParserLib: I thought the patterns are rearranged based on they way you have to process them, in order to avoid X hits you for Y Fire damage to be caught by "%d hits You for %d", not on hit-rate.
Apparently, some people were using MCL/MCP for a long, long time after 'discontinuation' (read: it just works, and I got bored with Nurfed CL :P), so I'm going to do a cleanup and review on those two mods and rerelease them. It's nice to see how small a fully featured combatlog can be with just a parser and no other externals, the layout code is 13k and add another 5 for slash handlers.
Because type and WoW event is not one-on-one, and I didn't bother to create a type-event list in Parser-1.1.
That being said, I added such list to Parser-2.0, and the Parser-2.0 version in svn changed the API to make use of AceEvent-2.0:
ParserLib did both. More common patterns are placed at the front of the list manually, and then the subsets are sorted individually to avoid the problem. This way I still have to manually make sure the result list doesn't cause the problem though (with a testing function).