comparison libpurple/protocols/yahoo/yahoochat.c @ 19554:c07a9c6f0263

Fix yahoo chats again for their new super-duper-ultra-mega secure captcha stuff. "/join chat" still doesn't work, you need to use the roomlist because they now require the chat id to be set (the native client also has this problem). Fixes #2860.
author Daniel Atallah <daniel.atallah@gmail.com>
date Thu, 30 Aug 2007 18:38:15 +0000
parents 7e326d88bb42
children 44b4e8bd759b
comparison
equal deleted inserted replaced
19553:f36d0d2bf6f2 19554:c07a9c6f0263
53 /* special function to log us on to the yahoo chat service */ 53 /* special function to log us on to the yahoo chat service */
54 static void yahoo_chat_online(PurpleConnection *gc) 54 static void yahoo_chat_online(PurpleConnection *gc)
55 { 55 {
56 struct yahoo_data *yd = gc->proto_data; 56 struct yahoo_data *yd = gc->proto_data;
57 struct yahoo_packet *pkt; 57 struct yahoo_packet *pkt;
58 const char *rll;
58 59
59 if (yd->wm) { 60 if (yd->wm) {
60 ycht_connection_open(gc); 61 ycht_connection_open(gc);
61 return; 62 return;
62 } 63 }
63 64
65 rll = purple_account_get_string(purple_connection_get_account(gc),
66 "room_list_locale", YAHOO_ROOMLIST_LOCALE);
67
64 pkt = yahoo_packet_new(YAHOO_SERVICE_CHATONLINE, YAHOO_STATUS_AVAILABLE,0); 68 pkt = yahoo_packet_new(YAHOO_SERVICE_CHATONLINE, YAHOO_STATUS_AVAILABLE,0);
65 yahoo_packet_hash(pkt, "ssss", 1, purple_connection_get_display_name(gc), 69 yahoo_packet_hash(pkt, "sssss",
66 109, purple_connection_get_display_name(gc), 6, "abcde", 70 109, purple_connection_get_display_name(gc),
67 135, "ym8.1.0.415"); 71 1, purple_connection_get_display_name(gc),
72 6, "abcde",
73 /* I'm not sure this is the correct way to set this. */
74 98, rll,
75 135, "ym8.1.0.415");
68 yahoo_packet_send_and_free(pkt, yd); 76 yahoo_packet_send_and_free(pkt, yd);
69 } 77 }
70 78
71 /* this is slow, and different from the purple_* version in that it (hopefully) won't add a user twice */ 79 /* this is slow, and different from the purple_* version in that it (hopefully) won't add a user twice */
72 void yahoo_chat_add_users(PurpleConvChat *chat, GList *newusers) 80 void yahoo_chat_add_users(PurpleConvChat *chat, GList *newusers)
123 131
124 switch (pair->key) { 132 switch (pair->key) {
125 case 1: /* us, but we already know who we are */ 133 case 1: /* us, but we already know who we are */
126 break; 134 break;
127 case 57: 135 case 57:
136 g_free(room);
128 room = yahoo_string_decode(gc, pair->value, FALSE); 137 room = yahoo_string_decode(gc, pair->value, FALSE);
129 break; 138 break;
130 case 50: /* inviter */ 139 case 50: /* inviter */
131 who = pair->value; 140 who = pair->value;
132 g_string_append_printf(members, "%s\n", who); 141 g_string_append_printf(members, "%s\n", who);
134 case 52: /* invitee (me) */ 143 case 52: /* invitee (me) */
135 case 53: /* members */ 144 case 53: /* members */
136 g_string_append_printf(members, "%s\n", pair->value); 145 g_string_append_printf(members, "%s\n", pair->value);
137 break; 146 break;
138 case 58: 147 case 58:
148 g_free(msg);
139 msg = yahoo_string_decode(gc, pair->value, FALSE); 149 msg = yahoo_string_decode(gc, pair->value, FALSE);
140 break; 150 break;
141 case 13: /* ? */ 151 case 13: /* ? */
142 break; 152 break;
143 } 153 }
144 } 154 }
145 155
146 if (!room) { 156 if (!room) {
157 g_string_free(members, TRUE);
158 g_free(msg);
159 return;
160 }
161
162 if (!yahoo_privacy_check(gc, who) ||
163 (purple_account_get_bool(purple_connection_get_account(gc), "ignore_invites", FALSE))) {
164 purple_debug_info("yahoo",
165 "Invite to conference %s from %s has been dropped.\n", room, who);
166 g_free(room);
167 g_free(msg);
147 g_string_free(members, TRUE); 168 g_string_free(members, TRUE);
148 return; 169 return;
149 } 170 }
150 171
151 components = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free); 172 components = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free);
152 g_hash_table_replace(components, g_strdup("room"), room); 173 g_hash_table_replace(components, g_strdup("room"), room);
153 if (msg) 174 if (msg)
154 g_hash_table_replace(components, g_strdup("topic"), msg); 175 g_hash_table_replace(components, g_strdup("topic"), msg);
155 g_hash_table_replace(components, g_strdup("type"), g_strdup("Conference")); 176 g_hash_table_replace(components, g_strdup("type"), g_strdup("Conference"));
156 if (members) { 177 g_hash_table_replace(components, g_strdup("members"), g_string_free(members, FALSE));
157 g_hash_table_replace(components, g_strdup("members"), g_strdup(members->str));
158 }
159 if (!yahoo_privacy_check(gc, who) ||
160 (purple_account_get_bool(purple_connection_get_account(gc), "ignore_invites", FALSE))) {
161 purple_debug_info("yahoo",
162 "Invite to conference %s from %s has been dropped.\n", room, who);
163 g_string_free(members, TRUE);
164 return;
165 }
166 serv_got_chat_invite(gc, room, who, msg, components); 178 serv_got_chat_invite(gc, room, who, msg, components);
167 179
168 g_string_free(members, TRUE);
169 } 180 }
170 181
171 void yahoo_process_conference_decline(PurpleConnection *gc, struct yahoo_packet *pkt) 182 void yahoo_process_conference_decline(PurpleConnection *gc, struct yahoo_packet *pkt)
172 { 183 {
173 GSList *l; 184 GSList *l;
178 for (l = pkt->hash; l; l = l->next) { 189 for (l = pkt->hash; l; l = l->next) {
179 struct yahoo_pair *pair = l->data; 190 struct yahoo_pair *pair = l->data;
180 191
181 switch (pair->key) { 192 switch (pair->key) {
182 case 57: 193 case 57:
194 g_free(room);
183 room = yahoo_string_decode(gc, pair->value, FALSE); 195 room = yahoo_string_decode(gc, pair->value, FALSE);
184 break; 196 break;
185 case 54: 197 case 54:
186 who = pair->value; 198 who = pair->value;
187 break; 199 break;
188 case 14: 200 case 14:
201 g_free(msg);
189 msg = yahoo_string_decode(gc, pair->value, FALSE); 202 msg = yahoo_string_decode(gc, pair->value, FALSE);
190 break; 203 break;
191 } 204 }
192 } 205 }
193 if (!yahoo_privacy_check(gc, who)) { 206 if (!yahoo_privacy_check(gc, who)) {
194 g_free(room); 207 g_free(room);
195 if (msg != NULL) 208 g_free(msg);
196 g_free(msg);
197 return; 209 return;
198 } 210 }
199 211
200 if (who && room) { 212 if (who && room) {
201 /* make sure we're in the room before we process a decline message for it */ 213 /* make sure we're in the room before we process a decline message for it */
207 purple_notify_info(gc, NULL, _("Invitation Rejected"), tmp); 219 purple_notify_info(gc, NULL, _("Invitation Rejected"), tmp);
208 g_free(tmp); 220 g_free(tmp);
209 } 221 }
210 222
211 g_free(room); 223 g_free(room);
212 if (msg) 224 g_free(msg);
213 g_free(msg);
214 } 225 }
215 } 226 }
216 227
217 void yahoo_process_conference_logon(PurpleConnection *gc, struct yahoo_packet *pkt) 228 void yahoo_process_conference_logon(PurpleConnection *gc, struct yahoo_packet *pkt)
218 { 229 {
224 for (l = pkt->hash; l; l = l->next) { 235 for (l = pkt->hash; l; l = l->next) {
225 struct yahoo_pair *pair = l->data; 236 struct yahoo_pair *pair = l->data;
226 237
227 switch (pair->key) { 238 switch (pair->key) {
228 case 57: 239 case 57:
240 g_free(room);
229 room = yahoo_string_decode(gc, pair->value, FALSE); 241 room = yahoo_string_decode(gc, pair->value, FALSE);
230 break; 242 break;
231 case 53: 243 case 53:
232 who = pair->value; 244 who = pair->value;
233 break; 245 break;
252 for (l = pkt->hash; l; l = l->next) { 264 for (l = pkt->hash; l; l = l->next) {
253 struct yahoo_pair *pair = l->data; 265 struct yahoo_pair *pair = l->data;
254 266
255 switch (pair->key) { 267 switch (pair->key) {
256 case 57: 268 case 57:
269 g_free(room);
257 room = yahoo_string_decode(gc, pair->value, FALSE); 270 room = yahoo_string_decode(gc, pair->value, FALSE);
258 break; 271 break;
259 case 56: 272 case 56:
260 who = pair->value; 273 who = pair->value;
261 break; 274 break;
274 { 287 {
275 GSList *l; 288 GSList *l;
276 char *room = NULL; 289 char *room = NULL;
277 char *who = NULL; 290 char *who = NULL;
278 char *msg = NULL; 291 char *msg = NULL;
279 char *msg2;
280 int utf8 = 0; 292 int utf8 = 0;
281 PurpleConversation *c; 293 PurpleConversation *c;
282 294
283 for (l = pkt->hash; l; l = l->next) { 295 for (l = pkt->hash; l; l = l->next) {
284 struct yahoo_pair *pair = l->data; 296 struct yahoo_pair *pair = l->data;
285 297
286 switch (pair->key) { 298 switch (pair->key) {
287 case 57: 299 case 57:
300 g_free(room);
288 room = yahoo_string_decode(gc, pair->value, FALSE); 301 room = yahoo_string_decode(gc, pair->value, FALSE);
289 break; 302 break;
290 case 3: 303 case 3:
291 who = pair->value; 304 who = pair->value;
292 break; 305 break;
297 utf8 = strtol(pair->value, NULL, 10); 310 utf8 = strtol(pair->value, NULL, 10);
298 break; 311 break;
299 } 312 }
300 } 313 }
301 314
302 if (room && who && msg) { 315 if (room && who && msg) {
303 msg2 = yahoo_string_decode(gc, msg, utf8); 316 char *msg2;
304 c = yahoo_find_conference(gc, room); 317
305 if (!c) 318 c = yahoo_find_conference(gc, room);
306 return; 319 if (!c) {
307 msg = yahoo_codes_to_html(msg2);
308 serv_got_chat_in(gc, purple_conv_chat_get_id(PURPLE_CONV_CHAT(c)), who, 0, msg, time(NULL));
309 g_free(msg);
310 g_free(msg2);
311 }
312 if (room)
313 g_free(room); 320 g_free(room);
314 } 321 return;
315 322 }
323
324 msg2 = yahoo_string_decode(gc, msg, utf8);
325 msg = yahoo_codes_to_html(msg2);
326 serv_got_chat_in(gc, purple_conv_chat_get_id(PURPLE_CONV_CHAT(c)), who, 0, msg, time(NULL));
327 g_free(msg);
328 g_free(msg2);
329 }
330
331 g_free(room);
332 }
333
334 static void yahoo_chat_join(PurpleConnection *gc, const char *dn, const char *room, const char *topic, const char *id)
335 {
336 struct yahoo_data *yd = gc->proto_data;
337 struct yahoo_packet *pkt;
338 char *room2;
339 gboolean utf8 = TRUE;
340
341 if (yd->wm) {
342 g_return_if_fail(yd->ycht != NULL);
343 ycht_chat_join(yd->ycht, room);
344 return;
345 }
346
347 /* apparently room names are always utf8, or else always not utf8,
348 * so we don't have to actually pass the flag in the packet. Or something. */
349 room2 = yahoo_string_encode(gc, room, &utf8);
350
351 pkt = yahoo_packet_new(YAHOO_SERVICE_CHATJOIN, YAHOO_STATUS_AVAILABLE, 0);
352 yahoo_packet_hash(pkt, "ssss",
353 1, purple_connection_get_display_name(gc),
354 104, room2,
355 62, "2",
356 129, id ? id : "0");
357 yahoo_packet_send_and_free(pkt, yd);
358 g_free(room2);
359 }
316 360
317 /* this is a confirmation of yahoo_chat_online(); */ 361 /* this is a confirmation of yahoo_chat_online(); */
318 void yahoo_process_chat_online(PurpleConnection *gc, struct yahoo_packet *pkt) 362 void yahoo_process_chat_online(PurpleConnection *gc, struct yahoo_packet *pkt)
319 { 363 {
320 struct yahoo_data *yd = (struct yahoo_data *) gc->proto_data; 364 struct yahoo_data *yd = (struct yahoo_data *) gc->proto_data;
321 365
322 if (pkt->status == 1) 366 if (pkt->status == 1) {
323 yd->chat_online = 1; 367 yd->chat_online = 1;
368
369 /* We need to goto a user in chat */
370 if (yd->pending_chat_goto) {
371 struct yahoo_packet *pkt = yahoo_packet_new(YAHOO_SERVICE_CHATGOTO, YAHOO_STATUS_AVAILABLE, 0);
372 yahoo_packet_hash(pkt, "sss",
373 109, yd->pending_chat_goto,
374 1, purple_connection_get_display_name(gc),
375 62, "2");
376 yahoo_packet_send_and_free(pkt, yd);
377 } else if (yd->pending_chat_room) {
378 yahoo_chat_join(gc, purple_connection_get_display_name(gc), yd->pending_chat_room,
379 yd->pending_chat_topic, yd->pending_chat_id);
380 }
381
382 g_free(yd->pending_chat_room);
383 yd->pending_chat_room = NULL;
384 g_free(yd->pending_chat_id);
385 yd->pending_chat_id = NULL;
386 g_free(yd->pending_chat_topic);
387 yd->pending_chat_topic = NULL;
388 g_free(yd->pending_chat_goto);
389 yd->pending_chat_goto = NULL;
390 }
324 } 391 }
325 392
326 /* this is basicly the opposite of chat_online */ 393 /* this is basicly the opposite of chat_online */
327 void yahoo_process_chat_logout(PurpleConnection *gc, struct yahoo_packet *pkt) 394 void yahoo_process_chat_logout(PurpleConnection *gc, struct yahoo_packet *pkt)
328 { 395 {
338 return; 405 return;
339 } 406 }
340 407
341 if (pkt->status == 1) { 408 if (pkt->status == 1) {
342 yd->chat_online = 0; 409 yd->chat_online = 0;
410 g_free(yd->pending_chat_room);
411 yd->pending_chat_room = NULL;
412 g_free(yd->pending_chat_id);
413 yd->pending_chat_id = NULL;
414 g_free(yd->pending_chat_topic);
415 yd->pending_chat_topic = NULL;
416 g_free(yd->pending_chat_goto);
417 yd->pending_chat_goto = NULL;
343 if (yd->in_chat) 418 if (yd->in_chat)
344 yahoo_c_leave(gc, YAHOO_CHAT_ID); 419 yahoo_c_leave(gc, YAHOO_CHAT_ID);
345 } 420 }
346 } 421 }
347 422
382 struct yahoo_pair *pair = l->data; 457 struct yahoo_pair *pair = l->data;
383 458
384 switch (pair->key) { 459 switch (pair->key) {
385 460
386 case 104: 461 case 104:
462 g_free(room);
387 room = yahoo_string_decode(gc, pair->value, TRUE); 463 room = yahoo_string_decode(gc, pair->value, TRUE);
388 break; 464 break;
389 case 105: 465 case 105:
466 g_free(topic);
390 topic = yahoo_string_decode(gc, pair->value, TRUE); 467 topic = yahoo_string_decode(gc, pair->value, TRUE);
391 break; 468 break;
392 case 128: 469 case 128:
393 someid = pair->value; 470 someid = pair->value;
394 break; 471 break;
443 char *tmpmsg; 520 char *tmpmsg;
444 521
445 purple_conversation_set_name(c, room); 522 purple_conversation_set_name(c, room);
446 523
447 c = serv_got_joined_chat(gc, YAHOO_CHAT_ID, room); 524 c = serv_got_joined_chat(gc, YAHOO_CHAT_ID, room);
448 if (topic) 525 if (topic) {
449 purple_conv_chat_set_topic(PURPLE_CONV_CHAT(c), NULL, topic); 526 purple_conv_chat_set_topic(PURPLE_CONV_CHAT(c), NULL, topic);
527 /* Also print the topic to the backlog so that the captcha link is clickable */
528 purple_conv_chat_write(PURPLE_CONV_CHAT(c), "", topic, PURPLE_MESSAGE_SYSTEM, time(NULL));
529 }
450 yd->in_chat = 1; 530 yd->in_chat = 1;
451 yd->chat_name = g_strdup(room); 531 yd->chat_name = g_strdup(room);
452 purple_conv_chat_add_users(PURPLE_CONV_CHAT(c), members, NULL, flags, FALSE); 532 purple_conv_chat_add_users(PURPLE_CONV_CHAT(c), members, NULL, flags, FALSE);
453 533
454 tmpmsg = g_strdup_printf(_("You are now chatting in %s."), room); 534 tmpmsg = g_strdup_printf(_("You are now chatting in %s."), room);
455 purple_conv_chat_write(PURPLE_CONV_CHAT(c), "", tmpmsg, PURPLE_MESSAGE_SYSTEM, time(NULL)); 535 purple_conv_chat_write(PURPLE_CONV_CHAT(c), "", tmpmsg, PURPLE_MESSAGE_SYSTEM, time(NULL));
456 g_free(tmpmsg); 536 g_free(tmpmsg);
457 } else { 537 } else {
458 c = serv_got_joined_chat(gc, YAHOO_CHAT_ID, room); 538 c = serv_got_joined_chat(gc, YAHOO_CHAT_ID, room);
459 if (topic) 539 if (topic) {
460 purple_conv_chat_set_topic(PURPLE_CONV_CHAT(c), NULL, topic); 540 purple_conv_chat_set_topic(PURPLE_CONV_CHAT(c), NULL, topic);
541 /* Also print the topic to the backlog so that the captcha link is clickable */
542 purple_conv_chat_write(PURPLE_CONV_CHAT(c), "", topic, PURPLE_MESSAGE_SYSTEM, time(NULL));
543 }
461 yd->in_chat = 1; 544 yd->in_chat = 1;
462 yd->chat_name = g_strdup(room); 545 yd->chat_name = g_strdup(room);
463 purple_conv_chat_add_users(PURPLE_CONV_CHAT(c), members, NULL, flags, FALSE); 546 purple_conv_chat_add_users(PURPLE_CONV_CHAT(c), members, NULL, flags, FALSE);
464 } 547 }
465 g_list_free(flags); 548 g_list_free(flags);
466 } else if (c) { 549 } else if (c) {
550 if (topic) {
551 const char *cur_topic = purple_conv_chat_get_topic(PURPLE_CONV_CHAT(c));
552 if (cur_topic == NULL || strcmp(cur_topic, topic) != 0)
553 purple_conv_chat_set_topic(PURPLE_CONV_CHAT(c), NULL, topic);
554 }
467 yahoo_chat_add_users(PURPLE_CONV_CHAT(c), members); 555 yahoo_chat_add_users(PURPLE_CONV_CHAT(c), members);
468 } 556 }
469 557
470 if (account->deny && c) { 558 if (account->deny && c) {
471 PurpleConversationUiOps *ops = purple_conversation_get_ui_ops(c); 559 PurpleConversationUiOps *ops = purple_conversation_get_ui_ops(c);
495 yd = gc->proto_data; 583 yd = gc->proto_data;
496 584
497 for (l = pkt->hash; l; l = l->next) { 585 for (l = pkt->hash; l; l = l->next) {
498 struct yahoo_pair *pair = l->data; 586 struct yahoo_pair *pair = l->data;
499 587
500 if (pair->key == 104) 588 if (pair->key == 104) {
589 g_free(room);
501 room = yahoo_string_decode(gc, pair->value, TRUE); 590 room = yahoo_string_decode(gc, pair->value, TRUE);
591 }
502 if (pair->key == 109) 592 if (pair->key == 109)
503 who = pair->value; 593 who = pair->value;
504 } 594 }
505 595
506 if (who && room) { 596 if (who && room) {
527 617
528 case 97: 618 case 97:
529 utf8 = strtol(pair->value, NULL, 10); 619 utf8 = strtol(pair->value, NULL, 10);
530 break; 620 break;
531 case 104: 621 case 104:
622 g_free(room);
532 room = yahoo_string_decode(gc, pair->value, TRUE); 623 room = yahoo_string_decode(gc, pair->value, TRUE);
533 break; 624 break;
534 case 109: 625 case 109:
535 who = pair->value; 626 who = pair->value;
536 break; 627 break;
581 for (l = pkt->hash; l; l = l->next) { 672 for (l = pkt->hash; l; l = l->next) {
582 struct yahoo_pair *pair = l->data; 673 struct yahoo_pair *pair = l->data;
583 674
584 switch (pair->key) { 675 switch (pair->key) {
585 case 104: 676 case 104:
677 g_free(room);
586 room = yahoo_string_decode(gc, pair->value, TRUE); 678 room = yahoo_string_decode(gc, pair->value, TRUE);
587 break; 679 break;
588 case 129: /* room id? */ 680 case 129: /* room id? */
589 break; 681 break;
590 case 126: /* ??? */ 682 case 126: /* ??? */
591 break; 683 break;
592 case 117: 684 case 117:
685 g_free(msg);
593 msg = yahoo_string_decode(gc, pair->value, FALSE); 686 msg = yahoo_string_decode(gc, pair->value, FALSE);
594 break; 687 break;
595 case 119: 688 case 119:
596 who = pair->value; 689 who = pair->value;
597 break; 690 break;
601 } 694 }
602 695
603 if (room && who) { 696 if (room && who) {
604 GHashTable *components; 697 GHashTable *components;
605 698
699 if (!yahoo_privacy_check(gc, who) ||
700 (purple_account_get_bool(purple_connection_get_account(gc), "ignore_invites", FALSE))) {
701 purple_debug_info("yahoo", "Invite to room %s from %s has been dropped.\n", room, who);
702 g_free(room);
703 g_free(msg);
704 return;
705 }
706
606 components = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free); 707 components = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free);
607 g_hash_table_replace(components, g_strdup("room"), g_strdup(room)); 708 g_hash_table_replace(components, g_strdup("room"), g_strdup(room));
608 if (!yahoo_privacy_check(gc, who) ||
609 (purple_account_get_bool(purple_connection_get_account(gc), "ignore_invites", FALSE))) {
610 purple_debug_info("yahoo",
611 "Invite to room %s from %s has been dropped.\n", room, who);
612 if (room != NULL)
613 g_free(room);
614 if (msg != NULL)
615 g_free(msg);
616 return;
617 }
618 serv_got_chat_invite(gc, room, who, msg, components); 709 serv_got_chat_invite(gc, room, who, msg, components);
619 } 710 }
620 if (room) 711
621 g_free(room); 712 g_free(room);
622 if (msg) 713 g_free(msg);
623 g_free(msg);
624 } 714 }
625 715
626 void yahoo_process_chat_goto(PurpleConnection *gc, struct yahoo_packet *pkt) 716 void yahoo_process_chat_goto(PurpleConnection *gc, struct yahoo_packet *pkt)
627 { 717 {
628 if (pkt->status == -1) 718 if (pkt->status == -1)
781 YAHOO_STATUS_AVAILABLE, 0); 871 YAHOO_STATUS_AVAILABLE, 0);
782 yahoo_packet_hash_str(pkt, 1, dn); 872 yahoo_packet_hash_str(pkt, 1, dn);
783 yahoo_packet_send_and_free(pkt, yd); 873 yahoo_packet_send_and_free(pkt, yd);
784 874
785 yd->chat_online = 0; 875 yd->chat_online = 0;
876 g_free(yd->pending_chat_room);
877 yd->pending_chat_room = NULL;
878 g_free(yd->pending_chat_id);
879 yd->pending_chat_id = NULL;
880 g_free(yd->pending_chat_topic);
881 yd->pending_chat_topic = NULL;
882 g_free(yd->pending_chat_goto);
883 yd->pending_chat_goto = NULL;
786 g_free(eroom); 884 g_free(eroom);
787 } 885 }
788 886
789 static int yahoo_chat_send(PurpleConnection *gc, const char *dn, const char *room, const char *what, PurpleMessageFlags flags) 887 static int yahoo_chat_send(PurpleConnection *gc, const char *dn, const char *room, const char *what, PurpleMessageFlags flags)
790 { 888 {
827 g_free(room2); 925 g_free(room2);
828 926
829 return 0; 927 return 0;
830 } 928 }
831 929
832 static void yahoo_chat_join(PurpleConnection *gc, const char *dn, const char *room, const char *topic)
833 {
834 struct yahoo_data *yd = gc->proto_data;
835 struct yahoo_packet *pkt;
836 char *room2;
837 gboolean utf8 = TRUE;
838
839 if (yd->wm) {
840 g_return_if_fail(yd->ycht != NULL);
841 ycht_chat_join(yd->ycht, room);
842 return;
843 }
844
845 /* apparently room names are always utf8, or else always not utf8,
846 * so we don't have to actually pass the flag in the packet. Or something. */
847 room2 = yahoo_string_encode(gc, room, &utf8);
848
849 pkt = yahoo_packet_new(YAHOO_SERVICE_CHATJOIN, YAHOO_STATUS_AVAILABLE, 0);
850 yahoo_packet_hash(pkt, "ssss", 1, purple_connection_get_display_name(gc),
851 62, "2", 104, room2, 129, "0");
852 yahoo_packet_send_and_free(pkt, yd);
853 g_free(room2);
854 }
855 930
856 static void yahoo_chat_invite(PurpleConnection *gc, const char *dn, const char *buddy, 931 static void yahoo_chat_invite(PurpleConnection *gc, const char *dn, const char *buddy,
857 const char *room, const char *msg) 932 const char *room, const char *msg)
858 { 933 {
859 struct yahoo_data *yd = gc->proto_data; 934 struct yahoo_data *yd = gc->proto_data;
890 g_return_if_fail(yd->ycht != NULL); 965 g_return_if_fail(yd->ycht != NULL);
891 ycht_chat_goto_user(yd->ycht, name); 966 ycht_chat_goto_user(yd->ycht, name);
892 return; 967 return;
893 } 968 }
894 969
895 if (!yd->chat_online) 970 if (!yd->chat_online) {
896 yahoo_chat_online(gc); 971 yahoo_chat_online(gc);
972 g_free(yd->pending_chat_room);
973 yd->pending_chat_room = NULL;
974 g_free(yd->pending_chat_id);
975 yd->pending_chat_id = NULL;
976 g_free(yd->pending_chat_topic);
977 yd->pending_chat_topic = NULL;
978 g_free(yd->pending_chat_goto);
979 yd->pending_chat_goto = g_strdup(name);
980 return;
981 }
897 982
898 pkt = yahoo_packet_new(YAHOO_SERVICE_CHATGOTO, YAHOO_STATUS_AVAILABLE, 0); 983 pkt = yahoo_packet_new(YAHOO_SERVICE_CHATGOTO, YAHOO_STATUS_AVAILABLE, 0);
899 yahoo_packet_hash(pkt, "sss", 109, name, 1, purple_connection_get_display_name(gc), 62, "2"); 984 yahoo_packet_hash(pkt, "sss", 109, name, 1, purple_connection_get_display_name(gc), 62, "2");
900 yahoo_packet_send_and_free(pkt, yd); 985 yahoo_packet_send_and_free(pkt, yd);
901 } 986 }
986 } 1071 }
987 1072
988 void yahoo_c_join(PurpleConnection *gc, GHashTable *data) 1073 void yahoo_c_join(PurpleConnection *gc, GHashTable *data)
989 { 1074 {
990 struct yahoo_data *yd; 1075 struct yahoo_data *yd;
991 char *room, *topic, *members, *type; 1076 char *room, *topic, *type;
992 int id;
993 PurpleConversation *c; 1077 PurpleConversation *c;
994 1078
995 yd = (struct yahoo_data *) gc->proto_data; 1079 yd = (struct yahoo_data *) gc->proto_data;
996 if (!yd) 1080 if (!yd)
997 return; 1081 return;
1002 1086
1003 topic = g_hash_table_lookup(data, "topic"); 1087 topic = g_hash_table_lookup(data, "topic");
1004 if (!topic) 1088 if (!topic)
1005 topic = ""; 1089 topic = "";
1006 1090
1007 members = g_hash_table_lookup(data, "members");
1008
1009 if ((type = g_hash_table_lookup(data, "type")) && !strcmp(type, "Conference")) { 1091 if ((type = g_hash_table_lookup(data, "type")) && !strcmp(type, "Conference")) {
1092 int id;
1093 const char *members = g_hash_table_lookup(data, "members");
1010 id = yd->conf_id++; 1094 id = yd->conf_id++;
1011 c = serv_got_joined_chat(gc, id, room); 1095 c = serv_got_joined_chat(gc, id, room);
1012 yd->confs = g_slist_prepend(yd->confs, c); 1096 yd->confs = g_slist_prepend(yd->confs, c);
1013 purple_conv_chat_set_topic(PURPLE_CONV_CHAT(c), purple_connection_get_display_name(gc), topic); 1097 purple_conv_chat_set_topic(PURPLE_CONV_CHAT(c), purple_connection_get_display_name(gc), topic);
1014 yahoo_conf_join(yd, c, purple_connection_get_display_name(gc), room, topic, members); 1098 yahoo_conf_join(yd, c, purple_connection_get_display_name(gc), room, topic, members);
1015 return; 1099 return;
1016 } else { 1100 } else {
1017 if (yd->in_chat) 1101 const char *id;
1102 /*if (yd->in_chat)
1018 yahoo_chat_leave(gc, room, 1103 yahoo_chat_leave(gc, room,
1019 purple_connection_get_display_name(gc), 1104 purple_connection_get_display_name(gc),
1020 FALSE); 1105 FALSE);*/
1021 if (!yd->chat_online) 1106
1107 id = g_hash_table_lookup(data, "id");
1108
1109 if (!yd->chat_online) {
1022 yahoo_chat_online(gc); 1110 yahoo_chat_online(gc);
1023 yahoo_chat_join(gc, purple_connection_get_display_name(gc), room, topic); 1111 g_free(yd->pending_chat_room);
1112 yd->pending_chat_room = g_strdup(room);
1113 g_free(yd->pending_chat_id);
1114 yd->pending_chat_id = g_strdup(id);
1115 g_free(yd->pending_chat_topic);
1116 yd->pending_chat_topic = g_strdup(topic);
1117 g_free(yd->pending_chat_goto);
1118 yd->pending_chat_goto = NULL;
1119 } else {
1120 yahoo_chat_join(gc, purple_connection_get_display_name(gc), room, topic, id);
1121 }
1024 return; 1122 return;
1025 } 1123 }
1026 } 1124 }
1027 1125
1028 void yahoo_c_invite(PurpleConnection *gc, int id, const char *msg, const char *name) 1126 void yahoo_c_invite(PurpleConnection *gc, int id, const char *msg, const char *name)
1146 } else if (!strcmp(ename, "room")) { 1244 } else if (!strcmp(ename, "room")) {
1147 s->room.users = s->room.voices = s->room.webcams = 0; 1245 s->room.users = s->room.voices = s->room.webcams = 0;
1148 1246
1149 for (i = 0; anames[i]; i++) { 1247 for (i = 0; anames[i]; i++) {
1150 if (!strcmp(anames[i], "id")) { 1248 if (!strcmp(anames[i], "id")) {
1151 if (s->room.id) 1249 g_free(s->room.id);
1152 g_free(s->room.id);
1153 s->room.id = g_strdup(avalues[i]); 1250 s->room.id = g_strdup(avalues[i]);
1154 } else if (!strcmp(anames[i], "name")) { 1251 } else if (!strcmp(anames[i], "name")) {
1155 if (s->room.name) 1252 g_free(s->room.name);
1156 g_free(s->room.name);
1157 s->room.name = g_strdup(avalues[i]); 1253 s->room.name = g_strdup(avalues[i]);
1158 } else if (!strcmp(anames[i], "topic")) { 1254 } else if (!strcmp(anames[i], "topic")) {
1159 if (s->room.topic) 1255 g_free(s->room.topic);
1160 g_free(s->room.topic);
1161 s->room.topic = g_strdup(avalues[i]); 1256 s->room.topic = g_strdup(avalues[i]);
1162 } else if (!strcmp(anames[i], "type")) { 1257 } else if (!strcmp(anames[i], "type")) {
1163 if (!strcmp("yahoo", avalues[i])) 1258 if (!strcmp("yahoo", avalues[i]))
1164 s->room.type = yrt_yahoo; 1259 s->room.type = yrt_yahoo;
1165 else 1260 else