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++)
92 IO.Compress(path, text);
96 File.WriteAllText(path, text);
98 DirectoryInfo[] directories =
new DirectoryInfo(
pathCurrentSave).GetDirectories();
99 foreach (DirectoryInfo directoryInfo
in directories)
101 if (
int.TryParse(directoryInfo.Name, out var result) && !
EClass.
game.
spatials.
map.ContainsKey(result))
103 IO.DeleteDirectory(directoryInfo.FullName);
104 Debug.Log(
"Deleting unused map:" + directoryInfo.FullName);
117 Debug.Log(
"Start backup:" + index.
id);
118 string id = index.
id;
119 bool cloud = index.
cloud;
122 IO.CreateDirectory(text);
124 List<DirectoryInfo> dirs =
new DirectoryInfo(text).GetDirectories().ToList();
125 dirs.ForeachReverse(delegate(DirectoryInfo i)
127 if (!
int.TryParse(i.Name, out var _))
132 dirs.Sort((DirectoryInfo a, DirectoryInfo b) =>
int.Parse(a.Name) -
int.Parse(b.Name));
133 int count = dirs.Count;
134 Debug.Log(
"Deleting excess backup:" + dirs.Count +
"/" +
NumBackup);
137 for (
int j = 0; j < count -
NumBackup; j++)
139 IO.DeleteDirectory(dirs[j].FullName);
142 Debug.Log(
"Copying backup:");
143 string newId =
GetNewId(text +
"/",
"", (dirs.Count == 0) ? 1 :
int.Parse(dirs.LastItem().Name));
157 string path = root +
"/game.txt";
158 foreach (KeyValuePair<string, string> fallbackType
in gameIndex.fallbackTypes)
164 gameIndex.cloud =
true;
167 else if (!File.Exists(path))
171 return JsonConvert.DeserializeObject<
Game>(IO.IsCompressed(path) ? IO.Decompress(path) : File.ReadAllText(path),
jsReadGame);
178 path = CorePath.RootSaveCloud +
"/" + id;
180 Debug.Log(
"Prepareing Steam Cloud:" +
id +
": " + path);
181 string text = CorePath.RootSaveCloud +
"/cloud.zip";
182 string text2 = path +
"/cloud.zip";
185 if (File.Exists(text))
189 if (File.Exists(text2))
193 ZipFile.CreateFromDirectory(path, text);
194 if (File.Exists(text2))
198 File.Move(text, text2);
208 Debug.Log(
"LoadGame using cloud save");
209 string text = pathSave +
"/cloud.zip";
210 string text2 = CorePath.RootSaveCloud +
"/cloud.zip";
214 if (!File.Exists(text))
216 EClass.
ui.Say(
"Steam Cloud save not found:" + text);
219 if (File.Exists(text2))
223 File.Move(text, text2);
224 IO.DeleteDirectory(pathSave);
226 Directory.CreateDirectory(pathSave);
227 ZipFile.ExtractToDirectory(text2, pathSave);
228 if (File.Exists(text))
232 File.Move(text2, text);
239 Debug.Log(
"Try restore backup:");
240 if (Directory.Exists(pathSave))
242 Directory.Delete(pathSave);
244 File.Move(text2, text);
254 IO.SaveFile(i.
path +
"/index.txt", i);
257 public static void SaveFile(
string path,
object obj)
267 public static void DeleteGame(
string id,
bool cloud,
bool deleteBackup =
true)
270 if (!Directory.Exists(path))
274 DirectoryInfo directoryInfo =
new DirectoryInfo(path);
275 if (directoryInfo.Exists)
277 directoryInfo.Delete(recursive:
true);
282 if (directoryInfo.Exists)
284 directoryInfo.Delete(recursive:
true);
289 public static List<GameIndex>
GetGameList(
string path,
bool sortByName =
false,
bool includeEmptyFolder =
false)
291 List<GameIndex> list =
new List<GameIndex>();
292 DirectoryInfo directoryInfo =
new DirectoryInfo(path);
293 if (!directoryInfo.Exists)
297 DirectoryInfo[] directories = directoryInfo.GetDirectories();
298 foreach (DirectoryInfo directoryInfo2
in directories)
300 if (File.Exists(directoryInfo2?.ToString() +
"/index.txt"))
304 GameIndex gameIndex = IO.LoadFile<
GameIndex>(directoryInfo2?.ToString() +
"/index.txt");
305 gameIndex.id = directoryInfo2.Name;
306 gameIndex.path = directoryInfo2.FullName;
309 catch (Exception message)
318 if (includeEmptyFolder && Directory.Exists(
CorePath.
PathBackup + directoryInfo2.Name))
321 gameIndex2.id = directoryInfo2.Name;
322 gameIndex2.path = directoryInfo2.FullName;
323 gameIndex2.date = (gameIndex2.real =
new Date());
324 list.Add(gameIndex2);
331 int.TryParse(a.
id, out var result);
332 int.TryParse(b.
id, out var result2);
333 return result2 - result;
345 DirectoryInfo[] directories =
new DirectoryInfo(path).GetDirectories();
346 foreach (DirectoryInfo directoryInfo
in directories)
348 if (!File.Exists(directoryInfo?.ToString() +
"/game.txt"))
350 directoryInfo.Delete(recursive:
true);
355 public static string GetNewId(
string path,
string prefix =
"",
int start = 1)
358 for (
int i = start; i < 999999; i++)
361 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 JsonSerializerSettings jsReadGame
static Game LoadGame(string id, string root, bool cloud)
static void PrepareSteamCloud(string id, string path="")
static bool TryLoadSteamCloud(string pathSave)
static List< GameIndex > GetGameList(string path, bool sortByName=false, bool includeEmptyFolder=false)
static void MakeBackup(GameIndex index, string suffix="")
GameIndex Create(Game game)
static Dictionary< string, string > fallbackTypes
static readonly ShouldSerializeContractResolver Instance
bool IsSaveCompatible(Version v)