This commit is contained in:
momo5502 2015-12-26 02:51:58 +01:00
parent 81c049e192
commit 18cc328efc
17 changed files with 243 additions and 7 deletions

View File

@ -4,6 +4,7 @@ namespace Components
{
bool AssetHandler::BypassState = false;
std::map<Game::XAssetType, AssetHandler::Callback> AssetHandler::TypeCallbacks;
std::vector<AssetHandler::RestrictCallback> AssetHandler::RestrictCallbacks;
Game::XAssetHeader AssetHandler::FindAsset(Game::XAssetType type, const char* filename)
{
@ -60,7 +61,6 @@ namespace Components
jmp eax
finishFound:
pop edi
pop esi
pop ebp
@ -70,14 +70,65 @@ namespace Components
}
}
bool AssetHandler::IsAssetEligible(Game::XAssetType type, Game::XAssetHeader *asset)
{
const char* name = Game::DB_GetXAssetNameHandlers[type](asset);
if (!name) return false;
for (auto callback : AssetHandler::RestrictCallbacks)
{
if (!callback(type, *asset, name))
{
return false;
}
}
return true;
}
void __declspec(naked) AssetHandler::AddAssetStub()
{
__asm
{
push [esp + 8]
push [esp + 8]
call AssetHandler::IsAssetEligible
add esp, 08h
test al, al
jz doNotLoad
// push [esp + 8]
// push [esp + 8]
// call DoBeforeLoadAsset
// add esp, 08h
mov eax, [esp + 8]
sub esp, 14h
mov ecx, 5BB657h
jmp ecx
doNotLoad:
mov eax, [esp + 8]
retn
}
}
void AssetHandler::On(Game::XAssetType type, AssetHandler::Callback callback)
{
AssetHandler::TypeCallbacks[type] = callback;
}
void AssetHandler::Restrict(RestrictCallback callback)
{
AssetHandler::RestrictCallbacks.push_back(callback);
}
AssetHandler::AssetHandler()
{
Utils::Hook(Game::DB_FindXAssetHeader, AssetHandler::FindAssetStub).Install()->Quick();
Utils::Hook(0x5BB650, AssetHandler::AddAssetStub, HOOK_JUMP).Install()->Quick();
}
AssetHandler::~AssetHandler()

View File

@ -4,19 +4,24 @@ namespace Components
{
public:
typedef Game::XAssetHeader(*Callback)(Game::XAssetType, const char*);
typedef bool(*RestrictCallback)(Game::XAssetType type, Game::XAssetHeader asset, const char* name);
AssetHandler();
~AssetHandler();
const char* GetName() { return "AssetHandler"; };
static void On(Game::XAssetType type, Callback callback);
static void Restrict(RestrictCallback callback);
private:
static bool BypassState;
static Game::XAssetHeader FindAsset(Game::XAssetType type, const char* filename);
static bool IsAssetEligible(Game::XAssetType type, Game::XAssetHeader* asset);
static void FindAssetStub();
static void AddAssetStub();
static std::map<Game::XAssetType, Callback> TypeCallbacks;
static std::vector<RestrictCallback> RestrictCallbacks;
};
}

View File

