frontend: wire up controls for interacting with the game

This commit is contained in:
Tyler Wilding 2023-02-18 16:52:32 -05:00
parent 5513d99608
commit e2b284515f
No known key found for this signature in database
GPG key ID: 77CB07796494137E
11 changed files with 304 additions and 654 deletions

View file

@ -6,7 +6,6 @@
import Settings from "./routes/Settings.svelte";
import Sidebar from "./components/sidebar/Sidebar.svelte";
import Background from "./components/background/Background.svelte";
import { isInDebugMode } from "$lib/setup/setup";
import { appWindow } from "@tauri-apps/api/window";
import { isInstalling } from "./lib/stores/AppStore";
import { log } from "$lib/utils/log";
@ -15,6 +14,7 @@
import Textures from "./routes/Textures.svelte";
import Update from "./routes/Update.svelte";
import GameInProgress from "./components/games/GameInProgress.svelte";
import { isInDebugMode } from "$lib/utils/common";
let revokeSpecificActions = false;
@ -75,7 +75,12 @@
<Route path="/" component={Game} primary={false} let:params />
<Route path="/:game_name" component={Game} primary={false} let:params />
<Route path="/jak2" component={GameInProgress} primary={false} let:params />
<Route path="/settings/:tab" component={Settings} primary={false} let:params />
<Route
path="/settings/:tab"
component={Settings}
primary={false}
let:params
/>
<Route path="/faq" component={Faq} primary={false} />
<Route path="/textures" component={Textures} primary={false} />
<Route path="/update" component={Update} primary={false} />

View file

