Merge pull request #44 from trippjoe/main

front-end cleanup
This commit is contained in:
tripp 2022-06-01 13:10:22 -04:00 committed by GitHub
commit a44ae01ca6
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
23 changed files with 970 additions and 1396 deletions

15
LICENSE Normal file
View file

@ -0,0 +1,15 @@
ISC License
Copyright (c) 2022-2022 OpenGOAL Team
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

172
package-lock.json generated
View file

@ -8,12 +8,12 @@
"name": "opengoal-launcher",
"version": "0.2.2",
"dependencies": {
"@tauri-apps/api": "^1.0.0-rc.4",
"@tauri-apps/api": "^1.0.0-rc.6",
"tauri-plugin-store-api": "github:tauri-apps/tauri-plugin-store"
},
"devDependencies": {
"@sveltejs/vite-plugin-svelte": "^1.0.0-next.30",
"@tauri-apps/cli": "^1.0.0-rc.9",
"@tauri-apps/cli": "^1.0.0-rc.13",
"@tauri-apps/tauricon": "github:tauri-apps/tauricon",
"execa": "^6.1.0",
"prettier": "2.6.2",
@ -594,9 +594,9 @@
}
},
"node_modules/@tauri-apps/api": {
"version": "1.0.0-rc.4",
"resolved": "https://registry.npmjs.org/@tauri-apps/api/-/api-1.0.0-rc.4.tgz",
"integrity": "sha512-1HaUsx8+TzFHDoQ+Mmd6RWaMsPyZlurQHgACDt+il5e/ui6pDkumVXaS92SnY5XOcS4gBC0BkgjVfkWgcm/Oww==",
"version": "1.0.0-rc.6",
"resolved": "https://registry.npmjs.org/@tauri-apps/api/-/api-1.0.0-rc.6.tgz",
"integrity": "sha512-/PbVs3/dUzid0/1XbML8tAkRSOmp+6Gv9ql02HGt3aIjNTvaL2902qEbiTX6xK++3oUoKJJ88t+V6IiNd1JUkw==",
"dependencies": {
"type-fest": "2.12.2"
},
@ -611,9 +611,9 @@
}
},
"node_modules/@tauri-apps/cli": {
"version": "1.0.0-rc.9",
"resolved": "https://registry.npmjs.org/@tauri-apps/cli/-/cli-1.0.0-rc.9.tgz",
"integrity": "sha512-j+HZ65wdfFrMwisYeQpdZnldONevBPHjAo9v9Impf0irUU2UR5nwyvyArHTaWCvNeqEs+YV4XXHsfm2xVpnaug==",
"version": "1.0.0-rc.13",
"resolved": "https://registry.npmjs.org/@tauri-apps/cli/-/cli-1.0.0-rc.13.tgz",
"integrity": "sha512-q7i45Mi1SMv5XllNoX09QS4Q/fYVFwD6piVYmqMSrKY/T5RwedQhytiVH60TxC2xk6o0akVHa7BdYiyJvXNR8A==",
"dev": true,
"bin": {
"tauri": "tauri.js"
@ -626,21 +626,21 @@
"url": "https://opencollective.com/tauri"
},
"optionalDependencies": {
"@tauri-apps/cli-darwin-arm64": "1.0.0-rc.9",
"@tauri-apps/cli-darwin-x64": "1.0.0-rc.9",
"@tauri-apps/cli-linux-arm-gnueabihf": "1.0.0-rc.9",
"@tauri-apps/cli-linux-arm64-gnu": "1.0.0-rc.9",
"@tauri-apps/cli-linux-arm64-musl": "1.0.0-rc.9",
"@tauri-apps/cli-linux-x64-gnu": "1.0.0-rc.9",
"@tauri-apps/cli-linux-x64-musl": "1.0.0-rc.9",
"@tauri-apps/cli-win32-ia32-msvc": "1.0.0-rc.9",
"@tauri-apps/cli-win32-x64-msvc": "1.0.0-rc.9"
"@tauri-apps/cli-darwin-arm64": "1.0.0-rc.13",
"@tauri-apps/cli-darwin-x64": "1.0.0-rc.13",
"@tauri-apps/cli-linux-arm-gnueabihf": "1.0.0-rc.13",
"@tauri-apps/cli-linux-arm64-gnu": "1.0.0-rc.13",
"@tauri-apps/cli-linux-arm64-musl": "1.0.0-rc.13",
"@tauri-apps/cli-linux-x64-gnu": "1.0.0-rc.13",
"@tauri-apps/cli-linux-x64-musl": "1.0.0-rc.13",
"@tauri-apps/cli-win32-ia32-msvc": "1.0.0-rc.13",
"@tauri-apps/cli-win32-x64-msvc": "1.0.0-rc.13"
}
},
"node_modules/@tauri-apps/cli-darwin-arm64": {
"version": "1.0.0-rc.9",
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-darwin-arm64/-/cli-darwin-arm64-1.0.0-rc.9.tgz",
"integrity": "sha512-cpcSRyVOh3n5GsCdKtVQpLJ36yx7h+KY868l7KhPnM5EL1cQbFwYzD/VHlzFvfrpS19YvPBB/AHln4rll5iWvw==",
"version": "1.0.0-rc.13",
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-darwin-arm64/-/cli-darwin-arm64-1.0.0-rc.13.tgz",
"integrity": "sha512-/EqOz7ASHOU98H58Ibbkg12pLG/P5oyQz8OlueaMYryajkJdmi+bHTkJ05DfbS0owAaHkRJ6f+NmoW/AnyqUbg==",
"cpu": [
"arm64"
],
@ -654,9 +654,9 @@
}
},
"node_modules/@tauri-apps/cli-darwin-x64": {
"version": "1.0.0-rc.9",
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-darwin-x64/-/cli-darwin-x64-1.0.0-rc.9.tgz",
"integrity": "sha512-ku8QpMNrfqyCk2adLdVB+zzaCb7T0/RgVvaqEZqK54WW4blUxkeKHbKqZ/SKRdxTkghHbgJIoBtlk1A5GUbAwg==",
"version": "1.0.0-rc.13",
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-darwin-x64/-/cli-darwin-x64-1.0.0-rc.13.tgz",
"integrity": "sha512-bvZ0MBKFD1kc4gdVPXgwUA6tHNKj0EmlQK0Xolk6PYP9vZZeNTP1vejevW0bh2IqxC8DuqUArbG9USXwu+LFbQ==",
"cpu": [
"x64"
],
@ -670,9 +670,9 @@
}
},
"node_modules/@tauri-apps/cli-linux-arm-gnueabihf": {
"version": "1.0.0-rc.9",
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-arm-gnueabihf/-/cli-linux-arm-gnueabihf-1.0.0-rc.9.tgz",
"integrity": "sha512-Qlwm4eWo0uCeL3kmowfaLghPehYTYvnM4fH6cRZndzs6/abqsFdghmEmhP5mn34/RAnHXAUANItqlgk6L7C4iw==",
"version": "1.0.0-rc.13",
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-arm-gnueabihf/-/cli-linux-arm-gnueabihf-1.0.0-rc.13.tgz",
"integrity": "sha512-yODvfUkNvtYYdDTOJSDXMx9fpoEB66I2PTrYx1UKonKTEaLrQDcpw2exD/S9LPQzCYgyTuJ/kHRhG1uLdO/UUQ==",
"cpu": [
"arm"
],
@ -686,9 +686,9 @@
}
},
"node_modules/@tauri-apps/cli-linux-arm64-gnu": {
"version": "1.0.0-rc.9",
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-arm64-gnu/-/cli-linux-arm64-gnu-1.0.0-rc.9.tgz",
"integrity": "sha512-Rr4S902dYjRnDCu141f5Cz3JxwKxX/ax7LiMhSifQu5o2wSiezmZ20VRHBwW1UuZxvGV+hxTuZVnfD6NKQdWdA==",
"version": "1.0.0-rc.13",
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-arm64-gnu/-/cli-linux-arm64-gnu-1.0.0-rc.13.tgz",
"integrity": "sha512-kVDJHERD8CmTeMcd2VTnD/nVCHdnNAK8a6ur3l0KTR1iF8A1AtN/sPahMQjK4f7Ar00UDjIzTw74liqakOeiZg==",
"cpu": [
"arm64"
],
@ -702,9 +702,9 @@
}
},
"node_modules/@tauri-apps/cli-linux-arm64-musl": {
"version": "1.0.0-rc.9",
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-arm64-musl/-/cli-linux-arm64-musl-1.0.0-rc.9.tgz",
"integrity": "sha512-MxqjspY2aS/nxtvBMT8TExZfDWDEsUvQRHHY/2KoBYpqpzucW6WXRGmeOvS1GeA3vnub2/Kq5i32jGRDT1tvrA==",
"version": "1.0.0-rc.13",
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-arm64-musl/-/cli-linux-arm64-musl-1.0.0-rc.13.tgz",
"integrity": "sha512-PFHz+0xKCGMqqn2TmbOSPvTRS61xJQV7srwTZjs5sHBvK536mdBnF/6V6BPEvTn5LzfRnxMu2A5X5GFkYnrZ7w==",
"cpu": [
"arm64"
],
@ -718,9 +718,9 @@
}
},
"node_modules/@tauri-apps/cli-linux-x64-gnu": {
"version": "1.0.0-rc.9",
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-x64-gnu/-/cli-linux-x64-gnu-1.0.0-rc.9.tgz",
"integrity": "sha512-LD7KnJuH1mYFwQfcALPttBnaSG6pgO87Z6nY3xXJjo+A4ttPHcmIBaNdXCTjAmib/umD0nD8k95Hw9iJFYTuiA==",
"version": "1.0.0-rc.13",
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-x64-gnu/-/cli-linux-x64-gnu-1.0.0-rc.13.tgz",
"integrity": "sha512-EWhTOUNHaaMM7mxp/ue+Osnzn6/o9/7qVle3MSnNI9pGQzumc/dOtBs+sWS/NPXdVEiWKET2mFMK120KJlYcQQ==",
"cpu": [
"x64"
],
@ -734,9 +734,9 @@
}
},
"node_modules/@tauri-apps/cli-linux-x64-musl": {
"version": "1.0.0-rc.9",
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-x64-musl/-/cli-linux-x64-musl-1.0.0-rc.9.tgz",
"integrity": "sha512-ifocAxBYhk7qrO5x1mizxx/yABvkmyia0kw9eXUn7d5a30HoBcl/A9t+w+7c4B/n/D+gxEMSr6CPaIZv7KnTog==",
"version": "1.0.0-rc.13",
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-x64-musl/-/cli-linux-x64-musl-1.0.0-rc.13.tgz",
"integrity": "sha512-i8lsKw5iAGTAhqSQHeUCISLjhRXNrloHPoFCaSZtU0/GAPGbW/qST7u593h7cKWxRooeMwzo74ij4GhgmddClQ==",
"cpu": [
"x64"
],
@ -750,9 +750,9 @@
}
},
"node_modules/@tauri-apps/cli-win32-ia32-msvc": {
"version": "1.0.0-rc.9",
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-win32-ia32-msvc/-/cli-win32-ia32-msvc-1.0.0-rc.9.tgz",
"integrity": "sha512-ClDYF4CstoccPMVkIHyvy1jzlWXIYZX2mjKB6z18MdJ0O7Je8TC115K30lqXtSdPuKX35xWDcWU2b/gllcUUzA==",
"version": "1.0.0-rc.13",
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-win32-ia32-msvc/-/cli-win32-ia32-msvc-1.0.0-rc.13.tgz",
"integrity": "sha512-rJxSqWIQXeeT2oLzSiQyqZPgDKSGH5sK7MUr8cOCBitqy3T0COlOMX4O7hhqF3cJ/5s0aX+MuNZBzF/D0QUcxA==",
"cpu": [
"ia32"
],
@ -766,9 +766,9 @@
}
},
"node_modules/@tauri-apps/cli-win32-x64-msvc": {
"version": "1.0.0-rc.9",
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-win32-x64-msvc/-/cli-win32-x64-msvc-1.0.0-rc.9.tgz",
"integrity": "sha512-hJjnpl864OhpIp2lTMTW4ad2Aia5/Tbf7k8GJILzUY/XkBhZjNIgZORa8bDcnZRCTU+RDgMFc+AoKtDIircjnA==",
"version": "1.0.0-rc.13",
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-win32-x64-msvc/-/cli-win32-x64-msvc-1.0.0-rc.13.tgz",
"integrity": "sha512-ifOTrJVQoBAQUYX+EVnE4XJ/FCMHs4FQ8qxGNszqkSxrU24mmT7La6tzj77352q80KnxRa05xjjLL6GGhmzXRg==",
"cpu": [
"x64"
],
@ -8142,90 +8142,90 @@
}
},
"@tauri-apps/api": {
"version": "1.0.0-rc.4",
"resolved": "https://registry.npmjs.org/@tauri-apps/api/-/api-1.0.0-rc.4.tgz",
"integrity": "sha512-1HaUsx8+TzFHDoQ+Mmd6RWaMsPyZlurQHgACDt+il5e/ui6pDkumVXaS92SnY5XOcS4gBC0BkgjVfkWgcm/Oww==",
"version": "1.0.0-rc.6",
"resolved": "https://registry.npmjs.org/@tauri-apps/api/-/api-1.0.0-rc.6.tgz",
"integrity": "sha512-/PbVs3/dUzid0/1XbML8tAkRSOmp+6Gv9ql02HGt3aIjNTvaL2902qEbiTX6xK++3oUoKJJ88t+V6IiNd1JUkw==",
"requires": {
"type-fest": "2.12.2"
}
},
"@tauri-apps/cli": {
"version": "1.0.0-rc.9",
"resolved": "https://registry.npmjs.org/@tauri-apps/cli/-/cli-1.0.0-rc.9.tgz",
"integrity": "sha512-j+HZ65wdfFrMwisYeQpdZnldONevBPHjAo9v9Impf0irUU2UR5nwyvyArHTaWCvNeqEs+YV4XXHsfm2xVpnaug==",
"version": "1.0.0-rc.13",
"resolved": "https://registry.npmjs.org/@tauri-apps/cli/-/cli-1.0.0-rc.13.tgz",
"integrity": "sha512-q7i45Mi1SMv5XllNoX09QS4Q/fYVFwD6piVYmqMSrKY/T5RwedQhytiVH60TxC2xk6o0akVHa7BdYiyJvXNR8A==",
"dev": true,
"requires": {
"@tauri-apps/cli-darwin-arm64": "1.0.0-rc.9",
"@tauri-apps/cli-darwin-x64": "1.0.0-rc.9",
"@tauri-apps/cli-linux-arm-gnueabihf": "1.0.0-rc.9",
"@tauri-apps/cli-linux-arm64-gnu": "1.0.0-rc.9",
"@tauri-apps/cli-linux-arm64-musl": "1.0.0-rc.9",
"@tauri-apps/cli-linux-x64-gnu": "1.0.0-rc.9",
"@tauri-apps/cli-linux-x64-musl": "1.0.0-rc.9",
"@tauri-apps/cli-win32-ia32-msvc": "1.0.0-rc.9",
"@tauri-apps/cli-win32-x64-msvc": "1.0.0-rc.9"
"@tauri-apps/cli-darwin-arm64": "1.0.0-rc.13",
"@tauri-apps/cli-darwin-x64": "1.0.0-rc.13",
"@tauri-apps/cli-linux-arm-gnueabihf": "1.0.0-rc.13",
"@tauri-apps/cli-linux-arm64-gnu": "1.0.0-rc.13",
"@tauri-apps/cli-linux-arm64-musl": "1.0.0-rc.13",
"@tauri-apps/cli-linux-x64-gnu": "1.0.0-rc.13",
"@tauri-apps/cli-linux-x64-musl": "1.0.0-rc.13",
"@tauri-apps/cli-win32-ia32-msvc": "1.0.0-rc.13",
"@tauri-apps/cli-win32-x64-msvc": "1.0.0-rc.13"
}
},
"@tauri-apps/cli-darwin-arm64": {
"version": "1.0.0-rc.9",
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-darwin-arm64/-/cli-darwin-arm64-1.0.0-rc.9.tgz",
"integrity": "sha512-cpcSRyVOh3n5GsCdKtVQpLJ36yx7h+KY868l7KhPnM5EL1cQbFwYzD/VHlzFvfrpS19YvPBB/AHln4rll5iWvw==",
"version": "1.0.0-rc.13",
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-darwin-arm64/-/cli-darwin-arm64-1.0.0-rc.13.tgz",
"integrity": "sha512-/EqOz7ASHOU98H58Ibbkg12pLG/P5oyQz8OlueaMYryajkJdmi+bHTkJ05DfbS0owAaHkRJ6f+NmoW/AnyqUbg==",
"dev": true,
"optional": true
},
"@tauri-apps/cli-darwin-x64": {
"version": "1.0.0-rc.9",
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-darwin-x64/-/cli-darwin-x64-1.0.0-rc.9.tgz",
"integrity": "sha512-ku8QpMNrfqyCk2adLdVB+zzaCb7T0/RgVvaqEZqK54WW4blUxkeKHbKqZ/SKRdxTkghHbgJIoBtlk1A5GUbAwg==",
"version": "1.0.0-rc.13",
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-darwin-x64/-/cli-darwin-x64-1.0.0-rc.13.tgz",
"integrity": "sha512-bvZ0MBKFD1kc4gdVPXgwUA6tHNKj0EmlQK0Xolk6PYP9vZZeNTP1vejevW0bh2IqxC8DuqUArbG9USXwu+LFbQ==",
"dev": true,
"optional": true
},
"@tauri-apps/cli-linux-arm-gnueabihf": {
"version": "1.0.0-rc.9",
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-arm-gnueabihf/-/cli-linux-arm-gnueabihf-1.0.0-rc.9.tgz",
"integrity": "sha512-Qlwm4eWo0uCeL3kmowfaLghPehYTYvnM4fH6cRZndzs6/abqsFdghmEmhP5mn34/RAnHXAUANItqlgk6L7C4iw==",
"version": "1.0.0-rc.13",
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-arm-gnueabihf/-/cli-linux-arm-gnueabihf-1.0.0-rc.13.tgz",
"integrity": "sha512-yODvfUkNvtYYdDTOJSDXMx9fpoEB66I2PTrYx1UKonKTEaLrQDcpw2exD/S9LPQzCYgyTuJ/kHRhG1uLdO/UUQ==",
"dev": true,
"optional": true
},
"@tauri-apps/cli-linux-arm64-gnu": {
"version": "1.0.0-rc.9",
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-arm64-gnu/-/cli-linux-arm64-gnu-1.0.0-rc.9.tgz",
"integrity": "sha512-Rr4S902dYjRnDCu141f5Cz3JxwKxX/ax7LiMhSifQu5o2wSiezmZ20VRHBwW1UuZxvGV+hxTuZVnfD6NKQdWdA==",
"version": "1.0.0-rc.13",
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-arm64-gnu/-/cli-linux-arm64-gnu-1.0.0-rc.13.tgz",
"integrity": "sha512-kVDJHERD8CmTeMcd2VTnD/nVCHdnNAK8a6ur3l0KTR1iF8A1AtN/sPahMQjK4f7Ar00UDjIzTw74liqakOeiZg==",
"dev": true,
"optional": true
},
"@tauri-apps/cli-linux-arm64-musl": {
"version": "1.0.0-rc.9",
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-arm64-musl/-/cli-linux-arm64-musl-1.0.0-rc.9.tgz",
"integrity": "sha512-MxqjspY2aS/nxtvBMT8TExZfDWDEsUvQRHHY/2KoBYpqpzucW6WXRGmeOvS1GeA3vnub2/Kq5i32jGRDT1tvrA==",
"version": "1.0.0-rc.13",
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-arm64-musl/-/cli-linux-arm64-musl-1.0.0-rc.13.tgz",
"integrity": "sha512-PFHz+0xKCGMqqn2TmbOSPvTRS61xJQV7srwTZjs5sHBvK536mdBnF/6V6BPEvTn5LzfRnxMu2A5X5GFkYnrZ7w==",
"dev": true,
"optional": true
},
"@tauri-apps/cli-linux-x64-gnu": {
"version": "1.0.0-rc.9",
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-x64-gnu/-/cli-linux-x64-gnu-1.0.0-rc.9.tgz",
"integrity": "sha512-LD7KnJuH1mYFwQfcALPttBnaSG6pgO87Z6nY3xXJjo+A4ttPHcmIBaNdXCTjAmib/umD0nD8k95Hw9iJFYTuiA==",
"version": "1.0.0-rc.13",
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-x64-gnu/-/cli-linux-x64-gnu-1.0.0-rc.13.tgz",
"integrity": "sha512-EWhTOUNHaaMM7mxp/ue+Osnzn6/o9/7qVle3MSnNI9pGQzumc/dOtBs+sWS/NPXdVEiWKET2mFMK120KJlYcQQ==",
"dev": true,
"optional": true
},
"@tauri-apps/cli-linux-x64-musl": {
"version": "1.0.0-rc.9",
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-x64-musl/-/cli-linux-x64-musl-1.0.0-rc.9.tgz",
"integrity": "sha512-ifocAxBYhk7qrO5x1mizxx/yABvkmyia0kw9eXUn7d5a30HoBcl/A9t+w+7c4B/n/D+gxEMSr6CPaIZv7KnTog==",
"version": "1.0.0-rc.13",
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-x64-musl/-/cli-linux-x64-musl-1.0.0-rc.13.tgz",
"integrity": "sha512-i8lsKw5iAGTAhqSQHeUCISLjhRXNrloHPoFCaSZtU0/GAPGbW/qST7u593h7cKWxRooeMwzo74ij4GhgmddClQ==",
"dev": true,
"optional": true
},
"@tauri-apps/cli-win32-ia32-msvc": {
"version": "1.0.0-rc.9",
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-win32-ia32-msvc/-/cli-win32-ia32-msvc-1.0.0-rc.9.tgz",
"integrity": "sha512-ClDYF4CstoccPMVkIHyvy1jzlWXIYZX2mjKB6z18MdJ0O7Je8TC115K30lqXtSdPuKX35xWDcWU2b/gllcUUzA==",
"version": "1.0.0-rc.13",
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-win32-ia32-msvc/-/cli-win32-ia32-msvc-1.0.0-rc.13.tgz",
"integrity": "sha512-rJxSqWIQXeeT2oLzSiQyqZPgDKSGH5sK7MUr8cOCBitqy3T0COlOMX4O7hhqF3cJ/5s0aX+MuNZBzF/D0QUcxA==",
"dev": true,
"optional": true
},
"@tauri-apps/cli-win32-x64-msvc": {
"version": "1.0.0-rc.9",
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-win32-x64-msvc/-/cli-win32-x64-msvc-1.0.0-rc.9.tgz",
"integrity": "sha512-hJjnpl864OhpIp2lTMTW4ad2Aia5/Tbf7k8GJILzUY/XkBhZjNIgZORa8bDcnZRCTU+RDgMFc+AoKtDIircjnA==",
"version": "1.0.0-rc.13",
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-win32-x64-msvc/-/cli-win32-x64-msvc-1.0.0-rc.13.tgz",
"integrity": "sha512-ifOTrJVQoBAQUYX+EVnE4XJ/FCMHs4FQ8qxGNszqkSxrU24mmT7La6tzj77352q80KnxRa05xjjLL6GGhmzXRg==",
"dev": true,
"optional": true
},

