首页 | 数据结构 | 文件列表 | 数据字段 | 全局定义

group_join.c

浏览该文件的文档。
00001 
00023 // START OF FILE
00024 /*****************************************************************************/
00025 #include "debug.h"              // gaim_debug
00026 #include "notify.h"             // gaim_notify_xxx
00027 #include "request.h"            // gaim_request_input
00028 #include "server.h"             // serv_got_joined_chat
00029 
00030 #include "buddy_opt.h"          // gc_and_uid
00031 #include "char_conv.h"          // QQ_CHARSET_DEFAULT
00032 #include "group_conv.h"         // qq_group_conv_show_window
00033 #include "group_find.h"         // qq_group_find_by_internal_group_id
00034 #include "group_free.h"         // qq_group_remove_by_internal_group_id
00035 #include "group_hash.h"         // qq_group_refresh
00036 #include "group_info.h"         // qq_send_cmd_group_get_group_info
00037 #include "group_join.h"
00038 #include "group_opt.h"          // qq_send_cmd_group_auth
00039 #include "group_network.h"      // qq_send_group_cmd
00040 
00041 enum {
00042         QQ_GROUP_JOIN_OK = 0x01,
00043         QQ_GROUP_JOIN_NEED_AUTH = 0x02,
00044 };
00045 
00046 /*****************************************************************************/
00047 void _qq_group_exit_with_gc_and_id(gc_and_uid * g)
00048 {
00049         GaimConnection *gc;
00050         guint32 internal_group_id;
00051         qq_group *group;
00052 
00053         g_return_if_fail(g != NULL && g->gc != NULL && g->uid > 0);
00054         gc = g->gc;
00055         internal_group_id = g->uid;
00056 
00057         group = qq_group_find_by_internal_group_id(gc, internal_group_id);
00058         g_return_if_fail(group != NULL);
00059 
00060         qq_send_cmd_group_exit_group(gc, group);
00061 }                               // _qq_group_exist_with_gc_and_id
00062 
00063 /*****************************************************************************/
00064 // send packet to join a group without auth
00065 void _qq_send_cmd_group_join_group(GaimConnection * gc, qq_group * group)
00066 {
00067         guint8 *raw_data, *cursor;
00068         gint bytes, data_len;
00069 
00070         g_return_if_fail(gc != NULL && group != NULL);
00071         if (group->my_status == QQ_GROUP_MEMBER_STATUS_NOT_MEMBER) {
00072                 group->my_status = QQ_GROUP_MEMBER_STATUS_APPLYING;
00073                 qq_group_refresh(gc, group);
00074         }                       // if group->my_status
00075 
00076         data_len = 5;
00077         raw_data = g_newa(guint8, data_len);
00078         cursor = raw_data;
00079 
00080         bytes = 0;
00081         bytes += create_packet_b(raw_data, &cursor, QQ_GROUP_CMD_JOIN_GROUP);
00082         bytes += create_packet_dw(raw_data, &cursor, group->internal_group_id);
00083 
00084         if (bytes != data_len)
00085                 gaim_debug(GAIM_DEBUG_ERROR, "QQ",
00086                            "Fail create packet for %s\n", qq_group_cmd_get_desc(QQ_GROUP_CMD_JOIN_GROUP));
00087         else
00088                 qq_send_group_cmd(gc, group, raw_data, data_len);
00089 }                               // _qq_send_cmd_group_join_group
00090 
00091 /*****************************************************************************/
00092 void _qq_group_join_auth_with_gc_and_id(gc_and_uid * g, const gchar * reason_utf8)
00093 {
00094         GaimConnection *gc;
00095         qq_group *group;
00096         guint32 internal_group_id;
00097 
00098         g_return_if_fail(g != NULL && g->gc != NULL && g->uid > 0);
00099         gc = g->gc;
00100         internal_group_id = g->uid;
00101 
00102         group = qq_group_find_by_internal_group_id(gc, internal_group_id);
00103         if (group == NULL) {
00104                 gaim_debug(GAIM_DEBUG_ERROR, "QQ", "Can not find qq_group by internal_id: %d\n", internal_group_id);
00105                 return;
00106         } else                  // everything is OK
00107                 qq_send_cmd_group_auth(gc, group, QQ_GROUP_AUTH_REQUEST_APPLY, 0, reason_utf8);
00108 
00109 }                               // _qq_group_join_auth_with_gc_and_id
00110 
00111 /*****************************************************************************/
00112 void _qq_group_join_auth(GaimConnection * gc, qq_group * group)
00113 {
00114         gchar *msg;
00115         gc_and_uid *g;
00116         g_return_if_fail(gc != NULL && group != NULL);
00117 
00118         gaim_debug(GAIM_DEBUG_INFO, "QQ", "Group (internal id: %d) needs authentication\n", group->internal_group_id);
00119 
00120         msg = g_strdup_printf("Group \"%s\" needs authentication\n", group->group_name_utf8);
00121         g = g_new0(gc_and_uid, 1);
00122         g->gc = gc;
00123         g->uid = group->internal_group_id;
00124         gaim_request_input(gc, NULL, msg,
00125                            _("Input request here"),
00126                            _("Would you be my friend?"), TRUE, FALSE, NULL,
00127                            _("Send"),
00128                            G_CALLBACK(_qq_group_join_auth_with_gc_and_id),
00129                            _("Cancel"), G_CALLBACK(qq_do_nothing_with_gc_and_uid), g);
00130         g_free(msg);
00131 }                               // _qq_group_join_auth
00132 
00133 /*****************************************************************************/
00134 unsigned  char unknown32[32] = {0x68, 0x12, 0x8c, 0xf1, 0x95, 0xdd, 0xbb, 0x47,
00135                       0xf6, 0xb1, 0xb0, 0xf6, 0x86, 0xd7, 0x26, 0x6d,
00136                       0x47, 0xe9, 0x22, 0x57, 0xc2, 0xde, 0x68, 0xa5,
00137                       0xd7, 0x0b, 0x3b, 0xa8, 0x90, 0x2c, 0xca, 0x1c
00138         };
00139 void qq_send_cmd_group_auth(GaimConnection * gc, qq_group * group, guint8 opt, guint32 uid, const gchar * reason_utf8) {
00140         guint8 *raw_data, *cursor;
00141         gchar *reason_qq;
00142         gint bytes, data_len;
00143 
00144         g_return_if_fail(gc != NULL && group != NULL);
00145 
00146         if (reason_utf8 == NULL || strlen(reason_utf8) == 0)
00147                 reason_qq = g_strdup("");
00148         else
00149                 reason_qq = utf8_to_qq(reason_utf8, QQ_CHARSET_DEFAULT);
00150 
00151         if (opt == QQ_GROUP_AUTH_REQUEST_APPLY) {
00152                 group->my_status = QQ_GROUP_MEMBER_STATUS_APPLYING;
00153                 qq_group_refresh(gc, group);
00154                 uid = 0;
00155         }                       // if (opt == QQ_GROUP_AUTH_REQUEST_APPLY)
00156 
00157         data_len = 44 + strlen(reason_qq) + 1;
00158         raw_data = g_newa(guint8, data_len);
00159         cursor = raw_data;
00160 
00161         bytes = 0;
00162         bytes += create_packet_b(raw_data, &cursor, QQ_GROUP_CMD_JOIN_GROUP_AUTH);
00163         bytes += create_packet_dw(raw_data, &cursor, group->internal_group_id);
00164         bytes += create_packet_b(raw_data, &cursor, opt);
00165         bytes += create_packet_b(raw_data, &cursor, 0);
00166         bytes += create_packet_b(raw_data, &cursor, 32);
00167         bytes += create_packet_data(raw_data, &cursor, unknown32, 32);
00168         bytes += create_packet_dw(raw_data, &cursor, uid);
00169         bytes += create_packet_b(raw_data, &cursor, strlen(reason_qq));
00170         bytes += create_packet_data(raw_data, &cursor, reason_qq, strlen(reason_qq));
00171 
00172         if (bytes != data_len)
00173                 gaim_debug(GAIM_DEBUG_ERROR, "QQ",
00174                            "Fail create packet for %s\n", qq_group_cmd_get_desc(QQ_GROUP_CMD_JOIN_GROUP_AUTH));
00175         else
00176                 qq_send_group_cmd(gc, group, raw_data, data_len);
00177 }                               // qq_send_packet_group_auth
00178 
00179 /*****************************************************************************/
00180 // send packet to exit one group
00181 // In fact, this will never be used for GAIM
00182 // when we remove a GaimChat node, there is no user controlable callback
00183 // so we only remove the GaimChat node,
00184 // but we never use this cmd to update the server side
00185 // anyway, it is function, as when we remove the GaimChat node,
00186 // user has no way to start up the chat conversation window
00187 // therefore even we are still in it, 
00188 // the group IM will not show up to bother us. (Limited by GAIM)
00189 void qq_send_cmd_group_exit_group(GaimConnection * gc, qq_group * group)
00190 {
00191         guint8 *raw_data, *cursor;
00192         gint bytes, data_len;
00193 
00194         g_return_if_fail(gc != NULL && group != NULL);
00195 
00196         data_len = 5;
00197         raw_data = g_newa(guint8, data_len);
00198         cursor = raw_data;
00199 
00200         bytes = 0;
00201         bytes += create_packet_b(raw_data, &cursor, QQ_GROUP_CMD_EXIT_GROUP);
00202         bytes += create_packet_dw(raw_data, &cursor, group->internal_group_id);
00203 
00204         if (bytes != data_len)
00205                 gaim_debug(GAIM_DEBUG_ERROR, "QQ",
00206                            "Fail create packet for %s\n", qq_group_cmd_get_desc(QQ_GROUP_CMD_EXIT_GROUP));
00207         else
00208                 qq_send_group_cmd(gc, group, raw_data, data_len);
00209 }                               // qq_send_cmd_group_get_group_info
00210 
00211 /*****************************************************************************/
00212 // If comes here, cmd is OK already
00213 void qq_process_group_cmd_exit_group(guint8 * data, guint8 ** cursor, gint len, GaimConnection * gc) {
00214         gint bytes, expected_bytes;
00215         guint32 internal_group_id;
00216         GaimChat *chat;
00217         qq_group *group;
00218         qq_data *qd;
00219 
00220         g_return_if_fail(gc != NULL && gc->proto_data != NULL);
00221         g_return_if_fail(data != NULL && len > 0);
00222         qd = (qq_data *) gc->proto_data;
00223 
00224         bytes = 0;
00225         expected_bytes = 4;
00226         bytes += read_packet_dw(data, cursor, len, &internal_group_id);
00227 
00228         if (bytes == expected_bytes) {
00229                 group = qq_group_find_by_internal_group_id(gc, internal_group_id);
00230                 if (group != NULL) {
00231                         chat =
00232                             gaim_blist_find_chat
00233                             (gaim_connection_get_account(gc), g_strdup_printf("%d", group->external_group_id));
00234                         if (chat != NULL)
00235                                 gaim_blist_remove_chat(chat);
00236                         qq_group_remove_by_internal_group_id(qd, internal_group_id);
00237                 }               // if group
00238                 gaim_notify_info(gc, _("QQ Qun Operation"), _("You have successfully exit group"), NULL);
00239         } else
00240                 gaim_debug(GAIM_DEBUG_ERROR, "QQ",
00241                            "Invalid exit group reply, expect %d bytes, read %d bytes\n", expected_bytes, bytes);
00242 
00243 }                               // qq_process_group_cmd_exit_group
00244 
00245 /*****************************************************************************/
00246 // Process the reply to group_auth subcmd
00247 void qq_process_group_cmd_join_group_auth(guint8 * data, guint8 ** cursor, gint len, GaimConnection * gc) {
00248         gint bytes, expected_bytes;
00249         guint32 internal_group_id;
00250         qq_data *qd;
00251 
00252         g_return_if_fail(gc != NULL && gc->proto_data != NULL);
00253         g_return_if_fail(data != NULL && len > 0);
00254         qd = (qq_data *) gc->proto_data;
00255 
00256         bytes = 0;
00257         expected_bytes = 4;
00258         bytes += read_packet_dw(data, cursor, len, &internal_group_id);
00259         g_return_if_fail(internal_group_id > 0);
00260 
00261         if (bytes == expected_bytes)
00262                 gaim_notify_info
00263                     (gc, _("QQ Group Auth"), _("You authorization operation has been accepted by QQ server"), NULL);
00264         else
00265                 gaim_debug(GAIM_DEBUG_ERROR, "QQ",
00266                            "Invalid join group reply, expect %d bytes, read %d bytes\n", expected_bytes, bytes);
00267 
00268 }                               // qq_process_group_cmd_group_auth
00269 
00270 /*****************************************************************************/
00271 // process group cmd reply "join group"
00272 void qq_process_group_cmd_join_group(guint8 * data, guint8 ** cursor, gint len, GaimConnection * gc) {
00273         gint bytes, expected_bytes;
00274         guint32 internal_group_id;
00275         guint8 reply;
00276         qq_group *group;
00277 
00278         g_return_if_fail(gc != NULL && data != NULL && len > 0);
00279 
00280         bytes = 0;
00281         expected_bytes = 5;
00282         bytes += read_packet_dw(data, cursor, len, &internal_group_id);
00283         bytes += read_packet_b(data, cursor, len, &reply);
00284 
00285         if (bytes != expected_bytes) {
00286                 gaim_debug(GAIM_DEBUG_ERROR, "QQ",
00287                            "Invalid join group reply, expect %d bytes, read %d bytes\n", expected_bytes, bytes);
00288                 return;
00289         } else {                // join group OK
00290                 group = qq_group_find_by_internal_group_id(gc, internal_group_id);
00291                 // need to check if group is NULL or not.
00292                 g_return_if_fail(group != NULL);
00293                 switch (reply) {
00294                 case QQ_GROUP_JOIN_OK:
00295                         gaim_debug(GAIM_DEBUG_INFO, "QQ", "Succeed joining group \"%s\"\n", group->group_name_utf8);
00296                         group->my_status = QQ_GROUP_MEMBER_STATUS_IS_MEMBER;
00297                         qq_group_refresh(gc, group);
00298                         // this must be show before getting online member
00299                         qq_group_conv_show_window(gc, group);
00300                         qq_send_cmd_group_get_group_info(gc, group);
00301                         break;
00302                 case QQ_GROUP_JOIN_NEED_AUTH:
00303                         gaim_debug(GAIM_DEBUG_INFO, "QQ",
00304                                    "Fail joining group [%d] %s, needs authentication\n",
00305                                    group->external_group_id, group->group_name_utf8);
00306                         group->my_status = QQ_GROUP_MEMBER_STATUS_NOT_MEMBER;
00307                         qq_group_refresh(gc, group);
00308                         _qq_group_join_auth(gc, group);
00309                         break;
00310                 default:
00311                         gaim_debug(GAIM_DEBUG_INFO, "QQ",
00312                                    "Error joining group [%d] %s, unknown reply: 0x%02x\n",
00313                                    group->external_group_id, group->group_name_utf8, reply);
00314                 }               // switch reply
00315         }                       // if bytes != expected_bytes
00316 }                               // qq_process_group_cmd_join_group
00317 
00318 /*****************************************************************************/
00319 // Apply to join one group without auth
00320 void qq_group_join(GaimConnection * gc, GHashTable * data)
00321 {
00322         gchar *internal_group_id_ptr;
00323         guint32 internal_group_id;
00324         qq_group *group;
00325 
00326         g_return_if_fail(gc != NULL && data != NULL);
00327 
00328         internal_group_id_ptr = g_hash_table_lookup(data, "internal_group_id");
00329         internal_group_id = strtol(internal_group_id_ptr, NULL, 10);
00330 
00331         g_return_if_fail(internal_group_id > 0);
00332 
00333         // for those we have subscribed, they should have been put into
00334         // qd->groups in qq_group_init subroutine
00335         group = qq_group_find_by_internal_group_id(gc, internal_group_id);
00336         if (group == NULL)
00337                 group = qq_group_from_hashtable(gc, data);
00338 
00339         g_return_if_fail(group != NULL);
00340 
00341         switch (group->auth_type) {
00342         case QQ_GROUP_AUTH_TYPE_NO_AUTH:
00343         case QQ_GROUP_AUTH_TYPE_NEED_AUTH:
00344                 _qq_send_cmd_group_join_group(gc, group);
00345                 break;
00346         case QQ_GROUP_AUTH_TYPE_NO_ADD:
00347                 gaim_notify_warning(gc, NULL, _("This group does not allow others to join"), NULL);
00348                 break;
00349         default:
00350                 gaim_debug(GAIM_DEBUG_ERROR, "QQ", "Unknown group auth type: %d\n", group->auth_type);
00351         }                       // switch auth_type
00352 }                               // qq_group_join
00353 
00354 /*****************************************************************************/
00355 void qq_group_exit(GaimConnection * gc, GHashTable * data)
00356 {
00357         gchar *internal_group_id_ptr;
00358         guint32 internal_group_id;
00359         gc_and_uid *g;
00360 
00361         g_return_if_fail(gc != NULL && data != NULL);
00362 
00363         internal_group_id_ptr = g_hash_table_lookup(data, "internal_group_id");
00364         internal_group_id = strtol(internal_group_id_ptr, NULL, 10);
00365 
00366         g_return_if_fail(internal_group_id > 0);
00367 
00368         g = g_new0(gc_and_uid, 1);
00369         g->gc = gc;
00370         g->uid = internal_group_id;
00371 
00372         gaim_request_action(gc, _("QQ Qun Operation"),
00373                             _("Are you sure to exit this Qun?"),
00374                             _
00375                             ("Note, if you are the creator, \nthis operation will eventually remove this Qun."),
00376                             1, g, 2, _("Cancel"),
00377                             G_CALLBACK(qq_do_nothing_with_gc_and_uid),
00378                             _("Go ahead"), G_CALLBACK(_qq_group_exit_with_gc_and_id));
00379 
00380 }                               // qq_group_exit
00381 
00382 /*****************************************************************************/
00383 // END OF FILE

Generated at Mon May 8 15:41:24 2006 for OpenQ by  doxygen 1.4.4