| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539 | 
							- using UnityEngine;
 
- using ExIni;
 
- using System;
 
- using System.Collections.Generic;
 
- using System.Text;
 
- using System.IO;
 
- using Util;
 
- namespace CM3D2.MultipleMaids.Plugin
 
- {
 
-     public partial class MultipleMaids
 
-     {
 
-         internal static readonly byte[] pngEnd = Encoding.ASCII.GetBytes("IEND");
 
-         internal static readonly byte[] kankyoHeader = Encoding.ASCII.GetBytes("KANKYO");
 
-         internal const string sceneDirectoryName = "< Scene Root >";
 
-         internal const string kankyoDirectoryName = "< Kankyo Root >";
 
-         internal readonly string saveScenePath = Path.Combine(Path.GetFullPath(".\\"), "Mod\\MultipleMaidsScene");
 
-         private static string kankyoScenePath = Path.Combine(Path.GetFullPath(".\\"), "Mod\\MultipleMaidsKankyo");
 
-         private static string sceneData;
 
-         private static List<ScenePng> scenes = new List<ScenePng>(50);
 
-         private GUIStyle selectedButtonStyle;
 
-         private GUIStyle sceneSortComboStyle;
 
-         private GUIContent infoString;
 
-         private string[] directoryList;
 
-         private Texture2D frame;
 
-         private Texture2D infoHighlight;
 
-         private Rect sceneManagerRect;
 
-         private Rect sceneModalRect;
 
-         private Rect resizeManagerRect;
 
-         private Vector2 sceneManagerScrollPos = Vector2.zero;
 
-         private Vector2 dirListScrollPos = Vector2.zero;
 
-         private bool sceneManagerInitialize = false;
 
-         private bool loadSceneFlag = false;
 
-         private bool overwriteFlag = false;
 
-         private bool createSceneFlag = false;
 
-         private bool quickSaveFlag = false;
 
-         private bool manageSceneFlag = false;
 
-         private bool kankyoModeFlag = false;
 
-         private bool kankyoToggle = false;
 
-         private bool kankyoScene = false;
 
-         private bool createDirectoryFlag = false;
 
-         private bool deleteDirectoryFlag = false;
 
-         private bool deleteSceneFlag = false;
 
-         private bool resizeManager = false;
 
-         private int selectedScene = 0;
 
-         private int selectedDirectory = 0;
 
-         private string currentDirectory = sceneDirectoryName;
 
-         private string textFieldValue = "";
 
-         private readonly ComboBox2 sceneSortCombo = new ComboBox2();
 
-         private static GUIContent[] sceneSortComboList;
 
-         private static int sceneSortModeOld = 0;
 
-         private static bool sceneSortAscendingOld = true;
 
-         private static int selectedSceneSortMode = 0;
 
-         private static bool sceneSortAscending = true;
 
-         private static readonly string[] ConfigSortMode = new[] { "name", "date_created", "date_modified" };
 
-         private enum SortMode
 
-         {
 
-             Name, DateCreated, DateModified
 
-         }
 
-         public void InitializeSceneManager()
 
-         {
 
-             frame = MakeTex(2, 2, Color.white);
 
-             infoHighlight = MakeTex(2, 2, new Color(0f, 0f, 0f, 0.8f));
 
-             sceneSortCombo.selectedItemIndex = selectedSceneSortMode;
 
-             sceneSortComboList = new GUIContent[] {
 
-                 new GUIContent("Name"),
 
-                 new GUIContent("Date Created"),
 
-                 new GUIContent("Date Modified")
 
-             };
 
-             selectedButtonStyle = new GUIStyle("button");
 
-             selectedButtonStyle.normal.background = MakeTex(1, 1, new Color(0.5f, 0.5f, 0.5f, 0.4f));
 
-             selectedButtonStyle.normal.textColor = Color.white;
 
-             sceneSortComboStyle = new GUIStyle();
 
-             sceneSortComboStyle.normal.textColor = Color.white;
 
-             sceneSortComboStyle.normal.background = MakeTex(2, 2, new Color(0.0f, 0.0f, 0.0f, 0.5f));
 
-             sceneSortComboStyle.onHover.background = sceneSortComboStyle.hover.background = new Texture2D(2, 2);
 
-             sceneSortComboStyle.padding.left = sceneSortComboStyle.padding.right = sceneSortComboStyle.padding.top = sceneSortComboStyle.padding.bottom = GetPix(0);
 
-             sceneSortComboStyle.fontSize = GetPix(13);
 
-             currentDirectory = kankyoModeFlag ? kankyoDirectoryName : sceneDirectoryName;
 
-             GetSceneDirectories();
 
-             if (Preferences["scenemanager"]["converted"].Value != "true")
 
-             {
 
-                 ConvertIni();
 
-                 Preferences["scenemanager"]["converted"].Value = "true";
 
-                 SaveConfig();
 
-             }
 
-             GetScenes(currentDirectory);
 
-             sceneManagerInitialize = true;
 
-         }
 
-         private void SaveSceneSortPreferences()
 
-         {
 
-             if (sceneSortAscending != sceneSortAscendingOld || sceneSortModeOld != selectedSceneSortMode)
 
-             {
 
-                 Preferences["scenemanager"]["scene_sort_ascending"].Value = sceneSortAscending ? "true" : "false";
 
-                 Preferences["scenemanager"]["scene_sort_mode"].Value = ConfigSortMode[selectedSceneSortMode];
 
-                 SaveConfig();
 
-                 sceneSortAscendingOld = sceneSortAscending;
 
-                 sceneSortModeOld = selectedSceneSortMode;
 
-             }
 
-         }
 
-         private void RefreshSceneManager()
 
-         {
 
-             SwitchDirectory(currentDirectory);
 
-             GetSceneDirectories();
 
-             GetScenes(currentDirectory);
 
-         }
 
-         private void SwitchDirectory(string target)
 
-         {
 
-             string root = kankyoModeFlag ? kankyoScenePath : saveScenePath;
 
-             string path = target.Equals(sceneDirectoryName) || target.Equals(kankyoDirectoryName)
 
-                 ? ""
 
-                 : target;
 
-             string targetDirectory = Path.Combine(root, path);
 
-             if (!Directory.Exists(targetDirectory))
 
-             {
 
-                 currentDirectory = kankyoModeFlag ? kankyoDirectoryName : sceneDirectoryName;
 
-                 selectedDirectory = 0;
 
-                 GetSceneDirectories();
 
-             }
 
-             else
 
-             {
 
-                 selectedDirectory = Array.FindIndex(directoryList, d => d.Equals(target, StringComparison.OrdinalIgnoreCase));
 
-                 selectedDirectory = selectedDirectory == -1 ? 0 : selectedDirectory;
 
-             }
 
-             if (target == currentDirectory) return;
 
-             currentDirectory = target;
 
-             GetScenes(target);
 
-         }
 
-         private void GetSceneDirectories()
 
-         {
 
-             if (!Directory.Exists(saveScenePath))
 
-             {
 
-                 Directory.CreateDirectory(saveScenePath);
 
-             }
 
-             if (!Directory.Exists(kankyoScenePath))
 
-             {
 
-                 Directory.CreateDirectory(kankyoScenePath);
 
-             }
 
-             string root = kankyoModeFlag ? kankyoScenePath : saveScenePath;
 
-             DirectoryInfo[] directoryInfo = new DirectoryInfo(root).GetDirectories();
 
-             directoryList = new string[directoryInfo.Length + 1];
 
-             directoryList[0] = kankyoModeFlag ? kankyoDirectoryName : sceneDirectoryName;
 
-             for (int i = 0; i < directoryInfo.Length; i++)
 
-             {
 
-                 directoryList[i + 1] = directoryInfo[i].Name;
 
-             }
 
-         }
 
-         private void GetScenes(string target)
 
-         {
 
-             string root = kankyoModeFlag ? kankyoScenePath : saveScenePath;
 
-             scenes.Clear();
 
-             if (target.Equals(sceneDirectoryName) || target.Equals(kankyoDirectoryName))
 
-             {
 
-                 target = "";
 
-             }
 
-             string workingPath = Path.Combine(root, target);
 
-             DirectoryInfo info = new DirectoryInfo(workingPath);
 
-             foreach (var scene in info.GetFiles("*.png"))
 
-             {
 
-                 Texture2D screenshot = new Texture2D(2, 2, TextureFormat.ARGB32, false);
 
-                 screenshot.LoadImage(File.ReadAllBytes(scene.FullName));
 
-                 scenes.Add(new ScenePng(scene, screenshot));
 
-             }
 
-             selectedScene = scenes.Count == 0 ? 0 : scenes.Count - 1;
 
-             SortScenes();
 
-             sceneManagerScrollPos.y = 0;
 
-         }
 
-         private void SortScenes()
 
-         {
 
-             Comparison<ScenePng> sortMode = null;
 
-             switch ((SortMode)selectedSceneSortMode)
 
-             {
 
-                 case SortMode.Name:
 
-                     sortMode = SortByName;
 
-                     break;
 
-                 case SortMode.DateCreated:
 
-                     sortMode = SortByDateCreated;
 
-                     break;
 
-                 case SortMode.DateModified:
 
-                     sortMode = SortByDateModified;
 
-                     break;
 
-             }
 
-             scenes.Sort(sortMode);
 
-         }
 
-         private void SetSceneSortAscending(bool ascending)
 
-         {
 
-             sceneSortAscending = ascending;
 
-             SortScenes();
 
-         }
 
-         private void SetSceneSortMode(int sortMode)
 
-         {
 
-             selectedSceneSortMode = Mathf.Clamp(sortMode, 0, 2);
 
-             SortScenes();
 
-         }
 
-         private static int SortByName(ScenePng a, ScenePng b)
 
-         {
 
-             int direction = sceneSortAscending ? -1 : 1;
 
-             return direction * a.info.Name.CompareTo(b.info.Name);
 
-         }
 
-         private static int SortByDateCreated(ScenePng a, ScenePng b)
 
-         {
 
-             int direction = sceneSortAscending ? -1 : 1;
 
-             return direction * a.info.CreationTime.CompareTo(b.info.CreationTime);
 
-         }
 
-         private static int SortByDateModified(ScenePng a, ScenePng b)
 
-         {
 
-             int direction = sceneSortAscending ? -1 : 1;
 
-             return direction * a.info.LastWriteTime.CompareTo(b.info.LastWriteTime);
 
-         }
 
-         private void CreateDirectory(string directoryName)
 
-         {
 
-             string root = kankyoModeFlag ? kankyoScenePath : saveScenePath;
 
-             directoryName = string.Join("", directoryName.Split(Path.GetInvalidFileNameChars()));
 
-             string newDirectory = Path.Combine(root, directoryName);
 
-             if (!Directory.Exists(newDirectory))
 
-             {
 
-                 Directory.CreateDirectory(newDirectory);
 
-             }
 
-             GetSceneDirectories();
 
-             SwitchDirectory(directoryName);
 
-         }
 
-         private void DeleteDirectory()
 
-         {
 
-             string root = kankyoModeFlag ? kankyoScenePath : saveScenePath;
 
-             string directory = Path.Combine(root, directoryList[selectedDirectory]);
 
-             if (Directory.Exists(directory))
 
-             {
 
-                 DirectoryInfo dirInfo = new DirectoryInfo(directory);
 
-                 foreach (var finfo in dirInfo.GetFiles())
 
-                 {
 
-                     finfo.Delete();
 
-                 }
 
-                 dirInfo.Delete();
 
-                 currentDirectory = sceneDirectoryName;
 
-             }
 
-             RefreshSceneManager();
 
-         }
 
-         private void DeleteScene()
 
-         {
 
-             string file = scenes[selectedScene].info.FullName;
 
-             if (File.Exists(file))
 
-             {
 
-                 scenes[selectedScene].info.Delete();
 
-                 scenes.RemoveAt(selectedScene);
 
-             }
 
-             RefreshSceneManager();
 
-         }
 
-         private void OverwriteScene()
 
-         {
 
-             string file = scenes[selectedScene].info.FullName;
 
-             if (!File.Exists(file))
 
-             {
 
-                 RefreshSceneManager();
 
-             }
 
-         }
 
-         private void SaveScene()
 
-         {
 
-             string target = currentDirectory;
 
-             bool scene = target.Equals(sceneDirectoryName);
 
-             bool kankyo = target.Equals(kankyoDirectoryName);
 
-             if (scene || kankyo)
 
-                 target = "";
 
-             string saveDirectory;
 
-             saveDirectory = kankyoModeFlag
 
-                 ? Path.Combine(kankyoScenePath, target)
 
-                 : Path.Combine(saveScenePath, target);
 
-             if (!Directory.Exists(saveDirectory))
 
-             {
 
-                 thum_byte_to_base64_ = "";
 
-                 thum_file_path_ = "";
 
-                 RefreshSceneManager();
 
-                 return;
 
-             }
 
-             string sceneString = SerializeScene();
 
-             #region MM screenshot processing 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
 
-             thum_byte_to_base64_ = "";
 
-             thum_file_path_ = "";
 
-             string sceneType = kankyoModeFlag ? "mmkankyo" : "mmscene";
 
-             string filePath;
 
-             string fileName = $"{sceneType}{DateTime.Now:yyyyMMddHHmmss}.png";
 
-             FileInfo oldFileInfo = null;
 
-             if (overwriteFlag)
 
-             {
 
-                 oldFileInfo = scenes[selectedScene].info;
 
-                 fileName = oldFileInfo.Name;
 
-                 scenes.RemoveAt(selectedScene);
 
-             }
 
-             filePath = Path.Combine(saveDirectory, fileName);
 
-             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);
 
-                 if (kankyoModeFlag) fileStream.Write(kankyoHeader, 0, kankyoHeader.Length);
 
-                 fileStream.Write(sceneBuffer, 0, sceneBuffer.Length);
 
-             }
 
-             ScenePng newScenePng = new ScenePng(new FileInfo(filePath), screenshot);
 
-             if (oldFileInfo != null)
 
-             {
 
-                 File.SetCreationTime(filePath, oldFileInfo.CreationTime);
 
-                 newScenePng.info.CreationTime = oldFileInfo.CreationTime;
 
-             }
 
-             scenes.Add(newScenePng);
 
-             selectedScene = scenes.Count - 1;
 
-             SortScenes();
 
-         }
 
