mirror of
https://github.com/clearlinux/linux-steam-integration.git
synced 2026-09-06 22:01:27 +00:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
be3023263f | ||
|
|
27e5cd0ae0 | ||
|
|
79fece840c | ||
|
|
478a0f1810 | ||
|
|
2cf5db42b3 | ||
|
|
191ea02946 | ||
|
|
03dd537574 | ||
|
|
8ded405801 | ||
|
|
35b3f132fd | ||
|
|
4b718a4bc7 | ||
|
|
5ceacb27fb |
+1
-1
@@ -1,7 +1,7 @@
|
||||
project(
|
||||
'linux-steam-integration',
|
||||
['c'],
|
||||
version: '0.4.1',
|
||||
version: '0.5',
|
||||
license: [
|
||||
'LGPL-2.1',
|
||||
],
|
||||
|
||||
+1
-1
@@ -5,7 +5,7 @@ git submodule init
|
||||
git submodule update
|
||||
|
||||
# Script for ikey because he went with meson. *shrug*
|
||||
VERSION="0.4"
|
||||
VERSION="0.5"
|
||||
NAME="linux-steam-integration"
|
||||
git-archive-all.sh --format tar --prefix ${NAME}-${VERSION}/ --verbose -t HEAD ${NAME}-${VERSION}.tar
|
||||
xz -9 "${NAME}-${VERSION}.tar"
|
||||
|
||||
+165
-77
@@ -14,16 +14,101 @@
|
||||
#include <link.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include "../common.h"
|
||||
#include "nica/nica.h"
|
||||
#include "nica/util.h"
|
||||
|
||||
static inline bool lsi_file_exists(const char *path)
|
||||
{
|
||||
struct stat st = { .st_ino = 0 };
|
||||
return (lstat(path, &st) == 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Is this a process we're actually interested in?
|
||||
* What's the known process name?
|
||||
*/
|
||||
static bool process_supported = false;
|
||||
static const char *matched_process = NULL;
|
||||
|
||||
/**
|
||||
* We support a number of modes, but we mostly exist to make Steam behave
|
||||
*/
|
||||
typedef enum {
|
||||
INTERCEPT_MODE_NONE = 0,
|
||||
INTERCEPT_MODE_STEAM,
|
||||
INTERCEPT_MODE_VENDOR_OFFENDER,
|
||||
} InterceptMode;
|
||||
|
||||
/**
|
||||
* by default, we're not "on"
|
||||
*/
|
||||
static InterceptMode work_mode = INTERCEPT_MODE_NONE;
|
||||
|
||||
/* Patterns we'll permit Steam to privately load */
|
||||
static const char *steam_allowed[] = {
|
||||
/* general */
|
||||
"libicui18n.so",
|
||||
"libicuuc.so",
|
||||
"libavcodec.so.",
|
||||
"libavformat.so.",
|
||||
"libavresample.so.",
|
||||
"libavutil.so.",
|
||||
"libswscale.so.",
|
||||
|
||||
/* core plugins */
|
||||
"chromehtml.so",
|
||||
"crashhandler.so",
|
||||
"filesystem_stdio.so",
|
||||
"friendsui.so",
|
||||
"gameoverlayrenderer.so",
|
||||
"gameoverlayui.so",
|
||||
"libaudio.so",
|
||||
"libmiles.so",
|
||||
"libopenvr_api.so",
|
||||
"liboverride.so",
|
||||
"libsteam.so",
|
||||
"libtier0_s.so",
|
||||
"libv8.so",
|
||||
"libvideo.so",
|
||||
"libvstdlib_s.so",
|
||||
"serverbrowser.so",
|
||||
"steamclient.so",
|
||||
"steamoverlayvulkanlayer.so",
|
||||
"steamservice.so",
|
||||
"steamui.so",
|
||||
"vgui2_s.so",
|
||||
|
||||
/* big picture mode */
|
||||
"panorama",
|
||||
"libpangoft2-1.0.so",
|
||||
"libpango-1.0.so",
|
||||
|
||||
/* steamwebhelper */
|
||||
"libcef.so",
|
||||
};
|
||||
|
||||
static const char *wanted_steam_processes[] = {
|
||||
"html5app_steam",
|
||||
"opengl-program",
|
||||
"steam",
|
||||
"steamwebhelper",
|
||||
};
|
||||
|
||||
/**
|
||||
* Vendor offendors should not be allowed to load replacements for libraries
|
||||
* that are KNOWN to cause issues, i.e. SDL + libstdc++
|
||||
*/
|
||||
static const char *vendor_blacklist[] = {
|
||||
/* base libraries being replaced will cause a C++ ABI issue when
|
||||
* loading the mesalib drivers. */
|
||||
"libgcc_",
|
||||
"libstdc++",
|
||||
"libSDL",
|
||||
|
||||
/* general problem causer. */
|
||||
"libopenal.so.",
|
||||
};
|
||||
|
||||
/**
|
||||
* Determine the basename'd process
|
||||
*/
|
||||
@@ -42,27 +127,16 @@ static inline char *get_process_name(void)
|
||||
}
|
||||
|
||||
/**
|
||||
* Find out if we're being executed by a process we actually need to override,
|
||||
* otherwise we'd not be loaded by rtld-audit
|
||||
* Determine if we're in a given process set, i.e. the process name matches
|
||||
* the given table
|
||||
*/
|
||||
static bool is_intercept_candidate(void)
|
||||
static bool is_in_process_set(char *process_name, const char **processes, size_t n_processes)
|
||||
{
|
||||
static const char *wanted_processes[] = {
|
||||
"html5app_steam",
|
||||
"opengl-program",
|
||||
"steam",
|
||||
"steamwebhelper",
|
||||
};
|
||||
autofree(char) *nom = NULL;
|
||||
|
||||
nom = get_process_name();
|
||||
if (!nom) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < ARRAY_SIZE(wanted_processes); i++) {
|
||||
if (streq(wanted_processes[i], nom)) {
|
||||
matched_process = wanted_processes[i];
|
||||
/* Are we some portion of the process set? */
|
||||
for (size_t i = 0; i < n_processes; i++) {
|
||||
if (streq(processes[i], process_name)) {
|
||||
work_mode = INTERCEPT_MODE_STEAM;
|
||||
matched_process = processes[i];
|
||||
if (!getenv("LSI_DEBUG")) {
|
||||
return true;
|
||||
}
|
||||
@@ -75,6 +149,27 @@ static bool is_intercept_candidate(void)
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Find out if we're being executed by a process we actually need to override,
|
||||
* otherwise we'd not be loaded by rtld-audit
|
||||
*/
|
||||
static void check_is_intercept_candidate(void)
|
||||
{
|
||||
autofree(char) *nom = NULL;
|
||||
|
||||
nom = get_process_name();
|
||||
if (!nom) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (is_in_process_set(nom, wanted_steam_processes, ARRAY_SIZE(wanted_steam_processes))) {
|
||||
work_mode = INTERCEPT_MODE_STEAM;
|
||||
} else {
|
||||
work_mode = INTERCEPT_MODE_VENDOR_OFFENDER;
|
||||
matched_process = "vendor_offender";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* la_version is our main entry point and will only continue if our
|
||||
* process is explicitly Steam
|
||||
@@ -82,7 +177,7 @@ static bool is_intercept_candidate(void)
|
||||
_nica_public_ unsigned int la_version(unsigned int supported_version)
|
||||
{
|
||||
/* Unfortunately glibc will die if we tell it to skip us .. */
|
||||
process_supported = is_intercept_candidate();
|
||||
check_is_intercept_candidate();
|
||||
return supported_version;
|
||||
}
|
||||
|
||||
@@ -100,63 +195,12 @@ static void emit_overriden_lib(const char *lib_name)
|
||||
}
|
||||
|
||||
/**
|
||||
* la_objsearch will allow us to blacklist certain LD_LIBRARY_PATH duplicate
|
||||
* libraries being loaded by the Steam client, such as the broken libSDL shipped
|
||||
* as a private vendored lib
|
||||
* lsi_search_steam handles whitelisting for the main Steam processes
|
||||
*/
|
||||
_nica_public_ char *la_objsearch(const char *name, __lsi_unused__ uintptr_t *cookie,
|
||||
__lsi_unused__ unsigned int flag)
|
||||
char *lsi_search_steam(const char *name)
|
||||
{
|
||||
/* We don't know about this process, so have glibc do its thing as normal */
|
||||
if (!process_supported) {
|
||||
return (char *)name;
|
||||
}
|
||||
|
||||
/* Patterns we'll permit Steam to privately load */
|
||||
static const char *steam_allowed[] = {
|
||||
/* general */
|
||||
"libicui18n.so",
|
||||
"libicuuc.so",
|
||||
"libavcodec.so.",
|
||||
"libavformat.so.",
|
||||
"libavresample.so.",
|
||||
"libavutil.so.",
|
||||
"libswscale.so.",
|
||||
|
||||
/* core plugins */
|
||||
"chromehtml.so",
|
||||
"crashhandler.so",
|
||||
"filesystem_stdio.so",
|
||||
"friendsui.so",
|
||||
"gameoverlayrenderer.so",
|
||||
"gameoverlayui.so",
|
||||
"libaudio.so",
|
||||
"libmiles.so",
|
||||
"libopenvr_api.so",
|
||||
"liboverride.so",
|
||||
"libsteam.so",
|
||||
"libtier0_s.so",
|
||||
"libv8.so",
|
||||
"libvideo.so",
|
||||
"libvstdlib_s.so",
|
||||
"serverbrowser.so",
|
||||
"steamclient.so",
|
||||
"steamoverlayvulkanlayer.so",
|
||||
"steamservice.so",
|
||||
"steamui.so",
|
||||
"vgui2_s.so",
|
||||
|
||||
/* big picture mode */
|
||||
"panorama",
|
||||
"libpangoft2-1.0.so",
|
||||
"libpango-1.0.so",
|
||||
|
||||
/* steamwebhelper */
|
||||
"libcef.so",
|
||||
};
|
||||
|
||||
/* Find out if it exists */
|
||||
bool file_exists = nc_file_exists(name);
|
||||
bool file_exists = lsi_file_exists(name);
|
||||
|
||||
/* Find out if its a Steam private lib.. These are relative "./" files too! */
|
||||
if (name && (strstr(name, "/Steam/") || strncmp(name, "./", 2) == 0)) {
|
||||
@@ -176,6 +220,50 @@ _nica_public_ char *la_objsearch(const char *name, __lsi_unused__ uintptr_t *coo
|
||||
return (char *)name;
|
||||
}
|
||||
|
||||
char *lsi_blacklist_vendor(const char *name)
|
||||
{
|
||||
/* Find out if it exists */
|
||||
bool file_exists = lsi_file_exists(name);
|
||||
|
||||
/* Find out if its a Steam private lib.. These are relative "./" files too! */
|
||||
if (name && (strstr(name, "/Steam/") || strncmp(name, "./", 2) == 0)) {
|
||||
for (size_t i = 0; i < ARRAY_SIZE(vendor_blacklist); i++) {
|
||||
if (!strstr(name, vendor_blacklist[i])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/* If LSI_DEBUG is set, spam it. */
|
||||
if (getenv("LSI_DEBUG") && file_exists) {
|
||||
emit_overriden_lib(name);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
/* Allowed to exist */
|
||||
return (char *)name;
|
||||
}
|
||||
|
||||
return (char *)name;
|
||||
}
|
||||
|
||||
/**
|
||||
* la_objsearch will allow us to blacklist certain LD_LIBRARY_PATH duplicate
|
||||
* libraries being loaded by the Steam client, such as the broken libSDL shipped
|
||||
* as a private vendored lib
|
||||
*/
|
||||
_nica_public_ char *la_objsearch(const char *name, __lsi_unused__ uintptr_t *cookie,
|
||||
__lsi_unused__ unsigned int flag)
|
||||
{
|
||||
switch (work_mode) {
|
||||
case INTERCEPT_MODE_STEAM:
|
||||
return lsi_search_steam(name);
|
||||
case INTERCEPT_MODE_VENDOR_OFFENDER:
|
||||
return lsi_blacklist_vendor(name);
|
||||
case INTERCEPT_MODE_NONE:
|
||||
default:
|
||||
return (char *)name;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Editor modelines - https://www.wireshark.org/tools/modelines.html
|
||||
*
|
||||
|
||||
@@ -6,10 +6,26 @@ if with_libintercept == true
|
||||
'main.c',
|
||||
]
|
||||
|
||||
nica_build = static_library(
|
||||
'nica',
|
||||
sources: nica_sources,
|
||||
include_directories: nica_includes,
|
||||
)
|
||||
|
||||
link_nica = declare_dependency(
|
||||
link_with: nica_build,
|
||||
include_directories: nica_includes,
|
||||
)
|
||||
|
||||
|
||||
main_intercept = shared_library(
|
||||
'lsi-intercept',
|
||||
sources: intercept_sources + nica_sources,
|
||||
sources: intercept_sources,
|
||||
c_args: ['-fvisibility=hidden'],
|
||||
include_directories: nica_includes,
|
||||
dependencies: [
|
||||
link_nica,
|
||||
],
|
||||
install: true,
|
||||
)
|
||||
endif
|
||||
|
||||
+1
-4
@@ -44,11 +44,8 @@ int main(int argc, char **argv)
|
||||
int8_t off = 0;
|
||||
int (*vfunc)(const char *, char *const argv[]) = NULL;
|
||||
|
||||
#ifdef REPLACE_STEAM
|
||||
lsi_exec_bin = STEAM_BINARY;
|
||||
#else
|
||||
lsi_exec_bin = "/usr/bin/steam";
|
||||
#endif
|
||||
|
||||
/* Initialise config */
|
||||
if (!lsi_config_load(&config)) {
|
||||
lsi_config_load_defaults(&config);
|
||||
|
||||
Reference in New Issue
Block a user