Example #1
0
        /// <summary>
        /// Starts a task that waits for the next rendering from Chrome.
        /// Chrome also renders the page loading, so if you want to see a complete rendering,
        /// only start this task once your page is loaded (which you can detect via FrameLoadEnd
        /// or your own heuristics based on evaluating JavaScript).
        /// It is your responsibility to dispose the returned Bitmap.
        /// The bitmap size is determined by the Size property set earlier.
        /// </summary>
        /// <param name="ignoreExistingScreenshot">Ignore existing bitmap (if any) and return the next avaliable bitmap</param>
        /// /// <param name="blend">Choose which bitmap to retrieve, choose <see cref="PopupBlending.Blend"/> for a merged bitmap.</param>
        /// <returns>Task&lt;Bitmap&gt;.</returns>
        public Task <Bitmap> ScreenshotAsync(bool ignoreExistingScreenshot = false, PopupBlending blend = PopupBlending.Main)
        {
            // Try our luck and see if there is already a screenshot, to save us creating a new thread for nothing.
            var screenshot = ScreenshotOrNull(blend);

            var completionSource = new TaskCompletionSource <Bitmap>();

            if (screenshot == null || ignoreExistingScreenshot)
            {
                EventHandler <OnPaintEventArgs> paint = null; // otherwise we cannot reference ourselves in the anonymous method below

                paint = (sender, e) =>
                {
                    // Chromium has rendered.  Tell the task about it.
                    Paint -= paint;

                    completionSource.TrySetResultAsync(ScreenshotOrNull());
                };

                Paint += paint;
            }
            else
            {
                completionSource.TrySetResultAsync(screenshot);
            }

            return(completionSource.Task);
        }
        bool ICookieVisitor.Visit(Cookie cookie, int count, int total, ref bool deleteCookie)
        {
            list.Add(cookie);

            if (count == (total - 1))
            {
                //Set the result on the ThreadPool so the Task continuation is not run on the CEF UI Thread
                taskCompletionSource.TrySetResultAsync(list);
            }

            return(true);
        }
        private void InitialLoad(bool?isLoading, CefErrorCode?errorCode)
        {
            if (IsDisposed)
            {
                initialLoadAction = null;

                initialLoadTaskCompletionSource.TrySetCanceled();

                return;
            }

            if (isLoading.HasValue)
            {
                if (isLoading.Value)
                {
                    return;
                }

                initialLoadAction = null;

                var host = browser?.GetHost();

                var navEntry = host?.GetVisibleNavigationEntry();

                int statusCode = navEntry?.HttpStatusCode ?? -1;

                //By default 0 is some sort of error, we map that to -1
                //so that it's clearer that something failed.
                if (statusCode == 0)
                {
                    statusCode = -1;
                }

                initialLoadTaskCompletionSource.TrySetResultAsync(new LoadUrlAsyncResponse(CefErrorCode.None, statusCode));
            }
            else if (errorCode.HasValue)
            {
                //Actions that trigger a download will raise an aborted error.
                //Generally speaking Aborted is safe to ignore
                if (errorCode == CefErrorCode.Aborted)
                {
                    return;
                }

                initialLoadAction = null;

                initialLoadTaskCompletionSource.TrySetResultAsync(new LoadUrlAsyncResponse(errorCode.Value, -1));
            }
        }
Example #4
0
        /// <summary>
        /// Resize the browser
        /// </summary>
        /// <param name="width">width</param>
        /// <param name="height">height</param>
        /// <param name="deviceScaleFactor">device scale factor</param>
        /// <returns>A task that can be awaited and will resolve when the desired size is achieved.</returns>
        /// <remarks>
        /// The current implementation is fairly symplistic, it simply resizes the browser
        /// and resolves the task when the browser starts painting at the desired size.
        /// </remarks>
        public Task ResizeAsync(int width, int height, float?deviceScaleFactor = null)
        {
            ThrowExceptionIfDisposed();
            ThrowExceptionIfBrowserNotInitialized();

            if (size.Width == width && size.Height == height && deviceScaleFactor == null)
            {
                return(Task.FromResult(true));
            }

            var tcs = new TaskCompletionSource <bool>();
            EventHandler <OnPaintEventArgs> handler = null;

            handler = (s, e) =>
            {
                if (e.Width == width && e.Height == height)
                {
                    AfterPaint -= handler;

                    tcs.TrySetResultAsync(true);
                }
            };

            AfterPaint += handler;

            //Only set the value if not null otherwise
            //a call to NotifyScreenInfoChanged will be made.
            if (deviceScaleFactor.HasValue)
            {
                DeviceScaleFactor = deviceScaleFactor.Value;
            }
            Size = new Size(width, height);

            return(tcs.Task);
        }
