Execution: Custom Alert Mod (GUI now available)

All things /script related

Moderators: Fridmarr, Worldie, Aergis, _Chloe

Re: New Personal Project? Addon Idea

Postby moduspwnens » Tue Aug 11, 2009 8:32 am

I'm looking for a good algorithm for rule to event comparisons. I thought what I was doing would work, and while it does, I tried it out on Yogg last night for funsies with only one rule (source -> target for fear) and it quickly jumped to 9MB of memory eaten. I know of some changes I'm going to make, but I thought I'd post here to see if anyone has done something similar or can think of a good algorithm. Storing the rule can be inefficient or slow, as that only really happens at load time or when the user enters a new rule. I just need it to be as fast as possible when comparing the event to rules.
I rule.
moduspwnens
Moderator
 
Posts: 3382
Joined: Tue Nov 06, 2007 12:28 pm
Location: Shattered Hand

Re: New Personal Project? Addon Idea

Postby Arees » Wed Aug 12, 2009 8:20 am

moduspwnens wrote:I just need it to be as fast as possible when comparing the event to rules.


I don't know much about LUA, or scripting languages in general, so I don't know what kind of data structures you have to work with. A hashmap would be incredibly efficient for looking up rules. It has O(1) search time. Its not as efficient for space, but thats a paradigm I studied in my computer science classes... you trade off speed for memory and vice versa.

If you don't know what a hashmap it, think of it this way. Each 'event' stored in it also has a key that references it. For example, if I were writing a hashmap to store people's medical records, I would have some function add(person, ssn). Where ssn is the identifier for that person object. What happens is that ssn is really a pointer to a memory location. So when I called get(ssn) it goes straight to that memory location and grabs the person.

*edit*
We're really busy at work... we're trying to get a beta version of our software out within the next couple weeks, and I am writing a server/client that handles sending alerts to the clients when something goes wrong (like a database crash). When both the server and client have several threads running, there are many concurrency issues to worry about and its a pain to test.

When I'm done writing this pain in the butt server, I'll probably have some time to spare to help you code (after I learn some LUA). I'm really liking TJH and you're new addon sounds intriguing.
Image
User avatar
Arees
 
Posts: 301
Joined: Tue Dec 25, 2007 9:50 pm

Re: New Personal Project? Addon Idea

Postby moduspwnens » Wed Aug 12, 2009 8:29 am

I ended up switching to the following algorithm. When a user inputs a rule, make sure the arguments for the event are in the order the game will be giving. That way, I just have what is essentially a "while" loop that goes from argument to argument and breaks if it sees a parameter that doesn't match (and matching is defined by a function that varies by parameter). I previously had it formatting each event by its expected arguments and whatnot before being processed, but that was just unnecessary overhead.
I rule.
moduspwnens
Moderator
 
Posts: 3382
Joined: Tue Nov 06, 2007 12:28 pm
Location: Shattered Hand

Re: New Personal Project? Addon Idea

Postby moduspwnens » Thu Aug 13, 2009 10:55 pm

I feel like I've come to a point where the add-on is ready enough to be uploaded as working and useful. It has been uploaded to WoWInterface, and a download link is available here.

Execution
Combat Alert Mod

ReadMe Updated 10/15/2009

Commands:
  • /ex - Open rule creation GUI
  • /ex list - List rules
  • /ex load 3 - Load rule 3 into GUI
  • /ex options - Show options


ADVANCED: Logical Operators. You can now use logical operators for both event parameters and extra filters. This means you can use "and", "or", "not" and parentheses to be even more specific with your rules. Execution supports the following logical operators:
    & (and)
    | (or)
    ! (not)
    ( ) (grouping)
Let's say you want to be helpful and announce when someone is hit by Mimiron's Shock Blast, but you want to be a little sneaky and NOT announce when it's you that gets hit. Rather than specify an individual rule for everyone in the raid but yourself, just change your target flags ("affiliation") for it from "RAID" (announces for anyone in the raid) to "RAID&!MINE" (which reads as "in the raid and not me"). Bam. Sneakiness accomplished. These operators are translated and interpreted by the client itself, so the sky is the limit as far as how complex you want to get with them.

Bugs/Feedback. If you find a bug or have feedback on this, feel free to post here or send me a PM. I'll try and get a fix up as soon as possible.
Last edited by moduspwnens on Thu Oct 15, 2009 7:14 am, edited 8 times in total.
I rule.
moduspwnens
Moderator
 
Posts: 3382
Joined: Tue Nov 06, 2007 12:28 pm
Location: Shattered Hand

