Newer
Older
Qwilight / Qwilight / System / TwilightSystem.cs
@Taehui Taehui on 19 Aug 115 KB v1.16.39
using CommunityToolkit.Mvvm.Messaging;
using Google.Protobuf;
using Ionic.Zip;
using Microsoft.Data.Sqlite;
using Qwilight.Compute;
using Qwilight.MSG;
using Qwilight.UIComponent;
using Qwilight.Utilities;
using Qwilight.View;
using Qwilight.ViewModel;
using System.Buffers;
using System.Collections.Concurrent;
using System.IO;
using System.Net;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Net.Security;
using System.Net.Sockets;
using System.Security.Authentication;
using System.Text;
using System.Windows.Documents;
using Windows.Win32.UI.WindowsAndMessaging;

namespace Qwilight
{
    public sealed class TwilightSystem : Model, IDisposable
    {
        const int NotEstablished = 0;
        const int NotLoggedIn = 1;
        const int LoggedIn = 2;

        public static readonly TwilightSystem Instance = QwilightComponent.GetBuiltInData<TwilightSystem>(nameof(TwilightSystem));

        static readonly string FaultEntryPath = Path.Combine(QwilightComponent.FaultEntryPath, nameof(TwilightSystem));

        readonly Action<object> _handleSendParallel;
        readonly ConcurrentDictionary<string, NotifyItem> _bundleNotifyItems = new();
        readonly HttpClient _wwwClient = new()
        {
            DefaultRequestVersion = HttpVersion.Version30
        };
        Stream _ts;
        int _twilightSituation;
        bool _isAvailable = true;

        string QwilightName => QwilightComponent.IsValve ? ValveSystem.Instance.ValveName : Environment.UserName;

        public TwilightSystem()
        {
            _wwwClient.DefaultRequestHeaders.Add("User-Agent", "Mozilla/5.0");
            _handleSendParallel = o =>
            {
                var eventItem = o as Event;
                if (eventItem != null)
                {
                    eventItem.Millis = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
                    eventItem.AvatarID = AvatarID;
                    try
                    {
                        lock (_ts)
                        {
                            eventItem.WriteDelimitedTo(_ts);
                        }
                    }
                    catch
                    {
                    }
                }
            };
        }

        public AvatarWww AvatarWwwValue { get; set; }

        public string Totem { get; set; } = string.Empty;

        public string AvatarID { get; set; } = string.Empty;

        public string AvatarName { get; set; } = string.Empty;

        public string GetAvatarName() => TwilightSituation == NotEstablished ? QwilightName : AvatarName;

        public int TwilightSituation
        {
            get => _twilightSituation;

            set
            {
                if (value != LoggedIn)
                {
                    AvatarDrawingSystem.Instance.WipeAvatarDrawings();
                    AvatarEdgeSystem.Instance.WipeAvatarEdges();
                    AvatarTitleSystem.Instance.WipeAvatarTitles();
                }
                if (SetProperty(ref _twilightSituation, value, nameof(TwilightSituation)))
                {
                    OnPropertyChanged(nameof(IsEstablished));
                    OnPropertyChanged(nameof(IsLoggedIn));
                    ViewModels.Instance.MainValue.NotifyCanSaveAsBundle();
                    ViewModels.Instance.MainValue.NotifyCanTwilightCommentary();
                    ViewModels.Instance.MainValue.NotifyCanTwilightFavor();
                    ViewModels.Instance.ConfigureValue.NotifyCanGetDefaultText();
                    ViewModels.Instance.ConfigureValue.NotifyCanSaveAsBundle();
                    ViewModels.Instance.BundleValue.NotifyIsMe();
                    ViewModels.Instance.AvatarValue.NotifyIsMe();
                    ViewModels.Instance.AvatarValue.NotifyIsLevelVSVisible();
                }
            }
        }

        public void StopBundle(string siteID)
        {
            if (_bundleNotifyItems.TryGetValue(siteID, out var savingBundleItem))
            {
                savingBundleItem.OnStop(false);
            }
        }

        public bool IsEstablished => TwilightSituation != NotEstablished;

        public bool IsLoggedIn => TwilightSituation == LoggedIn;

        public void NotifyAvatarWwwValue()
        {
            AvatarWwwValue = new AvatarWww(AvatarID);
            OnPropertyChanged(nameof(AvatarWwwValue));
        }

        public override void NotifyModel()
        {
            base.NotifyModel();
            NotifyAvatarWwwValue();
        }

        static Event NewEvent<T>(Event.Types.EventID eventID, T text, ByteString[] data)
        {
            var eventItem = new Event
            {
                EventID = eventID,
                Text = text != null ? text as string ?? Utility.SetJSON(text) : string.Empty
            };
            if (data != null)
            {
                eventItem.Data.AddRange(data);
            }
            return eventItem;
        }

        void Send<T>(Event.Types.EventID eventID, T text, params ByteString[] data)
        {
            if (IsEstablished)
            {
                _handleSendParallel(NewEvent<T>(eventID, text, data));
            }
        }

        public void SendParallel(Event.Types.EventID eventID, string text, params ByteString[] data)
        {
            if (IsEstablished || eventID == Event.Types.EventID.Establish)
            {
                Task.Factory.StartNew(_handleSendParallel, NewEvent(eventID, text, data));
            }
        }

        public void SendParallel<T>(Event.Types.EventID eventID, T text, params ByteString[] data)
        {
            if (IsEstablished || eventID == Event.Types.EventID.Establish)
            {
                Task.Factory.StartNew(_handleSendParallel, NewEvent(eventID, text, data));
            }
        }

        public void SendParallel(Event eventItem)
        {
            if (IsEstablished)
            {
                Task.Factory.StartNew(_handleSendParallel, eventItem);
            }
        }

        void AutoEnter(Func<int, bool> onAutoEnter)
        {
            SendParallel(Event.Types.EventID.EnterSite, new
            {
                siteID = "00000000-0000-0000-0000-000000000003",
                siteCipher = string.Empty
            });
            if (onAutoEnter(Configure.Instance.AutoEnterNotifySite.Data))
            {
                SendParallel(Event.Types.EventID.EnterSite, new
                {
                    siteID = "00000000-0000-0000-0000-000000000000",
                    siteCipher = string.Empty
                });
            }
            if (onAutoEnter(Configure.Instance.AutoEnterDefaultSite.Data))
            {
                SendParallel(Event.Types.EventID.EnterSite, new
                {
                    siteID = "00000000-0000-0000-0000-000000000001",
                    siteCipher = string.Empty
                });
            }
            if (onAutoEnter(Configure.Instance.AutoEnterPlatformSite.Data))
            {
                SendParallel(Event.Types.EventID.EnterSite, new
                {
                    siteID = "00000000-0000-0000-0000-000000000002",
                    siteCipher = string.Empty
                });
            }
        }

