浏览代码

Updated info comments, README.md, and LICENSE

master
achmizs 4 年前
父节点
当前提交
8749e525a5

+ 5
- 16
IRCClient.h 查看文件

// //
// IRCClient.h // IRCClient.h
// IRCClient
// //
/*
* 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.
*/
// Modified IRCClient Copyright 2015-2021 Said Achmiz.
// Original IRCClient Copyright 2009 Nathan Ollerenshaw.
// libircclient Copyright 2004-2009 Georgy Yunaev.
//
// See LICENSE and README.md for more info.


#ifndef IRCCLIENT #ifndef IRCCLIENT
#define IRCCLIENT #define IRCCLIENT

+ 35
- 42
IRCClient/IRCClientChannel.h 查看文件

// //
// IRCClientChannel.h // IRCClientChannel.h
// IRCClient
/*
* Copyright 2015 Said Achmiz (www.saidachmiz.net)
*
* 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.
*/
//
// Modified IRCClient Copyright 2015-2021 Said Achmiz.
// Original IRCClient Copyright 2009 Nathan Ollerenshaw.
// libircclient Copyright 2004-2009 Georgy Yunaev.
//
// See LICENSE and README.md for more info.


#import <Foundation/Foundation.h> #import <Foundation/Foundation.h>
#import "IRCClientChannelDelegate.h" #import "IRCClientChannelDelegate.h"
#pragma mark - Properties #pragma mark - Properties
/************************/ /************************/


/** Delegate to send events to */
/** Delegate to send events to. */
@property (assign) id <IRCClientChannelDelegate> delegate; @property (assign) id <IRCClientChannelDelegate> delegate;


/** Associated session */
/** Associated session. */
@property (readonly) IRCClientSession *session; @property (readonly) IRCClientSession *session;


/** Name of the channel */
/** Name of the channel. */
@property (readonly) NSData *name; @property (readonly) NSData *name;


/** Encoding used by, and in, this channel */
/** Encoding used by, and in, this channel. */
@property (assign) NSStringEncoding encoding; @property (assign) NSStringEncoding encoding;


/** Topic of the channel /** Topic of the channel
* *
* You can (attempt to) set the topic by using setChannelTopic:, not by
* You can (attempt to) set the topic by using -[setChannelTopic:], not by
* changing this property (which is readonly). If the connected user has the * 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 * 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).
* -[topicSet:forChannel:by:] message (and the topic property of the channel
* object will be updated automatically).
*/ */
@property (readonly) NSData *topic; @property (readonly) NSData *topic;


/** Modes of the channel */
/** Modes of the channel. */
@property (readonly) NSData *modes; @property (readonly) NSData *modes;


/** An array of nicknames stored as NSData objects that list the connected users /** An array of nicknames stored as NSData objects that list the connected users
for the channel */
for the channel. */
@property (readonly) NSArray *nicks; @property (readonly) NSArray *nicks;


/** Stores arbitrary user info. */ /** Stores arbitrary user info. */


/** Invites another IRC client to the channel. /** Invites another IRC client to the channel.
* *
* @param nick the nickname of the client to invite.
* @param nick The nickname of the client to invite.
*/ */
-(int) invite:(NSData *)nick; -(int) invite:(NSData *)nick;


/** Sets the topic of the channel. /** 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 a topicSet:by: event on the IRCClientChannelDelegate.
* 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
* a -[topicSet:forChannel:by:] event on the IRCClientChannelDelegate.
* *
* @param aTopic the topic the client wishes to set for the channel.
* @param aTopic The topic the client wishes to set for the channel.
*/ */
-(int) setChannelTopic:(NSData *)newTopic; -(int) setChannelTopic:(NSData *)newTopic;


/** Sets the mode of the channel. /** 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:withParams:by: event on the IRCClientChannelDelegate.
* 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:forChannel:withParams:by:] event on the IRCClientChannelDelegate.
* *
* @param mode the mode to set the channel to
* @param mode The mode to set the channel to.
*/ */
-(int) setMode:(NSData *)mode -(int) setMode:(NSData *)mode
params:(NSData *)params; params:(NSData *)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.
/** 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.
@param message The message to send to the channel.
*/ */
-(int) message:(NSData *)message; -(int) message:(NSData *)message;


/** Sends a public CTCP ACTION to the channel. /** Sends a public CTCP ACTION to the channel.
* *
* @param action action to send to the channel.
* @param action Action to send to the channel.
*/ */
-(int) action:(NSData *)action; -(int) action:(NSData *)action;


/** Sends a public NOTICE to the channel. /** Sends a public NOTICE to the channel.
* *
* @param notice message to send to the channel.
* @param notice Message to send to the channel.
*/ */
-(int) notice:(NSData *)notice; -(int) notice:(NSData *)notice;


