protected async Task HandleExitingAsync(IReference refback) { var styles = new Dictionary <string, object> { { "height", $"{CollapsedHeight}px" }, { "transition-duration", $"{GetExitDuration()}ms" } }; await DomHelpers.SetStyleAsync(refback.Current, styles, trigger : true); OnExiting?.Invoke(refback); }
protected async Task PerformExit() { if (!(Exit.HasValue && Exit.Value)) { Current = TransitionState.Exited; // TODO: need to check Next = TransitionState.None; await LocalStateHasChanged(); await(OnExited?.Invoke(RefBack) ?? Task.CompletedTask); return; } Current = TransitionState.Exit; await LocalStateHasChanged(); await(OnExit?.Invoke(RefBack) ?? Task.CompletedTask); Current = TransitionState.Exiting; await LocalStateHasChanged(); await(OnExiting?.Invoke(RefBack) ?? Task.CompletedTask); await OnTransitionEnd(async() => { Current = UnmountOnExit ? TransitionState.Unmounted : TransitionState.Exited; // TODO: need to check Next = TransitionState.None; await LocalStateHasChanged(force: UnmountOnExit); await(OnExited?.Invoke(RefBack) ?? Task.CompletedTask); }, TimeoutExit); }
protected virtual async Task FireExiting(IExitContext context) { await OnExiting.InvokeAsync(context); }
protected void HandleExiting(IReference refback) { OnExiting?.Invoke(refback); }
internal static void Exiting() => OnExiting?.Invoke();
private void Exiting(object sender, System.EventArgs args) { OnExiting?.Invoke(); }
protected virtual void RaiseEvent(JObject message) { switch (message["update-type"].ToObject <string>()) { case "SwitchScenes": List <SceneItem> sources = new List <SceneItem>(); foreach (JObject source in message["sources"]) { sources.Add(new SceneItem() { alignment = source["alignment"].ToObject <int>(), cx = source["cx"].ToObject <double>(), x = source["x"].ToObject <double>(), cy = source["cy"].ToObject <double>(), y = source["y"].ToObject <double>(), volume = source["volume"].ToObject <double>(), locked = source["locked"].ToObject <bool>(), name = source["name"].ToObject <string>(), type = source["type"].ToObject <string>(), id = source["id"].ToObject <int>(), render = source["render"].ToObject <bool>(), muted = source["muted"].ToObject <bool>(), source_cx = source["source_cx"].ToObject <int>(), source_cy = source["source_cy"].ToObject <int>() }); } OnSceneSwitched?.Invoke(this, new SceneSwitchedEventArgs() { newSceneName = message["scene-name"].ToObject <string>(), sources = sources.ToArray() }); break; case "ScenesChanged": OnScenesChanged?.Invoke(this, new OBSEventArgs()); break; case "SceneCollectionChanged": OnSceneCollectionChanged?.Invoke(this, new OBSEventArgs()); break; case "SceneCollectionListChanged": OnSceneCollectionListChanged?.Invoke(this, new OBSEventArgs()); break; case "SwitchTransition": OnSwitchTransition?.Invoke(this, new SwitchTransitionEventArgs() { transitionName = message["transition-name"].ToObject <string>() }); break; case "TransitionListChanged": OnTransitionListChanged?.Invoke(this, new OBSEventArgs()); break; case "TransitionDurationChanged": OnTransitionDurationChanged?.Invoke(this, new TransitionDurationChangedEventArgs() { newDuration = message["new-duration"].ToObject <int>() }); break; case "TransitionBegin": OnTransitionBegin?.Invoke(this, new TransitionBeginEventArgs() { duration = message["duration"].ToObject <int>(), fromScene = message["from-scene"].ToObject <string>(), toScene = message["to-scene"].ToObject <string>(), name = message["name"].ToObject <string>(), type = message["type"].ToObject <string>() }); break; case "TransitionEnd": OnTransitionEnd?.Invoke(this, new TransitionEndEventArgs() { duration = message["duration"].ToObject <int>(), toScene = message["to-scene"].ToObject <string>(), name = message["name"].ToObject <string>(), type = message["type"].ToObject <string>() }); break; case "TransitionVideoEnd": OnTransitionVideoEnd?.Invoke(this, new TransitionVideoEndEventArgs() { duration = message["duration"].ToObject <int>(), fromScene = message["from-scene"].ToObject <string>(), toScene = message["to-scene"].ToObject <string>(), name = message["name"].ToObject <string>(), type = message["type"].ToObject <string>() }); break; case "ProfileChanged": OnProfileChanged?.Invoke(this, new OBSEventArgs()); break; case "ProfileListChanged": OnProfileListChanged?.Invoke(this, new OBSEventArgs()); break; case "StreamStarting": OnStreamStarting?.Invoke(this, new OBSEventArgs()); break; case "StreamStarted": OnStreamStarted?.Invoke(this, new OBSEventArgs()); break; case "StreamStopping": OnStreamStopping?.Invoke(this, new OBSEventArgs()); break; case "StreamStopped": OnStreamStopped?.Invoke(this, new OBSEventArgs()); break; case "StreamStatus": OnStreamStatusUpdate?.Invoke(this, new StreamStatusUpdateEventArgs() { recording = message["recording"].ToObject <bool>(), recordingPaused = message["recording-paused"].ToObject <bool>(), replayBufferActive = message["replay-buffer-active"].ToObject <bool>(), streaming = message["streaming"].ToObject <bool>(), bytesPerSec = message["bytes-per-sec"].ToObject <int>(), kbitsPerSec = message["kbits-per-sec"].ToObject <int>(), totalStreamTime = message["total-stream-time"].ToObject <int>(), numTotalFrames = message["num-total-frames"].ToObject <int>(), numDroppedFrames = message["num-dropped-frames"].ToObject <int>(), renderTotalFrames = message["render-total-frames"].ToObject <int>(), renderMissedFrames = message["render-missed-frames"].ToObject <int>(), outputTotalFrames = message["output-total-frames"].ToObject <int>(), outputSkippedFrames = message["output-skipped-frames"].ToObject <int>(), strain = message["strain"].ToObject <double>(), fps = message["fps"].ToObject <double>(), averageFrameTime = message["average-frame-time"].ToObject <double>(), cpuUsage = message["cpu-usage"].ToObject <double>(), memoryUsage = message["memory-usage"].ToObject <double>(), freeDiskSpace = message["free-disk-space"].ToObject <double>() }); break; case "RecordingStarting": OnRecordingStarting?.Invoke(this, new OBSEventArgs()); break; case "RecordingStarted": OnRecordingStarted?.Invoke(this, new OBSEventArgs()); break; case "RecordingStopping": OnRecordingStopping?.Invoke(this, new OBSEventArgs()); break; case "RecordingStopped": OnRecordingStopped?.Invoke(this, new OBSEventArgs()); break; case "RecordingPaused": OnRecordingPaused?.Invoke(this, new OBSEventArgs()); break; case "RecordingResumed": OnRecordingResumed?.Invoke(this, new OBSEventArgs()); break; case "ReplayStarting": OnReplayStarting?.Invoke(this, new OBSEventArgs()); break; case "ReplayStarted": OnReplayStarted?.Invoke(this, new OBSEventArgs()); break; case "ReplayStopping": OnReplayStopping?.Invoke(this, new OBSEventArgs()); break; case "ReplayStopped": OnReplayStopped?.Invoke(this, new OBSEventArgs()); break; case "Exiting": OnExiting?.Invoke(this, new OBSEventArgs()); break; case "Heartbeat": OnHeartbeat?.Invoke(this, new HeartbeatEventArgs() { pulse = message["pulse"].ToObject <bool>(), streaming = message.ContainsKey("streaming") ? message["streaming"].ToObject <bool>() : false, recording = message.ContainsKey("recording") ? message["recording"].ToObject <bool>() : false, currentProfile = message.ContainsKey("current-profile") ? message["current-profile"].ToObject <string>() : string.Empty, currentScene = message.ContainsKey("current-scene") ? message["current-scene"].ToObject <string>() : string.Empty, totalStreamTime = message.ContainsKey("total-stream-time") ? message["total-stream-time"].ToObject <int>() : 0, totalStreamBytes = message.ContainsKey("total-stream-bytes") ? message["total-stream-bytes"].ToObject <int>() : 0, totalStreamFrames = message.ContainsKey("total-stream-frames") ? message["total-stream-frames"].ToObject <int>() : 0, totalRecordTime = message.ContainsKey("total-record-time") ? message["total-record-time"].ToObject <int>() : 0, totalRecordBytes = message.ContainsKey("total-record-bytes") ? message["total-record-bytes"].ToObject <int>() : 0, totalRecordFrames = message.ContainsKey("total-record-frames") ? message["total-record-frames"].ToObject <int>() : 0, stats = message.ContainsKey("stats") ? (new OBSStats() { fps = message["stats"]["fps"].ToObject <double>(), averageframetime = message["stats"]["average-frame-time"].ToObject <double>(), cpuusage = message["stats"]["cpu-usage"].ToObject <double>(), memoryusage = message["stats"]["memory-usage"].ToObject <double>(), freediskspace = message["stats"]["free-disk-space"].ToObject <double>(), rendertotalframes = message["stats"]["render-total-frames"].ToObject <int>(), rendermissedframes = message["stats"]["render-missed-frames"].ToObject <int>(), outputtotalframes = message["stats"]["output-total-frames"].ToObject <int>(), outputskippedframes = message["stats"]["output-skipped-frames"].ToObject <int>() }) : new OBSStats() }); break; case "SourceCreated": OnSourceCreated?.Invoke(this, new SourceEventArgs() { sourceName = message["sourceName"].ToObject <string>(), sourceType = message["sourceType"].ToObject <string>(), sourceKind = message["sourceKind"].ToObject <string>() }); break; case "SourceDestroyed": OnSourceDestroyed?.Invoke(this, new SourceEventArgs() { sourceName = message["sourceName"].ToObject <string>(), sourceType = message["sourceType"].ToObject <string>(), sourceKind = message["sourceKind"].ToObject <string>() }); break; case "SourceVolumeChanged": OnSourceVolumeChanged?.Invoke(this, new SourceVolumeChangedEventArgs() { sourcename = message["sourceName"].ToObject <string>(), sourcevolume = Convert.ToSingle(message["volume"].ToObject <string>()) }); break; case "SourceMuteStateChanged": OnSourceMuteChanged?.Invoke(this, new SourceMuteChangedEventArgs() { sourceName = message["sourceName"].ToObject <string>(), muted = message["muted"].ToObject <bool>() }); break; case "SourceAudioSyncOffsetChanged": OnSourceAudioSyncOffsetChanged?.Invoke(this, new SourceAudioSyncOffsetChangedArgs() { sourceName = message["sourceName"].ToObject <string>(), syncOffset = message["syncOffset"].ToObject <int>() }); break; case "SourceAudioMixersChanged": List <Mixer> mixerlist = new List <Mixer>(); foreach (JObject mixer in message["mixers"]) { mixerlist.Add(new Mixer() { id = mixer["id"].ToObject <int>(), enabled = mixer["enabled"].ToObject <bool>() }); } OnSourceAudioMixersChanged?.Invoke(this, new SourceAudioMixersChangedArgs() { sourceName = message["sourceName"].ToObject <string>(), hexMixersValue = message["hexMixersValue"].ToObject <string>(), mixers = mixerlist.ToArray() }); break; case "SourceRenamed": OnSourceRenamed?.Invoke(this, new SourceRenamedEventArgs() { previousName = message["previousName"].ToObject <string>(), newName = message["newName"].ToObject <string>() }); break; case "SourceFilterAdded": OnSourceFilterAdded?.Invoke(this, new SourceFilterEventArgs() { filterName = message["filterName"].ToObject <string>(), sourceName = message["sourceName"].ToObject <string>(), filterType = message["filterType"].ToObject <string>() }); break; case "SourceFilterRemoved": OnSourceFilterAdded?.Invoke(this, new SourceFilterEventArgs() { filterName = message["filterName"].ToObject <string>(), sourceName = message["sourceName"].ToObject <string>(), filterType = message["filterType"].ToObject <string>() }); break; case "SourceFilterVisibilityChanged": OnSourceFilterVisibilityChanged?.Invoke(this, new SourceFilterVisibilityChangedEventArgs() { filterName = message["filterName"].ToObject <string>(), sourceName = message["sourceName"].ToObject <string>(), filterEnabled = message["filterEnabled"].ToObject <bool>() }); break; case "SourceFiltersReordered": List <Filter> filterlist = new List <Filter>(); foreach (JObject filter in message["filters"]) { filterlist.Add(new Filter() { name = filter["name"].ToObject <string>(), type = filter["type"].ToObject <string>() }); } OnSourceFiltersReordered?.Invoke(this, new SourceFiltersReorderedEventArgs() { sourceName = message["sourceName"].ToObject <string>(), filters = filterlist.ToArray() }); break; case "SceneItemAdded": OnSceneItemAdded?.Invoke(this, new SceneItemEventArgs() { sceneName = message["scene-name"].ToObject <string>(), itemName = message["item-name"].ToObject <string>(), itemId = message["item-id"].ToObject <int>() }); break; case "SceneItemRemoved": OnSceneItemRemoved?.Invoke(this, new SceneItemEventArgs() { sceneName = message["scene-name"].ToObject <string>(), itemName = message["item-name"].ToObject <string>(), itemId = message["item-id"].ToObject <int>() }); break; case "SceneItemVisibilityChanged": OnSceneItemVisibilityChanged?.Invoke(this, new SceneItemVisibilityChangedEventArgs() { sceneName = message["scene-name"].ToObject <string>(), itemName = message["item-name"].ToObject <string>(), itemId = message["item-id"].ToObject <int>(), itemVisible = message["item-visible"].ToObject <bool>() }); break; case "SceneItemLockChanged": OnSceneItemLockChanged?.Invoke(this, new SceneItemLockChangedEventArgs() { sceneName = message["scene-name"].ToObject <string>(), itemName = message["item-name"].ToObject <string>(), itemId = message["item-id"].ToObject <int>(), itemLocked = message["item-locked"].ToObject <bool>() }); break; case "StudioModeSwitched": OnStudioModeSwitched?.Invoke(this, new StudioModeSwitchedEventArgs() { newState = message["new-state"].ToObject <bool>() }); break; default: this.OnOBSWebsocketInfo?.Invoke(this, new OBSWebsocketEventArgs() { text = string.Format("Event not implemented: {0}", (string)message["update-type"]) }); break; } }
static void Main(string[] args) { //RC-Channel-ID 30773965 //ChatRoom 1a1bd140-55b3-4a63-815c-077b094ffba1 try { ///Load bot configuration Config = new BotConfiguration(Storage = new WindowsStorage("FoxBot")); Channel = Config.GetBindable <string>(BotSetting.Channel); ChatBotChannel = Config.GetBindable <string>(BotSetting.BotChatRoom); ///Set log folder Logger.Storage = Storage.GetStorageForDirectory("logs"); ///Create if not exist Directory.CreateDirectory("./Modues"); ///Create client instance client = new IrcClient() { //Username = Nick, //AuthToken = ServerPass, }; ///Initialize command service commands = new CommandService(new CommandServiceConfig() { CaseSensitiveCommands = false, DefaultRunMode = RunMode.Sync, }); ///Create form instance Form = new DialogWindow(); ///------------------------------================= bool interrupt = false; ///Modules update thread. Please, use async func for long timed work in case not blocking other modules Thread updateThread = new Thread(() => { while (!interrupt) { ///update if (DateTimeOffset.Now > GetUserListTimout) { var req = new JsonWebRequest <ChatData>($"https://tmi.twitch.tv/group/user/{Channel.Value.Replace("#", "")}/chatters"); req.Finished += () => { DialogWindow.UpdateChattersList(req.ResponseObject); if (BotEntry.ChannelsChatters.ContainsKey(BotEntry.Channel)) { BotEntry.ChannelsChatters[BotEntry.Channel] = req.ResponseObject.chatters; } else { BotEntry.ChannelsChatters.Add(BotEntry.Channel, req.ResponseObject.chatters); } }; ///In case not block current thread req.PerformAsync(); GetUserListTimout = GetUserListTimout.AddMinutes(5); } OnTickActions?.Invoke(); Thread.Sleep(50); } }); ///Load dust data using (var file = new StreamReader(Storage.GetStream($"Dust/{BotEntry.Channel}#RedstoneData.json", FileAccess.ReadWrite))) { if (!file.EndOfStream) { BotEntry.RedstoneDust = JsonConvert.DeserializeObject <SortedDictionary <string, RedstoneData> >(file.ReadToEnd()); } if (BotEntry.RedstoneDust == null) { BotEntry.RedstoneDust = new SortedDictionary <string, RedstoneData> { } } ; } ///Start update thread updateThread.Start(); ///Load some configs in form Form.Load(Storage); services = new ServiceCollection() .AddSingleton(client) .AddSingleton(commands) .AddSingleton(Form) .BuildServiceProvider(); client.ChannelMessage += HandleMessage; client.OnConnect += Client_OnConnect; commands.AddModulesAsync(Assembly.GetEntryAssembly(), services); ///Try load all module in /Modules folder var dll = Directory.GetFiles(Directory.GetCurrentDirectory() + "\\Modues", "*.dll", SearchOption.TopDirectoryOnly); foreach (var it in dll) { try { Logger.Log($"Loading {it} module..."); commands.AddModulesAsync(Assembly.LoadFile(it), services); } catch { continue; } } ///Load items metadata foreach (var data in RedstoneDust) { data.Value.ReadJsonData(); } PostInit?.Invoke(); ///Run form Application.Run(Form); ///Save any config changes inside form Logger.Log($"Unloading form data..."); Form.Unload(Storage); ///Interrupt a thread interrupt = true; Thread.Sleep(1000); ///Unload all data and exit Logger.Log($"====================UNLOADING SERVICES====================="); OnExiting?.Invoke(); client.Disconnect(); ///Commands.CommandsService.Unload(Storage); Logger.Log($"=================UNLOADING SERVICES ENDED=================="); ///Prepare item metadata to unloading foreach (var data in RedstoneDust) { data.Value.PrepareJsonData(); } ///Unload dust data using (var file = new StreamWriter(Storage.GetStream($"Dust/{BotEntry.Channel}#RedstoneData.json", FileAccess.ReadWrite, FileMode.Truncate))) { file.Write(JsonConvert.SerializeObject(BotEntry.RedstoneDust, Formatting.Indented)); } Thread.Sleep(1000); } catch (Exception e) { Logger.GetLogger(LoggingTarget.Stacktrace).Add($"FATAL ERROR: {e.Message}. SEE STACKTRACE FOR DETAIL"); Logger.GetLogger(LoggingTarget.Stacktrace).Add(e.StackTrace); Thread.Sleep(50); foreach (var data in RedstoneDust) { data.Value.PrepareJsonData(); } using (var file = new StreamWriter(Storage.GetStream($"Dust/{BotEntry.Channel}#RedstoneData.json", FileAccess.ReadWrite, FileMode.Truncate))) { file.Write(JsonConvert.SerializeObject(BotEntry.RedstoneDust, Formatting.Indented)); } } }