Skip to content

Commit

Permalink
backup savegames in case of computer hardware malfunction
Browse files Browse the repository at this point in the history
The backups are removed at game over, so permadeath still enforced.
  • Loading branch information
Mikolaj committed Mar 20, 2011
1 parent f46dafe commit 1f87418
Show file tree
Hide file tree
Showing 4 changed files with 32 additions and 12 deletions.
3 changes: 2 additions & 1 deletion src/Action.hs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import Display2 hiding (display)
import Message
import State
import Level
import qualified Save

newtype Action a = Action
{ runAction ::
Expand Down Expand Up @@ -53,7 +54,7 @@ handlerToIO :: Session -> State -> Message -> Action () -> IO ()
handlerToIO session state msg h =
runAction h
session
(shutdown session) -- get out of the game
(Save.rmBkp (sconfig state) >> shutdown session) -- get out of the game
(perception_ state) -- cached perception
(\ _ _ x -> return x) -- final continuation returns result
(ioError $ userError "unhandled abort")
Expand Down
7 changes: 5 additions & 2 deletions src/Actions.hs
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,9 @@ import Message
import Monster
import Perception
import Random
import qualified Save as S
import State
import qualified Config
import qualified Save

displayHistory :: Action ()
displayHistory =
Expand All @@ -52,7 +52,7 @@ saveGame =
then do
-- Save the game state
st <- get
liftIO $ S.saveGame st
liftIO $ Save.saveGame st
ln <- gets (lname . slevel)
let total = calculateTotal st
status = H.Camping ln
Expand Down Expand Up @@ -400,6 +400,9 @@ lvlchange vdir =
updatePlayerBody (\ p -> p { mloc = nloc })
-- Change the level of the player recorded in cursor.
modify (updateCursor (\ c -> c { creturnLn = nln }))
-- Create a backup of the savegame.
state <- get
liftIO $ Save.saveGame state >> Save.mvBkp (sconfig state)
_ -> -- no stairs
if targeting
then do
Expand Down
2 changes: 1 addition & 1 deletion src/Config.hs
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ defaultCP :: CP
defaultCP = toCP defCF

-- | Path to the user configuration file.
file :: IO String
file :: IO FilePath
file =
do
appData <- getAppUserDataDirectory "LambdaHack"
Expand Down
32 changes: 24 additions & 8 deletions src/Save.hs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import State
import qualified Config

-- | Name of the save game.
file :: Config.CP -> IO String
file :: Config.CP -> IO FilePath
file config = Config.getFile config "files" "saveGame"

-- | We save a simple serialized version of the current level and
Expand All @@ -18,7 +18,7 @@ saveGame :: State -> IO ()
saveGame state =
do
f <- file (sconfig state)
encodeCompressedFile f (state,False)
encodeCompressedFile f (state, False)

-- | Restore a saved game. Returns either the current level and
-- game state, or a string containing an error message if restoring
Expand All @@ -27,10 +27,26 @@ restoreGame :: Config.CP -> IO (Either State String)
restoreGame config =
E.catch (do
f <- file config
r <- strictDecodeCompressedFile f
removeFile f
case r of
(x,z) -> (z :: Bool) `seq` return $ Left x)
(x, z) <- strictDecodeCompressedFile f
mvBkp config
(z :: Bool) `seq` return $ Left x)
(\ e -> case e :: IOException of
_ -> return (Right $ "Restore failed: " ++
(unwords . lines) (show e)))
_ -> return (Right $
"Restore failed: "
++ (unwords . lines) (show e)))

-- | Move the savegame file to a backup slot.
mvBkp :: Config.CP -> IO ()
mvBkp config =
do
f <- file config
renameFile f (f ++ ".bkp")

-- | Remove the backup of the savegame. Should be called before any
-- non-error exit from the game.
rmBkp :: Config.CP -> IO ()
rmBkp config =
do
f <- file config
E.catch (removeFile (f ++ ".bkp"))
(\ e -> case e :: IOException of _ -> return ())

0 comments on commit 1f87418

Please sign in to comment.