using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using BepInEx; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyTitle("RPKP_Safety")] [assembly: AssemblyDescription("Safe check plugin for RPKP")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("RPKP_Safety")] [assembly: AssemblyCopyright("© 2025 whiteline7. All rights reserved")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("608acb94-b33f-4c97-b60a-997112e70298")] [assembly: AssemblyFileVersion("5.4.0.0")] [assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("5.4.0.0")] [module: UnverifiableCode] [BepInPlugin("whiteline7", "RPKP_Safety", "5.4.0")] public class RPKP_Safety : BaseUnityPlugin { private void Awake() { try { ((BaseUnityPlugin)this).Logger.LogInfo((object)"RPKP 한글패치 안전검사 시작"); string text = FindPluginsPath(); if (string.IsNullOrEmpty(text) || !Directory.Exists(text)) { ((BaseUnityPlugin)this).Logger.LogError((object)("RPKP_Safety: plugins 폴더를 찾을 수 없습니다: " + text)); ((BaseUnityPlugin)this).Logger.LogInfo((object)"RPKP 한글패치 안전검사 종료"); return; } HashSet hashSet = (from d in Directory.EnumerateDirectories(text) select Path.GetFileName(d) into n where !string.IsNullOrEmpty(n) select n).ToHashSet(); List list = new List(); bool flag = hashSet.Contains("whiteline7-MKP"); string configRootPath = GetConfigRootPath(); string text2 = null; if (!string.IsNullOrEmpty(configRootPath) && Directory.Exists(configRootPath)) { try { string text3 = Path.Combine(configRootPath, "{RPKP}"); text2 = Directory.EnumerateFiles(Directory.Exists(text3) ? text3 : configRootPath, "*.txt", SearchOption.TopDirectoryOnly).FirstOrDefault((string f) => string.Equals(Path.GetFileNameWithoutExtension(f), "Mod Korean Patch", StringComparison.OrdinalIgnoreCase)); } catch { } } if (flag && !string.IsNullOrEmpty(text2)) { ((BaseUnityPlugin)this).Logger.LogInfo((object)"MKP 모드가 있고 요구 구성 파일이 존재합니다, 정상입니다."); } else if (!flag && !string.IsNullOrEmpty(text2)) { string text4 = "MKP 모드가 없지만 잔여 구성 파일이 남아있습니다, 성능 개선을 위해 제거합니다."; ((BaseUnityPlugin)this).Logger.LogWarning((object)text4); list.Add(text4 + " 경로: " + text2); try { File.Delete(text2); } catch (Exception arg) { string text5 = $"RPKP_Safety: 잔여 구성 파일 삭제 중 예외가 발생했습니다: {arg}"; ((BaseUnityPlugin)this).Logger.LogError((object)text5); list.Add(text5); } } else if (flag && string.IsNullOrEmpty(text2)) { string text6 = "MKP 모드가 있으나 요구 구성 파일이 누락되었습니다. MKP를 재설치해주세요."; ((BaseUnityPlugin)this).Logger.LogError((object)text6); list.Add(text6); } if (flag) { if (hashSet.Count((string n) => !string.Equals(n, "whiteline7-MKP", StringComparison.OrdinalIgnoreCase)) > 2) { string text7 = "MKP 확장팩이 있고 다른 모드가 4개 이상 있습니다. 정상입니다"; ((BaseUnityPlugin)this).Logger.LogInfo((object)text7); } else { string text8 = "현재 모드 구성이 MKP 확장팩을 필요로 하지 않습니다, 성능을 위해 제거하는걸 권장드립니다"; ((BaseUnityPlugin)this).Logger.LogWarning((object)text8); list.Add(text8); } } if (!string.IsNullOrEmpty(configRootPath) && Directory.Exists(configRootPath)) { try { string path = Path.Combine(configRootPath, "Translation"); if (Directory.Exists(path) && Directory.EnumerateFiles(path, "*.txt", SearchOption.AllDirectories).Any()) { string text9 = "타 언어패치 모드의 구성 파일이 감지되었습니다. 이는 충돌을 야기할 수 있습니다\nConfig editor에서 {RPKP}가 아닌 Translation이 붙은 txt 파일을 제거하는걸 권장드립니다\n혹은 모드팩 자체를 새로 구성해주세요, 한글화 시스템에 문제가 없다면 이 오류를 무시하셔도 좋습니다"; ((BaseUnityPlugin)this).Logger.LogWarning((object)text9); list.Add(text9); } } catch { } } CheckAndLog(hashSet, "Blend-REPO_Korean_Translation_BETA", "귀하의 모드 중에 REPO_Korean_Translation_BETA 모드가 있습니다!\n해당 모드는 더 이상 사용되지 않는 옛날 한글패치이며 RPKP와 충돌이 발생합니다\n번역 품질이 저하되며 오류가 발생하므로 제거하시기 바랍니다!", "REPO_Korean_Translation_BETA와의 충돌 없음, 정상입니다", list); CheckAndLog(hashSet, "Hayrizan-XUnity_AutoTranslator", "귀하의 모드 중에 XUnity_AutoTranslator 모드가 있습니다!\n해당 모드는 RPKP에 이미 내장되어 있는 기능이며 RPKP와 충돌이 발생합니다\n번역이 고장날 수 있으며 오류가 발생하므로 제거하시기 바랍니다!", "XUnity_AutoTranslator와의 충돌 없음, 정상입니다", list); CheckAndLog(hashSet, "RTLC-REPO_Russian_Translation", "귀하의 모드 중에 REPO_Russian_Translation 모드가 있습니다!\n해당 모드는 RPKP와는 다른 언어의 언어패치 모드이며 RPKP와 충돌이 발생합니다\n번역이 중첩되거나 고장나며 오류가 발생하므로 제거하시기 바랍니다!", "REPO_Russian_Translation와의 충돌 없음, 정상입니다", list); CheckAndLog(hashSet, "AmnesiaXII-REPO_ESP_Translation", "귀하의 모드 중에 REPO_ESP_Translation 모드가 있습니다!\n해당 모드는 RPKP와는 다른 언어의 언어패치 모드이며 RPKP와 충돌이 발생합니다\n번역이 중첩되거나 고장나며 오류가 발생하므로 제거하시기 바랍니다!", "REPO_ESP_Translation와의 충돌 없음, 정상입니다", list); CheckAndLog(hashSet, "xiandaoll-Simplified_Chinese_Translation", "귀하의 모드 중에 Simplified_Chinese_Translation 모드가 있습니다!\n해당 모드는 RPKP와는 다른 언어의 언어패치 모드이며 RPKP와 충돌이 발생합니다\n번역이 중첩되거나 고장나며 오류가 발생하므로 제거하시기 바랍니다!", "Simplified_Chinese_Translation와의 충돌 없음, 정상입니다", list); CheckAndLog(hashSet, "toored-Chinese_Translation", "귀하의 모드 중에 toored-Chinese_Translation 모드가 있습니다!\n해당 모드는 RPKP와는 다른 언어의 언어패치 모드이며 RPKP와 충돌이 발생합니다\n번역이 중첩되거나 고장나며 오류가 발생하므로 제거하시기 바랍니다!", "toored-Chinese_Translation와의 충돌 없음, 정상입니다", list); CheckAndLog(hashSet, "UncleDan-RU_PEREVOD_UNCLEDAN", "귀하의 모드 중에 RU_PEREVOD_UNCLEDAN 모드가 있습니다!\n해당 모드는 RPKP와는 다른 언어의 언어패치 모드이며 RPKP와 충돌이 발생합니다\n번역이 중첩되거나 고장나며 오류가 발생하므로 제거하시기 바랍니다!", "RU_PEREVOD_UNCLEDAN와의 충돌 없음, 정상입니다", list); CheckAndLog(hashSet, "UFresh-SPANISH_Translate_ESP", "귀하의 모드 중에 SPANISH_Translate_ESP 모드가 있습니다!\n해당 모드는 RPKP와는 다른 언어의 언어패치 모드이며 RPKP와 충돌이 발생합니다\n번역이 중첩되거나 고장나며 오류가 발생하므로 제거하시기 바랍니다!", "SPANISH_Translate_ESP와의 충돌 없음, 정상입니다", list); CheckAndLog(hashSet, "Russian_kid-RU_REPEREVOD_RUSSIANKID", "귀하의 모드 중에 RU_REPEREVOD_RUSSIANKID 모드가 있습니다!\n해당 모드는 RPKP와는 다른 언어의 언어패치 모드이며 RPKP와 충돌이 발생합니다\n번역이 중첩되거나 고장나며 오류가 발생하므로 제거하시기 바랍니다!", "RU_REPEREVOD_RUSSIANKID와의 충돌 없음, 정상입니다", list); CheckAndLog(hashSet, "REPO_FUN-RepoFunTranslator", "귀하의 모드 중에 RepoFunTranslator 모드가 있습니다!\n해당 모드는 RPKP와는 다른 언어의 언어패치 모드이며 RPKP와 충돌이 발생합니다\n번역이 중첩되거나 고장나며 오류가 발생하므로 제거하시기 바랍니다!", "RepoFunTranslator와의 충돌 없음, 정상입니다", list); CheckAndLog(hashSet, "RasvetTM-BEST_Russian_Translate_REPO", "귀하의 모드 중에 BEST_Russian_Translate_REPO 모드가 있습니다!\n해당 모드는 RPKP와는 다른 언어의 언어패치 모드이며 RPKP와 충돌이 발생합니다\n번역이 중첩되거나 고장나며 오류가 발생하므로 제거하시기 바랍니다!", "BEST_Russian_Translate_REPO와의 충돌 없음, 정상입니다", list); CheckAndLog(hashSet, "QERT2002-REPO_Translator", "귀하의 모드 중에 REPO_Translator 모드가 있습니다!\n해당 모드는 RPKP와는 다른 언어의 언어패치 모드이며 RPKP와 충돌이 발생합니다\n번역이 중첩되거나 고장나며 오류가 발생하므로 제거하시기 바랍니다!", "REPO_Translator와의 충돌 없음, 정상입니다", list); CheckAndLog(hashSet, "ProyeutuMontanies-REPO_Cantabrian_Translate", "귀하의 모드 중에 REPO_Cantabrian_Translate 모드가 있습니다!\n해당 모드는 RPKP와는 다른 언어의 언어패치 모드이며 RPKP와 충돌이 발생합니다\n번역이 중첩되거나 고장나며 오류가 발생하므로 제거하시기 바랍니다!", "REPO_Cantabrian_Translate와의 충돌 없음, 정상입니다", list); CheckAndLog(hashSet, "Piskotryasi-RU_ROFLOPEREVOD", "귀하의 모드 중에 RU_ROFLOPEREVOD 모드가 있습니다!\n해당 모드는 RPKP와는 다른 언어의 언어패치 모드이며 RPKP와 충돌이 발생합니다\n번역이 중첩되거나 고장나며 오류가 발생하므로 제거하시기 바랍니다!", "RU_ROFLOPEREVOD와의 충돌 없음, 정상입니다", list); CheckAndLog(hashSet, "Omniscye-Sims_Translation", "귀하의 모드 중에 Sims_Translation 모드가 있습니다!\n해당 모드는 RPKP와는 다른 언어의 언어패치 모드이며 RPKP와 충돌이 발생합니다\n번역이 중첩되거나 고장나며 오류가 발생하므로 제거하시기 바랍니다!", "Sims_Translation와의 충돌 없음, 정상입니다", list); CheckAndLog(hashSet, "Mlao-REPO_Translator_CN", "귀하의 모드 중에 REPO_Translator_CN 모드가 있습니다!\n해당 모드는 RPKP와는 다른 언어의 언어패치 모드이며 RPKP와 충돌이 발생합니다\n번역이 중첩되거나 고장나며 오류가 발생하므로 제거하시기 바랍니다!", "REPO_Translator_CN와의 충돌 없음, 정상입니다", list); CheckAndLog(hashSet, "metastreum-REPO_French", "귀하의 모드 중에 REPO_French 모드가 있습니다!\n해당 모드는 RPKP와는 다른 언어의 언어패치 모드이며 RPKP와 충돌이 발생합니다\n번역이 중첩되거나 고장나며 오류가 발생하므로 제거하시기 바랍니다!", "REPO_French와의 충돌 없음, 정상입니다", list); CheckAndLog(hashSet, "makuromk6-REPO_JP_TranslationAndFont", "귀하의 모드 중에 REPO_JP_TranslationAndFont 모드가 있습니다!\n해당 모드는 RPKP와는 다른 언어의 언어패치 모드이며 RPKP와 충돌이 발생합니다\n번역이 중첩되거나 고장나며 오류가 발생하므로 제거하시기 바랍니다!", "REPO_JP_TranslationAndFont와의 충돌 없음, 정상입니다", list); CheckAndLog(hashSet, "Kulis6k-Czech_Translate", "귀하의 모드 중에 Czech_Translate 모드가 있습니다!\n해당 모드는 RPKP와는 다른 언어의 언어패치 모드이며 RPKP와 충돌이 발생합니다\n번역이 중첩되거나 고장나며 오류가 발생하므로 제거하시기 바랍니다!", "Czech_Translate와의 충돌 없음, 정상입니다", list); CheckAndLog(hashSet, "JayDevelopment-TCTranslation", "귀하의 모드 중에 TCTranslation 모드가 있습니다!\n해당 모드는 RPKP와는 다른 언어의 언어패치 모드이며 RPKP와 충돌이 발생합니다\n번역이 중첩되거나 고장나며 오류가 발생하므로 제거하시기 바랍니다!", "TCTranslation와의 충돌 없음, 정상입니다", list); CheckAndLog(hashSet, "Jajo-Polish_Translate", "귀하의 모드 중에 Polish_Translate 모드가 있습니다!\n해당 모드는 RPKP와는 다른 언어의 언어패치 모드이며 RPKP와 충돌이 발생합니다\n번역이 중첩되거나 고장나며 오류가 발생하므로 제거하시기 바랍니다!", "Polish_Translate와의 충돌 없음, 정상입니다", list); CheckAndLog(hashSet, "iFanat-REPO_TRANSLATOR_UA", "귀하의 모드 중에 REPO_TRANSLATOR_UA 모드가 있습니다!\n해당 모드는 RPKP와는 다른 언어의 언어패치 모드이며 RPKP와 충돌이 발생합니다\n번역이 중첩되거나 고장나며 오류가 발생하므로 제거하시기 바랍니다!", "REPO_TRANSLATOR_UA와의 충돌 없음, 정상입니다", list); CheckAndLog(hashSet, "Ernedev-REPO_Turkish_Translate", "귀하의 모드 중에 REPO_Turkish_Translate 모드가 있습니다!\n해당 모드는 RPKP와는 다른 언어의 언어패치 모드이며 RPKP와 충돌이 발생합니다\n번역이 중첩되거나 고장나며 오류가 발생하므로 제거하시기 바랍니다!", "REPO_Turkish_Translate와의 충돌 없음, 정상입니다", list); CheckAndLog(hashSet, "DarklightMods-REPO_German_Translations", "귀하의 모드 중에 REPO_German_Translations 모드가 있습니다!\n해당 모드는 RPKP와는 다른 언어의 언어패치 모드이며 RPKP와 충돌이 발생합니다\n번역이 중첩되거나 고장나며 오류가 발생하므로 제거하시기 바랍니다!", "REPO_German_Translations와의 충돌 없음, 정상입니다", list); CheckAndLog(hashSet, "ColoredNok-REPO_Thai_Translation", "귀하의 모드 중에 REPO_Thai_Translation 모드가 있습니다!\n해당 모드는 RPKP와는 다른 언어의 언어패치 모드이며 RPKP와 충돌이 발생합니다\n번역이 중첩되거나 고장나며 오류가 발생하므로 제거하시기 바랍니다!", "REPO_Thai_Translation와의 충돌 없음, 정상입니다", list); CheckAndLog(hashSet, "AutoKFontPatcher-AutoKFontPatcher", "RPKP_Safety 경고!\n다운로드된 모드 중에 AutoKFontPatcher 가 없습니다!\n이 모드는 RPKP가 요구하는 중요 종속성 모드로 폰트 설치 이외에도 기능을 합니다.\n없을 경우 심각한 오류가 발생할 수 있습니다! 다운로드 하시는 것을 권장합니다.", "AutoKFontPatcher가 설치되어 있습니다. (필수 의존성 확인 완료)", list); CheckAndLog(hashSet, "xingKong-REPO_Simplified_Chinese_Translation", "귀하의 모드 중에 REPO_Simplified_Chinese_Translation 모드가 있습니다!\n해당 모드는 RPKP와는 다른 언어의 언어패치 모드이며 RPKP와 충돌이 발생합니다\n번역이 중첩되거나 고장나며 오류가 발생하므로 제거하시기 바랍니다!", "REPO_Simplified_Chinese_Translation와의 충돌 없음, 정상입니다", list); CheckAndLog(hashSet, "Rinary-Great_REPO_Translator", "귀하의 모드 중에 Great_REPO_Translator 모드가 있습니다!\n해당 모드는 RPKP가 사용하는 플러그인이 아니며 RPKP는 내장된 기능을 사용합니다!\n번역이 고장날 수 있으며 오류가 발생하므로 제거하시기 바랍니다!", "Great_REPO_Translator와의 충돌 없음, 정상입니다", list); CheckAndLog(hashSet, "saitogo-REPOJapaneseTranslation", "귀하의 모드 중에 REPOJapaneseTranslation 모드가 있습니다!\n해당 모드는 RPKP와는 다른 언어의 언어패치 모드이며 RPKP와 충돌이 발생합니다\n번역이 중첩되거나 고장나며 오류가 발생하므로 제거하시기 바랍니다!", "REPOJapaneseTranslation와의 충돌 없음, 정상입니다", list); if (list.Count > 0) { ((BaseUnityPlugin)this).Logger.LogError((object)("RPKP_Safety: 검출된 문제들 총 " + list.Count + "건:\n" + string.Join("\n-----\n", list))); } ((BaseUnityPlugin)this).Logger.LogInfo((object)"RPKP 한글패치 안전검사 종료"); } catch (Exception arg2) { ((BaseUnityPlugin)this).Logger.LogError((object)$"RPKP_Safety: 플러그인 검사 중 예외가 발생했습니다: {arg2}"); } } private string FindPluginsPath() { string location = Assembly.GetExecutingAssembly().Location; if (string.IsNullOrEmpty(location)) { return TryFallbackPluginPath(); } string directoryName = Path.GetDirectoryName(location); while (!string.IsNullOrEmpty(directoryName)) { string text = Path.Combine(directoryName, "plugins"); if (Directory.Exists(text)) { return text; } if (string.Equals(Path.GetFileName(directoryName), "BepInEx", StringComparison.OrdinalIgnoreCase)) { try { string text2 = Directory.EnumerateDirectories(directoryName, "plugins", SearchOption.AllDirectories).FirstOrDefault(); if (!string.IsNullOrEmpty(text2)) { return text2; } } catch { } } directoryName = Path.GetDirectoryName(directoryName); } return TryFallbackPluginPath(); } private string GetConfigRootPath() { try { string configPath = Paths.ConfigPath; if (!string.IsNullOrEmpty(configPath) && Directory.Exists(configPath)) { return configPath; } } catch { } return TryFallbackConfigRpkpPath(); } private string TryFallbackPluginPath() { try { string pluginPath = Paths.PluginPath; if (!string.IsNullOrEmpty(pluginPath) && Directory.Exists(pluginPath)) { return pluginPath; } } catch { } try { string bepInExRootPath = Paths.BepInExRootPath; if (!string.IsNullOrEmpty(bepInExRootPath)) { string text = Path.Combine(bepInExRootPath, "plugins"); if (Directory.Exists(text)) { return text; } } } catch { } return null; } private string TryFallbackConfigRpkpPath() { try { string bepInExRootPath = Paths.BepInExRootPath; if (!string.IsNullOrEmpty(bepInExRootPath)) { string text = Path.Combine(bepInExRootPath, "config"); if (Directory.Exists(text)) { return text; } } } catch { } try { string text2 = TryFallbackPluginPath(); if (!string.IsNullOrEmpty(text2)) { string directoryName = Path.GetDirectoryName(text2); if (!string.IsNullOrEmpty(directoryName)) { string text3 = Path.Combine(directoryName, "config"); if (Directory.Exists(text3)) { return text3; } } } } catch { } return null; } private void CheckAndLog(HashSet folderNames, string folderKey, string errorMessage, string okMessage, List errorList) { bool flag = folderNames.Contains(folderKey); if (folderKey == "AutoKFontPatcher-AutoKFontPatcher") { if (!flag) { ((BaseUnityPlugin)this).Logger.LogError((object)errorMessage); errorList.Add(errorMessage); } else { ((BaseUnityPlugin)this).Logger.LogInfo((object)okMessage); } } else if (flag) { ((BaseUnityPlugin)this).Logger.LogError((object)errorMessage); errorList.Add(errorMessage); } else { ((BaseUnityPlugin)this).Logger.LogInfo((object)okMessage); } } }