aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--NorthstarDLL/config/profile.cpp2
-rw-r--r--NorthstarDLL/core/filesystem/filesystem.cpp5
-rw-r--r--NorthstarDLL/mods/modmanager.cpp38
-rw-r--r--NorthstarDLL/mods/modmanager.h13
-rw-r--r--NorthstarDLL/mods/reload/reloadmodweapons.cpp42
-rw-r--r--NorthstarDLL/mods/reload/reloadmodweapons_misc.cpp72
-rw-r--r--NorthstarDLL/scripts/client/scriptmodmenu.cpp7
7 files changed, 159 insertions, 20 deletions
diff --git a/NorthstarDLL/config/profile.cpp b/NorthstarDLL/config/profile.cpp
index 80ddb59f..017735d0 100644
--- a/NorthstarDLL/config/profile.cpp
+++ b/NorthstarDLL/config/profile.cpp
@@ -39,5 +39,5 @@ void InitialiseNorthstarPrefix()
// set the console title to show the current profile
// dont do this on dedi as title contains useful information on dedi and setting title breaks it as well
if (!IsDedicatedServer())
- SetConsoleTitleA((fs::path("NorthstarLauncher | ") / NORTHSTAR_FOLDER_PREFIX).string().c_str());
+ SetConsoleTitleA((std::string("NorthstarLauncher | ") + NORTHSTAR_FOLDER_PREFIX.string()).c_str());
}
diff --git a/NorthstarDLL/core/filesystem/filesystem.cpp b/NorthstarDLL/core/filesystem/filesystem.cpp
index b06bd140..1646562c 100644
--- a/NorthstarDLL/core/filesystem/filesystem.cpp
+++ b/NorthstarDLL/core/filesystem/filesystem.cpp
@@ -12,7 +12,7 @@ using namespace R2;
bool bReadingOriginalFile = false;
std::string sCurrentModPath;
-ConVar* Cvar_ns_fs_log_reads;
+VAR_AT(filesystem_stdio.dll + 0xE5940, ConVar*, Cvar_fs_showAllReads);
// use the R2 namespace for game funcs
namespace R2
@@ -84,6 +84,9 @@ void SetNewModSearchPaths(Mod* mod)
bool TryReplaceFile(const char* pPath, bool shouldCompile)
{
+ if (Cvar_fs_showAllReads->GetBool())
+ spdlog::info("filesystem open: {}", pPath);
+
if (bReadingOriginalFile)
return false;
diff --git a/NorthstarDLL/mods/modmanager.cpp b/NorthstarDLL/mods/modmanager.cpp
index ab1ef791..6d36a975 100644
--- a/NorthstarDLL/mods/modmanager.cpp
+++ b/NorthstarDLL/mods/modmanager.cpp
@@ -294,7 +294,7 @@ ModManager::ModManager()
m_LastModLoadState = nullptr;
m_ModLoadState = new ModLoadState;
- LoadMods(false);
+ LoadMods(false, false);
}
template <ScriptContext context> auto ModConCommandCallback_Internal(std::string name, const CCommand& command)
@@ -352,7 +352,7 @@ auto ModConCommandCallback(const CCommand& command)
-void ModManager::LoadMods(bool bDeferredAssetReload)
+void ModManager::LoadMods(bool bReloadAssets, bool bDeferredAssetReload)
{
// reset state of all currently loaded mods, if we've loaded once already
if (m_bHasLoadedMods)
@@ -366,7 +366,7 @@ void ModManager::LoadMods(bool bDeferredAssetReload)
LoadModDefinitions();
// install mods (load all files)
- InstallMods(bDeferredAssetReload);
+ InstallMods(bReloadAssets, bDeferredAssetReload);
// write json storing currently enabled mods
SaveEnabledMods();
@@ -1043,6 +1043,21 @@ void ModManager::ReloadNecessaryModAssets(bool bDeferred, const ModAssetsToReloa
}
else
{
+ if (pAssetsToReload->bAimAssistSettings)
+ TryImmediateReloadADSPulls();
+
+ if (pAssetsToReload->bAmmoSuckBehaviours)
+ TryImmediateReloadAmmoSuckBehaviours();
+
+ if (pAssetsToReload->bDamageDefs)
+ TryImmediateReloadDamageFlags();
+
+ if (pAssetsToReload->bWeaponSprings)
+ TryImmediateReloadWeaponSprings();
+
+ TryImmediateReloadWeapons(pAssetsToReload->setsWeaponSettings);
+
+
// need to reimplement mat_reloadmaterials for this
// if (m_AssetTypesToReload.bMaterials)
// R2::Cbuf_AddText(R2::Cbuf_GetCurrentPlayer(), "mat_reloadmaterials", R2::cmd_source_t::kCommandSrcCode);
@@ -1057,7 +1072,7 @@ void ModManager::ReloadNecessaryModAssets(bool bDeferred, const ModAssetsToReloa
R2::Cbuf_Execute();
}
-void ModManager::InstallMods(bool bDeferredAssetReload)
+void ModManager::InstallMods(bool bReloadAssets, bool bDeferredAssetReload)
{
for (Mod& mod : GetMods() | FilterEnabled)
{
@@ -1075,7 +1090,7 @@ void ModManager::InstallMods(bool bDeferredAssetReload)
InstallModFileOverrides(mod);
}
- if (m_bHasLoadedMods) // only reload assets after initial load
+ if (m_bHasLoadedMods && bReloadAssets) // only reload assets after initial load
{
ModAssetsToReload assetsToReload;
@@ -1183,12 +1198,20 @@ void ModManager::CompileAssetsForFile(const char* filename)
void ConCommand_mods_reload(const CCommand& args)
{
- g_pModManager->LoadMods(false);
+ // reload assets now
+ g_pModManager->LoadMods(true, false);
}
void ConCommand_mods_reload_deferred(const CCommand& args)
{
- g_pModManager->LoadMods(true);
+ // reload assets later
+ g_pModManager->LoadMods(true, true);
+}
+
+void ConCommand_mods_no_asset_reload(const CCommand& args)
+{
+ // reload assets never
+ g_pModManager->LoadMods(false, false);
}
void ConCommand_mods_getfileowner(const CCommand& args)
@@ -1232,5 +1255,6 @@ ON_DLL_LOAD_RELIESON("engine.dll", ModManager, (ConCommand, MasterServer), (CMod
RegisterConCommand("reload_mods", ConCommand_mods_reload, "reloads mods", FCVAR_NONE);
RegisterConCommand("mods_reload", ConCommand_mods_reload, "reloads mods", FCVAR_NONE);
RegisterConCommand("mods_reload_deferred", ConCommand_mods_reload_deferred, "reloads mods, prefers reloading assets on level load rather than now", FCVAR_NONE);
+ RegisterConCommand("mods_reload_no_asset_reload", ConCommand_mods_no_asset_reload, "reloads mods without trying to reload assets", FCVAR_NONE);
RegisterConCommand("mods_getfileowner", ConCommand_mods_getfileowner, "find the mod that owns a given file", FCVAR_NONE);
}
diff --git a/NorthstarDLL/mods/modmanager.h b/NorthstarDLL/mods/modmanager.h
index 9b194ea9..9eccffc5 100644
--- a/NorthstarDLL/mods/modmanager.h
+++ b/NorthstarDLL/mods/modmanager.h
@@ -141,7 +141,7 @@ class ModManager
void LoadModDefinitions();
void SaveEnabledMods();
void BuildPublicModList();
- void InstallMods(bool bDeferredAssetReload);
+ void InstallMods(bool bReloadAssets, bool bDeferredAssetReload);
struct ModAssetsToReload
{
@@ -203,7 +203,7 @@ class ModManager
public:
ModManager();
- void LoadMods(bool bDeferredAssetReload);
+ void LoadMods(bool bReloadAssets, bool bDeferredAssetReload);
std::string NormaliseModFilePath(const fs::path path);
void CompileAssetsForFile(const char* filename);
@@ -235,7 +235,14 @@ class ModManager
void DeferredReloadADSPulls();
void DeferredReloadWeapons(const std::unordered_set<std::string> setsWeapons);
- // asset reloading funcs
+ // hybrid asset reloading funcs (i.e. try reload on both client and server immediately, defer sides that aren't currently possible)
+ void TryImmediateReloadDamageFlags();
+ void TryImmediateReloadWeaponSprings();
+ void TryImmediateReloadAmmoSuckBehaviours();
+ void TryImmediateReloadADSPulls();
+ void TryImmediateReloadWeapons(const std::unordered_set<std::string> setsWeapons);
+
+ // individual asset reloading funcs
bool TryReloadWeapon(const char* pWeaponName, const SidedWeaponReloadPointers* pReloadPointers);
// for std::views::filter, e.g. for (Mod& mod : g_pModManager::GetMods() | ModManager::FilterEnabled)
diff --git a/NorthstarDLL/mods/reload/reloadmodweapons.cpp b/NorthstarDLL/mods/reload/reloadmodweapons.cpp
index 4619fb31..077c2835 100644
--- a/NorthstarDLL/mods/reload/reloadmodweapons.cpp
+++ b/NorthstarDLL/mods/reload/reloadmodweapons.cpp
@@ -1,4 +1,6 @@
#include "mods/modmanager.h"
+#include "dedicated/dedicated.h"
+#include "engine/r2engine.h"
AUTOHOOK_INIT()
@@ -23,9 +25,13 @@ OFFSET_STRUCT(GlobalWeaponDefs)
VAR_AT(client.dll + 0xB33A02, uint16_t*, g_pnClientWeaponsLoaded);
VAR_AT(client.dll + 0xB339E8, GlobalWeaponDefs**, g_ppClientWeaponDefs);
+VAR_AT(server.dll + 0xBB57C2, uint16_t*, g_pnServerWeaponsLoaded);
+VAR_AT(server.dll + 0xBB57A8, GlobalWeaponDefs**, g_ppServerWeaponDefs);
FUNCTION_AT(client.dll + 0x3D2FB0, void,, ClientReparseWeapon, (WeaponDefinition* pWeapon));
FUNCTION_AT(client.dll + 0x3CE270, void,, ClientReloadWeaponCallbacks, (int nWeaponIndex));
+FUNCTION_AT(client.dll + 0x6D1170, void,, ServerReparseWeapon, (WeaponDefinition * pWeapon));
+FUNCTION_AT(client.dll + 0x6CCE80, void, , ServerReloadWeaponCallbacks, (int nWeaponIndex));
std::unordered_set<std::string> setsClientWeaponsToReload;
std::unordered_set<std::string> setsServerWeaponsToReload;
@@ -43,6 +49,7 @@ struct SidedWeaponReloadPointers
void (*m_fnReparseWeapon)(WeaponDefinition* pWeapon);
void (*m_fnReloadWeaponCallbacks)(int nWeaponIndex);
+ SidedWeaponReloadPointers() {} // don't use
SidedWeaponReloadPointers(
uint16_t* pnWeaponsLoaded,
GlobalWeaponDefs** ppWeaponDefs,
@@ -56,8 +63,7 @@ struct SidedWeaponReloadPointers
m_fnReparseWeapon = fnReparseWeapon;
m_fnReloadWeaponCallbacks = fnReloadWeaponCallbacks;
}
-};
-
+} clientReloadPointers, serverReloadPointers;
int WeaponIndexByName(const char* pWeaponName, const SidedWeaponReloadPointers* pReloadPointers)
{
@@ -81,6 +87,24 @@ void ModManager::DeferredReloadWeapons(const std::unordered_set<std::string> set
}
}
+void ModManager::TryImmediateReloadWeapons(const std::unordered_set<std::string> setsWeapons)
+{
+ // try to reload all weapons on client and server, if we can't reload for any reason
+ // (either due to either side being inactive, or just failure to reload)
+ for (const std::string& sWeapon : setsWeapons)
+ {
+ if (!IsDedicatedServer())
+ {
+ setsClientWeaponsToReload.insert(sWeapon);
+ // if this fails, the weapon will still be there for deferred reload
+ TryReloadWeapon(sWeapon.c_str(), &clientReloadPointers);
+ }
+
+ setsServerWeaponsToReload.insert(sWeapon);
+ TryReloadWeapon(sWeapon.c_str(), &serverReloadPointers);
+ }
+}
+
bool ModManager::TryReloadWeapon(const char* pWeaponName, const SidedWeaponReloadPointers* pReloadPointers)
{
if (!pReloadPointers->m_psetsWeaponsToReload->contains(pWeaponName))
@@ -108,9 +132,6 @@ AUTOHOOK(ClientPrecacheWeaponFromStringtable, client.dll + 0x195A60,
bool, __fastcall, (void* a1, void* a2, void* a3, const char* pWeaponName))
// clang-format on
{
- static SidedWeaponReloadPointers clientReloadPointers(
- g_pnClientWeaponsLoaded, g_ppClientWeaponDefs, &setsClientWeaponsToReload, ClientReparseWeapon, ClientReloadWeaponCallbacks);
-
if (g_pModManager->TryReloadWeapon(pWeaponName, &clientReloadPointers))
return true;
@@ -120,5 +141,16 @@ bool, __fastcall, (void* a1, void* a2, void* a3, const char* pWeaponName))
ON_DLL_LOAD_CLIENT("client.dll", ModReloadWeaponsClient, (CModule module))
{
+ AUTOHOOK_DISPATCH_MODULE(client.dll)
+
+ clientReloadPointers = SidedWeaponReloadPointers(
+ g_pnClientWeaponsLoaded, g_ppClientWeaponDefs, &setsClientWeaponsToReload, ClientReparseWeapon, ClientReloadWeaponCallbacks);
+}
+
+ON_DLL_LOAD_CLIENT("server.dll", ModReloadWeaponsServer, (CModule module))
+{
AUTOHOOK_DISPATCH_MODULE(server.dll)
+
+ serverReloadPointers = SidedWeaponReloadPointers(
+ g_pnServerWeaponsLoaded, g_ppServerWeaponDefs, &setsServerWeaponsToReload, ServerReparseWeapon, ServerReloadWeaponCallbacks);
}
diff --git a/NorthstarDLL/mods/reload/reloadmodweapons_misc.cpp b/NorthstarDLL/mods/reload/reloadmodweapons_misc.cpp
index 5f43b11f..75503382 100644
--- a/NorthstarDLL/mods/reload/reloadmodweapons_misc.cpp
+++ b/NorthstarDLL/mods/reload/reloadmodweapons_misc.cpp
@@ -1,4 +1,6 @@
#include "mods/modmanager.h"
+#include "dedicated/dedicated.h"
+#include "engine/r2engine.h"
AUTOHOOK_INIT()
@@ -9,11 +11,21 @@ VAR_AT(client.dll + 0x23EF0C6, bool*, g_pbClientHasLoadedWeaponSprings);
VAR_AT(client.dll + 0x23EF0C7, bool*, g_pbClientHasLoadedWeaponAmmoSuckBehaviours);
VAR_AT(client.dll + 0x23EF0C4, bool*, g_pbClientHasLoadedWeaponADSPulls);
+FUNCTION_AT(client.dll + 0x3CDDF0, void,, ClientReparseDamageFlags, ()); // requires g_pbClientHasLoadedDamageFlags to be false
+FUNCTION_AT(client.dll + 0x3CE5B0, void,, ClientReparseWeaponSprings, ());
+FUNCTION_AT(client.dll + 0x3CE060, void,, ClientReparseWeaponAmmoSuckBehaviours, ());
+FUNCTION_AT(client.dll + 0x3CD700, void,, ClientReparseWeaponADSPulls, ());
+
VAR_AT(server.dll + 0x160B474, bool*, g_pbServerHasLoadedDamageFlags);
VAR_AT(server.dll + 0x160B475, bool*, g_pbServerHasLoadedWeaponSprings);
VAR_AT(server.dll + 0x160B476, bool*, g_pbServerHasLoadedWeaponAmmoSuckBehaviours);
VAR_AT(server.dll + 0x160B477, bool*, g_pbServerHasLoadedWeaponADSPulls);
+FUNCTION_AT(client.dll + 0x6CC9F0, void,, ServerReparseDamageFlags, ()); // requires g_pbClientHasLoadedDamageFlags to be false
+FUNCTION_AT(client.dll + 0x6CD1C0, void,, ServerReparseWeaponSprings, ());
+FUNCTION_AT(client.dll + 0x6CCC70, void,, ServerReparseWeaponAmmoSuckBehaviours, ());
+FUNCTION_AT(client.dll + 0x6CC300, void,, ServerReparseWeaponADSPulls, ());
+
void ModManager::DeferredReloadDamageFlags()
{
*g_pbClientHasLoadedDamageFlags = false;
@@ -38,8 +50,68 @@ void ModManager::DeferredReloadADSPulls()
*g_pbServerHasLoadedWeaponADSPulls = false;
}
+void ModManager::TryImmediateReloadDamageFlags()
+{
+ if (!IsDedicatedServer())
+ {
+ *g_pbClientHasLoadedDamageFlags = false;
+ if (g_pSquirrel<ScriptContext::CLIENT>->m_pSQVM)
+ ClientReparseDamageFlags();
+ }
+
+ *g_pbServerHasLoadedDamageFlags = false;
+ if (*R2::g_pServerState == R2::ss_active)
+ ServerReparseDamageFlags();
+}
+
+void ModManager::TryImmediateReloadWeaponSprings()
+{
+ if (!IsDedicatedServer())
+ {
+ *g_pbClientHasLoadedWeaponSprings = false;
+ if (g_pSquirrel<ScriptContext::CLIENT>->m_pSQVM)
+ ClientReparseWeaponSprings();
+ }
+
+ *g_pbServerHasLoadedWeaponSprings = false;
+ if (*R2::g_pServerState == R2::ss_active)
+ ServerReparseWeaponSprings();
+}
+
+void ModManager::TryImmediateReloadAmmoSuckBehaviours()
+{
+ if (!IsDedicatedServer())
+ {
+ *g_pbClientHasLoadedWeaponAmmoSuckBehaviours = false;
+ if (g_pSquirrel<ScriptContext::CLIENT>->m_pSQVM)
+ ClientReparseWeaponAmmoSuckBehaviours();
+ }
+
+ *g_pbServerHasLoadedWeaponAmmoSuckBehaviours = false;
+ if (*R2::g_pServerState == R2::ss_active)
+ ServerReparseWeaponAmmoSuckBehaviours();
+}
+
+void ModManager::TryImmediateReloadADSPulls()
+{
+ if (!IsDedicatedServer())
+ {
+ *g_pbClientHasLoadedWeaponADSPulls = false;
+ if (g_pSquirrel<ScriptContext::CLIENT>->m_pSQVM)
+ ClientReparseWeaponADSPulls();
+ }
+
+ *g_pbServerHasLoadedWeaponADSPulls = false;
+ if (*R2::g_pServerState == R2::ss_active)
+ ServerReparseWeaponADSPulls();
+}
ON_DLL_LOAD_CLIENT("client.dll", ClientModReloadWeaponsMisc, (CModule module))
{
AUTOHOOK_DISPATCH_MODULE(client.dll)
}
+
+ON_DLL_LOAD_CLIENT("server.dll", ServerModReloadWeaponsMisc, (CModule module))
+{
+ AUTOHOOK_DISPATCH_MODULE(server.dll)
+}
diff --git a/NorthstarDLL/scripts/client/scriptmodmenu.cpp b/NorthstarDLL/scripts/client/scriptmodmenu.cpp
index e16216fd..b969fca6 100644
--- a/NorthstarDLL/scripts/client/scriptmodmenu.cpp
+++ b/NorthstarDLL/scripts/client/scriptmodmenu.cpp
@@ -158,10 +158,11 @@ ADD_SQFUNC(
return SQRESULT_NOTNULL; // return empty array
}
-ADD_SQFUNC("void", NSReloadMods, "bool deferredReload = false", "", ScriptContext::UI)
+ADD_SQFUNC("void", NSReloadMods, "bool reloadAssets = true, bool deferredReload = false", "", ScriptContext::UI)
{
- const SQBool bDeferredReload = g_pSquirrel<context>->getbool(sqvm, 1);
- g_pModManager->LoadMods(bDeferredReload);
+ const SQBool bReloadAssets = g_pSquirrel<context>->getbool(sqvm, 1);
+ const SQBool bDeferredReload = g_pSquirrel<context>->getbool(sqvm, 2);
+ g_pModManager->LoadMods(bReloadAssets, bDeferredReload);
return SQRESULT_NULL;
}