2using System.Collections.Generic;
4using System.IO.Compression;
7using Newtonsoft.Json.Serialization;
12 public static JsonSerializerSettings
jsReadGame =
new JsonSerializerSettings
14 NullValueHandling = NullValueHandling.Ignore,
15 DefaultValueHandling = DefaultValueHandling.Ignore,
16 PreserveReferencesHandling = PreserveReferencesHandling.Objects,
17 TypeNameHandling = TypeNameHandling.Auto,
19 SerializationBinder = GameSerializationBinder.Instance
22 public static JsonSerializerSettings
jsWriteGame =
new JsonSerializerSettings
24 NullValueHandling = NullValueHandling.Ignore,
25 DefaultValueHandling = DefaultValueHandling.Ignore,
26 PreserveReferencesHandling = PreserveReferencesHandling.Objects,
27 TypeNameHandling = TypeNameHandling.Auto,
32 public static Formatting
formatting = Formatting.Indented;
44 JsonSerializerSettings jsonSerializerSettings =
jsReadGame;
45 jsonSerializerSettings.Error = (EventHandler<Newtonsoft.Json.Serialization.ErrorEventArgs>)Delegate.Combine(jsonSerializerSettings.Error, (EventHandler<Newtonsoft.Json.Serialization.ErrorEventArgs>)delegate(
object sender, Newtonsoft.Json.Serialization.ErrorEventArgs args)
47 if (args.ErrorContext.Error.Message.Contains(
"UnknownTypePlaceholder"))
49 args.ErrorContext.Handled =
true;
56 DirectoryInfo directoryInfo =
new DirectoryInfo(
pathTemp);
57 if (directoryInfo.Exists)
59 directoryInfo.Delete(recursive:
true);
66 DirectoryInfo directoryInfo =
new DirectoryInfo(
pathTemp);
67 if (directoryInfo.Exists)
69 DirectoryInfo[] directories = directoryInfo.GetDirectories();
70 for (
int i = 0; i < directories.Length; i++)
72 directories[i].Delete(recursive:
true);
74 FileInfo[] files = directoryInfo.GetFiles();
75 for (
int i = 0; i < files.Length; i++)
85 DirectoryInfo[] directories =
new DirectoryInfo(
pathCurrentSave).GetDirectories();
86 foreach (DirectoryInfo directoryInfo
in directories)
88 if (
int.TryParse(directoryInfo.Name, out var result) && !
EClass.
game.
spatials.
map.ContainsKey(result))
90 IO.DeleteDirectory(directoryInfo.FullName);
91 Debug.Log(
"Deleting unused map:" + directoryInfo.FullName);
105 IO.DeleteFile(path +
"cloud.zip");
108 if (zone.
map !=
null)
120 string path = root +
"game.txt";
124 IO.SaveFile(root +
"index.txt", gameIndex);
127 IO.Compress(path, text);
131 File.WriteAllText(path, text);
138 Debug.Log(
"Start backup:" + index.
id);
139 string id = index.
id;
140 bool cloud = index.
cloud;
143 IO.CreateDirectory(text);
145 List<DirectoryInfo> dirs =
new DirectoryInfo(text).GetDirectories().ToList();
146 dirs.ForeachReverse(delegate(DirectoryInfo i)
148 if (!
int.TryParse(i.Name, out var _))
153 dirs.Sort((DirectoryInfo a, DirectoryInfo b) =>
int.Parse(a.Name) -
int.Parse(b.Name));
154 int count = dirs.Count;
155 Debug.Log(
"Deleting excess backup:" + dirs.Count +
"/" +
NumBackup);
158 for (
int num = 0; num < count -
NumBackup; num++)
160 IO.DeleteDirectory(dirs[num].FullName);
163 Debug.Log(
"Copying backup:");
164 string newId =
GetNewId(text +
"/",
"", (dirs.Count == 0) ? 1 :
int.Parse(dirs.LastItem().Name));
178 string path = root +
"/game.txt";
179 foreach (KeyValuePair<string, string> fallbackType
in gameIndex.fallbackTypes)
181 ModUtil.
fallbackTypes[fallbackType.Key] = fallbackType.Value;
185 gameIndex.cloud =
true;
188 else if (!File.Exists(path))
192 return JsonConvert.DeserializeObject<
Game>(IO.IsCompressed(path) ? IO.Decompress(path) : File.ReadAllText(path),
jsReadGame);
199 path = CorePath.RootSaveCloud +
"/" + id;
201 Debug.Log(
"Prepareing Steam Cloud:" +
id +
": " + path);
202 string text = CorePath.RootSaveCloud +
"/cloud.zip";
203 string text2 = path +
"/cloud.zip";
206 if (File.Exists(text))
210 if (File.Exists(text2))
214 ZipFile.CreateFromDirectory(path, text);
215 if (File.Exists(text2))
219 File.Move(text, text2);
229 Debug.Log(
"LoadGame using cloud save");
230 string text = pathSave +
"/cloud.zip";
231 string text2 = CorePath.RootSaveCloud +
"/cloud.zip";
235 if (!File.Exists(text))
237 EClass.
ui.Say(
"Steam Cloud save not found:" + text);
240 if (File.Exists(text2))
244 File.Move(text, text2);
245 IO.DeleteDirectory(pathSave);
247 Directory.CreateDirectory(pathSave);
248 ZipFile.ExtractToDirectory(text2, pathSave);
249 if (File.Exists(text))
253 File.Move(text2, text);
260 Debug.Log(
"Try restore backup:");
261 if (Directory.Exists(pathSave))
263 Directory.Delete(pathSave);
265 File.Move(text2, text);
275 IO.SaveFile(i.
path +
"/index.txt", i);
278 public static void SaveFile(
string path,
object obj)
288 public static void DeleteGame(
string id,
bool cloud,
bool deleteBackup =
true)
291 if (!Directory.Exists(path))
295 DirectoryInfo directoryInfo =
new DirectoryInfo(path);
296 if (directoryInfo.Exists)
298 directoryInfo.Delete(recursive:
true);
303 if (directoryInfo.Exists)
305 directoryInfo.Delete(recursive:
true);
310 public static List<GameIndex>
GetGameList(
string path,
bool sortByName =
false,
bool includeEmptyFolder =
false)
312 List<GameIndex> list =
new List<GameIndex>();
313 DirectoryInfo directoryInfo =
new DirectoryInfo(path);
314 if (!directoryInfo.Exists)
318 DirectoryInfo[] directories = directoryInfo.GetDirectories();
319 foreach (DirectoryInfo directoryInfo2
in directories)
321 if (File.Exists(directoryInfo2?.ToString() +
"/index.txt"))
325 GameIndex gameIndex = IO.LoadFile<
GameIndex>(directoryInfo2?.ToString() +
"/index.txt");
326 gameIndex.id = directoryInfo2.Name;
327 gameIndex.path = directoryInfo2.FullName;
330 catch (Exception message)
339 if (includeEmptyFolder && Directory.Exists(
CorePath.
PathBackup + directoryInfo2.Name))
342 gameIndex2.id = directoryInfo2.Name;
343 gameIndex2.path = directoryInfo2.FullName;
344 gameIndex2.date = (gameIndex2.real =
new Date());
345 list.Add(gameIndex2);
352 int.TryParse(a.
id, out var result);
353 int.TryParse(b.
id, out var result2);
354 return result2 - result;
366 DirectoryInfo[] directories =
new DirectoryInfo(path).GetDirectories();
367 foreach (DirectoryInfo directoryInfo
in directories)
369 if (!File.Exists(directoryInfo?.ToString() +
"/game.txt"))
371 directoryInfo.Delete(recursive:
true);
376 public static string GetNewId(
string path,
string prefix =
"",
int start = 1)
379 for (
int i = start; i < 999999; i++)
382 if (!Directory.Exists(path + text))
static string RootSaveCloud
static string PathBackupCloud
int GetRawReal(int offsetHours=0)
static void SaveFile(string path, object obj)
static void DeleteGame(string id, bool cloud, bool deleteBackup=true)
static T LoadFile< T >(string path)
static string GetNewId(string path, string prefix="", int start=1)
static void DeleteEmptyGameFolders(string path)
static string pathCurrentSave
static bool CanLoad(string root)
static JsonSerializerSettings jsWriteGame
static void UpdateGameIndex(GameIndex i)
static GameIndex SaveGame()
static Formatting formatting
static GameIndex WriteGame(string root)
static JsonSerializerSettings jsReadGame
static Game LoadGame(string id, string root, bool cloud)
static void PrepareSteamCloud(string id, string path="")
static bool TryLoadSteamCloud(string pathSave)
static void SaveGameCopy(string path)
static List< GameIndex > GetGameList(string path, bool sortByName=false, bool includeEmptyFolder=false)
static void MakeBackup(GameIndex index, string suffix="")
GameIndex Create(Game game)
Dictionary< string, string > fallbackTypes
void Save(string path, ZoneExportData export=null, PartialMap partial=null)
static readonly ShouldSerializeContractResolver Instance
bool IsSaveCompatible(Version v)