Mercurial > pidgin.yaz
comparison libpurple/protocols/mxit/roster.c @ 28903:69aa4660401a
Initial addition of the MXit protocol plugin, provided by the MXit folks
themselves.
author | John Bailey <rekkanoryo@rekkanoryo.org> |
---|---|
date | Sun, 08 Nov 2009 23:55:56 +0000 |
parents | |
children | 5f80ab7ac183 |
comparison
equal
deleted
inserted
replaced
28901:13e668ef158d | 28903:69aa4660401a |
---|---|
1 /* | |
2 * MXit Protocol libPurple Plugin | |
3 * | |
4 * -- user roster management (mxit contacts) -- | |
5 * | |
6 * Pieter Loubser <libpurple@mxit.com> | |
7 * | |
8 * (C) Copyright 2009 MXit Lifestyle (Pty) Ltd. | |
9 * <http://www.mxitlifestyle.com> | |
10 * | |
11 * This program is free software; you can redistribute it and/or modify | |
12 * it under the terms of the GNU General Public License as published by | |
13 * the Free Software Foundation; either version 2 of the License, or | |
14 * (at your option) any later version. | |
15 * | |
16 * This program is distributed in the hope that it will be useful, | |
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
19 * GNU General Public License for more details. | |
20 * | |
21 * You should have received a copy of the GNU General Public License | |
22 * along with this program; if not, write to the Free Software | |
23 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA | |
24 */ | |
25 | |
26 #include <stdio.h> | |
27 #include <unistd.h> | |
28 #include <string.h> | |
29 | |
30 #include "purple.h" | |
31 | |
32 #include "protocol.h" | |
33 #include "mxit.h" | |
34 #include "roster.h" | |
35 | |
36 | |
37 struct contact_invite { | |
38 struct MXitSession* session; /* MXit session object */ | |
39 struct contact* contact; /* The contact performing the invite */ | |
40 }; | |
41 | |
42 | |
43 /*======================================================================================================================== | |
44 * Presence / Status | |
45 */ | |
46 | |
47 /* statuses (reference: libpurple/status.h) */ | |
48 static struct status | |
49 { | |
50 PurpleStatusPrimitive primative; | |
51 int mxit; | |
52 const char* id; | |
53 const char* name; | |
54 } const mxit_statuses[] = { | |
55 /* primative, no, id, name */ | |
56 { PURPLE_STATUS_OFFLINE, MXIT_PRESENCE_OFFLINE, "offline", "Offline" }, /* 0 */ | |
57 { PURPLE_STATUS_AVAILABLE, MXIT_PRESENCE_ONLINE, "online", "Available" }, /* 1 */ | |
58 { PURPLE_STATUS_AWAY, MXIT_PRESENCE_AWAY, "away", "Away" }, /* 2 */ | |
59 { PURPLE_STATUS_AVAILABLE, MXIT_PRESENCE_AVAILABLE, "chat", "Chatty" }, /* 3 */ | |
60 { PURPLE_STATUS_UNAVAILABLE, MXIT_PRESENCE_DND, "dnd", "Do Not Disturb" } /* 4 */ | |
61 }; | |
62 | |
63 | |
64 /*------------------------------------------------------------------------ | |
65 * Return list of supported statuses. (see status.h) | |
66 * | |
67 * @param account The MXit account object | |
68 * @return List of PurpleStatusType | |
69 */ | |
70 GList* mxit_status_types( PurpleAccount* account ) | |
71 { | |
72 GList* statuslist = NULL; | |
73 PurpleStatusType* type; | |
74 unsigned int i; | |
75 | |
76 for ( i = 0; i < ARRAY_SIZE( mxit_statuses ); i++ ) { | |
77 const struct status* status = &mxit_statuses[i]; | |
78 | |
79 /* add mxit status (reference: "libpurple/status.h") */ | |
80 type = purple_status_type_new_with_attrs( status->primative, status->id, status->name, TRUE, TRUE, FALSE, | |
81 "message", _( "Message" ), purple_value_new( PURPLE_TYPE_STRING ), | |
82 NULL ); | |
83 | |
84 statuslist = g_list_append( statuslist, type ); | |
85 } | |
86 | |
87 return statuslist; | |
88 } | |
89 | |
90 | |
91 /*------------------------------------------------------------------------ | |
92 * Returns the MXit presence code, given the unique status ID. | |
93 * | |
94 * @param id The status ID | |
95 * @return The MXit presence code | |
96 */ | |
97 int mxit_convert_presence( const char* id ) | |
98 { | |
99 unsigned int i; | |
100 | |
101 for ( i = 0; i < ARRAY_SIZE( mxit_statuses ); i++ ) { | |
102 if ( strcmp( mxit_statuses[i].id, id ) == 0 ) /* status found! */ | |
103 return mxit_statuses[i].mxit; | |
104 } | |
105 | |
106 return -1; | |
107 } | |
108 | |
109 | |
110 /*------------------------------------------------------------------------ | |
111 * Returns the MXit presence as a string, given the MXit presence ID. | |
112 * | |
113 * @param no The MXit presence I (see above) | |
114 * @return The presence as a text string | |
115 */ | |
116 const char* mxit_convert_presence_to_name( short no ) | |
117 { | |
118 unsigned int i; | |
119 | |
120 for ( i = 0; i < ARRAY_SIZE( mxit_statuses ); i++ ) { | |
121 if ( mxit_statuses[i].mxit == no ) /* status found! */ | |
122 return _( mxit_statuses[i].name ); | |
123 } | |
124 | |
125 return ""; | |
126 } | |
127 | |
128 | |
129 /*======================================================================================================================== | |
130 * Moods | |
131 */ | |
132 | |
133 /*------------------------------------------------------------------------ | |
134 * Returns the MXit mood as a string, given the MXit mood's ID. | |
135 * | |
136 * @param id The MXit mood ID (see roster.h) | |
137 * @return The mood as a text string | |
138 */ | |
139 const char* mxit_convert_mood_to_name( short id ) | |
140 { | |
141 switch ( id ) { | |
142 case MXIT_MOOD_ANGRY : | |
143 return _( "Angry" ); | |
144 case MXIT_MOOD_EXCITED : | |
145 return _( "Excited" ); | |
146 case MXIT_MOOD_GRUMPY : | |
147 return _( "Grumpy" ); | |
148 case MXIT_MOOD_HAPPY : | |
149 return _( "Happy" ); | |
150 case MXIT_MOOD_INLOVE : | |
151 return _( "In Love" ); | |
152 case MXIT_MOOD_INVINCIBLE : | |
153 return _( "Invincible" ); | |
154 case MXIT_MOOD_SAD : | |
155 return _( "Sad" ); | |
156 case MXIT_MOOD_HOT : | |
157 return _( "Hot" ); | |
158 case MXIT_MOOD_SICK : | |
159 return _( "Sick" ); | |
160 case MXIT_MOOD_SLEEPY : | |
161 return _( "Sleepy" ); | |
162 case MXIT_MOOD_NONE : | |
163 default : | |
164 return ""; | |
165 } | |
166 } | |
167 | |
168 | |
169 /*======================================================================================================================== | |
170 * Subscription Types | |
171 */ | |
172 | |
173 /*------------------------------------------------------------------------ | |
174 * Returns a Contact subscription type as a string. | |
175 * | |
176 * @param subtype The subscription type | |
177 * @return The subscription type as a text string | |
178 */ | |
179 const char* mxit_convert_subtype_to_name( short subtype ) | |
180 { | |
181 switch ( subtype ) { | |
182 case MXIT_SUBTYPE_BOTH : | |
183 return _( "Both" ); | |
184 case MXIT_SUBTYPE_PENDING : | |
185 return _( "Pending" ); | |
186 case MXIT_SUBTYPE_ASK : | |
187 return _( "Invited" ); | |
188 case MXIT_SUBTYPE_REJECTED : | |
189 return _( "Rejected" ); | |
190 case MXIT_SUBTYPE_DELETED : | |
191 return _( "Deleted" ); | |
192 case MXIT_SUBTYPE_NONE : | |
193 return _( "None" ); | |
194 default : | |
195 return ""; | |
196 } | |
197 } | |
198 | |
199 | |
200 /*======================================================================================================================== | |
201 * Calls from the MXit Protocol layer | |
202 */ | |
203 | |
204 #if 0 | |
205 /*------------------------------------------------------------------------ | |
206 * Dump a contact's info the the debug console. | |
207 * | |
208 * @param contact The contact | |
209 */ | |
210 static void dump_contact( struct contact* contact ) | |
211 { | |
212 purple_debug_info( MXIT_PLUGIN_ID, "CONTACT: name='%s', alias='%s', group='%s', type='%i', presence='%i', mood='%i'\n", | |
213 contact->username, contact->alias, contact->groupname, contact->type, contact->presence, contact->mood ); | |
214 } | |
215 #endif | |
216 | |
217 | |
218 #if 0 | |
219 /*------------------------------------------------------------------------ | |
220 * Move a buddy from one group to another | |
221 * | |
222 * @param buddy the buddy to move between groups | |
223 * @param group the new group to move the buddy to | |
224 */ | |
225 static PurpleBuddy* mxit_update_buddy_group( struct MXitSession* session, PurpleBuddy* buddy, PurpleGroup* group ) | |
226 { | |
227 struct contact* contact = NULL; | |
228 PurpleGroup* current_group = purple_buddy_get_group( buddy ); | |
229 PurpleBuddy* newbuddy = NULL; | |
230 | |
231 /* make sure the groups actually differs */ | |
232 if ( strcmp( current_group->name, group->name ) != 0 ) { | |
233 /* groupnames does not match, so we need to make the update */ | |
234 | |
235 purple_debug_info( MXIT_PLUGIN_ID, "Moving '%s' from group '%s' to '%s'\n", buddy->alias, current_group->name, group->name ); | |
236 | |
237 /* | |
238 * XXX: libPurple does not currently provide an API to change or rename the group name | |
239 * for a specific buddy. One option is to remove the buddy from the list and re-adding | |
240 * him in the new group, but by doing that makes the buddy go offline and then online | |
241 * again. This is really not ideal and very iretating, but how else then? | |
242 */ | |
243 | |
244 /* create new buddy */ | |
245 newbuddy = purple_buddy_new( session->acc, buddy->name, buddy->alias ); | |
246 newbuddy->proto_data = buddy->proto_data; | |
247 buddy->proto_data = NULL; | |
248 | |
249 /* remove the buddy */ | |
250 purple_blist_remove_buddy( buddy ); | |
251 | |
252 /* add buddy */ | |
253 purple_blist_add_buddy( newbuddy, NULL, group, NULL ); | |
254 | |
255 /* now re-instate his presence again */ | |
256 contact = newbuddy->proto_data; | |
257 if ( contact ) { | |
258 | |
259 /* update the buddy's status (reference: "libpurple/prpl.h") */ | |
260 if ( contact->statusMsg ) | |
261 purple_prpl_got_user_status( session->acc, newbuddy->name, mxit_statuses[contact->presence].id, "message", contact->statusMsg, NULL ); | |
262 else | |
263 purple_prpl_got_user_status( session->acc, newbuddy->name, mxit_statuses[contact->presence].id, NULL ); | |
264 | |
265 /* update avatar */ | |
266 if ( contact->avatarId ) { | |
267 mxit_get_avatar( session, newbuddy->name, contact->avatarId ); | |
268 g_free( contact->avatarId ); | |
269 contact->avatarId = NULL; | |
270 } | |
271 } | |
272 | |
273 return newbuddy; | |
274 } | |
275 else | |
276 return buddy; | |
277 } | |
278 #endif | |
279 | |
280 | |
281 /*------------------------------------------------------------------------ | |
282 * A contact update packet was received from the MXit server, so update the buddy's | |
283 * information. | |
284 * | |
285 * @param session The MXit session object | |
286 * @param contact The contact | |
287 */ | |
288 void mxit_update_contact( struct MXitSession* session, struct contact* contact ) | |
289 { | |
290 PurpleBuddy* buddy = NULL; | |
291 PurpleGroup* group = NULL; | |
292 const char* id = NULL; | |
293 | |
294 purple_debug_info( MXIT_PLUGIN_ID, "mxit_update_contact: user='%s' alias='%s' group='%s'\n", contact->username, contact->alias, contact->groupname ); | |
295 | |
296 /* | |
297 * libPurple requires all contacts to be in a group. | |
298 * So if this MXit contact isn't in a group, pretend it is. | |
299 */ | |
300 if ( *contact->groupname == '\0' ) { | |
301 strcpy( contact->groupname, MXIT_DEFAULT_GROUP ); | |
302 } | |
303 | |
304 /* find or create a group for this contact */ | |
305 group = purple_find_group( contact->groupname ); | |
306 if ( !group ) | |
307 group = purple_group_new( contact->groupname ); | |
308 | |
309 /* see if the buddy is not in the group already */ | |
310 buddy = purple_find_buddy_in_group( session->acc, contact->username, group ); | |
311 if ( !buddy ) { | |
312 /* buddy not found in the group */ | |
313 | |
314 /* lets try finding him in all groups */ | |
315 buddy = purple_find_buddy( session->acc, contact->username ); | |
316 if ( buddy ) { | |
317 /* ok, so we found him in another group. to switch him between groups we must delete him and add him again. */ | |
318 purple_blist_remove_buddy( buddy ); | |
319 buddy = NULL; | |
320 } | |
321 | |
322 /* create new buddy */ | |
323 buddy = purple_buddy_new( session->acc, contact->username, contact->alias ); | |
324 buddy->proto_data = contact; | |
325 | |
326 /* add new buddy to list */ | |
327 purple_blist_add_buddy( buddy, NULL, group, NULL ); | |
328 } | |
329 else { | |
330 /* buddy was found in the group */ | |
331 | |
332 /* now update the buddy's alias */ | |
333 purple_blist_alias_buddy( buddy, contact->alias ); | |
334 | |
335 /* replace the buddy's contact struct */ | |
336 if ( buddy->proto_data ) | |
337 free( buddy->proto_data ); | |
338 buddy->proto_data = contact; | |
339 } | |
340 | |
341 /* load buddy's avatar id */ | |
342 id = purple_buddy_icons_get_checksum_for_user( buddy ); | |
343 if ( id ) | |
344 contact->avatarId = g_strdup( id ); | |
345 else | |
346 contact->avatarId = NULL; | |
347 | |
348 /* update the buddy's status (reference: "libpurple/prpl.h") */ | |
349 purple_prpl_got_user_status( session->acc, contact->username, mxit_statuses[contact->presence].id, NULL ); | |
350 } | |
351 | |
352 | |
353 /*------------------------------------------------------------------------ | |
354 * A presence update packet was received from the MXit server, so update the buddy's | |
355 * information. | |
356 * | |
357 * @param session The MXit session object | |
358 * @param username The contact which presence to update | |
359 * @param presence The new presence state for the contact | |
360 * @param mood The new mood for the contact | |
361 * @param customMood The custom mood identifier | |
362 * @param statusMsg This is the contact's status message | |
363 * @param avatarId This is the contact's avatar id | |
364 */ | |
365 void mxit_update_buddy_presence( struct MXitSession* session, const char* username, short presence, short mood, const char* customMood, const char* statusMsg, const char* avatarId ) | |
366 { | |
367 PurpleBuddy* buddy = NULL; | |
368 struct contact* contact = NULL; | |
369 | |
370 purple_debug_info( MXIT_PLUGIN_ID, "mxit_update_buddy_presence: user='%s' presence=%i mood=%i customMood='%s' statusMsg='%s' avatar='%s'\n", | |
371 username, presence, mood, customMood, statusMsg, avatarId ); | |
372 | |
373 if ( ( presence < MXIT_PRESENCE_OFFLINE ) || ( presence > MXIT_PRESENCE_DND ) ) { | |
374 purple_debug_info( MXIT_PLUGIN_ID, "mxit_update_buddy_presence: invalid presence state %i\n", presence ); | |
375 return; /* ignore packet */ | |
376 } | |
377 | |
378 /* find the buddy information for this contact (reference: "libpurple/blist.h") */ | |
379 buddy = purple_find_buddy( session->acc, username ); | |
380 if ( !buddy ) { | |
381 purple_debug_warning( MXIT_PLUGIN_ID, "mxit_update_buddy_presence: unable to find the buddy '%s'\n", username ); | |
382 return; | |
383 } | |
384 | |
385 contact = buddy->proto_data; | |
386 if ( !contact ) | |
387 return; | |
388 | |
389 contact->presence = presence; | |
390 contact->mood = mood; | |
391 | |
392 g_strlcpy( contact->customMood, customMood, sizeof( contact->customMood ) ); | |
393 // TODO: Download custom mood frame. | |
394 | |
395 /* update status message */ | |
396 if ( contact->statusMsg ) { | |
397 g_free( contact->statusMsg ); | |
398 contact->statusMsg = NULL; | |
399 } | |
400 if ( statusMsg[0] != '\0' ) | |
401 contact->statusMsg = g_strdup( statusMsg ); | |
402 | |
403 /* update avatarId */ | |
404 if ( ( contact->avatarId ) && ( g_ascii_strcasecmp( contact->avatarId, avatarId ) == 0 ) ) { | |
405 /* avatar has not changed - do nothing */ | |
406 } | |
407 else if ( avatarId[0] != '\0' ) { /* avatar has changed */ | |
408 if ( contact->avatarId ) | |
409 g_free( contact->avatarId ); | |
410 contact->avatarId = g_strdup( avatarId ); | |
411 | |
412 /* Send request to download new avatar image */ | |
413 mxit_get_avatar( session, username, avatarId ); | |
414 } | |
415 else /* clear current avatar */ | |
416 purple_buddy_icons_set_for_user( session->acc, username, NULL, 0, NULL ); | |
417 | |
418 /* update the buddy's status (reference: "libpurple/prpl.h") */ | |
419 if ( contact->statusMsg ) | |
420 purple_prpl_got_user_status( session->acc, username, mxit_statuses[contact->presence].id, "message", contact->statusMsg, NULL ); | |
421 else | |
422 purple_prpl_got_user_status( session->acc, username, mxit_statuses[contact->presence].id, NULL ); | |
423 } | |
424 | |
425 | |
426 /*------------------------------------------------------------------------ | |
427 * update the blist cached by libPurple. We need to do this to keep | |
428 * libPurple and MXit's rosters in sync with each other. | |
429 * | |
430 * @param session The MXit session object | |
431 */ | |
432 void mxit_update_blist( struct MXitSession* session ) | |
433 { | |
434 PurpleBuddy* buddy = NULL; | |
435 GSList* list = NULL; | |
436 unsigned int i; | |
437 | |
438 /* remove all buddies we did not receive a roster update for. | |
439 * these contacts must have been removed from another client */ | |
440 list = purple_find_buddies( session->acc, NULL ); | |
441 | |
442 for ( i = 0; i < g_slist_length( list ); i++ ) { | |
443 buddy = g_slist_nth_data( list, i ); | |
444 | |
445 if ( !buddy->proto_data ) { | |
446 /* this buddy should be removed, because we did not receive him in our roster update from MXit */ | |
447 purple_debug_info( MXIT_PLUGIN_ID, "Removed 'old' buddy from the blist '%s' (%s)\n", buddy->alias, buddy->name ); | |
448 purple_blist_remove_buddy( buddy ); | |
449 } | |
450 } | |
451 | |
452 /* tell the UI to update the blist */ | |
453 purple_blist_add_account( session->acc ); | |
454 } | |
455 | |
456 | |
457 /*------------------------------------------------------------------------ | |
458 * The user authorized an invite (subscription request). | |
459 * | |
460 * @param user_data Object associated with the invite | |
461 */ | |
462 static void mxit_cb_buddy_auth( gpointer user_data ) | |
463 { | |
464 struct contact_invite* invite = (struct contact_invite*) user_data; | |
465 | |
466 purple_debug_info( MXIT_PLUGIN_ID, "mxit_cb_buddy_auth '%s'\n", invite->contact->username ); | |
467 | |
468 /* send a allow subscription packet to MXit */ | |
469 mxit_send_allow_sub( invite->session, invite->contact->username, invite->contact->alias ); | |
470 | |
471 /* freeup invite object */ | |
472 if ( invite->contact->msg ) | |
473 g_free( invite->contact->msg ); | |
474 g_free( invite->contact ); | |
475 g_free( invite ); | |
476 } | |
477 | |
478 | |
479 /*------------------------------------------------------------------------ | |
480 * The user rejected an invite (subscription request). | |
481 * | |
482 * @param user_data Object associated with the invite | |
483 */ | |
484 static void mxit_cb_buddy_deny( gpointer user_data ) | |
485 { | |
486 struct contact_invite* invite = (struct contact_invite*) user_data; | |
487 | |
488 purple_debug_info( MXIT_PLUGIN_ID, "mxit_cb_buddy_deny '%s'\n", invite->contact->username ); | |
489 | |
490 /* send a deny subscription packet to MXit */ | |
491 mxit_send_deny_sub( invite->session, invite->contact->username ); | |
492 | |
493 /* freeup invite object */ | |
494 if ( invite->contact->msg ) | |
495 g_free( invite->contact->msg ); | |
496 g_free( invite->contact ); | |
497 g_free( invite ); | |
498 } | |
499 | |
500 | |
501 /*------------------------------------------------------------------------ | |
502 * A new subscription request packet was received from the MXit server. | |
503 * Prompt user to accept or reject it. | |
504 * | |
505 * @param session The MXit session object | |
506 * @param contact The contact performing the invite | |
507 */ | |
508 void mxit_new_subscription( struct MXitSession* session, struct contact* contact ) | |
509 { | |
510 struct contact_invite* invite; | |
511 | |
512 purple_debug_info( MXIT_PLUGIN_ID, "mxit_new_subscription from '%s' (%s)\n", contact->username, contact->alias ); | |
513 | |
514 invite = g_new0( struct contact_invite, 1 ); | |
515 invite->session = session; | |
516 invite->contact = contact; | |
517 | |
518 /* (reference: "libpurple/account.h") */ | |
519 purple_account_request_authorization( session->acc, contact->username, NULL, contact->alias, contact->msg, FALSE, mxit_cb_buddy_auth, mxit_cb_buddy_deny, invite ); | |
520 } | |
521 | |
522 | |
523 /*------------------------------------------------------------------------ | |
524 * Return TRUE if this is a MXit Chatroom contact. | |
525 * | |
526 * @param session The MXit session object | |
527 * @param username The username of the contact | |
528 */ | |
529 gboolean is_mxit_chatroom_contact( struct MXitSession* session, const char* username ) | |
530 { | |
531 PurpleBuddy* buddy; | |
532 struct contact* contact = NULL; | |
533 | |
534 /* find the buddy */ | |
535 buddy = purple_find_buddy( session->acc, username ); | |
536 if ( !buddy ) { | |
537 purple_debug_warning( MXIT_PLUGIN_ID, "is_mxit_chatroom_contact: unable to find the buddy '%s'\n", username ); | |
538 return FALSE; | |
539 } | |
540 | |
541 contact = buddy->proto_data; | |
542 if ( !contact ) | |
543 return FALSE; | |
544 | |
545 return ( contact->type == MXIT_TYPE_CHATROOM ); | |
546 } | |
547 | |
548 | |
549 /*======================================================================================================================== | |
550 * Callbacks from libpurple | |
551 */ | |
552 | |
553 /*------------------------------------------------------------------------ | |
554 * The user has added a buddy to the list, so send an invite request. | |
555 * | |
556 * @param gc The connection object | |
557 * @param buddy The new buddy | |
558 * @param group The group of the new buddy | |
559 */ | |
560 void mxit_add_buddy( PurpleConnection* gc, PurpleBuddy* buddy, PurpleGroup* group ) | |
561 { | |
562 struct MXitSession* session = (struct MXitSession*) gc->proto_data; | |
563 GSList* list = NULL; | |
564 PurpleBuddy* mxbuddy = NULL; | |
565 unsigned int i; | |
566 | |
567 purple_debug_info( MXIT_PLUGIN_ID, "mxit_add_buddy '%s' (group='%s')\n", buddy->name, group->name ); | |
568 | |
569 list = purple_find_buddies( session->acc, buddy->name ); | |
570 if ( g_slist_length( list ) == 1 ) { | |
571 purple_debug_info( MXIT_PLUGIN_ID, "mxit_add_buddy (scenario 1) (list:%i)\n", g_slist_length( list ) ); | |
572 /* | |
573 * we only send an invite to MXit when the user is not already inside our | |
574 * blist. this is done because purple does an add_buddy() call when | |
575 * you accept an invite. so in that case the user is already | |
576 * in our blist and ready to be chatted to. | |
577 */ | |
578 mxit_send_invite( session, buddy->name, buddy->alias, group->name ); | |
579 } | |
580 else { | |
581 purple_debug_info( MXIT_PLUGIN_ID, "mxit_add_buddy (scenario 2) (list:%i)\n", g_slist_length( list ) ); | |
582 /* | |
583 * we already have the buddy in our list, so we will only update | |
584 * his information here and not send another invite message | |
585 */ | |
586 | |
587 /* find the correct buddy */ | |
588 for ( i = 0; i < g_slist_length( list ); i++ ) { | |
589 mxbuddy = g_slist_nth_data( list, i ); | |
590 | |
591 if ( mxbuddy->proto_data != NULL ) { | |
592 /* this is our REAL MXit buddy! */ | |
593 | |
594 /* now update the buddy's alias */ | |
595 purple_blist_alias_buddy( mxbuddy, buddy->alias ); | |
596 | |
597 /* now update the buddy's group */ | |
598 // mxbuddy = mxit_update_buddy_group( session, mxbuddy, group ); | |
599 | |
600 /* send the update to the MXit server */ | |
601 mxit_send_update_contact( session, mxbuddy->name, mxbuddy->alias, group->name ); | |
602 } | |
603 } | |
604 } | |
605 | |
606 /* | |
607 * we remove the buddy here from the buddy list because the MXit server | |
608 * will send us a proper contact update packet if this succeeds. now | |
609 * we do not have to worry about error handling in case of adding an | |
610 * invalid contact. so the user will still see the contact as offline | |
611 * until he eventually accepts the invite. | |
612 */ | |
613 purple_blist_remove_buddy( buddy ); | |
614 | |
615 g_slist_free( list ); | |
616 } | |
617 | |
618 | |
619 /*------------------------------------------------------------------------ | |
620 * The user has removed a buddy from the list. | |
621 * | |
622 * @param gc The connection object | |
623 * @param buddy The buddy being removed | |
624 * @param group The group the buddy was in | |
625 */ | |
626 void mxit_remove_buddy( PurpleConnection* gc, PurpleBuddy* buddy, PurpleGroup* group ) | |
627 { | |
628 struct MXitSession* session = (struct MXitSession*) gc->proto_data; | |
629 | |
630 purple_debug_info( MXIT_PLUGIN_ID, "mxit_remove_buddy '%s'\n", buddy->name ); | |
631 | |
632 mxit_send_remove( session, buddy->name ); | |
633 } | |
634 | |
635 | |
636 /*------------------------------------------------------------------------ | |
637 * The user changed the buddy's alias. | |
638 * | |
639 * @param gc The connection object | |
640 * @param who The username of the buddy | |
641 * @param alias The new alias | |
642 */ | |
643 void mxit_buddy_alias( PurpleConnection* gc, const char* who, const char* alias ) | |
644 { | |
645 struct MXitSession* session = (struct MXitSession*) gc->proto_data; | |
646 PurpleBuddy* buddy = NULL; | |
647 PurpleGroup* group = NULL; | |
648 | |
649 purple_debug_info( MXIT_PLUGIN_ID, "mxit_buddy_alias '%s' to '%s\n", who, alias ); | |
650 | |
651 /* find the buddy */ | |
652 buddy = purple_find_buddy( session->acc, who ); | |
653 if ( !buddy ) { | |
654 purple_debug_warning( MXIT_PLUGIN_ID, "mxit_buddy_alias: unable to find the buddy '%s'\n", who ); | |
655 return; | |
656 } | |
657 | |
658 /* find buddy group */ | |
659 group = purple_buddy_get_group( buddy ); | |
660 if ( !group ) { | |
661 purple_debug_warning( MXIT_PLUGIN_ID, "mxit_buddy_alias: unable to find the group for buddy '%s'\n", who ); | |
662 return; | |
663 } | |
664 | |
665 mxit_send_update_contact( session, who, alias, group->name ); | |
666 } | |
667 | |
668 | |
669 /*------------------------------------------------------------------------ | |
670 * The user changed the group for a single buddy. | |
671 * | |
672 * @param gc The connection object | |
673 * @param who The username of the buddy | |
674 * @param old_group The old group's name | |
675 * @param new_group The new group's name | |
676 */ | |
677 void mxit_buddy_group( PurpleConnection* gc, const char* who, const char* old_group, const char* new_group ) | |
678 { | |
679 struct MXitSession* session = (struct MXitSession*) gc->proto_data; | |
680 PurpleBuddy* buddy = NULL; | |
681 | |
682 purple_debug_info( MXIT_PLUGIN_ID, "mxit_buddy_group from '%s' to '%s'\n", old_group, new_group ); | |
683 | |
684 /* find the buddy */ | |
685 buddy = purple_find_buddy( session->acc, who ); | |
686 if ( !buddy ) { | |
687 purple_debug_warning( MXIT_PLUGIN_ID, "mxit_buddy_group: unable to find the buddy '%s'\n", who ); | |
688 return; | |
689 } | |
690 | |
691 mxit_send_update_contact( session, who, buddy->alias, new_group ); | |
692 } | |
693 | |
694 | |
695 /*------------------------------------------------------------------------ | |
696 * The user has selected to rename a group, so update all contacts in that | |
697 * group. | |
698 * | |
699 * @param gc The connection object | |
700 * @param old_name The old group name | |
701 * @param group The updated group object | |
702 * @param moved_buddies The buddies affected by the rename | |
703 */ | |
704 void mxit_rename_group( PurpleConnection* gc, const char* old_name, PurpleGroup* group, GList* moved_buddies ) | |
705 { | |
706 struct MXitSession* session = (struct MXitSession*) gc->proto_data; | |
707 PurpleBuddy* buddy = NULL; | |
708 GList* item = NULL; | |
709 | |
710 purple_debug_info( MXIT_PLUGIN_ID, "mxit_rename_group from '%s' to '%s\n", old_name, group->name ); | |
711 | |
712 // TODO: Might be more efficient to use the "rename group" command (cmd=29). | |
713 | |
714 /* loop through all the contacts in the group and send updates */ | |
715 item = moved_buddies; | |
716 while ( item ) { | |
717 buddy = item->data; | |
718 mxit_send_update_contact( session, buddy->name, buddy->alias, group->name ); | |
719 item = g_list_next( item ); | |
720 } | |
721 } | |
722 |