4
0
mirror of https://github.com/AltarikMC/Launcher synced 2024-11-22 06:19:50 +01:00

Merge pull request #67 from AltarikMC/render-process-switch-to-vue

added vue as front-end framework
This commit is contained in:
Quentin Legot 2021-09-19 17:35:40 +02:00 committed by GitHub
commit 59a12285c0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 259 additions and 235 deletions

1
.gitignore vendored
View File

@ -3,3 +3,4 @@ game
out/ out/
.vscode/ .vscode/
*.code-workspace *.code-workspace
.idea

View File

@ -1,6 +1 @@
# Launcher # Launcher
## Dependencies
- <https://www.npmjs.com/package/electron>
- <https://www.npmjs.com/package/minecraft-launcher-core>

5
package-lock.json generated
View File

@ -6097,6 +6097,11 @@
"extsprintf": "^1.2.0" "extsprintf": "^1.2.0"
} }
}, },
"vue": {
"version": "2.6.14",
"resolved": "https://registry.npmjs.org/vue/-/vue-2.6.14.tgz",
"integrity": "sha512-x2284lgYvjOMj3Za7kqzRcUSxBboHqtgRE2zlos1qWaOye5yUmHn42LB1250NJBLRwEcdrB0JRwyPTEPhfQjiQ=="
},
"wcwidth": { "wcwidth": {
"version": "1.0.1", "version": "1.0.1",
"resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz", "resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz",

View File

@ -36,7 +36,8 @@
"extract-zip": "^2.0.1", "extract-zip": "^2.0.1",
"hasha": "^5.2.2", "hasha": "^5.2.2",
"minecraft-launcher-core": "^3.16.8", "minecraft-launcher-core": "^3.16.8",
"msmc": "^2.2.1" "msmc": "^2.2.1",
"vue": "^2.6.14"
}, },
"config": { "config": {
"forge": "./config.forge.js" "forge": "./config.forge.js"

View File

@ -148,7 +148,6 @@ h3 {
width: 100%; width: 100%;
height: calc(100% - 28px); height: calc(100% - 28px);
background-color: rgba(0, 0, 0, 0.6); background-color: rgba(0, 0, 0, 0.6);
display: none;
z-index: 10; z-index: 10;
} }
@ -212,3 +211,10 @@ h3 {
border-width:0; border-width:0;
border-top: 1px solid black; border-top: 1px solid black;
} }
/* .slider {
min-width: 60%;
position:relative;
left:50%;
transform: translateX(-50%);
} */

View File

@ -64,4 +64,9 @@
.material-icons{ .material-icons{
position: relative; position: relative;
top: 2px; top: 2px;
}
#vue {
width: 100vw;
height: 100vh;
} }

View File

