Skip to content

Commit

Permalink
Fix issues of restriction of chat message charset
Browse files Browse the repository at this point in the history
  • Loading branch information
p0358 committed Jan 6, 2023
1 parent 33eb325 commit 21f176c
Show file tree
Hide file tree
Showing 6 changed files with 104 additions and 52 deletions.
2 changes: 2 additions & 0 deletions NorthstarDLL/NorthstarDLL.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -445,6 +445,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>
Expand Down Expand Up @@ -533,6 +534,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>
Expand Down
9 changes: 9 additions & 0 deletions NorthstarDLL/NorthstarDLL.vcxproj.filters
Original file line number Diff line number Diff line change
Expand Up @@ -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>
</ItemGroup>
<ItemGroup>
<None Include="..\include\spdlog\fmt\bundled\LICENSE.rst">
Expand Down Expand Up @@ -1411,6 +1414,12 @@
<ClCompile Include="core\sourceinterface.cpp">
<Filter>Source Files\core</Filter>
</ClCompile>
<ClCompile Include="client\rejectconnectionfixes.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="util\utils.cpp">
<Filter>Source Files\util</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<MASM Include="audio_asm.asm">
Expand Down
28 changes: 2 additions & 26 deletions NorthstarDLL/scripts/client/clientchathooks.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#include "pch.h"
#include "squirrel/squirrel.h"
#include "util/utils.h"

#include "server/serverchathooks.h"
#include "client/localchatwriter.h"
Expand All @@ -8,25 +9,6 @@

AUTOHOOK_INIT()

static char* skip_valid_ansi_csi_sgr(char* str)
{
if (*str++ != '\x1B')
return NULL;
if (*str++ != '[') // CSI
return NULL;
for (char* c = str; *c; c++)
{
if (*c >= '0' && *c <= '9')
continue;
if (*c == ';')
continue;
if (*c == 'm') // SGR
break;
return NULL;
}
return str;
}

// clang-format off
AUTOHOOK(CHudChat__AddGameLine, client.dll + 0x22E580,
void, __fastcall, (void* self, const char* message, int inboxId, bool isTeam, bool isDead))
Expand All @@ -49,13 +31,7 @@ void, __fastcall, (void* self, const char* message, int inboxId, bool isTeam, bo
payload = message + 1;
}

for (char* c = const_cast<char*>(message); *c; c++)
{
if (*c == '\x1B' && (c = skip_valid_ansi_csi_sgr(c)))
c--;
else if (*c <= 9 || (*c >= 12 && *c <= 31))
*c = ' ';
}
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);
Expand Down
28 changes: 2 additions & 26 deletions NorthstarDLL/server/serverchathooks.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand Down Expand Up @@ -34,38 +35,13 @@ void(__fastcall* MessageWriteByte)(int iValue);
void(__fastcall* MessageWriteString)(const char* sz);
void(__fastcall* MessageWriteBool)(bool bValue);

static char* skip_valid_ansi_csi_sgr(char* str)
{
if (*str++ != '\x1B')
return NULL;
if (*str++ != '[') // CSI
return NULL;
for (char* c = str; *c; c++)
{
if (*c >= '0' && *c <= '9')
continue;
if (*c == ';')
continue;
if (*c == 'm') // SGR
break;
return NULL;
}
return str;
}

bool bShouldCallSayTextHook = false;
// clang-format off
AUTOHOOK(_CServerGameDLL__OnReceivedSayTextMessage, server.dll + 0x1595C0,
void, __fastcall, (CServerGameDLL* self, unsigned int senderPlayerId, const char* text, bool isTeam))
// clang-format on
{
for (char* c = const_cast<char*>(text); *c; c++)
{
if (*c == '\x1B' && (c = skip_valid_ansi_csi_sgr(c)))
c--;
else if (*c <= 9 || (*c >= 12 && *c <= 31))
*c = ' ';
}
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.
Expand Down
83 changes: 83 additions & 0 deletions NorthstarDLL/util/utils.cpp
Original file line number Diff line number Diff line change
@@ -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 = ' ';
}
}
6 changes: 6 additions & 0 deletions NorthstarDLL/util/utils.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#pragma once

namespace NS::Utils
{
void RemoveAsciiControlSequences(char* str, bool allow_color_codes);
}

0 comments on commit 21f176c

Please sign in to comment.