Keep track of users in a channel.

FossilOrigin-Name: 5f51d55981a74610c7d36038d540cc689b15d41194b00b2e8b0c7428bf102341
This commit is contained in:
Jonathan Schleifer 2011-10-05 19:40:33 +00:00
parent 77e2dba178
commit 318f4a2c1b
5 changed files with 83 additions and 1 deletions

View file

@ -21,16 +21,21 @@
*/ */
#import <ObjFW/OFObject.h> #import <ObjFW/OFObject.h>
#import <ObjFW/OFSet.h>
@class OFString; @class OFString;
@interface IRCChannel: OFObject @interface IRCChannel: OFObject
{ {
OFString *name; OFString *name;
OFMutableSet *users;
} }
@property (readonly) OFString *name; @property (readonly) OFString *name;
@property (copy) OFSet *users;
+ channelWithName: (OFString*)name; + channelWithName: (OFString*)name;
- initWithName: (OFString*)name; - initWithName: (OFString*)name;
- (void)IRC_addUser: (OFString*)user;
- (void)IRC_removeUser: (OFString*)user;
@end @end

View file

@ -23,7 +23,7 @@
#import "IRCChannel.h" #import "IRCChannel.h"
@implementation IRCChannel @implementation IRCChannel
@synthesize name; @synthesize name, users;
+ channelWithName: (OFString*)name + channelWithName: (OFString*)name
{ {
@ -36,6 +36,7 @@
@try { @try {
name = [name_ copy]; name = [name_ copy];
users = [[OFMutableSet alloc] init];
} @catch (id e) { } @catch (id e) {
[self release]; [self release];
@throw e; @throw e;
@ -47,6 +48,7 @@
- (void)dealloc - (void)dealloc
{ {
[name release]; [name release];
[users release];
[super dealloc]; [super dealloc];
} }
@ -55,4 +57,14 @@
{ {
return name; return name;
} }
- (void)IRC_addUser: (OFString*)user
{
[users addObject: user];
}
- (void)IRC_removeUser: (OFString*)user
{
[users removeObject: user];
}
@end @end

View file

@ -68,6 +68,8 @@
didReceiveNotice: (OFString*)notice didReceiveNotice: (OFString*)notice
fromUser: (IRCUser*)user fromUser: (IRCUser*)user
inChannel: (IRCChannel*)channel; inChannel: (IRCChannel*)channel;
- (void)connection: (IRCConnection*)connection
didReceiveNamesForChannel: (IRCChannel*)channel;
@end @end
@interface IRCConnection: OFObject @interface IRCConnection: OFObject

View file

@ -226,6 +226,8 @@
} else } else
channel = [channels objectForKey: where]; channel = [channels objectForKey: where];
[channel IRC_addUser: user.nickname];
if ([delegate respondsToSelector: if ([delegate respondsToSelector:
@selector(connection:didSeeUser:joinChannel:)]) @selector(connection:didSeeUser:joinChannel:)])
[delegate connection: self [delegate connection: self
@ -236,6 +238,47 @@
return; return;
} }
/* NAMES reply */
if ([action isEqual: @"353"] && split.count >= 6) {
IRCChannel *channel;
OFArray *users;
size_t pos;
channel = [channels objectForKey: [split objectAtIndex: 4]];
if (channel == nil) {
/* We did not request that */
[pool release];
return;
}
pos = [[split objectAtIndex: 0] length] +
[[split objectAtIndex: 1] length] +
[[split objectAtIndex: 2] length] +
[[split objectAtIndex: 3] length] +
[[split objectAtIndex: 4] length] + 6;
users = [[line substringWithRange:
of_range(pos, line.length - pos)]
componentsSeparatedByString: @" "];
for (OFString *user in users) {
if ([user hasPrefix: @"@"] || [user hasPrefix: @"+"] ||
[user hasPrefix: @"%"] || [user hasPrefix: @"*"])
user = [user substringWithRange:
of_range(1, user.length - 1)];
[channel IRC_addUser: user];
}
if ([delegate respondsToSelector: @selector(connection:
didReceiveNamesForChannel:)])
[delegate connection: self
didReceiveNamesForChannel: channel];
[pool release];
return;
}
/* PART */ /* PART */
if ([action isEqual: @"PART"] && split.count >= 3) { if ([action isEqual: @"PART"] && split.count >= 3) {
OFString *who = [split objectAtIndex: 0]; OFString *who = [split objectAtIndex: 0];
@ -254,6 +297,8 @@
reason = [line substringWithRange: reason = [line substringWithRange:
of_range(pos + 2, line.length - pos - 2)]; of_range(pos + 2, line.length - pos - 2)];
[channel IRC_removeUser: user.nickname];
if ([delegate respondsToSelector: if ([delegate respondsToSelector:
@selector(connection:didSeeUser:leaveChannel: @selector(connection:didSeeUser:leaveChannel:
withReason:)]) withReason:)])
@ -286,6 +331,8 @@
reason = [line substringWithRange: reason = [line substringWithRange:
of_range(pos + 2, line.length - pos - 2)]; of_range(pos + 2, line.length - pos - 2)];
[channel IRC_removeUser: user.nickname];
if ([delegate respondsToSelector: if ([delegate respondsToSelector:
@selector(connection:didSeeUser:kickUser: @selector(connection:didSeeUser:kickUser:
fromChannel:withReason:)]) fromChannel:withReason:)])
@ -313,6 +360,9 @@
reason = [line substringWithRange: reason = [line substringWithRange:
of_range(pos + 2, line.length - pos - 2)]; of_range(pos + 2, line.length - pos - 2)];
for (IRCChannel *channel in channels)
[channel IRC_removeUser: user.nickname];
if ([delegate respondsToSelector: if ([delegate respondsToSelector:
@selector(connection:didSeeUserQuit:withReason:)]) @selector(connection:didSeeUserQuit:withReason:)])
[delegate connection: self [delegate connection: self
@ -340,6 +390,13 @@
nickname = [user.nickname copy]; nickname = [user.nickname copy];
} }
for (IRCChannel *channel in channels) {
if ([channel.users containsObject: user.nickname]) {
[channel IRC_removeUser: user.nickname];
[channel IRC_addUser: newNickname];
}
}
if ([delegate respondsToSelector: if ([delegate respondsToSelector:
@selector(connection:didSeeUser:changeNicknameTo:)]) @selector(connection:didSeeUser:changeNicknameTo:)])
[delegate connection: self [delegate connection: self

View file

@ -132,4 +132,10 @@ OF_APPLICATION_DELEGATE(TestApp)
{ {
of_log(@"NOTICE: [%@] %@: %@", channel, user, notice); of_log(@"NOTICE: [%@] %@: %@", channel, user, notice);
} }
- (void)connection: (IRCConnection*)connection
didReceiveNamesForChannel: (IRCChannel*)channel
{
of_log(@"Users in %@: %@", channel, channel.users);
}
@end @end