Skip to content
Open
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
130 changes: 91 additions & 39 deletions src/nvhttp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#define BOOST_BIND_GLOBAL_PLACEHOLDERS

// standard includes
#include <algorithm>
#include <chrono>
#include <filesystem>
#include <map>
Expand Down Expand Up @@ -1777,12 +1778,42 @@ namespace nvhttp {
}
}

void
launch(bool &host_audio, resp_https_t response, req_https_t request) {
print_req<SunshineHTTPS>(request);
static bool
has_required_launch_params(const args_t &args, bool require_appid) {
return args.find("rikey"s) != std::end(args)
&& args.find("rikeyid"s) != std::end(args)
&& args.find("localAudioPlayMode"s) != std::end(args)
&& (!require_appid || args.find("appid"s) != std::end(args));
}

print_request_ip<SunshineHTTPS>(request, "Launch request");
static bool
has_required_resume_params(const args_t &args) {
return args.find("rikey"s) != std::end(args)
&& args.find("rikeyid"s) != std::end(args);
}

static int
find_desktop_app_id() {
const auto &apps = proc::proc.get_apps();
auto desktop = std::find_if(std::begin(apps), std::end(apps), [](const auto &app) {
return app.image_path == "desktop" || app.name == "Desktop";
});

if (desktop == std::end(apps)) {
desktop = std::find_if(std::begin(apps), std::end(apps), [](const auto &app) {
return app.cmd.empty();
});
}

if (desktop == std::end(apps)) {
return 0;
}

return util::from_view(desktop->id);
}

void
launch_app(bool &host_audio, resp_https_t response, req_https_t request, const args_t &args, int appid) {
pt::ptree tree;
bool need_to_restore_display_state { false };
auto g = util::fail_guard([&]() {
Expand All @@ -1801,21 +1832,6 @@ namespace nvhttp {
}
});

auto args = request->parse_query_string();
if (
args.find("rikey"s) == std::end(args) ||
args.find("rikeyid"s) == std::end(args) ||
args.find("localAudioPlayMode"s) == std::end(args) ||
args.find("appid"s) == std::end(args)) {
tree.put("root.resume", 0);
tree.put("root.<xmlattr>.status_code", 400);
tree.put("root.<xmlattr>.status_message", "Missing a required launch parameter");

return;
}

auto appid = util::from_view(get_arg(args, "appid"));

auto current_appid = proc::proc.running();
if (current_appid > 0) {
tree.put("root.resume", 0);
Expand All @@ -1835,8 +1851,11 @@ namespace nvhttp {
return;
}

host_audio = util::from_view(get_arg(args, "localAudioPlayMode"));
if (args.find("localAudioPlayMode"s) != std::end(args)) {
host_audio = util::from_view(get_arg(args, "localAudioPlayMode"));
}
const auto launch_session = make_launch_session(host_audio, args);
launch_session->appid = appid;

// 获取客户端证书UUID(稳定的客户端标识符)
std::string client_cert_uuid = get_client_cert_uuid_from_request(request);
Expand Down Expand Up @@ -1877,15 +1896,13 @@ namespace nvhttp {
return;
}

if (appid > 0) {
auto err = proc::proc.execute(appid, launch_session);
if (err) {
tree.put("root.<xmlattr>.status_code", err);
tree.put("root.<xmlattr>.status_message", "Failed to start the specified application");
tree.put("root.gamesession", 0);
auto err = proc::proc.execute(appid, launch_session);
if (err) {
tree.put("root.<xmlattr>.status_code", err);
tree.put("root.<xmlattr>.status_message", "Failed to start the specified application");
tree.put("root.gamesession", 0);

return;
}
return;
}

tree.put("root.<xmlattr>.status_code", 200);
Expand Down Expand Up @@ -1916,6 +1933,35 @@ namespace nvhttp {
need_to_restore_display_state = false;
}

void
launch(bool &host_audio, resp_https_t response, req_https_t request) {
print_req<SunshineHTTPS>(request);

print_request_ip<SunshineHTTPS>(request, "Launch request");

auto args = request->parse_query_string();
if (!has_required_launch_params(args, true)) {
pt::ptree tree;
auto g = util::fail_guard([&]() {
std::ostringstream data;

pt::write_xml(data, tree);
response->write(data.str());
response->close_connection_after_response = true;
});

tree.put("root.resume", 0);
tree.put("root.<xmlattr>.status_code", 400);
tree.put("root.<xmlattr>.status_message", "Missing a required launch parameter");

return;
}

auto appid = util::from_view(get_arg(args, "appid"));

launch_app(host_audio, response, request, args, appid);
}

void
resume(bool &host_audio, resp_https_t response, req_https_t request) {
print_req<SunshineHTTPS>(request);
Expand All @@ -1941,23 +1987,28 @@ namespace nvhttp {
response->close_connection_after_response = true;
});

auto current_appid = proc::proc.running();
if (current_appid == 0) {
auto args = request->parse_query_string();
if (!has_required_resume_params(args)) {
tree.put("root.resume", 0);
tree.put("root.<xmlattr>.status_code", 503);
tree.put("root.<xmlattr>.status_message", "No running app to resume");
tree.put("root.<xmlattr>.status_code", 400);
tree.put("root.<xmlattr>.status_message", "Missing a required resume parameter");

return;
}

auto args = request->parse_query_string();
if (
args.find("rikey"s) == std::end(args) ||
args.find("rikeyid"s) == std::end(args)) {
tree.put("root.resume", 0);
tree.put("root.<xmlattr>.status_code", 400);
tree.put("root.<xmlattr>.status_message", "Missing a required resume parameter");
auto current_appid = proc::proc.running();
if (current_appid == 0) {
auto desktop_appid = find_desktop_app_id();
if (desktop_appid <= 0) {
tree.put("root.resume", 0);
tree.put("root.<xmlattr>.status_code", 404);
tree.put("root.<xmlattr>.status_message", "No running app to resume and Desktop app not found");

return;
}

g.disable();
launch_app(host_audio, response, request, args, desktop_appid);
return;
}

Expand All @@ -1969,6 +2020,7 @@ namespace nvhttp {
host_audio = util::from_view(get_arg(args, "localAudioPlayMode"));
}
const auto launch_session = make_launch_session(host_audio, args);
launch_session->appid = current_appid;

// Get client certificate UUID (stable client identifier) and store it in env
std::string client_cert_uuid = get_client_cert_uuid_from_request(request);
Expand Down
Loading