Skip to content

dev#69

Open
EarthCow wants to merge 16 commits into
masterfrom
dev
Open

dev#69
EarthCow wants to merge 16 commits into
masterfrom
dev

Conversation

@EarthCow

Copy link
Copy Markdown
Contributor

No description provided.

@coderabbitai

coderabbitai Bot commented May 30, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 0332b3da-225f-4586-af04-ffc20863f83e

📥 Commits

Reviewing files that changed from the base of the PR and between 9424faf and 6fcf026.

📒 Files selected for processing (2)
  • src/main/java/xyz/earthcow/networkjoinmessages/common/abstraction/CorePlayer.java
  • src/main/java/xyz/earthcow/networkjoinmessages/common/listeners/CorePlayerListener.java
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/main/java/xyz/earthcow/networkjoinmessages/common/listeners/CorePlayerListener.java

📝 Walkthrough

New Features

  • Added GitHub Actions workflow to publish releases to Modrinth (publishes build/libs/*.jar, uses secrets.MODRINTH_TOKEN and vars.MODRINTH_PROJECT_ID, uses release tag and body for version/changelog, sets loaders: velocity and bungeecord, game version: >=1.8)

Improvements

  • Strengthened disconnect handling to validate player identity and avoid processing missing or duplicate player instances; debug logs added when disconnects are ignored
  • Simplified connection-state logic by moving tracking to CorePlayer: join/leave flows now use CorePlayer.isConnected()/setConnected()
  • Replaced manual disconnect-flag handling with an atomic markDisconnecting() to prevent duplicate disconnect processing
  • PlayerListener implementations now accept and use platform-specific loggers to emit connection and identity debug messages

Development

  • Removed ServerType enum and removed getCore() and getServerType() methods from CorePlugin and platform main classes (BungeeMain, VelocityMain)
  • Removed connection-tracking APIs from PlayerStateStore and deleted related unit tests in PlayerStateStoreTest
  • Converted CorePlayer connected/disconnecting fields to AtomicBoolean; disabled Lombok accessors for those fields and added explicit isConnected(), setConnected(boolean), and markDisconnecting() methods
  • Updated platform PlayerListener constructors to accept platform logger instances (BungeeLogger / VelocityLogger)

Walkthrough

This PR moves player connection state into CorePlayer, updates listeners to read/write that flag, removes connection-tracking APIs and ServerType/CorePlugin methods, injects Bungee/Velocity loggers into platform listeners with stricter disconnect validation, removes related tests, and adds a Modrinth publish workflow.

Changes

Connection State Refactoring and Platform Integration

Layer / File(s) Summary
Player connection state migration
src/main/java/xyz/earthcow/networkjoinmessages/common/abstraction/CorePlayer.java, src/main/java/xyz/earthcow/networkjoinmessages/common/listeners/CorePlayerListener.java, src/main/java/xyz/earthcow/networkjoinmessages/common/abstraction/CorePlugin.java, src/main/java/xyz/earthcow/networkjoinmessages/common/player/PlayerStateStore.java
CorePlayer gains atomic connected and disconnecting flags with isConnected(), setConnected(...), and markDisconnecting(); CorePlayerListener now uses those methods; PlayerStateStore online tracking and isConnected/setConnected APIs removed; CorePlugin no longer declares getCore()/getServerType().
BungeeMain platform integration
src/main/java/xyz/earthcow/networkjoinmessages/bungee/BungeeMain.java, src/main/java/xyz/earthcow/networkjoinmessages/bungee/listeners/PlayerListener.java
BungeeMain registers PlayerListener with a BungeeLogger; Bungee PlayerListener constructor now accepts the logger and ignores disconnects for missing/identity-mismatched CorePlayer, logging the ignore; getCore()/getServerType() overrides removed.
VelocityMain platform integration
src/main/java/xyz/earthcow/networkjoinmessages/velocity/VelocityMain.java, src/main/java/xyz/earthcow/networkjoinmessages/velocity/listeners/PlayerListener.java
VelocityMain registers PlayerListener with a VelocityLogger; Velocity PlayerListener constructor now accepts the logger and ignores disconnects for missing/identity-mismatched CorePlayer, logging the ignore; getCore()/getServerType() overrides removed.
Test cleanup and Modrinth publishing workflow
src/test/java/xyz/earthcow/networkjoinmessages/common/player/PlayerStateStoreTest.java, .github/workflows/publish-modrinth.yml
Removes tests for PlayerStateStore connection APIs; adds publish-modrinth.yml workflow publishing build/libs/*.jar to Modrinth on GitHub Release using JDK 21 and configured loaders/game version.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Poem

A player keeps its state within its chest,
Quiet flags that race and settle true,
Platform loggers nod and drop the rest,
Tests trimmed, releases push to Modrinth’s view,
Small changes hum — the network smiles anew.

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 inconclusive)

Check name Status Explanation Resolution
Title check ❓ Inconclusive The title 'dev' is vague and non-descriptive, failing to convey any meaningful information about the changeset's actual purpose. Replace with a clear, descriptive title summarizing the main change (e.g., 'Migrate connection state tracking from PlayerStateStore to CorePlayer' or 'Remove ServerType enum and refactor plugin interface').
✅ Passed checks (2 passed)
Check name Status Explanation
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch dev

Comment @coderabbitai help to get the list of available commands and usage tips.

@EarthCow EarthCow marked this pull request as ready for review June 13, 2026 02:59

@coderabbitai coderabbitai 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.

🧹 Nitpick comments (3)
.github/workflows/publish-modrinth.yml (2)

26-27: ⚡ Quick win

Consider adding Gradle dependency caching.

Adding Gradle caching would significantly speed up builds by caching dependencies between workflow runs.

⚡ Proposed addition for Gradle caching
       - name: Set up JDK 21
         uses: actions/setup-java@v4
         with:
           java-version: '21'
           distribution: 'temurin'
+          cache: 'gradle'

       - name: Build with Gradle
         run: ./gradlew build
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/publish-modrinth.yml around lines 26 - 27, The workflow
currently runs the step named "Build with Gradle" which executes "./gradlew
build" without caching; add a cache step (using actions/cache@v4) before that
step to cache Gradle artifacts (e.g., paths like ~/.gradle/caches and
~/.gradle/wrapper) and use a key that includes the OS and the Gradle wrapper
checksum (or JAVA version plus wrapper checksum) so cached dependencies are
restored on subsequent runs and invalidated when the wrapper changes; ensure the
cache step is placed immediately before the "Build with Gradle" step and
references the same working-directory/context as the build command.

16-16: 💤 Low value

Consider pinning actions to commit SHAs for enhanced security.

The static analysis tool flags that actions are not pinned to commit hashes. While version tags (like @v4) are commonly used, pinning to specific commit SHAs provides better protection against supply chain attacks where a version tag could be moved to malicious code.

🔒 Example of SHA pinning
     steps:
-      - uses: actions/checkout@v4
+      - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
         with:
           persist-credentials: false

       - name: Set up JDK 21
-        uses: actions/setup-java@v4
+        uses: actions/setup-java@8df1039502a15bceb9433410b1a100fbe190c53b # v4
         with:
           java-version: '21'
           distribution: 'temurin'

       - name: Publish to Modrinth
-        uses: cloudnode-pro/modrinth-publish@v2
+        uses: cloudnode-pro/modrinth-publish@<commit-sha> # v2

Note: You'll need to look up the current commit SHAs for each action version.

Also applies to: 21-21, 30-30

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/publish-modrinth.yml at line 16, Replace loose action tags
with pinned commit SHAs: find the action usages such as "uses:
actions/checkout@v4" (and any other "uses: ...@<tag>" instances flagged) and
replace the version tag with the exact commit SHA for that release (e.g., "uses:
actions/checkout@<commit-sha>"); fetch the current commit SHA for each action
release from the action's repository and update the workflow to use the
SHA-pinned reference to improve supply-chain security.

Source: Linters/SAST tools

src/main/java/xyz/earthcow/networkjoinmessages/common/abstraction/CorePlayer.java (1)

14-16: ⚡ Quick win

Consider making connected and disconnecting volatile for thread visibility.

Both fields are accessed across multiple threads—connected is checked in async tasks and disconnect handlers, while disconnecting uses a check-then-act pattern. Without volatile, changes made by one thread may not be visible to others, leading to potential stale reads.

🔒 Proposed fix for thread visibility
     // Fields
-    private boolean connected = false;
+    private volatile boolean connected = false;
     private CoreBackendServer lastKnownConnectedServer;
-    private boolean disconnecting = false;
+    private volatile boolean disconnecting = false;
     private String cachedLeaveMessage;
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@src/main/java/xyz/earthcow/networkjoinmessages/common/abstraction/CorePlayer.java`
around lines 14 - 16, The fields connected and disconnecting in CorePlayer are
accessed from multiple threads; make them thread-visible by declaring them
volatile (change "private boolean connected" and "private boolean disconnecting"
to volatile). For the check-then-act usage of disconnecting also consider using
an AtomicBoolean (replace disconnecting with an AtomicBoolean field and use
compareAndSet in places that test-and-set) to ensure atomicity; update all
references to use either the volatile boolean or AtomicBoolean API
(get/set/compareAndSet) consistently.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In @.github/workflows/publish-modrinth.yml:
- Around line 26-27: The workflow currently runs the step named "Build with
Gradle" which executes "./gradlew build" without caching; add a cache step
(using actions/cache@v4) before that step to cache Gradle artifacts (e.g., paths
like ~/.gradle/caches and ~/.gradle/wrapper) and use a key that includes the OS
and the Gradle wrapper checksum (or JAVA version plus wrapper checksum) so
cached dependencies are restored on subsequent runs and invalidated when the
wrapper changes; ensure the cache step is placed immediately before the "Build
with Gradle" step and references the same working-directory/context as the build
command.
- Line 16: Replace loose action tags with pinned commit SHAs: find the action
usages such as "uses: actions/checkout@v4" (and any other "uses: ...@<tag>"
instances flagged) and replace the version tag with the exact commit SHA for
that release (e.g., "uses: actions/checkout@<commit-sha>"); fetch the current
commit SHA for each action release from the action's repository and update the
workflow to use the SHA-pinned reference to improve supply-chain security.

In
`@src/main/java/xyz/earthcow/networkjoinmessages/common/abstraction/CorePlayer.java`:
- Around line 14-16: The fields connected and disconnecting in CorePlayer are
accessed from multiple threads; make them thread-visible by declaring them
volatile (change "private boolean connected" and "private boolean disconnecting"
to volatile). For the check-then-act usage of disconnecting also consider using
an AtomicBoolean (replace disconnecting with an AtomicBoolean field and use
compareAndSet in places that test-and-set) to ensure atomicity; update all
references to use either the volatile boolean or AtomicBoolean API
(get/set/compareAndSet) consistently.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 7c083dac-a357-4975-a40f-8cff0d1e6f7c

📥 Commits

Reviewing files that changed from the base of the PR and between dfb2511 and 970bf26.

📒 Files selected for processing (11)
  • .github/workflows/publish-modrinth.yml
  • src/main/java/xyz/earthcow/networkjoinmessages/bungee/BungeeMain.java
  • src/main/java/xyz/earthcow/networkjoinmessages/bungee/listeners/PlayerListener.java
  • src/main/java/xyz/earthcow/networkjoinmessages/common/abstraction/CorePlayer.java
  • src/main/java/xyz/earthcow/networkjoinmessages/common/abstraction/CorePlugin.java
  • src/main/java/xyz/earthcow/networkjoinmessages/common/abstraction/ServerType.java
  • src/main/java/xyz/earthcow/networkjoinmessages/common/listeners/CorePlayerListener.java
  • src/main/java/xyz/earthcow/networkjoinmessages/common/player/PlayerStateStore.java
  • src/main/java/xyz/earthcow/networkjoinmessages/velocity/VelocityMain.java
  • src/main/java/xyz/earthcow/networkjoinmessages/velocity/listeners/PlayerListener.java
  • src/test/java/xyz/earthcow/networkjoinmessages/common/player/PlayerStateStoreTest.java
💤 Files with no reviewable changes (4)
  • src/main/java/xyz/earthcow/networkjoinmessages/common/abstraction/ServerType.java
  • src/main/java/xyz/earthcow/networkjoinmessages/common/abstraction/CorePlugin.java
  • src/main/java/xyz/earthcow/networkjoinmessages/common/player/PlayerStateStore.java
  • src/test/java/xyz/earthcow/networkjoinmessages/common/player/PlayerStateStoreTest.java

@coderabbitai coderabbitai 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.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In
`@src/main/java/xyz/earthcow/networkjoinmessages/common/abstraction/CorePlayer.java`:
- Around line 14-16: The disconnect dedupe is racy because CorePlayer uses a
volatile boolean 'disconnecting' checked by isDisconnecting() then set via
setDisconnecting(true); replace the boolean with an AtomicBoolean (e.g., private
final AtomicBoolean disconnecting) and change callers (like
CorePlayerListener.onDisconnect) to use disconnecting.compareAndSet(false, true)
(or provide a new method on CorePlayer, e.g., beginDisconnect() that returns
boolean) so only the thread that transitions false->true proceeds with cleanup;
update isDisconnecting()/setDisconnecting() semantics or remove setDisconnecting
to rely on the atomic compare-and-set.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 33a13074-1e85-4136-b269-d87687aaf966

📥 Commits

Reviewing files that changed from the base of the PR and between 970bf26 and 91308ea.

📒 Files selected for processing (1)
  • src/main/java/xyz/earthcow/networkjoinmessages/common/abstraction/CorePlayer.java

Comment thread src/main/java/xyz/earthcow/networkjoinmessages/common/abstraction/CorePlayer.java Outdated

@coderabbitai coderabbitai 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.

🧹 Nitpick comments (1)
src/main/java/xyz/earthcow/networkjoinmessages/common/abstraction/CorePlayer.java (1)

16-16: ⚡ Quick win

Check-then-set pattern on connected could race under concurrent connects.

The connected field uses volatile boolean with the same check-then-set pattern (isConnected()setConnected(true)) that existed with the old disconnecting field. If two onServerConnected events fire concurrently for the same player, both could see !isConnected() as true and both run handleJoin, causing duplicate join processing.

Platform event systems typically serialize per-player events, so this may not happen in practice, but it's not guaranteed at the type level. If join duplication is a concern, consider using the same atomic pattern as disconnecting:

♻️ Optional atomic pattern for connected state
-    private volatile boolean connected = false;
+    `@Getter`(AccessLevel.NONE) `@Setter`(AccessLevel.NONE)
+    private AtomicBoolean connected = new AtomicBoolean(false);
+    
+    public boolean markConnected() {
+        return connected.compareAndSet(false, true);
+    }
+    
+    public boolean isConnected() {
+        return connected.get();
+    }
+    
+    public void setConnected(boolean value) {
+        connected.set(value);
+    }

Then update CorePlayerListener.handleJoin to use if (player.markConnected()) { /* first connect wins */ }.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@src/main/java/xyz/earthcow/networkjoinmessages/common/abstraction/CorePlayer.java`
at line 16, The connected field currently uses a volatile boolean with a
check-then-set pattern (isConnected() → setConnected(true)) which can race;
replace it with an AtomicBoolean (or equivalent) and add an atomic helper like
markConnected() that does return connected.compareAndSet(false, true), update
any getters/setters (isConnected()/setConnected) to use the AtomicBoolean, and
change CorePlayerListener.handleJoin to call if (player.markConnected()) { /*
first connect wins */ } so only the first concurrent connect executes
handleJoin.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In
`@src/main/java/xyz/earthcow/networkjoinmessages/common/abstraction/CorePlayer.java`:
- Line 16: The connected field currently uses a volatile boolean with a
check-then-set pattern (isConnected() → setConnected(true)) which can race;
replace it with an AtomicBoolean (or equivalent) and add an atomic helper like
markConnected() that does return connected.compareAndSet(false, true), update
any getters/setters (isConnected()/setConnected) to use the AtomicBoolean, and
change CorePlayerListener.handleJoin to call if (player.markConnected()) { /*
first connect wins */ } so only the first concurrent connect executes
handleJoin.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: d322dede-5d53-4755-8cdf-670b124e527b

📥 Commits

Reviewing files that changed from the base of the PR and between 91308ea and 9424faf.

📒 Files selected for processing (2)
  • src/main/java/xyz/earthcow/networkjoinmessages/common/abstraction/CorePlayer.java
  • src/main/java/xyz/earthcow/networkjoinmessages/common/listeners/CorePlayerListener.java
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/main/java/xyz/earthcow/networkjoinmessages/common/listeners/CorePlayerListener.java

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