//------------------------------------------------------------------------------------- void Proxy::onDefDataChanged(const PropertyDescription* propertyDescription, PyObject* pyData) { uint32 flags = propertyDescription->getFlags(); if((flags & ED_FLAG_BASE_AND_CLIENT) <= 0 || clientMailbox_ == NULL) return; // 创建一个需要广播的模板流 MemoryStream* mstream = MemoryStream::ObjPool().createObject(); propertyDescription->getDataType()->addToStream(mstream, pyData); Mercury::Bundle* pBundle = Mercury::Bundle::ObjPool().createObject(); (*pBundle).newMessage(ClientInterface::onUpdatePropertys); (*pBundle) << id(); if(scriptModule_->usePropertyDescrAlias()) (*pBundle) << propertyDescription->aliasIDAsUint8(); else (*pBundle) << propertyDescription->getUType(); pBundle->append(*mstream); g_privateClientEventHistoryStats.trackEvent(scriptName(), propertyDescription->getName(), pBundle->currMsgLength()); sendToClient(ClientInterface::onUpdatePropertys, pBundle); MemoryStream::ObjPool().reclaimObject(mstream); }
//------------------------------------------------------------------------------------- void DebugHelper::sync() { lockthread(); if(hasBufferedLogPackets_ == 0) { unlockthread(); return; } if(Mercury::Address::NONE == messagelogAddr_) { if(hasBufferedLogPackets_ > g_kbeSrvConfig.tickMaxBufferedLogs()) { clearBufferedLog(); } canLogFile_ = true; unlockthread(); return; } Mercury::Channel* pMessagelogChannel = pNetworkInterface_->findChannel(messagelogAddr_); if(pMessagelogChannel == NULL) { if(hasBufferedLogPackets_ > g_kbeSrvConfig.tickMaxBufferedLogs()) { clearBufferedLog(); } canLogFile_ = true; unlockthread(); return; } int8 v = Mercury::g_trace_packet; Mercury::g_trace_packet = 0; uint32 i = 0; size_t totalLen = 0; while(!bufferedLogPackets_.empty()) { if(i++ >= g_kbeSrvConfig.tickMaxSyncLogs() || totalLen > (PACKET_MAX_SIZE_TCP * 10)) break; Mercury::Bundle* pBundle = bufferedLogPackets_.front(); bufferedLogPackets_.pop(); totalLen += pBundle->currMsgLength(); pMessagelogChannel->send(pBundle); --hasBufferedLogPackets_; } Mercury::g_trace_packet = v; canLogFile_ = false; unlockthread(); }
//------------------------------------------------------------------------------------- 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->getID()); if(pEntity == NULL) { //WARNING_MSG(boost::format("BaseRemoteMethod::callClientMethod: not found entity(%1%).\n") % // mailbox->getID()); return RemoteEntityMethod::tp_call(self, args, kwds); } // 如果是调用客户端方法, 我们记录事件并且记录带宽 if(methodDescription->checkArgs(args)) { Mercury::Bundle* pBundle = Mercury::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->getScriptName(), methodDescription->getName(), pBundle->currMsgLength(), "::"); mailbox->postMail((*pBundle)); Mercury::Bundle::ObjPool().reclaimObject(pBundle); 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(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* 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; }
//------------------------------------------------------------------------------------- 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); } // 如果是调用客户端方法, 我们记录事件并且记录带宽 if(methodDescription->checkArgs(args)) { Mercury::Bundle* pBundle = Mercury::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()); if(Mercury::g_trace_packet > 0) { if(Mercury::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(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); MemoryStream::ObjPool().reclaimObject(mstream); // 记录这个事件产生的数据量大小 g_privateClientEventHistoryStats.trackEvent(pEntity->scriptName(), methodDescription->getName(), pBundle->currMsgLength(), "::"); } S_Return; }
//------------------------------------------------------------------------------------- void Entity::onDefDataChanged(const PropertyDescription* propertyDescription, PyObject* pyData) { // 如果不是一个realEntity则不理会 if(!isReal() && initing_) return; const uint32& flags = propertyDescription->getFlags(); ENTITY_PROPERTY_UID utype = propertyDescription->getUType(); // 首先创建一个需要广播的模板流 MemoryStream* mstream = MemoryStream::ObjPool().createObject(); (*mstream) << utype; propertyDescription->getDataType()->addToStream(mstream, pyData); // 判断是否需要广播给其他的cellapp, 这个还需一个前提是entity必须拥有ghost实体 // 只有在cell边界一定范围内的entity才拥有ghost实体 if((flags & ENTITY_BROADCAST_CELL_FLAGS) > 0) { } /* // 判断这个属性是否还需要广播给其他客户端 if((flags & ENTITY_BROADCAST_OTHER_CLIENT_FLAGS) > 0) { int8 detailLevel = propertyDescription->getDetailLevel(); for(int8 i=DETAIL_LEVEL_NEAR; i<=detailLevel; i++) { std::map<ENTITY_ID, Entity*>::iterator iter = witnessEntities_[i].begin(); for(; iter != witnessEntities_[i].end(); iter++) { Entity* entity = iter->second; EntityMailbox* clientMailbox = entity->getClientMailbox(); if(clientMailbox != NULL) { Packet* sp = clientMailbox->createMail(MAIL_TYPE_UPDATE_PROPERTY); (*sp) << id_; sp->append(mstream->contents(), mstream->size()); clientMailbox->post(sp); } } } // 这个属性已经更新过, 将这些信息添加到曾经进入过这个级别的entity, 但现在可能走远了一点, 在他回来重新进入这个detaillevel // 时如果重新将所有的属性都更新到他的客户端可能不合适, 我们记录这个属性的改变, 下次他重新进入我们只需要将所有期间有过改变的 // 数据发送到他的客户端更新 for(int8 i=detailLevel; i<=DETAIL_LEVEL_FAR; i++) { std::map<ENTITY_ID, Entity*>::iterator iter = witnessEntities_[i].begin(); for(; iter != witnessEntities_[i].end(); iter++) { Entity* entity = iter->second; EntityMailbox* clientMailbox = entity->getClientMailbox(); if(clientMailbox != NULL) { WitnessInfo* witnessInfo = witnessEntityDetailLevelMap_.find(iter->first)->second; if(witnessInfo->detailLevelLog[detailLevel]) { std::vector<uint32>& cddlog = witnessInfo->changeDefDataLogs[detailLevel]; std::vector<uint32>::iterator fiter = std::find(cddlog.begin(), cddlog.end(), utype); if(fiter == cddlog.end()) witnessInfo->changeDefDataLogs[detailLevel].push_back(utype); } } // 记录这个事件产生的数据量大小 std::string event_name = this->getScriptName(); event_name += "."; event_name += propertyDescription->getName(); g_publicClientEventHistoryStats.add(getScriptName(), propertyDescription->getName(), pSendBundle->currMsgLength()); } } } */ // 判断这个属性是否还需要广播给自己的客户端 if((flags & ENTITY_BROADCAST_OWN_CLIENT_FLAGS) > 0 && clientMailbox_ != NULL && pWitness_) { Mercury::Bundle* pForwardBundle = Mercury::Bundle::ObjPool().createObject(); (*pForwardBundle).newMessage(ClientInterface::onUpdatePropertys); (*pForwardBundle) << getID(); pForwardBundle->append(*mstream); // 记录这个事件产生的数据量大小 if((flags & ENTITY_BROADCAST_OTHER_CLIENT_FLAGS) <= 0) { g_privateClientEventHistoryStats.trackEvent(getScriptName(), propertyDescription->getName(), pForwardBundle->currMsgLength()); } Mercury::Bundle* pSendBundle = Mercury::Bundle::ObjPool().createObject(); MERCURY_ENTITY_MESSAGE_FORWARD_CLIENT(getID(), (*pSendBundle), (*pForwardBundle)); pWitness_->sendToClient(ClientInterface::onUpdatePropertys, pSendBundle); Mercury::Bundle::ObjPool().reclaimObject(pForwardBundle); } MemoryStream::ObjPool().reclaimObject(mstream); }
//------------------------------------------------------------------------------------- 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->getScriptName(), methodDescription_->getName(), srcEntity->getID()); 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) <= 0) { e = (*iter)->pEntity(); break; } } if(e == NULL) { PyErr_Format(PyExc_AssertionError, "%s::clientEntity(%s): not found entity(%d), srcEntityID(%d).\n", srcEntity->getScriptName(), methodDescription_->getName(), clientEntityID_, srcEntity->getID()); PyErr_PrintEx(0); return 0; } MethodDescription* methodDescription = getDescription(); if(methodDescription->checkArgs(args)) { MemoryStream* mstream = MemoryStream::ObjPool().createObject(); methodDescription->addToStream(mstream, args); Mercury::Bundle* pForwardBundle = Mercury::Bundle::ObjPool().createObject(); Mercury::Bundle* pSendBundle = Mercury::Bundle::ObjPool().createObject(); srcEntity->pWitness()->addSmartAOIEntityMessageToBundle(pForwardBundle, ClientInterface::onRemoteMethodCall, ClientInterface::onRemoteOtherEntityMethodCall, clientEntityID_); 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("ClientEntityMethod::callmethod: pushUpdateData: ClientInterface::onRemoteOtherEntityMethodCall(%1%::%2%)\n") % srcEntity->getScriptName() % 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(srcEntity->getID(), (*pSendBundle), (*pForwardBundle)); srcEntity->pWitness()->sendToClient(ClientInterface::onRemoteOtherEntityMethodCall, pSendBundle); // 记录这个事件产生的数据量大小 g_publicClientEventHistoryStats.trackEvent(srcEntity->getScriptName(), (std::string(e->getScriptName()) + "." + methodDescription->getName()), pForwardBundle->currMsgLength(), "::"); MemoryStream::ObjPool().reclaimObject(mstream); Mercury::Bundle::ObjPool().reclaimObject(pForwardBundle); } S_Return; }