Listening on arbitrary ports now compatible with Moonlight
This commit is contained in:
+19
-8
@@ -189,34 +189,45 @@ int main(int argc, char *argv[]) {
|
|||||||
|
|
||||||
task_pool.start(1);
|
task_pool.start(1);
|
||||||
|
|
||||||
|
util::TaskPool::task_id_t force_shutdown = nullptr;
|
||||||
// Create signal handler after logging has been initialized
|
// Create signal handler after logging has been initialized
|
||||||
auto shutdown_event = mail::man->event<bool>(mail::shutdown);
|
auto shutdown_event = mail::man->event<bool>(mail::shutdown);
|
||||||
on_signal(SIGINT, [shutdown_event]() {
|
on_signal(SIGINT, [&force_shutdown, shutdown_event]() {
|
||||||
BOOST_LOG(info) << "Interrupt handler called"sv;
|
BOOST_LOG(info) << "Interrupt handler called"sv;
|
||||||
|
|
||||||
task_pool.pushDelayed([]() {
|
auto task = []() {
|
||||||
BOOST_LOG(fatal) << "10 seconds passed, yet Sunshine's still running: Forcing shutdown"sv;
|
BOOST_LOG(fatal) << "10 seconds passed, yet Sunshine's still running: Forcing shutdown"sv;
|
||||||
log_flush();
|
log_flush();
|
||||||
std::abort();
|
std::abort();
|
||||||
},
|
};
|
||||||
10s);
|
force_shutdown = task_pool.pushDelayed(task, 10s).task_id;
|
||||||
|
|
||||||
|
|
||||||
shutdown_event->raise(true);
|
shutdown_event->raise(true);
|
||||||
});
|
});
|
||||||
|
|
||||||
on_signal(SIGTERM, [shutdown_event]() {
|
on_signal(SIGTERM, [&force_shutdown, shutdown_event]() {
|
||||||
BOOST_LOG(info) << "Terminate handler called"sv;
|
BOOST_LOG(info) << "Terminate handler called"sv;
|
||||||
|
|
||||||
task_pool.pushDelayed([]() {
|
auto task = []() {
|
||||||
BOOST_LOG(fatal) << "10 seconds passed, yet Sunshine's still running: Forcing shutdown"sv;
|
BOOST_LOG(fatal) << "10 seconds passed, yet Sunshine's still running: Forcing shutdown"sv;
|
||||||
log_flush();
|
log_flush();
|
||||||
std::abort();
|
std::abort();
|
||||||
},
|
};
|
||||||
10s);
|
force_shutdown = task_pool.pushDelayed(task, 10s).task_id;
|
||||||
|
|
||||||
shutdown_event->raise(true);
|
shutdown_event->raise(true);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
auto exit_guard = util::fail_guard([&force_shutdown]() {
|
||||||
|
task_pool.cancel(force_shutdown);
|
||||||
|
|
||||||
|
std::cout << "Sunshine exited: Press enter to continue"sv << std::endl;
|
||||||
|
|
||||||
|
std::string _;
|
||||||
|
std::getline(std::cin, _);
|
||||||
|
});
|
||||||
|
|
||||||
proc::refresh(config::stream.file_apps);
|
proc::refresh(config::stream.file_apps);
|
||||||
|
|
||||||
auto deinit_guard = platf::init();
|
auto deinit_guard = platf::init();
|
||||||
|
|||||||
@@ -520,6 +520,8 @@ void serverinfo(std::shared_ptr<typename SimpleWeb::ServerBase<T>::Response> res
|
|||||||
tree.put("root.appversion", VERSION);
|
tree.put("root.appversion", VERSION);
|
||||||
tree.put("root.GfeVersion", GFE_VERSION);
|
tree.put("root.GfeVersion", GFE_VERSION);
|
||||||
tree.put("root.uniqueid", http::unique_id);
|
tree.put("root.uniqueid", http::unique_id);
|
||||||
|
tree.put("root.HttpsPort", map_port(PORT_HTTPS));
|
||||||
|
tree.put("root.ExternalPort", map_port(PORT_HTTP));
|
||||||
tree.put("root.mac", platf::get_mac_address(request->local_endpoint_address()));
|
tree.put("root.mac", platf::get_mac_address(request->local_endpoint_address()));
|
||||||
tree.put("root.MaxLumaPixelsHEVC", config::video.hevc_mode > 1 ? "1869449984" : "0");
|
tree.put("root.MaxLumaPixelsHEVC", config::video.hevc_mode > 1 ? "1869449984" : "0");
|
||||||
tree.put("root.LocalIP", request->local_endpoint_address());
|
tree.put("root.LocalIP", request->local_endpoint_address());
|
||||||
@@ -673,6 +675,7 @@ void launch(bool &host_audio, resp_https_t response, req_https_t request) {
|
|||||||
stream::launch_session_raise(make_launch_session(host_audio, args));
|
stream::launch_session_raise(make_launch_session(host_audio, args));
|
||||||
|
|
||||||
tree.put("root.<xmlattr>.status_code", 200);
|
tree.put("root.<xmlattr>.status_code", 200);
|
||||||
|
tree.put("root.sessionUrl0", "rtspru://"s + request->local_endpoint_address() + ':' + std::to_string(map_port(stream::RTSP_SETUP_PORT)));
|
||||||
tree.put("root.gamesession", 1);
|
tree.put("root.gamesession", 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -718,6 +721,7 @@ void resume(bool &host_audio, resp_https_t response, req_https_t request) {
|
|||||||
stream::launch_session_raise(make_launch_session(host_audio, args));
|
stream::launch_session_raise(make_launch_session(host_audio, args));
|
||||||
|
|
||||||
tree.put("root.<xmlattr>.status_code", 200);
|
tree.put("root.<xmlattr>.status_code", 200);
|
||||||
|
tree.put("root.sessionUrl0", "rtspru://"s + request->local_endpoint_address() + ':' + std::to_string(map_port(stream::RTSP_SETUP_PORT)));
|
||||||
tree.put("root.resume", 1);
|
tree.put("root.resume", 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+25
-6
@@ -328,10 +328,11 @@ void cmd_describe(rtsp_server_t *server, net::peer_t peer, msg_t &&req) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void cmd_setup(rtsp_server_t *server, net::peer_t peer, msg_t &&req) {
|
void cmd_setup(rtsp_server_t *server, net::peer_t peer, msg_t &&req) {
|
||||||
OPTION_ITEM options[2] {};
|
OPTION_ITEM options[3] {};
|
||||||
|
|
||||||
auto &seqn = options[0];
|
auto &seqn = options[0];
|
||||||
auto &session_option = options[1];
|
auto &session_option = options[1];
|
||||||
|
auto &port_option = options[2];
|
||||||
|
|
||||||
seqn.option = const_cast<char *>("CSeq");
|
seqn.option = const_cast<char *>("CSeq");
|
||||||
|
|
||||||
@@ -343,18 +344,36 @@ void cmd_setup(rtsp_server_t *server, net::peer_t peer, msg_t &&req) {
|
|||||||
auto end = std::find(begin, std::end(target), '/');
|
auto end = std::find(begin, std::end(target), '/');
|
||||||
std::string_view type { begin, (size_t)std::distance(begin, end) };
|
std::string_view type { begin, (size_t)std::distance(begin, end) };
|
||||||
|
|
||||||
|
std::uint16_t port;
|
||||||
if(type == "audio"sv) {
|
if(type == "audio"sv) {
|
||||||
seqn.next = &session_option;
|
port = map_port(stream::AUDIO_STREAM_PORT);
|
||||||
|
|
||||||
session_option.option = const_cast<char *>("Session");
|
|
||||||
session_option.content = const_cast<char *>("DEADBEEFCAFE;timeout = 90");
|
|
||||||
}
|
}
|
||||||
else if(type != "video"sv && type != "control"sv) {
|
else if(type == "video"sv) {
|
||||||
|
port = map_port(stream::VIDEO_STREAM_PORT);
|
||||||
|
}
|
||||||
|
else if(type == "control"sv) {
|
||||||
|
port = map_port(stream::CONTROL_PORT);
|
||||||
|
}
|
||||||
|
else {
|
||||||
cmd_not_found(server->host(), peer, std::move(req));
|
cmd_not_found(server->host(), peer, std::move(req));
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
seqn.next = &session_option;
|
||||||
|
|
||||||
|
session_option.option = const_cast<char *>("Session");
|
||||||
|
session_option.content = const_cast<char *>("DEADBEEFCAFE;timeout = 90");
|
||||||
|
|
||||||
|
session_option.next = &port_option;
|
||||||
|
|
||||||
|
// Moonlight merely requires 'server_port=<port>'
|
||||||
|
auto port_value = "server_port=" + std::to_string(port);
|
||||||
|
|
||||||
|
port_option.option = const_cast<char *>("Transport");
|
||||||
|
port_option.content = port_value.data();
|
||||||
|
|
||||||
|
|
||||||
respond(server->host(), peer, &seqn, 200, "OK", req->sequenceNumber, {});
|
respond(server->host(), peer, &seqn, 200, "OK", req->sequenceNumber, {});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user