Skip to content

ImperaZim/LibAssets

Repository files navigation

LibAssets 1.0.0-dev PocketMine-MP 5.0.0+ PHP 8.2+ License

LibAssets

Asset manifests, Bedrock resource-pack validation and packaging helpers for PocketMine-MP plugins and EasyLibrary packages.

What It Is

LibAssets is the official EasyLibrary asset helper package. It is designed for plugins that ship or prepare resource packs, generated files and other versioned assets that need predictable hashes and validation before a server uses them.

The first 3.0-dev version focuses on practical local workflows:

  • scan a directory and create a SHA-256 asset manifest;
  • compare an existing manifest against files on disk;
  • parse and validate Bedrock resource-pack manifest.json files;
  • validate resource-pack directories and ZIP files;
  • build resource-pack ZIPs with byte size and SHA-256 metadata;
  • register resource-pack definitions and inspect whether they are active, prepared, pending, disabled or invalid;
  • prepare packs into a controlled plugin workspace instead of mixing source, build output and cache files;
  • expose a small downloader adapter contract so LibHttp can provide remote bytes while LibAssets still owns local validation;
  • keep the API offline-first so it can be used safely during startup and tests.

Requirements

  • PHP 8.2+
  • PocketMine-MP API 5.0.0+
  • LibCommons 1.0.0-dev+

LibCommons provides the shared pure helpers used internally for SHA-256, JSON, path and filesystem operations. It does not make LibAssets depend on network, UI, command or world-editing code.

Installation

Standalone plugin:

  1. Download LibCommons-1.0.0-dev.phar and LibAssets-1.0.0-dev.phar.
  2. Put both files in plugins/.
  3. Restart the server.

EasyLibrary package:

/easylibrary packages install libcommons development confirm
/easylibrary packages install libassets development confirm

When dependency resolution is available, installing libassets should stage libcommons as its required package dependency. Installing both explicitly is still safe and easier to reason about during development smoke tests.

Then restart and confirm:

/easylibrary packages doctor

Asset Manifest

use imperazim\assets\AssetManifest;

$manifest = AssetManifest::fromDirectory($plugin->getDataFolder() . 'assets');

foreach ($manifest->getFiles() as $file) {
    $plugin->getLogger()->info($file->getPath() . ' ' . $file->getSha256());
}

$report = $manifest->validateAgainstDirectory($plugin->getDataFolder() . 'assets');
if (!$report->isValid()) {
    foreach ($report->getProblems() as $problem) {
        $plugin->getLogger()->warning($problem);
    }
}

The manifest stores relative paths, file sizes and SHA-256 hashes. It rejects path traversal and keeps paths normalized with /.

Resource Pack Validation

use imperazim\assets\resource\ResourcePackValidator;

$report = ResourcePackValidator::validateDirectory($plugin->getDataFolder() . 'pack');

if (!$report->isValid()) {
    foreach ($report->getErrors() as $error) {
        $plugin->getLogger()->error($error);
    }
}

LibAssets validates the real Bedrock resource-pack contract it can safely check from PHP: manifest.json, format_version, header UUID/version/name and resource modules.

Build A Resource Pack ZIP

use imperazim\assets\resource\ResourcePackBuilder;

$result = ResourcePackBuilder::buildZip(
    $plugin->getDataFolder() . 'pack',
    $plugin->getDataFolder() . 'dist/server-pack.zip'
);

$plugin->getLogger()->info('Pack SHA-256: ' . $result->getSha256());

The builder validates the source directory first and writes a deterministic ZIP with normalized paths. The returned result includes path, size, hash and parsed manifest metadata.

Controlled Resource Pack Workflow

Use ResourcePackWorkflow when a plugin owns one or more resource-pack sources and wants a predictable staging area under its data folder.

use imperazim\assets\resource\ResourcePackDefinition;
use imperazim\assets\resource\ResourcePackWorkflow;
use imperazim\assets\resource\ResourcePackWorkflowStatus;

