# Developer Overview Painting-API is a platform-neutral interface for reading the active pack registry, reacting to player pack status, and triggering resends. The same API works against the Paper and Velocity implementations — only the Bukkit / Velocity event-bus glue differs. --- ## Maven / Gradle The Painting-API artifact is hosted on JitPack. Add it as a `compileOnly` / `provided` dependency so Painting is not shaded into your plugin. **Repository:** *Gradle (Kotlin DSL):* ```kotlin repositories { maven("https://jitpack.io") } ``` *Maven:* ```xml <repository> <id>jitpack.io</id> <url>https://jitpack.io</url> </repository> ``` **Dependency:** *Gradle (Kotlin DSL):* ```kotlin compileOnly("com.github.Lodestones:Painting-API:1.0.0") ``` *Maven:* ```xml <dependency> <groupId>com.github.Lodestones</groupId> <artifactId>Painting-API</artifactId> <version>1.0.0</version> <scope>provided</scope> </dependency> ``` Add `Painting` as a dependency in your `paper-plugin.yml` (Paper) or to your Velocity plugin metadata. ```yaml dependencies: server: Painting: required: true load: BEFORE ``` --- ## Accessing the API The API is accessed through the static `PaintingAPI` class. The instance is registered by the platform plugin during enable. ```java import gg.lode.paintingapi.PaintingAPI; import gg.lode.paintingapi.IPaintingAPI; if (!PaintingAPI.isAvailable()) return; IPaintingAPI api = PaintingAPI.get(); ``` Calling `PaintingAPI.get()` before the plugin has initialized throws `IllegalStateException`. Use `PaintingAPI.isAvailable()` to gate the call when load order is not guaranteed. --- ## Common Operations ### List all configured packs ```java for (PackDefinition def : PaintingAPI.get().getPackDefinitions()) { plugin.getLogger().info("Pack " + def.name() + " has " + def.variants().size() + " variants."); } ``` ### Look up a pack by name ```java PackDefinition base = PaintingAPI.get().getPackDefinition("base"); if (base == null) return; PackVariant variant = base.pickFor(player.getProtocolVersion().getProtocol()); ``` ### Check if a server requires a pack ```java boolean required = PaintingAPI.get().isRequiredForServer("survival-1"); ``` ### Force a resend ```java // Resend to a single player (Paper or Velocity). PaintingAPI.get().resendPacksToPlayer(player.getUniqueId()); // Resend to everyone online. PaintingAPI.get().resendPacksToOnlinePlayers(); ``` ### Reload the registry ```java PaintingAPI.get().reload(); ``` --- ## Events Painting fires three event types through each platform's native event bus. All three implement the platform-neutral interfaces in `gg.lode.paintingapi.api.event` so consumers can write platform-agnostic listener interfaces if desired. ### PackStatusEvent Fired whenever the player's resource pack state changes (`ACCEPTED`, `DECLINED`, `DOWNLOADED`, `LOADED`, `FAILED`, `DISCARDED`, `INVALID_URL`). *Paper:* ```java @EventHandler public void onPackStatus(PaperPackStatusEvent event) { if (event.getStatus() == PackStatus.LOADED) { // Pack applied successfully } } ``` *Velocity:* ```java @Subscribe public void onPackStatus(VelocityPackStatusEvent event) { if (event.getStatus() == PackStatus.FAILED && event.isRequiredForServer()) { // Failed and going to be kicked unless retry succeeds } } ``` ### PackPreSendEvent (Paper only — cancellable) Fired before each pack offer is sent to a player. Cancelling skips that specific pack. ```java @EventHandler public void onPreSend(PaperPackPreSendEvent event) { if (event.getPackName().equals("staff-overlay") && !isStaff(event.getPlayerId())) { event.setCancelled(true); } } ``` ### PackRegistryReloadEvent (Paper only) Fired after `/painting reload` once the pack and server registries have been re-read. ```java @EventHandler public void onReload(PaperPackRegistryReloadEvent event) { plugin.getLogger().info("Painting reloaded: " + event.getDefinitionCount() + " packs, " + event.getServerEntryCount() + " server entries."); } ``` --- ## Pack Status Values | Status | Meaning | |---|---| | `ACCEPTED` | Player clicked Yes on the prompt. Download starts. | | `DOWNLOADED` | Pack download finished. | | `LOADED` | Pack applied to the client. | | `DECLINED` | Player clicked No. | | `FAILED` | Download failed. | | `DISCARDED` | Pack was unloaded (replaced or removed). | | `INVALID_URL` | Client rejected the URL as malformed. | | `UNKNOWN` | Future status not mapped by this version. | --- ## Related Pages - [[Painting/Developers/API Reference]] — full interface documentation - [[Painting/Server Owners/Configuration]] — config values the API exposes - [[Painting/API/PaintingAPI]] — static accessor source