Exemplo n.º 1
0
	Uint32 PacketSocket::write(Uint32 max, bt::TimeStamp now)
	{
		if (sock->state() == net::SocketDevice::CONNECTING && !sock->connectSuccesFull())
			return 0;
		
		if (!curr_packet)
			curr_packet = selectPacket();
		
		Uint32 written = 0;
		while (curr_packet && (written < max || max == 0))
		{
			Uint32 limit = (max == 0) ? 0 : max - written;
			int ret = curr_packet->send(sock, limit);
			if (ret > 0)
			{
				written += ret;
				QMutexLocker locker(&mutex);
				if (curr_packet->getType() == PIECE)
				{
					up_speed->onData(ret, now);
					uploaded_data_bytes += ret;
				}
			}
			else
				break; // Socket buffer full, so stop sending for now
			
			if (curr_packet->isSent())
			{
				// packet sent, so remove it
				if (curr_packet->getType() == PIECE)
				{
					QMutexLocker locker(&mutex);
					if (!data_packets.empty())
						data_packets.pop_front();
					// reset ctrl_packets_sent so the next packet should be a ctrl packet
					ctrl_packets_sent = 0;  
				}
				else
				{
					QMutexLocker locker(&mutex);
					if (!control_packets.empty())
						control_packets.pop_front();
					ctrl_packets_sent++;
				}
				curr_packet = selectPacket();
			}
			else
			{
				// we can't write it fully, so break out of loop
				break;
			}
		}
		
		return written;
	}
Exemplo n.º 2
0
void PlayPG::render(float deltaTime) {
	glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
	glClear(GL_COLOR_BUFFER_BIT);

	switch (gameState) {
	case GameState::LOGIN: {
		if (inputManager->isKeyJustPressed(SDL_SCANCODE_SPACE)) {
			if (doLogin()) {
				gameState = GameState::CHARACTER_SELECT;
			}
		} else if (inputManager->isKeyJustPressed(SDL_SCANCODE_1)) {
			username = "******";
		}
		break;
	}

	case GameState::CHARACTER_SELECT: {
		if (inputManager->isKeyJustPressed(SDL_SCANCODE_RETURN)) {
			socket.clear();
			socket.putShort(util::to_integral(ClientOpcode::REQUEST_CHARACTERS));
			socket.send();

			socket.waitForActivity();
			const auto charBytes = socket.recv();

			if (charBytes == 0) {
				logger->error("Couldn't get characters from LoginServer");
				break;
			}

			const auto charOpcode = socket.getShort();

			if (charOpcode != util::to_integral(ServerOpcode::PLAYER_CHARACTERS)) {
				logger->error("Got invalid response from server.");
				break;
			}

			const auto jsonLength = socket.getShort();
			const auto json = socket.getStringByLength(jsonLength);

			logger->info("Got %v.", json);

			APG::JSONSerializer<PlayerCharacters> charS11N;
			const auto charList = charS11N.fromJSON(json.c_str());

			if (charList.characters.size() == 0) {
				logger->fatal("Server has no characters for this account. Exiting.");
				break;
			}

			currentCharacter = std::make_unique<Character>(charList.characters[0]);

			CharacterSelect selectPacket(*currentCharacter);
			socket.clear();
			socket.put(&selectPacket.buffer);
			socket.send();

			gameState = GameState::MAP_SERVER_CONNECT;
		}

		break;
	}

	case GameState::MAP_SERVER_CONNECT: {
		socket.clear();
		socket.waitForActivity();

		const auto bytesRec = socket.recv();

		if(bytesRec == 0) {
			break;
		}

		const auto opcode = socket.getShort();
		switch (opcode) {
		case util::to_integral(ServerOpcode::NO_MAP_SERVER_ERROR): {
			const auto messageLength = socket.getShort();
			const auto message = socket.getStringByLength(messageLength);
			logger->error("Couldn't find an appropriate map server for that character. Error: %v", message);
			gameState = GameState::CHARACTER_SELECT;
			break;
		}

		case util::to_integral(ServerOpcode::MAP_SERVER_CONNECTION_INSTRUCTIONS): {
			// success; read the JSON provided

			const auto jsonLength = socket.getShort();
			const auto jsonString = socket.getStringByLength(jsonLength);

			APG::JSONSerializer<MapServerConnectionInstructions> msciJSON;

			const MapServerConnectionInstructions msci = msciJSON.fromJSON(jsonString.c_str());

			logger->info("Got map server details: %v:%v", msci.hostName, msci.port);
			gameState = GameState::PLAYING;

			break;
		}

		default: {
			logger->error("Invalid response from server for that character.");
			gameState = GameState::CHARACTER_SELECT;
			break;
		}
		}

		socket.clear();

		break;
	}

	case GameState::PLAYING: {
		if (inputManager->isKeyJustPressed(SDL_SCANCODE_RETURN)) {
			if (indoor) {
				indoor = false;
				changeToWorld(mapOutdoor);
			} else {
				indoor = true;
				changeToWorld(mapIndoor);
			}
		}

		outdoorRenderer->update(deltaTime);

		engine->update(deltaTime);
		break;
	}
	}

	SDL_GL_SwapWindow(window.get());
}