From 2f89d85fca400a5f077d13b45d55cfcfe93d31eb Mon Sep 17 00:00:00 2001 From: Yukino Song Date: Wed, 28 May 2025 22:47:51 +0800 Subject: [PATCH] Add legacy ordering support toggle for each client --- src/confighttp.cpp | 13 ++++- src/crypto.h | 2 + src/nvhttp.cpp | 30 ++++++++--- src/nvhttp.h | 4 +- src_assets/common/assets/web/pin.html | 50 ++++++++++++++++--- .../assets/web/public/assets/locale/en.json | 6 ++- .../assets/web/public/assets/locale/zh.json | 6 ++- 7 files changed, 94 insertions(+), 17 deletions(-) diff --git a/src/confighttp.cpp b/src/confighttp.cpp index fb9599d3..a2f0bcd3 100644 --- a/src/confighttp.cpp +++ b/src/confighttp.cpp @@ -867,10 +867,21 @@ namespace confighttp { std::string uuid = input_tree.value("uuid", ""); std::string name = input_tree.value("name", ""); std::string display_mode = input_tree.value("display_mode", ""); + bool enable_legacy_ordering = input_tree.value("enable_legacy_ordering", true); + bool allow_client_commands = input_tree.value("allow_client_commands", true); auto do_cmds = nvhttp::extract_command_entries(input_tree, "do"); auto undo_cmds = nvhttp::extract_command_entries(input_tree, "undo"); auto perm = static_cast(input_tree.value("perm", static_cast(crypto::PERM::_no)) & static_cast(crypto::PERM::_all)); - output_tree["status"] = nvhttp::update_device_info(uuid, name, display_mode, do_cmds, undo_cmds, perm); + output_tree["status"] = nvhttp::update_device_info( + uuid, + name, + display_mode, + do_cmds, + undo_cmds, + perm, + enable_legacy_ordering, + allow_client_commands + ); send_response(response, output_tree); } catch (std::exception &e) { BOOST_LOG(warning) << "Update Client: "sv << e.what(); diff --git a/src/crypto.h b/src/crypto.h index c854f737..3cff172c 100644 --- a/src/crypto.h +++ b/src/crypto.h @@ -104,6 +104,8 @@ namespace crypto { std::list do_cmds; std::list undo_cmds; PERM perm; + bool enable_legacy_ordering; + bool allow_client_commands; }; using p_named_cert_t = std::shared_ptr; diff --git a/src/nvhttp.cpp b/src/nvhttp.cpp index 032f0232..af8399c1 100644 --- a/src/nvhttp.cpp +++ b/src/nvhttp.cpp @@ -248,6 +248,9 @@ namespace nvhttp { named_cert_node["uuid"] = named_cert_p->uuid; named_cert_node["display_mode"] = named_cert_p->display_mode; named_cert_node["perm"] = static_cast(named_cert_p->perm); + named_cert_node["enable_legacy_ordering"] = named_cert_p->enable_legacy_ordering; + named_cert_node["allow_client_commands"] = named_cert_p->allow_client_commands; + // Add "do" commands if available. if (!named_cert_p->do_cmds.empty()) { @@ -324,6 +327,8 @@ namespace nvhttp { named_cert_p->uuid = uuid_util::uuid_t::generate().string(); named_cert_p->display_mode = ""; named_cert_p->perm = PERM::_all; + named_cert_p->enable_legacy_ordering = true; + named_cert_p->allow_client_commands = true; client.named_devices.emplace_back(named_cert_p); } } @@ -339,6 +344,8 @@ namespace nvhttp { named_cert_p->uuid = el.value("uuid", ""); named_cert_p->display_mode = el.value("display_mode", ""); named_cert_p->perm = (PERM)(util::get_non_string_json_value(el, "perm", (uint32_t)PERM::_all)) & PERM::_all; + named_cert_p->enable_legacy_ordering = el.value("enable_legacy_ordering", true); + named_cert_p->allow_client_commands = el.value("allow_client_commands", true); // Load command entries for "do" and "undo" keys. named_cert_p->do_cmds = extract_command_entries(el, "do"); named_cert_p->undo_cmds = extract_command_entries(el, "undo"); @@ -1009,6 +1016,8 @@ namespace nvhttp { named_cert_node["uuid"] = named_cert->uuid; named_cert_node["display_mode"] = named_cert->display_mode; named_cert_node["perm"] = static_cast(named_cert->perm); + named_cert_node["enable_legacy_ordering"] = named_cert->enable_legacy_ordering; + named_cert_node["allow_client_commands"] = named_cert->allow_client_commands; // Add "do" commands if available if (!named_cert->do_cmds.empty()) { @@ -1073,8 +1082,9 @@ namespace nvhttp { auto app_list = proc::proc.get_apps(); + bool enable_legacy_ordering = config::sunshine.legacy_ordering && named_cert_p->enable_legacy_ordering; size_t bits; - if (config::sunshine.legacy_ordering) { + if (enable_legacy_ordering) { bits = zwpad::pad_width_for_count(app_list.size()); } @@ -1095,9 +1105,11 @@ namespace nvhttp { } } - auto app_name = app.name; - if (config::sunshine.legacy_ordering) { - zwpad::pad_for_ordering(app.name, bits, i); + std::string app_name; + if (enable_legacy_ordering) { + app_name = zwpad::pad_for_ordering(app.name, bits, i); + } else { + app_name = app.name; } pt::ptree app_node; @@ -1253,7 +1265,7 @@ namespace nvhttp { BOOST_LOG(debug) << "Resuming app [" << proc::proc.get_last_run_app_name() << "] from launch app path..."; - if (!proc::proc.allow_client_commands) { + if (!proc::proc.allow_client_commands || !named_cert_p->allow_client_commands) { launch_session->client_do_cmds.clear(); launch_session->client_undo_cmds.clear(); } @@ -1370,7 +1382,7 @@ namespace nvhttp { } auto launch_session = make_launch_session(host_audio, false, args, named_cert_p); - if (!proc::proc.allow_client_commands) { + if (!proc::proc.allow_client_commands || !named_cert_p->allow_client_commands) { launch_session->client_do_cmds.clear(); launch_session->client_undo_cmds.clear(); } @@ -1792,7 +1804,9 @@ namespace nvhttp { const std::string& display_mode, const cmd_list_t& do_cmds, const cmd_list_t& undo_cmds, - const crypto::PERM newPerm + const crypto::PERM newPerm, + const bool enable_legacy_ordering, + const bool allow_client_commands ) { find_and_udpate_session_info(uuid, name, newPerm); @@ -1806,6 +1820,8 @@ namespace nvhttp { named_cert_p->perm = newPerm; named_cert_p->do_cmds = do_cmds; named_cert_p->undo_cmds = undo_cmds; + named_cert_p->enable_legacy_ordering = enable_legacy_ordering; + named_cert_p->allow_client_commands = allow_client_commands; save_state(); return true; } diff --git a/src/nvhttp.h b/src/nvhttp.h index c2f89833..fc71ff73 100644 --- a/src/nvhttp.h +++ b/src/nvhttp.h @@ -274,6 +274,8 @@ namespace nvhttp { const std::string& display_mode, const cmd_list_t& do_cmds, const cmd_list_t& undo_cmds, - const crypto::PERM newPerm + const crypto::PERM newPerm, + const bool enable_legacy_ordering, + const bool allow_client_commands ); } // namespace nvhttp diff --git a/src_assets/common/assets/web/pin.html b/src_assets/common/assets/web/pin.html index 4fb30301..9806856e 100644 --- a/src_assets/common/assets/web/pin.html +++ b/src_assets/common/assets/web/pin.html @@ -105,6 +105,15 @@ + + +
@@ -119,8 +128,17 @@
{{ $t('pin.display_mode_override_desc') }} {{ $t('_common.learn_more') }}
+ + + -
+
{{ $t(`pin.client_${cmdType}_cmd_desc`) }} {{ $t('_common.learn_more') }}
@@ -185,6 +203,7 @@ import { createApp } from 'vue' import { initApp } from './init' import Navbar from './Navbar.vue' + import Checkbox from './Checkbox.vue' let resetOTPTimeout = null; const qrContainer = document.createElement('div'); @@ -353,7 +372,8 @@ let app = createApp({ components: { - Navbar + Navbar, + Checkbox }, inject: ['i18n'], data, @@ -497,22 +517,26 @@ if (currentEditingClient) { this.cancelEdit(currentEditingClient); } - currentEditingClient = client; client.editing = true; client.editPerm = client.perm; client.editName = client.name; + client.editAllowClientCommands = client.allow_client_commands; + client.editEnableLegacyOrdering = client.enable_legacy_ordering; client.editDisplayMode = client.display_mode; client.edit_do = JSON.parse(JSON.stringify(client.do || [])); client.edit_undo = JSON.parse(JSON.stringify(client.undo || [])); + currentEditingClient = client; console.log(client.do, client.undo) }, cancelEdit(client) { + currentEditingClient = null; client.editing = false; client.editPerm = client.perm; client.editName = client.name; client.editDisplayMode = client.display_mode; - currentEditingClient = null; + client.editAllowClientCommands = client.allow_client_commands; + client.editEnableLegacyOrdering = client.enable_legacy_ordering; }, saveClient(client) { client.editing = false; @@ -521,6 +545,8 @@ uuid: client.uuid, name: client.editName, display_mode: client.editDisplayMode.trim(), + allow_client_commands: client.editAllowClientCommands, + enable_legacy_ordering: client.editEnableLegacyOrdering, perm: client.editPerm & permissionMapping._all, do: client.edit_do.reduce((filtered, {cmd: _cmd, elevated}) => { const cmd = _cmd.trim() @@ -643,7 +669,17 @@ .then((response) => { if (response.status && response.named_certs && response.named_certs.length) { this.platform = response.platform - this.clients = response.named_certs.map(({name, uuid, display_mode, perm, connected, do: _do, undo}) => { + this.clients = response.named_certs.map(({ + name, + uuid, + display_mode, + perm, + connected, + do: _do, + undo, + allow_client_commands, + enable_legacy_ordering + }) => { const permInt = parseInt(perm, 10); return { name, @@ -653,7 +689,9 @@ connected, editing: false, do: _do, - undo + undo, + allow_client_commands, + enable_legacy_ordering } }) currentEditingClient = null; diff --git a/src_assets/common/assets/web/public/assets/locale/en.json b/src_assets/common/assets/web/public/assets/locale/en.json index ffb0b6f0..40e1329d 100644 --- a/src_assets/common/assets/web/public/assets/locale/en.json +++ b/src_assets/common/assets/web/public/assets/locale/en.json @@ -307,7 +307,7 @@ "lan_encryption_mode_2": "Required for all clients", "lan_encryption_mode_desc": "This determines when encryption will be used when streaming over your local network. Encryption can reduce streaming performance, particularly on less powerful hosts and clients.", "legacy_ordering": "App ordering for legacy clients", - "legacy_ordering_desc": "Enable ordering support workaround for legacy clients. Can cause issues with clients or scripts that can't handle UTF8 correctly.", + "legacy_ordering_desc": "Enable ordering support workaround for legacy clients. Can cause issues with clients or scripts that can't handle UTF8 correctly. Artemis clients support this by default.", "limit_framerate": "Limit capture framerate", "limit_framerate_desc": "Limit the framerate being captured to client requested framerate. May not run at full framerate if vsync is enabled and display refreshrate does not match requested framerate. Could cause lag on some clients if disabled.", "locale": "Locale", @@ -497,6 +497,8 @@ "launch": "Launch Apps" }, "pin": { + "allow_client_commands": "Allow client commands", + "allow_client_commands_desc": "Allow client commands to be executed when connecting to this device.", "client_do_cmd": "Client connect commands", "client_do_cmd_desc": "Commands to be executed when client connects. All of the commands are executed detached.", "client_undo_cmd": "Client disconnect commands", @@ -505,6 +507,8 @@ "display_mode_override": "Display Mode Override", "display_mode_override_desc": "Apollo will ignore client requested display mode and use this value to configure (virtual) displays. Leave blank for auto matching. Format: [Width]x[Height]x[FPS]", "display_mode_override_error": "Invalid mode override. Format: [Width]x[Height]x[FPS]", + "enable_legacy_ordering": "Enable legacy ordering", + "enable_legacy_ordering_desc": "Enable app ordering for legacy clients. Disable if this client can't handle UTF8 correctly. Needs to enable \"App ordering for legacy clients\" in the Advanced settings.", "pair_failure": "Pairing Failed: Check if the PIN is typed correctly", "pair_success": "Success! Please check Moonlight to continue", "pair_success_check_perm": "Pair success! Please grant necessary permissions to the client manually below.", diff --git a/src_assets/common/assets/web/public/assets/locale/zh.json b/src_assets/common/assets/web/public/assets/locale/zh.json index 7df9b9f2..94bf62ff 100644 --- a/src_assets/common/assets/web/public/assets/locale/zh.json +++ b/src_assets/common/assets/web/public/assets/locale/zh.json @@ -302,7 +302,7 @@ "lan_encryption_mode_2": "强制所有客户端使用", "lan_encryption_mode_desc": "这将决定在本地网络上进行流媒体传输时何时使用加密。加密会降低流媒体性能,尤其是在功能较弱的主机和客户端上。", "legacy_ordering": "过时客户端 APP 排序支持", - "legacy_ordering_desc": "启用对过时客户端的 APP 排序支持。可能在某些无法正确处理 UTF8 编码的客户端/脚本上导致问题。", + "legacy_ordering_desc": "启用对过时客户端的 APP 排序支持。可能在某些无法正确处理 UTF8 编码的客户端/脚本上导致问题。Artemis 客户端默认支持此功能。", "limit_framerate": "限制捕获帧率", "limit_framerate_desc": "将捕获帧率限制到客户端请求的帧率。当启用垂直同步且显示器刷新率与客户端刷新率不匹配时可能会跑不满请求的帧率。若禁用,可能会在某些客户端上导致延迟。", "locale": "本地化", @@ -490,6 +490,8 @@ "launch": "启动APP" }, "pin": { + "allow_client_commands": "允许客户端命令", + "allow_client_commands_desc": "允许客户端命令在运行此应用时执行。", "client_do_cmd": "客户端连入命令", "client_do_cmd_desc": "当此客户端连接时执行的命令。所有命令都以后台模式允许。", "client_undo_cmd": "客户端断开命令", @@ -498,6 +500,8 @@ "display_mode_override": "显示模式覆盖", "display_mode_override_desc": "Apollo 将无视客户端请求的显示参数而使用此参数来配置(虚拟)显示器。留空则自动匹配。格式: [Width]x[Height]x[FPS]", "display_mode_override_error": "无效的显示模式。格式: [Width]x[Height]x[FPS]", + "enable_legacy_ordering": "启用过时客户端 APP 排序", + "enable_legacy_ordering_desc": "启用对过时客户端的 APP 排序支持。如果此客户端无法正确处理 UTF8 编码,请禁用。需要在高级设置中启用 \"过时客户端 APP 排序支持\" 选项。", "pair_failure": "配对失败:请检查 PIN 码是否正确输入", "pair_success": "成功!请检查 Moonlight 以继续", "pair_success_check_perm": "配对成功!请在下方手动授予客户端必要的权限。",