Example #5
0
        internal void Update(ClientState state, GuildSyncModel model)
        {
            var members = new ConcurrentDictionary <ulong, SocketGuildUser>(ConcurrentHashSet.DefaultConcurrencyLevel, (int)(model.Members.Length * 1.05));

            {
                for (int i = 0; i < model.Members.Length; i++)
                {
                    var member = SocketGuildUser.Create(this, state, model.Members[i]);
                    members.TryAdd(member.Id, member);
                }
                DownloadedMemberCount = members.Count;

                for (int i = 0; i < model.Presences.Length; i++)
                {
                    if (members.TryGetValue(model.Presences[i].User.Id, out SocketGuildUser member))
                    {
                        member.Update(state, model.Presences[i], true);
                    }
                }
            }
            _members = members;

            var _ = _syncPromise.TrySetResultAsync(true);

            /*if (!model.Large)
             *  _ = _downloaderPromise.TrySetResultAsync(true);*/
        }
Example #6
0
        public static Task LoadPageAsync(IWebBrowser browser, string address = null)
        {
            //If using .Net 4.6 then use TaskCreationOptions.RunContinuationsAsynchronously
            //and switch to tcs.TrySetResult below - no need for the custom extension method
            var tcs = new TaskCompletionSource <bool>();

            EventHandler <LoadingStateChangedEventArgs> handler = null;

            handler = (sender, args) =>
            {
                //Wait for while page to finish loading not just the first frame
                if (!args.IsLoading)
                {
                    browser.LoadingStateChanged -= handler;
                    //This is required when using a standard TaskCompletionSource
                    //Extension method found in the CefSharp.Internals namespace
                    tcs.TrySetResultAsync(true);
                }
            };

            browser.LoadingStateChanged += handler;

            if (!string.IsNullOrEmpty(address))
            {
                browser.Load(address);
            }
            return(tcs.Task);
        }
        /// <summary>
        /// Retrieve the current <see cref="NavigationEntry"/>. Contains information like
        /// <see cref="NavigationEntry.HttpStatusCode"/> and <see cref="NavigationEntry.SslStatus"/>
        /// </summary>
        /// <param name="browser">The ChromiumWebBrowser instance this method extends.</param>
        /// <returns>
        /// <see cref="Task{NavigationEntry}"/> that when executed returns the current <see cref="NavigationEntry"/> or null
        /// </returns>
        public static Task <NavigationEntry> GetVisibleNavigationEntryAsync(this IWebBrowser browser)
        {
            var host = browser.GetBrowserHost();

            if (host == null)
            {
                return(Task.FromResult <NavigationEntry>(null));
            }

            if (Cef.CurrentlyOnThread(CefThreadIds.TID_UI))
            {
                var entry = host.GetVisibleNavigationEntry();

                return(Task.FromResult <NavigationEntry>(entry));
            }

            var tcs = new TaskCompletionSource <NavigationEntry>();

            Cef.UIThreadTaskFactory.StartNew(delegate
            {
                var entry = host.GetVisibleNavigationEntry();

                tcs.TrySetResultAsync(entry);
            });

            return(tcs.Task);
        }
