BlockyDonations

BlockyDonations

Folia Paper 1.21+ PlaceholderAPI v2.0.3

Real-time webstore integration for Paper and Folia servers. Syncs purchases from Tebex, CraftingStore, MineStoreCMS, PayNow and KantoPay (or records them manually), broadcasts donations in-game, posts Discord notifications, tracks goals and milestones, and exposes PlaceholderAPI placeholders and a developer API.

Overview

BlockyDonations polls your webstore on a configurable interval and processes new purchases automatically. When a donation is detected it fires a configurable multi-line chat broadcast with optional player-head rendering, triggers a GG Wave reaction window, sends a Discord embed and updates leaderboard, goal and milestone state.

Storage is SQLite, MySQL or MariaDB. Polling and Discord requests run asynchronously so the main thread is never blocked, and Folia's threaded schedulers are detected automatically. Multi-server setups are supported through database leader election and optional Redis event sync.

Supported Providers

  • Tebex
  • CraftingStore
  • MineStoreCMS
  • PayNow
  • KantoPay
  • Manual - donations recorded with /bd record

Optional Integrations

  • PlaceholderAPI - required for all %bd_*% placeholders
  • Floodgate - Bedrock player and skin resolution
  • SkinRestorer - uses restored skins for heads and renders
  • NoteBlockAPI - .nbs songs as GG Wave music
  • Chat plugins - ChatControl, ZelChat, AdvancedChat, TownyChat and others
  • FancyHolograms / FancyNpcs - load order only; use the leaderboard and skin placeholders
  • Redis - cross-server events
✓

No restart needed for most changes. Run /bd reload after editing config files. Adding or removing a provider is the exception.

Installation

  1. Download BlockyDonations from BuiltByBit
  2. Place the JAR in your plugins/ folder
  3. Start the server - default files generate automatically
  4. Edit plugins/BlockyDonations/config.yml with your store credentials
  5. Run /bd reload or restart to activate
i

PlaceholderAPI required: install it separately for %bd_*% placeholders to work in scoreboards, holograms and NPCs.

i

Config updates: when the plugin version changes, config files are merged with the new defaults. Your values are kept and the old files are backed up to plugins/BlockyDonations/backup/.

Configuration

Store Providers

store.providers is a list. Use one entry for a single store or several to run them together. The legacy store.provider key is migrated automatically.

config.yml
store:
  providers:  # tebex | craftingstore | minestorecms | paynow | kantopay | manual
    - tebex

  tebex:
    secret-key: "YOUR_TEBEX_SECRET_KEY_HERE"

  craftingstore:
    api-token: "YOUR_CRAFTINGSTORE_TOKEN_HERE"

  paynow:
    api-key: "YOUR_PAYNOW_API_KEY_HERE"
    store-id: "YOUR_PAYNOW_STORE_ID_HERE"

  minestorecms:
    secret-key: "YOUR_MINESTORECMS_SECRET_KEY_HERE"
    store-url: "https://store.yourserver.com"

  kantopay:
    api-key: "YOUR_KANTOPAY_API_KEY_HERE"
    currency: "PHP"
    goal-target: 0.0
    goal-period: "month"  # day | week | month | year | all
    include-test: false

  manual:
    store-name: "Manual Store"
    currency: "USD"
i

Restart required. Adding or removing a provider needs a full server restart. /bd reload only reloads the settings of providers that are already running.

Database

SQLite (local file) or MySQL/MariaDB (external). MySQL enables multi-server clustering.

config.yml
database:
  type: "sqlite"  # sqlite | mysql | mariadb

  sqlite:
    file: "donations.db"

  mysql:
    host: "127.0.0.1"
    port: 3306
    database: "blockydonations"
    username: "root"
    password: "change-me"
    use-ssl: false
    parameters: "useUnicode=true&characterEncoding=utf8&serverTimezone=UTC"

  pool:
    maximum-pool-size: 10
    minimum-idle: 2
    connection-timeout-ms: 10000

Sync Settings

config.yml
sync:
  interval: 120  # seconds between syncs (min 30)
  fetch-limit: 50  # max purchases per sync cycle

Broadcast Message

The broadcast is a YAML list - each entry is one chat line. Player head rows ({player_head_1} through {player_head_8}) render the donor's face alongside the text. Full MiniMessage is supported, including gradients, hover effects and click events.

config.yml
broadcast:
  enabled: true
  message:
    - ' '
    - '{player_head_1}  <#FF8800>✦ <gradient:#FF8800:#FFD700><bold>New Donation!</bold></gradient>'
    - '{player_head_2}'
    - '{player_head_3}  <white>Player: <#FFD700>{player}'
    - '{player_head_4}  <white>Package: <#00BBFF>{package}'
    - '{player_head_5}  <white>Amount: <#49FF00>{amount_formatted}'
    - '{player_head_6}'
    - '{player_head_7}  <click:open_url:"https://store.servername.com"><hover:show_text:"<gold>Click to Open!"><#FFD700>Visit our store!</hover></click>'
    - '{player_head_8}  <white>Write <#FFD700>"GG" <white>in chat to celebrate! <#FF3232>❤'
    - ' '

  sound:
    enabled: true
    type: "ENTITY_PLAYER_LEVELUP"
    volume: 1.0
    pitch: 1.0

  head-render-type: "helm"  # helm (with hat) | avatar (raw face)

Broadcast Placeholders

variables
{player}                Player name
{package}               Package / product name
{amount}                Raw amount (e.g. 9.99)
{amount_formatted}      Amount with symbol (e.g. $9.99)
{currency}              ISO currency code
{currency_symbol}       Symbol (e.g. $)
{provider}              Store provider name
{store_name}            Store display name
{store_url}             Store URL
{store_url_encoded}     URL-encoded (use in open_url tags)
{player_head_1..8}      Full 8-pixel row (top=1, bottom=8)
{player_head}           Row 1 only (compact)
{player_face_url}       mc-heads.net avatar URL
{skin_minotar_avatar|helm|bust|body}
{skin_starlight_archer|bust|chibi|walking|portrait|default}

Multi-Provider & Currencies

Every provider keeps its own revenue, leaderboards, latest purchase, goals and sales. Purchases are stored per currency, so amounts in different currencies are never mixed.

Combined Leaderboards

With more than one provider, /bd top and the unprefixed top placeholders combine all providers using cached exchange rates. If rates are missing or older than three days, the view falls back to the first provider.

config.yml
store:
  exchange-rates:
    enabled: true
    preferred-display-currency: "USD"
    refresh-interval-hours: 12
    combined-leaderboard-pool-multiplier: 4

Provider-Scoped Placeholders

Prefix any placeholder (except milestones) with a provider key to scope it to that store:

placeholders
%bd_tebex_store_name%
%bd_kantopay_top_alltime_1%
%bd_paynow_goal_bar%

Manual Provider

Add manual to store.providers, then record a donation with /bd record <player> <amount> [package] [currency]. It runs through the normal pipeline: broadcast, Discord, goals and milestones. The currency must match store.manual.currency.

Network Sync

With MySQL or MariaDB, database.multi-server enables leader election so only one server polls each provider, and announcements are claimed so each donation is announced once. Redis adds live event sync between servers.

config.yml
database:
  multi-server:
    enabled: true
    leader-election: true
    server-id: "auto"
    lease-seconds: 45
    claim-timeout-seconds: 120
    claim-batch-size: 50

redis:
  enabled: false
  host: "127.0.0.1"
  port: 6379
  password: ""
  ssl: false
  key-prefix: "blockydonations"
  network-secret: ""
  dedupe-ttl-seconds: 90
  sync-gg-wave: true
  sync-goal-reached-chat: true
  sync-donation-message: true

Redis syncs donation broadcasts, GG Waves, goal announcements and milestone completions. Events are signed with HMAC-SHA256 when redis.network-secret is set - use the same secret on every server.

✓

Set redis.password, redis.ssl and redis.network-secret for any Redis instance that is not on localhost.

Commands

Base command: /blockydonations - aliases: /bd, /blockydon, /d, /donations

