Example #1
0
        /// <summary>
        /// 指定ゴーストのシェルを同期的に読み込む
        /// </summary>
        protected void LoadShellAndFaceImage(ExplorerGhost ghost, bool reload = false)
        {
            // リロードフラグONの場合は既存情報を破棄
            if (reload)
            {
                Shells[ghost.DirPath] = null;

                if (FaceImages.ContainsKey(ghost.DirPath))
                {
                    if (FaceImages[ghost.DirPath] != null)
                    {
                        FaceImages[ghost.DirPath].Dispose();
                    }

                    FaceImages.Remove(ghost.DirPath);
                }
                imgListFace.Images.RemoveByKey(ghost.DirPath);
            }

            // メイン読み込み処理。シェルをまだ読み込んでいない場合、もしくはリロードフラグON時のみ実行
            if (reload ||
                !Shells.ContainsKey(ghost.DirPath) ||
                Shells[ghost.DirPath] == null)
            {
                // シェル読み込み
                LoadShell(ghost);

                // 顔画像読み込み
                LoadFaceImageIfShellLoaded(ghost);

                // UI側へ反映
                ReflectFaceImageToUIIfShellLoaded(ghost);
            }
        }
        /// <summary>
        /// 全ゴーストの顔画像の取得・変換を行う (キャッシュ処理も行う)
        /// </summary>
        /// <returns>ゴーストフォルダパスをキー、顔画像 (Bitmap) を値とするDictionary</returns>
        public virtual Bitmap GetFaceImage(ExplorerGhost ghost, ExplorerShell shell, Size faceSize)
        {
            var cacheDir = Util.GetCacheDirPath();

            // キャッシュフォルダが存在しなければ作成
            if (!Directory.Exists(cacheDir))
            {
                Directory.CreateDirectory(cacheDir);
            }

            try
            {
                Bitmap face      = null;
                var    cachePath = Path.Combine(cacheDir, string.Format("{0}_face.png", Path.GetFileName(ghost.DirPath)));

                // 顔画像のキャッシュがあり、更新日時がシェルの更新日以降なら、キャッシュを使用
                if (File.Exists(cachePath) && File.GetLastWriteTime(cachePath) >= shell.LastModified)
                {
                    face = new Bitmap(cachePath);
                }
                else
                {
                    // キャッシュがない場合、サーフェス0から顔画像を生成 (サーフェスを読み込めている場合のみ)
                    if (shell.SakuraSurfaceModel != null)
                    {
                        using (var faceImg = shell.DrawFaceImage(shell.SakuraSurfaceModel, faceSize.Width, faceSize.Height))
                        {
                            face = faceImg.ToBitmap();
                        }

                        if (face != null)
                        {
                            // 顔画像のキャッシュを保存
                            face.Save(cachePath);
                        }
                    }
                }

                // 画像を返す
                return(face);
            }
            catch (InvalidDescriptException ex)
            {
                MessageBox.Show(string.Format("{0} の explorer2\\descript.txt に不正な記述があります。\n{1}", ghost.Name, ex.Message),
                                "エラー",
                                MessageBoxButtons.OK,
                                MessageBoxIcon.Warning);

                Debug.WriteLine(ex.ToString());
                return(null);
            }
            catch (Exception ex)
            {
                Debug.WriteLine(ex.ToString());
                return(null);
            }
        }
Example #3
0
 /// <summary>
 /// 指定ゴーストの顔画像を読み込む (シェルの読み込みに成功していれば)
 /// </summary>
 protected virtual void LoadFaceImageIfShellLoaded(ExplorerGhost ghost)
 {
     // ロック取得 (同期処理と非同期処理が競合しないように)
     lock (GhostManager)
     {
         // シェルの読み込みに成功している場合のみ
         if (Shells.ContainsKey(ghost.DirPath) && Shells[ghost.DirPath] != null)
         {
             // まだ読み込んでいなければ、ゴーストの顔画像を変換・取得
             if (!FaceImages.ContainsKey(ghost.DirPath))
             {
                 FaceImages[ghost.DirPath] = GhostManager.GetFaceImage(ghost, Shells[ghost.DirPath], imgListFace.ImageSize);
                 Debug.WriteLine(string.Format("<{0}> faceImage loaded: {1}", Thread.CurrentThread.ManagedThreadId, ghost.Name));
             }
         }
     }
 }
        /// <summary>
        /// 対象ゴーストのシェル情報読み込み
        /// </summary>
        public virtual ExplorerShell LoadShell(ExplorerGhost ghost)
        {
            // シェルが1つも存在しない場合はエラーとする
            if (ghost.CurrentShellRelDirPath == null)
            {
                throw new ShellNotFoundException(string.Format(@"有効なシェルが1つも存在しません。", ghost.DefaultShellDirName));
            }

            var shellDir = Path.Combine(ghost.DirPath, ghost.CurrentShellRelDirPath);

            // descript.txtが存在しない場合はエラーとする
            if (!ExplorerShell.IsShellDir(shellDir))
            {
                throw new ShellDescriptNotFoundException("シェルフォルダの中に descript.txt が存在しません。");
            }

            return(ExplorerShell.Load(shellDir, ghost.SakuraDefaultSurfaceId, ghost.KeroDefaultSurfaceId));
        }
