From a4a1743062e49acd62e85444084b138c7d2f6dba Mon Sep 17 00:00:00 2001 From: redphx <96280+redphx@users.noreply.github.com> Date: Wed, 22 May 2024 18:23:08 +0700 Subject: [PATCH] Update better-xcloud.user.js --- dist/better-xcloud.user.js | 4631 ++++++------------------------------ 1 file changed, 774 insertions(+), 3857 deletions(-) diff --git a/dist/better-xcloud.user.js b/dist/better-xcloud.user.js index 1b065ed..ea444f0 100644 --- a/dist/better-xcloud.user.js +++ b/dist/better-xcloud.user.js @@ -107,6 +107,7 @@ class UserAgent { var SCRIPT_VERSION = "4.4.0"; var SCRIPT_HOME = "https://github.com/redphx/better-xcloud"; var AppInterface = window.AppInterface; +var NATIVE_FETCH = window.fetch; UserAgent.init(); var userAgent = window.navigator.userAgent.toLowerCase(); var isTv = userAgent.includes("smart-tv") || userAgent.includes("smarttv") || /\baft.*\b/.test(userAgent); @@ -358,9 +359,9 @@ class BaseGameBarAction { // src/utils/translation.ts var SUPPORTED_LANGUAGES = { + "en-US": "English (United States)", "en-ID": "Bahasa Indonesia", "de-DE": "Deutsch", - "en-US": "English (United States)", "es-ES": "español (España)", "fr-FR": "français", "it-IT": "italiano", @@ -375,1942 +376,124 @@ var SUPPORTED_LANGUAGES = { "zh-CN": "中文(简体)" }; var Texts = { - activate: [ - "Aktivieren", - "Aktifkan", - "Activate", - "Activo", - "Activer", - "Abilita", - "設定する", - "활성화", - "Aktywuj", - "Ativar", - "Активировать", - "Etkinleştir", - "Активувати", - "Kích hoạt", - "启用" - ], - activated: [ - "Aktiviert", - "Diaktifkan", - "Activated", - "Activado", - "Activé", - "In uso", - "設定中", - "활성화 됨", - "Aktywowane", - "Ativado", - "Активирован", - "Etkin", - "Активований", - "Đã kích hoạt", - "已启用" - ], - active: [ - "Aktiv", - "Aktif", - "Active", - "Activo", - "Actif", - "Attivo", - "有効", - "활성화", - "Aktywny", - "Ativo", - "Активный", - "Etkin", - "Активний", - "Hoạt động", - "已启用" - ], - advanced: [ - "Erweitert", - "Lanjutan", - "Advanced", - "Avanzado", - "Options avancées", - "Avanzate", - "高度な設定", - "고급", - "Zaawansowane", - "Avançado", - "Продвинутые", - "Gelişmiş ayarlar", - "Розширені", - "Nâng cao", - "高级选项" - ], - "android-app-settings": [ - "Android App Einstellungen", - "Pengaturan aplikasi", - "Android app settings", - "Ajustes de la aplicación para Android", - "Paramètres de l’application Android", - "Impostazioni App Android", - "Androidアプリ設定", - "안드로이드 앱 설정", - , - "Configurações do aplicativo Android", - "Настройки приложения Android", - "Android uygulama ayarları", - "Налаштування програми Android", - "Thiết lập ứng dụng Android", - "安卓应用设置" - ], - apply: [ - "Anwenden", - "Terapkan", - "Apply", - "Aplicar", - "Appliquer", - "Applica", - "適用", - "적용", - "Zastosuj", - "Aplicar", - "Применить", - "Uygula", - "Застосувати", - "Áp dụng", - "应用" - ], - audio: [ - , - , - "Audio", - , - , - , - "音声", - "오디오", - "Dźwięk", - "Áudio", - "Звук", - "Ses", - "Звук", - "Âm thanh", - "音频" - ], - auto: [ - "Automatisch", - "Otomatis", - "Auto", - , - , - "Automatico", - "自動", - "자동", - "Automatyczne", - "Automático", - "Автоматически", - "Otomatik", - "Автоматично", - "Tự động", - "自动" - ], - "badge-audio": [ - , - , - "Audio", - , - , - , - "音声", - "오디오", - "Dźwięk", - "Áudio", - "Звук", - "Ses", - "Звук", - "Tiếng", - "音频" - ], - "badge-battery": [ - "Batterie", - "Baterai", - "Battery", - "Batería", - "Batterie", - "Batteria", - "バッテリー", - "배터리", - "Bateria", - "Bateria", - "Батарея", - "Pil", - "Батарея", - "Pin", - "电量" - ], - "badge-in": [ - "Empfangen", - "Masuk", - "In", - "Entrada", - "Dans", - "DL", - "IN", - "다운로드", - "Pobieranie", - "Recebidos", - "Входящие", - "Gelen", - "Завантаження", - "Nhận", - "下载" - ], - "badge-out": [ - "Gesendet", - "Keluar", - "Out", - "Salida", - "Sorti", - "UP", - "OUT", - "업로드", - "Wysyłanie", - "Enviados", - "Исходящие", - "Giden", - "Вивантаження", - "Gởi", - "上传" - ], - "badge-playtime": [ - "Spielzeit", - "Waktu bermain", - "Playtime", - "Tiempo jugado", - "Temps de jeu", - "In gioco da", - "プレイ時間", - "플레이한 시간", - "Czas gry", - "Tempo de jogo", - "Время в игре", - "Oynanış süresi", - "Час гри", - "Giờ chơi", - "游玩时间" - ], - "badge-server": [ - , - , - "Server", - "Servidor", - "Serveur", - , - "サーバー", - "서버", - "Serwer", - "Servidor", - "Сервер", - "Sunucu", - "Сервер", - "Máy chủ", - "服务器" - ], - "badge-video": [ - , - , - "Video", - , - "Vidéo", - , - "映像", - "비디오", - "Obraz", - "Vídeo", - "Видео", - "Görüntü", - "Відео", - "Hình", - "视频" - ], - "bitrate-audio-maximum": [ - "Maximale Audio-Bitrate", - "Bitrate Suara Tertinggi ", - "Maximum audio bitrate", - "Tasa de bits de audio máxima", - "Débit audio maximum", - "Bitrate massimo dell'audio", - "最大音声ビットレート", - "최대 오디오 비트레이트", - "Maksymalny bitrate dźwięku", - "Taxa máxima de bits de áudio", - "Максимальный битрейт аудио", - "Maksimum ses bithızı", - "Максимальна швидкість потоку аудіо", - "Bitrate tối đa của âm thanh", - "最大音频码率" - ], - "bitrate-video-maximum": [ - "Maximale Video-Bitrate", - "Bitrate Video Tertinggi ", - "Maximum video bitrate", - "Tasa de bits máxima de vídeo", - "Débit vidéo maximum", - "Bitrate massimo del video", - "最大映像ビットレート", - "최대 비디오 비트레이트", - "Maksymalny bitrate wideo", - "Taxa máxima de bits de vídeo", - "Максимальный битрейт видео", - "Maksimum görüntü bithızı", - "Максимальна швидкість потоку відео", - "Bitrate tối đa của hình ảnh", - "最大视频码率" - ], - "bottom-left": [ - "Unten links", - "Kiri bawah", - "Bottom-left", - "Inferior izquierdo", - "En bas à gauche", - "In basso a sinistra", - "左下", - "좌측 하단", - "Lewy dolny róg", - "Inferior esquerdo", - "Левый нижний угол", - "Sol alt", - "Внизу ліворуч", - "Phía dưới bên trái", - "左下角" - ], - "bottom-right": [ - "Unten rechts", - "Kanan bawah", - "Bottom-right", - "Inferior derecha", - "En bas à droite", - "In basso a destra", - "右下", - "우측 하단", - "Prawy dolny róg", - "Inferior direito", - "Правый нижний угол", - "Sağ alt", - "Внизу праворуч", - "Phía dưới bên phải", - "右下角" - ], - brightness: [ - "Helligkeit", - "Kecerahan", - "Brightness", - "Brillo", - "Luminosité", - "Luminosità", - "輝度", - "밝기", - "Jasność", - "Brilho", - "Яркость", - "Aydınlık", - "Яскравість", - "Độ sáng", - "亮度" - ], - "browser-unsupported-feature": [ - "Dein Browser unterstützt diese Funktion nicht", - "Browser anda tidak mendukung fitur ini", - "Your browser doesn't support this feature", - "Su navegador no soporta esta característica", - "Votre navigateur ne supporte pas cette fonctionnalité", - "Il tuo browser non supporta questa funzione", - "お使いのブラウザはこの機能をサポートしていません。", - "이 브라우저에서 이 기능을 지원하지 않습니다.", - "Twoja przeglądarka nie obsługuje tej funkcji", - "Seu navegador não suporta este recurso", - "Ваш браузер не поддерживает эту функцию", - "Web tarayıcınız bu özelliği desteklemiyor", - "Ваш браузер не підтримує цю функцію", - "Trình duyệt không hỗ trợ tính năng này", - "您的浏览器不支持此功能" - ], - "can-stream-xbox-360-games": [ - "Kann Xbox 360 Spiele streamen", - "Dapat melakukan stream game Xbox 360", - "Can stream Xbox 360 games", - "Puede transmitir juegos de Xbox 360", - "Vous pouvez jouer à des jeux Xbox 360", - "Puoi riprodurre i giochi Xbox 360", - "Xbox 360ゲームのストリーミング可能", - "Xbox 360 게임 스트림 가능", - "Można strumieniować gry Xbox 360", - "Pode transmitir jogos de Xbox 360", - "Позволяет транслировать Xbox 360 игры", - "Xbox 360 oyunlarına erişim sağlanabilir", - "Дозволяє транслювати ігри Xbox 360", - "Có thể stream các game Xbox 360", - "可以进行流式传输Xbox360游戏" - ], - cancel: [ - "Abbrechen", - "Batal", - "Cancel", - "Cancelar", - "Annuler", - "Annulla", - "キャンセル", - "취소", - "Anuluj", - "Cancelar", - "Отмена", - "Vazgeç", - "Скасувати", - "Hủy", - "取消" - ], - "cant-stream-xbox-360-games": [ - "Kann Xbox 360 Spiele nicht streamen", - "Tidak dapat melakukan stream game Xbox 360", - "Can't stream Xbox 360 games", - "No puede transmitir juegos de Xbox 360", - "Impossible de jouer à des jeux Xbox 360", - "Non puoi riprodurre giochi Xbox 360", - "Xbox 360ゲームのストリーミング不可", - "Xbox 360 게임 스트림 불가", - "Nie można strumieniować gier Xbox 360", - "Não pode transmitir jogos de Xbox 360", - "Невозможно транслировать игры Xbox 360", - "Xbox 360 oyunlarına erişim sağlanamaz", - "Не дозволяє транслювати ігри Xbox 360", - "Không thể stream các game Xbox 360", - "不可以进行流式传输Xbox360游戏" - ], - clarity: [ - "Klarheit", - "Kejernihan", - "Clarity", - "Claridad", - "Clarté", - "Nitidezza", - "明瞭度(クラリティ)", - "선명도", - "Ostrość", - "Nitidez", - "Чёткость", - "Netlik", - "Чіткість", - "Độ nét", - "清晰度" - ], - "clarity-boost-warning": [ - "Diese Einstellungen funktionieren nicht, wenn \"Clarity Boost\" aktiviert ist", - "Pengaturan ini tidak bekerja ketika mode \"Kejernihan Extra \" aktif", - "These settings don't work when the Clarity Boost mode is ON", - "Estos ajustes no funcionan cuando el modo Clarity Boost está activado", - "Ces paramètres ne fonctionnent pas lorsque le mode Clarity Boost est activé", - "Queste impostazioni non funzionano quando la modalità Clarity Boost è attiva", - "クラリティブーストが有効の場合、映像設定は無効化されます。", - "이 설정들은 선명도 향상 기능이 켜져 있을 때는 동작하지 않습니다.", - 'Te ustawienia nie będą działać, gdy tryb "Clarity Boost" jest włączony', - 'Estas configurações não funcionam quando o modo "Clarity Boost" está ATIVADO', - "Эти настройки не работают, когда включен режим Clarity Boost", - "Netliği Artırma modu açıkken bu ayarlar ETKİSİZDİR", - 'Ці налаштування не працюють, коли увімкнено режим "Clarity Boost"', - "Các tùy chỉnh này không hoạt động khi chế độ Clarity Boost đang được bật", - "这些设置在 Clarity Boost 清晰度增强 开启时不可用" - ], - clear: [ - "Zurücksetzen", - "Bersihkan", - "Clear", - "Borrar", - "Effacer", - "Pulisci", - "消去", - "비우기", - "Wyczyść", - "Limpar", - "Очистить", - "Temizle", - "Очистити", - "Xóa", - "清空" - ], - close: [ - "Schließen", - "Tutup", - "Close", - "Cerrar", - "Fermer", - "Chiudi", - "閉じる", - "닫기", - "Zamknij", - "Fechar", - "Закрыть", - "Kapat", - "Закрити", - "Đóng", - "关闭" - ], - "combine-audio-video-streams": [ - "Audio- und Video-Streams kombinieren", - "Gabung audio & video stream", - "Combine audio & video streams", - "Combinar flujos de audio y vídeo", - "Combiner les flux audio et vidéo", - "Combinare i flussi audio e video", - "音声を映像ストリーミングと統合", - "오디오 및 비디오 스트림 결합", - "Połącz strumienie audio i wideo", - "Combinar fluxos de áudio e vídeo", - "Объединить аудио и видео потоки", - "Ses ve görüntü akışını birleştir", - "Поєднайте аудіо та відео потоки", - "Hòa hợp nguồn của âm thanh và hình ảnh", - "合并视频音频流" - ], - "combine-audio-video-streams-summary": [ - "Könnte das Problem mit verzögertem Ton beheben", - "Mungkin memperbaiki masalah lag pada audio", - "May fix the laggy audio problem", - "Puede arreglar el problema de audio con retraso", - "Peut résoudre le problème de latence audio", - "Potrebbe risolvere il problema dell'audio irregolare", - "音声の遅延を改善できる可能性があります", - "오디오 지연 문제를 수정할 수도 있습니다", - "Może rozwiązać problem z zacinającym dźwiękiem", - "Pode corrigir o problema de áudio atrasado", - "Может исправить проблему подвисания звука", - "Sesteki gecikme sorununa çözüm olabilir", - "Може виправити проблему із затримкою звуку", - "Có thể sửa được lỗi trễ tiếng", - "有助于缓解音频延迟" - ], - "conditional-formatting": [ - "Zustandsabhängige Textfarbe", - "Pewarnaan Format teks kondisional", - "Conditional formatting text color", - "Color condicional de formato de texto", - "Couleur du texte de mise en forme conditionnelle", - "Colore testo formattazione condizionale", - "状態に応じた文字色で表示", - "통계에 따라 글자 색 지정", - "Kolor tekstu zależny od wartości", - "Cor do texto de formatação condicional", - "Цвет текста в зависимости от условий", - "Metin renginin koşullu biçimlendirilmesi", - "Колір тексту в залежності від умов", - "Thay đổi màu chữ tùy theo giá trị", - "更改文本颜色" - ], - "confirm-delete-preset": [ - "Möchtest Du diese Voreinstellung löschen?", - "Apakah anda yakin ingin menghapus preset ini?", - "Do you want to delete this preset?", - "¿Desea eliminar este preajuste?", - "Voulez-vous supprimer ce préréglage?", - "Vuoi eliminare questo profilo?", - "このプリセットを削除しますか?", - "이 프리셋을 삭제하시겠습니까?", - "Czy na pewno chcesz usunąć ten szablon?", - "Você quer excluir esta predefinição?", - "Вы точно хотите удалить этот шаблон?", - "Bu hazır ayarı silmek istiyor musunuz?", - "Ви бажаєте видалити цей пресет?", - "Bạn có muốn xoá thiết lập sẵn này không?", - "您想要删除此预设吗?" - ], - "confirm-reload-stream": [ - "Möchtest Du den Stream aktualisieren?", - "Apakah anda ingin memuat ulang stream?", - "Do you want to refresh the stream?", - `¿Quieres actualizar el stream? -`, - "Voulez-vous actualiser le stream ?", - "Vuoi aggiornare lo stream?", - "ストリーミングをリフレッシュしますか?", - "스트리밍을 재시작할까요?", - "Czy chcesz odświeżyć transmisję?", - "Você deseja atualizar a transmissão?", - "Вы хотите перезапустить поток?", - "Yayını yeniden başlatmak istiyor musunuz?", - "Бажаєте оновити трансляцію?", - "Bạn có muốn kết nối lại stream không?", - "您想要刷新吗?" - ], - connected: [ - "Verbunden", - "Tersambung", - "Connected", - "Conectado", - "Connecté", - "Connesso", - "接続済み", - "연결됨", - "Połączony", - "Conectado", - "Подключен", - "Bağlı", - "Під’єднано", - "Đã kết nối", - "已连接" - ], - "console-connect": [ - "Verbinden", - "Sambungkan", - "Connect", - "Conectar", - "Se connecter", - "Connetti", - "本体に接続", - "콘솔 연결", - "Połącz", - "Conectar", - "Подключиться", - "Bağlan", - "Під’єднатися", - "Kết nối", - "连接" - ], - contrast: [ - "Kontrast", - "Kontras", - "Contrast", - "Contraste", - "Contraste", - "Contrasto", - "コントラスト", - "대비", - "Kontrast", - "Contraste", - "Контрастность", - "Karşıtlık", - "Контрастність", - "Độ tương phản", - "对比度" - ], - controller: [ - , - "Kontroler", - "Controller", - "Joystick", - "Manette", - , - "コントローラー", - "컨트롤러", - "Kontroler", - "Controle", - "Контроллер", - "Oyun Kumandası", - "Контролер", - "Bộ điều khiển", - "手柄" - ], - "controller-shortcuts": [ - "Controller-Shortcuts", - "Pintasan kontroler", - "Controller shortcuts", - "Habilitar atajos del Joystick", - "Raccourcis de la manette", - "Abilita scrociatorie da controller", - "コントローラーショートカット", - "컨트롤러 단축키", - "Skróty kontrolera", - "Atalhos do controle", - "Горячие клавиши контроллера", - "Oyun kumandası kısayolları", - "Ярлики контролера", - "Các phím tắt tay cầm", - "手柄快捷键" - ], - "controller-vibration": [ - "Vibration des Controllers", - "Getaran kontroler", - "Controller vibration", - "Vibración del mando", - "Vibration de la manette", - "Vibrazione del controller", - "コントローラーの振動", - "컨트롤러 진동", - "Wibracje kontrolera", - "Vibração do controle", - "Вибрация контроллера", - "Oyun kumandası titreşimi", - "Вібрація контролера", - "Rung bộ điều khiển", - "控制器振动" - ], - copy: [ - "Kopieren", - "Salin", - "Copy", - "Copiar", - "Copier", - "Duplica", - "コピー", - "복사", - "Kopiuj", - "Copiar", - "Скопировать", - "Kopyala", - "Копіювати", - "Sao chép", - "复制" - ], - custom: [ - "Benutzerdefiniert", - "Kustom", - "Custom", - "Personalizado", - "Personnalisée", - "Personalizzato", - "カスタム", - "사용자 지정", - "Niestandardowe", - "Personalizado", - "Вручную", - "Özel", - "Користувацькі", - "Tùy chỉnh", - "自定义" - ], - "deadzone-counterweight": [ - "Deadzone Gegengewicht", - "Pengimbang deadzone", - "Deadzone counterweight", - "Contrapeso de la zona muerta", - "Compenser la zone morte", - "Compensazione della zona morta", - "デッドゾーンのカウンターウエイト", - "데드존 반동제어", - "Przeciwwaga martwej strefy", - "Contrapeso de zona morta", - "Противодействие мертвой зоне игры", - "Ölü alan denge ağırlığı", - "Противага Deadzone", - "Đối trọng vùng chết", - "死区补偿" - ], - default: [ - "Standard", - "Bawaan", - "Default", - "Por defecto", - "Par défaut", - "Predefinito", - "デフォルト", - "기본값", - "Domyślny", - "Padrão", - "По умолчанию", - "Varsayılan", - "За замовчуванням", - "Mặc định", - "默认" - ], - delete: [ - "Löschen", - "Hapus", - "Delete", - "Borrar", - "Supprimer", - "Elimina", - "削除", - "삭제", - "Usuń", - "Deletar", - "Удалить", - "Sil", - "Видалити", - "Xóa", - "删除" - ], - "device-unsupported-touch": [ - "Dein Gerät hat keine Touch-Unterstützung", - "Perangkat anda tidak mendukung sentuhan Layar", - "Your device doesn't have touch support", - "Tu dispositivo no tiene soporte táctil", - "Votre appareil n'a pas de support tactile", - "Il tuo dispositivo non supporta i comandi su schermo", - "お使いのデバイスはタッチ機能をサポートしていません。", - "이 장치에서 터치 기능을 지원하지 않습니다.", - "Twoje urządzenie nie obsługuję tej funkcji", - "Seu dispositivo não possui suporte de toque", - "Ваше устройство не поддерживает сенсорное управление", - "Cihazınızda dokunmatik ekran özelliği yoktur", - "Ваш пристрій не має підтримки сенсорного керування", - "Thiết bị này không hỗ trợ cảm ứng", - "您的设备不支持触摸" - ], - "device-vibration": [ - "Vibration des Geräts", - "Getaran perangkat", - "Device vibration", - "Vibración del dispositivo", - "Vibration de l'appareil", - "Vibrazione del dispositivo", - "デバイスの振動", - "기기 진동", - "Wibracje urządzenia", - "Vibração do dispositivo", - "Вибрация устройства", - "Cihaz titreşimi", - "Вібрація пристрою", - "Rung thiết bị", - "设备振动" - ], - "device-vibration-not-using-gamepad": [ - "An, wenn kein Gamepad verbunden", - "Aktif ketika tidak menggunakan gamepad", - "On when not using gamepad", - "Activado cuando no se utiliza el mando", - "Activé lorsque vous n'utilisez pas de manette", - "Abilita quando non si usa un gamepad", - "ゲームパッド未使用時にオン", - "게임패드를 사용하지 않을 때", - "Włączone, gdy nie używasz kontrolera", - "Ativar quando não estiver usando o dispositivo", - "Включить когда не используется геймпад", - "Oyun kumandası bağlanmadan titreşim", - "Увімкнена, коли не використовується геймпад", - "Bật khi không dùng tay cầm", - "当不使用游戏手柄时" - ], - disable: [ - "Deaktiviert", - "Menonaktifkan", - "Disable", - "Deshabilitar", - "Désactiver", - "Disabilita", - "無効", - "비활성화", - "Wyłącz", - "Desabilitar", - "Отключить", - "Devre dışı bırak", - "Вимкнути", - "Vô hiệu hóa", - "禁用" - ], - "disable-home-context-menu": [ - , - , - "Disable context menu in Home page", - , - , - "Disabilita il menu contestuale nella Home page", - "ホームページでコンテキストメニューを無効化", - "홈페이지에서 상황별 팝업메뉴 비활성화", - , - , - , - , - "Вимкнути контекстне меню на Домашній сторінці", - "Tắt menu ngữ cảnh trên Trang chủ", - "在主页禁用快捷菜单" - ], - "disable-native-mkb": [ - "Native Maus- & Tastaturunterstützung deaktivieren", - "Matikan Mouse & Keyboard bawaan", - "Disable native Mouse & Keyboard feature", - "Desactivar función nativa de ratón y teclado", - "Désactiver la fonction native Souris et Clavier", - "Disabilita il supporto nativo per Mouse e Tastiera", - "ネイティブ版マウス&キーボードの機能を無効化", - "마우스 및 키보드 공식지원 기능 비활성화", - "Wyłącz funkcję natywnej obsługi myszki i klawiatury", - "Desabilitar recurso nativo do Mouse e Teclado", - , - "Yerleşik klavye ve fare özelliğini kapat", - "Вимкнути функцію рідної миші та клавіатури", - "Tắt tính năng Chuột và Bàn phím chính thức", - "禁用原生键鼠支持" - ], - "disable-post-stream-feedback-dialog": [ - "Feedback-Dialog beim Beenden deaktivieren", - "Matikan umpan balik dialog pasca-stream", - "Disable post-stream feedback dialog", - "Desactivar diálogo de retroalimentación post-stream", - "Désactiver la boîte de dialogue de commentaires post-stream", - "Disabilita la finestra di feedback al termine dello stream", - "ストリーミング終了後のフィードバック画面を非表示", - "스트림 후 품질 조사요청 비활성화", - "Wyłącz okno opinii po zakończeniu transmisji", - "Desativar o diálogo de comentários pós-transmissão", - "Отключить диалог обратной связи после стрима", - "Yayın sonrası geribildirim ekranını kapat", - "Відключити діалогове вікно зворотного зв’язку після трансляції", - "Tắt hộp thoại góp ý sau khi chơi xong", - "禁用反馈问卷" - ], - "disable-social-features": [ - "Soziale Funktionen deaktivieren", - "Matikan fitur social", - "Disable social features", - "Desactivar características sociales", - "Désactiver les fonctionnalités sociales", - "Disabilita le funzioni social", - "ソーシャル機能を無効", - "소셜 기능 비활성화", - "Wyłącz funkcje społecznościowe", - "Desativar recursos sociais", - "Отключить социальные функции", - "Sosyal özellikleri kapat", - "Вимкнути соціальні функції", - "Khóa các tính năng xã hội", - "禁用社交功能" - ], - "disable-xcloud-analytics": [ - "xCloud-Datenanalyse deaktivieren", - "Matikan analisis xCloud", - "Disable xCloud analytics", - "Desactivar análisis de xCloud", - "Désactiver les analyses xCloud", - "Disabilita l'analitica di xCloud", - "xCloudアナリティクスを無効", - "xCloud 통계 비활성화", - "Wyłącz analitykę xCloud", - "Desativar telemetria do xCloud", - "Отключить аналитику xCloud", - "xCloud'un veri toplamasını devre dışı bırak", - "Вимкнути аналітику xCloud", - "Khóa phân tích thông tin của xCloud", - "关闭 xCloud 遥测数据统计" - ], - disabled: [ - "Deaktiviert", - "Dinonaktifkan", - "Disabled", - "Desactivado", - "Désactivé", - "Disattivato", - "無効", - "비활성화됨", - "Wyłączony", - "Desativado", - "Отключено", - "Kapalı", - "Вимкнено", - "Đã tắt", - "禁用" - ], - disconnected: [ - "Getrennt", - "Terputus", - "Disconnected", - "Desconectado", - "Déconnecté", - "Disconnesso", - "切断", - "연결 끊김", - "Rozłączony", - "Desconectado", - "Отключен", - "Bağlı değil", - "Від'єднано", - "Đã ngắt kết nối", - "已断开连接" - ], - edit: [ - "Bearbeiten", - , - "Edit", - "Editar", - "Modifier", - "Modifica", - "編集", - "편집", - "Edytuj", - "Editar", - "Редактировать", - "Düzenle", - "Редагувати", - "Sửa", - "编辑" - ], - "enable-controller-shortcuts": [ - "Controller-Shortcuts aktivieren", - "Nyalakan pintas kontroler", - "Enable controller shortcuts", - "Habilitar accesos directos del Joystick", - "Activer les raccourcis de la manette", - "Consenti scorciatoie da controller", - "コントローラーショートカットを有効化", - "컨트롤러 단축키 활성화", - "Włącz skróty kontrolera", - "Ativar atalhos do controle", - "Включить быстрые клавиши контроллера", - "Oyun kumandası kısayollarını aç", - "Увімкнути ярлики контролера", - "Bật tính năng phím tắt cho bộ điều khiển", - "启用手柄快捷方式" - ], - "enable-local-co-op-support": [ - "Lokale Koop-Unterstützung aktivieren", - "Nyalakan dukungan mode lokal co-op", - "Enable local co-op support", - "Habilitar soporte co-op local", - "Activer le support du co-op local", - "Abilita supporto cooperativo locale", - "ローカルマルチプレイのサポートを有効化", - "로컬 협동 지원 활성화", - "Włącz lokalny co-op", - "Habilitar o suporte a co-op local", - "Включить поддержку локальной кооперативной игры", - "Yerel çok oyuncu desteğini aktive et", - "Увімкнути локальну co-op підтримку", - "Kích hoạt tính năng chơi chung cục bộ", - "启用本地多人联机" - ], - "enable-local-co-op-support-note": [ - "Funktioniert nur, wenn das Spiel kein anderes Profil benötigt", - "Hanya berfungsi saat permainan tidak membutuhkan profil berbeda", - "Only works if the game doesn't require a different profile", - "Solo funciona si el juego no requiere un perfil diferente", - "Ne fonctionne que si le jeu ne nécessite pas un profil différent", - "Funziona quando il gioco non richiede un profilo differente", - "別アカウントでのサインインを必要としないゲームのみ動作します", - "게임에서 다른 프로필을 지원하지 않을때만 동작", - "Działa tylko wtedy, gdy gra nie wymaga innego profilu", - "Só funciona se o jogo não exigir um perfil diferente", - "Работает только в том случае, если игра не требует другого профиля", - "Bu seçenek ancak oyun ayrı profillere giriş yapılmasını istemiyorsa etki eder", - "Працює, лише якщо для гри не потрібен інший профіль", - "Chỉ hoạt động nếu game không yêu cầu thêm tài khoản khác", - "仅在当前游戏不要求切换账户时才能使用" - ], - "enable-mic-on-startup": [ - "Mikrofon bei Spielstart aktivieren", - "Nyalakan mikrofon saat permainan diluncurkan", - "Enable microphone on game launch", - "Activar micrófono al iniciar el juego", - "Activer le microphone lors du lancement du jeu", - "Abilita il microfono all'avvio del gioco", - "ゲーム起動時にマイクを有効化", - "게임 시작 시 마이크 활성화", - "Włącz mikrofon przy uruchomieniu gry", - "Ativar microfone ao iniciar um jogo", - "Автоматически включать микрофон при запуске игры", - "Oyun başlarken mikrofonu aç", - "Увімкнути мікрофон при запуску гри", - "Bật mic lúc vào game", - "游戏启动时打开麦克风" - ], - "enable-mkb": [ - "Controller mit Maus & Tastatur emulieren", - "Tirukan kontroler menggunakan Mouse & Keyboard", - "Emulate controller with Mouse & Keyboard", - "Emular mandos con teclado y ratón", - "Émuler la manette avec la souris et le clavier", - "Abilita il supporto per mouse e tastiera", - "マウス&キーボード操作をコントローラー化", - "마우스 및 키보드를 컨트롤러로 에뮬레이트", - "Emuluj kontroler za pomocą myszy i klawiatury", - "Emular controlador com mouse e teclado", - "Эмулировать контроллер с помощью мыши и клавиатуры", - "Klavye ve fareyle oyun kumandasını taklit et", - "Емуляція контролера за допомогою миші та клавіатури", - "Giả lập tay cầm bằng Chuột và Bàn phím", - "使用键鼠模拟手柄输入" - ], - "enable-quick-glance-mode": [ - "\"Kurzer Blick\"-Modus aktivieren", - "Aktifkan mode \"Quick Glance\"", - "Enable \"Quick Glance\" mode", - 'Activar modo "Vista rápida"', - 'Activer le mode "Aperçu rapide"', - "Abilita la modalità Quick Glance", - "クイック確認モードを有効化", - '"퀵 글랜스" 모드 활성화', - 'Włącz tryb "Quick Glance"', - "Ativar modo \"Relance\"", - "Включить режим «Быстрый взгляд»", - '"Seri Bakış" modunu aç', - 'Увімкнути режим "Quick Glance"', - 'Bật chế độ "Xem nhanh"', - "仅在打开设置时显示统计信息" - ], - "enable-remote-play-feature": [ - "\"Remote Play\" Funktion aktivieren", - "Nyalakan fitur \"Remote Play\"", - "Enable the \"Remote Play\" feature", - 'Activar la función "Reproducción remota"', - 'Activer la fonction "Jeu à distance"', - "Abilitare la funzione \"Riproduzione Remota\"", - "リモートプレイ機能を有効化", - '"리모트 플레이" 기능 활성화', - 'Włącz funkcję "Gra zdalna"', - 'Ativar o recurso "Reprodução Remota"', - "Включить функцию «Удаленная игра»", - '"Uzaktan Oynama" özelliğini aktive et', - 'Увімкнути функцію "Remote Play"', - 'Bật tính năng "Chơi Từ Xa"', - '启用"Remote Play"主机串流' - ], - "enable-volume-control": [ - "Lautstärkeregelung aktivieren", - "Nyalakan fitur kontrol volume", - "Enable volume control feature", - "Habilitar la función de control de volumen", - "Activer la fonction de contrôle du volume", - "Abilità controlli volume", - "音量調節機能を有効化", - "음량 조절 기능 활성화", - "Włącz funkcję kontroli głośności", - "Ativar recurso de controle de volume", - "Включить управление громкостью", - "Ses düzeyini yönetmeyi etkinleştir", - "Увімкнути функцію керування гучністю", - "Bật tính năng điều khiển âm lượng", - "启用音量控制" - ], - enabled: [ - "Aktiviert", - "Diaktifkan", - "Enabled", - "Activado", - "Activé", - "Attivato", - "有効", - "활성화됨", - "Włączony", - "Ativado", - "Включено", - "Açık", - "Увімкнено", - "Đã bật", - "启用" - ], - experimental: [ - "Experimentell", - "Eksperimental", - "Experimental", - , - "Expérimental", - "Sperimentale", - "実験的機能", - "실험실", - "Eksperymentalne", - , - "Экспериментально", - "Deneme aşamasında", - "Експериментальне", - "Thử nghiệm", - "实验性功能" - ], - export: [ - "Exportieren", - "Ekspor", - "Export", - "Exportar", - "Exporter", - "Esporta", - "エクスポート(書出し)", - "내보내기", - "Eksportuj", - "Exportar", - "Экспортировать", - "Dışa aktar", - "Експорт", - "Xuất", - "导出" - ], - fast: [ - "Schnell", - "Cepat", - "Fast", - "Rápido", - "Rapide", - "Veloce", - "高速", - "빠름", - "Szybko", - "Rápido", - "Быстрый", - "Hızlı", - "Швидкий", - "Nhanh", - "快速" - ], - "fortnite-allow-stw-mode": [ - 'Erlaubt das Spielen im "STW"-Modus auf Mobilgeräten', - "Aktikan mode STW", - "Allows playing STW mode on mobile", - "Permitir jugar al modo STW en el móvil", - "Autoriser le mode STW sur mobile", - "Consente di riprodurre la modalità Salva il Mondo sul cellulare", - "モバイル版で「世界を救え」をプレイできるようになります", - "모바일에서 포트나이트 STW모드 플레이 허용", - "Zezwól na granie w tryb STW na urządzeniu mobilnym", - "Permitir a reprodução do modo STW no celular", - "Позволяет играть в режиме STW на мобильных устройствах", - "Mobil cihazda Fortnite: Dünyayı Kurtar modunu etkinleştir", - "Дозволити відтворення режиму STW на мобільному пристрої", - "Cho phép chơi chế độ STW trên điện thoại", - "允许游玩Save the World模式" - ], - "fortnite-force-console-version": [ - "Fortnite: Erzwinge Konsolenversion", - "Fortnite: Paksa versi konsol", - "Fortnite: force console version", - "Fortnite: forzar versión de consola", - "Fortnite : Forcer la version console", - "Fortnite: forza la versione console", - "Fortnite: 強制的にコンソール版を起動する", - "포트나이트: 콘솔 버전 강제", - "Fortnite: wymuś wersję konsolową", - "Fortnite: forçar versão para console", - "Fortnite: форсированная консольная версия", - "Fortnite'ın konsol sürümünü aç", - "Fortnite: примусова консольна версія", - "Fortnite: bắt buộc phiên bản console", - "Fortnite: 强制使用主机版客户端" - ], - "game-bar": [ - , - , - "Game Bar", - , - , - , - , - "게임 바" - ], - "getting-consoles-list": [ - "Rufe Liste der Konsolen ab...", - "Mendapatkan daftar konsol...", - "Getting the list of consoles...", - "Obteniendo la lista de consolas...", - "Récupération de la liste des consoles...", - "Ottengo la lista delle console...", - "本体のリストを取得中...", - "콘솔 목록 불러오는 중...", - "Pobieranie listy konsoli...", - "Obtendo a lista de consoles...", - "Получение списка консолей...", - "Konsol listesine erişiliyor...", - "Отримання списку консолей...", - "Đang lấy danh sách các console...", - "正在获取控制台列表..." - ], - help: [ - "Hilfe", - "Bantuan", - "Help", - "Ayuda", - "Aide", - "Guida", - "ヘルプ", - "도움말", - "Pomoc", - "Ajuda", - "Справка", - "Yardım", - "Довідка", - "Trợ giúp", - "帮助" - ], - "hide-idle-cursor": [ - "Mauszeiger bei Inaktivität ausblenden", - "Sembunyikan kursor mouse saat tidak digunakan", - "Hide mouse cursor on idle", - "Ocultar el cursor del ratón al estar inactivo", - "Masquer le curseur de la souris", - "Nascondi il cursore previa inattività", - "マウスカーソルを3秒間動かしていない場合に非表示", - "대기 상태에서 마우스 커서 숨기기", - "Ukryj kursor myszy podczas bezczynności", - "Ocultar o cursor do mouse quando ocioso", - "Скрыть курсор мыши при бездействии", - "Boştayken fare imlecini gizle", - "Приховати курсор при очікуванні", - "Ẩn con trỏ chuột khi không di chuyển", - "空闲时隐藏鼠标" - ], - "hide-scrollbar": [ - "Scrollbalken der Webseite ausblenden", - "Sembunyikan bilah gulir halaman", - "Hide web page's scrollbar", - "Oculta la barra de desplazamiento de la página", - "Masquer la barre de défilement de la page web", - "Nascondi la barra di scorrimento della pagina web", - "Webページのスクロールバーを隠す", - "웹 페이지 스크롤 바 숨기기", - "Ukryj pasek przewijania strony", - "Ocultar a barra de rolagem da página", - "Скрыть полосу прокрутки страницы", - "Yandaki kaydırma çubuğunu gizle", - "Приховати смугу прокрутки вебсторінок", - "Ẩn thanh cuộn của trang web", - "隐藏浏览器滚动条" - ], - "hide-system-menu-icon": [ - "Symbol des System-Menüs ausblenden", - "Sembunyikan ikon menu sistem", - "Hide System menu's icon", - "Ocultar el icono del menú del sistema", - "Masquer l'icône du menu système", - "Nascondi icona del menu a tendina", - "システムメニューのアイコンを非表示", - "시스템 메뉴 아이콘 숨기기", - "Ukryj ikonę menu systemu", - "Ocultar ícone do menu do Sistema", - "Скрыть значок системного меню", - "Sistem menüsü simgesini gizle", - "Приховати іконку системного меню", - "Ẩn biểu tượng của menu Hệ thống", - "隐藏系统菜单图标" - ], - "hide-touch-controller": [ - "Touch-Controller ausblenden", - "Sembunyikan kontrol sentuh", - "Hide touch controller", - "Ocultar controles táctiles", - "Masquer les commandes tactiles", - "Nascondi il Controller Touch", - "タッチコントローラーを隠す", - "터치 컨트롤러 숨기기", - "Ukryj sterowanie dotykowe", - "Ocultar controles por toque", - "Скрыть сенсорный контроллер", - "Dokunmatik kontrolleri gizle", - "Приховати сенсорний контролер", - "Ẩn bộ điều khiển cảm ứng", - "隐藏虚拟按键" - ], - "horizontal-sensitivity": [ - "Horizontale Empfindlichkeit", - "Sensitifitas horizontal", - "Horizontal sensitivity", - "Sensibilidad horizontal", - "Sensibilité horizontale", - "Sensibilità orizzontale", - "左右方向の感度", - "수평 민감도", - "Czułość pozioma", - "Sensibilidade horizontal", - "Горизонтальная чувствительность", - "Yatay hassasiyet", - "Горизонтальна чутливість", - "Độ nhạy ngang", - "水平灵敏度" - ], - import: [ - "Importieren", - "Impor", - "Import", - "Importar", - "Importer", - "Importa", - "インポート(読込み)", - "가져오기", - "Importuj", - "Importar", - "Импортировать", - "İçeri aktar", - "Імпорт", - "Nhập", - "导入" - ], - "install-android": [ - '"Better xCloud" App für Android installieren', - "Pasang aplikasi Better xCloud untuk Android", - "Install Better xCloud app for Android", - "Instale la aplicación Better xCloud para Android", - "Installer l'application Better xCloud pour Android", - "Installa l'applicazione Better xCloud per Android", - "Android用のBetter xCloudをインストール", - "안드로이드용 Better xCloud 앱 설치", - "Zainstaluj aplikację Better xCloud na Androida", - "Instalar o aplicativo Better xCloud para Android", - "Установите приложение Better xCloud для Android", - "Better xCloud'un Android uygulamasını indir", - "Встановити додаток Better xCloud для Android", - "Cài đặt ứng dụng Better xCloud cho Android", - "安装Better xCloud安卓客户端" - ], - "keyboard-shortcuts": [ - "Tastatur-Shortcuts", - "Pintasan keyboard", - "Keyboard shortcuts", - "Atajos del teclado", - "Raccourcis clavier", - "Scorciatoie da tastiera", - "キーボードショートカット", - "키보드 단축키", - "Skróty klawiszowe", - "Atalhos do teclado", - "Горячие клавиши", - "Klavye kısayolları", - "Комбінації клавіш", - "Các phím tắt bàn phím", - "键盘快捷键" - ], - language: [ - "Sprache", - "Bahasa", - "Language", - "Idioma", - "Langue", - "Lingua", - "言語", - "언어", - "Język", - "Idioma", - "Язык", - "Dil", - "Мова", - "Ngôn ngữ", - "切换语言" - ], - large: [ - "Groß", - "Besar", - "Large", - "Grande", - "Grande", - "Grande", - "大", - "크게", - "Duży", - "Grande", - "Большой", - "Büyük", - "Великий", - "Lớn", - "大" - ], - layout: [ - , - "Tata letak", - "Layout", - "Diseño", - "Disposition", - , - "レイアウト", - "레이아웃", - "Układ", - , - "Расположение", - "Arayüz Görünümü", - "Розташування", - "Bố cục", - "布局" - ], - "left-stick": [ - "Linker Stick", - "Stik kiri", - "Left stick", - "Joystick izquierdo", - "Stick gauche", - "Levetta sinistra", - "左スティック", - "왼쪽 스틱", - "Lewy drążek analogowy", - "Direcional analógico esquerdo", - "Левый стик", - "Sol analog çubuk", - "Лівий стік", - "Analog trái", - "左摇杆" - ], - "loading-screen": [ - "Ladebildschirm", - "Pemuatan layar", - "Loading screen", - "Pantalla de carga", - "Écran de chargement", - "Schermata di caricamento", - "ロード画面", - "로딩 화면", - "Ekran wczytywania", - "Tela de carregamento", - "Экран загрузки", - "Yükleme ekranı", - "Екран завантаження", - "Màn hình chờ", - "载入画面" - ], - "local-co-op": [ - "Lokales Koop", - "Lokal co-op", - "Local co-op", - "Co-op local", - "Co-op local", - "Cooperativa locale", - "ローカルマルチプレイ", - "로컬 협동", - "Lokalna kooperacja", - "Co-op local", - "Локальная кооперативная игра", - "Yerel çoklu oyunculu", - "Локальний co-op", - "Chơi chung cục bộ", - "本地多人联机" - ], - "map-mouse-to": [ - "Maus binden an", - "Petakan mouse ke", - "Map mouse to", - "Mapear ratón a", - "Mapper la souris à", - "Usa il mouse come", - "マウスの割り当て", - "마우스를 다음에 할당", - "Przypisz myszkę do", - "Mapear o mouse para", - "Наведите мышку на", - "Fareyi ata", - "Прив'язати мишу до", - "Gán chuột với", - "将鼠标映射到" - ], - "may-not-work-properly": [ - "Funktioniert evtl. nicht fehlerfrei!", - "Mungkin tidak berfungsi dengan baik!", - "May not work properly!", - "¡Puede que no funcione correctamente!", - "Peut ne pas fonctionner correctement !", - "Potrebbe non funzionare correttamente!", - "正常に動作しない場合があります!", - "제대로 작동하지 않을 수 있음!", - "Może nie działać poprawnie!", - "Pode não funcionar corretamente!", - "Может работать некорректно!", - "Düzgün çalışmayabilir!", - "Може працювати некоректно!", - "Có thể không hoạt động!", - "可能无法正常工作!" - ], - "menu-stream-settings": [ - "Stream Einstellungen", - "Pengaturan streaming", - "Stream settings", - "Ajustes del stream", - "Réglages Stream", - "Impostazioni dello stream", - "ストリーミング設定", - "스트리밍 설정", - "Ustawienia strumienia", - "Ajustes de transmissão", - "Настройки потоковой передачи", - "Yayın ayarları", - "Налаштування трансляції", - "Cấu hình stream", - "串流设置" - ], - "menu-stream-stats": [ - "Stream Statistiken", - "Statistik stream", - "Stream stats", - "Estadísticas del stream", - "Statistiques du stream", - "Statistiche dello stream", - "ストリーミング統計情報", - "통계", - "Statystyki strumienia", - "Estatísticas da transmissão", - "Статистика стрима", - "Yayın durumu", - "Статистика трансляції", - "Thông số stream", - "串流统计数据" - ], - microphone: [ - "Mikrofon", - "Mikrofon", - "Microphone", - "Micrófono", - , - "Microfono", - "マイク", - "마이크", - "Mikrofon", - "Microfone", - "Микрофон", - "Mikrofon", - "Мікрофон", - "Micro", - "麦克风" - ], - "mkb-adjust-ingame-settings": [ - "Vielleicht müssen auch Empfindlichkeit & Deadzone in den Spieleinstellungen angepasst werden", - "Anda mungkin butuh untuk menyesuaikan pengaturan sensitivitas & deadzone dalam permainan", - "You may also need to adjust the in-game sensitivity & deadzone settings", - "También puede que necesites ajustar la sensibilidad del juego y la configuración de la zona muerta", - "Vous pouvez également avoir besoin de régler les paramètres de sensibilité et de zone morte en jeu", - "Potrebbe anche essere necessario regolare le impostazioni della sensibilità e deadzone del gioco", - "ゲーム内の設定で感度とデッドゾーンの調整が必要な場合があります", - "게임 내 민감도 및 데드존 설정을 조정해야 할 수도 있습니다", - "Może być również konieczne dostosowanie czułości w grze i ustawienia 'martwej strefy' urządzenia", - "Você talvez também precise ajustar as configurações de sensibilidade e zona morta no jogo", - "Также может потребоваться изменить настройки чувствительности и мертвой зоны в игре", - "Bu seçenek etkinken bile oyun içi seçeneklerden hassasiyet ve ölü bölge ayarlarını düzeltmeniz gerekebilir", - "Можливо, вам також доведеться регулювати чутливість і deadzone у параметрах гри", - "Có thể bạn cần phải điều chỉnh các thông số độ nhạy và điểm chết trong game", - "您可能还需要调整游戏内的灵敏度和死区设置" - ], - "mkb-click-to-activate": [ - "Klicken zum Aktivieren", - "Klik untuk mengaktifkan", - "Click to activate", - "Haz clic para activar", - "Cliquez pour activer", - "Fare clic per attivare", - "マウスクリックで開始", - "클릭해서 활성화", - "Kliknij, aby aktywować", - "Clique para ativar", - "Нажмите, чтобы активировать", - "Etkinleştirmek için tıklayın", - "Натисніть, щоб активувати", - "Nhấn vào để kích hoạt", - "单击以启用" - ], - "mkb-disclaimer": [ - "Das Nutzen dieser Funktion beim Online-Spielen könnte als Betrug angesehen werden", - "Mengaktifkan fitur ini saat bermain online akan dianggap curang", - "Using this feature when playing online could be viewed as cheating", - "Usar esta función al jugar en línea podría ser visto como trampas", - "L'utilisation de cette fonctionnalité lors du jeu en ligne pourrait être considéré comme de la triche", - "L'utilizzo di questa funzione quando si gioca online potrebbe essere considerato come barare", - "オンラインプレイでこの機能を使用すると不正行為と判定される可能性があります", - "이 기능을 사용한다면 온라인 플레이시 부정행위로 보여질 수 있습니다", - "Używanie tej funkcji podczas grania online może być postrzegane jako oszukiwanie", - "Usar esta função em jogos online pode ser considerado como uma forma de trapaça", - "Использование этой функции при игре онлайн может рассматриваться как читерство", - "Bu özellik çevrimiçi oyunlarda sizi hile yapıyormuşsunuz gibi gösterebilir", - "Використання цієї функції під час гри онлайн може розглядатися як шахрайство", - "Sử dụng tính năng này khi chơi trực tuyến có thể bị xem là gian lận", - "游玩在线游戏时,使用此功能可能被视为作弊。" - ], - "mouse-and-keyboard": [ - "Maus & Tastatur", - , - "Mouse & Keyboard", - "Ratón y teclado", - "Souris et clavier", - "Mouse e tastiera", - "マウス&キーボード", - "마우스 & 키보드", - "Mysz i klawiatura", - "Mouse e Teclado", - "Мышь и клавиатура", - "Klavye ve Fare", - "Миша та клавіатура", - "Chuột và Bàn phím", - "鼠标和键盘" - ], - muted: [ - "Stumm", - "Bisukan", - "Muted", - "Silenciado", - "Son désactivé", - "Microfono disattivato", - "ミュート", - "음소거", - "Wyciszony", - "Mudo", - "Выкл микрофон", - "Kapalı", - "Без звуку", - "Đã tắt âm", - "静音" - ], - name: [ - , - "Nama", - "Name", - "Nombre", - "Nom", - "Nome", - "名前", - "이름", - "Nazwa", - "Nome", - "Имя", - "İsim", - "Назва", - "Tên", - "名称" - ], - new: [ - "Neu", - "Baru", - "New", - "Nuevo", - "Nouveau", - "Nuovo", - "新しい", - "새로 만들기", - "Nowy", - "Novo", - "Создать", - "Yeni", - "Новий", - "Tạo mới", - "新建" - ], - "no-consoles-found": [ - "Keine Konsolen gefunden", - "Tidak ditemukan konsol", - "No consoles found", - "No se encontraron consolas", - "Aucune console trouvée", - "Nessuna console trovata", - "本体が見つかりません", - "콘솔을 찾을 수 없음", - "Nie znaleziono konsoli", - "Nenhum console encontrado", - "Консолей не найдено", - "Konsol bulunamadı", - "Не знайдено консолі", - "Không tìm thấy console nào", - "未找到主机" - ], - normal: [ - , - , - "Normal", - , - , - "Normale", - "標準", - "보통", - "Normalny", - , - "Средний", - , - "Нормальний", - "Thường", - "中" - ], - off: [ - "Aus", - "Mati", - "Off", - "Apagado", - "Désactivé", - "Disattivato", - "オフ", - "꺼짐", - "Wyłączone", - "Desligado", - "Выключен", - "Kapalı", - "Вимкнено", - "Tắt", - "关" - ], - on: [ - "An", - "Hidup", - "On", - "Activado", - "Activé", - "Attivo", - "オン", - "켜짐", - "Włącz", - "Ativado", - "Вкл", - "Açık", - "Увімкнено", - "Bật", - "开启" - ], - "only-supports-some-games": [ - "Unterstützt nur einige Spiele", - "Hanya mendukung beberapa permainan", - "Only supports some games", - "Sólo soporta algunos juegos", - "Ne prend en charge que certains jeux", - "Supporta solo alcuni giochi", - "一部のゲームのみサポート", - "몇몇 게임만 지원", - "Wspiera tylko niektóre gry", - "Suporta apenas alguns jogos", - "Поддерживает только некоторые игры", - "Yalnızca belli oyunlar destekleniyor", - "Підтримує лише деякі ігри", - "Chỉ hỗ trợ một vài game", - "仅支持一些游戏" - ], - opacity: [ - "Deckkraft", - "Opasitas", - "Opacity", - "Opacidad", - "Opacité", - "Opacità", - "透過度", - "불투명도", - "Przezroczystość", - "Opacidade", - "Непрозрачность", - "Saydamsızlık", - "Непрозорість", - "Độ mờ", - "透明度" - ], - other: [ - "Sonstiges", - "Lainnya", - "Other", - "Otro", - "Autres", - "Altro", - "その他", - "기타", - "Inne", - "Outros", - "Прочее", - "Diğer", - "Інше", - "Khác", - "其他" - ], - playing: [ - "Spielt", - "Sedang memainkan", - "Playing", - "Jugando", - "En jeu", - "Gioca a", - "プレイ中", - "플레이 중", - "W grze", - "Jogando", - "Играет", - "Şu anda oyunda", - "Гра триває", - "Đang chơi", - "游戏中" - ], - position: [ - , - "Posisi", - "Position", - "Posición", - , - "Posizione", - "位置", - "위치", - "Pozycja", - "Posição", - "Расположение", - "Konum", - "Позиція", - "Vị trí", - "位置" - ], - "powered-off": [ - "Ausgeschaltet", - "Dimatikan", - "Powered off", - "Desactivado", - "Éteint", - "Spenta", - "本体オフ", - "전원 꺼짐", - "Zasilanie wyłączone", - "Desligado", - "Выключено", - "Kapalı", - "Вимкнений", - "Đã tắt nguồn", - "关机" - ], - "powered-on": [ - "Eingeschaltet", - "Dihidupkan", - "Powered on", - "Activado", - "Démarrer", - "Accesa", - "本体オン", - "전원 켜짐", - "Zasilanie włączone", - "Ligado", - "Включено", - "Açık", - "Увімкнений", - "Đang bật nguồn", - "开机" - ], - "prefer-ipv6-server": [ - "IPv6-Server bevorzugen", - "Utamakan Server IPv6", - "Prefer IPv6 server", - "Servidor IPv6 preferido", - "Préférer le serveur IPv6", - "Preferisci server IPv6", - "IPv6 サーバーを優先", - "IPv6 서버 우선", - "Preferuj serwer IPv6", - "Preferir servidor IPv6", - "Предпочитать IPv6 сервер", - "IPv6 sunucusunu tercih et", - "Віддавати перевагу IPv6", - "Ưu tiên máy chủ IPv6", - "优先使用 IPv6 服务器" - ], - "preferred-game-language": [ - "Bevorzugte Spielsprache", - "Bahasa Permainan yang diutamakan", - "Preferred game's language", - "Idioma preferencial del juego", - "Langue préférée du jeu", - "Lingua del gioco preferita", - "ゲームの優先言語設定", - "선호하는 게임 언어", - "Preferowany język gry", - "Idioma preferencial do jogo", - "Предпочитаемый язык игры", - "Oyunda tercih edilen dil", - "Бажана мова гри", - "Ngôn ngữ game ưu tiên", - "首选游戏语言" - ], - preset: [ - "Voreinstellung", - , - "Preset", - "Preajuste", - "Préréglages", - "Profilo", - "プリセット", - "프리셋", - "Szablon", - "Predefinição", - "Шаблон", - "Hazır ayar", - "Пресет", - "Thiết lập sẵn", - "预设" - ], - "press-esc-to-cancel": [ - 'Zum Abbrechen "Esc" drücken', - "Tekan Esc untuk batal", - "Press Esc to cancel", - "Presione Esc para cancelar", - "Appuyez sur Echap pour annuler", - "Premi Esc per annullare", - "Escを押してキャンセル", - "ESC를 눌러 취소", - "Naciśnij Esc, aby anulować", - "Pressione Esc para cancelar", - "Нажмите Esc для отмены", - "İptal etmek için Esc'ye basın", - "Натисніть Esc, щоб скасувати", - "Nhấn Esc để bỏ qua", - "按下ESC键以取消" - ], + activate: "Activate", + activated: "Activated", + active: "Active", + advanced: "Advanced", + "android-app-settings": "Android app settings", + apply: "Apply", + audio: "Audio", + auto: "Auto", + "badge-audio": "Audio", + "badge-battery": "Battery", + "badge-in": "In", + "badge-out": "Out", + "badge-playtime": "Playtime", + "badge-server": "Server", + "badge-video": "Video", + "bitrate-audio-maximum": "Maximum audio bitrate", + "bitrate-video-maximum": "Maximum video bitrate", + "bottom-left": "Bottom-left", + "bottom-right": "Bottom-right", + brightness: "Brightness", + "browser-unsupported-feature": "Your browser doesn't support this feature", + "can-stream-xbox-360-games": "Can stream Xbox 360 games", + cancel: "Cancel", + "cant-stream-xbox-360-games": "Can't stream Xbox 360 games", + clarity: "Clarity", + "clarity-boost-warning": "These settings don't work when the Clarity Boost mode is ON", + clear: "Clear", + close: "Close", + "combine-audio-video-streams": "Combine audio & video streams", + "combine-audio-video-streams-summary": "May fix the laggy audio problem", + "conditional-formatting": "Conditional formatting text color", + "confirm-delete-preset": "Do you want to delete this preset?", + "confirm-reload-stream": "Do you want to refresh the stream?", + connected: "Connected", + "console-connect": "Connect", + contrast: "Contrast", + controller: "Controller", + "controller-shortcuts": "Controller shortcuts", + "controller-vibration": "Controller vibration", + copy: "Copy", + custom: "Custom", + "deadzone-counterweight": "Deadzone counterweight", + default: "Default", + delete: "Delete", + "device-unsupported-touch": "Your device doesn't have touch support", + "device-vibration": "Device vibration", + "device-vibration-not-using-gamepad": "On when not using gamepad", + disable: "Disable", + "disable-home-context-menu": "Disable context menu in Home page", + "disable-native-mkb": "Disable native Mouse & Keyboard feature", + "disable-post-stream-feedback-dialog": "Disable post-stream feedback dialog", + "disable-social-features": "Disable social features", + "disable-xcloud-analytics": "Disable xCloud analytics", + disabled: "Disabled", + disconnected: "Disconnected", + edit: "Edit", + "enable-controller-shortcuts": "Enable controller shortcuts", + "enable-local-co-op-support": "Enable local co-op support", + "enable-local-co-op-support-note": "Only works if the game doesn't require a different profile", + "enable-mic-on-startup": "Enable microphone on game launch", + "enable-mkb": "Emulate controller with Mouse & Keyboard", + "enable-quick-glance-mode": "Enable \"Quick Glance\" mode", + "enable-remote-play-feature": "Enable the \"Remote Play\" feature", + "enable-volume-control": "Enable volume control feature", + enabled: "Enabled", + experimental: "Experimental", + export: "Export", + fast: "Fast", + "fortnite-allow-stw-mode": "Allows playing STW mode on mobile", + "fortnite-force-console-version": "Fortnite: force console version", + "game-bar": "Game Bar", + "getting-consoles-list": "Getting the list of consoles...", + help: "Help", + "hide-idle-cursor": "Hide mouse cursor on idle", + "hide-scrollbar": "Hide web page's scrollbar", + "hide-system-menu-icon": "Hide System menu's icon", + "hide-touch-controller": "Hide touch controller", + "horizontal-sensitivity": "Horizontal sensitivity", + import: "Import", + "install-android": "Install Better xCloud app for Android", + "keyboard-shortcuts": "Keyboard shortcuts", + language: "Language", + large: "Large", + layout: "Layout", + "left-stick": "Left stick", + "loading-screen": "Loading screen", + "local-co-op": "Local co-op", + "map-mouse-to": "Map mouse to", + "may-not-work-properly": "May not work properly!", + "menu-stream-settings": "Stream settings", + "menu-stream-stats": "Stream stats", + microphone: "Microphone", + "mkb-adjust-ingame-settings": "You may also need to adjust the in-game sensitivity & deadzone settings", + "mkb-click-to-activate": "Click to activate", + "mkb-disclaimer": "Using this feature when playing online could be viewed as cheating", + "mouse-and-keyboard": "Mouse & Keyboard", + muted: "Muted", + name: "Name", + new: "New", + "no-consoles-found": "No consoles found", + normal: "Normal", + off: "Off", + on: "On", + "only-supports-some-games": "Only supports some games", + opacity: "Opacity", + other: "Other", + playing: "Playing", + position: "Position", + "powered-off": "Powered off", + "powered-on": "Powered on", + "prefer-ipv6-server": "Prefer IPv6 server", + "preferred-game-language": "Preferred game's language", + preset: "Preset", + "press-esc-to-cancel": "Press Esc to cancel", "press-key-to-toggle-mkb": [ + (e) => `Press ${e.key} to toggle the Mouse and Keyboard feature`, (e) => `${e.key}: Maus- und Tastaturunterstützung an-/ausschalten`, (e) => `Tekan ${e.key} untuk mengaktifkan fitur Mouse dan Keyboard`, - (e) => `Press ${e.key} to toggle the Mouse and Keyboard feature`, (e) => `Pulsa ${e.key} para activar la función de ratón y teclado`, (e) => `Appuyez sur ${e.key} pour activer/désactiver la fonction Souris et Clavier`, (e) => `Premi ${e.key} per attivare o disattivare la funzione Mouse e Tastiera`, @@ -2324,1081 +507,73 @@ var Texts = { (e) => `Nhấn ${e.key} để bật/tắt tính năng Chuột và Bàn phím`, (e) => `按下 ${e.key} 切换键鼠模式` ], - "press-to-bind": [ - "Zum Festlegen Taste drücken oder mit der Maus klicken...", - "Tekan tombol atau gunakan mouse untuk mengaitkan...", - "Press a key or do a mouse click to bind...", - "Presione una tecla o haga un clic del ratón para enlazar...", - "Appuyez sur une touche ou faites un clic de souris pour associer...", - "Premi un tasto o fai un clic del mouse per associare...", - "キーを押すかマウスをクリックして割り当て...", - "키를 누르거나 마우스를 클릭하여 할당하기", - "Naciśnij klawisz lub kliknij myszą, aby przypisać...", - "Pressione uma tecla ou clique do mouse para vincular...", - "Нажмите клавишу или щелкните мышкой, чтобы связать...", - "Klavyedeki bir tuşa basarak veya fareyle tıklayarak tuş ataması yapın...", - "Натисніть клавішу або кнопку миші, щоб прив'язати...", - "Nhấn nút hoặc nhấn chuột để gán...", - "按相应按键或鼠标键来绑定" - ], - "prompt-preset-name": [ - "Voreinstellung Name:", - "Nama preset:", - "Preset's name:", - "Nombre del preajuste:", - "Nom du préréglage :", - "Nome del profilo:", - "プリセット名:", - "프리셋 이름:", - "Nazwa szablonu:", - "Nome da predefinição:", - "Имя шаблона:", - "Hazır ayar adı:", - "Назва пресету:", - "Tên của mẫu sẵn:", - "预设名称:" - ], - ratio: [ - "Seitenverhältnis", - "Rasio", - "Ratio", - "Relación de aspecto", - , - "Rapporto", - "比率", - "화면 비율", - "Współczynnik proporcji", - "Proporção", - "Соотношение сторон", - "Görüntü oranı", - "Співвідношення сторін", - "Tỉ lệ", - "宽高比" - ], - "reduce-animations": [ - "Animationen reduzieren", - "Kurangi animasi antarmuka", - "Reduce UI animations", - "Reduce las animaciones de la interfaz", - "Réduire les animations dans l’interface", - "Animazioni ridottte", - "UIアニメーションを減らす", - "인터페이스 애니메이션 감소", - "Ogranicz animacje interfejsu", - "Reduzir animações da interface", - "Убрать анимации интерфейса", - "Arayüz animasyonlarını azalt", - "Зменшити анімацію інтерфейсу", - "Giảm hiệu ứng chuyển động", - "减少UI动画" - ], - region: [ - , - "Wilayah", - "Region", - "Región", - "Région", - "Regione", - "地域", - "지역", - , - "Região", - "Регион", - "Bölge", - "Регіон", - "Khu vực", - "地区" - ], - "remote-play": [ - , - , - "Remote Play", - "Reproducción remota", - "Jeu à distance", - "Riproduzione Remota", - "リモートプレイ", - "리모트 플레이", - "Gra zdalna", - "Reprodução remota", - "Удаленная игра", - "Uzaktan Bağlanma", - "Віддалена гра", - "Chơi Từ Xa", - "远程串流" - ], - rename: [ - "Umbenennen", - "Ubah nama", - "Rename", - "Renombrar", - "Renommer", - "Rinomina", - "名前変更", - "이름 바꾸기", - "Zmień nazwę", - "Renomear", - "Переименовать", - "Ad değiştir", - "Перейменувати", - "Sửa tên", - "重命名" - ], - "right-click-to-unbind": [ - "Rechtsklick auf Taste: Zuordnung aufheben", - "Klik kanan pada tombol untuk menghapus", - "Right-click on a key to unbind it", - "Clic derecho en una tecla para desvincularla", - "Faites un clic droit sur une touche pour la désassocier", - "Clic col tasto destro su una assegnazione per dissociarla", - "右クリックで割り当て解除", - "할당 해제하려면 키를 오른쪽 클릭하세요", - "Kliknij prawym przyciskiem myszy na klawisz, aby anulować przypisanie", - "Clique com o botão direito em uma tecla para desvinculá-la", - "Щелкните правой кнопкой мыши по кнопке, чтобы отвязать её", - "Tuş atamasını kaldırmak için fareyle sağ tık yapın", - "Натисніть правою кнопкою миші, щоб відв'язати", - "Nhấn chuột phải lên một phím để gỡ nó", - "右键解除绑定" - ], - "right-stick": [ - "Rechter Stick", - "Stik kanan", - "Right stick", - "Joystick derecho", - "Stick droit", - "Levetta destra", - "右スティック", - "오른쪽 스틱", - "Prawy drążek analogowy", - "Direcional analógico direito", - "Правый стик", - "Sağ analog çubuk", - "Правий стік", - "Analog phải", - "右摇杆" - ], - "rocket-always-hide": [ - "Immer ausblenden", - "Selalu sembunyikan", - "Always hide", - "Ocultar siempre", - "Toujours masquer", - "Nascondi sempre", - "常に非表示", - "항상 숨기기", - "Zawsze ukrywaj", - "Sempre ocultar", - "Всегда скрывать", - "Her zaman gizle", - "Ховати завжди", - "Luôn ẩn", - "始终隐藏" - ], - "rocket-always-show": [ - "Immer anzeigen", - "Selalu tampilkan", - "Always show", - "Mostrar siempre", - "Toujours afficher", - "Mostra sempre", - "常に表示", - "항상 표시", - "Zawsze pokazuj", - "Sempre mostrar", - "Всегда показывать", - "Her zaman göster", - "Показувати завжди", - "Luôn hiển thị", - "始终显示" - ], - "rocket-animation": [ - "Raketen Animation", - "Animasi roket", - "Rocket animation", - "Animación del cohete", - "Animation de la fusée", - "Razzo animato", - "ロケットのアニメーション", - "로켓 애니메이션", - "Animacja rakiety", - "Animação do foguete", - "Анимация ракеты", - "Roket animasyonu", - "Анімація ракети", - "Phi thuyền", - "火箭动画" - ], - "rocket-hide-queue": [ - "Bei Warteschlange ausblenden", - "Sembunyikan ketika mengantri", - "Hide when queuing", - "Ocultar al hacer cola", - "Masquer lors de la file d'attente", - "Nascondi durante la coda", - "待機中は非表示", - "대기 중에는 숨기기", - "Ukryj podczas czekania w kolejce", - "Ocultar quando estiver na fila", - "Скрыть, когда есть очередь", - "Sıradayken gizle", - "Не показувати у черзі", - "Ẩn khi xếp hàng chờ", - "排队时隐藏" - ], - "safari-failed-message": [ - 'Ausführen von "Better xCloud" fehlgeschlagen. Versuche es erneut, bitte warten...', - "Gagal menjalankan Better xCloud. Mencoba ulang, Mohon tunggu...", - "Failed to run Better xCloud. Retrying, please wait...", - "No se pudo ejecutar Better xCloud. Reintentando, por favor espera...", - "Impossible d'exécuter Better xCloud. Nouvelle tentative, veuillez patienter...", - "Si è verificato un errore durante l'esecuzione di Better xCloud. Nuovo tentativo, attendere...", - "Better xCloud の実行に失敗しました。再試行中...", - "Better xCloud 시작에 실패했습니다. 재시도중이니 잠시만 기다려 주세요.", - "Nie udało się uruchomić Better xCloud. Ponawiam próbę...", - "Falha ao executar o Better xCloud. Tentando novamente, aguarde...", - "Не удалось запустить Better xCloud. Идет перезапуск, пожалуйста, подождите...", - "Better xCloud çalıştırılamadı. Yeniden deneniyor...", - "Не вдалий старт Better xCloud. Повторна спроба, будь ласка, зачекайте...", - "Không thể chạy Better xCloud. Đang thử lại, vui lòng chờ...", - "插件无法运行。正在重试,请稍候..." - ], - saturation: [ - "Sättigung", - "Saturasi", - "Saturation", - "Saturación", - , - "Saturazione", - "彩度", - "채도", - "Nasycenie", - "Saturação", - "Насыщенность", - "Renk doygunluğu", - "Насиченість", - "Độ bão hòa", - "饱和度" - ], - save: [ - "Speichern", - "Simpan", - "Save", - "Guardar", - "Enregistrer", - "Conferma", - "保存", - "저장", - "Zapisz", - "Salvar", - "Сохранить", - "Kaydet", - "Зберегти", - "Lưu", - "保存" - ], - "screenshot-apply-filters": [ - "Videofilter auf Screenshots anwenden", - "Terapkan filter video pada screenshot", - "Applies video filters to screenshots", - "Aplica filtros de vídeo a las capturas de pantalla", - "Appliquer les filtres vidéo aux captures d'écran", - "Applica filtri video agli screenshot", - "スクリーンショットにビデオフィルターを適用", - "스크린샷에 비디오 필터 적용", - "Stosuje filtry wideo do zrzutów ekranu", - "Aplicar filtros de vídeo às capturas de tela", - "Применяет фильтры видео к скриншотам", - "Görsel filtreleri ekran görüntülerine de uygular", - "Застосовує відеофільтри до знімків екрана", - "Áp dụng hiệu ứng video vào ảnh chụp màn hình", - "为截图添加滤镜" - ], - "separate-touch-controller": [ - "Trenne Touch-Controller & Controller #1", - "Pisahkan Kontrol sentuh & Kontroler #1", - "Separate Touch controller & Controller #1", - "Separar controlador táctil y controlador #1", - "Séparer les commandes tactiles et la manette #1", - "Controller su schermo e Controller #1 separati", - "タッチコントローラーとコントローラー#1を分ける", - "터치 컨트롤러와 컨트롤러 #1을 분리하여 인식하기", - "Oddziel Kontroler dotykowy i Kontroler #1", - "Separar o Controle por Toque e o Controle #1", - "Раздельный сенсорный контроллер и контроллер #1", - "Dokunmatik kumandayı ve birincil kumandayı ayrı tut", - "Відокремити Сенсорний контролер та Контролер #1", - "Tách biệt Bộ điều khiển cảm ứng và Tay cầm #1", - "虚拟摇杆和手柄分别控制不同角色" - ], - "separate-touch-controller-note": [ - "Touch-Controller ist Spieler 1, Controller #1 ist Spieler 2", - "Kontrol sentuh adalah Player 1, Kontroler #1 adalah Player 2", - "Touch controller is Player 1, Controller #1 is Player 2", - "El controlador táctil es Jugador 1, Controlador #1 es Jugador 2", - "Commandes tactiles affectées au joueur 1, manette #1 affectée au joueur 2", - "Il Giocatore 1 userà il Controller su schermo, il Giocatore 2 userà il Controller #1", - "タッチコントローラーがプレイヤー1、コントローラー#1がプレイヤー2に割り当てられます", - "터치 컨트롤러는 플레이어 1, 컨트롤러 #1은 플레이어 2입니다.", - "Kontroler dotykowy to Gracz 1, Kontroler #1 to Gracz 2", - "O Controle por Toque é o Jogador 1, o Controle #1 é o Jogador 2", - "Сенсорный контроллер — игрок 1, контроллер #1 — игрок 2", - "Dokunmaktik kumanda birinci oyuncu, birincil kumanda ikinci oyuncu", - "Сенсорний контролер це Гравець 1, Контролер #1 це Гравець 2", - "Bộ điều khiển cảm ứng là Người chơi 1, Tay cầm #1 là Người chơi 2", - "虚拟摇杆为玩家1,手柄#1为玩家2" - ], - server: [ - , - , - "Server", - "Servidor", - "Serveur", - , - "サーバー", - "서버", - "Serwer", - "Servidor", - "Сервер", - "Sunucu", - "Сервер", - "Máy chủ", - "服务器" - ], - "settings-reload": [ - "Seite neu laden und Änderungen anwenden", - "Muat ulang untuk menerapkan", - "Reload page to reflect changes", - "Actualice la página para aplicar los cambios", - "Recharger la page pour bénéficier des changements", - "Applica e ricarica la pagina", - "ページを更新をして設定変更を適用", - "적용 및 페이지 새로고침", - "Odśwież stronę, aby zastosować zmiany", - "Recarregue a página para aplicar as alterações", - "Перезагрузить страницу, чтобы применить изменения", - "Kaydetmek için sayfayı yenile", - "Перезавантажте сторінку, щоб застосувати зміни", - "Tải lại trang để áp dụng các thay đổi", - "重新加载页面以应用更改" - ], - "settings-reloading": [ - "Wird neu geladen...", - "Memuat ulang...", - "Reloading...", - "Recargando...", - "Actualisation...", - "Ricaricamento...", - "更新中...", - "새로고침하는 중...", - "Ponowne ładowanie...", - "Recarregando...", - "Перезагрузка...", - "Sayfa yenileniyor...", - "Перезавантаження...", - "Đang tải lại...", - "正在重新加载..." - ], - "shortcut-keys": [ - "Shortcut-Tasten", - "Tombol pintasan", - "Shortcut keys", - "Teclas de atajo", - "Touches de raccourci", - "Tasti di scelta rapida", - "ショートカットキー", - "단축키", - "Skróty klawiszowe", - "Teclas de atalho", - "Горячие клавиши", - "Kısayol tuşları", - "Клавіші швидкого доступу", - "Các phím tắt", - "快捷键" - ], - "show-game-art": [ - "Poster des Spiels anzeigen", - "Tampilkan sampul permainan", - "Show game art", - "Mostrar imagen del juego", - "Afficher la couverture du jeu", - "Mostra immagine del gioco", - "ゲームアートを表示", - "게임 아트 표시", - "Pokaż okładkę gry", - "Mostrar arte do jogo", - "Показывать игровую обложку", - "Oyun resmini göster", - "Показувати ігровий арт", - "Hiển thị ảnh game", - "显示游戏封面" - ], - "show-stats-on-startup": [ - "Statistiken beim Start des Spiels anzeigen", - "Tampilkan statistik ketika permainan dimulai", - "Show stats when starting the game", - "Mostrar estadísticas al iniciar el juego", - "Afficher les statistiques au démarrage de la partie", - "Mostra le statistiche quando si avvia la partita", - "ゲーム開始時に統計情報を表示", - "게임 시작 시 통계 보여주기", - "Pokaż statystyki podczas uruchamiania gry", - "Mostrar estatísticas ao iniciar o jogo", - "Показывать статистику при запуске игры", - "Oyun başlatırken yayın durumunu göster", - "Показувати статистику при запуску гри", - "Hiển thị thông số khi vào game", - "开始游戏时显示统计信息" - ], - "show-touch-controller": [ - "Touch-Controller anzeigen", - "Tampilkan kontrol sentuh", - "Show touch controller", - "Mostrar controles táctiles", - "Afficher les commandes tactiles", - "Mostra il Controller Touch", - "タッチコントローラーを表示", - "터치 컨트롤러 표시", - "Pokaż sterowanie dotykowe", - "Mostrar controles por toque", - "Показать сенсорный контроллер", - "Dokunmatik kontrolleri göster", - "Показати сенсорний контролер", - "Hiện bộ điều khiển cảm ứng", - "显示虚拟按键" - ], - "show-wait-time": [ - "Geschätzte Wartezeit anzeigen", - "Tampilkan waktu antrian", - "Show the estimated wait time", - "Mostrar el tiempo de espera estimado", - "Afficher le temps d'attente estimé", - "Mostra una stima del tempo di attesa", - "推定待機時間を表示", - "예상 대기 시간 표시", - "Pokaż szacowany czas oczekiwania", - "Mostrar o tempo de espera estimado", - "Показать предполагаемое время до запуска", - "Tahminî bekleme süresini göster", - "Показувати орієнтовний час очікування", - "Hiển thị thời gian chờ dự kiến", - "显示预计等待时间" - ], - "simplify-stream-menu": [ - "Stream-Menü vereinfachen", - "Sederhanakan menu Stream", - "Simplify Stream's menu", - "Simplificar el menú del stream", - "Simplifier le menu de Stream", - "Semplifica il menu della trasmissione", - "ストリーミングメニューのラベルを非表示", - "스트리밍 메뉴 간단히 보기", - "Uprość menu strumienia", - "Simplificar menu de transmissão", - "Упростить меню потока", - "Yayın menüsünü basitleştir", - "Спростити меню трансляції", - "Đơn giản hóa menu của Stream", - "简化菜单" - ], - "skip-splash-video": [ - "Xbox-Logo bei Spielstart überspringen", - "Lewati video splash Xbox", - "Skip Xbox splash video", - "Saltar vídeo de presentación de Xbox", - "Ignorer la vidéo de démarrage Xbox", - "Salta il logo Xbox iniziale", - "Xboxの起動画面をスキップ", - "Xbox 스플래시 영상 건너뛰기", - "Pomiń wstępne intro Xbox", - "Pular introdução do Xbox", - "Пропустить видео с заставкой Xbox", - "Xbox açılış ekranını atla", - "Пропустити заставку Xbox", - "Bỏ qua video Xbox", - "跳过 Xbox 启动动画" - ], - slow: [ - "Langsam", - "Lambat", - "Slow", - "Lento", - "Lent", - "Lento", - "低速", - "느림", - "Wolno", - "Lento", - "Медленный", - "Yavaş", - "Повільний", - "Chậm", - "慢速" - ], - small: [ - "Klein", - "Kecil", - "Small", - "Pequeño", - "Petite", - "Piccolo", - "小", - "작게", - "Mały", - "Pequeno", - "Маленький", - "Küçük", - "Маленький", - "Nhỏ", - "小" - ], - "smart-tv": [ - , - , - "Smart TV", - , - , - , - "スマートTV", - "스마트 TV", - , - , - , - "Akıllı TV", - , - "TV thông minh", - "智能电视" - ], - sound: [ - "Ton", - "Suara", - "Sound", - "Sonido", - "Son", - "Suoni", - "サウンド", - "소리", - "Dźwięk", - "Som", - "Звук", - "Ses", - "Звук", - "Âm thanh", - "声音" - ], - standby: [ - , - "Siaga", - "Standby", - "Modo de espera", - "Mise en veille", - "In sospensione", - "スタンバイ", - "대기", - "Stan czuwania", - "Suspenso", - "Режим ожидания", - "Beklemede", - "Режим очікування", - "Đang ở chế độ chờ", - "待机" - ], - "stat-bitrate": [ - , - , - "Bitrate", - "Tasa de bits", - , - , - "ビットレート", - "비트레이트", - , - , - "Скорость соединения", - "Bit hızı", - "Швидкість потоку", - , - "码率" - ], - "stat-decode-time": [ - "Dekodierzeit", - "Waktu dekode", - "Decode time", - "Tiempo de decodificación", - "Décodage", - "Decodifica", - "デコード時間", - "디코딩 시간", - "Czas dekodowania", - "Tempo de decodificação", - "Время декодирования", - "Kod çözme süresi", - "Час декодування", - "Thời gian giải mã", - "解码时间" - ], - "stat-fps": [ - "Framerate", - , - "FPS", - , - , - , - , - , - , - , - "Кадр/сек", - , - "Кадрів на секунду", - , - "帧率" - ], - "stat-frames-lost": [ - "Verlorene Frames", - "Bingkai terbuang", - "Frames lost", - "Pérdida de fotogramas", - "Images perdues", - "Perdita di fotogrammi", - "フレームロス", - "프레임 손실", - "Utracone klatki", - "Quadros perdidos", - "Потери кадров", - "Kare kaybı", - "Кадрів втрачено", - "Số khung hình bị mất", - "丢帧" - ], - "stat-packets-lost": [ - "Paketverluste", - "Paket hilang", - "Packets lost", - "Pérdida de paquetes", - "Perte paquets", - "Perdita di pacchetti", - "パケットロス", - "패킷 손실", - "Utracone pakiety", - "Pacotes perdidos", - "Потери пакетов", - "Paket kaybı", - "Пакетів втрачено", - "Số gói tin bị mất", - "丢包" - ], - "stat-ping": [ - , - , - "Ping", - "Latencia", - , - , - , - "지연 시간", - , - , - "Задержка соединения", - "Gecikme", - "Затримка", - , - "延迟" - ], - stats: [ - "Statistiken", - "Statistik", - "Stats", - "Estadísticas", - , - "Statistiche", - "統計情報", - "통계", - "Statystyki", - "Estatísticas", - "Статистика", - "Durum", - "Статистика", - "Các thông số", - "统计信息" - ], - "stick-decay-minimum": [ - "Stick Abklingzeit Minimum", - "Minimum pelepasan stik", - "Stick decay minimum", - "Disminuir mínimamente el analógico", - "Force minimum du retour au centre du stick", - "Tempo minimo di rilascio dello stick", - "スティックの減衰の最小値", - "스틱 복귀 최소값", - "Minimalne opóźnienie drążka", - "Tempo mínimo de redefinição do analógico", - "Минимальная перезарядка стика", - "Çubuğun ortalanma süresi minimumu", - "Мінімальне згасання стіка", - "Độ suy giảm tối thiểu của cần điều khiển", - "最小摇杆回中延迟" - ], - "stick-decay-strength": [ - "Stick Abklingzeit Geschwindigkeit", - "Kekuatan pelepasan stik", - "Stick decay strength", - "Intensidad de decaimiento del analógico", - "Force du retour au centre du stick", - "Velocità di rilascio dello stick", - "スティックの減衰の強さ", - "스틱 복귀 강도", - "Siła opóźnienia drążka", - "Velocidade de redefinição do analógico", - "Скорость перезарядки стика", - "Çubuğun ortalanma gücü", - "Сила згасання стіка", - "Sức mạnh độ suy giảm của cần điều khiển", - "摇杆回中强度" - ], - stream: [ - , - , - "Stream", - , - , - , - "ストリーミング", - "스트리밍", - , - "Transmissão", - "Видеопоток", - "Yayın", - "Трансляція", - , - "串流" - ], - stretch: [ - "Strecken", - "Rentangkan", - "Stretch", - "Estirado", - "Étirer", - "Riempi", - "引き伸ばし", - "늘이기", - "Rozciągnij", - "Esticar", - "Растянуть", - "Genişlet", - "Розтягнути", - "Kéo giãn", - "拉伸" - ], - "stretch-note": [ - "Nicht verwenden bei Spielen mit nativer Touch-Unterstützung", - , - "Don't use with native touch games", - "No usar con juegos nativos táctiles", - "Ne pas utiliser avec les jeux tactiles natifs", - "Non usare nei giochi con supporto touch nativo", - , - "터치 공식지원 게임에는 사용하지 마세요", - "Nie używaj dla gier wspierających natywne funkcje dotykowe", - , - , - , - "Не використовуйте в іграх з рідним сенсором", - "Không dùng với các game cảm ứng trực tiếp", - "不要在支持原生触控的游戏中启用" - ], - "support-better-xcloud": [ - '"Better xCloud" unterstützen', - "Dukung Better xCloud", - "Support Better xCloud", - "Apoyar a Better xCloud", - "Soutenir Better xCloud", - "Sostieni Better xCloud", - "Better xCloudをサポート", - "Better xCloud 후원", - "Wesprzyj Better xCloud", - "Apoie o Better xCloud", - "Поддержать Better xCloud", - "Better xCloud'a destek ver", - "Підтримати Better xCloud", - "Ủng hộ Better xCloud", - "赞助本插件" - ], - "swap-buttons": [ - "Tasten tauschen", - "Tukar tombol", - "Swap buttons", - "Intercambiar botones", - "Permuter les boutons", - "Inverti i pulsanti", - "ボタン入れ替え", - "버튼 바꾸기", - "Zamień przyciski", - "Trocar botões", - "Поменять кнопки", - "Düğme düzenini ters çevir", - "Поміняти кнопки місцями", - "Hoán đổi nút", - "交换按钮" - ], - "take-screenshot": [ - "Screenshot aufnehmen", - "Ambil tangkapan layar", - "Take screenshot", - "Capturar pantalla", - "Prendre une capture d'écran", - "Cattura schermo", - "スクリーンショットを撮影", - "스크린샷 찍기", - "Zrób zrzut ekranu", - "Captura de tela", - "Сделать снимок экрана", - "Ekran görüntüsü al", - "Зробити знімок екрану", - "Lưu ảnh màn hình", - "截图" - ], - "target-resolution": [ - "Festgelegte Auflösung", - "Resolusi", - "Target resolution", - "Calidad de imagen", - "Résolution cible", - "Risoluzione prevista", - "ターゲット解像度", - "목표 해상도", - "Rozdzielczość docelowa", - "Resolução padrão", - "Целевое разрешение", - "Tercih edilen çözünürlük", - "Цільова роздільна здатність", - "Độ phân giải", - "目标分辨率" - ], - "tc-all-games": [ - "Alle Spiele", - "Semua permainan", - "All games", - "Todos los juegos", - "Tous les jeux", - "Tutti i giochi", - "全てのゲームで有効", - "모든 게임", - "Wszystkie gry", - "Todos os jogos", - "Все игры", - "Tüm oyunlar", - "Всі ігри", - "Tất cả các game", - "所有游戏" - ], - "tc-all-white": [ - "Komplett weiß", - "Putih", - "All white", - "Todo blanco", - "Tout blanc", - "Tutti bianchi", - "オールホワイト", - "모두 하얗게", - "Wszystkie białe", - "Todo branco", - "Полностью белые", - "Hepsi beyaz", - "Все біле", - "Trắng hoàn toàn", - "白色" - ], - "tc-auto-off": [ - "Aus, wenn Controller gefunden", - "Mati saat kontroler terhubung", - "Off when controller found", - "Desactivar cuando se encuentra el controlador", - "Désactivé lorsque la manette est connectée", - "Disabilitata quando un controllor viene rilevato", - "コントローラー接続時に無効化", - "컨트롤러가 연결되면 끄기", - "Wyłącz, gdy kontroler zostanie znaleziony", - "Desligar toque quando o controle estiver conectado", - "Выключить, когда контроллер найден", - "Başka bir kumanda bağlandığında kapat", - "Вимкнено, коли контролер знайдено", - "Tắt khi sử dụng tay cầm", - "手柄连接时隐藏虚拟摇杆" - ], - "tc-availability": [ - "Verfügbarkeit", - "Ketersediaan", - "Availability", - "Disponibilidad", - "Disponibilité", - "Disponibilità", - "強制的に有効化", - "사용 여부", - "Dostępność", - "Disponibilidade", - "В каких играх включить", - "Uygunluk durumu", - "Доступність", - "Khả dụng", - "启用" - ], - "tc-custom-layout-style": [ - "Angepasstes Layout Button Stil", - "Gaya tata letak tombol kustom", - "Custom layout's button style", - "Estilo de botones de diseño personalizado", - "Style personnalisé des boutons", - "Layout dei tasti personalizzato", - "カスタムレイアウト", - "커스텀 레이아웃의 버튼 스타일", - "Niestandardowy układ przycisków", - "Estilo de botão do layout personalizado", - "Пользовательский стиль кнопок", - "Özelleştirilmiş düğme düzeninin biçimi", - "Користувацький стиль кнопок", - "Màu của bố cục tùy chọn", - "特殊游戏按钮样式" - ], - "tc-default-opacity": [ - "Standard Deckkraft", - "Opasitas bawaan", - "Default opacity", - "Opacidad por defecto", - "Opacité par défaut", - "Opacità predefinita", - "既定の透過度", - "기본 불투명도", - "Domyślna przezroczystość", - "Opacidade padrão", - "Прозрачность по умолчанию", - "Varsayılan opaklık", - "Непрозорість за замовчуванням", - "Độ mờ mặc định", - "默认不透明度" - ], - "tc-muted-colors": [ - "Matte Farben", - "Warna Semu", - "Muted colors", - "Colores apagados", - "Couleurs adoucies", - "Colori tenui", - "ミュートカラー", - "저채도 색상", - "Stonowane kolory", - "Cores opacas", - "Приглушенные цвета", - "Yumuşak renkler", - "Приглушені кольори", - "Màu câm", - "低饱和度" - ], - "tc-standard-layout-style": [ - "Standard Layout Button Stil", - "Gaya tata letak tombol standar", - "Standard layout's button style", - "Estilo de botones de diseño estándar", - "Disposition standard des boutons", - "Layout dei tasti standard", - "標準レイアウト", - "표준 레이아웃의 버튼 스타일", - "Standardowy układ przycisków", - "Estilo de botão do layout padrão", - "Стандартный стиль кнопок", - "Varsayılan düğme düzeninin biçimi", - "Стандартний стиль кнопок", - "Màu của bố cục tiêu chuẩn", - "通用按钮样式" - ], - "text-size": [ - "Textgröße", - "Ukuran teks", - "Text size", - "Tamano del texto", - "Taille du texte", - "Dimensione del testo", - "文字サイズ", - "글자 크기", - "Rozmiar tekstu", - "Tamanho do texto", - "Размер текста", - "Metin boyutu", - "Розмір тексту", - "Cỡ chữ", - "文字大小" - ], - "top-center": [ - "Oben zentriert", - "Tengah atas", - "Top-center", - "Superior centrado", - "En haut au centre", - "In alto al centro", - "上", - "중앙 상단", - "Wyśrodkowany na górze", - "Superior centralizado", - "Сверху", - "Orta üst", - "Зверху по центру", - "Chính giữa phía trên", - "顶部居中" - ], - "top-left": [ - "Oben links", - "Kiri atas", - "Top-left", - "Superior izquierdo", - "En haut à gauche", - "In alto a sinistra", - "左上", - "좌측 상단", - "Lewy górny róg", - "Superior esquerdo", - "Левый верхний угол", - "Sol üst", - "Зверху ліворуч", - "Phía trên bên trái", - "左上角" - ], - "top-right": [ - "Oben rechts", - "Kanan atas", - "Top-right", - "Superior derecho", - "En haut à droite", - "In alto a destra", - "右上", - "우측 상단", - "Prawy górny róg", - "Superior direito", - "Справа", - "Sağ üst", - "Зверху праворуч", - "Phía trên bên phải", - "右上角" - ], - "touch-control-layout": [ - "Touch-Steuerungslayout", - "Tata letak kontrol sentuhan", - "Touch control layout", - "Diseño de control táctil", - "Disposition des commandes tactiles", - "Configurazione dei comandi su schermo", - "タッチコントロールレイアウト", - "터치 컨트롤 레이아웃", - "Układ sterowania dotykowego", - "Layout do controle por toque", - "Расположение сенсорных кнопок", - "Dokunmatik kontrol şeması", - "Розташування сенсорного керування", - "Bố cục điều khiển cảm ứng", - "虚拟摇杆布局" - ], + "press-to-bind": "Press a key or do a mouse click to bind...", + "prompt-preset-name": "Preset's name:", + ratio: "Ratio", + "reduce-animations": "Reduce UI animations", + region: "Region", + "remote-play": "Remote Play", + rename: "Rename", + "right-click-to-unbind": "Right-click on a key to unbind it", + "right-stick": "Right stick", + "rocket-always-hide": "Always hide", + "rocket-always-show": "Always show", + "rocket-animation": "Rocket animation", + "rocket-hide-queue": "Hide when queuing", + "safari-failed-message": "Failed to run Better xCloud. Retrying, please wait...", + saturation: "Saturation", + save: "Save", + "screenshot-apply-filters": "Applies video filters to screenshots", + "separate-touch-controller": "Separate Touch controller & Controller #1", + "separate-touch-controller-note": "Touch controller is Player 1, Controller #1 is Player 2", + server: "Server", + "settings-reload": "Reload page to reflect changes", + "settings-reloading": "Reloading...", + "shortcut-keys": "Shortcut keys", + "show-game-art": "Show game art", + "show-stats-on-startup": "Show stats when starting the game", + "show-touch-controller": "Show touch controller", + "show-wait-time": "Show the estimated wait time", + "simplify-stream-menu": "Simplify Stream's menu", + "skip-splash-video": "Skip Xbox splash video", + slow: "Slow", + small: "Small", + "smart-tv": "Smart TV", + sound: "Sound", + standby: "Standby", + "stat-bitrate": "Bitrate", + "stat-decode-time": "Decode time", + "stat-fps": "FPS", + "stat-frames-lost": "Frames lost", + "stat-packets-lost": "Packets lost", + "stat-ping": "Ping", + stats: "Stats", + "stick-decay-minimum": "Stick decay minimum", + "stick-decay-strength": "Stick decay strength", + stream: "Stream", + stretch: "Stretch", + "stretch-note": "Don't use with native touch games", + "support-better-xcloud": "Support Better xCloud", + "swap-buttons": "Swap buttons", + "take-screenshot": "Take screenshot", + "target-resolution": "Target resolution", + "tc-all-games": "All games", + "tc-all-white": "All white", + "tc-auto-off": "Off when controller found", + "tc-availability": "Availability", + "tc-custom-layout-style": "Custom layout's button style", + "tc-default-opacity": "Default opacity", + "tc-muted-colors": "Muted colors", + "tc-standard-layout-style": "Standard layout's button style", + "text-size": "Text size", + "top-center": "Top-center", + "top-left": "Top-left", + "top-right": "Top-right", + "touch-control-layout": "Touch control layout", "touch-control-layout-by": [ + (e) => `Touch control layout by ${e.name}`, (e) => `Touch-Steuerungslayout von ${e.name}`, (e) => `Tata letak Sentuhan layar oleh ${e.name}`, - (e) => `Touch control layout by ${e.name}`, (e) => `Disposición del control táctil por ${e.nombre}`, (e) => `Disposition du contrôleur tactile par ${e.name}`, (e) => `Configurazione dei comandi su schermo creata da ${e.name}`, @@ -3412,373 +587,114 @@ var Texts = { (e) => `Bố cục điều khiển cảm ứng tạo bởi ${e.name}`, (e) => `由 ${e.name} 提供的虚拟按键样式` ], - "touch-controller": [ - "Touch-Controller", - "Kontrol sentuhan", - "Touch controller", - "Controles táctiles", - "Commandes tactiles", - "Controller su schermo", - "タッチコントローラー", - "터치 컨트롤", - "Sterowanie dotykiem", - "Controle de toque", - "Сенсорные кнопки", - "Dokunmatik oyun kumandası", - "Сенсорне керування", - "Bộ điều khiển cảm ứng", - "虚拟摇杆" - ], - "transparent-background": [ - "Transparenter Hintergrund", - "Latar belakang transparan", - "Transparent background", - "Fondo transparente", - "Fond transparent", - "Sfondo trasparente", - "背景の透過", - "투명 배경", - "Przezroczyste tło", - "Fundo transparente", - "Прозрачный фон", - "Saydam arka plan", - "Прозоре тло", - "Trong suốt màu nền", - "透明背景" - ], - ui: [ - "Benutzeroberfläche", - "Antarmuka pengguna", - "UI", - "Interfaz de usuario", - "Interface utilisateur", - "Interfaccia", - , - , - "Interfejs", - "Interface", - "Интерфейс", - "Kullanıcı arayüzü", - "Інтерфейс користувача", - "Giao diện" - ], - "unexpected-behavior": [ - "Könnte unerwartetes Verhalten verursachen", - "Dapat menyebabkan masalah yang tidak diinginkan", - "May cause unexpected behavior", - "Puede causar un comportamiento inesperado", - "Peut causer un comportement inattendu", - "Può causare un comportamento anomalo", - "予期せぬ動作を引き起こす可能性があります", - "예상치 못한 동작이 발생할 수 있습니다", - "Może spowodować nieoczekiwane zachowanie", - "Pode causar comportamento inesperado", - "Может вызвать нестабильное поведение", - "Beklenmedik sorunlara yol açabilir", - "Може викликати неочікувану поведінку", - "Có thể gây ra các hành vi không mong muốn", - "可能导致意外行为" - ], - unknown: [ - "Unbekannt", - "Tidak diketahui", - "Unknown", - "Desconocido", - "Inconnu", - "Sconosciuto", - "不明", - "알 수 없음", - "Nieznane", - "Desconhecido", - "Неизвестный", - "Bilinmiyor", - "Невідомий", - "Không rõ", - "未知" - ], - unlimited: [ - "Unbegrenzt", - "Tak terbatas", - "Unlimited", - "Ilimitado", - "Illimité", - "Illimitato", - "無制限", - "제한없음", - "Bez ograniczeń", - "Ilimitado", - "Неограничено", - "Limitsiz", - "Необмежено", - "Không giới hạn", - "无限制" - ], - unmuted: [ - "Ton an", - "Bunyikan", - "Unmuted", - "Activar sonido", - "Son activé", - "Microfono attivato", - "ミュート解除", - "음소거 해제", - "Wyciszenie wyłączone", - "Sem Mudo", - "Вкл микрофон", - "Açık", - "Увімкнути звук", - "Đã mở âm", - "已取消静音" - ], - "use-mouse-absolute-position": [ - "Absolute Position der Maus verwenden", - "Gunakan posisi mouse mutlak", - "Use mouse's absolute position", - "Usar la posición absoluta del ratón", - "Utiliser la position absolue de la souris", - "Usa la posizione assoluta del mouse", - "マウスの絶対座標を使用", - "마우스 절대위치 사용", - "Użyj pozycji bezwzględnej myszy", - "Usar posição absoluta do mouse", - "Использовать абсолютное положение мыши", - "Farenin mutlak pozisyonunu baz al", - "Використовувати абсолютне положення миші", - "Sử dụng vị trí tuyệt đối của chuột", - "使用鼠标的绝对位置" - ], - "user-agent-profile": [ - "User-Agent Profil", - "Profil User-Agent", - "User-Agent profile", - "Perfil del agente de usuario", - "Profil de l'agent utilisateur", - "User-Agent", - "ユーザーエージェントプロファイル", - "사용자 에이전트 프로파일", - "Profil User-Agent", - "Perfil do User-Agent", - "Профиль устройства", - "Kullanıcı aracısı profili", - "Профіль User-Agent", - "User-Agent", - "浏览器UA伪装" - ], - "vertical-sensitivity": [ - "Vertikale Empfindlichkeit", - "Sensitivitas vertikal", - "Vertical sensitivity", - "Sensibilidad Vertical", - "Sensibilité verticale", - "Sensibilità verticale", - "上下方向の感度", - "수직 민감도", - "Czułość pionowa", - "Sensibilidade vertical", - "Вертикальная чувствительность", - "Dikey hassasiyet", - "Вертикальна чутливість", - "Độ ngạy dọc", - "垂直灵敏度" - ], - "vibration-intensity": [ - "Vibrationsstärke", - "Intensitas getaran", - "Vibration intensity", - "Intensidad de la vibración", - "Intensité des vibrations", - "Intensità della vibrazione", - "振動の強さ", - "진동 세기", - "Siła wibracji", - "Intensidade da vibração", - "Сила вибрации", - "Titreşim gücü", - "Інтенсивність вібрації", - "Cường độ rung", - "振动强度" - ], - "vibration-status": [ - , - "Getaran", - "Vibration", - "Vibración", - , - "Vibrazione", - "振動", - "진동", - "Wibracje", - "Vibração", - "Вибрация", - "Titreşim", - "Вібрація", - "Rung", - "手柄震动" - ], - video: [ - , - , - "Video", - , - "Vidéo", - , - "映像", - "비디오", - "Obraz", - "Vídeo", - "Видео", - "Görüntü", - "Відео", - "Hình ảnh", - "视频" - ], - "visual-quality": [ - "Bildqualität", - "Kualitas visual", - "Visual quality", - "Calidad visual", - "Qualité visuelle", - "Profilo codec preferito", - "画質", - "시각적 품질", - "Jakość grafiki", - "Qualidade visual", - "Качество видеопотока", - "Görüntü kalitesi", - "Візуальна якість", - "Chất lượng hình ảnh", - "画质" - ], - "visual-quality-high": [ - "Hoch", - "Tinggi", - "High", - "Alto", - "Élevée", - "Alta", - "高", - "높음", - "Wysoka", - "Alto", - "Высокое", - "Yüksek", - "Високий", - "Cao", - "高" - ], - "visual-quality-low": [ - "Niedrig", - "Rendah", - "Low", - "Bajo", - "Basse", - "Bassa", - "低", - "낮음", - "Niska", - "Baixo", - "Низкое", - "Düşük", - "Низький", - "Thấp", - "低" - ], - "visual-quality-normal": [ - "Mittel", - , - "Normal", - , - , - "Normale", - "中", - "보통", - "Normalna", - , - "Среднее", - , - "Нормальний", - "Thường", - "中" - ], - volume: [ - "Lautstärke", - , - "Volume", - "Volumen", - , - , - "音量", - "음량", - "Głośność", - , - "Громкость", - "Ses düzeyi", - "Гучність", - "Âm lượng", - "音量" - ], - "wait-time-countdown": [ - , - "Hitung mundur", - "Countdown", - "Cuenta Regresiva", - "Compte à rebours", - , - "カウントダウン", - "카운트다운", - "Pozostały czas oczekiwania", - "Contagem regressiva", - "Время до запуска", - "Geri sayım", - "Зворотній відлік", - "Đếm ngược", - "倒计时" - ], - "wait-time-estimated": [ - "Geschätzte Endzeit", - "Perkiraan waktu Selesai ", - "Estimated finish time", - "Tiempo estimado de finalización", - "Temps estimé avant la fin", - "Tempo residuo stimato", - "推定完了時間", - "예상 완료 시간", - "Szacowany czas zakończenia", - "Tempo estimado para a conclusão", - "Примерное время запуска", - "Tahminî bitiş süresi", - "Орієнтовний час завершення", - "Thời gian hoàn thành dự kiến", - "预计等待时间" - ] + "touch-controller": "Touch controller", + "transparent-background": "Transparent background", + ui: "UI", + "unexpected-behavior": "May cause unexpected behavior", + unknown: "Unknown", + unlimited: "Unlimited", + unmuted: "Unmuted", + "use-mouse-absolute-position": "Use mouse's absolute position", + "user-agent-profile": "User-Agent profile", + "vertical-sensitivity": "Vertical sensitivity", + "vibration-intensity": "Vibration intensity", + "vibration-status": "Vibration", + video: "Video", + "visual-quality": "Visual quality", + "visual-quality-high": "High", + "visual-quality-low": "Low", + "visual-quality-normal": "Normal", + volume: "Volume", + "wait-time-countdown": "Countdown", + "wait-time-estimated": "Estimated finish time" }; class Translations { - static #enUS = -1; - static #selectedLocale = -1; + static #EN_US = "en-US"; + static #KEY_LOCALE = "better_xcloud_locale"; + static #KEY_TRANSLATIONS = "better_xcloud_translations"; + static #enUsIndex = -1; + static #selectedLocaleIndex = -1; + static #selectedLocale = "en-US"; + static #supportedLocales = Object.keys(SUPPORTED_LANGUAGES); + static #foreignTranslations = {}; + static async init() { + Translations.#enUsIndex = Translations.#supportedLocales.indexOf(Translations.#EN_US); + Translations.refreshCurrentLocale(); + await Translations.#loadTranslations(); + } static refreshCurrentLocale() { - const supportedLocales = Object.keys(SUPPORTED_LANGUAGES); - supportedLocales.sort(); - Translations.#enUS = supportedLocales.indexOf("en-US"); - let locale = localStorage.getItem("better_xcloud_locale"); + const supportedLocales = Translations.#supportedLocales; + let locale = localStorage.getItem(Translations.#KEY_LOCALE); if (!locale) { - locale = window.navigator.language || "en-US"; + locale = window.navigator.language || Translations.#EN_US; if (supportedLocales.indexOf(locale) === -1) { - locale = "en-US"; + locale = Translations.#EN_US; } - localStorage.setItem("better_xcloud_locale", locale); + localStorage.setItem(Translations.#KEY_LOCALE, locale); } - Translations.#selectedLocale = supportedLocales.indexOf(locale); + Translations.#selectedLocale = locale; + Translations.#selectedLocaleIndex = supportedLocales.indexOf(locale); } static get(key, values) { - const texts = Texts[key] || alert(`Missing translation key: ${key}`); - const translation = texts[Translations.#selectedLocale] || texts[Translations.#enUS]; - return values ? translation(values) : translation; + let text = null; + if (Translations.#selectedLocale !== Translations.#EN_US) { + text = Translations.#foreignTranslations[key]; + } + if (!text) { + text = Texts[key] || alert(`Missing translation key: ${key}`); + } + let translation; + if (Array.isArray(text)) { + translation = text[Translations.#selectedLocaleIndex] || text[Translations.#enUsIndex]; + return translation(values); + } + translation = text; + return translation; + } + static async#loadTranslations() { + if (Translations.#selectedLocale === Translations.#EN_US) { + return; + } + try { + Translations.#foreignTranslations = JSON.parse(window.localStorage.getItem(Translations.#KEY_TRANSLATIONS)); + } catch (e) { + } + if (!Translations.#foreignTranslations) { + await this.downloadTranslations(Translations.#selectedLocale); + } + } + static async updateTranslations(async = false) { + if (Translations.#selectedLocale === Translations.#EN_US) { + return; + } + if (async) { + Translations.downloadTranslationsAsync(Translations.#selectedLocale); + } else { + await Translations.downloadTranslations(Translations.#selectedLocale); + } + } + static async downloadTranslations(locale) { + try { + const resp = await NATIVE_FETCH(`https://raw.githubusercontent.com/redphx/better-xcloud/gh-pages/translations/${locale}.json`); + const translations = await resp.json(); + window.localStorage.setItem(Translations.#KEY_TRANSLATIONS, JSON.stringify(translations)); + Translations.#foreignTranslations = translations; + return true; + } catch (e) { + debugger; + } + return false; + } + static downloadTranslationsAsync(locale) { + NATIVE_FETCH(`https://raw.githubusercontent.com/redphx/better-xcloud/gh-pages/translations/${locale}.json`).then((resp) => resp.json()).then((translations) => { + window.localStorage.setItem(Translations.#KEY_TRANSLATIONS, JSON.stringify(translations)); + Translations.#foreignTranslations = translations; + }); } } var t = Translations.get; -var refreshCurrentLocale = Translations.refreshCurrentLocale; -refreshCurrentLocale(); +await Translations.init(); // src/utils/screenshot.ts class Screenshot { @@ -5301,6 +2217,496 @@ var getPref = prefs.get.bind(prefs); var setPref = prefs.set.bind(prefs); var toPrefElement = prefs.toElement.bind(prefs); +// src/modules/touch-controller.ts +var LOG_TAG = "TouchController"; + +class TouchController { + static #EVENT_SHOW_DEFAULT_CONTROLLER = new MessageEvent("message", { + data: JSON.stringify({ + content: '{"layoutId":""}', + target: "/streaming/touchcontrols/showlayoutv2", + type: "Message" + }), + origin: "better-xcloud" + }); + static #$style; + static #enable = false; + static #dataChannel; + static #customLayouts = {}; + static #baseCustomLayouts = {}; + static #currentLayoutId; + static #customList; + static enable() { + TouchController.#enable = true; + } + static disable() { + TouchController.#enable = false; + } + static isEnabled() { + return TouchController.#enable; + } + static #showDefault() { + TouchController.#dispatchMessage(TouchController.#EVENT_SHOW_DEFAULT_CONTROLLER); + } + static #show() { + document.querySelector("#BabylonCanvasContainer-main")?.parentElement?.classList.remove("bx-offscreen"); + } + static #hide() { + document.querySelector("#BabylonCanvasContainer-main")?.parentElement?.classList.add("bx-offscreen"); + } + static toggleVisibility(status) { + if (!TouchController.#dataChannel) { + return; + } + status ? TouchController.#hide() : TouchController.#show(); + } + static reset() { + TouchController.#enable = false; + TouchController.#dataChannel = null; + TouchController.#$style && (TouchController.#$style.textContent = ""); + } + static #dispatchMessage(msg) { + TouchController.#dataChannel && window.setTimeout(() => { + TouchController.#dataChannel.dispatchEvent(msg); + }, 10); + } + static #dispatchLayouts(data) { + BxEvent.dispatch(window, BxEvent.CUSTOM_TOUCH_LAYOUTS_LOADED, { + data + }); + } + static async getCustomLayouts(xboxTitleId, retries = 1) { + if (xboxTitleId in TouchController.#customLayouts) { + TouchController.#dispatchLayouts(TouchController.#customLayouts[xboxTitleId]); + return; + } + retries = retries || 1; + if (retries > 2) { + TouchController.#customLayouts[xboxTitleId] = null; + window.setTimeout(() => TouchController.#dispatchLayouts(null), 1000); + return; + } + const baseUrl = `https://raw.githubusercontent.com/redphx/better-xcloud/gh-pages/touch-layouts${BX_FLAGS.UseDevTouchLayout ? "/dev" : ""}`; + const url = `${baseUrl}/${xboxTitleId}.json`; + try { + const resp = await NATIVE_FETCH(url); + const json = await resp.json(); + const layouts = {}; + json.layouts.forEach(async (layoutName) => { + let baseLayouts = {}; + if (layoutName in TouchController.#baseCustomLayouts) { + baseLayouts = TouchController.#baseCustomLayouts[layoutName]; + } else { + try { + const layoutUrl = `${baseUrl}/layouts/${layoutName}.json`; + const resp2 = await NATIVE_FETCH(layoutUrl); + const json2 = await resp2.json(); + baseLayouts = json2.layouts; + TouchController.#baseCustomLayouts[layoutName] = baseLayouts; + } catch (e) { + } + } + Object.assign(layouts, baseLayouts); + }); + json.layouts = layouts; + TouchController.#customLayouts[xboxTitleId] = json; + window.setTimeout(() => TouchController.#dispatchLayouts(json), 1000); + } catch (e) { + TouchController.getCustomLayouts(xboxTitleId, retries + 1); + } + } + static loadCustomLayout(xboxTitleId, layoutId, delay = 0) { + if (!window.BX_EXPOSED.touchLayoutManager) { + const listener = (e) => { + window.removeEventListener(BxEvent.TOUCH_LAYOUT_MANAGER_READY, listener); + if (TouchController.#enable) { + TouchController.loadCustomLayout(xboxTitleId, layoutId, 0); + } + }; + window.addEventListener(BxEvent.TOUCH_LAYOUT_MANAGER_READY, listener); + return; + } + const layoutChanged = TouchController.#currentLayoutId !== layoutId; + TouchController.#currentLayoutId = layoutId; + const layoutData = TouchController.#customLayouts[xboxTitleId]; + if (!xboxTitleId || !layoutId || !layoutData) { + TouchController.#enable && TouchController.#showDefault(); + return; + } + const layout = layoutData.layouts[layoutId] || layoutData.layouts[layoutData.default_layout]; + if (!layout) { + return; + } + let msg; + let html9 = false; + if (layout.author) { + const author = `${escapeHtml(layout.author)}`; + msg = t("touch-control-layout-by", { name: author }); + html9 = true; + } else { + msg = t("touch-control-layout"); + } + layoutChanged && Toast.show(msg, layout.name, { html: html9 }); + window.setTimeout(() => { + window.BX_EXPOSED.shouldShowSensorControls = JSON.stringify(layout).includes("gyroscope"); + window.BX_EXPOSED.touchLayoutManager.changeLayoutForScope({ + type: "showLayout", + scope: xboxTitleId, + subscope: "base", + layout: { + id: "System.Standard", + displayName: "System", + layoutFile: layout + } + }); + }, delay); + } + static updateCustomList() { + const key = "better_xcloud_custom_touch_layouts"; + TouchController.#customList = JSON.parse(window.localStorage.getItem(key) || "[]"); + NATIVE_FETCH("https://raw.githubusercontent.com/redphx/better-xcloud/gh-pages/touch-layouts/ids.json").then((response) => response.json()).then((json) => { + TouchController.#customList = json; + window.localStorage.setItem(key, JSON.stringify(json)); + }); + } + static getCustomList() { + return TouchController.#customList; + } + static setup() { + window.testTouchLayout = (layout) => { + const { touchLayoutManager } = window.BX_EXPOSED; + touchLayoutManager && touchLayoutManager.changeLayoutForScope({ + type: "showLayout", + scope: "" + STATES.currentStream?.xboxTitleId, + subscope: "base", + layout: { + id: "System.Standard", + displayName: "Custom", + layoutFile: layout + } + }); + }; + const $style = document.createElement("style"); + document.documentElement.appendChild($style); + TouchController.#$style = $style; + const PREF_STYLE_STANDARD = getPref(PrefKey.STREAM_TOUCH_CONTROLLER_STYLE_STANDARD); + const PREF_STYLE_CUSTOM = getPref(PrefKey.STREAM_TOUCH_CONTROLLER_STYLE_CUSTOM); + window.addEventListener(BxEvent.DATA_CHANNEL_CREATED, (e) => { + const dataChannel = e.dataChannel; + if (!dataChannel || dataChannel.label !== "message") { + return; + } + let filter = ""; + if (TouchController.#enable) { + if (PREF_STYLE_STANDARD === "white") { + filter = "grayscale(1) brightness(2)"; + } else if (PREF_STYLE_STANDARD === "muted") { + filter = "sepia(0.5)"; + } + } else if (PREF_STYLE_CUSTOM === "muted") { + filter = "sepia(0.5)"; + } + if (filter) { + $style.textContent = `#babylon-canvas { filter: ${filter} !important; }`; + } else { + $style.textContent = ""; + } + TouchController.#dataChannel = dataChannel; + dataChannel.addEventListener("open", () => { + window.setTimeout(TouchController.#show, 1000); + }); + let focused = false; + dataChannel.addEventListener("message", (msg) => { + if (msg.origin === "better-xcloud" || typeof msg.data !== "string") { + return; + } + if (msg.data.includes("touchcontrols/showtitledefault")) { + if (TouchController.#enable) { + if (focused) { + TouchController.getCustomLayouts(STATES.currentStream?.xboxTitleId); + } else { + TouchController.#showDefault(); + } + } + return; + } + try { + if (msg.data.includes("/titleinfo")) { + const json = JSON.parse(JSON.parse(msg.data).content); + focused = json.focused; + if (!json.focused) { + TouchController.#show(); + } + STATES.currentStream.xboxTitleId = parseInt(json.titleid, 16).toString(); + } + } catch (e2) { + BxLogger.error(LOG_TAG, "Load custom layout", e2); + } + }); + }); + } +} + +// src/modules/game-bar/action-touch-control.ts +class TouchControlAction extends BaseGameBarAction { + $content; + constructor() { + super(); + const onClick = (e) => { + BxEvent.dispatch(window, BxEvent.GAME_BAR_ACTION_ACTIVATED); + const $parent = e.target.closest("div[data-enabled]"); + let enabled = $parent.getAttribute("data-enabled", "true") === "true"; + $parent.setAttribute("data-enabled", (!enabled).toString()); + TouchController.toggleVisibility(enabled); + }; + const $btnEnable = createButton({ + style: ButtonStyle.GHOST, + icon: BxIcon.TOUCH_CONTROL_ENABLE, + title: t("show-touch-controller"), + onClick, + classes: ["bx-activated"] + }); + const $btnDisable = createButton({ + style: ButtonStyle.GHOST, + icon: BxIcon.TOUCH_CONTROL_DISABLE, + title: t("hide-touch-controller"), + onClick + }); + this.$content = CE("div", {}, $btnEnable, $btnDisable); + this.reset(); + } + render() { + return this.$content; + } + reset() { + this.$content.setAttribute("data-enabled", "true"); + } +} + +// src/modules/game-bar/action-microphone.ts +var MicrophoneState; +(function(MicrophoneState2) { + MicrophoneState2["REQUESTED"] = "Requested"; + MicrophoneState2["ENABLED"] = "Enabled"; + MicrophoneState2["MUTED"] = "Muted"; + MicrophoneState2["NOT_ALLOWED"] = "NotAllowed"; + MicrophoneState2["NOT_FOUND"] = "NotFound"; +})(MicrophoneState || (MicrophoneState = {})); + +class MicrophoneAction extends BaseGameBarAction { + $content; + visible = false; + constructor() { + super(); + const onClick = (e) => { + BxEvent.dispatch(window, BxEvent.GAME_BAR_ACTION_ACTIVATED); + const state = this.$content.getAttribute("data-enabled"); + const enableMic = state === "true" ? false : true; + try { + window.BX_EXPOSED.streamSession.tryEnableChatAsync(enableMic); + this.$content.setAttribute("data-enabled", enableMic.toString()); + } catch (e2) { + console.log(e2); + } + }; + const $btnDefault = createButton({ + style: ButtonStyle.GHOST, + icon: BxIcon.MICROPHONE, + title: t("show-touch-controller"), + onClick, + classes: ["bx-activated"] + }); + const $btnMuted = createButton({ + style: ButtonStyle.GHOST, + icon: BxIcon.MICROPHONE_MUTED, + title: t("hide-touch-controller"), + onClick + }); + this.$content = CE("div", {}, $btnDefault, $btnMuted); + this.reset(); + window.addEventListener(BxEvent.MICROPHONE_STATE_CHANGED, (e) => { + const microphoneState = e.microphoneState; + const enabled = microphoneState === MicrophoneState.ENABLED; + this.$content.setAttribute("data-enabled", enabled.toString()); + this.$content.classList.remove("bx-gone"); + }); + } + render() { + return this.$content; + } + reset() { + this.visible = false; + this.$content.classList.add("bx-gone"); + this.$content.setAttribute("data-enabled", "false"); + } +} + +// src/modules/game-bar/game-bar.ts +class GameBar { + static instance; + static getInstance() { + if (!GameBar.instance) { + GameBar.instance = new GameBar; + } + return GameBar.instance; + } + static VISIBLE_DURATION = 2000; + $gameBar; + $container; + timeout = null; + actions = []; + constructor() { + let $container; + const position = getPref(PrefKey.GAME_BAR_POSITION); + const $gameBar = CE("div", { id: "bx-game-bar", class: "bx-gone", "data-position": position }, $container = CE("div", { class: "bx-game-bar-container bx-offscreen" }), createSvgIcon(position === "bottom-left" ? BxIcon.CARET_RIGHT : BxIcon.CARET_LEFT)); + this.actions = [ + new ScreenshotAction, + ...STATES.hasTouchSupport && getPref(PrefKey.STREAM_TOUCH_CONTROLLER) !== "off" ? [new TouchControlAction] : [], + new MicrophoneAction + ]; + if (position === "bottom-right") { + this.actions.reverse(); + } + for (const action of this.actions) { + $container.appendChild(action.render()); + } + $gameBar.addEventListener("click", (e) => { + if (e.target !== $gameBar) { + return; + } + $container.classList.contains("bx-show") ? this.hideBar() : this.showBar(); + }); + window.addEventListener(BxEvent.GAME_BAR_ACTION_ACTIVATED, this.hideBar.bind(this)); + $container.addEventListener("pointerover", this.clearHideTimeout.bind(this)); + $container.addEventListener("pointerout", this.beginHideTimeout.bind(this)); + $container.addEventListener("transitionend", (e) => { + const classList = $container.classList; + if (classList.contains("bx-hide")) { + classList.remove("bx-offscreen", "bx-hide"); + classList.add("bx-offscreen"); + } + }); + document.documentElement.appendChild($gameBar); + this.$gameBar = $gameBar; + this.$container = $container; + } + beginHideTimeout() { + this.clearHideTimeout(); + this.timeout = window.setTimeout(() => { + this.timeout = null; + this.hideBar(); + }, GameBar.VISIBLE_DURATION); + } + clearHideTimeout() { + this.timeout && clearTimeout(this.timeout); + this.timeout = null; + } + enable() { + this.$gameBar && this.$gameBar.classList.remove("bx-gone"); + } + disable() { + this.hideBar(); + this.$gameBar && this.$gameBar.classList.add("bx-gone"); + } + showBar() { + if (!this.$container) { + return; + } + this.$container.classList.remove("bx-offscreen", "bx-hide"); + this.$container.classList.add("bx-show"); + this.beginHideTimeout(); + } + hideBar() { + if (!this.$container) { + return; + } + this.$container.classList.remove("bx-show"); + this.$container.classList.add("bx-hide"); + } + reset() { + for (const action of this.actions) { + action.reset(); + } + } +} + +// src/utils/bx-exposed.ts +var InputType; +(function(InputType2) { + InputType2["CONTROLLER"] = "Controller"; + InputType2["MKB"] = "MKB"; + InputType2["CUSTOM_TOUCH_OVERLAY"] = "CustomTouchOverlay"; + InputType2["GENERIC_TOUCH"] = "GenericTouch"; + InputType2["NATIVE_TOUCH"] = "NativeTouch"; + InputType2["BATIVE_SENSOR"] = "NativeSensor"; +})(InputType || (InputType = {})); +var BxExposed = { + onPollingModeChanged: (mode) => { + if (getPref(PrefKey.GAME_BAR_POSITION) === "off") { + return; + } + const gameBar = GameBar.getInstance(); + if (!STATES.isPlaying) { + gameBar.disable(); + return; + } + mode !== "None" ? gameBar.disable() : gameBar.enable(); + }, + getTitleInfo: () => STATES.currentStream.titleInfo, + modifyTitleInfo: (titleInfo) => { + titleInfo = structuredClone(titleInfo); + let supportedInputTypes = titleInfo.details.supportedInputTypes; + if (getPref(PrefKey.NATIVE_MKB_DISABLED) || UserAgent.isMobile()) { + supportedInputTypes = supportedInputTypes.filter((i) => i !== InputType.MKB); + } + titleInfo.details.hasMkbSupport = supportedInputTypes.includes(InputType.MKB); + if (STATES.hasTouchSupport) { + let touchControllerAvailability = getPref(PrefKey.STREAM_TOUCH_CONTROLLER); + if (touchControllerAvailability !== "off" && getPref(PrefKey.STREAM_TOUCH_CONTROLLER_AUTO_OFF)) { + const gamepads = window.navigator.getGamepads(); + let gamepadFound = false; + for (let gamepad of gamepads) { + if (gamepad && gamepad.connected) { + gamepadFound = true; + break; + } + } + gamepadFound && (touchControllerAvailability = "off"); + } + if (touchControllerAvailability === "off") { + supportedInputTypes = supportedInputTypes.filter((i) => i !== InputType.CUSTOM_TOUCH_OVERLAY && i !== InputType.GENERIC_TOUCH); + } + titleInfo.details.hasTouchSupport = supportedInputTypes.includes(InputType.NATIVE_TOUCH) || supportedInputTypes.includes(InputType.CUSTOM_TOUCH_OVERLAY) || supportedInputTypes.includes(InputType.GENERIC_TOUCH); + if (!titleInfo.details.hasTouchSupport && touchControllerAvailability === "all") { + titleInfo.details.hasFakeTouchSupport = true; + supportedInputTypes.push(InputType.GENERIC_TOUCH); + } + } + titleInfo.details.supportedInputTypes = supportedInputTypes; + STATES.currentStream.titleInfo = titleInfo; + BxEvent.dispatch(window, BxEvent.TITLE_INFO_READY); + return titleInfo; + }, + setupGainNode: ($media, audioStream) => { + if ($media instanceof HTMLAudioElement) { + $media.muted = true; + $media.addEventListener("playing", (e) => { + $media.muted = true; + $media.pause(); + }); + } else { + $media.muted = true; + $media.addEventListener("playing", (e) => { + $media.muted = true; + }); + } + const audioCtx = STATES.currentStream.audioContext; + const source = audioCtx.createMediaStreamSource(audioStream); + const gainNode = audioCtx.createGain(); + source.connect(gainNode).connect(audioCtx.destination); + } +}; + // src/utils/region.ts function getPreferredServerRegion(shortName = false) { let preferredRegion = getPref(PrefKey.SERVER_REGION); @@ -5964,7 +3370,7 @@ function showStreamSettings(tabId) { } // src/modules/mkb/mkb-handler.ts -var LOG_TAG = "MkbHandler"; +var LOG_TAG2 = "MkbHandler"; class MkbHandler { static #instance; @@ -6302,7 +3708,7 @@ class MkbHandler { static setupEvents() { getPref(PrefKey.MKB_ENABLED) && !UserAgent.isMobile() && window.addEventListener(BxEvent.STREAM_PLAYING, () => { if (!STATES.currentStream.titleInfo?.details.hasMkbSupport) { - BxLogger.info(LOG_TAG, "Emulate MKB"); + BxLogger.info(LOG_TAG2, "Emulate MKB"); MkbHandler.INSTANCE.init(); } }); @@ -7301,7 +4707,7 @@ function setupStreamUi() { } // src/modules/remote-play.ts -var LOG_TAG2 = "RemotePlay"; +var LOG_TAG3 = "RemotePlay"; var RemotePlayConsoleState; (function(RemotePlayConsoleState2) { RemotePlayConsoleState2["ON"] = "On"; @@ -7367,7 +4773,7 @@ class RemotePlay { RemotePlay.#$content = CE("div", {}, t("getting-consoles-list")); RemotePlay.#getXhomeToken(() => { RemotePlay.#getConsolesList(() => { - BxLogger.info(LOG_TAG2, "Consoles", RemotePlay.#CONSOLES); + BxLogger.info(LOG_TAG3, "Consoles", RemotePlay.#CONSOLES); RemotePlay.#renderConsoles(); BxEvent.dispatch(window, BxEvent.REMOTE_PLAY_READY); }); @@ -7755,7 +5161,6 @@ function interceptHttpRequests() { return XcloudInterceptor.handle(request, init); }; } -var NATIVE_FETCH = window.fetch; var RequestType; (function(RequestType2) { RequestType2["XCLOUD"] = "xcloud"; @@ -8034,496 +5439,6 @@ class XcloudInterceptor { } } -// src/modules/touch-controller.ts -var LOG_TAG3 = "TouchController"; - -class TouchController { - static #EVENT_SHOW_DEFAULT_CONTROLLER = new MessageEvent("message", { - data: JSON.stringify({ - content: '{"layoutId":""}', - target: "/streaming/touchcontrols/showlayoutv2", - type: "Message" - }), - origin: "better-xcloud" - }); - static #$style; - static #enable = false; - static #dataChannel; - static #customLayouts = {}; - static #baseCustomLayouts = {}; - static #currentLayoutId; - static #customList; - static enable() { - TouchController.#enable = true; - } - static disable() { - TouchController.#enable = false; - } - static isEnabled() { - return TouchController.#enable; - } - static #showDefault() { - TouchController.#dispatchMessage(TouchController.#EVENT_SHOW_DEFAULT_CONTROLLER); - } - static #show() { - document.querySelector("#BabylonCanvasContainer-main")?.parentElement?.classList.remove("bx-offscreen"); - } - static #hide() { - document.querySelector("#BabylonCanvasContainer-main")?.parentElement?.classList.add("bx-offscreen"); - } - static toggleVisibility(status) { - if (!TouchController.#dataChannel) { - return; - } - status ? TouchController.#hide() : TouchController.#show(); - } - static reset() { - TouchController.#enable = false; - TouchController.#dataChannel = null; - TouchController.#$style && (TouchController.#$style.textContent = ""); - } - static #dispatchMessage(msg) { - TouchController.#dataChannel && window.setTimeout(() => { - TouchController.#dataChannel.dispatchEvent(msg); - }, 10); - } - static #dispatchLayouts(data) { - BxEvent.dispatch(window, BxEvent.CUSTOM_TOUCH_LAYOUTS_LOADED, { - data - }); - } - static async getCustomLayouts(xboxTitleId, retries = 1) { - if (xboxTitleId in TouchController.#customLayouts) { - TouchController.#dispatchLayouts(TouchController.#customLayouts[xboxTitleId]); - return; - } - retries = retries || 1; - if (retries > 2) { - TouchController.#customLayouts[xboxTitleId] = null; - window.setTimeout(() => TouchController.#dispatchLayouts(null), 1000); - return; - } - const baseUrl = `https://raw.githubusercontent.com/redphx/better-xcloud/gh-pages/touch-layouts${BX_FLAGS.UseDevTouchLayout ? "/dev" : ""}`; - const url = `${baseUrl}/${xboxTitleId}.json`; - try { - const resp = await NATIVE_FETCH(url); - const json = await resp.json(); - const layouts = {}; - json.layouts.forEach(async (layoutName) => { - let baseLayouts = {}; - if (layoutName in TouchController.#baseCustomLayouts) { - baseLayouts = TouchController.#baseCustomLayouts[layoutName]; - } else { - try { - const layoutUrl = `${baseUrl}/layouts/${layoutName}.json`; - const resp2 = await NATIVE_FETCH(layoutUrl); - const json2 = await resp2.json(); - baseLayouts = json2.layouts; - TouchController.#baseCustomLayouts[layoutName] = baseLayouts; - } catch (e) { - } - } - Object.assign(layouts, baseLayouts); - }); - json.layouts = layouts; - TouchController.#customLayouts[xboxTitleId] = json; - window.setTimeout(() => TouchController.#dispatchLayouts(json), 1000); - } catch (e) { - TouchController.getCustomLayouts(xboxTitleId, retries + 1); - } - } - static loadCustomLayout(xboxTitleId, layoutId, delay = 0) { - if (!window.BX_EXPOSED.touchLayoutManager) { - const listener = (e) => { - window.removeEventListener(BxEvent.TOUCH_LAYOUT_MANAGER_READY, listener); - if (TouchController.#enable) { - TouchController.loadCustomLayout(xboxTitleId, layoutId, 0); - } - }; - window.addEventListener(BxEvent.TOUCH_LAYOUT_MANAGER_READY, listener); - return; - } - const layoutChanged = TouchController.#currentLayoutId !== layoutId; - TouchController.#currentLayoutId = layoutId; - const layoutData = TouchController.#customLayouts[xboxTitleId]; - if (!xboxTitleId || !layoutId || !layoutData) { - TouchController.#enable && TouchController.#showDefault(); - return; - } - const layout = layoutData.layouts[layoutId] || layoutData.layouts[layoutData.default_layout]; - if (!layout) { - return; - } - let msg; - let html16 = false; - if (layout.author) { - const author = `${escapeHtml(layout.author)}`; - msg = t("touch-control-layout-by", { name: author }); - html16 = true; - } else { - msg = t("touch-control-layout"); - } - layoutChanged && Toast.show(msg, layout.name, { html: html16 }); - window.setTimeout(() => { - window.BX_EXPOSED.shouldShowSensorControls = JSON.stringify(layout).includes("gyroscope"); - window.BX_EXPOSED.touchLayoutManager.changeLayoutForScope({ - type: "showLayout", - scope: xboxTitleId, - subscope: "base", - layout: { - id: "System.Standard", - displayName: "System", - layoutFile: layout - } - }); - }, delay); - } - static updateCustomList() { - const key = "better_xcloud_custom_touch_layouts"; - TouchController.#customList = JSON.parse(window.localStorage.getItem(key) || "[]"); - NATIVE_FETCH("https://raw.githubusercontent.com/redphx/better-xcloud/gh-pages/touch-layouts/ids.json").then((response) => response.json()).then((json) => { - TouchController.#customList = json; - window.localStorage.setItem(key, JSON.stringify(json)); - }); - } - static getCustomList() { - return TouchController.#customList; - } - static setup() { - window.testTouchLayout = (layout) => { - const { touchLayoutManager } = window.BX_EXPOSED; - touchLayoutManager && touchLayoutManager.changeLayoutForScope({ - type: "showLayout", - scope: "" + STATES.currentStream?.xboxTitleId, - subscope: "base", - layout: { - id: "System.Standard", - displayName: "Custom", - layoutFile: layout - } - }); - }; - const $style = document.createElement("style"); - document.documentElement.appendChild($style); - TouchController.#$style = $style; - const PREF_STYLE_STANDARD = getPref(PrefKey.STREAM_TOUCH_CONTROLLER_STYLE_STANDARD); - const PREF_STYLE_CUSTOM = getPref(PrefKey.STREAM_TOUCH_CONTROLLER_STYLE_CUSTOM); - window.addEventListener(BxEvent.DATA_CHANNEL_CREATED, (e) => { - const dataChannel = e.dataChannel; - if (!dataChannel || dataChannel.label !== "message") { - return; - } - let filter = ""; - if (TouchController.#enable) { - if (PREF_STYLE_STANDARD === "white") { - filter = "grayscale(1) brightness(2)"; - } else if (PREF_STYLE_STANDARD === "muted") { - filter = "sepia(0.5)"; - } - } else if (PREF_STYLE_CUSTOM === "muted") { - filter = "sepia(0.5)"; - } - if (filter) { - $style.textContent = `#babylon-canvas { filter: ${filter} !important; }`; - } else { - $style.textContent = ""; - } - TouchController.#dataChannel = dataChannel; - dataChannel.addEventListener("open", () => { - window.setTimeout(TouchController.#show, 1000); - }); - let focused = false; - dataChannel.addEventListener("message", (msg) => { - if (msg.origin === "better-xcloud" || typeof msg.data !== "string") { - return; - } - if (msg.data.includes("touchcontrols/showtitledefault")) { - if (TouchController.#enable) { - if (focused) { - TouchController.getCustomLayouts(STATES.currentStream?.xboxTitleId); - } else { - TouchController.#showDefault(); - } - } - return; - } - try { - if (msg.data.includes("/titleinfo")) { - const json = JSON.parse(JSON.parse(msg.data).content); - focused = json.focused; - if (!json.focused) { - TouchController.#show(); - } - STATES.currentStream.xboxTitleId = parseInt(json.titleid, 16).toString(); - } - } catch (e2) { - BxLogger.error(LOG_TAG3, "Load custom layout", e2); - } - }); - }); - } -} - -// src/modules/game-bar/action-touch-control.ts -class TouchControlAction extends BaseGameBarAction { - $content; - constructor() { - super(); - const onClick = (e) => { - BxEvent.dispatch(window, BxEvent.GAME_BAR_ACTION_ACTIVATED); - const $parent = e.target.closest("div[data-enabled]"); - let enabled = $parent.getAttribute("data-enabled", "true") === "true"; - $parent.setAttribute("data-enabled", (!enabled).toString()); - TouchController.toggleVisibility(enabled); - }; - const $btnEnable = createButton({ - style: ButtonStyle.GHOST, - icon: BxIcon.TOUCH_CONTROL_ENABLE, - title: t("show-touch-controller"), - onClick, - classes: ["bx-activated"] - }); - const $btnDisable = createButton({ - style: ButtonStyle.GHOST, - icon: BxIcon.TOUCH_CONTROL_DISABLE, - title: t("hide-touch-controller"), - onClick - }); - this.$content = CE("div", {}, $btnEnable, $btnDisable); - this.reset(); - } - render() { - return this.$content; - } - reset() { - this.$content.setAttribute("data-enabled", "true"); - } -} - -// src/modules/game-bar/action-microphone.ts -var MicrophoneState; -(function(MicrophoneState2) { - MicrophoneState2["REQUESTED"] = "Requested"; - MicrophoneState2["ENABLED"] = "Enabled"; - MicrophoneState2["MUTED"] = "Muted"; - MicrophoneState2["NOT_ALLOWED"] = "NotAllowed"; - MicrophoneState2["NOT_FOUND"] = "NotFound"; -})(MicrophoneState || (MicrophoneState = {})); - -class MicrophoneAction extends BaseGameBarAction { - $content; - visible = false; - constructor() { - super(); - const onClick = (e) => { - BxEvent.dispatch(window, BxEvent.GAME_BAR_ACTION_ACTIVATED); - const state = this.$content.getAttribute("data-enabled"); - const enableMic = state === "true" ? false : true; - try { - window.BX_EXPOSED.streamSession.tryEnableChatAsync(enableMic); - this.$content.setAttribute("data-enabled", enableMic.toString()); - } catch (e2) { - console.log(e2); - } - }; - const $btnDefault = createButton({ - style: ButtonStyle.GHOST, - icon: BxIcon.MICROPHONE, - title: t("show-touch-controller"), - onClick, - classes: ["bx-activated"] - }); - const $btnMuted = createButton({ - style: ButtonStyle.GHOST, - icon: BxIcon.MICROPHONE_MUTED, - title: t("hide-touch-controller"), - onClick - }); - this.$content = CE("div", {}, $btnDefault, $btnMuted); - this.reset(); - window.addEventListener(BxEvent.MICROPHONE_STATE_CHANGED, (e) => { - const microphoneState = e.microphoneState; - const enabled = microphoneState === MicrophoneState.ENABLED; - this.$content.setAttribute("data-enabled", enabled.toString()); - this.$content.classList.remove("bx-gone"); - }); - } - render() { - return this.$content; - } - reset() { - this.visible = false; - this.$content.classList.add("bx-gone"); - this.$content.setAttribute("data-enabled", "false"); - } -} - -// src/modules/game-bar/game-bar.ts -class GameBar { - static instance; - static getInstance() { - if (!GameBar.instance) { - GameBar.instance = new GameBar; - } - return GameBar.instance; - } - static VISIBLE_DURATION = 2000; - $gameBar; - $container; - timeout = null; - actions = []; - constructor() { - let $container; - const position = getPref(PrefKey.GAME_BAR_POSITION); - const $gameBar = CE("div", { id: "bx-game-bar", class: "bx-gone", "data-position": position }, $container = CE("div", { class: "bx-game-bar-container bx-offscreen" }), createSvgIcon(position === "bottom-left" ? BxIcon.CARET_RIGHT : BxIcon.CARET_LEFT)); - this.actions = [ - new ScreenshotAction, - ...STATES.hasTouchSupport && getPref(PrefKey.STREAM_TOUCH_CONTROLLER) !== "off" ? [new TouchControlAction] : [], - new MicrophoneAction - ]; - if (position === "bottom-right") { - this.actions.reverse(); - } - for (const action of this.actions) { - $container.appendChild(action.render()); - } - $gameBar.addEventListener("click", (e) => { - if (e.target !== $gameBar) { - return; - } - $container.classList.contains("bx-show") ? this.hideBar() : this.showBar(); - }); - window.addEventListener(BxEvent.GAME_BAR_ACTION_ACTIVATED, this.hideBar.bind(this)); - $container.addEventListener("pointerover", this.clearHideTimeout.bind(this)); - $container.addEventListener("pointerout", this.beginHideTimeout.bind(this)); - $container.addEventListener("transitionend", (e) => { - const classList = $container.classList; - if (classList.contains("bx-hide")) { - classList.remove("bx-offscreen", "bx-hide"); - classList.add("bx-offscreen"); - } - }); - document.documentElement.appendChild($gameBar); - this.$gameBar = $gameBar; - this.$container = $container; - } - beginHideTimeout() { - this.clearHideTimeout(); - this.timeout = window.setTimeout(() => { - this.timeout = null; - this.hideBar(); - }, GameBar.VISIBLE_DURATION); - } - clearHideTimeout() { - this.timeout && clearTimeout(this.timeout); - this.timeout = null; - } - enable() { - this.$gameBar && this.$gameBar.classList.remove("bx-gone"); - } - disable() { - this.hideBar(); - this.$gameBar && this.$gameBar.classList.add("bx-gone"); - } - showBar() { - if (!this.$container) { - return; - } - this.$container.classList.remove("bx-offscreen", "bx-hide"); - this.$container.classList.add("bx-show"); - this.beginHideTimeout(); - } - hideBar() { - if (!this.$container) { - return; - } - this.$container.classList.remove("bx-show"); - this.$container.classList.add("bx-hide"); - } - reset() { - for (const action of this.actions) { - action.reset(); - } - } -} - -// src/utils/bx-exposed.ts -var InputType; -(function(InputType2) { - InputType2["CONTROLLER"] = "Controller"; - InputType2["MKB"] = "MKB"; - InputType2["CUSTOM_TOUCH_OVERLAY"] = "CustomTouchOverlay"; - InputType2["GENERIC_TOUCH"] = "GenericTouch"; - InputType2["NATIVE_TOUCH"] = "NativeTouch"; - InputType2["BATIVE_SENSOR"] = "NativeSensor"; -})(InputType || (InputType = {})); -var BxExposed = { - onPollingModeChanged: (mode) => { - if (getPref(PrefKey.GAME_BAR_POSITION) === "off") { - return; - } - const gameBar = GameBar.getInstance(); - if (!STATES.isPlaying) { - gameBar.disable(); - return; - } - mode !== "None" ? gameBar.disable() : gameBar.enable(); - }, - getTitleInfo: () => STATES.currentStream.titleInfo, - modifyTitleInfo: (titleInfo) => { - titleInfo = structuredClone(titleInfo); - let supportedInputTypes = titleInfo.details.supportedInputTypes; - if (getPref(PrefKey.NATIVE_MKB_DISABLED) || UserAgent.isMobile()) { - supportedInputTypes = supportedInputTypes.filter((i) => i !== InputType.MKB); - } - titleInfo.details.hasMkbSupport = supportedInputTypes.includes(InputType.MKB); - if (STATES.hasTouchSupport) { - let touchControllerAvailability = getPref(PrefKey.STREAM_TOUCH_CONTROLLER); - if (touchControllerAvailability !== "off" && getPref(PrefKey.STREAM_TOUCH_CONTROLLER_AUTO_OFF)) { - const gamepads = window.navigator.getGamepads(); - let gamepadFound = false; - for (let gamepad of gamepads) { - if (gamepad && gamepad.connected) { - gamepadFound = true; - break; - } - } - gamepadFound && (touchControllerAvailability = "off"); - } - if (touchControllerAvailability === "off") { - supportedInputTypes = supportedInputTypes.filter((i) => i !== InputType.CUSTOM_TOUCH_OVERLAY && i !== InputType.GENERIC_TOUCH); - } - titleInfo.details.hasTouchSupport = supportedInputTypes.includes(InputType.NATIVE_TOUCH) || supportedInputTypes.includes(InputType.CUSTOM_TOUCH_OVERLAY) || supportedInputTypes.includes(InputType.GENERIC_TOUCH); - if (!titleInfo.details.hasTouchSupport && touchControllerAvailability === "all") { - titleInfo.details.hasFakeTouchSupport = true; - supportedInputTypes.push(InputType.GENERIC_TOUCH); - } - } - titleInfo.details.supportedInputTypes = supportedInputTypes; - STATES.currentStream.titleInfo = titleInfo; - BxEvent.dispatch(window, BxEvent.TITLE_INFO_READY); - return titleInfo; - }, - setupGainNode: ($media, audioStream) => { - if ($media instanceof HTMLAudioElement) { - $media.muted = true; - $media.addEventListener("playing", (e) => { - $media.muted = true; - $media.pause(); - }); - } else { - $media.muted = true; - $media.addEventListener("playing", (e) => { - $media.muted = true; - }); - } - const audioCtx = STATES.currentStream.audioContext; - const source = audioCtx.createMediaStreamSource(audioStream); - const gainNode = audioCtx.createGain(); - source.connect(gainNode).connect(audioCtx.destination); - } -}; - // src/utils/gamepad.ts function showGamepadToast(gamepad) { if (gamepad.id === MkbHandler.VIRTUAL_GAMEPAD_ID) { @@ -9902,6 +6817,7 @@ function checkForUpdate() { setPref(PrefKey.LATEST_VERSION, json.tag_name.substring(1)); setPref(PrefKey.CURRENT_VERSION, SCRIPT_VERSION); }); + Translations.updateTranslations(true); } function disablePwa() { const userAgent2 = (window.navigator.orgUserAgent || window.navigator.userAgent || "").toLowerCase(); @@ -10617,13 +7533,14 @@ function setupSettingsUi() { $wrapper.appendChild($btn); } } - const onChange = (e) => { + const onChange = async (e) => { PatcherCache.clear(); $btnReload.classList.add("bx-danger"); const $btnHeaderSettings = document.querySelector(".bx-header-settings-button"); $btnHeaderSettings && $btnHeaderSettings.classList.add("bx-danger"); if (e.target.id === "bx_setting_" + PrefKey.BETTER_XCLOUD_LOCALE) { - refreshCurrentLocale(); + Translations.refreshCurrentLocale(); + await Translations.updateTranslations(); $btnReload.textContent = t("settings-reloading"); $btnReload.click(); }