4 * Purple is the legal property of its developers, whose names are too numerous
5 * to list here. Please refer to the COPYRIGHT file distributed with this
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
24 /* This file is the fullcrap */
28 #include "conversation.h"
41 #define SECS_BEFORE_RESENDING_AUTORESPONSE 600
42 #define SEX_BEFORE_RESENDING_AUTORESPONSE "Only after you're married"
45 serv_send_typing(PurpleConnection
*gc
, const char *name
, PurpleTypingState state
)
48 PurplePluginProtocolInfo
*prpl_info
;
51 prpl
= purple_connection_get_prpl(gc
);
52 prpl_info
= PURPLE_PLUGIN_PROTOCOL_INFO(prpl
);
54 if (prpl_info
->send_typing
)
55 return prpl_info
->send_typing(gc
, name
, state
);
61 static GSList
*last_auto_responses
= NULL
;
62 struct last_auto_response
{
69 expire_last_auto_responses(gpointer data
)
72 struct last_auto_response
*lar
;
74 tmp
= last_auto_responses
;
79 lar
= (struct last_auto_response
*)cur
->data
;
81 if ((time(NULL
) - lar
->sent
) > SECS_BEFORE_RESENDING_AUTORESPONSE
) {
82 last_auto_responses
= g_slist_remove(last_auto_responses
, lar
);
87 return FALSE
; /* do not run again */
90 static struct last_auto_response
*
91 get_last_auto_response(PurpleConnection
*gc
, const char *name
)
94 struct last_auto_response
*lar
;
96 /* because we're modifying or creating a lar, schedule the
97 * function to expire them as the pref dictates */
98 purple_timeout_add_seconds((SECS_BEFORE_RESENDING_AUTORESPONSE
+ 1), expire_last_auto_responses
, NULL
);
100 tmp
= last_auto_responses
;
103 lar
= (struct last_auto_response
*)tmp
->data
;
105 if (gc
== lar
->gc
&& !strncmp(name
, lar
->name
, sizeof(lar
->name
)))
111 lar
= (struct last_auto_response
*)g_new0(struct last_auto_response
, 1);
112 g_snprintf(lar
->name
, sizeof(lar
->name
), "%s", name
);
115 last_auto_responses
= g_slist_prepend(last_auto_responses
, lar
);
120 int serv_send_im(PurpleConnection
*gc
, const char *name
, const char *message
,
121 PurpleMessageFlags flags
)
123 PurpleConversation
*conv
= NULL
;
124 PurpleAccount
*account
= NULL
;
125 PurplePresence
*presence
= NULL
;
126 PurplePlugin
*prpl
= NULL
;
127 PurplePluginProtocolInfo
*prpl_info
= NULL
;
129 const gchar
*auto_reply_pref
= NULL
;
131 g_return_val_if_fail(gc
!= NULL
, val
);
133 prpl
= purple_connection_get_prpl(gc
);
135 g_return_val_if_fail(prpl
!= NULL
, val
);
137 prpl_info
= PURPLE_PLUGIN_PROTOCOL_INFO(prpl
);
139 account
= purple_connection_get_account(gc
);
140 presence
= purple_account_get_presence(account
);
142 conv
= purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM
, name
, account
);
144 if (prpl_info
->send_im
)
145 val
= prpl_info
->send_im(gc
, name
, message
, flags
);
148 * XXX - If "only auto-reply when away & idle" is set, then shouldn't
149 * this only reset lar->sent if we're away AND idle?
151 auto_reply_pref
= purple_prefs_get_string("/purple/away/auto_reply");
152 if((gc
->flags
& PURPLE_CONNECTION_AUTO_RESP
) &&
153 !purple_presence_is_available(presence
) &&
154 !purple_strequal(auto_reply_pref
, "never")) {
156 struct last_auto_response
*lar
;
157 lar
= get_last_auto_response(gc
, name
);
158 lar
->sent
= time(NULL
);
161 if(conv
&& purple_conv_im_get_send_typed_timeout(PURPLE_CONV_IM(conv
)))
162 purple_conv_im_stop_send_typed_timeout(PURPLE_CONV_IM(conv
));
167 void serv_get_info(PurpleConnection
*gc
, const char *name
)
170 PurplePluginProtocolInfo
*prpl_info
;
173 prpl
= purple_connection_get_prpl(gc
);
174 prpl_info
= PURPLE_PLUGIN_PROTOCOL_INFO(prpl
);
176 if (prpl_info
->get_info
)
177 prpl_info
->get_info(gc
, name
);
181 void serv_set_info(PurpleConnection
*gc
, const char *info
)
184 PurplePluginProtocolInfo
*prpl_info
;
185 PurpleAccount
*account
;
188 prpl
= purple_connection_get_prpl(gc
);
189 prpl_info
= PURPLE_PLUGIN_PROTOCOL_INFO(prpl
);
191 if (prpl_info
->set_info
) {
192 account
= purple_connection_get_account(gc
);
194 if (purple_signal_emit_return_1(purple_accounts_get_handle(),
195 "account-setting-info", account
, info
))
198 prpl_info
->set_info(gc
, info
);
200 purple_signal_emit(purple_accounts_get_handle(),
201 "account-set-info", account
, info
);
207 * Set buddy's alias on server roster/list
209 void serv_alias_buddy(PurpleBuddy
*b
)
211 PurpleAccount
*account
;
212 PurpleConnection
*gc
;
214 PurplePluginProtocolInfo
*prpl_info
;
217 account
= purple_buddy_get_account(b
);
220 gc
= purple_account_get_connection(account
);
223 prpl
= purple_connection_get_prpl(gc
);
224 prpl_info
= PURPLE_PLUGIN_PROTOCOL_INFO(prpl
);
226 if (prpl_info
->alias_buddy
)
227 prpl_info
->alias_buddy(gc
,
228 purple_buddy_get_name(b
),
229 purple_buddy_get_local_buddy_alias(b
));
236 serv_got_alias(PurpleConnection
*gc
, const char *who
, const char *alias
)
238 PurpleAccount
*account
;
241 PurpleConversation
*conv
;
243 account
= purple_connection_get_account(gc
);
244 buddies
= purple_find_buddies(account
, who
);
246 while (buddies
!= NULL
)
248 const char *server_alias
;
251 buddies
= g_slist_delete_link(buddies
, buddies
);
253 server_alias
= purple_buddy_get_server_alias(b
);
255 if (purple_strequal(server_alias
, alias
))
258 purple_blist_server_alias_buddy(b
, alias
);
260 conv
= purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM
, purple_buddy_get_name(b
), account
);
261 if (conv
!= NULL
&& alias
!= NULL
&& !purple_strequal(alias
, who
))
263 char *escaped
= g_markup_escape_text(who
, -1);
264 char *escaped2
= g_markup_escape_text(alias
, -1);
265 char *tmp
= g_strdup_printf(_("%s is now known as %s.\n"),
268 purple_conversation_write(conv
, NULL
, tmp
,
269 PURPLE_MESSAGE_SYSTEM
| PURPLE_MESSAGE_NO_LINKIFY
,
280 purple_serv_got_private_alias(PurpleConnection
*gc
, const char *who
, const char *alias
)
282 PurpleAccount
*account
= NULL
;
283 GSList
*buddies
= NULL
;
284 PurpleBuddy
*b
= NULL
;
286 account
= purple_connection_get_account(gc
);
287 buddies
= purple_find_buddies(account
, who
);
289 while(buddies
!= NULL
) {
293 buddies
= g_slist_delete_link(buddies
, buddies
);
295 balias
= purple_buddy_get_local_buddy_alias(b
);
296 if (purple_strequal(balias
, alias
))
299 purple_blist_alias_buddy(b
, alias
);
304 PurpleAttentionType
*purple_get_attention_type_from_code(PurpleAccount
*account
, guint type_code
)
307 PurpleAttentionType
* attn
;
308 GList
*(*get_attention_types
)(PurpleAccount
*);
310 g_return_val_if_fail(account
!= NULL
, NULL
);
312 prpl
= purple_find_prpl(purple_account_get_protocol_id(account
));
314 /* Lookup the attention type in the protocol's attention_types list, if any. */
315 get_attention_types
= PURPLE_PLUGIN_PROTOCOL_INFO(prpl
)->get_attention_types
;
316 if (get_attention_types
) {
317 GList
*attention_types
;
319 attention_types
= get_attention_types(account
);
320 attn
= (PurpleAttentionType
*)g_list_nth_data(attention_types
, type_code
);
329 serv_send_attention(PurpleConnection
*gc
, const char *who
, guint type_code
)
331 purple_prpl_send_attention(gc
, who
, type_code
);
335 serv_got_attention(PurpleConnection
*gc
, const char *who
, guint type_code
)
337 purple_prpl_got_attention(gc
, who
, type_code
);
342 * Move a buddy from one group to another on server.
344 * Note: For now we'll not deal with changing gc's at the same time, but
345 * it should be possible. Probably needs to be done, someday. Although,
346 * the UI for that would be difficult, because groups are Purple-wide.
348 void serv_move_buddy(PurpleBuddy
*b
, PurpleGroup
*og
, PurpleGroup
*ng
)
350 PurpleAccount
*account
;
351 PurpleConnection
*gc
;
353 PurplePluginProtocolInfo
*prpl_info
;
355 g_return_if_fail(b
!= NULL
);
356 g_return_if_fail(og
!= NULL
);
357 g_return_if_fail(ng
!= NULL
);
359 account
= purple_buddy_get_account(b
);
360 gc
= purple_account_get_connection(account
);
363 prpl
= purple_connection_get_prpl(gc
);
364 prpl_info
= PURPLE_PLUGIN_PROTOCOL_INFO(prpl
);
366 if (prpl_info
->group_buddy
)
367 prpl_info
->group_buddy(gc
, purple_buddy_get_name(b
),
368 purple_group_get_name(og
),
369 purple_group_get_name(ng
));
373 void serv_add_permit(PurpleConnection
*gc
, const char *name
)
376 PurplePluginProtocolInfo
*prpl_info
;
379 prpl
= purple_connection_get_prpl(gc
);
380 prpl_info
= PURPLE_PLUGIN_PROTOCOL_INFO(prpl
);
382 if (prpl_info
->add_permit
)
383 prpl_info
->add_permit(gc
, name
);
387 void serv_add_deny(PurpleConnection
*gc
, const char *name
)
390 PurplePluginProtocolInfo
*prpl_info
;
393 prpl
= purple_connection_get_prpl(gc
);
394 prpl_info
= PURPLE_PLUGIN_PROTOCOL_INFO(prpl
);
396 if (prpl_info
->add_deny
)
397 prpl_info
->add_deny(gc
, name
);
401 void serv_rem_permit(PurpleConnection
*gc
, const char *name
)
404 PurplePluginProtocolInfo
*prpl_info
;
407 prpl
= purple_connection_get_prpl(gc
);
408 prpl_info
= PURPLE_PLUGIN_PROTOCOL_INFO(prpl
);
410 if (prpl_info
->rem_permit
)
411 prpl_info
->rem_permit(gc
, name
);
415 void serv_rem_deny(PurpleConnection
*gc
, const char *name
)
418 PurplePluginProtocolInfo
*prpl_info
;
421 prpl
= purple_connection_get_prpl(gc
);
422 prpl_info
= PURPLE_PLUGIN_PROTOCOL_INFO(prpl
);
424 if (prpl_info
->rem_deny
)
425 prpl_info
->rem_deny(gc
, name
);
429 void serv_set_permit_deny(PurpleConnection
*gc
)
432 PurplePluginProtocolInfo
*prpl_info
;
435 prpl
= purple_connection_get_prpl(gc
);
436 prpl_info
= PURPLE_PLUGIN_PROTOCOL_INFO(prpl
);
439 * this is called when either you import a buddy list, and make lots
440 * of changes that way, or when the user toggles the permit/deny mode
441 * in the prefs. In either case you should probably be resetting and
442 * resending the permit/deny info when you get this.
444 if (prpl_info
->set_permit_deny
)
445 prpl_info
->set_permit_deny(gc
);
449 void serv_join_chat(PurpleConnection
*gc
, GHashTable
*data
)
452 PurplePluginProtocolInfo
*prpl_info
;
455 prpl
= purple_connection_get_prpl(gc
);
456 prpl_info
= PURPLE_PLUGIN_PROTOCOL_INFO(prpl
);
458 if (prpl_info
->join_chat
)
459 prpl_info
->join_chat(gc
, data
);
464 void serv_reject_chat(PurpleConnection
*gc
, GHashTable
*data
)
467 PurplePluginProtocolInfo
*prpl_info
;
470 prpl
= purple_connection_get_prpl(gc
);
471 prpl_info
= PURPLE_PLUGIN_PROTOCOL_INFO(prpl
);
473 if (prpl_info
->reject_chat
)
474 prpl_info
->reject_chat(gc
, data
);
478 void serv_chat_invite(PurpleConnection
*gc
, int id
, const char *message
, const char *name
)
480 PurplePlugin
*prpl
= NULL
;
481 PurplePluginProtocolInfo
*prpl_info
= NULL
;
482 PurpleConversation
*conv
;
483 char *buffy
= message
&& *message
? g_strdup(message
) : NULL
;
485 conv
= purple_find_chat(gc
, id
);
491 prpl
= purple_connection_get_prpl(gc
);
494 prpl_info
= PURPLE_PLUGIN_PROTOCOL_INFO(prpl
);
496 purple_signal_emit(purple_conversations_get_handle(), "chat-inviting-user",
499 if (prpl_info
&& prpl_info
->chat_invite
)
500 prpl_info
->chat_invite(gc
, id
, buffy
, name
);
502 purple_signal_emit(purple_conversations_get_handle(), "chat-invited-user",
508 /* Ya know, nothing uses this except purple_conversation_destroy(),
509 * I think I'll just merge it into that later...
510 * Then again, something might want to use this, from outside prpl-land
511 * to leave a chat without destroying the conversation.
513 void serv_chat_leave(PurpleConnection
*gc
, int id
)
516 PurplePluginProtocolInfo
*prpl_info
;
518 prpl
= purple_connection_get_prpl(gc
);
519 prpl_info
= PURPLE_PLUGIN_PROTOCOL_INFO(prpl
);
521 if (prpl_info
->chat_leave
)
522 prpl_info
->chat_leave(gc
, id
);
525 void serv_chat_whisper(PurpleConnection
*gc
, int id
, const char *who
, const char *message
)
528 PurplePluginProtocolInfo
*prpl_info
;
531 prpl
= purple_connection_get_prpl(gc
);
532 prpl_info
= PURPLE_PLUGIN_PROTOCOL_INFO(prpl
);
534 if (prpl_info
->chat_whisper
)
535 prpl_info
->chat_whisper(gc
, id
, who
, message
);
539 int serv_chat_send(PurpleConnection
*gc
, int id
, const char *message
, PurpleMessageFlags flags
)
542 PurplePluginProtocolInfo
*prpl_info
;
544 prpl
= purple_connection_get_prpl(gc
);
545 prpl_info
= PURPLE_PLUGIN_PROTOCOL_INFO(prpl
);
547 if (prpl_info
->chat_send
)
548 return prpl_info
->chat_send(gc
, id
, message
, flags
);
554 * woo. i'm actually going to comment this function. isn't that fun. make
555 * sure to follow along, kids
557 void serv_got_im(PurpleConnection
*gc
, const char *who
, const char *msg
,
558 PurpleMessageFlags flags
, time_t mtime
)
560 PurpleAccount
*account
;
561 PurpleConversation
*conv
;
562 char *message
, *name
;
566 g_return_if_fail(msg
!= NULL
);
568 account
= purple_connection_get_account(gc
);
571 * XXX: Should we be setting this here, or relying on prpls to set it?
573 flags
|= PURPLE_MESSAGE_RECV
;
575 if (!purple_privacy_check(account
, who
)) {
576 purple_signal_emit(purple_conversations_get_handle(), "blocked-im-msg",
577 account
, who
, msg
, flags
, (unsigned int)mtime
);
582 * We should update the conversation window buttons and menu,
585 conv
= purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM
, who
, gc
->account
);
588 * Make copies of the message and the sender in case plugins want
589 * to free these strings and replace them with a modifed version.
591 buffy
= g_strdup(msg
);
592 angel
= g_strdup(who
);
594 plugin_return
= GPOINTER_TO_INT(
595 purple_signal_emit_return_1(purple_conversations_get_handle(),
596 "receiving-im-msg", gc
->account
,
597 &angel
, &buffy
, conv
, &flags
));
599 if (!buffy
|| !angel
|| plugin_return
) {
608 purple_signal_emit(purple_conversations_get_handle(), "received-im-msg", gc
->account
,
609 name
, message
, conv
, flags
);
611 /* search for conversation again in case it was created by received-im-msg handler */
613 conv
= purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM
, name
, gc
->account
);
616 conv
= purple_conversation_new(PURPLE_CONV_TYPE_IM
, account
, name
);
618 purple_conv_im_write(PURPLE_CONV_IM(conv
), name
, message
, flags
, mtime
);
622 * Don't autorespond if:
624 * - it's not supported on this connection
627 * - or we're not idle and the 'only auto respond if idle' pref
630 if (gc
->flags
& PURPLE_CONNECTION_AUTO_RESP
)
632 PurplePresence
*presence
;
633 PurpleStatus
*status
;
634 PurpleStatusType
*status_type
;
635 PurpleStatusPrimitive primitive
;
636 const gchar
*auto_reply_pref
;
637 const char *away_msg
= NULL
;
638 gboolean mobile
= FALSE
;
640 auto_reply_pref
= purple_prefs_get_string("/purple/away/auto_reply");
642 presence
= purple_account_get_presence(account
);
643 status
= purple_presence_get_active_status(presence
);
644 status_type
= purple_status_get_type(status
);
645 primitive
= purple_status_type_get_primitive(status_type
);
646 mobile
= purple_presence_is_status_primitive_active(presence
, PURPLE_STATUS_MOBILE
);
647 if ((primitive
== PURPLE_STATUS_AVAILABLE
) ||
648 (primitive
== PURPLE_STATUS_INVISIBLE
) ||
650 purple_strequal(auto_reply_pref
, "never") ||
651 (!purple_presence_is_idle(presence
) && purple_strequal(auto_reply_pref
, "awayidle")))
657 away_msg
= purple_value_get_string(
658 purple_status_get_attr_value(status
, "message"));
660 if ((away_msg
!= NULL
) && (*away_msg
!= '\0')) {
661 struct last_auto_response
*lar
;
662 time_t now
= time(NULL
);
665 * This used to be based on the conversation window. But um, if
666 * you went away, and someone sent you a message and got your
667 * auto-response, and then you closed the window, and then they
668 * sent you another one, they'd get the auto-response back too
669 * soon. Besides that, we need to keep track of this even if we've
670 * got a queue. So the rest of this block is just the auto-response,
673 lar
= get_last_auto_response(gc
, name
);
674 if ((now
- lar
->sent
) >= SECS_BEFORE_RESENDING_AUTORESPONSE
)
677 * We don't want to send an autoresponse in response to the other user's
678 * autoresponse. We do, however, not want to then send one in response to the
679 * _next_ message, so we still set lar->sent to now.
683 if (!(flags
& PURPLE_MESSAGE_AUTO_RESP
))
685 serv_send_im(gc
, name
, away_msg
, PURPLE_MESSAGE_AUTO_RESP
);
687 purple_conv_im_write(PURPLE_CONV_IM(conv
), NULL
, away_msg
,
688 PURPLE_MESSAGE_SEND
| PURPLE_MESSAGE_AUTO_RESP
,
698 void serv_got_typing(PurpleConnection
*gc
, const char *name
, int timeout
,
699 PurpleTypingState state
) {
700 PurpleConversation
*conv
;
701 PurpleConvIm
*im
= NULL
;
703 conv
= purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM
, name
, gc
->account
);
705 im
= PURPLE_CONV_IM(conv
);
707 purple_conv_im_set_typing_state(im
, state
);
712 purple_signal_emit(purple_conversations_get_handle(),
713 "buddy-typing", gc
->account
, name
);
716 purple_signal_emit(purple_conversations_get_handle(),
717 "buddy-typed", gc
->account
, name
);
719 case PURPLE_NOT_TYPING
:
720 purple_signal_emit(purple_conversations_get_handle(),
721 "buddy-typing-stopped", gc
->account
, name
);
726 if (conv
!= NULL
&& timeout
> 0)
727 purple_conv_im_start_typing_timeout(im
, timeout
);
730 void serv_got_typing_stopped(PurpleConnection
*gc
, const char *name
) {
732 PurpleConversation
*conv
;
735 conv
= purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM
, name
, gc
->account
);
738 im
= PURPLE_CONV_IM(conv
);
740 if (im
->typing_state
== PURPLE_NOT_TYPING
)
743 purple_conv_im_stop_typing_timeout(im
);
744 purple_conv_im_set_typing_state(im
, PURPLE_NOT_TYPING
);
748 purple_signal_emit(purple_conversations_get_handle(),
749 "buddy-typing-stopped", gc
->account
, name
);
753 struct chat_invite_data
{
754 PurpleConnection
*gc
;
755 GHashTable
*components
;
758 static void chat_invite_data_free(struct chat_invite_data
*cid
)
761 g_hash_table_destroy(cid
->components
);
766 static void chat_invite_reject(struct chat_invite_data
*cid
)
768 serv_reject_chat(cid
->gc
, cid
->components
);
769 chat_invite_data_free(cid
);
773 static void chat_invite_accept(struct chat_invite_data
*cid
)
775 serv_join_chat(cid
->gc
, cid
->components
);
776 chat_invite_data_free(cid
);
781 void serv_got_chat_invite(PurpleConnection
*gc
, const char *name
,
782 const char *who
, const char *message
, GHashTable
*data
)
784 PurpleAccount
*account
;
786 struct chat_invite_data
*cid
;
789 g_return_if_fail(name
!= NULL
);
790 g_return_if_fail(who
!= NULL
);
792 account
= purple_connection_get_account(gc
);
793 if (!purple_privacy_check(account
, who
)) {
794 purple_signal_emit(purple_conversations_get_handle(), "chat-invite-blocked",
795 account
, who
, name
, message
, data
);
799 cid
= g_new0(struct chat_invite_data
, 1);
801 plugin_return
= GPOINTER_TO_INT(purple_signal_emit_return_1(
802 purple_conversations_get_handle(),
803 "chat-invited", account
, who
, name
, message
, data
));
806 cid
->components
= data
;
808 if (plugin_return
== 0)
812 g_snprintf(buf2
, sizeof(buf2
),
813 _("%s has invited %s to the chat room %s:\n%s"),
814 who
, purple_account_get_username(account
), name
, message
);
817 g_snprintf(buf2
, sizeof(buf2
),
818 _("%s has invited %s to the chat room %s\n"),
819 who
, purple_account_get_username(account
), name
);
822 purple_request_accept_cancel(gc
, NULL
, _("Accept chat invitation?"), buf2
,
823 PURPLE_DEFAULT_ACTION_NONE
, account
, who
, NULL
,
824 cid
, G_CALLBACK(chat_invite_accept
),
825 G_CALLBACK(chat_invite_reject
));
827 else if (plugin_return
> 0)
828 chat_invite_accept(cid
);
830 chat_invite_reject(cid
);
833 PurpleConversation
*serv_got_joined_chat(PurpleConnection
*gc
,
834 int id
, const char *name
)
836 PurpleConversation
*conv
;
837 PurpleConvChat
*chat
;
838 PurpleAccount
*account
;
840 account
= purple_connection_get_account(gc
);
842 g_return_val_if_fail(account
!= NULL
, NULL
);
843 g_return_val_if_fail(name
!= NULL
, NULL
);
845 conv
= purple_conversation_new(PURPLE_CONV_TYPE_CHAT
, account
, name
);
846 g_return_val_if_fail(conv
!= NULL
, NULL
);
848 chat
= PURPLE_CONV_CHAT(conv
);
850 if (!g_slist_find(gc
->buddy_chats
, conv
))
851 gc
->buddy_chats
= g_slist_append(gc
->buddy_chats
, conv
);
853 purple_conv_chat_set_id(chat
, id
);
855 purple_signal_emit(purple_conversations_get_handle(), "chat-joined", conv
);
860 void serv_got_chat_left(PurpleConnection
*g
, int id
)
863 PurpleConversation
*conv
= NULL
;
864 PurpleConvChat
*chat
= NULL
;
866 for (bcs
= g
->buddy_chats
; bcs
!= NULL
; bcs
= bcs
->next
) {
867 conv
= (PurpleConversation
*)bcs
->data
;
869 chat
= PURPLE_CONV_CHAT(conv
);
871 if (purple_conv_chat_get_id(chat
) == id
)
880 purple_debug(PURPLE_DEBUG_INFO
, "server", "Leaving room: %s\n",
881 purple_conversation_get_name(conv
));
883 g
->buddy_chats
= g_slist_remove(g
->buddy_chats
, conv
);
885 purple_conv_chat_left(PURPLE_CONV_CHAT(conv
));
887 purple_signal_emit(purple_conversations_get_handle(), "chat-left", conv
);
890 void purple_serv_got_join_chat_failed(PurpleConnection
*gc
, GHashTable
*data
)
892 purple_signal_emit(purple_conversations_get_handle(), "chat-join-failed",
896 void serv_got_chat_in(PurpleConnection
*g
, int id
, const char *who
,
897 PurpleMessageFlags flags
, const char *message
, time_t mtime
)
900 PurpleConversation
*conv
= NULL
;
901 PurpleConvChat
*chat
= NULL
;
905 g_return_if_fail(who
!= NULL
);
906 g_return_if_fail(message
!= NULL
);
908 for (bcs
= g
->buddy_chats
; bcs
!= NULL
; bcs
= bcs
->next
) {
909 conv
= (PurpleConversation
*)bcs
->data
;
911 chat
= PURPLE_CONV_CHAT(conv
);
913 if (purple_conv_chat_get_id(chat
) == id
)
922 /* Did I send the message? */
923 if (purple_strequal(purple_conv_chat_get_nick(chat
),
924 purple_normalize(purple_conversation_get_account(conv
), who
))) {
925 flags
|= PURPLE_MESSAGE_SEND
;
926 flags
&= ~PURPLE_MESSAGE_RECV
; /* Just in case some prpl sets it! */
928 flags
|= PURPLE_MESSAGE_RECV
;
932 * Make copies of the message and the sender in case plugins want
933 * to free these strings and replace them with a modifed version.
935 buffy
= g_strdup(message
);
936 angel
= g_strdup(who
);
938 plugin_return
= GPOINTER_TO_INT(
939 purple_signal_emit_return_1(purple_conversations_get_handle(),
940 "receiving-chat-msg", g
->account
,
941 &angel
, &buffy
, conv
, &flags
));
943 if (!buffy
|| !angel
|| plugin_return
) {
952 purple_signal_emit(purple_conversations_get_handle(), "received-chat-msg", g
->account
,
953 who
, message
, conv
, flags
);
955 purple_conv_chat_write(chat
, who
, message
, flags
, mtime
);
961 void serv_send_file(PurpleConnection
*gc
, const char *who
, const char *file
)
964 PurplePluginProtocolInfo
*prpl_info
;
967 prpl
= purple_connection_get_prpl(gc
);
968 prpl_info
= PURPLE_PLUGIN_PROTOCOL_INFO(prpl
);
970 if (prpl_info
->send_file
&&
971 (!prpl_info
->can_receive_file
972 || prpl_info
->can_receive_file(gc
, who
)))
973 prpl_info
->send_file(gc
, who
, file
);