diff --git a/launcher/app/assets/js/processbuilder.js b/launcher/app/assets/js/processbuilder.js index 79a0225..48da80e 100644 --- a/launcher/app/assets/js/processbuilder.js +++ b/launcher/app/assets/js/processbuilder.js @@ -13,17 +13,20 @@ const ConfigManager = require('./configmanager') const logger = LoggerUtil.getLogger('ProcessBuilder') /** - * SurviePote : dossiers système contenant libGL/libEGL/libvulkan (dispatch + drivers). - * Nécessaire là où dlopen ne les voit pas (ex: NixOS hors wrapper, LD_LIBRARY_PATH vide). + * SurviePote : dossiers système contenant les libs natives dlopen par le jeu + * (libGL/libEGL/libvulkan + drivers Mesa, et backends audio libasound/libpulse/libpipewire). + * Nécessaires là où dlopen ne les voit pas (ex: NixOS hors wrapper, LD_LIBRARY_PATH vide). + * Sans ça : "[LWJGL] libGL.so.1 not found in system paths" ou "Failed to open OpenAL device". * Ne retourne que des dossiers existants. Ordre : dispatch d'abord, drivers ensuite. * * @returns {Array.} Dossiers à ajouter à LD_LIBRARY_PATH pour le jeu. */ -function resolveSystemGLDirs(){ +function resolveSystemNativeDirs(){ const dirs = [] const candidates = [ '/run/opengl-driver/lib', '/run/opengl-driver-32/lib', + '/run/current-system/sw/lib', '/usr/lib/x86_64-linux-gnu', '/usr/lib64', '/usr/lib' @@ -35,11 +38,13 @@ function resolveSystemGLDirs(){ } } catch(_err) { /* ignore */ } } - // NixOS : libglvnd (dispatch libGL/libEGL) + vulkan-loader dans le store. + // NixOS : libglvnd (dispatch GL), vulkan-loader, alsa/pulse/pipewire dans le store. try { const store = fs.readdirSync('/nix/store') for(const entry of store){ - if(entry.includes('libglvnd') || entry.includes('vulkan-loader')){ + if(entry.includes('libglvnd') || entry.includes('vulkan-loader') + || entry.includes('alsa-lib') || entry.includes('pulseaudio') + || (entry.includes('pipewire') && !entry.includes('python'))){ const lib = path.join('/nix/store', entry, 'lib') if(fs.existsSync(lib) && !dirs.includes(lib)){ dirs.push(lib) @@ -50,6 +55,27 @@ function resolveSystemGLDirs(){ return dirs } +/** + * SurviePote : dossier des plugins SPA PipeWire (routage audio). + * Sans lui, OpenAL voit PipeWire mais ne peut router aucun son. + * + * @returns {string|null} Chemin spa-0.2 ou null. + */ +function resolveSpaPluginDir(){ + try { + const store = fs.readdirSync('/nix/store') + for(const entry of store){ + if(entry.includes('pipewire') && !entry.includes('python')){ + const spa = path.join('/nix/store', entry, 'lib', 'spa-0.2') + if(fs.existsSync(spa)){ + return spa + } + } + } + } catch(_err) { /* ignore */ } + return null +} + /** * Only forge and fabric are top level mod loaders. @@ -120,11 +146,18 @@ class ProcessBuilder { // Sans ça : "[LWJGL] libGL.so.1 not found in system paths" -> crash "no OpenGL context API". const gameEnv = { ...process.env } if(process.platform === 'linux'){ - const glDirs = resolveSystemGLDirs() - if(glDirs.length > 0){ + const nativeDirs = resolveSystemNativeDirs() + if(nativeDirs.length > 0){ const prev = gameEnv.LD_LIBRARY_PATH ? gameEnv.LD_LIBRARY_PATH + ':' : '' - gameEnv.LD_LIBRARY_PATH = prev + glDirs.join(':') - logger.info('Prepended GL driver dirs to LD_LIBRARY_PATH:', glDirs.join(':')) + gameEnv.LD_LIBRARY_PATH = prev + nativeDirs.join(':') + logger.info('Prepended system native dirs to LD_LIBRARY_PATH:', nativeDirs.join(':')) + } + if(!gameEnv.SPA_PLUGIN_DIR){ + const spa = resolveSpaPluginDir() + if(spa){ + gameEnv.SPA_PLUGIN_DIR = spa + logger.info('Set SPA_PLUGIN_DIR:', spa) + } } } diff --git a/shell.nix b/shell.nix index f5ebd54..4c0e61b 100644 --- a/shell.nix +++ b/shell.nix @@ -24,6 +24,10 @@ pkgs.mkShell { pango nspr nss + # Audio (backends OpenAL : ALSA/Pulse/PipeWire). + alsa-lib + pulseaudio + pipewire libxkbcommon mesa libX11