View file

@ -19,7 +19,7 @@
},
"devDependencies": {
"@sveltejs/vite-plugin-svelte": "^1.0.0-next.30",
"@tauri-apps/cli": "^1.0.0-rc.9",
"@tauri-apps/cli": "^1.0.0-rc.13",
"@tauri-apps/tauricon": "github:tauri-apps/tauricon",
"execa": "^6.1.0",
"prettier": "2.6.2",
@ -28,7 +28,7 @@
"svelte-routing": "^1.6.0"
},
"dependencies": {
"@tauri-apps/api": "^1.0.0-rc.4",
"@tauri-apps/api": "^1.0.0-rc.6",
"tauri-plugin-store-api": "github:tauri-apps/tauri-plugin-store"
}
}

1219
src-tauri/Cargo.lock generated

File diff suppressed because it is too large Load diff

View file

@ -2,22 +2,22 @@
name = "app"
version = "0.2.2" # APP_VERSION
description = "A Tauri App"
authors = ["you"]
license = ""
repository = ""
authors = ["OpenGOAL"]
license = "ISC"
repository = "https://github.com/open-goal/launcher"
default-run = "app"
edition = "2021"
rust-version = "1.57"
rust-version = "1.61"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[build-dependencies]
tauri-build = { version = "1.0.0-rc.7", features = [] }
tauri-build = { version = "1.0.0-rc.12", features = [] }
[dependencies]
serde_json = "1.0"
serde = { version = "1.0", features = ["derive"] }
tauri = { version = "1.0.0-rc.8", features = ["api-all", "devtools", "updater"] }
tauri = { version = "1.0.0-rc.14", features = ["api-all", "devtools"] }
[dependencies.tauri-plugin-store]
git = "https://github.com/tauri-apps/tauri-plugin-store"

