Developer Guide

Comprehensive guide for developers extending or integrating with the zCrates plugin.

Table of Contents

  • Architecture Overview

  • Project Structure

  • Core Systems

  • Extension Points

  • JavaScript API

  • Database Schema

  • Security Model

  • Best Practices


Architecture Overview

zCrates follows a layered architecture with clear separation between API, implementation, and extensions:

┌─────────────────────────────────────────────────────┐
│                   Extensions Layer                   │
│  (Hooks: ItemsAdder, MythicMobs, PlaceholderAPI)    │
└─────────────────────────────────────────────────────┘

┌─────────────────────────────────────────────────────┐
│                  Business Logic Layer                │
│         (Managers, Commands, Listeners)              │
└─────────────────────────────────────────────────────┘

┌─────────────────────────────────────────────────────┐
│                   Registry Layer                     │
│   (Crates, Animations, Algorithms, Providers)       │
└─────────────────────────────────────────────────────┘

┌─────────────────────────────────────────────────────┐
│                   Data Layer                         │
│         (Storage, Repositories, DTOs)                │
└─────────────────────────────────────────────────────┘

┌─────────────────────────────────────────────────────┐
│                   API Layer                          │
│    (Interfaces, Events, Models, Services)            │
└─────────────────────────────────────────────────────┘

Key Design Patterns

  1. Registry Pattern - Centralized component registration and retrieval

  2. Manager Pattern - Business logic orchestration via Bukkit ServicesManager

  3. Wrapper Pattern - Safe object exposure to JavaScript sandboxes

  4. Factory Pattern - Display creation via CrateDisplayFactory

  5. Polymorphic Serialization - Type-safe YAML deserialization with Structura

  6. Repository Pattern - Database access abstraction via Sarah ORM


Project Structure


Core Systems

1. Registry System

The registry system provides centralized component registration and retrieval using Guava's ClassToInstanceMap.

Registry Interface

FileBasedRegistry

Abstract base class for file-loaded registries with folder hierarchy support:

Available Registries

Registry
ID Type
Item Type
Source

AnimationsRegistry

String

Animation

