diff options
-rw-r--r-- | CMakeLists.txt | 3 | ||||
-rw-r--r-- | launcher/Application.cpp | 22 | ||||
-rw-r--r-- | launcher/Application.h | 2 | ||||
-rw-r--r-- | launcher/BaseInstance.cpp | 2 | ||||
-rw-r--r-- | launcher/InstanceList.cpp | 16 | ||||
-rw-r--r-- | launcher/icons/IconList.cpp | 11 | ||||
-rw-r--r-- | launcher/icons/IconList.h | 1 | ||||
-rw-r--r-- | launcher/minecraft/MinecraftInstance.cpp | 2 | ||||
-rw-r--r-- | launcher/net/Download.cpp | 2 | ||||
-rw-r--r-- | launcher/net/PasteUpload.cpp | 4 | ||||
-rw-r--r-- | launcher/net/Upload.cpp | 2 | ||||
-rw-r--r-- | launcher/screenshots/ImgurAlbumCreation.cpp | 2 | ||||
-rw-r--r-- | launcher/screenshots/ImgurUpload.cpp | 3 | ||||
-rw-r--r-- | launcher/ui/pages/global/APIPage.cpp | 5 | ||||
-rw-r--r-- | launcher/ui/pages/global/APIPage.ui | 129 | ||||
-rw-r--r-- | libraries/launcher/net/minecraft/Launcher.java | 65 |
16 files changed, 209 insertions, 62 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index 11d58213..a0ae0a4f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -45,8 +45,7 @@ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DQT_NO_DEPRECATED_WARNINGS=Y") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DQT_DISABLE_DEPRECATED_BEFORE=0x050C00") # set CXXFLAGS for build targets -set(CMAKE_CXX_FLAGS_DEBUG "-O2 -D_FORTIFY_SOURCE=2 ${CMAKE_CXX_FLAGS}") -set(CMAKE_CXX_FLAGS_RELEASE "-O2 -D_FORTIFY_SOURCE=2 ${CMAKE_CXX_FLAGS}") +set(CMAKE_CXX_FLAGS_RELEASE "-O2 -D_FORTIFY_SOURCE=2 ${CMAKE_CXX_FLAGS_RELEASE}") option(ENABLE_LTO "Enable Link Time Optimization" off) diff --git a/launcher/Application.cpp b/launcher/Application.cpp index 99e3d4c5..a4525d83 100644 --- a/launcher/Application.cpp +++ b/launcher/Application.cpp @@ -711,6 +711,7 @@ Application::Application(int &argc, char **argv) : QApplication(argc, argv) // Custom MSA credentials m_settings->registerSetting("MSAClientIDOverride", ""); m_settings->registerSetting("CFKeyOverride", ""); + m_settings->registerSetting("UserAgentOverride", ""); // Init page provider { @@ -1556,3 +1557,24 @@ QString Application::getCurseKey() return BuildConfig.CURSEFORGE_API_KEY; } + +QString Application::getUserAgent() +{ + QString uaOverride = m_settings->get("UserAgentOverride").toString(); + if (!uaOverride.isEmpty()) { + return uaOverride.replace("$LAUNCHER_VER", BuildConfig.printableVersionString()); + } + + return BuildConfig.USER_AGENT; +} + +QString Application::getUserAgentUncached() +{ + QString uaOverride = m_settings->get("UserAgentOverride").toString(); + if (!uaOverride.isEmpty()) { + uaOverride += " (Uncached)"; + return uaOverride.replace("$LAUNCHER_VER", BuildConfig.printableVersionString()); + } + + return BuildConfig.USER_AGENT_UNCACHED; +} diff --git a/launcher/Application.h b/launcher/Application.h index 3129b4fb..f440f433 100644 --- a/launcher/Application.h +++ b/launcher/Application.h @@ -156,6 +156,8 @@ public: QString getMSAClientID(); QString getCurseKey(); + QString getUserAgent(); + QString getUserAgentUncached(); /// this is the root of the 'installation'. Used for automatic updates const QString &root() { diff --git a/launcher/BaseInstance.cpp b/launcher/BaseInstance.cpp index 2fb31d94..0240afa8 100644 --- a/launcher/BaseInstance.cpp +++ b/launcher/BaseInstance.cpp @@ -59,7 +59,7 @@ BaseInstance::BaseInstance(SettingsObjectPtr globalSettings, SettingsObjectPtr s m_settings->registerSetting("lastLaunchTime", 0); m_settings->registerSetting("totalTimePlayed", 0); m_settings->registerSetting("lastTimePlayed", 0); - m_settings->registerSetting("InstanceType", "OneSix"); + m_settings->registerSetting("InstanceType", ""); // Custom Commands auto commandSetting = m_settings->registerSetting({"OverrideCommands","OverrideLaunchCmd"}, false); diff --git a/launcher/InstanceList.cpp b/launcher/InstanceList.cpp index 847d897e..3e3c81f7 100644 --- a/launcher/InstanceList.cpp +++ b/launcher/InstanceList.cpp @@ -547,8 +547,20 @@ InstancePtr InstanceList::loadInstance(const InstanceId& id) auto instanceRoot = FS::PathCombine(m_instDir, id); auto instanceSettings = std::make_shared<INISettingsObject>(FS::PathCombine(instanceRoot, "instance.cfg")); InstancePtr inst; - // TODO: Handle incompatible instances - inst.reset(new MinecraftInstance(m_globalSettings, instanceSettings, instanceRoot)); + + instanceSettings->registerSetting("InstanceType", ""); + + QString inst_type = instanceSettings->get("InstanceType").toString(); + + // NOTE: Some PolyMC versions didn't save the InstanceType properly. We will just bank on the probability that this is probably a OneSix instance + if (inst_type == "OneSix" || inst_type.isEmpty()) + { + inst.reset(new MinecraftInstance(m_globalSettings, instanceSettings, instanceRoot)); + } + else + { + inst.reset(new NullInstance(m_globalSettings, instanceSettings, instanceRoot)); + } qDebug() << "Loaded instance " << inst->name() << " from " << inst->instanceRoot(); return inst; } diff --git a/launcher/icons/IconList.cpp b/launcher/icons/IconList.cpp index 0ddfae55..d426aa80 100644 --- a/launcher/icons/IconList.cpp +++ b/launcher/icons/IconList.cpp @@ -56,6 +56,15 @@ IconList::IconList(const QStringList &builtinPaths, QString path, QObject *paren emit iconUpdated({}); } +void IconList::sortIconList() +{ + qDebug() << "Sorting icon list..."; + std::sort(icons.begin(), icons.end(), [](const MMCIcon& a, const MMCIcon& b) { + return a.m_key.localeAwareCompare(b.m_key) < 0; + }); + reindex(); +} + void IconList::directoryChanged(const QString &path) { QDir new_dir (path); @@ -141,6 +150,8 @@ void IconList::directoryChanged(const QString &path) emit iconUpdated(key); } } + + sortIconList(); } void IconList::fileChanged(const QString &path) diff --git a/launcher/icons/IconList.h b/launcher/icons/IconList.h index ebbb52e2..f9f49e7f 100644 --- a/launcher/icons/IconList.h +++ b/launcher/icons/IconList.h @@ -71,6 +71,7 @@ private: // hide assign op IconList &operator=(const IconList &) = delete; void reindex(); + void sortIconList(); public slots: void directoryChanged(const QString &path); diff --git a/launcher/minecraft/MinecraftInstance.cpp b/launcher/minecraft/MinecraftInstance.cpp index 2f339014..e99d30fe 100644 --- a/launcher/minecraft/MinecraftInstance.cpp +++ b/launcher/minecraft/MinecraftInstance.cpp @@ -168,6 +168,8 @@ MinecraftInstance::MinecraftInstance(SettingsObjectPtr globalSettings, SettingsO m_settings->registerOverride(globalSettings->getSetting("CloseAfterLaunch"), miscellaneousOverride); m_settings->registerOverride(globalSettings->getSetting("QuitAfterGameStop"), miscellaneousOverride); + m_settings->set("InstanceType", "OneSix"); + m_components.reset(new PackProfile(this)); } diff --git a/launcher/net/Download.cpp b/launcher/net/Download.cpp index 966d4126..d93eb088 100644 --- a/launcher/net/Download.cpp +++ b/launcher/net/Download.cpp @@ -116,7 +116,7 @@ void Download::executeTask() return; } - request.setHeader(QNetworkRequest::UserAgentHeader, BuildConfig.USER_AGENT); + request.setHeader(QNetworkRequest::UserAgentHeader, APPLICATION->getUserAgent().toUtf8()); if (request.url().host().contains("api.curseforge.com")) { request.setRawHeader("x-api-key", APPLICATION->getCurseKey().toUtf8()); }; diff --git a/launcher/net/PasteUpload.cpp b/launcher/net/PasteUpload.cpp index 3855190a..ead5e170 100644 --- a/launcher/net/PasteUpload.cpp +++ b/launcher/net/PasteUpload.cpp @@ -71,7 +71,7 @@ void PasteUpload::executeTask() QNetworkRequest request{QUrl(m_uploadUrl)}; QNetworkReply *rep{}; - request.setHeader(QNetworkRequest::UserAgentHeader, BuildConfig.USER_AGENT_UNCACHED); + request.setHeader(QNetworkRequest::UserAgentHeader, APPLICATION->getUserAgentUncached().toUtf8()); switch (m_pasteType) { case NullPointer: { @@ -91,7 +91,7 @@ void PasteUpload::executeTask() break; } case Hastebin: { - request.setHeader(QNetworkRequest::UserAgentHeader, BuildConfig.USER_AGENT_UNCACHED); + request.setHeader(QNetworkRequest::UserAgentHeader, APPLICATION->getUserAgentUncached().toUtf8()); rep = APPLICATION->network()->post(request, m_text); break; } diff --git a/launcher/net/Upload.cpp b/launcher/net/Upload.cpp index bbd27390..c9942a8d 100644 --- a/launcher/net/Upload.cpp +++ b/launcher/net/Upload.cpp @@ -173,7 +173,7 @@ namespace Net { return; } - request.setHeader(QNetworkRequest::UserAgentHeader, BuildConfig.USER_AGENT); + request.setHeader(QNetworkRequest::UserAgentHeader, APPLICATION->getUserAgent().toUtf8()); if (request.url().host().contains("api.curseforge.com")) { request.setRawHeader("x-api-key", APPLICATION->getCurseKey().toUtf8()); } diff --git a/launcher/screenshots/ImgurAlbumCreation.cpp b/launcher/screenshots/ImgurAlbumCreation.cpp index 7afdc5cc..04e26ea2 100644 --- a/launcher/screenshots/ImgurAlbumCreation.cpp +++ b/launcher/screenshots/ImgurAlbumCreation.cpp @@ -55,7 +55,7 @@ void ImgurAlbumCreation::executeTask() { m_state = State::Running; QNetworkRequest request(m_url); - request.setHeader(QNetworkRequest::UserAgentHeader, BuildConfig.USER_AGENT_UNCACHED); + request.setHeader(QNetworkRequest::UserAgentHeader, APPLICATION->getUserAgentUncached().toUtf8()); request.setHeader(QNetworkRequest::ContentTypeHeader, "application/x-www-form-urlencoded"); request.setRawHeader("Authorization", QString("Client-ID %1").arg(BuildConfig.IMGUR_CLIENT_ID).toStdString().c_str()); request.setRawHeader("Accept", "application/json"); diff --git a/launcher/screenshots/ImgurUpload.cpp b/launcher/screenshots/ImgurUpload.cpp index fbcfb95f..9aeb6fb8 100644 --- a/launcher/screenshots/ImgurUpload.cpp +++ b/launcher/screenshots/ImgurUpload.cpp @@ -35,6 +35,7 @@ #include "ImgurUpload.h" #include "BuildConfig.h" +#include "Application.h" #include <QNetworkRequest> #include <QHttpMultiPart> @@ -56,7 +57,7 @@ void ImgurUpload::executeTask() finished = false; m_state = Task::State::Running; QNetworkRequest request(m_url); - request.setHeader(QNetworkRequest::UserAgentHeader, BuildConfig.USER_AGENT_UNCACHED); + request.setHeader(QNetworkRequest::UserAgentHeader, APPLICATION->getUserAgentUncached().toUtf8()); request.setRawHeader("Authorization", QString("Client-ID %1").arg(BuildConfig.IMGUR_CLIENT_ID).toStdString().c_str()); request.setRawHeader("Accept", "application/json"); diff --git a/launcher/ui/pages/global/APIPage.cpp b/launcher/ui/pages/global/APIPage.cpp index 5d812d07..b889e6f7 100644 --- a/launcher/ui/pages/global/APIPage.cpp +++ b/launcher/ui/pages/global/APIPage.cpp @@ -75,9 +75,9 @@ APIPage::APIPage(QWidget *parent) : // This function needs to be called even when the ComboBox's index is still in its default state. updateBaseURLPlaceholder(ui->pasteTypeComboBox->currentIndex()); ui->baseURLEntry->setValidator(new QRegularExpressionValidator(validUrlRegExp, ui->baseURLEntry)); - ui->tabWidget->tabBar()->hide(); ui->metaURL->setPlaceholderText(BuildConfig.META_URL); + ui->userAgentLineEdit->setPlaceholderText(BuildConfig.USER_AGENT); loadSettings(); @@ -139,6 +139,8 @@ void APIPage::loadSettings() ui->metaURL->setText(metaURL); QString curseKey = s->get("CFKeyOverride").toString(); ui->curseKey->setText(curseKey); + QString customUserAgent = s->get("UserAgentOverride").toString(); + ui->userAgentLineEdit->setText(customUserAgent); } void APIPage::applySettings() @@ -167,6 +169,7 @@ void APIPage::applySettings() s->set("MetaURLOverride", metaURL); QString curseKey = ui->curseKey->text(); s->set("CFKeyOverride", curseKey); + s->set("UserAgentOverride", ui->userAgentLineEdit->text()); } bool APIPage::apply() diff --git a/launcher/ui/pages/global/APIPage.ui b/launcher/ui/pages/global/APIPage.ui index 5c927391..5327771c 100644 --- a/launcher/ui/pages/global/APIPage.ui +++ b/launcher/ui/pages/global/APIPage.ui @@ -30,7 +30,7 @@ </property> <widget class="QWidget" name="tab"> <attribute name="title"> - <string notr="true">Tab 1</string> + <string notr="true">Services</string> </attribute> <layout class="QVBoxLayout" name="verticalLayout_2"> <item> @@ -86,15 +86,15 @@ </widget> </item> <item> - <widget class="QGroupBox" name="groupBox_msa"> + <widget class="QGroupBox" name="groupBox_meta"> <property name="title"> - <string>&Microsoft Authentication</string> + <string>Meta&data Server</string> </property> - <layout class="QVBoxLayout" name="verticalLayout_4"> + <layout class="QVBoxLayout" name="verticalLayout_5"> <item> - <widget class="QLabel" name="label_3"> + <widget class="QLabel" name="label_5"> <property name="text"> - <string>Note: you probably don't need to set this if logging in via Microsoft Authentication already works.</string> + <string>You can set this to a third-party metadata server to use patched libraries or other hacks.</string> </property> <property name="textFormat"> <enum>Qt::RichText</enum> @@ -105,16 +105,16 @@ </widget> </item> <item> - <widget class="QLineEdit" name="msaClientID"> + <widget class="QLineEdit" name="metaURL"> <property name="placeholderText"> - <string>(Default)</string> + <string/> </property> </widget> </item> <item> - <widget class="QLabel" name="label_4"> + <widget class="QLabel" name="label_6"> <property name="text"> - <string>Enter a custom client ID for Microsoft Authentication here. </string> + <string>Enter a custom URL for meta here.</string> </property> <property name="textFormat"> <enum>Qt::RichText</enum> @@ -131,15 +131,35 @@ </widget> </item> <item> - <widget class="QGroupBox" name="groupBox_meta"> + <spacer name="verticalSpacer_2"> + <property name="orientation"> + <enum>Qt::Vertical</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>20</width> + <height>40</height> + </size> + </property> + </spacer> + </item> + </layout> + </widget> + <widget class="QWidget" name="tab_2"> + <attribute name="title"> + <string>API Keys</string> + </attribute> + <layout class="QVBoxLayout" name="verticalLayout_8"> + <item> + <widget class="QGroupBox" name="groupBox_msa"> <property name="title"> - <string>Meta&data Server</string> + <string>&Microsoft Authentication</string> </property> - <layout class="QVBoxLayout" name="verticalLayout_5"> + <layout class="QVBoxLayout" name="verticalLayout_4"> <item> - <widget class="QLabel" name="label_5"> + <widget class="QLabel" name="label_3"> <property name="text"> - <string>You can set this to a third-party metadata server to use patched libraries or other hacks.</string> + <string>Note: you probably don't need to set this if logging in via Microsoft Authentication already works.</string> </property> <property name="textFormat"> <enum>Qt::RichText</enum> @@ -150,16 +170,16 @@ </widget> </item> <item> - <widget class="QLineEdit" name="metaURL"> + <widget class="QLineEdit" name="msaClientID"> <property name="placeholderText"> - <string/> + <string>(Default)</string> </property> </widget> </item> <item> - <widget class="QLabel" name="label_6"> + <widget class="QLabel" name="label_4"> <property name="text"> - <string>Enter a custom URL for meta here.</string> + <string>Enter a custom client ID for Microsoft Authentication here. </string> </property> <property name="textFormat"> <enum>Qt::RichText</enum> @@ -183,25 +203,15 @@ <property name="title"> <string>&CurseForge Core API</string> </property> - <layout class="QVBoxLayout" name="verticalLayout_6"> - <item> + <layout class="QGridLayout" name="gridLayout"> + <item row="0" column="0"> <widget class="QLabel" name="label_8"> <property name="text"> <string>Note: you probably don't need to set this if CurseForge already works.</string> </property> </widget> </item> - <item> - <widget class="QLineEdit" name="curseKey"> - <property name="enabled"> - <bool>true</bool> - </property> - <property name="placeholderText"> - <string>(Default)</string> - </property> - </widget> - </item> - <item> + <item row="2" column="0"> <widget class="QLabel" name="label_7"> <property name="text"> <string>Enter a custom API Key for CurseForge here. </string> @@ -217,6 +227,16 @@ </property> </widget> </item> + <item row="1" column="0"> + <widget class="QLineEdit" name="curseKey"> + <property name="enabled"> + <bool>true</bool> + </property> + <property name="placeholderText"> + <string>(Default)</string> + </property> + </widget> + </item> </layout> </widget> </item> @@ -235,6 +255,51 @@ </item> </layout> </widget> + <widget class="QWidget" name="tab_3"> + <attribute name="title"> + <string>Miscellaneous</string> + </attribute> + <layout class="QVBoxLayout" name="verticalLayout_6"> + <item> + <widget class="QGroupBox" name="groupBox_ua"> + <property name="minimumSize"> + <size> + <width>0</width> + <height>0</height> + </size> + </property> + <property name="title"> + <string>User Agent</string> + </property> + <layout class="QVBoxLayout" name="verticalLayout_7"> + <item> + <widget class="QLineEdit" name="userAgentLineEdit"/> + </item> + <item> + <widget class="QLabel" name="userAgentLabel"> + <property name="text"> + <string>Enter a custom User Agent here. The special string $LAUNCHER_VER will be replaced with the version of the launcher.</string> + </property> + </widget> + </item> + </layout> + </widget> + </item> + <item> + <spacer name="verticalSpacer_3"> + <property name="orientation"> + <enum>Qt::Vertical</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>20</width> + <height>40</height> + </size> + </property> + </spacer> + </item> + </layout> + </widget> </widget> </item> </layout> diff --git a/libraries/launcher/net/minecraft/Launcher.java b/libraries/launcher/net/minecraft/Launcher.java index 265fa66a..6bf671be 100644 --- a/libraries/launcher/net/minecraft/Launcher.java +++ b/libraries/launcher/net/minecraft/Launcher.java @@ -24,24 +24,65 @@ import java.net.URL; import java.util.Map; import java.util.TreeMap; +/* + * WARNING: This class is reflectively accessed by legacy Forge versions. + * Changing field and method declarations without further testing is not recommended. + */ public final class Launcher extends Applet implements AppletStub { private final Map<String, String> params = new TreeMap<>(); - private final Applet wrappedApplet; + private Applet wrappedApplet; + + private URL documentBase; private boolean active = false; public Launcher(Applet applet) { + this(applet, null); + } + + public Launcher(Applet applet, URL documentBase) { this.setLayout(new BorderLayout()); this.add(applet, "Center"); this.wrappedApplet = applet; + + try { + if (documentBase != null) { + this.documentBase = documentBase; + } else if (applet.getClass().getPackage().getName().startsWith("com.mojang")) { + // Special case only for Classic versions + + this.documentBase = new URL("http", "www.minecraft.net", 80, "/game/"); + } else { + this.documentBase = new URL("http://www.minecraft.net/game/"); + } + } catch (MalformedURLException e) { + throw new RuntimeException(e); + } + } + + public void replace(Applet applet) { + this.wrappedApplet = applet; + + applet.setStub(this); + applet.setSize(getWidth(), getHeight()); + + this.setLayout(new BorderLayout()); + this.add(applet, "Center"); + + applet.init(); + + active = true; + + applet.start(); + + validate(); } - public void setParameter(String name, String value) - { + public void setParameter(String name, String value) { params.put(name, value); } @@ -54,7 +95,7 @@ public final class Launcher extends Applet implements AppletStub { try { return super.getParameter(name); - } catch (Exception ignore) {} + } catch (Exception ignored) {} return null; } @@ -108,25 +149,13 @@ public final class Launcher extends Applet implements AppletStub { try { return new URL("http://www.minecraft.net/game/"); } catch (MalformedURLException e) { - e.printStackTrace(); + throw new RuntimeException(e); } - - return null; } @Override public URL getDocumentBase() { - try { - // Special case only for Classic versions - if (wrappedApplet.getClass().getCanonicalName().startsWith("com.mojang")) - return new URL("http", "www.minecraft.net", 80, "/game/"); - - return new URL("http://www.minecraft.net/game/"); - } catch (MalformedURLException e) { - e.printStackTrace(); - } - - return null; + return documentBase; } @Override |