Release diff: master → previous_release - #12
Conversation
Upload both versioned JAR and async-anticheat.jar for easy linking
- Replace BukkitDevModeManager with RecordingManager - Add BukkitMainCommand for /aac record <player> <type> [label] - POST recordings to /observations API endpoint - Auto-stop recordings on player disconnect - Tab completion for cheat types and online players
| } | ||
| } | ||
| executor.shutdown(); | ||
| } |
There was a problem hiding this comment.
Recordings may be lost during server shutdown
The stopAll() method queues recording submissions to the executor and then calls shutdown() without awaitTermination(). Since the executor uses a daemon thread (line 40: t.setDaemon(true)), the JVM may exit before the HTTP requests complete during server shutdown, causing recordings to be lost. Daemon threads are terminated when all non-daemon threads finish, so there's no guarantee the recording submissions complete before the process exits.
| } | ||
| // Read as string for simplicity | ||
| return Optional.of(in.nextString()); | ||
| } |
There was a problem hiding this comment.
OptionalTypeAdapter read method incompatible with write output
The OptionalTypeAdapter.read() method always calls in.nextString() even though write() can output Numbers and Booleans via out.value(n) and out.value(b). If an Optional containing a Number or Boolean is serialized and later deserialized, nextString() will throw an IllegalStateException since the JSON token type won't match. While no deserialization currently uses this adapter, this creates an asymmetric read/write contract that will fail if Optional deserialization is added later.
| label, | ||
| Instant.now() | ||
| ); | ||
| activeRecordings.put(targetId, recording); |
There was a problem hiding this comment.
Race condition in startRecording check-then-act pattern
The startRecording method uses a non-atomic check-then-act pattern on a ConcurrentHashMap. It calls containsKey() on line 69 and then put() on line 82, which creates a race window where two concurrent calls for the same target could both pass the check and both insert recordings, with the second overwriting the first. Both callers would receive success, but only one recording would be tracked. The atomic putIfAbsent method would eliminate this race.
Automated PR. The 'previous_release' branch is force-updated on every push to master to point at the commit before the push, so this PR always represents the current release diff.
Note
Introduces a new in-game recording flow and streamlines release artifacts.
BukkitDevModeManager,BukkitDevModeCommand) and oldBukkitLinkCommand; addRecordingManagerandBukkitMainCommandexposing/aac record(start/stop/status) and dashboard status. Auto-stop recordings on player quit and on plugin disable. InitializeRecordingManagerwithservice.getConfig()andservice.getServerId()inAsyncAnticheatBukkitPlugin.aacdevcommand andasyncanticheat.devpermission; enhanceaaccommand; addasyncanticheat.recordpermission.OptionalTypeAdapter and exposeAsyncAnticheatService#getServerId().build/libs/async-anticheat.jarand attach both versioned and stable JARs to releases.Written by Cursor Bugbot for commit acfbd97. This will update automatically on new commits. Configure here.