/bd helpblockydonations.command.help
List all BlockyDonations commands.
/bd reloadblockydonations.command.reload
Reload config files and restart the sync cycle.
/bd syncblockydonations.command.sync
Immediately sync with your webstore(s).
/bd test [type] [player] [milestone-id]blockydonations.command.test
Fire a test event. Types: broadcast, discord, effects, goal, milestone, ggwave, all.
/bd stats [player]blockydonations.command.stats
Server revenue, or total, monthly spend and rank for a player.
/bd latestblockydonations.command.latest
Show the most recent donation.
/bd top [alltime|monthly] [provider] [size]blockydonations.command.top
Show the leaderboard. With multiple providers it shows the combined board, or one provider when named.
/bd goalsblockydonations.command.goals
Show goal progress.
/bd salesblockydonations.command.sales
Show sales synced from your store.
/bd status [page]blockydonations.command.status
Connection state and revenue. With multiple providers the output is paged per provider, with estimated combined revenue.
/bd ggwave [start|stop|status]blockydonations.command.ggwave
Control the GG Wave independently of donations.
/bd record &lt;player&gt; &lt;amount&gt; [package] [currency]blockydonations.command.record
Manually record a donation. Requires the manual provider.
/bd giftcard create &lt;player&gt; -d|-p &lt;amount&gt; [-e date] [-n name] [-c code]blockydonations.command.giftcard
-p creates a fixed-value card, -d a percentage discount, -e takes yyyy-MM-dd. Also check, list [page] and remove. Support varies by provider; unsupported options are logged and ignored.
/bd updateblockydonations.command.update
Check for the latest version.

Permissions

NodeDefaultDescription
blockydonations.*opAll BlockyDonations permissions.
blockydonations.adminopAll admin commands.
blockydonations.statsopGoals, sales, stats and latest commands.
blockydonations.command.reloadopUse /bd reload.
blockydonations.command.syncopUse /bd sync.
blockydonations.command.statusopUse /bd status.
blockydonations.command.testopUse /bd test.
blockydonations.command.ggwaveopUse /bd ggwave.
blockydonations.command.recordopUse /bd record.
blockydonations.command.giftcardopUse /bd giftcard.
blockydonations.command.updateopUse /bd update.
blockydonations.command.statsopUse /bd stats.
blockydonations.command.latestopUse /bd latest.
blockydonations.command.goalsopUse /bd goals.
blockydonations.command.salesopUse /bd sales.
blockydonations.command.toptrueUse /bd top - open to all players.
blockydonations.command.helptrueUse /bd help - open to all players.

PlaceholderAPI

All placeholders require PlaceholderAPI and start with %bd_. With multiple providers, add a provider key after the prefix (for example %bd_tebex_goal_bar%) to scope a placeholder.

Store Info

placeholders
%bd_store_name%               Store display name
%bd_store_url%                Store URL
%bd_store_currency%           Currency code (e.g. USD)
%bd_store_currency_symbol%    Currency symbol (e.g. $)
%bd_store_provider%           Provider name

Latest Donation

placeholders
%bd_latest_player%            Donor username
%bd_latest_package%           Package name
%bd_latest_amount%            Raw amount
%bd_latest_amount_formatted%  Amount with symbol
%bd_latest_currency%          Currency code

Revenue

placeholders
%bd_revenue_total%             Total revenue (raw)
%bd_revenue_monthly%           Monthly revenue (raw)
%bd_revenue_total_formatted%   Total with symbol
%bd_revenue_monthly_formatted% Monthly with symbol

Leaderboards

Replace alltime with monthly or recent, and 1 with any rank up to leaderboard.size.

placeholders
%bd_top_alltime_1%             Player name
%bd_top_alltime_1_amount%      Raw amount
%bd_top_alltime_1_formatted%   Amount with symbol
%bd_top_alltime_1_uuid%        Player UUID
%bd_top_alltime_1_skin%        Skin PNG URL (Java + Bedrock)
%bd_top_alltime_1_skin_body%   3D full-body render URL (Java + Bedrock)

Empty ranks return the default Steve skin URLs, so NPC and menu plugins always receive a valid image.

Requesting Player's Leaderboard Info

placeholders
%bd_top_alltime_amount%   Player's all-time amount
%bd_top_alltime_rank%     Player's all-time rank
%bd_top_monthly_amount%   Same for monthly
%bd_top_recent_rank%      Same for recent

Player Statistics

placeholders
%bd_player_total%             Total donated (raw)
%bd_player_monthly%           Monthly total (raw)
%bd_player_recent%            Last N days (leaderboard.recent-days)
%bd_player_total_formatted%   Total with symbol
%bd_player_monthly_formatted% Monthly with symbol
%bd_player_recent_formatted%  Recent with symbol
%bd_player_rank_alltime%      All-time leaderboard rank

Goals

placeholders
%bd_goal_name%                Goal name
%bd_goal_current%             Current progress (raw)
%bd_goal_target%              Target amount (raw)
%bd_goal_percent%             Completion percentage
%bd_goal_remaining%           Amount remaining
%bd_goal_bar%                 Visual progress bar
%bd_goal_completed%           true / false
%bd_goal_completions%         Times the primary goal was reached
%bd_goal_completions_<name>%  Times a named goal was reached

