{"id":50490729,"url":"https://github.com/escapepz/container_authority_framework","last_synced_at":"2026-06-02T02:30:56.797Z","repository":{"id":354417539,"uuid":"1157967980","full_name":"escapepz/container_authority_framework","owner":"escapepz","description":"A modding framework that lets creators build custom storage rules and container interactions.","archived":false,"fork":false,"pushed_at":"2026-04-28T12:34:35.000Z","size":1206,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"master","last_synced_at":"2026-04-28T14:32:19.870Z","etag":null,"topics":["lua","projectzomboid","zomboid"],"latest_commit_sha":null,"homepage":"https://steamcommunity.com/sharedfiles/filedetails/?id=3672918592","language":"Lua","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/escapepz.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-02-14T15:35:43.000Z","updated_at":"2026-04-28T12:34:40.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/escapepz/container_authority_framework","commit_stats":null,"previous_names":["escapepz/container_authority_framework"],"tags_count":4,"template":false,"template_full_name":null,"purl":"pkg:github/escapepz/container_authority_framework","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/escapepz%2Fcontainer_authority_framework","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/escapepz%2Fcontainer_authority_framework/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/escapepz%2Fcontainer_authority_framework/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/escapepz%2Fcontainer_authority_framework/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/escapepz","download_url":"https://codeload.github.com/escapepz/container_authority_framework/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/escapepz%2Fcontainer_authority_framework/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33803734,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-02T02:00:07.132Z","response_time":109,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["lua","projectzomboid","zomboid"],"created_at":"2026-06-02T02:30:55.332Z","updated_at":"2026-06-02T02:30:56.791Z","avatar_url":"https://github.com/escapepz.png","language":"Lua","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Container Authority Framework\n\nA modding framework for Project Zomboid that intercepts and controls item transfers between containers through a flexible three-phase event pipeline.\n\n## Overview\n\nContainer Authority Framework (CAF) provides API hooks to validate, audit, and react to container interactions. It enables complex storage systems without modifying the game's core container logic.\n\n**Core Use Cases:**\n\n- Rank-locked armories (faction-based access control)\n- One-way donation boxes (deposit-only containers)\n- Daily withdrawal caps on shared supplies\n- Theft detection and alerting systems\n- Realism penalties (cold hands, clumsiness, stress)\n- Economy systems with custom transfer rules\n\n## How It Works\n\nCAF intercepts item transfers through a three-phase pipeline:\n\n### 1. Validation Phase\n\n- Triggered **before** the transfer occurs\n- Allows rules to **block** unauthorized transfers\n- Use case: permission checks, rank requirements, weight limits\n\n### 2. Pre-Transfer Phase\n\n- Triggered **after validation**, **before** execution\n- Allows rules to audit or modify the context\n- Use case: deducting currency, logging intent, applying penalties\n\n### 3. Post-Transfer Phase\n\n- Triggered **after** the transfer completes\n- Allows rules to react with side effects\n- Use case: applying stress, attracting zombies, updating metadata\n\n## Installation\n\n**Requirements:**\n\n- Project Zomboid Build 42.13.1+\n- `zul` mod - [Zomboid Unified Logging](https://steamcommunity.com/sharedfiles/filedetails/?id=3653948326)\n- `pz_lua_commons` mod - [PZ Lua Commons](https://steamcommunity.com/sharedfiles/filedetails/?id=3672788969)\n\n**Add to `mod.info`**\n\n```\nrequire=\\container_authority_framework\n```\n\n## Usage for Modders\n\n### Registering a Rule\n\n```lua\nlocal caf = require(\"container_authority_framework\")\n\n-- Validation rule (blocking)\ncaf:registerRule(\"validation\", \"my_mod_rank_check\", function(ctx)\n    local player = ctx.character\n    local requiredRank = 5\n\n    if player:getAdmin() == false and getPlayerRank(player) \u003c requiredRank then\n        ctx.flags.rejected = true\n        ctx.flags.reason = \"Insufficient rank\"\n    end\nend, 10) -- priority 10\n\n-- Pre-Transfer rule (logging)\ncaf:registerRule(\"pre\", \"my_mod_audit_log\", function(ctx)\n    print(\"Player \" .. ctx.character:getUsername() .. \" transferring \" .. ctx.item:getType())\nend, 20)\n\n-- Post-Transfer rule (side effects)\ncaf:registerRule(\"post\", \"my_mod_stress_penalty\", function(ctx)\n    if ctx.result then\n        ctx.character:getStats():setStress(ctx.character:getStats():getStress() + 10)\n    end\nend, 30)\n```\n\n### Context Object\n\nAll callbacks receive a context table with:\n\n```lua\nctx = {\n    character = IsoPlayer,      -- The player performing the transfer\n    item = InventoryItem,       -- The item being transferred\n    src = ItemContainer,        -- Source container\n    dest = ItemContainer,       -- Destination container\n    dropSquare = IsoGridSquare, -- Optional drop location\n    result = any,               -- Post-transfer only: transfer result\n\n    flags = {\n        rejected = boolean,     -- Set to true to block transfer\n        reason = string,        -- Rejection reason (for logging)\n        adminOverride = boolean -- Admin bypass flag\n    },\n\n    metadata = {}               -- Custom data passed between phases\n}\n```\n\n### Priority System\n\nLower priority values execute first. Use this to control rule order:\n\n- Validation rules: 0-50 (permission checks first)\n- Pre-Transfer rules: 50-100 (logging/auditing)\n- Post-Transfer rules: 100+ (side effects last)\n\n## Configuration\n\nServer admins can configure listener limits via sandbox options:\n\n- `ValidationEventListenersMax` (default: 25)\n- `PreTransferEventListenersMax` (default: 50)\n- `PostTransferEventListenersMax` (default: 100)\n\nThese limits prevent performance degradation if too many rules are registered.\n\n## Example Mods Built with CAF\n\n- **JASM**: Just Another Shop Mod\n\n## Architecture\n\n- **Event-driven**: Rules register as listeners to three distinct events\n- **Reusable context**: Single reusable context object to minimize GC pressure\n- **Recursion guard**: Prevents infinite loops from nested transfer calls\n- **Error handling**: Critical errors logged without crashing the server\n- **Sandbox integration**: Admin-configurable limits per event phase\n\n## Performance\n\n- Context object reused across transfers (minimal allocations)\n- Direct EventManager integration (no closure overhead)\n- Configurable listener limits prevent bottlenecks\n- Efficient flag/metadata clearing between transfers\n\n## License\n\nSee LICENSE file for details.\n\n## Author\n\nescapepz\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fescapepz%2Fcontainer_authority_framework","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fescapepz%2Fcontainer_authority_framework","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fescapepz%2Fcontainer_authority_framework/lists"}