SaveManager.cs 10.0 KB

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