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