View file

@ -12,7 +12,10 @@
"tauri": {
"bundle": {
"active": true,
"targets": ["msi", "appimage"],
"targets": [
"msi",
"appimage"
],
"identifier": "opengoal-launcher",
"icon": [
"icons/32x32.png",
@ -21,8 +24,15 @@
"icons/icon.icns",
"icons/icon.ico"
],
"resources": ["data/"],
"externalBin": ["bin/extractor", "bin/gk", "bin/goalc", "bin/glewinfo"],
"resources": [
"data/"
],
"externalBin": [
"bin/extractor",
"bin/gk",
"bin/goalc",
"bin/glewinfo"
],
"copyright": "",
"category": "DeveloperTool",
"shortDescription": "",
@ -43,30 +53,32 @@
]
},
"shell": {
"scope": [{
"name": "bin/extractor",
"sidecar": true,
"cmd": "ignored",
"args": true
},
{
"name": "bin/gk",
"sidecar": true,
"cmd": "ignored",
"args": true
},
{
"name": "bin/goalc",
"sidecar": true,
"cmd": "ignored",
"args": true
},
{
"name": "bin/glewinfo",
"sidecar": true,
"cmd": "ignored",
"args": true
}]
"scope": [
{
"name": "bin/extractor",
"sidecar": true,
"cmd": "ignored",
"args": true
},
{
"name": "bin/gk",
"sidecar": true,
"cmd": "ignored",
"args": true
},
{
"name": "bin/goalc",
"sidecar": true,
"cmd": "ignored",
"args": true
},
{
"name": "bin/glewinfo",
"sidecar": true,
"cmd": "ignored",
"args": true
}
]
}
},
"windows": [
@ -75,11 +87,13 @@
"width": 800,
"height": 600,
"resizable": false,
"fullscreen": false
"fullscreen": false,
"x": 1750,
"y": 0
}
],
"security": {
"csp": null
}
}
}
}

View file

@ -1,11 +1,11 @@
<script>
// Assets
import bgVideo from '$assets/videos/background.webm';
import bgVideo from "$assets/videos/background.webm";
// Other Imports
import { onMount } from "svelte";
import { Router, Route } from "svelte-routing";
import Jak1 from "/src/routes/Jak1.svelte";
import Jak1_Setup from "/src/routes/setup/Jak1.svelte";
import Settings from "./routes/Settings.svelte";
import Sidebar from "/src/components/Sidebar.svelte";
import { initConfig } from "$lib/config";
import { isInDebugMode } from "$lib/setup";
@ -53,22 +53,15 @@
<main>
<div class="video-container">
<div class="overlay" />
<video
id="backgroundVideo"
src={bgVideo}
autoplay
muted
loop
/>
<video id="backgroundVideo" src={bgVideo} autoplay muted loop />
</div>
<div class="container">
<Sidebar />
<div id="main">
<Route path="/" component={Jak1} />
<Route path="/jak1" component={Jak1} />
<Route path="/setup/jak1" component={Jak1_Setup} />
<Route path="/settings" component={Settings} />
</div>
</div>
</main>
</Router>

View file

@ -0,0 +1,35 @@
<script>
import {
appendToInstallLog,
appendToInstallErrorLog,
clearInstallLogs,
} from "$lib/utils/file";
import { SUPPORTED_GAME } from "$lib/constants";
let installErrors;
let installSteps = [];
async function appendLogs(output) {
// const separator = `----${installSteps[currStep].text}----\n`;
// await appendToInstallLog(
// SUPPORTED_GAME.Jak1,
// "\n" + separator + output.stdout
// );
// await appendToInstallErrorLog(
// SUPPORTED_GAME.Jak1,
// "\n" + separator + output.stderr
// );
// if (installSteps[currStep] != undefined) {
// installSteps[currStep].logs += "\n" + separator + output.stdout;
// installSteps[currStep].errorLogs += output.stderr;
// }
}
</script>
<div class="row">
<details>
<summary>Installation Logs</summary>
<div class="logContainer" />
</details>
</div>

