Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Bug]: Multiple client instances launched after incorrect password attempts #3301

Open
magge-faf opened this issue Jan 25, 2025 · 1 comment
Labels

Comments

@magge-faf
Copy link
Collaborator

Describe the Bug

Entering incorrect passwords for a protected lobby one or more times causes that many game instances to launch when successfully joining any lobby afterwards.

Bug was reported via tech-support (Link to Discord Thread)

I can reproduce the bug as well.

Log file or Error Message

ice-adapter.log

client.log

Reproduce the bug

How to reproduce:

  1. Choose a lobby protected with password, and try to enter multiple times with wrong password
  2. Launch any public lobby or protected lobby with correct password
  3. Several SC instances will start at the same time, as many times you have entered the incorrect PW before.

Expected Behavior

Only one client instance should spawn when entering a lobby

Screenshots

Image

Image

Additional context

No response

Which Operating System are you using?

Windows

@magge-faf magge-faf added the bug label Jan 25, 2025
@Ivan-Shaml
Copy link
Member

Ivan-Shaml commented Jan 25, 2025

I think this is an issue with the recursive mess in GameRunner class (making code hard to read) and mainly the (misuse of) observable mechanism in Mono.

  1. Let's take a look at this method (FafLobbyClient#requestJoinGame)

faf-java-commons#FafLobbyClient

  1. And FafLobbyClient#requestJoinGame is invoked in:

public CompletableFuture<GameLaunchResponse> requestJoinGame(int gameId, String password) {
return lobbyClient.requestJoinGame(gameId, password).toFuture();
}

  1. And FafServerAccessor#requestJoinGame method is invoked in:

prepareAndLaunchGameWhenReady(game.getFeaturedMod(), simModUIds, game.getMapFolderName(),
() -> fafServerAccessor.requestJoinGame(game.getId(), password)).exceptionally(
throwable -> {
log.error("Game could not be joined", throwable);
notificationService.addImmediateErrorNotification(throwable, "games.couldNotJoin");
return null;
});

3.1. and effectively here (line 225) =>

CompletableFuture<Void> prepareAndLaunchGameWhenReady(String featuredModName, Set<String> simModUids,
@Nullable String mapFolderName,
Supplier<CompletableFuture<GameLaunchResponse>> gameLaunchSupplier) {
CompletableFuture<Void> updateFeaturedModFuture = featuredModService.updateFeaturedModToLatest(featuredModName,
false);
CompletableFuture<Void> installSimModsFuture = simModUids.isEmpty() ? completedFuture(
null) : modService.downloadAndEnableMods(simModUids).toFuture();
CompletableFuture<Void> downloadMapFuture = mapFolderName == null || mapFolderName.isBlank() ? completedFuture(
null) : mapService.downloadIfNecessary(mapFolderName).toFuture();
return CompletableFuture.allOf(updateFeaturedModFuture, installSimModsFuture, downloadMapFuture)
.thenCompose(ignored -> gameLaunchSupplier.get())
.thenCompose(this::startOnlineGame);
}

And it blocks until the server emmits GameLaunchResponse.class, but instead on wrong password it emits NoticeInfo.class, thus the CompletableFuture, hasn't completed yet, since it filters out this type of response.

And the more you click to join game and type in wrong password, the more subscribers/CompletableFuture stack up.

When you finally make the server return GameLaunchResponse (by successfully joining a game), all subscribers receive it, the CompletableFutures gets resolved => multiple(=number of subscribers) instances get launched with the same GameLaunchResponse data (possibly causing more issues...).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants