comparison libpurple/protocols/qq/qq.c @ 24095:25f62d21b3f8

disapproval of revision '8cebefbc6cd5d84acb69c74e69e8821f11dd225d'
author Daniel Atallah <daniel.atallah@gmail.com>
date Mon, 15 Sep 2008 03:04:07 +0000
parents 147ada94a1d8
children 225e0e9e1055
comparison
equal deleted inserted replaced
24088:147ada94a1d8 24095:25f62d21b3f8
22 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA 22 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
23 */ 23 */
24 24
25 #include "internal.h" 25 #include "internal.h"
26 26
27 #ifdef _WIN32
28 #define random rand
29 #endif
30
27 #include "accountopt.h" 31 #include "accountopt.h"
28 #include "debug.h" 32 #include "debug.h"
29 #include "notify.h" 33 #include "notify.h"
30 #include "prefs.h" 34 #include "prefs.h"
31 #include "prpl.h" 35 #include "prpl.h"
56 #include "version.h" 60 #include "version.h"
57 61
58 #define OPENQ_AUTHOR "Puzzlebird" 62 #define OPENQ_AUTHOR "Puzzlebird"
59 #define OPENQ_WEBSITE "http://openq.sourceforge.net" 63 #define OPENQ_WEBSITE "http://openq.sourceforge.net"
60 64
61 static GList *server_list_build(gchar select) 65 #define QQ_TCP_PORT 8000
62 { 66 #define QQ_UDP_PORT 8000
63 GList *list = NULL; 67
64 68 static void server_list_create(PurpleAccount *account) {
65 if ( select == 'T' || select == 'A') {
66 list = g_list_append(list, "tcpconn.tencent.com:8000");
67 list = g_list_append(list, "tcpconn2.tencent.com:8000");
68 list = g_list_append(list, "tcpconn3.tencent.com:8000");
69 list = g_list_append(list, "tcpconn4.tencent.com:8000");
70 list = g_list_append(list, "tcpconn5.tencent.com:8000");
71 list = g_list_append(list, "tcpconn6.tencent.com:8000");
72 }
73 if ( select == 'U' || select == 'A') {
74 list = g_list_append(list, "sz.tencent.com:8000");
75 list = g_list_append(list, "sz2.tencent.com:8000");
76 list = g_list_append(list, "sz3.tencent.com:8000");
77 list = g_list_append(list, "sz4.tencent.com:8000");
78 list = g_list_append(list, "sz5.tencent.com:8000");
79 list = g_list_append(list, "sz6.tencent.com:8000");
80 list = g_list_append(list, "sz7.tencent.com:8000");
81 list = g_list_append(list, "sz8.tencent.com:8000");
82 list = g_list_append(list, "sz9.tencent.com:8000");
83 }
84 return list;
85 }
86
87 static void server_list_create(PurpleAccount *account)
88 {
89 PurpleConnection *gc; 69 PurpleConnection *gc;
90 qq_data *qd; 70 qq_data *qd;
91 PurpleProxyInfo *gpi;
92 const gchar *user_server; 71 const gchar *user_server;
93 72 int port;
73
74 purple_debug(PURPLE_DEBUG_INFO, "QQ", "Create server list\n");
94 gc = purple_account_get_connection(account); 75 gc = purple_account_get_connection(account);
95 g_return_if_fail(gc != NULL && gc->proto_data != NULL); 76 g_return_if_fail(gc != NULL && gc->proto_data != NULL);
96 qd = gc->proto_data; 77 qd = gc->proto_data;
97 78
98 gpi = purple_proxy_get_setup(account); 79 qd->use_tcp = purple_account_get_bool(account, "use_tcp", TRUE);
99 80 port = purple_account_get_int(account, "port", 0);
100 qd->use_tcp = TRUE; 81 if (port == 0) {
101 if (purple_proxy_info_get_type(gpi) == PURPLE_PROXY_UDP) { 82 if (qd->use_tcp) {
102 qd->use_tcp = FALSE; 83 port = QQ_TCP_PORT;
103 } 84 } else {
104 85 port = QQ_UDP_PORT;
86 }
87 }
88 qd->user_port = port;
89
90 g_return_if_fail(qd->user_server == NULL);
105 user_server = purple_account_get_string(account, "server", NULL); 91 user_server = purple_account_get_string(account, "server", NULL);
106 purple_debug_info("QQ", "Select server '%s'\n", user_server); 92 if (user_server != NULL && strlen(user_server) > 0) {
107 if ( (user_server != NULL && strlen(user_server) > 0) && strcasecmp(user_server, "auto") != 0) { 93 qd->user_server = g_strdup(user_server);
108 qd->servers = g_list_append(qd->servers, g_strdup(user_server)); 94 }
95
96 if (qd->user_server != NULL) {
97 qd->servers = g_list_append(qd->servers, qd->user_server);
109 return; 98 return;
110 } 99 }
111
112 if (qd->use_tcp) { 100 if (qd->use_tcp) {
113 qd->servers = server_list_build('T'); 101 qd->servers = g_list_append(qd->servers, "tcpconn.tencent.com");
102 qd->servers = g_list_append(qd->servers, "tcpconn2.tencent.com");
103 qd->servers = g_list_append(qd->servers, "tcpconn3.tencent.com");
104 qd->servers = g_list_append(qd->servers, "tcpconn4.tencent.com");
105 qd->servers = g_list_append(qd->servers, "tcpconn5.tencent.com");
106 qd->servers = g_list_append(qd->servers, "tcpconn6.tencent.com");
114 return; 107 return;
115 } 108 }
116 109
117 qd->servers = server_list_build('U'); 110 qd->servers = g_list_append(qd->servers, "sz.tencent.com");
118 } 111 qd->servers = g_list_append(qd->servers, "sz2.tencent.com");
119 112 qd->servers = g_list_append(qd->servers, "sz3.tencent.com");
120 static void server_list_remove_all(qq_data *qd) 113 qd->servers = g_list_append(qd->servers, "sz4.tencent.com");
121 { 114 qd->servers = g_list_append(qd->servers, "sz5.tencent.com");
115 qd->servers = g_list_append(qd->servers, "sz6.tencent.com");
116 qd->servers = g_list_append(qd->servers, "sz7.tencent.com");
117 qd->servers = g_list_append(qd->servers, "sz8.tencent.com");
118 qd->servers = g_list_append(qd->servers, "sz9.tencent.com");
119 }
120
121 static void server_list_remove_all(qq_data *qd) {
122 g_return_if_fail(qd != NULL); 122 g_return_if_fail(qd != NULL);
123 123
124 purple_debug_info("QQ", "free server list\n"); 124 if (qd->real_hostname) {
125 purple_debug(PURPLE_DEBUG_INFO, "QQ", "free real_hostname\n");
126 g_free(qd->real_hostname);
127 qd->real_hostname = NULL;
128 }
129
130 if (qd->user_server != NULL) {
131 purple_debug(PURPLE_DEBUG_INFO, "QQ", "free user_server\n");
132 g_free(qd->user_server);
133 qd->user_server = NULL;
134 }
135
136 purple_debug(PURPLE_DEBUG_INFO, "QQ", "free server list\n");
125 g_list_free(qd->servers); 137 g_list_free(qd->servers);
126 qd->curr_server = NULL;
127 } 138 }
128 139
129 static void qq_login(PurpleAccount *account) 140 static void qq_login(PurpleAccount *account)
130 { 141 {
131 PurpleConnection *gc; 142 PurpleConnection *gc;
138 g_return_if_fail(gc != NULL); 149 g_return_if_fail(gc != NULL);
139 150
140 gc->flags |= PURPLE_CONNECTION_HTML | PURPLE_CONNECTION_NO_BGCOLOR | PURPLE_CONNECTION_AUTO_RESP; 151 gc->flags |= PURPLE_CONNECTION_HTML | PURPLE_CONNECTION_NO_BGCOLOR | PURPLE_CONNECTION_AUTO_RESP;
141 152
142 qd = g_new0(qq_data, 1); 153 qd = g_new0(qq_data, 1);
143 memset(qd, 0, sizeof(qq_data));
144 qd->gc = gc; 154 qd->gc = gc;
145 gc->proto_data = qd; 155 gc->proto_data = qd;
146 156
147 presence = purple_account_get_presence(account); 157 presence = purple_account_get_presence(account);
148 if(purple_presence_is_status_primitive_active(presence, PURPLE_STATUS_INVISIBLE)) { 158 if(purple_presence_is_status_primitive_active(presence, PURPLE_STATUS_INVISIBLE)) {
153 } else { 163 } else {
154 qd->login_mode = QQ_LOGIN_MODE_NORMAL; 164 qd->login_mode = QQ_LOGIN_MODE_NORMAL;
155 } 165 }
156 166
157 server_list_create(account); 167 server_list_create(account);
158 purple_debug_info("QQ", "Server list has %d\n", g_list_length(qd->servers)); 168 purple_debug(PURPLE_DEBUG_INFO, "QQ",
159 169 "Server list has %d\n", g_list_length(qd->servers));
160 qd->is_show_notice = purple_account_get_bool(account, "show_notice", TRUE); 170
161 qd->is_show_news = purple_account_get_bool(account, "show_news", TRUE); 171 qq_connect(account);
162
163 qd->itv_config.resend = purple_account_get_int(account, "resend_interval", 10);
164 if (qd->itv_config.resend <= 0) qd->itv_config.resend = 10;
165
166 qd->itv_config.keep_alive = purple_account_get_int(account, "keep_alive_interval", 60);
167 if (qd->itv_config.keep_alive < 30) qd->itv_config.keep_alive = 30;
168 qd->itv_config.keep_alive /= qd->itv_config.resend;
169 qd->itv_count.keep_alive = qd->itv_config.keep_alive;
170
171 qd->itv_config.update = purple_account_get_int(account, "update_interval", 300);
172 if (qd->itv_config.update > 0) {
173 if (qd->itv_config.update < qd->itv_config.keep_alive) {
174 qd->itv_config.update = qd->itv_config.keep_alive;
175 }
176 qd->itv_config.update /= qd->itv_config.resend;
177 qd->itv_count.update = qd->itv_config.update;
178 } else {
179 qd->itv_config.update = 0;
180 }
181
182 qd->connect_watcher = purple_timeout_add_seconds(0, qq_connect_later, gc);
183 } 172 }
184 173
185 /* clean up the given QQ connection and free all resources */ 174 /* clean up the given QQ connection and free all resources */
186 static void qq_close(PurpleConnection *gc) 175 static void qq_close(PurpleConnection *gc)
187 { 176 {
188 qq_data *qd; 177 qq_data *qd;
189 178
190 g_return_if_fail(gc != NULL && gc->proto_data); 179 g_return_if_fail(gc != NULL && gc->proto_data);
191 qd = gc->proto_data; 180 qd = gc->proto_data;
192 181
193 if (qd->check_watcher > 0) {
194 purple_timeout_remove(qd->check_watcher);
195 qd->check_watcher = 0;
196 }
197
198 if (qd->connect_watcher > 0) {
199 purple_timeout_remove(qd->connect_watcher);
200 qd->connect_watcher = 0;
201 }
202
203 qq_disconnect(gc); 182 qq_disconnect(gc);
183
204 server_list_remove_all(qd); 184 server_list_remove_all(qd);
205 185
206 g_free(qd); 186 g_free(qd);
187
207 gc->proto_data = NULL; 188 gc->proto_data = NULL;
208 } 189 }
209 190
210 /* returns the icon name for a buddy or protocol */ 191 /* returns the icon name for a buddy or protocol */
211 static const gchar *_qq_list_icon(PurpleAccount *a, PurpleBuddy *b) 192 static const gchar *_qq_list_icon(PurpleAccount *a, PurpleBuddy *b)
229 switch(q_bud->status) { 210 switch(q_bud->status) {
230 case QQ_BUDDY_OFFLINE: 211 case QQ_BUDDY_OFFLINE:
231 g_string_append(status, _("Offline")); 212 g_string_append(status, _("Offline"));
232 break; 213 break;
233 case QQ_BUDDY_ONLINE_NORMAL: 214 case QQ_BUDDY_ONLINE_NORMAL:
234 g_string_append(status, _("Online")); 215 return NULL;
235 break; 216 break;
236 /* TODO What does this status mean? Labelling it as offline... */ 217 /* TODO What does this status mean? Labelling it as offline... */
237 case QQ_BUDDY_ONLINE_OFFLINE: 218 case QQ_BUDDY_ONLINE_OFFLINE:
238 g_string_append(status, _("Offline")); 219 g_string_append(status, _("Offline"));
239 break; 220 break;
320 } 301 }
321 if (q_bud->comm_flag & QQ_COMM_FLAG_VIDEO) { 302 if (q_bud->comm_flag & QQ_COMM_FLAG_VIDEO) {
322 g_string_append( str, _(" Video") ); 303 g_string_append( str, _(" Video") );
323 } 304 }
324 305
325 if (q_bud->ext_flag & QQ_EXT_FLAG_ZONE) { 306 if (q_bud->ext_flag & QQ_EXT_FLAG_SPACE) {
326 g_string_append( str, _(" Zone") ); 307 g_string_append( str, _(" Space") );
327 } 308 }
328 purple_notify_user_info_add_pair(user_info, _("Flag"), str->str); 309 purple_notify_user_info_add_pair(user_info, _("Flag"), str->str);
329 310
330 g_string_free(str, TRUE); 311 g_string_free(str, TRUE);
331 312
346 /* we can show tiny icons on the four corners of buddy icon, */ 327 /* we can show tiny icons on the four corners of buddy icon, */
347 static const char *_qq_list_emblem(PurpleBuddy *b) 328 static const char *_qq_list_emblem(PurpleBuddy *b)
348 { 329 {
349 /* each char** are refering to a filename in pixmaps/purple/status/default/ */ 330 /* each char** are refering to a filename in pixmaps/purple/status/default/ */
350 qq_buddy *q_bud; 331 qq_buddy *q_bud;
351 332
352 if (!b || !(q_bud = b->proto_data)) { 333 if (!b || !(q_bud = b->proto_data)) {
353 return NULL; 334 return NULL;
354 } 335 }
355 336
356 if (q_bud->comm_flag & QQ_COMM_FLAG_MOBILE) 337 if (q_bud->comm_flag & QQ_COMM_FLAG_MOBILE)
391 372
392 return types; 373 return types;
393 } 374 }
394 375
395 /* initiate QQ away with proper change_status packet */ 376 /* initiate QQ away with proper change_status packet */
396 static void _qq_change_status(PurpleAccount *account, PurpleStatus *status) 377 static void _qq_set_away(PurpleAccount *account, PurpleStatus *status)
397 { 378 {
398 PurpleConnection *gc = purple_account_get_connection(account); 379 PurpleConnection *gc = purple_account_get_connection(account);
399 380
400 qq_request_change_status(gc, 0); 381 qq_send_packet_change_status(gc);
401 } 382 }
402 383
403 /* IMPORTANT: PurpleConvImFlags -> PurpleMessageFlags */ 384 /* IMPORTANT: PurpleConvImFlags -> PurpleMessageFlags */
404 /* send an instant msg to a buddy */ 385 /* send an instant msg to a buddy */
405 static gint _qq_send_im(PurpleConnection *gc, const gchar *who, const gchar *message, PurpleMessageFlags flags) 386 static gint _qq_send_im(PurpleConnection *gc, const gchar *who, const gchar *message, PurpleMessageFlags flags)
461 442
462 qd = gc->proto_data; 443 qd = gc->proto_data;
463 uid = purple_name_to_uid(who); 444 uid = purple_name_to_uid(who);
464 445
465 if (uid <= 0) { 446 if (uid <= 0) {
466 purple_debug_error("QQ", "Not valid QQid: %s\n", who); 447 purple_debug(PURPLE_DEBUG_ERROR, "QQ", "Not valid QQid: %s\n", who);
467 purple_notify_error(gc, NULL, _("Invalid name"), NULL); 448 purple_notify_error(gc, NULL, _("Invalid name"), NULL);
468 return; 449 return;
469 } 450 }
470 451
471 qq_send_packet_get_level(gc, uid); 452 qq_send_packet_get_level(gc, uid);
533 g_string_append_printf(info, _("<b>Current Online</b>: %d<br>\n"), qd->total_online); 514 g_string_append_printf(info, _("<b>Current Online</b>: %d<br>\n"), qd->total_online);
534 g_string_append_printf(info, _("<b>Last Refresh</b>: %s<br>\n"), ctime(&qd->last_get_online)); 515 g_string_append_printf(info, _("<b>Last Refresh</b>: %s<br>\n"), ctime(&qd->last_get_online));
535 516
536 g_string_append(info, "<hr>\n"); 517 g_string_append(info, "<hr>\n");
537 518
538 g_string_append_printf(info, _("<b>Server</b>: %s<br>\n"), qd->curr_server); 519 g_string_append_printf(info, _("<b>Server</b>: %s: %d<br>\n"), qd->server_name, qd->real_port);
539 g_string_append_printf(info, _("<b>Connection Mode</b>: %s<br>\n"), qd->use_tcp ? "TCP" : "UDP"); 520 g_string_append_printf(info, _("<b>Connection Mode</b>: %s<br>\n"), qd->use_tcp ? "TCP" : "UDP");
521 g_string_append_printf(info, _("<b>Real hostname</b>: %s: %d<br>\n"), qd->real_hostname, qd->real_port);
540 g_string_append_printf(info, _("<b>My Public IP</b>: %s<br>\n"), inet_ntoa(qd->my_ip)); 522 g_string_append_printf(info, _("<b>My Public IP</b>: %s<br>\n"), inet_ntoa(qd->my_ip));
541 523
542 g_string_append(info, "<hr>\n"); 524 g_string_append(info, "<hr>\n");
543 g_string_append(info, "<i>Information below may not be accurate</i><br>\n"); 525 g_string_append(info, "<i>Information below may not be accurate</i><br>\n");
544 526
649 { 631 {
650 GList *m; 632 GList *m;
651 PurpleMenuAction *act; 633 PurpleMenuAction *act;
652 634
653 m = NULL; 635 m = NULL;
654 act = purple_menu_action_new(_("Leave the QQ Qun"), PURPLE_CALLBACK(_qq_menu_unsubscribe_group), NULL, NULL); 636 act = purple_menu_action_new(_("Leave this QQ Qun"), PURPLE_CALLBACK(_qq_menu_unsubscribe_group), NULL, NULL);
655 m = g_list_append(m, act); 637 m = g_list_append(m, act);
656 638
657 /* TODO: enable this 639 /* TODO: enable this
658 act = purple_menu_action_new(_("Show Details"), PURPLE_CALLBACK(_qq_menu_manage_group), NULL, NULL); 640 act = purple_menu_action_new(_("Show Details"), PURPLE_CALLBACK(_qq_menu_manage_group), NULL, NULL);
659 m = g_list_append(m, act); 641 m = g_list_append(m, act);
724 qq_close, /* close */ 706 qq_close, /* close */
725 _qq_send_im, /* send_im */ 707 _qq_send_im, /* send_im */
726 NULL, /* set_info */ 708 NULL, /* set_info */
727 NULL, /* send_typing */ 709 NULL, /* send_typing */
728 _qq_get_info, /* get_info */ 710 _qq_get_info, /* get_info */
729 _qq_change_status, /* change status */ 711 _qq_set_away, /* set_away */
730 NULL, /* set_idle */ 712 NULL, /* set_idle */
731 NULL, /* change_passwd */ 713 NULL, /* change_passwd */
732 qq_add_buddy, /* add_buddy */ 714 qq_add_buddy, /* add_buddy */
733 NULL, /* add_buddies */ 715 NULL, /* add_buddies */
734 qq_remove_buddy, /* remove_buddy */ 716 qq_remove_buddy, /* remove_buddy */
816 798
817 799
818 static void init_plugin(PurplePlugin *plugin) 800 static void init_plugin(PurplePlugin *plugin)
819 { 801 {
820 PurpleAccountOption *option; 802 PurpleAccountOption *option;
821 PurpleKeyValuePair *kvp; 803
822 GList *list = NULL;
823 GList *kvlist = NULL;
824 GList *entry;
825
826 list = server_list_build('A');
827
828 purple_prefs_add_string_list("/plugins/prpl/qq/serverlist", list);
829 list = purple_prefs_get_string_list("/plugins/prpl/qq/serverlist");
830
831 kvlist = NULL;
832 kvp = g_new0(PurpleKeyValuePair, 1);
833 kvp->key = g_strdup(_("Auto"));
834 kvp->value = g_strdup("auto");
835 kvlist = g_list_append(kvlist, kvp);
836
837 entry = list;
838 while(entry) {
839 if (entry->data != NULL && strlen(entry->data) > 0) {
840 kvp = g_new0(PurpleKeyValuePair, 1);
841 kvp->key = g_strdup(entry->data);
842 kvp->value = g_strdup(entry->data);
843 kvlist = g_list_append(kvlist, kvp);
844 }
845 entry = entry->next;
846 }
847
848 /*
849 option = purple_account_option_string_new(_("Server"), "server", NULL); 804 option = purple_account_option_string_new(_("Server"), "server", NULL);
850 prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, option); 805 prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, option);
851 806
852 option = purple_account_option_int_new(_("Port"), "port", 0); 807 option = purple_account_option_int_new(_("Port"), "port", 0);
853 prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, option); 808 prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, option);
854 */ 809
855 option = purple_account_option_list_new(_("Server"), "server", kvlist); 810 option = purple_account_option_bool_new(_("Connect using TCP"), "use_tcp", TRUE);
856 prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, option); 811 prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, option);
857 812
858 option = purple_account_option_bool_new(_("Show server notice"), "show_notice", TRUE); 813 option = purple_account_option_int_new(_("resend interval(s)"), "resend_interval", 10);
859 prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, option);
860
861 option = purple_account_option_bool_new(_("Show server news"), "show_news", TRUE);
862 prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, option);
863
864 option = purple_account_option_int_new(_("Resend interval(s)"), "resend_interval", 10);
865 prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, option); 814 prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, option);
866 815
867 option = purple_account_option_int_new(_("Keep alive interval(s)"), "keep_alive_interval", 60); 816 option = purple_account_option_int_new(_("Keep alive interval(s)"), "keep_alive_interval", 60);
868 prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, option); 817 prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, option);
869 818
872 821
873 purple_prefs_add_none("/plugins/prpl/qq"); 822 purple_prefs_add_none("/plugins/prpl/qq");
874 purple_prefs_add_bool("/plugins/prpl/qq/show_status_by_icon", TRUE); 823 purple_prefs_add_bool("/plugins/prpl/qq/show_status_by_icon", TRUE);
875 purple_prefs_add_bool("/plugins/prpl/qq/show_fake_video", FALSE); 824 purple_prefs_add_bool("/plugins/prpl/qq/show_fake_video", FALSE);
876 purple_prefs_add_bool("/plugins/prpl/qq/prompt_group_msg_on_recv", TRUE); 825 purple_prefs_add_bool("/plugins/prpl/qq/prompt_group_msg_on_recv", TRUE);
877
878 } 826 }
879 827
880 PURPLE_INIT_PLUGIN(qq, init_plugin, info); 828 PURPLE_INIT_PLUGIN(qq, init_plugin, info);