source: protocols/bee_chat.c @ 25c4c78

Last change on this file since 25c4c78 was 885d294, checked in by dequis <dx@…>, at 2015-01-16T19:50:24Z

bee-chat: create temporary users for unknown chat participants

The imcb_chat_msg() function is unable to send messages to a chat with
a user who was not previously added. This function should allow for the
sending of messages with users who are not added. This is suitable for
protocols which are sending messages to a chat from random users or a
large amount of users which join and part frequently.

  • Property mode set to 100644
File size: 6.6 KB
Line 
1  /********************************************************************\
2  * BitlBee -- An IRC to other IM-networks gateway                     *
3  *                                                                    *
4  * Copyright 2002-2010 Wilmer van der Gaast and others                *
5  \********************************************************************/
6
7/* Stuff to handle rooms                                                */
8
9/*
10  This program is free software; you can redistribute it and/or modify
11  it under the terms of the GNU General Public License as published by
12  the Free Software Foundation; either version 2 of the License, or
13  (at your option) any later version.
14
15  This program is distributed in the hope that it will be useful,
16  but WITHOUT ANY WARRANTY; without even the implied warranty of
17  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  GNU General Public License for more details.
19
20  You should have received a copy of the GNU General Public License with
21  the Debian GNU/Linux distribution in /usr/share/common-licenses/GPL;
22  if not, write to the Free Software Foundation, Inc., 51 Franklin St.,
23  Fifth Floor, Boston, MA  02110-1301  USA
24*/
25
26#define BITLBEE_CORE
27#include "bitlbee.h"
28
29struct groupchat *imcb_chat_new( struct im_connection *ic, const char *handle )
30{
31        struct groupchat *c = g_new0( struct groupchat, 1 );
32        bee_t *bee = ic->bee;
33       
34        /* This one just creates the conversation structure, user won't see
35           anything yet until s/he is joined to the conversation. (This
36           allows you to add other already present participants first.) */
37       
38        ic->groupchats = g_slist_prepend( ic->groupchats, c );
39        c->ic = ic;
40        c->title = g_strdup( handle );
41        c->topic = g_strdup_printf( "BitlBee groupchat: \"%s\". Please keep in mind that root-commands won't work here. Have fun!", c->title );
42       
43        if( set_getbool( &ic->bee->set, "debug" ) )
44                imcb_log( ic, "Creating new conversation: (id=%p,handle=%s)", c, handle );
45       
46        if( bee->ui->chat_new )
47                bee->ui->chat_new( bee, c );
48       
49        return c;
50}
51
52void imcb_chat_name_hint( struct groupchat *c, const char *name )
53{
54        bee_t *bee = c->ic->bee;
55       
56        if( bee->ui->chat_name_hint )
57                bee->ui->chat_name_hint( bee, c, name );
58}
59
60void imcb_chat_free( struct groupchat *c )
61{
62        struct im_connection *ic = c->ic;
63        bee_t *bee = ic->bee;
64        GList *ir;
65       
66        if( bee->ui->chat_free )
67                bee->ui->chat_free( bee, c );
68       
69        if( set_getbool( &ic->bee->set, "debug" ) )
70                imcb_log( ic, "You were removed from conversation %p", c );
71       
72        ic->groupchats = g_slist_remove( ic->groupchats, c );
73       
74        for( ir = c->in_room; ir; ir = ir->next )
75                g_free( ir->data );
76        g_list_free( c->in_room );
77        g_free( c->title );
78        g_free( c->topic );
79        g_free( c );
80}
81
82void imcb_chat_msg( struct groupchat *c, const char *who, char *msg, uint32_t flags, time_t sent_at )
83{
84        struct im_connection *ic = c->ic;
85        bee_t *bee = ic->bee;
86        bee_user_t *bu;
87        gboolean temp;
88        char *s;
89       
90        /* Gaim sends own messages through this too. IRC doesn't want this, so kill them */
91        if( g_strcasecmp( who, ic->acc->user ) == 0 )
92                return;
93       
94        bu = bee_user_by_handle( bee, ic, who );
95        temp = ( bu == NULL );
96       
97        if( temp )
98                bu = bee_user_new( bee, ic, who, BEE_USER_ONLINE );
99       
100        s = set_getstr( &ic->bee->set, "strip_html" );
101        if( ( g_strcasecmp( s, "always" ) == 0 ) ||
102            ( ( ic->flags & OPT_DOES_HTML ) && s ) )
103                strip_html( msg );
104       
105        if( bee->ui->chat_msg )
106                bee->ui->chat_msg( bee, c, bu, msg, sent_at );
107       
108        if( temp )
109                bee_user_free( bee, bu );
110}
111
112void imcb_chat_log( struct groupchat *c, char *format, ... )
113{
114        struct im_connection *ic = c->ic;
115        bee_t *bee = ic->bee;
116        va_list params;
117        char *text;
118       
119        if( !bee->ui->chat_log )
120                return;
121       
122        va_start( params, format );
123        text = g_strdup_vprintf( format, params );
124        va_end( params );
125       
126        bee->ui->chat_log( bee, c, text );
127        g_free( text );
128}
129
130void imcb_chat_topic( struct groupchat *c, char *who, char *topic, time_t set_at )
131{
132        struct im_connection *ic = c->ic;
133        bee_t *bee = ic->bee;
134        bee_user_t *bu;
135       
136        if( !bee->ui->chat_topic )
137                return;
138       
139        if( who == NULL)
140                bu = NULL;
141        else if( g_strcasecmp( who, ic->acc->user ) == 0 )
142                bu = bee->user;
143        else
144                bu = bee_user_by_handle( bee, ic, who );
145       
146        if( ( g_strcasecmp( set_getstr( &ic->bee->set, "strip_html" ), "always" ) == 0 ) ||
147            ( ( ic->flags & OPT_DOES_HTML ) && set_getbool( &ic->bee->set, "strip_html" ) ) )
148                strip_html( topic );
149       
150        bee->ui->chat_topic( bee, c, topic, bu );
151}
152
153void imcb_chat_add_buddy( struct groupchat *c, const char *handle )
154{
155        struct im_connection *ic = c->ic;
156        bee_t *bee = ic->bee;
157        bee_user_t *bu = bee_user_by_handle( bee, ic, handle );
158        gboolean me;
159       
160        if( set_getbool( &c->ic->bee->set, "debug" ) )
161                imcb_log( c->ic, "User %s added to conversation %p", handle, c );
162       
163        me = ic->acc->prpl->handle_cmp( handle, ic->acc->user ) == 0;
164       
165        /* Most protocols allow people to join, even when they're not in
166           your contact list. Try to handle that here */
167        if( !me && !bu )
168                bu = bee_user_new( bee, ic, handle, BEE_USER_LOCAL );
169       
170        /* Add the handle to the room userlist */
171        /* TODO: Use bu instead of a string */
172        c->in_room = g_list_append( c->in_room, g_strdup( handle ) );
173       
174        if( bee->ui->chat_add_user )
175                bee->ui->chat_add_user( bee, c, me ? bee->user : bu );
176       
177        if( me )
178                c->joined = 1;
179}
180
181void imcb_chat_remove_buddy( struct groupchat *c, const char *handle, const char *reason )
182{
183        struct im_connection *ic = c->ic;
184        bee_t *bee = ic->bee;
185        bee_user_t *bu = NULL;
186       
187        if( set_getbool( &bee->set, "debug" ) )
188                imcb_log( ic, "User %s removed from conversation %p (%s)", handle, c, reason ? reason : "" );
189       
190        /* It might be yourself! */
191        if( g_strcasecmp( handle, ic->acc->user ) == 0 )
192        {
193                if( c->joined == 0 )
194                        return;
195               
196                bu = bee->user;
197                c->joined = 0;
198        }
199        else
200        {
201                bu = bee_user_by_handle( bee, ic, handle );
202        }
203       
204        if( bee->ui->chat_remove_user && bu )
205                bee->ui->chat_remove_user( bee, c, bu );
206}
207
208int bee_chat_msg( bee_t *bee, struct groupchat *c, const char *msg, int flags )
209{
210        struct im_connection *ic = c->ic;
211        char *buf = NULL;
212       
213        if( ( ic->flags & OPT_DOES_HTML ) && ( g_strncasecmp( msg, "<html>", 6 ) != 0 ) )
214        {
215                buf = escape_html( msg );
216                msg = buf;
217        }
218        else
219                buf = g_strdup( msg );
220       
221        ic->acc->prpl->chat_msg( c, buf, flags );
222        g_free( buf );
223       
224        return 1;
225}
226
227struct groupchat *bee_chat_by_title( bee_t *bee, struct im_connection *ic, const char *title )
228{
229        struct groupchat *c;
230        GSList *l;
231       
232        for( l = ic->groupchats; l; l = l->next )
233        {
234                c = l->data;
235                if( strcmp( c->title, title ) == 0 )
236                        return c;
237        }
238       
239        return NULL;
240}
241
242void imcb_chat_invite( struct im_connection *ic, const char *name, const char *who, const char *msg )
243{
244        bee_user_t *bu = bee_user_by_handle( ic->bee, ic, who );
245       
246        if( bu && ic->bee->ui->chat_invite )
247                ic->bee->ui->chat_invite( ic->bee, bu, name, msg );
248}
Note: See TracBrowser for help on using the repository browser.