Add support for zipped data and resource packs

This commit is contained in:
Andrew Miner
2025-10-14 09:36:54 -06:00
parent b83ed4241d
commit cf21103d3e
12 changed files with 164 additions and 54 deletions
+7 -2
View File
@@ -3,10 +3,12 @@ from mcpacker.format.report.mineralreport import MineralReport
from mcpacker.format.report.mobspawnreport import MobSpawnReport
from mcpacker.model.modpack import ModPack
from mcpacker.write.compositewriter import CompositeWriter
from mcpacker.write.datapack.metawriter import MetaWriter
from mcpacker.write.datapack.metawriter import DataPackMetaWriter
from mcpacker.write.datapack.writer import DataPackWriter
from mcpacker.write.incontrol.spawnerwriter import SpawnerWriter
from mcpacker.write.report.writer import ReportWriter
from mcpacker.write.resourcepack.metawriter import ResourcePackMetaWriter
from mcpacker.write.resourcepack.writer import ResourcePackWriter
from mcpacker.write.staticwriter import StaticWriter
from pathlib import Path
@@ -57,6 +59,9 @@ class Runner:
StaticWriter(self.pack, self.outputDir),
SpawnerWriter(self.pack, self.outputDir),
DataPackWriter(self.pack, self.outputDir, [
MetaWriter(self.pack, self.outputDir),
DataPackMetaWriter(self.pack, self.outputDir, 48),
]),
ResourcePackWriter(self.pack, self.outputDir, [
ResourcePackMetaWriter(self.pack, self.outputDir, 34),
]),
]).write()
+5 -19
View File
@@ -1,25 +1,11 @@
from mcpacker.model.modpack import ModPack
from mcpacker.write.writer import Writer
from mcpacker.write.packmetawriter import PackMetaWriter
from pathlib import Path
import mcpacker.json as json
# Class ############################################################################################
class MetaWriter(Writer):
class DataPackMetaWriter(PackMetaWriter):
def __init__(self, pack:ModPack, outputDir:Path):
super().__init__(pack, outputDir)
def doWrite(self):
path = self.locator.dataPack() / "pack.mcmeta"
self.resetOutputFile(path)
with path.open("w") as file:
file.write(json.dumps({
"pack": {
"pack_format": 48,
"description": f"auto-generated overrides for {self.pack.name}"
}
}, indent=" "))
@property
def packRoot(self) -> Path:
return self.locator.dataPack()
@@ -0,0 +1,7 @@
import mcpacker.write.datapack.metawriter
# Tests ############################################################################################
def test_syntax():
pass
+8 -30
View File
@@ -1,37 +1,15 @@
from collections.abc import Iterable
from mcpacker.model.modpack import ModPack
from mcpacker.write.compositewriter import CompositeWriter
from mcpacker.write.writer import Writer
from mcpacker.write.locator import Locator
from mcpacker.write.zipwriter import ZipWriter
from pathlib import Path
from tempfile import TemporaryDirectory
from zipfile import ZipFile
from zipfile import ZIP_DEFLATED
import mcpacker.json as json
import os
# Class ############################################################################################
class DataPackWriter(CompositeWriter):
class DataPackWriter(ZipWriter):
def doWrite(self):
outputDir = self.locator.outputDir
archivePath = self.locator.dataPacks() / f"{self.pack.name}.jar"
@property
def archiveFile(self) -> Path:
return self.locator.dataPacks() / f"{self.pack.name}.jar"
with TemporaryDirectory() as buildDir:
self.locator.outputDir = Path(buildDir)
for writer in self._writers:
writer.locator.outputDir = self.locator.outputDir
writer.write()
dataPackPath = self.locator.dataPack()
archivePath.parent.mkdir(exist_ok=True, parents=True)
with ZipFile(archivePath, "w", ZIP_DEFLATED) as zipFile:
for path in dataPackPath.rglob("*"):
if not path.is_file(): continue
zipFile.write(path, path.relative_to(dataPackPath.parent))
self.locator.outputDir = outputDir
@property
def gatherFromDir(self) -> Path:
return self.locator.dataPack()
+7
View File
@@ -0,0 +1,7 @@
import mcpacker.write.datapack.writer
# Tests ############################################################################################
def test_syntax():
pass
+21 -3
View File
@@ -1,8 +1,6 @@
from mcpacker.model.modpack import ModPack
from pathlib import Path
from typing import Protocol
from typing import TypeVar
from typing import TypeAlias
from tempfile import TemporaryDirectory
# Class ############################################################################################
@@ -25,6 +23,26 @@ class Locator:
self.pack = pack
self.outputDir = outputDir
def inTempDir(self):
locator = self
class Context:
def __init__(self):
self.tempDir = TemporaryDirectory()
self.originalDir:Path|None = None
def __enter__(self):
self.originalDir = locator.outputDir
locator.outputDir = Path(self.tempDir.name)
return self
def __exit__(self, errorType, errorValue, trackback):
locator.outputDir = self.originalDir
self.tempDir.cleanup()
return False
return Context()
def biomeModifiers(self, modName:str|None=None, dataPackName:str|None=None) -> Path:
return self.dataPackMod(modName, dataPackName) / "neoforge" / "biome_modifier"
+30
View File
@@ -0,0 +1,30 @@
from mcpacker.model.modpack import ModPack
from mcpacker.write.writer import Writer
from pathlib import Path
import mcpacker.json as json
# Class ############################################################################################
class PackMetaWriter(Writer):
def __init__(self, pack:ModPack, outputDir:Path, formatVersion:int):
super().__init__(pack, outputDir)
self.formatVersion = formatVersion
@property
def packRoot(self) -> Path:
raise NotImplementedError()
def doWrite(self):
path = self.packRoot / "pack.mcmeta"
self.resetOutputFile(path)
with path.open("w") as file:
file.write(json.dumps({
"pack": {
"pack_format": self.formatVersion,
"description": f"auto-generated overrides for {self.pack.name}"
}
}, indent=" "))
+11
View File
@@ -0,0 +1,11 @@
from mcpacker.write.packmetawriter import PackMetaWriter
from pathlib import Path
# Class ############################################################################################
class ResourcePackMetaWriter(PackMetaWriter):
@property
def packRoot(self) -> Path:
return self.locator.resourcePack()
@@ -0,0 +1,7 @@
import mcpacker.write.resourcepack.metawriter
# Tests ############################################################################################
def test_syntax():
pass
+15
View File
@@ -0,0 +1,15 @@
from mcpacker.write.zipwriter import ZipWriter
from pathlib import Path
# Class ############################################################################################
class ResourcePackWriter(ZipWriter):
@property
def archiveFile(self) -> Path:
return self.locator.resourcePacks() / f"{self.pack.name}.jar"
@property
def gatherFromDir(self) -> Path:
return self.locator.resourcePack()
@@ -0,0 +1,7 @@
import mcpacker.write.resourcepack.writer
# Tests ############################################################################################
def test_syntax():
pass
+39
View File
@@ -0,0 +1,39 @@
from collections.abc import Iterable
from mcpacker.model.modpack import ModPack
from mcpacker.write.compositewriter import CompositeWriter
from mcpacker.write.writer import Writer
from mcpacker.write.locator import Locator
from pathlib import Path
from zipfile import ZipFile
from zipfile import ZIP_DEFLATED
import mcpacker.json as json
import os
# Class ############################################################################################
class ZipWriter(CompositeWriter):
@property
def archiveFile(self) -> Path:
raise NotImplementedError()
@property
def gatherFromDir(self) -> Path:
raise NotImplementedError()
def doWrite(self):
archiveFile = self.archiveFile # grab before locator moves
with self.locator.inTempDir():
for writer in self._writers:
writer.locator.outputDir = self.locator.outputDir
writer.write()
archiveFile.parent.mkdir(exist_ok=True, parents=True)
with ZipFile(archiveFile, "w", ZIP_DEFLATED) as zipFile:
for path in self.gatherFromDir.rglob("*"):
if not path.is_file(): continue
zipFile.write(path, path.relative_to(self.gatherFromDir.parent))