aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CMakeLists.txt3
-rw-r--r--launcher/Application.cpp22
-rw-r--r--launcher/Application.h2
-rw-r--r--launcher/BaseInstance.cpp2
-rw-r--r--launcher/InstanceList.cpp16
-rw-r--r--launcher/icons/IconList.cpp11
-rw-r--r--launcher/icons/IconList.h1
-rw-r--r--launcher/minecraft/MinecraftInstance.cpp2
-rw-r--r--launcher/net/Download.cpp2
-rw-r--r--launcher/net/PasteUpload.cpp4
-rw-r--r--launcher/net/Upload.cpp2
-rw-r--r--launcher/screenshots/ImgurAlbumCreation.cpp2
-rw-r--r--launcher/screenshots/ImgurUpload.cpp3
-rw-r--r--launcher/ui/pages/global/APIPage.cpp5
-rw-r--r--launcher/ui/pages/global/APIPage.ui129
-rw-r--r--libraries/launcher/net/minecraft/Launcher.java65
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>&amp;Microsoft Authentication</string>
+ <string>Meta&amp;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&amp;data Server</string>
+ <string>&amp;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>&amp;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