/** * WebQQ login function * Step: * 1. Get webqq version * 2. Get verify code * 3. Calculate password's md5 * 4. Do real login * 5. check whether logining successfully * * @param client Lwqq Client * @param err Error code */ LWQQ_EXPORT void lwqq_login(LwqqClient *client, LwqqStatus status,LwqqErrorCode *err) { if (!client) { lwqq_log(LOG_ERROR, "Invalid pointer\n"); return ; } if(status == LWQQ_STATUS_LOGOUT || status == LWQQ_STATUS_OFFLINE){ lwqq_log(LOG_WARNING, "Invalid online status\n"); return; } client->stat = status; client->args->login_ec = LWQQ_EC_NO_RESULT; vp_do_repeat(client->events->start_login, NULL); /* optional: get webqq version */ //get_version(client, err); if(!client->vc){ LwqqAsyncEvent* ev = get_login_sig(client); lwqq_async_add_event_listener(ev, _C_(2p,login_stage_2,client,err)); }else{ login_stage_4(client,err); } }
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 void upload_offline_file_init(PurpleXfer* xfer) { qq_account* ac = purple_connection_get_protocol_data(purple_account_get_connection(xfer->account)); LwqqClient* lc = ac->qq; const char* serv_id; if(ac->flag&QQ_USE_QQNUM){ const char* qqnum = purple_xfer_get_remote_user(xfer); LwqqBuddy* b = find_buddy_by_qqnumber(ac->qq, qqnum); if(b == NULL) return; serv_id = b->uin; }else{ serv_id = purple_xfer_get_remote_user(xfer); } LwqqMsgOffFile* file = lwqq_msg_fill_upload_offline_file( xfer->local_filename, lc->myself->uin, serv_id); xfer->start_time = time(NULL); xfer->data = file; int flags = 0; if(ac->flag&QQ_DONT_EXPECT_100_CONTINUE) flags |= DONT_EXPECTED_100_CONTINUE; LwqqAsyncEvent* ev = lwqq_msg_upload_offline_file(lc,file,flags); lwqq_async_add_event_listener(ev,_C_(2p,send_file,ev,xfer)); LwqqHttpRequest* req = lwqq_async_event_get_conn(ev); lwqq_http_on_progress(req, file_trans_on_progress, xfer); lwqq_http_set_option(req, LWQQ_HTTP_CANCELABLE,1L); }
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_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 upload_offline_file_init(PurpleXfer* xfer) { qq_account* ac = purple_connection_get_protocol_data(purple_account_get_connection(xfer->account)); LwqqClient* lc = ac->qq; LwqqMsgOffFile* file = lwqq_msg_fill_upload_offline_file( xfer->local_filename, lc->myself->uin, purple_xfer_get_remote_user(xfer)); xfer->start_time = time(NULL); xfer->data = file; LwqqAsyncEvent* ev = lwqq_msg_upload_offline_file(lc,file); lwqq_async_add_event_listener(ev,_C_(2p,send_file,ev,xfer)); lwqq_async_event_set_progress(ev, file_trans_on_progress, xfer); }
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)); }
/** * WebQQ login function * Step: * 1. Get webqq version * 2. Get verify code * 3. Calculate password's md5 * 4. Do real login * 5. check whether logining successfully * * @param client Lwqq Client * @param err Error code */ void lwqq_login(LwqqClient *client, LwqqStatus status,LwqqErrorCode *err) { if (!client || !status) { lwqq_log(LOG_ERROR, "Invalid pointer\n"); return ; } client->stat = status; lwqq_puts("[login stage 1:get webqq version]\n"); /* First: get webqq version */ LwqqAsyncEvent* ev = get_version(client, err); lwqq_async_add_event_listener(ev,_C_(p,login_stage_2,ev)); }
static void recv_file_init(PurpleXfer* xfer) { qq_account* ac = purple_connection_get_protocol_data(purple_account_get_connection(xfer->account)); LwqqClient* lc = ac->qq; LwqqMsgFileMessage* file = xfer->data; const char* filename = purple_xfer_get_local_filename(xfer); xfer->start_time = time(NULL); LwqqAsyncEvent* ev = lwqq_msg_accept_file(lc,file,filename); if(ev == NULL){ lwqq_puts("file trans error "); purple_xfer_error(PURPLE_XFER_RECEIVE, ac->account, purple_xfer_get_remote_user(xfer), "接受文件失败"); purple_xfer_cancel_local(xfer); return; } lwqq_async_event_set_progress(ev,file_trans_on_progress,xfer); lwqq_async_add_event_listener(ev,_C_(p,recv_file_complete,xfer)); }
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 void recv_file_init(PurpleXfer* xfer) { qq_account* ac = purple_connection_get_protocol_data(purple_account_get_connection(xfer->account)); LwqqClient* lc = ac->qq; LwqqMsgFileMessage* file = xfer->data; const char* filename = purple_xfer_get_local_filename(xfer); xfer->start_time = time(NULL); LwqqAsyncEvent* ev = lwqq_msg_accept_file(lc,file,filename); if(ev == NULL){ lwqq_puts("file trans error "); purple_xfer_error(PURPLE_XFER_RECEIVE, ac->account, purple_xfer_get_remote_user(xfer), _("Receive file failed")); purple_xfer_cancel_local(xfer); return; } LwqqHttpRequest* req = lwqq_async_event_get_conn(ev); lwqq_http_on_progress(req, file_trans_on_progress, xfer); lwqq_http_set_option(req, LWQQ_HTTP_CANCELABLE,1L); lwqq_async_add_event_listener(ev,_C_(2p,recv_file_complete,xfer,ev)); }
void lwqq_async_add_event_chain(LwqqAsyncEvent* caller,LwqqAsyncEvent* called) { /**indeed caller->lc may be NULL when recursor */ called->lc = caller->lc; LwqqAsyncEvent_* called_ = (LwqqAsyncEvent_*)called; //cancel previous chained event if(called_->chained){ LwqqAsyncEvent_* chained_ = (LwqqAsyncEvent_*)called_->chained; vp_cancel0(chained_->cmd); } called_->chained = caller; if(caller->failcode == LWQQ_CALLBACK_SYNCED){ //when sync enabled, caller and called must finished already. //so free caller ,and do not trigger anything called->result = caller->result; called->failcode = caller->failcode; lwqq_async_event_finish(caller); }else{ lwqq_async_add_event_listener(caller,_C_(2p,on_chain,caller,called)); } }
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 send_file(LwqqAsyncEvent* event,PurpleXfer *xfer) { //now xfer is not valid. if(event->failcode != LWQQ_CALLBACK_VALID) return; qq_account* ac = purple_connection_get_protocol_data(purple_account_get_connection(xfer->account)); LwqqClient* lc = ac->qq; long errno = 0; if(event->failcode==LWQQ_CALLBACK_FAILED) { lwqq_msg_free((LwqqMsg*)xfer->data); return; } errno = lwqq_async_event_get_result(event); LwqqMsgOffFile* file = xfer->data; if(errno) { qq_sys_msg_write(ac,LWQQ_MS_BUDDY_MSG, file->super.to,"发送离线文件失败",PURPLE_MESSAGE_ERROR,time(NULL)); lwqq_msg_free((LwqqMsg*)file); purple_xfer_set_completed(xfer,1); } else { LwqqAsyncEvent* ev = lwqq_msg_send_offfile(lc,file); lwqq_async_add_event_listener(ev,_C_(2p,send_offline_file_receipt,ev,xfer)); } }
static void send_file(LwqqAsyncEvent* event,PurpleXfer *xfer) { qq_account* ac = purple_connection_get_protocol_data(purple_account_get_connection(xfer->account)); LwqqClient* lc = ac->qq; long errno = 0; if(lwqq_async_event_get_code(event)==LWQQ_CALLBACK_FAILED){ s_free(xfer->data); return; } errno = lwqq_async_event_get_result(event); LwqqMsgOffFile* file = xfer->data; //purple_xfer_unref(xfer); if(errno) { qq_sys_msg_write(ac,LWQQ_MT_BUDDY_MSG, file->to,"上传空间不足",PURPLE_MESSAGE_ERROR,time(NULL)); lwqq_msg_offfile_free(file); s_free(xfer->data); purple_xfer_set_completed(xfer,1); } else { LwqqAsyncEvent* ev = lwqq_msg_send_offfile(lc,file); lwqq_async_add_event_listener(ev,_C_(2p,send_offline_file_receipt,ev,xfer)); } }
void lwqq_async_add_event_chain(LwqqAsyncEvent* caller,LwqqAsyncEvent* called) { /**indeed caller->lc may be NULL when recursor */ called->lc = caller->lc; lwqq_async_add_event_listener(caller,_C_(2p,on_chain,caller,called)); }
void lwqq_async_add_event_chain(LwqqAsyncEvent* caller,LwqqAsyncEvent* called) { lwqq_async_add_event_listener(caller,async_call_on_chain,called); }
void lwqq_async_add_event_chain(LwqqAsyncEvent* caller,LwqqAsyncEvent* called) { called->lc = caller->lc; lwqq_async_add_event_listener(caller,_C_(2p,on_chain,caller,called)); }
void lwqq_async_add_event_chain(LwqqAsyncEvent* caller,LwqqAsyncEvent* called) { called->lc = caller->lc; lwqq_async_add_event_listener(caller,_C_(p,lwqq_async_event_finish,called)); }