4 Commits

Author SHA1 Message Date
dc88e9f2cc remove console logs 2024-01-22 12:53:59 +01:00
bf8a458b5f finish update dialog 2024-01-22 12:37:29 +01:00
3570582c6b remove requiring admin, this caused otd to not work 2024-01-22 12:06:22 +01:00
b9bd87c099 remove old files before replacing them 2024-01-22 12:06:04 +01:00
10 changed files with 162 additions and 118 deletions

View File

@@ -70,7 +70,6 @@ function getGlobalConfig(osuPath) {
path: "", path: "",
get: async (key) => { get: async (key) => {
if (!configFileInfo.path) { if (!configFileInfo.path) {
console.log("config file not loaded");
return ""; return "";
} }
const fileStream = await fs.promises.readFile( const fileStream = await fs.promises.readFile(
@@ -181,11 +180,6 @@ async function getFilesThatNeedUpdate(osuPath, releaseStreamFiles) {
if ( if (
fileHashOnDisk.trim().toLowerCase() != fileHash.trim().toLowerCase() fileHashOnDisk.trim().toLowerCase() != fileHash.trim().toLowerCase()
) { ) {
console.log({
fileOnDisk,
fileHashOnDisk,
fileHash,
});
updateFiles.push(updatePatch); updateFiles.push(updatePatch);
} }
} else updateFiles.push(updatePatch); } else updateFiles.push(updatePatch);
@@ -224,6 +218,11 @@ function downloadUpdateFiles(osuPath, updateFiles) {
}); });
}); });
try { try {
if (fs.existsSync(path.join(osuPath, fileName))) {
await fs.promises.rm(path.join(osuPath, fileName), {
force: true,
});
}
await fs.promises.writeFile( await fs.promises.writeFile(
path.join(osuPath, fileName), path.join(osuPath, fileName),
axiosDownloadWithProgress.data, axiosDownloadWithProgress.data,
@@ -298,6 +297,11 @@ function downloadPatcherUpdates(osuPath, patcherUpdates) {
}); });
try { try {
if (fs.existsSync(path.join(osuPath, "EZPPLauncher", fileName))) {
await fs.promises.rm(path.join(osuPath, "EZPPLauncher", fileName), {
force: true,
});
}
await fs.promises.writeFile( await fs.promises.writeFile(
path.join(osuPath, "EZPPLauncher", fileName), path.join(osuPath, "EZPPLauncher", fileName),
axiosDownloadWithProgress.data, axiosDownloadWithProgress.data,
@@ -362,6 +366,12 @@ function downloadUIFiles(osuPath, uiFiles) {
}, },
}); });
try { try {
if (fs.existsSync(path.join(osuPath, "EZPPLauncher", fileName))) {
await fs.promises.rm(path.join(osuPath, "EZPPLauncher", fileName), {
force: true,
});
}
await fs.promises.writeFile( await fs.promises.writeFile(
path.join(osuPath, "EZPPLauncher", fileName), path.join(osuPath, "EZPPLauncher", fileName),
axiosDownloadWithProgress.data, axiosDownloadWithProgress.data,

View File

@@ -3,7 +3,7 @@ const { appName, appVersion } = require("./appInfo.js");
const clientId = "1032772293220384808"; const clientId = "1032772293220384808";
let richPresence; let richPresence;
let intervalId let intervalId;
let currentStatus = { let currentStatus = {
details: " ", details: " ",
@@ -28,7 +28,6 @@ let currentStatus = {
module.exports = { module.exports = {
connect: () => { connect: () => {
console.log("Connecting to Discord...");
if (!richPresence) { if (!richPresence) {
richPresence = new DiscordRPC.AutoClient({ transport: "ipc" }); richPresence = new DiscordRPC.AutoClient({ transport: "ipc" });
richPresence.endlessLogin({ clientId }); richPresence.endlessLogin({ clientId });

View File

@@ -1,13 +1,16 @@
const semver = require("semver"); const semver = require("semver");
const { appVersion } = require("./appInfo"); const { appVersion } = require("./appInfo");
const repoUrl = const repoApiUrl =
"https://git.ez-pp.farm/api/v1/repos/EZPPFarm/EZPPLauncher/releases?limit=1"; "https://git.ez-pp.farm/api/v1/repos/EZPPFarm/EZPPLauncher/releases?limit=1";
const releasesUrl =
"https://git.ez-pp.farm/EZPPFarm/EZPPLauncher/releases/latest";
module.exports = { module.exports = {
updateAvailable: async () => { updateAvailable: async () => {
try { try {
const latestRelease = await fetch(repoUrl); const latestRelease = await fetch(repoApiUrl);
const json = await latestRelease.json(); const json = await latestRelease.json();
if (json.length <= 0) return false; if (json.length <= 0) return false;
return { return {
@@ -18,4 +21,5 @@ module.exports = {
return { update: false }; return { update: false };
} }
}, },
releasesUrl,
}; };

23
main.js
View File

@@ -1,5 +1,7 @@
// Modules to control application life and create native browser window // Modules to control application life and create native browser window
const { app, BrowserWindow, Menu, ipcMain, dialog } = require("electron"); const { app, BrowserWindow, Menu, ipcMain, dialog, shell } = require(
"electron",
);
const path = require("path"); const path = require("path");
const serve = require("electron-serve"); const serve = require("electron-serve");
const loadURL = serve({ directory: "public" }); const loadURL = serve({ directory: "public" });
@@ -31,7 +33,7 @@ const richPresence = require("./electron/richPresence");
const cryptUtil = require("./electron/cryptoUtil"); const cryptUtil = require("./electron/cryptoUtil");
const { getHwId } = require("./electron/hwidUtil"); const { getHwId } = require("./electron/hwidUtil");
const { appName, appVersion } = require("./electron/appInfo"); const { appName, appVersion } = require("./electron/appInfo");
const { updateAvailable } = require("./electron/updateCheck"); const { updateAvailable, releasesUrl } = require("./electron/updateCheck");
// Keep a global reference of the window object, if you don't, the window will // Keep a global reference of the window object, if you don't, the window will
// be closed automatically when the JavaScript object is garbage collected. // be closed automatically when the JavaScript object is garbage collected.
@@ -53,7 +55,6 @@ function startOsuStatus() {
osuCheckInterval = setInterval(async () => { osuCheckInterval = setInterval(async () => {
const osuWindowTitle = windowName.getWindowText("osu!.exe"); const osuWindowTitle = windowName.getWindowText("osu!.exe");
if (osuWindowTitle.length < 0) { if (osuWindowTitle.length < 0) {
console.log("No osu! window found");
return; return;
} }
const firstInstance = osuWindowTitle[0]; const firstInstance = osuWindowTitle[0];
@@ -319,6 +320,11 @@ function registerIPCPipes() {
return config.all(); return config.all();
}); });
ipcMain.handle("ezpplauncher:exitAndUpdate", async (e) => {
await shell.openExternal(releasesUrl);
app.exit();
});
ipcMain.handle("ezpplauncher:launch", async (e) => { ipcMain.handle("ezpplauncher:launch", async (e) => {
const configPatch = config.get("patch"); const configPatch = config.get("patch");
patch = configPatch != undefined ? configPatch == "true" : true; patch = configPatch != undefined ? configPatch == "true" : true;
@@ -361,7 +367,7 @@ function registerIPCPipes() {
mainWindow.webContents.send("ezpplauncher:alert", { mainWindow.webContents.send("ezpplauncher:alert", {
type: "error", type: "error",
message: message:
`Failed to download/replace ${filename}!\nMaybe try to rerun the Launcher as Admin.`, `Failed to download/replace ${filename}!\nMaybe try to restart EZPPLauncher.`,
}); });
}); });
uiDownloader.eventEmitter.on("data", (data) => { uiDownloader.eventEmitter.on("data", (data) => {
@@ -392,7 +398,7 @@ function registerIPCPipes() {
mainWindow.webContents.send("ezpplauncher:alert", { mainWindow.webContents.send("ezpplauncher:alert", {
type: "error", type: "error",
message: message:
`Failed to download/replace ${filename}!\nMaybe try to rerun the Launcher as Admin.`, `Failed to download/replace ${filename}!\nMaybe try to restart EZPPLauncher.`,
}); });
}); });
updateDownloader.eventEmitter.on("data", (data) => { updateDownloader.eventEmitter.on("data", (data) => {
@@ -439,7 +445,7 @@ function registerIPCPipes() {
mainWindow.webContents.send("ezpplauncher:alert", { mainWindow.webContents.send("ezpplauncher:alert", {
type: "error", type: "error",
message: message:
`Failed to download/replace ${filename}!\nMaybe try to rerun the Launcher as Admin.`, `Failed to download/replace ${filename}!\nMaybe try to restart EZPPLauncher.`,
}); });
}); });
patcherDownloader.eventEmitter.on("data", (data) => { patcherDownloader.eventEmitter.on("data", (data) => {
@@ -569,7 +575,6 @@ function createWindow() {
if (presenceEnabled == undefined) { if (presenceEnabled == undefined) {
richPresence.connect(); richPresence.connect();
} else { } else {
console.log(presenceEnabled);
if (presenceEnabled == "true") { if (presenceEnabled == "true") {
richPresence.connect(); richPresence.connect();
} }
@@ -580,7 +585,7 @@ function createWindow() {
// Open the DevTools and also disable Electron Security Warning. // Open the DevTools and also disable Electron Security Warning.
if (isDev()) { if (isDev()) {
process.env["ELECTRON_DISABLE_SECURITY_WARNINGS"] = true; process.env["ELECTRON_DISABLE_SECURITY_WARNINGS"] = true;
// mainWindow.webContents.openDevTools({ mode: "detach" }); mainWindow.webContents.openDevTools({ mode: "detach" });
} }
// Emitted when the window is closed. // Emitted when the window is closed.
@@ -595,7 +600,7 @@ function createWindow() {
// This helps in showing the window gracefully. // This helps in showing the window gracefully.
mainWindow.once("ready-to-show", async () => { mainWindow.once("ready-to-show", async () => {
const updateInfo = await updateAvailable(); const updateInfo = await updateAvailable();
if (!updateInfo.update) { if (updateInfo.update) {
mainWindow.webContents.send("ezpplauncher:update", updateInfo.release); mainWindow.webContents.send("ezpplauncher:update", updateInfo.release);
} }
mainWindow.show(); mainWindow.show();

10
package-lock.json generated
View File

@@ -22,6 +22,7 @@
"regedit-rs": "^1.0.2", "regedit-rs": "^1.0.2",
"semver": "^7.5.4", "semver": "^7.5.4",
"svelte-french-toast": "^1.2.0", "svelte-french-toast": "^1.2.0",
"sweetalert2": "^11.10.3",
"systeminformation": "^5.21.22" "systeminformation": "^5.21.22"
}, },
"devDependencies": { "devDependencies": {
@@ -8484,6 +8485,15 @@
"integrity": "sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow==", "integrity": "sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow==",
"dev": true "dev": true
}, },
"node_modules/sweetalert2": {
"version": "11.10.3",
"resolved": "https://registry.npmjs.org/sweetalert2/-/sweetalert2-11.10.3.tgz",
"integrity": "sha512-mZYtQR7v+khyEruq0SsVUa6XIdI9Aue8s2XAIpAwdlLN1T0w7mxKEjyubiBZ3/bLbHC/wGS4wNABvXWubCizvA==",
"funding": {
"type": "individual",
"url": "https://github.com/sponsors/limonte"
}
},
"node_modules/systeminformation": { "node_modules/systeminformation": {
"version": "5.21.22", "version": "5.21.22",
"resolved": "https://registry.npmjs.org/systeminformation/-/systeminformation-5.21.22.tgz", "resolved": "https://registry.npmjs.org/systeminformation/-/systeminformation-5.21.22.tgz",

View File

@@ -17,7 +17,6 @@
"electron/**/*" "electron/**/*"
], ],
"win": { "win": {
"requestedExecutionLevel": "requireAdministrator",
"target": [ "target": [
"portable" "portable"
] ]
@@ -50,6 +49,7 @@
"regedit-rs": "^1.0.2", "regedit-rs": "^1.0.2",
"semver": "^7.5.4", "semver": "^7.5.4",
"svelte-french-toast": "^1.2.0", "svelte-french-toast": "^1.2.0",
"sweetalert2": "^11.10.3",
"systeminformation": "^5.21.22" "systeminformation": "^5.21.22"
}, },
"devDependencies": { "devDependencies": {

View File

@@ -82,6 +82,10 @@ window.addEventListener("settings-set", async (e) => {
await ipcRenderer.invoke("ezpplauncher:settings-set", e.detail); await ipcRenderer.invoke("ezpplauncher:settings-set", e.detail);
}); });
window.addEventListener("updateExit", async () => {
await ipcRenderer.invoke("ezpplauncher:exitAndUpdate");
});
ipcRenderer.addListener("ezpplauncher:launchabort", (e, args) => { ipcRenderer.addListener("ezpplauncher:launchabort", (e, args) => {
window.dispatchEvent( window.dispatchEvent(
new CustomEvent("launch-abort"), new CustomEvent("launch-abort"),

View File

@@ -6,7 +6,6 @@
DropdownHeader, DropdownHeader,
DropdownDivider, DropdownDivider,
Button, Button,
Modal,
Indicator, Indicator,
} from "flowbite-svelte"; } from "flowbite-svelte";
import { import {
@@ -30,11 +29,11 @@
import toast, { Toaster } from "svelte-french-toast"; import toast, { Toaster } from "svelte-french-toast";
import type { User } from "./types/user"; import type { User } from "./types/user";
import Settings from "./pages/Settings.svelte"; import Settings from "./pages/Settings.svelte";
import Swal from "sweetalert2";
let user: User | undefined = undefined; let user: User | undefined = undefined;
let loggedIn = false; let loggedIn = false;
let showUpdateDialog = false;
let updateInfo: Record<string, unknown>; let updateInfo: Record<string, unknown>;
currentUser.subscribe((newUser) => { currentUser.subscribe((newUser) => {
@@ -54,14 +53,17 @@
}); });
}; };
window.addEventListener("update", (e) => { window.addEventListener("update", async (e) => {
const update = (e as CustomEvent).detail; const update = (e as CustomEvent).detail;
setTimeout(() => { await Swal.fire({
showUpdateDialog = true; html: `EZPPLauncher ${update.tag_name} is now available!<br>Click the Button bellow to download the latest release!`,
updateInfo = update; title: "It's your lucky day!",
allowOutsideClick: false,
document.getElementById("updateDialog")?.blur(); allowEscapeKey: false,
}, 2000); allowEnterKey: false,
confirmButtonText: "Thanks!",
});
window.dispatchEvent(new CustomEvent("updateExit"));
}); });
window.addEventListener("launchStatusUpdate", (e) => { window.addEventListener("launchStatusUpdate", (e) => {
@@ -117,104 +119,104 @@
<Toaster></Toaster> <Toaster></Toaster>
<!-- TODO: Update dialog--> {#if !updateInfo}
<div class="p-2 flex flex-row justify-between items-center">
<div class="p-2 flex flex-row justify-between items-center"> <div class="flex flex-row items-center animate-fadeIn opacity-0">
<div class="flex flex-row items-center animate-fadeIn opacity-0"> {#if $currentPage == Page.Settings}
{#if $currentPage == Page.Settings} <Button
<Button class="dark:active:!bg-gray-900 !ring-0 w-10 h-10 mr-1 rounded-lg animate-sideIn opacity-0 active:scale-95 transition-transform duration-75"
class="dark:active:!bg-gray-900 !ring-0 w-10 h-10 mr-1 rounded-lg animate-sideIn opacity-0 active:scale-95 transition-transform duration-75" color="light"
color="light" on:click={() => {
on:click={() => { currentPage.set(Page.Launch);
currentPage.set(Page.Launch); }}
}}
>
<ArrowLeftSolid class="outline-none border-none" size="sm" />
</Button>
{/if}
<img src={ezppLogo} alt="EZPPFarm Logo" class="w-12 h-12 mr-2" />
<span class="text-gray-700 dark:text-gray-100 text-xl font-extralight">
EZPPLauncher
</span>
</div>
{#if $currentPage == Page.Launch}
<div
class="flex flex-row gap-2 w-fill cursor-pointer md:order-2 animate-lsideIn opacity-0"
>
<Avatar
class="rounded-lg border dark:border-gray-700 hover:ring-4 hover:ring-gray-200 dark:hover:ring-gray-800"
src={loggedIn
? "https://a.ez-pp.farm/" + user?.id
: "https://a.ez-pp.farm/0"}
id="avatar-menu"
/>
<!-- TODO: if user has donator, display heart indicator-->
{#if $currentUser && $currentUser.id == 1001}
<Indicator
class="pointer-events-none"
color="red"
border
size="xl"
placement="top-right"
> >
<span class="text-red-300 text-xs font-bold"> <ArrowLeftSolid class="outline-none border-none" size="sm" />
<HeartSolid class="select-none pointer-events-none" size="xs" /> </Button>
</span>
</Indicator>
{/if} {/if}
<img src={ezppLogo} alt="EZPPFarm Logo" class="w-12 h-12 mr-2" />
<span class="text-gray-700 dark:text-gray-100 text-xl font-extralight">
EZPPLauncher
</span>
</div> </div>
<Dropdown placement="bottom-start" triggeredBy="#avatar-menu"> {#if $currentPage == Page.Launch}
<DropdownHeader> <div
<span class="block text-sm">{loggedIn ? user?.name : "Guest"}</span> class="flex flex-row gap-2 w-fill cursor-pointer md:order-2 animate-lsideIn opacity-0"
<span
class="block truncate text-sm font-medium text-gray-500 dark:text-gray-200"
>
{loggedIn ? user?.email : "Please log in!"}
</span>
</DropdownHeader>
<DropdownItem
class="flex flex-row gap-2 border-0 dark:!bg-gray-700 dark:active:!bg-gray-900 dark:hover:!bg-gray-800 transition-colors"
on:click={() => {
if (!$launching) currentPage.set(Page.Settings);
}}
> >
<UserSettingsSolid class="select-none outline-none border-none" /> <Avatar
Settings class="rounded-lg border dark:border-gray-700 hover:ring-4 hover:ring-gray-200 dark:hover:ring-gray-800"
</DropdownItem> src={loggedIn
<DropdownDivider /> ? "https://a.ez-pp.farm/" + user?.id
{#if loggedIn} : "https://a.ez-pp.farm/0"}
id="avatar-menu"
/>
<!-- TODO: if user has donator, display heart indicator-->
{#if $currentUser && $currentUser.donor}
<Indicator
class="pointer-events-none"
color="red"
border
size="xl"
placement="top-right"
>
<span class="text-red-300 text-xs font-bold">
<HeartSolid class="select-none pointer-events-none" size="xs" />
</span>
</Indicator>
{/if}
</div>
<Dropdown placement="bottom-start" triggeredBy="#avatar-menu">
<DropdownHeader>
<span class="block text-sm">{loggedIn ? user?.name : "Guest"}</span>
<span
class="block truncate text-sm font-medium text-gray-500 dark:text-gray-200"
>
{loggedIn ? user?.email : "Please log in!"}
</span>
</DropdownHeader>
<DropdownItem <DropdownItem
class="flex flex-row gap-2 border-0 dark:!bg-gray-700 dark:active:!bg-gray-900 dark:hover:!bg-gray-800 transition-colors" class="flex flex-row gap-2 border-0 dark:!bg-gray-700 dark:active:!bg-gray-900 dark:hover:!bg-gray-800 transition-colors"
on:click={() => { on:click={() => {
if (!$launching) logout(); if (!$launching) currentPage.set(Page.Settings);
}} }}
> >
<ArrowRightFromBracketSolid <UserSettingsSolid class="select-none outline-none border-none" />
class="select-none outline-none border-none" Settings
/>
Sign out
</DropdownItem> </DropdownItem>
{:else} <DropdownDivider />
<DropdownItem {#if loggedIn}
class="flex flex-row gap-2 border-0 dark:!bg-gray-700 dark:active:!bg-gray-900 dark:hover:!bg-gray-800 transition-colors" <DropdownItem
on:click={() => { class="flex flex-row gap-2 border-0 dark:!bg-gray-700 dark:active:!bg-gray-900 dark:hover:!bg-gray-800 transition-colors"
if (!$launching) currentPage.set(Page.Login); on:click={() => {
}} if (!$launching) logout();
> }}
<ArrowRightToBracketSolid >
class="select-none outline-none border-none" <ArrowRightFromBracketSolid
/> class="select-none outline-none border-none"
Login />
</DropdownItem> Sign out
{/if} </DropdownItem>
</Dropdown> {:else}
{/if} <DropdownItem
</div> class="flex flex-row gap-2 border-0 dark:!bg-gray-700 dark:active:!bg-gray-900 dark:hover:!bg-gray-800 transition-colors"
on:click={() => {
if (!$launching) currentPage.set(Page.Login);
}}
>
<ArrowRightToBracketSolid
class="select-none outline-none border-none"
/>
Login
</DropdownItem>
{/if}
</Dropdown>
{/if}
</div>
{#if $currentPage == Page.Login} {#if $currentPage == Page.Login}
<Login /> <Login />
{:else if $currentPage == Page.Settings} {:else if $currentPage == Page.Settings}
<Settings /> <Settings />
{:else} {:else}
<Launch /> <Launch />
{/if}
{/if} {/if}

View File

@@ -58,6 +58,15 @@ html .cet-titlebar .cet-control-icon svg {
background-color: #202020 !important; background-color: #202020 !important;
color: #ececec !important; color: #ececec !important;
} }
.swal2-container {
background: #202020 !important;
}
.swal2-container .swal2-popup {
background: #323232 !important;
color: #fff !important;
}
} }
.animatedProgress div { .animatedProgress div {

View File

@@ -1,5 +1,6 @@
export type User = { export type User = {
id: number; id: number;
donor: boolean;
name: string; name: string;
email: string; email: string;
}; };