Example #8
0
        private static Task LoadHtmlAsync(IWebBrowser browser, string html, string address)
        {
            // If using .Net 4.6 then use TaskCreationOptions.RunContinuationsAsynchronously
            // and switch to tcs.TrySetResult below - no need for the custom extension method
            var tcs = new TaskCompletionSource <bool>();

            EventHandler <FrameLoadEndEventArgs> handler = null;

            handler = (sender, args) =>
            {
                browser.FrameLoadEnd -= handler;

                // This is required when using a standard TaskCompletionSource
                // Extension method found in the CefSharp.Internals namespace
                tcs.TrySetResultAsync(true);
            };

            browser.FrameLoadEnd += handler;

            if (!string.IsNullOrEmpty(address))
            {
                browser.LoadHtml(html, address);
            }

            return(tcs.Task);
        }
        static async Task <bool> LoadPageAsync(IWebBrowser browser)
        {
            // Based on https://github.com/cefsharp/CefSharp/blob/master/CefSharp.OffScreen.Example/Program.cs
            // There are two notable differences from the example, which appear to be .NET 3.5 vs. 4.6 related.
            // See the following comment for a description of these differences.

            // If using .Net 4.6 then use TaskCreationOptions.RunContinuationsAsynchronously
            // and switch to tcs.TrySetResult below - no need for the custom extension method
            TaskCompletionSource <bool> tcs = new TaskCompletionSource <bool>(false).WithTimeout(pageLoadTimeout);

            EventHandler <LoadingStateChangedEventArgs> handler = null;

            handler = (sender, args) =>
            {
                // Wait for while page to finish loading not just the first frame
                if (!args.IsLoading)
                {
                    browser.LoadingStateChanged -= handler;

                    // This is required when using a standard TaskCompletionSource
                    // Extension method found in the CefSharp.Internals namespace
                    tcs.TrySetResultAsync(true);
                }
            };

            browser.LoadingStateChanged += handler;

            return(await tcs.Task);
        }
        protected override void OnPaint(bool isPopup, Structs.Rect dirtyRect, IntPtr buffer, int width, int height)
        {
            if (isTakingScreenshot)
            {
                //We ignore the first n number of frames
                if (ignoreFrames > 0)
                {
                    ignoreFrames--;
                    return;
                }

                //Wait until we have a frame that matches the updated size we requested
                if (screenshotSize.HasValue && screenshotSize.Value.Width == width && screenshotSize.Value.Height == height)
                {
                    var stride        = width * BytesPerPixel;
                    var numberOfBytes = stride * height;

                    //Create out own memory mapped view for the screenshot and copy the buffer into it.
                    //If we were going to create a lot of screenshots then it would be better to allocate a large buffer
                    //and reuse it.
                    var mappedFile   = MemoryMappedFile.CreateNew(null, numberOfBytes, MemoryMappedFileAccess.ReadWrite);
                    var viewAccessor = mappedFile.CreateViewAccessor();

                    CopyMemory(viewAccessor.SafeMemoryMappedViewHandle.DangerousGetHandle(), buffer, (uint)numberOfBytes);

                    //Bitmaps need to be created on the UI thread
                    Dispatcher.BeginInvoke((Action)(() =>
                    {
                        var backBuffer = mappedFile.SafeMemoryMappedFileHandle.DangerousGetHandle();
                        //NOTE: Interopbitmap is not capable of supporting DPI scaling
                        var bitmap = (InteropBitmap)Imaging.CreateBitmapSourceFromMemorySection(backBuffer,
                                                                                                width, height, PixelFormats.Bgra32, stride, 0);
                        //Using TaskExtensions.TrySetResultAsync extension method so continuation runs on Threadpool
                        screenshotTaskCompletionSource.TrySetResultAsync(bitmap);

                        isTakingScreenshot = false;
                        var browserHost = GetBrowser().GetHost();
                        //Return the framerate to the previous value
                        browserHost.WindowlessFrameRate = oldFrameRate;
                        //Let the browser know the size changes so normal rendering can continue
                        browserHost.WasResized();

                        if (viewAccessor != null)
                        {
                            viewAccessor.Dispose();
                        }

                        if (mappedFile != null)
                        {
                            mappedFile.Dispose();
                        }
                    }));
                }
            }
            else
            {
                base.OnPaint(isPopup, dirtyRect, buffer, width, height);
            }
        }
        void IDisposable.Dispose()
        {
            //Set the result on the ThreadPool so the Task continuation is not run on the CEF UI Thread
            taskCompletionSource.TrySetResultAsync(list);

            list = null;
            taskCompletionSource = null;
        }
Example #12
0
        public Task <Bitmap> ScreenshotAsync(bool ignoreExistingScreenshot = false, PopupBlending blend = PopupBlending.Main)
        {
            ThrowExceptionIfDisposed();

            // Try our luck and see if there is already a screenshot, to save us creating a new thread for nothing.
            var screenshot = ScreenshotOrNull(blend);

            var completionSource = new TaskCompletionSource <Bitmap>();

            if (screenshot == null || ignoreExistingScreenshot)
            {
                EventHandler <OnPaintEventArgs> afterPaint = null; // otherwise we cannot reference ourselves in the anonymous method below

                afterPaint = (sender, e) =>
                {
                    // Chromium has rendered.  Tell the task about it.
                    AfterPaint -= afterPaint;

                    //If the user handled the Paint event then we'll throw an exception here
                    //as it's not possible to use ScreenShotAsync as the buffer wasn't updated.
                    if (e.Handled)
                    {
                        completionSource.TrySetException(new InvalidOperationException("OnPaintEventArgs.Handled = true, unable to process request. The buffer has not been updated"));
                    }
                    else
                    {
                        completionSource.TrySetResultAsync(ScreenshotOrNull(blend));
                    }
                };

                AfterPaint += afterPaint;
            }
            else
            {
                completionSource.TrySetResultAsync(screenshot);
            }

            return(completionSource.Task);
        }
Example #13
0
        public Task LoadPageAsync(IWebBrowser browser)
        {
            var tcs = new TaskCompletionSource <bool>();

            EventHandler <LoadingStateChangedEventArgs> handler = null;

            handler = (sender, args) =>
            {
                if (!args.IsLoading)
                {
                    browser.LoadingStateChanged -= handler;
                    tcs.TrySetResultAsync(true);
                }
            };

            browser.LoadingStateChanged += handler;
            return(tcs.Task);
        }
        /// <summary>
        /// Downloads the specified <paramref name="url"/> as a <see cref="byte[]"/>.
        /// Makes a GET Request.
        /// </summary>
        /// <param name="frame">valid frame</param>
        /// <param name="url">url to download</param>
        /// <returns>A task that can be awaited to get the <see cref="byte[]"/> representing the Url</returns>
        public static Task <byte[]> DownloadUrlAsync(this IFrame frame, string url)
        {
            if (!frame.IsValid)
            {
                throw new Exception("Frame is invalid, unable to continue.");
            }

            var taskCompletionSource = new TaskCompletionSource <byte[]>();

            //Can be created on any valid CEF Thread, here we'll use the CEF UI Thread
            Cef.UIThreadTaskFactory.StartNew(delegate
            {
                var request = frame.CreateRequest(false);

                request.Method = "GET";
                request.Url    = url;

                var memoryStream = new MemoryStream();

                var urlRequestClient = Fluent.UrlRequestClient
                                       .Create()
                                       .OnDownloadData((req, stream) =>
                {
                    stream.CopyTo(memoryStream);
                })
                                       .OnRequestComplete((req) =>
                {
                    if (req.RequestStatus == UrlRequestStatus.Success)
                    {
                        taskCompletionSource.TrySetResultAsync(memoryStream.ToArray());
                    }
                    else
                    {
                        taskCompletionSource.TrySetExceptionAsync(new Exception("RequestStatus:" + req.RequestStatus + ";StatusCode:" + req.Response.StatusCode));
                    }
                })
                                       .Build();

                var urlRequest = frame.CreateUrlRequest(request, urlRequestClient);
            });

            return(taskCompletionSource.Task);
        }
Example #15
0
        protected override void OnPaint(BitmapInfo bitmapInfo)
        {
            if (isTakingScreenshot)
            {
                //We ignore the first n number of frames
                if (ignoreFrames > 0)
                {
                    ignoreFrames--;
                    return;
                }

                //Wait until we have a frame that matches the updated size we requested
                if (screenshotSize.HasValue && screenshotSize.Value.Width == bitmapInfo.Width && screenshotSize.Value.Height == bitmapInfo.Height)
                {
                    //Bitmaps need to be created on the UI thread
                    Dispatcher.BeginInvoke((Action)(() =>
                    {
                        var stride = bitmapInfo.Width * bitmapInfo.BytesPerPixel;

                        lock (bitmapInfo.BitmapLock)
                        {
                            //NOTE: Interopbitmap is not capable of supporting DPI scaling
                            var bitmap = (InteropBitmap)Imaging.CreateBitmapSourceFromMemorySection(bitmapInfo.FileMappingHandle,
                                                                                                    bitmapInfo.Width, bitmapInfo.Height, PixelFormats.Bgra32, stride, 0);
                            //Using TaskExtensions.TrySetResultAsync extension method so continuation runs on Threadpool
                            screenshotTaskCompletionSource.TrySetResultAsync(bitmap);

                            isTakingScreenshot = false;
                            var browserHost = GetBrowser().GetHost();
                            //Return the framerate to the previous value
                            browserHost.WindowlessFrameRate = oldFrameRate;
                            //Let the browser know the size changes so normal rendering can continue
                            browserHost.WasResized();
                        }
                    }));
                }
            }
            else
            {
                base.OnPaint(bitmapInfo);
            }
        }
        /// <summary>
        /// Create the underlying CEF browser. The address and request context passed into the constructor
        /// will be used. If a <see cref="Action{IBrowser}"/> delegate was passed
        /// into the constructor it will not be called as this method overrides that value internally.
        /// </summary>
        /// <param name="windowInfo">Window information used when creating the browser</param>
        /// <param name="browserSettings">Browser initialization settings</param>
        /// <exception cref="System.Exception">An instance of the underlying offscreen browser has already been created, this method can only be called once.</exception>
        /// <returns>
        /// A <see cref="Task{IBrowser}"/> that represents the creation of the underlying CEF browser (<see cref="IBrowser"/> instance.
        /// When the task completes then the CEF Browser will have been created and you can start performing basic tasks.
        /// Note that the control's <see cref="BrowserInitialized"/> event will be invoked after this task completes.
        /// </returns>
        public Task <IBrowser> CreateBrowserAsync(IWindowInfo windowInfo = null, IBrowserSettings browserSettings = null)
        {
            var tcs = new TaskCompletionSource <IBrowser>();

            onAfterBrowserCreatedDelegate += new Action <IBrowser>(b =>
            {
                tcs.TrySetResultAsync(b);
            });

            try
            {
                CreateBrowser(windowInfo, browserSettings);
            }
            catch (Exception ex)
            {
                tcs.TrySetExceptionAsync(ex);
            }

            return(tcs.Task);
        }
