Merge branch 'master' into jgrpp-beta

# Conflicts:
#	.github/workflows/commit-checker.yml
#	src/company_cmd.cpp
#	src/console_cmds.cpp
#	src/crashlog.cpp
#	src/lang/english.txt
#	src/lang/german.txt
#	src/lang/indonesian.txt
#	src/lang/japanese.txt
#	src/lang/korean.txt
#	src/lang/swedish.txt
#	src/linkgraph/linkgraphjob.cpp
#	src/linkgraph/mcf.cpp
#	src/network/core/tcp.cpp
#	src/network/core/tcp.h
#	src/network/core/tcp_game.h
#	src/network/core/udp.h
#	src/network/network.cpp
#	src/network/network_admin.cpp
#	src/network/network_admin.h
#	src/network/network_chat_gui.cpp
#	src/network/network_client.cpp
#	src/network/network_client.h
#	src/network/network_func.h
#	src/network/network_internal.h
#	src/network/network_server.cpp
#	src/network/network_server.h
#	src/newgrf.cpp
#	src/newgrf_station.cpp
#	src/order_gui.cpp
#	src/rail_cmd.cpp
#	src/saveload/saveload.cpp
#	src/settings.cpp
#	src/settings_gui.cpp
#	src/settings_internal.h
#	src/settings_type.h
#	src/station_cmd.cpp
#	src/stdafx.h
#	src/table/currency_settings.ini
#	src/table/misc_settings.ini
#	src/table/settings.h.preamble
#	src/table/settings.ini
#	src/terraform_cmd.cpp
#	src/timetable_gui.cpp
#	src/train_cmd.cpp
#	src/tree_cmd.cpp
#	src/water_cmd.cpp
This commit is contained in:
Jonathan G Rennison
2021-09-27 22:47:13 +01:00
204 changed files with 1829 additions and 1549 deletions

View File

@@ -180,7 +180,7 @@ bool NetworkAddress::IsInNetmask(const char *netmask)
int tmp_cidr = atoi(chr_cidr + 1);
/* Invalid CIDR, treat as single host */
if (tmp_cidr > 0 || tmp_cidr < cidr) cidr = tmp_cidr;
if (tmp_cidr > 0 && tmp_cidr < cidr) cidr = tmp_cidr;
/* Remove the / so that NetworkAddress works on the IP portion */
std::string ip_str(netmask, chr_cidr - netmask);

View File

