6729
|
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
|