IW5 material emedding system

This commit is contained in:
momo5502 2016-09-04 17:13:06 +02:00
parent e94d9788d0
commit 5e71960c7e
4 changed files with 84 additions and 33 deletions

View File

@ -24,9 +24,6 @@ namespace Components
Loader::Register(new Maps()); Loader::Register(new Maps());
Loader::Register(new News()); Loader::Register(new News());
Loader::Register(new Node()); Loader::Register(new Node());
#ifndef DISABLE_BITMESSAGE
Loader::Register(new BitMessage());
#endif
Loader::Register(new RCon()); Loader::Register(new RCon());
Loader::Register(new Menus()); Loader::Register(new Menus());
Loader::Register(new Toast()); Loader::Register(new Toast());
@ -53,9 +50,11 @@ namespace Components
Loader::Register(new Dedicated()); Loader::Register(new Dedicated());
Loader::Register(new Discovery()); Loader::Register(new Discovery());
Loader::Register(new Exception()); Loader::Register(new Exception());
Loader::Register(new MinidumpUpload());
Loader::Register(new FastFiles()); Loader::Register(new FastFiles());
Loader::Register(new Materials()); Loader::Register(new Materials());
#ifndef DISABLE_BITMESSAGE
Loader::Register(new BitMessage());
#endif
Loader::Register(new FileSystem()); Loader::Register(new FileSystem());
Loader::Register(new QuickPatch()); Loader::Register(new QuickPatch());
Loader::Register(new ServerInfo()); Loader::Register(new ServerInfo());
@ -65,6 +64,7 @@ namespace Components
Loader::Register(new AssetHandler()); Loader::Register(new AssetHandler());
Loader::Register(new Localization()); Loader::Register(new Localization());
Loader::Register(new MusicalTalent()); Loader::Register(new MusicalTalent());
Loader::Register(new MinidumpUpload());
Loader::Register(new StructuredData()); Loader::Register(new StructuredData());
Loader::Register(new ConnectProtocol()); Loader::Register(new ConnectProtocol());

View File