        public void HandleSystem()
        {
            var mainViewModel = ViewModels.Instance.MainValue;
            var bundleViewModel = ViewModels.Instance.BundleValue;
            var ubuntuViewModel = ViewModels.Instance.UbuntuValue;
            var toNotifyViewModel = ViewModels.Instance.NotifyValue;
            var siteContainerViewModel = ViewModels.Instance.SiteContainerValue;
            var twilightConfigureViewModel = ViewModels.Instance.TwilightConfigure;
            var netSiteCommentViewModel = ViewModels.Instance.NetSiteCommentValue;
            while (true)
            {
                string textClose = null;
                try
                {
                    using (var tc = new TcpClient(QwilightComponent.TaehuiNetDDNS, 6101))
                    using (_ts = QwilightComponent.TaehuiNetDDNS != "localhost" ? new SslStream(tc.GetStream(), false, QwilightComponent.IsVS ? (sender, certificate, chain, sslPolicyErrors) => true : null) : tc.GetStream())
                    {
                        if (_ts is SslStream ss)
                        {
                            ss.AuthenticateAsClient("taehui.ddns.net");
                        }
                        var textEstablish = new
                        {
                            hash = QwilightComponent.HashText,
                            date = QwilightComponent.DateText,
                            language = Configure.Instance.Language,
                            qwilightName = QwilightName,
                            amd64 = QwilightComponent.AMD64Name,
                            os = QwilightComponent.OSName,
                            ram = QwilightComponent.RAMName,
                            vga = QwilightComponent.GPUName,
                            m2 = QwilightComponent.M2Name,
                            audio = QwilightComponent.AudioName,
                            tv = QwilightComponent.TVName,
                            lan = QwilightComponent.LANName,
                        };
                        if (ValveSystem.Instance.ValveDrawing != null)
                        {
                            SendParallel(Event.Types.EventID.Establish, textEstablish, ValveSystem.Instance.ValveDrawing);
                        }
                        else
                        {
                            SendParallel(Event.Types.EventID.Establish, textEstablish);
                        }
                        while (_isAvailable)
                        {
                            var eventItem = Event.Parser.ParseDelimitedFrom(_ts);
                            try
                            {
                                var eventItemText = eventItem.Text;
                                var eventItemData = eventItem.Data;
                                var defaultComputer = mainViewModel.Computer;
                                switch (eventItem.EventID)
                                {
                                    case Event.Types.EventID.Close:
                                        textClose = eventItemText;
                                        break;
                                    case Event.Types.EventID.Establish:
                                        var twilightEstablish = Utility.GetJSON<JSON.TwilightEstablish>(eventItemText);
                                        Totem = string.Empty;
                                        AvatarID = twilightEstablish.avatarID;
                                        AvatarName = twilightEstablish.avatarName;
                                        TwilightSituation = NotLoggedIn;
                                        mainViewModel.LoadCommentItemCollection();
                                        AutoEnter(autoEnter => autoEnter == AutoEnterSite.AutoEnter);
                                        if (Configure.Instance.AutoLogIn)
                                        {
                                            var avatarCipher = Configure.Instance.GetCipher();
                                            if (!string.IsNullOrEmpty(avatarCipher))
                                            {
                                                SendParallel(Event.Types.EventID.LogIn, new
                                                {
                                                    avatarID = Configure.Instance.AvatarID,
                                                    avatarCipher
                                                });
                                            }
                                        }
                                        if (!ViewModels.Instance.MainValue.IsPragmatic)
                                        {
                                            _ = GetDefaultNoteDate(Configure.Instance.DefaultNotesDate, Configure.Instance.AutoGetDefaultNote);
                                            _ = GetDefaultUIDate(Configure.Instance.DefaultUIDate, Configure.Instance.AutoGetDefaultUI);
                                        }
                                        break;
                                    case Event.Types.EventID.UnavailableDate:
                                        if (!Configure.Instance.AutoGetQwilight)
                                        {
                                            NotifySystem.Instance.Notify(NotifySystem.NotifyVariety.Info, NotifySystem.NotifyConfigure.Default, eventItemText, false);
                                        }
                                        break;
                                    case Event.Types.EventID.LogIn:
                                        ViewModels.Instance.LogInValue.Close();
                                        var twilightLogIn = Utility.GetJSON<JSON.TwilightLogIn>(eventItemText);
                                        Totem = twilightLogIn.totem;
                                        AvatarID = twilightLogIn.avatarID;
                                        AvatarName = twilightLogIn.avatarName;
                                        TwilightSituation = LoggedIn;
                                        mainViewModel.LoadCommentItemCollection();
                                        NotifyAvatarWwwValue();
                                        NotifySystem.Instance.Notify(NotifySystem.NotifyVariety.OK, NotifySystem.NotifyConfigure.Default, string.Format(LanguageSystem.Instance.LoggedInContents, GetAvatarName()), false, "Sign in");
                                        BaseUI.Instance.HandleEvent(BaseUI.EventItem.LogIn);
                                        AutoEnter(autoEnter => autoEnter != AutoEnterSite.WaitSite);
                                        break;
                                    case Event.Types.EventID.NotLogIn:
                                        NotifySystem.Instance.Notify(NotifySystem.NotifyVariety.OK, NotifySystem.NotifyConfigure.Default, string.Format(LanguageSystem.Instance.NotLoggedInContents, GetAvatarName()), false, "Not Sign in");
                                        BaseUI.Instance.HandleEvent(BaseUI.EventItem.NotLogIn);
                                        var twilightNotLogIn = Utility.GetJSON<JSON.TwilightNotLogIn>(eventItemText);
                                        Totem = string.Empty;
                                        AvatarID = twilightNotLogIn.avatarID;
                                        AvatarName = twilightNotLogIn.avatarName;
                                        TwilightSituation = NotLoggedIn;
                                        AutoEnter(autoEnter => autoEnter == AutoEnterSite.AutoEnter);
                                        break;
                                    case Event.Types.EventID.QuitSite:
                                        var toQuitSiteViewModel = ViewModels.Instance.WipeSiteViewModel(eventItemText);
                                        if (toQuitSiteViewModel != null)
                                        {
                                            UIHandler.Instance.HandleParallel(() => siteContainerViewModel.SiteViewCollection.Remove(toQuitSiteViewModel.View));
                                        }
                                        break;
                                    case Event.Types.EventID.Notify:
                                        var twilightNotify = Utility.GetJSON<JSON.TwilightNotify>(eventItemText);
                                        NotifySystem.Instance.Notify(twilightNotify.v, NotifySystem.NotifyConfigure.Default, twilightNotify.text, twilightNotify.isUrgent);
                                        break;
                                    case Event.Types.EventID.NotifyPass:
                                        var twilightNotifyPasses = Utility.GetJSON<JSON.TwilightNotifyPass[]>(eventItemText);
                                        var passNotifyItems = twilightNotifyPasses.Select(twilightNotifyPass => new NotifyItem
                                        {
                                            Text = string.Format(LanguageSystem.Instance.PassNotifyText, Utility.GetPlatformText(twilightNotifyPass.title, twilightNotifyPass.artist, Utility.GetGenreText(twilightNotifyPass.genre), twilightNotifyPass.levelText), twilightNotifyPass.avatarName),
                                            Variety = NotifySystem.NotifyVariety.Info,
                                            OnHandle = async () => await mainViewModel.MoveEntryItemsView(twilightNotifyPass.noteID),
                                            AvatarWwwValue = new(twilightNotifyPass.avatarID),
                                            IsNew = true
                                        }).ToArray();
                                        UIHandler.Instance.HandleParallel(() =>
                                        {
                                            foreach (var passNotifyItem in passNotifyItems)
                                            {
                                                ViewModels.Instance.NotifyValue.PassNotifyItemCollection.Insert(0, passNotifyItem);
                                            }
                                        });
                                        if (passNotifyItems.Length == 1)
                                        {
                                            var passNotifyItem = passNotifyItems.Single();
                                            passNotifyItem.IsNew = false;
                                            NotifySystem.Instance.Notify(passNotifyItem.Variety, NotifySystem.NotifyConfigure.NotSave, passNotifyItem.Text, false, "Notify Pass", passNotifyItem.OnHandle);
                                        }
                                        else
                                        {
                                            NotifySystem.Instance.NotifyPendingPassNotify();
                                        }
                                        break;
                                    case Event.Types.EventID.LevelUp:
                                        var twilightLevelUp = Utility.GetJSON<JSON.TwilightLevelUp>(eventItemText);
                                        NotifySystem.Instance.Notify(NotifySystem.NotifyVariety.OK, NotifySystem.NotifyConfigure.Default, $"LV. {twilightLevelUp.from} → LV. {twilightLevelUp.to}", false, "Level Up");
                                        BaseUI.Instance.HandleEvent(BaseUI.EventItem.LevelUp);
                                        break;
                                    case Event.Types.EventID.AbilityUp:
                                        var twilightAbilityUp = Utility.GetJSON<JSON.TwilightAbilityUp>(eventItemText);
                                        NotifySystem.Instance.Notify(NotifySystem.NotifyVariety.OK, NotifySystem.NotifyConfigure.Default, twilightAbilityUp.ToString(), false, "Ability Up");
                                        BaseUI.Instance.HandleEvent(BaseUI.EventItem.AbilityUp);
                                        break;
                                    case Event.Types.EventID.WwwLevel:
                                        NotifySystem.Instance.Notify(NotifySystem.NotifyVariety.OK, NotifySystem.NotifyConfigure.Default, string.Format(LanguageSystem.Instance.WwwLevelClearContents, eventItemText), false, "Www Level Clear");
                                        BaseUI.Instance.HandleEvent(BaseUI.EventItem.LevelClear);
                                        break;
                                    case Event.Types.EventID.NewTitle:
                                        NotifySystem.Instance.Notify(NotifySystem.NotifyVariety.OK, NotifySystem.NotifyConfigure.Default, string.Format(LanguageSystem.Instance.NewTitleContents, eventItemText), false, "New Title");
                                        BaseUI.Instance.HandleEvent(BaseUI.EventItem.NewTitle);
                                        break;
                                    case Event.Types.EventID.AbilityClassUp:
                                        NotifySystem.Instance.Notify(NotifySystem.NotifyVariety.OK, NotifySystem.NotifyConfigure.Default, string.Format(LanguageSystem.Instance.AbilityClassUpContents, eventItemText), false, "Ability Class Up");
                                        BaseUI.Instance.HandleEvent(BaseUI.EventItem.AbilityClassUp);
                                        break;
                                    case Event.Types.EventID.SiteYell:
                                        var twilightSiteYell = Utility.GetJSON<JSON.TwilightSiteYell>(eventItemText);
                                        var siteYellSiteViewModel = ViewModels.Instance.GetSiteViewModel(twilightSiteYell.siteID);
                                        if (siteYellSiteViewModel != null)
                                        {
                                            var siteYell = new JSON.TwilightSiteYellItem
                                            {
                                                avatarID = twilightSiteYell.avatarID,
                                                avatarName = twilightSiteYell.avatarName,
                                                date = twilightSiteYell.date,
                                                siteYell = twilightSiteYell.siteYell,
                                                siteYellID = twilightSiteYell.siteYellID
                                            };
                                            siteYellSiteViewModel.NewSiteYells([siteYell], false);
                                            siteYellSiteViewModel.SetNew();
                                            if (twilightSiteYell.avatarName != "@Enter" || twilightSiteYell.siteYell != GetAvatarName())
                                            {
                                                siteYellSiteViewModel.Notify(siteYell);
                                            }
                                        }
                                        break;
                                    case Event.Types.EventID.ModifySiteYell:
                                        var twilightModifySiteYell = Utility.GetJSON<JSON.TwilightModifySiteYell>(eventItemText);
                                        ViewModels.Instance.GetSiteViewModel(twilightModifySiteYell.siteID)?.ModifySiteYell(twilightModifySiteYell);
                                        break;
                                    case Event.Types.EventID.WipeSiteYell:
                                        var twilightWipeSiteYell = Utility.GetJSON<JSON.TwilightWipeSiteYell>(eventItemText);
                                        ViewModels.Instance.GetSiteViewModel(twilightWipeSiteYell.siteID)?.WipeSiteYell(twilightWipeSiteYell);
                                        break;
                                    case Event.Types.EventID.GetSiteYells:
                                        var twilightGetSiteYells = Utility.GetJSON<JSON.TwilightGetSiteYells>(eventItemText);
                                        ViewModels.Instance.GetSiteViewModel(twilightGetSiteYells.siteID)?.NewSiteYells(twilightGetSiteYells.data, true);
                                        break;
                                    case Event.Types.EventID.EnterSite:
                                        var twilightEnterSite = Utility.GetJSON<JSON.TwilightEnterSite>(eventItemText);
                                        var toEnterSiteID = twilightEnterSite.siteID;
                                        var toEnterSiteViewModel = ViewModels.Instance.NewSiteViewModel(toEnterSiteID);
                                        toEnterSiteViewModel.SiteID = toEnterSiteID;
                                        toEnterSiteViewModel.SiteNotify = twilightEnterSite.siteNotify;
                                        toEnterSiteViewModel.IsGetNotify = twilightEnterSite.isGetNotify;
                                        toEnterSiteViewModel.IsEditable = twilightEnterSite.isEditable;
                                        toEnterSiteViewModel.CanAudioInput = twilightEnterSite.isAudioInput;
                                        toEnterSiteViewModel.IsAudioInput = twilightEnterSite.isAudioInput;
                                        toEnterSiteViewModel.NewSiteYells(twilightEnterSite.data, false);
                                        toEnterSiteViewModel.IsNetSite = twilightEnterSite.isNetSite;
                                        if (toEnterSiteViewModel.IsNetSite)
                                        {
                                            toEnterSiteViewModel.SetComputingValues(twilightEnterSite);
                                            toEnterSiteViewModel.IsFavorNoteFile = twilightEnterSite.isFavorNoteFile;
                                            toEnterSiteViewModel.IsFavorModeComponent = twilightEnterSite.isFavorModeComponent;
                                            toEnterSiteViewModel.IsFavorAudioMultiplier = twilightEnterSite.isFavorAudioMultiplier;
                                            toEnterSiteViewModel.IsAutoSiteHand = twilightEnterSite.isAutoSiteHand;
                                            toEnterSiteViewModel.ValidHunterMode = twilightEnterSite.validHunterMode;
                                            toEnterSiteViewModel.IsPostableItemMode = twilightEnterSite.validNetMode == 1;
                                            toEnterSiteViewModel.SetAllowedPostableItems(twilightEnterSite.allowedPostableItems);
                                            toEnterSiteViewModel.PostableItemBand = twilightEnterSite.postableItemBand;
                                            toEnterSiteViewModel.ModeComponentValue.CopyAsJSON(twilightEnterSite.modeComponentData);
                                        }
                                        UIHandler.Instance.HandleParallel(() =>
                                        {
                                            var toEnterSiteView = new SiteView
                                            {
                                                DataContext = toEnterSiteViewModel
                                            };
                                            toEnterSiteViewModel.View = toEnterSiteView;
                                            siteContainerViewModel.SiteViewCollection.Add(toEnterSiteView);
                                            siteContainerViewModel.SiteViewValue = toEnterSiteView;
                                        });
                                        break;
                                    case Event.Types.EventID.CallBundle:
                                        var twilightCallBundle = Utility.GetJSON<JSON.TwilightCallBundle>(eventItemText);
                                        var targetAvatar = twilightCallBundle.targetAvatar;
                                        if (!twilightCallBundle.isSilent || (bundleViewModel.IsOpened && bundleViewModel.TargetBundleAvatar == targetAvatar))
                                        {
                                            var noteFilesBundleItems = new List<BundleItem>();
                                            var noteFileBundleItems = new List<BundleItem>();
                                            var valueUIBundleItems = new List<BundleItem>();
                                            var qwilightBundleItems = new List<BundleItem>();
                                            var eventNoteBundleItems = new List<BundleItem>();
                                            foreach (var bundleDataItem in twilightCallBundle.data)
                                            {
                                                ((BundleItem.BundleVariety)bundleDataItem.bundleVariety switch
                                                {
                                                    BundleItem.BundleVariety.NoteFiles => noteFilesBundleItems,
                                                    BundleItem.BundleVariety.NoteFile => noteFileBundleItems,
                                                    BundleItem.BundleVariety.UI => valueUIBundleItems,
                                                    BundleItem.BundleVariety.Qwilight => qwilightBundleItems,
                                                    BundleItem.BundleVariety.EventNote => eventNoteBundleItems,
                                                    _ => throw new ArgumentException(bundleDataItem.bundleVariety.ToString())
                                                })?.Add(new(new()
                                                {
                                                    Data = bundleDataItem.bundleCompetence
                                                })
                                                {
                                                    Avatar = targetAvatar,
                                                    Date = DateTimeOffset.FromUnixTimeMilliseconds(bundleDataItem.date).LocalDateTime.ToLongDateString(),
                                                    Name = bundleDataItem.bundleName,
                                                    Length = bundleDataItem.bundleLength,
                                                    Variety = (BundleItem.BundleVariety)bundleDataItem.bundleVariety
                                                });
                                            }
                                            var noteFilesBundleItemCollection = bundleViewModel.NoteFilesBundleItemCollection;
                                            var noteFileBundleItemCollection = bundleViewModel.NoteFileBundleItemCollection;
                                            var valueUIBundleItemCollection = bundleViewModel.UIBundleItemCollection;
                                            var qwilightBundleItemCollection = bundleViewModel.QwilightBundleItemCollection;
                                            var eventNoteBundleItemCollection = bundleViewModel.EventNoteBundleItemCollection;
                                            UIHandler.Instance.HandleParallel(() =>
                                            {
                                                noteFilesBundleItemCollection.Clear();
                                                foreach (var noteFilesBundleItem in noteFilesBundleItems)
                                                {
                                                    noteFilesBundleItem.BundleItemCollection = noteFilesBundleItemCollection;
                                                    noteFilesBundleItemCollection.Add(noteFilesBundleItem);
                                                }
                                                noteFileBundleItemCollection.Clear();
                                                foreach (var noteFileBundleItem in noteFileBundleItems)
                                                {
                                                    noteFileBundleItem.BundleItemCollection = noteFileBundleItemCollection;
                                                    noteFileBundleItemCollection.Add(noteFileBundleItem);
                                                }
                                                valueUIBundleItemCollection.Clear();
                                                foreach (var valueUIBundleItem in valueUIBundleItems)
                                                {
                                                    valueUIBundleItem.BundleItemCollection = valueUIBundleItemCollection;
                                                    valueUIBundleItemCollection.Add(valueUIBundleItem);
                                                }
                                                qwilightBundleItemCollection.Clear();
                                                foreach (var qwilightBundleItem in qwilightBundleItems)
                                                {
                                                    qwilightBundleItem.BundleItemCollection = qwilightBundleItemCollection;
                                                    qwilightBundleItemCollection.Add(qwilightBundleItem);
                                                }
                                                eventNoteBundleItemCollection.Clear();
                                                foreach (var eventNoteBundleItem in eventNoteBundleItems)
                                                {
                                                    eventNoteBundleItem.BundleItemCollection = eventNoteBundleItemCollection;
                                                    eventNoteBundleItemCollection.Add(eventNoteBundleItem);
                                                }
                                            });
                                            bundleViewModel.TargetBundleAvatar = targetAvatar;
                                            bundleViewModel.TargetValue = twilightCallBundle.targetValue;
                                            bundleViewModel.BundleLength = twilightCallBundle.bundleLength;
                                            bundleViewModel.NotifyUI();
                                            bundleViewModel.Open();
                                        }
                                        break;
                                    case Event.Types.EventID.CallConfigure:
                                        var twilightCallConfigure = Utility.GetJSON<JSON.TwilightCallConfigure>(eventItemText);
                                        twilightConfigureViewModel.SilentSiteCompetence = new()
                                        {
                                            Data = twilightCallConfigure.silentSiteCompetence
                                        };
                                        twilightConfigureViewModel.NotifyUbuntu = new()
                                        {
                                            Data = twilightCallConfigure.toNotifyUbuntu
                                        };
                                        twilightConfigureViewModel.DefaultBundleCompetence = new()
                                        {
                                            Data = twilightCallConfigure.defaultBundleCompetence
                                        };
                                        twilightConfigureViewModel.IOCompetence = new()
                                        {
                                            Data = twilightCallConfigure.ioCompetence
                                        };
                                        twilightConfigureViewModel.NotifySaveBundle = new()
                                        {
                                            Data = twilightCallConfigure.toNotifySaveBundle
                                        };
                                        twilightConfigureViewModel.NotifyPass = new()
                                        {
                                            Data = twilightCallConfigure.toNotifyPass
                                        };
                                        twilightConfigureViewModel.Open();
                                        break;
                                    case Event.Types.EventID.CallUbuntu:
                                        Utility.SetUICollection(ubuntuViewModel.UbuntuCollection, Utility.GetJSON<JSON.TwilightCallUbuntu[]>(eventItemText).Select(data => new UbuntuItem(data.ubuntuID)
                                        {
                                            AvatarName = data.ubuntuName,
                                            UbuntuSituationValue = (UbuntuItem.UbuntuSituation)data.situationValue,
                                            SituationText = data.situationText
                                        }).ToArray(), null, null, (valueItem, targetItem) =>
                                        {
                                            valueItem.AvatarName = targetItem.AvatarName;
                                            valueItem.UbuntuSituationValue = targetItem.UbuntuSituationValue;
                                            valueItem.SituationText = targetItem.SituationText;
                                        });
                                        break;
                                    case Event.Types.EventID.CallSiteAvatar:
                                        var twilightCallSiteAvatar = Utility.GetJSON<JSON.TwilightCallSiteAvatar>(eventItemText);
                                        ViewModels.Instance.GetSiteViewModel(twilightCallSiteAvatar.siteID)?.SetSiteAvatar(twilightCallSiteAvatar);
                                        break;
                                    case Event.Types.EventID.CallSiteNet:
                                        var twilightCallSiteNet = Utility.GetJSON<JSON.TwilightCallSiteNet>(eventItemText);
                                        ViewModels.Instance.GetSiteViewModel(twilightCallSiteNet.siteID)?.SetSiteNet(twilightCallSiteNet);
                                        break;
                                    case Event.Types.EventID.CallSiteModeComponent:
                                        var twilightCallSiteModeComponent = Utility.GetJSON<JSON.TwilightCallSiteModeComponent>(eventItemText);
                                        ViewModels.Instance.GetSiteViewModel(twilightCallSiteModeComponent.siteID)?.SetSiteModeComponent(twilightCallSiteModeComponent);
                                        break;
                                    case Event.Types.EventID.LevyNet:
                                        var twilightLevyNet = Utility.GetJSON<JSON.TwilightLevyNet>(eventItemText);
                                        var toLevyNetSiteViewModel = ViewModels.Instance.GetSiteViewModel(twilightLevyNet.siteID);
                                        if (toLevyNetSiteViewModel != null)
                                        {
                                            if (mainViewModel.NoteID512s.TryGetValue(toLevyNetSiteViewModel.ComputingValue.NoteID, out var toLevyNoteFile))
                                            {
                                                var isFavorModeComponent = twilightLevyNet.isFavorModeComponent;
                                                toLevyNetSiteViewModel.IsFavorModeComponent = isFavorModeComponent;
                                                toLevyNetSiteViewModel.IsFavorAudioMultiplier = twilightLevyNet.isFavorAudioMultiplier;
                                                var toLevyModeComponentValue = toLevyNetSiteViewModel.ModeComponentValue;
                                                toLevyModeComponentValue.ComputingValue = toLevyNoteFile;
                                                toLevyModeComponentValue.CopyAsJSON(twilightLevyNet.modeComponentData);

                                                mainViewModel.IsCommentMode = false;
                                                var modeComponent = mainViewModel.ModeComponentValue;
                                                var defaultModeComponentValue = modeComponent.Clone();
                                                var defaultMultiplierValue = modeComponent.MultiplierValue;
                                                modeComponent.ComputingValue = toLevyNoteFile;
                                                if (!isFavorModeComponent)
                                                {
                                                    modeComponent.CopyAs(toLevyModeComponentValue);
                                                }
                                                modeComponent.CanModifyMultiplier = true;
                                                modeComponent.MultiplierValue = defaultMultiplierValue;
                                                modeComponent.CanModifyAudioMultiplier = toLevyNetSiteViewModel.IsFavorAudioMultiplier;
                                                if (modeComponent.CanModifyAudioMultiplier)
                                                {
                                                    modeComponent.AudioMultiplier = mainViewModel.ModeComponentValue.AudioMultiplier;
                                                }
                                                else
                                                {
                                                    modeComponent.AudioMultiplier = toLevyModeComponentValue.AudioMultiplier;
                                                }
                                                if (twilightLevyNet.validNetMode > 0)
                                                {
                                                    modeComponent.AudioMultiplier = 1.0;
                                                    modeComponent.FaintNoteModeValue = ModeComponent.FaintNoteMode.Default;
                                                    modeComponent.JudgmentModeValue = ModeComponent.JudgmentMode.Default;
                                                    modeComponent.HitPointsModeValue = ModeComponent.HitPointsMode.Default;
                                                    modeComponent.NoteMobilityModeValue = ModeComponent.NoteMobilityMode.Default;
                                                }
                                                Utility.HandleUIAudio("Levy Note File");
                                                mainViewModel.SetComputingMode(new NetCompute([toLevyNoteFile], twilightLevyNet.validNetMode == 0 && isFavorModeComponent ? null : defaultModeComponentValue, AvatarID, GetAvatarName(), twilightLevyNet));
                                            }
                                            else
                                            {
                                                SendParallel(Event.Types.EventID.Compiled, new
                                                {
                                                    siteID = toLevyNetSiteViewModel.SiteID,
                                                    twilightLevyNet.handlerID,
                                                    isCompiled = false
                                                });
                                                NotifySystem.Instance.Notify(NotifySystem.NotifyVariety.Warning, NotifySystem.NotifyConfigure.Default, LanguageSystem.Instance.HasNotNetNoteFile);
                                            }
                                        }
                                        break;
                                    case Event.Types.EventID.Compiled:
                                        if (defaultComputer is NetCompute && defaultComputer.HandlerID == eventItemText)
                                        {
                                            defaultComputer.HandleComputer();
                                            defaultComputer.WaitingTwilightLevel = DefaultCompute.WaitingTwilight.Default;
                                        }
                                        break;
                                    case Event.Types.EventID.CallNet:
                                        var twilightCallNet = eventItem.TwilightCallNet;
                                        if ((defaultComputer is NetCompute || defaultComputer is IOCompute) && defaultComputer.HandlerID == twilightCallNet.HandlerID && defaultComputer.IsHandling)
                                        {
                                            lock (defaultComputer.IsTwilightNetItemsCSX)
                                            {
                                                if (defaultComputer.IsTwilightNetItems)
                                                {
                                                    foreach (var netItem in defaultComputer.NetItems)
                                                    {
                                                        foreach (var data in twilightCallNet.Data)
                                                        {
                                                            if (data.AvatarID == netItem.AvatarID)
                                                            {
                                                                if (data.IsFailed)
                                                                {
                                                                    netItem.IsFailedStatus = 100.0;
                                                                }
                                                                netItem.TargetPosition = data.TargetPosition;
                                                                netItem.LastJudged = (Component.Judged)data.LastJudged;
                                                                netItem.AvatarNetStatus = data.AvatarNetStatus;
                                                                netItem.HitPointsModeValue = (ModeComponent.HitPointsMode)data.HitPointsMode;
                                                                netItem.SetValue(data.Stand, data.Band, data.Point, data.HitPoints, 1, data.Drawings, data.DrawingComponent);
                                                                break;
                                                            }
                                                        }
                                                    }
                                                }
                                                else
                                                {
                                                    var date = DateTime.Now;
                                                    defaultComputer.IsTwilightNetItems = true;
                                                    defaultComputer.LevyingNetPosition = 0;
                                                    defaultComputer.SetNetItems(twilightCallNet.Data.Select((data, i) =>
                                                    {
                                                        var avatarID = data.AvatarID;
                                                        return new NetItem(avatarID, data.AvatarName, date, data.Stand, data.Band, data.Point, data.HitPoints)
                                                        {
                                                            TargetPosition = i,
                                                            AvatarNetStatus = data.AvatarNetStatus,
                                                            IsMyNetItem = avatarID == defaultComputer.AvatarID,
                                                            IsFailedStatus = data.IsFailed ? 100.0 : 0.0,
                                                            LastJudged = (Component.Judged)data.LastJudged,
                                                            QuitValue = Utility.GetQuitStatusValue(data.Point, data.Stand, data.HitPoints, 1),
                                                            HitPointsModeValue = (ModeComponent.HitPointsMode)data.HitPointsMode
                                                        };
                                                    }).ToList());
                                                    defaultComputer.QuitNetPosition = defaultComputer.NetItems.Length - 1;
                                                }
                                            }
                                        }
                                        break;
                                    case Event.Types.EventID.QuitNet:
                                        var twilightQuitNet = Utility.GetJSON<JSON.TwilightQuitNet>(eventItemText);
                                        if (defaultComputer is NetCompute && defaultComputer.HandlerID == twilightQuitNet.handlerID)
                                        {
                                            if (twilightQuitNet.quitNetItems != null)
                                            {
                                                defaultComputer.PendingQuitNetItems = twilightQuitNet.quitNetItems;
                                                defaultComputer.PendingQuitNetComments = eventItemData.Select(data => Comment.Parser.ParseFrom(data)).ToArray();
                                                defaultComputer.SetQuitMode();
                                            }
                                            else
                                            {
                                                defaultComputer.SetNoteFileMode();
                                            }
                                        }
                                        break;
                                    case Event.Types.EventID.CallNetSiteComments:
                                        var twilightCallNetSiteComments = Utility.GetJSON<JSON.TwilightCallNetSiteComments[]>(eventItemText);
                                        if (twilightCallNetSiteComments != null)
                                        {
                                            var netSiteCommentItemCollection = new Dictionary<long, NetSiteCommentItems>();
                                            foreach (var twilightCallNetSiteComment in twilightCallNetSiteComments)
                                            {
                                                var date = twilightCallNetSiteComment.date;
                                                if (!netSiteCommentItemCollection.TryGetValue(date, out var netSiteCommentItems))
                                                {
                                                    netSiteCommentItems = new()
                                                    {
                                                        Values = new(),
                                                        Date = date
                                                    };
                                                }
                                                foreach (var toCallNetSiteCommentItem in twilightCallNetSiteComment.data)
                                                {
                                                    netSiteCommentItems.Values.Add(new(toCallNetSiteCommentItem));
                                                }
                                                netSiteCommentItemCollection[date] = netSiteCommentItems;
                                            }
                                            var netSiteCommentItemsCollection = netSiteCommentViewModel.NetSiteCommentItemsCollection;
                                            UIHandler.Instance.HandleParallel(() =>
                                            {
                                                netSiteCommentItemsCollection.Clear();
                                                foreach (var date in netSiteCommentItemCollection.Values)
                                                {
                                                    netSiteCommentItemsCollection.Add(date);
                                                }
                                                netSiteCommentViewModel.NetSiteCommentItemsValue = netSiteCommentItemsCollection.LastOrDefault();
                                            });
                                            netSiteCommentViewModel.Open();
                                        }
                                        break;
                                    case Event.Types.EventID.SaveAsBundle:
                                        var twilightSaveAsBundle = Utility.GetJSON<JSON.TwilightSaveAsBundle>(eventItemText);
                                        var bundleEntryPath = twilightSaveAsBundle.bundleEntryPath;
                                        var saveAsBundleID = twilightSaveAsBundle.bundleID;
                                        var saveAsBundleVariety = (BundleItem.BundleVariety)twilightSaveAsBundle.bundleVariety;
                                        var bundleNotifyItem = new NotifyItem
                                        {
                                            Text = LanguageSystem.Instance.SaveAsBundleContents,
                                            Variety = NotifySystem.NotifyVariety.Handling,
                                            Data = ArrayPool<byte>.Shared.Rent(QwilightComponent.SendUnit),
                                            OnStop = wipeTotal =>
                                            {
                                                if (wipeTotal)
                                                {
                                                    return !_bundleNotifyItems.ContainsKey(saveAsBundleID);
                                                }
                                                else
                                                {
                                                    if (_bundleNotifyItems.Remove(saveAsBundleID, out var savingBundleItem))
                                                    {
                                                        savingBundleItem.Variety = NotifySystem.NotifyVariety.Stopped;
                                                        savingBundleItem.Text = LanguageSystem.Instance.StopSavingAsBundleContents;
                                                        savingBundleItem.IsStopped = true;
                                                        SendParallel(Event.Types.EventID.StopSavingAsBundle, saveAsBundleID);
                                                        return false;
                                                    }
                                                    else
                                                    {
                                                        return true;
                                                    }
                                                }
                                            }
                                        };
                                        _bundleNotifyItems[saveAsBundleID] = bundleNotifyItem;
                                        UIHandler.Instance.HandleParallel(() => toNotifyViewModel.HandlingNotifyItemCollection.Insert(0, bundleNotifyItem));
                                        NotifySystem.Instance.Notify(NotifySystem.NotifyVariety.Info, NotifySystem.NotifyConfigure.NotSave, bundleNotifyItem.Text, false, null, null, NotifySystem.SaveAsBundleID);
                                        Task.Run(() =>
                                        {
                                            try
                                            {
                                                using var rms = PoolSystem.Instance.GetDataFlow();
                                                using (var zipFile = new ZipFile
                                                {
                                                    AlternateEncoding = Encoding.UTF8,
                                                    AlternateEncodingUsage = ZipOption.Always,
                                                })
                                                {
                                                    switch (saveAsBundleVariety)
                                                    {
                                                        case BundleItem.BundleVariety.Net:
                                                        case BundleItem.BundleVariety.NoteFiles:
                                                            zipFile.AddDirectory(bundleEntryPath);
                                                            zipFile.SaveProgress += OnSavingZipFile;
                                                            zipFile.Save(rms);
                                                            break;
                                                        case BundleItem.BundleVariety.UI:
                                                            if (Path.GetFileName(twilightSaveAsBundle.bundleName).StartsWith('@'))
                                                            {
                                                                BaseUI.ZipUIFile(zipFile, new()
                                                                {
                                                                    UIEntry = Path.GetDirectoryName(bundleEntryPath),
                                                                    YamlName = Path.GetFileNameWithoutExtension(bundleEntryPath)
                                                                }, string.Empty);
                                                            }
                                                            else
                                                            {
                                                                UI.ZipUIFile(zipFile, new()
                                                                {
                                                                    UIEntry = Path.GetDirectoryName(bundleEntryPath),
                                                                    YamlName = Path.GetFileNameWithoutExtension(bundleEntryPath)
                                                                }, string.Empty);
                                                            }
                                                            zipFile.SaveProgress += OnSavingZipFile;
                                                            zipFile.Save(rms);
                                                            break;
                                                        case BundleItem.BundleVariety.Qwilight:
                                                            Configure.Instance.Save(false);
                                                            GPUConfigure.Instance.Save(false);
                                                            DB.Instance.Save();
                                                            if (Directory.Exists(QwilightComponent.CommentEntryPath))
                                                            {
                                                                zipFile.AddDirectory(QwilightComponent.CommentEntryPath, "Comment");
                                                            }
                                                            var levelFilePath = Path.Combine(LevelSystem.EntryPath, $"{Configure.Instance.LastWantLevelName}.json");
                                                            if (File.Exists(levelFilePath))
                                                            {
                                                                zipFile.AddFile(levelFilePath, "Level");
                                                            }
                                                            levelFilePath = Path.Combine(LevelSystem.EntryPath, $"#{Configure.Instance.LastWantLevelName}.json");
                                                            if (File.Exists(levelFilePath))
                                                            {
                                                                zipFile.AddFile(levelFilePath, "Level");
                                                            }
                                                            if (Configure.Instance.BaseUIItemValue.UIEntry != "@Default" || Configure.Instance.BaseUIItemValue.YamlName != "@Default")
                                                            {
                                                                BaseUI.ZipUIFile(zipFile, Configure.Instance.BaseUIItemValue, "UI");
                                                            }
                                                            if (Configure.Instance.UIItemValue.UIEntry != "Default" || Configure.Instance.UIItemValue.YamlName != "Default")
                                                            {
                                                                UI.ZipUIFile(zipFile, Configure.Instance.UIItemValue, "UI");
                                                            }
                                                            zipFile.AddFile(Path.Combine(QwilightComponent.QwilightEntryPath, "Configure.json"), string.Empty);
                                                            zipFile.AddFile(Path.Combine(QwilightComponent.QwilightEntryPath, "GPU Configure.json"), string.Empty);
                                                            zipFile.AddFile(Path.Combine(QwilightComponent.QwilightEntryPath, "DB.db"), string.Empty);
                                                            zipFile.SaveProgress += OnSavingZipFile;
                                                            zipFile.Save(rms);
                                                            break;
                                                        case BundleItem.BundleVariety.EventNote:
                                                            var eventNoteData = Encoding.UTF8.GetBytes(bundleEntryPath);
                                                            rms.Write(eventNoteData, 0, eventNoteData.Length);
                                                            break;
                                                        case BundleItem.BundleVariety.NoteFile:
                                                            twilightSaveAsBundle.bundleEntryPath = Path.GetDirectoryName(bundleEntryPath)!;
                                                            zipFile.AddFile(bundleEntryPath, string.Empty);
                                                            zipFile.SaveProgress += OnSavingZipFile;
                                                            zipFile.Save(rms);
                                                            break;
                                                    }
                                                }

                                                if (!bundleNotifyItem.IsStopped)
                                                {
                                                    bundleNotifyItem.Text = LanguageSystem.Instance.SavingAsBundleContents;
                                                    NotifySystem.Instance.Notify(NotifySystem.NotifyVariety.Info, NotifySystem.NotifyConfigure.NotSave, bundleNotifyItem.Text, false, null, null, NotifySystem.SaveAsBundleID);
                                                    bundleNotifyItem.MaxStatus = rms.Length;
                                                    rms.Position = 0;
                                                    while (_bundleNotifyItems.TryGetValue(saveAsBundleID, out var savingBundleItem))
                                                    {
                                                        var length = (int)Math.Min(savingBundleItem.Data.Length, rms.Length - rms.Position);
                                                        rms.Read(savingBundleItem.Data, 0, length);
                                                        savingBundleItem.Status += length;
                                                        if (length < savingBundleItem.Data.Length)
                                                        {
                                                            Send(Event.Types.EventID.SavedAsBundle, saveAsBundleID, UnsafeByteOperations.UnsafeWrap(savingBundleItem.Data.AsMemory(0, length)));
                                                            if (_bundleNotifyItems.Remove(saveAsBundleID, out _))
                                                            {
                                                                savingBundleItem.Variety = NotifySystem.NotifyVariety.Closed;
                                                                savingBundleItem.Text = LanguageSystem.Instance.SavedAsBundleContents;
                                                                NotifySystem.Instance.Notify(NotifySystem.NotifyVariety.OK, NotifySystem.NotifyConfigure.NotSave, savingBundleItem.Text, false, null, null, NotifySystem.SaveAsBundleID);
                                                            }
                                                            break;
                                                        }
                                                        else
                                                        {
                                                            Send(Event.Types.EventID.SavingAsBundle, saveAsBundleID, UnsafeByteOperations.UnsafeWrap(savingBundleItem.Data));
                                                        }
                                                    }
                                                }

                                                void OnSavingZipFile(object sender, SaveProgressEventArgs e)
                                                {
                                                    if (bundleNotifyItem.IsStopped)
                                                    {
                                                        e.Cancel = true;
                                                        bundleNotifyItem.Dispose();
                                                    }
                                                    else
                                                    {
                                                        if (e.EntriesTotal > 0)
                                                        {
                                                            bundleNotifyItem.Status = e.EntriesSaved;
                                                            bundleNotifyItem.MaxStatus = e.EntriesTotal;
                                                        }
                                                    }
                                                }
                                            }
                                            catch (Exception e)
                                            {
                                                bundleNotifyItem.OnStop(false);
                                                NotifySystem.Instance.Notify(NotifySystem.NotifyVariety.Fault, NotifySystem.NotifyConfigure.Default, string.Format(LanguageSystem.Instance.SaveAsBundleFault, e.Message), false, null, null, NotifySystem.SaveAsBundleID);
                                            }
                                            finally
                                            {
                                                bundleNotifyItem.Dispose();
                                            }
                                        });
                                        break;
                                    case Event.Types.EventID.StopSavingAsBundle:
                                        if (_bundleNotifyItems.TryGetValue(eventItemText, out bundleNotifyItem))
                                        {
                                            bundleNotifyItem.Variety = NotifySystem.NotifyVariety.Stopped;
                                            bundleNotifyItem.Text = LanguageSystem.Instance.StopSavingAsBundleContents;
                                        }
                                        break;
                                    case Event.Types.EventID.SaveBundle:
                                        var twilightSaveBundle = Utility.GetJSON<JSON.TwilightSaveBundle>(eventItemText);
                                        var saveBundleID = twilightSaveBundle.bundleID;
                                        var saveBundleVariety = (BundleItem.BundleVariety)twilightSaveBundle.bundleVariety;
                                        var bundleLength = twilightSaveBundle.bundleLength;
                                        bundleNotifyItem = new NotifyItem
                                        {
                                            Text = LanguageSystem.Instance.SaveBundleContents,
                                            Variety = NotifySystem.NotifyVariety.Handling,
                                            DataFlow = PoolSystem.Instance.GetDataFlow(bundleLength),
                                            OnStop = wipeTotal =>
                                            {
                                                if (wipeTotal)
                                                {
                                                    return !_bundleNotifyItems.ContainsKey(saveBundleID);
                                                }
                                                else
                                                {
                                                    if (_bundleNotifyItems.Remove(saveBundleID, out var savingBundleItem))
                                                    {
                                                        savingBundleItem.Variety = NotifySystem.NotifyVariety.Stopped;
                                                        savingBundleItem.Text = LanguageSystem.Instance.StopSavingBundleContents;
                                                        savingBundleItem.IsStopped = true;
                                                        SendParallel(Event.Types.EventID.StopSavingBundle, saveBundleID);
                                                        return false;
                                                    }
                                                    else
                                                    {
                                                        return true;
                                                    }
                                                }
                                            },
                                            MaxStatus = bundleLength
                                        };
                                        _bundleNotifyItems[saveBundleID] = bundleNotifyItem;
                                        UIHandler.Instance.HandleParallel(() => toNotifyViewModel.HandlingNotifyItemCollection.Insert(0, bundleNotifyItem));
                                        if (saveBundleVariety != BundleItem.BundleVariety.DefaultNoteFiles && saveBundleVariety != BundleItem.BundleVariety.DefaultUI)
                                        {
                                            NotifySystem.Instance.Notify(NotifySystem.NotifyVariety.Info, NotifySystem.NotifyConfigure.NotSave, bundleNotifyItem.Text, false, null, null, NotifySystem.SaveBundleID);
                                        }
                                        SendParallel(Event.Types.EventID.SavingBundle, saveBundleID);
                                        break;
                                    case Event.Types.EventID.SavingBundle:
                                        if (_bundleNotifyItems.TryGetValue(eventItemText, out bundleNotifyItem))
                                        {
                                            if (bundleNotifyItem.IsStopped)
                                            {
                                                bundleNotifyItem.Dispose();
                                            }
                                            else
                                            {
                                                eventItemData[0].WriteTo(bundleNotifyItem.DataFlow);
                                            }
                                            bundleNotifyItem.Status += eventItemData[0].Length;
                                        }
                                        break;
                                    case Event.Types.EventID.SavedBundle:
                                        var twilightSavedBundle = Utility.GetJSON<JSON.TwilightSavedBundle>(eventItemText);
                                        if (_bundleNotifyItems.Remove(twilightSavedBundle.bundleID, out bundleNotifyItem))
                                        {
                                            if (bundleNotifyItem.IsStopped)
                                            {
                                                bundleNotifyItem.Dispose();
                                            }
                                            else
                                            {
                                                eventItemData[0].WriteTo(bundleNotifyItem.DataFlow);
                                                Utility.HandleParallelly(() =>
                                                {
                                                    var dataFlow = bundleNotifyItem.DataFlow;
                                                    dataFlow.Position = 0;
                                                    var bundleVariety = (BundleItem.BundleVariety)twilightSavedBundle.bundleVariety;
                                                    var isNotDefaultBundle = bundleVariety != BundleItem.BundleVariety.DefaultNoteFiles && bundleVariety != BundleItem.BundleVariety.DefaultUI;
                                                    try
                                                    {
                                                        switch (bundleVariety)
                                                        {
                                                            case BundleItem.BundleVariety.NoteFiles:
                                                            case BundleItem.BundleVariety.DefaultNoteFiles:
                                                            case BundleItem.BundleVariety.Net:
                                                                var bundleEntryPath = Path.Combine(QwilightComponent.BundleEntryPath, twilightSavedBundle.bundleName);
                                                                using (var zipFile = ZipFile.Read(dataFlow))
                                                                {
                                                                    bundleNotifyItem.Text = LanguageSystem.Instance.SavingBundleContents;
                                                                    if (isNotDefaultBundle)
                                                                    {
                                                                        NotifySystem.Instance.Notify(NotifySystem.NotifyVariety.Info, NotifySystem.NotifyConfigure.NotSave, bundleNotifyItem.Text, false, null, null, NotifySystem.SaveBundleID);
                                                                    }
                                                                    zipFile.ExtractProgress += OnSavingZipFile;
                                                                    zipFile.ExtractAll(bundleEntryPath, ExtractExistingFileAction.OverwriteSilently);
                                                                }
                                                                if (!bundleNotifyItem.IsStopped)
                                                                {
                                                                    mainViewModel.LoadEntryItem(DefaultEntryItem.EssentialBundle, bundleEntryPath, isNotDefaultBundle);
                                                                    bundleNotifyItem.Variety = NotifySystem.NotifyVariety.Closed;
                                                                    bundleNotifyItem.Text = LanguageSystem.Instance.SavedBundleContents;
                                                                    if (isNotDefaultBundle)
                                                                    {
                                                                        NotifySystem.Instance.Notify(NotifySystem.NotifyVariety.OK, NotifySystem.NotifyConfigure.NotSave, bundleNotifyItem.Text, false, null, null, NotifySystem.SaveBundleID);
                                                                    }
                                                                    else if (twilightSavedBundle.isLastDefault)
                                                                    {
                                                                        NotifySystem.Instance.Notify(NotifySystem.NotifyVariety.OK, NotifySystem.NotifyConfigure.NotSave, LanguageSystem.Instance.SavedDefaultNoteContents, false, null, null, NotifySystem.SaveBundleID);
                                                                    }
                                                                }
                                                                break;
                                                            case BundleItem.BundleVariety.DefaultUI:
                                                            case BundleItem.BundleVariety.UI:
                                                                using (var zipFile = ZipFile.Read(dataFlow))
                                                                {
                                                                    bundleNotifyItem.Text = LanguageSystem.Instance.SavingBundleContents;
                                                                    if (isNotDefaultBundle)
                                                                    {
                                                                        NotifySystem.Instance.Notify(NotifySystem.NotifyVariety.Info, NotifySystem.NotifyConfigure.NotSave, bundleNotifyItem.Text, false, null, null, NotifySystem.SaveBundleID);
                                                                    }
                                                                    zipFile.ExtractProgress += OnSavingZipFile;
                                                                    zipFile.ExtractAll(string.IsNullOrEmpty(Path.GetDirectoryName(zipFile.Where(zipEntry => zipEntry.FileName.IsTailCaselsss(".yaml")).OrderBy(zipEntry => zipEntry.FileName).FirstOrDefault().FileName)) ? Path.Combine(QwilightComponent.UIEntryPath, twilightSavedBundle.bundleName) : QwilightComponent.UIEntryPath, ExtractExistingFileAction.OverwriteSilently);
                                                                }
                                                                if (!bundleNotifyItem.IsStopped)
                                                                {
                                                                    bundleNotifyItem.Variety = NotifySystem.NotifyVariety.Closed;
                                                                    bundleNotifyItem.Text = LanguageSystem.Instance.SavedBundleContents;
                                                                    if (isNotDefaultBundle)
                                                                    {
                                                                        NotifySystem.Instance.Notify(NotifySystem.NotifyVariety.OK, NotifySystem.NotifyConfigure.NotSave, bundleNotifyItem.Text, false, null, null, NotifySystem.SaveBundleID);
                                                                    }
                                                                    else if (twilightSavedBundle.isLastDefault)
                                                                    {
                                                                        NotifySystem.Instance.Notify(NotifySystem.NotifyVariety.OK, NotifySystem.NotifyConfigure.NotSave, LanguageSystem.Instance.SavedDefaultUIContents, false, null, null, NotifySystem.SaveBundleID);
                                                                    }
                                                                }
                                                                break;
                                                            case BundleItem.BundleVariety.Qwilight:
                                                                using (var fs = File.OpenWrite(Path.Combine(QwilightComponent.QwilightEntryPath, "Qwilight.zip")))
                                                                {
                                                                    dataFlow.CopyTo(fs);
                                                                }
                                                                bundleNotifyItem.Variety = NotifySystem.NotifyVariety.Closed;
                                                                bundleNotifyItem.Text = LanguageSystem.Instance.SavedQwilightBundleContents;
                                                                NotifySystem.Instance.Notify(NotifySystem.NotifyVariety.Info, NotifySystem.NotifyConfigure.NotSave, bundleNotifyItem.Text, false, null, null, NotifySystem.SaveBundleID);
                                                                break;
                                                            case BundleItem.BundleVariety.EventNote:
                                                                try
                                                                {
                                                                    var eventNoteID = Encoding.UTF8.GetString(dataFlow.ToArray()).Split('.')[0];
                                                                    var eventNoteName = Path.GetFileNameWithoutExtension(twilightSavedBundle.bundleName);
                                                                    var eventNoteVariety = twilightSavedBundle.etc switch
                                                                    {
                                                                        "MD5" => DB.EventNoteVariety.MD5,
                                                                        "Qwilight" => DB.EventNoteVariety.Qwilight,
                                                                        _ => throw new ArgumentException(twilightSavedBundle.etc.ToString())
                                                                    };
                                                                    var date = DateTime.Now;
                                                                    DB.Instance.SetEventNote(eventNoteID, eventNoteName, date, eventNoteVariety);
                                                                    bundleNotifyItem.Variety = NotifySystem.NotifyVariety.Closed;
                                                                    bundleNotifyItem.Text = LanguageSystem.Instance.SavedBundleContents;
                                                                    NotifySystem.Instance.Notify(NotifySystem.NotifyVariety.OK, NotifySystem.NotifyConfigure.NotSave, bundleNotifyItem.Text, false, null, null, NotifySystem.SaveBundleID);
                                                                    mainViewModel.LoadEventNoteEntryItems();
                                                                    mainViewModel.Want();
                                                                }
                                                                catch (SqliteException)
                                                                {
                                                                    NotifySystem.Instance.Notify(NotifySystem.NotifyVariety.Warning, NotifySystem.NotifyConfigure.Default, LanguageSystem.Instance.BeforeEventNoteContents, false, null, null, NotifySystem.SaveBundleID);
                                                                }
                                                                break;
                                                            case BundleItem.BundleVariety.NoteFile:
                                                                var noteID = twilightSavedBundle.etc.Split('/').FirstOrDefault(noteID512s => mainViewModel.NoteID512s.ContainsKey(noteID512s));
                                                                if (noteID != null && mainViewModel.NoteID512s.TryGetValue(noteID, out var noteFile))
                                                                {
                                                                    using (var zipFile = ZipFile.Read(dataFlow))
                                                                    {
                                                                        bundleNotifyItem.Text = LanguageSystem.Instance.SavingBundleContents;
                                                                        NotifySystem.Instance.Notify(NotifySystem.NotifyVariety.Info, NotifySystem.NotifyConfigure.NotSave, bundleNotifyItem.Text, false, null, null, NotifySystem.SaveBundleID);
                                                                        zipFile.ExtractProgress += OnSavingZipFile;
                                                                        zipFile.ExtractAll(noteFile.EntryItem.EntryPath, ExtractExistingFileAction.OverwriteSilently);
                                                                    }
                                                                    if (!bundleNotifyItem.IsStopped)
                                                                    {
                                                                        mainViewModel.LoadEntryItem(noteFile.DefaultEntryItem, noteFile.EntryItem.EntryPath);
                                                                        bundleNotifyItem.Variety = NotifySystem.NotifyVariety.Closed;
                                                                        bundleNotifyItem.Text = LanguageSystem.Instance.SavedBundleContents;
                                                                        NotifySystem.Instance.Notify(NotifySystem.NotifyVariety.OK, NotifySystem.NotifyConfigure.NotSave, bundleNotifyItem.Text, false, null, null, NotifySystem.SaveBundleID);
                                                                    }
                                                                }
                                                                else
                                                                {
                                                                    bundleNotifyItem.Text = LanguageSystem.Instance.NotHaveNoteFileEntryText;
                                                                    NotifySystem.Instance.Notify(NotifySystem.NotifyVariety.Warning, NotifySystem.NotifyConfigure.NotSave, bundleNotifyItem.Text, false, null, null, NotifySystem.SaveBundleID);
                                                                }
                                                                break;
                                                        }

                                                        void OnSavingZipFile(object sender, ExtractProgressEventArgs e)
                                                        {
                                                            if (bundleNotifyItem.IsStopped)
                                                            {
                                                                e.Cancel = true;
                                                            }
                                                            else
                                                            {
                                                                if (e.EntriesTotal > 0)
                                                                {
                                                                    bundleNotifyItem.Status = e.EntriesExtracted;
                                                                    bundleNotifyItem.MaxStatus = e.EntriesTotal;
                                                                }
                                                            }
                                                        }
                                                    }
                                                    catch (Exception e)
                                                    {
                                                        bundleNotifyItem.OnStop(false);
                                                        NotifySystem.Instance.Notify(NotifySystem.NotifyVariety.Fault, NotifySystem.NotifyConfigure.Default, string.Format(LanguageSystem.Instance.SaveBundleFault, e.Message), false, null, null, NotifySystem.SaveBundleID);
                                                    }
                                                    finally
                                                    {
                                                        bundleNotifyItem.Dispose();
                                                    }
                                                }, false);
                                            }
                                        }
                                        break;
                                    case Event.Types.EventID.PostFile:
                                        var toPostFileSiteViewModel = ViewModels.Instance.SiteContainerValue.SiteValue;
                                        if (toPostFileSiteViewModel != null)
                                        {
                                            toPostFileSiteViewModel.TextInput = eventItemText;
                                        }
                                        break;
                                    case Event.Types.EventID.CallIo:
                                        var twilightCallIO = Utility.GetJSON<JSON.TwilightCallIO>(eventItemText);
                                        if (defaultComputer?.CanIO == true && defaultComputer.IsHandling)
                                        {
                                            SendParallel(Event.Types.EventID.CallIoComponent, new
                                            {
                                                noteID = defaultComputer.NoteFile.GetNoteID512(),
                                                handlerID = defaultComputer.HandlerID,
                                                twilightCallIO.avatarID,
                                                data = defaultComputer.ModeComponentValue.GetJSON(),
                                                ioHandlerID = twilightCallIO.handlerID,
                                                isFailMode = defaultComputer.IsFailMode,
                                                ioMillis = twilightCallIO.ioMillis,
                                                targetIOMillis = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds()
                                            });
                                        }
                                        else
                                        {
                                            SendParallel(Event.Types.EventID.IoNot, new
                                            {
                                                avatarID = twilightCallIO.avatarID,
                                                handlerID = twilightCallIO.handlerID
                                            });
                                        }
                                        break;
                                    case Event.Types.EventID.IoNot:
                                        if (string.IsNullOrEmpty(eventItemText))
                                        {
                                            NotifySystem.Instance.Notify(NotifySystem.NotifyVariety.Warning, NotifySystem.NotifyConfigure.Default, LanguageSystem.Instance.CannotIOContents);
                                        }
                                        break;
                                    case Event.Types.EventID.CallIoComponent:
                                        var twilightCallIOComponent = Utility.GetJSON<JSON.TwilightCallIOComponent>(eventItemText);
                                        if (mainViewModel.NoteID512s.TryGetValue(twilightCallIOComponent.noteID, out var ioNoteFile))
                                        {
                                            mainViewModel.IsCommentMode = false;
                                            var modeComponent = mainViewModel.ModeComponentValue;
                                            var defaultModeComponentValue = modeComponent.Clone();
                                            modeComponent.ComputingValue = ioNoteFile;
                                            modeComponent.CopyAsJSON(twilightCallIOComponent.data);
                                            modeComponent.CanModifyMultiplier = false;
                                            modeComponent.CanModifyAudioMultiplier = false;
                                            mainViewModel.SetComputingMode(new IOCompute([ioNoteFile], defaultModeComponentValue, twilightCallIOComponent));
                                        }
                                        else
                                        {
                                            NotifySystem.Instance.Notify(NotifySystem.NotifyVariety.Warning, NotifySystem.NotifyConfigure.Default, LanguageSystem.Instance.HasNotIONoteFile);
                                            if (!string.IsNullOrEmpty(twilightCallIOComponent.ioHandlerID))
                                            {
                                                mainViewModel.Computer.SetNoteFileMode();
                                            }
                                        }
                                        break;
                                    case Event.Types.EventID.CompiledIo:
                                        var twilightCompiledIO = Utility.GetJSON<JSON.TwilightCompiledIO>(eventItemText);
                                        if (defaultComputer.HandlerID == twilightCompiledIO.handlerID)
                                        {
                                            if (defaultComputer.CanIO && defaultComputer.IsHandling)
                                            {
                                                defaultComputer.TwilightCompiledIOQueue.Enqueue(twilightCompiledIO);
                                            }
                                            else
                                            {
                                                SendParallel(Event.Types.EventID.IoQuit, new
                                                {
                                                    twilightCompiledIO.handlerID,
                                                    avatarIDs = new[] { twilightCompiledIO.avatarID },
                                                    isBanned = true
                                                });
                                            }
                                        }
                                        break;
                                    case Event.Types.EventID.LevyIo:
                                        var twilightLevyIO = Utility.GetJSON<JSON.TwilightLevyIO>(eventItemText);
                                        if (defaultComputer is IOCompute && defaultComputer.HandlerID == twilightLevyIO.handlerID)
                                        {
                                            var comment = Comment.Parser.ParseFrom(eventItemData[0]);
                                            defaultComputer.IOLazyInit = new(() =>
                                            {
                                                defaultComputer.LastStand = twilightLevyIO.lastStand;
                                                defaultComputer.IsF.SetValue(twilightLevyIO.isF);
                                                var sentMultiplier = twilightLevyIO.multiplier;
                                                defaultComputer.ModeComponentValue.SentMultiplier = sentMultiplier;
                                                defaultComputer.ModeComponentValue.MultiplierValue = defaultComputer.ModeComponentValue.BPM * defaultComputer.ModeComponentValue.AudioMultiplier * sentMultiplier;
                                                defaultComputer.ModeComponentValue.AudioMultiplier = twilightLevyIO.audioMultiplier;
                                            });
                                            defaultComputer.IOMillis += twilightLevyIO.ioMillis;
                                            defaultComputer.LevyingWait = twilightLevyIO.levyingWait;
                                            defaultComputer.WaitingTwilightLevel = DefaultCompute.WaitingTwilight.Default;
                                            defaultComputer.EventComment = comment;
                                            if (defaultComputer.IsHandling)
                                            {
                                                defaultComputer.SetUndoValue = DefaultCompute.SetUndo.Just;
                                            }
                                            else
                                            {
                                                defaultComputer.HandleComputer();
                                            }
                                        }
                                        break;
                                    case Event.Types.EventID.IoInput:
                                        var twilightIOInput = eventItem.TwilightIOInput;
                                        if (defaultComputer is IOCompute && defaultComputer.HandlerID == twilightIOInput.HandlerID)
                                        {
                                            var twilightIOInputQueue = defaultComputer.TwilightIOInputQueue;
                                            lock (twilightIOInputQueue)
                                            {
                                                twilightIOInputQueue.Enqueue(Elapsable<Event.Types.TwilightIOInput>.GetElapsable(twilightIOInput));
                                            }
                                        }
                                        break;
                                    case Event.Types.EventID.IoJudge:
                                        var twilightIOJudge = eventItem.TwilightIOJudge;
                                        if (defaultComputer is IOCompute && defaultComputer.HandlerID == twilightIOJudge.HandlerID)
                                        {
                                            var twilightIOJudgeQueue = defaultComputer.TwilightIOJudgeQueue;
                                            lock (twilightIOJudgeQueue)
                                            {
                                                twilightIOJudgeQueue.Enqueue(Elapsable<Event.Types.TwilightIOJudge>.GetElapsable(twilightIOJudge));
                                            }
                                        }
                                        break;
                                    case Event.Types.EventID.IoNoteVisibility:
                                        var twilightIONoteVisibility = eventItem.TwilightIONoteVisibility;
                                        if (defaultComputer is IOCompute && defaultComputer.HandlerID == twilightIONoteVisibility.HandlerID)
                                        {
                                            var twilightIONoteVisibilityQueue = defaultComputer.TwilightIONoteVisibilityQueue;
                                            lock (twilightIONoteVisibilityQueue)
                                            {
                                                twilightIONoteVisibilityQueue.Enqueue(Elapsable<Event.Types.TwilightIONoteVisibility>.GetElapsable(twilightIONoteVisibility));
                                            }
                                        }
                                        break;
                                    case Event.Types.EventID.IoJudgmentMeter:
                                        var twilightIOJudgmentMeter = eventItem.TwilightIOJudgmentMeter;
                                        if (defaultComputer is IOCompute && defaultComputer.HandlerID == twilightIOJudgmentMeter.HandlerID)
                                        {
                                            var twilightIOJudgmentMeterQueue = defaultComputer.TwilightIOJudgmentMeterQueue;
                                            lock (twilightIOJudgmentMeterQueue)
                                            {
                                                twilightIOJudgmentMeterQueue.Enqueue(Elapsable<Event.Types.TwilightIOJudgmentMeter>.GetElapsable(twilightIOJudgmentMeter));
                                            }
                                        }
                                        break;
                                    case Event.Types.EventID.IoMultiplier:
                                        var twilightIOMultiplier = eventItem.TwilightIOMultiplier;
                                        if (defaultComputer is IOCompute && defaultComputer.HandlerID == twilightIOMultiplier.HandlerID)
                                        {
                                            var twilightIOMultiplierQueue = defaultComputer.TwilightIOMultiplierQueue;
                                            lock (twilightIOMultiplierQueue)
                                            {
                                                twilightIOMultiplierQueue.Enqueue(Elapsable<Event.Types.TwilightIOMultiplier>.GetElapsable(twilightIOMultiplier));
                                            }
                                        }
                                        break;
                                    case Event.Types.EventID.IoAudioMultiplier:
                                        var twilightIOAudioMultiplier = eventItem.TwilightIOAudioMultiplier;
                                        if (defaultComputer is IOCompute && defaultComputer.HandlerID == twilightIOAudioMultiplier.HandlerID)
                                        {
                                            var twilightAudioMultiplierQueue = defaultComputer.TwilightIOAudioMultiplierQueue;
                                            lock (twilightAudioMultiplierQueue)
                                            {
                                                twilightAudioMultiplierQueue.Enqueue(Elapsable<Event.Types.TwilightIOAudioMultiplier>.GetElapsable(twilightIOAudioMultiplier));
                                            }
                                        }
                                        break;
                                    case Event.Types.EventID.IoPause:
                                        var twilightIOPause = Utility.GetJSON<JSON.TwilightIOPause>(eventItemText);
                                        if (defaultComputer is IOCompute && defaultComputer.HandlerID == twilightIOPause.handlerID)
                                        {
                                            defaultComputer.SetPause = twilightIOPause.isPaused;
                                        }
                                        break;
                                    case Event.Types.EventID.IoQuit:
                                        var twilightIOQuit = Utility.GetJSON<JSON.TwilightIOQuit>(eventItemText);
                                        if (defaultComputer is IOCompute && defaultComputer.HandlerID == twilightIOQuit.handlerID)
                                        {
                                            if (string.IsNullOrEmpty(twilightIOQuit.avatarID))
                                            {
                                                defaultComputer.SetNoteFileMode();
                                            }
                                            else
                                            {
                                                defaultComputer.IOLazyInit = new(() =>
                                                {
                                                    defaultComputer.SetPause = true;
                                                });
                                                defaultComputer.LevyingWait = double.NaN;
                                                defaultComputer.SetUndoValue = DefaultCompute.SetUndo.Just;
                                                defaultComputer.WaitingTwilightLevel = DefaultCompute.WaitingTwilight.CallIO;
                                            }
                                        }
                                        break;
                                    case Event.Types.EventID.AudioInput:
                                        var twilightAudioInput = eventItem.TwilightAudioInput;
                                        var audioInputSiteViewModel = ViewModels.Instance.GetSiteViewModel(twilightAudioInput.SiteID);
                                        if (audioInputSiteViewModel?.IsAudioInput == true)
                                        {
                                            AudioInputSystem.Instance.Handle(twilightAudioInput.AvatarID, eventItemData[0].ToByteArray(), eventItemData[0].Length);
                                        }
                                        break;
                                    case Event.Types.EventID.InvalidateAvatarDrawing:
                                        AvatarDrawingSystem.Instance.WipeAvatarDrawing(eventItemText);
                                        break;
                                    case Event.Types.EventID.InvalidateAvatarTitle:
                                        AvatarTitleSystem.Instance.WipeAvatarTitle(eventItemText);
                                        break;
                                    case Event.Types.EventID.InvalidateAvatarEdge:
                                        AvatarEdgeSystem.Instance.WipeAvatarEdge(eventItemText);
                                        break;
                                    case Event.Types.EventID.AlreadyLoadingBundle:
                                        NotifySystem.Instance.Notify(NotifySystem.NotifyVariety.Warning, NotifySystem.NotifyConfigure.Default, LanguageSystem.Instance.AlreadyLoadingBundle);
                                        ViewModels.Instance.NotifyValue.Open();
                                        break;
                                    case Event.Types.EventID.PostItem:
                                        var twilightPostItem = eventItem.TwilightPostItem;
                                        if (defaultComputer is NetCompute && defaultComputer.IsPostableItemMode && defaultComputer.HandlerID == twilightPostItem.HandlerID)
                                        {
                                            defaultComputer.TwilightPostItemQueue.Enqueue(twilightPostItem);
                                        }
                                        break;
                                }
                            }
                            catch (Exception e)
                            {
                                if (_isAvailable)
                                {
                                    if (textClose == null)
                                    {
                                        Utility.SaveFaultFile(FaultEntryPath, e);
                                    }
                                    else if (textClose.Length > 0)
                                    {
                                        NotifySystem.Instance.Notify(NotifySystem.NotifyVariety.Info, NotifySystem.NotifyConfigure.Default, string.Format($"{LanguageSystem.Instance.TwilightCloseContents} ({{0}})", textClose), false);
                                    }
                                    else
                                    {
                                        NotifySystem.Instance.Notify(NotifySystem.NotifyVariety.Info, NotifySystem.NotifyConfigure.Default, LanguageSystem.Instance.TwilightCloseContents, false);
                                    }
                                }
                            }
                        }
                    }
                }
                catch
                {
                    Thread.Sleep(1000);
                }
                finally
                {
                    if (IsEstablished)
                    {
                        ViewModels.Instance.WipeSiteViewModels();
                        UIHandler.Instance.HandleParallel(siteContainerViewModel.SiteViewCollection.Clear);
                        foreach (var bundleID in _bundleNotifyItems.Keys)
                        {
                            if (_bundleNotifyItems.Remove(bundleID, out var savingBundleItem))
                            {
                                savingBundleItem.OnStop(false);
                            }
                        }
                        Totem = string.Empty;
                        AvatarID = string.Empty;
                        AvatarName = string.Empty;
                        TwilightSituation = NotEstablished;
                    }
                }
            }
        }