@ -53,6 +53,18 @@ namespace Components
FastFiles::ZonePaths.push_back(path);
}
std::string FastFiles::Current()
{
const char* file = (Utils::Hook::Get<char*>(0x112A680) + 4);
if ((int)file == 4)
{
return "";
}
return file;
}
FastFiles::FastFiles()
{
// Redirect zone paths
@ -62,6 +74,27 @@ namespace Components
Utils::Hook(0x506BC7, FastFiles::LoadDLCUIZones, HOOK_CALL).Install()->Quick();
Utils::Hook(0x60B4AC, FastFiles::LoadDLCUIZones, HOOK_CALL).Install()->Quick();
// basic checks (hash jumps, both normal and playlist)
Utils::Hook::Nop(0x5B97A3, 2);
Utils::Hook::Nop(0x5BA493, 2);
Utils::Hook::Nop(0x5B991C, 2);
Utils::Hook::Nop(0x5BA60C, 2);
Utils::Hook::Nop(0x5B97B4, 2);
Utils::Hook::Nop(0x5BA4A4, 2);
// allow loading of IWffu (unsigned) files
Utils::Hook::Set<BYTE>(0x4158D9, 0xEB); // main function
Utils::Hook::Nop(0x4A1D97, 2); // DB_AuthLoad_InflateInit
// some other, unknown, check
Utils::Hook::Set<BYTE>(0x5B9912, 0xB8);
Utils::Hook::Set<DWORD>(0x5B9913, 1);
Utils::Hook::Set<BYTE>(0x5BA602, 0xB8);
Utils::Hook::Set<DWORD>(0x5BA603, 1);
// Add custom zone paths
FastFiles::AddZonePath("zone\\patch\\");
FastFiles::AddZonePath("zone\\dlc\\");

View File

@ -8,6 +8,7 @@ namespace Components
const char* GetName() { return "FastFiles"; };
static void AddZonePath(std::string path);
static std::string Current();
private:
static std::vector<std::string> ZonePaths;

View File

@ -7,6 +7,7 @@ namespace Components
void Loader::Initialize()
{
Loader::Register(new Dvar());
Loader::Register(new Maps());
Loader::Register(new Menus());
Loader::Register(new Party());
Loader::Register(new Colors());

View File

@ -21,6 +21,7 @@ namespace Components
}
#include "Dvar.hpp"
#include "Maps.hpp"
#include "Menus.hpp"
#include "Colors.hpp"
#include "Logger.hpp"

View File

@ -2,6 +2,7 @@
namespace Components
{
Dvar::Var Localization::UseLocalization;
std::map<std::string, std::string> Localization::LocalizeMap;
void Localization::Set(const char* key, const char* value)
@ -11,6 +12,8 @@ namespace Components
const char* Localization::Get(const char* key)
{
if (!Localization::UseLocalization.Get<bool>()) return key;
if (Localization::LocalizeMap.find(key) != Localization::LocalizeMap.end())
{
return Localization::LocalizeMap[key].data();
@ -30,7 +33,8 @@ namespace Components
{
Utils::Hook(0x629B90, Localization::Get, HOOK_JUMP).Install()->Quick();
Localization::Set("MENU_MULTIPLAYER_CAPS", "^5Fotze");
//Localization::Set("MENU_MULTIPLAYER_CAPS", "^5Fotze");
Localization::UseLocalization = Dvar::Var::Register<bool>("ui_localize", true, Game::dvar_flag::DVAR_FLAG_NONE, "Use localization strings");
}
Localization::~Localization()

View File

@ -12,5 +12,6 @@ namespace Components
private:
static std::map<std::string, std::string> LocalizeMap;
static Dvar::Var UseLocalization;
};
}

104
iw4/Components/Maps.cpp Normal file
View File

@ -0,0 +1,104 @@
#include "..\STDInclude.hpp"
namespace Components
{
void* Maps::WorldMP = 0;
void* Maps::WorldSP = 0;
void Maps::GetBSPName(char* buffer, size_t size, const char* format, const char* mapname)
{
if (_strnicmp("mp_", mapname, 3))
{
format = "maps/%s.d3dbsp";
Utils::Hook::Set<void*>(0x4D90B7, (char*)Maps::WorldSP + 52);
}
else
{
Utils::Hook::Set<void*>(0x4D90B7, (char*)Maps::WorldMP + 4);
}
_snprintf(buffer, size, format, mapname);
}
typedef struct
{
char unknown[16];
} xAssetEntry_t;
static xAssetEntry_t xEntries[789312];
void ReallocXAssetEntries()
{
int newsize = 516 * 2048;
//newEnts = malloc(newsize);
// get (obfuscated) memory locations
unsigned int origMin = 0x134CAD8;
unsigned int origMax = 0x134CAE8;
unsigned int difference = (unsigned int)xEntries - origMin;
// scan the .text memory
char* scanMin = (char*)0x401000;
char* scanMax = (char*)0x6D7000;
char* current = scanMin;
for (; current < scanMax; current += 1) {
unsigned int* intCur = (unsigned int*)current;
// if the address points to something within our range of interest
if (*intCur == origMin || *intCur == origMax) {
// patch it
*intCur += difference;
}
}
*(DWORD*)0x5BAEB0 = 789312;
}
Maps::Maps()
{
// hunk size (was 300 MiB)
Utils::Hook::Set<DWORD>(0x64A029, 0x1C200000); // 450 MiB
Utils::Hook::Set<DWORD>(0x64A057, 0x1C200000);
// Intercept BSP name resolving
Utils::Hook(0x4C5979, Maps::GetBSPName, HOOK_CALL).Install()->Quick();
Maps::WorldSP = Game::ReallocateAssetPool(Game::XAssetType::ASSET_TYPE_GAME_MAP_SP, 1);
Maps::WorldMP = Utils::Hook::Get<char*>(0x4D90B7) - 4;
Game::ReallocateAssetPool(Game::XAssetType::ASSET_TYPE_IMAGE, 7168);
Game::ReallocateAssetPool(Game::XAssetType::ASSET_TYPE_LOADED_SOUND, 2700);
Game::ReallocateAssetPool(Game::XAssetType::ASSET_TYPE_FX, 1200);
Game::ReallocateAssetPool(Game::XAssetType::ASSET_TYPE_LOCALIZE, 14000);
Game::ReallocateAssetPool(Game::XAssetType::ASSET_TYPE_XANIM, 8192);
Game::ReallocateAssetPool(Game::XAssetType::ASSET_TYPE_XMODEL, 5125);
Game::ReallocateAssetPool(Game::XAssetType::ASSET_TYPE_PHYSPRESET, 128);
Game::ReallocateAssetPool(Game::XAssetType::ASSET_TYPE_PIXELSHADER, 10000);
Game::ReallocateAssetPool(Game::XAssetType::ASSET_TYPE_VERTEXSHADER, 3072);
Game::ReallocateAssetPool(Game::XAssetType::ASSET_TYPE_MATERIAL, 8192);
Game::ReallocateAssetPool(Game::XAssetType::ASSET_TYPE_VERTEXDECL, 196);
Game::ReallocateAssetPool(Game::XAssetType::ASSET_TYPE_WEAPON, 2400);
Game::ReallocateAssetPool(Game::XAssetType::ASSET_TYPE_STRINGTABLE, 800);
ReallocXAssetEntries();
AssetHandler::Restrict([] (Game::XAssetType type, Game::XAssetHeader asset, const char* name) -> bool
{
if (type == Game::XAssetType::ASSET_TYPE_MAP_ENTS)
{
static std::string mapEntities;
FileSystem::File ents(Utils::VA("%s.ents", name));
if (ents.Exists())
{
mapEntities = ents.GetBuffer();
asset.mapEnts->entitystring = mapEntities.data();
}
}
return true;
});
}
}

15
iw4/Components/Maps.hpp Normal file
View File

@ -0,0 +1,15 @@
namespace Components
{
class Maps : public Component
{
public:
Maps();
const char* GetName() { return "Maps"; };
private:
static void* WorldMP;
static void* WorldSP;
static void GetBSPName(char* buffer, size_t size, const char* format, const char* mapname);
};
}

View File

@ -153,8 +153,6 @@ namespace Components
}
}
OutputDebugStringA(Utils::VA("%X %s", menu->window.name, menu->window.name));
return menu;
}