Example #5
0
        /// <summary>
        /// 指定ゴーストの顔画像をFormへ反映
        /// </summary>
        protected virtual void ReflectFaceImageToUIIfShellLoaded(ExplorerGhost ghost)
        {
            // ロック取得 (同期処理と非同期処理が競合しないように)
            lock (GhostManager)
            {
                // シェルの読み込みに成功している場合のみ
                if (Shells.ContainsKey(ghost.DirPath) && Shells[ghost.DirPath] != null)
                {
                    // 顔画像を正常に読み込めていれば、イメージリストに追加
                    if (FaceImages[ghost.DirPath] != null)
                    {
                        imgListFace.Images.Add(ghost.DirPath, FaceImages[ghost.DirPath]);
                    }

                    // 顔画像表示を更新
                    UpdateFaceImageKey(ghost);
                }
            }
        }
Example #6
0
        /// <summary>
        /// 指定ゴーストの顔画像を更新 (不在かどうかに応じて処理を分ける)
        /// </summary>
        protected void UpdateFaceImageKey(ExplorerGhost ghost)
        {
            // リスト内に項目がなければ何もしない
            if (!lstGhost.Items.ContainsKey(ghost.DirPath))
            {
                return;
            }

            // 不在判定
            if (AbsenceInfo.ContainsKey(ghost.DirPath))
            {
                // いない
                lstGhost.Items[ghost.DirPath].ImageKey = AbsenceInfo[ghost.DirPath];
            }
            else
            {
                // いる
                lstGhost.Items[ghost.DirPath].ImageKey = ghost.DirPath;
            }
        }
Example #7
0
 /// <summary>
 /// 指定ゴーストのシェルを読み込む
 /// </summary>
 protected virtual void LoadShell(ExplorerGhost ghost)
 {
     // ロック取得 (同期処理と非同期処理が競合しないように)
     lock (GhostManager)
     {
         try
         {
             Shells[ghost.DirPath] = GhostManager.LoadShell(ghost);
             Debug.WriteLine(string.Format("<{0}> shell loaded: {1}", Thread.CurrentThread.ManagedThreadId, ghost.Name));
         }
         catch (UnhandlableShellException ex)
         {
             // 処理不可能なシェル
             if (!ErrorMessagesOnShellLoading.ContainsKey(ghost.DirPath))
             {
                 ErrorMessagesOnShellLoading[ghost.DirPath] = new List <string>();
             }
             ErrorMessagesOnShellLoading[ghost.DirPath].Add(ex.FriendlyMessage);
         }
     }
 }
        /// <summary>
        /// サーフェス画像を取得 (element, MAYUNAの合成も行う。またキャッシュがあればキャッシュから取得)
        /// </summary>
        /// <returns>サーフェス画像を取得できた場合はその画像。取得に失敗した場合はnull</returns>
        protected virtual Bitmap DrawSurfaceInternal(ExplorerGhost ghost, ExplorerShell shell, Shell.SurfaceModel surfaceModel, int surfaceId)
        {
            var cacheDir = Util.GetCacheDirPath();

            if (surfaceModel == null)
            {
                return(null);
            }

            // キャッシュフォルダが存在しなければ作成
            if (!Directory.Exists(cacheDir))
            {
                Directory.CreateDirectory(cacheDir);
            }

            // 立ち絵画像のキャッシュがあり、更新日時がシェルの更新日以降なら、キャッシュを使用
            var cachePath = Path.Combine(cacheDir, string.Format("{0}_s{1}.png", Path.GetFileName(ghost.DirPath), surfaceId));

            if (File.Exists(cachePath) && File.GetLastWriteTime(cachePath) >= shell.LastModified)
            {
                return(new Bitmap(cachePath));
            }
            else
            {
                // 立ち絵サーフェス画像を生成
                var surface = shell.DrawSurface(surfaceModel);

                // キャッシュとして保存
                surface.Write(cachePath);

                // サーフェス画像をBitmap形式に変換
                var surfaceBmp = surface.ToBitmap();

                // 元画像を即時破棄
                surface.Dispose();

                // サーフェス画像をBitmap形式に変換して返す
                return(surfaceBmp);
            }
        }
