From 34164cab86e5a5a106bde956e5af04bc53747c02 Mon Sep 17 00:00:00 2001 From: Ningyuan Li Date: Thu, 3 Oct 2024 00:23:30 +0900 Subject: [PATCH] supports host name in addition to IP address --- CMakeLists.txt | 2 +- src/app/backend/pcmanager.h | 6 +- src/app/backend/pcmanager/known_hosts.c | 17 ++-- src/app/backend/pcmanager/pairing.c | 8 +- src/app/backend/pcmanager/worker/manual_add.c | 19 ++--- src/app/backend/pcmanager/worker/update.c | 85 ++++--------------- src/app/backend/pcmanager/worker/worker.h | 4 +- src/app/stream/session_worker.c | 2 +- src/app/stream/session_worker_embedded.c | 2 +- src/app/ui/launcher/add.dialog.c | 11 +-- src/app/ui/launcher/apps.controller.c | 8 +- third_party/commons | 2 +- 12 files changed, 53 insertions(+), 113 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 1ff9f5bfb..b1bbaba8c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -299,7 +299,7 @@ target_link_libraries(moonlight-lib PUBLIC commons-ss4s-modules-list commons-sps target_link_libraries(moonlight-lib PUBLIC commons-logging commons-gamecontrollerdb-updater commons-lazy commons-refcounter commons-executor commons-linked-list commons-wol commons-ini-writer commons-copyfile - commons-sockaddr) + commons-sockaddr commons-host) configure_file(src/app/config.h.in ${CMAKE_CURRENT_BINARY_DIR}/config.h @ONLY) target_include_directories(moonlight-lib PUBLIC ${CMAKE_CURRENT_BINARY_DIR}) diff --git a/src/app/backend/pcmanager.h b/src/app/backend/pcmanager.h index f6af837d9..a4cba18d3 100644 --- a/src/app/backend/pcmanager.h +++ b/src/app/backend/pcmanager.h @@ -7,6 +7,7 @@ #include "libgamestream/client.h" #include "uuidstr.h" #include "sockaddr.h" +#include "host.h" typedef struct app_t app_t; typedef struct pcmanager_t pcmanager_t; @@ -77,7 +78,7 @@ void pcmanager_unregister_listener(pcmanager_t *manager, const pcmanager_listene * @param userdata * @return */ -bool pcmanager_manual_add(pcmanager_t *manager, sockaddr_t *address, pcmanager_callback_t callback, void *userdata); +bool pcmanager_manual_add(pcmanager_t *manager, host_t *host, pcmanager_callback_t callback, void *userdata); /** * @brief Generates a PIN code, and start pairing process. @@ -133,6 +134,5 @@ bool pcmanager_send_wol(pcmanager_t *manager, const uuidstr_t *uuid, pcmanager_c * @param userdata * @return */ -int pcmanager_update_by_ip(worker_context_t *context, const char *ip, uint16_t port, bool force); +int pcmanager_update_by_host(worker_context_t *context, const char *ip, uint16_t port, bool force); -int pcmanager_update_by_addr(worker_context_t *context, sockaddr_t *addr, bool force); \ No newline at end of file diff --git a/src/app/backend/pcmanager/known_hosts.c b/src/app/backend/pcmanager/known_hosts.c index 3b770e41a..60c412e0b 100644 --- a/src/app/backend/pcmanager/known_hosts.c +++ b/src/app/backend/pcmanager/known_hosts.c @@ -80,23 +80,20 @@ void pcmanager_save_known_hosts(pcmanager_t *manager) { if (!cur->server || !cur->known) { continue; } - char address_buf[64] = {0}; const SERVER_DATA *server = cur->server; + host_t *address = host_new(server->serverInfo.address, server->extPort); + if (address == NULL) { + continue; + } ini_write_section(fp, server->uuid); ini_write_string(fp, "mac", server->mac); ini_write_string(fp, "hostname", server->hostname); - struct sockaddr *address = sockaddr_new(); - if (sockaddr_set_ip_str(address, strchr(server->serverInfo.address, ':') ? AF_INET6 : AF_INET, - server->serverInfo.address) != 0) { - free(address); - continue; - } - sockaddr_set_port(address, server->extPort); - sockaddr_to_string(address, address_buf, sizeof(address_buf)); + char address_buf[260] = {0}; + host_to_string(address, address_buf, sizeof(address_buf)); ini_write_string(fp, "address", address_buf); - free(address); + host_free(address); if (!selected_set && cur->selected) { ini_write_bool(fp, "selected", true); diff --git a/src/app/backend/pcmanager/pairing.c b/src/app/backend/pcmanager/pairing.c index 1806a2445..69e43fcde 100644 --- a/src/app/backend/pcmanager/pairing.c +++ b/src/app/backend/pcmanager/pairing.c @@ -28,13 +28,13 @@ bool pcmanager_pair(pcmanager_t *manager, const uuidstr_t *uuid, char *pin, pcma return true; } -bool pcmanager_manual_add(pcmanager_t *manager, sockaddr_t *address, pcmanager_callback_t callback, void *userdata) { - if (address == NULL) { +bool pcmanager_manual_add(pcmanager_t *manager, host_t *host, pcmanager_callback_t callback, void *userdata) { + if (host == NULL) { return false; } worker_context_t *ctx = worker_context_new(manager, NULL, callback, userdata); - ctx->arg1 = address; - pcmanager_worker_queue(manager, worker_add_by_ip, ctx); + ctx->arg1 = host; + pcmanager_worker_queue(manager, worker_add_by_host, ctx); return true; } diff --git a/src/app/backend/pcmanager/worker/manual_add.c b/src/app/backend/pcmanager/worker/manual_add.c index 6bdcaac17..8a38b53d6 100644 --- a/src/app/backend/pcmanager/worker/manual_add.c +++ b/src/app/backend/pcmanager/worker/manual_add.c @@ -1,18 +1,15 @@ +#include #include "worker.h" #include "backend/pcmanager/priv.h" -#include "errors.h" -#include "sockaddr.h" -static int updated_by_addr(worker_context_t *context, bool force); +static int updated_by_host(worker_context_t *context, bool force); -int worker_add_by_ip(worker_context_t *context) { - return updated_by_addr(context, true); +int worker_add_by_host(worker_context_t *context) { + assert(context->arg1 != NULL); + return updated_by_host(context, true); } -int worker_host_discovered(worker_context_t *context) { - return updated_by_addr(context, false); -} - -int updated_by_addr(worker_context_t *context, bool force) { - return pcmanager_update_by_addr(context, context->arg1, force); +int updated_by_host(worker_context_t *context, bool force) { + const host_t *host = context->arg1; + return pcmanager_update_by_host(context, host_get_hostname(host), host_get_port(host), force); } diff --git a/src/app/backend/pcmanager/worker/update.c b/src/app/backend/pcmanager/worker/update.c index b769767b4..24ff3475e 100644 --- a/src/app/backend/pcmanager/worker/update.c +++ b/src/app/backend/pcmanager/worker/update.c @@ -1,7 +1,6 @@ #include "worker.h" #include "backend/pcmanager/priv.h" #include "backend/pcmanager/pclist.h" -#include "backend/pcmanager/listeners.h" #include @@ -11,91 +10,39 @@ #include "logging.h" #include "ui/fatal_error.h" -static void notify_querying(pclist_update_context_t *args); - int worker_host_update(worker_context_t *context) { const pclist_t *node = pcmanager_node(context->manager, &context->uuid); if (node == NULL) { return GS_FAILED; } - return pcmanager_update_by_ip(context, node->server->serverInfo.address, node->server->extPort, true); -} - -int pcmanager_update_by_ip(worker_context_t *context, const char *ip, uint16_t port, bool force) { - return 0; + return pcmanager_update_by_host(context, node->server->serverInfo.address, node->server->extPort, true); } -int pcmanager_update_by_addr(worker_context_t *context, sockaddr_t *addr, bool force) { +int pcmanager_update_by_host(worker_context_t *context, const char *ip, uint16_t port, bool force) { assert(context != NULL); assert(context->manager != NULL); - assert(addr != NULL); + assert(ip != NULL); int ret = 0; + pcmanager_t *manager = context->manager; - // FIXME: Implement this - char *ip_dup = strdup(""); - pclist_t *existing = pclist_find_by_ip(manager, ip_dup); - if (existing) { - SERVER_STATE_ENUM state = existing->state.code; - if (state == SERVER_STATE_QUERYING) { - commons_log_verbose("PCManager", "Skip upsert for querying node. ip: %s", ip_dup); - goto done; - } - if (!force && state & SERVER_STATE_ONLINE) { - goto done; - } - pcmanager_lock(manager); - pclist_update_context_t args = { - .manager = manager, - .uuid = existing->id, - .state = {.code = SERVER_STATE_QUERYING}, - }; - existing->state = args.state; - pcmanager_unlock(manager); - app_bus_post_sync(context->app, (bus_actionfunc) notify_querying, &args); - } - GS_CLIENT client = app_gs_client_new(context->app); - PSERVER_DATA server = serverdata_new(); - ret = gs_get_status(client, server, ip_dup, sockaddr_get_port(addr), app_configuration->unsupported); - ip_dup = NULL; - gs_destroy(client); - if (existing) { - pcmanager_lock(manager); - bool should_remove = ret == GS_OK && !uuidstr_t_equals_s(&existing->id, server->uuid); - pcmanager_unlock(manager); - if (should_remove) { - pclist_remove(manager, &existing->id); - existing = NULL; - } else { - pcmanager_lock(manager); - existing->state.code = SERVER_STATE_NONE; - pcmanager_unlock(manager); - } - } + + // Fetch server info + GS_CLIENT client = app_gs_client_new(manager->app); + SERVER_DATA *server = serverdata_new(); + ret = gs_get_status(client, server, strdup(ip), port, app_configuration->unsupported); if (ret == GS_OK) { - commons_log_info("PCManager", "Finished updating status from %s", server->serverInfo.address); - uuidstr_t uuid; - uuidstr_fromstr(&uuid, server->uuid); SERVER_STATE state = {.code = server->paired ? SERVER_STATE_AVAILABLE : SERVER_STATE_NOT_PAIRED}; - pclist_upsert(manager, &uuid, &state, server); + pclist_upsert(manager, (const uuidstr_t *) server->uuid, &state, server); } else { - const char *gs_error = NULL; - ret = gs_get_error(&gs_error); - commons_log_warn("PCManager", "Error %d while updating status from %s: %s", ret, server->serverInfo.address, - gs_error); - context->error = gs_error != NULL ? strdup(gs_error) : NULL; - if (existing && ret == GS_IO_ERROR) { - SERVER_STATE state = {.code = SERVER_STATE_OFFLINE}; - pclist_upsert(manager, &existing->id, &state, NULL); + const char *error = NULL; + gs_get_error(&error); + if (error) { + context->error = strdup(error); } serverdata_free(server); } - done: - if (ip_dup) { - free(ip_dup); - } + gs_destroy(client); + return ret; } -static void notify_querying(pclist_update_context_t *args) { - pcmanager_listeners_notify(args->manager, &args->uuid, PCMANAGER_NOTIFY_UPDATED); -} \ No newline at end of file diff --git a/src/app/backend/pcmanager/worker/worker.h b/src/app/backend/pcmanager/worker/worker.h index c6881f397..64d8d2b12 100644 --- a/src/app/backend/pcmanager/worker/worker.h +++ b/src/app/backend/pcmanager/worker/worker.h @@ -24,9 +24,7 @@ int worker_quit_app(worker_context_t *context); int worker_wol(worker_context_t *context); -int worker_add_by_ip(worker_context_t *context); - -int worker_host_discovered(worker_context_t *context); +int worker_add_by_host(worker_context_t *context); int worker_host_update(worker_context_t *context); diff --git a/src/app/stream/session_worker.c b/src/app/stream/session_worker.c index 41918001e..1a71b16de 100644 --- a/src/app/stream/session_worker.c +++ b/src/app/stream/session_worker.c @@ -112,7 +112,7 @@ int session_worker(session_t *session) { .app = app, .manager = pcmanager, }; - pcmanager_update_by_ip(&update_ctx, server->serverInfo.address, server->extPort, true); + pcmanager_update_by_host(&update_ctx, server->serverInfo.address, server->extPort, true); // Don't always reset status as error state should be kept session_set_state(session, STREAMING_NONE); diff --git a/src/app/stream/session_worker_embedded.c b/src/app/stream/session_worker_embedded.c index 724f61c15..a8d613de3 100644 --- a/src/app/stream/session_worker_embedded.c +++ b/src/app/stream/session_worker_embedded.c @@ -103,7 +103,7 @@ int session_worker_embedded(session_t *session) { .app = app, .manager = pcmanager, }; - pcmanager_update_by_ip(&update_ctx, server->serverInfo.address, server->extPort, true); + pcmanager_update_by_host(&update_ctx, server->serverInfo.address, server->extPort, true); // Don't always reset status as error state should be kept session_set_state(session, STREAMING_NONE); diff --git a/src/app/ui/launcher/add.dialog.c b/src/app/ui/launcher/add.dialog.c index f4fc70649..c6402ac5f 100644 --- a/src/app/ui/launcher/add.dialog.c +++ b/src/app/ui/launcher/add.dialog.c @@ -99,15 +99,15 @@ static void dialog_cb(lv_event_t *event) { } uint16_t btn = lv_msgbox_get_active_btn(dialog); if (btn == 1) { - sockaddr_t *address = sockaddr_parse(lv_textarea_get_text(controller->input)); - if (!address) { + host_t *host = host_parse(lv_textarea_get_text(controller->input)); + if (!host) { return; } lv_obj_add_state(controller->btns, LV_STATE_DISABLED); lv_obj_add_state(controller->input, LV_STATE_DISABLED); lv_obj_clear_flag(controller->progress, LV_OBJ_FLAG_HIDDEN); lv_obj_add_flag(controller->error, LV_OBJ_FLAG_HIDDEN); - pcmanager_manual_add(pcmanager, address, add_cb, controller); + pcmanager_manual_add(pcmanager, host, add_cb, controller); } else { lv_msgbox_close_async(dialog); } @@ -115,9 +115,10 @@ static void dialog_cb(lv_event_t *event) { static void input_changed_cb(lv_event_t *event) { add_dialog_controller_t *controller = lv_event_get_user_data(event); - sockaddr_t *address = sockaddr_parse(lv_textarea_get_text(controller->input)); - if (address) { + host_t *host = host_parse(lv_textarea_get_text(controller->input)); + if (host) { lv_btnmatrix_clear_btn_ctrl(controller->btns, 1, LV_BTNMATRIX_CTRL_DISABLED); + host_free(host); } else { lv_btnmatrix_set_btn_ctrl(controller->btns, 1, LV_BTNMATRIX_CTRL_DISABLED); } diff --git a/src/app/ui/launcher/apps.controller.c b/src/app/ui/launcher/apps.controller.c index b1405a002..e7c46baff 100644 --- a/src/app/ui/launcher/apps.controller.c +++ b/src/app/ui/launcher/apps.controller.c @@ -319,7 +319,7 @@ static void on_host_updated(const uuidstr_t *uuid, void *userdata) { if (controller != current_instance) { return; } if (!uuidstr_t_equals_t(&controller->uuid, uuid)) { return; } const SERVER_STATE *state = pcmanager_state(pcmanager, uuid); - SDL_assert_release(state != NULL); + assert(state != NULL); if (state->code == SERVER_STATE_AVAILABLE) { apploader_load(controller->apploader); } @@ -346,7 +346,7 @@ static void send_wol_cb(int result, const char *error, const uuidstr_t *uuid, vo if (!controller->base.managed->obj_created) { return; } lv_btnmatrix_clear_btn_ctrl_all(controller->actions, LV_BTNMATRIX_CTRL_DISABLED); const SERVER_STATE *state = pcmanager_state(pcmanager, &controller->uuid); - SDL_assert_release(state != NULL); + assert(state != NULL); if (state->code & SERVER_STATE_ONLINE || result != GS_OK) { return; } pcmanager_request_update(pcmanager, &controller->uuid, host_info_cb, controller); } @@ -360,7 +360,7 @@ static void update_view_state(apps_fragment_t *controller) { lv_obj_t *appload = controller->appload; lv_obj_t *apperror = controller->apperror; const SERVER_STATE *state = pcmanager_state(pcmanager, &controller->uuid); - SDL_assert_release(state != NULL); + assert(state != NULL); switch (state->code) { case SERVER_STATE_NONE: case SERVER_STATE_QUERYING: { @@ -527,7 +527,7 @@ static void appitem_bind(apps_fragment_t *controller, lv_obj_t *item, apploader_ controller->col_width, controller->col_height); lv_label_set_text(holder->title, app->base.name); - SDL_assert_release(controller->node); + assert(controller->node); int current_id = pcmanager_node_current_app(controller->node); if (current_id == app->base.id) { lv_obj_clear_flag(holder->play_indicator, LV_OBJ_FLAG_HIDDEN); diff --git a/third_party/commons b/third_party/commons index a8c933035..c0729041b 160000 --- a/third_party/commons +++ b/third_party/commons @@ -1 +1 @@ -Subproject commit a8c93303577178a9b5a66815f031417db7fdeb1f +Subproject commit c0729041b390e2b99ce1fa79742535b8deefe3d6