Theater stuff.
This commit is contained in:
parent
d70836e825
commit
0bcbd75787
@ -21,6 +21,7 @@ namespace Components
|
|||||||
Loader::Register(new Console());
|
Loader::Register(new Console());
|
||||||
Loader::Register(new IPCPipe());
|
Loader::Register(new IPCPipe());
|
||||||
Loader::Register(new Network());
|
Loader::Register(new Network());
|
||||||
|
Loader::Register(new Theatre());
|
||||||
Loader::Register(new Download());
|
Loader::Register(new Download());
|
||||||
Loader::Register(new Playlist());
|
Loader::Register(new Playlist());
|
||||||
Loader::Register(new RawFiles());
|
Loader::Register(new RawFiles());
|
||||||
|
@ -32,6 +32,7 @@ namespace Components
|
|||||||
#include "Modules\Console.hpp"
|
#include "Modules\Console.hpp"
|
||||||
#include "Modules\IPCPipe.hpp"
|
#include "Modules\IPCPipe.hpp"
|
||||||
#include "Modules\Network.hpp"
|
#include "Modules\Network.hpp"
|
||||||
|
#include "Modules\Theatre.hpp"
|
||||||
#include "Modules\Party.hpp" // Destroys the order, but requires network classes :D
|
#include "Modules\Party.hpp" // Destroys the order, but requires network classes :D
|
||||||
#include "Modules\Download.hpp"
|
#include "Modules\Download.hpp"
|
||||||
#include "Modules\Playlist.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_CloseAll_t Menus_CloseAll = (Menus_CloseAll_t)0x4BA5B0;
|
||||||
Menus_OpenByName_t Menus_OpenByName = (Menus_OpenByName_t)0x4CCE60;
|
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_AdrToString_t NET_AdrToString = (NET_AdrToString_t)0x469880;
|
||||||
NET_CompareAdr_t NET_CompareAdr = (NET_CompareAdr_t)0x4D0AA0;
|
NET_CompareAdr_t NET_CompareAdr = (NET_CompareAdr_t)0x4D0AA0;
|
||||||
NET_IsLocalAddress_t NET_IsLocalAddress = (NET_IsLocalAddress_t)0x402BD0;
|
NET_IsLocalAddress_t NET_IsLocalAddress = (NET_IsLocalAddress_t)0x402BD0;
|
||||||
@ -140,6 +152,10 @@ namespace Game
|
|||||||
int* numIP = (int*)0x64A1E68;
|
int* numIP = (int*)0x64A1E68;
|
||||||
netIP_t* localIP = (netIP_t*)0x64A1E28;
|
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)
|
void* ReallocateAssetPool(XAssetType type, unsigned int newSize)
|
||||||
{
|
{
|
||||||
int elSize = DB_GetXAssetSizeHandlers[type]();
|
int elSize = DB_GetXAssetSizeHandlers[type]();
|
||||||
|
@ -145,6 +145,45 @@ namespace Game
|
|||||||
typedef int(__cdecl * Menus_OpenByName_t)(UiContext *dc, const char *p);
|
typedef int(__cdecl * Menus_OpenByName_t)(UiContext *dc, const char *p);
|
||||||
extern Menus_OpenByName_t Menus_OpenByName;
|
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);
|
typedef const char* (__cdecl * NET_AdrToString_t)(netadr_t adr);
|
||||||
extern NET_AdrToString_t NET_AdrToString;
|
extern NET_AdrToString_t NET_AdrToString;
|
||||||
|
|
||||||
@ -271,6 +310,10 @@ namespace Game
|
|||||||
extern int* numIP;
|
extern int* numIP;
|
||||||
extern netIP_t* localIP;
|
extern netIP_t* localIP;
|
||||||
|
|
||||||
|
extern int* demoFile;
|
||||||
|
extern int* demoPlaying;
|
||||||
|
extern int* serverMessageSequence;
|
||||||
|
|
||||||
void* ReallocateAssetPool(XAssetType type, unsigned int newSize);
|
void* ReallocateAssetPool(XAssetType type, unsigned int newSize);
|
||||||
void Menu_FreeItemMemory(Game::itemDef_t* item);
|
void Menu_FreeItemMemory(Game::itemDef_t* item);
|
||||||
void OOBPrintT(int type, netadr_t netadr, const char* message);
|
void OOBPrintT(int type, netadr_t netadr, const char* message);
|
||||||
|
@ -644,14 +644,16 @@ namespace Game
|
|||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
int unknown1;
|
int overflowed;
|
||||||
int unknown2;
|
int readOnly;
|
||||||
char* data;
|
char *data;
|
||||||
int unknown3;
|
char *splitData;
|
||||||
int maxsize; // 16
|
int maxsize;
|
||||||
int cursize;
|
int cursize;
|
||||||
int unknown4;
|
int splitSize;
|
||||||
int readcount; // 28
|
int readcount;
|
||||||
|
int bit;
|
||||||
|
int lastEntityRef;
|
||||||
} msg_t;
|
} msg_t;
|
||||||
|
|
||||||
#pragma pack(push, 1)
|
#pragma pack(push, 1)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user