diff --git a/src/redirect/main.c b/src/redirect/main.c index d55ee43..3e22d4a 100644 --- a/src/redirect/main.c +++ b/src/redirect/main.c @@ -20,10 +20,12 @@ #include #include +#include "../common/common.h" #include "../common/files.h" #include "../common/log.h" #include "nica/util.h" +#include "profile.h" #include "redirect.h" /** @@ -42,6 +44,13 @@ static volatile bool lsi_override = false; */ typedef int (*lsi_open_file)(const char *p, int flags, mode_t mode); +/** + * Known profiles + */ +static lsi_profile_generator_func generators[] = { + &lsi_redirect_profile_new_ark, +}; + /** * Global storage of handles for nicer organisation. */ @@ -131,60 +140,6 @@ failed: abort(); } -/** - * Testing: Create profile for ARK: Survival Evolved - */ -static LsiRedirectProfile *lsi_redirect_profile_new_ark(char **steam_paths) -{ - LsiRedirectProfile *p = NULL; - LsiRedirect *redirect = NULL; - -#define ARK_BASE "steamapps/common/ARK/ShooterGame/Content" - static const char *def_mic_source = - ARK_BASE "/PrimalEarth/Environment/Water/Water_DepthBlur_MIC.uasset"; - static const char *def_mic_target = - ARK_BASE "/Mods/TheCenter/Assets/Mic/Water_DepthBlur_MIC.uasset"; -#undef ARK_BASE - - p = lsi_redirect_profile_new("ARK: Survival Evolved"); - if (!p) { - fputs("OUT OF MEMORY\n", stderr); - return NULL; - } - - /* For each steam path, try to create a rule for it */ - while (*steam_paths) { - char *steam_dir = *steam_paths; - autofree(char) *mic_source = NULL; - autofree(char) *mic_target = NULL; - - if (asprintf(&mic_source, "%s/%s", steam_dir, def_mic_source) < 0) { - goto failed; - } - if (asprintf(&mic_target, "%s/%s", steam_dir, def_mic_target) < 0) { - goto failed; - } - - /* Don't add a redirect if the paths don't exist. */ - redirect = lsi_redirect_new_path_replacement(mic_source, mic_target); - if (!redirect) { - goto next; - } - - lsi_redirect_profile_insert_rule(p, redirect); - next: - ++steam_paths; - } - - return p; - -failed: - /* Dead in the water.. */ - fputs("OUT OF MEMORY\n", stderr); - lsi_redirect_profile_free(p); - return NULL; -} - /** * Main entry point into this redirect module. * @@ -198,6 +153,7 @@ __attribute__((constructor)) static void lsi_redirect_init(void) lsi_redirect_init_tables(); autofree(char) *process_name = NULL; char **paths = NULL; + char **orig = NULL; process_name = lsi_get_process_name(); @@ -207,14 +163,23 @@ __attribute__((constructor)) static void lsi_redirect_init(void) } /* Grab the stam installation directories */ - paths = lsi_get_steam_paths(); + orig = paths = lsi_get_steam_paths(); - /* Temporary hack, we'll make this more generic later */ - if (strcmp(process_name, "ShooterGame") == 0) { - lsi_log_set_id("ShooterGame"); - lsi_profile = lsi_redirect_profile_new_ark(paths); + /* For each path try to form a valid profile for the process name and Steam directory */ + while (*paths) { + for (size_t i = 0; i < ARRAY_SIZE(generators); i++) { + lsi_profile = generators[i](process_name, *paths); + if (lsi_profile) { + goto use_profile; + } + } + ++paths; } +use_profile: + /* Rewind path set */ + paths = orig; + if (!lsi_profile) { goto clean_array; } @@ -226,7 +191,6 @@ clean_array: /* Free them again */ if (paths) { - char **orig = paths; while (*paths) { free(*paths); ++paths; diff --git a/src/redirect/meson.build b/src/redirect/meson.build index 1b86e24..b4cd395 100644 --- a/src/redirect/meson.build +++ b/src/redirect/meson.build @@ -8,6 +8,7 @@ if with_libredirect == true redirect_sources = [ 'main.c', 'profile.c', + 'profiles/ark.c', ] main_redirect = shared_library( diff --git a/src/redirect/profile.h b/src/redirect/profile.h new file mode 100644 index 0000000..73d7d53 --- /dev/null +++ b/src/redirect/profile.h @@ -0,0 +1,41 @@ +/* + * This file is part of linux-steam-integration. + * + * Copyright © 2017 Ikey Doherty + * + * linux-steam-integration is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 + * of the License, or (at your option) any later version. + */ + +#pragma once + +#include +#include + +#include "redirect.h" + +/** + * Generator function is used to attempt creation of profiles based on the + * steam directory + */ +typedef LsiRedirectProfile *(*lsi_profile_generator_func)(char *process_name, char *steam_root); + +/** + * Profile generator for Ark survival evolved + */ +LsiRedirectProfile *lsi_redirect_profile_new_ark(char *process_name, char *steam_root); + +/* + * Editor modelines - https://www.wireshark.org/tools/modelines.html + * + * Local variables: + * c-basic-offset: 8 + * tab-width: 8 + * indent-tabs-mode: nil + * End: + * + * vi: set shiftwidth=8 tabstop=8 expandtab: + * :indentSize=8:tabSize=8:noTabs=true: + */ diff --git a/src/redirect/profiles/ark.c b/src/redirect/profiles/ark.c new file mode 100644 index 0000000..c6195e8 --- /dev/null +++ b/src/redirect/profiles/ark.c @@ -0,0 +1,88 @@ +/* + * This file is part of linux-steam-integration. + * + * Copyright © 2017 Ikey Doherty + * + * linux-steam-integration is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 + * of the License, or (at your option) any later version. + */ + +#define _GNU_SOURCE + +#include +#include + +#include "nica/util.h" +#include "profile.h" +#include "redirect.h" + +/** + * This generator function is responsible for supporting ARK: Survival Evolved + * + * Simply it redirects the executable to open the correct asset when TheCenter + * DLC is installed. + */ +LsiRedirectProfile *lsi_redirect_profile_new_ark(char *process_name, char *steam_path) +{ + LsiRedirectProfile *p = NULL; + LsiRedirect *redirect = NULL; + autofree(char) *mic_source = NULL; + autofree(char) *mic_target = NULL; + + /* TODO: Switch to not using base names.. */ + if (strcmp(process_name, "ShooterGame") != 0) { + return NULL; + } + +#define ARK_BASE "steamapps/common/ARK/ShooterGame/Content" + static const char *def_mic_source = + ARK_BASE "/PrimalEarth/Environment/Water/Water_DepthBlur_MIC.uasset"; + static const char *def_mic_target = + ARK_BASE "/Mods/TheCenter/Assets/Mic/Water_DepthBlur_MIC.uasset"; +#undef ARK_BASE + + p = lsi_redirect_profile_new("ARK: Survival Evolved"); + if (!p) { + fputs("OUT OF MEMORY\n", stderr); + return NULL; + } + + if (asprintf(&mic_source, "%s/%s", steam_path, def_mic_source) < 0) { + goto failed; + } + if (asprintf(&mic_target, "%s/%s", steam_path, def_mic_target) < 0) { + goto failed; + } + + /* Don't add a redirect if the paths don't exist. */ + redirect = lsi_redirect_new_path_replacement(mic_source, mic_target); + if (!redirect) { + goto unused; + } + + lsi_redirect_profile_insert_rule(p, redirect); + + return p; + +failed: + /* Dead in the water.. */ + fputs("OUT OF MEMORY\n", stderr); +unused: + lsi_redirect_profile_free(p); + return NULL; +} + +/* + * Editor modelines - https://www.wireshark.org/tools/modelines.html + * + * Local variables: + * c-basic-offset: 8 + * tab-width: 8 + * indent-tabs-mode: nil + * End: + * + * vi: set shiftwidth=8 tabstop=8 expandtab: + * :indentSize=8:tabSize=8:noTabs=true: + */