View File

@ -69,8 +69,5 @@ namespace Components
Utils::Hook::Nop(0x6830B1, 20);
Utils::Hook(0x682EBF, QuickPatch::GetStatsID, HOOK_CALL).Install()->Quick();
Utils::Hook(0x6830B1, QuickPatch::GetStatsID, HOOK_CALL).Install()->Quick();
// Why?
Game::ReallocateAssetPool(Game::XAssetType::ASSET_TYPE_WEAPON, 2400);
}
}

View File

@ -15,6 +15,7 @@ namespace Game
Com_Milliseconds_t Com_Milliseconds = (Com_Milliseconds_t)0x42A660;
DB_FindXAssetHeader_t DB_FindXAssetHeader = (DB_FindXAssetHeader_t)0x407930;
DB_GetXAssetNameHandler_t* DB_GetXAssetNameHandlers = (DB_GetXAssetNameHandler_t*)0x799328;
DB_GetXAssetSizeHandler_t* DB_GetXAssetSizeHandlers = (DB_GetXAssetSizeHandler_t*)0x799488;
DB_LoadXAssets_t DB_LoadXAssets = (DB_LoadXAssets_t)0x4E5930;

View File

@ -27,6 +27,9 @@ namespace Game
typedef XAssetHeader (__cdecl * DB_FindXAssetHeader_t)(XAssetType type, const char* filename);
extern DB_FindXAssetHeader_t DB_FindXAssetHeader;
typedef const char* (__cdecl * DB_GetXAssetNameHandler_t)(Game::XAssetHeader* asset);
extern DB_GetXAssetNameHandler_t* DB_GetXAssetNameHandlers;
typedef int(__cdecl * DB_GetXAssetSizeHandler_t)();
extern DB_GetXAssetSizeHandler_t* DB_GetXAssetSizeHandlers;

View File

@ -858,6 +858,12 @@ namespace Game
const char* name;
};
struct MapEnts
{
const char* name;
const char* entitystring;
};
union XAssetHeader
{
void *data;
@ -866,5 +872,12 @@ namespace Game
Material *material;
snd_alias_list_t *aliasList;
localizedEntry_s *localize;
MapEnts* mapEnts;
};
struct XAsset
{
XAssetType type;
XAssetHeader header;
};
}

View File

@ -61,6 +61,7 @@
<ClInclude Include="Components\Loader.hpp" />
<ClInclude Include="Components\Localization.hpp" />
<ClInclude Include="Components\Logger.hpp" />
<ClInclude Include="Components\Maps.hpp" />
<ClInclude Include="Components\Materials.hpp" />
<ClInclude Include="Components\Menus.hpp" />
<ClInclude Include="Components\MusicalTalent.hpp" />
@ -96,6 +97,7 @@
<ClCompile Include="Components\Loader.cpp" />
<ClCompile Include="Components\Localization.cpp" />
<ClCompile Include="Components\Logger.cpp" />
<ClCompile Include="Components\Maps.cpp" />
<ClCompile Include="Components\Materials.cpp" />
<ClCompile Include="Components\Menus.cpp" />
<ClCompile Include="Components\MusicalTalent.cpp" />

View File

@ -125,6 +125,9 @@
<ClCompile Include="Components\Localization.cpp">
<Filter>Source\Components\Modules</Filter>
</ClCompile>
<ClCompile Include="Components\Maps.cpp">
<Filter>Source\Components\Modules</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="Steam\Interfaces\SteamUser.hpp">
@ -226,5 +229,8 @@
<ClInclude Include="Components\Localization.hpp">
<Filter>Source\Components\Modules</Filter>
</ClInclude>
<ClInclude Include="Components\Maps.hpp">
<Filter>Source\Components\Modules</Filter>
</ClInclude>
</ItemGroup>
</Project>