"Fixing" verify in the Star Citizen launcher

I've been "playing" Star Citizen (SC) for a few years now entirely on Linux, and it's been a bit of a rollercoaster. It's not officially supported on Linux, but these days it runs pretty well with Wine to the point where I get higher framerate than I do on Windows.

But, of course, something breaks everytime there's an update.

Unfortunately with the new and shiny launcher 2.0.5, the verify functionality on Linux will just spin forever without progressing. Can we either fix this or work around it to get into the game?

Stuck Launcher

When we check the launcher's logs, we see:

{ "t":"2024-10-18 19:01:24.184", "[main][info] ": "[Installer] - Verifying Star Citizen LIVE 3.24.2-live.9381373 at Z:\\mnt\\data\\Games\\star-citizen\\drive_c\\Program Files\\Roberts Space Industries\\StarCitizen"  },
{ "t":"2024-10-18 19:01:24.185", "[main][info] ": "[Installer] - Verifying permissions on Z:\\mnt\\data\\Games\\star-citizen\\drive_c\\Program Files\\Roberts Space Industries\\StarCitizen"  },
{ "t":"2024-10-18 19:01:24.373", "[main][info] ": "[Analytics] event sent : App:Verify:Start"  },
{ "t":"2024-10-18 19:01:25.406", "[main][error]": "[Installer] - Could not fix permissions on directory: Z:\\mnt\\data\\Games\\star-citizen\\drive_c\\Program Files\\Roberts Space Industries\\StarCitizen"  },
{ "t":"2024-10-18 19:02:14.247", "[main][info] ": "[API] - request: https://status.robertsspaceindustries.com/index.json"  },
{ "t":"2024-10-18 19:02:39.712", "[main][info] ": "Removing all remaining login data"  },

Right off the bat, we see that the launcher is trying to fix permissions on the installation directory, and failing. The UI should handle this gracefully, but it doesn't and so we end up spinning forever. We know our permissions are fine, so can we bypass this?

First, lets try to find where this log message is getting generated:

ag -a "Could not fix"
Binary file RSI Launcher/resources/app.asar matches.

Interesting! The launcher is an asar archive, which is a simple tar-like archive format that Electron uses to package its applications. We can extract this archive and look at the source code:

npx @electron/asar extract RSI\ Launcher/resources/app.asar output

Now we can search the extracted source code for the error message:

ag -a "Could not fix" output
output/lib/src/services/installer/installer.js
319: electron_log_1.default.error(`[Installer] - Could not fix permissions on directory: ${gameDirectory}`);

If we take a look at line 319 in output/lib/src/services/installer/installer.js, we see:

if (verify) {
    electron_log_1.default.info(`[Installer] - Verifying permissions on ${gameDirectory}`);
    try {
        await this.fixPermissions(gameDirectory);
    }
    catch (e) {
        electron_log_1.default.error(`[Installer] - Could not fix permissions on directory: ${gameDirectory}`);
        const newError = new Error(`[Installer] - Error while verifying permissions on ${gameDirectory}`);
        newError.name = 'FixPermissionsError';
        newError.stack = `${e}`;
        return this.mainWindow?.webContents.send(app_shared_1.ipcEvents.installer.INSTALLER_INSTALL_FAILED, newError);
    }
}

This tries to call a fixPermission utility, which is actually implemented as a bundled .exe:

/**
 * Attempts fixing the permissions for the game installation on a given directory
 * @param directory The directory of which to fix the permissions
 * @throws {Error}
 */
fixPermissions(directory) {
  const installerSupportExecutable = path_1.default.resolve(this.resourcesPath, this.executableName);
  const cmd = `"${installerSupportExecutable}" --fix-library-permissions "${directory}"`;
  return execPromise(cmd);
}

In theory, if this fails to run the main window should get an INSTALLER_INSTALL_FAILED event, but it doesn't seem to be doing anything with that error. Now, we know our permissions are fine, so we don't actually need any of this! We can just delete the entire if (verify) block and repackage the archive:

npx @electron/asar pack output RSI\ Launcher/resources/app.asar

Now if we restart the launcher, verification just works! The reason this stub .exe is failing is due to Powershell not being installed in our Wine prefix. We could install it, but adding another dependency to manage in our Wine prefix isn't ideal when it's only used here. This is a bit of a hack, but it works for now and we can get back to playing the game.