mirror of
https://github.com/AltarikMC/Launcher
synced 2024-11-21 06:09:51 +01:00
Merge pull request #334 from AltarikMC/electron28
Electron 28, moving to ESM, add eslint
This commit is contained in:
commit
f5a8ec27f0
29
.eslintrc.cjs
Normal file
29
.eslintrc.cjs
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
module.exports = {
|
||||||
|
env: {
|
||||||
|
browser: true,
|
||||||
|
es2021: true
|
||||||
|
},
|
||||||
|
extends: [
|
||||||
|
'standard'
|
||||||
|
],
|
||||||
|
overrides: [
|
||||||
|
{
|
||||||
|
env: {
|
||||||
|
node: true
|
||||||
|
},
|
||||||
|
files: [
|
||||||
|
'.eslintrc.{js,cjs}'
|
||||||
|
],
|
||||||
|
parserOptions: {
|
||||||
|
sourceType: 'script'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
parserOptions: {
|
||||||
|
ecmaVersion: 'latest',
|
||||||
|
sourceType: 'module'
|
||||||
|
},
|
||||||
|
plugins: [],
|
||||||
|
rules: {
|
||||||
|
}
|
||||||
|
}
|
@ -1,49 +1,49 @@
|
|||||||
const path = require('path');
|
const path = require('path');
|
||||||
const pkg = require('./package.json')
|
const pkg = require('./package.json')
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
packagerConfig: {
|
packagerConfig: {
|
||||||
packageName: "altarik-launcher",
|
packageName: "altarik-launcher",
|
||||||
name: "Altarik Launcher",
|
name: "Altarik Launcher",
|
||||||
productName: "altarik-launcher",
|
productName: "altarik-launcher",
|
||||||
icon: path.resolve(__dirname, 'icon.ico'),
|
icon: path.resolve(__dirname, 'icon.ico'),
|
||||||
asar: true,
|
asar: true,
|
||||||
},
|
},
|
||||||
plugins: [
|
plugins: [
|
||||||
{
|
{
|
||||||
name: '@electron-forge/plugin-auto-unpack-natives',
|
name: '@electron-forge/plugin-auto-unpack-natives',
|
||||||
config: {}
|
config: {}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
makers: [
|
makers: [
|
||||||
{
|
{
|
||||||
name: "@electron-forge/maker-squirrel",
|
name: "@electron-forge/maker-squirrel",
|
||||||
platforms: ['darwin', 'win32'],
|
platforms: ['darwin', 'win32'],
|
||||||
config: {
|
config: {
|
||||||
name: pkg.name,
|
name: pkg.name,
|
||||||
iconUrl: path.resolve(__dirname, 'icon.ico'),
|
iconUrl: path.resolve(__dirname, 'icon.ico'),
|
||||||
//loadingGif: path.resolve(__dirname, 'src/assets/loading.gif'),
|
//loadingGif: path.resolve(__dirname, 'src/assets/loading.gif'),
|
||||||
setupIcon: path.resolve(__dirname, 'icon.ico'),
|
setupIcon: path.resolve(__dirname, 'icon.ico'),
|
||||||
setupExe: `${pkg.name}-${pkg.version}-win32-x64.exe`
|
setupExe: `${pkg.name}-${pkg.version}-win32-x64.exe`
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: '@electron-forge/maker-zip',
|
name: '@electron-forge/maker-zip',
|
||||||
platforms: ['linux']
|
platforms: ['linux']
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
publishers: [
|
publishers: [
|
||||||
{
|
{
|
||||||
name: '@electron-forge/publisher-github',
|
name: '@electron-forge/publisher-github',
|
||||||
config: {
|
config: {
|
||||||
repository: {
|
repository: {
|
||||||
owner: 'AltarikMC',
|
owner: 'AltarikMC',
|
||||||
name: 'Launcher'
|
name: 'Launcher'
|
||||||
},
|
},
|
||||||
preRelease: false,
|
preRelease: false,
|
||||||
draft: true,
|
draft: true,
|
||||||
tagPrefix: ''
|
tagPrefix: ''
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
14
package.json
14
package.json
@ -4,6 +4,7 @@
|
|||||||
"version": "2.1.0",
|
"version": "2.1.0",
|
||||||
"description": "Altarik Launcher",
|
"description": "Altarik Launcher",
|
||||||
"main": "src/server/main.js",
|
"main": "src/server/main.js",
|
||||||
|
"type": "module",
|
||||||
"homepage": "https://altarik.fr/",
|
"homepage": "https://altarik.fr/",
|
||||||
"private": true,
|
"private": true,
|
||||||
"repository": "AltarikMC/Launcher",
|
"repository": "AltarikMC/Launcher",
|
||||||
@ -34,7 +35,12 @@
|
|||||||
"@electron-forge/maker-zip": "^7.1.0",
|
"@electron-forge/maker-zip": "^7.1.0",
|
||||||
"@electron-forge/plugin-auto-unpack-natives": "^7.1.0",
|
"@electron-forge/plugin-auto-unpack-natives": "^7.1.0",
|
||||||
"@electron-forge/publisher-github": "^7.1.0",
|
"@electron-forge/publisher-github": "^7.1.0",
|
||||||
"electron": "^27.1.0"
|
"electron": "28.0.0",
|
||||||
|
"eslint": "^8.0.1",
|
||||||
|
"eslint-config-standard": "^17.1.0",
|
||||||
|
"eslint-plugin-import": "^2.25.2",
|
||||||
|
"eslint-plugin-n": "^15.0.0 || ^16.0.0 ",
|
||||||
|
"eslint-plugin-promise": "^6.0.0"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"decompress": "^4.2.1",
|
"decompress": "^4.2.1",
|
||||||
@ -42,14 +48,14 @@
|
|||||||
"electron-log": "^5.0.0",
|
"electron-log": "^5.0.0",
|
||||||
"electron-squirrel-startup": "^1.0.0",
|
"electron-squirrel-startup": "^1.0.0",
|
||||||
"extract-zip": "^2.0.1",
|
"extract-zip": "^2.0.1",
|
||||||
"hasha": "^5.2.2",
|
"hasha": "^6.0.0",
|
||||||
"izitoast": "^1.4.0",
|
"izitoast": "^1.4.0",
|
||||||
"minecraft-launcher-core": "^3.17.3",
|
"minecraft-launcher-core": "^3.17.3",
|
||||||
"msmc": "^4.1.0",
|
"msmc": "^4.1.0",
|
||||||
"node-fetch": "^2.7.0",
|
"node-fetch": "^3.0.0",
|
||||||
"vue": "^3.3.8"
|
"vue": "^3.3.8"
|
||||||
},
|
},
|
||||||
"config": {
|
"config": {
|
||||||
"forge": "./config.forge.js"
|
"forge": "./config.forge.cjs"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,51 +1,47 @@
|
|||||||
function handleSquirrelEvent(app) {
|
export default function handleSquirrelEvent (app) {
|
||||||
if (process.argv.length === 1) {
|
if (process.argv.length === 1) {
|
||||||
return false;
|
return false
|
||||||
}
|
|
||||||
|
|
||||||
const ChildProcess = require('child_process');
|
|
||||||
const path = require('path');
|
|
||||||
|
|
||||||
const appFolder = path.resolve(process.execPath, '..');
|
|
||||||
const rootAtomFolder = path.resolve(appFolder, '..');
|
|
||||||
const updateDotExe = path.resolve(path.join(rootAtomFolder, 'Update.exe'));
|
|
||||||
const exeName = path.basename(process.execPath);
|
|
||||||
|
|
||||||
const spawn = function(command, args) {
|
|
||||||
let spawnedProcess;
|
|
||||||
|
|
||||||
try {
|
|
||||||
spawnedProcess = ChildProcess.spawn(command, args, {detached: true});
|
|
||||||
} catch (error) {}
|
|
||||||
|
|
||||||
return spawnedProcess;
|
|
||||||
};
|
|
||||||
|
|
||||||
const spawnUpdate = function(args) {
|
|
||||||
return spawn(updateDotExe, args);
|
|
||||||
};
|
|
||||||
|
|
||||||
const squirrelEvent = process.argv[1];
|
|
||||||
switch (squirrelEvent) {
|
|
||||||
case '--squirrel-install':
|
|
||||||
case '--squirrel-updated':
|
|
||||||
spawnUpdate(['--createShortcut', exeName]);
|
|
||||||
|
|
||||||
setTimeout(app.quit, 1000);
|
|
||||||
return true;
|
|
||||||
|
|
||||||
case '--squirrel-uninstall':
|
|
||||||
spawnUpdate(['--removeShortcut', exeName]);
|
|
||||||
|
|
||||||
setTimeout(app.quit, 1000);
|
|
||||||
return true;
|
|
||||||
|
|
||||||
case '--squirrel-obsolete':
|
|
||||||
app.quit();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = {
|
const ChildProcess = require('child_process')
|
||||||
handleSquirrelEvent
|
const path = require('path')
|
||||||
}
|
|
||||||
|
const appFolder = path.resolve(process.execPath, '..')
|
||||||
|
const rootAtomFolder = path.resolve(appFolder, '..')
|
||||||
|
const updateDotExe = path.resolve(path.join(rootAtomFolder, 'Update.exe'))
|
||||||
|
const exeName = path.basename(process.execPath)
|
||||||
|
|
||||||
|
const spawn = function (command, args) {
|
||||||
|
let spawnedProcess
|
||||||
|
|
||||||
|
try {
|
||||||
|
spawnedProcess = ChildProcess.spawn(command, args, { detached: true })
|
||||||
|
} catch (error) {}
|
||||||
|
|
||||||
|
return spawnedProcess
|
||||||
|
}
|
||||||
|
|
||||||
|
const spawnUpdate = function (args) {
|
||||||
|
return spawn(updateDotExe, args)
|
||||||
|
}
|
||||||
|
|
||||||
|
const squirrelEvent = process.argv[1]
|
||||||
|
switch (squirrelEvent) {
|
||||||
|
case '--squirrel-install':
|
||||||
|
case '--squirrel-updated':
|
||||||
|
spawnUpdate(['--createShortcut', exeName])
|
||||||
|
|
||||||
|
setTimeout(app.quit, 1000)
|
||||||
|
return true
|
||||||
|
|
||||||
|
case '--squirrel-uninstall':
|
||||||
|
spawnUpdate(['--removeShortcut', exeName])
|
||||||
|
|
||||||
|
setTimeout(app.quit, 1000)
|
||||||
|
return true
|
||||||
|
|
||||||
|
case '--squirrel-obsolete':
|
||||||
|
app.quit()
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -1,98 +1,112 @@
|
|||||||
const { app, BrowserWindow, Menu, ipcMain, autoUpdater, dialog } = require('electron')
|
import { app, BrowserWindow, Menu, ipcMain, autoUpdater, dialog } from 'electron'
|
||||||
const logger = require('electron-log')
|
import isDev from 'electron-is-dev'
|
||||||
const { join } = require('path')
|
import logger from 'electron-log'
|
||||||
const updater = require('./updater.js')
|
import { join, dirname } from 'path'
|
||||||
let updaterInstance = new updater.Updater(app, autoUpdater, dialog, logger, showNotification)
|
import Updater from './updater.js'
|
||||||
|
import electronStartup from 'electron-squirrel-startup'
|
||||||
|
import install from './install.js'
|
||||||
|
import Mc from './minecraft.js'
|
||||||
|
import { minimizeWindow, closeWindow } from './menubar.js'
|
||||||
|
import { fileURLToPath } from 'url'
|
||||||
|
|
||||||
|
const updaterInstance = new Updater(app, autoUpdater, dialog, logger, showNotification)
|
||||||
updaterInstance.configUpdater()
|
updaterInstance.configUpdater()
|
||||||
|
|
||||||
if (require('electron-squirrel-startup')) {
|
const minecraft = new Mc()
|
||||||
require("./install.js").handleSquirrelEvent(app)
|
|
||||||
app.quit()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
const minecraft = require('./minecraft.js')
|
|
||||||
minecraft.showNotification = showNotification
|
minecraft.showNotification = showNotification
|
||||||
|
|
||||||
const iconPath = join(__dirname, "icon.ico")
|
const __filename = fileURLToPath(import.meta.url)
|
||||||
|
const __dirname = dirname(__filename)
|
||||||
|
const iconPath = join(__dirname, 'icon.ico')
|
||||||
|
|
||||||
let win = null
|
let win = null
|
||||||
|
|
||||||
function createWindow () {
|
function createWindow () {
|
||||||
win = new BrowserWindow({
|
win = new BrowserWindow({
|
||||||
width: 1000,
|
width: 1000,
|
||||||
height: 600,
|
height: 600,
|
||||||
resizable: false,
|
resizable: false,
|
||||||
icon: iconPath,
|
icon: iconPath,
|
||||||
webPreferences: {
|
webPreferences: {
|
||||||
nodeIntegration: true,
|
nodeIntegration: true,
|
||||||
contextIsolation: false
|
contextIsolation: false
|
||||||
},
|
},
|
||||||
frame: false
|
frame: false
|
||||||
})
|
})
|
||||||
//Menu.setApplicationMenu(null)
|
if (!isDev) {
|
||||||
win.loadFile('src/client/checkingUpdate.html')
|
Menu.setApplicationMenu(null)
|
||||||
win.on("close", () => {
|
}
|
||||||
app.quit()
|
|
||||||
})
|
win.loadFile('src/client/checkingUpdate.html')
|
||||||
|
win.on('close', () => {
|
||||||
|
app.quit()
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
const { setWindow, minimizeWindow, closeWindow } = require("./menubar.js");
|
function showNotification (title, body = '', clazz = 'info') {
|
||||||
|
win.webContents.send('notification', { title, body, class: clazz })
|
||||||
|
}
|
||||||
|
|
||||||
app.whenReady().then(() => {
|
ipcMain.on('disconnect', () => {
|
||||||
|
minecraft.auth = null
|
||||||
|
win.loadFile('src/client/login.html').then(() => showNotification('Déconnecté', 'Vous avez été déconnecté de votre compte', 'success'))
|
||||||
|
})
|
||||||
|
|
||||||
|
ipcMain.on('pageReady', (event) => {
|
||||||
|
event.sender.send('nick', { name: minecraft.auth.name })
|
||||||
|
minecraft.getModsInformations(event)
|
||||||
|
})
|
||||||
|
|
||||||
|
ipcMain.on('checking-update', () => {
|
||||||
|
updaterInstance.checkForUpdates(win, showNotification)
|
||||||
|
})
|
||||||
|
|
||||||
|
function main () {
|
||||||
|
if (electronStartup) {
|
||||||
|
install.handleSquirrelEvent(app)
|
||||||
|
app.quit()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
app.whenReady().then(() => {
|
||||||
createWindow()
|
createWindow()
|
||||||
setWindow(win)
|
})
|
||||||
})
|
|
||||||
|
|
||||||
app.on('window-all-closed', () => {
|
app.on('window-all-closed', () => {
|
||||||
if (process.platform !== 'darwin') {
|
if (process.platform !== 'darwin') {
|
||||||
app.quit()
|
app.quit()
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
ipcMain.on('minimizeWindow', () => {
|
ipcMain.on('minimizeWindow', () => {
|
||||||
minimizeWindow(win)
|
minimizeWindow(win)
|
||||||
})
|
})
|
||||||
|
|
||||||
ipcMain.on('closeWindow', () => {
|
ipcMain.on('closeWindow', () => {
|
||||||
closeWindow(win)
|
closeWindow(win)
|
||||||
})
|
})
|
||||||
|
|
||||||
app.on('activate', () => {
|
app.on('activate', () => {
|
||||||
if (win === null){
|
if (win === null) {
|
||||||
createWindow()
|
createWindow()
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
ipcMain.on("login", (event, args) => {
|
ipcMain.on('login', (event, args) => {
|
||||||
minecraft.login(event, win, args.user, args.pass)
|
minecraft.login(event, win, args.user, args.pass)
|
||||||
})
|
})
|
||||||
|
|
||||||
ipcMain.on("microsoft-login", (event) => {
|
ipcMain.on('microsoft-login', (event) => {
|
||||||
minecraft.microsoftLogin(event, win)
|
minecraft.microsoftLogin(event, win)
|
||||||
})
|
})
|
||||||
|
|
||||||
ipcMain.on("invalidateData", event => {
|
ipcMain.on('invalidateData', event => {
|
||||||
minecraft.invalidateData(event)
|
minecraft.invalidateData(event)
|
||||||
})
|
})
|
||||||
|
|
||||||
ipcMain.on("launch", (event, args) => {
|
ipcMain.on('launch', (event, args) => {
|
||||||
minecraft.launch(event, args)
|
minecraft.launch(event, args)
|
||||||
})
|
})
|
||||||
|
|
||||||
function showNotification(title, body="", clazz="info") {
|
|
||||||
win.webContents.send('notification', {title: title, body: body, class: clazz})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ipcMain.on("disconnect", () => {
|
main()
|
||||||
minecraft.auth = null
|
|
||||||
win.loadFile('src/client/login.html').then(() => showNotification("Déconnecté", "Vous avez été déconnecté de votre compte", "success"))
|
|
||||||
|
|
||||||
})
|
|
||||||
|
|
||||||
ipcMain.on("pageReady", (event) => {
|
|
||||||
event.sender.send("nick", { name: minecraft.auth.name })
|
|
||||||
minecraft.getModsInformations(event)
|
|
||||||
})
|
|
||||||
|
|
||||||
ipcMain.on("checking-update", () => {
|
|
||||||
updaterInstance.checkForUpdates(win, showNotification)
|
|
||||||
})
|
|
||||||
|
@ -1,21 +1,9 @@
|
|||||||
let win;
|
export function minimizeWindow (browserWindow) {
|
||||||
|
if (browserWindow.minimizable) {
|
||||||
function setWindow(browserWindow) {
|
browserWindow.minimize()
|
||||||
win = browserWindow;
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function minimizeWindow(browserWindow = win) {
|
export function closeWindow (browserWindow) {
|
||||||
if(browserWindow.minimizable) {
|
browserWindow.close()
|
||||||
browserWindow.minimize()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function closeWindow(browserWindow = win) {
|
|
||||||
browserWindow.close()
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports = {
|
|
||||||
setWindow,
|
|
||||||
minimizeWindow,
|
|
||||||
closeWindow
|
|
||||||
}
|
|
@ -1,385 +1,375 @@
|
|||||||
const isDev = require("electron-is-dev")
|
import isDev from 'electron-is-dev'
|
||||||
const { Authenticator, Client } = require("minecraft-launcher-core")
|
import mlc from 'minecraft-launcher-core'
|
||||||
const fetch = require("node-fetch").default
|
import fetch from 'node-fetch'
|
||||||
const hasha = require("hasha")
|
import { hashFile } from 'hasha'
|
||||||
const fs = require("fs")
|
import fs from 'fs'
|
||||||
const { join } = require("path")
|
import { join } from 'path'
|
||||||
const constants = require("constants")
|
import zip from 'extract-zip'
|
||||||
const zip = require("extract-zip")
|
import logger from 'electron-log'
|
||||||
const logger = require("electron-log")
|
import { Auth, lst } from 'msmc'
|
||||||
const { Auth, lst } = require("msmc")
|
import decompress from 'decompress'
|
||||||
const decompress = require("decompress")
|
import decompressTar from 'decompress-targz'
|
||||||
const decompressTar = require("decompress-targz")
|
|
||||||
|
|
||||||
|
const { Authenticator, Client } = mlc
|
||||||
|
|
||||||
class Minecraft {
|
export default class Minecraft {
|
||||||
|
appdata = process.env.APPDATA || (process.platform === 'darwin' ? process.env.HOME + '/Library/Preferences' : process.env.HOME + '/.local/share')
|
||||||
|
localappdata = process.env.LOCALAPPDATA || (process.platform === 'darwin' ? process.env.HOME + '/Library/Application Support/' : process.env.HOME + '/.config')
|
||||||
|
minecraftpath = join(this.appdata, '.altarik')
|
||||||
|
launcher = new Client()
|
||||||
|
auth = null
|
||||||
|
modsList = undefined
|
||||||
|
showNotification = undefined
|
||||||
|
modsInformationsEndpoint = 'https://launcher.altarik.fr'
|
||||||
|
|
||||||
appdata = process.env.APPDATA || (process.platform === "darwin" ? process.env.HOME + "/Library/Preferences" : process.env.HOME + "/.local/share")
|
setShowNotification (showNotification) {
|
||||||
localappdata = process.env.LOCALAPPDATA || (process.platform === "darwin" ? process.env.HOME + "/Library/Application Support/" : process.env.HOME + "/.config")
|
this.showNotification = showNotification
|
||||||
minecraftpath = join(this.appdata, ".altarik")
|
}
|
||||||
launcher = new Client()
|
|
||||||
auth = null
|
|
||||||
modsList = undefined
|
|
||||||
showNotification = undefined
|
|
||||||
modsInformationsEndpoint = "https://launcher.altarik.fr"
|
|
||||||
|
|
||||||
setShowNotification(showNotification) {
|
/**
|
||||||
this.showNotification = showNotification
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @deprecated Mojang removed this method of authentification
|
* @deprecated Mojang removed this method of authentification
|
||||||
* Used to login through Mojang account
|
* Used to login through Mojang account
|
||||||
*/
|
*/
|
||||||
login(event, win, username, password) {
|
login (event, win, username, password) {
|
||||||
this.auth = null
|
this.auth = null
|
||||||
if(isDev || password.trim() !== "") {
|
if (isDev || password.trim() !== '') {
|
||||||
this.auth = Authenticator.getAuth(username, password)
|
this.auth = Authenticator.getAuth(username, password)
|
||||||
this.auth.then(v => {
|
this.auth.then(v => {
|
||||||
win.loadFile("src/client/index.html")
|
win.loadFile('src/client/index.html')
|
||||||
}).catch(() => {
|
}).catch(() => {
|
||||||
event.sender.send("loginError")
|
event.sender.send('loginError')
|
||||||
logger.error("[MJ login] User haven't purchase the game")
|
logger.error("[MJ login] User haven't purchase the game")
|
||||||
this.showNotification("Erreur de connexion", "Vous ne possèdez pas de licence Minecraft sur ce compte", "error")
|
this.showNotification('Erreur de connexion', 'Vous ne possèdez pas de licence Minecraft sur ce compte', 'error')
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
this.showNotification("Erreur de connexion", "Veuillez renseignez un mot de passe", "warning")
|
this.showNotification('Erreur de connexion', 'Veuillez renseignez un mot de passe', 'warning')
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Used to login through a Microsoft account
|
* Used to login through a Microsoft account
|
||||||
*/
|
*/
|
||||||
microsoftLogin(event, win) {
|
microsoftLogin (event, win) {
|
||||||
const authManager = new Auth("select_account")
|
const authManager = new Auth('select_account')
|
||||||
authManager.launch("electron").then(async xboxManager => {
|
authManager.launch('electron').then(async xboxManager => {
|
||||||
xboxManager.getMinecraft().then(async token => {
|
xboxManager.getMinecraft().then(async token => {
|
||||||
if(!token.isDemo()) {
|
if (!token.isDemo()) {
|
||||||
this.auth = token.mclc()
|
this.auth = token.mclc()
|
||||||
logger.info("[MS login] User has been connected successfully to them account")
|
logger.info('[MS login] User has been connected successfully to them account')
|
||||||
win.loadFile("src/client/index.html")
|
win.loadFile('src/client/index.html')
|
||||||
} else {
|
|
||||||
event.sender.send("loginError")
|
|
||||||
logger.error("[MS login] User haven't purchase the game")
|
|
||||||
this.showNotification("Erreur de connexion", "Vous ne possèdez pas de licence Minecraft sur ce compte", "error")
|
|
||||||
}
|
|
||||||
}).catch(err => {
|
|
||||||
event.sender.send("loginError")
|
|
||||||
logger.error("[MS login] " + lst(err))
|
|
||||||
this.showNotification("Erreur de connexion à Mojang", lst(err), "error")
|
|
||||||
})
|
|
||||||
}).catch(err => {
|
|
||||||
event.sender.send("loginError")
|
|
||||||
if(err != "error.gui.closed") {
|
|
||||||
logger.error("[MS login] " + lst(err))
|
|
||||||
this.showNotification("Une erreur de connexion à Xbox est survenue", lst(err), "error")
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
launch(event, args) {
|
|
||||||
this.extractJava(Number(args.chapter), event).then((javaPath) => {
|
|
||||||
this.extractMods(Number(args.chapter), event).then((chapter) => {
|
|
||||||
this.launcher.launch({
|
|
||||||
authorization: this.auth,
|
|
||||||
root: this.minecraftpath,
|
|
||||||
javaPath: javaPath,
|
|
||||||
version: {
|
|
||||||
number: chapter.minecraftVersion,
|
|
||||||
type: chapter.type | "release",
|
|
||||||
custom: chapter.customVersion
|
|
||||||
},
|
|
||||||
memory: {
|
|
||||||
max: args.maxMem,
|
|
||||||
min: args.minMem
|
|
||||||
}
|
|
||||||
}).then(v => {
|
|
||||||
if(v === null) {
|
|
||||||
this.close(event, -1)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
this.launcher.on("debug", (e) => logger.info(`debug: ${e}`));
|
|
||||||
this.launcher.on("data", (e) => logger.info(`data: ${e}`));
|
|
||||||
this.launcher.on("progress", (e) => {
|
|
||||||
event.sender.send("progress", e)
|
|
||||||
logger.info(`progress ${e.type} :${e.task} / ${e.total}`)
|
|
||||||
})
|
|
||||||
this.launcher.on("arguments", (e) => {
|
|
||||||
event.sender.send("launch", e)
|
|
||||||
logger.info("launching the game")
|
|
||||||
logger.info(e)
|
|
||||||
})
|
|
||||||
this.launcher.on("close", (e) => {
|
|
||||||
this.close(event, e)
|
|
||||||
})
|
|
||||||
}).catch((err) => {
|
|
||||||
this.showNotification("Impossible de lancer le jeu", "Erreur inconnue", "error")
|
|
||||||
event.sender.send("close", 1)
|
|
||||||
logger.error("Unable to launch the game")
|
|
||||||
logger.error(err)
|
|
||||||
})
|
|
||||||
}).catch(err => {
|
|
||||||
this.showNotification("Impossible de lancer le jeu", "Impossible d'installer Java pour votre configuration", "error")
|
|
||||||
event.sender.send("close", 1)
|
|
||||||
logger.warn("Unable to install java")
|
|
||||||
logger.warn(err)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
close(event, code) {
|
|
||||||
event.sender.send("close", code)
|
|
||||||
if(code !== 0) {
|
|
||||||
logger.warn("Minecraft didn't close properly")
|
|
||||||
logger.warn(code)
|
|
||||||
this.showNotification("Une erreur est survenue", "Minecraft ne s'est pas fermé correctement", "error")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
getModsInformations(event) {
|
|
||||||
fetch(this.modsInformationsEndpoint).then(response => {
|
|
||||||
if(response.ok) {
|
|
||||||
response.json().then(data => {
|
|
||||||
let folder = join(this.localappdata, "altarik-launcher", "data")
|
|
||||||
if(!fs.existsSync(folder))
|
|
||||||
fs.mkdirSync(folder, {recursive: true})
|
|
||||||
let file = join(folder, "launcher.json")
|
|
||||||
if(fs.existsSync(file))
|
|
||||||
fs.rmSync(file)
|
|
||||||
fs.writeFileSync(file, JSON.stringify(data))
|
|
||||||
event.sender.send("modsInformations", this.extractModsInformations(data))
|
|
||||||
}).catch(err => {
|
|
||||||
event.sender.send("modsInformations", this.extractModsFromFileSystem())
|
|
||||||
logger.warn(err)
|
|
||||||
logger.warn("An error occured while trying to connect to server")
|
|
||||||
})
|
|
||||||
} else {
|
|
||||||
logger.warn("Unable to connect to server")
|
|
||||||
logger.warn(err)
|
|
||||||
event.sender.send("modsInformations", this.extractModsFromFileSystem())
|
|
||||||
}
|
|
||||||
}).catch(err => {
|
|
||||||
logger.warn("Unable to connect to server")
|
|
||||||
logger.warn(err)
|
|
||||||
event.sender.send("modsInformations", this.extractModsFromFileSystem())
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
extractModsFromFileSystem() {
|
|
||||||
let filepath = join(this.localappdata, "altarik-launcher/data/launcher.json")
|
|
||||||
if(fs.existsSync(filepath)) {
|
|
||||||
let content = fs.readFileSync(filepath)
|
|
||||||
if(content !== null) {
|
|
||||||
this.showNotification("Impossible de récupérer certaines informations en ligne", "utilisation des dernières données récupérées", "warning")
|
|
||||||
return this.extractModsInformations(JSON.parse(content))
|
|
||||||
} else {
|
|
||||||
this.showNotification("Impossible de récupérer certaines informations en ligne", "Veuillez réessayez en cliquant sur le bouton", "warning")
|
|
||||||
logger.error("Unable to get chapters informations from server or filesystem")
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
return null;
|
event.sender.send('loginError')
|
||||||
|
logger.error("[MS login] User haven't purchase the game")
|
||||||
|
this.showNotification('Erreur de connexion', 'Vous ne possèdez pas de licence Minecraft sur ce compte', 'error')
|
||||||
}
|
}
|
||||||
}
|
}).catch(err => {
|
||||||
|
event.sender.send('loginError')
|
||||||
|
logger.error('[MS login] ' + lst(err))
|
||||||
|
this.showNotification('Erreur de connexion à Mojang', lst(err), 'error')
|
||||||
|
})
|
||||||
|
}).catch(err => {
|
||||||
|
event.sender.send('loginError')
|
||||||
|
if (err !== 'error.gui.closed') {
|
||||||
|
logger.error('[MS login] ' + lst(err))
|
||||||
|
this.showNotification('Une erreur de connexion à Xbox est survenue', lst(err), 'error')
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
extractModsInformations(json) {
|
launch (event, args) {
|
||||||
this.modsList = json.chapters
|
this.extractJava(Number(args.chapter), event).then((javaPath) => {
|
||||||
return this.modsList
|
this.extractMods(Number(args.chapter), event).then((chapter) => {
|
||||||
}
|
this.launcher.launch({
|
||||||
|
authorization: this.auth,
|
||||||
async extractMods(chapterId, event) {
|
root: this.minecraftpath,
|
||||||
return new Promise(async (resolve, reject) => {
|
javaPath,
|
||||||
const modsFolder = join(this.minecraftpath, "mods")
|
version: {
|
||||||
const shaderFolder = join(this.minecraftpath, "shaderpacks")
|
number: chapter.minecraftVersion,
|
||||||
if(fs.existsSync(modsFolder))
|
type: chapter.type | 'release',
|
||||||
fs.rmSync(modsFolder, { recursive: true })
|
custom: chapter.customVersion
|
||||||
if(fs.existsSync(shaderFolder))
|
},
|
||||||
fs.rmSync(shaderFolder, { recursive: true })
|
memory: {
|
||||||
for(const i in this.modsList) {
|
max: args.maxMem,
|
||||||
if(Number(i) === chapterId) {
|
min: args.minMem
|
||||||
const chapter = this.modsList[i]
|
}
|
||||||
for(let j in chapter.modspack.mods) {
|
}).then(v => {
|
||||||
event.sender.send("progress", {type: "mods", task: 0, total: chapter.modspack.mods.length })
|
if (v === null) {
|
||||||
let modpackFolder = join(this.minecraftpath, "modpack", chapter.title)
|
this.close(event, -1)
|
||||||
if(!fs.existsSync(modpackFolder))
|
}
|
||||||
fs.mkdirSync(modpackFolder, { recursive: true })
|
|
||||||
const path = join(modpackFolder, `modpack${j}.zip`)
|
|
||||||
try {
|
|
||||||
fs.accessSync(path, constants.W_OK)
|
|
||||||
let sha1 = await hasha.fromFile(path, {algorithm: "sha1"})
|
|
||||||
if(sha1 === chapter.modspack.sha1sum[j]) {
|
|
||||||
await this.unzipMods(path).catch(err => {
|
|
||||||
reject(err)
|
|
||||||
})
|
|
||||||
} else {
|
|
||||||
logger.warn(`sha1sum ${sha1} don't correspond to ${chapter.modspack.sha1sum[j]} of mods ${path}`)
|
|
||||||
await this.downloadAndExtractMods(chapter.modspack.mods[j], path).catch(err => {
|
|
||||||
reject(err)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
event.sender.send("progress", {type: "mods", task: Number(j)+1, total: chapter.modspack.mods.length })
|
|
||||||
} catch (err) {
|
|
||||||
try {
|
|
||||||
await this.downloadAndExtractMods(chapter.modspack.mods[j], path)
|
|
||||||
} catch(e) {
|
|
||||||
reject({ err, e })
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
resolve(chapter)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
reject("didn't found the correct chapter" + chapter)
|
|
||||||
})
|
})
|
||||||
}
|
this.launcher.on('debug', (e) => logger.info(`debug: ${e}`))
|
||||||
downloadMods(link, path) {
|
this.launcher.on('data', (e) => logger.info(`data: ${e}`))
|
||||||
return new Promise((resolve, reject) => {
|
this.launcher.on('progress', (e) => {
|
||||||
fetch(link).then(response => {
|
event.sender.send('progress', e)
|
||||||
if(response.ok) {
|
logger.info(`progress ${e.type} :${e.task} / ${e.total}`)
|
||||||
if(fs.existsSync(path))
|
|
||||||
fs.rmSync(path)
|
|
||||||
const dest = fs.createWriteStream(path)
|
|
||||||
response.body.pipe(dest)
|
|
||||||
response.body.on("end", () => {
|
|
||||||
logger.log("download completed");
|
|
||||||
resolve("download completed")
|
|
||||||
})
|
|
||||||
dest.on("error", () => {
|
|
||||||
reject("An error appenned when using stream")
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
reject(response.status)
|
|
||||||
}
|
|
||||||
}).catch(err => {
|
|
||||||
reject(err)
|
|
||||||
})
|
|
||||||
})
|
})
|
||||||
}
|
this.launcher.on('arguments', (e) => {
|
||||||
|
event.sender.send('launch', e)
|
||||||
async unzipMods(zipLocation, outLocation=this.minecraftpath) {
|
logger.info('launching the game')
|
||||||
return new Promise(async (resolve, reject) => {
|
logger.info(e)
|
||||||
logger.info(`unzipping ${zipLocation} file to ${outLocation}`)
|
|
||||||
zip(zipLocation, { dir: outLocation }).then(() => {
|
|
||||||
resolve()
|
|
||||||
}).catch(err => {
|
|
||||||
logger.error(`failed to unzip file`)
|
|
||||||
reject(err)
|
|
||||||
})
|
|
||||||
|
|
||||||
})
|
})
|
||||||
|
this.launcher.on('close', (e) => {
|
||||||
}
|
this.close(event, e)
|
||||||
|
|
||||||
async extractTar(tarLocation, outLocation=this.microsoftpath) {
|
|
||||||
return new Promise(async (resolve, reject) => {
|
|
||||||
logger.info(`Extracting targz ${tarLocation} file to ${outLocation}`)
|
|
||||||
decompress(tarLocation, outLocation, {
|
|
||||||
plugins: [
|
|
||||||
decompressTar()
|
|
||||||
]
|
|
||||||
}).then(() => {
|
|
||||||
resolve()
|
|
||||||
}).catch((e) => {
|
|
||||||
logger.error(`Failed to extract targz file`)
|
|
||||||
reject(e)
|
|
||||||
})
|
|
||||||
})
|
})
|
||||||
}
|
}).catch((err) => {
|
||||||
|
this.showNotification('Impossible de lancer le jeu', 'Erreur inconnue', 'error')
|
||||||
|
event.sender.send('close', 1)
|
||||||
|
logger.error('Unable to launch the game')
|
||||||
|
logger.error(err)
|
||||||
|
})
|
||||||
|
}).catch(err => {
|
||||||
|
this.showNotification('Impossible de lancer le jeu', "Impossible d'installer Java pour votre configuration", 'error')
|
||||||
|
event.sender.send('close', 1)
|
||||||
|
logger.warn('Unable to install java')
|
||||||
|
logger.warn(err)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
async downloadAndExtractMods(link, path) {
|
close (event, code) {
|
||||||
return new Promise(async (resolve, reject) => {
|
event.sender.send('close', code)
|
||||||
this.downloadMods(link, path).then(() => {
|
if (code !== 0) {
|
||||||
this.unzipMods(path).then(() => {
|
logger.warn("Minecraft didn't close properly")
|
||||||
resolve()
|
logger.warn(code)
|
||||||
}).catch(err => {
|
this.showNotification('Une erreur est survenue', "Minecraft ne s'est pas fermé correctement", 'error')
|
||||||
reject(err)
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
getModsInformations (event) {
|
||||||
|
fetch(this.modsInformationsEndpoint).then(response => {
|
||||||
|
if (response.ok) {
|
||||||
|
response.json().then(data => {
|
||||||
|
const folder = join(this.localappdata, 'altarik-launcher', 'data')
|
||||||
|
if (!fs.existsSync(folder)) { fs.mkdirSync(folder, { recursive: true }) }
|
||||||
|
const file = join(folder, 'launcher.json')
|
||||||
|
if (fs.existsSync(file)) { fs.rmSync(file) }
|
||||||
|
fs.writeFileSync(file, JSON.stringify(data))
|
||||||
|
event.sender.send('modsInformations', this.extractModsInformations(data))
|
||||||
|
}).catch(err => {
|
||||||
|
event.sender.send('modsInformations', this.extractModsFromFileSystem())
|
||||||
|
logger.warn(err)
|
||||||
|
logger.warn('An error occured while trying to connect to server')
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
logger.warn('Unable to connect to server')
|
||||||
|
logger.warn(response.status)
|
||||||
|
event.sender.send('modsInformations', this.extractModsFromFileSystem())
|
||||||
|
}
|
||||||
|
}).catch(err => {
|
||||||
|
logger.warn('Unable to connect to server')
|
||||||
|
logger.warn(err)
|
||||||
|
event.sender.send('modsInformations', this.extractModsFromFileSystem())
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
extractModsFromFileSystem () {
|
||||||
|
const filepath = join(this.localappdata, 'altarik-launcher/data/launcher.json')
|
||||||
|
if (fs.existsSync(filepath)) {
|
||||||
|
const content = fs.readFileSync(filepath)
|
||||||
|
if (content !== null) {
|
||||||
|
this.showNotification('Impossible de récupérer certaines informations en ligne', 'utilisation des dernières données récupérées', 'warning')
|
||||||
|
return this.extractModsInformations(JSON.parse(content))
|
||||||
|
} else {
|
||||||
|
this.showNotification('Impossible de récupérer certaines informations en ligne', 'Veuillez réessayez en cliquant sur le bouton', 'warning')
|
||||||
|
logger.error('Unable to get chapters informations from server or filesystem')
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extractModsInformations (json) {
|
||||||
|
this.modsList = json.chapters
|
||||||
|
return this.modsList
|
||||||
|
}
|
||||||
|
|
||||||
|
async extractMods (chapterId, event) {
|
||||||
|
return new Promise(async (resolve, reject) => {
|
||||||
|
const modsFolder = join(this.minecraftpath, 'mods')
|
||||||
|
const shaderFolder = join(this.minecraftpath, 'shaderpacks')
|
||||||
|
if (fs.existsSync(modsFolder)) { fs.rmSync(modsFolder, { recursive: true }) }
|
||||||
|
if (fs.existsSync(shaderFolder)) { fs.rmSync(shaderFolder, { recursive: true }) }
|
||||||
|
for (const i in this.modsList) {
|
||||||
|
if (Number(i) === chapterId) {
|
||||||
|
const chapter = this.modsList[i]
|
||||||
|
for (const j in chapter.modspack.mods) {
|
||||||
|
event.sender.send('progress', { type: 'mods', task: 0, total: chapter.modspack.mods.length })
|
||||||
|
const modpackFolder = join(this.minecraftpath, 'modpack', chapter.title)
|
||||||
|
if (!fs.existsSync(modpackFolder)) { fs.mkdirSync(modpackFolder, { recursive: true }) }
|
||||||
|
const path = join(modpackFolder, `modpack${j}.zip`)
|
||||||
|
try {
|
||||||
|
fs.accessSync(path, fs.W_OK)
|
||||||
|
const sha1 = await hashFile(path, { algorithm: 'sha1' })
|
||||||
|
if (sha1 === chapter.modspack.sha1sum[j]) {
|
||||||
|
await this.unzipMods(path).catch(err => {
|
||||||
|
reject(err)
|
||||||
})
|
})
|
||||||
}).catch(err => {
|
} else {
|
||||||
reject(err)
|
logger.warn(`sha1sum ${sha1} don't correspond to ${chapter.modspack.sha1sum[j]} of mods ${path}`)
|
||||||
})
|
await this.downloadAndExtractMods(chapter.modspack.mods[j], path).catch(err => {
|
||||||
})
|
reject(err)
|
||||||
}
|
|
||||||
|
|
||||||
async extractJava(chapterId, event) {
|
|
||||||
return new Promise(async (resolve, reject) => {
|
|
||||||
const runtime = join(this.minecraftpath, "runtime")
|
|
||||||
if(this.modsList[chapterId].java.platform[process.platform] !== undefined
|
|
||||||
&& this.modsList[chapterId].java.platform[process.platform][process.arch] !== undefined) {
|
|
||||||
event.sender.send("progress", {type: "java", task: 0, total: 1 })
|
|
||||||
const infos = this.modsList[chapterId].java.platform[process.platform][process.arch]
|
|
||||||
const jre = join(runtime, infos.name)
|
|
||||||
const downloadFolder = join(runtime, "download")
|
|
||||||
const downloadFile = join(downloadFolder, `${infos.name}.zip`)
|
|
||||||
if(fs.existsSync(jre))
|
|
||||||
fs.rmSync(jre, { recursive: true })
|
|
||||||
if(!fs.existsSync(downloadFolder))
|
|
||||||
fs.mkdirSync(downloadFolder, { recursive: true })
|
|
||||||
if(fs.existsSync(downloadFile)) {
|
|
||||||
let sha1 = await hasha.fromFile(downloadFile, {algorithm: "sha256"})
|
|
||||||
if(sha1 === infos.sha256sum) {
|
|
||||||
await this.extractJavaArchive(downloadFile, runtime)
|
|
||||||
let filename = process.platform == "win32" ? "java.exe" : "java"
|
|
||||||
resolve(join(jre, "bin", filename))
|
|
||||||
} else {
|
|
||||||
logger.warn(`java sha256sum ${sha1} don't correspond to ${infos.sha256sum}`)
|
|
||||||
await this.downloadAndExtractJava(infos, downloadFolder, runtime).then(() => resolve(join(jre, "bin", process.platform === "win32" ? "java.exe" : "java"))).catch(err => reject(err))
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
await this.downloadAndExtractJava(infos, downloadFolder, runtime).then(() => resolve(join(jre, "bin", process.platform === "win32" ? "java.exe" : "java"))).catch(err => reject(err))
|
|
||||||
}
|
|
||||||
event.sender.send("progress", {type: "java", task: 1, total: 1 })
|
|
||||||
} else {
|
|
||||||
reject("There is not available version for this system")
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
async downloadAndExtractJava(infos, downloadFolder, runtimeFolder) {
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
logger.info(`Downloading ${infos.name}`)
|
|
||||||
this.downloadMods(infos.link, join(downloadFolder, `${infos.name}.zip`)).then(() => {
|
|
||||||
logger.info(`download completed`)
|
|
||||||
this.extractJavaArchive(join(downloadFolder, `${infos.name}.zip`), runtimeFolder).then(() => {
|
|
||||||
logger.info(`File unzipped`)
|
|
||||||
resolve()
|
|
||||||
}).catch(err => {
|
|
||||||
let join_s = join(downloadFolder, `${infos.name}.zip`)
|
|
||||||
logger.info(`Failed to unzip ${join_s}`)
|
|
||||||
reject(err)
|
|
||||||
})
|
})
|
||||||
}).catch(err => {
|
}
|
||||||
logger.err(`Failed to download ${infos.link} to ${infos.name}.zip`)
|
event.sender.send('progress', { type: 'mods', task: Number(j) + 1, total: chapter.modspack.mods.length })
|
||||||
reject(err)
|
} catch (err) {
|
||||||
})
|
try {
|
||||||
})
|
await this.downloadAndExtractMods(chapter.modspack.mods[j], path)
|
||||||
}
|
} catch (e) {
|
||||||
|
reject(new Error({ err, e }))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
resolve(chapter)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
reject(new Error("didn't found the correct chapter" + chapterId))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
async extractJavaArchive(zipLocation, outLocation) {
|
downloadMods (link, path) {
|
||||||
if(process.platform === "win32") {
|
return new Promise((resolve, reject) => {
|
||||||
await this.unzipMods(zipLocation, outLocation)
|
fetch(link).then(response => {
|
||||||
|
if (response.ok) {
|
||||||
|
if (fs.existsSync(path)) { fs.rmSync(path) }
|
||||||
|
const dest = fs.createWriteStream(path)
|
||||||
|
response.body.pipe(dest)
|
||||||
|
response.body.on('end', () => {
|
||||||
|
logger.log('download completed')
|
||||||
|
resolve('download completed')
|
||||||
|
})
|
||||||
|
dest.on('error', () => {
|
||||||
|
reject(new Error('An error appenned when using stream'))
|
||||||
|
})
|
||||||
} else {
|
} else {
|
||||||
await this.extractTar(zipLocation, outLocation)
|
reject(response.status)
|
||||||
}
|
}
|
||||||
}
|
}).catch(err => {
|
||||||
|
reject(err)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
invalidateData(event) {
|
async unzipMods (zipLocation, outLocation = this.minecraftpath) {
|
||||||
logger.info("invalidate game data...")
|
return new Promise((resolve, reject) => {
|
||||||
const assets = join(this.minecraftpath, "assets")
|
logger.info(`unzipping ${zipLocation} file to ${outLocation}`)
|
||||||
const librairies = join(this.minecraftpath,"libraries")
|
zip(zipLocation, { dir: outLocation }).then(() => {
|
||||||
const natives = join(this.minecraftpath, "natives")
|
resolve()
|
||||||
const versions = join(this.minecraftpath, "versions")
|
}).catch(err => {
|
||||||
if(fs.existsSync(assets))
|
logger.error('failed to unzip file')
|
||||||
fs.rmSync(assets, { recursive: true })
|
reject(err)
|
||||||
if(fs.existsSync(librairies))
|
})
|
||||||
fs.rmSync(librairies, { recursive: true })
|
})
|
||||||
if(fs.existsSync(natives))
|
}
|
||||||
fs.rmSync(natives, { recursive: true })
|
|
||||||
if(fs.existsSync(versions))
|
async extractTar (tarLocation, outLocation = this.microsoftpath) {
|
||||||
fs.rmSync(versions, { recursive: true })
|
return new Promise((resolve, reject) => {
|
||||||
logger.info("Game data invalidated")
|
logger.info(`Extracting targz ${tarLocation} file to ${outLocation}`)
|
||||||
event.sender.send("invalidated")
|
decompress(tarLocation, outLocation, {
|
||||||
|
plugins: [
|
||||||
|
decompressTar()
|
||||||
|
]
|
||||||
|
}).then(() => {
|
||||||
|
resolve()
|
||||||
|
}).catch((e) => {
|
||||||
|
logger.error('Failed to extract targz file')
|
||||||
|
reject(e)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
async downloadAndExtractMods (link, path) {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
this.downloadMods(link, path).then(() => {
|
||||||
|
this.unzipMods(path).then(() => {
|
||||||
|
resolve()
|
||||||
|
}).catch(err => {
|
||||||
|
reject(err)
|
||||||
|
})
|
||||||
|
}).catch(err => {
|
||||||
|
reject(err)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
async extractJava (chapterId, event) {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
const runtime = join(this.minecraftpath, 'runtime')
|
||||||
|
if (this.modsList[chapterId].java.platform[process.platform] !== undefined &&
|
||||||
|
this.modsList[chapterId].java.platform[process.platform][process.arch] !== undefined) {
|
||||||
|
event.sender.send('progress', { type: 'java', task: 0, total: 1 })
|
||||||
|
const infos = this.modsList[chapterId].java.platform[process.platform][process.arch]
|
||||||
|
const jre = join(runtime, infos.name)
|
||||||
|
const downloadFolder = join(runtime, 'download')
|
||||||
|
const downloadFile = join(downloadFolder, `${infos.name}.zip`)
|
||||||
|
if (fs.existsSync(jre)) { fs.rmSync(jre, { recursive: true }) }
|
||||||
|
if (!fs.existsSync(downloadFolder)) { fs.mkdirSync(downloadFolder, { recursive: true }) }
|
||||||
|
if (fs.existsSync(downloadFile)) {
|
||||||
|
hashFile(downloadFile, { algorithm: 'sha256' }).then(sha1 => {
|
||||||
|
if (sha1 === infos.sha256sum) {
|
||||||
|
this.extractJavaArchive(downloadFile, runtime).then(() => {
|
||||||
|
const filename = process.platform === 'win32' ? 'java.exe' : 'java'
|
||||||
|
resolve(join(jre, 'bin', filename))
|
||||||
|
}).catch(err => {
|
||||||
|
reject(err)
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
logger.warn(`java sha256sum ${sha1} don't correspond to ${infos.sha256sum}`)
|
||||||
|
this.downloadAndExtractJava(infos, downloadFolder, runtime).then(() => resolve(join(jre, 'bin', process.platform === 'win32' ? 'java.exe' : 'java'))).catch(err => reject(err))
|
||||||
|
}
|
||||||
|
}).catch(err => {
|
||||||
|
reject(err)
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
this.downloadAndExtractJava(infos, downloadFolder, runtime).then(() => resolve(join(jre, 'bin', process.platform === 'win32' ? 'java.exe' : 'java'))).catch(err => reject(err))
|
||||||
|
}
|
||||||
|
event.sender.send('progress', { type: 'java', task: 1, total: 1 })
|
||||||
|
} else {
|
||||||
|
reject(new Error('There is not available version for this system'))
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
async downloadAndExtractJava (infos, downloadFolder, runtimeFolder) {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
logger.info(`Downloading ${infos.name}`)
|
||||||
|
this.downloadMods(infos.link, join(downloadFolder, `${infos.name}.zip`)).then(() => {
|
||||||
|
logger.info('download completed')
|
||||||
|
this.extractJavaArchive(join(downloadFolder, `${infos.name}.zip`), runtimeFolder).then(() => {
|
||||||
|
logger.info('File unzipped')
|
||||||
|
resolve()
|
||||||
|
}).catch(err => {
|
||||||
|
const joinS = join(downloadFolder, `${infos.name}.zip`)
|
||||||
|
logger.info(`Failed to unzip ${joinS}`)
|
||||||
|
reject(err)
|
||||||
|
})
|
||||||
|
}).catch(err => {
|
||||||
|
logger.err(`Failed to download ${infos.link} to ${infos.name}.zip`)
|
||||||
|
reject(err)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
async extractJavaArchive (zipLocation, outLocation) {
|
||||||
|
if (process.platform === 'win32') {
|
||||||
|
await this.unzipMods(zipLocation, outLocation)
|
||||||
|
} else {
|
||||||
|
await this.extractTar(zipLocation, outLocation)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
invalidateData (event) {
|
||||||
|
logger.info('invalidate game data...')
|
||||||
|
const assets = join(this.minecraftpath, 'assets')
|
||||||
|
const librairies = join(this.minecraftpath, 'libraries')
|
||||||
|
const natives = join(this.minecraftpath, 'natives')
|
||||||
|
const versions = join(this.minecraftpath, 'versions')
|
||||||
|
if (fs.existsSync(assets)) { fs.rmSync(assets, { recursive: true }) }
|
||||||
|
if (fs.existsSync(librairies)) { fs.rmSync(librairies, { recursive: true }) }
|
||||||
|
if (fs.existsSync(natives)) { fs.rmSync(natives, { recursive: true }) }
|
||||||
|
if (fs.existsSync(versions)) { fs.rmSync(versions, { recursive: true }) }
|
||||||
|
logger.info('Game data invalidated')
|
||||||
|
event.sender.send('invalidated')
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = new Minecraft
|
|
@ -1,101 +1,94 @@
|
|||||||
const isDev = require('electron-is-dev')
|
import isDev from 'electron-is-dev'
|
||||||
const fetch = require('node-fetch').default
|
import fetch from 'node-fetch'
|
||||||
const pkg = require('../../package.json')
|
import pkg from '../../package.json' assert {type: 'json'}
|
||||||
|
|
||||||
const server = 'https://update.electronjs.org'
|
const server = 'https://update.electronjs.org'
|
||||||
|
|
||||||
class Updater {
|
export default class Updater {
|
||||||
|
constructor (app, autoUpdater, dialog, logger, ipcMain) {
|
||||||
|
this.app = app
|
||||||
|
this.autoUpdater = autoUpdater
|
||||||
|
this.dialog = dialog
|
||||||
|
this.logger = logger
|
||||||
|
this.ipcMain = ipcMain
|
||||||
|
}
|
||||||
|
|
||||||
constructor(app, autoUpdater, dialog, logger, ipcMain) {
|
configUpdater () {
|
||||||
this.app = app
|
this.logger.info(`electron version: ${process.versions.electron}`)
|
||||||
this.autoUpdater = autoUpdater
|
this.logger.info(`chrome version: ${process.versions.chrome}`)
|
||||||
this.dialog = dialog
|
this.logger.info(`Node version: ${process.versions.node}`)
|
||||||
this.logger = logger
|
this.logger.info(`platform: ${process.platform}`)
|
||||||
this.ipcMain = ipcMain
|
this.logger.info(`arch: ${process.arch}`)
|
||||||
|
if (isDev) {
|
||||||
|
this.logger.info(`developpement version ${this.app.getVersion()}`)
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
this.logger.info(`production version ${this.app.getVersion()}`)
|
||||||
|
// TODO : replace dialog by automatic restart
|
||||||
|
this.autoUpdater.on('update-downloaded', (_event, releaseNotes, releaseName) => {
|
||||||
|
this.logger.info(`update downloaded ${releaseName}`)
|
||||||
|
this.logger.info('Leaving application to install update...')
|
||||||
|
this.autoUpdater.quitAndInstall()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
configUpdater() {
|
checkForUpdates (win, showNotification) {
|
||||||
this.logger.info(`electron version: ${process.versions['electron']}`)
|
if (isDev) {
|
||||||
this.logger.info(`chrome version: ${process.versions['chrome']}`)
|
win.loadFile('src/client/login.html')
|
||||||
this.logger.info(`Node version: ${process.versions['node']}`)
|
return
|
||||||
this.logger.info(`platform: ${process.platform}`)
|
|
||||||
this.logger.info(`arch: ${process.arch}`)
|
|
||||||
if(isDev) {
|
|
||||||
this.logger.info(`developpement version ${this.app.getVersion()}`)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
this.logger.info(`production version ${this.app.getVersion()}`)
|
|
||||||
// TODO : replace dialog by automatic restart
|
|
||||||
this.autoUpdater.on('update-downloaded', (_event, releaseNotes, releaseName) => {
|
|
||||||
this.logger.info(`update downloaded ${releaseName}`)
|
|
||||||
this.logger.info("Leaving application to install update...")
|
|
||||||
this.autoUpdater.quitAndInstall()
|
|
||||||
})
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
this.logger.info('Checking for update...')
|
||||||
|
const feed = `${server}/${pkg.repository}/${process.platform}-${process.arch}/${this.app.getVersion()}`
|
||||||
|
if (process.platform !== 'linux') {
|
||||||
|
this.autoUpdater.setFeedURL(feed)
|
||||||
|
this.autoUpdater.on('error', message => {
|
||||||
|
this.displayError(win, showNotification, message)
|
||||||
|
})
|
||||||
|
|
||||||
checkForUpdates(win, showNotification) {
|
this.autoUpdater.on('update-available', () => {
|
||||||
if(isDev) {
|
this.logger.info('update available, downloading...')
|
||||||
win.loadFile('src/client/login.html')
|
win.webContents.send('update-available')
|
||||||
return;
|
})
|
||||||
}
|
this.autoUpdater.on('update-not-available', () => {
|
||||||
this.logger.info("Checking for update...")
|
this.logger.info('update not available')
|
||||||
const feed = `${server}/${pkg.repository}/${process.platform}-${process.arch}/${this.app.getVersion()}`
|
win.loadFile('src/client/login.html')
|
||||||
if(process.platform != 'linux') {
|
})
|
||||||
this.autoUpdater.setFeedURL(feed)
|
this.autoUpdater.checkForUpdates()
|
||||||
this.autoUpdater.on('error', message => {
|
} else {
|
||||||
this.displayError(win, showNotification, message)
|
this.searchUpdateLinux(win, showNotification)
|
||||||
})
|
|
||||||
|
|
||||||
this.autoUpdater.on('update-available', () => {
|
|
||||||
this.logger.info("update available, downloading...")
|
|
||||||
win.webContents.send("update-available")
|
|
||||||
})
|
|
||||||
this.autoUpdater.on("update-not-available", () => {
|
|
||||||
this.logger.info("update not available")
|
|
||||||
win.loadFile('src/client/login.html')
|
|
||||||
})
|
|
||||||
this.autoUpdater.checkForUpdates()
|
|
||||||
} else {
|
|
||||||
this.searchUpdateLinux(win, showNotification)
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
searchUpdateLinux(win, showNotification) {
|
searchUpdateLinux (win, showNotification) {
|
||||||
const url = 'https://api.github.com/repos/AltarikMc/Launcher/releases/latest'
|
const url = 'https://api.github.com/repos/AltarikMc/Launcher/releases/latest'
|
||||||
fetch(url).then(response => {
|
fetch(url).then(response => {
|
||||||
if(response.status === 200) {
|
if (response.status === 200) {
|
||||||
response.json().then(json => {
|
response.json().then(json => {
|
||||||
if(json.tag_name !== pkg.version) {
|
if (json.tag_name !== pkg.version) {
|
||||||
let asset = json.assets.filter(el => el.browser_download_url.includes(".zip"))
|
const asset = json.assets.filter(el => el.browser_download_url.includes('.zip'))
|
||||||
if(asset.length === 1) {
|
if (asset.length === 1) {
|
||||||
let downloadUrl = asset[0].browser_download_url
|
const downloadUrl = asset[0].browser_download_url
|
||||||
win.webContents.send("please-download-update", { url: downloadUrl} )
|
win.webContents.send('please-download-update', { url: downloadUrl })
|
||||||
this.logger.info("update available, please download")
|
this.logger.info('update available, please download')
|
||||||
} else {
|
|
||||||
this.displayError(win, showNotification, "Can't find right asset in last update")
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
this.logger.info("update not available")
|
|
||||||
win.loadFile('src/client/login.html')
|
|
||||||
}
|
|
||||||
}).catch(err => this.displayError(win, showNotification, err))
|
|
||||||
} else {
|
} else {
|
||||||
this.displayError(win, showNotification, "Server unavailable")
|
this.displayError(win, showNotification, "Can't find right asset in last update")
|
||||||
}
|
}
|
||||||
}).catch(err => this.displayError(win, showNotification, err))
|
} else {
|
||||||
}
|
this.logger.info('update not available')
|
||||||
|
win.loadFile('src/client/login.html')
|
||||||
displayError(win, showNotification, errorMessage) {
|
}
|
||||||
this.logger.error('There was a problem updating the application')
|
}).catch(err => this.displayError(win, showNotification, err))
|
||||||
this.logger.error(errorMessage)
|
} else {
|
||||||
win.loadFile('src/client/login.html').then(() => {
|
this.displayError(win, showNotification, 'Server unavailable')
|
||||||
showNotification("Une erreur est survenue lors de la vérification de la mise à jour", "Veuillez vérifier votre connexion internet et réessayer", "error")
|
}
|
||||||
})
|
}).catch(err => this.displayError(win, showNotification, err))
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
displayError (win, showNotification, errorMessage) {
|
||||||
|
this.logger.error('There was a problem updating the application')
|
||||||
module.exports = {
|
this.logger.error(errorMessage)
|
||||||
Updater
|
win.loadFile('src/client/login.html').then(() => {
|
||||||
|
showNotification('Une erreur est survenue lors de la vérification de la mise à jour', 'Veuillez vérifier votre connexion internet et réessayer', 'error')
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user