mirror of
https://git.sanhost.net/sanasol/hytale-f2p.git
synced 2026-02-26 06:41:47 -03:00
trying
This commit is contained in:
@@ -635,20 +635,6 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Installation effects overlay -->
|
|
||||||
<div id="installationEffects" class="installation-effects" style="display: none;">
|
|
||||||
<div class="space-effects">
|
|
||||||
<div class="warp-line"></div>
|
|
||||||
<div class="warp-line"></div>
|
|
||||||
<div class="warp-line"></div>
|
|
||||||
<div class="warp-line"></div>
|
|
||||||
<div class="warp-line"></div>
|
|
||||||
<div class="warp-line"></div>
|
|
||||||
<div class="warp-line"></div>
|
|
||||||
<div class="warp-line"></div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div id="chatUsernameModal" class="chat-username-modal" style="display: none;">
|
<div id="chatUsernameModal" class="chat-username-modal" style="display: none;">
|
||||||
<div class="chat-username-modal-content">
|
<div class="chat-username-modal-content">
|
||||||
<div class="chat-username-modal-header">
|
<div class="chat-username-modal-header">
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
|
|
||||||
let CF_API_KEY = "$2a$10$bqk254NMZOWVTzLVJCcxEOmhcyUujKxA5xk.kQCN9q0KNYFJd5b32";
|
let API_KEY = "$2a$10$bqk254NMZOWVTzLVJCcxEOmhcyUujKxA5xk.kQCN9q0KNYFJd5b32";
|
||||||
const CURSEFORGE_API = 'https://api.curseforge.com/v1';
|
const CURSEFORGE_API = 'https://api.curseforge.com/v1';
|
||||||
const HYTALE_GAME_ID = 70216;
|
const HYTALE_GAME_ID = 70216;
|
||||||
|
|
||||||
@@ -12,7 +12,9 @@ let modsTotalPages = 1;
|
|||||||
|
|
||||||
export async function initModsManager() {
|
export async function initModsManager() {
|
||||||
try {
|
try {
|
||||||
console.log('Loaded API Key:', CF_API_KEY ? 'Yes' : 'No');
|
if (window.electronAPI && window.electronAPI.getEnvVar) {
|
||||||
|
console.log('Loaded API Key:', API_KEY ? 'Yes' : 'No');
|
||||||
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error('Failed to load API Key:', err);
|
console.error('Failed to load API Key:', err);
|
||||||
}
|
}
|
||||||
@@ -194,7 +196,7 @@ async function loadBrowseMods() {
|
|||||||
browseContainer.innerHTML = `<div class="loading-mods"><div class="loading-spinner"></div><span>${window.i18n ? window.i18n.t('mods.loadingMods') : 'Loading mods from CurseForge...'}</span></div>`;
|
browseContainer.innerHTML = `<div class="loading-mods"><div class="loading-spinner"></div><span>${window.i18n ? window.i18n.t('mods.loadingMods') : 'Loading mods from CurseForge...'}</span></div>`;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (!CF_API_KEY || CF_API_KEY.length < 10) {
|
if (!API_KEY || API_KEY.length < 10) {
|
||||||
browseContainer.innerHTML = `
|
browseContainer.innerHTML = `
|
||||||
<div class=\"empty-browse-mods\">
|
<div class=\"empty-browse-mods\">
|
||||||
<i class=\"fas fa-key\"></i>
|
<i class=\"fas fa-key\"></i>
|
||||||
@@ -221,7 +223,7 @@ async function loadBrowseMods() {
|
|||||||
|
|
||||||
const response = await fetch(url, {
|
const response = await fetch(url, {
|
||||||
headers: {
|
headers: {
|
||||||
'x-api-key': CF_API_KEY,
|
'x-api-key': API_KEY,
|
||||||
'Accept': 'application/json'
|
'Accept': 'application/json'
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -207,11 +207,6 @@ function setupSettingsElements() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (closeLauncherCheck) {
|
|
||||||
closeLauncherCheck.addEventListener('change', saveCloseLauncher);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// UUID event listeners
|
// UUID event listeners
|
||||||
if (copyUuidBtn) {
|
if (copyUuidBtn) {
|
||||||
copyUuidBtn.addEventListener('click', copyCurrentUuid);
|
copyUuidBtn.addEventListener('click', copyCurrentUuid);
|
||||||
@@ -397,31 +392,6 @@ async function loadCloseLauncher() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
async function saveCloseLauncher() {
|
|
||||||
try {
|
|
||||||
if (window.electronAPI && window.electronAPI.saveCloseLauncher && closeLauncherCheck) {
|
|
||||||
const enabled = closeLauncherCheck.checked;
|
|
||||||
await window.electronAPI.saveCloseLauncher(enabled);
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
console.error('Error saving close launcher setting:', error);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async function loadCloseLauncher() {
|
|
||||||
try {
|
|
||||||
if (window.electronAPI && window.electronAPI.loadCloseLauncher) {
|
|
||||||
const enabled = await window.electronAPI.loadCloseLauncher();
|
|
||||||
if (closeLauncherCheck) {
|
|
||||||
closeLauncherCheck.checked = enabled;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
console.error('Error loading close launcher setting:', error);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
async function savePlayerName() {
|
async function savePlayerName() {
|
||||||
try {
|
try {
|
||||||
if (!window.electronAPI || !settingsPlayerName) return;
|
if (!window.electronAPI || !settingsPlayerName) return;
|
||||||
|
|||||||
@@ -638,9 +638,6 @@ function setupUI() {
|
|||||||
// Setup retry button
|
// Setup retry button
|
||||||
setupRetryButton();
|
setupRetryButton();
|
||||||
|
|
||||||
// Setup draggable progress bar
|
|
||||||
setupProgressDrag();
|
|
||||||
|
|
||||||
lockPlayButton(true);
|
lockPlayButton(true);
|
||||||
|
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
@@ -741,6 +738,7 @@ window.LauncherUI = {
|
|||||||
|
|
||||||
// Make installation effects globally available
|
// Make installation effects globally available
|
||||||
|
|
||||||
|
|
||||||
// Draggable progress bar functionality
|
// Draggable progress bar functionality
|
||||||
function setupProgressDrag() {
|
function setupProgressDrag() {
|
||||||
if (!progressOverlay) return;
|
if (!progressOverlay) return;
|
||||||
|
|||||||
818
GUI/style.css
818
GUI/style.css
@@ -1770,252 +1770,252 @@ body {
|
|||||||
animation: shimmer 2s infinite;
|
animation: shimmer 2s infinite;
|
||||||
}
|
}
|
||||||
|
|
||||||
@keyframes shimmer {
|
@keyframes shimmer {
|
||||||
0% {
|
0% {
|
||||||
left: -100%;
|
left: -100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
100% {
|
100% {
|
||||||
left: 100%;
|
left: 100%;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Progress Error and Retry Styles */
|
/* Progress Error and Retry Styles */
|
||||||
.progress-error-container {
|
.progress-error-container {
|
||||||
margin-top: 0.75rem;
|
margin-top: 0.75rem;
|
||||||
padding-top: 0.75rem;
|
padding-top: 0.75rem;
|
||||||
border-top: 1px solid rgba(239, 68, 68, 0.3);
|
border-top: 1px solid rgba(239, 68, 68, 0.3);
|
||||||
animation: errorSlideIn 0.3s ease-out;
|
animation: errorSlideIn 0.3s ease-out;
|
||||||
}
|
}
|
||||||
|
|
||||||
@keyframes errorSlideIn {
|
@keyframes errorSlideIn {
|
||||||
from {
|
from {
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
transform: translateY(-10px);
|
transform: translateY(-10px);
|
||||||
}
|
}
|
||||||
to {
|
to {
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
transform: translateY(0);
|
transform: translateY(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.progress-error-message {
|
.progress-error-message {
|
||||||
color: #f87171;
|
color: #f87171;
|
||||||
font-family: 'JetBrains Mono', monospace;
|
font-family: 'JetBrains Mono', monospace;
|
||||||
font-size: 0.75rem;
|
font-size: 0.75rem;
|
||||||
margin-bottom: 0.5rem;
|
margin-bottom: 0.5rem;
|
||||||
text-shadow: 0 0 8px rgba(248, 113, 113, 0.4);
|
text-shadow: 0 0 8px rgba(248, 113, 113, 0.4);
|
||||||
line-height: 1.4;
|
line-height: 1.4;
|
||||||
}
|
}
|
||||||
|
|
||||||
.progress-retry-section {
|
.progress-retry-section {
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
gap: 0.75rem;
|
gap: 0.75rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.progress-retry-buttons {
|
.progress-retry-buttons {
|
||||||
display: flex;
|
display: flex;
|
||||||
gap: 0.5rem;
|
gap: 0.5rem;
|
||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
}
|
}
|
||||||
|
|
||||||
.progress-retry-info {
|
.progress-retry-info {
|
||||||
color: #fbbf24;
|
color: #fbbf24;
|
||||||
font-family: 'JetBrains Mono', monospace;
|
font-family: 'JetBrains Mono', monospace;
|
||||||
font-size: 0.7rem;
|
font-size: 0.7rem;
|
||||||
flex: 1;
|
flex: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
.progress-retry-btn {
|
.progress-retry-btn {
|
||||||
background: linear-gradient(135deg, #dc2626, #ef4444);
|
background: linear-gradient(135deg, #dc2626, #ef4444);
|
||||||
color: white;
|
color: white;
|
||||||
border: none;
|
border: none;
|
||||||
padding: 0.5rem 1rem;
|
padding: 0.5rem 1rem;
|
||||||
border-radius: 6px;
|
border-radius: 6px;
|
||||||
font-family: 'JetBrains Mono', monospace;
|
font-family: 'JetBrains Mono', monospace;
|
||||||
font-size: 0.75rem;
|
font-size: 0.75rem;
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
transition: all 0.2s ease;
|
transition: all 0.2s ease;
|
||||||
box-shadow: 0 2px 8px rgba(220, 38, 38, 0.3);
|
box-shadow: 0 2px 8px rgba(220, 38, 38, 0.3);
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
min-width: 120px;
|
min-width: 120px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.progress-retry-btn:hover {
|
.progress-retry-btn:hover {
|
||||||
background: linear-gradient(135deg, #b91c1c, #dc2626);
|
background: linear-gradient(135deg, #b91c1c, #dc2626);
|
||||||
transform: translateY(-1px);
|
transform: translateY(-1px);
|
||||||
box-shadow: 0 4px 12px rgba(220, 38, 38, 0.4);
|
box-shadow: 0 4px 12px rgba(220, 38, 38, 0.4);
|
||||||
}
|
}
|
||||||
|
|
||||||
.progress-retry-btn:active {
|
.progress-retry-btn:active {
|
||||||
transform: translateY(0);
|
transform: translateY(0);
|
||||||
box-shadow: 0 2px 6px rgba(220, 38, 38, 0.3);
|
box-shadow: 0 2px 6px rgba(220, 38, 38, 0.3);
|
||||||
}
|
}
|
||||||
|
|
||||||
.progress-retry-btn:disabled {
|
.progress-retry-btn:disabled {
|
||||||
background: linear-gradient(135deg, #4b5563, #6b7280);
|
background: linear-gradient(135deg, #4b5563, #6b7280);
|
||||||
cursor: not-allowed;
|
cursor: not-allowed;
|
||||||
transform: none;
|
transform: none;
|
||||||
box-shadow: none;
|
box-shadow: none;
|
||||||
opacity: 0.6;
|
opacity: 0.6;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Progress overlay error state */
|
/* Progress overlay error state */
|
||||||
.progress-overlay.error-state {
|
.progress-overlay.error-state {
|
||||||
border-color: rgba(239, 68, 68, 0.5);
|
border-color: rgba(239, 68, 68, 0.5);
|
||||||
box-shadow:
|
box-shadow:
|
||||||
0 4px 16px rgba(0, 0, 0, 0.5),
|
0 4px 16px rgba(0, 0, 0, 0.5),
|
||||||
0 0 30px rgba(239, 68, 68, 0.2),
|
0 0 30px rgba(239, 68, 68, 0.2),
|
||||||
inset 0 1px 0 rgba(255, 255, 255, 0.05);
|
inset 0 1px 0 rgba(255, 255, 255, 0.05);
|
||||||
}
|
}
|
||||||
|
|
||||||
.progress-overlay.error-state #progressBarFill {
|
.progress-overlay.error-state #progressBarFill {
|
||||||
background: linear-gradient(90deg, #dc2626, #ef4444);
|
background: linear-gradient(90deg, #dc2626, #ef4444);
|
||||||
animation: errorPulse 1.5s ease-in-out infinite;
|
animation: errorPulse 1.5s ease-in-out infinite;
|
||||||
}
|
}
|
||||||
|
|
||||||
@keyframes errorPulse {
|
@keyframes errorPulse {
|
||||||
0%, 100% {
|
0%, 100% {
|
||||||
opacity: 0.8;
|
opacity: 0.8;
|
||||||
}
|
}
|
||||||
50% {
|
50% {
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Error type specific styling */
|
/* Error type specific styling */
|
||||||
.progress-error-container.error-network {
|
.progress-error-container.error-network {
|
||||||
border-top-color: rgba(59, 130, 246, 0.5);
|
border-top-color: rgba(59, 130, 246, 0.5);
|
||||||
}
|
}
|
||||||
|
|
||||||
.progress-error-container.error-network .progress-error-message {
|
.progress-error-container.error-network .progress-error-message {
|
||||||
color: #60a5fa;
|
color: #60a5fa;
|
||||||
text-shadow: 0 0 8px rgba(96, 165, 250, 0.4);
|
text-shadow: 0 0 8px rgba(96, 165, 250, 0.4);
|
||||||
}
|
}
|
||||||
|
|
||||||
.progress-error-container.error-stall {
|
.progress-error-container.error-stall {
|
||||||
border-top-color: rgba(245, 158, 11, 0.5);
|
border-top-color: rgba(245, 158, 11, 0.5);
|
||||||
}
|
}
|
||||||
|
|
||||||
.progress-error-container.error-stall .progress-error-message {
|
.progress-error-container.error-stall .progress-error-message {
|
||||||
color: #fbbf24;
|
color: #fbbf24;
|
||||||
text-shadow: 0 0 8px rgba(251, 191, 36, 0.4);
|
text-shadow: 0 0 8px rgba(251, 191, 36, 0.4);
|
||||||
}
|
}
|
||||||
|
|
||||||
.progress-error-container.error-file {
|
.progress-error-container.error-file {
|
||||||
border-top-color: rgba(239, 68, 68, 0.5);
|
border-top-color: rgba(239, 68, 68, 0.5);
|
||||||
}
|
}
|
||||||
|
|
||||||
.progress-error-container.error-file .progress-error-message {
|
.progress-error-container.error-file .progress-error-message {
|
||||||
color: #f87171;
|
color: #f87171;
|
||||||
text-shadow: 0 0 8px rgba(248, 113, 113, 0.4);
|
text-shadow: 0 0 8px rgba(248, 113, 113, 0.4);
|
||||||
}
|
}
|
||||||
|
|
||||||
.progress-error-container.error-permission {
|
.progress-error-container.error-permission {
|
||||||
border-top-color: rgba(168, 85, 247, 0.5);
|
border-top-color: rgba(168, 85, 247, 0.5);
|
||||||
}
|
}
|
||||||
|
|
||||||
.progress-error-container.error-permission .progress-error-message {
|
.progress-error-container.error-permission .progress-error-message {
|
||||||
color: #a855f7;
|
color: #a855f7;
|
||||||
text-shadow: 0 0 8px rgba(168, 85, 247, 0.4);
|
text-shadow: 0 0 8px rgba(168, 85, 247, 0.4);
|
||||||
}
|
}
|
||||||
|
|
||||||
.progress-error-container.error-server {
|
.progress-error-container.error-server {
|
||||||
border-top-color: rgba(236, 72, 153, 0.5);
|
border-top-color: rgba(236, 72, 153, 0.5);
|
||||||
}
|
}
|
||||||
|
|
||||||
.progress-error-container.error-server .progress-error-message {
|
.progress-error-container.error-server .progress-error-message {
|
||||||
color: #ec4899;
|
color: #ec4899;
|
||||||
text-shadow: 0 0 8px rgba(236, 72, 153, 0.4);
|
text-shadow: 0 0 8px rgba(236, 72, 153, 0.4);
|
||||||
}
|
}
|
||||||
|
|
||||||
.progress-error-container.error-corruption {
|
.progress-error-container.error-corruption {
|
||||||
border-top-color: rgba(220, 38, 38, 0.8);
|
border-top-color: rgba(220, 38, 38, 0.8);
|
||||||
}
|
}
|
||||||
|
|
||||||
.progress-error-container.error-corruption .progress-error-message {
|
.progress-error-container.error-corruption .progress-error-message {
|
||||||
color: #dc2626;
|
color: #dc2626;
|
||||||
text-shadow: 0 0 8px rgba(220, 38, 38, 0.6);
|
text-shadow: 0 0 8px rgba(220, 38, 38, 0.6);
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
}
|
}
|
||||||
|
|
||||||
.progress-error-container.error-butler {
|
.progress-error-container.error-butler {
|
||||||
border-top-color: rgba(245, 158, 11, 0.5);
|
border-top-color: rgba(245, 158, 11, 0.5);
|
||||||
}
|
}
|
||||||
|
|
||||||
.progress-error-container.error-butler .progress-error-message {
|
.progress-error-container.error-butler .progress-error-message {
|
||||||
color: #f59e0b;
|
color: #f59e0b;
|
||||||
text-shadow: 0 0 8px rgba(245, 158, 11, 0.4);
|
text-shadow: 0 0 8px rgba(245, 158, 11, 0.4);
|
||||||
}
|
}
|
||||||
|
|
||||||
.progress-error-container.error-space {
|
.progress-error-container.error-space {
|
||||||
border-top-color: rgba(168, 85, 247, 0.5);
|
border-top-color: rgba(168, 85, 247, 0.5);
|
||||||
}
|
}
|
||||||
|
|
||||||
.progress-error-container.error-space .progress-error-message {
|
.progress-error-container.error-space .progress-error-message {
|
||||||
color: #a855f7;
|
color: #a855f7;
|
||||||
text-shadow: 0 0 8px rgba(168, 85, 247, 0.4);
|
text-shadow: 0 0 8px rgba(168, 85, 247, 0.4);
|
||||||
}
|
}
|
||||||
|
|
||||||
.progress-error-container.error-conflict {
|
.progress-error-container.error-conflict {
|
||||||
border-top-color: rgba(6, 182, 212, 0.5);
|
border-top-color: rgba(6, 182, 212, 0.5);
|
||||||
}
|
}
|
||||||
|
|
||||||
.progress-error-container.error-conflict .progress-error-message {
|
.progress-error-container.error-conflict .progress-error-message {
|
||||||
color: #06b6d4;
|
color: #06b6d4;
|
||||||
text-shadow: 0 0 8px rgba(6, 182, 212, 0.4);
|
text-shadow: 0 0 8px rgba(6, 182, 212, 0.4);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Connection quality indicators */
|
/* Connection quality indicators */
|
||||||
.progress-details {
|
.progress-details {
|
||||||
transition: all 0.3s ease;
|
transition: all 0.3s ease;
|
||||||
}
|
}
|
||||||
|
|
||||||
.progress-details #progressSize {
|
.progress-details #progressSize {
|
||||||
transition: color 0.5s ease;
|
transition: color 0.5s ease;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Enhanced retry button states */
|
/* Enhanced retry button states */
|
||||||
.progress-retry-btn.retrying {
|
.progress-retry-btn.retrying {
|
||||||
background: linear-gradient(135deg, #059669, #10b981);
|
background: linear-gradient(135deg, #059669, #10b981);
|
||||||
animation: retryingPulse 1s ease-in-out infinite;
|
animation: retryingPulse 1s ease-in-out infinite;
|
||||||
}
|
}
|
||||||
|
|
||||||
@keyframes retryingPulse {
|
@keyframes retryingPulse {
|
||||||
0%, 100% {
|
0%, 100% {
|
||||||
transform: scale(1);
|
transform: scale(1);
|
||||||
box-shadow: 0 2px 8px rgba(5, 150, 105, 0.3);
|
box-shadow: 0 2px 8px rgba(5, 150, 105, 0.3);
|
||||||
}
|
}
|
||||||
50% {
|
50% {
|
||||||
transform: scale(1.05);
|
transform: scale(1.05);
|
||||||
box-shadow: 0 4px 12px rgba(5, 150, 105, 0.4);
|
box-shadow: 0 4px 12px rgba(5, 150, 105, 0.4);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Network status indicator (optional future enhancement) */
|
/* Network status indicator (optional future enhancement) */
|
||||||
.network-status {
|
.network-status {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 5px;
|
top: 5px;
|
||||||
right: 5px;
|
right: 5px;
|
||||||
width: 8px;
|
width: 8px;
|
||||||
height: 8px;
|
height: 8px;
|
||||||
border-radius: 50%;
|
border-radius: 50%;
|
||||||
background: #10b981;
|
background: #10b981;
|
||||||
box-shadow: 0 0 6px rgba(16, 185, 129, 0.6);
|
box-shadow: 0 0 6px rgba(16, 185, 129, 0.6);
|
||||||
}
|
}
|
||||||
|
|
||||||
.network-status.poor {
|
.network-status.poor {
|
||||||
background: #f87171;
|
background: #f87171;
|
||||||
box-shadow: 0 0 6px rgba(248, 113, 113, 0.6);
|
box-shadow: 0 0 6px rgba(248, 113, 113, 0.6);
|
||||||
}
|
}
|
||||||
|
|
||||||
.network-status.fair {
|
.network-status.fair {
|
||||||
background: #fbbf24;
|
background: #fbbf24;
|
||||||
box-shadow: 0 0 6px rgba(251, 191, 36, 0.6);
|
box-shadow: 0 0 6px rgba(251, 191, 36, 0.6);
|
||||||
}
|
}
|
||||||
|
|
||||||
.progress-bar-fill {
|
.progress-bar-fill {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
@@ -5990,167 +5990,167 @@ select.settings-input option {
|
|||||||
to {
|
to {
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* Launcher Update Modal Styles */
|
/* Launcher Update Modal Styles */
|
||||||
.update-modal-overlay {
|
.update-modal-overlay {
|
||||||
position: fixed;
|
position: fixed;
|
||||||
top: 0;
|
top: 0;
|
||||||
left: 0;
|
left: 0;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
background: rgba(0, 0, 0, 0.85);
|
background: rgba(0, 0, 0, 0.85);
|
||||||
backdrop-filter: blur(10px);
|
backdrop-filter: blur(10px);
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
z-index: 100000;
|
z-index: 100000;
|
||||||
animation: fadeIn 0.3s ease;
|
animation: fadeIn 0.3s ease;
|
||||||
}
|
}
|
||||||
|
|
||||||
.update-modal {
|
.update-modal {
|
||||||
background: linear-gradient(135deg, #1a1a2e 0%, #16213e 100%);
|
background: linear-gradient(135deg, #1a1a2e 0%, #16213e 100%);
|
||||||
border: 2px solid rgba(147, 51, 234, 0.3);
|
border: 2px solid rgba(147, 51, 234, 0.3);
|
||||||
border-radius: 16px;
|
border-radius: 16px;
|
||||||
padding: 2rem;
|
padding: 2rem;
|
||||||
max-width: 500px;
|
max-width: 500px;
|
||||||
width: 90%;
|
width: 90%;
|
||||||
box-shadow: 0 20px 60px rgba(147, 51, 234, 0.3);
|
box-shadow: 0 20px 60px rgba(147, 51, 234, 0.3);
|
||||||
animation: slideUp 0.3s ease;
|
animation: slideUp 0.3s ease;
|
||||||
}
|
}
|
||||||
|
|
||||||
@keyframes slideUp {
|
@keyframes slideUp {
|
||||||
from {
|
from {
|
||||||
transform: translateY(30px);
|
transform: translateY(30px);
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
}
|
}
|
||||||
to {
|
to {
|
||||||
transform: translateY(0);
|
transform: translateY(0);
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.update-header {
|
.update-header {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
gap: 1rem;
|
gap: 1rem;
|
||||||
margin-bottom: 1.5rem;
|
margin-bottom: 1.5rem;
|
||||||
color: #9333ea;
|
color: #9333ea;
|
||||||
}
|
}
|
||||||
|
|
||||||
.update-header i {
|
.update-header i {
|
||||||
font-size: 2rem;
|
font-size: 2rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.update-header h2 {
|
.update-header h2 {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
font-size: 1.5rem;
|
font-size: 1.5rem;
|
||||||
color: #fff;
|
color: #fff;
|
||||||
}
|
}
|
||||||
|
|
||||||
.update-content {
|
.update-content {
|
||||||
color: #e0e0e0;
|
color: #e0e0e0;
|
||||||
margin-bottom: 1.5rem;
|
margin-bottom: 1.5rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.update-version {
|
.update-version {
|
||||||
font-size: 1.2rem;
|
font-size: 1.2rem;
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
color: #9333ea;
|
color: #9333ea;
|
||||||
margin-bottom: 0.5rem;
|
margin-bottom: 0.5rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.current-version {
|
.current-version {
|
||||||
color: #888;
|
color: #888;
|
||||||
font-size: 0.9rem;
|
font-size: 0.9rem;
|
||||||
margin-bottom: 1rem;
|
margin-bottom: 1rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.release-notes {
|
.release-notes {
|
||||||
background: rgba(0, 0, 0, 0.3);
|
background: rgba(0, 0, 0, 0.3);
|
||||||
border-left: 3px solid #9333ea;
|
border-left: 3px solid #9333ea;
|
||||||
padding: 1rem;
|
padding: 1rem;
|
||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
max-height: 200px;
|
max-height: 200px;
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
font-size: 0.9rem;
|
font-size: 0.9rem;
|
||||||
line-height: 1.6;
|
line-height: 1.6;
|
||||||
}
|
}
|
||||||
|
|
||||||
.update-progress {
|
.update-progress {
|
||||||
margin-bottom: 1.5rem;
|
margin-bottom: 1.5rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.progress-bar-container {
|
.progress-bar-container {
|
||||||
background: rgba(0, 0, 0, 0.3);
|
background: rgba(0, 0, 0, 0.3);
|
||||||
border-radius: 10px;
|
border-radius: 10px;
|
||||||
height: 20px;
|
height: 20px;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
margin-bottom: 0.5rem;
|
margin-bottom: 0.5rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.progress-bar {
|
.progress-bar {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
background: linear-gradient(90deg, #9333ea 0%, #7c3aed 100%);
|
background: linear-gradient(90deg, #9333ea 0%, #7c3aed 100%);
|
||||||
width: 0%;
|
width: 0%;
|
||||||
transition: width 0.3s ease;
|
transition: width 0.3s ease;
|
||||||
border-radius: 10px;
|
border-radius: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.progress-text {
|
.progress-text {
|
||||||
color: #aaa;
|
color: #aaa;
|
||||||
font-size: 0.9rem;
|
font-size: 0.9rem;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.update-note {
|
.update-note {
|
||||||
background: rgba(147, 51, 234, 0.1);
|
background: rgba(147, 51, 234, 0.1);
|
||||||
border: 1px solid rgba(147, 51, 234, 0.3);
|
border: 1px solid rgba(147, 51, 234, 0.3);
|
||||||
padding: 0.75rem;
|
padding: 0.75rem;
|
||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
font-size: 0.9rem;
|
font-size: 0.9rem;
|
||||||
margin-top: 1rem;
|
margin-top: 1rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.update-actions {
|
.update-actions {
|
||||||
display: flex;
|
display: flex;
|
||||||
gap: 1rem;
|
gap: 1rem;
|
||||||
justify-content: flex-end;
|
justify-content: flex-end;
|
||||||
}
|
}
|
||||||
|
|
||||||
.update-actions button {
|
.update-actions button {
|
||||||
padding: 0.75rem 1.5rem;
|
padding: 0.75rem 1.5rem;
|
||||||
border: none;
|
border: none;
|
||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
transition: all 0.2s;
|
transition: all 0.2s;
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
gap: 0.5rem;
|
gap: 0.5rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.update-actions .btn-primary {
|
.update-actions .btn-primary {
|
||||||
background: linear-gradient(135deg, #9333ea 0%, #7c3aed 100%);
|
background: linear-gradient(135deg, #9333ea 0%, #7c3aed 100%);
|
||||||
color: white;
|
color: white;
|
||||||
}
|
}
|
||||||
|
|
||||||
.update-actions .btn-primary:hover:not(:disabled) {
|
.update-actions .btn-primary:hover:not(:disabled) {
|
||||||
transform: translateY(-2px);
|
transform: translateY(-2px);
|
||||||
box-shadow: 0 5px 15px rgba(147, 51, 234, 0.4);
|
box-shadow: 0 5px 15px rgba(147, 51, 234, 0.4);
|
||||||
}
|
}
|
||||||
|
|
||||||
.update-actions .btn-secondary {
|
.update-actions .btn-secondary {
|
||||||
background: rgba(255, 255, 255, 0.1);
|
background: rgba(255, 255, 255, 0.1);
|
||||||
color: #e0e0e0;
|
color: #e0e0e0;
|
||||||
border: 1px solid rgba(255, 255, 255, 0.2);
|
border: 1px solid rgba(255, 255, 255, 0.2);
|
||||||
}
|
}
|
||||||
|
|
||||||
.update-actions .btn-secondary:hover:not(:disabled) {
|
.update-actions .btn-secondary:hover:not(:disabled) {
|
||||||
background: rgba(255, 255, 255, 0.15);
|
background: rgba(255, 255, 255, 0.15);
|
||||||
}
|
}
|
||||||
|
|
||||||
.update-actions button:disabled {
|
.update-actions button:disabled {
|
||||||
opacity: 0.5;
|
opacity: 0.5;
|
||||||
cursor: not-allowed;
|
cursor: not-allowed;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,12 +15,6 @@ class AppUpdater {
|
|||||||
}
|
}
|
||||||
|
|
||||||
setupAutoUpdater() {
|
setupAutoUpdater() {
|
||||||
// Enable dev mode for testing (reads dev-app-update.yml)
|
|
||||||
// Only enable in development, not in production builds
|
|
||||||
if (process.env.NODE_ENV === 'development' || !app.isPackaged) {
|
|
||||||
autoUpdater.forceDevUpdateConfig = true;
|
|
||||||
console.log('Dev update mode enabled - using dev-app-update.yml');
|
|
||||||
}
|
|
||||||
|
|
||||||
// Configure logger for electron-updater
|
// Configure logger for electron-updater
|
||||||
// Create a compatible logger interface
|
// Create a compatible logger interface
|
||||||
|
|||||||
@@ -406,5 +406,6 @@ module.exports = {
|
|||||||
getJavaDetection,
|
getJavaDetection,
|
||||||
downloadJRE,
|
downloadJRE,
|
||||||
extractJRE,
|
extractJRE,
|
||||||
|
retryJREDownload,
|
||||||
JAVA_EXECUTABLE
|
JAVA_EXECUTABLE
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ const { getModsPath, getProfilesDir } = require('../core/paths');
|
|||||||
const { saveModsToConfig, loadModsFromConfig } = require('../core/config');
|
const { saveModsToConfig, loadModsFromConfig } = require('../core/config');
|
||||||
const profileManager = require('./profileManager');
|
const profileManager = require('./profileManager');
|
||||||
|
|
||||||
const CF_API_KEY = "$2a$10$bqk254NMZOWVTzLVJCcxEOmhcyUujKxA5xk.kQCN9q0KNYFJd5b32";
|
const API_KEY = "$2a$10$bqk254NMZOWVTzLVJCcxEOmhcyUujKxA5xk.kQCN9q0KNYFJd5b32";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the physical mods path for a specific profile.
|
* Get the physical mods path for a specific profile.
|
||||||
@@ -120,7 +120,7 @@ async function downloadMod(modInfo) {
|
|||||||
if (!downloadUrl && modInfo.fileId && modInfo.modId) {
|
if (!downloadUrl && modInfo.fileId && modInfo.modId) {
|
||||||
const response = await axios.get(`https://api.curseforge.com/v1/mods/${modInfo.modId || modInfo.curseForgeId}/files/${modInfo.fileId || modInfo.curseForgeFileId}`, {
|
const response = await axios.get(`https://api.curseforge.com/v1/mods/${modInfo.modId || modInfo.curseForgeId}/files/${modInfo.fileId || modInfo.curseForgeFileId}`, {
|
||||||
headers: {
|
headers: {
|
||||||
'x-api-key': modInfo.apiKey || CF_API_KEY,
|
'x-api-key': modInfo.apiKey || API_KEY,
|
||||||
'Accept': 'application/json'
|
'Accept': 'application/json'
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -393,7 +393,7 @@ async function syncModsForCurrentProfile() {
|
|||||||
...mod,
|
...mod,
|
||||||
modId: mod.curseForgeId,
|
modId: mod.curseForgeId,
|
||||||
fileId: mod.curseForgeFileId || mod.fileId,
|
fileId: mod.curseForgeFileId || mod.fileId,
|
||||||
apiKey: CF_API_KEY
|
apiKey: API_KEY
|
||||||
});
|
});
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error(`[ModManager] Auto-repair failed for "${mod.name}": ${err.message}`);
|
console.error(`[ModManager] Auto-repair failed for "${mod.name}": ${err.message}`);
|
||||||
|
|||||||
@@ -103,40 +103,36 @@ async function downloadFile(url, dest, progressCallback, maxRetries = 5) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const headers = {
|
const headers = {
|
||||||
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36',
|
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36',
|
||||||
'Accept': '*/*',
|
'Accept': '*/*'
|
||||||
'Accept-Language': 'en-US,en;q=0.9',
|
|
||||||
'Referer': 'https://launcher.hytale.com/',
|
|
||||||
'Connection': 'keep-alive'
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Add Range header for resume capability
|
// Add Range header ONLY if resuming (startByte > 0)
|
||||||
if (startByte > 0) {
|
if (startByte > 0) {
|
||||||
headers['Range'] = `bytes=${startByte}-`;
|
headers['Range'] = `bytes=${startByte}-`;
|
||||||
|
console.log(`Adding Range header: bytes=${startByte}-`);
|
||||||
|
} else {
|
||||||
|
console.log('Fresh download, no Range header');
|
||||||
}
|
}
|
||||||
|
|
||||||
const response = await axios({
|
const response = await axios({
|
||||||
method: 'GET',
|
method: 'GET',
|
||||||
url: url,
|
url: url,
|
||||||
responseType: 'stream',
|
responseType: 'stream',
|
||||||
timeout: 60000, // 60 secondes timeout
|
timeout: 60000,
|
||||||
signal: controller.signal,
|
signal: controller.signal,
|
||||||
headers: headers,
|
headers: headers,
|
||||||
// Configuration Axios pour la robustesse réseau
|
|
||||||
validateStatus: function (status) {
|
validateStatus: function (status) {
|
||||||
// Accept both 200 (full download) and 206 (partial content for resume)
|
|
||||||
return (status >= 200 && status < 300) || status === 206;
|
return (status >= 200 && status < 300) || status === 206;
|
||||||
},
|
},
|
||||||
// Retry configuration
|
|
||||||
maxRedirects: 5,
|
maxRedirects: 5,
|
||||||
// Network resilience
|
family: 4
|
||||||
family: 4 // Force IPv4
|
|
||||||
});
|
});
|
||||||
|
|
||||||
const contentLength = response.headers['content-length'];
|
const contentLength = response.headers['content-length'];
|
||||||
const totalSize = contentLength ? parseInt(contentLength, 10) + startByte : 0; // Adjust for resume
|
const totalSize = contentLength ? parseInt(contentLength, 10) + startByte : 0;
|
||||||
let downloaded = startByte; // Start with existing bytes
|
let downloaded = startByte;
|
||||||
lastProgressTime = Date.now(); // Update time after response received
|
lastProgressTime = Date.now();
|
||||||
const startTime = Date.now();
|
const startTime = Date.now();
|
||||||
|
|
||||||
// Check network status before attempting download
|
// Check network status before attempting download
|
||||||
@@ -344,7 +340,6 @@ async function downloadFile(url, dest, progressCallback, maxRetries = 5) {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
// Si on arrive ici, le téléchargement a réussi
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
@@ -375,6 +370,9 @@ async function downloadFile(url, dest, progressCallback, maxRetries = 5) {
|
|||||||
// Enhanced file cleanup with validation
|
// Enhanced file cleanup with validation
|
||||||
if (fs.existsSync(dest)) {
|
if (fs.existsSync(dest)) {
|
||||||
try {
|
try {
|
||||||
|
// HTTP 416 = Range Not Satisfiable, delete corrupted partial file
|
||||||
|
const isRangeError = error.message && error.message.includes('416');
|
||||||
|
|
||||||
// Check if file is corrupted (small or invalid) or if error is non-resumable
|
// Check if file is corrupted (small or invalid) or if error is non-resumable
|
||||||
const partialStats = fs.statSync(dest);
|
const partialStats = fs.statSync(dest);
|
||||||
const isResumableError = error.message && (
|
const isResumableError = error.message && (
|
||||||
@@ -387,13 +385,14 @@ async function downloadFile(url, dest, progressCallback, maxRetries = 5) {
|
|||||||
// Check if download appears to be complete (close to expected PWR size)
|
// Check if download appears to be complete (close to expected PWR size)
|
||||||
const isPossiblyComplete = partialStats.size >= 1500 * 1024 * 1024; // >= 1.5GB
|
const isPossiblyComplete = partialStats.size >= 1500 * 1024 * 1024; // >= 1.5GB
|
||||||
|
|
||||||
if (partialStats.size < 1024 * 1024 || (!isResumableError && !isPossiblyComplete)) {
|
if (isRangeError || partialStats.size < 1024 * 1024 || (!isResumableError && !isPossiblyComplete)) {
|
||||||
// Delete if file is too small OR error is non-resumable AND not possibly complete
|
// Delete if HTTP 416 OR file is too small OR error is non-resumable AND not possibly complete
|
||||||
console.log(`[Cleanup] Removing PWR file (${!isResumableError && !isPossiblyComplete ? 'non-resumable error' : 'too small'}): ${(partialStats.size / 1024 / 1024).toFixed(2)} MB`);
|
const reason = isRangeError ? 'HTTP 416 range error' : (!isResumableError && !isPossiblyComplete ? 'non-resumable error' : 'too small');
|
||||||
|
console.log(`[Cleanup] Removing file (${reason}): ${(partialStats.size / 1024 / 1024).toFixed(2)} MB`);
|
||||||
fs.unlinkSync(dest);
|
fs.unlinkSync(dest);
|
||||||
} else {
|
} else {
|
||||||
// Keep the file for resume on resumable errors or if possibly complete
|
// Keep the file for resume on resumable errors or if possibly complete
|
||||||
console.log(`[Resume] Keeping PWR file (${isPossiblyComplete ? 'possibly complete' : 'for resume'}): ${(partialStats.size / 1024 / 1024).toFixed(2)} MB`);
|
console.log(`[Resume] Keeping file (${isPossiblyComplete ? 'possibly complete' : 'for resume'}): ${(partialStats.size / 1024 / 1024).toFixed(2)} MB`);
|
||||||
}
|
}
|
||||||
} catch (cleanupError) {
|
} catch (cleanupError) {
|
||||||
console.warn('Could not handle partial file:', cleanupError.message);
|
console.warn('Could not handle partial file:', cleanupError.message);
|
||||||
@@ -554,6 +553,17 @@ async function retryDownload(url, dest, progressCallback, previousError = null)
|
|||||||
fs.mkdirSync(destDir, { recursive: true });
|
fs.mkdirSync(destDir, { recursive: true });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// CRITICAL: Delete partial file before manual retry to avoid HTTP 416
|
||||||
|
if (fs.existsSync(dest)) {
|
||||||
|
try {
|
||||||
|
const stats = fs.statSync(dest);
|
||||||
|
console.log(`[Retry] Deleting partial file before retry: ${(stats.size / 1024 / 1024).toFixed(2)} MB`);
|
||||||
|
fs.unlinkSync(dest);
|
||||||
|
} catch (err) {
|
||||||
|
console.warn('Could not delete partial file:', err.message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await downloadFile(url, dest, progressCallback, additionalRetries);
|
await downloadFile(url, dest, progressCallback, additionalRetries);
|
||||||
console.log('Manual retry successful');
|
console.log('Manual retry successful');
|
||||||
|
|||||||
15
main.js
15
main.js
@@ -1,4 +1,5 @@
|
|||||||
const path = require('path');
|
const path = require('path');
|
||||||
|
require('dotenv').config({ path: path.join(__dirname, '.env') });
|
||||||
const { app, BrowserWindow, ipcMain, dialog, shell } = require('electron');
|
const { app, BrowserWindow, ipcMain, dialog, shell } = require('electron');
|
||||||
const { autoUpdater } = require('electron-updater');
|
const { autoUpdater } = require('electron-updater');
|
||||||
const fs = require('fs');
|
const fs = require('fs');
|
||||||
@@ -446,6 +447,13 @@ ipcMain.handle('launch-game', async (event, playerName, javaPath, installPath, g
|
|||||||
|
|
||||||
ipcMain.handle('install-game', async (event, playerName, javaPath, installPath, branch) => {
|
ipcMain.handle('install-game', async (event, playerName, javaPath, installPath, branch) => {
|
||||||
try {
|
try {
|
||||||
|
console.log(`[IPC] install-game called with parameters:`);
|
||||||
|
console.log(` - playerName: ${playerName}`);
|
||||||
|
console.log(` - javaPath: ${javaPath}`);
|
||||||
|
console.log(` - installPath: ${installPath}`);
|
||||||
|
console.log(` - branch: ${branch}`);
|
||||||
|
console.log(`[IPC] branch type: ${typeof branch}, value: ${JSON.stringify(branch)}`);
|
||||||
|
|
||||||
// Signal installation start
|
// Signal installation start
|
||||||
if (mainWindow && !mainWindow.isDestroyed()) {
|
if (mainWindow && !mainWindow.isDestroyed()) {
|
||||||
mainWindow.webContents.send('installation-start');
|
mainWindow.webContents.send('installation-start');
|
||||||
@@ -625,6 +633,7 @@ ipcMain.handle('load-close-launcher', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
ipcMain.handle('select-install-path', async () => {
|
ipcMain.handle('select-install-path', async () => {
|
||||||
|
|
||||||
const result = await dialog.showOpenDialog(mainWindow, {
|
const result = await dialog.showOpenDialog(mainWindow, {
|
||||||
properties: ['openDirectory'],
|
properties: ['openDirectory'],
|
||||||
title: 'Select Installation Folder'
|
title: 'Select Installation Folder'
|
||||||
@@ -742,8 +751,8 @@ ipcMain.handle('retry-download', async (event, retryData) => {
|
|||||||
console.log('[IPC] Full JRE retry data:', JSON.stringify(retryData, null, 2));
|
console.log('[IPC] Full JRE retry data:', JSON.stringify(retryData, null, 2));
|
||||||
|
|
||||||
const { retryJREDownload } = require('./backend/managers/javaManager');
|
const { retryJREDownload } = require('./backend/managers/javaManager');
|
||||||
await retryJREDownload(retryData.jreUrl, jreCacheFile, progressCallback);
|
|
||||||
const jreCacheFile = path.join(retryData.cacheDir, retryData.fileName);
|
const jreCacheFile = path.join(retryData.cacheDir, retryData.fileName);
|
||||||
|
await retryJREDownload(retryData.jreUrl, jreCacheFile, progressCallback);
|
||||||
|
|
||||||
return { success: true };
|
return { success: true };
|
||||||
}
|
}
|
||||||
@@ -930,6 +939,10 @@ ipcMain.handle('get-local-app-data', async () => {
|
|||||||
return process.env.LOCALAPPDATA || path.join(os.homedir(), 'AppData', 'Local');
|
return process.env.LOCALAPPDATA || path.join(os.homedir(), 'AppData', 'Local');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
ipcMain.handle('get-env-var', async (event, key) => {
|
||||||
|
return process.env[key];
|
||||||
|
});
|
||||||
|
|
||||||
ipcMain.handle('get-user-id', async () => {
|
ipcMain.handle('get-user-id', async () => {
|
||||||
try {
|
try {
|
||||||
const { getOrCreatePlayerId } = require('./backend/launcher');
|
const { getOrCreatePlayerId } = require('./backend/launcher');
|
||||||
|
|||||||
@@ -35,6 +35,7 @@ contextBridge.exposeInMainWorld('electronAPI', {
|
|||||||
openGameLocation: () => ipcRenderer.invoke('open-game-location'),
|
openGameLocation: () => ipcRenderer.invoke('open-game-location'),
|
||||||
saveSettings: (settings) => ipcRenderer.invoke('save-settings', settings),
|
saveSettings: (settings) => ipcRenderer.invoke('save-settings', settings),
|
||||||
loadSettings: () => ipcRenderer.invoke('load-settings'),
|
loadSettings: () => ipcRenderer.invoke('load-settings'),
|
||||||
|
getEnvVar: (key) => ipcRenderer.invoke('get-env-var', key),
|
||||||
getLocalAppData: () => ipcRenderer.invoke('get-local-app-data'),
|
getLocalAppData: () => ipcRenderer.invoke('get-local-app-data'),
|
||||||
getModsPath: () => ipcRenderer.invoke('get-mods-path'),
|
getModsPath: () => ipcRenderer.invoke('get-mods-path'),
|
||||||
loadInstalledMods: (modsPath) => ipcRenderer.invoke('load-installed-mods', modsPath),
|
loadInstalledMods: (modsPath) => ipcRenderer.invoke('load-installed-mods', modsPath),
|
||||||
|
|||||||
Reference in New Issue
Block a user