        public void Stop()
        {
            _ts?.Dispose();
        }

        public void Dispose()
        {
            _isAvailable = false;
            Stop();
        }

        public async ValueTask<Stream> GetWwwParallel(string target)
        {
            if (!target.IsFrontCaselsss(QwilightComponent.QwilightAPI) || IsEstablished)
            {
                try
                {
                    var dataGet = new HttpRequestMessage(HttpMethod.Get, target);
                    var www = await _wwwClient.SendAsync(dataGet);
                    www.EnsureSuccessStatusCode();
                    return await www.Content.ReadAsStreamAsync();
                }
                catch
                {
                }
            }

            return Stream.Null;
        }

        public async Task<T> GetWwwParallel<T>(string target)
        {
            if (target.EqualsCaseless($"{QwilightComponent.TaehuiNetFE}/qwilight/qwilight.json") || !target.IsFrontCaselsss(QwilightComponent.TaehuiNetFE) || IsEstablished)
            {
                try
                {
                    var dataGet = new HttpRequestMessage(HttpMethod.Get, target);
                    using var www = await _wwwClient.SendAsync(dataGet);
                    www.EnsureSuccessStatusCode();
                    var text = await www.Content.ReadAsStringAsync();
                    if (!string.IsNullOrEmpty(text))
                    {
                        return Utility.GetJSON<T>(text);
                    }
                }
                catch
                {
                }
            }

            return default(T);
        }

