Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ support.
- Automated, modularized backup creation
- Fast, asynchronous, multithreaded task execution
- Have synchronized (shared) folders
- Native Minecraft client profiles, server browser and local virtual worlds — see the [launcher guide](./docs/native-launcher.md).
- Web-Panel for starting, stopping restarting the server and viewing the last updating results summaries

Premium [AutoPlug-Web](https://autoplug.one) features:
Expand Down
69 changes: 69 additions & 0 deletions docs/authentication-lifecycle.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
# Microsoft sign-in lifecycle regression

Based on PR #297 revision `fdc3c95d3ed6454874e0a9bfdb5e474366869ca6` by AntonSelin.
The native launcher/profile/dashboard implementation remains that existing MIT contribution.
This small supplemental patch and regression fixtures were written and reviewed by an AI agent;
no separate human review or human acceptance test is claimed. PR #298 was read for comparison;
none of its source was copied into this patch. No HMCL code or new dependencies are introduced.

## Defect and behavior

The modeless sign-in dialog allows another account choice while authentication is pending.
The original service installs the result unconditionally, so sign-in A can overwrite an offline
choice, or replace newer sign-in B if A finishes last. Closing the device dialog does not cancel
the service. Obsolete results can also change the persisted selected account and save credentials.

Each account intent now reserves a generation before the dashboard queues its worker. New sign-in,
offline selection, dialog Cancel/close and dashboard/service shutdown invalidate the earlier intent
and interrupt its polling worker. Device instructions and account persistence check the generation;
UI callbacks check a separate display generation. A late network result that ignores interruption
cannot commit. A queued older offline worker cannot cancel a newer sign-in. Changed Microsoft app
ID or credential persistence preferences cancel active sign-in. Cancellation does not mark a newer
operation's progress as failed. The original single-argument sign-in/offline service APIs remain usable.

Interruption stops sleeping polling. It does not guarantee immediate abort of an already executing
OkHttp HTTP call; existing connect/read timeouts still bound that call. The generation check prevents
its late response from changing state. This change does not refactor token-refresh locking or establish
transactional disk rollback if persisting a valid account fails.

## Reproduction and verification

`LauncherAuthenticationRaceTest` runs real `LauncherServices` state/persistence operations with a
latched fake `MicrosoftAccountService`. One fixture deliberately ignores interruption, so merely
interrupting a worker cannot satisfy the regression. Tests cover A→offline→A completion, A/B reverse
completion, cancellation, shutdown, delayed device instructions, stale queued sign-in/offline requests,
interruptible polling, changed auth preferences, and a valid current login. Test credentials and paths
are synthetic. All discovery is pointed at an explicit temporary Minecraft directory.

The baseline uses the original account state logic with only injectable-provider constructor plumbing
and backwards-compatible interface defaults, so the same tests compile. Its authentication methods,
offline method, close method and UI remain unchanged. It fails nine of ten cases, while the current-login
control passes. The patched service passes all ten.

`DashboardAuthenticationLifecycleTest` creates native Swing windows with a fake `LauncherActions`,
programmatically clicks actual buttons, answers the synthetic device-start confirmation, sends a native
window-closing event, and supplies delayed callbacks. It verifies repeated login selection, window close,
offline selection, and completion progress. It uses no real authentication or browser. Its image artifacts
are Swing renders of live native-peer windows, not photographs or OS screenshots. Service persistence
is tested separately above; the UI fixture is not an end-to-end Microsoft protocol test.

Typical commands after resolving existing Maven dependencies:

```sh
mvn -o -Djava.awt.headless=true \
-Dtest=LauncherAuthenticationRaceTest,MicrosoftAccountServiceTest,DashboardPanelTest test
mvn -o -Djava.awt.headless=false \
-Dtest=DashboardAuthenticationLifecycleTest,DashboardDisplayableTest test
```

The prepared workspace uses a checksum-verified portable JDK 21 and Maven 3.9.11, explicit blank Maven
settings, its own local dependency repository and `user.home`, and no `Main` invocation. Headless tests
run under the restricted environment with Maven offline. Native tests need desktop access; the first
restricted native attempt terminated the JVM (exit 134), then the explicitly scoped approved native run
succeeded. No automatic approval rejection occurred.

Validation covers Java 9 release compilation, ten service regressions, five existing auth fixtures,
sixteen existing dashboard cases and four native cases. It does not validate real Microsoft login,
Minecraft gameplay/mod compatibility, authenticated server admission, real-router sharing or all #296
acceptance requirements. No game/server artifacts, EULA acceptance, port mapping or payment action
are involved. This supplemental patch alone is not a complete bounty implementation.
152 changes: 152 additions & 0 deletions docs/derived-verification.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
# Derived authentication, world startup and profile validation fixes

This derived contribution builds on AntonSelin's PR #297, commit
`fdc3c95d3ed6454874e0a9bfdb5e474366869ca6`, and the repository's MIT license.
ithyme7's PR #298, commit `cb16ea15d4aeb2e9f35ec3f019bc449c204390dd`, was
reviewed for comparable authentication and world cancellation designs. Its
implementation was not copied into this delta. The inherited launcher,
profiles, dashboard, world orchestration and previews remain the original
contributors' work.

AI coding agents wrote and directly source-reviewed this delta and ran its
automated and native Swing fixture checks. No separate human technical review,
human gameplay test, real Microsoft sign-in or real router validation is claimed.
Issue #296 delegates the final live authenticated join to maintainers. Passing
these checks does not establish maintainer acceptance, merge or bounty payment.

## Behavior

- A cancelled or superseded Microsoft sign-in cannot replace the current
account or persisted choice. See [authentication-lifecycle.md](authentication-lifecycle.md).
- `WorldService` registers a pending owner before installation. Stop and service
close invalidate and interrupt it even before a running session exists.
Late installer, readiness, process-factory and client results are checked;
owned processes and locks are cleaned up rather than publishing a late session.
A cancelled but unfinished collaborator retains its ownership until it returns.
- Profiles validate type/loader compatibility at create, save and read. A
PLUGINS collection requires a plugin loader; vanilla server collections use
MODS_SERVER. Client/server mod collections reject plugin loaders. Create and
clone dialogs filter choices using the same rule. Previously saved invalid
metadata produces an explicit error; it is not rewritten or silently discarded.
- The offline client fixture compares filesystem identity rather than literal
working-directory spelling, accommodating macOS `/var` versus `/private/var`
while still rejecting a different launch directory.

## Relevant new regressions

`LauncherAuthenticationRaceTest`, `DashboardAuthenticationLifecycleTest`,
`WorldStartupCancellationTest`, `ProfileLoaderCompatibilityTest`,
`DashboardProfileCompatibilityTest`, and `ManagedWorldStartupNativeTest` use
fake auth/installers or original harmless process fixtures. Delayed collaborators
intentionally ignore interruption, so tests require invalidation as well as an
interrupt signal. The native profile dialog persists through actual ProfileStore;
the native Stop buttons call actual WorldService.

Synthetic EULA flags belong only to temporary test metadata. Real Minecraft
servers are never launched by these tests. Production EULA guards remain in
place. The packaged CLI smoke refuses unaccepted-world launch before installation;
the packaged-wrapper smoke starts original tiny JVM servers without an eula.txt.

Native tests must run separately with `-Djava.awt.headless=false`; a headless
skip is not a native test pass. Native peer paint images and offscreen previews
show component layout; process/account assertions establish fixture behavior.

Existing selected suites cover profile isolation and migration, provider errors,
disable summaries, actual MineStat/NBT responses, manifests and loader metadata,
offline client JVM arguments/cache, UPnP local SOAP/forwarder ownership, managed
child cleanup, default utility staging, chooser/history/fullscreen arguments,
progress and UI layout. External-network/SteamCMD/download suites are not included
in the deterministic selection. Runtime compile targets remain Java 9, with the
inherited legacy world helper targeting Java 8.

## Remaining limits

In-flight non-cooperative HTTP/installer operations may finish before the caller
can release their resources, but cancellation rejects their late launch results.
Long service monitors in inherited launcher/settings code and server readiness
version verification remain review areas outside this delta. This is not a general
launch parallelism rewrite or a promise of immediate cancellation of every IO call.

Game/utility-pack play, true save load/preservation in Minecraft, real loader
processors against game artifacts, real Microsoft entitlement/join and router/WAN
reachability still require appropriate acceptance testing. Real publisher JSON
and metadata-only production parser checks do not execute game or loader code.

## Executed validation

The AI agent executed these checks on macOS with checksum-verified JDK 21 and
Maven 3.9.11, using isolated data/home directories and Maven dependencies:

- 210 selected deterministic test cases passed, zero failures/errors/skips.
- 6 native Swing cases passed separately, zero failures/errors/skips.
- Offline Maven packaging passed with Java 9 and legacy-helper Java 8 targets.
- The 12 new world/profile regressions against unmodified #297 behavior produced
10 assertion failures, one blocked-close timeout, and one passing positive control;
all 12 pass with this delta. The earlier auth baseline fails nine of ten, with
the current-login control passing. Original auth/UI coverage remains included.
- The actual packaged CLI passed invalid-profile guards, version periods,
empty-profile clone/migration, offline selection, world creation and refusal
to launch an unaccepted world before installation.
- The inherited `ManagedWorldPackagedSmoke` started two actual packaged AutoPlug
wrappers around original tiny JVM servers, verifying command isolation, restart,
graceful stop and wrapper exit after the raw server stopped. No game server
binary or real EULA was involved. Native/wrapper checks blocked non-loopback
traffic using a supplemental OS policy and IPv4 loopback configuration.
- Read-only public Mojang/Fabric/Modrinth JSON probes returned HTTP 200;
published Mojang metadata SHA1 values matched. A production metadata-only
parser read 1.21.1 and 26.3 as Java 21 and 25. No game/mod/loader/runtime
artifact was installed or executed by these metadata probes.

[Per-suite results](verification/derived-results.json) omit raw Maven environment
properties, local paths and credentials. The exact deterministic selector is in
[derived-test-selector.txt](verification/derived-test-selector.txt).
No inherited author test counts are added to these 216 executed cases.

After preparing the existing Maven dependencies in a reviewed environment:

```sh
selector=$(cat docs/verification/derived-test-selector.txt)
mvn -o -Djava.awt.headless=true "-Dtest=$selector" package
mvn -o -Djava.awt.headless=false \
-Dtest=DashboardAuthenticationLifecycleTest,DashboardDisplayableTest,DashboardProfileCompatibilityTest,ManagedWorldStartupNativeTest test
```

The native suite requires a desktop; a headless skip must not be reported as a
pass. For packaged offline-world reproduction, run the inherited smoke helper
with the packaged JAR and test classes after reviewing its source:

```sh
fixture_root=$(mktemp -d)
JAVA_TOOL_OPTIONS="-Duser.home=$fixture_root/home -Djava.net.preferIPv4Stack=true" \
java -cp target/test-classes:target/AutoPlug-Client.jar \
com.osiris.autoplug.client.worlds.ManagedWorldPackagedSmoke "$PWD" "$fixture_root/worlds"
```

Do not use raw local Maven logs as public evidence: they contain execution paths
and environment properties. No payout address, credentials, game JAR or local
user files are part of this contribution. Full local logs remain available for
private verification; the public summary only reports checks actually executed.

## Native fixture images

These are component paints of live native-peer windows with synthetic data,
not human screenshots or gameplay evidence. The auth baseline intentionally
shows the stale-login defect after closing the dialog.

![Auth baseline after close](images/derived-verification/baseline-after-close.png)
![Auth fixed after close](images/derived-verification/fixed-after-close.png)
![Pending world before Stop](images/derived-verification/world-preparation-before-stop.png)
![Cancelled world after Stop](images/derived-verification/world-preparation-after-stop.png)
![Compatible plugin profile dialog](images/derived-verification/profile-plugin-dialog.png)

## Submission and acceptance

This derived draft requests maintainer feedback and final acceptance validation
for [#296](https://github.com/Osiris-Team/AutoPlug-Client/issues/296), including
[the maintainer's final authenticated join arrangement](https://github.com/Osiris-Team/AutoPlug-Client/issues/296#issuecomment-5972762400).
It does not claim all gameplay/UX acceptance is complete or a bounty is earned.
The original author remains active; this is not an abandonment claim. Current
bounty terms and the original contributor's seven-calendar-day grace period,
when initiated by a maintainer for a merge-ready derived PR, remain applicable.
Draft submission alone is not claimed to start that period. No payout information
or profile edit is requested or included.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/images/native-launcher/launch-chooser.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/images/native-launcher/managed-console.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/images/native-launcher/overall-progress.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/images/native-launcher/profiles-compact.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/images/native-launcher/profiles-dark.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/images/native-launcher/profiles.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/images/native-launcher/server-browser.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/images/native-launcher/settings-compact.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/images/native-launcher/settings-dark.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/images/native-launcher/settings.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/images/native-launcher/virtual-worlds.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/images/native-launcher/worlds-compact.png
Binary file added docs/images/native-launcher/worlds.png
Loading