@ -1,143 +1,126 @@
const os = require('os') const os = require('os')
const launchBtn = document.querySelector('#launch-btn')
const launchText = document.querySelector("#launch-text")
const fullProgressBar = document.querySelector('#fullprogressbar')
const progressBar = document.querySelector('#progressbar')
const loadingMessage = document.querySelector('#loading-message')
const disconnectBtn = document.querySelector('#disconnect-btn')
const fullscreen = document.querySelector('#fullscreen')
const minMem = document.querySelector('#minMem')
const maxMem = document.querySelector('#maxMem')
const outputMinMem = document.querySelector('#outputMinMem')
const outputMaxMem = document.querySelector('#outputMaxMem')
const totalMem = os.totalmem() / (1.049 * Math.pow(10, 6)) const totalMem = os.totalmem() / (1.049 * Math.pow(10, 6))
let app = new vue({
el: "#vue",
data: {
minMemValue: localStorage.getItem("minMem") != null ? localStorage.getItem("minMem") : 1024 ,
maxMemValue: localStorage.getItem("maxMem") != null ? localStorage.getItem("maxMem") : 2048,
memStep: 128,
memMax: totalMem,
invalidateButtonText: "Supprimer et retélécharger les bibliothèques",
invalidateButtonDisabled: false,
displayFullscreen: "none",
nick: "Chargement",
launchBtnText: "Selectionnez un chapitre",
launchBtnDisable: true,
launchBtnHidden: false,
loadingMessageHidden: true,
loadingMessageText: "Téléchargement de Minecraft en cours...",
fullprogressbarHidden: true,
progressbarWidth: 0,
sidebarContent: "<hr><p>Chargement en cours</p>"
},
mounted: function () {
this.demandModsInformations()
},
methods: {
invalidateData: function () {
this.invalidateButtonDisabled = true
this.invalidateButtonText = "Opération en cours"
ipcRenderer.send('invalidateData')
},
launchBtnClick: function () {
this.launchBtnHidden = true
this.fullprogressbarHidden = false
app.loadingMessageHidden = false
if(Number(this.minMemValue) <= Number(this.maxMemValue)){
ipcRenderer.send('launch', {
minMem: this.minMemValue + "M",
maxMem: this.maxMemValue + "M",
chapter: selectedChapter
})
app.launchBtnDisable = true
localStorage.setItem("minMem", this.minMemValue)
localStorage.setItem("maxMem", this.maxMemValue)
gameLaunching = true
} else{
ipcRenderer.send('notification', {
title: "Erreur de lancement",
body: "La mémoire minimale doit être inférieure ou égale à la mémoire maximale"
})
}
},
disconnectBtn: function () {
ipcRenderer.send('disconnect')
},
options: function () {
if(!gameLaunching)
this.displayFullscreen = "block"
},
discord: () => shell.openExternal("https://discord.gg/b923tMhmRE"),
web: () => shell.openExternal("https://altarik.fr"),
closeFullscreen: function () {
this.displayFullscreen = "none"
},
demandModsInformations: function () {
ipcRenderer.send('demandModsInformations')
}
}
})
const sidebar = document.querySelector("#sidebar-content") const sidebar = document.querySelector("#sidebar-content")
const invalidateButton = document.querySelector("#invalidateData")
let gameLaunching = false let gameLaunching = false
let selectedChapter = -1; let selectedChapter = -1;
document.body.onload = () => { ipcRenderer.on("nick", (_, args) => app.nick = args.name)
minMem.max = totalMem
maxMem.max = totalMem
minMem.value = localStorage.getItem("minMem") != null ? localStorage.getItem("minMem") : 1024
outputMinMem.textContent = minMem.value
maxMem.value = localStorage.getItem("maxMem") != null ? localStorage.getItem("maxMem") : 2048
outputMaxMem.textContent = maxMem.value
demandModsInformations()
}
ipcRenderer.on("nick", (event, args) => {
console.log(args)
document.querySelector("#nick").innerHTML = args.name
})
launchBtn.addEventListener("click", e => {
launchText.classList.add('hidden')
fullProgressBar.classList.remove('hidden')
loadingMessage.classList.remove('hidden')
if(Number(minMem.value) <= Number(maxMem.value)){
ipcRenderer.send('launch', {
minMem: minMem.value + "M",
maxMem: maxMem.value + "M",
chapter: selectedChapter
})
launchBtn.disabled = true
localStorage.setItem("minMem", minMem.value)
localStorage.setItem("maxMem", maxMem.value)
gameLaunching = true
} else{
ipcRenderer.send('notification', {
title: "Erreur de lancement",
body: "La mémoire minimale doit être inférieure ou égale à la mémoire maximale"
})
}
})
document.querySelector("#web").addEventListener("click", e => {
shell.openExternal("https://altarik.fr")
})
document.querySelector("#options").addEventListener("click", e => {
if(!gameLaunching)
fullscreen.style.display = "block"
})
document.querySelector("#discord").addEventListener("click", e => {
shell.openExternal("https://discord.gg/b923tMhmRE")
})
document.querySelector("#close").addEventListener("click", e => {
fullscreen.style.display = "none"
});
invalidateButton.addEventListener("click", e => {
invalidateButton.disabled = true
invalidateButton.childNodes[0].nodeValue = "Opération en cours"
ipcRenderer.send('invalidateData')
})
ipcRenderer.on("invalidated", e => { ipcRenderer.on("invalidated", e => {
invalidateButton.disabled = false app.invalidateButtonDisabled = false
invalidateButton.childNodes[0].nodeValue = "Supprimer et retélécharger les bibliothèques" app.invalidateButtonText = "Supprimer et retélécharger les bibliothèques"
}) })
ipcRenderer.on("progress", (e, args) => { ipcRenderer.on("progress", (e, args) => {
progressBar.style.width = (args.task / Math.max(args.total, args.task)) * 100 + "%" app.progressbarWidth = (args.task / Math.max(args.total, args.task)) * 100
loadingMessage.innerHTML = "Téléchargement de " + args.type + ": " + args.task + " sur " + Math.max(args.total, args.task) app.loadingMessageText = "Téléchargement de " + args.type + ": " + args.task + " sur " + Math.max(args.total, args.task)
}) })
ipcRenderer.on("close", (e, args) => { ipcRenderer.on("close", (_e, _args) => {
launchText.classList.remove('hidden') app.launchBtnHidden = false
fullProgressBar.classList.add('hidden') app.fullprogressbarHidden = true
loadingMessage.classList.add('hidden') app.loadingMessageHidden = true
loadingMessage.innerHTML = "Chargement de Minecraft en cours..." app.loadingMessageText = "Chargement de Minecraft en cours..."
progressBar.style.width = "0" app.progressbarWidth = 0
launchBtn.disabled = false app.launchBtnDisable = false
gameLaunching = false gameLaunching = false
}) })
ipcRenderer.on('launch', (e, args) => { ipcRenderer.on('launch', (_e, _args) => {
fullProgressBar.classList.add('hidden') app.fullprogressbarHidden = true
loadingMessage.classList.add('hidden') app.loadingMessageText = true
}) })
ipcRenderer.on("modsInformations", (e, args) => { ipcRenderer.on("modsInformations", (e, args) => {
console.log(args)
if(args === null) { if(args === null) {
sidebar.innerHTML = "<hr><p>Une erreur est survenue lors de la récupération des informations, vérifiez votre connexion internet puis cliquez sur réessayez</p>" app.sidebarContent = "<hr><p>Une erreur est survenue lors de la récupération des informations, vérifiez votre connexion internet puis cliquez sur réessayez</p>"
+ "<button onclick=\"demandModsInformations()\">Réessayer</button>" + "<button onclick=\"app.demandModsInformations()\">Réessayer</button>"
} else { } else {
let element = "" let element = ""
for(const i in args) { for(const i in args) {
element += `<hr><div data-chapter="${i}" onclick="changeSelectedChapter(this)"><h3>${args[i].title}</h3><p>${args[i].description}</p></div>` element += `<hr><div data-chapter="${i}" onclick="changeSelectedChapter(this)"><h3>${args[i].title}</h3><p>${args[i].description}</p></div>`
} }
sidebar.innerHTML = element app.sidebarContent = element
} }
}) })
function demandModsInformations() {
ipcRenderer.send('demandModsInformations')
}
function changeSelectedChapter(element) { function changeSelectedChapter(element) {
selectedChapter = Number(element.dataset.chapter) selectedChapter = Number(element.dataset.chapter)
document.querySelectorAll("#sidebar-content > div").forEach((v, key) => { document.querySelectorAll("#sidebar-content > div").forEach((v, key) => {
v.classList.remove("selected") v.classList.remove("selected")
}) })
element.classList.add("selected") element.classList.add("selected")
launchText.innerHTML = "JOUER" app.launchBtnText = "JOUER"
launchBtn.disabled = false app.launchBtnDisable = false
} }
disconnectBtn.addEventListener('click', e => {
ipcRenderer.send('disconnect')
})
minMem.addEventListener("input", e => {
outputMinMem.textContent = e.target.value
})
maxMem.addEventListener("input", e => {
outputMaxMem.textContent = e.target.value
})

