24 Commits
2.1.0 ... 2.1.4

Author SHA1 Message Date
2bb4a86df3 Merge pull request 'dev' (#14) from dev into master
Reviewed-on: #14
2024-04-14 15:32:58 +00:00
f41ca92711 update readme 2024-04-14 17:32:11 +02:00
65a3e86261 bump version 2024-04-14 17:31:37 +02:00
c74bc57453 remove test 2024-04-14 17:17:07 +02:00
528af70446 add .net8 check when patch is enabled 2024-04-14 17:16:46 +02:00
6f2764a047 patcher update, no more hardcoded urls, launch fixes 2024-04-14 16:36:32 +02:00
1c4a40c495 add mode and global rank to rpc 2024-03-16 18:48:44 +01:00
144d1bb86a Merge pull request 'bump version' (#13) from dev into master
Reviewed-on: #13
2024-03-11 18:36:17 +00:00
a9de377456 bump version 2024-03-11 19:35:54 +01:00
c3f0882951 Merge pull request 'add dynamic beatmap images to presence' (#12) from dev into master
Reviewed-on: #12
2024-03-11 17:55:54 +00:00
c17cbc48d8 fix user reset 2024-03-11 18:46:04 +01:00
513692c2d5 reset user on exit 2024-03-11 18:37:33 +01:00
90717ed960 display user as small image, fix dynamic beatmap images 2024-03-11 18:06:24 +01:00
6bcce04b72 Merge branch 'dev' of https://git.ez-pp.farm/EZPPFarm/EZPPLauncher into dev 2024-03-11 17:34:38 +01:00
8d2024aa0a check if rpc is connected 2024-03-11 17:34:36 +01:00
22815e74b6 check if beatmap is not null 2024-03-11 15:46:07 +01:00
c4d9862860 assign the cover url to a const 2024-03-11 15:42:08 +01:00
d56d4875e0 add dynamic beatmap image to presence 2024-03-11 15:38:20 +01:00
4c33323e9e Merge pull request 'oops' (#10) from dev into master
Reviewed-on: #10
2024-01-30 08:52:43 +00:00
da8e237679 oops 2024-01-30 09:51:23 +01:00
eb166c0165 Merge pull request 'bump patch version' (#9) from dev into master
Reviewed-on: #9
2024-01-29 07:58:55 +00:00
c4cd8fed12 bump patch version 2024-01-29 08:58:42 +01:00
6bca0b32a9 Merge pull request 'disable unhandled error logging for now' (#8) from dev into master
Reviewed-on: #8
2024-01-29 07:57:48 +00:00
72d466b1ec disable unhandled error logging for now 2024-01-29 08:57:28 +01:00
15 changed files with 692 additions and 880 deletions

View File

@@ -12,6 +12,7 @@ The Launcher is a "plug and play thing", download it, place it on the desktop an
- Automatic osu! client updating before Launch
- Custom osu! Logo in MainMenu
- Relax misses and much more
- Account saving
## Build from source

View File

@@ -1,4 +1,4 @@
const appName = "EZPPLauncher";
const appVersion = "2.1.0";
const appVersion = "2.1.4";
module.exports = { appName, appVersion };

15
electron/imageUtil.js Normal file
View File

@@ -0,0 +1,15 @@
async function checkImageExists(url) {
try {
const response = await fetch(url, { method: "HEAD" });
if (!response.ok) {
return false;
}
const contentType = response.headers.get("content-type");
if (!contentType) return false;
return contentType.startsWith("image/");
} catch (error) {
return false;
}
}
module.exports = { checkImageExists };

20
electron/netUtils.js Normal file
View File

@@ -0,0 +1,20 @@
const { exec } = require("child_process");
async function isNet8Installed() {
return new Promise((resolve, reject) => {
exec("dotnet --version", (error, stdout, stderr) => {
if (error) {
resolve(false);
return;
}
if (stderr) {
resolve(false);
return;
}
const version = stdout.trim();
resolve(version.startsWith("8."));
})
});
}
module.exports = { isNet8Installed };

View File

@@ -10,6 +10,16 @@ const checkUpdateURL =
const ignoredOsuEntities = [
"osu!auth.dll",
];
const gamemodes = {
0: "osu!",
1: "taiko",
2: "catch",
3: "mania",
4: "osu!(rx)",
5: "taiko(rx)",
6: "catch(rx)",
8: "osu!(ap)"
}
const osuEntities = [
"avcodec-51.dll",
"avformat-52.dll",
@@ -34,26 +44,7 @@ const osuEntities = [
"scores.db",
];
const patcherFiles = [
{
name: "patcher.exe",
url_download: "https://ez-pp.farm/assets/patcher.exe",
url_hash: "https://ez-pp.farm/assets/patcher.md5",
},
{
name: "patch.hook.dll",
url_download: "https://ez-pp.farm/assets/patch.hook.dll",
url_hash: "https://ez-pp.farm/assets/patch.hook.md5",
},
];
const uiFiles = [
{
name: "ezpp!ui.dll",
url_download: "https://ez-pp.farm/assets/ezpp!ui.dll",
url_hash: "https://ez-pp.farm/assets/ezpp!ui.md5",
},
];
const ezppLauncherUpdateList = "https://ez-pp.farm/ezpplauncher"
async function isValidOsuFolder(path) {
const allFiles = await fs.promises.readdir(path);
@@ -255,115 +246,41 @@ function runOsuWithDevServer(osuPath, serverDomain, onExit) {
runFile(osuPath, osuExecuteable, ["-devserver", serverDomain], onExit);
}
async function getPatcherUpdates(osuPath) {
async function getEZPPLauncherUpdateFiles(osuPath) {
const filesToDownload = [];
const patcherDir = path.join(osuPath, "EZPPLauncher");
if (!fs.existsSync(patcherDir)) fs.mkdirSync(patcherDir);
for (const patcherFile of patcherFiles) {
if (fs.existsSync(path.join(patcherDir, patcherFile.name))) {
const latestPatchFileHash = await (await fetch(patcherFile.url_hash))
.text();
const localPatchFileHash = crypto.createHash("md5").update(
fs.readFileSync(path.join(patcherDir, patcherFile.name)),
).digest("hex");
if (
latestPatchFileHash.trim().toLowerCase() !=
localPatchFileHash.trim().toLowerCase()
) filesToDownload.push(patcherFile);
} else filesToDownload.push(patcherFile);
}
return filesToDownload;
}
function downloadPatcherUpdates(osuPath, patcherUpdates) {
const eventEmitter = new EventEmitter();
const startDownload = async () => {
const patcherDir = path.join(osuPath, "EZPPLauncher");
if (!fs.existsSync(patcherDir)) fs.mkdirSync(patcherDir);
for (const patcherFile of patcherUpdates) {
const fileName = patcherFile.name;
const fileURL = patcherFile.url_download;
const axiosDownloadWithProgress = await axios.get(fileURL, {
responseType: "stream",
onDownloadProgress: (progressEvent) => {
const { loaded, total } = progressEvent;
eventEmitter.emit("data", {
fileName,
loaded,
total,
progress: Math.floor((loaded / total) * 100),
});
},
});
try {
if (fs.existsSync(path.join(osuPath, "EZPPLauncher", fileName))) {
await fs.promises.rm(path.join(osuPath, "EZPPLauncher", fileName), {
force: true,
});
}
await fs.promises.writeFile(
path.join(osuPath, "EZPPLauncher", fileName),
axiosDownloadWithProgress.data,
);
} catch (err) {
console.log(err);
eventEmitter.emit("error", {
fileName,
});
const updateFilesRequest = await fetch(ezppLauncherUpdateList, { method: "PATCH" });
const updateFiles = await updateFilesRequest.json();
for (const updateFile of updateFiles) {
const filePath = path.join(osuPath, ...updateFile.folder.split("/"), updateFile.name);
if (fs.existsSync(filePath)) {
const fileHash = updateFile.md5.toLowerCase();
const localFileHash = crypto.createHash("md5").update(
fs.readFileSync(filePath),
).digest("hex").toLowerCase();
if (fileHash !== localFileHash) {
filesToDownload.push(updateFile);
}
} else {
filesToDownload.push(updateFile);
}
};
return {
eventEmitter,
startDownload,
};
}
async function getUIFiles(osuPath) {
const filesToDownload = [];
const ezppLauncherDir = path.join(osuPath, "EZPPLauncher");
if (!fs.existsSync(ezppLauncherDir)) fs.mkdirSync(ezppLauncherDir);
for (const uiFile of uiFiles) {
if (fs.existsSync(path.join(ezppLauncherDir, uiFile.name))) {
const latestPatchFileHash = await (await fetch(uiFile.url_hash)).text();
const localPatchFileHash = crypto.createHash("md5").update(
fs.readFileSync(path.join(ezppLauncherDir, uiFile.name)),
).digest("hex");
if (
latestPatchFileHash.trim().toLowerCase() !=
localPatchFileHash.trim().toLowerCase()
) filesToDownload.push(uiFile);
} else filesToDownload.push(uiFile);
}
return filesToDownload;
}
function downloadUIFiles(osuPath, uiFiles) {
async function downloadEZPPLauncherUpdateFiles(osuPath, updateFiles) {
const eventEmitter = new EventEmitter();
const startDownload = async () => {
const ezpplauncherDir = path.join(osuPath, "EZPPLauncher");
if (!fs.existsSync(ezpplauncherDir)) fs.mkdirSync(ezpplauncherDir);
for (const uiFile of uiFiles) {
const fileName = uiFile.name;
const fileURL = uiFile.url_download;
const axiosDownloadWithProgress = await axios.get(fileURL, {
for (const updateFile of updateFiles) {
const filePath = path.join(osuPath, ...updateFile.folder.split("/"), updateFile.name);
const folder = path.dirname(filePath);
if (!fs.existsSync(folder)) await fs.promises.mkdir(folder, { recursive: true });
const axiosDownloadWithProgress = await axios.get(updateFile.url, {
responseType: "stream",
onDownloadProgress: (progressEvent) => {
const { loaded, total } = progressEvent;
eventEmitter.emit("data", {
fileName,
fileName: path.basename(filePath),
loaded,
total,
progress: Math.floor((loaded / total) * 100),
@@ -371,24 +288,23 @@ function downloadUIFiles(osuPath, uiFiles) {
},
});
try {
if (fs.existsSync(path.join(osuPath, "EZPPLauncher", fileName))) {
await fs.promises.rm(path.join(osuPath, "EZPPLauncher", fileName), {
if (fs.existsSync(filePath)) {
await fs.promises.rm(filePath, {
force: true,
});
}
await fs.promises.writeFile(
path.join(osuPath, "EZPPLauncher", fileName),
filePath,
axiosDownloadWithProgress.data,
);
} catch (err) {
console.log(err);
eventEmitter.emit("error", {
fileName,
fileName: path.basename(filePath),
});
}
}
};
}
return {
eventEmitter,
@@ -396,23 +312,41 @@ function downloadUIFiles(osuPath, uiFiles) {
};
}
async function replaceUIFile(osuPath, revert) {
async function replaceUIFiles(osuPath, revert) {
if (!revert) {
const ezppUIFile = path.join(osuPath, "EZPPLauncher", "ezpp!ui.dll");
const oldOsuUIFile = path.join(osuPath, "osu!ui.dll");
const ezppGameplayFile = path.join(osuPath, "EZPPLauncher", "ezpp!gameplay.dll");
const oldOsuGameplayFile = path.join(osuPath, "osu!gameplay.dll");
await fs.promises.rename(
oldOsuUIFile,
path.join(osuPath, "osu!ui.dll.bak"),
);
await fs.promises.rename(ezppUIFile, oldOsuUIFile);
await fs.promises.rename(
oldOsuGameplayFile,
path.join(osuPath, "osu!gameplay.dll.bak"),
);
await fs.promises.rename(ezppGameplayFile, oldOsuGameplayFile);
} else {
const oldOsuUIFile = path.join(osuPath, "osu!ui.dll");
const ezppUIFile = path.join(osuPath, "EZPPLauncher", "ezpp!ui.dll");
const oldOsuGameplayFile = path.join(osuPath, "osu!gameplay.dll");
const ezppGameplayFile = path.join(osuPath, "EZPPLauncher", "ezpp!gameplay.dll");
await fs.promises.rename(oldOsuUIFile, ezppUIFile);
await fs.promises.rename(
path.join(osuPath, "osu!ui.dll.bak"),
oldOsuUIFile,
);
await fs.promises.rename(oldOsuGameplayFile, ezppGameplayFile);
await fs.promises.rename(
path.join(osuPath, "osu!gameplay.dll.bak"),
oldOsuGameplayFile,
);
}
}
@@ -473,12 +407,11 @@ module.exports = {
getFilesThatNeedUpdate,
downloadUpdateFiles,
runOsuWithDevServer,
getPatcherUpdates,
downloadPatcherUpdates,
downloadUIFiles,
getUIFiles,
replaceUIFile,
replaceUIFiles,
findOsuInstallation,
updateOsuConfigHashes,
runOsuUpdater,
getEZPPLauncherUpdateFiles,
downloadEZPPLauncherUpdateFiles,
gamemodes
};

View File

@@ -2,7 +2,10 @@ const DiscordRPC = require("discord-auto-rpc");
const { appName, appVersion } = require("./appInfo.js");
const clientId = "1032772293220384808";
/** @type {DiscordRPC.AutoClient} */
let richPresence;
let intervalId;
let currentStatus = {
@@ -32,6 +35,7 @@ module.exports = {
richPresence = new DiscordRPC.AutoClient({ transport: "ipc" });
richPresence.endlessLogin({ clientId });
richPresence.once("ready", () => {
console.log("connected presence with user " + richPresence.user.username);
richPresence.setActivity(currentStatus);
intervalId = setInterval(() => {
richPresence.setActivity(currentStatus);
@@ -47,16 +51,17 @@ module.exports = {
richPresence = null;
}
},
updateStatus: ({ state, details }) => {
updateStatus: ({ state, details, largeImageKey }) => {
currentStatus.state = state ?? " ";
currentStatus.details = details ?? " ";
currentStatus.largeImageKey = largeImageKey ?? "ezppfarm";
},
updateVersion: (osuVersion) => {
currentStatus.smallImageKey = osuVersion ? "osu" : " ";
currentStatus.smallImageText = osuVersion ? `osu! ${osuVersion}` : " ";
updateUser: ({ username, id }) => {
currentStatus.smallImageKey = id ? `https://a.ez-pp.farm/${id}` : " ";
currentStatus.smallImageText = username ?? " ";
},
update: () => {
if (richPresence) {
if (richPresence && richPresence.user) {
richPresence.setActivity(currentStatus);
}
},

157
main.js
View File

@@ -3,15 +3,6 @@ const { app, BrowserWindow, Menu, ipcMain, dialog, shell } = require(
"electron",
);
const unhandled = require("electron-unhandled");
unhandled({
logger: console.error,
showDialog: true,
reportButton: () => {
shell.openExternal("https://ez-pp.farm/discord");
},
});
const path = require("path");
const serve = require("electron-serve");
const loadURL = serve({ directory: "public" });
@@ -27,14 +18,13 @@ const {
downloadUpdateFiles,
getUserConfig,
runOsuWithDevServer,
getPatcherUpdates,
downloadPatcherUpdates,
getUIFiles,
downloadUIFiles,
replaceUIFile,
replaceUIFiles,
findOsuInstallation,
updateOsuConfigHashes,
runOsuUpdater,
gamemodes,
getEZPPLauncherUpdateFiles,
downloadEZPPLauncherUpdateFiles,
} = require("./electron/osuUtil");
const { formatBytes } = require("./electron/formattingUtil");
const windowName = require("get-window-by-name");
@@ -46,6 +36,8 @@ const { getHwId } = require("./electron/hwidUtil");
const { appName, appVersion } = require("./electron/appInfo");
const { updateAvailable, releasesUrl } = require("./electron/updateCheck");
const fkill = require("fkill");
const { checkImageExists } = require("./electron/imageUtil");
const { isNet8Installed } = require("./electron/netUtils");
// 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.
@@ -72,12 +64,32 @@ function startOsuStatus() {
if (firstInstance) {
if (!osuLoaded) {
osuLoaded = true;
try {
const currentUserInfo = await fetch(`https://api.ez-pp.farm/get_player_info?name=${currentUser.username}&scope=info`);
const currentUserInfoJson = await currentUserInfo.json();
if ("player" in currentUserInfoJson && currentUserInfoJson.player != null) {
if ("info" in currentUserInfoJson.player && currentUserInfoJson.player.info != null) {
const id = currentUserInfoJson.player.info.id;
const username = currentUserInfoJson.player.info.name;
richPresence.updateUser({
id,
username,
});
richPresence.update();
}
}
} catch {
}
setTimeout(() => {
if (patch) {
const patcherExecuteable = path.join(
userOsuPath,
"EZPPLauncher",
"patcher.exe",
"patcher",
"osu!.patcher.exe",
);
if (fs.existsSync(patcherExecuteable)) {
runFileDetached(userOsuPath, patcherExecuteable);
@@ -96,15 +108,45 @@ function startOsuStatus() {
if (!("player_status" in currentStatus)) return;
if (!("status" in currentStatus.player_status)) return;
const currentMode = currentStatus.player_status.status.mode;
const currentModeString = gamemodes[currentMode];
const currentInfoRequest = await fetch(
"https://api.ez-pp.farm/get_player_info?name=" + currentUser.username + "&scope=all",
);
const currentInfo = await currentInfoRequest.json();
let currentUsername = currentInfo.player.info.name;
const currentId = currentInfo.player.info.id;
const currentStats = currentInfo.player.stats[currentMode];
currentUsername += ` (#${currentStats.rank})`;
let largeImageKey = "ezppfarm";
let details = "Idle...";
let infoText = currentStatus.player_status.status.info_text.length > 0
? currentStatus.player_status.status.info_text
: " ";
if (
"beatmap" in currentStatus.player_status.status &&
currentStatus.player_status.status.beatmap !== null
) {
const setId = currentStatus.player_status.status.beatmap.set_id;
if (setId) {
const coverImage =
`https://assets.ppy.sh/beatmaps/${setId}/covers/list@2x.jpg`;
if (
checkImageExists(coverImage)
) {
largeImageKey = coverImage;
}
}
}
switch (currentStatus.player_status.status.action) {
case 1:
details = "AFK...";
infoText = " ";
largeImageKey = "ezppfarm";
break;
case 2:
details = "Playing...";
@@ -118,6 +160,7 @@ function startOsuStatus() {
case 5:
details = "Multiplayer: Selecting a Beatmap...";
infoText = " ";
largeImageKey = "ezppfarm";
break;
case 6:
details = "Watching...";
@@ -127,10 +170,12 @@ function startOsuStatus() {
break;
case 9:
details = "Submitting...";
largeImageKey = "ezppfarm";
break;
case 11:
details = "Multiplayer: Idle...";
infoText = " ";
largeImageKey = "ezppfarm";
break;
case 12:
details = "Multiplayer: Playing...";
@@ -138,12 +183,21 @@ function startOsuStatus() {
case 13:
details = "Browsing osu!direct...";
infoText = " ";
largeImageKey = "ezppfarm";
break;
}
details = `[${currentModeString}] ${details}`;
richPresence.updateUser({
username: currentUsername,
id: currentId,
})
richPresence.updateStatus({
details,
state: infoText,
largeImageKey,
});
richPresence.update();
@@ -351,6 +405,7 @@ function registerIPCPipes() {
type: "error",
message: "osu! path not set!",
});
mainWindow.webContents.send("ezpplauncher:open-settings");
return;
}
if (!(await isValidOsuFolder(osuPath))) {
@@ -361,45 +416,24 @@ function registerIPCPipes() {
});
return;
}
if (patch) {
if (!(await isNet8Installed())) {
mainWindow.webContents.send("ezpplauncher:launchabort");
mainWindow.webContents.send("ezpplauncher:alert", {
type: "error",
message: ".NET 8 is not installed.",
});
//open .net 8 download in browser
shell.openExternal('https://dotnet.microsoft.com/en-us/download/dotnet/thank-you/runtime-desktop-8.0.4-windows-x64-installer');
}
}
mainWindow.webContents.send("ezpplauncher:launchstatus", {
status: "Checking for osu! updates...",
});
await new Promise((res) => setTimeout(res, 1000));
const releaseStream = await getGlobalConfig(osuPath).get("_ReleaseStream");
const latestFiles = await getUpdateFiles(releaseStream);
const uiFiles = await getUIFiles(osuPath);
const updateFiles = await getFilesThatNeedUpdate(osuPath, latestFiles);
if (uiFiles.length > 0) {
const uiDownloader = downloadUIFiles(osuPath, uiFiles);
let errored = false;
uiDownloader.eventEmitter.on("error", (data) => {
const filename = data.fileName;
errored = true;
mainWindow.webContents.send("ezpplauncher:alert", {
type: "error",
message:
`Failed to download/replace ${filename}!\nMaybe try to restart EZPPLauncher.`,
});
});
uiDownloader.eventEmitter.on("data", (data) => {
mainWindow.webContents.send("ezpplauncher:launchprogress", {
progress: Math.ceil(data.progress),
});
mainWindow.webContents.send("ezpplauncher:launchstatus", {
status: `Downloading ${data.fileName}(${formatBytes(data.loaded)}/${
formatBytes(data.total)
})...`,
});
});
await uiDownloader.startDownload();
mainWindow.webContents.send("ezpplauncher:launchprogress", {
progress: -1,
});
if (errored) {
mainWindow.webContents.send("ezpplauncher:launchabort");
return;
}
}
if (updateFiles.length > 0) {
const updateDownloader = downloadUpdateFiles(osuPath, updateFiles);
let errored = false;
@@ -417,9 +451,8 @@ function registerIPCPipes() {
progress: Math.ceil(data.progress),
});
mainWindow.webContents.send("ezpplauncher:launchstatus", {
status: `Downloading ${data.fileName}(${formatBytes(data.loaded)}/${
formatBytes(data.total)
})...`,
status: `Downloading ${data.fileName}(${formatBytes(data.loaded)}/${formatBytes(data.total)
})...`,
});
});
await updateDownloader.startDownload();
@@ -446,9 +479,9 @@ function registerIPCPipes() {
status: "Looking for patcher updates...",
});
await new Promise((res) => setTimeout(res, 1000));
const patchFiles = await getPatcherUpdates(osuPath);
const patchFiles = await getEZPPLauncherUpdateFiles(osuPath);
if (patchFiles.length > 0) {
const patcherDownloader = downloadPatcherUpdates(osuPath, patchFiles);
const patcherDownloader = await downloadEZPPLauncherUpdateFiles(osuPath, patchFiles);
let errored = false;
patcherDownloader.eventEmitter.on("error", (data) => {
const filename = data.fileName;
@@ -464,9 +497,8 @@ function registerIPCPipes() {
progress: Math.ceil(data.progress),
});
mainWindow.webContents.send("ezpplauncher:launchstatus", {
status: `Downloading ${data.fileName}(${formatBytes(data.loaded)}/${
formatBytes(data.total)
})...`,
status: `Downloading ${data.fileName}(${formatBytes(data.loaded)}/${formatBytes(data.total)
})...`,
});
});
await patcherDownloader.startDownload();
@@ -520,14 +552,14 @@ function registerIPCPipes() {
});
await updateOsuConfigHashes(osuPath);
await replaceUIFile(osuPath, false);
await replaceUIFiles(osuPath, false);
const forceUpdateFiles = [
".require_update",
"help.txt",
"_pending",
];
//TODO: needs testing
try {
for (const updateFileName of forceUpdateFiles) {
const updateFile = path.join(osuPath, updateFileName);
@@ -538,11 +570,9 @@ function registerIPCPipes() {
});
}
}
} catch {}
} catch { }
const userConfig = getUserConfig(osuPath);
richPresence.updateVersion(await userConfig.get("LastVersion"));
richPresence.update();
if (richPresence.hasPresence) {
await userConfig.set("DiscordRichPresence", "0");
}
@@ -563,7 +593,10 @@ function registerIPCPipes() {
mainWindow.show();
mainWindow.focus();
stopOsuStatus();
richPresence.updateVersion();
richPresence.updateUser({
username: " ",
id: undefined
});
richPresence.updateStatus({
state: "Idle in Launcher...",
details: undefined,
@@ -574,7 +607,7 @@ function registerIPCPipes() {
});
setTimeout(async () => {
await replaceUIFile(osuPath, true);
await replaceUIFiles(osuPath, true);
mainWindow.webContents.send("ezpplauncher:launchabort");
osuLoaded = false;
}, 5000);

1113
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +1,6 @@
{
"name": "ezpplauncher-next",
"version": "2.1.0",
"version": "2.1.4",
"description": "EZPPLauncher rewritten with Svelte.",
"private": false,
"license": "MIT",
@@ -61,7 +61,6 @@
"@rollup/plugin-node-resolve": "^15.2.3",
"@rollup/plugin-terser": "^0.4.4",
"@rollup/plugin-typescript": "^11.1.5",
"@sveltejs/vite-plugin-svelte": "^3.0.1",
"@tsconfig/svelte": "^5.0.2",
"autoprefixer": "^10.4.16",
"concurrently": "^8.2.2",

View File

@@ -115,3 +115,9 @@ ipcRenderer.addListener("ezpplauncher:update", (e, args) => {
new CustomEvent("update", { detail: args }),
);
});
ipcRenderer.addListener("ezpplauncher:open-settings", (e, args) => {
window.dispatchEvent(
new CustomEvent("open-settings"),
);
});

View File

@@ -66,6 +66,10 @@
window.dispatchEvent(new CustomEvent("updateExit"));
});
window.addEventListener("open-settings", (e) => {
currentPage.set(Page.Settings);
});
window.addEventListener("launchStatusUpdate", (e) => {
const status = (e as CustomEvent).detail.status;
launchStatus.set(status);

View File

@@ -26,12 +26,12 @@
green: "bg-green-600 dark:bg-green-500",
yellow: "bg-yellow-400",
purple: "bg-purple-600 dark:bg-purple-500",
indigo: "bg-indigo-600 dark:bg-indigo-500",
indigo: "bg-indigo-600 dark:bg-indigo-500"
};
let _progress = tweened(0, {
duration: tweenDuration,
easing,
easing
});
$: {
@@ -50,8 +50,12 @@
>
<span class="text-sm font-medium text-blue-700 dark:text-white"
>{animate
? $_progress.toFixed(precision)
: progress.toFixed(precision)}%</span
? isNaN($_progress)
? parseInt("100").toFixed(precision)
: $_progress.toFixed(precision)
: isNaN(progress)
? parseInt("100").toFixed(precision)
: progress.toFixed(precision)}%</span
>
</div>
{/if}
@@ -63,7 +67,13 @@
class={twJoin(labelInsideClass, barColors[color])}
style="width: {animate ? $_progress : progress}%"
>
{animate ? $_progress.toFixed(precision) : progress.toFixed(precision)}%
{animate
? isNaN($_progress)
? parseInt("100").toFixed(precision)
: $_progress.toFixed(precision)
: isNaN(progress)
? parseInt("100").toFixed(precision)
: progress.toFixed(precision)}%
</div>
{:else}
<div

View File

@@ -1,11 +1,11 @@
<script lang="ts">
import { Button, Checkbox } from "flowbite-svelte";
import { Button } from "flowbite-svelte";
import Progressbar from "../lib/Progressbar.svelte";
import {
launching,
patch,
launchStatus,
launchPercentage,
launchPercentage
} from "./../storage/localStore";
let progressbarFix = true;

View File

@@ -1,7 +1,6 @@
<script lang="ts">
import { Input, Button, Spinner, Checkbox } from "flowbite-svelte";
import type { User } from "../types/user";
import type { Error } from "../types/error";
import { type User } from "../types/user";
import { currentPage, currentUser, startup } from "../storage/localStore";
import toast from "svelte-french-toast";
import { Page } from "../consts/pages";
@@ -43,14 +42,14 @@
position: "bottom-center",
className:
"dark:!bg-gray-800 border-1 dark:!border-gray-700 dark:!text-gray-100",
duration: 3000,
duration: 3000
});
},
{ once: true }
);
window.dispatchEvent(
new CustomEvent("login-attempt", {
detail: { username, password, saveCredentials },
detail: { username, password, saveCredentials }
})
);
});
@@ -59,13 +58,13 @@
{
loading: "Logging in...",
success: "Successfully logged in!",
error: "Invalid Username or Password!",
error: "Invalid Username or Password!"
},
{
position: "bottom-center",
className:
"dark:!bg-gray-800 border-1 dark:!border-gray-700 dark:!text-gray-100",
duration: 3000,
duration: 3000
}
);
};
@@ -87,7 +86,7 @@
position: "bottom-center",
className:
"dark:!bg-gray-800 border-1 dark:!border-gray-700 dark:!text-gray-100",
duration: 3000,
duration: 3000
});
return;
}
@@ -104,7 +103,7 @@
position: "bottom-center",
className:
"dark:!bg-gray-800 border-1 dark:!border-gray-700 dark:!text-gray-100",
duration: 3000,
duration: 3000
});
loading = false;
},
@@ -117,13 +116,13 @@
{
loading: "Logging in...",
success: "Successfully logged in!",
error: "Failed to login.",
error: "Failed to login."
},
{
position: "bottom-center",
className:
"dark:!bg-gray-800 border-1 dark:!border-gray-700 dark:!text-gray-100",
duration: 3000,
duration: 3000
}
);
};
@@ -135,7 +134,7 @@
position: "bottom-center",
className:
"dark:!bg-gray-800 border-1 dark:!border-gray-700 dark:!text-gray-100",
duration: 3000,
duration: 3000
});
};

View File

@@ -1,7 +1,7 @@
const { vitePreprocess } = require("@sveltejs/vite-plugin-svelte");
const preprocess = require("svelte-preprocess");
const config = {
preprocess: [vitePreprocess({})],
preprocess: [preprocess()],
};
module.exports = config;