Sales

placeholders
%bd_sale_name%                Active sale name
%bd_sale_discount%            Discount (e.g. 25% or $5.00 off)
%bd_sale_active%              true / false

Milestones

Milestone placeholders are global (not provider-scoped) and work for offline players.

placeholders
%bd_milestone_<id>_name%         %bd_milestone_<id>_target%
%bd_milestone_<id>_current%      %bd_milestone_<id>_percent%
%bd_milestone_<id>_remaining%    %bd_milestone_<id>_bar%
%bd_milestone_<id>_completed%    %bd_milestone_<id>_completions%

%bd_milestone_chain_<chain>_bar%        %bd_milestone_chain_<chain>_tier%
%bd_milestone_chain_<chain>_percent%    %bd_milestone_chain_<chain>_current%
%bd_milestone_chain_<chain>_target%     %bd_milestone_chain_<chain>_remaining%
%bd_milestone_chain_<chain>_completed%

Broadcast

Broadcast text supports full MiniMessage syntax. Player head rows sample the donor's skin and render it as colored block characters across consecutive chat lines. Skins are resolved asynchronously: cached or fallback heads are shown immediately while fresh ones load in the background.

Java skins come from Mojang or SkinRestorer when installed. Bedrock skins are resolved through Floodgate and Geyser.

Head Render Type

config.yml
broadcast:
  head-render-type: "helm"  # helm (with hat layer) | avatar (raw face only)

Skin Render URLs

Use these in custom messages:

variables
{skin_minotar_avatar}     Minotar avatar
{skin_minotar_helm}       Minotar with hat
{skin_minotar_bust}       Minotar bust
{skin_minotar_body}       Minotar full body
{skin_starlight_archer}   StarlightSkins archer pose
{skin_starlight_bust}     StarlightSkins bust
{skin_starlight_chibi}    StarlightSkins chibi

Chat Reactions (GG Wave)

A reaction window opens after each qualifying donation. Players who type a reaction word (like "GG") get their message colored. Start or stop one manually with /bd ggwave.

Basic Configuration

config.yml
chat-reactions:
  enabled: true
  listener-priority: "LOWEST"  # HIGHEST | HIGH | NORMAL | LOW | LOWEST
  window-seconds: 15
  min-amount: 2  # minimum donation to trigger the wave (0 = no minimum)
  chance: 100  # 0-100 chance for the wave to activate
  match-anywhere: true  # false = exact match, true = word anywhere in message
  mute-non-reactions: false  # true = block other chat while the wave is active
  case-sensitive: false

  words:
    - "gg"
    - "ggs"
    - "thank you"
    - "thanks"
    - "w"
    - "pog"
    - "poggers"

Text Formatting

config.yml
chat-reactions:
  format: "rainbow"  # rainbow | gradient | solid | solidrainbow

  rainbow:
    gradient: "#FF0000:#FF9A00:#FFF200:#00D26A:#8B00FF"
    gradient-smoothness: 8  # 2-32 (higher = smoother)

  solid-color: "#FFD700"

  solid-rainbow-colors:
    - "#FF0000"
    - "#FF7700"
    - "#FFFF00"

  decorations:
    bold: true
    italic: false
    underline: false

Rewards

Run commands when players react. Prefix with [CONSOLE] (default), [PLAYER], [MESSAGE] or [PLUGIN_MESSAGE], and append [CHANCE:n] for a per-command chance. {player} is sanitized before use.

config.yml
chat-reactions:
  rewards:
    enabled: true
    commands:
      - "[CONSOLE] eco give {player} 100"
    run-once-per-wave: false  # true = one reward per player per wave
    chance: 25
    word-overrides: []  # per-word chance, commands or enabled flag

Sounds

config.yml
chat-reactions:
  sounds:
    wave-start:
      enabled: true
      type: "item.goat_horn.sound.0"
      volume: 1.0
      pitch: 1.0

    wave-music:
      enabled: false
      trigger: "always"  # always | on-first
      type: "music_disc.cat"
      nbs:  # requires NoteBlockAPI; songs go in plugins/BlockyDonations/songs/
        enabled: false
        file: "random"
        volume: 80
        category: "RECORDS"

    reaction:
      enabled: true
      type: "entity.experience_orb.pickup"
      broadcast: true  # false = only the typing player hears it

    word-sounds: []

