//------------------------------------------------------------------------------------- bool BaseMessagesForwardHandler::process() { if(!startForward_) return true; if(bufferedSendToCellappMessages_.size() == 0) { completed_ = true; pBase_->onBufferedForwardToCellappMessagesOver(); return false; } if(pBase_->cellMailbox() == NULL || pBase_->cellMailbox()->getChannel() == NULL) return true; int remainPacketSize = PACKET_MAX_SIZE_TCP * 10; std::vector<Network::Bundle*>::iterator iter = bufferedSendToCellappMessages_.begin(); for(; iter != bufferedSendToCellappMessages_.end(); ) { Network::Bundle* pBundle = (*iter); remainPacketSize -= pBundle->packetsLength(); iter = bufferedSendToCellappMessages_.erase(iter); pBase_->sendToCellapp(pBundle); if(remainPacketSize <= 0) return true; } return true; }
//------------------------------------------------------------------------------------- void EntityMailboxAbstract::newMail(Network::Bundle& bundle) { // 如果是server端的mailbox if(g_componentType != CLIENT_TYPE && g_componentType != BOTS_TYPE) { // 如果ID为0,则这是一个客户端组件,否则为服务端。 if(componentID_ == 0) { bundle.newMessage(ClientInterface::onRemoteMethodCall); } else { Components::ComponentInfos* cinfos = Components::getSingleton().findComponent(componentID_); if(cinfos != NULL) { // 找到对应的组件投递过去, 如果这个mailbox还需要中转比如 e.base.cell , 则由baseapp转往cellapp if(cinfos->componentType == BASEAPP_TYPE) { bundle.newMessage(BaseappInterface::onEntityMail); } else { bundle.newMessage(CellappInterface::onEntityMail); } } else { ERROR_MSG(fmt::format("EntityMailboxAbstract::newMail: not found component({})!\n", componentID_)); } } bundle << id_; // 如果是发往客户端的包则无需附加这样一个类型 if(componentID_ > 0) bundle << type_; } else { // 如果是客户端上的mailbox调用服务端方法只存在调用cell或者base switch(type_) { case MAILBOX_TYPE_BASE: bundle.newMessage(BaseappInterface::onRemoteMethodCall); break; case MAILBOX_TYPE_CELL: bundle.newMessage(BaseappInterface::onRemoteCallCellMethodFromClient); break; default: KBE_ASSERT(false && "no support!\n"); break; }; bundle << id_; } }
//------------------------------------------------------------------------------------- void EntityMailboxAbstract::newMail(Network::Bundle& bundle) { // If it is a server-side mailbox if(g_componentType != CLIENT_TYPE && g_componentType != BOTS_TYPE) { // If the ID is 0, then this is a client-side component, otherwise the server-side. if(componentID_ == 0) { bundle.newMessage(ClientInterface::onRemoteMethodCall); } else { Components::ComponentInfos* cinfos = Components::getSingleton().findComponent(componentID_); if(cinfos != NULL) { // Post a component found in the past, if the mailbox needs to transit such as e.base.cell, by baseapp transferred cellapp if(cinfos->componentType == BASEAPP_TYPE) { bundle.newMessage(BaseappInterface::onEntityMail); } else { bundle.newMessage(CellappInterface::onEntityMail); } } else { ERROR_MSG(fmt::format("EntityMailboxAbstract::newMail: not found component({}), entityID({})!\n", componentID_, id_)); } } bundle << id_; // If the package is sent to the client is not necessary to attach such a type if(componentID_ > 0) bundle << type_; } else { // If the mailbox is on the client calls the server-side method calls the cell or base switch(type_) { case MAILBOX_TYPE_BASE: bundle.newMessage(BaseappInterface::onRemoteMethodCall); break; case MAILBOX_TYPE_CELL: bundle.newMessage(BaseappInterface::onRemoteCallCellMethodFromClient); break; default: KBE_ASSERT(false && "no support!\n"); break; }; bundle << id_; } }
//------------------------------------------------------------------------------------- void Loginapp::onClientActiveTick(Network::Channel* pChannel) { if(!pChannel->isExternal()) return; onAppActiveTick(pChannel, CLIENT_TYPE, 0); Network::Bundle* pBundle = Network::Bundle::createPoolObject(); pBundle->newMessage(ClientInterface::onAppActiveTickCB); pChannel->send(pBundle); }
//------------------------------------------------------------------------------------- void Baseappmgr::registerPendingAccountToBaseapp(Network::Channel* pChannel, MemoryStream& s) { std::string loginName; std::string accountName; std::string password; std::string datas; DBID entityDBID; uint32 flags; uint64 deadline; COMPONENT_TYPE componentType; s >> loginName >> accountName >> password >> entityDBID >> flags >> deadline >> componentType; s.readBlob(datas); Components::ComponentInfos* cinfos = Components::getSingleton().findComponent(pChannel); if(cinfos == NULL || cinfos->pChannel == NULL) { ERROR_MSG("Baseappmgr::registerPendingAccountToBaseapp: not found loginapp!\n"); return; } pending_logins_[loginName] = cinfos->cid; ENTITY_ID eid = 0; cinfos = Components::getSingleton().findComponent(BASEAPP_TYPE, bestBaseappID_); if(cinfos == NULL || cinfos->pChannel == NULL || cinfos->state != COMPONENT_STATE_RUN) { Network::Bundle* pBundle = Network::Bundle::ObjPool().createObject(); ForwardItem* pFI = new ForwardItem(); pFI->pBundle = pBundle; (*pBundle).newMessage(BaseappInterface::registerPendingLogin); (*pBundle) << loginName << accountName << password << eid << entityDBID << flags << deadline << componentType; pBundle->appendBlob(datas); WARNING_MSG("Baseappmgr::registerPendingAccountToBaseapp: not found baseapp, message is buffered.\n"); pFI->pHandler = NULL; forward_baseapp_messagebuffer_.push(pFI); return; } DEBUG_MSG(fmt::format("Baseappmgr::registerPendingAccountToBaseapp:{0}. allocBaseapp=[{1}].\n", accountName, bestBaseappID_)); Network::Bundle* pBundle = Network::Bundle::ObjPool().createObject(); (*pBundle).newMessage(BaseappInterface::registerPendingLogin); (*pBundle) << loginName << accountName << password << eid << entityDBID << flags << deadline << componentType; pBundle->appendBlob(datas); cinfos->pChannel->send(pBundle); }
static util::StringVector getReferenceLabels(network::Bundle& bundle, const model::Model& model) { if(bundle.contains("referenceLabels")) { util::StringVector labels; auto& referenceLabels = bundle["referenceLabels"].get<matrix::LabelVector>(); for(auto& referenceLabel : referenceLabels) { labels.push_back(std::string()); for(auto& grapheme : referenceLabel) { labels.back() += model.getOutputLabel(grapheme); } } return labels; } auto& referenceActivations = bundle["referenceActivations"].get<matrix::MatrixVector>().front(); return convertActivationsToLabels(std::move(referenceActivations), model); }
//------------------------------------------------------------------------------------- PyObject* BaseRemoteMethod::tp_call(PyObject* self, PyObject* args, PyObject* kwds) { BaseRemoteMethod* rmethod = static_cast<BaseRemoteMethod*>(self); MethodDescription* methodDescription = rmethod->getDescription(); EntityMailboxAbstract* mailbox = rmethod->getMailbox(); if(!mailbox->isClient()) { return RemoteEntityMethod::tp_call(self, args, kwds); } Base* pEntity = Baseapp::getSingleton().findEntity(mailbox->id()); if(pEntity == NULL) { //WARNING_MSG(fmt::format("BaseRemoteMethod::callClientMethod: not found entity({}).\n", // mailbox->id())); return RemoteEntityMethod::tp_call(self, args, kwds); } // 如果是调用客户端方法, 我们记录事件并且记录带宽 if(methodDescription->checkArgs(args)) { Network::Bundle* pBundle = Network::Bundle::ObjPool().createObject(); mailbox->newMail((*pBundle)); MemoryStream* mstream = MemoryStream::ObjPool().createObject(); methodDescription->addToStream(mstream, args); if(mstream->wpos() > 0) (*pBundle).append(mstream->data(), mstream->wpos()); // 记录这个事件产生的数据量大小 g_privateClientEventHistoryStats.trackEvent(pEntity->scriptName(), methodDescription->getName(), pBundle->currMsgLength(), "::"); static_cast<Proxy*>(pEntity)->sendToClient(ClientInterface::onRemoteMethodCall, pBundle); //Network::Bundle::ObjPool().reclaimObject(pBundle); MemoryStream::ObjPool().reclaimObject(mstream); } S_Return; }
//------------------------------------------------------------------------------------- void Baseappmgr::registerPendingAccountToBaseappAddr(Network::Channel* pChannel, MemoryStream& s) { COMPONENT_ID componentID; std::string loginName; std::string accountName; std::string password; std::string datas; ENTITY_ID entityID; DBID entityDBID; uint32 flags; uint64 deadline; COMPONENT_TYPE componentType; s >> componentID >> loginName >> accountName >> password >> entityID >> entityDBID >> flags >> deadline >> componentType; s.readBlob(datas); DEBUG_MSG(fmt::format("Baseappmgr::registerPendingAccountToBaseappAddr:{0}, componentID={1}, entityID={2}.\n", accountName, componentID, entityID)); Components::ComponentInfos* cinfos = Components::getSingleton().findComponent(pChannel); if(cinfos == NULL || cinfos->pChannel == NULL) { ERROR_MSG("Baseappmgr::registerPendingAccountToBaseapp: not found loginapp!\n"); return; } pending_logins_[loginName] = cinfos->cid; cinfos = Components::getSingleton().findComponent(componentID); if(cinfos == NULL || cinfos->pChannel == NULL) { ERROR_MSG(fmt::format("Baseappmgr::registerPendingAccountToBaseappAddr: not found baseapp({}).\n", componentID)); sendAllocatedBaseappAddr(pChannel, loginName, accountName, "", 0); return; } Network::Bundle* pBundle = Network::Bundle::ObjPool().createObject(); (*pBundle).newMessage(BaseappInterface::registerPendingLogin); (*pBundle) << loginName << accountName << password << entityID << entityDBID << flags << deadline << componentType; pBundle->appendBlob(datas); cinfos->pChannel->send(pBundle); }
//------------------------------------------------------------------------------------- void Base::onDefDataChanged(const PropertyDescription* propertyDescription, PyObject* pyData) { if(initing()) return; if(propertyDescription->isPersistent()) setDirty(); uint32 flags = propertyDescription->getFlags(); if((flags & ED_FLAG_BASE_AND_CLIENT) <= 0 || clientMailbox_ == NULL) return; // 创建一个需要广播的模板流 MemoryStream* mstream = MemoryStream::createPoolObject(); propertyDescription->getDataType()->addToStream(mstream, pyData); Network::Bundle* pBundle = Network::Bundle::createPoolObject(); (*pBundle).newMessage(ClientInterface::onUpdatePropertys); (*pBundle) << id(); if(pScriptModule_->usePropertyDescrAlias()) (*pBundle) << propertyDescription->aliasIDAsUint8(); else (*pBundle) << propertyDescription->getUType(); pBundle->append(*mstream); g_privateClientEventHistoryStats.trackEvent(scriptName(), propertyDescription->getName(), pBundle->currMsgLength()); // 按照当前的设计来说,有clientMailbox_必定是proxy // 至于为何跑到base里来和python本身是C语言实现有关 static_cast<Proxy*>(this)->sendToClient(ClientInterface::onUpdatePropertys, pBundle); MemoryStream::reclaimPoolObject(mstream); }
//------------------------------------------------------------------------------------- void LogWatcher::onMessage(uint32 logtype, COMPONENT_TYPE componentType, COMPONENT_ID componentID, COMPONENT_ORDER componentOrder, int64 tm, GAME_TIME kbetime, const std::string& str, const std::stringstream& sstr) { if(!VALID_COMPONENT(componentType) || componentBitmap_[componentType] == 0) return; if((logtypes_ & logtype) <= 0) return; if(appOrder_ > 0 && appOrder_ != componentOrder) return; Network::Channel* pChannel = Messagelog::getSingleton().networkInterface().findChannel(addr_); if(pChannel == NULL) return; Network::Bundle bundle; ConsoleInterface::ConsoleLogMessageHandler msgHandler; bundle.newMessage(msgHandler); bundle << sstr.str().c_str(); bundle.send(Messagelog::getSingleton().networkInterface(), pChannel); }
//------------------------------------------------------------------------------------- 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(fmt::format("EntityRemoteMethod::callClientMethod: not found entity({}).\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())))) { Network::Bundle* pBundle = Network::Bundle::ObjPool().createObject(); pEntity->clientMailbox()->newMail((*pBundle)); if(mstream->wpos() > 0) (*pBundle).append(mstream->data(), mstream->wpos()); if(Network::g_trace_packet > 0) { if(Network::g_trace_packet_use_logfile) DebugHelper::getSingleton().changeLogger("packetlogs"); DEBUG_MSG(fmt::format("ClientsRemoteEntityMethod::callmethod: 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)); } //mailbox->postMail((*pBundle)); pEntity->pWitness()->sendToClient(ClientInterface::onRemoteMethodCall, 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; Network::Channel* pChannel = mailbox->getChannel(); if(pChannel == NULL) continue; if(!pAoiEntity->pWitness()->entityInAOI(pEntity->id())) continue; Network::Bundle* pSendBundle = Network::Bundle::ObjPool().createObject(); Network::Bundle* pForwardBundle = Network::Bundle::ObjPool().createObject(); pAoiEntity->pWitness()->addSmartAOIEntityMessageToBundle(pForwardBundle, ClientInterface::onRemoteMethodCall, ClientInterface::onRemoteMethodCallOptimized, pEntity->id()); if(mstream->wpos() > 0) (*pForwardBundle).append(mstream->data(), mstream->wpos()); if(Network::g_trace_packet > 0) { if(Network::g_trace_packet_use_logfile) DebugHelper::getSingleton().changeLogger("packetlogs"); DEBUG_MSG(fmt::format("ClientsRemoteEntityMethod::callmethod: pushUpdateData: ClientInterface::onRemoteOtherEntityMethodCall({}::{})\n", pAoiEntity->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)); } NETWORK_ENTITY_MESSAGE_FORWARD_CLIENT(pAoiEntity->id(), (*pSendBundle), (*pForwardBundle)); //mailbox->postMail((*pBundle)); pAoiEntity->pWitness()->sendToClient(ClientInterface::onRemoteMethodCallOptimized, pSendBundle); // 记录这个事件产生的数据量大小 g_publicClientEventHistoryStats.trackEvent(pAoiEntity->scriptName(), methodDescription->getName(), pForwardBundle->currMsgLength(), "::"); Network::Bundle::ObjPool().reclaimObject(pForwardBundle); } MemoryStream::ObjPool().reclaimObject(mstream); } S_Return; }
//------------------------------------------------------------------------------------- thread::TPTask::TPTaskState DataDownload::presentMainThread() { if(error_) { ERROR_MSG(fmt::format("DataDownload::presentMainThread: proxy({}), downloadID({}), type({}), thread error.\n", entityID(), id(), type())); return thread::TPTask::TPTASK_STATE_COMPLETED; } uint32 datasize = GAME_PACKET_MAX_SIZE_TCP - sizeof(int16) - sizeof(uint32); if(remainSent_ > 0 && currSent_ < remainSent_) { Network::Bundle* pBundle = Network::Bundle::ObjPool().createObject(); if(!sentStart_) { pBundle->newMessage(ClientInterface::onStreamDataStarted); (*pBundle) << this->id(); (*pBundle) << totalBytes_; (*pBundle) << descr_; (*pBundle) << type(); sentStart_ = true; if(!send(ClientInterface::onStreamDataStarted, pBundle)) { DEBUG_MSG(fmt::format("DataDownload::presentMainThread: proxy({}), downloadID({}), type({}), thread exit.\n", entityID(), id(), type())); return thread::TPTask::TPTASK_STATE_COMPLETED; } return thread::TPTask::TPTASK_STATE_CONTINUE_MAINTHREAD; } pBundle->newMessage(ClientInterface::onStreamDataRecv); (*pBundle) << id(); if(remainSent_ - currSent_ > datasize) { (*pBundle) << datasize; (*pBundle).append(getOutStream() + currSent_, datasize); currSent_ += datasize; totalSentBytes_ += datasize; if(!send(ClientInterface::onStreamDataRecv, pBundle)) { DEBUG_MSG(fmt::format("DataDownload::presentMainThread: proxy({}), downloadID({}), type({}), thread exit.\n", entityID(), id(), type())); error_ = true; return thread::TPTask::TPTASK_STATE_COMPLETED; } } else { datasize = remainSent_ - currSent_; (*pBundle) << datasize; (*pBundle).append(getOutStream() + currSent_, datasize); if(!send(ClientInterface::onStreamDataRecv, pBundle)) { DEBUG_MSG(fmt::format("DataDownload::presentMainThread: proxy({}), downloadID({}), type({}), thread exit.\n", entityID(), id(), type())); error_ = true; return thread::TPTask::TPTASK_STATE_COMPLETED; } totalSentBytes_ += datasize; currSent_ = remainSent_; } } if(totalSentBytes_ == totalBytes_) { DEBUG_MSG(fmt::format("DataDownload::presentMainThread: proxy({0}), downloadID({1}), type({6}), sentBytes={5},{2}/{3} ({4:.2f}%).\n", entityID(), id(), totalSentBytes_, this->totalBytes(), 100.0f, datasize, type())); pDataDownloads_->onDownloadCompleted(this); Network::Bundle* pBundle = Network::Bundle::ObjPool().createObject(); pBundle->newMessage(ClientInterface::onStreamDataCompleted); (*pBundle) << this->id(); send(ClientInterface::onStreamDataCompleted, pBundle); return thread::TPTask::TPTASK_STATE_COMPLETED; } DEBUG_MSG(fmt::format("DataDownload::presentMainThread: proxy({0}), downloadID({1}), type({6}), sentBytes={5},{2}/{3} ({4:.2f}%).\n", entityID(), id(), totalSentBytes_, this->totalBytes(), (((float)totalSentBytes_ / (float)this->totalBytes()) * 100.0f), datasize, type())); if(currSent_ == remainSent_) { DEBUG_MSG(fmt::format("DataDownload::presentMainThread: proxy({}), downloadID({}), type({}), thread-continue.\n", entityID(), id(), type())); return thread::TPTask::TPTASK_STATE_CONTINUE_CHILDTHREAD; } return thread::TPTask::TPTASK_STATE_CONTINUE_MAINTHREAD; }
//------------------------------------------------------------------------------------- bool Components::updateComponentInfos(const Components::ComponentInfos* info) { // 不对其他machine做处理 if(info->componentType == MACHINE_TYPE) { return true; } if (!lookupLocalComponentRunning(info->pid)) return false; Network::EndPoint epListen; epListen.socket(SOCK_STREAM); if (!epListen.good()) { ERROR_MSG("Components::updateComponentInfos: couldn't create a socket\n"); return true; } epListen.setnonblocking(true); while(true) { fd_set frds, fwds; struct timeval tv = { 0, 300000 }; // 100ms FD_ZERO( &frds ); FD_ZERO( &fwds ); FD_SET((int)epListen, &frds); FD_SET((int)epListen, &fwds); if(epListen.connect(info->pIntAddr->port, info->pIntAddr->ip) == -1) { int selgot = select(epListen+1, &frds, &fwds, NULL, &tv); if(selgot > 0) { break; } WARNING_MSG(fmt::format("Components::updateComponentInfos: couldn't connect to:{}\n", info->pIntAddr->c_str())); return false; } } epListen.setnodelay(true); Network::Bundle* pBundle = Network::Bundle::createPoolObject(); // 由于COMMON_NETWORK_MESSAGE不包含client, 如果是bots, 我们需要单独处理 if(info->componentType != BOTS_TYPE) { COMMON_NETWORK_MESSAGE(info->componentType, (*pBundle), lookApp); } else { (*pBundle).newMessage(BotsInterface::lookApp); } epListen.send(pBundle->pCurrPacket()->data(), pBundle->pCurrPacket()->wpos()); Network::Bundle::reclaimPoolObject(pBundle); fd_set fds; struct timeval tv = { 0, 300000 }; // 100ms FD_ZERO( &fds ); FD_SET((int)epListen, &fds); int selgot = select(epListen+1, &fds, NULL, NULL, &tv); if(selgot == 0) { // 超时, 可能对方繁忙 return true; } else if(selgot == -1) { return true; } else { COMPONENT_TYPE ctype; COMPONENT_ID cid; int8 istate = 0; ArraySize entitySize = 0, cellSize = 0; int32 clientsSize = 0, proxicesSize = 0; uint32 telnet_port = 0; Network::TCPPacket packet; packet.resize(255); int recvsize = sizeof(ctype) + sizeof(cid) + sizeof(istate); if(info->componentType == CELLAPP_TYPE) { recvsize += sizeof(entitySize) + sizeof(cellSize) + sizeof(telnet_port); } if(info->componentType == BASEAPP_TYPE) { recvsize += sizeof(entitySize) + sizeof(clientsSize) + sizeof(proxicesSize) + sizeof(telnet_port); } int len = epListen.recv(packet.data(), recvsize); packet.wpos(len); if(recvsize != len) { WARNING_MSG(fmt::format("Components::updateComponentInfos: packet invalid(recvsize({}) != ctype_cid_len({}).\n" , len, recvsize)); if(len == 0) return false; return true; } packet >> ctype >> cid >> istate; if(ctype == CELLAPP_TYPE) { packet >> entitySize >> cellSize >> telnet_port; } if(ctype == BASEAPP_TYPE) { packet >> entitySize >> clientsSize >> proxicesSize >> telnet_port; }
//------------------------------------------------------------------------------------- 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->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; } EntityRef::AOI_ENTITIES::iterator iter = srcEntity->pWitness()->aoiEntities().begin(); Entity* e = NULL; for(; iter != srcEntity->pWitness()->aoiEntities().end(); ++iter) { if((*iter)->id() == clientEntityID_ && ((*iter)->flags() & (ENTITYREF_FLAG_ENTER_CLIENT_PENDING | ENTITYREF_FLAG_LEAVE_CLIENT_PENDING)) <= 0) { e = (*iter)->pEntity(); break; } } 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::ObjPool().createObject(); methodDescription->addToStream(mstream, args); Network::Bundle* pForwardBundle = Network::Bundle::ObjPool().createObject(); Network::Bundle* pSendBundle = Network::Bundle::ObjPool().createObject(); srcEntity->pWitness()->addSmartAOIEntityMessageToBundle(pForwardBundle, ClientInterface::onRemoteMethodCall, ClientInterface::onRemoteMethodCallOptimized, clientEntityID_); if(mstream->wpos() > 0) (*pForwardBundle).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)); } NETWORK_ENTITY_MESSAGE_FORWARD_CLIENT(srcEntity->id(), (*pSendBundle), (*pForwardBundle)); srcEntity->pWitness()->sendToClient(ClientInterface::onRemoteMethodCallOptimized, pSendBundle); // 记录这个事件产生的数据量大小 g_publicClientEventHistoryStats.trackEvent(srcEntity->scriptName(), (std::string(e->scriptName()) + "." + methodDescription->getName()), pForwardBundle->currMsgLength(), "::"); MemoryStream::ObjPool().reclaimObject(mstream); Network::Bundle::ObjPool().reclaimObject(pForwardBundle); } S_Return; }
//------------------------------------------------------------------------------------- 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 Baseappmgr::registerPendingAccountToBaseapp(Network::Channel* pChannel, MemoryStream& s) { std::string loginName; std::string accountName; std::string password; std::string datas; DBID entityDBID; uint32 flags; uint64 deadline; COMPONENT_TYPE componentType; s >> loginName >> accountName >> password >> entityDBID >> flags >> deadline >> componentType; s.readBlob(datas); Components::ComponentInfos* cinfos = Components::getSingleton().findComponent(pChannel); if(cinfos == NULL || cinfos->pChannel == NULL) { ERROR_MSG("Baseappmgr::registerPendingAccountToBaseapp: not found loginapp!\n"); return; } pending_logins_[loginName] = cinfos->cid; updateBestBaseapp(); if (bestBaseappID_ == 0 && numLoadBalancingApp() == 0) { ERROR_MSG(fmt::format("Baseappmgr::registerPendingAccountToBaseapp: Unable to allocate baseapp for load balancing! baseappSize={}, accountName={}.\n", baseapps_.size(), loginName)); } ENTITY_ID eid = 0; cinfos = Components::getSingleton().findComponent(BASEAPP_TYPE, bestBaseappID_); if (cinfos == NULL || cinfos->pChannel == NULL || cinfos->state != COMPONENT_STATE_RUN) { Network::Bundle* pBundle = Network::Bundle::createPoolObject(); ForwardItem* pFI = new AppForwardItem(); pFI->pBundle = pBundle; (*pBundle).newMessage(BaseappInterface::registerPendingLogin); (*pBundle) << loginName << accountName << password << eid << entityDBID << flags << deadline << componentType; pBundle->appendBlob(datas); int runstate = -1; if (cinfos) runstate = (int)cinfos->state; WARNING_MSG(fmt::format("Baseappmgr::registerPendingAccountToBaseapp: not found baseapp({}, runstate={}, pChannel={}), message is buffered.\n", bestBaseappID_, runstate, (cinfos && cinfos->pChannel ? cinfos->pChannel->c_str() : "NULL"))); pFI->pHandler = NULL; forward_anywhere_baseapp_messagebuffer_.push(pFI); return; } std::map< COMPONENT_ID, Baseapp >::iterator baseapps_iter = baseapps_.find(bestBaseappID_); DEBUG_MSG(fmt::format("Baseappmgr::registerPendingAccountToBaseapp:{}. allocBaseapp={}, numEntities={}.\n", accountName, bestBaseappID_, (bestBaseappID_ > 0 ? baseapps_iter->second.numEntities() : 0))); Network::Bundle* pBundle = Network::Bundle::createPoolObject(); (*pBundle).newMessage(BaseappInterface::registerPendingLogin); (*pBundle) << loginName << accountName << password << eid << entityDBID << flags << deadline << componentType; pBundle->appendBlob(datas); cinfos->pChannel->send(pBundle); // 预先将实体数量增加 if (baseapps_iter != baseapps_.end()) { baseapps_iter->second.incNumProxices(); } }
//------------------------------------------------------------------------------------- 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; }
//------------------------------------------------------------------------------------- PyObject* RealEntityMethod::callmethod(PyObject* args, PyObject* kwds) { MethodDescription* methodDescription = getDescription(); if(methodDescription->checkArgs(args)) { MemoryStream* mstream = MemoryStream::ObjPool().createObject(); methodDescription->addToStream(mstream, args); Network::Bundle* pForwardBundle = Network::Bundle::ObjPool().createObject(); (*pForwardBundle).newMessage(CellappInterface::onRemoteRealMethodCall); (*pForwardBundle) << ghostEntityID_; if(mstream->wpos() > 0) (*pForwardBundle).append(mstream->data(), mstream->wpos()); if(Network::g_trace_packet > 0) { if(Network::g_trace_packet_use_logfile) DebugHelper::getSingleton().changeLogger("packetlogs"); DEBUG_MSG(fmt::format("RealEntityMethod::callmethod: pushUpdateData: CellappInterface::onRemoteRealMethodCall({2}({0})::{1})\n", ghostEntityID_, methodDescription->getName(), scriptName_)); 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_publicCellEventHistoryStats.trackEvent(scriptName_, methodDescription->getName(), pForwardBundle->currMsgLength(), "::"); MemoryStream::ObjPool().reclaimObject(mstream); GhostManager* gm = Cellapp::getSingleton().pGhostManager(); if(gm) { gm->pushMessage(realCell_, pForwardBundle); } else { Network::Bundle::ObjPool().reclaimObject(pForwardBundle); } } S_Return; }