public void UpdateUserStatistics(GameStatisticsUpdate update)
        {
            var user = this.GetUserById(update.UserId);

            user.GameCreatedCount += update.GameCreatedCount;
            user.GameJoinedCount  += update.GameJoinedCount;
            user.MapModifiedCount += update.MapModifiedCount;
            user.PostAddedCount   += update.PostAddedCount;
            user.WallAddedCount   += update.WallAddedCount;
            user.LineAddedCount   += update.LineAddedCount;

            this.UpdateUser(user);
        }
        protected override void OnWebSocketOpen()
        {
            var userToken    = JwtHelper.DecodeToken(this.Context.QueryString.Get("auth_token"));
            var gameIdString = this.Context.QueryString.Get("game_id");

            Guid gameId;

            if (userToken == null || string.IsNullOrEmpty(gameIdString) || !Guid.TryParse(gameIdString, out gameId))
            {
                this.Sessions.CloseSession(this.ID, 2000, "Invalid query parameters");
                return;
            }

            if (!this._gameManager.GameHosts.ContainsKey(gameId))
            {
                this.Sessions.CloseSession(this.ID, 2001, "This game doesn't exist");
                return;
            }

            this._gameHost   = this._gameManager.GameHosts[gameId];
            this._warsimUser = this._gameManager.GetUser(userToken.UserId);

            if (this._warsimUser == null)
            {
                this.Sessions.CloseSession(this.ID, 2002, "This user isn't connected");
                return;
            }

            var password   = this.Context.QueryString.Get("game_password");
            var playerType = this.Context.QueryString.Get("player_type");

            if (playerType == "spectator")
            {
                // Start spectating, without telling other players
                try
                {
                    this._gameHost.Spectate(this._warsimUser, password);
                }
                catch (GameException e)
                {
                    this.Sessions.CloseSession(this.ID, e.Code, e.Message);
                    return;
                }
            }
            else
            {
                try
                {
                    this._gameHost.Join(this._warsimUser, password);
                }
                catch (GameException e)
                {
                    this.Sessions.CloseSession(this.ID, e.Code, e.Message);
                    return;
                }

                var msg = new PlayerConnectedMessage
                {
                    UserId   = this._warsimUser.UserId,
                    Username = this._warsimUser.Username
                };

                this.BroadcastToCurrentGame(EventBuilder.Build(msg).Serialize());
            }

            var statsUpdate = new GameStatisticsUpdate {
                UserId = this._warsimUser.UserId
            };

            if (this.IsGameOwner())
            {
                statsUpdate.GameCreatedCount++;
            }
            else
            {
                statsUpdate.GameJoinedCount++;
            }

            new UserRepository(new ApplicationDbContext()).UpdateUserStatistics(statsUpdate);

            this._warsimUser.GameHostWebSocketId = this.ID;
            this._warsimUser.ActiveGameId        = this._gameHost.Id;
        }