Merge branch 'develop' of github.com:MultiMC/MultiMC5 into develop
This commit is contained in:
		| @@ -346,6 +346,8 @@ logic/JavaUtils.h | ||||
| logic/JavaUtils.cpp | ||||
| logic/NagUtils.h | ||||
| logic/NagUtils.cpp | ||||
| logic/SkinUtils.h | ||||
| logic/SkinUtils.cpp | ||||
|  | ||||
| ) | ||||
|  | ||||
|   | ||||
| @@ -76,6 +76,7 @@ | ||||
| #include "logic/OneSixUpdate.h" | ||||
| #include "logic/JavaUtils.h" | ||||
| #include "logic/NagUtils.h" | ||||
| #include "logic/SkinUtils.h" | ||||
|  | ||||
| #include "logic/LegacyInstance.h" | ||||
|  | ||||
| @@ -164,6 +165,41 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWi | ||||
| 	statusBar()->addPermanentWidget(m_statusLeft, 1); | ||||
| 	statusBar()->addPermanentWidget(m_statusRight, 0); | ||||
|  | ||||
| 	// Add "manage accounts" button, right align | ||||
|  | ||||
| 	QWidget* spacer = new QWidget(); | ||||
| 	spacer->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); | ||||
| 	ui->mainToolBar->addWidget(spacer); | ||||
|  | ||||
| 	actionManageAccounts = new QToolButton(this); | ||||
| 	actionManageAccounts->setToolTip(tr("Manage your Mojang or Minecraft accounts.")); | ||||
| 	actionManageAccounts->setObjectName("actionManageAccounts"); | ||||
| 	actionManageAccounts->setText(tr("Manage accounts")); | ||||
| 	actionManageAccounts->setToolButtonStyle(Qt::ToolButtonTextBesideIcon); | ||||
| 	actionManageAccounts->setLayoutDirection(Qt::RightToLeft); | ||||
|  | ||||
| 	MojangAccountPtr account = MMC->accounts()->activeAccount(); | ||||
| 	if(account != nullptr) | ||||
| 	{ | ||||
| 		auto job = new NetJob("Startup player skins: " + account->username()); | ||||
|  | ||||
| 		for(AccountProfile profile : account->profiles()) | ||||
| 		{ | ||||
| 			auto meta = MMC->metacache()->resolveEntry("skins", profile.name() + ".png"); | ||||
| 			auto action = CacheDownload::make( | ||||
| 				QUrl("http://skins.minecraft.net/MinecraftSkins/" + profile.name() + ".png"), | ||||
| 				meta); | ||||
| 			job->addNetAction(action); | ||||
| 			meta->stale = true; | ||||
| 		} | ||||
|  | ||||
| 		connect(job, SIGNAL(succeeded()), SLOT(activeAccountChanged())); | ||||
| 		job->start(); | ||||
| 	} | ||||
|  | ||||
| 	connect(actionManageAccounts, SIGNAL(clicked()), this, SLOT(on_actionManageAccounts_triggered())); | ||||
| 	ui->mainToolBar->addWidget(actionManageAccounts); | ||||
|  | ||||
| 	// run the things that load and download other things... FIXME: this is NOT the place | ||||
| 	// FIXME: invisible actions in the background = NOPE. | ||||
| 	{ | ||||
| @@ -196,6 +232,20 @@ MainWindow::~MainWindow() | ||||
| 	delete assets_downloader; | ||||
| } | ||||
|  | ||||
| void MainWindow::activeAccountChanged() | ||||
| { | ||||
| 	MojangAccountPtr account = MMC->accounts()->activeAccount(); | ||||
|  | ||||
| 	if(account != nullptr) | ||||
| 	{ | ||||
| 		const AccountProfile *profile = account->currentProfile(); | ||||
| 		if(profile != nullptr) | ||||
| 		{ | ||||
| 			actionManageAccounts->setIcon(SkinUtils::getFaceFromCache(profile->name())); | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|  | ||||
| bool MainWindow::eventFilter(QObject *obj, QEvent *ev) | ||||
| { | ||||
| 	if (obj == view) | ||||
| @@ -427,6 +477,7 @@ void MainWindow::on_actionSettings_triggered() | ||||
| void MainWindow::on_actionManageAccounts_triggered() | ||||
| { | ||||
| 	AccountListDialog dialog(this); | ||||
| 	connect(&dialog, SIGNAL(activeAccountChanged()), SLOT(activeAccountChanged())); | ||||
| 	dialog.exec(); | ||||
| } | ||||
|  | ||||
| @@ -612,51 +663,6 @@ void MainWindow::prepareLaunch(BaseInstance* instance, MojangAccountPtr account) | ||||
| 		tDialog.exec(updateTask); | ||||
| 		delete updateTask; | ||||
| 	} | ||||
|  | ||||
| 	QString playerName = account->currentProfile()->name(); | ||||
|  | ||||
| 	auto job = new NetJob("Player skin: " + playerName); | ||||
|  | ||||
| 	auto meta = MMC->metacache()->resolveEntry("skins", playerName + ".png"); | ||||
| 	auto action = CacheDownload::make( | ||||
| 		QUrl("http://skins.minecraft.net/MinecraftSkins/" + playerName + ".png"), | ||||
| 		meta); | ||||
| 	job->addNetAction(action); | ||||
| 	meta->stale = true; | ||||
|  | ||||
| 	job->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(account->username()).toArray(); | ||||
|  | ||||
| 	if (!usernames.contains(playerName)) | ||||
| 	{ | ||||
| 		usernames.prepend(playerName); | ||||
| 		mappings[account->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::launchInstance(BaseInstance *instance, MojangAccountPtr account) | ||||
|   | ||||
| @@ -146,6 +146,8 @@ slots: | ||||
|  | ||||
| 	void startTask(Task *task); | ||||
|  | ||||
| 	void activeAccountChanged(); | ||||
|  | ||||
| protected: | ||||
| 	bool eventFilter(QObject *obj, QEvent *ev); | ||||
| 	void setCatBackground(bool enabled); | ||||
| @@ -167,4 +169,6 @@ private: | ||||
|  | ||||
| 	QLabel *m_statusLeft; | ||||
| 	QLabel *m_statusRight; | ||||
|  | ||||
| 	QToolButton *actionManageAccounts; | ||||
| }; | ||||
|   | ||||
| @@ -70,7 +70,6 @@ | ||||
|    <addaction name="separator"/> | ||||
|    <addaction name="actionCheckUpdate"/> | ||||
|    <addaction name="actionSettings"/> | ||||
|    <addaction name="actionManageAccounts"/> | ||||
|    <addaction name="separator"/> | ||||
|    <addaction name="actionReportBug"/> | ||||
|    <addaction name="actionNews"/> | ||||
|   | ||||
| @@ -21,6 +21,7 @@ | ||||
| #include <logger/QsLog.h> | ||||
|  | ||||
| #include <logic/auth/AuthenticateTask.h> | ||||
| #include <logic/net/NetJob.h> | ||||
|  | ||||
| #include <gui/dialogs/LoginDialog.h> | ||||
| #include <gui/dialogs/ProgressDialog.h> | ||||
| @@ -56,6 +57,8 @@ void AccountListDialog::on_rmAccountBtn_clicked() | ||||
| 	{ | ||||
| 		QModelIndex selected = selection.first(); | ||||
| 		m_accounts->removeAccount(selected); | ||||
|  | ||||
| 		emit activeAccountChanged(); | ||||
| 	} | ||||
| } | ||||
|  | ||||
| @@ -72,7 +75,9 @@ void AccountListDialog::on_setActiveBtn_clicked() | ||||
| 		QModelIndex selected = selection.first(); | ||||
| 		MojangAccountPtr account = selected.data(MojangAccountList::PointerRole).value<MojangAccountPtr>(); | ||||
| 		m_accounts->setActiveAccount(account->username()); | ||||
| 	} | ||||
|  | ||||
| 		emit activeAccountChanged(); | ||||
| 	}	 | ||||
| } | ||||
|  | ||||
| void AccountListDialog::on_closeBtnBox_rejected() | ||||
| @@ -108,5 +113,21 @@ void AccountListDialog::onLoginComplete() | ||||
| 	MojangAccountPtr account = m_authTask->getMojangAccount(); | ||||
| 	m_accounts->addAccount(account); | ||||
| 	//ui->listView->update(); | ||||
|  | ||||
| 	// Grab associated player skins | ||||
| 	auto job = new NetJob("Player skins: " + account->username()); | ||||
|  | ||||
| 	for(AccountProfile profile : account->profiles()) | ||||
| 	{ | ||||
| 		auto meta = MMC->metacache()->resolveEntry("skins", profile.name() + ".png"); | ||||
| 		auto action = CacheDownload::make( | ||||
| 			QUrl("http://skins.minecraft.net/MinecraftSkins/" + profile.name() + ".png"), | ||||
| 			meta); | ||||
| 		job->addNetAction(action); | ||||
| 		meta->stale = true; | ||||
| 	} | ||||
|  | ||||
| 	connect(job, SIGNAL(succeeded()), SIGNAL(activeAccountChanged())); | ||||
| 	job->start(); | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -47,6 +47,9 @@ slots: | ||||
| 	// This will be sent when the "close" button is clicked. | ||||
| 	void on_closeBtnBox_rejected(); | ||||
|  | ||||
| signals: | ||||
| 	void activeAccountChanged(); | ||||
|  | ||||
| protected: | ||||
| 	std::shared_ptr<MojangAccountList> m_accounts; | ||||
|  | ||||
|   | ||||
| @@ -18,6 +18,7 @@ | ||||
| #include "keyring.h" | ||||
| #include "gui/Platform.h" | ||||
| #include "MultiMC.h" | ||||
| #include "logic/SkinUtils.h" | ||||
|  | ||||
| #include <QFile> | ||||
| #include <QJsonObject> | ||||
| @@ -168,47 +169,10 @@ void LoginDialog::userTextChanged(const QString &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(); | ||||
| 		} | ||||
| 		QPixmap face = SkinUtils::getFaceFromCache(user); | ||||
| 		gotFace = !face.isNull(); | ||||
|  | ||||
| 		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->setPixmap(face); | ||||
| 	} | ||||
|  | ||||
| 	ui->lblFace->setVisible(gotFace); | ||||
|   | ||||
							
								
								
									
										47
									
								
								logic/SkinUtils.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										47
									
								
								logic/SkinUtils.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,47 @@ | ||||
