aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBobTheBob <32057864+BobTheBob9@users.noreply.github.com>2021-07-28 04:16:20 +0100
committerBobTheBob <32057864+BobTheBob9@users.noreply.github.com>2021-07-28 04:16:20 +0100
commita5a937d19fcb51fe4168345d09596784e174726e (patch)
tree08eaf40ed362348c1ea187a477b71f70c6fe74a1
parent5ed2fbecaa3a96b69b97d889a28bd2f96fcf2572 (diff)
downloadNorthstarLauncher-a5a937d19fcb51fe4168345d09596784e174726e.tar.gz
NorthstarLauncher-a5a937d19fcb51fe4168345d09596784e174726e.zip
improve lookup speeds for mod files
-rw-r--r--NorthstarDedicatedTest/filesystem.cpp29
-rw-r--r--NorthstarDedicatedTest/modmanager.cpp8
-rw-r--r--NorthstarDedicatedTest/modmanager.h3
-rw-r--r--NorthstarDedicatedTest/scriptsrson.cpp13
-rw-r--r--NorthstarDedicatedTest/scriptsrson.h3
-rw-r--r--NorthstarDedicatedTest/serverauthentication.cpp36
-rw-r--r--NorthstarDedicatedTest/serverauthentication.h1
7 files changed, 62 insertions, 31 deletions
diff --git a/NorthstarDedicatedTest/filesystem.cpp b/NorthstarDedicatedTest/filesystem.cpp
index 04b8c98e..1a2fb993 100644
--- a/NorthstarDedicatedTest/filesystem.cpp
+++ b/NorthstarDedicatedTest/filesystem.cpp
@@ -9,13 +9,13 @@
#include <sstream>
// hook forward declares
-typedef FileHandle_t(*ReadFileFromVPKType)(VPKData* vpkInfo, __int64* b, const char* filename);
+typedef FileHandle_t(*ReadFileFromVPKType)(VPKData* vpkInfo, __int64* b, char* filename);
ReadFileFromVPKType readFileFromVPK;
-FileHandle_t ReadFileFromVPKHook(VPKData* vpkInfo, __int64* b, const char* filename);
+FileHandle_t ReadFileFromVPKHook(VPKData* vpkInfo, __int64* b, char* filename);
-typedef bool(*ReadFromCacheType)(IFileSystem* filesystem, const char* path, void* result);
+typedef bool(*ReadFromCacheType)(IFileSystem* filesystem, char* path, void* result);
ReadFromCacheType readFromCache;
-bool ReadFromCacheHook(IFileSystem* filesystem, const char* path, void* result);
+bool ReadFromCacheHook(IFileSystem* filesystem, char* path, void* result);
typedef void(*AddSearchPathType)(IFileSystem* fileSystem, const char* pPath, const char* pathID, SearchPathAdd_t addType);
AddSearchPathType addSearchPathOriginal;
@@ -78,32 +78,31 @@ void SetNewModSearchPaths(Mod* mod)
currentModPath = (fs::absolute(mod->ModDirectory) / MOD_OVERRIDE_DIR).string();
}
}
- else if (!currentModPath.size()) // if currentModPath isn't set yet, then push compiled to head
+ else // push compiled to head
addSearchPathOriginal(&*(*g_Filesystem), fs::absolute(COMPILED_ASSETS_PATH).string().c_str(), "GAME", PATH_ADD_TO_HEAD);
}
-bool TryReplaceFile(const char* path)
+bool TryReplaceFile(char* path)
{
if (readingOriginalFile)
return false;
(*g_ModManager).CompileAssetsForFile(path);
- // is this efficient? could probably be improved
- for (ModOverrideFile* modFile : g_ModManager->m_modFiles)
+ // idk how efficient the lexically normal check is
+ // can't just set all /s in path to \, since some paths aren't in writeable memory
+ auto file = g_ModManager->m_modFiles.find(fs::path(path).lexically_normal().string());
+ if (file != g_ModManager->m_modFiles.end())
{
- if (!modFile->path.compare(fs::path(path).lexically_normal()))
- {
- SetNewModSearchPaths(modFile->owningMod);
- return true;
- }
+ SetNewModSearchPaths(file->second->owningMod);
+ return true;
}
return false;
}
-FileHandle_t ReadFileFromVPKHook(VPKData* vpkInfo, __int64* b, const char* filename)
+FileHandle_t ReadFileFromVPKHook(VPKData* vpkInfo, __int64* b, char* filename)
{
// move this to a convar at some point when we can read them in native
//spdlog::info("ReadFileFromVPKHook {} {}", filename, vpkInfo->path);
@@ -116,7 +115,7 @@ FileHandle_t ReadFileFromVPKHook(VPKData* vpkInfo, __int64* b, const char* filen
return readFileFromVPK(vpkInfo, b, filename);
}
-bool ReadFromCacheHook(IFileSystem* filesystem, const char* path, void* result)
+bool ReadFromCacheHook(IFileSystem* filesystem, char* path, void* result)
{
// move this to a convar at some point when we can read them in native
//spdlog::info("ReadFromCacheHook {}", path);
diff --git a/NorthstarDedicatedTest/modmanager.cpp b/NorthstarDedicatedTest/modmanager.cpp
index ea16f591..964d37ae 100644
--- a/NorthstarDedicatedTest/modmanager.cpp
+++ b/NorthstarDedicatedTest/modmanager.cpp
@@ -248,13 +248,15 @@ void ModManager::LoadMods()
{
for (fs::directory_entry file : fs::recursive_directory_iterator(m_loadedMods[i]->ModDirectory / MOD_OVERRIDE_DIR))
{
- if (file.is_regular_file())
+ fs::path path = file.path().lexically_relative(m_loadedMods[i]->ModDirectory / MOD_OVERRIDE_DIR).lexically_normal();
+
+ if (file.is_regular_file() && m_modFiles.find(path.string()) == m_modFiles.end())
{
// super temp because it relies hard on load order
ModOverrideFile* modFile = new ModOverrideFile;
modFile->owningMod = m_loadedMods[i];
- modFile->path = file.path().lexically_relative(m_loadedMods[i]->ModDirectory / MOD_OVERRIDE_DIR).lexically_normal();
- m_modFiles.push_back(modFile);
+ modFile->path = path;
+ m_modFiles.insert(std::make_pair(path.string(), modFile));
}
}
}
diff --git a/NorthstarDedicatedTest/modmanager.h b/NorthstarDedicatedTest/modmanager.h
index 78b3153c..6146de0a 100644
--- a/NorthstarDedicatedTest/modmanager.h
+++ b/NorthstarDedicatedTest/modmanager.h
@@ -92,7 +92,8 @@ class ModManager
{
public:
std::vector<Mod*> m_loadedMods;
- std::vector<ModOverrideFile*> m_modFiles;
+ //std::vector<ModOverrideFile*> m_modFiles;
+ std::unordered_map<std::string, ModOverrideFile*> m_modFiles;
public:
ModManager();
diff --git a/NorthstarDedicatedTest/scriptsrson.cpp b/NorthstarDedicatedTest/scriptsrson.cpp
index 1f08e7f1..b5aef421 100644
--- a/NorthstarDedicatedTest/scriptsrson.cpp
+++ b/NorthstarDedicatedTest/scriptsrson.cpp
@@ -20,6 +20,11 @@ void ModManager::BuildScriptsRson()
for (Mod* mod : m_loadedMods)
{
+ // this isn't needed at all, just nice to have imo
+ scriptsRson += "// MOD: ";
+ scriptsRson += mod->Name;
+ scriptsRson += ":\n\n";
+
for (ModScript* script : mod->Scripts)
{
/* should create something with this format for each script
@@ -47,8 +52,12 @@ void ModManager::BuildScriptsRson()
ModOverrideFile* overrideFile = new ModOverrideFile;
overrideFile->owningMod = nullptr;
- overrideFile->path = "scripts/vscripts/scripts.rson";
- m_modFiles.push_back(overrideFile);
+ overrideFile->path = VPK_SCRIPTS_RSON_PATH;
+
+ if (m_modFiles.find(VPK_SCRIPTS_RSON_PATH) == m_modFiles.end())
+ m_modFiles.insert(std::make_pair(VPK_SCRIPTS_RSON_PATH, overrideFile));
+ else
+ m_modFiles[VPK_SCRIPTS_RSON_PATH] = overrideFile;
// todo: for preventing dupe scripts in scripts.rson, we could actually parse when conditions with the squirrel vm, just need a way to get a result out of squirrelmanager.ExecuteCode
// this would probably be the best way to do this, imo
diff --git a/NorthstarDedicatedTest/scriptsrson.h b/NorthstarDedicatedTest/scriptsrson.h
index f9297065..16e91fb8 100644
--- a/NorthstarDedicatedTest/scriptsrson.h
+++ b/NorthstarDedicatedTest/scriptsrson.h
@@ -1,3 +1,4 @@
#pragma once
-const fs::path MOD_SCRIPTS_RSON_PATH = COMPILED_ASSETS_PATH / "scripts/vscripts/scripts.rson"; \ No newline at end of file
+const fs::path MOD_SCRIPTS_RSON_PATH = COMPILED_ASSETS_PATH / "scripts/vscripts/scripts.rson";
+const char* VPK_SCRIPTS_RSON_PATH = "scripts\\vscripts\\scripts.rson"; \ No newline at end of file
diff --git a/NorthstarDedicatedTest/serverauthentication.cpp b/NorthstarDedicatedTest/serverauthentication.cpp
index da7702d2..a856c00f 100644
--- a/NorthstarDedicatedTest/serverauthentication.cpp
+++ b/NorthstarDedicatedTest/serverauthentication.cpp
@@ -83,6 +83,23 @@ bool ServerAuthenticationManager::AuthenticatePlayer(void* player, char* authTok
return true; // auth successful, client stays on
}
+bool ServerAuthenticationManager::RemovePlayerAuthData(void* player)
+{
+ // we don't have our auth token at this point, so lookup authdata by uid
+ for (auto& auth : m_authData)
+ {
+ if (!strcmp((char*)player + 0xF500, auth.second->uid))
+ {
+ // pretty sure this is fine, since we don't iterate after the erase
+ // i think if we iterated after it'd be undefined behaviour tho
+ m_authData.erase(auth.first);
+ return true;
+ }
+ }
+
+ return false;
+}
+
void ServerAuthenticationManager::WritePersistentData(void* player)
{
// we use 0x4 internally to mark clients as using remote persistence
@@ -100,7 +117,7 @@ void ServerAuthenticationManager::WritePersistentData(void* player)
// auth hooks
// store this in a var so we can use it in CBaseClient::Connect
-// this is fine because serverfilter ptr won't decay by the time we use this
+// this is fine because serverfilter ptr won't decay by the time we use this, just don't use it outside of cbaseclient::connect
char* nextPlayerToken;
void* CBaseServer__ConnectClientHook(void* server, void* a2, void* a3, uint32_t a4, uint32_t a5, int32_t a6, void* a7, void* a8, char* serverFilter, void* a10, char a11, void* a12, char a13, char a14, void* a15, uint32_t a16, uint32_t a17)
@@ -116,7 +133,9 @@ char CBaseClient__ConnectHook(void* self, char* name, __int64 netchan_ptr_arg, c
// try to auth player, dc if it fails
// we connect irregardless of auth, because returning bad from this function can fuck client state p bad
char ret = CBaseClient__Connect(self, name, netchan_ptr_arg, b_fake_player_arg, a5, Buffer, a7);
- if (!g_ServerAuthenticationManager->AuthenticatePlayer(self, nextPlayerToken))
+ if (strlen(name) >= 64) // fix for name overflow bug
+ CBaseClient__Disconnect(self, 1, "Invalid name");
+ else if (!g_ServerAuthenticationManager->AuthenticatePlayer(self, nextPlayerToken))
CBaseClient__Disconnect(self, 1, "Authentication Failed");
return ret;
@@ -124,13 +143,12 @@ char CBaseClient__ConnectHook(void* self, char* name, __int64 netchan_ptr_arg, c
void CBaseClient__ActivatePlayerHook(void* self)
{
- // check whether we're authed, todo: need to only write persistence on/after second call to this per player
- // todo: also need to remove authdata here
- if (*((char*)self + 0x4A0) >= (char)0x3)
- {
- CBaseClient__ActivatePlayer(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 (since this func is called on map loads)
+ if (*((char*)self + 0x4A0) >= (char)0x3 && !g_ServerAuthenticationManager->RemovePlayerAuthData(self))
g_ServerAuthenticationManager->WritePersistentData(self);
- }
+
+ CBaseClient__ActivatePlayer(self);
}
void CBaseClient__DisconnectHook(void* self, uint32_t unknownButAlways1, const char* reason, ...)
@@ -159,7 +177,7 @@ void InitialiseServerAuthentication(HMODULE baseAddress)
HookEnabler hook;
ENABLER_CREATEHOOK(hook, (char*)baseAddress + 0x114430, &CBaseServer__ConnectClientHook, reinterpret_cast<LPVOID*>(&CBaseServer__ConnectClient));
ENABLER_CREATEHOOK(hook, (char*)baseAddress + 0x101740, &CBaseClient__ConnectHook, reinterpret_cast<LPVOID*>(&CBaseClient__Connect));
- //ENABLER_CREATEHOOK(hook, (char*)baseAddress + 0x100F80, &CBaseClient__ActivatePlayerHook, reinterpret_cast<LPVOID*>(&CBaseClient__ActivatePlayer));
+ ENABLER_CREATEHOOK(hook, (char*)baseAddress + 0x100F80, &CBaseClient__ActivatePlayerHook, reinterpret_cast<LPVOID*>(&CBaseClient__ActivatePlayer));
ENABLER_CREATEHOOK(hook, (char*)baseAddress + 0x1012C0, &CBaseClient__DisconnectHook, reinterpret_cast<LPVOID*>(&CBaseClient__Disconnect));
// patch to disable kicking based on incorrect serverfilter in connectclient, since we repurpose it for use as an auth token
diff --git a/NorthstarDedicatedTest/serverauthentication.h b/NorthstarDedicatedTest/serverauthentication.h
index 3051ea10..4301b78e 100644
--- a/NorthstarDedicatedTest/serverauthentication.h
+++ b/NorthstarDedicatedTest/serverauthentication.h
@@ -19,6 +19,7 @@ public:
public:
void AddPlayerAuth(char* authToken, char* uid, char* pdata, size_t pdataSize);
bool AuthenticatePlayer(void* player, char* authToken);
+ bool RemovePlayerAuthData(void* player);
void WritePersistentData(void* player);
};