Skip to content

Commit

Permalink
Merge branch 'main' into feat/overhaul-mod-loading-locations
Browse files Browse the repository at this point in the history
  • Loading branch information
GeckoEidechse authored Nov 12, 2024
2 parents a4b09bc + 13344f3 commit 6509283
Show file tree
Hide file tree
Showing 17 changed files with 85 additions and 88 deletions.
4 changes: 4 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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()
1 change: 0 additions & 1 deletion primedev/Northstar.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
1 change: 0 additions & 1 deletion primedev/core/convar/convar.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
#pragma once
#include "core/sourceinterface.h"
#include "core/math/color.h"
#include "cvar.h"
#include "concommand.h"
Expand Down
4 changes: 2 additions & 2 deletions primedev/core/filesystem/rpakfilesystem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -342,15 +342,15 @@ 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)
continue;

if (mod->RpakAliases.find(originalPath) != mod->RpakAliases.end())
{
originalPath = (mod->m_ModDirectory / "paks" / mod->RpakAliases[originalPath]).string();
originalPath = mod->RpakAliases[originalPath];
return;
}
}
Expand Down
1 change: 0 additions & 1 deletion primedev/core/sourceinterface.cpp
Original file line number Diff line number Diff line change
@@ -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
Expand Down
32 changes: 0 additions & 32 deletions primedev/core/sourceinterface.h

This file was deleted.

6 changes: 6 additions & 0 deletions primedev/core/tier1.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
1 change: 0 additions & 1 deletion primedev/logging/sourceconsole.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
#pragma once
#include "core/sourceinterface.h"
#include "spdlog/sinks/base_sink.h"
#include <map>

Expand Down
2 changes: 0 additions & 2 deletions primedev/mods/compiled/modkeyvalues.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@

#include <fstream>

AUTOHOOK_INIT()

void ModManager::TryBuildKeyValues(const char* filename)
{
spdlog::info("Building KeyValues for file {}", filename);
Expand Down
1 change: 1 addition & 0 deletions primedev/plugins/interfaces/IPluginId.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
1 change: 1 addition & 0 deletions primedev/plugins/interfaces/interface.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#include <string.h>
#include "core/tier1.h"
#include "interface.h"

InterfaceReg* s_pInterfaceRegs;
Expand Down
1 change: 1 addition & 0 deletions primedev/plugins/interfaces/sys/ISys.cpp
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
#include "core/tier1.h"
#include "plugins/interfaces/interface.h"
#include "ISys.h"
#include "plugins/plugins.h"
Expand Down
11 changes: 9 additions & 2 deletions primedev/plugins/plugins.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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"

Expand All @@ -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());

Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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)
Expand Down
3 changes: 2 additions & 1 deletion primedev/plugins/plugins.h
Original file line number Diff line number Diff line change
@@ -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"
Expand All @@ -20,6 +20,7 @@ class Plugin
std::string m_location; // path of the dll
bool m_runOnServer;
bool m_runOnClient;
Color m_logColor;

public:
HMODULE m_handle;
Expand Down
13 changes: 5 additions & 8 deletions primedev/scripts/client/clientchathooks.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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)
Expand Down Expand Up @@ -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);
}
67 changes: 43 additions & 24 deletions primedev/server/auth/serverauthentication.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,6 @@
#include <string>
#include <thread>

AUTOHOOK_INIT()

// global vars
ServerAuthenticationManager* g_pServerAuthentication;
CBaseServer__RejectConnectionType CBaseServer__RejectConnection;
Expand Down Expand Up @@ -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,
Expand All @@ -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];
Expand All @@ -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
Expand All @@ -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
Expand All @@ -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];
Expand Down Expand Up @@ -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)
Expand All @@ -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;

Expand Down
24 changes: 11 additions & 13 deletions primedev/server/buildainfile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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())
{
Expand All @@ -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");
Expand Down

0 comments on commit 6509283

Please sign in to comment.