Port to ObjC1.
FossilOrigin-Name: 7f37e545cfcebaba2be9b426cdd4fc2c425982278d1baf68da55458943ad606f
This commit is contained in:
parent
279f33ec61
commit
9fbc9c9b30
7 changed files with 374 additions and 189 deletions
|
@ -31,11 +31,15 @@
|
||||||
OFMutableSet *users;
|
OFMutableSet *users;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef OF_HAVE_PROPERTIES
|
||||||
@property (readonly) OFString *name;
|
@property (readonly) OFString *name;
|
||||||
@property (copy) OFSet *users;
|
@property (readonly, copy) OFSet *users;
|
||||||
|
#endif
|
||||||
|
|
||||||
+ channelWithName: (OFString*)name;
|
+ channelWithName: (OFString*)name;
|
||||||
- initWithName: (OFString*)name;
|
- initWithName: (OFString*)name;
|
||||||
|
- (OFString*)name;
|
||||||
|
- (OFSet*)users;
|
||||||
- (void)IRC_addUser: (OFString*)user;
|
- (void)IRC_addUser: (OFString*)user;
|
||||||
- (void)IRC_removeUser: (OFString*)user;
|
- (void)IRC_removeUser: (OFString*)user;
|
||||||
@end
|
@end
|
||||||
|
|
|
@ -22,11 +22,11 @@
|
||||||
|
|
||||||
#import <ObjFW/OFString.h>
|
#import <ObjFW/OFString.h>
|
||||||
|
|
||||||
|
#import <ObjFW/macros.h>
|
||||||
|
|
||||||
#import "IRCChannel.h"
|
#import "IRCChannel.h"
|
||||||
|
|
||||||
@implementation IRCChannel
|
@implementation IRCChannel
|
||||||
@synthesize name, users;
|
|
||||||
|
|
||||||
+ channelWithName: (OFString*)name
|
+ channelWithName: (OFString*)name
|
||||||
{
|
{
|
||||||
return [[[self alloc] initWithName: name] autorelease];
|
return [[[self alloc] initWithName: name] autorelease];
|
||||||
|
@ -55,9 +55,19 @@
|
||||||
[super dealloc];
|
[super dealloc];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (OFString*)name
|
||||||
|
{
|
||||||
|
OF_GETTER(name, YES)
|
||||||
|
}
|
||||||
|
|
||||||
|
- (OFSet*)users
|
||||||
|
{
|
||||||
|
return [[users copy] autorelease];
|
||||||
|
}
|
||||||
|
|
||||||
- (OFString*)description
|
- (OFString*)description
|
||||||
{
|
{
|
||||||
return name;
|
return [[name copy] autorelease];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)IRC_addUser: (OFString*)user
|
- (void)IRC_addUser: (OFString*)user
|
||||||
|
|
|
@ -29,8 +29,14 @@
|
||||||
@class IRCUser;
|
@class IRCUser;
|
||||||
@class IRCChannel;
|
@class IRCChannel;
|
||||||
|
|
||||||
|
#ifndef IRC_CONNECTION_M
|
||||||
|
@protocol IRCConnectionDelegate <OFObject>
|
||||||
|
#else
|
||||||
@protocol IRCConnectionDelegate
|
@protocol IRCConnectionDelegate
|
||||||
|
#endif
|
||||||
|
#ifdef OF_HAVE_OPTIONAL_PROTOCOLS
|
||||||
@optional
|
@optional
|
||||||
|
#endif
|
||||||
- (void)connection: (IRCConnection*)connection
|
- (void)connection: (IRCConnection*)connection
|
||||||
didReceiveLine: (OFString*)line;
|
didReceiveLine: (OFString*)line;
|
||||||
- (void)connection: (IRCConnection*)connection
|
- (void)connection: (IRCConnection*)connection
|
||||||
|
@ -80,15 +86,30 @@
|
||||||
uint16_t port;
|
uint16_t port;
|
||||||
OFString *nickname, *username, *realname;
|
OFString *nickname, *username, *realname;
|
||||||
OFMutableDictionary *channels;
|
OFMutableDictionary *channels;
|
||||||
id <IRCConnectionDelegate, OFObject> delegate;
|
id <IRCConnectionDelegate> delegate;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef OF_HAVE_PROPERTIES
|
||||||
@property (copy) OFString *server;
|
@property (copy) OFString *server;
|
||||||
@property (assign) uint16_t port;
|
@property (assign) uint16_t port;
|
||||||
@property (copy) OFString *nickname, *username, *realname;
|
@property (copy) OFString *nickname, *username, *realname;
|
||||||
@property (assign) id <IRCConnectionDelegate, OFObject> delegate;
|
@property (assign) id <IRCConnectionDelegate> delegate;
|
||||||
@property (retain, getter=socket) OFTCPSocket *sock;
|
@property (readonly, retain, getter=socket) OFTCPSocket *sock;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
- (void)setServer: (OFString*)server;
|
||||||
|
- (OFString*)server;
|
||||||
|
- (void)setPort: (uint16_t)port;
|
||||||
|
- (uint16_t)port;
|
||||||
|
- (void)setNickname: (OFString*)nickname;
|
||||||
|
- (OFString*)nickname;
|
||||||
|
- (void)setUsername: (OFString*)username;
|
||||||
|
- (OFString*)username;
|
||||||
|
- (void)setRealname: (OFString*)realname;
|
||||||
|
- (OFString*)realname;
|
||||||
|
- (void)setDelegate: (id <IRCConnectionDelegate>)delegate;
|
||||||
|
- (id <IRCConnectionDelegate>)delegate;
|
||||||
|
- (OFTCPSocket*)socket;
|
||||||
- (void)sendLine: (OFString*)line;
|
- (void)sendLine: (OFString*)line;
|
||||||
- (void)sendLineWithFormat: (OFConstantString*)line, ...;
|
- (void)sendLineWithFormat: (OFConstantString*)line, ...;
|
||||||
- (void)connect;
|
- (void)connect;
|
||||||
|
@ -113,3 +134,6 @@
|
||||||
- (void)processLine: (OFString*)line;
|
- (void)processLine: (OFString*)line;
|
||||||
- (void)handleConnection;
|
- (void)handleConnection;
|
||||||
@end
|
@end
|
||||||
|
|
||||||
|
@interface OFObject (IRCConnectionDelegate) <IRCConnectionDelegate>
|
||||||
|
@end
|
||||||
|
|
|
@ -20,6 +20,8 @@
|
||||||
* POSSIBILITY OF SUCH DAMAGE.
|
* POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#define IRC_CONNECTION_M
|
||||||
|
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
|
|
||||||
#import <ObjFW/OFString.h>
|
#import <ObjFW/OFString.h>
|
||||||
|
@ -37,8 +39,6 @@
|
||||||
#import "IRCChannel.h"
|
#import "IRCChannel.h"
|
||||||
|
|
||||||
@implementation IRCConnection
|
@implementation IRCConnection
|
||||||
@synthesize server, port, nickname, username, realname, delegate, sock;
|
|
||||||
|
|
||||||
- init
|
- init
|
||||||
{
|
{
|
||||||
self = [super init];
|
self = [super init];
|
||||||
|
@ -54,6 +54,71 @@
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (void)setServer: (OFString*)server_
|
||||||
|
{
|
||||||
|
OF_SETTER(server, server_, YES, YES)
|
||||||
|
}
|
||||||
|
|
||||||
|
- (OFString*)server
|
||||||
|
{
|
||||||
|
OF_GETTER(server, YES)
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)setPort: (uint16_t)port_
|
||||||
|
{
|
||||||
|
port = port_;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (uint16_t)port
|
||||||
|
{
|
||||||
|
return port;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)setNickname: (OFString*)nickname_
|
||||||
|
{
|
||||||
|
OF_SETTER(nickname, nickname_, YES, YES)
|
||||||
|
}
|
||||||
|
|
||||||
|
- (OFString*)nickname
|
||||||
|
{
|
||||||
|
OF_GETTER(nickname, YES)
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)setUsername: (OFString*)username_
|
||||||
|
{
|
||||||
|
OF_SETTER(username, username_, YES, YES)
|
||||||
|
}
|
||||||
|
|
||||||
|
- (OFString*)username
|
||||||
|
{
|
||||||
|
OF_GETTER(username, YES)
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)setRealname: (OFString*)realname_
|
||||||
|
{
|
||||||
|
OF_SETTER(realname, realname_, YES, YES)
|
||||||
|
}
|
||||||
|
|
||||||
|
- (OFString*)realname
|
||||||
|
{
|
||||||
|
OF_GETTER(realname, YES)
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)setDelegate: (id <IRCConnectionDelegate>)delegate_
|
||||||
|
{
|
||||||
|
delegate = delegate_;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (id <IRCConnectionDelegate>)delegate
|
||||||
|
{
|
||||||
|
return delegate;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (OFTCPSocket*)socket
|
||||||
|
{
|
||||||
|
OF_GETTER(sock, YES)
|
||||||
|
}
|
||||||
|
|
||||||
- (void)connect
|
- (void)connect
|
||||||
{
|
{
|
||||||
OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init];
|
OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init];
|
||||||
|
@ -96,18 +161,18 @@
|
||||||
withReason: (OFString*)reason
|
withReason: (OFString*)reason
|
||||||
{
|
{
|
||||||
if (reason == nil)
|
if (reason == nil)
|
||||||
[self sendLineWithFormat: @"PART %@", channel.name];
|
[self sendLineWithFormat: @"PART %@", [channel name]];
|
||||||
else
|
else
|
||||||
[self sendLineWithFormat: @"PART %@ :%@", channel.name, reason];
|
[self sendLineWithFormat: @"PART %@ :%@",
|
||||||
|
[channel name], reason];
|
||||||
|
|
||||||
[channels removeObjectForKey: channel.name];
|
[channels removeObjectForKey: [channel name]];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)sendLine: (OFString*)line
|
- (void)sendLine: (OFString*)line
|
||||||
{
|
{
|
||||||
if ([delegate respondsToSelector: @selector(connection:didSendLine:)])
|
[delegate connection: self
|
||||||
[delegate connection: self
|
didSendLine: line];
|
||||||
didSendLine: line];
|
|
||||||
|
|
||||||
[sock writeLine: line];
|
[sock writeLine: line];
|
||||||
}
|
}
|
||||||
|
@ -131,7 +196,7 @@
|
||||||
- (void)sendMessage: (OFString*)msg
|
- (void)sendMessage: (OFString*)msg
|
||||||
toChannel: (IRCChannel*)channel
|
toChannel: (IRCChannel*)channel
|
||||||
{
|
{
|
||||||
[self sendLineWithFormat: @"PRIVMSG %@ :%@", channel.name, msg];
|
[self sendLineWithFormat: @"PRIVMSG %@ :%@", [channel name], msg];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)sendMessage: (OFString*)msg
|
- (void)sendMessage: (OFString*)msg
|
||||||
|
@ -149,7 +214,7 @@
|
||||||
- (void)sendNotice: (OFString*)notice
|
- (void)sendNotice: (OFString*)notice
|
||||||
toChannel: (IRCChannel*)channel
|
toChannel: (IRCChannel*)channel
|
||||||
{
|
{
|
||||||
[self sendLineWithFormat: @"NOTICE %@ :%@", channel.name, notice];
|
[self sendLineWithFormat: @"NOTICE %@ :%@", [channel name], notice];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)kickUser: (OFString*)user
|
- (void)kickUser: (OFString*)user
|
||||||
|
@ -157,7 +222,7 @@
|
||||||
withReason: (OFString*)reason
|
withReason: (OFString*)reason
|
||||||
{
|
{
|
||||||
[self sendLineWithFormat: @"KICK %@ %@ :%@",
|
[self sendLineWithFormat: @"KICK %@ %@ :%@",
|
||||||
channel.name, user, reason];
|
[channel name], user, reason];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)changeNicknameTo: (OFString*)nickname_
|
- (void)changeNicknameTo: (OFString*)nickname_
|
||||||
|
@ -165,21 +230,19 @@
|
||||||
[self sendLineWithFormat: @"NICK %@", nickname_];
|
[self sendLineWithFormat: @"NICK %@", nickname_];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)processLine: (OFString*)line
|
- (void)IRC_processLine: (OFString*)line
|
||||||
{
|
{
|
||||||
OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init];
|
OFArray *components;
|
||||||
OFArray *split;
|
|
||||||
OFString *action = nil;
|
OFString *action = nil;
|
||||||
|
|
||||||
if ([delegate respondsToSelector:
|
[delegate connection: self
|
||||||
@selector(connection:didReceiveLine:)])
|
didReceiveLine: line];
|
||||||
[delegate connection: self
|
|
||||||
didReceiveLine: line];
|
|
||||||
|
|
||||||
split = [line componentsSeparatedByString: @" "];
|
components = [line componentsSeparatedByString: @" "];
|
||||||
|
|
||||||
/* PING */
|
/* PING */
|
||||||
if (split.count == 2 && [split.firstObject isEqual: @"PING"]) {
|
if ([components count] == 2 &&
|
||||||
|
[[components firstObject] isEqual: @"PING"]) {
|
||||||
OFMutableString *s = [[line mutableCopy] autorelease];
|
OFMutableString *s = [[line mutableCopy] autorelease];
|
||||||
[s replaceOccurrencesOfString: @"PING"
|
[s replaceOccurrencesOfString: @"PING"
|
||||||
withString: @"PONG"];
|
withString: @"PONG"];
|
||||||
|
@ -188,26 +251,22 @@
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
action = [[split objectAtIndex: 1] uppercaseString];
|
action = [[components objectAtIndex: 1] uppercaseString];
|
||||||
|
|
||||||
/* Connected */
|
/* Connected */
|
||||||
if ([action isEqual: @"001"] && split.count >= 4) {
|
if ([action isEqual: @"001"] && [components count] >= 4) {
|
||||||
if ([delegate respondsToSelector:
|
[delegate connectionWasEstablished: self];
|
||||||
@selector(connectionWasEstablished:)])
|
|
||||||
[delegate connectionWasEstablished: self];
|
|
||||||
|
|
||||||
[pool release];
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* JOIN */
|
/* JOIN */
|
||||||
if ([action isEqual: @"JOIN"] && split.count == 3) {
|
if ([action isEqual: @"JOIN"] && [components count] == 3) {
|
||||||
OFString *who = [split objectAtIndex: 0];
|
OFString *who = [components objectAtIndex: 0];
|
||||||
OFString *where = [split objectAtIndex: 2];
|
OFString *where = [components objectAtIndex: 2];
|
||||||
IRCUser *user;
|
IRCUser *user;
|
||||||
IRCChannel *channel;
|
IRCChannel *channel;
|
||||||
|
|
||||||
who = [who substringWithRange: of_range(1, who.length - 1)];
|
who = [who substringWithRange: of_range(1, [who length] - 1)];
|
||||||
user = [IRCUser IRCUserWithString: who];
|
user = [IRCUser IRCUserWithString: who];
|
||||||
|
|
||||||
if ([who hasPrefix: [nickname stringByAppendingString: @"!"]]) {
|
if ([who hasPrefix: [nickname stringByAppendingString: @"!"]]) {
|
||||||
|
@ -217,199 +276,190 @@
|
||||||
} else
|
} else
|
||||||
channel = [channels objectForKey: where];
|
channel = [channels objectForKey: where];
|
||||||
|
|
||||||
[channel IRC_addUser: user.nickname];
|
[channel IRC_addUser: [user nickname]];
|
||||||
|
|
||||||
if ([delegate respondsToSelector:
|
[delegate connection: self
|
||||||
@selector(connection:didSeeUser:joinChannel:)])
|
didSeeUser: user
|
||||||
[delegate connection: self
|
joinChannel: channel];
|
||||||
didSeeUser: user
|
|
||||||
joinChannel: channel];
|
|
||||||
|
|
||||||
[pool release];
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* NAMES reply */
|
/* NAMES reply */
|
||||||
if ([action isEqual: @"353"] && split.count >= 6) {
|
if ([action isEqual: @"353"] && [components count] >= 6) {
|
||||||
IRCChannel *channel;
|
IRCChannel *channel;
|
||||||
OFArray *users;
|
OFArray *users;
|
||||||
size_t pos;
|
size_t pos;
|
||||||
|
OFEnumerator *enumerator;
|
||||||
|
OFString *user;
|
||||||
|
|
||||||
channel = [channels objectForKey: [split objectAtIndex: 4]];
|
channel = [channels
|
||||||
|
objectForKey: [components objectAtIndex: 4]];
|
||||||
if (channel == nil) {
|
if (channel == nil) {
|
||||||
/* We did not request that */
|
/* We did not request that */
|
||||||
[pool release];
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
pos = [[split objectAtIndex: 0] length] +
|
pos = [[components objectAtIndex: 0] length] +
|
||||||
[[split objectAtIndex: 1] length] +
|
[[components objectAtIndex: 1] length] +
|
||||||
[[split objectAtIndex: 2] length] +
|
[[components objectAtIndex: 2] length] +
|
||||||
[[split objectAtIndex: 3] length] +
|
[[components objectAtIndex: 3] length] +
|
||||||
[[split objectAtIndex: 4] length] + 6;
|
[[components objectAtIndex: 4] length] + 6;
|
||||||
|
|
||||||
users = [[line substringWithRange:
|
users = [[line substringWithRange:
|
||||||
of_range(pos, line.length - pos)]
|
of_range(pos, [line length] - pos)]
|
||||||
componentsSeparatedByString: @" "];
|
componentsSeparatedByString: @" "];
|
||||||
|
|
||||||
for (OFString *user in users) {
|
enumerator = [users objectEnumerator];
|
||||||
|
while ((user = [enumerator nextObject]) != nil) {
|
||||||
if ([user hasPrefix: @"@"] || [user hasPrefix: @"+"] ||
|
if ([user hasPrefix: @"@"] || [user hasPrefix: @"+"] ||
|
||||||
[user hasPrefix: @"%"] || [user hasPrefix: @"*"])
|
[user hasPrefix: @"%"] || [user hasPrefix: @"*"])
|
||||||
user = [user substringWithRange:
|
user = [user substringWithRange:
|
||||||
of_range(1, user.length - 1)];
|
of_range(1, [user length] - 1)];
|
||||||
|
|
||||||
[channel IRC_addUser: user];
|
[channel IRC_addUser: user];
|
||||||
}
|
}
|
||||||
|
|
||||||
if ([delegate respondsToSelector: @selector(connection:
|
[delegate connection: self
|
||||||
didReceiveNamesForChannel:)])
|
didReceiveNamesForChannel: channel];
|
||||||
[delegate connection: self
|
|
||||||
didReceiveNamesForChannel: channel];
|
|
||||||
|
|
||||||
[pool release];
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* PART */
|
/* PART */
|
||||||
if ([action isEqual: @"PART"] && split.count >= 3) {
|
if ([action isEqual: @"PART"] && [components count] >= 3) {
|
||||||
OFString *who = [split objectAtIndex: 0];
|
OFString *who = [components objectAtIndex: 0];
|
||||||
OFString *where = [split objectAtIndex: 2];
|
OFString *where = [components objectAtIndex: 2];
|
||||||
IRCUser *user;
|
IRCUser *user;
|
||||||
IRCChannel *channel;
|
IRCChannel *channel;
|
||||||
OFString *reason = nil;
|
OFString *reason = nil;
|
||||||
size_t pos = who.length + 1 +
|
size_t pos = [who length] + 1 +
|
||||||
[[split objectAtIndex: 1] length] + 1 + where.length;
|
[[components objectAtIndex: 1] length] + 1 + [where length];
|
||||||
|
|
||||||
who = [who substringWithRange: of_range(1, who.length - 1)];
|
who = [who substringWithRange: of_range(1, [who length] - 1)];
|
||||||
user = [IRCUser IRCUserWithString: who];
|
user = [IRCUser IRCUserWithString: who];
|
||||||
channel = [channels objectForKey: where];
|
channel = [channels objectForKey: where];
|
||||||
|
|
||||||
if (split.count > 3)
|
if ([components count] > 3)
|
||||||
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];
|
[channel IRC_removeUser: [user nickname]];
|
||||||
|
|
||||||
if ([delegate respondsToSelector:
|
[delegate connection: self
|
||||||
@selector(connection:didSeeUser:leaveChannel:
|
didSeeUser: user
|
||||||
withReason:)])
|
leaveChannel: channel
|
||||||
[delegate connection: self
|
withReason: reason];
|
||||||
didSeeUser: user
|
|
||||||
leaveChannel: channel
|
|
||||||
withReason: reason];
|
|
||||||
|
|
||||||
[pool release];
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* KICK */
|
/* KICK */
|
||||||
if ([action isEqual: @"KICK"] && split.count >= 4) {
|
if ([action isEqual: @"KICK"] && [components count] >= 4) {
|
||||||
OFString *who = [split objectAtIndex: 0];
|
OFString *who = [components objectAtIndex: 0];
|
||||||
OFString *where = [split objectAtIndex: 2];
|
OFString *where = [components objectAtIndex: 2];
|
||||||
OFString *whom = [split objectAtIndex: 3];
|
OFString *whom = [components objectAtIndex: 3];
|
||||||
IRCUser *user;
|
IRCUser *user;
|
||||||
IRCChannel *channel;
|
IRCChannel *channel;
|
||||||
OFString *reason = nil;
|
OFString *reason = nil;
|
||||||
size_t pos = who.length + 1 +
|
size_t pos = [who length] + 1 +
|
||||||
[[split objectAtIndex: 1] length] + 1 + where.length + 1 +
|
[[components objectAtIndex: 1] length] + 1 +
|
||||||
whom.length;
|
[where length] + 1 + [whom length];
|
||||||
|
|
||||||
who = [who substringWithRange: of_range(1, who.length - 1)];
|
who = [who substringWithRange: of_range(1, [who length] - 1)];
|
||||||
user = [IRCUser IRCUserWithString: who];
|
user = [IRCUser IRCUserWithString: who];
|
||||||
channel = [channels objectForKey: where];
|
channel = [channels objectForKey: where];
|
||||||
|
|
||||||
if (split.count > 4)
|
if ([components count] > 4)
|
||||||
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];
|
[channel IRC_removeUser: [user nickname]];
|
||||||
|
|
||||||
if ([delegate respondsToSelector:
|
[delegate connection: self
|
||||||
@selector(connection:didSeeUser:kickUser:
|
didSeeUser: user
|
||||||
fromChannel:withReason:)])
|
kickUser: whom
|
||||||
[delegate connection: self
|
fromChannel: channel
|
||||||
didSeeUser: user
|
withReason: reason];
|
||||||
kickUser: whom
|
|
||||||
fromChannel: channel
|
|
||||||
withReason: reason];
|
|
||||||
|
|
||||||
[pool release];
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* QUIT */
|
/* QUIT */
|
||||||
if ([action isEqual: @"QUIT"] && split.count >= 2) {
|
if ([action isEqual: @"QUIT"] && [components count] >= 2) {
|
||||||
OFString *who = [split objectAtIndex: 0];
|
OFString *who = [components objectAtIndex: 0];
|
||||||
IRCUser *user;
|
IRCUser *user;
|
||||||
OFString *reason = nil;
|
OFString *reason = nil;
|
||||||
size_t pos = who.length + 1 + [[split objectAtIndex: 1] length];
|
size_t pos = [who length] + 1 +
|
||||||
|
[[components objectAtIndex: 1] length];
|
||||||
|
OFEnumerator *enumerator;
|
||||||
|
IRCChannel *channel;
|
||||||
|
|
||||||
who = [who substringWithRange: of_range(1, who.length - 1)];
|
who = [who substringWithRange: of_range(1, [who length] - 1)];
|
||||||
user = [IRCUser IRCUserWithString: who];
|
user = [IRCUser IRCUserWithString: who];
|
||||||
|
|
||||||
if (split.count > 2)
|
if ([components count] > 2)
|
||||||
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)
|
enumerator = [channels keyEnumerator];
|
||||||
[channel IRC_removeUser: user.nickname];
|
while ((channel = [enumerator nextObject]) != nil)
|
||||||
|
[channel IRC_removeUser: [user nickname]];
|
||||||
|
|
||||||
if ([delegate respondsToSelector:
|
[delegate connection: self
|
||||||
@selector(connection:didSeeUserQuit:withReason:)])
|
didSeeUserQuit: user
|
||||||
[delegate connection: self
|
withReason: reason];
|
||||||
didSeeUserQuit: user
|
|
||||||
withReason: reason];
|
|
||||||
|
|
||||||
[pool release];
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* NICK */
|
/* NICK */
|
||||||
if ([action isEqual: @"NICK"] && split.count == 3) {
|
if ([action isEqual: @"NICK"] && [components count] == 3) {
|
||||||
OFString *who = [split objectAtIndex: 0];
|
OFString *who = [components objectAtIndex: 0];
|
||||||
OFString *newNickname = [split objectAtIndex: 2];
|
OFString *newNickname = [components objectAtIndex: 2];
|
||||||
IRCUser *user;
|
IRCUser *user;
|
||||||
|
OFEnumerator *enumerator;
|
||||||
|
IRCChannel *channel;
|
||||||
|
|
||||||
who = [who substringWithRange: of_range(1, who.length - 1)];
|
who = [who substringWithRange: of_range(1, [who length] - 1)];
|
||||||
newNickname = [newNickname substringWithRange:
|
newNickname = [newNickname substringWithRange:
|
||||||
of_range(1, newNickname.length - 1)];
|
of_range(1, [newNickname length] - 1)];
|
||||||
|
|
||||||
user = [IRCUser IRCUserWithString: who];
|
user = [IRCUser IRCUserWithString: who];
|
||||||
|
|
||||||
if ([user.nickname isEqual: nickname]) {
|
if ([[user nickname] isEqual: nickname]) {
|
||||||
[nickname release];
|
[nickname release];
|
||||||
nickname = [user.nickname copy];
|
nickname = [[user nickname] copy];
|
||||||
}
|
}
|
||||||
|
|
||||||
for (IRCChannel *channel in channels) {
|
enumerator = [channels keyEnumerator];
|
||||||
if ([channel.users containsObject: user.nickname]) {
|
while ((channel = [enumerator nextObject]) != nil) {
|
||||||
[channel IRC_removeUser: user.nickname];
|
if ([[channel users] containsObject: [user nickname]]) {
|
||||||
|
[channel IRC_removeUser: [user nickname]];
|
||||||
[channel IRC_addUser: newNickname];
|
[channel IRC_addUser: newNickname];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ([delegate respondsToSelector:
|
[delegate connection: self
|
||||||
@selector(connection:didSeeUser:changeNicknameTo:)])
|
didSeeUser: user
|
||||||
[delegate connection: self
|
changeNicknameTo: newNickname];
|
||||||
didSeeUser: user
|
|
||||||
changeNicknameTo: newNickname];
|
|
||||||
|
|
||||||
[pool release];
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* PRIVMSG */
|
/* PRIVMSG */
|
||||||
if ([action isEqual: @"PRIVMSG"] && split.count >= 4) {
|
if ([action isEqual: @"PRIVMSG"] && [components count] >= 4) {
|
||||||
OFString *from = [split objectAtIndex: 0];
|
OFString *from = [components objectAtIndex: 0];
|
||||||
OFString *to = [split objectAtIndex: 2];
|
OFString *to = [components objectAtIndex: 2];
|
||||||
IRCUser *user;
|
IRCUser *user;
|
||||||
OFString *msg;
|
OFString *msg;
|
||||||
size_t pos = from.length + 1 +
|
size_t pos = [from length] + 1 +
|
||||||
[[split objectAtIndex: 1] length] + 1 + to.length;
|
[[components objectAtIndex: 1] length] + 1 + [to length];
|
||||||
|
|
||||||
from = [from substringWithRange: of_range(1, from.length - 1)];
|
from = [from substringWithRange:
|
||||||
|
of_range(1, [from length] - 1)];
|
||||||
msg = [line substringWithRange:
|
msg = [line substringWithRange:
|
||||||
of_range(pos + 2, line.length - pos - 2)];
|
of_range(pos + 2, [line length] - pos - 2)];
|
||||||
user = [IRCUser IRCUserWithString: from];
|
user = [IRCUser IRCUserWithString: from];
|
||||||
|
|
||||||
if (![to isEqual: nickname]) {
|
if (![to isEqual: nickname]) {
|
||||||
|
@ -417,43 +467,34 @@
|
||||||
|
|
||||||
channel = [channels objectForKey: to];
|
channel = [channels objectForKey: to];
|
||||||
|
|
||||||
if ([delegate respondsToSelector:
|
[delegate connection: self
|
||||||
@selector(connection:didReceiveMessage:
|
didReceiveMessage: msg
|
||||||
fromUser:inChannel:)])
|
fromUser: user
|
||||||
[delegate connection: self
|
inChannel: channel];
|
||||||
didReceiveMessage: msg
|
} else
|
||||||
fromUser: user
|
[delegate connection: self
|
||||||
inChannel: channel];
|
didReceivePrivateMessage: msg
|
||||||
} else {
|
fromUser: user];
|
||||||
if ([delegate respondsToSelector:
|
|
||||||
@selector(connection:
|
|
||||||
didReceivePrivateMessage:fromUser:)])
|
|
||||||
[delegate
|
|
||||||
connection: self
|
|
||||||
didReceivePrivateMessage: msg
|
|
||||||
fromUser: user];
|
|
||||||
}
|
|
||||||
|
|
||||||
[pool release];
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* NOTICE */
|
/* NOTICE */
|
||||||
if ([action isEqual: @"NOTICE"] && split.count >= 4) {
|
if ([action isEqual: @"NOTICE"] && [components count] >= 4) {
|
||||||
OFString *from = [split objectAtIndex: 0];
|
OFString *from = [components objectAtIndex: 0];
|
||||||
OFString *to = [split objectAtIndex: 2];
|
OFString *to = [components objectAtIndex: 2];
|
||||||
IRCUser *user = nil;
|
IRCUser *user = nil;
|
||||||
OFString *notice;
|
OFString *notice;
|
||||||
size_t pos = from.length + 1 +
|
size_t pos = [from length] + 1 +
|
||||||
[[split objectAtIndex: 1] length] + 1 + to.length;
|
[[components objectAtIndex: 1] length] + 1 + [to length];
|
||||||
|
|
||||||
from = [from substringWithRange: of_range(1, from.length - 1)];
|
from = [from substringWithRange:
|
||||||
|
of_range(1, [from length] - 1)];
|
||||||
notice = [line substringWithRange:
|
notice = [line substringWithRange:
|
||||||
of_range(pos + 2, line.length - pos - 2)];
|
of_range(pos + 2, [line length] - pos - 2)];
|
||||||
|
|
||||||
if (![from containsString: @"!"] || [to isEqual: @"*"]) {
|
if (![from containsString: @"!"] || [to isEqual: @"*"]) {
|
||||||
/* System message - ignore for now */
|
/* System message - ignore for now */
|
||||||
[pool release];
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -464,34 +505,35 @@
|
||||||
|
|
||||||
channel = [channels objectForKey: to];
|
channel = [channels objectForKey: to];
|
||||||
|
|
||||||
if ([delegate respondsToSelector:
|
[delegate connection: self
|
||||||
@selector(connection:didReceiveNotice:
|
didReceiveNotice: notice
|
||||||
fromUser:inChannel:)])
|
fromUser: user
|
||||||
[delegate connection: self
|
inChannel: channel];
|
||||||
didReceiveNotice: notice
|
} else
|
||||||
fromUser: user
|
[delegate connection: self
|
||||||
inChannel: channel];
|
didReceiveNotice: notice
|
||||||
} else {
|
fromUser: user];
|
||||||
if ([delegate respondsToSelector:
|
|
||||||
@selector(connection:didReceiveNotice:
|
|
||||||
fromUser:)])
|
|
||||||
[delegate connection: self
|
|
||||||
didReceiveNotice: notice
|
|
||||||
fromUser: user];
|
|
||||||
}
|
|
||||||
|
|
||||||
[pool release];
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (void)processLine: (OFString*)line
|
||||||
|
{
|
||||||
|
OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init];
|
||||||
|
|
||||||
|
[self IRC_processLine: line];
|
||||||
|
|
||||||
|
[pool release];
|
||||||
|
}
|
||||||
|
|
||||||
- (BOOL)connection: (OFTCPSocket*)connection
|
- (BOOL)connection: (OFTCPSocket*)connection
|
||||||
didReceiveISO88591Line: (OFString*)line
|
didReceiveISO88591Line: (OFString*)line
|
||||||
context: (id)context
|
context: (id)context
|
||||||
exception: (OFException*)exception
|
exception: (OFException*)exception
|
||||||
{
|
{
|
||||||
if (line != nil) {
|
if (line != nil) {
|
||||||
[self processLine: line];
|
[self IRC_processLine: line];
|
||||||
[sock asyncReadLineWithTarget: self
|
[sock asyncReadLineWithTarget: self
|
||||||
selector: @selector(connection:
|
selector: @selector(connection:
|
||||||
didReceiveLine:context:
|
didReceiveLine:context:
|
||||||
|
@ -508,7 +550,7 @@
|
||||||
exception: (OFException*)exception
|
exception: (OFException*)exception
|
||||||
{
|
{
|
||||||
if (line != nil) {
|
if (line != nil) {
|
||||||
[self processLine: line];
|
[self IRC_processLine: line];
|
||||||
return YES;
|
return YES;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -543,3 +585,87 @@
|
||||||
[super dealloc];
|
[super dealloc];
|
||||||
}
|
}
|
||||||
@end
|
@end
|
||||||
|
|
||||||
|
@implementation OFObject (IRCConnectionDelegate)
|
||||||
|
- (void)connection: (IRCConnection*)connection
|
||||||
|
didReceiveLine: (OFString*)line
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)connection: (IRCConnection*)connection
|
||||||
|
didSendLine: (OFString*)line
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)connectionWasEstablished: (IRCConnection*)connection
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)connection: (IRCConnection*)connection
|
||||||
|
didSeeUser: (IRCUser*)user
|
||||||
|
joinChannel: (IRCChannel*)channel
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)connection: (IRCConnection*)connection
|
||||||
|
didSeeUser: (IRCUser*)user
|
||||||
|
leaveChannel: (IRCChannel*)channel
|
||||||
|
withReason: (OFString*)reason
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)connection: (IRCConnection*)connection
|
||||||
|
didSeeUser: (IRCUser*)user
|
||||||
|
changeNicknameTo: (OFString*)nickname
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)connection: (IRCConnection*)connection
|
||||||
|
didSeeUser: (IRCUser*)user
|
||||||
|
kickUser: (OFString*)kickedUser
|
||||||
|
fromChannel: (IRCChannel*)channel
|
||||||
|
withReason: (OFString*)reason
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)connection: (IRCConnection*)connection
|
||||||
|
didSeeUserQuit: (IRCUser*)user
|
||||||
|
withReason: (OFString*)reason
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)connection: (IRCConnection*)connection
|
||||||
|
didReceiveMessage: (OFString*)msg
|
||||||
|
fromUser: (IRCUser*)user
|
||||||
|
inChannel: (IRCChannel*)channel
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)connection: (IRCConnection*)connection
|
||||||
|
didReceivePrivateMessage: (OFString*)msg
|
||||||
|
fromUser: (IRCUser*)user
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)connection: (IRCConnection*)connection
|
||||||
|
didReceiveNotice: (OFString*)notice
|
||||||
|
fromUser: (IRCUser*)user
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)connection: (IRCConnection*)connection
|
||||||
|
didReceiveNotice: (OFString*)notice
|
||||||
|
fromUser: (IRCUser*)user
|
||||||
|
inChannel: (IRCChannel*)channel
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)connection: (IRCConnection*)connection
|
||||||
|
didReceiveNamesForChannel: (IRCChannel*)channel
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)connectionWasClosed: (IRCConnection*)connection
|
||||||
|
{
|
||||||
|
}
|
||||||
|
@end
|
||||||
|
|
|
@ -29,8 +29,13 @@
|
||||||
OFString *hostname;
|
OFString *hostname;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef OF_HAVE_PROPERTIES
|
||||||
@property (copy, readonly) OFString *nickname, *username, *hostname;
|
@property (copy, readonly) OFString *nickname, *username, *hostname;
|
||||||
|
#endif
|
||||||
|
|
||||||
+ IRCUserWithString: (OFString*)string;
|
+ IRCUserWithString: (OFString*)string;
|
||||||
- initWithString: (OFString*)string;
|
- initWithString: (OFString*)string;
|
||||||
|
- (OFString*)nickname;
|
||||||
|
- (OFString*)username;
|
||||||
|
- (OFString*)hostname;
|
||||||
@end
|
@end
|
||||||
|
|
|
@ -28,10 +28,11 @@
|
||||||
#import <ObjFW/OFInvalidFormatException.h>
|
#import <ObjFW/OFInvalidFormatException.h>
|
||||||
#import <ObjFW/OFOutOfMemoryException.h>
|
#import <ObjFW/OFOutOfMemoryException.h>
|
||||||
|
|
||||||
|
#import <ObjFW/macros.h>
|
||||||
|
|
||||||
#import "IRCUser.h"
|
#import "IRCUser.h"
|
||||||
|
|
||||||
@implementation IRCUser
|
@implementation IRCUser
|
||||||
@synthesize username, nickname, hostname;
|
|
||||||
+ IRCUserWithString: (OFString*)string
|
+ IRCUserWithString: (OFString*)string
|
||||||
{
|
{
|
||||||
return [[[self alloc] initWithString: string] autorelease];
|
return [[[self alloc] initWithString: string] autorelease];
|
||||||
|
@ -48,19 +49,19 @@
|
||||||
|
|
||||||
if ((tmp2 = strdup([string UTF8String])) == NULL)
|
if ((tmp2 = strdup([string UTF8String])) == NULL)
|
||||||
@throw [OFOutOfMemoryException
|
@throw [OFOutOfMemoryException
|
||||||
exceptionWithClass: isa
|
exceptionWithClass: [self class]
|
||||||
requestedSize: [string UTF8StringLength]];
|
requestedSize: [string UTF8StringLength]];
|
||||||
|
|
||||||
if ((tmp = strchr(tmp2, '@')) == NULL)
|
if ((tmp = strchr(tmp2, '@')) == NULL)
|
||||||
@throw [OFInvalidFormatException
|
@throw [OFInvalidFormatException
|
||||||
exceptionWithClass: isa];
|
exceptionWithClass: [self class]];
|
||||||
|
|
||||||
*tmp = '\0';
|
*tmp = '\0';
|
||||||
hostname = [[OFString alloc] initWithUTF8String: tmp + 1];
|
hostname = [[OFString alloc] initWithUTF8String: tmp + 1];
|
||||||
|
|
||||||
if ((tmp = strchr(tmp2, '!')) == NULL)
|
if ((tmp = strchr(tmp2, '!')) == NULL)
|
||||||
@throw [OFInvalidFormatException
|
@throw [OFInvalidFormatException
|
||||||
exceptionWithClass: isa];
|
exceptionWithClass: [self class]];
|
||||||
|
|
||||||
*tmp = '\0';
|
*tmp = '\0';
|
||||||
username = [[OFString alloc] initWithUTF8String: tmp + 1];
|
username = [[OFString alloc] initWithUTF8String: tmp + 1];
|
||||||
|
@ -86,6 +87,21 @@
|
||||||
[super dealloc];
|
[super dealloc];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (OFString*)username
|
||||||
|
{
|
||||||
|
OF_GETTER(username, YES)
|
||||||
|
}
|
||||||
|
|
||||||
|
- (OFString*)nickname
|
||||||
|
{
|
||||||
|
OF_GETTER(nickname, YES)
|
||||||
|
}
|
||||||
|
|
||||||
|
- (OFString*)hostname
|
||||||
|
{
|
||||||
|
OF_GETTER(hostname, YES)
|
||||||
|
}
|
||||||
|
|
||||||
- copy
|
- copy
|
||||||
{
|
{
|
||||||
return [self retain];
|
return [self retain];
|
||||||
|
|
14
tests/test.m
14
tests/test.m
|
@ -28,7 +28,7 @@
|
||||||
#import "IRCUser.h"
|
#import "IRCUser.h"
|
||||||
#import "IRCChannel.h"
|
#import "IRCChannel.h"
|
||||||
|
|
||||||
@interface TestApp: OFObject <OFApplicationDelegate, IRCConnectionDelegate>
|
@interface TestApp: OFObject
|
||||||
@end
|
@end
|
||||||
|
|
||||||
OF_APPLICATION_DELEGATE(TestApp)
|
OF_APPLICATION_DELEGATE(TestApp)
|
||||||
|
@ -38,11 +38,11 @@ OF_APPLICATION_DELEGATE(TestApp)
|
||||||
{
|
{
|
||||||
IRCConnection *connection = [[IRCConnection alloc] init];
|
IRCConnection *connection = [[IRCConnection alloc] init];
|
||||||
|
|
||||||
connection.server = @"irc.freenode.net";
|
[connection setServer: @"irc.freenode.net"];
|
||||||
connection.nickname = @"ObjIRC";
|
[connection setNickname: @"ObjIRC"];
|
||||||
connection.username = @"ObjIRC";
|
[connection setUsername: @"ObjIRC"];
|
||||||
connection.realname = @"ObjIRC";
|
[connection setRealname: @"ObjIRC"];
|
||||||
connection.delegate = self;
|
[connection setDelegate: self];
|
||||||
|
|
||||||
[connection connect];
|
[connection connect];
|
||||||
[connection handleConnection];
|
[connection handleConnection];
|
||||||
|
@ -136,6 +136,6 @@ OF_APPLICATION_DELEGATE(TestApp)
|
||||||
- (void)connection: (IRCConnection*)connection
|
- (void)connection: (IRCConnection*)connection
|
||||||
didReceiveNamesForChannel: (IRCChannel*)channel
|
didReceiveNamesForChannel: (IRCChannel*)channel
|
||||||
{
|
{
|
||||||
of_log(@"Users in %@: %@", channel, channel.users);
|
of_log(@"Users in %@: %@", channel, [channel users]);
|
||||||
}
|
}
|
||||||
@end
|
@end
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue