static void login_stage_3(LwqqAsyncEvent* ev) { if(lwqq_async_event_get_code(ev) == LWQQ_CALLBACK_FAILED) return; int err = lwqq_async_event_get_result(ev); LwqqClient* lc = lwqq_async_event_get_owner(ev); if(!lwqq_client_valid(lc)) return; switch (err) { case LWQQ_EC_LOGIN_NEED_VC: lwqq_log(LOG_WARNING, "Need to enter verify code\n"); LwqqAsyncEvent* ev = get_verify_image(lc); lwqq_async_add_event_listener(ev,_C_(p,lc->async_opt->login_verify,lc)); return ; case LWQQ_EC_NETWORK_ERROR: lwqq_log(LOG_ERROR, "Network error\n"); lc->async_opt->login_complete(lc,err); return ; case LWQQ_EC_OK: lwqq_log(LOG_DEBUG, "Get verify code OK\n"); break; default: lwqq_log(LOG_ERROR, "Unknown error\n"); lc->async_opt->login_complete(lc,err); return ; } login_stage_4(lc); }
static void login_stage_3(LwqqAsyncEvent* ev,LwqqErrorCode* ec) { if(lwqq_async_event_get_code(ev) == LWQQ_CALLBACK_FAILED) return; int err = lwqq_async_event_get_result(ev); if(ec) *ec=err; LwqqClient* lc = lwqq_async_event_get_owner(ev); if(!lwqq_client_valid(lc)) return; switch (err) { case LWQQ_EC_LOGIN_NEED_VC: lwqq_log(LOG_WARNING, "Need to enter verify code\n"); lc->vc->cmd = _C_(2p,login_stage_4,lc,ec); get_verify_image(lc); return ; case LWQQ_EC_NETWORK_ERROR: lwqq_log(LOG_ERROR, "Network error\n"); lc->stat = LWQQ_STATUS_LOGOUT; lc->args->login_ec = err; vp_do_repeat(lc->events->login_complete, NULL); return ; case LWQQ_EC_OK: lwqq_log(LOG_DEBUG, "Get verify code OK\n"); break; default: lwqq_log(LOG_ERROR, "Unknown error\n"); lc->stat = LWQQ_STATUS_LOGOUT; lc->args->login_ec = err; vp_do_repeat(lc->events->login_complete, NULL); return ; } login_stage_4(lc,ec); }
static void login_stage_2(LwqqAsyncEvent* ev) { if(lwqq_async_event_get_code(ev) == LWQQ_CALLBACK_FAILED) return; LwqqClient* lc = lwqq_async_event_get_owner(ev); if(!lwqq_client_valid(lc)) return; int err = lwqq_async_event_get_result(ev); if (err) { lwqq_log(LOG_ERROR, "Get webqq version error\n"); lc->async_opt->login_complete(lc,err); return ; } lwqq_log(LOG_NOTICE, "Get webqq version: %s\n", lc->version); /** * Second, we get the verify code from server. * If server provide us a image and let us enter code shown * in image number, in this situation, we just return LWQQ_EC_LOGIN_NEED_VC * simply, so user should call lwqq_login() again after he set correct * code to vc->str; * Else, if we can get the code directly, do login immediately. * */ if (!lc->vc) { LwqqAsyncEvent* ev = get_verify_code(lc,APPID); lwqq_async_add_event_listener(ev,_C_(p,login_stage_3,ev)); return; } login_stage_4(lc); }
static int set_online_status_back(LwqqHttpRequest* req) { int err = LWQQ_EC_OK; int ret; char* response; char* value; json_t * json = NULL; LwqqClient* lc = req->lc; if(!lwqq_client_valid(lc)){ err = LWQQ_EC_ERROR; goto done; } if (req->http_code != 200) { err = LWQQ_EC_HTTP_ERROR; goto done; } /** * Here, we got a json object like this: * {"retcode":0,"result":{"uin":1421032531,"cip":2013211875,"index":1060,"port":43415,"status":"online","vfwebqq":"e7ce7913336ad0d28de9cdb9b46a57e4a6127161e35b87d09486001870226ec1fca4c2ba31c025c7","psessionid":"8368046764001e636f6e6e7365727665725f77656271714031302e3133332e34312e32303200006b2900001544016e0400533cb3546d0000000a4046674d4652585136496d00000028e7ce7913336ad0d28de9cdb9b46a57e4a6127161e35b87d09486001870226ec1fca4c2ba31c025c7","user_state":0,"f":0}} * */ response = req->response; lwqq_verbose(3,"%s\n",response); ret = json_parse_document(&json, response); if (ret != JSON_OK) { err = LWQQ_EC_ERROR; goto done; } if (!(value = json_parse_simple_value(json, "retcode"))) { err = LWQQ_EC_ERROR; goto done; } /** * Do we need parse "seskey? from kernelhcy's code, we need it, * but from the response we got like above, we dont need * */ lwqq__override(lc->seskey,lwqq__json_get_value(json,"seskey")); lwqq__override(lc->cip,lwqq__json_get_value(json,"cip")); lwqq__override(lc->myself->uin,lwqq__json_get_value(json,"uin")); lwqq__override(lc->index,lwqq__json_get_value(json,"index")); lwqq__override(lc->port,lwqq__json_get_value(json,"port")); lwqq__override(lc->vfwebqq,lwqq__json_get_value(json,"vfwebqq")); lwqq__override(lc->psessionid,lwqq__json_get_value(json,"psessionid")); lc->stat = lwqq_status_from_str( json_parse_simple_value(json, "status")); err = LWQQ_EC_OK; done: if (json) json_free_value(&json); lwqq_http_request_free(req); return err; }
static void login_stage_f(LwqqAsyncEvent* ev) { if(lwqq_async_event_get_code(ev) == LWQQ_CALLBACK_FAILED) return; int err = lwqq_async_event_get_result(ev); LwqqClient* lc = lwqq_async_event_get_owner(ev); if(!lwqq_client_valid(lc)) return; lc->async_opt->login_complete(lc,err); lwqq_vc_free(lc->vc); lc->vc = NULL; }
static void login_stage_4(LwqqClient* lc) { if(!lwqq_client_valid(lc)) return; /* Third: calculate the md5 */ char *md5 = lwqq_enc_pwd(lc->password, lc->vc->str, lc->vc->uin); /* Last: do real login */ LwqqAsyncEvent* ev = do_login(lc, md5, NULL); s_free(md5); lwqq_async_add_event_listener(ev,_C_(p,login_stage_5,ev)); }
static void login_stage_f(LwqqAsyncEvent* ev,LwqqErrorCode* ec) { if(lwqq_async_event_get_code(ev) == LWQQ_CALLBACK_FAILED) return; int err = lwqq_async_event_get_result(ev); if(ec)(*ec=err); LwqqClient* lc = lwqq_async_event_get_owner(ev); if(!lwqq_client_valid(lc)) return; lwqq_vc_free(lc->vc); lc->vc = NULL; if(err) lc->stat = LWQQ_STATUS_LOGOUT; lc->args->login_ec = err; vp_do_repeat(lc->events->login_complete, NULL); }
static void login_stage_5(LwqqAsyncEvent* ev) { if(lwqq_async_event_get_code(ev) == LWQQ_CALLBACK_FAILED) return; int err = lwqq_async_event_get_result(ev); LwqqClient* lc = lwqq_async_event_get_owner(ev); if(!lwqq_client_valid(lc)) return; /* Free old value */ if(err != LWQQ_EC_OK){ lc->async_opt->login_complete(lc,err); } LwqqAsyncEvent* event = set_online_status(lc, lwqq_status_to_str(lc->stat)); lwqq_async_add_event_listener(event,_C_(p,login_stage_f,event)); }
static void login_stage_5(LwqqAsyncEvent* ev,LwqqErrorCode* ec) { if(lwqq_async_event_get_code(ev) == LWQQ_CALLBACK_FAILED) return; int err = lwqq_async_event_get_result(ev); if(ec)(*ec=err); LwqqClient* lc = lwqq_async_event_get_owner(ev); if(!lwqq_client_valid(lc)) return; /* Free old value */ if(err != LWQQ_EC_OK){ lc->stat = LWQQ_STATUS_LOGOUT; lc->args->login_ec = err; vp_do_repeat(lc->events->login_complete, NULL); return; } LwqqAsyncEvent* event = set_online_status(lc, lwqq_status_to_str(lc->stat)); lwqq_async_add_event_listener(event,_C_(2p,login_stage_f,event,ec)); }
static int get_version_back(LwqqHttpRequest* req) { int err = LWQQ_EC_OK; char* response = NULL; LwqqClient* lc = req->lc; if(!lwqq_client_valid(lc)){ err = LWQQ_EC_ERROR; goto done; } if (req->http_code!=200) { err = LWQQ_EC_NETWORK_ERROR; goto done; } response = req->response; if(response == NULL){ err = LWQQ_EC_NETWORK_ERROR; goto done; } if (strstr(response, "ptuiV")) { char *s, *t; char *v; s = strchr(response, '('); t = strchr(response, ')'); if (!s || !t) { err = LWQQ_EC_ERROR; goto done; } s++; v = malloc(t - s + 1); memset(v, 0, t - s + 1); strncpy(v, s, t - s); s_free(lc->version); lc->version = s_strdup(v); err = LWQQ_EC_OK; s_free(v); } done: lwqq_http_request_free(req); return err; }
static void login_stage_2(LwqqClient* lc,LwqqErrorCode* err) { if(!lwqq_client_valid(lc)) err&&(*err=LWQQ_EC_ERROR); /** * Second, we get the verify code from server. * If server provide us a image and let us enter code shown * in image number, in this situation, we just return LWQQ_EC_LOGIN_NEED_VC * simply, so user should call lwqq_login() again after he set correct * code to vc->str; * Else, if we can get the code directly, do login immediately. * */ if (!lc->vc) { LwqqAsyncEvent* ev = check_need_verify(lc,APPID); lwqq_async_add_event_listener(ev,_C_(2p,login_stage_3,ev,err)); return; } login_stage_4(lc,err); }
static void* _background_login(void* data) { qq_account* ac=(qq_account*)data; if(!qq_account_valid(ac)) return NULL; LwqqClient* lc = ac->qq; LwqqErrorCode err; //it would raise a invalid ac when wake up from sleep. //it would login twice,why? //so what i can do is disable the invalid one. if(!lwqq_client_valid(lc)) return NULL; const char* status = purple_status_get_id(purple_account_get_active_status(ac->account)); lwqq_login(lc,lwqq_status_from_str(status), &err); if (err == LWQQ_EC_LOGIN_NEED_VC) { lc->dispatch(vp_func_pi,(CALLBACK_FUNC)extra_async_opt.need_verify,lc,err); }else{ lc->dispatch(vp_func_pi,(CALLBACK_FUNC)extra_async_opt.login_complete,lc,err); } return NULL; }
static PurpleConversation* find_conversation(LwqqMsgType msg_type, const char* serv_id, qq_account* ac, const char** local_id_out) { PurpleAccount* account = ac->account; LwqqClient* lc = ac->qq; // add a valid check if (!lwqq_client_valid(lc)) return NULL; const char* local_id = NULL; PurpleConversation* conv = NULL; switch (msg_type) { case LWQQ_MS_BUDDY_MSG: case LWQQ_MS_SESS_MSG: if (ac->flag & QQ_USE_QQNUM) { LwqqBuddy* buddy = ac->qq->find_buddy_by_uin(ac->qq, serv_id); local_id = (buddy && buddy->qqnumber) ? buddy->qqnumber : serv_id; } else local_id = serv_id; conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM, local_id, account); break; case LWQQ_MS_GROUP_MSG: case LWQQ_MS_DISCU_MSG: if (ac->flag & QQ_USE_QQNUM) { LwqqGroup* group = find_group_by_gid(ac->qq, serv_id); local_id = (group && group->account) ? group->account : serv_id; } else local_id = serv_id; conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_CHAT, local_id, account); break; default: break; } *local_id_out = local_id; return conv; }
PurpleConversation* find_conversation(LwqqMsgType msg_type,const char* serv_id,qq_account* ac) { PurpleAccount* account = ac->account; LwqqClient* lc = ac->qq; //add a valid check if(!lwqq_client_valid(lc)) return NULL; const char* local_id; if(msg_type == LWQQ_MS_BUDDY_MSG || msg_type == LWQQ_MS_SESS_MSG){ if(ac->flag&QQ_USE_QQNUM){ LwqqBuddy* buddy = ac->qq->find_buddy_by_uin(ac->qq,serv_id); local_id = (buddy&&buddy->qqnumber)?buddy->qqnumber:serv_id; }else local_id = serv_id; return purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM,local_id,account); } else if(msg_type == LWQQ_MS_GROUP_MSG || msg_type == LWQQ_MS_DISCU_MSG){ if(ac->flag&QQ_USE_QQNUM){ LwqqGroup* group = find_group_by_gid(ac->qq,serv_id); local_id = (group&&group->account)?group->account:serv_id; }else local_id = serv_id; return purple_find_conversation_with_account(PURPLE_CONV_TYPE_CHAT,local_id,account); } else return NULL; }