1
0

SaveManager.cs 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306
  1. using UnityEngine;
  2. using System;
  3. using System.Linq;
  4. using System.Collections.Generic;
  5. using System.Text;
  6. using System.IO;
  7. using Util;
  8. namespace CM3D2.MultipleMaids.Plugin
  9. {
  10. public partial class MultipleMaids
  11. {
  12. private static readonly byte[] pngEnd = Encoding.ASCII.GetBytes("IEND");
  13. private static string sceneData;
  14. private const string baseDirectoryName = "< Base Directory >";
  15. private string saveScenePath = Path.Combine(Path.GetFullPath(".\\"), "Mod\\MultipleMaidsSave");
  16. private List<SavePng> saveScenes = new List<SavePng>(50);
  17. private GUIStyle selectedButtonStyle;
  18. private string[] directoryList;
  19. private Texture2D frame;
  20. private Rect saveManagerRect;
  21. private Rect saveModalRect;
  22. private Rect resizeManagerRect;
  23. private Vector2 saveManagerScrollPos = Vector2.zero;
  24. private Vector2 dirListScrollPos = Vector2.zero;
  25. private bool saveManagerInitialize = false;
  26. private bool loadSaveFlag = false;
  27. private bool overwriteFlag = false;
  28. private bool createSaveFlag = false;
  29. private bool manageSaveFlag = false;
  30. private bool createDirectory = false;
  31. private bool deleteDirectoryFlag = false;
  32. private bool deleteFileFlag = false;
  33. private bool resizeManager = false;
  34. private int selectedSave = 0;
  35. private int selectedDirectory = 0;
  36. private string currentDirectory = "";
  37. private string textFieldValue = "";
  38. public void InitializeSaveManager()
  39. {
  40. frame = MakeTex(2, 2, Color.white);
  41. if (!Directory.Exists(saveScenePath))
  42. {
  43. Directory.CreateDirectory(saveScenePath);
  44. }
  45. selectedButtonStyle = new GUIStyle("button");
  46. selectedButtonStyle.normal.background = MakeTex(1, 1, new Color(0.5f, 0.5f, 0.5f, 0.4f));
  47. selectedButtonStyle.normal.textColor = Color.white;
  48. GetSaveDirectories();
  49. InitializeSaveList();
  50. saveManagerInitialize = true;
  51. }
  52. private void RefreshSaveManager()
  53. {
  54. SwitchDirectory(currentDirectory);
  55. GetSaveDirectories();
  56. InitializeSaveList();
  57. }
  58. private void InitializeSaveList()
  59. {
  60. saveScenes.Clear();
  61. string workingPath = Path.Combine(saveScenePath, currentDirectory);
  62. DirectoryInfo info = new DirectoryInfo(workingPath);
  63. foreach (var save in info.GetFiles("*.png"))
  64. {
  65. Texture2D screenshot = new Texture2D(1, 1, TextureFormat.ARGB32, false);
  66. screenshot.LoadImage(File.ReadAllBytes(save.FullName));
  67. saveScenes.Add(new SavePng(save, screenshot));
  68. }
  69. selectedSave = saveScenes.Count == 0 ? 0 : saveScenes.Count - 1;
  70. saveScenes.Sort((a, b) => a.info.LastWriteTime.CompareTo(b.info.LastWriteTime));
  71. saveManagerScrollPos.y = 0;
  72. }
  73. private void GetSaveDirectories()
  74. {
  75. DirectoryInfo[] directoryInfo = new DirectoryInfo(saveScenePath).GetDirectories();
  76. directoryList = new string[directoryInfo.Length + 1];
  77. directoryList[0] = baseDirectoryName;
  78. for (int i = 0; i < directoryInfo.Length; i++)
  79. {
  80. directoryList[i + 1] = directoryInfo[i].Name;
  81. }
  82. }
  83. private void SwitchDirectory(string target)
  84. {
  85. if (target.Equals(baseDirectoryName)) target = "";
  86. string targetDirectory = Path.Combine(saveScenePath, target);
  87. if (!Directory.Exists(targetDirectory))
  88. {
  89. currentDirectory = "";
  90. selectedDirectory = 0;
  91. GetSaveDirectories();
  92. }
  93. else
  94. {
  95. selectedDirectory = Array.FindIndex(directoryList, d => d.Equals(target, StringComparison.OrdinalIgnoreCase));
  96. selectedDirectory = selectedDirectory == -1 ? 0 : selectedDirectory;
  97. if (target == currentDirectory) return;
  98. currentDirectory = target;
  99. }
  100. InitializeSaveList();
  101. }
  102. private void LoadSave()
  103. {
  104. string filePath = saveScenes[selectedSave].info.FullName;
  105. if (!File.Exists(filePath))
  106. {
  107. InitializeSaveList();
  108. sceneData = null;
  109. return;
  110. }
  111. using (FileStream fileStream = File.OpenRead(filePath))
  112. {
  113. byte[] buffer = new byte[pngEnd.Length];
  114. long position = 0;
  115. while (true)
  116. {
  117. int bytesRead = fileStream.Read(buffer, 0, buffer.Length);
  118. if (bytesRead != pngEnd.Length)
  119. {
  120. sceneData = null;
  121. return;
  122. }
  123. if (BytesEqual(buffer, pngEnd))
  124. {
  125. fileStream.Position += 4;
  126. break;
  127. }
  128. fileStream.Position = ++position;
  129. }
  130. using (MemoryStream sceneStream = LZMA.Decompress(fileStream))
  131. {
  132. sceneData = Encoding.Unicode.GetString(sceneStream.ToArray());
  133. }
  134. }
  135. SavePng temp = saveScenes[selectedSave];
  136. FileSystemInfo info = temp.info;
  137. info.LastWriteTime = info.LastAccessTime = DateTime.Now;
  138. saveScenes.RemoveAt(selectedSave);
  139. saveScenes.Add(temp);
  140. saveManagerScrollPos.y = 0;
  141. }
  142. private void Overwrite()
  143. {
  144. string filePath = saveScenes[selectedSave].info.FullName;
  145. if (!File.Exists(filePath))
  146. {
  147. RefreshSaveManager();
  148. }
  149. else
  150. {
  151. File.Delete(filePath);
  152. saveScenes.RemoveAt(selectedSave);
  153. saveManagerScrollPos.y = 0;
  154. }
  155. }
  156. private void MakeNewDirectory(string directoryName)
  157. {
  158. directoryName = string.Join("", directoryName.Split(Path.GetInvalidFileNameChars()));
  159. string newDirectory = Path.Combine(saveScenePath, directoryName);
  160. if (!Directory.Exists(newDirectory))
  161. {
  162. Directory.CreateDirectory(newDirectory);
  163. }
  164. GetSaveDirectories();
  165. SwitchDirectory(directoryName);
  166. }
  167. private void DeleteDirectory()
  168. {
  169. string directory = Path.Combine(saveScenePath, directoryList[selectedDirectory]);
  170. if (Directory.Exists(directory))
  171. {
  172. DirectoryInfo dirInfo = new DirectoryInfo(directory);
  173. foreach (var finfo in dirInfo.GetFiles())
  174. {
  175. finfo.Delete();
  176. }
  177. dirInfo.Delete();
  178. }
  179. RefreshSaveManager();
  180. }
  181. private void DeleteFile()
  182. {
  183. string file = saveScenes[selectedSave].info.FullName;
  184. if (File.Exists(file))
  185. {
  186. saveScenes[selectedSave].info.Delete();
  187. saveScenes.RemoveAt(selectedSave);
  188. }
  189. RefreshSaveManager();
  190. }
  191. private void SaveScene()
  192. {
  193. string saveDirectory = Path.Combine(saveScenePath, currentDirectory);
  194. if (!Directory.Exists(saveDirectory))
  195. {
  196. thum_byte_to_base64_ = "";
  197. thum_file_path_ = "";
  198. RefreshSaveManager();
  199. return;
  200. }
  201. string sceneString = SerializeScene(true);
  202. #region MM GUI stuff
  203. Texture2D screenshot = new Texture2D(1, 1, TextureFormat.ARGB32, false);
  204. screenshot.LoadImage(File.ReadAllBytes(thum_file_path_));
  205. float num2 = screenshot.width / (float)screenshot.height;
  206. Vector2 vector2 = new Vector2(480f, 270f);
  207. int newWidth = screenshot.width;
  208. int newHeight = screenshot.height;
  209. if (vector2.x < (double)screenshot.width && vector2.y < (double)screenshot.height)
  210. {
  211. newWidth = (int)vector2.x;
  212. newHeight = Mathf.RoundToInt(newWidth / num2);
  213. if (vector2.y < (double)newHeight)
  214. {
  215. newHeight = (int)vector2.y;
  216. newWidth = Mathf.RoundToInt(newHeight * num2);
  217. }
  218. }
  219. else if (vector2.x < (double)screenshot.width)
  220. {
  221. newWidth = (int)vector2.x;
  222. newHeight = Mathf.RoundToInt(newWidth / num2);
  223. }
  224. else if (vector2.y < (double)screenshot.height)
  225. {
  226. newHeight = (int)vector2.y;
  227. newWidth = Mathf.RoundToInt(newHeight * num2);
  228. }
  229. TextureScale.Bilinear(screenshot, newWidth, newHeight);
  230. #endregion
  231. thum_byte_to_base64_ = "";
  232. thum_file_path_ = "";
  233. string filePath = Path.Combine(saveDirectory, $"mmsave{DateTime.Now:yyyyMMddHHmmss}.png");
  234. using (FileStream fileStream = File.Create(filePath))
  235. using (MemoryStream sceneStream = new MemoryStream(Encoding.Unicode.GetBytes(sceneString)))
  236. {
  237. byte[] screenshotBuffer = screenshot.EncodeToPNG();
  238. byte[] sceneBuffer = LZMA.Compress(sceneStream);
  239. fileStream.Write(screenshotBuffer, 0, screenshotBuffer.Length);
  240. fileStream.Write(sceneBuffer, 0, sceneBuffer.Length);
  241. }
  242. saveScenes.Add(new SavePng(new FileInfo(filePath), screenshot));
  243. selectedSave = saveScenes.Count - 1;
  244. }
  245. private static bool BytesEqual(byte[] a, byte[] b)
  246. {
  247. if (a.Length != b.Length) return false;
  248. for (int i = 0; i < a.Length; i++)
  249. {
  250. if (a[i] != b[i]) return false;
  251. }
  252. return true;
  253. }
  254. class SavePng
  255. {
  256. public FileInfo info { get; }
  257. public Texture2D screenshot { get; }
  258. public SavePng(FileInfo info, Texture2D screenshot)
  259. {
  260. this.info = info;
  261. this.screenshot = screenshot;
  262. }
  263. }
  264. }
  265. }