Theater done.

This commit is contained in:
momo5502 2016-01-10 15:48:49 +01:00
parent 519c298b0b
commit 99f5d2cd81
7 changed files with 87 additions and 5 deletions

View File

@ -17,7 +17,7 @@ namespace Components
_time64(&time); _time64(&time);
ltime = _localtime64(&time); ltime = _localtime64(&time);
strftime(filename, sizeof(filename) - 1, "iw4m-" VERSION_STR "-%Y%m%d%H%M%S.dmp", ltime); strftime(filename, sizeof(filename) - 1, "iw4x-" VERSION_STR "-%Y%m%d%H%M%S.dmp", ltime);
HANDLE hFile = CreateFile(filename, GENERIC_WRITE, FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); HANDLE hFile = CreateFile(filename, GENERIC_WRITE, FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);

View File

@ -263,14 +263,67 @@ namespace Components
Dvar::Var("ui_demo_mapname").Set(info.Mapname); Dvar::Var("ui_demo_mapname").Set(info.Mapname);
Dvar::Var("ui_demo_mapname_localized").Set(Game::UI_LocalizeMapName(info.Mapname.data())); Dvar::Var("ui_demo_mapname_localized").Set(Game::UI_LocalizeMapName(info.Mapname.data()));
Dvar::Var("ui_demo_gametype").Set(Game::UI_LocalizeGameType(info.Gametype.data())); Dvar::Var("ui_demo_gametype").Set(Game::UI_LocalizeGameType(info.Gametype.data()));
Dvar::Var("ui_demo_length").Set(info.Length); // TODO: Parse as readable string Dvar::Var("ui_demo_length").Set(Utils::FormatTimeSpan(info.Length)); // TODO: Parse as readable string
Dvar::Var("ui_demo_author").Set(info.Author); Dvar::Var("ui_demo_author").Set(info.Author);
Dvar::Var("ui_demo_date").Set(std::asctime(std::localtime(&info.TimeStamp))); Dvar::Var("ui_demo_date").Set(std::asctime(std::localtime(&info.TimeStamp)));
} }
} }
uint32_t Theatre::InitCGameStub()
{
if (Dvar::Var("cl_autoRecord").Get<bool>() && !*Game::demoPlaying)
{
std::vector<std::string> files;
std::vector<std::string> demos = FileSystem::GetFileList("demos/", "dm_13");
for (auto demo : demos)
{
if (Utils::StartsWith(demo, "auto_"))
{
files.push_back(demo);
}
}
int numDel = files.size() - Dvar::Var("cl_demosKeep").Get<int>();
for (int i = 0; i < numDel; i++)
{
Logger::Print("Deleting old demo %s\n", files[i].data());
FileSystem::DeleteFile("demos", files[i].data());
FileSystem::DeleteFile("demos", Utils::VA("%s.json", files[i].data()));
}
Command::Execute(Utils::VA("record auto_%I64d", time(0)), true);
}
return Utils::Hook::Call<DWORD()>(0x42BBB0)();
}
void Theatre::MapChangeStub()
{
if (*Game::demoRecording)
{
Command::Execute("stoprecord", true);
}
Utils::Hook::Call<void()>(0x464A60)();
}
void Theatre::MapChangeSVStub(char* a1, char* a2)
{
if (*Game::demoRecording)
{
Command::Execute("stoprecord", true);
}
Utils::Hook::Call<void(char*, char*)>(0x487C50)(a1, a2);
}
Theatre::Theatre() Theatre::Theatre()
{ {
Dvar::Register<bool>("cl_autoRecord", true, Game::dvar_flag::DVAR_FLAG_SAVED, "Automatically record games.");
Dvar::Register<int>("cl_demosKeep", 30, 1, 999, Game::dvar_flag::DVAR_FLAG_SAVED, "How many demos to keep with autorecord.");
Utils::Hook(0x5A8370, Theatre::GamestateWriteStub, HOOK_CALL).Install()->Quick(); Utils::Hook(0x5A8370, Theatre::GamestateWriteStub, HOOK_CALL).Install()->Quick();
Utils::Hook(0x5A85D2, Theatre::RecordGamestateStub, HOOK_CALL).Install()->Quick(); Utils::Hook(0x5A85D2, Theatre::RecordGamestateStub, HOOK_CALL).Install()->Quick();
Utils::Hook(0x5ABE36, Theatre::BaselineStoreStub, HOOK_JUMP).Install()->Quick(); Utils::Hook(0x5ABE36, Theatre::BaselineStoreStub, HOOK_JUMP).Install()->Quick();
@ -283,6 +336,11 @@ namespace Components
Utils::Hook(0x5A82AE, Theatre::RecordStub, HOOK_CALL).Install()->Quick(); Utils::Hook(0x5A82AE, Theatre::RecordStub, HOOK_CALL).Install()->Quick();
Utils::Hook(0x5A8156, Theatre::StopRecordStub, HOOK_CALL).Install()->Quick(); Utils::Hook(0x5A8156, Theatre::StopRecordStub, HOOK_CALL).Install()->Quick();
// Autorecording
Utils::Hook(0x5A1D6A, Theatre::InitCGameStub, HOOK_CALL).Install()->Quick();
Utils::Hook(0x4A712A, Theatre::MapChangeStub, HOOK_CALL).Install()->Quick();
Utils::Hook(0x5AA91C, Theatre::MapChangeSVStub, HOOK_CALL).Install()->Quick();
// UIScripts // UIScripts
UIScript::Add("loadDemos", Theatre::LoadDemos); UIScript::Add("loadDemos", Theatre::LoadDemos);
UIScript::Add("launchDemo", Theatre::PlayDemo); UIScript::Add("launchDemo", Theatre::PlayDemo);

View File

@ -61,6 +61,10 @@ namespace Components
static void ServerTimedOutStub(); static void ServerTimedOutStub();
static void UISetActiveMenuStub(); static void UISetActiveMenuStub();
static uint32_t InitCGameStub();
static void MapChangeStub();
static void MapChangeSVStub(char* a1, char* a2);
static void RecordStub(int channel, char* message, char* file); static void RecordStub(int channel, char* message, char* file);
static void StopRecordStub(int channel, char* message); static void StopRecordStub(int channel, char* message);
}; };

