Files @ r28025:9116d6e411b0
Branch filter:

Location: cpp/openttd-patchpack/source/src/network/network_udp.cpp - annotation

Rubidium
Codechange: replace x.size() == 0 with x.empty()
r12768:980ae0491352
r12768:980ae0491352
r12768:980ae0491352
r12768:980ae0491352
r12768:980ae0491352
r12768:980ae0491352
r12768:980ae0491352
r6121:a8ff6abe7fb2
r6121:a8ff6abe7fb2
r6121:a8ff6abe7fb2
r25802:5a9afa6d773f
r6121:a8ff6abe7fb2
r6121:a8ff6abe7fb2
r6121:a8ff6abe7fb2
r5584:545d748cc681
r27229:662da0bb155f
r8139:4fc34c1bc2fb
r14248:a9050881acd7
r27853:21baf162bd57
r5584:545d748cc681
r10828:d8d68d002525
r5584:545d748cc681
r14248:a9050881acd7
r8132:f5cfeb0d46c0
r10208:ef8fcc3dc4ca
r9451:01b0b6cc547f
r15579:ec523aee641f
r16664:0a9a4431500f
r16664:0a9a4431500f
r5584:545d748cc681
r5584:545d748cc681
r5584:545d748cc681
r21383:942c32fb8b0e
r21383:942c32fb8b0e
r25169:d36f2d41209f
r27737:728d55b97775
r25169:d36f2d41209f
r25170:5ff0708cecdc
r25170:5ff0708cecdc
r25170:5ff0708cecdc
r25170:5ff0708cecdc
r25170:5ff0708cecdc
r25803:2bb6ece6b23e
r25170:5ff0708cecdc
r25458:3aaccd46b7fa
r25170:5ff0708cecdc
r25803:2bb6ece6b23e
r25803:2bb6ece6b23e
r25803:2bb6ece6b23e
r25170:5ff0708cecdc
r25170:5ff0708cecdc
r25170:5ff0708cecdc
r25170:5ff0708cecdc
r25803:2bb6ece6b23e
r25170:5ff0708cecdc
r25170:5ff0708cecdc
r25170:5ff0708cecdc
r25170:5ff0708cecdc
r25170:5ff0708cecdc
r25170:5ff0708cecdc
r5619:40c6c3e3d5f7
r5584:545d748cc681
r17641:a80e43fd2f5e
r5619:40c6c3e3d5f7
r5619:40c6c3e3d5f7
r23506:bba4d0c6d70d
r5619:40c6c3e3d5f7
r17641:a80e43fd2f5e
r17641:a80e43fd2f5e
r17641:a80e43fd2f5e
r17641:a80e43fd2f5e
r11593:8dd431018ab1
r27372:06d384d76bd2
r5619:40c6c3e3d5f7
r5619:40c6c3e3d5f7
r27942:f7389062d120
r5584:545d748cc681
r5898:2191f99d1ffb
r5898:2191f99d1ffb
r5584:545d748cc681
r25655:1030dcb7eb52
r5584:545d748cc681
r5584:545d748cc681
r5619:40c6c3e3d5f7
r5619:40c6c3e3d5f7
r17641:a80e43fd2f5e
r5619:40c6c3e3d5f7
r5619:40c6c3e3d5f7
r23506:bba4d0c6d70d
r5619:40c6c3e3d5f7
r27372:06d384d76bd2
r5619:40c6c3e3d5f7
r5619:40c6c3e3d5f7
r27942:f7389062d120
r5619:40c6c3e3d5f7
r25655:1030dcb7eb52
r5619:40c6c3e3d5f7
r25803:2bb6ece6b23e
r5584:545d748cc681
r5584:545d748cc681
r17641:a80e43fd2f5e
r5619:40c6c3e3d5f7
r5584:545d748cc681
r23536:ce42deb0b32d
r25655:1030dcb7eb52
r5584:545d748cc681
r25803:2bb6ece6b23e
r23536:ce42deb0b32d
r5584:545d748cc681
r5584:545d748cc681
r5584:545d748cc681
r17641:a80e43fd2f5e
r6247:96e840dbefcc
r5584:545d748cc681
r11363:6906c490a00e
r5584:545d748cc681
r5584:545d748cc681
r25655:1030dcb7eb52
r5584:545d748cc681
r25170:5ff0708cecdc
r5584:545d748cc681
r5584:545d748cc681
r5584:545d748cc681
r17641:a80e43fd2f5e
r6247:96e840dbefcc
r5584:545d748cc681
r11608:fbeed55c850b
r25170:5ff0708cecdc
r11608:fbeed55c850b
r25655:1030dcb7eb52
r25802:5a9afa6d773f
r10476:e0a6350eb358
r25170:5ff0708cecdc
r11629:97018c71b598
r11593:8dd431018ab1
r11629:97018c71b598
r25170:5ff0708cecdc
r11606:d8d6a74590cd
r5584:545d748cc681
r5584:545d748cc681
r25169:d36f2d41209f
r25169:d36f2d41209f
r25169:d36f2d41209f
r25169:d36f2d41209f
r25169:d36f2d41209f
r25170:5ff0708cecdc
r5584:545d748cc681
r5584:545d748cc681
r17641:a80e43fd2f5e
r11606:d8d6a74590cd
r5619:40c6c3e3d5f7
r25458:3aaccd46b7fa
r25458:3aaccd46b7fa
r11606:d8d6a74590cd
r11606:d8d6a74590cd
r11606:d8d6a74590cd
r25655:1030dcb7eb52
r5619:40c6c3e3d5f7
r5619:40c6c3e3d5f7
r18892:ba984148392c
r18892:ba984148392c
r18892:ba984148392c
r18892:ba984148392c
r25170:5ff0708cecdc
r18892:ba984148392c
r25170:5ff0708cecdc
r18892:ba984148392c
r18892:ba984148392c
r18892:ba984148392c
/*
 * This file is part of OpenTTD.
 * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
 * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
 */

