Make non-blocking processing possible.
FossilOrigin-Name: 8b4878957125416dad0f0a91a2b64ae63c8284e39286e70eb7ae15086ef90307
This commit is contained in:
parent
a8b7db8d28
commit
8057b5df61
2 changed files with 275 additions and 275 deletions
|
@ -107,5 +107,6 @@
|
|||
fromChannel: (IRCChannel*)channel
|
||||
withReason: (OFString*)reason;
|
||||
- (void)changeNicknameTo: (OFString*)nickname;
|
||||
- (void)process;
|
||||
- (void)handleConnection;
|
||||
@end
|
||||
|
|
|
@ -163,288 +163,287 @@
|
|||
[self sendLineWithFormat: @"NICK %@", nickname_];
|
||||
}
|
||||
|
||||
- (void)handleConnection
|
||||
- (void)process
|
||||
{
|
||||
OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init];
|
||||
OFString *line;
|
||||
OFArray *split;
|
||||
OFString *action = nil;
|
||||
|
||||
for (;;) {
|
||||
OFString *action = nil;
|
||||
|
||||
@try {
|
||||
line = [sock readLine];
|
||||
} @catch (OFInvalidEncodingException *e) {
|
||||
[e dealloc];
|
||||
line = [sock readLineWithEncoding:
|
||||
OF_STRING_ENCODING_WINDOWS_1252];
|
||||
}
|
||||
|
||||
if (line == nil)
|
||||
break;
|
||||
|
||||
if ([delegate respondsToSelector:
|
||||
@selector(connection:didReceiveLine:)])
|
||||
[delegate connection: self
|
||||
didReceiveLine: line];
|
||||
|
||||
split = [line componentsSeparatedByString: @" "];
|
||||
|
||||
/* PING */
|
||||
if (split.count == 2 && [split.firstObject isEqual: @"PING"]) {
|
||||
OFMutableString *s = [[line mutableCopy] autorelease];
|
||||
[s replaceOccurrencesOfString: @"PING"
|
||||
withString: @"PONG"];
|
||||
[self sendLine: s];
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
action = [[split objectAtIndex: 1] uppercaseString];
|
||||
|
||||
/* Connected */
|
||||
if ([action isEqual: @"001"] && split.count >= 4) {
|
||||
if ([delegate respondsToSelector:
|
||||
@selector(connectionWasEstablished:)])
|
||||
[delegate connectionWasEstablished: self];
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
/* JOIN */
|
||||
if ([action isEqual: @"JOIN"] && split.count == 3) {
|
||||
OFString *who = [split objectAtIndex: 0];
|
||||
OFString *where = [split objectAtIndex: 2];
|
||||
IRCUser *user;
|
||||
IRCChannel *channel;
|
||||
|
||||
who = [who substringWithRange:
|
||||
of_range(1, who.length - 1)];
|
||||
where = [where substringWithRange:
|
||||
of_range(1, where.length - 1)];
|
||||
user = [IRCUser IRCUserWithString: who];
|
||||
|
||||
if ([who hasPrefix:
|
||||
[nickname stringByAppendingString: @"!"]]) {
|
||||
channel = [IRCChannel channelWithName: where];
|
||||
[channels setObject: channel
|
||||
forKey: where];
|
||||
} else
|
||||
channel = [channels objectForKey: where];
|
||||
|
||||
if ([delegate respondsToSelector:
|
||||
@selector(connection:didSeeUser:joinChannel:)])
|
||||
[delegate connection: self
|
||||
didSeeUser: user
|
||||
joinChannel: channel];
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
/* PART */
|
||||
if ([action isEqual: @"PART"] && split.count >= 3) {
|
||||
OFString *who = [split objectAtIndex: 0];
|
||||
OFString *where = [split objectAtIndex: 2];
|
||||
IRCUser *user;
|
||||
IRCChannel *channel;
|
||||
OFString *reason = nil;
|
||||
size_t pos = who.length + 1 +
|
||||
[[split objectAtIndex: 1] length] + 1 +
|
||||
where.length;
|
||||
|
||||
who = [who substringWithRange:
|
||||
of_range(1, who.length - 1)];
|
||||
user = [IRCUser IRCUserWithString: who];
|
||||
channel = [channels objectForKey: where];
|
||||
|
||||
if (split.count > 3)
|
||||
reason = [line substringWithRange:
|
||||
of_range(pos + 2, line.length - pos - 2)];
|
||||
|
||||
if ([delegate respondsToSelector:
|
||||
@selector(connection:didSeeUser:leaveChannel:
|
||||
withReason:)])
|
||||
[delegate connection: self
|
||||
didSeeUser: user
|
||||
leaveChannel: channel
|
||||
withReason: reason];
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
/* KICK */
|
||||
if ([action isEqual: @"KICK"] && split.count >= 4) {
|
||||
OFString *who = [split objectAtIndex: 0];
|
||||
OFString *where = [split objectAtIndex: 2];
|
||||
OFString *whom = [split objectAtIndex: 3];
|
||||
IRCUser *user;
|
||||
IRCChannel *channel;
|
||||
OFString *reason = nil;
|
||||
size_t pos = who.length + 1 +
|
||||
[[split objectAtIndex: 1] length] + 1 +
|
||||
where.length + 1 + whom.length;
|
||||
|
||||
who = [who substringWithRange:
|
||||
of_range(1, who.length - 1)];
|
||||
user = [IRCUser IRCUserWithString: who];
|
||||
channel = [channels objectForKey: where];
|
||||
|
||||
if (split.count > 4)
|
||||
reason = [line substringWithRange:
|
||||
of_range(pos + 2, line.length - pos - 2)];
|
||||
|
||||
if ([delegate respondsToSelector:
|
||||
@selector(connection:didSeeUser:kickUser:
|
||||
fromChannel:withReason:)])
|
||||
[delegate connection: self
|
||||
didSeeUser: user
|
||||
kickUser: whom
|
||||
fromChannel: channel
|
||||
withReason: reason];
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
/* QUIT */
|
||||
if ([action isEqual: @"QUIT"] && split.count >= 2) {
|
||||
OFString *who = [split objectAtIndex: 0];
|
||||
IRCUser *user;
|
||||
OFString *reason = nil;
|
||||
size_t pos = who.length + 1 +
|
||||
[[split objectAtIndex: 1] length];
|
||||
|
||||
who = [who substringWithRange:
|
||||
of_range(1, who.length - 1)];
|
||||
user = [IRCUser IRCUserWithString: who];
|
||||
|
||||
if (split.count > 2)
|
||||
reason = [line substringWithRange:
|
||||
of_range(pos + 2, line.length - pos - 2)];
|
||||
|
||||
if ([delegate respondsToSelector:
|
||||
@selector(connection:didSeeUserQuit:withReason:)])
|
||||
[delegate connection: self
|
||||
didSeeUserQuit: user
|
||||
withReason: reason];
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
/* NICK */
|
||||
if ([action isEqual: @"NICK"] && split.count == 3) {
|
||||
OFString *who = [split objectAtIndex: 0];
|
||||
OFString *newNickname = [split objectAtIndex: 2];
|
||||
IRCUser *user;
|
||||
|
||||
who = [who substringWithRange:
|
||||
of_range(1, who.length - 1)];
|
||||
newNickname = [newNickname substringWithRange:
|
||||
of_range(1, newNickname.length - 1)];
|
||||
|
||||
user = [IRCUser IRCUserWithString: who];
|
||||
|
||||
if ([user.nickname isEqual: nickname]) {
|
||||
[nickname release];
|
||||
nickname = [user.nickname copy];
|
||||
}
|
||||
|
||||
if ([delegate respondsToSelector:
|
||||
@selector(connection:didSeeUser:changeNicknameTo:)])
|
||||
[delegate connection: self
|
||||
didSeeUser: user
|
||||
changeNicknameTo: newNickname];
|
||||
}
|
||||
|
||||
/* PRIVMSG */
|
||||
if ([action isEqual: @"PRIVMSG"] && split.count >= 4) {
|
||||
OFString *from = [split objectAtIndex: 0];
|
||||
OFString *to = [split objectAtIndex: 2];
|
||||
IRCUser *user;
|
||||
OFString *msg;
|
||||
size_t pos = from.length + 1 +
|
||||
[[split objectAtIndex: 1] length] + 1 +
|
||||
to.length;
|
||||
|
||||
from = [from substringWithRange:
|
||||
of_range(1, from.length - 1)];
|
||||
msg = [line substringWithRange:
|
||||
of_range(pos + 2, line.length - pos - 2)];
|
||||
user = [IRCUser IRCUserWithString: from];
|
||||
|
||||
if (![to isEqual: nickname]) {
|
||||
IRCChannel *channel;
|
||||
|
||||
channel = [channels objectForKey: to];
|
||||
|
||||
if ([delegate respondsToSelector:
|
||||
@selector(connection:didReceiveMessage:
|
||||
fromUser:inChannel:)])
|
||||
[delegate connection: self
|
||||
didReceiveMessage: msg
|
||||
fromUser: user
|
||||
inChannel: channel];
|
||||
} else {
|
||||
if ([delegate respondsToSelector:
|
||||
@selector(connection:
|
||||
didReceivePrivateMessage:fromUser:)])
|
||||
[delegate
|
||||
connection: self
|
||||
didReceivePrivateMessage: msg
|
||||
fromUser: user];
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
/* NOTICE */
|
||||
if ([action isEqual: @"NOTICE"] && split.count >= 4) {
|
||||
OFString *from = [split objectAtIndex: 0];
|
||||
OFString *to = [split objectAtIndex: 2];
|
||||
IRCUser *user = nil;
|
||||
OFString *notice;
|
||||
size_t pos = from.length + 1 +
|
||||
[[split objectAtIndex: 1] length] + 1 +
|
||||
to.length;
|
||||
|
||||
from = [from substringWithRange:
|
||||
of_range(1, from.length - 1)];
|
||||
notice = [line substringWithRange:
|
||||
of_range(pos + 2, line.length - pos - 2)];
|
||||
|
||||
if (![from containsString: @"!"] || [to isEqual: @"*"])
|
||||
/* System message - ignore for now */
|
||||
continue;
|
||||
|
||||
user = [IRCUser IRCUserWithString: from];
|
||||
|
||||
if (![to isEqual: nickname]) {
|
||||
IRCChannel *channel;
|
||||
|
||||
channel = [channels objectForKey: to];
|
||||
|
||||
if ([delegate respondsToSelector:
|
||||
@selector(connection:didReceiveNotice:
|
||||
fromUser:inChannel:)])
|
||||
[delegate connection: self
|
||||
didReceiveNotice: notice
|
||||
fromUser: user
|
||||
inChannel: channel];
|
||||
} else {
|
||||
if ([delegate respondsToSelector:
|
||||
@selector(connection:didReceiveNotice:
|
||||
fromUser:)])
|
||||
[delegate connection: self
|
||||
didReceiveNotice: notice
|
||||
fromUser: user];
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
[pool releaseObjects];
|
||||
@try {
|
||||
line = [sock tryReadLine];
|
||||
} @catch (OFInvalidEncodingException *e) {
|
||||
[e dealloc];
|
||||
line = [sock tryReadLineWithEncoding:
|
||||
OF_STRING_ENCODING_WINDOWS_1252];
|
||||
}
|
||||
|
||||
[pool release];
|
||||
if (line == nil)
|
||||
return;
|
||||
|
||||
if ([delegate respondsToSelector:
|
||||
@selector(connection:didReceiveLine:)])
|
||||
[delegate connection: self
|
||||
didReceiveLine: line];
|
||||
|
||||
split = [line componentsSeparatedByString: @" "];
|
||||
|
||||
/* PING */
|
||||
if (split.count == 2 && [split.firstObject isEqual: @"PING"]) {
|
||||
OFMutableString *s = [[line mutableCopy] autorelease];
|
||||
[s replaceOccurrencesOfString: @"PING"
|
||||
withString: @"PONG"];
|
||||
[self sendLine: s];
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
action = [[split objectAtIndex: 1] uppercaseString];
|
||||
|
||||
/* Connected */
|
||||
if ([action isEqual: @"001"] && split.count >= 4) {
|
||||
if ([delegate respondsToSelector:
|
||||
@selector(connectionWasEstablished:)])
|
||||
[delegate connectionWasEstablished: self];
|
||||
|
||||
[pool release];
|
||||
return;
|
||||
}
|
||||
|
||||
/* JOIN */
|
||||
if ([action isEqual: @"JOIN"] && split.count == 3) {
|
||||
OFString *who = [split objectAtIndex: 0];
|
||||
OFString *where = [split objectAtIndex: 2];
|
||||
IRCUser *user;
|
||||
IRCChannel *channel;
|
||||
|
||||
who = [who substringWithRange: of_range(1, who.length - 1)];
|
||||
where = [where substringWithRange:
|
||||
of_range(1, where.length - 1)];
|
||||
user = [IRCUser IRCUserWithString: who];
|
||||
|
||||
if ([who hasPrefix: [nickname stringByAppendingString: @"!"]]) {
|
||||
channel = [IRCChannel channelWithName: where];
|
||||
[channels setObject: channel
|
||||
forKey: where];
|
||||
} else
|
||||
channel = [channels objectForKey: where];
|
||||
|
||||
if ([delegate respondsToSelector:
|
||||
@selector(connection:didSeeUser:joinChannel:)])
|
||||
[delegate connection: self
|
||||
didSeeUser: user
|
||||
joinChannel: channel];
|
||||
|
||||
[pool release];
|
||||
return;
|
||||
}
|
||||
|
||||
/* PART */
|
||||
if ([action isEqual: @"PART"] && split.count >= 3) {
|
||||
OFString *who = [split objectAtIndex: 0];
|
||||
OFString *where = [split objectAtIndex: 2];
|
||||
IRCUser *user;
|
||||
IRCChannel *channel;
|
||||
OFString *reason = nil;
|
||||
size_t pos = who.length + 1 +
|
||||
[[split objectAtIndex: 1] length] + 1 + where.length;
|
||||
|
||||
who = [who substringWithRange: of_range(1, who.length - 1)];
|
||||
user = [IRCUser IRCUserWithString: who];
|
||||
channel = [channels objectForKey: where];
|
||||
|
||||
if (split.count > 3)
|
||||
reason = [line substringWithRange:
|
||||
of_range(pos + 2, line.length - pos - 2)];
|
||||
|
||||
if ([delegate respondsToSelector:
|
||||
@selector(connection:didSeeUser:leaveChannel:
|
||||
withReason:)])
|
||||
[delegate connection: self
|
||||
didSeeUser: user
|
||||
leaveChannel: channel
|
||||
withReason: reason];
|
||||
|
||||
[pool release];
|
||||
return;
|
||||
}
|
||||
|
||||
/* KICK */
|
||||
if ([action isEqual: @"KICK"] && split.count >= 4) {
|
||||
OFString *who = [split objectAtIndex: 0];
|
||||
OFString *where = [split objectAtIndex: 2];
|
||||
OFString *whom = [split objectAtIndex: 3];
|
||||
IRCUser *user;
|
||||
IRCChannel *channel;
|
||||
OFString *reason = nil;
|
||||
size_t pos = who.length + 1 +
|
||||
[[split objectAtIndex: 1] length] + 1 + where.length + 1 +
|
||||
whom.length;
|
||||
|
||||
who = [who substringWithRange: of_range(1, who.length - 1)];
|
||||
user = [IRCUser IRCUserWithString: who];
|
||||
channel = [channels objectForKey: where];
|
||||
|
||||
if (split.count > 4)
|
||||
reason = [line substringWithRange:
|
||||
of_range(pos + 2, line.length - pos - 2)];
|
||||
|
||||
if ([delegate respondsToSelector:
|
||||
@selector(connection:didSeeUser:kickUser:
|
||||
fromChannel:withReason:)])
|
||||
[delegate connection: self
|
||||
didSeeUser: user
|
||||
kickUser: whom
|
||||
fromChannel: channel
|
||||
withReason: reason];
|
||||
|
||||
[pool release];
|
||||
return;
|
||||
}
|
||||
|
||||
/* QUIT */
|
||||
if ([action isEqual: @"QUIT"] && split.count >= 2) {
|
||||
OFString *who = [split objectAtIndex: 0];
|
||||
IRCUser *user;
|
||||
OFString *reason = nil;
|
||||
size_t pos = who.length + 1 + [[split objectAtIndex: 1] length];
|
||||
|
||||
who = [who substringWithRange: of_range(1, who.length - 1)];
|
||||
user = [IRCUser IRCUserWithString: who];
|
||||
|
||||
if (split.count > 2)
|
||||
reason = [line substringWithRange:
|
||||
of_range(pos + 2, line.length - pos - 2)];
|
||||
|
||||
if ([delegate respondsToSelector:
|
||||
@selector(connection:didSeeUserQuit:withReason:)])
|
||||
[delegate connection: self
|
||||
didSeeUserQuit: user
|
||||
withReason: reason];
|
||||
|
||||
[pool release];
|
||||
return;
|
||||
}
|
||||
|
||||
/* NICK */
|
||||
if ([action isEqual: @"NICK"] && split.count == 3) {
|
||||
OFString *who = [split objectAtIndex: 0];
|
||||
OFString *newNickname = [split objectAtIndex: 2];
|
||||
IRCUser *user;
|
||||
|
||||
who = [who substringWithRange: of_range(1, who.length - 1)];
|
||||
newNickname = [newNickname substringWithRange:
|
||||
of_range(1, newNickname.length - 1)];
|
||||
|
||||
user = [IRCUser IRCUserWithString: who];
|
||||
|
||||
if ([user.nickname isEqual: nickname]) {
|
||||
[nickname release];
|
||||
nickname = [user.nickname copy];
|
||||
}
|
||||
|
||||
if ([delegate respondsToSelector:
|
||||
@selector(connection:didSeeUser:changeNicknameTo:)])
|
||||
[delegate connection: self
|
||||
didSeeUser: user
|
||||
changeNicknameTo: newNickname];
|
||||
|
||||
[pool release];
|
||||
return;
|
||||
}
|
||||
|
||||
/* PRIVMSG */
|
||||
if ([action isEqual: @"PRIVMSG"] && split.count >= 4) {
|
||||
OFString *from = [split objectAtIndex: 0];
|
||||
OFString *to = [split objectAtIndex: 2];
|
||||
IRCUser *user;
|
||||
OFString *msg;
|
||||
size_t pos = from.length + 1 +
|
||||
[[split objectAtIndex: 1] length] + 1 + to.length;
|
||||
|
||||
from = [from substringWithRange: of_range(1, from.length - 1)];
|
||||
msg = [line substringWithRange:
|
||||
of_range(pos + 2, line.length - pos - 2)];
|
||||
user = [IRCUser IRCUserWithString: from];
|
||||
|
||||
if (![to isEqual: nickname]) {
|
||||
IRCChannel *channel;
|
||||
|
||||
channel = [channels objectForKey: to];
|
||||
|
||||
if ([delegate respondsToSelector:
|
||||
@selector(connection:didReceiveMessage:
|
||||
fromUser:inChannel:)])
|
||||
[delegate connection: self
|
||||
didReceiveMessage: msg
|
||||
fromUser: user
|
||||
inChannel: channel];
|
||||
} else {
|
||||
if ([delegate respondsToSelector:
|
||||
@selector(connection:
|
||||
didReceivePrivateMessage:fromUser:)])
|
||||
[delegate
|
||||
connection: self
|
||||
didReceivePrivateMessage: msg
|
||||
fromUser: user];
|
||||
}
|
||||
|
||||
[pool release];
|
||||
return;
|
||||
}
|
||||
|
||||
/* NOTICE */
|
||||
if ([action isEqual: @"NOTICE"] && split.count >= 4) {
|
||||
OFString *from = [split objectAtIndex: 0];
|
||||
OFString *to = [split objectAtIndex: 2];
|
||||
IRCUser *user = nil;
|
||||
OFString *notice;
|
||||
size_t pos = from.length + 1 +
|
||||
[[split objectAtIndex: 1] length] + 1 + to.length;
|
||||
|
||||
from = [from substringWithRange: of_range(1, from.length - 1)];
|
||||
notice = [line substringWithRange:
|
||||
of_range(pos + 2, line.length - pos - 2)];
|
||||
|
||||
if (![from containsString: @"!"] || [to isEqual: @"*"]) {
|
||||
/* System message - ignore for now */
|
||||
[pool release];
|
||||
return;
|
||||
}
|
||||
|
||||
user = [IRCUser IRCUserWithString: from];
|
||||
|
||||
if (![to isEqual: nickname]) {
|
||||
IRCChannel *channel;
|
||||
|
||||
channel = [channels objectForKey: to];
|
||||
|
||||
if ([delegate respondsToSelector:
|
||||
@selector(connection:didReceiveNotice:
|
||||
fromUser:inChannel:)])
|
||||
[delegate connection: self
|
||||
didReceiveNotice: notice
|
||||
fromUser: user
|
||||
inChannel: channel];
|
||||
} else {
|
||||
if ([delegate respondsToSelector:
|
||||
@selector(connection:didReceiveNotice:
|
||||
fromUser:)])
|
||||
[delegate connection: self
|
||||
didReceiveNotice: notice
|
||||
fromUser: user];
|
||||
}
|
||||
|
||||
[pool release];
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
- (void)handleConnection
|
||||
{
|
||||
while (![sock isAtEndOfStream])
|
||||
[self process];
|
||||
}
|
||||
|
||||
- (void)dealloc
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue