Releases: nicki41/UniversalAdmin
Release list
UniversalAdmin 0.1.0-alpha.5
Added
- Every GitHub release is now automatically mirrored to the
universaladmin
Modrinth project as a new version (Kira-NT/mc-publish, the new
MODRINTH_TOKENrepository secret). See
docs/release/releasing.md. - The
universaladminModrinth project page is now filled in: icon
(assets/icon.png), title, summary, description, categories, license, and
links - content lives in docs/release/modrinth.md.
Full Changelog: v0.1.0-alpha.4...v0.1.0-alpha.5
UniversalAdmin 0.1.0-alpha.4
Full Changelog: v0.1.0-alpha.3...v0.1.0-alpha.4
UniversalAdmin 0.1.0-alpha.3
Changed
- Releases are no longer flagged "Pre-release" on GitHub,
-alpha/-beta/
-rcversions included - the project's status is already communicated by
the version string and the README, not GitHub's separate prerelease flag.
See docs/release/releasing.md. - The telemetry endpoint is no longer a config value:
telemetry.endpoint
has been removed fromconfig.ymlandCoreSettings, and every heartbeat
now goes to the officialnicki41-telemetryinstance, fixed in
TelemetryBootstrap.telemetry.enabledremains the only switch. This
also means an oldconfig.ymlwith a leftovertelemetry.endpointvalue
(e.g. an explicit empty string) no longer has any effect.
Fixed
auto-release.yml's version-bump commit/tag push had no recovery if
mainmoved between checkout and push (hit for real when a backlog of
delayed Actions runs raced each other) - now retries up to 5 times, each
attempt recomputing from a freshgit fetch/reset --hard origin/main.
Full Changelog: v0.1.0-alpha.2...v0.1.0-alpha.3
UniversalAdmin 0.1.0-alpha.2
Added
- Automatic update checks:
dev.universaladmin.updatepolls the GitHub
releases API on a jittered interval (default every 6 hours) and, when a
newer version exists, notifies staff (universaladmin.update.notify) and
logs a console warning./admin update(universaladmin.update.apply)
downloads the latest release's jar into Bukkit's ownplugins/update/
folder (verified against its published SHA-256 checksum) - applied at the
next restart, never a live hot-swap.update.check-for-updates(default
true) is the on/off switch;update.check-intervalconfigures the
background timer. - Empty-slot placeholders in the Players module's and Staff-Mode's
inventory/ender-chest editors: a dyed-gray leather armor piece per slot
(helmet/chestplate/leggings/boots), a grayed-out shield for offhand, and a
visibly distinct hotbar row -EmptySlotPlaceholder, stripped back to
nullbefore ever writing to a real inventory.
Changed
TelemetryPayload's wire format gained apluginIdfield (fixed:
"universaladmin") and renameduniversalAdminVersionto
pluginVersion- the shape a shared, multi-plugin telemetry backend
expects (see docs/user/telemetry.md). What's
collected and the opt-out are unchanged.telemetry.endpointnow defaults tohttps://telemetry.0nicki.de/v1/telemetry
(the officialnicki41-telemetryinstance) instead of empty - a fresh
install now reports anonymous usage statistics out of the box;
telemetry.enabled: false(or clearingtelemetry.endpoint) still turns
it off entirely. See docs/user/telemetry.md.
Fixed
- Closing a live inventory/ender-chest editor (Players module or the
Staff-Mode Inspector tools) showed the "Done." confirmation twice - both
halves of the split main-storage/equipment write notified independently;
now only the first does.
Full Changelog: v0.1.0-alpha.1...v0.1.0-alpha.2
UniversalAdmin 0.1.0-alpha.1
Added
-
Anonymous usage statistics (
dev.universaladmin.telemetry):
InstallationIdentity/InstallationIdentityStore(128 bits from
SecureRandom, derived from nothing, persisted in
installation-id.yml),TelemetryPayload(exactly six fields),
TelemetryClientwithHttpTelemetryClient(JDK HTTP client, short
timeouts, no redirects, response discarded) andNoOpTelemetryClient,
TelemetryService(enabled check on every heartbeat, player counts read
on the main thread, the request runs in the background, failures are
swallowed and only warned once per run),TelemetryScheduler(a
delayed start, an interval with jitter, its own daemon thread), and
TelemetryBootstrap(wiring with three outcomes: off / no endpoint /
active). New settingstelemetry.enabled(switchable live),
telemetry.endpoint(empty by default - nothing is sent by
default), andtelemetry.interval. Full documentation including
everything that's never collected:
docs/user/telemetry.md. -
Tests for telemetry with zero real network requests: id
generation/persistence, "disabled means zero requests", a payload
without player identities, serialization, an endpoint failure with no
side effect, jitter bounds, scheduler cleanup. -
LICENSE(Apache-2.0, unmodified official license text) and a
licensing decision with rationale in
docs/release/licensing.md. -
docs/development/architecture-rules.md- the binding architecture,
package, threading, settings, module, security, dependency, and test
rules as regular developer documentation. -
docs/release/releasing.md- a reproducible release process
(version → CHANGELOG → build → commit → tag → push). -
.github/workflows/release.yml- av*tag automatically produces a
GitHub release: a tag-vs-project-version check, a build including
tests, the shaded jar plus a SHA-256 file as assets, prerelease
detection for-alpha/-beta/-rc.contents: write, no additional
secrets. Also callable directly (workflow_call, with ataginput) by
auto-release.ymlbelow, not only by its own tag-push trigger. -
.github/workflows/auto-release.yml- releases automatically after any
push tomainthat changes more than docs/CI metadata: bumps the
-alpha.Ncounter inbuild.gradle.kts, moves theCHANGELOG.md
[Unreleased]section into a dated one, commits, tags, and calls
release.yml. Skips a beta/rc/stable version bump (a bigger decision
than this workflow makes on its own) and its own release commits (no
loop). See docs/release/releasing.md. -
A
printVersionGradle task as the single source of the project
version for CI (the tag check, artifact naming). -
Issue forms (
bug_report.yml,feature_request.yml) and
ISSUE_TEMPLATE/config.ymlpointing at private vulnerability reporting
instead of public security issues. -
Project architecture defined and documented (see ARCHITECTURE.md,
docs/architecture/, ADRs under docs/architecture/decisions/). -
Gradle setup (Java 25 toolchain, Shadow plugin, SQLite/MySQL drivers,
JUnit 5). -
Plugin bootstrap (
UniversalAdminPlugin) with manual dependency wiring. -
Core abstractions:
Module,Action/ActionResult,GuiPage,
Repository/Migration,PermissionRegistry,ServiceRegistry,
AuditService,MessageService,NotificationService,TaskScheduler. -
Eight module skeletons: Players, Moderation, Server, Worlds, Whitelist,
Performance, Audit Log, Settings.Playersas the complete reference
implementation (repository → service → action, including a migration). -
Test infrastructure with example tests (registry, permission
validation, a service with an in-memory fake, migrations against a
real SQLite database). -
Core bootstrap lifecycle (
onLoad/onEnable/onDisable) with a clear
separation between critical core components (config, scheduler,
storage/migrations, shared registries - failures abort the whole
plugin start) and individual modules (failures are isolated, see
ModuleManager). -
Internal module lifecycle system:
ModuleDescriptor(metadata
including dependencies, settings/permission namespace, an optional GUI
icon placeholder),ModuleState
(DISCOVERED/LOADED/ENABLED/DISABLED/FAILED),ModuleRegistry
(state tracking),ModuleManager(dependency ordering, failure
isolation),ModuleResources(automatic release of
listeners/tasks/registry entries on disable). See
docs/architecture/modules.md. -
PluginStatus/ComponentStatus- a live snapshot of version, uptime,
active/failed modules, coarse database/web status. -
/admincommand (aliases/ua,/uadmin) as a status placeholder,
renderingPluginStatus. -
unregister(...)onActionRegistry/GuiRegistry/PermissionRegistry
for module-disable cleanup. -
Tests for the module lifecycle system (
ModuleManagerTest):
registration, a duplicate module id, lifecycle ordering, failure
isolation, disable cleanup, dependency ordering, cycle detection, a
missing dependency. -
Typed settings system (
dev.universaladmin.settings):
SettingKey<T>/SettingType<T>/SettingValidator<T>/SettingDefinition<T>/
SettingValue<T>/SettingRegistry/SettingsService, with built-in
types for string/boolean/int/long/double/Duration/enum/string list,
validators for min/max/regex/multiple-of, and namespacing between core
settings and future module/extension settings. See
docs/development/settings.md and ADR 0007. -
CoreSettings- registers the completeconfig.ymltree (general,
database,gui,audit,modules,performance,maintenance,
web);modules.*now actually controls whether a built-in module
gets registered at all. -
config.ymlversioning:config-version,ConfigMigration/
ConfigMigrationRunner(dev.universaladmin.config) - an existing
user config gets migrated on future schema changes instead of
overwritten. -
A safe
/admin reload(ReloadConfigAction, permission
universaladmin.reload) - only ever reloads UniversalAdmin's own
config.yml, never Bukkit's global/reload. Restart-required
settings are reported as "pending restart" on change instead of
applied live. -
Multi-language message system:
lang/en_US.yml(default/fallback) and
lang/de_DE.yml,YamlLocaleMessageServicewith a fallback chain
(active locale →en_US→ a visible[missing: ...]marker with a
one-time debug log),ComponentMessagesas a MiniMessage renderer for
in-game output, kept separate from plain string resolution (for web
reuse). -
Tests for the settings/localization system: defaults, invalid values
(parse/validation errors → fallback instead of a crash), enum parsing,
duration parsing, duplicate setting keys, locale fallback, parameter
interpolation. -
DatabaseHealth(DISCONNECTED/CONNECTING/READY/FAILED),
tracked byStorageServiceand mapped onto the existing
ComponentStatusinUniversalAdmin#status()- see
docs/architecture/storage.md#health. -
SQLite pragmas in
DataSourceFactory(journal_mode=WAL,
synchronous=NORMAL,foreign_keys=on,busy_timeout=5000). -
Transactions(dev.universaladmin.storage) - a helper for repository
methods that need to run multiple statements atomically (commit/
rollback) over one connection. -
StorageException- a generic unchecked wrapper forSQLExceptionin
the storage foundation itself (StorageService,Transactions). -
docs/user/database.md- user documentation for SQLite vs.
MySQL/MariaDB (when which, creating a MySQL user, behavior on startup
failure, backups). -
Tests:
StorageServiceTest(SQLite init, health states, failure on an
invalid path),TransactionsTest(commit, rollback on error),
JdbcPlayerProfileRepositoryTest(the repository foundation end to
end against a real SQLite database), database-type parsing in
SettingTypesTest, an explicit "no duplicate migration run" assertion
inMigrationRunnerTest. -
A reusable in-game GUI framework (
dev.universaladmin.gui):
AbstractGuiPage/AbstractListGuiPage(navigation, permission-driven
visibility, pagination, async loading with loading/empty/error state),
GuiSession/GuiSessionManager(per-player state with no held
Playerreferences, cleanup on disconnect/a real inventory close),
GuiListeneras the single, centrally registered click/drag handler,
GuiLayout/Paginationas pure, tested slot/pagination logic,
IconProvider/MaterialIconProvideras the central material
resolution,ConfirmationDialog(danger level NORMAL/WARNING/
DANGEROUS),SelectionDialog,GuiTextInput(a free-text/search flow
via the Paper dialog API instead of packet hacks/anvil/sign) - see
docs/development/gui-framework.md. -
MainMenuPage: the/adminmain menu with one button per built-in
module, filtered by actualModuleState.ENABLEDand permission;
PlaceholderGuiPageas the "not built yet" target page per module. A
new permissionuniversaladmin.menu.open. -
ModuleDescriptor.icon()set for all eight built-in modules
(previouslynulleverywhere, seeGuiIcon). -
Tests for the GUI framework:
PaginationTest,GuiLayoutTest,
GuiSessionTest,GuiSessionManagerTest,GuiButtonVisibilityTest,
GuiClickContextTest(the navigation stack),GuiListenerTest
(click cancel/dispatch, close/quit cleanup). -
GuiView#onChange- a live-sync hookGuiListenerruns one tick after a
click/drag it let through, on top of the existingonClose. Used by the
Players module's inventory/ender chest editors and the new Staff-Mode
Ender Chest Inspector tool so an edit mirrors onto the real target
immediately instead of only when the viewer closes the GUI. -
Staff-Mode Ender Chest Inspector tool (
EnderChestInspectorPage),
alongside a now-live (not read-only) Inventory Inspect...