Merge branch 'master' into jgrpp-beta

# Conflicts:
#	src/cargopacket.h
#	src/lang/korean.txt
#	src/linkgraph/linkgraph.h
#	src/linkgraph/linkgraphjob.h
#	src/linkgraph/linkgraphschedule.h
#	src/network/network_admin.h
#	src/network/network_func.h
#	src/network/network_server.cpp
#	src/network/network_server.h
#	src/order_base.h
#	src/rail_cmd.cpp
#	src/saveload/company_sl.cpp
#	src/saveload/depot_sl.cpp
#	src/saveload/economy_sl.cpp
#	src/saveload/linkgraph_sl.cpp
#	src/saveload/map_sl.cpp
#	src/saveload/newgrf_sl.cpp
#	src/saveload/order_sl.cpp
#	src/saveload/saveload.cpp
#	src/saveload/saveload.h
#	src/saveload/signs_sl.cpp
#	src/saveload/station_sl.cpp
#	src/saveload/subsidy_sl.cpp
#	src/saveload/town_sl.cpp
#	src/saveload/vehicle_sl.cpp
#	src/script/api/script_object.cpp
#	src/settings.cpp
#	src/string.cpp
#	src/string_func.h
#	src/table/CMakeLists.txt
#	src/table/settings/settings.ini
#	src/viewport_sprite_sorter_sse4.cpp
This commit is contained in:
Jonathan G Rennison
2021-10-18 18:01:27 +01:00
113 changed files with 721 additions and 755 deletions

View File

@@ -401,7 +401,7 @@ void Packet::Recv_string(char *buffer, size_t size, StringValidationSettings set
assert(pos <= std::numeric_limits<PacketSize>::max());
this->pos = static_cast<PacketSize>(pos);
str_validate(bufp, last, settings);
StrMakeValidInPlace(bufp, last, settings);
}
/**
@@ -430,7 +430,7 @@ std::string Packet::Recv_string(size_t length, StringValidationSettings settings
while (this->Recv_uint8() != '\0') {}
}
return str_validate(str, settings);
return StrMakeValid(str, settings);
}
/**
@@ -455,7 +455,7 @@ void Packet::Recv_string(std::string &buffer, StringValidationSettings settings)
size_t length = ttd_strnlen((const char *)(this->buffer.data() + this->pos), this->Size() - this->pos - 1);
buffer.assign((const char *)(this->buffer.data() + this->pos), length);
this->pos += (uint)length + 1;
str_validate_inplace(buffer, settings);
StrMakeValidInPlace(buffer, settings);
}
/**

View File

@@ -30,8 +30,6 @@ static_assert((int)CRR_END == (int)ADMIN_CRR_END);
NetworkAdminSocketHandler::NetworkAdminSocketHandler(SOCKET s) : status(ADMIN_STATUS_INACTIVE)
{
this->sock = s;
this->admin_name[0] = '\0';
this->admin_version[0] = '\0';
}
NetworkRecvStatus NetworkAdminSocketHandler::CloseConnection(bool error)
@@ -89,9 +87,9 @@ NetworkRecvStatus NetworkAdminSocketHandler::HandlePacket(Packet *p)
default:
if (this->HasClientQuit()) {
DEBUG(net, 0, "[tcp/admin] Received invalid packet type %d from '%s' (%s)", type, this->admin_name, this->admin_version);
DEBUG(net, 0, "[tcp/admin] Received invalid packet type %d from '%s' (%s)", type, this->admin_name.c_str(), this->admin_version.c_str());
} else {
DEBUG(net, 0, "[tcp/admin] Received illegal packet from '%s' (%s)", this->admin_name, this->admin_version);
DEBUG(net, 0, "[tcp/admin] Received illegal packet from '%s' (%s)", this->admin_name.c_str(), this->admin_version.c_str());
}
this->CloseConnection();
@@ -124,7 +122,7 @@ NetworkRecvStatus NetworkAdminSocketHandler::ReceivePackets()
*/
NetworkRecvStatus NetworkAdminSocketHandler::ReceiveInvalidPacket(PacketAdminType type)
{
DEBUG(net, 0, "[tcp/admin] Received illegal packet type %d from admin %s (%s)", type, this->admin_name, this->admin_version);
DEBUG(net, 0, "[tcp/admin] Received illegal packet type %d from admin %s (%s)", type, this->admin_name.c_str(), this->admin_version.c_str());
return NETWORK_RECV_STATUS_MALFORMED_PACKET;
}

