diff options
author | Sky <git@bunnies.cc> | 2013-10-19 06:40:46 +0100 |
---|---|---|
committer | Sky <git@bunnies.cc> | 2013-10-19 06:40:46 +0100 |
commit | 681d36b23251993a8678db8e72859d4018396b63 (patch) | |
tree | 9082d1bc7107c1b1d0bc7b72fb486bd84cd21560 | |
parent | be2c7f451541647899478d0197d3e9500d63c833 (diff) | |
download | MultiMC-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.txt | 2 | ||||
-rw-r--r-- | MultiMC.cpp | 1 | ||||
-rw-r--r-- | gui/logindialog.cpp | 50 | ||||
-rw-r--r-- | gui/logindialog.ui | 43 | ||||
-rw-r--r-- | gui/mainwindow.cpp | 38 | ||||
-rw-r--r-- | logic/net/SkinDownload.cpp | 60 | ||||
-rw-r--r-- | logic/net/SkinDownload.h | 38 |
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; |