[demo] Remove hash verification functions from the game. See Issue #68. Release Build 11565.
This commit is contained in:
parent
b9ea6d1432
commit
63ba75400c
@ -112,6 +112,10 @@
|
||||
<SubType>
|
||||
</SubType>
|
||||
</ClCompile>
|
||||
<ClCompile Include="FileTests.cpp">
|
||||
<SubType>
|
||||
</SubType>
|
||||
</ClCompile>
|
||||
<ClCompile Include="GeometryTests.cpp" />
|
||||
<ClCompile Include="ItemTests.cpp">
|
||||
<SubType>
|
||||
|
@ -78,6 +78,9 @@
|
||||
<ClCompile Include="BuffTests.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="FileTests.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="GameHelper.h">
|
||||
|
113
Adventures in Lestoria Tests/FileTests.cpp
Normal file
113
Adventures in Lestoria Tests/FileTests.cpp
Normal file
@ -0,0 +1,113 @@
|
||||
#pragma region License
|
||||
/*
|
||||
License (OLC-3)
|
||||
~~~~~~~~~~~~~~~
|
||||
|
||||
Copyright 2024 Joshua Sigona <sigonasr2@gmail.com>
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions or derivations of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions or derivative works in binary form must reproduce the above
|
||||
copyright notice. This list of conditions and the following disclaimer must be
|
||||
reproduced in the documentation and/or other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of the copyright holder nor the names of its contributors may
|
||||
be used to endorse or promote products derived from this software without specific
|
||||
prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
|
||||
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
|
||||
SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
|
||||
TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
||||
BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
SUCH DAMAGE.
|
||||
|
||||
Portions of this software are copyright © 2024 The FreeType
|
||||
Project (www.freetype.org). Please see LICENSE_FT.txt for more information.
|
||||
All rights reserved.
|
||||
*/
|
||||
#pragma endregion
|
||||
#include "CppUnitTest.h"
|
||||
#include "AdventuresInLestoria.h"
|
||||
#include "config.h"
|
||||
#include "ItemDrop.h"
|
||||
#include "Tutorial.h"
|
||||
#include "DamageNumber.h"
|
||||
#include "GameHelper.h"
|
||||
#include "SaveFile.h"
|
||||
#include <ranges>
|
||||
|
||||
using namespace Microsoft::VisualStudio::CppUnitTestFramework;
|
||||
using namespace olc::utils;
|
||||
|
||||
INCLUDE_MONSTER_DATA
|
||||
INCLUDE_game
|
||||
INCLUDE_GFX
|
||||
INCLUDE_DAMAGENUMBER_LIST
|
||||
INCLUDE_MONSTER_LIST
|
||||
INCLUDE_INITIALIZEGAMECONFIGURATIONS
|
||||
|
||||
namespace FileTests
|
||||
{
|
||||
TEST_CLASS(FileTest)
|
||||
{
|
||||
public:
|
||||
std::unique_ptr<AiL>testGame;
|
||||
#pragma region Setup Functions
|
||||
void SetupTest(){
|
||||
InitializeGameConfigurations();
|
||||
testGame.reset(new AiL(true));
|
||||
ItemAttribute::Initialize();
|
||||
ItemInfo::InitializeItems();
|
||||
testGame->InitializeGraphics();
|
||||
testGame->InitializeClasses();
|
||||
sig::Animation::InitializeAnimations();
|
||||
testGame->InitializeDefaultKeybinds();
|
||||
testGame->InitializePlayer();
|
||||
sig::Animation::SetupPlayerAnimations();
|
||||
Menu::InitializeMenus();
|
||||
Tutorial::Initialize();
|
||||
Stats::InitializeDamageReductionTable();
|
||||
|
||||
GameState::Initialize();
|
||||
GameState::STATE=GameState::states.at(States::State::GAME_RUN);
|
||||
testGame->ResetLevelStates();
|
||||
|
||||
#pragma region Setup a fake test map
|
||||
game->MAP_DATA["CAMPAIGN_1_1"];
|
||||
game->_SetCurrentLevel("CAMPAIGN_1_1");
|
||||
ItemDrop::ClearDrops();
|
||||
#pragma endregion
|
||||
|
||||
MonsterData testMonsterData{"TestName","Test Monster",30,10,5,{MonsterDropData{"Health Potion",100.f,1,1}},200.f};
|
||||
MONSTER_DATA["TestName"]=testMonsterData;
|
||||
|
||||
Menu::themes.SetInitialized();
|
||||
GFX.SetInitialized();
|
||||
DAMAGENUMBER_LIST.clear();
|
||||
}
|
||||
void SetupMockMap(){
|
||||
game->MAP_DATA["CAMPAIGN_1_1"];
|
||||
ItemDrop::ClearDrops();
|
||||
}
|
||||
#pragma endregion
|
||||
|
||||
TEST_METHOD_INITIALIZE(FileTestInitialize){
|
||||
SetupTest();
|
||||
SetupMockMap();
|
||||
}
|
||||
TEST_METHOD_CLEANUP(CleanupFileTests){
|
||||
testGame->EndGame();
|
||||
testGame->OnUserUpdate(0.f);
|
||||
testGame.reset();
|
||||
}
|
||||
};
|
||||
}
|
@ -81,7 +81,7 @@ const size_t SaveFile::GetOnlineSaveFileCount(){
|
||||
return count;
|
||||
}
|
||||
|
||||
const void SaveFile::SaveGame(){
|
||||
const bool SaveFile::SaveGame(){
|
||||
game->saveGameDisplayTime=6.f;
|
||||
|
||||
game->SetQuitAllowed(false);
|
||||
@ -206,41 +206,7 @@ const void SaveFile::SaveGame(){
|
||||
}
|
||||
}
|
||||
|
||||
#pragma region Save save file and prep File Hash
|
||||
bool fileNoHashWrittenSuccessfully{false};
|
||||
bool fileHashWrittenSuccessfully{false};
|
||||
while(!fileNoHashWrittenSuccessfully||!fileHashWrittenSuccessfully){
|
||||
fileNoHashWrittenSuccessfully=false;
|
||||
fileHashWrittenSuccessfully=false;
|
||||
|
||||
saveFile["Hash"].SetString("");
|
||||
fileNoHashWrittenSuccessfully=utils::datafile::Write(saveFile,"save_file_path"_S+std::format("save.{:04}",saveFileID)+".tmp");
|
||||
|
||||
auto trim = [](std::string& s)
|
||||
{
|
||||
s.erase(0, s.find_first_not_of(" \\\t\n\r\f\v"));
|
||||
s.erase(s.find_last_not_of(" \\\t\n\r\f\v") + 1);
|
||||
for(int marker=0;marker<s.length();marker++){
|
||||
char&c{s[marker]};
|
||||
if(c=='\\'){
|
||||
s.erase(marker,1U);
|
||||
marker--;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
std::string fileHash=util::GetHash("save_file_path"_S+std::format("save.{:04}",saveFileID)+".tmp");
|
||||
trim(fileHash); //It's possible the expected file hash has a space at the end/beginning that gets stripped out. We want to trim and match that string.
|
||||
saveFile["Hash"].SetString(fileHash);
|
||||
|
||||
fileHashWrittenSuccessfully=utils::datafile::Write(saveFile,"save_file_path"_S+std::format("save.{:04}",saveFileID)); //Once the hash has been computed and added, save the file a second time.
|
||||
}
|
||||
std::error_code result;
|
||||
const bool succeeded{std::filesystem::remove("save_file_path"_S+std::format("save.{:04}",saveFileID)+".tmp",result)};
|
||||
if(!succeeded)LOG(std::format("WARNING! Could not delete temporary save file. Error: {}",result.message()));
|
||||
#pragma endregion
|
||||
//WARNING! DO NOT WRITE ANY CODE BELOW HERE!!!!! THE HASH HAS ALREADY BEEN WRITTEN.
|
||||
//FILES BECOME CORRUPTED IF THE SAVE FILE IS MODIFIED FROM HERE ONWARDS.
|
||||
utils::datafile::Write(saveFile,"save_file_path"_S+std::format("save.{:04}",saveFileID));
|
||||
}
|
||||
while(!utils::datafile::Write(saveSystemFile,"save_file_path"_S+"system.conf"));
|
||||
utils::datafile metadata;
|
||||
@ -338,63 +304,16 @@ const void SaveFile::SaveGame(){
|
||||
#else
|
||||
game->SetQuitAllowed(true);
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
#define HASH_VERIFICATION_REQUIRED true
|
||||
|
||||
void SaveFile::LoadFile(){
|
||||
const bool SaveFile::LoadFile(){
|
||||
utils::datafile loadFile;
|
||||
|
||||
std::string loadFilename="save_file_path"_S+std::format("save.{:04}",saveFileID);
|
||||
|
||||
if(std::filesystem::exists(loadFilename)){
|
||||
utils::datafile::Read(loadFile,"save_file_path"_S+std::format("save.{:04}",saveFileID));
|
||||
if(!ADMIN_MODE&&HASH_VERIFICATION_REQUIRED){
|
||||
if(!loadFile.HasProperty("Hash")){
|
||||
LOG(std::format("WARNING! Filehash for file {} does not exist!","save_file_path"_S+std::format("save.{:04}",saveFileID)));
|
||||
return;
|
||||
}
|
||||
if(loadFile.HasProperty("Hash")){
|
||||
std::string expectedFileHash=loadFile["Hash"].GetString();
|
||||
bool fileNoHashWrittenSuccessfully{false};
|
||||
bool fileHashWrittenSuccessfully{false};
|
||||
while(!fileNoHashWrittenSuccessfully||!fileHashWrittenSuccessfully){
|
||||
fileNoHashWrittenSuccessfully=false;
|
||||
fileHashWrittenSuccessfully=false;
|
||||
|
||||
loadFile["Hash"].SetString("");
|
||||
fileNoHashWrittenSuccessfully=utils::datafile::Write(loadFile,"save_file_path"_S+std::format("save.{:04}",saveFileID)+".tmp");
|
||||
|
||||
auto trim = [](std::string& s)
|
||||
{
|
||||
s.erase(0, s.find_first_not_of(" \t\n\r\f\v"));
|
||||
s.erase(s.find_last_not_of(" \t\n\r\f\v") + 1);
|
||||
for(int marker=0;marker<s.length();marker++){
|
||||
char&c{s[marker]};
|
||||
if(c=='\\'){
|
||||
s.erase(marker,1U);
|
||||
marker--;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
std::string fileHash=util::GetHash("save_file_path"_S+std::format("save.{:04}",saveFileID)+".tmp");
|
||||
trim(fileHash); //It's possible the expected file hash has a space at the end/beginning that gets stripped out. We want to trim and match that string.
|
||||
|
||||
if(!ADMIN_MODE&&expectedFileHash!=fileHash){
|
||||
LOG(std::format("WARNING! Filehash for file {} was not identified as proper! Will not load this file!","save_file_path"_S+std::format("save.{:04}",saveFileID)));
|
||||
return;
|
||||
}
|
||||
|
||||
loadFile["Hash"].SetString(expectedFileHash); //Now write the hash back into the file since we tampered with it.
|
||||
fileHashWrittenSuccessfully=utils::datafile::Write(loadFile,"save_file_path"_S+std::format("save.{:04}",saveFileID));
|
||||
}
|
||||
|
||||
std::error_code result;
|
||||
const bool succeeded{std::filesystem::remove("save_file_path"_S+std::format("save.{:04}",saveFileID)+".tmp",result)};
|
||||
if(!succeeded)LOG(std::format("WARNING! Could not delete temporary save file. Error: {}",result.message()));
|
||||
}
|
||||
}
|
||||
game->ResetGame();
|
||||
for(auto&[key,data]:loadFile["Items"].GetOrderedKeys()){
|
||||
std::weak_ptr<Item>newItem=Inventory::AddItem(data["Item Name"].GetString(),data["Amt"].GetInt());
|
||||
@ -503,8 +422,10 @@ void SaveFile::LoadFile(){
|
||||
}
|
||||
|
||||
GameState::ChangeState(States::OVERWORLD_MAP,0.5f);
|
||||
return true;
|
||||
}else{
|
||||
LOG(std::format("WARNING! File {} does not exist for loading!","save_file_path"_S+std::format("save.{:04}",saveFileID)));
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -63,9 +63,9 @@ public:
|
||||
static void SetOnlineMode(bool online);
|
||||
static const std::string_view GetUserID();
|
||||
static const void SetUserID(std::string_view userID);
|
||||
static const void SaveGame();
|
||||
static const bool SaveGame();
|
||||
static const void LoadGame();
|
||||
static void LoadFile();
|
||||
static const bool LoadFile();
|
||||
static const void SetSaveFileID(size_t saveFileID);
|
||||
static const void SetSaveFileOfflineID_TransitionToOverworldMap();
|
||||
//Called whenever the save game data is updated.
|
||||
|
@ -39,7 +39,7 @@ All rights reserved.
|
||||
#define VERSION_MAJOR 1
|
||||
#define VERSION_MINOR 3
|
||||
#define VERSION_PATCH 0
|
||||
#define VERSION_BUILD 11563
|
||||
#define VERSION_BUILD 11565
|
||||
|
||||
#define stringify(a) stringify_(a)
|
||||
#define stringify_(a) #a
|
||||
|
Binary file not shown.
Loading…
x
Reference in New Issue
Block a user