Skip to content

Commit

Permalink
Unit Group password support.
Browse files Browse the repository at this point in the history
  • Loading branch information
332fg-raven committed Feb 9, 2024
1 parent 4966f2e commit 07fe67e
Show file tree
Hide file tree
Showing 2 changed files with 57 additions and 0 deletions.
24 changes: 24 additions & 0 deletions dcs/unitgroup.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@
import dcs.condition as condition
import dcs.task as task
import dcs.mapping as mapping
import hashlib
import base64
import string

PointT = TypeVar("PointT", bound=StaticPoint)
UnitT = TypeVar("UnitT", bound=Unit)
Expand All @@ -44,6 +47,7 @@ def __init__(self, _id: int, name: Optional[str] = None) -> None:
self.units: List[UnitT] = []
self.points: List[PointT] = []
self.name: str = name if name is not None else ""
self.password: Optional[str] = None

def __str__(self):
return "Group: " + self.name
Expand All @@ -52,6 +56,7 @@ def load_from_dict(self, d: Dict[str, Any], terrain: Terrain) -> None:
self.hidden = d.get("hidden", False)
self.hidden_on_planner = d.get("hiddenOnPlanner", False)
self.hidden_on_mfd = d.get("hiddenOnMFD", False)
self.password = d.get("password", None)

def add_unit(self, unit: UnitT):
self.units.append(unit)
Expand Down Expand Up @@ -223,8 +228,27 @@ def dict(self):
for point in self.points:
d["route"]["points"][i] = point.dict()
i += 1
if self.password is not None:
d["password"] = self.password
return d

def set_password(self, password: str) -> None:
# see https://www.reddit.com/r/hoggit/comments/uf2sh0/psa_creating_the_new_slot_passwords_outside_of_dcs/

SALT_SIZE = 11
DIGEST_SIZE = 32

key = ''.join(random.sample(string.digits + string.ascii_letters, SALT_SIZE))
p_hash = hashlib.blake2b(key=key.encode(), digest_size=DIGEST_SIZE)
p_hash.update(password.encode())
b64hash = base64.encodebytes(p_hash.digest()).decode()

# remove '=\n' at the end.
self.password = key + ":" + b64hash[:len(b64hash) - 2]

def set_no_password(self) -> None:
self.password = None


class MovingGroup(Generic[UnitT], Group[UnitT, MovingPoint]):
def __init__(self, _id, name=None, start_time=0):
Expand Down
33 changes: 33 additions & 0 deletions tests/test_mission.py
Original file line number Diff line number Diff line change
Expand Up @@ -1238,6 +1238,39 @@ def validate_formation(m: Mission, m2: Mission, position: FormationPosition, exp
validate_formation(m, m2, FormationPosition.Back, Expend.Auto, WeaponType.IronBombs, False)
validate_formation(m, m2, FormationPosition.Right, Expend.Auto, WeaponType.Auto, False)

def test_unit_group_password(self) -> None:
m = dcs.mission.Mission()

kobuleti = m.terrain.airports["Kobuleti"]
kobuleti.set_blue()
batumi = m.terrain.airports["Batumi"]
batumi.set_blue()

country_name = "USA"
coal_name = str(Coalition.Blue.value)
country = m.coalition[coal_name].country(country_name)

flying_group = m.flight_group_from_airport(country, "Airgroup", dcs.planes.A_10C, kobuleti,
start_type=dcs.mission.StartType.Warm)
flying_group.units[0].set_client()
flying_group.set_password('testpassword')
self.assertIsNotNone(flying_group.password)
m.save('missions/saved.flying-group-with-password.miz')

m2 = Mission()
m2.load_file('missions/saved.flying-group-with-password.miz')
m2_flying_group = m2.coalition[coal_name].country(country_name).plane_group[0]
self.assertIsNotNone(m2_flying_group.password)
self.assertEqual(m2_flying_group.password, flying_group.password)

m2_flying_group.set_no_password()
m2.save('missions/saved.flying-group-with-no-password')

m3 = Mission()
m3.load_file('missions/saved.flying-group-with-no-password')
m3_flying_group = m3.coalition[coal_name].country(country_name).plane_group[0]
self.assertIsNone(m3_flying_group.password)

def test_geffect(self) -> None:
m = Mission()
m.load_file("tests/missions/g-effect-uncheked.miz")
Expand Down

0 comments on commit 07fe67e

Please sign in to comment.