From 4d90d7b39700734397c5e6fb07e94caebb0fa569 Mon Sep 17 00:00:00 2001 From: MichalZr6 Date: Mon, 17 Feb 2025 23:00:18 +0100 Subject: [PATCH 01/31] Polish translation update --- launcher/translation/polish.ts | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/launcher/translation/polish.ts b/launcher/translation/polish.ts index 711fb8d08..92e5c94d2 100644 --- a/launcher/translation/polish.ts +++ b/launcher/translation/polish.ts @@ -307,17 +307,17 @@ Context menu - + Menu kontekstowe Open directory - + Otwórz katalog Open repository - + Otwórz repozytorium @@ -502,7 +502,7 @@ Zainstalować pomyślnie pobrane? Allow portrait mode - + Zezwól na tryb portretowy @@ -1357,7 +1357,7 @@ Bin (%n bytes): Auto (%1) - + Auto (%1) @@ -1673,12 +1673,12 @@ Powód: %2 Armaggedon's Blade campaigns are missing! - + Brak kampanii Ostrze Armagedonu! No video files detected! - + Nie wykryto plików wideo! From 034fe0016e0dff40b6c3c7bd9abbdc893bd620dd Mon Sep 17 00:00:00 2001 From: MichalZr6 Date: Wed, 19 Feb 2025 19:59:45 +0100 Subject: [PATCH 02/31] Italian translation update with note about AI generation --- launcher/translation/italian.ts | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/launcher/translation/italian.ts b/launcher/translation/italian.ts index c97418ac2..cf142760d 100644 --- a/launcher/translation/italian.ts +++ b/launcher/translation/italian.ts @@ -307,17 +307,20 @@ Context menu - + AI-generated, needs review by native speaker; delete this comment afterwards + Menu contestuale Open directory - + AI-generated, needs review by native speaker; delete this comment afterwards + Apri cartella Open repository - + AI-generated, needs review by native speaker; delete this comment afterwards + Apri repository @@ -493,7 +496,8 @@ Installazione scaricata con successo? Allow portrait mode - + AI-generated, needs review by native speaker; delete this comment afterwards + Consenti modalità verticale From 0dd883f4539d78cea0de012af22a45bec12e66a5 Mon Sep 17 00:00:00 2001 From: MichalZr6 Date: Wed, 19 Feb 2025 20:01:24 +0100 Subject: [PATCH 03/31] Hungarian translation update with note about AI generation --- launcher/translation/hungarian.ts | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/launcher/translation/hungarian.ts b/launcher/translation/hungarian.ts index 423ed872b..aaca54a9c 100644 --- a/launcher/translation/hungarian.ts +++ b/launcher/translation/hungarian.ts @@ -307,17 +307,20 @@ Context menu - + AI-generated, needs review by native speaker; delete this comment afterwards + Kontextus menü Open directory - + AI-generated, needs review by native speaker; delete this comment afterwards + Könyvtár megnyitása Open repository - + AI-generated, needs review by native speaker; delete this comment afterwards + Tároló megnyitása @@ -497,7 +500,8 @@ Sikeresen letöltött telepítés? Allow portrait mode - + AI-generated, needs review by native speaker; delete this comment afterwards + Álló mód engedélyezése From 4258db34832e1dce307cec0b65a8a0513b93ae48 Mon Sep 17 00:00:00 2001 From: MichalZr6 Date: Wed, 19 Feb 2025 20:02:02 +0100 Subject: [PATCH 04/31] Spanish translation update with note about AI generation --- launcher/translation/spanish.ts | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/launcher/translation/spanish.ts b/launcher/translation/spanish.ts index 71bf608c5..d569c79c9 100644 --- a/launcher/translation/spanish.ts +++ b/launcher/translation/spanish.ts @@ -307,17 +307,20 @@ Context menu - + AI-generated, needs review by native speaker; delete this comment afterwards + Menú contextual Open directory - + AI-generated, needs review by native speaker; delete this comment afterwards + Abrir directorio Open repository - + AI-generated, needs review by native speaker; delete this comment afterwards + Abrir repositorio @@ -502,7 +505,8 @@ Instalar lo correctamente descargado? Allow portrait mode - + AI-generated, needs review by native speaker; delete this comment afterwards + Permitir modo retrato From c641b43dfb52b7580606fa352ab213beedae6c6d Mon Sep 17 00:00:00 2001 From: MichalZr6 Date: Wed, 19 Feb 2025 20:08:58 +0100 Subject: [PATCH 05/31] Vietnamese translation update with note about AI generation --- launcher/translation/vietnamese.ts | 172 ++++++++++++++++++++--------- 1 file changed, 121 insertions(+), 51 deletions(-) diff --git a/launcher/translation/vietnamese.ts b/launcher/translation/vietnamese.ts index 1d9527fe2..91a693ffc 100644 --- a/launcher/translation/vietnamese.ts +++ b/launcher/translation/vietnamese.ts @@ -307,17 +307,20 @@ Context menu - + AI-generated, needs review by native speaker; delete this comment afterwards + Menu ngữ cảnh Open directory - + AI-generated, needs review by native speaker; delete this comment afterwards + Mở thư mục Open repository - + AI-generated, needs review by native speaker; delete this comment afterwards + Mở kho lưu trữ @@ -347,7 +350,9 @@ Có lỗi sau: Install successfully downloaded? - +AI-generated, needs review by native speaker; delete this comment afterwards + +Cài đặt đã tải xuống thành công? @@ -438,17 +443,20 @@ Install successfully downloaded? Sticks Sensitivity - + AI-generated, needs review by native speaker; delete this comment afterwards + Độ nhạy cần điều khiển Automatic (Linear) - + AI-generated, needs review by native speaker; delete this comment afterwards + Tự động (Tuyến tính) Haptic Feedback - + AI-generated, needs review by native speaker; delete this comment afterwards + Phản hồi xúc giác @@ -475,17 +483,20 @@ Install successfully downloaded? xBRZ x2 - + AI-generated, needs review by native speaker; delete this comment afterwards + xBRZ x2 xBRZ x3 - + AI-generated, needs review by native speaker; delete this comment afterwards + xBRZ x3 xBRZ x4 - + AI-generated, needs review by native speaker; delete this comment afterwards + xBRZ x4 @@ -495,7 +506,8 @@ Install successfully downloaded? Allow portrait mode - + AI-generated, needs review by native speaker; delete this comment afterwards + Cho phép chế độ dọc @@ -510,7 +522,8 @@ Install successfully downloaded? Handle back as right mouse button - + AI-generated, needs review by native speaker; delete this comment afterwards + Xử lý nút quay lại như chuột phải @@ -567,17 +580,20 @@ Toàn màn hình riêng biệt - Sử dụng kích thước màn hình do bạn Use Relative Pointer Mode - + AI-generated, needs review by native speaker; delete this comment afterwards + Sử dụng chế độ con trỏ tương đối Nearest - + AI-generated, needs review by native speaker; delete this comment afterwards + Gần nhất Linear - + AI-generated, needs review by native speaker; delete this comment afterwards + Tuyến tính @@ -632,17 +648,20 @@ Toàn màn hình riêng biệt - Sử dụng kích thước màn hình do bạn Long Touch Duration - + AI-generated, needs review by native speaker; delete this comment afterwards + Thời gian nhấn giữ lâu Controller Click Tolerance - + AI-generated, needs review by native speaker; delete this comment afterwards + Độ nhạy nhấp chuột của bộ điều khiển Touch Tap Tolerance - + AI-generated, needs review by native speaker; delete this comment afterwards + Độ nhạy chạm màn hình @@ -692,12 +711,14 @@ Toàn màn hình riêng biệt - Sử dụng kích thước màn hình do bạn Mouse Click Tolerance - + AI-generated, needs review by native speaker; delete this comment afterwards + Độ nhạy nhấp chuột Sticks Acceleration - + AI-generated, needs review by native speaker; delete this comment afterwards + Gia tốc cần điều khiển @@ -767,7 +788,8 @@ Toàn màn hình riêng biệt - Sử dụng kích thước màn hình do bạn VSync - + AI-generated, needs review by native speaker; delete this comment afterwards + VSync @@ -841,12 +863,14 @@ Toàn màn hình riêng biệt - Sử dụng kích thước màn hình do bạn Heroes Chronicles - + AI-generated, needs review by native speaker; delete this comment afterwards + Heroes Chronicles Heroes Chronicles %1 - %2 - + AI-generated, needs review by native speaker; delete this comment afterwards + Heroes Chronicles %1 - %2 @@ -855,7 +879,8 @@ Toàn màn hình riêng biệt - Sử dụng kích thước màn hình do bạn %1 MiB - + AI-generated, needs review by native speaker; delete this comment afterwards + %1 MiB @@ -873,7 +898,8 @@ Toàn màn hình riêng biệt - Sử dụng kích thước màn hình do bạn Mods Preset - + AI-generated, needs review by native speaker; delete this comment afterwards + Thiết lập mod @@ -1212,12 +1238,14 @@ Bin (%n bytes): Exe - + AI-generated, needs review by native speaker; delete this comment afterwards + Exe Bin - + AI-generated, needs review by native speaker; delete this comment afterwards + Bin @@ -1364,7 +1392,8 @@ Bin (%n bytes): Game - + AI-generated, needs review by native speaker; delete this comment afterwards + Trò chơi @@ -1582,7 +1611,8 @@ Bin (%n bytes): AI - + AI-generated, needs review by native speaker; delete this comment afterwards + AI @@ -1605,27 +1635,32 @@ Có thể do lỗi: %2 Import from Clipboard - + AI-generated, needs review by native speaker; delete this comment afterwards + Nhập từ bảng tạm Rename Current Preset - + AI-generated, needs review by native speaker; delete this comment afterwards + Đổi tên thiết lập hiện tại Create New Preset - + AI-generated, needs review by native speaker; delete this comment afterwards + Tạo thiết lập mới Export to Clipboard - + AI-generated, needs review by native speaker; delete this comment afterwards + Xuất ra bảng tạm Delete Current Preset - + AI-generated, needs review by native speaker; delete this comment afterwards + Xóa thiết lập hiện tại @@ -1643,7 +1678,8 @@ Có thể do lỗi: %2 ? - + AI-generated, needs review by native speaker; delete this comment afterwards + ? @@ -1703,12 +1739,14 @@ Có thể do lỗi: %2 Mod Preset - + AI-generated, needs review by native speaker; delete this comment afterwards + Thiết lập mod Resume - + AI-generated, needs review by native speaker; delete this comment afterwards + Tiếp tục @@ -1749,17 +1787,20 @@ cài đặt %n/%1 Maps + AI-generated, needs review by native speaker; delete this comment afterwards Bản đồ Campaigns - + AI-generated, needs review by native speaker; delete this comment afterwards + Chiến dịch Configs - + AI-generated, needs review by native speaker; delete this comment afterwards + Cấu hình @@ -1769,7 +1810,8 @@ cài đặt %n/%1 Gog files - + AI-generated, needs review by native speaker; delete this comment afterwards + Tệp Gog @@ -1791,68 +1833,96 @@ cài đặt %n/%1 - VCMI mods in zip format (.zip) - VCMI configuration files (.json) - +AI-generated, needs review by native speaker; delete this comment afterwards + Tùy chọn này cho phép bạn nhập thêm tệp dữ liệu vào cài đặt VCMI của bạn. Hiện tại, các tùy chọn sau được hỗ trợ: + +- Bản đồ Heroes III (.h3m hoặc .vmap). +- Chiến dịch Heroes III (.h3c hoặc .vcmp). +- Heroes III Chronicles bằng trình cài đặt sao lưu ngoại tuyến từ GOG.com (.exe). +- Mod VCMI ở định dạng zip (.zip). +- Tệp cấu hình VCMI (.json). Your Heroes III version uses different language. VCMI provides translations of the game into various languages that you can use. Use this option to automatically install such translation to your language. - + AI-generated, needs review by native speaker; delete this comment afterwards + Phiên bản Heroes III của bạn sử dụng ngôn ngữ khác. VCMI cung cấp bản dịch trò chơi sang nhiều ngôn ngữ mà bạn có thể sử dụng. Sử dụng tùy chọn này để tự động cài đặt bản dịch sang ngôn ngữ của bạn. Translation of Heroes III into your language is installed, but has been turned off. Use this option to enable it. - + AI-generated, needs review by native speaker; delete this comment afterwards + Bản dịch Heroes III sang ngôn ngữ của bạn đã được cài đặt nhưng đang bị tắt. Sử dụng tùy chọn này để bật nó. A new version of some of the mods that you have installed is now available in mod repository. Use this option to automatically update all your mods to latest version. WARNING: In some cases, updated versions of mods may not be compatible with your existing saves. You may want to postpone mod update until you finish any of your ongoing games. - +AI-generated, needs review by native speaker; delete this comment afterwards + Một phiên bản mới của một số mod mà bạn đã cài đặt hiện có sẵn trong kho lưu trữ mod. Sử dụng tùy chọn này để tự động cập nhật tất cả các mod của bạn lên phiên bản mới nhất. + +CẢNH BÁO: Trong một số trường hợp, các phiên bản cập nhật của mod có thể không tương thích với các bản lưu hiện có của bạn. Bạn có thể muốn hoãn cập nhật mod cho đến khi hoàn thành trò chơi hiện tại của mình. If you own Heroes Chronicles on gog.com, you can use offline backup installers provided by gog to import Heroes Chronicles data into VCMI as custom campaigns. To import Heroes Chronicles, download offline backup installer of each chronicle that you wish to install, select 'Import files' option and select downloaded file. This will generate and install mod for VCMI that contains imported chronicles - +AI-generated, needs review by native speaker; delete this comment afterwards + Nếu bạn sở hữu Heroes Chronicles trên GOG.com, bạn có thể sử dụng trình cài đặt sao lưu ngoại tuyến do GOG cung cấp để nhập dữ liệu Heroes Chronicles vào VCMI dưới dạng chiến dịch tùy chỉnh. +Để nhập Heroes Chronicles, hãy tải xuống trình cài đặt sao lưu ngoại tuyến của từng phần Chronicles mà bạn muốn cài đặt, chọn tùy chọn 'Nhập tệp' và chọn tệp đã tải xuống. Điều này sẽ tạo và cài đặt mod cho VCMI chứa các Chronicles đã nhập. VCMI has detected that Heroes III music files are missing from your installation. VCMI will run, but in-game music will not be available. To resolve this problem, please copy missing mp3 files from Heroes III to VCMI data files directory manually or reinstall VCMI and re-import Heroes III data files - +AI-generated, needs review by native speaker; delete this comment afterwards + VCMI đã phát hiện rằng các tệp nhạc Heroes III bị thiếu trong cài đặt của bạn. VCMI sẽ chạy, nhưng nhạc trong trò chơi sẽ không khả dụng. + +Để giải quyết vấn đề này, vui lòng sao chép các tệp mp3 bị thiếu từ Heroes III vào thư mục dữ liệu VCMI theo cách thủ công hoặc cài đặt lại VCMI và nhập lại các tệp dữ liệu Heroes III. VCMI has detected that Heroes III video files are missing from your installation. VCMI will run, but in-game cutscenes will not be available. To resolve this problem, please copy VIDEO.VID file from Heroes III to VCMI data files directory manually or reinstall VCMI and re-import Heroes III data files - +AI-generated, needs review by native speaker; delete this comment afterwards + VCMI đã phát hiện rằng các tệp video Heroes III bị thiếu trong cài đặt của bạn. VCMI sẽ chạy, nhưng các cảnh cắt trong trò chơi sẽ không khả dụng. + +Để giải quyết vấn đề này, vui lòng sao chép tệp VIDEO.VID từ Heroes III vào thư mục dữ liệu VCMI theo cách thủ công hoặc cài đặt lại VCMI và nhập lại các tệp dữ liệu Heroes III. VCMI has detected that some of Heroes III data files are missing from your installation. You may attempt to run VCMI, but game may not work as expected or crash. To resolve this problem, please reinstall game and reimport data files using supported version of Heroes III. VCMI requires Heroes III: Shadow of Death or Complete Edition to run, which you can get (for example) from gog.com - +AI-generated, needs review by native speaker; delete this comment afterwards + VCMI đã phát hiện rằng một số tệp dữ liệu của Heroes III bị thiếu trong cài đặt của bạn. Bạn có thể cố gắng chạy VCMI, nhưng trò chơi có thể không hoạt động như mong đợi hoặc bị lỗi. + +Để giải quyết vấn đề này, vui lòng cài đặt lại trò chơi và nhập lại các tệp dữ liệu bằng phiên bản Heroes III được hỗ trợ. VCMI yêu cầu Heroes III: Shadow of Death hoặc Complete Edition để chạy, mà bạn có thể mua (ví dụ) từ GOG.com. VCMI has detected that some of Heroes III: Armageddon's Blade data files are missing from your installation. VCMI will work, but Armageddon's Blade campaigns will not be available. To resolve this problem, please copy missing data files from Heroes III to VCMI data files directory manually or reinstall VCMI and re-import Heroes III data files - +AI-generated, needs review by native speaker; delete this comment afterwards + VCMI đã phát hiện rằng một số tệp dữ liệu của Heroes III: Armageddon's Blade bị thiếu trong cài đặt của bạn. VCMI sẽ hoạt động, nhưng các chiến dịch của Armageddon's Blade sẽ không khả dụng. + +Để giải quyết vấn đề này, vui lòng sao chép các tệp dữ liệu bị thiếu từ Heroes III vào thư mục dữ liệu VCMI theo cách thủ công hoặc cài đặt lại VCMI và nhập lại các tệp dữ liệu Heroes III. Enter preset name: - + AI-generated, needs review by native speaker; delete this comment afterwards + Nhập tên thiết lập: Rename preset '%1' to: - + AI-generated, needs review by native speaker; delete this comment afterwards + Đổi tên thiết lập '%1' thành: From 7f175be0edbb74ea266c6a50e38ca97c539ee306 Mon Sep 17 00:00:00 2001 From: MichalZr6 Date: Wed, 19 Feb 2025 20:10:55 +0100 Subject: [PATCH 06/31] Portuguese translation update with note about AI generation --- launcher/translation/portuguese.ts | 32 +++++++++++++++++++++--------- 1 file changed, 23 insertions(+), 9 deletions(-) diff --git a/launcher/translation/portuguese.ts b/launcher/translation/portuguese.ts index 8c8662487..9c09d8261 100644 --- a/launcher/translation/portuguese.ts +++ b/launcher/translation/portuguese.ts @@ -307,17 +307,20 @@ Context menu - + AI-generated, needs review by native speaker; delete this comment afterwards + Menu de contexto Open directory - + AI-generated, needs review by native speaker; delete this comment afterwards + Abrir diretório Open repository - + AI-generated, needs review by native speaker; delete this comment afterwards + Abrir repositório @@ -497,7 +500,8 @@ O download da instalação foi bem-sucedido? Allow portrait mode - + AI-generated, needs review by native speaker; delete this comment afterwards + Permitir modo retrato @@ -512,7 +516,8 @@ O download da instalação foi bem-sucedido? Handle back as right mouse button - + AI-generated, needs review by native speaker; delete this comment afterwards + Tratar botão voltar como botão direito do mouse @@ -848,7 +853,8 @@ Modo de tela cheia exclusivo - o jogo cobrirá toda a sua tela e usará a resolu Heroes Chronicles %1 - %2 - + AI-generated, needs review by native speaker; delete this comment afterwards + Heroes Chronicles %1 - %2 @@ -1188,11 +1194,14 @@ Motivo do erro: Exe (%n bytes): %1 param is hash + AI-generated, needs review by native speaker; delete this comment afterwards Hash SHA1 dos arquivos fornecidos: Exe (%n bytes): %1 - + Hash SHA1 dos arquivos fornecidos: +Exe (%n bytes): +%1 @@ -1201,11 +1210,14 @@ Exe (%n bytes): Bin (%n bytes): %1 param is hash + AI-generated, needs review by native speaker; delete this comment afterwards Bin (%n bytes): %1 - + +Bin (%n bytes): +%1 @@ -1382,6 +1394,7 @@ Bin (%n bytes): Error starting executable + AI-generated, needs review by native speaker; delete this comment afterwards Erro ao iniciar o executável @@ -1479,7 +1492,8 @@ Bin (%n bytes): Mod data was not found - + AI-generated, needs review by native speaker; delete this comment afterwards + Os dados do mod não foram encontrados From 4bf7bb1daa12b8eb064f7091dfb82e3e611e019a Mon Sep 17 00:00:00 2001 From: MichalZr6 Date: Wed, 19 Feb 2025 20:13:45 +0100 Subject: [PATCH 07/31] French translation update with note about AI generation --- launcher/translation/french.ts | 395 ++++++++++++++++++++++++--------- 1 file changed, 288 insertions(+), 107 deletions(-) diff --git a/launcher/translation/french.ts b/launcher/translation/french.ts index 8f62ca06d..6e8ab3b87 100644 --- a/launcher/translation/french.ts +++ b/launcher/translation/french.ts @@ -282,17 +282,20 @@ This mod cannot be enabled because it translates into a different language. - + AI-generated, needs review by native speaker; delete this comment afterwards + Ce mod ne peut pas être activé car il traduit dans une langue différente. This mod can not be enabled because the following dependencies are not present - + AI-generated, needs review by native speaker; delete this comment afterwards + Ce mod ne peut pas être activé car les dépendances suivantes sont manquantes This mod can not be installed because the following dependencies are not present - + AI-generated, needs review by native speaker; delete this comment afterwards + Ce mod ne peut pas être installé car les dépendances suivantes sont manquantes @@ -308,17 +311,20 @@ Context menu - + AI-generated, needs review by native speaker; delete this comment afterwards + Menu contextuel Open directory - + AI-generated, needs review by native speaker; delete this comment afterwards + Ouvrir le répertoire Open repository - + AI-generated, needs review by native speaker; delete this comment afterwards + Ouvrir le dépôt @@ -355,7 +361,8 @@ Installer les téchargements réussis? Installing Heroes Chronicles - + AI-generated, needs review by native speaker; delete this comment afterwards + Installation de Heroes Chronicles @@ -463,7 +470,8 @@ Installer les téchargements réussis? Mods Validation - + AI-generated, needs review by native speaker; delete this comment afterwards + Validation des mods @@ -488,17 +496,20 @@ Installer les téchargements réussis? Full - + AI-generated, needs review by native speaker; delete this comment afterwards + Complet Allow portrait mode - + AI-generated, needs review by native speaker; delete this comment afterwards + Autoriser le mode portrait Use scalable fonts - + AI-generated, needs review by native speaker; delete this comment afterwards + Utiliser des polices évolutives @@ -508,22 +519,26 @@ Installer les téchargements réussis? Handle back as right mouse button - + AI-generated, needs review by native speaker; delete this comment afterwards + Gérer le retour comme le bouton droit de la souris Cursor Scaling - + AI-generated, needs review by native speaker; delete this comment afterwards + Mise à l'échelle du curseur Scalable - + AI-generated, needs review by native speaker; delete this comment afterwards + Évolutif Miscellaneous - + AI-generated, needs review by native speaker; delete this comment afterwards + Divers @@ -534,17 +549,26 @@ Windowed - the game will run inside a window that covers part of your screen. Borderless Windowed Mode - the game will run in a full-screen window, matching your screen's resolution. Fullscreen Exclusive Mode - the game will cover the entirety of your screen and will use selected resolution. - +AI-generated, needs review by native speaker; delete this comment afterwards + Sélectionnez un mode d'affichage pour le jeu + +Fenêtré - le jeu s'exécutera dans une fenêtre couvrant une partie de votre écran. + +Mode Fenêtré Sans Bordures - le jeu s'exécutera en plein écran dans une fenêtre correspondant à la résolution de votre écran. + +Mode Plein Écran Exclusif - le jeu couvrira entièrement votre écran et utilisera la résolution sélectionnée. Font Scaling (experimental) - + AI-generated, needs review by native speaker; delete this comment afterwards + Mise à l'échelle des polices (expérimental) Original - + AI-generated, needs review by native speaker; delete this comment afterwards + Original @@ -554,7 +578,8 @@ Fullscreen Exclusive Mode - the game will cover the entirety of your screen and Basic - + AI-generated, needs review by native speaker; delete this comment afterwards + Basique @@ -817,33 +842,39 @@ Fullscreen Exclusive Mode - the game will cover the entirety of your screen and Invalid file selected - Fichier sélectionné non valide + AI-generated, needs review by native speaker; delete this comment afterwards + Fichier sélectionné invalide You have to select a Heroes Chronicles installer file! - + AI-generated, needs review by native speaker; delete this comment afterwards + Vous devez sélectionner un fichier d'installation de Heroes Chronicles ! Extracting error! - Erreur d'extraction ! + AI-generated, needs review by native speaker; delete this comment afterwards + Erreur d'extraction ! Hash error! - + AI-generated, needs review by native speaker; delete this comment afterwards + Erreur de hachage ! Heroes Chronicles - + AI-generated, needs review by native speaker; delete this comment afterwards + Heroes Chronicles Heroes Chronicles %1 - %2 - + AI-generated, needs review by native speaker; delete this comment afterwards + Heroes Chronicles %1 - %2 @@ -891,7 +922,14 @@ Before you can start playing, there are a few more steps to complete. Please remember that to use VCMI, you must own the original data files for Heroes® of Might and Magic® III: Complete or The Shadow of Death. Heroes® of Might and Magic® III HD is currently not supported! - +AI-generated, needs review by native speaker; delete this comment afterwards + Merci d'avoir installé VCMI ! + +Avant de pouvoir commencer à jouer, il y a encore quelques étapes à compléter. + +Veuillez noter que pour utiliser VCMI, vous devez posséder les fichiers de données originaux de Heroes® of Might and Magic® III: Complete ou The Shadow of Death. + +Heroes® of Might and Magic® III HD n'est actuellement pas pris en charge ! @@ -977,13 +1015,16 @@ Heroes® of Might and Magic® III HD is currently not supported! You can manually copy directories Maps, Data, and Mp3 from the original game directory to the VCMI data directory that you can see on top of this page - + AI-generated, needs review by native speaker; delete this comment afterwards + Vous pouvez copier manuellement les répertoires Maps, Data et Mp3 du jeu original vers le répertoire de données VCMI visible en haut de cette page. If you own Heroes III on gog.com, you can download a backup offline installer from gog.com. VCMI will then import Heroes III data using the offline installer. Offline installer consists of two files: ".exe" and ".bin" - you must download both. - +AI-generated, needs review by native speaker; delete this comment afterwards + Si vous possédez Heroes III sur gog.com, vous pouvez télécharger un installateur hors ligne de sauvegarde depuis gog.com. VCMI importera alors les données de Heroes III en utilisant l'installateur hors ligne. +L'installateur hors ligne est composé de deux fichiers : ".exe" et ".bin" - vous devez télécharger les deux. @@ -1014,7 +1055,8 @@ Offline installer consists of two files: ".exe" and ".bin" - Install mod that provides various interface improvements, such as a better interface for random maps and selectable actions in battles - + AI-generated, needs review by native speaker; delete this comment afterwards + Installez un mod qui améliore l'interface, comme une meilleure interface pour les cartes aléatoires et des actions sélectionnables en bataille. @@ -1087,13 +1129,17 @@ Offline installer consists of two files: ".exe" and ".bin" - Heroes III: HD Edition files are not supported by VCMI. Please select the directory with Heroes III: Complete Edition or Heroes III: Shadow of Death. - +AI-generated, needs review by native speaker; delete this comment afterwards + Les fichiers de Heroes III: HD Edition ne sont pas pris en charge par VCMI. +Veuillez sélectionner le répertoire contenant Heroes III: Complete Edition ou Heroes III: Shadow of Death. Unknown or unsupported Heroes III version found. Please select the directory with Heroes III: Complete Edition or Heroes III: Shadow of Death. - +AI-generated, needs review by native speaker; delete this comment afterwards + Version inconnue ou non prise en charge de Heroes III détectée. +Veuillez sélectionner le répertoire contenant Heroes III: Complete Edition ou Heroes III: Shadow of Death. @@ -1103,12 +1149,14 @@ Please select the directory with Heroes III: Complete Edition or Heroes III: Sha You've provided a GOG Galaxy installer! This file doesn't contain the game. Please download the offline backup game installer! - + AI-generated, needs review by native speaker; delete this comment afterwards + Vous avez fourni un installateur GOG Galaxy ! Ce fichier ne contient pas le jeu. Veuillez télécharger l'installateur de sauvegarde hors ligne ! Hash error! - + AI-generated, needs review by native speaker; delete this comment afterwards + Erreur de hachage ! @@ -1124,7 +1172,9 @@ Please select the directory with Heroes III: Complete Edition or Heroes III: Sha Failed to detect valid Heroes III data in chosen directory. Please select the directory with installed Heroes III data. - +AI-generated, needs review by native speaker; delete this comment afterwards + Impossible de détecter des données valides de Heroes III dans le répertoire choisi. +Veuillez sélectionner le répertoire contenant les données installées de Heroes III. @@ -1160,12 +1210,14 @@ Raison de l'erreur : Not a supported Inno Setup installer! - Programme d’installation Inno Setup non pris en charge ! + AI-generated, needs review by native speaker; delete this comment afterwards + Ce n'est pas un installateur Inno Setup pris en charge ! VCMI was compiled without innoextract support, which is needed to extract exe files! - + AI-generated, needs review by native speaker; delete this comment afterwards + VCMI a été compilé sans prise en charge de innoextract, ce qui est nécessaire pour extraire les fichiers exe ! @@ -1173,9 +1225,14 @@ Raison de l'erreur : Exe (%n bytes): %1 param is hash + AI-generated, needs review by native speaker; delete this comment afterwards - - + Hachage SHA1 des fichiers fournis: +Exe (%n octets): +%1 + Hachage SHA1 des fichiers fournis: +Exe (%n octets): +%1 @@ -1184,9 +1241,14 @@ Exe (%n bytes): Bin (%n bytes): %1 param is hash + AI-generated, needs review by native speaker; delete this comment afterwards - - + +Bin (%n octets): +%1 + +Bin (%n octets): +%1 @@ -1194,17 +1256,22 @@ Bin (%n bytes): Internal copy process failed. Enough space on device? %1 - +AI-generated, needs review by native speaker; delete this comment afterwards + Échec du processus de copie interne. Espace suffisant sur l'appareil ? + +%1 Exe - + AI-generated, needs review by native speaker; delete this comment afterwards + Exe Bin - + AI-generated, needs review by native speaker; delete this comment afterwards + Bin @@ -1212,7 +1279,11 @@ Bin (%n bytes): %1 %2 - +AI-generated, needs review by native speaker; delete this comment afterwards + Incohérence de langue ! +%1 + +%2 @@ -1220,14 +1291,21 @@ Bin (%n bytes): %1 %2 - +AI-generated, needs review by native speaker; delete this comment afterwards + Un seul fichier connu ! Peut-être que les fichiers sont corrompus ? Veuillez télécharger à nouveau. +%1 + +%2 Unknown files! Maybe files are corrupted? Please download again. %1 - +AI-generated, needs review by native speaker; delete this comment afterwards + Fichiers inconnus ! Peut-être que les fichiers sont corrompus ? Veuillez télécharger à nouveau. + +%1 @@ -1348,22 +1426,26 @@ Bin (%n bytes): Game - + AI-generated, needs review by native speaker; delete this comment afterwards + Jeu Error starting executable - Erreur lors du démarrage de l'exécutable + AI-generated, needs review by native speaker; delete this comment afterwards + Erreur au démarrage de l'exécutable Replace config file? + AI-generated, needs review by native speaker; delete this comment afterwards Remplacer le fichier de configuration ? Do you want to replace %1? - Voulez vous remplacer %1 ? + AI-generated, needs review by native speaker; delete this comment afterwards + Voulez-vous remplacer %1 ? @@ -1384,79 +1466,94 @@ Bin (%n bytes): Can not install submod - Impossible d'installer le sous-mod + AI-generated, needs review by native speaker; delete this comment afterwards + Impossible d'installer le sous-mod Mod is already installed + AI-generated, needs review by native speaker; delete this comment afterwards Le mod est déjà installé Can not uninstall submod - Impossible de désinstaller le sousmod + AI-generated, needs review by native speaker; delete this comment afterwards + Impossible de désinstaller le sous-mod Mod is not installed - Le mod n'est pas installé + AI-generated, needs review by native speaker; delete this comment afterwards + Le mod n'est pas installé Mod is already enabled - Mod déjà activé + AI-generated, needs review by native speaker; delete this comment afterwards + Le mod est déjà activé Mod must be installed first - Le mode doit d'abord être installé + AI-generated, needs review by native speaker; delete this comment afterwards + Le mod doit d'abord être installé Mod is not compatible, please update VCMI and check the latest mod revisions - + AI-generated, needs review by native speaker; delete this comment afterwards + Le mod n'est pas compatible, veuillez mettre à jour VCMI et vérifier les dernières révisions du mod Can not enable translation mod for a different language! - + AI-generated, needs review by native speaker; delete this comment afterwards + Impossible d'activer le mod de traduction pour une langue différente ! Required mod %1 is missing + AI-generated, needs review by native speaker; delete this comment afterwards Le mod requis %1 est manquant Mod is already disabled - Mod déjà désactivé + AI-generated, needs review by native speaker; delete this comment afterwards + Le mod est déjà désactivé Mod archive is missing - Archive du mod manquante + AI-generated, needs review by native speaker; delete this comment afterwards + L'archive du mod est manquante Mod archive is invalid or corrupted - L'archive du mod est invalide ou corrompue + AI-generated, needs review by native speaker; delete this comment afterwards + L'archive du mod est invalide ou corrompue Failed to extract mod data - Echec de l'extraction des données du mod + AI-generated, needs review by native speaker; delete this comment afterwards + Échec de l'extraction des données du mod Mod data was not found - + AI-generated, needs review by native speaker; delete this comment afterwards + Les données du mod n'ont pas été trouvées Mod is located in a protected directory, please remove it manually: - +AI-generated, needs review by native speaker; delete this comment afterwards + Le mod est situé dans un répertoire protégé, veuillez le supprimer manuellement : @@ -1464,102 +1561,122 @@ Bin (%n bytes): Translation + AI-generated, needs review by native speaker; delete this comment afterwards Traduction Town + AI-generated, needs review by native speaker; delete this comment afterwards Ville Test + AI-generated, needs review by native speaker; delete this comment afterwards Test Templates + AI-generated, needs review by native speaker; delete this comment afterwards Modèles Spells + AI-generated, needs review by native speaker; delete this comment afterwards Sorts Music + AI-generated, needs review by native speaker; delete this comment afterwards Musique Maps + AI-generated, needs review by native speaker; delete this comment afterwards Cartes Sounds + AI-generated, needs review by native speaker; delete this comment afterwards Sons Skills + AI-generated, needs review by native speaker; delete this comment afterwards Compétences Other + AI-generated, needs review by native speaker; delete this comment afterwards Autre Objects + AI-generated, needs review by native speaker; delete this comment afterwards Objets Mechanics - Mécaniques + AI-generated, needs review by native speaker; delete this comment afterwards + Mécanique Interface + AI-generated, needs review by native speaker; delete this comment afterwards Interface Heroes + AI-generated, needs review by native speaker; delete this comment afterwards Héros Graphical + AI-generated, needs review by native speaker; delete this comment afterwards Graphisme Expansion + AI-generated, needs review by native speaker; delete this comment afterwards Extension Creatures + AI-generated, needs review by native speaker; delete this comment afterwards Créatures Compatibility + AI-generated, needs review by native speaker; delete this comment afterwards Compatibilité Artifacts - Artefacts + AI-generated, needs review by native speaker; delete this comment afterwards + Artifacts AI + AI-generated, needs review by native speaker; delete this comment afterwards IA @@ -1583,32 +1700,38 @@ Raison : %2 Import from Clipboard - + AI-generated, needs review by native speaker; delete this comment afterwards + Importer depuis le presse-papiers Rename Current Preset - + AI-generated, needs review by native speaker; delete this comment afterwards + Renommer le préréglage actuel Create New Preset - + AI-generated, needs review by native speaker; delete this comment afterwards + Créer un nouveau préréglage Export to Clipboard - + AI-generated, needs review by native speaker; delete this comment afterwards + Exporter vers le presse-papiers Delete Current Preset - + AI-generated, needs review by native speaker; delete this comment afterwards + Supprimer le préréglage actuel Unsupported or corrupted game data detected! - + AI-generated, needs review by native speaker; delete this comment afterwards + Données du jeu non prises en charge ou corrompues détectées ! @@ -1621,144 +1744,173 @@ Raison : %2 ? - + AI-generated, needs review by native speaker; delete this comment afterwards + ? Install Translation - + AI-generated, needs review by native speaker; delete this comment afterwards + Installer la traduction No soundtrack detected! - + AI-generated, needs review by native speaker; delete this comment afterwards + Aucune bande-son détectée ! Armaggedon's Blade campaigns are missing! - + AI-generated, needs review by native speaker; delete this comment afterwards + Les campagnes d'Armageddon's Blade sont manquantes ! No video files detected! - + AI-generated, needs review by native speaker; delete this comment afterwards + Aucun fichier vidéo détecté ! Activate Translation - + AI-generated, needs review by native speaker; delete this comment afterwards + Activer la traduction Import files - + AI-generated, needs review by native speaker; delete this comment afterwards + Importer des fichiers Check For Updates - + AI-generated, needs review by native speaker; delete this comment afterwards + Vérifier les mises à jour Go to Downloads Page - + AI-generated, needs review by native speaker; delete this comment afterwards + Aller à la page des téléchargements Go to Changelog Page - + AI-generated, needs review by native speaker; delete this comment afterwards + Aller à la page du journal des modifications You are using the latest version - + AI-generated, needs review by native speaker; delete this comment afterwards + Vous utilisez la dernière version Game Data Files - + AI-generated, needs review by native speaker; delete this comment afterwards + Fichiers de données du jeu Mod Preset - + AI-generated, needs review by native speaker; delete this comment afterwards + Préréglage du mod Resume - + AI-generated, needs review by native speaker; delete this comment afterwards + Reprendre Play - + AI-generated, needs review by native speaker; delete this comment afterwards + Jouer Editor - + AI-generated, needs review by native speaker; delete this comment afterwards + Éditeur Update %n mods + AI-generated, needs review by native speaker; delete this comment afterwards - - + Mettre à jour %n mods + Mettre à jour %n mods Heroes Chronicles: %n/%1 installed + AI-generated, needs review by native speaker; delete this comment afterwards - - + Heroes Chronicles : +%n/%1 installé + Heroes Chronicles : +%n/%1 installé Update to %1 available - + AI-generated, needs review by native speaker; delete this comment afterwards + Mise à jour vers %1 disponible All supported files - Tous les fichiers supportés + AI-generated, needs review by native speaker; delete this comment afterwards + Tous les fichiers pris en charge Maps + AI-generated, needs review by native speaker; delete this comment afterwards Cartes Campaigns + AI-generated, needs review by native speaker; delete this comment afterwards Campagnes Configs + AI-generated, needs review by native speaker; delete this comment afterwards Configurations Mods + AI-generated, needs review by native speaker; delete this comment afterwards Mods Gog files - + AI-generated, needs review by native speaker; delete this comment afterwards + Fichiers Gog All files (*.*) - + AI-generated, needs review by native speaker; delete this comment afterwards + Tous les fichiers (*.*) Select files (configs, mods, maps, campaigns, gog files) to install... - + AI-generated, needs review by native speaker; delete this comment afterwards + Sélectionnez les fichiers (configurations, mods, cartes, campagnes, fichiers gog) à installer... @@ -1770,68 +1922,96 @@ Raison : %2 - VCMI mods in zip format (.zip) - VCMI configuration files (.json) - +AI-generated, needs review by native speaker; delete this comment afterwards + Cette option vous permet d'importer des fichiers de données supplémentaires dans votre installation VCMI. Actuellement, les options suivantes sont prises en charge : + +- Cartes Heroes III (.h3m ou .vmap). +- Campagnes Heroes III (.h3c ou .vcmp). +- Heroes III Chronicles en utilisant l'installateur de sauvegarde hors ligne de GOG.com (.exe). +- Mods VCMI au format zip (.zip) +- Fichiers de configuration VCMI (.json) Your Heroes III version uses different language. VCMI provides translations of the game into various languages that you can use. Use this option to automatically install such translation to your language. - + AI-generated, needs review by native speaker; delete this comment afterwards + Votre version de Heroes III utilise une langue différente. VCMI propose des traductions du jeu dans diverses langues que vous pouvez utiliser. Utilisez cette option pour installer automatiquement la traduction dans votre langue. Translation of Heroes III into your language is installed, but has been turned off. Use this option to enable it. - + AI-generated, needs review by native speaker; delete this comment afterwards + La traduction de Heroes III dans votre langue est installée, mais elle a été désactivée. Utilisez cette option pour l'activer. A new version of some of the mods that you have installed is now available in mod repository. Use this option to automatically update all your mods to latest version. WARNING: In some cases, updated versions of mods may not be compatible with your existing saves. You may want to postpone mod update until you finish any of your ongoing games. - +AI-generated, needs review by native speaker; delete this comment afterwards + Une nouvelle version de certains des mods que vous avez installés est maintenant disponible dans le référentiel de mods. Utilisez cette option pour mettre automatiquement à jour tous vos mods vers la dernière version. + +ATTENTION : Dans certains cas, les versions mises à jour des mods peuvent ne pas être compatibles avec vos sauvegardes existantes. Vous voudrez peut-être reporter la mise à jour des mods jusqu'à ce que vous ayez terminé vos parties en cours. If you own Heroes Chronicles on gog.com, you can use offline backup installers provided by gog to import Heroes Chronicles data into VCMI as custom campaigns. To import Heroes Chronicles, download offline backup installer of each chronicle that you wish to install, select 'Import files' option and select downloaded file. This will generate and install mod for VCMI that contains imported chronicles - +AI-generated, needs review by native speaker; delete this comment afterwards + Si vous possédez Heroes Chronicles sur gog.com, vous pouvez utiliser les installateurs de sauvegarde hors ligne fournis par gog pour importer les données de Heroes Chronicles dans VCMI en tant que campagnes personnalisées. +Pour importer Heroes Chronicles, téléchargez l'installateur de sauvegarde hors ligne de chaque chronique que vous souhaitez installer, sélectionnez l'option 'Importer des fichiers' et sélectionnez le fichier téléchargé. Cela générera et installera un mod pour VCMI contenant les chroniques importées. VCMI has detected that Heroes III music files are missing from your installation. VCMI will run, but in-game music will not be available. To resolve this problem, please copy missing mp3 files from Heroes III to VCMI data files directory manually or reinstall VCMI and re-import Heroes III data files - +AI-generated, needs review by native speaker; delete this comment afterwards + VCMI a détecté que les fichiers de musique de Heroes III sont manquants dans votre installation. VCMI fonctionnera, mais la musique en jeu ne sera pas disponible. + +Pour résoudre ce problème, veuillez copier manuellement les fichiers mp3 manquants de Heroes III vers le répertoire des fichiers de données VCMI ou réinstallez VCMI et réimportez les fichiers de données de Heroes III. VCMI has detected that Heroes III video files are missing from your installation. VCMI will run, but in-game cutscenes will not be available. To resolve this problem, please copy VIDEO.VID file from Heroes III to VCMI data files directory manually or reinstall VCMI and re-import Heroes III data files - +AI-generated, needs review by native speaker; delete this comment afterwards + VCMI a détecté que les fichiers vidéo de Heroes III sont manquants dans votre installation. VCMI fonctionnera, mais les cinématiques du jeu ne seront pas disponibles. + +Pour résoudre ce problème, veuillez copier manuellement le fichier VIDEO.VID de Heroes III vers le répertoire des fichiers de données VCMI ou réinstallez VCMI et réimportez les fichiers de données de Heroes III. VCMI has detected that some of Heroes III data files are missing from your installation. You may attempt to run VCMI, but game may not work as expected or crash. To resolve this problem, please reinstall game and reimport data files using supported version of Heroes III. VCMI requires Heroes III: Shadow of Death or Complete Edition to run, which you can get (for example) from gog.com - +AI-generated, needs review by native speaker; delete this comment afterwards + VCMI a détecté que certains fichiers de données de Heroes III sont manquants dans votre installation. Vous pouvez tenter d'exécuter VCMI, mais le jeu peut ne pas fonctionner comme prévu ou planter. + +Pour résoudre ce problème, veuillez réinstaller le jeu et réimporter les fichiers de données en utilisant une version prise en charge de Heroes III. VCMI nécessite Heroes III : Shadow of Death ou Complete Edition pour fonctionner, que vous pouvez obtenir (par exemple) sur gog.com. VCMI has detected that some of Heroes III: Armageddon's Blade data files are missing from your installation. VCMI will work, but Armageddon's Blade campaigns will not be available. To resolve this problem, please copy missing data files from Heroes III to VCMI data files directory manually or reinstall VCMI and re-import Heroes III data files - +AI-generated, needs review by native speaker; delete this comment afterwards + VCMI a détecté que certains fichiers de données de Heroes III: Armageddon's Blade sont manquants dans votre installation. VCMI fonctionnera, mais les campagnes d'Armageddon's Blade ne seront pas disponibles. + +Pour résoudre ce problème, veuillez copier manuellement les fichiers de données manquants de Heroes III vers le répertoire des fichiers de données VCMI ou réinstallez VCMI et réimportez les fichiers de données de Heroes III. Enter preset name: - + AI-generated, needs review by native speaker; delete this comment afterwards + Entrez le nom du préréglage : Rename preset '%1' to: - + AI-generated, needs review by native speaker; delete this comment afterwards + Renommer le préréglage '%1' en : @@ -1859,7 +2039,8 @@ To resolve this problem, please copy missing data files from Heroes III to VCMI Cannot read JSON from URL or incorrect JSON data - + AI-generated, needs review by native speaker; delete this comment afterwards + Impossible de lire le JSON depuis l'URL ou les données JSON sont incorrectes. From 206c4c8f702aa67daecdf4763cbd9c3a3235913b Mon Sep 17 00:00:00 2001 From: MichalZr6 Date: Wed, 19 Feb 2025 20:14:45 +0100 Subject: [PATCH 08/31] Chinese translation update with note about AI generation --- launcher/translation/chinese.ts | 70 ++++++++++++++++++++++----------- 1 file changed, 47 insertions(+), 23 deletions(-) diff --git a/launcher/translation/chinese.ts b/launcher/translation/chinese.ts index 500fc652f..61dc5eb81 100644 --- a/launcher/translation/chinese.ts +++ b/launcher/translation/chinese.ts @@ -310,17 +310,20 @@ Context menu - + AI-generated, needs review by native speaker; delete this comment afterwards + 上下文菜单 Open directory - + AI-generated, needs review by native speaker; delete this comment afterwards + 打开目录 Open repository - + AI-generated, needs review by native speaker; delete this comment afterwards + 打开存储库 @@ -506,7 +509,8 @@ Install successfully downloaded? Allow portrait mode - + AI-generated, needs review by native speaker; delete this comment afterwards + 允许纵向模式 @@ -521,7 +525,8 @@ Install successfully downloaded? Handle back as right mouse button - + AI-generated, needs review by native speaker; delete this comment afterwards + 将返回键作为鼠标右键 @@ -853,7 +858,8 @@ Fullscreen Exclusive Mode - the game will cover the entirety of your screen and Heroes Chronicles %1 - %2 - 英雄无敌历代记 %1 - %2 + AI-generated, needs review by native speaker; delete this comment afterwards + 英雄编年史 %1 - %2 @@ -1268,7 +1274,8 @@ Bin (%n字节): Czech - + AI-generated, needs review by native speaker; delete this comment afterwards + 捷克语 @@ -1278,77 +1285,92 @@ Bin (%n字节): English - + AI-generated, needs review by native speaker; delete this comment afterwards + 英语 Finnish - + AI-generated, needs review by native speaker; delete this comment afterwards + 芬兰语 French - + AI-generated, needs review by native speaker; delete this comment afterwards + 法语 German - + AI-generated, needs review by native speaker; delete this comment afterwards + 德语 Hungarian - + AI-generated, needs review by native speaker; delete this comment afterwards + 匈牙利语 Italian - + AI-generated, needs review by native speaker; delete this comment afterwards + 意大利语 Korean - + AI-generated, needs review by native speaker; delete this comment afterwards + 韩语 Polish - + AI-generated, needs review by native speaker; delete this comment afterwards + 波兰语 Portuguese - + AI-generated, needs review by native speaker; delete this comment afterwards + 葡萄牙语 Russian - + AI-generated, needs review by native speaker; delete this comment afterwards + 俄语 Spanish - + AI-generated, needs review by native speaker; delete this comment afterwards + 西班牙语 Swedish - + AI-generated, needs review by native speaker; delete this comment afterwards + 瑞典语 Turkish - + AI-generated, needs review by native speaker; delete this comment afterwards + 土耳其语 Ukrainian - + AI-generated, needs review by native speaker; delete this comment afterwards + 乌克兰语 Vietnamese - + AI-generated, needs review by native speaker; delete this comment afterwards + 越南语 @@ -1386,6 +1408,7 @@ Bin (%n字节): Error starting executable + AI-generated, needs review by native speaker; delete this comment afterwards 启动可执行文件时出错 @@ -1483,7 +1506,8 @@ Bin (%n字节): Mod data was not found - + AI-generated, needs review by native speaker; delete this comment afterwards + 未找到模组数据 From f6eb59de40bea0025bd6cb8f5521407a22948ece Mon Sep 17 00:00:00 2001 From: MichalZr6 Date: Mon, 17 Feb 2025 23:08:17 +0100 Subject: [PATCH 09/31] Russian translation update --- launcher/translation/russian.ts | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/launcher/translation/russian.ts b/launcher/translation/russian.ts index acc10b642..e1988c7df 100644 --- a/launcher/translation/russian.ts +++ b/launcher/translation/russian.ts @@ -307,17 +307,17 @@ Context menu - + Контекстное меню Open directory - + Открыть каталог Open repository - + Открыть репозиторий @@ -532,7 +532,7 @@ Install successfully downloaded? Allow portrait mode - + Разрешить портретный режим @@ -547,7 +547,7 @@ Install successfully downloaded? Handle back as right mouse button - + Обрабатывать кнопку «Назад» как правую кнопку мыши @@ -940,12 +940,12 @@ Fullscreen Exclusive Mode - the game will cover the entirety of your screen and Install compatible version of "Horn of the Abyss", a fan-made Heroes III expansion ported by the VCMI team - Установить совместимую версию Horn of the Abyss: фанатского дополнения к Героям III (портированную командой VCMI) + Установить совместимую версию Рога Бездны: фанатского дополнения к Героям III (портированного командой VCMI) Install compatible version of "In The Wake of Gods", a fan-made Heroes III expansion - Установить совместимую версию In The Wake of Gods: фанатского дополнения к Героям III (портированную командой VCMI) + Установить совместимую версию Во Имя Богов: фанатского дополнения к Героям III (портированного командой VCMI) @@ -1036,7 +1036,7 @@ Offline installer consists of two files: ".exe" and ".bin" - Horn of the Abyss - + Рог Бездны @@ -1046,7 +1046,7 @@ Offline installer consists of two files: ".exe" and ".bin" - In The Wake of Gods - + Во Имя Богов @@ -1188,7 +1188,7 @@ error reason: Exe (%n bytes): %1 param is hash - + SHA1 хэш предоставленных файлов: Exe (%n байт): %1 @@ -1202,7 +1202,7 @@ Exe (%n байт): Bin (%n bytes): %1 param is hash - + Bin (%n байт): %1 @@ -1384,7 +1384,7 @@ Bin (%n байт): Error starting executable - Ошибка запуска исполняемого файла + Ошибка запуска исполняемого файла @@ -1481,7 +1481,7 @@ Bin (%n байт): Mod data was not found - + Данные мода не найдены From c34052e54812fe041737ef46a3dc6d5c9f868bc7 Mon Sep 17 00:00:00 2001 From: MichalZr6 Date: Sun, 23 Feb 2025 16:41:54 +0100 Subject: [PATCH 10/31] French translation reviewed --- launcher/translation/french.ts | 414 ++++++++++++--------------------- 1 file changed, 143 insertions(+), 271 deletions(-) diff --git a/launcher/translation/french.ts b/launcher/translation/french.ts index 6e8ab3b87..a6b644ca1 100644 --- a/launcher/translation/french.ts +++ b/launcher/translation/french.ts @@ -282,20 +282,17 @@ This mod cannot be enabled because it translates into a different language. - AI-generated, needs review by native speaker; delete this comment afterwards - Ce mod ne peut pas être activé car il traduit dans une langue différente. + Ce mod ne peut pas être activé car il traduit dans une langue différente. This mod can not be enabled because the following dependencies are not present - AI-generated, needs review by native speaker; delete this comment afterwards - Ce mod ne peut pas être activé car les dépendances suivantes sont manquantes + Ce mod ne peut pas être activé car les dépendances suivantes sont manquantes This mod can not be installed because the following dependencies are not present - AI-generated, needs review by native speaker; delete this comment afterwards - Ce mod ne peut pas être installé car les dépendances suivantes sont manquantes + Ce mod ne peut pas être installé car les dépendances suivantes sont manquantes @@ -311,20 +308,17 @@ Context menu - AI-generated, needs review by native speaker; delete this comment afterwards - Menu contextuel + Menu contextuel Open directory - AI-generated, needs review by native speaker; delete this comment afterwards - Ouvrir le répertoire + Ouvrir le répertoire Open repository - AI-generated, needs review by native speaker; delete this comment afterwards - Ouvrir le dépôt + Ouvrir le dépôt @@ -361,8 +355,7 @@ Installer les téchargements réussis? Installing Heroes Chronicles - AI-generated, needs review by native speaker; delete this comment afterwards - Installation de Heroes Chronicles + Installation de Heroes Chronicles @@ -470,8 +463,7 @@ Installer les téchargements réussis? Mods Validation - AI-generated, needs review by native speaker; delete this comment afterwards - Validation des mods + Validation des mods @@ -496,20 +488,17 @@ Installer les téchargements réussis? Full - AI-generated, needs review by native speaker; delete this comment afterwards - Complet + Complet Allow portrait mode - AI-generated, needs review by native speaker; delete this comment afterwards - Autoriser le mode portrait + Autoriser le mode portrait Use scalable fonts - AI-generated, needs review by native speaker; delete this comment afterwards - Utiliser des polices évolutives + Utiliser des polices redimensionnables @@ -519,26 +508,22 @@ Installer les téchargements réussis? Handle back as right mouse button - AI-generated, needs review by native speaker; delete this comment afterwards - Gérer le retour comme le bouton droit de la souris + Gérer le retour en atnt que le bouton droit de la souris Cursor Scaling - AI-generated, needs review by native speaker; delete this comment afterwards - Mise à l'échelle du curseur + Mise à l'échelle du curseur Scalable - AI-generated, needs review by native speaker; delete this comment afterwards - Évolutif + Redimensionnable Miscellaneous - AI-generated, needs review by native speaker; delete this comment afterwards - Divers + Divers @@ -549,26 +534,23 @@ Windowed - the game will run inside a window that covers part of your screen. Borderless Windowed Mode - the game will run in a full-screen window, matching your screen's resolution. Fullscreen Exclusive Mode - the game will cover the entirety of your screen and will use selected resolution. -AI-generated, needs review by native speaker; delete this comment afterwards - Sélectionnez un mode d'affichage pour le jeu + Sélectionnez un mode d'affichage pour le jeu -Fenêtré - le jeu s'exécutera dans une fenêtre couvrant une partie de votre écran. +Fenêtré - le jeu s'exécutera dans une fenêtre couvrant une partie de votre écran. -Mode Fenêtré Sans Bordures - le jeu s'exécutera en plein écran dans une fenêtre correspondant à la résolution de votre écran. +Mode Fenêtré Sans Bordures - le jeu s'exécutera en plein écran dans une fenêtre correspondant à la résolution de votre écran. Mode Plein Écran Exclusif - le jeu couvrira entièrement votre écran et utilisera la résolution sélectionnée. Font Scaling (experimental) - AI-generated, needs review by native speaker; delete this comment afterwards - Mise à l'échelle des polices (expérimental) + Mise à l'échelle des polices (expérimental) Original - AI-generated, needs review by native speaker; delete this comment afterwards - Original + Original @@ -578,8 +560,7 @@ Mode Plein Écran Exclusif - le jeu couvrira entièrement votre écran et utilis Basic - AI-generated, needs review by native speaker; delete this comment afterwards - Basique + Basique @@ -842,39 +823,33 @@ Mode Plein Écran Exclusif - le jeu couvrira entièrement votre écran et utilis Invalid file selected - AI-generated, needs review by native speaker; delete this comment afterwards - Fichier sélectionné invalide + Fichier sélectionné invalide You have to select a Heroes Chronicles installer file! - AI-generated, needs review by native speaker; delete this comment afterwards - Vous devez sélectionner un fichier d'installation de Heroes Chronicles ! + Vous devez sélectionner un fichier d'installation de Heroes Chronicles ! Extracting error! - AI-generated, needs review by native speaker; delete this comment afterwards - Erreur d'extraction ! + Erreur d'extraction ! Hash error! - AI-generated, needs review by native speaker; delete this comment afterwards - Erreur de hachage ! + Erreur de hachage ! Heroes Chronicles - AI-generated, needs review by native speaker; delete this comment afterwards - Heroes Chronicles + Heroes Chronicles Heroes Chronicles %1 - %2 - AI-generated, needs review by native speaker; delete this comment afterwards - Heroes Chronicles %1 - %2 + Heroes Chronicles %1 - %2 @@ -922,14 +897,13 @@ Before you can start playing, there are a few more steps to complete. Please remember that to use VCMI, you must own the original data files for Heroes® of Might and Magic® III: Complete or The Shadow of Death. Heroes® of Might and Magic® III HD is currently not supported! -AI-generated, needs review by native speaker; delete this comment afterwards - Merci d'avoir installé VCMI ! + Merci d'avoir installé VCMI ! Avant de pouvoir commencer à jouer, il y a encore quelques étapes à compléter. Veuillez noter que pour utiliser VCMI, vous devez posséder les fichiers de données originaux de Heroes® of Might and Magic® III: Complete ou The Shadow of Death. -Heroes® of Might and Magic® III HD n'est actuellement pas pris en charge ! +Heroes® of Might and Magic® III HD n'est pas actuellement pris en charge ! @@ -1015,16 +989,14 @@ Heroes® of Might and Magic® III HD n'est actuellement pas pris en charge ! You can manually copy directories Maps, Data, and Mp3 from the original game directory to the VCMI data directory that you can see on top of this page - AI-generated, needs review by native speaker; delete this comment afterwards - Vous pouvez copier manuellement les répertoires Maps, Data et Mp3 du jeu original vers le répertoire de données VCMI visible en haut de cette page. + Vous pouvez copier manuellement les répertoires Maps, Data et Mp3 du jeu original vers le répertoire de données VCMI visible en haut de cette page. If you own Heroes III on gog.com, you can download a backup offline installer from gog.com. VCMI will then import Heroes III data using the offline installer. Offline installer consists of two files: ".exe" and ".bin" - you must download both. -AI-generated, needs review by native speaker; delete this comment afterwards - Si vous possédez Heroes III sur gog.com, vous pouvez télécharger un installateur hors ligne de sauvegarde depuis gog.com. VCMI importera alors les données de Heroes III en utilisant l'installateur hors ligne. -L'installateur hors ligne est composé de deux fichiers : ".exe" et ".bin" - vous devez télécharger les deux. + Si vous possédez Heroes III sur gog.com, vous pouvez télécharger un installateur hors ligne de sauvegarde depuis gog.com. VCMI importera alors les données de Heroes III en utilisant l'installateur hors ligne. +L'installateur hors ligne est composé de deux fichiers : ".exe" et ".bin" - vous devez télécharger les deux. @@ -1055,8 +1027,7 @@ L'installateur hors ligne est composé de deux fichiers : ".exe" et &q Install mod that provides various interface improvements, such as a better interface for random maps and selectable actions in battles - AI-generated, needs review by native speaker; delete this comment afterwards - Installez un mod qui améliore l'interface, comme une meilleure interface pour les cartes aléatoires et des actions sélectionnables en bataille. + Installe un mod qui améliore l'interface, comme une meilleure interface pour les cartes aléatoires et des actions sélectionnables en bataille. @@ -1129,16 +1100,14 @@ L'installateur hors ligne est composé de deux fichiers : ".exe" et &q Heroes III: HD Edition files are not supported by VCMI. Please select the directory with Heroes III: Complete Edition or Heroes III: Shadow of Death. -AI-generated, needs review by native speaker; delete this comment afterwards - Les fichiers de Heroes III: HD Edition ne sont pas pris en charge par VCMI. + Les fichiers de Heroes III: HD Edition ne sont pas pris en charge par VCMI. Veuillez sélectionner le répertoire contenant Heroes III: Complete Edition ou Heroes III: Shadow of Death. Unknown or unsupported Heroes III version found. Please select the directory with Heroes III: Complete Edition or Heroes III: Shadow of Death. -AI-generated, needs review by native speaker; delete this comment afterwards - Version inconnue ou non prise en charge de Heroes III détectée. + Version inconnue ou non prise en charge de Heroes III détectée. Veuillez sélectionner le répertoire contenant Heroes III: Complete Edition ou Heroes III: Shadow of Death. @@ -1149,14 +1118,12 @@ Veuillez sélectionner le répertoire contenant Heroes III: Complete Edition ou You've provided a GOG Galaxy installer! This file doesn't contain the game. Please download the offline backup game installer! - AI-generated, needs review by native speaker; delete this comment afterwards - Vous avez fourni un installateur GOG Galaxy ! Ce fichier ne contient pas le jeu. Veuillez télécharger l'installateur de sauvegarde hors ligne ! + Vous avez fourni un installateur GOG Galaxy ! Ce fichier ne contient pas le jeu. Veuillez télécharger l'installateur de sauvegarde hors ligne ! Hash error! - AI-generated, needs review by native speaker; delete this comment afterwards - Erreur de hachage ! + Erreur de hachage ! @@ -1172,8 +1139,7 @@ Veuillez sélectionner le répertoire contenant Heroes III: Complete Edition ou Failed to detect valid Heroes III data in chosen directory. Please select the directory with installed Heroes III data. -AI-generated, needs review by native speaker; delete this comment afterwards - Impossible de détecter des données valides de Heroes III dans le répertoire choisi. + Impossible de détecter des données valides de Heroes III dans le répertoire choisi. Veuillez sélectionner le répertoire contenant les données installées de Heroes III. @@ -1204,20 +1170,18 @@ Veuillez sélectionner le répertoire contenant les données installées de Hero Stream error while extracting files! error reason: - Erreur de flux lors de l'extraction des fichiers ! + Erreur de flux lors de l'extraction des fichiers ! Raison de l'erreur : Not a supported Inno Setup installer! - AI-generated, needs review by native speaker; delete this comment afterwards - Ce n'est pas un installateur Inno Setup pris en charge ! + Ce n'est pas un installateur Inno Setup pris en charge ! VCMI was compiled without innoextract support, which is needed to extract exe files! - AI-generated, needs review by native speaker; delete this comment afterwards - VCMI a été compilé sans prise en charge de innoextract, ce qui est nécessaire pour extraire les fichiers exe ! + VCMI a été compilé sans prise en charge de innoextract, ce qui est nécessaire pour extraire les fichiers exe ! @@ -1225,12 +1189,11 @@ Raison de l'erreur : Exe (%n bytes): %1 param is hash - AI-generated, needs review by native speaker; delete this comment afterwards - - Hachage SHA1 des fichiers fournis: -Exe (%n octets): + + Hachage SHA1 des fichiers fournis : +Exe (%n octet): %1 - Hachage SHA1 des fichiers fournis: + Hachage SHA1 des fichiers fournis : Exe (%n octets): %1 @@ -1241,10 +1204,9 @@ Exe (%n octets): Bin (%n bytes): %1 param is hash - AI-generated, needs review by native speaker; delete this comment afterwards - + -Bin (%n octets): +Bin (%n octet): %1 Bin (%n octets): @@ -1256,22 +1218,19 @@ Bin (%n octets): Internal copy process failed. Enough space on device? %1 -AI-generated, needs review by native speaker; delete this comment afterwards - Échec du processus de copie interne. Espace suffisant sur l'appareil ? + Échec du processus de copie interne. Espace suffisant sur l'appareil ? %1 Exe - AI-generated, needs review by native speaker; delete this comment afterwards - Exe + Exe Bin - AI-generated, needs review by native speaker; delete this comment afterwards - Bin + Bin @@ -1279,8 +1238,7 @@ Bin (%n octets): %1 %2 -AI-generated, needs review by native speaker; delete this comment afterwards - Incohérence de langue ! + Incohérence de langue ! %1 %2 @@ -1291,8 +1249,7 @@ Bin (%n octets): %1 %2 -AI-generated, needs review by native speaker; delete this comment afterwards - Un seul fichier connu ! Peut-être que les fichiers sont corrompus ? Veuillez télécharger à nouveau. + Un seul fichier connu ! Peut-être que les fichiers sont corrompus ? Veuillez télécharger à nouveau. %1 %2 @@ -1302,8 +1259,7 @@ Bin (%n octets): Unknown files! Maybe files are corrupted? Please download again. %1 -AI-generated, needs review by native speaker; delete this comment afterwards - Fichiers inconnus ! Peut-être que les fichiers sont corrompus ? Veuillez télécharger à nouveau. + Fichiers inconnus ! Peut-être que les fichiers sont corrompus ? Veuillez télécharger à nouveau. %1 @@ -1426,26 +1382,22 @@ Bin (%n octets): Game - AI-generated, needs review by native speaker; delete this comment afterwards - Jeu + Jeu Error starting executable - AI-generated, needs review by native speaker; delete this comment afterwards - Erreur au démarrage de l'exécutable + Erreur au démarrage de l'exécutable Replace config file? - AI-generated, needs review by native speaker; delete this comment afterwards - Remplacer le fichier de configuration ? + Remplacer le fichier de configuration ? Do you want to replace %1? - AI-generated, needs review by native speaker; delete this comment afterwards - Voulez-vous remplacer %1 ? + Voulez-vous remplacer %1 ? @@ -1466,94 +1418,79 @@ Bin (%n octets): Can not install submod - AI-generated, needs review by native speaker; delete this comment afterwards - Impossible d'installer le sous-mod + Impossible d'installer le sous-mod Mod is already installed - AI-generated, needs review by native speaker; delete this comment afterwards - Le mod est déjà installé + Le mod est déjà installé Can not uninstall submod - AI-generated, needs review by native speaker; delete this comment afterwards - Impossible de désinstaller le sous-mod + Impossible de désinstaller le sous-mod Mod is not installed - AI-generated, needs review by native speaker; delete this comment afterwards - Le mod n'est pas installé + Le mod n'est pas installé Mod is already enabled - AI-generated, needs review by native speaker; delete this comment afterwards - Le mod est déjà activé + Le mod est déjà activé Mod must be installed first - AI-generated, needs review by native speaker; delete this comment afterwards - Le mod doit d'abord être installé + Le mod doit d'abord être installé Mod is not compatible, please update VCMI and check the latest mod revisions - AI-generated, needs review by native speaker; delete this comment afterwards - Le mod n'est pas compatible, veuillez mettre à jour VCMI et vérifier les dernières révisions du mod + Le mod n'est pas compatible, veuillez mettre à jour VCMI et vérifier les dernières révisions du mod Can not enable translation mod for a different language! - AI-generated, needs review by native speaker; delete this comment afterwards - Impossible d'activer le mod de traduction pour une langue différente ! + Impossible d'activer le mod de traduction pour une langue différente ! Required mod %1 is missing - AI-generated, needs review by native speaker; delete this comment afterwards - Le mod requis %1 est manquant + Le mod requis %1 est manquant Mod is already disabled - AI-generated, needs review by native speaker; delete this comment afterwards - Le mod est déjà désactivé + Le mod est déjà désactivé Mod archive is missing - AI-generated, needs review by native speaker; delete this comment afterwards - L'archive du mod est manquante + L'archive du mod est manquante Mod archive is invalid or corrupted - AI-generated, needs review by native speaker; delete this comment afterwards - L'archive du mod est invalide ou corrompue + L'archive du mod est invalide ou corrompue Failed to extract mod data - AI-generated, needs review by native speaker; delete this comment afterwards - Échec de l'extraction des données du mod + Échec de l'extraction des données du mod Mod data was not found - AI-generated, needs review by native speaker; delete this comment afterwards - Les données du mod n'ont pas été trouvées + Les données du mod n'ont pas été trouvées Mod is located in a protected directory, please remove it manually: -AI-generated, needs review by native speaker; delete this comment afterwards - Le mod est situé dans un répertoire protégé, veuillez le supprimer manuellement : + Le mod est situé dans un répertoire protégé, veuillez le supprimer manuellement : @@ -1561,123 +1498,103 @@ Bin (%n octets): Translation - AI-generated, needs review by native speaker; delete this comment afterwards - Traduction + Traduction Town - AI-generated, needs review by native speaker; delete this comment afterwards - Ville + Ville Test - AI-generated, needs review by native speaker; delete this comment afterwards - Test + Test Templates - AI-generated, needs review by native speaker; delete this comment afterwards - Modèles + Modèles Spells - AI-generated, needs review by native speaker; delete this comment afterwards - Sorts + Sorts Music - AI-generated, needs review by native speaker; delete this comment afterwards - Musique + Musique Maps - AI-generated, needs review by native speaker; delete this comment afterwards - Cartes + Cartes Sounds - AI-generated, needs review by native speaker; delete this comment afterwards - Sons + Sons Skills - AI-generated, needs review by native speaker; delete this comment afterwards - Compétences + Compétences Other - AI-generated, needs review by native speaker; delete this comment afterwards - Autre + Autre Objects - AI-generated, needs review by native speaker; delete this comment afterwards - Objets + Objets Mechanics - AI-generated, needs review by native speaker; delete this comment afterwards - Mécanique + Mécanique Interface - AI-generated, needs review by native speaker; delete this comment afterwards - Interface + Interface Heroes - AI-generated, needs review by native speaker; delete this comment afterwards - Héros + Héros Graphical - AI-generated, needs review by native speaker; delete this comment afterwards - Graphisme + Graphisme Expansion - AI-generated, needs review by native speaker; delete this comment afterwards - Extension + Extension Creatures - AI-generated, needs review by native speaker; delete this comment afterwards - Créatures + Créatures Compatibility - AI-generated, needs review by native speaker; delete this comment afterwards - Compatibilité + Compatibilité Artifacts - AI-generated, needs review by native speaker; delete this comment afterwards - Artifacts + Artéfacts AI - AI-generated, needs review by native speaker; delete this comment afterwards - IA + IA @@ -1700,38 +1617,32 @@ Raison : %2 Import from Clipboard - AI-generated, needs review by native speaker; delete this comment afterwards - Importer depuis le presse-papiers + Importer depuis le Presse-papiers Rename Current Preset - AI-generated, needs review by native speaker; delete this comment afterwards - Renommer le préréglage actuel + Renommer le Préréglage Actuel Create New Preset - AI-generated, needs review by native speaker; delete this comment afterwards - Créer un nouveau préréglage + Créer un Nouveau Préréglage Export to Clipboard - AI-generated, needs review by native speaker; delete this comment afterwards - Exporter vers le presse-papiers + Exporter vers le Presse-papiers Delete Current Preset - AI-generated, needs review by native speaker; delete this comment afterwards - Supprimer le préréglage actuel + Supprimer le Préréglage Actuel Unsupported or corrupted game data detected! - AI-generated, needs review by native speaker; delete this comment afterwards - Données du jeu non prises en charge ou corrompues détectées ! + Données du jeu non prises en charge ou corrompues détectées ! @@ -1744,105 +1655,88 @@ Raison : %2 ? - AI-generated, needs review by native speaker; delete this comment afterwards - ? + ? Install Translation - AI-generated, needs review by native speaker; delete this comment afterwards - Installer la traduction + Installer la Traduction No soundtrack detected! - AI-generated, needs review by native speaker; delete this comment afterwards - Aucune bande-son détectée ! + Aucune bande-son détectée ! Armaggedon's Blade campaigns are missing! - AI-generated, needs review by native speaker; delete this comment afterwards - Les campagnes d'Armageddon's Blade sont manquantes ! + Les campagnes d'Armageddon's Blade sont manquantes ! No video files detected! - AI-generated, needs review by native speaker; delete this comment afterwards - Aucun fichier vidéo détecté ! + Aucun fichier vidéo détecté ! Activate Translation - AI-generated, needs review by native speaker; delete this comment afterwards - Activer la traduction + Activer la Traduction Import files - AI-generated, needs review by native speaker; delete this comment afterwards - Importer des fichiers + Importer des fichiers Check For Updates - AI-generated, needs review by native speaker; delete this comment afterwards - Vérifier les mises à jour + Vérifier les mises à jour Go to Downloads Page - AI-generated, needs review by native speaker; delete this comment afterwards - Aller à la page des téléchargements + Aller à la Page des Téléchargements Go to Changelog Page - AI-generated, needs review by native speaker; delete this comment afterwards - Aller à la page du journal des modifications + Aller à la Page du Journal des Modifications You are using the latest version - AI-generated, needs review by native speaker; delete this comment afterwards - Vous utilisez la dernière version + Vous utilisez la dernière version Game Data Files - AI-generated, needs review by native speaker; delete this comment afterwards - Fichiers de données du jeu + Fichiers de Données du Jeu Mod Preset - AI-generated, needs review by native speaker; delete this comment afterwards - Préréglage du mod + Préréglage du Mod Resume - AI-generated, needs review by native speaker; delete this comment afterwards - Reprendre + Reprendre Play - AI-generated, needs review by native speaker; delete this comment afterwards - Jouer + Jouer Editor - AI-generated, needs review by native speaker; delete this comment afterwards - Éditeur + Éditeur Update %n mods - AI-generated, needs review by native speaker; delete this comment afterwards - - Mettre à jour %n mods + + Mettre à jour %n mod Mettre à jour %n mods @@ -1850,67 +1744,57 @@ Raison : %2 Heroes Chronicles: %n/%1 installed - AI-generated, needs review by native speaker; delete this comment afterwards - + Heroes Chronicles : %n/%1 installé Heroes Chronicles : -%n/%1 installé +%n/%1 installés Update to %1 available - AI-generated, needs review by native speaker; delete this comment afterwards - Mise à jour vers %1 disponible + Mise à jour vers %1 disponible All supported files - AI-generated, needs review by native speaker; delete this comment afterwards - Tous les fichiers pris en charge + Tous les fichiers pris en charge Maps - AI-generated, needs review by native speaker; delete this comment afterwards - Cartes + Cartes Campaigns - AI-generated, needs review by native speaker; delete this comment afterwards - Campagnes + Campagnes Configs - AI-generated, needs review by native speaker; delete this comment afterwards - Configurations + Configurations Mods - AI-generated, needs review by native speaker; delete this comment afterwards - Mods + Mods Gog files - AI-generated, needs review by native speaker; delete this comment afterwards - Fichiers Gog + Fichiers Gog All files (*.*) - AI-generated, needs review by native speaker; delete this comment afterwards - Tous les fichiers (*.*) + Tous les fichiers (*.*) Select files (configs, mods, maps, campaigns, gog files) to install... - AI-generated, needs review by native speaker; delete this comment afterwards - Sélectionnez les fichiers (configurations, mods, cartes, campagnes, fichiers gog) à installer... + Sélectionnez les fichiers (configurations, mods, cartes, campagnes, fichiers gog) à installer... @@ -1922,52 +1806,46 @@ Raison : %2 - VCMI mods in zip format (.zip) - VCMI configuration files (.json) -AI-generated, needs review by native speaker; delete this comment afterwards - Cette option vous permet d'importer des fichiers de données supplémentaires dans votre installation VCMI. Actuellement, les options suivantes sont prises en charge : + Cette option vous permet d'importer des fichiers de données supplémentaires dans votre installation VCMI. Actuellement, les options suivantes sont prises en charge : - Cartes Heroes III (.h3m ou .vmap). - Campagnes Heroes III (.h3c ou .vcmp). -- Heroes III Chronicles en utilisant l'installateur de sauvegarde hors ligne de GOG.com (.exe). +- Heroes III Chronicles en utilisant l'installateur de sauvegarde hors ligne de GOG.com (.exe). - Mods VCMI au format zip (.zip) - Fichiers de configuration VCMI (.json) Your Heroes III version uses different language. VCMI provides translations of the game into various languages that you can use. Use this option to automatically install such translation to your language. - AI-generated, needs review by native speaker; delete this comment afterwards - Votre version de Heroes III utilise une langue différente. VCMI propose des traductions du jeu dans diverses langues que vous pouvez utiliser. Utilisez cette option pour installer automatiquement la traduction dans votre langue. + Votre version de Heroes III utilise une langue différente. VCMI propose des traductions du jeu dans diverses langues que vous pouvez utiliser. Utilisez cette option pour installer automatiquement la traduction dans votre langue. Translation of Heroes III into your language is installed, but has been turned off. Use this option to enable it. - AI-generated, needs review by native speaker; delete this comment afterwards - La traduction de Heroes III dans votre langue est installée, mais elle a été désactivée. Utilisez cette option pour l'activer. + La traduction de Heroes III dans votre langue est installée, mais elle a été désactivée. Utilisez cette option pour l'activer. A new version of some of the mods that you have installed is now available in mod repository. Use this option to automatically update all your mods to latest version. WARNING: In some cases, updated versions of mods may not be compatible with your existing saves. You may want to postpone mod update until you finish any of your ongoing games. -AI-generated, needs review by native speaker; delete this comment afterwards - Une nouvelle version de certains des mods que vous avez installés est maintenant disponible dans le référentiel de mods. Utilisez cette option pour mettre automatiquement à jour tous vos mods vers la dernière version. + Une nouvelle version de certains des mods que vous avez installés est maintenant disponible dans le référentiel de mods. Utilisez cette option pour mettre automatiquement à jour tous vos mods vers la dernière version. -ATTENTION : Dans certains cas, les versions mises à jour des mods peuvent ne pas être compatibles avec vos sauvegardes existantes. Vous voudrez peut-être reporter la mise à jour des mods jusqu'à ce que vous ayez terminé vos parties en cours. +ATTENTION : Dans certains cas, les versions mises à jour des mods peuvent ne pas être compatibles avec vos sauvegardes existantes. Vous voudrez peut-être reporter la mise à jour des mods jusqu'à ce que vous ayez terminé vos parties en cours. If you own Heroes Chronicles on gog.com, you can use offline backup installers provided by gog to import Heroes Chronicles data into VCMI as custom campaigns. To import Heroes Chronicles, download offline backup installer of each chronicle that you wish to install, select 'Import files' option and select downloaded file. This will generate and install mod for VCMI that contains imported chronicles -AI-generated, needs review by native speaker; delete this comment afterwards - Si vous possédez Heroes Chronicles sur gog.com, vous pouvez utiliser les installateurs de sauvegarde hors ligne fournis par gog pour importer les données de Heroes Chronicles dans VCMI en tant que campagnes personnalisées. -Pour importer Heroes Chronicles, téléchargez l'installateur de sauvegarde hors ligne de chaque chronique que vous souhaitez installer, sélectionnez l'option 'Importer des fichiers' et sélectionnez le fichier téléchargé. Cela générera et installera un mod pour VCMI contenant les chroniques importées. + Si vous possédez Heroes Chronicles sur gog.com, vous pouvez utiliser les installateurs de sauvegarde hors ligne fournis par gog pour importer les données de Heroes Chronicles dans VCMI en tant que campagnes personnalisées. +Pour importer Heroes Chronicles, téléchargez l'installateur de sauvegarde hors ligne de chaque chronique que vous souhaitez installer, sélectionnez l'option 'Importer des fichiers' et sélectionnez le fichier téléchargé. Cela générera et installera un mod pour VCMI contenant les chroniques importées. VCMI has detected that Heroes III music files are missing from your installation. VCMI will run, but in-game music will not be available. To resolve this problem, please copy missing mp3 files from Heroes III to VCMI data files directory manually or reinstall VCMI and re-import Heroes III data files -AI-generated, needs review by native speaker; delete this comment afterwards - VCMI a détecté que les fichiers de musique de Heroes III sont manquants dans votre installation. VCMI fonctionnera, mais la musique en jeu ne sera pas disponible. + VCMI a détecté que les fichiers de musique de Heroes III sont manquants dans votre installation. VCMI fonctionnera, mais la musique en jeu ne sera pas disponible. Pour résoudre ce problème, veuillez copier manuellement les fichiers mp3 manquants de Heroes III vers le répertoire des fichiers de données VCMI ou réinstallez VCMI et réimportez les fichiers de données de Heroes III. @@ -1976,8 +1854,7 @@ Pour résoudre ce problème, veuillez copier manuellement les fichiers mp3 manqu VCMI has detected that Heroes III video files are missing from your installation. VCMI will run, but in-game cutscenes will not be available. To resolve this problem, please copy VIDEO.VID file from Heroes III to VCMI data files directory manually or reinstall VCMI and re-import Heroes III data files -AI-generated, needs review by native speaker; delete this comment afterwards - VCMI a détecté que les fichiers vidéo de Heroes III sont manquants dans votre installation. VCMI fonctionnera, mais les cinématiques du jeu ne seront pas disponibles. + VCMI a détecté que les fichiers vidéo de Heroes III sont manquants dans votre installation. VCMI fonctionnera, mais les cinématiques du jeu ne seront pas disponibles. Pour résoudre ce problème, veuillez copier manuellement le fichier VIDEO.VID de Heroes III vers le répertoire des fichiers de données VCMI ou réinstallez VCMI et réimportez les fichiers de données de Heroes III. @@ -1986,8 +1863,7 @@ Pour résoudre ce problème, veuillez copier manuellement le fichier VIDEO.VID d VCMI has detected that some of Heroes III data files are missing from your installation. You may attempt to run VCMI, but game may not work as expected or crash. To resolve this problem, please reinstall game and reimport data files using supported version of Heroes III. VCMI requires Heroes III: Shadow of Death or Complete Edition to run, which you can get (for example) from gog.com -AI-generated, needs review by native speaker; delete this comment afterwards - VCMI a détecté que certains fichiers de données de Heroes III sont manquants dans votre installation. Vous pouvez tenter d'exécuter VCMI, mais le jeu peut ne pas fonctionner comme prévu ou planter. + VCMI a détecté que certains fichiers de données de Heroes III sont manquants dans votre installation. Vous pouvez tenter d'exécuter VCMI, mais le jeu peut ne pas fonctionner comme prévu ou planter. Pour résoudre ce problème, veuillez réinstaller le jeu et réimporter les fichiers de données en utilisant une version prise en charge de Heroes III. VCMI nécessite Heroes III : Shadow of Death ou Complete Edition pour fonctionner, que vous pouvez obtenir (par exemple) sur gog.com. @@ -1996,22 +1872,19 @@ Pour résoudre ce problème, veuillez réinstaller le jeu et réimporter les fic VCMI has detected that some of Heroes III: Armageddon's Blade data files are missing from your installation. VCMI will work, but Armageddon's Blade campaigns will not be available. To resolve this problem, please copy missing data files from Heroes III to VCMI data files directory manually or reinstall VCMI and re-import Heroes III data files -AI-generated, needs review by native speaker; delete this comment afterwards - VCMI a détecté que certains fichiers de données de Heroes III: Armageddon's Blade sont manquants dans votre installation. VCMI fonctionnera, mais les campagnes d'Armageddon's Blade ne seront pas disponibles. + VCMI a détecté que certains fichiers de données de Heroes III: Armageddon's Blade sont manquants dans votre installation. VCMI fonctionnera, mais les campagnes d'Armageddon's Blade ne seront pas disponibles. Pour résoudre ce problème, veuillez copier manuellement les fichiers de données manquants de Heroes III vers le répertoire des fichiers de données VCMI ou réinstallez VCMI et réimportez les fichiers de données de Heroes III. Enter preset name: - AI-generated, needs review by native speaker; delete this comment afterwards - Entrez le nom du préréglage : + Entrez le nom du préréglage : Rename preset '%1' to: - AI-generated, needs review by native speaker; delete this comment afterwards - Renommer le préréglage '%1' en : + Renommer le préréglage '%1' en : @@ -2039,8 +1912,7 @@ Pour résoudre ce problème, veuillez copier manuellement les fichiers de donné Cannot read JSON from URL or incorrect JSON data - AI-generated, needs review by native speaker; delete this comment afterwards - Impossible de lire le JSON depuis l'URL ou les données JSON sont incorrectes. + Impossible de lire le JSON depuis l'URL ou les données JSON sont incorrectes. - + \ No newline at end of file From d897246fa4c411d9d0a724aa723124b8e1deebb7 Mon Sep 17 00:00:00 2001 From: Maurycy <55395993+XCOM-HUB@users.noreply.github.com> Date: Sun, 9 Mar 2025 01:20:06 +0100 Subject: [PATCH 11/31] Update swedish.json (beta) Added new strings. --- Mods/vcmi/Content/config/swedish.json | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Mods/vcmi/Content/config/swedish.json b/Mods/vcmi/Content/config/swedish.json index 53c2c36f1..9d5d8397d 100644 --- a/Mods/vcmi/Content/config/swedish.json +++ b/Mods/vcmi/Content/config/swedish.json @@ -178,7 +178,7 @@ "vcmi.lobby.match.solo" : "Spel för en spelare", "vcmi.lobby.match.duel" : "Spel med %s", // %s -> smeknamn på en annan spelare "vcmi.lobby.match.multi" : "%d spelare", - "vcmi.lobby.room.create.hover" : "Skapa nytt rum", + "vcmi.lobby.room.create.hover" : "Skapa nytt rum", "vcmi.lobby.room.players.limit" : "Begränsning av spelare", "vcmi.lobby.room.description.public" : "Alla spelare kan gå med i det offentliga rummet.", "vcmi.lobby.room.description.private": "Endast inbjudna spelare kan gå med i ett privat rum.", @@ -307,6 +307,8 @@ "vcmi.systemOptions.enableLargeSpellbookButton.help" : "{Stor trollformelsbok}\n\nAktiverar en större trollformelsbok som rymmer fler trollformler per sida (animeringen av sidbyte i den större trollformelsboken fungerar inte).", "vcmi.systemOptions.audioMuteFocus.hover" : "Tyst vid inaktivitet", "vcmi.systemOptions.audioMuteFocus.help" : "{Tyst vid inaktivitet}\n\nStänger av ljudet i spelet vid inaktivitet. Undantag är meddelanden i spelet och ljudet för ny turomgång.", + "vcmi.systemOptions.enableOverlayButton.hover" : "Aktivera överläggsinformation", + "vcmi.systemOptions.enableOverlayButton.help" : "{Aktivera överläggsinformation}\n\nVisar behjälplig information på skärmen, så som namn på byggnader och objekt med hjälp av ALT-tangenten eller en tvåfingergest.", "vcmi.adventureOptions.infoBarPick.hover" : "Visar textmeddelanden i infopanelen", "vcmi.adventureOptions.infoBarPick.help" : "{Infopanelsmeddelanden}\n\nNär det är möjligt kommer spelmeddelanden från besökande kartobjekt att visas i infopanelen istället för att dyka upp i ett separat fönster.", From 5847d56fa426c74b1617bae351fba336c8266756 Mon Sep 17 00:00:00 2001 From: Ivan Savenko Date: Tue, 11 Mar 2025 16:22:41 +0000 Subject: [PATCH 12/31] Try to fix remaining crashes with innoextract on Android (cherry picked from commit ee39aebdaa0029c6779e9fc39ec01ddc2df0067a) --- launcher/firstLaunch/firstlaunch_moc.cpp | 223 +++++++++++++---------- launcher/firstLaunch/firstlaunch_moc.h | 1 + 2 files changed, 129 insertions(+), 95 deletions(-) diff --git a/launcher/firstLaunch/firstlaunch_moc.cpp b/launcher/firstLaunch/firstlaunch_moc.cpp index 0fb7abe0c..0dacf673c 100644 --- a/launcher/firstLaunch/firstlaunch_moc.cpp +++ b/launcher/firstLaunch/firstlaunch_moc.cpp @@ -330,25 +330,6 @@ void FirstLaunchView::extractGogData() return file; }; - auto checkMagic = [this](QString filename, QString filter, QByteArray magic) - { - QString titleErr = tr("You have to select %1 file!", "param is file extension").arg(filter); - - QFile tmpFile(filename); - if(!tmpFile.open(QIODevice::ReadOnly)) - { - QMessageBox::critical(this, tr("File cannot be opened"), tmpFile.errorString()); - return false; - } - QByteArray magicFile = tmpFile.read(magic.length()); - if(!magicFile.startsWith(magic)) - { - QMessageBox::critical(this, tr("Invalid file selected"), titleErr); - return false; - } - return true; - }; - QString filterBin = tr("GOG data") + " (*.bin)"; QString filterExe = tr("GOG installer") + " (*.exe)"; @@ -363,89 +344,141 @@ void FirstLaunchView::extractGogData() ui->pushButtonGogInstall->setVisible(false); setEnabled(false); - QTimer::singleShot(100, this, [this, fileExe, fileBin, checkMagic, filterBin, filterExe](){ // background to make sure FileDialog is closed... - QDir tempDir(pathToQString(VCMIDirs::get().userDataPath())); - if(tempDir.cd("tmp")) - { - tempDir.removeRecursively(); // remove if already exists (e.g. previous crash) - tempDir.cdUp(); - } - tempDir.mkdir("tmp"); - if(!tempDir.cd("tmp")) - return; // should not happen - but avoid deleting wrong folder in any case - - QString tmpFileExe = tempDir.filePath("h3_gog.exe"); - QString tmpFileBin = tempDir.filePath("h3_gog-1.bin"); - - Helper::performNativeCopy(fileExe, tmpFileExe); - Helper::performNativeCopy(fileBin, tmpFileBin); - - if (!checkMagic(tmpFileBin, filterBin, QByteArray{"idska32"}) || - !checkMagic(tmpFileExe, filterExe, QByteArray{"MZ"})) - return; - - logGlobal->info("Installing exe '%s' ('%s')", tmpFileExe.toStdString(), fileExe.toStdString()); - logGlobal->info("Installing bin '%s' ('%s')", tmpFileBin.toStdString(), fileBin.toStdString()); - - QString errorText{}; - - auto isGogGalaxyExe = [](QString fileToTest) { - QFile file(fileToTest); - quint64 fileSize = file.size(); - - if(fileSize > 10 * 1024 * 1024) - return false; // avoid to load big files; galaxy exe is smaller... - - if(!file.open(QIODevice::ReadOnly)) - return false; - QByteArray data = file.readAll(); - - const QByteArray magicId{reinterpret_cast(u"GOG Galaxy"), 20}; - return data.contains(magicId); - }; - - if(isGogGalaxyExe(tmpFileExe)) - errorText = tr("You've provided a GOG Galaxy installer! This file doesn't contain the game. Please download the offline backup game installer!"); - - if(errorText.isEmpty()) - errorText = Innoextract::extract(tmpFileExe, tempDir.path(), [this](float progress) { - ui->progressBarGog->setValue(progress * 100); - qApp->processEvents(); - }); - - QString hashError; - if(!errorText.isEmpty()) - hashError = Innoextract::getHashError(tmpFileExe, tmpFileBin, fileExe, fileBin); - + QTimer::singleShot(100, this, [this, fileBin, fileExe](){ // background to make sure FileDialog is closed... + extractGogDataAsync(fileBin, fileExe); ui->progressBarGog->setVisible(false); ui->pushButtonGogInstall->setVisible(true); setEnabled(true); - - QStringList dirData = tempDir.entryList({"data"}, QDir::Filter::Dirs); - if(!errorText.isEmpty() || dirData.empty() || QDir(tempDir.filePath(dirData.front())).entryList({"*.lod"}, QDir::Filter::Files).empty()) - { - if(!errorText.isEmpty()) - { - logGlobal->error("Gog installer extraction failure! Reason: %s", errorText.toStdString()); - QMessageBox::critical(this, tr("Extracting error!"), errorText, QMessageBox::Ok, QMessageBox::Ok); - if(!hashError.isEmpty()) - { - logGlobal->error("Hash error: %s", hashError.toStdString()); - QMessageBox::critical(this, tr("Hash error!"), hashError, QMessageBox::Ok, QMessageBox::Ok); - } - } - else - QMessageBox::critical(this, tr("No Heroes III data!"), tr("Selected files do not contain Heroes III data!"), QMessageBox::Ok, QMessageBox::Ok); - tempDir.removeRecursively(); - return; - } - copyHeroesData(tempDir.path(), true); - - tempDir.removeRecursively(); }); #endif } +void FirstLaunchView::extractGogDataAsync(QString filePathBin, QString filePathExe) +{ + logGlobal->info("Extracting gog data from '%s' and '%s'", filePathBin.toStdString(), filePathExe.toStdString()); + +#ifdef ENABLE_INNOEXTRACT + auto checkMagic = [](QString filename, QString filter, QByteArray magic) + { + logGlobal->info("Checking file %s", filename.toStdString()); + + QFile tmpFile(filename); + if(!tmpFile.open(QIODevice::ReadOnly)) + { + logGlobal->info("File cannot be opened: %s", tmpFile.errorString().toStdString()); + return tr("Failed to open file: %1").arg(tmpFile.errorString()); + } + + QByteArray magicFile = tmpFile.read(magic.length()); + if(!magicFile.startsWith(magic)) + { + logGlobal->info("Invalid file selected: %s", filter.toStdString()); + return tr("You have to select %1 file!", "param is file extension").arg(filter); + } + + logGlobal->info("Checking file %s", filename.toStdString()); + return QString(); + }; + + QString filterBin = tr("GOG data") + " (*.bin)"; + QString filterExe = tr("GOG installer") + " (*.exe)"; + + QDir tempDir(pathToQString(VCMIDirs::get().userDataPath())); + if(tempDir.cd("tmp")) + { + logGlobal->info("Cleaning up old data"); + tempDir.removeRecursively(); // remove if already exists (e.g. previous crash) + tempDir.cdUp(); + } + tempDir.mkdir("tmp"); + if(!tempDir.cd("tmp")) + return; // should not happen - but avoid deleting wrong folder in any case + + logGlobal->info("Using '%s' as temporary directory", tempDir.path().toStdString()); + + QString tmpFileExe = tempDir.filePath("h3_gog.exe"); + QString tmpFileBin = tempDir.filePath("h3_gog-1.bin"); + + logGlobal->info("Performing native copy..."); + Helper::performNativeCopy(filePathExe, tmpFileExe); + Helper::performNativeCopy(filePathBin, tmpFileBin); + logGlobal->info("Native copy completed"); + + QString errorText{}; + + if (errorText.isEmpty()) + errorText = checkMagic(tmpFileBin, filterBin, QByteArray{"idska32"}); + + if (errorText.isEmpty()) + errorText = checkMagic(tmpFileExe, filterExe, QByteArray{"MZ"}); + + logGlobal->info("Installing exe '%s' ('%s')", tmpFileExe.toStdString(), filePathExe.toStdString()); + logGlobal->info("Installing bin '%s' ('%s')", tmpFileBin.toStdString(), filePathBin.toStdString()); + + auto isGogGalaxyExe = [](QString fileToTest) { + QFile file(fileToTest); + quint64 fileSize = file.size(); + + if(fileSize > 10 * 1024 * 1024) + return false; // avoid to load big files; galaxy exe is smaller... + + if(!file.open(QIODevice::ReadOnly)) + return false; + QByteArray data = file.readAll(); + + const QByteArray magicId{reinterpret_cast(u"GOG Galaxy"), 20}; + return data.contains(magicId); + }; + + if(errorText.isEmpty()) + { + if(isGogGalaxyExe(tmpFileExe)) + { + logGlobal->info("Gog Galaxy detected! Aborting..."); + errorText = tr("You've provided a GOG Galaxy installer! This file doesn't contain the game. Please download the offline backup game installer!"); + } + } + + if(errorText.isEmpty()) + { + logGlobal->info("Performing extraction using innoextract..."); + errorText = Innoextract::extract(tmpFileExe, tempDir.path(), [this](float progress) { + ui->progressBarGog->setValue(progress * 100); + qApp->processEvents(); + }); + logGlobal->info("Extraction done!"); + } + + QString hashError; + if(!errorText.isEmpty()) + hashError = Innoextract::getHashError(tmpFileExe, tmpFileBin, filePathExe, filePathBin); + + QStringList dirData = tempDir.entryList({"data"}, QDir::Filter::Dirs); + if(!errorText.isEmpty() || dirData.empty() || QDir(tempDir.filePath(dirData.front())).entryList({"*.lod"}, QDir::Filter::Files).empty()) + { + if(!errorText.isEmpty()) + { + logGlobal->error("Gog installer extraction failure! Reason: %s", errorText.toStdString()); + QMessageBox::critical(this, tr("Extracting error!"), errorText, QMessageBox::Ok, QMessageBox::Ok); + if(!hashError.isEmpty()) + { + logGlobal->error("Hash error: %s", hashError.toStdString()); + QMessageBox::critical(this, tr("Hash error!"), hashError, QMessageBox::Ok, QMessageBox::Ok); + } + } + else + QMessageBox::critical(this, tr("No Heroes III data!"), tr("Selected files do not contain Heroes III data!"), QMessageBox::Ok, QMessageBox::Ok); + tempDir.removeRecursively(); + return; + } + + logGlobal->info("Copying provided game files..."); + copyHeroesData(tempDir.path(), true); + + tempDir.removeRecursively(); +#endif +} + void FirstLaunchView::copyHeroesData(const QString & path, bool move) { QDir sourceRoot{path}; diff --git a/launcher/firstLaunch/firstlaunch_moc.h b/launcher/firstLaunch/firstlaunch_moc.h index 995504656..3dbb469c8 100644 --- a/launcher/firstLaunch/firstlaunch_moc.h +++ b/launcher/firstLaunch/firstlaunch_moc.h @@ -42,6 +42,7 @@ class FirstLaunchView : public QWidget QString getHeroesInstallDir(); void extractGogData(); + void extractGogDataAsync(QString filePathBin, QString filePathExe); void copyHeroesData(const QString & path = {}, bool move = false); // Tab Mod Preset From 751a334e5a98c5867ab1a81501efba3501411eca Mon Sep 17 00:00:00 2001 From: Ivan Savenko Date: Tue, 11 Mar 2025 13:41:14 +0000 Subject: [PATCH 13/31] Fix possible crash on accessing Cannon Yard from HotA (cherry picked from commit e273263334ef8900c8fee8e0ae04959ec10b6073) --- lib/mapObjects/CGDwelling.cpp | 14 +++++++++++--- server/CGameHandler.cpp | 11 +++++++++++ 2 files changed, 22 insertions(+), 3 deletions(-) diff --git a/lib/mapObjects/CGDwelling.cpp b/lib/mapObjects/CGDwelling.cpp index af8de0b43..b169e5446 100644 --- a/lib/mapObjects/CGDwelling.cpp +++ b/lib/mapObjects/CGDwelling.cpp @@ -474,9 +474,17 @@ void CGDwelling::heroAcceptsCreatures( const CGHeroInstance *h) const SetAvailableCreatures sac; sac.tid = id; sac.creatures = creatures; - sac.creatures[0].first = !h->getArt(ArtifactPosition::MACH1); //ballista - sac.creatures[1].first = !h->getArt(ArtifactPosition::MACH3); //first aid tent - sac.creatures[2].first = !h->getArt(ArtifactPosition::MACH2); //ammo cart + + for (auto & entry : sac.creatures) + { + CreatureID creature = entry.second.at(0); + ArtifactID warMachine = creature.toCreature()->warMachine; + + if (h->hasArt(warMachine, true, false)) + entry.first = 0; + else + entry.first = 1; + } cb->sendAndApply(sac); } diff --git a/server/CGameHandler.cpp b/server/CGameHandler.cpp index 14ad48a2a..f0eae8dae 100644 --- a/server/CGameHandler.cpp +++ b/server/CGameHandler.cpp @@ -2397,7 +2397,18 @@ bool CGameHandler::recruitCreatures(ObjectInstanceID objid, ObjectInstanceID dst COMPLAIN_RET_FALSE_IF(!hero, "Only hero can buy war machines"); COMPLAIN_RET_FALSE_IF(artId == ArtifactID::CATAPULT, "Catapult cannot be recruited!"); COMPLAIN_RET_FALSE_IF(nullptr == art, "Invalid war machine artifact"); + COMPLAIN_RET_FALSE_IF(hero->hasArt(artId),"Hero already has this machine!"); + bool hasFreeSlot = false; + for(auto slot : art->getPossibleSlots().at(ArtBearer::HERO)) + if (hero->getArt(slot) == nullptr) + hasFreeSlot = true; + + if (!hasFreeSlot) + { + auto slot = art->getPossibleSlots().at(ArtBearer::HERO).front(); + removeArtifact(ArtifactLocation(hero->id, slot)); + } return giveHeroNewArtifact(hero, artId, ArtifactPosition::FIRST_AVAILABLE); } else From facc1888c5095c8bb1b8e4ce16dc98f8acb9924b Mon Sep 17 00:00:00 2001 From: Laserlicht <13953785+Laserlicht@users.noreply.github.com> Date: Sat, 8 Mar 2025 12:46:00 +0100 Subject: [PATCH 14/31] fix crash, when no cost for upgrade --- client/windows/CCastleInterface.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/client/windows/CCastleInterface.cpp b/client/windows/CCastleInterface.cpp index adf5f1cbd..56e728fbd 100644 --- a/client/windows/CCastleInterface.cpp +++ b/client/windows/CCastleInterface.cpp @@ -398,6 +398,8 @@ void CHeroGSlot::gesture(bool on, const Point & initialPosition, const Point & f std::vector> resComps; for(TResources::nziterator i(upgradableSlots.totalCosts); i.valid(); i++) resComps.push_back(std::make_shared(ComponentType::RESOURCE, i->resType, i->resVal)); + if(!resComps.size()) + resComps.push_back(std::make_shared(ComponentType::RESOURCE, static_cast(GameResID::GOLD), 0)); // add at least gold, when there are no costs resComps.back()->newLine = true; for(auto & upgradeInfo : upgradableSlots.upgradeInfos) resComps.push_back(std::make_shared(ComponentType::CREATURE, upgradeInfo.second.getUpgrade(), obj->Slots().at(upgradeInfo.first)->count)); From 5682b3a2844b76ab6302da5d8bc61df37c7a330f Mon Sep 17 00:00:00 2001 From: Laserlicht <13953785+Laserlicht@users.noreply.github.com> Date: Sat, 8 Mar 2025 15:08:33 +0100 Subject: [PATCH 15/31] Update client/windows/CCastleInterface.cpp Co-authored-by: Ivan Savenko --- client/windows/CCastleInterface.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/windows/CCastleInterface.cpp b/client/windows/CCastleInterface.cpp index 56e728fbd..eb86da176 100644 --- a/client/windows/CCastleInterface.cpp +++ b/client/windows/CCastleInterface.cpp @@ -398,7 +398,7 @@ void CHeroGSlot::gesture(bool on, const Point & initialPosition, const Point & f std::vector> resComps; for(TResources::nziterator i(upgradableSlots.totalCosts); i.valid(); i++) resComps.push_back(std::make_shared(ComponentType::RESOURCE, i->resType, i->resVal)); - if(!resComps.size()) + if(resComps.empty()) resComps.push_back(std::make_shared(ComponentType::RESOURCE, static_cast(GameResID::GOLD), 0)); // add at least gold, when there are no costs resComps.back()->newLine = true; for(auto & upgradeInfo : upgradableSlots.upgradeInfos) From 9fa43435b8ec125f840ff4a16cbaef2b07a99681 Mon Sep 17 00:00:00 2001 From: Laserlicht <13953785+Laserlicht@users.noreply.github.com> Date: Mon, 10 Mar 2025 18:27:35 +0100 Subject: [PATCH 16/31] fix sort crash --- client/lobby/SelectionTab.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/client/lobby/SelectionTab.cpp b/client/lobby/SelectionTab.cpp index ec36440a6..d7c6e8b12 100644 --- a/client/lobby/SelectionTab.cpp +++ b/client/lobby/SelectionTab.cpp @@ -617,7 +617,13 @@ void SelectionTab::sort() if(!sortModeAscending) { if(firstMapIndex) - std::reverse(std::next(curItems.begin(), boost::starts_with(curItems[0]->folderName, "..") ? 1 : 0), std::next(curItems.begin(), firstMapIndex - 1)); + { + auto startIt = std::next(curItems.begin(), boost::starts_with(curItems[0]->folderName, "..") ? 1 : 0); + auto endIt = std::next(curItems.begin(), firstMapIndex - 1); + if(startIt > endIt) + std::swap(startIt, endIt); + std::reverse(startIt, endIt); + } std::reverse(std::next(curItems.begin(), firstMapIndex), curItems.end()); } From 20be3279027f4d2e44dd41cb66dfb50c216614cb Mon Sep 17 00:00:00 2001 From: Andrey Filipenkov Date: Wed, 12 Mar 2025 13:59:19 +0300 Subject: [PATCH 17/31] [iOS] enable portrait mode launcher stays landscape-only on iPhones --- client/eventsSDL/InputHandler.cpp | 2 +- clientapp/ios/Info.plist | 5 -- launcher/CMakeLists.txt | 6 ++ launcher/prepare.cpp | 64 +------------------ launcher/prepare_android.cpp | 71 +++++++++++++++++++++ launcher/prepare_ios.mm | 40 ++++++++++++ launcher/prepare_p.h | 19 ++++++ launcher/settingsView/csettingsview_moc.cpp | 4 +- 8 files changed, 142 insertions(+), 69 deletions(-) create mode 100644 launcher/prepare_android.cpp create mode 100644 launcher/prepare_ios.mm create mode 100644 launcher/prepare_p.h diff --git a/client/eventsSDL/InputHandler.cpp b/client/eventsSDL/InputHandler.cpp index f6e32166b..b0d20711a 100644 --- a/client/eventsSDL/InputHandler.cpp +++ b/client/eventsSDL/InputHandler.cpp @@ -237,7 +237,7 @@ void InputHandler::preprocessEvent(const SDL_Event & ev) #endif break; case SDL_WINDOWEVENT_SIZE_CHANGED: -#ifdef VCMI_ANDROID +#ifdef VCMI_MOBILE { boost::mutex::scoped_lock interfaceLock(GH.interfaceMutex); GH.onScreenResize(true); diff --git a/clientapp/ios/Info.plist b/clientapp/ios/Info.plist index 0fba21025..32d1f671d 100644 --- a/clientapp/ios/Info.plist +++ b/clientapp/ios/Info.plist @@ -53,10 +53,5 @@ UIStatusBarHidden - UISupportedInterfaceOrientations - - UIInterfaceOrientationLandscapeLeft - UIInterfaceOrientationLandscapeRight - diff --git a/launcher/CMakeLists.txt b/launcher/CMakeLists.txt index 7f163cbf1..47530635a 100644 --- a/launcher/CMakeLists.txt +++ b/launcher/CMakeLists.txt @@ -31,6 +31,11 @@ if(APPLE_IOS) ios/revealdirectoryinfiles.mm ios/selectdirectory.h ios/selectdirectory.mm + prepare_ios.mm + ) +elseif(ANDROID) + list(APPEND launcher_SRCS + prepare_android.cpp ) endif() @@ -55,6 +60,7 @@ set(launcher_HEADERS helper.h innoextract.h prepare.h + prepare_p.h ) set(launcher_FORMS diff --git a/launcher/prepare.cpp b/launcher/prepare.cpp index 7e158d4ac..f971bf644 100644 --- a/launcher/prepare.cpp +++ b/launcher/prepare.cpp @@ -9,75 +9,17 @@ */ #include "StdInc.h" #include "prepare.h" +#include "prepare_p.h" #include "../vcmiqt/launcherdirs.h" -#include -#include -#include - -#ifdef VCMI_ANDROID -#include "../lib/CAndroidVMHelper.h" - -#include -#include -#include - -namespace -{ -// https://gist.github.com/ssendeavour/7324701 -bool copyRecursively(const QString &srcFilePath, const QString &tgtFilePath) -{ - QFileInfo srcFileInfo{srcFilePath}; - if(srcFileInfo.isDir()) { - QDir targetDir{tgtFilePath}; - targetDir.cdUp(); - if(!targetDir.mkpath(QFileInfo{tgtFilePath}.fileName())) - return false; - targetDir.setPath(tgtFilePath); - - QDir sourceDir{srcFilePath}; - const auto fileNames = sourceDir.entryList(QDir::Files | QDir::Dirs | QDir::NoDotAndDotDot | QDir::Hidden | QDir::System); - for(const auto & fileName : fileNames) { - const auto newSrcFilePath = sourceDir.filePath(fileName); - const auto newTgtFilePath = targetDir.filePath(fileName); - if(!copyRecursively(newSrcFilePath, newTgtFilePath)) - return false; - } - } else { - if(!QFile::copy(srcFilePath, tgtFilePath)) - return false; - } - return true; -} - -void prepareAndroid() -{ - QAndroidJniEnvironment jniEnv; - CAndroidVMHelper::initClassloader(static_cast(jniEnv)); - - const bool justLaunched = QtAndroid::androidActivity().getField("justLaunched") == JNI_TRUE; - if(!justLaunched) - return; - - // copy core data to internal directory - const auto vcmiDir = QAndroidJniObject::callStaticObjectMethod("eu/vcmi/vcmi/NativeMethods", "internalDataRoot").toString(); - for(auto vcmiFilesResource : {QLatin1String{"config"}, QLatin1String{"Mods"}}) - { - QDir destDir = QString{"%1/%2"}.arg(vcmiDir, vcmiFilesResource); - destDir.removeRecursively(); - copyRecursively(QString{":/%1"}.arg(vcmiFilesResource), destDir.absolutePath()); - } -} -} -#endif - - namespace launcher { void prepare() { #ifdef VCMI_ANDROID prepareAndroid(); +#elif defined(VCMI_IOS) + prepareIos(); #endif CLauncherDirs::prepare(); diff --git a/launcher/prepare_android.cpp b/launcher/prepare_android.cpp new file mode 100644 index 000000000..0a25b3972 --- /dev/null +++ b/launcher/prepare_android.cpp @@ -0,0 +1,71 @@ +/* + * prepare_android.cpp, part of VCMI engine + * + * Authors: listed in file AUTHORS in main folder + * + * License: GNU General Public License v2.0 or later + * Full text of license available in license.txt file, in main folder + * + */ +#include "StdInc.h" +#include "prepare_p.h" +#include "../lib/CAndroidVMHelper.h" + +#include +#include +#include + +#include +#include +#include + +namespace +{ +// https://gist.github.com/ssendeavour/7324701 +bool copyRecursively(const QString & srcFilePath, const QString & tgtFilePath) +{ + QFileInfo srcFileInfo{srcFilePath}; + if(srcFileInfo.isDir()) { + QDir targetDir{tgtFilePath}; + targetDir.cdUp(); + if(!targetDir.mkpath(QFileInfo{tgtFilePath}.fileName())) + return false; + targetDir.setPath(tgtFilePath); + + QDir sourceDir{srcFilePath}; + const auto fileNames = sourceDir.entryList(QDir::Files | QDir::Dirs | QDir::NoDotAndDotDot | QDir::Hidden | QDir::System); + for(const auto & fileName : fileNames) { + const auto newSrcFilePath = sourceDir.filePath(fileName); + const auto newTgtFilePath = targetDir.filePath(fileName); + if(!copyRecursively(newSrcFilePath, newTgtFilePath)) + return false; + } + } else { + if(!QFile::copy(srcFilePath, tgtFilePath)) + return false; + } + return true; +} +} + +namespace launcher +{ +void prepareAndroid() +{ + QAndroidJniEnvironment jniEnv; + CAndroidVMHelper::initClassloader(static_cast(jniEnv)); + + const bool justLaunched = QtAndroid::androidActivity().getField("justLaunched") == JNI_TRUE; + if(!justLaunched) + return; + + // copy core data to internal directory + const auto vcmiDir = QAndroidJniObject::callStaticObjectMethod("eu/vcmi/vcmi/NativeMethods", "internalDataRoot").toString(); + for(auto vcmiFilesResource : {QLatin1String{"config"}, QLatin1String{"Mods"}}) + { + QDir destDir = QString{"%1/%2"}.arg(vcmiDir, vcmiFilesResource); + destDir.removeRecursively(); + copyRecursively(QString{":/%1"}.arg(vcmiFilesResource), destDir.absolutePath()); + } +} +} diff --git a/launcher/prepare_ios.mm b/launcher/prepare_ios.mm new file mode 100644 index 000000000..25f4d2c79 --- /dev/null +++ b/launcher/prepare_ios.mm @@ -0,0 +1,40 @@ +/* + * prepare_ios.mm, part of VCMI engine + * + * Authors: listed in file AUTHORS in main folder + * + * License: GNU General Public License v2.0 or later + * Full text of license available in license.txt file, in main folder + * + */ +#include "StdInc.h" +#include "prepare_p.h" + +#import + +#include + +namespace +{ +UIInterfaceOrientationMask swizzled_supportedInterfaceOrientationsForWindow + (id __unused self, SEL __unused _cmd, UIApplication * __unused application, UIWindow * __unused _Nullable window) +{ + if(UIDevice.currentDevice.userInterfaceIdiom == UIUserInterfaceIdiomPad) + return UIInterfaceOrientationMaskAll; + return UIInterfaceOrientationMaskLandscape; +} +} + +namespace launcher +{ +void prepareIos() +{ + auto sel = @selector(application:supportedInterfaceOrientationsForWindow:); + auto methodDesc = protocol_getMethodDescription(@protocol(UIApplicationDelegate), sel, NO, YES); + auto appDelegateClass = object_getClass(UIApplication.sharedApplication.delegate); + [[maybe_unused]] auto existingImp = class_replaceMethod( + appDelegateClass, sel, (IMP)swizzled_supportedInterfaceOrientationsForWindow, methodDesc.types); + // also check implementation in qtbase - src/plugins/platforms/ios/qiosapplicationdelegate.mm + NSCAssert(existingImp == nullptr, @"original app delegate has this method, don't ignore it"); +} +} diff --git a/launcher/prepare_p.h b/launcher/prepare_p.h new file mode 100644 index 000000000..904353cea --- /dev/null +++ b/launcher/prepare_p.h @@ -0,0 +1,19 @@ +/* + * prepare_p.h, part of VCMI engine + * + * Authors: listed in file AUTHORS in main folder + * + * License: GNU General Public License v2.0 or later + * Full text of license available in license.txt file, in main folder + * + */ +#pragma once + +namespace launcher +{ +#ifdef VCMI_ANDROID +void prepareAndroid(); +#elif defined(VCMI_IOS) +void prepareIos(); +#endif +} diff --git a/launcher/settingsView/csettingsview_moc.cpp b/launcher/settingsView/csettingsview_moc.cpp index c1cb1cbb5..b45025274 100644 --- a/launcher/settingsView/csettingsview_moc.cpp +++ b/launcher/settingsView/csettingsview_moc.cpp @@ -120,6 +120,8 @@ void CSettingsView::loadSettings() ui->labelHapticFeedback->hide(); ui->labelResetTutorialTouchscreen->hide(); ui->pushButtonResetTutorialTouchscreen->hide(); + ui->labelAllowPortrait->hide(); + ui->buttonAllowPortrait->hide(); if (settings["video"]["realFullscreen"].Bool()) ui->comboBoxFullScreen->setCurrentIndex(2); else @@ -128,8 +130,6 @@ void CSettingsView::loadSettings() #ifndef VCMI_ANDROID ui->buttonHandleBackRightMouseButton->hide(); ui->labelHandleBackRightMouseButton->hide(); - ui->buttonAllowPortrait->hide(); - ui->labelAllowPortrait->hide(); #endif fillValidScalingRange(); From e9dc6c2b5305d1b9a03f0dc401e3437833a024b1 Mon Sep 17 00:00:00 2001 From: Andrey Filipenkov Date: Fri, 14 Mar 2025 10:18:37 +0300 Subject: [PATCH 18/31] [conan] move comment to a separate line --- CI/conan/base/android | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CI/conan/base/android b/CI/conan/base/android index 931061b30..507c18bbc 100644 --- a/CI/conan/base/android +++ b/CI/conan/base/android @@ -6,4 +6,5 @@ compiler.version=14 os=Android [buildenv] -LD=ld # fixes shared libiconv build +# fixes shared libiconv build +LD=ld From 602616f38f0ca17de9ba47eddb0a80b799812025 Mon Sep 17 00:00:00 2001 From: Andrey Filipenkov Date: Tue, 25 Mar 2025 09:57:47 +0300 Subject: [PATCH 19/31] [launcher] restore quitting launcher when starting game on Windows and macOS --- launcher/main.cpp | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/launcher/main.cpp b/launcher/main.cpp index 019ee87e6..dfef9f96b 100644 --- a/launcher/main.cpp +++ b/launcher/main.cpp @@ -108,21 +108,36 @@ void startEditor(const QStringList & args) #ifndef VCMI_MOBILE void startExecutable(QString name, const QStringList & args) { + QProcess process; + auto showError = [&] { + QMessageBox::critical(qApp->activeWindow(), + QObject::tr("Error starting executable"), + QObject::tr("Failed to start %1\nReason: %2").arg(name, process.errorString())); + }; + +#if defined(VCMI_MAC) || defined(VCMI_WINDOWS) + if(process.startDetached(name, args)) + { + qApp->quit(); + } + else + { + showError(); + } +#else // Linux // Start vcmiclient and vcmieditor with QProcess::start() instead of QProcess::startDetached() // since startDetached() results in a missing terminal prompt after quitting vcmiclient. // QProcess::start() causes the launcher window to freeze while the child process is running, so we hide it in // MainWindow::on_startGameButton_clicked() and MainWindow::on_startEditorButton_clicked() - QProcess process; process.setProcessChannelMode(QProcess::ForwardedChannels); process.start(name, args); process.waitForFinished(-1); if (process.exitStatus() != QProcess::NormalExit || process.exitCode() != 0) { - QMessageBox::critical(qApp->activeWindow(), - QObject::tr("Error starting executable"), - QObject::tr("Failed to start %1\nReason: %2").arg(name, process.errorString())); + showError(); } qApp->quit(); +#endif } #endif From 9da598dcaf3cf527bce71bf94d5f9dc76800b373 Mon Sep 17 00:00:00 2001 From: Ivan Savenko Date: Sun, 16 Mar 2025 17:34:15 +0000 Subject: [PATCH 20/31] Fix possible crash on accessing content rect with nullptr surface --- client/renderSDL/SDLImage.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/client/renderSDL/SDLImage.cpp b/client/renderSDL/SDLImage.cpp index 8722ecd41..85a10d1c2 100644 --- a/client/renderSDL/SDLImage.cpp +++ b/client/renderSDL/SDLImage.cpp @@ -352,9 +352,10 @@ Rect SDLImageShared::contentRect() const if(upscalingInProgress) throw std::runtime_error("Attempt to access images that is still being loaded!"); - auto tmpMargins = margins; - auto tmpSize = Point(surf->w, surf->h); - return Rect(tmpMargins, tmpSize); + if (!surf) + return Rect(); + + return Rect(margins, Point(surf->w, surf->h)); } const SDL_Palette * SDLImageShared::getPalette() const From ded12f2df9d0e47039d099d66b41fb68430432d1 Mon Sep 17 00:00:00 2001 From: Ivan Savenko Date: Sun, 16 Mar 2025 17:34:35 +0000 Subject: [PATCH 21/31] Disable auto-selection of xbrz on 32-bit systems --- client/renderSDL/ScreenHandler.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/client/renderSDL/ScreenHandler.cpp b/client/renderSDL/ScreenHandler.cpp index 082fa6dcf..deada10e1 100644 --- a/client/renderSDL/ScreenHandler.cpp +++ b/client/renderSDL/ScreenHandler.cpp @@ -368,6 +368,7 @@ EUpscalingFilter ScreenHandler::loadUpscalingFilter() const float scaleY = static_cast(outputResolution.x) / logicalResolution.x; float scaling = std::min(scaleX, scaleY); int systemMemoryMb = SDL_GetSystemRAM(); + bool is32Bit = sizeof(void*) == 4; if (scaling <= 1.001f) return EUpscalingFilter::NONE; // running at original resolution or even lower than that - no need for xbrz @@ -375,6 +376,9 @@ EUpscalingFilter ScreenHandler::loadUpscalingFilter() const if (systemMemoryMb < 2048) return EUpscalingFilter::NONE; // xbrz2 may use ~1.0 - 1.5 Gb of RAM and has notable CPU cost - avoid on low-spec hardware + if (is32Bit) + return EUpscalingFilter::NONE; // to be safe, avoid large numbers of memory (re)allocations when address space is small + // Only using xbrz2 for autoselection. // Higher options may have high system requirements and should be only selected explicitly by player return EUpscalingFilter::XBRZ_2; From 8a0fed7b3a379e161593cddeb680921b187e89c9 Mon Sep 17 00:00:00 2001 From: Ivan Savenko Date: Sun, 16 Mar 2025 17:35:31 +0000 Subject: [PATCH 22/31] Temporarily(?) use weak_ptr to reduce ram usage increase during long game sessions --- client/renderSDL/RenderHandler.cpp | 15 ++++++++++----- client/renderSDL/RenderHandler.h | 4 ++-- client/renderSDL/SDLImage.cpp | 21 ++++++++++++--------- client/renderSDL/SDLImage.h | 5 +++-- 4 files changed, 27 insertions(+), 18 deletions(-) diff --git a/client/renderSDL/RenderHandler.cpp b/client/renderSDL/RenderHandler.cpp index df44e9a19..1a6445ff4 100644 --- a/client/renderSDL/RenderHandler.cpp +++ b/client/renderSDL/RenderHandler.cpp @@ -58,13 +58,14 @@ std::shared_ptr RenderHandler::getAnimationFile(const AnimationPath & auto it = animationFiles.find(actualPath); if (it != animationFiles.end()) - return it->second; + { + auto locked = it->second.lock(); + if (locked) + return locked; + } if (!CResourceHandler::get()->existsResource(actualPath)) - { - animationFiles[actualPath] = nullptr; return nullptr; - } auto result = std::make_shared(actualPath); @@ -200,7 +201,11 @@ std::shared_ptr RenderHandler::loadImageImpl(const ImageLoc { auto it = imageFiles.find(locator); if (it != imageFiles.end()) - return it->second; + { + auto locked = it->second.lock(); + if (locked) + return locked; + } auto sdlImage = loadImageFromFileUncached(locator); auto scaledImage = std::make_shared(locator, sdlImage); diff --git a/client/renderSDL/RenderHandler.h b/client/renderSDL/RenderHandler.h index b795e5a4e..c5d88e3f9 100644 --- a/client/renderSDL/RenderHandler.h +++ b/client/renderSDL/RenderHandler.h @@ -24,9 +24,9 @@ class RenderHandler final : public IRenderHandler { using AnimationLayoutMap = std::map>; - std::map> animationFiles; + std::map> animationFiles; std::map animationLayouts; - std::map> imageFiles; + std::map> imageFiles; std::map> fonts; std::unique_ptr assetGenerator; diff --git a/client/renderSDL/SDLImage.cpp b/client/renderSDL/SDLImage.cpp index 85a10d1c2..a9119ed9c 100644 --- a/client/renderSDL/SDLImage.cpp +++ b/client/renderSDL/SDLImage.cpp @@ -246,7 +246,7 @@ std::shared_ptr SDLImageShared::scaleInteger(int factor, SDL else algorithm = EScalingAlgorithm::XBRZ_ALPHA; - auto result = std::make_shared(this, factor, algorithm); + auto result = SDLImageShared::createScaled(this, factor, algorithm); if (surf->format->palette) SDL_SetSurfacePalette(surf, originalPalette); @@ -254,28 +254,31 @@ std::shared_ptr SDLImageShared::scaleInteger(int factor, SDL return result; } -SDLImageShared::SDLImageShared(const SDLImageShared * from, int integerScaleFactor, EScalingAlgorithm algorithm) +std::shared_ptr SDLImageShared::createScaled(const SDLImageShared * from, int integerScaleFactor, EScalingAlgorithm algorithm) { + auto self = std::make_shared(nullptr); + static tbb::task_arena upscalingArena; - upscalingInProgress = true; + self->upscalingInProgress = true; auto scaler = std::make_shared(from->surf, Rect(from->margins, from->fullSize), true); - const auto & scalingTask = [this, algorithm, scaler]() + const auto & scalingTask = [self, algorithm, scaler]() { scaler->scaleSurfaceIntegerFactor(GH.screenHandler().getScalingFactor(), algorithm); - surf = scaler->acquireResultSurface(); - fullSize = scaler->getResultDimensions().dimensions(); - margins = scaler->getResultDimensions().topLeft(); - - upscalingInProgress = false; + self->surf = scaler->acquireResultSurface(); + self->fullSize = scaler->getResultDimensions().dimensions(); + self->margins = scaler->getResultDimensions().topLeft(); + self->upscalingInProgress = false; }; if(settings["video"]["asyncUpscaling"].Bool()) upscalingArena.enqueue(scalingTask); else scalingTask(); + + return self; } bool SDLImageShared::isLoading() const diff --git a/client/renderSDL/SDLImage.h b/client/renderSDL/SDLImage.h index 2ad465c67..bd81d01cf 100644 --- a/client/renderSDL/SDLImage.h +++ b/client/renderSDL/SDLImage.h @@ -49,10 +49,11 @@ public: SDLImageShared(const ImagePath & filename); //Create using existing surface, extraRef will increase refcount on SDL_Surface SDLImageShared(SDL_Surface * from); - /// Creates image at specified scaling factor from source image - SDLImageShared(const SDLImageShared * from, int integerScaleFactor, EScalingAlgorithm algorithm); ~SDLImageShared(); + /// Creates image at specified scaling factor from source image + static std::shared_ptr createScaled(const SDLImageShared * from, int integerScaleFactor, EScalingAlgorithm algorithm); + void scaledDraw(SDL_Surface * where, SDL_Palette * palette, const Point & scaling, const Point & dest, const Rect * src, const ColorRGBA & colorMultiplier, uint8_t alpha, EImageBlitMode mode) const override; void draw(SDL_Surface * where, SDL_Palette * palette, const Point & dest, const Rect * src, const ColorRGBA & colorMultiplier, uint8_t alpha, EImageBlitMode mode) const override; From 7d3e59d7d381ec8450016c19172737b98b57a263 Mon Sep 17 00:00:00 2001 From: Ivan Savenko Date: Wed, 26 Mar 2025 16:00:31 +0000 Subject: [PATCH 23/31] Do not track clipboard on mobile systems to avoid permissions prompt --- client/renderSDL/SDL_Extensions.cpp | 2 +- config/schemas/settings.json | 25 +++++++++++++++++-------- launcher/startGame/StartGameTab.cpp | 24 ++++++++++++++++++++---- 3 files changed, 38 insertions(+), 13 deletions(-) diff --git a/client/renderSDL/SDL_Extensions.cpp b/client/renderSDL/SDL_Extensions.cpp index 38818999f..0ecf60db0 100644 --- a/client/renderSDL/SDL_Extensions.cpp +++ b/client/renderSDL/SDL_Extensions.cpp @@ -85,7 +85,7 @@ SDL_Surface * CSDL_Ext::newSurface(const Point & dimensions, SDL_Surface * mod) std::string messagePattern = "Failed to create SDL Surface of size %d x %d, %d bpp. Reason: %s"; std::string message = boost::str(boost::format(messagePattern) % dimensions.x % dimensions.y % mod->format->BitsPerPixel % error); - handleFatalError(message, true); + throw std::runtime_error(message); } if (mod->format->palette) diff --git a/config/schemas/settings.json b/config/schemas/settings.json index 14043aff0..29d6b6a9a 100644 --- a/config/schemas/settings.json +++ b/config/schemas/settings.json @@ -649,14 +649,15 @@ "additionalProperties" : false, "required" : [ "setupCompleted", - "defaultRepositoryEnabled", - "defaultRepositoryURL", - "extraRepositoryURL", - "extraRepositoryEnabled", - "autoCheckRepositories", + "defaultRepositoryEnabled", + "defaultRepositoryURL", + "extraRepositoryURL", + "extraRepositoryEnabled", + "autoCheckRepositories", "ignoreSslErrors", - "updateOnStartup", - "updateConfigUrl" + "updateOnStartup", + "updateConfigUrl", + "trackClipboardState" ], "properties" : { "defaultRepositoryEnabled" : { @@ -694,7 +695,15 @@ "updateConfigUrl" : { "type" : "string", "default" : "https://raw.githubusercontent.com/vcmi/vcmi-updates/master/vcmi-updates.json" - } + }, + "trackClipboardState" : { + "type" : "boolean", + "default" : true, + "defaultIOS": false, + "defaultAndroid": false, + "defaultDesktop" : true + + }, } }, "lobby" : { diff --git a/launcher/startGame/StartGameTab.cpp b/launcher/startGame/StartGameTab.cpp index f68c6d6d6..83db61191 100644 --- a/launcher/startGame/StartGameTab.cpp +++ b/launcher/startGame/StartGameTab.cpp @@ -50,9 +50,11 @@ StartGameTab::StartGameTab(QWidget * parent) ui->buttonGameEditor->hide(); #endif - auto clipboard = QGuiApplication::clipboard(); - - connect(clipboard, SIGNAL(dataChanged()), this, SLOT(clipboardDataChanged())); + if (settings["launcher"]["trackClipboardState"].Bool()) + { + auto clipboard = QGuiApplication::clipboard(); + connect(clipboard, SIGNAL(dataChanged()), this, SLOT(clipboardDataChanged())); + } } void StartGameTab::clipboardDataChanged() @@ -103,7 +105,8 @@ void StartGameTab::refreshState() refreshPresets(); refreshMods(); - clipboardDataChanged(); + if (settings["launcher"]["trackClipboardState"].Bool()) + clipboardDataChanged(); } void StartGameTab::refreshPresets() @@ -405,9 +408,22 @@ void StartGameTab::on_buttonPresetExport_clicked() void StartGameTab::on_buttonPresetImport_clicked() { QString presetString = QGuiApplication::clipboard()->text(); + + if (!presetString.startsWith("{")) + { + MessageBoxCustom::information(this, tr("Preset import failed"), tr("Failed to import preset - data in clipboard does not looks like mod preset!")); + return; + } + QByteArray presetBytes(presetString.toUtf8()); JsonNode presetJson(reinterpret_cast(presetBytes.data()), presetBytes.size(), "imported preset"); + if (presetJson["name"].String().empty() || presetJson["mods"].Vector().empty()) + { + MessageBoxCustom::information(this, tr("Preset import failed"), tr("Failed to import preset - data in clipboard does not looks like mod preset!")); + return; + } + getMainWindow()->getModView()->importPreset(presetJson); getMainWindow()->switchToModsTab(); refreshPresets(); From 8771ecdf57054b32847f1d7c69b917b520dce9a5 Mon Sep 17 00:00:00 2001 From: Ivan Savenko Date: Wed, 26 Mar 2025 20:32:55 +0000 Subject: [PATCH 24/31] Workaround for crash due to static destruction order --- lib/CConfigHandler.cpp | 15 ++++++++++++++- lib/CConfigHandler.h | 5 +++++ 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/lib/CConfigHandler.cpp b/lib/CConfigHandler.cpp index c89c125ee..4fbfc57fe 100644 --- a/lib/CConfigHandler.cpp +++ b/lib/CConfigHandler.cpp @@ -55,6 +55,13 @@ SettingsStorage::SettingsStorage(): { } +SettingsStorage::~SettingsStorage() +{ + // hack for possible crash due to static destruction order (setting storage can be destroyed before all listeners have died) + for(SettingsListener * listener : listeners) + listener->terminate(); +} + void SettingsStorage::init(const std::string & dataFilename, const std::string & schema) { this->dataFilename = dataFilename; @@ -132,9 +139,15 @@ SettingsListener::SettingsListener(const SettingsListener &sl): parent.listeners.insert(this); } +void SettingsListener::terminate() +{ + wasTerminated = true; +} + SettingsListener::~SettingsListener() { - parent.listeners.erase(this); + if (!wasTerminated) + parent.listeners.erase(this); } void SettingsListener::nodeInvalidated(const std::vector &changedPath) diff --git a/lib/CConfigHandler.h b/lib/CConfigHandler.h index 915863a52..4822db41c 100644 --- a/lib/CConfigHandler.h +++ b/lib/CConfigHandler.h @@ -48,6 +48,7 @@ class DLL_LINKAGE SettingsStorage public: // Initialize config structure SettingsStorage(); + ~SettingsStorage(); void init(const std::string & dataFilename, const std::string & schema); // Get write access to config node at path @@ -73,11 +74,15 @@ class DLL_LINKAGE SettingsListener // Callback std::function callback; + // hack for crash due to static destruction order + bool wasTerminated = false; + SettingsListener(SettingsStorage & _parent, std::vector _path); // Executes callback if changedpath begins with path void nodeInvalidated(const std::vector & changedPath); + void terminate(); public: SettingsListener(const SettingsListener &sl); ~SettingsListener(); From 3dd15beede9645b263174968696a81ea12c57fbe Mon Sep 17 00:00:00 2001 From: Ivan Savenko Date: Sun, 6 Apr 2025 18:39:29 +0300 Subject: [PATCH 25/31] Fix rare crash if player changes starting hero in MP while another has town right-click popup open --- client/lobby/OptionsTab.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/client/lobby/OptionsTab.cpp b/client/lobby/OptionsTab.cpp index dd00f5442..64b2d6829 100644 --- a/client/lobby/OptionsTab.cpp +++ b/client/lobby/OptionsTab.cpp @@ -68,13 +68,14 @@ void OptionsTab::recreate() entries.clear(); humanPlayers = 0; + for (auto tooltipWindow : GH.windows().findWindows()) + tooltipWindow->close(); + for (auto heroOverview : GH.windows().findWindows()) heroOverview->close(); for (auto selectionWindow : GH.windows().findWindows()) - { selectionWindow->reopen(); - } OBJECT_CONSTRUCTION; for(auto & pInfo : SEL->getStartInfo()->playerInfos) From 6c1cb3ac54364036e6757c6899672614df7be6b6 Mon Sep 17 00:00:00 2001 From: Ivan Savenko Date: Sun, 6 Apr 2025 18:39:53 +0300 Subject: [PATCH 26/31] Workaround / debug info for crash on failure to render ttf text --- client/renderSDL/CTrueTypeFont.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/client/renderSDL/CTrueTypeFont.cpp b/client/renderSDL/CTrueTypeFont.cpp index 245697058..a44bd8c56 100644 --- a/client/renderSDL/CTrueTypeFont.cpp +++ b/client/renderSDL/CTrueTypeFont.cpp @@ -147,7 +147,8 @@ void CTrueTypeFont::renderTextImpl(SDL_Surface * surface, const std::string & da else rendered = TTF_RenderUTF8_Solid(font.get(), data.c_str(), CSDL_Ext::toSDL(color)); - assert(rendered); + if (!rendered) + throw std::runtime_error("Failed to render text '" + data + "'. Reason: '" + TTF_GetError() + "'"); CSDL_Ext::blitSurface(rendered, surface, pos); SDL_FreeSurface(rendered); From 4555b2d22842c4140a280eeac94c7f2d0003e5ef Mon Sep 17 00:00:00 2001 From: Ivan Savenko Date: Sun, 6 Apr 2025 18:40:27 +0300 Subject: [PATCH 27/31] Increase system RAM for xbrz2 auto-activation to 4Gb due to crashes on Android --- client/renderSDL/ScreenHandler.cpp | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/client/renderSDL/ScreenHandler.cpp b/client/renderSDL/ScreenHandler.cpp index deada10e1..b94085bdb 100644 --- a/client/renderSDL/ScreenHandler.cpp +++ b/client/renderSDL/ScreenHandler.cpp @@ -368,17 +368,13 @@ EUpscalingFilter ScreenHandler::loadUpscalingFilter() const float scaleY = static_cast(outputResolution.x) / logicalResolution.x; float scaling = std::min(scaleX, scaleY); int systemMemoryMb = SDL_GetSystemRAM(); - bool is32Bit = sizeof(void*) == 4; if (scaling <= 1.001f) return EUpscalingFilter::NONE; // running at original resolution or even lower than that - no need for xbrz - if (systemMemoryMb < 2048) + if (systemMemoryMb <= 4096) return EUpscalingFilter::NONE; // xbrz2 may use ~1.0 - 1.5 Gb of RAM and has notable CPU cost - avoid on low-spec hardware - if (is32Bit) - return EUpscalingFilter::NONE; // to be safe, avoid large numbers of memory (re)allocations when address space is small - // Only using xbrz2 for autoselection. // Higher options may have high system requirements and should be only selected explicitly by player return EUpscalingFilter::XBRZ_2; From 87caec6be1133565b6668b30df00f6b9b1cf66cb Mon Sep 17 00:00:00 2001 From: Ivan Savenko Date: Sun, 6 Apr 2025 18:41:20 +0300 Subject: [PATCH 28/31] Check for presence of builtin ttf fonts & report on start to avoid strange crashes on font loading --- clientapp/EntryPoint.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/clientapp/EntryPoint.cpp b/clientapp/EntryPoint.cpp index a0cbd7b16..ee38300aa 100644 --- a/clientapp/EntryPoint.cpp +++ b/clientapp/EntryPoint.cpp @@ -297,9 +297,10 @@ int main(int argc, char * argv[]) testFile("DATA/HELP.TXT", "VCMI requires Heroes III: Shadow of Death or Heroes III: Complete data files to run!"); testFile("DATA/TENTCOLR.TXT", "Heroes III: Restoration of Erathia (including HD Edition) data files are not supported!"); - testFile("MODS/VCMI/MOD.JSON", "VCMI installation is corrupted! Built-in mod was not found!"); - testFile("DATA/PLAYERS.PAL", "Heroes III data files (Data/H3Bitmap.lod) are incomplete or corruped! Please reinstall them."); - testFile("SPRITES/DEFAULT.DEF", "Heroes III data files (Data/H3Sprite.lod) are incomplete or corruped! Please reinstall them."); + testFile("MODS/VCMI/MOD.JSON", "VCMI installation is corrupted!\nBuilt-in mod was not found!"); + testFile("DATA/NOTOSERIF-MEDIUM.TTF", "VCMI installation is corrupted!\nBuilt-in font was not found!\nManually deleting '" + VCMIDirs::get().userDataPath().string() + "/Mods/VCMI' directory (if it exists)\nor clearing app data and reimporting Heroes III files may fix this problem."); + testFile("DATA/PLAYERS.PAL", "Heroes III data files (Data/H3Bitmap.lod) are incomplete or corruped!\n Please reinstall them."); + testFile("SPRITES/DEFAULT.DEF", "Heroes III data files (Data/H3Sprite.lod) are incomplete or corruped!\n Please reinstall them."); srand ( (unsigned int)time(nullptr) ); From cbfaefd805c3002d1e885b4c15e84b0f5c47efd5 Mon Sep 17 00:00:00 2001 From: Ivan Savenko Date: Sun, 6 Apr 2025 18:43:55 +0300 Subject: [PATCH 29/31] Fix rare crash if player selects maximum movement speed and moves hero across event that grants enough XP to level up --- server/NetPacksServer.cpp | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/server/NetPacksServer.cpp b/server/NetPacksServer.cpp index ee23bcc9e..67666349d 100644 --- a/server/NetPacksServer.cpp +++ b/server/NetPacksServer.cpp @@ -70,6 +70,15 @@ void ApplyGhNetPackVisitor::visitMoveHero(MoveHero & pack) result = false; return; } + + // player got some query he has to reply to first for example, from triggered event + // ignore remaining path (if any), but handle this as success - since at least part of path was legal & was applied + auto query = gh.queries->topQuery(pack.player); + if (query && query->blocksPack(&pack)) + { + result = true; + return; + } } result = true; From dcbf12ef268ac64c7b25e4d6b88827d89f5ec736 Mon Sep 17 00:00:00 2001 From: Ivan Savenko Date: Sun, 6 Apr 2025 18:44:44 +0300 Subject: [PATCH 30/31] Fix rare crash on merging two stacks in town garrison with stack artifacts equipped --- lib/networkPacks/NetPacksLib.cpp | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/lib/networkPacks/NetPacksLib.cpp b/lib/networkPacks/NetPacksLib.cpp index 44ce5dc63..7d67dfe27 100644 --- a/lib/networkPacks/NetPacksLib.cpp +++ b/lib/networkPacks/NetPacksLib.cpp @@ -1639,13 +1639,19 @@ void RebalanceStacks::applyGs(CGameState *gs) { if(auto dstArt = dstStack->getArt(ArtifactPosition::CREATURE_SLOT)) { - auto dstSlot = ArtifactUtils::getArtBackpackPosition(srcHero, dstArt->getTypeId()); - if(srcHero && dstSlot != ArtifactPosition::PRE_FIRST) + bool artifactIsLost = true; + + if(srcHero) { - gs->map->moveArtifactInstance(*dstStack, ArtifactPosition::CREATURE_SLOT, *srcHero, dstSlot); + auto dstSlot = ArtifactUtils::getArtBackpackPosition(srcHero, dstArt->getTypeId()); + if (dstSlot != ArtifactPosition::PRE_FIRST) + { + gs->map->moveArtifactInstance(*dstStack, ArtifactPosition::CREATURE_SLOT, *srcHero, dstSlot); + artifactIsLost = false; + } } - //else - artifact can be lost :/ - else + + if (artifactIsLost) { BulkEraseArtifacts ea; ea.artHolder = dstHero->id; From 49e215a7c3e3a48bf0c3ab6e7b2eb2a333087e6b Mon Sep 17 00:00:00 2001 From: Ivan Savenko Date: Tue, 1 Apr 2025 17:58:21 +0300 Subject: [PATCH 31/31] Bump fuzzylite submodule to latest commit --- AI/CMakeLists.txt | 11 +++-------- AI/FuzzyLite | 2 +- 2 files changed, 4 insertions(+), 9 deletions(-) diff --git a/AI/CMakeLists.txt b/AI/CMakeLists.txt index 733ac5fba..796b2b10d 100644 --- a/AI/CMakeLists.txt +++ b/AI/CMakeLists.txt @@ -30,14 +30,9 @@ if(NOT fuzzylite_FOUND) if(ANDROID) set(FL_BACKTRACE OFF CACHE BOOL "" FORCE) endif() - #It is for compiling FuzzyLite, it will not compile without it on GCC - if("x${CMAKE_CXX_COMPILER_FRONTEND_VARIANT}" STREQUAL "xGNU" OR ${CMAKE_CXX_COMPILER_ID} STREQUAL "GNU") - add_compile_options(-Wno-error=deprecated-declarations) - endif() - add_subdirectory(FuzzyLite/fuzzylite EXCLUDE_FROM_ALL) - set_property(TARGET fl-static PROPERTY CXX_STANDARD 14) # doesn't compile under 17 due to using removed symbol(s) - add_library(fuzzylite::fuzzylite ALIAS fl-static) - target_include_directories(fl-static PUBLIC ${CMAKE_HOME_DIRECTORY}/AI/FuzzyLite/fuzzylite) + + add_subdirectory(FuzzyLite EXCLUDE_FROM_ALL) + add_library(fuzzylite::fuzzylite ALIAS staticTarget) endif() ####################################### diff --git a/AI/FuzzyLite b/AI/FuzzyLite index 7aee562d6..13b3122f5 160000 --- a/AI/FuzzyLite +++ b/AI/FuzzyLite @@ -1 +1 @@ -Subproject commit 7aee562d6ca17f3cf42588ffb5116e03017c3c50 +Subproject commit 13b3122f5c353c0389ed4e66041d548c44ec9df6