Smooth asset handler

This commit is contained in:
momo5502 2015-12-23 22:21:03 +01:00
parent f174fd77ef
commit da7f3e619e
18 changed files with 366 additions and 4 deletions

View File

@ -0,0 +1,85 @@
#include "..\STDInclude.hpp"
namespace Components
{
bool AssetHandler::BypassState = false;
std::map<Game::XAssetType, AssetHandler::Callback> AssetHandler::TypeCallbacks;
Game::XAssetHeader AssetHandler::FindAsset(Game::XAssetType type, const char* filename)
{
Game::XAssetHeader header = nullptr;
AssetHandler::BypassState = true;
if (AssetHandler::TypeCallbacks.find(type) != AssetHandler::TypeCallbacks.end())
{
header = AssetHandler::TypeCallbacks[type](type, filename);
}
AssetHandler::BypassState = false;
return header;
}
void __declspec(naked) AssetHandler::FindAssetStub()
{
__asm
{
push ecx
push ebx
push ebp
push esi
push edi
// Check if custom handler should be bypassed
xor eax, eax
mov al, AssetHandler::BypassState
test al, al
jnz finishOriginal
mov ecx, [esp + 18h] // Asset type
mov ebx, [esp + 1Ch] // Filename
push ebx
push ecx
call AssetHandler::FindAsset
add esp, 8h
test eax, eax
jnz finishFound
finishOriginal:
// Asset not found using custom handlers, redirect to DB_FindXAssetHeader
mov ebx, ds:6D7190h // InterlockedDecrement
mov eax, 40793Bh
jmp eax
finishFound:
pop edi
pop esi
pop ebp
pop ebx
pop ecx
retn
}
}
void AssetHandler::On(Game::XAssetType type, AssetHandler::Callback callback)
{
AssetHandler::TypeCallbacks[type] = callback;
}
AssetHandler::AssetHandler()
{
Utils::Hook(Game::DB_FindXAssetHeader, AssetHandler::FindAssetStub).Install()->Quick();
}
AssetHandler::~AssetHandler()
{
AssetHandler::TypeCallbacks.clear();
}
}

View File

@ -0,0 +1,22 @@
namespace Components
{
class AssetHandler : public Component
{
public:
typedef Game::XAssetHeader(*Callback)(Game::XAssetType, const char*);
AssetHandler();
~AssetHandler();
const char* GetName() { return "AssetHandler"; };
static void On(Game::XAssetType type, Callback callback);
private:
static bool BypassState;
static Game::XAssetHeader FindAsset(Game::XAssetType type, const char* filename);
static void FindAssetStub();
static std::map<Game::XAssetType, Callback> TypeCallbacks;
};
}

View File

