Esempio n. 1
0
//-------------------------------------------------------------------------------------
void Space::onSpaceDataChanged(const std::string& key, const std::string& value, bool isdel)
{
	// 通知脚本
	if(!isdel)
	{
		SCRIPT_OBJECT_CALL_ARGS3(Cellapp::getSingleton().getEntryScript().get(), const_cast<char*>("onSpaceData"), 
			const_cast<char*>("Iss"), this->id(), key.c_str(), value.c_str());
	}
	else
	{
		SCRIPT_OBJECT_CALL_ARGS3(Cellapp::getSingleton().getEntryScript().get(), const_cast<char*>("onSpaceData"), 
			const_cast<char*>("IsO"), this->id(), key.c_str(), Py_None);
	}

	SPACE_ENTITIES::const_iterator iter = this->entities().begin();
	for(; iter != this->entities().end(); iter++)
	{
		const Entity* pEntity = (*iter).get();

		if(pEntity == NULL || pEntity->isDestroyed() || !pEntity->hasWitness())
			continue;

		Mercury::Bundle* pForwardBundle = Mercury::Bundle::ObjPool().createObject();

		if(!isdel)
		{
			pForwardBundle->newMessage(ClientInterface::setSpaceData);
			(*pForwardBundle) << this->id();
			(*pForwardBundle) << key;
			(*pForwardBundle) << value;
		}
		else
		{
			pForwardBundle->newMessage(ClientInterface::delSpaceData);
			(*pForwardBundle) << this->id();
			(*pForwardBundle) << key;
		}

		Mercury::Bundle* pSendBundle = Mercury::Bundle::ObjPool().createObject();
		MERCURY_ENTITY_MESSAGE_FORWARD_CLIENT(pEntity->id(), (*pSendBundle), (*pForwardBundle));

		if(!isdel)
			pEntity->pWitness()->sendToClient(ClientInterface::setSpaceData, pSendBundle);
		else
			pEntity->pWitness()->sendToClient(ClientInterface::delSpaceData, pSendBundle);

		Mercury::Bundle::ObjPool().reclaimObject(pForwardBundle);
	}
}
Esempio n. 2
0
//-------------------------------------------------------------------------------------
void Space::_addSpaceDatasToEntityClient(const Entity* pEntity)
{
	if(!pEntity)
	{
		return;
	}

	if(pEntity->isDestroyed())
	{
		return;
	}

	if(!pEntity->hasWitness())
	{
		WARNING_MSG(fmt::format("Space::_addSpaceDatasToEntityClient: entity {} no client!\n", 
			pEntity->id()));

		return;
	}

	Mercury::Bundle* pForwardBundle = Mercury::Bundle::ObjPool().createObject();

	pForwardBundle->newMessage(ClientInterface::initSpaceData);
	(*pForwardBundle) << this->id();

	SPACE_DATA::iterator iter = datas_.begin();
	for(; iter != datas_.end(); iter++)
	{
		(*pForwardBundle) << iter->first;
		(*pForwardBundle) << iter->second;
	}

	Mercury::Bundle* pSendBundle = Mercury::Bundle::ObjPool().createObject();
	MERCURY_ENTITY_MESSAGE_FORWARD_CLIENT(pEntity->id(), (*pSendBundle), (*pForwardBundle));

	pEntity->pWitness()->sendToClient(ClientInterface::initSpaceData, pSendBundle);
	Mercury::Bundle::ObjPool().reclaimObject(pForwardBundle);
}
Esempio n. 3
0
//-------------------------------------------------------------------------------------
void Space::_addSpaceGeometryMappingToEntityClient(const Entity* pEntity)
{
	if(!hasGeometry_)
	{
		ERROR_MSG(boost::format("KBEngine::addSpaceGeometryMapping: spaceID=%1%, respath=%2%, hasGeometry = false!\n") %
			getID() % loadGeometryPath_);

		return;
	}

	if(!pEntity)
	{
		return;
	}

	if(pEntity->isDestroyed())
	{
		return;
	}

	if(!pEntity->hasWitness())
	{
		WARNING_MSG(boost::format("Space::_addSpaceGeometryMappingToEntityClient: entity %1% no client!\n") % 
			pEntity->getID());

		return;
	}

	Mercury::Bundle* pForwardBundle = Mercury::Bundle::ObjPool().createObject();
	pForwardBundle->newMessage(ClientInterface::addSpaceGeometryMapping);
	(*pForwardBundle) << this->getID();
	(*pForwardBundle) << loadGeometryPath_;

	Mercury::Bundle* pSendBundle = Mercury::Bundle::ObjPool().createObject();
	MERCURY_ENTITY_MESSAGE_FORWARD_CLIENT(pEntity->getID(), (*pSendBundle), (*pForwardBundle));
	pEntity->pWitness()->sendToClient(ClientInterface::addSpaceGeometryMapping, pSendBundle);
	Mercury::Bundle::ObjPool().reclaimObject(pForwardBundle);
}
//-------------------------------------------------------------------------------------
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;
}
Esempio n. 5
0
//-------------------------------------------------------------------------------------
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);
}
Esempio n. 6
0
//-------------------------------------------------------------------------------------
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;
}