Files
BiLauncher/launcherpaths.cpp
T

158 lines
4.2 KiB
C++
Raw Permalink Normal View History

2026-08-23 03:30:31 +03:00
#include "launcherpaths.h"
#include "localization.h"
2026-08-23 03:30:31 +03:00
#include <QDir>
#include <QFileInfo>
2026-10-13 08:51:07 +03:00
#include <QtGlobal>
2026-08-23 03:30:31 +03:00
namespace {
2026-09-29 09:38:12 +03:00
const QString kFolderName = QStringLiteral("BiLauncher");
2026-08-23 03:30:31 +03:00
2026-10-13 08:51:07 +03:00
// Домашняя папка, от которой строятся все пути (см. LauncherPaths::homeOverride()).
QString homeBase()
{
const QString overridden = LauncherPaths::homeOverride();
return overridden.isEmpty() ? QDir::homePath() : overridden;
}
2026-08-23 03:30:31 +03:00
} // namespace
2026-10-13 08:51:07 +03:00
QString LauncherPaths::homeOverride()
{
// Относительный путь зависел бы от текущей папки процесса — такой не принимаем.
const QString value = QDir::fromNativeSeparators(qEnvironmentVariable("BILAUNCHER_HOME"));
if (value.isEmpty() || !QDir::isAbsolutePath(value))
return QString();
return QDir::cleanPath(value);
}
2026-08-23 03:30:31 +03:00
QString LauncherPaths::containerDir()
{
#if defined(Q_OS_WIN)
2026-10-13 08:51:07 +03:00
return homeBase() + QStringLiteral("/AppData/Roaming");
2026-08-23 03:30:31 +03:00
#elif defined(Q_OS_MACOS)
2026-10-13 08:51:07 +03:00
return homeBase() + QStringLiteral("/Library/Application Support");
2026-08-23 03:30:31 +03:00
#else // Linux и прочие Unix-системы
2026-10-13 08:51:07 +03:00
return homeBase();
2026-08-23 03:30:31 +03:00
#endif
}
QString LauncherPaths::rootDir()
{
return containerDir() + u'/' + kFolderName;
}
QString LauncherPaths::defaultMinecraftDir()
{
#if defined(Q_OS_MACOS)
// На macOS папка игры исторически без точки.
return containerDir() + QStringLiteral("/minecraft");
#else
return containerDir() + QStringLiteral("/.minecraft");
#endif
}
QString LauncherPaths::settingsFile()
{
return rootDir() + QStringLiteral("/settings.json");
}
QString LauncherPaths::profilesFile()
{
return rootDir() + QStringLiteral("/profiles.json");
}
QString LauncherPaths::customBuildsFile()
{
return rootDir() + QStringLiteral("/customBuilds.json");
}
QString LauncherPaths::legacyCustomBuildsFile()
2026-08-23 03:30:31 +03:00
{
return rootDir() + QStringLiteral("/versions.json");
}
QString LauncherPaths::buildStorageDir()
{
return rootDir() + QStringLiteral("/builds");
}
2026-08-31 00:59:14 +03:00
QString LauncherPaths::buildDir(int buildId)
{
return buildStorageDir() + u'/' + QString::number(buildId);
}
QString LauncherPaths::seasonalStateFile(int buildId)
{
return buildDir(buildId) + QStringLiteral("/season.json");
}
2026-08-23 03:30:31 +03:00
QString LauncherPaths::runtimeDir()
{
return rootDir() + QStringLiteral("/runtime");
}
2026-08-27 19:35:11 +03:00
QString LauncherPaths::javaDir()
{
return rootDir() + QStringLiteral("/java");
}
QString LauncherPaths::javaCatalogFile()
{
return cacheDir() + QStringLiteral("/java_runtimes.json");
}
QString LauncherPaths::javaDownloadDir()
{
return cacheDir() + QStringLiteral("/java");
}
2026-08-24 21:09:52 +03:00
QString LauncherPaths::cacheDir()
{
return rootDir() + QStringLiteral("/cache");
}
QString LauncherPaths::versionManifestFile()
{
return cacheDir() + QStringLiteral("/version_manifest.json");
}
2026-08-31 00:59:14 +03:00
QString LauncherPaths::seasonalCatalogFile()
{
return cacheDir() + QStringLiteral("/seasonal_builds.json");
}
QString LauncherPaths::loaderCacheFile(const QString &loaderKey)
{
return cacheDir() + QStringLiteral("/loader_") + loaderKey + QStringLiteral(".json");
}
QString LauncherPaths::loaderDownloadDir()
{
return cacheDir() + QStringLiteral("/loaders");
}
2026-08-23 03:30:31 +03:00
bool LauncherPaths::ensureRootExists(QString *error)
{
2026-08-27 19:35:11 +03:00
const QStringList required{rootDir(), runtimeDir(), cacheDir(),
loaderDownloadDir(), buildStorageDir(), javaDir(),
javaDownloadDir()};
2026-08-23 03:30:31 +03:00
for (const QString &path : required) {
if (!QDir().mkpath(path)) {
if (error)
*error = Loc::text("storage.error.createFailed").arg(QDir::toNativeSeparators(path));
2026-08-23 03:30:31 +03:00
return false;
}
// mkpath отвечает true и для существующего каталога, в который нельзя писать,
// и для подсунутого вместо папки файла — тогда все сохранения провалились бы молча.
const QFileInfo info(path);
if (!info.isDir() || !info.isWritable()) {
if (error)
*error = Loc::text("storage.error.notWritable").arg(QDir::toNativeSeparators(path));
2026-08-23 03:30:31 +03:00
return false;
}
}
return true;
}