mirror of
https://github.com/dcs-retribution/dcs-retribution.git
synced 2025-11-10 15:41:24 +00:00
Add major/minor versioning of the campaign schema.
Many of the schema version increases are just to add new features that don't render old campaigns obsolete. Convert the version number to a major/minor format so we can detect the difference between changes that render old campaigns obsolete (major versions) and new features that will not work on older builds of Liberation (minor versions).
This commit is contained in:
parent
f63d218aae
commit
8076206a90
@ -53,4 +53,4 @@ VERSION = _build_version_string()
|
|||||||
#: by a blue circular TriggerZone, campaign creation will fail. Blue circular
|
#: by a blue circular TriggerZone, campaign creation will fail. Blue circular
|
||||||
#: TriggerZones must also have their first property's value field define the type of
|
#: TriggerZones must also have their first property's value field define the type of
|
||||||
#: objective (a valid value for a building TGO category, from `game.db.PRICES`).
|
#: objective (a valid value for a building TGO category, from `game.db.PRICES`).
|
||||||
CAMPAIGN_FORMAT_VERSION = 4
|
CAMPAIGN_FORMAT_VERSION = (4, 0)
|
||||||
|
|||||||
@ -4,15 +4,16 @@ import json
|
|||||||
import logging
|
import logging
|
||||||
from dataclasses import dataclass
|
from dataclasses import dataclass
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from typing import Any, Dict, List, Optional, Union
|
from typing import Any, Dict, List, Union, Tuple
|
||||||
|
|
||||||
|
import packaging.version
|
||||||
from PySide2 import QtGui
|
from PySide2 import QtGui
|
||||||
from PySide2.QtCore import QItemSelectionModel
|
from PySide2.QtCore import QItemSelectionModel
|
||||||
from PySide2.QtGui import QStandardItem, QStandardItemModel
|
from PySide2.QtGui import QStandardItem, QStandardItemModel
|
||||||
from PySide2.QtWidgets import QAbstractItemView, QListView
|
from PySide2.QtWidgets import QAbstractItemView, QListView
|
||||||
|
|
||||||
import qt_ui.uiconstants as CONST
|
import qt_ui.uiconstants as CONST
|
||||||
from game.theater import ConflictTheater, MizCampaignLoader
|
from game.theater import ConflictTheater
|
||||||
from game.version import CAMPAIGN_FORMAT_VERSION
|
from game.version import CAMPAIGN_FORMAT_VERSION
|
||||||
|
|
||||||
PERF_FRIENDLY = 0
|
PERF_FRIENDLY = 0
|
||||||
@ -31,7 +32,7 @@ class Campaign:
|
|||||||
#: The revision of the campaign format the campaign was built for. We do not attempt
|
#: The revision of the campaign format the campaign was built for. We do not attempt
|
||||||
#: to migrate old campaigns, but this is used to show a warning in the UI when
|
#: to migrate old campaigns, but this is used to show a warning in the UI when
|
||||||
#: selecting a campaign that is not up to date.
|
#: selecting a campaign that is not up to date.
|
||||||
version: int
|
version: Tuple[int, int]
|
||||||
|
|
||||||
recommended_player_faction: str
|
recommended_player_faction: str
|
||||||
recommended_enemy_faction: str
|
recommended_enemy_faction: str
|
||||||
@ -45,12 +46,20 @@ class Campaign:
|
|||||||
data = json.load(campaign_file)
|
data = json.load(campaign_file)
|
||||||
|
|
||||||
sanitized_theater = data["theater"].replace(" ", "")
|
sanitized_theater = data["theater"].replace(" ", "")
|
||||||
|
version_field = data.get("version", "0")
|
||||||
|
try:
|
||||||
|
version = packaging.version.parse(version_field)
|
||||||
|
except TypeError:
|
||||||
|
logging.warning(
|
||||||
|
f"Non-string campaign version in {path}. Parse may be incorrect."
|
||||||
|
)
|
||||||
|
version = packaging.version.parse(str(version_field))
|
||||||
return cls(
|
return cls(
|
||||||
data["name"],
|
data["name"],
|
||||||
f"Terrain_{sanitized_theater}",
|
f"Terrain_{sanitized_theater}",
|
||||||
data.get("authors", "???"),
|
data.get("authors", "???"),
|
||||||
data.get("description", ""),
|
data.get("description", ""),
|
||||||
data.get("version", 0),
|
(version.major, version.minor),
|
||||||
data.get("recommended_player_faction", "USA 2005"),
|
data.get("recommended_player_faction", "USA 2005"),
|
||||||
data.get("recommended_enemy_faction", "Russia 1990"),
|
data.get("recommended_enemy_faction", "Russia 1990"),
|
||||||
data.get("performance", 0),
|
data.get("performance", 0),
|
||||||
@ -63,8 +72,15 @@ class Campaign:
|
|||||||
|
|
||||||
@property
|
@property
|
||||||
def is_out_of_date(self) -> bool:
|
def is_out_of_date(self) -> bool:
|
||||||
"""Returns True if this campaign is not up to date with the latest format."""
|
"""Returns True if this campaign is not up to date with the latest format.
|
||||||
return self.version < CAMPAIGN_FORMAT_VERSION
|
|
||||||
|
This is more permissive than is_from_future, which is sensitive to minor version
|
||||||
|
bumps (the old game definitely doesn't support the minor features added in the
|
||||||
|
new version, and the campaign may require them. However, the minor version only
|
||||||
|
indicates *optional* new features, so we do not need to mark out of date
|
||||||
|
campaigns as incompatible if they are within the same major version.
|
||||||
|
"""
|
||||||
|
return self.version[0] < CAMPAIGN_FORMAT_VERSION[0]
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def is_from_future(self) -> bool:
|
def is_from_future(self) -> bool:
|
||||||
|
|||||||
@ -13,12 +13,14 @@ MarkupSafe==1.1.1
|
|||||||
mypy==0.812
|
mypy==0.812
|
||||||
mypy-extensions==0.4.3
|
mypy-extensions==0.4.3
|
||||||
nodeenv==1.5.0
|
nodeenv==1.5.0
|
||||||
|
packaging==20.9
|
||||||
pathspec==0.8.1
|
pathspec==0.8.1
|
||||||
pefile==2019.4.18
|
pefile==2019.4.18
|
||||||
Pillow==8.1.1
|
Pillow==8.1.1
|
||||||
pre-commit==2.10.1
|
pre-commit==2.10.1
|
||||||
pyinstaller==4.3
|
pyinstaller==4.3
|
||||||
pyinstaller-hooks-contrib==2021.1
|
pyinstaller-hooks-contrib==2021.1
|
||||||
|
pyparsing==2.4.7
|
||||||
pyproj==3.0.1
|
pyproj==3.0.1
|
||||||
PySide2==5.15.2
|
PySide2==5.15.2
|
||||||
pywin32-ctypes==0.2.0
|
pywin32-ctypes==0.2.0
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user