diff --git a/IRCClient.xcodeproj/project.pbxproj b/IRCClient.xcodeproj/project.pbxproj index 323fc48..f96b6e8 100644 --- a/IRCClient.xcodeproj/project.pbxproj +++ b/IRCClient.xcodeproj/project.pbxproj @@ -10,11 +10,11 @@ 8657E6DD1C29F4C700BD4E50 /* NSData+SA_NSDataExtensions.h in Headers */ = {isa = PBXBuildFile; fileRef = 8657E6DB1C29F4C700BD4E50 /* NSData+SA_NSDataExtensions.h */; }; 8657E6DE1C29F4C700BD4E50 /* NSData+SA_NSDataExtensions.m in Sources */ = {isa = PBXBuildFile; fileRef = 8657E6DC1C29F4C700BD4E50 /* NSData+SA_NSDataExtensions.m */; }; 8657E6E21C2B55B900BD4E50 /* IRC_Numerics.plist in Resources */ = {isa = PBXBuildFile; fileRef = 8657E6E11C2B55B900BD4E50 /* IRC_Numerics.plist */; }; - 866EF0101C25FF07006303A1 /* libircclient.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 866EF00F1C25FF07006303A1 /* libircclient.a */; }; 868374A91C24E774005B97E5 /* IRCClient.h in Headers */ = {isa = PBXBuildFile; fileRef = 868374A81C24E774005B97E5 /* IRCClient.h */; settings = {ATTRIBUTES = (Public, ); }; }; 86B6232C1C21FD7C00D6E3AF /* README in Resources */ = {isa = PBXBuildFile; fileRef = 86B6232B1C21FD7C00D6E3AF /* README */; }; + 86CEFEEB1C2BC9A6000DB861 /* libircclient.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 86CEFEEA1C2BC9A6000DB861 /* libircclient.a */; }; + 86CEFEED1C2BC9BC000DB861 /* libirc_events.h in Headers */ = {isa = PBXBuildFile; fileRef = 86CEFEEC1C2BC9BC000DB861 /* libirc_events.h */; }; 86D784A61C24C39F00C7458D /* libirc_errors.h in Headers */ = {isa = PBXBuildFile; fileRef = 86D784A01C24C39F00C7458D /* libirc_errors.h */; }; - 86D784A71C24C39F00C7458D /* libirc_events.h in Headers */ = {isa = PBXBuildFile; fileRef = 86D784A11C24C39F00C7458D /* libirc_events.h */; }; 86D784A81C24C39F00C7458D /* libirc_options.h in Headers */ = {isa = PBXBuildFile; fileRef = 86D784A21C24C39F00C7458D /* libirc_options.h */; }; 86D784A91C24C39F00C7458D /* libirc_rfcnumeric.h in Headers */ = {isa = PBXBuildFile; fileRef = 86D784A31C24C39F00C7458D /* libirc_rfcnumeric.h */; }; 86D784AB1C24C39F00C7458D /* libircclient.h in Headers */ = {isa = PBXBuildFile; fileRef = 86D784A51C24C39F00C7458D /* libircclient.h */; }; @@ -31,11 +31,11 @@ 8657E6DB1C29F4C700BD4E50 /* NSData+SA_NSDataExtensions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSData+SA_NSDataExtensions.h"; sourceTree = ""; }; 8657E6DC1C29F4C700BD4E50 /* NSData+SA_NSDataExtensions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSData+SA_NSDataExtensions.m"; sourceTree = ""; }; 8657E6E11C2B55B900BD4E50 /* IRC_Numerics.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = IRC_Numerics.plist; sourceTree = ""; }; - 866EF00F1C25FF07006303A1 /* libircclient.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libircclient.a; sourceTree = ""; }; 868374A81C24E774005B97E5 /* IRCClient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IRCClient.h; sourceTree = ""; }; 86B6232B1C21FD7C00D6E3AF /* README */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = README; sourceTree = ""; }; + 86CEFEEA1C2BC9A6000DB861 /* libircclient.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libircclient.a; sourceTree = ""; }; + 86CEFEEC1C2BC9BC000DB861 /* libirc_events.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = libirc_events.h; sourceTree = ""; }; 86D784A01C24C39F00C7458D /* libirc_errors.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = libirc_errors.h; sourceTree = ""; }; - 86D784A11C24C39F00C7458D /* libirc_events.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = libirc_events.h; sourceTree = ""; }; 86D784A21C24C39F00C7458D /* libirc_options.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = libirc_options.h; sourceTree = ""; }; 86D784A31C24C39F00C7458D /* libirc_rfcnumeric.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = libirc_rfcnumeric.h; sourceTree = ""; }; 86D784A51C24C39F00C7458D /* libircclient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = libircclient.h; sourceTree = ""; }; @@ -55,7 +55,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 866EF0101C25FF07006303A1 /* libircclient.a in Frameworks */, + 86CEFEEB1C2BC9A6000DB861 /* libircclient.a in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -74,9 +74,9 @@ 86D7849F1C24C39F00C7458D /* libircclient */ = { isa = PBXGroup; children = ( - 866EF00F1C25FF07006303A1 /* libircclient.a */, + 86CEFEEA1C2BC9A6000DB861 /* libircclient.a */, 86D784A01C24C39F00C7458D /* libirc_errors.h */, - 86D784A11C24C39F00C7458D /* libirc_events.h */, + 86CEFEEC1C2BC9BC000DB861 /* libirc_events.h */, 86D784A21C24C39F00C7458D /* libirc_options.h */, 86D784A31C24C39F00C7458D /* libirc_rfcnumeric.h */, 86D784A51C24C39F00C7458D /* libircclient.h */, @@ -135,9 +135,9 @@ 86F2EFFB1C21F81900B033A4 /* IRCClientChannelDelegate.h in Headers */, 8657E6DD1C29F4C700BD4E50 /* NSData+SA_NSDataExtensions.h in Headers */, 86F2EFFC1C21F81900B033A4 /* IRCClientSession.h in Headers */, - 86D784A71C24C39F00C7458D /* libirc_events.h in Headers */, 86D784A91C24C39F00C7458D /* libirc_rfcnumeric.h in Headers */, 86D784A81C24C39F00C7458D /* libirc_options.h in Headers */, + 86CEFEED1C2BC9BC000DB861 /* libirc_events.h in Headers */, 86F2EFF81C21F81900B033A4 /* IRCClientChannel_Private.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; diff --git a/IRCClient/IRCClientSession.h b/IRCClient/IRCClientSession.h index afe410a..f6eb110 100644 --- a/IRCClient/IRCClientSession.h +++ b/IRCClient/IRCClientSession.h @@ -146,7 +146,7 @@ messages have implementation-specific uses. See the various RFCs, and other info sources, for details. */ -+(NSDictionary *)IRCNumericCodes; ++(NSDictionary *)ircNumericCodes; /** Set the nickname, username, and realname for the session. diff --git a/IRCClient/IRCClientSession.m b/IRCClient/IRCClientSession.m index 111a87f..7b52797 100644 --- a/IRCClient/IRCClientSession.m +++ b/IRCClient/IRCClientSession.m @@ -39,8 +39,10 @@ static void onTopic(irc_session_t *session, const char *event, const char *origi static void onKick(irc_session_t *session, const char *event, const char *origin, const char **params, unsigned int count); static void onChannelPrvmsg(irc_session_t *session, const char *event, const char *origin, const char **params, unsigned int count); static void onPrivmsg(irc_session_t *session, const char *event, const char *origin, const char **params, unsigned int count); +static void onServerMsg(irc_session_t *session, const char *event, const char *origin, const char **params, unsigned int count); static void onNotice(irc_session_t *session, const char *event, const char *origin, const char **params, unsigned int count); static void onChannelNotice(irc_session_t *session, const char *event, const char *origin, const char **params, unsigned int count); +static void onServerNotice(irc_session_t *session, const char *event, const char *origin, const char **params, unsigned int count); static void onInvite(irc_session_t *session, const char *event, const char *origin, const char **params, unsigned int count); static void onCtcpRequest(irc_session_t *session, const char *event, const char *origin, const char **params, unsigned int count); static void onCtcpReply(irc_session_t *session, const char *event, const char *origin, const char **params, unsigned int count); @@ -124,8 +126,10 @@ static NSDictionary* ircNumericCodeList; _callbacks.event_kick = onKick; _callbacks.event_channel = onChannelPrvmsg; _callbacks.event_privmsg = onPrivmsg; + _callbacks.event_server_msg = onServerMsg; _callbacks.event_notice = onNotice; _callbacks.event_channel_notice = onChannelNotice; + _callbacks.event_server_notice = onServerNotice; _callbacks.event_invite = onInvite; _callbacks.event_ctcp_req = onCtcpRequest; _callbacks.event_ctcp_rep = onCtcpReply; @@ -143,7 +147,10 @@ static NSDictionary* ircNumericCodeList; } // Strip server info from nicks. -// irc_option_set(irc_session, LIBIRC_OPTION_STRIPNICKS); +// irc_option_set(_irc_session, LIBIRC_OPTION_STRIPNICKS); + + // Set debug mode. + irc_option_set(_irc_session, LIBIRC_OPTION_DEBUG); irc_set_ctx(_irc_session, (__bridge void *)(self)); @@ -166,7 +173,7 @@ static NSDictionary* ircNumericCodeList; irc_destroy_session(_irc_session); } -+(NSDictionary *)IRCNumericCodes ++(NSDictionary *)ircNumericCodes { if(ircNumericCodeList == nil) { @@ -178,11 +185,12 @@ static NSDictionary* ircNumericCodeList; +(void)loadNumericCodes { - NSString* numericCodeListPath = [[NSBundle mainBundle] pathForResource:@"IRC_Numerics" ofType:@"plist"]; + NSString* numericCodeListPath = [[NSBundle bundleForClass:[self class]] pathForResource:@"IRC_Numerics" ofType:@"plist"]; ircNumericCodeList = [NSDictionary dictionaryWithContentsOfFile:numericCodeListPath]; if(ircNumericCodeList) { NSLog(@"IRC numeric codes list loaded successfully.\n"); +// NSLog(@"%@", ircNumericCodeList); } else { @@ -427,6 +435,11 @@ static NSDictionary* ircNumericCodeList; [_delegate privateMessageReceived:messageString fromUser:nick]; } +- (void)serverMessageReceivedFrom:(NSString *)origin params:(NSArray *)params +{ + [_delegate serverMessageReceivedFrom:origin params:params]; +} + - (void)privateNoticeReceived:(NSData *)notice fromUser:(NSString *)nick { NSString* noticeString = [NSString stringWithCString:notice.SA_terminatedCString encoding:_encoding]; @@ -441,6 +454,11 @@ static NSDictionary* ircNumericCodeList; [channel noticeSent:notice byUser:nick]; } +- (void)serverNoticeReceivedFrom:(NSString *)origin params:(NSArray *)params +{ + [_delegate serverNoticeReceivedFrom:origin params:params]; +} + - (void)invitedToChannel:(NSData *)channelName by:(NSString *)nick { [_delegate invitedToChannel:channelName.SA_dataWithTerminatedCString by:nick]; @@ -839,6 +857,28 @@ static void onPrivmsg(irc_session_t *session, const char *event, const char *ori [clientSession privateMessageReceived:message fromUser:nick]; } +/*! + * The "privmsg" event is triggered upon receipt of a PRIVMSG message + * which is addressed to no one in particular, but it sent to the client + * anyway. + * + * \param origin the person, who generates the message. + * \param params optional, contains who knows what. + */ +static void onServerMsg(irc_session_t *session, const char *event, const char *origin, const char **params, unsigned int count) +{ + IRCClientSession *clientSession = (__bridge IRCClientSession *) irc_get_ctx(session); + NSString *sender = @(origin); + + NSMutableArray *paramsArray = [[NSMutableArray alloc] init]; + for (unsigned int i = 0; i < count; i++) + { + [paramsArray addObject:[NSData dataWithBytes:params[i] length:strlen(params[i]) + 1]]; + } + + [clientSession serverMessageReceivedFrom:sender params:paramsArray]; +} + /*! * The "notice" event is triggered upon receipt of a NOTICE message * which means that someone has sent the client a public or private @@ -902,6 +942,34 @@ static void onChannelNotice(irc_session_t *session, const char *event, const cha [clientSession noticeSent:notice toChannel:channelName byUser:nick]; } +/*! + * The "server_notice" event is triggered upon receipt of a NOTICE + * message which means that the server has sent the client a notice. + * This notice is not necessarily addressed to the client's nick + * (for example, AUTH notices, sent before the client's nick is known). + * According to RFC 1459, the only difference between NOTICE + * and PRIVMSG is that you should NEVER automatically reply to NOTICE + * messages. Unfortunately, this rule is frequently violated by IRC + * servers itself - for example, NICKSERV messages require reply, and + * are NOTICEs. + * + * \param origin the person, who generates the message. + * \param params optional, contains who knows what. + */ +static void onServerNotice(irc_session_t *session, const char *event, const char *origin, const char **params, unsigned int count) +{ + IRCClientSession *clientSession = (__bridge IRCClientSession *) irc_get_ctx(session); + NSString *sender = @(origin); + + NSMutableArray *paramsArray = [[NSMutableArray alloc] init]; + for (unsigned int i = 0; i < count; i++) + { + [paramsArray addObject:[NSData dataWithBytes:params[i] length:strlen(params[i]) + 1]]; + } + + [clientSession serverNoticeReceivedFrom:sender params:paramsArray]; +} + /*! * The "invite" event is triggered upon receipt of an INVITE message, * which means that someone is permitting the client's entry into a +i diff --git a/IRCClient/IRCClientSessionDelegate.h b/IRCClient/IRCClientSessionDelegate.h index f68b578..b1dd9c4 100644 --- a/IRCClient/IRCClientSessionDelegate.h +++ b/IRCClient/IRCClientSessionDelegate.h @@ -85,6 +85,20 @@ */ - (void)privateNoticeReceived:(NSString *)notice fromUser:(NSString *)nick; +/** The client has received a private PRIVMSG from the server. + * + * @param origin the sender of the message + * @param params the parameters of the message + */ +- (void)serverMessageReceivedFrom:(NSString *)origin params:(NSArray *)params; + +/** The client has received a private NOTICE from the server. + * + * @param origin the sender of the notice + * @param params the parameters of the notice + */ +- (void)serverNoticeReceivedFrom:(NSString *)origin params:(NSArray *)params; + /** The IRC client has been invited to a channel. * * Note that the name is provided as an NSData object, because we have no idea