Compare commits
No commits in common. "main" and "0.0.1-alpha" have entirely different histories.
main
...
0.0.1-alph
32
.github/workflows/build.yml
vendored
32
.github/workflows/build.yml
vendored
@ -1,32 +0,0 @@
|
|||||||
name: Release app
|
|
||||||
on:
|
|
||||||
workflow_dispatch: null
|
|
||||||
jobs:
|
|
||||||
release:
|
|
||||||
runs-on: ${{ matrix.os }}
|
|
||||||
strategy:
|
|
||||||
matrix:
|
|
||||||
os:
|
|
||||||
- windows-latest
|
|
||||||
- macos-latest
|
|
||||||
- macos-latest
|
|
||||||
- ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- name: Check out Git repository
|
|
||||||
uses: actions/checkout@4.2.2
|
|
||||||
- name: Install Node.js, NPM and Yarn
|
|
||||||
uses: actions/setup-node@4.4.0
|
|
||||||
with:
|
|
||||||
node-version: 20
|
|
||||||
- name: Config git user
|
|
||||||
run: |
|
|
||||||
git config --global user.email "gilleslazure04@gmail.com"
|
|
||||||
git config --global user.name "Gilles Lazure <azures04>"
|
|
||||||
- name: Install app dependencies
|
|
||||||
run: |
|
|
||||||
npm i
|
|
||||||
- name: Build app
|
|
||||||
run: |
|
|
||||||
node build
|
|
||||||
env:
|
|
||||||
GITHUB_TOKEN: ${{ github.token }}
|
|
||||||
BIN
app/assets/audio/Golden Hill (Radio Edit).mp3
Normal file
BIN
app/assets/audio/Golden Hill (Radio Edit).mp3
Normal file
Binary file not shown.
Binary file not shown.
@ -11,14 +11,6 @@ body {
|
|||||||
background-color: #262626;
|
background-color: #262626;
|
||||||
}
|
}
|
||||||
|
|
||||||
main {
|
|
||||||
app-region: drag;
|
|
||||||
}
|
|
||||||
|
|
||||||
main > * {
|
|
||||||
app-region: no-drag;
|
|
||||||
}
|
|
||||||
|
|
||||||
main > article > section > img {
|
main > article > section > img {
|
||||||
width: 150px;
|
width: 150px;
|
||||||
}
|
}
|
||||||
@ -41,14 +33,6 @@ main > article > section.informations {
|
|||||||
font-family: "Roboto", sans-serif;
|
font-family: "Roboto", sans-serif;
|
||||||
}
|
}
|
||||||
|
|
||||||
main > article > section.logo > h2 {
|
|
||||||
color: #ffffff;
|
|
||||||
padding: 13px 13px 13px 13px;
|
|
||||||
font-weight: bolder;
|
|
||||||
text-align: center;
|
|
||||||
font-family: "Roboto", sans-serif;
|
|
||||||
}
|
|
||||||
|
|
||||||
main > article > section.informations > h2 {
|
main > article > section.informations > h2 {
|
||||||
margin-bottom: 10px;
|
margin-bottom: 10px;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -4,8 +4,6 @@
|
|||||||
* {
|
* {
|
||||||
margin: 0px;
|
margin: 0px;
|
||||||
padding: 0px;
|
padding: 0px;
|
||||||
outline: none;
|
|
||||||
user-select: none;
|
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
font-family: "Roboto", sans-serif;
|
font-family: "Roboto", sans-serif;
|
||||||
}
|
}
|
||||||
@ -18,11 +16,6 @@ body {
|
|||||||
background-attachment: fixed;
|
background-attachment: fixed;
|
||||||
}
|
}
|
||||||
|
|
||||||
img {
|
|
||||||
app-region: drag;
|
|
||||||
pointer-events: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
main {
|
main {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 0px;
|
top: 0px;
|
||||||
@ -31,19 +24,12 @@ main {
|
|||||||
bottom: 0px;
|
bottom: 0px;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
overflow: hidden;
|
|
||||||
app-region: drag;
|
|
||||||
}
|
|
||||||
|
|
||||||
main > * {
|
|
||||||
app-region: no-drag;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
main > nav {
|
main > nav {
|
||||||
margin-left: 1rem;
|
margin-left: 1rem;
|
||||||
width: 20%;
|
width: 20%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
overflow-y: auto;
|
|
||||||
background-color: #3e3e3ee6;
|
background-color: #3e3e3ee6;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -106,7 +92,7 @@ img.logo {
|
|||||||
img.mascot {
|
img.mascot {
|
||||||
width: 50%;
|
width: 50%;
|
||||||
float: right;
|
float: right;
|
||||||
margin-top: calc(300px - (50% + 32px));
|
margin-top: calc(300px - (50% + 12px));
|
||||||
}
|
}
|
||||||
|
|
||||||
fieldset {
|
fieldset {
|
||||||
@ -386,63 +372,7 @@ div.checkboxes > input[type="checkbox"] {
|
|||||||
font-size: small;
|
font-size: small;
|
||||||
}
|
}
|
||||||
|
|
||||||
div.loader {
|
|
||||||
overflow: hidden;
|
|
||||||
position: absolute;
|
|
||||||
left: 0px;
|
|
||||||
right: 0px;
|
|
||||||
bottom: 0px;
|
|
||||||
width: 100%;
|
|
||||||
height: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.loader > div.full {
|
|
||||||
height: 10px;
|
|
||||||
width: 100%;
|
|
||||||
background-color: #3e3e3ee6;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.loader > div.full > div.progress,
|
|
||||||
div.loader > div.full > div.loading {
|
|
||||||
height: 10px;
|
|
||||||
width: 50%;
|
|
||||||
transition: 1s width;
|
|
||||||
background-color: #39aa6d;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.loader > div.full > div.loading {
|
|
||||||
animation: animateLoadingEffect 1s linear infinite;
|
|
||||||
}
|
|
||||||
|
|
||||||
[hidden] {
|
[hidden] {
|
||||||
display: none;
|
display: none;
|
||||||
visibility: hidden;
|
visibility: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Chrome-specific scrollbar styling */
|
|
||||||
::-webkit-scrollbar {
|
|
||||||
width: 8px;
|
|
||||||
height: 8px;
|
|
||||||
}
|
|
||||||
|
|
||||||
::-webkit-scrollbar-track {
|
|
||||||
background: rgba(0, 0, 0, 0.1); /* Slightly visible track for better contrast */
|
|
||||||
}
|
|
||||||
|
|
||||||
::-webkit-scrollbar-thumb {
|
|
||||||
background: #2E8B57;
|
|
||||||
border-radius: 4px; /* Rounded edges for a modern look */
|
|
||||||
}
|
|
||||||
|
|
||||||
::-webkit-scrollbar-thumb:hover {
|
|
||||||
background: #39aa6d;
|
|
||||||
}
|
|
||||||
|
|
||||||
@keyframes animateLoadingEffect {
|
|
||||||
0% {
|
|
||||||
transform: translateX(-100%);
|
|
||||||
}
|
|
||||||
100% {
|
|
||||||
transform: translateX(200%);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
BIN
app/assets/img/alcaz_mascote.png
Normal file
BIN
app/assets/img/alcaz_mascote.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 389 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 846 KiB |
@ -7,7 +7,7 @@ const audioPourcentageLabel = document.querySelector("label[for='audioVolume']")
|
|||||||
const audio = new Audio()
|
const audio = new Audio()
|
||||||
|
|
||||||
function startAudio() {
|
function startAudio() {
|
||||||
audio.src = "./assets/audio/main_menu.mp3"
|
audio.src = "./assets/audio/Golden Hill (Radio Edit).mp3"
|
||||||
audio.loop = true
|
audio.loop = true
|
||||||
audio.play()
|
audio.play()
|
||||||
audio.onended = () => {
|
audio.onended = () => {
|
||||||
@ -58,39 +58,25 @@ function toggleAudio(element) {
|
|||||||
|
|
||||||
function toggleMusic(element) {
|
function toggleMusic(element) {
|
||||||
if (element.getAttribute("state") == 0) {
|
if (element.getAttribute("state") == 0) {
|
||||||
audio.pause()
|
system.call("audio::mute")
|
||||||
element.setAttribute("state", 1)
|
element.setAttribute("state", 1)
|
||||||
element.children[0].classList.replace("fa-pause", "fa-play")
|
element.children[0].classList.replace("fa-pause", "fa-play")
|
||||||
element.children[1].innerText = "Reprendre"
|
element.children[1].innerText = "Reprendre"
|
||||||
} else {
|
} else {
|
||||||
audio.play()
|
system.call("audio::unmute")
|
||||||
element.setAttribute("state", 0)
|
element.setAttribute("state", 0)
|
||||||
element.children[0].classList.replace("fa-play", "fa-pause")
|
element.children[0].classList.replace("fa-play", "fa-pause")
|
||||||
element.children[1].innerText = "Pause"
|
element.children[1].innerText = "Pause"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function toggleMusicVolume(element) {
|
|
||||||
if (element.getAttribute("state") == 0) {
|
|
||||||
system.call("audio::mute")
|
|
||||||
element.setAttribute("state", 1)
|
|
||||||
element.children[0].classList.replace("fa-volume", "fa-volume-slash")
|
|
||||||
element.children[1].innerText = "Activer le son"
|
|
||||||
} else {
|
|
||||||
system.call("audio::unmute")
|
|
||||||
element.setAttribute("state", 0)
|
|
||||||
element.children[0].classList.replace("fa-volume-slash", "fa-volume")
|
|
||||||
element.children[1].innerText = "Couper le son"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function updateVolume(value) {
|
function updateVolume(value) {
|
||||||
audio.volume = value / 100
|
audio.volume = value / 100
|
||||||
audioPourcentageLabel.innerText = `${value}%`
|
audioPourcentageLabel.innerText = `${value}%`
|
||||||
}
|
}
|
||||||
|
|
||||||
function logout() {
|
function logout() {
|
||||||
system.call("auth::reset")
|
localStorage.removeItem("user")
|
||||||
document.location.href = './login.html'
|
document.location.href = './login.html'
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -98,82 +84,30 @@ system.result("server::ping", pong => {
|
|||||||
playersStatus.innerText = `${pong.players.online}/${pong.players.max}`
|
playersStatus.innerText = `${pong.players.online}/${pong.players.max}`
|
||||||
})
|
})
|
||||||
|
|
||||||
|
system.result("player::profile", playerProfile => {
|
||||||
|
if (!localStorage.getItem("user")) {
|
||||||
|
localStorage.setItem("user", JSON.stringify(playerProfile))
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
function handleOptionsChanges(key, value) {
|
function handleOptionsChanges(key, value) {
|
||||||
system.call("game::optionSet", { key, value })
|
system.call("game::optionSet", { key, value })
|
||||||
const span = document.querySelector(`span#current${key.replace(/./, c => c.toUpperCase())}`)
|
|
||||||
if (span) {
|
|
||||||
span.innerText = Math.floor(value)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleSettingsChanges(key, value) {
|
function handleSettingsChanges(key, value) {
|
||||||
system.call("settings::set", { key, value })
|
system.call("settings::set", { key, value })
|
||||||
const span = document.querySelector(`span#${key == "ram" ? "currentRam" : key}`)
|
|
||||||
if (span) {
|
|
||||||
span.innerText = key == "ram" ? Math.floor(value.max / 1024) + " G" : value
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function setLoadingType(type) {
|
|
||||||
const loader = document.querySelector(".loader")
|
|
||||||
switch (type) {
|
|
||||||
case "continuous":
|
|
||||||
loader.children[0].children[0].classList.remove("progress")
|
|
||||||
loader.children[0].children[0].classList.add("loading")
|
|
||||||
break
|
|
||||||
case "progress":
|
|
||||||
loader.children[0].children[0].classList.remove("loading")
|
|
||||||
loader.children[0].children[0].classList.add("progress")
|
|
||||||
break
|
|
||||||
default:
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function setLoadingProgress(pourcentage) {
|
|
||||||
const loader = document.querySelector(".loader")
|
|
||||||
const progress = loader.querySelector(".progress")
|
|
||||||
if (progress) {
|
|
||||||
progress.setAttribute("style", `width: ${pourcentage}%`)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function toggleLoadingBar() {
|
|
||||||
const loader = document.querySelector(".loader")
|
|
||||||
if (loader.hasAttribute("hidden")) {
|
|
||||||
loader.removeAttribute("hidden")
|
|
||||||
} else {
|
|
||||||
loader.setAttribute("hidden", "")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function showLoadingBar() {
|
|
||||||
const loader = document.querySelector(".loader")
|
|
||||||
if (loader.hasAttribute("hidden")) {
|
|
||||||
loader.removeAttribute("hidden")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function hideLoadingBar() {
|
|
||||||
const loader = document.querySelector(".loader")
|
|
||||||
if (!loader.hasAttribute("hidden")) {
|
|
||||||
loader.setAttribute("hidden", "")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
system.result("game::parseOptions", options => {
|
system.result("game::parseOptions", options => {
|
||||||
gamma.checked = options.gamma == 1 ? true : false
|
gamma.checked = options.gamma == 1 ? true : false
|
||||||
renderClouds.checked = options.renderrenderClouds == false ? false : true
|
renderClouds.checked = options.renderrenderClouds == false ? false : true
|
||||||
guiScale.value = options.guiScale
|
guiScale.value = options.guiScale
|
||||||
currentGuiScale.innerText = options.guiScale
|
|
||||||
graphicsMode.checked = options.graphicsMode == 0 ? true : false
|
graphicsMode.checked = options.graphicsMode == 0 ? true : false
|
||||||
renderDistance.value = options.renderDistance
|
renderDistance.value = options.renderDistance
|
||||||
currentRenderDistance.innerText = options.renderDistance
|
|
||||||
})
|
})
|
||||||
|
|
||||||
system.result("settings::read", settings => {
|
system.result("settings::read", settings => {
|
||||||
ram.value = settings.ram.max
|
ram.value = settings.ram.max
|
||||||
currentRam.innerText = `${Math.floor(settings.ram.max / 1024)} G`
|
|
||||||
})
|
})
|
||||||
|
|
||||||
system.result("hardware::ramInformation", $ram => {
|
system.result("hardware::ramInformation", $ram => {
|
||||||
@ -184,52 +118,16 @@ system.result("hardware::ramInformation", $ram => {
|
|||||||
system.result("game::launch", info => {
|
system.result("game::launch", info => {
|
||||||
if (info.disablePlayButton) {
|
if (info.disablePlayButton) {
|
||||||
playButton.removeAttribute("hidden")
|
playButton.removeAttribute("hidden")
|
||||||
hideLoadingBar()
|
|
||||||
} else {
|
} else {
|
||||||
playButton.setAttribute("hidden", "")
|
playButton.setAttribute("hidden", "")
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
system.result("game::launched", info => {
|
|
||||||
muteAudio()
|
|
||||||
hideLoadingBar()
|
|
||||||
})
|
|
||||||
|
|
||||||
system.result("player::profile", playerProfile => {
|
|
||||||
console.log(playerProfile)
|
|
||||||
})
|
|
||||||
|
|
||||||
system.result("oculus::getdefaultshaderset", boolean => {
|
|
||||||
sildurs_shader.checked = boolean
|
|
||||||
})
|
|
||||||
|
|
||||||
system.result("progress::update", info => {
|
|
||||||
showLoadingBar()
|
|
||||||
setLoadingType(info.type)
|
|
||||||
if (info.type == "progress" && typeof info.pourcentage == "number") {
|
|
||||||
setLoadingProgress(info.pourcentage)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
system.result("progress::hide", () => {
|
|
||||||
hideLoadingBar()
|
|
||||||
})
|
|
||||||
|
|
||||||
system.result("izitoast::error", info => {
|
|
||||||
iziToast.error(info)
|
|
||||||
})
|
|
||||||
|
|
||||||
system.result("progress::info", info => {
|
|
||||||
iziToast.error(info)
|
|
||||||
})
|
|
||||||
|
|
||||||
window.onload = () => {
|
window.onload = () => {
|
||||||
system.call("hardware::ramInformation")
|
system.call("hardware::ramInformation")
|
||||||
system.call("game::parseOptions")
|
system.call("game::parseOptions")
|
||||||
system.call("server::ping")
|
system.call("server::ping")
|
||||||
system.call("player::profile")
|
system.call("player::profile")
|
||||||
system.call("settings::read")
|
system.call("settings::read")
|
||||||
system.call("oculus::getdefaultshaderset")
|
|
||||||
hideLoadingBar()
|
|
||||||
startAudio()
|
startAudio()
|
||||||
}
|
}
|
||||||
@ -19,3 +19,12 @@ system.result("auth::microsoft", () => {
|
|||||||
system.result("auth::refresh", () => {
|
system.result("auth::refresh", () => {
|
||||||
selectLoginType("select")
|
selectLoginType("select")
|
||||||
})
|
})
|
||||||
|
|
||||||
|
window.onload = () => {
|
||||||
|
if (localStorage.getItem("user")) {
|
||||||
|
system.call("auth::refresh", {
|
||||||
|
user: JSON.parse(localStorage.getItem("user"))
|
||||||
|
})
|
||||||
|
selectLoginType("token")
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,28 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html lang="en">
|
|
||||||
<head>
|
|
||||||
<meta charset="UTF-8">
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
||||||
<link rel="stylesheet" href="./assets/css/banned.css">
|
|
||||||
<title>Launcher banni</title>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
|
|
||||||
<main>
|
|
||||||
<button class="close" onclick="system.call('window::close')">
|
|
||||||
<i class="fas fa-times"></i>
|
|
||||||
</button>
|
|
||||||
<article>
|
|
||||||
<section class="logo">
|
|
||||||
<img src="./assets/img/icon.png" alt="">
|
|
||||||
<h2>
|
|
||||||
Veuillez patienter
|
|
||||||
</h2>
|
|
||||||
</section>
|
|
||||||
</article>
|
|
||||||
</main>
|
|
||||||
|
|
||||||
<script src="./assets/js/banned.js"></script>
|
|
||||||
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
@ -3,7 +3,6 @@
|
|||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/izitoast/1.4.0/css/iziToast.css">
|
|
||||||
<link rel="stylesheet" href="./assets/css/index.css">
|
<link rel="stylesheet" href="./assets/css/index.css">
|
||||||
<title>NyanLauncher</title>
|
<title>NyanLauncher</title>
|
||||||
</head>
|
</head>
|
||||||
@ -12,9 +11,6 @@
|
|||||||
<button class="close" onclick="system.call('window::close')">
|
<button class="close" onclick="system.call('window::close')">
|
||||||
<i class="fas fa-times"></i>
|
<i class="fas fa-times"></i>
|
||||||
</button>
|
</button>
|
||||||
<button class="close" onclick="system.call('window::reduce')">
|
|
||||||
<i class="fas fa-minus"></i>
|
|
||||||
</button>
|
|
||||||
<nav hidden>
|
<nav hidden>
|
||||||
<button class="close" onclick="hideNavBar()">
|
<button class="close" onclick="hideNavBar()">
|
||||||
<i class="fas fa-times"></i>
|
<i class="fas fa-times"></i>
|
||||||
@ -50,10 +46,10 @@
|
|||||||
Ram alloué
|
Ram alloué
|
||||||
</label>
|
</label>
|
||||||
<div class="ranges">
|
<div class="ranges">
|
||||||
<span id="currentRam">
|
<span>
|
||||||
0.5GB
|
0.5GB
|
||||||
</span>
|
</span>
|
||||||
<input type="range" name="ram" min="0" max="2048" id="ram" onchange="handleSettingsChanges('ram', { max: this.value })">
|
<input type="range" name="ram" min="0" max="2048" id="ram" onchange="handleSettingsChanges(this.name, this.value)">
|
||||||
<span id="maxRam">
|
<span id="maxRam">
|
||||||
MAX
|
MAX
|
||||||
</span>
|
</span>
|
||||||
@ -63,7 +59,7 @@
|
|||||||
Distance de rendu
|
Distance de rendu
|
||||||
</label>
|
</label>
|
||||||
<div class="ranges">
|
<div class="ranges">
|
||||||
<span id="currentRenderDistance">
|
<span>
|
||||||
4
|
4
|
||||||
</span>
|
</span>
|
||||||
<input type="range" name="renderDistance" min="4" max="32" id="renderDistance" onchange="handleOptionsChanges(this.name, this.value)">
|
<input type="range" name="renderDistance" min="4" max="32" id="renderDistance" onchange="handleOptionsChanges(this.name, this.value)">
|
||||||
@ -76,7 +72,7 @@
|
|||||||
Taille de l'interface
|
Taille de l'interface
|
||||||
</label>
|
</label>
|
||||||
<div class="ranges">
|
<div class="ranges">
|
||||||
<span id="currentGuiScale">
|
<span>
|
||||||
1
|
1
|
||||||
</span>
|
</span>
|
||||||
<input type="range" name="guiScale" min="1" max="4" id="guiScale" onchange="handleOptionsChanges(this.name, this.value)">
|
<input type="range" name="guiScale" min="1" max="4" id="guiScale" onchange="handleOptionsChanges(this.name, this.value)">
|
||||||
@ -104,12 +100,12 @@
|
|||||||
Luminsoité max
|
Luminsoité max
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<!-- <div>
|
||||||
<input type="checkbox" name="sildurs_shader" id="sildurs_shader" onclick="system.call('oculus::defaultshaderset', { boolean: this.checked })">
|
<input type="checkbox" name="sildurs_shader" id="sildurs_shader">
|
||||||
<label for="sildurs_shader">
|
<label for="sildurs_shader">
|
||||||
Sildur's Shader
|
Sildur's Shader
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div> -->
|
||||||
</div>
|
</div>
|
||||||
</article>
|
</article>
|
||||||
</details>
|
</details>
|
||||||
@ -129,12 +125,6 @@
|
|||||||
100%
|
100%
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
<button class="classic" onclick="toggleMusicVolume(this)" state="0">
|
|
||||||
<i class="fas fa-volume"></i>
|
|
||||||
<span>
|
|
||||||
Couper le son
|
|
||||||
</span>
|
|
||||||
</button>
|
|
||||||
<button class="classic" onclick="toggleMusic(this)" state="0">
|
<button class="classic" onclick="toggleMusic(this)" state="0">
|
||||||
<i class="fas fa-pause"></i>
|
<i class="fas fa-pause"></i>
|
||||||
<span>
|
<span>
|
||||||
@ -215,23 +205,16 @@
|
|||||||
<section class="center">
|
<section class="center">
|
||||||
<img class="logo" src="./assets/img/logo.png" alt="">
|
<img class="logo" src="./assets/img/logo.png" alt="">
|
||||||
<br>
|
<br>
|
||||||
<button class="play load" name="play" onclick="system.call('game::launch')">
|
<button class="play" name="play" onclick="system.call('game::launch')">
|
||||||
Jouer
|
Jouer
|
||||||
</button>
|
</button>
|
||||||
</section>
|
</section>
|
||||||
<section class="right">
|
<section class="right">
|
||||||
<img class="mascot" src="./assets/img/sulli.png" alt="">
|
<img class="mascot" src="./assets/img/alcaz_mascote.png" alt="">
|
||||||
</section>
|
</section>
|
||||||
</footer>
|
</footer>
|
||||||
<div class="loader">
|
|
||||||
<div class="full">
|
|
||||||
<div class="loading">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</main>
|
</main>
|
||||||
|
|
||||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/izitoast/1.4.0/js/iziToast.min.js"></script>
|
|
||||||
<script src="./assets/js/index.js"></script>
|
<script src="./assets/js/index.js"></script>
|
||||||
|
|
||||||
</body>
|
</body>
|
||||||
|
|||||||
@ -12,9 +12,6 @@
|
|||||||
<button class="close" onclick="system.call('window::close')">
|
<button class="close" onclick="system.call('window::close')">
|
||||||
<i class="fas fa-times"></i>
|
<i class="fas fa-times"></i>
|
||||||
</button>
|
</button>
|
||||||
<button class="close" onclick="system.call('window::reduce')">
|
|
||||||
<i class="fas fa-minus"></i>
|
|
||||||
</button>
|
|
||||||
<article class="loginchoice">
|
<article class="loginchoice">
|
||||||
<div frame="select">
|
<div frame="select">
|
||||||
<h2>
|
<h2>
|
||||||
|
|||||||
4
build.js
4
build.js
@ -1,4 +1,4 @@
|
|||||||
require("v8-compile-cache")
|
const fs = require("node:fs")
|
||||||
const path = require("node:path")
|
const path = require("node:path")
|
||||||
const builder = require("electron-builder")
|
const builder = require("electron-builder")
|
||||||
|
|
||||||
@ -43,7 +43,7 @@ async function buildApp() {
|
|||||||
"!dist",
|
"!dist",
|
||||||
"!.env"
|
"!.env"
|
||||||
],
|
],
|
||||||
buildNumber: 2,
|
buildNumber: 1,
|
||||||
buildVersion: `${package.version}`,
|
buildVersion: `${package.version}`,
|
||||||
releaseInfo: {
|
releaseInfo: {
|
||||||
releaseDate: getFormattedProductionDate(),
|
releaseDate: getFormattedProductionDate(),
|
||||||
|
|||||||
@ -6,8 +6,7 @@
|
|||||||
"checkBanStatus": "/api/v1/ban/iam",
|
"checkBanStatus": "/api/v1/ban/iam",
|
||||||
"telemetry": "/api/v1/telemetry",
|
"telemetry": "/api/v1/telemetry",
|
||||||
"gameFiles": "/api/v1/file/game",
|
"gameFiles": "/api/v1/file/game",
|
||||||
"downloadFile": "/api/v1/file/game/download",
|
"downloadFile": "/api/v1/file/game/download"
|
||||||
"countdown": "/api/v1/countdown"
|
|
||||||
},
|
},
|
||||||
"websockets": {
|
"websockets": {
|
||||||
"base": {
|
"base": {
|
||||||
|
|||||||
215
main.js
215
main.js
@ -1,5 +1,4 @@
|
|||||||
const { BrowserWindow, app, net, dialog, ipcMain, nativeImage, session, shell } = require("electron")
|
const { BrowserWindow, app, net, dialog, ipcMain, nativeImage, session, shell } = require("electron")
|
||||||
const properties = require("js-java-properties")
|
|
||||||
const msmc = require("msmc")
|
const msmc = require("msmc")
|
||||||
const os = require("node:os")
|
const os = require("node:os")
|
||||||
const fs = require("node:fs")
|
const fs = require("node:fs")
|
||||||
@ -14,16 +13,12 @@ const fileManager = require("./modules/fileManager")
|
|||||||
const launcher = new Client()
|
const launcher = new Client()
|
||||||
const { io } = require("socket.io-client")
|
const { io } = require("socket.io-client")
|
||||||
const download = require("download")
|
const download = require("download")
|
||||||
const rpc = require("./modules/rpc")
|
|
||||||
const java = require("./modules/java")
|
|
||||||
const socket = io({
|
const socket = io({
|
||||||
host: config.api.websockets.base.host,
|
host: config.api.websockets.base.host,
|
||||||
port: config.api.websockets.base.port
|
port: config.api.websockets.base.port
|
||||||
})
|
})
|
||||||
|
|
||||||
let launcherWindow, defaultWindow, auth, gamePlayable = false, launchProcess
|
let launcherWindow, auth, gamePlayable = false, launchProcess
|
||||||
|
|
||||||
rpc.startRichPresence()
|
|
||||||
|
|
||||||
async function createLauncherWindow() {
|
async function createLauncherWindow() {
|
||||||
gameOptions.initOptions(path.join(app.getPath("appData"), ".catboat", "options.txt"))
|
gameOptions.initOptions(path.join(app.getPath("appData"), ".catboat", "options.txt"))
|
||||||
@ -109,63 +104,6 @@ async function createLauncherWindow() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function createDefaultWindow() {
|
|
||||||
gameOptions.initOptions(path.join(app.getPath("appData"), ".catboat", "options.txt"))
|
|
||||||
launcherSettings.initSettings(path.join(app.getPath("appData"), ".catboat"))
|
|
||||||
if (net.isOnline()) {
|
|
||||||
const isLauncherNotBanned = await checkIfIAmBanned()
|
|
||||||
try {
|
|
||||||
defaultWindow = new BrowserWindow({
|
|
||||||
frame: false,
|
|
||||||
width: 300,
|
|
||||||
height: 400,
|
|
||||||
minWidth: 300,
|
|
||||||
minHeight: 400,
|
|
||||||
titleBarStyle: "hidden",
|
|
||||||
autoHideMenuBar: true,
|
|
||||||
roundedCorners: false,
|
|
||||||
resizable: false,
|
|
||||||
webPreferences: {
|
|
||||||
nodeIntegration: false,
|
|
||||||
contextIsolation: true,
|
|
||||||
preload: path.join(__dirname, "modules", "preload.js"),
|
|
||||||
webviewTag: true,
|
|
||||||
devTools: false
|
|
||||||
}
|
|
||||||
})
|
|
||||||
if (os.platform() == "darwin") {
|
|
||||||
app.dock.setIcon(nativeImage.createFromPath(path.join(__dirname, "app", "assets", "img", "icon.png")))
|
|
||||||
}
|
|
||||||
defaultWindow.setIcon(path.join(__dirname, "app", "assets", "img", "icon.png"))
|
|
||||||
if (isLauncherNotBanned.success) {
|
|
||||||
defaultWindow.loadFile(path.join(__dirname, "app", "loading.html"))
|
|
||||||
defaultWindow.webContents.openDevTools()
|
|
||||||
try {
|
|
||||||
await java.main(path.join(app.getPath("appData"), ".catboat", "jre"))
|
|
||||||
await launchGame(false)
|
|
||||||
defaultWindow.hide()
|
|
||||||
createLauncherWindow()
|
|
||||||
} catch (error) {
|
|
||||||
console.log(error)
|
|
||||||
defaultWindow.hide()
|
|
||||||
createLauncherWindow()
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
launcherWindow.loadFile(path.join(__dirname, "app", "banned.html"))
|
|
||||||
defaultWindow.webContents.executeJavaScript(`
|
|
||||||
setBannedBy("${isLauncherNotBanned.banned_by}")
|
|
||||||
setBannedAt("${isLauncherNotBanned.banned_at}")
|
|
||||||
setBannedBecause("${isLauncherNotBanned.reason}")
|
|
||||||
`)
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
dialog.showErrorBox("Erreur", error.toString())
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
dialog.showErrorBox("Connexion internet", "Le launcher requiert une connexion internet.")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async function checkIfIAmBanned() {
|
async function checkIfIAmBanned() {
|
||||||
if (net.isOnline()) {
|
if (net.isOnline()) {
|
||||||
try {
|
try {
|
||||||
@ -191,31 +129,10 @@ async function checkIfIAmBanned() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function checkCoutdown(uuid) {
|
|
||||||
try {
|
|
||||||
const response = await fetch(`${config.api.base}${config.api.endpoints.countdown}/${uuid}`)
|
|
||||||
const json = await response.json()
|
|
||||||
console.log(json)
|
|
||||||
return json.success
|
|
||||||
} catch (error) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function writeOculusConfigFile(filePath) {
|
|
||||||
const oculusProperties = properties.parse(fs.readFileSync(filePath).toString())
|
|
||||||
if (data.args.boolean) {
|
|
||||||
properties.setProperty(oculusProperties, "shaderPack", "Sildurs_Vibrant_Shaders_v1.50_Medium.zip")
|
|
||||||
} else {
|
|
||||||
properties.setProperty(oculusProperties, "shaderPack", "")
|
|
||||||
}
|
|
||||||
fs.writeFileSync(filePath, properties.stringify(oculusProperties))
|
|
||||||
}
|
|
||||||
|
|
||||||
app.whenReady().then(() => {
|
app.whenReady().then(() => {
|
||||||
createDefaultWindow()
|
createLauncherWindow()
|
||||||
app.on("activate", async () => {
|
app.on("activate", async () => {
|
||||||
if (BrowserWindow.getAllWindows().length === 0) await createDefaultWindow()
|
if (BrowserWindow.getAllWindows().length === 0) await createLauncherWindow()
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -239,9 +156,6 @@ ipcMain.on("call", async (event, data) => {
|
|||||||
launcherWindow.close()
|
launcherWindow.close()
|
||||||
app.quit()
|
app.quit()
|
||||||
break
|
break
|
||||||
case "window::reduce":
|
|
||||||
launcherWindow.minimize()
|
|
||||||
break
|
|
||||||
case "skin::set":
|
case "skin::set":
|
||||||
const file = await dialog.showOpenDialog(launcherWindow, {
|
const file = await dialog.showOpenDialog(launcherWindow, {
|
||||||
filters: [
|
filters: [
|
||||||
@ -267,19 +181,8 @@ ipcMain.on("call", async (event, data) => {
|
|||||||
case "auth::mojang":
|
case "auth::mojang":
|
||||||
if (data.args.trim() != "") {
|
if (data.args.trim() != "") {
|
||||||
auth = Authenticator.getAuth(data.args.username, data.args.password)
|
auth = Authenticator.getAuth(data.args.username, data.args.password)
|
||||||
launcherSettings.set("auth", { token: (await auth).access_token, type: "mojang", clientToken: (await auth).client_token })
|
|
||||||
if (await checkCoutdown((await auth).uuid)) {
|
|
||||||
await launcherWindow.loadFile(path.join(__dirname, "app", "logged.html"))
|
|
||||||
await fetch(`${config.api.base}${config.api.endpoints.telemetry}/${hwid.getHWID()}/${(await auth).uuid}`)
|
await fetch(`${config.api.base}${config.api.endpoints.telemetry}/${hwid.getHWID()}/${(await auth).uuid}`)
|
||||||
} else {
|
await launcherWindow.loadFile(path.join(__dirname, "app", "logged.html"))
|
||||||
await launcherWindow.loadURL("https://nyancraft.catboat.fr")
|
|
||||||
await launcherWindow.webContents.insertCSS("a.download-button { display: none; } #return-button { app-region: no-drag } ")
|
|
||||||
await launcherWindow.webContents.executeJavaScript(`
|
|
||||||
const returnButton = document.querySelector(\"#return-button\")
|
|
||||||
returnButton.innerText = "Fermer le launcher"
|
|
||||||
returnButton.onclick = () => system.call("window::close")
|
|
||||||
`)
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
dialog.showErrorBox("Erreur", "Le mot de passe n'est pas défini. Les comptes crackés ne sont pas supporté par le launcher.")
|
dialog.showErrorBox("Erreur", "Le mot de passe n'est pas défini. Les comptes crackés ne sont pas supporté par le launcher.")
|
||||||
}
|
}
|
||||||
@ -287,23 +190,11 @@ ipcMain.on("call", async (event, data) => {
|
|||||||
case "auth::microsoft":
|
case "auth::microsoft":
|
||||||
const authManager = new msmc.Auth("select_account")
|
const authManager = new msmc.Auth("select_account")
|
||||||
try {
|
try {
|
||||||
const xboxManager = await authManager.launch("electron")
|
const xboxManager = await authManager.launch("raw")
|
||||||
const token = await xboxManager.getMinecraft()
|
const token = await xboxManager.getMinecraft()
|
||||||
auth = token.mclc()
|
auth = token.mclc()
|
||||||
console.log(auth.meta)
|
await fetch(`${config.api.base}${config.api.endpoints.telemetry}/${hwid.getHWID()}/${auth.uuid}`)
|
||||||
launcherSettings.set("auth", { token: auth.meta, type: "msa", clientToken: auth.client_token })
|
await launcherWindow.loadFile(path.join(__dirname, "app", "logged.html"))
|
||||||
if (await checkCoutdown(auth.uuid)) {
|
|
||||||
launcherWindow.loadFile(path.join(__dirname, "app", "logged.html"))
|
|
||||||
fetch(`${config.api.base}${config.api.endpoints.telemetry}/${hwid.getHWID()}/${auth.uuid}`)
|
|
||||||
} else {
|
|
||||||
await launcherWindow.loadURL("https://nyancraft.catboat.fr")
|
|
||||||
await launcherWindow.webContents.insertCSS("a.download-button { display: none; } #return-button { app-region: no-drag } ")
|
|
||||||
await launcherWindow.webContents.executeJavaScript(`
|
|
||||||
const returnButton = document.querySelector(\"#return-button\")
|
|
||||||
returnButton.innerText = "Fermer le launcher"
|
|
||||||
returnButton.onclick = () => system.call("window::close")
|
|
||||||
`)
|
|
||||||
}
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(error)
|
console.error(error)
|
||||||
if (error == "error.gui.closed") {
|
if (error == "error.gui.closed") {
|
||||||
@ -311,11 +202,32 @@ ipcMain.on("call", async (event, data) => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
break
|
break
|
||||||
case "auth::reset":
|
case "auth::refresh":
|
||||||
launcherSettings.set("auth", { token: "", type: "msa", clientToken: "" })
|
const user = data.args.user
|
||||||
break
|
if (user.meta?.type == "msa") {
|
||||||
case "settings::set":
|
try {
|
||||||
launcherSettings.set(data.args.key, data.args.value)
|
const authManager = new msmc.Auth("none")
|
||||||
|
const xboxManager = await authManager.refresh(user.meta.refresh)
|
||||||
|
const minecraft = await xboxManager.getMinecraft()
|
||||||
|
auth = minecraft.mclc()
|
||||||
|
await launcherWindow.loadFile(path.join(__dirname, "app", "logged.html"))
|
||||||
|
await fetch(`${config.api.base}${config.api.endpoints.telemetry}/${hwid.getHWID()}/${auth.uuid}`)
|
||||||
|
} catch (error) {
|
||||||
|
dialog.showErrorBox("Erreur lors de la connexion via token", error)
|
||||||
|
console.error(error)
|
||||||
|
launcherWindow.webContents.send("Response<auth::refresh>")
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
try {
|
||||||
|
auth = Authenticator.refreshAuth(user.access_token, user.client_token)
|
||||||
|
await launcherWindow.loadFile(path.join(__dirname, "app", "logged.html"))
|
||||||
|
await fetch(`${config.api.base}${config.api.endpoints.telemetry}/${hwid.getHWID()}/${(await auth).uuid}`)
|
||||||
|
} catch (error) {
|
||||||
|
dialog.showErrorBox("Erreur lors de la connexion via token", error)
|
||||||
|
console.error(error)
|
||||||
|
launcherWindow.webContents.send("Response<auth::refresh>")
|
||||||
|
}
|
||||||
|
}
|
||||||
break
|
break
|
||||||
case "shell::openExternal":
|
case "shell::openExternal":
|
||||||
shell.openExternal(data.args.url)
|
shell.openExternal(data.args.url)
|
||||||
@ -362,39 +274,17 @@ ipcMain.on("call", async (event, data) => {
|
|||||||
case "app::devtools":
|
case "app::devtools":
|
||||||
launcherWindow.webContents.openDevTools()
|
launcherWindow.webContents.openDevTools()
|
||||||
break
|
break
|
||||||
case "oculus::defaultshaderset":
|
|
||||||
const filePath = path.join(app.getPath("appData"), ".catboat", "config", "oculus.properties")
|
|
||||||
if (fs.existsSync(filePath)) {
|
|
||||||
writeOculusConfigFile(filePath)
|
|
||||||
} else {
|
|
||||||
fs.copyFileSync(path.join(__dirname, "oculus.properties"), filePath)
|
|
||||||
writeOculusConfigFile(filePath)
|
|
||||||
}
|
|
||||||
break
|
|
||||||
case "oculus::getdefaultshaderset":
|
|
||||||
const $filePath = path.join(app.getPath("appData"), ".catboat", "config", "oculus.properties")
|
|
||||||
if (fs.existsSync($filePath)) {
|
|
||||||
const $oculusProperties = properties.parse(fs.readFileSync($filePath).toString())
|
|
||||||
launcherWindow.webContents.send("Response<oculus::getdefaultshaderset>", properties.getProperty($oculusProperties, "shaderPack") == "Sildurs_Vibrant_Shaders_v1.50_Medium.zip" ? true : false) } else {
|
|
||||||
const $oculusProperties = properties.parse(fs.readFileSync($filePath).toString())
|
|
||||||
launcherWindow.webContents.send("Response<oculus::getdefaultshaderset>", properties.getProperty($oculusProperties, "shaderPack") == "Sildurs_Vibrant_Shaders_v1.50_Medium.zip" ? true : false)
|
|
||||||
}
|
|
||||||
break
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
async function launchGame(restartGame) {
|
async function launchGame(restartGame) {
|
||||||
let sendToRenderer = false
|
|
||||||
if (launcherWindow instanceof BrowserWindow) {
|
|
||||||
sendToRenderer = true
|
|
||||||
launcherWindow.webContents.send("Response<game::launch>", { disablePlayButton: false })
|
launcherWindow.webContents.send("Response<game::launch>", { disablePlayButton: false })
|
||||||
}
|
|
||||||
const downloadQueue = []
|
const downloadQueue = []
|
||||||
const remoteFiles = await fileManager.getRemoteFiles()
|
const remoteFiles = await fileManager.getRemoteFiles()
|
||||||
const localFiles = fs.readdirSync(path.join(app.getPath("appData"), ".catboat"), { recursive: true })
|
const localFiles = fs.readdirSync(path.join(app.getPath("appData"), ".catboat"), { recursive: true })
|
||||||
if (launcherWindow instanceof BrowserWindow) {
|
launcherWindow.setProgressBar(10, {
|
||||||
launcherWindow.webContents.send("Response<progress::update>", { type: "landing" })
|
mode: "indeterminate"
|
||||||
}
|
})
|
||||||
for (const remoteFile of remoteFiles) {
|
for (const remoteFile of remoteFiles) {
|
||||||
try {
|
try {
|
||||||
const localFile = localFiles.find(file => file === remoteFile)
|
const localFile = localFiles.find(file => file === remoteFile)
|
||||||
@ -423,34 +313,32 @@ async function launchGame(restartGame) {
|
|||||||
const url = `${config.api.base}${config.api.endpoints.downloadFile}/${new String(item).replace(/\\/g, "/")}`
|
const url = `${config.api.base}${config.api.endpoints.downloadFile}/${new String(item).replace(/\\/g, "/")}`
|
||||||
try {
|
try {
|
||||||
await download(url, path.join(app.getPath("appData"), ".catboat", path.dirname(item)))
|
await download(url, path.join(app.getPath("appData"), ".catboat", path.dirname(item)))
|
||||||
if (launcherWindow instanceof BrowserWindow) {
|
launcherWindow.setProgressBar(((downloadQueue.indexOf(item) + 1) / downloadQueue.length) * 100, {
|
||||||
launcherWindow.webContents.send("Response<izitoast::info>", { title: "Lancement du jeu", message: "Ce processus peut être plus ou moins long selon votre configuration." })
|
mode: "normal"
|
||||||
launcherWindow.webContents.send("Response<progress::update>", { type: "continuous" })
|
})
|
||||||
}
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
if (launcherWindow instanceof BrowserWindow) {
|
launcherWindow.setProgressBar(((downloadQueue.indexOf(item) + 1) / downloadQueue.length) * 100, {
|
||||||
launcherWindow.webContents.send("Response<progress::hide>")
|
mode: "error"
|
||||||
launcherWindow.webContents.send("Response<izitoast::error>", { title: "Erreur", message: new String(error) })
|
})
|
||||||
}
|
|
||||||
dialog.showErrorBox("Erreur lors du téléchargement des fichiers", error.toString())
|
dialog.showErrorBox("Erreur lors du téléchargement des fichiers", error.toString())
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
launcherWindow.setProgressBar(0, {
|
||||||
|
mode: "none"
|
||||||
|
})
|
||||||
|
dialog.showMessageBox(launcherWindow, {
|
||||||
|
title: "Téléchargement des fichiers",
|
||||||
|
message: "Téléchargement fini."
|
||||||
|
})
|
||||||
gamePlayable = true
|
gamePlayable = true
|
||||||
launcher.on("close", () => {
|
launcher.on("close", () => {
|
||||||
launcherWindow.webContents.send("Response<game::launch>", { disablePlayButton: true })
|
launcherSettings.webContents.send("Response<game::launch>", { disablePlayButton: true })
|
||||||
gamePlayable = true
|
gamePlayable = true
|
||||||
})
|
})
|
||||||
launcher.on("debug", (log) => {
|
launcher.on("debug", (log) => {
|
||||||
console.log(log)
|
console.log(log)
|
||||||
})
|
})
|
||||||
launcher.on("data", (log) => {
|
|
||||||
if (sendToRenderer) {
|
|
||||||
launcherWindow.webContents.send("Response<game::launched>")
|
|
||||||
sendToRenderer = false
|
|
||||||
}
|
|
||||||
console.log(log)
|
|
||||||
})
|
|
||||||
launcher.on("data", (log) => {
|
launcher.on("data", (log) => {
|
||||||
console.log(log)
|
console.log(log)
|
||||||
})
|
})
|
||||||
@ -463,7 +351,6 @@ async function launchGame(restartGame) {
|
|||||||
type: "release"
|
type: "release"
|
||||||
},
|
},
|
||||||
forge: path.join(app.getPath("appData"), ".catboat", "forge-1.16.5.jar"),
|
forge: path.join(app.getPath("appData"), ".catboat", "forge-1.16.5.jar"),
|
||||||
javaPath: await java.getPath(path.join(app.getPath("appData"), ".catboat", "jre")),
|
|
||||||
memory: {
|
memory: {
|
||||||
min: 512,
|
min: 512,
|
||||||
max: launcherSettings.get("ram").max
|
max: launcherSettings.get("ram").max
|
||||||
@ -481,7 +368,5 @@ socket.on("force-game-update", async () => {
|
|||||||
})
|
})
|
||||||
launchProcess.kill()
|
launchProcess.kill()
|
||||||
await launchGame(true)
|
await launchGame(true)
|
||||||
} else {
|
|
||||||
await launchGame(false)
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@ -1,95 +0,0 @@
|
|||||||
const { execSync } = require("child_process")
|
|
||||||
const fs = require("fs")
|
|
||||||
const path = require("path")
|
|
||||||
const os = require("os")
|
|
||||||
const download = require("download")
|
|
||||||
const AdmZip = require("adm-zip")
|
|
||||||
|
|
||||||
const JAVA_DOWNLOAD_URL = {
|
|
||||||
win32: "https://download.oracle.com/java/17/archive/jdk-17.0.12_windows-x64_bin.zip",
|
|
||||||
darwin: "https://download.oracle.com/java/17/archive/jdk-17.0.12_macos-x64_bin.tar.gz",
|
|
||||||
linux: "https://download.oracle.com/java/17/archive/jdk-17.0.12_linux-aarch64_bin.tar.gz",
|
|
||||||
}
|
|
||||||
|
|
||||||
function checkJavaVersion(requiredVersion = "17") {
|
|
||||||
try {
|
|
||||||
const javaVersionOutput = execSync("java -version", {
|
|
||||||
encoding: "utf8",
|
|
||||||
stdio: "pipe"
|
|
||||||
})
|
|
||||||
const versionMatch = javaVersionOutput.match(/"(\d+\.\d+)(\.\d+)?_\d+"/)
|
|
||||||
if (versionMatch) {
|
|
||||||
const installedVersion = versionMatch[1]
|
|
||||||
console.log(`Java is installed. Version: ${installedVersion}`)
|
|
||||||
if (parseFloat(installedVersion) >= parseFloat(requiredVersion)) {
|
|
||||||
console.log("Required Java version is already installed.")
|
|
||||||
return true
|
|
||||||
} else {
|
|
||||||
console.log(`Installed Java version (${installedVersion}) is less than required version (${requiredVersion}).`)
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
console.log("Java is installed but version could not be determined.")
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
console.log("Java is not installed.")
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async function downloadAndInstallJava(extractPath = null) {
|
|
||||||
const platform = os.platform()
|
|
||||||
const tempDir = fs.mkdtempSync(path.join(os.tmpdir(), "java-installer-"))
|
|
||||||
|
|
||||||
const downloadUrl = JAVA_DOWNLOAD_URL[platform]
|
|
||||||
if (!downloadUrl) {
|
|
||||||
console.error("Unsupported platform for Java installation.")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
const zipPath = path.join(tempDir, "java-package.zip")
|
|
||||||
await download(downloadUrl, tempDir, {
|
|
||||||
filename: "java-package.zip"
|
|
||||||
})
|
|
||||||
|
|
||||||
const extractionDir = extractPath || tempDir
|
|
||||||
const zip = new AdmZip(zipPath)
|
|
||||||
zip.extractAllTo(extractionDir, true)
|
|
||||||
|
|
||||||
fs.unlinkSync(zipPath)
|
|
||||||
}
|
|
||||||
|
|
||||||
async function main(customExtractPath) {
|
|
||||||
const requiredVersion = "17"
|
|
||||||
const isJavaInstalled = checkJavaVersion(requiredVersion)
|
|
||||||
|
|
||||||
if (!isJavaInstalled) {
|
|
||||||
|
|
||||||
if (!fs.existsSync(path.join(customExtractPath, "jdk-17.0.12", "bin", os.platform() == "win32" ? "java.exe" : "java"))) {
|
|
||||||
await downloadAndInstallJava(customExtractPath || path.join(__dirname, "..", "..", "java"))
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
console.log("No further action is required.")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async function getPath(customExtractPath) {
|
|
||||||
const requiredVersion = "17"
|
|
||||||
const isJavaInstalled = checkJavaVersion(requiredVersion)
|
|
||||||
|
|
||||||
if (!isJavaInstalled) {
|
|
||||||
if (!fs.existsSync(path.join(customExtractPath, "jdk-17.0.12", "bin", os.platform() == "win32" ? "java.exe" : "java"))) {
|
|
||||||
await main(customExtractPath)
|
|
||||||
} else {
|
|
||||||
return path.join(customExtractPath, "jdk-17.0.12", "bin", os.platform() == "win32" ? "java.exe" : "java")
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
console.log("No further action is required.")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports = {
|
|
||||||
main,
|
|
||||||
getPath
|
|
||||||
}
|
|
||||||
@ -5,27 +5,23 @@ let launcherDataPath = path.join(__dirname, ".catboat")
|
|||||||
|
|
||||||
const baseSettings = {
|
const baseSettings = {
|
||||||
ram: {
|
ram: {
|
||||||
max: 2048
|
max: 1024
|
||||||
},
|
|
||||||
auth: {
|
|
||||||
token: "",
|
|
||||||
type: "msa",
|
|
||||||
clientToken: ""
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function initSettings($launcherDataPath) {
|
function initSettings($launcherDataPath) {
|
||||||
launcherDataPath = $launcherDataPath
|
launcherDataPath = $launcherDataPath
|
||||||
if (!fs.existsSync(launcherDataPath)) {
|
const gameDir = path.parse($launcherDataPath).dir
|
||||||
|
if (!fs.existsSync(gameDir)) {
|
||||||
try {
|
try {
|
||||||
fs.mkdirSync(launcherDataPath)
|
fs.mkdirSync(gameDir)
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
throw error
|
throw error
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!fs.existsSync(path.join(launcherDataPath, "launcher_settings.json"))) {
|
if (!fs.existsSync($launcherDataPath)) {
|
||||||
try {
|
try {
|
||||||
fs.writeFileSync(path.join(launcherDataPath, "launcher_settings.json"), JSON.stringify(baseSettings, null, 4))
|
fs.writeFileSync($launcherDataPath, JSON.stringify(baseSettings, null, 4))
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
throw error
|
throw error
|
||||||
}
|
}
|
||||||
@ -41,8 +37,7 @@ function writeSettings(settings) {
|
|||||||
fs.writeFileSync(path.join(launcherDataPath, "launcher_settings.json"), JSON.stringify(settings, null, 4))
|
fs.writeFileSync(path.join(launcherDataPath, "launcher_settings.json"), JSON.stringify(settings, null, 4))
|
||||||
return
|
return
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
clean()
|
throw error
|
||||||
return writeSettings(settings)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -63,8 +58,8 @@ function get(key) {
|
|||||||
|
|
||||||
return value
|
return value
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
clean()
|
console.error("Erreur lors de l'accès aux paramètres :", error.message)
|
||||||
return get(key)
|
throw error
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -86,10 +81,10 @@ function set(key, newValue) {
|
|||||||
|
|
||||||
obj[keys[keys.length - 1]] = newValue
|
obj[keys[keys.length - 1]] = newValue
|
||||||
|
|
||||||
fs.writeFileSync(filePath, JSON.stringify(settings, null, 4))
|
fs.writeFileSync(filePath, JSON.stringify(settings, null, 2))
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
clean()
|
console.error("Erreur lors de la mise à jour des paramètres :", error.message)
|
||||||
return set(ke, value)
|
throw error
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -106,8 +101,7 @@ function readSettings() {
|
|||||||
try {
|
try {
|
||||||
return JSON.parse(fs.readFileSync(path.join(launcherDataPath, "launcher_settings.json")))
|
return JSON.parse(fs.readFileSync(path.join(launcherDataPath, "launcher_settings.json")))
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
clean()
|
throw error
|
||||||
return readSettings()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,27 +0,0 @@
|
|||||||
const os = require("os")
|
|
||||||
|
|
||||||
function arch() {
|
|
||||||
switch (os.arch()) {
|
|
||||||
case "x32":
|
|
||||||
case "ia32":
|
|
||||||
case "x86":
|
|
||||||
case "mips":
|
|
||||||
case "ppc":
|
|
||||||
case "s390":
|
|
||||||
return "x86"
|
|
||||||
case "x64":
|
|
||||||
case "arm64":
|
|
||||||
return "arm64"
|
|
||||||
case "mipsel":
|
|
||||||
case "ppc64":
|
|
||||||
case "riscv64":
|
|
||||||
case "s390x":
|
|
||||||
case "loong64":
|
|
||||||
return "x64"
|
|
||||||
|
|
||||||
default:
|
|
||||||
return "unknown"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports.arch = arch
|
|
||||||
@ -3,22 +3,19 @@ const RPC = require("discord-rpc")
|
|||||||
class DiscordRPC {
|
class DiscordRPC {
|
||||||
constructor() {
|
constructor() {
|
||||||
readonly: this.activity = {
|
readonly: this.activity = {
|
||||||
details: "Officiel | Solva x Alcaz",
|
details: "Actif dans le launcher",
|
||||||
timestamps : { start: Date.now() },
|
|
||||||
assets: {
|
assets: {
|
||||||
large_image: "rpc_catboat_large",
|
large_image: "logo",
|
||||||
large_text: "CatBoat Launcher",
|
large_text: "CatBoat Minecraft Launcher"
|
||||||
small_image : "alflamme_comm_legoshi",
|
|
||||||
small_text: "by TheAlfiTeam",
|
|
||||||
},
|
},
|
||||||
buttons: [
|
buttons: [
|
||||||
{
|
{
|
||||||
"label": "Discord",
|
label: "Discord",
|
||||||
"url": "https://discord.gg/catboat"
|
url: "https://discord.com/invite/catboat"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"label": "Download Launcher",
|
label: "CatBoat",
|
||||||
"url": "https://catboat.thealfigame.fr"
|
url: "https://catboat.fr/"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
instance: true
|
instance: true
|
||||||
@ -33,12 +30,12 @@ class DiscordRPC {
|
|||||||
this.client.request("SET_ACTIVITY", { pid: process.pid, activity: this.activity })
|
this.client.request("SET_ACTIVITY", { pid: process.pid, activity: this.activity })
|
||||||
console.log("The Discord Rich Presence has been set successfully.")
|
console.log("The Discord Rich Presence has been set successfully.")
|
||||||
})
|
})
|
||||||
this.client.login({ clientId: "1259291027148115988" }).catch(e => {
|
this.client.login({ clientId: "1365563093157154868" }).catch(e => {
|
||||||
console.log("Silent client detected: the activity status has been disabled.")
|
|
||||||
console.log(e)
|
console.log(e)
|
||||||
|
console.log("Silent client detected: the activity status has been disabled.")
|
||||||
this.isEnabled = false
|
this.isEnabled = false
|
||||||
}).then(r => this.isEnabled = true)
|
}).then(r => this.isEnabled = true)
|
||||||
.catch(err => console.log(err))
|
.catch(err => console.log)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,8 +0,0 @@
|
|||||||
#This file stores configuration options for Oculus, such as the currently active shaderpack
|
|
||||||
#Sun May 11 07:39:36 CEST 2025
|
|
||||||
colorSpace=SRGB
|
|
||||||
disableUpdateMessage=false
|
|
||||||
enableDebugOptions=false
|
|
||||||
maxShadowRenderDistance=32
|
|
||||||
shaderPack=Sildurs_Vibrant_Shaders_v1.50_Medium.zip
|
|
||||||
enableShaders=true
|
|
||||||
23
package-lock.json
generated
23
package-lock.json
generated
@ -1,21 +1,19 @@
|
|||||||
{
|
{
|
||||||
"name": "catboat-launcher",
|
"name": "catboat-launcher",
|
||||||
"version": "0.0.9-alpha",
|
"version": "0.0.1-alpha",
|
||||||
"lockfileVersion": 3,
|
"lockfileVersion": 3,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "catboat-launcher",
|
"name": "catboat-launcher",
|
||||||
"version": "0.0.9-alpha",
|
"version": "0.0.1-alpha",
|
||||||
"license": "AGPL-3.0-or-later",
|
"license": "AGPL-3.0-or-later",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"discord-rpc": "^4.0.1",
|
"discord-rpc": "^4.0.1",
|
||||||
"download": "^8.0.0",
|
"download": "^8.0.0",
|
||||||
"js-java-properties": "^1.0.3",
|
|
||||||
"minecraft-launcher-core": "^3.18.2",
|
"minecraft-launcher-core": "^3.18.2",
|
||||||
"msmc": "^5.0.5",
|
"msmc": "^5.0.5",
|
||||||
"socket.io-client": "^4.8.1",
|
"socket.io-client": "^4.8.1"
|
||||||
"v8-compile-cache": "^2.4.0"
|
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"electron": "^35.2.1",
|
"electron": "^35.2.1",
|
||||||
@ -4220,15 +4218,6 @@
|
|||||||
"node": "*"
|
"node": "*"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/js-java-properties": {
|
|
||||||
"version": "1.0.3",
|
|
||||||
"resolved": "https://registry.npmjs.org/js-java-properties/-/js-java-properties-1.0.3.tgz",
|
|
||||||
"integrity": "sha512-KFvPPxguCIv4T/Z45tk+eDkD2UiPglaarN8qyrY3RsJDnhz2LMlHp52WFYRYjub5F4SlMKv2u0Z6F/yR1eZ5Jg==",
|
|
||||||
"license": "MIT",
|
|
||||||
"engines": {
|
|
||||||
"node": ">= 14"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/js-yaml": {
|
"node_modules/js-yaml": {
|
||||||
"version": "4.1.0",
|
"version": "4.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz",
|
||||||
@ -6597,12 +6586,6 @@
|
|||||||
"uuid": "dist/bin/uuid"
|
"uuid": "dist/bin/uuid"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/v8-compile-cache": {
|
|
||||||
"version": "2.4.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.4.0.tgz",
|
|
||||||
"integrity": "sha512-ocyWc3bAHBB/guyqJQVI5o4BZkPhznPYUG2ea80Gond/BgNWpap8TOmLSeeQG7bnh2KMISxskdADG59j7zruhw==",
|
|
||||||
"license": "MIT"
|
|
||||||
},
|
|
||||||
"node_modules/verror": {
|
"node_modules/verror": {
|
||||||
"version": "1.10.1",
|
"version": "1.10.1",
|
||||||
"resolved": "https://registry.npmjs.org/verror/-/verror-1.10.1.tgz",
|
"resolved": "https://registry.npmjs.org/verror/-/verror-1.10.1.tgz",
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "catboat-launcher",
|
"name": "catboat-launcher",
|
||||||
"version": "0.1.0-alpha",
|
"version": "0.0.1-alpha",
|
||||||
"description": "a simple minecraft launcher for catboat",
|
"description": "a simple minecraft launcher for catboat",
|
||||||
"main": "main.js",
|
"main": "main.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
@ -22,14 +22,11 @@
|
|||||||
"electron-builder": "^26.0.12",
|
"electron-builder": "^26.0.12",
|
||||||
"electronmon": "^2.0.3"
|
"electronmon": "^2.0.3"
|
||||||
},
|
},
|
||||||
"homepage": "https://nyancraft.catboat.fr",
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"discord-rpc": "^4.0.1",
|
"discord-rpc": "^4.0.1",
|
||||||
"download": "^8.0.0",
|
"download": "^8.0.0",
|
||||||
"js-java-properties": "^1.0.3",
|
|
||||||
"minecraft-launcher-core": "^3.18.2",
|
"minecraft-launcher-core": "^3.18.2",
|
||||||
"msmc": "^5.0.5",
|
"msmc": "^5.0.5",
|
||||||
"socket.io-client": "^4.8.1",
|
"socket.io-client": "^4.8.1"
|
||||||
"v8-compile-cache": "^2.4.0"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user