Rewrite some IRCClientChannel functionality to rely less on libircclient’s implementation of IRC commands

This commit is contained in:
achmizs 2021-12-04 22:15:53 -05:00
parent 3bb861b44d
commit 49fd91b2c7
4 changed files with 261 additions and 122 deletions

View File

@ -27,6 +27,8 @@
* for a given session when the client joins an IRC channel. * for a given session when the client joins an IRC channel.
*/ */
@class IRCClientSession;
/**********************************************/ /**********************************************/
#pragma mark IRCClientChannel class declaration #pragma mark IRCClientChannel class declaration
/**********************************************/ /**********************************************/
@ -40,6 +42,9 @@
/** Delegate to send events to */ /** Delegate to send events to */
@property (assign) id <IRCClientChannelDelegate> delegate; @property (assign) id <IRCClientChannelDelegate> delegate;
/** Associated session */
@property (readonly) IRCClientSession *session;
/** Name of the channel */ /** Name of the channel */
@property (readonly) NSData *name; @property (readonly) NSData *name;
@ -50,7 +55,7 @@
* *
* 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 channels delegate will receive a
* topicSet:by: message (and the topic property of the channel object will be * topicSet:by: message (and the topic property of the channel object will be
* updated automatically). * updated automatically).
*/ */
@ -66,18 +71,24 @@
/** Stores arbitrary user info. */ /** Stores arbitrary user info. */
@property (strong) NSDictionary *userInfo; @property (strong) NSDictionary *userInfo;
/********************************************/
#pragma mark - Initializers & factory methods
/********************************************/
+(instancetype) channel;
/**************************/ /**************************/
#pragma mark - IRC commands #pragma mark - IRC commands
/**************************/ /**************************/
/** Parts the channel. */ /** Parts the channel. */
- (int)part; -(int) part;
/** 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.
* *
@ -86,7 +97,7 @@
* *
* @param aTopic the topic the client wishes to set for the channel. * @param aTopic the topic the client wishes to set for the channel.
*/ */
- (void)setChannelTopic:(NSData *)newTopic; -(int) setChannelTopic:(NSData *)newTopic;
/** Sets the mode of the channel. /** Sets the mode of the channel.
* *
@ -95,33 +106,35 @@
* *
* @param mode the mode to set the channel to * @param mode the mode to set the channel to
*/ */
- (int)setMode:(NSData *)mode params:(NSData *)params; -(int) setMode:(NSData *)mode
params:(NSData *)params;
/** Sends a public PRIVMSG to the channel. If you try to send more than can fit on an IRC /** Sends a public PRIVMSG to the channel. If you try to send more than can fit on an IRC
buffer, it will be truncated. 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 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 reason the message to give to the channel and the IRC client for the kick.
*/ */
- (int)kick:(NSData *)nick reason:(NSData *)reason; -(int) kick:(NSData *)nick
reason:(NSData *)reason;
/** Sends a CTCP request to the channel. /** Sends a CTCP request to the channel.
* *
@ -130,6 +143,6 @@
* *
* @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;
@end @end

View File

@ -25,17 +25,14 @@
#pragma mark IRCClientChannel class extension #pragma mark IRCClientChannel class extension
/********************************************/ /********************************************/
@interface IRCClientChannel() @interface IRCClientChannel() {
{ irc_session_t *_irc_session;
irc_session_t *_irc_session;
NSMutableArray *_nicks; // TODO: actually keep track of nicks! Use RPL_NAMREPLY and so on...
// (see refreshNames...)
NSMutableArray *_nicks;
} }
@property (readwrite) NSData *topic;
@property (readwrite) NSData *modes;
@property (readwrite) NSMutableArray *nicks;
@end @end
/***************************************************/ /***************************************************/
@ -44,37 +41,43 @@
@implementation IRCClientChannel @implementation IRCClientChannel
/******************************/ /************************/
#pragma mark - Custom accessors #pragma mark - Properties
/******************************/ /************************/
-(NSArray *)nicks -(NSArray *) nicks {
{ return [_nicks copy];
NSArray* nicksCopy = [_nicks copy];
return nicksCopy;
} }
-(void)setNicks:(NSArray *)nicks -(IRCClientSession *) session {
{ return (__bridge IRCClientSession *) irc_get_ctx(_irc_session);
_nicks = [nicks mutableCopy]; }
/********************************************/
#pragma mark - Initializers & factory methods
/********************************************/
+(instancetype) channel {
return [self new];
} }
/**************************/ /**************************/
#pragma mark - Initializers #pragma mark - Initializers
/**************************/ /**************************/
-(instancetype)initWithName:(NSData *)name andIRCSession:(irc_session_t *)irc_session -(instancetype) initWithName:(NSData *)name
{ andIRCSession:(irc_session_t *)irc_session {
if ((self = [super init])) self = [super init];
{ if (!self) return nil;
_irc_session = irc_session;
_irc_session = irc_session;
_name = name;
_encoding = NSUTF8StringEncoding;
_topic = [NSData dataWithBlankCString];
_modes = [NSData dataWithBlankCString];
_nicks = [NSMutableArray array];
_name = name;
_encoding = NSUTF8StringEncoding;
_topic = [NSData dataWithBlankCString];
_modes = [NSData dataWithBlankCString];
}
return self; return self;
} }
@ -82,110 +85,202 @@
#pragma mark - IRC commands #pragma mark - IRC commands
/**************************/ /**************************/
- (int)part -(int) part {
{ return irc_send_raw(_irc_session,
return irc_cmd_part(_irc_session, _name.SA_terminatedCString); "PART %s",
_name.SA_terminatedCString);
} }
- (int)invite:(NSData *)nick -(int) invite:(NSData *)nick {
{ if (!nick || nick.length == 0)
return irc_cmd_invite(_irc_session, nick.SA_terminatedCString, _name.SA_terminatedCString); return LIBIRC_ERR_STATE;
return irc_send_raw(_irc_session,
"INVITE %s %s",
nick.SA_terminatedCString,
_name.SA_terminatedCString);
} }
- (int)refreshNames -(int) refreshNames {
{ return irc_send_raw(_irc_session,
return irc_cmd_names(_irc_session, _name.SA_terminatedCString); "NAMES %s",
_name.SA_terminatedCString);
} }
- (void)setChannelTopic:(NSData *)newTopic -(int) setChannelTopic:(NSData *)newTopic {
{ if (newTopic)
irc_cmd_topic(_irc_session, _name.SA_terminatedCString, newTopic.SA_terminatedCString); return irc_send_raw(_irc_session,
} "TOPIC %s :%s",
_name.SA_terminatedCString,
- (int)setMode:(NSData *)mode params:(NSData *)params newTopic.SA_terminatedCString);
{
if(params != nil)
{
NSMutableData *fullModeString = (params != nil) ? [NSMutableData dataWithLength:mode.length + 1 + params.length] : [NSMutableData dataWithLength:mode.length];
sprintf(fullModeString.mutableBytes, "%s %s", mode.bytes, params.bytes);
return irc_cmd_channel_mode(_irc_session, _name.SA_terminatedCString, fullModeString.SA_terminatedCString);
}
else else
{ return irc_send_raw(_irc_session,
return irc_cmd_channel_mode(_irc_session, _name.SA_terminatedCString, mode.SA_terminatedCString); "TOPIC %s",
_name.SA_terminatedCString);
}
-(int) setMode:(NSData *)mode
params:(NSData *)params {
if (mode != nil) {
NSMutableData *fullModeString = ((params != nil) ?
[NSMutableData dataWithLength:mode.length + 1 + params.length] :
[NSMutableData dataWithLength:mode.length + 1]);
sprintf(fullModeString.mutableBytes,
"%s %s",
mode.SA_terminatedCString,
params.SA_terminatedCString);
return irc_send_raw(_irc_session,
"MODE %s %s",
_name.SA_terminatedCString,
fullModeString.SA_terminatedCString);
} else {
return irc_send_raw(_irc_session,
"MODE %s",
_name.SA_terminatedCString);
} }
} }
- (int)message:(NSData *)message -(int) message:(NSData *)message {
{ if (!message || message.length == 0)
return irc_cmd_msg(_irc_session, _name.SA_terminatedCString, message.SA_terminatedCString); return LIBIRC_ERR_STATE;
return irc_send_raw(_irc_session,
"PRIVMSG %s :%s",
_name.SA_terminatedCString,
irc_color_convert_to_mirc(message.SA_terminatedCString));
} }
- (int)action:(NSData *)action -(int) action:(NSData *)action {
{ if (!action || action.length == 0)
return irc_cmd_me(_irc_session, _name.SA_terminatedCString, action.SA_terminatedCString); return LIBIRC_ERR_STATE;
return irc_send_raw(_irc_session,
"PRIVMSG %s :\x01" "ACTION %s\x01",
_name.SA_terminatedCString,
irc_color_convert_to_mirc(action.SA_terminatedCString));
} }
- (int)notice:(NSData *)notice -(int) notice:(NSData *)notice {
{ if (!notice || notice.length == 0)
return irc_cmd_notice(_irc_session, _name.SA_terminatedCString, notice.SA_terminatedCString); return LIBIRC_ERR_STATE;
return irc_send_raw(_irc_session,
"NOTICE %s :%s",
_name.SA_terminatedCString,
notice.SA_terminatedCString);
} }
- (int)kick:(NSData *)nick reason:(NSData *)reason -(int) kick:(NSData *)nick
{ reason:(NSData *)reason {
return irc_cmd_kick(_irc_session, nick.SA_terminatedCString, _name.SA_terminatedCString, reason.SA_terminatedCString); if (!nick || nick.length == 0)
return LIBIRC_ERR_STATE;
if (reason)
return irc_send_raw(_irc_session,
"KICK %s %s :%s",
_name.SA_terminatedCString,
nick.SA_terminatedCString,
reason.SA_terminatedCString);
else
return irc_send_raw(_irc_session,
"KICK %s %s",
_name.SA_terminatedCString,
nick.SA_terminatedCString);
} }
- (int)ctcpRequest:(NSData *)request -(int) ctcpRequest:(NSData *)request {
{ if (!request || request.length == 0)
return irc_cmd_ctcp_request(_irc_session, _name.SA_terminatedCString, request.SA_terminatedCString); return LIBIRC_ERR_STATE;
return irc_send_raw(_irc_session,
"PRIVMSG %s :\x01%s\x01",
_name.SA_terminatedCString,
request.SA_terminatedCString);
} }
/****************************/ /****************************/
#pragma mark - Event handlers #pragma mark - Event handlers
/****************************/ /****************************/
- (void)userJoined:(NSData *)nick -(void) userJoined:(NSData *)nick {
{ [_nicks addObject:nick];
[_delegate userJoined:nick channel:self];
[_delegate userJoined:nick
channel:self];
} }
- (void)userParted:(NSData *)nick withReason:(NSData *)reason us:(BOOL)wasItUs -(void) userParted:(NSData *)nick
{ withReason:(NSData *)reason
[_delegate userParted:nick channel:self withReason:reason us:wasItUs]; us:(BOOL)wasItUs {
if (!wasItUs)
[_nicks removeObject:nick];
// TODO: but what if it was us? the delegate handles it...? or do we do
// something here?
[_delegate userParted:nick
channel:self
withReason:reason
us:wasItUs];
} }
- (void)modeSet:(NSData *)mode withParams:(NSData *)params by:(NSData *)nick -(void) modeSet:(NSData *)mode
{ withParams:(NSData *)params
[_delegate modeSet:mode forChannel:self withParams:params by:nick]; by:(NSData *)nick {
// TODO: actually update the mode based on this event ... figure out what
// mode set event returns?
// _modes =
[_delegate modeSet:mode
forChannel:self
withParams:params
by:nick];
} }
- (void)topicSet:(NSData *)topic by:(NSData *)nick -(void) topicSet:(NSData *)topic
{ by:(NSData *)nick {
_topic = topic; _topic = topic;
[_delegate topicSet:topic forChannel:self by:nick]; [_delegate topicSet:topic
forChannel:self
by:nick];
} }
- (void)userKicked:(NSData *)nick withReason:(NSData *)reason by:(NSData *)byNick us:(BOOL)wasItUs -(void) userKicked:(NSData *)nick
{ withReason:(NSData *)reason
[_delegate userKicked:nick fromChannel:self withReason:reason by:byNick us:wasItUs]; by:(NSData *)byNick
us:(BOOL)wasItUs {
if (!wasItUs)
[_nicks removeObject:nick];
// TODO: but what if it was us? the delegate handles it...? or do we do
// something here?
[_delegate userKicked:nick
fromChannel:self
withReason:reason
by:byNick
us:wasItUs];
} }
- (void)messageSent:(NSData *)message byUser:(NSData *)nick -(void) messageSent:(NSData *)message
{ byUser:(NSData *)nick {
[_delegate messageSent:message byUser:nick onChannel:self]; [_delegate messageSent:message
byUser:nick
onChannel:self];
} }
- (void)noticeSent:(NSData *)notice byUser:(NSData *)nick -(void) noticeSent:(NSData *)notice
{ byUser:(NSData *)nick {
[_delegate noticeSent:notice byUser:nick onChannel:self]; [_delegate noticeSent:notice
byUser:nick
onChannel:self];
} }
- (void)actionPerformed:(NSData *)action byUser:(NSData *)nick -(void) actionPerformed:(NSData *)action
{ byUser:(NSData *)nick {
[_delegate actionPerformed:action byUser:nick onChannel:self]; [_delegate actionPerformed:action
byUser:nick
onChannel:self];
} }
@end @end

