|
From: <ste...@us...> - 2010-07-05 18:02:20
|
Revision: 1333
http://rails.svn.sourceforge.net/rails/?rev=1333&view=rev
Author: stefanfrey
Date: 2010-07-05 18:02:13 +0000 (Mon, 05 Jul 2010)
Log Message:
-----------
Added autosave for game recovery
Modified Paths:
--------------
trunk/18xx/LocalisedText.properties
trunk/18xx/my.properties
trunk/18xx/rails/game/DisplayBuffer.java
trunk/18xx/rails/game/GameManager.java
trunk/18xx/rails/ui/swing/GameSetupWindow.java
Modified: trunk/18xx/LocalisedText.properties
===================================================================
--- trunk/18xx/LocalisedText.properties 2010-07-04 20:51:33 UTC (rev 1332)
+++ trunk/18xx/LocalisedText.properties 2010-07-05 18:02:13 UTC (rev 1333)
@@ -416,6 +416,9 @@
Pullman=Pullman-Car
QUIT=Quit
RandomizePlayers=Randomize Order
+RecoverGame=Recover Previous Game
+RecoverySaveFailed=Recovery save failed, reason: {0}
+RecoverySaveSuccessAgain=Recovery save succeeded
REDO=Redo
ReleasedFromEscrow={0} receives {1} released from bank escrow
ReleasesTrains=Makes {0}-trains available for purchasing
Modified: trunk/18xx/my.properties
===================================================================
--- trunk/18xx/my.properties 2010-07-04 20:51:33 UTC (rev 1332)
+++ trunk/18xx/my.properties 2010-07-05 18:02:13 UTC (rev 1333)
@@ -58,6 +58,12 @@
# The default extension is .rails
#save.filename.extension=rails
+### AutoSave for game recovery
+# Activation of autosave (default is yes)
+# save.recovery.active=yes
+# Filepath for autosave (default is 18xx_autosave.rails in current working directory
+# save.recovery.filepath=18xx_autosave.rails
+
### Game report directory
# If the below entry exists, is not empty, and specifies an existing
# directory, a copy of the Game Report (as displayed in the Report Window)
Modified: trunk/18xx/rails/game/DisplayBuffer.java
===================================================================
--- trunk/18xx/rails/game/DisplayBuffer.java 2010-07-04 20:51:33 UTC (rev 1332)
+++ trunk/18xx/rails/game/DisplayBuffer.java 2010-07-05 18:02:13 UTC (rev 1333)
@@ -73,13 +73,26 @@
}
private static DisplayBuffer getInstance() {
- return GameManager.getInstance().getDisplayBuffer();
+ GameManagerI gm = GameManager.getInstance();
+ if (gm == null) {
+ return null;
+ } else {
+ return gm.getDisplayBuffer();
+ }
}
/** Get the current message buffer, and clear it */
public static String[] get() {
DisplayBuffer instance = getInstance();
- if (instance.displayBuffer.size() > 0) {
+ if (instance == null) {
+ if (initialQueue.isEmpty()) {
+ return null;
+ } else {
+ String[] message = initialQueue.toArray(new String[0]);
+ initialQueue.clear();
+ return message;
+ }
+ } else if (instance.displayBuffer.size() > 0) {
String[] message = instance.displayBuffer.toArray(new String[0]);
instance.displayBuffer.clear();
return message;
Modified: trunk/18xx/rails/game/GameManager.java
===================================================================
--- trunk/18xx/rails/game/GameManager.java 2010-07-04 20:51:33 UTC (rev 1332)
+++ trunk/18xx/rails/game/GameManager.java 2010-07-05 18:02:13 UTC (rev 1333)
@@ -187,6 +187,9 @@
/** A List of available game options */
protected List<GameOption> availableGameOptions =
new ArrayList<GameOption>();
+
+ /** indicates that the recoverySave already issued a warning, avoids displaying several warnings */
+ protected boolean recoverySaveWarning = true;
protected static Logger log =
Logger.getLogger(GameManager.class.getPackage().getName());
@@ -810,6 +813,7 @@
if (action != null) {
if (result && !(action instanceof GameAction) && action.hasActed()) {
if (moveStack.isOpen()) moveStack.finish();
+ recoverySave();
} else {
if (moveStack.isOpen()) moveStack.cancel();
}
@@ -929,15 +933,72 @@
return true;
}
+ /** recoverySave method
+ * Uses filePath defined in save.recovery.filepath
+ * */
+ protected void recoverySave() {
+ if (Config.get("save.recovery.active", "yes").equalsIgnoreCase("no")) return;
+
+ String filePath = Config.get("save.recovery.filepath", "18xx_autosave.rails");
+ // create temporary new save file
+ File tempFile = null;
+ tempFile = new File(filePath + ".tmp");
+ if (!save(tempFile, recoverySaveWarning, "RecoverySaveFailed")) {
+ recoverySaveWarning = false;
+ return;
+ }
+
+ // rename the temp file to the recover file
+ File recoveryFile = null;
+ boolean result;
+ try {
+ log.debug("Created temporary recovery file, path = " + tempFile.getAbsolutePath());
+ // check if previous save file exists
+ recoveryFile = new File(filePath);
+ log.debug("Potential recovery filePath = " + recoveryFile.getAbsolutePath());
+ if (recoveryFile.exists()) {
+ log.debug("Potential recovery filePath = " + recoveryFile.getAbsolutePath());
+ File backupFile = new File(filePath + ".bak");
+ if (recoveryFile.renameTo(backupFile)) {
+ result = tempFile.renameTo(recoveryFile);
+ } else {
+ result = backupFile.renameTo(recoveryFile);
+ }
+ } else {
+ log.debug("Tries to rename temporary file");
+ result = tempFile.renameTo(recoveryFile);
+ }
+ } catch (Exception e) {
+ DisplayBuffer.add(LocalText.getText("RecoverySaveFailed", e.getMessage()));
+ recoverySaveWarning = false;
+ return;
+ }
+
+ if (result) {
+ log.debug("Renamed to recovery file, path = " + recoveryFile.getAbsolutePath());
+ if (!recoverySaveWarning) {
+ DisplayBuffer.add(LocalText.getText("RecoverySaveSuccessAgain"));
+ recoverySaveWarning = true;
+ }
+ } else {
+ if (recoverySaveWarning) {
+ DisplayBuffer.add(LocalText.getText("RecoverySaveFailed", "file renaming not possible"));
+ recoverySaveWarning = false;
+ }
+ }
+ }
+
protected boolean save(GameAction saveAction) {
-
- String filepath = saveAction.getFilepath();
+ File file = new File(saveAction.getFilepath());
+ return save(file, true, "SaveFailed");
+ }
+
+ protected boolean save(File file, boolean displayErrorMessage, String errorMessageKey) {
boolean result = false;
try {
ObjectOutputStream oos =
- new ObjectOutputStream(new FileOutputStream(new File(
- filepath)));
+ new ObjectOutputStream(new FileOutputStream(file));
oos.writeObject(Game.version+" "+BuildInfo.buildDate);
oos.writeObject(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
oos.writeObject(saveFileVersionID);
@@ -949,10 +1010,11 @@
result = true;
} catch (IOException e) {
- log.error("Save failed", e);
- DisplayBuffer.add(LocalText.getText("SaveFailed", e.getMessage()));
+ log.error(errorMessageKey, e);
+ if (displayErrorMessage) {
+ DisplayBuffer.add(LocalText.getText("SaveFailed", e.getMessage()));
+ }
}
-
return result;
}
Modified: trunk/18xx/rails/ui/swing/GameSetupWindow.java
===================================================================
--- trunk/18xx/rails/ui/swing/GameSetupWindow.java 2010-07-04 20:51:33 UTC (rev 1332)
+++ trunk/18xx/rails/ui/swing/GameSetupWindow.java 2010-07-05 18:02:13 UTC (rev 1333)
@@ -25,7 +25,7 @@
private static final long serialVersionUID = 1L;
GridBagConstraints gc;
JPanel gameListPane, playersPane, buttonPane, optionsPane;
- JButton newButton, loadButton, quitButton, optionButton, infoButton;
+ JButton newButton, loadButton, recoveryButton, quitButton, optionButton, infoButton;
JButton creditsButton, randomizeButton;
JComboBox gameNameBox = new JComboBox();
JComboBox[] playerBoxes = new JComboBox[Player.MAX_PLAYERS];
@@ -66,6 +66,7 @@
newButton = new JButton(LocalText.getText("NewGame"));
loadButton = new JButton(LocalText.getText("LoadGame"));
+ recoveryButton = new JButton(LocalText.getText("RecoverGame"));
quitButton = new JButton(LocalText.getText("QUIT"));
optionButton = new JButton(LocalText.getText("OPTIONS"));
infoButton = new JButton(LocalText.getText("INFO"));
@@ -73,6 +74,7 @@
newButton.setMnemonic(KeyEvent.VK_N);
loadButton.setMnemonic(KeyEvent.VK_L);
+ recoveryButton.setMnemonic(KeyEvent.VK_R);
quitButton.setMnemonic(KeyEvent.VK_Q);
optionButton.setMnemonic(KeyEvent.VK_O);
infoButton.setMnemonic(KeyEvent.VK_G);
@@ -85,12 +87,15 @@
populateGameList(GamesInfo.getGameNames(), gameNameBox);
gameListPane.add(new JLabel("Available Games:"));
+ gameListPane.add(new JLabel("")); // empty slot
gameListPane.add(gameNameBox);
+ gameListPane.add(optionButton);
gameListPane.setLayout(new GridLayout(2, 2));
gameListPane.setBorder(BorderFactory.createLoweredBevelBorder());
newButton.addActionListener(this);
loadButton.addActionListener(this);
+ recoveryButton.addActionListener(this);
quitButton.addActionListener(this);
optionButton.addActionListener(this);
infoButton.addActionListener(this);
@@ -99,7 +104,9 @@
buttonPane.add(newButton);
buttonPane.add(loadButton);
- buttonPane.add(optionButton);
+ if (!Config.get("save.recovery.active", "yes").equalsIgnoreCase("no")) {
+ buttonPane.add(recoveryButton);
+ }
buttonPane.add(infoButton);
buttonPane.add(quitButton);
buttonPane.add(creditsButton);
@@ -187,6 +194,26 @@
}
}
+ /*
+ * loads and start the game given a filename
+ */
+ private void loadAndStartGame(String filePath, String saveDirectory) {
+ if ((game = Game.load(filePath)) == null) {
+ JOptionPane.showMessageDialog(this,
+ DisplayBuffer.get(), "", JOptionPane.ERROR_MESSAGE);
+ return;
+ } else if (DisplayBuffer.getSize() > 0) {
+ JOptionPane.showMessageDialog(this,
+ DisplayBuffer.get(), "", JOptionPane.ERROR_MESSAGE);
+ }
+ startGameUIManager(game);
+ if (saveDirectory != null) {
+ gameUIManager.setSaveDirectory (saveDirectory);
+ }
+ gameUIManager.startLoadedGame();
+ setVisible(false);
+ }
+
public void actionPerformed(ActionEvent arg0) {
if (arg0.getSource().equals(newButton)) {
startNewGame();
@@ -200,24 +227,13 @@
if (jfc.showOpenDialog(getContentPane()) == JFileChooser.APPROVE_OPTION) {
File selectedFile = jfc.getSelectedFile();
- String filepath = selectedFile.getPath();
- saveDirectory = selectedFile.getParent();
- if ((game = Game.load(filepath)) == null) {
- JOptionPane.showMessageDialog(this,
- DisplayBuffer.get(), "", JOptionPane.ERROR_MESSAGE);
- return;
- } else if (DisplayBuffer.getSize() > 0) {
- JOptionPane.showMessageDialog(this,
- DisplayBuffer.get(), "", JOptionPane.ERROR_MESSAGE);
- }
+ loadAndStartGame(selectedFile.getPath(), selectedFile.getParent());
} else { // cancel pressed
return;
}
-
- startGameUIManager(game);
- gameUIManager.setSaveDirectory (saveDirectory);
- gameUIManager.startLoadedGame();
- setVisible(false);
+ } else if (arg0.getSource().equals(recoveryButton)) {
+ String filePath = Config.get("save.recovery.filepath", "18xx_autosave.rails");
+ loadAndStartGame(filePath, null);
} else if (arg0.getSource().equals(infoButton)) {
JOptionPane.showMessageDialog(this,
GamesInfo.getDescription(gameName), "Information about "
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|