io.github.robertograham.fortniteapirestclient.FortniteApiRestClient Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of fortnite-api-rest-client Show documentation
Show all versions of fortnite-api-rest-client Show documentation
Provides access to the Fortnite REST API
package io.github.robertograham.fortniteapirestclient;
import io.github.robertograham.fortniteapirestclient.domain.Credentials;
import io.github.robertograham.fortniteapirestclient.domain.EnhancedLeaderBoard;
import io.github.robertograham.fortniteapirestclient.domain.StatsGroup;
import io.github.robertograham.fortniteapirestclient.service.account.AccountService;
import io.github.robertograham.fortniteapirestclient.service.account.impl.AccountServiceImpl;
import io.github.robertograham.fortniteapirestclient.service.account.model.Account;
import io.github.robertograham.fortniteapirestclient.service.account.model.request.GetAccountRequest;
import io.github.robertograham.fortniteapirestclient.service.authentication.AuthenticationService;
import io.github.robertograham.fortniteapirestclient.service.authentication.impl.AuthenticationServiceImpl;
import io.github.robertograham.fortniteapirestclient.service.authentication.model.ExchangeCode;
import io.github.robertograham.fortniteapirestclient.service.authentication.model.OAuthToken;
import io.github.robertograham.fortniteapirestclient.service.authentication.model.request.GetExchangeCodeRequest;
import io.github.robertograham.fortniteapirestclient.service.authentication.model.request.GetOAuthTokenRequest;
import io.github.robertograham.fortniteapirestclient.service.authentication.model.request.KillSessionRequest;
import io.github.robertograham.fortniteapirestclient.service.leaderBoard.LeaderBoardService;
import io.github.robertograham.fortniteapirestclient.service.leaderBoard.impl.LeaderBoardServiceImpl;
import io.github.robertograham.fortniteapirestclient.service.leaderBoard.model.LeaderBoard;
import io.github.robertograham.fortniteapirestclient.service.leaderBoard.model.request.GetWinsLeaderBoardRequest;
import io.github.robertograham.fortniteapirestclient.service.statistics.StatisticsService;
import io.github.robertograham.fortniteapirestclient.service.statistics.impl.StatisticsServiceImpl;
import io.github.robertograham.fortniteapirestclient.service.statistics.model.Statistic;
import io.github.robertograham.fortniteapirestclient.service.statistics.model.request.GetBattleRoyaleStatisticsRequest;
import io.github.robertograham.fortniteapirestclient.service.statistics.model.request.GetSoloDuoSquadBattleRoyaleStatisticsByPlatformRequest;
import io.github.robertograham.fortniteapirestclient.service.statistics.model.request.GetSoloDuoSquadBattleRoyaleStatisticsRequest;
import io.github.robertograham.fortniteapirestclient.util.ResponseHandlerProvider;
import org.apache.http.NameValuePair;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.Closeable;
import java.io.IOException;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
public class FortniteApiRestClient implements Closeable {
private static final Logger LOG = LoggerFactory.getLogger(FortniteApiRestClient.class);
private final Credentials credentials;
private final AuthenticationService authenticationService;
private final AccountService accountService;
private final StatisticsService statisticsService;
private final ScheduledExecutorService scheduledExecutorService;
private final LeaderBoardService leaderBoardService;
private final CloseableHttpClient httpClient;
private OAuthToken sessionToken;
FortniteApiRestClient(Credentials credentials, CloseableHttpClient httpClient, ResponseHandlerProvider responseHandlerProvider, ScheduledExecutorService scheduledExecutorService, boolean autoLoginDisabled) {
this.credentials = credentials;
this.httpClient = httpClient;
authenticationService = new AuthenticationServiceImpl(httpClient, responseHandlerProvider);
accountService = new AccountServiceImpl(httpClient, responseHandlerProvider);
statisticsService = new StatisticsServiceImpl(httpClient, responseHandlerProvider);
leaderBoardService = new LeaderBoardServiceImpl(httpClient, responseHandlerProvider, accountService);
this.scheduledExecutorService = scheduledExecutorService;
scheduledExecutorService.scheduleWithFixedDelay(tokenRefreshRunnable(), 1, 1, TimeUnit.SECONDS);
if (!autoLoginDisabled)
try {
login().get();
} catch (InterruptedException | ExecutionException e) {
LOG.error("Exception occurred during login process", e);
}
}
public static FortniteApiRestClientBuilder builder(Credentials credentials) {
return new FortniteApiRestClientBuilder(credentials);
}
private Runnable tokenRefreshRunnable() {
return () -> {
LocalDateTime now = LocalDateTime.now();
LOG.debug("Validity of token that expires at {} being checked at {}", sessionToken != null ? sessionToken.getExpiresAt() : LocalDateTime.MIN, now);
if (sessionToken != null && sessionToken.getExpiresAt().minusMinutes(15).isBefore(now)) {
LOG.info("Token has expired - refreshing");
try {
authenticationService.getOAuthToken(GetOAuthTokenRequest.builder()
.grantType("refresh_token")
.authHeaderValue("basic " + credentials.getFortniteClientToken())
.additionalFormEntries(new NameValuePair[]{
new BasicNameValuePair("refresh_token", sessionToken.getRefreshToken())
})
.build())
.thenAcceptAsync(token -> setSessionToken(token != null ? token : sessionToken))
.get();
} catch (InterruptedException | ExecutionException e) {
LOG.error("Exception occurred during token refresh", e);
}
}
};
}
private CompletableFuture getUsernameAndPasswordDerivedOAuthToken() {
return authenticationService.getOAuthToken(GetOAuthTokenRequest.builder()
.grantType("password")
.authHeaderValue("basic " + credentials.getEpicGamesLauncherToken())
.additionalFormEntries(new NameValuePair[]{
new BasicNameValuePair("username", credentials.getEpicGamesEmailAddress()),
new BasicNameValuePair("password", credentials.getEpicGamesPassword())
})
.build());
}
private CompletableFuture getExchangeCode(OAuthToken usernameAndPasswordDerivedOAuthToken) {
return authenticationService.getExchangeCode(GetExchangeCodeRequest.builder()
.authHeaderValue("bearer " + usernameAndPasswordDerivedOAuthToken.getAccessToken())
.build());
}
private CompletableFuture getFortniteApiOAuthTokenFromExchangeCode(ExchangeCode exchangeCode) {
return authenticationService.getOAuthToken(GetOAuthTokenRequest.builder()
.grantType("exchange_code")
.authHeaderValue("basic " + credentials.getFortniteClientToken())
.additionalFormEntries(new NameValuePair[]{
new BasicNameValuePair("exchange_code", exchangeCode.getCode()),
new BasicNameValuePair("token_type", "eg1")
})
.build());
}
public CompletableFuture login() {
return getUsernameAndPasswordDerivedOAuthToken()
.thenComposeAsync(this::getExchangeCode)
.thenComposeAsync(this::getFortniteApiOAuthTokenFromExchangeCode)
.thenAcceptAsync(this::setSessionToken);
}
public CompletableFuture account(String accountName) {
return accountService.getAccount(GetAccountRequest.builder()
.accountName(accountName)
.authHeaderValue("bearer " + nonNullableSessionToken().getAccessToken())
.build());
}
public CompletableFuture enhancedBattleRoyaleStatsByPlatform(String accountId, String platform, String window) {
return statisticsService.getSoloDuoSquadBattleRoyaleStatisticsByPlatform(GetSoloDuoSquadBattleRoyaleStatisticsByPlatformRequest.builder()
.accountId(accountId)
.window(window)
.authHeaderValue("bearer " + nonNullableSessionToken().getAccessToken())
.platform(platform)
.build());
}
public CompletableFuture