Implement per-client app identity

This commit is contained in:
Yukino Song
2025-01-23 18:09:43 +08:00
parent 8433eaa8b3
commit 8a20264c19
5 changed files with 50 additions and 9 deletions

View File

@@ -216,10 +216,30 @@ namespace proc {
VDISPLAY::setRenderAdapterByName(platf::from_utf8(config::video.adapter_name)); VDISPLAY::setRenderAdapterByName(platf::from_utf8(config::video.adapter_name));
} }
auto device_uuid_str = _app.use_app_identity ? _app.uuid : launch_session->unique_id; std::string device_name;
auto device_name = _app.use_app_identity ? _app.name : launch_session->device_name; std::string device_uuid_str;
uuid_util::uuid_t device_uuid;
auto device_uuid = uuid_util::uuid_t::parse(device_uuid_str); if (_app.use_app_identity) {
device_name = _app.name;
if (_app.per_client_app_identity) {
device_uuid = uuid_util::uuid_t::parse(launch_session->unique_id);
auto app_uuid = uuid_util::uuid_t::parse(_app.uuid);
// Use XOR to mix the two UUIDs
device_uuid.b64[0] ^= app_uuid.b64[0];
device_uuid.b64[1] ^= app_uuid.b64[1];
device_uuid_str = device_uuid.string();
} else {
device_uuid_str = _app.uuid;
device_uuid = uuid_util::uuid_t::parse(_app.uuid);
}
} else {
device_name = launch_session->device_name;
device_uuid_str = launch_session->unique_id;
device_uuid = uuid_util::uuid_t::parse(launch_session->unique_id);
}
memcpy(&launch_session->display_guid, &device_uuid, sizeof(GUID)); memcpy(&launch_session->display_guid, &device_uuid, sizeof(GUID));
@@ -913,6 +933,7 @@ namespace proc {
auto virtual_display = app_node.get_optional<bool>("virtual-display"s); auto virtual_display = app_node.get_optional<bool>("virtual-display"s);
auto resolution_scale_factor = app_node.get_optional<int>("scale-factor"s); auto resolution_scale_factor = app_node.get_optional<int>("scale-factor"s);
auto use_app_identity = app_node.get_optional<bool>("use-app-identity"s); auto use_app_identity = app_node.get_optional<bool>("use-app-identity"s);
auto per_client_app_identity = app_node.get_optional<bool>("per-client-app-identity");
auto allow_client_commands = app_node.get_optional<bool>("allow-client-commands"); auto allow_client_commands = app_node.get_optional<bool>("allow-client-commands");
ctx.uuid = app_uuid.value(); ctx.uuid = app_uuid.value();
@@ -988,6 +1009,7 @@ namespace proc {
ctx.virtual_display = virtual_display.value_or(false); ctx.virtual_display = virtual_display.value_or(false);
ctx.scale_factor = resolution_scale_factor.value_or(100); ctx.scale_factor = resolution_scale_factor.value_or(100);
ctx.use_app_identity = use_app_identity.value_or(false); ctx.use_app_identity = use_app_identity.value_or(false);
ctx.per_client_app_identity = per_client_app_identity.value_or(false);
ctx.allow_client_commands = allow_client_commands.value_or(true); ctx.allow_client_commands = allow_client_commands.value_or(true);
auto possible_ids = calculate_app_id(name, ctx.image_path, i++); auto possible_ids = calculate_app_id(name, ctx.image_path, i++);
@@ -1017,6 +1039,7 @@ namespace proc {
ctx.virtual_display = true; ctx.virtual_display = true;
ctx.scale_factor = 100; ctx.scale_factor = 100;
ctx.use_app_identity = false; ctx.use_app_identity = false;
ctx.per_client_app_identity = false;
ctx.allow_client_commands = false; ctx.allow_client_commands = false;
ctx.elevated = false; ctx.elevated = false;

View File

@@ -73,6 +73,7 @@ namespace proc {
bool virtual_display; bool virtual_display;
bool virtual_display_primary; bool virtual_display_primary;
bool use_app_identity; bool use_app_identity;
bool per_client_app_identity;
bool allow_client_commands; bool allow_client_commands;
int scale_factor; int scale_factor;
std::chrono::seconds exit_timeout; std::chrono::seconds exit_timeout;

View File

@@ -290,12 +290,24 @@
default="false" default="false"
></Checkbox> ></Checkbox>
<!-- use app identity --> <!-- use app identity -->
<div class="mb-3 form-check"> <Checkbox class="mb-3"
<label for="useAppIdentity" class="form-check-label">{{ $t('apps.use_app_identity') }}</label> id="useAppIdentity"
<input type="checkbox" class="form-check-input" id="useAppIdentity" v-model="editForm['use-app-identity']" label="apps.use_app_identity"
true-value="true" false-value="false" /> desc="apps.use_app_identity_desc"
<div class="form-text">{{ $t('apps.use_app_identity_desc') }}</div> v-model="editForm['use-app-identity']"
</div> true-value="true"
false-value="false"
></Checkbox>
<!-- use app identity -->
<Checkbox class="mb-3"
v-if="editForm['use-app-identity'] === 'true'"
id="perClientAppIdentity"
label="apps.per_client_app_identity"
desc="apps.per_client_app_identity_desc"
v-model="editForm['per-client-app-identity']"
true-value="true"
false-value="false"
></Checkbox>
<!-- resolution scale factor --> <!-- resolution scale factor -->
<div class="mb-3" v-if="platform === 'windows'"> <div class="mb-3" v-if="platform === 'windows'">
<label for="resolutionScaleFactor" class="form-label">{{ $t('apps.resolution_scale_factor') }}: {{editForm['scale-factor']}}%</label> <label for="resolutionScaleFactor" class="form-label">{{ $t('apps.resolution_scale_factor') }}: {{editForm['scale-factor']}}%</label>
@@ -418,6 +430,7 @@
"image-path": "", "image-path": "",
"scale-factor": "100", "scale-factor": "100",
"use-app-identity": false, "use-app-identity": false,
"per-client-app-identity": false,
"allow-client-commands": true, "allow-client-commands": true,
} }

View File

@@ -86,6 +86,8 @@
"name": "Name", "name": "Name",
"output_desc": "The file where the output of the command is stored, if it is not specified, the output is ignored", "output_desc": "The file where the output of the command is stored, if it is not specified, the output is ignored",
"output_name": "Output", "output_name": "Output",
"per-client-app-identrty": "Per Client App Identity",
"per-client-app-identity-desc": "Separate the app's identity per-client. Useful when you want different virtual display configurations on this specific app for different clients",
"run_as_desc": "This can be necessary for some applications that require administrator permissions to run properly. Might cause URL schemes to fail.", "run_as_desc": "This can be necessary for some applications that require administrator permissions to run properly. Might cause URL schemes to fail.",
"wait_all": "Continue streaming until all app processes exit", "wait_all": "Continue streaming until all app processes exit",
"wait_all_desc": "This will continue streaming until all processes started by the app have terminated. When unchecked, streaming will stop when the initial app process exits, even if other app processes are still running.", "wait_all_desc": "This will continue streaming until all processes started by the app have terminated. When unchecked, streaming will stop when the initial app process exits, even if other app processes are still running.",

View File

@@ -84,6 +84,8 @@
"name": "名称", "name": "名称",
"output_desc": "存储命令输出的文件,如果未指定,输出将被忽略", "output_desc": "存储命令输出的文件,如果未指定,输出将被忽略",
"output_name": "输出", "output_name": "输出",
"per-client-app-identrty": "按客户端区分 App 身份",
"per-client-app-identity-desc": "当你希望在使用此 App 时每个客户端都有不同的虚拟显示器组合配置时有用。",
"run_as_desc": "这可能是某些需要管理员权限才能正常运行的应用程序所必需的。可能会导致 URL schemes 无法正常启动。", "run_as_desc": "这可能是某些需要管理员权限才能正常运行的应用程序所必需的。可能会导致 URL schemes 无法正常启动。",
"wait_all": "继续串流直到所有应用进程退出", "wait_all": "继续串流直到所有应用进程退出",
"wait_all_desc": "这将继续串流直到应用程序启动的所有进程终止。 当未选中时,串流将在初始应用进程终止时停止,即使其他应用进程仍在运行。", "wait_all_desc": "这将继续串流直到应用程序启动的所有进程终止。 当未选中时,串流将在初始应用进程终止时停止,即使其他应用进程仍在运行。",