PDA

View Full Version : Addon developers - opinions requested for Jamba character online checks.



Jafula
01-07-2009, 07:57 PM
I know a few addon developers lurk on these forums; hopefully you can help...

Jamba needs to know if your team members are online or not. If your team members are online, Jamba can send messages to them. Otherwise you get a lot of "Player Not Found" messages. Currently Jamba has a character "enabled" toggle. This toggle is confusing, but it works. I would like to remove this "enabled" setting and let Jamba decide whether your characters are online or not.

I have implemented the following:
When the addon is enabled, check to see if characters are online using UnitIsConnected( characterName ) - this is only good for party/raid AFAIK. If this check fails, try /who. I use SendWho( "-n"..characterName ) and catch the WHO_LIST_UPDATE event. Then I send a command to all characters that this character can see online telling them this character is online. Problem is, if all team members have just logging in, no one will know about anyone else, so the tell I am online command is useless. So I run both commands again in 15, 30 seconds. I also check for connection status when party members/leader changes. When a character logs out, they send a message to the others telling them they have gone offline.Other stuff:
I'm adding profile support; so you can set up solo modes / different teams easily. I know about LibWho2, but I could not get the library to function as I wanted and it has lot of extra code I won't use. What I have now doesn't work (not had much time to try it) and the friends frame who list pops up upon login.
Questions:
I'm not sure that the SetWhoToUI API command is going to be honored; I'm sure another addon can change it. Anyone know / have any experience with this? Will the WHO_LIST_UPDATE event always fire when who results are returned (seems to be controlled by the SetWhoToUI command)? Should I be checking for online status at other times? On a repeated timer? Other events? Should I even bother with the online checks( the enabled thing seems to work ok and this seems very flaky)?Relevant code (work in progress):



-- Called when the addon is enabled.
function AJM:OnEnable()
self:RegisterEvent( "WHO_LIST_UPDATE" )
self:RegisterEvent( "PLAYER_LOGOUT" )
self:RegisterEvent( "PARTY_LEADER_CHANGED" )
self:RegisterEvent( "PARTY_MEMBERS_CHANGED" )
-- Get team members online status to not connected.
self:__InitialiseTeamOnlineStatus()
-- Get the online status for other team members.
self:UpdateTeamOnlineStatus()
-- Kickstart the settings team list scroll frame.
self:__SettingsTeamListScrollRefresh()
-- Tell other members in the team that this character is online.
self:JambaSendCommandToTeam( AJM.COMMAND_CHARACTER_ONLINE, self.characterName, true )
-- Check online status again in 15 seconds.
self:ScheduleTimer( "UpdateTeamOnlineStatus", 15 )
-- Send I am online command to team again in 30 seconds.
self:ScheduleTimer( "JambaSendCommandToTeam", 30, AJM.COMMAND_CHARACTER_ONLINE, self.characterName, true )
end

-- Update team online status.
function AJM:UpdateTeamOnlineStatus()
for characterName, characterOrder in pairs( self.db.teamList ) do
self:__UpdateCharacterOnlineStatus( characterName )
end
end

-- Get a character's online status.
function AJM:__GetCharacterOnlineStatus( characterName )
return self.characterOnline[characterName]
end

-- Set a character's online status.
function AJM:__SetCharacterOnlineStatus( characterName, isOnline )
self.characterOnline[characterName] = isOnline
AJM:__SettingsTeamListScrollRefresh()
end

-- Update character online status.
function AJM:__UpdateCharacterOnlineStatus( characterName )
-- Check to see if it is in the same party/raid as this character.
if UnitIsConnected( characterName ) == 1 then
self:__SetCharacterOnlineStatus( characterName, true )
else
-- Does not appear to be in the same party/raid.
-- Make sure results are sent to the WHO_LIST_UPDATE event.
-- TODO: Does this popup the who dialog in the friends frame?
SetWhoToUI( 1 )
-- Check /who.
SendWho( "-n"..characterName )
end
end

function AJM:__InitialiseTeamOnlineStatus()
-- Set all characters online status to false.
for characterName, characterOrder in pairs( self.db.teamList ) do
self:__SetCharacterOnlineStatus( characterName, false )
end
end

function AJM:WHO_LIST_UPDATE()
-- TODO; which return from GetNumWhoResults to use?
local matchingCharacters, totalResults = GetNumWhoResults()
for iterateWhoResults = 1, totalResults do
local characterName, guildName, level, race, class, zone, classFileName = GetWhoInfo( iterateWhoResults )
if self:CharacterIsInTeam( characterName ) == true then
self:__SetCharacterOnlineStatus( characterName, true )
end
end
end

-- Player is logging out.
function AJM:PLAYER_LOGOUT()
-- Tell the other team members this player has logged out.
self:JambaSendCommandToTeam( AJM.COMMAND_CHARACTER_ONLINE, self.characterName, false )
end

-- Party leader changed.
function AJM:PARTY_LEADER_CHANGED()
-- Get the online status for other team members.
self:UpdateTeamOnlineStatus()
end

