Theater stuff.
This commit is contained in:
parent
d70836e825
commit
0bcbd75787
@ -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());
|
||||
|
@ -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"
|
||||
|
167
src/Components/Modules/Theatre.cpp
Normal file
167
src/Components/Modules/Theatre.cpp
Normal 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;
|
||||
}
|
||||
}
|
25
src/Components/Modules/Theatre.hpp
Normal file
25
src/Components/Modules/Theatre.hpp
Normal 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();
|
||||
};
|
||||
}
|
@ -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]();
|
||||
|
@ -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);
|
||||
|
@ -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)
|
||||
|
Loading…
Reference in New Issue
Block a user