From 9eb3f36a6a46312cce8f47fe1ad4a50969314d91 Mon Sep 17 00:00:00 2001 From: Hyper <34012267+hyperbx@users.noreply.github.com> Date: Thu, 4 Jun 2026 13:20:02 +0100 Subject: [PATCH 1/9] [Sonic Forces] Always Run in the Background --- .../System/Always Run in the Background.hmm | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 Source/Sonic Forces/System/Always Run in the Background.hmm diff --git a/Source/Sonic Forces/System/Always Run in the Background.hmm b/Source/Sonic Forces/System/Always Run in the Background.hmm new file mode 100644 index 00000000..459b470e --- /dev/null +++ b/Source/Sonic Forces/System/Always Run in the Background.hmm @@ -0,0 +1,12 @@ +Patch "Always Run in the Background" in "System" by "Hyper" does +/* +Stops the game from pausing when the window is unfocused. + +Known issues: +- The main menu and world map will continue to mute when unfocused. +- The credits will continue to pause when unfocused. +*/ +{ + WriteProtected(0x14014E659, 0x74, 0x21); + WriteProtected(0x140108C3E, 0xEB); +} From b04586600c65eeec2b7630b4af5e2f0b71303993 Mon Sep 17 00:00:00 2001 From: Hyper <34012267+hyperbx@users.noreply.github.com> Date: Thu, 4 Jun 2026 18:57:30 +0100 Subject: [PATCH 2/9] [Sonic Forces] Allow Background Input --- Source/Sonic Forces/System/Allow Background Input.hmm | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 Source/Sonic Forces/System/Allow Background Input.hmm diff --git a/Source/Sonic Forces/System/Allow Background Input.hmm b/Source/Sonic Forces/System/Allow Background Input.hmm new file mode 100644 index 00000000..44c94d39 --- /dev/null +++ b/Source/Sonic Forces/System/Allow Background Input.hmm @@ -0,0 +1,3 @@ +Patch "Allow Background Input" in "System" by "Hyper" does "Allows the controller to be used when the window is unfocused." +WriteNop(0x1406BF74E, 6); +WriteNop(0x1458FB11E, 6); From 789f3f5fbe8099518c09a6d28324aa83e62bb60a Mon Sep 17 00:00:00 2001 From: Hyper <34012267+hyperbx@users.noreply.github.com> Date: Mon, 29 Jun 2026 17:57:08 +0100 Subject: [PATCH 3/9] [Sonic Frontiers] Converse: fix use-after-free and memory leak --- Source/Sonic Frontiers/Libraries/Converse.hmm | 185 ++++++++++-------- 1 file changed, 108 insertions(+), 77 deletions(-) diff --git a/Source/Sonic Frontiers/Libraries/Converse.hmm b/Source/Sonic Frontiers/Libraries/Converse.hmm index 91a91f9b..e6744fc6 100644 --- a/Source/Sonic Frontiers/Libraries/Converse.hmm +++ b/Source/Sonic Frontiers/Libraries/Converse.hmm @@ -81,20 +81,27 @@ Library "Converse" by "Hyper & M&M" UNMANAGED_FUNCTION(long, RedirectString, long in_pCnvrsKey, long in_pCnvrsText, int in_cnvrsTextLength) { - if (in_pCnvrsKey == 0) - return in_pCnvrsText; + var result = (nint)0; + var length = 0; - string cnvrsKey = Marshal.PtrToStringAnsi((IntPtr)in_pCnvrsKey); - string cnvrsText = in_pCnvrsText == 0 ? string.Empty : Marshal.PtrToStringUni((IntPtr)in_pCnvrsText, in_cnvrsTextLength); - nint pData = 0; + var cnvrsKey = in_pCnvrsKey == 0 + ? string.Empty + : Marshal.PtrToStringAnsi((nint)in_pCnvrsKey); + + var cnvrsText = string.Empty; + + if (in_pCnvrsText != 0 && in_cnvrsTextLength > 0) + cnvrsText = Marshal.PtrToStringUni((nint)in_pCnvrsText, in_cnvrsTextLength); void MarshalString(string in_str) { - int length = sizeof(int) + ((in_str.Length + 1) * sizeof(short)); - - pData = Marshal.AllocHGlobal(length); + if (result != 0) + Marshal.FreeHGlobal(result); + + length = in_str.Length; + result = Marshal.AllocHGlobal(sizeof(int) + ((length + 1) * sizeof(short))); - var wideTextStart = pData + sizeof(int); + var wideTextStart = result + sizeof(int); var wideText = Encoding.Unicode.GetBytes(in_str); var wideTextEnd = wideTextStart + wideText.Length; @@ -102,74 +109,78 @@ Library "Converse" by "Hyper & M&M" // Null terminator. Marshal.WriteInt16(wideTextEnd, 0); - - in_pCnvrsText = (long)pData; - in_cnvrsTextLength = length; } - string redirectResult = cnvrsText; + if (!string.IsNullOrEmpty(cnvrsKey)) { - foreach (var entry in _redirectedStrings) + var redirectResult = cnvrsText; { - if (entry.Key == cnvrsKey) + foreach (var entry in _redirectedStrings) { + if (entry.Key != cnvrsKey) + continue; + redirectResult = entry.IsRawAttributes ? entry.Value : WriteAttributes(entry.Value); } - } - if (redirectResult != cnvrsText) - MarshalString(redirectResult); - } + if (redirectResult != cnvrsText) + MarshalString(redirectResult); + } - string notifyResult = redirectResult; - { - foreach (var entry in _converseNotifyActions) + var notifyResult = redirectResult; { - notifyResult = entry.Key(cnvrsKey, notifyResult, ReadAttributes(notifyResult)); + foreach (var entry in _converseNotifyActions) + { + notifyResult = entry.Key(cnvrsKey, notifyResult, ReadAttributes(notifyResult)); - if (!entry.Value) - notifyResult = WriteAttributes(notifyResult); - } + if (!entry.Value) + notifyResult = WriteAttributes(notifyResult); + } - if (notifyResult != cnvrsText) - MarshalString(notifyResult); - } + if (notifyResult != cnvrsText) + MarshalString(notifyResult); + } - foreach (var entry in _replacementStrings) - { - string replacementResult = entry.IsRawAttributes - ? notifyResult - : ReadAttributes(notifyResult); + foreach (var entry in _replacementStrings) + { + var replacementResult = entry.IsRawAttributes + ? notifyResult + : ReadAttributes(notifyResult); - // Perform replacement operation. - replacementResult = entry.IsRegex - ? new Regex(entry.Pattern).Replace(replacementResult, entry.Replacement) - : replacementResult.Replace(entry.Pattern, entry.Replacement); + // Perform replacement operation. + replacementResult = entry.IsRegex + ? new Regex(entry.Pattern).Replace(replacementResult, entry.Replacement) + : replacementResult.Replace(entry.Pattern, entry.Replacement); - replacementResult = entry.IsRawAttributes - ? replacementResult - : WriteAttributes(replacementResult); + replacementResult = entry.IsRawAttributes + ? replacementResult + : WriteAttributes(replacementResult); - if (replacementResult != cnvrsText) - MarshalString(replacementResult); + if (replacementResult != cnvrsText) + MarshalString(replacementResult); + } } - if (pData != 0) - { - // Wide string length. - Marshal.WriteInt32(pData, in_cnvrsTextLength); - Marshal.FreeHGlobal(pData); - } - else if (in_pCnvrsText != 0) + // Handle null strings. + if (result == 0 && (in_pCnvrsKey == 0 || in_pCnvrsText == 0 || in_cnvrsTextLength <= 0)) + MarshalString(" "); + + if (result != 0) { - /* No need to reallocate all strings, - return -1 and reload original pointer. */ - in_pCnvrsText = -1; + // String character length. + Marshal.WriteInt32(result, length); + + return result; } - return in_pCnvrsText; + return -1L; + } + + UNMANAGED_FUNCTION(void, FreeString, long in_pCnvrsText) + { + Marshal.FreeHGlobal((nint)in_pCnvrsText); } [LibraryInitializer] @@ -183,28 +194,48 @@ Library "Converse" by "Hyper & M&M" WriteAsmHook ( $@" - mov r8d, dword ptr [rsp + 0x1C8 + 0xFFFFFFFFFFFFFE60] - mov rcx, rsi + mov r8d, dword ptr [rsp + 0x28] ; Converse Text Length + mov rdx, qword ptr [rsp + 0x20] ; Converse Text + mov rcx, rsi ; Converse Key mov rax, {GET_UNMANAGED_FUNCTION_PTR(RedirectString)} call rax - cmp rax, 0 - jne notNull - mov rdx, {TO_WSTRING_PTR(" ")} - mov r8d, 1 - jmp exit - notNull: - cmp rax, -1 - je notCustom - lea rdx, qword ptr [rax + 4] - mov r8d, dword ptr [rax] - jmp exit - notCustom: - mov rdx, qword ptr [rsp + 0x1C8 + 0xFFFFFFFFFFFFFE58] - mov r8d, dword ptr [rsp + 0x1C8 + 0xFFFFFFFFFFFFFE60] - exit: - mov rcx, qword ptr [rdi + 8] + mov rbx, rax ; Preserve result in RBX. + + ; Check if result is -1 or null, use original string if so. + cmp rbx, -1 + je original + test rbx, rbx + jz original + + mov r8d, dword ptr [rbx] ; Redirected Text Length + lea rdx, qword ptr [rbx + 0x04] ; Redirected Text + jmp cnvrs + + original: + mov r8d, dword ptr [rsp + 0x28] ; Converse Text Length + mov rdx, qword ptr [rsp + 0x20] ; Converse Text + + cnvrs: + mov rcx, qword ptr [rdi + 0x08] ; Allocator + push rbx mov rax, {Memory.ReadCall(in_addr + 0x09)} call rax + pop rbx + + ; Check if redirect result is -1, skip free if so. + cmp rbx, -1 + je exit + + ; Free redirected string. + mov r12, rax + mov rcx, rbx + sub rsp, 32 + mov rax, {GET_UNMANAGED_FUNCTION_PTR(FreeString)} + call rax + add rsp, 32 + mov rax, r12 ; Restore original result. + + exit: ", in_addr, @@ -215,10 +246,10 @@ Library "Converse" by "Hyper & M&M" WriteNop ( - /* v1.41: 0x14DA978CD */ + /* v1.42: 0x14D89049D */ ScanSignature ( - "\x0F\x84\xE8\x00\x00\x00\x48\x8D\x8F\xC8\x00\x00\x00", + "\x0F\x84\xF7\x00\x00\x00\x48\x8D\x8F\xC8\x00\x00\x00", "xxxxxxxxxxxxx" ), @@ -227,7 +258,7 @@ Library "Converse" by "Hyper & M&M" ConverseHook ( - /* 0x14DC858D3 */ + /* v1.42: 0x14D8904D1 */ ScanSignature ( "\x44\x8B\x44\x24\x28\x48\x8B\x4F\x08\xE8\xCC\xCC\xCC\xCC\x48\x89\xC2\x48\x8B\x8F\xF0\x00\x00\x00", @@ -249,7 +280,7 @@ Library "Converse" by "Hyper & M&M" ConverseHook ( - /* 0x14DC8593A */ + /* v1.42: 0x14D89053C */ ScanSignature ( "\x44\x8B\x44\x24\x28\x48\x8B\x4F\x08\xE8\xCC\xCC\xCC\xCC\x48\x89\xC2\x48\x89\xF9", @@ -259,7 +290,7 @@ Library "Converse" by "Hyper & M&M" fixed (sbyte* p_language = &_language) { - /* 0x140AFA200 */ + /* v1.42: 0x146E3A1CC */ var sig = Memory.ReadCall ( ScanSignature From 021ae877f18f1a238ebe5b0a09b58defdabb14d3 Mon Sep 17 00:00:00 2001 From: Hyper <34012267+hyperbx@users.noreply.github.com> Date: Mon, 29 Jun 2026 18:13:41 +0100 Subject: [PATCH 4/9] Update author name --- Source/Sonic Frontiers/Libraries/Converse.hmm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/Sonic Frontiers/Libraries/Converse.hmm b/Source/Sonic Frontiers/Libraries/Converse.hmm index e6744fc6..c37fb0fc 100644 --- a/Source/Sonic Frontiers/Libraries/Converse.hmm +++ b/Source/Sonic Frontiers/Libraries/Converse.hmm @@ -1,4 +1,4 @@ -Library "Converse" by "Hyper & M&M" +Library "Converse" by "Hyper & RagdollClash" { #include "Helpers" noemit From dc286b78c218b96a4198dc0bdd0ad039563aef01 Mon Sep 17 00:00:00 2001 From: Hyper <34012267+hyperbx@users.noreply.github.com> Date: Mon, 29 Jun 2026 22:38:39 +0100 Subject: [PATCH 5/9] [Sonic Frontiers] Converse: remove null terminator from redirected string The game copies the string using a fixed length, rather than using a terminator. --- Source/Sonic Frontiers/Libraries/Converse.hmm | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/Source/Sonic Frontiers/Libraries/Converse.hmm b/Source/Sonic Frontiers/Libraries/Converse.hmm index c37fb0fc..b4519cd6 100644 --- a/Source/Sonic Frontiers/Libraries/Converse.hmm +++ b/Source/Sonic Frontiers/Libraries/Converse.hmm @@ -83,13 +83,13 @@ Library "Converse" by "Hyper & RagdollClash" { var result = (nint)0; var length = 0; - - var cnvrsKey = in_pCnvrsKey == 0 - ? string.Empty - : Marshal.PtrToStringAnsi((nint)in_pCnvrsKey); + var cnvrsKey = string.Empty; var cnvrsText = string.Empty; + if (in_pCnvrsKey != 0) + cnvrsKey = Marshal.PtrToStringAnsi((nint)in_pCnvrsKey); + if (in_pCnvrsText != 0 && in_cnvrsTextLength > 0) cnvrsText = Marshal.PtrToStringUni((nint)in_pCnvrsText, in_cnvrsTextLength); @@ -99,16 +99,13 @@ Library "Converse" by "Hyper & RagdollClash" Marshal.FreeHGlobal(result); length = in_str.Length; - result = Marshal.AllocHGlobal(sizeof(int) + ((length + 1) * sizeof(short))); + result = Marshal.AllocHGlobal(sizeof(int) + (length * sizeof(short))); - var wideTextStart = result + sizeof(int); + var wideTextStart = sizeof(int) + result; var wideText = Encoding.Unicode.GetBytes(in_str); var wideTextEnd = wideTextStart + wideText.Length; Marshal.Copy(wideText, 0, wideTextStart, wideText.Length); - - // Null terminator. - Marshal.WriteInt16(wideTextEnd, 0); } if (!string.IsNullOrEmpty(cnvrsKey)) From 7a384b9d9aebea7643866da0aa11b2f6853cf34d Mon Sep 17 00:00:00 2001 From: Hyper <34012267+hyperbx@users.noreply.github.com> Date: Mon, 29 Jun 2026 22:39:17 +0100 Subject: [PATCH 6/9] [Sonic Frontiers] Converse: fix register corruption --- Source/Sonic Frontiers/Libraries/Converse.hmm | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Source/Sonic Frontiers/Libraries/Converse.hmm b/Source/Sonic Frontiers/Libraries/Converse.hmm index b4519cd6..9826b4ae 100644 --- a/Source/Sonic Frontiers/Libraries/Converse.hmm +++ b/Source/Sonic Frontiers/Libraries/Converse.hmm @@ -166,7 +166,7 @@ Library "Converse" by "Hyper & RagdollClash" if (result != 0) { - // String character length. + // Text character length. Marshal.WriteInt32(result, length); return result; @@ -224,13 +224,13 @@ Library "Converse" by "Hyper & RagdollClash" je exit ; Free redirected string. - mov r12, rax mov rcx, rbx + mov rbx, rax sub rsp, 32 mov rax, {GET_UNMANAGED_FUNCTION_PTR(FreeString)} call rax add rsp, 32 - mov rax, r12 ; Restore original result. + mov rax, rbx ; Restore original result. exit: ", From 416f1e6472e618faabe6c2403ba85fe0c2429c40 Mon Sep 17 00:00:00 2001 From: Hyper <34012267+hyperbx@users.noreply.github.com> Date: Mon, 29 Jun 2026 23:02:12 +0100 Subject: [PATCH 7/9] [Sonic Frontiers] Converse: optimise string allocations --- Source/Sonic Frontiers/Libraries/Converse.hmm | 30 +++++++------------ 1 file changed, 11 insertions(+), 19 deletions(-) diff --git a/Source/Sonic Frontiers/Libraries/Converse.hmm b/Source/Sonic Frontiers/Libraries/Converse.hmm index 9826b4ae..bd9cebf0 100644 --- a/Source/Sonic Frontiers/Libraries/Converse.hmm +++ b/Source/Sonic Frontiers/Libraries/Converse.hmm @@ -95,17 +95,17 @@ Library "Converse" by "Hyper & RagdollClash" void MarshalString(string in_str) { - if (result != 0) - Marshal.FreeHGlobal(result); - - length = in_str.Length; - result = Marshal.AllocHGlobal(sizeof(int) + (length * sizeof(short))); - - var wideTextStart = sizeof(int) + result; - var wideText = Encoding.Unicode.GetBytes(in_str); - var wideTextEnd = wideTextStart + wideText.Length; + if (in_str.Length > length) + { + if (result != 0) + Marshal.FreeHGlobal(result); + + length = in_str.Length; + result = Marshal.AllocHGlobal(sizeof(int) + (length * sizeof(char))); + } - Marshal.Copy(wideText, 0, wideTextStart, wideText.Length); + Marshal.WriteInt32(result, length); + Marshal.Copy(in_str.ToCharArray(), 0, result + sizeof(int), length); } if (!string.IsNullOrEmpty(cnvrsKey)) @@ -164,15 +164,7 @@ Library "Converse" by "Hyper & RagdollClash" if (result == 0 && (in_pCnvrsKey == 0 || in_pCnvrsText == 0 || in_cnvrsTextLength <= 0)) MarshalString(" "); - if (result != 0) - { - // Text character length. - Marshal.WriteInt32(result, length); - - return result; - } - - return -1L; + return result != 0 ? result : -1L; } UNMANAGED_FUNCTION(void, FreeString, long in_pCnvrsText) From 020df044a4edfa4381cc05e7a2d98f7bf49d486a Mon Sep 17 00:00:00 2001 From: Hyper <34012267+hyperbx@users.noreply.github.com> Date: Tue, 30 Jun 2026 21:49:17 +0100 Subject: [PATCH 8/9] [Sonic Frontiers] Converse: improved string redirection code --- Source/Sonic Frontiers/Libraries/Converse.hmm | 108 ++++++++---------- 1 file changed, 46 insertions(+), 62 deletions(-) diff --git a/Source/Sonic Frontiers/Libraries/Converse.hmm b/Source/Sonic Frontiers/Libraries/Converse.hmm index bd9cebf0..05332201 100644 --- a/Source/Sonic Frontiers/Libraries/Converse.hmm +++ b/Source/Sonic Frontiers/Libraries/Converse.hmm @@ -81,9 +81,7 @@ Library "Converse" by "Hyper & RagdollClash" UNMANAGED_FUNCTION(long, RedirectString, long in_pCnvrsKey, long in_pCnvrsText, int in_cnvrsTextLength) { - var result = (nint)0; - var length = 0; - + var result = string.Empty; var cnvrsKey = string.Empty; var cnvrsText = string.Empty; @@ -91,80 +89,60 @@ Library "Converse" by "Hyper & RagdollClash" cnvrsKey = Marshal.PtrToStringAnsi((nint)in_pCnvrsKey); if (in_pCnvrsText != 0 && in_cnvrsTextLength > 0) - cnvrsText = Marshal.PtrToStringUni((nint)in_pCnvrsText, in_cnvrsTextLength); - - void MarshalString(string in_str) + result = cnvrsText = Marshal.PtrToStringUni((nint)in_pCnvrsText, in_cnvrsTextLength); + + foreach (var entry in _redirectedStrings) { - if (in_str.Length > length) - { - if (result != 0) - Marshal.FreeHGlobal(result); - - length = in_str.Length; - result = Marshal.AllocHGlobal(sizeof(int) + (length * sizeof(char))); - } + if (entry.Key != cnvrsKey) + continue; - Marshal.WriteInt32(result, length); - Marshal.Copy(in_str.ToCharArray(), 0, result + sizeof(int), length); + result = entry.IsRawAttributes + ? entry.Value + : WriteAttributes(entry.Value); } - if (!string.IsNullOrEmpty(cnvrsKey)) + foreach (var entry in _converseNotifyActions) { - var redirectResult = cnvrsText; - { - foreach (var entry in _redirectedStrings) - { - if (entry.Key != cnvrsKey) - continue; - - redirectResult = entry.IsRawAttributes - ? entry.Value - : WriteAttributes(entry.Value); - } + result = entry.Key(cnvrsKey, result, ReadAttributes(result)); - if (redirectResult != cnvrsText) - MarshalString(redirectResult); - } + if (!entry.Value) + result = WriteAttributes(result); + } - var notifyResult = redirectResult; + foreach (var entry in _replacementStrings) + { + var text = entry.IsRawAttributes + ? result + : ReadAttributes(result); + + if (!string.IsNullOrEmpty(text)) { - foreach (var entry in _converseNotifyActions) - { - notifyResult = entry.Key(cnvrsKey, notifyResult, ReadAttributes(notifyResult)); - - if (!entry.Value) - notifyResult = WriteAttributes(notifyResult); - } - - if (notifyResult != cnvrsText) - MarshalString(notifyResult); + text = entry.IsRegex + ? new Regex(entry.Pattern).Replace(text, entry.Replacement) + : text.Replace(entry.Pattern, entry.Replacement); } - foreach (var entry in _replacementStrings) - { - var replacementResult = entry.IsRawAttributes - ? notifyResult - : ReadAttributes(notifyResult); + result = entry.IsRawAttributes + ? text + : WriteAttributes(text); + } - // Perform replacement operation. - replacementResult = entry.IsRegex - ? new Regex(entry.Pattern).Replace(replacementResult, entry.Replacement) - : replacementResult.Replace(entry.Pattern, entry.Replacement); + // Fallback for null strings. + if (string.IsNullOrEmpty(result)) + result = " "; - replacementResult = entry.IsRawAttributes - ? replacementResult - : WriteAttributes(replacementResult); + if (result != cnvrsText) + { + var length = result.Length; + var buffer = Marshal.AllocHGlobal(sizeof(int) + (length * sizeof(char))); - if (replacementResult != cnvrsText) - MarshalString(replacementResult); - } - } + Marshal.WriteInt32(buffer, length); + Marshal.Copy(result.ToCharArray(), 0, buffer + sizeof(int), length); - // Handle null strings. - if (result == 0 && (in_pCnvrsKey == 0 || in_pCnvrsText == 0 || in_cnvrsTextLength <= 0)) - MarshalString(" "); + return (long)buffer; + } - return result != 0 ? result : -1L; + return -1L; } UNMANAGED_FUNCTION(void, FreeString, long in_pCnvrsText) @@ -388,6 +366,9 @@ Library "Converse" by "Hyper & RagdollClash" /// The input string where known binary Converse attributes are replaced with XML keys. public string ReadAttributes(string in_text) { + if (string.IsNullOrEmpty(in_text)) + return in_text; + var result = new StringBuilder(); var chars = Encoding.Unicode.GetChars(Encoding.Unicode.GetBytes(in_text)); @@ -467,6 +448,9 @@ Library "Converse" by "Hyper & RagdollClash" /// The input string where XML Converse attributes are replaced with known binary attributes. public string WriteAttributes(string in_text, XElement in_element = null) { + if (string.IsNullOrEmpty(in_text)) + return in_text; + var result = new StringBuilder(); var root = in_element ?? XElement.Parse($"{in_text}"); From 1d57a8f14c042adf034438128ec7c2c0660e5527 Mon Sep 17 00:00:00 2001 From: Hyper <34012267+hyperbx@users.noreply.github.com> Date: Wed, 1 Jul 2026 09:20:24 +0100 Subject: [PATCH 9/9] Quick fixes Co-authored-by: Sajid --- Source/Sonic Frontiers/Libraries/Converse.hmm | 40 ++++++++++--------- 1 file changed, 21 insertions(+), 19 deletions(-) diff --git a/Source/Sonic Frontiers/Libraries/Converse.hmm b/Source/Sonic Frontiers/Libraries/Converse.hmm index 05332201..1446cdc9 100644 --- a/Source/Sonic Frontiers/Libraries/Converse.hmm +++ b/Source/Sonic Frontiers/Libraries/Converse.hmm @@ -115,12 +115,12 @@ Library "Converse" by "Hyper & RagdollClash" ? result : ReadAttributes(result); - if (!string.IsNullOrEmpty(text)) - { - text = entry.IsRegex - ? new Regex(entry.Pattern).Replace(text, entry.Replacement) - : text.Replace(entry.Pattern, entry.Replacement); - } + if (string.IsNullOrEmpty(text)) + break; + + text = entry.IsRegex + ? new Regex(entry.Pattern).Replace(text, entry.Replacement) + : text.Replace(entry.Pattern, entry.Replacement); result = entry.IsRawAttributes ? text @@ -155,7 +155,7 @@ Library "Converse" by "Hyper & RagdollClash" { if (_isInitialised) return; - + void ConverseHook(long in_addr) { WriteAsmHook @@ -368,13 +368,12 @@ Library "Converse" by "Hyper & RagdollClash" { if (string.IsNullOrEmpty(in_text)) return in_text; - + var result = new StringBuilder(); - var chars = Encoding.Unicode.GetChars(Encoding.Unicode.GetBytes(in_text)); - for (int i = 0; i < chars.Length; i++) + for (int i = 0; i < in_text.Length; i++) { - var c = chars[i]; + var c = in_text[i]; switch ((AttributeType)(c & 0xF00F)) { @@ -386,15 +385,15 @@ Library "Converse" by "Hyper & RagdollClash" result.Append(""); break; } - + i++; var nameLength = GetNameLength(c) - 2; - var argb = (uint)(chars[i] << 16 | (chars[i + 1])); + var argb = (uint)(in_text[i] << 16 | (in_text[i + 1])); i += 2; - var name = new string(chars, i, nameLength); + var name = in_text.Substring(i, nameLength); result.Append($""); @@ -402,13 +401,13 @@ Library "Converse" by "Hyper & RagdollClash" break; } - + case AttributeType.Variable: { i++; var nameLength = GetNameLength(c); - var name = new string(chars, i, nameLength); + var name = in_text.Substring(i, nameLength); result.Append($""); @@ -416,13 +415,13 @@ Library "Converse" by "Hyper & RagdollClash" break; } - + case AttributeType.Image: { i++; var nameLength = GetNameLength(c); - var name = new string(chars, i, nameLength); + var name = in_text.Substring(i, nameLength); result.Append($""); @@ -535,7 +534,7 @@ Library "Converse" by "Hyper & RagdollClash" public string OmitAttributes(string in_text) { var result = new StringBuilder(); - var chars = Encoding.Unicode.GetChars(Encoding.Unicode.GetBytes(in_text)); + var chars = in_text.ToCharArray(); for (int i = 0; i < chars.Length; i++) { @@ -605,6 +604,7 @@ Library "Converse" by "Hyper & RagdollClash" if (first != null) { first.Value = in_text; + first.IsRawAttributes = in_isRawAttributes; return; } @@ -628,6 +628,8 @@ Library "Converse" by "Hyper & RagdollClash" if (first != null) { first.Replacement = in_replacement; + first.IsRegex = in_isRegex; + first.IsRawAttributes = in_isRawAttributes; return; }