GH-1314 add UI for custom minecraft jar addition
Also changes the text of the jar mod addition button. It should be clearer what it does and hopefully will not confuse as many people.
This commit is contained in:
parent
117bfef151
commit
8cf88ffc58
@ -664,6 +664,12 @@ void MinecraftProfile::installJarMods(QStringList selectedFiles)
|
|||||||
m_strategy->installJarMods(selectedFiles);
|
m_strategy->installJarMods(selectedFiles);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MinecraftProfile::installCustomJar(QString selectedFile)
|
||||||
|
{
|
||||||
|
m_strategy->installCustomJar(selectedFile);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* TODO: get rid of this. Get rid of all order numbers.
|
* TODO: get rid of this. Get rid of all order numbers.
|
||||||
*/
|
*/
|
||||||
|
@ -58,6 +58,9 @@ public:
|
|||||||
/// install more jar mods
|
/// install more jar mods
|
||||||
void installJarMods(QStringList selectedFiles);
|
void installJarMods(QStringList selectedFiles);
|
||||||
|
|
||||||
|
/// install more jar mods
|
||||||
|
void installCustomJar(QString selectedFile);
|
||||||
|
|
||||||
/// DEPRECATED, remove ASAP
|
/// DEPRECATED, remove ASAP
|
||||||
int getFreeOrderNumber();
|
int getFreeOrderNumber();
|
||||||
|
|
||||||
|
@ -23,6 +23,9 @@ public:
|
|||||||
/// install a list of jar mods into the instance
|
/// install a list of jar mods into the instance
|
||||||
virtual bool installJarMods(QStringList filepaths) = 0;
|
virtual bool installJarMods(QStringList filepaths) = 0;
|
||||||
|
|
||||||
|
/// install a custom jar (replaces the one from the Minecraft component)
|
||||||
|
virtual bool installCustomJar(QString filepath) = 0;
|
||||||
|
|
||||||
/// remove any files or records that constitute the version patch
|
/// remove any files or records that constitute the version patch
|
||||||
virtual bool removePatch(ProfilePatchPtr jarMod) = 0;
|
virtual bool removePatch(ProfilePatchPtr jarMod) = 0;
|
||||||
|
|
||||||
|
@ -118,6 +118,11 @@ bool FTBProfileStrategy::installJarMods(QStringList filepaths)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool FTBProfileStrategy::installCustomJar(QString filepath)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
bool FTBProfileStrategy::customizePatch(ProfilePatchPtr patch)
|
bool FTBProfileStrategy::customizePatch(ProfilePatchPtr patch)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
|
@ -9,13 +9,14 @@ class FTBProfileStrategy : public OneSixProfileStrategy
|
|||||||
public:
|
public:
|
||||||
FTBProfileStrategy(OneSixFTBInstance * instance);
|
FTBProfileStrategy(OneSixFTBInstance * instance);
|
||||||
virtual ~FTBProfileStrategy() {};
|
virtual ~FTBProfileStrategy() {};
|
||||||
virtual void load() override;
|
void load() override;
|
||||||
virtual bool resetOrder() override;
|
bool resetOrder() override;
|
||||||
virtual bool saveOrder(ProfileUtils::PatchOrder order) override;
|
bool saveOrder(ProfileUtils::PatchOrder order) override;
|
||||||
virtual bool installJarMods(QStringList filepaths) override;
|
bool installJarMods(QStringList filepaths) override;
|
||||||
virtual bool customizePatch (ProfilePatchPtr patch) override;
|
bool installCustomJar(QString filepath) override;
|
||||||
virtual bool revertPatch (ProfilePatchPtr patch) override;
|
bool customizePatch (ProfilePatchPtr patch) override;
|
||||||
|
bool revertPatch (ProfilePatchPtr patch) override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void loadDefaultBuiltinPatches() override;
|
void loadDefaultBuiltinPatches() override;
|
||||||
};
|
};
|
||||||
|
@ -637,11 +637,16 @@ QString OneSixInstance::jarModsDir() const
|
|||||||
return FS::PathCombine(instanceRoot(), "jarmods");
|
return FS::PathCombine(instanceRoot(), "jarmods");
|
||||||
}
|
}
|
||||||
|
|
||||||
QString OneSixInstance::libDir() const
|
QString OneSixInstance::FMLlibDir() const
|
||||||
{
|
{
|
||||||
return FS::PathCombine(minecraftRoot(), "lib");
|
return FS::PathCombine(minecraftRoot(), "lib");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QString OneSixInstance::customLibrariesDir() const
|
||||||
|
{
|
||||||
|
return FS::PathCombine(instanceRoot(), "libraries");
|
||||||
|
}
|
||||||
|
|
||||||
QString OneSixInstance::worldDir() const
|
QString OneSixInstance::worldDir() const
|
||||||
{
|
{
|
||||||
return FS::PathCombine(minecraftRoot(), "saves");
|
return FS::PathCombine(minecraftRoot(), "saves");
|
||||||
|
@ -48,7 +48,8 @@ public:
|
|||||||
QString texturePacksDir() const;
|
QString texturePacksDir() const;
|
||||||
QString loaderModsDir() const;
|
QString loaderModsDir() const;
|
||||||
QString coreModsDir() const;
|
QString coreModsDir() const;
|
||||||
QString libDir() const;
|
QString FMLlibDir() const;
|
||||||
|
QString customLibrariesDir() const;
|
||||||
QString worldDir() const;
|
QString worldDir() const;
|
||||||
virtual QString instanceConfigFolder() const override;
|
virtual QString instanceConfigFolder() const override;
|
||||||
|
|
||||||
|
@ -405,3 +405,67 @@ bool OneSixProfileStrategy::installJarMods(QStringList filepaths)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool OneSixProfileStrategy::installCustomJar(QString filepath)
|
||||||
|
{
|
||||||
|
QString patchDir = FS::PathCombine(m_instance->instanceRoot(), "patches");
|
||||||
|
if(!FS::ensureFolderPathExists(patchDir))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString libDir = m_instance->customLibrariesDir();
|
||||||
|
if (!FS::ensureFolderPathExists(libDir))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto specifier = GradleSpecifier("org.multimc:customjar:1");
|
||||||
|
QFileInfo sourceInfo(filepath);
|
||||||
|
QString target_filename = specifier.getFileName();
|
||||||
|
QString target_id = specifier.artifactId();
|
||||||
|
QString target_name = sourceInfo.completeBaseName() + " (custom jar)";
|
||||||
|
QString finalPath = FS::PathCombine(libDir, target_filename);
|
||||||
|
|
||||||
|
QFileInfo jarInfo(finalPath);
|
||||||
|
if (jarInfo.exists())
|
||||||
|
{
|
||||||
|
if(!QFile::remove(finalPath))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!QFile::copy(filepath, finalPath))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto f = std::make_shared<VersionFile>();
|
||||||
|
auto jarMod = std::make_shared<Library>();
|
||||||
|
jarMod->setRawName(specifier);
|
||||||
|
jarMod->setDisplayName(sourceInfo.completeBaseName());
|
||||||
|
jarMod->setHint("local");
|
||||||
|
f->mainJar = jarMod;
|
||||||
|
f->name = target_name;
|
||||||
|
f->uid = target_id;
|
||||||
|
f->order = profile->getFreeOrderNumber();
|
||||||
|
QString patchFileName = FS::PathCombine(patchDir, target_id + ".json");
|
||||||
|
|
||||||
|
QFile file(patchFileName);
|
||||||
|
if (!file.open(QFile::WriteOnly))
|
||||||
|
{
|
||||||
|
qCritical() << "Error opening" << file.fileName()
|
||||||
|
<< "for reading:" << file.errorString();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
file.write(OneSixVersionFormat::versionFileToJson(f, true).toJson());
|
||||||
|
file.close();
|
||||||
|
|
||||||
|
auto patch = std::make_shared<ProfilePatch>(f, patchFileName);
|
||||||
|
patch->setMovable(true);
|
||||||
|
patch->setRemovable(true);
|
||||||
|
profile->appendPatch(patch);
|
||||||
|
|
||||||
|
profile->saveCurrentOrder();
|
||||||
|
profile->reapplyPatches();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
@ -8,13 +8,14 @@ class OneSixProfileStrategy : public ProfileStrategy
|
|||||||
public:
|
public:
|
||||||
OneSixProfileStrategy(OneSixInstance * instance);
|
OneSixProfileStrategy(OneSixInstance * instance);
|
||||||
virtual ~OneSixProfileStrategy() {};
|
virtual ~OneSixProfileStrategy() {};
|
||||||
virtual void load() override;
|
void load() override;
|
||||||
virtual bool resetOrder() override;
|
bool resetOrder() override;
|
||||||
virtual bool saveOrder(ProfileUtils::PatchOrder order) override;
|
bool saveOrder(ProfileUtils::PatchOrder order) override;
|
||||||
virtual bool installJarMods(QStringList filepaths) override;
|
bool installJarMods(QStringList filepaths) override;
|
||||||
virtual bool removePatch(ProfilePatchPtr patch) override;
|
bool installCustomJar(QString filepath) override;
|
||||||
virtual bool customizePatch(ProfilePatchPtr patch) override;
|
bool removePatch(ProfilePatchPtr patch) override;
|
||||||
virtual bool revertPatch(ProfilePatchPtr patch) override;
|
bool customizePatch(ProfilePatchPtr patch) override;
|
||||||
|
bool revertPatch(ProfilePatchPtr patch) override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void loadDefaultBuiltinPatches();
|
virtual void loadDefaultBuiltinPatches();
|
||||||
|
@ -45,7 +45,7 @@ void FMLLibrariesTask::executeTask()
|
|||||||
// now check the lib folder inside the instance for files.
|
// now check the lib folder inside the instance for files.
|
||||||
for (auto &lib : libList)
|
for (auto &lib : libList)
|
||||||
{
|
{
|
||||||
QFileInfo libInfo(FS::PathCombine(inst->libDir(), lib.filename));
|
QFileInfo libInfo(FS::PathCombine(inst->FMLlibDir(), lib.filename));
|
||||||
if (libInfo.exists())
|
if (libInfo.exists())
|
||||||
continue;
|
continue;
|
||||||
fmlLibsToProcess.append(lib);
|
fmlLibsToProcess.append(lib);
|
||||||
@ -95,13 +95,13 @@ void FMLLibrariesTask::fmllibsFinished()
|
|||||||
{
|
{
|
||||||
progress(index, fmlLibsToProcess.size());
|
progress(index, fmlLibsToProcess.size());
|
||||||
auto entry = metacache->resolveEntry("fmllibs", lib.filename);
|
auto entry = metacache->resolveEntry("fmllibs", lib.filename);
|
||||||
auto path = FS::PathCombine(inst->libDir(), lib.filename);
|
auto path = FS::PathCombine(inst->FMLlibDir(), lib.filename);
|
||||||
if (!FS::ensureFilePathExists(path))
|
if (!FS::ensureFilePathExists(path))
|
||||||
{
|
{
|
||||||
emitFailed(tr("Failed creating FML library folder inside the instance."));
|
emitFailed(tr("Failed creating FML library folder inside the instance."));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!QFile::copy(entry->getFullPath(), FS::PathCombine(inst->libDir(), lib.filename)))
|
if (!QFile::copy(entry->getFullPath(), FS::PathCombine(inst->FMLlibDir(), lib.filename)))
|
||||||
{
|
{
|
||||||
emitFailed(tr("Failed copying Forge/FML library: %1.").arg(lib.filename));
|
emitFailed(tr("Failed copying Forge/FML library: %1.").arg(lib.filename));
|
||||||
return;
|
return;
|
||||||
|
@ -56,8 +56,7 @@ void GuiUtil::setClipboardText(const QString &text)
|
|||||||
QApplication::clipboard()->setText(text);
|
QApplication::clipboard()->setText(text);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static QStringList BrowseForFileInternal(QString context, QString caption, QString filter, QString defaultPath, QWidget *parentWidget, bool single)
|
||||||
QStringList GuiUtil::BrowseForFiles(QString context, QString caption, QString filter, QString defaultPath, QWidget *parentWidget)
|
|
||||||
{
|
{
|
||||||
static QMap<QString, QString> savedPaths;
|
static QMap<QString, QString> savedPaths;
|
||||||
|
|
||||||
@ -82,7 +81,7 @@ QStringList GuiUtil::BrowseForFiles(QString context, QString caption, QString fi
|
|||||||
}
|
}
|
||||||
urls.append(QUrl::fromLocalFile(defaultPath));
|
urls.append(QUrl::fromLocalFile(defaultPath));
|
||||||
|
|
||||||
w.setFileMode(QFileDialog::ExistingFiles);
|
w.setFileMode(single ? QFileDialog::ExistingFile : QFileDialog::ExistingFiles);
|
||||||
w.setAcceptMode(QFileDialog::AcceptOpen);
|
w.setAcceptMode(QFileDialog::AcceptOpen);
|
||||||
w.setNameFilter(filter);
|
w.setNameFilter(filter);
|
||||||
|
|
||||||
@ -114,3 +113,19 @@ QStringList GuiUtil::BrowseForFiles(QString context, QString caption, QString fi
|
|||||||
savedPaths[context] = w.directory().absolutePath();
|
savedPaths[context] = w.directory().absolutePath();
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QString GuiUtil::BrowseForFile(QString context, QString caption, QString filter, QString defaultPath, QWidget *parentWidget)
|
||||||
|
{
|
||||||
|
auto resultList = BrowseForFileInternal(context, caption, filter, defaultPath, parentWidget, true);
|
||||||
|
if(resultList.size())
|
||||||
|
{
|
||||||
|
return resultList[0];
|
||||||
|
}
|
||||||
|
return QString();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
QStringList GuiUtil::BrowseForFiles(QString context, QString caption, QString filter, QString defaultPath, QWidget *parentWidget)
|
||||||
|
{
|
||||||
|
return BrowseForFileInternal(context, caption, filter, defaultPath, parentWidget, false);
|
||||||
|
}
|
||||||
|
@ -7,4 +7,5 @@ namespace GuiUtil
|
|||||||
QString uploadPaste(const QString &text, QWidget *parentWidget);
|
QString uploadPaste(const QString &text, QWidget *parentWidget);
|
||||||
void setClipboardText(const QString &text);
|
void setClipboardText(const QString &text);
|
||||||
QStringList BrowseForFiles(QString context, QString caption, QString filter, QString defaultPath, QWidget *parentWidget);
|
QStringList BrowseForFiles(QString context, QString caption, QString filter, QString defaultPath, QWidget *parentWidget);
|
||||||
|
QString BrowseForFile(QString context, QString caption, QString filter, QString defaultPath, QWidget *parentWidget);
|
||||||
}
|
}
|
||||||
|
@ -501,9 +501,6 @@ MultiMC::MultiMC(int &argc, char **argv) : QApplication(argc, argv)
|
|||||||
|
|
||||||
m_settings->registerSetting("UpdateDialogGeometry", "");
|
m_settings->registerSetting("UpdateDialogGeometry", "");
|
||||||
|
|
||||||
// Jar mod nag dialog in version page
|
|
||||||
m_settings->registerSetting("JarModNagSeen", false);
|
|
||||||
|
|
||||||
// paste.ee API key
|
// paste.ee API key
|
||||||
m_settings->registerSetting("PasteEEAPIKey", "multimc");
|
m_settings->registerSetting("PasteEEAPIKey", "multimc");
|
||||||
|
|
||||||
|
@ -250,34 +250,20 @@ void VersionPage::on_modBtn_clicked()
|
|||||||
|
|
||||||
void VersionPage::on_jarmodBtn_clicked()
|
void VersionPage::on_jarmodBtn_clicked()
|
||||||
{
|
{
|
||||||
bool nagShown = false;
|
|
||||||
if (!m_profile->hasTrait("legacyLaunch") && !m_profile->hasTrait("alphaLaunch"))
|
|
||||||
{
|
|
||||||
// not legacy launch... nag
|
|
||||||
auto seenNag = MMC->settings()->get("JarModNagSeen").toBool();
|
|
||||||
if(!seenNag)
|
|
||||||
{
|
|
||||||
auto result = QMessageBox::question(this,
|
|
||||||
tr("Are you sure?"),
|
|
||||||
tr("This will add mods directly to the Minecraft jar.\n"
|
|
||||||
"Unless you KNOW that this is what NEEDS to be done, you should just use the mods folder (Loader mods).\n"
|
|
||||||
"\n"
|
|
||||||
"Do you want to continue?"),
|
|
||||||
tr("I understand, continue."), tr("Cancel"), QString(), 1, 1
|
|
||||||
);
|
|
||||||
if(result != 0)
|
|
||||||
return;
|
|
||||||
nagShown = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
auto list = GuiUtil::BrowseForFiles("jarmod", tr("Select jar mods"), tr("Minecraft.jar mods (*.zip *.jar)"), MMC->settings()->get("CentralModsDir").toString(), this->parentWidget());
|
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())
|
if(!list.empty())
|
||||||
{
|
{
|
||||||
m_profile->installJarMods(list);
|
m_profile->installJarMods(list);
|
||||||
if(nagShown)
|
|
||||||
{
|
|
||||||
MMC->settings()->set("JarModNagSeen", QVariant(true));
|
|
||||||
}
|
}
|
||||||
|
updateButtons();
|
||||||
|
}
|
||||||
|
|
||||||
|
void VersionPage::on_jarBtn_clicked()
|
||||||
|
{
|
||||||
|
auto jarPath = GuiUtil::BrowseForFile("jar", tr("Select jar"), tr("Minecraft.jar replacement (*.jar)"), MMC->settings()->get("CentralModsDir").toString(), this->parentWidget());
|
||||||
|
if(!jarPath.isEmpty())
|
||||||
|
{
|
||||||
|
m_profile->installCustomJar(jarPath);
|
||||||
}
|
}
|
||||||
updateButtons();
|
updateButtons();
|
||||||
}
|
}
|
||||||
|
@ -58,6 +58,7 @@ private slots:
|
|||||||
void on_moveUpBtn_clicked();
|
void on_moveUpBtn_clicked();
|
||||||
void on_moveDownBtn_clicked();
|
void on_moveDownBtn_clicked();
|
||||||
void on_jarmodBtn_clicked();
|
void on_jarmodBtn_clicked();
|
||||||
|
void on_jarBtn_clicked();
|
||||||
void on_revertBtn_clicked();
|
void on_revertBtn_clicked();
|
||||||
void on_editBtn_clicked();
|
void on_editBtn_clicked();
|
||||||
void on_modBtn_clicked();
|
void on_modBtn_clicked();
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>693</width>
|
<width>693</width>
|
||||||
<height>750</height>
|
<height>788</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QVBoxLayout" name="verticalLayout">
|
<layout class="QVBoxLayout" name="verticalLayout">
|
||||||
@ -206,7 +206,14 @@
|
|||||||
<string>Add a mod into the Minecraft jar file.</string>
|
<string>Add a mod into the Minecraft jar file.</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Add jar mod</string>
|
<string>Add to Minecraft.jar</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="jarBtn">
|
||||||
|
<property name="text">
|
||||||
|
<string>Replace Minecraft.jar</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
@ -281,7 +288,6 @@
|
|||||||
</customwidget>
|
</customwidget>
|
||||||
</customwidgets>
|
</customwidgets>
|
||||||
<tabstops>
|
<tabstops>
|
||||||
<tabstop>tabWidget</tabstop>
|
|
||||||
<tabstop>packageView</tabstop>
|
<tabstop>packageView</tabstop>
|
||||||
<tabstop>changeVersionBtn</tabstop>
|
<tabstop>changeVersionBtn</tabstop>
|
||||||
<tabstop>moveUpBtn</tabstop>
|
<tabstop>moveUpBtn</tabstop>
|
||||||
|
Loading…
Reference in New Issue
Block a user