@@ -40,7 +40,9 @@ struct Packet;
* SocketHandler for all network sockets in OpenTTD.
*/
class NetworkSocketHandler {
private:
bool has_quit; ///< Whether the current client has quit/send a bad packet
public:
/** Create a new unbound socket */
NetworkSocketHandler() { this->has_quit = false; }
@@ -49,12 +51,13 @@ public:
virtual ~NetworkSocketHandler() {}
/**
* Close the current connection; for TCP this will be mostly equivalent
* to Close(), but for UDP it just means the packet has to be dropped.
* @param error Whether we quit under an error condition or not.
* @return new status of the connection.
* Mark the connection as closed.
*
* This doesn't mean the actual connection is closed, but just that we
* act like it is. This is useful for UDP, which doesn't normally close
* a socket, but its handler might need to pretend it does.
*/
virtual NetworkRecvStatus CloseConnection(bool error = true) { this->has_quit = true; return NETWORK_RECV_STATUS_OKAY; }
void MarkClosed() { this->has_quit = true; }
/**
* Whether the current client connected to the socket has quit.

View File

@@ -128,7 +128,7 @@ void CheckGameCompatibility(NetworkGameInfo &ngi, bool extended)
*/
void FillStaticNetworkServerGameInfo()
{
_network_game_info.use_password = !StrEmpty(_settings_client.network.server_password);
_network_game_info.use_password = !_settings_client.network.server_password.empty();
_network_game_info.start_date = ConvertYMDToDate(_settings_game.game_creation.starting_year, 0, 1);
_network_game_info.clients_max = _settings_client.network.max_clients;
_network_game_info.companies_max = _settings_client.network.max_companies;

View File

@@ -20,72 +20,7 @@
*/
static void NetworkFindBroadcastIPsInternal(NetworkAddressList *broadcast);
#if defined(__HAIKU__) /* doesn't have neither getifaddrs or net/if.h */
/* Based on Andrew Bachmann's netstat+.c. Big thanks to him! */
extern "C" int _netstat(int fd, char **output, int verbose);
int seek_past_header(char **pos, const char *header)
{
char *new_pos = strstr(*pos, header);
if (new_pos == 0) {
return B_ERROR;
}
*pos += strlen(header) + new_pos - *pos + 1;
return B_OK;
}
static void NetworkFindBroadcastIPsInternal(NetworkAddressList *broadcast) // BEOS implementation
{
int sock = socket(AF_INET, SOCK_DGRAM, 0);
if (sock < 0) {
DEBUG(net, 0, "Could not create socket: %s", NetworkError::GetLast().AsString());
return;
}
char *output_pointer = nullptr;
int output_length = _netstat(sock, &output_pointer, 1);
if (output_length < 0) {
DEBUG(net, 0, "Error running _netstat()");
return;
}
char **output = &output_pointer;
if (seek_past_header(output, "IP Interfaces:") == B_OK) {
for (;;) {
uint32 n;
int fields, read;
uint8 i1, i2, i3, i4, j1, j2, j3, j4;
uint32 ip;
uint32 netmask;
fields = sscanf(*output, "%u: %hhu.%hhu.%hhu.%hhu, netmask %hhu.%hhu.%hhu.%hhu%n",
&n, &i1, &i2, &i3, &i4, &j1, &j2, &j3, &j4, &read);
read += 1;
if (fields != 9) {
break;
}
ip = (uint32)i1 << 24 | (uint32)i2 << 16 | (uint32)i3 << 8 | (uint32)i4;
netmask = (uint32)j1 << 24 | (uint32)j2 << 16 | (uint32)j3 << 8 | (uint32)j4;
if (ip != INADDR_LOOPBACK && ip != INADDR_ANY) {
sockaddr_storage address;
memset(&address, 0, sizeof(address));
((sockaddr_in*)&address)->sin_addr.s_addr = htonl(ip | ~netmask);
NetworkAddress addr(address, sizeof(sockaddr));
if (std::none_of(broadcast->begin(), broadcast->end(), [&addr](NetworkAddress const& elem) -> bool { return elem == addr; })) broadcast->push_back(addr);
}
if (read < 0) {
break;
}
*output += read;
}
closesocket(sock);
}
}
#elif defined(HAVE_GETIFADDRS)
#if defined(HAVE_GETIFADDRS)
static void NetworkFindBroadcastIPsInternal(NetworkAddressList *broadcast) // GETIFADDRS implementation
{
struct ifaddrs *ifap, *ifa;

View File

@@ -124,6 +124,13 @@ typedef unsigned long in_addr_t;
# undef FD_SETSIZE
# define FD_SETSIZE 64
# endif
/* Haiku says it supports FD_SETSIZE fds, but it really only supports 512. */
# if defined(__HAIKU__)
# undef FD_SETSIZE
# define FD_SETSIZE 512
# endif
#endif /* UNIX */
/* OS/2 stuff */

View File

@@ -224,7 +224,7 @@ bool Packet::CanReadFromPacket(size_t bytes_to_read, bool close_connection)
/* Check if variable is within packet-size */
if (this->pos + bytes_to_read > this->Size()) {
if (close_connection) this->cs->NetworkSocketHandler::CloseConnection();
if (close_connection) this->cs->NetworkSocketHandler::MarkClosed();
return false;
}
@@ -381,14 +381,13 @@ uint64 Packet::Recv_uint64()
*/
void Packet::Recv_string(char *buffer, size_t size, StringValidationSettings settings)
{
PacketSize pos;
char *bufp = buffer;
const char *last = buffer + size - 1;
/* Don't allow reading from a closed socket */
if (cs->HasClientQuit()) return;
pos = this->pos;
size_t pos = this->pos;
while (--size > 0 && pos < this->Size() && (*buffer++ = this->buffer[pos++]) != '\0') {}
if (size == 0 || pos == this->Size()) {
@@ -398,7 +397,9 @@ void Packet::Recv_string(char *buffer, size_t size, StringValidationSettings set
while (pos < this->Size() && this->buffer[pos] != '\0') pos++;
pos++;
}
this->pos = pos;
assert(pos <= std::numeric_limits<PacketSize>::max());
this->pos = static_cast<PacketSize>(pos);
str_validate(bufp, last, settings);
}

View File

@@ -28,21 +28,42 @@ NetworkTCPSocketHandler::NetworkTCPSocketHandler(SOCKET s) :
NetworkTCPSocketHandler::~NetworkTCPSocketHandler()
{
/* Virtual functions get called statically in destructors, so make it explicit to remove any confusion. */
this->NetworkTCPSocketHandler::CloseConnection();
this->EmptyPacketQueue();
this->CloseSocket();
}
/**
* Free all pending and partially received packets.
*/
void NetworkTCPSocketHandler::EmptyPacketQueue()
{
this->packet_queue.clear();
this->packet_recv.reset();
}
/**
* Close the actual socket of the connection.
* Please make sure CloseConnection is called before CloseSocket, as
* otherwise not all resources might be released.
*/
void NetworkTCPSocketHandler::CloseSocket()
{
if (this->sock != INVALID_SOCKET) closesocket(this->sock);
this->sock = INVALID_SOCKET;
}
/**
* This will put this socket handler in a close state. It will not
* actually close the OS socket; use CloseSocket for this.
* @param error Whether we quit under an error condition or not.
* @return new status of the connection.
*/
NetworkRecvStatus NetworkTCPSocketHandler::CloseConnection(bool error)
{
this->MarkClosed();
this->writable = false;
NetworkSocketHandler::CloseConnection(error);
/* Free all pending and partially received packets */
this->packet_queue.clear();
this->packet_recv.reset();
this->EmptyPacketQueue();
return NETWORK_RECV_STATUS_OKAY;
}

View File

@@ -35,6 +35,8 @@ class NetworkTCPSocketHandler : public NetworkSocketHandler {
private:
std::deque<std::unique_ptr<Packet>> packet_queue; ///< Packets that are awaiting delivery
std::unique_ptr<Packet> packet_recv; ///< Partially received packet
void EmptyPacketQueue();
public:
SOCKET sock; ///< The socket currently connected to
bool writable; ///< Can we write to this socket?
@@ -45,7 +47,9 @@ public:
*/
bool IsConnected() const { return this->sock != INVALID_SOCKET; }
NetworkRecvStatus CloseConnection(bool error = true) override;
virtual NetworkRecvStatus CloseConnection(bool error = true);
void CloseSocket();
void SendPacket(std::unique_ptr<Packet> packet);
void SendPrependPacket(std::unique_ptr<Packet> packet, int queue_after_packet_type);

View File

@@ -34,10 +34,6 @@ NetworkAdminSocketHandler::NetworkAdminSocketHandler(SOCKET s) : status(ADMIN_ST
this->admin_version[0] = '\0';
}
NetworkAdminSocketHandler::~NetworkAdminSocketHandler()
{
}
NetworkRecvStatus NetworkAdminSocketHandler::CloseConnection(bool error)
{
delete this;

View File

@@ -482,7 +482,6 @@ public:
NetworkRecvStatus CloseConnection(bool error = true) override;
NetworkAdminSocketHandler(SOCKET s);
~NetworkAdminSocketHandler();
NetworkRecvStatus ReceivePackets();

View File

@@ -137,17 +137,6 @@ const char *ContentInfo::GetTextfile(TextfileType type) const
return ::GetTextfile(type, GetContentInfoSubDir(this->type), tmp);
}
/**
* Close the actual socket.
*/
void NetworkContentSocketHandler::CloseSocket()
{
if (this->sock == INVALID_SOCKET) return;
closesocket(this->sock);
this->sock = INVALID_SOCKET;
}
/**
* Handle the given packet, i.e. pass it to the right
* parser receive command.

View File

@@ -21,8 +21,6 @@
/** Base socket handler for all Content TCP sockets */
class NetworkContentSocketHandler : public NetworkTCPSocketHandler {
protected:
void CloseSocket();
bool ReceiveInvalidPacket(PacketContentType type);
/**

View File

@@ -310,7 +310,7 @@ protected:
virtual NetworkRecvStatus Receive_SERVER_SETTINGS_ACCESS(Packet *p);
/**
* The client is joined and ready to receive his map:
* The client is joined and ready to receive their map:
* uint32 Own client ID.
* uint32 Generation seed.
* string Network ID of the server.

View File

@@ -68,17 +68,18 @@ NetworkHTTPSocketHandler::NetworkHTTPSocketHandler(SOCKET s,
/** Free whatever needs to be freed. */
NetworkHTTPSocketHandler::~NetworkHTTPSocketHandler()
{
this->CloseConnection();
this->CloseSocket();
if (this->sock != INVALID_SOCKET) closesocket(this->sock);
this->sock = INVALID_SOCKET;
free(this->data);
}
NetworkRecvStatus NetworkHTTPSocketHandler::CloseConnection(bool error)
/**
* Close the actual socket of the connection.
*/
void NetworkHTTPSocketHandler::CloseSocket()
{
NetworkSocketHandler::CloseConnection(error);
return NETWORK_RECV_STATUS_OKAY;
if (this->sock != INVALID_SOCKET) closesocket(this->sock);
this->sock = INVALID_SOCKET;
}
/**
@@ -313,7 +314,7 @@ int NetworkHTTPSocketHandler::Receive()
if (ret < 0) cur->callback->OnFailure();
if (ret <= 0) {
/* Then... the connection can be closed */
cur->CloseConnection();
cur->CloseSocket();
iter = _http_connections.erase(iter);
delete cur;
continue;

View File

@@ -58,7 +58,7 @@ public:
return this->sock != INVALID_SOCKET;
}
NetworkRecvStatus CloseConnection(bool error = true) override;
void CloseSocket();
NetworkHTTPSocketHandler(SOCKET sock, HTTPCallback *callback,
const char *host, const char *url, const char *data, int depth);

View File

@@ -46,7 +46,7 @@ NetworkUDPSocketHandler::NetworkUDPSocketHandler(NetworkAddressList *bind)
bool NetworkUDPSocketHandler::Listen()
{
/* Make sure socket is closed */
this->Close();
this->CloseSocket();
for (NetworkAddress &addr : this->bind) {
addr.Listen(SOCK_DGRAM, &this->sockets);
@@ -56,9 +56,9 @@ bool NetworkUDPSocketHandler::Listen()
}
/**
* Close the given UDP socket
* Close the actual UDP socket.
*/
void NetworkUDPSocketHandler::Close()
void NetworkUDPSocketHandler::CloseSocket()
{
for (auto &s : this->sockets) {
closesocket(s.second);
@@ -66,12 +66,6 @@ void NetworkUDPSocketHandler::Close()
this->sockets.clear();
}
NetworkRecvStatus NetworkUDPSocketHandler::CloseConnection(bool error)
{
NetworkSocketHandler::CloseConnection(error);
return NETWORK_RECV_STATUS_OKAY;
}
/**
* Send a packet over UDP
* @param p the packet to send

View File

@@ -66,8 +66,6 @@ protected:
};
std::vector<FragmentSet> fragments;
NetworkRecvStatus CloseConnection(bool error = true) override;
void ReceiveInvalidPacket(PacketUDPType, NetworkAddress *client_addr);
/**
@@ -208,10 +206,10 @@ public:
NetworkUDPSocketHandler(NetworkAddressList *bind = nullptr);
/** On destructing of this class, the socket needs to be closed */
virtual ~NetworkUDPSocketHandler() { this->Close(); }
virtual ~NetworkUDPSocketHandler() { this->CloseSocket(); }
bool Listen();
void Close();
void CloseSocket();
void SendPacket(Packet *p, NetworkAddress *recv, bool all = false, bool broadcast = false, bool short_mtu = false);
void ReceivePackets();

View File

@@ -35,6 +35,8 @@
#include "../error.h"
#include "../core/checksum_func.hpp"
#include <charconv>
#include <sstream>
#include <iomanip>
#include "../safeguards.h"
@@ -158,9 +160,9 @@ byte NetworkSpectatorCount()
* @param password The unhashed password we like to set ('*' or '' resets the password)
* @return The password.
*/
const char *NetworkChangeCompanyPassword(CompanyID company_id, const char *password)
std::string NetworkChangeCompanyPassword(CompanyID company_id, std::string password)
{
if (strcmp(password, "*") == 0) password = "";
if (password.compare("*") == 0) password = "";
if (_network_server) {
NetworkServerSetCompanyPassword(company_id, password, false);
@@ -178,33 +180,35 @@ const char *NetworkChangeCompanyPassword(CompanyID company_id, const char *passw
* @param password_game_seed Game seed.
* @return The hashed password.
*/
const char *GenerateCompanyPasswordHash(const char *password, const char *password_server_id, uint32 password_game_seed)
std::string GenerateCompanyPasswordHash(const std::string &password, const std::string &password_server_id, uint32 password_game_seed)
{
if (StrEmpty(password)) return password;
if (password.empty()) return password;
char salted_password[NETWORK_SERVER_ID_LENGTH];
size_t password_length = strlen(password);
size_t password_server_id_length = strlen(password_server_id);
size_t password_length = password.size();
size_t password_server_id_length = password_server_id.size();
/* Add the game seed and the server's ID as the salt. */
std::ostringstream salted_password;
/* Add the password with the server's ID and game seed as the salt. */
for (uint i = 0; i < NETWORK_SERVER_ID_LENGTH - 1; i++) {
char password_char = (i < password_length ? password[i] : 0);
char server_id_char = (i < password_server_id_length ? password_server_id[i] : 0);
char seed_char = password_game_seed >> (i % 32);
salted_password[i] = password_char ^ server_id_char ^ seed_char;
salted_password << (char)(password_char ^ server_id_char ^ seed_char); // Cast needed, otherwise interpreted as integer to format
}
Md5 checksum;
uint8 digest[16];
static char hashed_password[NETWORK_SERVER_ID_LENGTH];
/* Generate the MD5 hash */
checksum.Append(salted_password, sizeof(salted_password) - 1);
std::string salted_password_string = salted_password.str();
checksum.Append(salted_password_string.data(), salted_password_string.size());
checksum.Finish(digest);
for (int di = 0; di < 16; di++) seprintf(hashed_password + di * 2, lastof(hashed_password), "%02x", digest[di]);
std::ostringstream hashed_password;
hashed_password << std::hex << std::setfill('0');
for (int di = 0; di < 16; di++) hashed_password << std::setw(2) << (int)digest[di]; // Cast needed, otherwise interpreted as character to add
return hashed_password;
return hashed_password.str();
}
/**
@@ -220,8 +224,10 @@ bool NetworkCompanyIsPassworded(CompanyID company_id)
/* This puts a text-message to the console, or in the future, the chat-box,
* (to keep it all a bit more general)
* If 'self_send' is true, this is the client who is sending the message */
void NetworkTextMessage(NetworkAction action, TextColour colour, bool self_send, const char *name, const char *str, NetworkTextMessageData data)
void NetworkTextMessage(NetworkAction action, TextColour colour, bool self_send, const std::string &name, const std::string &str, NetworkTextMessageData data)
{
SetDParamStr(0, name);
char message_src[256];
StringID strid;
switch (action) {
@@ -250,10 +256,9 @@ void NetworkTextMessage(NetworkAction action, TextColour colour, bool self_send,
case NETWORK_ACTION_NAME_CHANGE: strid = STR_NETWORK_MESSAGE_NAME_CHANGE; break;
case NETWORK_ACTION_GIVE_MONEY: {
SetDParamStr(0, name);
SetDParam(1, data.auxdata >> 16);
GetString(message_src, STR_NETWORK_MESSAGE_MONEY_GIVE_SRC_DESCRIPTION, lastof(message_src));
name = message_src;
SetDParamStr(0, message_src);
extern byte GetCurrentGrfLangID();
byte lang_id = GetCurrentGrfLangID();
@@ -275,7 +280,6 @@ void NetworkTextMessage(NetworkAction action, TextColour colour, bool self_send,
}
char message[1024];
SetDParamStr(0, name);
SetDParamStr(1, str);
SetDParam(2, data.data);
@@ -295,8 +299,8 @@ void NetworkTextMessage(NetworkAction action, TextColour colour, bool self_send,
uint NetworkCalculateLag(const NetworkClientSocket *cs)
{
int lag = cs->last_frame_server - cs->last_frame;
/* This client has missed his ACK packet after 1 DAY_TICKS..
* so we increase his lag for every frame that passes!
/* This client has missed their ACK packet after 1 DAY_TICKS..
* so we increase their lag for every frame that passes!
* The packet can be out by a max of _net_frame_freq */
if (cs->last_frame_server + DAY_TICKS + _settings_client.network.frame_freq < _frame_counter) {
lag += _frame_counter - (cs->last_frame_server + DAY_TICKS + _settings_client.network.frame_freq);
@@ -393,9 +397,7 @@ void NetworkHandlePauseChange(PauseMode prev_mode, PauseMode changed_mode)
str = paused ? STR_NETWORK_SERVER_MESSAGE_GAME_PAUSED : STR_NETWORK_SERVER_MESSAGE_GAME_UNPAUSED;
}
char buffer[DRAW_STRING_BUFFER];
GetString(buffer, str, lastof(buffer));
NetworkTextMessage(NETWORK_ACTION_SERVER_MESSAGE, CC_DEFAULT, false, nullptr, buffer);
NetworkTextMessage(NETWORK_ACTION_SERVER_MESSAGE, CC_DEFAULT, false, "", GetString(str));
break;
}
@@ -627,7 +629,7 @@ void NetworkClose(bool close_admins)
NetworkFreeLocalCommandQueue();
free(_network_company_states);
delete[] _network_company_states;
_network_company_states = nullptr;
InitializeNetworkPools(close_admins);
@@ -710,7 +712,7 @@ public:
};
/**
* Query a server to fetch his game-info for the lobby.
* Query a server to fetch the game-info for the lobby.
* @param connection_string the address to query.
*/
void NetworkQueryLobbyServer(const std::string &connection_string)
@@ -817,7 +819,7 @@ public:
* @param join_company_password The password for the company.
* @return Whether the join has started.
*/
bool NetworkClientConnectGame(const std::string &connection_string, CompanyID default_company, const char *join_server_password, const char *join_company_password)
bool NetworkClientConnectGame(const std::string &connection_string, CompanyID default_company, const std::string &join_server_password, const std::string &join_company_password)
{
CompanyID join_as = default_company;
std::string resolved_connection_string = ParseGameConnectionString(connection_string, NETWORK_DEFAULT_PORT, &join_as).GetAddressAsString(false);
@@ -854,7 +856,7 @@ void NetworkClientJoinGame()
NetworkDisconnect();
NetworkInitialize();
strecpy(_settings_client.network.last_joined, _network_join.connection_string.c_str(), lastof(_settings_client.network.last_joined));
_settings_client.network.last_joined = _network_join.connection_string;
_network_join_status = NETWORK_JOIN_STATUS_CONNECTING;
ShowJoinStatusWindow();
@@ -863,8 +865,8 @@ void NetworkClientJoinGame()
static void NetworkInitGameInfo()
{
if (StrEmpty(_settings_client.network.server_name)) {
strecpy(_settings_client.network.server_name, "Unnamed Server", lastof(_settings_client.network.server_name));
if (_settings_client.network.server_name.empty()) {
_settings_client.network.server_name = "Unnamed Server";
}
FillStaticNetworkServerGameInfo();
@@ -876,7 +878,7 @@ static void NetworkInitGameInfo()
NetworkClientInfo *ci = new NetworkClientInfo(CLIENT_ID_SERVER);
ci->client_playas = _network_dedicated ? COMPANY_SPECTATOR : GetDefaultLocalCompany();
strecpy(ci->client_name, _settings_client.network.client_name, lastof(ci->client_name));
ci->client_name = _settings_client.network.client_name;
}
/**
@@ -887,16 +889,16 @@ static void NetworkInitGameInfo()
*/
static void CheckClientAndServerName()
{
static const char *fallback_client_name = "Unnamed Client";
if (StrEmpty(_settings_client.network.client_name) || strcmp(_settings_client.network.client_name, fallback_client_name) == 0) {
DEBUG(net, 1, "No \"client_name\" has been set, using \"%s\" instead. Please set this now using the \"name <new name>\" command", fallback_client_name);
strecpy(_settings_client.network.client_name, fallback_client_name, lastof(_settings_client.network.client_name));
static const std::string fallback_client_name = "Unnamed Client";
if (_settings_client.network.client_name.empty() || _settings_client.network.client_name.compare(fallback_client_name) == 0) {
DEBUG(net, 1, "No \"client_name\" has been set, using \"%s\" instead. Please set this now using the \"name <new name>\" command", fallback_client_name.c_str());
_settings_client.network.client_name = fallback_client_name;
}
static const char *fallback_server_name = "Unnamed Server";
if (StrEmpty(_settings_client.network.server_name) || strcmp(_settings_client.network.server_name, fallback_server_name) == 0) {
DEBUG(net, 1, "No \"server_name\" has been set, using \"%s\" instead. Please set this now using the \"server_name <new name>\" command", fallback_server_name);
strecpy(_settings_client.network.server_name, fallback_server_name, lastof(_settings_client.network.server_name));
static const std::string fallback_server_name = "Unnamed Server";
if (_settings_client.network.server_name.empty() || _settings_client.network.server_name.compare(fallback_server_name) == 0) {
DEBUG(net, 1, "No \"server_name\" has been set, using \"%s\" instead. Please set this now using the \"server_name <new name>\" command", fallback_server_name.c_str());
_settings_client.network.server_name = fallback_server_name;
}
}
@@ -917,7 +919,7 @@ bool NetworkServerStart()
if (!ServerNetworkGameSocketHandler::Listen(_settings_client.network.server_port)) return false;
/* Only listen for admins when the password isn't empty. */
if (!StrEmpty(_settings_client.network.admin_password)) {
if (!_settings_client.network.admin_password.empty()) {
DEBUG(net, 5, "Starting listeners for admins");
if (!ServerNetworkAdminSocketHandler::Listen(_settings_client.network.server_admin_port)) return false;
}
@@ -926,7 +928,7 @@ bool NetworkServerStart()
DEBUG(net, 5, "Starting listeners for incoming server queries");
NetworkUDPServerListen();
_network_company_states = CallocT<NetworkCompanyState>(MAX_COMPANIES);
_network_company_states = new NetworkCompanyState[MAX_COMPANIES];
_network_server = true;
_networking = true;
_frame_counter = 0;
@@ -1241,7 +1243,7 @@ static void NetworkGenerateServerId()
}
/* _settings_client.network.network_id is our id */
seprintf(_settings_client.network.network_id, lastof(_settings_client.network.network_id), "%s", hex_output);
_settings_client.network.network_id = hex_output;
}
class TCPNetworkDebugConnecter : TCPConnecter {
@@ -1281,7 +1283,7 @@ void NetworkStartUp()
_network_need_advertise = true;
/* Generate an server id when there is none yet */
if (StrEmpty(_settings_client.network.network_id)) NetworkGenerateServerId();
if (_settings_client.network.network_id.empty()) NetworkGenerateServerId();
_network_game_info = {};

View File

@@ -89,7 +89,7 @@ ServerNetworkAdminSocketHandler::~ServerNetworkAdminSocketHandler()
*/
/* static */ bool ServerNetworkAdminSocketHandler::AllowConnection()
{
bool accept = !StrEmpty(_settings_client.network.admin_password) && _network_admins_connected < MAX_ADMINS;
bool accept = !_settings_client.network.admin_password.empty() && _network_admins_connected < MAX_ADMINS;
/* We can't go over the MAX_ADMINS limit here. However, if we accept
* the connection, there has to be space in the pool. */
static_assert(NetworkAdminSocketPool::MAX_SIZE == MAX_ADMINS);
@@ -138,11 +138,9 @@ NetworkRecvStatus ServerNetworkAdminSocketHandler::SendError(NetworkErrorCode er
p->Send_uint8(error);
this->SendPacket(p);
char str[100];
StringID strid = GetNetworkErrorMsg(error);
GetString(str, strid, lastof(str));
std::string error_message = GetString(GetNetworkErrorMsg(error));
DEBUG(net, 1, "[admin] The admin '%s' (%s) made an error and has been disconnected: '%s'", this->admin_name, this->admin_version, str);
DEBUG(net, 1, "[admin] The admin '%s' (%s) made an error and has been disconnected: '%s'", this->admin_name, this->admin_version, error_message.c_str());
return this->CloseConnection(true);
}
@@ -321,20 +319,13 @@ NetworkRecvStatus ServerNetworkAdminSocketHandler::SendCompanyNew(CompanyID comp
*/
NetworkRecvStatus ServerNetworkAdminSocketHandler::SendCompanyInfo(const Company *c)
{
char company_name[NETWORK_COMPANY_NAME_LENGTH];
char manager_name[NETWORK_COMPANY_NAME_LENGTH];
SetDParam(0, c->index);
GetString(company_name, STR_COMPANY_NAME, lastof(company_name));
SetDParam(0, c->index);
GetString(manager_name, STR_PRESIDENT_NAME, lastof(manager_name));
Packet *p = new Packet(ADMIN_PACKET_SERVER_COMPANY_INFO);
p->Send_uint8 (c->index);
p->Send_string(company_name);
p->Send_string(manager_name);
SetDParam(0, c->index);
p->Send_string(GetString(STR_COMPANY_NAME));
SetDParam(0, c->index);
p->Send_string(GetString(STR_PRESIDENT_NAME));
p->Send_uint8 (c->colour);
p->Send_bool (NetworkCompanyIsPassworded(c->index));
p->Send_uint32(c->inaugurated_year);
@@ -357,20 +348,13 @@ NetworkRecvStatus ServerNetworkAdminSocketHandler::SendCompanyInfo(const Company
*/
NetworkRecvStatus ServerNetworkAdminSocketHandler::SendCompanyUpdate(const Company *c)
{
char company_name[NETWORK_COMPANY_NAME_LENGTH];
char manager_name[NETWORK_COMPANY_NAME_LENGTH];
SetDParam(0, c->index);
GetString(company_name, STR_COMPANY_NAME, lastof(company_name));
SetDParam(0, c->index);
GetString(manager_name, STR_PRESIDENT_NAME, lastof(manager_name));
Packet *p = new Packet(ADMIN_PACKET_SERVER_COMPANY_UPDATE);
p->Send_uint8 (c->index);
p->Send_string(company_name);
p->Send_string(manager_name);
SetDParam(0, c->index);
p->Send_string(GetString(STR_COMPANY_NAME));
SetDParam(0, c->index);
p->Send_string(GetString(STR_PRESIDENT_NAME));
p->Send_uint8 (c->colour);
p->Send_bool (NetworkCompanyIsPassworded(c->index));
p->Send_uint8 (CeilDiv(c->months_of_bankruptcy, 3)); // send as quarters_of_bankruptcy
@@ -471,7 +455,7 @@ NetworkRecvStatus ServerNetworkAdminSocketHandler::SendCompanyStats()
* @param msg The actual message.
* @param data Arbitrary extra data.
*/
NetworkRecvStatus ServerNetworkAdminSocketHandler::SendChat(NetworkAction action, DestType desttype, ClientID client_id, const char *msg, NetworkTextMessageData data)
NetworkRecvStatus ServerNetworkAdminSocketHandler::SendChat(NetworkAction action, DestType desttype, ClientID client_id, const std::string &msg, NetworkTextMessageData data)
{
Packet *p = new Packet(ADMIN_PACKET_SERVER_CHAT);
@@ -669,11 +653,10 @@ NetworkRecvStatus ServerNetworkAdminSocketHandler::Receive_ADMIN_JOIN(Packet *p)
{
if (this->status != ADMIN_STATUS_INACTIVE) return this->SendError(NETWORK_ERROR_NOT_EXPECTED);
char password[NETWORK_PASSWORD_LENGTH];
p->Recv_string(password, sizeof(password));
std::string password = p->Recv_string(NETWORK_PASSWORD_LENGTH);
if (StrEmpty(_settings_client.network.admin_password) ||
strcmp(password, _settings_client.network.admin_password) != 0) {
if (_settings_client.network.admin_password.empty() ||
_settings_client.network.admin_password.compare(password) != 0) {
/* Password is invalid */
return this->SendError(NETWORK_ERROR_WRONG_PASSWORD);
}
@@ -793,8 +776,7 @@ NetworkRecvStatus ServerNetworkAdminSocketHandler::Receive_ADMIN_CHAT(Packet *p)
DestType desttype = (DestType)p->Recv_uint8();
int dest = p->Recv_uint32();
char msg[NETWORK_CHAT_LENGTH];
p->Recv_string(msg, NETWORK_CHAT_LENGTH);
std::string msg = p->Recv_string(NETWORK_CHAT_LENGTH);
switch (action) {
case NETWORK_ACTION_CHAT:
@@ -926,7 +908,7 @@ void NetworkAdminCompanyRemove(CompanyID company_id, AdminCompanyRemoveReason bc
/**
* Send chat to the admin network (if they did opt in for the respective update).
*/
void NetworkAdminChat(NetworkAction action, DestType desttype, ClientID client_id, const char *msg, NetworkTextMessageData data, bool from_admin)
void NetworkAdminChat(NetworkAction action, DestType desttype, ClientID client_id, const std::string &msg, NetworkTextMessageData data, bool from_admin)
{
if (from_admin) return;

View File

@@ -61,7 +61,7 @@ public:
NetworkRecvStatus SendCompanyEconomy();
NetworkRecvStatus SendCompanyStats();
NetworkRecvStatus SendChat(NetworkAction action, DestType desttype, ClientID client_id, const char *msg, NetworkTextMessageData data);
NetworkRecvStatus SendChat(NetworkAction action, DestType desttype, ClientID client_id, const std::string &msg, NetworkTextMessageData data);
NetworkRecvStatus SendRcon(uint16 colour, const char *command);
NetworkRecvStatus SendConsole(const char *origin, const char *command);
NetworkRecvStatus SendGameScript(const char *json);
@@ -106,7 +106,7 @@ void NetworkAdminCompanyInfo(const Company *company, bool new_company);
void NetworkAdminCompanyUpdate(const Company *company);
void NetworkAdminCompanyRemove(CompanyID company_id, AdminCompanyRemoveReason bcrr);
void NetworkAdminChat(NetworkAction action, DestType desttype, ClientID client_id, const char *msg, NetworkTextMessageData data = NetworkTextMessageData(), bool from_admin = false);
void NetworkAdminChat(NetworkAction action, DestType desttype, ClientID client_id, const std::string &msg, NetworkTextMessageData data = NetworkTextMessageData(), bool from_admin = false);
void NetworkAdminUpdate(AdminUpdateFrequency freq);
void NetworkServerSendAdminRcon(AdminIndex admin_index, TextColour colour_code, const char *string);
void NetworkAdminConsole(const char *origin, const char *string);

View File

@@ -22,10 +22,10 @@ extern NetworkClientInfoPool _networkclientinfo_pool;
/** Container for all information known about a client. */
struct NetworkClientInfo : NetworkClientInfoPool::PoolItem<&_networkclientinfo_pool> {
ClientID client_id; ///< Client identifier (same as ClientState->client_id)
char client_name[NETWORK_CLIENT_NAME_LENGTH]; ///< Name of the client
CompanyID client_playas; ///< As which company is this client playing (CompanyID)
Date join_date; ///< Gamedate the client has joined
ClientID client_id; ///< Client identifier (same as ClientState->client_id)
std::string client_name; ///< Name of the client
CompanyID client_playas; ///< As which company is this client playing (CompanyID)
Date join_date; ///< Gamedate the client has joined
/**
* Create a new client.

View File

@@ -128,7 +128,7 @@ void NetworkUndrawChatMessage()
/* Sometimes we also need to hide the cursor
* This is because both textmessage and the cursor take a shot of the
* screen before drawing.
* Now the textmessage takes his shot and paints his data before the cursor
* Now the textmessage takes its shot and paints its data before the cursor
* does, so in the shot of the cursor is the screen-data of the textmessage
* included when the cursor hangs somewhere over the textmessage. To
* avoid wrong repaints, we undraw the cursor in that case, and everything
@@ -259,9 +259,9 @@ void NetworkDrawChatMessage()
* @param type The type of destination.
* @param dest The actual destination index.
*/
static void SendChat(const char *buf, DestType type, int dest)
static void SendChat(const std::string &buf, DestType type, int dest)
{
if (StrEmpty(buf)) return;
if (buf.empty()) return;
assert(type >= DESTTYPE_BROADCAST && type <= DESTTYPE_CLIENT);
if (!_network_server) {
MyClient::SendChat((NetworkAction)(NETWORK_ACTION_CHAT + type), type, dest, buf, NetworkTextMessageData());
@@ -334,7 +334,7 @@ struct NetworkChatWindow : public Window {
/* Skip inactive clients */
for (NetworkClientInfo *ci : NetworkClientInfo::Iterate(*item)) {
*item = ci->index;
return ci->client_name;
return ci->client_name.c_str();
}
*item = MAX_CLIENT_SLOTS;
}

View File

@@ -166,6 +166,7 @@ ClientNetworkGameSocketHandler::~ClientNetworkGameSocketHandler()
_network_settings_access = false;
delete this->savegame;
delete this->GetInfo();
if (this->desync_log_file) {
if (!this->server_desync_log.empty()) {
@@ -212,7 +213,6 @@ NetworkRecvStatus ClientNetworkGameSocketHandler::CloseConnection(NetworkRecvSta
this->ReceivePackets();
}
delete this->GetInfo();
delete this;
return status;
@@ -230,7 +230,7 @@ void ClientNetworkGameSocketHandler::ClientError(NetworkRecvStatus res)
/* We just want to close the connection.. */
if (res == NETWORK_RECV_STATUS_CLOSE_QUERY) {
this->NetworkSocketHandler::CloseConnection();
this->NetworkSocketHandler::MarkClosed();
this->CloseConnection(res);
_networking = false;
@@ -382,7 +382,7 @@ static uint32 _rcon_password_game_seed;
/** One bit of 'entropy' used to generate a salt for the settings passwords. */
static uint32 _settings_password_game_seed;
/** The other bit of 'entropy' used to generate a salt for the company, server, rcon, and settings passwords. */
static char _password_server_id[NETWORK_SERVER_ID_LENGTH];
static std::string _password_server_id;
/** Maximum number of companies of the currently joined server. */
static uint8 _network_server_max_companies;
@@ -454,7 +454,7 @@ NetworkRecvStatus ClientNetworkGameSocketHandler::SendNewGRFsOk()
* Set the game password as requested.
* @param password The game password.
*/
NetworkRecvStatus ClientNetworkGameSocketHandler::SendGamePassword(const char *password)
NetworkRecvStatus ClientNetworkGameSocketHandler::SendGamePassword(const std::string &password)
{
Packet *p = new Packet(PACKET_CLIENT_GAME_PASSWORD, SHRT_MAX);
p->Send_string(GenerateCompanyPasswordHash(password, _password_server_id, _server_password_game_seed));
@@ -466,7 +466,7 @@ NetworkRecvStatus ClientNetworkGameSocketHandler::SendGamePassword(const char *p
* Set the company password as requested.
* @param password The company password.
*/
NetworkRecvStatus ClientNetworkGameSocketHandler::SendCompanyPassword(const char *password)
NetworkRecvStatus ClientNetworkGameSocketHandler::SendCompanyPassword(const std::string &password)
{
Packet *p = new Packet(PACKET_CLIENT_COMPANY_PASSWORD, SHRT_MAX);
p->Send_string(GenerateCompanyPasswordHash(password, _password_server_id, _company_password_game_seed));
@@ -478,10 +478,10 @@ NetworkRecvStatus ClientNetworkGameSocketHandler::SendCompanyPassword(const char
* Set the game password as requested.
* @param password The game password.
*/
NetworkRecvStatus ClientNetworkGameSocketHandler::SendSettingsPassword(const char *password)
NetworkRecvStatus ClientNetworkGameSocketHandler::SendSettingsPassword(const std::string &password)
{
Packet *p = new Packet(PACKET_CLIENT_SETTINGS_PASSWORD, SHRT_MAX);
if (StrEmpty(password)) {
if (password.empty()) {
p->Send_string("");
} else {
p->Send_string(GenerateCompanyPasswordHash(password, _password_server_id, _settings_password_game_seed));
@@ -540,7 +540,7 @@ NetworkRecvStatus ClientNetworkGameSocketHandler::SendCommand(const CommandPacke
}
/** Send a chat-packet over the network */
NetworkRecvStatus ClientNetworkGameSocketHandler::SendChat(NetworkAction action, DestType type, int dest, const char *msg, NetworkTextMessageData data)
NetworkRecvStatus ClientNetworkGameSocketHandler::SendChat(NetworkAction action, DestType type, int dest, const std::string &msg, NetworkTextMessageData data)
{
if (!my_client) return NETWORK_RECV_STATUS_CLIENT_QUIT;
Packet *p = new Packet(PACKET_CLIENT_CHAT, SHRT_MAX);
@@ -599,7 +599,7 @@ NetworkRecvStatus ClientNetworkGameSocketHandler::SendDesyncMessage(const char *
* Tell the server that we like to change the password of the company.
* @param password The new password.
*/
NetworkRecvStatus ClientNetworkGameSocketHandler::SendSetPassword(const char *password)
NetworkRecvStatus ClientNetworkGameSocketHandler::SendSetPassword(const std::string &password)
{
Packet *p = new Packet(PACKET_CLIENT_SET_PASSWORD, SHRT_MAX);
@@ -637,7 +637,7 @@ NetworkRecvStatus ClientNetworkGameSocketHandler::SendQuit()
* @param pass The password for the remote command.
* @param command The actual command.
*/
NetworkRecvStatus ClientNetworkGameSocketHandler::SendRCon(const char *pass, const char *command)
NetworkRecvStatus ClientNetworkGameSocketHandler::SendRCon(const std::string &pass, const char *command)
{
Packet *p = new Packet(PACKET_CLIENT_RCON, SHRT_MAX);
p->Send_string(GenerateCompanyPasswordHash(pass, _password_server_id, _rcon_password_game_seed));
@@ -651,7 +651,7 @@ NetworkRecvStatus ClientNetworkGameSocketHandler::SendRCon(const char *pass, con
* @param company The company to move to.
* @param password The password of the company to move to.
*/
NetworkRecvStatus ClientNetworkGameSocketHandler::SendMove(CompanyID company, const char *password)
NetworkRecvStatus ClientNetworkGameSocketHandler::SendMove(CompanyID company, const std::string &password)
{
Packet *p = new Packet(PACKET_CLIENT_MOVE, SHRT_MAX);
p->Send_uint8(company);
@@ -761,7 +761,7 @@ NetworkRecvStatus ClientNetworkGameSocketHandler::Receive_SERVER_COMPANY_INFO(Pa
NetworkCompanyInfo *company_info = GetLobbyCompanyInfo(current);
if (company_info == nullptr) return NETWORK_RECV_STATUS_CLOSE_QUERY;
p->Recv_string(company_info->company_name, sizeof(company_info->company_name));
company_info->company_name = p->Recv_string(NETWORK_COMPANY_NAME_LENGTH);
company_info->inaugurated_year = p->Recv_uint32();
company_info->company_value = p->Recv_uint64();
company_info->money = p->Recv_uint64();
@@ -776,7 +776,7 @@ NetworkRecvStatus ClientNetworkGameSocketHandler::Receive_SERVER_COMPANY_INFO(Pa
}
company_info->ai = p->Recv_bool();
p->Recv_string(company_info->clients, sizeof(company_info->clients));
company_info->clients = p->Recv_string(NETWORK_CLIENTS_LENGTH);
SetWindowDirty(WC_NETWORK_WINDOW, WN_NETWORK_WINDOW_LOBBY);
@@ -794,9 +794,8 @@ NetworkRecvStatus ClientNetworkGameSocketHandler::Receive_SERVER_CLIENT_INFO(Pac
NetworkClientInfo *ci;
ClientID client_id = (ClientID)p->Recv_uint32();
CompanyID playas = (CompanyID)p->Recv_uint8();
char name[NETWORK_NAME_LENGTH];
p->Recv_string(name, sizeof(name));
std::string name = p->Recv_string(NETWORK_NAME_LENGTH);
if (this->status < STATUS_AUTHORIZED) return NETWORK_RECV_STATUS_MALFORMED_PACKET;
if (this->HasClientQuit()) return NETWORK_RECV_STATUS_CLIENT_QUIT;
@@ -807,7 +806,7 @@ NetworkRecvStatus ClientNetworkGameSocketHandler::Receive_SERVER_CLIENT_INFO(Pac
ci = NetworkClientInfo::GetByClientID(client_id);
if (ci != nullptr) {
if (playas == ci->client_playas && strcmp(name, ci->client_name) != 0) {
if (playas == ci->client_playas && name.compare(ci->client_name) != 0) {
/* Client name changed, display the change */
NetworkTextMessage(NETWORK_ACTION_NAME_CHANGE, CC_DEFAULT, false, ci->client_name, name);
} else if (playas != ci->client_playas) {
@@ -820,7 +819,7 @@ NetworkRecvStatus ClientNetworkGameSocketHandler::Receive_SERVER_CLIENT_INFO(Pac
if (client_id == _network_own_client_id) SetLocalCompany(!Company::IsValidID(playas) ? COMPANY_SPECTATOR : playas);
ci->client_playas = playas;
strecpy(ci->client_name, name, lastof(ci->client_name));
ci->client_name = name;
InvalidateWindowData(WC_CLIENT_LIST, 0);
@@ -839,7 +838,7 @@ NetworkRecvStatus ClientNetworkGameSocketHandler::Receive_SERVER_CLIENT_INFO(Pac
ci->client_playas = playas;
if (client_id == _network_own_client_id) this->SetInfo(ci);
strecpy(ci->client_name, name, lastof(ci->client_name));
ci->client_name = name;
InvalidateWindowData(WC_CLIENT_LIST, 0);
@@ -888,8 +887,7 @@ NetworkRecvStatus ClientNetworkGameSocketHandler::Receive_SERVER_ERROR(Packet *p
if (error < (ptrdiff_t)lengthof(network_error_strings)) err = network_error_strings[error];
/* In case of kicking a client, we assume there is a kick message in the packet if we can read one byte */
if (error == NETWORK_ERROR_KICKED && p->CanReadFromPacket(1)) {
char kick_msg[255];
p->Recv_string(kick_msg, sizeof(kick_msg));
std::string kick_msg = p->Recv_string(NETWORK_CHAT_LENGTH);
SetDParamStr(0, kick_msg);
ShowErrorMessage(err, STR_NETWORK_ERROR_KICK_MESSAGE, WL_CRITICAL);
} else {
@@ -944,12 +942,11 @@ NetworkRecvStatus ClientNetworkGameSocketHandler::Receive_SERVER_NEED_GAME_PASSW
this->status = STATUS_AUTH_GAME;
_server_password_game_seed = p->Recv_uint32();
p->Recv_string(_password_server_id, sizeof(_password_server_id));
_password_server_id = p->Recv_string(NETWORK_SERVER_ID_LENGTH);
if (this->HasClientQuit()) return NETWORK_RECV_STATUS_MALFORMED_PACKET;
const char *password = _network_join.server_password;
if (!StrEmpty(password)) {
return SendGamePassword(password);
if (!_network_join.server_password.empty()) {
return SendGamePassword(_network_join.server_password);
}
ShowNetworkNeedPassword(NETWORK_GAME_PASSWORD);
@@ -963,12 +960,11 @@ NetworkRecvStatus ClientNetworkGameSocketHandler::Receive_SERVER_NEED_COMPANY_PA
this->status = STATUS_AUTH_COMPANY;
_company_password_game_seed = p->Recv_uint32();
p->Recv_string(_password_server_id, sizeof(_password_server_id));
_password_server_id = p->Recv_string(NETWORK_SERVER_ID_LENGTH);
if (this->HasClientQuit()) return NETWORK_RECV_STATUS_MALFORMED_PACKET;
const char *password = _network_join.company_password;
if (!StrEmpty(password)) {
return SendCompanyPassword(password);
if (!_network_join.company_password.empty()) {
return SendCompanyPassword(_network_join.company_password);
}
ShowNetworkNeedPassword(NETWORK_COMPANY_PASSWORD);
@@ -988,7 +984,7 @@ NetworkRecvStatus ClientNetworkGameSocketHandler::Receive_SERVER_WELCOME(Packet
_server_password_game_seed = p->Recv_uint32();
_rcon_password_game_seed = p->Recv_uint32();
_settings_password_game_seed = p->Recv_uint32();
p->Recv_string(_password_server_id, sizeof(_password_server_id));
_password_server_id = p->Recv_string(NETWORK_SERVER_ID_LENGTH);
/* Start receiving the map */
return SendGetMap();
@@ -1184,13 +1180,13 @@ NetworkRecvStatus ClientNetworkGameSocketHandler::Receive_SERVER_CHAT(Packet *p)
if (this->status == STATUS_CLOSING) return NETWORK_RECV_STATUS_OKAY;
if (this->status != STATUS_ACTIVE) return NETWORK_RECV_STATUS_MALFORMED_PACKET;
char name[NETWORK_NAME_LENGTH], msg[NETWORK_CHAT_LENGTH];
std::string name;
const NetworkClientInfo *ci = nullptr, *ci_to;
NetworkAction action = (NetworkAction)p->Recv_uint8();
ClientID client_id = (ClientID)p->Recv_uint32();
bool self_send = p->Recv_bool();
p->Recv_string(msg, NETWORK_CHAT_LENGTH);
std::string msg = p->Recv_string(NETWORK_CHAT_LENGTH);
NetworkTextMessageData data;
data.recv(p);
@@ -1202,7 +1198,7 @@ NetworkRecvStatus ClientNetworkGameSocketHandler::Receive_SERVER_CHAT(Packet *p)
switch (action) {
case NETWORK_ACTION_CHAT_CLIENT:
/* For speaking to client we need the client-name */
seprintf(name, lastof(name), "%s", ci_to->client_name);
name = ci_to->client_name;
ci = NetworkClientInfo::GetByClientID(_network_own_client_id);
break;
@@ -1215,7 +1211,7 @@ NetworkRecvStatus ClientNetworkGameSocketHandler::Receive_SERVER_CHAT(Packet *p)
StringID str = Company::IsValidID(ci_to->client_playas) ? STR_COMPANY_NAME : STR_NETWORK_SPECTATORS;
SetDParam(0, ci_to->client_playas);
GetString(name, str, lastof(name));
name = GetString(str);
ci = NetworkClientInfo::GetByClientID(_network_own_client_id);
break;
}
@@ -1224,7 +1220,7 @@ NetworkRecvStatus ClientNetworkGameSocketHandler::Receive_SERVER_CHAT(Packet *p)
}
} else {
/* Display message from somebody else */
seprintf(name, lastof(name), "%s", ci_to->client_name);
name = ci_to->client_name;
ci = ci_to;
}
@@ -1243,7 +1239,7 @@ NetworkRecvStatus ClientNetworkGameSocketHandler::Receive_SERVER_ERROR_QUIT(Pack
NetworkClientInfo *ci = NetworkClientInfo::GetByClientID(client_id);
if (ci != nullptr) {
NetworkTextMessage(NETWORK_ACTION_LEAVE, CC_DEFAULT, false, ci->client_name, nullptr, GetNetworkErrorMsg((NetworkErrorCode)p->Recv_uint8()));
NetworkTextMessage(NETWORK_ACTION_LEAVE, CC_DEFAULT, false, ci->client_name, "", GetNetworkErrorMsg((NetworkErrorCode)p->Recv_uint8()));
delete ci;
}
@@ -1269,7 +1265,7 @@ NetworkRecvStatus ClientNetworkGameSocketHandler::Receive_SERVER_QUIT(Packet *p)
NetworkClientInfo *ci = NetworkClientInfo::GetByClientID(client_id);
if (ci != nullptr) {
NetworkTextMessage(NETWORK_ACTION_LEAVE, CC_DEFAULT, false, ci->client_name, nullptr, STR_NETWORK_MESSAGE_CLIENT_LEAVING);
NetworkTextMessage(NETWORK_ACTION_LEAVE, CC_DEFAULT, false, ci->client_name, "", STR_NETWORK_MESSAGE_CLIENT_LEAVING);
delete ci;
} else {
DEBUG(net, 1, "Unknown client (%d) is leaving the game", client_id);
@@ -1334,10 +1330,9 @@ NetworkRecvStatus ClientNetworkGameSocketHandler::Receive_SERVER_RCON(Packet *p)
TextColour colour_code = (TextColour)p->Recv_uint16();
if (!IsValidConsoleColour(colour_code)) return NETWORK_RECV_STATUS_MALFORMED_PACKET;
char rcon_out[NETWORK_RCONCOMMAND_LENGTH];
p->Recv_string(rcon_out, sizeof(rcon_out));
std::string rcon_out = p->Recv_string(NETWORK_RCONCOMMAND_LENGTH);
IConsolePrint(colour_code, rcon_out);
IConsolePrint(colour_code, rcon_out.c_str());
return NETWORK_RECV_STATUS_OKAY;
}
@@ -1472,7 +1467,7 @@ void NetworkClient_Connected()
* @param password The password.
* @param command The command to execute.
*/
void NetworkClientSendRcon(const char *password, const char *command)
void NetworkClientSendRcon(const std::string &password, const char *command)
{
MyClient::SendRCon(password, command);
}
@@ -1482,7 +1477,7 @@ void NetworkClientSendRcon(const char *password, const char *command)
* @param password The password.
* @param command The command to execute.
*/
void NetworkClientSendSettingsPassword(const char *password)
void NetworkClientSendSettingsPassword(const std::string &password)
{
MyClient::SendSettingsPassword(password);
}
@@ -1493,7 +1488,7 @@ void NetworkClientSendSettingsPassword(const char *password)
* @param pass the password, is only checked on the server end if a password is needed.
* @return void
*/
void NetworkClientRequestMove(CompanyID company_id, const char *pass)
void NetworkClientRequestMove(CompanyID company_id, const std::string &pass)
{
MyClient::SendMove(company_id, pass);
}
@@ -1524,10 +1519,10 @@ void NetworkClientsToSpectators(CompanyID cid)
* @param client_name The client name to check for validity.
* @return True iff the name is valid.
*/
bool NetworkIsValidClientName(const char *client_name)
bool NetworkIsValidClientName(const std::string_view client_name)
{
if (StrEmpty(client_name)) return false;
if (*client_name == ' ') return false;
if (client_name.empty()) return false;
if (client_name[0] == ' ') return false;
return true;
}
@@ -1546,7 +1541,7 @@ bool NetworkIsValidClientName(const char *client_name)
* and trailing spaces.
* @return True iff the client name is valid.
*/
bool NetworkValidateClientName(char *client_name)
bool NetworkValidateClientName(std::string &client_name)
{
StrTrimInPlace(client_name);
if (NetworkIsValidClientName(client_name)) return true;
@@ -1582,13 +1577,16 @@ void NetworkUpdateClientName()
if (!NetworkValidateClientName()) return;
/* Don't change the name if it is the same as the old name */
if (strcmp(ci->client_name, _settings_client.network.client_name) != 0) {
if (_settings_client.network.client_name.compare(ci->client_name) != 0) {
if (!_network_server) {
MyClient::SendSetName(_settings_client.network.client_name);
MyClient::SendSetName(_settings_client.network.client_name.c_str());
} else {
if (NetworkFindName(_settings_client.network.client_name, lastof(_settings_client.network.client_name))) {
NetworkTextMessage(NETWORK_ACTION_NAME_CHANGE, CC_DEFAULT, false, ci->client_name, _settings_client.network.client_name);
strecpy(ci->client_name, _settings_client.network.client_name, lastof(ci->client_name));
/* Copy to a temporary buffer so no #n gets added after our name in the settings when there are duplicate names. */
char temporary_name[NETWORK_CLIENT_NAME_LENGTH];
strecpy(temporary_name, _settings_client.network.client_name.c_str(), lastof(temporary_name));
if (NetworkFindName(temporary_name, lastof(temporary_name))) {
NetworkTextMessage(NETWORK_ACTION_NAME_CHANGE, CC_DEFAULT, false, ci->client_name, temporary_name);
ci->client_name = temporary_name;
NetworkUpdateClientInfo(CLIENT_ID_SERVER);
}
}
@@ -1603,7 +1601,7 @@ void NetworkUpdateClientName()
* @param msg The actual message.
* @param data Arbitrary extra data.
*/
void NetworkClientSendChat(NetworkAction action, DestType type, int dest, const char *msg, NetworkTextMessageData data)
void NetworkClientSendChat(NetworkAction action, DestType type, int dest, const std::string &msg, NetworkTextMessageData data)
{
MyClient::SendChat(action, type, dest, msg, data);
}
@@ -1618,7 +1616,7 @@ void NetworkClientSendDesyncMsg(const char *msg)
* Set/Reset company password on the client side.
* @param password Password to be set.
*/
void NetworkClientSetCompanyPassword(const char *password)
void NetworkClientSetCompanyPassword(const std::string &password)
{
MyClient::SendSetPassword(password);
}

View File

@@ -104,15 +104,15 @@ public:
static NetworkRecvStatus SendQuit();
static NetworkRecvStatus SendAck();
static NetworkRecvStatus SendGamePassword(const char *password);
static NetworkRecvStatus SendCompanyPassword(const char *password);
static NetworkRecvStatus SendSettingsPassword(const char *password);
static NetworkRecvStatus SendGamePassword(const std::string &password);
static NetworkRecvStatus SendCompanyPassword(const std::string &password);
static NetworkRecvStatus SendSettingsPassword(const std::string &password);
static NetworkRecvStatus SendChat(NetworkAction action, DestType type, int dest, const char *msg, NetworkTextMessageData data);
static NetworkRecvStatus SendSetPassword(const char *password);
static NetworkRecvStatus SendChat(NetworkAction action, DestType type, int dest, const std::string &msg, NetworkTextMessageData data);
static NetworkRecvStatus SendSetPassword(const std::string &password);
static NetworkRecvStatus SendSetName(const char *name);
static NetworkRecvStatus SendRCon(const char *password, const char *command);
static NetworkRecvStatus SendMove(CompanyID company, const char *password);
static NetworkRecvStatus SendRCon(const std::string &password, const char *command);
static NetworkRecvStatus SendMove(CompanyID company, const std::string &password);
static bool IsConnected();
@@ -127,15 +127,15 @@ public:
typedef ClientNetworkGameSocketHandler MyClient;
void NetworkClient_Connected();
void NetworkClientSetCompanyPassword(const char *password);
void NetworkClientSetCompanyPassword(const std::string &password);
/** Information required to join a server. */
struct NetworkJoinInfo {
NetworkJoinInfo() : company(COMPANY_SPECTATOR), server_password(nullptr), company_password(nullptr) {}
NetworkJoinInfo() : company(COMPANY_SPECTATOR) {}
std::string connection_string; ///< The address of the server to join.
CompanyID company; ///< The company to join.
const char *server_password; ///< The password of the server to join.
const char *company_password; ///< The password of the company to join.
std::string server_password; ///< The password of the server to join.
std::string company_password; ///< The password of the company to join.
};
extern NetworkJoinInfo _network_join;

View File

@@ -79,7 +79,7 @@ bool ClientNetworkContentSocketHandler::Receive_SERVER_INFO(Packet *p)
if (!ci->IsValid()) {
delete ci;
this->Close();
this->CloseConnection();
return false;
}
@@ -512,7 +512,7 @@ bool ClientNetworkContentSocketHandler::Receive_SERVER_CONTENT(Packet *p)
p->Recv_string(this->curInfo->filename, lengthof(this->curInfo->filename));
if (!this->BeforeDownload()) {
this->Close();
this->CloseConnection();
return false;
}
} else {
@@ -521,7 +521,7 @@ bool ClientNetworkContentSocketHandler::Receive_SERVER_CONTENT(Packet *p)
if (toRead != 0 && (size_t)p->TransferOut(TransferOutFWrite, this->curFile) != toRead) {
DeleteWindowById(WC_NETWORK_STATUS_WINDOW, WN_NETWORK_STATUS_WINDOW_CONTENT_DOWNLOAD);
ShowErrorMessage(STR_CONTENT_ERROR_COULD_NOT_DOWNLOAD, STR_CONTENT_ERROR_COULD_NOT_DOWNLOAD_FILE_NOT_WRITABLE, WL_ERROR);
this->Close();
this->CloseConnection();
fclose(this->curFile);
this->curFile = nullptr;
@@ -805,14 +805,16 @@ void ClientNetworkContentSocketHandler::Connect()
/**
* Disconnect from the content server.
*/
void ClientNetworkContentSocketHandler::Close()
NetworkRecvStatus ClientNetworkContentSocketHandler::CloseConnection(bool error)
{
if (this->sock == INVALID_SOCKET) return;
NetworkContentSocketHandler::CloseConnection();
if (this->sock == INVALID_SOCKET) return NETWORK_RECV_STATUS_OKAY;
this->CloseConnection();
this->CloseSocket();
this->OnDisconnect();
return NETWORK_RECV_STATUS_OKAY;
}
/**
@@ -824,7 +826,7 @@ void ClientNetworkContentSocketHandler::SendReceive()
if (this->sock == INVALID_SOCKET || this->isConnecting) return;
if (std::chrono::steady_clock::now() > this->lastActivity + IDLE_TIMEOUT) {
this->Close();
this->CloseConnection();
return;
}
@@ -1027,9 +1029,9 @@ void ClientNetworkContentSocketHandler::CheckDependencyState(ContentInfo *ci)
/* First check whether anything depends on us */
int sel_count = 0;
bool force_selection = false;
for (const ContentInfo *ci : parents) {
if (ci->IsSelected()) sel_count++;
if (ci->state == ContentInfo::SELECTED) force_selection = true;
for (const ContentInfo *parent_ci : parents) {
if (parent_ci->IsSelected()) sel_count++;
if (parent_ci->state == ContentInfo::SELECTED) force_selection = true;
}
if (sel_count == 0) {
/* Nothing depends on us */
@@ -1044,8 +1046,8 @@ void ClientNetworkContentSocketHandler::CheckDependencyState(ContentInfo *ci)
this->ReverseLookupTreeDependency(parents, c);
/* Is there anything that is "force" selected?, if so... we're done. */
for (const ContentInfo *ci : parents) {
if (ci->state != ContentInfo::SELECTED) continue;
for (const ContentInfo *parent_ci : parents) {
if (parent_ci->state != ContentInfo::SELECTED) continue;
force_selection = true;
break;

View File

@@ -110,7 +110,7 @@ public:
void Connect();
void SendReceive();
void Close();
NetworkRecvStatus CloseConnection(bool error = true) override;
void RequestContentList(ContentType type);
void RequestContentList(uint count, const ContentID *content_ids);

View File

@@ -260,7 +260,7 @@ public:
{
if (widget == WID_NCDS_CANCELOK) {
if (this->downloaded_bytes != this->total_bytes) {
_network_content_client.Close();
_network_content_client.CloseConnection();
delete this;
} else {
/* If downloading succeeded, close the online content window. This will close

View File

@@ -35,12 +35,12 @@ extern StringList _network_host_list;
extern StringList _network_ban_list;
byte NetworkSpectatorCount();
bool NetworkIsValidClientName(const char *client_name);
bool NetworkIsValidClientName(const std::string_view client_name);
bool NetworkValidateClientName();
bool NetworkValidateClientName(char *client_name);
bool NetworkValidateClientName(std::string &client_name);
void NetworkUpdateClientName();
bool NetworkCompanyHasClients(CompanyID company);
const char *NetworkChangeCompanyPassword(CompanyID company_id, const char *password);
std::string NetworkChangeCompanyPassword(CompanyID company_id, std::string password);
void NetworkReboot();
void NetworkDisconnect(bool blocking = false, bool close_admins = true);
void NetworkGameLoop();
@@ -51,12 +51,12 @@ void NetworkPopulateCompanyStats(NetworkCompanyStats *stats);
void NetworkUpdateClientInfo(ClientID client_id);
void NetworkClientsToSpectators(CompanyID cid);
bool NetworkClientConnectGame(const std::string &connection_string, CompanyID default_company, const char *join_server_password = nullptr, const char *join_company_password = nullptr);
bool NetworkClientConnectGame(const std::string &connection_string, CompanyID default_company, const std::string &join_server_password = "", const std::string &join_company_password = "");
void NetworkClientJoinGame();
void NetworkClientRequestMove(CompanyID company, const char *pass = "");
void NetworkClientSendRcon(const char *password, const char *command);
void NetworkClientSendSettingsPassword(const char *password);
void NetworkClientSendChat(NetworkAction action, DestType type, int dest, const char *msg, NetworkTextMessageData data = NetworkTextMessageData());
void NetworkClientRequestMove(CompanyID company, const std::string &pass = "");
void NetworkClientSendRcon(const std::string &password, const char *command);
void NetworkClientSendSettingsPassword(const std::string &password);
void NetworkClientSendChat(NetworkAction action, DestType type, int dest, const std::string &msg, NetworkTextMessageData data = NetworkTextMessageData());
void NetworkClientSendDesyncMsg(const char *msg);
bool NetworkClientPreferTeamChat(const NetworkClientInfo *cio);
bool NetworkCompanyIsPassworded(CompanyID company_id);
@@ -79,7 +79,7 @@ bool NetworkServerChangeClientName(ClientID client_id, const char *new_name);
void NetworkServerDoMove(ClientID client_id, CompanyID company_id);
void NetworkServerSendRcon(ClientID client_id, TextColour colour_code, const char *string);
void NetworkServerSendChat(NetworkAction action, DestType type, int dest, const char *msg, ClientID from_id, NetworkTextMessageData data = NetworkTextMessageData(), bool from_admin = false);
void NetworkServerSendChat(NetworkAction action, DestType type, int dest, const std::string &msg, ClientID from_id, NetworkTextMessageData data = NetworkTextMessageData(), bool from_admin = false);
void NetworkServerKickClient(ClientID client_id, const char *reason);
uint NetworkServerKickOrBanIP(ClientID client_id, bool ban, const char *reason);

View File

@@ -477,7 +477,7 @@ public:
this->FinishInitNested(WN_NETWORK_WINDOW_GAME);
this->querystrings[WID_NG_CLIENT] = &this->name_editbox;
this->name_editbox.text.Assign(_settings_client.network.client_name);
this->name_editbox.text.Assign(_settings_client.network.client_name.c_str());
this->querystrings[WID_NG_FILTER] = &this->filter_editbox;
this->filter_editbox.cancel_button = QueryString::ACTION_CLEAR;
@@ -663,7 +663,7 @@ public:
DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y, STR_NETWORK_SERVER_LIST_SERVER_VERSION); // server version
y += FONT_HEIGHT_NORMAL;
SetDParamStr(0, sel->connection_string.c_str());
SetDParamStr(0, sel->connection_string);
DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y, STR_NETWORK_SERVER_LIST_SERVER_ADDRESS); // server address
y += FONT_HEIGHT_NORMAL;
@@ -835,7 +835,7 @@ public:
case WID_NG_CLIENT:
/* Validation of the name will happen once the user tries to join or start a game, as getting
* error messages while typing (e.g. when you clear the name) defeats the purpose of the check. */
strecpy(_settings_client.network.client_name, this->name_editbox.text.buf, lastof(_settings_client.network.client_name));
_settings_client.network.client_name = this->name_editbox.text.buf;
break;
}
}
@@ -843,7 +843,7 @@ public:
void OnQueryTextFinished(char *str) override
{
if (!StrEmpty(str)) {
strecpy(_settings_client.network.connect_to_ip, str, lastof(_settings_client.network.connect_to_ip));
_settings_client.network.connect_to_ip = str;
NetworkAddServer(str);
NetworkRebuildHostList();
}
@@ -1005,7 +1005,7 @@ struct NetworkStartServerWindow : public Window {
this->InitNested(WN_NETWORK_WINDOW_START);
this->querystrings[WID_NSS_GAMENAME] = &this->name_editbox;
this->name_editbox.text.Assign(_settings_client.network.server_name);
this->name_editbox.text.Assign(_settings_client.network.server_name.c_str());
this->SetFocusedWidget(WID_NSS_GAMENAME);
}
@@ -1047,7 +1047,7 @@ struct NetworkStartServerWindow : public Window {
switch (widget) {
case WID_NSS_SETPWD:
/* If password is set, draw red '*' next to 'Set password' button. */
if (!StrEmpty(_settings_client.network.server_password)) DrawString(r.right + WD_FRAMERECT_LEFT, this->width - WD_FRAMERECT_RIGHT, r.top, "*", TC_RED);
if (!_settings_client.network.server_password.empty()) DrawString(r.right + WD_FRAMERECT_LEFT, this->width - WD_FRAMERECT_RIGHT, r.top, "*", TC_RED);
}
}
@@ -1151,7 +1151,7 @@ struct NetworkStartServerWindow : public Window {
void OnEditboxChanged(int wid) override
{
if (wid == WID_NSS_GAMENAME) {
strecpy(_settings_client.network.server_name, this->name_editbox.text.buf, lastof(_settings_client.network.server_name));
_settings_client.network.server_name = this->name_editbox.text.buf;
}
}
@@ -1171,7 +1171,7 @@ struct NetworkStartServerWindow : public Window {
if (str == nullptr) return;
if (this->widget_id == WID_NSS_SETPWD) {
strecpy(_settings_client.network.server_password, str, lastof(_settings_client.network.server_password));
_settings_client.network.server_password = str;
} else {
int32 value = atoi(str);
this->SetWidgetDirty(this->widget_id);
@@ -1298,7 +1298,7 @@ struct NetworkLobbyWindow : public Window {
{
/* Scroll through all this->company_info and get the 'pos' item that is not empty. */
for (CompanyID i = COMPANY_FIRST; i < MAX_COMPANIES; i++) {
if (!StrEmpty(this->company_info[i].company_name)) {
if (!this->company_info[i].company_name.empty()) {
if (pos-- == 0) return i;
}
}
@@ -1413,7 +1413,7 @@ struct NetworkLobbyWindow : public Window {
GfxFillRect(r.left + 1, r.top + 1, r.right - 1, r.top + detail_height - 1, PC_DARK_BLUE);
DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, r.top + 12, STR_NETWORK_GAME_LOBBY_COMPANY_INFO, TC_FROMSTRING, SA_HOR_CENTER);
if (this->company == INVALID_COMPANY || StrEmpty(this->company_info[this->company].company_name)) return;
if (this->company == INVALID_COMPANY || this->company_info[this->company].company_name.empty()) return;
int y = r.top + detail_height + 4;
const NetworkGameInfo *gi = &this->server->info;
@@ -1571,7 +1571,7 @@ static void ShowNetworkLobbyWindow(NetworkGameList *ngl)
DeleteWindowById(WC_NETWORK_WINDOW, WN_NETWORK_WINDOW_START);
DeleteWindowById(WC_NETWORK_WINDOW, WN_NETWORK_WINDOW_GAME);
strecpy(_settings_client.network.last_joined, ngl->connection_string.c_str(), lastof(_settings_client.network.last_joined));
_settings_client.network.last_joined = ngl->connection_string;
NetworkQueryLobbyServer(ngl->connection_string);
@@ -2214,19 +2214,16 @@ public:
case WID_CL_SERVER_NAME_EDIT: {
if (!_network_server) break;
uint index;
GetSettingFromName("network.server_name", &index);
SetSettingValue(index, StrEmpty(str) ? "Unnamed Server" : str);
SetSettingValue(GetSettingFromName("network.server_name"), StrEmpty(str) ? "Unnamed Server" : str);
this->InvalidateData();
break;
}
case WID_CL_CLIENT_NAME_EDIT: {
if (!NetworkValidateClientName(str)) break;
std::string client_name(str);
if (!NetworkValidateClientName(client_name)) break;
uint index;
GetSettingFromName("network.client_name", &index);
SetSettingValue(index, str);
SetSettingValue(GetSettingFromName("network.client_name"), client_name.c_str());
this->InvalidateData();
break;
}
@@ -2598,7 +2595,7 @@ struct NetworkCompanyPasswordWindow : public Window {
void OnOk()
{
if (this->IsWidgetLowered(WID_NCP_SAVE_AS_DEFAULT_PASSWORD)) {
strecpy(_settings_client.network.default_company_pass, this->password_editbox.text.buf, lastof(_settings_client.network.default_company_pass));
_settings_client.network.default_company_pass = this->password_editbox.text.buf;
}
NetworkChangeCompanyPassword(_local_company, this->password_editbox.text.buf);

View File

@@ -28,14 +28,14 @@ void ShowNetworkCompanyPasswordWindow(Window *parent);
/** Company information stored at the client side */
struct NetworkCompanyInfo : NetworkCompanyStats {
char company_name[NETWORK_COMPANY_NAME_LENGTH]; ///< Company name
Year inaugurated_year; ///< What year the company started in
Money company_value; ///< The company value
Money money; ///< The amount of money the company has
Money income; ///< How much did the company earned last year
uint16 performance; ///< What was his performance last month?
bool use_password; ///< Is there a password
char clients[NETWORK_CLIENTS_LENGTH]; ///< The clients that control this company (Name1, name2, ..)
std::string company_name; ///< Company name
Year inaugurated_year; ///< What year the company started in
Money company_value; ///< The company value
Money money; ///< The amount of money the company has
Money income; ///< How much did the company earn last year
uint16 performance; ///< What was his performance last month?
bool use_password; ///< Is there a password
std::string clients; ///< The clients that control this company (Name1, name2, ..)
};
NetworkCompanyInfo *GetLobbyCompanyInfo(CompanyID company);

View File

@@ -121,11 +121,11 @@ void NetworkFreeLocalCommandQueue();
void NetworkSyncCommandQueue(NetworkClientSocket *cs);
void ShowNetworkError(StringID error_string);
void NetworkTextMessage(NetworkAction action, TextColour colour, bool self_send, const char *name, const char *str = "", NetworkTextMessageData data = NetworkTextMessageData());
void NetworkTextMessage(NetworkAction action, TextColour colour, bool self_send, const std::string &name, const std::string &str = "", NetworkTextMessageData data = NetworkTextMessageData());
uint NetworkCalculateLag(const NetworkClientSocket *cs);
StringID GetNetworkErrorMsg(NetworkErrorCode err);
bool NetworkFindName(char *new_name, const char *last);
const char *GenerateCompanyPasswordHash(const char *password, const char *password_server_id, uint32 password_game_seed);
std::string GenerateCompanyPasswordHash(const std::string &password, const std::string &password_server_id, uint32 password_game_seed);
NetworkAddress ParseConnectionString(const std::string &connection_string, uint16 default_port);
std::string NormalizeConnectionString(const std::string &connection_string, uint16 default_port);

View File

@@ -259,7 +259,7 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::CloseConnection(NetworkRecvSta
this->GetClientName(client_name, lastof(client_name));
NetworkTextMessage(NETWORK_ACTION_LEAVE, CC_DEFAULT, false, client_name, nullptr, STR_NETWORK_ERROR_CLIENT_CONNECTION_LOST);
NetworkTextMessage(NETWORK_ACTION_LEAVE, CC_DEFAULT, false, client_name, "", STR_NETWORK_ERROR_CLIENT_CONNECTION_LOST);
/* Inform other clients of this... strange leaving ;) */
for (NetworkClientSocket *new_cs : NetworkClientSocket::Iterate()) {
@@ -386,13 +386,12 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::SendCompanyInfo()
NetworkPopulateCompanyStats(company_stats);
/* Make a list of all clients per company */
char clients[MAX_COMPANIES][NETWORK_CLIENTS_LENGTH];
memset(clients, 0, sizeof(clients));
std::string clients[MAX_COMPANIES];
/* Add the local player (if not dedicated) */
const NetworkClientInfo *ci = NetworkClientInfo::GetByClientID(CLIENT_ID_SERVER);
if (ci != nullptr && Company::IsValidID(ci->client_playas)) {
strecpy(clients[ci->client_playas], ci->client_name, lastof(clients[ci->client_playas]));
clients[ci->client_playas] = ci->client_name;
}
for (NetworkClientSocket *csi : NetworkClientSocket::Iterate()) {
@@ -402,11 +401,11 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::SendCompanyInfo()
ci = csi->GetInfo();
if (ci != nullptr && Company::IsValidID(ci->client_playas)) {
if (!StrEmpty(clients[ci->client_playas])) {
strecat(clients[ci->client_playas], ", ", lastof(clients[ci->client_playas]));
if (!clients[ci->client_playas].empty()) {
clients[ci->client_playas] += ", ";
}
strecat(clients[ci->client_playas], client_name, lastof(clients[ci->client_playas]));
clients[ci->client_playas] += client_name;
}
}
@@ -421,7 +420,7 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::SendCompanyInfo()
p->Send_bool (true);
this->SendCompanyInformation(p, company, &company_stats[company->index]);
if (StrEmpty(clients[company->index])) {
if (clients[company->index].empty()) {
p->Send_string("<none>");
} else {
p->Send_string(clients[company->index]);
@@ -446,7 +445,6 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::SendCompanyInfo()
*/
NetworkRecvStatus ServerNetworkGameSocketHandler::SendError(NetworkErrorCode error, const char *reason)
{
char str[100];
Packet *p = new Packet(PACKET_SERVER_ERROR, SHRT_MAX);
p->Send_uint8(error);
@@ -454,7 +452,6 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::SendError(NetworkErrorCode err
this->SendPacket(p);
StringID strid = GetNetworkErrorMsg(error);
GetString(str, strid, lastof(str));
/* Only send when the current client was in game */
if (this->status > STATUS_AUTHORIZED) {
@@ -462,12 +459,12 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::SendError(NetworkErrorCode err
this->GetClientName(client_name, lastof(client_name));
DEBUG(net, 1, "'%s' made an error and has been disconnected: %s", client_name, str);
DEBUG(net, 1, "'%s' made an error and has been disconnected: %s", client_name, GetString(strid).c_str());
if (error == NETWORK_ERROR_KICKED && reason != nullptr) {
NetworkTextMessage(NETWORK_ACTION_KICKED, CC_DEFAULT, false, client_name, reason, strid);
} else {
NetworkTextMessage(NETWORK_ACTION_LEAVE, CC_DEFAULT, false, client_name, nullptr, strid);
NetworkTextMessage(NETWORK_ACTION_LEAVE, CC_DEFAULT, false, client_name, "", strid);
}
for (NetworkClientSocket *new_cs : NetworkClientSocket::Iterate()) {
@@ -483,10 +480,10 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::SendError(NetworkErrorCode err
NetworkAdminClientError(this->client_id, error);
} else {
DEBUG(net, 1, "Client %d made an error and has been disconnected: %s", this->client_id, str);
DEBUG(net, 1, "Client %d made an error and has been disconnected: %s", this->client_id, GetString(strid).c_str());
}
/* The client made a mistake, so drop his connection now! */
/* The client made a mistake, so drop the connection now! */
return this->CloseConnection(NETWORK_RECV_STATUS_SERVER_ERROR);
}
@@ -759,7 +756,7 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::SendCommand(const CommandPacke
* @param msg The actual message.
* @param data Arbitrary extra data.
*/
NetworkRecvStatus ServerNetworkGameSocketHandler::SendChat(NetworkAction action, ClientID client_id, bool self_send, const char *msg, NetworkTextMessageData data)
NetworkRecvStatus ServerNetworkGameSocketHandler::SendChat(NetworkAction action, ClientID client_id, bool self_send, const std::string &msg, NetworkTextMessageData data)
{
if (this->status < STATUS_PRE_ACTIVE) return NETWORK_RECV_STATUS_OKAY;
@@ -912,12 +909,12 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::Receive_CLIENT_NEWGRFS_CHECKED
NetworkClientInfo *ci = this->GetInfo();
/* We now want a password from the client else we do not allow him in! */
if (!StrEmpty(_settings_client.network.server_password)) {
/* We now want a password from the client else we do not allow them in! */
if (!_settings_client.network.server_password.empty()) {
return this->SendNeedGamePassword();
}
if (Company::IsValidID(ci->client_playas) && !StrEmpty(_network_company_states[ci->client_playas].password)) {
if (Company::IsValidID(ci->client_playas) && !_network_company_states[ci->client_playas].password.empty()) {
return this->SendNeedCompanyPassword();
}
@@ -984,7 +981,7 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::Receive_CLIENT_JOIN(Packet *p)
NetworkClientInfo *ci = new NetworkClientInfo(this->client_id);
this->SetInfo(ci);
ci->join_date = _date;
strecpy(ci->client_name, name, lastof(ci->client_name));
ci->client_name = name;
ci->client_playas = playas;
DEBUG(desync, 1, "client: date{%08x; %02x; %02x}; client: %02x; company: %02x", _date, _date_fract, _tick_skip_counter, (int)ci->index, (int)ci->client_playas);
@@ -1007,18 +1004,17 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::Receive_CLIENT_GAME_PASSWORD(P
return this->SendError(NETWORK_ERROR_NOT_EXPECTED);
}
char password[NETWORK_PASSWORD_LENGTH];
p->Recv_string(password, sizeof(password));
std::string password = p->Recv_string(NETWORK_PASSWORD_LENGTH);
/* Check game password. Allow joining if we cleared the password meanwhile */
if (!StrEmpty(_settings_client.network.server_password) &&
strcmp(password, GenerateCompanyPasswordHash(_settings_client.network.server_password, _settings_client.network.network_id, _settings_game.game_creation.generation_seed ^ this->server_hash_bits)) != 0) {
if (!_settings_client.network.server_password.empty() &&
password != GenerateCompanyPasswordHash(_settings_client.network.server_password.c_str(), _settings_client.network.network_id.c_str(), _settings_game.game_creation.generation_seed ^ this->server_hash_bits)) {
/* Password is invalid */
return this->SendError(NETWORK_ERROR_WRONG_PASSWORD);
}
const NetworkClientInfo *ci = this->GetInfo();
if (Company::IsValidID(ci->client_playas) && !StrEmpty(_network_company_states[ci->client_playas].password)) {
if (Company::IsValidID(ci->client_playas) && !_network_company_states[ci->client_playas].password.empty()) {
return this->SendNeedCompanyPassword();
}
@@ -1032,15 +1028,14 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::Receive_CLIENT_COMPANY_PASSWOR
return this->SendError(NETWORK_ERROR_NOT_EXPECTED);
}
char password[NETWORK_PASSWORD_LENGTH];
p->Recv_string(password, sizeof(password));
std::string password = p->Recv_string(NETWORK_PASSWORD_LENGTH);
/* Check company password. Allow joining if we cleared the password meanwhile.
* Also, check the company is still valid - client could be moved to spectators
* in the middle of the authorization process */
CompanyID playas = this->GetInfo()->client_playas;
if (Company::IsValidID(playas) && !StrEmpty(_network_company_states[playas].password) &&
strcmp(password, _network_company_states[playas].password) != 0) {
if (Company::IsValidID(playas) && !_network_company_states[playas].password.empty() &&
_network_company_states[playas].password.compare(password) != 0) {
/* Password is invalid */
return this->SendError(NETWORK_ERROR_WRONG_PASSWORD);
}
@@ -1062,8 +1057,8 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::Receive_CLIENT_SETTINGS_PASSWO
if (StrEmpty(password)) {
if (this->settings_authed) DEBUG(net, 0, "[settings-ctrl] client-id %d deauthed", this->client_id);
this->settings_authed = false;
} else if (StrEmpty(_settings_client.network.settings_password) ||
strcmp(password, GenerateCompanyPasswordHash(_settings_client.network.settings_password, _settings_client.network.network_id, _settings_game.game_creation.generation_seed ^ this->settings_hash_bits)) != 0) {
} else if (_settings_client.network.settings_password.empty() ||
password != GenerateCompanyPasswordHash(_settings_client.network.settings_password.c_str(), _settings_client.network.network_id.c_str(), _settings_game.game_creation.generation_seed ^ this->settings_hash_bits)) {
DEBUG(net, 0, "[settings-ctrl] wrong password from client-id %d", this->client_id);
NetworkServerSendRcon(this->client_id, CC_ERROR, "Access Denied");
this->settings_authed = false;
@@ -1078,7 +1073,7 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::Receive_CLIENT_SETTINGS_PASSWO
NetworkRecvStatus ServerNetworkGameSocketHandler::Receive_CLIENT_GETMAP(Packet *p)
{
/* The client was never joined.. so this is impossible, right?
* Ignore the packet, give the client a warning, and close his connection */
* Ignore the packet, give the client a warning, and close the connection */
if (this->status < STATUS_AUTHORIZED || this->HasClientQuit()) {
return this->SendError(NETWORK_ERROR_NOT_AUTHORIZED);
}
@@ -1106,7 +1101,7 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::Receive_CLIENT_MAP_OK(Packet *
this->GetClientName(client_name, lastof(client_name));
NetworkTextMessage(NETWORK_ACTION_JOIN, CC_DEFAULT, false, client_name, nullptr, this->client_id);
NetworkTextMessage(NETWORK_ACTION_JOIN, CC_DEFAULT, false, client_name, "", this->client_id);
InvalidateWindowData(WC_CLIENT_LIST, 0);
/* Mark the client as pre-active, and wait for an ACK
@@ -1148,7 +1143,7 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::Receive_CLIENT_MAP_OK(Packet *
NetworkRecvStatus ServerNetworkGameSocketHandler::Receive_CLIENT_COMMAND(Packet *p)
{
/* The client was never joined.. so this is impossible, right?
* Ignore the packet, give the client a warning, and close his connection */
* Ignore the packet, give the client a warning, and close the connection */
if (this->status < STATUS_DONE_MAP || this->HasClientQuit()) {
return this->SendError(NETWORK_ERROR_NOT_EXPECTED);
}
@@ -1214,7 +1209,6 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::Receive_CLIENT_ERROR(Packet *p
{
/* This packets means a client noticed an error and is reporting this
* to us. Display the error and report it to the other clients */
char str[100];
char client_name[NETWORK_CLIENT_NAME_LENGTH];
NetworkErrorCode errorno = (NetworkErrorCode)p->Recv_uint8();
NetworkRecvStatus rx_status = p->CanReadFromPacket(1) ? (NetworkRecvStatus)p->Recv_uint8() : NETWORK_RECV_STATUS_OKAY;
@@ -1223,19 +1217,17 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::Receive_CLIENT_ERROR(Packet *p
/* The client was never joined.. thank the client for the packet, but ignore it */
if (this->status < STATUS_DONE_MAP || this->HasClientQuit()) {
if (_debug_net_level >= 2) GetString(str, GetNetworkErrorMsg(errorno), lastof(str));
DEBUG(net, 2, "non-joined client %d reported an error and is closing its connection (%s) (%d, %d, %d)", this->client_id, str, rx_status, status, last_pkt_type);
DEBUG(net, 2, "non-joined client %d reported an error and is closing its connection (%s) (%d, %d, %d)", this->client_id, GetString(GetNetworkErrorMsg(errorno)).c_str(), rx_status, status, last_pkt_type);
return this->CloseConnection(NETWORK_RECV_STATUS_CLIENT_QUIT);
}
this->GetClientName(client_name, lastof(client_name));
StringID strid = GetNetworkErrorMsg(errorno);
GetString(str, strid, lastof(str));
DEBUG(net, 1, "'%s' reported an error and is closing its connection (%s) (%d, %d, %d)", client_name, str, rx_status, status, last_pkt_type);
DEBUG(net, 1, "'%s' reported an error and is closing its connection (%s) (%d, %d, %d)", client_name, GetString(strid).c_str(), rx_status, status, last_pkt_type);
NetworkTextMessage(NETWORK_ACTION_LEAVE, CC_DEFAULT, false, client_name, nullptr, strid);
NetworkTextMessage(NETWORK_ACTION_LEAVE, CC_DEFAULT, false, client_name, "", strid);
for (NetworkClientSocket *new_cs : NetworkClientSocket::Iterate()) {
if (new_cs->status >= STATUS_AUTHORIZED) {
@@ -1301,7 +1293,7 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::Receive_CLIENT_QUIT(Packet *p)
this->GetClientName(client_name, lastof(client_name));
NetworkTextMessage(NETWORK_ACTION_LEAVE, CC_DEFAULT, false, client_name, nullptr, STR_NETWORK_MESSAGE_CLIENT_LEAVING);
NetworkTextMessage(NETWORK_ACTION_LEAVE, CC_DEFAULT, false, client_name, "", STR_NETWORK_MESSAGE_CLIENT_LEAVING);
for (NetworkClientSocket *new_cs : NetworkClientSocket::Iterate()) {
if (new_cs->status >= STATUS_AUTHORIZED && new_cs != this) {
@@ -1370,7 +1362,7 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::Receive_CLIENT_ACK(Packet *p)
* @param data Arbitrary data.
* @param from_admin Whether the origin is an admin or not.
*/
void NetworkServerSendChat(NetworkAction action, DestType desttype, int dest, const char *msg, ClientID from_id, NetworkTextMessageData data, bool from_admin)
void NetworkServerSendChat(NetworkAction action, DestType desttype, int dest, const std::string &msg, ClientID from_id, NetworkTextMessageData data, bool from_admin)
{
const NetworkClientInfo *ci, *ci_own, *ci_to;
@@ -1448,10 +1440,9 @@ void NetworkServerSendChat(NetworkAction action, DestType desttype, int dest, co
/* Display the message locally (so you know you have sent it) */
if (ci != nullptr && show_local) {
if (from_id == CLIENT_ID_SERVER) {
char name[NETWORK_NAME_LENGTH];
StringID str = Company::IsValidID(ci_to->client_playas) ? STR_COMPANY_NAME : STR_NETWORK_SPECTATORS;
SetDParam(0, ci_to->client_playas);
GetString(name, str, lastof(name));
std::string name = GetString(str);
NetworkTextMessage(action, GetDrawStringCompanyColour(ci_own->client_playas), true, name, msg, data);
} else {
for (NetworkClientSocket *cs : NetworkClientSocket::Iterate()) {
@@ -1494,9 +1485,8 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::Receive_CLIENT_CHAT(Packet *p)
NetworkAction action = (NetworkAction)p->Recv_uint8();
DestType desttype = (DestType)p->Recv_uint8();
int dest = p->Recv_uint32();
char msg[NETWORK_CHAT_LENGTH];
p->Recv_string(msg, NETWORK_CHAT_LENGTH);
std::string msg = p->Recv_string(NETWORK_CHAT_LENGTH);
NetworkTextMessageData data;
data.recv(p);
@@ -1524,11 +1514,8 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::Receive_CLIENT_SET_PASSWORD(Pa
return this->SendError(NETWORK_ERROR_NOT_EXPECTED);
}
char password[NETWORK_PASSWORD_LENGTH];
const NetworkClientInfo *ci;
p->Recv_string(password, sizeof(password));
ci = this->GetInfo();
std::string password = p->Recv_string(NETWORK_PASSWORD_LENGTH);
const NetworkClientInfo *ci = this->GetInfo();
NetworkServerSetCompanyPassword(ci->client_playas, password);
return NETWORK_RECV_STATUS_OKAY;
@@ -1560,7 +1547,7 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::Receive_CLIENT_SET_NAME(Packet
/* Display change */
if (NetworkFindName(client_name, lastof(client_name))) {
NetworkTextMessage(NETWORK_ACTION_NAME_CHANGE, CC_DEFAULT, false, ci->client_name, client_name);
strecpy(ci->client_name, client_name, lastof(ci->client_name));
ci->client_name = client_name;
NetworkUpdateClientInfo(ci->client_id);
}
}
@@ -1571,18 +1558,17 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::Receive_CLIENT_RCON(Packet *p)
{
if (this->status != STATUS_ACTIVE) return this->SendError(NETWORK_ERROR_NOT_EXPECTED);
char pass[NETWORK_PASSWORD_LENGTH];
char command[NETWORK_RCONCOMMAND_LENGTH];
if (StrEmpty(_settings_client.network.rcon_password)) {
if (_settings_client.network.rcon_password.empty()) {
NetworkServerSendRcon(this->client_id, CC_ERROR, "Access Denied");
return NETWORK_RECV_STATUS_OKAY;
}
p->Recv_string(pass, sizeof(pass));
std::string password = p->Recv_string(NETWORK_PASSWORD_LENGTH);
p->Recv_string(command, sizeof(command));
if (strcmp(pass, GenerateCompanyPasswordHash(_settings_client.network.rcon_password, _settings_client.network.network_id, _settings_game.game_creation.generation_seed ^ this->rcon_hash_bits)) != 0) {
if (password != GenerateCompanyPasswordHash(_settings_client.network.rcon_password.c_str(), _settings_client.network.network_id.c_str(), _settings_game.game_creation.generation_seed ^ this->rcon_hash_bits)) {
DEBUG(net, 0, "[rcon] wrong password from client-id %d", this->client_id);
NetworkServerSendRcon(this->client_id, CC_ERROR, "Access Denied");
return NETWORK_RECV_STATUS_OKAY;
@@ -1606,13 +1592,12 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::Receive_CLIENT_MOVE(Packet *p)
if (company_id != COMPANY_SPECTATOR && !Company::IsValidHumanID(company_id)) return NETWORK_RECV_STATUS_OKAY;
/* Check if we require a password for this company */
if (company_id != COMPANY_SPECTATOR && !StrEmpty(_network_company_states[company_id].password)) {
if (company_id != COMPANY_SPECTATOR && !_network_company_states[company_id].password.empty()) {
/* we need a password from the client - should be in this packet */
char password[NETWORK_PASSWORD_LENGTH];
p->Recv_string(password, sizeof(password));
std::string password = p->Recv_string(NETWORK_PASSWORD_LENGTH);
/* Incorrect password sent, return! */
if (strcmp(password, _network_company_states[company_id].password) != 0) {
if (_network_company_states[company_id].password.compare(password) != 0) {
DEBUG(net, 2, "Wrong password from client-id #%d for company #%d", this->client_id, company_id + 1);
return NETWORK_RECV_STATUS_OKAY;
}
@@ -1686,7 +1671,7 @@ void NetworkSocketHandler::SendCompanyInformation(Packet *p, const Company *c, c
p->Send_uint16(c->old_economy[0].performance_history);
/* Send 1 if there is a password for the company else send 0 */
p->Send_bool (!StrEmpty(_network_company_states[c->index].password));
p->Send_bool (!_network_company_states[c->index].password.empty());
for (uint i = 0; i < NETWORK_VEH_END; i++) {
p->Send_uint16(stats->num_vehicle[i]);
@@ -1823,15 +1808,15 @@ static void NetworkAutoCleanCompanies()
_network_company_states[c->index].months_empty++;
/* Is the company empty for autoclean_unprotected-months, and is there no protection? */
if (_settings_client.network.autoclean_unprotected != 0 && _network_company_states[c->index].months_empty > _settings_client.network.autoclean_unprotected && StrEmpty(_network_company_states[c->index].password)) {
if (_settings_client.network.autoclean_unprotected != 0 && _network_company_states[c->index].months_empty > _settings_client.network.autoclean_unprotected && _network_company_states[c->index].password.empty()) {
/* Shut the company down */
DoCommandP(0, CCA_DELETE | c->index << 16 | CRR_AUTOCLEAN << 24, 0, CMD_COMPANY_CTRL);
IConsolePrintF(CC_DEFAULT, "Auto-cleaned company #%d with no password", c->index + 1);
}
/* Is the company empty for autoclean_protected-months, and there is a protection? */
if (_settings_client.network.autoclean_protected != 0 && _network_company_states[c->index].months_empty > _settings_client.network.autoclean_protected && !StrEmpty(_network_company_states[c->index].password)) {
if (_settings_client.network.autoclean_protected != 0 && _network_company_states[c->index].months_empty > _settings_client.network.autoclean_protected && !_network_company_states[c->index].password.empty()) {
/* Unprotect the company */
_network_company_states[c->index].password[0] = '\0';
_network_company_states[c->index].password.clear();
IConsolePrintF(CC_DEFAULT, "Auto-removed protection from company #%d", c->index + 1);
_network_company_states[c->index].months_empty = 0;
NetworkServerUpdateCompanyPassworded(c->index, false);
@@ -1866,7 +1851,7 @@ bool NetworkFindName(char *new_name, const char *last)
while (!found_name) {
found_name = true;
for (const NetworkClientInfo *ci : NetworkClientInfo::Iterate()) {
if (strcmp(ci->client_name, new_name) == 0) {
if (ci->client_name.compare(new_name) == 0) {
/* Name already in use */
found_name = false;
break;
@@ -1875,7 +1860,7 @@ bool NetworkFindName(char *new_name, const char *last)
/* Check if it is the same as the server-name */
const NetworkClientInfo *ci = NetworkClientInfo::GetByClientID(CLIENT_ID_SERVER);
if (ci != nullptr) {
if (strcmp(ci->client_name, new_name) == 0) found_name = false; // name already in use
if (ci->client_name.compare(new_name) == 0) found_name = false; // name already in use
}
if (!found_name) {
@@ -1900,7 +1885,7 @@ bool NetworkServerChangeClientName(ClientID client_id, const char *new_name)
{
/* Check if the name's already in use */
for (NetworkClientInfo *ci : NetworkClientInfo::Iterate()) {
if (strcmp(ci->client_name, new_name) == 0) return false;
if (ci->client_name.compare(new_name) == 0) return false;
}
NetworkClientInfo *ci = NetworkClientInfo::GetByClientID(client_id);
@@ -1908,7 +1893,7 @@ bool NetworkServerChangeClientName(ClientID client_id, const char *new_name)
NetworkTextMessage(NETWORK_ACTION_NAME_CHANGE, CC_DEFAULT, true, ci->client_name, new_name);
strecpy(ci->client_name, new_name, lastof(ci->client_name));
ci->client_name = new_name;
NetworkUpdateClientInfo(client_id);
return true;
@@ -1920,16 +1905,17 @@ bool NetworkServerChangeClientName(ClientID client_id, const char *new_name)
* @param password The new password.
* @param already_hashed Is the given password already hashed?
*/
void NetworkServerSetCompanyPassword(CompanyID company_id, const char *password, bool already_hashed)
void NetworkServerSetCompanyPassword(CompanyID company_id, const std::string &password, bool already_hashed)
{
if (!Company::IsValidHumanID(company_id)) return;
if (!already_hashed) {
password = GenerateCompanyPasswordHash(password, _settings_client.network.network_id, _settings_game.game_creation.generation_seed);
if (already_hashed) {
_network_company_states[company_id].password = password;
} else {
_network_company_states[company_id].password = GenerateCompanyPasswordHash(password, _settings_client.network.network_id, _settings_game.game_creation.generation_seed);
}
strecpy(_network_company_states[company_id].password, password, lastof(_network_company_states[company_id].password));
NetworkServerUpdateCompanyPassworded(company_id, !StrEmpty(_network_company_states[company_id].password));
NetworkServerUpdateCompanyPassworded(company_id, !_network_company_states[company_id].password.empty());
}
/**
@@ -2025,7 +2011,7 @@ void NetworkServer_Tick(bool send_frame)
* spamming the client. Strictly speaking this variable
* tracks when we last received a packet from the client,
* but as it is waiting, it will not send us any till we
* start sending him data. */
* start sending them data. */
cs->last_packet = std::chrono::steady_clock::now();
}
break;
@@ -2144,7 +2130,7 @@ void NetworkServerShowStatusToConsole()
status = (cs->status < (ptrdiff_t)lengthof(stat_str) ? stat_str[cs->status] : "unknown");
IConsolePrintF(CC_INFO, "Client #%1d name: '%s' status: '%s' frame-lag: %3d company: %1d IP: %s",
cs->client_id, ci->client_name, status, lag,
cs->client_id, ci->client_name.c_str(), status, lag,
ci->client_playas + (Company::IsValidID(ci->client_playas) ? 1 : 0),
cs->GetClientIP());
}
@@ -2316,10 +2302,10 @@ void ServerNetworkGameSocketHandler::GetClientName(char *client_name, const char
{
const NetworkClientInfo *ci = this->GetInfo();
if (ci == nullptr || StrEmpty(ci->client_name)) {
if (ci == nullptr || ci->client_name.empty()) {
seprintf(client_name, last, "Client #%4d", this->client_id);
} else {
strecpy(client_name, ci->client_name, last);
strecpy(client_name, ci->client_name.c_str(), last);
}
}
@@ -2332,13 +2318,13 @@ void NetworkPrintClients()
if (_network_server) {
IConsolePrintF(CC_INFO, "Client #%1d name: '%s' company: %1d IP: %s",
ci->client_id,
ci->client_name,
ci->client_name.c_str(),
ci->client_playas + (Company::IsValidID(ci->client_playas) ? 1 : 0),
ci->client_id == CLIENT_ID_SERVER ? "server" : NetworkClientSocket::GetByClientID(ci->client_id)->GetClientIP());
} else {
IConsolePrintF(CC_INFO, "Client #%1d name: '%s' company: %1d",
ci->client_id,
ci->client_name,
ci->client_name.c_str(),
ci->client_playas + (Company::IsValidID(ci->client_playas) ? 1 : 0));
}
}
@@ -2356,14 +2342,14 @@ void NetworkServerNewCompany(const Company *c, NetworkClientInfo *ci)
if (!_network_server) return;
_network_company_states[c->index].months_empty = 0;
_network_company_states[c->index].password[0] = '\0';
_network_company_states[c->index].password.clear();
NetworkServerUpdateCompanyPassworded(c->index, false);
if (ci != nullptr) {
/* ci is nullptr when replaying, or for AIs. In neither case there is a client. */
ci->client_playas = c->index;
NetworkUpdateClientInfo(ci->client_id);
NetworkSendCommand(0, 0, 0, 0, CMD_RENAME_PRESIDENT, nullptr, ci->client_name, c->index, 0);
NetworkSendCommand(0, 0, 0, 0, CMD_RENAME_PRESIDENT, nullptr, ci->client_name.c_str(), c->index, 0);
}
/* Announce new company on network. */

View File

@@ -109,7 +109,7 @@ public:
NetworkRecvStatus SendClientInfo(NetworkClientInfo *ci);
NetworkRecvStatus SendError(NetworkErrorCode error, const char *reason = nullptr);
NetworkRecvStatus SendDesyncLog(const std::string &log);
NetworkRecvStatus SendChat(NetworkAction action, ClientID client_id, bool self_send, const char *msg, NetworkTextMessageData data);
NetworkRecvStatus SendChat(NetworkAction action, ClientID client_id, bool self_send, const std::string &msg, NetworkTextMessageData data);
NetworkRecvStatus SendJoin(ClientID client_id);
NetworkRecvStatus SendFrame();
NetworkRecvStatus SendSync();
@@ -139,7 +139,7 @@ public:
};
void NetworkServer_Tick(bool send_frame);
void NetworkServerSetCompanyPassword(CompanyID company_id, const char *password, bool already_hashed = true);
void NetworkServerSetCompanyPassword(CompanyID company_id, const std::string &password, bool already_hashed = true);
void NetworkServerUpdateCompanyPassworded(CompanyID company_id, bool passworded);
#endif /* NETWORK_SERVER_H */

View File

@@ -62,8 +62,8 @@ struct NetworkCompanyStats {
/** Some state information of a company, especially for servers */
struct NetworkCompanyState {
char password[NETWORK_PASSWORD_LENGTH]; ///< The password for the company
uint16 months_empty; ///< How many months the company is empty
std::string password; ///< The password for the company
uint16 months_empty; ///< How many months the company is empty
};
struct NetworkClientInfo;

View File

@@ -64,10 +64,10 @@ struct UDPSocket {
UDPSocket(const std::string &name_) : name(name_), socket(nullptr) {}
void Close()
void CloseSocket()
{
std::lock_guard<std::mutex> lock(mutex);
socket->Close();
socket->CloseSocket();
delete socket;
socket = nullptr;
}
@@ -715,9 +715,9 @@ void NetworkUDPServerListen()
/** Close all UDP related stuff. */
void NetworkUDPClose()
{
_udp_client.Close();
_udp_server.Close();
_udp_master.Close();
_udp_client.CloseSocket();
_udp_server.CloseSocket();
_udp_master.CloseSocket();
_network_udp_server = false;
_network_udp_broadcast = 0;