//------------------------------------------------------------------------------------- void Base::reqBackupCellData() { if(isGetingCellData_) return; EntityMailbox* mb = this->getCellMailbox(); if(mb == NULL) return; Mercury::Bundle bundle; bundle.newMessage(CellappInterface::reqBackupEntityCellData); bundle << this->getID(); mb->postMail(bundle); isGetingCellData_ = true; }
//------------------------------------------------------------------------------------- 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; }
//------------------------------------------------------------------------------------- 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::createPoolObject(); methodDescription->addToStream(mstream, args); if((!otherClients_ && (pEntity->pWitness() || (pEntity->clientMailbox())))) { Network::Bundle* pBundle = Network::Bundle::createPoolObject(); pEntity->clientMailbox()->newMail((*pBundle)); 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("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; // 这个可能性是存在的,例如数据来源于createWitnessFromStream() // 又如自己的entity还未在目标客户端上创建 if (!pAoiEntity->pWitness()->entityInAOI(pEntity->id())) continue; Network::Bundle* pSendBundle = pChannel->createSendBundle(); NETWORK_ENTITY_MESSAGE_FORWARD_CLIENT_START(pAoiEntity->id(), (*pSendBundle)); int ialiasID = -1; const Network::MessageHandler& msgHandler = pAoiEntity->pWitness()->getAOIEntityMessageHandler(ClientInterface::onRemoteMethodCall, ClientInterface::onRemoteMethodCallOptimized, pEntity->id(), 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) << pEntity->id(); } 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("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)); } ENTITY_MESSAGE_FORWARD_CLIENT_END(pSendBundle, msgHandler, aOIEntityMessage); // 记录这个事件产生的数据量大小 g_publicClientEventHistoryStats.trackEvent(pAoiEntity->scriptName(), methodDescription->getName(), pSendBundle->currMsgLength(), "::"); //mailbox->postMail((*pBundle)); pAoiEntity->pWitness()->sendToClient(ClientInterface::onRemoteMethodCallOptimized, pSendBundle); } MemoryStream::reclaimPoolObject(mstream); } S_Return; }
//------------------------------------------------------------------------------------- PyObject* Base::pyTeleport(PyObject* baseEntityMB) { if(isDestroyed()) { PyErr_Format(PyExc_Exception, "%s::teleport: %d is destroyed!\n", getScriptName(), getID()); PyErr_PrintEx(0); S_Return; } if(this->getCellMailbox() == NULL) { PyErr_Format(PyExc_Exception, "%s::teleport: %d no has cell!\n", getScriptName(), getID()); PyErr_PrintEx(0); S_Return; } if(baseEntityMB == NULL) { PyErr_Format(PyExc_Exception, "%s::teleport: %d baseEntityMB is NULL!\n", getScriptName(), getID()); PyErr_PrintEx(0); S_Return; } bool isMailbox = PyObject_TypeCheck(baseEntityMB, EntityMailbox::getScriptType()); bool isEntity = !isMailbox && (PyObject_TypeCheck(baseEntityMB, Base::getScriptType()) || PyObject_TypeCheck(baseEntityMB, Proxy::getScriptType())); if(!isMailbox && !isEntity) { PyErr_Format(PyExc_Exception, "%s::teleport: %d invalid baseEntityMB!\n", getScriptName(), getID()); PyErr_PrintEx(0); S_Return; } ENTITY_ID eid = 0; // 如果不是mailbox则是本地base if(isMailbox) { EntityMailbox* mb = static_cast<EntityMailbox*>(baseEntityMB); if(mb->getType() != MAILBOX_TYPE_BASE && mb->getType() != MAILBOX_TYPE_CELL_VIA_BASE) { PyErr_Format(PyExc_Exception, "%s::teleport: %d baseEntityMB is not baseMailbox!\n", getScriptName(), getID()); PyErr_PrintEx(0); S_Return; } eid = mb->getID(); Mercury::Bundle bundle; bundle.newMessage(BaseappInterface::reqTeleportOther); bundle << eid; BaseappInterface::reqTeleportOtherArgs3::staticAddToBundle(bundle, this->getID(), this->getCellMailbox()->getComponentID(), g_componentID); mb->postMail(bundle); } else { Base* base = static_cast<Base*>(baseEntityMB); if(!base->isDestroyed()) { base->reqTeleportOther(NULL, this->getID(), this->getCellMailbox()->getComponentID(), g_componentID); } else { PyErr_Format(PyExc_Exception, "%s::teleport: %d baseEntity is destroyed!\n", getScriptName(), getID()); PyErr_PrintEx(0); S_Return; } } S_Return; }