-- Party members changed.
function AJM:PARTY_MEMBERS_CHANGED()
-- Get the online status for other team members.
self:UpdateTeamOnlineStatus()
end


Any ideas / suggestions / criticism on this system greatly appreciated.

Jafula
01-07-2009, 08:03 PM
Well I missed that the SendWho command should be:

SendWho("n-\"..characterName..\"")

JasonB87
01-07-2009, 10:06 PM
The only thing I can think of after looking at the api could be adding the groups names to the players friend list then use GetFriendInfo(index). Only problem I see with this is you would need to query for the number of friends GetNumFriends() then loop for index matches by checking the name returned GetFriendInfo(index). I do not know if the indexes change as users sign on, I would assume they don't meaning once you grab the index just a matter of querying the players that are offline until you get an online response. Kinda sounds cumbersome to me but I can't think of any way for members to discover members.

dippy
01-08-2009, 02:59 AM
Unfortunately, I haven't seen an API call that does exactly what you want.

I have seen a number of addons that use a common channel to communicate and update automatically.

The idea is for all group members to use the same channel using a unique name entered by the jamba user. On logon, the jamba master would announce itself to the channel and ask for all online toons in the channel to respond. Each client would also announce login/logout to the channel, and the master would ping frequently (every minute?) to check for clients who logged off without notification.

The most recent code I saw to do this was for Guild Event Manager ('http://christophe.calmejane.free.fr/wow/gem/').

It's going to require quite a bit of manual coding unfortunately, so I'm not sure how worthwhile the time invested would be.

Jafula
01-08-2009, 06:28 AM
The only thing I can think of after looking at the api could be adding the groups names to the players friend list then use GetFriendInfo(index). Only problem I see with this is you would need to query for the number of friends GetNumFriends() then loop for index matches by checking the name returned GetFriendInfo(index). I do not know if the indexes change as users sign on, I would assume they don't meaning once you grab the index just a matter of querying the players that are offline until you get an online response. Kinda sounds cumbersome to me but I can't think of any way for members to discover members.Thanks for your response; I did this with the original Jamba 0.1. While developing, I managed to get it into a state where I could consistently crash wow.exe with a 132 error. :D On release, it worked for some and did not work for others (wow could not load). Some people had full friends lists and didn't like their characters being added to their friends list. So I think the friends list idea is out.

Jafula
01-08-2009, 06:42 AM
Unfortunately, I haven't seen an API call that does exactly what you want.

I have seen a number of addons that use a common channel to communicate and update automatically.

The idea is for all group members to use the same channel using a unique name entered by the jamba user. On logon, the jamba master would announce itself to the channel and ask for all online toons in the channel to respond. Each client would also announce login/logout to the channel, and the master would ping frequently (every minute?) to check for clients who logged off without notification.

The most recent code I saw to do this was for Guild Event Manager ('http://christophe.calmejane.free.fr/wow/gem/').

It's going to require quite a bit of manual coding unfortunately, so I'm not sure how worthwhile the time invested would be.Thanks, I like this idea. It would be reasonably simple to do, I would have to tweak it to be peer to peer rather than master based, but it would solve the problems I have trying to send addon messages to players that are not online. I could define a default channel for Jamba, with an option to override it with the name of another channel should the default channel get hijacked.

DgtlSorcrs
01-09-2009, 01:21 PM
That solution kind of reminds me of an ARP request ("whohas 192.168.0.1")

I was trying to do something similar in terms of having my addon know if a toon existed (so when you would type a name in my white list, it would only allow you to put in valid toon names... to help avoid misspellings), but I found that if a toon was not online, I could get no info on them (they did not exist)

However, even if you have a valid toon name can't you just do UnitExists('name') because if they are offline, but exist, you get same result as if they don't exist at all.

From my reference materials, I would think UnitIsConnected(unitid|name) would work, but obviously, you've already tried it and found that it only works in party

This might be clunky, but what about making sure the target is either in guild or on friends list and have the player make sure the UI announces logon / logoff, then you could have your app watch the CHAT_MSG_SYSTEM event and then parse the messages to see if so-and-so has gone offline / come online?

Sorry if you've already tried this route too.

Jafula
01-09-2009, 01:41 PM
Thanks for the ideas, DgtlSorcrs. I want to be as unobtrusive as possible. Relying on toons being in friends / guild list was something I tried in the early days.

Last night, I had some success with custom channel method that dippy mention. WoW keeps track of who is in a channel, so joining a channel when the addon starts is all I have to do to announce a toons presence. When the toon logs off an event is fired, so I can keep track of toons leaving that way. Polling the /chatwho once in a while lets me catch up with any characters I missed.

And once your toons are in a group, my character online code also checks for same party / raid membership and if it finds that it just ignores the online status. So for the majority out there whose toons are usually always grouped, there will never be any issues of characters being ignored when they are online.

BobGnarly
01-09-2009, 07:54 PM
Premise: UnitExists() returns nil if you are logged out or if the character really doesn't exist.

