# Commands
Painting registers a single root command on both Paper and Velocity. The Paper plugin uses CommandAPI; the Velocity plugin uses Velocity's `SimpleCommand`. The command surface is identical on both platforms.
---
## /painting
| Subcommand | Permission | Description |
|---|---|---|
| `reload` | `lodestone.painting.commands.painting` | Reload pack and server registries from disk. |
| `resend` | `lodestone.painting.commands.painting` | Resend resource pack offers to every online player. |
| `generatehashes` | `lodestone.painting.commands.painting` | Download every configured pack URL, compute SHA-1, and write the hash back to config. |
| `hash <url\|file>` | `lodestone.painting.commands.painting` | Print the SHA-1 of a single pack URL or pack file without touching config. |
Aliases: `/resourcepack`.
---
## /painting reload
Reloads the configuration without restarting the server.
1. Saves the default config if missing.
2. Re-reads pack definitions, server entries, message templates, and protocol overrides.
3. Logs a warning for any server entry referencing an undefined pack.
4. Fires `PaperPackRegistryReloadEvent` (Paper) — Velocity does not currently fire a registry reload event externally.
5. *(Velocity)* Reschedules the periodic hash refresh task.
Existing pack offers on connected players are not re-sent. Use `/painting resend` to push the new state to live sessions.
---
## /painting resend
Re-issues pack offers to every online player.
- **Paper standalone** — sends the resolved pack list using the local server name.
- **Velocity** — sends the resolved pack list per-player using each player's current server name.
- Velocity's `sendResourcePacks` dedupes against `getAppliedResourcePacks()` — already-applied packs are skipped.
---
## /painting generatehashes
Downloads every configured pack URL, computes SHA-1, and writes the result back to the config file.
| Outcome | Message |
|---|---|
| No URLs configured | `No packs with a URL to hash.` |
| All hashes already current | `All N hashes already up to date.` |
| Mixed | `<changed> of <total> hashes changed.` (with optional `(N failed)` suffix) |
After a successful run, the config is reloaded so the new hashes take effect immediately. A manual `generatehashes` always forces a refresh, bypassing the `hash-refresh-throttle` window — on both platforms.
Players joining mid-run are let through without a pack and sent theirs as soon as the run finishes, so a rehash never offers a pack with a hash the client would reject.
Since 1.0.20 you rarely need this: both platforms re-check hashes on their own (see `hash-refresh-throttle` in [[Painting/Server Owners/Configuration]]). Reach for `generatehashes` when you want a full re-download now, ignoring what the origin says about freshness.
---
## /painting hash
Prints the SHA-1 of one source and nothing else — config is untouched.
```
/painting hash https://cdn.example.com/pack.zip
/painting hash packs/base.zip
```
A path is resolved against the Painting data folder first, then the server directory. Useful for filling in a `hash:` field by hand, or checking what a CDN is actually serving.
The command runs under the same limits as the API: `http`/`https` only, a byte cap, and paths confined to the server directory. A source outside them comes back as an error rather than a hash — see `hash-security` in [[Painting/Server Owners/Configuration]].
---
## Permissions
| Permission | Grants |
|---|---|
| `lodestone.painting.commands.painting` | All `/painting` subcommands. Defaults to `op` on Paper. |
---
## Related Pages
- [[Painting/Server Owners/Configuration]] — config values reloaded by `/painting reload`
- [[Painting/Developers/Overview]] — `PackRegistryReloadEvent` is fired after `/painting reload`