summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSky <git@bunnies.cc>2013-10-19 06:40:46 +0100
committerSky <git@bunnies.cc>2013-10-19 06:40:46 +0100
commit681d36b23251993a8678db8e72859d4018396b63 (patch)
tree9082d1bc7107c1b1d0bc7b72fb486bd84cd21560
parentbe2c7f451541647899478d0197d3e9500d63c833 (diff)
downloadMultiMC-681d36b23251993a8678db8e72859d4018396b63.tar
MultiMC-681d36b23251993a8678db8e72859d4018396b63.tar.gz
MultiMC-681d36b23251993a8678db8e72859d4018396b63.tar.lz
MultiMC-681d36b23251993a8678db8e72859d4018396b63.tar.xz
MultiMC-681d36b23251993a8678db8e72859d4018396b63.zip
First draft of player faces in the login dialog
-rw-r--r--CMakeLists.txt2
-rw-r--r--MultiMC.cpp1
-rw-r--r--gui/logindialog.cpp50
-rw-r--r--gui/logindialog.ui43
-rw-r--r--gui/mainwindow.cpp38
-rw-r--r--logic/net/SkinDownload.cpp60
-rw-r--r--logic/net/SkinDownload.h38
7 files changed, 227 insertions, 5 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index b7dd6ea3..d00fbd5e 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -256,6 +256,8 @@ logic/net/HttpMetaCache.h
logic/net/HttpMetaCache.cpp
logic/net/LoginTask.h
logic/net/LoginTask.cpp
+logic/net/SkinDownload.h
+logic/net/SkinDownload.cpp
# legacy instances
logic/LegacyInstance.h
diff --git a/MultiMC.cpp b/MultiMC.cpp
index 6c3c0269..e38733a1 100644
--- a/MultiMC.cpp
+++ b/MultiMC.cpp
@@ -294,6 +294,7 @@ void MultiMC::initHttpMetaCache()
m_metacache->addBase("versions", QDir("versions").absolutePath());
m_metacache->addBase("libraries", QDir("libraries").absolutePath());
m_metacache->addBase("minecraftforge", QDir("mods/minecraftforge").absolutePath());
+ m_metacache->addBase("skins", QDir("playerdata/skins").absolutePath());
m_metacache->Load();
}
diff --git a/gui/logindialog.cpp b/gui/logindialog.cpp
index ed3983b7..332b5d38 100644
--- a/gui/logindialog.cpp
+++ b/gui/logindialog.cpp
@@ -17,6 +17,13 @@
#include "ui_logindialog.h"
#include "keyring.h"
#include "gui/platform.h"
+#include "MultiMC.h"
+
+#include <QFile>
+#include <QJsonObject>
+#include <QJsonArray>
+#include <QJsonParseError>
+#include "logic/net/HttpMetaCache.h"
#include <logger/QsLog.h>
LoginDialog::LoginDialog(QWidget *parent, const QString& loginErrMsg) :
@@ -51,6 +58,8 @@ LoginDialog::LoginDialog(QWidget *parent, const QString& loginErrMsg) :
arg(loginErrMsg));
}
+ ui->lblFace->setVisible(false);
+
resize(minimumSizeHint());
layout()->setSizeConstraint(QLayout::SetFixedSize);
Keyring * k = Keyring::instance();
@@ -151,13 +160,54 @@ void LoginDialog::userTextChanged ( const QString& user )
blockToggles = true;
Keyring * k = Keyring::instance();
QStringList sl = k->getStoredAccounts("minecraft");
+ bool gotFace = false;
+
if(sl.contains(user))
{
ui->rememberUsernameCheckbox->setChecked(true);
QString passwd = k->getPassword("minecraft",user);
ui->rememberPasswordCheckbox->setChecked(!passwd.isEmpty());
ui->passwordTextBox->setText(passwd);
+
+ QByteArray data;
+ {
+ auto filename = MMC->metacache()->resolveEntry("skins", "skins.json")->getFullPath();
+ QFile listFile(filename);
+ if(!listFile.open(QIODevice::ReadOnly))
+ return;
+ data = listFile.readAll();
+ }
+
+ QJsonParseError jsonError;
+ QJsonDocument jsonDoc = QJsonDocument::fromJson(data, &jsonError);
+ QJsonObject root = jsonDoc.object();
+ QJsonObject mappings = root.value("mappings").toObject();
+
+ if(!mappings[user].isUndefined())
+ {
+ QJsonArray usernames = mappings.value(user).toArray();
+ if(!usernames.isEmpty())
+ {
+ QString mapped_username = usernames[0].toString();
+
+ if(!mapped_username.isEmpty())
+ {
+ QFile fskin(MMC->metacache()->resolveEntry("skins", mapped_username + ".png")->getFullPath());
+ if(fskin.exists())
+ {
+ QPixmap skin(MMC->metacache()->resolveEntry("skins", mapped_username + ".png")->getFullPath());
+ QPixmap face = skin.copy(8, 8, 8, 8).scaled(48, 48, Qt::KeepAspectRatio);
+
+ ui->lblFace->setPixmap(face);
+ gotFace = true;
+ }
+ }
+ }
+ }
}
+
+ if(gotFace) ui->lblFace->setVisible(true);
+ else ui->lblFace->setVisible(false);
blockToggles = false;
}
diff --git a/gui/logindialog.ui b/gui/logindialog.ui
index 0aaad52b..46965425 100644
--- a/gui/logindialog.ui
+++ b/gui/logindialog.ui
@@ -23,10 +23,34 @@
</item>
<item>
<layout class="QGridLayout" name="gridLayout">
- <item row="0" column="0">
- <widget class="QLabel" name="usernameLabel">
+ <item row="0" column="4" rowspan="2">
+ <widget class="QLabel" name="lblFace">
+ <property name="minimumSize">
+ <size>
+ <width>48</width>
+ <height>48</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>48</width>
+ <height>48</height>
+ </size>
+ </property>
+ <property name="sizeIncrement">
+ <size>
+ <width>1</width>
+ <height>1</height>
+ </size>
+ </property>
<property name="text">
- <string>Username:</string>
+ <string/>
+ </property>
+ <property name="pixmap">
+ <pixmap resource="../multimc.qrc">:/icons/instances/steve</pixmap>
+ </property>
+ <property name="scaledContents">
+ <bool>true</bool>
</property>
</widget>
</item>
@@ -37,6 +61,13 @@
</property>
</widget>
</item>
+ <item row="0" column="0">
+ <widget class="QLabel" name="usernameLabel">
+ <property name="text">
+ <string>Username:</string>
+ </property>
+ </widget>
+ </item>
<item row="1" column="0">
<widget class="QLabel" name="passwordLabel">
<property name="text">
@@ -54,7 +85,7 @@
</property>
</widget>
</item>
- <item row="0" column="2" rowspan="2">
+ <item row="0" column="5" rowspan="2">
<widget class="QPushButton" name="forgetButton">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Minimum">
@@ -111,7 +142,9 @@
</item>
</layout>
</widget>
- <resources/>
+ <resources>
+ <include location="../multimc.qrc"/>
+ </resources>
<connections>
<connection>
<sender>loginButtonBox</sender>
diff --git a/gui/mainwindow.cpp b/gui/mainwindow.cpp
index 0bd6f651..b68af5fa 100644
--- a/gui/mainwindow.cpp
+++ b/gui/mainwindow.cpp
@@ -57,6 +57,8 @@
#include "logic/lists/JavaVersionList.h"
#include "logic/net/LoginTask.h"
+#include "logic/net/SkinDownload.h"
+
#include "logic/BaseInstance.h"
#include "logic/InstanceFactory.h"
#include "logic/MinecraftProcess.h"
@@ -517,6 +519,42 @@ void MainWindow::onLoginComplete()
tDialog.exec(updateTask);
delete updateTask;
}
+
+ auto download = new SkinDownload(m_activeLogin.player_name);
+ download->start();
+
+ auto filename = MMC->metacache()->resolveEntry("skins", "skins.json")->getFullPath();
+ QFile listFile(filename);
+
+ // Add skin mapping
+ QByteArray data;
+ {
+ if(!listFile.open(QIODevice::ReadWrite))
+ {
+ QLOG_ERROR() << "Failed to open/make skins list JSON";
+ return;
+ }
+
+ data = listFile.readAll();
+ }
+
+ QJsonParseError jsonError;
+ QJsonDocument jsonDoc = QJsonDocument::fromJson(data, &jsonError);
+ QJsonObject root = jsonDoc.object();
+ QJsonObject mappings = root.value("mappings").toObject();
+ QJsonArray usernames = mappings.value(m_activeLogin.username).toArray();
+
+ if(!usernames.contains(m_activeLogin.player_name))
+ {
+ usernames.prepend(m_activeLogin.player_name);
+ mappings[m_activeLogin.username] = usernames;
+ root["mappings"] = mappings;
+ jsonDoc.setObject(root);
+
+ // QJson hack - shouldn't have to clear the file every time a save happens
+ listFile.resize(0);
+ listFile.write(jsonDoc.toJson());
+ }
}
void MainWindow::onGameUpdateComplete()
diff --git a/logic/net/SkinDownload.cpp b/logic/net/SkinDownload.cpp
new file mode 100644
index 00000000..fa7be2b5
--- /dev/null
+++ b/logic/net/SkinDownload.cpp
@@ -0,0 +1,60 @@
+#include "MultiMC.h"
+#include "SkinDownload.h"
+#include "DownloadJob.h"
+#include <pathutils.h>
+
+#include <QImage>
+#include <QPainter>
+#include <QCryptographicHash>
+#include <QFileInfo>
+#include <QDateTime>
+#include <logger/QsLog.h>
+
+SkinDownload::SkinDownload(QString name)
+{
+ m_name = name;
+ m_entry = MMC->metacache()->resolveEntry("skins", name + ".png");
+ m_entry->stale = true;
+ m_url = QUrl("http://skins.minecraft.net/MinecraftSkins/" + name + ".png");
+}
+
+void SkinDownload::start()
+{
+ auto job = new DownloadJob("Player skin: " + m_name);
+
+ job->addCacheDownload(m_url, m_entry);
+ m_job.reset(job);
+
+ connect(m_job.get(), SIGNAL(started()), SLOT(downloadStarted()));
+ connect(m_job.get(), SIGNAL(progress(qint64, qint64)), SLOT(downloadProgress(qint64, qint64)));
+ connect(m_job.get(), SIGNAL(succeeded()), SLOT(downloadSucceeded()));
+ connect(m_job.get(), SIGNAL(failed()), SLOT(downloadFailed()));
+
+ m_job->start();
+}
+
+void SkinDownload::downloadStarted()
+{
+ //QLOG_INFO() << "Started skin download for " << m_name << ".";
+
+ emit started();
+}
+
+void SkinDownload::downloadProgress(qint64 bytesReceived, qint64 bytesTotal)
+{
+ emit progress(bytesReceived, bytesTotal);
+}
+
+void SkinDownload::downloadSucceeded()
+{
+ //QLOG_INFO() << "Got skin for " << m_name << ", cropping.";
+
+ emit succeeded();
+}
+
+void SkinDownload::downloadFailed()
+{
+ //QLOG_ERROR() << "Failed to download skin for: " << m_name;
+
+ emit failed();
+}
diff --git a/logic/net/SkinDownload.h b/logic/net/SkinDownload.h
new file mode 100644
index 00000000..56e5c01d
--- /dev/null
+++ b/logic/net/SkinDownload.h
@@ -0,0 +1,38 @@
+#pragma once
+
+#include "Download.h"
+#include "HttpMetaCache.h"
+#include "DownloadJob.h"
+#include <QFile>
+#include <QTemporaryFile>
+
+class SkinDownload : public QObject
+{
+ Q_OBJECT
+
+public:
+ explicit SkinDownload(QString name);
+ QString m_name;
+ QUrl m_url;
+ MetaEntryPtr m_entry;
+ DownloadJobPtr m_job;
+
+ void start();
+
+protected slots:
+ void downloadStarted();
+ void downloadProgress(qint64 bytesReceived, qint64 bytesTotal);
+ void downloadSucceeded();
+ void downloadFailed();
+
+signals:
+ void started();
+ void progress(qint64 current, qint64 total);
+ void succeeded();
+ void failed();
+
+protected:
+
+};
+
+typedef std::shared_ptr<SkinDownload> SkinDownloadPtr;