Ejemplo n.º 1
0
        public async Task ConnectAsync(CancellationToken cancellationToken = default)
        {
            var handler = new HttpClientHandler()
            {
                CookieContainer = _cookies
            };
            var httpClient = new HttpClient(handler)
            {
                BaseAddress = _serverUri
            };
            var request = new HttpRequestMessage(HttpMethod.Get, $"/api/join?={_botInformation.DisplayName}&role=Player");
            await httpClient.SendAsync(request, cancellationToken);

            _connection.On("d", new[] { typeof(JArray) }, HandlePayloadAsync);

            // Binding this because the client crashes on unknown invocations
            _connection.On("l", new[] { typeof(JArray) }, (data) => Task.CompletedTask);
            _connection.On("mapSizeIncreased", new[] { typeof(JArray) }, data => Task.CompletedTask);
            _connection.On("disconnect", () => DisconnectAsync().Wait());

            await _connection.StartAsync(cancellationToken);

            var stateCookie = _cookies.GetCookies(_serverUri)["shootr.state"];

            var decodedValue             = WebUtility.UrlDecode(stateCookie.Value);
            var shootRState              = JsonConvert.DeserializeObject <ShootRState>(decodedValue);
            var clientInitializationData = await _connection.InvokeAsync <InitializationData>("bot_initializeClient", shootRState.RegistrationID, cancellationToken);

            _payloadDecompressor = new PayloadDecompressor(clientInitializationData);

            await _connection.InvokeAsync("bot_readyForPayloads", cancellationToken);

            _connected = true;
        }
Ejemplo n.º 2
0
        public async Task ConnectAsync(CancellationToken cancellationToken = default)
        {
            var handler = new HttpClientHandler()
            {
                CookieContainer = _cookies
            };
            var httpClient = new HttpClient(handler)
            {
                BaseAddress = _serverUri
            };
            var request = new HttpRequestMessage(HttpMethod.Get, $"/api/join?name={_botInformation.DisplayName}&role=Player&photoUrl={_botInformation.Photo}");
            await httpClient.SendAsync(request, cancellationToken);

            _connection.On("d", new[] { typeof(JArray) }, (parameters) => HandlePayloadAsync((JArray)parameters[0]));

            // Binding this because the client crashes on unknown invocations
            _connection.On <JArray>("l", (data) => { });
            _connection.On <JArray>("mapSizeIncreased", data => { });
            _connection.On("disconnect", () => DisconnectAsync().Wait());
            _connection.On <string, string, int>("chatMessage", (from, message, type) => Console.WriteLine($"{from}: {message}"));

            await _connection.StartAsync(cancellationToken);

            var stateCookie = _cookies.GetCookies(_serverUri)["shootr.state"];

            var decodedValue             = WebUtility.UrlDecode(stateCookie.Value);
            var shootRState              = JsonConvert.DeserializeObject <ShootRState>(decodedValue);
            var clientInitializationData = await _connection.InvokeAsync <InitializationData>("bot_initializeClient", shootRState.RegistrationID, cancellationToken);

            if (clientInitializationData.ServerFull)
            {
                throw new Exception("Server Full.");
            }

            _initializationData  = clientInitializationData;
            _payloadDecompressor = new PayloadDecompressor(clientInitializationData);

            await _connection.InvokeAsync("bot_readyForPayloads", cancellationToken);

            _connected = true;
        }
Ejemplo n.º 3
0
        internal async Task InternalConnectAsync()
        {
            SocketLock socketLock = null;

            try
            {
                if (this.GatewayInfo == null)
                {
                    await this.InternalUpdateGatewayAsync().ConfigureAwait(false);
                }
                await this.InitializeAsync().ConfigureAwait(false);

                socketLock = this.GetSocketLock();
                await socketLock.LockAsync().ConfigureAwait(false);
            }
            catch
            {
                socketLock?.UnlockAfter(TimeSpan.Zero);
                throw;
            }

            if (!this.Presences.ContainsKey(this.CurrentUser.Id))
            {
                this._presences[this.CurrentUser.Id] = new DiscordPresence
                {
                    Discord      = this,
                    RawActivity  = new TransportActivity(),
                    Activity     = new DiscordActivity(),
                    Status       = UserStatus.Online,
                    InternalUser = new TransportUser
                    {
                        Id            = this.CurrentUser.Id,
                        Username      = this.CurrentUser.Username,
                        Discriminator = this.CurrentUser.Discriminator,
                        AvatarHash    = this.CurrentUser.AvatarHash
                    }
                };
            }
            else
            {
                var pr = this._presences[this.CurrentUser.Id];
                pr.RawActivity = new TransportActivity();
                pr.Activity    = new DiscordActivity();
                pr.Status      = UserStatus.Online;
            }

            Volatile.Write(ref this._skippedHeartbeats, 0);

            this._webSocketClient     = this.Configuration.WebSocketClientFactory(this.Configuration.Proxy);
            this._payloadDecompressor = this.Configuration.GatewayCompressionLevel != GatewayCompressionLevel.None
                ? new PayloadDecompressor(this.Configuration.GatewayCompressionLevel)
                : null;

            this._cancelTokenSource = new CancellationTokenSource();
            this._cancelToken       = this._cancelTokenSource.Token;

            this._webSocketClient.Connected       += SocketOnConnect;
            this._webSocketClient.Disconnected    += SocketOnDisconnect;
            this._webSocketClient.MessageReceived += SocketOnMessage;
            this._webSocketClient.ExceptionThrown += SocketOnException;

            var gwuri = new QueryUriBuilder(this.GatewayUri)
                        .AddParameter("v", "6")
                        .AddParameter("encoding", "json");

            if (this.Configuration.GatewayCompressionLevel == GatewayCompressionLevel.Stream)
            {
                gwuri.AddParameter("compress", "zlib-stream");
            }

            await this._webSocketClient.ConnectAsync(gwuri.Build()).ConfigureAwait(false);

            Task SocketOnConnect(IWebSocketClient sender, SocketEventArgs e)
            => this._socketOpened.InvokeAsync(this, e);

            async Task SocketOnMessage(IWebSocketClient sender, SocketMessageEventArgs e)
            {
                MemoryStream msg = default;

                if (e is SocketTextMessageEventArgs etext)
                {
                    msg = etext.Message;
                }
                else if (e is SocketBinaryMessageEventArgs ebin) // :DDDD
                {
                    msg = new MemoryStream();
                    if (!this._payloadDecompressor.TryDecompress(new ArraySegment <byte>(ebin.Message), msg))
                    {
                        this.Logger.LogError(LoggerEvents.WebSocketReceiveFailure, "Payload decompression failed");
                        return;
                    }

                    msg.Seek(0, SeekOrigin.Begin);

                    if (this.Configuration.MinimumLogLevel == LogLevel.Trace)
                    {
                        var cs = new MemoryStream();
                        await msg.CopyToAsync(cs).ConfigureAwait(false);

                        msg.Seek(0, SeekOrigin.Begin);
                        cs.Seek(0, SeekOrigin.Begin);

                        using (var sr = new StreamReader(cs, Utilities.UTF8))
                        {
                            this.Logger.LogTrace(LoggerEvents.GatewayWsRx, await sr.ReadToEndAsync().ConfigureAwait(false));
                        }
                    }
                }

                try
                {
                    await this.HandleSocketMessageAsync(msg).ConfigureAwait(false);
                }
                catch (Exception ex)
                {
                    this.Logger.LogError(LoggerEvents.WebSocketReceiveFailure, ex, "Socket handler suppressed an exception");
                }
            }

            Task SocketOnException(IWebSocketClient sender, SocketErrorEventArgs e)
            => this._socketErrored.InvokeAsync(this, e);

            async Task SocketOnDisconnect(IWebSocketClient sender, SocketCloseEventArgs e)
            {
                // release session and connection
                this.ConnectionLock.Set();
                this.SessionLock.Set();

                if (!this._disposed)
                {
                    this._cancelTokenSource.Cancel();
                }

                this.Logger.LogDebug(LoggerEvents.ConnectionClose, "Connection closed ({0}, '{1}')", e.CloseCode, e.CloseMessage);
                await this._socketClosed.InvokeAsync(this, e).ConfigureAwait(false);



                if (this.Configuration.AutoReconnect && (e.CloseCode < 4001 || e.CloseCode >= 5000))
                {
                    this.Logger.LogCritical(LoggerEvents.ConnectionClose, "Connection terminated ({0}, '{1}'), reconnecting", e.CloseCode, e.CloseMessage);

                    if (this._status == null)
                    {
                        await this.ConnectAsync().ConfigureAwait(false);
                    }
                    else
                    if (this._status.IdleSince.HasValue)
                    {
                        await this.ConnectAsync(this._status._activity, this._status.Status, Utilities.GetDateTimeOffsetFromMilliseconds(this._status.IdleSince.Value)).ConfigureAwait(false);
                    }
                    else
                    {
                        await this.ConnectAsync(this._status._activity, this._status.Status).ConfigureAwait(false);
                    }
                }
                else
                {
                    this.Logger.LogCritical(LoggerEvents.ConnectionClose, "Connection terminated ({0}, '{1}')", e.CloseCode, e.CloseMessage);
                }
            }
        }