Regex Patterns

Patterns are tested before the word list; the first match wins.

config.yml
chat-reactions:
  sounds:
    patterns:
      - pattern: "(?i)^g+$"
        replace-with: "GG"
        color: "gradient"  # rainbow | gradient | solid | none
        sound:
          type: "entity.player_levelup"
          volume: 1.0
          pitch: 1.2
          broadcast: true
i

Compatible chat plugins: ChatControl, ZelChat, AdvancedChat, TownyChat, VentureChat, EssentialsX, HeroChat and DeluxeChat. ZelChat and AdvancedChat use dedicated hooks. If reactions are not colored, try changing listener-priority.

Discord (Webhook + Bot)

Bot Mode (Optional)

Requires a restart. When enabled with a valid token, the bot takes priority over the webhook.

discord.yml
bot:
  enabled: false
  token: "YOUR_BOT_TOKEN"
  channel-id: "YOUR_CHANNEL_ID"

  auto-create-thread:
    enabled: false
    name: "Thank you {player}"
    embeds:
      - "donation-embed"
      - "goal-embed"
    auto-archive-duration: 1440  # 60 | 1440 | 4320 | 10080

Webhook Setup

  1. Open Discord server settings, go to Integrations, then Webhooks.
  2. Create a webhook, choose a channel and copy the URL.
  3. Paste it into discord.yml and set discord.enabled: true.
  4. Run /bd reload, then /bd test discord.

Donation Embed

discord.yml
discord:
  enabled: false
  webhook-url: "https://discord.com/api/webhooks/YOUR_WEBHOOK_ID/YOUR_WEBHOOK_TOKEN"

  donation-embed:
    enabled: true  # disable to keep goal embeds only
    title: "New Donation! 🎉"
    description: "**{player}** donated **{currency_symbol}{amount}** for **{package}**!"
    color: "#FFD700"
    footer: "Server Goal: {goal_percent}% / 100% {goal_bar}"
    timestamp:
      enabled: true
    author:
      enabled: true

    image:
      provider: "starlight"  # minotar | starlight | crafatar | nmsr | none
      placement: "image"  # thumbnail | image | description | none
      starlight:
        type: "random"
      fallback:
        enabled: true
        probe-timeout-seconds: 5
        providers:
          - "nmsr"
          - "crafatar"
          - "minotar"

    branding-images:
      - url: "https://leafstudios.dev/images/logo_small.png"
        placement: "thumbnail"

    deduplication:
      enabled: true
      window-seconds: 60

Embed placeholders: {player} {package} {amount} {currency} {currency_symbol} {store} {skin_url} {goal_name} {goal_current} {goal_target} {goal_percent} {goal_remaining} {goal_bar} {goal_completions}

Goal Reached Embed

discord.yml
discord:
  goal-embed:
    enabled: true
    title: "🎉 Goal Reached! 🎉"
    description: "Thanks to **{latest_donator}** and everyone who donated.\n\nWe've reached our goal of **{goal_target_formatted}**!\nThis is completion #**{goal_completions}**."
    color: "#FFD700"
    timestamp:
      enabled: true
✓

Payloads are queued, deduplicated (network-wide when Redis is on) and sent at most once per second. Rate limits are retried automatically.

Leaderboards

Three leaderboards are maintained per currency:

  • alltime - total donations since install
  • monthly - current UTC calendar month
  • recent - past N days, set by leaderboard.recent-days
config.yml
leaderboard:
  size: 10  # 1-20
  recent-days: 7

Use /bd top in-game, or the placeholders in holograms, scoreboards and NPCs. With several providers the boards are combined using exchange rates, and you can scope them with /bd top <provider> or %bd_<provider>_top_*%.

Goals

i

Goal modes. external syncs goals from the store. internal tracks progress from received purchases and is required for PayNow. Set goals.internal.combined: true to track one goal across all providers in the preferred display currency.

When a goal completes, BlockyDonations announces it in chat and Discord, runs reward commands, and fires GoalCompletedEvent. Internal goals reset to 0 automatically so they can be completed again.

