maybe work
This commit is contained in:
@ -481,40 +481,66 @@ export function initMinecraftHandlers() {
|
||||
memory = 4096,
|
||||
baseVersion = '1.21.4',
|
||||
fabricVersion = '0.16.14',
|
||||
packName = 'Comfort', // Название основной сборки
|
||||
versionToLaunchOverride = '', // Возможность переопределить версию для запуска
|
||||
packName = 'Comfort', // имя сборки (папка с модами)
|
||||
versionToLaunchOverride = '', // переопределение версии для запуска (например, 1.21.10 для ванили)
|
||||
serverIp = 'popa-popa.ru',
|
||||
serverPort, // опциональный порт
|
||||
serverPort,
|
||||
isVanillaVersion = false,
|
||||
} = gameConfig || {};
|
||||
|
||||
const appPath = path.dirname(app.getPath('exe'));
|
||||
const minecraftDir = path.join(appPath, '.minecraft');
|
||||
const versionsDir = path.join(minecraftDir, 'versions');
|
||||
fs.mkdirSync(versionsDir, { recursive: true });
|
||||
|
||||
// gamePath:
|
||||
// - ваниль → .minecraft
|
||||
// - модпак → .minecraft/versions/Comfort (или другое packName)
|
||||
const packDir = isVanillaVersion
|
||||
? minecraftDir
|
||||
: path.join(versionsDir, packName);
|
||||
if (!fs.existsSync(packDir)) {
|
||||
fs.mkdirSync(packDir, { recursive: true });
|
||||
}
|
||||
|
||||
// Определяем версию для запуска
|
||||
const versionsContents = fs.existsSync(versionsDir)
|
||||
? fs.readdirSync(versionsDir)
|
||||
: [];
|
||||
console.log('Доступные версии:', versionsContents);
|
||||
|
||||
// Найти версию пакета, Fabric или базовую версию
|
||||
let versionToLaunch = versionToLaunchOverride;
|
||||
// --- Определяем базовую / фактическую версию ---
|
||||
let effectiveBaseVersion = baseVersion;
|
||||
|
||||
console.log('fabric:', `${baseVersion}-fabric${fabricVersion}`);
|
||||
// Для ванили считаем базовой именно ту, которую хотим запустить
|
||||
if (isVanillaVersion && versionToLaunchOverride) {
|
||||
effectiveBaseVersion = versionToLaunchOverride;
|
||||
}
|
||||
|
||||
let versionToLaunch: string | undefined =
|
||||
versionToLaunchOverride || undefined;
|
||||
|
||||
if (!versionToLaunch) {
|
||||
if (
|
||||
versionsContents.includes(`${baseVersion}-fabric${fabricVersion}`)
|
||||
) {
|
||||
versionToLaunch = `${baseVersion}-fabric${fabricVersion}`;
|
||||
} else if (versionsContents.includes(packName)) {
|
||||
versionToLaunch = packName;
|
||||
if (isVanillaVersion) {
|
||||
// Ваниль — запускаем baseVersion (или override)
|
||||
versionToLaunch = effectiveBaseVersion;
|
||||
} else {
|
||||
versionToLaunch = baseVersion;
|
||||
// Модпак — запускаем именно fabric-версию
|
||||
const fabricId = `${effectiveBaseVersion}-fabric${fabricVersion}`;
|
||||
if (versionsContents.includes(fabricId)) {
|
||||
versionToLaunch = fabricId;
|
||||
} else {
|
||||
// даже если папки нет — installFabric её создаст
|
||||
versionToLaunch = fabricId;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
console.log('Запускаем версию:', versionToLaunch);
|
||||
console.log('isVanillaVersion:', isVanillaVersion);
|
||||
console.log('baseVersion:', baseVersion);
|
||||
console.log('effectiveBaseVersion:', effectiveBaseVersion);
|
||||
console.log('fabricVersion:', fabricVersion);
|
||||
console.log('versionToLaunch:', versionToLaunch);
|
||||
console.log('packDir:', packDir);
|
||||
|
||||
// --- Поиск Java ---
|
||||
event.sender.send('installation-status', {
|
||||
@ -524,23 +550,24 @@ export function initMinecraftHandlers() {
|
||||
|
||||
console.log('Поиск Java...');
|
||||
|
||||
let javaPath: string;
|
||||
let javaPath = 'java';
|
||||
try {
|
||||
javaPath = await findJava();
|
||||
} catch (error) {
|
||||
console.warn('Ошибка при поиске Java:', error);
|
||||
event.sender.send('installation-status', {
|
||||
step: 'java-error',
|
||||
message: 'Не удалось найти Java. Используем системную Java.',
|
||||
message:
|
||||
'Не удалось найти Java. Попробуем запустить с системной Java.',
|
||||
});
|
||||
javaPath = 'java';
|
||||
}
|
||||
|
||||
// --- Установка Minecraft / Fabric / зависимостей ---
|
||||
console.log('Используем Java:', javaPath);
|
||||
|
||||
// --- 1. Установка ванильного Minecraft (effectiveBaseVersion) ---
|
||||
let resolvedVersion: any;
|
||||
|
||||
try {
|
||||
// 1. Получаем список версий и устанавливаем ванильный Minecraft
|
||||
event.sender.send('installation-status', {
|
||||
step: 'minecraft-list',
|
||||
message: 'Получение списка версий Minecraft...',
|
||||
@ -550,22 +577,13 @@ export function initMinecraftHandlers() {
|
||||
|
||||
const versionList = await getVersionList();
|
||||
const minecraftVersion = versionList.versions.find(
|
||||
(v) => v.id === baseVersion,
|
||||
(v) => v.id === effectiveBaseVersion,
|
||||
);
|
||||
|
||||
console.log('minecraftVersion:', minecraftVersion);
|
||||
|
||||
if (minecraftVersion) {
|
||||
// Устанавливаем базовую версию Minecraft
|
||||
event.sender.send('installation-status', {
|
||||
step: 'minecraft-install',
|
||||
message: `Установка Minecraft ${baseVersion}...`,
|
||||
});
|
||||
|
||||
console.log('Установка Minecraft...');
|
||||
|
||||
const installMcTask = installTask(minecraftVersion, minecraftDir, {
|
||||
// немного уменьшаем агрессию загрузчика
|
||||
skipRevalidate: true,
|
||||
assetsDownloadConcurrency: 2,
|
||||
librariesDownloadConcurrency: 2,
|
||||
@ -573,6 +591,11 @@ export function initMinecraftHandlers() {
|
||||
|
||||
console.log('installMcTask started for', minecraftVersion.id);
|
||||
|
||||
event.sender.send('installation-status', {
|
||||
step: 'minecraft-install',
|
||||
message: `Установка Minecraft ${minecraftVersion.id}...`,
|
||||
});
|
||||
|
||||
await installMcTask.startAndWait({
|
||||
onFailed(task, error) {
|
||||
const stepName = (task as any).path || task.name || 'unknown';
|
||||
@ -588,113 +611,9 @@ export function initMinecraftHandlers() {
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
// 2. Устанавливаем Fabric
|
||||
console.log('Попытка установки Fabric:', {
|
||||
minecraftVersion: baseVersion,
|
||||
fabricVersion: fabricVersion,
|
||||
minecraftDir: minecraftDir,
|
||||
});
|
||||
|
||||
try {
|
||||
event.sender.send('installation-status', {
|
||||
step: 'fabric-list',
|
||||
message: 'Получение списка версий Fabric...',
|
||||
});
|
||||
|
||||
if (fabricVersion) {
|
||||
event.sender.send('installation-status', {
|
||||
step: 'fabric-install',
|
||||
message: `Установка Fabric ${fabricVersion}...`,
|
||||
});
|
||||
|
||||
console.log('installFabric:', {
|
||||
minecraftVersion: baseVersion,
|
||||
fabricVersion: fabricVersion,
|
||||
minecraftDir: minecraftDir,
|
||||
});
|
||||
|
||||
await installFabric({
|
||||
minecraftVersion: baseVersion,
|
||||
version: fabricVersion,
|
||||
minecraft: minecraftDir,
|
||||
});
|
||||
}
|
||||
} catch (error) {
|
||||
console.log('Ошибка при установке Fabric, продолжаем:', error);
|
||||
}
|
||||
|
||||
// 3. Подготовка версии и установка зависимостей
|
||||
try {
|
||||
const fabricVersionId = `${baseVersion}-fabric${fabricVersion}`;
|
||||
|
||||
console.log('version-parse:', fabricVersionId);
|
||||
|
||||
event.sender.send('installation-status', {
|
||||
step: 'version-parse',
|
||||
message: 'Подготовка версии...',
|
||||
});
|
||||
|
||||
console.log('version-parse:', {
|
||||
minecraftDir: minecraftDir,
|
||||
fabricVersionId: fabricVersionId,
|
||||
});
|
||||
|
||||
resolvedVersion = await Version.parse(
|
||||
minecraftDir,
|
||||
fabricVersionId,
|
||||
);
|
||||
|
||||
event.sender.send('installation-status', {
|
||||
step: 'dependencies',
|
||||
message: 'Установка библиотек и ресурсов...',
|
||||
});
|
||||
|
||||
const depsTask = installDependenciesTask(resolvedVersion, {
|
||||
// максимально душим параллельность
|
||||
assetsDownloadConcurrency: 2,
|
||||
librariesDownloadConcurrency: 2,
|
||||
// общие оптимизации
|
||||
skipRevalidate: true,
|
||||
prevalidSizeOnly: true,
|
||||
checksumValidatorResolver: () => ({
|
||||
validate: async () => {
|
||||
// отключаем проверку хэшей, чтобы не падать от мелких расхождений
|
||||
},
|
||||
}),
|
||||
});
|
||||
|
||||
try {
|
||||
await depsTask.startAndWait({
|
||||
onFailed(task, error) {
|
||||
const stepName = (task as any).path || task.name || 'unknown';
|
||||
console.warn(
|
||||
`[deps] step "${stepName}" failed: ${
|
||||
(error as any).code ?? ''
|
||||
} ${(error as any).message}`,
|
||||
);
|
||||
|
||||
event.sender.send('installation-status', {
|
||||
step: `dependencies.${stepName}`,
|
||||
message: `Ошибка: ${(error as any).message}`,
|
||||
});
|
||||
},
|
||||
});
|
||||
} catch (error: any) {
|
||||
console.log(
|
||||
'Ошибка при загрузке ресурсов, продолжаем запуск:',
|
||||
error.message || error,
|
||||
);
|
||||
}
|
||||
} catch (error: any) {
|
||||
console.log(
|
||||
'Ошибка при подготовке версии, продолжаем:',
|
||||
error.message || error,
|
||||
);
|
||||
}
|
||||
} else {
|
||||
console.warn(
|
||||
`Версия ${baseVersion} не найдена в списке версий Minecraft`,
|
||||
`Версия ${effectiveBaseVersion} не найдена в списке версий Minecraft. Предполагаем, что она уже установлена.`,
|
||||
);
|
||||
}
|
||||
} catch (error: any) {
|
||||
@ -702,12 +621,93 @@ export function initMinecraftHandlers() {
|
||||
const innerCount = Array.isArray(agg?.errors) ? agg.errors.length : 0;
|
||||
|
||||
console.log(
|
||||
'Ошибка при установке Minecraft/Fabric/зависимостей, продолжаем:',
|
||||
'Ошибка при установке ванильного Minecraft, продолжаем:',
|
||||
agg?.message || String(agg),
|
||||
innerCount ? `(внутренних ошибок: ${innerCount})` : '',
|
||||
);
|
||||
}
|
||||
|
||||
// --- 2. Установка Fabric (только для модпаков) ---
|
||||
if (!isVanillaVersion && fabricVersion) {
|
||||
try {
|
||||
event.sender.send('installation-status', {
|
||||
step: 'fabric-install',
|
||||
message: `Установка Fabric ${fabricVersion}...`,
|
||||
});
|
||||
|
||||
console.log('installFabric:', {
|
||||
minecraftVersion: effectiveBaseVersion,
|
||||
fabricVersion,
|
||||
minecraftDir,
|
||||
});
|
||||
|
||||
await installFabric({
|
||||
minecraftVersion: effectiveBaseVersion,
|
||||
version: fabricVersion,
|
||||
minecraft: minecraftDir,
|
||||
});
|
||||
} catch (error) {
|
||||
console.log('Ошибка при установке Fabric, продолжаем:', error);
|
||||
}
|
||||
}
|
||||
|
||||
// --- 3. Установка зависимостей для versionToLaunch ---
|
||||
try {
|
||||
if (!versionToLaunch) {
|
||||
throw new Error('versionToLaunch не определён');
|
||||
}
|
||||
|
||||
console.log('version-parse:', {
|
||||
minecraftDir,
|
||||
versionToLaunch,
|
||||
});
|
||||
|
||||
event.sender.send('installation-status', {
|
||||
step: 'version-parse',
|
||||
message: 'Подготовка версии...',
|
||||
});
|
||||
|
||||
resolvedVersion = await Version.parse(minecraftDir, versionToLaunch);
|
||||
|
||||
event.sender.send('installation-status', {
|
||||
step: 'dependencies',
|
||||
message: 'Установка библиотек и ресурсов...',
|
||||
});
|
||||
|
||||
const depsTask = installDependenciesTask(resolvedVersion, {
|
||||
skipRevalidate: true,
|
||||
prevalidSizeOnly: true,
|
||||
assetsDownloadConcurrency: 2,
|
||||
librariesDownloadConcurrency: 2,
|
||||
checksumValidatorResolver: () => ({
|
||||
async validate() {
|
||||
// Игнорируем sha1, чтобы не падать из-за несоответствий
|
||||
},
|
||||
}),
|
||||
});
|
||||
|
||||
await depsTask.startAndWait({
|
||||
onFailed(task, error) {
|
||||
const stepName = (task as any).path || task.name || 'unknown';
|
||||
console.warn(
|
||||
`[deps] step "${stepName}" failed: ${
|
||||
(error as any).code ?? ''
|
||||
} ${(error as any).message}`,
|
||||
);
|
||||
|
||||
event.sender.send('installation-status', {
|
||||
step: `dependencies.${stepName}`,
|
||||
message: `Ошибка: ${(error as any).message}`,
|
||||
});
|
||||
},
|
||||
});
|
||||
} catch (error: any) {
|
||||
console.log(
|
||||
'Ошибка при подготовке версии/зависимостей, продолжаем запуск:',
|
||||
error.message || error,
|
||||
);
|
||||
}
|
||||
|
||||
// --- authlib-injector ---
|
||||
const authlibPath = await ensureAuthlibInjectorExists(appPath);
|
||||
console.log('authlibPath:', authlibPath);
|
||||
@ -725,26 +725,17 @@ export function initMinecraftHandlers() {
|
||||
message: 'Запуск игры...',
|
||||
});
|
||||
|
||||
const packDir = path.join(versionsDir, packName);
|
||||
|
||||
const serverConfig: any = { ip: serverIp };
|
||||
if (serverPort) {
|
||||
serverConfig.port = serverPort;
|
||||
}
|
||||
|
||||
console.log('packDir:', packDir);
|
||||
|
||||
const proc = await launch({
|
||||
gamePath: packDir,
|
||||
resourcePath: minecraftDir,
|
||||
javaPath,
|
||||
version: versionToLaunch,
|
||||
version: versionToLaunch!,
|
||||
launcherName: 'popa-popa',
|
||||
extraJVMArgs: [
|
||||
'-Dlog4j2.formatMsgNoLookups=true',
|
||||
`-javaagent:${authlibPath}=${API_BASE_URL}`,
|
||||
`-Xmx${memory}M`,
|
||||
'-Dauthlibinjector.skinWhitelist=127.0.0.1,falrfg-213-87-196-173.ru.tuna.am',
|
||||
'-Dauthlibinjector.skinWhitelist=https://minecraft.api.popa-popa.ru/',
|
||||
'-Dauthlibinjector.debug=verbose,authlib',
|
||||
'-Dauthlibinjector.legacySkinPolyfill=enabled',
|
||||
'-Dauthlibinjector.mojangAntiFeatures=disabled',
|
||||
@ -842,28 +833,32 @@ export function initMinecraftHandlers() {
|
||||
|
||||
for (const item of items) {
|
||||
const versionPath = path.join(versionsDir, item);
|
||||
if (fs.statSync(versionPath).isDirectory()) {
|
||||
// Проверяем, есть ли конфигурация для пакета
|
||||
const versionJsonPath = path.join(versionPath, `${item}.json`);
|
||||
let versionInfo = {
|
||||
id: item,
|
||||
name: item,
|
||||
version: item,
|
||||
};
|
||||
if (!fs.statSync(versionPath).isDirectory()) continue;
|
||||
|
||||
if (fs.existsSync(versionJsonPath)) {
|
||||
try {
|
||||
const versionData = JSON.parse(
|
||||
fs.readFileSync(versionJsonPath, 'utf8'),
|
||||
);
|
||||
versionInfo.version = versionData.id || item;
|
||||
} catch (error) {
|
||||
console.warn(`Ошибка при чтении файла версии ${item}:`, error);
|
||||
}
|
||||
}
|
||||
|
||||
versions.push(versionInfo);
|
||||
// ❗ Прячем технические fabric-версии типа 1.21.10-fabric0.18.1
|
||||
if (item.includes('-fabric')) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const versionJsonPath = path.join(versionPath, `${item}.json`);
|
||||
let versionInfo = {
|
||||
id: item,
|
||||
name: item,
|
||||
version: item,
|
||||
};
|
||||
|
||||
if (fs.existsSync(versionJsonPath)) {
|
||||
try {
|
||||
const versionData = JSON.parse(
|
||||
fs.readFileSync(versionJsonPath, 'utf8'),
|
||||
);
|
||||
versionInfo.version = versionData.id || item;
|
||||
} catch (error) {
|
||||
console.warn(`Ошибка при чтении файла версии ${item}:`, error);
|
||||
}
|
||||
}
|
||||
|
||||
versions.push(versionInfo);
|
||||
}
|
||||
|
||||
return { success: true, versions };
|
||||
@ -1117,9 +1112,9 @@ ipcMain.handle('get-version-config', async (event, { versionId }) => {
|
||||
versionFileName: `${versionId}_version.txt`,
|
||||
packName: versionId,
|
||||
memory: 4096,
|
||||
baseVersion: '1.21.4',
|
||||
baseVersion: '1.21.10',
|
||||
serverIp: 'popa-popa.ru',
|
||||
fabricVersion: '0.16.14',
|
||||
fabricVersion: '0.18.1',
|
||||
preserveFiles: ['popa-launcher-config.json'],
|
||||
};
|
||||
|
||||
@ -1129,6 +1124,8 @@ ipcMain.handle('get-version-config', async (event, { versionId }) => {
|
||||
'https://github.com/DIKER0K/Comfort/releases/latest/download/Comfort.zip';
|
||||
config.apiReleaseUrl =
|
||||
'https://api.github.com/repos/DIKER0K/Comfort/releases/latest';
|
||||
config.baseVersion = '1.21.10';
|
||||
config.fabricVersion = '0.18.1';
|
||||
}
|
||||
|
||||
// Если есть конфигурационный файл, загружаем из него
|
||||
|
||||
@ -115,17 +115,21 @@ const LaunchPage = ({
|
||||
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 || [],
|
||||
});
|
||||
// Если конфиг пустой — считаем, что он невалидный и идём по IPC-ветке
|
||||
if (Object.keys(parsedConfig).length > 0) {
|
||||
setVersionConfig(parsedConfig);
|
||||
|
||||
// Очищаем localStorage
|
||||
localStorage.removeItem('selected_version_config');
|
||||
return;
|
||||
setConfig({
|
||||
memory: parsedConfig.memory || 4096,
|
||||
preserveFiles: parsedConfig.preserveFiles || [],
|
||||
});
|
||||
|
||||
localStorage.removeItem('selected_version_config');
|
||||
return;
|
||||
} else {
|
||||
localStorage.removeItem('selected_version_config');
|
||||
}
|
||||
}
|
||||
|
||||
// Если нет в localStorage, запрашиваем с сервера
|
||||
|
||||
@ -177,11 +177,17 @@ export const VersionsExplorer = () => {
|
||||
fetchVersions();
|
||||
}, []);
|
||||
|
||||
const handleSelectVersion = (version: VersionInfo) => {
|
||||
localStorage.setItem(
|
||||
'selected_version_config',
|
||||
JSON.stringify(version.config || {}),
|
||||
);
|
||||
const handleSelectVersion = (version: VersionInfo | AvailableVersionInfo) => {
|
||||
const cfg: any = (version as any).config;
|
||||
|
||||
if (cfg && (cfg.downloadUrl || cfg.apiReleaseUrl)) {
|
||||
// Версия из Gist — у неё есть нормальный config
|
||||
localStorage.setItem('selected_version_config', JSON.stringify(cfg));
|
||||
} else {
|
||||
// Установленная версия без config — не засоряем localStorage пустым объектом
|
||||
localStorage.removeItem('selected_version_config');
|
||||
}
|
||||
|
||||
navigate(`/launch/${version.id}`);
|
||||
};
|
||||
|
||||
@ -240,7 +246,8 @@ export const VersionsExplorer = () => {
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
cursor: 'pointer',
|
||||
filter: hoveredCardId && hoveredCardId !== 'add' ? 'blur(5px)' : 'blur(0)',
|
||||
filter:
|
||||
hoveredCardId && hoveredCardId !== 'add' ? 'blur(5px)' : 'blur(0)',
|
||||
transform: hoveredCardId === 'add' ? 'scale(1.03)' : 'scale(1)',
|
||||
zIndex: hoveredCardId === 'add' ? 10 : 1,
|
||||
'&:hover': {
|
||||
|
||||
Reference in New Issue
Block a user