using System; using Godot; using Godot.Collections; using FileAccess = Godot.FileAccess; namespace Babushka.scripts.CSharp.Common.Savegame; /// /// Handles the saving and loading of game states. /// Holds the central SaveData object that serves as a temporary SaveFile. /// Automatically writes to disk on every scene change. /// Uses the Godot Json Serializer, which may implicitly convert integers to floats, so be careful when extending! /// public static class SavegameService { public static string SavePath = ""; public static Dictionary SaveDatas = new (); public static bool _loaded = false; public static void AppendDataToSave(string scenename, string id, Dictionary payload) { var saveData = new SaveData(); saveData.SceneName = scenename; saveData.Id = id; saveData.JsonPayload = Json.Stringify(payload, indent: "\t"); AppendSave(saveData); } /// /// Adds or overwrites an entry in the SaveData dictionary. /// /// private static void AppendSave(SaveData saveData) { string key = string.Concat(saveData.SceneName, "_", saveData.Id); if (SaveDatas.TryGetValue(key, out var value)) { SaveDatas[key] = saveData.JsonPayload; } else { SaveDatas.Add(key, saveData.JsonPayload); } } /// /// Checks the SaveData dictionary for an entry and returns the jsondata as a string for it. /// Requires the scenename and object ID for lookup. /// /// /// /// public static Dictionary GetSaveData(string sceneName, string id) { Dictionary saveData = new(); string key = string.Concat(sceneName, "_", id); string saveDataString = ""; if (!_loaded) { GD.Print("SavegameService: SaveFile not loaded."); return saveData; } if (SaveDatas.ContainsKey(key)) { saveDataString = SaveDatas[key]; saveData = Json.ParseString(saveDataString).AsGodotDictionary(); } return saveData; } /// /// Writes the contents of the current SaveData dictionary to disk as a json file. /// public static void Save() { string json = Json.Stringify(SaveDatas, indent: "\t"); GD.Print(SavePath); // create cloud directory System.IO.Directory.CreateDirectory(System.IO.Path.GetDirectoryName(SavePath) ?? ""); try { using var file = FileAccess.Open(SavePath, FileAccess.ModeFlags.Write); file.StoreString(json); } catch (Exception e) { GD.Print(e.Message); } } /// /// Loads the current savegame file from disk and parses it into the SaveData dictionary. /// public static void Load() { try { if (!System.IO.File.Exists(SavePath)) { SaveDatas = new(); return; } string saveDataJson = FileAccess.GetFileAsString(SavePath); SaveDatas = Json.ParseString(saveDataJson).AsGodotDictionary(); } catch(Exception e) { GD.PrintRich(e.Message); return; } _loaded = true; } public static void Reset() { SaveDatas = new (); Save(); } }