Skip to content

Commit 8006263

Browse files
committed
feat: move loading GameState from file from Game into SDK
1 parent 602d1f3 commit 8006263

File tree

4 files changed

+59
-93
lines changed

4 files changed

+59
-93
lines changed

plugin/src/server/sc/plugin2021/Game.kt

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -76,18 +76,6 @@ class Game(override val currentState: GameState = GameState()): AbstractGame<Pla
7676
}
7777
}
7878

79-
override fun loadGameInfo(gameInfo: Any) {
80-
TODO("Not yet implemented")
81-
}
82-
83-
override fun loadFromFile(file: String) {
84-
TODO("Not yet implemented")
85-
}
86-
87-
override fun loadFromFile(file: String, turn: Int) {
88-
TODO("Not yet implemented")
89-
}
90-
9179
override fun getScoreFor(player: Player): PlayerScore {
9280
val team = player.color as Team
9381
logger.debug("Get score for player $team (violated: ${if (player.hasViolated()) "yes" else "no"})")

sdk/src/server-api/sc/api/plugins/IGameInstance.kt

Lines changed: 0 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -38,30 +38,6 @@ interface IGameInstance {
3838
*/
3939
fun destroy()
4040

41-
/**
42-
* The game is requested to load itself from a file.
43-
* Similar to a replay but with actual clients.
44-
*
45-
* @param file File the game should be loaded from
46-
*/
47-
fun loadFromFile(file: String)
48-
49-
/**
50-
* The game is requested to load itself from a file.
51-
* Similar to a replay but with actual clients.
52-
*
53-
* @param file File where the game should be loaded from
54-
* @param turn The turn to load from the replay
55-
*/
56-
fun loadFromFile(file: String, turn: Int)
57-
58-
/**
59-
* The game is requested to load itself from a given game information object.
60-
*
61-
* @param gameInfo the stored gameInformation
62-
*/
63-
fun loadGameInfo(gameInfo: Any)
64-
6541
/**
6642
* Returns the players that have won the game, empty if the game has no winners,
6743
* or null if the game has not yet finished.

server/src/sc/server/gaming/GameRoomManager.java

Lines changed: 59 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,12 @@
22

33
import org.slf4j.Logger;
44
import org.slf4j.LoggerFactory;
5+
import sc.api.plugins.IGameInstance;
6+
import sc.api.plugins.IGamePlugin;
7+
import sc.api.plugins.IGameState;
58
import sc.api.plugins.exceptions.GameRoomException;
69
import sc.api.plugins.exceptions.RescuableClientException;
10+
import sc.api.plugins.host.GameLoader;
711
import sc.networking.InvalidScoreDefinitionException;
812
import sc.protocol.requests.PrepareGameRequest;
913
import sc.protocol.responses.GamePreparedResponse;
@@ -15,14 +19,16 @@
1519
import sc.server.plugins.UnknownGameTypeException;
1620
import sc.shared.*;
1721

22+
import java.io.File;
23+
import java.io.IOException;
1824
import java.math.BigDecimal;
1925
import java.math.MathContext;
2026
import java.util.*;
2127

2228
/**
2329
* The GameManager is responsible to keep all games alive and kill them once
24-
* they are done. Additionally the GameManager has to detect and kill games,
25-
* which seem to be dead-locked or have caused a timeout.
30+
* they are done. Additionally the GameManager has to detect and kill games
31+
* which seem dead-locked or have caused a timeout.
2632
*/
2733
public class GameRoomManager {
2834
private Map<String, GameRoom> rooms;
@@ -46,66 +52,67 @@ private synchronized void add(GameRoom room) {
4652
this.rooms.put(room.getId(), room);
4753
}
4854

55+
public IGamePlugin findPlugin(String gameType) throws RescuableClientException {
56+
GamePluginInstance plugin = this.gamePluginManager.getPlugin(gameType);
57+
58+
if (plugin == null) {
59+
logger.warn("Couldn't find a game of type " + gameType);
60+
throw new UnknownGameTypeException(gameType, this.gamePluginManager.getPluginUUIDs());
61+
}
62+
63+
return plugin.getPlugin();
64+
}
65+
4966
/**
50-
* Create a not prepared {@link GameRoom GameRoom} of given type
51-
*
52-
* @param gameType String of current Game
67+
* Create a not prepared {@link GameRoom GameRoom} of given type.
5368
*
5469
* @return Newly created GameRoom
5570
*
5671
* @throws RescuableClientException if creation of game failed
5772
*/
58-
public synchronized GameRoom createGame(String gameType) throws RescuableClientException {
59-
return createGame(gameType, false);
73+
public synchronized GameRoom createGameRoom(String gameType) throws RescuableClientException {
74+
IGamePlugin plugin = findPlugin(gameType);
75+
IGameInstance game;
76+
77+
String gameFileLocation = Configuration.get(Configuration.GAMELOADFILE);
78+
if (gameFileLocation != null && !gameFileLocation.equals("")) {
79+
File gameFile = new File(gameFileLocation);
80+
Integer turn = null;
81+
try {
82+
turn = Integer.parseInt(Configuration.get(Configuration.TURN_TO_LOAD));
83+
} catch(NumberFormatException ignored) {
84+
}
85+
86+
// TODO skip to turn
87+
// TODO implement tests
88+
logger.info("Loading game from file '{}' at turn {}", gameFile, turn);
89+
try {
90+
game = plugin.createGameFromState((IGameState) new GameLoader(IGameState.class).loadGame(gameFile));
91+
} catch(IOException e) {
92+
logger.error("Failed to load game from file", e);
93+
game = plugin.createGame();
94+
}
95+
} else {
96+
game = plugin.createGame();
97+
}
98+
99+
return createGameRoom(plugin.getScoreDefinition(), game, false);
60100
}
61101

62102
/**
63-
* Create a new GameRoom from the matching plugin.
64-
* If gameFile is set, load gameState from file.
103+
* Create a new GameRoom with the given Game.
65104
*
66-
* @param gameType id of the game plugin to use
67-
* @param prepared signals whether the game was prepared by gui or ..., false if player has to send JoinRoomRequest
105+
* @param prepared signals whether the game was prepared by an administrative client,
106+
* false if from a JoinRoomRequest
68107
*
69108
* @return newly created GameRoom
70-
*
71-
* @throws UnknownGameTypeException if no matching GamePlugin was found
72109
*/
73-
public GameRoom createGame(String gameType, boolean prepared) throws RescuableClientException {
74-
GamePluginInstance plugin = this.gamePluginManager.getPlugin(gameType);
75-
76-
if (plugin == null) {
77-
logger.warn("Couldn't find a game of type " + gameType);
78-
throw new UnknownGameTypeException(gameType, this.gamePluginManager.getPluginUUIDs());
79-
}
80-
81-
logger.info("Creating new game of type " + gameType);
82-
83-
String roomId = generateRoomId();
84-
GameRoom room = new GameRoom(roomId, this, plugin.getPlugin().getScoreDefinition(), plugin.createGame(), prepared);
110+
public GameRoom createGameRoom(ScoreDefinition scoreDefinition, IGameInstance game, boolean prepared) {
111+
GameRoom room = new GameRoom(generateRoomId(), this, scoreDefinition, game, prepared);
85112
// pause room if specified in server.properties on joinRoomRequest
86113
if (!prepared) {
87114
boolean paused = Boolean.parseBoolean(Configuration.get(Configuration.PAUSED));
88115
room.pause(paused);
89-
logger.info("Pause is set to {}", paused);
90-
}
91-
92-
String gameFile = Configuration.get(Configuration.GAMELOADFILE);
93-
if (gameFile != null && !gameFile.equals("")) {
94-
logger.info("Request plugin to load game from file: " + gameFile);
95-
int turn;
96-
if (Configuration.get(Configuration.TURN_TO_LOAD) != null) {
97-
turn = Integer.parseInt(Configuration.get(Configuration.TURN_TO_LOAD));
98-
} else {
99-
turn = 0;
100-
}
101-
logger.debug("Turns is to load is: " + turn);
102-
if (turn > 0) {
103-
logger.debug("Loading from non default turn");
104-
room.game.loadFromFile(gameFile, turn);
105-
} else {
106-
logger.debug("Loading first gameState found");
107-
room.game.loadFromFile(gameFile);
108-
}
109116
}
110117

111118
this.add(room);
@@ -126,7 +133,7 @@ private static synchronized String generateRoomId() {
126133
*/
127134
public synchronized RoomWasJoinedEvent createAndJoinGame(Client client, String gameType)
128135
throws RescuableClientException {
129-
GameRoom room = createGame(gameType);
136+
GameRoom room = createGameRoom(gameType);
130137
if (room.join(client)) {
131138
return roomJoined(room);
132139
}
@@ -164,23 +171,22 @@ public GamePluginManager getPluginManager() {
164171
}
165172

166173
/**
167-
* Creates a new GameRoom through {@link #createGame(String) createGame} with reserved PlayerSlots according to the
174+
* Creates a new GameRoom with reserved PlayerSlots according to the
168175
* descriptors and loads a game state from a file if provided.
169176
*
170177
* @return new PrepareGameProtocolMessage with roomId and slot reservations
171178
*
172179
* @throws RescuableClientException if game could not be created
173180
*/
174-
public synchronized GamePreparedResponse prepareGame(String gameType, boolean paused, SlotDescriptor[] descriptors, Object loadGameInfo)
181+
public synchronized GamePreparedResponse prepareGame(String gameType, boolean paused, SlotDescriptor[] descriptors, IGameState loadGameInfo)
175182
throws RescuableClientException {
176-
GameRoom room = createGame(gameType, true);
183+
IGamePlugin plugin = findPlugin(gameType);
184+
IGameInstance game = loadGameInfo != null ? plugin.createGameFromState(loadGameInfo) : plugin.createGame();
185+
186+
GameRoom room = createGameRoom(plugin.getScoreDefinition(), game, true);
177187
room.pause(paused);
178188
room.openSlots(descriptors);
179189

180-
if (loadGameInfo != null) {
181-
room.game.loadGameInfo(loadGameInfo);
182-
}
183-
184190
return new GamePreparedResponse(room.getId(), room.reserveAllSlots());
185191
}
186192

server/test/sc/server/plugins/TestGame.kt

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -52,10 +52,6 @@ data class TestGame(
5252
return PlayerScore(true, "Spieler hat gewonnen.")
5353
}
5454

55-
override fun loadFromFile(file: String) {}
56-
override fun loadFromFile(file: String, turn: Int) {}
57-
override fun loadGameInfo(gameInfo: Any) {}
58-
5955
override fun getTimeoutFor(player: Player): ActionTimeout =
6056
ActionTimeout(false)
6157

0 commit comments

Comments
 (0)