summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--CMakeLists.txt19
-rw-r--r--data/loginresponse.cpp69
-rw-r--r--data/loginresponse.h47
-rw-r--r--data/userinfo.cpp49
-rw-r--r--data/userinfo.h39
-rw-r--r--gui/logindialog.cpp51
-rw-r--r--gui/logindialog.h40
-rw-r--r--gui/logindialog.ui146
-rw-r--r--gui/mainwindow.cpp34
-rw-r--r--gui/mainwindow.h11
-rw-r--r--gui/taskdialog.cpp109
-rw-r--r--gui/taskdialog.h63
-rw-r--r--gui/taskdialog.ui53
-rw-r--r--main.cpp4
-rw-r--r--tasks/logintask.cpp121
-rw-r--r--tasks/logintask.h48
-rw-r--r--tasks/task.cpp56
-rw-r--r--tasks/task.h54
18 files changed, 1011 insertions, 2 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index aa9e39de..f67b8346 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -17,6 +17,7 @@ include_directories(hacks)
#### Find the required Qt parts ####
find_package(Qt5Widgets)
+find_package(Qt5Network)
#find_package(Qt5Declarative)
include_directories(${Qt5Widgets_INCLUDE_DIRS})
@@ -96,17 +97,24 @@ data/instancebase.cpp
data/instancemodel.cpp
data/stdinstance.cpp
data/version.cpp
+data/userinfo.cpp
+data/loginresponse.cpp
gui/mainwindow.cpp
gui/modeditwindow.cpp
gui/settingsdialog.cpp
gui/newinstancedialog.cpp
+gui/logindialog.cpp
+gui/taskdialog.cpp
util/pathutils.cpp
util/osutils.cpp
java/javautils.cpp
java/annotations.cpp
+
+tasks/task.cpp
+tasks/logintask.cpp
)
SET(MULTIMC_HEADERS
@@ -114,6 +122,8 @@ gui/mainwindow.h
gui/modeditwindow.h
gui/settingsdialog.h
gui/newinstancedialog.h
+gui/logindialog.h
+gui/taskdialog.h
data/appsettings.h
data/inifile.h
@@ -121,6 +131,8 @@ data/instancebase.h
data/instancemodel.h
data/stdinstance.h
data/version.h
+data/userinfo.h
+data/loginresponse.h
util/apputils.h
util/pathutils.h
@@ -135,6 +147,9 @@ java/endian.h
java/errors.h
java/javautils.h
java/membuffer.h
+
+tasks/task.h
+tasks/logintask.h
)
SET(MULTIMC5_UIS
@@ -142,6 +157,8 @@ gui/mainwindow.ui
gui/modeditwindow.ui
gui/settingsdialog.ui
gui/newinstancedialog.ui
+gui/logindialog.ui
+gui/taskdialog.ui
)
IF(WIN32)
@@ -155,7 +172,7 @@ QT5_WRAP_UI(MULTIMC_UI ${MULTIMC5_UIS})
QT5_ADD_RESOURCES(MULTIMC_QRC multimc.qrc)
add_executable(MultiMC ${MULTIMC_SOURCES} ${MULTIMC_HEADERS} ${MULTIMC_UI} ${MULTIMC_QRC})
-qt5_use_modules(MultiMC Widgets)
+qt5_use_modules(MultiMC Widgets Network)
target_link_libraries(MultiMC quazip patchlib ${MultiMC_LINK_ADDITIONAL_LIBS})
add_dependencies(MultiMC MultiMCLauncher)
install(TARGETS MultiMC RUNTIME DESTINATION .)
diff --git a/data/loginresponse.cpp b/data/loginresponse.cpp
new file mode 100644
index 00000000..44bc80eb
--- /dev/null
+++ b/data/loginresponse.cpp
@@ -0,0 +1,69 @@
+/* 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 "loginresponse.h"
+
+LoginResponse::LoginResponse(const QString& username, const QString& sessionID,
+ qint64 latestVersion, QObject *parent) :
+ QObject(parent)
+{
+ this->username = username;
+ this->sessionID = sessionID;
+ this->latestVersion = latestVersion;
+}
+
+LoginResponse::LoginResponse()
+{
+ this->username = "";
+ this->sessionID = "";
+ this->latestVersion = 0;
+}
+
+LoginResponse::LoginResponse(const LoginResponse &other)
+{
+ this->username = other.getUsername();
+ this->sessionID = other.getSessionID();
+ this->latestVersion = other.getLatestVersion();
+}
+
+QString LoginResponse::getUsername() const
+{
+ return username;
+}
+
+void LoginResponse::setUsername(const QString& username)
+{
+ this->username = username;
+}
+
+QString LoginResponse::getSessionID() const
+{
+ return sessionID;
+}
+
+void LoginResponse::setSessionID(const QString& sessionID)
+{
+ this->sessionID = sessionID;
+}
+
+qint64 LoginResponse::getLatestVersion() const
+{
+ return latestVersion;
+}
+
+void LoginResponse::setLatestVersion(qint64 v)
+{
+ this->latestVersion = v;
+}
diff --git a/data/loginresponse.h b/data/loginresponse.h
new file mode 100644
index 00000000..bcb77d56
--- /dev/null
+++ b/data/loginresponse.h
@@ -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.
+ */
+
+#ifndef LOGINRESPONSE_H
+#define LOGINRESPONSE_H
+
+#include <QObject>
+
+class LoginResponse : public QObject
+{
+ Q_OBJECT
+public:
+ explicit LoginResponse(const QString &username, const QString &sessionID,
+ qint64 latestVersion, QObject *parent = 0);
+ LoginResponse();
+ LoginResponse(const LoginResponse& other);
+
+ QString getUsername() const;
+ void setUsername(const QString& username);
+
+ QString getSessionID() const;
+ void setSessionID(const QString& sessionID);
+
+ qint64 getLatestVersion() const;
+ void setLatestVersion(qint64 v);
+
+private:
+ QString username;
+ QString sessionID;
+ qint64 latestVersion;
+};
+
+Q_DECLARE_METATYPE(LoginResponse)
+
+#endif // LOGINRESPONSE_H
diff --git a/data/userinfo.cpp b/data/userinfo.cpp
new file mode 100644
index 00000000..907f93a2
--- /dev/null
+++ b/data/userinfo.cpp
@@ -0,0 +1,49 @@
+/* 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 "userinfo.h"
+
+UserInfo::UserInfo(const QString &username, const QString &password, QObject *parent) :
+ QObject(parent)
+{
+ this->username = username;
+ this->password = password;
+}
+
+UserInfo::UserInfo(const UserInfo &other)
+{
+ this->username = other.username;
+ this->password = other.password;
+}
+
+QString UserInfo::getUsername() const
+{
+ return username;
+}
+
+void UserInfo::setUsername(const QString &username)
+{
+ this->username = username;
+}
+
+QString UserInfo::getPassword() const
+{
+ return password;
+}
+
+void UserInfo::setPassword(const QString &password)
+{
+ this->password = password;
+}
diff --git a/data/userinfo.h b/data/userinfo.h
new file mode 100644
index 00000000..ccfc741e
--- /dev/null
+++ b/data/userinfo.h
@@ -0,0 +1,39 @@
+/* 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.
+ */
+
+#ifndef USERINFO_H
+#define USERINFO_H
+
+#include <QObject>
+
+class UserInfo : public QObject
+{
+ Q_OBJECT
+public:
+ explicit UserInfo(const QString& username, const QString& password, QObject *parent = 0);
+ explicit UserInfo(const UserInfo& other);
+
+ QString getUsername() const;
+ void setUsername(const QString& username);
+
+ QString getPassword() const;
+ void setPassword(const QString& password);
+
+protected:
+ QString username;
+ QString password;
+};
+
+#endif // USERINFO_H
diff --git a/gui/logindialog.cpp b/gui/logindialog.cpp
new file mode 100644
index 00000000..426757a9
--- /dev/null
+++ b/gui/logindialog.cpp
@@ -0,0 +1,51 @@
+/* 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 "logindialog.h"
+#include "ui_logindialog.h"
+
+LoginDialog::LoginDialog(QWidget *parent, const QString& loginErrMsg) :
+ QDialog(parent),
+ ui(new Ui::LoginDialog)
+{
+ ui->setupUi(this);
+
+ if (loginErrMsg.isEmpty())
+ ui->loginErrorLabel->setVisible(false);
+ else
+ {
+ ui->loginErrorLabel->setVisible(true);
+ ui->loginErrorLabel->setText(QString("<span style=\" color:#ff0000;\">%1</span>").
+ arg(loginErrMsg));
+ }
+
+ resize(minimumSizeHint());
+ layout()->setSizeConstraint(QLayout::SetFixedSize);
+}
+
+LoginDialog::~LoginDialog()
+{
+ delete ui;
+}
+
+QString LoginDialog::getUsername() const
+{
+ return ui->usernameTextBox->text();
+}
+
+QString LoginDialog::getPassword() const
+{
+ return ui->passwordTextBox->text();
+}
diff --git a/gui/logindialog.h b/gui/logindialog.h
new file mode 100644
index 00000000..1b70dcd5
--- /dev/null
+++ b/gui/logindialog.h
@@ -0,0 +1,40 @@
+/* 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.
+ */
+
+#ifndef LOGINDIALOG_H
+#define LOGINDIALOG_H
+
+#include <QDialog>
+
+namespace Ui {
+class LoginDialog;
+}
+
+class LoginDialog : public QDialog
+{
+ Q_OBJECT
+
+public:
+ explicit LoginDialog(QWidget *parent = 0, const QString& loginErrMsg = "");
+ ~LoginDialog();
+
+ QString getUsername() const;
+ QString getPassword() const;
+
+private:
+ Ui::LoginDialog *ui;
+};
+
+#endif // LOGINDIALOG_H
diff --git a/gui/logindialog.ui b/gui/logindialog.ui
new file mode 100644
index 00000000..ce41d2f5
--- /dev/null
+++ b/gui/logindialog.ui
@@ -0,0 +1,146 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>LoginDialog</class>
+ <widget class="QDialog" name="LoginDialog">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>365</width>
+ <height>145</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>Login</string>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout">
+ <item>
+ <widget class="QLabel" name="loginErrorLabel">
+ <property name="text">
+ <string>&lt;span style=&quot; color:#ff0000;&quot;&gt;Error&lt;/span&gt;</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <layout class="QGridLayout" name="gridLayout">
+ <item row="0" column="0">
+ <widget class="QLabel" name="usernameLabel">
+ <property name="text">
+ <string>Username:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1">
+ <widget class="QLineEdit" name="usernameTextBox">
+ <property name="placeholderText">
+ <string>Username</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="0">
+ <widget class="QLabel" name="passwordLabel">
+ <property name="text">
+ <string>Password:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1">
+ <widget class="QLineEdit" name="passwordTextBox">
+ <property name="echoMode">
+ <enum>QLineEdit::Password</enum>
+ </property>
+ <property name="placeholderText">
+ <string>Password</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="checkboxLayout">
+ <item>
+ <widget class="QPushButton" name="forceUpdateButton">
+ <property name="text">
+ <string>&amp;Force Update</string>
+ </property>
+ <property name="checkable">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QCheckBox" name="rememberUsernameCheckbox">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Maximum" vsizetype="Fixed">
+ <horstretch>1</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>&amp;Remember Username?</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QCheckBox" name="rememberPasswordCheckbox">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Maximum" vsizetype="Fixed">
+ <horstretch>1</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>R&amp;emember Password?</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <widget class="QDialogButtonBox" name="loginButtonBox">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="standardButtons">
+ <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <resources/>
+ <connections>
+ <connection>
+ <sender>loginButtonBox</sender>
+ <signal>accepted()</signal>
+ <receiver>LoginDialog</receiver>
+ <slot>accept()</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>248</x>
+ <y>254</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>157</x>
+ <y>274</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>loginButtonBox</sender>
+ <signal>rejected()</signal>
+ <receiver>LoginDialog</receiver>
+ <slot>reject()</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>316</x>
+ <y>260</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>286</x>
+ <y>274</y>
+ </hint>
+ </hints>
+ </connection>
+ </connections>
+</ui>
diff --git a/gui/mainwindow.cpp b/gui/mainwindow.cpp
index 1ff633b2..bc0840a0 100644
--- a/gui/mainwindow.cpp
+++ b/gui/mainwindow.cpp
@@ -26,10 +26,14 @@
#include "gui/settingsdialog.h"
#include "gui/newinstancedialog.h"
+#include "gui/logindialog.h"
+#include "gui/taskdialog.h"
#include "data/appsettings.h"
#include "data/version.h"
+#include "tasks/logintask.h"
+
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
@@ -121,3 +125,33 @@ void MainWindow::on_instanceView_customContextMenuRequested(const QPoint &pos)
instContextMenu->exec(ui->instanceView->mapToGlobal(pos));
}
+
+
+void MainWindow::on_actionLaunchInstance_triggered()
+{
+ doLogin();
+}
+
+void MainWindow::doLogin(const QString &errorMsg)
+{
+ LoginDialog* loginDlg = new LoginDialog(this, errorMsg);
+ if (loginDlg->exec())
+ {
+ UserInfo uInfo(loginDlg->getUsername(), loginDlg->getPassword());
+
+ TaskDialog* tDialog = new TaskDialog(this);
+ LoginTask* loginTask = new LoginTask(uInfo, tDialog);
+ connect(loginTask, SIGNAL(loginComplete(LoginResponse)),
+ SLOT(onLoginComplete(LoginResponse)), Qt::QueuedConnection);
+ connect(loginTask, SIGNAL(loginFailed(QString)),
+ SLOT(doLogin(QString)), Qt::QueuedConnection);
+ tDialog->exec(loginTask);
+ }
+}
+
+void MainWindow::onLoginComplete(LoginResponse response)
+{
+ QMessageBox::information(this, "Login Successful",
+ QString("Logged in as %1 with session ID %2.").
+ arg(response.getUsername(), response.getSessionID()));
+}
diff --git a/gui/mainwindow.h b/gui/mainwindow.h
index ce06a085..28ca341a 100644
--- a/gui/mainwindow.h
+++ b/gui/mainwindow.h
@@ -18,7 +18,8 @@
#include <QMainWindow>
-#include "../data/instancemodel.h"
+#include "data/instancemodel.h"
+#include "data/loginresponse.h"
namespace Ui
{
@@ -58,6 +59,14 @@ private slots:
void on_instanceView_customContextMenuRequested(const QPoint &pos);
+ void on_actionLaunchInstance_triggered();
+
+
+ void doLogin(const QString& errorMsg = "");
+
+
+ void onLoginComplete(LoginResponse response);
+
private:
Ui::MainWindow *ui;
diff --git a/gui/taskdialog.cpp b/gui/taskdialog.cpp
new file mode 100644
index 00000000..a8738fe3
--- /dev/null
+++ b/gui/taskdialog.cpp
@@ -0,0 +1,109 @@
+/* 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 "taskdialog.h"
+#include "ui_taskdialog.h"
+
+#include <QKeyEvent>
+
+#include "tasks/task.h"
+
+TaskDialog::TaskDialog(QWidget *parent) :
+ QDialog(parent),
+ ui(new Ui::TaskDialog)
+{
+ ui->setupUi(this);
+ updateSize();
+
+ changeProgress(0);
+}
+
+TaskDialog::~TaskDialog()
+{
+ delete ui;
+}
+
+void TaskDialog::updateSize()
+{
+ resize(QSize(480, minimumSizeHint().height()));
+}
+
+void TaskDialog::exec(Task *task)
+{
+ this->task = task;
+
+ // Connect signals.
+ connect(task, SIGNAL(taskStarted(Task*)),
+ this, SLOT(onTaskStarted(Task*)));
+ connect(task, SIGNAL(taskEnded(Task*)),
+ this, SLOT(onTaskEnded(Task*)));
+ connect(task, SIGNAL(statusChanged(const QString&)),
+ this, SLOT(changeStatus(const QString&)));
+ connect(task, SIGNAL(progressChanged(int)),
+ this, SLOT(changeProgress(int)));
+
+ task->startTask();
+ QDialog::exec();
+}
+
+Task* TaskDialog::getTask()
+{
+ return task;
+}
+
+void TaskDialog::onTaskStarted(Task*)
+{
+
+}
+
+void TaskDialog::onTaskEnded(Task*)
+{
+ close();
+}
+
+void TaskDialog::changeStatus(const QString &status)
+{
+ ui->statusLabel->setText(status);
+ updateSize();
+}
+
+void TaskDialog::changeProgress(int progress)
+{
+ if (progress < 0)
+ progress = 0;
+ else if (progress > 100)
+ progress = 100;
+
+ ui->taskProgressBar->setValue(progress);
+}
+
+void TaskDialog::keyPressEvent(QKeyEvent* e)
+{
+ if (e->key() == Qt::Key_Escape)
+ return;
+ QDialog::keyPressEvent(e);
+}
+
+void TaskDialog::closeEvent(QCloseEvent* e)
+{
+ if (task && task->isRunning())
+ {
+ e->ignore();
+ }
+ else
+ {
+ QDialog::closeEvent(e);
+ }
+}
diff --git a/gui/taskdialog.h b/gui/taskdialog.h
new file mode 100644
index 00000000..faf3ed90
--- /dev/null
+++ b/gui/taskdialog.h
@@ -0,0 +1,63 @@
+/* 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.
+ */
+
+#ifndef TASKDIALOG_H
+#define TASKDIALOG_H
+
+#include <QDialog>
+
+class Task;
+
+namespace Ui {
+class TaskDialog;
+}
+
+class TaskDialog : public QDialog
+{
+ Q_OBJECT
+
+public:
+ explicit TaskDialog(QWidget *parent = 0);
+ ~TaskDialog();
+
+ void updateSize();
+
+ void exec(Task* task);
+
+ Task* getTask();
+
+public slots:
+ void onTaskStarted(Task*);
+ void onTaskEnded(Task*);
+
+ void changeStatus(const QString& status);
+ void changeProgress(int progress);
+
+ void test() { qDebug("Lol"); }
+
+signals:
+
+
+protected:
+ virtual void keyPressEvent(QKeyEvent* e);
+ virtual void closeEvent(QCloseEvent* e);
+
+private:
+ Ui::TaskDialog *ui;
+
+ Task* task;
+};
+
+#endif // TASKDIALOG_H
diff --git a/gui/taskdialog.ui b/gui/taskdialog.ui
new file mode 100644
index 00000000..1cdf7978
--- /dev/null
+++ b/gui/taskdialog.ui
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>TaskDialog</class>
+ <widget class="QDialog" name="TaskDialog">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>400</width>
+ <height>58</height>
+ </rect>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>400</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>600</width>
+ <height>16777215</height>
+ </size>
+ </property>
+ <property name="windowTitle">
+ <string>Please wait...</string>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout">
+ <item>
+ <widget class="QLabel" name="statusLabel">
+ <property name="text">
+ <string>Task Status...</string>
+ </property>
+ <property name="wordWrap">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QProgressBar" name="taskProgressBar">
+ <property name="value">
+ <number>24</number>
+ </property>
+ <property name="textVisible">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/main.cpp b/main.cpp
index 019a8853..6e840317 100644
--- a/main.cpp
+++ b/main.cpp
@@ -19,6 +19,7 @@
#include "data/appsettings.h"
+#include "data/loginresponse.h"
int main(int argc, char *argv[])
{
@@ -28,6 +29,9 @@ int main(int argc, char *argv[])
settings = new AppSettings(&app);
+ // Register meta types.
+ qRegisterMetaType<LoginResponse>("LoginResponse");
+
MainWindow mainWin;
mainWin.show();
diff --git a/tasks/logintask.cpp b/tasks/logintask.cpp
new file mode 100644
index 00000000..f683b811
--- /dev/null
+++ b/tasks/logintask.cpp
@@ -0,0 +1,121 @@
+/* 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 "logintask.h"
+
+#include <QStringList>
+
+#include <QtNetwork/QNetworkAccessManager>
+#include <QtNetwork/QNetworkReply>
+#include <QtNetwork/QNetworkRequest>
+
+#include <QUrl>
+#include <QUrlQuery>
+
+LoginTask::LoginTask(const UserInfo &uInfo, QObject *parent) :
+ Task(parent), uInfo(uInfo)
+{
+
+}
+
+void LoginTask::executeTask()
+{
+ setStatus("Logging in...");
+
+ QNetworkAccessManager netMgr;
+ connect(&netMgr, SIGNAL(finished(QNetworkReply*)),
+ SLOT(processNetReply(QNetworkReply*)));
+
+ QUrl loginURL("https://login.minecraft.net/");
+ QNetworkRequest netRequest(loginURL);
+ netRequest.setHeader(QNetworkRequest::ContentTypeHeader,
+ "application/x-www-form-urlencoded");
+
+ QUrlQuery params;
+ params.addQueryItem("user", uInfo.getUsername());
+ params.addQueryItem("password", uInfo.getPassword());
+ params.addQueryItem("version", "13");
+
+ netReply = netMgr.post(netRequest, params.query(QUrl::EncodeSpaces).toUtf8());
+ exec();
+}
+
+void LoginTask::processNetReply(QNetworkReply *reply)
+{
+ // Check for errors.
+ switch (reply->error())
+ {
+ case QNetworkReply::NoError:
+ {
+ // Check the response code.
+ int responseCode = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
+
+ if (responseCode == 200)
+ {
+ QString responseStr(reply->readAll());
+
+ QStringList strings = responseStr.split(":");
+ if (strings.count() >= 4)
+ {
+ bool parseSuccess;
+ qint64 latestVersion = strings[0].toLongLong(&parseSuccess);
+ if (parseSuccess)
+ {
+ // strings[1] is the download ticket. It isn't used anymore.
+ QString username = strings[2];
+ QString sessionID = strings[3];
+
+ LoginResponse response(username, sessionID, latestVersion);
+ emit loginComplete(response);
+ }
+ else
+ {
+ emit loginFailed("Failed to parse Minecraft version string.");
+ }
+ }
+ else
+ {
+ if (responseStr.toLower() == "bad login")
+ emit loginFailed("Invalid username or password.");
+ else if (responseStr.toLower() == "old version")
+ emit loginFailed("Launcher outdated, please update.");
+ else
+ emit loginFailed("Login failed: " + responseStr);
+ }
+ }
+ else if (responseCode == 503)
+ {
+ emit loginFailed("The login servers are currently unavailable. "
+ "Check http://help.mojang.com/ for more info.");
+ }
+ else
+ {
+ emit loginFailed(QString("Login failed: Unknown HTTP error %1 occurred.").
+ arg(QString::number(responseCode)));
+ }
+ break;
+ }
+
+ case QNetworkReply::OperationCanceledError:
+ emit loginFailed("Login canceled.");
+ break;
+
+ default:
+ emit loginFailed("Login failed: " + reply->errorString());
+ break;
+ }
+
+ quit();
+}
diff --git a/tasks/logintask.h b/tasks/logintask.h
new file mode 100644
index 00000000..d96bfec7
--- /dev/null
+++ b/tasks/logintask.h
@@ -0,0 +1,48 @@
+/* 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.
+ */
+
+#ifndef LOGINTASK_H
+#define LOGINTASK_H
+
+#include "task.h"
+
+#include "data/userinfo.h"
+#include "data/loginresponse.h"
+
+//class QNetworkAccessManager;
+class QNetworkReply;
+
+class LoginTask : public Task
+{
+ Q_OBJECT
+public:
+ explicit LoginTask(const UserInfo& uInfo, QObject *parent = 0);
+
+public slots:
+ void processNetReply(QNetworkReply* reply);
+
+signals:
+ void loginComplete(LoginResponse loginResponse);
+ void loginFailed(const QString& errorMsg);
+
+protected:
+ void executeTask();
+
+ QNetworkReply* netReply;
+
+ UserInfo uInfo;
+};
+
+#endif // LOGINTASK_H
diff --git a/tasks/task.cpp b/tasks/task.cpp
new file mode 100644
index 00000000..d581a1dd
--- /dev/null
+++ b/tasks/task.cpp
@@ -0,0 +1,56 @@
+/* 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 "task.h"
+
+Task::Task(QObject *parent) :
+ QThread(parent)
+{
+
+}
+
+QString Task::getStatus() const
+{
+ return status;
+}
+
+void Task::setStatus(const QString &status)
+{
+ this->status = status;
+ emit statusChanged(status);
+}
+
+int Task::getProgress() const
+{
+ return progress;
+}
+
+void Task::setProgress(int progress)
+{
+ this->progress = progress;
+ emit progressChanged(progress);
+}
+
+void Task::startTask()
+{
+ start();
+}
+
+void Task::run()
+{
+ emit taskStarted(this);
+ executeTask();
+ emit taskEnded(this);
+}
diff --git a/tasks/task.h b/tasks/task.h
new file mode 100644
index 00000000..0124d8cf
--- /dev/null
+++ b/tasks/task.h
@@ -0,0 +1,54 @@
+/* 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.
+ */
+
+#ifndef TASK_H
+#define TASK_H
+
+#include <QObject>
+#include <QThread>
+#include <QString>
+
+class Task : public QThread
+{
+ Q_OBJECT
+public:
+ explicit Task(QObject *parent = 0);
+
+ // Starts the task.
+ void startTask();
+
+ QString getStatus() const;
+ int getProgress() const;
+
+public slots:
+ void setStatus(const QString& status);
+ void setProgress(int progress);
+
+signals:
+ void taskStarted(Task* task);
+ void taskEnded(Task* task);
+
+ void statusChanged(const QString& status);
+ void progressChanged(int progress);
+
+protected:
+ virtual void run();
+ virtual void executeTask() = 0;
+
+ QString status;
+ int progress;
+};
+
+#endif // TASK_H