/** Kicks someone from a channel. /** 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.
* @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:(NSData *)nick -(int) kick:(NSData *)nick
reason:(NSData *)reason; reason:(NSData *)reason;


/** Sends a CTCP request to the channel. /** 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.
* 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.
* @param request The string of the request, in CTCP format.
*/ */
-(int) ctcpRequest:(NSData *)request; -(int) ctcpRequest:(NSData *)request;



+ 6
- 16
IRCClient/IRCClientChannel.m 查看文件

// //
// IRCClientChannel.m // IRCClientChannel.m
// IRCClient
/*
* Copyright 2015 Said Achmiz (www.saidachmiz.net)
*
* 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.
*/
//
// Modified IRCClient Copyright 2015-2021 Said Achmiz.
// Original IRCClient Copyright 2009 Nathan Ollerenshaw.
// libircclient Copyright 2004-2009 Georgy Yunaev.
//
// See LICENSE and README.md for more info.


#import "IRCClientChannel.h" #import "IRCClientChannel.h"
#import "IRCClientChannel_Private.h" #import "IRCClientChannel_Private.h"

+ 19
- 29
IRCClient/IRCClientChannelDelegate.h 查看文件

// //
// IRCClientChannelDelegate.h // IRCClientChannelDelegate.h
// IRCClient
/*
* Copyright 2015 Said Achmiz (www.saidachmiz.net)
*
* 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.
*/
//
// Modified IRCClient Copyright 2015-2021 Said Achmiz.
// Original IRCClient Copyright 2009 Nathan Ollerenshaw.
// libircclient Copyright 2004-2009 Georgy Yunaev.
//
// See LICENSE and README.md for more info.


#import <Foundation/Foundation.h> #import <Foundation/Foundation.h>


* nickname, depending on the server implementation. * nickname, depending on the server implementation.
* *
* You should also expect to see this event when the client first joins a channel, * You should also expect to see this event when the client first joins a channel,
* with a parameter of the client's nickname.
* with a parameter of the clients nickname.
* *
* @param nick The nickname of the user that joined the channel. * @param nick The nickname of the user that joined the channel.
*/ */
/** Received when an IRC client changes the channel mode. What modes are available /** Received when an IRC client changes the channel mode. What modes are available
* for a given channel is an implementation detail for each server. * 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.
* @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:(NSData *)mode -(void) modeSet:(NSData *)mode
forChannel:(IRCClientChannel *)session forChannel:(IRCClientChannel *)session


/** Received when an IRC client is kicked from a channel. /** 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 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? * @param wasItUs Was it us who got kicked, or another user?
*/ */
-(void) userKicked:(NSData *)nick -(void) userKicked:(NSData *)nick
* user may not necessarily be required to be on the channel to send a message * user may not necessarily be required to be on the channel to send a message
* to it. * to it.
* *
* @param message the message sent to the channel.
* @param nick the nickname of the IRC client that sent the message.
* @param message The message sent to the channel.
* @param nick The nickname of the IRC client that sent the message.
*/ */
-(void) messageSent:(NSData *)message -(void) messageSent:(NSData *)message
byUser:(NSData *)nick byUser:(NSData *)nick
* it. Furthermore, the RFC states that the only difference between PRIVMSG and * it. Furthermore, the RFC states that the only difference between PRIVMSG and
* NOTICE is that a NOTICE may never be responded to automatically. * 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.
* @param notice The notice sent to the channel.
* @param nick The nickname of the IRC client that sent the notice.
*/ */
-(void) noticeSent:(NSData *)notice -(void) noticeSent:(NSData *)notice
byUser:(NSData *)nick byUser:(NSData *)nick


/** Received when an IRC client sends a CTCP ACTION message to the channel. /** 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.
* @param action The action message sent to the channel.
* @param nick The nickname of the IRC client that sent the message.
*/ */
-(void) actionPerformed:(NSData *)action -(void) actionPerformed:(NSData *)action
byUser:(NSData *)nick byUser:(NSData *)nick

+ 6
- 14
IRCClient/IRCClientChannel_Private.h 查看文件

// //
// IRCClientChannel_Private.h // IRCClientChannel_Private.h
// 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.
*/
//
// Modified IRCClient Copyright 2015-2021 Said Achmiz.
// Original IRCClient Copyright 2009 Nathan Ollerenshaw.
// libircclient Copyright 2004-2009 Georgy Yunaev.
//
// See LICENSE and README.md for more info.


#import "IRCClientChannel.h" #import "IRCClientChannel.h"
#include "libircclient.h" #include "libircclient.h"

+ 56
- 101
IRCClient/IRCClientSession.h 查看文件

