4
0
mirror of https://github.com/AltarikMC/Launcher synced 2025-12-14 11:52:27 +00:00

refactored project + changed name

This commit is contained in:
2021-02-01 21:54:34 +01:00
committed by Quentin Legot
parent cbd966a695
commit ff7aee024b
20 changed files with 96 additions and 93 deletions

Binary file not shown.

View File

@@ -0,0 +1,100 @@
* {
box-sizing: border-box;
}
@font-face {
font-family: "Roboto";
src: url("../Roboto-Regular.ttf") format("truetype");
}
html{
height: 100%;
}
body{
background: white;
margin:0;
height:100%;
font-family: "Roboto";
}
#content{
display: flex;
height:100%;
padding-top:28px;
}
#sidebar{
flex:20%;
background-color: rgb(43, 43, 43);
color: white;
padding:5px;
}
#main{
flex: 80%;
background-color: rgb(216, 216, 216);
padding: 0px;
}
#main-img {
height:100%;
width:100%;
}
h3 {
margin-block-end: 0.5em;
}
#launch{
position: absolute;
bottom:0;
right:0;
width:80%;
height:70px;
background-color:rgb(49, 49, 49);
}
#launch-btn {
position: relative;
top: 50%;
left:50%;
transform: translate(-50%, -50%);
width: 20%;
max-width:200px;
height:50px;
padding:10px;
text-align: center;
color:white;
font-weight: bold;
font-size:1.2rem;
background-color: green;
border: 1px solid black;
border-radius: 3px;
}
.hidden{
display:none;
}
#fullprogressbar{
position:relative;
margin: 0 auto;
width:80%;
height:25px;
background-color:gray;
}
#progressbar{
background-color: green;
height:100%;
width:0;
}
#loading-message{
width:80%;
position:relative;
margin: 0 auto;
height:28px;
color:white;
}

View File

@@ -0,0 +1,54 @@
* {
box-sizing: border-box;
}
@font-face {
font-family: "Roboto";
src: url("../Roboto-Regular.ttf") format("truetype");
}
html{
height: 100%;
}
body{
background: rgb(48, 48, 48);
margin:0;
height:100%;
font-family: "Roboto";
}
#content{
height:100%;
}
#login {
position:relative;
width: 300px;
top:50%;
left:50%;
transform: translate(-50%, -50%);
background-color: white;
padding: 8px;
}
#login input[type="text"],
#login input[type="password"]{
width:100%;
padding: 5px 2px;
}
#login input[type="submit"] {
padding: 5px;
width: 70%;
height: 25px;
margin: 10px 15%;
background-color: white;
border: 1px solid lightgrey;
transition: background 0.1s linear, border 0.2s;
cursor: pointer;
}
#login h3 {
margin-bottom: 0;
}

View File

@@ -0,0 +1,23 @@
/* fallback */
@font-face {
font-family: 'Material Icons';
font-style: normal;
font-weight: 400;
src: url(../material-icons.woff2) format('woff2');
}
.material-icons {
font-family: 'Material Icons';
font-weight: normal;
font-style: normal;
font-size: 24px;
line-height: 1;
letter-spacing: normal;
text-transform: none;
display: inline-block;
white-space: nowrap;
word-wrap: normal;
direction: ltr;
-webkit-font-feature-settings: 'liga';
-webkit-font-smoothing: antialiased;
}

View File

@@ -0,0 +1,55 @@
#menubar{
position:fixed;
top:0;
left:0;
width:100%;
height:28px;
background-color:rgb(37, 37, 37);
color:white;
cursor: move;
-webkit-app-region: drag;
-webkit-user-select: none;
}
#menubar ul{
margin:0;
padding:0;
}
#menubar .left{
float:left;
}
#menubar .right{
float: right;
-webkit-app-region: no-drag;
}
#menubar .right li,
#menubar .left li {
display: inline-block;
height:28px;
}
#menubar .right li:hover,
#menubar .left li:hover {
cursor: pointer;
}
#minimize-btn:hover,
#max-unmax-btn:hover{
background-color: rgb(55, 55, 55);
transition: 0.3s background-color ease;
}
#close-btn:hover{
background-color:red;
transition: 0.3s background-color ease;
}
.material-icons{
position: relative;
top: 2px;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 453 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 74 KiB

View File

@@ -0,0 +1,77 @@
const os = require('os');
const launchBtn = document.querySelector('#launch-btn');
const fullProgressBar = document.querySelector('#fullprogressbar')
const progressBar = document.querySelector('#progressbar')
const loadingMessage = document.querySelector('#loading-message')
const disconnectBtn = document.querySelector('#disconnect-btn')
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))
document.body.onload = (e) => {
minMem.max = totalMem
maxMem.max = totalMem
minMem.value = localStorage.getItem("minMem") != null ? localStorage.getItem("minMem") : 1024
outputMinMem.innerHTML = minMem.value
maxMem.value = localStorage.getItem("maxMem") != null ? localStorage.getItem("maxMem") : 2048
outputMaxMem.innerHTML = maxMem.value
}
ipcRenderer.on("nick", (event, args) => {
console.log(args)
document.querySelector("#nick-span").innerHTML = args.name
})
launchBtn.addEventListener("click", e => {
launchBtn.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"
})
launchBtn.disabled = true
localStorage.setItem("minMem", minMem.value)
localStorage.setItem("maxMem", maxMem.value)
} else{
ipcRenderer.send('notification', {
title: "Erreur de lancement",
body: "La mémoire minimale doit être inférieure ou égale à la mémoire maximale"
})
}
})
ipcRenderer.on("progress", (e, args) => {
progressBar.style.width = (args.task / args.total) * 100 + "%"
loadingMessage.innerHTML = "Téléchargement de " + args.type + ": " + args.task + " sur " + args.total;
})
ipcRenderer.on("close", (e, args) => {
launchBtn.classList.remove('hidden');
fullProgressBar.classList.add('hidden');
loadingMessage.classList.add('hidden');
loadingMessage.innerHTML = "Chargement de Minecraft en cours..."
progressBar.style.width = "0"
launchBtn.disabled = false
})
ipcRenderer.on('launch', (e, args) => {
fullProgressBar.classList.add('hidden');
loadingMessage.classList.add('hidden');
})
disconnectBtn.addEventListener('click', e => {
ipcRenderer.send('disconnect')
})
minMem.addEventListener("input", (e) => {
outputMinMem.innerHTML = e.target.value
})
maxMem.addEventListener("input", (e) => {
outputMaxMem.innerHTML = e.target.value
})

