Beispiel #1
0
//-------------------------------------------------------------------------------------
void Baseapp::createInNewSpace(Base* base, PyObject* cell)
{
	ENTITY_ID id = base->getID();
	std::string entityType = base->ob_type->tp_name;
	std::string strCellData = script::Pickler::pickle(base->getCellData());
	uint32 cellDataLength = strCellData.length();

	Mercury::Bundle bundle;

	bundle.newMessage(CellappmgrInterface::reqCreateInNewSpace);

	bundle << entityType;
	bundle << id;
	bundle << componentID_;
	bundle << cellDataLength;

	if(cellDataLength > 0)
		bundle.append(strCellData.data(), cellDataLength);
	
	Components::COMPONENTS& components = Components::getSingleton().getComponents(CELLAPPMGR_TYPE);
	Components::COMPONENTS::iterator iter = components.begin();
	if(iter != components.end())
	{
		bundle.send(this->getNetworkInterface(), (*iter).pChannel);
		return;
	}
	
	ERROR_MSG("Baseapp::createInNewSpace: not found cellappmgr.\n");
}
Beispiel #2
0
//-------------------------------------------------------------------------------------
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);
}
Beispiel #3
0
//-------------------------------------------------------------------------------------		
void ServerApp::queryWatcher(Mercury::Channel* pChannel, MemoryStream& s)
{
	AUTO_SCOPED_PROFILE("watchers");

	std::string path;
	s >> path;

	MemoryStream::SmartPoolObjectPtr readStreamPtr = MemoryStream::createSmartPoolObj();
	WatcherPaths::root().readWatchers(path, readStreamPtr.get()->get());

	MemoryStream::SmartPoolObjectPtr readStreamPtr1 = MemoryStream::createSmartPoolObj();
	WatcherPaths::root().readChildPaths(path, path, readStreamPtr1.get()->get());

	Mercury::Bundle bundle;
	ConsoleInterface::ConsoleWatcherCBMessageHandler msgHandler;
	bundle.newMessage(msgHandler);

	uint8 type = 0;
	bundle << type;
	bundle.append(readStreamPtr.get()->get());
	bundle.send(getNetworkInterface(), pChannel);

	Mercury::Bundle bundle1;
	bundle1.newMessage(msgHandler);

	type = 1;
	bundle1 << type;
	bundle1.append(readStreamPtr1.get()->get());
	bundle1.send(getNetworkInterface(), pChannel);
}
Beispiel #4
0
//-------------------------------------------------------------------------------------
void Cellappmgr::forwardMessage(Mercury::Channel* pChannel, MemoryStream& s)
{
	COMPONENT_ID sender_componentID, forward_componentID;

	s >> sender_componentID >> forward_componentID;
	Components::ComponentInfos* cinfos = Components::getSingleton().findComponent(forward_componentID);
	KBE_ASSERT(cinfos != NULL && cinfos->pChannel != NULL);

	Mercury::Bundle bundle;
	bundle.append((char*)s.data() + s.rpos(), s.opsize());
	bundle.send(this->getNetworkInterface(), cinfos->pChannel);
	s.opfini();
}
Beispiel #5
0
//-------------------------------------------------------------------------------------
void Base::forwardEntityMessageToCellappFromClient(Mercury::Channel* pChannel, MemoryStream& s)
{
	if(pChannel->proxyID() != this->getID())
	{
		WARNING_MSG("Base::forwardEntityMessageToCellappFromClient: not srcEntity(%d/%d).\n", 
			pChannel->proxyID(), this->getID());
		return;
	}

	EntityMailbox* mb = this->getCellMailbox();
	if(mb == NULL)
		return;

	// 将这个消息再打包转寄给cellapp, cellapp会对这个包中的每个消息进行判断
	// 检查是否是entity消息, 否则不合法.
	Mercury::Bundle bundle;
	bundle.newMessage(CellappInterface::forwardEntityMessageToCellappFromClient);
	bundle << this->getID();
	bundle.append(s);
	this->getCellMailbox()->postMail(bundle);
}
Beispiel #6
0
//-------------------------------------------------------------------------------------
void Base::onCellWriteToDBCompleted()
{
	PyObject* pyResult = PyObject_CallMethod(this, 
		const_cast<char*>("onPreArchive"), const_cast<char*>(""));

	if(pyResult != NULL)
		Py_DECREF(pyResult);
	else
		PyErr_PrintEx(0);

	hasDB(true);

	onWriteToDB();

	isArchiveing_ = false;

	MemoryStream* s = MemoryStream::ObjPool().createObject();
	addPersistentsDataToStream(ED_FLAG_ALL, s);

	Components::COMPONENTS cts = Components::getSingleton().getComponents(DBMGR_TYPE);
	Components::ComponentInfos* dbmgrinfos = NULL;

	if(cts.size() > 0)
		dbmgrinfos = &(*cts.begin());

	if(dbmgrinfos == NULL || dbmgrinfos->pChannel == NULL || dbmgrinfos->cid == 0)
	{
		ERROR_MSG("Base::onCellWriteToDBCompleted: not found dbmgr!\n");
		return;
	}

	Mercury::Bundle bundle;
	bundle.newMessage(DbmgrInterface::writeEntity);
	bundle << this->getID();
	bundle << this->getScriptModule()->getUType();
	bundle.append(*s);
	bundle.send(Baseapp::getSingleton().getNetworkInterface(), dbmgrinfos->pChannel);
	MemoryStream::ObjPool().reclaimObject(s);
}
Beispiel #7
0
//-------------------------------------------------------------------------------------
void Baseapp::createCellEntity(EntityMailboxAbstract* createToCellMailbox, Base* base)
{
	if(base->getCellMailbox())
	{
		ERROR_MSG("Baseapp::createCellEntity: %s %d has a cell!\n", base->getScriptName(), base->getID());
		return;
	}

	Mercury::Bundle bundle;
	bundle.newMessage(CellappInterface::onCreateCellEntityFromBaseapp);

	ENTITY_ID id = base->getID();
	std::string entityType = base->ob_type->tp_name;
	std::string strCellData = script::Pickler::pickle(base->getCellData());
	uint32 cellDataLength = strCellData.length();
	EntityMailbox* clientMailbox = base->getClientMailbox();
	bool hasClient = (clientMailbox != NULL);
	
	bundle << createToCellMailbox->getID();				// 在这个mailbox所在的cellspace上创建
	bundle << entityType;
	bundle << id;
	bundle << componentID_;
	bundle << hasClient;
	bundle << cellDataLength;

	if(cellDataLength > 0)
		bundle.append(strCellData.data(), cellDataLength);

	if(createToCellMailbox->getChannel() == NULL)
	{
		ERROR_MSG("Baseapp::createCellEntity: not found cellapp(createToCellMailbox:componentID=%"PRAppID", entityID=%d), create is error!\n", 
			createToCellMailbox->getComponentID(), createToCellMailbox->getID());
		base->onCreateCellFailure();
		return;
	}

	bundle.send(this->getNetworkInterface(), createToCellMailbox->getChannel());
}
Beispiel #8
0
//-------------------------------------------------------------------------------------
void Baseapp::createBaseAnywhere(const char* entityType, PyObject* params, PyObject* pyCallback)
{
	std::string strInitData = "";
	uint32 initDataLength = 0;
	if(params != NULL && PyDict_Check(params))
	{
		strInitData = script::Pickler::pickle(params);
		initDataLength = strInitData.length();
	}

	Mercury::Bundle bundle;
	bundle.newMessage(BaseappmgrInterface::reqCreateBaseAnywhere);

	bundle << entityType;
	bundle << initDataLength;
	if(initDataLength > 0)
		bundle.append(strInitData.data(), initDataLength);

	bundle << componentID_;

	CALLBACK_ID callbackID = 0;
	if(pyCallback != NULL)
	{
		callbackID = callbackMgr().save(pyCallback);
	}

	bundle << callbackID;

	Components::COMPONENTS& components = Components::getSingleton().getComponents(BASEAPPMGR_TYPE);
	Components::COMPONENTS::iterator iter = components.begin();
	if(iter != components.end())
	{
		bundle.send(this->getNetworkInterface(), (*iter).pChannel);
		return;
	}

	ERROR_MSG("Baseapp::createBaseAnywhere: not found baseappmgr.\n");
}
Beispiel #9
0
//-------------------------------------------------------------------------------------
void Baseapp::executeRawDatabaseCommand(const char* datas, uint32 size, PyObject* pycallback)
{
	if(datas == NULL)
	{
		ERROR_MSG("Baseapp::executeRawDatabaseCommand: execute is error!\n");
		return;
	}

	Components::COMPONENTS cts = Components::getSingleton().getComponents(DBMGR_TYPE);
	Components::ComponentInfos* dbmgrinfos = NULL;

	if(cts.size() > 0)
		dbmgrinfos = &(*cts.begin());

	if(dbmgrinfos == NULL || dbmgrinfos->pChannel == NULL || dbmgrinfos->cid == 0)
	{
		ERROR_MSG("Baseapp::executeRawDatabaseCommand: not found dbmgr!\n");
		return;
	}

	DEBUG_MSG("KBEngine::executeRawDatabaseCommand:%s.\n", datas);

	Mercury::Bundle bundle;
	bundle.newMessage(DbmgrInterface::executeRawDatabaseCommand);
	bundle << componentID_ << componentType_;

	CALLBACK_ID callbackID = 0;

	if(pycallback && PyCallable_Check(pycallback))
		callbackID = callbackMgr().save(pycallback);

	bundle << callbackID;
	bundle << size;
	bundle.append(datas, size);
	bundle.send(this->getNetworkInterface(), dbmgrinfos->pChannel);
}
Beispiel #10
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);
}