config: fix issue related to loading the settings on initial launch (#109)

This commit is contained in:
Tyler Wilding 2022-07-22 23:50:40 -04:00 committed by GitHub
parent 00f6218015
commit 2cee538376
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
13 changed files with 282 additions and 246 deletions

View file

@ -30,7 +30,6 @@
}, },
"dependencies": { "dependencies": {
"@tauri-apps/api": "^1.0.2", "@tauri-apps/api": "^1.0.2",
"svelte-navigator": "^3.1.6", "svelte-navigator": "^3.1.6"
"tauri-plugin-store-api": "github:tauri-apps/tauri-plugin-store"
} }
} }

13
src-tauri/Cargo.lock generated
View file

@ -61,7 +61,6 @@ dependencies = [
"serde_json", "serde_json",
"tauri", "tauri",
"tauri-build", "tauri-build",
"tauri-plugin-store",
] ]
[[package]] [[package]]
@ -2846,18 +2845,6 @@ dependencies = [
"tauri-utils", "tauri-utils",
] ]
[[package]]
name = "tauri-plugin-store"
version = "0.0.0"
source = "git+https://github.com/tauri-apps/tauri-plugin-store#17cf4d781c82a6c6578c472068c11136c0652d50"
dependencies = [
"log",
"serde",
"serde_json",
"tauri",
"thiserror",
]
[[package]] [[package]]
name = "tauri-runtime" name = "tauri-runtime"
version = "0.10.2" version = "0.10.2"

View file

@ -19,10 +19,6 @@ serde_json = "1.0"
serde = { version = "1.0", features = ["derive"] } serde = { version = "1.0", features = ["derive"] }
tauri = { version = "1.0.3", features = ["api-all", "devtools"] } tauri = { version = "1.0.3", features = ["api-all", "devtools"] }
[dependencies.tauri-plugin-store]
git = "https://github.com/tauri-apps/tauri-plugin-store"
#branch = "main"
[features] [features]
# by default Tauri runs in production mode # by default Tauri runs in production mode
# when `tauri dev` runs it is executed with `cargo run --no-default-features` if `devPath` is an URL # when `tauri dev` runs it is executed with `cargo run --no-default-features` if `devPath` is an URL

View file

