summaryrefslogtreecommitdiffstats
path: root/logic
diff options
context:
space:
mode:
authorPetr Mrázek <peterix@gmail.com>2013-08-27 22:32:41 +0200
committerPetr Mrázek <peterix@gmail.com>2013-08-27 22:32:41 +0200
commitfcd05ca2f6b7a76063c98e2720be758be1f67980 (patch)
tree29638132d6f5365a6db0ec0d42a3d3ff1caf9c3e /logic
parenta266e5d0ccafe1585bafd471d7a71181358ceb59 (diff)
downloadMultiMC-fcd05ca2f6b7a76063c98e2720be758be1f67980.tar
MultiMC-fcd05ca2f6b7a76063c98e2720be758be1f67980.tar.gz
MultiMC-fcd05ca2f6b7a76063c98e2720be758be1f67980.tar.lz
MultiMC-fcd05ca2f6b7a76063c98e2720be758be1f67980.tar.xz
MultiMC-fcd05ca2f6b7a76063c98e2720be758be1f67980.zip
Read mod files to get versions... and stuff.
Diffstat (limited to 'logic')
-rw-r--r--logic/Mod.cpp230
-rw-r--r--logic/Mod.h3
2 files changed, 100 insertions, 133 deletions
diff --git a/logic/Mod.cpp b/logic/Mod.cpp
index 03c34140..38faa760 100644
--- a/logic/Mod.cpp
+++ b/logic/Mod.cpp
@@ -14,9 +14,20 @@
// limitations under the License.
//
+#include <QDir>
+#include <QString>
+#include <QJsonDocument>
+#include <QJsonObject>
+#include <QJsonArray>
+#include <QJsonValue>
+#include <QDebug>
+#include <quazip.h>
+#include <quazipfile.h>
+
#include "Mod.h"
#include <pathutils.h>
-#include <QDir>
+#include <inifile.h>
+
Mod::Mod( const QFileInfo& file )
{
@@ -40,164 +51,117 @@ void Mod::repath ( const QFileInfo& file )
else
m_type = MOD_SINGLEFILE;
}
-
- /*
- switch (modType)
+ if(m_type == MOD_ZIPFILE)
{
- case MOD_ZIPFILE:
+ QuaZip zip(m_file.filePath());
+ if(!zip.open(QuaZip::mdUnzip))
+ return;
+
+ QuaZipFile file(&zip);
+ for(bool more=zip.goToFirstFile(); more; more=zip.goToNextFile())
{
- wxFFileInputStream fileIn(modFile.GetFullPath());
- wxZipInputStream zipIn(fileIn);
-
- std::auto_ptr<wxZipEntry> entry;
-
- bool is_forge = false;
- while(true)
+ QString name = zip.getCurrentFileName();
+ if(name == "mcmod.info")
{
- entry.reset(zipIn.GetNextEntry());
- if (entry.get() == nullptr)
- break;
- if(entry->GetInternalName().EndsWith("mcmod.info"))
- break;
- if(entry->GetInternalName().EndsWith("forgeversion.properties"))
+ if(!file.open(QIODevice::ReadOnly))
{
- is_forge = true;
- break;
+ zip.close();
+ return;
}
+ ReadMCModInfo(file.readAll());
+ file.close();
+ zip.close();
+ return;
}
-
- if (entry.get() != nullptr)
- {
- // Read the info file into text
- wxString infoFileData;
- wxStringOutputStream stringOut(&infoFileData);
- zipIn.Read(stringOut);
- if(!is_forge)
- ReadModInfoData(infoFileData);
- else
- ReadForgeInfoData(infoFileData);
- }
- }
- break;
-
- case MOD_FOLDER:
- {
- wxString infoFile = Path::Combine(modFile, "mcmod.info");
- if (!wxFileExists(infoFile))
+ else if(name == "forgeversion.properties")
{
- infoFile = wxEmptyString;
-
- wxDir modDir(modFile.GetFullPath());
-
- if (!modDir.IsOpened())
- {
- wxLogError(_("Can't fine mod info file. Failed to open mod folder."));
- break;
- }
-
- wxString currentFile;
- if (modDir.GetFirst(&currentFile))
+ if(!file.open(QIODevice::ReadOnly))
{
- do
- {
- if (currentFile.EndsWith("mcmod.info"))
- {
- infoFile = Path::Combine(modFile.GetFullPath(), currentFile);
- break;
- }
- } while (modDir.GetNext(&currentFile));
+ zip.close();
+ return;
}
- }
-
- if (infoFile != wxEmptyString && wxFileExists(infoFile))
- {
- wxString infoStr;
- wxFFileInputStream fileIn(infoFile);
- wxStringOutputStream strOut(&infoStr);
- fileIn.Read(strOut);
- ReadModInfoData(infoStr);
+ ReadForgeInfo(file.readAll());
+ file.close();
+ zip.close();
+ return;
}
}
- break;
+ zip.close();
+ }
+ else if(m_type == MOD_FOLDER)
+ {
+ QFileInfo mcmod_info(PathCombine(m_file.filePath(), "mcmod.info"));
+ if (mcmod_info.isFile())
+ {
+ QFile mcmod(mcmod_info.filePath());
+ if(!mcmod.open(QIODevice::ReadOnly))
+ return;
+ auto data = mcmod.readAll();
+ if(data.isEmpty() || data.isNull())
+ return;
+ ReadMCModInfo(data);
+ }
}
-*/
}
+// NEW format
+// https://github.com/MinecraftForge/FML/wiki/FML-mod-information-file/6f62b37cea040daf350dc253eae6326dd9c822c3
-/*
-void ReadModInfoData(QString info)
+// OLD format:
+// https://github.com/MinecraftForge/FML/wiki/FML-mod-information-file/5bf6a2d05145ec79387acc0d45c958642fb049fc
+void Mod::ReadMCModInfo(QByteArray contents)
{
- using namespace boost::property_tree;
-
- // Read the data
- ptree ptRoot;
-
- std::stringstream stringIn(cStr(info));
- try
+ auto getInfoFromArray = [&]( QJsonArray arr ) -> void
{
- read_json(stringIn, ptRoot);
-
- ptree pt = ptRoot.get_child(ptRoot.count("modlist") == 1 ? "modlist" : "").begin()->second;
-
- modID = wxStr(pt.get<std::string>("modid"));
- modName = wxStr(pt.get<std::string>("name"));
- modVersion = wxStr(pt.get<std::string>("version"));
- }
- catch (json_parser_error e)
+ if(!arr.at(0).isObject())
+ return;
+ auto firstObj = arr.at(0).toObject();
+ m_id = firstObj.value("modid").toString();
+ m_name = firstObj.value("name").toString();
+ m_version = firstObj.value("version").toString();
+ return;
+ };
+ QJsonParseError jsonError;
+ QJsonDocument jsonDoc = QJsonDocument::fromJson(contents, &jsonError);
+ // this is the very old format that had just the array
+ if(jsonDoc.isArray())
{
- // Silently fail...
+ getInfoFromArray(jsonDoc.array());
}
- catch (ptree_error e)
+ else if(jsonDoc.isObject())
{
- // Silently fail...
+ auto val = jsonDoc.object().value("modinfoversion");
+ int version = val.toDouble();
+ if(version != 2)
+ {
+ qDebug() << "BAD stuff happened to mod json:";
+ qDebug() << contents;
+ return;
+ }
+ auto arrVal = jsonDoc.object().value("modlist");
+ if(arrVal.isArray())
+ {
+ getInfoFromArray(arrVal.toArray());
+ }
}
}
-*/
-// FIXME: abstraction violated.
-/*
-void Mod::ReadForgeInfoData(QString infoFileData)
+void Mod::ReadForgeInfo(QByteArray contents)
{
- using namespace boost::property_tree;
-
// Read the data
- ptree ptRoot;
- modName = "Minecraft Forge";
- modID = "Forge";
- std::stringstream stringIn(cStr(infoFileData));
- try
- {
- read_ini(stringIn, ptRoot);
- wxString major, minor, revision, build;
- // BUG: boost property tree is bad. won't let us get a key with dots in it
- // Likely cause = treating the dots as path separators.
- for (auto iter = ptRoot.begin(); iter != ptRoot.end(); iter++)
- {
- auto &item = *iter;
- std::string key = item.first;
- std::string value = item.second.get_value<std::string>();
- if(key == "forge.major.number")
- major = value;
- if(key == "forge.minor.number")
- minor = value;
- if(key == "forge.revision.number")
- revision = value;
- if(key == "forge.build.number")
- build = value;
- }
- modVersion.Empty();
- modVersion << major << "." << minor << "." << revision << "." << build;
- }
- catch (json_parser_error e)
- {
- std::cerr << e.what();
- }
- catch (ptree_error e)
- {
- std::cerr << e.what();
- }
+ m_name = "Minecraft Forge";
+ m_id = "Forge";
+ INIFile ini;
+ if(!ini.loadFile(contents))
+ return;
+
+ QString major = ini.get("forge.major.number","0").toString();
+ QString minor = ini.get("forge.minor.number","0").toString();
+ QString revision = ini.get("forge.revision.number","0").toString();
+ QString build = ini.get("forge.build.number","0").toString();
+
+ m_version = major + "." + minor + "." + revision + "." + build;
}
-*/
bool Mod::replace ( Mod& with )
{
diff --git a/logic/Mod.h b/logic/Mod.h
index ea0827bd..fcfcc139 100644
--- a/logic/Mod.h
+++ b/logic/Mod.h
@@ -56,6 +56,9 @@ public:
{
return filename() == other.filename() && id() == other.id() && version() == other.version() && type() == other.type();
}
+private:
+ void ReadMCModInfo(QByteArray contents);
+ void ReadForgeInfo(QByteArray contents);
protected:
//FIXME: what do do with those? HMM...