animations/*.js

RandomAlgorithmsRegistry

String

RandomAlgorithm

algorithms/*.js

CratesRegistry

String

Crate

crates/*.yml

ItemsProvidersRegistry

String

ItemsProvider

Runtime registration

HooksRegistry

String

Hook

Classpath scanning

CrateDisplayFactoriesRegistry

DisplayType

CrateDisplayFactory

Runtime registration

Usage Example:


2. Manager Layer

Managers orchestrate business logic and are registered via Bukkit's ServicesManager.

CratesManager

Handles crate opening, animations, and placed crates.

Key Methods:

Internal State Management:

UsersManager

Handles player data and key management with async database operations.

Key Methods:

Caching Strategy:


3. Script Engine System

ZScriptEngine provides secure, sandboxed JavaScript execution using Mozilla Rhino.

Security Features

Blocked Methods:

  • getClass(), class

  • notify(), notifyAll(), wait()

  • clone(), finalize(), hashCode()

Allowed JavaScript:

  • ES6 features (arrow functions, let/const, template literals)

  • Standard objects (Array, Object, Math, JSON, Date, RegExp)

  • Context objects (player, inventory, crate, rewards, history)

Script Execution Methods

Usage Example:


4. Animation System

Animations provide frame-by-frame visual effects during crate opening.

Animation Model

AnimationExecutor

Manages animation timing and phase transitions:

Execution Flow:

  1. Initialize phase 0

  2. Call onStart(context)

  3. Every interval ticks: call onTick(context, tickData)

  4. After duration ms: call onComplete(context) and move to next phase

  5. After all phases: call animation's onComplete(context)

AnimationContext

Provides safe access to runtime objects:

TickData

Per-tick information passed to onTick():

JavaScript API:


5. Algorithm System

Algorithms provide customizable reward selection logic.

RandomAlgorithm Model

AlgorithmContext

Runtime context passed to selector function:

JavaScript API:


6. Reward System

Rewards define what players receive from crates.

Reward Interface

Implementations

Type
Class
Fields
Behavior

ITEM

ItemReward

ItemStackWrapper item

Give single item

ITEMS

ItemsListReward

List<ItemStackWrapper> items

Give multiple items

COMMAND

CommandReward

String command

Execute command

COMMANDS

CommandsListReward

List<String> commands

Execute multiple commands

YAML Configuration:

ItemStackWrapper System

Supports both vanilla materials and custom item plugins:

Available Delegates:

  • ItemsAdder - ItemsAdder custom items

  • Oraxen - Oraxen custom items

  • Nexo - Nexo custom items

  • zItems - zItems custom items (via ItemsAdder provider)


7. Key System

Keys control crate access and come in two types.

Key Interface

VirtualKey

Database-stored key balance:

Storage:

  • Table: user_keys

  • Columns: user_id, key_name, amount

  • Managed by UsersManager

PhysicKey

Physical item in inventory:

Matching:

  • Uses PDC (PersistentDataContainer) for identification

  • Key: zcrates:key_name

  • Value: key name string


8. Condition System

Conditions gate crate opening with arbitrary requirements.

OpenCondition Interface

Built-in Conditions

Type
Class
Configuration
Behavior

PERMISSION

PermissionCondition

permission: node

Check permission

COOLDOWN

CooldownCondition

cooldown: 60000

Rate-limit (ms)

PLACEHOLDER

PlaceholderCondition

placeholder, comparison, result

PlaceholderAPI check

YAML Configuration:


9. Display System

Displays represent crates in the game world.

CrateDisplay Interface

CrateDisplayFactory Interface

Built-in Display Types

DisplayType
Factory
Display
Value Type

BLOCK

BlockCrateDisplayFactory

BlockCrateDisplay

Material name

ENTITY

EntityCrateDisplayFactory

EntityCrateDisplay

EntityType name

MYTHIC_MOB

MythicMobCrateDisplayFactory

MythicMobCrateDisplay

MythicMob ID

ITEMS_ADDER

IACrateDisplayFactory

IACrateDisplay

ItemsAdder furniture ID

NEXO

NexoCrateDisplayFactory

NexoCrateDisplay

Nexo furniture ID

ORAXEN

OraxenCrateDisplayFactory

OraxenCrateDisplay

Oraxen furniture ID

PlacedCrate Record

Persistence:

  • Stored in Chunk PDC via PlacedCrateDataType

  • Loads on chunk load, unloads on chunk unload

  • Managed by CratesManager


10. Event System

All events extend CrateEvent which provides player and crate context.

Event Types

Event
Cancellable
When Fired
Purpose

CratePreOpenEvent

Yes

Before opening

Prevent opening

CrateOpenEvent

No

After key consumed

Track opening

CrateRerollEvent

Yes

Before reroll

Prevent reroll

RewardGeneratedEvent

No

Reward selected

Track selection

RewardGivenEvent

No

Reward given

Track distribution

Usage Example:


Extension Points

1. Creating Custom Hooks

Hooks integrate with external plugins using the @AutoHook annotation.

Step 1: Create Hook Class

Step 2: Create build.gradle.kts (if in hooks/ directory)

Step 3: Hook Auto-Discovery

Hooks are automatically discovered if:

  • Located in package fr.traqueur.crates or subpackages

  • Annotated with @AutoHook("PluginName")

  • Target plugin is loaded

2. Creating Custom Conditions

Step 1: Implement OpenCondition

Step 2: Register Polymorphic Type

Step 3: Use in YAML

3. Creating Custom ItemsProvider

Usage in YAML:

4. Creating Custom CrateDisplayFactory

Registration:


JavaScript API

Animation Context API

Algorithm Context API

ArrayHelper Utility


Database Schema

Tables

users

user_keys

crate_openings


Security Model

JavaScript Sandbox

Blocked Java Access:

  • No java.* package access

  • No Packages global

  • No reflection APIs

Blocked Methods:

  • getClass(), class

  • notify(), notifyAll(), wait()

  • clone(), finalize(), hashCode()

Allowed:

  • Standard JavaScript objects (Array, Object, Math, JSON, Date, RegExp)

  • ES6 features (arrow functions, let/const, template literals)

  • Context objects (player, inventory, crate, rewards, history)

  • Utility: ArrayHelper

Isolation:

  • Each script execution uses isolated scope

  • Null parent scopes prevent prototype pollution

  • Interpreter mode (no bytecode generation)

Inventory Security

Slot Authorization:

  • Only authorized slots can be manipulated during animation

  • Prevents inventory manipulation exploits

Data Security

PDC Storage:

  • Chunk data persisted in PersistentDataContainer

  • Type-safe serialization via PlacedCrateDataType

User Cache:

  • Proper lifecycle (load on join, save on quit)

  • Concurrent-safe operations

Database:

  • Async operations via CompletableFuture

  • Connection pooling

  • Prepared statements (SQL injection protection)


Best Practices

1. Event Handling

2. Registry Access

3. Async Operations

4. Custom Animations

5. Custom Algorithms

6. Error Handling


Support

For questions, issues, or contributions:

  • Discord: [https://discord.gg/PTSYTC53d3]

  • GitHub: [https://github.com/GroupeZ-dev/zCrates]

  • Documentation: See USER_GUIDE.md

Last updated