Example #17
0
        public static void MarshalTaskResults <TResult>(this Task source, TaskCompletionSource <TResult> proxy)
        {
            switch (source.Status)
            {
            case TaskStatus.Faulted:
                proxy.TrySetExceptionAsync(source.Exception);
                break;

            case TaskStatus.Canceled:
                proxy.TrySetCanceledAsync();
                break;

            case TaskStatus.RanToCompletion:
                Task <TResult> castedSource = source as Task <TResult>;
                proxy.TrySetResultAsync(
                    castedSource == null ? default(TResult) :                 // source is a Task
                    castedSource.Result);                                     // source is a Task<TResult>
                break;
            }
        }
Example #18
0
        public static Task LoadPageAsync(IWebBrowser browser, string address = null)
        {
            var tcs = new TaskCompletionSource <bool>();
            EventHandler <LoadingStateChangedEventArgs> handler = null;

            handler = (sender, args) =>
            {
                if (!args.IsLoading)
                {
                    browser.LoadingStateChanged -= handler;
                    tcs.TrySetResultAsync(true);
                }
            };
            browser.LoadingStateChanged += handler;
            if (!string.IsNullOrEmpty(address))
            {
                browser.Load(address);
            }
            return(tcs.Task);
        }
Example #19
0
        private Task HandleAuthentication()
        {
            var tcs = new TaskCompletionSource <bool>();

            var scriptTask = _browser.EvaluateScriptAsync($"$('#cred_userid_inputtext').val('{_username}'); $('#cred_password_inputtext').val('{_password}'); $('#credentials').submit();");

            scriptTask.ContinueWith(t =>
            {
                Thread.Sleep(45000);

                // Wait for the screenshot to be taken.
                var task = _browser.ScreenshotAsync();
                task.ContinueWith(x =>
                {
                    // Make a file to save it to (e.g. C:\Users\jan\Desktop\CefSharp screenshot.png)
                    var screenshotPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "CefSharp screenshot.png");

                    Console.WriteLine();
                    Console.WriteLine("Screenshot ready. Saving to {0}", screenshotPath);

                    // Save the Bitmap to the path.
                    // The image type is auto-detected via the ".png" extension.
                    task.Result.Save(screenshotPath);

                    // We no longer need the Bitmap.
                    // Dispose it to avoid keeping the memory alive.  Especially important in 32-bit applications.
                    task.Result.Dispose();

                    Console.WriteLine("Screenshot saved.  Launching your default image viewer...");

                    // Tell Windows to launch the saved image.
                    Process.Start(screenshotPath);

                    tcs.TrySetResultAsync(true);
                });
            });
            return(tcs.Task);
        }
