Theater stuff.

This commit is contained in:
momo5502 2016-01-09 20:56:28 +01:00
parent d70836e825
commit 0bcbd75787
7 changed files with 262 additions and 7 deletions

View File

@ -21,6 +21,7 @@ namespace Components
Loader::Register(new Console());
Loader::Register(new IPCPipe());
Loader::Register(new Network());
Loader::Register(new Theatre());
Loader::Register(new Download());
Loader::Register(new Playlist());
Loader::Register(new RawFiles());

View File

@ -32,6 +32,7 @@ namespace Components
#include "Modules\Console.hpp"
#include "Modules\IPCPipe.hpp"
#include "Modules\Network.hpp"
#include "Modules\Theatre.hpp"
#include "Modules\Party.hpp" // Destroys the order, but requires network classes :D
#include "Modules\Download.hpp"
#include "Modules\Playlist.hpp"

View File

@ -0,0 +1,167 @@
#include "STDInclude.hpp"
namespace Components
{
char Theatre::BaselineSnapshot[131072] = { 0 };
PBYTE Theatre::BaselineSnapshotMsg = 0;
int Theatre::BaselineSnapshotMsgLen;
int Theatre::BaselineSnapshotMsgOff;
void Theatre::GamestateWriteStub(Game::msg_t* msg, char byte)
{
Game::MSG_WriteLong(msg, 0);
Game::MSG_WriteByte(msg, byte);
}
void Theatre::RecordGamestateStub()
{
int sequence = (*Game::serverMessageSequence - 1);
Game::FS_Write(&sequence, 4, *Game::demoFile);
}
void __declspec(naked) Theatre::BaselineStoreStub()
{
// Store snapshot message
__asm mov Theatre::BaselineSnapshotMsg, edi
// Store offset and length
Theatre::BaselineSnapshotMsgLen = *(int*)(Theatre::BaselineSnapshotMsg + 20);
Theatre::BaselineSnapshotMsgOff = *(int*)(Theatre::BaselineSnapshotMsg + 28) - 7;
// Copy to our snapshot buffer
memcpy(Theatre::BaselineSnapshot, *(DWORD**)(Theatre::BaselineSnapshotMsg + 8), *(DWORD*)(Theatre::BaselineSnapshotMsg + 20));
__asm
{
mov edx, 5ABEF5h
jmp edx
}
}
void Theatre::WriteBaseline()
{
static char bufData[131072];
static char cmpData[131072];
Game::msg_t buf;
Game::MSG_Init(&buf, bufData, 131072);
Game::MSG_WriteData(&buf, &Theatre::BaselineSnapshot[Theatre::BaselineSnapshotMsgOff], Theatre::BaselineSnapshotMsgLen - Theatre::BaselineSnapshotMsgOff);
Game::MSG_WriteByte(&buf, 6);
int compressedSize = Game::MSG_WriteBitsCompress(false, buf.data, cmpData, buf.cursize);
int fileCompressedSize = compressedSize + 4;
int byte8 = 8;
char byte0 = 0;
Game::FS_Write(&byte0, 1, *Game::demoFile);
Game::FS_Write(Game::serverMessageSequence, 4, *Game::demoFile);
Game::FS_Write(&fileCompressedSize, 4, *Game::demoFile);
Game::FS_Write(&byte8, 4, *Game::demoFile);
for (int i = 0; i < compressedSize; i += 1024)
{
int size = min(compressedSize - i, 1024);
if (i + size >= sizeof(cmpData))
{
Logger::Print("Error: Writing compressed demo baseline exceeded buffer\n");
break;
}
Game::FS_Write(&cmpData[i], size, *Game::demoFile);
}
}
void __declspec(naked) Theatre::BaselineToFileStub()
{
__asm
{
call Theatre::WriteBaseline
// Restore overwritten operation
mov ecx, 0A5E9C4h
mov [ecx], 0
// Return to original code
mov ecx, 5A863Ah
jmp ecx
}
}
void __declspec(naked) Theatre::AdjustTimeDeltaStub()
{
__asm
{
mov eax, Game::demoPlaying
mov eax, [eax]
test al, al
jz continue
// delta doesn't drift for demos
retn
continue:
mov eax, 5A1AD0h
jmp eax
}
}
void __declspec(naked) Theatre::ServerTimedOutStub()
{
__asm
{
mov eax, Game::demoPlaying
mov eax, [eax]
test al, al
jz continue
mov eax, 5A8E70h
jmp eax
continue:
mov eax, 0B2BB90h
mov esi, 5A8E08h
jmp esi
}
}
void __declspec(naked) Theatre::UISetActiveMenuStub()
{
if (*Game::demoPlaying == 1)
{
__asm
{
mov eax, 4CB49Ch
jmp eax
}
}
__asm
{
mov ecx, [esp + 10h]
push 10h
push ecx
mov eax, 4CB3F6h
jmp eax
}
}
Theatre::Theatre()
{
Utils::Hook(0x5A8370, Theatre::GamestateWriteStub, HOOK_CALL).Install()->Quick();
Utils::Hook(0x5A85D2, Theatre::RecordGamestateStub, HOOK_CALL).Install()->Quick();
Utils::Hook(0x5ABE36, Theatre::BaselineStoreStub, HOOK_JUMP).Install()->Quick();
Utils::Hook(0x5A8630, Theatre::BaselineToFileStub, HOOK_JUMP).Install()->Quick();
Utils::Hook(0x4CB3EF, Theatre::UISetActiveMenuStub, HOOK_JUMP).Install()->Quick();
Utils::Hook(0x50320E, Theatre::AdjustTimeDeltaStub, HOOK_CALL).Install()->Quick();
Utils::Hook(0x5A8E03, Theatre::ServerTimedOutStub, HOOK_JUMP).Install()->Quick();
// set the configstrings stuff to load the default (empty) string table; this should allow demo recording on all gametypes/maps
if(!Dedicated::IsDedicated()) Utils::Hook::Set<char*>(0x47440B, "mp/defaultStringTable.csv");
*(BYTE*)0x5AC854 = 4;
*(BYTE*)0x5AC85A = 4;
}
}