// //
// IRCClientSession.h // IRCClientSession.h
// IRCClient
/*! \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.delegate = controller;
* controller.session = session;
*
* session.server = @"chat.freenode.net".dataAsUTF8];
* session.port = 6665;
* [session setNickname:@"test".dataAsUTF8 username:@"test".dataAsUTF8 realname:@"test".dataAsUTF8];
* [session connect];
*
* [session run]; //starts the thread
* \endcode
*
* \section author Author, copyright, support.
*
* If you have questions, bug reports, or suggestions regarding IRCClient,
* find Obormot on the Freenode IRC network.
*
* If you have any questions, bug reports, suggestions regarding libircclient,
* 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>
*/
//
// Modified IRCClient Copyright 2015-2021 Said Achmiz.
// Original IRCClient Copyright 2009 Nathan Ollerenshaw.
// libircclient Copyright 2004-2009 Georgy Yunaev.
//
// See LICENSE and README.md for more info.


#import <Foundation/Foundation.h> #import <Foundation/Foundation.h>
#import "IRCClientSessionDelegate.h" #import "IRCClientSessionDelegate.h"
* the object, setting the delegate, server, port, and password (if required) * the object, setting the delegate, server, port, and password (if required)
* properties, and setting the nickname, username and realname using the * properties, and setting the nickname, username and realname using the
* setNickname:username:realname: method, you call the connect: and run: methods * setNickname:username:realname: method, you call the connect: and run: methods
* to connect to the IRC server and start a new thread.
* to connect to the IRC server and place the connection on a new event queue.
* *
* This thread then sends messages to the IRC server delegate, * This thread then sends messages to the IRC server delegate,
* or to the IRCClientChannel delegate, as required. * or to the IRCClientChannel delegate, as required.


@interface IRCClientSession : NSObject @interface IRCClientSession : NSObject


/******************************/
#pragma mark - Class properties
/******************************/

/** Returns a dictionary of IRC numeric codes.

The dictionary contains entries for all known IRC numeric codes (as keys).
(The list is taken from https://www.alien.net.au/irc/irc2numerics.html .)

The value for each key is an NSArray with the known numeric reply names for
which the numeric code is used.

Note that there is no guarantee whatsoever that any given numeric reply
name will, in fact, describe the contents of the message; most IRC numeric
messages have implementation-specific uses. See the various RFCs, and other
info sources, for details.
*/
@property (class, nonatomic, readonly) NSDictionary <NSString *, NSDictionary *> *ircNumericCodes;

/************************/ /************************/
#pragma mark - Properties #pragma mark - Properties
/************************/ /************************/


/** delegate to send events to. */
/** Delegate to send events to. */
@property (assign) id <IRCClientSessionDelegate> delegate; @property (assign) id <IRCClientSessionDelegate> delegate;


/** The version string for the client to send back on CTCP VERSION requests. /** The version string for the client to send back on CTCP VERSION requests.
*/ */
@property (copy, nonatomic) NSData *version; @property (copy, nonatomic) NSData *version;


/** IRC server to connect to */
/** IRC server to connect to. */
@property (copy, nonatomic) NSData *server; @property (copy, nonatomic) NSData *server;


/** IRC port to connect to */
/** IRC port to connect to. */
@property (assign) NSUInteger port; @property (assign) NSUInteger port;


/** Server password to provide on connect (may be left empty or nil) */
/** Server password to provide on connect (may be left empty or nil). */
@property (copy, nonatomic) NSData *password; @property (copy, nonatomic) NSData *password;


/** Nickname of the connected client. /** Nickname of the connected client.
/** Stores arbitrary user info. */ /** Stores arbitrary user info. */
@property (nonatomic, readonly) NSMutableDictionary *userInfo; @property (nonatomic, readonly) NSMutableDictionary *userInfo;


/** Returns a dictionary of IRC numeric codes.

The dictionary contains entries for all known IRC numeric codes (as keys).
(The list is taken from https://www.alien.net.au/irc/irc2numerics.html .)

The value for each key is an NSArray with the known numeric reply names for
which the numeric code is used.

Note that there is no guarantee whatsoever that any given numeric reply
name will, in fact, describe the contents of the message; most IRC numeric
messages have implementation-specific uses. See the various RFCs, and other
info sources, for details.
*/
@property (class, nonatomic, readonly) NSDictionary <NSString *, NSDictionary *> *ircNumericCodes;

/********************************************/ /********************************************/
#pragma mark - Initializers & factory methods #pragma mark - Initializers & factory methods
/********************************************/ /********************************************/
#pragma mark - IRC commands #pragma mark - IRC commands
/**************************/ /**************************/


/** Sends a raw message to the IRC server. Please consult rfc1459 for the format
of IRC commands.
/** Sends a raw message to the IRC server. Please consult RFC 1459 for the
format of IRC commands.
*/ */
-(int) sendRaw:(NSData *)message; -(int) sendRaw:(NSData *)message;


/** Quits the IRC server with the given reason. /** Quits the IRC server with the given reason.
On success, a userQuit:withReason: event will be sent to the
On success, a -[userQuit:withReason:session:] event will be sent to the
IRCClientSessionDelegate with the nickname of the IRC client and the reason IRCClientSessionDelegate with the nickname of the IRC client and the reason
provided by the user (or nil if no reason was provided). provided by the user (or nil if no reason was provided).
@param reason The quit reason.
*/ */
-(int) quit:(NSData *)reason; -(int) quit:(NSData *)reason;