@ -2,6 +2,7 @@
namespace Components namespace Components
{ {
int Materials::ImageNameLength;
Utils::Hook Materials::ImageVersionCheckHook; Utils::Hook Materials::ImageVersionCheckHook;
__declspec(naked) void Materials::ImageVersionCheck() __declspec(naked) void Materials::ImageVersionCheck()
@ -20,40 +21,41 @@ namespace Components
} }
} }
Game::Material* Materials::VerifyMaterial(Game::Material* material) Game::Material* Materials::ResolveMaterial(const char* stringPtr)
{ {
// if (!IsBadReadPtr(material, 4) && !IsBadReadPtr(material->name, 1)) const char* imagePtr = stringPtr + 4;
// { unsigned int length = static_cast<unsigned int>(stringPtr[3] & 0xFF);
// return material;
// }
Materials::VerifyContainer container = { false, material }; if (strlen(imagePtr) >= length)
Game::DB_EnumXAssets(Game::XAssetType::ASSET_TYPE_MATERIAL, [] (Game::XAssetHeader header, void* data)
{ {
Materials::VerifyContainer* container = reinterpret_cast<Materials::VerifyContainer*>(data); Materials::ImageNameLength = 4 + length;
std::string image(imagePtr, length);
if (container && header.material == container->material) return Game::DB_FindXAssetHeader(Game::XAssetType::ASSET_TYPE_MATERIAL, image.data()).material;
{
container->isValid = true;
} }
}, &container, false);
if (container.isValid) Materials::ImageNameLength = 4;
{
return material;
}
else
{
return Game::DB_FindXAssetHeader(Game::XAssetType::ASSET_TYPE_MATERIAL, "default").material; return Game::DB_FindXAssetHeader(Game::XAssetType::ASSET_TYPE_MATERIAL, "default").material;
} }
__declspec(naked) void Materials::PostDrawMaterialStub()
{
__asm
{
mov eax, Materials::ImageNameLength
add [esp + 30h], eax
mov eax, 5358FFh
jmp eax
}
} }
__declspec(naked) void Materials::DrawMaterialStub() __declspec(naked) void Materials::DrawMaterialStub()
{ {
__asm __asm
{ {
push eax push ecx
call Materials::VerifyMaterial call Materials::ResolveMaterial
add esp, 4h add esp, 4h
mov edx, 5310F0h mov edx, 5310F0h
@ -61,13 +63,59 @@ namespace Components
} }
} }
int Materials::WriteDeathMessageIcon(char* string, int offset, Game::Material* material)
{
if (!material)
{
material = Game::DB_FindXAssetHeader(Game::XAssetType::ASSET_TYPE_MATERIAL, "default").material;
}
int length = strlen(material->name);
string[offset++] = static_cast<char>(length);
strncpy_s(string + offset, 1024 - offset, material->name, length);
return offset + length;
}
__declspec(naked) void Materials::DeathMessageStub()
{
__asm
{
push edx // Material
push eax // offset
push ecx // String
call Materials::WriteDeathMessageIcon
add esp, 14h
retn
}
}
Materials::Materials() Materials::Materials()
{ {
Materials::ImageNameLength = 7;
// Allow codo images // Allow codo images
Materials::ImageVersionCheckHook.Initialize(0x53A456, Materials::ImageVersionCheck, HOOK_CALL)->Install(); Materials::ImageVersionCheckHook.Initialize(0x53A456, Materials::ImageVersionCheck, HOOK_CALL)->Install();
// Fix material pointer exploit // Fix material pointer exploit
Utils::Hook(0x534E0C, Materials::DrawMaterialStub, HOOK_CALL).Install()->Quick(); Utils::Hook(0x534E0C, Materials::DrawMaterialStub, HOOK_CALL).Install()->Quick();
// Increment string pointer accordingly
Utils::Hook(0x5358FA, Materials::PostDrawMaterialStub, HOOK_JUMP).Install()->Quick();
// Adapt death message to IW5 material format
Utils::Hook(0x5A30D9, Materials::DeathMessageStub, HOOK_JUMP).Install()->Quick();
// Renderer::OnFrame([] ()
// {
// Game::Font* font = Game::R_RegisterFont("fonts/normalFont");
// float color[4] = { 1.0f, 1.0f, 1.0f, 1.0f };
//
// Game::R_AddCmdDrawText("test^==preview_mp_rustzob", 0x7FFFFFFF, font, 500.0f, 150.0f, 1.0f, 1.0f, 0.0f, color, Game::ITEM_TEXTSTYLE_SHADOWED);
// });
} }
Materials::~Materials() Materials::~Materials()

View File

@ -11,17 +11,16 @@ namespace Components
#endif #endif
private: private:
class VerifyContainer static int ImageNameLength;
{
public:
bool isValid;
Game::Material* material;
};
static Utils::Hook ImageVersionCheckHook; static Utils::Hook ImageVersionCheckHook;
static void ImageVersionCheck(); static void ImageVersionCheck();
static Game::Material* VerifyMaterial(Game::Material* material); static Game::Material* ResolveMaterial(const char* stringPtr);
static void DrawMaterialStub(); static void DrawMaterialStub();
static void PostDrawMaterialStub();
static int WriteDeathMessageIcon(char* string, int offset, Game::Material* material);
static void DeathMessageStub();
}; };
} }

View File

@ -21,6 +21,8 @@ namespace Components
Game::StringTable* StringTable::LoadObject(std::string filename) Game::StringTable* StringTable::LoadObject(std::string filename)
{ {
filename = Utils::String::ToLower(filename);
Game::StringTable* table = nullptr; Game::StringTable* table = nullptr;
FileSystem::File rawTable(filename); FileSystem::File rawTable(filename);
@ -73,6 +75,8 @@ namespace Components
{ {
Game::XAssetHeader header = { 0 }; Game::XAssetHeader header = { 0 };
filename = Utils::String::ToLower(filename);
if (StringTable::StringTableMap.find(filename) != StringTable::StringTableMap.end()) if (StringTable::StringTableMap.find(filename) != StringTable::StringTableMap.end())
{ {
header.stringTable = StringTable::StringTableMap[filename]; header.stringTable = StringTable::StringTableMap[filename];