Re: New Personal Project? Addon Idea

Postby Jerey-Darkspear » Thu Aug 13, 2009 11:35 pm

I was looking for a case-switch statement in lua for something else earlier and found a page that looks like it might be exactly what you're looking for: http://lua-users.org/wiki/SwitchStatement

Enjoy!
Image
Jerey-Darkspear
 
Posts: 135
Joined: Tue Jun 17, 2008 12:38 am

Re: New Personal Project? Addon Idea

Postby moduspwnens » Fri Aug 14, 2009 12:01 am

Jerey-Darkspear wrote:I was looking for a case-switch statement in lua for something else earlier and found a page that looks like it might be exactly what you're looking for: http://lua-users.org/wiki/SwitchStatement

Enjoy!


Nice! It looks like it is exactly what I'm looking for. It'll take a little reworking but that appears to be a great idea. It's definitely on the list.
I rule.
moduspwnens
Moderator
 
Posts: 3382
Joined: Tue Nov 06, 2007 12:28 pm
Location: Shattered Hand

Re: New Personal Project? Addon Idea

Postby trellian » Fri Aug 14, 2009 5:14 am

moduspwnens wrote:That reminds me... I need to think of a replacement for DBM's reply/status whisper backs to people who aren't in the raid ("<DBM> Modus is fighting Yogg-Saron (50%, 25/25 alive). Whisper with "status" for an update."). I think I'll make that a different add-on. I have some good ideas for making one that's a little, well, better. Well, now that I think about it, though, some of its methods and data would be duplicated if you have both my add-on project and a separate reply add-on. That may be better just as an "extra module."


BossWhisperer (Ace addon) allready exist
User avatar
trellian
 
Posts: 343
Joined: Wed Jul 16, 2008 3:02 am
Location: Silvermoon, EU

Re: New Personal Project? Addon Idea

Postby moduspwnens » Fri Aug 14, 2009 9:58 am

trellian wrote:BossWhisperer (Ace addon) allready exist

/shrug. Might not have to worry about that one then.

If anyone needs help creating any rule for this new add-on, post here and I'll see if I can help you out.
I rule.
moduspwnens
Moderator
 
Posts: 3382
Joined: Tue Nov 06, 2007 12:28 pm
Location: Shattered Hand

Re: Execution: Custom Alert Mod (Now available for testing)

Postby Arees » Fri Aug 14, 2009 10:34 am

I've been investigating the vehicle thing. I'm probably gonna mess with it some this weekend. I'm going to make a small addon with a / command to run it so that whatever your targeting it will either say "X is a person" or "X is a vehicle and Z is driving it."

This code should decide if a unit is a vehicle or not, but I haven't tested it yet, and I'm not sure if I have the correct syntax either.

Code: Select all
function yourmod.UnitIsVehicle( unit )

   local g = UnitGUID( unit )

   if not g then return end

   local t = tonumber( g:sub( 5, 5 ), 16 ) % 8

   if t == 5 then return true end

end


I'm still trying to work out how to tell who is driving it.
Image
User avatar
Arees
 
Posts: 301
Joined: Tue Dec 25, 2007 9:50 pm

Re: Execution: Custom Alert Mod (Now available for testing)

Postby moduspwnens » Fri Aug 14, 2009 10:39 am

WATERBOYsh wrote:I'm still trying to work out how to tell who is driving it.

Yeah, that was my problem. The only way I can think of is, well:

Code: Select all
for i=1,40 do
    local petGUID = UnitGUID("raidpet"..i) or 0
    if petGUID == targetVehicleGUID then -- Presumably whatever the GUID of the vehicle you've found is
        return UnitName("raid"..i)
    end
end


It would work, but be pretty inefficient unless you mapped it for future events, which is when I decided it was outside the scope of TJH.
I rule.
moduspwnens
Moderator
 
Posts: 3382
Joined: Tue Nov 06, 2007 12:28 pm
Location: Shattered Hand

Re: Execution: Custom Alert Mod (Now available for testing)

Postby Arees » Fri Aug 14, 2009 10:47 am

http://wowprogramming.com/docs/api/UnitVehicleSeatInfo

Code: Select all
controlType, occupantName, occupantRealm, canEject, canSwitchSeats = UnitVehicleSeatInfo("unit", seat)


hopefully the drivers seat is index 0... or does lua start at 1? I've seen several for loops that start at 1 instead of 0.
Image
User avatar
Arees
 
Posts: 301
Joined: Tue Dec 25, 2007 9:50 pm

Re: Execution: Custom Alert Mod (Now available for testing)