View File

@ -41,7 +41,8 @@
* *
* @param nick The nickname of the user that joined the channel. * @param nick The nickname of the user that joined the channel.
*/ */
- (void)userJoined:(NSData *)nick channel:(IRCClientChannel *)sender; -(void) userJoined:(NSData *)nick
channel:(IRCClientChannel *)session;
/** When an IRC client parts a channel you are connect to, you will see /** 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. * an onPart event. You will also see this event when you part a channel.
@ -50,7 +51,10 @@
* @param reason (optional) The reason, if any, that the user gave for leaving. * @param reason (optional) The reason, if any, that the user gave for leaving.
* @param wasItUs (required) Was it us who parted, or another user? * @param wasItUs (required) Was it us who parted, or another user?
*/ */
- (void)userParted:(NSData *)nick channel:(IRCClientChannel *)sender withReason:(NSData *)reason us:(BOOL)wasItUs; -(void) userParted:(NSData *)nick
channel:(IRCClientChannel *)session
withReason:(NSData *)reason
us:(BOOL)wasItUs;
/** 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.
@ -59,14 +63,19 @@
* @param params any parameters with the mode (such as channel key). * @param params any parameters with the mode (such as channel key).
* @param nick the nickname of the IRC client that changed the mode. * @param nick the nickname of the IRC client that changed the mode.
*/ */
- (void)modeSet:(NSData *)mode forChannel:(IRCClientChannel *)sender withParams:(NSData *)params by:(NSData *)nick; -(void) modeSet:(NSData *)mode
forChannel:(IRCClientChannel *)session
withParams:(NSData *)params
by:(NSData *)nick;
/** Received when the topic is changed for the channel. /** Received when the topic is changed for the channel.
* *
* @param aTopic The new topic of the channel. * @param aTopic The new topic of the channel.
* @param nick Nickname of the IRC client that changed the topic. * @param nick Nickname of the IRC client that changed the topic.
*/ */
- (void)topicSet:(NSData *)topic forChannel:(IRCClientChannel *)sender by:(NSData *)nick; -(void) topicSet:(NSData *)topic
forChannel:(IRCClientChannel *)session
by:(NSData *)nick;
/** Received when an IRC client is kicked from a channel. /** Received when an IRC client is kicked from a channel.
* *
@ -75,7 +84,11 @@
* @param byNick nickname of the client that performed the kick command * @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 fromChannel:(IRCClientChannel *)sender withReason:(NSData *)reason by:(NSData *)byNick us:(BOOL)wasItUs; -(void) userKicked:(NSData *)nick
fromChannel:(IRCClientChannel *)session
withReason:(NSData *)reason
by:(NSData *)byNick
us:(BOOL)wasItUs;
/** Received when an IRC client sends a public PRIVMSG to the channel. Note that the /** 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 * user may not necessarily be required to be on the channel to send a message
@ -84,7 +97,9 @@
* @param message the message sent to the channel. * @param message the message sent to the channel.
* @param nick the nickname of the IRC client that sent the message. * @param nick the nickname of the IRC client that sent the message.
*/ */
- (void)messageSent:(NSData *)message byUser:(NSData *)nick onChannel:(IRCClientChannel *)sender; -(void) messageSent:(NSData *)message
byUser:(NSData *)nick
onChannel:(IRCClientChannel *)session;
/** Received when an IRC client sends a public NOTICE to the channel. Note that /** 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 * the user may not necessarily be required to be on the channel to send a notice to
@ -94,13 +109,17 @@
* @param notice the notice sent to the channel. * @param notice the notice sent to the channel.
* @param nick the nickname of the IRC client that sent the notice. * @param nick the nickname of the IRC client that sent the notice.
*/ */
- (void)noticeSent:(NSData *)notice byUser:(NSData *)nick onChannel:(IRCClientChannel *)sender; -(void) noticeSent:(NSData *)notice
byUser:(NSData *)nick
onChannel:(IRCClientChannel *)session;
/** 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 action the action message sent to the channel.
* @param nick the nickname of the IRC client that sent the message. * @param nick the nickname of the IRC client that sent the message.
*/ */
- (void)actionPerformed:(NSData *)action byUser:(NSData *)nick onChannel:(IRCClientChannel *)sender; -(void) actionPerformed:(NSData *)action
byUser:(NSData *)nick
onChannel:(IRCClientChannel *)session;
@end @end

