Beispiel #1
0
//-------------------------------------------------------------------------------------
void ClientApp::handleGameTick()
{
	g_kbetime++;
	threadPool_.onMainThreadTick();
	
	networkInterface().processChannels(KBEngine::Network::MessageHandlers::pMainMessageHandlers);
	tickSend();

	switch(state_)
	{
		case C_STATE_INIT:
			state_ = C_STATE_PLAY;
			break;
		case C_STATE_INITLOGINAPP_CHANNEL:
			state_ = C_STATE_PLAY;
			break;
		case C_STATE_LOGIN:

			state_ = C_STATE_PLAY;

			if(!ClientObjectBase::login())
			{
				WARNING_MSG("ClientApp::handleGameTick: login is failed!\n");
				return;
			}

			break;
		case C_STATE_LOGIN_GATEWAY_CHANNEL:
			{
				state_ = C_STATE_PLAY;

				bool ret = updateChannel(false, "", "", "", 0);
				if(ret)
				{
					// 先握手然后等helloCB之后再进行登录
					Network::Bundle* pBundle = Network::Bundle::ObjPool().createObject();
					(*pBundle).newMessage(BaseappInterface::hello);
					(*pBundle) << KBEVersion::versionString();
					(*pBundle) << KBEVersion::scriptVersionString();

					if(Network::g_channelExternalEncryptType == 1)
					{
						pBlowfishFilter_ = new Network::BlowfishFilter();
						(*pBundle).appendBlob(pBlowfishFilter_->key());
						pServerChannel_->pFilter(NULL);
					}
					else
					{
						std::string key = "";
						(*pBundle).appendBlob(key);
					}

					pServerChannel_->pEndPoint()->send(pBundle);
					Network::Bundle::ObjPool().reclaimObject(pBundle);
					// ret = ClientObjectBase::loginGateWay();
				}
			}
			break;
		case C_STATE_LOGIN_GATEWAY:

			state_ = C_STATE_PLAY;

			if(!ClientObjectBase::loginGateWay())
			{
				WARNING_MSG("ClientApp::handleGameTick: loginGateWay is failed!\n");
				return;
			}

			break;
		case C_STATE_PLAY:
			break;
		default:
			KBE_ASSERT(false);
			break;
	};
}
Beispiel #2
0
//-------------------------------------------------------------------------------------
void ClientObject::gameTick()
{
    if(pServerChannel()->pEndPoint())
    {
        pServerChannel()->processPackets(NULL);
    }
    else
    {
        if(connectedGateway_)
        {
            EventData_ServerCloased eventdata;
            eventHandler_.fire(&eventdata);
            connectedGateway_ = false;
            canReset_ = true;
            state_ = C_STATE_INIT;

            DEBUG_MSG(fmt::format("ClientObject({})::tickSend: serverCloased! name({})!\n",
                                  this->appID(), this->name()));
        }
    }

    if(locktime() > 0 && timestamp() < locktime())
    {
        return;
    }

    switch(state_)
    {
    case C_STATE_INIT:

        state_ = C_STATE_PLAY;

        if(!initCreate())
            return;

        break;
    case C_STATE_CREATE:

        state_ = C_STATE_PLAY;

        if(!createAccount())
            return;

        break;
    case C_STATE_LOGIN:

        state_ = C_STATE_PLAY;

        if(!login())
            return;

        break;
    case C_STATE_LOGIN_GATEWAY_CREATE:

        state_ = C_STATE_PLAY;

        if(!initLoginGateWay())
            return;

        break;
    case C_STATE_LOGIN_GATEWAY:

        state_ = C_STATE_PLAY;

        if(!loginGateWay())
            return;

        break;
    case C_STATE_PLAY:
        break;
    default:
        KBE_ASSERT(false);
        break;
    };

    tickSend();
}
Beispiel #3
0
//-------------------------------------------------------------------------------------
void ClientObject::gameTick()
{
	if(pServerChannel()->endpoint())
	{
		pServerChannel()->processPackets(NULL);
	}
	else
	{
		if(connectedGateway_)
		{
			EventData_ServerCloased eventdata;
			eventHandler_.fire(&eventdata);
			connectedGateway_ = false;
			canReset_ = true;
		}
	}

	switch(state_)
	{
		case C_STATE_INIT:

			state_ = C_STATE_PLAY;

			if(!initCreate())
				return;

			break;
		case C_STATE_CREATE:

			state_ = C_STATE_PLAY;

			if(!createAccount())
				return;

			break;
		case C_STATE_LOGIN:

			state_ = C_STATE_PLAY;

			if(!login())
				return;

			break;
		case C_STATE_LOGIN_GATEWAY_CREATE:

			state_ = C_STATE_PLAY;

			if(!initLoginGateWay())
				return;

			break;
		case C_STATE_LOGIN_GATEWAY:

			state_ = C_STATE_PLAY;

			if(!loginGateWay())
				return;

			break;
		case C_STATE_PLAY:
			break;
		default:
			KBE_ASSERT(false);
			break;
	};

	tickSend();
}
Beispiel #4
0
//-------------------------------------------------------------------------------------
void ClientApp::handleGameTick()
{
	g_kbetime++;
	threadPool_.onMainThreadTick();
	handleTimers();
	
	if(lastAddr.ip != 0)
	{
		getNetworkInterface().deregisterChannel(lastAddr);
		getNetworkInterface().registerChannel(pServerChannel_);
		lastAddr.ip = 0;
	}

	getNetworkInterface().processAllChannelPackets(KBEngine::Mercury::MessageHandlers::pMainMessageHandlers);
	tickSend();

	switch(state_)
	{
		case C_STATE_INIT:
			state_ = C_STATE_PLAY;
			break;
		case C_STATE_INITLOGINAPP_CHANNEL:
			state_ = C_STATE_PLAY;
			break;
		case C_STATE_LOGIN:

			state_ = C_STATE_PLAY;

			if(!ClientObjectBase::login())
			{
				WARNING_MSG("ClientApp::handleGameTick: login is failed!\n");
				return;
			}

			break;
		case C_STATE_LOGIN_GATEWAY_CHANNEL:
			{
				state_ = C_STATE_PLAY;

				bool exist = false;

				if(pServerChannel_->endpoint())
				{
					lastAddr = pServerChannel_->endpoint()->addr();
					getNetworkInterface().dispatcher().deregisterFileDescriptor(*pServerChannel_->endpoint());
					exist = getNetworkInterface().findChannel(pServerChannel_->endpoint()->addr()) != NULL;
				}

				bool ret = initBaseappChannel() != NULL;
				if(ret)
				{
					if(!exist)
					{
						getNetworkInterface().registerChannel(pServerChannel_);
						pTCPPacketReceiver_ = new Mercury::TCPPacketReceiver(*pServerChannel_->endpoint(), getNetworkInterface());
					}
					else
					{
						pTCPPacketReceiver_->endpoint(pServerChannel_->endpoint());
					}

					getNetworkInterface().dispatcher().registerFileDescriptor(*pServerChannel_->endpoint(), pTCPPacketReceiver_);
					
					// 先握手然后等helloCB之后再进行登录
					Mercury::Bundle* pBundle = Mercury::Bundle::ObjPool().createObject();
					(*pBundle).newMessage(BaseappInterface::hello);
					(*pBundle) << KBEVersion::versionString();
					
					if(Mercury::g_channelExternalEncryptType == 1)
					{
						pBlowfishFilter_ = new Mercury::BlowfishFilter();
						(*pBundle).appendBlob(pBlowfishFilter_->key());
						pServerChannel_->pFilter(NULL);
					}
					else
					{
						std::string key = "";
						(*pBundle).appendBlob(key);
					}

					pServerChannel_->pushBundle(pBundle);
					// ret = ClientObjectBase::loginGateWay();
				}
			}
			break;
		case C_STATE_LOGIN_GATEWAY:

			state_ = C_STATE_PLAY;

			if(!ClientObjectBase::loginGateWay())
			{
				WARNING_MSG("ClientApp::handleGameTick: loginGateWay is failed!\n");
				return;
			}

			break;
		case C_STATE_PLAY:
			break;
		default:
			KBE_ASSERT(false);
			break;
	};
}
Beispiel #5
0
void Client::tick(NetworkEvent* event)
{
	event->eventCode = eNone;

	if (clientSock_ == INVALID_SOCKET)
	{
		// create socket
		clientSock_ = socket(PF_INET, SOCK_STREAM, 0);
		if (clientSock_ == INVALID_SOCKET)
		{
			cleanup();
			event->eventCode = eCreateSocketError;
			return;
		}

		setNonBlocking(clientSock_, true);

		connecting_ = true;
	}
		

	if (connecting_ == true)
	{
		// connect
		sockaddr_in ai_addr;
		ai_addr.sin_family = AF_INET;
		ai_addr.sin_addr.s_addr = inet_addr(ip_.c_str());
		ai_addr.sin_port = htons(port_);

		int c = connect(clientSock_, (struct sockaddr*)&ai_addr, sizeof(ai_addr));

		if (c == 0 || getError() == EISCONN2)
		{
			connecting_ = false;
			event->eventCode = eOtherSideConnected;
			return;
		}
		else
		{
			if (getError() == EWOULDBLOCK2 || getError() == EALREADY2 || getError() == EINPROGRESS2 || getError() == EINVAL2)
			{
				// still trying to connect
				return;
			}
			else
			{
				cleanup();
				event->eventCode = eConnectError;
				return;
			}
		}
	}

	// send and recv
	if (clientSock_ != INVALID_SOCKET)
	{
		tickRecv(event);
		if (eFirstError < event->eventCode && event->eventCode < eLastError)
		{
			cleanup();
			return;
		}

		if (event->eventCode != eNone)
			return;

		tickSend(event);
		if (eFirstError < event->eventCode && event->eventCode < eLastError)
		{
			cleanup();
			return;
		}
	}
}
Beispiel #6
0
void Server::tick(NetworkEvent* event)
{
	event->eventCode = eNone;

	// try to initialize	
	if (serverSock_ == INVALID_SOCKET && clientSock_ == INVALID_SOCKET)
	{
		serverSock_ = socket(PF_INET, SOCK_STREAM, 0);
		if (serverSock_ == INVALID_SOCKET)
		{
			cleanup();
			event->eventCode = eCreateSocketError;
			return;
		}

		int yes = 1;
		if (setsockopt(serverSock_, SOL_SOCKET, SO_REUSEADDR, (const char*)&yes, sizeof(int)) == -1)
		{
			cleanup();
			event->eventCode = eSetReuseAddrError;
			return;
		}

		sockaddr_in ai_addr;
		memset(&ai_addr, 0, sizeof(ai_addr));
		ai_addr.sin_family = AF_INET;
		ai_addr.sin_addr.s_addr = htonl(INADDR_ANY);
		ai_addr.sin_port = htons(port_);
		if (bind(serverSock_, (sockaddr *)&ai_addr, sizeof(ai_addr)) == -1)
		{
			cleanup();
			event->eventCode = eBindError;
			return;
		}

		if (listen(serverSock_, BACKLOG) == -1)
		{
			cleanup();
			event->eventCode = eListenError;
			return;
		}

		setNonBlocking(serverSock_, true);
	}

	// try to accept
	if (serverSock_ != INVALID_SOCKET && clientSock_ == INVALID_SOCKET)
	{
		sockaddr_in client_addr;
		socklen_t sizeof_client_addr = sizeof(client_addr);
		clientSock_ = accept(serverSock_, (sockaddr *)&client_addr, &sizeof_client_addr);
		if (clientSock_ == INVALID_SOCKET)
		{
			if (getError() == EWOULDBLOCK2)
			{
				// no connections are present to be accepted, everything is ok, just return
				return;
			}
			else
			{
				// there is another error
				cleanup();
				event->eventCode = eAcceptError;
				return;
			}
		}

		setNonBlocking(clientSock_, true);

		// we close the listening serverSock_ in order to prevent more incoming connections on the same port
		setNonBlocking(serverSock_, false);
		closesocket(serverSock_);
		serverSock_ = INVALID_SOCKET;

		event->eventCode = eOtherSideConnected;
		return;
	}

	// send and recv
	if (clientSock_ != INVALID_SOCKET)
	{
		tickRecv(event);
		if (eFirstError < event->eventCode && event->eventCode < eLastError)
		{
			cleanup();
			return;
		}

		if (event->eventCode != eNone)
			return;

		tickSend(event);
		if (eFirstError < event->eventCode && event->eventCode < eLastError)
		{
			cleanup();
			return;
		}
	}
}