aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGeckoEidechse <40122905+GeckoEidechse@users.noreply.github.com>2024-11-12 17:11:31 +0100
committerGitHub <noreply@github.com>2024-11-12 17:11:31 +0100
commit6509283abd620038bf48f0d90ba23b8fa17feec7 (patch)
treea4186aef12d8c44e3bc71868f2e1556068e4a6dd
parenta4b09bc42d5f79ef86697c893efc9e3b7d966502 (diff)
parent13344f3910befa2cd15bfd306ba2c5e42e6c80ec (diff)
downloadNorthstarLauncher-6509283abd620038bf48f0d90ba23b8fa17feec7.tar.gz
NorthstarLauncher-6509283abd620038bf48f0d90ba23b8fa17feec7.zip
Merge branch 'main' into feat/overhaul-mod-loading-locationsfeat/overhaul-mod-loading-locations
-rw-r--r--CMakeLists.txt4
-rw-r--r--primedev/Northstar.cmake1
-rw-r--r--primedev/core/convar/convar.h1
-rw-r--r--primedev/core/filesystem/rpakfilesystem.cpp4
-rw-r--r--primedev/core/sourceinterface.cpp1
-rw-r--r--primedev/core/sourceinterface.h32
-rw-r--r--primedev/core/tier1.h6
-rw-r--r--primedev/logging/sourceconsole.h1
-rw-r--r--primedev/mods/compiled/modkeyvalues.cpp2
-rw-r--r--primedev/plugins/interfaces/IPluginId.h1
-rw-r--r--primedev/plugins/interfaces/interface.cpp1
-rw-r--r--primedev/plugins/interfaces/sys/ISys.cpp1
-rw-r--r--primedev/plugins/plugins.cpp11
-rw-r--r--primedev/plugins/plugins.h3
-rw-r--r--primedev/scripts/client/clientchathooks.cpp13
-rw-r--r--primedev/server/auth/serverauthentication.cpp67
-rw-r--r--primedev/server/buildainfile.cpp24
17 files changed, 85 insertions, 88 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index a9646ae1..c9516e52 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -50,3 +50,7 @@ include_directories(primedev/thirdparty)
# Targets
add_subdirectory(primedev)
+# Forces Minizip to not use functions that are not available in Win 7 libraries.
+if(WIN32)
+ target_compile_definitions(minizip PUBLIC -D_WIN32_WINNT=0x0601)
+endif()
diff --git a/primedev/Northstar.cmake b/primedev/Northstar.cmake
index 4e8ec973..35383e69 100644
--- a/primedev/Northstar.cmake
+++ b/primedev/Northstar.cmake
@@ -52,7 +52,6 @@ add_library(
"core/memalloc.cpp"
"core/memalloc.h"
"core/sourceinterface.cpp"
- "core/sourceinterface.h"
"core/tier0.cpp"
"core/tier0.h"
"core/tier1.cpp"
diff --git a/primedev/core/convar/convar.h b/primedev/core/convar/convar.h
index f0366b46..33a50c1c 100644
--- a/primedev/core/convar/convar.h
+++ b/primedev/core/convar/convar.h
@@ -1,5 +1,4 @@
#pragma once
-#include "core/sourceinterface.h"
#include "core/math/color.h"
#include "cvar.h"
#include "concommand.h"
diff --git a/primedev/core/filesystem/rpakfilesystem.cpp b/primedev/core/filesystem/rpakfilesystem.cpp
index ebb9085a..c3e5e74e 100644
--- a/primedev/core/filesystem/rpakfilesystem.cpp
+++ b/primedev/core/filesystem/rpakfilesystem.cpp
@@ -342,7 +342,7 @@ void PakLoadManager::UnloadDependentPaks(PakHandle handle)
static void HandlePakAliases(std::string& originalPath)
{
// convert the pak being loaded to its aliased one, e.g. aliasing mp_hub_timeshift => sp_hub_timeshift
- for (int64_t i = g_pModManager->m_LoadedMods.size() - 1; i > PakHandle::INVALID; i--)
+ for (int64_t i = g_pModManager->m_LoadedMods.size() - 1; i > -1; i--)
{
Mod* mod = &g_pModManager->m_LoadedMods[i];
if (!mod->m_bEnabled)
@@ -350,7 +350,7 @@ static void HandlePakAliases(std::string& originalPath)
if (mod->RpakAliases.find(originalPath) != mod->RpakAliases.end())
{
- originalPath = (mod->m_ModDirectory / "paks" / mod->RpakAliases[originalPath]).string();
+ originalPath = mod->RpakAliases[originalPath];
return;
}
}
diff --git a/primedev/core/sourceinterface.cpp b/primedev/core/sourceinterface.cpp
index 74e4a996..7ce33925 100644
--- a/primedev/core/sourceinterface.cpp
+++ b/primedev/core/sourceinterface.cpp
@@ -1,4 +1,3 @@
-#include "sourceinterface.h"
#include "logging/sourceconsole.h"
// really wanted to do a modular callback system here but honestly couldn't be bothered so hardcoding stuff for now: todo later
diff --git a/primedev/core/sourceinterface.h b/primedev/core/sourceinterface.h
deleted file mode 100644
index 730339da..00000000
--- a/primedev/core/sourceinterface.h
+++ /dev/null
@@ -1,32 +0,0 @@
-#pragma once
-#include <string>
-
-// interface return status
-enum class InterfaceStatus : int
-{
- IFACE_OK = 0,
- IFACE_FAILED,
-};
-
-// literally just copied from ttf2sdk definition
-typedef void* (*CreateInterfaceFn)(const char* pName, int* pReturnCode);
-
-template <typename T> class SourceInterface
-{
-private:
- T* m_interface;
-
-public:
- SourceInterface(const std::string& moduleName, const std::string& interfaceName)
- {
- HMODULE handle = GetModuleHandleA(moduleName.c_str());
- CreateInterfaceFn createInterface = (CreateInterfaceFn)GetProcAddress(handle, "CreateInterface");
- m_interface = (T*)createInterface(interfaceName.c_str(), NULL);
- if (m_interface == nullptr)
- spdlog::error("Failed to call CreateInterface for %s in %s", interfaceName, moduleName);
- }
-
- T* operator->() const { return m_interface; }
-
- operator T*() const { return m_interface; }
-};
diff --git a/primedev/core/tier1.h b/primedev/core/tier1.h
index d162e7c8..36f577cc 100644
--- a/primedev/core/tier1.h
+++ b/primedev/core/tier1.h
@@ -7,6 +7,12 @@
#define CREATEINTERFACE_PROCNAME "CreateInterface"
+enum class InterfaceStatus : int
+{
+ IFACE_OK = 0,
+ IFACE_FAILED,
+};
+
typedef void* (*CreateInterfaceFn)(const char* pName, int* pReturnCode);
CMemory Sys_GetFactoryPtr(const std::string& svModuleName, const std::string& svFact);
diff --git a/primedev/logging/sourceconsole.h b/primedev/logging/sourceconsole.h
index 35cc1723..8c647fb4 100644
--- a/primedev/logging/sourceconsole.h
+++ b/primedev/logging/sourceconsole.h
@@ -1,5 +1,4 @@
#pragma once
-#include "core/sourceinterface.h"
#include "spdlog/sinks/base_sink.h"
#include <map>
diff --git a/primedev/mods/compiled/modkeyvalues.cpp b/primedev/mods/compiled/modkeyvalues.cpp
index e44a81d3..dfff706d 100644
--- a/primedev/mods/compiled/modkeyvalues.cpp
+++ b/primedev/mods/compiled/modkeyvalues.cpp
@@ -3,8 +3,6 @@
#include <fstream>
-AUTOHOOK_INIT()
-
void ModManager::TryBuildKeyValues(const char* filename)
{
spdlog::info("Building KeyValues for file {}", filename);
diff --git a/primedev/plugins/interfaces/IPluginId.h b/primedev/plugins/interfaces/IPluginId.h
index dc4c548b..0b025224 100644
--- a/primedev/plugins/interfaces/IPluginId.h
+++ b/primedev/plugins/interfaces/IPluginId.h
@@ -18,6 +18,7 @@ enum class PluginString : int
enum class PluginField : int
{
CONTEXT = 0,
+ COLOR = 1,
};
// an interface that is required from every plugin to query data about it
diff --git a/primedev/plugins/interfaces/interface.cpp b/primedev/plugins/interfaces/interface.cpp
index bc900542..e8200560 100644
--- a/primedev/plugins/interfaces/interface.cpp
+++ b/primedev/plugins/interfaces/interface.cpp
@@ -1,4 +1,5 @@
#include <string.h>
+#include "core/tier1.h"
#include "interface.h"
InterfaceReg* s_pInterfaceRegs;
diff --git a/primedev/plugins/interfaces/sys/ISys.cpp b/primedev/plugins/interfaces/sys/ISys.cpp
index 6b0b41dd..948e7d90 100644
--- a/primedev/plugins/interfaces/sys/ISys.cpp
+++ b/primedev/plugins/interfaces/sys/ISys.cpp
@@ -1,3 +1,4 @@
+#include "core/tier1.h"
#include "plugins/interfaces/interface.h"
#include "ISys.h"
#include "plugins/plugins.h"
diff --git a/primedev/plugins/plugins.cpp b/primedev/plugins/plugins.cpp
index 92be9d5c..3e623167 100644
--- a/primedev/plugins/plugins.cpp
+++ b/primedev/plugins/plugins.cpp
@@ -2,7 +2,6 @@
#include "pluginmanager.h"
#include "squirrel/squirrel.h"
#include "util/wininfo.h"
-#include "core/sourceinterface.h"
#include "logging/logging.h"
#include "dedicated/dedicated.h"
@@ -24,6 +23,7 @@ bool isValidSquirrelIdentifier(std::string s)
Plugin::Plugin(std::string path)
: m_location(path)
+ , m_logColor(NS::Colors::PLUGIN)
{
HMODULE pluginModule = GetModuleHandleA(path.c_str());
@@ -70,6 +70,13 @@ Plugin::Plugin(std::string path)
m_runOnServer = context & PluginContext::DEDICATED;
m_runOnClient = context & PluginContext::CLIENT;
+ int64_t logColor = m_pluginId->GetField(PluginField::COLOR);
+ // Apply custom colour if plugin has specified one
+ if ((logColor & 0xFFFFFF) != 0)
+ {
+ m_logColor = Color((int)(logColor & 0xFF), (int)((logColor >> 8) & 0xFF), (int)((logColor >> 16) & 0xFF));
+ }
+
if (!name)
{
NS::log::PLUGINSYS->error("Could not load name of plugin at '{}'", path);
@@ -106,7 +113,7 @@ Plugin::Plugin(std::string path)
return;
}
- m_logger = std::make_shared<ColoredLogger>(m_logName, NS::Colors::PLUGIN);
+ m_logger = std::make_shared<ColoredLogger>(m_logName, m_logColor);
RegisterLogger(m_logger);
if (IsDedicatedServer() && !m_runOnServer)
diff --git a/primedev/plugins/plugins.h b/primedev/plugins/plugins.h
index d004038c..95ec08b5 100644
--- a/primedev/plugins/plugins.h
+++ b/primedev/plugins/plugins.h
@@ -1,5 +1,5 @@
#pragma once
-#include "core/sourceinterface.h"
+#include "core/tier1.h"
#include "plugins/interfaces/interface.h"
#include "plugins/interfaces/IPluginId.h"
#include "plugins/interfaces/IPluginCallbacks.h"
@@ -20,6 +20,7 @@ private:
std::string m_location; // path of the dll
bool m_runOnServer;
bool m_runOnClient;
+ Color m_logColor;
public:
HMODULE m_handle;
diff --git a/primedev/scripts/client/clientchathooks.cpp b/primedev/scripts/client/clientchathooks.cpp
index e084f47e..c0a06dd2 100644
--- a/primedev/scripts/client/clientchathooks.cpp
+++ b/primedev/scripts/client/clientchathooks.cpp
@@ -6,12 +6,8 @@
#include <rapidjson/document.h>
-AUTOHOOK_INIT()
-
-// clang-format off
-AUTOHOOK(CHudChat__AddGameLine, client.dll + 0x22E580,
-void, __fastcall, (void* self, const char* message, int inboxId, bool isTeam, bool isDead))
-// clang-format on
+static void(__fastcall* o_pCHudChat__AddGameLine)(void* self, const char* message, int inboxId, bool isTeam, bool isDead) = nullptr;
+static void __fastcall h_CHudChat__AddGameLine(void* self, const char* message, int inboxId, bool isTeam, bool isDead)
{
// This hook is called for each HUD, but we only want our logic to run once.
if (self != *CHudChat::allHuds)
@@ -36,7 +32,7 @@ void, __fastcall, (void* self, const char* message, int inboxId, bool isTeam, bo
"CHudChat_ProcessMessageStartThread", static_cast<int>(senderId) - 1, payload, isTeam, isDead, type);
if (result == SQRESULT_ERROR)
for (CHudChat* hud = *CHudChat::allHuds; hud != NULL; hud = hud->next)
- CHudChat__AddGameLine(hud, message, inboxId, isTeam, isDead);
+ o_pCHudChat__AddGameLine(hud, message, inboxId, isTeam, isDead);
}
ADD_SQFUNC("void", NSChatWrite, "int context, string text", "", ScriptContext::CLIENT)
@@ -68,5 +64,6 @@ ADD_SQFUNC("void", NSChatWriteLine, "int context, string text", "", ScriptContex
ON_DLL_LOAD_CLIENT("client.dll", ClientChatHooks, (CModule module))
{
- AUTOHOOK_DISPATCH()
+ o_pCHudChat__AddGameLine = module.Offset(0x22E580).RCast<decltype(o_pCHudChat__AddGameLine)>();
+ HookAttach(&(PVOID&)o_pCHudChat__AddGameLine, (PVOID)h_CHudChat__AddGameLine);
}
diff --git a/primedev/server/auth/serverauthentication.cpp b/primedev/server/auth/serverauthentication.cpp
index d0d4c698..58268bcf 100644
--- a/primedev/server/auth/serverauthentication.cpp
+++ b/primedev/server/auth/serverauthentication.cpp
@@ -19,8 +19,6 @@
#include <string>
#include <thread>
-AUTOHOOK_INIT()
-
// global vars
ServerAuthenticationManager* g_pServerAuthentication;
CBaseServer__RejectConnectionType CBaseServer__RejectConnection;
@@ -207,9 +205,25 @@ void ServerAuthenticationManager::WritePersistentData(CBaseClient* pPlayer)
char* pNextPlayerToken;
uint64_t iNextPlayerUid;
-// clang-format off
-AUTOHOOK(CBaseServer__ConnectClient, engine.dll + 0x114430,
-void*,, (
+static void* (*o_pCBaseServer__ConnectClient)(
+ void* self,
+ void* addr,
+ void* a3,
+ uint32_t a4,
+ uint32_t a5,
+ int32_t a6,
+ void* a7,
+ char* playerName,
+ char* serverFilter,
+ void* a10,
+ char a11,
+ void* a12,
+ char a13,
+ char a14,
+ int64_t uid,
+ uint32_t a16,
+ uint32_t a17) = nullptr;
+static void* h_CBaseServer__ConnectClient(
void* self,
void* addr,
void* a3,
@@ -226,22 +240,21 @@ void*,, (
char a14,
int64_t uid,
uint32_t a16,
- uint32_t a17))
-// clang-format on
+ uint32_t a17)
{
// auth tokens are sent with serverfilter, can't be accessed from player struct to my knowledge, so have to do this here
pNextPlayerToken = serverFilter;
iNextPlayerUid = uid;
- return CBaseServer__ConnectClient(self, addr, a3, a4, a5, a6, a7, playerName, serverFilter, a10, a11, a12, a13, a14, uid, a16, a17);
+ return o_pCBaseServer__ConnectClient(self, addr, a3, a4, a5, a6, a7, playerName, serverFilter, a10, a11, a12, a13, a14, uid, a16, a17);
}
ConVar* Cvar_ns_allowuserclantags;
-// clang-format off
-AUTOHOOK(CBaseClient__Connect, engine.dll + 0x101740,
-bool,, (CBaseClient* self, char* pName, void* pNetChannel, char bFakePlayer, void* a5, char pDisconnectReason[256], void* a7))
-// clang-format on
+static bool (*o_pCBaseClient__Connect)(
+ CBaseClient* self, char* pName, void* pNetChannel, char bFakePlayer, void* a5, char pDisconnectReason[256], void* a7) = nullptr;
+static bool
+h_CBaseClient__Connect(CBaseClient* self, char* pName, void* pNetChannel, char bFakePlayer, void* a5, char pDisconnectReason[256], void* a7)
{
const char* pAuthenticationFailure = nullptr;
char pVerifiedName[64];
@@ -267,7 +280,7 @@ bool,, (CBaseClient* self, char* pName, void* pNetChannel, char bFakePlayer, voi
}
// try to actually connect the player
- if (!CBaseClient__Connect(self, pVerifiedName, pNetChannel, bFakePlayer, a5, pDisconnectReason, a7))
+ if (!o_pCBaseClient__Connect(self, pVerifiedName, pNetChannel, bFakePlayer, a5, pDisconnectReason, a7))
return false;
// we already know this player's authentication data is legit, actually write it to them now
@@ -279,10 +292,8 @@ bool,, (CBaseClient* self, char* pName, void* pNetChannel, char bFakePlayer, voi
return true;
}
-// clang-format off
-AUTOHOOK(CBaseClient__ActivatePlayer, engine.dll + 0x100F80,
-void,, (CBaseClient* self))
-// clang-format on
+static void (*o_pCBaseClient__ActivatePlayer)(CBaseClient* self) = nullptr;
+static void h_CBaseClient__ActivatePlayer(CBaseClient* self)
{
// if we're authed, write our persistent data
// RemovePlayerAuthData returns true if it removed successfully, i.e. on first call only, and we only want to write on >= second call
@@ -294,13 +305,11 @@ void,, (CBaseClient* self))
g_pServerPresence->SetPlayerCount((int)g_pServerAuthentication->m_PlayerAuthenticationData.size());
}
- CBaseClient__ActivatePlayer(self);
+ o_pCBaseClient__ActivatePlayer(self);
}
-// clang-format off
-AUTOHOOK(_CBaseClient__Disconnect, engine.dll + 0x1012C0,
-void,, (CBaseClient* self, uint32_t unknownButAlways1, const char* pReason, ...))
-// clang-format on
+static void (*o_pCBaseClient__Disconnect)(CBaseClient* self, uint32_t unknownButAlways1, const char* pReason, ...) = nullptr;
+static void h_CBaseClient__Disconnect(CBaseClient* self, uint32_t unknownButAlways1, const char* pReason, ...)
{
// have to manually format message because can't pass varargs to original func
char buf[1024];
@@ -328,7 +337,7 @@ void,, (CBaseClient* self, uint32_t unknownButAlways1, const char* pReason, ...)
g_pServerPresence->SetPlayerCount((int)g_pServerAuthentication->m_PlayerAuthenticationData.size());
- _CBaseClient__Disconnect(self, unknownButAlways1, buf);
+ o_pCBaseClient__Disconnect(self, unknownButAlways1, buf);
}
void ConCommand_ns_resetpersistence(const CCommand& args)
@@ -346,7 +355,17 @@ void ConCommand_ns_resetpersistence(const CCommand& args)
ON_DLL_LOAD_RELIESON("engine.dll", ServerAuthentication, (ConCommand, ConVar), (CModule module))
{
- AUTOHOOK_DISPATCH()
+ o_pCBaseServer__ConnectClient = module.Offset(0x114430).RCast<decltype(o_pCBaseServer__ConnectClient)>();
+ HookAttach(&(PVOID&)o_pCBaseServer__ConnectClient, (PVOID)h_CBaseServer__ConnectClient);
+
+ o_pCBaseClient__Connect = module.Offset(0x101740).RCast<decltype(o_pCBaseClient__Connect)>();
+ HookAttach(&(PVOID&)o_pCBaseClient__Connect, (PVOID)h_CBaseClient__Connect);
+
+ o_pCBaseClient__ActivatePlayer = module.Offset(0x100F80).RCast<decltype(o_pCBaseClient__ActivatePlayer)>();
+ HookAttach(&(PVOID&)o_pCBaseClient__ActivatePlayer, (PVOID)h_CBaseClient__ActivatePlayer);
+
+ o_pCBaseClient__Disconnect = module.Offset(0x1012C0).RCast<decltype(o_pCBaseClient__Disconnect)>();
+ HookAttach(&(PVOID&)o_pCBaseClient__Disconnect, (PVOID)h_CBaseClient__Disconnect);
g_pServerAuthentication = new ServerAuthenticationManager;
diff --git a/primedev/server/buildainfile.cpp b/primedev/server/buildainfile.cpp
index 19a6d0e3..456c84f0 100644
--- a/primedev/server/buildainfile.cpp
+++ b/primedev/server/buildainfile.cpp
@@ -7,8 +7,6 @@
namespace fs = std::filesystem;
-AUTOHOOK_INIT()
-
const int AINET_VERSION_NUMBER = 57;
const int AINET_SCRIPT_VERSION_NUMBER = 21;
const int PLACEHOLDER_CRC = 0;
@@ -359,22 +357,18 @@ void DumpAINInfo(CAI_Network* aiNetwork)
writeStream.close();
}
-// clang-format off
-AUTOHOOK(CAI_NetworkBuilder__Build, server.dll + 0x385E20,
-void, __fastcall, (void* builder, CAI_Network* aiNetwork, void* unknown))
-// clang-format on
+static void(__fastcall* o_pCAI_NetworkBuilder__Build)(void* builder, CAI_Network* aiNetwork, void* unknown) = nullptr;
+static void __fastcall h_CAI_NetworkBuilder__Build(void* builder, CAI_Network* aiNetwork, void* unknown)
{
- CAI_NetworkBuilder__Build(builder, aiNetwork, unknown);
+ o_pCAI_NetworkBuilder__Build(builder, aiNetwork, unknown);
DumpAINInfo(aiNetwork);
}
-// clang-format off
-AUTOHOOK(LoadAINFile, server.dll + 0x3933A0,
-void, __fastcall, (void* aimanager, void* buf, const char* filename))
-// clang-format on
+static void(__fastcall* o_pLoadAINFile)(void* aimanager, void* buf, const char* filename) = nullptr;
+static void __fastcall h_LoadAINFile(void* aimanager, void* buf, const char* filename)
{
- LoadAINFile(aimanager, buf, filename);
+ o_pLoadAINFile(aimanager, buf, filename);
if (Cvar_ns_ai_dumpAINfileFromLoad->GetBool())
{
@@ -385,7 +379,11 @@ void, __fastcall, (void* aimanager, void* buf, const char* filename))
ON_DLL_LOAD("server.dll", BuildAINFile, (CModule module))
{
- AUTOHOOK_DISPATCH()
+ o_pCAI_NetworkBuilder__Build = module.Offset(0x385E20).RCast<decltype(o_pCAI_NetworkBuilder__Build)>();
+ HookAttach(&(PVOID&)o_pCAI_NetworkBuilder__Build, (PVOID)h_CAI_NetworkBuilder__Build);
+
+ o_pLoadAINFile = module.Offset(0x3933A0).RCast<decltype(o_pLoadAINFile)>();
+ HookAttach(&(PVOID&)o_pLoadAINFile, (PVOID)h_LoadAINFile);
Cvar_ns_ai_dumpAINfileFromLoad = new ConVar(
"ns_ai_dumpAINfileFromLoad", "0", FCVAR_NONE, "For debugging: whether we should dump ain data for ains loaded from disk");