Postby moduspwnens » Fri Aug 14, 2009 10:49 am

WATERBOYsh wrote:http://wowprogramming.com/docs/api/UnitVehicleSeatInfo

Code: Select all
controlType, occupantName, occupantRealm, canEject, canSwitchSeats = UnitVehicleSeatInfo("unit", seat)


hopefully the drivers seat is index 0... or does lua start at 1? I've seen several for loops that start at 1 instead of 0.


Well, the problem is that you'll need a unitID to use that function.
I rule.
moduspwnens
Moderator
 
Posts: 3382
Joined: Tue Nov 06, 2007 12:28 pm
Location: Shattered Hand

Re: Execution: Custom Alert Mod (Now available for testing)

Postby Arees » Fri Aug 14, 2009 10:52 am

moduspwnens wrote:Well, the problem is that you'll need a unitID to use that function.


Can you not pass it the guid of the vehicle?

I know it can be done... the game knows which one of the pyrite debuffs is mine because its big and farther left than everyone elses. I just have to figure out how...
Image
User avatar
Arees
 
Posts: 301
Joined: Tue Dec 25, 2007 9:50 pm

Re: Execution: Custom Alert Mod (Now available for testing)

Postby moduspwnens » Fri Aug 14, 2009 11:02 am

WATERBOYsh wrote:
moduspwnens wrote:Well, the problem is that you'll need a unitID to use that function.


Can you not pass it the guid of the vehicle?

I know it can be done... the game knows which one of the pyrite debuffs is mine because its big and farther left than everyone elses. I just have to figure out how...


The GUID isn't the same as the UnitID.

http://www.wowwiki.com/UnitId
http://www.wowwiki.com/API_UnitGUID

The way you'd figure out which one is yours is just how I showed above, except rather than cycling through the raid, you'd just see if the GUID in the combat log event matches UnitGUID("vehicle"), which is the vehicle the player is currently in.
I rule.
moduspwnens
Moderator
 
Posts: 3382
Joined: Tue Nov 06, 2007 12:28 pm
Location: Shattered Hand

Re: Execution: Custom Alert Mod (Now available for testing)

Postby fafhrd » Fri Aug 14, 2009 5:04 pm

Hm. Is it possible at all to have a rule span multiple events? Like say you get a UNIT_DIED for a tank, which I think includes the ID of the UNIT that killed him. You then want to see the last buff that unit gained (not the tank, the mob that killed him).

I suppose that's actually jumping ahead a bit by needing to remember past events, a simpler start would be to see something related to the mob after it kills the tank, like the next buff it gets, or the next person it attacks. A rule to catch a mob killing the tank is easy, and a rule to catch a mob hitting a player is easy, but how about a mechanism to pass attributes of an event caught by the first rule (viz. "this is the guid of the mob that killed a player") as input to the second rule (viz. "filter SPELL_DAMAGE for unit with GUID"). And then add something so that the 2nd rule only matches one event and is then disabled (until the first rule triggers again).
ImageImage
1/1 Lore pre-nerf.
User avatar
fafhrd
 
Posts: 3156
Joined: Fri Aug 31, 2007 2:31 pm

Re: Execution: Custom Alert Mod (Now available for testing)

Postby moduspwnens » Fri Aug 14, 2009 5:44 pm

fafhrd wrote:Hm. Is it possible at all to have a rule span multiple events? Like say you get a UNIT_DIED for a tank, which I think includes the ID of the UNIT that killed him. You then want to see the last buff that unit gained (not the tank, the mob that killed him).


It's not currently possible, but a plan to be able to do something like this is definitely in the works. This would be a little more advanced and specific for something I'd make a function for, but should easily be possible with a custom reaction in Lua after I implement the ability for rules to enable and disable other rules. I don't think UNIT_DIED lists a source normally, but the way you'd probably implement it would be:

    Rule 1: Triggered when an enemy mob gains a buff. Custom reaction is to save a new variable, which would be a table that contains the mob's GUID and the buff gained.
    Rule 2: Triggered when the designated player (or role, such as "tank") takes damage. Custom reaction is to save the GUID of the last mob to do damage to him to a different variable (will be invalid if it's not from a mob with a GUID).
    Rule 3: Triggered when the designated player dies. Custom reaction is to check the variable for last mob to damage him and check that with the variable that matches. If nothing is invalid, announce that value.
    Rule 4 (Optional): Triggered when the player leaves combat. Clears all variables.

You could save yourself a rule by just looking for an overkill value that's more than zero on the tank, but that would (presumably) not work if the tank is hit to exactly 0 HP. Hmph. I guess you wouldn't even have to enable or disable other rules for that one, but it's still on the list because it definitely has some practical uses.

Code: Select all
7/15 19:35:36.858  UNIT_DIED,0x0000000000000000,nil,0x80000000,0x020000000270D6D8,"Durga",0x2000514


fafhrd wrote:I suppose that's actually jumping ahead a bit by needing to remember past events, a simpler start would be to see something related to the mob after it kills the tank, like the next buff it gets, or the next person it attacks. A rule to catch a mob killing the tank is easy, and a rule to catch a mob hitting a player is easy, but how about a mechanism to pass attributes of an event caught by the first rule (viz. "this is the guid of the mob that killed a player") as input to the second rule (viz. "filter SPELL_DAMAGE for unit with GUID"). And then add something so that the 2nd rule only matches one event and is then disabled (until the first rule triggers again).


I'm having difficulty following this. Could you offer a clearer example?
I rule.
moduspwnens
Moderator
 
Posts: 3382
Joined: Tue Nov 06, 2007 12:28 pm
Location: Shattered Hand

Re: Execution: Custom Alert Mod (Now available for testing)

Postby fafhrd » Fri Aug 14, 2009 10:57 pm

i think the 2nd case is doable in a similar way to what you suggested for the first, but for a clearer example:

Suppose for whatever reason, you want to announce who Patchwerk hits first after killing the tank. You only want to announce the first person though, you don't want a listing of all the hits he does on the new "tank".

So you have one rule (rule A) that picks up when tank dies. Maybe it's watching overkill, maybe it's unit_died. For the sake of the example, assume unit_died lists the mob that killed the unit as source. So now this rule has triggered, and knows that Mob#123 killed Player#1.

Now you need to make a rule (rule B) to catch outgoing damage from Mob#123. You only know that it's Mob#123 you want and not some other mob because the first rule you had found out it's Mob#123 that killed Player#1. So you either create a new rule that catches Mob#123's attacks, or you have an existing rule that catches a variable mob's attacks and you feed it #123 so that it catches the ones for the mob you're interested in.

Once this rule triggers, it disables itself so it doesn't keep spamming ever attack on the new tank (although when he dies, the cycle would probably start again).

With the system you outlined for the first case, rule A would likely save "Mob#123" in some variable somewhere, and rule B would be coded to match events for the mob with Guid equal to whatever happens to be saved in that variable.

Other interesting and probably more useful cases for things like this would be "who killed the lasher on freya or guardian on yogg that blew up and killed someone". In both those cases you should be able to trace the GUIDs through a chain of events to find out who started the chain.
ImageImage
1/1 Lore pre-nerf.
User avatar
fafhrd
 
Posts: 3156
Joined: Fri Aug 31, 2007 2:31 pm

Re: Execution: Custom Alert Mod (Now available for testing)

Postby moduspwnens » Sat Aug 15, 2009 8:27 pm

I've posted up an update with the following new stuff:

    An options GUI. "/ex" will bring it up, and it's under the Addon options in the UI.
    Added a localization dropdown. It doesn't yet do much since I only have an English set, but it should work correctly when I add other localizations.
    Added a "hide outgoing whispers sent by this add-on" option.
    Fixed an issue that would cause variables in chat reactions (like *target) to not be replaced if they weren't the first reaction in the list.
Mainly my first attempt at visual frames.
I rule.
moduspwnens
Moderator
 
Posts: 3382
Joined: Tue Nov 06, 2007 12:28 pm
Location: Shattered Hand

Re: Execution: Custom Alert Mod (Now available for testing)

Postby Arees » Sun Aug 16, 2009 7:07 am

I like TJH so much... I'm definitely going to try this out soon modus.
Image
User avatar
Arees
 
Posts: 301
Joined: Tue Dec 25, 2007 9:50 pm

Re: Execution: Custom Alert Mod (Now available for testing)

Postby moduspwnens » Sun Aug 16, 2009 4:16 pm

WATERBOYsh wrote:I like TJH so much... I'm definitely going to try this out soon modus.


I won't recommend it as a 100% replacement until I get the GUI working. The text UI isn't bad, but aside from the TJH import, it's fairly painful to input and manage rules.
I rule.
moduspwnens
Moderator
 
Posts: 3382
Joined: Tue Nov 06, 2007 12:28 pm
Location: Shattered Hand

Re: Execution: Custom Alert Mod (Now available for testing)

Postby moduspwnens » Mon Aug 17, 2009 9:41 pm

Alright. Evidently my problem with excess garbage is more serious than I thought. I thought it was my algorithm but I guess that actually had nothing to do with it (even though the new one is better anyway). I ran AddonUsage, commented out the part where the add-on does reactions, and you can just watch the add-on's memory usage get higher and higher as events come in. A quick garbage collect brings it back to normal size, though, so it must be a problem with my code.

If this WoWWiki page is correct, my strings, numbers, and booleans should be irrelevant, and this problem can only be occurring because of how I'm using my tables. It did correctly outline what I was doing wrong (creating a new table with each new event and then never using it again), but I believe I changed that and the problem is still happening. I double checked that all other variables used aren't tables, and that all other methods used don't generate tables, yet the add-on's garbage generation still seems to increase steadily with each event checked.

If anyone who knows anything about this subject would like to help out, you can grab the code here. The relevant blocks are the EX_OnEvent function and any function called therein. The OnEvent function is in Execution.lua but it does reference some functions in Ex_vars.lua.

EDIT: Right now I'm trying to comment out the different pieces to narrow it down.
I rule.
moduspwnens
Moderator
 
Posts: 3382
Joined: Tue Nov 06, 2007 12:28 pm
Location: Shattered Hand

Re: Execution: Custom Alert Mod (Now available for testing)

Postby moduspwnens » Mon Aug 17, 2009 10:11 pm

I suppose disregard that last post. It ends up my excess garbage appears to be from how I'm using gsub. I was creating a new function for it to use every time (albeit a very simple function, still a function) which appears to be what's doing it.
I rule.
moduspwnens
Moderator
 
Posts: 3382
Joined: Tue Nov 06, 2007 12:28 pm
Location: Shattered Hand

Re: Execution: Custom Alert Mod (Now available for testing)

Postby moduspwnens » Mon Aug 17, 2009 10:55 pm

Alright, so now I have a different problem. I'd like to be able to create new functions without excess garbage. One of the reasons this causes an issue is because my logical operator script works by making the expression into a string and loadstring'ing it. Evidently that creates a function, though, which is now creating garbage. Likewise, in my gsub function, I was using something simple like:

Code: Select all
extraFilterString = gsub(extraFilterString, argumentPattern, function(eachArgument) return tostring(checkArgument(eachArgument)) end)


Obviously that's a very tiny function, but it is technically creating a function each time, which appears to be adding to my garbage. That particular situation is easier to work around, but I'm having difficulty getting gsub to call a function with any parameters other than the ones it's found, which is another problem for me.

Bottom line: Is there a way to create a function or overwrite a function without creating extra garbage?

My add-on's memory usage continually grows to out-of-control levels in raid combat and drops FPS significantly.
I rule.
moduspwnens
Moderator
 
Posts: 3382
Joined: Tue Nov 06, 2007 12:28 pm
Location: Shattered Hand

Re: Execution: Custom Alert Mod (Now available for testing)

Postby _Chloe » Tue Aug 18, 2009 1:09 am

Use local variables instead of globals?
User avatar
_Chloe
Moderator
 
Posts: 831
Joined: Fri Dec 07, 2007 6:36 pm
Location: Santa Monica, CA

Re: Execution: Custom Alert Mod (Now available for testing)

Postby moduspwnens » Tue Aug 18, 2009 3:59 am

_Chloe wrote:Use local variables instead of globals?


Hmm. In what sense? Like, here's one function that could cause problems. This particular one is more easily worked around but is clearer for showing you guys:

Code: Select all
function EX_CheckExtraFilter(extraFilterString)

   if extraFilterString == "" or extraFilterString == nil then return true end

   local argumentPattern = "[^&|()!][^&|()]*"

   extraFilterString = gsub(extraFilterString, argumentPattern, function(eachArgument) return tostring(EX_ExtraFilterHandler(eachArgument)) end)

   return EX_Evaluator(extraFilterString)

end


Slapping local in front of that function causes a compile-time error. Or do you mean defining the function locally beforehand, and then calling it there in the gsub? That might work. Brb trying.
I rule.
moduspwnens
Moderator
 
Posts: 3382
Joined: Tue Nov 06, 2007 12:28 pm
Location: Shattered Hand

PreviousNext

Return to Add-ons, UI, and Macros

Who is online

Users browsing this forum: Google [Bot] and 1 guest

Who is online

In total there are 2 users online :: 1 registered, 0 hidden and 1 guest (based on users active over the past 5 minutes)
Most users ever online was 380 on Tue Oct 14, 2008 6:28 pm

Users browsing this forum: Google [Bot] and 1 guest