comparison libgaim/protocols/qq/buddy_status.c @ 14318:437ce90442cf

[gaim-migrate @ 17011] Use GaimPresence to keep track of our status instead of qd->status. Also allow invisible logins. committer: Tailor Script <tailor@pidgin.im>
author Mark Huetsch <markhuetsch>
date Thu, 24 Aug 2006 07:00:34 +0000
parents 584cbd1628d0
children 6b8bc59414f0
comparison
equal deleted inserted replaced
14317:c8ddda5d8ec8 14318:437ce90442cf
33 #include "utils.h" 33 #include "utils.h"
34 34
35 #include "qq_proxy.h" 35 #include "qq_proxy.h"
36 36
37 #define QQ_MISC_STATUS_HAVING_VIIDEO 0x00000001 37 #define QQ_MISC_STATUS_HAVING_VIIDEO 0x00000001
38
39 #define QQ_ICON_SUFFIX_DEFAULT QQ_ICON_SUFFIX_OFFLINE
40 #define QQ_CHANGE_ONLINE_STATUS_REPLY_OK 0x30 /* ASCII value of "0" */ 38 #define QQ_CHANGE_ONLINE_STATUS_REPLY_OK 0x30 /* ASCII value of "0" */
41
42 enum {
43 QQ_ICON_SUFFIX_NORMAL = 1,
44 QQ_ICON_SUFFIX_OFFLINE = 2,
45 QQ_ICON_SUFFIX_AWAY = 3,
46 };
47 39
48 void qq_buddy_status_dump_unclear(qq_buddy_status *s) 40 void qq_buddy_status_dump_unclear(qq_buddy_status *s)
49 { 41 {
50 GString *dump; 42 GString *dump;
51 43
118 return FALSE; 110 return FALSE;
119 } 111 }
120 return FALSE; 112 return FALSE;
121 } 113 }
122 114
123 /* The QQ client seems to use a separate icon for each 115 /* Help calculate the correct icon index to tell the server. */
124 * face/status combo, but we only use one and let Gaim 116 gint get_icon_offset(GaimConnection *gc)
125 * handle the rest. We need to use this function to report 117 {
126 * the correct icon file back to the server. */ 118 GaimAccount *account;
127 gint get_icon_offset_from_self_status(guint8 status) 119 GaimPresence *presence;
128 { 120
129 switch (status) { 121 g_return_val_if_fail(gc != NULL && gc->proto_data != NULL, 2);
130 case QQ_SELF_STATUS_AVAILABLE: 122
123 account = gaim_connection_get_account(gc);
124 presence = gaim_account_get_presence(account);
125
126 if (gaim_presence_is_status_primitive_active(presence, GAIM_STATUS_INVISIBLE)) {
127 return 2;
128 } else if (gaim_presence_is_status_primitive_active(presence, GAIM_STATUS_AWAY)
129 || gaim_presence_is_status_primitive_active(presence, GAIM_STATUS_EXTENDED_AWAY)
130 || gaim_presence_is_status_primitive_active(presence, GAIM_STATUS_UNAVAILABLE)) {
131 return 1;
132 } else {
131 return 0; 133 return 0;
132 case QQ_SELF_STATUS_AWAY:
133 case QQ_SELF_STATUS_CUSTOM:
134 return 1;
135 case QQ_SELF_STATUS_INVISIBLE:
136 return 2;
137 default:
138 return 2;
139 } 134 }
140 } 135 }
141 136
142 /* send a packet to change my online status */ 137 /* send a packet to change my online status */
143 void qq_send_packet_change_status(GaimConnection *gc) 138 void qq_send_packet_change_status(GaimConnection *gc)
144 { 139 {
145 qq_data *qd; 140 qq_data *qd;
146 guint8 *raw_data, *cursor, away_cmd; 141 guint8 *raw_data, *cursor, away_cmd;
147 guint32 misc_status; 142 guint32 misc_status;
148 gboolean fake_video; 143 gboolean fake_video;
144 GaimAccount *account;
145 GaimPresence *presence;
149 146
150 g_return_if_fail(gc != NULL && gc->proto_data != NULL); 147 g_return_if_fail(gc != NULL && gc->proto_data != NULL);
148
149 account = gaim_connection_get_account(gc);
150 presence = gaim_account_get_presence(account);
151 151
152 qd = (qq_data *) gc->proto_data; 152 qd = (qq_data *) gc->proto_data;
153 if (!qd->logged_in) 153 if (!qd->logged_in)
154 return; 154 return;
155 155
156 switch (qd->status) { 156 if (gaim_presence_is_status_primitive_active(presence, GAIM_STATUS_INVISIBLE)) {
157 case QQ_SELF_STATUS_AVAILABLE:
158 away_cmd = QQ_BUDDY_ONLINE_NORMAL;
159 break;
160 case QQ_SELF_STATUS_INVISIBLE:
161 away_cmd = QQ_BUDDY_ONLINE_INVISIBLE; 157 away_cmd = QQ_BUDDY_ONLINE_INVISIBLE;
162 break; 158 } else if (gaim_presence_is_status_primitive_active(presence, GAIM_STATUS_AWAY)
163 case QQ_SELF_STATUS_AWAY: 159 || gaim_presence_is_status_primitive_active(presence, GAIM_STATUS_EXTENDED_AWAY)
164 case QQ_SELF_STATUS_IDLE: 160 || gaim_presence_is_status_primitive_active(presence, GAIM_STATUS_UNAVAILABLE)) {
165 case QQ_SELF_STATUS_CUSTOM:
166 away_cmd = QQ_BUDDY_ONLINE_AWAY; 161 away_cmd = QQ_BUDDY_ONLINE_AWAY;
167 break; 162 } else {
168 default:
169 away_cmd = QQ_BUDDY_ONLINE_NORMAL; 163 away_cmd = QQ_BUDDY_ONLINE_NORMAL;
170 } 164 }
171 165
172 raw_data = g_new0(guint8, 5); 166 raw_data = g_new0(guint8, 5);
173 cursor = raw_data; 167 cursor = raw_data;
189 void qq_process_change_status_reply(guint8 *buf, gint buf_len, GaimConnection *gc) 183 void qq_process_change_status_reply(guint8 *buf, gint buf_len, GaimConnection *gc)
190 { 184 {
191 qq_data *qd; 185 qq_data *qd;
192 gint len; 186 gint len;
193 guint8 *data, *cursor, reply; 187 guint8 *data, *cursor, reply;
188 GaimBuddy *b;
189 qq_buddy *q_bud;
190 gchar *name;
194 191
195 g_return_if_fail(gc != NULL && gc->proto_data != NULL); 192 g_return_if_fail(gc != NULL && gc->proto_data != NULL);
196 g_return_if_fail(buf != NULL && buf_len != 0); 193 g_return_if_fail(buf != NULL && buf_len != 0);
197 194
198 qd = (qq_data *) gc->proto_data; 195 qd = (qq_data *) gc->proto_data;
202 if (qq_crypt(DECRYPT, buf, buf_len, qd->session_key, data, &len)) { 199 if (qq_crypt(DECRYPT, buf, buf_len, qd->session_key, data, &len)) {
203 cursor = data; 200 cursor = data;
204 read_packet_b(data, &cursor, len, &reply); 201 read_packet_b(data, &cursor, len, &reply);
205 if (reply != QQ_CHANGE_ONLINE_STATUS_REPLY_OK) { 202 if (reply != QQ_CHANGE_ONLINE_STATUS_REPLY_OK) {
206 gaim_debug(GAIM_DEBUG_WARNING, "QQ", "Change status fail\n"); 203 gaim_debug(GAIM_DEBUG_WARNING, "QQ", "Change status fail\n");
207 } else 204 } else {
208 gaim_debug(GAIM_DEBUG_INFO, "QQ", "Change status OK\n"); 205 gaim_debug(GAIM_DEBUG_INFO, "QQ", "Change status OK\n");
209 } else 206 name = uid_to_gaim_name(qd->uid);
207 b = gaim_find_buddy(gc->account, name);
208 g_free(name);
209 q_bud = (b == NULL) ? NULL : (qq_buddy *) b->proto_data;
210 qq_update_buddy_contact(gc, q_bud);
211 }
212 } else {
210 gaim_debug(GAIM_DEBUG_ERROR, "QQ", "Error decrypt chg status reply\n"); 213 gaim_debug(GAIM_DEBUG_ERROR, "QQ", "Error decrypt chg status reply\n");
211 214 }
212 } 215 }
213 216
214 /* it is a server message indicating that one of my buddies has changed its status */ 217 /* it is a server message indicating that one of my buddies has changed its status */
215 void qq_process_friend_change_status(guint8 *buf, gint buf_len, GaimConnection *gc) 218 void qq_process_friend_change_status(guint8 *buf, gint buf_len, GaimConnection *gc)
216 { 219 {
234 if (qq_crypt(DECRYPT, buf, buf_len, qd->session_key, data, &len)) { 237 if (qq_crypt(DECRYPT, buf, buf_len, qd->session_key, data, &len)) {
235 s = g_new0(qq_buddy_status, 1); 238 s = g_new0(qq_buddy_status, 1);
236 bytes = 0; 239 bytes = 0;
237 /* 000-030: qq_buddy_status */ 240 /* 000-030: qq_buddy_status */
238 bytes += qq_buddy_status_read(data, &cursor, len, s); 241 bytes += qq_buddy_status_read(data, &cursor, len, s);
239 /* 031-034: my uid */ 242 /* 031-034: my uid */
243 /* This has a value of 0 when we've changed our status to
244 * QQ_BUDDY_ONLINE_INVISIBLE */
240 bytes += read_packet_dw(data, &cursor, len, &my_uid); 245 bytes += read_packet_dw(data, &cursor, len, &my_uid);
241 246
242 if (my_uid == 0 || bytes != 35) { 247 if (bytes != 35) {
243 gaim_debug(GAIM_DEBUG_ERROR, "QQ", "my_uid == 0 || bytes(%d) != 35\n", bytes); 248 gaim_debug(GAIM_DEBUG_ERROR, "QQ", "bytes(%d) != 35\n", bytes);
244 g_free(s->ip); 249 g_free(s->ip);
245 g_free(s->unknown_key); 250 g_free(s->unknown_key);
246 g_free(s); 251 g_free(s);
247 return; 252 return;
248 } 253 }
261 if(0 != s->client_version) 266 if(0 != s->client_version)
262 q_bud->client_version = s->client_version; 267 q_bud->client_version = s->client_version;
263 qq_update_buddy_contact(gc, q_bud); 268 qq_update_buddy_contact(gc, q_bud);
264 } else { 269 } else {
265 gaim_debug(GAIM_DEBUG_ERROR, "QQ", 270 gaim_debug(GAIM_DEBUG_ERROR, "QQ",
266 "got information of unknown buddy by gfhuang %d\n", s->uid); 271 "got information of unknown buddy %d\n", s->uid);
267 } 272 }
268 273
269 g_free(s->ip); 274 g_free(s->ip);
270 g_free(s->unknown_key); 275 g_free(s->unknown_key);
271 g_free(s); 276 g_free(s);