Skip to content
This repository has been archived by the owner on Sep 12, 2021. It is now read-only.

Commit

Permalink
Bugfixes for #22
Browse files Browse the repository at this point in the history
  • Loading branch information
DronCode committed Mar 1, 2020
1 parent 8df84e8 commit d497b45
Show file tree
Hide file tree
Showing 7 changed files with 106 additions and 54 deletions.
113 changes: 65 additions & 48 deletions HM3CoreKill/HM3CoreKill/ck/HM3FreeFileSystemLocatorProxy.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,23 @@ namespace ck {

int HM3FreeFileSystemLocatorProxy::readFileProvider(const char* name, void* dest, int fileSize, int unk1)
{
typedef int(__thiscall* FsZip_read_t)(ioi::hm3::FsZip_t*, const char*, void*, int, int);
// --- copy pack info before pthis not corrupted ---
int zipPackagePathLength = 0;
const int zipPackagePathBuffLength = 512;
char zipPackagePath[zipPackagePathBuffLength] = { 0 };

if (this->m_zipFilePath && reinterpret_cast<DWORD>(this->m_zipFilePath) > 0xFFFFF)
{
zipPackagePathLength = strlen(this->m_zipFilePath);
memcpy(zipPackagePath, this->m_zipFilePath, zipPackagePathLength);
}
else
{
zipPackagePathLength = strlen(this->m_missionZipFilePath);
memcpy(zipPackagePath, this->m_missionZipFilePath, zipPackagePathLength);
}

// --- continue ---
auto sys = ioi::hm3::getGlacierInterface<ioi::hm3::ZSysInterfaceWintel>(ioi::hm3::SysInterface);

// --- detect scene ---
Expand Down Expand Up @@ -81,10 +97,6 @@ namespace ck {
}
memcpy((void*)sceneIdBuffer, sys->m_currentScene + missionNameStartsAt, missionNameLength);
// --- detect pack ---
const char* zipPackagePath = (this->m_zipFilePath ? this->m_zipFilePath : this->m_missionZipFilePath);
HM3_ASSERT(zipPackagePath != nullptr, "FATAL ERROR AT IOI ZIP FS");
const int zipPackagePathLength = strlen(zipPackagePath);

const int packageNameLength = 32;
char packageName[packageNameLength] = { 0 };

Expand All @@ -98,63 +110,68 @@ namespace ck {
}
zipPackageStartPtr = i;
}
HM3_ASSERT(zipPackageEndPtr - zipPackageStartPtr < packageNameLength, "ZIP package name length is out of bounds!");
memcpy((void*)&packageName, zipPackagePath + zipPackageStartPtr, zipPackageEndPtr - zipPackageStartPtr - 3);
// --- detect various file ---
std::string fileName(name);
bool fileNameResolved = false;

if (fileName[0] == '*')
if (zipPackageStartPtr != -1 && zipPackageEndPtr - zipPackageStartPtr < packageNameLength) //In some cases we have corrupted environment. In that case best solution is use ZIP FS.
{
// Oh shit, IOI, I really hate you!
// Here we need to find file by passed mask!
const int maskedPathLength = 512;
char maskedPath[maskedPathLength] = { 0 };
memcpy((void*)&packageName, zipPackagePath + zipPackageStartPtr, zipPackageEndPtr - zipPackageStartPtr - 3);
// --- detect various file ---
std::string fileName(name);
bool fileNameResolved = false;

if (fileName[0] == '*')
{
// Oh shit, IOI, I really hate you!
// Here we need to find file by passed mask!
const int maskedPathLength = 512;
char maskedPath[maskedPathLength] = { 0 };

//snprintf(maskedPath, maskedPathLength, "%s\\UnpackedScenes\\%s\\%s\\%s", currentPath, sceneIdBuffer, packageName, fileName);
snprintf(maskedPath, maskedPathLength, "UnpackedScenes\\%s\\%s", sceneIdBuffer, packageName);

std::string foundFile = findFileInFolderRecursively(maskedPath, fileName.c_str() + 1);
if (!foundFile.empty())
{
fileName = foundFile;
fileNameResolved = true;
}
//snprintf(maskedPath, maskedPathLength, "%s\\UnpackedScenes\\%s\\%s\\%s", currentPath, sceneIdBuffer, packageName, fileName);
snprintf(maskedPath, maskedPathLength, "UnpackedScenes\\%s\\%s", sceneIdBuffer, packageName);

}
// --- detect full path to pure fs ---
std::string finalFilePath;
std::string foundFile = findFileInFolderRecursively(maskedPath, fileName.c_str() + 1);
if (!foundFile.empty())
{
fileName = foundFile;
fileNameResolved = true;
}

if (!fileNameResolved)
{
const int fullPathBufferSize = 512;
char fullPathBuffer[fullPathBufferSize];
snprintf(fullPathBuffer, fullPathBufferSize, "UnpackedScenes\\%s\\%s\\%s", sceneIdBuffer, packageName, fileName.c_str());
finalFilePath = fullPathBuffer;
}
else {
finalFilePath = fileName;
}
}
// --- detect full path to pure fs ---
std::string finalFilePath;

FILE* fileHandle = fopen(finalFilePath.c_str(), "rb");
if (fileHandle)
{
if (fileSize == 0)
if (!fileNameResolved)
{
// The game engine doesn't know the actual size of file and pass zero to us. We must explore how much bytes will be used by file in memory space.
fseek(fileHandle, 0L, SEEK_END); //move to end
fileSize = ftell(fileHandle); //save the endpoint
rewind(fileHandle); //move to start of file
const int fullPathBufferSize = 512;
char fullPathBuffer[fullPathBufferSize];
snprintf(fullPathBuffer, fullPathBufferSize, "UnpackedScenes\\%s\\%s\\%s", sceneIdBuffer, packageName, fileName.c_str());
finalFilePath = fullPathBuffer;
}
else {
finalFilePath = fileName;
}

const int readyBytes = fread(dest, 1, fileSize, fileHandle);
fclose(fileHandle);
HM3_DEBUG("[0x%.8X] FsZip::readContents| read file from raw fs %s (ready bytes %d)\n", reinterpret_cast<int>(this), finalFilePath.c_str(), readyBytes);
return readyBytes;
FILE* fileHandle = fopen(finalFilePath.c_str(), "rb");
if (fileHandle)
{
if (fileSize == 0)
{
// The game engine doesn't know the actual size of file and pass zero to us
// We must explore how much bytes will be used by file in memory space.
fseek(fileHandle, 0L, SEEK_END); //move to end
fileSize = ftell(fileHandle); //save the endpoint
rewind(fileHandle); //move to start of file
}

const int readyBytes = fread(dest, 1, fileSize, fileHandle);
fclose(fileHandle);
HM3_DEBUG("[0x%.8X] FsZip::readContents| read file from raw fs %s (ready bytes %d)\n", reinterpret_cast<int>(this), finalFilePath.c_str(), readyBytes);
return readyBytes;
}
}

// original code
typedef int(__thiscall* FsZip_read_t)(ioi::hm3::FsZip_t*, const char*, void*, int, int);
FsZip_read_t original = (FsZip_read_t)HM3Offsets::FsZip_ReadMethodFunc;
int result = original(reinterpret_cast<ioi::hm3::FsZip_t*>(this), name, dest, fileSize, unk1);
HM3_DEBUG("[0x%.8X] FsZip::readContents| read from ZIP FS file %s result put at 0x%.8X [%d;%d] => %d\n", reinterpret_cast<int>(this), name, dest, fileSize, unk1, result);
Expand Down
4 changes: 2 additions & 2 deletions HM3CoreKill/HM3CoreKill/ck/HM3FreeFileSystemLocatorProxy.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,12 @@ namespace ck

class HM3FreeFileSystemLocatorProxy
{
public:
char pad_0000[16]; //0x0000
char* m_missionZipFilePath; //0x0010
char pad_0014[100]; //0x0014
char* m_zipFilePath; //0x0078

public:

static std::string findFileInFolderRecursively(const std::string& folder, const std::string& file);

int readFileProvider(const char* name, void* dest, int fileSize, int unk1);
Expand Down
16 changes: 16 additions & 0 deletions HM3CoreKill/HM3CoreKill/ck/HM3Game.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -277,6 +277,22 @@ void HM3Game::setupFsZipHook()
x86_popfd,
x86_popad
});

