From ecce4da6e89bbe244094968ccd159a9def6e9bdb Mon Sep 17 00:00:00 2001 From: Ted John Date: Mon, 27 Apr 2020 19:54:29 +0100 Subject: [PATCH] Add ipAddress and publicHashKey properties to player API --- distribution/openrct2.d.ts | 2 ++ src/openrct2/network/Network.cpp | 45 ++++++++++++++++++++++++++++ src/openrct2/network/Socket.cpp | 42 ++++++++++++++++++++++++-- src/openrct2/network/Socket.h | 1 + src/openrct2/network/network.h | 2 ++ src/openrct2/scripting/ScNetwork.hpp | 12 ++++++++ 6 files changed, 101 insertions(+), 3 deletions(-) diff --git a/distribution/openrct2.d.ts b/distribution/openrct2.d.ts index 62b1152b0d..6fb51e0b1e 100644 --- a/distribution/openrct2.d.ts +++ b/distribution/openrct2.d.ts @@ -590,6 +590,8 @@ declare global { readonly ping: number; readonly commandsRan: number; readonly moneySpent: number; + readonly ipAddress: string; + readonly publicKeyHash: string; } interface PlayerGroup { diff --git a/src/openrct2/network/Network.cpp b/src/openrct2/network/Network.cpp index d1c011f7f2..087717b8a1 100644 --- a/src/openrct2/network/Network.cpp +++ b/src/openrct2/network/Network.cpp @@ -136,6 +136,7 @@ public: void ProcessDisconnectedClients(); std::vector>::iterator GetPlayerIteratorByID(uint8_t id); NetworkPlayer* GetPlayerByID(uint8_t id); + NetworkConnection* GetPlayerConnection(uint8_t id); std::vector>::iterator GetGroupIteratorByID(uint8_t id); NetworkGroup* GetGroupByID(uint8_t id); static const char* FormatChat(NetworkPlayer* fromplayer, const char* text); @@ -665,6 +666,22 @@ uint8_t Network::GetPlayerID() return player_id; } +NetworkConnection* Network::GetPlayerConnection(uint8_t id) +{ + auto player = GetPlayerByID(id); + if (player != nullptr) + { + for (auto& connection : client_connection_list) + { + if (connection->Player == player) + { + return connection.get(); + } + } + } + return nullptr; +} + void Network::Update() { _closeLock = true; @@ -3385,6 +3402,26 @@ money32 network_get_player_money_spent(uint32_t index) return gNetwork.player_list[index]->MoneySpent; } +std::string network_get_player_ip_address(uint32_t id) +{ + auto conn = gNetwork.GetPlayerConnection(id); + if (conn != nullptr) + { + return conn->Socket->GetIpAddress(); + } + return {}; +} + +std::string network_get_player_public_key_hash(uint32_t id) +{ + auto player = gNetwork.GetPlayerByID(id); + if (player != nullptr) + { + return player->KeyHash; + } + return {}; +} + void network_add_player_money_spent(uint32_t index, money32 cost) { gNetwork.player_list[index]->AddMoneySpent(cost); @@ -4054,6 +4091,14 @@ money32 network_get_player_money_spent(uint32_t index) { return MONEY(0, 0); } +std::string network_get_player_ip_address(uint32_t id) +{ + return {}; +} +std::string network_get_player_public_key_hash(uint32_t id) +{ + return {}; +} void network_add_player_money_spent(uint32_t index, money32 cost) { } diff --git a/src/openrct2/network/Socket.cpp b/src/openrct2/network/Socket.cpp index b4a7f0c08d..7c192084ef 100644 --- a/src/openrct2/network/Socket.cpp +++ b/src/openrct2/network/Socket.cpp @@ -201,6 +201,7 @@ private: uint16_t _listeningPort = 0; SOCKET _socket = INVALID_SOCKET; + std::string _ipAddress; std::string _hostName; std::future _connectFuture; std::string _error; @@ -322,18 +323,21 @@ public: } else { + auto ipAddress = GetIpAddressFromSocket(reinterpret_cast(&client_addr)); + char hostName[NI_MAXHOST]; int32_t rc = getnameinfo( reinterpret_cast(&client_addr), client_len, hostName, sizeof(hostName), nullptr, 0, NI_NUMERICHOST | NI_NUMERICSERV); SetOption(socket, IPPROTO_TCP, TCP_NODELAY, true); + if (rc == 0) { - tcpSocket = std::unique_ptr(new TcpSocket(socket, hostName)); + tcpSocket = std::unique_ptr(new TcpSocket(socket, hostName, ipAddress)); } else { - tcpSocket = std::unique_ptr(new TcpSocket(socket, "")); + tcpSocket = std::unique_ptr(new TcpSocket(socket, "", ipAddress)); } } } @@ -546,11 +550,17 @@ public: return _hostName.empty() ? nullptr : _hostName.c_str(); } + std::string GetIpAddress() const override + { + return _ipAddress; + } + private: - explicit TcpSocket(SOCKET socket, const std::string& hostName) + explicit TcpSocket(SOCKET socket, const std::string& hostName, const std::string& ipAddress) { _socket = socket; _hostName = hostName; + _ipAddress = ipAddress; _status = SOCKET_STATUS_CONNECTED; } @@ -563,6 +573,32 @@ private: } _status = SOCKET_STATUS_CLOSED; } + + std::string GetIpAddressFromSocket(const sockaddr_in* addr) + { + std::string result; +# if defined(__MINGW32__) + if (addr->sin_family == AF_INET) + { + result = inet_ntoa(addr->sin_addr); + } +# else + if (addr->sin_family == AF_INET) + { + char str[INET_ADDRSTRLEN]{}; + inet_ntop(AF_INET, &addr->sin_addr, str, sizeof(str)); + result = str; + } + else if (addr->sin_family == AF_INET6) + { + auto addrv6 = reinterpret_cast(&addr); + char str[INET6_ADDRSTRLEN]{}; + inet_ntop(AF_INET6, &addrv6->sin6_addr, str, sizeof(str)); + result = str; + } +# endif + return result; + } }; class UdpSocket final : public IUdpSocket, protected Socket diff --git a/src/openrct2/network/Socket.h b/src/openrct2/network/Socket.h index 601168b31b..562cad8d5f 100644 --- a/src/openrct2/network/Socket.h +++ b/src/openrct2/network/Socket.h @@ -55,6 +55,7 @@ public: virtual SOCKET_STATUS GetStatus() const abstract; virtual const char* GetError() const abstract; virtual const char* GetHostName() const abstract; + virtual std::string GetIpAddress() const abstract; virtual void Listen(uint16_t port) abstract; virtual void Listen(const std::string& address, uint16_t port) abstract; diff --git a/src/openrct2/network/network.h b/src/openrct2/network/network.h index 1b3d079445..02e4ad3b7c 100644 --- a/src/openrct2/network/network.h +++ b/src/openrct2/network/network.h @@ -61,6 +61,8 @@ uint32_t network_get_player_flags(uint32_t index); int32_t network_get_player_ping(uint32_t index); int32_t network_get_player_id(uint32_t index); money32 network_get_player_money_spent(uint32_t index); +std::string network_get_player_ip_address(uint32_t id); +std::string network_get_player_public_key_hash(uint32_t id); void network_add_player_money_spent(uint32_t index, money32 cost); int32_t network_get_player_last_action(uint32_t index, int32_t time); void network_set_player_last_action(uint32_t index, int32_t command); diff --git a/src/openrct2/scripting/ScNetwork.hpp b/src/openrct2/scripting/ScNetwork.hpp index af0f6c7b3f..9e99ab4450 100644 --- a/src/openrct2/scripting/ScNetwork.hpp +++ b/src/openrct2/scripting/ScNetwork.hpp @@ -233,6 +233,16 @@ namespace OpenRCT2::Scripting # endif } + std::string ipAddress_get() const + { + return network_get_player_ip_address(_id); + } + + std::string publicKeyHash_get() const + { + return network_get_player_public_key_hash(_id); + } + static void Register(duk_context* ctx) { dukglue_register_property(ctx, &ScPlayer::id_get, nullptr, "id"); @@ -241,6 +251,8 @@ namespace OpenRCT2::Scripting dukglue_register_property(ctx, &ScPlayer::ping_get, nullptr, "ping"); dukglue_register_property(ctx, &ScPlayer::commandsRan_get, nullptr, "commandsRan"); dukglue_register_property(ctx, &ScPlayer::moneySpent_get, nullptr, "moneySpent"); + dukglue_register_property(ctx, &ScPlayer::ipAddress_get, nullptr, "ipAddress"); + dukglue_register_property(ctx, &ScPlayer::publicKeyHash_get, nullptr, "publicKeyHash"); } };