View File

@@ -109,9 +109,9 @@ enum AdminCompanyRemoveReason {
/** Main socket handler for admin related connections. */
class NetworkAdminSocketHandler : public NetworkTCPSocketHandler {
protected:
char admin_name[NETWORK_CLIENT_NAME_LENGTH]; ///< Name of the admin.
char admin_version[NETWORK_REVISION_LENGTH]; ///< Version string of the admin.
AdminStatus status; ///< Status of this admin.
std::string admin_name; ///< Name of the admin.
std::string admin_version; ///< Version string of the admin.
AdminStatus status; ///< Status of this admin.
NetworkRecvStatus ReceiveInvalidPacket(PacketAdminType type);

View File

@@ -74,7 +74,7 @@ ServerNetworkAdminSocketHandler::ServerNetworkAdminSocketHandler(SOCKET s) : Net
ServerNetworkAdminSocketHandler::~ServerNetworkAdminSocketHandler()
{
_network_admins_connected--;
DEBUG(net, 3, "[admin] '%s' (%s) has disconnected", this->admin_name, this->admin_version);
DEBUG(net, 3, "[admin] '%s' (%s) has disconnected", this->admin_name.c_str(), this->admin_version.c_str());
if (_redirect_console_to_admin == this->index) _redirect_console_to_admin = INVALID_ADMIN_ID;
if (this->update_frequency[ADMIN_UPDATE_CONSOLE] & ADMIN_FREQUENCY_AUTOMATIC) {
@@ -140,7 +140,7 @@ NetworkRecvStatus ServerNetworkAdminSocketHandler::SendError(NetworkErrorCode er
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, error_message.c_str());
DEBUG(net, 1, "[admin] The admin '%s' (%s) made an error and has been disconnected: '%s'", this->admin_name.c_str(), this->admin_version.c_str(), error_message.c_str());
return this->CloseConnection(true);
}
@@ -473,7 +473,7 @@ NetworkRecvStatus ServerNetworkAdminSocketHandler::SendChat(NetworkAction action
* Send a notification indicating the rcon command has completed.
* @param command The original command sent.
*/
NetworkRecvStatus ServerNetworkAdminSocketHandler::SendRconEnd(const char *command)
NetworkRecvStatus ServerNetworkAdminSocketHandler::SendRconEnd(const std::string_view command)
{
Packet *p = new Packet(ADMIN_PACKET_SERVER_RCON_END);
@@ -488,7 +488,7 @@ NetworkRecvStatus ServerNetworkAdminSocketHandler::SendRconEnd(const char *comma
* @param colour The colour of the text.
* @param result The result of the command.
*/
NetworkRecvStatus ServerNetworkAdminSocketHandler::SendRcon(uint16 colour, const char *result)
NetworkRecvStatus ServerNetworkAdminSocketHandler::SendRcon(uint16 colour, const std::string_view result)
{
Packet *p = new Packet(ADMIN_PACKET_SERVER_RCON);
@@ -503,14 +503,12 @@ NetworkRecvStatus ServerNetworkAdminSocketHandler::Receive_ADMIN_RCON(Packet *p)
{
if (this->status == ADMIN_STATUS_INACTIVE) return this->SendError(NETWORK_ERROR_NOT_EXPECTED);
char command[NETWORK_RCONCOMMAND_LENGTH];
std::string command = p->Recv_string(NETWORK_RCONCOMMAND_LENGTH);
p->Recv_string(command, sizeof(command));
DEBUG(net, 3, "[admin] Rcon command from '%s' (%s): %s", this->admin_name, this->admin_version, command);
DEBUG(net, 3, "[admin] Rcon command from '%s' (%s): %s", this->admin_name.c_str(), this->admin_version.c_str(), command.c_str());
_redirect_console_to_admin = this->index;
IConsoleCmdExec(command);
IConsoleCmdExec(command.c_str());
_redirect_console_to_admin = INVALID_ADMIN_ID;
return this->SendRconEnd(command);
}
@@ -519,11 +517,9 @@ NetworkRecvStatus ServerNetworkAdminSocketHandler::Receive_ADMIN_GAMESCRIPT(Pack
{
if (this->status == ADMIN_STATUS_INACTIVE) return this->SendError(NETWORK_ERROR_NOT_EXPECTED);
char json[NETWORK_GAMESCRIPT_JSON_LENGTH];
std::string json = p->Recv_string(NETWORK_GAMESCRIPT_JSON_LENGTH);
p->Recv_string(json, sizeof(json));
DEBUG(net, 6, "[admin] GameScript JSON from '%s' (%s): %s", this->admin_name, this->admin_version, json);
DEBUG(net, 6, "[admin] GameScript JSON from '%s' (%s): %s", this->admin_name.c_str(), this->admin_version.c_str(), json.c_str());
Game::NewEvent(new ScriptEventAdminPort(json));
return NETWORK_RECV_STATUS_OKAY;
@@ -535,7 +531,7 @@ NetworkRecvStatus ServerNetworkAdminSocketHandler::Receive_ADMIN_PING(Packet *p)
uint32 d1 = p->Recv_uint32();
DEBUG(net, 6, "[admin] Ping from '%s' (%s): %d", this->admin_name, this->admin_version, d1);
DEBUG(net, 6, "[admin] Ping from '%s' (%s): %d", this->admin_name.c_str(), this->admin_version.c_str(), d1);
return this->SendPong(d1);
}
@@ -545,13 +541,13 @@ NetworkRecvStatus ServerNetworkAdminSocketHandler::Receive_ADMIN_PING(Packet *p)
* @param origin The origin of the string.
* @param string The string that's put on the console.
*/
NetworkRecvStatus ServerNetworkAdminSocketHandler::SendConsole(const char *origin, const char *string)
NetworkRecvStatus ServerNetworkAdminSocketHandler::SendConsole(const std::string_view origin, const std::string_view string)
{
/* If the length of both strings, plus the 2 '\0' terminations and 3 bytes of the packet
* are bigger than the MTU, just ignore the message. Better safe than sorry. It should
* never occur though as the longest strings are chat messages, which are still 30%
* smaller than COMPAT_MTU. */
if (strlen(origin) + strlen(string) + 2 + 3 >= COMPAT_MTU) return NETWORK_RECV_STATUS_OKAY;
if (origin.size() + string.size() + 2 + 3 >= COMPAT_MTU) return NETWORK_RECV_STATUS_OKAY;
Packet *p = new Packet(ADMIN_PACKET_SERVER_CONSOLE);
@@ -566,12 +562,12 @@ NetworkRecvStatus ServerNetworkAdminSocketHandler::SendConsole(const char *origi
* Send GameScript JSON output.
* @param json The JSON string.
*/
NetworkRecvStatus ServerNetworkAdminSocketHandler::SendGameScript(const char *json)
NetworkRecvStatus ServerNetworkAdminSocketHandler::SendGameScript(const std::string_view json)
{
/* At the moment we cannot transmit anything larger than MTU. So we limit
* the maximum amount of json data that can be sent. Account also for
* the trailing \0 of the string */
if (strlen(json) + 1 >= NETWORK_GAMESCRIPT_JSON_LENGTH) return NETWORK_RECV_STATUS_OKAY;
if (json.size() + 1 >= NETWORK_GAMESCRIPT_JSON_LENGTH) return NETWORK_RECV_STATUS_OKAY;
Packet *p = new Packet(ADMIN_PACKET_SERVER_GAMESCRIPT);
@@ -661,17 +657,17 @@ NetworkRecvStatus ServerNetworkAdminSocketHandler::Receive_ADMIN_JOIN(Packet *p)
return this->SendError(NETWORK_ERROR_WRONG_PASSWORD);
}
p->Recv_string(this->admin_name, sizeof(this->admin_name));
p->Recv_string(this->admin_version, sizeof(this->admin_version));
this->admin_name = p->Recv_string(NETWORK_CLIENT_NAME_LENGTH);
this->admin_version = p->Recv_string(NETWORK_REVISION_LENGTH);
if (StrEmpty(this->admin_name) || StrEmpty(this->admin_version)) {
if (this->admin_name.empty() || this->admin_version.empty()) {
/* no name or version supplied */
return this->SendError(NETWORK_ERROR_ILLEGAL_PACKET);
}
this->status = ADMIN_STATUS_ACTIVE;
DEBUG(net, 3, "[admin] '%s' (%s) has connected", this->admin_name, this->admin_version);
DEBUG(net, 3, "[admin] '%s' (%s) has connected", this->admin_name.c_str(), this->admin_version.c_str());
return this->SendProtocol();
}
@@ -691,7 +687,7 @@ NetworkRecvStatus ServerNetworkAdminSocketHandler::Receive_ADMIN_UPDATE_FREQUENC
if (type >= ADMIN_UPDATE_END || (_admin_update_type_frequencies[type] & freq) != freq) {
/* The server does not know of this UpdateType. */
DEBUG(net, 1, "[admin] Not supported update frequency %d (%d) from '%s' (%s)", type, freq, this->admin_name, this->admin_version);
DEBUG(net, 1, "[admin] Not supported update frequency %d (%d) from '%s' (%s)", type, freq, this->admin_name.c_str(), this->admin_version.c_str());
return this->SendError(NETWORK_ERROR_ILLEGAL_PACKET);
}
@@ -761,7 +757,7 @@ NetworkRecvStatus ServerNetworkAdminSocketHandler::Receive_ADMIN_POLL(Packet *p)
default:
/* An unsupported "poll" update type. */
DEBUG(net, 1, "[admin] Not supported poll %d (%d) from '%s' (%s).", type, d1, this->admin_name, this->admin_version);
DEBUG(net, 1, "[admin] Not supported poll %d (%d) from '%s' (%s).", type, d1, this->admin_name.c_str(), this->admin_version.c_str());
return this->SendError(NETWORK_ERROR_ILLEGAL_PACKET);
}
@@ -787,7 +783,7 @@ NetworkRecvStatus ServerNetworkAdminSocketHandler::Receive_ADMIN_CHAT(Packet *p)
break;
default:
DEBUG(net, 1, "[admin] Invalid chat action %d from admin '%s' (%s).", action, this->admin_name, this->admin_version);
DEBUG(net, 1, "[admin] Invalid chat action %d from admin '%s' (%s).", action, this->admin_name.c_str(), this->admin_version.c_str());
return this->SendError(NETWORK_ERROR_ILLEGAL_PACKET);
}
@@ -925,7 +921,7 @@ void NetworkAdminChat(NetworkAction action, DestType desttype, ClientID client_i
* @param colour_code The colour of the string.
* @param string The string to show.
*/
void NetworkServerSendAdminRcon(AdminIndex admin_index, TextColour colour_code, const char *string)
void NetworkServerSendAdminRcon(AdminIndex admin_index, TextColour colour_code, const std::string_view string)
{
ServerNetworkAdminSocketHandler::Get(admin_index)->SendRcon(colour_code, string);
}
@@ -935,7 +931,7 @@ void NetworkServerSendAdminRcon(AdminIndex admin_index, TextColour colour_code,
* @param origin the origin of the message.
* @param string the message as printed on the console.
*/
void NetworkAdminConsole(const char *origin, const char *string)
void NetworkAdminConsole(const std::string_view origin, const std::string_view string)
{
for (ServerNetworkAdminSocketHandler *as : ServerNetworkAdminSocketHandler::IterateActive()) {
if (as->update_frequency[ADMIN_UPDATE_CONSOLE] & ADMIN_FREQUENCY_AUTOMATIC) {
@@ -948,7 +944,7 @@ void NetworkAdminConsole(const char *origin, const char *string)
* Send GameScript JSON to the admin network (if they did opt in for the respective update).
* @param json The JSON data as received from the GameScript.
*/
void NetworkAdminGameScript(const char *json)
void NetworkAdminGameScript(const std::string_view json)
{
for (ServerNetworkAdminSocketHandler *as : ServerNetworkAdminSocketHandler::IterateActive()) {
if (as->update_frequency[ADMIN_UPDATE_GAMESCRIPT] & ADMIN_FREQUENCY_AUTOMATIC) {

View File

@@ -62,12 +62,12 @@ public:
NetworkRecvStatus SendCompanyStats();
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);
NetworkRecvStatus SendRcon(uint16 colour, const std::string_view command);
NetworkRecvStatus SendConsole(const std::string_view origin, const std::string_view command);
NetworkRecvStatus SendGameScript(const std::string_view json);
NetworkRecvStatus SendCmdNames();
NetworkRecvStatus SendCmdLogging(ClientID client_id, const CommandPacket *cp);
NetworkRecvStatus SendRconEnd(const char *command);
NetworkRecvStatus SendRconEnd(const std::string_view command);
static void Send();
static void AcceptConnection(SOCKET s, const NetworkAddress &address);
@@ -108,9 +108,9 @@ void NetworkAdminCompanyRemove(CompanyID company_id, AdminCompanyRemoveReason bc
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);
void NetworkAdminGameScript(const char *json);
void NetworkServerSendAdminRcon(AdminIndex admin_index, TextColour colour_code, const std::string_view string);
void NetworkAdminConsole(const std::string_view origin, const std::string_view string);
void NetworkAdminGameScript(const std::string_view json);
void NetworkAdminCmdLogging(const NetworkClientSocket *owner, const CommandPacket *cp);
#endif /* NETWORK_ADMIN_H */

View File

@@ -612,7 +612,7 @@ NetworkRecvStatus ClientNetworkGameSocketHandler::SendSetPassword(const std::str
* Tell the server that we like to change the name of the client.
* @param name The new name.
*/
NetworkRecvStatus ClientNetworkGameSocketHandler::SendSetName(const char *name)
NetworkRecvStatus ClientNetworkGameSocketHandler::SendSetName(const std::string &name)
{
Packet *p = new Packet(PACKET_CLIENT_SET_NAME, 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 std::string &pass, const char *command)
NetworkRecvStatus ClientNetworkGameSocketHandler::SendRCon(const std::string &pass, const std::string &command)
{
Packet *p = new Packet(PACKET_CLIENT_RCON, SHRT_MAX);
p->Send_string(GenerateCompanyPasswordHash(pass, _password_server_id, _rcon_password_game_seed));
@@ -1467,7 +1467,7 @@ void NetworkClient_Connected()
* @param password The password.
* @param command The command to execute.
*/
void NetworkClientSendRcon(const std::string &password, const char *command)
void NetworkClientSendRcon(const std::string &password, const std::string &command)
{
MyClient::SendRCon(password, command);
}
@@ -1574,12 +1574,11 @@ void NetworkUpdateClientName(const std::string &client_name)
/* Don't change the name if it is the same as the old name */
if (client_name.compare(ci->client_name) != 0) {
if (!_network_server) {
MyClient::SendSetName(client_name.c_str());
MyClient::SendSetName(client_name);
} else {
/* 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, client_name.c_str(), lastof(temporary_name));
if (NetworkFindName(temporary_name, lastof(temporary_name))) {
std::string temporary_name = client_name;
if (NetworkMakeClientNameUnique(temporary_name)) {
NetworkTextMessage(NETWORK_ACTION_NAME_CHANGE, CC_DEFAULT, false, ci->client_name, temporary_name);
ci->client_name = temporary_name;
NetworkUpdateClientInfo(CLIENT_ID_SERVER);

View File

@@ -110,8 +110,8 @@ public:
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 std::string &password, const char *command);
static NetworkRecvStatus SendSetName(const std::string &name);
static NetworkRecvStatus SendRCon(const std::string &password, const std::string &command);
static NetworkRecvStatus SendMove(CompanyID company, const std::string &password);
static bool IsConnected();

View File

@@ -55,7 +55,7 @@ void NetworkClientsToSpectators(CompanyID cid);
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 std::string &pass = "");
void NetworkClientSendRcon(const std::string &password, const char *command);
void NetworkClientSendRcon(const std::string &password, const std::string &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);
@@ -75,16 +75,16 @@ void NetworkServerUpdateGameInfo();
void NetworkServerShowStatusToConsole();
bool NetworkServerStart();
void NetworkServerNewCompany(const Company *company, NetworkClientInfo *ci);
bool NetworkServerChangeClientName(ClientID client_id, const char *new_name);
bool NetworkServerChangeClientName(ClientID client_id, const std::string &new_name);
void NetworkServerDoMove(ClientID client_id, CompanyID company_id);
void NetworkServerSendRcon(ClientID client_id, TextColour colour_code, const char *string);
void NetworkServerSendRcon(ClientID client_id, TextColour colour_code, const std::string &string);
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);
uint NetworkServerKickOrBanIP(const char *ip, bool ban, const char *reason);
void NetworkServerKickClient(ClientID client_id, const std::string &reason);
uint NetworkServerKickOrBanIP(ClientID client_id, bool ban, const std::string &reason);
uint NetworkServerKickOrBanIP(const std::string &ip, bool ban, const std::string &reason);
void NetworkInitChatMessage();
void CDECL NetworkAddChatMessage(TextColour colour, uint duration, const std::string &message);

View File

@@ -1676,7 +1676,7 @@ enum DropDownAdmin {
*/
static void AdminClientKickCallback(Window *w, bool confirmed)
{
if (confirmed) NetworkServerKickClient(_admin_client_id, nullptr);
if (confirmed) NetworkServerKickClient(_admin_client_id, {});
}
/**
@@ -1686,7 +1686,7 @@ static void AdminClientKickCallback(Window *w, bool confirmed)
*/
static void AdminClientBanCallback(Window *w, bool confirmed)
{
if (confirmed) NetworkServerKickOrBanIP(_admin_client_id, true, nullptr);
if (confirmed) NetworkServerKickOrBanIP(_admin_client_id, true, {});
}
/**

View File

@@ -124,7 +124,7 @@ void ShowNetworkError(StringID error_string);
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);
bool NetworkMakeClientNameUnique(std::string &new_name);
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);

View File

@@ -443,12 +443,12 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::SendCompanyInfo()
* @param error The error to disconnect for.
* @param reason In case of kicking a client, specifies the reason for kicking the client.
*/
NetworkRecvStatus ServerNetworkGameSocketHandler::SendError(NetworkErrorCode error, const char *reason)
NetworkRecvStatus ServerNetworkGameSocketHandler::SendError(NetworkErrorCode error, const std::string &reason)
{
Packet *p = new Packet(PACKET_SERVER_ERROR, SHRT_MAX);
p->Send_uint8(error);
if (reason != nullptr) p->Send_string(reason);
if (!reason.empty()) p->Send_string(reason);
this->SendPacket(p);
StringID strid = GetNetworkErrorMsg(error);
@@ -461,7 +461,7 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::SendError(NetworkErrorCode err
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) {
if (error == NETWORK_ERROR_KICKED && !reason.empty()) {
NetworkTextMessage(NETWORK_ACTION_KICKED, CC_DEFAULT, false, client_name, reason, strid);
} else {
NetworkTextMessage(NETWORK_ACTION_LEAVE, CC_DEFAULT, false, client_name, "", strid);
@@ -823,7 +823,7 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::SendNewGame()
* @param colour The colour of the result.
* @param command The command that was executed.
*/
NetworkRecvStatus ServerNetworkGameSocketHandler::SendRConResult(uint16 colour, const char *command)
NetworkRecvStatus ServerNetworkGameSocketHandler::SendRConResult(uint16 colour, const std::string &command)
{
Packet *p = new Packet(PACKET_SERVER_RCON, SHRT_MAX);
@@ -928,8 +928,6 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::Receive_CLIENT_JOIN(Packet *p)
return this->SendError(NETWORK_ERROR_NOT_EXPECTED);
}
char name[NETWORK_CLIENT_NAME_LENGTH];
CompanyID playas;
char client_revision[NETWORK_REVISION_LENGTH];
p->Recv_string(client_revision, sizeof(client_revision));
@@ -941,8 +939,8 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::Receive_CLIENT_JOIN(Packet *p)
return this->SendError(NETWORK_ERROR_WRONG_REVISION);
}
p->Recv_string(name, sizeof(name));
playas = (Owner)p->Recv_uint8();
std::string client_name = p->Recv_string(NETWORK_CLIENT_NAME_LENGTH);
CompanyID playas = (Owner)p->Recv_uint8();
if (this->HasClientQuit()) return NETWORK_RECV_STATUS_CLIENT_QUIT;
@@ -965,14 +963,14 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::Receive_CLIENT_JOIN(Packet *p)
break;
}
if (!NetworkIsValidClientName(name)) {
if (!NetworkIsValidClientName(client_name)) {
/* An invalid client name was given. However, the client ensures the name
* is valid before it is sent over the network, so something went horribly
* wrong. This is probably someone trying to troll us. */
return this->SendError(NETWORK_ERROR_INVALID_CLIENT_NAME);
}
if (!NetworkFindName(name, lastof(name))) { // Change name if duplicate
if (!NetworkMakeClientNameUnique(client_name)) { // Change name if duplicate
/* We could not create a name for this client */
return this->SendError(NETWORK_ERROR_NAME_IN_USE);
}
@@ -981,7 +979,7 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::Receive_CLIENT_JOIN(Packet *p)
NetworkClientInfo *ci = new NetworkClientInfo(this->client_id);
this->SetInfo(ci);
ci->join_date = _date;
ci->client_name = name;
ci->client_name = client_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);
@@ -1528,10 +1526,9 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::Receive_CLIENT_SET_NAME(Packet
return this->SendError(NETWORK_ERROR_NOT_EXPECTED);
}
char client_name[NETWORK_CLIENT_NAME_LENGTH];
NetworkClientInfo *ci;
p->Recv_string(client_name, sizeof(client_name));
std::string client_name = p->Recv_string(NETWORK_CLIENT_NAME_LENGTH);
ci = this->GetInfo();
if (this->HasClientQuit()) return NETWORK_RECV_STATUS_CLIENT_QUIT;
@@ -1545,7 +1542,7 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::Receive_CLIENT_SET_NAME(Packet
}
/* Display change */
if (NetworkFindName(client_name, lastof(client_name))) {
if (NetworkMakeClientNameUnique(client_name)) {
NetworkTextMessage(NETWORK_ACTION_NAME_CHANGE, CC_DEFAULT, false, ci->client_name, client_name);
ci->client_name = client_name;
NetworkUpdateClientInfo(ci->client_id);
@@ -1558,15 +1555,13 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::Receive_CLIENT_RCON(Packet *p)
{
if (this->status != STATUS_ACTIVE) return this->SendError(NETWORK_ERROR_NOT_EXPECTED);
char command[NETWORK_RCONCOMMAND_LENGTH];
if (_settings_client.network.rcon_password.empty()) {
NetworkServerSendRcon(this->client_id, CC_ERROR, "Access Denied");
return NETWORK_RECV_STATUS_OKAY;
}
std::string password = p->Recv_string(NETWORK_PASSWORD_LENGTH);
p->Recv_string(command, sizeof(command));
std::string command = p->Recv_string(NETWORK_RCONCOMMAND_LENGTH);
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);
@@ -1574,10 +1569,10 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::Receive_CLIENT_RCON(Packet *p)
return NETWORK_RECV_STATUS_OKAY;
}
DEBUG(net, 3, "[rcon] Client-id %d executed: %s", this->client_id, command);
DEBUG(net, 3, "[rcon] Client-id %d executed: %s", this->client_id, command.c_str());
_redirect_console_to_client = this->client_id;
IConsoleCmdExec(command);
IConsoleCmdExec(command.c_str());
_redirect_console_to_client = INVALID_CLIENT_ID;
return NETWORK_RECV_STATUS_OKAY;
}
@@ -1837,42 +1832,40 @@ static void NetworkAutoCleanCompanies()
/**
* Check whether a name is unique, and otherwise try to make it unique.
* @param new_name The name to check/modify.
* @param last The last writeable element of the buffer.
* @return True if an unique name was achieved.
*/
bool NetworkFindName(char *new_name, const char *last)
bool NetworkMakeClientNameUnique(std::string &name)
{
bool found_name = false;
bool is_name_unique = false;
uint number = 0;
char original_name[NETWORK_CLIENT_NAME_LENGTH];
std::string original_name = name;
strecpy(original_name, new_name, lastof(original_name));
while (!found_name) {
found_name = true;
while (!is_name_unique) {
is_name_unique = true;
for (const NetworkClientInfo *ci : NetworkClientInfo::Iterate()) {
if (ci->client_name.compare(new_name) == 0) {
if (ci->client_name.compare(name) == 0) {
/* Name already in use */
found_name = false;
is_name_unique = false;
break;
}
}
/* Check if it is the same as the server-name */
const NetworkClientInfo *ci = NetworkClientInfo::GetByClientID(CLIENT_ID_SERVER);
if (ci != nullptr) {
if (ci->client_name.compare(new_name) == 0) found_name = false; // name already in use
if (ci->client_name.compare(name) == 0) is_name_unique = false; // name already in use
}
if (!found_name) {
if (!is_name_unique) {
/* Try a new name (<name> #1, <name> #2, and so on) */
name = original_name + " #" + std::to_string(number);
/* Something's really wrong when there're more names than clients */
if (number++ > MAX_CLIENTS) break;
seprintf(new_name, last, "%s #%d", original_name, number);
/* The constructed client name is larger than the limit,
* so... bail out as no valid name can be created. */
if (name.size() >= NETWORK_CLIENT_NAME_LENGTH) return false;
}
}
return found_name;
return is_name_unique;
}
/**
@@ -1881,7 +1874,7 @@ bool NetworkFindName(char *new_name, const char *last)
* @param new_name the new name for the client
* @return true iff the name was changed
*/
bool NetworkServerChangeClientName(ClientID client_id, const char *new_name)
bool NetworkServerChangeClientName(ClientID client_id, const std::string &new_name)
{
/* Check if the name's already in use */
for (NetworkClientInfo *ci : NetworkClientInfo::Iterate()) {
@@ -2213,7 +2206,7 @@ void NetworkServerDoMove(ClientID client_id, CompanyID company_id)
* @param colour_code The colour of the text.
* @param string The actual reply.
*/
void NetworkServerSendRcon(ClientID client_id, TextColour colour_code, const char *string)
void NetworkServerSendRcon(ClientID client_id, TextColour colour_code, const std::string &string)
{
NetworkClientSocket::GetByClientID(client_id)->SendRConResult(colour_code, string);
}
@@ -2223,7 +2216,7 @@ void NetworkServerSendRcon(ClientID client_id, TextColour colour_code, const cha
* @param client_id The client to kick.
* @param reason In case of kicking a client, specifies the reason for kicking the client.
*/
void NetworkServerKickClient(ClientID client_id, const char *reason)
void NetworkServerKickClient(ClientID client_id, const std::string &reason)
{
if (client_id == CLIENT_ID_SERVER) return;
NetworkClientSocket::GetByClientID(client_id)->SendError(NETWORK_ERROR_KICKED, reason);
@@ -2235,7 +2228,7 @@ void NetworkServerKickClient(ClientID client_id, const char *reason)
* @param ban Whether to ban or kick.
* @param reason In case of kicking a client, specifies the reason for kicking the client.
*/
uint NetworkServerKickOrBanIP(ClientID client_id, bool ban, const char *reason)
uint NetworkServerKickOrBanIP(ClientID client_id, bool ban, const std::string &reason)
{
return NetworkServerKickOrBanIP(NetworkClientSocket::GetByClientID(client_id)->GetClientIP(), ban, reason);
}
@@ -2246,7 +2239,7 @@ uint NetworkServerKickOrBanIP(ClientID client_id, bool ban, const char *reason)
* @param ban Whether to ban or just kick.
* @param reason In case of kicking a client, specifies the reason for kicking the client.
*/
uint NetworkServerKickOrBanIP(const char *ip, bool ban, const char *reason)
uint NetworkServerKickOrBanIP(const std::string &ip, bool ban, const std::string &reason)
{
/* Add address to ban-list */
if (ban) {
@@ -2270,7 +2263,7 @@ uint NetworkServerKickOrBanIP(const char *ip, bool ban, const char *reason)
for (NetworkClientSocket *cs : NetworkClientSocket::Iterate()) {
if (cs->client_id == CLIENT_ID_SERVER) continue;
if (cs->client_id == _redirect_console_to_client) continue;
if (cs->client_address.IsInNetmask(ip)) {
if (cs->client_address.IsInNetmask(ip.c_str())) {
NetworkServerKickClient(cs->client_id, reason);
n++;
}

View File

@@ -103,11 +103,11 @@ public:
NetworkRecvStatus SendQuit(ClientID client_id);
NetworkRecvStatus SendShutdown();
NetworkRecvStatus SendNewGame();
NetworkRecvStatus SendRConResult(uint16 colour, const char *command);
NetworkRecvStatus SendRConResult(uint16 colour, const std::string &command);
NetworkRecvStatus SendMove(ClientID client_id, CompanyID company_id);
NetworkRecvStatus SendClientInfo(NetworkClientInfo *ci);
NetworkRecvStatus SendError(NetworkErrorCode error, const char *reason = nullptr);
NetworkRecvStatus SendError(NetworkErrorCode error, const std::string &reason = {});
NetworkRecvStatus SendDesyncLog(const std::string &log);
NetworkRecvStatus SendChat(NetworkAction action, ClientID client_id, bool self_send, const std::string &msg, NetworkTextMessageData data);
NetworkRecvStatus SendJoin(ClientID client_id);