NOISSUE Remove Legacy support

This commit is contained in:
Petr Mrázek 2017-07-23 21:29:03 +02:00
parent 4c01983f47
commit b29382c748
22 changed files with 0 additions and 2793 deletions

View File

@ -236,14 +236,6 @@ set(MINECRAFT_SOURCES
minecraft/launch/LauncherPartLaunch.h
minecraft/launch/PrintInstanceInfo.cpp
minecraft/launch/PrintInstanceInfo.h
minecraft/legacy/LegacyModList.h
minecraft/legacy/LegacyModList.cpp
minecraft/legacy/LegacyUpdate.h
minecraft/legacy/LegacyUpdate.cpp
minecraft/legacy/LegacyInstance.h
minecraft/legacy/LegacyInstance.cpp
minecraft/legacy/LwjglVersionList.h
minecraft/legacy/LwjglVersionList.cpp
minecraft/GradleSpecifier.h
minecraft/MinecraftProfile.cpp
minecraft/MinecraftProfile.h

View File

@ -10,7 +10,6 @@
#include "tasks/Task.h"
#include "meta/Index.h"
#include "FileSystem.h"
#include "minecraft/legacy/LwjglVersionList.h"
#include <QDebug>
@ -182,13 +181,4 @@ void Env::setJarsPath(const QString& path)
d->m_jarsPath = path;
}
LWJGLVersionList *Env::getLegacyLWJGL()
{
if(!d->m_lwjgllist)
{
d->m_lwjgllist.reset(new LWJGLVersionList());
}
return d->m_lwjgllist.get();
}
#include "Env.moc"

View File

@ -53,8 +53,6 @@ public:
shared_qobject_ptr<Meta::Index> metadataIndex();
LWJGLVersionList *getLegacyLWJGL();
QString getJarsPath();
void setJarsPath(const QString & path);
protected:

View File