View File

@@ -0,0 +1,18 @@
user = document.querySelector('#nickname')
password = document.querySelector('#password')
document.querySelector('#login-form').addEventListener("submit", (e) => {
e.preventDefault()
if(user.value){
ipcRenderer.send("login", {
user: user.value,
pass: password.value
})
}else{
ipcRenderer.send("notification", {
title: "error",
body: "Veuillez entrer des identifiants"
})
}
})

View File

@@ -0,0 +1,42 @@
const { remote } = require('electron')
const {Menu, BrowserWindow, MenuItem, shell} = remote
function getCurrentWindow() {
return remote.getCurrentWindow()
}
function minimizeWindow(browserWindow = getCurrentWindow()) {
if (browserWindow.minimizable) {
// browserWindow.isMinimizable() for old electron versions
browserWindow.minimize()
}
}
function unmaximizeWindow(browserWindow = getCurrentWindow()) {
browserWindow.unmaximize()
}
function maxUnmaxWindow(browserWindow = getCurrentWindow()) {
if (browserWindow.isMaximized()) {
browserWindow.unmaximize()
} else {
browserWindow.maximize()
}
}
function closeWindow(browserWindow = getCurrentWindow()) {
browserWindow.close()
}
function isWindowMaximized(browserWindow = getCurrentWindow()) {
return browserWindow.isMaximized()
}
module.exports = {
getCurrentWindow,
minimizeWindow,
unmaximizeWindow,
maxUnmaxWindow,
isWindowMaximized,
closeWindow,
}

View File

@@ -0,0 +1,28 @@
'use strict';
const {remote, ipcRenderer} = require('electron');
const {
getCurrentWindow,
minimizeWindow,
unmaximizeWindow,
maxUnmaxWindow,
isWindowMaximized,
closeWindow,
} = require("./assets/js/menubar.js");
window.addEventListener("DOMContentLoaded", () => {
window.getCurrentWindow = getCurrentWindow
window.minimizeWindow = minimizeWindow
window.unmaximizeWindow = unmaximizeWindow
window.maxUnmaxWindow = maxUnmaxWindow
window.isWindowMaximized = isWindowMaximized
window.closeWindow = closeWindow
const minimizeButton = document.getElementById("minimize-btn")
const maxUnmaxButton = document.getElementById("max-unmax-btn")
const closeButton = document.getElementById("close-btn")
minimizeButton.addEventListener("click", e => window.minimizeWindow())
// maxUnmaxButton.addEventListener("click", e => window.maxUnmaxWindow())
closeButton.addEventListener("click", e => window.closeWindow())
})

Binary file not shown.

48
src/client/index.html Normal file
View File

