Merge branch 'develop' of https://github.com/PolyMC/PolyMC into rebase
This commit is contained in:
commit
763627ee65
@ -79,12 +79,12 @@ set(Launcher_NEWS_OPEN_URL "https://polymc.org/news" CACHE STRING "URL that gets
|
||||
set(Launcher_HELP_URL "https://polymc.org/wiki/help-pages/%1" CACHE STRING "URL (with arg %1 to be substituted with page-id) that gets opened when the user requests help")
|
||||
|
||||
######## Set version numbers ########
|
||||
set(Launcher_VERSION_MAJOR 1)
|
||||
set(Launcher_VERSION_MINOR 4)
|
||||
set(Launcher_VERSION_HOTFIX 1)
|
||||
set(Launcher_VERSION_MAJOR 5)
|
||||
set(Launcher_VERSION_MINOR 0)
|
||||
|
||||
# Build number
|
||||
set(Launcher_VERSION_BUILD -1 CACHE STRING "Build number. -1 for no build number.")
|
||||
set(Launcher_VERSION_NAME "${Launcher_VERSION_MAJOR}.${Launcher_VERSION_MINOR}")
|
||||
set(Launcher_VERSION_NAME4 "${Launcher_VERSION_MAJOR}.${Launcher_VERSION_MINOR}.0.0")
|
||||
set(Launcher_VERSION_NAME4_COMMA "${Launcher_VERSION_MAJOR},${Launcher_VERSION_MINOR},0,0")
|
||||
|
||||
# Build platform.
|
||||
set(Launcher_BUILD_PLATFORM "" CACHE STRING "A short string identifying the platform that this build was built for. Only used to display in the about dialog.")
|
||||
@ -143,15 +143,8 @@ message(STATUS "Git commit: ${Launcher_GIT_COMMIT}")
|
||||
message(STATUS "Git tag: ${Launcher_GIT_TAG}")
|
||||
message(STATUS "Git refspec: ${Launcher_GIT_REFSPEC}")
|
||||
|
||||
set(Launcher_RELEASE_VERSION_NAME "${Launcher_VERSION_MAJOR}.${Launcher_VERSION_MINOR}.${Launcher_VERSION_HOTFIX}")
|
||||
set(Launcher_RELEASE_VERSION_NAME4 "${Launcher_RELEASE_VERSION_NAME}.0")
|
||||
set(Launcher_RELEASE_VERSION_NAME4_COMMA "${Launcher_VERSION_MAJOR},${Launcher_VERSION_MINOR},${Launcher_VERSION_HOTFIX},0")
|
||||
string(TIMESTAMP TODAY "%Y-%m-%d")
|
||||
set(Launcher_RELEASE_TIMESTAMP "${TODAY}")
|
||||
|
||||
#### Custom target to just print the version.
|
||||
add_custom_target(version echo "Version: ${Launcher_RELEASE_VERSION_NAME}")
|
||||
add_custom_target(tcversion echo "\\#\\#teamcity[setParameter name=\\'env.LAUNCHER_VERSION\\' value=\\'${Launcher_RELEASE_VERSION_NAME}\\']")
|
||||
set(Launcher_BUILD_TIMESTAMP "${TODAY}")
|
||||
|
||||
################################ 3rd Party Libs ################################
|
||||
|
||||
@ -226,9 +219,9 @@ if(UNIX AND APPLE)
|
||||
set(MACOSX_BUNDLE_BUNDLE_NAME "${Launcher_Name}")
|
||||
set(MACOSX_BUNDLE_INFO_STRING "${Launcher_Name}: A custom launcher for Minecraft that allows you to easily manage multiple installations of Minecraft at once.")
|
||||
set(MACOSX_BUNDLE_GUI_IDENTIFIER "org.polymc.${Launcher_Name}")
|
||||
set(MACOSX_BUNDLE_BUNDLE_VERSION "${Launcher_VERSION_MAJOR}.${Launcher_VERSION_MINOR}.${Launcher_VERSION_HOTFIX}")
|
||||
set(MACOSX_BUNDLE_SHORT_VERSION_STRING "${Launcher_VERSION_MAJOR}.${Launcher_VERSION_MINOR}.${Launcher_VERSION_HOTFIX}")
|
||||
set(MACOSX_BUNDLE_LONG_VERSION_STRING "${Launcher_VERSION_MAJOR}.${Launcher_VERSION_MINOR}.${Launcher_VERSION_HOTFIX}")
|
||||
set(MACOSX_BUNDLE_BUNDLE_VERSION "${Launcher_VERSION_NAME}")
|
||||
set(MACOSX_BUNDLE_SHORT_VERSION_STRING "${Launcher_VERSION_NAME}")
|
||||
set(MACOSX_BUNDLE_LONG_VERSION_STRING "${Launcher_VERSION_NAME}")
|
||||
set(MACOSX_BUNDLE_ICON_FILE ${Launcher_Name}.icns)
|
||||
set(MACOSX_BUNDLE_COPYRIGHT "Copyright 2021-2022 ${Launcher_Copyright}")
|
||||
set(MACOSX_SPARKLE_UPDATE_PUBLIC_KEY "idALcUIazingvKSSsEa9U7coDVxZVx/ORpOEE/QtJfg=")
|
||||
|
83
COPYING.md
83
COPYING.md
@ -32,27 +32,47 @@
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
## MinGW runtime (Windows)
|
||||
## MinGW-w64 runtime (Windows)
|
||||
|
||||
Copyright (c) 2012 MinGW.org project
|
||||
Copyright (c) 2009, 2010, 2011, 2012, 2013 by the mingw-w64 project
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
to deal in the Software without restriction, including without limitation
|
||||
the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
and/or sell copies of the Software, and to permit persons to whom the
|
||||
Software is furnished to do so, subject to the following conditions:
|
||||
This license has been certified as open source. It has also been designated
|
||||
as GPL compatible by the Free Software Foundation (FSF).
|
||||
|
||||
The above copyright notice, this permission notice and the below disclaimer
|
||||
shall be included in all copies or substantial portions of the Software.
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
DEALINGS IN THE SOFTWARE.
|
||||
1. Redistributions in source code must retain the accompanying copyright
|
||||
notice, this list of conditions, and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the accompanying
|
||||
copyright notice, this list of conditions, and the following disclaimer
|
||||
in the documentation and/or other materials provided with the
|
||||
distribution.
|
||||
3. Names of the copyright holders must not be used to endorse or promote
|
||||
products derived from this software without prior written permission
|
||||
from the copyright holders.
|
||||
4. The right to distribute this software or to use it for any purpose does
|
||||
not give you the right to use Servicemarks (sm) or Trademarks (tm) of
|
||||
the copyright holders. Use of them is covered by separate agreement
|
||||
with the copyright holders.
|
||||
5. If any files are modified, you must cause the modified files to carry
|
||||
prominent notices stating that you changed the files and the date of
|
||||
any change.
|
||||
|
||||
Disclaimer
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY EXPRESSED
|
||||
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
|
||||
EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
|
||||
OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
||||
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
Information on third party licenses used in MinGW-w64 can be found in its COPYING.MinGW-w64-runtime.txt.
|
||||
|
||||
## Qt 5/6
|
||||
|
||||
@ -345,3 +365,32 @@
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
## Gamemode
|
||||
|
||||
Copyright (c) 2017-2022, Feral Interactive
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of Feral Interactive nor the names of its contributors
|
||||
may be used to endorse or promote products derived from this software
|
||||
without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
|
@ -55,10 +55,9 @@ Config::Config()
|
||||
// Version information
|
||||
VERSION_MAJOR = @Launcher_VERSION_MAJOR@;
|
||||
VERSION_MINOR = @Launcher_VERSION_MINOR@;
|
||||
VERSION_HOTFIX = @Launcher_VERSION_HOTFIX@;
|
||||
VERSION_BUILD = @Launcher_VERSION_BUILD@;
|
||||
|
||||
BUILD_PLATFORM = "@Launcher_BUILD_PLATFORM@";
|
||||
BUILD_DATE = "@Launcher_BUILD_TIMESTAMP@";
|
||||
UPDATER_BASE = "@Launcher_UPDATER_BASE@";
|
||||
|
||||
MAC_SPARKLE_PUB_KEY = "@MACOSX_SPARKLE_UPDATE_PUBLIC_KEY@";
|
||||
@ -85,7 +84,7 @@ Config::Config()
|
||||
{
|
||||
VERSION_CHANNEL = GIT_REFSPEC;
|
||||
VERSION_CHANNEL.remove("refs/heads/");
|
||||
if(!UPDATER_BASE.isEmpty() && !BUILD_PLATFORM.isEmpty() && VERSION_BUILD >= 0) {
|
||||
if(!UPDATER_BASE.isEmpty() && !BUILD_PLATFORM.isEmpty()) {
|
||||
UPDATER_ENABLED = true;
|
||||
}
|
||||
}
|
||||
@ -98,7 +97,6 @@ Config::Config()
|
||||
VERSION_CHANNEL = "unknown";
|
||||
}
|
||||
|
||||
VERSION_STR = "@Launcher_VERSION_STRING@";
|
||||
NEWS_RSS_URL = "@Launcher_NEWS_RSS_URL@";
|
||||
NEWS_OPEN_URL = "@Launcher_NEWS_OPEN_URL@";
|
||||
HELP_URL = "@Launcher_HELP_URL@";
|
||||
@ -116,7 +114,7 @@ Config::Config()
|
||||
|
||||
QString Config::versionString() const
|
||||
{
|
||||
return QString("%1.%2.%3").arg(VERSION_MAJOR).arg(VERSION_MINOR).arg(VERSION_HOTFIX);
|
||||
return QString("%1.%2").arg(VERSION_MAJOR).arg(VERSION_MINOR);
|
||||
}
|
||||
|
||||
QString Config::printableVersionString() const
|
||||
@ -128,11 +126,5 @@ QString Config::printableVersionString() const
|
||||
{
|
||||
vstr += "-" + VERSION_CHANNEL;
|
||||
}
|
||||
|
||||
// if a build number is set, also add it to the end
|
||||
if(VERSION_BUILD >= 0)
|
||||
{
|
||||
vstr += "+build." + QString::number(VERSION_BUILD);
|
||||
}
|
||||
return vstr;
|
||||
}
|
||||
|
@ -55,10 +55,6 @@ class Config {
|
||||
int VERSION_MAJOR;
|
||||
/// The minor version number.
|
||||
int VERSION_MINOR;
|
||||
/// The hotfix number.
|
||||
int VERSION_HOTFIX;
|
||||
/// The build number.
|
||||
int VERSION_BUILD;
|
||||
|
||||
/**
|
||||
* The version channel
|
||||
@ -71,6 +67,9 @@ class Config {
|
||||
/// A short string identifying this build's platform. For example, "lin64" or "win32".
|
||||
QString BUILD_PLATFORM;
|
||||
|
||||
/// A string containing the build timestamp
|
||||
QString BUILD_DATE;
|
||||
|
||||
/// URL for the updater's channel
|
||||
QString UPDATER_BASE;
|
||||
|
||||
@ -95,9 +94,6 @@ class Config {
|
||||
/// The git refspec of this build
|
||||
QString GIT_REFSPEC;
|
||||
|
||||
/// This is printed on start to standard output
|
||||
QString VERSION_STR;
|
||||
|
||||
/**
|
||||
* This is used to fetch the news RSS feed.
|
||||
* It defaults in CMakeLists.txt to "https://multimc.org/rss.xml"
|
||||
|
@ -774,7 +774,7 @@ Application::Application(int &argc, char **argv) : QApplication(argc, argv)
|
||||
auto platform = getIdealPlatform(BuildConfig.BUILD_PLATFORM);
|
||||
auto channelUrl = BuildConfig.UPDATER_BASE + platform + "/channels.json";
|
||||
qDebug() << "Initializing updater with platform: " << platform << " -- " << channelUrl;
|
||||
m_updateChecker.reset(new UpdateChecker(m_network, channelUrl, BuildConfig.VERSION_CHANNEL, BuildConfig.VERSION_BUILD));
|
||||
m_updateChecker.reset(new UpdateChecker(m_network, channelUrl, BuildConfig.VERSION_CHANNEL));
|
||||
qDebug() << "<> Updater started.";
|
||||
}
|
||||
|
||||
|
@ -53,15 +53,22 @@ BaseInstance::BaseInstance(SettingsObjectPtr globalSettings, SettingsObjectPtr s
|
||||
: QObject()
|
||||
{
|
||||
m_settings = settings;
|
||||
m_global_settings = globalSettings;
|
||||
m_rootDir = rootDir;
|
||||
|
||||
m_settings->registerSetting("name", "Unnamed Instance");
|
||||
m_settings->registerSetting("iconKey", "default");
|
||||
m_settings->registerSetting("notes", "");
|
||||
|
||||
m_settings->registerSetting("lastLaunchTime", 0);
|
||||
m_settings->registerSetting("totalTimePlayed", 0);
|
||||
m_settings->registerSetting("lastTimePlayed", 0);
|
||||
|
||||
// Game time override
|
||||
auto gameTimeOverride = m_settings->registerSetting("OverrideGameTime", false);
|
||||
m_settings->registerOverride(globalSettings->getSetting("ShowGameTime"), gameTimeOverride);
|
||||
m_settings->registerOverride(globalSettings->getSetting("RecordGameTime"), gameTimeOverride);
|
||||
|
||||
// NOTE: Sometimees InstanceType is already registered, as it was used to identify the type of
|
||||
// a locally stored instance
|
||||
if (!m_settings->getSetting("InstanceType"))
|
||||
@ -149,7 +156,7 @@ void BaseInstance::setManagedPack(const QString& type, const QString& id, const
|
||||
|
||||
int BaseInstance::getConsoleMaxLines() const
|
||||
{
|
||||
auto lineSetting = settings()->getSetting("ConsoleMaxLines");
|
||||
auto lineSetting = m_settings->getSetting("ConsoleMaxLines");
|
||||
bool conversionOk = false;
|
||||
int maxLines = lineSetting->get().toInt(&conversionOk);
|
||||
if(!conversionOk)
|
||||
@ -162,7 +169,7 @@ int BaseInstance::getConsoleMaxLines() const
|
||||
|
||||
bool BaseInstance::shouldStopOnConsoleOverflow() const
|
||||
{
|
||||
return settings()->get("ConsoleOverflowStop").toBool();
|
||||
return m_settings->get("ConsoleOverflowStop").toBool();
|
||||
}
|
||||
|
||||
void BaseInstance::iconUpdated(QString key)
|
||||
@ -237,7 +244,7 @@ void BaseInstance::setRunning(bool running)
|
||||
|
||||
int64_t BaseInstance::totalTimePlayed() const
|
||||
{
|
||||
qint64 current = settings()->get("totalTimePlayed").toLongLong();
|
||||
qint64 current = m_settings->get("totalTimePlayed").toLongLong();
|
||||
if(m_isRunning)
|
||||
{
|
||||
QDateTime timeNow = QDateTime::currentDateTime();
|
||||
@ -253,7 +260,7 @@ int64_t BaseInstance::lastTimePlayed() const
|
||||
QDateTime timeNow = QDateTime::currentDateTime();
|
||||
return m_timeStarted.secsTo(timeNow);
|
||||
}
|
||||
return settings()->get("lastTimePlayed").toLongLong();
|
||||
return m_settings->get("lastTimePlayed").toLongLong();
|
||||
}
|
||||
|
||||
void BaseInstance::resetTimePlayed()
|
||||
@ -272,8 +279,10 @@ QString BaseInstance::instanceRoot() const
|
||||
return m_rootDir;
|
||||
}
|
||||
|
||||
SettingsObjectPtr BaseInstance::settings() const
|
||||
SettingsObjectPtr BaseInstance::settings()
|
||||
{
|
||||
loadSpecificSettings();
|
||||
|
||||
return m_settings;
|
||||
}
|
||||
|
||||
@ -340,7 +349,7 @@ QString BaseInstance::windowTitle() const
|
||||
}
|
||||
|
||||
// FIXME: why is this here? move it to MinecraftInstance!!!
|
||||
QStringList BaseInstance::extraArguments() const
|
||||
QStringList BaseInstance::extraArguments()
|
||||
{
|
||||
return Commandline::splitArgs(settings()->get("JvmArgs").toString());
|
||||
}
|
||||
|
@ -154,7 +154,7 @@ public:
|
||||
return level;
|
||||
};
|
||||
|
||||
virtual QStringList extraArguments() const;
|
||||
virtual QStringList extraArguments();
|
||||
|
||||
/// Traits. Normally inside the version, depends on instance implementation.
|
||||
virtual QSet <QString> traits() const = 0;
|
||||
@ -170,9 +170,18 @@ public:
|
||||
/*!
|
||||
* \brief Gets this instance's settings object.
|
||||
* This settings object stores instance-specific settings.
|
||||
*
|
||||
* Note that this method is not const.
|
||||
* It may call loadSpecificSettings() to ensure those are loaded.
|
||||
*
|
||||
* \return A pointer to this instance's settings object.
|
||||
*/
|
||||
virtual SettingsObjectPtr settings() const;
|
||||
virtual SettingsObjectPtr settings();
|
||||
|
||||
/*!
|
||||
* \brief Loads settings specific to an instance type if they're not already loaded.
|
||||
*/
|
||||
virtual void loadSpecificSettings() = 0;
|
||||
|
||||
/// returns a valid update task
|
||||
virtual Task::Ptr createUpdateTask(Net::Mode mode) = 0;
|
||||
@ -206,7 +215,7 @@ public:
|
||||
virtual QString instanceConfigFolder() const = 0;
|
||||
|
||||
/// get variables this instance exports
|
||||
virtual QMap<QString, QString> getVariables() const = 0;
|
||||
virtual QMap<QString, QString> getVariables() = 0;
|
||||
|
||||
virtual QString typeName() const = 0;
|
||||
|
||||
@ -268,6 +277,11 @@ public:
|
||||
protected:
|
||||
void changeStatus(Status newStatus);
|
||||
|
||||
SettingsObjectPtr globalSettings() const { return m_global_settings.lock(); };
|
||||
|
||||
bool isSpecificSettingsLoaded() const { return m_specific_settings_loaded; }
|
||||
void setSpecificSettingsLoaded(bool loaded) { m_specific_settings_loaded = loaded; }
|
||||
|
||||
signals:
|
||||
/*!
|
||||
* \brief Signal emitted when properties relevant to the instance view change
|
||||
@ -296,6 +310,10 @@ private: /* data */
|
||||
bool m_crashed = false;
|
||||
bool m_hasUpdate = false;
|
||||
bool m_hasBrokenVersion = false;
|
||||
|
||||
SettingsObjectWeakPtr m_global_settings;
|
||||
bool m_specific_settings_loaded = false;
|
||||
|
||||
};
|
||||
|
||||
Q_DECLARE_METATYPE(shared_qobject_ptr<BaseInstance>)
|
||||
|
@ -861,6 +861,8 @@ SET(LAUNCHER_SOURCES
|
||||
ui/dialogs/ModDownloadDialog.h
|
||||
ui/dialogs/ScrollMessageBox.cpp
|
||||
ui/dialogs/ScrollMessageBox.h
|
||||
ui/dialogs/BlockedModsDialog.cpp
|
||||
ui/dialogs/BlockedModsDialog.h
|
||||
ui/dialogs/ChooseProviderDialog.h
|
||||
ui/dialogs/ChooseProviderDialog.cpp
|
||||
ui/dialogs/ModUpdateDialog.cpp
|
||||
@ -971,6 +973,7 @@ qt_wrap_ui(LAUNCHER_UI
|
||||
ui/dialogs/EditAccountDialog.ui
|
||||
ui/dialogs/ReviewMessageBox.ui
|
||||
ui/dialogs/ScrollMessageBox.ui
|
||||
ui/dialogs/BlockedModsDialog.ui
|
||||
ui/dialogs/ChooseProviderDialog.ui
|
||||
)
|
||||
|
||||
|
@ -60,7 +60,7 @@
|
||||
#include "net/ChecksumValidator.h"
|
||||
|
||||
#include "ui/dialogs/CustomMessageBox.h"
|
||||
#include "ui/dialogs/ScrollMessageBox.h"
|
||||
#include "ui/dialogs/BlockedModsDialog.h"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
@ -396,21 +396,24 @@ void InstanceImportTask::processFlame()
|
||||
auto results = m_modIdResolver->getResults();
|
||||
//first check for blocked mods
|
||||
QString text;
|
||||
QList<QUrl> urls;
|
||||
auto anyBlocked = false;
|
||||
for(const auto& result: results.files.values()) {
|
||||
if (!result.resolved || result.url.isEmpty()) {
|
||||
text += QString("%1: <a href='%2'>%2</a><br/>").arg(result.fileName, result.websiteUrl);
|
||||
urls.append(QUrl(result.websiteUrl));
|
||||
anyBlocked = true;
|
||||
}
|
||||
}
|
||||
if(anyBlocked) {
|
||||
qWarning() << "Blocked mods found, displaying mod list";
|
||||
|
||||
auto message_dialog = new ScrollMessageBox(m_parent,
|
||||
auto message_dialog = new BlockedModsDialog(m_parent,
|
||||
tr("Blocked mods found"),
|
||||
tr("The following mods were blocked on third party launchers.<br/>"
|
||||
"You will need to manually download them and add them to the modpack"),
|
||||
text);
|
||||
text,
|
||||
urls);
|
||||
message_dialog->setModal(true);
|
||||
|
||||
if (message_dialog->exec()) {
|
||||
|
@ -15,6 +15,10 @@ public:
|
||||
void saveNow() override
|
||||
{
|
||||
}
|
||||
void loadSpecificSettings() override
|
||||
{
|
||||
setSpecificSettingsLoaded(true);
|
||||
}
|
||||
QString getStatusbarDescription() override
|
||||
{
|
||||
return tr("Unknown instance type");
|
||||
@ -43,7 +47,7 @@ public:
|
||||
{
|
||||
return QProcessEnvironment();
|
||||
}
|
||||
QMap<QString, QString> getVariables() const override
|
||||
QMap<QString, QString> getVariables() override
|
||||
{
|
||||
return QMap<QString, QString>();
|
||||
}
|
||||
|
@ -1,91 +1,37 @@
|
||||
#pragma once
|
||||
|
||||
#include <QObject>
|
||||
#include <QSharedPointer>
|
||||
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
#include <QObject>
|
||||
|
||||
namespace details
|
||||
{
|
||||
struct DeleteQObjectLater
|
||||
{
|
||||
void operator()(QObject *obj) const
|
||||
{
|
||||
obj->deleteLater();
|
||||
}
|
||||
};
|
||||
}
|
||||
/**
|
||||
* A unique pointer class with unique pointer semantics intended for derivates of QObject
|
||||
* Calls deleteLater() instead of destroying the contained object immediately
|
||||
*/
|
||||
template<typename T> using unique_qobject_ptr = std::unique_ptr<T, details::DeleteQObjectLater>;
|
||||
template <typename T>
|
||||
using unique_qobject_ptr = QScopedPointer<T, QScopedPointerDeleteLater>;
|
||||
|
||||
/**
|
||||
* A shared pointer class with shared pointer semantics intended for derivates of QObject
|
||||
* Calls deleteLater() instead of destroying the contained object immediately
|
||||
*/
|
||||
template <typename T>
|
||||
class shared_qobject_ptr
|
||||
{
|
||||
public:
|
||||
shared_qobject_ptr(){}
|
||||
shared_qobject_ptr(T * wrap)
|
||||
{
|
||||
reset(wrap);
|
||||
}
|
||||
shared_qobject_ptr(const shared_qobject_ptr<T>& other)
|
||||
{
|
||||
m_ptr = other.m_ptr;
|
||||
}
|
||||
template<typename Derived>
|
||||
shared_qobject_ptr(const shared_qobject_ptr<Derived> &other)
|
||||
{
|
||||
m_ptr = other.unwrap();
|
||||
}
|
||||
class shared_qobject_ptr : public QSharedPointer<T> {
|
||||
public:
|
||||
constexpr shared_qobject_ptr() : QSharedPointer<T>() {}
|
||||
constexpr shared_qobject_ptr(T* ptr) : QSharedPointer<T>(ptr, &QObject::deleteLater) {}
|
||||
constexpr shared_qobject_ptr(std::nullptr_t null_ptr) : QSharedPointer<T>(null_ptr, &QObject::deleteLater) {}
|
||||
|
||||
public:
|
||||
void reset(T * wrap)
|
||||
{
|
||||
using namespace std::placeholders;
|
||||
m_ptr.reset(wrap, std::bind(&QObject::deleteLater, _1));
|
||||
}
|
||||
void reset(const shared_qobject_ptr<T> &other)
|
||||
{
|
||||
m_ptr = other.m_ptr;
|
||||
}
|
||||
void reset()
|
||||
{
|
||||
m_ptr.reset();
|
||||
}
|
||||
T * get() const
|
||||
{
|
||||
return m_ptr.get();
|
||||
}
|
||||
T * operator->() const
|
||||
{
|
||||
return m_ptr.get();
|
||||
}
|
||||
T & operator*() const
|
||||
{
|
||||
return *m_ptr.get();
|
||||
}
|
||||
operator bool() const
|
||||
{
|
||||
return m_ptr.get() != nullptr;
|
||||
}
|
||||
const std::shared_ptr <T> unwrap() const
|
||||
{
|
||||
return m_ptr;
|
||||
}
|
||||
template<typename U>
|
||||
bool operator==(const shared_qobject_ptr<U>& other) const {
|
||||
return m_ptr == other.m_ptr;
|
||||
}
|
||||
template<typename U>
|
||||
bool operator!=(const shared_qobject_ptr<U>& other) const {
|
||||
return m_ptr != other.m_ptr;
|
||||
}
|
||||
template <typename Derived>
|
||||
constexpr shared_qobject_ptr(const shared_qobject_ptr<Derived>& other) : QSharedPointer<T>(other)
|
||||
{}
|
||||
|
||||
private:
|
||||
std::shared_ptr <T> m_ptr;
|
||||
void reset() { QSharedPointer<T>::reset(); }
|
||||
void reset(const shared_qobject_ptr<T>& other)
|
||||
{
|
||||
shared_qobject_ptr<T> t(other);
|
||||
this->swap(t);
|
||||
}
|
||||
};
|
||||
|
@ -115,6 +115,19 @@ private:
|
||||
MinecraftInstance::MinecraftInstance(SettingsObjectPtr globalSettings, SettingsObjectPtr settings, const QString &rootDir)
|
||||
: BaseInstance(globalSettings, settings, rootDir)
|
||||
{
|
||||
m_components.reset(new PackProfile(this));
|
||||
}
|
||||
|
||||
void MinecraftInstance::saveNow()
|
||||
{
|
||||
m_components->saveNow();
|
||||
}
|
||||
|
||||
void MinecraftInstance::loadSpecificSettings()
|
||||
{
|
||||
if (isSpecificSettingsLoaded())
|
||||
return;
|
||||
|
||||
// Java Settings
|
||||
auto javaOverride = m_settings->registerSetting("OverrideJava", false);
|
||||
auto locationOverride = m_settings->registerSetting("OverrideJavaLocation", false);
|
||||
@ -124,64 +137,58 @@ MinecraftInstance::MinecraftInstance(SettingsObjectPtr globalSettings, SettingsO
|
||||
auto javaOrLocation = std::make_shared<OrSetting>("JavaOrLocationOverride", javaOverride, locationOverride);
|
||||
auto javaOrArgs = std::make_shared<OrSetting>("JavaOrArgsOverride", javaOverride, argsOverride);
|
||||
|
||||
m_settings->registerOverride(globalSettings->getSetting("JavaPath"), javaOrLocation);
|
||||
m_settings->registerOverride(globalSettings->getSetting("JvmArgs"), javaOrArgs);
|
||||
m_settings->registerOverride(globalSettings->getSetting("IgnoreJavaCompatibility"), javaOrLocation);
|
||||
if (auto global_settings = globalSettings()) {
|
||||
m_settings->registerOverride(global_settings->getSetting("JavaPath"), javaOrLocation);
|
||||
m_settings->registerOverride(global_settings->getSetting("JvmArgs"), javaOrArgs);
|
||||
m_settings->registerOverride(global_settings->getSetting("IgnoreJavaCompatibility"), javaOrLocation);
|
||||
|
||||
// special!
|
||||
m_settings->registerPassthrough(globalSettings->getSetting("JavaTimestamp"), javaOrLocation);
|
||||
m_settings->registerPassthrough(globalSettings->getSetting("JavaVersion"), javaOrLocation);
|
||||
m_settings->registerPassthrough(globalSettings->getSetting("JavaArchitecture"), javaOrLocation);
|
||||
// special!
|
||||
m_settings->registerPassthrough(global_settings->getSetting("JavaTimestamp"), javaOrLocation);
|
||||
m_settings->registerPassthrough(global_settings->getSetting("JavaVersion"), javaOrLocation);
|
||||
m_settings->registerPassthrough(global_settings->getSetting("JavaArchitecture"), javaOrLocation);
|
||||
|
||||
// Window Size
|
||||
auto windowSetting = m_settings->registerSetting("OverrideWindow", false);
|
||||
m_settings->registerOverride(globalSettings->getSetting("LaunchMaximized"), windowSetting);
|
||||
m_settings->registerOverride(globalSettings->getSetting("MinecraftWinWidth"), windowSetting);
|
||||
m_settings->registerOverride(globalSettings->getSetting("MinecraftWinHeight"), windowSetting);
|
||||
// Window Size
|
||||
auto windowSetting = m_settings->registerSetting("OverrideWindow", false);
|
||||
m_settings->registerOverride(global_settings->getSetting("LaunchMaximized"), windowSetting);
|
||||
m_settings->registerOverride(global_settings->getSetting("MinecraftWinWidth"), windowSetting);
|
||||
m_settings->registerOverride(global_settings->getSetting("MinecraftWinHeight"), windowSetting);
|
||||
|
||||
// Memory
|
||||
auto memorySetting = m_settings->registerSetting("OverrideMemory", false);
|
||||
m_settings->registerOverride(globalSettings->getSetting("MinMemAlloc"), memorySetting);
|
||||
m_settings->registerOverride(globalSettings->getSetting("MaxMemAlloc"), memorySetting);
|
||||
m_settings->registerOverride(globalSettings->getSetting("PermGen"), memorySetting);
|
||||
// Memory
|
||||
auto memorySetting = m_settings->registerSetting("OverrideMemory", false);
|
||||
m_settings->registerOverride(global_settings->getSetting("MinMemAlloc"), memorySetting);
|
||||
m_settings->registerOverride(global_settings->getSetting("MaxMemAlloc"), memorySetting);
|
||||
m_settings->registerOverride(global_settings->getSetting("PermGen"), memorySetting);
|
||||
|
||||
// Minecraft launch method
|
||||
auto launchMethodOverride = m_settings->registerSetting("OverrideMCLaunchMethod", false);
|
||||
m_settings->registerOverride(globalSettings->getSetting("MCLaunchMethod"), launchMethodOverride);
|
||||
// Minecraft launch method
|
||||
auto launchMethodOverride = m_settings->registerSetting("OverrideMCLaunchMethod", false);
|
||||
m_settings->registerOverride(global_settings->getSetting("MCLaunchMethod"), launchMethodOverride);
|
||||
|
||||
// Native library workarounds
|
||||
auto nativeLibraryWorkaroundsOverride = m_settings->registerSetting("OverrideNativeWorkarounds", false);
|
||||
m_settings->registerOverride(globalSettings->getSetting("UseNativeOpenAL"), nativeLibraryWorkaroundsOverride);
|
||||
m_settings->registerOverride(globalSettings->getSetting("UseNativeGLFW"), nativeLibraryWorkaroundsOverride);
|
||||
// Native library workarounds
|
||||
auto nativeLibraryWorkaroundsOverride = m_settings->registerSetting("OverrideNativeWorkarounds", false);
|
||||
m_settings->registerOverride(global_settings->getSetting("UseNativeOpenAL"), nativeLibraryWorkaroundsOverride);
|
||||
m_settings->registerOverride(global_settings->getSetting("UseNativeGLFW"), nativeLibraryWorkaroundsOverride);
|
||||
|
||||
// Peformance related options
|
||||
auto performanceOverride = m_settings->registerSetting("OverridePerformance", false);
|
||||
m_settings->registerOverride(globalSettings->getSetting("EnableFeralGamemode"), performanceOverride);
|
||||
m_settings->registerOverride(globalSettings->getSetting("EnableMangoHud"), performanceOverride);
|
||||
m_settings->registerOverride(globalSettings->getSetting("UseDiscreteGpu"), performanceOverride);
|
||||
// Peformance related options
|
||||
auto performanceOverride = m_settings->registerSetting("OverridePerformance", false);
|
||||
m_settings->registerOverride(global_settings->getSetting("EnableFeralGamemode"), performanceOverride);
|
||||
m_settings->registerOverride(global_settings->getSetting("EnableMangoHud"), performanceOverride);
|
||||
m_settings->registerOverride(global_settings->getSetting("UseDiscreteGpu"), performanceOverride);
|
||||
|
||||
// Game time
|
||||
auto gameTimeOverride = m_settings->registerSetting("OverrideGameTime", false);
|
||||
m_settings->registerOverride(globalSettings->getSetting("ShowGameTime"), gameTimeOverride);
|
||||
m_settings->registerOverride(globalSettings->getSetting("RecordGameTime"), gameTimeOverride);
|
||||
// Miscellaneous
|
||||
auto miscellaneousOverride = m_settings->registerSetting("OverrideMiscellaneous", false);
|
||||
m_settings->registerOverride(global_settings->getSetting("CloseAfterLaunch"), miscellaneousOverride);
|
||||
m_settings->registerOverride(global_settings->getSetting("QuitAfterGameStop"), miscellaneousOverride);
|
||||
|
||||
m_settings->set("InstanceType", "OneSix");
|
||||
}
|
||||
|
||||
// Join server on launch, this does not have a global override
|
||||
m_settings->registerSetting("JoinServerOnLaunch", false);
|
||||
m_settings->registerSetting("JoinServerOnLaunchAddress", "");
|
||||
|
||||
// Miscellaneous
|
||||
auto miscellaneousOverride = m_settings->registerSetting("OverrideMiscellaneous", false);
|
||||
m_settings->registerOverride(globalSettings->getSetting("CloseAfterLaunch"), miscellaneousOverride);
|
||||
m_settings->registerOverride(globalSettings->getSetting("QuitAfterGameStop"), miscellaneousOverride);
|
||||
qDebug() << "Instance-type specific settings were loaded!";
|
||||
|
||||
m_settings->set("InstanceType", "OneSix");
|
||||
|
||||
m_components.reset(new PackProfile(this));
|
||||
}
|
||||
|
||||
void MinecraftInstance::saveNow()
|
||||
{
|
||||
m_components->saveNow();
|
||||
setSpecificSettingsLoaded(true);
|
||||
}
|
||||
|
||||
QString MinecraftInstance::typeName() const
|
||||
@ -308,7 +315,7 @@ QDir MinecraftInstance::versionsPath() const
|
||||
return QDir::current().absoluteFilePath("versions");
|
||||
}
|
||||
|
||||
QStringList MinecraftInstance::getClassPath() const
|
||||
QStringList MinecraftInstance::getClassPath()
|
||||
{
|
||||
QStringList jars, nativeJars;
|
||||
auto javaArchitecture = settings()->get("JavaArchitecture").toString();
|
||||
@ -323,7 +330,7 @@ QString MinecraftInstance::getMainClass() const
|
||||
return profile->getMainClass();
|
||||
}
|
||||
|
||||
QStringList MinecraftInstance::getNativeJars() const
|
||||
QStringList MinecraftInstance::getNativeJars()
|
||||
{
|
||||
QStringList jars, nativeJars;
|
||||
auto javaArchitecture = settings()->get("JavaArchitecture").toString();
|
||||
@ -332,7 +339,7 @@ QStringList MinecraftInstance::getNativeJars() const
|
||||
return nativeJars;
|
||||
}
|
||||
|
||||
QStringList MinecraftInstance::extraArguments() const
|
||||
QStringList MinecraftInstance::extraArguments()
|
||||
{
|
||||
auto list = BaseInstance::extraArguments();
|
||||
auto version = getPackProfile();
|
||||
@ -366,7 +373,7 @@ QStringList MinecraftInstance::extraArguments() const
|
||||
return list;
|
||||
}
|
||||
|
||||
QStringList MinecraftInstance::javaArguments() const
|
||||
QStringList MinecraftInstance::javaArguments()
|
||||
{
|
||||
QStringList args;
|
||||
|
||||
@ -423,7 +430,7 @@ QStringList MinecraftInstance::javaArguments() const
|
||||
return args;
|
||||
}
|
||||
|
||||
QMap<QString, QString> MinecraftInstance::getVariables() const
|
||||
QMap<QString, QString> MinecraftInstance::getVariables()
|
||||
{
|
||||
QMap<QString, QString> out;
|
||||
out.insert("INST_NAME", name());
|
||||
@ -951,9 +958,9 @@ shared_qobject_ptr<LaunchTask> MinecraftInstance::createLaunchTask(AuthSessionPt
|
||||
process->appendStep(new CreateGameFolders(pptr));
|
||||
}
|
||||
|
||||
if (!serverToJoin && m_settings->get("JoinServerOnLaunch").toBool())
|
||||
if (!serverToJoin && settings()->get("JoinServerOnLaunch").toBool())
|
||||
{
|
||||
QString fullAddress = m_settings->get("JoinServerOnLaunchAddress").toString();
|
||||
QString fullAddress = settings()->get("JoinServerOnLaunchAddress").toString();
|
||||
serverToJoin.reset(new MinecraftServerTarget(MinecraftServerTarget::parse(fullAddress)));
|
||||
}
|
||||
|
||||
@ -1068,10 +1075,10 @@ shared_qobject_ptr<LaunchTask> MinecraftInstance::createLaunchTask(AuthSessionPt
|
||||
|
||||
QString MinecraftInstance::launchMethod()
|
||||
{
|
||||
return m_settings->get("MCLaunchMethod").toString();
|
||||
return settings()->get("MCLaunchMethod").toString();
|
||||
}
|
||||
|
||||
JavaVersion MinecraftInstance::getJavaVersion() const
|
||||
JavaVersion MinecraftInstance::getJavaVersion()
|
||||
{
|
||||
return JavaVersion(settings()->get("JavaVersion").toString());
|
||||
}
|
||||
|
@ -21,6 +21,8 @@ public:
|
||||
virtual ~MinecraftInstance() {};
|
||||
virtual void saveNow() override;
|
||||
|
||||
void loadSpecificSettings() override;
|
||||
|
||||
// FIXME: remove
|
||||
QString typeName() const override;
|
||||
// FIXME: remove
|
||||
@ -80,15 +82,15 @@ public:
|
||||
////// Launch stuff //////
|
||||
Task::Ptr createUpdateTask(Net::Mode mode) override;
|
||||
shared_qobject_ptr<LaunchTask> createLaunchTask(AuthSessionPtr account, MinecraftServerTargetPtr serverToJoin) override;
|
||||
QStringList extraArguments() const override;
|
||||
QStringList extraArguments() override;
|
||||
QStringList verboseDescription(AuthSessionPtr session, MinecraftServerTargetPtr serverToJoin) override;
|
||||
QList<Mod*> getJarMods() const;
|
||||
QString createLaunchScript(AuthSessionPtr session, MinecraftServerTargetPtr serverToJoin);
|
||||
/// get arguments passed to java
|
||||
QStringList javaArguments() const;
|
||||
QStringList javaArguments();
|
||||
|
||||
/// get variables for launch command variable substitution/environment
|
||||
QMap<QString, QString> getVariables() const override;
|
||||
QMap<QString, QString> getVariables() override;
|
||||
|
||||
/// create an environment for launching processes
|
||||
QProcessEnvironment createEnvironment() override;
|
||||
@ -104,16 +106,16 @@ public:
|
||||
QString getStatusbarDescription() override;
|
||||
|
||||
// FIXME: remove
|
||||
virtual QStringList getClassPath() const;
|
||||
virtual QStringList getClassPath();
|
||||
// FIXME: remove
|
||||
virtual QStringList getNativeJars() const;
|
||||
virtual QStringList getNativeJars();
|
||||
// FIXME: remove
|
||||
virtual QString getMainClass() const;
|
||||
|
||||
// FIXME: remove
|
||||
virtual QStringList processMinecraftArgs(AuthSessionPtr account, MinecraftServerTargetPtr serverToJoin) const;
|
||||
|
||||
virtual JavaVersion getJavaVersion() const;
|
||||
virtual JavaVersion getJavaVersion();
|
||||
|
||||
protected:
|
||||
QMap<QString, QString> createCensorFilterFromSession(AuthSessionPtr session);
|
||||
|
@ -43,7 +43,7 @@ void MinecraftUpdate::executeTask()
|
||||
m_tasks.clear();
|
||||
// create folders
|
||||
{
|
||||
m_tasks.append(std::make_shared<FoldersTask>(m_inst));
|
||||
m_tasks.append(new FoldersTask(m_inst));
|
||||
}
|
||||
|
||||
// add metadata update task if necessary
|
||||
@ -53,23 +53,23 @@ void MinecraftUpdate::executeTask()
|
||||
auto task = components->getCurrentTask();
|
||||
if(task)
|
||||
{
|
||||
m_tasks.append(task.unwrap());
|
||||
m_tasks.append(task);
|
||||
}
|
||||
}
|
||||
|
||||
// libraries download
|
||||
{
|
||||
m_tasks.append(std::make_shared<LibrariesTask>(m_inst));
|
||||
m_tasks.append(new LibrariesTask(m_inst));
|
||||
}
|
||||
|
||||
// FML libraries download and copy into the instance
|
||||
{
|
||||
m_tasks.append(std::make_shared<FMLLibrariesTask>(m_inst));
|
||||
m_tasks.append(new FMLLibrariesTask(m_inst));
|
||||
}
|
||||
|
||||
// assets update
|
||||
{
|
||||
m_tasks.append(std::make_shared<AssetUpdateTask>(m_inst));
|
||||
m_tasks.append(new AssetUpdateTask(m_inst));
|
||||
}
|
||||
|
||||
if(!m_preFailure.isEmpty())
|
||||
|
@ -50,7 +50,7 @@ private:
|
||||
|
||||
private:
|
||||
MinecraftInstance *m_inst = nullptr;
|
||||
QList<std::shared_ptr<Task>> m_tasks;
|
||||
QList<Task::Ptr> m_tasks;
|
||||
QString m_preFailure;
|
||||
int m_currentTask = -1;
|
||||
bool m_abort = false;
|
||||
|
@ -264,7 +264,7 @@ void MinecraftAccount::authFailed(QString reason)
|
||||
}
|
||||
|
||||
bool MinecraftAccount::isActive() const {
|
||||
return m_currentTask;
|
||||
return !m_currentTask.isNull();
|
||||
}
|
||||
|
||||
bool MinecraftAccount::shouldRefresh() const {
|
||||
|
@ -63,6 +63,9 @@ void ModFolderModel::startWatching()
|
||||
if(is_watching)
|
||||
return;
|
||||
|
||||
// Remove orphaned metadata next time
|
||||
m_first_folder_load = true;
|
||||
|
||||
update();
|
||||
|
||||
// Watch the mods folder
|
||||
@ -113,7 +116,8 @@ bool ModFolderModel::update()
|
||||
}
|
||||
|
||||
auto index_dir = indexDir();
|
||||
auto task = new ModFolderLoadTask(dir(), index_dir, m_is_indexed);
|
||||
auto task = new ModFolderLoadTask(dir(), index_dir, m_is_indexed, m_first_folder_load);
|
||||
m_first_folder_load = false;
|
||||
|
||||
m_update = task->result();
|
||||
|
||||
|
@ -172,6 +172,7 @@ protected:
|
||||
bool interaction_disabled = false;
|
||||
QDir m_dir;
|
||||
bool m_is_indexed;
|
||||
bool m_first_folder_load = true;
|
||||
QMap<QString, int> modsIndex;
|
||||
QMap<int, LocalModParseTask::ResultPtr> activeTickets;
|
||||
int nextResolutionTicket = 0;
|
||||
|
@ -38,8 +38,8 @@
|
||||
|
||||
#include "minecraft/mod/MetadataHandler.h"
|
||||
|
||||
ModFolderLoadTask::ModFolderLoadTask(QDir& mods_dir, QDir& index_dir, bool is_indexed)
|
||||
: m_mods_dir(mods_dir), m_index_dir(index_dir), m_is_indexed(is_indexed), m_result(new Result())
|
||||
ModFolderLoadTask::ModFolderLoadTask(QDir& mods_dir, QDir& index_dir, bool is_indexed, bool clean_orphan)
|
||||
: m_mods_dir(mods_dir), m_index_dir(index_dir), m_is_indexed(is_indexed), m_clean_orphan(clean_orphan), m_result(new Result())
|
||||
{}
|
||||
|
||||
void ModFolderLoadTask::run()
|
||||
@ -85,12 +85,14 @@ void ModFolderLoadTask::run()
|
||||
|
||||
// Remove orphan metadata to prevent issues
|
||||
// See https://github.com/PolyMC/PolyMC/issues/996
|
||||
QMutableMapIterator<QString, Mod::Ptr> iter(m_result->mods);
|
||||
while (iter.hasNext()) {
|
||||
auto mod = iter.next().value();
|
||||
if (mod->status() == ModStatus::NotInstalled) {
|
||||
mod->destroy(m_index_dir, false);
|
||||
iter.remove();
|
||||
if (m_clean_orphan) {
|
||||
QMutableMapIterator<QString, Mod::Ptr> iter(m_result->mods);
|
||||
while (iter.hasNext()) {
|
||||
auto mod = iter.next().value();
|
||||
if (mod->status() == ModStatus::NotInstalled) {
|
||||
mod->destroy(m_index_dir, false);
|
||||
iter.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -56,7 +56,7 @@ public:
|
||||
}
|
||||
|
||||
public:
|
||||
ModFolderLoadTask(QDir& mods_dir, QDir& index_dir, bool is_indexed);
|
||||
ModFolderLoadTask(QDir& mods_dir, QDir& index_dir, bool is_indexed, bool clean_orphan = false);
|
||||
void run();
|
||||
signals:
|
||||
void succeeded();
|
||||
@ -67,5 +67,6 @@ private:
|
||||
private:
|
||||
QDir& m_mods_dir, m_index_dir;
|
||||
bool m_is_indexed;
|
||||
bool m_clean_orphan;
|
||||
ResultPtr m_result;
|
||||
};
|
||||
|
@ -48,7 +48,7 @@
|
||||
|
||||
#include "Application.h"
|
||||
#include "BuildConfig.h"
|
||||
#include "ui/dialogs/ScrollMessageBox.h"
|
||||
#include "ui/dialogs/BlockedModsDialog.h"
|
||||
|
||||
namespace ModpacksCH {
|
||||
|
||||
@ -173,6 +173,7 @@ void PackInstallTask::onResolveModsSucceeded()
|
||||
m_abortable = false;
|
||||
|
||||
QString text;
|
||||
QList<QUrl> urls;
|
||||
auto anyBlocked = false;
|
||||
|
||||
Flame::Manifest results = m_mod_id_resolver_task->getResults();
|
||||
@ -190,6 +191,7 @@ void PackInstallTask::onResolveModsSucceeded()
|
||||
|
||||
type[0] = type[0].toUpper();
|
||||
text += QString("%1: %2 - <a href='%3'>%3</a><br/>").arg(type, local_file.name, results_file.websiteUrl);
|
||||
urls.append(QUrl(results_file.websiteUrl));
|
||||
anyBlocked = true;
|
||||
} else {
|
||||
local_file.url = results_file.url.toString();
|
||||
@ -201,10 +203,11 @@ void PackInstallTask::onResolveModsSucceeded()
|
||||
if (anyBlocked) {
|
||||
qDebug() << "Blocked files found, displaying file list";
|
||||
|
||||
auto message_dialog = new ScrollMessageBox(m_parent, tr("Blocked files found"),
|
||||
auto message_dialog = new BlockedModsDialog(m_parent, tr("Blocked files found"),
|
||||
tr("The following files are not available for download in third party launchers.<br/>"
|
||||
"You will need to manually download them and add them to the instance."),
|
||||
text);
|
||||
text,
|
||||
urls);
|
||||
|
||||
if (message_dialog->exec() == QDialog::Accepted)
|
||||
downloadPack();
|
||||
|
@ -25,6 +25,7 @@ class Setting;
|
||||
class SettingsObject;
|
||||
|
||||
typedef std::shared_ptr<SettingsObject> SettingsObjectPtr;
|
||||
typedef std::weak_ptr<SettingsObject> SettingsObjectWeakPtr;
|
||||
|
||||
/*!
|
||||
* \brief The SettingsObject handles communicating settings between the application and a
|
||||
|
@ -157,10 +157,15 @@ AboutDialog::AboutDialog(QWidget *parent) : QDialog(parent), ui(new Ui::AboutDia
|
||||
else
|
||||
ui->platformLabel->setVisible(false);
|
||||
|
||||
if (BuildConfig.VERSION_BUILD >= 0)
|
||||
ui->buildNumLabel->setText(tr("Build Number") +": " + QString::number(BuildConfig.VERSION_BUILD));
|
||||
if (!BuildConfig.GIT_COMMIT.isEmpty())
|
||||
ui->commitLabel->setText(tr("Commit: %1").arg(BuildConfig.GIT_COMMIT));
|
||||
else
|
||||
ui->buildNumLabel->setVisible(false);
|
||||
ui->commitLabel->setVisible(false);
|
||||
|
||||
if (!BuildConfig.BUILD_DATE.isEmpty())
|
||||
ui->buildDateLabel->setText(tr("Build date: %1").arg(BuildConfig.BUILD_DATE));
|
||||
else
|
||||
ui->buildDateLabel->setVisible(false);
|
||||
|
||||
if (!BuildConfig.VERSION_CHANNEL.isEmpty())
|
||||
ui->channelLabel->setText(tr("Channel") +": " + BuildConfig.VERSION_CHANNEL);
|
||||
|
@ -184,12 +184,28 @@
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="buildNumLabel">
|
||||
<widget class="QLabel" name="buildDateLabel">
|
||||
<property name="cursor">
|
||||
<cursorShape>IBeamCursor</cursorShape>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Build Number:</string>
|
||||
<string>Build Date:</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
<property name="textInteractionFlags">
|
||||
<set>Qt::TextSelectableByMouse</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="commitLabel">
|
||||
<property name="cursor">
|
||||
<cursorShape>IBeamCursor</cursorShape>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Commit:</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
|
28
launcher/ui/dialogs/BlockedModsDialog.cpp
Normal file
28
launcher/ui/dialogs/BlockedModsDialog.cpp
Normal file
@ -0,0 +1,28 @@
|
||||
#include "BlockedModsDialog.h"
|
||||
#include "ui_BlockedModsDialog.h"
|
||||
#include <QPushButton>
|
||||
#include <QDialogButtonBox>
|
||||
#include <QDesktopServices>
|
||||
|
||||
|
||||
BlockedModsDialog::BlockedModsDialog(QWidget *parent, const QString &title, const QString &text, const QString &body, const QList<QUrl> &urls) :
|
||||
QDialog(parent), ui(new Ui::BlockedModsDialog), urls(urls) {
|
||||
ui->setupUi(this);
|
||||
|
||||
auto openAllButton = ui->buttonBox->addButton(tr("Open All"), QDialogButtonBox::ActionRole);
|
||||
connect(openAllButton, &QPushButton::clicked, this, &BlockedModsDialog::openAll);
|
||||
|
||||
this->setWindowTitle(title);
|
||||
ui->label->setText(text);
|
||||
ui->textBrowser->setText(body);
|
||||
}
|
||||
|
||||
BlockedModsDialog::~BlockedModsDialog() {
|
||||
delete ui;
|
||||
}
|
||||
|
||||
void BlockedModsDialog::openAll() {
|
||||
for(auto &url : urls) {
|
||||
QDesktopServices::openUrl(url);
|
||||
}
|
||||
}
|
22
launcher/ui/dialogs/BlockedModsDialog.h
Normal file
22
launcher/ui/dialogs/BlockedModsDialog.h
Normal file
@ -0,0 +1,22 @@
|
||||
#pragma once
|
||||
|
||||
#include <QDialog>
|
||||
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
namespace Ui { class BlockedModsDialog; }
|
||||
QT_END_NAMESPACE
|
||||
|
||||
class BlockedModsDialog : public QDialog {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
BlockedModsDialog(QWidget *parent, const QString &title, const QString &text, const QString &body, const QList<QUrl> &urls);
|
||||
|
||||
~BlockedModsDialog() override;
|
||||
|
||||
private:
|
||||
Ui::BlockedModsDialog *ui;
|
||||
const QList<QUrl> &urls;
|
||||
void openAll();
|
||||
};
|
84
launcher/ui/dialogs/BlockedModsDialog.ui
Normal file
84
launcher/ui/dialogs/BlockedModsDialog.ui
Normal file
@ -0,0 +1,84 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>BlockedModsDialog</class>
|
||||
<widget class="QDialog" name="BlockedModsDialog">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>400</width>
|
||||
<height>455</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string notr="true">BlockedModsDialog</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string notr="true"/>
|
||||
</property>
|
||||
<property name="textFormat">
|
||||
<enum>Qt::RichText</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QDialogButtonBox" name="buttonBox">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="standardButtons">
|
||||
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QTextBrowser" name="textBrowser">
|
||||
<property name="acceptRichText">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="openExternalLinks">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections>
|
||||
<connection>
|
||||
<sender>buttonBox</sender>
|
||||
<signal>accepted()</signal>
|
||||
<receiver>BlockedModsDialog</receiver>
|
||||
<slot>accept()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>199</x>
|
||||
<y>425</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>199</x>
|
||||
<y>227</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>buttonBox</sender>
|
||||
<signal>rejected()</signal>
|
||||
<receiver>BlockedModsDialog</receiver>
|
||||
<slot>reject()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>199</x>
|
||||
<y>425</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>199</x>
|
||||
<y>227</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
</connections>
|
||||
</ui>
|
@ -115,5 +115,5 @@ MinecraftAccountPtr LoginDialog::newAccount(QWidget *parent, QString msg)
|
||||
{
|
||||
return dlg.m_account;
|
||||
}
|
||||
return 0;
|
||||
return nullptr;
|
||||
}
|
||||
|
@ -169,5 +169,5 @@ MinecraftAccountPtr MSALoginDialog::newAccount(QWidget *parent, QString msg)
|
||||
{
|
||||
return dlg.m_account;
|
||||
}
|
||||
return 0;
|
||||
return nullptr;
|
||||
}
|
||||
|
@ -103,5 +103,5 @@ MinecraftAccountPtr OfflineLoginDialog::newAccount(QWidget *parent, QString msg)
|
||||
{
|
||||
return dlg.m_account;
|
||||
}
|
||||
return 0;
|
||||
return nullptr;
|
||||
}
|
||||
|
@ -101,7 +101,7 @@ ExternalResourcesPage::ExternalResourcesPage(BaseInstance* instance, std::shared
|
||||
{
|
||||
ui->setupUi(this);
|
||||
|
||||
runningStateChanged(m_instance && m_instance->isRunning());
|
||||
ExternalResourcesPage::runningStateChanged(m_instance && m_instance->isRunning());
|
||||
|
||||
ui->actionsToolbar->insertSpacer(ui->actionViewConfigs);
|
||||
|
||||
|
@ -46,7 +46,7 @@ class ExternalResourcesPage : public QMainWindow, public BasePage {
|
||||
protected slots:
|
||||
void itemActivated(const QModelIndex& index);
|
||||
void filterTextChanged(const QString& newContents);
|
||||
void runningStateChanged(bool running);
|
||||
virtual void runningStateChanged(bool running);
|
||||
|
||||
virtual void addItem();
|
||||
virtual void removeItem();
|
||||
|
@ -84,51 +84,46 @@ ModFolderPage::ModFolderPage(BaseInstance* inst, std::shared_ptr<ModFolderModel>
|
||||
ui->actionsToolbar->insertActionAfter(ui->actionAddItem, ui->actionUpdateItem);
|
||||
connect(ui->actionUpdateItem, &QAction::triggered, this, &ModFolderPage::updateMods);
|
||||
|
||||
connect(ui->treeView->selectionModel(), &QItemSelectionModel::selectionChanged, this,
|
||||
[this] { ui->actionUpdateItem->setEnabled(ui->treeView->selectionModel()->hasSelection() || !m_model->empty()); });
|
||||
auto check_allow_update = [this] {
|
||||
return (!m_instance || !m_instance->isRunning()) &&
|
||||
(ui->treeView->selectionModel()->hasSelection() || !m_model->empty());
|
||||
};
|
||||
|
||||
connect(mods.get(), &ModFolderModel::rowsInserted, this,
|
||||
[this] { ui->actionUpdateItem->setEnabled(ui->treeView->selectionModel()->hasSelection() || !m_model->empty()); });
|
||||
|
||||
connect(mods.get(), &ModFolderModel::updateFinished, this, [this, mods] {
|
||||
ui->actionUpdateItem->setEnabled(ui->treeView->selectionModel()->hasSelection() || !m_model->empty());
|
||||
connect(ui->treeView->selectionModel(), &QItemSelectionModel::selectionChanged, this, [this, check_allow_update] {
|
||||
ui->actionUpdateItem->setEnabled(check_allow_update());
|
||||
});
|
||||
|
||||
connect(mods.get(), &ModFolderModel::rowsInserted, this, [this, check_allow_update] {
|
||||
ui->actionUpdateItem->setEnabled(check_allow_update());
|
||||
});
|
||||
|
||||
connect(mods.get(), &ModFolderModel::rowsRemoved, this, [this, check_allow_update] {
|
||||
ui->actionUpdateItem->setEnabled(check_allow_update());
|
||||
});
|
||||
|
||||
connect(mods.get(), &ModFolderModel::updateFinished, this, [this, check_allow_update, mods] {
|
||||
ui->actionUpdateItem->setEnabled(check_allow_update());
|
||||
|
||||
// Prevent a weird crash when trying to open the mods page twice in a session o.O
|
||||
disconnect(mods.get(), &ModFolderModel::updateFinished, this, 0);
|
||||
});
|
||||
|
||||
ModFolderPage::runningStateChanged(m_instance && m_instance->isRunning());
|
||||
}
|
||||
}
|
||||
|
||||
CoreModFolderPage::CoreModFolderPage(BaseInstance* inst, std::shared_ptr<ModFolderModel> mods, QWidget* parent)
|
||||
: ModFolderPage(inst, mods, parent)
|
||||
{}
|
||||
void ModFolderPage::runningStateChanged(bool running)
|
||||
{
|
||||
ExternalResourcesPage::runningStateChanged(running);
|
||||
ui->actionDownloadItem->setEnabled(!running);
|
||||
ui->actionUpdateItem->setEnabled(!running);
|
||||
}
|
||||
|
||||
bool ModFolderPage::shouldDisplay() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CoreModFolderPage::shouldDisplay() const
|
||||
{
|
||||
if (ModFolderPage::shouldDisplay()) {
|
||||
auto inst = dynamic_cast<MinecraftInstance*>(m_instance);
|
||||
if (!inst)
|
||||
return true;
|
||||
|
||||
auto version = inst->getPackProfile();
|
||||
|
||||
if (!version)
|
||||
return true;
|
||||
if (!version->getComponent("net.minecraftforge"))
|
||||
return false;
|
||||
if (!version->getComponent("net.minecraft"))
|
||||
return false;
|
||||
if (version->getComponent("net.minecraft")->getReleaseDateTime() < g_VersionFilterData.legacyCutoffDate)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void ModFolderPage::installMods()
|
||||
{
|
||||
if (!m_controlsEnabled)
|
||||
@ -232,3 +227,28 @@ void ModFolderPage::updateMods()
|
||||
m_model->update();
|
||||
}
|
||||
}
|
||||
|
||||
CoreModFolderPage::CoreModFolderPage(BaseInstance* inst, std::shared_ptr<ModFolderModel> mods, QWidget* parent)
|
||||
: ModFolderPage(inst, mods, parent)
|
||||
{}
|
||||
|
||||
bool CoreModFolderPage::shouldDisplay() const
|
||||
{
|
||||
if (ModFolderPage::shouldDisplay()) {
|
||||
auto inst = dynamic_cast<MinecraftInstance*>(m_instance);
|
||||
if (!inst)
|
||||
return true;
|
||||
|
||||
auto version = inst->getPackProfile();
|
||||
|
||||
if (!version)
|
||||
return true;
|
||||
if (!version->getComponent("net.minecraftforge"))
|
||||
return false;
|
||||
if (!version->getComponent("net.minecraft"))
|
||||
return false;
|
||||
if (version->getComponent("net.minecraft")->getReleaseDateTime() < g_VersionFilterData.legacyCutoffDate)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
@ -53,6 +53,7 @@ class ModFolderPage : public ExternalResourcesPage {
|
||||
virtual QString helpPage() const override { return "Loader-mods"; }
|
||||
|
||||
virtual bool shouldDisplay() const override;
|
||||
void runningStateChanged(bool running) override;
|
||||
|
||||
private slots:
|
||||
void installMods();
|
||||
@ -63,5 +64,11 @@ class CoreModFolderPage : public ModFolderPage {
|
||||
public:
|
||||
explicit CoreModFolderPage(BaseInstance* inst, std::shared_ptr<ModFolderModel> mods, QWidget* parent = 0);
|
||||
virtual ~CoreModFolderPage() = default;
|
||||
virtual bool shouldDisplay() const;
|
||||
|
||||
virtual QString displayName() const override { return tr("Core mods"); }
|
||||
virtual QIcon icon() const override { return APPLICATION->getThemedIcon("coremods"); }
|
||||
virtual QString id() const override { return "coremods"; }
|
||||
virtual QString helpPage() const override { return "Core-mods"; }
|
||||
|
||||
virtual bool shouldDisplay() const override;
|
||||
};
|
||||
|
@ -25,12 +25,11 @@
|
||||
|
||||
#include "BuildConfig.h"
|
||||
|
||||
UpdateChecker::UpdateChecker(shared_qobject_ptr<QNetworkAccessManager> nam, QString channelUrl, QString currentChannel, int currentBuild)
|
||||
UpdateChecker::UpdateChecker(shared_qobject_ptr<QNetworkAccessManager> nam, QString channelUrl, QString currentChannel)
|
||||
{
|
||||
m_network = nam;
|
||||
m_channelUrl = channelUrl;
|
||||
m_currentChannel = currentChannel;
|
||||
m_currentBuild = currentBuild;
|
||||
|
||||
#ifdef Q_OS_MAC
|
||||
m_externalUpdater = new MacSparkleUpdater();
|
||||
|
@ -28,7 +28,7 @@ class UpdateChecker : public QObject
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
UpdateChecker(shared_qobject_ptr<QNetworkAccessManager> nam, QString channelUrl, QString currentChannel, int currentBuild);
|
||||
UpdateChecker(shared_qobject_ptr<QNetworkAccessManager> nam, QString channelUrl, QString currentChannel);
|
||||
void checkForUpdate(const QString& updateChannel, bool notifyNoUpdate);
|
||||
|
||||
/*!
|
||||
|
@ -16,7 +16,7 @@ A performance optimization daemon.
|
||||
|
||||
See [github repo](https://github.com/FeralInteractive/gamemode).
|
||||
|
||||
BSD licensed
|
||||
BSD-3-Clause licensed
|
||||
|
||||
## hoedown
|
||||
|
||||
@ -161,9 +161,9 @@ Public domain (the author disclaimed the copyright).
|
||||
|
||||
## quazip
|
||||
|
||||
A zip manipulation library, forked for MultiMC's use.
|
||||
A zip manipulation library.
|
||||
|
||||
LGPL 2.1
|
||||
LGPL 2.1 with linking exception.
|
||||
|
||||
## rainbow
|
||||
|
||||
@ -173,7 +173,7 @@ Available either under LGPL version 2.1 or later.
|
||||
|
||||
## systeminfo
|
||||
|
||||
A MultiMC-specific library for probing system information.
|
||||
A PolyMC-specific library for probing system information.
|
||||
|
||||
Apache 2.0
|
||||
|
||||
@ -187,6 +187,6 @@ Licenced under the MIT licence.
|
||||
|
||||
## xz-embedded
|
||||
|
||||
Tiny implementation of LZMA2 de/compression. This format is only used by Forge to save bandwidth.
|
||||
Tiny implementation of LZMA2 de/compression. This format was only used by Forge to save bandwidth.
|
||||
|
||||
Public domain.
|
||||
|
@ -6,7 +6,7 @@
|
||||
</provides>
|
||||
<launchable type="desktop-id">org.polymc.PolyMC.desktop</launchable>
|
||||
<name>PolyMC</name>
|
||||
<developer_name>PolyMC Team</developer_name>
|
||||
<developer_name>PolyMC</developer_name>
|
||||
<summary>A custom launcher for Minecraft that allows you to easily manage multiple installations of Minecraft at once</summary>
|
||||
<metadata_license>CC0-1.0</metadata_license>
|
||||
<project_license>GPL-3.0-only</project_license>
|
||||
@ -16,39 +16,43 @@
|
||||
<p>PolyMC is a custom launcher for Minecraft that focuses on predictability, long term stability and simplicity.</p>
|
||||
<p>Features:</p>
|
||||
<ul>
|
||||
<li>Easily install game modifications, such as Fabric or Forge</li>
|
||||
<li>Easily install game modifications, such as Fabric, Forge and Quilt</li>
|
||||
<li>Control your java settings</li>
|
||||
<li>Manage worlds and resource packs from the launcher</li>
|
||||
<li>See logs and other details easily</li>
|
||||
<li>Kill Minecraft in case of a crash/freeze</li>
|
||||
<li>Isolate minecraft instances to keep everything clean</li>
|
||||
<li>Install mods directly from the launcher</li>
|
||||
<li>Install and update mods directly from the launcher</li>
|
||||
</ul>
|
||||
</description>
|
||||
<screenshots>
|
||||
<screenshot type="default">
|
||||
<caption>The main PolyMC window</caption>
|
||||
<image type="source" width="931" height="759">https://polymc.org/img/screenshots/LauncherDark.png</image>
|
||||
<image type="source" width="578" height="452">https://polymc.org/img/screenshots/LauncherDark.png</image>
|
||||
</screenshot>
|
||||
<screenshot>
|
||||
<caption>Modpack installation</caption>
|
||||
<image type="source" width="860" height="848">https://polymc.org/img/screenshots/ModpackInstallDark.png</image>
|
||||
<image type="source" width="523" height="452">https://polymc.org/img/screenshots/ModpackInstallDark.png</image>
|
||||
</screenshot>
|
||||
<screenshot>
|
||||
<caption>Mod installation</caption>
|
||||
<image type="source" width="1018" height="858">https://polymc.org/img/screenshots/ModInstallDark.png</image>
|
||||
<image type="source" width="654" height="452">https://polymc.org/img/screenshots/ModInstallDark.png</image>
|
||||
</screenshot>
|
||||
<screenshot>
|
||||
<caption>Mod updating</caption>
|
||||
<image type="source" width="490" height="452">https://polymc.org/img/screenshots/ModUpdateDark.png</image>
|
||||
</screenshot>
|
||||
<screenshot>
|
||||
<caption>Instance management</caption>
|
||||
<image type="source" width="777" height="693">https://polymc.org/img/screenshots/PropertiesDark.png</image>
|
||||
<image type="source" width="667" height="452">https://polymc.org/img/screenshots/PropertiesDark.png</image>
|
||||
</screenshot>
|
||||
<screenshot>
|
||||
<caption>Cat :)</caption>
|
||||
<image type="source" width="931" height="759">https://polymc.org/img/screenshots/LauncherCatDark.png</image>
|
||||
<image type="source" width="555" height="452">https://polymc.org/img/screenshots/LauncherCatDark.png</image>
|
||||
</screenshot>
|
||||
</screenshots>
|
||||
<releases>
|
||||
<release version="@Launcher_RELEASE_VERSION_NAME@" date="@Launcher_RELEASE_TIMESTAMP@"></release>
|
||||
<release version="@Launcher_VERSION_NAME@" date="@Launcher_BUILD_TIMESTAMP@"></release>
|
||||
</releases>
|
||||
<content_rating type="oars-1.1">
|
||||
<content_attribute id="violence-fantasy">moderate</content_attribute>
|
||||
|
@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0" xmlns:asmv3="urn:schemas-microsoft-com:asm.v3">
|
||||
<assemblyIdentity name="PolyMC.Application.1" type="win32" version="@Launcher_RELEASE_VERSION_NAME4@" />
|
||||
<assemblyIdentity name="PolyMC.Application.1" type="win32" version="@Launcher_VERSION_NAME4@" />
|
||||
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
|
||||
<security>
|
||||
<requestedPrivileges>
|
||||
|
@ -7,7 +7,7 @@ IDI_ICON1 ICON DISCARDABLE "polymc.ico"
|
||||
1 RT_MANIFEST "polymc.manifest"
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION @Launcher_RELEASE_VERSION_NAME4_COMMA@
|
||||
FILEVERSION @Launcher_VERSION_NAME4_COMMA@
|
||||
FILEOS VOS_NT_WINDOWS32
|
||||
FILETYPE VFT_APP
|
||||
BEGIN
|
||||
@ -17,9 +17,9 @@ BEGIN
|
||||
BEGIN
|
||||
VALUE "CompanyName", "MultiMC & PolyMC Contributors"
|
||||
VALUE "FileDescription", "PolyMC"
|
||||
VALUE "FileVersion", "@Launcher_RELEASE_VERSION_NAME4@"
|
||||
VALUE "FileVersion", "@Launcher_VERSION_NAME4@"
|
||||
VALUE "ProductName", "PolyMC"
|
||||
VALUE "ProductVersion", "@Launcher_RELEASE_VERSION_NAME4@"
|
||||
VALUE "ProductVersion", "@Launcher_VERSION_NAME4@"
|
||||
END
|
||||
END
|
||||
BLOCK "VarFileInfo"
|
||||
|
@ -102,13 +102,13 @@ OutFile "../@Launcher_CommonName@-Setup.exe"
|
||||
;--------------------------------
|
||||
|
||||
; Version info
|
||||
VIProductVersion "@Launcher_RELEASE_VERSION_NAME4@"
|
||||
VIFileVersion "@Launcher_RELEASE_VERSION_NAME4@"
|
||||
VIProductVersion "@Launcher_VERSION_NAME4@"
|
||||
VIFileVersion "@Launcher_VERSION_NAME4@"
|
||||
VIAddVersionKey /LANG=${LANG_ENGLISH} "ProductName" "@Launcher_CommonName@"
|
||||
VIAddVersionKey /LANG=${LANG_ENGLISH} "FileDescription" "@Launcher_CommonName@ Installer"
|
||||
VIAddVersionKey /LANG=${LANG_ENGLISH} "LegalCopyright" "@Launcher_Copyright@"
|
||||
VIAddVersionKey /LANG=${LANG_ENGLISH} "FileVersion" "@Launcher_RELEASE_VERSION_NAME4@"
|
||||
VIAddVersionKey /LANG=${LANG_ENGLISH} "ProductVersion" "@Launcher_RELEASE_VERSION_NAME4@"
|
||||
VIAddVersionKey /LANG=${LANG_ENGLISH} "FileVersion" "@Launcher_VERSION_NAME4@"
|
||||
VIAddVersionKey /LANG=${LANG_ENGLISH} "ProductVersion" "@Launcher_VERSION_NAME4@"
|
||||
|
||||
;--------------------------------
|
||||
|
||||
@ -145,8 +145,8 @@ Section "@Launcher_CommonName@"
|
||||
WriteRegStr HKCU "${UNINST_KEY}" "QuietUninstallString" '"$INSTDIR\uninstall.exe" /S'
|
||||
WriteRegStr HKCU "${UNINST_KEY}" "InstallLocation" "$INSTDIR"
|
||||
WriteRegStr HKCU "${UNINST_KEY}" "Publisher" "@Launcher_CommonName@ Contributors"
|
||||
WriteRegStr HKCU "${UNINST_KEY}" "Version" "@Launcher_RELEASE_VERSION_NAME4@"
|
||||
WriteRegStr HKCU "${UNINST_KEY}" "DisplayVersion" "@Launcher_RELEASE_VERSION_NAME@"
|
||||
WriteRegStr HKCU "${UNINST_KEY}" "Version" "@Launcher_VERSION_NAME4@"
|
||||
WriteRegStr HKCU "${UNINST_KEY}" "DisplayVersion" "@Launcher_VERSION_NAME@"
|
||||
WriteRegStr HKCU "${UNINST_KEY}" "VersionMajor" "@Launcher_VERSION_MAJOR@"
|
||||
WriteRegStr HKCU "${UNINST_KEY}" "VersionMinor" "@Launcher_VERSION_MINOR@"
|
||||
${GetSize} "$INSTDIR" "/S=0K" $0 $1 $2
|
||||
|
Loading…
Reference in New Issue
Block a user