diff --git a/assets/sunshine.conf b/assets/sunshine.conf index e98b50f3..ef96f52f 100644 --- a/assets/sunshine.conf +++ b/assets/sunshine.conf @@ -34,11 +34,8 @@ # # origin_pin_allowed = lan -# Pretty self-explanatory -unique_id = 03904e64-51da-4fb3-9afd-a9f7ff70fea4 - -# The file where info on paired devices is stored -# file_devices = devices.json +# The file where current state of Sunshine is stored +# file_state = sunshine_state.json # How long to wait in milliseconds for data from moonlight before shutting down the stream ping_timeout = 2000 diff --git a/sunshine/config.cpp b/sunshine/config.cpp index 6280f941..444cd16c 100644 --- a/sunshine/config.cpp +++ b/sunshine/config.cpp @@ -42,8 +42,7 @@ nvhttp_t nvhttp { CERTIFICATE_FILE, boost::asio::ip::host_name(), // sunshine_name, - "03904e64-51da-4fb3-9afd-a9f7ff70fea4"s, // unique_id - "devices.json"s // file_devices + "sunshine_state.json"s // file_state }; input_t input { @@ -167,8 +166,7 @@ void parse_file(const char *file) { string_f(vars, "pkey", nvhttp.pkey); string_f(vars, "cert", nvhttp.cert); string_f(vars, "sunshine_name", nvhttp.sunshine_name); - string_f(vars, "unique_id", nvhttp.unique_id); - string_f(vars, "file_devices", nvhttp.file_devices); + string_f(vars, "file_state", nvhttp.file_state); string_f(vars, "external_ip", nvhttp.external_ip); string_f(vars, "audio_sink", audio.sink); diff --git a/sunshine/config.h b/sunshine/config.h index df950b3b..c55b5c85 100644 --- a/sunshine/config.h +++ b/sunshine/config.h @@ -39,8 +39,7 @@ struct nvhttp_t { std::string sunshine_name; - std::string unique_id; //UUID - std::string file_devices; + std::string file_state; std::string external_ip; }; diff --git a/sunshine/nvhttp.cpp b/sunshine/nvhttp.cpp index a4b668a5..2f274ecf 100644 --- a/sunshine/nvhttp.cpp +++ b/sunshine/nvhttp.cpp @@ -22,6 +22,7 @@ #include "nvhttp.h" #include "platform/common.h" #include "network.h" +#include "uuid.h" #include "main.h" @@ -75,6 +76,7 @@ struct pair_session_t { // uniqueID, session std::unordered_map map_id_sess; std::unordered_map map_id_client; +std::string unique_id; std::string local_ip; net::net_e origin_pin_allowed; @@ -89,9 +91,10 @@ enum class op_e { REMOVE }; -void save_devices() { +void save_state() { pt::ptree root; + root.put("root.uniqueid", unique_id); auto &nodes = root.add_child("root.devices", pt::ptree {}); for(auto &[_,client] : map_id_client) { pt::ptree node; @@ -109,34 +112,36 @@ void save_devices() { nodes.push_back(std::make_pair(""s, node)); } - pt::write_json(config::nvhttp.file_devices, root); + pt::write_json(config::nvhttp.file_state, root); } -void load_devices() { - auto file_devices = fs::current_path() / config::nvhttp.file_devices; +void load_state() { + auto file_state = fs::current_path() / config::nvhttp.file_state; - if(!fs::exists(file_devices)) { + if(!fs::exists(file_state)) { + unique_id = util::uuid_t::generate().string(); return; } pt::ptree root; try { - pt::read_json(config::nvhttp.file_devices, root); + pt::read_json(config::nvhttp.file_state, root); } catch (std::exception &e) { BOOST_LOG(warning) << e.what(); return; } - auto nodes = root.get_child("root.devices"); + unique_id = root.get("root.uniqueid"); + auto device_nodes = root.get_child("root.devices"); - for(auto &[_,node] : nodes) { - auto uniqID = node.get("uniqueid"); + for(auto &[_,device_node] : device_nodes) { + auto uniqID = device_node.get("uniqueid"); auto &client = map_id_client.emplace(uniqID, client_t {}).first->second; client.uniqueID = uniqID; - for(auto &[_, el] : node.get_child("certs")) { + for(auto &[_, el] : device_node.get_child("certs")) { client.certs.emplace_back(el.get_value()); } } @@ -156,7 +161,7 @@ void update_id_client(const std::string &uniqueID, std::string &&cert, op_e op) break; } - save_devices(); + save_state(); } void getservercert(pair_session_t &sess, pt::ptree &tree, const std::string &pin) { @@ -436,7 +441,7 @@ void serverinfo(std::shared_ptr::Response> res tree.put("root.appversion", VERSION); tree.put("root.GfeVersion", GFE_VERSION); - tree.put("root.uniqueid", config::nvhttp.unique_id); + tree.put("root.uniqueid", unique_id); tree.put("root.mac", "00:00:00:00:00:00"); tree.put("root.MaxLumaPixelsHEVC", config::video.hevc_mode > 0 ? "1869449984" : "0"); tree.put("root.LocalIP", local_ip); @@ -658,7 +663,7 @@ void start(std::shared_ptr> shutdown_event) { std::abort(); } - load_devices(); + load_state(); conf_intern.pkey = read_file(config::nvhttp.pkey.c_str()); conf_intern.servercert = read_file(config::nvhttp.cert.c_str()); diff --git a/sunshine/uuid.h b/sunshine/uuid.h index 19b8fa1f..01fad1d6 100644 --- a/sunshine/uuid.h +++ b/sunshine/uuid.h @@ -7,6 +7,7 @@ #include +namespace util { union uuid_t { std::uint8_t b8[16]; std::uint16_t b16[8]; @@ -17,7 +18,7 @@ union uuid_t { std::uniform_int_distribution dist(0, std::numeric_limits::max()); uuid_t buf; - for(auto &el : buf.b8) { + for (auto &el : buf.b8) { el = dist(engine); } @@ -30,11 +31,38 @@ union uuid_t { static uuid_t generate() { std::random_device r; - std::default_random_engine engine { r() }; + std::default_random_engine engine{r()}; return generate(engine); } + [[nodiscard]] std::string string() const { + std::string result; + + result.reserve(sizeof(uuid_t) * 2 + 4); + + auto hex = util::hex(*this, true); + auto hex_view = hex.to_string_view(); + + std::string_view slices[] = { + hex_view.substr(0, 8), + hex_view.substr(8, 4), + hex_view.substr(12, 4), + hex_view.substr(16, 4) + }; + auto last_slice = hex_view.substr(20, 12); + + for(auto &slice : slices) { + std::copy(std::begin(slice), std::end(slice), std::back_inserter(result)); + + result.push_back('-'); + } + + std::copy(std::begin(last_slice), std::end(last_slice), std::back_inserter(result)); + + return result; + } + constexpr bool operator==(const uuid_t &other) const { return b64[0] == other.b64[0] && b64[1] == other.b64[1]; } @@ -47,4 +75,5 @@ union uuid_t { return (b64[0] > other.b64[0] || (b64[0] == other.b64[0] && b64[1] > other.b64[1])); } }; +} #endif //T_MAN_UUID_H