Skip to content

Commit 201a74f

Browse files
authored
Use websockets for lobby connection (#3037)
1 parent ef64c1d commit 201a74f

File tree

15 files changed

+110
-64
lines changed

15 files changed

+110
-64
lines changed

build.gradle

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -292,8 +292,9 @@ dependencies {
292292
implementation("org.springframework:spring-websocket")
293293

294294
implementation("io.projectreactor.addons:reactor-extra")
295+
implementation("io.projectreactor:reactor-tools")
295296

296-
def commonsVersion = "4a3facc824"
297+
def commonsVersion = "c060e973aa54e1fa215df15c1b8bad22806d84aa"
297298

298299
implementation("com.github.FAForever.faf-java-commons:faf-commons-data:${commonsVersion}") {
299300
exclude module: 'guava'
@@ -363,4 +364,4 @@ dependencies {
363364
testCompileOnly("org.projectlombok:lombok")
364365

365366
codacy("com.github.codacy:codacy-coverage-reporter:-SNAPSHOT")
366-
}
367+
}

src/lombok.config

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
lombok.accessors.chain=true
22
config.stopBubbling=true
33
lombok.anyConstructor.addConstructorProperties=true
4+
lombok.copyableAnnotations+=org.springframework.beans.factory.annotation.Qualifier

src/main/java/com/faforever/client/api/FafApiAccessor.java

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
import com.github.jasminb.jsonapi.exceptions.ResourceParseException;
3636
import com.github.rutledgepaulv.qbuilders.builders.QBuilder;
3737
import com.github.rutledgepaulv.qbuilders.conditions.Condition;
38+
import lombok.RequiredArgsConstructor;
3839
import lombok.extern.slf4j.Slf4j;
3940
import org.jetbrains.annotations.NotNull;
4041
import org.jetbrains.annotations.VisibleForTesting;
@@ -74,6 +75,7 @@
7475
@Slf4j
7576
@Component
7677
@Profile("!offline")
78+
@RequiredArgsConstructor
7779
public class FafApiAccessor implements InitializingBean {
7880

7981
@VisibleForTesting
@@ -119,19 +121,14 @@ public class FafApiAccessor implements InitializingBean {
119121
private static final String JSONAPI_MEDIA_TYPE = "application/vnd.api+json;charset=utf-8";
120122

121123
private final ClientProperties clientProperties;
124+
@Qualifier("apiWebClient")
122125
private final ObjectFactory<WebClient> apiWebClientFactory;
123126

124127
private WebClient apiWebClient;
125128
private Retry apiRetrySpec;
126129

127130
private CountDownLatch authorizedLatch = new CountDownLatch(1);
128131

129-
public FafApiAccessor(ClientProperties clientProperties,
130-
@Qualifier("apiWebClient") ObjectFactory<WebClient> apiWebClientFactory) {
131-
this.clientProperties = clientProperties;
132-
this.apiWebClientFactory = apiWebClientFactory;
133-
}
134-
135132
@Override
136133
public void afterPropertiesSet() {
137134
Api api = clientProperties.getApi();

src/main/java/com/faforever/client/config/ClientProperties.java

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ public class ClientProperties {
2828
private Imgur imgur = new Imgur();
2929
private TrueSkill trueSkill = new TrueSkill();
3030
private Api api = new Api();
31+
private User user = new User();
3132
private Oauth oauth = new Oauth();
3233
private UnitDatabase unitDatabase = new UnitDatabase();
3334
private FAFDebugger fafDebugger = new FAFDebugger();
@@ -80,8 +81,7 @@ public static class Irc {
8081

8182
@Data
8283
public static class Server {
83-
private String host;
84-
private int port;
84+
private String url;
8585
private int retryDelaySeconds = 30;
8686
private int retryAttempts = 10;
8787
}
@@ -148,11 +148,15 @@ public static class Api {
148148
private int maxPageSize = 10000;
149149
}
150150

151+
@Data
152+
public static class User {
153+
private String baseUrl;
154+
}
155+
151156
public void updateFromEndpoint(ServerEndpoints serverEndpoints) {
152-
SocketEndpoint lobby = serverEndpoints.getLobby();
153-
if (lobby != null) {
154-
server.setHost(lobby.getHost());
155-
server.setPort(lobby.getPort());
157+
UrlEndpoint user = serverEndpoints.getUser();
158+
if (user != null) {
159+
this.user.setBaseUrl(user.getUrl());
156160
}
157161

158162
SocketEndpoint liveReplay = serverEndpoints.getLiveReplay();

src/main/java/com/faforever/client/config/WebClientConfig.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,4 +22,11 @@ public WebClient apiWebClient(WebClient.Builder webClientBuilder, OAuthTokenFilt
2222
return webClientBuilder.baseUrl(clientProperties.getApi().getBaseUrl()).filter(oAuthTokenFilter).build();
2323
}
2424

25+
@Bean
26+
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
27+
public WebClient userWebClient(WebClient.Builder webClientBuilder, OAuthTokenFilter oAuthTokenFilter,
28+
ClientProperties clientProperties) {
29+
return webClientBuilder.baseUrl(clientProperties.getUser().getBaseUrl()).filter(oAuthTokenFilter).build();
30+
}
31+
2532
}

src/main/java/com/faforever/client/login/LoginController.java

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
import com.faforever.client.config.ClientProperties;
44
import com.faforever.client.config.ClientProperties.Irc;
55
import com.faforever.client.config.ClientProperties.Replay;
6-
import com.faforever.client.config.ClientProperties.Server;
6+
import com.faforever.client.config.ClientProperties.User;
77
import com.faforever.client.fx.Controller;
88
import com.faforever.client.fx.FxApplicationThreadExecutor;
99
import com.faforever.client.fx.JavaFxUtil;
@@ -78,8 +78,7 @@ public class LoginController implements Controller<Pane> {
7878
public Label loginErrorLabel;
7979
public Pane loginRoot;
8080
public GridPane serverConfigPane;
81-
public TextField serverHostField;
82-
public TextField serverPortField;
81+
public TextField userUrlField;
8382
public TextField replayServerHostField;
8483
public TextField replayServerPortField;
8584
public TextField ircServerHostField;
@@ -201,9 +200,8 @@ private void showClientOutdatedPane(String minimumVersion) {
201200

202201
private void populateEndpointFields() {
203202
fxApplicationThreadExecutor.execute(() -> {
204-
Server server = clientProperties.getServer();
205-
serverHostField.setText(server.getHost());
206-
serverPortField.setText(String.valueOf(server.getPort()));
203+
User user = clientProperties.getUser();
204+
userUrlField.setText(user.getBaseUrl());
207205
Replay replay = clientProperties.getReplay();
208206
replayServerHostField.setText(replay.getRemoteHost());
209207
replayServerPortField.setText(String.valueOf(replay.getRemotePort()));
@@ -236,9 +234,8 @@ public void onDownloadUpdateButtonClicked() {
236234
public CompletableFuture<Void> onLoginButtonClicked() {
237235
initializeFuture.join();
238236

239-
clientProperties.getServer()
240-
.setHost(serverHostField.getText())
241-
.setPort(Integer.parseInt(serverPortField.getText()));
237+
clientProperties.getUser()
238+
.setBaseUrl(userUrlField.getText());
242239

243240
clientProperties.getReplay()
244241
.setRemoteHost(replayServerHostField.getText())

src/main/java/com/faforever/client/remote/FafServerAccessor.java

Lines changed: 23 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -37,9 +37,12 @@
3737
import lombok.extern.slf4j.Slf4j;
3838
import org.springframework.beans.factory.DisposableBean;
3939
import org.springframework.beans.factory.InitializingBean;
40+
import org.springframework.beans.factory.ObjectFactory;
41+
import org.springframework.beans.factory.annotation.Qualifier;
4042
import org.springframework.context.annotation.Lazy;
4143
import org.springframework.scheduling.TaskScheduler;
4244
import org.springframework.stereotype.Component;
45+
import org.springframework.web.reactive.function.client.WebClient;
4346
import reactor.core.publisher.Flux;
4447
import reactor.core.publisher.Mono;
4548

@@ -70,16 +73,16 @@ public class FafServerAccessor implements InitializingBean, DisposableBean {
7073
private final EventBus eventBus;
7174
private final ClientProperties clientProperties;
7275
private final FafLobbyClient lobbyClient;
76+
@Qualifier("userWebClient")
77+
private final ObjectFactory<WebClient> userWebClientFactory;
7378

7479
@Override
7580
public void afterPropertiesSet() throws Exception {
7681
eventBus.register(this);
77-
getEvents(IrcPasswordInfo.class)
78-
.doOnError(throwable -> log.error("Error processing irc password", throwable))
82+
getEvents(IrcPasswordInfo.class).doOnError(throwable -> log.error("Error processing irc password", throwable))
7983
.retry()
8084
.subscribe(this::onIrcPassword);
81-
getEvents(NoticeInfo.class)
82-
.doOnError(throwable -> log.error("Error processing notice", throwable))
85+
getEvents(NoticeInfo.class).doOnError(throwable -> log.error("Error processing notice", throwable))
8386
.retry()
8487
.subscribe(this::onNotice);
8588

@@ -119,16 +122,22 @@ public ReadOnlyObjectProperty<ConnectionState> connectionStateProperty() {
119122
}
120123

121124
public Mono<Player> connectAndLogIn() {
122-
Config config = new Config(tokenRetriever.getRefreshedTokenValue(), Version.getCurrentVersion(), clientProperties.getUserAgent(), clientProperties.getServer()
123-
.getHost(), clientProperties.getServer().getPort() + 1, sessionId -> {
124-
try {
125-
return uidService.generate(String.valueOf(sessionId));
126-
} catch (IOException e) {
127-
throw new UIDException("Cannot generate UID", e, "uid.generate.error");
128-
}
129-
}, 1024 * 1024, false, clientProperties.getServer().getRetryAttempts(), clientProperties.getServer()
130-
.getRetryDelaySeconds());
131-
return lobbyClient.connectAndLogin(config);
125+
return userWebClientFactory.getObject()
126+
.get()
127+
.uri("/lobby/access")
128+
.retrieve()
129+
.bodyToMono(LobbyAccess.class)
130+
.map(lobbyAccess -> new Config(tokenRetriever.getRefreshedTokenValue(), Version.getCurrentVersion(), clientProperties.getUserAgent(), lobbyAccess.accessUrl(), this::tryGenerateUid, 1024 * 1024, false, clientProperties.getServer()
131+
.getRetryAttempts(), clientProperties.getServer().getRetryDelaySeconds()))
132+
.flatMap(lobbyClient::connectAndLogin);
133+
}
134+
135+
private String tryGenerateUid(Long sessionId) {
136+
try {
137+
return uidService.generate(String.valueOf(sessionId));
138+
} catch (IOException e) {
139+
throw new UIDException("Cannot generate UID", e, "uid.generate.error");
140+
}
132141
}
133142

134143
public CompletableFuture<GameLaunchResponse> requestHostGame(NewGameInfo newGameInfo) {
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
package com.faforever.client.remote;
2+
3+
public record LobbyAccess(String accessUrl) {
4+
}

src/main/java/com/faforever/client/update/ClientConfiguration.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@ public static class GitHubRepo {
3232
public static class ServerEndpoints {
3333
private String name;
3434
private SocketEndpoint lobby;
35+
private UrlEndpoint lobbyWebsocket;
36+
private UrlEndpoint user;
3537
private SocketEndpoint irc;
3638
private SocketEndpoint liveReplay;
3739
private UrlEndpoint api;

src/main/resources/application-local.yml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
faf-client:
22
server:
3-
host: localhost
4-
port: 8001
3+
url: ws://localhost:8003
54

65
irc:
76
host: localhost

0 commit comments

Comments
 (0)