Skip to content

Add shared platform services with Bukkit/Folia adapters - #319

Merged
BenCodez merged 2 commits into
masterfrom
codex/shared-platform-services
Sep 12, 2026
Merged

BenCodez merged 2 commits into
masterfrom
codex/shared-platform-services

Conversation

@BenCodez

@BenCodez BenCodez commented Sep 12, 2026 •

Copy link
Copy Markdown
Owner

Summary

Task 2 of the Fabric/Forge/NeoForge preparation, based on merged #318.

  • Add JDK-only PlatformServices, PlatformPlayer, and PlatformScheduler contracts for UUID-based online-session lookup, literal native permissions, rendered text, console/player commands, and distinct server-wide/player-owned scheduling.
  • Implement BukkitPlatformServices using the existing plugin-owned SimpleAPI Bukkit/Folia scheduler. Construction and owner resolution remain lazy; no new executor, listener, persistent user, player cache, or global service registry is created.
  • Extract ConsoleCommandDispatcher and wire the existing private MiscUtils.runConsoleCommand through it. The public command-list path uses the new services immediately, preserving one-leading-slash removal, parsing/logging, iteration, native dispatch, and seconds-based stagger timing.
  • Add 11 JUnit cases plus a JDK-only fixture covering shared behavior, isolated no-server loading, native adapter behavior, correct entity scheduling, stale sessions, disable, exception propagation, lazy ownership, and legacy command-list integration.

Compatibility and scope

Existing public API signatures and permission-provider helpers are unchanged. Player handles represent one online login; queued work is not redirected to a replacement login or to the global scheduler when an entity disappears. Messages and commands are already-rendered text, with no additional placeholder/script evaluation or operator privilege escalation.

Scheduling means submitted, not completed. These methods do not provide durable reward acknowledgements, persistent retries, or execution checkpoints. The platform's existing scheduler owns cancellation; this PR adds no parallel lifecycle.

One Maven project, core/Bukkit packages. No POM, workflow, dependency, storage, FLAT, user-cache, reward-queue, or loader-packaging changes. SimpleAPI remains 1.0.2-SNAPSHOT and the unwanted dependency-pinning test stays removed. #314 remains closed.

Coordination with #317: that PR also touches MiscUtils.java. This PR changes only its legacy private command-list dispatcher plus imports/field initialization. Single-command overloads and #317's async completion/checkpoint methods are not refactored here. Preserve those additions and rerun both suites when combining branches.

Verified GitHub Actions build

Java CI with Maven — run 592 passed. Inspected the completed build job 103622316990 and its actual Maven log:

  • mvn -B -f AdvancedCore/pom.xml package on Temurin Java 21.0.12.
  • 330 tests run, 0 failures, 0 errors, 0 skipped.
  • All 11 new tests passed: BukkitPlatformServicesTest (8), MiscUtilsPlatformCommandsTest (1), and PlatformServicesHeadlessTest (2), including isolated execution with server APIs absent.
  • Existing MiscUtilsTest (3) and existing reward/configuration/user/lifecycle regression tests passed.
  • Maven refreshed Nexus snapshot metadata and downloaded SimpleAPI 1.0.2-20260912.210028-21. The POM remains 1.0.2-SNAPSHOT; this timestamp records tested inputs, not a dependency pin.
  • AdvancedCore/target/AdvancedCore.jar generated; shading/minimization completed; BUILD SUCCESS.
  • Tested integration merge b81070a0e3639a0933ae2aa61f4220ca00e112ba for candidate ac0353315c587bc8b062f437fae92eb4444f1e64 and base 977a3f1e07c37fb47d457338461d73d0681f8e64.

These full Maven results are from GitHub Actions, not a local build. Shade emitted minimization/overlap warnings; successful packaging is not packaged-runtime/linkage or live-server validation.

Validation performed locally

  • Verified the original MiscUtils.java against upstream Git blob f0a8276fa23aa21636b1c540f86322bbad9b67a7 before editing.
  • Compiled the four new core production classes and JDK-only fixture with javac --release 21; ran PlatformServicesFixture: passed. This tests the actual shared dispatcher with a fake platform, not the Bukkit adapter.
  • Parsed all 10 changed/added Java sources using the JDK compiler: syntax passed. This is not full dependency/type checking.
  • git diff --cached --check passed in an exact-baseline partial repository fixture; inspected the entire intended diff and verified all 11 uploaded file blob hashes against the local copies.
  • Verified the published diff: 11 paths, 758 additions/19 deletions; the only existing production method changed is the private legacy console-list handoff.
  • Same-context source review only; no independent clean-review verdict is claimed.

Still draft / remaining validation

Full local Maven validation is blocked in this editing environment: Maven is absent and direct repository/dependency host resolution is unavailable. Local SimpleAPI -> AdvancedCore -> VotingPlugin builds against the candidate artifacts, final shaded-JAR linkage checks, live Bukkit/Paper/Folia tests, and a fresh independent review have not been performed. Mocked scheduler routing and isolated core loading do not establish live Folia or native-mod compatibility.

Base: 977a3f1e07c37fb47d457338461d73d0681f8e64.
Candidate: ac0353315c587bc8b062f437fae92eb4444f1e64.

No merge, release, deployment, or manual external review request is included.

AI assistance: ChatGPT assisted with implementation, test authoring, same-context inspection, and this description.

@BenCodez
BenCodez marked this pull request as ready for review September 12, 2026 21:24
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Sep 12, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-09-12T21:42:11.367330Z 264234e New commits
🔒 Security Review ✅ Completed 2026-09-12T21:29:18.205650Z ac03533 Draft marked ready
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: ac0353315c

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Objects.requireNonNull(playerId, "playerId");
Objects.requireNonNull(task, "task");
Player player = Bukkit.getPlayer(playerId);
if (player == null || !player.isOnline()) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Move the online check behind the player-thread handoff

runPlayer is explicitly the handoff intended for asynchronous consumers, but it calls Player.isOnline() on the caller's arbitrary thread before submitting anything to the entity scheduler. On Paper/Folia, an async caller therefore accesses a Bukkit entity outside its owning thread and may trigger thread-safety failures before the callback can be handed off; use the UUID lookup only to locate the entity and perform the session/online validation inside the scheduled callback.

AGENTS.md reference: AGENTS.md:L32-L32

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in 264234e.

runPlayer now uses UUID lookup only to locate the entity and rejects a null lookup without reading player state on the submitting thread. The existing captured-session online/identity validation remains inside the entity-scheduled callback, along with the plugin-enabled check. There is still no global fallback or redirection to a replacement login. Updated the scheduling contract to clarify that true means submitted, not confirmed online or completed.

Added two regression tests: a real worker-thread submission that fails if Player.isOnline() is called before the entity callback, and an already-disconnected lookup that is checked/rejected only within that callback. Existing disconnect, replacement, disable, and rejection coverage remains intact.

Verified Maven CI run 596, build job 103625631616: mvn -B -f AdvancedCore/pom.xml package on Java 21 passed with 332 tests, 0 failures, 0 errors, 0 skipped, including all 10 BukkitPlatformServicesTest cases. AdvancedCore.jar was generated and shading completed. Maven refreshed the snapshot and resolved SimpleAPI 1.0.2-20260912.212854-22; the POM remains 1.0.2-SNAPSHOT.

Locally, a guarded component probe reproduced the original off-thread read and passed all seven handoff scenarios after the fix; that probe uses test-only native boundary stubs, not a live Bukkit/Folia server. Java syntax and git diff --check passed, and all four changed file hashes match the uploaded commit. Full local Maven/downstream builds remain unavailable here (Maven absent and dependency-host DNS unavailable). GitHub Actions results are not represented as local/live-server validation, and shading warnings still require packaged-runtime verification.

Codex has automatically started a fresh code review of the new commit; no duplicate manual review request was posted. No merge or deployment performed.

@BenCodez
BenCodez merged commit b03cb7f into master Sep 12, 2026
4 checks passed
@BenCodez
BenCodez deleted the codex/shared-platform-services branch September 12, 2026 21:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant