• 0

    posted a message on You asked for it
    Quote from halcinlatsmir
    Erm... When passing variables to a function, I thought you were passing the values not a reference. (ie: the calling function does not effect the contents as seen by the called function)

    All tables (and only tables) are passed by reference, including in the assignment operator, like so:
    local a = {1, 2, 3}
    local b = a
    b[2] = 5   
    -- a[2] is also 5 now


    Edit: I didn't think of functions and strings, as Adirelle points out below. Rookie mistake.
    Posted in: Lua Code Discussion
  • 0

    posted a message on Detecting Secure Frames
    Quote from Arrowmaster
    Well nothing in the Default UI uses COMBAT_LOG_EVENT_UNFILTERED so you could use http://wowprogramming.com/docs/api/GetFramesRegisteredForEvent to get a list of all frames using it and none of those should be secure. But bewarned you do not want to hook the main event handlers for framework addons like Ace2 and Ace3 because you could cause some serious harm if you do it wrong.

    Are you joking me? I cannot believe that function actually exists. Thank you a ton. I'll try it later tonight.

    I break down the Ace2/3 Addons by hooking the specific functions for each addon so I can see how much data they use, like so:
    function core:Start()		
    	-- Ace 3
    	local CLEU = LibStub:GetLibrary("AceEvent-3.0").events.events.COMBAT_LOG_EVENT_UNFILTERED;
    	if (CLEU) then
    		for addon, event in pairs(CLEU) do
    			self:RawHook(CLEU, addon, function(...)
    				local span;
    				debugprofilestart();
    				self.hooks[CLEU][addon](...);
    				span = debugprofilestop();
    				self.records.timeSpent[addon] = (self.records.timeSpent[addon] or 0) + span;
    				self.records.count[addon] = (self.records.count[addon] or 0) + 1;
    			end);
    		end
    	end
    end
    
    -- had to write my own RawHook to allow objects with non-string keys
    function core:RawHook(object, method, handler)
    	if (not self.hooks) then
    		self.hooks = {};
    	end
    	if (not self.hooks[object]) then
    		self.hooks[object] = {};
    	end
    	self.hooks[object][method] = object[method];
    	object[method] = handler;
    end
    Posted in: Lua Code Discussion
  • 0

    posted a message on Detecting Secure Frames
    Well, the specific reason I was doing this was to limit the profiling only to time spent in COMBAT_LOG_EVENT_UNFILTERED. My addon works great with Ace3 or Ace2 addons, but since it's something that I'm mostly using for personal development, I might just hard code all the events from the different addons I want to hook. That is, unless I can think of something else clever.

    Thanks for all your input.
    Posted in: Lua Code Discussion
  • 0

    posted a message on Detecting Secure Frames
    Quote from egingell
    No. Where did you get that idea?

    /run testVar = 5
    /dump issecurevariable(testVar) -- returns 1, nil
    /dump issecurevariable(_G, "testVar") -- returns nil, ""


    and

    /run testVar2 = ActionButton_OnEvent
    /dump issecurevariable(_G, "ActionButton_OnEvent") -- returns 1, nil
    /dump issecurevariable(_G, "testVar2") -- returns nil, ""


    Quote from egingell
    The script handler is irrelevant when referring to secure frames. Some secure frames have unprotected script handlers, so it's a moot point.

    What are you saying I would pass to issecurevariable? I guess I'm confused about this function in general.
    Posted in: Lua Code Discussion
  • 0

    posted a message on Detecting Secure Frames
    Quote from egingell
    Your best bet is to use issecurevariable inside the EnumerateFrames() loop.


    The way I understand it, issecurevariable needs and object and string, so that it can check whether the variable itself is secure and not the memory it refers to. Is there something in the frame that points to the function you pass with SetScript?
    Posted in: Lua Code Discussion
  • 0

    posted a message on Detecting Secure Frames
    I did look at that, but the obvious issecurevariable(frame, "OnEvent") did not work. I assume this is because there is no function frame["OnEvent"], but now that you mention it, issecurevariable(_G, "ActionButton_OnEvent") does return 1, for example. So, I could feasibly loop through _G and index each function that has this property and see if the frame's OnEvent function matches with any of them and skip if so?

    Edit:
    local secures = {};
    local ct = 0;
    for i,v in pairs(_G) do
    	if (issecurevariable(_G, i) and type(v) == "function") then
    		secures[v] = true;
    		ct = ct + 1;
    	end
    end
    print("Count:", ct);
    local frame = EnumerateFrames();
    while (frame) do
    	local script = frame:GetScript("OnEvent");
    	if(script and secures[script]) then
    		print(frame, frame:GetName(), script);
    	end
    	frame = EnumerateFrames(frame);
    end

    prints "Count: 4585", but that's it. No prints after that about frames with an OnEvent in the global namespace, but I think I'm doing something wrong.

    Though... if any Blizzard frame used an anonymous function as its handler, this idea would fail completely, I think.
    Posted in: Lua Code Discussion
  • 0

    posted a message on Detecting Secure Frames

    I hadn't seen this before, but looking through the tool and the code for it, I'm not quite sure how this relates to what I'm doing.

    Quote from Adirelle
    :CanChangeAttribute would help you to detect secure frames that cannot actually be modified. But this isn't the same issue as tainting :
    - secure frames cannot be modified while in combat,
    - you taint any Blizzard code you change or hook, be it in combat or not.

    So basically, you could change every scripts of every frames out of combat, but that would taint the entire UI and cause lots of taint errors during subsequent combats.

    Right, that's basically what I was doing now. If I run the code that I put in my first post, I can't cast any spell, even out of combat, since I tainted the execution path of my Action Buttons.

    I was thinking more on my problem, though, and I am curious as to whether these scripts that I am tainting were all written by Blizzard or not. I know that anything in Blizzard's section of the UI is secure by default, but I don't know if addons could somehow also have secure functions. I believe that Bartender, which is a main contender in my mass-taint, just inherits the OnEvent functions from Blizzard's. So, I'm wondering if I can basically make a table of all of Blizzard's functions bound to OnEvents, and check each returned script against that table. It's not very efficient or future-proof, but it seems like it might be the only way.
    Posted in: Lua Code Discussion
  • 0

    posted a message on Detecting Secure Frames
    As I mentioned in my Addon Ideas Post, I am trying to hook every OnEvent script on every frame to do some profiling. However, since I need to use debugprofilestart/stop, a :Hook() won't do; I'll have to :SetScript. And then, since I try to call the original function that may or may not have been secure, I have taint issues everywhere.

    So my question is basically, is there a way to test if a frame script is secure before trying to set its script? I would just skip all those frames when cycling through and setting up my hooks.

    Edit: In my infinite wisdom, I thought about searching the Widget API for "Protected" in addition to "Secure" and found :IsProtected, but I don't think this applies to what I'm trying to do, because I'm still having taint issues.

    while (frame) do
    	local script = frame:GetScript("OnEvent");
    	if (script and not frame:IsProtected()) then
    		frame:SetScript("OnEvent", function(...)
    			debugprofilestart();
    			script(...);
    			local span = debugprofilestop();
    			self.records.timeSpent[frame] = (self.records.timeSpent[frame] or 0) + span;
    			self.records.count[frame] = (self.records.count[frame] or 0) + 1;
    		end);
    	end
    	frame = EnumerateFrames(frame);
    end
    Posted in: Lua Code Discussion
  • 0

    posted a message on Profiling OnEvent Usage
    I know my test was far from practical, but it was impromptu and there weren't many other fights where I could fool around without a UI. I'm running an i7 920 @ 3.0 and an HD 4870 which both should be more than capable of handling WoW at 30 fps.
    Posted in: Addon Ideas
  • 0

    posted a message on Profiling OnEvent Usage
    Tried it in our alt run. Went from 12-18 fps during Marrowgar to 30-35 fps during Lady Deathwhisper with only Bartender and EBB on (still kind of surprising it was less than 60). I'm going to try and put something rough together for our next raid on Sunday and see what kind of information I can get.
    Posted in: Addon Ideas
  • 0

    posted a message on Profiling OnEvent Usage
    So I've been at the conclusion for a while that most of my raid lag comes from too many addons, specifically those registering CLEU. When I'm out of combat, in a 10 man raid, or even in 25 man combat while doing nothing (practicing on normal Lich King waiting for Valks to drop and no one in the raid DPSing), I get 60 fps. In combat, and especially during heroism, my framerate plummets to under 15.

    Anyway, I am thinking about creating an addon to specifically break down the usage per addon of CLEU (and maybe also general OnEvent usage, though my guess is CLEU dwarfs everything else). This would break things down by Frame, but I would also like to hook into Ace2/3's dispatch, as most of my addons are Ace, and it wouldn't be very helpful to keep them grouped up.

    I've been playing around with InterfaceUsage, and while it's pretty decent, it causes a ton of taint, making it entirely unusable in a raid setting. On the subject of taint, I am most likely going to have to skip those frames entirely, since I don't know of any way to pre and post hook them, which I believe is required to get the time spent in the function.

    Any input or ideas would be nice, or even other addons that I've missed that do more like what I'm looking to do.
    Posted in: Addon Ideas
  • 0

    posted a message on Stupid question about scope of AceDB variables
    I remember when I made my first Ace addon, I named it "C[...]". It worked fine, but I later renamed it to "A[...]" and all of a sudden it broke because it was the first alphabetical addon and I wasn't including the Libraries. I'm guessing that your addon is "Badger", which means maybe the intermittent problem is because you are turning on and off another addon that precedes it that uses some of the libraries?

    Though, I'm also assuming this isn't a problem since LibStub throws errors when it can't find libraries, so I would assume you would see those too.
    Posted in: Lua Code Discussion
  • 0

    posted a message on Stupid question about scope of AceDB variables
    Quote from feasmira
        if self.db.global.toons == nil then
           self.db.global.toons = {}
        if self.db.global.toons[me] == nil then
           self.db.global.toons[me] = {}
        if self.db.global.toons[me].x == nil then
           self.db.global.toons[me].x = 0


    Unless I've been missing something in Lua, isn't this a syntax error because each if-block isn't ended? But I can't imagine this causing anything short of massive problems outside what you describe, so I'm assuming I'm getting confused somehow.
    Posted in: Lua Code Discussion
  • 0

    posted a message on precise, comparable, date & time stamp
    If you want the process of picking a master to be complicated and without needing to communicate (not sure if you were having the new client roll and pick or if they would roll and broadcast rolls), a way for everyone to decide would be to hash some strings together and get an integer result and sort by that. Though this is probably way over-complicating things and inefficient given Lua's lack of character support and bitwise functions, here's what I came up with out of boredom and curiosity:

    local function hash(key, ...)
    	local i, j, str;
    	for i=1,select('#', ...) do
    		j=0;
    		str=select(i, ...);
    		key = key:gsub(".", function(k)
    			j = (j % strlen(str))+1;
    			return strchar((strbyte(k,1)*strbyte(str,j)) % 256);
    		end);
    	end
    	i=0;
    	for j=1,strlen(key) do
    		i = (i + strbyte(key,j)) % 100;
    	end
    	return i;
    end


    So you could do something like:
    hash("COMM_CHANNEL", new_client_name, potential_master[i]);

    to assign an integer value to each master, and then pick by lowest or something.

    Again, disclaimer that I know next to nothing about optimization in Lua and this probably sucks/is overcomplicated/was mostly for fun.
    Posted in: Lua Code Discussion
  • 0

    posted a message on Chat throttling and general code cleanliness questions.
    I actually wrote the same addon for my guild. Though I don't understand your first question completely (why not just print one person, one damage value per line?), I do have something that worked for me for the second problem, so long as you are okay with destroying the data after it is printed (as I do at the end of each pull). This is built on my own framework, but should still be straightforward. Basically, keep finding the max, print it, and discard it. I do top 5 each pull.

    if (next(damageBoard)) then
    	local type = "minor"; -- this type prints to raid
    	local count = 5;
    	core:Message("Val'kyr Overkill:", type);
    	for i=1,count do
    		local max = 0;
    		for p,dmg in pairs(damageBoard) do
    			if (dmg > (damageBoard[max] or 0)) then
    				max = p;
    			end
    		end
    		if (damageBoard[max]) then
    			core:Message(format("%d. %s - %.1fk", i, max, damageBoard[max]/1000), type);
    			damageBoard[max] = nil;
    		end
    	end
    	wipe(damageBoard);
    end
    Posted in: Lua Code Discussion
  • To post a comment, please or register a new account.