View file

@ -0,0 +1,7 @@
<script>
import logo from "$assets/images/logo.png";
</script>
<div class="logo">
<img id="logo" width="65%" src={logo} alt="OpenGOAL" />
</div>

View file

@ -0,0 +1,65 @@
<script>
export let errorMsg;
// function handleError(output) {
// if (output.code === 0) {
// return;
// }
// switch (output.code) {
// case 4000:
// installErrors = [
// ...installErrors,
// {
// title: `can't locate ELF in ISO's contents`,
// description: "unable to determine the version of the game",
// },
// ];
// break;
// case 4001:
// installErrors = [
// ...installErrors,
// {
// title: `Unsupported serial`,
// description:
// "ISO containing an unsupported game serial or version was provided",
// },
// ];
// break;
// case 4002:
// case 4010:
// case 4011:
// installErrors = [
// ...installErrors,
// {
// title: `Unsupported game version`,
// description:
// "ISO contains files that are for an unsupported version, were modified from the original, or is an incomplete dump",
// },
// ];
// break;
// case 4020:
// installErrors = [
// ...installErrors,
// {
// title: `Unexpected Extraction Result`,
// description:
// "The extracted ISO's contents were not as expected, installation cannot proceed",
// },
// ];
// break;
// default:
// installErrors = [
// ...installErrors,
// {
// title: `Unexpected Error Code ${output.code}`,
// description:
// "An unexpected error occurred during installation, check logs",
// },
// ];
// }
// }
</script>
<section>
<h2>Error: {errorMsg}</h2>
</section>

View file

@ -8,31 +8,31 @@
<nav id="sidebar">
<div class="games">
<div class="jak-1 nav-item active">
<Link to="/jak1" data-tooltip="Jak & Daxter: The Precursor Legacy">
<img src={logoJak1} alt="Jak - TPL">
<Link to="jak1" data-tooltip="Jak & Daxter: The Precursor Legacy">
<img src={logoJak1} alt="Jak - TPL" />
</Link>
</div>
<div class="jak-2 nav-item disabled">
<Link to="/jak2" data-tooltip="Jak 2 - Not Available!">
<img src={logoJak2} alt="Jak 2">
<Link to="" data-tooltip="Jak 2 - Not Available!">
<img src={logoJak2} alt="Jak 2" />
</Link>
</div>
<div class="jak-3 nav-item disabled">
<Link to="/jak2" data-tooltip="Jak 3 - Not Available!">
<img src={logoJak3} alt="Jak 3">
<Link to="" data-tooltip="Jak 3 - Not Available!">
<img src={logoJak3} alt="Jak 3" />
</Link>
</div>
</div>
<div class="spacer"></div>
<div class="spacer" />
<div class="controls">
<div class="console nav-item">
<Link to="/console" data-tooltip="Toggle Debug Console">
<i class="bi bi-terminal-fill"></i>
<Link to="" data-tooltip="Toggle Debug Console">
<i class="bi bi-terminal-fill" />
</Link>
</div>
<div class="settings nav-item">
<Link to="/settings" data-tooltip="Settings">
<i class="bi bi-sliders"></i>
<Link to="settings" data-tooltip="Settings">
<i class="bi bi-sliders" />
</Link>
</div>
</div>

View file

@ -0,0 +1,15 @@
<script>
import { launchGame } from "$lib/launch";
function onClickConfig() {
alert("TODO");
}
function onClickPlay() {
launchGame();
}
</script>
<div id="launcherControls">
<button class="btn lg" on:click={onClickConfig} disabled>Config</button>
<button class="btn lg" on:click={onClickPlay}>Play</button>
</div>

View file

