comparison src/protocols/yahoo/yahoochat.c @ 6729:7b878ee8f064

[gaim-migrate @ 7256] Tim Ringenbach (marv_sf) writes: " This adds Chat and Conference support to the Yahoo! prpl. I think I got all the major bugs out, and it works pretty good. You can invite others, and accept inventations for both chats and conferences, you can join a chat from the Buddies menu in the buddy list, like you would for irc, and you can initiate a conference by right clicking on a buddy, like you would for msn. You can also attempt to join user in chat, which will fail if they're not actually in a chat. (Apparently the offical version can't tell before hand either.) Oh, and you can chat." committer: Tailor Script <tailor@pidgin.im>
author Luke Schierer <lschiere@pidgin.im>
date Wed, 03 Sep 2003 12:45:17 +0000
parents
children 3ef17670e69f
comparison
equal deleted inserted replaced
6728:fa7359c3f93c 6729:7b878ee8f064
1 /*
2 * gaim
3 *
4 * Some code copyright 2003 Tim Ringenbach <omarvo@hotmail.com>
5 * (marv on irc.freenode.net)
6 * Some code borrowed from libyahoo2, copyright (C) 2002, Philip
7 * S Tellis <philip . tellis AT gmx . net>
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 *
23 */
24
25 #ifdef HAVE_CONFIG_H
26 #include "config.h"
27 #endif
28
29 #include "debug.h"
30 #include "prpl.h"
31
32 #include "conversation.h"
33 #include "notify.h"
34 #include "util.h"
35 #include "multi.h"
36 #include "internal.h"
37
38 #include "yahoo.h"
39 #include "yahoochat.h"
40
41 #define YAHOO_CHAT_ID (1)
42
43 /* special function to log us on to the yahoo chat service */
44 static void yahoo_chat_online(GaimConnection *gc)
45 {
46 struct yahoo_data *yd = gc->proto_data;
47 struct yahoo_packet *pkt;
48
49
50 pkt = yahoo_packet_new(YAHOO_SERVICE_CHATONLINE, YAHOO_STATUS_AVAILABLE,0);
51 yahoo_packet_hash(pkt, 1, gaim_connection_get_display_name(gc));
52 yahoo_packet_hash(pkt, 109, gaim_connection_get_display_name(gc));
53 yahoo_packet_hash(pkt, 6, "abcde");
54
55 yahoo_send_packet(yd, pkt);
56
57 yahoo_packet_free(pkt);
58 }
59
60 static gint _mystrcmpwrapper(gconstpointer a, gconstpointer b)
61 {
62 return strcmp(a, b);
63 }
64
65 /* this is slow, and different from the gaim_* version in that it (hopefully) won't add a user twice */
66 static void yahoo_chat_add_users(GaimChat *chat, GList *newusers)
67 {
68 GList *users, *i, *j;
69
70 users = gaim_chat_get_users(chat);
71
72 for (i = newusers; i; i = i->next) {
73 j = g_list_find_custom(users, i->data, _mystrcmpwrapper);
74 if (j)
75 continue;
76 gaim_chat_add_user(chat, i->data, NULL);
77 }
78 }
79
80 static void yahoo_chat_add_user(GaimChat *chat, const char *user, const char *reason)
81 {
82 GList *users;
83
84 users = gaim_chat_get_users(chat);
85
86 if ((g_list_find_custom(users, user, _mystrcmpwrapper)))
87 return;
88
89 gaim_chat_add_user(chat, user, reason);
90 }
91
92 static GaimConversation *yahoo_find_conference(GaimConnection *gc, const char *name)
93 {
94 struct yahoo_data *yd;
95 GSList *l;
96
97 yd = gc->proto_data;
98
99 for (l = yd->confs; l; l = l->next) {
100 GaimConversation *c = l->data;
101 if (!gaim_utf8_strcasecmp(gaim_conversation_get_name(c), name))
102 return c;
103 }
104 return NULL;
105 }
106
107
108 void yahoo_process_conference_invite(GaimConnection *gc, struct yahoo_packet *pkt)
109 {
110 GSList *l;
111 char *room = NULL;
112 char *who = NULL;
113 char *msg = NULL;
114 GString *members = NULL;
115 GHashTable *components;
116
117
118 if (pkt->status == 2)
119 return; /* XXX */
120
121 members = g_string_sized_new(512);
122
123 for (l = pkt->hash; l; l = l->next) {
124 struct yahoo_pair *pair = l->data;
125
126 switch (pair->key) {
127 case 1: /* us, but we already know who we are */
128 break;
129 case 57:
130 room = pair->value;
131 break;
132 case 50: /* inviter */
133 who = pair->value;
134 g_string_append_printf(members, "%s\n", who);
135 break;
136 case 52: /* members */
137 g_string_append_printf(members, "%s\n", pair->value);
138 break;
139 case 58:
140 msg = pair->value;
141 break;
142 case 13: /* ? */
143 break;
144 }
145 }
146
147 if (!room) {
148 g_string_free(members, TRUE);
149 return;
150 }
151
152 components = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free);
153 g_hash_table_replace(components, g_strdup("room"), g_strdup(room));
154 if (msg)
155 g_hash_table_replace(components, g_strdup("topic"), g_strdup(msg));
156 g_hash_table_replace(components, g_strdup("type"), g_strdup("Conference"));
157 if (members) {
158 g_hash_table_replace(components, g_strdup("members"), g_strdup(members->str));
159 }
160 serv_got_chat_invite(gc, room, who, msg, components);
161
162 g_string_free(members, TRUE);
163 }
164
165 void yahoo_process_conference_decline(GaimConnection *gc, struct yahoo_packet *pkt)
166 {
167 GSList *l;
168 char *room = NULL;
169 char *who = NULL;
170 char *msg = NULL;
171
172 for (l = pkt->hash; l; l = l->next) {
173 struct yahoo_pair *pair = l->data;
174
175 switch (pair->key) {
176 case 57:
177 room = pair->value;
178 break;
179 case 54:
180 who = pair->value;
181 break;
182 case 14:
183 msg = pair->value;
184 break;
185 }
186 }
187
188 if (who && room) {
189 char *tmp;
190
191 tmp = g_strdup_printf(_("%s declined your conference invitation to room \"%s\" because \"%s\"."),
192 who, room, msg?msg:"");
193 gaim_notify_info(gc, NULL, _("Invitation Rejected"), tmp);
194 g_free(tmp);
195 }
196 }
197
198 void yahoo_process_conference_logon(GaimConnection *gc, struct yahoo_packet *pkt)
199 {
200 GSList *l;
201 char *room = NULL;
202 char *who = NULL;
203 GaimConversation *c;
204
205 for (l = pkt->hash; l; l = l->next) {
206 struct yahoo_pair *pair = l->data;
207
208 switch (pair->key) {
209 case 57:
210 room = pair->value;
211 break;
212 case 53:
213 who = pair->value;
214 break;
215 }
216 }
217
218 if (who && room) {
219 c = yahoo_find_conference(gc, room);
220 if (c)
221 yahoo_chat_add_user(GAIM_CHAT(c), who, NULL);
222 }
223 }
224
225 void yahoo_process_conference_logoff(GaimConnection *gc, struct yahoo_packet *pkt)
226 {
227 GSList *l;
228 char *room = NULL;
229 char *who = NULL;
230 GaimConversation *c;
231
232 for (l = pkt->hash; l; l = l->next) {
233 struct yahoo_pair *pair = l->data;
234
235 switch (pair->key) {
236 case 57:
237 room = pair->value;
238 break;
239 case 56:
240 who = pair->value;
241 break;
242 }
243 }
244
245 if (who && room) {
246 c = yahoo_find_conference(gc, room);
247 if (c)
248 gaim_chat_remove_user(GAIM_CHAT(c), who, NULL);
249 }
250 }
251
252 void yahoo_process_conference_message(GaimConnection *gc, struct yahoo_packet *pkt)
253 {
254 GSList *l;
255 char *room = NULL;
256 char *who = NULL;
257 char *msg = NULL;
258 GaimConversation *c;
259
260 for (l = pkt->hash; l; l = l->next) {
261 struct yahoo_pair *pair = l->data;
262
263 switch (pair->key) {
264 case 57:
265 room = pair->value;
266 break;
267 case 3:
268 who = pair->value;
269 break;
270 case 14:
271 msg = pair->value;
272 break;
273 }
274 }
275
276 if (room && who && msg) {
277 c = yahoo_find_conference(gc, room);
278 if (!c)
279 return;
280 msg = yahoo_codes_to_html(msg);
281 serv_got_chat_in(gc, gaim_chat_get_id(GAIM_CHAT(c)), who, 0, msg, time(NULL));
282 g_free(msg);
283 }
284
285 }
286
287
288 /* this is a comfirmation of yahoo_chat_online(); */
289 void yahoo_process_chat_online(GaimConnection *gc, struct yahoo_packet *pkt)
290 {
291 struct yahoo_data *yd = (struct yahoo_data *) gc->proto_data;
292
293 if (pkt->status == 1)
294 yd->chat_online = 1;
295 }
296
297 /* this is basicly the opposite of chat_online */
298 void yahoo_process_chat_logout(GaimConnection *gc, struct yahoo_packet *pkt)
299 {
300 struct yahoo_data *yd = (struct yahoo_data *) gc->proto_data;
301
302 if (pkt->status == 1)
303 yd->chat_online = 0;
304 }
305
306 void yahoo_process_chat_join(GaimConnection *gc, struct yahoo_packet *pkt)
307 {
308 struct yahoo_data *yd = (struct yahoo_data *) gc->proto_data;
309 GaimConversation *c = NULL;
310 GSList *l;
311 GList *members = NULL;
312 char *room = NULL;
313 char *topic = NULL;
314 char *someid, *someotherid, *somebase64orhashosomething, *somenegativenumber;
315
316 if (pkt->status == -1) {
317 gaim_notify_error(gc, NULL, _("Failed to join chat"), _("Maybe the room is full?"));
318 return;
319 }
320
321 for (l = pkt->hash; l; l = l->next) {
322 struct yahoo_pair *pair = l->data;
323
324 switch (pair->key) {
325
326 case 104:
327 room = pair->value;
328 break;
329 case 105:
330 topic = pair->value;
331 break;
332 case 128:
333 someid = pair->value;
334 break;
335 case 108: /* number of joiners */
336 break;
337 case 129:
338 someotherid = pair->value;
339 break;
340 case 130:
341 somebase64orhashosomething = pair->value;
342 break;
343 case 126:
344 somenegativenumber = pair->value;
345 break;
346 case 13: /* this is 1. maybe its the type of room? (normal, user created, private, etc?) */
347 break;
348 case 61: /*this looks similiar to 130 */
349 break;
350
351 /* the previous section was just room info. this next section is
352 info about individual room members, (including us) */
353
354 case 109: /* the yahoo id */
355 members = g_list_append(members, pair->value);
356 break;
357 case 110: /* age */
358 break;
359 case 141: /* nickname */
360 break;
361 case 142: /* location */
362 break;
363 case 113: /* bitmask */
364 break;
365 }
366 }
367
368 if (!room)
369 return;
370
371 if (yd->chat_name && gaim_utf8_strcasecmp(room, yd->chat_name))
372 yahoo_c_leave(gc, YAHOO_CHAT_ID);
373
374 c = gaim_find_chat(gc, YAHOO_CHAT_ID);
375
376 if (!c) {
377 c = serv_got_joined_chat(gc, YAHOO_CHAT_ID, room);
378 if (topic)
379 gaim_chat_set_topic(GAIM_CHAT(c), NULL, topic);
380 yd->in_chat = 1;
381 yd->chat_name = g_strdup(room);
382 gaim_chat_add_users(GAIM_CHAT(c), members);
383 } else {
384 yahoo_chat_add_users(GAIM_CHAT(c), members);
385 }
386
387 g_list_free(members);
388 }
389
390 void yahoo_process_chat_exit(GaimConnection *gc, struct yahoo_packet *pkt)
391 {
392 char *who = NULL;
393 GSList *l;
394 struct yahoo_data *yd;
395
396 yd = gc->proto_data;
397
398 for (l = pkt->hash; l; l = l->next) {
399 struct yahoo_pair *pair = l->data;
400
401 if (pair->key == 109)
402 who = pair->value;
403 }
404
405
406 if (who) {
407 GaimConversation *c = gaim_find_chat(gc, YAHOO_CHAT_ID);
408 if (c)
409 gaim_chat_remove_user(GAIM_CHAT(c), who, NULL);
410
411 }
412 }
413
414 void yahoo_process_chat_message(GaimConnection *gc, struct yahoo_packet *pkt)
415 {
416 char *room = NULL, *who = NULL, *msg = NULL;
417 int msgtype = 1;
418 GaimConversation *c = NULL;
419 GSList *l;
420
421 for (l = pkt->hash; l; l = l->next) {
422 struct yahoo_pair *pair = l->data;
423
424 switch (pair->key) {
425
426 case 104:
427 room = pair->value;
428 break;
429 case 109:
430 who = pair->value;
431 break;
432 case 117:
433 msg = pair->value;
434 break;
435 case 124:
436 msgtype = strtol(pair->value, NULL, 10);
437 break;
438 }
439 }
440
441 if (!who)
442 return;
443
444 c = gaim_find_chat(gc, YAHOO_CHAT_ID);
445 if (!c) {
446 /* we still get messages after we part, funny that */
447 return;
448 }
449
450 if (!msg) {
451 gaim_debug(GAIM_DEBUG_MISC, "yahoo", "Got a message packet with no message.\nThis probably means something important, but we're ignoring it.\n");
452 return;
453 }
454 msg = yahoo_codes_to_html(msg);
455
456 if (msgtype == 2 || msgtype == 3) {
457 char *tmp;
458 tmp = g_strdup_printf("/me %s", msg);
459 g_free(msg);
460 msg = tmp;
461 }
462
463 serv_got_chat_in(gc, YAHOO_CHAT_ID, who, 0, msg, time(NULL));
464 g_free(msg);
465 }
466
467 void yahoo_process_chat_addinvite(GaimConnection *gc, struct yahoo_packet *pkt)
468 {
469 GSList *l;
470 char *room = NULL;
471 char *msg = NULL;
472 char *who = NULL;
473
474
475 for (l = pkt->hash; l; l = l->next) {
476 struct yahoo_pair *pair = l->data;
477
478 switch (pair->key) {
479 case 104:
480 room = pair->value;
481 break;
482 case 129: /* room id? */
483 break;
484 case 126: /* ??? */
485 break;
486 case 117:
487 msg = pair->value;
488 break;
489 case 119:
490 who = pair->value;
491 break;
492 case 118: /* us */
493 break;
494 }
495 }
496
497 if (room && who) {
498 GHashTable *components;
499
500 components = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free);
501 g_hash_table_replace(components, g_strdup("room"), g_strdup(room));
502 serv_got_chat_invite(gc, room, who, msg, components);
503 }
504 }
505
506 void yahoo_process_chat_goto(GaimConnection *gc, struct yahoo_packet *pkt)
507 {
508 if (pkt->status == -1)
509 gaim_notify_error(gc, NULL, _("Failed to join buddy in chat"),
510 _("Maybe they're not in a chat?"));
511 }
512
513
514 /*
515 * Functions dealing with conferences
516 */
517
518 static void yahoo_conf_leave(struct yahoo_data *yd, const char *room, const char *dn, GList *who)
519 {
520 struct yahoo_packet *pkt;
521 GList *w;
522
523
524 pkt = yahoo_packet_new(YAHOO_SERVICE_CONFLOGOFF, YAHOO_STATUS_AVAILABLE, 0);
525
526 yahoo_packet_hash(pkt, 1, dn);
527 for (w = who; w; w = w->next) {
528 yahoo_packet_hash(pkt, 3, (char *)w->data);
529 }
530
531 yahoo_packet_hash(pkt, 57, room);
532
533 yahoo_send_packet(yd, pkt);
534
535 yahoo_packet_free(pkt);
536 }
537
538 static int yahoo_conf_send(struct yahoo_data *yd, const char *dn, const char *room,
539 GList *members, const char *what)
540 {
541 struct yahoo_packet *pkt;
542 GList *who;
543
544 pkt = yahoo_packet_new(YAHOO_SERVICE_CONFMSG, YAHOO_STATUS_AVAILABLE, 0);
545
546 yahoo_packet_hash(pkt, 1, dn);
547 for (who = members; who; who = who->next)
548 yahoo_packet_hash(pkt, 53, (char *)who->data);
549 yahoo_packet_hash(pkt, 57, room);
550 yahoo_packet_hash(pkt, 14, what);
551 yahoo_packet_hash(pkt, 97, "1"); /* utf-8 */
552
553 yahoo_send_packet(yd, pkt);
554
555 yahoo_packet_free(pkt);
556
557 return 0;
558 }
559
560 static void yahoo_conf_join(struct yahoo_data *yd, GaimConversation *c, const char *dn, const char *room,
561 const char *topic, const char *members)
562 {
563 struct yahoo_packet *pkt;
564 char **memarr = NULL;
565 int i;
566
567 if (members)
568 memarr = g_strsplit(members, "\n", 0);
569
570
571 pkt = yahoo_packet_new(YAHOO_SERVICE_CONFLOGON, YAHOO_STATUS_AVAILABLE, 0);
572
573 yahoo_packet_hash(pkt, 1, dn);
574 yahoo_packet_hash(pkt, 3, dn);
575 yahoo_packet_hash(pkt, 57, room);
576 if (memarr) {
577 for(i = 0 ; memarr[i]; i++) {
578 if (!strcmp(memarr[i], "") || !strcmp(memarr[i], dn))
579 continue;
580 yahoo_packet_hash(pkt, 3, memarr[i]);
581 gaim_chat_add_user(GAIM_CHAT(c), memarr[i], NULL);
582 }
583 }
584 yahoo_send_packet(yd, pkt);
585
586 yahoo_packet_free(pkt);
587
588 if (memarr)
589 g_strfreev(memarr);
590 }
591
592 static void yahoo_conf_invite(struct yahoo_data *yd, GaimConversation *c,
593 const char *dn, const char *buddy, const char *room, const char *msg)
594 {
595 struct yahoo_packet *pkt;
596 GList *members;
597
598 members = gaim_chat_get_users(GAIM_CHAT(c));
599
600 pkt = yahoo_packet_new(YAHOO_SERVICE_CONFADDINVITE, YAHOO_STATUS_AVAILABLE, 0);
601
602 yahoo_packet_hash(pkt, 1, dn);
603 yahoo_packet_hash(pkt, 51, buddy);
604 yahoo_packet_hash(pkt, 57, room);
605 yahoo_packet_hash(pkt, 58, msg?msg:"");
606 yahoo_packet_hash(pkt, 13, "0");
607 for(; members; members = members->next) {
608 if (!strcmp(members->data, dn))
609 continue;
610 yahoo_packet_hash(pkt, 52, (char *)members->data);
611 yahoo_packet_hash(pkt, 53, (char *)members->data);
612 }
613 yahoo_send_packet(yd, pkt);
614
615 yahoo_packet_free(pkt);
616 }
617
618 /*
619 * Functions dealing with chats
620 */
621
622 static void yahoo_chat_leave(struct yahoo_data *yd, const char *room, const char *dn)
623 {
624 struct yahoo_packet *pkt;
625
626 pkt = yahoo_packet_new(YAHOO_SERVICE_CHATEXIT, YAHOO_STATUS_AVAILABLE, 0);
627
628 yahoo_packet_hash(pkt, 104, room);
629 yahoo_packet_hash(pkt, 109, dn);
630 yahoo_packet_hash(pkt, 108, "1");
631 yahoo_packet_hash(pkt, 112, "0"); /* what does this one mean? */
632
633 yahoo_send_packet(yd, pkt);
634
635 yahoo_packet_free(pkt);
636
637 yd->in_chat = 0;
638 if (yd->chat_name) {
639 g_free(yd->chat_name);
640 yd->chat_name = NULL;
641 }
642
643 }
644
645 static int yahoo_chat_send(struct yahoo_data *yd, const char *dn, const char *room, const char *what)
646 {
647 struct yahoo_packet *pkt;
648 const char *msg;
649 int me = 0;
650
651 if (!g_ascii_strncasecmp(what, "/me ", 4)) { /* XXX fix this to ignore leading html */
652 me = 1;
653 msg = what + 4;
654 } else
655 msg = what;
656
657 pkt = yahoo_packet_new(YAHOO_SERVICE_COMMENT, YAHOO_STATUS_AVAILABLE, 0);
658
659 yahoo_packet_hash(pkt, 1, dn);
660 yahoo_packet_hash(pkt, 104, room);
661 yahoo_packet_hash(pkt, 117, msg);
662 if (me)
663 yahoo_packet_hash(pkt, 124, "2");
664 else
665 yahoo_packet_hash(pkt, 124, "1");
666 /* fixme: what about /think? (124=3) */
667
668 yahoo_send_packet(yd, pkt);
669 yahoo_packet_free(pkt);
670
671 return 0;
672 }
673
674 static void yahoo_chat_join(struct yahoo_data *yd, const char *dn, const char *room, const char *topic)
675 {
676 struct yahoo_packet *pkt;
677
678 pkt = yahoo_packet_new(YAHOO_SERVICE_CHATJOIN, YAHOO_STATUS_AVAILABLE, 0);
679
680 yahoo_packet_hash(pkt, 62, "2");
681 yahoo_packet_hash(pkt, 104, room);
682 yahoo_packet_hash(pkt, 129, "0");
683
684 yahoo_send_packet(yd, pkt);
685
686 yahoo_packet_free(pkt);
687 }
688
689 static void yahoo_chat_invite(struct yahoo_data *yd, const char *dn, const char *buddy,
690 const char *room, const char *msg)
691 {
692 struct yahoo_packet *pkt;
693
694 pkt = yahoo_packet_new(YAHOO_SERVICE_CHATADDINVITE, YAHOO_STATUS_AVAILABLE, 0);
695
696 yahoo_packet_hash(pkt, 1, dn);
697 yahoo_packet_hash(pkt, 118, buddy);
698 yahoo_packet_hash(pkt, 104, room);
699 yahoo_packet_hash(pkt, 117, (msg?msg:""));
700 yahoo_packet_hash(pkt, 129, "0");
701
702 yahoo_send_packet(yd, pkt);
703 yahoo_packet_free(pkt);
704 }
705
706 void yahoo_chat_goto(GaimConnection *gc, const char *name)
707 {
708 struct yahoo_data *yd;
709 struct yahoo_packet *pkt;
710
711 yd = gc->proto_data;
712
713 if (!yd->chat_online)
714 yahoo_chat_online(gc);
715
716 pkt = yahoo_packet_new(YAHOO_SERVICE_CHATGOTO, YAHOO_STATUS_AVAILABLE, 0);
717
718 yahoo_packet_hash(pkt, 109, name);
719 yahoo_packet_hash(pkt, 1, gaim_connection_get_display_name(gc));
720 yahoo_packet_hash(pkt, 62, "2");
721
722 yahoo_send_packet(yd, pkt);
723 yahoo_packet_free(pkt);
724 }
725 /*
726 * These are the functions registered with the core
727 * which get called for both chats and conferences.
728 */
729
730 void yahoo_c_leave(GaimConnection *gc, int id)
731 {
732 struct yahoo_data *yd = (struct yahoo_data *) gc->proto_data;
733 GaimConversation *c;
734
735 if (!yd)
736 return;
737
738
739 c = gaim_find_chat(gc, id);
740 if (!c)
741 return;
742
743 if (id != YAHOO_CHAT_ID) {
744 yahoo_conf_leave(yd, gaim_conversation_get_name(c),
745 gaim_connection_get_display_name(gc), gaim_chat_get_users(GAIM_CHAT(c)));
746 yd->confs = g_slist_remove(yd->confs, c);
747 } else {
748 yahoo_chat_leave(yd, gaim_conversation_get_name(c), gaim_connection_get_display_name(gc));
749 }
750
751 serv_got_chat_left(gc, id);
752 }
753
754 int yahoo_c_send(GaimConnection *gc, int id, const char *what)
755 {
756 GaimConversation *c;
757 int ret;
758 struct yahoo_data *yd;
759 char *msg;
760
761 yd = (struct yahoo_data *) gc->proto_data;
762 if (!yd)
763 return -1;
764
765 c = gaim_find_chat(gc, id);
766 if (!c)
767 return -1;
768
769 msg = yahoo_html_to_codes(what);
770
771 if (id != YAHOO_CHAT_ID) {
772 ret = yahoo_conf_send(yd, gaim_connection_get_display_name(gc),
773 gaim_conversation_get_name(c), gaim_chat_get_users(GAIM_CHAT(c)), msg);
774 } else {
775 ret = yahoo_chat_send(yd, gaim_connection_get_display_name(gc),
776 gaim_conversation_get_name(c), msg);
777 if (!ret)
778 serv_got_chat_in(gc, gaim_chat_get_id(GAIM_CHAT(c)),
779 gaim_connection_get_display_name(gc), 0, what, time(NULL));
780 }
781
782 g_free(msg);
783 return ret;
784 }
785
786 GList *yahoo_c_info(GaimConnection *gc)
787 {
788 GList *m = NULL;
789 struct proto_chat_entry *pce;
790
791 pce = g_new0(struct proto_chat_entry, 1);
792 pce->label = _("Room:");
793 pce->identifier = "room";
794 m = g_list_append(m, pce);
795
796 return m;
797 }
798
799 void yahoo_c_join(GaimConnection *gc, GHashTable *data)
800 {
801 struct yahoo_data *yd;
802 char *room, *topic, *members, *type;
803 int id;
804 GaimConversation *c;
805
806 yd = (struct yahoo_data *) gc->proto_data;
807 if (!yd)
808 return;
809
810 room = g_hash_table_lookup(data, "room");
811 if (!room)
812 return;
813
814 topic = g_hash_table_lookup(data, "topic");
815 if (!topic)
816 topic = "";
817
818 members = g_hash_table_lookup(data, "members");
819
820
821 if ((type = g_hash_table_lookup(data, "type")) && !strcmp(type, "Conference")) {
822 id = yd->conf_id++;
823 c = serv_got_joined_chat(gc, id, room);
824 yd->confs = g_slist_prepend(yd->confs, c);
825 gaim_chat_set_topic(GAIM_CHAT(c), gaim_connection_get_display_name(gc), topic);
826 yahoo_conf_join(yd, c, gaim_connection_get_display_name(gc), room, topic, members);
827 return;
828 } else {
829 if (yd->in_chat)
830 yahoo_c_leave(gc, YAHOO_CHAT_ID);
831 if (!yd->chat_online)
832 yahoo_chat_online(gc);
833 yahoo_chat_join(yd, gaim_connection_get_display_name(gc), room, topic);
834 return;
835 }
836 }
837
838 void yahoo_c_invite(GaimConnection *gc, int id, const char *msg, const char *name)
839 {
840 struct yahoo_data *yd = (struct yahoo_data *) gc->proto_data;
841 GaimConversation *c;
842
843 c = gaim_find_chat(gc, id);
844 if (!c || !c->name)
845 return;
846
847 if (id != YAHOO_CHAT_ID) {
848 yahoo_conf_invite(yd, c, gaim_connection_get_display_name(gc), name,
849 gaim_conversation_get_name(c), msg);
850 } else {
851 yahoo_chat_invite(yd, gaim_connection_get_display_name(gc), name,
852 gaim_conversation_get_name(c), msg);
853 }
854 }
855