/** Joins a channel with a given name and key. /** Joins a channel with a given name and key.
On success, a userJoined:channel: event will be sent to the
IRCClientSessionDelegate with the nickname of the IRC client and the name of
the channel that was joined.
On success, a -[joinedNewChannel:session:] event will be sent to the
IRCClientSessionDelegate with the IRCClientChannel object representing the
newly-joined channel.
@param channel the channel to join
@param key they key for the channel (may be nil)
@param channel The name of the channel to join.
@param key The key for the channel (may be nil).
*/ */
-(int) join:(NSData *)channel -(int) join:(NSData *)channel
key:(NSData *)key; key:(NSData *)key;


/** Lists users in an IRC channel (or channels). /** Lists users in an IRC channel (or channels).


@param channel a channel name or string to pass to the NAMES command.
@param channel A channel name or string to pass to the NAMES command.
Implementation specific. Implementation specific.
*/ */
-(int) names:(NSData *)channel; -(int) names:(NSData *)channel;


/** Lists channels on the IRC server. /** Lists channels on the IRC server.
@param channel a channel name or string to pass to the LIST command.
@param channel A channel name or string to pass to the LIST command.
Implementation specific. Implementation specific.
*/ */
-(int) list:(NSData *)channel; -(int) list:(NSData *)channel;


/** Sets the user mode for the IRC client. /** Sets the user mode for the IRC client.
@param mode string to set
@param mode The mode string to set.
*/ */
-(int) userMode:(NSData *)mode; -(int) userMode:(NSData *)mode;


IRCClientSessionDelegate with our old nick and the new nick that we now IRCClientSessionDelegate with our old nick and the new nick that we now
have. have.
@param newnick new nickname to set.
@param newnick The new nickname to set.
*/ */
-(int) nick:(NSData *)newnick; -(int) nick:(NSData *)newnick;


/** Sends a WHO query to the IRC server. /** Sends a WHO query to the IRC server.


@param nickmask nickname mask of the irc client to who.
@param nickmask Nickname mask of the IRC client to WHO.
*/ */
-(int) who:(NSData *)nickmask; -(int) who:(NSData *)nickmask;


/** Sends a WHOIS query to the IRC server. /** Sends a WHOIS query to the IRC server.
@param nick nickname of the irc client to whois.
@param nick Nickname of the IRC client to WHOIS.
*/ */
-(int) whois:(NSData *)nick; -(int) whois:(NSData *)nick;


/** Send a PRIVMSG to another IRC client. /** Send a PRIVMSG to another IRC client.
@param message message to send
@param target the other IRC client to send the message to.
@param message Message to send.
@param target The other IRC client to send the message to.
*/ */
-(int) message:(NSData *)message -(int) message:(NSData *)message
to:(NSData *)target; to:(NSData *)target;


/** Sends a CTCP ACTION to another IRC client. /** Sends 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.
@param action The action message to send.
@param target The nickname of the irc client to send the message to.
*/ */
-(int) action:(NSData *)action -(int) action:(NSData *)action
to:(NSData *)target; to:(NSData *)target;


/** Send a NOTICE to another IRC client. /** 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.
@param notice The message text to send.
@param target The nickname of the irc client to send the notice to.
*/ */
-(int) notice:(NSData *)notice -(int) notice:(NSData *)notice
to:(NSData *)target; to:(NSData *)target;


/** Send a CTCP request to another IRC client. /** 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.
@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 -(int) ctcpRequest:(NSData *)request
target:(NSData *)target; target:(NSData *)target;


/** Send a CTCP reply to another IRC client. /** 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.
@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 -(int) ctcpReply:(NSData *)reply
target:(NSData *)target; target:(NSData *)target;

+ 60
- 55
IRCClient/IRCClientSession.m 查看文件

// //
// IRCClientSession.m // IRCClientSession.m
// IRCClient
/*
* Copyright 2015 Said Achmiz (www.saidachmiz.net)
*
* 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.
*/
//
// Modified IRCClient Copyright 2015-2021 Said Achmiz.
// Original IRCClient Copyright 2009 Nathan Ollerenshaw.
// libircclient Copyright 2004-2009 Georgy Yunaev.
//
// See LICENSE and README.md for more info.


/********************************/ /********************************/
#pragma mark Defines and includes #pragma mark Defines and includes
/***************************************************/ /***************************************************/


@implementation IRCClientSession { @implementation IRCClientSession {
irc_callbacks_t _callbacks;
irc_session_t *_irc_session;
irc_callbacks_t _callbacks;
irc_session_t *_irc_session;


NSMutableDictionary <NSData *, IRCClientChannel *> *_channels; NSMutableDictionary <NSData *, IRCClientChannel *> *_channels;
} }
/*************************************/ /*************************************/


