Mercurial > pidgin
annotate src/protocols/yahoo/yahoochat.c @ 7458:7c320cdc0f3a
[gaim-migrate @ 8071]
Fixes the bug where some dialogs would crash when spell checking was
enabled. Closes #827930.
committer: Tailor Script <tailor@pidgin.im>
author | Christian Hammond <chipx86@chipx86.com> |
---|---|
date | Sat, 08 Nov 2003 05:18:17 +0000 |
parents | 0da869011d8a |
children | ee32e030c9be |
rev | line source |
---|---|
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 | |
7186 | 43 /* prototype(s) */ |
44 static void yahoo_chat_leave(GaimConnection *gc, const char *room, const char *dn, gboolean logout); | |
45 | |
6729 | 46 /* special function to log us on to the yahoo chat service */ |
47 static void yahoo_chat_online(GaimConnection *gc) | |
48 { | |
49 struct yahoo_data *yd = gc->proto_data; | |
50 struct yahoo_packet *pkt; | |
51 | |
52 | |
53 pkt = yahoo_packet_new(YAHOO_SERVICE_CHATONLINE, YAHOO_STATUS_AVAILABLE,0); | |
54 yahoo_packet_hash(pkt, 1, gaim_connection_get_display_name(gc)); | |
55 yahoo_packet_hash(pkt, 109, gaim_connection_get_display_name(gc)); | |
56 yahoo_packet_hash(pkt, 6, "abcde"); | |
57 | |
58 yahoo_send_packet(yd, pkt); | |
59 | |
60 yahoo_packet_free(pkt); | |
61 } | |
62 | |
63 static gint _mystrcmpwrapper(gconstpointer a, gconstpointer b) | |
64 { | |
65 return strcmp(a, b); | |
66 } | |
67 | |
68 /* this is slow, and different from the gaim_* version in that it (hopefully) won't add a user twice */ | |
7118
bf630f7dfdcd
[gaim-migrate @ 7685]
Christian Hammond <chipx86@chipx86.com>
parents:
6804
diff
changeset
|
69 static void yahoo_chat_add_users(GaimConvChat *chat, GList *newusers) |
6729 | 70 { |
71 GList *users, *i, *j; | |
72 | |
7118
bf630f7dfdcd
[gaim-migrate @ 7685]
Christian Hammond <chipx86@chipx86.com>
parents:
6804
diff
changeset
|
73 users = gaim_conv_chat_get_users(chat); |
6729 | 74 |
75 for (i = newusers; i; i = i->next) { | |
76 j = g_list_find_custom(users, i->data, _mystrcmpwrapper); | |
77 if (j) | |
78 continue; | |
7118
bf630f7dfdcd
[gaim-migrate @ 7685]
Christian Hammond <chipx86@chipx86.com>
parents:
6804
diff
changeset
|
79 gaim_conv_chat_add_user(chat, i->data, NULL); |
6729 | 80 } |
81 } | |
82 | |
7118
bf630f7dfdcd
[gaim-migrate @ 7685]
Christian Hammond <chipx86@chipx86.com>
parents:
6804
diff
changeset
|
83 static void yahoo_chat_add_user(GaimConvChat *chat, const char *user, const char *reason) |
6729 | 84 { |
85 GList *users; | |
86 | |
7118
bf630f7dfdcd
[gaim-migrate @ 7685]
Christian Hammond <chipx86@chipx86.com>
parents:
6804
diff
changeset
|
87 users = gaim_conv_chat_get_users(chat); |
6729 | 88 |
89 if ((g_list_find_custom(users, user, _mystrcmpwrapper))) | |
90 return; | |
91 | |
7118
bf630f7dfdcd
[gaim-migrate @ 7685]
Christian Hammond <chipx86@chipx86.com>
parents:
6804
diff
changeset
|
92 gaim_conv_chat_add_user(chat, user, reason); |
6729 | 93 } |
94 | |
95 static GaimConversation *yahoo_find_conference(GaimConnection *gc, const char *name) | |
96 { | |
97 struct yahoo_data *yd; | |
98 GSList *l; | |
99 | |
100 yd = gc->proto_data; | |
101 | |
102 for (l = yd->confs; l; l = l->next) { | |
103 GaimConversation *c = l->data; | |
104 if (!gaim_utf8_strcasecmp(gaim_conversation_get_name(c), name)) | |
105 return c; | |
106 } | |
107 return NULL; | |
108 } | |
109 | |
110 | |
111 void yahoo_process_conference_invite(GaimConnection *gc, struct yahoo_packet *pkt) | |
112 { | |
113 GSList *l; | |
114 char *room = NULL; | |
115 char *who = NULL; | |
116 char *msg = NULL; | |
117 GString *members = NULL; | |
118 GHashTable *components; | |
119 | |
120 | |
121 if (pkt->status == 2) | |
122 return; /* XXX */ | |
123 | |
124 members = g_string_sized_new(512); | |
125 | |
126 for (l = pkt->hash; l; l = l->next) { | |
127 struct yahoo_pair *pair = l->data; | |
128 | |
129 switch (pair->key) { | |
130 case 1: /* us, but we already know who we are */ | |
131 break; | |
132 case 57: | |
133 room = pair->value; | |
134 break; | |
135 case 50: /* inviter */ | |
136 who = pair->value; | |
137 g_string_append_printf(members, "%s\n", who); | |
138 break; | |
139 case 52: /* members */ | |
140 g_string_append_printf(members, "%s\n", pair->value); | |
141 break; | |
142 case 58: | |
143 msg = pair->value; | |
144 break; | |
145 case 13: /* ? */ | |
146 break; | |
147 } | |
148 } | |
149 | |
150 if (!room) { | |
151 g_string_free(members, TRUE); | |
152 return; | |
153 } | |
154 | |
155 components = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free); | |
156 g_hash_table_replace(components, g_strdup("room"), g_strdup(room)); | |
157 if (msg) | |
158 g_hash_table_replace(components, g_strdup("topic"), g_strdup(msg)); | |
159 g_hash_table_replace(components, g_strdup("type"), g_strdup("Conference")); | |
160 if (members) { | |
161 g_hash_table_replace(components, g_strdup("members"), g_strdup(members->str)); | |
162 } | |
163 serv_got_chat_invite(gc, room, who, msg, components); | |
164 | |
165 g_string_free(members, TRUE); | |
166 } | |
167 | |
168 void yahoo_process_conference_decline(GaimConnection *gc, struct yahoo_packet *pkt) | |
169 { | |
170 GSList *l; | |
171 char *room = NULL; | |
172 char *who = NULL; | |
173 char *msg = NULL; | |
174 | |
175 for (l = pkt->hash; l; l = l->next) { | |
176 struct yahoo_pair *pair = l->data; | |
177 | |
178 switch (pair->key) { | |
179 case 57: | |
180 room = pair->value; | |
181 break; | |
182 case 54: | |
183 who = pair->value; | |
184 break; | |
185 case 14: | |
186 msg = pair->value; | |
187 break; | |
188 } | |
189 } | |
190 | |
191 if (who && room) { | |
192 char *tmp; | |
193 | |
194 tmp = g_strdup_printf(_("%s declined your conference invitation to room \"%s\" because \"%s\"."), | |
195 who, room, msg?msg:""); | |
196 gaim_notify_info(gc, NULL, _("Invitation Rejected"), tmp); | |
197 g_free(tmp); | |
198 } | |
199 } | |
200 | |
201 void yahoo_process_conference_logon(GaimConnection *gc, struct yahoo_packet *pkt) | |
202 { | |
203 GSList *l; | |
204 char *room = NULL; | |
205 char *who = NULL; | |
206 GaimConversation *c; | |
207 | |
208 for (l = pkt->hash; l; l = l->next) { | |
209 struct yahoo_pair *pair = l->data; | |
210 | |
211 switch (pair->key) { | |
212 case 57: | |
213 room = pair->value; | |
214 break; | |
215 case 53: | |
216 who = pair->value; | |
217 break; | |
218 } | |
219 } | |
220 | |
221 if (who && room) { | |
222 c = yahoo_find_conference(gc, room); | |
223 if (c) | |
7118
bf630f7dfdcd
[gaim-migrate @ 7685]
Christian Hammond <chipx86@chipx86.com>
parents:
6804
diff
changeset
|
224 yahoo_chat_add_user(GAIM_CONV_CHAT(c), who, NULL); |
6729 | 225 } |
226 } | |
227 | |
228 void yahoo_process_conference_logoff(GaimConnection *gc, struct yahoo_packet *pkt) | |
229 { | |
230 GSList *l; | |
231 char *room = NULL; | |
232 char *who = NULL; | |
233 GaimConversation *c; | |
234 | |
235 for (l = pkt->hash; l; l = l->next) { | |
236 struct yahoo_pair *pair = l->data; | |
237 | |
238 switch (pair->key) { | |
239 case 57: | |
240 room = pair->value; | |
241 break; | |
242 case 56: | |
243 who = pair->value; | |
244 break; | |
245 } | |
246 } | |
247 | |
248 if (who && room) { | |
249 c = yahoo_find_conference(gc, room); | |
250 if (c) | |
7118
bf630f7dfdcd
[gaim-migrate @ 7685]
Christian Hammond <chipx86@chipx86.com>
parents:
6804
diff
changeset
|
251 gaim_conv_chat_remove_user(GAIM_CONV_CHAT(c), who, NULL); |
6729 | 252 } |
253 } | |
254 | |
255 void yahoo_process_conference_message(GaimConnection *gc, struct yahoo_packet *pkt) | |
256 { | |
257 GSList *l; | |
258 char *room = NULL; | |
259 char *who = NULL; | |
260 char *msg = NULL; | |
261 GaimConversation *c; | |
262 | |
263 for (l = pkt->hash; l; l = l->next) { | |
264 struct yahoo_pair *pair = l->data; | |
265 | |
266 switch (pair->key) { | |
267 case 57: | |
268 room = pair->value; | |
269 break; | |
270 case 3: | |
271 who = pair->value; | |
272 break; | |
273 case 14: | |
274 msg = pair->value; | |
275 break; | |
276 } | |
277 } | |
278 | |
279 if (room && who && msg) { | |
280 c = yahoo_find_conference(gc, room); | |
281 if (!c) | |
282 return; | |
283 msg = yahoo_codes_to_html(msg); | |
7118
bf630f7dfdcd
[gaim-migrate @ 7685]
Christian Hammond <chipx86@chipx86.com>
parents:
6804
diff
changeset
|
284 serv_got_chat_in(gc, gaim_conv_chat_get_id(GAIM_CONV_CHAT(c)), who, 0, msg, time(NULL)); |
6729 | 285 g_free(msg); |
286 } | |
287 | |
288 } | |
289 | |
290 | |
291 /* this is a comfirmation of yahoo_chat_online(); */ | |
292 void yahoo_process_chat_online(GaimConnection *gc, struct yahoo_packet *pkt) | |
293 { | |
294 struct yahoo_data *yd = (struct yahoo_data *) gc->proto_data; | |
295 | |
296 if (pkt->status == 1) | |
297 yd->chat_online = 1; | |
298 } | |
299 | |
300 /* this is basicly the opposite of chat_online */ | |
301 void yahoo_process_chat_logout(GaimConnection *gc, struct yahoo_packet *pkt) | |
302 { | |
303 struct yahoo_data *yd = (struct yahoo_data *) gc->proto_data; | |
7186 | 304 GSList *l; |
305 | |
306 for (l = pkt->hash; l; l = l->next) { | |
307 struct yahoo_pair *pair = l->data; | |
6729 | 308 |
7186 | 309 if (pair->key == 1) |
310 if (g_ascii_strcasecmp(pair->value, | |
311 gaim_connection_get_display_name(gc))) | |
312 return; | |
313 } | |
314 | |
315 if (pkt->status == 1) { | |
6729 | 316 yd->chat_online = 0; |
7186 | 317 if (yd->in_chat) |
318 yahoo_c_leave(gc, YAHOO_CHAT_ID); | |
319 } | |
6729 | 320 } |
321 | |
322 void yahoo_process_chat_join(GaimConnection *gc, struct yahoo_packet *pkt) | |
323 { | |
324 struct yahoo_data *yd = (struct yahoo_data *) gc->proto_data; | |
325 GaimConversation *c = NULL; | |
326 GSList *l; | |
327 GList *members = NULL; | |
328 char *room = NULL; | |
329 char *topic = NULL; | |
330 char *someid, *someotherid, *somebase64orhashosomething, *somenegativenumber; | |
331 | |
332 if (pkt->status == -1) { | |
333 gaim_notify_error(gc, NULL, _("Failed to join chat"), _("Maybe the room is full?")); | |
334 return; | |
335 } | |
336 | |
337 for (l = pkt->hash; l; l = l->next) { | |
338 struct yahoo_pair *pair = l->data; | |
339 | |
340 switch (pair->key) { | |
341 | |
342 case 104: | |
343 room = pair->value; | |
344 break; | |
345 case 105: | |
346 topic = pair->value; | |
347 break; | |
348 case 128: | |
349 someid = pair->value; | |
350 break; | |
351 case 108: /* number of joiners */ | |
352 break; | |
353 case 129: | |
354 someotherid = pair->value; | |
355 break; | |
356 case 130: | |
357 somebase64orhashosomething = pair->value; | |
358 break; | |
359 case 126: | |
360 somenegativenumber = pair->value; | |
361 break; | |
362 case 13: /* this is 1. maybe its the type of room? (normal, user created, private, etc?) */ | |
363 break; | |
364 case 61: /*this looks similiar to 130 */ | |
365 break; | |
366 | |
367 /* the previous section was just room info. this next section is | |
368 info about individual room members, (including us) */ | |
369 | |
370 case 109: /* the yahoo id */ | |
371 members = g_list_append(members, pair->value); | |
372 break; | |
373 case 110: /* age */ | |
374 break; | |
375 case 141: /* nickname */ | |
376 break; | |
377 case 142: /* location */ | |
378 break; | |
379 case 113: /* bitmask */ | |
380 break; | |
381 } | |
382 } | |
383 | |
384 if (!room) | |
385 return; | |
386 | |
387 if (yd->chat_name && gaim_utf8_strcasecmp(room, yd->chat_name)) | |
7186 | 388 yahoo_chat_leave(gc, room, |
389 gaim_connection_get_display_name(gc), FALSE); | |
6729 | 390 |
391 c = gaim_find_chat(gc, YAHOO_CHAT_ID); | |
392 | |
7186 | 393 if (!c && members && ((g_list_length(members) > 1) || |
394 !g_ascii_strcasecmp(members->data, | |
395 gaim_connection_get_display_name(gc)))) { | |
6729 | 396 c = serv_got_joined_chat(gc, YAHOO_CHAT_ID, room); |
397 if (topic) | |
7118
bf630f7dfdcd
[gaim-migrate @ 7685]
Christian Hammond <chipx86@chipx86.com>
parents:
6804
diff
changeset
|
398 gaim_conv_chat_set_topic(GAIM_CONV_CHAT(c), NULL, topic); |
6729 | 399 yd->in_chat = 1; |
400 yd->chat_name = g_strdup(room); | |
7118
bf630f7dfdcd
[gaim-migrate @ 7685]
Christian Hammond <chipx86@chipx86.com>
parents:
6804
diff
changeset
|
401 gaim_conv_chat_add_users(GAIM_CONV_CHAT(c), members); |
7186 | 402 } else if (c) { |
7118
bf630f7dfdcd
[gaim-migrate @ 7685]
Christian Hammond <chipx86@chipx86.com>
parents:
6804
diff
changeset
|
403 yahoo_chat_add_users(GAIM_CONV_CHAT(c), members); |
6729 | 404 } |
405 | |
406 g_list_free(members); | |
407 } | |
408 | |
409 void yahoo_process_chat_exit(GaimConnection *gc, struct yahoo_packet *pkt) | |
410 { | |
411 char *who = NULL; | |
7186 | 412 char *room = NULL; |
6729 | 413 GSList *l; |
414 struct yahoo_data *yd; | |
415 | |
416 yd = gc->proto_data; | |
417 | |
418 for (l = pkt->hash; l; l = l->next) { | |
419 struct yahoo_pair *pair = l->data; | |
420 | |
7186 | 421 if (pair->key == 104) |
422 room = pair->value; | |
6729 | 423 if (pair->key == 109) |
424 who = pair->value; | |
425 } | |
426 | |
427 | |
7186 | 428 if (who && room) { |
6729 | 429 GaimConversation *c = gaim_find_chat(gc, YAHOO_CHAT_ID); |
7186 | 430 if (c && !gaim_utf8_strcasecmp(gaim_conversation_get_name(c), room)) |
7118
bf630f7dfdcd
[gaim-migrate @ 7685]
Christian Hammond <chipx86@chipx86.com>
parents:
6804
diff
changeset
|
431 gaim_conv_chat_remove_user(GAIM_CONV_CHAT(c), who, NULL); |
6729 | 432 |
433 } | |
434 } | |
435 | |
436 void yahoo_process_chat_message(GaimConnection *gc, struct yahoo_packet *pkt) | |
437 { | |
438 char *room = NULL, *who = NULL, *msg = NULL; | |
439 int msgtype = 1; | |
440 GaimConversation *c = NULL; | |
441 GSList *l; | |
442 | |
443 for (l = pkt->hash; l; l = l->next) { | |
444 struct yahoo_pair *pair = l->data; | |
445 | |
446 switch (pair->key) { | |
447 | |
448 case 104: | |
449 room = pair->value; | |
450 break; | |
451 case 109: | |
452 who = pair->value; | |
453 break; | |
454 case 117: | |
455 msg = pair->value; | |
456 break; | |
457 case 124: | |
458 msgtype = strtol(pair->value, NULL, 10); | |
459 break; | |
460 } | |
461 } | |
462 | |
463 if (!who) | |
464 return; | |
465 | |
466 c = gaim_find_chat(gc, YAHOO_CHAT_ID); | |
467 if (!c) { | |
468 /* we still get messages after we part, funny that */ | |
469 return; | |
470 } | |
471 | |
472 if (!msg) { | |
473 gaim_debug(GAIM_DEBUG_MISC, "yahoo", "Got a message packet with no message.\nThis probably means something important, but we're ignoring it.\n"); | |
474 return; | |
475 } | |
476 msg = yahoo_codes_to_html(msg); | |
477 | |
478 if (msgtype == 2 || msgtype == 3) { | |
479 char *tmp; | |
480 tmp = g_strdup_printf("/me %s", msg); | |
481 g_free(msg); | |
482 msg = tmp; | |
483 } | |
484 | |
485 serv_got_chat_in(gc, YAHOO_CHAT_ID, who, 0, msg, time(NULL)); | |
486 g_free(msg); | |
487 } | |
488 | |
489 void yahoo_process_chat_addinvite(GaimConnection *gc, struct yahoo_packet *pkt) | |
490 { | |
491 GSList *l; | |
492 char *room = NULL; | |
493 char *msg = NULL; | |
494 char *who = NULL; | |
495 | |
496 | |
497 for (l = pkt->hash; l; l = l->next) { | |
498 struct yahoo_pair *pair = l->data; | |
499 | |
500 switch (pair->key) { | |
501 case 104: | |
502 room = pair->value; | |
503 break; | |
504 case 129: /* room id? */ | |
505 break; | |
506 case 126: /* ??? */ | |
507 break; | |
508 case 117: | |
509 msg = pair->value; | |
510 break; | |
511 case 119: | |
512 who = pair->value; | |
513 break; | |
514 case 118: /* us */ | |
515 break; | |
516 } | |
517 } | |
518 | |
519 if (room && who) { | |
520 GHashTable *components; | |
521 | |
522 components = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free); | |
523 g_hash_table_replace(components, g_strdup("room"), g_strdup(room)); | |
524 serv_got_chat_invite(gc, room, who, msg, components); | |
525 } | |
526 } | |
527 | |
528 void yahoo_process_chat_goto(GaimConnection *gc, struct yahoo_packet *pkt) | |
529 { | |
530 if (pkt->status == -1) | |
531 gaim_notify_error(gc, NULL, _("Failed to join buddy in chat"), | |
532 _("Maybe they're not in a chat?")); | |
533 } | |
534 | |
535 | |
536 /* | |
537 * Functions dealing with conferences | |
538 */ | |
539 | |
540 static void yahoo_conf_leave(struct yahoo_data *yd, const char *room, const char *dn, GList *who) | |
541 { | |
542 struct yahoo_packet *pkt; | |
543 GList *w; | |
544 | |
545 | |
546 pkt = yahoo_packet_new(YAHOO_SERVICE_CONFLOGOFF, YAHOO_STATUS_AVAILABLE, 0); | |
547 | |
548 yahoo_packet_hash(pkt, 1, dn); | |
549 for (w = who; w; w = w->next) { | |
550 yahoo_packet_hash(pkt, 3, (char *)w->data); | |
551 } | |
552 | |
553 yahoo_packet_hash(pkt, 57, room); | |
554 | |
555 yahoo_send_packet(yd, pkt); | |
556 | |
557 yahoo_packet_free(pkt); | |
558 } | |
559 | |
560 static int yahoo_conf_send(struct yahoo_data *yd, const char *dn, const char *room, | |
561 GList *members, const char *what) | |
562 { | |
563 struct yahoo_packet *pkt; | |
564 GList *who; | |
6804 | 565 char *msg; |
566 | |
567 msg = yahoo_html_to_codes(what); | |
6729 | 568 |
569 pkt = yahoo_packet_new(YAHOO_SERVICE_CONFMSG, YAHOO_STATUS_AVAILABLE, 0); | |
570 | |
571 yahoo_packet_hash(pkt, 1, dn); | |
572 for (who = members; who; who = who->next) | |
573 yahoo_packet_hash(pkt, 53, (char *)who->data); | |
574 yahoo_packet_hash(pkt, 57, room); | |
6804 | 575 yahoo_packet_hash(pkt, 14, msg); |
6729 | 576 yahoo_packet_hash(pkt, 97, "1"); /* utf-8 */ |
577 | |
578 yahoo_send_packet(yd, pkt); | |
579 | |
580 yahoo_packet_free(pkt); | |
6804 | 581 g_free(msg); |
6729 | 582 |
583 return 0; | |
584 } | |
585 | |
586 static void yahoo_conf_join(struct yahoo_data *yd, GaimConversation *c, const char *dn, const char *room, | |
587 const char *topic, const char *members) | |
588 { | |
589 struct yahoo_packet *pkt; | |
590 char **memarr = NULL; | |
591 int i; | |
592 | |
593 if (members) | |
594 memarr = g_strsplit(members, "\n", 0); | |
595 | |
596 | |
597 pkt = yahoo_packet_new(YAHOO_SERVICE_CONFLOGON, YAHOO_STATUS_AVAILABLE, 0); | |
598 | |
599 yahoo_packet_hash(pkt, 1, dn); | |
600 yahoo_packet_hash(pkt, 3, dn); | |
601 yahoo_packet_hash(pkt, 57, room); | |
602 if (memarr) { | |
603 for(i = 0 ; memarr[i]; i++) { | |
604 if (!strcmp(memarr[i], "") || !strcmp(memarr[i], dn)) | |
605 continue; | |
606 yahoo_packet_hash(pkt, 3, memarr[i]); | |
7118
bf630f7dfdcd
[gaim-migrate @ 7685]
Christian Hammond <chipx86@chipx86.com>
parents:
6804
diff
changeset
|
607 gaim_conv_chat_add_user(GAIM_CONV_CHAT(c), memarr[i], NULL); |
6729 | 608 } |
609 } | |
610 yahoo_send_packet(yd, pkt); | |
611 | |
612 yahoo_packet_free(pkt); | |
613 | |
614 if (memarr) | |
615 g_strfreev(memarr); | |
616 } | |
617 | |
618 static void yahoo_conf_invite(struct yahoo_data *yd, GaimConversation *c, | |
619 const char *dn, const char *buddy, const char *room, const char *msg) | |
620 { | |
621 struct yahoo_packet *pkt; | |
622 GList *members; | |
623 | |
7118
bf630f7dfdcd
[gaim-migrate @ 7685]
Christian Hammond <chipx86@chipx86.com>
parents:
6804
diff
changeset
|
624 members = gaim_conv_chat_get_users(GAIM_CONV_CHAT(c)); |
6729 | 625 |
626 pkt = yahoo_packet_new(YAHOO_SERVICE_CONFADDINVITE, YAHOO_STATUS_AVAILABLE, 0); | |
627 | |
628 yahoo_packet_hash(pkt, 1, dn); | |
629 yahoo_packet_hash(pkt, 51, buddy); | |
630 yahoo_packet_hash(pkt, 57, room); | |
631 yahoo_packet_hash(pkt, 58, msg?msg:""); | |
632 yahoo_packet_hash(pkt, 13, "0"); | |
633 for(; members; members = members->next) { | |
634 if (!strcmp(members->data, dn)) | |
635 continue; | |
636 yahoo_packet_hash(pkt, 52, (char *)members->data); | |
637 yahoo_packet_hash(pkt, 53, (char *)members->data); | |
638 } | |
639 yahoo_send_packet(yd, pkt); | |
640 | |
641 yahoo_packet_free(pkt); | |
642 } | |
643 | |
644 /* | |
645 * Functions dealing with chats | |
646 */ | |
647 | |
7186 | 648 static void yahoo_chat_leave(GaimConnection *gc, const char *room, const char *dn, gboolean logout) |
6729 | 649 { |
7186 | 650 struct yahoo_data *yd = gc->proto_data; |
6729 | 651 struct yahoo_packet *pkt; |
7186 | 652 GaimConversation *c; |
6729 | 653 |
654 pkt = yahoo_packet_new(YAHOO_SERVICE_CHATEXIT, YAHOO_STATUS_AVAILABLE, 0); | |
655 | |
656 yahoo_packet_hash(pkt, 104, room); | |
657 yahoo_packet_hash(pkt, 109, dn); | |
658 yahoo_packet_hash(pkt, 108, "1"); | |
659 yahoo_packet_hash(pkt, 112, "0"); /* what does this one mean? */ | |
660 | |
661 yahoo_send_packet(yd, pkt); | |
662 | |
663 yahoo_packet_free(pkt); | |
664 | |
665 yd->in_chat = 0; | |
666 if (yd->chat_name) { | |
667 g_free(yd->chat_name); | |
668 yd->chat_name = NULL; | |
669 } | |
670 | |
7186 | 671 if ((c = gaim_find_chat(gc, YAHOO_CHAT_ID))) |
672 serv_got_chat_left(gc, YAHOO_CHAT_ID); | |
673 | |
674 if (!logout) | |
675 return; | |
676 | |
677 pkt = yahoo_packet_new(YAHOO_SERVICE_CHATLOGOUT, | |
678 YAHOO_STATUS_AVAILABLE, 0); | |
679 yahoo_packet_hash(pkt, 1, dn); | |
680 yahoo_send_packet(yd, pkt); | |
681 yahoo_packet_free(pkt); | |
682 | |
683 yd->chat_online = 0; | |
6729 | 684 } |
685 | |
6804 | 686 /* borrowed from gtkconv.c */ |
687 static gboolean | |
688 meify(char *message, size_t len) | |
689 { | |
690 /* | |
691 * Read /me-ify: If the message (post-HTML) starts with /me, | |
692 * remove the "/me " part of it (including that space) and return TRUE. | |
693 */ | |
694 char *c; | |
695 gboolean inside_html = 0; | |
696 | |
697 /* Umm.. this would be very bad if this happens. */ | |
698 g_return_val_if_fail(message != NULL, FALSE); | |
699 | |
700 if (len == -1) | |
701 len = strlen(message); | |
702 | |
703 for (c = message; *c != '\0'; c++, len--) { | |
704 if (inside_html) { | |
705 if (*c == '>') | |
706 inside_html = FALSE; | |
707 } | |
708 else { | |
709 if (*c == '<') | |
710 inside_html = TRUE; | |
711 else | |
712 break; | |
713 } | |
714 } | |
715 | |
716 if (*c != '\0' && !g_ascii_strncasecmp(c, "/me ", 4)) { | |
717 memmove(c, c + 4, len - 3); | |
718 | |
719 return TRUE; | |
720 } | |
721 | |
722 return FALSE; | |
723 } | |
724 | |
6729 | 725 static int yahoo_chat_send(struct yahoo_data *yd, const char *dn, const char *room, const char *what) |
726 { | |
727 struct yahoo_packet *pkt; | |
728 int me = 0; | |
6804 | 729 char *msg1, *msg2; |
730 | |
731 msg1 = g_strdup(what); | |
6729 | 732 |
6804 | 733 if (meify(msg1, -1)) |
6729 | 734 me = 1; |
6804 | 735 |
736 msg2 = yahoo_html_to_codes(msg1); | |
737 g_free(msg1); | |
6729 | 738 |
739 pkt = yahoo_packet_new(YAHOO_SERVICE_COMMENT, YAHOO_STATUS_AVAILABLE, 0); | |
740 | |
741 yahoo_packet_hash(pkt, 1, dn); | |
742 yahoo_packet_hash(pkt, 104, room); | |
6804 | 743 yahoo_packet_hash(pkt, 117, msg2); |
6729 | 744 if (me) |
745 yahoo_packet_hash(pkt, 124, "2"); | |
746 else | |
747 yahoo_packet_hash(pkt, 124, "1"); | |
748 /* fixme: what about /think? (124=3) */ | |
749 | |
750 yahoo_send_packet(yd, pkt); | |
751 yahoo_packet_free(pkt); | |
6804 | 752 g_free(msg2); |
6729 | 753 |
754 return 0; | |
755 } | |
756 | |
757 static void yahoo_chat_join(struct yahoo_data *yd, const char *dn, const char *room, const char *topic) | |
758 { | |
759 struct yahoo_packet *pkt; | |
760 | |
761 pkt = yahoo_packet_new(YAHOO_SERVICE_CHATJOIN, YAHOO_STATUS_AVAILABLE, 0); | |
762 | |
763 yahoo_packet_hash(pkt, 62, "2"); | |
764 yahoo_packet_hash(pkt, 104, room); | |
765 yahoo_packet_hash(pkt, 129, "0"); | |
766 | |
767 yahoo_send_packet(yd, pkt); | |
768 | |
769 yahoo_packet_free(pkt); | |
770 } | |
771 | |
772 static void yahoo_chat_invite(struct yahoo_data *yd, const char *dn, const char *buddy, | |
773 const char *room, const char *msg) | |
774 { | |
775 struct yahoo_packet *pkt; | |
776 | |
777 pkt = yahoo_packet_new(YAHOO_SERVICE_CHATADDINVITE, YAHOO_STATUS_AVAILABLE, 0); | |
778 | |
779 yahoo_packet_hash(pkt, 1, dn); | |
780 yahoo_packet_hash(pkt, 118, buddy); | |
781 yahoo_packet_hash(pkt, 104, room); | |
782 yahoo_packet_hash(pkt, 117, (msg?msg:"")); | |
783 yahoo_packet_hash(pkt, 129, "0"); | |
784 | |
785 yahoo_send_packet(yd, pkt); | |
786 yahoo_packet_free(pkt); | |
787 } | |
788 | |
789 void yahoo_chat_goto(GaimConnection *gc, const char *name) | |
790 { | |
791 struct yahoo_data *yd; | |
792 struct yahoo_packet *pkt; | |
793 | |
794 yd = gc->proto_data; | |
795 | |
796 if (!yd->chat_online) | |
797 yahoo_chat_online(gc); | |
798 | |
799 pkt = yahoo_packet_new(YAHOO_SERVICE_CHATGOTO, YAHOO_STATUS_AVAILABLE, 0); | |
800 | |
801 yahoo_packet_hash(pkt, 109, name); | |
802 yahoo_packet_hash(pkt, 1, gaim_connection_get_display_name(gc)); | |
803 yahoo_packet_hash(pkt, 62, "2"); | |
804 | |
805 yahoo_send_packet(yd, pkt); | |
806 yahoo_packet_free(pkt); | |
807 } | |
808 /* | |
809 * These are the functions registered with the core | |
810 * which get called for both chats and conferences. | |
811 */ | |
812 | |
813 void yahoo_c_leave(GaimConnection *gc, int id) | |
814 { | |
815 struct yahoo_data *yd = (struct yahoo_data *) gc->proto_data; | |
816 GaimConversation *c; | |
817 | |
818 if (!yd) | |
819 return; | |
820 | |
821 | |
822 c = gaim_find_chat(gc, id); | |
823 if (!c) | |
824 return; | |
825 | |
826 if (id != YAHOO_CHAT_ID) { | |
827 yahoo_conf_leave(yd, gaim_conversation_get_name(c), | |
7118
bf630f7dfdcd
[gaim-migrate @ 7685]
Christian Hammond <chipx86@chipx86.com>
parents:
6804
diff
changeset
|
828 gaim_connection_get_display_name(gc), gaim_conv_chat_get_users(GAIM_CONV_CHAT(c))); |
6729 | 829 yd->confs = g_slist_remove(yd->confs, c); |
830 } else { | |
7186 | 831 yahoo_chat_leave(gc, gaim_conversation_get_name(c), gaim_connection_get_display_name(gc), TRUE); |
6729 | 832 } |
833 | |
834 serv_got_chat_left(gc, id); | |
835 } | |
836 | |
837 int yahoo_c_send(GaimConnection *gc, int id, const char *what) | |
838 { | |
839 GaimConversation *c; | |
840 int ret; | |
841 struct yahoo_data *yd; | |
842 | |
843 yd = (struct yahoo_data *) gc->proto_data; | |
844 if (!yd) | |
845 return -1; | |
846 | |
847 c = gaim_find_chat(gc, id); | |
848 if (!c) | |
849 return -1; | |
850 | |
851 if (id != YAHOO_CHAT_ID) { | |
852 ret = yahoo_conf_send(yd, gaim_connection_get_display_name(gc), | |
7118
bf630f7dfdcd
[gaim-migrate @ 7685]
Christian Hammond <chipx86@chipx86.com>
parents:
6804
diff
changeset
|
853 gaim_conversation_get_name(c), gaim_conv_chat_get_users(GAIM_CONV_CHAT(c)), what); |
6729 | 854 } else { |
855 ret = yahoo_chat_send(yd, gaim_connection_get_display_name(gc), | |
6804 | 856 gaim_conversation_get_name(c), what); |
6729 | 857 if (!ret) |
7118
bf630f7dfdcd
[gaim-migrate @ 7685]
Christian Hammond <chipx86@chipx86.com>
parents:
6804
diff
changeset
|
858 serv_got_chat_in(gc, gaim_conv_chat_get_id(GAIM_CONV_CHAT(c)), |
6729 | 859 gaim_connection_get_display_name(gc), 0, what, time(NULL)); |
860 } | |
861 return ret; | |
862 } | |
863 | |
864 GList *yahoo_c_info(GaimConnection *gc) | |
865 { | |
866 GList *m = NULL; | |
867 struct proto_chat_entry *pce; | |
868 | |
869 pce = g_new0(struct proto_chat_entry, 1); | |
870 pce->label = _("Room:"); | |
871 pce->identifier = "room"; | |
872 m = g_list_append(m, pce); | |
873 | |
874 return m; | |
875 } | |
876 | |
877 void yahoo_c_join(GaimConnection *gc, GHashTable *data) | |
878 { | |
879 struct yahoo_data *yd; | |
880 char *room, *topic, *members, *type; | |
881 int id; | |
882 GaimConversation *c; | |
883 | |
884 yd = (struct yahoo_data *) gc->proto_data; | |
885 if (!yd) | |
886 return; | |
887 | |
888 room = g_hash_table_lookup(data, "room"); | |
889 if (!room) | |
890 return; | |
891 | |
892 topic = g_hash_table_lookup(data, "topic"); | |
893 if (!topic) | |
894 topic = ""; | |
895 | |
896 members = g_hash_table_lookup(data, "members"); | |
897 | |
898 | |
899 if ((type = g_hash_table_lookup(data, "type")) && !strcmp(type, "Conference")) { | |
900 id = yd->conf_id++; | |
901 c = serv_got_joined_chat(gc, id, room); | |
902 yd->confs = g_slist_prepend(yd->confs, c); | |
7118
bf630f7dfdcd
[gaim-migrate @ 7685]
Christian Hammond <chipx86@chipx86.com>
parents:
6804
diff
changeset
|
903 gaim_conv_chat_set_topic(GAIM_CONV_CHAT(c), gaim_connection_get_display_name(gc), topic); |
6729 | 904 yahoo_conf_join(yd, c, gaim_connection_get_display_name(gc), room, topic, members); |
905 return; | |
906 } else { | |
907 if (yd->in_chat) | |
7186 | 908 yahoo_chat_leave(gc, room, |
909 gaim_connection_get_display_name(gc), | |
910 FALSE); | |
6729 | 911 if (!yd->chat_online) |
912 yahoo_chat_online(gc); | |
913 yahoo_chat_join(yd, gaim_connection_get_display_name(gc), room, topic); | |
914 return; | |
915 } | |
916 } | |
917 | |
918 void yahoo_c_invite(GaimConnection *gc, int id, const char *msg, const char *name) | |
919 { | |
920 struct yahoo_data *yd = (struct yahoo_data *) gc->proto_data; | |
921 GaimConversation *c; | |
922 | |
923 c = gaim_find_chat(gc, id); | |
924 if (!c || !c->name) | |
925 return; | |
926 | |
927 if (id != YAHOO_CHAT_ID) { | |
928 yahoo_conf_invite(yd, c, gaim_connection_get_display_name(gc), name, | |
929 gaim_conversation_get_name(c), msg); | |
930 } else { | |
931 yahoo_chat_invite(yd, gaim_connection_get_display_name(gc), name, | |
932 gaim_conversation_get_name(c), msg); | |
933 } | |
934 } | |
935 |