mirror of
https://github.com/scummvm/scummvm.git
synced 2026-06-20 05:45:29 +00:00
163 lines
5.4 KiB
C++
163 lines
5.4 KiB
C++
/* ScummVM - Graphic Adventure Engine
|
|
*
|
|
* ScummVM is the legal property of its developers, whose names
|
|
* are too numerous to list here. Please refer to the COPYRIGHT
|
|
* file distributed with this source distribution.
|
|
*
|
|
* This program is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation, either version 3 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
*
|
|
*/
|
|
|
|
#include "gui/integrity-dialog.h"
|
|
|
|
#include "common/array.h"
|
|
#include "common/config-manager.h"
|
|
#include "common/debug.h"
|
|
#include "common/file.h"
|
|
#include "common/md5.h"
|
|
|
|
namespace GUI {
|
|
|
|
IntegrityDialog::IntegrityDialog(Common::String endpoint, Common::String gameConfig) : Dialog("GameOptions_IntegrityDialog") {
|
|
_endpoint = endpoint;
|
|
_gamePath = ConfMan.get("path", gameConfig);
|
|
_gameid = ConfMan.get("gameid", gameConfig);
|
|
_engineid = ConfMan.get("engineid", gameConfig);
|
|
_extra = ConfMan.get("extra", gameConfig);
|
|
_platform = ConfMan.get("platform", gameConfig);
|
|
_language = ConfMan.get("language", gameConfig);
|
|
}
|
|
|
|
IntegrityDialog::~IntegrityDialog() {
|
|
}
|
|
|
|
Common::Array<Common::StringArray> IntegrityDialog::generateChecksums(Common::Path gamePath, Common::Array<Common::StringArray> &fileChecksums) {
|
|
const Common::FSNode dir(gamePath);
|
|
|
|
if (!dir.exists() || !dir.isDirectory())
|
|
return {};
|
|
|
|
Common::FSList fileList;
|
|
if (!dir.getChildren(fileList, Common::FSNode::kListAll))
|
|
return {};
|
|
|
|
if (fileList.empty())
|
|
return {};
|
|
|
|
// Process the files and subdirectories in the current directory recursively
|
|
for (Common::FSList::const_iterator it = fileList.begin(); it != fileList.end(); it++) {
|
|
const Common::FSNode &entry = *it;
|
|
|
|
if (entry.isDirectory())
|
|
generateChecksums(entry.getPath(), fileChecksums);
|
|
else {
|
|
const Common::Path filename(entry.getPath());
|
|
Common::File file;
|
|
if (!file.open(entry))
|
|
continue;
|
|
|
|
Common::Array<Common::String> fileChecksum = {filename.toString()};
|
|
// Various checksizes
|
|
for (auto size : {0, 5000, 1024 * 1024}) {
|
|
fileChecksum.push_back(Common::computeStreamMD5AsString(file, size).c_str());
|
|
file.seek(0);
|
|
}
|
|
// Tail checksums with checksize 5000
|
|
file.seek(-5000, SEEK_END);
|
|
fileChecksum.push_back(Common::computeStreamMD5AsString(file).c_str());
|
|
|
|
file.close();
|
|
fileChecksums.push_back(fileChecksum);
|
|
}
|
|
}
|
|
|
|
return fileChecksums;
|
|
}
|
|
|
|
Common::JSONValue *IntegrityDialog::generateJSONRequest(Common::Path gamePath, Common::String gameid, Common::String engineid, Common::String extra, Common::String platform, Common::String language) {
|
|
Common::Array<Common::StringArray> fileChecksums = {};
|
|
fileChecksums = generateChecksums(gamePath, fileChecksums);
|
|
Common::JSONObject requestObject;
|
|
|
|
requestObject.setVal("gameid", new Common::JSONValue(gameid));
|
|
requestObject.setVal("engineid", new Common::JSONValue(engineid));
|
|
requestObject.setVal("extra", new Common::JSONValue(extra));
|
|
requestObject.setVal("platform", new Common::JSONValue(platform));
|
|
requestObject.setVal("language", new Common::JSONValue(language));
|
|
|
|
Common::JSONArray filesObject;
|
|
|
|
for (Common::StringArray fileChecksum : fileChecksums) {
|
|
Common::JSONObject file;
|
|
Common::Path relativePath = Common::Path(fileChecksum[0]).relativeTo(gamePath);
|
|
file.setVal("name", new Common::JSONValue(relativePath.toConfig()));
|
|
|
|
auto tempNode = Common::FSNode(Common::Path(fileChecksum[0]));
|
|
Common::File tempFile;
|
|
if (!tempFile.open(tempNode))
|
|
continue;
|
|
long long fileSize = tempFile.size();
|
|
tempFile.close();
|
|
|
|
file.setVal("size", new Common::JSONValue(fileSize));
|
|
|
|
Common::JSONArray checksums;
|
|
Common::StringArray checkcodes = {"md5", "md5-5000", "md5-1M", "md5-t-5000"};
|
|
|
|
int index = -1;
|
|
for (Common::String val : fileChecksum) {
|
|
index++;
|
|
|
|
Common::JSONObject checksum;
|
|
if (index < 1) {
|
|
continue;
|
|
}
|
|
|
|
checksum.setVal("type", new Common::JSONValue(checkcodes[index - 1]));
|
|
checksum.setVal("checksum", new Common::JSONValue(val));
|
|
|
|
checksums.push_back(new Common::JSONValue(checksum));
|
|
}
|
|
file.setVal("checksums", new Common::JSONValue(checksums));
|
|
|
|
filesObject.push_back(new Common::JSONValue(file));
|
|
}
|
|
|
|
requestObject.setVal("files", new Common::JSONValue(filesObject));
|
|
|
|
Common::JSONValue *request = new Common::JSONValue(requestObject);
|
|
return request;
|
|
}
|
|
|
|
void IntegrityDialog::checksumResponseCallback(const Common::JSONValue *r) {
|
|
debug("Response recieved!");
|
|
}
|
|
|
|
void IntegrityDialog::errorCallback(const Networking::ErrorResponse &error) {
|
|
debug("ERROR %ld: %s", error.httpResponseCode, error.response.c_str());
|
|
}
|
|
|
|
void IntegrityDialog::sendJSON() {
|
|
Networking::PostRequest conn(_endpoint,
|
|
new Common::Callback<IntegrityDialog, const Common::JSONValue *>(this, &IntegrityDialog::checksumResponseCallback),
|
|
new Common::Callback<IntegrityDialog, const Networking::ErrorResponse &>(this, &IntegrityDialog::errorCallback));
|
|
|
|
Common::JSONValue *json = generateJSONRequest(Common::Path(_gamePath), _gameid, _engineid, _extra, _platform, _language);
|
|
conn.setJSONData(json);
|
|
conn.start();
|
|
delete json;
|
|
}
|
|
|
|
} // End of namespace GUI
|