예제 #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");
}
예제 #2
0
//-------------------------------------------------------------------------------------
void Loginapp::onChannelDeregister(Mercury::Channel * pChannel)
{
	// 如果是外部通道则处理
	if(!pChannel->isInternal())
	{
		const std::string& extra = pChannel->extra();

		// 通知billing从队列中清除他的请求, 避免拥塞
		if(extra.size() > 0)
		{
			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)
			{
			}
			else
			{
				Mercury::Bundle bundle;
				bundle.newMessage(DbmgrInterface::eraseClientReq);
				bundle << extra;
				bundle.send(this->getNetworkInterface(), dbmgrinfos->pChannel);
			}
		}
	}

	ServerApp::onChannelDeregister(pChannel);
}
예제 #3
0
//-------------------------------------------------------------------------------------
void Loginapp::onReqCreateAccountResult(Mercury::Channel* pChannel, MemoryStream& s)
{
	SERVER_ERROR_CODE failedcode;
	std::string accountName;
	std::string password;
	std::string retdatas = "";

	s >> failedcode >> accountName >> password;
	s.readBlob(retdatas);

	DEBUG_MSG(boost::format("Loginapp::onReqCreateAccountResult: accountName=%1%, failedcode=%2%.\n") %
		accountName.c_str() % failedcode);

	PendingLoginMgr::PLInfos* ptinfos = pendingCreateMgr_.remove(accountName);
	if(ptinfos == NULL)
		return;

	Mercury::Channel* pClientChannel = this->getNetworkInterface().findChannel(ptinfos->addr);
	if(pClientChannel == NULL)
		return;

	pClientChannel->extra("");

	Mercury::Bundle bundle;
	bundle.newMessage(ClientInterface::onCreateAccountResult);
	bundle << failedcode;
	bundle.appendBlob(retdatas);

	bundle.send(this->getNetworkInterface(), pClientChannel);

	SAFE_RELEASE(ptinfos);
}
예제 #4
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);
}
예제 #5
0
//-------------------------------------------------------------------------------------
void Base::reqTeleportOther(Mercury::Channel* pChannel, ENTITY_ID reqTeleportEntityID, 
							COMPONENT_ID reqTeleportEntityCellAppID, COMPONENT_ID reqTeleportEntityBaseAppID)
{
	DEBUG_MSG("Base::reqTeleportOther: reqTeleportEntityID=%d, reqTeleportEntityCellAppID=%"PRAppID".\n",
		reqTeleportEntityID, reqTeleportEntityCellAppID);

	if(this->getCellMailbox() == NULL || this->getCellMailbox()->getChannel() == NULL)
	{
		ERROR_MSG("%s::reqTeleportOther: %d, teleport is error, cellMailbox is NULL, reqTeleportEntityID, reqTeleportEntityCellAppID=%"PRAppID".\n",
			this->getScriptName(), this->getID(), reqTeleportEntityID, reqTeleportEntityCellAppID);
		return;
	}

	Components::ComponentInfos* cinfos = Components::getSingleton().findComponent(reqTeleportEntityCellAppID);
	if(cinfos == NULL || cinfos->pChannel == NULL)
	{
		ERROR_MSG("%s::reqTeleportOther: %d, teleport is error, not found cellapp, reqTeleportEntityID, reqTeleportEntityCellAppID=%"PRAppID".\n",
			this->getScriptName(), this->getID(), reqTeleportEntityID, reqTeleportEntityCellAppID);
		return;
	}

	Mercury::Bundle bundle;
	bundle.newMessage(CellappInterface::teleportFromBaseapp);
	bundle << reqTeleportEntityID;
	CellappInterface::teleportFromBaseappArgs3::staticAddToBundle(bundle, this->getCellMailbox()->getComponentID(), this->getID(), reqTeleportEntityBaseAppID);
	bundle.send(Baseapp::getSingleton().getNetworkInterface(), cinfos->pChannel);
}
예제 #6
0
void EntityApp<E>::onExecScriptCommand(Mercury::Channel* pChannel, KBEngine::MemoryStream& s)
{
	std::string cmd;
	s.readBlob(cmd);

	PyObject* pycmd = PyUnicode_DecodeUTF8(cmd.data(), cmd.size(), NULL);
	if(pycmd == NULL)
	{
		SCRIPT_ERROR_CHECK();
		return;
	}

	DEBUG_MSG(boost::format("EntityApp::onExecScriptCommand: size(%1%), command=%2%.\n") % 
		cmd.size() % cmd);

	std::string retbuf = "";
	PyObject* pycmd1 = PyUnicode_AsEncodedString(pycmd, "utf-8", NULL);

	if(script_.run_simpleString(PyBytes_AsString(pycmd1), &retbuf) == 0)
	{
		// 将结果返回给客户端
		Mercury::Bundle bundle;
		ConsoleInterface::ConsoleExecCommandCBMessageHandler msgHandler;
		bundle.newMessage(msgHandler);
		ConsoleInterface::ConsoleExecCommandCBMessageHandlerArgs1::staticAddToBundle(bundle, retbuf);
		bundle.send(this->getNetworkInterface(), pChannel);
	}

	Py_DECREF(pycmd);
	Py_DECREF(pycmd1);
}
예제 #7
0
//-------------------------------------------------------------------------------------
void TelnetHandler::processPythonCommand(std::string command)
{
	if(pTelnetServer_->pScript() == NULL || command.size() == 0)
		return;
	
	command += "\n";
	PyObject* pycmd = PyUnicode_DecodeUTF8(command.data(), command.size(), NULL);
	if(pycmd == NULL)
	{
		SCRIPT_ERROR_CHECK();
		return;
	}

	DEBUG_MSG(boost::format("TelnetHandler::processPythonCommand: size(%1%), command=%2%.\n") % 
		command.size() % command);

	std::string retbuf = "";
	PyObject* pycmd1 = PyUnicode_AsEncodedString(pycmd, "utf-8", NULL);

	pTelnetServer_->pScript()->run_simpleString(PyBytes_AsString(pycmd1), &retbuf);

	if(retbuf.size() > 0)
	{
		// 将结果返回给客户端
		Mercury::Bundle bundle;
		bundle << retbuf;
		bundle.send(*pEndPoint_);
		sendEnter();
	}

	Py_DECREF(pycmd);
	Py_DECREF(pycmd1);
}
예제 #8
0
//-------------------------------------------------------------------------------------
bool ClientObject::loginGateWay()
{
	// 请求登录网关
	Mercury::Bundle bundle;
	bundle.newMessage(BaseappInterface::loginGateway);
	bundle << name_;
	bundle << password_;
	bundle.send(*pChannel_->endpoint());
	return true;
}
예제 #9
0
//-------------------------------------------------------------------------------------
bool ClientObject::createAccount()
{
	// 创建账号
	Mercury::Bundle bundle;
	bundle.newMessage(LoginappInterface::reqCreateAccount);
	bundle << name_;
	bundle << password_;
	bundle.send(*pChannel_->endpoint());
	return true;
}
예제 #10
0
//-------------------------------------------------------------------------------------
void Loginapp::reqAccountResetPassword(Mercury::Channel* pChannel, std::string& accountName)
{
	AUTO_SCOPED_PROFILE("reqAccountResetPassword");

	accountName = KBEngine::strutil::kbe_trim(accountName);
	INFO_MSG(boost::format("Loginapp::reqAccountResetPassword: accountName(%1%)\n") %
		accountName);

	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(boost::format("Loginapp::_createAccount: create(%1%), not found dbmgr!\n") % 
			accountName);

		Mercury::Bundle bundle;
		bundle.newMessage(ClientInterface::onReqAccountResetPasswordCB);
		SERVER_ERROR_CODE retcode = SERVER_ERR_SRV_NO_READY;
		bundle << retcode;
		bundle.send(this->getNetworkInterface(), pChannel);
		return;
	}

	{
		Mercury::Bundle bundle;
		bundle.newMessage(DbmgrInterface::accountReqResetPassword);
		bundle << accountName;
		bundle.send(this->getNetworkInterface(), dbmgrinfos->pChannel);
	}

	{
		Mercury::Bundle bundle;
		bundle.newMessage(ClientInterface::onReqAccountResetPasswordCB);
		SERVER_ERROR_CODE retcode = SERVER_SUCCESS;
		bundle << retcode;
		bundle.send(this->getNetworkInterface(), pChannel);
	}
}
예제 #11
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();
}
예제 #12
0
void EntityApp<E>::onExecScriptCommand(Mercury::Channel* pChannel, std::string& strcommand)
{
	DEBUG_MSG("EntityApp::onExecScriptCommand: command size(%d).\n", strcommand.size());

	std::string retbuf = "";
	if(script_.run_simpleString(strcommand, &retbuf) == 0)
	{
		// 将结果返回给客户端
		Mercury::Bundle bundle;
		ConsoleInterface::ConsoleExecCommandCBMessageHandler msgHandler;
		bundle.newMessage(msgHandler);
		ConsoleInterface::ConsoleExecCommandCBMessageHandlerArgs1::staticAddToBundle(bundle, retbuf);
		bundle.send(this->getNetworkInterface(), pChannel);
	}
}
예제 #13
0
void CLogWindow::OnBnClickedButton1()
{
	// TODO: Add your control notification handler code here
	// 请求服务器拉取日志
	CguiconsoleDlg* dlg = static_cast<CguiconsoleDlg*>(theApp.m_pMainWnd);
	
	HTREEITEM item = dlg->hasCheckApp(MESSAGELOG_TYPE);
	if(item == NULL)
	{
		::AfxMessageBox(L"messagelog no select!");
		return;
	}

	Mercury::Address addr = dlg->getTreeItemAddr(item);

	Mercury::Channel* pChannel = dlg->networkInterface().findChannel(addr);
	if(pChannel == NULL)
	{
		::AfxMessageBox(L"messagelog is error!");
		return;
	}

	Mercury::Bundle bundle;
	bundle.newMessage(MessagelogInterface::registerLogWatcher);

	bundle << getSelLogTypes();
	
	CString apporder;
	m_appIDEdit.GetWindowTextW(apporder);

	char* cs = KBEngine::strutil::wchar2char(apporder.GetBuffer(0));
	COMPONENT_ORDER order = atoi(cs);
	free(cs);

	bundle << order;

	int8 count = 0;
	std::vector<KBEngine::COMPONENT_TYPE> vec = getSelComponents();
	count = vec.size();
	bundle << count;
	std::vector<KBEngine::COMPONENT_TYPE>::iterator iter = vec.begin();
	for(; iter != vec.end(); iter++)
	{
		bundle << (*iter);
	}

	bundle.send(dlg->networkInterface(), pChannel);
}
예제 #14
0
//-------------------------------------------------------------------------------------
bool Base::destroyCellEntity(void)
{
	if(isDestroyed())	
	{
		return false;																					
	}

	if(cellMailbox_  == NULL || cellMailbox_->getChannel() == NULL)
		return false;

	Mercury::Bundle bundle;
	bundle.newMessage(CellappInterface::onDestroyCellEntityFromBaseapp);
	bundle << id_;
	bundle.send(Baseapp::getSingleton().getNetworkInterface(), cellMailbox_->getChannel());
	return true;
}
예제 #15
0
//-------------------------------------------------------------------------------------
void ClientObject::sendTick()
{
	// 向服务器发送tick
	uint64 check = uint64( Mercury::g_channelExternalTimeout * stampsPerSecond() ) / 2;
	if (timestamp() - lastSentActiveTickTime_ > check)
	{
		lastSentActiveTickTime_ = timestamp();

		Mercury::Bundle bundle;
		if(connectedGateway_)
			bundle.newMessage(BaseappInterface::onClientActiveTick);
		else
			bundle.newMessage(LoginappInterface::onClientActiveTick);
		bundle.send(*pChannel_->endpoint());
	}
}
예제 #16
0
//-------------------------------------------------------------------------------------
void EntityIDClient::onAlloc(void)
{
	if(hasReqServerAlloc() || getSize() > ID_ENOUGH_LIMIT || idList_.size() > 0)
		return;
	
	Mercury::Bundle bundle;
	bundle.newMessage(DbmgrInterface::onReqAllocEntityID);
	DbmgrInterface::onReqAllocEntityIDArgs2::staticAddToBundle(bundle, pApp_->componentType(), pApp_->componentID());

	Components::COMPONENTS cts =  Components::getSingleton().getComponents(DBMGR_TYPE);
	KBE_ASSERT(cts.size() > 0);
	Components::ComponentInfos* cinfos = &(*cts.begin());
	KBE_ASSERT(cinfos->pChannel != NULL);

	bundle.send(pApp_->getNetworkInterface(), cinfos->pChannel);
	ERROR_MSG("EntityIDClient::onAlloc: not enough(%d) entityIDs!\n", ID_ENOUGH_LIMIT);
}
예제 #17
0
//-------------------------------------------------------------------------------------
bool EntityMailboxAbstract::postMail(Mercury::Bundle& bundle)
{
	KBE_ASSERT(Components::getSingleton().pNetworkInterface() != NULL);
	Mercury::Channel* pChannel = getChannel();

	if(pChannel && !pChannel->isDead())
	{
		bundle.send(*Components::getSingleton().pNetworkInterface(), pChannel);
		return true;
	}
	else
	{
		ERROR_MSG("EntityMailboxAbstract::postMail: invalid channel(%s)!\n", addr_.c_str());
	}

	return false;
}
예제 #18
0
//-------------------------------------------------------------------------------------
void Baseapp::onGetEntityAppFromDbmgr(Mercury::Channel* pChannel, int32 uid, std::string& username, 
						int8 componentType, uint64 componentID, 
						uint32 intaddr, uint16 intport, uint32 extaddr, uint16 extport)
{
	if(pChannel->isExternal())
		return;

	EntityApp<Base>::onRegisterNewApp(pChannel, uid, username, componentType, componentID, 
									intaddr, intport, extaddr, extport);

	KBEngine::COMPONENT_TYPE tcomponentType = (KBEngine::COMPONENT_TYPE)componentType;

	Components::COMPONENTS cts = Componentbridge::getComponents().getComponents(DBMGR_TYPE);
	KBE_ASSERT(cts.size() >= 1);
	
	Components::ComponentInfos* cinfos = Componentbridge::getComponents().findComponent(tcomponentType, uid, componentID);
	cinfos->pChannel = NULL;

	int ret = Components::getSingleton().connectComponent(tcomponentType, uid, componentID);
	KBE_ASSERT(ret != -1);

	Mercury::Bundle bundle;

	switch(tcomponentType)
	{
	case BASEAPP_TYPE:
		bundle.newMessage(BaseappInterface::onRegisterNewApp);
		BaseappInterface::onRegisterNewAppArgs8::staticAddToBundle(bundle, getUserUID(), getUsername(), BASEAPP_TYPE, componentID_, 
			this->getNetworkInterface().intaddr().ip, this->getNetworkInterface().intaddr().port, 
			this->getNetworkInterface().extaddr().ip, this->getNetworkInterface().extaddr().port);
		break;
	case CELLAPP_TYPE:
		bundle.newMessage(CellappInterface::onRegisterNewApp);
		CellappInterface::onRegisterNewAppArgs8::staticAddToBundle(bundle, getUserUID(), getUsername(), BASEAPP_TYPE, componentID_, 
			this->getNetworkInterface().intaddr().ip, this->getNetworkInterface().intaddr().port, 
			this->getNetworkInterface().extaddr().ip, this->getNetworkInterface().extaddr().port);
		break;
	default:
		KBE_ASSERT(false && "no support!\n");
		break;
	};
	
	bundle.send(this->getNetworkInterface(), cinfos->pChannel);
}
예제 #19
0
//-------------------------------------------------------------------------------------
bool ClientObject::login()
{
	if(error_ != C_ERROR_NONE)
		return false;

	Mercury::Bundle bundle;

	std::string bindatas = "bots client";

	// 提交账号密码请求登录
	bundle.newMessage(LoginappInterface::login);
	CLIENT_CTYPE tclient = CLIENT_TYPE_BOTS;
	bundle << tclient;
	bundle.appendBlob(bindatas);
	bundle << name_;
	bundle << password_;
	bundle.send(*pChannel_->endpoint());
	return true;
}
예제 #20
0
//-------------------------------------------------------------------------------------
void Machine::onFindInterfaceAddr(Mercury::Channel* pChannel, int32 uid, std::string& username, int8 componentType, 
								  int8 findComponentType, uint32 finderAddr, uint16 finderRecvPort)
{
	INFO_MSG("Machine::onFindInterfaceAddr: uid:%d, username:%s, componentType:%s, "
		"find:%s, finderaddr:%s, finderRecvPort:%u.\n", 
		uid, username.c_str(), COMPONENT_NAME_EX((COMPONENT_TYPE)componentType),  COMPONENT_NAME_EX((COMPONENT_TYPE)findComponentType), 
		inet_ntoa((struct in_addr&)finderAddr), ntohs(finderRecvPort));

	Mercury::EndPoint ep;
	ep.socket(SOCK_DGRAM);

	if (!ep.good())
	{
		ERROR_MSG("Machine::onFindInterfaceAddr: Failed to create socket.\n");
		return;
	}
	
	const Components::ComponentInfos* pinfos = 
		Componentbridge::getComponents().findComponent((KBEngine::COMPONENT_TYPE)findComponentType, uid, 0);
	
	Mercury::Bundle bundle;

	if(pinfos == NULL)
	{
		WARNING_MSG("Machine::onFindInterfaceAddr: %s not found %s.\n", COMPONENT_NAME_EX((COMPONENT_TYPE)componentType), 
			COMPONENT_NAME_EX((COMPONENT_TYPE)findComponentType));

		MachineInterface::onBroadcastInterfaceArgs8::staticAddToBundle(bundle, 0, 
			"", UNKNOWN_COMPONENT_TYPE, 0, 0, 0, 0, 0);
	}
	else
		MachineInterface::onBroadcastInterfaceArgs8::staticAddToBundle(bundle, pinfos->uid, 
			pinfos->username, findComponentType, pinfos->cid, pinfos->pIntAddr->ip, pinfos->pIntAddr->port,
			pinfos->pExtAddr->ip, pinfos->pExtAddr->port);
	
	if(finderAddr != 0 && finderRecvPort != 0)
		bundle.sendto(ep, finderRecvPort, finderAddr);
	else
		bundle.send(this->getNetworkInterface(), pChannel);
}
예제 #21
0
//-------------------------------------------------------------------------------------
void Loginapp::onReqCreateMailAccountResult(Mercury::Channel* pChannel, MemoryStream& s)
{
	SERVER_ERROR_CODE failedcode;
	std::string accountName;
	std::string password;
	std::string retdatas = "";

	s >> failedcode >> accountName >> password;
	s.readBlob(retdatas);

	DEBUG_MSG(boost::format("Loginapp::onReqCreateMailAccountResult: accountName=%1%, failedcode=%2%.\n") %
		accountName.c_str() % failedcode);

	if(failedcode == SERVER_SUCCESS)
	{
		threadPool_.addTask(new SendActivateEMailTask(accountName, retdatas, 
			g_kbeSrvConfig.getLoginApp().http_cbhost, 
			g_kbeSrvConfig.getLoginApp().http_cbport));
	}

	PendingLoginMgr::PLInfos* ptinfos = pendingCreateMgr_.remove(accountName);
	if(ptinfos == NULL)
		return;

	Mercury::Channel* pClientChannel = this->getNetworkInterface().findChannel(ptinfos->addr);
	if(pClientChannel == NULL)
		return;

	pClientChannel->extra("");
	retdatas = "";

	Mercury::Bundle bundle;
	bundle.newMessage(ClientInterface::onCreateAccountResult);
	bundle << failedcode;
	bundle.appendBlob(retdatas);

	bundle.send(this->getNetworkInterface(), pClientChannel);

	SAFE_RELEASE(ptinfos);
}
예제 #22
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);
}
예제 #23
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());
}
예제 #24
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");
}
예제 #25
0
//-------------------------------------------------------------------------------------
void ServerApp::handleTimeout(TimerHandle, void * arg)
{
    switch (reinterpret_cast<uintptr>(arg))
    {
    case TIMEOUT_ACTIVE_TICK:
    {
        int8 findComponentTypes[] = {BASEAPPMGR_TYPE, CELLAPPMGR_TYPE, DBMGR_TYPE, CELLAPP_TYPE,
                                     BASEAPP_TYPE, LOGINAPP_TYPE, MESSAGELOG_TYPE, RESOURCEMGR_TYPE, UNKNOWN_COMPONENT_TYPE
                                    };

        int ifind = 0;
        while(findComponentTypes[ifind] != UNKNOWN_COMPONENT_TYPE)
        {
            COMPONENT_TYPE componentType = (COMPONENT_TYPE)findComponentTypes[ifind];

            Components::COMPONENTS& components = Components::getSingleton().getComponents(componentType);
            Components::COMPONENTS::iterator iter = components.begin();
            for(; iter != components.end(); iter++)
            {
                Mercury::Bundle bundle;
                COMMON_MERCURY_MESSAGE(componentType, bundle, onAppActiveTick);

                bundle << g_componentType;
                bundle << componentID_;
                if((*iter).pChannel != NULL)
                    bundle.send(getNetworkInterface(), (*iter).pChannel);
            }

            ifind++;
        }
        break;
    }
    default:
        break;
    }
}
예제 #26
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;


	Mercury::Channel* pChannel = Messagelog::getSingleton().getNetworkInterface().findChannel(addr_);

	if(pChannel == NULL)
		return;

	Mercury::Bundle bundle;
	ConsoleInterface::ConsoleLogMessageHandler msgHandler;
	bundle.newMessage(msgHandler);
	bundle << sstr.str().c_str();
	bundle.send(Messagelog::getSingleton().getNetworkInterface(), pChannel);
}
예제 #27
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);
}
예제 #28
0
//-------------------------------------------------------------------------------------
void Machine::stopserver(Mercury::Channel* pChannel, KBEngine::MemoryStream& s)
{
	int32 uid = 0;
	COMPONENT_TYPE componentType;
	uint32 recvip;
	uint16 recvport;
	Mercury::Bundle bundle;
	bool success = true;

	s >> uid;
	s >> componentType;
	s >> recvip;
	s >> recvport;

	Mercury::EndPoint ep;
	ep.socket(SOCK_DGRAM);

	if (!ep.good())
	{
		ERROR_MSG("Machine::stopserver: Failed to create socket.\n");
		return;
	}
	
	Components::COMPONENTS& components = Componentbridge::getComponents().getComponents(componentType);
	Components::COMPONENTS::iterator iter = components.begin();

	Components::ComponentInfos* cinfos = NULL;

	for(; iter != components.end(); )
	{
		if((*iter).uid != uid)
			continue;

		if(componentType != (*iter).componentType)
		{
			continue;
		}

		bool usable = Componentbridge::getComponents().checkComponentUsable(&(*iter));
		
		if(!usable)
		{
			success = true;
			break;
		}

		cinfos = &(*iter);
		Mercury::Bundle closebundle;
		COMMON_MERCURY_MESSAGE(componentType, closebundle, reqCloseServer);

		Mercury::EndPoint ep1;
		ep1.socket(SOCK_STREAM);

		if (!ep1.good())
		{
			ERROR_MSG("Machine::stopserver: Failed to create socket.\n");
			success = false;
			break;
		}
		
		if(ep1.connect((*iter).pIntAddr.get()->port, (*iter).pIntAddr.get()->ip) == -1)
		{
			ERROR_MSG("Machine::stopserver: connect server is error(%s)!\n", kbe_strerror());
			success = false;
			break;
		}

		closebundle.send(ep1);
		Mercury::TCPPacket recvpacket;
		recvpacket.resize(255);
		int len = ep1.recv(recvpacket.data(), 1);
		if(len != 1)
		{
			success = false;
			break;
		}

		recvpacket >> success;
		break;
	}

	bundle << success;
	bundle.sendto(ep, recvport, recvip);
}
예제 #29
0
//-------------------------------------------------------------------------------------
bool RestoreEntityHandler::process()
{
	Components::COMPONENTS& cts = Components::getSingleton().getComponents(CELLAPP_TYPE);
	Mercury::Channel* pChannel = NULL;

	if(cts.size() > 0)
	{
		Components::COMPONENTS::iterator ctiter = cts.begin();
		if((*ctiter).pChannel == NULL)
			return true;

		pChannel = (*ctiter).pChannel;
	}

	if(pChannel == NULL)
		return true;

	int count = 0;

	// 首先需要找到这个cell上的space
	// KBE_ASSERT(restoreSpaces_.size() > 0);
	// 如果spaceEntity不在这个baseapp上创建则继续等待
	// 当spaceEntity的cell创建好了之后会广播给所有的baseapp, 每个baseapp
	// 去判断是否有需要恢复的entity
	if(restoreSpaces_.size() > 0)
	{
		if(timestamp() - tickReport_ > uint64( 3 * stampsPerSecond() ))
		{
			tickReport_ = timestamp();
			INFO_MSG(boost::format("RestoreEntityHandler::process(%3%): wait for localSpace to get cell!, entitiesSize(%1%), spaceSize=%2%\n") % 
				entities_.size() % restoreSpaces_.size() % cellappID_);
		}

		int spaceCellCount = 0;

		// 必须等待space恢复
		std::vector<RestoreData>::iterator restoreSpacesIter = restoreSpaces_.begin();
		for(; restoreSpacesIter != restoreSpaces_.end(); restoreSpacesIter++)
		{
			Base* pBase = Baseapp::getSingleton().findEntity((*restoreSpacesIter).id);
			
			if(pBase)
			{
				if(++count > (int)g_kbeSrvConfig.getBaseApp().entityRestoreSize)
				{
					return true;
				}

				if((*restoreSpacesIter).creatingCell == false)
				{
					(*restoreSpacesIter).creatingCell = true;
					pBase->restoreCell(NULL);
				}
				else
				{
					if(pBase->cellMailbox() == NULL)
					{
						return true;
					}
					else
					{
						spaceCellCount++;
						if(!(*restoreSpacesIter).processed)
						{
							(*restoreSpacesIter).processed = true;
							pBase->onRestore();
						}
					}
				}
			}
			else
			{
				ERROR_MSG(boost::format("RestoreEntityHandler::process(%1%): lose space(%2%).\n") % cellappID_ % (*restoreSpacesIter).id);
			}
		}
		
		if(spaceCellCount != (int)restoreSpaces_.size())
			return true;

		// 通知其他baseapp, space恢复了cell
		if(!broadcastOtherBaseapps_)
		{
			broadcastOtherBaseapps_ = true;

			INFO_MSG(boost::format("RestoreEntityHandler::process(%1%): begin broadcast-spaceGetCell to otherBaseapps...\n") % cellappID_);

			std::vector<RestoreData>::iterator restoreSpacesIter = restoreSpaces_.begin();
			for(; restoreSpacesIter != restoreSpaces_.end(); restoreSpacesIter++)
			{
				Base* pBase = Baseapp::getSingleton().findEntity((*restoreSpacesIter).id);
				bool destroyed = (pBase == NULL || pBase->isDestroyed());
				COMPONENT_ID baseappID = g_componentID;
				COMPONENT_ID cellappID = 0;
				SPACE_ID spaceID = (*restoreSpacesIter).spaceID;
				ENTITY_ID spaceEntityID = (*restoreSpacesIter).id;
				ENTITY_SCRIPT_UID utype = 0;

				if(!destroyed)
				{
					utype = pBase->scriptModule()->getUType();
					cellappID = pBase->cellMailbox()->componentID();
				}

				spaceIDs_.erase(std::remove(spaceIDs_.begin(), spaceIDs_.end(), spaceID), spaceIDs_.end());

				Mercury::Channel* pChannel = NULL;
				Components::COMPONENTS& cts = Componentbridge::getComponents().getComponents(BASEAPP_TYPE);
				Components::COMPONENTS::iterator comsiter = cts.begin();
				for(; comsiter != cts.end(); comsiter++)
				{
					pChannel = (*comsiter).pChannel;
					
					if(pChannel)
					{
						INFO_MSG(boost::format("RestoreEntityHandler::process(%5%): broadcast baseapp[%1%, %2%], spaceID[%3%], utype[%4%]...\n") % 
							(*comsiter).cid % pChannel->c_str() % spaceID % utype % cellappID_);

						Mercury::Bundle* pBundle = Mercury::Bundle::ObjPool().createObject();
						(*pBundle).newMessage(BaseappInterface::onRestoreSpaceCellFromOtherBaseapp);
						(*pBundle) << baseappID << cellappID << spaceID << spaceEntityID << utype << destroyed;
						pBundle->send(Baseapp::getSingleton().getNetworkInterface(), pChannel);
						Mercury::Bundle::ObjPool().reclaimObject(pBundle);
					}
				}
			}
		}
	}

	if(spaceIDs_.size() > 0)
	{
		if(timestamp() - tickReport_ > uint64( 3 * stampsPerSecond() ))
		{
			tickReport_ = timestamp();
			INFO_MSG(boost::format("RestoreEntityHandler::process(%1%): wait for otherBaseappSpaces to get cell!, entitiesSize(%2%), spaceSize=%3%\n") % 
				cellappID_ % entities_.size() % spaceIDs_.size());
		}

		return true;
	}

	// 恢复其他entity
	std::vector<RestoreData>::iterator iter = entities_.begin();
	for(; iter != entities_.end(); )
	{
		RestoreData& data = (*iter);
		Base* pBase = Baseapp::getSingleton().findEntity(data.id);

		if(pBase)
		{
			if(++count > g_kbeSrvConfig.getBaseApp().entityRestoreSize)
			{
				return true;
			}

			if(pBase->cellMailbox() != NULL)
			{
				if(!data.processed)
				{
					data.processed = true;
					pBase->onRestore();
				}

				iter = entities_.erase(iter);
			}
			else
			{
				if(!data.creatingCell)
				{
					data.creatingCell = true;
					
					EntityMailboxAbstract* cellMailbox = NULL;
					std::vector<RestoreData>::iterator restoreSpacesIter = restoreSpaces_.begin();
					for(; restoreSpacesIter != restoreSpaces_.end(); restoreSpacesIter++)
					{
						Base* pSpace = Baseapp::getSingleton().findEntity((*restoreSpacesIter).id);
						if(pSpace && pBase->spaceID() == pSpace->spaceID())
						{
							cellMailbox = pSpace->cellMailbox();
							break;
						}
					}
					
					if(cellMailbox == NULL)
					{
						restoreSpacesIter = otherRestoredSpaces_.begin();
						for(; restoreSpacesIter != otherRestoredSpaces_.end(); restoreSpacesIter++)
						{
							if(pBase->spaceID() == (*restoreSpacesIter).spaceID && (*restoreSpacesIter).cell)
							{
								cellMailbox = (*restoreSpacesIter).cell;
								break;
							}
						}
					}

					if(cellMailbox)
					{
						pBase->restoreCell(cellMailbox);
					}
					else
					{
						ENTITY_ID delID = pBase->id();

						pBase->destroy();
						WARNING_MSG(boost::format("RestoreEntityHandler::process(%1%): not fount spaceCell, killed base(%2%)!") 
							% cellappID_ % delID);

						if(Baseapp::getSingleton().findEntity(delID) == NULL)
							iter = entities_.erase(iter);

						continue;
					}
				}

				iter++;
			}
		}
		else
		{
			iter = entities_.erase(iter);
		}
	}

	if(entities_.size() == 0)
	{
		std::vector<RestoreData>::iterator restoreSpacesIter = otherRestoredSpaces_.begin();
		for(; restoreSpacesIter != otherRestoredSpaces_.end(); restoreSpacesIter++)
		{
			if((*restoreSpacesIter).cell)
			{
				Py_DECREF((*restoreSpacesIter).cell);
				(*restoreSpacesIter).cell = NULL;
			}
		}
		
		otherRestoredSpaces_.clear();

		inProcess_ = false;
		Baseapp::getSingleton().onRestoreEntitiesOver(this);
		return false;
	}

	return true;
}
예제 #30
0
//-------------------------------------------------------------------------------------
void Baseapp::onCreateBaseAnywhere(Mercury::Channel* pChannel, MemoryStream& s)
{
	if(pChannel->isExternal())
		return;

	std::string strInitData = "";
	uint32 initDataLength = 0;
	PyObject* params = NULL;
	std::string entityType;
	COMPONENT_ID componentID;
	CALLBACK_ID callbackID;

	s >> entityType;
	s >> initDataLength;

	if(initDataLength > 0)
	{
		strInitData.assign((char*)(s.data() + s.rpos()), initDataLength);
		s.read_skip(initDataLength);
	}

	s >> componentID;
	s >> callbackID;

	if(strInitData.size() > 0)
		params = script::Pickler::unpickle(strInitData);

	Base* base = createEntityCommon(entityType.c_str(), params);
	Py_XDECREF(params);

	if(base == NULL)
		return;

	// 如果不是在发起创建entity的baseapp上创建则需要转发回调到发起方
	if(componentID != componentID_)
	{
		Components::ComponentInfos* cinfos = Components::getSingleton().findComponent(componentID);
		if(cinfos == NULL || cinfos->pChannel == NULL)
		{
			ForwardItem* pFI = new ForwardItem();
			pFI->pHandler = NULL;
			pFI->bundle.newMessage(BaseappInterface::onCreateBaseAnywhereCallback);
			pFI->bundle << callbackID;
			pFI->bundle << entityType;
			pFI->bundle << base->getID();
			pFI->bundle << componentID_;
			forward_messagebuffer_.push(componentID, pFI);
			WARNING_MSG("Baseapp::onCreateBaseAnywhere: not found baseapp, message is buffered.\n");
			return;
		}

		Mercury::Channel* lpChannel = cinfos->pChannel;

		// 需要baseappmgr转发给目的baseapp
		Mercury::Bundle forwardbundle;
		forwardbundle.newMessage(BaseappInterface::onCreateBaseAnywhereCallback);
		forwardbundle << callbackID;
		forwardbundle << entityType;
		forwardbundle << base->getID();
		forwardbundle << componentID_;
		forwardbundle.send(this->getNetworkInterface(), lpChannel);
	}
	else
	{
		ENTITY_ID eid = base->getID();
		_onCreateBaseAnywhereCallback(NULL, callbackID, entityType, eid, componentID_);
	}
}