View File

@ -1,36 +1,50 @@
let app = new vue({
el: "#vue",
data: {
login: "Connexion",
email: "Email",
password: "Mot de passe",
send_credentials: "Se connecter",
microsoft_button: "Connexion avec un compte Microsoft"
},
methods: {
formSubmit: (e) => {
e.preventDefault()
if(!microsoftButton.disabled) {
form.disabled = true
if(user.value) {
ipcRenderer.send("login", {
user: user.value,
pass: password.value
})
}else{
ipcRenderer.send("notification", {
title: "error",
body: "Veuillez entrer des identifiants"
})
}
}
},
microsoftButton: (e) => {
e.preventDefault()
if(!form.disabled) {
microsoftButton.disabled = true
form.disabled = true
ipcRenderer.send("microsoft-login")
}
}
}
});
// theirs const are declared after vue cause vue modify them when declaring new vue instance
const form = document.querySelector('#login-form') const form = document.querySelector('#login-form')
const user = document.querySelector('#nickname') const user = document.querySelector('#nickname')
const password = document.querySelector('#password') const password = document.querySelector('#password')
const microsoftButton = document.querySelector("#microsoft-button") const microsoftButton = document.querySelector("#microsoft-button")
form.addEventListener("submit", (e) => { ipcRenderer.on("loginError", () => {
e.preventDefault()
if(!microsoftButton.disabled) {
form.disabled = true
if(user.value) {
ipcRenderer.send("login", {
user: user.value,
pass: password.value
})
}else{
ipcRenderer.send("notification", {
title: "error",
body: "Veuillez entrer des identifiants"
})
}
}
})
microsoftButton.addEventListener("click", (e) => {
e.preventDefault()
if(!form.disabled) {
microsoftButton.disabled = true
form.disabled = true
ipcRenderer.send("microsoft-login")
}
})
ipcRenderer.on("loginError", event => {
form.disabled = false form.disabled = false
microsoftButton.disabled = false microsoftButton.disabled = false
}) })

