Пример #1
0
void QSocketSession::findByteOrder()
{
	float i = 3.1415;
	if (theIsMaster)
	{	sendChunk((uchar *)&i, 4);
		if (!waitForAck(1000, &theSameByteOrder) || !isOpen())
		{	qWarning("*** ERROR: Handshake failed: Didn't receive ack. Closing link.");
			close();
			return;
		}
	}
	else
	{	float remotei;
		if (!receiveChunk((uchar *)&remotei, 4, 1000) || !isOpen())
		{	qWarning("*** ERROR: Handshake failed: Didn't receive remote bit pattern. Closing link.");
			close();
			return;
		}
		float rremotei;
		uint &t = *((uint *)&rremotei);
		t = bswap_32(*((uint *)&remotei));

		if (remotei == i)
			theSameByteOrder = true;
		else if (rremotei == i)
			theSameByteOrder = false;
		else
			qWarning("*** CRITICAL: Two hosts have neither same nor opposite byte order. (%f or %f should be %f)", remotei, rremotei, i);
		ack(theSameByteOrder);
	}
}
Пример #2
0
QByteArray QSocketSession::receiveString()
{
	int l = safeReceiveWord<uint32_t>();
	QByteArray s(l, ' ');
	receiveChunk((uchar *)s.data(), l);
	return s;
}
Пример #3
0
void QSocketSession::handshake()
{
	if (MESSAGES) qDebug("Handshaking... (isOpen()=%d)", isOpen());
	ack();
	if (!waitForAck(1000) || !isOpen())
	{	qWarning("*** ERROR: Handshake failed: Didn't receive ack. Closing link.");
		close();
		return;
	}
	if (MESSAGES) qDebug("Got ack!");
	for (bool know = false; !know;)
	{	uchar mi = rand() & 255;
		sendByte(mi);
		uchar i;
		if (!receiveChunk((uchar *)&i, 1, 1000) || !isOpen())
		{	qWarning("*** ERROR: Handshake failed: Didn't receive random. Closing link.");
			close();
			return;
		}
		if (mi != i)
		{	theIsMaster = mi > i;
			know = true;
		}
		else
		{	if (MESSAGES) qDebug("Doh! Number clash (%d = %d)", mi, i);
		}
	}
	findByteOrder();
}
Пример #4
0
void QSocketSession::safeReceiveWordArray(int32_t *t, uint32_t size)
{
	receiveChunk((uchar *)t, 4 * size);
	if (!theSameByteOrder)
		for (uint32_t i = 0; i < size; i++)
			t[i] = bswap_32(t[i]);
}
Пример #5
0
uint32_t QSocketSession::safeReceiveWord()
{
	union { int32_t i; uint32_t t; uchar c[4]; } d;
	receiveChunk(d.c, 4);
	if (!theSameByteOrder) d.i = bswap_32(d.i);
	return d.t;
}
Пример #6
0
void QSocketSession::safeReceiveWordArray(float *t, uint32_t size)
{
	int32_t *array = (int32_t *)t;
	receiveChunk((uchar *)array, 4 * size);
	if (!theSameByteOrder)
		for (uint32_t i = 0; i < size; i++)
			array[i] = bswap_32(array[i]);
}
Пример #7
0
void Client::processMessage(ENetEvent& event)
{
    std::string packetContents = std::string(reinterpret_cast<char*>(event.packet->data), event.packet->dataLength);

    uint32_t packetType = Packet::deserializePacketType(packetContents);

    switch (packetType) {
    case Packet::FromServerPacketContents::ChatMessageFromServerPacket:
        receiveChatMessage(packetContents);
        break;

    case Packet::FromServerPacketContents::InitialPlayerDataFromServerPacket:
        receiveInitialPlayerData(packetContents);
        break;

    case Packet::FromServerPacketContents::PlayerDisconnectedFromServerPacket:
        receivePlayerDisconnected(packetContents);
        break;

    case Packet::FromServerPacketContents::PlayerMoveFromServerPacket:
        receivePlayerMove(packetContents);
        break;

    case Packet::FromServerPacketContents::InitialPlayerDataFinishedFromServerPacket:
        m_initialPlayersReceivedFinished = true;
        break;

    case Packet::FromServerPacketContents::ChunkFromServerPacket:
        receiveChunk(packetContents);
        break;

    case Packet::QuickBarInventoryItemFromServerPacket:
        receiveQuickBarInventoryItem(packetContents);
        break;

    case Packet::QuickBarInventoryItemCountChangedFromServerPacket:
        receiveQuickBarInventoryItemCountChanged(packetContents);
        break;

    case Packet::ItemSpawnedFromServerPacket:
        receiveItemSpawned(packetContents);
        break;

    case Packet::WorldTimeChangedFromServerPacket:
        receiveWorldTimeChanged(packetContents);
        break;

    case Packet::InitialVegetationSpawningFromServerPacket:
        receiveInitialVegetationSpawning(packetContents);
        break;

    default:
        Debug::assertf(false, "Client failure, unhandled packet type received from server, it needs implemented apparently.");
    }

    enet_packet_destroy(event.packet);
}
Пример #8
0
bool QSocketSession::waitForAck(bool *ackType)
{
	uchar c = 0;
	while (isOpen() && c != 1 && c != 2)
		receiveChunk(&c, 1);

	if (c != 1 && c != 2) return false;
	if (ackType) *ackType = c;
	return true;
}
Пример #9
0
	void NodeVersionLoader::receiveData(std::uint64_t size)
	{
		auto self = shared_from_this();
		checkThread();
		
		state = State::ReceivingData;
		remainingBytes = size;
		lastReceiveTime = boost::posix_time::second_clock::local_time();
		
		setWatchDogTimer();
		receiveChunk();
	}
Пример #10
0
bool QSocketSession::waitForAck(uint timeOut, bool *ackType)
{
	uchar c = 0;
	while (isOpen() && c != 1 && c != 2)
		if (!receiveChunk(&c, 1, timeOut))
		{	if (MESSAGES) qWarning("*** INFO: Connection error - Timeout while waiting for Ack.");
			return false;
		}

	if (c != 1 && c != 2) return false;
	if (ackType) *ackType = c;
	return true;
}
Пример #11
0
	void NodeVersionLoader::receiveChunk()
	{
		auto self = shared_from_this();
		checkThread();
		
		auto& item = currentDownloadItem();
		auto chunkSize = static_cast<std::size_t>
		(std::min<std::uint64_t>(readBuffer.size(), static_cast<std::uint64_t>(remainingBytes)));
		
		if (chunkSize == 0) {
			// Done!
			BOOST_LOG_SEV(log, LogLevel::Info) <<
			"Download completed.";
			
			auto ver = item.version;
			{
				std::lock_guard<std::mutex> lock(downloadQueueMutex);
				downloadQueue.pop_front();
				// note: `item` is a dangling reference now
			}
			
			file.reset();
			timer.cancel();
			
			onVersionDownloaded(ver);
			
			log.setChannel(std::string("(none)"));
			
			state = State::Waiting;
			timer.expires_from_now(boost::posix_time::seconds(1));
			timer.async_wait([this, self] (const error_code& error) {
				if (error) {
					return;
				}
				if (disposed) {
					BOOST_LOG_SEV(log, LogLevel::Debug) <<
					"Retry timer aborted.: Disposed.";
					return;
				}
				state = State::Idle;
				checkQueue();
			});
			return;
		}
		
		
		asio::async_read(socket, asio::buffer(readBuffer.data(), chunkSize), [this, self, &item, chunkSize](const error_code& error, std::size_t) {
			checkThread();
			
			if (disposed) {
				downloadCancelled();
				return;
			}
			if (error) {
				downloadFailed(error.message());
				return;
			}
			
			lastReceiveTime = boost::posix_time::second_clock::local_time();
			
			try {
				file->write(readBuffer.data(), chunkSize);
			} catch (...) {
				downloadFailed("Failed to write to the downloaded file.: " +
							   boost::current_exception_diagnostic_information());
				return;
			}
			remainingBytes -= static_cast<std::uint64_t>(chunkSize);
			
			receiveChunk();
		});
		
		
	}