add: VersionExplorer, don't work first run Minecraft

This commit is contained in:
2025-07-08 03:29:36 +05:00
parent 31a26dc1ce
commit 815ce286f7
5 changed files with 559 additions and 106 deletions

View File

@ -8,7 +8,7 @@ import {
Modal,
} from '@mui/material';
import { useEffect, useState } from 'react';
import { useNavigate } from 'react-router-dom';
import { useNavigate, useParams } from 'react-router-dom';
import ServerStatus from '../components/ServerStatus/ServerStatus';
import PopaPopa from '../components/popa-popa';
import SettingsIcon from '@mui/icons-material/Settings';
@ -30,7 +30,9 @@ declare global {
// Определяем тип для props
interface LaunchPageProps {
launchOptions: {
onLaunchPage?: () => void;
launchOptions?: {
// Делаем опциональным
downloadUrl: string;
apiReleaseUrl: string;
versionFileName: string;
@ -42,8 +44,11 @@ interface LaunchPageProps {
};
}
const LaunchPage = ({ launchOptions }: LaunchPageProps) => {
const LaunchPage = ({ onLaunchPage, launchOptions = {} as any }: LaunchPageProps) => {
const navigate = useNavigate();
const { versionId } = useParams();
const [versionConfig, setVersionConfig] = useState<any>(null);
// Начальное состояние должно быть пустым или с минимальными значениями
const [config, setConfig] = useState<{
memory: number;
@ -101,27 +106,82 @@ const LaunchPage = ({ launchOptions }: LaunchPageProps) => {
}, [navigate]);
useEffect(() => {
// Загрузка конфигурации сборки при монтировании
const loadPackConfig = async () => {
const fetchVersionConfig = async () => {
if (!versionId) return;
try {
// Сначала проверяем, есть ли конфигурация в localStorage
const savedConfig = localStorage.getItem('selected_version_config');
if (savedConfig) {
const parsedConfig = JSON.parse(savedConfig);
setVersionConfig(parsedConfig);
// Устанавливаем значения памяти и preserveFiles из конфигурации
setConfig({
memory: parsedConfig.memory || 4096,
preserveFiles: parsedConfig.preserveFiles || [],
});
// Очищаем localStorage
localStorage.removeItem('selected_version_config');
return;
}
// Если нет в localStorage, запрашиваем с сервера
const result = await window.electron.ipcRenderer.invoke(
'load-pack-config',
{
packName: launchOptions.packName,
},
'get-version-config',
{ versionId },
);
if (result.success && result.config) {
// Полностью заменяем config значениями из файла
setConfig(result.config);
if (result.success) {
setVersionConfig(result.config);
setConfig({
memory: result.config.memory || 4096,
preserveFiles: result.config.preserveFiles || [],
});
} else {
// Если не удалось получить конфигурацию, используем значения по умолчанию
const defaultConfig = {
downloadUrl: '',
apiReleaseUrl: '',
versionFileName: `${versionId}_version.txt`,
packName: versionId || 'Comfort',
memory: 4096,
baseVersion: '1.21.4',
serverIp: 'popa-popa.ru',
fabricVersion: '0.16.14',
preserveFiles: ['popa-launcher-config.json'],
};
setVersionConfig(defaultConfig);
setConfig({
memory: defaultConfig.memory,
preserveFiles: defaultConfig.preserveFiles || [],
});
}
} catch (error) {
console.error('Ошибка при загрузке настроек:', error);
console.error('Ошибка при получении настроек версии:', error);
// Используем значения по умолчанию
const defaultConfig = {
downloadUrl: '',
apiReleaseUrl: '',
versionFileName: `${versionId}_version.txt`,
packName: versionId || 'Comfort',
memory: 4096,
baseVersion: '1.21.4',
serverIp: 'popa-popa.ru',
fabricVersion: '0.16.14',
preserveFiles: ['popa-launcher-config.json'],
};
setVersionConfig(defaultConfig);
setConfig({
memory: defaultConfig.memory,
preserveFiles: defaultConfig.preserveFiles || [],
});
}
};
loadPackConfig();
}, [launchOptions.packName]);
fetchVersionConfig();
}, [versionId]);
const showNotification = (
message: string,
@ -134,94 +194,86 @@ const LaunchPage = ({ launchOptions }: LaunchPageProps) => {
setNotification({ ...notification, open: false });
};
// Функция для запуска игры с настройками выбранной версии
const handleLaunchMinecraft = async () => {
try {
setIsDownloading(true);
setDownloadProgress(0);
setBuffer(10);
// Загружаем настройки сборки
const result = await window.electron.ipcRenderer.invoke(
'load-pack-config',
{
packName: launchOptions.packName,
},
);
// Используем настройки выбранной версии или дефолтные
const currentConfig = versionConfig || {
packName: versionId || 'Comfort',
memory: 4096,
baseVersion: '1.21.4',
serverIp: 'popa-popa.ru',
fabricVersion: '0.16.14',
preserveFiles: [],
};
// Используйте уже существующий state вместо локальной переменной
if (result.success && result.config) {
setConfig(result.config); // Обновляем state
// Проверяем, является ли это ванильной версией
const isVanillaVersion =
!currentConfig.downloadUrl || currentConfig.downloadUrl === '';
if (!isVanillaVersion) {
// Если это не ванильная версия, выполняем загрузку и распаковку
const packOptions = {
downloadUrl: currentConfig.downloadUrl,
apiReleaseUrl: currentConfig.apiReleaseUrl,
versionFileName: currentConfig.versionFileName,
packName: versionId || currentConfig.packName,
preserveFiles: config.preserveFiles,
};
// Передаем опции для скачивания
const downloadResult = await window.electron.ipcRenderer.invoke(
'download-and-extract',
packOptions,
);
if (downloadResult?.success) {
if (downloadResult.updated) {
showNotification(
`Сборка ${downloadResult.packName} успешно обновлена до версии ${downloadResult.version}`,
'success',
);
} else {
showNotification(
`Установлена актуальная версия сборки ${downloadResult.packName} (${downloadResult.version})`,
'info',
);
}
}
} else {
showNotification('Запускаем ванильный Minecraft...', 'info');
}
// Опции для запуска Minecraft
const savedConfig = JSON.parse(
localStorage.getItem('launcher_config') || '{}',
);
// Опции для скачивания сборки
const packOptions = {
downloadUrl: launchOptions.downloadUrl,
apiReleaseUrl: launchOptions.apiReleaseUrl,
versionFileName: launchOptions.versionFileName,
packName: launchOptions.packName,
preserveFiles: config.preserveFiles,
const options = {
accessToken: savedConfig.accessToken,
uuid: savedConfig.uuid,
username: savedConfig.username,
memory: config.memory,
baseVersion: currentConfig.baseVersion,
packName: versionId || currentConfig.packName,
serverIp: currentConfig.serverIp,
fabricVersion: currentConfig.fabricVersion,
// Для ванильной версии устанавливаем флаг
isVanillaVersion: isVanillaVersion,
versionToLaunchOverride: isVanillaVersion ? versionId : undefined,
};
// Передаем опции для скачивания
const downloadResult = await window.electron.ipcRenderer.invoke(
'download-and-extract',
packOptions,
const launchResult = await window.electron.ipcRenderer.invoke(
'launch-minecraft',
options,
);
if (downloadResult?.success) {
let needsSecondAttempt = false;
if (downloadResult.updated) {
showNotification(
`Сборка ${downloadResult.packName} успешно обновлена до версии ${downloadResult.version}`,
'success',
);
needsSecondAttempt = true;
} else {
showNotification(
`Установлена актуальная версия сборки ${downloadResult.packName} (${downloadResult.version})`,
'info',
);
}
// Опции для запуска
const options = {
accessToken: savedConfig.accessToken,
uuid: savedConfig.uuid,
username: savedConfig.username,
memory: config.memory, // Используем state
baseVersion: launchOptions.baseVersion,
packName: launchOptions.packName,
serverIp: launchOptions.serverIp,
fabricVersion: launchOptions.fabricVersion,
};
const launchResult = await window.electron.ipcRenderer.invoke(
'launch-minecraft',
options,
);
if (needsSecondAttempt) {
showNotification(
'Завершаем настройку компонентов, повторный запуск...',
'info',
);
await new Promise((resolve) => setTimeout(resolve, 2000));
const secondAttempt = await window.electron.ipcRenderer.invoke(
'launch-minecraft',
options,
);
showNotification('Minecraft успешно запущен!', 'success');
} else if (launchResult?.success) {
showNotification('Minecraft успешно запущен!', 'success');
}
if (launchResult?.success) {
showNotification('Minecraft успешно запущен!', 'success');
}
} catch (error) {
console.error('Error:', error);
@ -240,7 +292,7 @@ const LaunchPage = ({ launchOptions }: LaunchPageProps) => {
};
await window.electron.ipcRenderer.invoke('save-pack-config', {
packName: launchOptions.packName,
packName: versionId || versionConfig?.packName || 'Comfort',
config: configToSave,
});
@ -285,7 +337,7 @@ const LaunchPage = ({ launchOptions }: LaunchPageProps) => {
<Box>
<ServerStatus
serverIp={launchOptions.serverIp}
serverIp={versionConfig?.serverIp || 'popa-popa.ru'}
refreshInterval={30000}
/>
</Box>
@ -393,8 +445,8 @@ const LaunchPage = ({ launchOptions }: LaunchPageProps) => {
Файлы и папки, которые будут сохранены после переустановки сборки
</Typography>
<FilesSelector
packName={launchOptions.packName}
initialSelected={config.preserveFiles} // Передаем текущие выбранные файлы
packName={versionId || versionConfig?.packName || 'Comfort'}
initialSelected={config.preserveFiles}
onSelectionChange={(selected) => {
setConfig((prev) => ({ ...prev, preserveFiles: selected }));
}}