Skip to content

Commit

Permalink
project restructure to avoid file replacement
Browse files Browse the repository at this point in the history
  • Loading branch information
ThirteenAG committed May 28, 2023
1 parent 3c59c4d commit 9d35be5
Show file tree
Hide file tree
Showing 68 changed files with 211 additions and 45 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -329,3 +329,5 @@ ASALocalRun/

# MFractors (Xamarin productivity tool) working folder
.mfractor/

data/**/*.img
5 changes: 5 additions & 0 deletions buildimg.bat
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
cd tools
cd IMGConsole
fastman92ImgConsole32.exe -script "..\..\data\update\GTAIV.EFLC.FusionFix\cdimagemake.ims"
cd ..
cd ..
Binary file removed data/TBoGT/pc/models/cdimages/vehicles.img
Binary file not shown.
Binary file removed data/common/GTAIV.EFLC.FusionFix.img
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
9 changes: 9 additions & 0 deletions data/update/GTAIV.EFLC.FusionFix/cdimagemake.ims
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
-create "GTAIV.EFLC.FusionFix.img" "3" "IMG_VERSION_3_ENCRYPTION_TYPE_NONE"
-importFromDirectory "GTAIV.EFLC.FusionFix"
-rebuild
-close

-create "TBOGT.FixedVehicles.img" "3" "IMG_VERSION_3_ENCRYPTION_TYPE_NONE"
-importFromDirectory "TBOGT.FixedVehicles"
-rebuild
-close
2 changes: 1 addition & 1 deletion premake5.bat
Original file line number Diff line number Diff line change
@@ -1 +1 @@
premake5 vs2019
premake5 vs2022
Binary file modified premake5.exe
Binary file not shown.
24 changes: 1 addition & 23 deletions readme.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
[![Build status](https://ci.appveyor.com/api/projects/status/wwokiviriq3m52t6?svg=true)](https://ci.appveyor.com/project/ThirteenAG/gtaiv-eflc-fusionfix)
[![Build Status](https://dev.azure.com/thirteenag/GTAIV.EFLC.FusionFix/_apis/build/status/ThirteenAG.GTAIV.EFLC.FusionFix?branchName=master)](https://dev.azure.com/thirteenag/GTAIV.EFLC.FusionFix/_build/latest?definitionId=1&branchName=master)
[![Discord](https://img.shields.io/badge/chat-on%20discord-7289da.svg?logo=discord)](https://discord.gg/y2cZFRA)
[![Discord](https://img.shields.io/badge/chat-on%20discord-7289da.svg?logo=discord)](https://discord.gg/PJEJHaB5)

<p align="center">
<img height="100" src="https://user-images.githubusercontent.com/4904157/63623173-921aaf00-c601-11e9-8b84-fc5803269323.png">
Expand Down Expand Up @@ -64,27 +63,6 @@ This fix was tested only with latest official update and latest [ASI Loader](htt

**MouseFix** - fixes small mouse movements not being recognized.

## Files rundown:

TBoGT/pc/models/cdimages/vehicles.img

**Car lights fix for TBoGT.**

common/shaders/win32_30/gta_emissivestrong.fxc
common/shaders/win32_30_atidx10/gta_emissivestrong.fxc
common/shaders/win32_30_low_ati/gta_emissivestrong.fxc
common/shaders/win32_30_nv6/gta_emissivestrong.fxc
common/shaders/win32_30_nv7/gta_emissivestrong.fxc
common/shaders/win32_30_nv8/gta_emissivestrong.fxc
common/GTAIV.EFLC.FusionFix.img

**Corrected shaders to make emissive lights appear. Used in conjunction with GTAIV.EFLC.FusionFix.asi.**

plugins/GTAIV.EFLC.FusionFix.asi
plugins/GTAIV.EFLC.FusionFix.ini

**Recoil, definition, shader and other bugs are fixed here.**

# Reporting more issues

We're making a list of **GTA IV** issues that weren't addressed in official patches.
Expand Down
214 changes: 193 additions & 21 deletions source/dllmain.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#include <misc.h>
#include <mmsystem.h>
#pragma comment(lib, "winmm.lib") // needed for timeBeginPeriod()/timeEndPeriod()
#include <filesystem>

uint32_t* dword_11CC9D0;
int32_t* dword_112EAC0;
Expand Down Expand Up @@ -238,6 +239,114 @@ double __cdecl MouseFix(void*, int32_t axis)
return 0.0;
}

template<class T>
T GetModulePath(HMODULE hModule)
{
static constexpr auto INITIAL_BUFFER_SIZE = MAX_PATH;
static constexpr auto MAX_ITERATIONS = 7;
T ret;
auto bufferSize = INITIAL_BUFFER_SIZE;
for (size_t iterations = 0; iterations < MAX_ITERATIONS; ++iterations)
{
ret.resize(bufferSize);
size_t charsReturned = 0;
if constexpr (std::is_same_v<T, std::string>)
charsReturned = GetModuleFileNameA(hModule, &ret[0], bufferSize);
else
charsReturned = GetModuleFileNameW(hModule, &ret[0], bufferSize);
if (charsReturned < ret.length())
{
ret.resize(charsReturned);
return ret;
}
else
{
bufferSize *= 2;
}
}
return T();
}

template<class T>
T GetExeModulePath()
{
T r = GetModulePath<T>(NULL);
if constexpr (std::is_same_v<T, std::string>)
r = r.substr(0, r.find_last_of("/\\") + 1);
else
r = r.substr(0, r.find_last_of(L"/\\") + 1);
return r;
}

template <typename T, typename V>
bool iequals(const T& s1, const V& s2)
{
T str1(s1); T str2(s2);
std::transform(str1.begin(), str1.end(), str1.begin(), ::tolower);
std::transform(str2.begin(), str2.end(), str2.begin(), ::tolower);
return (str1 == str2);
}

std::filesystem::path gamePath;
std::filesystem::path GetFileName(auto lpFilename)
{
auto filePath = std::filesystem::path(lpFilename);
auto relativePath = std::filesystem::relative(filePath, gamePath);

static auto updatePath = std::filesystem::path("update/").make_preferred();
static std::vector<std::filesystem::path> redirectedPaths = {
std::filesystem::path("pc/").make_preferred(),
std::filesystem::path("TLAD/pc/").make_preferred(),
std::filesystem::path("TBoGT/pc/").make_preferred(),
std::filesystem::path("common/").make_preferred(),
std::filesystem::path("TLAD/common/").make_preferred(),
std::filesystem::path("TBoGT/common/").make_preferred(),
std::filesystem::path("movies/").make_preferred(),
std::filesystem::path("TLAD/movies/").make_preferred(),
std::filesystem::path("TBoGT/movies/").make_preferred()
};

auto starts_with = [](const std::filesystem::path& path, const std::filesystem::path& base) -> bool {
std::wstring str1(path.wstring()); std::wstring str2(base.wstring());
std::transform(str1.begin(), str1.end(), str1.begin(), ::tolower);
std::transform(str2.begin(), str2.end(), str2.begin(), ::tolower);
return str1.starts_with(str2);
};

auto find = [](const std::filesystem::path& path, const std::filesystem::path& base) -> auto {
std::wstring str1(path.wstring()); std::wstring str2(base.wstring());
std::transform(str1.begin(), str1.end(), str1.begin(), ::tolower);
std::transform(str2.begin(), str2.end(), str2.begin(), ::tolower);
return str1.find(str2);
};

if (std::any_of(std::begin(redirectedPaths), std::end(redirectedPaths), [&](auto& it) { return starts_with(relativePath, it); }))
{
auto newPath = filePath.native();
auto pos = find(newPath, relativePath);
if (pos != newPath.npos)
{
newPath.insert(pos, updatePath);

if (std::filesystem::exists(newPath) && !std::filesystem::is_directory(newPath) && std::filesystem::is_regular_file(newPath))
return newPath;
}
}
return lpFilename;
}

HANDLE(WINAPI* ptrCreateFileA)(LPCSTR lpFilename, DWORD dwAccess, DWORD dwSharing, LPSECURITY_ATTRIBUTES saAttributes, DWORD dwCreation, DWORD dwAttributes, HANDLE hTemplate);
HANDLE WINAPI CreateFileAHook(LPCSTR lpFilename, DWORD dwAccess, DWORD dwSharing, LPSECURITY_ATTRIBUTES saAttributes, DWORD dwCreation, DWORD dwAttributes, HANDLE hTemplate)
{
return ptrCreateFileA(GetFileName(lpFilename).string().c_str(), dwAccess, dwSharing, saAttributes, dwCreation, dwAttributes, hTemplate);
}

HANDLE(WINAPI* ptrCreateFileW)(LPCWSTR lpFilename, DWORD dwAccess, DWORD dwSharing, LPSECURITY_ATTRIBUTES saAttributes, DWORD dwCreation, DWORD dwAttributes, HANDLE hTemplate);
HANDLE WINAPI CreateFileWHook(LPCWSTR lpFilename, DWORD dwAccess, DWORD dwSharing, LPSECURITY_ATTRIBUTES saAttributes, DWORD dwCreation, DWORD dwAttributes, HANDLE hTemplate)
{
return ptrCreateFileW(GetFileName(lpFilename).wstring().c_str(), dwAccess, dwSharing, saAttributes, dwCreation, dwAttributes, hTemplate);
}

void Init()
{
CIniReader iniReader("");
Expand Down Expand Up @@ -279,8 +388,8 @@ void Init()

// animation fix for phone interaction on bikes
{
auto pattern = hook::pattern("83 3D ? ? ? ? 01 0F 8C 18 01 00 00");
injector::MakeNOP(pattern.get(0).get<int>(0), 13, true);
auto pattern = hook::pattern("83 3D ? ? ? ? 01 0F 8C 18 01 00 00");
injector::MakeNOP(pattern.get(0).get<int>(0), 13, true);
}

//fix for lods appearing inside normal models, unless the graphics menu was opened once (draw distances aren't set properly?)
Expand Down Expand Up @@ -424,25 +533,6 @@ void Init()
regs.eax = regs.eax << 4;
}
}; injector::MakeInline<ShaderTest>(pattern.count(2).get(1).get<void>(0), pattern.count(2).get(1).get<void>(6));

//BAWSAQ
pattern = hook::pattern("E8 ? ? ? ? 6A 00 E8 ? ? ? ? 83 C4 14 6A 00");
static auto CImgManager__addImgFile = (void(__cdecl*)(const char*, char, int)) injector::GetBranchDestination(pattern.get_first(0)).get();
static auto sub_A95980 = (void(__cdecl*)(char)) injector::GetBranchDestination(pattern.get_first(7)).get();

pattern = hook::pattern("B9 ? ? ? ? E8 ? ? ? ? 84 C0 74 22 68");
static auto g_assetManager = *pattern.get_first<uint32_t>(1);
struct AddImgHook
{
void operator()(injector::reg_pack& regs)
{
regs.ecx = g_assetManager;

sub_A95980(255);
CImgManager__addImgFile("common:/GTAIV.EFLC.FusionFix.img", 1, -1);
sub_A95980(0);
}
}; injector::MakeInline<AddImgHook>(pattern.get_first(0));
}

if (bHandbrakeCamFix)
Expand Down Expand Up @@ -577,6 +667,88 @@ void Init()
auto pattern = hook::pattern("F7 2D ? ? ? ? 8B C2 C1 E8 1F 03 C2 89 0D ? ? ? ? A3 ? ? ? ? 83 C4 10 C3");
injector::WriteMemory(*pattern.get_first<void*>(2), nPedBudget, true);
}

{
gamePath = std::filesystem::path(GetExeModulePath<std::wstring>()).remove_filename();

auto pattern = hook::pattern("FF 15 ? ? ? ? 8B F0 32 C0");
ptrCreateFileW = (HANDLE(WINAPI*)(LPCWSTR, DWORD, DWORD, LPSECURITY_ATTRIBUTES, DWORD, DWORD, HANDLE))injector::GetBranchDestination(pattern.get_first(0)).get();
injector::WriteMemory(*pattern.get_first<void*>(2), CreateFileWHook);

pattern = hook::pattern("FF 15 ? ? ? ? 8B F0 83 FE FF 74 21");
ptrCreateFileA = (HANDLE(WINAPI*)(LPCSTR, DWORD, DWORD, LPSECURITY_ATTRIBUTES, DWORD, DWORD, HANDLE))injector::GetBranchDestination(pattern.get_first(0)).get();
injector::WriteMemory(*pattern.get_first<void*>(2), CreateFileAHook);

//IMG Loader
pattern = hook::pattern("E8 ? ? ? ? 6A 00 E8 ? ? ? ? 83 C4 14 6A 00");
static auto CImgManager__addImgFile = (void(__cdecl*)(const char*, char, int)) injector::GetBranchDestination(pattern.get_first(0)).get();
static auto sub_A95980 = (void(__cdecl*)(char)) injector::GetBranchDestination(pattern.get_first(7)).get();

pattern = hook::pattern("83 3D ? ? ? ? ? 75 0F 6A 02");
static auto _dwCurrentEpisode = *pattern.get_first<int*>(2);

pattern = hook::pattern("89 44 24 44 8B 44 24 4C 53");
struct ImgListHook
{
void operator()(injector::reg_pack& regs)
{
*(uint32_t*)(regs.esp + 0x44) = regs.eax;
regs.eax = *(uint32_t*)(regs.esp + 0x4C);

auto exePath = std::filesystem::path(GetExeModulePath<std::wstring>());
auto updatePath = exePath.remove_filename() / L"update";

if (std::filesystem::exists(updatePath))
{
for (const auto& file : std::filesystem::recursive_directory_iterator(updatePath, std::filesystem::directory_options::skip_permission_denied))
{
auto filePath = std::filesystem::path(file.path());
auto relativePath = std::filesystem::relative(filePath, gamePath);

if (!std::filesystem::is_directory(file) && file.is_regular_file() && iequals(filePath.extension().wstring(), L".img"))
{
static std::vector<std::filesystem::path> episodicPaths = {
std::filesystem::path("/IV/").make_preferred(),
std::filesystem::path("/TLAD/").make_preferred(),
std::filesystem::path("/TBoGT/").make_preferred(),
};

auto is_subpath = [](const std::filesystem::path& path, const std::filesystem::path& base) -> bool {
std::wstring str1(path.wstring()); std::wstring str2(base.wstring());
std::transform(str1.begin(), str1.end(), str1.begin(), ::tolower);
std::transform(str2.begin(), str2.end(), str2.begin(), ::tolower);
return str1.contains(str2);
};

auto imgPath = std::filesystem::relative(filePath, exePath).native();
std::replace(std::begin(imgPath), std::end(imgPath), L'\\', L'/');
auto pos = imgPath.find(std::filesystem::path("/").native());

if (pos != imgPath.npos)
{
imgPath.replace(pos, 1, std::filesystem::path(":/").native());
if (std::any_of(std::begin(episodicPaths), std::end(episodicPaths), [&](auto& it) { return is_subpath(relativePath, it); }))
{
if (*_dwCurrentEpisode < episodicPaths.size() && is_subpath(relativePath, episodicPaths[*_dwCurrentEpisode]))
{
sub_A95980(255);
CImgManager__addImgFile(std::filesystem::path(imgPath).string().c_str(), 1, -1);
sub_A95980(0);
}
}
else
{
sub_A95980(255);
CImgManager__addImgFile(std::filesystem::path(imgPath).string().c_str(), 1, -1);
sub_A95980(0);
}
}
}
}
}
}
}; injector::MakeInline<ImgListHook>(pattern.get_first(0), pattern.get_first(8));
}
}

CEXP void InitializeASI()
Expand Down
Binary file added tools/IMGConsole/fastman92ImgConsole32.exe
Binary file not shown.
Binary file added tools/IMGConsole/zlib1.dll
Binary file not shown.

0 comments on commit 9d35be5

Please sign in to comment.