private async Task ParseReply(MemoryStream message, ObsReplyObject obsReply) { message.Seek(0, SeekOrigin.Begin); if (obsReply.Status == "ok" && Enum.IsDefined(typeof(ObsRequestType), obsReply.RequestType)) { obsReply.MessageObject = await JsonSerializer.DeserializeAsync(message, ObsWsRequestReply.GetType(obsReply.RequestType)).ConfigureAwait(false); object settingsObject; ReadOnlyMemory <char> settingsJson; ObsSourceType sourceType; switch (obsReply.RequestType) { case ObsRequestType.GetAuthRequired: GetAuthRequiredReply getAuthRequiredReply = obsReply.MessageObject as GetAuthRequiredReply; CanSend = !getAuthRequiredReply.AuthRequired; if (!CanSend) { AuthenticateRequest authRequest = new AuthenticateRequest(); if (PasswordPreference == null || PasswordPreference.Length == 0) { AutoReconnect = false; OnErrorState(new Exception(rm.GetString("auth_required_no_password", CultureInfo.CurrentCulture)), -1); break; } PopulateAuthenticateRequest(ref authRequest, getAuthRequiredReply); await ObsSend(authRequest).ConfigureAwait(true); } else { await OBS_EnableHeartBeat().ConfigureAwait(true); } break; case ObsRequestType.GetSourceTypesList: foreach (ObsWsReplyType type in (obsReply.MessageObject as GetSourceTypesListReply).Types) { if (!CanDeserializeSourceType(ObsTypes.ObsTypeNameDictionary[type.TypeId], type.DefaultSettings.GetRawText().AsMemory(), out settingsObject)) { Trace.WriteLine($"Unknown source type: {type.DisplayName} ({type.TypeId}) is not defined but the server supports it."); continue; } type.DefaultSettingsObj = settingsObject; } break; case ObsRequestType.GetSourceSettings: GetJsonElementFromObjectProperty(obsReply.MessageObject, "SourceSettings", out settingsJson); if (!CanDeserializeSourceType(obsReply.SourceType, settingsJson, out settingsObject)) { break; } (obsReply.MessageObject as GetSourceSettingsReply).SourceSettingsObj = settingsObject; break; case ObsRequestType.SetSourceSettings: GetJsonElementFromObjectProperty(obsReply.MessageObject, "SourceSettings", out settingsJson); if (!CanDeserializeSourceType(obsReply.SourceType, settingsJson, out settingsObject)) { break; } (obsReply.MessageObject as SetSourceSettingsReply).SourceSettingsObj = settingsObject; break; case ObsRequestType.GetSourceFilters: foreach (ObsWsReplyFilter filter in (obsReply.MessageObject as GetSourceFiltersReply).Filters) { settingsJson = filter.Settings.GetRawText().AsMemory(); sourceType = ObsTypes.ObsTypeNameDictionary[filter.Type]; if (!CanDeserializeSourceType(sourceType, settingsJson, out settingsObject)) { continue; } filter.SettingsObj = settingsObject; } break; case ObsRequestType.GetSourceFilterInfo: GetJsonElementFromObjectProperty(obsReply.MessageObject, "Settings", out settingsJson); if (!CanDeserializeSourceType(obsReply.SourceType, settingsJson, out settingsObject)) { break; } (obsReply.MessageObject as GetSourceFilterInfoReply).SettingsObj = settingsObject; break; case ObsRequestType.Authenticate: CanSend = true; await OBS_EnableHeartBeat().ConfigureAwait(true); break; default: break; } NewObsReply(obsReply); } else if (obsReply.Status == "error") { ObsError replyModel = (ObsError)await JsonSerializer.DeserializeAsync(message, typeof(ObsError)).ConfigureAwait(false); if (obsReply.RequestType == ObsRequestType.Authenticate && !CanSend) { AutoReconnect = false; } WsClientErrorMessage errorMessage = new WsClientErrorMessage() { Error = new Exception( replyModel.Error, new Exception(String.Format(CultureInfo.CurrentCulture, Properties.Resources.exception_obs_error_format, obsReply.RequestMetadata.OriginalRequestType, obsReply.MessageId, obsReply.Status)) ), ReconnectDelay = -1 }; OnErrorState(errorMessage.Error, errorMessage.ReconnectDelay); } }
protected virtual void NewObsReply(ObsReplyObject obsReply) { OnObsReply?.Invoke(this, obsReply); }
private async Task OBS_ParseJson(MemoryStream message) { using JsonDocument document = GetJsonDocumentFromMemoryStream(message); JsonElement root = document.RootElement; JsonElement sourceType; if (root.TryGetProperty("message-id", out JsonElement messageIdJson)) { bool sentMessageGuidExists = false; ObsRequestMetadata requestMetadata = null; if (Guid.TryParse(messageIdJson.GetString(), out Guid guid)) { sentMessageGuidExists = sentMessageGuids.TryGetValue(guid, out requestMetadata); } root.TryGetProperty("status", out JsonElement statusJson); if (sentMessageGuidExists) { ObsReplyObject obsReply = new ObsReplyObject() { MessageId = guid, Status = statusJson.GetString() }; if (sentMessageGuidExists) { obsReply.RequestMetadata = requestMetadata; sentMessageGuids.Remove(guid); } if (Enum.TryParse(requestMetadata.OriginalRequestType.ToString(), out ObsRequestType reqType)) { obsReply.RequestType = reqType; } switch (obsReply.RequestType) { case ObsRequestType.GetSourceSettings: case ObsRequestType.SetSourceSettings: root.TryGetProperty("sourceType", out sourceType); obsReply.SourceType = ObsTypes.ObsTypeNameDictionary[sourceType.ToString()]; break; case ObsRequestType.GetSourceFilterInfo: root.TryGetProperty("type", out sourceType); obsReply.SourceType = ObsTypes.ObsTypeNameDictionary[sourceType.ToString()]; break; default: break; } await ParseReply(message, obsReply).ConfigureAwait(false); } else { Trace.WriteLine($"message-id {messageIdJson} received, but no matching request found."); } } else if (root.TryGetProperty("update-type", out JsonElement updateTypeJson)) { Trace.WriteLine($"Received a message of type {updateTypeJson}."); bool isStreaming = root.TryGetProperty("stream-timecode", out JsonElement jsonStreamTimecode); bool isRecording = root.TryGetProperty("rec-timecode", out JsonElement jsonRecTimecode); ObsEventObject obsEvent = new ObsEventObject(); if (Enum.TryParse(updateTypeJson.GetString(), out ObsEventType eventType)) { obsEvent.EventType = eventType; } switch (obsEvent.EventType) { case ObsEventType.SourceCreated: root.TryGetProperty("sourceKind", out sourceType); obsEvent.SourceType = ObsTypes.ObsTypeNameDictionary[sourceType.ToString()]; break; case ObsEventType.SourceFilterAdded: root.TryGetProperty("filterType", out sourceType); obsEvent.SourceType = ObsTypes.ObsTypeNameDictionary[sourceType.ToString()]; break; default: break; } await ParseEvent(message, obsEvent).ConfigureAwait(false); } else { Trace.WriteLine("Unexpected JSON."); } }