diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/console_cmds.cpp | 40 | ||||
-rw-r--r-- | src/lang/english.txt | 2 | ||||
-rw-r--r-- | src/network/network.cpp | 1 | ||||
-rw-r--r-- | src/network/network_client.cpp | 11 | ||||
-rw-r--r-- | src/network/network_func.h | 6 | ||||
-rw-r--r-- | src/network/network_gui.cpp | 4 | ||||
-rw-r--r-- | src/network/network_server.cpp | 25 | ||||
-rw-r--r-- | src/network/network_server.h | 2 | ||||
-rw-r--r-- | src/network/network_type.h | 1 |
9 files changed, 66 insertions, 26 deletions
diff --git a/src/console_cmds.cpp b/src/console_cmds.cpp index 748e4ab4c..c4b454b51 100644 --- a/src/console_cmds.cpp +++ b/src/console_cmds.cpp @@ -470,7 +470,7 @@ DEF_CONSOLE_CMD(ConClearBuffer) * Network Core Console Commands **********************************/ -static bool ConKickOrBan(const char *argv, bool ban) +static bool ConKickOrBan(const char *argv, bool ban, const char *reason) { uint n; @@ -494,14 +494,14 @@ static bool ConKickOrBan(const char *argv, bool ban) if (!ban) { /* Kick only this client, not all clients with that IP */ - NetworkServerKickClient(client_id); + NetworkServerKickClient(client_id, reason); return true; } /* When banning, kick+ban all clients with that IP */ - n = NetworkServerKickOrBanIP(client_id, ban); + n = NetworkServerKickOrBanIP(client_id, ban, reason); } else { - n = NetworkServerKickOrBanIP(argv, ban); + n = NetworkServerKickOrBanIP(argv, ban, reason); } if (n == 0) { @@ -516,28 +516,48 @@ static bool ConKickOrBan(const char *argv, bool ban) DEF_CONSOLE_CMD(ConKick) { if (argc == 0) { - IConsoleHelp("Kick a client from a network game. Usage: 'kick <ip | client-id>'"); + IConsoleHelp("Kick a client from a network game. Usage: 'kick <ip | client-id> [<kick-reason>]'"); IConsoleHelp("For client-id's, see the command 'clients'"); return true; } - if (argc != 2) return false; + if (argc != 2 && argc != 3) return false; + + /* No reason supplied for kicking */ + if (argc == 2) return ConKickOrBan(argv[1], false, nullptr); - return ConKickOrBan(argv[1], false); + /* Reason for kicking supplied */ + int kick_message_length = strlen(argv[2]); + if (kick_message_length >= 255) { + IConsolePrintF(CC_ERROR, "ERROR: Maximum kick message length is 254 characters. You entered %d characters.", kick_message_length); + return false; + } else { + return ConKickOrBan(argv[1], false, argv[2]); + } } DEF_CONSOLE_CMD(ConBan) { if (argc == 0) { - IConsoleHelp("Ban a client from a network game. Usage: 'ban <ip | client-id>'"); + IConsoleHelp("Ban a client from a network game. Usage: 'ban <ip | client-id> [<ban-reason>]'"); IConsoleHelp("For client-id's, see the command 'clients'"); IConsoleHelp("If the client is no longer online, you can still ban his/her IP"); return true; } - if (argc != 2) return false; + if (argc != 2 && argc != 3) return false; + + /* No reason supplied for kicking */ + if (argc == 2) return ConKickOrBan(argv[1], true, nullptr); - return ConKickOrBan(argv[1], true); + /* Reason for kicking supplied */ + int kick_message_length = strlen(argv[2]); + if (kick_message_length >= 255) { + IConsolePrintF(CC_ERROR, "ERROR: Maximum kick message length is 254 characters. You entered %d characters.", kick_message_length); + return false; + } else { + return ConKickOrBan(argv[1], true, argv[2]); + } } DEF_CONSOLE_CMD(ConUnBan) diff --git a/src/lang/english.txt b/src/lang/english.txt index 963fc3d28..2a4ab1c28 100644 --- a/src/lang/english.txt +++ b/src/lang/english.txt @@ -2168,6 +2168,7 @@ STR_NETWORK_ERROR_WRONG_PASSWORD :{WHITE}Wrong pa STR_NETWORK_ERROR_SERVER_FULL :{WHITE}The server is full STR_NETWORK_ERROR_SERVER_BANNED :{WHITE}You are banned from this server STR_NETWORK_ERROR_KICKED :{WHITE}You were kicked out of the game +STR_NETWORK_ERROR_KICK_MESSAGE :{WHITE}Reason: {RAW_STRING} STR_NETWORK_ERROR_CHEATER :{WHITE}Cheating is not allowed on this server STR_NETWORK_ERROR_TOO_MANY_COMMANDS :{WHITE}You were sending too many commands to the server STR_NETWORK_ERROR_TIMEOUT_PASSWORD :{WHITE}You took too long to enter the password @@ -2227,6 +2228,7 @@ STR_NETWORK_MESSAGE_GIVE_MONEY :*** {RAW_STRING STR_NETWORK_MESSAGE_GAVE_MONEY_AWAY :*** You gave {1:RAW_STRING} {2:CURRENCY_LONG} STR_NETWORK_MESSAGE_SERVER_SHUTDOWN :{WHITE}The server closed the session STR_NETWORK_MESSAGE_SERVER_REBOOT :{WHITE}The server is restarting...{}Please wait... +STR_NETWORK_MESSAGE_KICKED :*** {RAW_STRING} was kicked. Reason: ({RAW_STRING}) # Content downloading window STR_CONTENT_TITLE :{WHITE}Content downloading diff --git a/src/network/network.cpp b/src/network/network.cpp index fe7e6a855..e8c99c89b 100644 --- a/src/network/network.cpp +++ b/src/network/network.cpp @@ -248,6 +248,7 @@ void NetworkTextMessage(NetworkAction action, TextColour colour, bool self_send, case NETWORK_ACTION_GIVE_MONEY: strid = self_send ? STR_NETWORK_MESSAGE_GAVE_MONEY_AWAY : STR_NETWORK_MESSAGE_GIVE_MONEY; break; case NETWORK_ACTION_CHAT_COMPANY: strid = self_send ? STR_NETWORK_CHAT_TO_COMPANY : STR_NETWORK_CHAT_COMPANY; break; case NETWORK_ACTION_CHAT_CLIENT: strid = self_send ? STR_NETWORK_CHAT_TO_CLIENT : STR_NETWORK_CHAT_CLIENT; break; + case NETWORK_ACTION_KICKED: strid = STR_NETWORK_MESSAGE_KICKED; break; default: strid = STR_NETWORK_CHAT_ALL; break; } diff --git a/src/network/network_client.cpp b/src/network/network_client.cpp index 08ec7823e..74b802f91 100644 --- a/src/network/network_client.cpp +++ b/src/network/network_client.cpp @@ -687,8 +687,15 @@ NetworkRecvStatus ClientNetworkGameSocketHandler::Receive_SERVER_ERROR(Packet *p StringID err = STR_NETWORK_ERROR_LOSTCONNECTION; if (error < (ptrdiff_t)lengthof(network_error_strings)) err = network_error_strings[error]; - - ShowErrorMessage(err, INVALID_STRING_ID, WL_CRITICAL); + /* 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)); + SetDParamStr(0, kick_msg); + ShowErrorMessage(err, STR_NETWORK_ERROR_KICK_MESSAGE, WL_CRITICAL); + } else { + ShowErrorMessage(err, INVALID_STRING_ID, WL_CRITICAL); + } /* Perform an emergency save if we had already entered the game */ if (this->status == STATUS_ACTIVE) ClientNetworkEmergencySave(); diff --git a/src/network/network_func.h b/src/network/network_func.h index d4a62ddd3..cbb89820c 100644 --- a/src/network/network_func.h +++ b/src/network/network_func.h @@ -75,9 +75,9 @@ 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, int64 data = 0, bool from_admin = false); -void NetworkServerKickClient(ClientID client_id); -uint NetworkServerKickOrBanIP(ClientID client_id, bool ban); -uint NetworkServerKickOrBanIP(const char *ip, bool ban); +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 NetworkInitChatMessage(); void CDECL NetworkAddChatMessage(TextColour colour, uint duration, const char *message, ...) WARN_FORMAT(3, 4); diff --git a/src/network/network_gui.cpp b/src/network/network_gui.cpp index 2faf5a395..c4488f35d 100644 --- a/src/network/network_gui.cpp +++ b/src/network/network_gui.cpp @@ -1687,12 +1687,12 @@ static WindowDesc _client_list_popup_desc( /* Here we start to define the options out of the menu */ static void ClientList_Kick(const NetworkClientInfo *ci) { - NetworkServerKickClient(ci->client_id); + NetworkServerKickClient(ci->client_id, nullptr); } static void ClientList_Ban(const NetworkClientInfo *ci) { - NetworkServerKickOrBanIP(ci->client_id, true); + NetworkServerKickOrBanIP(ci->client_id, true, nullptr); } static void ClientList_GiveMoney(const NetworkClientInfo *ci) diff --git a/src/network/network_server.cpp b/src/network/network_server.cpp index f68cfd05c..dd88042a1 100644 --- a/src/network/network_server.cpp +++ b/src/network/network_server.cpp @@ -407,13 +407,15 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::SendCompanyInfo() /** * Send an error to the client, and close its connection. * @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) +NetworkRecvStatus ServerNetworkGameSocketHandler::SendError(NetworkErrorCode error, const char *reason) { char str[100]; Packet *p = new Packet(PACKET_SERVER_ERROR); p->Send_uint8(error); + if (reason != nullptr) p->Send_string(reason); this->SendPacket(p); StringID strid = GetNetworkErrorMsg(error); @@ -427,7 +429,11 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::SendError(NetworkErrorCode err DEBUG(net, 1, "'%s' made an error and has been disconnected. Reason: '%s'", client_name, str); - NetworkTextMessage(NETWORK_ACTION_LEAVE, CC_DEFAULT, false, client_name, nullptr, strid); + 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); + } for (NetworkClientSocket *new_cs : NetworkClientSocket::Iterate()) { if (new_cs->status > STATUS_AUTHORIZED && new_cs != this) { @@ -2039,29 +2045,32 @@ void NetworkServerSendRcon(ClientID client_id, TextColour colour_code, const cha /** * Kick a single client. * @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) +void NetworkServerKickClient(ClientID client_id, const char *reason) { if (client_id == CLIENT_ID_SERVER) return; - NetworkClientSocket::GetByClientID(client_id)->SendError(NETWORK_ERROR_KICKED); + NetworkClientSocket::GetByClientID(client_id)->SendError(NETWORK_ERROR_KICKED, reason); } /** * Ban, or kick, everyone joined from the given client's IP. * @param client_id The client to check for. * @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) +uint NetworkServerKickOrBanIP(ClientID client_id, bool ban, const char *reason) { - return NetworkServerKickOrBanIP(NetworkClientSocket::GetByClientID(client_id)->GetClientIP(), ban); + return NetworkServerKickOrBanIP(NetworkClientSocket::GetByClientID(client_id)->GetClientIP(), ban, reason); } /** * Kick or ban someone based on an IP address. * @param ip The IP address/range to ban/kick. * @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) +uint NetworkServerKickOrBanIP(const char *ip, bool ban, const char *reason) { /* Add address to ban-list */ if (ban) { @@ -2081,7 +2090,7 @@ uint NetworkServerKickOrBanIP(const char *ip, bool ban) for (NetworkClientSocket *cs : NetworkClientSocket::Iterate()) { if (cs->client_id == CLIENT_ID_SERVER) continue; if (cs->client_address.IsInNetmask(ip)) { - NetworkServerKickClient(cs->client_id); + NetworkServerKickClient(cs->client_id, reason); n++; } } diff --git a/src/network/network_server.h b/src/network/network_server.h index 9a1873520..3dfcf5594 100644 --- a/src/network/network_server.h +++ b/src/network/network_server.h @@ -89,7 +89,7 @@ public: NetworkRecvStatus SendMove(ClientID client_id, CompanyID company_id); NetworkRecvStatus SendClientInfo(NetworkClientInfo *ci); - NetworkRecvStatus SendError(NetworkErrorCode error); + NetworkRecvStatus SendError(NetworkErrorCode error, const char *reason = nullptr); NetworkRecvStatus SendChat(NetworkAction action, ClientID client_id, bool self_send, const char *msg, int64 data); NetworkRecvStatus SendJoin(ClientID client_id); NetworkRecvStatus SendFrame(); diff --git a/src/network/network_type.h b/src/network/network_type.h index 595eaad0f..5f796b83d 100644 --- a/src/network/network_type.h +++ b/src/network/network_type.h @@ -85,6 +85,7 @@ enum DestType { enum NetworkAction { NETWORK_ACTION_JOIN, NETWORK_ACTION_LEAVE, + NETWORK_ACTION_KICKED, NETWORK_ACTION_SERVER_MESSAGE, NETWORK_ACTION_CHAT, NETWORK_ACTION_CHAT_COMPANY, |