diff --git a/src/network/network.cpp b/src/network/network.cpp index 922d8fe180..8d1e564f2e 100644 --- a/src/network/network.cpp +++ b/src/network/network.cpp @@ -77,6 +77,7 @@ enum { NETWORK_COMMAND_GAMEINFO, NETWORK_COMMAND_SHOWERROR, NETWORK_COMMAND_GROUPLIST, + NETWORK_COMMAND_EVENT, NETWORK_COMMAND_MAX, NETWORK_COMMAND_INVALID = -1 }; @@ -94,6 +95,11 @@ enum { MASTER_SERVER_STATUS_INTERNAL_ERROR = 500 }; +enum { + SERVER_EVENT_PLAYER_JOINED, + SERVER_EVENT_PLAYER_DISCONNECTED, +}; + constexpr int MASTER_SERVER_REGISTER_TIME = 120 * 1000; // 2 minutes constexpr int MASTER_SERVER_HEARTBEAT_TIME = 60 * 1000; // 1 minute @@ -566,6 +572,7 @@ Network::Network() client_command_handlers[NETWORK_COMMAND_SETDISCONNECTMSG] = &Network::Client_Handle_SETDISCONNECTMSG; client_command_handlers[NETWORK_COMMAND_SHOWERROR] = &Network::Client_Handle_SHOWERROR; client_command_handlers[NETWORK_COMMAND_GROUPLIST] = &Network::Client_Handle_GROUPLIST; + client_command_handlers[NETWORK_COMMAND_EVENT] = &Network::Client_Handle_EVENT; server_command_handlers.resize(NETWORK_COMMAND_MAX, 0); server_command_handlers[NETWORK_COMMAND_AUTH] = &Network::Server_Handle_AUTH; server_command_handlers[NETWORK_COMMAND_CHAT] = &Network::Server_Handle_CHAT; @@ -1501,6 +1508,25 @@ void Network::Server_Send_GROUPLIST(NetworkConnection& connection) connection.QueuePacket(std::move(packet)); } +void Network::Server_Send_EVENT_PLAYER_JOINED(const char *playerName) +{ + std::unique_ptr packet = std::move(NetworkPacket::Allocate()); + *packet << (uint32)NETWORK_COMMAND_EVENT; + *packet << (uint16)SERVER_EVENT_PLAYER_JOINED; + packet->WriteString(playerName); + SendPacketToClients(*packet); +} + +void Network::Server_Send_EVENT_PLAYER_DISCONNECTED(const char *playerName, const char *reason) +{ + std::unique_ptr packet = std::move(NetworkPacket::Allocate()); + *packet << (uint32)NETWORK_COMMAND_EVENT; + *packet << (uint16)SERVER_EVENT_PLAYER_DISCONNECTED; + packet->WriteString(playerName); + packet->WriteString(reason); + SendPacketToClients(*packet); +} + bool Network::ProcessConnection(NetworkConnection& connection) { int packetStatus; @@ -1606,7 +1632,7 @@ void Network::RemoveClient(std::unique_ptr& connection) } chat_history_add(text); - gNetwork.Server_Send_CHAT(text); + gNetwork.Server_Send_EVENT_PLAYER_DISCONNECTED((char*)connection_player->name, connection->getLastDisconnectReason()); } player_list.erase(std::remove_if(player_list.begin(), player_list.end(), [connection_player](std::unique_ptr& player){ return player.get() == connection_player; }), player_list.end()); client_connection_list.remove(connection); @@ -1709,7 +1735,7 @@ void Network::Server_Handle_AUTH(NetworkConnection& connection, NetworkPacket& p format_string(text, STR_MULTIPLAYER_PLAYER_HAS_JOINED_THE_GAME, &player_name); chat_history_add(text); Server_Send_MAP(&connection); - gNetwork.Server_Send_CHAT(text); + gNetwork.Server_Send_EVENT_PLAYER_JOINED(player_name); Server_Send_GROUPLIST(connection); Server_Send_PLAYERLIST(); } @@ -1968,6 +1994,36 @@ void Network::Client_Handle_GROUPLIST(NetworkConnection& connection, NetworkPack } } +void Network::Client_Handle_EVENT(NetworkConnection& connection, NetworkPacket& packet) +{ + uint16 eventType; + packet >> eventType; + switch (eventType) { + case SERVER_EVENT_PLAYER_JOINED: + { + char text[256]; + const char *playerName = packet.ReadString(); + format_string(text, STR_MULTIPLAYER_PLAYER_HAS_JOINED_THE_GAME, &playerName); + chat_history_add(text); + break; + } + case SERVER_EVENT_PLAYER_DISCONNECTED: + { + char text[256]; + const char *playerName = packet.ReadString(); + const char *reason = packet.ReadString(); + const char *args[] = { playerName, reason }; + if (str_is_null_or_empty(reason)) { + format_string(text, STR_MULTIPLAYER_PLAYER_HAS_DISCONNECTED_NO_REASON, args); + } else { + format_string(text, STR_MULTIPLAYER_PLAYER_HAS_DISCONNECTED_WITH_REASON, args); + } + chat_history_add(text); + break; + } + } +} + int network_init() { return gNetwork.Init(); diff --git a/src/network/network.h b/src/network/network.h index 7d5742e7a6..5fe28cc7f8 100644 --- a/src/network/network.h +++ b/src/network/network.h @@ -68,7 +68,7 @@ extern "C" { // This define specifies which version of network stream current build uses. // It is used for making sure only compatible builds get connected, even within // single OpenRCT2 version. -#define NETWORK_STREAM_VERSION "3" +#define NETWORK_STREAM_VERSION "4" #define NETWORK_STREAM_ID OPENRCT2_VERSION "-" NETWORK_STREAM_VERSION #define NETWORK_DISCONNECT_REASON_BUFFER_SIZE 256 @@ -337,6 +337,8 @@ public: void Server_Send_GAMEINFO(NetworkConnection& connection); void Server_Send_SHOWERROR(NetworkConnection& connection, rct_string_id title, rct_string_id message); void Server_Send_GROUPLIST(NetworkConnection& connection); + void Server_Send_EVENT_PLAYER_JOINED(const char *playerName); + void Server_Send_EVENT_PLAYER_DISCONNECTED(const char *playerName, const char *reason); std::vector> player_list; std::vector> group_list; @@ -412,6 +414,7 @@ private: void Server_Handle_GAMEINFO(NetworkConnection& connection, NetworkPacket& packet); void Client_Handle_SHOWERROR(NetworkConnection& connection, NetworkPacket& packet); void Client_Handle_GROUPLIST(NetworkConnection& connection, NetworkPacket& packet); + void Client_Handle_EVENT(NetworkConnection& connection, NetworkPacket& packet); }; #endif // __cplusplus