View File

@ -0,0 +1,25 @@
namespace Components
{
class Theatre : public Component
{
public:
Theatre();
const char* GetName() { return "Theatre"; };
private:
static char BaselineSnapshot[131072];
static PBYTE BaselineSnapshotMsg;
static int BaselineSnapshotMsgLen;
static int BaselineSnapshotMsgOff;
static void WriteBaseline();
static void GamestateWriteStub(Game::msg_t* msg, char byte);
static void RecordGamestateStub();
static void BaselineStoreStub();
static void BaselineToFileStub();
static void AdjustTimeDeltaStub();
static void ServerTimedOutStub();
static void UISetActiveMenuStub();
};
}

View File

@ -62,6 +62,18 @@ namespace Game
Menus_CloseAll_t Menus_CloseAll = (Menus_CloseAll_t)0x4BA5B0;
Menus_OpenByName_t Menus_OpenByName = (Menus_OpenByName_t)0x4CCE60;
MSG_Init_t MSG_Init = (MSG_Init_t)0x45FCA0;
MSG_ReadData_t MSG_ReadData = (MSG_ReadData_t)0x4527C0;
MSG_ReadLong_t MSG_ReadLong = (MSG_ReadLong_t)0x4C9550;
MSG_ReadShort_t MSG_ReadShort = (MSG_ReadShort_t)0x40BDD0;
MSG_ReadInt64_t MSG_ReadInt64 = (MSG_ReadInt64_t)0x4F1850;
MSG_ReadString_t MSG_ReadString = (MSG_ReadString_t)0x60E2B0;
MSG_WriteByte_t MSG_WriteByte = (MSG_WriteByte_t)0x48C520;
MSG_WriteData_t MSG_WriteData = (MSG_WriteData_t)0x4F4120;
MSG_WriteLong_t MSG_WriteLong = (MSG_WriteLong_t)0x41CA20;
MSG_WriteBitsCompress_t MSG_WriteBitsCompress = (MSG_WriteBitsCompress_t)0x4319D0;
MSG_ReadByte_t MSG_ReadByte = (MSG_ReadByte_t)0x4C1C20;
NET_AdrToString_t NET_AdrToString = (NET_AdrToString_t)0x469880;
NET_CompareAdr_t NET_CompareAdr = (NET_CompareAdr_t)0x4D0AA0;
NET_IsLocalAddress_t NET_IsLocalAddress = (NET_IsLocalAddress_t)0x402BD0;
@ -140,6 +152,10 @@ namespace Game
int* numIP = (int*)0x64A1E68;
netIP_t* localIP = (netIP_t*)0x64A1E28;
int* demoFile = (int*)0xA5EA1C;
int* demoPlaying = (int*)0xA5EA0C;
int* serverMessageSequence = (int*)0xA3E9B4;
void* ReallocateAssetPool(XAssetType type, unsigned int newSize)
{
int elSize = DB_GetXAssetSizeHandlers[type]();

View File

@ -145,6 +145,45 @@ namespace Game
typedef int(__cdecl * Menus_OpenByName_t)(UiContext *dc, const char *p);
extern Menus_OpenByName_t Menus_OpenByName;
typedef void(__cdecl * MSG_Init_t)(void* msg, void* data, int maxsize);
extern MSG_Init_t MSG_Init;
typedef int(__cdecl * MSG_ReadData_t)(msg_t* msg, char*, size_t);
extern MSG_ReadData_t MSG_ReadData;
typedef int(__cdecl * MSG_ReadLong_t)(msg_t* msg);
extern MSG_ReadLong_t MSG_ReadLong;
typedef short(__cdecl * MSG_ReadShort_t)(msg_t* msg);
extern MSG_ReadShort_t MSG_ReadShort;
typedef __int64(__cdecl * MSG_ReadInt64_t)(msg_t* msg);
extern MSG_ReadInt64_t MSG_ReadInt64;
typedef char* (__cdecl * MSG_ReadString_t)(msg_t*);
extern MSG_ReadString_t MSG_ReadString;
typedef void(__cdecl * MSG_WriteByte_t)(msg_t* msg, unsigned char);
extern MSG_WriteByte_t MSG_WriteByte;
typedef void(__cdecl * MSG_WriteData_t)(msg_t* msg, char*, size_t);
extern MSG_WriteData_t MSG_WriteData;
typedef void(__cdecl * MSG_WriteLong_t)(msg_t* msg, int);
extern MSG_WriteLong_t MSG_WriteLong;
typedef int(__cdecl * MSG_WriteBitsCompress_t)(bool trainHuffman, const char *from, char *to, int size);
extern MSG_WriteBitsCompress_t MSG_WriteBitsCompress;
typedef short(__cdecl * MSG_ReadShort_t)(msg_t* msg);
extern MSG_ReadShort_t MSG_ReadShort;
typedef __int64(__cdecl * MSG_ReadInt64_t)(msg_t* msg);
extern MSG_ReadInt64_t MSG_ReadInt64;
typedef int(__cdecl * MSG_ReadByte_t)(msg_t* msg);
extern MSG_ReadByte_t MSG_ReadByte;
typedef const char* (__cdecl * NET_AdrToString_t)(netadr_t adr);
extern NET_AdrToString_t NET_AdrToString;
@ -271,6 +310,10 @@ namespace Game
extern int* numIP;
extern netIP_t* localIP;
extern int* demoFile;
extern int* demoPlaying;
extern int* serverMessageSequence;
void* ReallocateAssetPool(XAssetType type, unsigned int newSize);
void Menu_FreeItemMemory(Game::itemDef_t* item);
void OOBPrintT(int type, netadr_t netadr, const char* message);

View File

@ -644,14 +644,16 @@ namespace Game
typedef struct
{
int unknown1;
int unknown2;
char* data;
int unknown3;
int maxsize; // 16
int overflowed;
int readOnly;
char *data;
char *splitData;
int maxsize;
int cursize;
int unknown4;
int readcount; // 28
int splitSize;
int readcount;
int bit;
int lastEntityRef;
} msg_t;
#pragma pack(push, 1)