        public async Task<bool> PostWwwParallel(string target, string data, string dataVariety = "text/plain")
        {
            if (IsEstablished)
            {
                try
                {
                    var dataPost = new HttpRequestMessage(HttpMethod.Post, target)
                    {
                        Content = new StringContent(data, Encoding.UTF8, dataVariety)
                    };
                    dataPost.Headers.Add("millis", DateTimeOffset.UtcNow.ToUnixTimeMilliseconds().ToString());
                    using var www = await _wwwClient.SendAsync(dataPost);
                    www.EnsureSuccessStatusCode();
                    return true;
                }
                catch
                {
                }
            }

            return false;
        }

        public async ValueTask<bool> PostAvatarDrawingParallel(string target, string fileName)
        {
            if (IsEstablished)
            {
                try
                {
                    var dataPost = new HttpRequestMessage(HttpMethod.Post, target)
                    {
                        Content = new ByteArrayContent(await File.ReadAllBytesAsync(fileName))
                    };
                    dataPost.Headers.Add("millis", DateTimeOffset.UtcNow.ToUnixTimeMilliseconds().ToString());
                    dataPost.Headers.Add("totem", Totem);
                    using var www = await _wwwClient.SendAsync(dataPost);
                    www.EnsureSuccessStatusCode();
                    return true;
                }
                catch
                {
                }
            }

            return false;
        }