@ -4,7 +4,6 @@
)] )]
use tauri::RunEvent; use tauri::RunEvent;
use tauri_plugin_store::PluginBuilder;
mod commands; mod commands;
use commands::close_splashscreen; use commands::close_splashscreen;
@ -14,7 +13,6 @@ use commands::copy_dir;
fn main() { fn main() {
tauri::Builder::default() tauri::Builder::default()
.plugin(PluginBuilder::default().build())
.invoke_handler(tauri::generate_handler![ .invoke_handler(tauri::generate_handler![
get_highest_simd, get_highest_simd,
open_dir, open_dir,

View file

@ -1,5 +1,5 @@
<script type="ts"> <script type="ts">
import { getGameInstallVersion, setInstallStatus } from "$lib/config"; import { launcherConfig } from "$lib/config";
import { getInternalName, SupportedGame } from "$lib/constants"; import { getInternalName, SupportedGame } from "$lib/constants";
import { launchGame } from "$lib/launch"; import { launchGame } from "$lib/launch";
import { openDir } from "$lib/rpc/commands"; import { openDir } from "$lib/rpc/commands";
@ -15,7 +15,7 @@ import { createEventDispatcher, onMount } from "svelte";
let gameVersion = undefined; let gameVersion = undefined;
onMount(async () => { onMount(async () => {
gameVersion = await getGameInstallVersion(activeGame); gameVersion = await launcherConfig.getGameInstallVersion(activeGame);
configPath = await join(await configDir(), "OpenGOAL", getInternalName(activeGame)); configPath = await join(await configDir(), "OpenGOAL", getInternalName(activeGame));
componentLoaded = true; componentLoaded = true;
}); });
@ -25,7 +25,7 @@ import { createEventDispatcher, onMount } from "svelte";
} }
async function onClickUninstall() { async function onClickUninstall() {
await setInstallStatus(SupportedGame.Jak1, false); await launcherConfig.setInstallStatus(SupportedGame.Jak1, false);
dispatch('change'); dispatch('change');
} }
@ -45,7 +45,7 @@ import { createEventDispatcher, onMount } from "svelte";
{#if componentLoaded} {#if componentLoaded}
<div id="launcherControls"> <div id="launcherControls">
<button class="btn lg" on:click={onClickPlay}>Play</button> <button class="btn lg" on:click={onClickPlay}>Play</button>
<p>Game Version: {gameVersion}</p> <p class="text-shadow">Game Version: {gameVersion}</p>
<!-- TODO - when clicking decompile/compile -- show logs --> <!-- TODO - when clicking decompile/compile -- show logs -->
<div class="mt-1"> <div class="mt-1">
<button class="btn md" on:click={() => openDir(configPath)}>Settings and Saves</button> <button class="btn md" on:click={() => openDir(configPath)}>Settings and Saves</button>
@ -55,3 +55,9 @@ import { createEventDispatcher, onMount } from "svelte";
</div> </div>
</div> </div>
{/if} {/if}
<style>
.text-shadow {
text-shadow: -1px -1px 0 #000, 1px -1px 0 #000, -1px 1px 0 #000, 1px 1px 0 #000;
}
</style>

View file

@ -1,7 +1,7 @@
<script type="ts"> <script type="ts">
import { areRequirementsMet } from "$lib/config"; import { launcherConfig } from "$lib/config";
import { gameNeedsReinstall, isInstalling, ProcessLogs } from "$lib/stores/AppStore"; import { gameNeedsReinstall, isInstalling, ProcessLogs } from "$lib/stores/AppStore";
import { fullInstallation, recompileGame } from "$lib/setup/setup"; import { checkRequirements, fullInstallation, recompileGame } from "$lib/setup/setup";
// components // components
import Progress from "./Progress.svelte"; import Progress from "./Progress.svelte";
// constants // constants
@ -18,7 +18,11 @@
let requirementsMet = false; let requirementsMet = false;
onMount(async () => { onMount(async () => {
requirementsMet = await areRequirementsMet(); // NOTE - potentially has problems if the user changes hardware
if (!(await launcherConfig.areRequirementsMet())) {
await checkRequirements();
}
requirementsMet = await launcherConfig.areRequirementsMet();
componentLoaded = true; componentLoaded = true;
}); });

View file

@ -1,5 +1,5 @@
<script> <script>
import { InstallStatus } from "../../../lib/stores/AppStore"; import { InstallStatus } from "$lib/stores/AppStore";
import { tweened } from "svelte/motion"; import { tweened } from "svelte/motion";
import { cubicOut } from "svelte/easing"; import { cubicOut } from "svelte/easing";

View file

@ -1,5 +1,5 @@
<script type="ts"> <script type="ts">
import { isAVXRequirementMet, isOpenGLRequirementMet } from "$lib/config"; import { launcherConfig } from "$lib/config";
import { onMount } from "svelte"; import { onMount } from "svelte";
@ -9,8 +9,8 @@ import { onMount } from "svelte";
let isOpenGLMet = false; let isOpenGLMet = false;
onMount(async () => { onMount(async () => {
isAVXMet = await isAVXRequirementMet(); isAVXMet = await launcherConfig.isAVXRequirementMet();
isOpenGLMet = await isOpenGLRequirementMet(); isOpenGLMet = await launcherConfig.isOpenGLRequirementMet();
componentLoaded = true; componentLoaded = true;
}); });
</script> </script>

View file

@ -1,212 +1,255 @@
import { createDir, readTextFile, writeFile } from "@tauri-apps/api/fs"; import { createDir, readTextFile, writeFile } from "@tauri-apps/api/fs";
import { appDir, join } from "@tauri-apps/api/path"; import { appDir, join } from "@tauri-apps/api/path";
import { Store } from "tauri-plugin-store-api";
import { SupportedGame } from "./constants"; import { SupportedGame } from "./constants";
import { fileExists } from "./utils/file"; import { fileExists } from "./utils/file";
import { log } from "./utils/log"; import { log } from "./utils/log";
class GameConfig { interface Serializable<T> {
isInstalled: boolean = false; deserialize(input: Object): T;
version: string = null;
} }
// TODO: LINK REQUIREMENTS TO CHECK REQUIREMENTS FUNCTION TO AVOID RUNNING FUNCTION IF REQUIREMENTS ARE MET class GameConfig implements Serializable<GameConfig> {
class LauncherConfig { isInstalled: boolean = false;
version = "1.0"; version: string = null;
requirements: { avx: boolean | null; openGL: boolean | null } = {
avx: null, deserialize(json: JSON): GameConfig {
openGL: null, this.isInstalled = json["isInstalled"];
}; this.version = json["version"];
return this;
}
}
class GameRequirements implements Serializable<GameRequirements> {
avx: boolean | null = null;
openGL: boolean | null = null;
deserialize(json: JSON): GameRequirements {
this.avx = json["avx"];
this.openGL = json["openGL"];
return this;
}
}
export class LauncherConfig implements Serializable<LauncherConfig> {
version: string | null = "1.0";
requirements: GameRequirements = new GameRequirements();
games = { games = {
[SupportedGame.Jak1]: new GameConfig(), [SupportedGame.Jak1]: new GameConfig(),
[SupportedGame.Jak2]: new GameConfig(), [SupportedGame.Jak2]: new GameConfig(),
[SupportedGame.Jak3]: new GameConfig(), [SupportedGame.Jak3]: new GameConfig(),
[SupportedGame.JakX]: new GameConfig(), [SupportedGame.JakX]: new GameConfig(),
}; };
lastActiveGame: SupportedGame; lastActiveGame: SupportedGame | null;
}
const store = new Store("settings.json"); private _loaded: boolean = false;
/** deserialize(json: JSON): LauncherConfig {
* Checks the version to enable safe config operations this.version = json["version"];
* @param {*} version "<major>.<minor>" this.requirements = new GameRequirements().deserialize(
* @returns True if majors match, and expected minor greater than or equal to stored. False otherwise, or if no version can be found json["requirements"]
*/ );
async function validVersion(version: string): Promise<boolean> { this.games[SupportedGame.Jak1] = new GameConfig().deserialize(
let [major, minor] = version.split("."); json["games"][SupportedGame.Jak1]
await store.load(); );
if (!(await store.has("version"))) { this.games[SupportedGame.Jak2] = new GameConfig().deserialize(
return false; json["games"][SupportedGame.Jak2]
);
this.games[SupportedGame.Jak3] = new GameConfig().deserialize(
json["games"][SupportedGame.Jak3]
);
this.games[SupportedGame.JakX] = new GameConfig().deserialize(
json["games"][SupportedGame.JakX]
);
this.lastActiveGame = json["lastActiveGame"];
return this;
} }
let [storedMajor, storedMinor]: string[] = (await store.get("version")).split(
"."
);
if (major != storedMajor) {
return false;
}
if (parseInt(minor) < parseInt(storedMinor)) {
return false;
}
return true;
}
export async function initConfig() { private async loadConfigFromFile() {
const path = await join(await appDir(), "settings.json"); if (this._loaded) {
let configExists = await fileExists(path); return;
if (!configExists) { }
log.info("settings file not found or could not be loaded!"); const configPath = await join(await appDir(), "settings.json");
await createDir(await appDir(), { recursive: true }); const configExists = await fileExists(configPath);
if (!configExists) {
console.log(
`[Launcher]: Settings file not found at '${configPath}, initializing with defaults!`
);
await createDir(await appDir(), { recursive: true });
await writeFile({
contents: JSON.stringify(this, null, 2),
path: configPath,
});
console.log("[Launcher]: Settings file initialized");
} else {
const data = await readTextFile(configPath);
this.deserialize(JSON.parse(data));
}
this._loaded = true;
}
private async saveConfigToFile() {
if (!this._loaded) {
log.info("config not loaded when trying to save, initializing it first!");
await this.loadConfigFromFile();
return;
}
const path = await join(await appDir(), "settings.json");
await writeFile({ await writeFile({
contents: JSON.stringify(new LauncherConfig(), null, 2), contents: JSON.stringify(this, null, 2),
path: path, path: path,
}); });
log.info("settings file initialized"); log.info("settings file initialized");
} }
}
/** /**
* If a game is installed or not * Checks the version to enable safe config operations
* @param {string} supportedGame *
* @returns {Promise<boolean>} * Assumes the config has been loaded before calling to reduce boilerplate
*/ *
export async function getInstallStatus( * @param {*} version "<major>.<minor>"
supportedGame: SupportedGame * @returns True if majors match, and expected minor greater than or equal to stored. False otherwise, or if no version can be found
): Promise<boolean> { */
await store.load(); private validVersion(requiredVersion: string): boolean {
if (!(await validVersion("1.0"))) { const [requiredMajor, requiredMinor] = requiredVersion.split(".");
return false; if (this.version === null) {
} return false;
// TODO: create a proper type for gameConfigs - exists with 'LauncherConfig' }
const gameConfigs: object = await store.get("games"); const [storedMajor, storedMinor] = this.version.split(".");
if (gameConfigs == null || !(supportedGame in gameConfigs)) { if (requiredMajor != storedMajor) {
return false; return false;
} }
return gameConfigs[supportedGame].isInstalled; if (parseInt(requiredMinor) < parseInt(storedMinor)) {
} return false;
}
/**
* The last game that was considered active in the launcher
* @returns {Promise<SupportedGame | null>}
*/
export async function getLastActiveGame(): Promise<SupportedGame> {
await store.load();
if (!(await validVersion("1.0"))) {
return null;
}
const lastActiveGame: SupportedGame = await store.get("lastActiveGame");
return lastActiveGame;
}
/**
* @param {string} supportedGame
* @param {boolean} installed
* @returns
*/
export async function setInstallStatus(
supportedGame: SupportedGame,
installed: boolean
): Promise<void> {
await store.load();
if (!(await validVersion("1.0"))) {
return;
}
// TODO: create a proper type for gameConfigs - 'LauncherConfig'
let gameConfigs: object = await store.get("games");
// NOTE: Do we need this conditional? Considering we generate the store file this condition should never happen.
if (gameConfigs == null || !(supportedGame in gameConfigs)) {
return;
}
gameConfigs[supportedGame].isInstalled = installed;
await store.set("games", gameConfigs);
await store.save();
}
export async function setRequirementsMet(
avx: boolean = null,
openGL: boolean = null
) {
await store.load();
await store.set("requirements", { avx, openGL });
await store.save();
return;
}
/**
* Checks the user config file to see if avx and openGL requirements are met.
*/
export async function areRequirementsMet(): Promise<boolean> {
if ((await isAVXRequirementMet()) && (await isOpenGLRequirementMet())) {
return true; return true;
} }
return false;
}
export async function isAVXRequirementMet(): Promise<boolean> { // GETTERS
await store.load();
let requirements = await store.get("requirements");
if (!requirements["avx"]) {
log.error("requirement false - AVX unsupported");
return false;
}
return true;
}
export async function isOpenGLRequirementMet(): Promise<boolean> { /**
await store.load(); * If a game is installed or not
let requirements = await store.get("requirements"); * @param {string} supportedGame
if (!requirements["openGL"]) { * @returns {Promise<boolean>}
log.error("requirement false - OpenGL unsupported"); */
return false; async getInstallStatus(supportedGame: SupportedGame): Promise<boolean> {
} await this.loadConfigFromFile();
return true; if (!this.validVersion("1.0")) {
} return false;
}
export async function getGameInstallVersion( const gameConfigs = this.games;
game: SupportedGame if (gameConfigs === null || !(supportedGame in gameConfigs)) {
): Promise<String> { return false;
// TODO - this can fail on first time startup from splash (where the config is init) }
// no idea why yet return gameConfigs[supportedGame].isInstalled;
await store.load();
let games: GameConfig = await store.get("games");
const { version } = games[game];
return version;
}
export async function setGameInstallVersion(game: SupportedGame) {
const version = await getLatestToolsVersion();
await store.load();
let games: GameConfig = await store.get("games");
games[game].version = version;
await store.set("games", games);
return await store.save();
}
export async function getLatestToolsVersion(): Promise<String> {
const appDirPath = await appDir();
const userMetaPath = await join(appDirPath, "data", "metadata.json");
const data = await readTextFile(userMetaPath);
const { version } = JSON.parse(data);
return version;
}
export async function shouldUpdateGameInstall(
game: SupportedGame
): Promise<Boolean> {
const installVersion = await getGameInstallVersion(game);
if (installVersion === null || installVersion === undefined) {
return false;
}
const toolsVersion = await getLatestToolsVersion();
if (installVersion === toolsVersion) {
return false;
} }
log.warn("Tools version is different than install verison", { /**
tools: toolsVersion, * The last game that was considered active in the launcher
installed: installVersion, * @returns {Promise<SupportedGame | null>}
}); */
return true; async getLastActiveGame(): Promise<SupportedGame | null> {
await this.loadConfigFromFile();
if (!this.validVersion("1.0")) {
return null;
}
return this.lastActiveGame;
}
/**
* Checks the user config file to see if avx and openGL requirements are met.
*/
async areRequirementsMet(): Promise<boolean> {
await this.loadConfigFromFile();
if (!this.validVersion("1.0")) {
return false;
}
return this.requirements.avx && this.requirements.openGL;
}
async isAVXRequirementMet(): Promise<boolean> {
await this.loadConfigFromFile();
if (!this.validVersion("1.0")) {
log.error("requirement false - AVX unsupported");
return false;
}
return this.requirements.avx;
}
async isOpenGLRequirementMet(): Promise<boolean> {
await this.loadConfigFromFile();
if (!this.validVersion("1.0")) {
log.error("requirement false - OpenGL 4.3 unsupported");
return false;
}
return this.requirements.openGL;
}
async getGameInstallVersion(game: SupportedGame): Promise<String> {
await this.loadConfigFromFile();
if (!this.validVersion("1.0")) {
return null;
}
return this.games[game].version;
}
private async getLatestProjectBinaryVersion(): Promise<string | null> {
// TODO - make a LauncherMetadata class similar to this
const appDirPath = await appDir();
const userMetaPath = await join(appDirPath, "data", "metadata.json");
// TODO - ensure it exists!
const data = await readTextFile(userMetaPath);
const { version } = JSON.parse(data);
return version;
}
async shouldUpdateGameInstall(game: SupportedGame): Promise<Boolean> {
const installVersion = await this.getGameInstallVersion(game);
if (installVersion === null || installVersion === undefined) {
return false;
}
const toolsVersion = await this.getLatestProjectBinaryVersion();
if (installVersion === toolsVersion) {
return false;
}
log.warn("Tools version is different than install verison", {
tools: toolsVersion,
installed: installVersion,
});
return true;
}
// SETTERS
/**
* @param {string} supportedGame
* @param {boolean} installed
* @returns
*/
async setInstallStatus(
supportedGame: SupportedGame,
installed: boolean
): Promise<void> {
this.games[supportedGame].isInstalled = installed;
await this.saveConfigToFile();
}
async setRequirementsMet(
avx: boolean = null,
openGL: boolean = null
): Promise<void> {
this.requirements.avx = avx;
this.requirements.openGL = openGL;
await this.saveConfigToFile();
}
async setGameInstallVersion(game: SupportedGame) {
const version = await this.getLatestProjectBinaryVersion();
this.games[game].version = version;
await this.saveConfigToFile();
}
} }
// Initialize with defaults
export let launcherConfig: LauncherConfig = new LauncherConfig();

View file

@ -5,13 +5,10 @@ import { getHighestSimd } from "$lib/rpc/commands";
import { InstallStatus, isInstalling } from "../stores/AppStore"; import { InstallStatus, isInstalling } from "../stores/AppStore";
import { SETUP_ERROR, SETUP_SUCCESS, SupportedGame } from "$lib/constants"; import { SETUP_ERROR, SETUP_SUCCESS, SupportedGame } from "$lib/constants";
import { filePrompt } from "$lib/utils/file"; import { filePrompt } from "$lib/utils/file";
import { import { launcherConfig } from "$lib/config";
setGameInstallVersion,
setInstallStatus,
setRequirementsMet,
} from "../config";
import { resolveErrorCode } from "./setup_errors"; import { resolveErrorCode } from "./setup_errors";
import { installLog, log } from "$lib/utils/log"; import { installLog, log } from "$lib/utils/log";
import { ProcessLogs } from "$lib/stores/AppStore";
let sidecarOptions = {}; let sidecarOptions = {};
@ -27,7 +24,7 @@ export async function isAVXSupported() {
if (highestSIMD.toLowerCase().startsWith("avx")) { if (highestSIMD.toLowerCase().startsWith("avx")) {
return true; return true;
} }
throw new Error("UNSUPPORTED AVX"); return false;
} }
/** /**
@ -38,7 +35,8 @@ export async function isOpenGLVersionSupported(
version: string version: string
): Promise<boolean> { ): Promise<boolean> {
if ((await os.platform()) === "darwin") { if ((await os.platform()) === "darwin") {
throw new Error("Unsupported OS!"); // TODO - log!
return false;
} }
// Otherwise, query for the version // Otherwise, query for the version
let command = Command.sidecar("bin/glewinfo", ["-version", version]); let command = Command.sidecar("bin/glewinfo", ["-version", version]);
@ -47,21 +45,22 @@ export async function isOpenGLVersionSupported(
return true; return true;
} }
log.error("opengl requirement check failed", { log.error("opengl requirement check failed", {
version: version,
statusCode: output.code, statusCode: output.code,
stdout: output.stdout, stdout: output.stdout,
stderr: output.stderr, stderr: output.stderr,
}); });
throw new Error("UNSUPPORTED OPENGL VERSION"); return false;
} }
export async function checkRequirements(): Promise<Boolean> { export async function checkRequirements(): Promise<void> {
try { try {
await isAVXSupported(); const isAVX = await isAVXSupported();
await isOpenGLVersionSupported("4.3"); const isOpenGL = await isOpenGLVersionSupported("4.3");
await setRequirementsMet(true, true); console.log(`avx - ${isAVX} opengl - ${isOpenGL}`);
return true; await launcherConfig.setRequirementsMet(isAVX, isOpenGL);
} catch (err) { } catch (err) {
return false; await launcherConfig.setRequirementsMet(false, false);
} }
} }
@ -109,11 +108,13 @@ export async function extractAndValidateISO(
installLog.info(output.stdout, { installLog.info(output.stdout, {
game: SupportedGame.Jak1, game: SupportedGame.Jak1,
}); });
ProcessLogs.update((currLogs) => currLogs + output.stdout);
} }
if (output.stderr) { if (output.stderr) {
installLog.error(output.stderr, { installLog.error(output.stderr, {
game: SupportedGame.Jak1, game: SupportedGame.Jak1,
}); });
ProcessLogs.update((currLogs) => currLogs + output.stderr);
} }
if (output.code === 0) { if (output.code === 0) {
return true; return true;
@ -143,11 +144,13 @@ export async function decompileGameData(filePath: string): Promise<boolean> {
installLog.info(output.stdout, { installLog.info(output.stdout, {
game: SupportedGame.Jak1, game: SupportedGame.Jak1,
}); });
ProcessLogs.update((currLogs) => currLogs + output.stdout);
} }
if (output.stderr) { if (output.stderr) {
installLog.error(output.stderr, { installLog.error(output.stderr, {
game: SupportedGame.Jak1, game: SupportedGame.Jak1,
}); });
ProcessLogs.update((currLogs) => currLogs + output.stderr);
} }
if (output.code === 0) { if (output.code === 0) {
return true; return true;
@ -175,11 +178,13 @@ export async function compileGame(filePath: string): Promise<Boolean> {
installLog.info(output.stdout, { installLog.info(output.stdout, {
game: SupportedGame.Jak1, game: SupportedGame.Jak1,
}); });
ProcessLogs.update((currLogs) => currLogs + output.stdout);
} }
if (output.stderr) { if (output.stderr) {
installLog.error(output.stderr, { installLog.error(output.stderr, {
game: SupportedGame.Jak1, game: SupportedGame.Jak1,
}); });
ProcessLogs.update((currLogs) => currLogs + output.stderr);
} }
if (output.code === 0) { if (output.code === 0) {
InstallStatus.update(() => SETUP_SUCCESS.ready); InstallStatus.update(() => SETUP_SUCCESS.ready);
@ -193,12 +198,13 @@ export async function fullInstallation(game: SupportedGame): Promise<boolean> {
isInstalling.update(() => true); isInstalling.update(() => true);
try { try {
isoPath = await isoPrompt(); isoPath = await isoPrompt();
ProcessLogs.update(() => "");
await extractAndValidateISO(isoPath); await extractAndValidateISO(isoPath);
await decompileGameData(isoPath); await decompileGameData(isoPath);
await compileGame(isoPath); await compileGame(isoPath);
await setInstallStatus(game, true); await launcherConfig.setInstallStatus(game, true);
isInstalling.update(() => false); isInstalling.update(() => false);
await setGameInstallVersion(game); await launcherConfig.setGameInstallVersion(game);
return true; return true;
} catch (err) { } catch (err) {
installLog.error("unexpected error encountered", { installLog.error("unexpected error encountered", {
@ -226,7 +232,7 @@ export async function recompileGame(game: SupportedGame) {
await decompileGameData(isoPath); await decompileGameData(isoPath);
await compileGame(isoPath); await compileGame(isoPath);
// update settings.json with latest tools version from metadata.json // update settings.json with latest tools version from metadata.json
await setGameInstallVersion(game); await launcherConfig.setGameInstallVersion(game);
isInstalling.update(() => false); isInstalling.update(() => false);
} catch (err) { } catch (err) {
installLog.error("unexpected error encountered", { installLog.error("unexpected error encountered", {

View file

@ -6,4 +6,4 @@ export const InstallStatus = writable({
}); });
export const isInstalling = writable(false); export const isInstalling = writable(false);
export const gameNeedsReinstall = writable(false); export const gameNeedsReinstall = writable(false);
export const ProcessLogs = writable(); export const ProcessLogs = writable("");

View file

@ -1,6 +1,6 @@
<script> <script>
import { fade } from "svelte/transition"; import { fade } from "svelte/transition";
import { getInstallStatus, shouldUpdateGameInstall } from "$lib/config"; import { launcherConfig } from "$lib/config";
import { fromRoute, getGameTitle, SupportedGame } from "$lib/constants"; import { fromRoute, getGameTitle, SupportedGame } from "$lib/constants";
import { useParams } from "svelte-navigator"; import { useParams } from "svelte-navigator";
import GameContent from "../components/games/GameControls.svelte"; import GameContent from "../components/games/GameControls.svelte";
@ -31,7 +31,7 @@
activeGame = fromRoute($params["game_name"]); activeGame = fromRoute($params["game_name"]);
} }
isGameInstalled = await getInstallStatus(activeGame); isGameInstalled = await launcherConfig.getInstallStatus(activeGame);
// Do some checks before the user can play the game // Do some checks before the user can play the game
// First, let's see if their data directory needs updating // First, let's see if their data directory needs updating
@ -39,7 +39,7 @@
dataDirUpToDate = await isDataDirectoryUpToDate(); dataDirUpToDate = await isDataDirectoryUpToDate();
// If it's up to date we'll do the second check now, does their game need to be re-compiled? // If it's up to date we'll do the second check now, does their game need to be re-compiled?
if (dataDirUpToDate) { if (dataDirUpToDate) {
if (await shouldUpdateGameInstall(activeGame)) { if (await launcherConfig.shouldUpdateGameInstall(activeGame)) {
// await recompileGame(activeGame); // await recompileGame(activeGame);
gameNeedsReinstall.update(() => true); gameNeedsReinstall.update(() => true);
} }
@ -53,7 +53,7 @@
try { try {
await copyDataDirectory(); await copyDataDirectory();
// Now that the directory is up to date, let's see if they need to reinstall the game // Now that the directory is up to date, let's see if they need to reinstall the game
if (await shouldUpdateGameInstall(activeGame)) { if (await launcherConfig.shouldUpdateGameInstall(activeGame)) {
gameNeedsReinstall.update(() => true); gameNeedsReinstall.update(() => true);
} }
} catch (err) { } catch (err) {
@ -63,13 +63,13 @@
} }
async function updateGameState(evt) { async function updateGameState(evt) {
isGameInstalled = await getInstallStatus(activeGame); isGameInstalled = await launcherConfig.getInstallStatus(activeGame);
} }
</script> </script>
{#if componentLoaded} {#if componentLoaded}
<div class="flex-center" in:fade> <div class="flex-center" in:fade>
<h1> <h1 class="text-shadow">
{getGameTitle(activeGame)} {getGameTitle(activeGame)}
</h1> </h1>
{#if isGameInstalled && !$gameNeedsReinstall} {#if isGameInstalled && !$gameNeedsReinstall}
@ -102,3 +102,9 @@
{:else} {:else}
<!-- TODO - component library - spinner --> <!-- TODO - component library - spinner -->
{/if} {/if}
<style>
.text-shadow {
text-shadow: -1px -1px 0 #000, 1px -1px 0 #000, -1px 1px 0 #000, 1px 1px 0 #000;
}
</style>

View file

@ -1,7 +1,5 @@
<script> <script>
import { closeSplashScreen } from "$lib/rpc/commands"; import { closeSplashScreen } from "$lib/rpc/commands";
import { areRequirementsMet, initConfig } from "$lib/config";
import { checkRequirements } from "$lib/setup/setup";
import { onMount } from "svelte"; import { onMount } from "svelte";
import logo from "$assets/images/icon.webp"; import logo from "$assets/images/icon.webp";
import { copyDataDirectory, dataDirectoryExists } from "$lib/utils/data-files"; import { copyDataDirectory, dataDirectoryExists } from "$lib/utils/data-files";
@ -12,13 +10,6 @@ import { log } from "$lib/utils/log";
// Events // Events
onMount(async () => { onMount(async () => {
await initConfig();
currentStatusText = "Checking Requirements";
currentProgress = 10;
// NOTE - potentially has problems if the user changes hardware
if (!(await areRequirementsMet())) {
await checkRequirements();
}
currentStatusText = "Checking Data Files"; currentStatusText = "Checking Data Files";
currentProgress = 25; currentProgress = 25;