$workflow = new ResourcePackWorkflow($plugin->getDataFolder() . 'resource-packs');
$workflow->register(new ResourcePackDefinition(
    id: 'lobby',
    sourceDirectory: $plugin->getFile() . 'resources/lobby-pack',
    targetArchiveName: 'lobby-pack.zip',
    enabled: true
));

$report = $workflow->inspect('lobby');
if ($report->getStatus() === ResourcePackWorkflowStatus::PENDING) {
    $result = $workflow->prepare('lobby');
    $plugin->getLogger()->info('Prepared pack: ' . $result->getBuildResult()?->getPath());
}

The workflow creates these directories inside the workspace:

  • prepared/<id>/ contains the copied, validated pack source;
  • dist/<archive> contains the generated ZIP/pack archive;
  • manifests/<id>.json stores the generated metadata and source fingerprint;
  • cache/<archive> is reserved for optional remote downloads.

Status meanings:

  • active: enabled, prepared and current;
  • prepared: prepared and current, but disabled in this workflow definition;
  • pending: source is valid, but the prepared output is missing or stale;
  • disabled: valid source, disabled and not prepared yet;
  • invalid: source, manifest, metadata or generated archive has a clear error.

This workflow does not force PocketMine-MP to register packs at runtime. It keeps the risky part explicit: your plugin decides when and how to pass the prepared archive to the server or a deployment/CDN layer.

Optional Remote Cache

LibAssets does not perform HTTP requests itself. Instead, it exposes AssetDownloader, a tiny adapter contract that LibHttp or another transport can implement.

use imperazim\assets\remote\AssetDownloader;
use imperazim\assets\remote\AssetDownloadResult;
use imperazim\assets\resource\ResourcePackDefinition;
use imperazim\assets\resource\ResourcePackWorkflow;

$workflow = new ResourcePackWorkflow($plugin->getDataFolder() . 'resource-packs');
$workflow->register(ResourcePackDefinition::fromCdn(
    id: 'seasonal',
    sourceDirectory: $plugin->getDataFolder() . 'seasonal-pack-source',
    baseUrl: 'https://cdn.example.com/packs',
    targetArchiveName: 'seasonal-pack.zip',
    expectedSha256: '0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef'
));

$download = $workflow->downloadRemoteArchive('seasonal', new class implements AssetDownloader {
    public function download(string $url, string $targetPath, ?string $expectedSha256 = null): AssetDownloadResult {
        // Call LibHttp here, write the response body to $targetPath,
        // then return AssetDownloadResult::fromPath($targetPath).
        return AssetDownloadResult::fromPath($targetPath);
    }
});

downloadRemoteArchive() validates the downloaded ZIP and checks the expected SHA-256 when one is configured. That gives plugins a clean split:

  • LibHttp: request, retry, timeout, response handling;
  • LibAssets: cache path, checksum, Bedrock pack validation and local status.

Examples

The PHP examples are included in the repository lint step so documentation code stays syntactically valid as the API evolves.

Package Contract

LibAssets ships both:

  • plugin.yml for normal PMMP plugin installation;
  • package.yml for EasyLibrary package manager installation.

Runtime dependencies:

  • standalone PHAR: depend: [LibCommons];
  • EasyLibrary package: dependencies.required: [libcommons];
  • Composer development/autoload: imperazim/libcommons from the development branch.

Release assets include:

  • LibAssets-1.0.0-dev.phar;
  • LibAssets-1.0.0-dev.easylib.zip;
  • package.yml;
  • checksums.txt.

Compatibility

  • PHP 8.2+
  • PocketMine-MP API 5.0.0
  • LibCommons 1.0.0-dev+
  • EasyLibrary 3.0.0-dev package manager

This package intentionally does not own network transport. Remote fetching belongs in LibHttp or a plugin adapter; LibAssets handles local validation, cache paths and packaging after bytes exist on disk.

About

Asset manifest and resource-pack packaging helpers for PocketMine-MP plugins.

Topics

Resources

License

Code of conduct

Contributing

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Packages

 
 
 

Contributors

Languages