diff options
-rw-r--r-- | irc.h | 6 | ||||
-rw-r--r-- | irc_channel.c | 50 | ||||
-rw-r--r-- | irc_commands.c | 4 | ||||
-rw-r--r-- | irc_im.c | 124 | ||||
-rw-r--r-- | root_commands.c | 21 |
5 files changed, 131 insertions, 74 deletions
@@ -194,12 +194,6 @@ struct irc_control_channel struct account *account; }; -struct irc_groupchat_stub -{ - struct account *acc; - char *room; -}; - extern const struct bee_ui_funcs irc_ui_funcs; /* irc.c */ diff --git a/irc_channel.c b/irc_channel.c index 64bbd614..bceb067c 100644 --- a/irc_channel.c +++ b/irc_channel.c @@ -28,7 +28,8 @@ static char *set_eval_channel_type( set_t *set, char *value ); static gint irc_channel_user_cmp( gconstpointer a_, gconstpointer b_ ); static const struct irc_channel_funcs control_channel_funcs; -static const struct irc_channel_funcs groupchat_stub_funcs; + +extern const struct irc_channel_funcs irc_channel_im_chat_funcs; irc_channel_t *irc_channel_new( irc_t *irc, const char *name ) { @@ -103,7 +104,7 @@ static char *set_eval_channel_type( set_t *set, char *value ) if( strcmp( value, "control" ) == 0 ) new = &control_channel_funcs; else if( strcmp( value, "chat" ) == 0 ) - new = &groupchat_stub_funcs; + new = &irc_channel_im_chat_funcs; else return SET_INVALID; @@ -388,48 +389,3 @@ static const struct irc_channel_funcs control_channel_funcs = { control_channel_init, control_channel_free, }; - -/* Groupchat stub: Only handles /INVITE at least for now. */ -static gboolean groupchat_stub_invite( irc_channel_t *ic, irc_user_t *iu ) -{ - bee_user_t *bu = iu->bu; - - if( iu->bu->ic->acc->prpl->chat_with ) - { - ic->flags |= IRC_CHANNEL_CHAT_PICKME; - iu->bu->ic->acc->prpl->chat_with( bu->ic, bu->handle ); - ic->flags &= ~IRC_CHANNEL_CHAT_PICKME; - return TRUE; - } - else - { - irc_send_num( ic->irc, 482, "%s :IM protocol does not support room invitations", ic->name ); - return FALSE; - } -} - -static gboolean groupchat_stub_join( irc_channel_t *ic ) -{ - struct irc_groupchat_stub *igs = ic->data; - - if( igs && igs->acc->ic && igs->acc->prpl->chat_join ) - { - ic->flags |= IRC_CHANNEL_CHAT_PICKME; - igs->acc->prpl->chat_join( igs->acc->ic, igs->room, ic->irc->user->nick, NULL ); - ic->flags &= ~IRC_CHANNEL_CHAT_PICKME; - return FALSE; - } - else - { - irc_send_num( ic->irc, 403, "%s :Can't join channel, account offline?", ic->name ); - return FALSE; - } -} - -static const struct irc_channel_funcs groupchat_stub_funcs = { - NULL, - groupchat_stub_join, - NULL, - NULL, - groupchat_stub_invite, -}; diff --git a/irc_commands.c b/irc_commands.c index 24be35e3..ccfc2171 100644 --- a/irc_commands.c +++ b/irc_commands.c @@ -398,9 +398,7 @@ static void irc_cmd_invite( irc_t *irc, char **cmd ) return; } - if( ic->f->invite ) - ic->f->invite( ic, iu ); - else + if( !ic->f->invite || !ic->f->invite( ic, iu ) ) irc_send_num( irc, 482, "%s :Can't invite people here", cmd[2] ); } @@ -317,7 +317,7 @@ static const struct irc_user_funcs irc_user_im_funcs = { /* IM->IRC: Groupchats */ -static const struct irc_channel_funcs irc_channel_im_chat_funcs; +const struct irc_channel_funcs irc_channel_im_chat_funcs; static gboolean bee_irc_chat_new( bee_t *bee, struct groupchat *c ) { @@ -340,7 +340,7 @@ static gboolean bee_irc_chat_new( bee_t *bee, struct groupchat *c ) if( l == NULL ) for( i = 0; i <= 999; i ++ ) { char name[16]; - sprintf( name, "&chat_%03d", i ); + sprintf( name, "#chat_%03d", i ); if( ( ic = irc_channel_new( irc, name ) ) ) break; } @@ -350,7 +350,6 @@ static gboolean bee_irc_chat_new( bee_t *bee, struct groupchat *c ) c->ui_data = ic; ic->data = c; - ic->f = &irc_channel_im_chat_funcs; topic = g_strdup_printf( "BitlBee groupchat: \"%s\". Please keep in mind that root-commands won't work here. Have fun!", c->title ); irc_channel_set_topic( ic, topic, irc->root ); @@ -366,7 +365,10 @@ static gboolean bee_irc_chat_free( bee_t *bee, struct groupchat *c ) if( ic->flags & IRC_CHANNEL_JOINED ) irc_channel_printf( ic, "Cleaning up channel, bye!" ); - irc_channel_free( ic ); + /* irc_channel_free( ic ); */ + + irc_channel_del_user( ic, ic->irc->user ); + ic->data = NULL; return TRUE; } @@ -467,33 +469,70 @@ static gboolean bee_irc_channel_chat_privmsg( irc_channel_t *ic, const char *msg { struct groupchat *c = ic->data; + if( c == NULL ) + return FALSE; + bee_chat_msg( ic->irc->b, c, msg, 0 ); return TRUE; +} + +static gboolean bee_irc_channel_chat_join( irc_channel_t *ic ) +{ + char *acc_s, *room; + account_t *acc; + if( strcmp( set_getstr( &ic->set, "chat_type" ), "room" ) != 0 ) + return TRUE; + + if( ( acc_s = set_getstr( &ic->set, "account" ) ) && + ( room = set_getstr( &ic->set, "room" ) ) && + ( acc = account_get( ic->irc->b, acc_s ) ) && + acc->ic && acc->prpl->chat_join ) + { + char *nick; + + if( !( nick = set_getstr( &ic->set, "nick" ) ) ) + nick = ic->irc->user->nick; + + ic->flags |= IRC_CHANNEL_CHAT_PICKME; + acc->prpl->chat_join( acc->ic, room, nick, NULL ); + ic->flags &= ~IRC_CHANNEL_CHAT_PICKME; + + return FALSE; + } + else + { + irc_send_num( ic->irc, 403, "%s :Can't join channel, account offline?", ic->name ); + return FALSE; + } } static gboolean bee_irc_channel_chat_part( irc_channel_t *ic, const char *msg ) { struct groupchat *c = ic->data; - if( c->ic->acc->prpl->chat_leave ) + if( c && c->ic->acc->prpl->chat_leave ) c->ic->acc->prpl->chat_leave( c ); return TRUE; - } static gboolean bee_irc_channel_chat_topic( irc_channel_t *ic, const char *new ) { struct groupchat *c = ic->data; - char *topic = g_strdup( new ); /* TODO: Need more const goodness here, sigh */ + + if( c == NULL ) + return FALSE; if( c->ic->acc->prpl->chat_topic == NULL ) irc_send_num( ic->irc, 482, "%s :IM network does not support channel topics", ic->name ); else { + /* TODO: Need more const goodness here, sigh */ + char *topic = g_strdup( new ); c->ic->acc->prpl->chat_topic( c, topic ); + g_free( topic ); return TRUE; } @@ -503,23 +542,82 @@ static gboolean bee_irc_channel_chat_topic( irc_channel_t *ic, const char *new ) static gboolean bee_irc_channel_chat_invite( irc_channel_t *ic, irc_user_t *iu ) { struct groupchat *c = ic->data; + bee_user_t *bu = iu->bu; + + if( bu == NULL ) + return FALSE; - if( iu->bu->ic != c->ic ) - irc_send_num( ic->irc, 482, "%s :Can't mix different IM networks in one groupchat", ic->name ); - else if( c->ic->acc->prpl->chat_invite ) - c->ic->acc->prpl->chat_invite( c, iu->bu->handle, NULL ); + if( c ) + { + if( iu->bu->ic != c->ic ) + irc_send_num( ic->irc, 482, "%s :Can't mix different IM networks in one groupchat", ic->name ); + else if( c->ic->acc->prpl->chat_invite ) + c->ic->acc->prpl->chat_invite( c, iu->bu->handle, NULL ); + else + irc_send_num( ic->irc, 482, "%s :IM protocol does not support room invitations", ic->name ); + } + else if( bu->ic->acc->prpl->chat_with && + strcmp( set_getstr( &ic->set, "chat_type" ), "groupchat" ) == 0 ) + { + ic->flags |= IRC_CHANNEL_CHAT_PICKME; + iu->bu->ic->acc->prpl->chat_with( bu->ic, bu->handle ); + ic->flags &= ~IRC_CHANNEL_CHAT_PICKME; + } else + { irc_send_num( ic->irc, 482, "%s :IM protocol does not support room invitations", ic->name ); + } return TRUE; } -static const struct irc_channel_funcs irc_channel_im_chat_funcs = { +static char *set_eval_room_account( set_t *set, char *value ); + +static gboolean bee_irc_channel_init( irc_channel_t *ic ) +{ + set_add( &ic->set, "account", NULL, set_eval_room_account, ic ); + set_add( &ic->set, "chat_type", "groupchat", NULL, ic ); + set_add( &ic->set, "nick", NULL, NULL, ic ); + set_add( &ic->set, "room", NULL, NULL, ic ); + + return TRUE; +} + +static char *set_eval_room_account( set_t *set, char *value ) +{ + struct irc_channel *ic = set->data; + account_t *acc; + + if( !( acc = account_get( ic->irc->b, value ) ) ) + return SET_INVALID; + else if( !acc->prpl->chat_join ) + { + irc_usermsg( ic->irc, "Named chatrooms not supported on that account." ); + return SET_INVALID; + } + + return g_strdup_printf( "%s(%s)", acc->prpl->name, acc->user ); +} + +static gboolean bee_irc_channel_free( irc_channel_t *ic ) +{ + set_del( &ic->set, "account" ); + set_del( &ic->set, "chat_type" ); + set_del( &ic->set, "nick" ); + set_del( &ic->set, "room" ); + + return TRUE; +} + +const struct irc_channel_funcs irc_channel_im_chat_funcs = { bee_irc_channel_chat_privmsg, - NULL, /* join */ + bee_irc_channel_chat_join, bee_irc_channel_chat_part, bee_irc_channel_chat_topic, bee_irc_channel_chat_invite, + + bee_irc_channel_init, + bee_irc_channel_free, }; diff --git a/root_commands.c b/root_commands.c index cf1c169c..7c54e272 100644 --- a/root_commands.c +++ b/root_commands.c @@ -979,6 +979,11 @@ static void cmd_chat( irc_t *irc, char **cmd ) irc_usermsg( irc, "Invalid account" ); return; } + else if( !acc->prpl->chat_join ) + { + irc_usermsg( irc, "Named chatrooms not supported on that account." ); + return; + } if( cmd[4] == NULL ) { @@ -998,13 +1003,19 @@ static void cmd_chat( irc_t *irc, char **cmd ) channel = s; } - if( ( ic = irc_channel_new( irc, channel ) ) ) + if( ( ic = irc_channel_new( irc, channel ) ) && + set_setstr( &ic->set, "chat_type", "room" ) && + set_setstr( &ic->set, "account", cmd[2] ) && + set_setstr( &ic->set, "room", cmd[3] ) ) + { + irc_usermsg( irc, "Chatroom successfully added." ); + } + else { - struct irc_groupchat_stub *igs; + if( ic ) + irc_channel_free( ic ); - ic->data = igs = g_new0( struct irc_groupchat_stub, 1 ); - igs->acc = acc; - igs->room = g_strdup( cmd[3] ); + irc_usermsg( irc, "Could not add chatroom." ); } } /* |