module Game.LambdaHack.Save
( saveGame, restoreGame, rmBkpSaveDiary, saveGameBkp
) where
import System.Directory
import System.FilePath
import qualified Control.Exception as E hiding (handle)
import Control.Monad
import Game.LambdaHack.Utils.File
import Game.LambdaHack.State
import qualified Game.LambdaHack.Config as Config
saveFile :: Config.CP -> IO FilePath
saveFile config = Config.getFile config "files" "saveFile"
bkpFile :: Config.CP -> IO FilePath
bkpFile config = do
sfile <- saveFile config
return $ sfile ++ ".bkp"
diaryFile :: Config.CP -> IO FilePath
diaryFile config = Config.getFile config "files" "diaryFile"
saveDiary :: State -> Diary -> IO ()
saveDiary state diary = do
dfile <- diaryFile (sconfig state)
encodeEOF dfile diary
saveGame :: State -> Diary -> IO ()
saveGame state diary = do
sfile <- saveFile (sconfig state)
encodeEOF sfile state
saveDiary state diary
tryCreateDir :: FilePath -> IO ()
tryCreateDir dir =
E.catch
(createDirectory dir)
(\ e -> case e :: E.IOException of _ -> return ())
tryCopyDataFiles :: (FilePath -> IO FilePath) -> FilePath -> IO ()
tryCopyDataFiles pathsDataFile dirNew = do
configFile <- pathsDataFile "config.default"
scoresFile <- pathsDataFile "scores"
let configNew = combine dirNew "config"
scoresNew = combine dirNew "scores"
E.catch
(copyFile configFile configNew >>
copyFile scoresFile scoresNew)
(\ e -> case e :: E.IOException of _ -> return ())
restoreGame :: (FilePath -> IO FilePath) -> Config.CP -> String
-> IO (Either (State, Diary) (String, Diary))
restoreGame pathsDataFile config title = do
appData <- Config.appDataDir
ab <- doesDirectoryExist appData
unless ab $ do
tryCreateDir appData
tryCopyDataFiles pathsDataFile appData
diary <-
do dfile <- diaryFile config
db <- doesFileExist dfile
if db
then strictDecodeEOF dfile
else defaultDiary
sfile <- saveFile config
sb <- doesFileExist sfile
if sb
then E.catch
(do mvBkp config
bfile <- bkpFile config
state <- strictDecodeEOF bfile
return $ Left (state, diary))
(\ e -> case e :: E.SomeException of
_ -> let msg = "Starting a new game, because restore failed. "
++ "The error message was: "
++ (unwords . lines) (show e)
in return $ Right (msg, diary))
else
return $ Right ("Welcome to " ++ title ++ "!", diary)
mvBkp :: Config.CP -> IO ()
mvBkp config = do
sfile <- saveFile config
bfile <- bkpFile config
renameFile sfile bfile
saveGameBkp :: State -> Diary -> IO ()
saveGameBkp state diary = do
saveGame state diary
mvBkp (sconfig state)
rmBkpSaveDiary :: State -> Diary -> IO ()
rmBkpSaveDiary state diary = do
saveDiary state diary
bfile <- bkpFile (sconfig state)
bb <- doesFileExist bfile
when bb $ removeFile bfile