using UnityEngine; using System; using System.Collections.Generic; using System.Text; using System.IO; using Util; namespace CM3D2.MultipleMaids.Plugin { public partial class MultipleMaids { private static readonly byte[] pngEnd = Encoding.ASCII.GetBytes("IEND"); private Rect saveManagerRect; private Vector2 saveManagerScrollPos = Vector2.zero; private bool saveManagerInitialize; private int selectedSave; private bool loadSaveFlag = false; private bool overwriteFlag = false; private bool createSaveFlag = false; private string saveScenePath = Path.Combine(Path.GetFullPath(".\\"), "Mod\\MultipleMaidsSave"); private static string sceneData; private List> saveScenes = new List>(50); private Texture2D frame; public void InitializeSaveManager() { frame = MakeTex(2, 2, Color.white); if (!Directory.Exists(saveScenePath)) { Directory.CreateDirectory(saveScenePath); } InitializeSaveList(); saveManagerInitialize = true; } private void InitializeSaveList() { saveScenes.Clear(); DirectoryInfo info = new DirectoryInfo(saveScenePath); foreach (var save in info.GetFiles("*.png")) { Texture2D screenshot = new Texture2D(1, 1, TextureFormat.ARGB32, false); screenshot.LoadImage(File.ReadAllBytes(save.FullName)); saveScenes.Add(new Tuple(save, screenshot)); } saveScenes.Sort((a, b) => a.Item1.LastWriteTime.CompareTo(b.Item1.LastWriteTime)); selectedSave = saveScenes.Count - 1; } private static bool BytesEqual(byte[] a, byte[] b) { if (a.Length != b.Length) return false; for (int i = 0; i < a.Length; i++) { if (a[i] != b[i]) return false; } return true; } private void LoadSave() { string filePath = saveScenes[selectedSave].Item1.FullName; if (!File.Exists(filePath)) { InitializeSaveList(); sceneData = null; return; } using (FileStream fileStream = File.OpenRead(filePath)) { byte[] buffer = new byte[pngEnd.Length]; long position = 0; while (true) { int bytesRead = fileStream.Read(buffer, 0, buffer.Length); if (bytesRead != pngEnd.Length) { return; } if (BytesEqual(buffer, pngEnd)) { fileStream.Position += 4; break; } fileStream.Position = ++position; } using (MemoryStream sceneStream = LZMA.Decompress(fileStream)) { sceneData = Encoding.Unicode.GetString(sceneStream.ToArray()); } } } private void OverWrite() { string filePath = Path.Combine(saveScenePath, saveScenes[selectedSave].Item1.FullName); if (File.Exists(filePath)) { File.Delete(filePath); } saveScenes.RemoveAt(selectedSave); } private void SaveScene() { string sceneString = SerializeScene(true); thum_byte_to_base64_ = ""; #region MM GUI stuff Texture2D screenshot = new Texture2D(1, 1, TextureFormat.ARGB32, false); screenshot.LoadImage(File.ReadAllBytes(thum_file_path_)); float num2 = screenshot.width / (float)screenshot.height; Vector2 vector2 = new Vector2(480f, 270f); int newWidth = screenshot.width; int newHeight = screenshot.height; if (vector2.x < (double)screenshot.width && vector2.y < (double)screenshot.height) { newWidth = (int)vector2.x; newHeight = Mathf.RoundToInt(newWidth / num2); if (vector2.y < (double)newHeight) { newHeight = (int)vector2.y; newWidth = Mathf.RoundToInt(newHeight * num2); } } else if (vector2.x < (double)screenshot.width) { newWidth = (int)vector2.x; newHeight = Mathf.RoundToInt(newWidth / num2); } else if (vector2.y < (double)screenshot.height) { newHeight = (int)vector2.y; newWidth = Mathf.RoundToInt(newHeight * num2); } TextureScale.Bilinear(screenshot, newWidth, newHeight); #endregion string filePath = Path.Combine(saveScenePath, $"mmsave{DateTime.Now:yyyyMMddHHmmss}.png"); using (FileStream fileStream = File.Create(filePath)) using (MemoryStream sceneStream = new MemoryStream(Encoding.Unicode.GetBytes(sceneString))) { byte[] screenshotBuffer = screenshot.EncodeToPNG(); byte[] sceneBuffer = LZMA.Compress(sceneStream); fileStream.Write(screenshotBuffer, 0, screenshotBuffer.Length); fileStream.Write(sceneBuffer, 0, sceneBuffer.Length); } saveScenes.Add(new Tuple(new FileInfo(filePath), screenshot)); selectedSave = saveScenes.Count - 1; thum_file_path_ = ""; } private class Tuple { public T1 Item1 { get; } public T2 Item2 { get; } public Tuple(T1 Item1, T2 Item2) { this.Item1 = Item1; this.Item2 = Item2; } } } }