# IPaintingAPI
The platform-neutral interface implemented by both Paper and Velocity plugins. Retrieved via `PaintingAPI.get()`.
---
## Source
```java
package gg.lode.paintingapi;
import gg.lode.paintingapi.api.model.PackDefinition;
import gg.lode.paintingapi.api.model.ServerEntry;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.CompletableFuture;
public interface IPaintingAPI {
boolean isEnabled();
@NotNull List<PackDefinition> getPackDefinitions();
@Nullable PackDefinition getPackDefinition(@NotNull String name);
@NotNull List<ServerEntry> getServerEntries();
boolean isRequiredForServer(@NotNull String serverName);
void reload();
void resendPacksToOnlinePlayers();
void resendPacksToPlayer(@NotNull UUID playerId);
/**
* Re-checks every configured pack URL and rewrites any hash that moved.
*
* <p>Runs off the server thread. Unforced calls are throttled and deduped
* against the periodic refresh, so calling this on a hot path is cheap:
* a run that happened within {@code hash-refresh-throttle} seconds is
* reused rather than repeated.
*
* @param force bypass the throttle and re-download every pack
* @return how many variant hashes changed
*/
default @NotNull CompletableFuture<Integer> refreshPackHashes(boolean force) {
throw new UnsupportedOperationException("refreshPackHashes is not supported by this Painting build");
}
/**
* SHA-1 of a pack, from an {@code http(s)} URL or from a file on disk —
* whichever {@code source} turns out to be.
*
* <p>The source is validated before anything is read: only http/https,
* redirects followed by hand with every hop re-checked, a byte cap on the
* body, and file paths resolved through their symlinks and confined to the
* server directory. Limits come from the {@code hash-security} block in
* Painting's config; the future completes exceptionally with a
* {@link SecurityException} when the source falls outside them.
*
* @param source pack URL, or a path relative to the Painting data folder /
* the server directory
* @return hex SHA-1, ready to drop into a {@code hash:} field
*/
default @NotNull CompletableFuture<String> computeHash(@NotNull String source) {
throw new UnsupportedOperationException("computeHash is not supported by this Painting build");
}
/** As {@link #computeHash(String)}, refusing anything that is not an http(s) URL. */
default @NotNull CompletableFuture<String> computeHashFromUrl(@NotNull String url) {
throw new UnsupportedOperationException("computeHashFromUrl is not supported by this Painting build");
}
/** As {@link #computeHash(String)}, refusing anything that is not a file inside the server directory. */
default @NotNull CompletableFuture<String> computeHashFromFile(@NotNull String path) {
throw new UnsupportedOperationException("computeHashFromFile is not supported by this Painting build");
}
}
```
---
## Related Pages
- [[Painting/API/PaintingAPI]] — static accessor that delegates to this interface
- [[Painting/API/PackDefinition]] — returned by `getPackDefinition`
- [[Painting/API/ServerEntry]] — returned by `getServerEntries`
- [[Painting/API/Hash/PackHasher]] — what the `computeHash` methods call
- [[Painting/API/Hash/HashPolicy]] — the limits those methods apply