Example #20
0
        /// <summary>
        /// Create the underlying CEF browser. The address and request context passed into the constructor
        /// will be used. If a <see cref="Action{IBrowser}"/> delegate was passed
        /// into the constructor it will not be called as this method overrides that value internally.
        /// </summary>
        /// <param name="windowInfo">Window information used when creating the browser</param>
        /// <param name="browserSettings">Browser initialization settings</param>
        /// <exception cref="System.Exception">An instance of the underlying offscreen browser has already been created, this method can only be called once.</exception>
        /// <returns>
        /// A <see cref="Task{IBrowser}"/> that represents the creation of the underlying CEF browser (<see cref="IBrowser"/> instance.
        /// When the task completes then the CEF Browser will have been created and you can start performing basic tasks.
        /// Note that the control's <see cref="BrowserInitialized"/> event will be invoked after this task completes.
        /// </returns>
        public Task <IBrowser> CreateBrowserAsync(IWindowInfo windowInfo = null, IBrowserSettings browserSettings = null)
        {
            if (browserCreated)
            {
                throw new Exception("An instance of the underlying offscreen browser has already been created, this method can only be called once.");
            }

            browserCreated = true;

            if (browserSettings == null)
            {
                browserSettings = Core.ObjectFactory.CreateBrowserSettings(autoDispose: true);
            }

            if (windowInfo == null)
            {
                windowInfo = Core.ObjectFactory.CreateWindowInfo();
                windowInfo.SetAsWindowless(IntPtr.Zero);
            }

            var tcs = new TaskCompletionSource <IBrowser>();

            onAfterBrowserCreatedDelegate = new Action <IBrowser>(b =>
            {
                tcs.TrySetResultAsync(b);
            });

            managedCefBrowserAdapter.CreateBrowser(windowInfo, browserSettings, RequestContext, Address);

            //Dispose of BrowserSettings if we created it, if user created then they're responsible
            if (browserSettings.AutoDispose)
            {
                browserSettings.Dispose();
            }
            browserSettings = null;

            return(tcs.Task);
        }
Example #21
0
        private Task LoadPageAsync(string address = null)
        {
            var tcs = new TaskCompletionSource <bool>();

            EventHandler <LoadingStateChangedEventArgs> handler = null;

            handler = (sender, args) =>
            {
                //Wait for while page to finish loading not just the first frame
                if (!args.IsLoading)
                {
                    _browser.LoadingStateChanged -= handler;
                    tcs.TrySetResultAsync(true);
                }
            };

            _browser.LoadingStateChanged += handler;

            if (!string.IsNullOrEmpty(address))
            {
                _browser.Load(address);
            }
            return(tcs.Task);
        }
Example #22
0
        private async Task ProcessMessageAsync(VoiceOpCode opCode, object payload)
        {
#if BENCHMARK
            Stopwatch stopwatch = Stopwatch.StartNew();
            try
            {
#endif
            try
            {
                switch (opCode)
                {
                case VoiceOpCode.Ready:
                {
                    await _audioLogger.DebugAsync("Received Ready").ConfigureAwait(false);

                    var 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}");
                    }

                    _heartbeatTime = 0;
                    _heartbeatTask = RunHeartbeatAsync(data.HeartbeatInterval, _cancelToken.Token);

                    var entry = await Dns.GetHostEntryAsync(_url).ConfigureAwait(false);

                    ApiClient.SetUdpEndpoint(new IPEndPoint(entry.AddressList[0], data.Port));
                    await ApiClient.SendDiscoveryAsync(_ssrc).ConfigureAwait(false);
                }
                break;

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

                    var 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;
                    await ApiClient.SendSetSpeaking(true).ConfigureAwait(false);

                    var _ = _connectTask.TrySetResultAsync(true);
                }
                break;

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

                    var heartbeatTime = _heartbeatTime;
                    if (heartbeatTime != 0)
                    {
                        int latency = (int)(Environment.TickCount - _heartbeatTime);
                        _heartbeatTime = 0;

                        int before = Latency;
                        Latency = latency;

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

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

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

                return;
            }
#if BENCHMARK
        }

        finally
        {
            stopwatch.Stop();
            double millis = Math.Round(stopwatch.ElapsedTicks / (double)Stopwatch.Frequency * 1000.0, 2);
            await _benchmarkLogger.DebugAsync($"{millis} ms").ConfigureAwait(false);
        }
#endif
        }