@ -0,0 +1,106 @@
<script>
import { message } from "@tauri-apps/api/dialog";
import { onMount } from "svelte";
import { Link, navigate } from "svelte-routing";
import { filePrompt } from "$lib/utils/file";
import { setInstallStatus } from "$lib/config";
import { clearInstallLogs } from "$lib/utils/file";
import {
compileGame,
decompileGameData,
extractAndValidateISO,
isAVXSupported,
isOpenGLVersionSupported,
} from "$lib/setup";
// components
import Progress from "./Progress.svelte";
// constants
import {
SETUP_SUCCESS,
SETUP_ERROR,
SUPPORTED_GAME,
} from "../../lib/constants";
let isoPath;
let currentStatus = {};
const setStatus = (status) => (currentStatus = status);
async function areRequirementsMet() {
const res = await Promise.resolve()
.then(async () => {
setStatus(SETUP_SUCCESS.checkCompatible);
await isAVXSupported();
setStatus(SETUP_SUCCESS.avxSupported);
})
.then(async () => {
await isOpenGLVersionSupported("4.3");
setStatus(SETUP_SUCCESS.openGLSupported);
})
.catch((err) => {
setStatus({ status: err.message, percent: -1 });
console.error(err);
});
return res;
}
async function installProcess() {
await clearInstallLogs(SUPPORTED_GAME.Jak1);
const res = await Promise.resolve()
.then(async () => {
setStatus(SETUP_SUCCESS.awaitingISO);
isoPath = await filePrompt();
})
.then(async () => {
setStatus(SETUP_SUCCESS.extractingISO);
await extractAndValidateISO(isoPath);
})
.then(async () => {
setStatus(SETUP_SUCCESS.decompiling);
await decompileGameData(isoPath);
})
.then(async () => {
setStatus(SETUP_SUCCESS.compiling);
await compileGame(isoPath);
})
.then(async () => {
setStatus(SETUP_SUCCESS.ready);
await setInstallStatus(SUPPORTED_GAME.Jak1, true);
await message("READY TO PLAY");
navigate("/", { replace: true });
})
.catch((err) => {
console.error(err);
setStatus({ status: err.message, percent: -1 });
});
return res;
}
onMount(async () => {
// TODO - app crashes after checking requirements
// in the future i want to save the requirements met in the settings.json store file so it doesnt need to be run every time
// then the requirements met function can check against the store data to avoid running the external bins each time
// gotta revise this in the future because this will still run the install process even if the user doesnt meet the requirements
// await areRequirementsMet();
await installProcess();
});
function onClickBrowse() {
installProcess();
}
</script>
<div class="content">
<Progress step={currentStatus} />
<div style="text-align:center">
<!-- have to edit this conditional in the future but for now its okay -->
{#if currentStatus.status === "No ISO File Selected!"}
<button class="btn" on:click={onClickBrowse}> Browse for ISO </button>
{/if}
<Link to="/jak1">
<button class="btn">Cancel</button>
</Link>
</div>
</div>

View file

@ -0,0 +1,19 @@
<script>
import "./progress.css";
export let step;
</script>
<section>
<div class="status">
<h2>{step.status}</h2>
</div>
{#if step.percent >= 0}
<div class="progress">
<div
class="progress-bar progress-bar-animated"
style="width: {step.percent}%"
/>
</div>
{/if}
</section>

View file

@ -0,0 +1,43 @@
.progress {
display: flex;
overflow: hidden;
height: 30px;
background-color: #ecf0f1;
width: 75%;
margin: 20px auto;
}
.progress-bar {
overflow: hidden;
text-align: center;
background-color: dodgerblue;
}
.progress-bar-animated {
position: relative;
}
.progress-bar-animated::before {
content: "";
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: linear-gradient(to right, transparent, rgba(255, 255, 255, 0.5));
transform: translateX(-100%);
animation: progress-bar-shine 2s infinite;
}
@keyframes progress-bar-shine {
to {
transform: translateX(0);
opacity: 0.1;
}
}
.status {
justify-content: center;
align-items: center;
text-align: center;
}

View file

@ -1,36 +1,9 @@
import { createDir, writeFile } from "@tauri-apps/api/fs";
import { appDir, join } from "@tauri-apps/api/path";
import { Store } from "tauri-plugin-store-api";
import { SUPPORTED_GAME } from "./constants";
import { fileExists } from "./utils/file";
export class SupportedGame {
static Jak1 = new SupportedGame("Jak 1");
static Jak2 = new SupportedGame("Jak 2");
static Jak3 = new SupportedGame("Jak 3");
static JakX = new SupportedGame("Jak X");
constructor(name) {
this.name = name;
}
static fromName(name) {
switch (name) {
case this.Jak1.name:
return this.Jak1;
case this.Jak2.name:
return this.Jak2;
case this.Jak3.name:
return this.Jak3;
case this.JakX.name:
return this.JakX;
default:
return null;
}
}
static allGames = [this.Jak1, this.Jak2, this.Jak3, this.JakX];
}
class GameConfig {
isInstalled = false;
isActive = false;
@ -42,13 +15,18 @@ class GameConfig {
}
}
// TODO: LINK REQUIREMENTS TO CHECK REQUIREMENTS FUNCTION TO AVOID RUNNING FUNCTION IF REQUIREMENTS ARE MET
class LauncherConfig {
version = "1.0";
requirements = {
avx: null,
openGL: null,
};
games = {
[SupportedGame.Jak1.name]: GameConfig.createActive(),
[SupportedGame.Jak2.name]: new GameConfig(),
[SupportedGame.Jak3.name]: new GameConfig(),
[SupportedGame.JakX.name]: new GameConfig(),
[SUPPORTED_GAME.Jak1]: GameConfig.createActive(),
[SUPPORTED_GAME.Jak2]: new GameConfig(),
[SUPPORTED_GAME.Jak3]: new GameConfig(),
[SUPPORTED_GAME.JakX]: new GameConfig(),
};
}
@ -91,7 +69,7 @@ export async function initConfig() {
/**
* If a game is installed or not
* @param {SupportedGame} supportedGame
* @param {string} supportedGame
* @returns {Promise<boolean>}
*/
export async function getInstallStatus(supportedGame) {
@ -100,24 +78,24 @@ export async function getInstallStatus(supportedGame) {
return false;
}
const gameConfigs = await store.get("games");
if (gameConfigs == null || !(supportedGame.name in gameConfigs)) {
if (gameConfigs == null || !(supportedGame in gameConfigs)) {
return false;
}
return gameConfigs[supportedGame.name].isInstalled;
return gameConfigs[supportedGame].isInstalled;
}
/**
* The last game that was considered active in the launcher
* @returns {Promise<SupportedGame | null>}
* @returns {Promise<String | null>}
*/
export async function getLastActiveGame() {
await store.load();
if (!(await validVersion("1.0"))) {
return null;
}
// Look through all games, find first
for (const game of SupportedGame.allGames) {
const gameConfig = await store.get(game.name);
// Look through all games, find first active game
for (const game in SUPPORTED_GAME) {
const gameConfig = await store.get(game);
if (gameConfig.isActive) {
return game;
}
@ -125,7 +103,7 @@ export async function getLastActiveGame() {
}
/**
* @param {SupportedGame} supportedGame
* @param {string} supportedGame
* @param {boolean} installed
* @returns
*/
@ -135,10 +113,10 @@ export async function setInstallStatus(supportedGame, installed) {
return;
}
let gameConfigs = await store.get("games");
if (gameConfigs == null || !(supportedGame.name in gameConfigs)) {
if (gameConfigs == null || !(supportedGame in gameConfigs)) {
return;
}
gameConfigs[supportedGame.name].isInstalled = installed;
gameConfigs[supportedGame].isInstalled = installed;
await store.set("games", gameConfigs);
await store.save();
}

27
src/lib/constants.js Normal file
View file

@ -0,0 +1,27 @@
export const SETUP_SUCCESS = {
avxSupported: { status: "AVX SUPPORTED", percent: 10 },
openGLSupported: { status: "OPENGL SUPPORTED", percent: 20 },
checkCompatible: { status: "Checking Compatibility", percent: 0 },
awaitingISO: { status: "Awaiting ISO File", percent: 20 },
extractingISO: {
status: "Extracting and Validating ISO contents",
percent: 40,
},
decompiling: { status: "Decompiling the game", percent: 60 },
compiling: { status: "Compiling the game", percent: 80 },
ready: { status: "Ready to Play!", percent: 100 },
};
export const SETUP_ERROR = {
unsupportedAVX: { status: "UNSUPPORTED AVX", percent: -1 },
noISO: { status: "No ISO File Selected!", percent: -1 },
unsupportedOS: { status: "Unsupported OS!", percent: -1 },
unsupportedOpenGL: { status: "UNSUPPORTED OPENGL VERSION", percent: -1 },
};
export const SUPPORTED_GAME = {
Jak1: "Jak 1",
Jak2: "Jak 2",
Jak3: "Jak 3",
JakX: "Jak X",
};

View file

@ -11,12 +11,14 @@ let debugPath;
if (isInDebugMode()) {
let path = await resourceDir();
debugPath = path.split("launcher")[0].split("?\\")[1];
debugPath += "\\launcher\\bundle-test\\data";
// debugPath += "launcher\\bundle-test\\data";
debugPath += "launcher\\src-tauri\\data";
}
export async function launchGame() {
let command;
if (isInDebugMode()) {
console.log(debugPath);
command = Command.sidecar(
"bin/gk",
["-boot", "-fakeiso", "-debug", "-proj-path", debugPath],
@ -27,5 +29,7 @@ export async function launchGame() {
cwd: "bin",
});
}
command.execute();
let output = await command.execute();
console.log(output.stdout);
console.log(output.stderr);
}

View file

@ -3,48 +3,41 @@ import { resourceDir } from "@tauri-apps/api/path";
import { os } from "@tauri-apps/api";
import { getHighestSimd } from "$lib/commands";
export class InstallationStatus {
static Pending = Symbol("pending");
static InProgress = Symbol("inprogress");
static Failed = Symbol("failed");
static Success = Symbol("success");
}
export class RequirementStatus {
static Unknown = Symbol("unknown");
static Met = Symbol("met");
static Failed = Symbol("failed");
static Checking = Symbol("checking");
}
let debugPath;
let sidecarOptions = {};
export function isInDebugMode() {
return process.env.NODE_ENV === "development";
}
let debugPath;
let sidecarOptions = {};
if (isInDebugMode()) {
// TODO - this is kind of a total hack
let path = await resourceDir();
debugPath = path.split("launcher")[0].split("?\\")[1];
debugPath += "\\launcher\\bundle-test\\data";
// debugPath += "launcher\\bundle-test\\data";
debugPath += "launcher\\src-tauri\\data\\";
sidecarOptions = { cwd: "bin" };
}
export async function isAVXSupported() {
let highestSIMD = await getHighestSimd();
const highestSIMD = await getHighestSimd();
if (highestSIMD === undefined) {
return RequirementStatus.Unknown;
return true;
}
if (highestSIMD.toLowerCase().startsWith("avx")) {
return RequirementStatus.Met;
return true;
}
return RequirementStatus.Failed;
throw new Error("UNSUPPORTED AVX");
}
/**
* @param {String} version
* @returns {Promise<Boolean>}
*/
export async function isOpenGLVersionSupported(version) {
if ((await os.platform()) === "darwin") {
return RequirementStatus.Unknown;
throw new Error("Unsupported OS!");
// return RequirementStatus.Unknown;
}
// Otherwise, query for the version
let command = Command.sidecar(
@ -52,27 +45,24 @@ export async function isOpenGLVersionSupported(version) {
["-version", version],
sidecarOptions
);
try {
let output = await command.execute();
if (output.code === 0) {
return RequirementStatus.Met;
}
return RequirementStatus.Failed;
} catch (e) {
return RequirementStatus.Failed;
const output = await command.execute();
if (output.code === 0) {
return true;
}
throw new Error("UNSUPPORTED OPENGL VERSION");
}
/**
* @param {String} filePath
* @returns {Promise<ChildProcess>}
* @returns {Promise<Boolean>}
*/
export async function extractAndValidateISO(filePath) {
let command;
if (isInDebugMode()) {
console.log(filePath);
command = Command.sidecar(
"bin/extractor",
[filePath, "--extract", "--proj-path", debugPath],
[filePath, "--extract", "--validate", "--proj-path", debugPath],
sidecarOptions
);
} else {
@ -83,12 +73,18 @@ export async function extractAndValidateISO(filePath) {
);
}
return await command.execute();
const output = await command.execute();
console.log(output.stdout);
console.log(output.stderr);
if (output.code === 0) {
return true;
}
throw new Error(`Extractor exited with code: ${output.code}`);
}
/**
* @param {String} filePath
* @returns {Promise<ChildProcess>}
* @returns {Promise<Boolean>}
*/
export async function decompileGameData(filePath) {
let command;
@ -106,12 +102,18 @@ export async function decompileGameData(filePath) {
);
}
return await command.execute();
const output = await command.execute();
if (output.code === 0) {
return true;
}
console.log(output.stdout);
console.log(output.stderr);
throw new Error(`Decompiler exited with code: ${output.code}`);
}
/**
* @param {String} filePath
* @returns {Promise<ChildProcess>}
* @returns {Promise<Boolean>}
*/
export async function compileGame(filePath) {
let command;
@ -129,5 +131,11 @@ export async function compileGame(filePath) {
);
}
return await command.execute();
const output = await command.execute();
console.log(output.stdout);
console.log(output.stderr);
if (output.code === 0) {
return true;
}
throw new Error(`Compiler exited with code: ${output.code}`);
}

View file

@ -11,7 +11,7 @@ export async function fileExists(path) {
}
}
export async function filePrompt(title) {
export async function filePrompt() {
// TODO - pull strings out into args
const path = await open({
multiple: false,
@ -22,17 +22,17 @@ export async function filePrompt(title) {
if (path) {
return path;
}
return null;
throw new Error("No ISO File Selected!");
}
export async function clearInstallLogs(supportedGame, text) {
const dir = await logDir();
let fileName = `${supportedGame.name}-install.log`;
let fileName = `${supportedGame}-install.log`;
let fullPath = await join(dir, fileName);
if (await fileExists(fullPath)) {
await writeFile({ contents: "", path: fullPath });
}
fileName = `${supportedGame.name}-install-errors.log`;
fileName = `${supportedGame}-install-errors.log`;
fullPath = await join(dir, fileName);
if (await fileExists(fullPath)) {
await writeFile({ contents: "", path: fullPath });
@ -41,7 +41,7 @@ export async function clearInstallLogs(supportedGame, text) {
export async function appendToInstallLog(supportedGame, text) {
const dir = await logDir();
const fileName = `${supportedGame.name}-install.log`;
const fileName = `${supportedGame}-install.log`;
const fullPath = await join(dir, fileName);
console.log(`[OG]: Writing logs to ${fullPath}`);
let contents = "";
@ -56,7 +56,7 @@ export async function appendToInstallLog(supportedGame, text) {
export async function appendToInstallErrorLog(supportedGame, text) {
const dir = await logDir();
const fileName = `${supportedGame.name}-install-errors.log`;
const fileName = `${supportedGame}-install-errors.log`;
const fullPath = await join(dir, fileName);
console.log(`[OG]: Writing logs to ${fullPath}`);
let contents = "";

View file

@ -1,39 +1,24 @@
<script>
// Assets
import logo from '$assets/images/logo.png';
import { onMount } from 'svelte';
import { Link } from "svelte-routing";
import { getInstallStatus, SupportedGame } from '$lib/config';
import { launchGame } from '$lib/launch';
import { getInstallStatus } from "$lib/config";
import Setup from "../components/setup/Jak1Setup.svelte";
import Jak1Main from "../components/games/Jak1Main.svelte";
import Console from "../components/Console.svelte";
import Logo from "../components/Logo.svelte";
import { SUPPORTED_GAME } from "$lib/constants";
// State
let gameInstalled = false;
// Events
onMount(async () => {
gameInstalled = await getInstallStatus(SupportedGame.Jak1);
});
function onClickConfig() {
alert("TODO");
}
function onClickPlay() {
launchGame();
}
const gameInstalled = async () => await getInstallStatus(SUPPORTED_GAME.Jak1);
</script>
<div class="flex-center">
<div class="logo">
<img id="logo" width="65%" src={logo} alt="OpenGOAL">
</div>
<div id="launcherControls">
{#if gameInstalled}
<button class="btn lg" on:click={onClickConfig} disabled>Config</button>
<button class="btn lg" on:click={onClickPlay}>Play</button>
<Logo />
{#await gameInstalled() then installed}
{#if installed}
<Jak1Main />
{:else}
<Link to="/setup/jak1">
<button class="btn lg">Setup</button>
</Link>
<Setup />
<Console />
{/if}
</div>
{/await}
</div>

View file

@ -1,5 +1,4 @@
<svelte:head>
<title>OpenGOAL Launcher - Settings</title>
</svelte:head>
<script>
</script>
<h1>TODO!</h1>

View file

@ -1,308 +0,0 @@
<script>
import { onMount } from "svelte";
import { Link, navigate } from "svelte-routing";
import { filePrompt } from "$lib/utils/file";
import {
compileGame,
decompileGameData,
extractAndValidateISO,
isAVXSupported,
isOpenGLVersionSupported,
} from "$lib/setup";
import { SupportedGame, setInstallStatus } from "$lib/config";
import { InstallationStatus, RequirementStatus } from "$lib/setup";
import {
appendToInstallLog,
appendToInstallErrorLog,
clearInstallLogs,
} from "$lib/utils/file";
let setupStarted = false;
let setupInProgress = false;
let isoPath = undefined;
let requirementChecks = [
{
status: RequirementStatus.Checking,
text: `CPU Supports&nbsp;<a href="https://en.wikipedia.org/wiki/Advanced_Vector_Extensions" target="_blank"><strong>AVX or AVX2</strong></a>`,
check: async () => await isAVXSupported(),
},
{
status: RequirementStatus.Checking,
text: `GPU Supports&nbsp;OpenGL&nbsp;<span class="orange-text"><strong>4.3</strong></span>`,
check: async () => await isOpenGLVersionSupported("4.3"),
},
];
let currStep = 0;
let installSteps = [
{
status: InstallationStatus.Pending,
text: "Extracting and Validate ISO",
logs: "",
errorLogs: "",
},
{
status: InstallationStatus.Pending,
text: "Decompiling the Game",
logs: "",
errorLogs: "",
},
{
status: InstallationStatus.Pending,
text: "Compiling the Game",
logs: "",
errorLogs: "",
},
];
let installErrors = [];
// TODO - move this to the enum
function statusIndicator(status) {
if (
status === InstallationStatus.InProgress ||
status === RequirementStatus.Checking
) {
return `<div class="loader" />`;
} else if (
status === InstallationStatus.Success ||
status === RequirementStatus.Met
) {
return "✅";
} else if (
status === InstallationStatus.Failed ||
status === RequirementStatus.Failed
) {
return "❌";
} else if (status === RequirementStatus.Unknown) {
return "⚠️";
} else {
return "⏳";
}
}
function areRequirementsMet(checks) {
for (let i = 0; i < checks.length; i++) {
if (
checks[i].status !== RequirementStatus.Met &&
checks[i].status !== RequirementStatus.Unknown
) {
return false;
}
}
return true;
}
function handleError(output) {
if (output.code === 0) {
return;
}
switch (output.code) {
case 4000:
installErrors = [
...installErrors,
{
title: `can't locate ELF in ISO's contents`,
description: "unable to determine the version of the game",
},
];
break;
case 4001:
installErrors = [
...installErrors,
{
title: `Unsupported serial`,
description:
"ISO containing an unsupported game serial or version was provided",
},
];
break;
case 4002:
case 4010:
case 4011:
installErrors = [
...installErrors,
{
title: `Unsupported game version`,
description:
"ISO contains files that are for an unsupported version, were modified from the original, or is an incomplete dump",
},
];
break;
case 4020:
installErrors = [
...installErrors,
{
title: `Unexpected Extraction Result`,
description:
"The extracted ISO's contents were not as expected, installation cannot proceed",
},
];
break;
default:
installErrors = [
...installErrors,
{
title: `Unexpected Error Code ${output.code}`,
description:
"An unexpected error occurred during installation, check logs",
},
];
}
}
function finishStep(output) {
appendLogs(output);
installSteps[currStep].status =
output.code === 0
? InstallationStatus.Success
: InstallationStatus.Failed;
handleError(output);
if (output.code === 0) {
currStep++;
if (currStep < installSteps.length) {
installSteps[currStep].status = InstallationStatus.InProgress;
}
}
}
async function appendLogs(output) {
const separator = `----${installSteps[currStep].text}----\n`;
await appendToInstallLog(
SupportedGame.Jak1,
"\n" + separator + output.stdout
);
await appendToInstallErrorLog(
SupportedGame.Jak1,
"\n" + separator + output.stderr
);
if (installSteps[currStep] != undefined) {
installSteps[currStep].logs += "\n" + separator + output.stdout;
installSteps[currStep].errorLogs += output.stderr;
}
}
async function installProcess() {
await clearInstallLogs(SupportedGame.Jak1);
// Reset experience
installErrors = [];
for (let i = 0; i < installSteps.length; i++) {
installSteps[i].logs = "";
installSteps[i].errorLogs = "";
installSteps[i].status = InstallationStatus.Pending;
}
currStep = 0;
setupStarted = true;
setupInProgress = true;
installSteps[currStep].status = InstallationStatus.InProgress;
let output = await extractAndValidateISO(isoPath);
finishStep(output);
if (output.code === 0) {
console.log("[OpenGOAL]: Extraction and Validation Completed");
output = await decompileGameData(isoPath);
finishStep(output);
}
if (output.code === 0) {
console.log("[OpenGOAL]: Decompilation Completed");
output = await compileGame(isoPath);
finishStep(output);
}
if (output.code === 0) {
console.log("[OpenGOAL]: Compilation Completed");
await setInstallStatus(SupportedGame.Jak1, true);
navigate("/jak1", { replace: true });
}
setupInProgress = false;
isoPath = undefined;
}
// Events
onMount(async () => {
for (let i = 0; i < requirementChecks.length; i++) {
requirementChecks[i].status = await requirementChecks[i].check();
}
});
async function onClickBrowse() {
isoPath = await filePrompt();
installProcess();
}
</script>
<div class="content">
<h1>Setup Process</h1>
<h2>Minimum Requirements</h2>
<ul class="no-decoration">
{#each requirementChecks as check}
<li>
<span class="progress-row">
{@html statusIndicator(check.status)}
{@html check.text}
</span>
{#if check.status === RequirementStatus.Unknown}
<ul class="no-decoration">
<li>Unable to determine this requirement</li>
</ul>
{/if}
</li>
{/each}
</ul>
{#if areRequirementsMet(requirementChecks)}
<p>Browse for your ISO - Obtained by dumping your own legitimate copy</p>
<div>
<button class="btn" disabled={setupInProgress} on:click={onClickBrowse}
>Browse for ISO</button
>
{#if isoPath}
{isoPath}
{/if}
<span id="filePathLabel" />
</div>
{#if !setupInProgress}
<div class="row">
<Link to="/jak1">
<button class="btn">Cancel</button>
</Link>
</div>
{/if}
{#if setupStarted}
<div>
<h2>Progress</h2>
<ul class="no-decoration">
{#each installSteps as step}
<li>
<span class="progress-row">
{@html statusIndicator(step.status)}
{step.text}
</span>
</li>
{/each}
</ul>
</div>
{#each installErrors as err}
<div class="error-row">
<h3>{err.title}</h3>
<p>{err.description}</p>
</div>
{/each}
<div class="row">
<details>
<summary>Installation Logs</summary>
<div class="logContainer">
{#each installSteps as step}
{#if step.logs !== ""}
{step.logs}
{/if}
{#if step.errorLogs !== ""}
<div class="errorLogs">
{step.errorLogs}
</div>
{/if}
{/each}
</div>
</details>
</div>
{/if}
{/if}
</div>