        public async Task<string> PostWwwParallel(string target, byte[] data)
        {
            if (IsEstablished)
            {
                try
                {
                    var dataPost = new HttpRequestMessage(HttpMethod.Post, target)
                    {
                        Content = new ByteArrayContent(data)
                    };
                    dataPost.Headers.Add("millis", DateTimeOffset.UtcNow.ToUnixTimeMilliseconds().ToString());
                    using var www = await _wwwClient.SendAsync(dataPost);
                    www.EnsureSuccessStatusCode();
                    return await www.Content.ReadAsStringAsync();
                }
                catch
                {
                }
            }

            return string.Empty;
        }

        public async Task PutAvatarParallel(string target, string avatarIntro)
        {
            if (!target.IsFrontCaselsss(QwilightComponent.TaehuiNetFE) || IsEstablished)
            {
                try
                {
                    var dataPut = new HttpRequestMessage(HttpMethod.Put, target)
                    {
                        Content = new StringContent(avatarIntro)
                    };
                    dataPut.Headers.Add("millis", DateTimeOffset.UtcNow.ToUnixTimeMilliseconds().ToString());
                    dataPut.Headers.Add("totem", Totem);
                    using var www = await _wwwClient.SendAsync(dataPut);
                    www.EnsureSuccessStatusCode();
                }
                catch
                {
                }
            }
        }

