99#include < atomic>
1010#include < mutex>
1111#include < share.h>
12+ #include < cstdarg>
1213
1314char g_gameDir[MAX_PATH] = {};
1415FILE* gLogFile = nullptr ;
@@ -75,55 +76,91 @@ __int64 __fastcall InitialFileCheck(__int64 a1, const char* a2, unsigned int a3,
7576 if (!a2)
7677 return oInitialFileCheck (a1, a2, a3, a4, a5);
7778
79+ size_t len = strlen (a2);
80+ if (len >= 4 && _stricmp (a2 + len - 4 , " .pac" ) == 0 )
81+ return oInitialFileCheck (a1, a2, a3, a4, a5);
82+
7883 static thread_local char safeFullPath[MAX_PATH];
7984 static thread_local char localizedPath[MAX_PATH];
8085 const char * finalPath = a2;
8186
87+ size_t gameDirLen = 0 ;
88+ bool gameDirHasSlash = false ;
89+ if (g_gameDir[0 ]) {
90+ gameDirLen = strnlen_s (g_gameDir, MAX_PATH);
91+ if (gameDirLen > 0 ) {
92+ char last = g_gameDir[gameDirLen - 1 ];
93+ gameDirHasSlash = (last == ' \\ ' || last == ' /' );
94+ }
95+ }
96+
97+ auto normalize_to_backslashes = [](char * s) {
98+ for (; *s; ++s) if (*s == ' /' ) *s = ' \\ ' ;
99+ };
100+
101+ bool hasLocaleSuffix = false ;
102+
82103 if (oLocaleHandler && g_localeMgr)
83104 {
84- memset (localizedPath, 0 , sizeof (localizedPath));
85-
105+ localizedPath[0 ] = ' \0 ' ;
86106 oLocaleHandler (g_localeMgr, localizedPath, (unsigned __int16*)&a5, (char *)a2, 0 );
87107
88108 if (localizedPath[0 ])
89109 {
90- std::string src (a2);
91- std::string dest (localizedPath);
92- for (char & c : src) if (c == ' \\ ' ) c = ' /' ;
93- for (char & c : dest) if (c == ' \\ ' ) c = ' /' ;
94-
95- size_t slashSrc = src.find (' /' );
96- size_t slashDest = dest.find (' /' );
97- if (slashSrc != std::string::npos && slashDest != std::string::npos)
110+ char srcNorm[MAX_PATH];
111+ char destNorm[MAX_PATH];
112+ strncpy_s (srcNorm, sizeof (srcNorm), a2, _TRUNCATE);
113+ strncpy_s (destNorm, sizeof (destNorm), localizedPath, _TRUNCATE);
114+
115+ for (char * p = srcNorm; *p; ++p) if (*p == ' \\ ' ) *p = ' /' ;
116+ for (char * p = destNorm; *p; ++p) if (*p == ' \\ ' ) *p = ' /' ;
117+
118+ const char * slashSrc = strchr (srcNorm, ' /' );
119+ const char * slashDest = strchr (destNorm, ' /' );
120+
121+ if (slashSrc && slashDest)
98122 {
99- std::string srcDir = src.substr (0 , slashSrc);
100- std::string destDir = dest.substr (0 , slashDest);
101- if (destDir.rfind (srcDir, 0 ) == 0 && destDir.length () > srcDir.length ())
102- {
103- std::string currentSuffix = destDir.substr (srcDir.length ());
123+ size_t srcDirLen = (size_t )(slashSrc - srcNorm);
124+ size_t destDirLen = (size_t )(slashDest - destNorm);
125+ if (destDirLen > srcDirLen && strncmp (destNorm, srcNorm, srcDirLen) == 0 ) {
126+ size_t suffixLen = destDirLen - srcDirLen;
127+ if (suffixLen < MAX_PATH) {
128+ char currentSuffix[MAX_PATH] = {};
129+ strncpy_s (currentSuffix, sizeof (currentSuffix), destNorm + srcDirLen, suffixLen);
130+ if (strlen (currentSuffix) > 0 ) {
131+ std::lock_guard<std::mutex> lock (g_localeMutex);
132+ g_localeSuffix = currentSuffix;
133+ hasLocaleSuffix = true ;
134+ Log (" [MOD] >>> Detected locale suffix: '%s'" , currentSuffix);
135+ }
136+ }
104137 }
105138 }
106139
107- char fullPath[MAX_PATH];
108- snprintf (fullPath, MAX_PATH, " %s%s%s" ,
109- g_gameDir,
110- (g_gameDir[strlen (g_gameDir) - 1 ] == ' \\ ' || g_gameDir[strlen (g_gameDir) - 1 ] == ' /' ) ? " " : " \\ " ,
111- localizedPath);
140+ if (hasLocaleSuffix)
141+ {
142+ char fullPath[MAX_PATH];
143+ if (gameDirLen && gameDirHasSlash)
144+ snprintf (fullPath, sizeof (fullPath), " %s%s" , g_gameDir, localizedPath);
145+ else if (gameDirLen)
146+ snprintf (fullPath, sizeof (fullPath), " %s\\ %s" , g_gameDir, localizedPath);
147+ else
148+ snprintf (fullPath, sizeof (fullPath), " %s" , localizedPath);
112149
113- for (char * p = fullPath; *p; ++p)
114- if (*p == ' /' ) *p = ' \\ ' ;
150+ normalize_to_backslashes (fullPath);
115151
116- Log (" [MOD] Checking localized loose file: '%s'" , fullPath);
152+ Log (" [MOD] Checking localized loose file: '%s'" , fullPath);
117153
118- if (FileExistsOnDisk (fullPath))
119- {
120- Log (" [MOD] Found localized loose file! Using '%s'" , fullPath);
121- strncpy_s (safeFullPath, fullPath, sizeof (safeFullPath) - 1 );
122- finalPath = safeFullPath;
123- }
124- else
125- {
126- return oInitialFileCheck (a1, localizedPath, a3, a4, a5);
154+ if (FileExistsOnDisk (fullPath))
155+ {
156+ Log (" [MOD] Found localized loose file! Using '%s'" , fullPath);
157+ strncpy_s (safeFullPath, sizeof (safeFullPath), fullPath, _TRUNCATE);
158+ finalPath = safeFullPath;
159+ }
160+ else
161+ {
162+ finalPath = localizedPath;
163+ }
127164 }
128165 }
129166 else
@@ -135,20 +172,21 @@ __int64 __fastcall InitialFileCheck(__int64 a1, const char* a2, unsigned int a3,
135172 if (finalPath == a2)
136173 {
137174 char fullPathToCheck[MAX_PATH];
138- snprintf (fullPathToCheck, MAX_PATH, " %s%s%s" ,
139- g_gameDir,
140- (g_gameDir[strlen (g_gameDir) - 1 ] == ' \\ ' || g_gameDir[strlen (g_gameDir) - 1 ] == ' /' ) ? " " : " \\ " ,
141- a2);
175+ if (gameDirLen && gameDirHasSlash)
176+ snprintf (fullPathToCheck, sizeof (fullPathToCheck), " %s%s" , g_gameDir, a2);
177+ else if (gameDirLen)
178+ snprintf (fullPathToCheck, sizeof (fullPathToCheck), " %s\\ %s" , g_gameDir, a2);
179+ else
180+ snprintf (fullPathToCheck, sizeof (fullPathToCheck), " %s" , a2);
142181
143- for (char * p = fullPathToCheck; *p; ++p)
144- if (*p == ' /' ) *p = ' \\ ' ;
182+ normalize_to_backslashes (fullPathToCheck);
145183
146184 Log (" [MOD] Checking standard loose file: '%s'" , fullPathToCheck);
147185
148186 if (FileExistsOnDisk (fullPathToCheck))
149187 {
150188 Log (" [MOD] Standard loose file found: '%s'" , fullPathToCheck);
151- strncpy_s (safeFullPath, fullPathToCheck, sizeof (safeFullPath) - 1 );
189+ strncpy_s (safeFullPath, sizeof (safeFullPath), fullPathToCheck, _TRUNCATE );
152190 finalPath = safeFullPath;
153191 }
154192 }
@@ -157,6 +195,8 @@ __int64 __fastcall InitialFileCheck(__int64 a1, const char* a2, unsigned int a3,
157195 return oInitialFileCheck (a1, finalPath, a3, a4, a5);
158196}
159197
198+
199+
160200void __fastcall DebugLogger (int a1, __int64 a2, __int64 a3, const char * a4, ...) {
161201 if (!a4) return ;
162202 char buffer[4096 ] = { 0 };
@@ -177,26 +217,30 @@ void __fastcall hkLocaleHandler(__int64 mgr, char* dest, unsigned __int16* local
177217 oLocaleHandler (mgr, dest, locale, src, zero);
178218
179219 if (src && dest && dest[0 ] != ' \0 ' ) {
180- std::string s_src (src);
181- std::string s_dest (dest);
182-
183- for (char & c : s_src) if (c == ' \\ ' ) c = ' /' ;
184- for (char & c : s_dest) if (c == ' \\ ' ) c = ' /' ;
185-
186- size_t firstSlashSrc = s_src.find (' /' );
187- size_t firstSlashDest = s_dest.find (' /' );
188-
189- if (firstSlashSrc != std::string::npos && firstSlashDest != std::string::npos) {
190- std::string srcDir = s_src.substr (0 , firstSlashSrc);
191- std::string destDir = s_dest.substr (0 , firstSlashDest);
192-
193- if (destDir.rfind (srcDir, 0 ) == 0 && destDir.length () > srcDir.length ()) {
194- std::string currentSuffix = destDir.substr (srcDir.length ());
195- {
196- std::lock_guard<std::mutex> lock (g_localeMutex);
197- g_localeSuffix = currentSuffix;
220+ char s_src[MAX_PATH];
221+ char s_dest[MAX_PATH];
222+ strncpy_s (s_src, sizeof (s_src), src, _TRUNCATE);
223+ strncpy_s (s_dest, sizeof (s_dest), dest, _TRUNCATE);
224+ for (char * p = s_src; *p; ++p) if (*p == ' \\ ' ) *p = ' /' ;
225+ for (char * p = s_dest; *p; ++p) if (*p == ' \\ ' ) *p = ' /' ;
226+
227+ const char * firstSlashSrc = strchr (s_src, ' /' );
228+ const char * firstSlashDest = strchr (s_dest, ' /' );
229+
230+ if (firstSlashSrc && firstSlashDest) {
231+ size_t srcDirLen = (size_t )(firstSlashSrc - s_src);
232+ size_t destDirLen = (size_t )(firstSlashDest - s_dest);
233+ if (destDirLen > srcDirLen && strncmp (s_dest, s_src, srcDirLen) == 0 ) {
234+ size_t suffixLen = destDirLen - srcDirLen;
235+ if (suffixLen < MAX_PATH) {
236+ char currentSuffix[MAX_PATH] = {};
237+ strncpy_s (currentSuffix, sizeof (currentSuffix), s_dest + srcDirLen, suffixLen);
238+ {
239+ std::lock_guard<std::mutex> lock (g_localeMutex);
240+ g_localeSuffix = currentSuffix;
241+ }
242+ Log (" [MOD] >>> Detected locale suffix: '%s'" , currentSuffix);
198243 }
199- Log (" [MOD] >>> Detected locale suffix: '%s'" , currentSuffix.c_str ());
200244 }
201245 }
202246 }
0 commit comments