/* SPDX-FileCopyrightText: 2026 Project Tick * SPDX-FileContributor: Project Tick * SPDX-License-Identifier: GPL-3.0-or-later * * MeshMC - A Custom Launcher for Minecraft * Copyright (C) 2026 Project Tick * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * * This file incorporates work covered by the following copyright and * permission notice: * * Copyright 2013-2021 MultiMC Contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include #include #include #include #include "LegacyInstance.h" #include "minecraft/legacy/LegacyModList.h" #include "minecraft/WorldList.h" #include #include LegacyInstance::LegacyInstance(SettingsObjectPtr globalSettings, SettingsObjectPtr settings, const QString& rootDir) : BaseInstance(globalSettings, settings, rootDir) { settings->registerSetting("NeedsRebuild", true); settings->registerSetting("ShouldUpdate", false); settings->registerSetting("JarVersion", QString()); settings->registerSetting("IntendedJarVersion", QString()); /* * custom base jar has no default. it is determined in code... see the * accessor methods for it * * for instances that DO NOT have the CustomBaseJar setting (legacy * instances), * [.]minecraft/bin/mcbackup.jar is the default base jar */ settings->registerSetting("UseCustomBaseJar", true); settings->registerSetting("CustomBaseJar", ""); } QString LegacyInstance::mainJarToPreserve() const { bool customJar = m_settings->get("UseCustomBaseJar").toBool(); if (customJar) { auto base = baseJar(); if (QFile::exists(base)) { return base; } } auto runnable = runnableJar(); if (QFile::exists(runnable)) { return runnable; } return QString(); } QString LegacyInstance::baseJar() const { bool customJar = m_settings->get("UseCustomBaseJar").toBool(); if (customJar) { return customBaseJar(); } else return defaultBaseJar(); } QString LegacyInstance::customBaseJar() const { QString value = m_settings->get("CustomBaseJar").toString(); if (value.isNull() || value.isEmpty()) { return defaultCustomBaseJar(); } return value; } bool LegacyInstance::shouldUseCustomBaseJar() const { return m_settings->get("UseCustomBaseJar").toBool(); } Task::Ptr LegacyInstance::createUpdateTask(Net::Mode) { return nullptr; } std::shared_ptr LegacyInstance::jarModList() const { if (!jar_mod_list) { auto list = new LegacyModList(jarModsDir(), modListFile()); jar_mod_list.reset(list); } jar_mod_list->update(); return jar_mod_list; } QString LegacyInstance::gameRoot() const { QFileInfo mcDir(FS::PathCombine(instanceRoot(), "minecraft")); QFileInfo dotMCDir(FS::PathCombine(instanceRoot(), ".minecraft")); if (mcDir.exists() && !dotMCDir.exists()) return mcDir.filePath(); else return dotMCDir.filePath(); } QString LegacyInstance::binRoot() const { return FS::PathCombine(gameRoot(), "bin"); } QString LegacyInstance::modsRoot() const { return FS::PathCombine(gameRoot(), "mods"); } QString LegacyInstance::jarModsDir() const { return FS::PathCombine(instanceRoot(), "instMods"); } QString LegacyInstance::libDir() const { return FS::PathCombine(gameRoot(), "lib"); } QString LegacyInstance::savesDir() const { return FS::PathCombine(gameRoot(), "saves"); } QString LegacyInstance::coreModsDir() const { return FS::PathCombine(gameRoot(), "coremods"); } QString LegacyInstance::resourceDir() const { return FS::PathCombine(gameRoot(), "resources"); } QString LegacyInstance::texturePacksDir() const { return FS::PathCombine(gameRoot(), "texturepacks"); } QString LegacyInstance::runnableJar() const { return FS::PathCombine(binRoot(), "minecraft.jar"); } QString LegacyInstance::modListFile() const { return FS::PathCombine(instanceRoot(), "modlist"); } QString LegacyInstance::instanceConfigFolder() const { return FS::PathCombine(gameRoot(), "config"); } bool LegacyInstance::shouldRebuild() const { return m_settings->get("NeedsRebuild").toBool(); } QString LegacyInstance::currentVersionId() const { return m_settings->get("JarVersion").toString(); } QString LegacyInstance::intendedVersionId() const { return m_settings->get("IntendedJarVersion").toString(); } bool LegacyInstance::shouldUpdate() const { QVariant var = settings()->get("ShouldUpdate"); if (!var.isValid() || var.toBool() == false) { return intendedVersionId() != currentVersionId(); } return true; } QString LegacyInstance::defaultBaseJar() const { return "versions/" + intendedVersionId() + "/" + intendedVersionId() + ".jar"; } QString LegacyInstance::defaultCustomBaseJar() const { return FS::PathCombine(binRoot(), "mcbackup.jar"); } std::shared_ptr LegacyInstance::worldList() const { if (!m_world_list) { m_world_list.reset(new WorldList(savesDir())); } return m_world_list; } QString LegacyInstance::typeName() const { return tr("Legacy"); } QString LegacyInstance::getStatusbarDescription() { return tr("Instance from previous versions."); } QStringList LegacyInstance::verboseDescription(AuthSessionPtr session, MinecraftServerTargetPtr serverToJoin) { QStringList out; auto alltraits = traits(); if (alltraits.size()) { out << "Traits:"; for (auto trait : alltraits) { out << " " + trait; } out << ""; } QString windowParams; if (settings()->get("LaunchMaximized").toBool()) { out << "Window size: max (if available)"; } else { auto width = settings()->get("MinecraftWinWidth").toInt(); auto height = settings()->get("MinecraftWinHeight").toInt(); out << "Window size: " + QString::number(width) + " x " + QString::number(height); } out << ""; return out; }