SaveManager.cs 9.0 KB

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