redirect: Split hard-coded Ark into separate generation function

This allows us to make profile initialisation more generic, and potentially
support more workarounds in future. For now our entry point will walk the
generator table until a profile is supported.

Signed-off-by: Ikey Doherty <ikey@solus-project.com>
This commit is contained in:
Ikey Doherty
2017-10-23 18:51:14 +01:00
parent 4001ffc814
commit c3a071e2a0
4 changed files with 154 additions and 60 deletions
+24 -60
View File
@@ -20,10 +20,12 @@
#include <string.h>
#include <sys/stat.h>
#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;
+1
View File
@@ -8,6 +8,7 @@ if with_libredirect == true
redirect_sources = [
'main.c',
'profile.c',
'profiles/ark.c',
]
main_redirect = shared_library(
+41
View File
@@ -0,0 +1,41 @@
/*
* This file is part of linux-steam-integration.
*
* Copyright © 2017 Ikey Doherty <ikey@solus-project.com>
*
* 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 <stdbool.h>
#include <stdlib.h>
#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:
*/
+88
View File
@@ -0,0 +1,88 @@
/*
* This file is part of linux-steam-integration.
*
* Copyright © 2017 Ikey Doherty <ikey@solus-project.com>
*
* 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 <stdio.h>
#include <stdlib.h>
#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:
*/