2009-08-21 22:21:05 +02:00
|
|
|
/*
|
|
|
|
* 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/>.
|
|
|
|
*/
|
|
|
|
|
2007-02-23 09:37:33 +01:00
|
|
|
/**
|
|
|
|
* @file network_udp.cpp This file handles the UDP related communication.
|
|
|
|
*
|
2021-04-29 16:11:44 +02:00
|
|
|
* This is the GameServer <-> GameClient
|
2007-02-23 09:37:33 +01:00
|
|
|
* communication before the game is being joined.
|
|
|
|
*/
|
|
|
|
|
2007-01-02 18:34:03 +01:00
|
|
|
#include "../stdafx.h"
|
2023-05-04 15:14:12 +02:00
|
|
|
#include "../timer/timer_game_calendar.h"
|
2007-12-26 12:45:43 +01:00
|
|
|
#include "../map_func.h"
|
2010-01-15 17:41:15 +01:00
|
|
|
#include "../debug.h"
|
2023-09-02 19:46:52 +02:00
|
|
|
#include "core/network_game_info.h"
|
2004-12-04 18:54:56 +01:00
|
|
|
#include "network_gamelist.h"
|
2008-05-30 20:20:26 +02:00
|
|
|
#include "network_internal.h"
|
2009-01-20 12:28:18 +01:00
|
|
|
#include "network_udp.h"
|
2010-01-15 17:41:15 +01:00
|
|
|
#include "network.h"
|
2007-12-25 14:28:09 +01:00
|
|
|
#include "../core/endian_func.hpp"
|
2008-09-30 22:51:04 +02:00
|
|
|
#include "../company_base.h"
|
2008-06-03 10:04:35 +02:00
|
|
|
#include "../rev.h"
|
2010-07-31 11:33:39 +02:00
|
|
|
#include "../newgrf_text.h"
|
2010-12-05 23:21:13 +01:00
|
|
|
#include "../strings_func.h"
|
|
|
|
#include "table/strings.h"
|
2007-01-02 18:34:03 +01:00
|
|
|
|
|
|
|
#include "core/udp.h"
|
|
|
|
|
2014-04-23 22:13:33 +02:00
|
|
|
#include "../safeguards.h"
|
|
|
|
|
2021-04-11 11:22:50 +02:00
|
|
|
static bool _network_udp_server; ///< Is the UDP server started?
|
2023-05-08 19:01:06 +02:00
|
|
|
static uint16_t _network_udp_broadcast; ///< Timeout for the UDP broadcasts.
|
2021-04-11 11:22:50 +02:00
|
|
|
|
2021-04-11 11:30:44 +02:00
|
|
|
/** 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.
|
|
|
|
|
2021-04-29 17:52:09 +02:00
|
|
|
UDPSocket(const std::string &name) : name(name), socket(nullptr) {}
|
2021-04-11 11:30:44 +02:00
|
|
|
|
2021-05-13 11:46:51 +02:00
|
|
|
void CloseSocket()
|
2021-04-11 11:30:44 +02:00
|
|
|
{
|
2021-04-29 17:52:09 +02:00
|
|
|
this->socket->CloseSocket();
|
|
|
|
delete this->socket;
|
|
|
|
this->socket = nullptr;
|
2021-04-11 11:30:44 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void ReceivePackets()
|
|
|
|
{
|
2021-04-29 17:52:09 +02:00
|
|
|
this->socket->ReceivePackets();
|
2021-04-11 11:30:44 +02:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
static UDPSocket _udp_client("Client"); ///< udp client socket
|
|
|
|
static UDPSocket _udp_server("Server"); ///< udp server socket
|
|
|
|
|
2007-01-12 15:30:01 +01:00
|
|
|
///*** Communication with clients (we are server) ***/
|
|
|
|
|
2011-05-04 22:24:23 +02:00
|
|
|
/** Helper class for handling all server side communication. */
|
2007-01-12 15:30:01 +01:00
|
|
|
class ServerNetworkUDPSocketHandler : public NetworkUDPSocketHandler {
|
|
|
|
protected:
|
2024-02-03 19:43:38 +01:00
|
|
|
void Receive_CLIENT_FIND_SERVER(Packet &p, NetworkAddress &client_addr) override;
|
2007-01-12 15:30:01 +01:00
|
|
|
public:
|
2011-05-04 22:24:23 +02:00
|
|
|
/**
|
|
|
|
* Create the socket.
|
|
|
|
* @param addresses The addresses to bind on.
|
|
|
|
*/
|
2009-04-07 22:27:13 +02:00
|
|
|
ServerNetworkUDPSocketHandler(NetworkAddressList *addresses) : NetworkUDPSocketHandler(addresses) {}
|
2023-05-14 23:31:03 +02:00
|
|
|
virtual ~ServerNetworkUDPSocketHandler() = default;
|
2007-01-12 15:30:01 +01:00
|
|
|
};
|
|
|
|
|
2024-02-03 19:43:38 +01:00
|
|
|
void ServerNetworkUDPSocketHandler::Receive_CLIENT_FIND_SERVER(Packet &, NetworkAddress &client_addr)
|
2004-12-04 18:54:56 +01:00
|
|
|
{
|
2024-02-04 12:31:56 +01:00
|
|
|
Packet packet(this, PACKET_UDP_SERVER_RESPONSE);
|
2024-02-03 19:43:38 +01:00
|
|
|
this->SendPacket(packet, client_addr);
|
2004-12-04 18:54:56 +01:00
|
|
|
|
2024-02-03 19:43:38 +01:00
|
|
|
Debug(net, 7, "Queried from {}", client_addr.GetHostname());
|
2004-12-04 18:54:56 +01:00
|
|
|
}
|
|
|
|
|
2007-01-12 15:30:01 +01:00
|
|
|
///*** Communication with servers (we are client) ***/
|
|
|
|
|
2011-05-04 22:24:23 +02:00
|
|
|
/** Helper class for handling all client side communication. */
|
2007-01-12 15:30:01 +01:00
|
|
|
class ClientNetworkUDPSocketHandler : public NetworkUDPSocketHandler {
|
|
|
|
protected:
|
2024-02-03 19:43:38 +01:00
|
|
|
void Receive_SERVER_RESPONSE(Packet &p, NetworkAddress &client_addr) override;
|
2007-01-12 15:30:01 +01:00
|
|
|
public:
|
2023-05-14 23:31:03 +02:00
|
|
|
virtual ~ClientNetworkUDPSocketHandler() = default;
|
2007-01-12 15:30:01 +01:00
|
|
|
};
|
|
|
|
|
2024-02-03 19:43:38 +01:00
|
|
|
void ClientNetworkUDPSocketHandler::Receive_SERVER_RESPONSE(Packet &, NetworkAddress &client_addr)
|
2007-01-12 15:30:01 +01:00
|
|
|
{
|
2024-02-03 19:43:38 +01:00
|
|
|
Debug(net, 3, "Server response from {}", client_addr.GetAddressAsString());
|
2007-01-12 15:30:01 +01:00
|
|
|
|
2024-02-03 19:43:38 +01:00
|
|
|
NetworkAddServer(client_addr.GetAddressAsString(false), false, true);
|
2006-12-18 13:26:55 +01:00
|
|
|
}
|
|
|
|
|
2011-05-04 22:24:23 +02:00
|
|
|
/** Broadcast to all ips */
|
2007-01-12 15:30:01 +01:00
|
|
|
static void NetworkUDPBroadCast(NetworkUDPSocketHandler *socket)
|
2004-12-04 18:54:56 +01:00
|
|
|
{
|
2019-02-17 12:20:52 +01:00
|
|
|
for (NetworkAddress &addr : _broadcast_list) {
|
2021-06-12 09:10:17 +02:00
|
|
|
Debug(net, 5, "Broadcasting to {}", addr.GetHostname());
|
2004-12-04 18:54:56 +01:00
|
|
|
|
2024-02-04 12:31:56 +01:00
|
|
|
Packet p(socket, PACKET_UDP_CLIENT_FIND_SERVER);
|
2024-02-03 19:43:38 +01:00
|
|
|
socket->SendPacket(p, addr, true, true);
|
2004-12-04 18:54:56 +01:00
|
|
|
}
|
2004-12-22 19:42:56 +01:00
|
|
|
}
|
|
|
|
|
2011-05-04 22:24:23 +02:00
|
|
|
/** Find all servers */
|
2007-03-07 12:47:46 +01:00
|
|
|
void NetworkUDPSearchGame()
|
2004-12-04 18:54:56 +01:00
|
|
|
{
|
2009-03-15 01:32:18 +01:00
|
|
|
/* We are still searching.. */
|
2006-12-26 18:36:18 +01:00
|
|
|
if (_network_udp_broadcast > 0) return;
|
2004-12-04 18:54:56 +01:00
|
|
|
|
2021-06-12 09:10:17 +02:00
|
|
|
Debug(net, 3, "Searching server");
|
2004-12-04 18:54:56 +01:00
|
|
|
|
2021-04-11 11:30:44 +02:00
|
|
|
NetworkUDPBroadCast(_udp_client.socket);
|
2004-12-04 18:54:56 +01:00
|
|
|
_network_udp_broadcast = 300; // Stay searching for 300 ticks
|
|
|
|
}
|
|
|
|
|
2011-05-04 22:24:23 +02:00
|
|
|
/** Initialize the whole UDP bit. */
|
2007-03-07 12:47:46 +01:00
|
|
|
void NetworkUDPInitialize()
|
2004-12-04 18:54:56 +01:00
|
|
|
{
|
2009-04-08 23:03:00 +02:00
|
|
|
/* If not closed, then do it. */
|
2021-04-11 11:30:44 +02:00
|
|
|
if (_udp_server.socket != nullptr) NetworkUDPClose();
|
2009-04-08 23:03:00 +02:00
|
|
|
|
2021-06-12 09:10:17 +02:00
|
|
|
Debug(net, 3, "Initializing UDP listeners");
|
2021-04-29 16:11:44 +02:00
|
|
|
assert(_udp_client.socket == nullptr && _udp_server.socket == nullptr);
|
2008-12-23 21:58:03 +01:00
|
|
|
|
2021-04-11 11:30:44 +02:00
|
|
|
_udp_client.socket = new ClientNetworkUDPSocketHandler();
|
2009-04-10 14:56:55 +02:00
|
|
|
|
|
|
|
NetworkAddressList server;
|
|
|
|
GetBindAddresses(&server, _settings_client.network.server_port);
|
2021-04-11 11:30:44 +02:00
|
|
|
_udp_server.socket = new ServerNetworkUDPSocketHandler(&server);
|
2009-04-08 21:36:51 +02:00
|
|
|
|
2004-12-04 18:54:56 +01:00
|
|
|
_network_udp_server = false;
|
|
|
|
_network_udp_broadcast = 0;
|
2021-04-11 11:22:50 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/** Start the listening of the UDP server component. */
|
|
|
|
void NetworkUDPServerListen()
|
|
|
|
{
|
2021-04-11 11:30:44 +02:00
|
|
|
_network_udp_server = _udp_server.socket->Listen();
|
2004-12-04 18:54:56 +01:00
|
|
|
}
|
|
|
|
|
2011-05-04 22:24:23 +02:00
|
|
|
/** Close all UDP related stuff. */
|
2009-04-08 21:36:51 +02:00
|
|
|
void NetworkUDPClose()
|
2007-01-12 15:30:01 +01:00
|
|
|
{
|
2021-05-13 11:46:51 +02:00
|
|
|
_udp_client.CloseSocket();
|
|
|
|
_udp_server.CloseSocket();
|
2009-04-08 21:36:51 +02:00
|
|
|
|
|
|
|
_network_udp_server = false;
|
|
|
|
_network_udp_broadcast = 0;
|
2021-06-12 09:10:17 +02:00
|
|
|
Debug(net, 5, "Closed UDP listeners");
|
2007-01-12 15:30:01 +01:00
|
|
|
}
|
|
|
|
|
2012-01-04 23:08:43 +01:00
|
|
|
/** Receive the UDP packets. */
|
|
|
|
void NetworkBackgroundUDPLoop()
|
|
|
|
{
|
|
|
|
if (_network_udp_server) {
|
2021-04-11 11:30:44 +02:00
|
|
|
_udp_server.ReceivePackets();
|
2012-01-04 23:08:43 +01:00
|
|
|
} else {
|
2021-04-11 11:30:44 +02:00
|
|
|
_udp_client.ReceivePackets();
|
2012-01-04 23:08:43 +01:00
|
|
|
if (_network_udp_broadcast > 0) _network_udp_broadcast--;
|
|
|
|
}
|
|
|
|
}
|