        public async Task GetDefaultNoteDate(long defaultNoteDate, bool isSilent)
        {
            var twilightWwwDefaultDate = await GetWwwParallel<JSON.TwilightWwwDefaultDate?>($"{QwilightComponent.QwilightAPI}/defaultNoteDate?date={defaultNoteDate}");
            if (twilightWwwDefaultDate.HasValue)
            {
                var date = twilightWwwDefaultDate.Value.date;
                Configure.Instance.DefaultNotesDate = date;
                if (isSilent)
                {
                    GetDefaultNote();
                }
                else
                {
                    if (StrongReferenceMessenger.Default.Send(new ViewAllowWindow
                    {
                        Text = string.Format(LanguageSystem.Instance.SaveDefaultNoteNotify, DateTimeOffset.FromUnixTimeMilliseconds(date).LocalDateTime.ToLongDateString()),
                        Data = MESSAGEBOX_STYLE.MB_YESNO | MESSAGEBOX_STYLE.MB_ICONQUESTION | MESSAGEBOX_STYLE.MB_DEFBUTTON1
                    }) == MESSAGEBOX_RESULT.IDYES)
                    {
                        GetDefaultNote();
                    }
                }

                void GetDefaultNote()
                {
                    SendParallel(Event.Types.EventID.SaveDefaultNote, Utility.GetEntry(QwilightComponent.BundleEntryPath).Select(bundleEntryPath => Path.GetFileName(bundleEntryPath)));
                    NotifySystem.Instance.Notify(NotifySystem.NotifyVariety.Info, NotifySystem.NotifyConfigure.Default, LanguageSystem.Instance.SavingDefaultNotesContents, false, null, () => ViewModels.Instance.NotifyValue.Open());
                }
            }
        }

