int CWorldCrossserver::OnCrossClientResp(CPluto& u) { CHECK_AND_GET_RPC_FIELD(u, nSeq, uint32_t); //检查流水号对应的外系统连接是否还在 map<uint32_t, _SCrossClientInfo*>::iterator iter1 = m_InRpc.find(nSeq); if(iter1 == m_InRpc.end()) { LogWarning("CWorldCrossserver::OnCrossClientResp", "notfound_seq=%d", nSeq); return -1; } _SCrossClientInfo* pInfo = iter1 ->second; CMailBox* mb = GetServer()->GetClientMailbox(pInfo->fd); if(mb == NULL) { //外系统已经断开连接了 LogWarning("CWorldCrossserver::OnCrossClientResp", "notfoundclient_seq=%d", nSeq); return -2; } CPluto* u2 = new CPluto; u2->Encode(MSGID_CROSSCLIENT_RESP) << pInfo->sid << pInfo->etype << pInfo->eid; //转发包内容 u2->FillBuff(u.GetBuff()+u.GetLen(), u.GetMaxLen()-u.GetLen()); u2->endPluto(); mb->PushPluto(u2); //删除数据,即每个流水号只能被回调一次 delete pInfo; m_InRpc.erase(iter1); m_lsFreeRpcSeq.push_back(nSeq); //流水号重用 return 0; }
bool login_baseapp(SBaseappLoginData* bd) { if(bd == NULL) { return false; } if(this->connect(bd->m_strBase.c_str(), bd->m_unPort)) { //发送登录包 CPluto u; m_rpc.Encode(u, MSGID_BASEAPP_CLIENT_LOGIN, bd->m_strKey); write_some(u.GetBuff(), u.GetLen()); } else { return false; } //等待绑定entity(等Account转换为Avatar) #ifdef _WIN32 Sleep(100); #else Sleep(1); #endif bool bWait = true; int nWaitCount = 0; while(bWait) { CPluto* u = read_pluto(); if(u) { //T_VECTOR_OBJECT* p = m_rpc.decode(*u); //if(p) //{ // pluto_msgid_t msgid = u->getMsgId(); // if(msgid == MSGID_CLIENT_ENTITY_ATTACHED) // { // bWait = false; // printf("entity attached.\n"); // } // clear_T_LIST_OBJECT(p); //} //delete u; bWait = false; printf("entity attached.\n"); } if(++nWaitCount > 3) { bWait = false; printf("wait_timeout.\n"); } } return true; }
//模拟错误的rpc包 bool err_avatar_rpc() { //远程方法名 CDefParser& defp = GetWorld()->GetDefParser(); const SEntityDef* pDef = defp.GetEntityDefByName("Avatar"); string strFunc("UseSkillReq"); uint16_t nFunc = (uint16_t)pDef->m_baseMethodsMap.GetIntByStr(strFunc); CPluto u; u.Encode(MSGID_BASEAPP_CLIENT_RPCALL) << nFunc; //其他参数 u << (uint64_t) 1 << (uint16_t) 2 << (uint16_t)3 << (uint8_t) 4 << (uint16_t) 5 ; u << (uint8_t) 6; //error u << EndPluto; //发送 printf("send err_cmd: %s \n", strFunc.c_str()); //print_hex_pluto(u); write_some(u.GetBuff(), u.GetLen()); //收取回应包 //async_read_some(); //CPluto* u2 = read_pluto(); //delete u2; return true; }
//来自跨服的广播 int CWorldCrossclient::OnCrossClientBroadcast(CPluto& u) { //printf("CWorldCrossclient::OnCrossClientBroadcast \n"); if(m_nBcBaseappId == 0) { //挑一个baseapp来处理,挑完之后不会再变了 vector<CMailBox*>& mbs = GetServer()->GetAllServerMbs(); vector<CMailBox*>::iterator iter1 = mbs.begin(); for(; iter1 != mbs.end(); ++iter1) { CMailBox* mb2 = *iter1; if(mb2 && mb2->GetServerMbType() == SERVER_BASEAPP) { m_nBcBaseappId = mb2->GetMailboxId(); break; } } } CMailBox* mb = GetServerMailbox(m_nBcBaseappId); if(mb) { CPluto* u2 = new CPluto(u.GetBuff(), u.GetMaxLen()); u2->ReplaceField<uint16_t>(6, MSGID_BASEAPP_CROSSCLIENT_BROADCAST); mb->PushPluto(u2); } return 0; }
//随机走动 void random_move() { uint16_t x = 3016 + rand() % 300; uint16_t y = 2020 + rand() % 300; CPluto u; u.Encode(MSGID_BASEAPP_CLIENT_MOVE_REQ) << x << y << EndPluto; //u.Cryto(); write_some(u.GetBuff(), u.GetLen()); }
bool avatar_cell_rpc(const char* cmd) { list<string> ls; SplitString(cmd, '|', ls); if(ls.empty()) { printf("error rpc, empty string. \n"); return false; } //远程方法名 CDefParser& defp = GetWorld()->GetDefParser(); const SEntityDef* pDef = defp.GetEntityDefByName("Avatar"); string strFunc = ls.front(); ls.pop_front(); uint16_t nFunc = (uint16_t)pDef->m_cellMethodsMap.GetIntByStr(strFunc); CPluto u; u.Encode(MSGID_BASEAPP_CLIENT_RPC2CELL_VIA_BASE) << nFunc; //其他参数 map<string, _SEntityDefMethods*>::const_iterator iter11 = pDef->m_cellMethods.find(strFunc); if(iter11 != pDef->m_cellMethods.end()) { _SEntityDefMethods* pmethod = iter11->second; list<VTYPE>::const_iterator iter = pmethod->m_argsType.begin(); for(; iter != pmethod->m_argsType.end(); ++iter) { if(ls.empty()) { printf("error rpc, less params, %s \n", cmd); return false; } const string& sv = ls.front(); u.FillPlutoFromStr(*iter, sv.c_str(), (unsigned long)sv.size()); ls.pop_front(); } } u << EndPluto; //发送 printf("send cell cmd: %s \n", cmd); //print_hex_pluto(u); write_some(u.GetBuff(), u.GetLen()); //收取回应包 //async_read_some(); //CPluto* u2 = read_pluto(); //delete u2; return true; }
//来自原始服的跨服调用 int CWorldCrossserver::OnCrossServerRpc(CPluto& u) { //printf("CWorldCrossserver::OnCrossServerRpc 111\n"); CHECK_AND_GET_RPC_FIELD(u, uSrcServerId, uint16_t); CHECK_AND_GET_RPC_FIELD(u, etype, TENTITYTYPE); CHECK_AND_GET_RPC_FIELD(u, eid, TENTITYID); CHECK_AND_GET_RPC_FIELD(u, strGlobal, string); //CHECK_AND_GET_RPC_FIELD(u, strFuncId, uint16_t); uint32_t nSeq = GetNextRpcSeq(u, uSrcServerId, etype, eid); if(nSeq == 0) { return -1; } //printf("CWorldCrossserver::OnCrossServerRpc 222, %d - %d - %d - %s - seq =%d \n", uSrcServerId, etype, eid, strGlobal.c_str(), nSeq); map<string, CEntityMailbox*>::iterator iter1 = m_globalBases.find(strGlobal); if(iter1 == m_globalBases.end()) { return -2; } CEntityMailbox* emb = iter1->second; CMailBox* mb = GetServerMailbox(emb->m_nServerMailboxId); if(mb) { CPluto* u2 = new CPluto; u2->Encode(MSGID_BASEAPP_ENTITY_RPC) << (*emb); u2->FillBuff(u.GetBuff()+u.GetLen(), 2); //msg_id u2->FillField(nSeq); //填充流水号字段 u2->FillBuff(u.GetBuff()+u.GetLen()+2, u.GetMaxLen()-u.GetLen()-2);//copy其他字段 u2->endPluto(); mb->PushPluto(u2); return 0; } return -2; }
//将base/cell共有属性打包 bool CEntityBase::PickleCellPropsToPluto(CPluto& u1) { CPluto u; const SEntityDef* pDef = this->GetEntityDef(); if(pDef) { map<string, _SEntityDefProperties*>::const_iterator iter = pDef->m_properties.begin(); for(; iter != pDef->m_properties.end(); ++iter) { _SEntityDefProperties* p = iter->second; if(IsCellFlag(p->m_nFlags) && IsBaseFlag(p->m_nFlags)) { const string& strEntityName = iter->first; map<string, VOBJECT*>::const_iterator iter2 = m_data.find(strEntityName); if(iter2 == m_data.end()) { //todo warning... continue; } u << (uint16_t)(pDef->m_propertiesMap.GetIntByStr(iter2->first)); u.FillPluto(*(iter2->second)); } else if (IsCellFlag(p->m_nFlags)) { //如果该属性只有cell才有,则到cellData上查找 const string& strEntityName = iter->first; map<string, VOBJECT*>::iterator iter3 = m_cellData.find(strEntityName); if (iter3 != m_cellData.end()) { u << (uint16_t)(pDef->m_propertiesMap.GetIntByStr(iter3->first)); u.FillPluto(*(iter3->second)); m_cellData.erase(iter3); LogDebug("CEntityBase::PickleCellPropsToPluto cellData", "strEntityName=%s", strEntityName.c_str()); } } } //print_hex_pluto(u); } charArrayDummy ad; ad.m_l = u.GetLen(); ad.m_s = (char*)u.GetBuff(); u1 << ad; ad.m_l = 0; return pDef != NULL; }
//来自跨服的回调 int CWorldCrossclient::OnCrossClientResp(CPluto& u) { //printf("CWorldCrossclient::onCrossClientResp\n"); CHECK_AND_GET_RPC_FIELD(u, sid, uint16_t); CMailBox* mb = GetServerMailbox(sid); //printf("CWorldCrossclient::onCrossClientResp 222, sid=%d;mb=%x\n", sid, mb); if(mb) { //发回给发起调用的那个entity CPluto* u2 = new CPluto; u2->Encode(MSGID_BASEAPP_ENTITY_RPC) << sid; u2->FillBuff(u.GetBuff()+u.GetLen(), u.GetMaxLen()-u.GetLen()); u2->endPluto(); mb->PushPluto(u2); } return 0; }
//转发跨服调用 int CWorldCrossclient::OnCrossServerRpc(CPluto& u) { //跨服服务名 CHECK_AND_GET_RPC_FIELD(u, strService, string); //检查对应的跨服服务器是否已连接 CMailBox* pmb = ((CCrossclientServer*)GetServer())->GetExternMailbox(strService); if(pmb == NULL) { //外系统当前不可用,记录日志;返回错误消息也无用 LogWarning("CWorldCrossclient::OnCrossServerRpc", "extern error,%s\n", strService.c_str()); return 0; } CPluto* u2 = new CPluto; u2->Encode(MSGID_CROSSSERVER_RPC); //转发包内容 u2->FillBuff(u.GetBuff()+u.GetLen(), u.GetMaxLen()-u.GetLen()); u2->endPluto(); pmb->PushPluto(u2); return 0; }
int BroadcastClientRpc(lua_State* L) { const char* pszEntity = luaL_checkstring(L, 1); const char* pszFunc = luaL_checkstring(L, 2); world* the_world = GetWorld(); if (!the_world) { return 0; } const SEntityDef* pDef = the_world->GetDefParser().GetEntityDefByName(pszEntity); if (!pDef) { return 0; } map<string, _SEntityDefMethods*>::const_iterator iter11 = \ pDef->m_clientMethods.find(pszFunc); if(iter11 == pDef->m_clientMethods.end()) { return 0; } //把pszEntity和pszFunc从堆栈中移除掉 lua_remove(L, 1); lua_remove(L, 1); const _SEntityDefMethods* pMethods = iter11->second; const list<VTYPE>& args = pMethods->m_argsType; int nArgCount = lua_gettop(L); if(nArgCount != (int)args.size()) { return 0; } uint16_t nFuncId = (uint16_t)pDef->m_clientMethodsMap.GetIntByStr(pszFunc); CPluto* u = new CPluto; u->Encode(MSGID_BASEAPP_BROADCAST_CLIENT_PRC); (*u) << the_world->GetDefParser().GetTypeId(pszEntity) << nFuncId; //打包rpc的所有参数为一个string int idx = 0; list<VTYPE>::const_iterator iter = args.begin(); for(; iter != args.end(); ++iter) { ++idx; VTYPE vt = *iter; u->FillPlutoFromLua(vt, L, idx); } (*u) << EndPluto; the_world->GetServer()->AddLocalRpcPluto(u); vector<CMailBox*>& mbs = the_world->GetServer()->GetAllServerMbs(); vector<CMailBox*>::iterator iter2 = mbs.begin(); for(; iter2 != mbs.end(); ++iter2) { CMailBox* basemb = *iter2; if(basemb && basemb->GetServerMbType() == SERVER_BASEAPP) { //发给每个其他baseapp的mb的pluto都是发给本地进程的那个pluto的拷贝 CPluto* u2 = new CPluto(u->GetBuff(), u->GetLen()); basemb->PushPluto(u2); } } return 0; }
bool random_cell_rpc() { //远程方法名 CDefParser& defp = GetWorld()->GetDefParser(); const SEntityDef* pDef = defp.GetEntityDefByName("Avatar"); int nMaxFuncId = (int)pDef->m_cellMethods.size(); int nFunc = rand() % nMaxFuncId; const string& strFunc = pDef->m_cellMethodsMap.GetStrByInt(nFunc); ostringstream oss; oss << strFunc; CPluto u; u.Encode(MSGID_BASEAPP_CLIENT_RPC2CELL_VIA_BASE) << nFunc; //其他参数 map<string, _SEntityDefMethods*>::const_iterator iter11 = pDef->m_cellMethods.find(strFunc); if(iter11 != pDef->m_cellMethods.end()) { _SEntityDefMethods* pmethod = iter11->second; list<VTYPE>::const_iterator iter = pmethod->m_argsType.begin(); for(; iter != pmethod->m_argsType.end(); ++iter) { VTYPE vt = *iter; string sv; switch(vt) { case V_STR: sv.assign("abcd"); break; case V_INT8: case V_UINT8: case V_INT16: case V_UINT16: case V_INT32: case V_UINT32: case V_INT64: case V_UINT64: case V_FLOAT32: case V_FLOAT64: sv.assign("14"); break; case V_BLOB: sv.assign("{}"); break; default: sv.assign(""); break; } oss << "|" << sv; u.FillPlutoFromStr(*iter, sv.c_str(), (unsigned long)sv.size()); } } u << EndPluto; //发送 printf("send cell_cmd: %d %s \n", nFunc, oss.str().c_str()); //print_hex_pluto(u); write_some(u.GetBuff(), u.GetLen()); //收取回应包 //async_read_some(); //CPluto* u2 = read_pluto(); //delete u2; return true; }
SBaseappLoginData* login_account(const char* pszHost, int nPort, const char* pszAccount, const char* pszPasswd) { printf("try to login account: [ %s : %d ] [ %s ] \n", pszHost, nPort, pszAccount); if(this->connect(pszHost, nPort)) { //发送登录包 CPluto u; m_rpc.Encode(u, MSGID_LOGINAPP_LOGIN, pszAccount, pszPasswd); write_some(u.GetBuff(), u.GetLen()); } else { return NULL; } bool bWait = true; int nWaitCount = 0; SBaseappLoginData* bd = NULL; while(bWait) { CPluto* u = read_pluto(); if(u) { T_VECTOR_OBJECT* p = m_rpc.Decode(*u); if(p) { pluto_msgid_t msgid = u->GetMsgId(); if(msgid == MSGID_CLIENT_LOGIN_RESP) { uint8_t nRet = VOBJECT_GET_U8((*p)[0]); printf("login ret=%d\n", nRet); if(nRet != 0) { bWait = false; } } else if(msgid == MSGID_CLIENT_NOTIFY_ATTACH_BASEAPP) { const char* pszBaseappIp = VOBJECT_GET_STR((*p)[0]); uint16_t nBaseappPort = VOBJECT_GET_U16((*p)[1]); const char* pszKey = VOBJECT_GET_STR((*p)[2]); bd = new SBaseappLoginData; bd->m_strBase.assign(pszBaseappIp); bd->m_strKey.assign(pszKey); bd->m_unPort = nBaseappPort; bWait = false; printf("redirect to baseapp [ %s : %d ] [ %s ] \n", pszBaseappIp, nBaseappPort, pszKey); //断开到loginapp的连接 this->disconnect(); } else if(msgid == MSGID_CLIENT_NOTIFY_MULTILOGIN) { int a = 0; ++a; printf("mutlilogin, [%s] \n", pszAccount); } else { int a = 0; ++a; } ClearTListObject(p); } delete u; } else { if(++nWaitCount > 3) { return NULL; } } } return bd; }
int CWorldOther::SdkServerVerify(T_VECTOR_OBJECT* p, CPluto& u) { #if 0 //注释掉老代码 if (p->size() != 4) { return -1; } string& url = VOBJECT_GET_SSTR((*p)[0]); int32_t nFd = VOBJECT_GET_I32((*p)[1]); string& strAccount = VOBJECT_GET_SSTR((*p)[2]); string& strPlatId = VOBJECT_GET_SSTR((*p)[3]); CMailBox* pmb = u.GetMailbox(); if (NULL == pmb) { return -1; } CPluto* duplicate = new CPluto(u.GetBuff(), u.GetMaxLen()); duplicate->SetMailbox(pmb); int ret = threadpool_add_job(g_threadpool, ThreadJob_SdkServerVerify, (void*)(duplicate)); if (ret != 0) { //直接返回服务器繁忙,请稍后再试 //printf("服务器繁忙,请稍后再试!\n"); //std::cout << "服务器繁忙,请稍后再试!" << endl; LogWarning("CWorldOther::SdkServerVerify", "threadpool list is full."); CPluto* u2 = new CPluto; u2->Encode(MSGID_LOGINAPP_LOGIN_VERIFY_CALLBACK); (*u2)<< int32_t(-2) << nFd << strAccount << strPlatId << EndPluto; g_pluto_sendlist.PushPluto(u2); //不适合多线程发送 //pmb->RpcCall(GetRpcUtil(), MSGID_LOGINAPP_LOGIN_VERIFY_CALLBACK, -2, nFd, strAccount, strPlatId); } return 0; #endif if (p->size() != 4) { return -1; } string& url = VOBJECT_GET_SSTR((*p)[0]); int32_t nFd = VOBJECT_GET_I32((*p)[1]); string& strAccount = VOBJECT_GET_SSTR((*p)[2]); string& strPlatId = VOBJECT_GET_SSTR((*p)[3]); CMailBox* pmb = u.GetMailbox(); pluto_msgid_t msg_id = u.GetMsgId();; string resp = ""; int ret = GetUrl_new(url.c_str(), resp); if (ret != CURLE_OK) { LogWarning("CWorldOther::SdkServerVerify", "%s ret = %d", strAccount.c_str(), ret); //todo:faild. SyncRpcCall(g_pluto_sendlist, SERVER_LOGINAPP, MSGID_LOGINAPP_LOGIN_VERIFY_CALLBACK, ret, nFd, strAccount, strPlatId); return 0; } Trim(resp); cJSON* json = cJSON_Parse(resp.c_str()); cJSON* childJs = cJSON_GetObjectItem(json, "code"); int rst = cJSON_GetObjectItem(json, "code")->valueint; if (rst == 1) { //succeed. if (strAccount.c_str() != cJSON_GetObjectItem(json, "msg")->valuestring) { ret = 0; } else { LogWarning("CWorldOther::SdkServerVerify", "strAccount[%s] msg[%s]", strAccount.c_str(), cJSON_GetObjectItem(json, "msg")->valuestring); ret = 1; //pmb->RpcCall(GetRpcUtil(), MSGID_LOGINAPP_LOGIN_VERIFY_CALLBACK, int32_t(1), nFd, strAccount, strPlatId); } } else { //failed. LogWarning("CWorldOther::SdkServerVerify", "strAccount[%s] rst[%d]", strAccount.c_str(), rst); ret = -1; //pmb->RpcCall(GetRpcUtil(), MSGID_LOGINAPP_LOGIN_VERIFY_CALLBACK, -1, nFd, strAccount, strPlatId); } SyncRpcCall(g_pluto_sendlist, SERVER_LOGINAPP, MSGID_LOGINAPP_LOGIN_VERIFY_CALLBACK, ret, nFd, strAccount, strPlatId); return 0; }