/*
Maybe later but now now!
HM3Function::hookFunction<void(__stdcall*)(DWORD), 6>(
HM3_PROCESS_NAME,
HM3Offsets::FsZip_Destructor,
(DWORD)FsZip_Destructor,
{
x86_pushad,
x86_pushfd,
x86_push_ecx
},
{
x86_popfd,
x86_popad
});*/
}

void HM3Game::onD3DInitialized(IDirect3DDevice9* device)
Expand Down
16 changes: 16 additions & 0 deletions HM3CoreKill/HM3CoreKill/ck/HM3Hooks.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,22 @@ void __stdcall ZGlacier_OnSTDOBJAttached(DWORD* unknownInstance)
void __stdcall FsZip_Constructed(ioi::hm3::FsZip_t* instance)
{
ck::HM3FreeFileSystemLocatorProxy* proxy = reinterpret_cast<ck::HM3FreeFileSystemLocatorProxy*>(instance);

//proxy->m_missionZipFilePath = nullptr;
//proxy->m_zipFilePath = nullptr;

HM3_DEBUG("FsZip_t created at 0x%.8X | Hook read() method\n", instance);
HM3Function::hookVFTable(proxy, HM3Offsets::FsZip_ReadMethodIndex, &ck::HM3FreeFileSystemLocatorProxy::readFileProvider, false);
}