@ -5,7 +5,7 @@ namespace Components
std::vector<Game::cmd_function_t*> Command::Functions;
std::map<std::string, Command::Callback> Command::FunctionMap;
const char* Command::Params::operator[](size_t index)
char* Command::Params::operator[](size_t index)
{
if (index >= this->Length())
{

View File

@ -9,7 +9,7 @@ namespace Components
Params(DWORD id) : CommandId(id) {};
Params(const Params &obj) { this->CommandId = obj.CommandId; };
const char* operator[](size_t index);
char* operator[](size_t index);
size_t Length();
private:

View File

@ -7,7 +7,9 @@ namespace Components
void Loader::Initialize()
{
Loader::Register(new Dvar());
Loader::Register(new Menus());
Loader::Register(new Colors());
Loader::Register(new Logger());
Loader::Register(new Window());
Loader::Register(new Command());
Loader::Register(new Console());
@ -15,13 +17,15 @@ namespace Components
Loader::Register(new Renderer());
Loader::Register(new Materials());
Loader::Register(new QuickPatch());
Loader::Register(new AssetHandler());
Loader::Register(new MusicalTalent());
}
void Loader::Uninitialize()
{
for (auto component : Loader::Components)
{
OutputDebugStringA(Utils::VA("Unregistering component: %s", component->GetName()));
Logger::Print("Unregistering component: %s", component->GetName());
delete component;
}
@ -32,7 +36,7 @@ namespace Components
{
if (component)
{
OutputDebugStringA(Utils::VA("Component registered: %s", component->GetName()));
Logger::Print("Component registered: %s", component->GetName());
Loader::Components.push_back(component);
}
}

View File

@ -21,7 +21,9 @@ namespace Components
}
#include "Dvar.hpp"
#include "Menus.hpp"
#include "Colors.hpp"
#include "Logger.hpp"
#include "Window.hpp"
#include "Command.hpp"
#include "Console.hpp"
@ -29,3 +31,5 @@ namespace Components
#include "Renderer.hpp"
#include "Materials.hpp"
#include "QuickPatch.hpp"
#include "AssetHandler.hpp"
#include "MusicalTalent.hpp"

57
iw4/Components/Logger.cpp Normal file
View File

@ -0,0 +1,57 @@
#include "..\STDInclude.hpp"
namespace Components
{
bool Logger::IsConsoleReady()
{
return (IsWindow(*(HWND*)0x64A3288) != FALSE);
}
void Logger::Print(const char* message, ...)
{
char buffer[0x1000] = { 0 };
va_list ap;
va_start(ap, message);
vsprintf_s(buffer, message, ap);
va_end(ap);
if (Logger::IsConsoleReady())
{
Game::Com_Printf(0, "%s", buffer);
}
else
{
OutputDebugStringA(buffer);
}
}
void Logger::Error(const char* message, ...)
{
char buffer[0x1000] = { 0 };
va_list ap;
va_start(ap, message);
vsprintf_s(buffer, message, ap);
va_end(ap);
Game::Com_Error(0, "%s", buffer);
}
void Logger::SoftError(const char* message, ...)
{
char buffer[0x1000] = { 0 };
va_list ap;
va_start(ap, message);
vsprintf_s(buffer, message, ap);
va_end(ap);
Game::Com_Error(2, "%s", buffer);
}
Logger::Logger()
{
}
}

14
iw4/Components/Logger.hpp Normal file
View File

@ -0,0 +1,14 @@
namespace Components
{
class Logger : public Component
{
public:
Logger();
const char* GetName() { return "Logger"; };
static void Print(const char* message, ...);
static void Error(const char* message, ...);
static void SoftError(const char* message, ...);
static bool IsConsoleReady();
};
}

26
iw4/Components/Menus.cpp Normal file
View File

@ -0,0 +1,26 @@
#include "..\STDInclude.hpp"
namespace Components
{
Menus::Menus()
{
Command::Add("openmenu", [] (Command::Params params)
{
if (params.Length() != 2)
{
Logger::Print("USAGE: openmenu <menu name>\n");
return;
}
char* menu = params[1];
__asm
{
push menu
push 62E2858h
mov eax, 4CCE60h
call eax
}
});
}
}

9
iw4/Components/Menus.hpp Normal file
View File

@ -0,0 +1,9 @@
namespace Components
{
class Menus : public Component
{
public:
Menus();
const char* GetName() { return "Menus"; };
};
}

View File

@ -0,0 +1,43 @@
#include "..\STDInclude.hpp"
namespace Components
{
std::map<std::string, const char*> MusicalTalent::SoundAliasList;
void MusicalTalent::Replace(std::string sound, const char* file)
{
MusicalTalent::SoundAliasList[Utils::StrToLower(sound)] = file;
}
Game::XAssetHeader MusicalTalent::ManipulateAliases(Game::XAssetType type, const char* filename)
{
if (MusicalTalent::SoundAliasList.find(Utils::StrToLower(filename)) != MusicalTalent::SoundAliasList.end())
{
Game::snd_alias_list_t* aliases = (Game::snd_alias_list_t*)Game::DB_FindXAssetHeader(type, filename);
if (aliases)
{
if (aliases->aliases->stream->type == 2)
{
aliases->aliases->stream->file = MusicalTalent::SoundAliasList[Utils::StrToLower(filename)];
}
return aliases;
}
}
return NULL;
}
MusicalTalent::MusicalTalent()
{
AssetHandler::On(Game::XAssetType::ASSET_TYPE_SOUND, MusicalTalent::ManipulateAliases);
MusicalTalent::Replace("music_mainmenu_mp", "hz_boneyard_intro_LR_1.mp3");
}
MusicalTalent::~MusicalTalent()
{
MusicalTalent::SoundAliasList.clear();
}
}

View File

@ -0,0 +1,15 @@
namespace Components
{
class MusicalTalent : public Component
{
public:
MusicalTalent();
~MusicalTalent();
static void Replace(std::string sound, const char* file);
private:
static std::map<std::string, const char*> SoundAliasList;
static Game::XAssetHeader ManipulateAliases(Game::XAssetType type, const char* filename);
};
}

View File

@ -38,6 +38,16 @@ namespace Components
// fs_basegame
Utils::Hook::Set<char*>(0x6431D1, "data");
// Disable UPNP
Utils::Hook::Nop(0x60BE24, 5);
// disable the IWNet IP detection (default 'got ipdetect' flag to 1)
Utils::Hook::Set<BYTE>(0x649D6F0, 1);
// Fix stats sleeping
Utils::Hook::Set<BYTE>(0x6832BA, 0xEB);
Utils::Hook::Set<BYTE>(0x4BD190, 0xC3);
// Why?
Game::ReallocateAssetPool(Game::XAssetType::ASSET_TYPE_WEAPON, 2400);
}

View File

@ -4,6 +4,11 @@ namespace Game
{
Cmd_AddCommand_t Cmd_AddCommand = (Cmd_AddCommand_t)0x470090;
Com_Error_t Com_Error = (Com_Error_t)0x4B22D0;
Com_Printf_t Com_Printf = (Com_Printf_t)0x402500;
Com_Milliseconds_t Com_Milliseconds = (Com_Milliseconds_t)0x42A660;
DB_FindXAssetHeader_t DB_FindXAssetHeader = (DB_FindXAssetHeader_t)0x407930;
DB_GetXAssetSizeHandler_t* DB_GetXAssetSizeHandlers = (DB_GetXAssetSizeHandler_t*)0x799488;
Dvar_RegisterBool_t Dvar_RegisterBool = (Dvar_RegisterBool_t)0x4CE1A0;

View File

@ -3,6 +3,18 @@ namespace Game
typedef void(__cdecl * Cmd_AddCommand_t)(const char* name, void(*callback), cmd_function_t* data, char);
extern Cmd_AddCommand_t Cmd_AddCommand;
typedef void(__cdecl * Com_Error_t)(int type, char* message, ...);
extern Com_Error_t Com_Error;
typedef void(__cdecl * Com_Printf_t)(int, const char*, ...);
extern Com_Printf_t Com_Printf;
typedef int(__cdecl * Com_Milliseconds_t)(void);
extern Com_Milliseconds_t Com_Milliseconds;
typedef XAssetHeader (__cdecl * DB_FindXAssetHeader_t)(XAssetType type, const char* filename);
extern DB_FindXAssetHeader_t DB_FindXAssetHeader;
typedef int(__cdecl * DB_GetXAssetSizeHandler_t)();
extern DB_GetXAssetSizeHandler_t* DB_GetXAssetSizeHandlers;

View File

@ -48,6 +48,8 @@ namespace Game
ASSET_TYPE_MAX = 43
} XAssetType;
typedef void *XAssetHeader; // Temporary
typedef enum
{
DVAR_FLAG_NONE = 0x0, //no flags
@ -120,4 +122,26 @@ namespace Game
{
char pad[24];
} cmd_function_t;
typedef struct
{
char type;
char pad[3];
const char* folder;
const char* file;
} StreamFile;
typedef struct
{
char pad[20];
StreamFile* stream;
char pad2[76];
} snd_alias_t;
typedef struct
{
const char* name;
snd_alias_t* aliases;
int numAliases;
} snd_alias_list_t;
}

View File

@ -51,12 +51,16 @@
</PostBuildEvent>
</ItemDefinitionGroup>
<ItemGroup>
<ClInclude Include="Components\AssetHandler.hpp" />
<ClInclude Include="Components\Colors.hpp" />
<ClInclude Include="Components\Command.hpp" />
<ClInclude Include="Components\Console.hpp" />
<ClInclude Include="Components\Dvar.hpp" />
<ClInclude Include="Components\Loader.hpp" />
<ClInclude Include="Components\Logger.hpp" />
<ClInclude Include="Components\Materials.hpp" />
<ClInclude Include="Components\Menus.hpp" />
<ClInclude Include="Components\MusicalTalent.hpp" />
<ClInclude Include="Components\QuickPatch.hpp" />
<ClInclude Include="Components\RawFiles.hpp" />
<ClInclude Include="Components\Renderer.hpp" />
@ -77,12 +81,16 @@
<ClInclude Include="Utils\Utils.hpp" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="Components\AssetHandler.cpp" />
<ClCompile Include="Components\Colors.cpp" />
<ClCompile Include="Components\Command.cpp" />
<ClCompile Include="Components\Console.cpp" />
<ClCompile Include="Components\Dvar.cpp" />
<ClCompile Include="Components\Loader.cpp" />
<ClCompile Include="Components\Logger.cpp" />
<ClCompile Include="Components\Materials.cpp" />
<ClCompile Include="Components\Menus.cpp" />
<ClCompile Include="Components\MusicalTalent.cpp" />
<ClCompile Include="Components\QuickPatch.cpp" />
<ClCompile Include="Components\RawFiles.cpp" />
<ClCompile Include="Components\Renderer.cpp" />

View File

@ -98,6 +98,18 @@
<ClCompile Include="Components\Renderer.cpp">
<Filter>Source\Components\Modules</Filter>
</ClCompile>
<ClCompile Include="Components\Menus.cpp">
<Filter>Source\Components\Modules</Filter>
</ClCompile>
<ClCompile Include="Components\Logger.cpp">
<Filter>Source\Components\Modules</Filter>
</ClCompile>
<ClCompile Include="Components\AssetHandler.cpp">
<Filter>Source\Components\Modules</Filter>
</ClCompile>
<ClCompile Include="Components\MusicalTalent.cpp">
<Filter>Source\Components\Modules</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="Steam\Interfaces\SteamUser.hpp">
@ -172,5 +184,17 @@
<ClInclude Include="Components\Renderer.hpp">
<Filter>Source\Components\Modules</Filter>
</ClInclude>
<ClInclude Include="Components\Menus.hpp">
<Filter>Source\Components\Modules</Filter>
</ClInclude>
<ClInclude Include="Components\Logger.hpp">
<Filter>Source\Components\Modules</Filter>
</ClInclude>
<ClInclude Include="Components\AssetHandler.hpp">
<Filter>Source\Components\Modules</Filter>
</ClInclude>
<ClInclude Include="Components\MusicalTalent.hpp">
<Filter>Source\Components\Modules</Filter>
</ClInclude>
</ItemGroup>
</Project>