@ -1,99 +1,46 @@
<script type="ts">
import { launcherConfig } from "$lib/config";
import { getGameTitle, getInternalName, SupportedGame } from "$lib/constants";
import { launchGameInDebug } from "$lib/launch";
import { openDir, openREPL } from "$lib/rpc/commands";
import { uninstallGame } from "$lib/setup/setup";
import { openDir } from "$lib/rpc/commands";
import Icon from "@iconify/svelte";
import { appDir, configDir, join } from "@tauri-apps/api/path";
import { configDir, join } from "@tauri-apps/api/path";
import { createEventDispatcher, onMount } from "svelte";
import {
isCompiling,
isDecompiling,
ProcessLogs,
} from "$lib/stores/AppStore";
import { link } from "svelte-navigator";
import { isCompiling, isDecompiling } from "$lib/stores/AppStore";
import { confirm } from "@tauri-apps/api/dialog";
import {
Button,
ButtonGroup,
Chevron,
Dropdown,
DropdownItem,
DropdownDivider,
Spinner,
Helper,
} from "flowbite-svelte";
import { launchGame } from "$lib/rpc/game";
import { launchGame, uninstallGame } from "$lib/rpc/game";
export let activeGame: SupportedGame;
const dispatch = createEventDispatcher();
let componentLoaded = false;
let configPath = undefined;
let screenshotsPath = undefined;
let settingsDir = undefined;
let savesDir = undefined;
onMount(async () => {
configPath = await join(
settingsDir = await join(
await configDir(),
"OpenGOAL",
getInternalName(activeGame)
getInternalName(activeGame),
"settings"
);
screenshotsPath = await join(
savesDir = await join(
await configDir(),
"OpenGOAL-Launcher/data/screenshots"
"OpenGOAL",
getInternalName(activeGame),
"saves"
);
componentLoaded = true;
});
function onClickPlay() {
launchGame("jak1");
}
async function onClickOpenREPL() {
await openREPL();
}
function onClickBootDebug() {
launchGameInDebug();
}
async function onClickUninstall() {
const confirmed = await confirm("Are you sure you want to uninstall?");
if (confirmed) {
await launcherConfig.setInstallStatus(activeGame, false);
await uninstallGame(activeGame);
dispatch("change");
}
}
async function onClickDecompile() {
ProcessLogs.update(() => "");
const isoPath = await join(
await appDir(),
"data",
"iso_data",
getInternalName(activeGame)
);
// await decompileGameData(isoPath);
}
async function onClickCompile() {
ProcessLogs.update(() => "");
const isoPath = await join(
await appDir(),
"data",
"iso_data",
getInternalName(activeGame)
);
// await compileGame(isoPath);
}
</script>
<!-- TODO - texture replacements left out for now, get everything else working end-to-end first -->
<!-- TOOO - time played -->
<div class="flex flex-col justify-end items-end mt-auto">
<!-- TOOO - time played -->
<h1
class="tracking-tighter text-2xl font-bold pb-3 text-orange-500 text-outline pointer-events-none"
>
@ -102,89 +49,83 @@
<div class="flex flex-row gap-2">
<Button
btnClass="border-solid border-2 border-slate-900 rounded bg-slate-900 hover:bg-slate-800 text-sm text-white font-semibold px-5 py-2"
on:click={onClickPlay}
on:click={async () => {
launchGame(getInternalName(activeGame), false);
}}
disabled={$isDecompiling || $isCompiling}>Play</Button
>
<Button
<!-- TODO - texture replacements left out for now, get everything else working end-to-end first -->
<!-- <Button
btnClass="text-center font-semibold focus:ring-0 focus:outline-none inline-flex items-center justify-center px-5 py-2 text-sm text-white border-solid border-2 border-slate-900 rounded bg-slate-900 hover:bg-slate-800"
><Chevron placement="top">Features</Chevron></Button
>
<Dropdown placement="top">
<DropdownItem>Dashboard</DropdownItem>
<DropdownDivider />
<DropdownItem>Settings</DropdownItem>
<DropdownItem>Earnings</DropdownItem>
<DropdownItem slot="footer">Separated link</DropdownItem>
</Dropdown>
<Dropdown placement="top-end">
<DropdownItem>Texture&nbsp;Replacements</DropdownItem>
</Dropdown> -->
<Button
btnClass="text-center font-semibold focus:ring-0 focus:outline-none inline-flex items-center justify-center px-2 py-2 text-sm text-white border-solid border-2 border-slate-900 rounded bg-slate-900 hover:bg-slate-800"
>
<Icon icon="material-symbols:settings" width={24} height={24} />
</Button
>
<Icon icon="material-symbols:settings" width={24} height={24} />
</Button>
<Dropdown placement="top-end" frameClass="mr-1">
<DropdownItem>Dashboard</DropdownItem>
<DropdownItem
on:click={async () => {
launchGame(getInternalName(activeGame), true);
}}>Play&nbsp;in&nbsp;Debug&nbsp;Mode</DropdownItem
>
<DropdownDivider />
<DropdownItem>Settings</DropdownItem>
<DropdownItem>Earnings</DropdownItem>
<DropdownItem slot="footer">Separated link</DropdownItem>
<!-- TODO - screenshot folder? how do we even configure where those go? -->
<DropdownItem
on:click={async () => {
await openDir(settingsDir);
}}>Open&nbsp;Settings&nbsp;Folder</DropdownItem
>
<DropdownItem
on:click={async () => {
await openDir(savesDir);
}}>Open&nbsp;Saves&nbsp;Folder</DropdownItem
>
<DropdownDivider />
<DropdownItem
on:click={async () => {
await openDir(settingsDir);
}}
>Decompile
<!-- NOTE - this is a bug in flowbite-svelte, it's not replacing the default class but just appending -->
<Helper helperClass="!text-neutral-400 !text-xs"
>Extracts game assets (ie. to apply texture replacements)</Helper
></DropdownItem
>
<DropdownItem
on:click={async () => {
await openDir(settingsDir);
}}
>Compile
<!-- NOTE - this is a bug in flowbite-svelte, it's not replacing the default class but just appending -->
<Helper helperClass="!text-neutral-400 !text-xs"
>Rebuild the game. (ie. after modifying OpenGOAL source code)</Helper
></DropdownItem
>
<DropdownDivider />
<!-- TODO - verify installation -->
<!-- <DropdownItem>Verify&nbsp;Install</DropdownItem> -->
<DropdownItem
on:click={async () => {
// Get confirmation
// TODO - probably move these confirms into the actual launcher itself
const confirmed = await confirm(
"Are you sure you want to uninstall?",
{ title: "OpenGOAL Launcher", type: "warning" }
);
if (confirmed) {
await uninstallGame(getInternalName(activeGame));
dispatch("change");
}
}}
>Uninstall<Helper helperClass="!text-neutral-400 !text-xs"
>This will not delete any saves or settings</Helper
></DropdownItem
>
</Dropdown>
</div>
</div>
<!-- {#if componentLoaded}
<ButtonGroup>
{#if $isDecompiling || $isCompiling}
<Spinner class="min-h-full mx-2" />
{/if}
<Button
class="w-56 !rounded-none !bg-[#222222] border-none !text-white hover:!text-blue-500 !text-2xl"
on:click={onClickPlay}
disabled={$isDecompiling || $isCompiling}>Play</Button
>
<Button disabled={$isDecompiling || $isCompiling}
><Chevron placement="top">Extras</Chevron></Button
>
<Dropdown class="!rounded-none" placement="top">
{#if !($isDecompiling || $isCompiling)}
<DropdownItem href="#" on:click={onClickBootDebug}
>Boot In Debug</DropdownItem
>
{/if}
<DropdownItem href="#" on:click={onClickOpenREPL}>Open REPL</DropdownItem>
<DropdownDivider />
<!-- NOTE: Wrapped these two dropdown items in a tags for the use:link, otherwise the dropdownitem doesnt support it -->
<!-- <a use:link href="/textures"><DropdownItem>Texture Packs</DropdownItem></a
>
<!-- <a use:link href="/mods">
<DropdownItem>Mods</DropdownItem>
</a> -->
<!-- </Dropdown>
<Button class="!rounded-none" disabled={$isDecompiling || $isCompiling}
><Chevron placement="top"><i class="fa fa-cog" /></Chevron></Button
>
<Dropdown class="!rounded-none" placement="top">
<DropdownItem href="#" on:click={() => openDir(configPath)}
>Open Settings & Saves</DropdownItem
>
<DropdownItem href="#" on:click={() => openDir(screenshotsPath)}
>Open Screenshots Directory</DropdownItem
>
{#if !($isDecompiling || $isCompiling)}
<DropdownDivider />
<DropdownItem href="#" on:click={async () => await onClickDecompile()}
>Decompile</DropdownItem
>
<DropdownItem href="#" on:click={async () => await onClickCompile()}
>Compile</DropdownItem
>
<DropdownDivider />
<DropdownItem href="#" color="red" on:click={() => onClickUninstall()}
>Uninstall</DropdownItem
>
{/if}
</Dropdown>
</ButtonGroup>
{/if} -->

View file

@ -1,19 +1,19 @@
<div class="ml-20">
<!-- TODO - the static height here is kinda a hack, it's because the
header and the rest of the layout aren't within a shared container -->
<div
class="flex flex-col h-[544px] justify-center items-center p-5 text-center"
>
<h1 class="text-2xl font-black mb-5">Jak 2 is Currently in Development</h1>
<p class="mb-10">
In the meantime, check out our latest progress reports showcasing what
we've accomplished so far
</p>
<a
class="font-bold text-orange-400 hover:text-orange-600"
href="https://opengoal.dev/blog/tags/progress-report"
target="_blank"
rel="noreferrer">Progress Reports</a
>
</div>
</div>
<div class="ml-20">
<!-- TODO - the static height here is kinda a hack, it's because the
header and the rest of the layout aren't within a shared container -->
<div
class="flex flex-col h-[544px] justify-center items-center p-5 text-center"
>
<h1 class="text-2xl font-black mb-5">Jak 2 is Currently in Development</h1>
<p class="mb-10">
In the meantime, check out our latest progress reports showcasing what
we've accomplished so far
</p>
<a
class="font-bold text-orange-400 hover:text-orange-600"
href="https://opengoal.dev/blog/tags/progress-report"
target="_blank"
rel="noreferrer">Progress Reports</a
>
</div>
</div>

View file

@ -59,11 +59,8 @@ body {
}
.text-outline {
text-shadow:
-1px -1px 0 #000,
1px -1px 0 #000,
-1px 1px 0 #000,
1px 1px 0 #000;
text-shadow: -1px -1px 0 #000, 1px -1px 0 #000, -1px 1px 0 #000,
1px 1px 0 #000;
}
.log-accordian > div > div.p-5 {

View file

@ -1,255 +0,0 @@
import { createDir, readTextFile, writeFile } from "@tauri-apps/api/fs";
import { appDir, join } from "@tauri-apps/api/path";
import { SupportedGame } from "./constants";
import { fileExists } from "./utils/file";
import { log } from "./utils/log";
interface Serializable<T> {
deserialize(input: Object): T;
}
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 | null;
private _loaded: boolean = false;
deserialize(json: JSON): LauncherConfig {
this.version = json["version"];
this.requirements = new GameRequirements().deserialize(
json["requirements"]
);
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;
}
private async loadConfigFromFile() {
if (this._loaded) {
return;
}
const configPath = await join(await appDir(), "settings.json");
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({
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>}
*/
async getInstallStatus(supportedGame: SupportedGame): Promise<boolean> {
await this.loadConfigFromFile();
if (!this.validVersion("1.0")) {
return false;
}
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>}
*/
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

@ -1,51 +1,51 @@
import { invoke } from "@tauri-apps/api/tauri";
export async function getInstallationDirectory(): Promise<string | null> {
try {
return await invoke("get_install_directory", {});
} catch (e) {
console.log("TODO AH!");
}
}
export async function setInstallationDirectory(
newInstallDir: string
): Promise<void> {
try {
await invoke("set_install_directory", { newDir: newInstallDir });
} catch (e) {
console.log("TODO AH!");
}
}
export async function isAVXRequirementMet(): Promise<boolean> {
try {
return await invoke("is_avx_requirement_met", {});
} catch (e) {
console.log("TODO AH!");
}
}
export async function isOpenGLRequirementMet(): Promise<boolean> {
try {
return await invoke("is_opengl_requirement_met", {});
} catch (e) {
console.log("TODO AH!");
}
}
export async function finalizeInstallation(gameName: string): Promise<void> {
try {
return await invoke("finalize_installation", { gameName: gameName });
} catch (e) {
console.log("TODO AH!");
}
}
export async function isGameInstalled(gameName: string): Promise<boolean> {
try {
return await invoke("is_game_installed", { gameName: gameName });
} catch (e) {
console.log("TODO AH!");
}
}
import { invoke } from "@tauri-apps/api/tauri";
export async function getInstallationDirectory(): Promise<string | null> {
try {
return await invoke("get_install_directory", {});
} catch (e) {
console.log("TODO AH!");
}
}
export async function setInstallationDirectory(
newInstallDir: string
): Promise<void> {
try {
await invoke("set_install_directory", { newDir: newInstallDir });
} catch (e) {
console.log("TODO AH!");
}
}
export async function isAVXRequirementMet(): Promise<boolean> {
try {
return await invoke("is_avx_requirement_met", {});
} catch (e) {
console.log("TODO AH!");
}
}
export async function isOpenGLRequirementMet(): Promise<boolean> {
try {
return await invoke("is_opengl_requirement_met", {});
} catch (e) {
console.log("TODO AH!");
}
}
export async function finalizeInstallation(gameName: string): Promise<void> {
try {
return await invoke("finalize_installation", { gameName: gameName });
} catch (e) {
console.log("TODO AH!");
}
}
export async function isGameInstalled(gameName: string): Promise<boolean> {
try {
return await invoke("is_game_installed", { gameName: gameName });
} catch (e) {
console.log("TODO AH!");
}
}

View file

@ -1,43 +1,43 @@
import { invoke } from "@tauri-apps/api/tauri";
export async function extractAndValidateISO(
pathToIso: string,
gameName: string
): Promise<void> {
try {
return await invoke("extract_and_validate_iso", {
pathToIso: pathToIso,
gameName: gameName,
});
} catch (e) {
console.log("TODO AH!");
}
}
export async function runDecompiler(
pathToIso: string,
gameName: string
): Promise<void> {
try {
return await invoke("run_decompiler", {
pathToIso: pathToIso,
gameName: gameName,
});
} catch (e) {
console.log("TODO AH!");
}
}
export async function runCompiler(
pathToIso: string,
gameName: string
): Promise<void> {
try {
return await invoke("run_compiler", {
pathToIso: pathToIso,
gameName: gameName,
});
} catch (e) {
console.log("TODO AH!");
}
}
import { invoke } from "@tauri-apps/api/tauri";
export async function extractAndValidateISO(
pathToIso: string,
gameName: string
): Promise<void> {
try {
return await invoke("extract_and_validate_iso", {
pathToIso: pathToIso,
gameName: gameName,
});
} catch (e) {
console.log("TODO AH!");
}
}
export async function runDecompiler(
pathToIso: string,
gameName: string
): Promise<void> {
try {
return await invoke("run_decompiler", {
pathToIso: pathToIso,
gameName: gameName,
});
} catch (e) {
console.log("TODO AH!");
}
}
export async function runCompiler(
pathToIso: string,
gameName: string
): Promise<void> {
try {
return await invoke("run_compiler", {
pathToIso: pathToIso,
gameName: gameName,
});
} catch (e) {
console.log("TODO AH!");
}
}

View file

@ -1,11 +1,25 @@
import { invoke } from "@tauri-apps/api/tauri";
export async function launchGame(gameName: string): Promise<void> {
try {
return await invoke("launch_game", {
gameName: gameName,
});
} catch (e) {
console.log("TODO AH!");
}
}
import { invoke } from "@tauri-apps/api/tauri";
export async function launchGame(
gameName: string,
inDebugMode: boolean
): Promise<void> {
try {
return await invoke("launch_game", {
gameName: gameName,
inDebug: inDebugMode,
});
} catch (e) {
console.log("TODO AH!");
}
}
export async function uninstallGame(gameName: string): Promise<void> {
try {
return await invoke("uninstall_game", {
gameName: gameName,
});
} catch (e) {
console.log("TODO AH!");
}
}

View file

@ -1,66 +1,66 @@
import { invoke } from "@tauri-apps/api/tauri";
export enum VersionFolders {
OFFICIAL = "official",
UNOFFICIAL = "unofficial",
DEVEL = "devel",
}
export async function listDownloadedVersions(
folder: VersionFolders
): Promise<string[]> {
try {
return await invoke("list_downloaded_versions", { versionFolder: folder });
} catch (e) {
console.log("TODO AH!");
}
}
export async function downloadOfficialVersion(
version: String,
url: String
): Promise<string[]> {
try {
return await invoke("download_official_version", { version: version, url });
} catch (e) {
console.log("TODO AH!");
}
}
export async function openVersionFolder(folder: VersionFolders) {
try {
return await invoke("go_to_version_folder", { versionFolder: folder });
} catch (e) {
console.log("TODO AH!");
}
}
export async function saveActiveVersionChange(
folder: VersionFolders,
newVersion: String
) {
try {
return await invoke("save_active_version_change", {
versionFolder: folder,
newActiveVersion: newVersion,
});
} catch (e) {
console.log("TODO AH!");
}
}
export async function getActiveVersion() {
try {
return await invoke("get_active_version", {});
} catch (e) {
console.log("TODO AH!");
}
}
export async function getActiveVersionFolder() {
try {
return await invoke("get_active_version_folder", {});
} catch (e) {
console.log("TODO AH!");
}
}
import { invoke } from "@tauri-apps/api/tauri";
export enum VersionFolders {
OFFICIAL = "official",
UNOFFICIAL = "unofficial",
DEVEL = "devel",
}
export async function listDownloadedVersions(
folder: VersionFolders
): Promise<string[]> {
try {
return await invoke("list_downloaded_versions", { versionFolder: folder });
} catch (e) {
console.log("TODO AH!");
}
}
export async function downloadOfficialVersion(
version: String,
url: String
): Promise<string[]> {
try {
return await invoke("download_official_version", { version: version, url });
} catch (e) {
console.log("TODO AH!");
}
}
export async function openVersionFolder(folder: VersionFolders) {
try {
return await invoke("go_to_version_folder", { versionFolder: folder });
} catch (e) {
console.log("TODO AH!");
}
}
export async function saveActiveVersionChange(
folder: VersionFolders,
newVersion: String
) {
try {
return await invoke("save_active_version_change", {
versionFolder: folder,
newActiveVersion: newVersion,
});
} catch (e) {
console.log("TODO AH!");
}
}
export async function getActiveVersion() {
try {
return await invoke("get_active_version", {});
} catch (e) {
console.log("TODO AH!");
}
}
export async function getActiveVersionFolder() {
try {
return await invoke("get_active_version_folder", {});
} catch (e) {
console.log("TODO AH!");
}
}

View file

@ -2,34 +2,14 @@ import { Command } from "@tauri-apps/api/shell";
import { appDir, join } from "@tauri-apps/api/path";
import { os } from "@tauri-apps/api";
import { getHighestSimd } from "$lib/rpc/commands";
import {
gameNeedsReinstall,
InstallStatus,
isCompiling,
isDecompiling,
isInstalling,
} from "../stores/AppStore";
import {
getInternalName,
SETUP_ERROR,
SETUP_SUCCESS,
SupportedGame,
} from "$lib/constants";
import { filePrompt } from "$lib/utils/file";
import { launcherConfig } from "$lib/config";
import { isInstalling } from "../stores/AppStore";
import { getInternalName, SupportedGame } from "$lib/constants";
import { resolveErrorCode } from "./setup_errors";
import { installLog, log } from "$lib/utils/log";
import { ProcessLogs } from "$lib/stores/AppStore";
import { removeDir } from "@tauri-apps/api/fs";
let sidecarOptions = {};
export interface InstallationStatus {}
export function isInDebugMode() {
return process.env.NODE_ENV === "development";
}
export async function isAVXSupported() {
const highestSIMD = await getHighestSimd();
if (highestSIMD === undefined) {
@ -72,9 +52,10 @@ export async function checkRequirements(): Promise<void> {
const isAVX = await isAVXSupported();
const isOpenGL = await isOpenGLVersionSupported("4.3");
console.log(`avx - ${isAVX} opengl - ${isOpenGL}`);
await launcherConfig.setRequirementsMet(isAVX, isOpenGL);
// TODO - fix
// await launcherConfig.setRequirementsMet(isAVX, isOpenGL);
} catch (err) {
await launcherConfig.setRequirementsMet(false, false);
// await launcherConfig.setRequirementsMet(false, false);
}
}
@ -86,39 +67,3 @@ async function handleErrorCode(code: number, stepName: string) {
}
throw new Error(explaination);
}
export async function decompileFromFile(activeGame: SupportedGame) {
const isoPath = await join(
await appDir(),
"data",
"iso_data",
getInternalName(activeGame)
);
await decompileGameData(isoPath);
}
export async function compileFromFile(activeGame: SupportedGame) {
const isoPath = await join(
await appDir(),
"data",
"iso_data",
getInternalName(activeGame)
);
await compileGame(isoPath);
}
export async function uninstallGame(game: SupportedGame) {
const dataDir = await join(await appDir(), "data");
try {
const t0 = await join(dataDir, "decompiler_out", getInternalName(game));
const t1 = await join(dataDir, "iso_data", getInternalName(game));
const t2 = await join(dataDir, "out", getInternalName(game));
const targets = [t0, t1, t2];
for (const target of targets) {
console.log("Deleting folder: ", target);
await removeDir(target, { recursive: true });
}
} catch (error) {
console.error(error);
}
}

3
src/lib/utils/common.ts Normal file
View file

@ -0,0 +1,3 @@
export function isInDebugMode() {
return process.env.NODE_ENV === "development";
}