Elin Decompiled Documentation EA 23.243 Nightly Patch 3
Loading...
Searching...
No Matches
GameIO.cs
Go to the documentation of this file.
1using System;
2using System.Collections.Generic;
3using System.IO;
4using System.IO.Compression;
5using System.Linq;
6using Newtonsoft.Json;
7using Newtonsoft.Json.Serialization;
8using UnityEngine;
9
10public class GameIO : EClass
11{
12 public static JsonSerializerSettings jsReadGame = new JsonSerializerSettings
13 {
14 NullValueHandling = NullValueHandling.Ignore,
15 DefaultValueHandling = DefaultValueHandling.Ignore,
16 PreserveReferencesHandling = PreserveReferencesHandling.Objects,
17 TypeNameHandling = TypeNameHandling.Auto,
18 Error = IO.OnError,
19 SerializationBinder = GameSerializationBinder.Instance
20 };
21
22 public static JsonSerializerSettings jsWriteGame = new JsonSerializerSettings
23 {
24 NullValueHandling = NullValueHandling.Ignore,
25 DefaultValueHandling = DefaultValueHandling.Ignore,
26 PreserveReferencesHandling = PreserveReferencesHandling.Objects,
27 TypeNameHandling = TypeNameHandling.Auto,
29 Error = IO.OnError
30 };
31
32 public static Formatting formatting = Formatting.Indented;
33
34 public static string pathCurrentSave => (EClass.core.game.isCloud ? CorePath.RootSaveCloud : CorePath.RootSave) + Game.id + "/";
35
36 public static string pathTemp => pathCurrentSave + "Temp/";
37
38 public static int NumBackup => (int)MathF.Max(5f, EClass.core.config.game.numBackup);
39
41
42 public static void Init()
43 {
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)
46 {
47 if (args.ErrorContext.Error.Message.Contains("UnknownTypePlaceholder"))
48 {
49 args.ErrorContext.Handled = true;
50 }
51 });
52 }
53
54 public static void ResetTemp()
55 {
56 DirectoryInfo directoryInfo = new DirectoryInfo(pathTemp);
57 if (directoryInfo.Exists)
58 {
59 directoryInfo.Delete(recursive: true);
60 }
61 IO.CreateDirectory(pathTemp);
62 }
63
64 public static void ClearTemp()
65 {
66 DirectoryInfo directoryInfo = new DirectoryInfo(pathTemp);
67 if (directoryInfo.Exists)
68 {
69 DirectoryInfo[] directories = directoryInfo.GetDirectories();
70 for (int i = 0; i < directories.Length; i++)
71 {
72 directories[i].Delete(recursive: true);
73 }
74 FileInfo[] files = directoryInfo.GetFiles();
75 for (int i = 0; i < files.Length; i++)
76 {
77 files[i].Delete();
78 }
79 }
80 }
81
82 public static GameIndex SaveGame()
83 {
84 string text = JsonConvert.SerializeObject(EClass.core.game, formatting, jsWriteGame);
85 string path = pathCurrentSave + "game.txt";
86 GameIndex gameIndex = new GameIndex().Create(EClass.core.game);
87 gameIndex.id = Game.id;
88 gameIndex.cloud = EClass.game.isCloud;
89 IO.SaveFile(pathCurrentSave + "index.txt", gameIndex);
90 if (compressSave)
91 {
92 IO.Compress(path, text);
93 }
94 else
95 {
96 File.WriteAllText(path, text);
97 }
98 DirectoryInfo[] directories = new DirectoryInfo(pathCurrentSave).GetDirectories();
99 foreach (DirectoryInfo directoryInfo in directories)
100 {
101 if (int.TryParse(directoryInfo.Name, out var result) && !EClass.game.spatials.map.ContainsKey(result))
102 {
103 IO.DeleteDirectory(directoryInfo.FullName);
104 Debug.Log("Deleting unused map:" + directoryInfo.FullName);
105 }
106 }
107 ClearTemp();
108 if (gameIndex.cloud)
109 {
110 PrepareSteamCloud(gameIndex.id);
111 }
112 return gameIndex;
113 }
114
115 public static void MakeBackup(GameIndex index, string suffix = "")
116 {
117 Debug.Log("Start backup:" + index.id);
118 string id = index.id;
119 bool cloud = index.cloud;
120 IO.CreateDirectory(cloud ? CorePath.PathBackupCloud : CorePath.PathBackup);
121 string text = (cloud ? CorePath.PathBackupCloud : CorePath.PathBackup) + id;
122 IO.CreateDirectory(text);
123 Debug.Log(text);
124 List<DirectoryInfo> dirs = new DirectoryInfo(text).GetDirectories().ToList();
125 dirs.ForeachReverse(delegate(DirectoryInfo i)
126 {
127 if (!int.TryParse(i.Name, out var _))
128 {
129 dirs.Remove(i);
130 }
131 });
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);
135 if (count > NumBackup)
136 {
137 for (int j = 0; j < count - NumBackup; j++)
138 {
139 IO.DeleteDirectory(dirs[j].FullName);
140 }
141 }
142 Debug.Log("Copying backup:");
143 string newId = GetNewId(text + "/", "", (dirs.Count == 0) ? 1 : int.Parse(dirs.LastItem().Name));
144 IO.CopyDir((cloud ? CorePath.RootSaveCloud : CorePath.RootSave) + id + "/", text + "/" + newId, (string s) => s == "Temp");
145 }
146
147 public static bool CanLoad(string root)
148 {
149 GameIndex gameIndex = IO.LoadFile<GameIndex>(root + "/index.txt");
150 return EClass.core.version.IsSaveCompatible(gameIndex.version);
151 }
152
153 public static Game LoadGame(string id, string root, bool cloud)
154 {
155 Game.id = id;
156 GameIndex gameIndex = IO.LoadFile<GameIndex>(root + "/index.txt");
157 string path = root + "/game.txt";
158 foreach (KeyValuePair<string, string> fallbackType in gameIndex.fallbackTypes)
159 {
160 ModUtil.fallbackTypes[fallbackType.Key] = fallbackType.Value;
161 }
162 if (cloud)
163 {
164 gameIndex.cloud = true;
165 Debug.Log(TryLoadSteamCloud(root));
166 }
167 else if (!File.Exists(path))
168 {
169 Debug.Log(TryLoadSteamCloud(root));
170 }
171 return JsonConvert.DeserializeObject<Game>(IO.IsCompressed(path) ? IO.Decompress(path) : File.ReadAllText(path), jsReadGame);
172 }
173
174 public static void PrepareSteamCloud(string id, string path = "")
175 {
176 if (path.IsEmpty())
177 {
178 path = CorePath.RootSaveCloud + "/" + id;
179 }
180 Debug.Log("Prepareing Steam Cloud:" + id + ": " + path);
181 string text = CorePath.RootSaveCloud + "/cloud.zip";
182 string text2 = path + "/cloud.zip";
183 try
184 {
185 if (File.Exists(text))
186 {
187 File.Delete(text);
188 }
189 if (File.Exists(text2))
190 {
191 File.Delete(text2);
192 }
193 ZipFile.CreateFromDirectory(path, text);
194 if (File.Exists(text2))
195 {
196 File.Delete(text2);
197 }
198 File.Move(text, text2);
199 }
200 catch (Exception ex)
201 {
202 EClass.ui.Say(ex.Message);
203 }
204 }
205
206 public static bool TryLoadSteamCloud(string pathSave)
207 {
208 Debug.Log("LoadGame using cloud save");
209 string text = pathSave + "/cloud.zip";
210 string text2 = CorePath.RootSaveCloud + "/cloud.zip";
211 bool flag = false;
212 try
213 {
214 if (!File.Exists(text))
215 {
216 EClass.ui.Say("Steam Cloud save not found:" + text);
217 return true;
218 }
219 if (File.Exists(text2))
220 {
221 File.Delete(text2);
222 }
223 File.Move(text, text2);
224 IO.DeleteDirectory(pathSave);
225 flag = true;
226 Directory.CreateDirectory(pathSave);
227 ZipFile.ExtractToDirectory(text2, pathSave);
228 if (File.Exists(text))
229 {
230 File.Delete(text);
231 }
232 File.Move(text2, text);
233 }
234 catch (Exception ex)
235 {
236 EClass.ui.Say(ex.Message);
237 if (flag)
238 {
239 Debug.Log("Try restore backup:");
240 if (Directory.Exists(pathSave))
241 {
242 Directory.Delete(pathSave);
243 }
244 File.Move(text2, text);
245 return true;
246 }
247 return false;
248 }
249 return true;
250 }
251
252 public static void UpdateGameIndex(GameIndex i)
253 {
254 IO.SaveFile(i.path + "/index.txt", i);
255 }
256
257 public static void SaveFile(string path, object obj)
258 {
259 IO.SaveFile(path, obj, compressSave, jsWriteGame);
260 }
261
262 public static T LoadFile<T>(string path) where T : new()
263 {
264 return IO.LoadFile<T>(path, compressSave, jsReadGame);
265 }
266
267 public static void DeleteGame(string id, bool cloud, bool deleteBackup = true)
268 {
269 string path = (cloud ? CorePath.RootSaveCloud : CorePath.RootSave) + id;
270 if (!Directory.Exists(path))
271 {
272 return;
273 }
274 DirectoryInfo directoryInfo = new DirectoryInfo(path);
275 if (directoryInfo.Exists)
276 {
277 directoryInfo.Delete(recursive: true);
278 }
279 if (deleteBackup)
280 {
281 directoryInfo = new DirectoryInfo((cloud ? CorePath.PathBackupCloud : CorePath.PathBackup) + id);
282 if (directoryInfo.Exists)
283 {
284 directoryInfo.Delete(recursive: true);
285 }
286 }
287 }
288
289 public static List<GameIndex> GetGameList(string path, bool sortByName = false, bool includeEmptyFolder = false)
290 {
291 List<GameIndex> list = new List<GameIndex>();
292 DirectoryInfo directoryInfo = new DirectoryInfo(path);
293 if (!directoryInfo.Exists)
294 {
295 return list;
296 }
297 DirectoryInfo[] directories = directoryInfo.GetDirectories();
298 foreach (DirectoryInfo directoryInfo2 in directories)
299 {
300 if (File.Exists(directoryInfo2?.ToString() + "/index.txt"))
301 {
302 try
303 {
304 GameIndex gameIndex = IO.LoadFile<GameIndex>(directoryInfo2?.ToString() + "/index.txt");
305 gameIndex.id = directoryInfo2.Name;
306 gameIndex.path = directoryInfo2.FullName;
307 list.Add(gameIndex);
308 }
309 catch (Exception message)
310 {
311 Debug.Log(message);
312 goto IL_0097;
313 }
314 continue;
315 }
316 goto IL_0097;
317 IL_0097:
318 if (includeEmptyFolder && Directory.Exists(CorePath.PathBackup + directoryInfo2.Name))
319 {
320 GameIndex gameIndex2 = new GameIndex();
321 gameIndex2.id = directoryInfo2.Name;
322 gameIndex2.path = directoryInfo2.FullName;
323 gameIndex2.date = (gameIndex2.real = new Date());
324 list.Add(gameIndex2);
325 }
326 }
327 if (sortByName)
328 {
329 list.Sort(delegate(GameIndex a, GameIndex b)
330 {
331 int.TryParse(a.id, out var result);
332 int.TryParse(b.id, out var result2);
333 return result2 - result;
334 });
335 }
336 else
337 {
338 list.Sort((GameIndex a, GameIndex b) => b.real.GetRawReal() - a.real.GetRawReal());
339 }
340 return list;
341 }
342
343 public static void DeleteEmptyGameFolders(string path)
344 {
345 DirectoryInfo[] directories = new DirectoryInfo(path).GetDirectories();
346 foreach (DirectoryInfo directoryInfo in directories)
347 {
348 if (!File.Exists(directoryInfo?.ToString() + "/game.txt"))
349 {
350 directoryInfo.Delete(recursive: true);
351 }
352 }
353 }
354
355 public static string GetNewId(string path, string prefix = "", int start = 1)
356 {
357 string text = "";
358 for (int i = start; i < 999999; i++)
359 {
360 text = prefix + i;
361 if (!Directory.Exists(path + text))
362 {
363 break;
364 }
365 }
366 return text;
367 }
368}
Version version
Definition: BaseCore.cs:17
new GameConfig game
Definition: CoreConfig.cs:609
static string RootSave
Definition: CorePath.cs:206
static string RootSaveCloud
Definition: CorePath.cs:208
static string PathBackup
Definition: CorePath.cs:216
static string PathBackupCloud
Definition: CorePath.cs:218
Game game
Definition: Core.cs:72
CoreConfig config
Definition: Core.cs:70
Definition: Date.cs:4
int GetRawReal(int offsetHours=0)
Definition: Date.cs:321
Definition: EClass.cs:6
static Game game
Definition: EClass.cs:9
static Core core
Definition: EClass.cs:7
static UI ui
Definition: EClass.cs:17
Definition: GameIO.cs:11
static void SaveFile(string path, object obj)
Definition: GameIO.cs:257
static void DeleteGame(string id, bool cloud, bool deleteBackup=true)
Definition: GameIO.cs:267
static T LoadFile< T >(string path)
Definition: GameIO.cs:262
static bool compressSave
Definition: GameIO.cs:40
static int NumBackup
Definition: GameIO.cs:38
static string GetNewId(string path, string prefix="", int start=1)
Definition: GameIO.cs:355
static void DeleteEmptyGameFolders(string path)
Definition: GameIO.cs:343
static string pathCurrentSave
Definition: GameIO.cs:34
static bool CanLoad(string root)
Definition: GameIO.cs:147
static JsonSerializerSettings jsWriteGame
Definition: GameIO.cs:22
static void UpdateGameIndex(GameIndex i)
Definition: GameIO.cs:252
static GameIndex SaveGame()
Definition: GameIO.cs:82
static Formatting formatting
Definition: GameIO.cs:32
static void ClearTemp()
Definition: GameIO.cs:64
static JsonSerializerSettings jsReadGame
Definition: GameIO.cs:12
static Game LoadGame(string id, string root, bool cloud)
Definition: GameIO.cs:153
static void Init()
Definition: GameIO.cs:42
static void PrepareSteamCloud(string id, string path="")
Definition: GameIO.cs:174
static bool TryLoadSteamCloud(string pathSave)
Definition: GameIO.cs:206
static void ResetTemp()
Definition: GameIO.cs:54
static string pathTemp
Definition: GameIO.cs:36
static List< GameIndex > GetGameList(string path, bool sortByName=false, bool includeEmptyFolder=false)
Definition: GameIO.cs:289
static void MakeBackup(GameIndex index, string suffix="")
Definition: GameIO.cs:115
GameIndex Create(Game game)
Definition: GameIndex.cs:70
string id
Definition: GameIndex.cs:13
bool cloud
Definition: GameIndex.cs:41
Date real
Definition: GameIndex.cs:11
Version version
Definition: GameIndex.cs:21
string path
Definition: GameIndex.cs:48
Definition: Game.cs:8
static string id
Definition: Game.cs:147
SpatialManager spatials
Definition: Game.cs:152
bool isCloud
Definition: Game.cs:245
static Dictionary< string, string > fallbackTypes
Definition: ModUtil.cs:10
static readonly ShouldSerializeContractResolver Instance
GlobalSpatialList map
bool IsSaveCompatible(Version v)
Definition: Version.cs:82