SaveManager.cs 10 KB

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