Example #9
0
        /// <summary>
        /// シェル情報一括読み込み
        /// </summary>
        protected virtual void LoadShells()
        {
            var appDirPath = Util.GetAppDirPath();

            // 既存情報クリア
            lstShell.Clear();
            imgListFace.Images.Clear();

            // FMO情報更新
            UpdateFMOInfo();

            // コマンドライン引数を解釈
            var args = Environment.GetCommandLineArgs().ToList();

            args.RemoveAt(0);                              // 先頭はexe名のため削除

            var caller = args.First();                     // 呼び出し元ゴースト (id or "unspecified")

            args.RemoveAt(0);                              // 先頭削除
            var ghostDirPath = args.First().TrimEnd('\\'); // ゴーストフォルダパス

            SakuraFMOData target  = null;
            var           matched = Regex.Match(caller, @"^id:(.+?)\z");

            if (matched.Success)
            {
                // idが指定された場合、そのidと一致するゴースト情報を探す
                var id = matched.Groups[1].Value.Trim();
                target = FMOGhostList.FirstOrDefault(g => g.Id == id);
            }

            if (caller == "unspecified")
            {
                // "unspecified" が指定された場合、現在起動しているゴーストのうち、ランダムに1体を呼び出し元とする (デバッグ用)
                var rand = new Random();
                target = FMOGhostList[rand.Next(0, FMOGhostList.Count - 1)];
            }

            if (target == null)
            {
                throw new Exception(string.Format("指定されたゴーストが見つかりませんでした。 ({0})", caller));
            }

            // 呼び出し元の情報をプロパティにセット
            CallerId         = target.Id;
            CallerSakuraName = target.Name;
            CallerKeroName   = target.KeroName;
            CallerHWnd       = (IntPtr)target.HWnd;

            // チェックボックスの位置移動
            ChkCloseAfterChange.Left = BtnChange.Left + 1;

            // ゴースト情報読み込み
            var ghost = ExplorerGhost.Load(ghostDirPath);

            // シェル情報読み込み
            ShellManager = ShellManager.Load(ghostDirPath, ghost.SakuraDefaultSurfaceId, ghost.KeroDefaultSurfaceId);

            // シェルが1件も取得できなかった場合はエラー表示
            if (!ShellManager.ListItems.Any())
            {
                MessageBox.Show("有効なシェルフォルダが1件も見つかりませんでした。"
                                , "エラー"
                                , MessageBoxButtons.OK
                                , MessageBoxIcon.Error);
                Application.Exit();
                return;
            }

            // 最終起動時の記録があり、かつ最終起動時とバージョンが異なる場合は、キャッシュをすべて破棄
            if (CurrentProfile.LastBootVersion != null && Util.GetVersion() != CurrentProfile.LastBootVersion)
            {
                Directory.Delete(Util.GetCacheBaseDirPath(), recursive: true);
            }

            // 最終起動情報をセットして、Profileを保存
            CurrentProfile.LastBootVersion = Util.GetVersion();
            Util.SaveProfile(CurrentProfile);

            // ゴーストの顔画像を変換・取得
            var faceImages = ShellManager.GetFaceImages(imgListFace.ImageSize);

            // リストビュー構築処理
            foreach (var shellItem in ShellManager.ListItems)
            {
                // 顔画像を正常に読み込めていれば、イメージリストに追加
                if (faceImages.ContainsKey(shellItem.DirPath))
                {
                    imgListFace.Images.Add(shellItem.DirPath, faceImages[shellItem.DirPath]);
                }

                // リスト項目追加
                var item = lstShell.Items.Add(key: shellItem.DirPath, text: shellItem.Name ?? "", imageKey: shellItem.DirPath);
                item.Tag = shellItem.DirPath;
            }

            // 読み込み中表示を消す
            lblLoading.Hide();

            // ゴースト情報リストの更新に伴う画面表示更新
            UpdateUIOnFMOChanged();

            // ボタン等表示状態を更新
            UpdateUIState();

            // 現在の使用シェルを選択
            var currentShellFolderName = Path.GetFileName(ghost.CurrentShellRelDirPath);

            foreach (ListViewItem item in lstShell.Items)
            {
                var shellFolderName = Path.GetFileName((string)item.Tag);
                if (shellFolderName == currentShellFolderName)
                {
                    item.Focused  = true;
                    item.Selected = true;
                    break;
                }
            }

            // 選択対象のシェルを判別できなかった場合は、1件目を選択
            if (SelectedShellListItem == null)
            {
                lstShell.Items[0].Focused  = true;
                lstShell.Items[0].Selected = true;
            }

            // スクロール
            var selectedIndex = lstShell.SelectedItems[0].Index;

            lstShell.EnsureVisible(selectedIndex);
        }
        /// <summary>
        /// ゴースト情報の一括読み込み (シェルはまだ読み込まない)
        /// </summary>
        public virtual void Load()
        {
            // 既存の値はクリア
            Ghosts.Clear();

            // ゴーストフォルダのサブフォルダを列挙
            foreach (var subDir in Directory.GetDirectories(GhostDirPath))
            {
                // 隠しフォルダの場合はスキップ
                var dirInfo = new DirectoryInfo(subDir);
                if ((dirInfo.Attributes & FileAttributes.Hidden) == FileAttributes.Hidden)
                {
                    continue;
                }

                // ゴーストフォルダでなければスキップ
                if (!ExplorerGhost.IsGhostDir(subDir))
                {
                    continue;
                }

                // ゴーストの基本情報を読み込み
                var ghost = ExplorerGhost.Load(subDir);

                // キーワードが指定されており、かつキーワードに合致しなければスキップ
                if (!string.IsNullOrWhiteSpace(FilterWord))
                {
                    if (!(ghost.Name.Contains(FilterWord) ||
                          ghost.SakuraName.Contains(FilterWord) ||
                          ghost.KeroName.Contains(FilterWord)))
                    {
                        continue;
                    }
                }

                // リストに追加
                Ghosts.Add(ghost);
            }

            // ゴースト別の使用頻度情報を抽出
            var totalBootTimes  = new Dictionary <string, long>();
            var lastBootSeconds = new Dictionary <string, long>();

            foreach (var ghost in Ghosts)
            {
                Realize2Text.Record rec = null;
                if (Realize2Text != null)
                {
                    rec = Realize2Text.GhostRecords.FirstOrDefault(r => r.Name == ghost.Name);
                }

                if (rec != null)
                {
                    totalBootTimes[ghost.Name]  = rec.TotalBootByMinute;
                    lastBootSeconds[ghost.Name] = rec.LastBootSecond;
                }
                else
                {
                    // 情報が見つからなければ0扱い
                    totalBootTimes[ghost.Name]  = 0;
                    lastBootSeconds[ghost.Name] = 0;
                }
            }

            // ゴースト別のインストール日付情報を取得 (インストール日時順でソートされた場合のみ)
            var installSeconds = new Dictionary <string, long>();

            if (SortType == Const.SortType.ByRecentInstall)
            {
                foreach (var ghost in Ghosts)
                {
                    // 初期値は0
                    installSeconds[ghost.DirPath] = 0;

                    // profile\var.txt が存在すれば、その中からインストール時刻を取得
                    var varPath = Path.Combine(ghost.DirPath, @"ghost\master\profile\var.txt");
                    if (File.Exists(varPath))
                    {
                        try
                        {
                            var lines = File.ReadAllLines(varPath);
                            foreach (var line in lines)
                            {
                                if (line.StartsWith("install,"))
                                {
                                    var tokens = line.TrimEnd().Split(',');
                                    installSeconds[ghost.DirPath] = long.Parse(tokens[1]);
                                    break;
                                }
                            }
                        }
                        catch (Exception ex)
                        {
                            Debug.WriteLine(ex);
                        }
                    }
                }
            }

            // 最後にソート
            switch (SortType)
            {
            case Const.SortType.ByBootTime:
                Ghosts = Ghosts.OrderByDescending(g => totalBootTimes[g.Name]).ToList();
                break;

            case Const.SortType.ByRecentBoot:
                Ghosts = Ghosts.OrderByDescending(g => lastBootSeconds[g.Name]).ToList();
                break;

            case Const.SortType.ByRecentInstall:
                Ghosts = Ghosts.OrderByDescending(g => installSeconds[g.DirPath]).ToList();
                break;

            default:
                // ゴースト名+フォルダパス順
                Ghosts = Ghosts.OrderBy(g => Tuple.Create(g.Name, g.DirPath)).ToList();
                break;
            }
        }
 /// <summary>
 /// kero側サーフェス画像を取得  (element, MAYUNAの合成も行う。またキャッシュがあればキャッシュから取得)
 /// </summary>
 /// <returns>サーフェス画像を取得できた場合はその画像。取得に失敗した場合はnull</returns>
 public virtual Bitmap DrawKeroSurface(ExplorerGhost ghost, ExplorerShell shell)
 {
     return(DrawSurfaceInternal(ghost, shell, shell.KeroSurfaceModel, shell.KeroSurfaceId));
 }