+(NSData *) nickFromNickUserHost:(NSData *)nickUserHost { +(NSData *) nickFromNickUserHost:(NSData *)nickUserHost {
if (nickUserHost == nil) return nil;
if (nickUserHost == nil)
return nil;


NSRange rangeOfNickUserSeparator = [nickUserHost rangeOfData:[NSData dataFromCString:"!"] NSRange rangeOfNickUserSeparator = [nickUserHost rangeOfData:[NSData dataFromCString:"!"]
options:(NSDataSearchOptions) 0 options:(NSDataSearchOptions) 0
range:NSRangeMake(0, nickUserHost.length)]; range:NSRangeMake(0, nickUserHost.length)];


return ((rangeOfNickUserSeparator.location == NSNotFound) ?
nickUserHost :
[nickUserHost subdataWithRange:NSRangeMake(0,
rangeOfNickUserSeparator.location)]);
return (rangeOfNickUserSeparator.location == NSNotFound
? nickUserHost
: [nickUserHost subdataWithRange:NSRangeMake(0, rangeOfNickUserSeparator.location)]);
} }


+(NSData *) userFromNickUserHost:(NSData *)nickUserHost { +(NSData *) userFromNickUserHost:(NSData *)nickUserHost {
if (nickUserHost == nil) return nil;
if (nickUserHost == nil)
return nil;


NSRange rangeOfNickUserSeparator = [nickUserHost rangeOfData:[NSData dataFromCString:"!"] NSRange rangeOfNickUserSeparator = [nickUserHost rangeOfData:[NSData dataFromCString:"!"]
options:(NSDataSearchOptions) 0 options:(NSDataSearchOptions) 0
options:(NSDataSearchOptions) 0 options:(NSDataSearchOptions) 0
range:NSRangeMake(0, nickUserHost.length)]; range:NSRangeMake(0, nickUserHost.length)];


return ((rangeOfNickUserSeparator.location == NSNotFound || rangeOfUserHostSeparator.location == NSNotFound) ?
[NSData data] :
[nickUserHost subdataWithRange:NSRangeMake(rangeOfNickUserSeparator.location + 1,
rangeOfUserHostSeparator.location - (rangeOfNickUserSeparator.location + 1))]);
return (( rangeOfNickUserSeparator.location == NSNotFound
|| rangeOfUserHostSeparator.location == NSNotFound)
? [NSData data]
: [nickUserHost subdataWithRange:NSRangeMake(rangeOfNickUserSeparator.location + 1,
rangeOfUserHostSeparator.location - (rangeOfNickUserSeparator.location + 1))]);
} }


+(NSData *) hostFromNickUserHost:(NSData *)nickUserHost { +(NSData *) hostFromNickUserHost:(NSData *)nickUserHost {
if (nickUserHost == nil) return nil;
if (nickUserHost == nil)
return nil;


NSRange rangeOfUserHostSeparator = [nickUserHost rangeOfData:[NSData dataFromCString:"@"] NSRange rangeOfUserHostSeparator = [nickUserHost rangeOfData:[NSData dataFromCString:"@"]
options:(NSDataSearchOptions) 0 options:(NSDataSearchOptions) 0
range:NSRangeMake(0, nickUserHost.length)]; range:NSRangeMake(0, nickUserHost.length)];


return ((rangeOfUserHostSeparator.location == NSNotFound) ?
[NSData data] :
[nickUserHost subdataWithRange:NSRangeMake(rangeOfUserHostSeparator.location + 1,
nickUserHost.length - (rangeOfUserHostSeparator.location + 1))]);
return (rangeOfUserHostSeparator.location == NSNotFound
? [NSData data]
: [nickUserHost subdataWithRange:NSRangeMake(rangeOfUserHostSeparator.location + 1,
nickUserHost.length - (rangeOfUserHostSeparator.location + 1))]);
} }


/***************************/ /***************************/
- (int) quit:(NSData *)reason { - (int) quit:(NSData *)reason {
return irc_send_raw(_irc_session, return irc_send_raw(_irc_session,
"QUIT :%s", "QUIT :%s",
reason ? reason.SA_terminatedCString : "quit");
(reason
? reason.SA_terminatedCString
: "quit"));
} }


-(int) join:(NSData *)channel -(int) join:(NSData *)channel
SA_IRC_IgnoreColorCodes, SA_IRC_IgnoreColorCodes,
} SA_IRC_ColorCodeHandling; } SA_IRC_ColorCodeHandling;


// TODO: Support setting this somehow...
SA_IRC_ColorCodeHandling whatAboutColors = SA_IRC_ParseColorCodes; SA_IRC_ColorCodeHandling whatAboutColors = SA_IRC_ParseColorCodes;


