Example #1
0
            public static SpeakingEvent Prepare(CharacterData character, char letter, float duration)
            {
                var e = new SpeakingEvent();

                e.Letter    = letter;
                e.Duration  = duration;
                e.Character = character;
                return(e);
            }
Example #2
0
        private async Task ProcessMessageAsync(VoiceOpCode opCode, object payload)
        {
            _lastMessageTime = Environment.TickCount;

            try
            {
                switch (opCode)
                {
                case VoiceOpCode.Ready:
                {
                    await _audioLogger.DebugAsync("Received Ready").ConfigureAwait(false);

                    ReadyEvent data = (payload as JToken).ToObject <ReadyEvent>(_serializer);

                    _ssrc = data.SSRC;

                    if (!data.Modes.Contains(DiscordVoiceAPIClient.Mode))
                    {
                        throw new InvalidOperationException($"Discord does not support {DiscordVoiceAPIClient.Mode}");
                    }

                    ApiClient.SetUdpEndpoint(data.Ip, data.Port);
                    await ApiClient.SendDiscoveryAsync(_ssrc).ConfigureAwait(false);


                    _heartbeatTask = RunHeartbeatAsync(41250, _connection.CancelToken);
                }
                break;

                case VoiceOpCode.SessionDescription:
                {
                    await _audioLogger.DebugAsync("Received SessionDescription").ConfigureAwait(false);

                    SessionDescriptionEvent data = (payload as JToken).ToObject <SessionDescriptionEvent>(_serializer);

                    if (data.Mode != DiscordVoiceAPIClient.Mode)
                    {
                        throw new InvalidOperationException($"Discord selected an unexpected mode: {data.Mode}");
                    }

                    SecretKey   = data.SecretKey;
                    _isSpeaking = false;
                    await ApiClient.SendSetSpeaking(false).ConfigureAwait(false);

                    _keepaliveTask = RunKeepaliveAsync(5000, _connection.CancelToken);

                    Task _ = _connection.CompleteAsync();
                }
                break;

                case VoiceOpCode.HeartbeatAck:
                {
                    await _audioLogger.DebugAsync("Received HeartbeatAck").ConfigureAwait(false);

                    if (_heartbeatTimes.TryDequeue(out long time))
                    {
                        int latency = (int)(Environment.TickCount - time);
                        int before  = Latency;
                        Latency = latency;

                        await _latencyUpdatedEvent.InvokeAsync(before, latency).ConfigureAwait(false);
                    }
                }
                break;

                case VoiceOpCode.Speaking:
                {
                    await _audioLogger.DebugAsync("Received Speaking").ConfigureAwait(false);

                    SpeakingEvent data = (payload as JToken).ToObject <SpeakingEvent>(_serializer);
                    _ssrcMap[data.Ssrc] = data.UserId;         //TODO: Memory Leak: SSRCs are never cleaned up

                    await _speakingUpdatedEvent.InvokeAsync(data.UserId, data.Speaking);
                }
                break;

                default:
                    await _audioLogger.WarningAsync($"Unknown OpCode ({opCode})").ConfigureAwait(false);

                    return;
                }
            }
            catch (Exception ex)
            {
                await _audioLogger.ErrorAsync($"Error handling {opCode}", ex).ConfigureAwait(false);

                return;
            }
        }
Example #3
0
    IEnumerator DisplayDialogue(DialogueNode d)
    {
        // emit dialogue started event
        EventDispatcher.Dispatch(DialogueEvent.Prepare(d, true));

        // Find the speaking character
        speakingCharacter = DialogueManager.Instance.GetCharacter(d.Character);

        // Clear the text box
        DialogueText.text = "";

        NameText.text = d.Character.Name;

        var index = 0;

        // Get the text from the dialogue
        var rawText = d.Text;

        // Wait a frame to avoid accidentally skipping to next dialogue
        yield return(null);

        // While there's letters left to show
        while (index < rawText.Length)
        {
            if (Input.GetMouseButtonUp(0))
            {
                index = rawText.Length - 1;
            }
            // get a version of the text we can modify
            var currentText = rawText;

            if (rawText[index] == '<')
            {
                while (index < rawText.Length && rawText[index] != '>')
                {
                    index++;
                }
            }

            // Insert the alpha tag to hide text after the index
            currentText  = currentText.Insert(index + 1, "<alpha=#00>");
            currentText += "<\\alpha>";

            // Display the text
            DialogueText.text = currentText;



            // Wait for a while depending on what character we just showed
            if (Char.IsLetterOrDigit(rawText[index]))
            {
                EventDispatcher.Dispatch(SpeakingEvent.Prepare(d.Character, rawText[index], LetterDelay));
                yield return(StartCoroutine(SkippableWaitForSeconds(LetterDelay)));
            }
            else if (rawText[index] == '.')
            {
                yield return(StartCoroutine(SkippableWaitForSeconds(SentanceDelay)));
            }
            else if (rawText[index] == ' ')
            {
                yield return(StartCoroutine(SkippableWaitForSeconds(SpaceDelay)));
            }
            else
            {
                yield return(StartCoroutine(SkippableWaitForSeconds(LetterDelay)));
            }


            // Go to the next character
            index++;
        }

        // Wait a frame to avoid accidentally skipping to next dialogue
        yield return(null);

        // If we're supposed to wait for input, wait for that here
        while (d.WaitForInput && !Input.GetMouseButtonUp(0))
        {
            yield return(null);
        }

        // Emit an event saying the dialogue is over
        EventDispatcher.Dispatch(DialogueEvent.Prepare(d, false));
    }