diff libpurple/protocols/qq/group_join.c @ 24157:1ee91ff0d5fe

2008.10.09 - ccpaging <ccpaging(at)gmail.com> * Update 'group' protocol * Functions of group_find, group_free, group_search merged into group_join and group_internal * Removed group_find.c/h, group_free.c/h, group_search.c/h
author SHiNE CsyFeK <csyfek@gmail.com>
date Tue, 28 Oct 2008 16:38:16 +0000
parents 3c52353b83ae
children 9be95f0b9472
line wrap: on
line diff
--- a/libpurple/protocols/qq/group_join.c	Tue Oct 28 16:35:06 2008 +0000
+++ b/libpurple/protocols/qq/group_join.c	Tue Oct 28 16:38:16 2008 +0000
@@ -31,12 +31,10 @@
 
 #include "char_conv.h"
 #include "im.h"
-#include "group_find.h"
 #include "group_internal.h"
 #include "group_info.h"
 #include "group_join.h"
 #include "group_opt.h"
-#include "group_search.h"
 #include "group_im.h"
 #include "qq_define.h"
 #include "packet_parse.h"
@@ -49,11 +47,16 @@
 	QQ_ROOM_JOIN_DENIED = 0x03,
 };
 
+enum {
+	QQ_ROOM_SEARCH_TYPE_BY_ID = 0x01,
+	QQ_ROOM_SEARCH_TYPE_DEMO = 0x02
+};
+
 static void group_quit_cb(qq_add_request *add_req)
 {
 	PurpleConnection *gc;
 	guint32 id;
-	qq_group *group;
+	qq_room_data *rmd;
 
 	if (add_req->gc == NULL || add_req->uid == 0) {
 		g_free(add_req);
@@ -63,48 +66,47 @@
 	gc = add_req->gc;
 	id = add_req->uid;
 
-	group = qq_room_search_id(gc, id);
-	if (group == NULL) {
+	rmd = qq_room_data_find(gc, id);
+	if (rmd == NULL) {
 		g_free(add_req);
 		return;
 	}
 
-	qq_send_room_cmd_only(gc, QQ_ROOM_CMD_QUIT, group->id);
+	qq_send_room_cmd_only(gc, QQ_ROOM_CMD_QUIT, rmd->id);
 	g_free(add_req);
 }
 
 /* send packet to join a group without auth */
-void qq_request_room_join(PurpleConnection *gc, qq_group *group)
+void qq_request_room_join(PurpleConnection *gc, qq_room_data *rmd)
 {
-	g_return_if_fail(group != NULL);
+	g_return_if_fail(rmd != NULL);
 
-	if (group->my_role == QQ_ROOM_ROLE_NO) {
-		group->my_role = QQ_ROOM_ROLE_REQUESTING;
-		qq_group_refresh(gc, group);
+	if (rmd->my_role == QQ_ROOM_ROLE_NO) {
+		rmd->my_role = QQ_ROOM_ROLE_REQUESTING;
 	}
 
-	switch (group->auth_type) {
+	switch (rmd->auth_type) {
 	case QQ_ROOM_AUTH_TYPE_NO_AUTH:
 	case QQ_ROOM_AUTH_TYPE_NEED_AUTH:
 		break;
 	case QQ_ROOM_AUTH_TYPE_NO_ADD:
-		if (group->my_role == QQ_ROOM_ROLE_NO
-				&& group->my_role == QQ_ROOM_ROLE_REQUESTING) {
+		if (rmd->my_role == QQ_ROOM_ROLE_NO
+				&& rmd->my_role == QQ_ROOM_ROLE_REQUESTING) {
 			purple_notify_warning(gc, NULL, _("The Qun does not allow others to join"), NULL);
 			return;
 		}
 		break;
 	default:
-		purple_debug_error("QQ", "Unknown room auth type: %d\n", group->auth_type);
+		purple_debug_error("QQ", "Unknown room auth type: %d\n", rmd->auth_type);
 		break;
 	}
 
-	qq_send_room_cmd_only(gc, QQ_ROOM_CMD_JOIN, group->id);
+	qq_send_room_cmd_only(gc, QQ_ROOM_CMD_JOIN, rmd->id);
 }
 
 static void group_join_cb(qq_add_request *add_req, const gchar *reason_utf8)
 {
-	qq_group *group;
+	qq_room_data *rmd;
 
 	g_return_if_fail(add_req != NULL);
 	if (add_req->gc == NULL || add_req->uid == 0) {
@@ -112,14 +114,14 @@
 		return;
 	}
 
-	group = qq_room_search_id(add_req->gc, add_req->uid);
-	if (group == NULL) {
-		purple_debug_error("QQ", "Can not find qq_group by internal_id: %d\n", add_req->uid);
+	rmd = qq_room_data_find(add_req->gc, add_req->uid);
+	if (rmd == NULL) {
+		purple_debug_error("QQ", "Can not find qq_room_data by internal_id: %d\n", add_req->uid);
 		g_free(add_req);
 		return;
 	}
 
-	qq_send_cmd_group_auth(add_req->gc, group, QQ_ROOM_AUTH_REQUEST_APPLY, 0, reason_utf8);
+	qq_send_cmd_group_auth(add_req->gc, rmd, QQ_ROOM_AUTH_REQUEST_APPLY, 0, reason_utf8);
 	g_free(add_req);
 }
 
@@ -129,36 +131,36 @@
 	g_free(add_req);
 }
 
-static void _qq_group_join_auth(PurpleConnection *gc, qq_group *group)
+static void _qq_group_join_auth(PurpleConnection *gc, qq_room_data *rmd)
 {
 	gchar *msg;
 	qq_add_request *add_req;
-	g_return_if_fail(group != NULL);
+	g_return_if_fail(rmd != NULL);
 
-	purple_debug_info("QQ", "Group (internal id: %d) needs authentication\n", group->id);
+	purple_debug_info("QQ", "Group (internal id: %d) needs authentication\n", rmd->id);
 
-	msg = g_strdup_printf("Group \"%s\" needs authentication\n", group->title_utf8);
+	msg = g_strdup_printf("Group \"%s\" needs authentication\n", rmd->title_utf8);
 	add_req = g_new0(qq_add_request, 1);
 	add_req->gc = gc;
-	add_req->uid = group->id;
+	add_req->uid = rmd->id;
 	purple_request_input(gc, NULL, msg,
 			   _("Input request here"),
 			   _("Would you be my friend?"), TRUE, FALSE, NULL,
 			   _("Send"),
 			   G_CALLBACK(group_join_cb),
 			   _("Cancel"), G_CALLBACK(qq_group_cancel_cb),
-			   purple_connection_get_account(gc), group->title_utf8, NULL,
+			   purple_connection_get_account(gc), rmd->title_utf8, NULL,
 			   add_req);
 	g_free(msg);
 }
 
-void qq_send_cmd_group_auth(PurpleConnection *gc, qq_group *group, guint8 opt, guint32 uid, const gchar *reason_utf8)
+void qq_send_cmd_group_auth(PurpleConnection *gc, qq_room_data *rmd, guint8 opt, guint32 uid, const gchar *reason_utf8)
 {
 	guint8 *raw_data;
 	gchar *reason_qq;
 	gint bytes;
 
-	g_return_if_fail(group != NULL);
+	g_return_if_fail(rmd != NULL);
 
 	if (reason_utf8 == NULL || strlen(reason_utf8) == 0)
 		reason_qq = g_strdup("");
@@ -166,8 +168,7 @@
 		reason_qq = utf8_to_qq(reason_utf8, QQ_CHARSET_DEFAULT);
 
 	if (opt == QQ_ROOM_AUTH_REQUEST_APPLY) {
-		group->my_role = QQ_ROOM_ROLE_REQUESTING;
-		qq_group_refresh(gc, group);
+		rmd->my_role = QQ_ROOM_ROLE_REQUESTING;
 		uid = 0;
 	}
 
@@ -179,18 +180,15 @@
 	bytes += qq_put8(raw_data + bytes, strlen(reason_qq));
 	bytes += qq_putdata(raw_data + bytes, (guint8 *) reason_qq, strlen(reason_qq));
 
-	qq_send_room_cmd(gc, QQ_ROOM_CMD_AUTH, group->id, raw_data, bytes);
+	qq_send_room_cmd(gc, QQ_ROOM_CMD_AUTH, rmd->id, raw_data, bytes);
 }
 
 /* If comes here, cmd is OK already */
 void qq_process_group_cmd_exit_group(guint8 *data, gint len, PurpleConnection *gc)
 {
+	qq_data *qd;
 	gint bytes;
 	guint32 id;
-	PurpleChat *chat;
-	qq_group *group;
-	qq_data *qd;
-	gchar *msg;
 
 	g_return_if_fail(data != NULL && len > 0);
 	qd = (qq_data *) gc->proto_data;
@@ -203,20 +201,7 @@
 	bytes = 0;
 	bytes += qq_get32(&id, data + bytes);
 
-	group = qq_room_search_id(gc, id);
-	if (group != NULL) {
-		msg = g_strdup_printf(_("Successed quit Qun %s (%d)"),
-				group->title_utf8, group->ext_id);
-		chat = purple_blist_find_chat
-			    (purple_connection_get_account(gc), g_strdup_printf("%d", group->ext_id));
-		if (chat != NULL)
-			purple_blist_remove_chat(chat);
-		qq_group_delete_internal_record(qd, id);
-	} else {
-		msg = g_strdup(_("Successed quit Qun"));
-	}
-	qq_got_attention(gc, msg);
-	g_free(msg);
+	qq_room_remove(gc, id);
 }
 
 /* Process the reply to group_auth subcmd */
@@ -225,7 +210,7 @@
 	gint bytes;
 	guint32 id;
 	qq_data *qd;
-	qq_group *group;
+	qq_room_data *rmd;
 	gchar *msg;
 
 	g_return_if_fail(data != NULL && len > 0);
@@ -240,9 +225,9 @@
 	bytes += qq_get32(&id, data + bytes);
 	g_return_if_fail(id > 0);
 
-	group = qq_room_search_id(gc, id);
-	if (group != NULL) {
-		msg = g_strdup_printf(_("Successed join to Qun %s (%d)"), group->title_utf8, group->ext_id);
+	rmd = qq_room_data_find(gc, id);
+	if (rmd != NULL) {
+		msg = g_strdup_printf(_("Successed join to Qun %s (%d)"), rmd->title_utf8, rmd->ext_id);
 		qq_got_attention(gc, msg);
 		g_free(msg);
 	} else {
@@ -256,14 +241,14 @@
 	gint bytes;
 	guint32 id;
 	guint8 reply;
-	qq_group *group;
+	qq_room_data *rmd;
 	gchar *msg;
 
 	g_return_if_fail(data != NULL && len > 0);
 
 	if (len < 5) {
 		purple_debug_error("QQ",
-			   "Invalid join group reply, expect %d bytes, read %d bytes\n", 5, len);
+			   "Invalid join room reply, expect %d bytes, read %d bytes\n", 5, len);
 		return;
 	}
 
@@ -272,34 +257,32 @@
 	bytes += qq_get8(&reply, data + bytes);
 
 	/* join group OK */
-	group = qq_room_search_id(gc, id);
+	rmd = qq_room_data_find(gc, id);
 	/* need to check if group is NULL or not. */
-	g_return_if_fail(group != NULL);
+	g_return_if_fail(rmd != NULL);
 	switch (reply) {
 	case QQ_ROOM_JOIN_OK:
-		purple_debug_info("QQ", "Successed in joining group \"%s\"\n", group->title_utf8);
-		group->my_role = QQ_ROOM_ROLE_YES;
-		qq_group_refresh(gc, group);
+		purple_debug_info("QQ", "Successed in joining group \"%s\"\n", rmd->title_utf8);
+		rmd->my_role = QQ_ROOM_ROLE_YES;
 		/* this must be shown before getting online members */
-		qq_room_conv_open(gc, group);
+		qq_room_conv_open(gc, rmd);
 		break;
 	case QQ_ROOM_JOIN_NEED_AUTH:
 		purple_debug_info("QQ",
 			   "Fail joining group [%d] %s, needs authentication\n",
-			   group->ext_id, group->title_utf8);
-		group->my_role = QQ_ROOM_ROLE_NO;
-		qq_group_refresh(gc, group);
-		_qq_group_join_auth(gc, group);
+			   rmd->ext_id, rmd->title_utf8);
+		rmd->my_role = QQ_ROOM_ROLE_NO;
+		_qq_group_join_auth(gc, rmd);
 		break;
 	case QQ_ROOM_JOIN_DENIED:
-		msg = g_strdup_printf(_("Qun %d denied to join"), group->ext_id);
+		msg = g_strdup_printf(_("Qun %d denied to join"), rmd->ext_id);
 		purple_notify_info(gc, _("QQ Qun Operation"), _("Failed:"), msg);
 		g_free(msg);
 		break;
 	default:
 		purple_debug_info("QQ",
 			   "Failed joining group [%d] %s, unknown reply: 0x%02x\n",
-			   group->ext_id, group->title_utf8, reply);
+			   rmd->ext_id, rmd->title_utf8, reply);
 
 		purple_notify_info(gc, _("QQ Qun Operation"), _("Failed:"), _("Join Qun, Unknow Reply"));
 	}
@@ -313,7 +296,7 @@
 	gchar *id_str;
 	guint32 ext_id;
 	guint32 id;
-	qq_group *group;
+	qq_room_data *rmd;
 
 	g_return_if_fail(data != NULL);
 	qd = (qq_data *) gc->proto_data;
@@ -325,9 +308,9 @@
 	if (id_str != NULL) {
 		id = strtol(id_str, NULL, 10);
 		if (id != 0) {
-			group = qq_room_search_id(gc, id);
-			if (group) {
-				qq_request_room_join(gc, group);
+			rmd = qq_room_data_find(gc, id);
+			if (rmd) {
+				qq_request_room_join(gc, rmd);
 				return;
 			}
 		}
@@ -362,3 +345,93 @@
 			    G_CALLBACK(qq_group_cancel_cb),
 			    _("Continue"), G_CALLBACK(group_quit_cb));
 }
+
+/* send packet to search for qq_group */
+void qq_request_room_search(PurpleConnection *gc, guint32 ext_id, int action)
+{
+	guint8 raw_data[16] = {0};
+	gint bytes = 0;
+	guint8 type;
+
+	purple_debug_info("QQ", "Search QQ Qun %d\n", ext_id);
+	type = (ext_id == 0x00000000) ? QQ_ROOM_SEARCH_TYPE_DEMO : QQ_ROOM_SEARCH_TYPE_BY_ID;
+
+	bytes = 0;
+	bytes += qq_put8(raw_data + bytes, type);
+	bytes += qq_put32(raw_data + bytes, ext_id);
+
+	qq_send_room_cmd_mess(gc, QQ_ROOM_CMD_SEARCH, 0, raw_data, bytes, 0, action);
+}
+
+static void add_to_roomlist(qq_data *qd, qq_room_data *rmd)
+{
+	PurpleRoomlistRoom *room;
+	gchar field[11];
+
+	room = purple_roomlist_room_new(PURPLE_ROOMLIST_ROOMTYPE_ROOM, rmd->title_utf8, NULL);
+	g_snprintf(field, sizeof(field), "%d", rmd->ext_id);
+	purple_roomlist_room_add_field(qd->roomlist, room, field);
+	g_snprintf(field, sizeof(field), "%d", rmd->creator_uid);
+	purple_roomlist_room_add_field(qd->roomlist, room, field);
+	purple_roomlist_room_add_field(qd->roomlist, room, rmd->desc_utf8);
+	g_snprintf(field, sizeof(field), "%d", rmd->id);
+	purple_roomlist_room_add_field(qd->roomlist, room, field);
+	g_snprintf(field, sizeof(field), "%d", rmd->type8);
+	purple_roomlist_room_add_field(qd->roomlist, room, field);
+	g_snprintf(field, sizeof(field), "%d", rmd->auth_type);
+	purple_roomlist_room_add_field(qd->roomlist, room, field);
+	g_snprintf(field, sizeof(field), "%d", rmd->category);
+	purple_roomlist_room_add_field(qd->roomlist, room, field);
+	purple_roomlist_room_add_field(qd->roomlist, room, rmd->title_utf8);
+	purple_roomlist_room_add(qd->roomlist, room);
+
+	purple_roomlist_set_in_progress(qd->roomlist, FALSE);
+}
+
+/* process group cmd reply "search group" */
+void qq_process_room_search(PurpleConnection *gc, guint8 *data, gint len, guint32 ship32)
+{
+	qq_data *qd;
+	qq_room_data rmd;
+	PurpleChat *chat;
+	gint bytes;
+	guint8 search_type;
+	guint16 unknown;
+
+	g_return_if_fail(data != NULL && len > 0);
+	qd = (qq_data *) gc->proto_data;
+
+	bytes = 0;
+	bytes += qq_get8(&search_type, data + bytes);
+
+	/* now it starts with group_info_entry */
+	bytes += qq_get32(&(rmd.id), data + bytes);
+	bytes += qq_get32(&(rmd.ext_id), data + bytes);
+	bytes += qq_get8(&(rmd.type8), data + bytes);
+	bytes += qq_get16(&(unknown), data + bytes);
+	bytes += qq_get16(&(unknown), data + bytes);
+	bytes += qq_get32(&(rmd.creator_uid), data + bytes);
+	bytes += qq_get16(&(unknown), data + bytes);
+	bytes += qq_get16(&(unknown), data + bytes);
+	bytes += qq_get16(&(unknown), data + bytes);
+	bytes += qq_get32(&(rmd.category), data + bytes);
+	bytes += qq_get_vstr(&(rmd.title_utf8), QQ_CHARSET_DEFAULT, data + bytes);
+	bytes += qq_get16(&(unknown), data + bytes);
+	bytes += qq_get8(&(rmd.auth_type), data + bytes);
+	bytes += qq_get_vstr(&(rmd.desc_utf8), QQ_CHARSET_DEFAULT, data + bytes);
+	/* end of one qq_group */
+	if(bytes != len) {
+		purple_debug_error("QQ",
+			"group_cmd_search_group: Dangerous error! maybe protocol changed, notify developers!");
+	}
+
+	if (ship32 == QQ_ROOM_SEARCH_FOR_JOIN) {
+		chat = qq_room_find_or_new(gc, rmd.id, rmd.ext_id);
+		g_return_if_fail(chat != NULL);
+
+		qq_room_update_chat_info(gc, &rmd);
+		qq_request_room_join(gc, &rmd);
+	} else {
+		add_to_roomlist(qd, &rmd);
+	}
+}