Skip to content

Commit

Permalink
Bot: show list of autosaves and allow players to load autosaves (#12744)
Browse files Browse the repository at this point in the history
In addition to listing all installed maps, also list all autosaves.
Previously players were unable to select bot-autosave files, now
they will be able to.
  • Loading branch information
DanVanAtta committed Jul 22, 2024
1 parent 5bcf651 commit d283a73
Show file tree
Hide file tree
Showing 3 changed files with 58 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,43 @@

import com.google.common.annotations.VisibleForTesting;
import games.strategy.triplea.settings.ClientSetting;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.List;
import java.util.Locale;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import lombok.extern.slf4j.Slf4j;

/**
* Provides methods for getting the names of auto-save files periodically generated during a game.
*/
@Slf4j
public class AutoSaveFileUtils {
/** Returns a list path objects representing each auto save file. */
public static List<Path> getAutoSavePaths() {
var autoSaveFolder = ClientSetting.saveGamesFolderPath.getValueOrThrow().resolve("autoSave");
try (Stream<Path> paths = Files.list(autoSaveFolder)) {
return paths.filter(f -> !Files.isDirectory(f)).collect(Collectors.toList());
} catch (IOException e) {
log.warn("Unable to list auto-save game files", e);
return List.of();
}
}

/** Returns the name of all auto save files. */
public static List<String> getAutoSaveFiles() {
return getAutoSavePaths().stream()
.map(Path::toFile)
.map(File::getName)
.sorted()
.collect(Collectors.toList());
}

@VisibleForTesting
Path getAutoSaveFile(final String baseFileName) {
return ClientSetting.saveGamesFolderPath
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import games.strategy.engine.data.GameData;
import games.strategy.engine.data.GameState;
import games.strategy.engine.data.properties.GameProperties;
import games.strategy.engine.framework.AutoSaveFileUtils;
import games.strategy.engine.framework.GameDataManager;
import games.strategy.engine.framework.GameRunner;
import games.strategy.engine.framework.ServerGame;
Expand Down Expand Up @@ -57,16 +58,33 @@ public Collection<String> getAvailableGames() {
}

public synchronized void setGameMapTo(final String gameName) {
log.info("Requested to change map to: " + gameName);
log.info("Requested to change map to: {}", gameName);

// don't change mid-game and only if we have the game
if (game == null && availableGames.hasGame(gameName)) {
if (game != null) {
log.info("Did NOT change game map to: {}, a game is currently running.", gameName);
return;
}

if (availableGames.hasGame(gameName)) {
// change map
gameSelectorModel.loadMap(availableGames.findGameXmlPathByGameName(gameName).orElseThrow());
log.info("Changed to game map: " + gameName);
log.info("Changed to game map: {}", gameName);
} else if (AutoSaveFileUtils.getAutoSaveFiles().contains(gameName)) {
// change to autosave
log.info("Loading {} as a savegame", gameName);
AutoSaveFileUtils.getAutoSavePaths().stream()
.filter(p -> p.toFile().getName().equals(gameName))
.findAny()
.ifPresentOrElse(
gameSelectorModel::loadSave,
() ->
log.warn(
"Unexpected, could not find save file: {}, from choices: {}",
gameName,
AutoSaveFileUtils.getAutoSavePaths()));
} else {
log.info(
String.format(
"Did NOT change game map to: %s, game == null ? %s, have game? %s",
gameName, game == null, availableGames.hasGame(gameName)));
log.warn("Unable to find save game as either a new map or a savegame: {}", gameName);
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package org.triplea.game.server;

import com.google.common.base.Preconditions;
import games.strategy.engine.framework.AutoSaveFileUtils;
import games.strategy.engine.framework.HeadlessAutoSaveType;
import games.strategy.engine.framework.message.PlayerListing;
import games.strategy.engine.framework.startup.mc.IServerStartupRemote;
Expand Down Expand Up @@ -78,7 +79,10 @@ public byte[] getGameOptions() {
public Set<String> getAvailableGames() {
// Copy available games collection into a serializable collection
// so it can be sent over network.
return new HashSet<>(headlessGameServer.getAvailableGames());
var games = new HashSet<String>();
games.addAll(AutoSaveFileUtils.getAutoSaveFiles());
games.addAll(headlessGameServer.getAvailableGames());
return games;
}

@Override
Expand Down

0 comments on commit d283a73

Please sign in to comment.