//-------------------------------------------------------------------------------------
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_;
    }
}
예제 #3
0
//-------------------------------------------------------------------------------------
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_;
	}
}
예제 #4
0
//-------------------------------------------------------------------------------------
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);
}
예제 #5
0
//-------------------------------------------------------------------------------------
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);
}
예제 #6
0
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);
}
예제 #7
0
//-------------------------------------------------------------------------------------
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;
}	
예제 #8
0
//-------------------------------------------------------------------------------------
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);
}
예제 #9
0
파일: base.cpp 프로젝트: ihuangx/kbengine
//-------------------------------------------------------------------------------------
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);
}
예제 #10
0
//-------------------------------------------------------------------------------------
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;
}
예제 #12
0
//-------------------------------------------------------------------------------------
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; 
}
예제 #13
0
//-------------------------------------------------------------------------------------		
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;
		}
예제 #14
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->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;
}
예제 #15
0
//-------------------------------------------------------------------------------------
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;
}	
예제 #16
0
//-------------------------------------------------------------------------------------
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();
    }
}
예제 #17
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->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;
}
예제 #18
0
//-------------------------------------------------------------------------------------
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;
}