diff --git a/.gitignore b/.gitignore index 6014c60..e969f3d 100644 --- a/.gitignore +++ b/.gitignore @@ -137,4 +137,8 @@ dist .idea packages */bin/ -*/obj/ \ No newline at end of file +*/obj/ +*/obj/.nuget/ + +# App settings (user preferences) +appsettings.json diff --git a/WeModPatcher/App.xaml b/WeModPatcher/App.xaml index c915d67..aca5417 100644 --- a/WeModPatcher/App.xaml +++ b/WeModPatcher/App.xaml @@ -6,6 +6,7 @@ + diff --git a/WeModPatcher/App.xaml.cs b/WeModPatcher/App.xaml.cs index 3cb40f1..94624c3 100644 --- a/WeModPatcher/App.xaml.cs +++ b/WeModPatcher/App.xaml.cs @@ -2,6 +2,7 @@ using System.Threading.Tasks; using System.Windows; using WeModPatcher.Core; +using WeModPatcher.Core.Services; using WeModPatcher.View.MainWindow; using MessageBox = System.Windows.Forms.MessageBox; @@ -14,6 +15,7 @@ namespace WeModPatcher { protected override void OnStartup(StartupEventArgs e) { + LocalizationManager.Initialize(); this.MainWindow.Show(); } diff --git a/WeModPatcher/Constants.cs b/WeModPatcher/Constants.cs index 4fdafb4..566e1f9 100644 --- a/WeModPatcher/Constants.cs +++ b/WeModPatcher/Constants.cs @@ -12,6 +12,7 @@ namespace WeModPatcher public static readonly string RepositoryUrl = $"https://github.com/{Owner}/{RepoName}"; public static readonly Version Version; public static readonly string[] WeModBrandNames = { "Wand", "WeMod" }; + public const string AppSettingsFileName = "appsettings.json"; public const string ProxyDllResouceName = "proxydll"; diff --git a/WeModPatcher/Core/Services/LocalizationManager.cs b/WeModPatcher/Core/Services/LocalizationManager.cs new file mode 100644 index 0000000..5509fe2 --- /dev/null +++ b/WeModPatcher/Core/Services/LocalizationManager.cs @@ -0,0 +1,150 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.Globalization; +using System.Linq; +using System.Threading; +using System.Windows; + +namespace WeModPatcher.Core.Services +{ + public static class LocalizationManager + { + public static readonly List SupportedLanguages = new List + { + new CultureInfo("en-US"), + new CultureInfo("zh-CN"), + new CultureInfo("de-DE"), + new CultureInfo("fr-FR"), + new CultureInfo("es-ES"), + new CultureInfo("it-IT"), + new CultureInfo("pt-BR"), + new CultureInfo("pl-PL"), + new CultureInfo("ru-RU"), + new CultureInfo("uk-UA"), + new CultureInfo("ja-JP"), + new CultureInfo("tr-TR") + }; + + private static CultureInfo _currentLanguage; + private static ResourceDictionary _englishBaseDictionary; + + public static CultureInfo CurrentLanguage + { + get => _currentLanguage; + set => SetLanguage(value); + } + + public static void Initialize() + { + // Load English as the base fallback dictionary + _englishBaseDictionary = new ResourceDictionary + { + Source = new Uri("Locale/lang.en-US.xaml", UriKind.Relative) + }; + + // Try to load saved language preference + var savedLanguage = SettingsManager.LoadSettings()?.Language; + CultureInfo targetCulture = null; + + if (!string.IsNullOrEmpty(savedLanguage)) + { + targetCulture = SupportedLanguages.FirstOrDefault(c => c.Name == savedLanguage); + } + + if (targetCulture == null) + { + // Fall back to system culture detection + var systemCulture = Thread.CurrentThread.CurrentUICulture; + targetCulture = SupportedLanguages.FirstOrDefault(c => + c.Name == systemCulture.Name || + c.TwoLetterISOLanguageName == systemCulture.TwoLetterISOLanguageName); + } + + SetLanguage(targetCulture ?? SupportedLanguages[0], saveSettings: false); + } + + private static void SetLanguage(CultureInfo culture, bool saveSettings = true) + { + if (culture == null) + throw new ArgumentNullException(nameof(culture)); + + if (Equals(culture, _currentLanguage)) + return; + + var supportedCulture = SupportedLanguages.FirstOrDefault(c => c.Name == culture.Name); + if (supportedCulture == null) + { + supportedCulture = SupportedLanguages[0]; // Default to English + } + + _currentLanguage = supportedCulture; + Thread.CurrentThread.CurrentUICulture = supportedCulture; + + // Create the locale dictionary with English as base for fallback + var localeDict = new ResourceDictionary(); + + // First, add English base dictionary for fallback + if (_englishBaseDictionary != null && supportedCulture.Name != SupportedLanguages[0].Name) + { + foreach (var key in _englishBaseDictionary.Keys) + { + localeDict[key] = _englishBaseDictionary[key]; + } + } + + // Then overlay with the selected language (will override English keys) + var targetDict = new ResourceDictionary + { + Source = new Uri($"Locale/lang.{supportedCulture.Name}.xaml", UriKind.Relative) + }; + + foreach (DictionaryEntry entry in targetDict) + { + localeDict[entry.Key] = targetDict[entry.Key]; + } + + // Find and replace the old locale dictionary + var oldDict = Application.Current.Resources.MergedDictionaries + .FirstOrDefault(d => d.Source != null && d.Source.OriginalString.StartsWith("Locale/lang.")); + + if (oldDict != null) + { + var index = Application.Current.Resources.MergedDictionaries.IndexOf(oldDict); + Application.Current.Resources.MergedDictionaries.Remove(oldDict); + Application.Current.Resources.MergedDictionaries.Insert(index, localeDict); + } + else + { + Application.Current.Resources.MergedDictionaries.Add(localeDict); + } + + if (saveSettings) + { + SettingsManager.SaveSettings(new AppSettings { Language = supportedCulture.Name }); + } + } + + public static string GetLanguageDisplayName(CultureInfo culture) + { + try + { + var dict = new ResourceDictionary + { + Source = new Uri($"Locale/lang.{culture.Name}.xaml", UriKind.Relative) + }; + + if (dict.Contains("language_display_name")) + { + return dict["language_display_name"] as string ?? culture.NativeName; + } + } + catch + { + // Fallback to native name if loading fails + } + + return culture.NativeName; + } + } +} diff --git a/WeModPatcher/Core/Services/SettingsManager.cs b/WeModPatcher/Core/Services/SettingsManager.cs new file mode 100644 index 0000000..3fb7f36 --- /dev/null +++ b/WeModPatcher/Core/Services/SettingsManager.cs @@ -0,0 +1,50 @@ +using System; +using System.IO; +using Newtonsoft.Json; + +namespace WeModPatcher.Core.Services +{ + public class AppSettings + { + public string Language { get; set; } + } + + public static class SettingsManager + { + private static readonly string SettingsPath = Path.Combine( + AppDomain.CurrentDomain.BaseDirectory, + Constants.AppSettingsFileName); + + public static AppSettings LoadSettings() + { + try + { + if (File.Exists(SettingsPath)) + { + var json = File.ReadAllText(SettingsPath); + return JsonConvert.DeserializeObject(json); + } + } + catch (Exception) + { + // Settings loading is non-critical - silently fall back to defaults + // This can fail due to file permissions, corrupted JSON, etc. + } + return null; + } + + public static void SaveSettings(AppSettings settings) + { + try + { + var json = JsonConvert.SerializeObject(settings, Formatting.Indented); + File.WriteAllText(SettingsPath, json); + } + catch (Exception) + { + // Settings saving is non-critical - silently ignore errors + // This can fail due to file permissions or read-only directories + } + } + } +} \ No newline at end of file diff --git a/WeModPatcher/Locale/lang.de-DE.xaml b/WeModPatcher/Locale/lang.de-DE.xaml new file mode 100644 index 0000000..c6be9dd --- /dev/null +++ b/WeModPatcher/Locale/lang.de-DE.xaml @@ -0,0 +1,41 @@ + + + + Deutsch + + + + WeMod Patcher + Eine neue Version ist verfügbar + Ordnerpfad + Ordner nicht gefunden + Patch + Wiederherstellen + Quellcode + Mit ❤️ von k1tbyte erstellt + Gib einen Stern, wenn dir das geholfen hat ;) + + + + Einstellungen + Sprache + Speichern + + + + WeMod Pro aktivieren + DevTools mit F12 + Updates deaktivieren + Starten + Was werden wir patchen? + + + + Vor dem Update wird dringend empfohlen, Patches rückgängig zu machen, falls sie angewendet wurden + Jetzt aktualisieren + Update verfügbar! + + + diff --git a/WeModPatcher/Locale/lang.en-US.xaml b/WeModPatcher/Locale/lang.en-US.xaml new file mode 100644 index 0000000..4754897 --- /dev/null +++ b/WeModPatcher/Locale/lang.en-US.xaml @@ -0,0 +1,41 @@ + + + + English + + + + WeMod Patcher + A new version is available + Folder path + Folder not found + Patch + Restore + Source code + Made with ❤️ by k1tbyte + Put a star if you found this helpful ;) + + + + Settings + Language + Save + + + + Activate WeMod Pro + DevTools on F12 + Disable updates + Start + What are we gonna patch? + + + + Before updating, it is strongly recommended to roll back patches if they have been applied + Update now + Update available! + + + diff --git a/WeModPatcher/Locale/lang.es-ES.xaml b/WeModPatcher/Locale/lang.es-ES.xaml new file mode 100644 index 0000000..27858f2 --- /dev/null +++ b/WeModPatcher/Locale/lang.es-ES.xaml @@ -0,0 +1,41 @@ + + + + Español + + + + WeMod Patcher + Una nueva versión está disponible + Ruta de la carpeta + Carpeta no encontrada + Parchear + Restaurar + Código fuente + Hecho con ❤️ por k1tbyte + Pon una estrella si te fue útil ;) + + + + Configuración + Idioma + Guardar + + + + Activar WeMod Pro + DevTools en F12 + Desactivar actualizaciones + Iniciar + ¿Qué vamos a parchear? + + + + Antes de actualizar, se recomienda encarecidamente revertir los parches si se han aplicado + Actualizar ahora + ¡Actualización disponible! + + + diff --git a/WeModPatcher/Locale/lang.fr-FR.xaml b/WeModPatcher/Locale/lang.fr-FR.xaml new file mode 100644 index 0000000..813a37a --- /dev/null +++ b/WeModPatcher/Locale/lang.fr-FR.xaml @@ -0,0 +1,41 @@ + + + + Français + + + + WeMod Patcher + Une nouvelle version est disponible + Chemin du dossier + Dossier non trouvé + Patcher + Restaurer + Code source + Fait avec ❤️ par k1tbyte + Mettez une étoile si cela vous a aidé ;) + + + + Paramètres + Langue + Enregistrer + + + + Activer WeMod Pro + DevTools sur F12 + Désactiver les mises à jour + Démarrer + Qu'allons-nous patcher ? + + + + Avant la mise à jour, il est fortement recommandé d'annuler les patchs s'ils ont été appliqués + Mettre à jour maintenant + Mise à jour disponible ! + + + diff --git a/WeModPatcher/Locale/lang.it-IT.xaml b/WeModPatcher/Locale/lang.it-IT.xaml new file mode 100644 index 0000000..41c04e0 --- /dev/null +++ b/WeModPatcher/Locale/lang.it-IT.xaml @@ -0,0 +1,41 @@ + + + + Italiano + + + + WeMod Patcher + È disponibile una nuova versione + Percorso cartella + Cartella non trovata + Patch + Ripristina + Codice sorgente + Creato con ❤️ da k1tbyte + Metti una stella se ti è stato utile ;) + + + + Impostazioni + Lingua + Salva + + + + Attiva WeMod Pro + DevTools su F12 + Disattiva aggiornamenti + Avvia + Cosa patcheremo? + + + + Prima dell'aggiornamento, si consiglia vivamente di annullare le patch se sono state applicate + Aggiorna ora + Aggiornamento disponibile! + + + diff --git a/WeModPatcher/Locale/lang.ja-JP.xaml b/WeModPatcher/Locale/lang.ja-JP.xaml new file mode 100644 index 0000000..e91e241 --- /dev/null +++ b/WeModPatcher/Locale/lang.ja-JP.xaml @@ -0,0 +1,41 @@ + + + + 日本語 + + + + WeMod Patcher + 新しいバージョンが利用可能です + フォルダパス + フォルダが見つかりません + パッチ + 復元 + ソースコード + k1tbyte が ❤️ を込めて作成 + 役に立ったらスターをつけてください ;) + + + + 設定 + 言語 + 保存 + + + + WeMod Pro を有効化 + F12でDevTools + アップデートを無効化 + 開始 + 何をパッチしますか? + + + + アップデート前に、パッチが適用されている場合はロールバックすることを強くお勧めします + 今すぐ更新 + アップデート利用可能! + + + diff --git a/WeModPatcher/Locale/lang.pl-PL.xaml b/WeModPatcher/Locale/lang.pl-PL.xaml new file mode 100644 index 0000000..f946e97 --- /dev/null +++ b/WeModPatcher/Locale/lang.pl-PL.xaml @@ -0,0 +1,41 @@ + + + + Polski + + + + WeMod Patcher + Dostępna jest nowa wersja + Ścieżka folderu + Folder nie znaleziony + Patchuj + Przywróć + Kod źródłowy + Wykonane z ❤️ przez k1tbyte + Daj gwiazdkę, jeśli ci pomogło ;) + + + + Ustawienia + Język + Zapisz + + + + Aktywuj WeMod Pro + DevTools na F12 + Wyłącz aktualizacje + Rozpocznij + Co będziemy patchować? + + + + Przed aktualizacją zdecydowanie zaleca się cofnięcie patchów, jeśli zostały zastosowane + Aktualizuj teraz + Dostępna aktualizacja! + + + diff --git a/WeModPatcher/Locale/lang.pt-BR.xaml b/WeModPatcher/Locale/lang.pt-BR.xaml new file mode 100644 index 0000000..8751dbf --- /dev/null +++ b/WeModPatcher/Locale/lang.pt-BR.xaml @@ -0,0 +1,41 @@ + + + + Português + + + + WeMod Patcher + Uma nova versão está disponível + Caminho da pasta + Pasta não encontrada + Patch + Restaurar + Código fonte + Feito com ❤️ por k1tbyte + Dê uma estrela se isso te ajudou ;) + + + + Configurações + Idioma + Salvar + + + + Ativar WeMod Pro + DevTools no F12 + Desativar atualizações + Iniciar + O que vamos patchear? + + + + Antes de atualizar, é altamente recomendável reverter os patches se eles foram aplicados + Atualizar agora + Atualização disponível! + + + diff --git a/WeModPatcher/Locale/lang.ru-RU.xaml b/WeModPatcher/Locale/lang.ru-RU.xaml new file mode 100644 index 0000000..f0257ae --- /dev/null +++ b/WeModPatcher/Locale/lang.ru-RU.xaml @@ -0,0 +1,41 @@ + + + + Русский + + + + WeMod Patcher + Доступна новая версия + Путь к папке + Папка не найдена + Патч + Восстановить + Исходный код + Сделано с ❤️ by k1tbyte + Поставьте звезду, если это было полезно ;) + + + + Настройки + Язык + Сохранить + + + + Активировать WeMod Pro + DevTools на F12 + Отключить обновления + Начать + Что будем патчить? + + + + Перед обновлением настоятельно рекомендуется откатить патчи, если они были применены + Обновить сейчас + Доступно обновление! + + + diff --git a/WeModPatcher/Locale/lang.tr-TR.xaml b/WeModPatcher/Locale/lang.tr-TR.xaml new file mode 100644 index 0000000..d212b85 --- /dev/null +++ b/WeModPatcher/Locale/lang.tr-TR.xaml @@ -0,0 +1,41 @@ + + + + Türkçe + + + + WeMod Patcher + Yeni bir sürüm mevcut + Klasör yolu + Klasör bulunamadı + Yama + Geri Yükle + Kaynak kodu + k1tbyte tarafından ❤️ ile yapıldı + Yardımcı olduysa yıldız verin ;) + + + + Ayarlar + Dil + Kaydet + + + + WeMod Pro'yu Etkinleştir + F12 ile DevTools + Güncellemeleri devre dışı bırak + Başlat + Ne yamalayacağız? + + + + Güncellemeden önce, yamalar uygulandıysa geri almak şiddetle tavsiye edilir + Şimdi güncelle + Güncelleme mevcut! + + + diff --git a/WeModPatcher/Locale/lang.uk-UA.xaml b/WeModPatcher/Locale/lang.uk-UA.xaml new file mode 100644 index 0000000..0c1c89f --- /dev/null +++ b/WeModPatcher/Locale/lang.uk-UA.xaml @@ -0,0 +1,41 @@ + + + + Українська + + + + WeMod Patcher + Доступна нова версія + Шлях до папки + Папку не знайдено + Патч + Відновити + Вихідний код + Зроблено з ❤️ by k1tbyte + Поставте зірку, якщо це було корисно ;) + + + + Налаштування + Мова + Зберегти + + + + Активувати WeMod Pro + DevTools на F12 + Вимкнути оновлення + Почати + Що будемо патчити? + + + + Перед оновленням наполегливо рекомендується відкотити патчі, якщо вони були застосовані + Оновити зараз + Доступне оновлення! + + + diff --git a/WeModPatcher/Locale/lang.zh-CN.xaml b/WeModPatcher/Locale/lang.zh-CN.xaml new file mode 100644 index 0000000..fd2bdd8 --- /dev/null +++ b/WeModPatcher/Locale/lang.zh-CN.xaml @@ -0,0 +1,41 @@ + + + + 简体中文 + + + + WeMod Patcher + 有新版本可用 + 文件夹路径 + 未找到文件夹 + 补丁 + 恢复 + 源代码 + 由 k1tbyte 用 ❤️ 制作 + 如果这对您有帮助,请给个星标 ;) + + + + 设置 + 语言 + 保存 + + + + 激活 WeMod Pro + 按 F12 打开开发者工具 + 禁用更新 + 开始 + 我们要打什么补丁? + + + + 在更新之前,强烈建议回滚已应用的补丁 + 立即更新 + 有更新可用! + + + diff --git a/WeModPatcher/Style/Styles.xaml b/WeModPatcher/Style/Styles.xaml index e132072..039c3c2 100644 --- a/WeModPatcher/Style/Styles.xaml +++ b/WeModPatcher/Style/Styles.xaml @@ -211,7 +211,7 @@ - + + + + \ No newline at end of file diff --git a/WeModPatcher/View/MainWindow/MainWindow.xaml b/WeModPatcher/View/MainWindow/MainWindow.xaml index 5882bf3..d719a09 100644 --- a/WeModPatcher/View/MainWindow/MainWindow.xaml +++ b/WeModPatcher/View/MainWindow/MainWindow.xaml @@ -50,7 +50,7 @@ ToolTip="Click to update" Command="{Binding UpdateCommand}" Visibility="{Binding IsUpdateAvailable, Converter={StaticResource ToVisibilityConverter}}" - Content="A new version is available"/> + Content="{DynamicResource mw_update_available}"/> @@ -59,6 +59,7 @@ Width="25" Height="25" Padding="5.5" Style="{StaticResource IconButton}" Tag="{StaticResource CogIcon}" + Command="{Binding OpenSettingsCommand}" /> + Command="{Binding ApplyPatchCommand}" + Content="{DynamicResource mw_patch}"/>