View File

@ -27,37 +27,49 @@
/** initWithName:andIRCSession: /** initWithName:andIRCSession:
* *
* Returns an initialised IRCClientChannel with a given channel name, associated * Returns an initialised IRCClientChannel with a given channel name, associated
* with the given irc_session_t object. You are not expected to initialise your * with the given irc_session_t object. You are not expected to initialize your
* own IRCClientChannel objects; if you wish to join a channel you should send a * own IRCClientChannel objects; if you wish to join a channel you should send a
* [IRCClientSession join:key:] message to your IRCClientSession object. * [IRCClientSession join:key:] message to your IRCClientSession object.
* *
* @param aName Name of the channel. * @param aName Name of the channel.
*/ */
-(instancetype)initWithName:(NSData *)aName andIRCSession:(irc_session_t *)session; -(instancetype) initWithName:(NSData *)aName
andIRCSession:(irc_session_t *)session;
/****************************/ /****************************/
#pragma mark - Event handlers #pragma mark - Event handlers
/****************************/ /****************************/
/* NOTE: These methods are not to be called by classes that use IRCClient; /* 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 * they are for the frameworks internal use only. Do not import this header
* in files that make use of the IRCClientChannel class. * in files that make use of the IRCClientChannel class.
*/ */
- (void)userJoined:(NSData *)nick; -(void) userJoined:(NSData *)nick;
- (void)userParted:(NSData *)nick withReason:(NSData *)reason us:(BOOL)wasItUs; -(void) userParted:(NSData *)nick
withReason:(NSData *)reason
us:(BOOL)wasItUs;
- (void)modeSet:(NSData *)mode withParams:(NSData *)params by:(NSData *)nick; -(void) modeSet:(NSData *)mode
withParams:(NSData *)params
by:(NSData *)nick;
- (void)topicSet:(NSData *)newTopic by:(NSData *)nick; -(void) topicSet:(NSData *)newTopic
by:(NSData *)nick;
- (void)userKicked:(NSData *)nick withReason:(NSData *)reason by:(NSData *)byNick us:(BOOL)wasItUs; -(void) userKicked:(NSData *)nick
withReason:(NSData *)reason
by:(NSData *)byNick
us:(BOOL)wasItUs;
- (void)messageSent:(NSData *)message byUser:(NSData *)nick; -(void) messageSent:(NSData *)message
byUser:(NSData *)nick;
- (void)noticeSent:(NSData *)notice byUser:(NSData *)nick; -(void) noticeSent:(NSData *)notice
byUser:(NSData *)nick;
- (void)actionPerformed:(NSData *)action byUser:(NSData *)nick; -(void) actionPerformed:(NSData *)action
byUser:(NSData *)nick;
@end @end