//------------------------------------------------------------------------------------- void Components::removeComponentFromChannel(Mercury::Channel * pChannel) { int ifind = 0; while(ALL_COMPONENT_TYPES[ifind] != UNKNOWN_COMPONENT_TYPE) { COMPONENT_TYPE componentType = ALL_COMPONENT_TYPES[ifind++]; COMPONENTS& components = getComponents(componentType); COMPONENTS::iterator iter = components.begin(); for(; iter != components.end();) { if((*iter).pChannel == pChannel) { //SAFE_RELEASE((*iter).pIntAddr); //SAFE_RELEASE((*iter).pExtAddr); // (*iter).pChannel->decRef(); WARNING_MSG(boost::format("Components::removeComponentFromChannel: %1% : %2%.\n") % COMPONENT_NAME_EX(componentType) % (*iter).cid); #if KBE_PLATFORM == PLATFORM_WIN32 printf("[WARNING]: %s.\n", (boost::format("Components::removeComponentFromChannel: %1% : %2%.\n") % COMPONENT_NAME_EX(componentType) % (*iter).cid).str().c_str()); #endif iter = components.erase(iter); return; } else iter++; } } // KBE_ASSERT(false && "channel is not found!\n"); }
//------------------------------------------------------------------------------------- void Components::delComponent(int32 uid, COMPONENT_TYPE componentType, COMPONENT_ID componentID, bool ignoreComponentID, bool shouldShowLog) { COMPONENTS& components = getComponents(componentType); COMPONENTS::iterator iter = components.begin(); for(; iter != components.end();) { if((uid < 0 || (*iter).uid == uid) && (ignoreComponentID == true || (*iter).cid == componentID)) { INFO_MSG(fmt::format("Components::delComponent[{}] componentID={}, component:totalcount={}.\n", COMPONENT_NAME_EX(componentType), componentID, components.size())); ComponentInfos* componentInfos = &(*iter); //SAFE_RELEASE((*iter).pIntAddr); //SAFE_RELEASE((*iter).pExtAddr); //(*iter).pChannel->decRef(); if(_pHandler) _pHandler->onRemoveComponent(componentInfos); iter = components.erase(iter); if(!ignoreComponentID) return; } else iter++; } if(shouldShowLog) { ERROR_MSG(fmt::format("Components::delComponent::not found [{}] component:totalcount:{}\n", COMPONENT_NAME_EX(componentType), components.size())); } }
//------------------------------------------------------------------------------------- void Components::removeComponentByChannel(Network::Channel * pChannel, bool isShutingdown) { int ifind = 0; while(ALL_COMPONENT_TYPES[ifind] != UNKNOWN_COMPONENT_TYPE) { COMPONENT_TYPE componentType = ALL_COMPONENT_TYPES[ifind++]; COMPONENTS& components = getComponents(componentType); COMPONENTS::iterator iter = components.begin(); for(; iter != components.end();) { if((*iter).pChannel == pChannel) { //SAFE_RELEASE((*iter).pIntAddr); //SAFE_RELEASE((*iter).pExtAddr); // (*iter).pChannel->decRef(); if (!isShutingdown && g_componentType != LOGGER_TYPE) { ERROR_MSG(fmt::format("Components::removeComponentByChannel: {} : {}, Abnormal exit! {}\n", COMPONENT_NAME_EX(componentType), (*iter).cid, kbe_strerror())); #if KBE_PLATFORM == PLATFORM_WIN32 printf("[ERROR]: %s.\n", (fmt::format("Components::removeComponentByChannel: {} : {}, Abnormal exit! {}\n", COMPONENT_NAME_EX(componentType), (*iter).cid, kbe_strerror())).c_str()); #endif } else { INFO_MSG(fmt::format("Components::removeComponentByChannel: {} : {}, Normal exit!\n", COMPONENT_NAME_EX(componentType), (*iter).cid)); } ComponentInfos* componentInfos = &(*iter); if(_pHandler) _pHandler->onRemoveComponent(componentInfos); iter = components.erase(iter); return; } else iter++; } } // KBE_ASSERT(false && "channel is not found!\n"); }
//------------------------------------------------------------------------------------- bool Components::checkComponents(int32 uid, COMPONENT_ID componentID, uint32 pid) { if(componentID <= 0) return true; int idx = 0; while(true) { COMPONENT_TYPE ct = ALL_COMPONENT_TYPES[idx++]; if(ct == UNKNOWN_COMPONENT_TYPE) break; ComponentInfos* cinfos = findComponent(ct, uid, componentID); if(cinfos != NULL) { if(cinfos->componentType != MACHINE_TYPE && cinfos->pid != 0 /* 等于0通常是预设, 这种情况我们先不作比较 */ && pid != cinfos->pid) { ERROR_MSG(fmt::format("Components::checkComponents: uid:{}, componentType={}, componentID:{} exist.\n", uid, COMPONENT_NAME_EX(ct), componentID)); KBE_ASSERT(false && "Components::checkComponents: componentID exist.\n"); } return false; } } return true; }
//------------------------------------------------------------------------------------- void ServerApp::onAppActiveTick(Network::Channel* pChannel, COMPONENT_TYPE componentType, COMPONENT_ID componentID) { if(componentType != CLIENT_TYPE) if(pChannel->isExternal()) return; Network::Channel* pTargetChannel = NULL; if(componentType != CONSOLE_TYPE && componentType != CLIENT_TYPE) { Components::ComponentInfos* cinfos = Components::getSingleton().findComponent(componentType, KBEngine::getUserUID(), componentID); if(cinfos == NULL || cinfos->pChannel == NULL) { ERROR_MSG(fmt::format("ServerApp::onAppActiveTick[{:p}]: {}:{} not found.\n", (void*)pChannel, COMPONENT_NAME_EX(componentType), componentID)); return; } pTargetChannel = cinfos->pChannel; pTargetChannel->updateLastReceivedTime(); } else { pChannel->updateLastReceivedTime(); pTargetChannel = pChannel; } //DEBUG_MSG("ServerApp::onAppActiveTick[%x]: %s:%"PRAppID" lastReceivedTime:%"PRIu64" at %s.\n", // pChannel, COMPONENT_NAME_EX(componentType), componentID, pChannel->lastReceivedTime(), pTargetChannel->c_str()); }
//------------------------------------------------------------------------------------- void ServerApp::onAppActiveTick(Mercury::Channel* pChannel, COMPONENT_TYPE componentType, COMPONENT_ID componentID) { if(componentType != CLIENT_TYPE) if(pChannel->isExternal()) return; Mercury::Channel* pTargetChannel = NULL; if(componentType != CONSOLE_TYPE && componentType != CLIENT_TYPE) { Components::ComponentInfos* cinfos = Componentbridge::getComponents().findComponent(componentType, KBEngine::getUserUID(), componentID); if(cinfos == NULL || cinfos->pChannel == NULL) { ERROR_MSG(boost::format("ServerApp::onAppActiveTick[%1%]: %2%:%3% not found.\n") % pChannel % COMPONENT_NAME_EX(componentType) % componentID); return; } pTargetChannel = cinfos->pChannel; pTargetChannel->updateLastReceivedTime(); } else { pChannel->updateLastReceivedTime(); pTargetChannel = pChannel; } //DEBUG_MSG("ServerApp::onAppActiveTick[%x]: %s:%"PRAppID" lastReceivedTime:%"PRIu64" at %s.\n", // pChannel, COMPONENT_NAME_EX(componentType), componentID, pChannel->lastReceivedTime(), pTargetChannel->c_str()); }
//------------------------------------------------------------------------------------- void ServerApp::onIdentityillegal(COMPONENT_TYPE componentType, COMPONENT_ID componentID, uint32 pid, const char* pAddr) { ERROR_MSG(fmt::format("ServerApp::onIdentityillegal: The current process and {}(componentID={} ->conflicted???, pid={}, addr={}) conflict, the process will exit!\n", COMPONENT_NAME_EX((COMPONENT_TYPE)componentType), componentID, pid, pAddr)); this->shutDown(1.f); }
//------------------------------------------------------------------------------------- void Components::removeComponentFromChannel(Mercury::Channel * pChannel) { int ifind = 0; while(ALL_COMPONENT_TYPES[ifind] != UNKNOWN_COMPONENT_TYPE) { COMPONENT_TYPE componentType = ALL_COMPONENT_TYPES[ifind++]; COMPONENTS& components = getComponents(componentType); COMPONENTS::iterator iter = components.begin(); for(; iter != components.end();) { if((*iter).pChannel == pChannel) { //SAFE_RELEASE((*iter).pIntAddr); //SAFE_RELEASE((*iter).pExtAddr); // (*iter).pChannel->decRef(); WARNING_MSG("Components::removeComponentFromChannel: %s : %"PRAppID".\n", COMPONENT_NAME_EX(componentType), (*iter).cid); iter = components.erase(iter); return; } else iter++; } } // KBE_ASSERT(false && "channel is not found!\n"); }
//------------------------------------------------------------------------------------- void Messagelog::writeLog(Mercury::Channel* pChannel, KBEngine::MemoryStream& s) { uint32 logtype; COMPONENT_TYPE componentType = UNKNOWN_COMPONENT_TYPE; COMPONENT_ID componentID = 0; COMPONENT_ORDER componentOrder = 0; int64 t; GAME_TIME kbetime = 0; std::string str; std::stringstream logstream; s >> logtype; s >> componentType; s >> componentID; s >> componentOrder; s >> t >> kbetime; s >> str; time_t tt = static_cast<time_t>(t); tm* aTm = localtime(&tt); // YYYY year // MM month (2 digits 01-12) // DD day (2 digits 01-31) // HH hour (2 digits 00-23) // MM minutes (2 digits 00-59) // SS seconds (2 digits 00-59) if(aTm == NULL) { ERROR_MSG("Messagelog::writeLog: log is error!\n"); return; } char timebuf[MAX_BUF]; kbe_snprintf(timebuf, MAX_BUF, " [%-4d-%02d-%02d %02d:%02d:%02d %02d] ", aTm->tm_year+1900, aTm->tm_mon+1, aTm->tm_mday, aTm->tm_hour, aTm->tm_min, aTm->tm_sec, kbetime); logstream << KBELOG_TYPE_NAME_EX(logtype); logstream << " "; logstream << COMPONENT_NAME_EX_1(componentType); logstream << " "; logstream << componentID; logstream << " "; logstream << (int)componentOrder; logstream << timebuf; logstream << "- "; logstream << str; DebugHelper::getSingleton().changeLogger(COMPONENT_NAME_EX(componentType)); PRINT_MSG(logstream.str()); DebugHelper::getSingleton().changeLogger("default"); LOG_WATCHERS::iterator iter = logWatchers_.begin(); for(; iter != logWatchers_.end(); iter++) { iter->second.onMessage(logtype, componentType, componentID, componentOrder, t, kbetime, str, logstream); } }
//------------------------------------------------------------------------------------- void DebugHelper::initHelper(COMPONENT_TYPE componentType) { #ifndef NO_USE_LOG4CXX g_logger = log4cxx::Logger::getLogger(COMPONENT_NAME_EX(componentType)); char helpConfig[256]; if(componentType == CLIENT_TYPE) { kbe_snprintf(helpConfig, 256, "log4j.properties"); } else { kbe_snprintf(helpConfig, 256, "server/log4cxx_properties/%s.properties", COMPONENT_NAME_EX(componentType)); } log4cxx::PropertyConfigurator::configure(Resmgr::getSingleton().matchRes(helpConfig).c_str()); #endif }
void EntityApp<E>::onSignalled(int sigNum) { this->ServerApp::onSignalled(sigNum); switch (sigNum) { case SIGQUIT: CRITICAL_MSG(boost::format("Received QUIT signal. This is likely caused by the " "%1%Mgr killing this %2% because it has been " "unresponsive for too long. Look at the callstack from " "the core dump to find the likely cause.\n") % COMPONENT_NAME_EX(componentType_) % COMPONENT_NAME_EX(componentType_) ); break; default: break; } }
//------------------------------------------------------------------------------------- void Machine::onFindInterfaceAddr(Mercury::Channel* pChannel, int32 uid, std::string& username, int8 componentType, int8 findComponentType, uint32 finderAddr, uint16 finderRecvPort) { INFO_MSG("Machine::onFindInterfaceAddr: uid:%d, username:%s, componentType:%s, " "find:%s, finderaddr:%s, finderRecvPort:%u.\n", uid, username.c_str(), COMPONENT_NAME_EX((COMPONENT_TYPE)componentType), COMPONENT_NAME_EX((COMPONENT_TYPE)findComponentType), inet_ntoa((struct in_addr&)finderAddr), ntohs(finderRecvPort)); Mercury::EndPoint ep; ep.socket(SOCK_DGRAM); if (!ep.good()) { ERROR_MSG("Machine::onFindInterfaceAddr: Failed to create socket.\n"); return; } const Components::ComponentInfos* pinfos = Componentbridge::getComponents().findComponent((KBEngine::COMPONENT_TYPE)findComponentType, uid, 0); Mercury::Bundle bundle; if(pinfos == NULL) { WARNING_MSG("Machine::onFindInterfaceAddr: %s not found %s.\n", COMPONENT_NAME_EX((COMPONENT_TYPE)componentType), COMPONENT_NAME_EX((COMPONENT_TYPE)findComponentType)); MachineInterface::onBroadcastInterfaceArgs8::staticAddToBundle(bundle, 0, "", UNKNOWN_COMPONENT_TYPE, 0, 0, 0, 0, 0); } else MachineInterface::onBroadcastInterfaceArgs8::staticAddToBundle(bundle, pinfos->uid, pinfos->username, findComponentType, pinfos->cid, pinfos->pIntAddr->ip, pinfos->pIntAddr->port, pinfos->pExtAddr->ip, pinfos->pExtAddr->port); if(finderAddr != 0 && finderRecvPort != 0) bundle.sendto(ep, finderRecvPort, finderAddr); else bundle.send(this->getNetworkInterface(), pChannel); }
void StatusWindow::addApp(Components::ComponentInfos& cinfos) { std::stringstream stream; stream << cinfos.cid; CString str; std::string tstr; stream >> tstr; wchar_t* ws = KBEngine::strutil::char2wchar(tstr.c_str()); str = ws; free(ws); bool found = false; for(int icount = 0; icount < m_statusList.GetItemCount(); icount++) { CString s = m_statusList.GetItemText(icount, 2); if(str == s) { found = true; break; } } if(!found) { CString suid; suid.Format(L"%u", cinfos.uid); m_statusList.InsertItem(0, suid); static int ndata = 0; m_statusList.SetItemData(0, ndata++); CString cname; ws = KBEngine::strutil::char2wchar(COMPONENT_NAME_EX(cinfos.componentType)); cname = ws; free(ws); m_statusList.SetItemText(0, 1, cname); m_statusList.SetItemText(0, 2, str); ws = KBEngine::strutil::char2wchar(cinfos.pIntAddr->c_str()); str = ws; free(ws); m_statusList.SetItemText(0, 7, str); ws = KBEngine::strutil::char2wchar(cinfos.username); str = ws; free(ws); m_statusList.SetItemText(0, 8, str); } }
//------------------------------------------------------------------------------------- void EntityMailbox::c_str(char* s, size_t size) { const char * mailboxName = (type_ == MAILBOX_TYPE_CELL) ? "Cell" : (type_ == MAILBOX_TYPE_BASE) ? "Base" : (type_ == MAILBOX_TYPE_CLIENT) ? "Client" : (type_ == MAILBOX_TYPE_BASE_VIA_CELL) ? "BaseViaCell" : (type_ == MAILBOX_TYPE_CLIENT_VIA_CELL) ? "ClientViaCell" : (type_ == MAILBOX_TYPE_CELL_VIA_BASE) ? "CellViaBase" : (type_ == MAILBOX_TYPE_CLIENT_VIA_BASE) ? "ClientViaBase" : "???"; Network::Channel* pChannel = getChannel(); kbe_snprintf(s, size, "%s id:%d, utype:%u, component=%s[%" PRIu64 "], addr: %s.", mailboxName, id_, utype_, COMPONENT_NAME_EX(ENTITY_MAILBOX_COMPONENT_TYPE_MAPPING[type_]), componentID_, (pChannel && pChannel->pEndPoint()) ? pChannel->addr().c_str() : "None"); }
//------------------------------------------------------------------------------------- void Dbmgr::onGlobalDataClientLogon(Mercury::Channel* pChannel, COMPONENT_TYPE componentType) { if(BASEAPP_TYPE == componentType) { pBaseAppData_->onGlobalDataClientLogon(pChannel, componentType); pGlobalData_->onGlobalDataClientLogon(pChannel, componentType); } else if(CELLAPP_TYPE == componentType) { pGlobalData_->onGlobalDataClientLogon(pChannel, componentType); pCellAppData_->onGlobalDataClientLogon(pChannel, componentType); } else { ERROR_MSG(boost::format("Dbmgr::onGlobalDataClientLogon: nonsupport %1%!\n") % COMPONENT_NAME_EX(componentType)); } }
//------------------------------------------------------------------------------------- void Machine::onBroadcastInterface(Mercury::Channel* pChannel, int32 uid, std::string& username, int8 componentType, uint64 componentID, uint32 intaddr, uint16 intport, uint32 extaddr, uint16 extport) { if(componentType == MACHINE_TYPE) { if(uid == getUserUID() && intaddr == this->getNetworkInterface().intaddr().ip) { return; } } else if(componentType == DBMGR_TYPE) // 如果是dbmgr重启了则清空所有这个uid的记录。 { const Components::ComponentInfos* pinfos = Componentbridge::getComponents().findComponent(DBMGR_TYPE, uid, componentID); // 做一个容错处理, windows下没做处理, 广播包会受到多次, linux不会出现。 // 将来会对windows进行下机制进行调整此处则不会出现不会NULL。 if(pinfos == NULL) { INFO_MSG("Machine::onBroadcastInterface: /-----------------------------reset kbengine.-------------------------/\n"); Componentbridge::getComponents().clear(uid); INFO_MSG("Machine::onBroadcastInterface: /-----------------------------end reset kbengine.---------------------/\n"); } else { return; } } INFO_MSG("Machine::onBroadcastInterface: uid:%d, username:%s, componentType:%s, " "componentID:%"PRAppID", intaddr:%s, intport:%u, extaddr:%s, extport:%u.\n", uid, username.c_str(), COMPONENT_NAME_EX((COMPONENT_TYPE)componentType), componentID, inet_ntoa((struct in_addr&)intaddr), ntohs(intport), extaddr != 0 ? inet_ntoa((struct in_addr&)extaddr) : "nonsupport", ntohs(extport)); Componentbridge::getComponents().addComponent(uid, username.c_str(), (KBEngine::COMPONENT_TYPE)componentType, componentID, intaddr, intport, extaddr, extport); }
//------------------------------------------------------------------------------------- void ServerApp::onRegisterNewApp(Mercury::Channel* pChannel, int32 uid, std::string& username, int8 componentType, uint64 componentID, int8 globalorderID, int8 grouporderID, uint32 intaddr, uint16 intport, uint32 extaddr, uint16 extport, std::string& extaddrEx) { if(pChannel->isExternal()) return; INFO_MSG(boost::format("ServerApp::onRegisterNewApp: uid:%1%, username:%2%, componentType:%3%, " "componentID:%4%, globalorderID=%10%, grouporderID=%11%, intaddr:%5%, intport:%6%, extaddr:%7%, extport:%8%, from %9%.\n") % uid % username.c_str() % COMPONENT_NAME_EX((COMPONENT_TYPE)componentType) % componentID % inet_ntoa((struct in_addr&)intaddr) % ntohs(intport) % (extaddr != 0 ? inet_ntoa((struct in_addr&)extaddr) : "nonsupport") % ntohs(extport) % pChannel->c_str() % ((int32)globalorderID) % ((int32)grouporderID)); Components::ComponentInfos* cinfos = Componentbridge::getComponents().findComponent(( KBEngine::COMPONENT_TYPE)componentType, uid, componentID); pChannel->componentID(componentID); if(cinfos == NULL) { Componentbridge::getComponents().addComponent(uid, username.c_str(), (KBEngine::COMPONENT_TYPE)componentType, componentID, globalorderID, grouporderID, intaddr, intport, extaddr, extport, extaddrEx, 0, 0.f, 0.f, 0, 0, 0, 0, 0, pChannel); } else { KBE_ASSERT(cinfos->pIntAddr->ip == intaddr && cinfos->pIntAddr->port == intport); cinfos->pChannel = pChannel; } }
//------------------------------------------------------------------------------------- void ServerApp::onRegisterNewApp(Network::Channel* pChannel, int32 uid, std::string& username, COMPONENT_TYPE componentType, COMPONENT_ID componentID, COMPONENT_ORDER globalorderID, COMPONENT_ORDER grouporderID, uint32 intaddr, uint16 intport, uint32 extaddr, uint16 extport, std::string& extaddrEx) { if(pChannel->isExternal()) return; INFO_MSG(fmt::format("ServerApp::onRegisterNewApp: uid:{0}, username:{1}, componentType:{2}, " "componentID:{3}, globalorderID={9}, grouporderID={10}, intaddr:{4}, intport:{5}, extaddr:{6}, extport:{7}, from {8}.\n", uid, username.c_str(), COMPONENT_NAME_EX((COMPONENT_TYPE)componentType), componentID, inet_ntoa((struct in_addr&)intaddr), ntohs(intport), (extaddr != 0 ? inet_ntoa((struct in_addr&)extaddr) : "nonsupport"), ntohs(extport), pChannel->c_str(), ((int32)globalorderID), ((int32)grouporderID))); Components::ComponentInfos* cinfos = Components::getSingleton().findComponent(( KBEngine::COMPONENT_TYPE)componentType, uid, componentID); pChannel->componentID(componentID); if(cinfos == NULL) { Components::getSingleton().addComponent(uid, username.c_str(), (KBEngine::COMPONENT_TYPE)componentType, componentID, globalorderID, grouporderID, intaddr, intport, extaddr, extport, extaddrEx, 0, 0.f, 0.f, 0, 0, 0, 0, 0, pChannel); } else { KBE_ASSERT(cinfos->pIntAddr->ip == intaddr && cinfos->pIntAddr->port == intport); cinfos->pChannel = pChannel; } }
//------------------------------------------------------------------------------------- void ServerApp::reqKillServer(Network::Channel* pChannel, MemoryStream& s) { if(pChannel->isExternal()) return; COMPONENT_ID componentID; COMPONENT_TYPE componentType; std::string username; int32 uid; std::string reason; s >> componentID >> componentType >> username >> uid >> reason; INFO_MSG(fmt::format("ServerApp::reqKillServer: requester(uid:{}, username:{}, componentType:{}, " "componentID:{}, reason:{}, from {})\n", uid, username, COMPONENT_NAME_EX((COMPONENT_TYPE)componentType), componentID, reason, pChannel->c_str())); CRITICAL_MSG("The application was killed!\n"); }
//------------------------------------------------------------------------------------- PyObject* ClientEntityMethod::callmethod(PyObject* args, PyObject* kwds) { Entity* srcEntity = Cellapp::getSingleton().findEntity(srcEntityID_); if(srcEntity == NULL) { PyErr_Format(PyExc_AssertionError, "Entity::clientEntity(%s): srcEntityID(%d) not found!\n", methodDescription_->getName(), srcEntityID_); PyErr_PrintEx(0); return 0; } if(srcEntity->isDestroyed()) { PyErr_Format(PyExc_AssertionError, "Entity::clientEntity(%s): srcEntityID(%d) is destroyed!\n", methodDescription_->getName(), srcEntityID_); PyErr_PrintEx(0); return 0; } if(!srcEntity->isReal()) { PyErr_Format(PyExc_AssertionError, "%s::clientEntity(%s): not is real entity, srcEntityID(%d).\n", srcEntity->scriptName(), methodDescription_->getName(), srcEntity->id()); PyErr_PrintEx(0); return 0; } if(srcEntity->pWitness() == NULL) { PyErr_Format(PyExc_AssertionError, "%s::clientEntity(%s): no client, srcEntityID(%d).\n", srcEntity->scriptName(), methodDescription_->getName(), srcEntity->id()); PyErr_PrintEx(0); return 0; } Network::Channel* pChannel = srcEntity->pWitness()->pChannel(); if(!pChannel) { PyErr_Format(PyExc_AssertionError, "%s::clientEntity(%s): no client, srcEntityID(%d).\n", srcEntity->scriptName(), methodDescription_->getName(), srcEntity->id()); PyErr_PrintEx(0); return 0; } EntityRef* pEntityRef = srcEntity->pWitness()->getAOIEntityRef(clientEntityID_); Entity* e = (pEntityRef && ((pEntityRef->flags() & (ENTITYREF_FLAG_ENTER_CLIENT_PENDING | ENTITYREF_FLAG_LEAVE_CLIENT_PENDING)) <= 0)) ? pEntityRef->pEntity() : NULL; if(e == NULL) { PyErr_Format(PyExc_AssertionError, "%s::clientEntity(%s): not found entity(%d), srcEntityID(%d).\n", srcEntity->scriptName(), methodDescription_->getName(), clientEntityID_, srcEntity->id()); PyErr_PrintEx(0); return 0; } MethodDescription* methodDescription = getDescription(); if(methodDescription->checkArgs(args)) { MemoryStream* mstream = MemoryStream::createPoolObject(); methodDescription->addToStream(mstream, args); Network::Bundle* pSendBundle = pChannel->createSendBundle(); NETWORK_ENTITY_MESSAGE_FORWARD_CLIENT_START(srcEntity->id(), (*pSendBundle)); int ialiasID = -1; const Network::MessageHandler& msgHandler = srcEntity->pWitness()->getAOIEntityMessageHandler(ClientInterface::onRemoteMethodCall, ClientInterface::onRemoteMethodCallOptimized, clientEntityID_, ialiasID); ENTITY_MESSAGE_FORWARD_CLIENT_START(pSendBundle, msgHandler, aOIEntityMessage); if(ialiasID != -1) { KBE_ASSERT(msgHandler.msgID == ClientInterface::onRemoteMethodCallOptimized.msgID); (*pSendBundle) << (uint8)ialiasID; } else { KBE_ASSERT(msgHandler.msgID == ClientInterface::onRemoteMethodCall.msgID); (*pSendBundle) << clientEntityID_; } if(mstream->wpos() > 0) (*pSendBundle).append(mstream->data(), (int)mstream->wpos()); if(Network::g_trace_packet > 0) { if(Network::g_trace_packet_use_logfile) DebugHelper::getSingleton().changeLogger("packetlogs"); DEBUG_MSG(fmt::format("ClientEntityMethod::callmethod: pushUpdateData: ClientInterface::onRemoteOtherEntityMethodCall({}::{})\n", srcEntity->scriptName(), methodDescription->getName())); switch(Network::g_trace_packet) { case 1: mstream->hexlike(); break; case 2: mstream->textlike(); break; default: mstream->print_storage(); break; }; if(Network::g_trace_packet_use_logfile) DebugHelper::getSingleton().changeLogger(COMPONENT_NAME_EX(g_componentType)); } ENTITY_MESSAGE_FORWARD_CLIENT_END(pSendBundle, msgHandler, aOIEntityMessage); // 记录这个事件产生的数据量大小 g_publicClientEventHistoryStats.trackEvent(srcEntity->scriptName(), (std::string(e->scriptName()) + "." + methodDescription->getName()), pSendBundle->currMsgLength(), "::"); srcEntity->pWitness()->sendToClient(ClientInterface::onRemoteMethodCallOptimized, pSendBundle); MemoryStream::reclaimPoolObject(mstream); } S_Return; }
int kbeMainT(int argc, char * argv[], COMPONENT_TYPE componentType, int32 extlisteningPort_min = -1, int32 extlisteningPort_max = -1, const char * extlisteningInterface = "", int32 intlisteningPort = 0, const char * intlisteningInterface = "") { setEvns(); startLeakDetection(componentType, g_componentID); g_componentType = componentType; DebugHelper::initHelper(componentType); INFO_MSG( "-----------------------------------------------------------------------------------------\n\n\n"); #ifdef USE_OPENSSL KBEKey kbekey(Resmgr::getSingleton().matchPath("key/") + "kbengine_public.key", Resmgr::getSingleton().matchPath("key/") + "kbengine_private.key"); #endif Resmgr::getSingleton().print(); Mercury::EventDispatcher dispatcher; DebugHelper::getSingleton().pDispatcher(&dispatcher); const ChannelCommon& channelCommon = g_kbeSrvConfig.channelCommon(); Mercury::g_SOMAXCONN = g_kbeSrvConfig.tcp_SOMAXCONN(g_componentType); Mercury::NetworkInterface networkInterface(&dispatcher, extlisteningPort_min, extlisteningPort_max, extlisteningInterface, channelCommon.extReadBufferSize, channelCommon.extWriteBufferSize, (intlisteningPort != -1) ? htons(intlisteningPort) : -1, intlisteningInterface, channelCommon.intReadBufferSize, channelCommon.intWriteBufferSize); DebugHelper::getSingleton().pNetworkInterface(&networkInterface); g_kbeSrvConfig.updateInfos(true, componentType, g_componentID, networkInterface.intaddr(), networkInterface.extaddr()); if(getUserUID() <= 0) { WARNING_MSG(boost::format("invalid UID(%1%) <= 0, please check UID for environment!\n") % getUserUID()); } Componentbridge* pComponentbridge = new Componentbridge(networkInterface, componentType, g_componentID); SERVER_APP app(dispatcher, networkInterface, componentType, g_componentID); START_MSG(COMPONENT_NAME_EX(componentType), g_componentID); if(!app.initialize()) { ERROR_MSG("app::initialize() is error!\n"); SAFE_RELEASE(pComponentbridge); app.finalise(); return -1; } INFO_MSG(boost::format("---- %1% is running ----\n") % COMPONENT_NAME_EX(componentType)); #if KBE_PLATFORM == PLATFORM_WIN32 printf("[INFO]: %s", (boost::format("---- %1% is running ----\n") % COMPONENT_NAME_EX(componentType)).str().c_str()); wchar_t exe_path[MAX_PATH]; memset(exe_path, 0, MAX_PATH * sizeof(wchar_t)); GetCurrentDirectory(MAX_PATH, exe_path); char* ccattr = strutil::wchar2char(exe_path); printf("Writing to: %s/logs/%s.*.log\n\n", ccattr, COMPONENT_NAME_EX(componentType)); free(ccattr); #endif int ret = app.run(); SAFE_RELEASE(pComponentbridge); app.finalise(); INFO_MSG(boost::format("%1%(%2%) has shut down.\n") % COMPONENT_NAME_EX(componentType) % g_componentID); return ret; }
//------------------------------------------------------------------------------------- int Components::connectComponent(COMPONENT_TYPE componentType, int32 uid, COMPONENT_ID componentID, bool printlog) { Components::ComponentInfos* pComponentInfos = findComponent(componentType, uid, componentID); if (pComponentInfos == NULL) { if (printlog) { ERROR_MSG(fmt::format("Components::connectComponent: not found componentType={}, uid={}, componentID={}!\n", COMPONENT_NAME_EX(componentType), uid, componentID)); } return -1; } Network::EndPoint * pEndpoint = Network::EndPoint::createPoolObject(); pEndpoint->socket(SOCK_STREAM); if (!pEndpoint->good()) { if (printlog) { ERROR_MSG("Components::connectComponent: couldn't create a socket\n"); } Network::EndPoint::reclaimPoolObject(pEndpoint); return -1; } pEndpoint->addr(*pComponentInfos->pIntAddr); int ret = pEndpoint->connect(pComponentInfos->pIntAddr->port, pComponentInfos->pIntAddr->ip); if(ret == 0) { Network::Channel* pChannel = Network::Channel::createPoolObject(); bool ret = pChannel->initialize(*_pNetworkInterface, pEndpoint, Network::Channel::INTERNAL); if(!ret) { if (printlog) { ERROR_MSG(fmt::format("Components::connectComponent: initialize({}) is failed!\n", pChannel->c_str())); } pChannel->destroy(); Network::Channel::reclaimPoolObject(pChannel); return -1; } pComponentInfos->pChannel = pChannel; pComponentInfos->pChannel->componentID(componentID); if(!_pNetworkInterface->registerChannel(pComponentInfos->pChannel)) { if (printlog) { ERROR_MSG(fmt::format("Components::connectComponent: registerChannel({}) is failed!\n", pComponentInfos->pChannel->c_str())); } pComponentInfos->pChannel->destroy(); Network::Channel::reclaimPoolObject(pComponentInfos->pChannel); // 此时不可强制释放内存,destroy中已经对其减引用 // SAFE_RELEASE(pComponentInfos->pChannel); pComponentInfos->pChannel = NULL; return -1; } else { Network::Bundle* pBundle = Network::Bundle::createPoolObject(); if(componentType == BASEAPPMGR_TYPE) { (*pBundle).newMessage(BaseappmgrInterface::onRegisterNewApp); BaseappmgrInterface::onRegisterNewAppArgs11::staticAddToBundle((*pBundle), getUserUID(), getUsername(), componentType_, componentID_, g_componentGlobalOrder, g_componentGroupOrder, _pNetworkInterface->intaddr().ip, _pNetworkInterface->intaddr().port, _pNetworkInterface->extaddr().ip, _pNetworkInterface->extaddr().port, g_kbeSrvConfig.getConfig().externalAddress); } else if(componentType == CELLAPPMGR_TYPE) { (*pBundle).newMessage(CellappmgrInterface::onRegisterNewApp); CellappmgrInterface::onRegisterNewAppArgs11::staticAddToBundle((*pBundle), getUserUID(), getUsername(), componentType_, componentID_, g_componentGlobalOrder, g_componentGroupOrder, _pNetworkInterface->intaddr().ip, _pNetworkInterface->intaddr().port, _pNetworkInterface->extaddr().ip, _pNetworkInterface->extaddr().port, g_kbeSrvConfig.getConfig().externalAddress); } else if(componentType == CELLAPP_TYPE) { (*pBundle).newMessage(CellappInterface::onRegisterNewApp); CellappInterface::onRegisterNewAppArgs11::staticAddToBundle((*pBundle), getUserUID(), getUsername(), componentType_, componentID_, g_componentGlobalOrder, g_componentGroupOrder, _pNetworkInterface->intaddr().ip, _pNetworkInterface->intaddr().port, _pNetworkInterface->extaddr().ip, _pNetworkInterface->extaddr().port, g_kbeSrvConfig.getConfig().externalAddress); } else if(componentType == BASEAPP_TYPE) { (*pBundle).newMessage(BaseappInterface::onRegisterNewApp); BaseappInterface::onRegisterNewAppArgs11::staticAddToBundle((*pBundle), getUserUID(), getUsername(), componentType_, componentID_, g_componentGlobalOrder, g_componentGroupOrder, _pNetworkInterface->intaddr().ip, _pNetworkInterface->intaddr().port, _pNetworkInterface->extaddr().ip, _pNetworkInterface->extaddr().port, g_kbeSrvConfig.getConfig().externalAddress); } else if(componentType == DBMGR_TYPE) { (*pBundle).newMessage(DbmgrInterface::onRegisterNewApp); DbmgrInterface::onRegisterNewAppArgs11::staticAddToBundle((*pBundle), getUserUID(), getUsername(), componentType_, componentID_, g_componentGlobalOrder, g_componentGroupOrder, _pNetworkInterface->intaddr().ip, _pNetworkInterface->intaddr().port, _pNetworkInterface->extaddr().ip, _pNetworkInterface->extaddr().port, g_kbeSrvConfig.getConfig().externalAddress); } else if(componentType == LOGGER_TYPE) { (*pBundle).newMessage(LoggerInterface::onRegisterNewApp); LoggerInterface::onRegisterNewAppArgs11::staticAddToBundle((*pBundle), getUserUID(), getUsername(), componentType_, componentID_, g_componentGlobalOrder, g_componentGroupOrder, _pNetworkInterface->intaddr().ip, _pNetworkInterface->intaddr().port, _pNetworkInterface->extaddr().ip, _pNetworkInterface->extaddr().port, g_kbeSrvConfig.getConfig().externalAddress); } else { KBE_ASSERT(false && "invalid componentType.\n"); } pComponentInfos->pChannel->send(pBundle); } } else { if (printlog) { ERROR_MSG(fmt::format("Components::connectComponent: connect({}) is failed! {}.\n", pComponentInfos->pIntAddr->c_str(), kbe_strerror())); } Network::EndPoint::reclaimPoolObject(pEndpoint); return -1; } return ret; }
//------------------------------------------------------------------------------------- PyObject* RealEntityMethod::callmethod(PyObject* args, PyObject* kwds) { MethodDescription* methodDescription = getDescription(); if(methodDescription->checkArgs(args)) { MemoryStream* mstream = MemoryStream::ObjPool().createObject(); methodDescription->addToStream(mstream, args); Mercury::Bundle* pForwardBundle = Mercury::Bundle::ObjPool().createObject(); (*pForwardBundle).newMessage(CellappInterface::onRemoteRealMethodCall); (*pForwardBundle) << ghostEntityID_; if(mstream->wpos() > 0) (*pForwardBundle).append(mstream->data(), mstream->wpos()); if(Mercury::g_trace_packet > 0) { if(Mercury::g_trace_packet_use_logfile) DebugHelper::getSingleton().changeLogger("packetlogs"); DEBUG_MSG(boost::format("RealEntityMethod::callmethod: pushUpdateData: CellappInterface::onRemoteRealMethodCall(%3%(%1%)::%2%)\n") % ghostEntityID_ % methodDescription->getName() % scriptName_); switch(Mercury::g_trace_packet) { case 1: mstream->hexlike(); break; case 2: mstream->textlike(); break; default: mstream->print_storage(); break; }; if(Mercury::g_trace_packet_use_logfile) DebugHelper::getSingleton().changeLogger(COMPONENT_NAME_EX(g_componentType)); } // 记录这个事件产生的数据量大小 g_publicCellEventHistoryStats.trackEvent(scriptName_, methodDescription->getName(), pForwardBundle->currMsgLength(), "::"); MemoryStream::ObjPool().reclaimObject(mstream); GhostManager* gm = Cellapp::getSingleton().pGhostManager(); if(gm) { gm->pushMessage(realCell_, pForwardBundle); } else { Mercury::Bundle::ObjPool().reclaimObject(pForwardBundle); } } S_Return; }
//------------------------------------------------------------------------------------- bool Componentbridge::findInterfaces() { int8 findComponentTypes[] = {UNKNOWN_COMPONENT_TYPE, UNKNOWN_COMPONENT_TYPE, UNKNOWN_COMPONENT_TYPE, UNKNOWN_COMPONENT_TYPE, UNKNOWN_COMPONENT_TYPE, UNKNOWN_COMPONENT_TYPE, UNKNOWN_COMPONENT_TYPE, UNKNOWN_COMPONENT_TYPE}; switch(componentType_) { case CELLAPP_TYPE: findComponentTypes[0] = MESSAGELOG_TYPE; findComponentTypes[1] = RESOURCEMGR_TYPE; findComponentTypes[2] = DBMGR_TYPE; findComponentTypes[3] = CELLAPPMGR_TYPE; findComponentTypes[4] = BASEAPPMGR_TYPE; break; case BASEAPP_TYPE: findComponentTypes[0] = MESSAGELOG_TYPE; findComponentTypes[1] = RESOURCEMGR_TYPE; findComponentTypes[2] = DBMGR_TYPE; findComponentTypes[3] = BASEAPPMGR_TYPE; findComponentTypes[4] = CELLAPPMGR_TYPE; break; case BASEAPPMGR_TYPE: findComponentTypes[0] = MESSAGELOG_TYPE; findComponentTypes[1] = DBMGR_TYPE; findComponentTypes[2] = CELLAPPMGR_TYPE; break; case CELLAPPMGR_TYPE: findComponentTypes[0] = MESSAGELOG_TYPE; findComponentTypes[1] = DBMGR_TYPE; findComponentTypes[2] = BASEAPPMGR_TYPE; break; case LOGINAPP_TYPE: findComponentTypes[0] = MESSAGELOG_TYPE; findComponentTypes[1] = DBMGR_TYPE; findComponentTypes[2] = BASEAPPMGR_TYPE; break; case DBMGR_TYPE: findComponentTypes[0] = MESSAGELOG_TYPE; break; default: if(componentType_ != MESSAGELOG_TYPE && componentType_ != MACHINE_TYPE) findComponentTypes[0] = MESSAGELOG_TYPE; break; }; int ifind = 0; srand(KBEngine::getSystemTime()); uint16 nport = KBE_PORT_START + (rand() % 1000); while(findComponentTypes[ifind] != UNKNOWN_COMPONENT_TYPE) { if(dispatcher().isBreakProcessing()) return false; int8 findComponentType = findComponentTypes[ifind]; INFO_MSG("Componentbridge::process: finding %s...\n", COMPONENT_NAME_EX((COMPONENT_TYPE)findComponentType)); Mercury::BundleBroadcast bhandler(networkInterface_, nport); if(!bhandler.good()) { KBEngine::sleep(10); nport = KBE_PORT_START + (rand() % 1000); continue; } if(bhandler.pCurrPacket() != NULL) { bhandler.pCurrPacket()->resetPacket(); } bhandler.newMessage(MachineInterface::onFindInterfaceAddr); MachineInterface::onFindInterfaceAddrArgs6::staticAddToBundle(bhandler, getUserUID(), getUsername(), componentType_, findComponentType, networkInterface_.intaddr().ip, bhandler.epListen().addr().port); if(!bhandler.broadcast()) { ERROR_MSG("Componentbridge::process: broadcast error!\n"); return false; } MachineInterface::onBroadcastInterfaceArgs8 args; if(bhandler.receive(&args, 0, 1000000)) { if(args.componentType == UNKNOWN_COMPONENT_TYPE) { //INFO_MSG("Componentbridge::process: not found %s, try again...\n", // COMPONENT_NAME_EX(findComponentType)); KBEngine::sleep(1000); // 如果是这些辅助组件没找到则跳过 if(findComponentType == MESSAGELOG_TYPE || findComponentType == RESOURCEMGR_TYPE) { WARNING_MSG("Componentbridge::process: not found %s!\n", COMPONENT_NAME_EX((COMPONENT_TYPE)findComponentType)); findComponentTypes[ifind] = -1; // 跳过标志 ifind++; } continue; } INFO_MSG("Componentbridge::process: found %s, addr:%s:%u\n", COMPONENT_NAME_EX((COMPONENT_TYPE)args.componentType), inet_ntoa((struct in_addr&)args.intaddr), ntohs(args.intaddr)); Componentbridge::getComponents().addComponent(args.uid, args.username.c_str(), (KBEngine::COMPONENT_TYPE)args.componentType, args.componentID, args.intaddr, args.intport, args.extaddr, args.extport); // 防止接收到的数据不是想要的数据 if(findComponentType == args.componentType) { ifind++; } else { ERROR_MSG("Componentbridge::process: %s not found. receive data is error!\n", COMPONENT_NAME_EX((COMPONENT_TYPE)findComponentType)); } } else { ERROR_MSG("Componentbridge::process: receive error!\n"); return false; } } ifind = 0; // 开始注册到所有的组件 while(findComponentTypes[ifind] != UNKNOWN_COMPONENT_TYPE) { if(dispatcher().isBreakProcessing()) return false; int8 findComponentType = findComponentTypes[ifind++]; if(findComponentType == -1) continue; INFO_MSG("Componentbridge::process: register self to %s...\n", COMPONENT_NAME_EX((COMPONENT_TYPE)findComponentType)); if(getComponents().connectComponent(static_cast<COMPONENT_TYPE>(findComponentType), getUserUID(), 0) != 0) { ERROR_MSG("Componentbridge::register self to %s is error!\n", COMPONENT_NAME_EX((COMPONENT_TYPE)findComponentType)); dispatcher().breakProcessing(); return false; } } return true; }
//------------------------------------------------------------------------------------- void Components::addComponent(int32 uid, const char* username, COMPONENT_TYPE componentType, COMPONENT_ID componentID, COMPONENT_ORDER globalorderid, COMPONENT_ORDER grouporderid, COMPONENT_GUS gus, uint32 intaddr, uint16 intport, uint32 extaddr, uint16 extport, std::string& extaddrEx, uint32 pid, float cpu, float mem, uint32 usedmem, uint64 extradata, uint64 extradata1, uint64 extradata2, uint64 extradata3, Network::Channel* pChannel) { COMPONENTS& components = getComponents(componentType); if(!checkComponents(uid, componentID, pid)) return; ComponentInfos* cinfos = findComponent(componentType, uid, componentID); if(cinfos != NULL) { WARNING_MSG(fmt::format("Components::addComponent[{}]: uid:{}, username:{}, " "componentType:{}, componentID:{} is exist!\n", COMPONENT_NAME_EX(componentType), uid, username, (int32)componentType, componentID)); return; } // 如果该uid下没有已经运行的任何相关组件,那么重置计数器 if (getGameSrvComponentsSize(uid) == 0) { _globalOrderLog[uid] = 0; _baseappGrouplOrderLog[uid] = 0; _cellappGrouplOrderLog[uid] = 0; _loginappGrouplOrderLog[uid] = 0; INFO_MSG(fmt::format("Components::addComponent: reset orderLog, uid={}!\n", uid)); } ComponentInfos componentInfos; componentInfos.pIntAddr.reset(new Network::Address(intaddr, intport)); componentInfos.pExtAddr.reset(new Network::Address(extaddr, extport)); if(extaddrEx.size() > 0) strncpy(componentInfos.externalAddressEx, extaddrEx.c_str(), MAX_NAME); componentInfos.uid = uid; componentInfos.cid = componentID; componentInfos.pChannel = pChannel; componentInfos.componentType = componentType; componentInfos.groupOrderid = 1; componentInfos.globalOrderid = 1; componentInfos.mem = mem; componentInfos.cpu = cpu; componentInfos.usedmem = usedmem; componentInfos.extradata = extradata; componentInfos.extradata1 = extradata1; componentInfos.extradata2 = extradata2; componentInfos.extradata3 = extradata3; componentInfos.pid = pid; if(pChannel) pChannel->componentID(componentID); strncpy(componentInfos.username, username, MAX_NAME); _globalOrderLog[uid]++; switch(componentType) { case BASEAPP_TYPE: _baseappGrouplOrderLog[uid]++; componentInfos.groupOrderid = _baseappGrouplOrderLog[uid]; break; case CELLAPP_TYPE: _cellappGrouplOrderLog[uid]++; componentInfos.groupOrderid = _cellappGrouplOrderLog[uid]; break; case LOGINAPP_TYPE: _loginappGrouplOrderLog[uid]++; componentInfos.groupOrderid = _loginappGrouplOrderLog[uid]; break; default: break; }; if(grouporderid > 0) componentInfos.groupOrderid = grouporderid; if(globalorderid > 0) componentInfos.globalOrderid = globalorderid; else componentInfos.globalOrderid = _globalOrderLog[uid]; componentInfos.gus = gus; if(cinfos == NULL) components.push_back(componentInfos); else *cinfos = componentInfos; INFO_MSG(fmt::format("Components::addComponent[{}], uid={}, " "componentID={}, globalorderid={}, grouporderid={}, totalcount={}\n", COMPONENT_NAME_EX(componentType), uid, componentID, ((int32)componentInfos.globalOrderid), ((int32)componentInfos.groupOrderid), components.size())); if(_pHandler) _pHandler->onAddComponent(&componentInfos); }
//------------------------------------------------------------------------------------- PyObject* EntityRemoteMethod::tp_call(PyObject* self, PyObject* args, PyObject* kwds) { EntityRemoteMethod* rmethod = static_cast<EntityRemoteMethod*>(self); MethodDescription* methodDescription = rmethod->getDescription(); EntityMailboxAbstract* mailbox = rmethod->getMailbox(); if(!mailbox->isClient()) { return RemoteEntityMethod::tp_call(self, args, kwds); } Entity* pEntity = Cellapp::getSingleton().findEntity(mailbox->id()); if(pEntity == NULL || pEntity->pWitness() == NULL) { //WARNING_MSG(fmt::format("EntityRemoteMethod::callClientMethod: not found entity({}).\n", // mailbox->id())); return RemoteEntityMethod::tp_call(self, args, kwds); } Network::Channel* pChannel = pEntity->pWitness()->pChannel(); if(!pChannel) { PyErr_Format(PyExc_AssertionError, "%s:EntityRemoteMethod(%s)::tp_call: no client, srcEntityID(%d).\n", pEntity->scriptName(), methodDescription->getName(), pEntity->id()); PyErr_PrintEx(0); return RemoteEntityMethod::tp_call(self, args, kwds); } // 如果是调用客户端方法, 我们记录事件并且记录带宽 if(methodDescription->checkArgs(args)) { Network::Bundle* pBundle = pChannel->createSendBundle(); mailbox->newMail((*pBundle)); MemoryStream* mstream = MemoryStream::createPoolObject(); methodDescription->addToStream(mstream, args); if(mstream->wpos() > 0) (*pBundle).append(mstream->data(), (int)mstream->wpos()); if(Network::g_trace_packet > 0) { if(Network::g_trace_packet_use_logfile) DebugHelper::getSingleton().changeLogger("packetlogs"); DEBUG_MSG(fmt::format("EntityRemoteMethod::tp_call: pushUpdateData: ClientInterface::onRemoteMethodCall({}::{})\n", pEntity->scriptName(), methodDescription->getName())); switch(Network::g_trace_packet) { case 1: mstream->hexlike(); break; case 2: mstream->textlike(); break; default: mstream->print_storage(); break; }; if(Network::g_trace_packet_use_logfile) DebugHelper::getSingleton().changeLogger(COMPONENT_NAME_EX(g_componentType)); } // 记录这个事件产生的数据量大小 g_privateClientEventHistoryStats.trackEvent(pEntity->scriptName(), methodDescription->getName(), pBundle->currMsgLength(), "::"); pEntity->pWitness()->sendToClient(ClientInterface::onRemoteMethodCall, pBundle); MemoryStream::reclaimPoolObject(mstream); } S_Return; }
//------------------------------------------------------------------------------------- void GlobalDataServer::broadcastDataChange(Mercury::Channel* pChannel, COMPONENT_TYPE componentType, const std::string& key, const std::string& value, bool isDelete) { INFO_MSG(boost::format("GlobalDataServer::broadcastDataChange: writer(%1%), key_size=%2%, val_size=%3%, isdelete=%4%.\n") % COMPONENT_NAME_EX(componentType) % key.size() % value.size() % (int)isDelete); std::vector<COMPONENT_TYPE>::iterator iter = concernComponentTypes_.begin(); for(; iter != concernComponentTypes_.end(); iter++) { COMPONENT_TYPE ct = (*iter); Components::COMPONENTS& channels = Components::getSingleton().getComponents(ct); Components::COMPONENTS::iterator iter1 = channels.begin(); for(; iter1 != channels.end(); iter1++) { Mercury::Channel* lpChannel = iter1->pChannel; KBE_ASSERT(lpChannel != NULL); if(pChannel == lpChannel) continue; Mercury::Bundle* pBundle = Mercury::Bundle::ObjPool().createObject(); switch(dataType_) { case GLOBAL_DATA: if(componentType == CELLAPP_TYPE) { (*pBundle).newMessage(CellappInterface::onBroadcastGlobalDataChange); } else if(componentType == BASEAPP_TYPE) { (*pBundle).newMessage(BaseappInterface::onBroadcastGlobalDataChange); } else { KBE_ASSERT(false && "componentType is error!\n"); } break; case GLOBAL_BASES: (*pBundle).newMessage(BaseappInterface::onBroadcastGlobalBasesChange); break; case CELLAPP_DATA: (*pBundle).newMessage(CellappInterface::onBroadcastCellAppDataChange); break; default: KBE_ASSERT(false && "dataType is error!\n"); break; }; (*pBundle) << isDelete; ArraySize slen = key.size(); (*pBundle) << slen; (*pBundle).assign(key.data(), slen); if(!isDelete) { slen = value.size(); (*pBundle) << slen; (*pBundle).assign(value.data(), slen); } (*pBundle).send(*lpChannel->endpoint()); Mercury::Bundle::ObjPool().reclaimObject(pBundle); } } }
//------------------------------------------------------------------------------------- bool Script::install(const wchar_t* pythonHomeDir, std::wstring pyPaths, const char* moduleName, COMPONENT_TYPE componentType) { std::wstring pySysPaths = SCRIPT_PATH; wchar_t* pwpySysResPath = strutil::char2wchar(const_cast<char*>(Resmgr::getSingleton().getPySysResPath().c_str())); strutil::kbe_replace(pySysPaths, L"../../res/", pwpySysResPath); pyPaths += pySysPaths; free(pwpySysResPath); #if KBE_PLATFORM == PLATFORM_WIN32 Py_SetPythonHome(const_cast<wchar_t*>(pythonHomeDir)); // 先设置python的环境变量 #else std::wstring fs = L";"; std::wstring rs = L":"; size_t pos = 0; while(true) { pos = pyPaths.find(fs, pos); if (pos == std::wstring::npos) break; pyPaths.replace(pos, fs.length(), rs); } Py_SetPath(pyPaths.c_str()); char* tmpchar = strutil::wchar2char(const_cast<wchar_t*>(pyPaths.c_str())); DEBUG_MSG(boost::format("Script::install: paths=%1%.\n") % tmpchar); free(tmpchar); #endif // Initialise python // Py_VerboseFlag = 2; Py_FrozenFlag = 1; // Warn if tab and spaces are mixed in indentation. // Py_TabcheckFlag = 1; Py_NoSiteFlag = 1; Py_IgnoreEnvironmentFlag = 1; Py_Initialize(); // python解释器的初始化 if (!Py_IsInitialized()) { ERROR_MSG("Script::install::Py_Initialize is failed!\n"); return false; } #if KBE_PLATFORM == PLATFORM_WIN32 PySys_SetPath(pyPaths.c_str()); #endif PyObject *m = PyImport_AddModule("__main__"); module_ = PyImport_AddModule(moduleName); // 添加一个脚本基础模块 if (module_ == NULL) return false; const char* componentName = COMPONENT_NAME_EX(componentType); if (PyModule_AddStringConstant(module_, "component", componentName)) { ERROR_MSG(boost::format("Script::init: Unable to set KBEngine.component to %1%\n") % componentName ); return false; } // 注册产生uuid方法到py APPEND_SCRIPT_MODULE_METHOD(module_, genUUID64, __py_genUUID64, METH_VARARGS, 0); if(!install_py_dlls()) { ERROR_MSG("Script::init: install_py_dlls() is failed!\n"); return false; } #ifndef KBE_SINGLE_THREADED s_pOurInitTimeModules = PyDict_Copy( PySys_GetObject( "modules" ) ); s_pMainThreadState = PyThreadState_Get(); s_defaultContext = s_pMainThreadState; PyEval_InitThreads(); KBEConcurrency::setMainThreadIdleFunctions( &Script::releaseLock, &Script::acquireLock ); #endif ScriptStdOutErr::installScript(NULL); // 安装py重定向模块 ScriptStdOutErrHook::installScript(NULL); static struct PyModuleDef moduleDesc = { PyModuleDef_HEAD_INIT, moduleName, "This module is created by KBEngine!", -1, NULL }; PyModule_Create(&moduleDesc); // 初始化基础模块 PyObject_SetAttrString(m, moduleName, module_); // 将模块对象加入main pyStdouterr_ = new ScriptStdOutErr(); // 重定向python输出 pyStdouterrHook_ = new ScriptStdOutErrHook(); if(!pyStdouterr_->install()){ // 安装py重定向脚本模块 ERROR_MSG("Script::install::pyStdouterr_->install() is failed!\n"); SCRIPT_ERROR_CHECK(); return false; } Pickler::initialize(); PyProfile::initialize(this); PyStruct::initialize(); Copy::initialize(); SCRIPT_ERROR_CHECK(); math::installModule("Math"); INFO_MSG("Script::install is successfully!\n"); return installExtraModule("KBExtra"); }
//------------------------------------------------------------------------------------- PyObject* ClientsRemoteEntityMethod::callmethod(PyObject* args, PyObject* kwds) { // 获取entityAOI范围内其他entity // 向这些entity的client推送这个方法的调用 MethodDescription* methodDescription = getDescription(); Entity* pEntity = Cellapp::getSingleton().findEntity(id_); if(pEntity == NULL || /*pEntity->pWitness() == NULL ||*/ pEntity->isDestroyed() /*|| pEntity->clientMailbox() == NULL*/) { //WARNING_MSG(boost::format("EntityRemoteMethod::callClientMethod: not found entity(%1%).\n") % // mailbox->id()); S_Return; } const std::list<ENTITY_ID>& entities = pEntity->witnesses(); if(otherClients_) { if(pEntity->witnessesSize() == 0) S_Return; } // 先发给自己 if(methodDescription->checkArgs(args)) { MemoryStream* mstream = MemoryStream::ObjPool().createObject(); methodDescription->addToStream(mstream, args); if((!otherClients_ && (pEntity->pWitness() || (pEntity->clientMailbox())))) { Mercury::Bundle* pBundle = Mercury::Bundle::ObjPool().createObject(); pEntity->clientMailbox()->newMail((*pBundle)); if(mstream->wpos() > 0) (*pBundle).append(mstream->data(), mstream->wpos()); if(Mercury::g_trace_packet > 0) { if(Mercury::g_trace_packet_use_logfile) DebugHelper::getSingleton().changeLogger("packetlogs"); DEBUG_MSG(boost::format("ClientsRemoteEntityMethod::callmethod: pushUpdateData: ClientInterface::onRemoteMethodCall(%1%::%2%)\n") % pEntity->scriptName() % methodDescription->getName()); switch(Mercury::g_trace_packet) { case 1: mstream->hexlike(); break; case 2: mstream->textlike(); break; default: mstream->print_storage(); break; }; if(Mercury::g_trace_packet_use_logfile) DebugHelper::getSingleton().changeLogger(COMPONENT_NAME_EX(g_componentType)); } //mailbox->postMail((*pBundle)); pEntity->pWitness()->sendToClient(ClientInterface::onRemoteMethodCall, pBundle); //Mercury::Bundle::ObjPool().reclaimObject(pBundle); // 记录这个事件产生的数据量大小 g_publicClientEventHistoryStats.trackEvent(pEntity->scriptName(), methodDescription->getName(), pBundle->currMsgLength(), "::"); } // 广播给其他人 std::list<ENTITY_ID>::const_iterator iter = entities.begin(); for(; iter != entities.end(); iter++) { Entity* pAoiEntity = Cellapp::getSingleton().findEntity((*iter)); if(pAoiEntity == NULL || pAoiEntity->pWitness() == NULL || pAoiEntity->isDestroyed()) continue; EntityMailbox* mailbox = pAoiEntity->clientMailbox(); if(mailbox == NULL) continue; Mercury::Channel* pChannel = mailbox->getChannel(); if(pChannel == NULL) continue; if(!pAoiEntity->pWitness()->entityInAOI(pEntity->id())) continue; Mercury::Bundle* pSendBundle = Mercury::Bundle::ObjPool().createObject(); Mercury::Bundle* pForwardBundle = Mercury::Bundle::ObjPool().createObject(); pAoiEntity->pWitness()->addSmartAOIEntityMessageToBundle(pForwardBundle, ClientInterface::onRemoteMethodCall, ClientInterface::onRemoteMethodCallOptimized, pEntity->id()); if(mstream->wpos() > 0) (*pForwardBundle).append(mstream->data(), mstream->wpos()); if(Mercury::g_trace_packet > 0) { if(Mercury::g_trace_packet_use_logfile) DebugHelper::getSingleton().changeLogger("packetlogs"); DEBUG_MSG(boost::format("ClientsRemoteEntityMethod::callmethod: pushUpdateData: ClientInterface::onRemoteOtherEntityMethodCall(%1%::%2%)\n") % pAoiEntity->scriptName() % methodDescription->getName()); switch(Mercury::g_trace_packet) { case 1: mstream->hexlike(); break; case 2: mstream->textlike(); break; default: mstream->print_storage(); break; }; if(Mercury::g_trace_packet_use_logfile) DebugHelper::getSingleton().changeLogger(COMPONENT_NAME_EX(g_componentType)); } MERCURY_ENTITY_MESSAGE_FORWARD_CLIENT(pAoiEntity->id(), (*pSendBundle), (*pForwardBundle)); //mailbox->postMail((*pBundle)); pAoiEntity->pWitness()->sendToClient(ClientInterface::onRemoteMethodCallOptimized, pSendBundle); //Mercury::Bundle::ObjPool().reclaimObject(pSendBundle); // 记录这个事件产生的数据量大小 g_publicClientEventHistoryStats.trackEvent(pAoiEntity->scriptName(), methodDescription->getName(), pForwardBundle->currMsgLength(), "::"); Mercury::Bundle::ObjPool().reclaimObject(pForwardBundle); } MemoryStream::ObjPool().reclaimObject(mstream); } S_Return; }
const char* name(){return COMPONENT_NAME_EX(componentType_);}