
Список изменений
Wiki: https://github.com/castledking/Allium/wiki
Highlights
- CanvasMC 26.2 support — Migrated from Paper API to Canvas API (
io.canvasmc.canvas:canvas-api). Canvas is a Folia fork targeting Minecraft 26.2 (build 835). All scheduling now goes through the newSchedulerAdapterin thecodes.castled.allium.schedulerpackage, which properly handles Canvas's regionized threading model. - New SchedulerAdapter — Complete rewrite of the scheduling layer. The old
util/SchedulerAdapter.java(587 lines of reflection-heavy Folia detection) is replaced by a clean 426-linescheduler/SchedulerAdapter.javawith a dedicatedTaskHandleabstraction. The old class is kept as a deprecated thin wrapper delegating to the new one, ensuring backward compatibility. - Tab completion API — New
AlliumTabCompletionsEvent+AlliumTabCompletionsListenerthat populate tab completions with all online non-vanished players when PartyManager is enabled. Other plugins can fire this event to get Allium-aware player name suggestions. - Vault initialization guard — Fixed a race condition where
registerVaultDependentListeners()could be called multiple times if Vault initialized successfully and then the retry timer fired again. Added aregisteredboolean flag to ensure one-time registration. - FAWE removed — FastAsyncWorldEdit dependency and repositories dropped from
pom.xml. No longer a soft dependency.
Minecraft Version Support
| Version | Status |
|---|---|
| 26.2 (Canvas build 835) | Primary target |
| 26.2 (Folia) | Supported |
| 1.21.x (Paper/Spigot) | Supported via fallback |
API / Dependency Changes
pom.xml:io.papermc.paper:paper-apireplaced withio.canvasmc.canvas:canvas-apipom.xml:<paper.version>bumped from26.2.build.37-alphato26.2.build.835-alphapom.xml: Addedcanvasmc-releasesandcanvasmc-snapshotsrepositoriespom.xml: RemovedFastAsyncWorldEdit-Coredependencypom.xml: Removed IntellectualSites repositoriesplugin.yml: RemovedFastAsyncWorldEditandWorldEditfromsoftdepend
New Files
| File | Description |
|---|---|
scheduler/SchedulerAdapter.java | Full Folia/Canvas scheduling adapter with global, async, entity, and location scheduling |
scheduler/TaskHandle.java | Lightweight abstraction over BukkitTask and Folia ScheduledTask |
events/AlliumTabCompletionsEvent.java | Custom event for populating player name tab completions |
listeners/AlliumTabCompletionsListener.java | Handles the event — returns all online non-vanished players when PartyManager is enabled |
SchedulerAdapter API
The new codes.castled.allium.scheduler.SchedulerAdapter provides:
// Global (main thread equivalent)
SchedulerAdapter.runGlobal(plugin, runnable)
SchedulerAdapter.runLaterGlobal(plugin, runnable, delayTicks)
SchedulerAdapter.runRepeatingGlobal(plugin, runnable, delayTicks, periodTicks)
// Async
SchedulerAdapter.runAsyncNow(plugin, runnable)
SchedulerAdapter.runAsyncLater(plugin, runnable, delayTicks)
SchedulerAdapter.runAsyncRepeating(plugin, runnable, delayTicks, periodTicks)
// Entity (Folia entity scheduler, Bukkit fallback)
SchedulerAdapter.runEntity(plugin, entity, runnable, retired)
SchedulerAdapter.runLaterEntity(plugin, entity, runnable, delayTicks)
SchedulerAdapter.runEntityRepeating(plugin, entity, runnable, retired, delayTicks, periodTicks)
// Location (Folia region scheduler, Bukkit fallback)
SchedulerAdapter.runAtLocation(plugin, location, runnable)
SchedulerAdapter.runAtLocationLater(plugin, location, runnable, delayTicks)
SchedulerAdapter.runAtLocationRepeating(plugin, location, runnable, delayTicks, periodTicks)
// Utility
SchedulerAdapter.cancelTasks(plugin)
SchedulerAdapter.isFolia()
All methods return codes.castled.allium.scheduler.TaskHandle which wraps both BukkitTask and Folia's ScheduledTask.
Deprecated API
codes.castled.allium.util.SchedulerAdapter is now a deprecated wrapper. All methods delegate to the new codes.castled.allium.scheduler.SchedulerAdapter. Existing code continues to work but should be migrated:
| Old (util) | New (scheduler) |
|---|---|
run(task) | runGlobal(plugin, task) |
runLater(task, delay) | runLaterGlobal(plugin, task, delay) |
runTimer(task, delay, period) | runRepeatingGlobal(plugin, task, delay, period) |
runAsync(task) | runAsyncNow(plugin, task) |
runLaterAsync(task, delay) | runAsyncLater(plugin, task, delay) |
runAtEntity(entity, task) | runEntity(plugin, entity, task, null) |
runAtEntityLater(entity, task, delay) | runLaterEntity(plugin, entity, task, delay) |
Files Changed (31)
| File | Change |
|---|---|
pom.xml | Canvas API, build 835, removed FAWE, added Canvas repos |
plugin.yml | Removed FAWE/WorldEdit softdepend |
scheduler/SchedulerAdapter.java | New — full scheduling adapter |
scheduler/TaskHandle.java | New — task handle abstraction |
events/AlliumTabCompletionsEvent.java | New — tab completion event |
listeners/AlliumTabCompletionsListener.java | New — tab completion handler |
util/SchedulerAdapter.java | Rewritten as deprecated wrapper (~500 lines removed) |
PluginStart.java | Vault init guard, SchedulerAdapter migration for channel/Discord retry |
Core.java | Bukkit.getScheduler() calls replaced with SchedulerAdapter |
PregenCommand.java | SchedulerAdapter for async completion callback |
StaffChatCommand.java | SchedulerAdapter for channel switch |
InventoryManager.java | SchedulerAdapter for autosave |
FormatChatListener.java | SchedulerAdapter for phase renderer |
StaffChatListener.java | SchedulerAdapter for message redirect |
WolfBehaviorListener.java | SchedulerAdapter for delayed task |
CommandManager.java | SchedulerAdapter migration |
ConnectionManager.java | SchedulerAdapter migration, significant refactor |
FreecamDetector.java | SchedulerAdapter migration |
HandcuffsListener.java | SchedulerAdapter migration |
IPNDetector.java | SchedulerAdapter migration |
ModDetectionListener.java | SchedulerAdapter migration |
VanishListener.java | SchedulerAdapter migration |
FaweActivityListener.java | SchedulerAdapter migration, FAWE removal |
OreGenerationListener.java | SchedulerAdapter migration |
AlliumChannelManager.java | SchedulerAdapter migration |
DiscordSrvMessageBridge.java | SchedulerAdapter migration |
GradientNameManager.java | SchedulerAdapter migration |
ModGuardManager.java | SchedulerAdapter migration |
ModGuardTranslationProbe.java | SchedulerAdapter migration |
OreGenerationManager.java | SchedulerAdapter migration |
CrowBarDataSender.java | SchedulerAdapter migration |
Technical Details
Scheduler Detection
Folia/Canvas detection uses Bukkit.getServer().getClass().getMethods() to find getGlobalRegionScheduler — more reliable than string-matching server name/version. The detection result is cached in a static final boolean at class load time.
TaskHandle
Wraps either a BukkitTask (Paper/Spigot path) or a raw Folia ScheduledTask object (accessed via reflection for cancel). Thread-safe cancellation via AtomicBoolean. The isScheduled() method returns best-effort status.
Vault Initialization Fix
Previously, if initializeVault() succeeded on attempt N but the timer tick was already queued, registerVaultDependentListeners() could fire twice. The fix adds a registered[] boolean flag checked before each registration call, ensuring idempotency.
Support and Feedback
Issues: https://github.com/castledking/Allium/issues Wiki: https://github.com/castledking/Allium/wiki Discord: https://discord.com/invite/pCKdCX6nYr Website: https://castled.codes/
