diff options
-rw-r--r-- | GameInjector/dllmain.cpp | 18 | ||||
-rw-r--r-- | LauncherInjector/main.cpp | 2 | ||||
-rw-r--r-- | NorthstarDedicatedTest/chatcommand.cpp | 9 | ||||
-rw-r--r-- | NorthstarDedicatedTest/concommand.cpp | 1 | ||||
-rw-r--r-- | NorthstarDedicatedTest/dedicated.cpp | 170 | ||||
-rw-r--r-- | NorthstarDedicatedTest/dedicated.h | 2 | ||||
-rw-r--r-- | NorthstarDedicatedTest/dllmain.cpp | 3 | ||||
-rw-r--r-- | NorthstarDedicatedTest/modmanager.cpp | 3 | ||||
-rw-r--r-- | NorthstarDedicatedTest/squirrel.cpp | 2 | ||||
-rw-r--r-- | NorthstarDedicatedTest/tier0.cpp | 2 |
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 |