7 Commits

Author SHA1 Message Date
2b12654825 set author 2022-10-16 23:19:24 +02:00
293ea1b798 disable set account button 2022-10-16 23:18:21 +02:00
5f36de6697 add appInfo 2022-10-16 23:16:05 +02:00
a0628cc873 remove/disable console logs 2022-10-16 23:10:55 +02:00
5c87704b10 launch mechanics working 2022-10-16 23:10:07 +02:00
72958950b7 adjust window height 2022-10-16 22:51:16 +02:00
8d29bd6822 whole update logic working 2022-10-16 22:44:56 +02:00
10 changed files with 160 additions and 30 deletions

1
.gitignore vendored
View File

@@ -1,2 +1,3 @@
node_modules/ node_modules/
release/
yarn.lock yarn.lock

80
app.js
View File

@@ -21,12 +21,31 @@ const run = () => {
mainWindow = createWindow(); mainWindow = createWindow();
mainWindow.on('show', async () => { mainWindow.on('show', async () => {
await doUpdateCheck(mainWindow);
})
app.on('activate', function () {
if (BrowserWindow.getAllWindows().length === 0) mainWindow = createWindow();
})
app.on('window-all-closed', () => {
app.quit()
})
ipcMain.handle('launch', async () => {
const result = await osuUtil.startOsuWithDevServer(tempOsuPath, "ez-pp.farm", async () => {
await doUpdateCheck(mainWindow);
});
return result;
})
ipcMain.on('do-update-check', async () => {
await doUpdateCheck(mainWindow);
})
ipcMain.on('do-update', async () => {
const osuPath = await config.get("osuPath", ""); const osuPath = await config.get("osuPath", "");
const isValid = await osuUtil.isValidOsuFolder(osuPath); const isValid = await osuUtil.isValidOsuFolder(osuPath);
if (osuPath.trim == "" || !isValid) { if (osuPath.trim == "" || !isValid) {
mainWindow.webContents.send('status_update', { mainWindow.webContents.send('status_update', {
type: "missing-folder" type: "error",
}) message: "Invalid osu! folder"
});
return; return;
} }
if (fs.existsSync(osuPath)) { if (fs.existsSync(osuPath)) {
@@ -41,23 +60,18 @@ const run = () => {
const releaseFiles = await osuUtil.getUpdateFiles(releaseStream); const releaseFiles = await osuUtil.getUpdateFiles(releaseStream);
const filesToDownload = await osuUtil.filesThatNeedUpdate(tempOsuPath, releaseFiles); const filesToDownload = await osuUtil.filesThatNeedUpdate(tempOsuPath, releaseFiles);
// const downloadTask = await osuUtil.downloadUpdateFiles(osuPath, filesToDownload); const downloadTask = await osuUtil.downloadUpdateFiles(osuPath, filesToDownload);
// downloadTask.on('completed', () => { downloadTask.on('completed', () => {
// console.log("done!"); mainWindow.webContents.send('status_update', {
// }); type: "update-complete"
mainWindow.webContents.send('status_update', { })
type: filesToDownload.length > 0 ? "update-available" : "up-to-date" });
})
} else } else
mainWindow.webContents.send('status_update', { mainWindow.webContents.send('status_update', {
type: "missing-folder" type: "error",
}) message: "Invalid osu! folder"
}) });
app.on('activate', function () {
if (BrowserWindow.getAllWindows().length === 0) mainWindow = createWindow();
})
app.on('window-all-closed', () => {
app.quit()
}) })
ipcMain.handle('set-osu-dir', async (event) => { ipcMain.handle('set-osu-dir', async (event) => {
const yes = await dialog.showOpenDialog({ const yes = await dialog.showOpenDialog({
@@ -75,9 +89,39 @@ const run = () => {
}) })
} }
async function doUpdateCheck(window) {
const osuPath = await config.get("osuPath", "");
const isValid = await osuUtil.isValidOsuFolder(osuPath);
if (osuPath.trim == "" || !isValid) {
window.webContents.send('status_update', {
type: "missing-folder"
})
return;
}
if (fs.existsSync(osuPath)) {
tempOsuPath = osuPath;
const osuConfig = await osuUtil.getLatestConfig(tempOsuPath);
const lastVersion = await osuConfig.get("LastVersion");
let releaseStream = "stable40";
if (lastVersion.endsWith("cuttingedge"))
releaseStream = "cuttingedge"
else if (lastVersion.endsWith("beta"))
releaseStream = "beta";
const releaseFiles = await osuUtil.getUpdateFiles(releaseStream);
const filesToDownload = await osuUtil.filesThatNeedUpdate(tempOsuPath, releaseFiles);
window.webContents.send('status_update', {
type: filesToDownload.length > 0 ? "update-available" : "up-to-date"
})
} else
window.webContents.send('status_update', {
type: "missing-folder"
})
}
function createWindow() { function createWindow() {
// Create the browser window. // Create the browser window.
const win = windowManager.createWindow(520, 420); const win = windowManager.createWindow(520, 350);
win.loadFile('./html/index.html'); win.loadFile('./html/index.html');

4
appInfo.js Normal file
View File

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

View File

@@ -26,7 +26,6 @@ async function get(key, defaultValue) {
} }
async function set(key, value) { async function set(key, value) {
console.log("setting " + key + " to " + value);
const configValues = new Map(); const configValues = new Map();
const fileStream = await fs.promises.readFile(configLocation, "utf-8"); const fileStream = await fs.promises.readFile(configLocation, "utf-8");
const lines = fileStream.split(/\r?\n/) const lines = fileStream.split(/\r?\n/)

18
executeUtil.js Normal file
View File

@@ -0,0 +1,18 @@
const childProcess = require('child_process');
module.exports = {
runFile: (folder, file, args, onExit) => {
childProcess.execFile(file, args, {
cwd: folder
}, (_err, _stdout, _stderr) => {
onExit();
});
},
runFileDetached: (folder, file, args) => {
const subprocess = childProcess.spawn(file + " " + args, {
cwd: folder,
detached: true,
stdio: 'ignore'
})
subprocess.unref()
}
}

View File

@@ -40,7 +40,7 @@
type="button" style="background-color:#d6016f" disabled>Looking for type="button" style="background-color:#d6016f" disabled>Looking for
updates...</button> updates...</button>
</div> </div>
<button class="btn btn-dark btn-sm float-start" id="account-btn"> <button class="btn btn-dark btn-sm float-start" id="account-btn" disabled>
set account set account
</button> </button>
<button class="btn btn-dark btn-sm float-end" id="folder-btn"> <button class="btn btn-dark btn-sm float-end" id="folder-btn">

View File

@@ -3,6 +3,7 @@ const fu = require('./fileUtil');
const path = require('path'); const path = require('path');
const crypto = require('crypto'); const crypto = require('crypto');
const axios = require('axios').default; const axios = require('axios').default;
const executeUtil = require('./executeUtil');
const { EventEmitter } = require('events'); const { EventEmitter } = require('events');
const { DownloaderHelper } = require('node-downloader-helper'); const { DownloaderHelper } = require('node-downloader-helper');
@@ -102,14 +103,14 @@ async function filesThatNeedUpdate(osuPath, updateFiles) {
fileName, fileName,
fileURL fileURL
}) })
console.log("hashes are not matching", `(${existingFileMD5} - ${fileHash})`); // console.log("hashes are not matching", `(${existingFileMD5} - ${fileHash})`);
} }
} else { } else {
filesToDownload.push({ filesToDownload.push({
fileName, fileName,
fileURL fileURL
}); });
console.log("new file " + fileName); // console.log("new file " + fileName);
} }
} }
return filesToDownload; return filesToDownload;
@@ -120,7 +121,9 @@ async function downloadUpdateFiles(osuPath, filesToUpdate) {
let completedIndex = 0; let completedIndex = 0;
filesToUpdate.forEach(async (fileToUpdate) => { filesToUpdate.forEach(async (fileToUpdate) => {
const filePath = path.join(osuPath, fileToUpdate.fileName); const filePath = path.join(osuPath, fileToUpdate.fileName);
await fs.promises.rm(filePath); if (await fu.existsAsync(filePath))
await fs.promises.rm(filePath);
const fileDownload = new DownloaderHelper(fileToUpdate.fileURL, osuPath, { const fileDownload = new DownloaderHelper(fileToUpdate.fileURL, osuPath, {
fileName: fileToUpdate.fileName, fileName: fileToUpdate.fileName,
override: true, override: true,
@@ -137,4 +140,11 @@ async function downloadUpdateFiles(osuPath, filesToUpdate) {
return eventEmitter; return eventEmitter;
} }
module.exports = { isValidOsuFolder, getLatestConfig, getUpdateFiles, filesThatNeedUpdate, downloadUpdateFiles } async function startWithDevServer(osuPath, serverDomain, onExit) {
const osuExe = path.join(osuPath, "osu!.exe");
if (!await fu.existsAsync(osuExe)) return false;
executeUtil.runFile(osuPath, osuExe, ["-devserver", serverDomain], onExit);
return true;
}
module.exports = { isValidOsuFolder, getLatestConfig, getUpdateFiles, filesThatNeedUpdate, downloadUpdateFiles, startOsuWithDevServer: startWithDevServer }

View File

@@ -3,6 +3,7 @@
"version": "1.0.0", "version": "1.0.0",
"main": "app.js", "main": "app.js",
"license": "MIT", "license": "MIT",
"author": "HorizonCode",
"build": { "build": {
"appId": "farm.ezpp.ezppfarm.launcher", "appId": "farm.ezpp.ezppfarm.launcher",
"productName": "ezpplauncher", "productName": "ezpplauncher",

View File

@@ -1,5 +1,6 @@
const { ipcRenderer } = require('electron'); const { ipcRenderer } = require('electron');
const { Titlebar, Color } = require('custom-electron-titlebar'); const { Titlebar, Color } = require('custom-electron-titlebar');
const appInfo = require('../appInfo');
let titlebar; let titlebar;
window.addEventListener('DOMContentLoaded', () => { window.addEventListener('DOMContentLoaded', () => {
@@ -10,11 +11,41 @@ window.addEventListener('DOMContentLoaded', () => {
maximizable: false maximizable: false
}); });
titlebar.updateTitle("EZPPLauncher"); titlebar.updateTitle(`${appInfo.appName} ${appInfo.appVersion}`);
const $ = require('jquery'); const $ = require('jquery');
const Swal = require('sweetalert2'); const Swal = require('sweetalert2');
let currentState;
$("#launch-btn").on('click', async () => {
switch (currentState) {
case "up-to-date":
$("#launch-btn").attr('disabled', true);
$('#launch-btn').html('Launching...');
const result = await ipcRenderer.invoke("launch");
if (!result) {
Swal.fire({
title: 'Uh oh!',
text: "Something went wrong while launching!",
icon: 'error',
confirmButtonText: 'Okay'
});
$("#launch-btn").attr('disabled', false);
$('#launch-btn').html('Launch');
} else {
$("#launch-btn").attr('disabled', true);
$('#launch-btn').html('Running...');
}
break;
case "update-available":
$("#launch-btn").attr('disabled', true);
$('#launch-btn').html('Updating...');
ipcRenderer.send("do-update");
break;
}
});
$("#folder-btn").on('click', async () => { $("#folder-btn").on('click', async () => {
const success = await ipcRenderer.invoke('set-osu-dir'); const success = await ipcRenderer.invoke('set-osu-dir');
if (success == undefined) if (success == undefined)
@@ -26,6 +57,7 @@ window.addEventListener('DOMContentLoaded', () => {
icon: 'success', icon: 'success',
confirmButtonText: 'Cool' confirmButtonText: 'Cool'
}) })
ipcRenderer.send("do-update-check");
} else { } else {
Swal.fire({ Swal.fire({
title: 'Uh oh!', title: 'Uh oh!',
@@ -37,6 +69,7 @@ window.addEventListener('DOMContentLoaded', () => {
}); });
ipcRenderer.on('status_update', (event, status) => { ipcRenderer.on('status_update', (event, status) => {
currentState = status.type;
switch (status.type) { switch (status.type) {
case "up-to-date": case "up-to-date":
$("#launch-btn").attr('disabled', false); $("#launch-btn").attr('disabled', false);
@@ -47,7 +80,26 @@ window.addEventListener('DOMContentLoaded', () => {
$('#launch-btn').html('Update'); $('#launch-btn').html('Update');
break; break;
case "missing-folder": case "missing-folder":
$('#launch-btn').html('Please set your osu folder!'); $('#launch-btn').html('Please set your osu! folder');
break;
case "error":
Swal.fire({
title: 'Uh oh!',
text: status.message,
icon: 'error',
confirmButtonText: 'Okay'
});
ipcRenderer.send("do-update-check");
break;
case "update-complete":
Swal.fire({
title: 'Yaaay!',
text: "Your osu! client has been successfully updated!",
icon: 'success',
confirmButtonText: 'Thanks :3'
});
ipcRenderer.send("do-update-check");
break;
} }
}) })

View File

@@ -1,4 +1,5 @@
const path = require("path"); const path = require("path");
const appInfo = require('../appInfo');
const { BrowserWindow } = require('electron'); const { BrowserWindow } = require('electron');
const { attachTitlebarToWindow } = require('custom-electron-titlebar/main'); const { attachTitlebarToWindow } = require('custom-electron-titlebar/main');
@@ -31,11 +32,11 @@ module.exports = {
window.show(); window.show();
}); });
window.webContents.setUserAgent("EZPPLauncher"); window.webContents.setUserAgent(`${appInfo.appName} ${appInfo.appVersion}`);
attachTitlebarToWindow(window); attachTitlebarToWindow(window);
window.webContents.openDevTools({ // window.webContents.openDevTools({
mode: "detach" // mode: "detach"
}); // });
return window; return window;
}, },