Skip to content

Commit

Permalink
XMPPRoster now automatically ties into MUC system to ignore presence …
Browse files Browse the repository at this point in the history
…elements related to MUC rooms.
  • Loading branch information
robbiehanson committed Apr 2, 2012
1 parent 0f873f1 commit 07dfba6
Show file tree
Hide file tree
Showing 5 changed files with 98 additions and 7 deletions.
4 changes: 3 additions & 1 deletion Extensions/Roster/XMPPRoster.h
Expand Up @@ -9,7 +9,7 @@
#import "XMPPResource.h"

@protocol XMPPRosterStorage;

@class DDList;

/**
* The XMPPRoster provides the scaffolding for a roster solution.
Expand Down Expand Up @@ -44,6 +44,8 @@
Byte flags;

NSMutableArray *earlyPresenceElements;

DDList *mucModules;
}

- (id)initWithRosterStorage:(id <XMPPRosterStorage>)storage;
Expand Down
66 changes: 64 additions & 2 deletions Extensions/Roster/XMPPRoster.m
Expand Up @@ -2,6 +2,7 @@
#import "XMPP.h"
#import "XMPPLogging.h"
#import "XMPPFramework.h"
#import "DDList.h"

#if ! __has_feature(objc_arc)
#warning This file must be compiled with ARC. Use -fobjc-arc flag (or convert project to ARC).
Expand Down Expand Up @@ -73,6 +74,8 @@ - (id)initWithRosterStorage:(id <XMPPRosterStorage>)storage dispatchQueue:(dispa
flags = 0;

earlyPresenceElements = [[NSMutableArray alloc] initWithCapacity:2];

mucModules = [[DDList alloc] init];
}
return self;
}
Expand All @@ -86,7 +89,27 @@ - (BOOL)activate:(XMPPStream *)aXmppStream
XMPPLogVerbose(@"%@: Activated", THIS_FILE);

#ifdef _XMPP_VCARD_AVATAR_MODULE_H
[xmppStream autoAddDelegate:self delegateQueue:moduleQueue toModulesOfClass:[XMPPvCardAvatarModule class]];
{
// Automatically tie into the vCard system so we can store user photos.

[xmppStream autoAddDelegate:self
delegateQueue:moduleQueue
toModulesOfClass:[XMPPvCardAvatarModule class]];
}
#endif

#ifdef _XMPP_MUC_H
{
// Automatically tie into the MUC system so we can ignore non-roster presence stanzas.

[xmppStream enumerateModulesWithBlock:^(XMPPModule *module, NSUInteger idx, BOOL *stop) {

if ([module isKindOfClass:[XMPPMUC class]])
{
[mucModules add:(__bridge void *)module];
}
}];
}
#endif

return YES;
Expand All @@ -100,7 +123,9 @@ - (void)deactivate
XMPPLogTrace();

#ifdef _XMPP_VCARD_AVATAR_MODULE_H
[xmppStream removeAutoDelegate:self delegateQueue:moduleQueue fromModulesOfClass:[XMPPvCardAvatarModule class]];
{
[xmppStream removeAutoDelegate:self delegateQueue:moduleQueue fromModulesOfClass:[XMPPvCardAvatarModule class]];
}
#endif

[super deactivate];
Expand Down Expand Up @@ -676,6 +701,20 @@ - (void)xmppStream:(XMPPStream *)sender didReceivePresence:(XMPPPresence *)prese
}
else
{
#ifdef _XMPP_MUC_H

// Ignore MUC related presence items

for (XMPPMUC *muc in mucModules)
{
if ([muc isMUCRoomPresence:presence])
{
return;
}
}

#endif

[xmppRosterStorage handlePresence:presence xmppStream:xmppStream];
}
}
Expand Down Expand Up @@ -718,6 +757,29 @@ - (void)xmppStreamDidDisconnect:(XMPPStream *)sender withError:(NSError *)error
[earlyPresenceElements removeAllObjects];
}

#ifdef _XMPP_MUC_H

- (void)xmppStream:(XMPPStream *)sender didRegisterModule:(id)module
{
if ([module isKindOfClass:[XMPPMUC class]])
{
if (![mucModules contains:(__bridge void *)module])
{
[mucModules add:(__bridge void *)module];
}
}
}

- (void)xmppStream:(XMPPStream *)sender willUnregisterModule:(id)module
{
if ([module isKindOfClass:[XMPPMUC class]])
{
[mucModules remove:(__bridge void *)module];
}
}

#endif

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#pragma mark XMPPvCardAvatarDelegate
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Expand Down
19 changes: 15 additions & 4 deletions Extensions/XEP-0045/XMPPMUC.m
Expand Up @@ -81,19 +81,30 @@ - (void)xmppStream:(XMPPStream *)sender didRegisterModule:(id)module
{
if ([module isKindOfClass:[XMPPRoom class]])
{
XMPPRoom *room = (XMPPRoom *)module;
XMPPJID *roomJID = [(XMPPRoom *)module roomJID];

[rooms addObject:room.roomJID];
[rooms addObject:roomJID];
}
}

- (void)xmppStream:(XMPPStream *)sender willUnregisterModule:(id)module
{
if ([module isKindOfClass:[XMPPRoom class]])
{
XMPPRoom *room = (XMPPRoom *)module;
XMPPJID *roomJID = [(XMPPRoom *)module roomJID];

[rooms removeObject:room.roomJID];
// It's common for the room to get deactivated and deallocated before
// we've received the goodbye presence from the server.
// So we're going to postpone for a bit removing the roomJID from the list.
// This way the isMUCRoomElement will still remain accurate
// for presence elements that may arrive momentarily.

double delayInSeconds = 30.0;
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, delayInSeconds * NSEC_PER_SEC);
dispatch_after(popTime, moduleQueue, ^{ @autoreleasepool {

[rooms removeObject:roomJID];
}});
}
}

Expand Down
2 changes: 2 additions & 0 deletions Utilities/DDList.h
Expand Up @@ -33,6 +33,8 @@ typedef struct DDListNode DDListNode;
- (void)removeAll:(void *)element;
- (void)removeAllElements;

- (BOOL)contains:(void *)element;

- (NSUInteger)count;

/**
Expand Down
14 changes: 14 additions & 0 deletions Utilities/DDList.m
Expand Up @@ -122,6 +122,20 @@ - (void)removeAllElements
listTail = NULL;
}

- (BOOL)contains:(void *)element
{
DDListNode *node;
for (node = listHead; node != NULL; node = node->next)
{
if (node->element == element)
{
return YES;
}
}

return NO;
}

- (NSUInteger)count
{
NSUInteger count = 0;
Expand Down

0 comments on commit 07dfba6

Please sign in to comment.