dmg 03acea6ba5
Release / release (push) Successful in 2m18s
CI / build (push) Successful in 1m6s
fix(stats): use compatible Bukkit registry keys
2026-08-08 12:51:55 -04:00
2026-08-01 11:49:07 -04:00
2026-08-01 11:49:07 -04:00
2026-08-01 11:49:07 -04:00
2026-08-01 11:51:55 -04:00

Spigot Event Producer

A Spigot 26.2 plugin that records Minecraft activity as CloudEvents 1.0, persists it in a local SQLite outbox, and sends newline-delimited batches to game-ingest-server.

Requirements

  • Spigot 26.2
  • Java 17 or newer
  • Network access to the ingest endpoint

Build and install

./gradlew clean test jar
cp build/libs/spigot-event-producer-0.1.0-SNAPSHOT.jar /path/to/server/plugins/

Start the Minecraft server once to create plugins/SpigotEventProducer/config.yml. Set a meaningful, stable server-name. When server-id is empty, the plugin generates and persists a UUID. Do not reuse that generated UUID on another server.

The default ingest endpoint is:

https://events.dmg.games/events

Events

Every event is a structured CloudEvent 1.0 JSON object with these common attributes:

  • source: urn:minecraft-server:<server UUID>
  • serverid and servername: CloudEvent extensions identifying the server
  • gameversion: the Bukkit game version
  • playerid: player UUID for player events
  • data.player_id and data.player_name: stable UUID and current player name

Produced event types:

Type Trigger
games.dmg.minecraft.server.started Plugin/server startup
games.dmg.minecraft.server.stopped Plugin/server shutdown
games.dmg.minecraft.player.joined Player joins
games.dmg.minecraft.player.quit Player quits
games.dmg.minecraft.chat Non-cancelled public player chat
games.dmg.minecraft.private_message A recognized private-message command
games.dmg.minecraft.player.location Location snapshot
games.dmg.minecraft.player.statistics Partitioned statistic snapshot

Chat and private messages

Public chat events contain the complete message text.

Private-message events recognize /msg, /message, /tell, /w, /whisper, /pm, /reply, and /r, including namespaced variants such as /minecraft:tell. Explicit commands contain the destination token. Reply commands set reply: true and omit the recipient so downstream processing can infer it from earlier ordered events. The event also reports whether the command was cancelled.

Spigot has no universal private-message event. Commands implemented with unrelated aliases or entirely custom plugin logic will not be recognized until their syntax is added. A recognized command event reports observation of the command, not guaranteed delivery to its recipient.

Location snapshots

Each online player is sampled every 60 seconds by default. Events include world UUID/name, coordinates, yaw, pitch, game mode, and biome.

Statistic snapshots

Every Bukkit statistic is read, including untyped, block, item, and entity statistics. Zero values are retained. Invalid statistic/material/entity combinations rejected by Bukkit are skipped.

Large snapshots are divided by category and size. All parts share a snapshot_id, capture start/completion timestamps, and include part and parts fields. Statistic reads are spread across ticks using a configurable operation budget; a player remains queued until all combinations have been read. Empty categories still emit an explicit part.

Delivery and durability

The outbox is stored at:

plugins/SpigotEventProducer/event-outbox.sqlite3

SQLite writes and queue-size decisions run on a dedicated persistence worker. NDJSON construction and HTTP requests use a separate delivery worker, so a slow ingest request cannot prevent newly observed events from reaching SQLite. Bukkit state is only read on Bukkit-managed threads.

The worker sends every five minutes by default. It may send earlier when the configured event or byte threshold is reached. Requests remain below the ingest service's default 1 MiB and 1,000-event limits. Events are removed only after HTTP 202 Accepted; failures remain in SQLite and are retried.

Delivery is at least once. If the ingest server accepts a request but its response is lost, the plugin retries the same stable CloudEvent IDs. Consumers should deduplicate by CloudEvent id when necessary.

A shutdown event is persisted before the plugin closes its outbox. If it is not uploaded during shutdown, it is delivered after the next startup.

Configuration

server-name: "minecraft-server"
server-id: ""

ingest-url: "https://events.dmg.games/events"
send-interval-seconds: 300
snapshot-interval-seconds: 60
http-timeout-seconds: 15

batch:
  max-events: 1000
  max-bytes: 900000

dispatch-threshold:
  events: 1000
  bytes: 900000

statistics:
  chunk-json-bytes: 200000
  operations-per-tick: 1000

All intervals and limits must be positive. Keep batch.max-bytes below the ingest server's configured body limit and batch.max-events at or below its maximum events per request.

Releases

Gitea Actions runs the Gradle checks for every push and pull request and stores a development JAR as a workflow artifact. Pushes to main also run semantic-release using conventional commits:

  • fix: creates a patch release;
  • feat: creates a minor release;
  • a breaking-change footer or ! creates a major release.

A successful release creates a vX.Y.Z tag and attaches spigot-event-producer-X.Y.Z.jar permanently to the corresponding Gitea Release. The release workflow requires a repository secret named RELEASE_TOKEN with repository contents write permission.

For a local versioned build:

./gradlew clean check jar -PreleaseVersion=1.2.3

Privacy and operations

This plugin deliberately records complete public and private message text, player identifiers, precise locations, and activity statistics. Server operators should disclose that collection, restrict access to the plugin data directory and ingest database, use HTTPS, and configure retention appropriate to their jurisdiction.

The outbox has no automatic retention limit because dropping unsent events would violate durability. Monitor disk usage if the ingest service is unavailable for an extended period.

S
Description
Spigot 26.2 CloudEvents producer with a durable SQLite outbox
Readme
121 KiB
v1.0.2
Latest
2026-08-08 18:52:01 +00:00
Languages
Java 100%