From 40b147148bcdbad2720c142d672401d3cead689c Mon Sep 17 00:00:00 2001 From: RndName Date: Thu, 12 Aug 2021 23:32:09 +0200 Subject: [PATCH] Open all files with utf-8 encoding - will not be used for binary read/writes (rb,wb)! - prevents a bug where units with special characters in the unit name can not be tracked anymore as there will be a name mismatch due to wrong encoding (cherry-picked from b5b0d82) --- changelog.md | 1 + game/dcs/aircrafttype.py | 2 +- game/dcs/groundunittype.py | 2 +- game/debriefing.py | 2 +- game/operation/operation.py | 2 +- game/version.py | 2 +- qt_ui/main.py | 3 ++- qt_ui/windows/QWaitingForMissionResultWindow.py | 2 +- qt_ui/windows/newgame/QCampaignList.py | 2 +- 9 files changed, 10 insertions(+), 8 deletions(-) diff --git a/changelog.md b/changelog.md index 263b7ddd..8f7a768a 100644 --- a/changelog.md +++ b/changelog.md @@ -10,6 +10,7 @@ Saves from 4.1.1 are compatible with 4.1.2. ## Fixes * **[UI]** Selling of Units is now visible again in the UI dialog and shows the correct amount of sold units +* **[Mission Generation]** Mission results and other files will now be opened with enforced utf-8 encoding to prevent an issue where destroyed ground units were untracked because of special characters in their names. # 4.1.1 diff --git a/game/dcs/aircrafttype.py b/game/dcs/aircrafttype.py index eb66287c..677d3264 100644 --- a/game/dcs/aircrafttype.py +++ b/game/dcs/aircrafttype.py @@ -288,7 +288,7 @@ class AircraftType(UnitType[Type[FlyingType]]): logging.warning(f"No data for {aircraft.id}; it will not be available") return - with data_path.open() as data_file: + with data_path.open(encoding="utf-8") as data_file: data = yaml.safe_load(data_file) try: diff --git a/game/dcs/groundunittype.py b/game/dcs/groundunittype.py index c22d8a21..db93aa49 100644 --- a/game/dcs/groundunittype.py +++ b/game/dcs/groundunittype.py @@ -67,7 +67,7 @@ class GroundUnitType(UnitType[Type[VehicleType]]): logging.warning(f"No data for {vehicle.id}; it will not be available") return - with data_path.open() as data_file: + with data_path.open(encoding="utf-8") as data_file: data = yaml.safe_load(data_file) try: diff --git a/game/debriefing.py b/game/debriefing.py index e4e3bf0f..8f1c0055 100644 --- a/game/debriefing.py +++ b/game/debriefing.py @@ -389,7 +389,7 @@ class PollDebriefingFileThread(threading.Thread): os.path.isfile("state.json") and os.path.getmtime("state.json") > last_modified ): - with open("state.json", "r") as json_file: + with open("state.json", "r", encoding="utf-8") as json_file: json_data = json.load(json_file) debriefing = Debriefing(json_data, self.game, self.unit_map) self.callback(debriefing) diff --git a/game/operation/operation.py b/game/operation/operation.py index da3f1c4a..530d2a05 100644 --- a/game/operation/operation.py +++ b/game/operation/operation.py @@ -63,7 +63,7 @@ class Operation: @classmethod def prepare(cls, game: Game) -> None: - with open("resources/default_options.lua", "r") as f: + with open("resources/default_options.lua", "r", encoding="utf-8") as f: options_dict = loads(f.read())["options"] cls._set_mission(Mission(game.theater.terrain)) cls.game = game diff --git a/game/version.py b/game/version.py index 333fcd75..c56828c3 100644 --- a/game/version.py +++ b/game/version.py @@ -12,7 +12,7 @@ def _build_version_string() -> str: ] build_number_path = Path("resources/buildnumber") if build_number_path.exists(): - with build_number_path.open("r") as build_number_file: + with build_number_path.open("r", encoding="utf-8") as build_number_file: components.append(build_number_file.readline()) if not Path("resources/final").exists(): diff --git a/qt_ui/main.py b/qt_ui/main.py index d1aacdff..b4d5eff7 100644 --- a/qt_ui/main.py +++ b/qt_ui/main.py @@ -68,7 +68,8 @@ def run_ui(game: Optional[Game]) -> None: # init the theme and load the stylesheet based on the theme index liberation_theme.init() with open( - "./resources/stylesheets/" + liberation_theme.get_theme_css_file() + "./resources/stylesheets/" + liberation_theme.get_theme_css_file(), + encoding="utf-8", ) as stylesheet: logging.info("Loading stylesheet: %s", liberation_theme.get_theme_css_file()) app.setStyleSheet(stylesheet.read()) diff --git a/qt_ui/windows/QWaitingForMissionResultWindow.py b/qt_ui/windows/QWaitingForMissionResultWindow.py index f4ce44fb..0361fcaa 100644 --- a/qt_ui/windows/QWaitingForMissionResultWindow.py +++ b/qt_ui/windows/QWaitingForMissionResultWindow.py @@ -228,7 +228,7 @@ class QWaitingForMissionResultWindow(QDialog): ) print(file) try: - with open(file[0], "r") as json_file: + with open(file[0], "r", encoding="utf-8") as json_file: json_data = json.load(json_file) json_data["mission_ended"] = True debriefing = Debriefing(json_data, self.game, self.unit_map) diff --git a/qt_ui/windows/newgame/QCampaignList.py b/qt_ui/windows/newgame/QCampaignList.py index 1d74e64a..1c5e241c 100644 --- a/qt_ui/windows/newgame/QCampaignList.py +++ b/qt_ui/windows/newgame/QCampaignList.py @@ -42,7 +42,7 @@ class Campaign: @classmethod def from_json(cls, path: Path) -> Campaign: - with path.open() as campaign_file: + with path.open(encoding="utf-8") as campaign_file: data = json.load(campaign_file) sanitized_theater = data["theater"].replace(" ", "")