Repository navigation
PackMerger v1.1.0
Operator-experience release. Correctness of the merge engine is settled from
1.0.x; this one focuses on observability, validation, admin workflow, and
external integrations.
Added
- Per-file merge provenance log. Every output path now records which pack
wrote it, every contributor (in merge order), the merge strategy used, and
whether it was a true merge vs single-contributor pass-through. Persisted
tooutput/<merged-pack>.zip.provenance.jsonso restarts don't blank the
state. Exposed viaPackMerger.getLastMergeProvenance(). /pm inspectcommand family./pm inspect— top-line summary of the last merge/pm inspect <pack>— per-pack detail (files won + files overridden)/pm inspect collisions— list of every path touched by 2+ packs/pm inspect export— writes the full plain-text report to
output/last-merge-report.txt
- Plugin API + Bukkit events. New
sh.pcx.packmerger.api.PackMergerApi
interface accessible viaplugin.getApi()with accessors for the current
pack URL, SHA-1, last merge time, and provenance, plustriggerMerge().
Six new Bukkit events fire at their natural call sites:
PackMergeStartedEvent,PackMergedEvent,PackUploadedEvent,
PackUploadFailedEvent,PackValidationFailedEvent,
PackSentToPlayerEvent. Seedocs/api-example.javafor a sample listener.
Tagged@Experimentaluntil 1.2 to allow iteration in 1.1.x. pack_formatvs server-version guardrail. PackValidator now warns
when the merged pack'spack_formatdoesn't match the running Minecraft
version. Honorssupported_formatsranges (int, array, and
{min_inclusive, max_inclusive}object shapes). Config key:
validation.pack-format-check(warn|error|off).- Rollback on validation failure. Merges now write to
<output>.new.zipfirst; validation runs against the temp, and the
previous output is kept live if validation errors trip. Fires
PackValidationFailedEventwithrolledBack=trueso listeners can
page someone. Config:validation.rollback-on-errors(defaulttrue)
andvalidation.fail-on-warnings(defaultfalse). - Orphan asset detection. New
OrphanDetectorscans the merged output
for unreferenced.pngand.oggfiles and reports them as warnings.
Reference discovery covers models, item definitions, blockstates, atlases
(with directory glob expansion), font providers, andsounds.json. Config:
validation.detect-orphans(defaulttrue) and
validation.orphan-report-limit(default20). /pm priorityin-game reordering. No more YAML edit + reload:
/pm priority list|up|down|top|bottom|set <pack> <n>. Persists via
plugin.saveConfig()and triggers an immediate re-merge. Note: Bukkit's
config writer doesn't preserve comments on save — documented tradeoff.- Profiles / presets. New
profiles:+active-profile:config keys
let operators flip between whole pack compositions atomically via
/pm profile switch <name>. When profiles aren't in use (or the section
is absent), PackMerger falls back to root-level keys — fully backwards-
compatible with 1.0.x configs. - Remote pack sources (HTTP). New
remote-packs:config section lets
admins declare pack aliases whose contents come from an HTTP(S) URL.
Packs are downloaded intopacks/.remote-cache/<alias>.zipand
recognized in the merge pipeline by their alias. ETag / Last-Modified
caching, env-var substitution for secrets, bearer + basic auth, HTTPS-
required-by-default. New/pm fetch [alias]command. Zero new runtime
deps — uses the JDK'sHttpClient. - S3-compatible upload provider. New
provider: "s3"setting with
support for AWS S3, Cloudflare R2, and Backblaze B2 (all via the S3
API). Bundled MinIO SDK, fully shaded + relocated. Supports
content-addressed or stable key strategies, public-read or presigned
(private) ACLs, and a retention policy for content-addressed buckets.
Jar grows from ~270 KB to ~13 MB as a result; document in release notes. - Two new
PluginLoggercategories:validation()(light purple) and
remote()(blue). - Runtime dependency loader. New
PackMergerLoaderdownloads MinIO and
its transitive closure from Maven Central on first enable, verifies each
artifact against a build-time SHA-256, and loads them through an isolated
classloader. Cached inplugins/PackMerger/libraries/for subsequent
starts. Drops the shipped jar from ~13 MB to ~360 KB. - Update check. On enable, the plugin polls
versions.jsonin the repo
to see if a newer release is available and surfaces it in the console +
as a chat notice to admins on join. Advisory only — no auto-download.
Config:update-check.enabled/update-check.url. - Actual Folia support. Swapped every
BukkitSchedulercall to the
right Folia scheduler (AsyncScheduler for periodic async work,
GlobalRegionScheduler / entity scheduler where a specific thread matters).
PackDistributor.sendPacknow self-schedules on the player's region so
callers don't have to know about threading.plugin.ymldeclares
folia-supported: true. Paper behavior is unchanged — the scheduler
APIs we use exist on both.
Changed
PackMergeEngine.merge()now accepts an optional target-file override
(merge(File)), used byPackMergerfor the write-to-temp-then-validate
flow. Backwards-compatible:merge()keeps writing to
plugin.getOutputFile().- Merge provenance moved from a single fixed-name file
(output/.merge-provenance.json) to a sidecar keyed by output name
(output/<merged-pack>.zip.provenance.json). Lets rollback rename the
zip and sidecar together. FileWatchernow explicitly ignores dot-prefixed entries so the
.remote-cache/subdirectory can't trigger cascading merges.
Dependencies
- MinIO Java SDK 8.5.10 + its transitive closure (OkHttp, Okio, Kotlin
stdlib, Jackson, BouncyCastle, Guava, Xerial Snappy) is now downloaded
at runtime by the loader rather than shaded into the plugin jar.
Manifest and SHA-256 digests live inRuntimeDependencies.java
(auto-generated at build time from theruntimeDownloadGradle
configuration).
Full Changelog: v1.0.5...v1.1.0