@ -2,7 +2,6 @@
#include "settings/INISettingsObject.h"
#include "FileSystem.h"
#include "minecraft/onesix/OneSixInstance.h"
#include "minecraft/legacy/LegacyInstance.h"
#include "NullInstance.h"
#include <QDir>
@ -91,10 +90,6 @@ InstancePtr FolderInstanceProvider::loadInstance(const InstanceId& id)
{
inst.reset(new OneSixInstance(m_globalSettings, instanceSettings, instanceRoot));
}
else if (inst_type == "Legacy")
{
inst.reset(new LegacyInstance(m_globalSettings, instanceSettings, instanceRoot));
}
else
{
inst.reset(new NullInstance(m_globalSettings, instanceSettings, instanceRoot));

View File

@ -24,7 +24,6 @@
#include "multimc_logic_export.h"
class LegacyInstance;
class BaseInstance;
class QFileSystemWatcher;

View File

@ -1,521 +0,0 @@
/* Copyright 2013-2017 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 <QFileInfo>
#include <minecraft/launch/LauncherPartLaunch.h>
#include <QDir>
#include <settings/Setting.h>
#include "LegacyInstance.h"
#include "minecraft/legacy/LegacyUpdate.h"
#include "minecraft/legacy/LegacyModList.h"
#include "minecraft/ModList.h"
#include "minecraft/WorldList.h"
#include <MMCZip.h>
#include <FileSystem.h>
LegacyInstance::LegacyInstance(SettingsObjectPtr globalSettings, SettingsObjectPtr settings, const QString &rootDir)
: MinecraftInstance(globalSettings, settings, rootDir)
{
m_lwjglFolderSetting = globalSettings->getSetting("LWJGLDir");
settings->registerSetting("NeedsRebuild", true);
settings->registerSetting("ShouldUpdate", false);
settings->registerSetting("JarVersion", "Unknown");
settings->registerSetting("LwjglVersion", "2.9.0");
settings->registerSetting("IntendedJarVersion", "");
/*
* 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::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;
}
void LegacyInstance::setCustomBaseJar(QString val)
{
if (val.isNull() || val.isEmpty() || val == defaultCustomBaseJar())
m_settings->reset("CustomBaseJar");
else
m_settings->set("CustomBaseJar", val);
}
void LegacyInstance::setShouldUseCustomBaseJar(bool val)
{
m_settings->set("UseCustomBaseJar", val);
}
bool LegacyInstance::shouldUseCustomBaseJar() const
{
return m_settings->get("UseCustomBaseJar").toBool();
}
shared_qobject_ptr<Task> LegacyInstance::createUpdateTask()
{
// make sure the jar mods list is initialized by asking for it.
auto list = jarModList();
// create an update task
return shared_qobject_ptr<Task>(new LegacyUpdate(this, this));
}
class LegacyJarModTask : public Task
{
Q_OBJECT
public:
explicit LegacyJarModTask(std::shared_ptr<LegacyInstance> inst) : Task(nullptr), m_inst(inst)
{
}
virtual void executeTask()
{
if (!m_inst->shouldRebuild())
{
emitSucceeded();
return;
}
// Get the mod list
auto modList = m_inst->getJarMods();
QFileInfo runnableJar(m_inst->runnableJar());
QFileInfo baseJar(m_inst->baseJar());
bool base_is_custom = m_inst->shouldUseCustomBaseJar();
// Nothing to do if there are no jar mods to install, no backup and just the mc jar
if (base_is_custom)
{
// yes, this can happen if the instance only has the runnable jar and not the base jar
// it *could* be assumed that such an instance is vanilla, but that wouldn't be safe
// because that's not something mmc4 guarantees
if (runnableJar.isFile() && !baseJar.exists() && modList.empty())
{
m_inst->setShouldRebuild(false);
emitSucceeded();
return;
}
setStatus(tr("Installing mods: Backing up minecraft.jar ..."));
if (!baseJar.exists() && !QFile::copy(runnableJar.filePath(), baseJar.filePath()))
{
emitFailed("It seems both the active and base jar are gone. A fresh base jar will "
"be used on next run.");
m_inst->setShouldRebuild(true);
m_inst->setShouldUpdate(true);
m_inst->setShouldUseCustomBaseJar(false);
return;
}
}
if (!baseJar.exists())
{
emitFailed("The base jar " + baseJar.filePath() + " does not exist");
return;
}
if (runnableJar.exists() && !QFile::remove(runnableJar.filePath()))
{
emitFailed("Failed to delete old minecraft.jar");
return;
}
setStatus(tr("Installing mods: Opening minecraft.jar ..."));
QString outputJarPath = runnableJar.filePath();
QString inputJarPath = baseJar.filePath();
if(!MMCZip::createModdedJar(inputJarPath, outputJarPath, modList))
{
emitFailed(tr("Failed to create the custom Minecraft jar file."));
return;
}
m_inst->setShouldRebuild(false);
// inst->UpdateVersion(true);
emitSucceeded();
return;
}
std::shared_ptr<LegacyInstance> m_inst;
};
std::shared_ptr<Task> LegacyInstance::createJarModdingTask()
{
return std::make_shared<LegacyJarModTask>(std::dynamic_pointer_cast<LegacyInstance>(shared_from_this()));
}
QString LegacyInstance::createLaunchScript(AuthSessionPtr session)
{
QString launchScript;
// window size
QString windowParams;
if (settings()->get("LaunchMaximized").toBool())
{
windowParams = "max";
}
else
{
windowParams = QString("%1x%2").arg(settings()->get("MinecraftWinWidth").toInt()).arg(settings()->get("MinecraftWinHeight").toInt());
}
QString lwjgl = QDir(m_lwjglFolderSetting->get().toString() + "/" + lwjglVersion()).absolutePath();
launchScript += "userName " + session->player_name + "\n";
launchScript += "sessionId " + session->session + "\n";
launchScript += "windowTitle " + windowTitle() + "\n";
launchScript += "windowParams " + windowParams + "\n";
launchScript += "cp bin/minecraft.jar\n";
launchScript += "cp " + lwjgl + "/lwjgl.jar\n";
launchScript += "cp " + lwjgl + "/lwjgl_util.jar\n";
launchScript += "cp " + lwjgl + "/jinput.jar\n";
launchScript += "natives " + lwjgl + "/natives\n";
launchScript += "traits legacyLaunch\n";
launchScript += "launcher onesix\n";
return launchScript;
}
std::shared_ptr<LaunchStep> LegacyInstance::createMainLaunchStep(LaunchTask * parent, AuthSessionPtr session)
{
auto step = std::make_shared<LauncherPartLaunch>(parent);
step->setWorkingDirectory(minecraftRoot());
step->setAuthSession(session);
return step;
}
QString LegacyInstance::launchMethod()
{
return "Legacy";
}
QStringList LegacyInstance::validLaunchMethods()
{
return {"Legacy"};
}
std::shared_ptr<ModList> LegacyInstance::coreModList() const
{
if (!core_mod_list)
{
core_mod_list.reset(new ModList(coreModsDir()));
}
core_mod_list->update();
return core_mod_list;
}
std::shared_ptr<LegacyModList> LegacyInstance::jarModList() const
{
if (!jar_mod_list)
{
auto list = new LegacyModList(jarModsDir(), modListFile());
connect(list, SIGNAL(changed()), SLOT(jarModsChanged()));
jar_mod_list.reset(list);
}
jar_mod_list->update();
return jar_mod_list;
}
QList<Mod> LegacyInstance::getJarMods() const
{
return jarModList()->allMods();
}
void LegacyInstance::jarModsChanged()
{
qDebug() << "Jar mods of instance " << name() << " have changed. Jar will be rebuilt.";
setShouldRebuild(true);
}
std::shared_ptr<ModList> LegacyInstance::loaderModList() const
{
if (!loader_mod_list)
{
loader_mod_list.reset(new ModList(loaderModsDir()));
}
loader_mod_list->update();
return loader_mod_list;
}
std::shared_ptr<ModList> LegacyInstance::texturePackList() const
{
if (!texture_pack_list)
{
texture_pack_list.reset(new ModList(texturePacksDir()));
}
texture_pack_list->update();
return texture_pack_list;
}
std::shared_ptr<WorldList> LegacyInstance::worldList() const
{
if (!m_world_list)
{
m_world_list.reset(new WorldList(savesDir()));
}
return m_world_list;
}
QString LegacyInstance::jarModsDir() const
{
return FS::PathCombine(instanceRoot(), "instMods");
}
QString LegacyInstance::libDir() const
{
return FS::PathCombine(minecraftRoot(), "lib");
}
QString LegacyInstance::savesDir() const
{
return FS::PathCombine(minecraftRoot(), "saves");
}
QString LegacyInstance::loaderModsDir() const
{
return FS::PathCombine(minecraftRoot(), "mods");
}
QString LegacyInstance::coreModsDir() const
{
return FS::PathCombine(minecraftRoot(), "coremods");
}
QString LegacyInstance::resourceDir() const
{
return FS::PathCombine(minecraftRoot(), "resources");
}
QString LegacyInstance::texturePacksDir() const
{
return FS::PathCombine(minecraftRoot(), "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(minecraftRoot(), "config");
}
bool LegacyInstance::shouldRebuild() const
{
return m_settings->get("NeedsRebuild").toBool();
}
void LegacyInstance::setShouldRebuild(bool val)
{
m_settings->set("NeedsRebuild", val);
}
QString LegacyInstance::currentVersionId() const
{
return m_settings->get("JarVersion").toString();
}
QString LegacyInstance::lwjglVersion() const
{
return m_settings->get("LwjglVersion").toString();
}
void LegacyInstance::setLWJGLVersion(QString val)
{
m_settings->set("LwjglVersion", val);
}
QString LegacyInstance::intendedVersionId() const
{
return m_settings->get("IntendedJarVersion").toString();
}
bool LegacyInstance::setIntendedVersionId(QString version)
{
settings()->set("IntendedJarVersion", version);
setShouldUpdate(true);
return true;
}
bool LegacyInstance::shouldUpdate() const
{
QVariant var = settings()->get("ShouldUpdate");
if (!var.isValid() || var.toBool() == false)
{
return intendedVersionId() != currentVersionId();
}
return true;
}
void LegacyInstance::setShouldUpdate(bool val)
{
settings()->set("ShouldUpdate", val);
}
QString LegacyInstance::defaultBaseJar() const
{
return "versions/" + intendedVersionId() + "/" + intendedVersionId() + ".jar";
}
QString LegacyInstance::defaultCustomBaseJar() const
{
return FS::PathCombine(binRoot(), "mcbackup.jar");
}
QString LegacyInstance::lwjglFolder() const
{
return m_lwjglFolderSetting->get().toString();
}
QString LegacyInstance::typeName() const
{
return tr("Legacy");
}
QStringList LegacyInstance::verboseDescription(AuthSessionPtr session)
{
QStringList out;
auto alltraits = traits();
if(alltraits.size())
{
out << "Traits:";
for (auto trait : alltraits)
{
out << " " + trait;
}
out << "";
}
if(loaderModList()->size())
{
out << "Mods:";
for(auto & mod: loaderModList()->allMods())
{
if(!mod.enabled())
continue;
if(mod.type() == Mod::MOD_FOLDER)
continue;
// TODO: proper implementation would need to descend into folders.
out << " " + mod.filename().completeBaseName();
}
out << "";
}
if(coreModList()->size())
{
out << "Core Mods:";
for(auto & coremod: coreModList()->allMods())
{
if(!coremod.enabled())
continue;
if(coremod.type() == Mod::MOD_FOLDER)
continue;
// TODO: proper implementation would need to descend into folders.
out << " " + coremod.filename().completeBaseName();
}
out << "";
}
if(jarModList()->size())
{
out << "Jar Mods:";
for(auto & jarmod: jarModList()->allMods())
{
out << " " + jarmod.name() + " (" + jarmod.filename().filePath() + ")";
}
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;
}
QStringList LegacyInstance::getClassPath() const
{
QString launchScript;
QString lwjgl = getNativePath();
QStringList out =
{
"bin/minecraft.jar",
lwjgl + "/lwjgl.jar",
lwjgl + "/lwjgl_util.jar",
lwjgl + "/jinput.jar"
};
return out;
}
QString LegacyInstance::getMainClass() const
{
return "net.minecraft.client.Minecraft";
}
QString LegacyInstance::getNativePath() const
{
return QDir(m_lwjglFolderSetting->get().toString() + "/" + lwjglVersion()).absolutePath();
}
QStringList LegacyInstance::getNativeJars() const
{
return {};
}
QStringList LegacyInstance::processMinecraftArgs(AuthSessionPtr account) const
{
QStringList out;
out.append(account->player_name);
out.append(account->session);
return out;
}
#include "LegacyInstance.moc"

View File

@ -1,155 +0,0 @@
/* Copyright 2013-2017 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.
*/
#pragma once
#include "minecraft/MinecraftInstance.h"
#include "multimc_logic_export.h"
class ModList;
class LegacyModList;
class Task;
class MULTIMC_LOGIC_EXPORT LegacyInstance : public MinecraftInstance
{
Q_OBJECT
public:
explicit LegacyInstance(SettingsObjectPtr globalSettings, SettingsObjectPtr settings, const QString &rootDir);
virtual void init() override {};
/// Path to the instance's minecraft.jar
QString runnableJar() const;
//! Path to the instance's modlist file.
QString modListFile() const;
/*
////// Edit Instance Dialog stuff //////
virtual QList<BasePage *> getPages();
virtual QString dialogTitle();
*/
////// Mod Lists //////
std::shared_ptr<LegacyModList> jarModList() const ;
virtual QList< Mod > getJarMods() const override;
std::shared_ptr<ModList> coreModList() const;
std::shared_ptr<ModList> loaderModList() const;
std::shared_ptr<ModList> texturePackList() const override;
std::shared_ptr<WorldList> worldList() const override;
////// Directories //////
QString libDir() const;
QString savesDir() const;
QString texturePacksDir() const;
QString jarModsDir() const;
QString loaderModsDir() const;
QString coreModsDir() const;
QString resourceDir() const;
virtual QString instanceConfigFolder() const override;
/// Get the curent base jar of this instance. By default, it's the
/// versions/$version/$version.jar
QString baseJar() const;
/// the default base jar of this instance
QString defaultBaseJar() const;
/// the default custom base jar of this instance
QString defaultCustomBaseJar() const;
/*!
* Whether or not custom base jar is used
*/
bool shouldUseCustomBaseJar() const;
void setShouldUseCustomBaseJar(bool val);
/*!
* The value of the custom base jar
*/
QString customBaseJar() const;
void setCustomBaseJar(QString val);
/*!
* Whether or not the instance's minecraft.jar needs to be rebuilt.
* If this is true, when the instance launches, its jar mods will be
* re-added to a fresh minecraft.jar file.
*/
bool shouldRebuild() const;
void setShouldRebuild(bool val);
virtual QString currentVersionId() const override;
//! The version of LWJGL that this instance uses.
QString lwjglVersion() const;
//! Where the lwjgl versions foor this instance can be found... HACK HACK HACK
QString lwjglFolder() const;
/// st the version of LWJGL libs this instance will use
void setLWJGLVersion(QString val);
virtual QString intendedVersionId() const override;
virtual bool setIntendedVersionId(QString version) override;
virtual QSet<QString> traits() override
{
return {"legacy-instance", "texturepacks"};
};
virtual bool shouldUpdate() const override;
virtual void setShouldUpdate(bool val) override;
virtual shared_qobject_ptr<Task> createUpdateTask() override;
virtual std::shared_ptr<Task> createJarModdingTask() override;
virtual QString createLaunchScript(AuthSessionPtr session) override;
virtual QString typeName() const override;
bool canExport() const override
{
return true;
}
QStringList getClassPath() const override;
QString getMainClass() const override;
QStringList getNativeJars() const override;
QString getNativePath() const override;
QString getLocalLibraryPath() const override
{
return QString();
}
QStringList processMinecraftArgs(AuthSessionPtr account) const override;
QStringList verboseDescription(AuthSessionPtr session) override;
protected:
std::shared_ptr<LaunchStep> createMainLaunchStep(LaunchTask *parent, AuthSessionPtr session) override;
QStringList validLaunchMethods() override;
QString launchMethod() override;
protected:
mutable std::shared_ptr<LegacyModList> jar_mod_list;
mutable std::shared_ptr<ModList> core_mod_list;
mutable std::shared_ptr<ModList> loader_mod_list;
mutable std::shared_ptr<ModList> texture_pack_list;
mutable std::shared_ptr<WorldList> m_world_list;
std::shared_ptr<Setting> m_lwjglFolderSetting;
protected
slots:
virtual void jarModsChanged();
};

View File

@ -1,616 +0,0 @@
/* Copyright 2013-2017 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 "LegacyModList.h"
#include <FileSystem.h>
#include <QMimeData>
#include <QUrl>
#include <QUuid>
#include <QString>
#include <QFileSystemWatcher>
#include <QDebug>
LegacyModList::LegacyModList(const QString &dir, const QString &list_file)
: QAbstractListModel(), m_dir(dir), m_list_file(list_file)
{
FS::ensureFolderPathExists(m_dir.absolutePath());
m_dir.setFilter(QDir::Readable | QDir::NoDotAndDotDot | QDir::Files | QDir::Dirs |
QDir::NoSymLinks);
m_dir.setSorting(QDir::Name | QDir::IgnoreCase | QDir::LocaleAware);
m_list_id = QUuid::createUuid().toString();
m_watcher = new QFileSystemWatcher(this);
is_watching = false;
connect(m_watcher, SIGNAL(directoryChanged(QString)), this,
SLOT(directoryChanged(QString)));
}
void LegacyModList::startWatching()
{
update();
is_watching = m_watcher->addPath(m_dir.absolutePath());
if (is_watching)
{
qDebug() << "Started watching " << m_dir.absolutePath();
}
else
{
qDebug() << "Failed to start watching " << m_dir.absolutePath();
}
}
void LegacyModList::stopWatching()
{
is_watching = !m_watcher->removePath(m_dir.absolutePath());
if (!is_watching)
{
qDebug() << "Stopped watching " << m_dir.absolutePath();
}
else
{
qDebug() << "Failed to stop watching " << m_dir.absolutePath();
}
}
void LegacyModList::internalSort(QList<Mod> &what)
{
auto predicate = [](const Mod &left, const Mod &right)
{
if (left.name() == right.name())
{
return left.mmc_id().localeAwareCompare(right.mmc_id()) < 0;
}
return left.name().localeAwareCompare(right.name()) < 0;
};
std::sort(what.begin(), what.end(), predicate);
}
bool LegacyModList::update()
{
if (!isValid())
return false;
QList<Mod> orderedMods;
QList<Mod> newMods;
m_dir.refresh();
auto folderContents = m_dir.entryInfoList();
bool orderOrStateChanged = false;
// first, process the ordered items (if any)
OrderList listOrder = readListFile();
for (auto item : listOrder)
{
QFileInfo infoEnabled(m_dir.filePath(item.id));
QFileInfo infoDisabled(m_dir.filePath(item.id + ".disabled"));
int idxEnabled = folderContents.indexOf(infoEnabled);
int idxDisabled = folderContents.indexOf(infoDisabled);
bool isEnabled;
// if both enabled and disabled versions are present, it's a special case...
if (idxEnabled >= 0 && idxDisabled >= 0)
{
// we only process the one we actually have in the order file.
// and exactly as we have it.
// THIS IS A CORNER CASE
isEnabled = item.enabled;
}
else
{
// only one is present.
// we pick the one that we found.
// we assume the mod was enabled/disabled by external means
isEnabled = idxEnabled >= 0;
}
int idx = isEnabled ? idxEnabled : idxDisabled;
QFileInfo &info = isEnabled ? infoEnabled : infoDisabled;
// if the file from the index file exists
if (idx != -1)
{
// remove from the actual folder contents list
folderContents.takeAt(idx);
// append the new mod
orderedMods.append(Mod(info));
if (isEnabled != item.enabled)
orderOrStateChanged = true;
}
else
{
orderOrStateChanged = true;
}
}
// if there are any untracked files...
if (folderContents.size())
{
// the order surely changed!
for (auto entry : folderContents)
{
newMods.append(Mod(entry));
}
internalSort(newMods);
orderedMods.append(newMods);
orderOrStateChanged = true;
}
// otherwise, if we were already tracking some mods
else if (mods.size())
{
// if the number doesn't match, order changed.
if (mods.size() != orderedMods.size())
orderOrStateChanged = true;
// if it does match, compare the mods themselves
else
for (int i = 0; i < mods.size(); i++)
{
if (!mods[i].strongCompare(orderedMods[i]))
{
orderOrStateChanged = true;
break;
}
}
}
beginResetModel();
mods.swap(orderedMods);
endResetModel();
if (orderOrStateChanged && !m_list_file.isEmpty())
{
qDebug() << "Mod list " << m_list_file << " changed!";
saveListFile();
emit changed();
}
return true;
}
void LegacyModList::directoryChanged(QString path)
{
update();
}
LegacyModList::OrderList LegacyModList::readListFile()
{
OrderList itemList;
if (m_list_file.isNull() || m_list_file.isEmpty())
return itemList;
QFile textFile(m_list_file);
if (!textFile.open(QIODevice::ReadOnly | QIODevice::Text))
return OrderList();
QTextStream textStream;
textStream.setAutoDetectUnicode(true);
textStream.setDevice(&textFile);
while (true)
{
QString line = textStream.readLine();
if (line.isNull() || line.isEmpty())
break;
else
{
OrderItem it;
it.enabled = !line.endsWith(".disabled");
if (!it.enabled)
{
line.chop(9);
}
it.id = line;
itemList.append(it);
}
}
textFile.close();
return itemList;
}
bool LegacyModList::saveListFile()
{
if (m_list_file.isNull() || m_list_file.isEmpty())
return false;
QFile textFile(m_list_file);
if (!textFile.open(QIODevice::WriteOnly | QIODevice::Text | QIODevice::Truncate))
return false;
QTextStream textStream;
textStream.setGenerateByteOrderMark(true);
textStream.setCodec("UTF-8");
textStream.setDevice(&textFile);
for (auto mod : mods)
{
textStream << mod.mmc_id();
if (!mod.enabled())
textStream << ".disabled";
textStream << endl;
}
textFile.close();
return false;
}
bool LegacyModList::isValid()
{
return m_dir.exists() && m_dir.isReadable();
}
bool LegacyModList::installMod(const QString &filename, int index)
{
// NOTE: fix for GH-1178: remove trailing slash to avoid issues with using the empty result of QFileInfo::fileName
QFileInfo fileinfo(FS::NormalizePath(filename));
qDebug() << "installing: " << fileinfo.absoluteFilePath();
if (!fileinfo.exists() || !fileinfo.isReadable() || index < 0)
{
return false;
}
Mod m(fileinfo);
if (!m.valid())
return false;
// if it's already there, replace the original mod (in place)
int idx = mods.indexOf(m);
if (idx != -1)
{
int idx2 = mods.indexOf(m, idx + 1);
if (idx2 != -1)
return false;
if (mods[idx].replace(m))
{
auto left = this->index(index);
auto right = this->index(index, columnCount(QModelIndex()) - 1);
emit dataChanged(left, right);
saveListFile();
update();
return true;
}
return false;
}
auto type = m.type();
if (type == Mod::MOD_UNKNOWN)
return false;
if (type == Mod::MOD_SINGLEFILE || type == Mod::MOD_ZIPFILE || type == Mod::MOD_LITEMOD)
{
QString newpath = FS::PathCombine(m_dir.path(), fileinfo.fileName());
if (!QFile::copy(fileinfo.filePath(), newpath))
return false;
m.repath(newpath);
beginInsertRows(QModelIndex(), index, index);
mods.insert(index, m);
endInsertRows();
saveListFile();
update();
return true;
}
else if (type == Mod::MOD_FOLDER)
{
QString from = fileinfo.filePath();
QString to = FS::PathCombine(m_dir.path(), fileinfo.fileName());
if (!FS::copy(from, to)())
return false;
m.repath(to);
beginInsertRows(QModelIndex(), index, index);
mods.insert(index, m);
endInsertRows();
saveListFile();
update();
return true;
}
return false;
}
bool LegacyModList::deleteMod(int index)
{
if (index >= mods.size() || index < 0)
return false;
Mod &m = mods[index];
if (m.destroy())
{
beginRemoveRows(QModelIndex(), index, index);
mods.removeAt(index);
endRemoveRows();
saveListFile();
emit changed();
return true;
}
return false;
}
bool LegacyModList::deleteMods(int first, int last)
{
for (int i = first; i <= last; i++)
{
Mod &m = mods[i];
m.destroy();
}
beginRemoveRows(QModelIndex(), first, last);
mods.erase(mods.begin() + first, mods.begin() + last + 1);
endRemoveRows();
saveListFile();
emit changed();
return true;
}
bool LegacyModList::moveModTo(int from, int to)
{
if (from < 0 || from >= mods.size())
return false;
if (to >= rowCount())
to = rowCount() - 1;
if (to == -1)
to = rowCount() - 1;
if (from == to)
return false;
int togap = to > from ? to + 1 : to;
beginMoveRows(QModelIndex(), from, from, QModelIndex(), togap);
mods.move(from, to);
endMoveRows();
saveListFile();
emit changed();
return true;
}
bool LegacyModList::moveModUp(int from)
{
if (from > 0)
return moveModTo(from, from - 1);
return false;
}
bool LegacyModList::moveModsUp(int first, int last)
{
if (first == 0)
return false;
beginMoveRows(QModelIndex(), first, last, QModelIndex(), first - 1);
mods.move(first - 1, last);
endMoveRows();
saveListFile();
emit changed();
return true;
}
bool LegacyModList::moveModDown(int from)
{
if (from < 0)
return false;
if (from < mods.size() - 1)
return moveModTo(from, from + 1);
return false;
}
bool LegacyModList::moveModsDown(int first, int last)
{
if (last == mods.size() - 1)
return false;
beginMoveRows(QModelIndex(), first, last, QModelIndex(), last + 2);
mods.move(last + 1, first);
endMoveRows();
saveListFile();
emit changed();
return true;
}
int LegacyModList::columnCount(const QModelIndex &parent) const
{
return 3;
}
QVariant LegacyModList::data(const QModelIndex &index, int role) const
{
if (!index.isValid())
return QVariant();
int row = index.row();
int column = index.column();
if (row < 0 || row >= mods.size())
return QVariant();
switch (role)
{
case Qt::DisplayRole:
switch (column)
{
case NameColumn:
return mods[row].name();
case VersionColumn:
return mods[row].version();
default:
return QVariant();
}
case Qt::ToolTipRole:
return mods[row].mmc_id();
case Qt::CheckStateRole:
switch (column)
{
case ActiveColumn:
return mods[row].enabled() ? Qt::Checked : Qt::Unchecked;
default:
return QVariant();
}
default:
return QVariant();
}
}
bool LegacyModList::setData(const QModelIndex &index, const QVariant &value, int role)
{
if (index.row() < 0 || index.row() >= rowCount(index) || !index.isValid())
{
return false;
}
if (role == Qt::CheckStateRole)
{
auto &mod = mods[index.row()];
if (mod.enable(!mod.enabled()))
{
emit dataChanged(index, index);
return true;
}
}
return false;
}
QVariant LegacyModList::headerData(int section, Qt::Orientation orientation, int role) const
{
switch (role)
{
case Qt::DisplayRole:
switch (section)
{
case ActiveColumn:
return QString();
case NameColumn:
return tr("Name");
case VersionColumn:
return tr("Version");
default:
return QVariant();
}
case Qt::ToolTipRole:
switch (section)
{
case ActiveColumn:
return tr("Is the mod enabled?");
case NameColumn:
return tr("The name of the mod.");
case VersionColumn:
return tr("The version of the mod.");
default:
return QVariant();
}
default:
return QVariant();
}
return QVariant();
}
Qt::ItemFlags LegacyModList::flags(const QModelIndex &index) const
{
Qt::ItemFlags defaultFlags = QAbstractListModel::flags(index);
if (index.isValid())
return Qt::ItemIsUserCheckable | Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled |
defaultFlags;
else
return Qt::ItemIsDropEnabled | defaultFlags;
}
QStringList LegacyModList::mimeTypes() const
{
QStringList types;
types << "text/uri-list";
types << "text/plain";
return types;
}
Qt::DropActions LegacyModList::supportedDropActions() const
{
// copy from outside, move from within and other mod lists
return Qt::CopyAction | Qt::MoveAction;
}
Qt::DropActions LegacyModList::supportedDragActions() const
{
// move to other mod lists or VOID
return Qt::MoveAction;
}
QMimeData *LegacyModList::mimeData(const QModelIndexList &indexes) const
{
QMimeData *data = new QMimeData();
if (indexes.size() == 0)
return data;
auto idx = indexes[0];
int row = idx.row();
if (row < 0 || row >= mods.size())
return data;
QStringList params;
params << m_list_id << QString::number(row);
data->setText(params.join('|'));
return data;
}
bool LegacyModList::dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column,
const QModelIndex &parent)
{
if (action == Qt::IgnoreAction)
return true;
// check if the action is supported
if (!data || !(action & supportedDropActions()))
return false;
if (parent.isValid())
{
row = parent.row();
column = parent.column();
}
if (row > rowCount())
row = rowCount();
if (row == -1)
row = rowCount();
if (column == -1)
column = 0;
qDebug() << "Drop row: " << row << " column: " << column;
// files dropped from outside?
if (data->hasUrls())
{
bool was_watching = is_watching;
if (was_watching)
stopWatching();
auto urls = data->urls();
for (auto url : urls)
{
// only local files may be dropped...
if (!url.isLocalFile())
continue;
QString filename = url.toLocalFile();
installMod(filename, row);
// if there is no ordering, re-sort the list
if (m_list_file.isEmpty())
{
beginResetModel();
internalSort(mods);
endResetModel();
}
}
if (was_watching)
startWatching();
return true;
}
else if (data->hasText())
{
QString sourcestr = data->text();
auto list = sourcestr.split('|');
if (list.size() != 2)
return false;
QString remoteId = list[0];
int remoteIndex = list[1].toInt();
qDebug() << "move: " << sourcestr;
// no moving of things between two lists
if (remoteId != m_list_id)
return false;
// no point moving to the same place...
if (row == remoteIndex)
return false;
// otherwise, move the mod :D
moveModTo(remoteIndex, row);
return true;
}
return false;
}

View File

@ -1,160 +0,0 @@
/* Copyright 2013-2017 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.
*/
#pragma once
#include <QList>
#include <QString>
#include <QDir>
#include <QAbstractListModel>
#include "minecraft/Mod.h"
#include "multimc_logic_export.h"
class LegacyInstance;
class BaseInstance;
class QFileSystemWatcher;
/**
* A legacy mod list.
* Backed by a folder.
*/
class MULTIMC_LOGIC_EXPORT LegacyModList : public QAbstractListModel
{
Q_OBJECT
public:
enum Columns
{
ActiveColumn = 0,
NameColumn,
VersionColumn
};
LegacyModList(const QString &dir, const QString &list_file = QString());
virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
virtual bool setData(const QModelIndex &index, const QVariant &value,
int role = Qt::EditRole);
virtual int rowCount(const QModelIndex &parent = QModelIndex()) const
{
return size();
}
;
virtual QVariant headerData(int section, Qt::Orientation orientation,
int role = Qt::DisplayRole) const;
virtual int columnCount(const QModelIndex &parent) const;
size_t size() const
{
return mods.size();
}
;
bool empty() const
{
return size() == 0;
}
Mod &operator[](size_t index)
{
return mods[index];
}
/// Reloads the mod list and returns true if the list changed.
virtual bool update();
/**
* Adds the given mod to the list at the given index - if the list supports custom ordering
*/
virtual bool installMod(const QString & filename, int index = 0);
/// Deletes the mod at the given index.
virtual bool deleteMod(int index);
/// Deletes all the selected mods
virtual bool deleteMods(int first, int last);
/**
* move the mod at index to the position N
* 0 is the beginning of the list, length() is the end of the list.
*/
virtual bool moveModTo(int from, int to);
/**
* move the mod at index one position upwards
*/
virtual bool moveModUp(int from);
virtual bool moveModsUp(int first, int last);
/**
* move the mod at index one position downwards
*/
virtual bool moveModDown(int from);
virtual bool moveModsDown(int first, int last);
/// flags, mostly to support drag&drop
virtual Qt::ItemFlags flags(const QModelIndex &index) const;
/// get data for drag action
virtual QMimeData *mimeData(const QModelIndexList &indexes) const;
/// get the supported mime types
virtual QStringList mimeTypes() const;
/// process data from drop action
virtual bool dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column,
const QModelIndex &parent);
/// what drag actions do we support?
virtual Qt::DropActions supportedDragActions() const;
/// what drop actions do we support?
virtual Qt::DropActions supportedDropActions() const;
void startWatching();
void stopWatching();
virtual bool isValid();
QDir dir()
{
return m_dir;
}
const QList<Mod> & allMods()
{
return mods;
}
private:
void internalSort(QList<Mod> & what);
struct OrderItem
{
QString id;
bool enabled = false;
};
typedef QList<OrderItem> OrderList;
OrderList readListFile();
bool saveListFile();
private
slots:
void directoryChanged(QString path);
signals:
void changed();
protected:
QFileSystemWatcher *m_watcher;
bool is_watching;
QDir m_dir;
QString m_list_file;
QString m_list_id;
QList<Mod> mods;
};

View File

@ -1,399 +0,0 @@
/* Copyright 2013-2017 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 <QStringList>
#include <quazip.h>
#include <quazipfile.h>
#include <QDebug>
#include "Env.h"
#include "BaseInstance.h"
#include "net/URLConstants.h"
#include "MMCZip.h"
#include "LegacyUpdate.h"
#include "LegacyModList.h"
#include "LwjglVersionList.h"
#include "LegacyInstance.h"
#include <FileSystem.h>
LegacyUpdate::LegacyUpdate(BaseInstance *inst, QObject *parent) : Task(parent), m_inst(inst)
{
}
void LegacyUpdate::executeTask()
{
fmllibsStart();
}
void LegacyUpdate::fmllibsStart()
{
// Get the mod list
LegacyInstance *inst = (LegacyInstance *)m_inst;
auto modList = inst->jarModList();
bool forge_present = false;
QString version = inst->intendedVersionId();
auto & fmlLibsMapping = g_VersionFilterData.fmlLibsMapping;
if (!fmlLibsMapping.contains(version))
{
lwjglStart();
return;
}
auto &libList = fmlLibsMapping[version];
// determine if we need some libs for FML or forge
setStatus(tr("Checking for FML libraries..."));
for (unsigned i = 0; i < modList->size(); i++)
{
auto &mod = modList->operator[](i);
// do not use disabled mods.
if (!mod.enabled())
continue;
if (mod.type() != Mod::MOD_ZIPFILE)
continue;
if (mod.mmc_id().contains("forge", Qt::CaseInsensitive))
{
forge_present = true;
break;
}
if (mod.mmc_id().contains("fml", Qt::CaseInsensitive))
{
forge_present = true;
break;
}
}
// we don't...
if (!forge_present)
{
lwjglStart();
return;
}
// now check the lib folder inside the instance for files.
for (auto &lib : libList)
{
QFileInfo libInfo(FS::PathCombine(inst->libDir(), lib.filename));
if (libInfo.exists())
continue;
fmlLibsToProcess.append(lib);
}
// if everything is in place, there's nothing to do here...
if (fmlLibsToProcess.isEmpty())
{
lwjglStart();
return;
}
// download missing libs to our place
setStatus(tr("Dowloading FML libraries..."));
auto dljob = new NetJob("FML libraries");
auto metacache = ENV.metacache();
for (auto &lib : fmlLibsToProcess)
{
auto entry = metacache->resolveEntry("fmllibs", lib.filename);
QString urlString = lib.ours ? URLConstants::FMLLIBS_OUR_BASE_URL + lib.filename
: URLConstants::FMLLIBS_FORGE_BASE_URL + lib.filename;
dljob->addNetAction(Net::Download::makeCached(QUrl(urlString), entry));
}
connect(dljob, &NetJob::succeeded, this, &LegacyUpdate::fmllibsFinished);
connect(dljob, &NetJob::failed, this, &LegacyUpdate::fmllibsFailed);
connect(dljob, &NetJob::progress, this, &LegacyUpdate::progress);
legacyDownloadJob.reset(dljob);
legacyDownloadJob->start();
}
void LegacyUpdate::fmllibsFinished()
{
legacyDownloadJob.reset();
if(!fmlLibsToProcess.isEmpty())
{
setStatus(tr("Copying FML libraries into the instance..."));
LegacyInstance *inst = (LegacyInstance *)m_inst;
auto metacache = ENV.metacache();
int index = 0;
for (auto &lib : fmlLibsToProcess)
{
progress(index, fmlLibsToProcess.size());
auto entry = metacache->resolveEntry("fmllibs", lib.filename);
auto path = FS::PathCombine(inst->libDir(), lib.filename);
if(!FS::ensureFilePathExists(path))
{
emitFailed(tr("Failed creating FML library folder inside the instance."));
return;
}
if (!QFile::copy(entry->getFullPath(), FS::PathCombine(inst->libDir(), lib.filename)))
{
emitFailed(tr("Failed copying Forge/FML library: %1.").arg(lib.filename));
return;
}
index++;
}
progress(index, fmlLibsToProcess.size());
}
lwjglStart();
}
void LegacyUpdate::fmllibsFailed(QString reason)
{
emitFailed(tr("Game update failed: it was impossible to fetch the required FML libraries. Reason: %1").arg(reason));
return;
}
void LegacyUpdate::lwjglStart()
{
LegacyInstance *inst = (LegacyInstance *)m_inst;
auto list = ENV.getLegacyLWJGL();
if (!list->isLoaded())
{
setStatus(tr("Checking the LWJGL version list..."));
list->loadList();
auto task = list->getLoadTask();
connect(task.get(), &Task::succeeded, this, &LegacyUpdate::lwjglStart);
connect(task.get(), &Task::failed, this, [&](const QString & error)
{
emitFailed(tr("Failed to refresh LWJGL list: %1.").arg(error));
});
return;
}
lwjglVersion = inst->lwjglVersion();
lwjglTargetPath = FS::PathCombine(inst->lwjglFolder(), lwjglVersion);
lwjglNativesPath = FS::PathCombine(lwjglTargetPath, "natives");
// if the 'done' file exists, we don't have to download this again
QFileInfo doneFile(FS::PathCombine(lwjglTargetPath, "done"));
if (doneFile.exists())
{
jarStart();
return;
}
setStatus(tr("Downloading new LWJGL..."));
auto version = std::dynamic_pointer_cast<LWJGLVersion>(list->findVersion(lwjglVersion));
if (!version)
{
emitFailed(QString("Game update failed: the selected LWJGL version is invalid: %1").arg(lwjglVersion));
return;
}
QString url = version->url();
QUrl realUrl(url);
QString hostname = realUrl.host();
auto worker = &ENV.qnam();
QNetworkRequest req(realUrl);
req.setRawHeader("Host", hostname.toLatin1());
req.setHeader(QNetworkRequest::UserAgentHeader, "MultiMC/5.0 (Cached)");
QNetworkReply *rep = worker->get(req);
m_reply = std::shared_ptr<QNetworkReply>(rep);
connect(rep, &QNetworkReply::downloadProgress, this, &LegacyUpdate::progress);
connect(worker, &QNetworkAccessManager::finished, this, &LegacyUpdate::lwjglFinished);
}
void LegacyUpdate::lwjglFinished(QNetworkReply *reply)
{
if (m_reply.get() != reply)
{
return;
}
if (reply->error() != QNetworkReply::NoError)
{
emitFailed("Failed to download: " + reply->errorString() +
"\nSometimes you have to wait a bit if you download many LWJGL versions in "
"a row. YMMV");
return;
}
auto worker = &ENV.qnam();
// Here i check if there is a cookie for me in the reply and extract it
QList<QNetworkCookie> cookies =
qvariant_cast<QList<QNetworkCookie>>(reply->header(QNetworkRequest::SetCookieHeader));
if (cookies.count() != 0)
{
// you must tell which cookie goes with which url
worker->cookieJar()->setCookiesFromUrl(cookies, QUrl("sourceforge.net"));
}
// here you can check for the 302 or whatever other header i need
QVariant newLoc = reply->header(QNetworkRequest::LocationHeader);
if (newLoc.isValid())
{
QString redirectedTo = reply->header(QNetworkRequest::LocationHeader).toString();
QUrl realUrl(redirectedTo);
QString hostname = realUrl.host();
QNetworkRequest req(redirectedTo);
req.setRawHeader("Host", hostname.toLatin1());
req.setHeader(QNetworkRequest::UserAgentHeader, "MultiMC/5.0 (Cached)");
QNetworkReply *rep = worker->get(req);
connect(rep, &QNetworkReply::downloadProgress, this, &LegacyUpdate::progress);
m_reply = std::shared_ptr<QNetworkReply>(rep);
return;
}
QFile saveMe("lwjgl.zip");
saveMe.open(QIODevice::WriteOnly);
saveMe.write(m_reply->readAll());
saveMe.close();
setStatus(tr("Installing new LWJGL..."));
extractLwjgl();
jarStart();
}
void LegacyUpdate::extractLwjgl()
{
// make sure the directories are there
bool success = FS::ensureFolderPathExists(lwjglNativesPath);
if (!success)
{
emitFailed("Failed to extract the lwjgl libs - error when creating required folders.");
return;
}
QuaZip zip("lwjgl.zip");
if (!zip.open(QuaZip::mdUnzip))
{
emitFailed("Failed to extract the lwjgl libs - not a valid archive.");
return;
}
// and now we are going to access files inside it
QuaZipFile file(&zip);
const QString jarNames[] = {"jinput.jar", "lwjgl_util.jar", "lwjgl.jar"};
for (bool more = zip.goToFirstFile(); more; more = zip.goToNextFile())
{
if (!file.open(QIODevice::ReadOnly))
{
zip.close();
emitFailed("Failed to extract the lwjgl libs - error while reading archive.");
return;
}
QuaZipFileInfo info;
QString name = file.getActualFileName();
if (name.endsWith('/'))
{
file.close();
continue;
}
QString destFileName;
// Look for the jars
for (int i = 0; i < 3; i++)
{
if (name.endsWith(jarNames[i]))
{
destFileName = FS::PathCombine(lwjglTargetPath, jarNames[i]);
}
}
// Not found? look for the natives
if (destFileName.isEmpty())
{
#ifdef Q_OS_WIN32
QString nativesDir = "windows";
#else
#ifdef Q_OS_MAC
QString nativesDir = "macosx";
#else
QString nativesDir = "linux";
#endif
#endif
if (name.contains(nativesDir))
{
int lastSlash = name.lastIndexOf('/');
int lastBackSlash = name.lastIndexOf('\\');
if (lastSlash != -1)
name = name.mid(lastSlash + 1);
else if (lastBackSlash != -1)
name = name.mid(lastBackSlash + 1);
destFileName = FS::PathCombine(lwjglNativesPath, name);
}
}
// Now if destFileName is still empty, go to the next file.
if (!destFileName.isEmpty())
{
setStatus(tr("Installing new LWJGL - extracting ") + name + "...");
QFile output(destFileName);
output.open(QIODevice::WriteOnly);
output.write(file.readAll());
output.close();
}
file.close(); // do not forget to close!
}
zip.close();
m_reply.reset();
QFile doneFile(FS::PathCombine(lwjglTargetPath, "done"));
doneFile.open(QIODevice::WriteOnly);
doneFile.write("done.");
doneFile.close();
}
void LegacyUpdate::lwjglFailed(QString reason)
{
emitFailed(tr("Bad stuff happened while trying to get the lwjgl libs: %1").arg(reason));
}
void LegacyUpdate::jarStart()
{
LegacyInstance *inst = (LegacyInstance *)m_inst;
if (!inst->shouldUpdate() || inst->shouldUseCustomBaseJar())
{
emitSucceeded();
return;
}
setStatus(tr("Checking for jar updates..."));
// Make directories
QDir binDir(inst->binRoot());
if (!binDir.exists() && !binDir.mkpath("."))
{
emitFailed("Failed to create bin folder.");
return;
}
// Build a list of URLs that will need to be downloaded.
setStatus(tr("Downloading new minecraft.jar ..."));
QString version_id = inst->intendedVersionId();
auto dljob = new NetJob("Minecraft.jar for version " + version_id);
auto metacache = ENV.metacache();
auto entry = metacache->resolveEntry("versions", URLConstants::getJarPath(version_id));
dljob->addNetAction(Net::Download::makeCached(QUrl(URLConstants::getLegacyJarUrl(version_id)), entry));
connect(dljob, SIGNAL(succeeded()), SLOT(jarFinished()));
connect(dljob, SIGNAL(failed(QString)), SLOT(jarFailed(QString)));
connect(dljob, SIGNAL(progress(qint64, qint64)), SIGNAL(progress(qint64, qint64)));
legacyDownloadJob.reset(dljob);
legacyDownloadJob->start();
}
void LegacyUpdate::jarFinished()
{
// process the jar
emitSucceeded();
}
void LegacyUpdate::jarFailed(QString reason)
{
// bad, bad
emitFailed(tr("Failed to download the minecraft jar: %1.").arg(reason));
}

View File

@ -1,70 +0,0 @@
/* Copyright 2013-2017 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.
*/
#pragma once
#include <QObject>
#include <QList>
#include <QUrl>
#include "net/NetJob.h"
#include "tasks/Task.h"
#include "minecraft/VersionFilterData.h"
class MinecraftVersion;
class BaseInstance;
class QuaZip;
class Mod;
class LegacyUpdate : public Task
{
Q_OBJECT
public:
explicit LegacyUpdate(BaseInstance *inst, QObject *parent = 0);
virtual void executeTask();
private
slots:
void lwjglStart();
void lwjglFinished(QNetworkReply *);
void lwjglFailed(QString reason);
void jarStart();
void jarFinished();
void jarFailed(QString reason);
void fmllibsStart();
void fmllibsFinished();
void fmllibsFailed(QString reason);
void extractLwjgl();
private:
std::shared_ptr<QNetworkReply> m_reply;
// target version, determined during this task
// MinecraftVersion *targetVersion;
QString lwjglURL;
QString lwjglVersion;
QString lwjglTargetPath;
QString lwjglNativesPath;
private:
NetJobPtr legacyDownloadJob;
BaseInstance *m_inst = nullptr;
QList<FMLlib> fmlLibsToProcess;
};

