From ada30e4c7406f3d3b957e98d79874a41cde5075e Mon Sep 17 00:00:00 2001 From: evie Date: Sat, 13 Jun 2026 00:24:49 -0400 Subject: [PATCH 1/2] Add password protection option to patch files --- __init__.py | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/__init__.py b/__init__.py index ee37c8f..87f94eb 100644 --- a/__init__.py +++ b/__init__.py @@ -76,6 +76,7 @@ from .utils.slim import is_slim_version, load_package, get_package_toc, slim_init from .utils.hashing import murmur64_hash +from .utils.hashing import murmur32_hash from .utils.memoryStream import MemoryStream from .utils.logger import PrettyPrint from .utils.constants import * @@ -122,6 +123,8 @@ Global_previousRandomHash = 0 +Global_password = 0 + #endregion #region Common Hashes & Lookups @@ -538,7 +541,10 @@ def Serialize(self, TocFile: MemoryStream, Index=0): self.Unknown1 = TocFile.uint64(self.Unknown1) self.Unknown2 = TocFile.uint64(self.Unknown2) self.TocDataSize = TocFile.uint32(len(self.TocData)) - self.StreamSize = TocFile.uint32(len(self.StreamData)) + if TocFile.IsWriting(): + self.StreamSize = TocFile.uint32(len(self.StreamData) ^ Global_password) + else: + self.StreamSize = TocFile.uint32(len(self.StreamData)) ^ Global_password self.GpuResourceSize = TocFile.uint32(len(self.GpuData)) self.Unknown3 = TocFile.uint32(self.Unknown3) self.Unknown4 = TocFile.uint32(self.Unknown4) @@ -4453,6 +4459,13 @@ def ChangeSearchString(self, context): for item in list_data: item.item_visible = not all([flag == 0 for flag in flt_flags]) break + +def ChangeUnitPassword(self, context): + global Global_password + if self.PatchPassword == "": + Global_password = 0 + if self.PatchPassword != "": + Global_password = murmur32_hash(self.PatchPassword.encode()) class Hd2ToolPanelSettings(PropertyGroup): # Patches @@ -4488,6 +4501,7 @@ class Hd2ToolPanelSettings(PropertyGroup): # Tools EnableTools : BoolProperty(name="Special Tools", description = "Enable advanced SDK Tools", default = False) + PatchPassword : StringProperty(name="Patch Password", description="Password to use when saving/loading patch files", default="", update=ChangeUnitPassword) UnloadEmptyArchives : BoolProperty(name="Unload Empty Archives", description="Unload Archives that do not Contain any Textures, Materials, or Meshes", default = True) DeleteOnLoadArchive : BoolProperty(name="Nuke Files on Archive Load", description="Delete all Textures, Materials, and Meshes in project when selecting a new archive", default = False) UnloadPatches : BoolProperty(name="Unload Previous Patches", description="Unload Previous Patches when bulk loading") @@ -4865,6 +4879,7 @@ def draw(self, context): row = settings_box.row(); box = row.box(); row = box.grid_flow(columns=1) #row.label() row.label(text="WARNING! Developer Tools, Please Know What You Are Doing!") + row.prop(scene.Hd2ToolPanelSettings, "PatchPassword") row.prop(scene.Hd2ToolPanelSettings, "UnloadEmptyArchives") row.prop(scene.Hd2ToolPanelSettings, "UnloadPatches") row.prop(scene.Hd2ToolPanelSettings, "LoadFoundArchives") From 43d468e3d855c5062ffe7524d288ee671c5bfaac Mon Sep 17 00:00:00 2001 From: evie Date: Sat, 13 Jun 2026 00:27:57 -0400 Subject: [PATCH 2/2] Change function name --- __init__.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/__init__.py b/__init__.py index 87f94eb..363bb36 100644 --- a/__init__.py +++ b/__init__.py @@ -4460,7 +4460,7 @@ def ChangeSearchString(self, context): item.item_visible = not all([flag == 0 for flag in flt_flags]) break -def ChangeUnitPassword(self, context): +def ChangePatchPassword(self, context): global Global_password if self.PatchPassword == "": Global_password = 0 @@ -4501,7 +4501,7 @@ class Hd2ToolPanelSettings(PropertyGroup): # Tools EnableTools : BoolProperty(name="Special Tools", description = "Enable advanced SDK Tools", default = False) - PatchPassword : StringProperty(name="Patch Password", description="Password to use when saving/loading patch files", default="", update=ChangeUnitPassword) + PatchPassword : StringProperty(name="Patch Password", description="Password to use when saving/loading patch files", default="", update=ChangePatchPassword) UnloadEmptyArchives : BoolProperty(name="Unload Empty Archives", description="Unload Archives that do not Contain any Textures, Materials, or Meshes", default = True) DeleteOnLoadArchive : BoolProperty(name="Nuke Files on Archive Load", description="Delete all Textures, Materials, and Meshes in project when selecting a new archive", default = False) UnloadPatches : BoolProperty(name="Unload Previous Patches", description="Unload Previous Patches when bulk loading")