From b54839b8976b5c1455c838828f2bc92cdeb178eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petr=20Mr=C3=A1zek?= Date: Wed, 2 Mar 2016 03:03:44 +0100 Subject: NOISSUE eliminate timestamp strings --- logic/minecraft/MinecraftProfile.cpp | 2 -- logic/minecraft/MinecraftProfile.h | 6 ++-- logic/minecraft/MinecraftVersion.cpp | 6 ++-- logic/minecraft/MinecraftVersion.h | 6 ++-- logic/minecraft/MinecraftVersionList.cpp | 29 +++-------------- logic/minecraft/MojangVersionFormat.cpp | 14 +++----- logic/minecraft/ParseUtils.cpp | 34 ++++++++++++------- logic/minecraft/ParseUtils.h | 15 ++++----- logic/minecraft/VersionFile.cpp | 6 ++-- logic/minecraft/VersionFile.h | 6 ++-- logic/minecraft/onesix/OneSixVersionFormat.cpp | 8 ++--- tests/CMakeLists.txt | 1 + tests/tst_ParseUtils.cpp | 45 ++++++++++++++++++++++++++ 13 files changed, 97 insertions(+), 81 deletions(-) create mode 100644 tests/tst_ParseUtils.cpp diff --git a/logic/minecraft/MinecraftProfile.cpp b/logic/minecraft/MinecraftProfile.cpp index 7a84996c..be847050 100644 --- a/logic/minecraft/MinecraftProfile.cpp +++ b/logic/minecraft/MinecraftProfile.cpp @@ -60,9 +60,7 @@ void MinecraftProfile::reload() void MinecraftProfile::clear() { id.clear(); - m_updateTimeString.clear(); m_updateTime = QDateTime(); - m_releaseTimeString.clear(); m_releaseTime = QDateTime(); type.clear(); assets.clear(); diff --git a/logic/minecraft/MinecraftProfile.h b/logic/minecraft/MinecraftProfile.h index 2a97f037..25663c74 100644 --- a/logic/minecraft/MinecraftProfile.h +++ b/logic/minecraft/MinecraftProfile.h @@ -121,12 +121,10 @@ public: /* data */ /// the ID - determines which jar to use! ACTUALLY IMPORTANT! QString id; - /// the time this version was actually released by Mojang, as string and as QDateTime - QString m_releaseTimeString; + /// the time this version was actually released by Mojang QDateTime m_releaseTime; - /// the time this version was last updated by Mojang, as string and as QDateTime - QString m_updateTimeString; + /// the time this version was last updated by Mojang QDateTime m_updateTime; /// Release type - "release" or "snapshot" diff --git a/logic/minecraft/MinecraftVersion.cpp b/logic/minecraft/MinecraftVersion.cpp index 4225fa50..8a1ac501 100644 --- a/logic/minecraft/MinecraftVersion.cpp +++ b/logic/minecraft/MinecraftVersion.cpp @@ -192,14 +192,12 @@ void MinecraftVersion::applyTo(MinecraftProfile *version) { version->type = m_type; } - if (!m_releaseTimeString.isNull()) + if (!m_releaseTime.isNull()) { - version->m_releaseTimeString = m_releaseTimeString; version->m_releaseTime = m_releaseTime; } - if (!m_updateTimeString.isNull()) + if (!m_updateTime.isNull()) { - version->m_updateTimeString = m_updateTimeString; version->m_updateTime = m_updateTime; } version->traits.unite(m_traits); diff --git a/logic/minecraft/MinecraftVersion.h b/logic/minecraft/MinecraftVersion.h index 63583968..33ca2899 100644 --- a/logic/minecraft/MinecraftVersion.h +++ b/logic/minecraft/MinecraftVersion.h @@ -111,12 +111,10 @@ public: /* data */ /// The type of this release QString m_type; - /// the time this version was actually released by Mojang, as string and as QDateTime - QString m_releaseTimeString; + /// the time this version was actually released by Mojang QDateTime m_releaseTime; - /// the time this version was last updated by Mojang, as string and as QDateTime - QString m_updateTimeString; + /// the time this version was last updated by Mojang QDateTime m_updateTime; /// MD5 hash of the minecraft jar diff --git a/logic/minecraft/MinecraftVersionList.cpp b/logic/minecraft/MinecraftVersionList.cpp index 578432cb..507d8254 100644 --- a/logic/minecraft/MinecraftVersionList.cpp +++ b/logic/minecraft/MinecraftVersionList.cpp @@ -184,14 +184,7 @@ void MinecraftVersionList::loadBuiltinList() mcVersion->m_name = mcVersion->m_descriptor = versionID; // Parse the timestamp. - if (!parse_timestamp(versionObj.value("releaseTime").toString(""), - mcVersion->m_releaseTimeString, mcVersion->m_releaseTime)) - { - qCritical() << "Error while parsing version" << versionID - << ": invalid version timestamp"; - continue; - } - + mcVersion->m_releaseTime = timeFromS3Time(versionObj.value("releaseTime").toString("")); mcVersion->m_versionFileURL = QString(); mcVersion->m_versionSource = Builtin; mcVersion->m_type = versionTypeStr; @@ -270,20 +263,8 @@ void MinecraftVersionList::loadMojangList(QJsonDocument jsonDoc, VersionSource s std::shared_ptr mcVersion(new MinecraftVersion()); mcVersion->m_name = mcVersion->m_descriptor = versionID; - if (!parse_timestamp(versionObj.value("releaseTime").toString(""), - mcVersion->m_releaseTimeString, mcVersion->m_releaseTime)) - { - qCritical() << "Error while parsing version" << versionID - << ": invalid release timestamp"; - continue; - } - if (!parse_timestamp(versionObj.value("time").toString(""), - mcVersion->m_updateTimeString, mcVersion->m_updateTime)) - { - qCritical() << "Error while parsing version" << versionID - << ": invalid update timestamp"; - continue; - } + mcVersion->m_releaseTime = timeFromS3Time(versionObj.value("releaseTime").toString("")); + mcVersion->m_updateTime = timeFromS3Time(versionObj.value("time").toString("")); if (mcVersion->m_releaseTime < g_VersionFilterData.legacyCutoffDate) { @@ -593,8 +574,8 @@ void MinecraftVersionList::saveCachedList() entryObj.insert("id", mcversion->descriptor()); entryObj.insert("version", mcversion->descriptor()); - entryObj.insert("time", mcversion->m_updateTimeString); - entryObj.insert("releaseTime", mcversion->m_releaseTimeString); + entryObj.insert("time", timeToS3Time(mcversion->m_updateTime)); + entryObj.insert("releaseTime", timeToS3Time(mcversion->m_releaseTime)); entryObj.insert("url", mcversion->m_versionFileURL); entryObj.insert("type", mcversion->m_type); entriesArr.append(entryObj); diff --git a/logic/minecraft/MojangVersionFormat.cpp b/logic/minecraft/MojangVersionFormat.cpp index d1a27f9f..e28a38ab 100644 --- a/logic/minecraft/MojangVersionFormat.cpp +++ b/logic/minecraft/MojangVersionFormat.cpp @@ -45,14 +45,8 @@ VersionFilePtr MojangVersionFormat::versionFileFromJson(const QJsonDocument &doc readString(root, "assets", out->assets); - if (!parse_timestamp(root.value("releaseTime").toString(""), out->m_releaseTimeString, out->m_releaseTime)) - { - out->addProblem(PROBLEM_WARNING, QObject::tr("Invalid 'releaseTime' timestamp")); - } - if (!parse_timestamp(root.value("time").toString(""), out->m_updateTimeString, out->m_updateTime)) - { - out->addProblem(PROBLEM_WARNING, QObject::tr("Invalid 'time' timestamp")); - } + out->m_releaseTime = timeFromS3Time(root.value("releaseTime").toString("")); + out->m_updateTime = timeFromS3Time(root.value("time").toString("")); if (root.contains("minimumLauncherVersion")) { @@ -90,8 +84,8 @@ static QJsonDocument versionFileToJson(VersionFilePtr patch) writeString(root, "minecraftArguments", patch->overwriteMinecraftArguments); writeString(root, "type", patch->type); writeString(root, "assets", patch->assets); - writeString(root, "releaseTime", patch->m_releaseTimeString); - writeString(root, "time", patch->m_updateTimeString); + writeString(root, "releaseTime", timeToS3Time(patch->m_releaseTime)); + writeString(root, "time", timeToS3Time(patch->m_updateTime)); if (!patch->addLibs.isEmpty()) { diff --git a/logic/minecraft/ParseUtils.cpp b/logic/minecraft/ParseUtils.cpp index 8fccf403..473ca1de 100644 --- a/logic/minecraft/ParseUtils.cpp +++ b/logic/minecraft/ParseUtils.cpp @@ -1,23 +1,33 @@ #include #include #include "ParseUtils.h" +#include QDateTime timeFromS3Time(QString str) { return QDateTime::fromString(str, Qt::ISODate); } -bool parse_timestamp (const QString & raw, QString & save_here, QDateTime & parse_here) +QString timeToS3Time(QDateTime time) { - save_here = raw; - if (save_here.isEmpty()) - { - return false; - } - parse_here = timeFromS3Time(save_here); - if (!parse_here.isValid()) - { - return false; - } - return true; + // this all because Qt can't format timestamps right. + int offsetRaw = time.offsetFromUtc(); + bool negative = offsetRaw < 0; + int offsetAbs = std::abs(offsetRaw); + + int offsetSeconds = offsetAbs % 60; + offsetAbs -= offsetSeconds; + + int offsetMinutes = offsetAbs % 3600; + offsetAbs -= offsetMinutes; + offsetMinutes /= 60; + + int offsetHours = offsetAbs / 3600; + + QString raw = time.toString("yyyy-MM-ddTHH:mm:ss"); + raw += (negative ? QChar('-') : QChar('+')); + raw += QString("%1").arg(offsetHours, 2, 10, QChar('0')); + raw += ":"; + raw += QString("%1").arg(offsetMinutes, 2, 10, QChar('0')); + return raw; } diff --git a/logic/minecraft/ParseUtils.h b/logic/minecraft/ParseUtils.h index bd2f6ffb..2b367a10 100644 --- a/logic/minecraft/ParseUtils.h +++ b/logic/minecraft/ParseUtils.h @@ -2,13 +2,10 @@ #include #include -/** - * parse the S3 timestamp in 'raw' and fill the forwarded variables. - * return true/false for success/failure - */ -bool parse_timestamp (const QString &raw, QString &save_here, QDateTime &parse_here); +#include "multimc_logic_export.h" -/** - * take the timestamp used by S3 and turn it into QDateTime - */ -QDateTime timeFromS3Time(QString str); +/// take the timestamp used by S3 and turn it into QDateTime +MULTIMC_LOGIC_EXPORT QDateTime timeFromS3Time(QString str); + +/// take a timestamp and convert it into an S3 timestamp +MULTIMC_LOGIC_EXPORT QString timeToS3Time(QDateTime); diff --git a/logic/minecraft/VersionFile.cpp b/logic/minecraft/VersionFile.cpp index 6e2af603..08f53a37 100644 --- a/logic/minecraft/VersionFile.cpp +++ b/logic/minecraft/VersionFile.cpp @@ -75,14 +75,12 @@ void VersionFile::applyTo(MinecraftProfile *version) { version->type = type; } - if (!m_releaseTimeString.isNull()) + if (!m_releaseTime.isNull()) { - version->m_releaseTimeString = m_releaseTimeString; version->m_releaseTime = m_releaseTime; } - if (!m_updateTimeString.isNull()) + if (!m_updateTime.isNull()) { - version->m_updateTimeString = m_updateTimeString; version->m_updateTime = m_updateTime; } } diff --git a/logic/minecraft/VersionFile.h b/logic/minecraft/VersionFile.h index df2f9bb2..64bec731 100644 --- a/logic/minecraft/VersionFile.h +++ b/logic/minecraft/VersionFile.h @@ -151,12 +151,10 @@ public: /* data */ /// Mojang: type of the Minecraft version QString type; - /// Mojang: the time this version was actually released by Mojang, as string and as QDateTime - QString m_releaseTimeString; + /// Mojang: the time this version was actually released by Mojang QDateTime m_releaseTime; - /// Mojang: the time this version was last updated by Mojang, as string and as QDateTime - QString m_updateTimeString; + /// Mojang: the time this version was last updated by Mojang QDateTime m_updateTime; /// Mojang: DEPRECATED asset group to be used with Minecraft diff --git a/logic/minecraft/onesix/OneSixVersionFormat.cpp b/logic/minecraft/onesix/OneSixVersionFormat.cpp index dc9cf9c4..45eef278 100644 --- a/logic/minecraft/onesix/OneSixVersionFormat.cpp +++ b/logic/minecraft/onesix/OneSixVersionFormat.cpp @@ -162,8 +162,8 @@ VersionFilePtr OneSixVersionFormat::versionFileFromJson(const QJsonDocument &doc readString(root, "+minecraftArguments", out->addMinecraftArguments); readString(root, "type", out->type); - parse_timestamp(readStringRet(root, "releaseTime"), out->m_releaseTimeString, out->m_releaseTime); - parse_timestamp(readStringRet(root, "time"), out->m_updateTimeString, out->m_updateTime); + out->m_releaseTime = timeFromS3Time(readStringRet(root, "releaseTime")); + out->m_updateTime = timeFromS3Time(readStringRet(root, "time")); readString(root, "assets", out->assets); @@ -280,8 +280,8 @@ static QJsonDocument versionFileToJson(VersionFilePtr patch, bool saveOrder) writeString(root, "assets", patch->assets); if (patch->isMinecraftVersion()) { - writeString(root, "releaseTime", patch->m_releaseTimeString); - writeString(root, "time", patch->m_updateTimeString); + writeString(root, "releaseTime", timeToS3Time(patch->m_releaseTime)); + writeString(root, "time", timeToS3Time(patch->m_updateTime)); } writeStringList(root, "tweakers", patch->overwriteTweakers); writeStringList(root, "+tweakers", patch->addTweakers); diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 4e37fa34..1e5c1aa9 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -31,6 +31,7 @@ add_unit_test(ModList tst_ModList.cpp) add_unit_test(Resource tst_Resource.cpp) add_unit_test(GZip tst_GZip.cpp) add_unit_test(JavaVersion tst_JavaVersion.cpp) +add_unit_test(ParseUtils tst_ParseUtils.cpp) # Tests END # diff --git a/tests/tst_ParseUtils.cpp b/tests/tst_ParseUtils.cpp new file mode 100644 index 00000000..d961e52b --- /dev/null +++ b/tests/tst_ParseUtils.cpp @@ -0,0 +1,45 @@ +#include +#include "TestUtil.h" + +#include "minecraft/ParseUtils.h" + +class ParseUtilsTest : public QObject +{ + Q_OBJECT +private +slots: + void test_Through_data() + { + QTest::addColumn("timestamp"); + const char * timestamps[] = + { + "2016-02-29T13:49:54+01:00", + "2016-02-26T15:21:11+00:01", + "2016-02-24T15:52:36+01:13", + "2016-02-18T17:41:00+00:00", + "2016-02-17T15:23:19+00:00", + "2016-02-16T15:22:39+09:22", + "2016-02-10T15:06:41+00:00", + "2016-02-04T15:28:02-05:33" + }; + for(int i = 0; i < (sizeof(timestamps) / sizeof(const char *)); i++) + { + QTest::newRow(timestamps[i]) << QString(timestamps[i]); + } + } + void test_Through() + { + QFETCH(QString, timestamp); + + auto time_parsed = timeFromS3Time(timestamp); + auto time_serialized = timeToS3Time(time_parsed); + + QCOMPARE(time_serialized, timestamp); + } + +}; + +QTEST_GUILESS_MAIN(ParseUtilsTest) + +#include "tst_ParseUtils.moc" + -- cgit v1.2.3