1003 lines
31 KiB
C++
1003 lines
31 KiB
C++
// MassBuilderSaveTool
|
|
// Copyright (C) 2021 Guillaume Jacquemin
|
|
//
|
|
// 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 <https://www.gnu.org/licenses/>.
|
|
|
|
#include <algorithm>
|
|
|
|
#include <Corrade/Containers/Array.h>
|
|
#include <Corrade/Utility/Directory.h>
|
|
#include <Corrade/Utility/FormatStl.h>
|
|
#include <Corrade/Utility/String.h>
|
|
|
|
#include "Profile.h"
|
|
|
|
#include "Locators.h"
|
|
|
|
using namespace Corrade;
|
|
|
|
Profile::Profile(const std::string& path) {
|
|
auto map = Utility::Directory::mapRead(path);
|
|
|
|
if(!map) {
|
|
_lastError = "Couldn't memory-map " + Utility::Directory::filename(path);
|
|
return;
|
|
}
|
|
|
|
_profileDirectory = Utility::Directory::path(path);
|
|
_filename = Utility::Directory::filename(path);
|
|
|
|
if(Utility::String::beginsWith(_filename, "Demo")) {
|
|
_type = ProfileType::Demo;
|
|
}
|
|
else {
|
|
_type = ProfileType::FullGame;
|
|
}
|
|
|
|
_steamId = Utility::String::ltrim(Utility::String::rtrim(_filename, ".sav"), (_type == ProfileType::Demo ? "Demo" : "") + std::string{"Profile"});
|
|
|
|
auto it = std::search(map.begin(), map.end(), &company_name_locator[0], &company_name_locator[27]);
|
|
|
|
if(it == map.end()) {
|
|
_lastError = "Couldn't find a company name in " + _filename;
|
|
return;
|
|
}
|
|
|
|
_companyName = std::string{it + 41};
|
|
|
|
_valid = true;
|
|
}
|
|
|
|
auto Profile::valid() const -> bool {
|
|
return _valid;
|
|
}
|
|
|
|
auto Profile::lastError() const -> std::string const& {
|
|
return _lastError;
|
|
}
|
|
|
|
auto Profile::filename() const -> std::string const& {
|
|
return _filename;
|
|
}
|
|
|
|
auto Profile::type() const -> ProfileType {
|
|
return _type;
|
|
}
|
|
|
|
auto Profile::steamId() const -> std::string const& {
|
|
return _steamId;
|
|
}
|
|
|
|
void Profile::refreshValues() {
|
|
getCompanyName();
|
|
getActiveFrameSlot();
|
|
getCredits();
|
|
getStoryProgress();
|
|
getLastMissionId();
|
|
|
|
getVerseSteel();
|
|
getUndinium();
|
|
getNecriumAlloy();
|
|
getLunarite();
|
|
getAsterite();
|
|
|
|
getEdnil();
|
|
getNuflalt();
|
|
getAurelene();
|
|
getSoldus();
|
|
getSynthesizedN();
|
|
|
|
getAlcarbonite();
|
|
getKeriphene();
|
|
getNitinolCM();
|
|
getQuarkium();
|
|
getAlterene();
|
|
|
|
getMixedComposition();
|
|
getVoidResidue();
|
|
getMuscularConstruction();
|
|
getMineralExoskeletology();
|
|
getCarbonizedSkin();
|
|
}
|
|
|
|
auto Profile::companyName() const -> std::string const& {
|
|
return _companyName;
|
|
}
|
|
|
|
auto Profile::getCompanyName() -> std::string const& {
|
|
auto mmap = Utility::Directory::mapRead(Utility::Directory::join(_profileDirectory, _filename));
|
|
|
|
auto it = std::search(mmap.begin(), mmap.end(), &company_name_locator[0], &company_name_locator[27]);
|
|
|
|
if(it == mmap.end()) {
|
|
_lastError = "Couldn't find a company name in " + _filename;
|
|
_companyName = "";
|
|
}
|
|
else {
|
|
_companyName = std::string{it + 41};
|
|
}
|
|
|
|
return _companyName;
|
|
}
|
|
|
|
auto Profile::renameCompany(const std::string& new_name) -> bool {
|
|
char length_difference = static_cast<char>(_companyName.length() - new_name.length());
|
|
|
|
std::string profile_data = Utility::Directory::readString(Utility::Directory::join(_profileDirectory, _filename));
|
|
|
|
auto iter = std::search(profile_data.begin(), profile_data.end(), &company_name_locator[0], &company_name_locator[27]);
|
|
|
|
if(iter != profile_data.end()) {
|
|
|
|
*(iter + 0x1C) = *(iter + 0x1C) - length_difference;
|
|
*(iter + 0x25) = *(iter + 0x25) - length_difference;
|
|
|
|
while(*(iter + 0x29) != '\0') {
|
|
profile_data.erase(iter + 0x29);
|
|
}
|
|
|
|
profile_data.insert(iter + 0x29, new_name.cbegin(), new_name.cend());
|
|
|
|
if(!Utility::Directory::writeString(Utility::Directory::join(_profileDirectory, _filename), profile_data)) {
|
|
_lastError = "The file" + _filename + " couldn't be written to.";
|
|
return false;
|
|
}
|
|
|
|
_companyName = new_name;
|
|
|
|
return true;
|
|
}
|
|
else {
|
|
_lastError = "Couldn't find the company name in " + _filename;
|
|
|
|
return false;
|
|
}
|
|
}
|
|
|
|
auto Profile::activeFrameSlot() const -> Int {
|
|
return _activeFrameSlot;
|
|
}
|
|
|
|
auto Profile::getActiveFrameSlot() -> Int {
|
|
auto mmap = Utility::Directory::mapRead(Utility::Directory::join(_profileDirectory, _filename));
|
|
|
|
auto iter = std::search(mmap.begin(), mmap.end(), &active_slot_locator[0], &active_slot_locator[31]);
|
|
|
|
if(iter == mmap.end()) {
|
|
if(std::search(mmap.begin(), mmap.end(), &credits_locator[0], &credits_locator[22]) != mmap.end()) {
|
|
_activeFrameSlot = 0;
|
|
}
|
|
else {
|
|
_lastError = "The profile save seems to be corrupted or the game didn't release the handle on the file.";
|
|
_activeFrameSlot = -1;
|
|
}
|
|
}
|
|
else {
|
|
_activeFrameSlot = *(iter + 41);
|
|
}
|
|
|
|
return _activeFrameSlot;
|
|
}
|
|
|
|
auto Profile::credits() const -> Int {
|
|
return _credits;
|
|
}
|
|
|
|
auto Profile::getCredits() -> Int {
|
|
auto mmap = Utility::Directory::mapRead(Utility::Directory::join(_profileDirectory, _filename));
|
|
|
|
auto iter = std::search(mmap.begin(), mmap.end(), &credits_locator[0], &credits_locator[22]);
|
|
|
|
if(iter != mmap.end()) {
|
|
_credits = *reinterpret_cast<const Int*>(iter + 0x20);
|
|
}
|
|
else {
|
|
_lastError = "The profile save seems to be corrupted or the game didn't release the handle on the file.";
|
|
_credits = -1;
|
|
}
|
|
|
|
return _credits;
|
|
}
|
|
|
|
auto Profile::setCredits(Int amount) -> bool {
|
|
auto mmap = Utility::Directory::map(Utility::Directory::join(_profileDirectory, _filename));
|
|
|
|
auto iter = std::search(mmap.begin(), mmap.end(), &credits_locator[0], &credits_locator[22]);
|
|
|
|
if(iter != mmap.end()) {
|
|
*reinterpret_cast<Int*>(iter + 0x20) = amount;
|
|
_credits = amount;
|
|
return true;
|
|
}
|
|
else {
|
|
_lastError = "The profile save seems to be corrupted or the game didn't release the handle on the file.";
|
|
return false;
|
|
}
|
|
}
|
|
|
|
auto Profile::storyProgress() const -> Int {
|
|
return _storyProgress;
|
|
}
|
|
|
|
auto Profile::getStoryProgress() -> Int {
|
|
auto mmap = Utility::Directory::mapRead(Utility::Directory::join(_profileDirectory, _filename));
|
|
|
|
auto iter = std::search(mmap.begin(), mmap.end(), &story_progress_locator[0], &story_progress_locator[29]);
|
|
|
|
if(iter != mmap.end()) {
|
|
_storyProgress = *reinterpret_cast<const Int*>(iter + 0x27);
|
|
}
|
|
else {
|
|
_lastError = "The profile save seems to be corrupted or the game didn't release the handle on the file.";
|
|
_storyProgress = -1;
|
|
}
|
|
|
|
return _storyProgress;
|
|
}
|
|
|
|
auto Profile::setStoryProgress(Int progress) -> bool {
|
|
auto mmap = Utility::Directory::map(Utility::Directory::join(_profileDirectory, _filename));
|
|
|
|
auto iter = std::search(mmap.begin(), mmap.end(), &story_progress_locator[0], &story_progress_locator[29]);
|
|
|
|
if(iter != mmap.end()) {
|
|
*reinterpret_cast<Int*>(iter + 0x27) = progress;
|
|
_storyProgress = progress;
|
|
return true;
|
|
}
|
|
else {
|
|
_lastError = "The profile save seems to be corrupted or the game didn't release the handle on the file.";
|
|
return false;
|
|
}
|
|
}
|
|
|
|
auto Profile::lastMissionId() const -> Int {
|
|
return _lastMissionId;
|
|
}
|
|
|
|
auto Profile::getLastMissionId() -> Int {
|
|
auto mmap = Utility::Directory::mapRead(Utility::Directory::join(_profileDirectory, _filename));
|
|
|
|
auto iter = std::search(mmap.begin(), mmap.end(), &last_mission_id_locator[0], &last_mission_id_locator[29]);
|
|
|
|
if(iter != mmap.end()) {
|
|
_lastMissionId = *reinterpret_cast<const Int*>(iter + 0x27);
|
|
}
|
|
else {
|
|
_lastError = "The profile save seems to be corrupted or the game didn't release the handle on the file.";
|
|
_lastMissionId = -1;
|
|
}
|
|
|
|
return _lastMissionId;
|
|
}
|
|
|
|
auto Profile::verseSteel() const -> Int {
|
|
return _verseSteel;
|
|
}
|
|
|
|
auto Profile::getVerseSteel() -> Int {
|
|
auto mmap = Utility::Directory::mapRead(Utility::Directory::join(_profileDirectory, _filename));
|
|
|
|
auto iter = std::search(mmap.begin(), mmap.end(), &verse_steel_locator[0], &verse_steel_locator[129]);
|
|
|
|
if(iter != mmap.end()) {
|
|
_verseSteel = *reinterpret_cast<const Int*>(iter + 0x8C);
|
|
}
|
|
else {
|
|
_lastError = "The profile save seems to be corrupted or the game didn't release the handle on the file.";
|
|
_verseSteel = -1;
|
|
}
|
|
|
|
return _verseSteel;
|
|
}
|
|
|
|
auto Profile::setVerseSteel(Int amount) -> bool {
|
|
auto mmap = Utility::Directory::map(Utility::Directory::join(_profileDirectory, _filename));
|
|
|
|
auto iter = std::search(mmap.begin(), mmap.end(), &verse_steel_locator[0], &verse_steel_locator[129]);
|
|
|
|
if(iter != mmap.end()) {
|
|
*reinterpret_cast<Int*>(iter + 0x8C) = amount;
|
|
_verseSteel = amount;
|
|
return true;
|
|
}
|
|
else {
|
|
_lastError = "The profile save seems to be corrupted or the game didn't release the handle on the file.";
|
|
return false;
|
|
}
|
|
}
|
|
|
|
auto Profile::undinium() const -> Int {
|
|
return _undinium;
|
|
}
|
|
|
|
auto Profile::getUndinium() -> Int {
|
|
auto mmap = Utility::Directory::mapRead(Utility::Directory::join(_profileDirectory, _filename));
|
|
|
|
auto iter = std::search(mmap.begin(), mmap.end(), &undinium_locator[0], &undinium_locator[129]);
|
|
|
|
if(iter != mmap.end()) {
|
|
_undinium = *reinterpret_cast<const Int*>(iter + 0x8C);
|
|
}
|
|
else {
|
|
_lastError = "The profile save seems to be corrupted or the game didn't release the handle on the file.";
|
|
_undinium = -1;
|
|
}
|
|
|
|
return _undinium;
|
|
}
|
|
|
|
auto Profile::setUndinium(Int amount) -> bool {
|
|
auto mmap = Utility::Directory::map(Utility::Directory::join(_profileDirectory, _filename));
|
|
|
|
auto iter = std::search(mmap.begin(), mmap.end(), &undinium_locator[0], &undinium_locator[129]);
|
|
|
|
if(iter != mmap.end()) {
|
|
*reinterpret_cast<Int*>(iter + 0x8C) = amount;
|
|
_undinium = amount;
|
|
return true;
|
|
}
|
|
else {
|
|
_lastError = "The profile save seems to be corrupted or the game didn't release the handle on the file.";
|
|
return false;
|
|
}
|
|
}
|
|
|
|
auto Profile::necriumAlloy() const -> Int {
|
|
return _necriumAlloy;
|
|
}
|
|
|
|
auto Profile::getNecriumAlloy() -> Int {
|
|
auto mmap = Utility::Directory::mapRead(Utility::Directory::join(_profileDirectory, _filename));
|
|
|
|
auto iter = std::search(mmap.begin(), mmap.end(), &necrium_alloy_locator[0], &necrium_alloy_locator[129]);
|
|
|
|
if(iter != mmap.end()) {
|
|
_necriumAlloy = *reinterpret_cast<const Int*>(iter + 0x8C);
|
|
}
|
|
else {
|
|
_lastError = "The profile save seems to be corrupted or the game didn't release the handle on the file.";
|
|
_necriumAlloy = -1;
|
|
}
|
|
|
|
return _necriumAlloy;
|
|
}
|
|
|
|
auto Profile::setNecriumAlloy(Int amount) -> bool {
|
|
auto mmap = Utility::Directory::map(Utility::Directory::join(_profileDirectory, _filename));
|
|
|
|
auto iter = std::search(mmap.begin(), mmap.end(), &necrium_alloy_locator[0], &necrium_alloy_locator[129]);
|
|
|
|
if(iter != mmap.end()) {
|
|
*reinterpret_cast<Int*>(iter + 0x8C) = amount;
|
|
_necriumAlloy = amount;
|
|
return true;
|
|
}
|
|
else {
|
|
_lastError = "The profile save seems to be corrupted or the game didn't release the handle on the file.";
|
|
return false;
|
|
}
|
|
}
|
|
|
|
auto Profile::lunarite() const -> Int {
|
|
return _lunarite;
|
|
}
|
|
|
|
auto Profile::getLunarite() -> Int {
|
|
auto mmap = Utility::Directory::mapRead(Utility::Directory::join(_profileDirectory, _filename));
|
|
|
|
auto iter = std::search(mmap.begin(), mmap.end(), &lunarite_locator[0], &lunarite_locator[129]);
|
|
|
|
if(iter != mmap.end()) {
|
|
_lunarite = *reinterpret_cast<const Int*>(iter + 0x8C);
|
|
}
|
|
else {
|
|
_lastError = "The profile save seems to be corrupted or the game didn't release the handle on the file.";
|
|
_lunarite = -1;
|
|
}
|
|
|
|
return _lunarite;
|
|
}
|
|
|
|
auto Profile::setLunarite(Int amount) -> bool {
|
|
auto mmap = Utility::Directory::map(Utility::Directory::join(_profileDirectory, _filename));
|
|
|
|
auto iter = std::search(mmap.begin(), mmap.end(), &lunarite_locator[0], &lunarite_locator[129]);
|
|
|
|
if(iter != mmap.end()) {
|
|
*reinterpret_cast<Int*>(iter + 0x8C) = amount;
|
|
_lunarite = amount;
|
|
return true;
|
|
}
|
|
else {
|
|
_lastError = "The profile save seems to be corrupted or the game didn't release the handle on the file.";
|
|
return false;
|
|
}
|
|
}
|
|
|
|
auto Profile::asterite() const -> Int {
|
|
return _asterite;
|
|
}
|
|
|
|
auto Profile::getAsterite() -> Int {
|
|
auto mmap = Utility::Directory::mapRead(Utility::Directory::join(_profileDirectory, _filename));
|
|
|
|
auto iter = std::search(mmap.begin(), mmap.end(), &asterite_locator[0], &asterite_locator[129]);
|
|
|
|
if(iter != mmap.end()) {
|
|
_asterite = *reinterpret_cast<const Int*>(iter + 0x8C);
|
|
}
|
|
else {
|
|
_lastError = "The profile save seems to be corrupted or the game didn't release the handle on the file.";
|
|
_asterite = -1;
|
|
}
|
|
|
|
return _asterite;
|
|
}
|
|
|
|
auto Profile::setAsterite(Int amount) -> bool {
|
|
auto mmap = Utility::Directory::map(Utility::Directory::join(_profileDirectory, _filename));
|
|
|
|
auto iter = std::search(mmap.begin(), mmap.end(), &asterite_locator[0], &asterite_locator[129]);
|
|
|
|
if(iter != mmap.end()) {
|
|
*reinterpret_cast<Int*>(iter + 0x8C) = amount;
|
|
_asterite = amount;
|
|
return true;
|
|
}
|
|
else {
|
|
_lastError = "The profile save seems to be corrupted or the game didn't release the handle on the file.";
|
|
return false;
|
|
}
|
|
}
|
|
|
|
auto Profile::ednil() const -> Int {
|
|
return _ednil;
|
|
}
|
|
|
|
auto Profile::getEdnil() -> Int {
|
|
auto mmap = Utility::Directory::mapRead(Utility::Directory::join(_profileDirectory, _filename));
|
|
|
|
auto iter = std::search(mmap.begin(), mmap.end(), &ednil_locator[0], &ednil_locator[129]);
|
|
|
|
if(iter != mmap.end()) {
|
|
_ednil = *reinterpret_cast<const Int*>(iter + 0x8C);
|
|
}
|
|
else {
|
|
_lastError = "The profile save seems to be corrupted or the game didn't release the handle on the file.";
|
|
_ednil = -1;
|
|
}
|
|
|
|
return _ednil;
|
|
}
|
|
|
|
auto Profile::setEdnil(Int amount) -> bool {
|
|
auto mmap = Utility::Directory::map(Utility::Directory::join(_profileDirectory, _filename));
|
|
|
|
auto iter = std::search(mmap.begin(), mmap.end(), &ednil_locator[0], &ednil_locator[129]);
|
|
|
|
if(iter != mmap.end()) {
|
|
*reinterpret_cast<Int*>(iter + 0x8C) = amount;
|
|
_ednil = amount;
|
|
return true;
|
|
}
|
|
else {
|
|
_lastError = "The profile save seems to be corrupted or the game didn't release the handle on the file.";
|
|
return false;
|
|
}
|
|
}
|
|
|
|
auto Profile::nuflalt() const -> Int {
|
|
return _nuflalt;
|
|
}
|
|
|
|
auto Profile::getNuflalt() -> Int {
|
|
auto mmap = Utility::Directory::mapRead(Utility::Directory::join(_profileDirectory, _filename));
|
|
|
|
auto iter = std::search(mmap.begin(), mmap.end(), &nuflalt_locator[0], &nuflalt_locator[129]);
|
|
|
|
if(iter != mmap.end()) {
|
|
_nuflalt = *reinterpret_cast<const Int*>(iter + 0x8C);
|
|
}
|
|
else {
|
|
_lastError = "The profile save seems to be corrupted or the game didn't release the handle on the file.";
|
|
_nuflalt = -1;
|
|
}
|
|
|
|
return _nuflalt;
|
|
}
|
|
|
|
auto Profile::setNuflalt(Int amount) -> bool {
|
|
auto mmap = Utility::Directory::map(Utility::Directory::join(_profileDirectory, _filename));
|
|
|
|
auto iter = std::search(mmap.begin(), mmap.end(), &nuflalt_locator[0], &nuflalt_locator[129]);
|
|
|
|
if(iter != mmap.end()) {
|
|
*reinterpret_cast<Int*>(iter + 0x8C) = amount;
|
|
_nuflalt = amount;
|
|
return true;
|
|
}
|
|
else {
|
|
_lastError = "The profile save seems to be corrupted or the game didn't release the handle on the file.";
|
|
return false;
|
|
}
|
|
}
|
|
|
|
auto Profile::aurelene() const -> Int {
|
|
return _aurelene;
|
|
}
|
|
|
|
auto Profile::getAurelene() -> Int {
|
|
auto mmap = Utility::Directory::mapRead(Utility::Directory::join(_profileDirectory, _filename));
|
|
|
|
auto iter = std::search(mmap.begin(), mmap.end(), &aurelene_locator[0], &aurelene_locator[129]);
|
|
|
|
if(iter != mmap.end()) {
|
|
_aurelene = *reinterpret_cast<const Int*>(iter + 0x8C);
|
|
}
|
|
else {
|
|
_lastError = "The profile save seems to be corrupted or the game didn't release the handle on the file.";
|
|
_aurelene = -1;
|
|
}
|
|
|
|
return _aurelene;
|
|
}
|
|
|
|
auto Profile::setAurelene(Int amount) -> bool {
|
|
auto mmap = Utility::Directory::map(Utility::Directory::join(_profileDirectory, _filename));
|
|
|
|
auto iter = std::search(mmap.begin(), mmap.end(), &aurelene_locator[0], &aurelene_locator[129]);
|
|
|
|
if(iter != mmap.end()) {
|
|
*reinterpret_cast<Int*>(iter + 0x8C) = amount;
|
|
_aurelene = amount;
|
|
return true;
|
|
}
|
|
else {
|
|
_lastError = "The profile save seems to be corrupted or the game didn't release the handle on the file.";
|
|
return false;
|
|
}
|
|
}
|
|
|
|
auto Profile::soldus() const -> Int {
|
|
return _soldus;
|
|
}
|
|
|
|
auto Profile::getSoldus() -> Int {
|
|
auto mmap = Utility::Directory::mapRead(Utility::Directory::join(_profileDirectory, _filename));
|
|
|
|
auto iter = std::search(mmap.begin(), mmap.end(), &soldus_locator[0], &soldus_locator[129]);
|
|
|
|
if(iter != mmap.end()) {
|
|
_soldus = *reinterpret_cast<const Int*>(iter + 0x8C);
|
|
}
|
|
else {
|
|
_lastError = "The profile save seems to be corrupted or the game didn't release the handle on the file.";
|
|
_soldus = -1;
|
|
}
|
|
|
|
return _soldus;
|
|
}
|
|
|
|
auto Profile::setSoldus(Int amount) -> bool {
|
|
auto mmap = Utility::Directory::map(Utility::Directory::join(_profileDirectory, _filename));
|
|
|
|
auto iter = std::search(mmap.begin(), mmap.end(), &soldus_locator[0], &soldus_locator[129]);
|
|
|
|
if(iter != mmap.end()) {
|
|
*reinterpret_cast<Int*>(iter + 0x8C) = amount;
|
|
_soldus = amount;
|
|
return true;
|
|
}
|
|
else {
|
|
_lastError = "The profile save seems to be corrupted or the game didn't release the handle on the file.";
|
|
return false;
|
|
}
|
|
}
|
|
|
|
auto Profile::synthesizedN() const -> Int {
|
|
return _synthesizedN;
|
|
}
|
|
|
|
auto Profile::getSynthesizedN() -> Int {
|
|
auto mmap = Utility::Directory::mapRead(Utility::Directory::join(_profileDirectory, _filename));
|
|
|
|
auto iter = std::search(mmap.begin(), mmap.end(), &synthesized_n_locator[0], &synthesized_n_locator[129]);
|
|
|
|
if(iter != mmap.end()) {
|
|
_synthesizedN = *reinterpret_cast<const Int*>(iter + 0x8C);
|
|
}
|
|
else {
|
|
_lastError = "The profile save seems to be corrupted or the game didn't release the handle on the file.";
|
|
_synthesizedN = -1;
|
|
}
|
|
|
|
return _synthesizedN;
|
|
}
|
|
|
|
auto Profile::setSynthesizedN(Int amount) -> bool {
|
|
auto mmap = Utility::Directory::map(Utility::Directory::join(_profileDirectory, _filename));
|
|
|
|
auto iter = std::search(mmap.begin(), mmap.end(), &synthesized_n_locator[0], &synthesized_n_locator[129]);
|
|
|
|
if(iter != mmap.end()) {
|
|
*reinterpret_cast<Int*>(iter + 0x8C) = amount;
|
|
_synthesizedN = amount;
|
|
return true;
|
|
}
|
|
else {
|
|
_lastError = "The profile save seems to be corrupted or the game didn't release the handle on the file.";
|
|
return false;
|
|
}
|
|
}
|
|
|
|
auto Profile::alcarbonite() const -> Int {
|
|
return _alcarbonite;
|
|
}
|
|
|
|
auto Profile::getAlcarbonite() -> Int {
|
|
auto mmap = Utility::Directory::mapRead(Utility::Directory::join(_profileDirectory, _filename));
|
|
|
|
auto iter = std::search(mmap.begin(), mmap.end(), &alcarbonite_locator[0], &alcarbonite_locator[129]);
|
|
|
|
if(iter != mmap.end()) {
|
|
_alcarbonite = *reinterpret_cast<const Int*>(iter + 0x8C);
|
|
}
|
|
else {
|
|
_lastError = "The profile save seems to be corrupted or the game didn't release the handle on the file.";
|
|
_alcarbonite = -1;
|
|
}
|
|
|
|
return _alcarbonite;
|
|
}
|
|
|
|
auto Profile::setAlcarbonite(Int amount) -> bool {
|
|
auto mmap = Utility::Directory::map(Utility::Directory::join(_profileDirectory, _filename));
|
|
|
|
auto iter = std::search(mmap.begin(), mmap.end(), &alcarbonite_locator[0], &alcarbonite_locator[129]);
|
|
|
|
if(iter != mmap.end()) {
|
|
*reinterpret_cast<Int*>(iter + 0x8C) = amount;
|
|
_alcarbonite = amount;
|
|
return true;
|
|
}
|
|
else {
|
|
_lastError = "The profile save seems to be corrupted or the game didn't release the handle on the file.";
|
|
return false;
|
|
}
|
|
}
|
|
|
|
auto Profile::keriphene() const -> Int {
|
|
return _keriphene;
|
|
}
|
|
|
|
auto Profile::getKeriphene() -> Int {
|
|
auto mmap = Utility::Directory::mapRead(Utility::Directory::join(_profileDirectory, _filename));
|
|
|
|
auto iter = std::search(mmap.begin(), mmap.end(), &keriphene_locator[0], &keriphene_locator[129]);
|
|
|
|
if(iter != mmap.end()) {
|
|
_keriphene = *reinterpret_cast<const Int*>(iter + 0x8C);
|
|
}
|
|
else {
|
|
_lastError = "The profile save seems to be corrupted or the game didn't release the handle on the file.";
|
|
_keriphene= -1;
|
|
}
|
|
|
|
return _keriphene;
|
|
}
|
|
|
|
auto Profile::setKeriphene(Int amount) -> bool {
|
|
auto mmap = Utility::Directory::map(Utility::Directory::join(_profileDirectory, _filename));
|
|
|
|
auto iter = std::search(mmap.begin(), mmap.end(), &keriphene_locator[0], &keriphene_locator[129]);
|
|
|
|
if(iter != mmap.end()) {
|
|
*reinterpret_cast<Int*>(iter + 0x8C) = amount;
|
|
_keriphene = amount;
|
|
return true;
|
|
}
|
|
else {
|
|
_lastError = "The profile save seems to be corrupted or the game didn't release the handle on the file.";
|
|
return false;
|
|
}
|
|
}
|
|
|
|
auto Profile::nitinolCM() const -> Int {
|
|
return _nitinolCM;
|
|
}
|
|
|
|
auto Profile::getNitinolCM() -> Int {
|
|
auto mmap = Utility::Directory::mapRead(Utility::Directory::join(_profileDirectory, _filename));
|
|
|
|
auto iter = std::search(mmap.begin(), mmap.end(), &nitinol_cm_locator[0], &nitinol_cm_locator[129]);
|
|
|
|
if(iter != mmap.end()) {
|
|
_nitinolCM = *reinterpret_cast<const Int*>(iter + 0x8C);
|
|
}
|
|
else {
|
|
_lastError = "The profile save seems to be corrupted or the game didn't release the handle on the file.";
|
|
_nitinolCM = -1;
|
|
}
|
|
|
|
return _nitinolCM;
|
|
}
|
|
|
|
auto Profile::setNitinolCM(Int amount) -> bool {
|
|
auto mmap = Utility::Directory::map(Utility::Directory::join(_profileDirectory, _filename));
|
|
|
|
auto iter = std::search(mmap.begin(), mmap.end(), &nitinol_cm_locator[0], &nitinol_cm_locator[129]);
|
|
|
|
if(iter != mmap.end()) {
|
|
*reinterpret_cast<Int*>(iter + 0x8C) = amount;
|
|
_nitinolCM = amount;
|
|
return true;
|
|
}
|
|
else {
|
|
_lastError = "The profile save seems to be corrupted or the game didn't release the handle on the file.";
|
|
return false;
|
|
}
|
|
}
|
|
|
|
auto Profile::quarkium() const -> Int {
|
|
return _quarkium;
|
|
}
|
|
|
|
auto Profile::getQuarkium() -> Int {
|
|
auto mmap = Utility::Directory::mapRead(Utility::Directory::join(_profileDirectory, _filename));
|
|
|
|
auto iter = std::search(mmap.begin(), mmap.end(), &quarkium_locator[0], &quarkium_locator[129]);
|
|
|
|
if(iter != mmap.end()) {
|
|
_quarkium = *reinterpret_cast<const Int*>(iter + 0x8C);
|
|
}
|
|
else {
|
|
_lastError = "The profile save seems to be corrupted or the game didn't release the handle on the file.";
|
|
_quarkium = -1;
|
|
}
|
|
|
|
return _quarkium;
|
|
}
|
|
|
|
auto Profile::setQuarkium(Int amount) -> bool {
|
|
auto mmap = Utility::Directory::map(Utility::Directory::join(_profileDirectory, _filename));
|
|
|
|
auto iter = std::search(mmap.begin(), mmap.end(), &quarkium_locator[0], &quarkium_locator[129]);
|
|
|
|
if(iter != mmap.end()) {
|
|
*reinterpret_cast<Int*>(iter + 0x8C) = amount;
|
|
_quarkium = amount;
|
|
return true;
|
|
}
|
|
else {
|
|
_lastError = "The profile save seems to be corrupted or the game didn't release the handle on the file.";
|
|
return false;
|
|
}
|
|
}
|
|
|
|
auto Profile::alterene() const -> Int {
|
|
return _alterene;
|
|
}
|
|
|
|
auto Profile::getAlterene() -> Int {
|
|
auto mmap = Utility::Directory::mapRead(Utility::Directory::join(_profileDirectory, _filename));
|
|
|
|
auto iter = std::search(mmap.begin(), mmap.end(), &alterene_locator[0], &alterene_locator[129]);
|
|
|
|
if(iter != mmap.end()) {
|
|
_alterene = *reinterpret_cast<const Int*>(iter + 0x8C);
|
|
}
|
|
else {
|
|
_lastError = "The profile save seems to be corrupted or the game didn't release the handle on the file.";
|
|
_alterene = -1;
|
|
}
|
|
|
|
return _alterene;
|
|
}
|
|
|
|
auto Profile::setAlterene(Int amount) -> bool {
|
|
auto mmap = Utility::Directory::map(Utility::Directory::join(_profileDirectory, _filename));
|
|
|
|
auto iter = std::search(mmap.begin(), mmap.end(), &alterene_locator[0], &alterene_locator[129]);
|
|
|
|
if(iter != mmap.end()) {
|
|
*reinterpret_cast<Int*>(iter + 0x8C) = amount;
|
|
_alterene = amount;
|
|
return true;
|
|
}
|
|
else {
|
|
_lastError = "The profile save seems to be corrupted or the game didn't release the handle on the file.";
|
|
return false;
|
|
}
|
|
}
|
|
|
|
auto Profile::mixedComposition() const -> Int {
|
|
return _mixedComposition;
|
|
}
|
|
|
|
auto Profile::getMixedComposition() -> Int {
|
|
auto mmap = Utility::Directory::mapRead(Utility::Directory::join(_profileDirectory, _filename));
|
|
|
|
auto iter = std::search(mmap.begin(), mmap.end(), &mixed_composition_locator[0], &mixed_composition_locator[129]);
|
|
|
|
if(iter != mmap.end()) {
|
|
_mixedComposition = *reinterpret_cast<const Int*>(iter + 0x8C);
|
|
}
|
|
else {
|
|
_lastError = "The profile save seems to be corrupted or the game didn't release the handle on the file.";
|
|
_mixedComposition = -1;
|
|
}
|
|
|
|
return _mixedComposition;
|
|
}
|
|
|
|
auto Profile::setMixedComposition(Int amount) -> bool {
|
|
auto mmap = Utility::Directory::map(Utility::Directory::join(_profileDirectory, _filename));
|
|
|
|
auto iter = std::search(mmap.begin(), mmap.end(), &mixed_composition_locator[0], &mixed_composition_locator[129]);
|
|
|
|
if(iter != mmap.end()) {
|
|
*reinterpret_cast<Int*>(iter + 0x8C) = amount;
|
|
_mixedComposition = amount;
|
|
return true;
|
|
}
|
|
else {
|
|
_lastError = "The profile save seems to be corrupted or the game didn't release the handle on the file.";
|
|
return false;
|
|
}
|
|
}
|
|
|
|
auto Profile::voidResidue() const -> Int {
|
|
return _voidResidue;
|
|
}
|
|
|
|
auto Profile::getVoidResidue() -> Int {
|
|
auto mmap = Utility::Directory::mapRead(Utility::Directory::join(_profileDirectory, _filename));
|
|
|
|
auto iter = std::search(mmap.begin(), mmap.end(), &void_residue_locator[0], &void_residue_locator[129]);
|
|
|
|
if(iter != mmap.end()) {
|
|
_voidResidue = *reinterpret_cast<const Int*>(iter + 0x8C);
|
|
}
|
|
else {
|
|
_lastError = "The profile save seems to be corrupted or the game didn't release the handle on the file.";
|
|
_voidResidue = -1;
|
|
}
|
|
|
|
return _voidResidue;
|
|
}
|
|
|
|
auto Profile::setVoidResidue(Int amount) -> bool {
|
|
auto mmap = Utility::Directory::map(Utility::Directory::join(_profileDirectory, _filename));
|
|
|
|
auto iter = std::search(mmap.begin(), mmap.end(), &void_residue_locator[0], &void_residue_locator[129]);
|
|
|
|
if(iter != mmap.end()) {
|
|
*reinterpret_cast<Int*>(iter + 0x8C) = amount;
|
|
_voidResidue = amount;
|
|
return true;
|
|
}
|
|
else {
|
|
_lastError = "The profile save seems to be corrupted or the game didn't release the handle on the file.";
|
|
return false;
|
|
}
|
|
}
|
|
|
|
auto Profile::muscularConstruction() const -> Int {
|
|
return _muscularConstruction;
|
|
}
|
|
|
|
auto Profile::getMuscularConstruction() -> Int {
|
|
auto mmap = Utility::Directory::mapRead(Utility::Directory::join(_profileDirectory, _filename));
|
|
|
|
auto iter = std::search(mmap.begin(), mmap.end(), &muscular_construction_locator[0], &muscular_construction_locator[129]);
|
|
|
|
if(iter != mmap.end()) {
|
|
_muscularConstruction = *reinterpret_cast<const Int*>(iter + 0x8C);
|
|
}
|
|
else {
|
|
_lastError = "The profile save seems to be corrupted or the game didn't release the handle on the file.";
|
|
_muscularConstruction = -1;
|
|
}
|
|
|
|
return _muscularConstruction;
|
|
}
|
|
|
|
auto Profile::setMuscularConstruction(Int amount) -> bool {
|
|
auto mmap = Utility::Directory::map(Utility::Directory::join(_profileDirectory, _filename));
|
|
|
|
auto iter = std::search(mmap.begin(), mmap.end(), &muscular_construction_locator[0], &muscular_construction_locator[129]);
|
|
|
|
if(iter != mmap.end()) {
|
|
*reinterpret_cast<Int*>(iter + 0x8C) = amount;
|
|
_muscularConstruction = amount;
|
|
return true;
|
|
}
|
|
else {
|
|
_lastError = "The profile save seems to be corrupted or the game didn't release the handle on the file.";
|
|
return false;
|
|
}
|
|
}
|
|
|
|
auto Profile::mineralExoskeletology() const -> Int {
|
|
return _mineralExoskeletology;
|
|
}
|
|
|
|
auto Profile::getMineralExoskeletology() -> Int {
|
|
auto mmap = Utility::Directory::mapRead(Utility::Directory::join(_profileDirectory, _filename));
|
|
|
|
auto iter = std::search(mmap.begin(), mmap.end(), &mineral_exoskeletology_locator[0], &mineral_exoskeletology_locator[129]);
|
|
|
|
if(iter != mmap.end()) {
|
|
_mineralExoskeletology = *reinterpret_cast<const Int*>(iter + 0x8C);
|
|
}
|
|
else {
|
|
_lastError = "The profile save seems to be corrupted or the game didn't release the handle on the file.";
|
|
_mineralExoskeletology = -1;
|
|
}
|
|
|
|
return _mineralExoskeletology;
|
|
}
|
|
|
|
auto Profile::setMineralExoskeletology(Int amount) -> bool {
|
|
auto mmap = Utility::Directory::map(Utility::Directory::join(_profileDirectory, _filename));
|
|
|
|
auto iter = std::search(mmap.begin(), mmap.end(), &mineral_exoskeletology_locator[0], &mineral_exoskeletology_locator[129]);
|
|
|
|
if(iter != mmap.end()) {
|
|
*reinterpret_cast<Int*>(iter + 0x8C) = amount;
|
|
_mineralExoskeletology = amount;
|
|
return true;
|
|
}
|
|
else {
|
|
_lastError = "The profile save seems to be corrupted or the game didn't release the handle on the file.";
|
|
return false;
|
|
}
|
|
}
|
|
|
|
auto Profile::carbonizedSkin() const -> Int {
|
|
return _carbonizedSkin;
|
|
}
|
|
|
|
auto Profile::getCarbonizedSkin() -> Int {
|
|
auto mmap = Utility::Directory::mapRead(Utility::Directory::join(_profileDirectory, _filename));
|
|
|
|
auto iter = std::search(mmap.begin(), mmap.end(), &carbonized_skin_locator[0], &carbonized_skin_locator[129]);
|
|
|
|
if(iter != mmap.end()) {
|
|
_carbonizedSkin = *reinterpret_cast<const Int*>(iter + 0x8C);
|
|
}
|
|
else {
|
|
_lastError = "The profile save seems to be corrupted or the game didn't release the handle on the file.";
|
|
_carbonizedSkin = -1;
|
|
}
|
|
|
|
return _carbonizedSkin;
|
|
}
|
|
|
|
auto Profile::setCarbonizedSkin(Int amount) -> bool {
|
|
auto mmap = Utility::Directory::map(Utility::Directory::join(_profileDirectory, _filename));
|
|
|
|
auto iter = std::search(mmap.begin(), mmap.end(), &carbonized_skin_locator[0], &carbonized_skin_locator[129]);
|
|
|
|
if(iter != mmap.end()) {
|
|
*reinterpret_cast<Int*>(iter + 0x8C) = amount;
|
|
_carbonizedSkin = amount;
|
|
return true;
|
|
}
|
|
else {
|
|
_lastError = "The profile save seems to be corrupted or the game didn't release the handle on the file.";
|
|
return false;
|
|
}
|
|
}
|