mirror of https://github.com/OpenTTD/OpenTTD.git
(svn r15157) -Codechange: wrap the hostname/ip and port into a single structure so we can pass either one of them and not convert an ip to a string and then back again.
This commit is contained in:
parent
6e1af6a051
commit
5f3772a42c
|
@ -692,7 +692,7 @@ DEF_CONSOLE_CMD(ConNetworkConnect)
|
|||
IConsolePrintF(CC_DEFAULT, " port: %s", port);
|
||||
}
|
||||
|
||||
NetworkClientConnectGame(ip, rport);
|
||||
NetworkClientConnectGame(NetworkAddress(ip, rport));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -451,12 +451,12 @@ void NetworkCloseClient(NetworkClientSocket *cs)
|
|||
}
|
||||
|
||||
// A client wants to connect to a server
|
||||
static bool NetworkConnect(const char *hostname, int port)
|
||||
static bool NetworkConnect(NetworkAddress address)
|
||||
{
|
||||
SOCKET s;
|
||||
struct sockaddr_in sin;
|
||||
|
||||
DEBUG(net, 1, "Connecting to %s %d", hostname, port);
|
||||
DEBUG(net, 1, "Connecting to %s %d", address.GetHostname(), address.GetPort());
|
||||
|
||||
s = socket(AF_INET, SOCK_STREAM, 0);
|
||||
if (s == INVALID_SOCKET) {
|
||||
|
@ -467,8 +467,8 @@ static bool NetworkConnect(const char *hostname, int port)
|
|||
if (!SetNoDelay(s)) DEBUG(net, 1, "Setting TCP_NODELAY failed");
|
||||
|
||||
sin.sin_family = AF_INET;
|
||||
sin.sin_addr.s_addr = NetworkResolveHost(hostname);
|
||||
sin.sin_port = htons(port);
|
||||
sin.sin_addr.s_addr = address.GetIP();
|
||||
sin.sin_port = htons(address.GetIP());
|
||||
_network_last_host_ip = sin.sin_addr.s_addr;
|
||||
|
||||
/* We failed to connect for which reason what so ever */
|
||||
|
@ -664,7 +664,7 @@ static void NetworkInitialize()
|
|||
// Query a server to fetch his game-info
|
||||
// If game_info is true, only the gameinfo is fetched,
|
||||
// else only the client_info is fetched
|
||||
void NetworkTCPQueryServer(const char *host, unsigned short port)
|
||||
void NetworkTCPQueryServer(NetworkAddress address)
|
||||
{
|
||||
if (!_network_available) return;
|
||||
|
||||
|
@ -672,7 +672,7 @@ void NetworkTCPQueryServer(const char *host, unsigned short port)
|
|||
NetworkInitialize();
|
||||
|
||||
// Try to connect
|
||||
_networking = NetworkConnect(host, port);
|
||||
_networking = NetworkConnect(address);
|
||||
|
||||
// We are connected
|
||||
if (_networking) {
|
||||
|
@ -701,7 +701,7 @@ void NetworkAddServer(const char *b)
|
|||
ParseConnectionString(&company, &port, host);
|
||||
if (port != NULL) rport = atoi(port);
|
||||
|
||||
NetworkUDPQueryServer(host, rport, true);
|
||||
NetworkUDPQueryServer(NetworkAddress(host, rport), true);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -727,20 +727,20 @@ void NetworkRebuildHostList()
|
|||
}
|
||||
|
||||
// Used by clients, to connect to a server
|
||||
void NetworkClientConnectGame(const char *host, uint16 port)
|
||||
void NetworkClientConnectGame(NetworkAddress address)
|
||||
{
|
||||
if (!_network_available) return;
|
||||
|
||||
if (port == 0) return;
|
||||
if (address.GetPort() == 0) return;
|
||||
|
||||
strecpy(_settings_client.network.last_host, host, lastof(_settings_client.network.last_host));
|
||||
_settings_client.network.last_port = port;
|
||||
strecpy(_settings_client.network.last_host, address.GetHostname(), lastof(_settings_client.network.last_host));
|
||||
_settings_client.network.last_port = address.GetPort();
|
||||
|
||||
NetworkDisconnect();
|
||||
NetworkInitialize();
|
||||
|
||||
// Try to connect
|
||||
_networking = NetworkConnect(host, port);
|
||||
_networking = NetworkConnect(address);
|
||||
|
||||
// We are connected
|
||||
if (_networking) {
|
||||
|
@ -1073,13 +1073,13 @@ static void NetworkGenerateUniqueId()
|
|||
snprintf(_settings_client.network.network_id, sizeof(_settings_client.network.network_id), "%s", hex_output);
|
||||
}
|
||||
|
||||
void NetworkStartDebugLog(const char *hostname, uint16 port)
|
||||
void NetworkStartDebugLog(NetworkAddress address)
|
||||
{
|
||||
extern SOCKET _debug_socket; // Comes from debug.c
|
||||
SOCKET s;
|
||||
struct sockaddr_in sin;
|
||||
|
||||
DEBUG(net, 0, "Redirecting DEBUG() to %s:%d", hostname, port);
|
||||
DEBUG(net, 0, "Redirecting DEBUG() to %s:%d", address.GetHostname(), address.GetPort());
|
||||
|
||||
s = socket(AF_INET, SOCK_STREAM, 0);
|
||||
if (s == INVALID_SOCKET) {
|
||||
|
@ -1090,11 +1090,11 @@ void NetworkStartDebugLog(const char *hostname, uint16 port)
|
|||
if (!SetNoDelay(s)) DEBUG(net, 1, "Setting TCP_NODELAY failed");
|
||||
|
||||
sin.sin_family = AF_INET;
|
||||
sin.sin_addr.s_addr = NetworkResolveHost(hostname);
|
||||
sin.sin_port = htons(port);
|
||||
sin.sin_addr.s_addr = address.GetIP();
|
||||
sin.sin_port = htons(address.GetPort());
|
||||
|
||||
if (connect(s, (struct sockaddr *)&sin, sizeof(sin)) != 0) {
|
||||
DEBUG(net, 0, "Failed to redirection DEBUG() to %s:%d", hostname, port);
|
||||
DEBUG(net, 0, "Failed to redirection DEBUG() to %s:%d", address.GetHostname(), address.GetIP());
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1154,6 +1154,24 @@ bool IsNetworkCompatibleVersion(const char *other)
|
|||
return strncmp(_openttd_revision, other, NETWORK_REVISION_LENGTH - 1) == 0;
|
||||
}
|
||||
|
||||
const char *NetworkAddress::GetHostname() const
|
||||
{
|
||||
if (this->hostname != NULL) return this->hostname;
|
||||
|
||||
in_addr addr;
|
||||
addr.s_addr = this->ip;
|
||||
return inet_ntoa(addr);
|
||||
}
|
||||
|
||||
uint32 NetworkAddress::GetIP()
|
||||
{
|
||||
if (!this->resolved) {
|
||||
this->ip = NetworkResolveHost(this->hostname);
|
||||
this->resolved = true;
|
||||
}
|
||||
return this->ip;
|
||||
}
|
||||
|
||||
#endif /* ENABLE_NETWORK */
|
||||
|
||||
/* NOTE: this variable needs to be always available */
|
||||
|
|
|
@ -32,11 +32,11 @@ void NetworkGameLoop();
|
|||
void NetworkUDPGameLoop();
|
||||
void NetworkUDPCloseAll();
|
||||
void ParseConnectionString(const char **company, const char **port, char *connection_string);
|
||||
void NetworkStartDebugLog(const char *hostname, uint16 port);
|
||||
void NetworkStartDebugLog(NetworkAddress address);
|
||||
void NetworkPopulateCompanyStats(NetworkCompanyStats *stats);
|
||||
|
||||
void NetworkUpdateClientInfo(ClientID client_id);
|
||||
void NetworkClientConnectGame(const char *host, uint16 port);
|
||||
void NetworkClientConnectGame(NetworkAddress address);
|
||||
void NetworkClientSendRcon(const char *password, const char *command);
|
||||
void NetworkClientSendChat(NetworkAction action, DestType type, int dest, const char *msg, int64 data = 0);
|
||||
void NetworkClientSetPassword(const char *password);
|
||||
|
|
|
@ -96,18 +96,13 @@ void NetworkGameListRequery()
|
|||
if (++requery_cnt < REQUERY_EVERY_X_GAMELOOPS) return;
|
||||
requery_cnt = 0;
|
||||
|
||||
struct in_addr ip;
|
||||
NetworkGameList *item;
|
||||
|
||||
for (item = _network_game_list; item != NULL; item = item->next) {
|
||||
for (NetworkGameList *item = _network_game_list; item != NULL; item = item->next) {
|
||||
item->retries++;
|
||||
if (item->retries < REFRESH_GAMEINFO_X_REQUERIES && (item->online || item->retries >= MAX_GAME_LIST_REQUERY_COUNT)) continue;
|
||||
|
||||
ip.s_addr = item->ip;
|
||||
|
||||
/* item gets mostly zeroed by NetworkUDPQueryServer */
|
||||
uint8 retries = item->retries;
|
||||
NetworkUDPQueryServer(inet_ntoa(ip), item->port);
|
||||
NetworkUDPQueryServer(NetworkAddress(item->ip, item->port));
|
||||
item->retries = (retries >= REFRESH_GAMEINFO_X_REQUERIES) ? 0 : retries;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -558,7 +558,7 @@ public:
|
|||
break;
|
||||
|
||||
case NGWW_REFRESH: // Refresh
|
||||
if (this->server != NULL) NetworkUDPQueryServer(this->server->info.hostname, this->server->port);
|
||||
if (this->server != NULL) NetworkUDPQueryServer(NetworkAddress(this->server->info.hostname, this->server->port));
|
||||
break;
|
||||
|
||||
case NGWW_NEWGRF: // NewGRF Settings
|
||||
|
@ -1313,22 +1313,22 @@ struct NetworkLobbyWindow : public Window {
|
|||
case NLWW_JOIN: // Join company
|
||||
/* Button can be clicked only when it is enabled */
|
||||
_network_playas = this->company;
|
||||
NetworkClientConnectGame(_settings_client.network.last_host, _settings_client.network.last_port);
|
||||
NetworkClientConnectGame(NetworkAddress(_settings_client.network.last_host, _settings_client.network.last_port));
|
||||
break;
|
||||
|
||||
case NLWW_NEW: // New company
|
||||
_network_playas = COMPANY_NEW_COMPANY;
|
||||
NetworkClientConnectGame(_settings_client.network.last_host, _settings_client.network.last_port);
|
||||
NetworkClientConnectGame(NetworkAddress(_settings_client.network.last_host, _settings_client.network.last_port));
|
||||
break;
|
||||
|
||||
case NLWW_SPECTATE: // Spectate game
|
||||
_network_playas = COMPANY_SPECTATOR;
|
||||
NetworkClientConnectGame(_settings_client.network.last_host, _settings_client.network.last_port);
|
||||
NetworkClientConnectGame(NetworkAddress(_settings_client.network.last_host, _settings_client.network.last_port));
|
||||
break;
|
||||
|
||||
case NLWW_REFRESH: // Refresh
|
||||
NetworkTCPQueryServer(_settings_client.network.last_host, _settings_client.network.last_port); // company info
|
||||
NetworkUDPQueryServer(_settings_client.network.last_host, _settings_client.network.last_port); // general data
|
||||
NetworkTCPQueryServer(NetworkAddress(_settings_client.network.last_host, _settings_client.network.last_port)); // company info
|
||||
NetworkUDPQueryServer(NetworkAddress(_settings_client.network.last_host, _settings_client.network.last_port)); // general data
|
||||
/* Clear the information so removed companies don't remain */
|
||||
memset(this->company_info, 0, sizeof(company_info));
|
||||
break;
|
||||
|
@ -1381,8 +1381,8 @@ static void ShowNetworkLobbyWindow(NetworkGameList *ngl)
|
|||
{
|
||||
DeleteWindowById(WC_NETWORK_WINDOW, 0);
|
||||
|
||||
NetworkTCPQueryServer(_settings_client.network.last_host, _settings_client.network.last_port); // company info
|
||||
NetworkUDPQueryServer(_settings_client.network.last_host, _settings_client.network.last_port); // general data
|
||||
NetworkTCPQueryServer(NetworkAddress(_settings_client.network.last_host, _settings_client.network.last_port)); // company info
|
||||
NetworkUDPQueryServer(NetworkAddress(_settings_client.network.last_host, _settings_client.network.last_port)); // general data
|
||||
|
||||
new NetworkLobbyWindow(&_network_lobby_window_desc, ngl);
|
||||
}
|
||||
|
|
|
@ -122,7 +122,7 @@ extern uint16 _network_udp_broadcast;
|
|||
|
||||
extern uint8 _network_advertise_retries;
|
||||
|
||||
void NetworkTCPQueryServer(const char *host, unsigned short port);
|
||||
void NetworkTCPQueryServer(NetworkAddress address);
|
||||
|
||||
void NetworkAddServer(const char *b);
|
||||
void NetworkRebuildHostList();
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
#include "../economy_type.h"
|
||||
#include "core/config.h"
|
||||
#include "core/game.h"
|
||||
#include "core/os_abstraction.h"
|
||||
|
||||
enum {
|
||||
/** How many clients can we have */
|
||||
|
@ -114,5 +115,95 @@ enum NetworkErrorCode {
|
|||
NETWORK_ERROR_FULL,
|
||||
};
|
||||
|
||||
/**
|
||||
* Wrapper for (un)resolved network addresses; there's no reason to transform
|
||||
* a numeric IP to a string and then back again to pass it to functions. It
|
||||
* furthermore allows easier delaying of the hostname lookup.
|
||||
*/
|
||||
class NetworkAddress {
|
||||
private:
|
||||
bool resolved; ///< Has the IP address been resolved
|
||||
char *hostname; ///< The hostname, NULL if there isn't one
|
||||
uint32 ip; ///< The resolved IP address
|
||||
uint16 port; ///< The port associated with the address
|
||||
|
||||
public:
|
||||
/**
|
||||
* Create a network address based on a resolved IP and port
|
||||
* @param ip the resolved ip
|
||||
* @param port the port
|
||||
*/
|
||||
NetworkAddress(in_addr_t ip, uint16 port) :
|
||||
resolved(true),
|
||||
hostname(NULL),
|
||||
ip(ip),
|
||||
port(port)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a network address based on a unresolved host and port
|
||||
* @param ip the unresolved hostname
|
||||
* @param port the port
|
||||
*/
|
||||
NetworkAddress(const char *hostname, uint16 port) :
|
||||
resolved(false),
|
||||
hostname(strdup(hostname)),
|
||||
ip(0),
|
||||
port(port)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Make a clone of another address
|
||||
* @param address the address to clone
|
||||
*/
|
||||
NetworkAddress(const NetworkAddress &address) :
|
||||
resolved(address.resolved),
|
||||
hostname(address.hostname == NULL ? NULL : strdup(address.hostname)),
|
||||
ip(address.ip),
|
||||
port(address.port)
|
||||
{
|
||||
}
|
||||
|
||||
/** Clean up our mess */
|
||||
~NetworkAddress()
|
||||
{
|
||||
free(hostname);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the hostname; in case it wasn't given the
|
||||
* IPv4 dotted representation is given.
|
||||
* @return the hostname
|
||||
*/
|
||||
const char *GetHostname() const;
|
||||
|
||||
/**
|
||||
* Get the IP address. If the IP has not been resolved yet this will resolve
|
||||
* it possibly blocking this function for a while
|
||||
* @return the IP address
|
||||
*/
|
||||
uint32 GetIP();
|
||||
|
||||
/**
|
||||
* Get the port
|
||||
* @return the port
|
||||
*/
|
||||
uint16 GetPort() const
|
||||
{
|
||||
return this->port;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether the IP address has been resolved already
|
||||
* @return true iff the port has been resolved
|
||||
*/
|
||||
bool IsResolved() const
|
||||
{
|
||||
return this->resolved;
|
||||
}
|
||||
};
|
||||
|
||||
#endif /* ENABLE_NETWORK */
|
||||
#endif /* NETWORK_TYPE_H */
|
||||
|
|
|
@ -276,27 +276,22 @@ DEF_UDP_RECEIVE_COMMAND(Client, PACKET_UDP_SERVER_RESPONSE)
|
|||
|
||||
DEF_UDP_RECEIVE_COMMAND(Client, PACKET_UDP_MASTER_RESPONSE_LIST)
|
||||
{
|
||||
int i;
|
||||
struct in_addr ip;
|
||||
uint16 port;
|
||||
uint8 ver;
|
||||
|
||||
/* packet begins with the protocol version (uint8)
|
||||
* then an uint16 which indicates how many
|
||||
* ip:port pairs are in this packet, after that
|
||||
* an uint32 (ip) and an uint16 (port) for each pair
|
||||
*/
|
||||
|
||||
ver = p->Recv_uint8();
|
||||
uint8 ver = p->Recv_uint8();
|
||||
|
||||
if (ver == 1) {
|
||||
for (i = p->Recv_uint16(); i != 0 ; i--) {
|
||||
ip.s_addr = TO_LE32(p->Recv_uint32());
|
||||
port = p->Recv_uint16();
|
||||
for (int i = p->Recv_uint16(); i != 0 ; i--) {
|
||||
uint32 ip = TO_LE32(p->Recv_uint32());
|
||||
uint16 port = p->Recv_uint16();
|
||||
|
||||
/* Somehow we reached the end of the packet */
|
||||
if (this->HasClientQuit()) return;
|
||||
NetworkUDPQueryServer(inet_ntoa(ip), port);
|
||||
NetworkUDPQueryServer(NetworkAddress(ip, port));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -425,7 +420,7 @@ void NetworkUDPSearchGame()
|
|||
_network_udp_broadcast = 300; // Stay searching for 300 ticks
|
||||
}
|
||||
|
||||
void NetworkUDPQueryServer(const char *host, unsigned short port, bool manually)
|
||||
void NetworkUDPQueryServer(NetworkAddress address, bool manually)
|
||||
{
|
||||
struct sockaddr_in out_addr;
|
||||
NetworkGameList *item;
|
||||
|
@ -436,17 +431,17 @@ void NetworkUDPQueryServer(const char *host, unsigned short port, bool manually)
|
|||
}
|
||||
|
||||
out_addr.sin_family = AF_INET;
|
||||
out_addr.sin_port = htons(port);
|
||||
out_addr.sin_addr.s_addr = NetworkResolveHost(host);
|
||||
out_addr.sin_port = htons(address.GetPort());
|
||||
out_addr.sin_addr.s_addr = address.GetIP();
|
||||
|
||||
// Clear item in gamelist
|
||||
item = NetworkGameListAddItem(inet_addr(inet_ntoa(out_addr.sin_addr)), ntohs(out_addr.sin_port));
|
||||
item = NetworkGameListAddItem(address.GetIP(), address.GetPort());
|
||||
if (item == NULL) return;
|
||||
|
||||
if (StrEmpty(item->info.server_name)) {
|
||||
memset(&item->info, 0, sizeof(item->info));
|
||||
strecpy(item->info.server_name, host, lastof(item->info.server_name));
|
||||
strecpy(item->info.hostname, host, lastof(item->info.hostname));
|
||||
strecpy(item->info.server_name, address.GetHostname(), lastof(item->info.server_name));
|
||||
strecpy(item->info.hostname, address.GetHostname(), lastof(item->info.hostname));
|
||||
item->online = false;
|
||||
}
|
||||
item->manually = manually;
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
void NetworkUDPInitialize();
|
||||
void NetworkUDPSearchGame();
|
||||
void NetworkUDPQueryMasterServer();
|
||||
void NetworkUDPQueryServer(const char *host, unsigned short port, bool manually = false);
|
||||
void NetworkUDPQueryServer(NetworkAddress address, bool manually = false);
|
||||
void NetworkUDPAdvertise();
|
||||
void NetworkUDPRemoveAdvertise();
|
||||
void NetworkUDPShutdown();
|
||||
|
|
|
@ -681,7 +681,7 @@ int ttd_main(int argc, char *argv[])
|
|||
ParseConnectionString(¬_used, &port, debuglog_conn);
|
||||
if (port != NULL) rport = atoi(port);
|
||||
|
||||
NetworkStartDebugLog(debuglog_conn, rport);
|
||||
NetworkStartDebugLog(NetworkAddress(debuglog_conn, rport));
|
||||
}
|
||||
#endif /* ENABLE_NETWORK */
|
||||
|
||||
|
@ -728,7 +728,7 @@ int ttd_main(int argc, char *argv[])
|
|||
|
||||
LoadIntroGame();
|
||||
_switch_mode = SM_NONE;
|
||||
NetworkClientConnectGame(network_conn, rport);
|
||||
NetworkClientConnectGame(NetworkAddress(network_conn, rport));
|
||||
}
|
||||
}
|
||||
#endif /* ENABLE_NETWORK */
|
||||
|
@ -1219,7 +1219,7 @@ void GameLoop()
|
|||
if (_network_reconnect > 0 && --_network_reconnect == 0) {
|
||||
/* This means that we want to reconnect to the last host
|
||||
* We do this here, because it means that the network is really closed */
|
||||
NetworkClientConnectGame(_settings_client.network.last_host, _settings_client.network.last_port);
|
||||
NetworkClientConnectGame(NetworkAddress(_settings_client.network.last_host, _settings_client.network.last_port));
|
||||
}
|
||||
/* Singleplayer */
|
||||
StateGameLoop();
|
||||
|
|
Loading…
Reference in New Issue