diff --git a/src/Components/Modules/AssetHandler.cpp b/src/Components/Modules/AssetHandler.cpp index 9a9fce6e..756a3354 100644 --- a/src/Components/Modules/AssetHandler.cpp +++ b/src/Components/Modules/AssetHandler.cpp @@ -116,15 +116,13 @@ namespace Components bool AssetHandler::IsAssetEligible(Game::XAssetType type, Game::XAssetHeader *asset) { const char* name = Game::DB_GetXAssetNameHandlers[type](asset); + if (!name) return false; - // Should we perform the null check before or after this? if (Flags::HasFlag("entries")) { OutputDebugStringA(Utils::String::VA("%s: %d: %s\n", FastFiles::Current().data(), type, name)); } - if (!name) return false; - bool restrict = false; AssetHandler::RestrictSignal(type, *asset, name, &restrict); @@ -190,9 +188,7 @@ namespace Components } offset->pointer = *reinterpret_cast(pointer); - - //Game::XAssetHeader zob{ offset->pointer }; - } + } void AssetHandler::ZoneSave(Game::XAsset asset, ZoneBuilder::Zone* builder) { diff --git a/src/Components/Modules/RawFiles.cpp b/src/Components/Modules/RawFiles.cpp index cc37184f..54b80d7b 100644 --- a/src/Components/Modules/RawFiles.cpp +++ b/src/Components/Modules/RawFiles.cpp @@ -25,5 +25,27 @@ namespace Components #ifndef DEBUG QuickPatch::OnFrame(AntiCheat::FlagIntegrityCheck); #endif + + Command::Add("dumpraw", [] (Command::Params params) + { + if (params.Length() < 2) + { + Logger::Print("Specify a filename!\n"); + return; + } + + std::string filename = params[1]; + const char* data = Game::LoadModdableRawfile(0, filename.data()); + + if (data) + { + Utils::IO::WriteFile("raw/" + filename, data); + Logger::Print("File '%s' written to raw!\n", filename.data()); + } + else + { + Logger::Print("File '%s' does not exist!\n", filename.data()); + } + }); } } diff --git a/src/Components/Modules/Zones.cpp b/src/Components/Modules/Zones.cpp index 42ba92f9..982ed86f 100644 --- a/src/Components/Modules/Zones.cpp +++ b/src/Components/Modules/Zones.cpp @@ -523,15 +523,15 @@ namespace Components Utils::Memory::Allocator allocator; Game::snd_alias_t* tempSounds = allocator.AllocateArray(count); - for (int i = 0; i < count; ++i) + for (int i = 0; i < count; ++i) { char* src = &buffer[i * 108]; - std::memcpy(&tempSounds[i], src + 0, 60); + std::memcpy(&tempSounds[i], src + 0, 60); std::memcpy(&tempSounds[i].pad2[36], src + 68, 20); std::memcpy(&tempSounds[i].pad2[56], src + 88, 20); - AssetHandler::Relocate(src + 0, buffer + (i * 100) + 0, 60); + AssetHandler::Relocate(src + 0, buffer + (i * 100) + 0, 60); AssetHandler::Relocate(src + 68, buffer + (i * 100) + 60, 20); AssetHandler::Relocate(src + 88, buffer + (i * 100) + 80, 20); } @@ -554,7 +554,7 @@ namespace Components bool Zones::LoadVehicleDef(bool atStreamStart, char* buffer) { bool result = Game::Load_Stream(atStreamStart, buffer, 788); - + Game::VehicleDef vehicle[2]; std::memcpy(vehicle, &buffer[0], 400); std::memcpy(&vehicle->pad[404], &buffer[400], 388); @@ -671,6 +671,7 @@ namespace Components memcpy(buffer + 28, buffer + 32, 4); AssetHandler::Relocate(buffer + 32, buffer + 28, 4); + //AssetHandler::Relocate(buffer + 28, buffer + 32, 4); // There is no point in storing the LoadDef return result; } @@ -718,7 +719,7 @@ namespace Components Utils::Hook::Set(0x418B30, (patch) ? 43 : Game::ASSET_TYPE_ADDON_MAP_ENTS); // Change block for images - //Utils::Hook::Set(0x4C13E4, ((Zones::ZoneVersion >= 332) ? 3 : 0)); + Utils::Hook::Set(0x4D3224, ((Zones::ZoneVersion >= 332) ? 3 : 0)); if (patch) { diff --git a/src/Game/Functions.hpp b/src/Game/Functions.hpp index a5a1d6aa..8e0d025f 100644 --- a/src/Game/Functions.hpp +++ b/src/Game/Functions.hpp @@ -353,7 +353,7 @@ namespace Game typedef void(__cdecl * Live_ParsePlaylists_t)(const char* data); extern Live_ParsePlaylists_t Live_ParsePlaylists; - typedef void* (__cdecl * LoadModdableRawfile_t)(int a1, const char* filename); + typedef char* (__cdecl * LoadModdableRawfile_t)(int a1, const char* filename); extern LoadModdableRawfile_t LoadModdableRawfile; typedef int(__cdecl * PC_ReadToken_t)(source_t*, token_t*); diff --git a/src/STDInclude.hpp b/src/STDInclude.hpp index 3b50f7d4..70df4e60 100644 --- a/src/STDInclude.hpp +++ b/src/STDInclude.hpp @@ -86,6 +86,7 @@ #include "Utils\IO.hpp" #include "Utils\CSV.hpp" +#include "Utils\Chain.hpp" #include "Utils\Utils.hpp" #include "Utils\WebIO.hpp" #include "Utils\Memory.hpp" diff --git a/src/Utils/Chain.hpp b/src/Utils/Chain.hpp new file mode 100644 index 00000000..c7e9b7cb --- /dev/null +++ b/src/Utils/Chain.hpp @@ -0,0 +1,151 @@ +namespace Utils +{ + template + class Chain + { + public: + class Entry + { + private: + std::shared_ptr Object; + std::shared_ptr Next; + + public: + bool HasNext() + { + return (this->Next.use_count() > 0); + } + + bool IsValid() + { + return (this->Object.use_count() > 0); + } + + void Set(T object) + { + this->Object = std::shared_ptr(new T()); + *this->Object.get() = object; + } + + std::shared_ptr Get() + { + return this->Object; + } + + Entry GetNext() + { + if (this->HasNext()) + { + return *(this->Next.get()); + } + else + { + return Entry(); + } + } + + std::shared_ptr GetNextEntry() + { + return this->Next; + } + + void SetNextEntry(std::shared_ptr entry) + { + this->Next = entry; + } + + T *operator->() + { + return (this->Object.get()); + } + + Entry& operator++ () + { + *this = this->GetNext(); + return *this; + } + + Entry operator++ (int) + { + Entry result = *this; + this->operator++(); + return result; + } + }; + + private: + std::mutex Mutex; + Entry Object; + + public: + void Add(T object) + { + this->Mutex.lock(); + + if (!this->Empty()) + { + // Create new chain entry + std::shared_ptr currentObject = std::shared_ptr(new Entry); + *currentObject.get() = this->Object; + + // Add it to the chain + this->Object = Entry(); + this->Object.SetNextEntry(currentObject); + } + + this->Object.Set(object); + + this->Mutex.unlock(); + } + + void Remove(std::shared_ptr object) + { + this->Mutex.lock(); + + if (!this->Empty()) + { + if (this->Object.Get().get() == object.get()) + { + this->Object = this->Object.GetNext(); + } + else if(this->Object.HasNext()) + { + for (auto entry = this->Object; entry.IsValid(); ++entry) + { + auto next = entry.GetNext(); + + if (next.IsValid() && next.Get().get() == object.get()) + { + *entry.GetNextEntry().get() = next.GetNext(); + } + } + } + } + + this->Mutex.unlock(); + } + + void Remove(Entry entry) + { + if (entry.IsValid()) + { + this->Remove(entry.Get()); + } + } + + bool Empty() + { + return !this->Object.IsValid(); + } + + Entry Begin() + { + return this->Object; + } + + void Clear() + { + this->Object = Entry(); + } + }; +} diff --git a/src/Utils/IO.cpp b/src/Utils/IO.cpp index 5fdf05a4..33e6a21c 100644 --- a/src/Utils/IO.cpp +++ b/src/Utils/IO.cpp @@ -11,6 +11,8 @@ namespace Utils void WriteFile(std::string file, std::string data) { + CreateDirectory(file.substr(0, file.find_last_of("/\\"))); + std::ofstream stream(file, std::ios::binary); if (stream.is_open())