summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndrew <forkk@forkk.net>2013-12-01 14:28:47 -0600
committerAndrew <forkk@forkk.net>2013-12-01 14:28:47 -0600
commit613699b3626aea750093ab7eaaeccaa28c0e87c6 (patch)
tree7fd542b8f4be10359ba2aaeac9834f1b5c86a750
parent2427ad687137bbcfc7303a931d7e0b74d5325e48 (diff)
parent75c4d97b90e39f2bda6e682def0fdda044cbcf6f (diff)
downloadMultiMC-613699b3626aea750093ab7eaaeccaa28c0e87c6.tar
MultiMC-613699b3626aea750093ab7eaaeccaa28c0e87c6.tar.gz
MultiMC-613699b3626aea750093ab7eaaeccaa28c0e87c6.tar.lz
MultiMC-613699b3626aea750093ab7eaaeccaa28c0e87c6.tar.xz
MultiMC-613699b3626aea750093ab7eaaeccaa28c0e87c6.zip
Merge branch 'develop' of github.com:MultiMC/MultiMC5 into develop
-rw-r--r--CMakeLists.txt223
-rw-r--r--MultiMC.cpp4
-rw-r--r--depends/groupview/src/categorizedview.cpp29
-rw-r--r--depends/groupview/src/categorizedview_p.h17
-rw-r--r--depends/groupview/src/categorydrawer.cpp2
-rw-r--r--depends/pack200/src/bands.cpp2
-rw-r--r--depends/pack200/src/bytes.h2
-rw-r--r--depends/pack200/src/coding.cpp1
-rw-r--r--depends/pack200/src/unpack.cpp17
-rw-r--r--depends/pack200/src/unpack200.cpp2
-rw-r--r--depends/quazip/unzip.c2
-rw-r--r--depends/quazip/zip.c2
-rw-r--r--depends/settings/include/keyring.h5
-rw-r--r--depends/settings/src/stubkeyring.h5
-rw-r--r--gui/ConsoleWindow.cpp21
-rw-r--r--gui/ConsoleWindow.h21
-rw-r--r--gui/MainWindow.cpp58
-rw-r--r--gui/dialogs/AccountListDialog.cpp17
-rw-r--r--gui/dialogs/AccountListDialog.h6
-rw-r--r--gui/dialogs/AccountSelectDialog.cpp8
-rw-r--r--gui/dialogs/AccountSelectDialog.h10
-rw-r--r--gui/dialogs/CopyInstanceDialog.cpp2
-rw-r--r--gui/dialogs/EditAccountDialog.cpp10
-rw-r--r--gui/dialogs/EditAccountDialog.h11
-rw-r--r--gui/dialogs/EditNotesDialog.cpp4
-rw-r--r--gui/dialogs/InstanceSettings.cpp2
-rw-r--r--gui/dialogs/LegacyModEditDialog.cpp2
-rw-r--r--gui/dialogs/OneSixModEditDialog.cpp2
-rw-r--r--gui/widgets/InstanceDelegate.cpp176
-rw-r--r--logic/BaseInstance.cpp2
-rw-r--r--logic/InstanceFactory.cpp12
-rw-r--r--logic/JavaChecker.cpp2
-rw-r--r--logic/JavaChecker.h2
-rw-r--r--logic/LegacyInstance.cpp1
-rw-r--r--logic/MinecraftProcess.cpp30
-rw-r--r--logic/MinecraftProcess.h14
-rw-r--r--logic/ModList.cpp10
-rw-r--r--logic/OneSixInstance.cpp1
-rw-r--r--logic/OneSixUpdate.cpp1
-rw-r--r--logic/auth/MojangAccount.cpp36
-rw-r--r--logic/auth/MojangAccount.h55
-rw-r--r--logic/auth/YggdrasilTask.cpp23
-rw-r--r--logic/auth/YggdrasilTask.h22
-rw-r--r--logic/auth/flows/AuthenticateTask.cpp (renamed from logic/auth/AuthenticateTask.cpp)88
-rw-r--r--logic/auth/flows/AuthenticateTask.h (renamed from logic/auth/AuthenticateTask.h)12
-rw-r--r--logic/auth/flows/InvalidateTask.cpp0
-rw-r--r--logic/auth/flows/InvalidateTask.h0
-rw-r--r--logic/auth/flows/RefreshTask.cpp156
-rw-r--r--logic/auth/flows/RefreshTask.h43
-rw-r--r--logic/auth/flows/ValidateTask.cpp (renamed from logic/auth/ValidateTask.cpp)8
-rw-r--r--logic/auth/flows/ValidateTask.h (renamed from logic/auth/ValidateTask.h)9
-rw-r--r--logic/lists/InstanceList.cpp22
-rw-r--r--logic/lists/InstanceList.h6
-rw-r--r--logic/lists/MojangAccountList.cpp33
-rw-r--r--logic/lists/MojangAccountList.h30
-rw-r--r--test.cpp60
56 files changed, 778 insertions, 563 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index f3cacbe2..79a69225 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -27,14 +27,14 @@ ENDIF()
######## Set compiler flags ########
IF(APPLE)
message(STATUS "Using APPLE CMAKE_CXX_FLAGS")
- SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x")
+ SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -Wall")
ELSEIF(UNIX)
# assume GCC, add C++0x/C++11 stuff
MESSAGE(STATUS "Using UNIX CMAKE_CXX_FLAGS")
- SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x")
+ SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -Wall")
ELSEIF(MINGW)
MESSAGE(STATUS "Using MINGW CMAKE_CXX_FLAGS")
- SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=gnu++0x")
+ SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=gnu++11 -Wall")
ENDIF()
################################ INCLUDE LIBRARIES ################################
@@ -48,6 +48,23 @@ find_package(Qt5LinguistTools REQUIRED)
include_directories(${Qt5Widgets_INCLUDE_DIRS})
+# The Qt5 cmake files don't provide its install paths, so ask qmake.
+get_target_property(QMAKE_EXECUTABLE Qt5::qmake LOCATION)
+function(QUERY_QMAKE VAR RESULT)
+ exec_program(${QMAKE_EXECUTABLE} ARGS "-query ${VAR}" RETURN_VALUE return_code OUTPUT_VARIABLE output )
+ if(NOT return_code)
+ file(TO_CMAKE_PATH "${output}" output)
+ set(${RESULT} ${output} PARENT_SCOPE)
+ endif(NOT return_code)
+endfunction(QUERY_QMAKE)
+
+query_qmake(QT_INSTALL_PLUGINS QT_PLUGINS_DIR)
+query_qmake(QT_INSTALL_IMPORTS QT_IMPORTS_DIR)
+query_qmake(QT_INSTALL_LIBS QT_LIBS_DIR)
+query_qmake(QT_HOST_DATA QT_DATA_DIR)
+set(QT_MKSPECS_DIR ${QT_DATA_DIR}/mkspecs)
+
+
######## Included Libs ########
# Add quazip
@@ -289,11 +306,14 @@ logic/auth/MojangAccount.h
logic/auth/MojangAccount.cpp
logic/auth/YggdrasilTask.h
logic/auth/YggdrasilTask.cpp
-logic/auth/AuthenticateTask.h
-logic/auth/AuthenticateTask.cpp
-logic/auth/ValidateTask.h
-logic/auth/ValidateTask.cpp
-
+logic/auth/flows/AuthenticateTask.h
+logic/auth/flows/AuthenticateTask.cpp
+logic/auth/flows/RefreshTask.cpp
+logic/auth/flows/RefreshTask.cpp
+logic/auth/flows/ValidateTask.h
+logic/auth/flows/ValidateTask.cpp
+logic/auth/flows/InvalidateTask.h
+logic/auth/flows/InvalidateTask.cpp
# legacy instances
logic/LegacyInstance.h
@@ -439,7 +459,6 @@ CONFIGURE_FILE(generated.qrc.in generated.qrc)
QT5_ADD_RESOURCES(GENERATED_QRC ${CMAKE_CURRENT_BINARY_DIR}/generated.qrc)
QT5_ADD_RESOURCES(GRAPHICS_QRC graphics.qrc)
-
# Add executable
ADD_EXECUTABLE(MultiMC MACOSX_BUNDLE WIN32
${MULTIMC_SOURCES} ${MULTIMC_UI} ${GRAPHICS_QRC} ${GENERATED_QRC} ${MULTIMC_RCS})
@@ -449,110 +468,122 @@ TARGET_LINK_LIBRARIES(MultiMC xz-embedded unpack200 quazip libUtil libSettings l
QT5_USE_MODULES(MultiMC Core Widgets Network Xml ${MultiMC_QT_ADDITIONAL_MODULES})
ADD_DEPENDENCIES(MultiMC MultiMCLauncher JavaCheck)
-option(BUILD_KEYRING_TEST "Build the simple keyring test binary" OFF)
-IF(BUILD_KEYRING_TEST)
- # test.cpp
- ADD_EXECUTABLE(Test test.cpp)
- QT5_USE_MODULES(Test Core)
- TARGET_LINK_LIBRARIES(Test libUtil libSettings)
-ENDIF()
-
################################ INSTALLATION AND PACKAGING ################################
-# use QtCreator's QTDIR var
-IF(DEFINED ENV{QTDIR})
- SET(Qt5_DIR $ENV{QTDIR})
-ENDIF()
-######## Plugin and library folders ########
-
-SET(PLUGIN_DEST_DIR plugins)
-SET(QTCONF_DEST_DIR .)
-SET(APPS "\${CMAKE_INSTALL_PREFIX}/MultiMC")
-
-IF(WIN32)
- SET(PLUGIN_DEST_DIR .)
- SET(QTCONF_DEST_DIR .)
- SET(APPS "\${CMAKE_INSTALL_PREFIX}/MultiMC.exe")
-ENDIF()
+######## Packaging/install paths setup ########
-IF(UNIX)
-IF(APPLE)
+IF(UNIX AND APPLE)
SET(PLUGIN_DEST_DIR MultiMC.app/Contents/MacOS)
SET(QTCONF_DEST_DIR MultiMC.app/Contents/Resources)
- SET(APPS "\${CMAKE_INSTALL_PREFIX}/MultiMC.app")
-ELSE()
- SET(APPS "\${CMAKE_INSTALL_PREFIX}/bin/MultiMC")
-ENDIF()
-ENDIF()
-
-SET(QT_PLUGINS_DIR ${Qt5_DIR}/plugins)
-SET(QT_LIBRARY_DIRS ${Qt5_DIR}/lib)
-
+ SET(APPS "\${CMAKE_INSTALL_PREFIX}/MultiMC.app")
-######## OS X Bundle Info ########
-
-IF(APPLE)
SET(MACOSX_BUNDLE_BUNDLE_NAME "MultiMC")
SET(MACOSX_BUNDLE_INFO_STRING "MultiMC Minecraft launcher and management utility.")
- SET(MACOSX_BUNDLE_BUNDLE_VERSION
- "${MultiMC_VERSION_MAJOR}.${MultiMC_VERSION_MINOR}.${MultiMC_VERSION_REV}.${MultiMC_VERSION_BUILD}")
+ SET(MACOSX_BUNDLE_BUNDLE_VERSION "${MultiMC_VERSION_MAJOR}.${MultiMC_VERSION_MINOR}.${MultiMC_VERSION_REV}.${MultiMC_VERSION_BUILD}")
#SET(MACOSX_BUNDLE_GUI_IDENTIFIER "")
SET(MACOSX_BUNDLE_ICON_FILE MultiMC.icns)
-ENDIF(APPLE)
+ELSEIF(UNIX)
+ SET(PLUGIN_DEST_DIR plugins)
+ SET(QTCONF_DEST_DIR .)
+ SET(APPS "\${CMAKE_INSTALL_PREFIX}/bin/MultiMC")
+ELSEIF(WIN32)
+ SET(PLUGIN_DEST_DIR .)
+ SET(QTCONF_DEST_DIR .)
+ SET(APPS "\${CMAKE_INSTALL_PREFIX}/MultiMC.exe")
+ENDIF()
+
+# directories to look for dependencies
+SET(DIRS "${QT_LIBS_DIR}")
######## Install ########
#### Executable ####
-IF(WIN32)
-INSTALL(TARGETS MultiMC
- BUNDLE DESTINATION . COMPONENT Runtime
- LIBRARY DESTINATION . COMPONENT Runtime
- RUNTIME DESTINATION . COMPONENT Runtime
-)
-ENDIF()
-IF(UNIX)
-IF(APPLE)
-INSTALL(TARGETS MultiMC
- BUNDLE DESTINATION . COMPONENT Runtime
- RUNTIME DESTINATION MultiMC.app/Contents/MacOS COMPONENT Runtime
-)
-ELSE()
-INSTALL(TARGETS MultiMC
- BUNDLE DESTINATION . COMPONENT Runtime
- RUNTIME DESTINATION bin COMPONENT Runtime
-)
-INSTALL(PROGRAMS package/linux/MultiMC DESTINATION .)
-ENDIF()
-ENDIF()
+IF(APPLE AND UNIX) ## OSX
+ INSTALL(TARGETS MultiMC
+ BUNDLE DESTINATION . COMPONENT Runtime
+ RUNTIME DESTINATION MultiMC.app/Contents/MacOS COMPONENT Runtime
+ )
+ELSEIF(UNIX) ## LINUX and similar
+ INSTALL(TARGETS MultiMC
+ BUNDLE DESTINATION . COMPONENT Runtime
+ RUNTIME DESTINATION bin COMPONENT Runtime
+ )
+ INSTALL(PROGRAMS package/linux/MultiMC DESTINATION .)
-#### Plugins ####
+ELSEIF(WIN32) ## WINDOWS
+ INSTALL(TARGETS MultiMC
+ BUNDLE DESTINATION . COMPONENT Runtime
+ LIBRARY DESTINATION . COMPONENT Runtime
+ RUNTIME DESTINATION . COMPONENT Runtime
+ )
+ENDIF()
-OPTION(MultiMC_INSTALL_SHARED_LIBS "if set, Qt's shared libraries will be copied to the installation directory on install")
+#### Dist package logic ####
-IF (MultiMC_INSTALL_SHARED_LIBS)
- # Image formats
- INSTALL(DIRECTORY "${QT_PLUGINS_DIR}/imageformats" DESTINATION ${PLUGIN_DEST_DIR} COMPONENT Runtime)
+if (CMAKE_BUILD_TYPE STREQUAL "Debug" OR CMAKE_BUILD_TYPE STREQUAL "RelWithDebInfo")
+# Image formats
+INSTALL(
+ DIRECTORY "${QT_PLUGINS_DIR}/imageformats"
+ DESTINATION ${PLUGIN_DEST_DIR}
+ COMPONENT Runtime
+ REGEX "tga|svg|tiff|mng" EXCLUDE
+)
- # Platform plugins
- INSTALL(DIRECTORY "${QT_PLUGINS_DIR}/platforms" DESTINATION ${PLUGIN_DEST_DIR} COMPONENT Runtime)
+# Platform plugins
+INSTALL(
+ DIRECTORY "${QT_PLUGINS_DIR}/platforms"
+ DESTINATION ${PLUGIN_DEST_DIR}
+ COMPONENT Runtime
+ REGEX "minimal|linuxfb|offscreen" EXCLUDE
+)
+else()
+# Image formats
+INSTALL(
+ DIRECTORY "${QT_PLUGINS_DIR}/imageformats"
+ DESTINATION ${PLUGIN_DEST_DIR}
+ COMPONENT Runtime
+ REGEX "tga|svg|tiff|mng" EXCLUDE
+ REGEX "d\\." EXCLUDE
+ REGEX "_debug\\." EXCLUDE
+)
- # qtconf
- INSTALL(CODE "
- FILE(WRITE \"\${CMAKE_INSTALL_PREFIX}/${QTCONF_DEST_DIR}/qt.conf\" \"\")
- " COMPONENT Runtime)
+# Platform plugins
+INSTALL(
+ DIRECTORY "${QT_PLUGINS_DIR}/platforms"
+ DESTINATION ${PLUGIN_DEST_DIR}
+ COMPONENT Runtime
+ REGEX "minimal|linuxfb|offscreen" EXCLUDE
+ REGEX "d\\." EXCLUDE
+ REGEX "_debug\\." EXCLUDE
+)
+endif()
+
+# qtconf
+INSTALL(
+ CODE "
+FILE(WRITE \"\${CMAKE_INSTALL_PREFIX}/${QTCONF_DEST_DIR}/qt.conf\" \"\")
+"
+ COMPONENT Runtime
+)
- # Dirs to look for dependencies.
- SET(DIRS "${QT_LIBRARY_DIRS}")
+INSTALL(
+ CODE "
+FILE(GLOB_RECURSE QTPLUGINS \"\${CMAKE_INSTALL_PREFIX}/${PLUGIN_DEST_DIR}/*${CMAKE_SHARED_LIBRARY_SUFFIX}\")
+function(gp_resolved_file_type_override resolved_file type_var)
+ if(resolved_file MATCHES \"^/usr/lib/libQt\")
+ message(\"resolving \${resolved_file} as other\")
+ set(\${type_var} other PARENT_SCOPE)
+ endif()
+endfunction()
+
+include(BundleUtilities)
+fixup_bundle(\"${APPS}\" \"\${QTPLUGINS}\" \"${DIRS}\")
+"
+ COMPONENT Runtime
+)
- INSTALL(CODE "
- file(GLOB_RECURSE QTPLUGINS
- \"\${CMAKE_INSTALL_PREFIX}/${PLUGIN_DEST_DIR}/plugins/*${CMAKE_SHARED_LIBRARY_SUFFIX}\")
- include(BundleUtilities)
- fixup_bundle(\"${APPS}\" \"\${QTPLUGINS}\" \"${DIRS}\")
- " COMPONENT Runtime)
-ENDIF()
######## Package ########
@@ -596,14 +627,12 @@ include_directories(${PROJECT_BINARY_DIR}/include)
file (GLOB TRANSLATIONS_FILES translations/*.ts)
option (UPDATE_TRANSLATIONS "Update source translation translations/*.ts files (WARNING: make clean will delete the source .ts files! Danger!)")
-if (UPDATE_TRANSLATIONS)
- qt5_create_translation(QM_FILES ${FILES_TO_TRANSLATE} ${TRANSLATIONS_FILES})
-else (UPDATE_TRANSLATIONS)
- qt5_add_translation(QM_FILES ${TRANSLATIONS_FILES})
-endif (UPDATE_TRANSLATIONS)
+IF(UPDATE_TRANSLATIONS)
+ qt5_create_translation(QM_FILES ${FILES_TO_TRANSLATE} ${TRANSLATIONS_FILES})
+ELSE()
+ qt5_add_translation(QM_FILES ${TRANSLATIONS_FILES})
+ENDIF()
add_custom_target (translations DEPENDS ${QM_FILES})
install(FILES ${QM_FILES} DESTINATION ${CMAKE_INSTALL_PREFIX}/translations)
-
-
diff --git a/MultiMC.cpp b/MultiMC.cpp
index a41f5f0a..e10292ab 100644
--- a/MultiMC.cpp
+++ b/MultiMC.cpp
@@ -189,6 +189,9 @@ MultiMC::MultiMC(int &argc, char **argv) : QApplication(argc, argv),
case QNetworkProxy::FtpCachingProxy:
proxyDesc = "FTP caching: ";
break;
+ default:
+ proxyDesc = "DERP proxy: ";
+ break;
}
proxyDesc += QString("%3@%1:%2 pass %4")
.arg(proxy.hostName())
@@ -326,6 +329,7 @@ void MultiMC::initGlobalSettings()
m_settings->registerSetting(new Setting("InstSortMode", "Name"));
+ m_settings->registerSetting(new Setting("SelectedInstance", QString()));
// Persistent value for the client ID
m_settings->registerSetting(new Setting("YggdrasilClientToken", ""));
diff --git a/depends/groupview/src/categorizedview.cpp b/depends/groupview/src/categorizedview.cpp
index f4449949..1345205c 100644
--- a/depends/groupview/src/categorizedview.cpp
+++ b/depends/groupview/src/categorizedview.cpp
@@ -58,18 +58,6 @@ struct KCategorizedView::Private::Item
struct KCategorizedView::Private::Block
{
- Block()
- : topLeft ( QPoint() )
- , height ( -1 )
- , firstIndex ( QModelIndex() )
- , quarantineStart ( QModelIndex() )
- , items ( QList<Item>() )
- , outOfQuarantine ( false )
- , alternate ( false )
- , collapsed ( false )
- {
- }
-
bool operator!= ( const Block &rhs ) const
{
return firstIndex != rhs.firstIndex;
@@ -83,7 +71,7 @@ struct KCategorizedView::Private::Block
}
QPoint topLeft;
- int height;
+ int height = -1;
QPersistentModelIndex firstIndex;
// if we have n elements on this block, and we inserted an element at position i. The quarantine
// will start at index (i, column, parent). This means that for all elements j where i <= j <= n, the
@@ -97,25 +85,16 @@ struct KCategorizedView::Private::Block
// this affects the whole block, not items separately. items contain the topLeft point relative
// to the block. Because of insertions or removals a whole block can be moved, so the whole block
// will enter in quarantine, what is faster than moving all items in absolute terms.
- bool outOfQuarantine;
+ bool outOfQuarantine = false;
// should we alternate its color ? is just a hint, could not be used
- bool alternate;
- bool collapsed;
+ bool alternate = false;
+ bool collapsed = false;
};
KCategorizedView::Private::Private ( KCategorizedView *q )
: q ( q )
- , proxyModel ( 0 )
- , categoryDrawer ( 0 )
- , categorySpacing ( 5 )
- , alternatingBlockColors ( false )
- , collapsibleBlocks ( false )
, hoveredBlock ( new Block() )
- , hoveredIndex ( QModelIndex() )
- , pressedPosition ( QPoint() )
- , rubberBandRect ( QRect() )
- , constantItemWidth( 0 )
{
}
diff --git a/depends/groupview/src/categorizedview_p.h b/depends/groupview/src/categorizedview_p.h
index 13809312..524bba3a 100644
--- a/depends/groupview/src/categorizedview_p.h
+++ b/depends/groupview/src/categorizedview_p.h
@@ -137,14 +137,15 @@ public:
*/
void _k_slotCollapseOrExpandClicked(QModelIndex);
- KCategorizedView *q;
- KCategorizedSortFilterProxyModel *proxyModel;
- KCategoryDrawer *categoryDrawer;
- int categorySpacing;
- bool alternatingBlockColors;
- bool collapsibleBlocks;
- bool constantItemWidth;
-
+ KCategorizedView *q = nullptr;
+ KCategorizedSortFilterProxyModel *proxyModel = nullptr;
+ KCategoryDrawer *categoryDrawer = nullptr;
+ int categorySpacing = 5;
+ bool alternatingBlockColors = false;
+ bool collapsibleBlocks = false;
+ bool constantItemWidth = false;
+
+ // FIXME: this is some really weird logic. Investigate.
Block *hoveredBlock;
QString hoveredCategory;
QModelIndex hoveredIndex;
diff --git a/depends/groupview/src/categorydrawer.cpp b/depends/groupview/src/categorydrawer.cpp
index 04903206..214ce3b2 100644
--- a/depends/groupview/src/categorydrawer.cpp
+++ b/depends/groupview/src/categorydrawer.cpp
@@ -42,9 +42,9 @@ public:
~Private()
{
}
+ KCategorizedView *view;
int leftMargin;
int rightMargin;
- KCategorizedView *view;
};
KCategoryDrawer::KCategoryDrawer(KCategorizedView *view)
diff --git a/depends/pack200/src/bands.cpp b/depends/pack200/src/bands.cpp
index 1c10b35b..1608d838 100644
--- a/depends/pack200/src/bands.cpp
+++ b/depends/pack200/src/bands.cpp
@@ -79,7 +79,6 @@ void band::readData(int expectedLength)
// Read one value to see what it might be.
int XB = _meta_default;
- int cp1 = 0, cp2 = 0;
if (!is_BYTE1)
{
// must be a variable-length coding
@@ -109,7 +108,6 @@ void band::readData(int expectedLength)
{
// Skip over the escape value.
u->rp = xvs.rp;
- cp1 = 1;
}
else
{
diff --git a/depends/pack200/src/bytes.h b/depends/pack200/src/bytes.h
index 2e4a9daf..6ed0b729 100644
--- a/depends/pack200/src/bytes.h
+++ b/depends/pack200/src/bytes.h
@@ -87,7 +87,7 @@ struct bytes
bytes res;
res.ptr = ptr + beg;
res.len = end - beg;
- assert(res.len == 0 || inBounds(res.ptr) && inBounds(res.limit() - 1));
+ assert(res.len == 0 ||(inBounds(res.ptr) && inBounds(res.limit() - 1)));
return res;
}
// building C strings inside byte buffers:
diff --git a/depends/pack200/src/coding.cpp b/depends/pack200/src/coding.cpp
index 226ba458..3e311131 100644
--- a/depends/pack200/src/coding.cpp
+++ b/depends/pack200/src/coding.cpp
@@ -121,7 +121,6 @@ coding *coding::init()
this->min = this->umin = 0;
if (S != 0 && range != 0)
{
- int Smask = (1 << S) - 1;
int64_t maxPosCode = range - 1;
int64_t maxNegCode = range - 1;
while (IS_NEG_CODE(S, maxPosCode))
diff --git a/depends/pack200/src/unpack.cpp b/depends/pack200/src/unpack.cpp
index b286269d..55d253b2 100644
--- a/depends/pack200/src/unpack.cpp
+++ b/depends/pack200/src/unpack.cpp
@@ -483,10 +483,6 @@ void unpacker::putu1ref(entry *e)
putu1_at(put_space(1), oidx);
}
-static int total_cp_size[] = {0, 0};
-static int largest_cp_ref[] = {0, 0};
-static int hash_probes[] = {0, 0};
-
// Allocation of small and large blocks.
enum
@@ -705,7 +701,7 @@ void unpacker::read_file_header()
unpack_abort("impossible archive size"); // bad input data
return;
}
- if (archive_size < header_size_1)
+ if (archive_size < (size_t)header_size_1)
{
unpack_abort("too much read-ahead"); // somehow we pre-fetched too much?
return;
@@ -1316,8 +1312,6 @@ void unpacker::read_signature_values(entry *cpMap, int len)
// Cf. PackageReader.readConstantPool
void unpacker::read_cp()
{
- byte *rp0 = rp;
-
int i;
for (int k = 0; k < (int)N_TAGS_IN_ORDER; k++)
@@ -1596,7 +1590,6 @@ band **unpacker::attr_definitions::buildBands(unpacker::layout_definition *lo)
const char *unpacker::attr_definitions::parseIntLayout(const char *lp, band *&res, byte le_kind,
bool can_be_signed)
{
- const char *lp0 = lp;
band *b = U_NEW(band, 1);
char le = *lp++;
int spec = UNSIGNED5_spec;
@@ -1638,7 +1631,6 @@ const char *unpacker::attr_definitions::parseIntLayout(const char *lp, band *&re
const char *unpacker::attr_definitions::parseNumeral(const char *lp, int &res)
{
- const char *lp0 = lp;
bool sgn = false;
if (*lp == '0')
{
@@ -1703,7 +1695,6 @@ band **unpacker::attr_definitions::popBody(int bs_base)
const char *unpacker::attr_definitions::parseLayout(const char *lp, band **&res, int curCble)
{
- const char *lp0 = lp;
int bs_base = band_stack.length();
bool top_level = (bs_base == 0);
band *b;
@@ -3135,8 +3126,6 @@ unpacker::read_bcs()
void unpacker::read_bands()
{
- byte *rp0 = rp;
-
read_file_header();
if (cp.nentries == 0)
@@ -3312,7 +3301,7 @@ void constant_pool::initMemberIndexes()
// Get the pre-existing indexes:
int nclasses = tag_count[CONSTANT_Class];
- entry *classes = tag_base[CONSTANT_Class] + entries;
+ // entry *classes = tag_base[CONSTANT_Class] + entries; // UNUSED
int nfields = tag_count[CONSTANT_Fieldref];
entry *fields = tag_base[CONSTANT_Fieldref] + entries;
int nmethods = tag_count[CONSTANT_Methodref];
@@ -3563,8 +3552,6 @@ void unpacker::start(void *packptr, size_t len)
void unpacker::check_options()
{
- const char *strue = "true";
- const char *sfalse = "false";
if (deflate_hint_or_zero != 0)
{
bool force_deflate_hint = (deflate_hint_or_zero > 0);
diff --git a/depends/pack200/src/unpack200.cpp b/depends/pack200/src/unpack200.cpp
index 2ff8c34a..0a9d2714 100644
--- a/depends/pack200/src/unpack200.cpp
+++ b/depends/pack200/src/unpack200.cpp
@@ -97,8 +97,6 @@ static int read_magic(unpacker *u, char peek[], int peeklen)
void unpack_200(std::string input_path, std::string output_path)
{
unpacker u;
- int status = 0;
-
FILE *input = fopen(input_path.c_str(), "rb");
if (!input)
{
diff --git a/depends/quazip/unzip.c b/depends/quazip/unzip.c
index 6e115ae6..52bc081f 100644
--- a/depends/quazip/unzip.c
+++ b/depends/quazip/unzip.c
@@ -1173,7 +1173,7 @@ extern int ZEXPORT unzOpenCurrentFile3 (file, method, level, raw, password)
if (password != NULL)
{
int i;
- s->pcrc_32_tab = get_crc_table();
+ s->pcrc_32_tab = (const unsigned long*) get_crc_table();
init_keys(password,s->keys,s->pcrc_32_tab);
if (ZSEEK(s->z_filefunc, s->filestream,
s->pfile_in_zip_read->pos_in_zipfile +
diff --git a/depends/quazip/zip.c b/depends/quazip/zip.c
index bf8c0a10..a36a20a1 100644
--- a/depends/quazip/zip.c
+++ b/depends/quazip/zip.c
@@ -903,7 +903,7 @@ extern int ZEXPORT zipOpenNewFileInZip3 (file, filename, zipfi,
unsigned char bufHead[RAND_HEAD_LEN];
unsigned int sizeHead;
zi->ci.encrypt = 1;
- zi->ci.pcrc_32_tab = get_crc_table();
+ zi->ci.pcrc_32_tab = (const unsigned long*) get_crc_table();
/*init_keys(password,zi->ci.keys,zi->ci.pcrc_32_tab);*/
crcForCrypting = (uLong)zi->ci.dosDate << 16; // ATTANTION! Without this row, you don't unpack your password protected archive in other app.
diff --git a/depends/settings/include/keyring.h b/depends/settings/include/keyring.h
index 747211de..a4da23b1 100644
--- a/depends/settings/include/keyring.h
+++ b/depends/settings/include/keyring.h
@@ -34,6 +34,11 @@ class LIBSETTINGS_EXPORT Keyring
{
public:
/**
+ * @brief virtual dtor
+ */
+ virtual ~Keyring() {};
+
+ /**
* @brief the System Keyring instance
* @return the Keyring instance
*/
diff --git a/depends/settings/src/stubkeyring.h b/depends/settings/src/stubkeyring.h
index f25cefde..1f4b1be0 100644
--- a/depends/settings/src/stubkeyring.h
+++ b/depends/settings/src/stubkeyring.h
@@ -24,6 +24,11 @@
class StubKeyring : public Keyring
{
public:
+ /**
+ * @brief virtual dtor
+ */
+ virtual ~StubKeyring() {};
+
virtual bool storePassword(QString service, QString username, QString password);
virtual QString getPassword(QString service, QString username);
virtual bool hasPassword(QString service, QString username);
diff --git a/gui/ConsoleWindow.cpp b/gui/ConsoleWindow.cpp
index d8a1b69d..d0210df6 100644
--- a/gui/ConsoleWindow.cpp
+++ b/gui/ConsoleWindow.cpp
@@ -58,13 +58,23 @@ void ConsoleWindow::writeColor(QString text, const char *color)
ui->text->appendHtml(QString("<font color=\"%1\">%2</font>").arg(color).arg(text));
else
ui->text->appendPlainText(text);
- // scroll down
- QScrollBar *bar = ui->text->verticalScrollBar();
- bar->setValue(bar->maximum());
}
void ConsoleWindow::write(QString data, MessageLevel::Enum mode)
{
+ QScrollBar *bar = ui->text->verticalScrollBar();
+ int max_bar = bar->maximum();
+ int val_bar = bar->value();
+ if(m_scroll_active)
+ {
+ if(m_last_scroll_value > val_bar)
+ m_scroll_active = false;
+ }
+ else
+ {
+ m_scroll_active = val_bar == max_bar;
+ }
+
if (data.endsWith('\n'))
data = data.left(data.length() - 1);
QStringList paragraphs = data.split('\n');
@@ -93,6 +103,11 @@ void ConsoleWindow::write(QString data, MessageLevel::Enum mode)
else
while (iter.hasNext())
writeColor(iter.next());
+ if(m_scroll_active)
+ {
+ bar->setValue(bar->maximum());
+ }
+ m_last_scroll_value = bar->value();
}
void ConsoleWindow::clear()
diff --git a/gui/ConsoleWindow.h b/gui/ConsoleWindow.h
index e0a47bc6..2d948484 100644
--- a/gui/ConsoleWindow.h
+++ b/gui/ConsoleWindow.h
@@ -38,6 +38,16 @@ public:
*/
void setMayClose(bool mayclose);
+private:
+ /**
+ * @brief write a colored paragraph
+ * @param data the string
+ * @param color the css color name
+ * this will only insert a single paragraph.
+ * \n are ignored. a real \n is always appended.
+ */
+ void writeColor(QString data, const char *color = nullptr);
+
signals:
void isClosing();
@@ -52,15 +62,6 @@ slots:
void write(QString data, MessageLevel::Enum level = MessageLevel::MultiMC);
/**
- * @brief write a colored paragraph
- * @param data the string
- * @param color the css color name
- * this will only insert a single paragraph.
- * \n are ignored. a real \n is always appended.
- */
- void writeColor(QString data, const char *color = nullptr);
-
- /**
* @brief clear the text widget
*/
void clear();
@@ -82,4 +83,6 @@ private:
Ui::ConsoleWindow *ui = nullptr;
MinecraftProcess *proc = nullptr;
bool m_mayclose = true;
+ int m_last_scroll_value = 0;
+ bool m_scroll_active = true;
};
diff --git a/gui/MainWindow.cpp b/gui/MainWindow.cpp
index cb81958b..854091c6 100644
--- a/gui/MainWindow.cpp
+++ b/gui/MainWindow.cpp
@@ -69,8 +69,9 @@
#include "logic/lists/IconList.h"
#include "logic/lists/JavaVersionList.h"
-#include "logic/auth/AuthenticateTask.h"
-#include "logic/auth/ValidateTask.h"
+#include "logic/auth/flows/AuthenticateTask.h"
+#include "logic/auth/flows/RefreshTask.h"
+#include "logic/auth/flows/ValidateTask.h"
#include "logic/BaseInstance.h"
#include "logic/InstanceFactory.h"
@@ -244,6 +245,28 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWi
connect(assets_downloader, SIGNAL(finished()), SLOT(assetsFinished()));
assets_downloader->start();
}
+
+ const QString currentInstanceId = MMC->settings()->get("SelectedInstance").toString();
+ if (!currentInstanceId.isNull())
+ {
+ const QModelIndex index = MMC->instances()->getInstanceIndexById(currentInstanceId);
+ if (index.isValid())
+ {
+ const QModelIndex mappedIndex = proxymodel->mapFromSource(index);
+ view->setCurrentIndex(mappedIndex);
+ }
+ else
+ {
+ view->setCurrentIndex(proxymodel->index(0, 0));
+ }
+ }
+ else
+ {
+ view->setCurrentIndex(proxymodel->index(0, 0));
+ }
+
+ // removing this looks stupid
+ view->setFocus();
}
MainWindow::~MainWindow()
@@ -254,7 +277,6 @@ MainWindow::~MainWindow()
delete assets_downloader;
}
-
void MainWindow::repopulateAccountsMenu()
{
accountMenu->clear();
@@ -769,16 +791,16 @@ void MainWindow::doLaunchInst(BaseInstance* instance, MojangAccountPtr account)
{
// We'll need to validate the access token to make sure the account is still logged in.
ProgressDialog progDialog(this);
- ValidateTask validateTask(account, &progDialog);
- progDialog.exec(&validateTask);
-
- if (validateTask.successful())
+ RefreshTask refreshtask(account, &progDialog);
+ progDialog.exec(&refreshtask);
+
+ if (refreshtask.successful())
{
prepareLaunch(m_selectedInstance, account);
}
else
{
- YggdrasilTask::Error* error = validateTask.getError();
+ YggdrasilTask::Error *error = refreshtask.getError();
if (error != nullptr)
{
@@ -790,17 +812,20 @@ void MainWindow::doLaunchInst(BaseInstance* instance, MojangAccountPtr account)
}
else
{
- CustomMessageBox::selectable(this, tr("Access Token Validation Error"),
+ CustomMessageBox::selectable(
+ this, tr("Access Token Validation Error"),
tr("There was an error when trying to validate your access token.\n"
- "Details: %s").arg(error->getDisplayMessage()),
+ "Details: %s").arg(error->getDisplayMessage()),
QMessageBox::Warning, QMessageBox::Ok)->exec();
}
}
else
{
- CustomMessageBox::selectable(this, tr("Access Token Validation Error"),
+ CustomMessageBox::selectable(
+ this, tr("Access Token Validation Error"),
tr("There was an unknown error when trying to validate your access token."
- "The authentication server might be down, or you might not be connected to the Internet."),
+ "The authentication server might be down, or you might not be connected to "
+ "the Internet."),
QMessageBox::Warning, QMessageBox::Ok)->exec();
}
}
@@ -857,10 +882,7 @@ void MainWindow::launchInstance(BaseInstance *instance, MojangAccountPtr account
console = new ConsoleWindow(proc);
connect(console, SIGNAL(isClosing()), this, SLOT(instanceEnded()));
- // I think this will work...
- QString username = account->username();
- QString session_id = account->accessToken();
- proc->setLogin(username, session_id);
+ proc->setLogin(account);
proc->launch();
}
@@ -983,10 +1005,14 @@ void MainWindow::instanceChanged(const QModelIndex &current, const QModelIndex &
m_statusLeft->setText(m_selectedInstance->getStatusbarDescription());
auto ico = MMC->icons()->getIcon(iconKey);
ui->actionChangeInstIcon->setIcon(ico);
+
+ MMC->settings()->set("SelectedInstance", m_selectedInstance->id());
}
else
{
selectionBad();
+
+ MMC->settings()->set("SelectedInstance", QString());
}
}
diff --git a/gui/dialogs/AccountListDialog.cpp b/gui/dialogs/AccountListDialog.cpp
index dfac4989..f5268b61 100644
--- a/gui/dialogs/AccountListDialog.cpp
+++ b/gui/dialogs/AccountListDialog.cpp
@@ -20,7 +20,7 @@
#include <logger/QsLog.h>
-#include <logic/auth/AuthenticateTask.h>
+#include <logic/auth/flows/AuthenticateTask.h>
#include <logic/net/NetJob.h>
#include <gui/dialogs/EditAccountDialog.h>
@@ -29,9 +29,8 @@
#include <MultiMC.h>
-AccountListDialog::AccountListDialog(QWidget *parent) :
- QDialog(parent),
- ui(new Ui::AccountListDialog)
+AccountListDialog::AccountListDialog(QWidget *parent)
+ : QDialog(parent), ui(new Ui::AccountListDialog)
{
ui->setupUi(this);
@@ -44,8 +43,8 @@ AccountListDialog::AccountListDialog(QWidget *parent) :
connect(selectionModel, &QItemSelectionModel::selectionChanged,
[this] (const QItemSelection& sel, const QItemSelection& dsel) { updateButtonStates(); });
- connect(m_accounts.get(), SIGNAL(listChanged), SLOT(listChanged));
- connect(m_accounts.get(), SIGNAL(activeAccountChanged), SLOT(listChanged));
+ connect(m_accounts.get(), SIGNAL(listChanged()), SLOT(listChanged()));
+ connect(m_accounts.get(), SIGNAL(activeAccountChanged()), SLOT(listChanged()));
updateButtonStates();
}
@@ -60,7 +59,6 @@ void AccountListDialog::listChanged()
updateButtonStates();
}
-
void AccountListDialog::on_addAccountBtn_clicked()
{
addAccount(tr("Please enter your Mojang or Minecraft account username and password to add your account."));
@@ -84,7 +82,7 @@ void AccountListDialog::on_setDefaultBtn_clicked()
QModelIndex selected = selection.first();
MojangAccountPtr account = selected.data(MojangAccountList::PointerRole).value<MojangAccountPtr>();
m_accounts->setActiveAccount(account->username());
- }
+ }
}
void AccountListDialog::on_noDefaultBtn_clicked()
@@ -104,7 +102,7 @@ void AccountListDialog::updateButtonStates()
ui->rmAccountBtn->setEnabled(selection.size() > 0);
ui->setDefaultBtn->setEnabled(selection.size() > 0);
-
+
ui->noDefaultBtn->setDown(m_accounts->activeAccount().get() == nullptr);
}
@@ -146,4 +144,3 @@ void AccountListDialog::addAccount(const QString& errMsg)
}
}
}
-
diff --git a/gui/dialogs/AccountListDialog.h b/gui/dialogs/AccountListDialog.h
index 634d944a..84ff8e0e 100644
--- a/gui/dialogs/AccountListDialog.h
+++ b/gui/dialogs/AccountListDialog.h
@@ -21,7 +21,8 @@
#include "logic/lists/MojangAccountList.h"
-namespace Ui {
+namespace Ui
+{
class AccountListDialog;
}
@@ -29,7 +30,7 @@ class AuthenticateTask;
class AccountListDialog : public QDialog
{
-Q_OBJECT
+ Q_OBJECT
public:
explicit AccountListDialog(QWidget *parent = 0);
~AccountListDialog();
@@ -62,4 +63,3 @@ slots:
private:
Ui::AccountListDialog *ui;
};
-
diff --git a/gui/dialogs/AccountSelectDialog.cpp b/gui/dialogs/AccountSelectDialog.cpp
index db1bd192..b8fa9e42 100644
--- a/gui/dialogs/AccountSelectDialog.cpp
+++ b/gui/dialogs/AccountSelectDialog.cpp
@@ -20,15 +20,14 @@
#include <logger/QsLog.h>
-#include <logic/auth/AuthenticateTask.h>
+#include <logic/auth/flows/AuthenticateTask.h>
#include <gui/dialogs/ProgressDialog.h>
#include <MultiMC.h>
-AccountSelectDialog::AccountSelectDialog(const QString& message, int flags, QWidget *parent) :
- QDialog(parent),
- ui(new Ui::AccountSelectDialog)
+AccountSelectDialog::AccountSelectDialog(const QString &message, int flags, QWidget *parent)
+ : QDialog(parent), ui(new Ui::AccountSelectDialog)
{
ui->setupUi(this);
@@ -85,4 +84,3 @@ void AccountSelectDialog::on_buttonBox_rejected()
{
close();
}
-
diff --git a/gui/dialogs/AccountSelectDialog.h b/gui/dialogs/AccountSelectDialog.h
index 41af4f7c..a539e7e9 100644
--- a/gui/dialogs/AccountSelectDialog.h
+++ b/gui/dialogs/AccountSelectDialog.h
@@ -21,17 +21,18 @@
#include "logic/lists/MojangAccountList.h"
-namespace Ui {
+namespace Ui
+{
class AccountSelectDialog;
}
class AccountSelectDialog : public QDialog
{
-Q_OBJECT
+ Q_OBJECT
public:
enum Flags
{
- NoFlags=0,
+ NoFlags = 0,
/*!
* Shows a check box on the dialog that allows the user to specify that the account
@@ -75,7 +76,7 @@ public:
public
slots:
void on_buttonBox_accepted();
-
+
void on_buttonBox_rejected();
protected:
@@ -87,4 +88,3 @@ protected:
private:
Ui::AccountSelectDialog *ui;
};
-
diff --git a/gui/dialogs/CopyInstanceDialog.cpp b/gui/dialogs/CopyInstanceDialog.cpp
index 4d588a1e..9d7ac30c 100644
--- a/gui/dialogs/CopyInstanceDialog.cpp
+++ b/gui/dialogs/CopyInstanceDialog.cpp
@@ -33,7 +33,7 @@
#include "logic/BaseInstance.h"
CopyInstanceDialog::CopyInstanceDialog(BaseInstance *original, QWidget *parent)
- : m_original(original), QDialog(parent), ui(new Ui::CopyInstanceDialog)
+ :QDialog(parent), ui(new Ui::CopyInstanceDialog), m_original(original)
{
MultiMCPlatform::fixWM_CLASS(this);
ui->setupUi(this);
diff --git a/gui/dialogs/EditAccountDialog.cpp b/gui/dialogs/EditAccountDialog.cpp
index d28336f7..dd3f0523 100644
--- a/gui/dialogs/EditAccountDialog.cpp
+++ b/gui/dialogs/EditAccountDialog.cpp
@@ -16,11 +16,10 @@
#include "EditAccountDialog.h"
#include "ui_EditAccountDialog.h"
-EditAccountDialog::EditAccountDialog(const QString& text, QWidget *parent, int flags) :
- QDialog(parent),
- ui(new Ui::EditAccountDialog)
+EditAccountDialog::EditAccountDialog(const QString &text, QWidget *parent, int flags)
+ : QDialog(parent), ui(new Ui::EditAccountDialog)
{
- ui->setupUi(this);
+ ui->setupUi(this);
ui->label->setText(text);
ui->label->setVisible(!text.isEmpty());
@@ -31,7 +30,7 @@ EditAccountDialog::EditAccountDialog(const QString& text, QWidget *parent, int f
EditAccountDialog::~EditAccountDialog()
{
- delete ui;
+ delete ui;
}
QString EditAccountDialog::username() const
@@ -43,4 +42,3 @@ QString EditAccountDialog::password() const
{
return ui->passTextBox->text();
}
-
diff --git a/gui/dialogs/EditAccountDialog.h b/gui/dialogs/EditAccountDialog.h
index 847c3be5..be3a88d8 100644
--- a/gui/dialogs/EditAccountDialog.h
+++ b/gui/dialogs/EditAccountDialog.h
@@ -17,16 +17,18 @@
#include <QDialog>
-namespace Ui {
+namespace Ui
+{
class EditAccountDialog;
}
class EditAccountDialog : public QDialog
{
-Q_OBJECT
+ Q_OBJECT
public:
- explicit EditAccountDialog(const QString& text="", QWidget *parent = 0, int flags=UsernameField | PasswordField);
+ explicit EditAccountDialog(const QString &text = "", QWidget *parent = 0,
+ int flags = UsernameField | PasswordField);
~EditAccountDialog();
/*!
@@ -41,7 +43,7 @@ public:
enum Flags
{
- NoFlags=0,
+ NoFlags = 0,
//! Specifies that the dialog should have a username field.
UsernameField,
@@ -53,4 +55,3 @@ public:
private:
Ui::EditAccountDialog *ui;
};
-
diff --git a/gui/dialogs/EditNotesDialog.cpp b/gui/dialogs/EditNotesDialog.cpp
index cd52e694..a265a4d0 100644
--- a/gui/dialogs/EditNotesDialog.cpp
+++ b/gui/dialogs/EditNotesDialog.cpp
@@ -21,8 +21,8 @@
#include <QApplication>
EditNotesDialog::EditNotesDialog(QString notes, QString name, QWidget *parent)
- : m_instance_notes(notes), m_instance_name(name), QDialog(parent),
- ui(new Ui::EditNotesDialog)
+ : QDialog(parent), ui(new Ui::EditNotesDialog), m_instance_name(name),
+ m_instance_notes(notes)
{
MultiMCPlatform::fixWM_CLASS(this);
ui->setupUi(this);
diff --git a/gui/dialogs/InstanceSettings.cpp b/gui/dialogs/InstanceSettings.cpp
index f059047f..bc6b266a 100644
--- a/gui/dialogs/InstanceSettings.cpp
+++ b/gui/dialogs/InstanceSettings.cpp
@@ -32,7 +32,7 @@
#include <QMessageBox>
InstanceSettings::InstanceSettings(SettingsObject *obj, QWidget *parent)
- : m_obj(obj), QDialog(parent), ui(new Ui::InstanceSettings)
+ : QDialog(parent), ui(new Ui::InstanceSettings), m_obj(obj)
{
MultiMCPlatform::fixWM_CLASS(this);
ui->setupUi(this);
diff --git a/gui/dialogs/LegacyModEditDialog.cpp b/gui/dialogs/LegacyModEditDialog.cpp
index 25a1c616..66d53ee1 100644
--- a/gui/dialogs/LegacyModEditDialog.cpp
+++ b/gui/dialogs/LegacyModEditDialog.cpp
@@ -31,7 +31,7 @@
#include <QKeyEvent>
LegacyModEditDialog::LegacyModEditDialog(LegacyInstance *inst, QWidget *parent)
- : m_inst(inst), QDialog(parent), ui(new Ui::LegacyModEditDialog)
+ : QDialog(parent), ui(new Ui::LegacyModEditDialog), m_inst(inst)
{
MultiMCPlatform::fixWM_CLASS(this);
ui->setupUi(this);
diff --git a/gui/dialogs/OneSixModEditDialog.cpp b/gui/dialogs/OneSixModEditDialog.cpp
index dea1b86b..51ea2d19 100644
--- a/gui/dialogs/OneSixModEditDialog.cpp
+++ b/gui/dialogs/OneSixModEditDialog.cpp
@@ -40,7 +40,7 @@
#include "logic/ForgeInstaller.h"
OneSixModEditDialog::OneSixModEditDialog(OneSixInstance *inst, QWidget *parent)
- : m_inst(inst), QDialog(parent), ui(new Ui::OneSixModEditDialog)
+ : QDialog(parent), ui(new Ui::OneSixModEditDialog), m_inst(inst)
{
MultiMCPlatform::fixWM_CLASS(this);
ui->setupUi(this);
diff --git a/gui/widgets/InstanceDelegate.cpp b/gui/widgets/InstanceDelegate.cpp
index 487fed61..5020b8b6 100644
--- a/gui/widgets/InstanceDelegate.cpp
+++ b/gui/widgets/InstanceDelegate.cpp
@@ -21,45 +21,45 @@
#include <QtCore/qmath.h>
// Origin: Qt
-static void viewItemTextLayout ( QTextLayout &textLayout, int lineWidth, qreal &height, qreal &widthUsed )
+static void viewItemTextLayout(QTextLayout &textLayout, int lineWidth, qreal &height,
+ qreal &widthUsed)
{
height = 0;
widthUsed = 0;
textLayout.beginLayout();
QString str = textLayout.text();
- while ( true )
+ while (true)
{
QTextLine line = textLayout.createLine();
- if ( !line.isValid() )
+ if (!line.isValid())
break;
- if(line.textLength() == 0)
+ if (line.textLength() == 0)
break;
- line.setLineWidth ( lineWidth );
- line.setPosition ( QPointF ( 0, height ) );
+ line.setLineWidth(lineWidth);
+ line.setPosition(QPointF(0, height));
height += line.height();
- widthUsed = qMax ( widthUsed, line.naturalTextWidth() );
+ widthUsed = qMax(widthUsed, line.naturalTextWidth());
}
textLayout.endLayout();
}
-#define QFIXED_MAX (INT_MAX/256)
+#define QFIXED_MAX (INT_MAX / 256)
-ListViewDelegate::ListViewDelegate ( QObject* parent ) : QStyledItemDelegate ( parent )
+ListViewDelegate::ListViewDelegate(QObject *parent) : QStyledItemDelegate(parent)
{
-
}
-void drawSelectionRect(QPainter *painter, const QStyleOptionViewItemV4 &option, const QRect &rect)
+void drawSelectionRect(QPainter *painter, const QStyleOptionViewItemV4 &option,
+ const QRect &rect)
{
if ((option.state & QStyle::State_Selected))
- painter->fillRect ( rect, option.palette.brush ( QPalette::Highlight ) );
+ painter->fillRect(rect, option.palette.brush(QPalette::Highlight));
else
{
QColor backgroundColor = option.palette.color(QPalette::Background);
backgroundColor.setAlpha(160);
- painter->fillRect ( rect, QBrush(backgroundColor) );
+ painter->fillRect(rect, QBrush(backgroundColor));
}
-
}
void drawFocusRect(QPainter *painter, const QStyleOptionViewItemV4 &option, const QRect &rect)
@@ -67,11 +67,12 @@ void drawFocusRect(QPainter *painter, const QStyleOptionViewItemV4 &option, cons
if (!(option.state & QStyle::State_HasFocus))
return;
QStyleOptionFocusRect opt;
- opt.direction = option.direction;
- opt.fontMetrics = option.fontMetrics;
- opt.palette = option.palette;
- opt.rect = rect;
- //opt.state = option.state | QStyle::State_KeyboardFocusChange | QStyle::State_Item;
+ opt.direction = option.direction;
+ opt.fontMetrics = option.fontMetrics;
+ opt.palette = option.palette;
+ opt.rect = rect;
+ // opt.state = option.state | QStyle::State_KeyboardFocusChange |
+ // QStyle::State_Item;
auto col = option.state & QStyle::State_Selected ? QPalette::Highlight : QPalette::Base;
opt.backgroundColor = option.palette.color(col);
// Apparently some widget styles expect this hint to not be set
@@ -84,29 +85,31 @@ void drawFocusRect(QPainter *painter, const QStyleOptionViewItemV4 &option, cons
painter->setRenderHint(QPainter::Antialiasing);
}
-static QSize viewItemTextSize ( const QStyleOptionViewItemV4 *option )
+static QSize viewItemTextSize(const QStyleOptionViewItemV4 *option)
{
QStyle *style = option->widget ? option->widget->style() : QApplication::style();
QTextOption textOption;
- textOption.setWrapMode ( QTextOption::WrapAtWordBoundaryOrAnywhere );
+ textOption.setWrapMode(QTextOption::WrapAtWordBoundaryOrAnywhere);
QTextLayout textLayout;
- textLayout.setTextOption ( textOption );
- textLayout.setFont ( option->font );
- textLayout.setText ( option->text );
- const int textMargin = style->pixelMetric ( QStyle::PM_FocusFrameHMargin, option, option->widget ) + 1;
- QRect bounds ( 0,0,100 - 2*textMargin,600 );
+ textLayout.setTextOption(textOption);
+ textLayout.setFont(option->font);
+ textLayout.setText(option->text);
+ const int textMargin =
+ style->pixelMetric(QStyle::PM_FocusFrameHMargin, option, option->widget) + 1;
+ QRect bounds(0, 0, 100 - 2 * textMargin, 600);
qreal height = 0, widthUsed = 0;
- viewItemTextLayout ( textLayout, bounds.width(), height, widthUsed );
- const QSize size ( qCeil ( widthUsed ), qCeil ( height ) );
- return QSize ( size.width() + 2 * textMargin, size.height() );
+ viewItemTextLayout(textLayout, bounds.width(), height, widthUsed);
+ const QSize size(qCeil(widthUsed), qCeil(height));
+ return QSize(size.width() + 2 * textMargin, size.height());
}
-void ListViewDelegate::paint ( QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index ) const
+void ListViewDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option,
+ const QModelIndex &index) const
{
QStyleOptionViewItemV4 opt = option;
- initStyleOption ( &opt, index );
+ initStyleOption(&opt, index);
painter->save();
- painter->setClipRect ( opt.rect );
+ painter->setClipRect(opt.rect);
opt.features |= QStyleOptionViewItem::WrapText;
opt.text = index.data().toString();
@@ -115,26 +118,27 @@ void ListViewDelegate::paint ( QPainter* painter, const QStyleOptionViewItem& op
QStyle *style = opt.widget ? opt.widget->style() : QApplication::style();
- //const int iconSize = style->pixelMetric(QStyle::PM_IconViewIconSize);
+ // const int iconSize = style->pixelMetric(QStyle::PM_IconViewIconSize);
const int iconSize = 48;
QRect iconbox = opt.rect;
- const int textMargin = style->pixelMetric ( QStyle::PM_FocusFrameHMargin, 0, opt.widget ) + 1;
+ const int textMargin = style->pixelMetric(QStyle::PM_FocusFrameHMargin, 0, opt.widget) + 1;
QRect textRect = opt.rect;
QRect textHighlightRect = textRect;
// clip the decoration on top, remove width padding
- textRect.adjust ( textMargin,iconSize + textMargin + 5,-textMargin,0 );
-
- textHighlightRect.adjust ( 0,iconSize + 5,0,0 );
+ textRect.adjust(textMargin, iconSize + textMargin + 5, -textMargin, 0);
+
+ textHighlightRect.adjust(0, iconSize + 5, 0, 0);
// draw background
{
- QSize textSize = viewItemTextSize ( &opt );
+ // FIXME: unused
+ // QSize textSize = viewItemTextSize ( &opt );
QPalette::ColorGroup cg;
QStyleOptionViewItemV4 opt2(opt);
-
- if((opt.widget && opt.widget->isEnabled()) || (opt.state & QStyle::State_Enabled))
+
+ if ((opt.widget && opt.widget->isEnabled()) || (opt.state & QStyle::State_Enabled))
{
- if(! ( opt.state & QStyle::State_Active ))
+ if (!(opt.state & QStyle::State_Active))
cg = QPalette::Inactive;
else
cg = QPalette::Normal;
@@ -144,31 +148,33 @@ void ListViewDelegate::paint ( QPainter* painter, const QStyleOptionViewItem& op
cg = QPalette::Disabled;
}
opt2.palette.setCurrentColorGroup(cg);
-
+
// fill in background, if any
- if ( opt.backgroundBrush.style() != Qt::NoBrush )
+ if (opt.backgroundBrush.style() != Qt::NoBrush)
{
QPointF oldBO = painter->brushOrigin();
- painter->setBrushOrigin ( opt.rect.topLeft() );
- painter->fillRect ( opt.rect, opt.backgroundBrush );
- painter->setBrushOrigin ( oldBO );
+ painter->setBrushOrigin(opt.rect.topLeft());
+ painter->fillRect(opt.rect, opt.backgroundBrush);
+ painter->setBrushOrigin(oldBO);
}
-
- if ( opt.showDecorationSelected )
+
+ if (opt.showDecorationSelected)
{
- drawSelectionRect(painter,opt2, opt.rect);
- drawFocusRect(painter,opt2, opt.rect);
- //painter->fillRect ( opt.rect, opt.palette.brush ( cg, QPalette::Highlight ) );
+ drawSelectionRect(painter, opt2, opt.rect);
+ drawFocusRect(painter, opt2, opt.rect);
+ // painter->fillRect ( opt.rect, opt.palette.brush ( cg, QPalette::Highlight ) );
}
else
{
-
- //if ( opt.state & QStyle::State_Selected )
+
+ // if ( opt.state & QStyle::State_Selected )
{
- //QRect textRect = subElementRect ( QStyle::SE_ItemViewItemText, opt, opt.widget );
- //painter->fillRect ( textHighlightRect, opt.palette.brush ( cg, QPalette::Highlight ) );
- drawSelectionRect(painter,opt2, textHighlightRect);
- drawFocusRect(painter,opt2, textHighlightRect);
+ // QRect textRect = subElementRect ( QStyle::SE_ItemViewItemText, opt,
+ // opt.widget );
+ // painter->fillRect ( textHighlightRect, opt.palette.brush ( cg,
+ // QPalette::Highlight ) );
+ drawSelectionRect(painter, opt2, textHighlightRect);
+ drawFocusRect(painter, opt2, textHighlightRect);
}
}
}
@@ -176,71 +182,73 @@ void ListViewDelegate::paint ( QPainter* painter, const QStyleOptionViewItem& op
// draw the icon
{
QIcon::Mode mode = QIcon::Normal;
- if ( ! ( opt.state & QStyle::State_Enabled ) )
+ if (!(opt.state & QStyle::State_Enabled))
mode = QIcon::Disabled;
- else if ( opt.state & QStyle::State_Selected )
+ else if (opt.state & QStyle::State_Selected)
mode = QIcon::Selected;
QIcon::State state = opt.state & QStyle::State_Open ? QIcon::On : QIcon::Off;
- iconbox.setHeight ( iconSize );
- opt.icon.paint ( painter, iconbox, Qt::AlignCenter, mode, state );
+ iconbox.setHeight(iconSize);
+ opt.icon.paint(painter, iconbox, Qt::AlignCenter, mode, state);
}
// set the text colors
- QPalette::ColorGroup cg = opt.state & QStyle::State_Enabled ? QPalette::Normal : QPalette::Disabled;
- if ( cg == QPalette::Normal && ! ( opt.state & QStyle::State_Active ) )
+ QPalette::ColorGroup cg =
+ opt.state & QStyle::State_Enabled ? QPalette::Normal : QPalette::Disabled;
+ if (cg == QPalette::Normal && !(opt.state & QStyle::State_Active))
cg = QPalette::Inactive;
- if ( opt.state & QStyle::State_Selected )
+ if (opt.state & QStyle::State_Selected)
{
- painter->setPen ( opt.palette.color ( cg, QPalette::HighlightedText ) );
+ painter->setPen(opt.palette.color(cg, QPalette::HighlightedText));
}
else
{
- painter->setPen ( opt.palette.color ( cg, QPalette::Text ) );
+ painter->setPen(opt.palette.color(cg, QPalette::Text));
}
// draw the text
QTextOption textOption;
- textOption.setWrapMode ( QTextOption::WrapAtWordBoundaryOrAnywhere );
- textOption.setTextDirection ( opt.direction );
- textOption.setAlignment ( QStyle::visualAlignment ( opt.direction, opt.displayAlignment ) );
+ textOption.setWrapMode(QTextOption::WrapAtWordBoundaryOrAnywhere);
+ textOption.setTextDirection(opt.direction);
+ textOption.setAlignment(QStyle::visualAlignment(opt.direction, opt.displayAlignment));
QTextLayout textLayout;
- textLayout.setTextOption ( textOption );
- textLayout.setFont ( opt.font );
- textLayout.setText ( opt.text );
+ textLayout.setTextOption(textOption);
+ textLayout.setFont(opt.font);
+ textLayout.setText(opt.text);
qreal width, height;
- viewItemTextLayout ( textLayout, textRect.width(), height, width );
+ viewItemTextLayout(textLayout, textRect.width(), height, width);
const int lineCount = textLayout.lineCount();
- const QRect layoutRect = QStyle::alignedRect ( opt.direction, opt.displayAlignment, QSize ( textRect.width(), int ( height ) ), textRect );
+ const QRect layoutRect = QStyle::alignedRect(
+ opt.direction, opt.displayAlignment, QSize(textRect.width(), int(height)), textRect);
const QPointF position = layoutRect.topLeft();
- for ( int i = 0; i < lineCount; ++i )
+ for (int i = 0; i < lineCount; ++i)
{
- const QTextLine line = textLayout.lineAt ( i );
- line.draw ( painter, position );
+ const QTextLine line = textLayout.lineAt(i);
+ line.draw(painter, position);
}
painter->restore();
}
-
-QSize ListViewDelegate::sizeHint ( const QStyleOptionViewItem & option, const QModelIndex & index ) const
+QSize ListViewDelegate::sizeHint(const QStyleOptionViewItem &option,
+ const QModelIndex &index) const
{
QStyleOptionViewItemV4 opt = option;
- initStyleOption ( &opt, index );
+ initStyleOption(&opt, index);
opt.features |= QStyleOptionViewItem::WrapText;
opt.text = index.data().toString();
opt.textElideMode = Qt::ElideRight;
opt.displayAlignment = Qt::AlignTop | Qt::AlignHCenter;
QStyle *style = opt.widget ? opt.widget->style() : QApplication::style();
- const int textMargin = style->pixelMetric ( QStyle::PM_FocusFrameHMargin, &option, opt.widget ) + 1;
+ const int textMargin =
+ style->pixelMetric(QStyle::PM_FocusFrameHMargin, &option, opt.widget) + 1;
int height = 48 + textMargin * 2 + 5; // TODO: turn constants into variables
- QSize szz = viewItemTextSize ( &opt );
+ QSize szz = viewItemTextSize(&opt);
height += szz.height();
// FIXME: maybe the icon items could scale and keep proportions?
- QSize sz ( 100,height );
+ QSize sz(100, height);
return sz;
}
-
diff --git a/logic/BaseInstance.cpp b/logic/BaseInstance.cpp
index c38f75ef..6f8222b7 100644
--- a/logic/BaseInstance.cpp
+++ b/logic/BaseInstance.cpp
@@ -30,7 +30,7 @@
BaseInstance::BaseInstance(BaseInstancePrivate *d_in, const QString &rootDir,
SettingsObject *settings_obj, QObject *parent)
- : inst_d(d_in), QObject(parent)
+ : QObject(parent), inst_d(d_in)
{
I_D(BaseInstance);
d->m_settings = settings_obj;
diff --git a/logic/InstanceFactory.cpp b/logic/InstanceFactory.cpp
index e1f1f202..66b271d0 100644
--- a/logic/InstanceFactory.cpp
+++ b/logic/InstanceFactory.cpp
@@ -133,16 +133,12 @@ InstanceFactory::InstCreateError InstanceFactory::copyInstance(BaseInstance *&ne
{
case NoLoadError:
return NoCreateError;
- case UnknownLoadError:
- {
- rootDir.removeRecursively();
- return UnknownCreateError;
- }
case NotAnInstance:
- {
rootDir.removeRecursively();
return CantCreateDir;
+ default:
+ case UnknownLoadError:
+ rootDir.removeRecursively();
+ return UnknownCreateError;
}
- }
- ;
}
diff --git a/logic/JavaChecker.cpp b/logic/JavaChecker.cpp
index fb37245f..daad7281 100644
--- a/logic/JavaChecker.cpp
+++ b/logic/JavaChecker.cpp
@@ -8,7 +8,7 @@ JavaChecker::JavaChecker(QObject *parent) : QObject(parent)
{
}
-int JavaChecker::performCheck(QString path)
+void JavaChecker::performCheck(QString path)
{
if(QFile::exists(CHECKER_FILE))
{
diff --git a/logic/JavaChecker.h b/logic/JavaChecker.h
index 60f8b56f..34782383 100644
--- a/logic/JavaChecker.h
+++ b/logic/JavaChecker.h
@@ -17,7 +17,7 @@ class JavaChecker : public QObject
Q_OBJECT
public:
explicit JavaChecker(QObject *parent = 0);
- int performCheck(QString path);
+ void performCheck(QString path);
signals:
void checkFinished(JavaCheckResult result);
diff --git a/logic/LegacyInstance.cpp b/logic/LegacyInstance.cpp
index 6ac03e76..72b6c51a 100644
--- a/logic/LegacyInstance.cpp
+++ b/logic/LegacyInstance.cpp
@@ -274,7 +274,6 @@ bool LegacyInstance::setIntendedVersionId(QString version)
bool LegacyInstance::shouldUpdate() const
{
- I_D(LegacyInstance);
QVariant var = settings().get("ShouldUpdate");
if (!var.isValid() || var.toBool() == false)
{
diff --git a/logic/MinecraftProcess.cpp b/logic/MinecraftProcess.cpp
index e4a26054..5d99bfae 100644
--- a/logic/MinecraftProcess.cpp
+++ b/logic/MinecraftProcess.cpp
@@ -71,6 +71,26 @@ void MinecraftProcess::setWorkdir(QString path)
m_prepostlaunchprocess.setWorkingDirectory(mcDir.absolutePath());
}
+QString MinecraftProcess::censorPrivateInfo(QString in)
+{
+ if(!m_account)
+ return in;
+ else
+ {
+ QString sessionId = m_account->sessionId();
+ QString accessToken = m_account->accessToken();
+ QString clientToken = m_account->clientToken();
+ QString profileId = m_account->currentProfile()->id();
+ QString profileName = m_account->currentProfile()->name();
+ in.replace(sessionId, "<SESSION ID>");
+ in.replace(accessToken, "<ACCESS TOKEN>");
+ in.replace(clientToken, "<CLIENT TOKEN>");
+ in.replace(profileId, "<PROFILE ID>");
+ in.replace(profileName, "<PROFILE NAME>");
+ return in;
+ }
+}
+
// console window
void MinecraftProcess::on_stdErr()
{
@@ -83,8 +103,7 @@ void MinecraftProcess::on_stdErr()
for (int i = 0; i < lines.size() - 1; i++)
{
QString &line = lines[i];
- emit log(line /*.replace(username, "<Username>").replace(sessionID, "<Session ID>")*/,
- getLevel(line, MessageLevel::Error));
+ emit log(censorPrivateInfo(line), getLevel(line, MessageLevel::Error));
}
if (!complete)
m_err_leftover = lines.last();
@@ -101,8 +120,7 @@ void MinecraftProcess::on_stdOut()
for (int i = 0; i < lines.size() - 1; i++)
{
QString &line = lines[i];
- emit log(line.replace(username, "<Username>").replace(sessionID, "<Session ID>"),
- getLevel(line, MessageLevel::Message));
+ emit log(censorPrivateInfo(line), getLevel(line, MessageLevel::Message));
}
if (!complete)
m_out_leftover = lines.last();
@@ -173,8 +191,8 @@ void MinecraftProcess::launch()
emit log(QString("Minecraft folder is: '%1'").arg(workingDirectory()));
QString JavaPath = m_instance->settings().get("JavaPath").toString();
emit log(QString("Java path: '%1'").arg(JavaPath));
- emit log(QString("Arguments: '%1'").arg(
- m_args.join("' '").replace(username, "<Username>").replace(sessionID, "<Session ID>")));
+ QString allArgs = m_args.join("' '");
+ emit log(QString("Arguments: '%1'").arg(censorPrivateInfo(allArgs)));
start(JavaPath, m_args);
if (!waitForStarted())
{
diff --git a/logic/MinecraftProcess.h b/logic/MinecraftProcess.h
index e38d2f83..bd0151cc 100644
--- a/logic/MinecraftProcess.h
+++ b/logic/MinecraftProcess.h
@@ -69,10 +69,9 @@ public:
void killMinecraft();
- inline void setLogin(QString user, QString sid)
+ inline void setLogin(MojangAccountPtr account)
{
- username = user;
- sessionID = sid;
+ m_account = account;
}
signals:
@@ -104,11 +103,13 @@ signals:
void log(QString text, MessageLevel::Enum level = MessageLevel::MultiMC);
protected:
- BaseInstance *m_instance;
+ BaseInstance *m_instance = nullptr;
QStringList m_args;
QString m_err_leftover;
QString m_out_leftover;
QProcess m_prepostlaunchprocess;
+ bool killed = false;
+ MojangAccountPtr m_account;
protected
slots:
@@ -117,8 +118,7 @@ slots:
void on_stdOut();
private:
- bool killed;
+ QString censorPrivateInfo(QString in);
MessageLevel::Enum getLevel(const QString &message, MessageLevel::Enum defaultLevel);
- QString sessionID;
- QString username;
+
};
diff --git a/logic/ModList.cpp b/logic/ModList.cpp
index 8ec73955..d5235fe9 100644
--- a/logic/ModList.cpp
+++ b/logic/ModList.cpp
@@ -39,18 +39,26 @@ void ModList::startWatching()
{
is_watching = m_watcher->addPath(m_dir.absolutePath());
if (is_watching)
+ {
QLOG_INFO() << "Started watching " << m_dir.absolutePath();
+ }
else
+ {
QLOG_INFO() << "Failed to start watching " << m_dir.absolutePath();
+ }
}
void ModList::stopWatching()
{
is_watching = !m_watcher->removePath(m_dir.absolutePath());
if (!is_watching)
+ {
QLOG_INFO() << "Stopped watching " << m_dir.absolutePath();
+ }
else
+ {
QLOG_INFO() << "Failed to stop watching " << m_dir.absolutePath();
+ }
}
bool ModList::update()
@@ -64,7 +72,6 @@ bool ModList::update()
bool orderWasInvalid = false;
// first, process the ordered items (if any)
- int currentOrderIndex = 0;
QStringList listOrder = readListFile();
for (auto item : listOrder)
{
@@ -363,6 +370,7 @@ QVariant ModList::headerData(int section, Qt::Orientation orientation, int role)
case 2:
return QString("Minecraft");
}
+ return QString();
}
Qt::ItemFlags ModList::flags(const QModelIndex &index) const
diff --git a/logic/OneSixInstance.cpp b/logic/OneSixInstance.cpp
index 27713860..08b63bf9 100644
--- a/logic/OneSixInstance.cpp
+++ b/logic/OneSixInstance.cpp
@@ -235,7 +235,6 @@ void OneSixInstance::setShouldUpdate(bool val)
bool OneSixInstance::shouldUpdate() const
{
- I_D(OneSixInstance);
QVariant var = settings().get("ShouldUpdate");
if (!var.isValid() || var.toBool() == false)
{
diff --git a/logic/OneSixUpdate.cpp b/logic/OneSixUpdate.cpp
index dfb958b2..25e16328 100644
--- a/logic/OneSixUpdate.cpp
+++ b/logic/OneSixUpdate.cpp
@@ -198,7 +198,6 @@ void OneSixUpdate::jarlibStart()
auto metacache = MMC->metacache();
QList<ForgeXzDownloadPtr> ForgeLibs;
- bool already_forge_xz = false;
for (auto lib : libs)
{
if (lib->hint() == "local")
diff --git a/logic/auth/MojangAccount.cpp b/logic/auth/MojangAccount.cpp
index 4f3839bc..4a61cf19 100644
--- a/logic/auth/MojangAccount.cpp
+++ b/logic/auth/MojangAccount.cpp
@@ -23,8 +23,7 @@
#include <logger/QsLog.h>
-MojangAccount::MojangAccount(const QString& username, QObject* parent) :
- QObject(parent)
+MojangAccount::MojangAccount(const QString &username, QObject *parent) : QObject(parent)
{
// Generate a client token.
m_clientToken = QUuid::createUuid().toString();
@@ -34,9 +33,9 @@ MojangAccount::MojangAccount(const QString& username, QObject* parent) :
m_currentProfile = -1;
}
-MojangAccount::MojangAccount(const QString& username, const QString& clientToken,
- const QString& accessToken, QObject* parent) :
- QObject(parent)
+MojangAccount::MojangAccount(const QString &username, const QString &clientToken,
+ const QString &accessToken, QObject *parent)
+ : QObject(parent)
{
m_username = username;
m_clientToken = clientToken;
@@ -45,7 +44,7 @@ MojangAccount::MojangAccount(const QString& username, const QString& clientToken
m_currentProfile = -1;
}
-MojangAccount::MojangAccount(const MojangAccount& other, QObject* parent)
+MojangAccount::MojangAccount(const MojangAccount &other, QObject *parent)
{
m_username = other.username();
m_clientToken = other.clientToken();
@@ -55,7 +54,6 @@ MojangAccount::MojangAccount(const MojangAccount& other, QObject* parent)
m_currentProfile = other.m_currentProfile;
}
-
QString MojangAccount::username() const
{
return m_username;
@@ -66,18 +64,17 @@ QString MojangAccount::clientToken() const
return m_clientToken;
}
-void MojangAccount::setClientToken(const QString& clientToken)
+void MojangAccount::setClientToken(const QString &clientToken)
{
m_clientToken = clientToken;
}
-
QString MojangAccount::accessToken() const
{
return m_accessToken;
}
-void MojangAccount::setAccessToken(const QString& accessToken)
+void MojangAccount::setAccessToken(const QString &accessToken)
{
m_accessToken = accessToken;
}
@@ -92,7 +89,7 @@ const QList<AccountProfile> MojangAccount::profiles() const
return m_profiles;
}
-const AccountProfile* MojangAccount::currentProfile() const
+const AccountProfile *MojangAccount::currentProfile() const
{
if (m_currentProfile < 0)
{
@@ -105,9 +102,9 @@ const AccountProfile* MojangAccount::currentProfile() const
return &m_profiles.at(m_currentProfile);
}
-bool MojangAccount::setProfile(const QString& profileId)
+bool MojangAccount::setProfile(const QString &profileId)
{
- const QList<AccountProfile>& profiles = this->profiles();
+ const QList<AccountProfile> &profiles = this->profiles();
for (int i = 0; i < profiles.length(); i++)
{
if (profiles.at(i).id() == profileId)
@@ -119,14 +116,14 @@ bool MojangAccount::setProfile(const QString& profileId)
return false;
}
-void MojangAccount::loadProfiles(const ProfileList& profiles)
+void MojangAccount::loadProfiles(const ProfileList &profiles)
{
m_profiles.clear();
for (auto profile : profiles)
m_profiles.append(profile);
}
-MojangAccountPtr MojangAccount::loadFromJson(const QJsonObject& object)
+MojangAccountPtr MojangAccount::loadFromJson(const QJsonObject &object)
{
// The JSON object must at least have a username for it to be valid.
if (!object.value("username").isString())
@@ -134,7 +131,7 @@ MojangAccountPtr MojangAccount::loadFromJson(const QJsonObject& object)
QLOG_ERROR() << "Can't load Mojang account info from JSON object. Username field is missing or of the wrong type.";
return nullptr;
}
-
+
QString username = object.value("username").toString("");
QString clientToken = object.value("clientToken").toString("");
QString accessToken = object.value("accessToken").toString("");
@@ -201,7 +198,7 @@ AccountProfile::AccountProfile(const QString& id, const QString& name)
m_name = name;
}
-AccountProfile::AccountProfile(const AccountProfile& other)
+AccountProfile::AccountProfile(const AccountProfile &other)
{
m_id = other.m_id;
m_name = other.m_name;
@@ -217,4 +214,7 @@ QString AccountProfile::name() const
return m_name;
}
-
+void MojangAccount::propagateChange()
+{
+ emit changed();
+}
diff --git a/logic/auth/MojangAccount.h b/logic/auth/MojangAccount.h
index 062b8aa2..25a85790 100644
--- a/logic/auth/MojangAccount.h
+++ b/logic/auth/MojangAccount.h
@@ -19,6 +19,7 @@
#include <QString>
#include <QList>
#include <QJsonObject>
+#include <QPair>
#include <memory>
@@ -27,7 +28,6 @@ class MojangAccount;
typedef std::shared_ptr<MojangAccount> MojangAccountPtr;
Q_DECLARE_METATYPE(MojangAccountPtr)
-
/**
* Class that represents a profile within someone's Mojang account.
*
@@ -38,56 +38,69 @@ Q_DECLARE_METATYPE(MojangAccountPtr)
class AccountProfile
{
public:
- AccountProfile(const QString& id, const QString& name);
- AccountProfile(const AccountProfile& other);
+ AccountProfile(const QString &id, const QString &name);
+ AccountProfile(const AccountProfile &other);
QString id() const;
QString name() const;
+
protected:
QString m_id;
QString m_name;
};
-
typedef QList<AccountProfile> ProfileList;
+struct User
+{
+ QString id;
+ // pair of key:value
+ // we don't know if the keys:value mapping is 1:1, so a list is used.
+ QList<QPair<QString, QString>> properties;
+};
/**
* Object that stores information about a certain Mojang account.
*
- * Said information may include things such as that account's username, client token, and access
+ * Said information may include things such as that account's username, client token, and access
* token if the user chose to stay logged in.
*/
class MojangAccount : public QObject
{
-Q_OBJECT
+ Q_OBJECT
public:
/**
* Constructs a new MojangAccount with the given username.
* The client token will be generated automatically and the access token will be blank.
*/
- explicit MojangAccount(const QString& username, QObject* parent = 0);
+ explicit MojangAccount(const QString &username, QObject *parent = 0);
/**
* Constructs a new MojangAccount with the given username, client token, and access token.
*/
- explicit MojangAccount(const QString& username, const QString& clientToken, const QString& accessToken, QObject* parent = 0);
+ explicit MojangAccount(const QString &username, const QString &clientToken,
+ const QString &accessToken, QObject *parent = 0);
/**
* Constructs a new MojangAccount matching the given account.
*/
- MojangAccount(const MojangAccount& other, QObject* parent);
+ MojangAccount(const MojangAccount &other, QObject *parent);
/**
* Loads a MojangAccount from the given JSON object.
*/
- static MojangAccountPtr loadFromJson(const QJsonObject& json);
+ static MojangAccountPtr loadFromJson(const QJsonObject &json);
/**
* Saves a MojangAccount to a JSON object and returns it.
*/
QJsonObject saveToJson();
+ /**
+ * Update the account on disk and lists (it changed, for whatever reason)
+ * This is called by various Yggdrasil tasks.
+ */
+ void propagateChange();
/**
* This MojangAccount's username. May be an email address if the account is migrated.
@@ -103,7 +116,7 @@ public:
/**
* Sets the MojangAccount's client token to the given value.
*/
- void setClientToken(const QString& token);
+ void setClientToken(const QString &token);
/**
* This MojangAccount's access token.
@@ -114,7 +127,7 @@ public:
/**
* Changes this MojangAccount's access token to the given value.
*/
- void setAccessToken(const QString& token);
+ void setAccessToken(const QString &token);
/**
* Get full session ID
@@ -130,25 +143,31 @@ public:
* Returns a pointer to the currently selected profile.
* If no profile is selected, returns the first profile in the profile list or nullptr if there are none.
*/
- const AccountProfile* currentProfile() const;
+ const AccountProfile *currentProfile() const;
/**
* Sets the currently selected profile to the profile with the given ID string.
* If profileId is not in the list of available profiles, the function will simply return false.
*/
- bool setProfile(const QString& profileId);
+ bool setProfile(const QString &profileId);
/**
* Clears the current account profile list and replaces it with the given profile list.
*/
- void loadProfiles(const ProfileList& profiles);
+ void loadProfiles(const ProfileList &profiles);
+signals:
+ /**
+ * This isgnal is emitted whrn the account changes
+ */
+ void changed();
protected:
QString m_username;
QString m_clientToken;
- QString m_accessToken; // Blank if not logged in.
- int m_currentProfile; // Index of the selected profile within the list of available profiles. -1 if nothing is selected.
+ QString m_accessToken; // Blank if not logged in.
+ int m_currentProfile; // Index of the selected profile within the list of available
+ // profiles. -1 if nothing is selected.
ProfileList m_profiles; // List of available profiles.
+ User m_user; // the user structure, whatever it is.
};
-
diff --git a/logic/auth/YggdrasilTask.cpp b/logic/auth/YggdrasilTask.cpp
index 31c8fbab..797e84cd 100644
--- a/logic/auth/YggdrasilTask.cpp
+++ b/logic/auth/YggdrasilTask.cpp
@@ -25,13 +25,12 @@
#include <MultiMC.h>
#include <logic/auth/MojangAccount.h>
-YggdrasilTask::YggdrasilTask(MojangAccountPtr account, QObject* parent) : Task(parent)
+YggdrasilTask::YggdrasilTask(MojangAccountPtr account, QObject *parent) : Task(parent)
{
m_error = nullptr;
m_account = account;
}
-
YggdrasilTask::~YggdrasilTask()
{
if (m_error)
@@ -46,17 +45,18 @@ void YggdrasilTask::executeTask()
QJsonDocument doc(getRequestContent());
auto worker = MMC->qnam();
- connect(worker.get(), SIGNAL(finished(QNetworkReply*)), this,
- SLOT(processReply(QNetworkReply*)));
+ connect(worker.get(), SIGNAL(finished(QNetworkReply *)), this,
+ SLOT(processReply(QNetworkReply *)));
QUrl reqUrl("https://authserver.mojang.com/" + getEndpoint());
QNetworkRequest netRequest(reqUrl);
netRequest.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
-
- m_netReply = worker->post(netRequest, doc.toJson());
+
+ QByteArray requestData = doc.toJson();
+ m_netReply = worker->post(netRequest, requestData);
}
-void YggdrasilTask::processReply(QNetworkReply* reply)
+void YggdrasilTask::processReply(QNetworkReply *reply)
{
setStatus(getStateMessage(STATE_PROCESSING_RESPONSE));
@@ -76,7 +76,6 @@ void YggdrasilTask::processReply(QNetworkReply* reply)
QJsonParseError jsonError;
QByteArray replyData = reply->readAll();
QJsonDocument doc = QJsonDocument::fromJson(replyData, &jsonError);
-
// Check the response code.
int responseCode = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
@@ -85,15 +84,16 @@ void YggdrasilTask::processReply(QNetworkReply* reply)
// If the response code was 200, then there shouldn't be an error. Make sure anyways.
// Also, sometimes an empty reply indicates success. If there was no data received,
// pass an empty json object to the processResponse function.
- if (jsonError.error == QJsonParseError::NoError || replyData.size() == 0)
+ if (jsonError.error == QJsonParseError::NoError || replyData.size() == 0)
{
if (!processResponse(replyData.size() > 0 ? doc.object() : QJsonObject()))
{
- YggdrasilTask::Error* err = getError();
+ YggdrasilTask::Error *err = getError();
if (err)
emitFailed(err->getErrorMessage());
else
- emitFailed(tr("An unknown error occurred when processing the response from the authentication server."));
+ emitFailed(tr("An unknown error occurred when processing the response "
+ "from the authentication server."));
}
else
{
@@ -166,4 +166,3 @@ MojangAccountPtr YggdrasilTask::getMojangAccount() const
{
return this->m_account;
}
-
diff --git a/logic/auth/YggdrasilTask.h b/logic/auth/YggdrasilTask.h
index 5a433aeb..62638c9d 100644
--- a/logic/auth/YggdrasilTask.h
+++ b/logic/auth/YggdrasilTask.h
@@ -24,15 +24,14 @@
class QNetworkReply;
-
/**
* A Yggdrasil task is a task that performs an operation on a given mojang account.
*/
class YggdrasilTask : public Task
{
-Q_OBJECT
+ Q_OBJECT
public:
- explicit YggdrasilTask(MojangAccountPtr account, QObject* parent=0);
+ explicit YggdrasilTask(MojangAccountPtr account, QObject *parent = 0);
~YggdrasilTask();
/**
@@ -49,7 +48,10 @@ public:
QString getCause() const { return m_cause; }
/// Gets the string to display in the GUI for describing this error.
- QString getDisplayMessage() { return getErrorMessage(); }
+ QString getDisplayMessage()
+ {
+ return getErrorMessage();
+ }
protected:
QString m_shortError;
@@ -66,7 +68,7 @@ public:
* Returns a pointer to a YggdrasilTask::Error object if an error has occurred.
* If no error has occurred, returns a null pointer.
*/
- virtual Error* getError() const;
+ virtual Error *getError() const;
protected:
/**
@@ -120,11 +122,11 @@ protected:
MojangAccountPtr m_account;
- QNetworkReply* m_netReply;
+ QNetworkReply *m_netReply;
- Error* m_error;
+ Error *m_error;
-protected slots:
- void processReply(QNetworkReply* reply);
+protected
+slots:
+ void processReply(QNetworkReply *reply);
};
-
diff --git a/logic/auth/AuthenticateTask.cpp b/logic/auth/flows/AuthenticateTask.cpp
index bf7a54f9..ec2004d6 100644
--- a/logic/auth/AuthenticateTask.cpp
+++ b/logic/auth/flows/AuthenticateTask.cpp
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-#include <logic/auth/AuthenticateTask.h>
+#include <logic/auth/flows/AuthenticateTask.h>
#include <logic/auth/MojangAccount.h>
@@ -26,8 +26,9 @@
#include "logger/QsLog.h"
-AuthenticateTask::AuthenticateTask(MojangAccountPtr account, const QString& password, QObject* parent) :
- YggdrasilTask(account, parent), m_password(password)
+AuthenticateTask::AuthenticateTask(MojangAccountPtr account, const QString &password,
+ QObject *parent)
+ : YggdrasilTask(account, parent), m_password(password)
{
}
@@ -37,20 +38,22 @@ QJsonObject AuthenticateTask::getRequestContent() const
* {
* "agent": { // optional
* "name": "Minecraft", // So far this is the only encountered value
- * "version": 1 // This number might be increased
+ * "version": 1 // This number might be increased
* // by the vanilla client in the future
* },
* "username": "mojang account name", // Can be an email address or player name for
// unmigrated accounts
* "password": "mojang account password",
* "clientToken": "client identifier" // optional
+ * "requestUser": true/false // request the user structure
* }
*/
QJsonObject req;
{
QJsonObject agent;
- // C++ makes string literals void* for some stupid reason, so we have to tell it QString... Thanks Obama.
+ // C++ makes string literals void* for some stupid reason, so we have to tell it
+ // QString... Thanks Obama.
agent.insert("name", QString("Minecraft"));
agent.insert("version", 1);
req.insert("agent", agent);
@@ -58,6 +61,7 @@ QJsonObject AuthenticateTask::getRequestContent() const
req.insert("username", getMojangAccount()->username());
req.insert("password", m_password);
+ req.insert("requestUser", true);
// If we already have a client token, give it to the server.
// Otherwise, let the server give us one.
@@ -69,10 +73,12 @@ QJsonObject AuthenticateTask::getRequestContent() const
bool AuthenticateTask::processResponse(QJsonObject responseData)
{
- // Read the response data. We need to get the client token, access token, and the selected profile.
+ // Read the response data. We need to get the client token, access token, and the selected
+ // profile.
QLOG_DEBUG() << "Processing authentication response.";
-
- // If we already have a client token, make sure the one the server gave us matches our existing one.
+
+ // If we already have a client token, make sure the one the server gave us matches our
+ // existing one.
QLOG_DEBUG() << "Getting client token.";
QString clientToken = responseData.value("clientToken").toString("");
if (clientToken.isEmpty())
@@ -82,16 +88,17 @@ bool AuthenticateTask::processResponse(QJsonObject responseData)
QLOG_ERROR() << "Server didn't send a client token.";
return false;
}
- if (!getMojangAccount()->clientToken().isEmpty() && clientToken != getMojangAccount()->clientToken())
+ if (!getMojangAccount()->clientToken().isEmpty() &&
+ clientToken != getMojangAccount()->clientToken())
{
- // The server changed our client token! Obey its wishes, but complain. That's what I do for my parents, so...
- QLOG_WARN() << "Server changed our client token to '" << clientToken
+ // The server changed our client token! Obey its wishes, but complain. That's what I do
+ // for my parents, so...
+ QLOG_WARN() << "Server changed our client token to '" << clientToken
<< "'. This shouldn't happen, but it isn't really a big deal.";
}
// Set the client token.
getMojangAccount()->setClientToken(clientToken);
-
// Now, we set the access token.
QLOG_DEBUG() << "Getting access token.";
QString accessToken = responseData.value("accessToken").toString("");
@@ -104,10 +111,9 @@ bool AuthenticateTask::processResponse(QJsonObject responseData)
// Set the access token.
getMojangAccount()->setAccessToken(accessToken);
-
// Now we load the list of available profiles.
- // Mojang hasn't yet implemented the profile system,
- // but we might as well support what's there so we
+ // Mojang hasn't yet implemented the profile system,
+ // but we might as well support what's there so we
// don't have trouble implementing it later.
QLOG_DEBUG() << "Loading profile list.";
QJsonArray availableProfiles = responseData.value("availableProfiles").toArray();
@@ -121,10 +127,11 @@ bool AuthenticateTask::processResponse(QJsonObject responseData)
if (id.isEmpty() || name.isEmpty())
{
- // This should never happen, but we might as well
+ // This should never happen, but we might as well
// warn about it if it does so we can debug it easily.
// You never know when Mojang might do something truly derpy.
- QLOG_WARN() << "Found entry in available profiles list with missing ID or name field. Ignoring it.";
+ QLOG_WARN() << "Found entry in available profiles list with missing ID or name "
+ "field. Ignoring it.";
}
// Now, add a new AccountProfile entry to the list.
@@ -133,10 +140,8 @@ bool AuthenticateTask::processResponse(QJsonObject responseData)
// Put the list of profiles we loaded into the MojangAccount object.
getMojangAccount()->loadProfiles(loadedProfiles);
-
-
// Finally, we set the current profile to the correct value. This is pretty simple.
- // We do need to make sure that the current profile that the server gave us
+ // We do need to make sure that the current profile that the server gave us
// is actually in the available profiles list.
// If it isn't, we'll just fail horribly (*shouldn't* ever happen, but you never know).
QLOG_DEBUG() << "Setting current profile.";
@@ -151,51 +156,23 @@ bool AuthenticateTask::processResponse(QJsonObject responseData)
if (!getMojangAccount()->setProfile(currentProfileId))
{
// TODO: Set an error to display to the user.
- QLOG_ERROR() << "Server specified a selected profile that wasn't in the available profiles list.";
+ QLOG_ERROR() << "Server specified a selected profile that wasn't in the available "
+ "profiles list.";
return false;
}
- /*
-public class User
-{
- private String id;
- private List<Property> properties;
-
- public String getId()
- {
- return this.id;
- }
-
- public List<Property> getProperties() {
- return this.properties;
- }
- public class Property {
- private String name;
- private String value;
-
- public Property() { }
- public String getKey() { return this.name; }
-
- public String getValue()
- {
- return this.value;
- }
- }
-}
-*/
-
// this is what the vanilla launcher passes to the userProperties launch param
// doesn't seem to be used for anything so far? I don't get any of this data on my account
// (peterixxx)
// is it a good idea to log this?
- if(responseData.contains("user"))
+ if (responseData.contains("user"))
{
auto obj = responseData.value("user").toObject();
auto userId = obj.value("id").toString();
auto propArray = obj.value("properties").toArray();
QLOG_DEBUG() << "User ID: " << userId;
QLOG_DEBUG() << "User Properties: ";
- for(auto prop: propArray)
+ for (auto prop : propArray)
{
auto propTuple = prop.toObject();
auto name = propTuple.value("name").toString();
@@ -203,8 +180,9 @@ public class User
QLOG_DEBUG() << name << " : " << value;
}
}
-
- // We've made it through the minefield of possible errors. Return true to indicate that we've succeeded.
+
+ // We've made it through the minefield of possible errors. Return true to indicate that
+ // we've succeeded.
QLOG_DEBUG() << "Finished reading authentication response.";
return true;
}
@@ -226,5 +204,3 @@ QString AuthenticateTask::getStateMessage(const YggdrasilTask::State state) cons
return YggdrasilTask::getStateMessage(state);
}
}
-
-
diff --git a/logic/auth/AuthenticateTask.h b/logic/auth/flows/AuthenticateTask.h
index 54a6b79a..3b99caad 100644
--- a/logic/auth/AuthenticateTask.h
+++ b/logic/auth/flows/AuthenticateTask.h
@@ -22,25 +22,25 @@
#include <QJsonObject>
/**
- * The authenticate task takes a MojangAccount with no access token and password and attempts to authenticate with Mojang's servers.
+ * The authenticate task takes a MojangAccount with no access token and password and attempts to
+ * authenticate with Mojang's servers.
* If successful, it will set the MojangAccount's access token.
*/
class AuthenticateTask : public YggdrasilTask
{
-Q_OBJECT
+ Q_OBJECT
public:
- AuthenticateTask(MojangAccountPtr account, const QString& password, QObject* parent=0);
+ AuthenticateTask(MojangAccountPtr account, const QString &password, QObject *parent = 0);
protected:
virtual QJsonObject getRequestContent() const;
-
+
virtual QString getEndpoint() const;
virtual bool processResponse(QJsonObject responseData);
-
+
QString getStateMessage(const YggdrasilTask::State state) const;
private:
QString m_password;
};
-
diff --git a/logic/auth/flows/InvalidateTask.cpp b/logic/auth/flows/InvalidateTask.cpp
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/logic/auth/flows/InvalidateTask.cpp
diff --git a/logic/auth/flows/InvalidateTask.h b/logic/auth/flows/InvalidateTask.h
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/logic/auth/flows/InvalidateTask.h
diff --git a/logic/auth/flows/RefreshTask.cpp b/logic/auth/flows/RefreshTask.cpp
new file mode 100644
index 00000000..b56ed9bc
--- /dev/null
+++ b/logic/auth/flows/RefreshTask.cpp
@@ -0,0 +1,156 @@
+/* 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 <logic/auth/flows/RefreshTask.h>
+
+#include <logic/auth/MojangAccount.h>
+
+#include <QJsonDocument>
+#include <QJsonObject>
+#include <QJsonArray>
+#include <QVariant>
+#include <QDebug>
+
+#include "logger/QsLog.h"
+
+RefreshTask::RefreshTask(MojangAccountPtr account, QObject *parent)
+ : YggdrasilTask(account, parent)
+{
+}
+
+QJsonObject RefreshTask::getRequestContent() const
+{
+ /*
+ * {
+ * "clientToken": "client identifier"
+ * "accessToken": "current access token to be refreshed"
+ * "selectedProfile": // specifying this causes errors
+ * {
+ * "id": "profile ID"
+ * "name": "profile name"
+ * }
+ * "requestUser": true/false // request the user structure
+ * }
+ */
+ auto account = getMojangAccount();
+ QJsonObject req;
+ req.insert("clientToken", account->clientToken());
+ req.insert("accessToken", account->accessToken());
+ /*
+ {
+ auto currentProfile = account->currentProfile();
+ QJsonObject profile;
+ profile.insert("id", currentProfile->id());
+ profile.insert("name", currentProfile->name());
+ req.insert("selectedProfile", profile);
+ }
+ */
+ req.insert("requestUser", true);
+
+ return req;
+}
+
+bool RefreshTask::processResponse(QJsonObject responseData)
+{
+ auto account = getMojangAccount();
+
+ // Read the response data. We need to get the client token, access token, and the selected
+ // profile.
+ QLOG_DEBUG() << "Processing authentication response.";
+
+ // If we already have a client token, make sure the one the server gave us matches our
+ // existing one.
+ QString clientToken = responseData.value("clientToken").toString("");
+ if (clientToken.isEmpty())
+ {
+ // Fail if the server gave us an empty client token
+ // TODO: Set an error properly to display to the user.
+ QLOG_ERROR() << "Server didn't send a client token.";
+ return false;
+ }
+ if (!account->clientToken().isEmpty() && clientToken != account->clientToken())
+ {
+ // The server changed our client token! Obey its wishes, but complain. That's what I do
+ // for my parents, so...
+ QLOG_ERROR() << "Server changed our client token to '" << clientToken
+ << "'. This shouldn't happen, but it isn't really a big deal.";
+ return false;
+ }
+
+ // Now, we set the access token.
+ QLOG_DEBUG() << "Getting new access token.";
+ QString accessToken = responseData.value("accessToken").toString("");
+ if (accessToken.isEmpty())
+ {
+ // Fail if the server didn't give us an access token.
+ // TODO: Set an error properly to display to the user.
+ QLOG_ERROR() << "Server didn't send an access token.";
+ return false;
+ }
+
+ // we validate that the server responded right. (our current profile = returned current
+ // profile)
+ QJsonObject currentProfile = responseData.value("selectedProfile").toObject();
+ QString currentProfileId = currentProfile.value("id").toString("");
+ if (account->currentProfile()->id() != currentProfileId)
+ {
+ // TODO: Set an error to display to the user.
+ QLOG_ERROR() << "Server didn't specify the same selected profile as ours.";
+ return false;
+ }
+
+ // this is what the vanilla launcher passes to the userProperties launch param
+ if (responseData.contains("user"))
+ {
+ auto obj = responseData.value("user").toObject();
+ auto userId = obj.value("id").toString();
+ auto propArray = obj.value("properties").toArray();
+ QLOG_DEBUG() << "User ID: " << userId;
+ QLOG_DEBUG() << "User Properties: ";
+ for (auto prop : propArray)
+ {
+ auto propTuple = prop.toObject();
+ auto name = propTuple.value("name").toString();
+ auto value = propTuple.value("value").toString();
+ QLOG_DEBUG() << name << " : " << value;
+ }
+ }
+
+ // We've made it through the minefield of possible errors. Return true to indicate that
+ // we've succeeded.
+ QLOG_DEBUG() << "Finished reading refresh response.";
+ // Reset the access token.
+ account->setAccessToken(accessToken);
+ account->propagateChange();
+ return true;
+}
+
+QString RefreshTask::getEndpoint() const
+{
+ return "refresh";
+}
+
+QString RefreshTask::getStateMessage(const YggdrasilTask::State state) const
+{
+ switch (state)
+ {
+ case STATE_SENDING_REQUEST:
+ return tr("Refreshing: Sending request.");
+ case STATE_PROCESSING_RESPONSE:
+ return tr("Refreshing: Processing response.");
+ default:
+ return YggdrasilTask::getStateMessage(state);
+ }
+}
diff --git a/logic/auth/flows/RefreshTask.h b/logic/auth/flows/RefreshTask.h
new file mode 100644
index 00000000..2596f6c7
--- /dev/null
+++ b/logic/auth/flows/RefreshTask.h
@@ -0,0 +1,43 @@
+/* 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 <logic/auth/YggdrasilTask.h>
+
+#include <QObject>
+#include <QString>
+#include <QJsonObject>
+
+/**
+ * The authenticate task takes a MojangAccount with a possibly timed-out access token
+ * and attempts to authenticate with Mojang's servers.
+ * If successful, it will set the new access token. The token is considered validated.
+ */
+class RefreshTask : public YggdrasilTask
+{
+ Q_OBJECT
+public:
+ RefreshTask(MojangAccountPtr account, QObject *parent = 0);
+
+protected:
+ virtual QJsonObject getRequestContent() const;
+
+ virtual QString getEndpoint() const;
+
+ virtual bool processResponse(QJsonObject responseData);
+
+ QString getStateMessage(const YggdrasilTask::State state) const;
+};
diff --git a/logic/auth/ValidateTask.cpp b/logic/auth/flows/ValidateTask.cpp
index 994d24e4..d9e0e46b 100644
--- a/logic/auth/ValidateTask.cpp
+++ b/logic/auth/flows/ValidateTask.cpp
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-#include <logic/auth/ValidateTask.h>
+#include <logic/auth/flows/ValidateTask.h>
#include <logic/auth/MojangAccount.h>
@@ -26,8 +26,8 @@
#include "logger/QsLog.h"
-ValidateTask::ValidateTask(MojangAccountPtr account, QObject* parent) :
- YggdrasilTask(account, parent)
+ValidateTask::ValidateTask(MojangAccountPtr account, QObject *parent)
+ : YggdrasilTask(account, parent)
{
}
@@ -62,5 +62,3 @@ QString ValidateTask::getStateMessage(const YggdrasilTask::State state) const
return YggdrasilTask::getStateMessage(state);
}
}
-
-
diff --git a/logic/auth/ValidateTask.h b/logic/auth/flows/ValidateTask.h
index 5bbc69c7..3ff78c6a 100644
--- a/logic/auth/ValidateTask.h
+++ b/logic/auth/flows/ValidateTask.h
@@ -26,19 +26,18 @@
*/
class ValidateTask : public YggdrasilTask
{
-Q_OBJECT
+ Q_OBJECT
public:
- ValidateTask(MojangAccountPtr account, QObject* parent=0);
+ ValidateTask(MojangAccountPtr account, QObject *parent = 0);
protected:
virtual QJsonObject getRequestContent() const;
-
+
virtual QString getEndpoint() const;
virtual bool processResponse(QJsonObject responseData);
-
+
QString getStateMessage(const YggdrasilTask::State state) const;
private:
};
-
diff --git a/logic/lists/InstanceList.cpp b/logic/lists/InstanceList.cpp
index 7081dc6f..b9595578 100644
--- a/logic/lists/InstanceList.cpp
+++ b/logic/lists/InstanceList.cpp
@@ -281,14 +281,6 @@ InstanceList::InstListError InstanceList::loadList()
auto &loader = InstanceFactory::get();
auto error = loader.loadInstance(instPtr, subDir);
- switch (error)
- {
- case InstanceFactory::NoLoadError:
- break;
- case InstanceFactory::NotAnInstance:
- break;
- }
-
if (error != InstanceFactory::NoLoadError && error != InstanceFactory::NotAnInstance)
{
QString errorMsg = QString("Failed to load instance %1: ")
@@ -362,8 +354,13 @@ int InstanceList::add(InstancePtr t)
return count() - 1;
}
-InstancePtr InstanceList::getInstanceById(QString instId)
+InstancePtr InstanceList::getInstanceById(QString instId) const
{
+ if (m_instances.isEmpty())
+ {
+ return InstancePtr();
+ }
+
QListIterator<InstancePtr> iter(m_instances);
InstancePtr inst;
while (iter.hasNext())
@@ -378,7 +375,12 @@ InstancePtr InstanceList::getInstanceById(QString instId)
return iter.peekPrevious();
}
-int InstanceList::getInstIndex(BaseInstance *inst)
+QModelIndex InstanceList::getInstanceIndexById(const QString &id) const
+{
+ return index(getInstIndex(getInstanceById(id).get()));
+}
+
+int InstanceList::getInstIndex(BaseInstance *inst) const
{
for (int i = 0; i < m_instances.count(); i++)
{
diff --git a/logic/lists/InstanceList.h b/logic/lists/InstanceList.h
index d08501eb..8cd39746 100644
--- a/logic/lists/InstanceList.h
+++ b/logic/lists/InstanceList.h
@@ -91,7 +91,9 @@ public:
int add(InstancePtr t);
/// Get an instance by ID
- InstancePtr getInstanceById(QString id);
+ InstancePtr getInstanceById(QString id) const;
+
+ QModelIndex getInstanceIndexById(const QString &id) const;
signals:
void dataIsInvalid();
@@ -106,7 +108,7 @@ slots:
void groupChanged();
private:
- int getInstIndex(BaseInstance *inst);
+ int getInstIndex(BaseInstance *inst) const;
protected:
QString m_instDir;
diff --git a/logic/lists/MojangAccountList.cpp b/logic/lists/MojangAccountList.cpp
index ec1937ad..466cc934 100644
--- a/logic/lists/MojangAccountList.cpp
+++ b/logic/lists/MojangAccountList.cpp
@@ -44,7 +44,6 @@ MojangAccountPtr MojangAccountList::findAccount(const QString &username) const
return nullptr;
}
-
const MojangAccountPtr MojangAccountList::at(int i) const
{
return MojangAccountPtr(m_accounts.at(i));
@@ -53,12 +52,13 @@ const MojangAccountPtr MojangAccountList::at(int i) const
void MojangAccountList::addAccount(const MojangAccountPtr account)
{
beginResetModel();
+ connect(account.get(), SIGNAL(changed()), SLOT(accountChanged()));
m_accounts.append(account);
endResetModel();
onListChanged();
}
-void MojangAccountList::removeAccount(const QString& username)
+void MojangAccountList::removeAccount(const QString &username)
{
beginResetModel();
for (auto account : m_accounts)
@@ -81,7 +81,6 @@ void MojangAccountList::removeAccount(QModelIndex index)
onListChanged();
}
-
MojangAccountPtr MojangAccountList::activeAccount() const
{
if (m_activeAccount.isEmpty())
@@ -90,7 +89,7 @@ MojangAccountPtr MojangAccountList::activeAccount() const
return findAccount(m_activeAccount);
}
-void MojangAccountList::setActiveAccount(const QString& username)
+void MojangAccountList::setActiveAccount(const QString &username)
{
beginResetModel();
if (username.isEmpty())
@@ -109,6 +108,11 @@ void MojangAccountList::setActiveAccount(const QString& username)
onActiveChanged();
}
+void MojangAccountList::accountChanged()
+{
+ // the list changed. there is no doubt.
+ onListChanged();
+}
void MojangAccountList::onListChanged()
{
@@ -127,13 +131,11 @@ void MojangAccountList::onActiveChanged()
emit activeAccountChanged();
}
-
int MojangAccountList::count() const
{
return m_accounts.count();
}
-
QVariant MojangAccountList::data(const QModelIndex &index, int role) const
{
if (!index.isValid())
@@ -220,10 +222,11 @@ void MojangAccountList::updateListData(QList<MojangAccountPtr> versions)
endResetModel();
}
-bool MojangAccountList::loadList(const QString& filePath)
+bool MojangAccountList::loadList(const QString &filePath)
{
QString path = filePath;
- if (path.isEmpty()) path = m_listFilePath;
+ if (path.isEmpty())
+ path = m_listFilePath;
if (path.isEmpty())
{
QLOG_ERROR() << "Can't load Mojang account list. No file path given and no default set.";
@@ -231,7 +234,7 @@ bool MojangAccountList::loadList(const QString& filePath)
}
QFile file(path);
-
+
// Try to open the file and fail if we can't.
// TODO: We should probably report this error to the user.
if (!file.open(QIODevice::ReadOnly))
@@ -286,6 +289,7 @@ bool MojangAccountList::loadList(const QString& filePath)
MojangAccountPtr account = MojangAccount::loadFromJson(accountObj);
if (account.get() != nullptr)
{
+ connect(account.get(), SIGNAL(changed()), SLOT(accountChanged()));
m_accounts.append(account);
}
else
@@ -297,14 +301,15 @@ bool MojangAccountList::loadList(const QString& filePath)
// Load the active account.
m_activeAccount = root.value("activeAccount").toString("");
-
+
return true;
}
-bool MojangAccountList::saveList(const QString& filePath)
+bool MojangAccountList::saveList(const QString &filePath)
{
QString path(filePath);
- if (path.isEmpty()) path = m_listFilePath;
+ if (path.isEmpty())
+ path = m_listFilePath;
if (path.isEmpty())
{
QLOG_ERROR() << "Can't save Mojang account list. No file path given and no default set.";
@@ -337,7 +342,6 @@ bool MojangAccountList::saveList(const QString& filePath)
// Create a JSON document object to convert our JSON to bytes.
QJsonDocument doc(root);
-
// Now that we're done building the JSON object, we can write it to the file.
QLOG_DEBUG() << "Writing account list to file.";
QFile file(path);
@@ -362,6 +366,5 @@ bool MojangAccountList::saveList(const QString& filePath)
void MojangAccountList::setListFilePath(QString path, bool autosave)
{
m_listFilePath = path;
- autosave = autosave;
+ m_autosave = autosave;
}
-
diff --git a/logic/lists/MojangAccountList.h b/logic/lists/MojangAccountList.h
index 908f5a7a..744f3c51 100644
--- a/logic/lists/MojangAccountList.h
+++ b/logic/lists/MojangAccountList.h
@@ -22,7 +22,6 @@
#include "logic/auth/MojangAccount.h"
-
/*!
* \brief List of available Mojang accounts.
* This should be loaded in the background by MultiMC on startup.
@@ -44,10 +43,10 @@ public:
enum VListColumns
{
// TODO: Add icon column.
-
+
// First column - Active?
ActiveColumn = 0,
-
+
// Second column - Name
NameColumn,
};
@@ -74,7 +73,7 @@ public:
/*!
* Removes the mojang account with the given username from the account list.
*/
- virtual void removeAccount(const QString& username);
+ virtual void removeAccount(const QString &username);
/*!
* Removes the account at the given QModelIndex.
@@ -88,7 +87,7 @@ public:
* one doesn't exist.
*/
virtual MojangAccountPtr findAccount(const QString &username) const;
-
+
/*!
* Sets the default path to save the list file to.
* If autosave is true, this list will automatically save to the given path whenever it changes.
@@ -96,21 +95,21 @@ public:
* after calling this function to ensure an autosaved change doesn't overwrite the list you intended
* to load.
*/
- virtual void setListFilePath(QString path, bool autosave=false);
+ virtual void setListFilePath(QString path, bool autosave = false);
/*!
* \brief Loads the account list from the given file path.
* If the given file is an empty string (default), will load from the default account list file.
* \return True if successful, otherwise false.
*/
- virtual bool loadList(const QString& file="");
+ virtual bool loadList(const QString &file = "");
/*!
* \brief Saves the account list to the given file.
* If the given file is an empty string (default), will save from the default account list file.
* \return True if successful, otherwise false.
*/
- virtual bool saveList(const QString& file="");
+ virtual bool saveList(const QString &file = "");
/*!
* \brief Gets a pointer to the account that the user has selected as their "active" account.
@@ -124,12 +123,13 @@ public:
* Sets the given account as the current active account.
* If the username given is an empty string, sets the active account to nothing.
*/
- virtual void setActiveAccount(const QString& username);
+ virtual void setActiveAccount(const QString &username);
signals:
/*!
* Signal emitted to indicate that the account list has changed.
- * This will also fire if the value of an element in the list changes (will be implemented later).
+ * This will also fire if the value of an element in the list changes (will be implemented
+ * later).
*/
void listChanged();
@@ -138,6 +138,13 @@ signals:
*/
void activeAccountChanged();
+public
+slots:
+ /**
+ * This is called when one of the accounts changes and the list needs to be updated
+ */
+ void accountChanged();
+
protected:
/*!
* Called whenever the list changes.
@@ -166,7 +173,7 @@ protected:
* If true, the account list will automatically save to the account list path when it changes.
* Ignored if m_listFilePath is blank.
*/
- bool m_autosave;
+ bool m_autosave = false;
protected
slots:
@@ -184,4 +191,3 @@ slots:
*/
virtual void updateListData(QList<MojangAccountPtr> versions);
};
-
diff --git a/test.cpp b/test.cpp
deleted file mode 100644
index 2b015454..00000000
--- a/test.cpp
+++ /dev/null
@@ -1,60 +0,0 @@
-
-#include <iostream>
-
-#include "keyring.h"
-#include "cmdutils.h"
-
-using namespace Util::Commandline;
-
-#include <QCoreApplication>
-
-int main(int argc, char **argv)
-{
- QCoreApplication app(argc, argv);
- app.setApplicationName("MMC Keyring test");
- app.setOrganizationName("Orochimarufan");
-
- Parser p;
- p.addArgument("user", false);
- p.addArgument("password", false);
- p.addSwitch("set");
- p.addSwitch("get");
- p.addSwitch("list");
- p.addOption("service", "Test");
- p.addShortOpt("service", 's');
-
- QHash<QString, QVariant> args;
- try {
- args = p.parse(app.arguments());
- } catch (ParsingError) {
- std::cout << "Syntax error." << std::endl;
- return 1;
- }
-
- if (args["set"].toBool()) {
- if (args["user"].isNull() || args["password"].isNull()) {
- std::cout << "set operation needs bot user and password set" << std::endl;
- return 1;
- }
-
- return Keyring::instance()->storePassword(args["service"].toString(),
- args["user"].toString(), args["password"].toString());
- } else if (args["get"].toBool()) {
- if (args["user"].isNull()) {
- std::cout << "get operation needs user set" << std::endl;
- return 1;
- }
-
- std::cout << "Password: " << qPrintable(Keyring::instance()->getPassword(args["service"].toString(),
- args["user"].toString())) << std::endl;
- return 0;
- } else if (args["list"].toBool()) {
- QStringList accounts = Keyring::instance()->getStoredAccounts(args["service"].toString());
- std::cout << "stored accounts:" << std::endl << '\t' << qPrintable(accounts.join("\n\t")) << std::endl;
- return 0;
- } else {
- std::cout << "No operation given!" << std::endl;
- std::cout << qPrintable(p.compileHelp(argv[0])) << std::endl;
- return 1;
- }
-}