-         private void ReadScene()
 
-         {
 
-             string filePath = scenes[selectedScene].info.FullName;
 
-             sceneData = null;
 
-             if (!File.Exists(filePath))
 
-             {
 
-                 RefreshSceneManager();
 
-                 return;
 
-             }
 
-             using (FileStream fileStream = File.OpenRead(filePath))
 
-             {
 
-                 long pos = fileStream.Position = fileStream.Length - pngEnd.Length;
 
-                 byte[] buf = new byte[pngEnd.Length];
 
-                 while (true)
 
-                 {
 
-                     if (pos < 0)
 
-                     {
 
-                         Util.Logger.Log(LogLevel.Error, $"Could not read '{Path.GetFileName(filePath)}'");
 
-                         return;
 
-                     }
 
-                     fileStream.Position = pos;
 
-                     fileStream.Read(buf, 0, pngEnd.Length);
 
-                     if (BytesEqual(buf, pngEnd)) break;
 
-                     --pos;
 
-                 }
 
-                 fileStream.Position += 4;
 
-                 byte[] kankyo = new byte[kankyoHeader.Length];
 
-                 fileStream.Read(kankyo, 0, kankyo.Length);
 
-                 if (BytesEqual(kankyo, kankyoHeader))
 
-                 {
 
-                     kankyoScene = true;
 
-                 }
 
-                 else
 
-                 {
 
-                     kankyoScene = false;
 
-                     fileStream.Position -= kankyoHeader.Length;
 
-                 }
 
-                 try
 
-                 {
 
-                     using (var sceneStream = LZMA.Decompress(fileStream))
 
-                     {
 
-                         sceneData = Encoding.Unicode.GetString(sceneStream.ToArray());
 
-                     }
 
-                 }
 
-                 catch (Exception e)
 
-                 {
 
-                     Util.Logger.Log(LogLevel.Error, $"Failed to decompress scene data because '{e}'\n");
 
-                 }
 
-             }
 
-         }
 
-         private static bool BytesEqual(byte[] a, byte[] b)
 
-         {
 
-             if (a.Length != b.Length) return false;
 
-             for (long i = 0; i < a.Length; i++)
 
-             {
 
-                 if (a[i] != b[i]) return false;
 
-             }
 
-             return true;
 
-         }
 
-         private void ConvertIni()
 
-         {
 
-             HashSet<int> saveSceneEntries = new HashSet<int>();
 
-             IniSection MMScene = Preferences["scene"];
 
-             foreach (IniKey iniKey in MMScene.Keys)
 
-             {
 
-                 string keyName = iniKey.Key;
 
-                 if (keyName[0] == 's')
 
-                 {
 
-                     int index = Int32.Parse(keyName.Substring(1 + (keyName[1] == 's' ? 1 : 0)));
 
-                     if (!saveSceneEntries.Contains(index))
 
-                     {
 
-                         saveSceneEntries.Add(index);
 
-                         ConvertSceneToPng(index, MMScene);
 
-                     }
 
-                 }
 
-             }
 
-         }
 
-         private void ConvertSceneToPng(int index, IniSection MMScene)
 
-         {
 
-             byte[] sceneBuffer;
 
-             byte[] screenshotBuffer = frame.EncodeToPNG();
 
-             string sceneString = MMScene.GetKey($"s{index}")?.RawValue;
 
-             string screenshotString = MMScene.GetKey($"ss{index}")?.RawValue;
 
-             bool kankyo = index >= 10000;
 
-             if (index == 9999 || String.IsNullOrEmpty(sceneString)) return;
 
-             using (MemoryStream stream = new MemoryStream(Encoding.Unicode.GetBytes(sceneString)))
 
-             {
 
-                 sceneBuffer = LZMA.Compress(stream);
 
-             }
 
-             DateTime dateSaved = DateTime.Parse(sceneString.Split(',')[0]);
 
-             if (!String.IsNullOrEmpty(screenshotString))
 
-                 screenshotBuffer = Convert.FromBase64String(screenshotString);
 
-             string sceneType = kankyo ? "mmkankyo" : "mmscene";
 
-             string savePngFilename = $"{sceneType}{index}_{dateSaved.ToString("yyyyMMddHHmm")}.png";
 
-             string outPath = Path.Combine(kankyo ? kankyoScenePath : saveScenePath, savePngFilename);
 
-             using (BinaryWriter stream = new BinaryWriter(File.Create(outPath)))
 
-             {
 
-                 stream.Write(screenshotBuffer);
 
-                 if (kankyo) stream.Write(kankyoHeader);
 
-                 stream.Write(sceneBuffer);
 
-             }
 
-             File.SetCreationTime(outPath, dateSaved);
 
-             File.SetLastWriteTime(outPath, dateSaved);
 
-         }
 
-         private class ScenePng
 
-         {
 
-             public FileInfo info { get; }
 
-             public Texture2D screenshot { get; }
 
-             public ScenePng(FileInfo info, Texture2D screenshot)
 
-             {
 
-                 this.info = info;
 
-                 this.screenshot = screenshot;
 
-             }
 
-         }
 
-     }
 
- }
 
 
  |