mirror of
https://github.com/open-goal/launcher.git
synced 2024-10-20 04:57:38 -04:00
config: fix issue related to loading the settings on initial launch (#109)
This commit is contained in:
parent
00f6218015
commit
2cee538376
|
@ -30,7 +30,6 @@
|
|||
},
|
||||
"dependencies": {
|
||||
"@tauri-apps/api": "^1.0.2",
|
||||
"svelte-navigator": "^3.1.6",
|
||||
"tauri-plugin-store-api": "github:tauri-apps/tauri-plugin-store"
|
||||
"svelte-navigator": "^3.1.6"
|
||||
}
|
||||
}
|
||||
|
|
13
src-tauri/Cargo.lock
generated
13
src-tauri/Cargo.lock
generated
|
@ -61,7 +61,6 @@ dependencies = [
|
|||
"serde_json",
|
||||
"tauri",
|
||||
"tauri-build",
|
||||
"tauri-plugin-store",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -2846,18 +2845,6 @@ dependencies = [
|
|||
"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]]
|
||||
name = "tauri-runtime"
|
||||
version = "0.10.2"
|
||||
|
|
|
@ -19,10 +19,6 @@ serde_json = "1.0"
|
|||
serde = { version = "1.0", features = ["derive"] }
|
||||
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]
|
||||
# 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
|
||||
|
|
|
@ -4,7 +4,6 @@
|
|||
)]
|
||||
|
||||
use tauri::RunEvent;
|
||||
use tauri_plugin_store::PluginBuilder;
|
||||
|
||||
mod commands;
|
||||
use commands::close_splashscreen;
|
||||
|
@ -14,7 +13,6 @@ use commands::copy_dir;
|
|||
|
||||
fn main() {
|
||||
tauri::Builder::default()
|
||||
.plugin(PluginBuilder::default().build())
|
||||
.invoke_handler(tauri::generate_handler![
|
||||
get_highest_simd,
|
||||
open_dir,
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<script type="ts">
|
||||
import { getGameInstallVersion, setInstallStatus } from "$lib/config";
|
||||
import { launcherConfig } from "$lib/config";
|
||||
import { getInternalName, SupportedGame } from "$lib/constants";
|
||||
import { launchGame } from "$lib/launch";
|
||||
import { openDir } from "$lib/rpc/commands";
|
||||
|
@ -15,7 +15,7 @@ import { createEventDispatcher, onMount } from "svelte";
|
|||
let gameVersion = undefined;
|
||||
|
||||
onMount(async () => {
|
||||
gameVersion = await getGameInstallVersion(activeGame);
|
||||
gameVersion = await launcherConfig.getGameInstallVersion(activeGame);
|
||||
configPath = await join(await configDir(), "OpenGOAL", getInternalName(activeGame));
|
||||
componentLoaded = true;
|
||||
});
|
||||
|
@ -25,7 +25,7 @@ import { createEventDispatcher, onMount } from "svelte";
|
|||
}
|
||||
|
||||
async function onClickUninstall() {
|
||||
await setInstallStatus(SupportedGame.Jak1, false);
|
||||
await launcherConfig.setInstallStatus(SupportedGame.Jak1, false);
|
||||
dispatch('change');
|
||||
}
|
||||
|
||||
|
@ -45,7 +45,7 @@ import { createEventDispatcher, onMount } from "svelte";
|
|||
{#if componentLoaded}
|
||||
<div id="launcherControls">
|
||||
<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 -->
|
||||
<div class="mt-1">
|
||||
<button class="btn md" on:click={() => openDir(configPath)}>Settings and Saves</button>
|
||||
|
@ -55,3 +55,9 @@ import { createEventDispatcher, onMount } from "svelte";
|
|||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
<style>
|
||||
.text-shadow {
|
||||
text-shadow: -1px -1px 0 #000, 1px -1px 0 #000, -1px 1px 0 #000, 1px 1px 0 #000;
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<script type="ts">
|
||||
import { areRequirementsMet } from "$lib/config";
|
||||
import { launcherConfig } from "$lib/config";
|
||||
import { gameNeedsReinstall, isInstalling, ProcessLogs } from "$lib/stores/AppStore";
|
||||
import { fullInstallation, recompileGame } from "$lib/setup/setup";
|
||||
import { checkRequirements, fullInstallation, recompileGame } from "$lib/setup/setup";
|
||||
// components
|
||||
import Progress from "./Progress.svelte";
|
||||
// constants
|
||||
|
@ -18,7 +18,11 @@
|
|||
let requirementsMet = false;
|
||||
|
||||
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;
|
||||
});
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<script>
|
||||
import { InstallStatus } from "../../../lib/stores/AppStore";
|
||||
import { InstallStatus } from "$lib/stores/AppStore";
|
||||
import { tweened } from "svelte/motion";
|
||||
import { cubicOut } from "svelte/easing";
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<script type="ts">
|
||||
import { isAVXRequirementMet, isOpenGLRequirementMet } from "$lib/config";
|
||||
import { launcherConfig } from "$lib/config";
|
||||
|
||||
import { onMount } from "svelte";
|
||||
|
||||
|
@ -9,8 +9,8 @@ import { onMount } from "svelte";
|
|||
let isOpenGLMet = false;
|
||||
|
||||
onMount(async () => {
|
||||
isAVXMet = await isAVXRequirementMet();
|
||||
isOpenGLMet = await isOpenGLRequirementMet();
|
||||
isAVXMet = await launcherConfig.isAVXRequirementMet();
|
||||
isOpenGLMet = await launcherConfig.isOpenGLRequirementMet();
|
||||
componentLoaded = true;
|
||||
});
|
||||
</script>
|
||||
|
|
|
@ -1,204 +1,213 @@
|
|||
import { createDir, readTextFile, writeFile } from "@tauri-apps/api/fs";
|
||||
import { appDir, join } from "@tauri-apps/api/path";
|
||||
import { Store } from "tauri-plugin-store-api";
|
||||
import { SupportedGame } from "./constants";
|
||||
import { fileExists } from "./utils/file";
|
||||
import { log } from "./utils/log";
|
||||
|
||||
class GameConfig {
|
||||
isInstalled: boolean = false;
|
||||
version: string = null;
|
||||
interface Serializable<T> {
|
||||
deserialize(input: Object): T;
|
||||
}
|
||||
|
||||
// TODO: LINK REQUIREMENTS TO CHECK REQUIREMENTS FUNCTION TO AVOID RUNNING FUNCTION IF REQUIREMENTS ARE MET
|
||||
class LauncherConfig {
|
||||
version = "1.0";
|
||||
requirements: { avx: boolean | null; openGL: boolean | null } = {
|
||||
avx: null,
|
||||
openGL: null,
|
||||
};
|
||||
class GameConfig implements Serializable<GameConfig> {
|
||||
isInstalled: boolean = false;
|
||||
version: string = null;
|
||||
|
||||
deserialize(json: JSON): GameConfig {
|
||||
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 = {
|
||||
[SupportedGame.Jak1]: new GameConfig(),
|
||||
[SupportedGame.Jak2]: new GameConfig(),
|
||||
[SupportedGame.Jak3]: new GameConfig(),
|
||||
[SupportedGame.JakX]: new GameConfig(),
|
||||
};
|
||||
lastActiveGame: SupportedGame;
|
||||
}
|
||||
lastActiveGame: SupportedGame | null;
|
||||
|
||||
const store = new Store("settings.json");
|
||||
private _loaded: boolean = false;
|
||||
|
||||
/**
|
||||
* Checks the version to enable safe config operations
|
||||
* @param {*} version "<major>.<minor>"
|
||||
* @returns True if majors match, and expected minor greater than or equal to stored. False otherwise, or if no version can be found
|
||||
*/
|
||||
async function validVersion(version: string): Promise<boolean> {
|
||||
let [major, minor] = version.split(".");
|
||||
await store.load();
|
||||
if (!(await store.has("version"))) {
|
||||
return false;
|
||||
}
|
||||
let [storedMajor, storedMinor]: string[] = (await store.get("version")).split(
|
||||
"."
|
||||
deserialize(json: JSON): LauncherConfig {
|
||||
this.version = json["version"];
|
||||
this.requirements = new GameRequirements().deserialize(
|
||||
json["requirements"]
|
||||
);
|
||||
if (major != storedMajor) {
|
||||
return false;
|
||||
this.games[SupportedGame.Jak1] = new GameConfig().deserialize(
|
||||
json["games"][SupportedGame.Jak1]
|
||||
);
|
||||
this.games[SupportedGame.Jak2] = new GameConfig().deserialize(
|
||||
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;
|
||||
}
|
||||
if (parseInt(minor) < parseInt(storedMinor)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
export async function initConfig() {
|
||||
const path = await join(await appDir(), "settings.json");
|
||||
let configExists = await fileExists(path);
|
||||
private async loadConfigFromFile() {
|
||||
if (this._loaded) {
|
||||
return;
|
||||
}
|
||||
const configPath = await join(await appDir(), "settings.json");
|
||||
const configExists = await fileExists(configPath);
|
||||
if (!configExists) {
|
||||
log.info("settings file not found or could not be loaded!");
|
||||
console.log(
|
||||
`[Launcher]: Settings file not found at '${configPath}, initializing with defaults!`
|
||||
);
|
||||
await createDir(await appDir(), { recursive: true });
|
||||
await writeFile({
|
||||
contents: JSON.stringify(new LauncherConfig(), null, 2),
|
||||
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({
|
||||
contents: JSON.stringify(this, null, 2),
|
||||
path: path,
|
||||
});
|
||||
log.info("settings file initialized");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
/**
|
||||
* Checks the version to enable safe config operations
|
||||
*
|
||||
* Assumes the config has been loaded before calling to reduce boilerplate
|
||||
*
|
||||
* @param {*} version "<major>.<minor>"
|
||||
* @returns True if majors match, and expected minor greater than or equal to stored. False otherwise, or if no version can be found
|
||||
*/
|
||||
private validVersion(requiredVersion: string): boolean {
|
||||
const [requiredMajor, requiredMinor] = requiredVersion.split(".");
|
||||
if (this.version === null) {
|
||||
return false;
|
||||
}
|
||||
const [storedMajor, storedMinor] = this.version.split(".");
|
||||
if (requiredMajor != storedMajor) {
|
||||
return false;
|
||||
}
|
||||
if (parseInt(requiredMinor) < parseInt(storedMinor)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// GETTERS
|
||||
|
||||
/**
|
||||
* If a game is installed or not
|
||||
* @param {string} supportedGame
|
||||
* @returns {Promise<boolean>}
|
||||
*/
|
||||
export async function getInstallStatus(
|
||||
supportedGame: SupportedGame
|
||||
): Promise<boolean> {
|
||||
await store.load();
|
||||
if (!(await validVersion("1.0"))) {
|
||||
async getInstallStatus(supportedGame: SupportedGame): Promise<boolean> {
|
||||
await this.loadConfigFromFile();
|
||||
if (!this.validVersion("1.0")) {
|
||||
return false;
|
||||
}
|
||||
// TODO: create a proper type for gameConfigs - exists with 'LauncherConfig'
|
||||
const gameConfigs: object = await store.get("games");
|
||||
if (gameConfigs == null || !(supportedGame in gameConfigs)) {
|
||||
const gameConfigs = this.games;
|
||||
if (gameConfigs === null || !(supportedGame in gameConfigs)) {
|
||||
return false;
|
||||
}
|
||||
return gameConfigs[supportedGame].isInstalled;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
/**
|
||||
* 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"))) {
|
||||
async getLastActiveGame(): Promise<SupportedGame | null> {
|
||||
await this.loadConfigFromFile();
|
||||
if (!this.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;
|
||||
return this.lastActiveGame;
|
||||
}
|
||||
// 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;
|
||||
}
|
||||
async areRequirementsMet(): Promise<boolean> {
|
||||
await this.loadConfigFromFile();
|
||||
if (!this.validVersion("1.0")) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return this.requirements.avx && this.requirements.openGL;
|
||||
}
|
||||
|
||||
export async function isAVXRequirementMet(): Promise<boolean> {
|
||||
await store.load();
|
||||
let requirements = await store.get("requirements");
|
||||
if (!requirements["avx"]) {
|
||||
async isAVXRequirementMet(): Promise<boolean> {
|
||||
await this.loadConfigFromFile();
|
||||
if (!this.validVersion("1.0")) {
|
||||
log.error("requirement false - AVX unsupported");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return this.requirements.avx;
|
||||
}
|
||||
|
||||
export async function isOpenGLRequirementMet(): Promise<boolean> {
|
||||
await store.load();
|
||||
let requirements = await store.get("requirements");
|
||||
if (!requirements["openGL"]) {
|
||||
log.error("requirement false - OpenGL unsupported");
|
||||
async isOpenGLRequirementMet(): Promise<boolean> {
|
||||
await this.loadConfigFromFile();
|
||||
if (!this.validVersion("1.0")) {
|
||||
log.error("requirement false - OpenGL 4.3 unsupported");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return this.requirements.openGL;
|
||||
}
|
||||
|
||||
export async function getGameInstallVersion(
|
||||
game: SupportedGame
|
||||
): Promise<String> {
|
||||
// TODO - this can fail on first time startup from splash (where the config is init)
|
||||
// no idea why yet
|
||||
await store.load();
|
||||
let games: GameConfig = await store.get("games");
|
||||
const { version } = games[game];
|
||||
return version;
|
||||
}
|
||||
async getGameInstallVersion(game: SupportedGame): Promise<String> {
|
||||
await this.loadConfigFromFile();
|
||||
if (!this.validVersion("1.0")) {
|
||||
return null;
|
||||
}
|
||||
return this.games[game].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> {
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
export async function shouldUpdateGameInstall(
|
||||
game: SupportedGame
|
||||
): Promise<Boolean> {
|
||||
const installVersion = await getGameInstallVersion(game);
|
||||
async shouldUpdateGameInstall(game: SupportedGame): Promise<Boolean> {
|
||||
const installVersion = await this.getGameInstallVersion(game);
|
||||
if (installVersion === null || installVersion === undefined) {
|
||||
return false;
|
||||
}
|
||||
const toolsVersion = await getLatestToolsVersion();
|
||||
const toolsVersion = await this.getLatestProjectBinaryVersion();
|
||||
|
||||
if (installVersion === toolsVersion) {
|
||||
return false;
|
||||
|
@ -209,4 +218,38 @@ export async function shouldUpdateGameInstall(
|
|||
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();
|
||||
|
|
|
@ -5,13 +5,10 @@ import { getHighestSimd } from "$lib/rpc/commands";
|
|||
import { InstallStatus, isInstalling } from "../stores/AppStore";
|
||||
import { SETUP_ERROR, SETUP_SUCCESS, SupportedGame } from "$lib/constants";
|
||||
import { filePrompt } from "$lib/utils/file";
|
||||
import {
|
||||
setGameInstallVersion,
|
||||
setInstallStatus,
|
||||
setRequirementsMet,
|
||||
} from "../config";
|
||||
import { launcherConfig } from "$lib/config";
|
||||
import { resolveErrorCode } from "./setup_errors";
|
||||
import { installLog, log } from "$lib/utils/log";
|
||||
import { ProcessLogs } from "$lib/stores/AppStore";
|
||||
|
||||
let sidecarOptions = {};
|
||||
|
||||
|
@ -27,7 +24,7 @@ export async function isAVXSupported() {
|
|||
if (highestSIMD.toLowerCase().startsWith("avx")) {
|
||||
return true;
|
||||
}
|
||||
throw new Error("UNSUPPORTED AVX");
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -38,7 +35,8 @@ export async function isOpenGLVersionSupported(
|
|||
version: string
|
||||
): Promise<boolean> {
|
||||
if ((await os.platform()) === "darwin") {
|
||||
throw new Error("Unsupported OS!");
|
||||
// TODO - log!
|
||||
return false;
|
||||
}
|
||||
// Otherwise, query for the version
|
||||
let command = Command.sidecar("bin/glewinfo", ["-version", version]);
|
||||
|
@ -47,21 +45,22 @@ export async function isOpenGLVersionSupported(
|
|||
return true;
|
||||
}
|
||||
log.error("opengl requirement check failed", {
|
||||
version: version,
|
||||
statusCode: output.code,
|
||||
stdout: output.stdout,
|
||||
stderr: output.stderr,
|
||||
});
|
||||
throw new Error("UNSUPPORTED OPENGL VERSION");
|
||||
return false;
|
||||
}
|
||||
|
||||
export async function checkRequirements(): Promise<Boolean> {
|
||||
export async function checkRequirements(): Promise<void> {
|
||||
try {
|
||||
await isAVXSupported();
|
||||
await isOpenGLVersionSupported("4.3");
|
||||
await setRequirementsMet(true, true);
|
||||
return true;
|
||||
const isAVX = await isAVXSupported();
|
||||
const isOpenGL = await isOpenGLVersionSupported("4.3");
|
||||
console.log(`avx - ${isAVX} opengl - ${isOpenGL}`);
|
||||
await launcherConfig.setRequirementsMet(isAVX, isOpenGL);
|
||||
} catch (err) {
|
||||
return false;
|
||||
await launcherConfig.setRequirementsMet(false, false);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -109,11 +108,13 @@ export async function extractAndValidateISO(
|
|||
installLog.info(output.stdout, {
|
||||
game: SupportedGame.Jak1,
|
||||
});
|
||||
ProcessLogs.update((currLogs) => currLogs + output.stdout);
|
||||
}
|
||||
if (output.stderr) {
|
||||
installLog.error(output.stderr, {
|
||||
game: SupportedGame.Jak1,
|
||||
});
|
||||
ProcessLogs.update((currLogs) => currLogs + output.stderr);
|
||||
}
|
||||
if (output.code === 0) {
|
||||
return true;
|
||||
|
@ -143,11 +144,13 @@ export async function decompileGameData(filePath: string): Promise<boolean> {
|
|||
installLog.info(output.stdout, {
|
||||
game: SupportedGame.Jak1,
|
||||
});
|
||||
ProcessLogs.update((currLogs) => currLogs + output.stdout);
|
||||
}
|
||||
if (output.stderr) {
|
||||
installLog.error(output.stderr, {
|
||||
game: SupportedGame.Jak1,
|
||||
});
|
||||
ProcessLogs.update((currLogs) => currLogs + output.stderr);
|
||||
}
|
||||
if (output.code === 0) {
|
||||
return true;
|
||||
|
@ -175,11 +178,13 @@ export async function compileGame(filePath: string): Promise<Boolean> {
|
|||
installLog.info(output.stdout, {
|
||||
game: SupportedGame.Jak1,
|
||||
});
|
||||
ProcessLogs.update((currLogs) => currLogs + output.stdout);
|
||||
}
|
||||
if (output.stderr) {
|
||||
installLog.error(output.stderr, {
|
||||
game: SupportedGame.Jak1,
|
||||
});
|
||||
ProcessLogs.update((currLogs) => currLogs + output.stderr);
|
||||
}
|
||||
if (output.code === 0) {
|
||||
InstallStatus.update(() => SETUP_SUCCESS.ready);
|
||||
|
@ -193,12 +198,13 @@ export async function fullInstallation(game: SupportedGame): Promise<boolean> {
|
|||
isInstalling.update(() => true);
|
||||
try {
|
||||
isoPath = await isoPrompt();
|
||||
ProcessLogs.update(() => "");
|
||||
await extractAndValidateISO(isoPath);
|
||||
await decompileGameData(isoPath);
|
||||
await compileGame(isoPath);
|
||||
await setInstallStatus(game, true);
|
||||
await launcherConfig.setInstallStatus(game, true);
|
||||
isInstalling.update(() => false);
|
||||
await setGameInstallVersion(game);
|
||||
await launcherConfig.setGameInstallVersion(game);
|
||||
return true;
|
||||
} catch (err) {
|
||||
installLog.error("unexpected error encountered", {
|
||||
|
@ -226,7 +232,7 @@ export async function recompileGame(game: SupportedGame) {
|
|||
await decompileGameData(isoPath);
|
||||
await compileGame(isoPath);
|
||||
// update settings.json with latest tools version from metadata.json
|
||||
await setGameInstallVersion(game);
|
||||
await launcherConfig.setGameInstallVersion(game);
|
||||
isInstalling.update(() => false);
|
||||
} catch (err) {
|
||||
installLog.error("unexpected error encountered", {
|
||||
|
|
|
@ -6,4 +6,4 @@ export const InstallStatus = writable({
|
|||
});
|
||||
export const isInstalling = writable(false);
|
||||
export const gameNeedsReinstall = writable(false);
|
||||
export const ProcessLogs = writable();
|
||||
export const ProcessLogs = writable("");
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<script>
|
||||
import { fade } from "svelte/transition";
|
||||
import { getInstallStatus, shouldUpdateGameInstall } from "$lib/config";
|
||||
import { launcherConfig } from "$lib/config";
|
||||
import { fromRoute, getGameTitle, SupportedGame } from "$lib/constants";
|
||||
import { useParams } from "svelte-navigator";
|
||||
import GameContent from "../components/games/GameControls.svelte";
|
||||
|
@ -31,7 +31,7 @@
|
|||
activeGame = fromRoute($params["game_name"]);
|
||||
}
|
||||
|
||||
isGameInstalled = await getInstallStatus(activeGame);
|
||||
isGameInstalled = await launcherConfig.getInstallStatus(activeGame);
|
||||
|
||||
// Do some checks before the user can play the game
|
||||
// First, let's see if their data directory needs updating
|
||||
|
@ -39,7 +39,7 @@
|
|||
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 (dataDirUpToDate) {
|
||||
if (await shouldUpdateGameInstall(activeGame)) {
|
||||
if (await launcherConfig.shouldUpdateGameInstall(activeGame)) {
|
||||
// await recompileGame(activeGame);
|
||||
gameNeedsReinstall.update(() => true);
|
||||
}
|
||||
|
@ -53,7 +53,7 @@
|
|||
try {
|
||||
await copyDataDirectory();
|
||||
// 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);
|
||||
}
|
||||
} catch (err) {
|
||||
|
@ -63,13 +63,13 @@
|
|||
}
|
||||
|
||||
async function updateGameState(evt) {
|
||||
isGameInstalled = await getInstallStatus(activeGame);
|
||||
isGameInstalled = await launcherConfig.getInstallStatus(activeGame);
|
||||
}
|
||||
</script>
|
||||
|
||||
{#if componentLoaded}
|
||||
<div class="flex-center" in:fade>
|
||||
<h1>
|
||||
<h1 class="text-shadow">
|
||||
{getGameTitle(activeGame)}
|
||||
</h1>
|
||||
{#if isGameInstalled && !$gameNeedsReinstall}
|
||||
|
@ -102,3 +102,9 @@
|
|||
{:else}
|
||||
<!-- TODO - component library - spinner -->
|
||||
{/if}
|
||||
|
||||
<style>
|
||||
.text-shadow {
|
||||
text-shadow: -1px -1px 0 #000, 1px -1px 0 #000, -1px 1px 0 #000, 1px 1px 0 #000;
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
<script>
|
||||
import { closeSplashScreen } from "$lib/rpc/commands";
|
||||
import { areRequirementsMet, initConfig } from "$lib/config";
|
||||
import { checkRequirements } from "$lib/setup/setup";
|
||||
import { onMount } from "svelte";
|
||||
import logo from "$assets/images/icon.webp";
|
||||
import { copyDataDirectory, dataDirectoryExists } from "$lib/utils/data-files";
|
||||
|
@ -12,13 +10,6 @@ import { log } from "$lib/utils/log";
|
|||
|
||||
// Events
|
||||
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";
|
||||
currentProgress = 25;
|
||||
|
||||
|
|
Loading…
Reference in a new issue