View File

@ -1,5 +1,7 @@
'use strict'; 'use strict';
const { ipcRenderer, shell } = require('electron'); const { ipcRenderer, shell } = require('electron');
// const isDev = require("electron-is-dev")
const vue = require(/*isDev ? */ 'vue/dist/vue'/* : 'vue' */)
window.addEventListener("DOMContentLoaded", () => { window.addEventListener("DOMContentLoaded", () => {
const minimizeButton = document.getElementById("minimize-btn") const minimizeButton = document.getElementById("minimize-btn")

View File

@ -3,66 +3,65 @@
<head> <head>
<meta charset="UTF-8"> <meta charset="UTF-8">
<title>Altarik Launcher</title> <title>Altarik Launcher</title>
<meta http-equiv="Content-Security-Policy" content="script-src 'self' 'unsafe-inline';" /> <meta http-equiv="Content-Security-Policy" content="script-src 'self' 'unsafe-inline' 'unsafe-eval';" />
<link href="assets/css/fonts.css" rel="stylesheet" /> <link href="assets/css/fonts.css" rel="stylesheet" />
<link href="assets/css/index.css" rel="stylesheet" /> <link href="assets/css/index.css" rel="stylesheet" />
<link href="assets/css/menubar.css" rel="stylesheet" /> <link href="assets/css/menubar.css" rel="stylesheet" />
<link rel="shortcut icon" type="image/png" href="assets/images/icon.png"/> <link rel="shortcut icon" type="image/png" href="assets/images/icon.png"/>
</head> </head>
<body> <body>
<div id="menubar"> <div id="vue">
<ul class="left"> <div id="menubar">
<img src="../../icon.ico"> <ul class="left">
</ul> <img src="../../icon.ico">
<ul class="right"> </ul>
<!-- Mettre ce code en ligne pour éviter que chrome ne met un espace automatiquement entre les éléments --> <ul class="right">
<li id="minimize-btn"><i class="material-icons">minimize</i></li><!--<li id="max-unmax-btn"><i class="material-icons">crop_square</i></li>--><li id="close-btn"><i class="material-icons">close</i></li> <!-- Mettre ce code en ligne pour éviter que chrome ne met un espace automatiquement entre les éléments -->
</ul> <li id="minimize-btn"><i class="material-icons">minimize</i></li><!--<li id="max-unmax-btn"><i class="material-icons">crop_square</i></li>--><li id="close-btn"><i class="material-icons">close</i></li>
</div> </ul>
<div id="fullscreen">
<div id="close"><i class="material-icons">close</i></div>
<div id="settings">
<h2>Modifier la configuration</h2>
<span href="" id="disconnect-btn">Se déconnecter</span>
<h4>Allocation mémoire</h4>
<label for="minMem">mémoire minimale : <span id="outputMinMem"></span></label><br />
<input type="range" min="1024" max="2048" step="128" value="1" class="slider" id="minMem"><br />
<label for="maxMem">mémoire maximale : <span id="outputMaxMem"></span></label><br />
<input type="range" min="1024" max="2048" step="128" value="1" class="slider" id="maxMem"><br />
<h4>Au secours, mon jeu ne démarre pas</h4>
<button id="invalidateData">Supprimer et retélécharger les bibliothèques</button>
</div> </div>
</div> <div id="fullscreen" :style="{ display: displayFullscreen }">
<div id="content"> <div @click="closeFullscreen" id="close"><i class="material-icons">close</i></div>
<div id="sidebar"> <div id="settings">
<h2>Chapitres</h2> <h2>Modifier la configuration</h2>
<div id="sidebar-content"> <span href="" id="disconnect-btn" @click="disconnectBtn">Se déconnecter</span>
<h4>Allocation mémoire</h4>
<label for="minMem">mémoire minimale : <span id="outputMinMem">{{ minMemValue }}</span></label><br />
<input type="number" min="1024" :max="memMax" :step="memStep" v-model="minMemValue" class="slider" id="minMem"><br />
<label for="maxMem">mémoire maximale : <span id="outputMaxMem">{{ maxMemValue }}</span></label><br />
<input type="number" min="1024" :max="memMax" :step="memStep" v-model="maxMemValue" class="slider" id="maxMem"><br />
<h4>Au secours, mon jeu ne démarre pas</h4>
<button @click="invalidateData" :disabled="invalidateButtonDisabled">{{ invalidateButtonText }}</button>
</div> </div>
</div> </div>
<div id="media"> <div id="content">
<div id="options"> <div id="sidebar">
<img src="assets/images/settings.png"> <h2>Chapitres</h2>
<div id="sidebar-content" v-html="sidebarContent"></div>
</div> </div>
<div id="discord"> <div id="media">
<img src="assets/images/discord.png"> <div @click="options">
<img src="assets/images/settings.png">
</div>
<div @click="discord">
<img src="assets/images/discord.png">
</div>
<div @click="web">
<img src="assets/images/web.png">
</div>
</div> </div>
<div id="web"> <div id="main">
<img src="assets/images/web.png"> <div id="account">
<div id="nick">{{ nick }}</div><!-- <img src=""> Head du joueur -->
</div>
<button @click="launchBtnClick" id="launch-btn" :disabled="launchBtnDisable">
<div id="launch-text" :class="[{hidden: launchBtnHidden}]">{{ launchBtnText }}</div>
<div id="loading-message" :class="[{hidden: loadingMessageHidden}]">{{ loadingMessageText }}</div>
<div id="fullprogressbar" :class="[{hidden: fullprogressbarHidden}]"><div id="progressbar" :style="{ width: progressbarWidth + '%' }"></div></div>
</button>
</div> </div>
</div> </div>
<div id="main">
<div id="account">
<div id="nick"></div><!-- <img src=""> Head du joueur -->
</div>
<button id="launch-btn" disabled>
<div id="launch-text">Selectionnez un chapitre</div>
<div id="loading-message" class="hidden">Téléchargement de Minecraft en cours...</div>
<div id="fullprogressbar" class="hidden"><div id="progressbar"></div></div>
</button>
</div>
</p>
</div> </div>
<script src="assets/js/script.js"></script> <script src="assets/js/script.js"></script>
<script src="assets/js/index.js"></script> <script src="assets/js/index.js"></script>

View File

@ -3,37 +3,39 @@
<head> <head>
<meta charset="UTF-8"> <meta charset="UTF-8">
<title>Altarik Launcher</title> <title>Altarik Launcher</title>
<meta http-equiv="Content-Security-Policy" content="script-src 'self' 'unsafe-inline';" /> <meta http-equiv="Content-Security-Policy" content="script-src 'self' 'unsafe-inline' 'unsafe-eval';" />
<link href="assets/css/fonts.css" rel="stylesheet" /> <link href="assets/css/fonts.css" rel="stylesheet" />
<link href="assets/css/login.css" rel="stylesheet" /> <link href="assets/css/login.css" rel="stylesheet" />
<link href="assets/css/menubar.css" rel="stylesheet" /> <link href="assets/css/menubar.css" rel="stylesheet" />
<link rel="shortcut icon" type="image/png" href="assets/images/icon.png"/> <link rel="shortcut icon" type="image/png" href="assets/images/icon.png"/>
</head> </head>
<body> <body>
<div id="menubar"> <div id="vue">
<ul class="left"> <div id="menubar">
<img src="../../icon.ico"> <ul class="left">
</ul> <img src="../../icon.ico">
<ul class="right"> </ul>
<!-- Mettre ce code en ligne pour éviter que chrome ne met un espace automatiquement entre les éléments --> <ul class="right">
<li id="minimize-btn"><i class="material-icons">minimize</i></li><!--<li id="max-unmax-btn"><i class="material-icons">crop_square</i></li>--><li id="close-btn"><i class="material-icons">close</i></li> <!-- Mettre ce code en ligne pour éviter que chrome ne met un espace automatiquement entre les éléments -->
</ul> <li id="minimize-btn"><i class="material-icons">minimize</i></li><!--<li id="max-unmax-btn"><i class="material-icons">crop_square</i></li>--><li id="close-btn"><i class="material-icons">close</i></li>
</div> </ul>
<div id="content">
<div id="login">
<h3>Connexion</h3>
<hr>
<form id="login-form">
<label for="nickname">Email:</label><br />
<input type="text" name="nickname" id="nickname"><br />
<label for="password">Mot de passe:</label><br />
<input type="password" name="password" id="password"><br />
<input type="submit" value="Se connecter">
</form>
</div> </div>
<button id="microsoft-button">Connexion avec un compte Microsoft</button> <div id="content">
<div id="login">
<h3>{{ login }}</h3>
<hr>
<form v-on:submit="formSubmit" id="login-form">
<label for="nickname">{{ email }}:</label><br />
<input type="text" name="nickname" id="nickname"><br />
<label for="password">{{ password }}:</label><br />
<input type="password" name="password" id="password"><br />
<input type="submit" v-bind:value="send_credentials">
</form>
</div>
<button id="microsoft-button" v-on:click="microsoftButton">{{ microsoft_button }}</button>
</div>
</div> </div>
<script src="assets/js/script.js"></script> <script src="assets/js/script.js"></script>
<script src="assets/js/login.js"></script> <script src="assets/js/login.js"></script>
</body> </body>

View File

@ -9,6 +9,7 @@ if (require('electron-squirrel-startup')) {
require('./updater.js').configUpdater(app, autoUpdater, dialog, logger) require('./updater.js').configUpdater(app, autoUpdater, dialog, logger)
const minecraft = require('./minecraft.js') const minecraft = require('./minecraft.js')
minecraft.showNotification = showNotification
const iconPath = join(__dirname, "icon.ico") const iconPath = join(__dirname, "icon.ico")
let win = null let win = null
@ -29,7 +30,7 @@ function createWindow () {
frame: false, frame: false,
nativeWindowOpen: true nativeWindowOpen: true
}) })
Menu.setApplicationMenu(null) // Menu.setApplicationMenu(null)
win.loadFile('src/client/login.html') win.loadFile('src/client/login.html')
win.on("close", () => { win.on("close", () => {
app.quit() app.quit()
@ -65,11 +66,11 @@ app.on('activate', () => {
}) })
ipcMain.on("login", (event, args) => { ipcMain.on("login", (event, args) => {
minecraft.login(event, win, showNotification, args.user, args.pass) minecraft.login(event, win, args.user, args.pass)
}) })
ipcMain.on("microsoft-login", (event, args) => { ipcMain.on("microsoft-login", (event, args) => {
minecraft.microsoftLogin(event, win, showNotification) minecraft.microsoftLogin(event, win)
}) })
ipcMain.on("invalidateData", event => { ipcMain.on("invalidateData", event => {
@ -77,7 +78,7 @@ ipcMain.on("invalidateData", event => {
}) })
ipcMain.on("launch", (event, args) => { ipcMain.on("launch", (event, args) => {
minecraft.launch(event, showNotification, args) minecraft.launch(event, args)
}) })
function showNotification(title, body="") { function showNotification(title, body="") {

View File

@ -16,11 +16,16 @@ class Minecraft {
launcher = new Client() launcher = new Client()
auth = null auth = null
modsList = undefined modsList = undefined
showNotification = undefined
setShowNotification(showNotification) {
this.showNotification = showNotification
}
/** /**
* Used to login through Mojang account * Used to login through Mojang account
*/ */
login(event, win, showNotification, 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)
@ -31,23 +36,23 @@ class Minecraft {
}).catch((err) => { }).catch((err) => {
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")
showNotification("Erreur de connexion") this.showNotification("Erreur de connexion")
}) })
} else { } else {
showNotification("Veuillez renseignez un mot de passe") this.showNotification("Veuillez renseignez un mot de passe")
} }
} }
/** /**
* Used to login through a Microsoft account * Used to login through a Microsoft account
*/ */
microsoftLogin(event, win, showNotification) { microsoftLogin(event, win) {
msmc.fastLaunch("electron", msmc.fastLaunch("electron",
(update) => { (update) => {
switch (update.type) { switch (update.type) {
case "Error": case "Error":
event.sender.send("loginError") event.sender.send("loginError")
showNotification("Une erreur est survenue", update.data) this.showNotification("Une erreur est survenue", update.data)
logger.error("MC-Account error:", update.data); logger.error("MC-Account error:", update.data);
break; break;
} }
@ -55,7 +60,7 @@ class Minecraft {
if(msmc.errorCheck(result)) { if(msmc.errorCheck(result)) {
event.sender.send("loginError") event.sender.send("loginError")
logger.error(result.reason) logger.error(result.reason)
showNotification("Erreur de connexion", result.reason) this.showNotification("Erreur de connexion", result.reason)
} else { } else {
if(!msmc.isDemoUser(result)) { if(!msmc.isDemoUser(result)) {
this.auth = msmc.getMCLC().getAuth(result) this.auth = msmc.getMCLC().getAuth(result)
@ -65,17 +70,17 @@ class Minecraft {
} else { } else {
event.sender.send("loginError") event.sender.send("loginError")
logger.error("[MS login] User haven't purchase the game") logger.error("[MS login] User haven't purchase the game")
showNotification("Erreur de connexion", "Vous ne possèdez pas de licence Minecraft sur ce compte") this.showNotification("Erreur de connexion", "Vous ne possèdez pas de licence Minecraft sur ce compte")
} }
} }
}).catch(reason => { }).catch(reason => {
event.sender.send("loginError") event.sender.send("loginError")
logger.error(reason) logger.error(reason)
showNotification("Erreur de connexion") this.showNotification("Erreur de connexion")
}) })
} }
launch(event, showNotification, args) { launch(event, args) {
this.extractJava(Number(args.chapter), event).then((javaPath) => { this.extractJava(Number(args.chapter), event).then((javaPath) => {
this.extractMods(Number(args.chapter), event).then((chapter) => { this.extractMods(Number(args.chapter), event).then((chapter) => {
this.launcher.launch({ this.launcher.launch({
@ -108,17 +113,17 @@ class Minecraft {
if(e !== 0) { if(e !== 0) {
logger.warn("Minecraft didn't close properly") logger.warn("Minecraft didn't close properly")
logger.warn(e) logger.warn(e)
showNotification("Une erreur est survenue", "Minecraft ne s'est pas fermé correctement") this.showNotification("Une erreur est survenue", "Minecraft ne s'est pas fermé correctement")
} }
}) })
}).catch((err) => { }).catch((err) => {
showNotification("Impossible de lancer le jeu") this.showNotification("Impossible de lancer le jeu")
event.sender.send("close", 1) event.sender.send("close", 1)
logger.error('Unable to launch the game') logger.error('Unable to launch the game')
logger.error(err) logger.error(err)
}) })
}).catch(err => { }).catch(err => {
showNotification("Impossible d'intaller Java pour votre configuration") this.showNotification("Impossible d'intaller Java pour votre configuration")
event.sender.send("close", 1) event.sender.send("close", 1)
logger.warn("Unable to install java") logger.warn("Unable to install java")
logger.warn(err) logger.warn(err)
@ -132,7 +137,10 @@ class Minecraft {
let folder = join(process.env.LOCALAPPDATA, "altarik-launcher", "data") let folder = join(process.env.LOCALAPPDATA, "altarik-launcher", "data")
if(!fs.existsSync(folder)) if(!fs.existsSync(folder))
fs.mkdirSync(folder) fs.mkdirSync(folder)
fs.writeFileSync(join(folder, "launcher.json"), JSON.stringify(o.data)) let file = join(folder, "launcher.json")
if(fs.existsSync(file))
fs.rmSync(file)
fs.writeFileSync(file, JSON.stringify(o.data))
event.sender.send('modsInformations', this.extractModsInformations(o.data)) event.sender.send('modsInformations', this.extractModsInformations(o.data))
} else { } else {
event.sender.send('modsInformations', this.extractModsFromFileSystem()) event.sender.send('modsInformations', this.extractModsFromFileSystem())
@ -145,12 +153,12 @@ class Minecraft {
} }
extractModsFromFileSystem() { extractModsFromFileSystem() {
content = fs.readFileSync(join(process.env.LOCALAPPDATA, "altarik-launcher/data/launcher.json")) let content = fs.readFileSync(join(process.env.LOCALAPPDATA, "altarik-launcher/data/launcher.json"))
if(content !== null) { if(content !== null) {
showNotification("Impossible de récupérer certaines informations en ligne", "utilisation des dernières données récupérées") this.showNotification("Impossible de récupérer certaines informations en ligne", "utilisation des dernières données récupérées")
return this.extractModsInformations(JSON.parse(content)) return this.extractModsInformations(JSON.parse(content))
} else { } else {
showNotification("Impossible de récupérer certaines informations en ligne", "Veuillez réessayez en cliquant sur le bouton") this.showNotification("Impossible de récupérer certaines informations en ligne", "Veuillez réessayez en cliquant sur le bouton")
logger.error("Unable to get chapters informations from server or filesystem") logger.error("Unable to get chapters informations from server or filesystem")
return null return null
} }
@ -215,9 +223,9 @@ class Minecraft {
downloadMods(link, path) { downloadMods(link, path) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
axios.get(link, { if(!navigator.onLine)
responseType: "stream" reject("offline")
}).then(res => { axios.get(link, {responseType: "stream"}).then(res => {
if(res.status === 200) { if(res.status === 200) {
if(fs.existsSync(path)) if(fs.existsSync(path))
fs.rmSync(path) fs.rmSync(path)
@ -305,6 +313,7 @@ class Minecraft {
} }
invalidateData(event) { invalidateData(event) {
logger.info("invalidate game data...")
const assets = join(this.minecraftpath, 'assets') const assets = join(this.minecraftpath, 'assets')
const librairies = join(this.minecraftpath,'libraries') const librairies = join(this.minecraftpath,'libraries')
const natives = join(this.minecraftpath, 'natives') const natives = join(this.minecraftpath, 'natives')
@ -314,6 +323,7 @@ class Minecraft {
fs.rmdirSync(librairies, { recursive: true }) fs.rmdirSync(librairies, { recursive: true })
if(fs.existsSync(natives)) if(fs.existsSync(natives))
fs.rmdirSync(natives, { recursive: true }) fs.rmdirSync(natives, { recursive: true })
logger.info("Game data invalidated")
event.sender.send("invalidated") event.sender.send("invalidated")
} }
} }