Added much stuff, including working Config System and Test System to Mount pak files and then Load its Content. (Loads Pak File and Mounts it but couldnt load any stuff from my Custom Pak yet)

This commit is contained in:
Unknown
2024-06-26 22:23:20 +02:00
parent f785e17b48
commit cc69714429
13 changed files with 2023 additions and 501 deletions

View File

@ -0,0 +1,415 @@
#include "Config.h"
#include <iostream>
bool ConfigSystem::InternalConfigSystem(std::string ConfigName, std::string Path) {
this->ConfigSettingsInternal = new ConfigSystemInternalSettings();
if (Path == "")
Path = this->ConfigSettingsInternal->ConfigPath;
this->failed = false;
this->LastErrors.clear();
if (!std::filesystem::exists(Path))
{
FailConfig("Couldn't finish Internal Config System, Input Path doesn't Exist!");
return false;
}
try {
std::filesystem::create_directory(Path);
// Get existing config files
for (const auto& entry : std::filesystem::directory_iterator(Path)) {
if (entry.path().extension() == ConfigSettingsInternal->ExtensionConfig) {
Configs.push_back(entry);
}
}
return ActivateConfig(ConfigName, Path);
}
catch (const std::exception& e) {
#if Debug
std::cerr << "Error in InternalConfigSystem: " << e.what() << std::endl;
#endif
return false;
}
}
#if Debug
std::vector<unsigned char> ByteArray;
#endif
bool ConfigSystem::ActivateConfig(std::string ConfigName,std::string Path) {
if (!std::filesystem::exists(Path))
{
FailConfig("Failed to ActivateConfig, Input Path doesn't Exist!");
return false;
}
std::string ConfigFileName = ConfigName + "." + ConfigSettingsInternal->ExtensionConfig;
std::string ConfigPath_ = Path + "/" + ConfigFileName;
std::ifstream ConfigOut(ConfigPath_, std::ios::binary);
std::vector<Field_Config> Fields;
bool result = false;
LastConfigName.clear();
LastPath.clear();
FieldReferences.clear();
if (ConfigOut.is_open()) {
// Get file size
ConfigOut.seekg(0, std::ios::end);
auto ByteNumb = ConfigOut.tellg();
ConfigOut.seekg(0, std::ios::beg);
std::vector<unsigned char> buffer(ByteNumb);
if (!buffer.empty()) {
ConfigOut.read((char*)buffer.data(), ByteNumb);
#if Debug
for (size_t i = 0; i < ByteArray.size(); i++)
{
if (ByteArray[i] != buffer[i]) {
std::cout << "Byte is not the same! At: " << i << "\n";
break;
}
}
std::cout << "Read out Data size of: " << ByteNumb << " Bytes!\n";
#endif
size_t FieldStructSize = sizeof(Field_Config);
size_t BuffSize = buffer.size();
for (size_t i = 0, b_ = 0; i < BuffSize && b_ < ConfigSettingsInternal->MaxFieldCount; b_++) {
try {
Fields.push_back(Field_Config(this->ConfigSettingsInternal, buffer, i));
} catch (const std::exception& e) {
#if Debug
std::cerr << "Error: " << e.what() << "\n";
#endif
break;
}
}
}
ConfigOut.close();
result = true;
}
if (!result) {
std::ofstream some_(ConfigPath_);
if (some_.is_open())
result = true;
some_.close();
}
if (result) {
LastConfigName = ConfigFileName;
LastPath = Path;
this->Fields = Fields;
}
return result;
}
//Writes Data retrieved from Config File to corresponding Fields
bool ConfigSystem::WriteToFields() {
bool wroteField = false;
for (auto& FieldCurrent : FieldReferences) {
if (FieldCurrent.OwningConfigField) {
wroteField = true;
std::memcpy(FieldCurrent.PtrToOwningField, FieldCurrent.OwningConfigField->Data.data(), FieldCurrent.TypeSize);
}
else {
for (const auto& FieldRealCurrent : Fields) {
if (FieldCurrent.ID == FieldRealCurrent.ID) {
wroteField = true;
std::memcpy(FieldCurrent.PtrToOwningField, FieldRealCurrent.Data.data(), FieldCurrent.TypeSize);
break;
}
}
}
}
return wroteField;
}
//Writes Fields to the Config Files
void ConfigSystem::WriteToConfigFile() {
if (LastPath.empty() || failed)
return;
std::ofstream Config(LastPath + "/" + LastConfigName, std::ios::binary);
if (Config.is_open()) {
std::vector<char> DataBuf;
for (auto FieldRef : FieldReferences) {
auto FieldData = std::vector<unsigned char>(FieldRef.FieldToChars());
#if Debug
bool DataValid = false;
try
{
size_t index = 0;
Field_Config test_(FieldData, index);
DataValid = true;
}
catch (const std::exception&)
{
}
std::cout << "Data check: " << (DataValid ? "true" : "false") << "\n";
#endif
DataBuf.insert(DataBuf.begin(), FieldData.begin(), FieldData.end());
}
#if Debug
ByteArray.insert(ByteArray.begin(), DataBuf.begin(), DataBuf.end());
std::cout << "Wrote " << DataBuf.size() << " Bytes to File!\n";
std::cout << std::to_string(DataBuf[352]) << "\n";
std::cout << std::to_string(DataBuf[353]) << "\n";
#endif
Config.clear();
for (size_t i = 0; i < DataBuf.size(); i++)
{
Config << DataBuf[i];
}
//Config.write(DataBuf.data(), DataBuf.size());
Config.close();
}
}
//Call this Function only after Adding the Fields and having all Fields inside a File, else this function just does nothing except write back already existing data to the Config ._.
void ConfigSystem::WriteToConfigFile(int ID) {
if (LastPath.empty())
return;
std::ofstream Config(LastPath + "/" + LastConfigName,std::ios::binary);
if (Config.is_open()) {
std::vector<char> DataBuf;
for (auto Field_ : Fields) {
if (Field_.ID == ID)
continue;
if (DataBuf.size() > 300) {
Config.write(DataBuf.data(), DataBuf.size());
DataBuf.clear();
}
try {
auto out_ = Field_.ToCharType(this->ConfigSettingsInternal);
DataBuf.insert(DataBuf.begin(), out_.begin(), out_.end());
}
catch (const std::exception&) {
}
}
for (auto FieldRef : FieldReferences) {
if (FieldRef.ID == ID) {
auto FieldData = FieldRef.FieldToChars();
DataBuf.insert(DataBuf.begin(), FieldData.begin(), FieldData.end());
break;
}
}
Config.write(DataBuf.data(), DataBuf.size());
Config.close();
}
}
//Resizes the Field that got added to the System. (use for Types that are Dynamically Sized)
void ConfigSystem::ResizeField(size_t Size, int ID)
{
for (auto& RefField : FieldReferences)
{
if (RefField.ID == ID)
{
RefField.TypeSize = Size;
return;
}
}
}
//Returns an list of Errors that happened on the System. (Use this to find out what went wrong to the Config System)
std::vector<std::string> ConfigSystem::GetLastErrors()
{
std::vector<std::string> Errors = LastErrors;
if (LastErrors.size() > 0)
LastErrors.clear();
return Errors;
}
//Checks if from Config Loaded Field exists
bool ConfigSystem::IsFieldExisting(int ID)
{
auto FieldListSize = this->Fields.size();
for (size_t i = 0; i < FieldListSize; i++)
{
if (this->Fields[i].ID == ID) return true;
}
return false;
}
//Calls when something goes wrong and the System cant continue
void ConfigSystem::FailConfig(std::string Reason, bool FailConfigSystem)
{
if(FailConfigSystem)
this->failed = true;
#if Debug == true
std::cout << "[~Error] : " << Reason << "\n";
#else
this->LastErrors.push_back(Reason);
#endif
}
ConfigSystem::ConfigSystem(std::string ConfigName) {
if (!InternalConfigSystem(ConfigName, ""));
FailConfig("Internal ConfigSystem failed!");
}
ConfigSystem::ConfigSystem(std::string ConfigName, std::string path) {
if (!InternalConfigSystem(ConfigName, path));
FailConfig("Internal ConfigSystem failed!");
}
std::wstring ConfigSystem::GetCurrentConfigNameW() {
std::wstring wstr(LastConfigName.length(), L' ');
std::copy(LastConfigName.begin(), LastConfigName.end(), wstr.begin());
return wstr;
}
std::string ConfigSystem::GetCurrentConfigName() {
return LastConfigName;
}
ByteType::ByteType(ConfigSystemInternalSettings* configSettings, std::vector<unsigned char> Data, size_t& Index) {
const int Size_t_Size = sizeof(size_t);
std::string Message = "Couldn't Create ByteType, because ";
unsigned char* Data_Copy = nullptr;
size_t FieldSize = 0;
Data_Copy = (unsigned char*)&FieldSize;
// Check if there's enough data to read
if (Data.size() - Index < Size_t_Size) {
throw std::exception((Message + "Not enough data to read size").c_str());
}
//Get Size of Field
for (size_t i = 0; i < Size_t_Size; i++, Index++) {
Data_Copy[i] = Data[Index];
}
if (FieldSize > configSettings->MaxTypeSize) {
throw std::exception((Message + "Data was Bigger than allowed Size!").c_str());
}
else if (FieldSize <= 0) {
throw std::exception((Message + "Data was Invalid!").c_str());
}
Size = FieldSize;
// Get Data of Field
for (size_t i = 0; i < FieldSize; i++, Index++) {
this->Data.push_back(Data[Index]);
}
}
//Dont call Directly, Internal Config System uses Protection and fail checks, calling raw doesnt use these Checks
Field_Config::Field_Config(ConfigSystemInternalSettings* configSettings, std::vector<unsigned char> Data, size_t& Index)
{
if (Data.size() - 1 < Index + sizeof(size_t) + 1)
throw std::exception(std::string("Data was Invalid, ini" + std::to_string(Data.size()) + ", max:" + std::to_string(Index + sizeof(size_t) + 1)).c_str()); // Throwing a proper exception
ByteType normalType = ByteType(configSettings, Data, Index);
ByteType idType = ByteType(configSettings, Data, Index);
this->Data = normalType.Data;
this->FieldSize = normalType.Size;
this->ID = idType.GetType<int>();
}
std::vector<char> Field_Config::ToCharType(ConfigSystemInternalSettings* configSettings)
{
if (this->FieldSize >= configSettings->MaxTypeSize || this->Data.size() != (this->FieldSize + 1))
throw std::exception("Field Data was faulty, couldnt create Data!");
size_t size_size_t = sizeof(size_t);
size_t size_int = sizeof(int);
size_t total_size = size_size_t + this->FieldSize + size_size_t + size_int;
// Allocate vector with the correct size
std::vector<char> Data_(total_size);
// Copy the TypeSize
std::memcpy(Data_.data(), &this->FieldSize, size_size_t);
// Copy the field data pointed by PtrToOwningField
std::memcpy(Data_.data() + size_size_t, this->Data.data(), this->FieldSize);
// Copy the size of int (though this seems unnecessary)
std::memcpy(Data_.data() + size_size_t + this->FieldSize, &size_int, size_size_t);
// Copy the ID
std::memcpy(Data_.data() + size_size_t + this->FieldSize + size_size_t, &ID, size_int);
return Data_;
}
std::vector<unsigned char> FieldOwning::FieldToChars()
{
size_t size_size_t = sizeof(size_t);
size_t size_int = sizeof(int);
size_t total_size = size_size_t + TypeSize + size_size_t + size_int;
// Allocate vector with the correct size
std::vector<unsigned char> Data_(total_size);
// Copy the TypeSize
std::memcpy(Data_.data(), &TypeSize, size_size_t);
// Copy the field data pointed by PtrToOwningField
std::memcpy(Data_.data() + size_size_t, PtrToOwningField, TypeSize);
// Copy the size of int (though this seems unnecessary)
std::memcpy(Data_.data() + size_size_t + TypeSize, &size_int, size_size_t);
// Copy the ID
std::memcpy(Data_.data() + size_size_t + TypeSize + size_size_t, &ID, size_int);
return Data_;
}