Example #23
0
        internal async Task <IAudioClient> ConnectAudioAsync(ulong channelId, bool selfDeaf, bool selfMute, bool external)
        {
            TaskCompletionSource <AudioClient> promise;

            await _audioLock.WaitAsync().ConfigureAwait(false);

            try
            {
                await DisconnectAudioInternalAsync().ConfigureAwait(false);

                promise = new TaskCompletionSource <AudioClient>();
                _audioConnectPromise = promise;

                if (external)
                {
                    var _ = promise.TrySetResultAsync(null);
                    await Discord.ApiClient.SendVoiceStateUpdateAsync(Id, channelId, selfDeaf, selfMute).ConfigureAwait(false);

                    return(null);
                }

                if (_audioClient == null)
                {
                    var audioClient = new AudioClient(this, Discord.GetAudioId(), channelId);
                    audioClient.Disconnected += async ex =>
                    {
                        if (!promise.Task.IsCompleted)
                        {
                            try
                            { audioClient.Dispose(); }
                            catch { }
                            _audioClient = null;
                            if (ex != null)
                            {
                                await promise.TrySetExceptionAsync(ex);
                            }
                            else
                            {
                                await promise.TrySetCanceledAsync();
                            }
                            return;
                        }
                    };
                    audioClient.Connected += () =>
                    {
                        var _ = promise.TrySetResultAsync(_audioClient);
                        return(Task.Delay(0));
                    };
                    _audioClient = audioClient;
                }

                await Discord.ApiClient.SendVoiceStateUpdateAsync(Id, channelId, selfDeaf, selfMute).ConfigureAwait(false);
            }
            catch (Exception)
            {
                await DisconnectAudioInternalAsync().ConfigureAwait(false);

                throw;
            }
            finally
            {
                _audioLock.Release();
            }

            try
            {
                var timeoutTask = Task.Delay(15000);
                if (await Task.WhenAny(promise.Task, timeoutTask) == timeoutTask)
                {
                    throw new TimeoutException();
                }
                return(await promise.Task.ConfigureAwait(false));
            }
            catch (Exception)
            {
                await DisconnectAudioAsync().ConfigureAwait(false);

                throw;
            }
        }
Example #24
0
        internal void Update(ClientState state, ExtendedModel model)
        {
            IsAvailable = !(model.Unavailable ?? false);
            if (!IsAvailable)
            {
                if (_channels == null)
                {
                    _channels = new ConcurrentHashSet <ulong>();
                }
                if (_members == null)
                {
                    _members = new ConcurrentDictionary <ulong, SocketGuildUser>();
                }
                if (_roles == null)
                {
                    _roles = new ConcurrentDictionary <ulong, SocketRole>();
                }

                /*if (Emojis == null)
                 *  _emojis = ImmutableArray.Create<Emoji>();
                 * if (Features == null)
                 *  _features = ImmutableArray.Create<string>();*/
                _syncPromise       = new TaskCompletionSource <bool>();
                _downloaderPromise = new TaskCompletionSource <bool>();
                return;
            }

            Update(state, model as Model);

            var channels = new ConcurrentHashSet <ulong>(ConcurrentHashSet.DefaultConcurrencyLevel, (int)(model.Channels.Length * 1.05));

            {
                for (int i = 0; i < model.Channels.Length; i++)
                {
                    var channel = SocketGuildChannel.Create(this, state, model.Channels[i]);
                    state.AddChannel(channel);
                    channels.TryAdd(channel.Id);
                }
            }
            _channels = channels;

            var members = new ConcurrentDictionary <ulong, SocketGuildUser>(ConcurrentHashSet.DefaultConcurrencyLevel, (int)(model.Members.Length * 1.05));

            {
                for (int i = 0; i < model.Members.Length; i++)
                {
                    var member = SocketGuildUser.Create(this, state, model.Members[i]);
                    members.TryAdd(member.Id, member);
                }
                DownloadedMemberCount = members.Count;

                for (int i = 0; i < model.Presences.Length; i++)
                {
                    if (members.TryGetValue(model.Presences[i].User.Id, out SocketGuildUser member))
                    {
                        member.Update(state, model.Presences[i], true);
                    }
                }
            }
            _members    = members;
            MemberCount = model.MemberCount;

            var voiceStates = new ConcurrentDictionary <ulong, SocketVoiceState>(ConcurrentHashSet.DefaultConcurrencyLevel, (int)(model.VoiceStates.Length * 1.05));

            {
                for (int i = 0; i < model.VoiceStates.Length; i++)
                {
                    SocketVoiceChannel channel = null;
                    if (model.VoiceStates[i].ChannelId.HasValue)
                    {
                        channel = state.GetChannel(model.VoiceStates[i].ChannelId.Value) as SocketVoiceChannel;
                    }
                    var voiceState = SocketVoiceState.Create(channel, model.VoiceStates[i]);
                    voiceStates.TryAdd(model.VoiceStates[i].UserId, voiceState);
                }
            }
            _voiceStates = voiceStates;

            _syncPromise       = new TaskCompletionSource <bool>();
            _downloaderPromise = new TaskCompletionSource <bool>();
            var _ = _syncPromise.TrySetResultAsync(true);

            /*if (!model.Large)
             *  _ = _downloaderPromise.TrySetResultAsync(true);*/
        }
