maybe work

This commit is contained in:
2025-12-02 04:19:19 +05:00
parent 65ea5418da
commit 59c7d7fd85
3 changed files with 192 additions and 184 deletions

View File

@ -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';
}
// Если есть конфигурационный файл, загружаем из него

View File

@ -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, запрашиваем с сервера

View File

@ -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': {