Skip to content

Commit

Permalink
Enable selection of a leaderboard for custom games.
Browse files Browse the repository at this point in the history
Hide leaderboards tab.
  • Loading branch information
Axle1975 committed Nov 25, 2021
1 parent 0b589a9 commit 0a0c5fc
Show file tree
Hide file tree
Showing 47 changed files with 395 additions and 137 deletions.
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ version=unspecified
javafxPlatform=unspecified
faf_ice_adapter_version=3.0.0
faf_uid_version=4.0.4
gpgnet4ta_version=0.14.6
gpgnet4ta_version=0.14.9
taftoolbox_version=0.14
propdepsVersion=0.0.7
springBootVersion=2.4.0
Expand Down
2 changes: 2 additions & 0 deletions src/main/java/com/faforever/client/api/FafApiAccessor.java
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,8 @@ public interface FafApiAccessor {

Optional<MatchmakerQueue> getMatchmakerQueue(String technicalName);

List<MatchmakerQueue> getMatchmakerQueuesByMod(String modTechnicalName);

List<Tournament> getAllTournaments();

List<ModerationReport> getPlayerModerationReports(int playerId);
Expand Down
10 changes: 9 additions & 1 deletion src/main/java/com/faforever/client/api/FafApiAccessorImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ public class FafApiAccessorImpl implements FafApiAccessor, InitializingBean {
private static final String REPORT_ENDPOINT = "/data/moderationReport";
private static final String TOURNAMENT_LIST_ENDPOINT = "/challonge/v1/tournaments.json";
private static final String REPLAY_INCLUDES = "featuredMod,playerStats,playerStats.player,playerStats.ratingChanges,reviews," +
"reviews.player,mapVersion,mapVersion.map,reviewsSummary";
"reviews.player,mapVersion,mapVersion.map,reviewsSummary,playerStats.ratingChanges.leaderboard";
private static final String MAP_INCLUDES = "latestVersion,author,statistics,reviewsSummary," +
"versions.reviews,versions.reviews.player";
private static final String MAP_VERSION_INCLUDES = "map,map.latestVersion,map.author,map.statistics," +
Expand Down Expand Up @@ -566,6 +566,14 @@ public Optional<MatchmakerQueue> getMatchmakerQueue(String technicalName) {
return Optional.ofNullable(queue.get(0));
}

@Override
@Cacheable(value = CacheNames.MATCHMAKER_QUEUES_BY_MOD, sync = true)
public List<MatchmakerQueue> getMatchmakerQueuesByMod(String modTechnicalName) {
return getAll("/data/matchmakerQueue", java.util.Map.of(
INCLUDE, "leaderboard,featuredMod",
FILTER, rsql(qBuilder().string("featuredMod.technicalName").eq(modTechnicalName))));
}

@Override
public List<TutorialCategory> getTutorialCategories() {
return getAll("/data/tutorialCategory",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -325,6 +325,9 @@ public Optional<MatchmakerQueue> getMatchmakerQueue(String technicalName) {
return Optional.empty();
}

@Override
public List<MatchmakerQueue> getMatchmakerQueuesByMod(String modTechnicalName) { return List.of(); }

@Override
public List<Tournament> getAllTournaments() {
return List.of();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,13 @@ public void initialize() {
ratingTypeComboBox.getItems().clear();
ratingTypeComboBox.getItems().addAll(leaderboards);
ratingTypeComboBox.setConverter(leaderboardStringConverter());
ratingTypeComboBox.getSelectionModel().selectFirst();

leaderboards.stream()
.filter(lbe -> lbe.getTechnicalName().equals(preferencesService.getPreferences().getLastLeaderboardSelection()))
.findAny()
.ifPresentOrElse(
lbe -> ratingTypeComboBox.getSelectionModel().select(lbe),
() -> ratingTypeComboBox.getSelectionModel().selectFirst());
});
return null;
});
Expand Down Expand Up @@ -330,9 +336,12 @@ private void plotGamesPlayedByModChart() {
private void plotGamesPlayedByLeaderboardChart() {
JavaFxUtil.runLater(() -> gamesPlayedByLeaderboardChart.getData().clear());
leaderboardService.getEntriesForPlayer(player.getId()).thenAccept(leaderboardEntries -> JavaFxUtil.runLater(() -> {
ratingTable.setItems(observableList(leaderboardEntries));
updateRatingGrids(leaderboardEntries);
leaderboardEntries.forEach(leaderboardEntry ->
List<LeaderboardEntry> sortedEntries = leaderboardEntries.stream()
.sorted((a,b) -> (int)(b.getRating() - a.getRating()))
.collect(Collectors.toList());
ratingTable.setItems(observableList(sortedEntries));
updateRatingGrids(sortedEntries);
sortedEntries.forEach(leaderboardEntry ->
gamesPlayedByLeaderboardChart.getData().add(new PieChart.Data(
i18n.getWithDefault(leaderboardEntry.getLeaderboard().getTechnicalName(), leaderboardEntry.getLeaderboard().getNameKey()),
leaderboardEntry.getWonGames())));
Expand All @@ -345,6 +354,10 @@ private void plotGamesPlayedByLeaderboardChart() {

public void onRatingTypeChange() {
if (ratingTypeComboBox.getValue() != null) {

preferencesService.getPreferences().setLastLeaderboardSelection(ratingTypeComboBox.getValue().getTechnicalName());
preferencesService.storeInBackground();

ratingHistoryChart.setVisible(false);
loadingHistoryPane.setVisible(true);
loadStatistics(ratingTypeComboBox.getValue()).thenRun(() -> JavaFxUtil.runLater(this::plotPlayerRatingGraph));
Expand Down
4 changes: 3 additions & 1 deletion src/main/java/com/faforever/client/config/CacheConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
import static com.faforever.client.config.CacheNames.MAP_PREVIEW;
import static com.faforever.client.config.CacheNames.MATCHMAKER_POOLS;
import static com.faforever.client.config.CacheNames.MATCHMAKER_QUEUES;
import static com.faforever.client.config.CacheNames.MATCHMAKER_QUEUES_BY_MOD;
import static com.faforever.client.config.CacheNames.MODS;
import static com.faforever.client.config.CacheNames.MOD_THUMBNAIL;
import static com.faforever.client.config.CacheNames.NEWS;
Expand Down Expand Up @@ -74,7 +75,8 @@ public CacheManager cacheManager() {
new CaffeineCache(FEATURED_MODS, newBuilder().build()),
new CaffeineCache(FEATURED_MOD_FILES, newBuilder().expireAfterWrite(10, MINUTES).build()),
new CaffeineCache(MATCHMAKER_QUEUES, newBuilder().expireAfterWrite(10, MINUTES).build()),
new CaffeineCache(MATCHMAKER_POOLS, newBuilder().expireAfterWrite(1, MINUTES).build()),
new CaffeineCache(MATCHMAKER_QUEUES_BY_MOD, newBuilder().expireAfterWrite(10, MINUTES).build()),
new CaffeineCache(MATCHMAKER_POOLS, newBuilder().expireAfterWrite(10, MINUTES).build()),
new CaffeineCache(TADEMO_MAP_HASH, newBuilder().expireAfterWrite(1, MINUTES).build()),
new CaffeineCache(TADEMO_MOD_HASH, newBuilder().expireAfterWrite(1, MINUTES).build()),

Expand Down
1 change: 1 addition & 0 deletions src/main/java/com/faforever/client/config/CacheNames.java
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ public final class CacheNames {
public static final String COOP_LEADERBOARD = "coopLeaderboard";
public static final String CLAN = "clan";
public static final String MATCHMAKER_QUEUES = "matchmakerQueues";
public static final String MATCHMAKER_QUEUES_BY_MOD = "matchmakerQueuesByMod";
public static final String MATCHMAKER_POOLS = "matchmakerPools";
public static final String TADEMO_MAP_HASH = "taDemoMapHash";
public static final String TADEMO_MOD_HASH = "taDemoModHash";
Expand Down
4 changes: 3 additions & 1 deletion src/main/java/com/faforever/client/coop/CoopController.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import com.faforever.client.fx.WebViewConfigurer;
import com.faforever.client.game.Game;
import com.faforever.client.game.GameService;
import com.faforever.client.game.GameVisibility;
import com.faforever.client.game.GamesTableController;
import com.faforever.client.game.NewGameInfo;
import com.faforever.client.i18n.I18n;
Expand Down Expand Up @@ -59,6 +60,7 @@
import java.util.function.Predicate;
import java.util.stream.Collectors;

import static com.faforever.client.game.GameService.DEFAULT_RATING_TYPE;
import static com.faforever.client.game.KnownFeaturedMod.COOP;
import static java.util.Collections.emptySet;
import static javafx.collections.FXCollections.observableList;
Expand Down Expand Up @@ -265,7 +267,7 @@ public void onPlayButtonClicked() {
modService.getFeaturedMod(COOP.getTechnicalName())
.thenAccept(featuredModBean -> gameService.hostGame(new NewGameInfo(titleTextField.getText(),
Strings.emptyToNull(passwordTextField.getText()), featuredModBean, getSelectedMission().getMapFolderName(),
emptySet())));
emptySet(), GameVisibility.PUBLIC, null, null, false, 300, DEFAULT_RATING_TYPE)));
}

public Node getRoot() {
Expand Down
103 changes: 94 additions & 9 deletions src/main/java/com/faforever/client/game/CreateGameController.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import com.faforever.client.preferences.PreferencesService;
import com.faforever.client.remote.FafService;
import com.faforever.client.remote.domain.GameStatus;
import com.faforever.client.teammatchmaking.MatchmakingQueue;
import com.faforever.client.theme.UiService;
import com.faforever.client.ui.preferences.event.GameDirectoryChooseEvent;
import com.google.common.eventbus.EventBus;
Expand All @@ -36,6 +37,7 @@
import javafx.beans.value.ChangeListener;
import javafx.collections.FXCollections;
import javafx.collections.ListChangeListener;
import javafx.collections.ObservableList;
import javafx.collections.WeakListChangeListener;
import javafx.collections.transformation.FilteredList;
import javafx.css.PseudoClass;
Expand Down Expand Up @@ -69,6 +71,7 @@
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
Expand All @@ -77,6 +80,7 @@
import java.util.stream.Collectors;
import java.util.stream.IntStream;

import static com.faforever.client.game.GameService.DEFAULT_RATING_TYPE;
import static com.faforever.client.net.ConnectionState.CONNECTED;
import static java.util.Collections.emptySet;
import static javafx.scene.layout.BackgroundPosition.CENTER;
Expand Down Expand Up @@ -124,6 +128,10 @@ public class CreateGameController implements Controller<Pane> {
public ComboBox<Integer> mapPreviewMaxPositionsComboBox;
public CheckBox onlyForFriendsCheckBox;
public ComboBox<LiveReplayOption> liveReplayOptionComboBox;
public ListView<MatchmakingQueue> mapPoolListView;

public CheckBox rankedEnabledCheckBox;
public Label rankedEnabledLabel;
@VisibleForTesting
FilteredList<MapBean> filteredMapBeans;
private Runnable onCloseButtonClickedListener;
Expand Down Expand Up @@ -306,6 +314,7 @@ private void init() {
bindLiveReplayDelayOption();
initMapSelection(KnownFeaturedMod.DEFAULT.getBaseGameName());
initFeaturedModList();
initMapPoolList();
initRatingBoundaries();
selectAppropriateMap();
setLastGameTitle();
Expand All @@ -332,6 +341,11 @@ private void init() {

createGameButton.disableProperty().bind(validatedButtonsDisableProperty);
updateGameButton.disableProperty().bind(interactionLevelProperty.isEqualTo("BROWSE"));
mapPoolListView.disableProperty().bind(interactionLevelProperty.isEqualTo("BROWSE"));

rankedEnabledCheckBox.disableProperty().bind(interactionLevelProperty.isEqualTo("BROWSE"));
rankedEnabledCheckBox.setSelected(preferencesService.getPreferences().getLastGame().getLastGameRankedEnabled());
rankedEnabledLabel.disableProperty().bind(interactionLevelProperty.isEqualTo("BROWSE"));

createGameButton.visibleProperty().bind(interactionLevelProperty.isEqualTo("CREATE"));
updateGameButton.visibleProperty().bind(createGameButton.visibleProperty().not());
Expand Down Expand Up @@ -417,19 +431,62 @@ protected void initMapListListeners() {
}

protected void setAvailableMaps(String modTechnical) {
filteredMapBeans = new FilteredList<>(
mapService.getInstalledMaps(modTechnical).filtered(mapBean -> mapBean.getType() == Type.SKIRMISH).sorted((o1, o2) -> o1.getMapName().compareToIgnoreCase(o2.getMapName()))
);

Path installedExePath = preferencesService.getTotalAnnihilation(modTechnical).getInstalledExePath();
if (filteredMapBeans.isEmpty() && installedExePath != null && Files.isExecutable(installedExePath)) {
mapListView.setItems(mapService.getOfficialMaps());
if (rankedEnabledCheckBox.isSelected() && mapPoolListView.getSelectionModel().getSelectedItem() != null) {
try {
MatchmakingQueue q = mapPoolListView.getSelectionModel().getSelectedItem();
HashSet<String> mapPoolMapNames = mapService.getMatchmakerMaps(q).get().stream()
.map(MapBean::getMapName)
.collect(Collectors.toCollection(HashSet::new));

filteredMapBeans = new FilteredList<>(mapService.getInstalledMaps(modTechnical)
.filtered(mapBean -> mapBean.getType() == Type.SKIRMISH)
.filtered(mapBean -> mapPoolMapNames.contains(mapBean.getMapName()))
.sorted((o1, o2) -> o1.getMapName().compareToIgnoreCase(o2.getMapName())));

doSetAvailableMaps(modTechnical, filteredMapBeans);

} catch (Exception e) {
log.error("[setAvailableMaps] {}", e.getMessage());
filteredMapBeans = new FilteredList<>(mapService.getInstalledMaps(modTechnical)
.filtered(mapBean -> mapBean.getType() == Type.SKIRMISH)
.sorted((o1, o2) -> o1.getMapName().compareToIgnoreCase(o2.getMapName())));
doSetAvailableMaps(modTechnical, filteredMapBeans);
}
}
else {
mapListView.setItems(filteredMapBeans);
filteredMapBeans = new FilteredList<>(mapService.getInstalledMaps(modTechnical)
.filtered(mapBean -> mapBean.getType() == Type.SKIRMISH)
.sorted((o1, o2) -> o1.getMapName().compareToIgnoreCase(o2.getMapName())));
doSetAvailableMaps(modTechnical, filteredMapBeans);
}
}

protected void doSetAvailableMaps(String modTechnical, ObservableList<MapBean> items) {
JavaFxUtil.runLater(() -> {
Path installedExePath = preferencesService.getTotalAnnihilation(modTechnical).getInstalledExePath();
if (filteredMapBeans.isEmpty() && installedExePath != null && Files.isExecutable(installedExePath)) {
mapListView.setItems(mapService.getOfficialMaps());
} else {
mapListView.setItems(items);
}
});
}

protected void setAvailableMapPools(String modTechnical) {
fafService.getMatchingQueuesByMod(modTechnical)
.thenAccept(queues -> {
JavaFxUtil.runLater(() -> {
mapPoolListView.getItems().setAll(queues);
if (mapPoolListView.getItems().size() > 0) {
mapPoolListView.getSelectionModel().select(0);
}
});
// just page the maps into cache so they're available should the user select them
queues.forEach(mapService::getMatchmakerMaps);
});
}

protected void setSelectedMap(MapBean newValue, PreviewType previewType, int maxNumPlayers) {
JavaFxUtil.assertApplicationThread();

Expand Down Expand Up @@ -490,6 +547,7 @@ private void initFeaturedModList() {
modService.getFeaturedMods().thenAccept(featuredModBeans -> JavaFxUtil.runLater(() -> {
featuredModListView.setItems(FXCollections.observableList(featuredModBeans).filtered(FeaturedMod::isVisible));
featuredModListView.getSelectionModel().selectedItemProperty().addListener((observable, oldValue, newValue) -> JavaFxUtil.runLater(() -> {
setAvailableMapPools(newValue.getTechnicalName());
setAvailableMaps(newValue.getTechnicalName());
Path installedExePath = preferencesService.getTotalAnnihilation(newValue.getTechnicalName()).getInstalledExePath();
setGamePathButton.setStyle(installedExePath == null || !Files.isExecutable(installedExePath)
Expand All @@ -503,6 +561,26 @@ private void initFeaturedModList() {
}));
}

private void initMapPoolList() {
mapPoolListView.setCellFactory(param ->
new StringListCell<>((q) -> i18n.get(q.getLeaderboard().getNameKey()))
);
mapPoolListView.visibleProperty().bind(rankedEnabledCheckBox.selectedProperty());
rankedEnabledCheckBox.selectedProperty().addListener((obs, oldValue, newValue) -> {
if (featuredModListView.getSelectionModel().getSelectedItem() != null) {
setAvailableMaps(featuredModListView.getSelectionModel().getSelectedItem().getTechnicalName());
selectAppropriateMap();
}
preferencesService.getPreferences().getLastGame().setLastGameRankedEnabled(newValue);
preferencesService.storeInBackground();
});

mapPoolListView.getSelectionModel().selectedItemProperty().addListener((obs,oldValue,newValue) -> {
setAvailableMaps(featuredModListView.getSelectionModel().getSelectedItem().getTechnicalName());
selectAppropriateMap();
});
}

private void initRatingBoundaries() {
Integer lastGameMinRating = preferencesService.getPreferences().getLastGame().getLastGameMinRating();
Integer lastGameMaxRating = preferencesService.getPreferences().getLastGame().getLastGameMaxRating();
Expand Down Expand Up @@ -634,7 +712,10 @@ private void hostGame(MapBean map) {
minRating,
maxRating,
enforceRating,
liveReplayOptionComboBox.getSelectionModel().getSelectedItem().getDelaySeconds());
liveReplayOptionComboBox.getSelectionModel().getSelectedItem().getDelaySeconds(),
rankedEnabledCheckBox.isSelected()
? mapPoolListView.getSelectionModel().getSelectedItem().getLeaderboard().getTechnicalName()
: DEFAULT_RATING_TYPE);

gameService.hostGame(newGameInfo).exceptionally(throwable -> {
log.warn("Game could not be hosted", throwable);
Expand All @@ -644,7 +725,11 @@ private void hostGame(MapBean map) {
}

public void onUpdateButtonClicked() {
gameService.setMapForStagingGame(mapListView.getSelectionModel().getSelectedItem().getMapName());
gameService.updateSettingsForStagingGame(
mapListView.getSelectionModel().getSelectedItem().getMapName(),
rankedEnabledCheckBox.isSelected()
? mapPoolListView.getSelectionModel().getSelectedItem().getLeaderboard().getTechnicalName()
: DEFAULT_RATING_TYPE);
}

public Pane getRoot() {
Expand Down
Loading

0 comments on commit 0a0c5fc

Please sign in to comment.