Merge branch 'master' into jgrpp
# Conflicts: # src/network/network_server.cpp
This commit is contained in:
		@@ -118,21 +118,20 @@ struct PacketWriter : SaveFilter {
 | 
			
		||||
	/**
 | 
			
		||||
	 * Transfer all packets from here to the network's queue while holding
 | 
			
		||||
	 * the lock on our mutex.
 | 
			
		||||
	 * @param socket The network socket to write to.
 | 
			
		||||
	 * @return True iff the last packet of the map has been sent.
 | 
			
		||||
	 */
 | 
			
		||||
	bool TransferToNetworkQueue(ServerNetworkGameSocketHandler *socket)
 | 
			
		||||
	bool TransferToNetworkQueue()
 | 
			
		||||
	{
 | 
			
		||||
		std::lock_guard<std::mutex> lock(this->mutex);
 | 
			
		||||
 | 
			
		||||
		if (this->map_size_packet) {
 | 
			
		||||
			/* Don't queue the PACKET_SERVER_MAP_SIZE before the corresponding PACKET_SERVER_MAP_BEGIN */
 | 
			
		||||
			socket->SendPrependPacket(std::move(this->map_size_packet), PACKET_SERVER_MAP_BEGIN);
 | 
			
		||||
			this->cs->SendPrependPacket(std::move(this->map_size_packet), PACKET_SERVER_MAP_BEGIN);
 | 
			
		||||
		}
 | 
			
		||||
		bool last_packet = false;
 | 
			
		||||
		for (auto &p : this->packets) {
 | 
			
		||||
			if (p->GetPacketType() == PACKET_SERVER_MAP_DONE) last_packet = true;
 | 
			
		||||
			socket->SendPacket(std::move(p));
 | 
			
		||||
			this->cs->SendPacket(std::move(p));
 | 
			
		||||
 | 
			
		||||
		}
 | 
			
		||||
		this->packets.clear();
 | 
			
		||||
@@ -142,13 +141,13 @@ struct PacketWriter : SaveFilter {
 | 
			
		||||
 | 
			
		||||
	void Write(byte *buf, size_t size) override
 | 
			
		||||
	{
 | 
			
		||||
		std::lock_guard<std::mutex> lock(this->mutex);
 | 
			
		||||
 | 
			
		||||
		/* We want to abort the saving when the socket is closed. */
 | 
			
		||||
		if (this->cs == nullptr) SlError(STR_NETWORK_ERROR_LOSTCONNECTION);
 | 
			
		||||
 | 
			
		||||
		if (this->current == nullptr) this->current = std::make_unique<Packet>(PACKET_SERVER_MAP_DATA, TCP_MTU);
 | 
			
		||||
 | 
			
		||||
		std::lock_guard<std::mutex> lock(this->mutex);
 | 
			
		||||
 | 
			
		||||
		byte *bufe = buf + size;
 | 
			
		||||
		while (buf != bufe) {
 | 
			
		||||
			size_t written = this->current->Send_binary_until_full(buf, bufe);
 | 
			
		||||
@@ -165,11 +164,11 @@ struct PacketWriter : SaveFilter {
 | 
			
		||||
 | 
			
		||||
	void Finish() override
 | 
			
		||||
	{
 | 
			
		||||
		std::lock_guard<std::mutex> lock(this->mutex);
 | 
			
		||||
 | 
			
		||||
		/* We want to abort the saving when the socket is closed. */
 | 
			
		||||
		if (this->cs == nullptr) SlError(STR_NETWORK_ERROR_LOSTCONNECTION);
 | 
			
		||||
 | 
			
		||||
		std::lock_guard<std::mutex> lock(this->mutex);
 | 
			
		||||
 | 
			
		||||
		/* Make sure the last packet is flushed. */
 | 
			
		||||
		if (this->current != nullptr) this->packets.push_back(std::move(this->current));
 | 
			
		||||
 | 
			
		||||
@@ -489,6 +488,17 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::SendDesyncLog(const std::strin
 | 
			
		||||
NetworkRecvStatus ServerNetworkGameSocketHandler::SendNewGRFCheck()
 | 
			
		||||
{
 | 
			
		||||
	auto p = std::make_unique<Packet>(PACKET_SERVER_CHECK_NEWGRFS, TCP_MTU);
 | 
			
		||||
 | 
			
		||||
	/* Invalid packet when status is anything but STATUS_INACTIVE. */
 | 
			
		||||
	if (this->status != STATUS_INACTIVE) return this->CloseConnection(NETWORK_RECV_STATUS_MALFORMED_PACKET);
 | 
			
		||||
 | 
			
		||||
	this->status = STATUS_NEWGRFS_CHECK;
 | 
			
		||||
 | 
			
		||||
	if (_grfconfig == nullptr) {
 | 
			
		||||
		/* There are no NewGRFs, continue with the game password. */
 | 
			
		||||
		return this->SendNeedGamePassword();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	const GRFConfig *c;
 | 
			
		||||
	uint grf_count = 0;
 | 
			
		||||
 | 
			
		||||
@@ -508,15 +518,16 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::SendNewGRFCheck()
 | 
			
		||||
/** Request the game password. */
 | 
			
		||||
NetworkRecvStatus ServerNetworkGameSocketHandler::SendNeedGamePassword()
 | 
			
		||||
{
 | 
			
		||||
	/* Invalid packet when status is anything but STATUS_NEWGRFS_CHECK. */
 | 
			
		||||
	if (this->status != STATUS_NEWGRFS_CHECK) return this->CloseConnection(NETWORK_RECV_STATUS_MALFORMED_PACKET);
 | 
			
		||||
 | 
			
		||||
	this->status = STATUS_AUTH_GAME;
 | 
			
		||||
 | 
			
		||||
	if (_settings_client.network.server_password.empty()) {
 | 
			
		||||
		/* Do not actually need a game password, continue with the company password. */
 | 
			
		||||
		return this->SendNeedCompanyPassword();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* Invalid packet when status is STATUS_AUTH_GAME or higher */
 | 
			
		||||
	if (this->status >= STATUS_AUTH_GAME) return this->CloseConnection(NETWORK_RECV_STATUS_MALFORMED_PACKET);
 | 
			
		||||
 | 
			
		||||
	this->status = STATUS_AUTH_GAME;
 | 
			
		||||
	/* Reset 'lag' counters */
 | 
			
		||||
	this->last_frame = this->last_frame_server = _frame_counter;
 | 
			
		||||
 | 
			
		||||
@@ -533,15 +544,16 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::SendNeedGamePassword()
 | 
			
		||||
/** Request the company password. */
 | 
			
		||||
NetworkRecvStatus ServerNetworkGameSocketHandler::SendNeedCompanyPassword()
 | 
			
		||||
{
 | 
			
		||||
	/* Invalid packet when status is anything but STATUS_AUTH_GAME. */
 | 
			
		||||
	if (this->status != STATUS_AUTH_GAME) return this->CloseConnection(NETWORK_RECV_STATUS_MALFORMED_PACKET);
 | 
			
		||||
 | 
			
		||||
	this->status = STATUS_AUTH_COMPANY;
 | 
			
		||||
 | 
			
		||||
	NetworkClientInfo *ci = this->GetInfo();
 | 
			
		||||
	if (!Company::IsValidID(ci->client_playas) || _network_company_states[ci->client_playas].password.empty()) {
 | 
			
		||||
		return this->SendWelcome();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* Invalid packet when status is STATUS_AUTH_COMPANY or higher */
 | 
			
		||||
	if (this->status >= STATUS_AUTH_COMPANY) return this->CloseConnection(NETWORK_RECV_STATUS_MALFORMED_PACKET);
 | 
			
		||||
 | 
			
		||||
	this->status = STATUS_AUTH_COMPANY;
 | 
			
		||||
	/* Reset 'lag' counters */
 | 
			
		||||
	this->last_frame = this->last_frame_server = _frame_counter;
 | 
			
		||||
 | 
			
		||||
@@ -555,10 +567,11 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::SendNeedCompanyPassword()
 | 
			
		||||
/** Send the client a welcome message with some basic information. */
 | 
			
		||||
NetworkRecvStatus ServerNetworkGameSocketHandler::SendWelcome()
 | 
			
		||||
{
 | 
			
		||||
	/* Invalid packet when status is AUTH or higher */
 | 
			
		||||
	if (this->status >= STATUS_AUTHORIZED) return this->CloseConnection(NETWORK_RECV_STATUS_MALFORMED_PACKET);
 | 
			
		||||
	/* Invalid packet when status is anything but STATUS_AUTH_COMPANY. */
 | 
			
		||||
	if (this->status != STATUS_AUTH_COMPANY) return this->CloseConnection(NETWORK_RECV_STATUS_MALFORMED_PACKET);
 | 
			
		||||
 | 
			
		||||
	this->status = STATUS_AUTHORIZED;
 | 
			
		||||
 | 
			
		||||
	/* Reset 'lag' counters */
 | 
			
		||||
	this->last_frame = this->last_frame_server = _frame_counter;
 | 
			
		||||
 | 
			
		||||
@@ -659,7 +672,7 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::SendMap()
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (this->status == STATUS_MAP) {
 | 
			
		||||
		bool last_packet = this->savegame->TransferToNetworkQueue(this);
 | 
			
		||||
		bool last_packet = this->savegame->TransferToNetworkQueue();
 | 
			
		||||
		if (last_packet) {
 | 
			
		||||
			/* Done reading, make sure saving is done as well */
 | 
			
		||||
			this->savegame->Destroy();
 | 
			
		||||
@@ -1015,13 +1028,6 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::Receive_CLIENT_JOIN(Packet &p)
 | 
			
		||||
	/* Make sure companies to which people try to join are not autocleaned */
 | 
			
		||||
	if (Company::IsValidID(playas)) _network_company_states[playas].months_empty = 0;
 | 
			
		||||
 | 
			
		||||
	this->status = STATUS_NEWGRFS_CHECK;
 | 
			
		||||
 | 
			
		||||
	if (_grfconfig == nullptr) {
 | 
			
		||||
		/* Continue asking for the game password. */
 | 
			
		||||
		return this->SendNeedGamePassword();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return this->SendNewGRFCheck();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user