From 9b3af0027b4671a64d3e3ad7c10a7de9ad54ff62 Mon Sep 17 00:00:00 2001
From: german <german@thesoftwareartisans.com>
Date: Sat, 27 Feb 2021 09:26:33 -0600
Subject: [PATCH] inputCommon: Use an unique client id for each socket instance

---
 src/input_common/udp/client.cpp               | 26 ++++++++++++-------
 src/input_common/udp/client.h                 |  6 ++---
 .../configuration/configure_motion_touch.cpp  |  8 +++---
 .../configuration/configure_motion_touch.h    |  2 +-
 4 files changed, 23 insertions(+), 19 deletions(-)

diff --git a/src/input_common/udp/client.cpp b/src/input_common/udp/client.cpp
index c4afa4174..df73f9ff7 100644
--- a/src/input_common/udp/client.cpp
+++ b/src/input_common/udp/client.cpp
@@ -5,6 +5,7 @@
 #include <chrono>
 #include <cstring>
 #include <functional>
+#include <random>
 #include <thread>
 #include <boost/asio.hpp>
 #include "common/logging/log.h"
@@ -26,10 +27,10 @@ class Socket {
 public:
     using clock = std::chrono::system_clock;
 
-    explicit Socket(const std::string& host, u16 port, std::size_t pad_index_, u32 client_id_,
+    explicit Socket(const std::string& host, u16 port, std::size_t pad_index_,
                     SocketCallback callback_)
         : callback(std::move(callback_)), timer(io_service),
-          socket(io_service, udp::endpoint(udp::v4(), 0)), client_id(client_id_),
+          socket(io_service, udp::endpoint(udp::v4(), 0)), client_id(GenerateRandomClientId()),
           pad_index(pad_index_) {
         boost::system::error_code ec{};
         auto ipv4 = boost::asio::ip::make_address_v4(host, ec);
@@ -63,6 +64,11 @@ public:
     }
 
 private:
+    u32 GenerateRandomClientId() const {
+        std::random_device device;
+        return device();
+    }
+
     void HandleReceive(const boost::system::error_code&, std::size_t bytes_transferred) {
         if (auto type = Response::Validate(receive_buffer.data(), bytes_transferred)) {
             switch (*type) {
@@ -115,7 +121,7 @@ private:
     boost::asio::basic_waitable_timer<clock> timer;
     udp::socket socket;
 
-    u32 client_id{};
+    const u32 client_id;
     std::size_t pad_index{};
 
     static constexpr std::size_t PORT_INFO_SIZE = sizeof(Message<Request::PortInfo>);
@@ -203,7 +209,7 @@ void Client::ReloadSockets() {
                 LOG_ERROR(Input, "Duplicated UDP servers found");
                 continue;
             }
-            StartCommunication(client++, udp_input_address, udp_input_port, pad, 24872);
+            StartCommunication(client++, udp_input_address, udp_input_port, pad);
         }
     }
 }
@@ -277,7 +283,7 @@ void Client::OnPadData(Response::PadData data, std::size_t client) {
 }
 
 void Client::StartCommunication(std::size_t client, const std::string& host, u16 port,
-                                std::size_t pad_index, u32 client_id) {
+                                std::size_t pad_index) {
     SocketCallback callback{[this](Response::Version version) { OnVersion(version); },
                             [this](Response::PortInfo info) { OnPortInfo(info); },
                             [this, client](Response::PadData data) { OnPadData(data, client); }};
@@ -287,7 +293,7 @@ void Client::StartCommunication(std::size_t client, const std::string& host, u16
     clients[client].port = port;
     clients[client].pad_index = pad_index;
     clients[client].active = 0;
-    clients[client].socket = std::make_unique<Socket>(host, port, pad_index, client_id, callback);
+    clients[client].socket = std::make_unique<Socket>(host, port, pad_index, callback);
     clients[client].thread = std::thread{SocketLoop, clients[client].socket.get()};
     // Set motion parameters
     // SetGyroThreshold value should be dependent on GyroscopeZeroDriftMode
@@ -416,7 +422,7 @@ const Common::SPSCQueue<UDPPadStatus>& Client::GetPadQueue() const {
     return pad_queue;
 }
 
-void TestCommunication(const std::string& host, u16 port, std::size_t pad_index, u32 client_id,
+void TestCommunication(const std::string& host, u16 port, std::size_t pad_index,
                        const std::function<void()>& success_callback,
                        const std::function<void()>& failure_callback) {
     std::thread([=] {
@@ -426,7 +432,7 @@ void TestCommunication(const std::string& host, u16 port, std::size_t pad_index,
             .port_info = [](Response::PortInfo) {},
             .pad_data = [&](Response::PadData) { success_event.Set(); },
         };
-        Socket socket{host, port, pad_index, client_id, std::move(callback)};
+        Socket socket{host, port, pad_index, std::move(callback)};
         std::thread worker_thread{SocketLoop, &socket};
         const bool result = success_event.WaitFor(std::chrono::seconds(5));
         socket.Stop();
@@ -440,7 +446,7 @@ void TestCommunication(const std::string& host, u16 port, std::size_t pad_index,
 }
 
 CalibrationConfigurationJob::CalibrationConfigurationJob(
-    const std::string& host, u16 port, std::size_t pad_index, u32 client_id,
+    const std::string& host, u16 port, std::size_t pad_index,
     std::function<void(Status)> status_callback,
     std::function<void(u16, u16, u16, u16)> data_callback) {
 
@@ -485,7 +491,7 @@ CalibrationConfigurationJob::CalibrationConfigurationJob(
                                         complete_event.Set();
                                     }
                                 }};
-        Socket socket{host, port, pad_index, client_id, std::move(callback)};
+        Socket socket{host, port, pad_index, std::move(callback)};
         std::thread worker_thread{SocketLoop, &socket};
         complete_event.Wait();
         socket.Stop();
diff --git a/src/input_common/udp/client.h b/src/input_common/udp/client.h
index a523f6124..e9e438e88 100644
--- a/src/input_common/udp/client.h
+++ b/src/input_common/udp/client.h
@@ -126,7 +126,7 @@ private:
     void OnPortInfo(Response::PortInfo);
     void OnPadData(Response::PadData, std::size_t client);
     void StartCommunication(std::size_t client, const std::string& host, u16 port,
-                            std::size_t pad_index, u32 client_id);
+                            std::size_t pad_index);
     void UpdateYuzuSettings(std::size_t client, const Common::Vec3<float>& acc,
                             const Common::Vec3<float>& gyro);
 
@@ -165,7 +165,7 @@ public:
      * @param data_callback Called when calibration data is ready
      */
     explicit CalibrationConfigurationJob(const std::string& host, u16 port, std::size_t pad_index,
-                                         u32 client_id, std::function<void(Status)> status_callback,
+                                         std::function<void(Status)> status_callback,
                                          std::function<void(u16, u16, u16, u16)> data_callback);
     ~CalibrationConfigurationJob();
     void Stop();
@@ -174,7 +174,7 @@ private:
     Common::Event complete_event;
 };
 
-void TestCommunication(const std::string& host, u16 port, std::size_t pad_index, u32 client_id,
+void TestCommunication(const std::string& host, u16 port, std::size_t pad_index,
                        const std::function<void()>& success_callback,
                        const std::function<void()>& failure_callback);
 
diff --git a/src/yuzu/configuration/configure_motion_touch.cpp b/src/yuzu/configuration/configure_motion_touch.cpp
index 1f2b792e4..52fdf7265 100644
--- a/src/yuzu/configuration/configure_motion_touch.cpp
+++ b/src/yuzu/configuration/configure_motion_touch.cpp
@@ -24,7 +24,7 @@
 
 CalibrationConfigurationDialog::CalibrationConfigurationDialog(QWidget* parent,
                                                                const std::string& host, u16 port,
-                                                               u8 pad_index, u16 client_id)
+                                                               u8 pad_index)
     : QDialog(parent) {
     layout = new QVBoxLayout;
     status_label = new QLabel(tr("Communicating with the server..."));
@@ -41,7 +41,7 @@ CalibrationConfigurationDialog::CalibrationConfigurationDialog(QWidget* parent,
 
     using namespace InputCommon::CemuhookUDP;
     job = std::make_unique<CalibrationConfigurationJob>(
-        host, port, pad_index, client_id,
+        host, port, pad_index,
         [this](CalibrationConfigurationJob::Status status) {
             QString text;
             switch (status) {
@@ -218,7 +218,6 @@ void ConfigureMotionTouch::OnCemuhookUDPTest() {
     udp_test_in_progress = true;
     InputCommon::CemuhookUDP::TestCommunication(
         ui->udp_server->text().toStdString(), static_cast<u16>(ui->udp_port->text().toInt()), 0,
-        24872,
         [this] {
             LOG_INFO(Frontend, "UDP input test success");
             QMetaObject::invokeMethod(this, "ShowUDPTestResult", Q_ARG(bool, true));
@@ -233,8 +232,7 @@ void ConfigureMotionTouch::OnConfigureTouchCalibration() {
     ui->touch_calibration_config->setEnabled(false);
     ui->touch_calibration_config->setText(tr("Configuring"));
     CalibrationConfigurationDialog dialog(this, ui->udp_server->text().toStdString(),
-                                          static_cast<u16>(ui->udp_port->text().toUInt()), 0,
-                                          24872);
+                                          static_cast<u16>(ui->udp_port->text().toUInt()), 0);
     dialog.exec();
     if (dialog.completed) {
         min_x = dialog.min_x;
diff --git a/src/yuzu/configuration/configure_motion_touch.h b/src/yuzu/configuration/configure_motion_touch.h
index 15d61e8ba..d76bc8154 100644
--- a/src/yuzu/configuration/configure_motion_touch.h
+++ b/src/yuzu/configuration/configure_motion_touch.h
@@ -30,7 +30,7 @@ class CalibrationConfigurationDialog : public QDialog {
     Q_OBJECT
 public:
     explicit CalibrationConfigurationDialog(QWidget* parent, const std::string& host, u16 port,
-                                            u8 pad_index, u16 client_id);
+                                            u8 pad_index);
     ~CalibrationConfigurationDialog() override;
 
 private: