diff --git a/changelog.md b/changelog.md index d138bf04..8cb857c9 100644 --- a/changelog.md +++ b/changelog.md @@ -23,6 +23,7 @@ Saves from 4.x are not compatible with 5.0. ## Fixes * **[Campaign]** Naval control points will no longer claim ground objectives during campaign generation and prevent them from spawning. +* **[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. * **[UI]** Selling of Units is now visible again in the UI dialog and shows the correct amount of sold units # 4.1.1 diff --git a/game/dcs/aircrafttype.py b/game/dcs/aircrafttype.py index 1ce958ca..b54d9bc0 100644 --- a/game/dcs/aircrafttype.py +++ b/game/dcs/aircrafttype.py @@ -325,7 +325,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 b2a155ad..e756f043 100644 --- a/game/debriefing.py +++ b/game/debriefing.py @@ -386,7 +386,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 3c070ba9..87b440d6 100644 --- a/game/operation/operation.py +++ b/game/operation/operation.py @@ -65,7 +65,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 87d8a841..d89d875d 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 09cfd011..67609d11 100644 --- a/qt_ui/main.py +++ b/qt_ui/main.py @@ -64,7 +64,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 8d2c1fd2..1fae35bc 100644 --- a/qt_ui/windows/newgame/QCampaignList.py +++ b/qt_ui/windows/newgame/QCampaignList.py @@ -43,7 +43,7 @@ class Campaign: @classmethod def from_file(cls, path: Path) -> Campaign: - with path.open() as campaign_file: + with path.open(encoding="utf-8") as campaign_file: if path.suffix == ".yaml": data = yaml.safe_load(campaign_file) else: