Opened 11 years ago

Closed 11 years ago

#1005 closed Enhancement (Fixed)

Let plugins work on raw data to be send to/received from connection

Reported by: hennk Owned by: timothy
Component: Colloquy (Mac) Version:
Severity: Major Keywords: Plugins encryption
Cc: hennk

Description

Right now plugins can process incoming and outgoing messages via processIncomingMessage:: / processOutgoingMessage:: (or the corresponding methods for other languages than ObjC).

These two methods only give access to the message after Colloquy did its own processing on it, ie. nick highlighting, URL detection etc. There are plugin-types, though, for which this behaviour is not optimal. For example an encryption plugin needs to decrypt the raw incoming message (encrypt the raw outgoing message) before Colloquy does its processing, as it won't find anything in an encrypted message.

I am currently developing a Blowfish encryption plugin, and it's limited by the current plugin interface. Another problem is the encoding of the strings. Afaik Colloquy does inform the user if an incoming message has a different encoding as selected for the current channel. I am not sure, but it might be doing fallback-encodings, too. But all this happens before my plugin gets to decrypt the message.

As already suggested in ticket:556 I suggest to provide a richer plugin interface, allowing plugins to work on the NSDatas before they get processed by Colloquy. This way, for example encryption plugins wouldn't even know about string encodings and such. To fix ticket:556 another methods might be supplied to let plugins work on NSStrings before the message gets translated to HTML. The same would be needed for outgoing messages, ie. a method to work on the raw message NSData before it gets send, and the raw NSString, after the conversion from HTML, and before encoding it in an NSData object.

Possible methods might be:

  • (processIncomingRawMessage:(NSData *)message from:(NSString/MVChatUser):sender in:(NSString/MVDirectChat/MVChatRoom)context on:(MVChatConnection *)connection
  • (processOutgoingRawMessage:(NSData *)message to:(NSString/MVChatUser):sender in:(NSString/MVDirectChat/MVChatRoom)context on:(MVChatConnection *)connection

Browsing the code quickly, some possible positions to do the raw data notifications would be:
For outgoing messages:
Outgoing:

  • MVIRCChatConnection - (void) _sendMessage:(NSAttributedString *) message withEncoding:(NSStringEncoding) msgEncoding toTarget:(NSString *) target asAction:(BOOL) action
  • MVDirectChatConnection - (void) sendMessage:(NSAttributedString *) message withEncoding:(NSStringEncoding) encoding asAction:(BOOL) action

Incoming:
JVChatController

  • (void) _gotDirectChatMessage:(NSNotification *) notification
  • (void) _gotRoomMessage:(NSNotification *) notification
  • (void) _gotPrivateMessage:(NSNotification *) notification

Change History (4)

comment:1 Changed 11 years ago by timothy

  • Status changed from new to assigned

I would call these new methods:

processIncomingMessageAsData:from:to:
processOutgoingMessageAsData:to:

comment:2 in reply to: ↑ description Changed 11 years ago by hennk

Replying to timothy:

I would call these new methods:

processIncomingMessageAsData:from:to:
processOutgoingMessageAsData:to:

I just uploaded a first version of a patch implementing this feature. Affected classes are:

  • MVIRCChatConnection
  • MVIRCChatRoom
  • MVIRCChatUser

Plugins can now implement methods:

  • (void) processIncomingMessageAsData:(NSMutableData *)message from:(MVChatUser *)sender to:(id)receiver isNotice:(BOOL)isNotice;
  • (void) processOutgoingMessageAsData:(NSMutableData *)message to:(id)receiver;

to receive incoming and outgoing IRC messages as raw data. If a plugin in this process empties the message data object, sending/receiving of the message gets cancelled.

Outgoing messages are handled in _sendMessage:withEncoding:toTarget:asAction:, where plugins get a chance to modify the message-body. This means, that plugins won't notice messages sent out with one of the sendRawMessage: methods, as these work on an even lower level. Something similar could certainly be implemented for sendRawMessage:, too, but the plugin would have to parse the complete message itself, as sendRawMessage doesn't know about what part of the message constitutes the body/command etc.

Incoming messages are handled either in _handlePrivmsg: or _handleNotice:. Currently, Private Messages and Notices, which are no CTCPs, are the only type of messages plugins can work on.

To make the methods for incoming and outgoing messages more coherent, _sendMessage:withEncoding:toTarget:asAction: has been changed to use MVChatUser/MVChatRoom as the target, instead of a simple NSString. This affected only 2 lines of code in MVIRCChatRoom and MVIRCChatUser, which have been changed accordingly.

comment:3 Changed 11 years ago by hennk

I just uploaded an updated version of the patch. This new patch contains all old changes plus the following:

CTCP Action messages are now handled by _handlePrivmsg:. Before, _handleCtcp would handle them on its own, but did dispatch exactly the same notifications as _handlePrivmsg does. So now, when _handleCtcp detects an action message, it just calls _handlePrivmsg.

This allows plugins to work on these types of messages, also, which I see as expected behaviour, as they get displayed to the user like regular messages.

comment:4 Changed 11 years ago by timothy

  • Resolution set to fixed
  • Status changed from assigned to closed

Landed in [3584].

Note: See TracTickets for help on using tickets.