Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add effects "Hello, this is Agatha" & "Dave Here" #3528

Open
wants to merge 12 commits into
base: master
Choose a base branch
from
3 changes: 3 additions & 0 deletions ChaosMod/ChaosMod.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@
<ClCompile Include="Components\DebugMenu.cpp" />
<ClCompile Include="Components\DebugSocket.cpp" />
<ClCompile Include="Components\EffectShortcuts.cpp" />
<ClCompile Include="Components\Globals.cpp" />
<ClCompile Include="dllmain.cpp" />
<ClCompile Include="Components\EffectDispatcher.cpp" />
<ClCompile Include="Effects\db\Meta\MetaAdditionalEffects.cpp" />
Expand All @@ -115,6 +116,7 @@
<ClCompile Include="Effects\db\Misc\MiscNoWaypoint.cpp" />
<ClCompile Include="Effects\db\Misc\MiscPause.cpp" />
<ClCompile Include="Effects\db\Misc\MiscPayRespects.cpp" />
<ClCompile Include="Effects\db\Misc\MiscPhoneCall.cpp" />
<ClCompile Include="Effects\db\Misc\MiscPortraitMode.cpp" />
<ClCompile Include="Effects\db\Misc\MiscNoSky.cpp" />
<ClCompile Include="Effects\db\Misc\MiscRampJam.cpp" />
Expand Down Expand Up @@ -413,6 +415,7 @@
<ClInclude Include="Components\DebugSocket.h" />
<ClInclude Include="Components\EffectDispatcher.h" />
<ClInclude Include="Components\EffectShortcuts.h" />
<ClInclude Include="Components\Globals.h" />
<ClInclude Include="Effects\EffectCategory.h" />
<ClInclude Include="Effects\EffectConfig.h" />
<ClInclude Include="Effects\EffectAttributes.h" />
Expand Down
90 changes: 90 additions & 0 deletions ChaosMod/Components/Globals.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
#include <stdafx.h>

#include "Globals.h"

#include "Lib/scrThread.h"

#include "Memory/Script.h"

std::vector<Globals::GlobalRegistration> ms_GlobalsRegistration = {};

Globals::Globals() : Component()
{
m_SearchGlobalsListener.Register(
Hooks::OnScriptThreadRun,
[&](rage::scrThread *thread)
{
if (ms_GlobalsRegistration.size() <= 0)
{
return true;
}

auto match =
std::find_if(ms_GlobalsRegistration.begin(), ms_GlobalsRegistration.end(),
[&thread](GlobalRegistration &reg) { return reg.m_ScriptName == thread->GetName(); });

if (match == ms_GlobalsRegistration.end())
{
return true;
}

GlobalRegistration searchedGlobal = *match;

auto program = Memory::ScriptThreadToProgram(thread);
if (program->m_CodeBlocks)
{
Handle handle = Memory::FindScriptPattern(searchedGlobal.m_Pattern, program);

if (!handle.IsValid())
{
LOG("Failed to find global \"" << searchedGlobal.m_Name << "\"");
}
else
{
int globalIndex;

if (searchedGlobal.m_PatternIdiom == GlobalPatternIdiom::GLOBAL_U16)
{
globalIndex = handle.At(searchedGlobal.m_Offset).Value<uint16_t>() & 0xFFFFFF;
}
else
{
globalIndex = handle.At(searchedGlobal.m_Offset).Value<uint32_t>() & 0xFFFFFF;
}

Globals::SetGlobal(searchedGlobal, globalIndex);

LOG("Found global \"" << searchedGlobal.m_Name << "\" (Global: " << globalIndex << ")");
}
}

ms_GlobalsRegistration.erase(match);

return true;
});
}

bool Globals::Searching(int handle)
{
return std::find_if(ms_GlobalsRegistration.begin(), ms_GlobalsRegistration.end(),
[&](GlobalRegistration &reg) { return reg.m_Handle == handle; })
!= ms_GlobalsRegistration.end();
}

int Globals::RegisterGlobal(std::string name, std::string scriptName, std::string pattern,
int patternOffset, GlobalPatternIdiom patternIdiom)
{
if (std::find_if(ms_GlobalsRegistration.begin(), ms_GlobalsRegistration.end(),
[&](GlobalRegistration &reg) { return reg.m_Name == name; })
!= ms_GlobalsRegistration.end()
|| Globals::GlobalFoundName(name))
{
return -1;
}

int handle = GetTickCount(); // Allows the handle to be truly unique

ms_GlobalsRegistration.push_back({ name, scriptName, pattern, patternOffset, patternIdiom, handle });

return handle;
}
97 changes: 97 additions & 0 deletions ChaosMod/Components/Globals.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
#pragma once

#include "Components/Component.h"

#include "Memory/Hooks/ScriptThreadRunHook.h"

#include <map>
#include <vector>

enum class GlobalPatternIdiom : uint8_t
{
GLOBAL_U16,
GLOBAL_U24
};

class Globals : public Component
{
public:
struct GlobalRegistration
{
public:
std::string m_Name;
std::string m_ScriptName;
std::string m_Pattern;
int m_Offset;
int m_Index = -1;
int m_Handle;
GlobalPatternIdiom m_PatternIdiom;

GlobalRegistration(std::string name, std::string scriptName, std::string pattern, int offset,
GlobalPatternIdiom patternIdiom, int handle)
: m_Name(name),
m_ScriptName(scriptName),
m_Pattern(pattern),
m_Offset(offset),
m_PatternIdiom(patternIdiom),
m_Handle(handle)
{
}
};

private:
static inline std::vector<GlobalRegistration> ms_Globals = {};

CHAOS_EVENT_LISTENER(Hooks::OnScriptThreadRun) m_SearchGlobalsListener;

static bool GetGlobalWhere()
{
return false;
}

protected:
Globals();

public:
static void SetGlobal(GlobalRegistration &reg, int index)
{
reg.m_Index = index;
ms_Globals.push_back(reg);
}

template <typename T> static T *GetGlobalAddr(int handle)
{
auto it = std::find_if(ms_Globals.begin(), ms_Globals.end(),
[&](GlobalRegistration &reg) { return reg.m_Handle == handle; });

if (it == ms_Globals.end())
{
return nullptr;
}

return reinterpret_cast<T *>(Memory::GetGlobalPtr(it->m_Index));
}

// used by RegisterGlobal to check if it wasn't already registered
static bool GlobalFoundName(std::string name)
{
return std::find_if(ms_Globals.begin(), ms_Globals.end(),
[&](GlobalRegistration &reg) { return reg.m_Name == name; })
!= ms_Globals.end();
}

static bool GlobalFound(int handle)
{
return std::find_if(ms_Globals.begin(), ms_Globals.end(),
[&](GlobalRegistration &reg) { return reg.m_Handle == handle; })
!= ms_Globals.end();
}

static bool Searching(int handle);
static int RegisterGlobal(std::string name, std::string scriptName, std::string pattern, int patternOffset,
GlobalPatternIdiom patternIdiom);

template <class T>
requires std::is_base_of_v<Component, T>
friend struct ComponentHolder;
};
Loading