@@ -0,0 +1,48 @@
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8">
<title>Launcher Projet Secret</title>
<meta http-equiv="Content-Security-Policy" content="script-src 'self' 'unsafe-inline';" />
<link href="assets/css/index.css" rel="stylesheet" />
<link href="assets/css/menubar.css" rel="stylesheet" />
<link href="assets/css/material-icons.css" rel="stylesheet" />
<link rel="shortcut icon" type="image/png" href="assets/images/icon.png"/>
</head>
<body>
<div id="menubar">
<ul class="left">
</ul>
<ul class="right">
<!-- Mettre ce code en ligne pour éviter que chrome ne met un espace automatiquement entre les éléments -->
<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>
</ul>
</div>
<div id="content">
<div id="sidebar">
<h3>Compte</h3>
<hr>
<span id="nick-span"></span>
<button id="disconnect-btn">Se déconnecter</button>
<h3>Modifier la configuration</h3>
<hr>
<h4>Allocation mémoire</h4>
<label for="minMem">mémoire minimale : <div id="outputMinMem"></div></label>
<input type="range" min="1024" max="2048" step="128" value="1" class="slider" id="minMem">
<label for="maxMem">mémoire maximale : <div id="outputMaxMem"></div></label>
<input type="range" min="1024" max="2048" step="128" value="1" class="slider" id="maxMem">
</div>
<div id="main">
<img id="main-img" src="assets/images/maxresdefault.jpg">
<div id="launch">
<button id="launch-btn">Lancer le jeu</button>
<div id="loading-message" class="hidden">Téléchargement de Minecraft en cours...</div>
<div id="fullprogressbar" class="hidden"><div id="progressbar"></div></div>
</div>
</div>
</p>
</div>
<script src="assets/js/script.js"></script>
<script src="assets/js/index.js"></script>
</body>
</html>

38
src/client/login.html Normal file
View File

@@ -0,0 +1,38 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Launcher Projet Secret</title>
<meta http-equiv="Content-Security-Policy" content="script-src 'self' 'unsafe-inline';" />
<link href="assets/css/login.css" rel="stylesheet" />
<link href="assets/css/menubar.css" rel="stylesheet" />
<link href="assets/css/material-icons.css" rel="stylesheet" />
<link rel="shortcut icon" type="image/png" href="assets/images/icon.png"/>
</head>
<body>
<div id="menubar">
<ul class="left">
</ul>
<ul class="right">
<!-- Mettre ce code en ligne pour éviter que chrome ne met un espace automatiquement entre les éléments -->
<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>
</ul>
</div>
<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>
<script src="assets/js/script.js"></script>
<script src="assets/js/login.js"></script>
</body>
</html>

51
src/server/install.js Normal file
View File

@@ -0,0 +1,51 @@
function handleSquirrelEvent(app) {
if (process.argv.length === 1) {
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, error;
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 = {
handleSquirrelEvent
}

114
src/server/main.js Normal file
View File

@@ -0,0 +1,114 @@
const { app, BrowserWindow, Menu, ipcMain, Notification } = require('electron')
const { join } = require('path')
if (require('electron-squirrel-startup')) {
require("./install.js").handleSquirrelEvent(app)
app.quit()
}
const { Client, Authenticator } = require('minecraft-launcher-core')
const appdata = process.env.APPDATA || (process.platform == 'darwin' ? process.env.HOME + '/Library/Preferences' : process.env.HOME + "/.local/share")
const launcher = new Client();
const iconPath = join(__dirname, "icon.ico");
let win = null
let auth = null
let Minecraftpath = join(appdata, ".altarik")
let clientPackage = "https://www.dropbox.com/s/ww6a052nzzgojdm/modpack.zip?dl=1"
let version = "1.16.4"
let versionFolder = "fabric-loader-0.10.8-1.16.4"
function createWindow () {
win = new BrowserWindow({
width: 1000,
minWidth: 1000,
maxWidth: 1000,
height: 600,
minHeight: 600,
maxHeight: 600,
icon: iconPath,
webPreferences: {
nodeIntegration: true,
enableRemoteModule: true
},
frame: false,
})
Menu.setApplicationMenu(null)
win.loadFile('src/client/login.html')
}
app.whenReady().then(() => {
createWindow()
})
app.on('window-all-closed', () => {
if (process.platform !== 'darwin') {
app.quit()
}
})
app.on('activate', () => {
if (win === null){
createWindow()
}
})
ipcMain.on("login", (event, args) => {
auth = Authenticator.getAuth(args.user, args.pass)
auth.then(v => {
win.loadFile('src/client/index.html')
setTimeout(() => {
event.sender.send("nick", {
name: v.name
})
}, 1000)
}).catch((err) => {
console.warn(err)
showNotification("Erreur de connexion")
})
})
function showNotification(title, body="") {
const notification = {
title: title,
body: body
}
new Notification(notification).show()
}
ipcMain.on("notification", (event, args) => {
showNotification(args.title, args.body)
})
ipcMain.on("launch", (event, args) => {
let opts = {
clientPackage: clientPackage,
authorization: auth,
root: Minecraftpath,
version: {
number: version,
type: "release",
custom: versionFolder
},
memory: {
max: args.maxMem,
min: args.minMem
}
}
launcher.launch(opts)
// launcher.on('debug', (e) => console.log("debug", e));
// launcher.on('data', (e) => console.log("data", e));
launcher.on('progress', (e) => event.sender.send("progress", e))
launcher.on('arguments', (e) => event.sender.send("launch", e))
launcher.on('close', (e) => {
event.sender.send("close", e)
if(e !== 0){
showNotification("Une erreur est survenue", "Minecraft ne s'est pas fermé correctement")
}
})
})
ipcMain.on("disconnect", (e) => {
win.loadFile('src/client/login.html')
})