        public async Task GetDefaultUIDate(long defaultUIDate, bool isSilent)
        {
            var twilightWwwDefaultDate = await GetWwwParallel<JSON.TwilightWwwDefaultDate?>($"{QwilightComponent.QwilightAPI}/defaultUIDate?date={defaultUIDate}");
            if (twilightWwwDefaultDate.HasValue)
            {
                var date = twilightWwwDefaultDate.Value.date;
                Configure.Instance.DefaultUIDate = date;
                if (isSilent)
                {
                    GetDefaultUI();
                }
                else
                {
                    if (StrongReferenceMessenger.Default.Send(new ViewAllowWindow
                    {
                        Text = string.Format(LanguageSystem.Instance.SaveDefaultUINotify, DateTimeOffset.FromUnixTimeMilliseconds(date).LocalDateTime.ToLongDateString()),
                        Data = MESSAGEBOX_STYLE.MB_YESNO | MESSAGEBOX_STYLE.MB_ICONQUESTION | MESSAGEBOX_STYLE.MB_DEFBUTTON1
                    }) == MESSAGEBOX_RESULT.IDYES)
                    {
                        GetDefaultUI();
                    }
                }

                void GetDefaultUI()
                {
                    SendParallel(Event.Types.EventID.SaveDefaultUi, bool.TrueString);
                    NotifySystem.Instance.Notify(NotifySystem.NotifyVariety.Info, NotifySystem.NotifyConfigure.Default, LanguageSystem.Instance.SavingDefaultUIContents, false, null, () => ViewModels.Instance.NotifyValue.Open());
                }
            }
        }
    }
}