libpurple/protocols/gg/gg.c

changeset 34350
89441dbabc83
parent 34348
15361867e114
child 34352
16ee13f507a0
equal deleted inserted replaced
34349:dab5af140c43 34350:89441dbabc83
37 #include "util.h" 37 #include "util.h"
38 #include "request.h" 38 #include "request.h"
39 #include "xmlnode.h" 39 #include "xmlnode.h"
40 40
41 #include "gg.h" 41 #include "gg.h"
42 #include "confer.h" 42 #include "chat.h"
43 #include "search.h" 43 #include "search.h"
44 #include "buddylist.h" 44 #include "buddylist.h"
45 #include "utils.h" 45 #include "utils.h"
46 #include "resolver-purple.h" 46 #include "resolver-purple.h"
47 #include "account.h" 47 #include "account.h"
59 { 59 {
60 ggp_buddy_data *buddy_data = purple_buddy_get_protocol_data(buddy); 60 ggp_buddy_data *buddy_data = purple_buddy_get_protocol_data(buddy);
61 if (buddy_data) 61 if (buddy_data)
62 return buddy_data; 62 return buddy_data;
63 63
64 buddy_data = g_new0(ggp_buddy_data, 1); 64 buddy_data = g_new0(ggp_buddy_data, 1); //TODO: leak
65 purple_buddy_set_protocol_data(buddy, buddy_data); 65 purple_buddy_set_protocol_data(buddy, buddy_data);
66 return buddy_data; 66 return buddy_data;
67 } 67 }
68 68
69 static void ggp_buddy_free(PurpleBuddy *buddy) 69 static void ggp_buddy_free(PurpleBuddy *buddy)
166 G_CALLBACK(ggp_callback_buddylist_load_ok), NULL, 166 G_CALLBACK(ggp_callback_buddylist_load_ok), NULL,
167 purple_connection_get_account(gc), NULL, NULL, 167 purple_connection_get_account(gc), NULL, NULL,
168 gc); 168 gc);
169 } 169 }
170 170
171 /* ----- CONFERENCES ---------------------------------------------------- */
172
173 static void ggp_callback_add_to_chat_ok(PurpleBuddy *buddy, PurpleRequestFields *fields)
174 {
175 PurpleConnection *conn;
176 PurpleRequestField *field;
177 GList *sel;
178
179 conn = purple_account_get_connection(purple_buddy_get_account(buddy));
180
181 g_return_if_fail(conn != NULL);
182
183 field = purple_request_fields_get_field(fields, "name");
184 sel = purple_request_field_list_get_selected(field);
185
186 if (sel == NULL) {
187 purple_debug_error("gg", "No chat selected\n");
188 return;
189 }
190
191 ggp_confer_participants_add_uin(conn, sel->data,
192 ggp_str_to_uin(purple_buddy_get_name(buddy)));
193 }
194
195 static void ggp_bmenu_add_to_chat(PurpleBlistNode *node, gpointer ignored)
196 {
197 PurpleBuddy *buddy;
198 PurpleConnection *gc;
199 GGPInfo *info;
200
201 PurpleRequestFields *fields;
202 PurpleRequestFieldGroup *group;
203 PurpleRequestField *field;
204
205 GList *l;
206 gchar *msg;
207
208 buddy = (PurpleBuddy *)node;
209 gc = purple_account_get_connection(purple_buddy_get_account(buddy));
210 info = purple_connection_get_protocol_data(gc);
211
212 fields = purple_request_fields_new();
213 group = purple_request_field_group_new(NULL);
214 purple_request_fields_add_group(fields, group);
215
216 field = purple_request_field_list_new("name", "Chat name");
217 for (l = info->chats; l != NULL; l = l->next) {
218 GGPChat *chat = l->data;
219 purple_request_field_list_add_icon(field, chat->name, NULL, chat->name);
220 }
221 purple_request_field_group_add_field(group, field);
222
223 msg = g_strdup_printf(_("Select a chat for buddy: %s"),
224 purple_buddy_get_alias(buddy));
225 purple_request_fields(gc,
226 _("Add to chat..."),
227 _("Add to chat..."),
228 msg,
229 fields,
230 _("Add"), G_CALLBACK(ggp_callback_add_to_chat_ok),
231 _("Cancel"), NULL,
232 purple_connection_get_account(gc), NULL, NULL,
233 buddy);
234 g_free(msg);
235 }
236
237 /* ----- BLOCK BUDDIES -------------------------------------------------- */ 171 /* ----- BLOCK BUDDIES -------------------------------------------------- */
238 172
239 static void ggp_add_deny(PurpleConnection *gc, const char *who) 173 static void ggp_add_deny(PurpleConnection *gc, const char *who)
240 { 174 {
241 GGPInfo *info = purple_connection_get_protocol_data(gc); 175 GGPInfo *info = purple_connection_get_protocol_data(gc);
271 * Image receiving, some code borrowed from Kadu http://www.kadu.net 205 * Image receiving, some code borrowed from Kadu http://www.kadu.net
272 */ 206 */
273 void ggp_recv_message_handler(PurpleConnection *gc, const struct gg_event_msg *ev, gboolean multilogon) 207 void ggp_recv_message_handler(PurpleConnection *gc, const struct gg_event_msg *ev, gboolean multilogon)
274 { 208 {
275 GGPInfo *info = purple_connection_get_protocol_data(gc); 209 GGPInfo *info = purple_connection_get_protocol_data(gc);
276 PurpleConversation *conv;
277 gchar *from; 210 gchar *from;
278 gchar *msg; 211 gchar *msg;
279 gchar *tmp; 212 gchar *tmp;
280 time_t mtime; 213 time_t mtime;
281 uin_t sender = ev->sender; 214 uin_t sender = ev->sender;
409 purple_debug_info("gg", "ggp_recv_message_handler: msg from (%s): %s (class = %d; rcpt_count = %d; multilogon = %d; chat_id = %llu)\n", 342 purple_debug_info("gg", "ggp_recv_message_handler: msg from (%s): %s (class = %d; rcpt_count = %d; multilogon = %d; chat_id = %llu)\n",
410 from, msg, ev->msgclass, 343 from, msg, ev->msgclass,
411 ev->recipients_count, 344 ev->recipients_count,
412 multilogon, ev->chat_id); 345 multilogon, ev->chat_id);
413 346
414 if (multilogon && ev->recipients_count != 0) { 347 if (ev->chat_id != 0) {
415 purple_debug_warning("gg", "ggp_recv_message_handler: conference multilogon messages are not yet handled\n"); 348 ggp_chat_got_message(gc, ev->chat_id, msg, mtime, ev->sender);
416 } else if (multilogon) { 349 } else if (multilogon) {
417 PurpleAccount *account = purple_connection_get_account(gc); 350 PurpleAccount *account = purple_connection_get_account(gc);
418 PurpleConversation *conv; 351 PurpleConversation *conv;
419 const gchar *who = ggp_uin_to_str(ev->sender); // not really sender 352 const gchar *who = ggp_uin_to_str(ev->sender); // not really sender
420 conv = purple_find_conversation_with_account( 353 conv = purple_find_conversation_with_account(
423 conv = purple_conversation_new(PURPLE_CONV_TYPE_IM, account, who); 356 conv = purple_conversation_new(PURPLE_CONV_TYPE_IM, account, who);
424 purple_conversation_write(conv, purple_account_get_username(account), msg, PURPLE_MESSAGE_SEND, mtime); 357 purple_conversation_write(conv, purple_account_get_username(account), msg, PURPLE_MESSAGE_SEND, mtime);
425 } else if (ev->recipients_count == 0) { 358 } else if (ev->recipients_count == 0) {
426 serv_got_im(gc, from, msg, 0, mtime); 359 serv_got_im(gc, from, msg, 0, mtime);
427 } else { 360 } else {
428 const char *chat_name; 361 purple_debug_fatal("gg", "ggp_recv_message_handler: not handled\n");
429 int chat_id;
430
431 chat_name = ggp_confer_find_by_participants(gc,
432 ev->recipients,
433 ev->recipients_count);
434
435 if (chat_name == NULL) {
436 chat_name = ggp_confer_add_new(gc, NULL);
437 serv_got_joined_chat(gc, info->chats_count, chat_name);
438
439 ggp_confer_participants_add_uin(gc, chat_name,
440 ev->sender);
441
442 ggp_confer_participants_add(gc, chat_name,
443 ev->recipients,
444 ev->recipients_count);
445 }
446 conv = ggp_confer_find_by_name(gc, chat_name);
447 chat_id = purple_conv_chat_get_id(PURPLE_CONV_CHAT(conv));
448
449 serv_got_chat_in(gc, chat_id,
450 ggp_buddylist_get_buddy_name(gc, ev->sender),
451 PURPLE_MESSAGE_RECV, msg, mtime);
452 } 362 }
453 g_free(msg); 363 g_free(msg);
454 g_free(from); 364 g_free(from);
455 } 365 }
456 366
479 xmlnode *xml = NULL; 389 xmlnode *xml = NULL;
480 xmlnode *xmlnode_next_event; 390 xmlnode *xmlnode_next_event;
481 391
482 xml = xmlnode_from_str(data, -1); 392 xml = xmlnode_from_str(data, -1);
483 if (xml == NULL) 393 if (xml == NULL)
394 {
395 purple_debug_error("gg", "ggp_xml_event_handler: "
396 "invalid xml: [%s]\n", data);
484 goto out; 397 goto out;
398 }
485 399
486 xmlnode_next_event = xmlnode_get_child(xml, "event"); 400 xmlnode_next_event = xmlnode_get_child(xml, "event");
487 while (xmlnode_next_event != NULL) 401 while (xmlnode_next_event != NULL)
488 { 402 {
489 xmlnode *xmlnode_current_event = xmlnode_next_event; 403 xmlnode *xmlnode_current_event = xmlnode_next_event;
599 case GG_EVENT_IMTOKEN: 513 case GG_EVENT_IMTOKEN:
600 purple_debug_info("gg", "gg11: got IMTOKEN %s\n", ev->event.imtoken.imtoken); 514 purple_debug_info("gg", "gg11: got IMTOKEN %s\n", ev->event.imtoken.imtoken);
601 break; 515 break;
602 case GG_EVENT_PONG110: 516 case GG_EVENT_PONG110:
603 purple_debug_info("gg", "gg11: got PONG110 %lu\n", ev->event.pong110.time); 517 purple_debug_info("gg", "gg11: got PONG110 %lu\n", ev->event.pong110.time);
518 break;
519 case GG_EVENT_JSON_EVENT:
520 purple_debug_info("gg", "gg11: got JSON event\n");
521 break;
522 case GG_EVENT_CHAT_INFO:
523 case GG_EVENT_CHAT_INFO_UPDATE:
524 case GG_EVENT_CHAT_CREATED:
525 case GG_EVENT_CHAT_INVITE_ACK:
526 case GG_EVENT_CHAT_SEND_MSG_ACK:
527 ggp_chat_got_event(gc, ev);
604 break; 528 break;
605 default: 529 default:
606 purple_debug_warning("gg", 530 purple_debug_warning("gg",
607 "unsupported event type=%d\n", ev->type); 531 "unsupported event type=%d\n", ev->type);
608 break; 532 break;
839 } else if (PURPLE_BUDDY_IS_ONLINE(b)) { 763 } else if (PURPLE_BUDDY_IS_ONLINE(b)) {
840 purple_notify_user_info_add_pair_plaintext(user_info, _("Status"), name); 764 purple_notify_user_info_add_pair_plaintext(user_info, _("Status"), name);
841 } 765 }
842 } 766 }
843 767
844 static GList *ggp_blist_node_menu(PurpleBlistNode *node)
845 {
846 PurpleMenuAction *act;
847 GList *m = NULL;
848 PurpleAccount *account;
849 PurpleConnection *gc;
850 GGPInfo *info;
851
852 if (!PURPLE_BLIST_NODE_IS_BUDDY(node))
853 return NULL;
854
855 account = purple_buddy_get_account((PurpleBuddy *) node);
856 gc = purple_account_get_connection(account);
857 info = purple_connection_get_protocol_data(gc);
858 if (info->chats) {
859 act = purple_menu_action_new(_("Add to chat"),
860 PURPLE_CALLBACK(ggp_bmenu_add_to_chat),
861 NULL, NULL);
862 m = g_list_append(m, act);
863 }
864
865 return m;
866 }
867
868 static GList *ggp_chat_info(PurpleConnection *gc)
869 {
870 GList *m = NULL;
871 struct proto_chat_entry *pce;
872
873 pce = g_new0(struct proto_chat_entry, 1);
874 pce->label = _("Chat _name:");
875 pce->identifier = "name";
876 pce->required = TRUE;
877 m = g_list_append(m, pce);
878
879 return m;
880 }
881
882 static void ggp_login(PurpleAccount *account) 768 static void ggp_login(PurpleAccount *account)
883 { 769 {
884 PurpleConnection *gc = purple_account_get_connection(account); 770 PurpleConnection *gc = purple_account_get_connection(account);
885 struct gg_login_params *glp; 771 struct gg_login_params *glp;
886 GGPInfo *info; 772 GGPInfo *info;
893 glp = g_new0(struct gg_login_params, 1); 779 glp = g_new0(struct gg_login_params, 1);
894 info = g_new0(GGPInfo, 1); 780 info = g_new0(GGPInfo, 1);
895 781
896 /* Probably this should be moved to *_new() function. */ 782 /* Probably this should be moved to *_new() function. */
897 info->session = NULL; 783 info->session = NULL;
898 info->chats = NULL;
899 info->chats_count = 0;
900 784
901 purple_connection_set_protocol_data(gc, info); 785 purple_connection_set_protocol_data(gc, info);
902
903 786
904 ggp_image_setup(gc); 787 ggp_image_setup(gc);
905 ggp_avatar_setup(gc); 788 ggp_avatar_setup(gc);
906 ggp_roster_setup(gc); 789 ggp_roster_setup(gc);
907 ggp_multilogon_setup(gc); 790 ggp_multilogon_setup(gc);
908 ggp_status_setup(gc); 791 ggp_status_setup(gc);
909 792 ggp_chat_setup(gc);
793
910 glp->uin = ggp_str_to_uin(purple_account_get_username(account)); 794 glp->uin = ggp_str_to_uin(purple_account_get_username(account));
911 glp->password = ggp_convert_to_cp1250(purple_account_get_password(account)); 795 glp->password = ggp_convert_to_cp1250(purple_account_get_password(account));
912 796
913 if (glp->uin == 0) { 797 if (glp->uin == 0) {
914 purple_connection_error(gc, 798 purple_connection_error(gc,
1013 ggp_image_cleanup(gc); 897 ggp_image_cleanup(gc);
1014 ggp_avatar_cleanup(gc); 898 ggp_avatar_cleanup(gc);
1015 ggp_roster_cleanup(gc); 899 ggp_roster_cleanup(gc);
1016 ggp_multilogon_cleanup(gc); 900 ggp_multilogon_cleanup(gc);
1017 ggp_status_cleanup(gc); 901 ggp_status_cleanup(gc);
902 ggp_chat_cleanup(gc);
1018 903
1019 if (info->inpa > 0) 904 if (info->inpa > 0)
1020 purple_input_remove(info->inpa); 905 purple_input_remove(info->inpa);
1021 906
1022 purple_connection_set_protocol_data(gc, NULL); 907 purple_connection_set_protocol_data(gc, NULL);
1196 1081
1197 gg_remove_notify(info->session, ggp_str_to_uin(purple_buddy_get_name(buddy))); 1082 gg_remove_notify(info->session, ggp_str_to_uin(purple_buddy_get_name(buddy)));
1198 ggp_roster_remove_buddy(gc, buddy, group); 1083 ggp_roster_remove_buddy(gc, buddy, group);
1199 } 1084 }
1200 1085
1201 static void ggp_join_chat(PurpleConnection *gc, GHashTable *data)
1202 {
1203 GGPInfo *info = purple_connection_get_protocol_data(gc);
1204 GGPChat *chat;
1205 char *chat_name;
1206 GList *l;
1207 PurpleConversation *conv;
1208 PurpleAccount *account = purple_connection_get_account(gc);
1209
1210 chat_name = g_hash_table_lookup(data, "name");
1211
1212 if (chat_name == NULL)
1213 return;
1214
1215 purple_debug_info("gg", "joined %s chat\n", chat_name);
1216
1217 for (l = info->chats; l != NULL; l = l->next) {
1218 chat = l->data;
1219
1220 if (chat != NULL && g_utf8_collate(chat->name, chat_name) == 0) {
1221 purple_notify_error(gc, _("Chat error"),
1222 _("This chat name is already in use"), NULL);
1223 return;
1224 }
1225 }
1226
1227 ggp_confer_add_new(gc, chat_name);
1228 conv = serv_got_joined_chat(gc, info->chats_count, chat_name);
1229 purple_conv_chat_add_user(PURPLE_CONV_CHAT(conv),
1230 purple_account_get_username(account), NULL,
1231 PURPLE_CBFLAGS_NONE, TRUE);
1232 }
1233
1234 static char *ggp_get_chat_name(GHashTable *data) {
1235 return g_strdup(g_hash_table_lookup(data, "name"));
1236 }
1237
1238 static int ggp_chat_send(PurpleConnection *gc, int id, const char *message, PurpleMessageFlags flags)
1239 {
1240 PurpleConversation *conv;
1241 GGPInfo *info = purple_connection_get_protocol_data(gc);
1242 GGPChat *chat = NULL;
1243 GList *l;
1244 /* char *msg, *plain; */
1245 gchar *msg;
1246 uin_t *uins;
1247 int count = 0;
1248
1249 if ((conv = purple_find_chat(gc, id)) == NULL)
1250 return -EINVAL;
1251
1252 for (l = info->chats; l != NULL; l = l->next) {
1253 chat = l->data;
1254
1255 if (g_utf8_collate(chat->name, purple_conversation_get_name(conv)) == 0) {
1256 break;
1257 }
1258
1259 chat = NULL;
1260 }
1261
1262 if (chat == NULL) {
1263 purple_debug_error("gg",
1264 "ggp_chat_send: Hm... that's strange. No such chat?\n");
1265 return -EINVAL;
1266 }
1267
1268 uins = g_new0(uin_t, g_list_length(chat->participants));
1269
1270 for (l = chat->participants; l != NULL; l = l->next) {
1271 uin_t uin = GPOINTER_TO_INT(l->data);
1272
1273 uins[count++] = uin;
1274 }
1275
1276 msg = purple_unescape_html(message);
1277 gg_send_message_confer(info->session, GG_CLASS_CHAT, count, uins,
1278 (unsigned char *)msg);
1279 g_free(msg);
1280 g_free(uins);
1281
1282 serv_got_chat_in(gc, id,
1283 purple_account_get_username(purple_connection_get_account(gc)),
1284 flags, message, time(NULL));
1285
1286 return 0;
1287 }
1288
1289 static void ggp_keepalive(PurpleConnection *gc) 1086 static void ggp_keepalive(PurpleConnection *gc)
1290 { 1087 {
1291 GGPInfo *info = purple_connection_get_protocol_data(gc); 1088 GGPInfo *info = purple_connection_get_protocol_data(gc);
1292 1089
1293 /* purple_debug_info("gg", "Keeping connection alive....\n"); */ 1090 /* purple_debug_info("gg", "Keeping connection alive....\n"); */
1390 ggp_list_icon, /* list_icon */ 1187 ggp_list_icon, /* list_icon */
1391 ggp_list_emblem, /* list_emblem */ 1188 ggp_list_emblem, /* list_emblem */
1392 ggp_status_buddy_text, /* status_text */ 1189 ggp_status_buddy_text, /* status_text */
1393 ggp_tooltip_text, /* tooltip_text */ 1190 ggp_tooltip_text, /* tooltip_text */
1394 ggp_status_types, /* status_types */ 1191 ggp_status_types, /* status_types */
1395 ggp_blist_node_menu, /* blist_node_menu */ 1192 NULL, /* blist_node_menu */
1396 ggp_chat_info, /* chat_info */ 1193 ggp_chat_info, /* chat_info */
1397 NULL, /* chat_info_defaults */ 1194 NULL, /* chat_info_defaults */
1398 ggp_login, /* login */ 1195 ggp_login, /* login */
1399 ggp_close, /* close */ 1196 ggp_close, /* close */
1400 ggp_send_im, /* send_im */ 1197 ggp_send_im, /* send_im */
1411 NULL, /* add_permit */ 1208 NULL, /* add_permit */
1412 ggp_add_deny, /* add_deny */ 1209 ggp_add_deny, /* add_deny */
1413 NULL, /* rem_permit */ 1210 NULL, /* rem_permit */
1414 ggp_rem_deny, /* rem_deny */ 1211 ggp_rem_deny, /* rem_deny */
1415 NULL, /* set_permit_deny */ 1212 NULL, /* set_permit_deny */
1416 ggp_join_chat, /* join_chat */ 1213 ggp_chat_join, /* join_chat */
1417 NULL, /* reject_chat */ 1214 NULL, /* reject_chat */
1418 ggp_get_chat_name, /* get_chat_name */ 1215 ggp_chat_get_name, /* get_chat_name */
1419 NULL, /* chat_invite */ 1216 ggp_chat_invite, /* chat_invite */
1420 NULL, /* chat_leave */ 1217 ggp_chat_leave, /* chat_leave */
1421 NULL, /* chat_whisper */ 1218 NULL, /* chat_whisper */
1422 ggp_chat_send, /* chat_send */ 1219 ggp_chat_send, /* chat_send */
1423 ggp_keepalive, /* keepalive */ 1220 ggp_keepalive, /* keepalive */
1424 ggp_account_register, /* register_user */ 1221 ggp_account_register, /* register_user */
1425 NULL, /* get_cb_info */ 1222 NULL, /* get_cb_info */

mercurial