1
mirror of https://github.com/R2Northstar/NorthstarLauncher synced 2024-09-29 09:19:41 +02:00
This commit is contained in:
HappyDOGE 2021-12-27 14:55:59 +03:00
commit 00eab35478
9 changed files with 296 additions and 15 deletions

View File

@ -136,7 +136,7 @@
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableUAC>false</EnableUAC>
<AdditionalDependencies>$(ProjectDir)include\MinHook.x64.lib;$(ProjectDir)include\libcrypto_static.lib;$(ProjectDir)include\libssl_static.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalDependencies>$(ProjectDir)include\MinHook.x64.lib;$(ProjectDir)include\libcrypto_static.lib;$(ProjectDir)include\libssl_static.lib;dbghelp.lib;%(AdditionalDependencies)</AdditionalDependencies>
<ForceSymbolReferences>
</ForceSymbolReferences>
</Link>
@ -164,7 +164,7 @@
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableUAC>false</EnableUAC>
<AdditionalDependencies>$(ProjectDir)include\MinHook.x64.lib;$(ProjectDir)include\libcrypto_static.lib;$(ProjectDir)include\libssl_static.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalDependencies>$(ProjectDir)include\MinHook.x64.lib;$(ProjectDir)include\libcrypto_static.lib;$(ProjectDir)include\libssl_static.lib;dbghelp.lib;%(AdditionalDependencies)</AdditionalDependencies>
<ForceSymbolReferences>
</ForceSymbolReferences>
</Link>
@ -580,6 +580,7 @@
<ClInclude Include="memalloc.h" />
<ClInclude Include="miscclientfixes.h" />
<ClInclude Include="misccommands.h" />
<ClInclude Include="miscserverfixes.h" />
<ClInclude Include="modlocalisation.h" />
<ClInclude Include="modmanager.h" />
<ClInclude Include="pch.h" />
@ -616,6 +617,7 @@
<ClCompile Include="memalloc.cpp" />
<ClCompile Include="miscclientfixes.cpp" />
<ClCompile Include="misccommands.cpp" />
<ClCompile Include="miscserverfixes.cpp" />
<ClCompile Include="modlocalisation.cpp" />
<ClCompile Include="logging.cpp" />
<ClCompile Include="masterserver.cpp" />

View File

@ -1386,8 +1386,8 @@
<ClInclude Include="include\internal\unicode.h">
<Filter>Header Files\include\openssl\internal</Filter>
</ClInclude>
<ClInclude Include="maxplayers.h">
<Filter>Header Files\Shared</Filter>
<ClInclude Include="miscserverfixes.h">
<Filter>Header Files\Server</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
@ -1496,9 +1496,6 @@
<ClCompile Include="miscclientfixes.cpp">
<Filter>Source Files\Client</Filter>
</ClCompile>
<ClCompile Include="maxplayers.cpp">
<Filter>Source Files\Shared</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<None Include="include\spdlog\fmt\bundled\LICENSE.rst">

View File

@ -24,6 +24,7 @@
#include "scriptbrowserhooks.h"
#include "scriptmainmenupromos.h"
#include "miscclientfixes.h"
#include "miscserverfixes.h"
#include "memalloc.h"
#include "maxplayers.h"
@ -111,6 +112,7 @@ void InitialiseNorthstar()
AddDllLoadCallback("engine.dll", InitialiseServerAuthentication);
AddDllLoadCallback("engine.dll", InitialiseSharedMasterServer);
AddDllLoadCallback("server.dll", InitialiseMiscServerScriptCommand);
AddDllLoadCallback("server.dll", InitialiseMiscServerFixes);
AddDllLoadCallback("engine.dll", InitialisePlaylistHooks);

View File