/**
 * @file network_udp.cpp This file handles the UDP related communication.
 *
 * This is the GameServer <-> GameClient
 * communication before the game is being joined.
 */

#include "../stdafx.h"
#include "../timer/timer_game_calendar.h"
#include "../map_func.h"
#include "../debug.h"
#include "core/network_game_info.h"
#include "network_gamelist.h"
#include "network_internal.h"
#include "network_udp.h"
#include "network.h"
#include "../core/endian_func.hpp"
#include "../company_base.h"
#include "../rev.h"
#include "../newgrf_text.h"
#include "../strings_func.h"
#include "table/strings.h"

#include "core/udp.h"

#include "../safeguards.h"

static bool _network_udp_server;         ///< Is the UDP server started?
static uint16_t _network_udp_broadcast;    ///< Timeout for the UDP broadcasts.

/** Some information about a socket, which exists before the actual socket has been created to provide locking and the likes. */
struct UDPSocket {
	const std::string name;                     ///< The name of the socket.
	NetworkUDPSocketHandler *socket;            ///< The actual socket, which may be nullptr when not initialized yet.

	UDPSocket(const std::string &name) : name(name), socket(nullptr) {}

	void CloseSocket()
	{
		this->socket->CloseSocket();
		delete this->socket;
		this->socket = nullptr;
	}

	void ReceivePackets()
	{
		this->socket->ReceivePackets();
	}
};

static UDPSocket _udp_client("Client"); ///< udp client socket
static UDPSocket _udp_server("Server"); ///< udp server socket

///*** Communication with clients (we are server) ***/

/** Helper class for handling all server side communication. */
class ServerNetworkUDPSocketHandler : public NetworkUDPSocketHandler {
protected:
	void Receive_CLIENT_FIND_SERVER(Packet *p, NetworkAddress *client_addr) override;
public:
	/**
	 * Create the socket.
	 * @param addresses The addresses to bind on.
	 */
	ServerNetworkUDPSocketHandler(NetworkAddressList *addresses) : NetworkUDPSocketHandler(addresses) {}
	virtual ~ServerNetworkUDPSocketHandler() = default;
};

void ServerNetworkUDPSocketHandler::Receive_CLIENT_FIND_SERVER(Packet *, NetworkAddress *client_addr)
{
	Packet packet(PACKET_UDP_SERVER_RESPONSE);
	this->SendPacket(&packet, client_addr);

	Debug(net, 7, "Queried from {}", client_addr->GetHostname());
}

///*** Communication with servers (we are client) ***/

/** Helper class for handling all client side communication. */
class ClientNetworkUDPSocketHandler : public NetworkUDPSocketHandler {
protected:
	void Receive_SERVER_RESPONSE(Packet *p, NetworkAddress *client_addr) override;
public:
	virtual ~ClientNetworkUDPSocketHandler() = default;
};

void ClientNetworkUDPSocketHandler::Receive_SERVER_RESPONSE(Packet *, NetworkAddress *client_addr)
{
	Debug(net, 3, "Server response from {}", client_addr->GetAddressAsString());

	NetworkAddServer(client_addr->GetAddressAsString(false), false, true);
}

/** Broadcast to all ips */
static void NetworkUDPBroadCast(NetworkUDPSocketHandler *socket)
{
	for (NetworkAddress &addr : _broadcast_list) {
		Debug(net, 5, "Broadcasting to {}", addr.GetHostname());

		Packet p(PACKET_UDP_CLIENT_FIND_SERVER);
		socket->SendPacket(&p, &addr, true, true);
	}
}

/** Find all servers */
void NetworkUDPSearchGame()
{
	/* We are still searching.. */
	if (_network_udp_broadcast > 0) return;

	Debug(net, 3, "Searching server");

	NetworkUDPBroadCast(_udp_client.socket);
	_network_udp_broadcast = 300; // Stay searching for 300 ticks
}

/** Initialize the whole UDP bit. */
void NetworkUDPInitialize()
{
	/* If not closed, then do it. */
	if (_udp_server.socket != nullptr) NetworkUDPClose();

	Debug(net, 3, "Initializing UDP listeners");
	assert(_udp_client.socket == nullptr && _udp_server.socket == nullptr);

	_udp_client.socket = new ClientNetworkUDPSocketHandler();

	NetworkAddressList server;
	GetBindAddresses(&server, _settings_client.network.server_port);
	_udp_server.socket = new ServerNetworkUDPSocketHandler(&server);

	_network_udp_server = false;
	_network_udp_broadcast = 0;
}

/** Start the listening of the UDP server component. */
void NetworkUDPServerListen()
{
	_network_udp_server = _udp_server.socket->Listen();
}

/** Close all UDP related stuff. */
void NetworkUDPClose()
{
	_udp_client.CloseSocket();
	_udp_server.CloseSocket();

	_network_udp_server = false;
	_network_udp_broadcast = 0;
	Debug(net, 5, "Closed UDP listeners");
}

/** Receive the UDP packets. */
void NetworkBackgroundUDPLoop()
{
	if (_network_udp_server) {
		_udp_server.ReceivePackets();
	} else {
		_udp_client.ReceivePackets();
		if (_network_udp_broadcast > 0) _network_udp_broadcast--;
	}
}