refactor: streamline v3 architecture, unify RCON execution, and remove legacy abstractions - #73
Conversation
…al, admin-bot & abilities)
Removes deprecated global extension.useExternalPluginsOnly check from PlugwrightCorePlugin and resolves pluginJar dynamically in LocalMode based on the environment spec, preserving backward compatibility while enabling per-environment configuration in v3.
monikon22
left a comment
There was a problem hiding this comment.
It looks great - migrating @plugwright/console-rcon directly into @plugwright/runner is useful, since RCON is becoming the foundation for the framework’s interaction with the server.
I agree with you on the idea of removing abilities. I left it in only for the users’ own needs (the original plan was to assign custom tags to specific accounts so they could later be filtered from the account pool based on certain properties), which was especially useful with reuse, which we removed in #59.
The need for PlugwrightCleanupTask also goes away with the decision to use only disposable identities (#58). I also understand the decision to abandon AdminBot—using a game account as a reliable foundation for maintaining the testing pipeline turned out not to be the best idea in practice.
The journal and --cleanup should also be removed, since cleaning up accounts and environments is the responsibility of the server and plugins, not the framework itself.
As for the other changes mentioned in this PR, I fully support these decisions; the fixes seem extremely useful, as does stabilizing the requires labels by converting them to object-based ones.
My main concern with this PR was the decision to fully migrate to RCON to replace stdin: it’s true that some command responses could be “swallowed” due to asynchronous behavior, but since the proposed solution has already accounted for this, there should be no cause for concern. If any problems arise with this, they can be addressed in new issues or PRs.
LGTM!
Summary
This PR finalizes the architectural cleanup for Plugwright v3. It consolidates core components, unifies server command execution under RCON for both local and external environments, and removes obsolete, fragile abstractions (
journal,AdminBot,abilities, and the standalone cleanup task). It also fixes a configuration inheritance bug in the Gradle plugin matrix foruseExternalPluginsOnly.Key Changes & Motivation
1. Unified RCON Console (
@plugwright/runner)@plugwright/runner: Merged the former@plugwright/console-rcondirectly into@plugwright/runner(runner-package/lib/rcon/), eliminating package overhead while keeping TCP socket protocol logic self-contained.stdinwhile external mode used RCON.stdincommand execution has no request-response correlation. Output from the server is a shared log stream, meaning generic replies (e.g.,"Success","Money given.") could not be reliably attributed to the command that triggered them.stdinrisked false positives and race conditions, requiring hacky synchronization markers (likeminecraft:say sync_<uuid>).await server.execute(...)returns the exact response for that specific command./op,/deop, or/gamemodebecause Minecraft produces immediate, synchronous command output that RCON captures directly.await server.execute(...)withexpect(server).toHaveReceived(...)to assert against delayed console or broadcast logs.RconConnection, handled authentication failures cleanly, and ensured explicit socket teardown on environment shutdown.2. Removal of Legacy & Fragile Abstractions
abilities:abilitiesset onPlayerWrapperwas an in-memory client-side record (mark('op'), etc.) that never validated against real server state./deopvia the console,player.abilitieswas immediately desynced. Because it was unmaintainable and barely used in the codebase, it has been eliminated.journal&PlugwrightCleanupTask:--cleanuptask were designed around edge cases like mid-test crashes or power loss on external servers.AdminBotConsole:AdminBotattempted to emulate a console by joining an OP player and running slash commands in chat.stdin, reading responses from player chat was ambiguous, prone to mixing with test player messages, and unnecessary with native RCON available.3. Gradle Plugin Refinements (
@plugwright/gradle-plugin)useExternalPluginsOnlyMatrix Scoping:PlugwrightCorePlugincheckedextension.useExternalPluginsOnly.get()globally when creating the project JAR provider. If set totrueat the root, matrix environments attempting to override it with.set(false)were ignored because the JAR provider was already discarded globally.useExternalPluginsOnlyevaluation toLocalMode.ktvia lazy property binding (flatMap), allowing individual matrix environments to decide whether to install the project JAR or rely purely on external plugins.applyLegacyDefaults.PaperProvisionTaskduring server provisioning.4. Documentation & Examples
.mdand.mdxdocs acrossdocs/and package READMEs to reflect the unified v3 architecture.server.execute(...)calls toawait server.execute(...)in documentation and test specs.publish.js,bump-version.js).5. Test Capabilities (
requires) Refactorrequires: Migrated the test filtering syntax from custom string arrays (e.g.,requires: ['consoleOutput:full', 'op']) to idiomatic, statically-typed object maps (requires: { consoleOutput: 'full', op: true }).RequiresMapis now strictly typed againstPartial<EnvironmentCapabilities>. This provides instant IDE autocomplete and rejects typos at compile time.string[]format was removed. This eliminatednormalizeRequires()boilerplate and cleaned up the runner's skip logic.freshState,lifecycle,arbitraryUsernames) from the framework. These practically functioned as synonyms for "local mode". TheEnvironmentCapabilitiesinterface is now extremely lean, focusing purely on properties that vary dynamically per connection (console,consoleOutput,op). Tests needing destructive actions should now use{ environments: ['local'] }instead.