Example #25
0
 void IDeleteCookiesCallback.OnComplete(int numDeleted)
 {
     taskCompletionSource.TrySetResultAsync(numDeleted);
 }
Example #26
0
 public void OnComplete()
 {
     taskCompletionSource.TrySetResultAsync(true);
 }
Example #27
0
        public static Task LoadPageAsync(IWebBrowser browser, string address = null)
        {
            //If using .Net 4.6 then use TaskCreationOptions.RunContinuationsAsynchronously
            //and switch to tcs.TrySetResult below - no need for the custom extension method
            var tcs = new TaskCompletionSource<bool>();

            EventHandler<LoadingStateChangedEventArgs> handler = null;
            handler = (sender, args) =>
            {
                //Wait for while page to finish loading not just the first frame
                if (!args.IsLoading)
                {
                    browser.LoadingStateChanged -= handler;
                    //This is required when using a standard TaskCompletionSource
                    //Extension method found in the CefSharp.Internals namespace
                    tcs.TrySetResultAsync(true);
                }
            };

            browser.LoadingStateChanged += handler;

            if (!string.IsNullOrEmpty(address))
            {
                browser.Load(address);
            }
            return tcs.Task;
        }
        private bool complete; //Only ever accessed on the same CEF thread, so no need for thread safety

        void IResolveCallback.OnResolveCompleted(CefErrorCode result, IList <string> resolvedIpAddresses)
        {
            complete = true;

            taskCompletionSource.TrySetResultAsync(new ResolveCallbackResult(result, resolvedIpAddresses));
        }
Example #29
0
        public static Task LoadPageAsync(IWebBrowser browser, string address = null)
        {
            var tcs = new TaskCompletionSource<bool>();

            EventHandler<LoadingStateChangedEventArgs> handler = null;
            handler = (sender, args) =>
            {
                //Wait for while page to finish loading not just the first frame
                if (!args.IsLoading)
                {
                    browser.LoadingStateChanged -= handler;
                    tcs.TrySetResultAsync(true);
                }
            };

            browser.LoadingStateChanged += handler;

            if (!string.IsNullOrEmpty(address))
            {
                browser.Load(address);
            }
            return tcs.Task;
        }
Example #30
0
        /// <summary>
        /// Starts a task that waits for the next rendering from Chrome.
        /// Chrome also renders the page loading, so if you want to see a complete rendering,
        /// only start this task once your page is loaded (which you can detect via FrameLoadEnd
        /// or your own heuristics based on evaluating JavaScript).
        /// It is your responsibility to dispose the returned Bitmap.
        /// The bitmap size is determined by the Size property set earlier.
        /// </summary>
        /// <param name="ignoreExistingScreenshot">Ignore existing bitmap (if any) and return the next avaliable bitmap</param>
        /// /// <param name="blend">Choose which bitmap to retrieve, choose <see cref="PopupBlending.Blend"/> for a merged bitmap.</param>
        /// <returns>Task&lt;Bitmap&gt;.</returns>
        public Task<Bitmap> ScreenshotAsync(bool ignoreExistingScreenshot = false, PopupBlending blend = PopupBlending.Main)
        {
            // Try our luck and see if there is already a screenshot, to save us creating a new thread for nothing.
            var screenshot = ScreenshotOrNull(blend);

            var completionSource = new TaskCompletionSource<Bitmap>();

            if (screenshot == null || ignoreExistingScreenshot)
            {
                EventHandler newScreenshot = null; // otherwise we cannot reference ourselves in the anonymous method below

                newScreenshot = (sender, e) =>
                {
                    // Chromium has rendered.  Tell the task about it.
                    NewScreenshot -= newScreenshot;

                    completionSource.TrySetResultAsync(ScreenshotOrNull());
                };

                NewScreenshot += newScreenshot;
            }
            else
            {
                completionSource.TrySetResultAsync(screenshot);
            }

            return completionSource.Task;
        }
        void ICompletionCallback.OnComplete()
        {
            onComplete = true;

            taskCompletionSource.TrySetResultAsync(true);
        }
        void IGetGeolocationCallback.OnLocationUpdate(Geoposition position)
        {
            taskCompletionSource.TrySetResultAsync(position);

            hasData = true;
        }
Example #33
0
        void IPrintToPdfCallback.OnPdfPrintFinished(string path, bool ok)
        {
            complete = true;

            taskCompletionSource.TrySetResultAsync(ok);
        }