aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--GameInjector/dllmain.cpp18
-rw-r--r--LauncherInjector/main.cpp2
-rw-r--r--NorthstarDedicatedTest/chatcommand.cpp9
-rw-r--r--NorthstarDedicatedTest/concommand.cpp1
-rw-r--r--NorthstarDedicatedTest/dedicated.cpp170
-rw-r--r--NorthstarDedicatedTest/dedicated.h2
-rw-r--r--NorthstarDedicatedTest/dllmain.cpp3
-rw-r--r--NorthstarDedicatedTest/modmanager.cpp3
-rw-r--r--NorthstarDedicatedTest/squirrel.cpp2
-rw-r--r--NorthstarDedicatedTest/tier0.cpp2
10 files changed, 182 insertions, 30 deletions
diff --git a/GameInjector/dllmain.cpp b/GameInjector/dllmain.cpp
index c18495be..38e262cc 100644
--- a/GameInjector/dllmain.cpp
+++ b/GameInjector/dllmain.cpp
@@ -44,14 +44,21 @@ BOOL WINAPI CreateProcessWHook(
// origin doesn't use lpApplicationName
if (lpApplicationName)
+ {
+ std::wcout << lpApplicationName << std::endl;
isTitanfallProcess = wcsstr(lpApplicationName, L"Titanfall2\\Titanfall2.exe");
+ }
else
+ {
+ std::wcout << lpCommandLine << std::endl;
isTitanfallProcess = wcsstr(lpCommandLine, L"Titanfall2\\Titanfall2.exe");
+ }
- std::wcout << lpCommandLine << std::endl;
+ // steam will start processes suspended
+ bool alreadySuspended = dwCreationFlags & CREATE_SUSPENDED;
// suspend process on creation so we can hook
- if (isTitanfallProcess)
+ if (isTitanfallProcess && !alreadySuspended)
dwCreationFlags |= CREATE_SUSPENDED;
BOOL ret = CreateProcessWOriginal(lpApplicationName, lpCommandLine, lpProcessAttributes, lpThreadAttributes, bInheritHandles, dwCreationFlags, lpEnvironment, lpCurrentDirectory, lpStartupInfo, lpProcessInformation);
@@ -73,7 +80,9 @@ BOOL WINAPI CreateProcessWHook(
CreateProcessA((tf2DirPath / "InjectionProxy64.exe").string().c_str(), (LPSTR)(argStr.str().c_str()), 0, 0, false, 0, 0, tf2DirPath.string().c_str(), (LPSTARTUPINFOA)&si, &pi);
WaitForSingleObject(pi.hThread, INFINITE);
- ResumeThread(lpProcessInformation->hProcess);
+
+ if (!alreadySuspended)
+ ResumeThread(lpProcessInformation->hThread);
MH_RemoveHook(&CreateProcessW);
FreeLibrary(ownHModule);
@@ -98,6 +107,9 @@ BOOL APIENTRY DllMain(HMODULE hModule,
break;
}
+ //AllocConsole();
+ //freopen("CONOUT$", "w", stdout);
+
ownHModule = hModule;
char ownDllPath[MAX_PATH];
GetModuleFileNameA(hModule, ownDllPath, MAX_PATH);
diff --git a/LauncherInjector/main.cpp b/LauncherInjector/main.cpp
index 1f26dfc0..08ae12c3 100644
--- a/LauncherInjector/main.cpp
+++ b/LauncherInjector/main.cpp
@@ -135,7 +135,7 @@ int main()
CreateAndHookUnpackedTitanfallProcess();
}
- // packed origin
+ // packed
else
{
// create a titanfall process, this will cause origin to start launching the game
diff --git a/NorthstarDedicatedTest/chatcommand.cpp b/NorthstarDedicatedTest/chatcommand.cpp
index 4742b5fd..0009cf1c 100644
--- a/NorthstarDedicatedTest/chatcommand.cpp
+++ b/NorthstarDedicatedTest/chatcommand.cpp
@@ -3,24 +3,25 @@
#include "concommand.h"
// note: isIngameChat is an int64 because the whole register the arg is stored in needs to be 0'd out to work
+// if isIngameChat is false, we use network chat instead
typedef void(__fastcall *ClientSayTextType)(void* a1, const char* message, __int64 isIngameChat, bool isTeamChat);
-ClientSayTextType SayText;
+ClientSayTextType ClientSayText;
void ConCommand_say(const CCommand& args)
{
if (args.ArgC() >= 2)
- SayText(nullptr, args.ArgS(), true, false);
+ ClientSayText(nullptr, args.ArgS(), true, false);
}
void ConCommand_say_team(const CCommand& args)
{
if (args.ArgC() >= 2)
- SayText(nullptr, args.ArgS(), true, true);
+ ClientSayText(nullptr, args.ArgS(), true, true);
}
void InitialiseChatCommands(HMODULE baseAddress)
{
- SayText = (ClientSayTextType)((char*)baseAddress + 0x54780);
+ ClientSayText = (ClientSayTextType)((char*)baseAddress + 0x54780);
RegisterConCommand("say", ConCommand_say, "Enters a message in public chat", FCVAR_CLIENTDLL);
RegisterConCommand("say_team", ConCommand_say_team, "Enters a message in team chat", FCVAR_CLIENTDLL);
} \ No newline at end of file
diff --git a/NorthstarDedicatedTest/concommand.cpp b/NorthstarDedicatedTest/concommand.cpp
index 2db46aa2..8cf52b9d 100644
--- a/NorthstarDedicatedTest/concommand.cpp
+++ b/NorthstarDedicatedTest/concommand.cpp
@@ -27,5 +27,6 @@ void InitialiseConCommands(HMODULE baseAddress)
{
conCommandConstructor = (ConCommandConstructorType)((char*)baseAddress + 0x415F60);
+ // this shouldn't be here but idk where else to put it rn
RegisterConCommand("setplaylist", SetPlaylistCommand, "", FCVAR_NONE);
} \ No newline at end of file
diff --git a/NorthstarDedicatedTest/dedicated.cpp b/NorthstarDedicatedTest/dedicated.cpp
index c7663201..67cb66d2 100644
--- a/NorthstarDedicatedTest/dedicated.cpp
+++ b/NorthstarDedicatedTest/dedicated.cpp
@@ -7,7 +7,7 @@
bool IsDedicated()
{
// temp: should get this from commandline
- return true;
+ //return true;
return false;
}
@@ -23,29 +23,79 @@ enum EngineState_t
struct CEngine
{
public:
- char unknown[12];
-
+ void* vtable;
+
+ int m_nQuitting;
EngineState_t m_nDllState;
EngineState_t m_nNextDllState;
+ double m_flCurrentTime;
+ float m_flFrameTime;
+ double m_flPreviousTime;
+ float m_flFilteredTime;
+ float m_flMinFrameTime; // Expected duration of a frame, or zero if it is unlimited.
+};
+
+enum HostState_t
+{
+ HS_NEW_GAME = 0,
+ HS_LOAD_GAME,
+ HS_CHANGE_LEVEL_SP,
+ HS_CHANGE_LEVEL_MP,
+ HS_RUN,
+ HS_GAME_SHUTDOWN,
+ HS_SHUTDOWN,
+ HS_RESTART,
+};
+
+struct CHostState
+{
+ HostState_t m_currentState;
+ HostState_t m_nextState;
+
+ float m_vecLocationX;
+ float m_vecLocationY;
+ float m_vecLocationZ;
+
+ float m_angLocationX;
+ float m_angLocationY;
+ float m_angLocationZ;
+
+ char m_levelName[32];
+
+ // there's more stuff here, just this is all i use atm
};
void InitialiseDedicated(HMODULE engineAddress)
{
spdlog::info("InitialiseDedicated");
- while (!IsDebuggerPresent())
- Sleep(100);
+ //while (!IsDebuggerPresent())
+ // Sleep(100);
// create binary patches
+ //{
+ // // CEngineAPI::SetStartupInfo
+ // // prevents englishclient_frontend from loading
+ //
+ // char* ptr = (char*)engineAddress + 0x1C7CBE;
+ // TempReadWrite rw(ptr);
+ //
+ // // je => jmp
+ // *ptr = (char)0xEB;
+ //}
+
{
- // CEngineAPI::SetStartupInfo
- // prevents englishclient_frontend from loading
+ // Host_Init
+ // prevent a particle init that relies on client dll
- char* ptr = (char*)engineAddress + 0x1C7CBE;
+ char* ptr = (char*)engineAddress + 0x156799;
TempReadWrite rw(ptr);
- // je => jmp
- *ptr = (char)0xEB;
+ *ptr = (char)0x90;
+ *(ptr + 1) = (char)0x90;
+ *(ptr + 2) = (char)0x90;
+ *(ptr + 3) = (char)0x90;
+ *(ptr + 4) = (char)0x90;
}
{
@@ -100,6 +150,67 @@ void InitialiseDedicated(HMODULE engineAddress)
*(ptr + 16) = (char)0x90;
}
+ {
+ // HostState_State_NewGame
+ char* ptr = (char*)engineAddress + 0x156B4C;
+ TempReadWrite rw(ptr);
+
+ // nop some access violations
+ *ptr = (char)0x90;
+ *(ptr + 1) = (char)0x90;
+ *(ptr + 2) = (char)0x90;
+ *(ptr + 3) = (char)0x90;
+ *(ptr + 4) = (char)0x90;
+ *(ptr + 5) = (char)0x90;
+ *(ptr + 6) = (char)0x90;
+ *(ptr + 7) = (char)0x90;
+ *(ptr + 8) = (char)0x90;
+ *(ptr + 9) = (char)0x90;
+ *(ptr + 10) = (char)0x90;
+ *(ptr + 11) = (char)0x90;
+ *(ptr + 12) = (char)0x90;
+ *(ptr + 13) = (char)0x90;
+ *(ptr + 14) = (char)0x90;
+ *(ptr + 15) = (char)0x90;
+ *(ptr + 16) = (char)0x90;
+ *(ptr + 17) = (char)0x90;
+ *(ptr + 18) = (char)0x90;
+ *(ptr + 19) = (char)0x90;
+ *(ptr + 20) = (char)0x90;
+ *(ptr + 21) = (char)0x90;
+ }
+
+ {
+ // HostState_State_NewGame
+ char* ptr = (char*)engineAddress + 0xB934C;
+ TempReadWrite rw(ptr);
+
+ // nop an access violation
+ *ptr = (char)0x90;
+ *(ptr + 1) = (char)0x90;
+ *(ptr + 2) = (char)0x90;
+ *(ptr + 3) = (char)0x90;
+ *(ptr + 4) = (char)0x90;
+ *(ptr + 5) = (char)0x90;
+ *(ptr + 6) = (char)0x90;
+ *(ptr + 7) = (char)0x90;
+ *(ptr + 8) = (char)0x90;
+ }
+
+ {
+ // some inputsystem bullshit
+ char* ptr = (char*)engineAddress + 0x1CEE28;
+ TempReadWrite rw(ptr);
+
+ // nop an accessviolation: temp because we still create game window atm
+ *ptr = (char)0x90;
+ *(ptr + 1) = (char)0x90;
+ *(ptr + 2) = (char)0x90;
+ }
+
+
+ // materialsystem later:
+ // do materialsystem + 5f0f1 je => jmp to make material loading not die
CDedicatedExports* dedicatedApi = new CDedicatedExports;
dedicatedApi->Sys_Printf = Sys_Printf;
@@ -122,36 +233,59 @@ void InitialiseDedicated(HMODULE engineAddress)
// also look into materialsystem + 5B344 since it seems to be the base of all the renderthread stuff
}
+void InitialiseDedicatedMaterialSystem(HMODULE baseAddress)
+{
+ {
+ // CMaterialSystem::FindMaterial
+ char* ptr = (char*)baseAddress + 0x5F0F1;
+ TempReadWrite rw(ptr);
+
+ // make the game use the error material
+ *ptr = 0xE9;
+ *(ptr + 1) = (char)0x34;
+ *(ptr + 2) = (char)0x03;
+ *(ptr + 3) = (char)0x00;
+ }
+}
+
void Sys_Printf(CDedicatedExports* dedicated, char* msg)
{
- std::cout << msg << std::endl;
+ spdlog::info("[DEDICATED PRINT] {}", msg);
}
+typedef void(*CHostState__InitType)(CHostState* self);
+
void RunServer(CDedicatedExports* dedicated)
{
+ while (!IsDebuggerPresent())Sleep(100);
+
Sys_Printf(dedicated, (char*)"CDedicatedServerAPI::RunServer(): starting");
HMODULE engine = GetModuleHandleA("engine.dll");
CEngine__Frame engineFrame = (CEngine__Frame)((char*)engine + 0x1C8650);
- CEngineAPI__ActivateSimulation engineApiStartSimulation = (CEngineAPI__ActivateSimulation)((char*)engine + 0x1C4370);
-
CEngine* cEnginePtr = (CEngine*)((char*)engine + 0x7D70C8);
-
- CEngineAPI__SetMap engineApiSetMap = (CEngineAPI__SetMap)((char*)engine + 0x1C7B30);
+ CHostState* cHostStatePtr = (CHostState*)((char*)engine + 0x7CF180);
+ CHostState__InitType CHostState__Init = (CHostState__InitType)((char*)engine + 0x16E110);
+
// call once to init
engineFrame(cEnginePtr);
- // allow us to hit CHostState::FrameUpdate
- cEnginePtr->m_nDllState = EngineState_t::DLL_ACTIVE;
+ // init hoststate, if we don't do this, we get a crash later on
+ CHostState__Init(cHostStatePtr);
+
+ // set up engine and host states to allow us to enter CHostState::FrameUpdate, with the state HS_NEW_GAME
cEnginePtr->m_nNextDllState = EngineState_t::DLL_ACTIVE;
+ cHostStatePtr->m_currentState = HostState_t::HS_NEW_GAME;
+ cHostStatePtr->m_nextState = HostState_t::HS_RUN;
+ strcpy(cHostStatePtr->m_levelName, "mp_lobby"); // set map to load into
while (true)
{
engineFrame(cEnginePtr);
+
//engineApiStartSimulation(nullptr, true);
Sys_Printf(dedicated, (char*)"engine->Frame()");
- engineApiSetMap(nullptr, "mp_thaw");
Sleep(50);
}
} \ No newline at end of file
diff --git a/NorthstarDedicatedTest/dedicated.h b/NorthstarDedicatedTest/dedicated.h
index 61d430ac..18213123 100644
--- a/NorthstarDedicatedTest/dedicated.h
+++ b/NorthstarDedicatedTest/dedicated.h
@@ -27,4 +27,4 @@ struct CDedicatedExports
// hooking stuff
extern bool bDedicatedHooksInitialised;
void InitialiseDedicated(HMODULE moduleAddress);
-
+void InitialiseDedicatedMaterialSystem(HMODULE baseAddress);
diff --git a/NorthstarDedicatedTest/dllmain.cpp b/NorthstarDedicatedTest/dllmain.cpp
index 12268d85..e5ea9517 100644
--- a/NorthstarDedicatedTest/dllmain.cpp
+++ b/NorthstarDedicatedTest/dllmain.cpp
@@ -52,7 +52,10 @@ void InitialiseNorthstar()
AddDllLoadCallback("engine.dll", InitialiseEngineGameUtilFunctions);
if (IsDedicated())
+ {
AddDllLoadCallback("engine.dll", InitialiseDedicated);
+ AddDllLoadCallback("materialsystem_dx11.dll", InitialiseDedicatedMaterialSystem);
+ }
AddDllLoadCallback("engine.dll", InitialiseConVars);
AddDllLoadCallback("engine.dll", InitialiseConCommands);
diff --git a/NorthstarDedicatedTest/modmanager.cpp b/NorthstarDedicatedTest/modmanager.cpp
index dedbbbc8..63115ea4 100644
--- a/NorthstarDedicatedTest/modmanager.cpp
+++ b/NorthstarDedicatedTest/modmanager.cpp
@@ -188,6 +188,9 @@ void ModManager::LoadMods()
std::vector<fs::path> modDirs;
+ // ensure dirs exist
+ fs::create_directories(MOD_FOLDER_PATH);
+
// get mod directories
for (fs::directory_entry dir : fs::directory_iterator(MOD_FOLDER_PATH))
if (fs::exists(dir.path() / "mod.json"))
diff --git a/NorthstarDedicatedTest/squirrel.cpp b/NorthstarDedicatedTest/squirrel.cpp
index 50e24075..4aa8b3da 100644
--- a/NorthstarDedicatedTest/squirrel.cpp
+++ b/NorthstarDedicatedTest/squirrel.cpp
@@ -356,7 +356,7 @@ template<Context context> char CallScriptInitCallbackHook(void* sqvm, const char
if (modCallback->Context == SERVER && modCallback->AfterCallback.length())
{
spdlog::info("Running custom {} script callback \"{}\"", GetContextName(context), modCallback->AfterCallback);
- ClientCallScriptInitCallback(sqvm, modCallback->AfterCallback.c_str());
+ ServerCallScriptInitCallback(sqvm, modCallback->AfterCallback.c_str());
}
}
}
diff --git a/NorthstarDedicatedTest/tier0.cpp b/NorthstarDedicatedTest/tier0.cpp
index ad533a9c..4b5234d0 100644
--- a/NorthstarDedicatedTest/tier0.cpp
+++ b/NorthstarDedicatedTest/tier0.cpp
@@ -81,9 +81,7 @@ double Plat_FloatTime()
Tier0FloatTime tier0Func = (Tier0FloatTime)ResolveTier0Function("Plat_FloatTime");
if (tier0Func)
- {
return tier0Func();
- }
else
return 0.0f;
} \ No newline at end of file