| /* Begin PBXBuildFile section */ | /* Begin PBXBuildFile section */ | ||||
| 86F2EFEA1C21F73600B033A4 /* IRCClient.h in Headers */ = {isa = PBXBuildFile; fileRef = 86F2EFE91C21F73600B033A4 /* IRCClient.h */; settings = {ATTRIBUTES = (Public, ); }; }; | 86F2EFEA1C21F73600B033A4 /* IRCClient.h in Headers */ = {isa = PBXBuildFile; fileRef = 86F2EFE91C21F73600B033A4 /* IRCClient.h */; settings = {ATTRIBUTES = (Public, ); }; }; | ||||
| 86F2EFF81C21F81900B033A4 /* IRCClientChannel_Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 86F2EFF11C21F81900B033A4 /* IRCClientChannel_Private.h */; }; | |||||
| 86F2EFF91C21F81900B033A4 /* IRCClientChannel.h in Headers */ = {isa = PBXBuildFile; fileRef = 86F2EFF21C21F81900B033A4 /* IRCClientChannel.h */; }; | |||||
| 86F2EFFA1C21F81900B033A4 /* IRCClientChannel.m in Sources */ = {isa = PBXBuildFile; fileRef = 86F2EFF31C21F81900B033A4 /* IRCClientChannel.m */; }; | |||||
| 86F2EFFB1C21F81900B033A4 /* IRCClientChannelDelegate.h in Headers */ = {isa = PBXBuildFile; fileRef = 86F2EFF41C21F81900B033A4 /* IRCClientChannelDelegate.h */; }; | |||||
| 86F2EFFC1C21F81900B033A4 /* IRCClientSession.h in Headers */ = {isa = PBXBuildFile; fileRef = 86F2EFF51C21F81900B033A4 /* IRCClientSession.h */; }; | |||||
| 86F2EFFD1C21F81900B033A4 /* IRCClientSession.m in Sources */ = {isa = PBXBuildFile; fileRef = 86F2EFF61C21F81900B033A4 /* IRCClientSession.m */; }; | |||||
| 86F2EFFE1C21F81900B033A4 /* IRCClientSessionDelegate.h in Headers */ = {isa = PBXBuildFile; fileRef = 86F2EFF71C21F81900B033A4 /* IRCClientSessionDelegate.h */; }; | |||||
| /* End PBXBuildFile section */ | /* End PBXBuildFile section */ | ||||
| /* Begin PBXFileReference section */ | /* Begin PBXFileReference section */ | ||||
| 86F2EFE61C21F73600B033A4 /* IRCClient.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = IRCClient.framework; sourceTree = BUILT_PRODUCTS_DIR; }; | 86F2EFE61C21F73600B033A4 /* IRCClient.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = IRCClient.framework; sourceTree = BUILT_PRODUCTS_DIR; }; | ||||
| 86F2EFE91C21F73600B033A4 /* IRCClient.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = IRCClient.h; sourceTree = "<group>"; }; | 86F2EFE91C21F73600B033A4 /* IRCClient.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = IRCClient.h; sourceTree = "<group>"; }; | ||||
| 86F2EFEB1C21F73600B033A4 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; }; | 86F2EFEB1C21F73600B033A4 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; }; | ||||
| 86F2EFF11C21F81900B033A4 /* IRCClientChannel_Private.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IRCClientChannel_Private.h; sourceTree = "<group>"; }; | |||||
| 86F2EFF21C21F81900B033A4 /* IRCClientChannel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IRCClientChannel.h; sourceTree = "<group>"; }; | |||||
| 86F2EFF31C21F81900B033A4 /* IRCClientChannel.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IRCClientChannel.m; sourceTree = "<group>"; }; | |||||
| 86F2EFF41C21F81900B033A4 /* IRCClientChannelDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IRCClientChannelDelegate.h; sourceTree = "<group>"; }; | |||||
| 86F2EFF51C21F81900B033A4 /* IRCClientSession.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IRCClientSession.h; sourceTree = "<group>"; }; | |||||
| 86F2EFF61C21F81900B033A4 /* IRCClientSession.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IRCClientSession.m; sourceTree = "<group>"; }; | |||||
| 86F2EFF71C21F81900B033A4 /* IRCClientSessionDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IRCClientSessionDelegate.h; sourceTree = "<group>"; }; | |||||
| /* End PBXFileReference section */ | /* End PBXFileReference section */ | ||||
| /* Begin PBXFrameworksBuildPhase section */ | /* Begin PBXFrameworksBuildPhase section */ | ||||
| 86F2EFE81C21F73600B033A4 /* IRCClient */ = { | 86F2EFE81C21F73600B033A4 /* IRCClient */ = { | ||||
| isa = PBXGroup; | isa = PBXGroup; | ||||
| children = ( | children = ( | ||||
| 86F2EFF11C21F81900B033A4 /* IRCClientChannel_Private.h */, | |||||
| 86F2EFF21C21F81900B033A4 /* IRCClientChannel.h */, | |||||
| 86F2EFF31C21F81900B033A4 /* IRCClientChannel.m */, | |||||
| 86F2EFF41C21F81900B033A4 /* IRCClientChannelDelegate.h */, | |||||
| 86F2EFF51C21F81900B033A4 /* IRCClientSession.h */, | |||||
| 86F2EFF61C21F81900B033A4 /* IRCClientSession.m */, | |||||
| 86F2EFF71C21F81900B033A4 /* IRCClientSessionDelegate.h */, | |||||
| 86F2EFE91C21F73600B033A4 /* IRCClient.h */, | 86F2EFE91C21F73600B033A4 /* IRCClient.h */, | ||||
| 86F2EFEB1C21F73600B033A4 /* Info.plist */, | 86F2EFEB1C21F73600B033A4 /* Info.plist */, | ||||
| ); | ); | ||||
| isa = PBXHeadersBuildPhase; | isa = PBXHeadersBuildPhase; | ||||
| buildActionMask = 2147483647; | buildActionMask = 2147483647; | ||||
| files = ( | files = ( | ||||
| 86F2EFFE1C21F81900B033A4 /* IRCClientSessionDelegate.h in Headers */, | |||||
| 86F2EFF91C21F81900B033A4 /* IRCClientChannel.h in Headers */, | |||||
| 86F2EFFB1C21F81900B033A4 /* IRCClientChannelDelegate.h in Headers */, | |||||
| 86F2EFFC1C21F81900B033A4 /* IRCClientSession.h in Headers */, | |||||
| 86F2EFF81C21F81900B033A4 /* IRCClientChannel_Private.h in Headers */, | |||||
| 86F2EFEA1C21F73600B033A4 /* IRCClient.h in Headers */, | 86F2EFEA1C21F73600B033A4 /* IRCClient.h in Headers */, | ||||
| ); | ); | ||||
| runOnlyForDeploymentPostprocessing = 0; | runOnlyForDeploymentPostprocessing = 0; | ||||
| isa = PBXSourcesBuildPhase; | isa = PBXSourcesBuildPhase; | ||||
| buildActionMask = 2147483647; | buildActionMask = 2147483647; | ||||
| files = ( | files = ( | ||||
| 86F2EFFD1C21F81900B033A4 /* IRCClientSession.m in Sources */, | |||||
| 86F2EFFA1C21F81900B033A4 /* IRCClientChannel.m in Sources */, | |||||
| ); | ); | ||||
| runOnlyForDeploymentPostprocessing = 0; | runOnlyForDeploymentPostprocessing = 0; | ||||
| }; | }; | ||||
| INFOPLIST_FILE = IRCClient/Info.plist; | INFOPLIST_FILE = IRCClient/Info.plist; | ||||
| INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; | ||||
| LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/Frameworks"; | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/Frameworks"; | ||||
| MACOSX_DEPLOYMENT_TARGET = 10.6; | |||||
| PRODUCT_BUNDLE_IDENTIFIER = saidachmiz.IRCClient; | PRODUCT_BUNDLE_IDENTIFIER = saidachmiz.IRCClient; | ||||
| PRODUCT_NAME = "$(TARGET_NAME)"; | PRODUCT_NAME = "$(TARGET_NAME)"; | ||||
| SKIP_INSTALL = YES; | SKIP_INSTALL = YES; | ||||
| INFOPLIST_FILE = IRCClient/Info.plist; | INFOPLIST_FILE = IRCClient/Info.plist; | ||||
| INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; | ||||
| LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/Frameworks"; | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/Frameworks"; | ||||
| MACOSX_DEPLOYMENT_TARGET = 10.6; | |||||
| PRODUCT_BUNDLE_IDENTIFIER = saidachmiz.IRCClient; | PRODUCT_BUNDLE_IDENTIFIER = saidachmiz.IRCClient; | ||||
| PRODUCT_NAME = "$(TARGET_NAME)"; | PRODUCT_NAME = "$(TARGET_NAME)"; | ||||
| SKIP_INSTALL = YES; | SKIP_INSTALL = YES; |
| /* | |||||
| * Modified IRCClient Copyright 2015 Said Achmiz (www.saidachmiz.net) | |||||
| * | |||||
| * Original IRCClient Copyright (C) 2009 Nathan Ollerenshaw chrome@stupendous.net | |||||
| * | |||||
| * This library is free software; you can redistribute it and/or modify it | |||||
| * under the terms of the GNU Lesser General Public License as published by | |||||
| * the Free Software Foundation; either version 2 of the License, or (at your | |||||
| * option) any later version. | |||||
| * | |||||
| * This library is distributed in the hope that it will be useful, but WITHOUT | |||||
| * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |||||
| * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public | |||||
| * License for more details. | |||||
| */ | |||||
| /** | |||||
| * @file IRCClientChannel.h | |||||
| * @author Nathan Ollerenshaw | |||||
| * @version 1.0 | |||||
| * @date 01.2009 | |||||
| * @brief Represents a connected IRC Channel. | |||||
| */ | |||||
| #import <Cocoa/Cocoa.h> | |||||
| #import "IRCClientChannelDelegate.h" | |||||
| #import "libircclient.h" | |||||
| /** \class IRCClientChannel | |||||
| * @brief Represents a connected IRC Channel. | |||||
| * | |||||
| * IRCClientChannel objects are created by the IRCClientSession object | |||||
| * for a given session when the client joins an IRC channel. | |||||
| */ | |||||
| @class IRCClientSession; | |||||
| #pragma mark IRCClientChannel class declaration | |||||
| @interface IRCClientChannel : NSObject | |||||
| /************************/ | |||||
| #pragma mark - Properties | |||||
| /************************/ | |||||
| /** Delegate to send events to */ | |||||
| @property (assign) id <IRCClientChannelDelegate> delegate; | |||||
| /** Name of the channel */ | |||||
| @property (nonatomic, retain) NSData *name; | |||||
| /** Encoding used by, and in, this channel */ | |||||
| @property (assign) NSStringEncoding encoding; | |||||
| /** Topic of the channel | |||||
| * | |||||
| * You can (attempt to) set the topic by using setChannelTopic:, not by | |||||
| * changing this property (which is readonly). If the connected user has the | |||||
| * privileges to set the channel topic, the channel's delegate will receive a | |||||
| * topicSet:by: message (and the topic property of the channel object will be | |||||
| * updated automatically). | |||||
| */ | |||||
| @property (nonatomic, readonly) NSData *topic; | |||||
| /** Modes of the channel */ | |||||
| @property (nonatomic, retain) NSString *modes; | |||||
| /** An array of nicknames stored as NSStrings that list the connected users | |||||
| for the channel */ | |||||
| @property (nonatomic, readonly) NSArray *nicks; | |||||
| /**************************/ | |||||
| #pragma mark - IRC commands | |||||
| /**************************/ | |||||
| /** Parts the channel. */ | |||||
| - (int)part; | |||||
| /** Invites another IRC client to the channel. | |||||
| * | |||||
| * @param nick the nickname of the client to invite. | |||||
| */ | |||||
| - (int)invite:(NSString *)nick; | |||||
| /** Sets the topic of the channel. | |||||
| * | |||||
| * Note that not all users on a channel have permission to change the topic; if you fail | |||||
| * to set the topic, then you will not see an onTopic event on the IRCClientChannelDelegate. | |||||
| * | |||||
| * @param aTopic the topic the client wishes to set for the channel. | |||||
| */ | |||||
| - (void)setChannelTopic:(NSString *)newTopic; | |||||
| /** Sets the mode of the channel. | |||||
| * | |||||
| * Note that not all users on a channel have permission to change the mode; if you fail | |||||
| * to set the mode, then you will not see a modeSet event on the IRCClientChannelDelegate. | |||||
| * | |||||
| * @param mode the mode to set the channel to | |||||
| */ | |||||
| - (int)setMode:(NSString *)mode params:(NSString *)params; | |||||
| /** Sends a public PRIVMSG to the channel. If you try to send more than can fit on an IRC | |||||
| buffer, it will be truncated. | |||||
| @param message the message to send to the channel. | |||||
| */ | |||||
| - (int)message:(NSString *)message; | |||||
| /** Sends a public CTCP ACTION to the channel. | |||||
| * | |||||
| * @param action action to send to the channel. | |||||
| */ | |||||
| - (int)action:(NSString *)action; | |||||
| /** Sends a public NOTICE to the channel. | |||||
| * | |||||
| * @param notice message to send to the channel. | |||||
| */ | |||||
| - (int)notice:(NSString *)notice; | |||||
| /** Kicks someone from a channel. | |||||
| * | |||||
| * @param nick the IRC client to kick from the channel. | |||||
| * @param reason the message to give to the channel and the IRC client for the kick. | |||||
| */ | |||||
| - (int)kick:(NSString *)nick reason:(NSString *)reason; | |||||
| /** Sends a CTCP request to the channel. | |||||
| * | |||||
| * It is perfectly legal to send a CTCP request to an IRC channel, however many clients | |||||
| * decline to respond to them, and often they are percieved as annoying. | |||||
| * | |||||
| * @param request the string of the request, in CTCP format. | |||||
| */ | |||||
| - (int)ctcpRequest:(NSData *)request; | |||||
| @end |
| /* | |||||
| * Modified IRCClient Copyright 2015 Said Achmiz (www.saidachmiz.net) | |||||
| * | |||||
| * Original IRCClient Copyright (C) 2009 Nathan Ollerenshaw chrome@stupendous.net | |||||
| * | |||||
| * This library is free software; you can redistribute it and/or modify it | |||||
| * under the terms of the GNU Lesser General Public License as published by | |||||
| * the Free Software Foundation; either version 2 of the License, or (at your | |||||
| * option) any later version. | |||||
| * | |||||
| * This library is distributed in the hope that it will be useful, but WITHOUT | |||||
| * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |||||
| * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public | |||||
| * License for more details. | |||||
| */ | |||||
| #import "IRCClientChannel.h" | |||||
| #import "IRCClientSession.h" | |||||
| #import "IRCClientChannel_Private.h" | |||||
| #pragma mark IRCClientChannel private category | |||||
| @interface IRCClientChannel() | |||||
| { | |||||
| NSData *name; | |||||
| irc_session_t *irc_session; | |||||
| NSStringEncoding encoding; | |||||
| NSData *topic; | |||||
| NSString *modes; | |||||
| NSMutableArray *nicks; | |||||
| } | |||||
| @property (nonatomic, retain) NSMutableArray *nicks; | |||||
| @end | |||||
| #pragma mark - IRCClientChannel class implementation | |||||
| @implementation IRCClientChannel | |||||
| #pragma mark - Property synthesis | |||||
| @synthesize delegate; | |||||
| @synthesize name; | |||||
| @synthesize encoding; | |||||
| @synthesize topic; | |||||
| @synthesize modes; | |||||
| #pragma mark - Custom accessors | |||||
| -(NSArray *)nicks | |||||
| { | |||||
| NSArray* nicksCopy = [nicks copy]; | |||||
| return nicksCopy; | |||||
| } | |||||
| -(void)setNicks:(NSArray *)newNicks | |||||
| { | |||||
| nicks = [newNicks mutableCopy]; | |||||
| } | |||||
| /**************************/ | |||||
| #pragma mark - Initializers | |||||
| /**************************/ | |||||
| -(instancetype)initWithName:(NSData *)aName andIRCSession:(irc_session_t *)session | |||||
| { | |||||
| if ((self = [super init])) { | |||||
| name = aName; | |||||
| irc_session = session; | |||||
| topic = [NSData dataWithBytes:@"".UTF8String length:1]; | |||||
| encoding = NSUTF8StringEncoding; | |||||
| } | |||||
| return self; | |||||
| } | |||||
| /**************************/ | |||||
| #pragma mark - IRC commands | |||||
| /**************************/ | |||||
| - (int)part | |||||
| { | |||||
| return irc_cmd_part(irc_session, name.bytes); | |||||
| } | |||||
| - (int)invite:(NSString *)nick | |||||
| { | |||||
| return irc_cmd_invite(irc_session, nick.UTF8String, name.bytes); | |||||
| } | |||||
| - (int)refreshNames | |||||
| { | |||||
| return irc_cmd_names(irc_session, name.bytes); | |||||
| } | |||||
| - (void)setChannelTopic:(NSString *)newTopic | |||||
| { | |||||
| irc_cmd_topic(irc_session, name.bytes, [newTopic cStringUsingEncoding:encoding]); | |||||
| } | |||||
| - (int)setMode:(NSString *)mode params:(NSString *)params | |||||
| { | |||||
| NSMutableString* modeString = [mode mutableCopy]; | |||||
| if(params != nil && params.length > 0) | |||||
| [modeString appendFormat:@" %@", params]; | |||||
| return irc_cmd_channel_mode(irc_session, name.bytes, modeString.UTF8String); | |||||
| } | |||||
| - (int)message:(NSString *)message | |||||
| { | |||||
| return irc_cmd_msg(irc_session, name.bytes, [message cStringUsingEncoding:encoding]); | |||||
| } | |||||
| - (int)action:(NSString *)action | |||||
| { | |||||
| return irc_cmd_me(irc_session, name.bytes, [action cStringUsingEncoding:encoding]); | |||||
| } | |||||
| - (int)notice:(NSString *)notice | |||||
| { | |||||
| return irc_cmd_notice(irc_session, name.bytes, [notice cStringUsingEncoding:encoding]); | |||||
| } | |||||
| - (int)kick:(NSString *)nick reason:(NSString *)reason | |||||
| { | |||||
| return irc_cmd_kick(irc_session, nick.UTF8String, name.bytes, [reason cStringUsingEncoding:encoding]); | |||||
| } | |||||
| - (int)ctcpRequest:(NSData *)request | |||||
| { | |||||
| return irc_cmd_ctcp_request(irc_session, name.bytes, request.bytes); | |||||
| } | |||||
| /****************************/ | |||||
| #pragma mark - Event handlers | |||||
| /****************************/ | |||||
| - (void)userJoined:(NSString *)nick | |||||
| { | |||||
| [delegate userJoined:nick]; | |||||
| } | |||||
| - (void)userParted:(NSString *)nick withReason:(NSData *)reason us:(BOOL)wasItUs | |||||
| { | |||||
| NSString* reasonString = [[NSString alloc] initWithData:reason encoding:encoding]; | |||||
| [delegate userParted:nick withReason:reasonString us:wasItUs]; | |||||
| } | |||||
| - (void)modeSet:(NSString *)mode withParams:(NSString *)params by:(NSString *)nick | |||||
| { | |||||
| [delegate modeSet:mode withParams:params by:nick]; | |||||
| } | |||||
| - (void)topicSet:(NSData *)newTopic by:(NSString *)nick | |||||
| { | |||||
| topic = newTopic; | |||||
| NSString* topicString = [[NSString alloc] initWithData:topic encoding:encoding]; | |||||
| [delegate topicSet:topicString by:nick]; | |||||
| } | |||||
| - (void)userKicked:(NSString *)nick withReason:(NSData *)reason by:(NSString *)byNick us:(BOOL)wasItUs | |||||
| { | |||||
| NSString* reasonString = [[NSString alloc] initWithData:reason encoding:encoding]; | |||||
| [delegate userKicked:nick withReason:reasonString by:byNick us:wasItUs]; | |||||
| } | |||||
| - (void)messageSent:(NSData *)message byUser:(NSString *)nick | |||||
| { | |||||
| NSString* messageString = [[NSString alloc] initWithData:message encoding:encoding]; | |||||
| [delegate messageSent:messageString byUser:nick]; | |||||
| } | |||||
| - (void)noticeSent:(NSData *)notice byUser:(NSString *)nick | |||||
| { | |||||
| NSString* noticeString = [[NSString alloc] initWithData:notice encoding:encoding]; | |||||
| [delegate noticeSent:noticeString byUser:nick]; | |||||
| } | |||||
| - (void)actionPerformed:(NSData *)action byUser:(NSString *)nick | |||||
| { | |||||
| NSString* actionString = [[NSString alloc] initWithData:action encoding:encoding]; | |||||
| [delegate actionPerformed:actionString byUser:nick]; | |||||
| } | |||||
| @end |
| /* | |||||
| * Modified IRCClient Copyright 2015 Said Achmiz (www.saidachmiz.net) | |||||
| * | |||||
| * Original IRCClient Copyright (C) 2009 Nathan Ollerenshaw chrome@stupendous.net | |||||
| * | |||||
| * This library is free software; you can redistribute it and/or modify it | |||||
| * under the terms of the GNU Lesser General Public License as published by | |||||
| * the Free Software Foundation; either version 2 of the License, or (at your | |||||
| * option) any later version. | |||||
| * | |||||
| * This library is distributed in the hope that it will be useful, but WITHOUT | |||||
| * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |||||
| * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public | |||||
| * License for more details. | |||||
| */ | |||||
| /** | |||||
| * @file IRCClientChannelDelegate.h | |||||
| * @author Nathan Ollerenshaw | |||||
| * @version 1.0 | |||||
| * @date 01.2009 | |||||
| * @brief Receives delegate messages from an IRCClientChannel. | |||||
| * @protocol IRCClientChannelDelegate | |||||
| */ | |||||
| #import <Cocoa/Cocoa.h> | |||||
| /** @brief Receives delegate messages from an IRCClientChannel. | |||||
| * | |||||
| * Each IRCClientChannel object needs a delegate. Delegate methods are called | |||||
| * for each event that occurs on an IRC channel that the client is current on. | |||||
| * | |||||
| * Note that for any given parameter, it may be optional, in which case a nil | |||||
| * object may be supplied instead of the given parameter. | |||||
| */ | |||||
| @protocol IRCClientChannelDelegate <NSObject> | |||||
| /** When a client joins this channel, the userJoined event is fired. Note that | |||||
| * the nickname is most likely in nick!user\@host format, but may simply be a | |||||
| * nickname, depending on the server implementation. | |||||
| * | |||||
| * You should also expect to see this event when the client first joins a channel, | |||||
| * with a parameter of the client's nickname. | |||||
| * | |||||
| * @param nick The nickname of the user that joined the channel. | |||||
| */ | |||||
| - (void)userJoined:(NSString *)nick; | |||||
| /** When an IRC client parts a channel you are connect to, you will see | |||||
| * an onPart event. You will also see this event when you part a channel. | |||||
| * | |||||
| * @param nick (required) The nickname of the user that left the channel. | |||||
| * @param reason (optional) The reason, if any, that the user gave for leaving. | |||||
| * @param wasItUs (required) Was it us who parted, or another user? | |||||
| */ | |||||
| - (void)userParted:(NSString *)nick withReason:(NSString *)reason us:(BOOL)wasItUs; | |||||
| /** Received when an IRC client changes the channel mode. What modes are available | |||||
| * for a given channel is an implementation detail for each server. | |||||
| * | |||||
| * @param mode the new channel mode. | |||||
| * @param params any parameters with the mode (such as channel key). | |||||
| * @param nick the nickname of the IRC client that changed the mode. | |||||
| */ | |||||
| - (void)modeSet:(NSString *)mode withParams:(NSString *)params by:(NSString *)nick; | |||||
| /** Received when the topic is changed for the channel. | |||||
| * | |||||
| * @param aTopic The new topic of the channel. | |||||
| * @param nick Nickname of the IRC client that changed the topic. | |||||
| */ | |||||
| - (void)topicSet:(NSString *)newTopic by:(NSString *)nick; | |||||
| /** Received when an IRC client is kicked from a channel. | |||||
| * | |||||
| * @param nick nickname of the client that was kicked | |||||
| * @param reason reason message given for the kick | |||||
| * @param byNick nickname of the client that performed the kick command | |||||
| * @param wasItUs Was it us who got kicked, or another user? | |||||
| */ | |||||
| - (void)userKicked:(NSString *)nick withReason:(NSString *)reason by:(NSString *)byNick us:(BOOL)wasItUs; | |||||
| /** Received when an IRC client sends a public PRIVMSG to the channel. Note that the | |||||
| * user may not necessarily be required to be on the channel to send a message | |||||
| * to it. | |||||
| * | |||||
| * @param message the message sent to the channel. | |||||
| * @param nick the nickname of the IRC client that sent the message. | |||||
| */ | |||||
| - (void)messageSent:(NSString *)message byUser:(NSString *)nick; | |||||
| /** Received when an IRC client sends a public NOTICE to the channel. Note that | |||||
| * the user may not necessarily be required to be on the channel to send a notice to | |||||
| * it. Furthermore, the RFC states that the only difference between PRIVMSG and | |||||
| * NOTICE is that a NOTICE may never be responded to automatically. | |||||
| * | |||||
| * @param notice the notice sent to the channel. | |||||
| * @param nick the nickname of the IRC client that sent the notice. | |||||
| */ | |||||
| - (void)noticeSent:(NSString *)notice byUser:(NSString *)nick; | |||||
| /** Received when an IRC client sends a CTCP ACTION message to the channel. | |||||
| * | |||||
| * @param action the action message sent to the channel. | |||||
| * @param nick the nickname of the IRC client that sent the message. | |||||
| */ | |||||
| - (void)actionPerformed:(NSString *)action byUser:(NSString *)nick; | |||||
| @end |
| // | |||||
| // IRCClientChannel_Private.h | |||||
| // Meil | |||||
| // | |||||
| // Copyright 2015 Said Achmiz (www.saidachmiz.net) | |||||
| // | |||||
| #import "IRCClientChannel.h" | |||||
| @interface IRCClientChannel () | |||||
| /** initWithName:andIRCSession: | |||||
| * | |||||
| * Returns an initialised IRCClientChannel with a given channel name, associated | |||||
| * with the given irc_session_t object. You are not expected to initialise your | |||||
| * own IRCClientChannel objects; if you wish to join a channel you should send a | |||||
| * [IRCClientSession join:key:] message to your IRCClientSession object. | |||||
| * | |||||
| * @param aName Name of the channel. | |||||
| */ | |||||
| -(instancetype)initWithName:(NSData *)aName andIRCSession:(irc_session_t *)session; | |||||
| /****************************/ | |||||
| #pragma mark - Event handlers | |||||
| /****************************/ | |||||
| /* NOTE: These methods are not to be called by classes that use IRCClient; | |||||
| * they are for the framework's internal use only. Do not import this header | |||||
| * in files that make use of the IRCClientChannel class. | |||||
| */ | |||||
| - (void)userJoined:(NSString *)nick; | |||||
| - (void)userParted:(NSString *)nick withReason:(NSData *)reason us:(BOOL)wasItUs; | |||||
| - (void)modeSet:(NSString *)mode withParams:(NSString *)params by:(NSString *)nick; | |||||
| - (void)topicSet:(NSData *)newTopic by:(NSString *)nick; | |||||
| - (void)userKicked:(NSString *)nick withReason:(NSData *)reason by:(NSString *)byNick us:(BOOL)wasItUs; | |||||
| - (void)messageSent:(NSData *)message byUser:(NSString *)nick; | |||||
| - (void)noticeSent:(NSData *)notice byUser:(NSString *)nick; | |||||
| - (void)actionPerformed:(NSData *)action byUser:(NSString *)nick; | |||||
| @end |
| /*! \mainpage IRCClient - a Cocoa IRC Framework to create IRC clients | |||||
| * | |||||
| * \section intro_sec Introduction | |||||
| * | |||||
| * IRCClient is a Cocoa Framework that uses the excellent libircclient library | |||||
| * written by Georgy Yunaev. | |||||
| * | |||||
| * \section usage Basic Usage | |||||
| * | |||||
| * To use this framework, you will need to write an IRCClientSessionDelegate to | |||||
| * handle all of the events generated by the server, and an IRCClientChannelDelegate | |||||
| * to handle all of the events generated by channels on that server. | |||||
| * | |||||
| * You then create an IRCClientSession object in your code, assign the required | |||||
| * properties, and call connect: to connect to the server and run: to create | |||||
| * the new thread and start receiving events. For example: | |||||
| * | |||||
| * \code | |||||
| * IRCClientSession *session = [[IRCClientSession alloc] init]; | |||||
| * MyIRCClientSessionDelegate *controller = [[MyIRCClientSessionDelegate alloc] init]; | |||||
| * | |||||
| * [session setDelegate:controller]; | |||||
| * [controller setSession:session]; | |||||
| * | |||||
| * [session setServer:@"irc.dal.net"]; | |||||
| * [session setPort:@"6667"]; | |||||
| * [session setNickname:@"test"]; | |||||
| * [session setUsername:@"test"]; | |||||
| * [session setRealname:@"test"]; | |||||
| * [session connect]; | |||||
| * | |||||
| * [session run]; //starts the thread | |||||
| * \endcode | |||||
| * | |||||
| * \section author Author, copyright, support. | |||||
| * | |||||
| * If you have any questions, bug reports, suggestions regarding libircclient | |||||
| * or the IRCClient framework, please visit http://libircclient.sourceforge.net | |||||
| * | |||||
| * <PRE> | |||||
| * libircclient Copyright (C) 2004-2009 Georgy Yunaev gyunaev@ulduzsoft.com | |||||
| * Original IRCClient Copyright (C) 2009 Nathan Ollerenshaw chrome@stupendous.net | |||||
| * Modified IRCClient Copyright 2015 Said Achmiz (www.saidachmiz.net) | |||||
| * | |||||
| * This library is free software; you can redistribute it and/or modify it | |||||
| * under the terms of the GNU Lesser General Public License as published by | |||||
| * the Free Software Foundation; either version 2 of the License, or (at your | |||||
| * option) any later version. | |||||
| * | |||||
| * This library is distributed in the hope that it will be useful, but WITHOUT | |||||
| * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |||||
| * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public | |||||
| * License for more details. | |||||
| * </PRE> | |||||
| */ | |||||
| /** | |||||
| * @file IRCClientSession.h | |||||
| * @author Nathan Ollerenshaw | |||||
| * @version 1.0 | |||||
| * @date 01.2009 | |||||
| * @brief Represents a connected IRC Session. | |||||
| */ | |||||
| #import <Cocoa/Cocoa.h> | |||||
| #import "IRCClientSessionDelegate.h" | |||||
| #include "libircclient.h" | |||||
| /** @class IRCClientSession | |||||
| * @brief Represents a connected IRC Session. | |||||
| * | |||||
| * IRCClientSession represents a single connection to an IRC server. On initialising | |||||
| * the object, and setting the delegate, server, port, password, nickname, username and realname | |||||
| * properties, you call the connect: and run: methods to connect to the IRC server | |||||
| * and start a new thread. | |||||
| * | |||||
| * This thread then sends messages back to the main runloop to the IRC server delegate, | |||||
| * or to the IRCClientChannel delegate as required. | |||||
| */ | |||||
| @class IRCClientChannel; | |||||
| #pragma mark IRCClientSession class declaration | |||||
| @interface IRCClientSession : NSObject | |||||
| /************************/ | |||||
| #pragma mark - Properties | |||||
| /************************/ | |||||
| /** delegate to send events to. */ | |||||
| @property (assign) id <IRCClientSessionDelegate> delegate; | |||||
| /** User-defined session ID (for one delegate to keep track of multiple sessions, | |||||
| if desired). | |||||
| */ | |||||
| @property NSUInteger sessionID; | |||||
| /** The version string for the client to send back on CTCP VERSION requests */ | |||||
| @property (copy) NSString *version; | |||||
| /** IRC server to connect to */ | |||||
| @property (copy) NSString *server; | |||||
| /** IRC port to connect to */ | |||||
| @property NSUInteger port; | |||||
| /** Server password to provide on connect (may be left empty or nil) */ | |||||
| @property (copy) NSData *password; | |||||
| /** Nickname of the connected client. Note that setting this after connection will | |||||
| not result in the client renaming on IRC. You need to send a nick: message instead. | |||||
| */ | |||||
| @property (copy) NSString *nickname; | |||||
| /** Username of the connected client. Also known as the ident. | |||||
| Setting this after connection does nothing. | |||||
| */ | |||||
| @property (copy) NSString *username; | |||||
| /** Realname of the connected client. | |||||
| Setting this after connection does nothing. | |||||
| */ | |||||
| @property (copy) NSString *realname; | |||||
| /** An NSDictionary of channels that the client is currently connected to. */ | |||||
| @property (retain, readonly) NSDictionary *channels; | |||||
| /** The default text encoding for messages on this server. | |||||
| This concerns messages received via PRIVMSG and NOTICE, and TOPIC in a channel. | |||||
| It also affects what encoding reasons given for QUIT messages are assumed to be in. | |||||
| You may change this at any time. | |||||
| */ | |||||
| @property (assign) NSStringEncoding encoding; | |||||
| /** returns YES if the server is currently connected successfully, and NO if | |||||
| it is not. */ | |||||
| @property (nonatomic, readonly) bool connected; | |||||
| /***************************/ | |||||
| #pragma mark - Class methods | |||||
| /***************************/ | |||||
| /** Connect to the IRC server. | |||||
| Note that this performs the initial DNS lookup and the TCP connection, so if | |||||
| there are any problems you will be notified via the return code of the message. | |||||
| Look at the libircclient documentation for the different return codes. | |||||
| */ | |||||
| - (int)connect; | |||||
| /** Disconnect from the IRC server. | |||||
| This always works, as it simply shuts down the socket. If you want to disconnect | |||||
| in a friendly way, you should use the quit: message. | |||||
| */ | |||||
| - (void)disconnect; | |||||
| /** Starts a new thread and starts the libircclient runloop, processing events and | |||||
| firing messages back to the main runloop as required. Calling this again will | |||||
| do nothing other than raise a warning in your logs. | |||||
| */ | |||||
| - (void)run; | |||||
| /**************************/ | |||||
| #pragma mark - IRC commands | |||||
| /**************************/ | |||||
| /** Sends a raw message to the IRC server. Please consult rfc1459 for the format | |||||
| of IRC commands. */ | |||||
| - (int)sendRaw:(NSData *)message; | |||||
| /** quits the IRC server with the given reason. On success, an onQuit event will be | |||||
| sent to the IRCClientSessionDelegate with the nickname of the IRC client. | |||||
| */ | |||||
| - (int)quit:(NSData *)reason; | |||||
| /** Joins a channel with a given name and key | |||||
| @param channel the channel to join | |||||
| @param key they key for the channel (may be nil) | |||||
| */ | |||||
| - (int)join:(NSData *)channel key:(NSData *)key; | |||||
| /** lists channels on the IRC server. | |||||
| @param channel a channel name or string to pass to the LIST command. Implementation specific. | |||||
| */ | |||||
| - (int)list:(NSData *)channel; | |||||
| /** sets the user mode for the IRC client | |||||
| @param mode string to set | |||||
| */ | |||||
| - (int)userMode:(NSString *)mode; | |||||
| /** sets the IRC client nickname. On success, an onNick event will be sent to the delegate | |||||
| @param newnick new nickname to set. | |||||
| */ | |||||
| - (int)nick:(NSString *)newnick; | |||||
| /** sends a WHOIS request to the IRC server | |||||
| @param nick nickname of the irc client to whois. | |||||
| */ | |||||
| - (int)whois:(NSString *)nick; | |||||
| /** send a PRIVMSG to another IRC client | |||||
| @param message message to send | |||||
| @param target the other IRC client to send the message to. | |||||
| */ | |||||
| - (int)message:(NSData *)message to:(NSString *)target; | |||||
| /** send a CTCP ACTION to another IRC client | |||||
| @param action the action message to send | |||||
| @param target the nickname of the irc client to send the message to. | |||||
| */ | |||||
| - (int)action:(NSData *)action to:(NSString *)target; | |||||
| /** send a NOTICE to another IRC client | |||||
| @param notice the message text to send | |||||
| @param target the nickname of the irc client to send the notice to. | |||||
| */ | |||||
| - (int)notice:(NSData *)notice to:(NSString *)target; | |||||
| /** send a CTCP request to another IRC client | |||||
| @param request the CTCP request string to send | |||||
| @param target the nickname of the IRC client to send the request to. | |||||
| */ | |||||
| - (int)ctcpRequest:(NSData *)request target:(NSString *)target; | |||||
| /** send a CTCP reply to another IRC client | |||||
| @param reply the CTCP reply string to send | |||||
| @param target the nickname of the IRC client to send the reply to. | |||||
| */ | |||||
| - (int)ctcpReply:(NSData *)reply target:(NSString *)target; | |||||
| @end | |||||
| NSString* getNickFromNickUserHost(NSString *nuh); | |||||
| NSString* getUserFromNickUserHost(NSString *nuh); | |||||
| NSString* getHostFromNickUserHost(NSString *nuh); |
| /* | |||||
| * Modified IRCClient Copyright 2015 Said Achmiz (www.saidachmiz.net) | |||||
| * | |||||
| * Original IRCClient Copyright (C) 2009 Nathan Ollerenshaw chrome@stupendous.net | |||||
| * | |||||
| * This library is free software; you can redistribute it and/or modify it | |||||
| * under the terms of the GNU Lesser General Public License as published by | |||||
| * the Free Software Foundation; either version 2 of the License, or (at your | |||||
| * option) any later version. | |||||
| * | |||||
| * This library is distributed in the hope that it will be useful, but WITHOUT | |||||
| * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |||||
| * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public | |||||
| * License for more details. | |||||
| */ | |||||
| #pragma mark Defines and includes | |||||
| #define IRCCLIENTVERSION "1.0" | |||||
| #import "IRCClientSession.h" | |||||
| #import "IRCClientChannel.h" | |||||
| #import "IRCClientChannel_Private.h" | |||||
| #include "string.h" | |||||
| #pragma mark - Callback function declarations | |||||
| static void onConnect(irc_session_t *session, const char *event, const char *origin, const char **params, unsigned int count); | |||||
| static void onNick(irc_session_t *session, const char *event, const char *origin, const char **params, unsigned int count); | |||||
| static void onQuit(irc_session_t *session, const char *event, const char *origin, const char **params, unsigned int count); | |||||
| static void onJoinChannel(irc_session_t *session, const char *event, const char *origin, const char **params, unsigned int count); | |||||
| static void onPartChannel(irc_session_t *session, const char *event, const char *origin, const char **params, unsigned int count); | |||||
| static void onMode(irc_session_t *session, const char *event, const char *origin, const char **params, unsigned int count); | |||||
| static void onUserMode(irc_session_t *session, const char *event, const char *origin, const char **params, unsigned int count); | |||||
| static void onTopic(irc_session_t *session, const char *event, const char *origin, const char **params, unsigned int count); | |||||
| 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 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 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); | |||||
| static void onCtcpAction(irc_session_t *session, const char *event, const char *origin, const char **params, unsigned int count); | |||||
| static void onUnknownEvent(irc_session_t *session, const char *event, const char *origin, const char **params, unsigned int count); | |||||
| static void onNumericEvent(irc_session_t *session, unsigned int event, const char *origin, const char **params, unsigned int count); | |||||
| #pragma mark - IRCClientSession private category declaration | |||||
| @interface IRCClientSession() | |||||
| { | |||||
| irc_callbacks_t callbacks; | |||||
| irc_session_t *irc_session; | |||||
| NSThread *thread; | |||||
| NSString *version; | |||||
| NSString *server; | |||||
| NSUInteger port; | |||||
| NSData *password; | |||||
| NSString *nickname; | |||||
| NSString *username; | |||||
| NSString *realname; | |||||
| NSMutableDictionary *channels; | |||||
| NSStringEncoding encoding; | |||||
| } | |||||
| @property (nonatomic, retain) NSMutableDictionary *channels; | |||||
| @end | |||||
| #pragma mark - IRCClientSession class implementation | |||||
| @implementation IRCClientSession | |||||
| #pragma mark - Property synthesis | |||||
| @synthesize delegate; | |||||
| @synthesize sessionID; | |||||
| @synthesize version; | |||||
| @synthesize server; | |||||
| @synthesize port; | |||||
| @synthesize password; | |||||
| @synthesize nickname; | |||||
| @synthesize username; | |||||
| @synthesize realname; | |||||
| @synthesize encoding; | |||||
| #pragma mark - Custom accessors | |||||
| -(NSDictionary*)channels | |||||
| { | |||||
| NSDictionary* channelsCopy = [channels copy]; | |||||
| return channelsCopy; | |||||
| } | |||||
| -(void)setChannels:(NSMutableDictionary *)newChannels | |||||
| { | |||||
| channels = newChannels; | |||||
| } | |||||
| - (bool)connected | |||||
| { | |||||
| return irc_is_connected(irc_session); | |||||
| } | |||||
| /************************************/ | |||||
| #pragma mark - Class methods | |||||
| /************************************/ | |||||
| -(instancetype)init | |||||
| { | |||||
| if ((self = [super init])) { | |||||
| callbacks.event_connect = onConnect; | |||||
| callbacks.event_nick = onNick; | |||||
| callbacks.event_quit = onQuit; | |||||
| callbacks.event_join = onJoinChannel; | |||||
| callbacks.event_part = onPartChannel; | |||||
| callbacks.event_mode = onMode; | |||||
| callbacks.event_umode = onUserMode; | |||||
| callbacks.event_topic = onTopic; | |||||
| callbacks.event_kick = onKick; | |||||
| callbacks.event_channel = onChannelPrvmsg; | |||||
| callbacks.event_privmsg = onPrivmsg; | |||||
| callbacks.event_notice = onNotice; | |||||
| callbacks.event_channel_notice = onChannelNotice; | |||||
| callbacks.event_invite = onInvite; | |||||
| callbacks.event_ctcp_req = onCtcpRequest; | |||||
| callbacks.event_ctcp_rep = onCtcpReply; | |||||
| callbacks.event_ctcp_action = onCtcpAction; | |||||
| callbacks.event_unknown = onUnknownEvent; | |||||
| callbacks.event_numeric = onNumericEvent; | |||||
| callbacks.event_dcc_chat_req = NULL; | |||||
| callbacks.event_dcc_send_req = NULL; | |||||
| irc_session = irc_create_session(&callbacks); | |||||
| if (!irc_session) { | |||||
| NSLog(@"Could not create irc_session."); | |||||
| return nil; | |||||
| } | |||||
| // Strip server info from nicks. | |||||
| // irc_option_set(irc_session, LIBIRC_OPTION_STRIPNICKS); | |||||
| irc_set_ctx(irc_session, (__bridge void *)(self)); | |||||
| unsigned int high, low; | |||||
| irc_get_version (&high, &low); | |||||
| version = [NSString stringWithFormat:@"IRCClient Framework v%s (Nathan Ollerenshaw) - libirc v%d.%d (Georgy Yunaev)", IRCCLIENTVERSION, high, low]; | |||||
| channels = [[NSMutableDictionary alloc] init]; | |||||
| } | |||||
| return self; | |||||
| } | |||||
| -(void)dealloc | |||||
| { | |||||
| if (irc_is_connected(irc_session)) | |||||
| NSLog(@"Warning: IRC Session is not disconnected on dealloc"); | |||||
| irc_destroy_session(irc_session); | |||||
| } | |||||
| - (int)connect; | |||||
| { | |||||
| unsigned short sPort = port; | |||||
| return irc_connect(irc_session, server.UTF8String, sPort, (password.length > 0 ? password.bytes : NULL), nickname.UTF8String, username.UTF8String, realname.UTF8String); | |||||
| } | |||||
| - (void)disconnect | |||||
| { | |||||
| irc_disconnect(irc_session); | |||||
| } | |||||
| - (void)startThread | |||||
| { | |||||
| @autoreleasepool { | |||||
| irc_run(irc_session); | |||||
| } | |||||
| } | |||||
| - (void)run | |||||
| { | |||||
| if (thread) { | |||||
| NSLog(@"Thread already running!"); | |||||
| return; | |||||
| } | |||||
| thread = [[NSThread alloc] initWithTarget:self selector:@selector(startThread) object:nil]; | |||||
| [thread start]; | |||||
| } | |||||
| /**************************/ | |||||
| #pragma mark - IRC commands | |||||
| /**************************/ | |||||
| - (int)sendRaw:(NSData *)message | |||||
| { | |||||
| return irc_send_raw(irc_session, message.bytes); | |||||
| } | |||||
| - (int)quit:(NSData *)reason | |||||
| { | |||||
| return irc_cmd_quit(irc_session, reason.bytes); | |||||
| } | |||||
| - (int)join:(NSData *)channel key:(NSData *)key | |||||
| { | |||||
| NSLog(@"Joining %@", channel); | |||||
| if (!key || !key.length > 0) | |||||
| return irc_cmd_join(irc_session, channel.bytes, NULL); | |||||
| return irc_cmd_join(irc_session, channel.bytes, key.bytes); | |||||
| } | |||||
| - (int)list:(NSData *)channel | |||||
| { | |||||
| return irc_cmd_list(irc_session, channel.bytes); | |||||
| } | |||||
| - (int)userMode:(NSString *)mode | |||||
| { | |||||
| return irc_cmd_user_mode(irc_session, mode.UTF8String); | |||||
| } | |||||
| - (int)nick:(NSString *)newnick | |||||
| { | |||||
| return irc_cmd_nick(irc_session, newnick.UTF8String); | |||||
| } | |||||
| - (int)whois:(NSString *)nick | |||||
| { | |||||
| return irc_cmd_whois(irc_session, nick.UTF8String); | |||||
| } | |||||
| - (int)message:(NSData *)message to:(NSString *)target | |||||
| { | |||||
| return irc_cmd_msg(irc_session, target.UTF8String, message.bytes); | |||||
| } | |||||
| - (int)action:(NSData *)action to:(NSString *)target | |||||
| { | |||||
| return irc_cmd_me(irc_session, target.UTF8String, action.bytes); | |||||
| } | |||||
| - (int)notice:(NSData *)notice to:(NSString *)target | |||||
| { | |||||
| return irc_cmd_notice(irc_session, target.UTF8String, notice.bytes); | |||||
| } | |||||
| - (int)ctcpRequest:(NSData *)request target:(NSString *)target | |||||
| { | |||||
| return irc_cmd_ctcp_request(irc_session, target.UTF8String, request.bytes); | |||||
| } | |||||
| - (int)ctcpReply:(NSData *)reply target:(NSString *)target | |||||
| { | |||||
| return irc_cmd_ctcp_reply(irc_session, target.UTF8String, reply.bytes); | |||||
| } | |||||
| /****************************/ | |||||
| #pragma mark - Event handlers | |||||
| /****************************/ | |||||
| - (void)connectionSucceeded | |||||
| { | |||||
| [delegate connectionSucceeded]; | |||||
| } | |||||
| - (void)nickChangedFrom:(NSString *)oldNick to:(NSString *)newNick | |||||
| { | |||||
| if ([nickname isEqualToString:oldNick]) | |||||
| { | |||||
| nickname = newNick; | |||||
| [delegate nickChangedFrom:oldNick to:newNick own:YES]; | |||||
| } | |||||
| else | |||||
| { | |||||
| [delegate nickChangedFrom:oldNick to:newNick own:NO]; | |||||
| } | |||||
| } | |||||
| - (void)userQuit:(NSString *)nick withReason:(NSData *)reason | |||||
| { | |||||
| NSString* reasonString; | |||||
| if(reason) | |||||
| { | |||||
| reasonString = [[NSString alloc] initWithData:reason encoding:encoding]; | |||||
| } | |||||
| [delegate userQuit:nick withReason:reasonString]; | |||||
| } | |||||
| - (void)userJoined:(NSString *)nick channel:(NSData *)channelName | |||||
| { | |||||
| NSString* nickOnly = getNickFromNickUserHost(nick); | |||||
| if ([nickname isEqualToString:nickOnly]) | |||||
| { | |||||
| // We just joined a channel; allocate an IRCClientChannel object and send it | |||||
| // to the main thread. | |||||
| IRCClientChannel* newChannel = [[IRCClientChannel alloc] initWithName:channelName andIRCSession:irc_session]; | |||||
| channels[channelName] = newChannel; | |||||
| [delegate joinedNewChannel:newChannel]; | |||||
| } | |||||
| else | |||||
| { | |||||
| // Someone joined a channel we're on. | |||||
| IRCClientChannel* channel = channels[channelName]; | |||||
| [channel userJoined:nick]; | |||||
| } | |||||
| } | |||||
| - (void)userParted:(NSString *)nick channel:(NSData *)channelName withReason:(NSData *)reason | |||||
| { | |||||
| IRCClientChannel* channel = channels[channelName]; | |||||
| NSString* nickOnly = getNickFromNickUserHost(nick); | |||||
| if ([nickname isEqualToString:nickOnly]) | |||||
| { | |||||
| // We just left a channel; remove it from the channels dict. | |||||
| [channels removeObjectForKey:channelName]; | |||||
| [channel userParted:nick withReason:reason us:YES]; | |||||
| } | |||||
| else | |||||
| { | |||||
| [channel userParted:nick withReason:reason us:NO]; | |||||
| } | |||||
| } | |||||
| - (void)modeSet:(NSString* )mode withParams:(NSString *)params forChannel:(NSData *)channelName by:(NSString *)nick | |||||
| { | |||||
| IRCClientChannel *channel = channels[channelName]; | |||||
| [channel modeSet:mode withParams:params by:nick]; | |||||
| } | |||||
| - (void)modeSet:(NSString *)mode by:(NSString *)nick | |||||
| { | |||||
| [delegate modeSet:mode by:nick]; | |||||
| } | |||||
| - (void)topicSet:(NSData *)newTopic forChannel:(NSData *)channelName by:(NSString *)nick | |||||
| { | |||||
| IRCClientChannel *channel = channels[channelName]; | |||||
| [channel topicSet:newTopic by:nick]; | |||||
| } | |||||
| - (void)userKicked:(NSString *)nick fromChannel:(NSData *)channelName by:(NSString *)byNick withReason:(NSData *)reason | |||||
| { | |||||
| IRCClientChannel* channel = channels[channelName]; | |||||
| if (nick == nil) | |||||
| { | |||||
| // we got kicked from a channel we're on | |||||
| [channels removeObjectForKey:channelName]; | |||||
| [channel userKicked:nickname withReason:reason by:byNick us:YES]; | |||||
| } | |||||
| else | |||||
| { | |||||
| // someone else got booted from a channel we're on | |||||
| [channel userKicked:nick withReason:reason by:byNick us:NO]; | |||||
| } | |||||
| } | |||||
| - (void)messageSent:(NSData *)message toChannel:(NSData *)channelName byUser:(NSString *)nick | |||||
| { | |||||
| IRCClientChannel *channel = channels[channelName]; | |||||
| [channel messageSent:message byUser:nick]; | |||||
| } | |||||
| - (void)privateMessageReceived:(NSData *)message fromUser:(NSString *)nick | |||||
| { | |||||
| NSString* messageString = [[NSString alloc] initWithData:message encoding:encoding]; | |||||
| [delegate privateMessageReceived:messageString fromUser:nick]; | |||||
| } | |||||
| - (void)noticeSent:(NSData *)notice toChannel:(NSData *)channelName byUser:(NSString *)nick | |||||
| { | |||||
| IRCClientChannel *channel = channels[channelName]; | |||||
| [channel noticeSent:notice byUser:nick]; | |||||
| } | |||||
| - (void)privateNoticeReceived:(NSData *)notice fromUser:(NSString *)nick | |||||
| { | |||||
| NSString* noticeString = [[NSString alloc] initWithData:notice encoding:encoding]; | |||||
| [delegate privateNoticeReceived:noticeString fromUser:nick]; | |||||
| } | |||||
| - (void)invitedToChannel:(NSData *)channelName by:(NSString *)nick | |||||
| { | |||||
| [delegate invitedToChannel:channelName by:nick]; | |||||
| } | |||||
| - (void)CTCPRequestReceived:(NSData *)request fromUser:(NSString *)nick | |||||
| { | |||||
| const char* the_nick = getNickFromNickUserHost(nick).UTF8String; | |||||
| const char* the_request = request.bytes; | |||||
| if (strstr(the_request, "PING") == the_request) | |||||
| { | |||||
| irc_cmd_ctcp_reply(irc_session, the_nick, the_request); | |||||
| } | |||||
| else if (!strcmp (the_request, "VERSION")) | |||||
| { | |||||
| irc_cmd_ctcp_reply (irc_session, the_nick, [NSString stringWithFormat:@"VERSION %@", version].UTF8String); | |||||
| } | |||||
| else if (!strcmp (the_request, "FINGER")) | |||||
| { | |||||
| irc_cmd_ctcp_reply (irc_session, the_nick, [NSString stringWithFormat:@"FINGER %@ (%@) Idle 0 seconds", username, realname].UTF8String); | |||||
| } | |||||
| else if (!strcmp (the_request, "TIME")) | |||||
| { | |||||
| irc_cmd_ctcp_reply(irc_session, the_nick, [[NSDate dateWithTimeIntervalSinceNow:0] descriptionWithCalendarFormat:@"TIME %a %b %e %H:%M:%S %Z %Y" timeZone:nil locale:[[NSUserDefaults standardUserDefaults] dictionaryRepresentation]].UTF8String); | |||||
| } | |||||
| else | |||||
| { | |||||
| if ([delegate respondsToSelector:@selector(CTCPRequestReceived:ofType:fromUser:)]) | |||||
| { | |||||
| char* request_string = malloc(request.length); | |||||
| [request getBytes:request_string length:request.length]; | |||||
| char* request_type = strtok(request_string, " "); | |||||
| char* request_body = strtok(NULL, " " ); | |||||
| [delegate CTCPRequestReceived:[NSData dataWithBytes:request_body length:strlen(request_body)+1] ofType:[NSData dataWithBytes:request_type length:strlen(request_type)+1] fromUser:nick]; | |||||
| } | |||||
| } | |||||
| } | |||||
| - (void)CTCPReplyReceived:(NSData *)reply fromUser:(NSString *)nick | |||||
| { | |||||
| [delegate CTCPReplyReceived:reply fromUser:nick]; | |||||
| } | |||||
| - (void)CTCPActionPerformed:(NSData *)action byUser:(NSString *)nick atTarget:(NSData *)target | |||||
| { | |||||
| IRCClientChannel* channel = channels[target]; | |||||
| if(channel != nil) | |||||
| { | |||||
| // An action on a channel we're on | |||||
| [channel actionPerformed:action byUser:nick]; | |||||
| } | |||||
| else | |||||
| { | |||||
| // An action in a private message | |||||
| NSString* actionString = [[NSString alloc] initWithData:action encoding:encoding]; | |||||
| [delegate privateCTCPActionReceived:actionString fromUser:nick]; | |||||
| } | |||||
| } | |||||
| - (void)unknownEventReceived:(NSData *)event from:(NSString *)origin params:(NSArray *)params | |||||
| { | |||||
| [delegate unknownEventReceived:event from:origin params:params]; | |||||
| } | |||||
| -(void)numericEventReceived:(NSUInteger)event from:(NSString *)origin params:(NSArray *)params | |||||
| { | |||||
| [delegate numericEventReceived:event from:origin params:params]; | |||||
| } | |||||
| @end | |||||
| #pragma mark - Useful helper functions | |||||
| NSString* getNickFromNickUserHost(NSString *nuh) | |||||
| { | |||||
| NSArray *nuhArray = [nuh componentsSeparatedByCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@"!@"]]; | |||||
| if (nuhArray.count == 3) | |||||
| { | |||||
| return [NSString stringWithString:nuhArray[0]]; | |||||
| } | |||||
| else | |||||
| { | |||||
| return [NSString stringWithString:nuh]; | |||||
| } | |||||
| } | |||||
| NSString* getUserFromNickUserHost(NSString *nuh) | |||||
| { | |||||
| NSArray *nuhArray = [nuh componentsSeparatedByCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@"!@"]]; | |||||
| if (nuhArray.count == 3) | |||||
| { | |||||
| return [NSString stringWithString:nuhArray[1]]; | |||||
| } | |||||
| else | |||||
| { | |||||
| return nil; | |||||
| } | |||||
| } | |||||
| NSString* getHostFromNickUserHost(NSString *nuh) | |||||
| { | |||||
| NSArray *nuhArray = [nuh componentsSeparatedByCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@"!@"]]; | |||||
| if (nuhArray.count == 3) | |||||
| { | |||||
| return [NSString stringWithString:nuhArray[2]]; | |||||
| } | |||||
| else | |||||
| { | |||||
| return nil; | |||||
| } | |||||
| } | |||||
| /***********************************************/ | |||||
| #pragma mark - Callback function implementations | |||||
| /***********************************************/ | |||||
| /*! | |||||
| * The "on_connect" event is triggered when the client successfully | |||||
| * connects to the server, and could send commands to the server. | |||||
| * No extra params supplied; \a params is 0. | |||||
| */ | |||||
| static void onConnect(irc_session_t *session, const char *event, const char *origin, const char **params, unsigned int count) | |||||
| { | |||||
| IRCClientSession* clientSession = (__bridge IRCClientSession *) irc_get_ctx(session); | |||||
| [clientSession connectionSucceeded]; | |||||
| } | |||||
| /*! | |||||
| * The "nick" event is triggered when the client receives a NICK message, | |||||
| * meaning that someone (including you) on a channel with the client has | |||||
| * changed their nickname. | |||||
| * | |||||
| * \param origin the person, who changes the nick. Note that it can be you! | |||||
| * \param params[0] mandatory, contains the new nick. | |||||
| */ | |||||
| static void onNick(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 *oldNick = @(origin); | |||||
| NSString *newNick = @(params[0]); | |||||
| [clientSession nickChangedFrom:oldNick to:newNick]; | |||||
| } | |||||
| /*! | |||||
| * The "quit" event is triggered upon receipt of a QUIT message, which | |||||
| * means that someone on a channel with the client has disconnected. | |||||
| * | |||||
| * \param origin the person, who is disconnected | |||||
| * \param params[0] optional, contains the reason message (user-specified). | |||||
| */ | |||||
| static void onQuit(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 *nick = @(origin); | |||||
| NSData *reason = nil; | |||||
| if(count > 0) | |||||
| { | |||||
| reason = [[NSData alloc] initWithBytes:params[0] length:strlen(params[0])]; | |||||
| } | |||||
| [clientSession userQuit:nick withReason:reason]; | |||||
| } | |||||
| /*! | |||||
| * The "join" event is triggered upon receipt of a JOIN message, which | |||||
| * means that someone has entered a channel that the client is on. | |||||
| * | |||||
| * \param origin the person, who joins the channel. By comparing it with | |||||
| * your own nickname, you can check whether your JOIN | |||||
| * command succeed. | |||||
| * \param params[0] mandatory, contains the channel name. | |||||
| */ | |||||
| static void onJoinChannel(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 *nick = @(origin); | |||||
| NSData *channelName = [NSData dataWithBytes:params[0] length:strlen(params[0])]; | |||||
| [clientSession userJoined:nick channel:channelName]; | |||||
| } | |||||
| /*! | |||||
| * The "part" event is triggered upon receipt of a PART message, which | |||||
| * means that someone has left a channel that the client is on. | |||||
| * | |||||
| * \param origin the person, who leaves the channel. By comparing it with | |||||
| * your own nickname, you can check whether your PART | |||||
| * command succeed. | |||||
| * \param params[0] mandatory, contains the channel name. | |||||
| * \param params[1] optional, contains the reason message (user-defined). | |||||
| */ | |||||
| static void onPartChannel(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 *nick = @(origin); | |||||
| NSData *channelName = [NSData dataWithBytes:params[0] length:strlen(params[0])]; | |||||
| NSData *reason = nil; | |||||
| if (count > 1) | |||||
| { | |||||
| reason = [NSData dataWithBytes:params[1] length:strlen(params[1])+1]; | |||||
| } | |||||
| [clientSession userParted:nick channel:channelName withReason:reason]; | |||||
| } | |||||
| /*! | |||||
| * The "mode" event is triggered upon receipt of a channel MODE message, | |||||
| * which means that someone on a channel with the client has changed the | |||||
| * channel's parameters. | |||||
| * | |||||
| * \param origin the person, who changed the channel mode. | |||||
| * \param params[0] mandatory, contains the channel name. | |||||
| * \param params[1] mandatory, contains the changed channel mode, like | |||||
| * '+t', '-i' and so on. | |||||
| * \param params[2] optional, contains the mode argument (for example, a | |||||
| * key for +k mode, or user who got the channel operator status for | |||||
| * +o mode) | |||||
| */ | |||||
| static void onMode(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 *nick = @(origin); | |||||
| NSData *channelName = [NSData dataWithBytes:params[0] length:strlen(params[0])]; | |||||
| NSString *mode = @(params[1]); | |||||
| NSString *modeParams = nil; | |||||
| if (count > 2) | |||||
| { | |||||
| modeParams = @(params[2]); | |||||
| } | |||||
| [clientSession modeSet:mode withParams:modeParams forChannel:channelName by:nick]; | |||||
| } | |||||
| /*! | |||||
| * The "umode" event is triggered upon receipt of a user MODE message, | |||||
| * which means that your user mode has been changed. | |||||
| * | |||||
| * \param origin the person, who changed the channel mode. | |||||
| * \param params[0] mandatory, contains the user changed mode, like | |||||
| * '+t', '-i' and so on. | |||||
| */ | |||||
| static void onUserMode(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* nick = @(origin); | |||||
| NSString *mode = @(params[0]); | |||||
| [clientSession modeSet:mode by:nick]; | |||||
| } | |||||
| /*! | |||||
| * The "topic" event is triggered upon receipt of a TOPIC message, which | |||||
| * means that someone on a channel with the client has changed the | |||||
| * channel's topic. | |||||
| * | |||||
| * \param origin the person, who changes the channel topic. | |||||
| * \param params[0] mandatory, contains the channel name. | |||||
| * \param params[1] optional, contains the new topic. | |||||
| */ | |||||
| static void onTopic(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 *nick = @(origin); | |||||
| NSData *channelName = [NSData dataWithBytes:params[0] length:strlen(params[0])]; | |||||
| NSData *topic = nil; | |||||
| if (count > 1) | |||||
| { | |||||
| topic = [NSData dataWithBytes:params[1] length:strlen(params[1])]; | |||||
| } | |||||
| [clientSession topicSet:topic forChannel:channelName by:nick]; | |||||
| } | |||||
| /*! | |||||
| * The "kick" event is triggered upon receipt of a KICK message, which | |||||
| * means that someone on a channel with the client (or possibly the | |||||
| * client itself!) has been forcibly ejected. | |||||
| * | |||||
| * \param origin the person, who kicked the poor. | |||||
| * \param params[0] mandatory, contains the channel name. | |||||
| * \param params[1] optional, contains the nick of kicked person. | |||||
| * \param params[2] optional, contains the kick text | |||||
| */ | |||||
| static void onKick(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 *byNick = @(origin); | |||||
| NSData *channelName = [NSData dataWithBytes:params[0] length:strlen(params[0])]; | |||||
| NSString *nick = nil; | |||||
| NSData *reason = nil; | |||||
| if (count > 1) | |||||
| { | |||||
| nick = @(params[1]); | |||||
| } | |||||
| if (count > 2) | |||||
| { | |||||
| reason = [NSData dataWithBytes:params[2] length:strlen(params[2])]; | |||||
| } | |||||
| [clientSession userKicked:nick fromChannel:channelName by:byNick withReason:reason]; | |||||
| } | |||||
| /*! | |||||
| * The "channel" event is triggered upon receipt of a PRIVMSG message | |||||
| * to an entire channel, which means that someone on a channel with | |||||
| * the client has said something aloud. Your own messages don't trigger | |||||
| * PRIVMSG event. | |||||
| * | |||||
| * \param origin the person, who generates the message. | |||||
| * \param params[0] mandatory, contains the channel name. | |||||
| * \param params[1] optional, contains the message text | |||||
| */ | |||||
| static void onChannelPrvmsg(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 *nick = @(origin); | |||||
| NSData *channelName = [NSData dataWithBytes:params[0] length:strlen(params[0])]; | |||||
| NSData *message = nil; | |||||
| if (count > 1) | |||||
| { | |||||
| message = [NSData dataWithBytes:params[1] length:strlen(params[1])]; | |||||
| } | |||||
| NSLog(@"onChannelPrvmsg"); | |||||
| [clientSession messageSent:message toChannel:channelName byUser:nick]; | |||||
| } | |||||
| /*! | |||||
| * The "privmsg" event is triggered upon receipt of a PRIVMSG message | |||||
| * which is addressed to one or more clients, which means that someone | |||||
| * is sending the client a private message. | |||||
| * | |||||
| * \param origin the person, who generates the message. | |||||
| * \param params[0] mandatory, contains your nick. | |||||
| * \param params[1] optional, contains the message text | |||||
| */ | |||||
| static void onPrivmsg(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 *nick = @(origin); | |||||
| NSData *message = nil; | |||||
| if (count > 1) | |||||
| { | |||||
| message = [NSData dataWithBytes:params[1] length:strlen(params[1])]; | |||||
| } | |||||
| [clientSession privateMessageReceived:message fromUser:nick]; | |||||
| } | |||||
| /*! | |||||
| * The "notice" event is triggered upon receipt of a NOTICE message | |||||
| * which means that someone has sent the client a public or private | |||||
| * notice. 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[0] mandatory, contains your nick. | |||||
| * \param params[1] optional, contains the message text | |||||
| */ | |||||
| static void onNotice(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 *nick = @(origin); | |||||
| NSData *notice = nil; | |||||
| if (count > 1) | |||||
| { | |||||
| notice = [NSData dataWithBytes:params[1] length:strlen(params[1])]; | |||||
| } | |||||
| [clientSession privateNoticeReceived:notice fromUser:nick]; | |||||
| } | |||||
| /*! | |||||
| * The "notice" event is triggered upon receipt of a NOTICE message | |||||
| * which means that someone has sent the client a public or private | |||||
| * notice. 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[0] mandatory, contains the target channel name. | |||||
| * \param params[1] optional, contains the message text. | |||||
| */ | |||||
| static void onChannelNotice(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 *nick = @(origin); | |||||
| NSData *channelName = [NSData dataWithBytes:params[0] length:strlen(params[0])]; | |||||
| NSData *notice = nil; | |||||
| if (count > 1) | |||||
| { | |||||
| notice = [NSData dataWithBytes:params[1] length:strlen(params[1])]; | |||||
| } | |||||
| [clientSession noticeSent:notice toChannel:channelName byUser:nick]; | |||||
| } | |||||
| /*! | |||||
| * The "invite" event is triggered upon receipt of an INVITE message, | |||||
| * which means that someone is permitting the client's entry into a +i | |||||
| * channel. | |||||
| * | |||||
| * \param origin the person, who INVITEs you. | |||||
| * \param params[0] mandatory, contains your nick. | |||||
| * \param params[1] mandatory, contains the channel name you're invited into. | |||||
| * | |||||
| * \sa irc_cmd_invite irc_cmd_chanmode_invite | |||||
| */ | |||||
| static void onInvite(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 *nick = @(origin); | |||||
| NSData *channelName = [NSData dataWithBytes:params[1] length:strlen(params[1])]; | |||||
| [clientSession invitedToChannel:channelName by:nick]; | |||||
| } | |||||
| /*! | |||||
| * The "ctcp" event is triggered when the client receives the CTCP | |||||
| * request. By default, the built-in CTCP request handler is used. The | |||||
| * build-in handler automatically replies on most CTCP messages, so you | |||||
| * will rarely need to override it. | |||||
| * | |||||
| * \param origin the person, who generates the message. | |||||
| * \param params[0] mandatory, the complete CTCP message, including its | |||||
| * arguments. | |||||
| * | |||||
| * Mirc generates PING, FINGER, VERSION, TIME and ACTION messages, | |||||
| * check the source code of \c libirc_event_ctcp_internal function to | |||||
| * see how to write your own CTCP request handler. Also you may find | |||||
| * useful this question in FAQ: \ref faq4 | |||||
| */ | |||||
| static void onCtcpRequest(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 *nick = @(origin); | |||||
| NSData* request = [NSData dataWithBytes:params[0] length:strlen(params[0])]; | |||||
| [clientSession CTCPRequestReceived:request fromUser:nick]; | |||||
| } | |||||
| /*! | |||||
| * The "ctcp" event is triggered when the client receives the CTCP reply. | |||||
| * | |||||
| * \param origin the person, who generates the message. | |||||
| * \param params[0] mandatory, the CTCP message itself with its arguments. | |||||
| */ | |||||
| static void onCtcpReply(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 *nick = @(origin); | |||||
| NSData *reply = [NSData dataWithBytes:params[0] length:strlen(params[0])]; | |||||
| [clientSession CTCPReplyReceived:reply fromUser:nick]; | |||||
| } | |||||
| /*! | |||||
| * The "action" event is triggered when the client receives the CTCP | |||||
| * ACTION message. These messages usually looks like:\n | |||||
| * \code | |||||
| * [23:32:55] * Tim gonna sleep. | |||||
| * \endcode | |||||
| * | |||||
| * \param origin the person, who generates the message. | |||||
| * \param params[0] mandatory, the target of the message. | |||||
| * \param params[1] mandatory, the ACTION message. | |||||
| */ | |||||
| static void onCtcpAction(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 *nick = @(origin); | |||||
| NSData *target = [NSData dataWithBytes:params[0] length:strlen(params[0])]; | |||||
| NSData *action = [NSData dataWithBytes:params[1] length:strlen(params[1])]; | |||||
| [clientSession CTCPActionPerformed:action byUser:nick atTarget:target]; | |||||
| } | |||||
| /*! | |||||
| * The "unknown" event is triggered upon receipt of any number of | |||||
| * unclassifiable miscellaneous messages, which aren't handled by the | |||||
| * library. | |||||
| */ | |||||
| static void onUnknownEvent(irc_session_t *session, const char *event, const char *origin, const char **params, unsigned int count) | |||||
| { | |||||
| IRCClientSession *clientSession = (__bridge IRCClientSession *) irc_get_ctx(session); | |||||
| NSData *eventString = [NSData dataWithBytes:event length:strlen(event)]; | |||||
| NSString *sender = nil; | |||||
| if (origin != NULL) | |||||
| 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])]]; | |||||
| [clientSession unknownEventReceived:eventString from:sender params:[paramsArray copy]]; | |||||
| } | |||||
| /*! | |||||
| * The "numeric" event is triggered upon receipt of any numeric response | |||||
| * from the server. There is a lot of such responses, see the full list | |||||
| * here: \ref rfcnumbers. | |||||
| * | |||||
| * See the params in ::irc_eventcode_callback_t specification. | |||||
| */ | |||||
| static void onNumericEvent(irc_session_t * session, unsigned int event, const char * origin, const char ** params, unsigned int count) | |||||
| { | |||||
| IRCClientSession *clientSession = (__bridge IRCClientSession *) irc_get_ctx(session); | |||||
| NSUInteger eventNumber = event; | |||||
| 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])]]; | |||||
| [clientSession numericEventReceived:eventNumber from:sender params:[paramsArray copy]]; | |||||
| } |
| /* | |||||
| * Modified IRCClient Copyright 2015 Said Achmiz (www.saidachmiz.net) | |||||
| * | |||||
| * Original IRCClient Copyright (C) 2009 Nathan Ollerenshaw chrome@stupendous.net | |||||
| * | |||||
| * This library is free software; you can redistribute it and/or modify it | |||||
| * under the terms of the GNU Lesser General Public License as published by | |||||
| * the Free Software Foundation; either version 2 of the License, or (at your | |||||
| * option) any later version. | |||||
| * | |||||
| * This library is distributed in the hope that it will be useful, but WITHOUT | |||||
| * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |||||
| * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public | |||||
| * License for more details. | |||||
| */ | |||||
| #import <Cocoa/Cocoa.h> | |||||
| #include "libircclient.h" | |||||
| /** | |||||
| * @file IRCClientSessionDelegate.h | |||||
| * @author Nathan Ollerenshaw | |||||
| * @version 1.0 | |||||
| * @date 01.2009 | |||||
| * @brief Receives delegate messages from an IRCClientSession. | |||||
| * @protocol IRCClientSessionDelegate | |||||
| */ | |||||
| @class IRCClientChannel; | |||||
| /** @brief Receives delegate messages from an IRCClientSession. | |||||
| * | |||||
| * Each IRCClientSession object needs a single delegate. Methods are called | |||||
| * for each event that occurs on an IRC server that the client is connected to. | |||||
| * | |||||
| * Note that for any given parameter, it may be optional, in which case a nil | |||||
| * object may be supplied instead of the given parameter. | |||||
| */ | |||||
| @protocol IRCClientSessionDelegate <NSObject> | |||||
| /** The client has successfully connected to the IRC server. */ | |||||
| - (void)connectionSucceeded; | |||||
| /** An IRC client on a channel that this client is connected to has changed nickname, | |||||
| * or this IRC client has changed nicknames. | |||||
| * | |||||
| * @param nick the new nickname | |||||
| * @param oldNick the old nickname | |||||
| * @param wasItUs did our nick change, or someone else's? | |||||
| */ | |||||
| - (void)nickChangedFrom:(NSString *)oldNick to:(NSString *)newNick own:(BOOL)wasItUs; | |||||
| /** An IRC client on a channel that this client is connected to has quit IRC. | |||||
| * | |||||
| * @param nick the nickname of the client that quit. | |||||
| * @param reason (optional) the quit message, if any. | |||||
| */ | |||||
| - (void)userQuit:(NSString *)nick withReason:(NSString *)reason; | |||||
| /** The IRC client has joined (connected) successfully to a new channel. This | |||||
| * event creates an IRCClientChannel object, which you are expected to assign a | |||||
| * delegate to, to handle events from the channel. | |||||
| * | |||||
| * For example, on receipt of this message, a graphical IRC client would most | |||||
| * likely open a new window, create an IRCClientChannelDelegate for the window, | |||||
| * set the new IRCClientChannel's delegate to the new delegate, and then hook | |||||
| * it up so that new events sent to the IRCClientChannelDelegate are sent to | |||||
| * the window. | |||||
| * | |||||
| * @param channel the IRCClientChannel object for the newly joined channel. | |||||
| */ | |||||
| - (void)joinedNewChannel:(IRCClientChannel *)channel; | |||||
| /** The client has changed it's user mode. | |||||
| * | |||||
| * @param mode the new mode. | |||||
| */ | |||||
| - (void)modeSet:(NSString *)mode by:(NSString *)nick; | |||||
| /** The client has received a private PRIVMSG from another IRC client. | |||||
| * | |||||
| * @param message the text of the message | |||||
| * @param nick the other IRC Client that sent the message. | |||||
| */ | |||||
| - (void)privateMessageReceived:(NSString *)message fromUser:(NSString *)nick; | |||||
| /** The client has received a private NOTICE from another client. | |||||
| * | |||||
| * @param notice the text of the message | |||||
| * @param nick the nickname of the other IRC client that sent the message. | |||||
| */ | |||||
| - (void)privateNoticeReceived:(NSString *)notice fromUser:(NSString *)nick; | |||||
| /** The IRC client has been invited to a channel. | |||||
| * | |||||
| * Note that the name is provided as an NSData object, because we have no idea | |||||
| * what encoding the channel name is in (it needn't be the same as used by e.g. | |||||
| * server messages, etc.), and it's important to attempt to join *exactly* the | |||||
| * channel you're being invited to, byte for byte, otherwise you might end up | |||||
| * joining the wrong channel. You should convert the name to an NSString for | |||||
| * display (using the encoding set for the server is probably a sane default) | |||||
| * but be aware that you might be displaying entirely wrong characters and are | |||||
| * not gauranteed that the channel name will look right - only that it will be | |||||
| * actually be the right name, internally. | |||||
| * | |||||
| * @param channel the channel for the invitation. | |||||
| * @param nick the nickname of the user that sent the invitation. | |||||
| */ | |||||
| - (void)invitedToChannel:(NSData *)channelName by:(NSString *)nick; | |||||
| /** A private CTCP request was sent to the IRC client. | |||||
| * | |||||
| * @param request the CTCP request string (after the type) | |||||
| * @param type the CTCP request type | |||||
| * @param nick the nickname of the user that sent the request. | |||||
| */ | |||||
| - (void)CTCPRequestReceived:(NSData *)request ofType:(NSData *)type fromUser:(NSString *)nick; | |||||
| /** A private CTCP reply was sent to the IRC client. | |||||
| * | |||||
| * @param reply an NSData containing the raw C string of the reply. | |||||
| * @param nick the nickname of the user that sent the reply. | |||||
| */ | |||||
| - (void)CTCPReplyReceived:(NSData *)reply fromUser:(NSString *)nick; | |||||
| /** A private CTCP ACTION was sent to the IRC client. | |||||
| * | |||||
| * CTCP ACTION is not limited to channels; it may also be sent directly to other users. | |||||
| * | |||||
| * @param action the action message text. | |||||
| * @param nick the nickname of the client that sent the action. | |||||
| */ | |||||
| - (void)privateCTCPActionReceived:(NSString *)action fromUser:(NSString *)nick; | |||||
| /** An unhandled event was received from the IRC server. | |||||
| * | |||||
| * @param event the unknown event name | |||||
| * @param origin the sender of the event | |||||
| * @param params an NSArray of NSData objects that are the raw C strings of the event. | |||||
| */ | |||||
| - (void)unknownEventReceived:(NSData *)event from:(NSString *)origin params:(NSArray *)params; | |||||
| /** An unhandled numeric was received from the IRC server | |||||
| * | |||||
| * @param event the unknown event number | |||||
| * @param origin the sender of the event | |||||
| * @param params an NSArray of NSData objects that are the raw C strings of the event. | |||||
| */ | |||||
| - (void)numericEventReceived:(NSUInteger)event from:(NSString *)origin params:(NSArray *)params; | |||||
| @end |
| <key>CFBundleVersion</key> | <key>CFBundleVersion</key> | ||||
| <string>$(CURRENT_PROJECT_VERSION)</string> | <string>$(CURRENT_PROJECT_VERSION)</string> | ||||
| <key>NSHumanReadableCopyright</key> | <key>NSHumanReadableCopyright</key> | ||||
| <string>Copyright © 2015 Said Achmiz. All rights reserved.</string> | |||||
| <string>Copyright © 2015 Said Achmiz.</string> | |||||
| <key>NSPrincipalClass</key> | <key>NSPrincipalClass</key> | ||||
| <string></string> | <string></string> | ||||
| </dict> | </dict> |