|
02-06-12, 04:52 AM | #1 |
Pattern matching and "player playing" status
Hello,
I've got two question I hope to get answers to: 1. I'm trying to match a pattern in strings that can come in two ways: a. "Bases: 3 Points: 150/1600 ..." b. "Points/Flags: 2 ..." I want to get the 150 in case it's a string type 'a' (with ####/####). And in case there is no such pattern (type 'b'), I want to get the number - 2 in the example. I've tried to use: Code:
string.match(origString, "(%d+)/*") Code:
string.match(origString, "(%d+)/") Is there a matching pattern that will catch both cases? Note that the string before the number can alter, it's not always 'Points' for example. 2. When trying to whisper to an offline player, I get error "No player named XXX is currently playing". Is there a way to know that prior to the whisper? Like an API telling me that? I looked but couldn't find one. Thanks |
|
02-06-12, 06:26 AM | #2 |
#1 - I don't think you're going to be able to get those with one pattern.
You want the values underlined here: (a) Bases: 3 Points: 150/1600 ... (b) Points/Flags: 2 ... But, any pattern I can think of would be unable to distinguish between the values underlined here: (a) Bases: 3 Points: 150/1600 ... (b) Points/Flags: 2 ... If you require a slash immediately after the number, then the pattern will not work to find the deisred number in the (b) string because there is no slash. If you can be more specific about where these strings are coming from and what you want to do with them, I can probably provide a better solution. #2 - There are three ways to tell if someone is online or offline: (1) They are on your friends list. (2) They are in your guild. (3) You perform a /who query that matches them. For addons sending whispers to arbitrary players who are not on your friends list or in your guild, I'd suggest looking at BadBoy_Levels for an example of how to add a name to your friends list for just long enough to get information about them (and then removing them so they are never "really" on the friends list as far as the user is concerned). BB_L checks their level, but the same code would work to see if they were online. Depending on why you want to do this, however, I'd be very careful. If you're sending instructions to players in your battleground, it shouldn't be an issue, but if you're sending, say, guild invitations via whisper, you're likely to generate a lot of ill will. Personally, I instantly /ignore anyone who sends me an unsolicited whisper about something I don't care about, and pretty much any topic people are whispering me about using an addon is something I don't care about. |
|
02-06-12, 06:57 AM | #3 |
Thanks
As for (1), the info is BG score I get from the API GetWorldStateUIInfo(). Some BGs have points/maxpoints, some have only points. My current workaround is to identify in what kind of BG the player is now, then set a different matching pattern according to the BG type. I was trying to make a generic matching pattern, in order for the code to be more efficient. I thought that using '*' will try to find the longest pattern so it will try to include '/' in the matched pattern, if any can found. I thought that this is the difference between '-' (shortest pattern) and '*' (longest patter). But apparently I was wrong about it, since it doesn't apply to several matches in a single string. (2) I'm a bit afraid of adding a player to the friends list, then removing it, like you've suggested. It seems to be too intrusive method. I'm afraid that that player might remain in the friend list on unpredictable cases, like a DC at the wrong moment, etc. "who" query looks too complex and problematic according to this: http://www.wowpedia.org/API_SetWhoToUI Edit: btw, I'm not sending unsolicited whisper, I hate those gold seller spam addons myself and I use badboy to report them. Last edited by Animor : 02-06-12 at 07:02 AM. |
|
02-06-12, 07:27 AM | #4 |
Battleground-specific code sounds like the way to go. I don't know which event(s) fire when the return values from that function change, but something like this:
Code:
local zoneFunctions = { ["Eye of the Storm"] = function(...) -- code goes here to deal with Eye of the Storm messages end, ["Warsong Gulch"] = function(...) -- code goes here to deal with Warsong Gulch messages end, } local fallbackFunction = function(...) -- code goes here to deal with unknown zones, -- or just leave the function empty end local currentFunction function addon:ZONE_CHANGED_NEW_AREA() local zone = GetRealZoneText() currentFunction = zoneFunctions[zone] or fallbackFunction end function addon:SOME_EVENT(...) -- 1. do any zone-independent pre-processing here -- 2. pass the args to the relevant function: currentFunction(...) -- 3. do any zone-independent post-processing here end |
|
02-06-12, 07:44 AM | #5 |
Thanks
I've already used a bit different approach. I will be happy to know if you see any flaws in it: Code:
function MyAddon:GetBGScore(locationName) local allianceScore = "" local hordeScore = "" local num1 = 1 local num2 = 2 local matchString = "(%d+)" local score1 = 0 local score2 = 0 local scoreMsg = "" -- BGs in which score format is ####/#### if sfind(locationName, "Gilneas") or sfind(locationName, "Basin") or sfind(locationName, "Storm") then matchString = "(%d+)/" end -- For BGs in which the first info line is global (not faction score) if sfind(locationName, "Warsong") or sfind(locationName, "Peaks") or sfind(locationName, "Storm") then num1 = 2 num2 = 3 end -- Get factions score from the lines that appear top-middle of the screen score1 = tonumber(smatch((select(4, GetWorldStateUIInfo(num1)) or ""), matchString)) or 0 score2 = tonumber(smatch((select(4, GetWorldStateUIInfo(num2)) or ""), matchString)) or 0 -- Location on screen - is first line Alliance or Horde? if sfind(string.lower(select(5, GetWorldStateUIInfo(num1))), "alliance") then allianceScore = score1 hordeScore = score2 else allianceScore = score2 hordeScore = score1 end -- No score in Strand of the Ancients, report instead end of round timer. if sfind(locationName, "Strand") then local endtime = smatch((select(4, GetWorldStateUIInfo(8)) or ""), "%d+.*") or L["<no data>"] scoreMsg = L["End of round in "]..endtime.. L[" min"] else scoreMsg = L["Score: "]..allianceScore.."(A) - "..hordeScore.."(H), " end return scoreMsg end Last edited by Animor : 02-06-12 at 07:53 AM. |
|
02-06-12, 08:08 AM | #6 |
I'd try to come up with something to reduce the use of string manipulation functions, but other than that I don't see anything obviously wrong.
For example, instead of: Code:
local matchString = "(%d+)" -- BGs in which score format is ####/#### if sfind(locationName, "Gilneas") or sfind(locationName, "Basin") or sfind(locationName, "Storm") then matchString = "(%d+)/" end Code:
local matchStrings = { ["Arathi Basin"] = "(%d+)/", ["Eye of the Storm"] = "(%d+)/", ["Warsong Gulch"] = "(%d+)", } Code:
local zoneName = GetRealZoneText() local matchString = matchStrings[zoneName] |
|
02-06-12, 07:33 AM | #7 | |
http://www.wowinterface.com/forums/s...ad.php?t=40977 |
||
WoWInterface » Developer Discussions » Lua/XML Help » Pattern matching and "player playing" status |
«
Previous Thread
|
Next Thread
»
|
Display Modes |
Switch to Linear Mode |
Hybrid Mode |
Switch to Threaded Mode |
|
|