void __stdcall FsZip_Destructor(ioi::hm3::FsZip_t* instance)
{
ck::HM3FreeFileSystemLocatorProxy* proxy = reinterpret_cast<ck::HM3FreeFileSystemLocatorProxy*>(instance);

proxy->m_missionZipFilePath = nullptr;
proxy->m_zipFilePath = nullptr;

// Just recover vftable here!
HM3_DEBUG("FsZip_t restore vftable for at 0x%.8X\n", proxy);
HM3Function::hookVFTable(reinterpret_cast<DWORD>(proxy), HM3Offsets::FsZip_ReadMethodIndex, HM3Offsets::FsZip_ReadMethodFunc, false); //restore back!
}
4 changes: 3 additions & 1 deletion HM3CoreKill/HM3CoreKill/ck/HM3Hooks.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,4 +48,6 @@ void __stdcall CMapObject_OnCreate(ioi::hm3::CMapObject* instance);

void __stdcall ZGlacier_OnSTDOBJAttached(DWORD* unknownInstance);

void __stdcall FsZip_Constructed(ioi::hm3::FsZip_t* instance);
void __stdcall FsZip_Constructed(ioi::hm3::FsZip_t* instance);

void __stdcall FsZip_Destructor(ioi::hm3::FsZip_t* instance);
6 changes: 3 additions & 3 deletions HM3CoreKill/HM3CoreKill/ck/HM3InGameTools.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -293,7 +293,7 @@ namespace ck
auto levelControl = gameData->m_LevelControl;
auto hitman3 = gameData->m_Hitman3;

auto printRTTR = [](ioi::hm3::ZGlacierRTTI* rtti) {
auto printRTTI = [](ioi::hm3::ZGlacierRTTI* rtti) {
ImGui::Separator();
ImGui::Text(" RTTI : ");
ImGui::Text(" ID : %d", rtti->TypeID);
Expand Down Expand Up @@ -330,10 +330,10 @@ namespace ck

ImGui::Text("Level control : "); ImGui::SameLine(0.f, 10.f); ImGui::TextColored(ImVec4(1.f, 1.f, 0.f, 1.f), "0x%.8X", levelControl);
ioi::hm3::ZGlacierRTTI* rtti = ioi::hm3::getTypeInfo(levelControl);
printRTTR(rtti);
printRTTI(rtti);

ImGui::Text("Map : "); ImGui::SameLine(0.f, 10.f); ImGui::TextColored(ImVec4(1.f, 1.f, 0.f, 1.f), "0x%.8X", gameData->m_IngameMap);
printRTTR(gameData->m_IngameMap->m_RTTI);
printRTTI(gameData->m_IngameMap->m_RTTI);
ImGui::Text(" isShowed : %s", (gameData->m_IngameMap->m_showed ? "Yes" : "No"));
if (gameData->m_IngameMap->m_showed)
{
Expand Down
1 change: 1 addition & 0 deletions HM3CoreKill/HM3CoreKill/ck/HM3Offsets.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ namespace HM3Offsets
static const FuncAddr_t Global_OnAttachSTDOBJ_OrgEnding = 0x004E6B16;
static const FuncAddr_t Global_OnAttachSTDOBJ_NewEnding = Global_OnAttachSTDOBJ_OrgEnding + 0x5;
static const FuncAddr_t FsZip_Constructor = 0x0042D0FC;
static const FuncAddr_t FsZip_Destructor = 0x0042D137;
static const FuncAddr_t FsZip_ReadMethodFunc = 0x0042C470;

static const Index_t CMapObject_OnProcessMethodIndex = 29;
Expand Down

0 comments on commit d497b45

Please sign in to comment.