NSMutableArray <NSData *> *params_array; NSMutableArray <NSData *> *params_array;
|| !strcmp(event, "SERVNOTICE") || !strcmp(event, "SERVNOTICE")
|| !strcmp(event, "CTCP_ACTION") || !strcmp(event, "CTCP_ACTION")
)) { )) {
char* (*process_color_codes) (const char *) = (whatAboutColors == SA_IRC_ParseColorCodes ?
irc_color_convert_from_mirc :
irc_color_strip_from_mirc);
char* (*process_color_codes) (const char *) = (whatAboutColors == SA_IRC_ParseColorCodes
? irc_color_convert_from_mirc
: irc_color_strip_from_mirc);


params_array = [NSMutableArray arrayWithCapacity:count]; params_array = [NSMutableArray arrayWithCapacity:count];
for (NSUInteger i = 0; i < count; i++) { for (NSUInteger i = 0; i < count; i++) {
} }


NSData *origin_data = origin ? [NSData dataFromCString:origin] : nil; NSData *origin_data = origin ? [NSData dataFromCString:origin] : nil;
NSData *param_0_data = ((count > 0) ? params_array[0] : nil);
NSData *param_1_data = ((count > 1) ? params_array[1] : nil);
NSData *param_2_data = ((count > 2) ? params_array[2] : nil);
NSData *param_0_data = (count > 0
? params_array[0]
: nil);
NSData *param_1_data = (count > 1
? params_array[1]
: nil);
NSData *param_2_data = (count > 2
? params_array[2]
: nil);


if (!strcmp(event, "CONNECT")) { if (!strcmp(event, "CONNECT")) {
/*! /*!
*/ */
[_delegate connectionSucceeded:self]; [_delegate connectionSucceeded:self];
} else if (!strcmp(event, "PING")) { } else if (!strcmp(event, "PING")) {
// TODO: the part about LIBIRC_OPTION_PING_PASSTHROUGH seems to be a lie??
// But see also LIBIRC_OPTION_IGNORE_PING???
/*! /*!
* The ‘ping’ event is triggered when the client receives a PING message. * The ‘ping’ event is triggered when the client receives a PING message.
* It is only generated if the LIBIRC_OPTION_PING_PASSTHROUGH option is set; * It is only generated if the LIBIRC_OPTION_PING_PASSTHROUGH option is set;
* \param origin the person, who generated the ping. * \param origin the person, who generated the ping.
* \param params[0] mandatory, contains who knows what. * \param params[0] mandatory, contains who knows what.
*/ */
if ([_delegate respondsToSelector:@selector(ping:session:)]) {
if ([_delegate respondsToSelector:@selector(ping:from:session:)]) {
[_delegate ping:param_0_data [_delegate ping:param_0_data
from:origin_data
session:self]; session:self];
} }
} else if (!strcmp(event, "NICK")) { } else if (!strcmp(event, "NICK")) {
options:(NSDataSearchOptions) 0 options:(NSDataSearchOptions) 0
range:NSRangeMake(0, request.length)]; range:NSRangeMake(0, request.length)];


NSRange rangeOfSecondSpace = (rangeOfFirstSpace.location != NSNotFound ?
[request rangeOfData:[NSData dataFromCString:" "]
options:(NSDataSearchOptions) 0
range:NSRangeMake(rangeOfFirstSpace.location + 1,
request.length - (rangeOfFirstSpace.location + 1))] :
NSRangeMake(NSNotFound, 0));
NSData *requestTypeData = (rangeOfFirstSpace.location != NSNotFound ?
[request subdataWithRange:NSRangeMake(0, rangeOfFirstSpace.location)] :
request);
NSData *requestBodyData = ((rangeOfSecondSpace.location != NSNotFound) ?
[request subdataWithRange:NSRangeMake(rangeOfFirstSpace.location + 1,
rangeOfSecondSpace.location - (rangeOfFirstSpace.location + 1))] :
nil);
NSRange rangeOfSecondSpace = (rangeOfFirstSpace.location != NSNotFound
? [request rangeOfData:[NSData dataFromCString:" "]
options:(NSDataSearchOptions) 0
range:NSRangeMake(rangeOfFirstSpace.location + 1,
request.length - (rangeOfFirstSpace.location + 1))]
: NSRangeMake(NSNotFound, 0));
NSData *requestTypeData = (rangeOfFirstSpace.location != NSNotFound
? [request subdataWithRange:NSRangeMake(0, rangeOfFirstSpace.location)]
: request);
NSData *requestBodyData = (rangeOfSecondSpace.location != NSNotFound
? [request subdataWithRange:NSRangeMake(rangeOfFirstSpace.location + 1,
rangeOfSecondSpace.location - (rangeOfFirstSpace.location + 1))]
: nil);
[_delegate CTCPRequestReceived:requestBodyData [_delegate CTCPRequestReceived:requestBodyData
ofType:requestTypeData ofType:requestTypeData

+ 49
- 48
IRCClient/IRCClientSessionDelegate.h 查看文件

// //
// IRCClientSessionDelegate.h // IRCClientSessionDelegate.h
// IRCClient
/*
* Copyright 2015 Said Achmiz (www.saidachmiz.net)
*
* 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.
*/
//
// Modified IRCClient Copyright 2015-2021 Said Achmiz.
// Original IRCClient Copyright 2009 Nathan Ollerenshaw.
// libircclient Copyright 2004-2009 Georgy Yunaev.
//
// See LICENSE and README.md for more info.


#import <Foundation/Foundation.h> #import <Foundation/Foundation.h>


@required @required
-(void) disconnected:(IRCClientSession *)session; -(void) disconnected:(IRCClientSession *)session;


/** The client has received a PING message.
*
* (The contents of a PING could be anything. Sometimes it’s the server’s
* hostname, sometimes other things...)
*
* @param pingData The contents of the PING message.
* @param origin (optional) Where (who) the PING came from.
*/
@optional @optional
-(void) ping:(NSData *)pingData -(void) ping:(NSData *)pingData
from:(NSData *)origin
session:(IRCClientSession *)session; session:(IRCClientSession *)session;


/** An IRC client on a channel that this client is connected to has changed nickname, /** An IRC client on a channel that this client is connected to has changed nickname,
* or this IRC client has changed nicknames. * 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?
* @param nick The new nickname.
* @param oldNick The old nickname.
* @param wasItUs Did our nick change, or someone else’s?
*/ */
@required @required
-(void) nickChangedFrom:(NSData *)oldNick -(void) nickChangedFrom:(NSData *)oldNick


/** An IRC client on a channel that this client is connected to has quit IRC. /** 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.
* @param nick The nickname of the client that quit.
* @param reason (optional) The quit message, if any.
*/ */
@required @required
-(void) userQuit:(NSData *)nick -(void) userQuit:(NSData *)nick
* *
* For example, on receipt of this message, a graphical IRC client would most * For example, on receipt of this message, a graphical IRC client would most
* likely open a new window, create an IRCClientChannelDelegate for the window, * likely open a new window, create an IRCClientChannelDelegate for the window,
* set the new IRCClientChannel's delegate to the new delegate, and then hook
* set the new IRCClientChannels delegate to the new delegate, and then hook
* it up so that new events sent to the IRCClientChannelDelegate are sent to * it up so that new events sent to the IRCClientChannelDelegate are sent to
* the window. * the window.
* *
* @param channel the IRCClientChannel object for the newly joined channel.
* @param channel The IRCClientChannel object for the newly joined channel.
*/ */
@required @required
-(void) joinedNewChannel:(IRCClientChannel *)channel -(void) joinedNewChannel:(IRCClientChannel *)channel
session:(IRCClientSession *)session; session:(IRCClientSession *)session;


/** The client has changed its user mode.
/** The client’s user mode has been changed.
* *
* @param mode the new mode.
* @param mode The new mode.
* @param nick The person who changed the user mode (client itself, or it could
* have been a channel operator, etc.).
*/ */
@required @required
-(void) modeSet:(NSData *)mode -(void) modeSet:(NSData *)mode


/** The client has received a private PRIVMSG from another IRC client. /** 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.
* @param message The text of the message.
* @param nick The other IRC Client that sent the message.
*/ */
@required @required
-(void) privateMessageReceived:(NSData *)message -(void) privateMessageReceived:(NSData *)message


/** The client has received a private NOTICE from another client. /** 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.
* @param notice The text of the message.
* @param nick The nickname of the other IRC client that sent the message.
*/ */
@required @required
-(void) privateNoticeReceived:(NSData *)notice -(void) privateNoticeReceived:(NSData *)notice


/** The client has received a private PRIVMSG from the server. /** The client has received a private PRIVMSG from the server.
* *
* @param origin the sender of the message
* @param params the parameters of the message
* @param origin The sender of the message.
* @param params The parameters of the message.
*/ */
@required @required
-(void) serverMessageReceivedFrom:(NSData *)origin -(void) serverMessageReceivedFrom:(NSData *)origin


/** The client has received a private NOTICE from the server. /** The client has received a private NOTICE from the server.
* *
* @param origin the sender of the notice
* @param params the parameters of the notice
* @param origin The sender of the notice.
* @param params The parameters of the notice.
*/ */
@required @required
-(void) serverNoticeReceivedFrom:(NSData *)origin -(void) serverNoticeReceivedFrom:(NSData *)origin


/** The IRC client has been invited to a channel. /** The IRC client has been invited to a channel.
* *
* @param channel the channel for the invitation.
* @param nick the nickname of the user that sent the invitation.
* @param channelName The name of the channel for the invitation.
* @param nick The nickname of the user that sent the invitation.
*/ */
@required @required
-(void) invitedToChannel:(NSData *)channelName -(void) invitedToChannel:(NSData *)channelName


/** A private CTCP request was sent to the IRC client. /** 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.
* @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.
*/ */
@optional @optional
-(void) CTCPRequestReceived:(NSData *)request -(void) CTCPRequestReceived:(NSData *)request


/** A private CTCP reply was sent to the IRC client. /** 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.
* @param reply An NSData containing the raw C string of the reply.
* @param nick The nickname of the user that sent the reply.
*/ */
@optional @optional
-(void) CTCPReplyReceived:(NSData *)reply -(void) CTCPReplyReceived:(NSData *)reply
* *
* CTCP ACTION is not limited to channels; it may also be sent directly to other users. * 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.
* @param action The action message text.
* @param nick The nickname of the client that sent the action.
*/ */
@required @required
-(void) privateCTCPActionReceived:(NSData *)action -(void) privateCTCPActionReceived:(NSData *)action


/** An unhandled numeric was received from the IRC server /** 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.
* @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.
*/ */
@optional @optional
-(void) numericEventReceived:(NSUInteger)event -(void) numericEventReceived:(NSUInteger)event


/** An unhandled event was received from the IRC server. /** 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.
* @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.
*/ */
@optional @optional
-(void) unknownEventReceived:(NSData *)event -(void) unknownEventReceived:(NSData *)event

+ 1
- 1
IRCClient/Info.plist 查看文件

<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.</string>
<string>Copyright 2015–2021 Said Achmiz.</string>
<key>NSPrincipalClass</key> <key>NSPrincipalClass</key>
<string></string> <string></string>
</dict> </dict>

+ 13
- 0
LICENSE 查看文件

Modified IRCClient Copyright 2015-2021 Said Achmiz.

Original IRCClient Copyright 2009 Nathan Ollerenshaw.

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.

+ 84
- 0
README.md 查看文件

This is a modified version of the IRCClient framework by Nathan Ollerenshaw. It uses the libircclient library by Georgy Yunaev. (See LICENSE for more info.) I’ve rewritten it to allow robust support for arbitrary text encodings, and fixed various other problems. The original version of IRCClient, as well as libircclient, is available here: [http://sourceforge.net/projects/libircclient/](http://sourceforge.net/projects/libircclient/).

---

## Adding IRCClient to your application

(using Xcode)
(these instructions apply to Xcode 7.1.1, build 7B1005)

1. Place the entire `IRCClient` folder in your project folder

2. Using **File -> Add Files…**, add `IRCClient.xcodeproj` to your project

3. Build the `IRCClient` framework target

4. Make sure the **Header Search Paths** build setting of your project contains the following entry:
```
$(PROJECT_DIR)/
(non-recursive)
```

5. Configure the build phases for your application target thusly:

* Add `IRCClient.framework` to **Link Binary With Libraries**
* Add `IRCClient.framework` to **Target Dependencies**
* Add a **Copy Files** build phase
* Set destination for the just-added **Copy Files** build phase to **Frameworks**
* Add `IRCClient.framework` to the just-added **Copy Files** build phase

6. Import IRCClient’s API into your code using `#import <IRCClient/IRCClient.h>`

7. If you’re using Swift in your project, add `IRCClient/IRCClient.h` to the **Objective-C Bridging Header** build setting.

### Documentation

See the following header files for documentation:

* `IRCClientSession.h`
* `IRCClientSessionDelegate.h`
* `IRCClientChannel.h`
* `IRCClientChannelDelegate.h`

### NOTE on strings

IRCClient stores and passes all strings (messages, nicks, channel names, mode strings, channel topics, etc.) as `NSData` objects. Values passed to framework methods (such as the IRC commands) should also be in this format[^1]. This means that IRCClient is encoding-agnostic[^1]; it is up to you to pass it properly encoded representations of your text strings, and it is also up to you to select an appropriate encoding for display or other handling of received strings, as necessary. The `encoding` property of `IRCClientSession` and `IRCClientChannel` may be useful in this regard (i.e. for the convenience of associating a server’s or channel’s preferred encoding with the relevant server or channel object), although note that this property is almost entirely epiphenomenal[^2].

[^1]: Of course, IRCClient does not support UTF-16 nor any other non-8-bit encoding, as the IRC protocol does not support such encodings either.

[^2]: The `encoding` property of `IRCClientSession` does have one effect: it controls the encoding used by replies to `CTCP TIME` requests.

---

## 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 place
the connection on a new event queue and start receiving events. For example:

```
IRCClientSession *session = [IRCClientSession new];
MyIRCClientSessionDelegate *controller = [[MyIRCClientSessionDelegate alloc] init];

session.delegate = controller;
controller.session = session;

session.server = @"irc.libera.chat".dataAsUTF8;
session.port = 6667;
[session setNickname:@"test".dataAsUTF8
username:@"test".dataAsUTF8
realname:@"test".dataAsUTF8];
[session connect];

[session run]; // Activates the event queue
```

If you have questions, bug reports, or suggestions regarding IRCClient,
find Obormot on the Libera.Chat IRC network.

If you have any questions, bug reports, suggestions regarding libircclient,
please visit [http://sourceforge.net/projects/libircclient/](http://sourceforge.net/projects/libircclient/).

正在加载...
取消
保存