aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBobTheBob9 <for.oliver.kirkham@gmail.com>2023-01-08 00:39:43 +0000
committerBobTheBob9 <for.oliver.kirkham@gmail.com>2023-01-08 00:39:43 +0000
commit955eaba6c4481a81b56d96a0cdacf5a3570dc9c3 (patch)
tree582b343a3574fbeebe188906ae7ac844cb85842c
parente9f8a34dc3ca736f307cf195390aee7c8f5cb456 (diff)
parentd4f90eafc91f83cca270e46164f435908dc94b9d (diff)
downloadNorthstarLauncher-955eaba6c4481a81b56d96a0cdacf5a3570dc9c3.tar.gz
NorthstarLauncher-955eaba6c4481a81b56d96a0cdacf5a3570dc9c3.zip
Merge remote-tracking branch 'origin/main' into experimental-bots-pr
-rw-r--r--NorthstarDLL/NorthstarDLL.vcxproj2
-rw-r--r--NorthstarDLL/NorthstarDLL.vcxproj.filters8
-rw-r--r--NorthstarDLL/client/modlocalisation.cpp43
-rw-r--r--NorthstarDLL/scripts/client/clientchathooks.cpp3
-rw-r--r--NorthstarDLL/server/serverchathooks.cpp3
-rw-r--r--NorthstarDLL/squirrel/squirrel.cpp4
-rw-r--r--NorthstarDLL/squirrel/squirreldatatypes.h16
-rw-r--r--NorthstarDLL/util/utils.cpp83
-rw-r--r--NorthstarDLL/util/utils.h6
9 files changed, 149 insertions, 19 deletions
diff --git a/NorthstarDLL/NorthstarDLL.vcxproj b/NorthstarDLL/NorthstarDLL.vcxproj
index dc5a3878..ba26b89b 100644
--- a/NorthstarDLL/NorthstarDLL.vcxproj
+++ b/NorthstarDLL/NorthstarDLL.vcxproj
@@ -446,6 +446,7 @@
<ClInclude Include="squirrel\squirrelautobind.h" />
<ClInclude Include="squirrel\squirrelclasstypes.h" />
<ClInclude Include="squirrel\squirreldatatypes.h" />
+ <ClInclude Include="util\utils.h" />
<ClInclude Include="util\version.h" />
</ItemGroup>
<ItemGroup>
@@ -535,6 +536,7 @@
<ClCompile Include="squirrel\squirrelautobind.cpp" />
<ClCompile Include="util\printcommands.cpp" />
<ClCompile Include="util\printmaps.cpp" />
+ <ClCompile Include="util\utils.cpp" />
<ClCompile Include="util\version.cpp" />
</ItemGroup>
<ItemGroup>
diff --git a/NorthstarDLL/NorthstarDLL.vcxproj.filters b/NorthstarDLL/NorthstarDLL.vcxproj.filters
index 5d964951..4c67cab3 100644
--- a/NorthstarDLL/NorthstarDLL.vcxproj.filters
+++ b/NorthstarDLL/NorthstarDLL.vcxproj.filters
@@ -1173,6 +1173,9 @@
<ClInclude Include="core\macros.h">
<Filter>Header Files\core</Filter>
</ClInclude>
+ <ClInclude Include="util\utils.h">
+ <Filter>Header Files\util</Filter>
+ </ClInclude>
<ClInclude Include="server\bots.h">
<Filter>Header Files\server</Filter>
</ClInclude>
@@ -1415,7 +1418,10 @@
<Filter>Source Files\core</Filter>
</ClCompile>
<ClCompile Include="client\rejectconnectionfixes.cpp">
- <Filter>Source Files\client</Filter>
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="util\utils.cpp">
+ <Filter>Source Files\util</Filter>
</ClCompile>
<ClCompile Include="server\bots.cpp">
<Filter>Source Files\server</Filter>
diff --git a/NorthstarDLL/client/modlocalisation.cpp b/NorthstarDLL/client/modlocalisation.cpp
index 430e3a5f..e5afc793 100644
--- a/NorthstarDLL/client/modlocalisation.cpp
+++ b/NorthstarDLL/client/modlocalisation.cpp
@@ -3,30 +3,51 @@
AUTOHOOK_INIT()
+void* g_pVguiLocalize;
+
// clang-format off
-AUTOHOOK(AddLocalisationFile, localize.dll + 0x6D80,
-bool, __fastcall, (void* pVguiLocalize, const char* path, const char* pathId, char unknown))
+AUTOHOOK(CLocalize__AddFile, localize.dll + 0x6D80,
+bool, __fastcall, (void* pVguiLocalize, const char* path, const char* pathId, bool bIncludeFallbackSearchPaths))
// clang-format on
{
- static bool bLoadModLocalisationFiles = true;
- bool ret = AddLocalisationFile(pVguiLocalize, path, pathId, unknown);
+ // save this for later
+ g_pVguiLocalize = pVguiLocalize;
+ bool ret = CLocalize__AddFile(pVguiLocalize, path, pathId, bIncludeFallbackSearchPaths);
if (ret)
spdlog::info("Loaded localisation file {} successfully", path);
- if (!bLoadModLocalisationFiles)
- return ret;
-
- bLoadModLocalisationFiles = false;
+ return true;
+}
+// clang-format off
+AUTOHOOK(CLocalize__ReloadLocalizationFiles, localize.dll + 0xB830,
+void, __fastcall, (void* pVguiLocalize))
+// clang-format on
+{
+ // load all mod localization manually, so we keep track of all files, not just previously loaded ones
for (Mod mod : g_pModManager->m_LoadedMods)
if (mod.m_bEnabled)
for (std::string& localisationFile : mod.LocalisationFiles)
- AddLocalisationFile(pVguiLocalize, localisationFile.c_str(), pathId, unknown);
+ CLocalize__AddFile(g_pVguiLocalize, localisationFile.c_str(), nullptr, false);
+
+ spdlog::info("reloading localization...");
+ CLocalize__ReloadLocalizationFiles(pVguiLocalize);
+}
- bLoadModLocalisationFiles = true;
+// clang-format off
+AUTOHOOK(CEngineVGui__Init, engine.dll + 0x247E10,
+void, __fastcall, (void* self))
+// clang-format on
+{
+ CEngineVGui__Init(self); // this loads r1_english, valve_english, dev_english
- return ret;
+ // previously we did this in CLocalize::AddFile, but for some reason it won't properly overwrite localization from
+ // files loaded previously if done there, very weird but this works so whatever
+ for (Mod mod : g_pModManager->m_LoadedMods)
+ if (mod.m_bEnabled)
+ for (std::string& localisationFile : mod.LocalisationFiles)
+ CLocalize__AddFile(g_pVguiLocalize, localisationFile.c_str(), nullptr, false);
}
ON_DLL_LOAD_CLIENT("localize.dll", Localize, (CModule module))
diff --git a/NorthstarDLL/scripts/client/clientchathooks.cpp b/NorthstarDLL/scripts/client/clientchathooks.cpp
index 0fc68302..a1a9e503 100644
--- a/NorthstarDLL/scripts/client/clientchathooks.cpp
+++ b/NorthstarDLL/scripts/client/clientchathooks.cpp
@@ -1,5 +1,6 @@
#include "pch.h"
#include "squirrel/squirrel.h"
+#include "util/utils.h"
#include "server/serverchathooks.h"
#include "client/localchatwriter.h"
@@ -30,6 +31,8 @@ void, __fastcall, (void* self, const char* message, int inboxId, bool isTeam, bo
payload = message + 1;
}
+ NS::Utils::RemoveAsciiControlSequences(const_cast<char*>(message), true);
+
SQRESULT result = g_pSquirrel<ScriptContext::CLIENT>->Call(
"CHudChat_ProcessMessageStartThread", static_cast<int>(senderId) - 1, payload, isTeam, isDead, type);
if (result == SQRESULT_ERROR)
diff --git a/NorthstarDLL/server/serverchathooks.cpp b/NorthstarDLL/server/serverchathooks.cpp
index 57c2c31a..0ea3c2d2 100644
--- a/NorthstarDLL/server/serverchathooks.cpp
+++ b/NorthstarDLL/server/serverchathooks.cpp
@@ -3,6 +3,7 @@
#include "shared/exploit_fixes/ns_limits.h"
#include "squirrel/squirrel.h"
#include "server/r2server.h"
+#include "util/utils.h"
#include <rapidjson/document.h>
#include <rapidjson/stringbuffer.h>
@@ -40,6 +41,8 @@ AUTOHOOK(_CServerGameDLL__OnReceivedSayTextMessage, server.dll + 0x1595C0,
void, __fastcall, (CServerGameDLL* self, unsigned int senderPlayerId, const char* text, bool isTeam))
// clang-format on
{
+ NS::Utils::RemoveAsciiControlSequences(const_cast<char*>(text), true);
+
// MiniHook doesn't allow calling the base function outside of anywhere but the hook function.
// To allow bypassing the hook, isSkippingHook can be set.
if (bShouldCallSayTextHook)
diff --git a/NorthstarDLL/squirrel/squirrel.cpp b/NorthstarDLL/squirrel/squirrel.cpp
index 8dd93ed0..4771bf3f 100644
--- a/NorthstarDLL/squirrel/squirrel.cpp
+++ b/NorthstarDLL/squirrel/squirrel.cpp
@@ -283,8 +283,7 @@ template <ScriptContext context> void SquirrelManager<context>::AddFuncOverride(
// hooks
bool IsUIVM(ScriptContext context, HSquirrelVM* pSqvm)
{
- return context != ScriptContext::SERVER && g_pSquirrel<ScriptContext::UI>->m_pSQVM &&
- g_pSquirrel<ScriptContext::UI>->m_pSQVM->sqvm == pSqvm;
+ return ScriptContext(pSqvm->sharedState->cSquirrelVM->vmContext) == ScriptContext::UI;
}
template <ScriptContext context> void* (*__fastcall sq_compiler_create)(HSquirrelVM* sqvm, void* a2, void* a3, SQBool bShouldThrowError);
@@ -376,6 +375,7 @@ void __fastcall ScriptCompileErrorHook(HSquirrelVM* sqvm, const char* error, con
// kill dedicated server if we hit this
if (IsDedicatedServer())
{
+ logger->error("Exiting dedicated server, compile error is fatal");
// flush the logger before we exit so debug things get saved to log file
logger->flush();
exit(EXIT_FAILURE);
diff --git a/NorthstarDLL/squirrel/squirreldatatypes.h b/NorthstarDLL/squirrel/squirreldatatypes.h
index b5025f6b..84ab15ec 100644
--- a/NorthstarDLL/squirrel/squirreldatatypes.h
+++ b/NorthstarDLL/squirrel/squirreldatatypes.h
@@ -19,6 +19,7 @@ struct SQNativeClosure;
struct SQArray;
struct tableNode;
struct SQUserData;
+struct CSquirrelVM;
typedef void (*releasehookType)(void* val, int size);
@@ -395,7 +396,7 @@ struct SQSharedState
SQString* _SpinOffStringValue;
SQObjectType _SpinOffDelayedStringType;
SQString* _SpinOffDelayedStringValue;
- unsigned char gap_43E8[8];
+ CSquirrelVM* cSquirrelVM;
bool enableDebugInfo; // functionality stripped
unsigned char gap_43F1[23];
};
@@ -470,11 +471,16 @@ struct SQCompiler
/* 155 */
struct CSquirrelVM
{
- unsigned char gap_0[8];
+ BYTE gap_0[8];
HSquirrelVM* sqvm;
- unsigned char gap_10[44];
- int loadEnumFromFileMaybe;
- unsigned char gap_40[200];
+ BYTE gap_10[8];
+ SQObject unknownObject_18;
+ __int64 unknown_28;
+ BYTE gap_30[12];
+ __int32 vmContext;
+ BYTE gap_40[648];
+ char* (*formatString)(__int64 a1, const char* format, ...);
+ BYTE gap_2D0[24];
};
struct SQUserData
diff --git a/NorthstarDLL/util/utils.cpp b/NorthstarDLL/util/utils.cpp
new file mode 100644
index 00000000..10c5b26d
--- /dev/null
+++ b/NorthstarDLL/util/utils.cpp
@@ -0,0 +1,83 @@
+#include "pch.h"
+#include <ctype.h>
+#include "utils.h"
+
+bool skip_valid_ansi_csi_sgr(char*& str)
+{
+ if (*str++ != '\x1B')
+ return false;
+ if (*str++ != '[') // CSI
+ return false;
+ for (char* c = str; *c; c++)
+ {
+ if (*c >= '0' && *c <= '9')
+ continue;
+ if (*c == ';' || *c == ':')
+ continue;
+ if (*c == 'm') // SGR
+ break;
+ return false;
+ }
+ return true;
+}
+
+void NS::Utils::RemoveAsciiControlSequences(char* str, bool allow_color_codes)
+{
+ for (char *pc = str, c = *pc; c = *pc; pc++)
+ {
+ // skip UTF-8 characters
+ int bytesToSkip = 0;
+ if ((c & 0xE0) == 0xC0)
+ bytesToSkip = 1; // skip 2-byte UTF-8 sequence
+ if ((c & 0xF0) == 0xE0)
+ bytesToSkip = 2; // skip 3-byte UTF-8 sequence
+ if ((c & 0xF8) == 0xF0)
+ bytesToSkip = 3; // skip 4-byte UTF-8 sequence
+ if ((c & 0xFC) == 0xF8)
+ bytesToSkip = 4; // skip 5-byte UTF-8 sequence
+ if ((c & 0xFE) == 0xFC)
+ bytesToSkip = 5; // skip 6-byte UTF-8 sequence
+
+ bool invalid = false;
+ char* orgpc = pc;
+ for (int i = 0; i < bytesToSkip; i++)
+ {
+ char next = pc[1];
+
+ // valid UTF-8 part
+ if ((next & 0xC0) == 0x80)
+ {
+ pc++;
+ continue;
+ }
+
+ // invalid UTF-8 part or encountered \0
+ invalid = true;
+ break;
+ }
+ if (invalid)
+ {
+ // erase the whole "UTF-8" sequence
+ for (char* x = orgpc; x <= pc; x++)
+ if (*x != '\0')
+ *x = ' ';
+ else
+ break;
+ }
+ if (bytesToSkip > 0)
+ continue; // this byte was already handled as UTF-8
+
+ // an invalid control character or an UTF-8 part outside of UTF-8 sequence
+ if ((iscntrl(c) && c != '\n' && c != '\r' && c != '\x1B') || (c & 0x80) != 0)
+ {
+ *pc = ' ';
+ continue;
+ }
+
+ if (c == '\x1B') // separate handling for this escape sequence...
+ if (allow_color_codes && skip_valid_ansi_csi_sgr(pc)) // ...which we allow for color codes...
+ pc--;
+ else // ...but remove it otherwise
+ *pc = ' ';
+ }
+}
diff --git a/NorthstarDLL/util/utils.h b/NorthstarDLL/util/utils.h
new file mode 100644
index 00000000..97b92f18
--- /dev/null
+++ b/NorthstarDLL/util/utils.h
@@ -0,0 +1,6 @@
+#pragma once
+
+namespace NS::Utils
+{
+ void RemoveAsciiControlSequences(char* str, bool allow_color_codes);
+}