View File

@ -154,6 +154,7 @@ namespace Game
int* demoFile = (int*)0xA5EA1C; int* demoFile = (int*)0xA5EA1C;
int* demoPlaying = (int*)0xA5EA0C; int* demoPlaying = (int*)0xA5EA0C;
int* demoRecording = (int*)0xA5EA08;
int* serverMessageSequence = (int*)0xA3E9B4; int* serverMessageSequence = (int*)0xA3E9B4;
void* ReallocateAssetPool(XAssetType type, unsigned int newSize) void* ReallocateAssetPool(XAssetType type, unsigned int newSize)

View File

@ -312,6 +312,7 @@ namespace Game
extern int* demoFile; extern int* demoFile;
extern int* demoPlaying; extern int* demoPlaying;
extern int* demoRecording;
extern int* serverMessageSequence; extern int* serverMessageSequence;
void* ReallocateAssetPool(XAssetType type, unsigned int newSize); void* ReallocateAssetPool(XAssetType type, unsigned int newSize);

View File

@ -25,9 +25,9 @@ namespace Utils
return input; return input;
} }
bool EndsWith(const char* heystack, const char* needle) bool EndsWith(const char* haystack, const char* needle)
{ {
return (strstr(heystack, needle) == (heystack + strlen(heystack) - strlen(needle))); return (strstr(haystack, needle) == (haystack + strlen(haystack) - strlen(needle)));
} }
std::vector<std::string> Explode(const std::string& str, char delim) std::vector<std::string> Explode(const std::string& str, char delim)
@ -62,6 +62,11 @@ namespace Utils
} }
} }
bool StartsWith(std::string haystack, std::string needle)
{
return (haystack.size() >= needle.size() && !strncmp(needle.data(), haystack.data(), needle.size()));
}
unsigned int OneAtATime(const char *key, size_t len) unsigned int OneAtATime(const char *key, size_t len)
{ {
unsigned int hash, i; unsigned int hash, i;
@ -97,6 +102,17 @@ namespace Utils
return LTrim(RTrim(s)); return LTrim(RTrim(s));
} }
std::string FormatTimeSpan(int milliseconds)
{
int secondsTotal = milliseconds / 1000;
int seconds = secondsTotal % 60;
int minutesTotal = secondsTotal / 60;
int minutes = minutesTotal % 60;
int hoursTotal = minutesTotal / 60;
return Utils::VA("%02d:%02d:%02d", hoursTotal, minutes, seconds);
}
std::string ParseChallenge(std::string data) std::string ParseChallenge(std::string data)
{ {
// Ensure line break // Ensure line break

View File

@ -2,14 +2,16 @@ namespace Utils
{ {
const char *VA(const char *fmt, ...); const char *VA(const char *fmt, ...);
std::string StrToLower(std::string input); std::string StrToLower(std::string input);
bool EndsWith(const char* heystack, const char* needle); bool EndsWith(const char* haystack, const char* needle);
std::vector<std::string> Explode(const std::string& str, char delim); std::vector<std::string> Explode(const std::string& str, char delim);
void Replace(std::string &string, std::string find, std::string replace); void Replace(std::string &string, std::string find, std::string replace);
bool StartsWith(std::string haystack, std::string needle);
unsigned int OneAtATime(const char *key, size_t len); unsigned int OneAtATime(const char *key, size_t len);
std::string &LTrim(std::string &s); std::string &LTrim(std::string &s);
std::string &RTrim(std::string &s); std::string &RTrim(std::string &s);
std::string &Trim(std::string &s); std::string &Trim(std::string &s);
std::string FormatTimeSpan(int milliseconds);
std::string ParseChallenge(std::string data); std::string ParseChallenge(std::string data);
bool FileExists(std::string file); bool FileExists(std::string file);