@ -4,11 +4,171 @@
#include "spdlog/sinks/basic_file_sink.h"
#include "hookutils.h"
#include "gameutils.h"
#include "dedicated.h"
#include <iomanip>
#include <sstream>
#include <Psapi.h>
#include <minidumpapiset.h>
long __stdcall ExceptionFilter(EXCEPTION_POINTERS* exceptionInfo)
{
static bool logged = false;
if (logged)
return EXCEPTION_CONTINUE_SEARCH;
if (!IsDebuggerPresent())
{
const DWORD exceptionCode = exceptionInfo->ExceptionRecord->ExceptionCode;
if (exceptionCode != EXCEPTION_ACCESS_VIOLATION && exceptionCode != EXCEPTION_ARRAY_BOUNDS_EXCEEDED &&
exceptionCode != EXCEPTION_DATATYPE_MISALIGNMENT && exceptionCode != EXCEPTION_FLT_DENORMAL_OPERAND &&
exceptionCode != EXCEPTION_FLT_DIVIDE_BY_ZERO && exceptionCode != EXCEPTION_FLT_INEXACT_RESULT &&
exceptionCode != EXCEPTION_FLT_INVALID_OPERATION && exceptionCode != EXCEPTION_FLT_OVERFLOW &&
exceptionCode != EXCEPTION_FLT_STACK_CHECK && exceptionCode != EXCEPTION_FLT_UNDERFLOW &&
exceptionCode != EXCEPTION_ILLEGAL_INSTRUCTION && exceptionCode != EXCEPTION_IN_PAGE_ERROR &&
exceptionCode != EXCEPTION_INT_DIVIDE_BY_ZERO && exceptionCode != EXCEPTION_INT_OVERFLOW &&
exceptionCode != EXCEPTION_INVALID_DISPOSITION && exceptionCode != EXCEPTION_NONCONTINUABLE_EXCEPTION &&
exceptionCode != EXCEPTION_PRIV_INSTRUCTION && exceptionCode != EXCEPTION_STACK_OVERFLOW)
return EXCEPTION_CONTINUE_SEARCH;
std::stringstream exceptionCause;
switch (exceptionCode)
{
case EXCEPTION_ACCESS_VIOLATION:
case EXCEPTION_IN_PAGE_ERROR:
{
exceptionCause << "Cause: Access Violation" << std::endl;
auto exceptionInfo0 = exceptionInfo->ExceptionRecord->ExceptionInformation[0];
auto exceptionInfo1 = exceptionInfo->ExceptionRecord->ExceptionInformation[1];
if (!exceptionInfo0)
exceptionCause << "Attempted to read from: 0x" << std::setw(8) << std::setfill('0') << std::hex << exceptionInfo1;
else if (exceptionInfo0 == 1)
exceptionCause << "Attempted to write to: 0x" << std::setw(8) << std::setfill('0') << std::hex << exceptionInfo1;
else if (exceptionInfo0 == 8)
exceptionCause << "Data Execution Prevention (DEP) at: 0x" << std::setw(8) << std::setfill('0') << std::hex << exceptionInfo1;
else
exceptionCause << "Unknown access violation at: 0x" << std::setw(8) << std::setfill('0') << std::hex << exceptionInfo1;
break;
}
case EXCEPTION_ARRAY_BOUNDS_EXCEEDED:
exceptionCause << "Cause: Array bounds exceeded";
break;
case EXCEPTION_DATATYPE_MISALIGNMENT:
exceptionCause << "Cause: Datatype misalignment";
break;
case EXCEPTION_FLT_DENORMAL_OPERAND:
exceptionCause << "Cause: Denormal operand";
break;
case EXCEPTION_FLT_DIVIDE_BY_ZERO:
case EXCEPTION_INT_DIVIDE_BY_ZERO:
exceptionCause << "Cause: Divide by zero";
break;
case EXCEPTION_FLT_INEXACT_RESULT:
exceptionCause << "Cause: Inexact result";
break;
case EXCEPTION_FLT_INVALID_OPERATION:
exceptionCause << "Cause: invalid operation";
break;
case EXCEPTION_FLT_OVERFLOW:
case EXCEPTION_INT_OVERFLOW:
exceptionCause << "Cause: Numeric overflow";
break;
case EXCEPTION_FLT_UNDERFLOW:
exceptionCause << "Cause: Numeric underflow";
break;
case EXCEPTION_FLT_STACK_CHECK:
exceptionCause << "Cause: Stack check";
break;
case EXCEPTION_ILLEGAL_INSTRUCTION:
exceptionCause << "Cause: Illegal instruction";
break;
case EXCEPTION_INVALID_DISPOSITION:
exceptionCause << "Cause: Invalid disposition";
break;
case EXCEPTION_NONCONTINUABLE_EXCEPTION:
exceptionCause << "Cause: Noncontinuable exception";
break;
case EXCEPTION_PRIV_INSTRUCTION:
exceptionCause << "Cause: Priv instruction";
break;
case EXCEPTION_STACK_OVERFLOW:
exceptionCause << "Cause: Stack overflow";
break;
default:
exceptionCause << "Cause: Unknown";
break;
}
void* exceptionAddress = exceptionInfo->ExceptionRecord->ExceptionAddress;
HMODULE crashedModuleHandle;
GetModuleHandleExA(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, static_cast<LPCSTR>(exceptionAddress), &crashedModuleHandle);
MODULEINFO crashedModuleInfo;
GetModuleInformation(GetCurrentProcess(), crashedModuleHandle, &crashedModuleInfo, sizeof(crashedModuleInfo));
char crashedModuleFullName[MAX_PATH];
GetModuleFileNameExA(GetCurrentProcess(), crashedModuleHandle, crashedModuleFullName, MAX_PATH);
char* crashedModuleName = strrchr(crashedModuleFullName, '\\') + 1;
DWORD crashedModuleOffset = ((DWORD)exceptionAddress) - ((DWORD)crashedModuleInfo.lpBaseOfDll);
CONTEXT* exceptionContext = exceptionInfo->ContextRecord;
spdlog::error("Northstar has crashed! a minidump has been written and exception info is available below:");
spdlog::error(exceptionCause.str());
spdlog::error("Address: {} + 0x{0:x}", crashedModuleName, crashedModuleOffset);
spdlog::error("RAX: 0x{0:x}", exceptionContext->Rax);
spdlog::error("RBX: 0x{0:x}", exceptionContext->Rbx);
spdlog::error("RCX: 0x{0:x}", exceptionContext->Rcx);
spdlog::error("RDX: 0x{0:x}", exceptionContext->Rdx);
spdlog::error("RSI: 0x{0:x}", exceptionContext->Rsi);
spdlog::error("RDI: 0x{0:x}", exceptionContext->Rdi);
spdlog::error("RBP: 0x{0:x}", exceptionContext->Rbp);
spdlog::error("RSP: 0x{0:x}", exceptionContext->Rsp);
spdlog::error("R8: 0x{0:x}", exceptionContext->R8);
spdlog::error("R9: 0x{0:x}", exceptionContext->R9);
spdlog::error("R10: 0x{0:x}", exceptionContext->R10);
spdlog::error("R11: 0x{0:x}", exceptionContext->R11);
spdlog::error("R12: 0x{0:x}", exceptionContext->R12);
spdlog::error("R13: 0x{0:x}", exceptionContext->R13);
spdlog::error("R14: 0x{0:x}", exceptionContext->R14);
spdlog::error("R15: 0x{0:x}", exceptionContext->R15);
time_t time = std::time(nullptr);
tm currentTime = *std::localtime(&time);
std::stringstream stream;
stream << std::put_time(&currentTime, "R2Northstar/logs/nsdump%d-%m-%Y %H-%M-%S.dmp");
auto hMinidumpFile = CreateFileA(stream.str().c_str(), GENERIC_WRITE, FILE_SHARE_READ, 0, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
if (hMinidumpFile)
{
MINIDUMP_EXCEPTION_INFORMATION dumpExceptionInfo;
dumpExceptionInfo.ThreadId = GetCurrentThreadId();
dumpExceptionInfo.ExceptionPointers = exceptionInfo;
dumpExceptionInfo.ClientPointers = false;
MiniDumpWriteDump(GetCurrentProcess(), GetCurrentProcessId(), hMinidumpFile, MINIDUMP_TYPE(MiniDumpWithIndirectlyReferencedMemory | MiniDumpScanMemory), &dumpExceptionInfo, nullptr, nullptr);
CloseHandle(hMinidumpFile);
}
else
spdlog::error("Failed to write minidump file {}!", stream.str());
if (!IsDedicated())
MessageBoxA(0, "Northstar has crashed! A crash log and dump can be found in R2Northstar/logs", "Northstar has crashed!", MB_ICONERROR | MB_OK);
}
logged = true;
return EXCEPTION_EXECUTE_HANDLER;
}
void InitialiseLogging()
{
AddVectoredExceptionHandler(TRUE, ExceptionFilter);
AllocConsole();
freopen("CONOUT$", "w", stdout);

View File

@ -35,6 +35,39 @@ CHostState__State_ChangeLevelSPType CHostState__State_ChangeLevelSP;
typedef void(*CHostState__State_GameShutdownType)(CHostState* hostState);
CHostState__State_GameShutdownType CHostState__State_GameShutdown;
const char* HttplibErrorToString(httplib::Error error)
{
switch (error)
{
case httplib::Error::Success:
return "httplib::Error::Success";
case httplib::Error::Unknown:
return "httplib::Error::Unknown";
case httplib::Error::Connection:
return "httplib::Error::Connection";
case httplib::Error::BindIPAddress:
return "httplib::Error::BindIPAddress";
case httplib::Error::Read:
return "httplib::Error::Read";
case httplib::Error::Write:
return "httplib::Error::Write";
case httplib::Error::ExceedRedirectCount:
return "httplib::Error::ExceedRedirectCount";
case httplib::Error::Canceled:
return "httplib::Error::Canceled";
case httplib::Error::SSLConnection:
return "httplib::Error::SSLConnection";
case httplib::Error::SSLLoadingCerts:
return "httplib::Error::SSLLoadingCerts";
case httplib::Error::SSLServerVerification:
return "httplib::Error::SSLServerVerification";
case httplib::Error::UnsupportedMultipartBoundaryChars:
return "httplib::Error::UnsupportedMultipartBoundaryChars";
}
return "";
}
RemoteServerInfo::RemoteServerInfo(const char* newId, const char* newName, const char* newDescription, const char* newMap, const char* newPlaylist, int newPlayerCount, int newMaxPlayers, bool newRequiresPassword)
{
// passworded servers don't have public ips
@ -80,6 +113,8 @@ void MasterServerManager::AuthenticateOriginWithMasterServer(char* uid, char* or
{
httplib::Client http(Cvar_ns_masterserver_hostname->m_pszString);
http.set_connection_timeout(25);
http.set_read_timeout(25);
http.set_write_timeout(25);
spdlog::info("Trying to authenticate with northstar masterserver for user {}", uidStr);
@ -113,7 +148,7 @@ void MasterServerManager::AuthenticateOriginWithMasterServer(char* uid, char* or
}
else
{
spdlog::error("Failed performing northstar origin auth: error {}", result.error());
spdlog::error("Failed performing northstar origin auth: error {}", HttplibErrorToString(result.error()));
m_successfullyConnected = false;
}
@ -143,6 +178,8 @@ void MasterServerManager::RequestServerList()
httplib::Client http(Cvar_ns_masterserver_hostname->m_pszString);
http.set_connection_timeout(25);
http.set_read_timeout(25);
http.set_write_timeout(25);
spdlog::info("Requesting server list from {}", Cvar_ns_masterserver_hostname->m_pszString);
@ -248,7 +285,7 @@ void MasterServerManager::RequestServerList()
}
else
{
spdlog::error("Failed requesting servers: error {}", result.error());
spdlog::error("Failed requesting servers: error {}", HttplibErrorToString(result.error()));
m_successfullyConnected = false;
}
@ -272,6 +309,8 @@ void MasterServerManager::RequestMainMenuPromos()
httplib::Client http(Cvar_ns_masterserver_hostname->m_pszString);
http.set_connection_timeout(25);
http.set_read_timeout(25);
http.set_write_timeout(25);
if (auto result = http.Get("/client/mainmenupromos"))
{
@ -345,7 +384,7 @@ void MasterServerManager::RequestMainMenuPromos()
}
else
{
spdlog::error("Failed requesting main menu promos: error {}", result.error());
spdlog::error("Failed requesting main menu promos: error {}", HttplibErrorToString(result.error()));
m_successfullyConnected = false;
}
@ -371,6 +410,8 @@ void MasterServerManager::AuthenticateWithOwnServer(char* uid, char* playerToken
{
httplib::Client http(Cvar_ns_masterserver_hostname->m_pszString);
http.set_connection_timeout(25);
http.set_read_timeout(25);
http.set_write_timeout(25);
if (auto result = http.Post(fmt::format("/client/auth_with_self?id={}&playerToken={}", uid, playerToken).c_str()))
{
@ -440,7 +481,7 @@ void MasterServerManager::AuthenticateWithOwnServer(char* uid, char* playerToken
}
else
{
spdlog::error("Failed authenticating with own server: error {}", result.error());
spdlog::error("Failed authenticating with own server: error {}", HttplibErrorToString(result.error()));
m_successfullyConnected = false;
m_successfullyAuthenticatedWithGameServer = false;
m_scriptAuthenticatingWithGameServer = false;
@ -479,6 +520,8 @@ void MasterServerManager::AuthenticateWithServer(char* uid, char* playerToken, c
httplib::Client http(Cvar_ns_masterserver_hostname->m_pszString);
http.set_connection_timeout(25);
http.set_read_timeout(25);
http.set_write_timeout(25);
spdlog::info("Attempting authentication with server of id \"{}\"", serverId);
@ -531,7 +574,7 @@ void MasterServerManager::AuthenticateWithServer(char* uid, char* playerToken, c
}
else
{
spdlog::error("Failed authenticating with server: error {}", result.error());
spdlog::error("Failed authenticating with server: error {}", HttplibErrorToString(result.error()));
m_successfullyConnected = false;
m_successfullyAuthenticatedWithGameServer = false;
m_scriptAuthenticatingWithGameServer = false;
@ -561,6 +604,8 @@ void MasterServerManager::AddSelfToServerList(int port, int authPort, char* name
std::thread requestThread([this, port, authPort, name, description, map, playlist, maxPlayers, password] {
httplib::Client http(Cvar_ns_masterserver_hostname->m_pszString);
http.set_connection_timeout(25);
http.set_read_timeout(25);
http.set_write_timeout(25);
m_ownServerId[0] = 0;
@ -647,6 +692,8 @@ void MasterServerManager::AddSelfToServerList(int port, int authPort, char* name
std::thread heartbeatThread([this] {
httplib::Client http(Cvar_ns_masterserver_hostname->m_pszString);
http.set_connection_timeout(25);
http.set_read_timeout(25);
http.set_write_timeout(25);
while (*m_ownServerId)
{
@ -659,7 +706,7 @@ void MasterServerManager::AddSelfToServerList(int port, int authPort, char* name
}
else
{
spdlog::error("Failed authenticating with server: error {}", result.error());
spdlog::error("Failed adding self to server list: error {}", HttplibErrorToString(result.error()));
m_successfullyConnected = false;
}
});
@ -676,6 +723,8 @@ void MasterServerManager::UpdateServerMapAndPlaylist(char* map, char* playlist,
std::thread requestThread([this, map, playlist, maxPlayers] {
httplib::Client http(Cvar_ns_masterserver_hostname->m_pszString);
http.set_connection_timeout(25);
http.set_read_timeout(25);
http.set_write_timeout(25);
// we dont process this at all atm, maybe do later, but atm not necessary
if (auto result = http.Post(fmt::format("/server/update_values?id={}&map={}&playlist={}&maxPlayers={}", m_ownServerId, map, playlist, maxPlayers).c_str()))
@ -700,6 +749,8 @@ void MasterServerManager::UpdateServerPlayerCount(int playerCount)
std::thread requestThread([this, playerCount] {
httplib::Client http(Cvar_ns_masterserver_hostname->m_pszString);
http.set_connection_timeout(25);
http.set_read_timeout(25);
http.set_write_timeout(25);
// we dont process this at all atm, maybe do later, but atm not necessary
if (auto result = http.Post(fmt::format("/server/update_values?id={}&playerCount={}", m_ownServerId, playerCount).c_str()))
@ -728,7 +779,9 @@ void MasterServerManager::WritePlayerPersistentData(char* playerId, char* pdata,
std::string playerIdTemp(playerId);
std::thread requestThread([this, playerIdTemp, pdata, pdataSize] {
httplib::Client http(Cvar_ns_masterserver_hostname->m_pszString);
http.set_connection_timeout(25);
http.set_connection_timeout(25);
http.set_read_timeout(25);
http.set_write_timeout(25);
httplib::MultipartFormDataItems requestItems = {
{ "pdata", std::string(pdata, pdataSize), "file.pdata", "application/octet-stream"}
@ -759,6 +812,8 @@ void MasterServerManager::RemoveSelfFromServerList()
std::thread requestThread([this] {
httplib::Client http(Cvar_ns_masterserver_hostname->m_pszString);
http.set_connection_timeout(25);
http.set_read_timeout(25);
http.set_write_timeout(25);
// we dont process this at all atm, maybe do later, but atm not necessary
if (auto result = http.Delete(fmt::format("/server/remove_server?id={}", m_ownServerId).c_str()))

View File

@ -0,0 +1,13 @@
#include "pch.h"
#include "miscserverfixes.h"
#include "hookutils.h"
void InitialiseMiscServerFixes(HMODULE baseAddress)
{
// ret at the start of the concommand GenerateObjFile as it can crash servers
{
void* ptr = (char*)baseAddress + 0x38D920;
TempReadWrite rw(ptr);
*((char*)ptr) = (char)0xC3;
}
}

View File

@ -0,0 +1 @@
void InitialiseMiscServerFixes(HMODULE baseAddress);

View File

@ -5,11 +5,17 @@
#include "gameutils.h"
#include "hookutils.h"
#include "dedicated.h"
#include "squirrel.h"
typedef char(*Onclc_SetPlaylistVarOverrideType)(void* a1, void* a2);
Onclc_SetPlaylistVarOverrideType Onclc_SetPlaylistVarOverride;
typedef int(*GetCurrentGamemodeMaxPlayersType)();
GetCurrentGamemodeMaxPlayersType GetCurrentGamemodeMaxPlayers;
// function type defined in gameutils.h
SetPlaylistVarOverrideType SetPlaylistVarOverrideOriginal;
GetCurrentPlaylistVarType GetCurrentPlaylistVarOriginal;
ConVar* Cvar_ns_use_clc_SetPlaylistVarOverride;
@ -21,6 +27,15 @@ void SetPlaylistCommand(const CCommand& args)
SetCurrentPlaylist(args.Arg(1));
}
void SetPlaylistVarOverrideCommand(const CCommand& args)
{
if (args.ArgC() < 3)
return;
for (int i = 1; i < args.ArgC(); i += 2)
SetPlaylistVarOverride(args.Arg(i), args.Arg(i + 1));
}
char Onclc_SetPlaylistVarOverrideHook(void* a1, void* a2)
{
// the private_match playlist is the only situation where there should be any legitimate sending of this netmessage
@ -39,9 +54,30 @@ void SetPlaylistVarOverrideHook(const char* varName, const char* value)
SetPlaylistVarOverrideOriginal(varName, value);
}
char* GetCurrentPlaylistVarHook(const char* varName, bool useOverrides)
{
if (!useOverrides && !strcmp(varName, "max_players"))
useOverrides = true;
return GetCurrentPlaylistVarOriginal(varName, useOverrides);
}
int GetCurrentGamemodeMaxPlayersHook()
{
char* maxPlayersStr = GetCurrentPlaylistVar("max_players", 0);
if (!maxPlayersStr)
return GetCurrentGamemodeMaxPlayers();
int maxPlayers = atoi(maxPlayersStr);
spdlog::info("Overwrote max_players to {}", maxPlayers);
return maxPlayers;
}
void InitialisePlaylistHooks(HMODULE baseAddress)
{
RegisterConCommand("setplaylist", SetPlaylistCommand, "Sets the current playlist", FCVAR_NONE);
RegisterConCommand("setplaylistvaroverrides", SetPlaylistVarOverrideCommand, "sets a playlist var override", FCVAR_NONE);
// note: clc_SetPlaylistVarOverride is pretty insecure, since it allows for entirely arbitrary playlist var overrides to be sent to the server
// this is somewhat restricted on custom servers to prevent it being done outside of private matches, but ideally it should be disabled altogether, since the custom menus won't use it anyway
// this should only really be accepted if you want vanilla client compatibility
@ -50,6 +86,8 @@ void InitialisePlaylistHooks(HMODULE baseAddress)
HookEnabler hook;
ENABLER_CREATEHOOK(hook, (char*)baseAddress + 0x222180, &Onclc_SetPlaylistVarOverrideHook, reinterpret_cast<LPVOID*>(&Onclc_SetPlaylistVarOverride));
ENABLER_CREATEHOOK(hook, (char*)baseAddress + 0x18ED00, &SetPlaylistVarOverrideHook, reinterpret_cast<LPVOID*>(&SetPlaylistVarOverrideOriginal));
ENABLER_CREATEHOOK(hook, (char*)baseAddress + 0x18C680, &GetCurrentPlaylistVarHook, reinterpret_cast<LPVOID*>(&GetCurrentPlaylistVarOriginal));
ENABLER_CREATEHOOK(hook, (char*)baseAddress + 0x18C430, &GetCurrentGamemodeMaxPlayersHook, reinterpret_cast<LPVOID*>(&GetCurrentGamemodeMaxPlayers));
// patch to prevent clc_SetPlaylistVarOverride from being able to crash servers if we reach max overrides due to a call to Error (why is this possible respawn, wtf)
// todo: add a warning for this
@ -58,4 +96,17 @@ void InitialisePlaylistHooks(HMODULE baseAddress)
TempReadWrite rw(ptr);
*((char*)ptr) = 0xC3; // jmp => ret
}
if (IsDedicated())
{
// patch to allow setplaylistvaroverride to be called before map init on dedicated
void* ptr = (char*)baseAddress + 0x18ED17;
TempReadWrite rw(ptr);
*((char*)ptr) = (char)0x90;
*((char*)ptr + 1) = (char)0x90;
*((char*)ptr + 2) = (char)0x90;
*((char*)ptr + 3) = (char)0x90;
*((char*)ptr + 4) = (char)0x90;
*((char*)ptr + 5) = (char)0x90;
}
}

View File

@ -437,7 +437,7 @@ void InitialiseServerAuthentication(HMODULE baseAddress)
Cvar_net_chan_limit_mode = RegisterConVar("net_chan_limit_mode", "0", FCVAR_GAMEDLL, "The mode for netchan processing limits: 0 = none, 1 = kick, 2 = log");
Cvar_net_chan_limit_msec_per_sec = RegisterConVar("net_chan_limit_msec_per_sec", "0", FCVAR_GAMEDLL, "Netchannel processing is limited to so many milliseconds, abort connection if exceeding budget");
Cvar_ns_player_auth_port = RegisterConVar("ns_player_auth_port", "8081", FCVAR_GAMEDLL, "");
Cvar_sv_querylimit_per_sec = RegisterConVar("sv_querylimit_per_sec", "10", FCVAR_GAMEDLL, "");
Cvar_sv_querylimit_per_sec = RegisterConVar("sv_querylimit_per_sec", "15", FCVAR_GAMEDLL, "");
HookEnabler hook;
ENABLER_CREATEHOOK(hook, (char*)baseAddress + 0x114430, &CBaseServer__ConnectClientHook, reinterpret_cast<LPVOID*>(&CBaseServer__ConnectClient));