config.yml
goals:
  type: "external"  # external | internal
  internal:
    name: "Server Goal"
    combined: false
    current: 0.0  # re-seeds progress when changed
    goal: 100.0

  overrides:  # per-provider type, internal.name, internal.current, internal.goal
    paynow:
      type: "internal"

  track-completions: true
  announce-in-chat: true

  progress-bar-length: 25
  progress-bar-style: "pipes"  # blocks | pipes | custom
  progress-bar-filled: "█"
  progress-bar-almost-filled: "█"
  progress-bar-empty: "█"
  progress-bar-color-filled: "<green><b>"
  progress-bar-color-almost-filled: "<yellow><b>"
  progress-bar-color-empty: "<gray><b>"

  rewards:
    enabled: true
    chance: 100
    commands:  # [CONSOLE] | [PLAYER] | [MESSAGE], optional [CHANCE:50]
      - "[CONSOLE] eco give {player} 500"

Milestones

Milestones reward individual players for reaching spending targets. Each can be one-time or repeatable, limited to a date window, and run reward commands on completion. Enable them in milestones.yml.

milestones.yml
milestones:
  enabled: true
  announce-complete: false  # true = announce to all servers

Metrics

  • TOTAL_SPEND - lifetime spend across all purchases
  • PACKAGE_SPEND - lifetime spend on matching packages
  • PACKAGE_COUNT - qualifying purchases, with optional per-package weights

Package matching is a case-insensitive substring match on the package name, so it works on every provider.

milestones.yml
goal:
  metric: PACKAGE_SPEND
  target: 500.0
  packages:
    - "vip"
    - "vip+"

goal:
  metric: PACKAGE_COUNT
  target: 15
  packages:
    key: 1
    bundle: 3

Full Example

milestones.yml
milestones:
  list:
    - id: patron
      chain: patron
      repeatable: false
      display-name: "<gradient:#FF0080:#00CCFF><bold>Patron Rank</bold></gradient>"

      goal:
        metric: TOTAL_SPEND
        target: 500.0
        currency: USD  # recommended when using multiple currencies
        providers:  # optional provider filter
          - tebex

      active:
        from: "2026-09-01T00:00:00Z"
        until: "2028-12-31T23:59:59Z"

      rewards:
        - "[CONSOLE] lp user {player} parent add patron"

      bar:
        length: 20
        style: gradient
        gradient: "#FF0080:#00CCFF"
        filled: "█"
        empty: "█"

      messages:
        progress:
          - "{bar} <#49FF00>{percent}%"
        complete:
          - "<gradient:#FF0080:#00CCFF><bold>✦ PATRON UNLOCKED ✦</bold></gradient>"

Chains

Milestones sharing a chain value form ordered tiers (for example patron, then patron-plus). The %bd_milestone_chain_*% placeholders show the player's current tier and a bar toward the final tier.

Rewards & Testing

Reward lines accept [CONSOLE] (default), [PLAYER] and [MESSAGE] prefixes. Test one with /bd test milestone <player> <id>.

message placeholders
{player}             Player name
{milestone}          Display name
{amount_formatted}   Triggering purchase amount
{progress}           Current progress
{goal}               Target value
{remaining}          Remaining to completion
{percent}            Completion percent
{bar}                Rendered progress bar
{completions}        Times completed

Effects

Effects fire for all online players when a donation is announced. Test them with /bd test effects.

Fireworks

config.yml
effects:
  firework:
    enabled: true
    type: BALL_LARGE  # BALL | BALL_LARGE | BURST | CREEPER | STAR
    power: 1  # 0-4
    flicker: true
    trail: true
    colors:
      - ORANGE
      - YELLOW
    fade-colors: []  # empty = same as colors

Lightning & Title

config.yml
effects:
  lightning:
    enabled: false
    damaging: false  # true = deals damage

  title:
    enabled: false
    title: "<#FFD700><bold>✦ New Donation! ✦<reset>"
    subtitle: "<#FFD700>{player} <white>donated <#FFD700>{amount_formatted}<white>!"
    fade-in: 10  # ticks (20 = 1 second)
    stay: 60
    fade-out: 20

Developer API

Get the API from Bukkit's services manager:

java
BlockyDonationsApi api = Bukkit.getServicesManager().load(BlockyDonationsApi.class);
double spent = api.getPlayerSpend(LeaderboardType.ALL_TIME, "Notch");

Available data: store info, latest and recent purchases, goals, the active sale, leaderboards (ALL_TIME, MONTHLY, RECENT), player spend and rank (by name or UUID), milestones and progress, and forceSync().

Events

  • DonationReceivedEvent - a new purchase was stored
  • DonationAnnounceEvent - before the broadcast; cancellable
  • GoalCompletedEvent - a goal was completed and announced
  • SyncCompletedEvent - a sync cycle finished