| /* Copyright 2013 MultiMC Contributors | ||||
|  * | ||||
|  * Licensed under the Apache License, Version 2.0 (the "License"); | ||||
|  * you may not use this file except in compliance with the License. | ||||
|  * You may obtain a copy of the License at | ||||
|  * | ||||
|  *     http://www.apache.org/licenses/LICENSE-2.0 | ||||
|  * | ||||
|  * Unless required by applicable law or agreed to in writing, software | ||||
|  * distributed under the License is distributed on an "AS IS" BASIS, | ||||
|  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||
|  * See the License for the specific language governing permissions and | ||||
|  * limitations under the License. | ||||
|  */ | ||||
|  | ||||
| #include "MultiMC.h" | ||||
| #include "logic/SkinUtils.h" | ||||
| #include "net/HttpMetaCache.h" | ||||
|  | ||||
| #include <QFile> | ||||
| #include <QJsonDocument> | ||||
| #include <QJsonObject> | ||||
| #include <QJsonArray> | ||||
|  | ||||
| namespace SkinUtils | ||||
| { | ||||
| /* | ||||
|  * Given a username, return a pixmap of the cached skin (if it exists), QPixmap() otherwise | ||||
|  */ | ||||
| QPixmap getFaceFromCache(QString username, int height, int width) | ||||
| { | ||||
| 	QFile fskin(MMC->metacache() | ||||
| 					->resolveEntry("skins", username + ".png") | ||||
| 					->getFullPath()); | ||||
|  | ||||
| 	if (fskin.exists()) | ||||
| 	{ | ||||
| 		QPixmap skin(fskin.fileName()); | ||||
| 		if(!skin.isNull()) | ||||
| 		{ | ||||
| 			return skin.copy(8, 8, 8, 8).scaled(height, width, Qt::KeepAspectRatio); | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	return QPixmap(); | ||||
| } | ||||
| } | ||||
							
								
								
									
										23
									
								
								logic/SkinUtils.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										23
									
								
								logic/SkinUtils.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,23 @@ | ||||
| /* Copyright 2013 MultiMC Contributors | ||||
|  * | ||||
|  * Licensed under the Apache License, Version 2.0 (the "License"); | ||||
|  * you may not use this file except in compliance with the License. | ||||
|  * You may obtain a copy of the License at | ||||
|  * | ||||
|  *     http://www.apache.org/licenses/LICENSE-2.0 | ||||
|  * | ||||
|  * Unless required by applicable law or agreed to in writing, software | ||||
|  * distributed under the License is distributed on an "AS IS" BASIS, | ||||
|  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||
|  * See the License for the specific language governing permissions and | ||||
|  * limitations under the License. | ||||
|  */ | ||||
|  | ||||
| #pragma once | ||||
|  | ||||
| #include <QPixmap> | ||||
|  | ||||
| namespace SkinUtils | ||||
| { | ||||
| QPixmap getFaceFromCache(QString username, int height = 48, int width = 48); | ||||
| } | ||||
		Reference in New Issue
	
	Block a user