If this is true, why not just use it to query the "existence" of the team member before you ever send them a message? I know this might not alert you to the case where you typo'd the name, but I think you'd notice that pretty quick when it wasn't working with one of your clients. The result would be quite a bit more elegant I think, it could probably be handled with something like:


function AJM:SendMsgToChar( characterName )
if(UnitExists(characterName)) then
-- do whatever to send the message
end;
end


...and just use this whenever you want to send to another character.

I tend to prefer these types of "stateless" approaches since they aren't prone to failure if, for some reason, your list of active characters gets out of sync (which, as a programmer, I can tell you they definitely will at some point ;)).

Jafula
01-09-2009, 08:10 PM
Premise: UnitExists() returns nil if you are logged out or if the character really doesn't exist.

If this is true, why not just use it to query the "existence" of the team member before you ever send them a message? I know this might not alert you to the case where you typo'd the name, but I think you'd notice that pretty quick when it wasn't working with one of your clients. The result would be quite a bit more elegant I think, it could probably be handled with something like:Thanks for your post. UnitExists is only valid if the unit you are querying is in your party or raid. I could have two of my characters next to each other (not grouped) and they would not know about each other. I frequently hit the Taxi, before I've gotten around to inviting my my characters to a group. Plus, the 6+ boxers might like to Taxi characters around using Jamba, and the UnitExists() would not work for them.

Oh, how I wish for stateless... I'm happy with my current solution (one more bug to fix) which is the channel join/leave/list members approach (no messages are ever sent on the channel). Basically I let WoW do my record keeping for me. My other characters status changes on my screen when they come online / go offline within a few seconds. It is very sweet compared with the enabled/disabled confused mess the current Jamba has.

dippy
01-12-2009, 02:33 AM
I could define a default channel for Jamba, with an option to override it with the name of another channel should the default channel get hijacked.Glad to hear you've (almost) got it working. I would still force the channel to be user-entered, as more than one boxer on the same faction and realm will interfere with one another. Or maybe make the channel be Jamba-<MASTERCHARNAME> and the user just enters the master toon in each client as they do now.

DgtlSorcrs
01-12-2009, 02:37 PM
It probably gets too far away from the direction you want to go in, but I ended up building a "white list" which was separate from friends / guild for similar reasons (wanted to not rely on in friends/guild list). One of the things I had wanted to do was when you'd type in a name to add to the list, it would "who' them to ensure that only valid names were in the list. But this failed for me as it turns out that every option I tried required the target toon to be online for it to know about them, or worse, as you've seen, in the party/raid.

In the end, the best option may end up being to figure out a good triggering event and loop through your team setup as someone else already suggested.

I'm glad they lock down WoW LUA so folks can't cheat / write hostile addons, but sometimes when I want to do something benign like this, I end up pounding my head on my desk. Some of the suggestions here HAVE given me some ideas for completely unrelated stuff though. muwwwa haah hahha (evyl laugh).

Jafula
01-12-2009, 03:48 PM
I could define a default channel for Jamba, with an option to override it with the name of another channel should the default channel get hijacked.Glad to hear you've (almost) got it working. I would still force the channel to be user-entered, as more than one boxer on the same faction and realm will interfere with one another. Or maybe make the channel be Jamba-<MASTERCHARNAME> and the user just enters the master toon in each client as they do now.No need to force the channel to be user entered (it will be an option). There are no messages sent on the channel.

Basically, I just check the channel to see who is in it. If any of those toons are in Jamba's toon list, then they must be online. If they are another boxers toons, Jamba will just ignore them as they are not in the list. And if you were a malicious boxer and entered someone else's toons name in your list; those toons would ignore your commands as your toons will not be in their list.

Channels fire an event for joining / leaving which I catch and update toon status as appropriate.

Also masters can change in Jamba, so creating a channel with the masters name could be problematic. I believe, that some users run Jamba with self as master as well (even in a team).


It probably gets too far away from the direction you want to go in, but I ended up building a "white list" which was separate from friends / guild for similar reasons (wanted to not rely on in friends/guild list). One of the things I had wanted to do was when you'd type in a name to add to the list, it would "who' them to ensure that only valid names were in the list. But this failed for me as it turns out that every option I tried required the target toon to be online for it to know about them, or worse, as you've seen, in the party/raid.

In the end, the best option may end up being to figure out a good triggering event and loop through your team setup as someone else already suggested.

I'm glad they lock down WoW LUA so folks can't cheat / write hostile addons, but sometimes when I want to do something benign like this, I end up pounding my head on my desk. Some of the suggestions here HAVE given me some ideas for completely unrelated stuff though. muwwwa haah hahha (evyl laugh).The channel solution works very well. I've been at this problem since August 2008 (on and off); and this is the nicest yet. A character logs off and my other characters know immediately; (see the screenshot for the Jamba 0.5 UI in the main Jamba thread).

I like that this conversation has sparked some ideas for you.