View File

@ -1,169 +0,0 @@
/* Copyright 2013-2017 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 "LwjglVersionList.h"
#include "Env.h"
#include <QtNetwork>
#include <QtXml>
#include <QRegExp>
#include <QDebug>
#define RSS_URL "https://sourceforge.net/projects/java-game-lib/rss"
LWJGLVersionList::LWJGLVersionList(QObject *parent) : BaseVersionList(parent)
{
}
QVariant LWJGLVersionList::data(const QModelIndex &index, int role) const
{
if (!index.isValid())
return QVariant();
if (index.row() > count())
return QVariant();
const PtrLWJGLVersion version = m_vlist.at(index.row());
switch (role)
{
case Qt::DisplayRole:
return version->name();
case Qt::ToolTipRole:
return version->url();
default:
return QVariant();
}
}
QVariant LWJGLVersionList::headerData(int section, Qt::Orientation orientation, int role) const
{
switch (role)
{
case Qt::DisplayRole:
return tr("Version");
case Qt::ToolTipRole:
return tr("LWJGL version name.");
default:
return QVariant();
}
}
int LWJGLVersionList::columnCount(const QModelIndex &parent) const
{
return 1;
}
void LWJGLVersionList::loadList()
{
if(m_loading)
{
return;
}
m_loading = true;
qDebug() << "Downloading LWJGL RSS...";
m_rssDLJob.reset(new NetJob("LWJGL RSS"));
m_rssDL = Net::Download::makeByteArray(QUrl(RSS_URL), &m_rssData);
m_rssDLJob->addNetAction(m_rssDL);
connect(m_rssDLJob.get(), &NetJob::failed, this, &LWJGLVersionList::rssFailed);
connect(m_rssDLJob.get(), &NetJob::succeeded, this, &LWJGLVersionList::rssSucceeded);
m_rssDLJob->start();
}
inline QDomElement getDomElementByTagName(QDomElement parent, QString tagname)
{
QDomNodeList elementList = parent.elementsByTagName(tagname);
if (elementList.count())
return elementList.at(0).toElement();
else
return QDomElement();
}
void LWJGLVersionList::rssFailed(const QString& reason)
{
m_rssDLJob.reset();
m_loading = false;
qWarning() << "Failed to load LWJGL list. Network error: " + reason;
}
void LWJGLVersionList::rssSucceeded()
{
QRegExp lwjglRegex("lwjgl-(([0-9]\\.?)+)\\.zip");
Q_ASSERT_X(lwjglRegex.isValid(), "load LWJGL list", "LWJGL regex is invalid");
QDomDocument doc;
QString xmlErrorMsg;
int errorLine;
if (!doc.setContent(m_rssData, false, &xmlErrorMsg, &errorLine))
{
qWarning() << "Failed to load LWJGL list. XML error: " + xmlErrorMsg + " at line " + QString::number(errorLine);
m_rssDLJob.reset();
m_rssData.clear();
m_loading = false;
return;
}
m_rssData.clear();
QDomNodeList items = doc.elementsByTagName("item");
QList<PtrLWJGLVersion> tempList;
for (int i = 0; i < items.length(); i++)
{
Q_ASSERT_X(items.at(i).isElement(), "load LWJGL list", "XML element isn't an element... wat?");
QDomElement linkElement = getDomElementByTagName(items.at(i).toElement(), "link");
if (linkElement.isNull())
{
qDebug() << "Link element" << i << "in RSS feed doesn't exist! Skipping.";
continue;
}
QString link = linkElement.text();
// Make sure it's a download link.
if (link.endsWith("/download") && link.contains(lwjglRegex))
{
QString name = link.mid(lwjglRegex.indexIn(link) + 6);
// Subtract 4 here to remove the .zip file extension.
name = name.left(lwjglRegex.matchedLength() - 10);
QUrl url(link);
if (!url.isValid())
{
qWarning() << "LWJGL version URL isn't valid:" << link << "Skipping.";
continue;
}
qDebug() << "Discovered LWGL version" << name << "at" << link;
tempList.append(std::make_shared<LWJGLVersion>(name, link));
}
}
beginResetModel();
m_vlist.swap(tempList);
endResetModel();
qDebug() << "Loaded LWJGL list.";
m_rssDLJob.reset();
m_loading = false;
}

View File

@ -1,116 +0,0 @@
/* Copyright 2013-2017 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.
*/
#pragma once
#include <QObject>
#include <QAbstractListModel>
#include <QUrl>
#include <QNetworkReply>
#include <memory>
#include "BaseVersion.h"
#include "BaseVersionList.h"
#include "multimc_logic_export.h"
#include <net/NetJob.h>
class LWJGLVersion;
typedef std::shared_ptr<LWJGLVersion> PtrLWJGLVersion;
class MULTIMC_LOGIC_EXPORT LWJGLVersion : public BaseVersion
{
public:
LWJGLVersion(const QString &name, const QString &url)
: m_name(name), m_url(url)
{
}
virtual QString descriptor()
{
return m_name;
}
virtual QString name()
{
return m_name;
}
virtual QString typeString() const
{
return QObject::tr("Upstream");
}
QString url() const
{
return m_url;
}
protected:
QString m_name;
QString m_url;
};
class MULTIMC_LOGIC_EXPORT LWJGLVersionList : public BaseVersionList
{
Q_OBJECT
public:
explicit LWJGLVersionList(QObject *parent = 0);
bool isLoaded() override
{
return m_vlist.length() > 0;
}
virtual const BaseVersionPtr at(int i) const override
{
return m_vlist[i];
}
virtual shared_qobject_ptr<Task> getLoadTask() override
{
return m_rssDLJob;
}
virtual void sortVersions() override {};
virtual void updateListData(QList< BaseVersionPtr > versions) override {};
int count() const override
{
return m_vlist.length();
}
virtual QVariant data(const QModelIndex &index, int role) const override;
virtual QVariant headerData(int section, Qt::Orientation orientation, int role) const override;
virtual int rowCount(const QModelIndex &parent) const override
{
return count();
}
virtual int columnCount(const QModelIndex &parent) const override;
public slots:
virtual void loadList();
private slots:
void rssFailed(const QString & reason);
void rssSucceeded();
private:
QList<PtrLWJGLVersion> m_vlist;
Net::Download::Ptr m_rssDL;
NetJobPtr m_rssDLJob;
QByteArray m_rssData;
bool m_loading = false;
};

View File

@ -131,10 +131,6 @@ SET(MULTIMC_SOURCES
pages/ScreenshotsPage.h
pages/OtherLogsPage.cpp
pages/OtherLogsPage.h
pages/LegacyJarModPage.cpp
pages/LegacyJarModPage.h
pages/LegacyUpgradePage.cpp
pages/LegacyUpgradePage.h
pages/WorldListPage.cpp
pages/WorldListPage.h
@ -241,8 +237,6 @@ SET(MULTIMC_UIS
pages/NotesPage.ui
pages/ScreenshotsPage.ui
pages/OtherLogsPage.ui
pages/LegacyJarModPage.ui
pages/LegacyUpgradePage.ui
pages/WorldListPage.ui
# Global settings pages

View File

@ -1,6 +1,5 @@
#pragma once
#include "minecraft/onesix/OneSixInstance.h"
#include "minecraft/legacy/LegacyInstance.h"
#include <FileSystem.h>
#include "pages/BasePage.h"
#include "pages/LogPage.h"
@ -13,7 +12,6 @@
#include "pages/InstanceSettingsPage.h"
#include "pages/OtherLogsPage.h"
#include "pages/BasePageProvider.h"
#include "pages/LegacyJarModPage.h"
#include "pages/WorldListPage.h"
@ -46,22 +44,6 @@ public:
values.append(new ScreenshotsPage(FS::PathCombine(onesix->minecraftRoot(), "screenshots")));
values.append(new InstanceSettingsPage(onesix.get()));
}
std::shared_ptr<LegacyInstance> legacy = std::dynamic_pointer_cast<LegacyInstance>(inst);
if(legacy)
{
// FIXME: actually implement the legacy instance upgrade, then enable this.
//values.append(new LegacyUpgradePage(this));
values.append(new LegacyJarModPage(legacy.get()));
auto modsPage = new ModFolderPage(legacy.get(), legacy->loaderModList(), "mods", "loadermods", tr("Loader mods"), "Loader-mods");
modsPage->setFilter("%1 (*.zip *.jar *.litemod)");
values.append(modsPage);
values.append(new ModFolderPage(legacy.get(), legacy->coreModList(), "coremods", "coremods", tr("Core mods"), "Loader-mods"));
values.append(new TexturePackPage(legacy.get()));
values.append(new NotesPage(legacy.get()));
values.append(new WorldListPage(legacy.get(), legacy->worldList(), "worlds", "worlds", tr("Worlds"), "Worlds"));
values.append(new ScreenshotsPage(FS::PathCombine(legacy->minecraftRoot(), "screenshots")));
values.append(new InstanceSettingsPage(legacy.get()));
}
auto logMatcher = inst->getLogFileMatcher();
if(logMatcher)
{

View File

@ -54,7 +54,6 @@
#include <java/JavaUtils.h>
#include <java/JavaInstallList.h>
#include <launch/LaunchTask.h>
#include <minecraft/legacy/LwjglVersionList.h>
#include <minecraft/auth/MojangAccountList.h>
#include <SkinUtils.h>
#include <net/URLConstants.h>

View File

@ -1,162 +0,0 @@
/* Copyright 2013-2017 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 "LegacyJarModPage.h"
#include "ui_LegacyJarModPage.h"
#include <QKeyEvent>
#include <QKeyEvent>
#include "dialogs/VersionSelectDialog.h"
#include "dialogs/ProgressDialog.h"
#include "dialogs/ModEditDialogCommon.h"
#include "minecraft/legacy/LegacyModList.h"
#include "minecraft/legacy/LegacyInstance.h"
#include "Env.h"
#include <DesktopServices.h>
#include "MultiMC.h"
#include <GuiUtil.h>
LegacyJarModPage::LegacyJarModPage(LegacyInstance *inst, QWidget *parent)
: QWidget(parent), ui(new Ui::LegacyJarModPage), m_inst(inst)
{
ui->setupUi(this);
ui->tabWidget->tabBar()->hide();
m_jarmods = m_inst->jarModList();
ui->jarModsTreeView->setModel(m_jarmods.get());
ui->jarModsTreeView->setDragDropMode(QAbstractItemView::DragDrop);
ui->jarModsTreeView->setSelectionMode(QAbstractItemView::SingleSelection);
ui->jarModsTreeView->installEventFilter(this);
m_jarmods->startWatching();
auto smodel = ui->jarModsTreeView->selectionModel();
connect(smodel, SIGNAL(currentChanged(QModelIndex, QModelIndex)),
SLOT(jarCurrent(QModelIndex, QModelIndex)));
}
LegacyJarModPage::~LegacyJarModPage()
{
m_jarmods->stopWatching();
delete ui;
}
bool LegacyJarModPage::shouldDisplay() const
{
return !m_inst->isRunning();
}
bool LegacyJarModPage::eventFilter(QObject *obj, QEvent *ev)
{
if (ev->type() != QEvent::KeyPress || obj != ui->jarModsTreeView)
{
return QWidget::eventFilter(obj, ev);
}
QKeyEvent *keyEvent = static_cast<QKeyEvent *>(ev);
switch (keyEvent->key())
{
case Qt::Key_Up:
{
if (keyEvent->modifiers() & Qt::ControlModifier)
{
on_moveJarUpBtn_clicked();
return true;
}
break;
}
case Qt::Key_Down:
{
if (keyEvent->modifiers() & Qt::ControlModifier)
{
on_moveJarDownBtn_clicked();
return true;
}
break;
}
case Qt::Key_Delete:
on_rmJarBtn_clicked();
return true;
case Qt::Key_Plus:
on_addJarBtn_clicked();
return true;
default:
break;
}
return QWidget::eventFilter(obj, ev);
}
void LegacyJarModPage::on_addJarBtn_clicked()
{
auto list = GuiUtil::BrowseForFiles("jarmod", tr("Select jar mods"), tr("Minecraft.jar mods (*.zip *.jar)"), MMC->settings()->get("CentralModsDir").toString(), this->parentWidget());
if(!list.empty())
{
m_jarmods->stopWatching();
for (auto filename : list)
{
m_jarmods->installMod(filename);
}
m_jarmods->startWatching();
}
}
void LegacyJarModPage::on_moveJarDownBtn_clicked()
{
int first, last;
auto list = ui->jarModsTreeView->selectionModel()->selectedRows();
if (!lastfirst(list, first, last))
return;
m_jarmods->moveModsDown(first, last);
}
void LegacyJarModPage::on_moveJarUpBtn_clicked()
{
int first, last;
auto list = ui->jarModsTreeView->selectionModel()->selectedRows();
if (!lastfirst(list, first, last))
return;
m_jarmods->moveModsUp(first, last);
}
void LegacyJarModPage::on_rmJarBtn_clicked()
{
int first, last;
auto list = ui->jarModsTreeView->selectionModel()->selectedRows();
if (!lastfirst(list, first, last))
return;
m_jarmods->stopWatching();
m_jarmods->deleteMods(first, last);
m_jarmods->startWatching();
}
void LegacyJarModPage::on_viewJarBtn_clicked()
{
DesktopServices::openDirectory(m_inst->jarModsDir(), true);
}
void LegacyJarModPage::jarCurrent(QModelIndex current, QModelIndex previous)
{
if (!current.isValid())
{
ui->jarMIFrame->clear();
return;
}
int row = current.row();
Mod &m = m_jarmods->operator[](row);
ui->jarMIFrame->updateWithMod(m);
}

View File

@ -1,76 +0,0 @@
/* Copyright 2013-2017 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.
*/
#pragma once
#include <QWidget>
#include "net/NetJob.h"
#include "BasePage.h"
#include <MultiMC.h>
class LegacyModList;
class LegacyInstance;
namespace Ui
{
class LegacyJarModPage;
}
class LegacyJarModPage : public QWidget, public BasePage
{
Q_OBJECT
public:
explicit LegacyJarModPage(LegacyInstance *inst, QWidget *parent = 0);
virtual ~LegacyJarModPage();
virtual QString displayName() const override
{
return tr("Jar Mods");
}
virtual QIcon icon() const override
{
return MMC->getThemedIcon("jarmods");
}
virtual QString id() const override
{
return "jarmods";
}
virtual QString helpPage() const override
{
return "Legacy-jar-mods";
}
virtual bool shouldDisplay() const override;
private
slots:
void on_addJarBtn_clicked();
void on_rmJarBtn_clicked();
void on_moveJarUpBtn_clicked();
void on_moveJarDownBtn_clicked();
void on_viewJarBtn_clicked();
void jarCurrent(QModelIndex current, QModelIndex previous);
protected:
virtual bool eventFilter(QObject *obj, QEvent *ev) override;
private:
Ui::LegacyJarModPage *ui;
std::shared_ptr<LegacyModList> m_jarmods;
LegacyInstance *m_inst;
NetJobPtr forgeJob;
};

View File

@ -1,162 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>LegacyJarModPage</class>
<widget class="QWidget" name="LegacyJarModPage">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>659</width>
<height>593</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QTabWidget" name="tabWidget">
<property name="currentIndex">
<number>0</number>
</property>
<widget class="QWidget" name="tab">
<attribute name="title">
<string notr="true">Tab 1</string>
</attribute>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="ModListView" name="jarModsTreeView">
<property name="verticalScrollBarPolicy">
<enum>Qt::ScrollBarAlwaysOn</enum>
</property>
<property name="horizontalScrollBarPolicy">
<enum>Qt::ScrollBarAlwaysOff</enum>
</property>
</widget>
</item>
<item>
<layout class="QVBoxLayout" name="jarModsButtonBox">
<item>
<widget class="QLabel" name="label">
<property name="text">
<string>Selection</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="rmJarBtn">
<property name="text">
<string>&amp;Remove</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="moveJarUpBtn">
<property name="text">
<string>Move &amp;Up</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="moveJarDownBtn">
<property name="text">
<string>Move &amp;Down</string>
</property>
</widget>
</item>
<item>
<widget class="LineSeparator" name="separator" native="true"/>
</item>
<item>
<widget class="QLabel" name="label_2">
<property name="text">
<string>Install</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="addJarBtn">
<property name="text">
<string>&amp;Add jar mod</string>
</property>
</widget>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="viewJarBtn">
<property name="text">
<string>&amp;View Folder</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</item>
</layout>
</widget>
</widget>
</item>
<item>
<widget class="MCModInfoFrame" name="jarMIFrame">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Minimum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
</widget>
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>ModListView</class>
<extends>QTreeView</extends>
<header>widgets/ModListView.h</header>
</customwidget>
<customwidget>
<class>MCModInfoFrame</class>
<extends>QFrame</extends>
<header>widgets/MCModInfoFrame.h</header>
<container>1</container>
</customwidget>
<customwidget>
<class>LineSeparator</class>
<extends>QWidget</extends>
<header>widgets/LineSeparator.h</header>
<container>1</container>
</customwidget>
</customwidgets>
<resources/>
<connections/>
</ui>

View File

@ -1,25 +0,0 @@
#include "LegacyUpgradePage.h"
#include "ui_LegacyUpgradePage.h"
#include "minecraft/legacy/LegacyInstance.h"
LegacyUpgradePage::LegacyUpgradePage(LegacyInstance *inst, QWidget *parent)
: QWidget(parent), ui(new Ui::LegacyUpgradePage), m_inst(inst)
{
ui->setupUi(this);
}
LegacyUpgradePage::~LegacyUpgradePage()
{
delete ui;
}
void LegacyUpgradePage::on_upgradeButton_clicked()
{
// now what?
}
bool LegacyUpgradePage::shouldDisplay() const
{
return !m_inst->isRunning();
}

View File

@ -1,60 +0,0 @@
/* Copyright 2013-2017 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.
*/
#pragma once
#include <QWidget>
#include "minecraft/legacy/LegacyInstance.h"
#include "pages/BasePage.h"
#include <MultiMC.h>
namespace Ui
{
class LegacyUpgradePage;
}
class LegacyUpgradePage : public QWidget, public BasePage
{
Q_OBJECT
public:
explicit LegacyUpgradePage(LegacyInstance *inst, QWidget *parent = 0);
virtual ~LegacyUpgradePage();
virtual QString displayName() const override
{
return tr("Upgrade");
}
virtual QIcon icon() const override
{
return MMC->getThemedIcon("checkupdate");
}
virtual QString id() const override
{
return "upgrade";
}
virtual QString helpPage() const override
{
return "Legacy-upgrade";
}
virtual bool shouldDisplay() const override;
private
slots:
void on_upgradeButton_clicked();
private:
Ui::LegacyUpgradePage *ui;
LegacyInstance *m_inst;
};

View File

@ -1,51 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>LegacyUpgradePage</class>
<widget class="QWidget" name="LegacyUpgradePage">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>546</width>
<height>405</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout_5">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QTextBrowser" name="textBrowser">
<property name="html">
<string>
&lt;h1&gt;New format is available&lt;/h1&gt;
&lt;p&gt;MultiMC now supports old Minecraft versions in the new (OneSix) instance format. The old format won't be getting any new features and only the most critical bugfixes. As a consequence, you should upgrade this instance.&lt;/p&gt;
&lt;p&gt;The upgrade will create a new instance with the same contents as the current one, in the new format. The original instance will remain untouched, in case anything goes wrong in the process.&lt;/p&gt;
&lt;p&gt;Please report any issues on our &lt;a href=&quot;https://github.com/MultiMC/MultiMC5/issues&quot;&gt;&lt;img src=&quot;:/icons/multimc/22x22/bug.png&quot; /&gt; github issues page&lt;/a&gt;.&lt;/p&gt;</string>
</property>
<property name="openExternalLinks">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QCommandLinkButton" name="upgradeButton">
<property name="text">
<string>Start the upgrade! (Not Yet Implemented, Coming Soon™)</string>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>