protected override async Task <Result> InitializeInternal()
        {
            this.cancellationTokenSource = new CancellationTokenSource();

            this.startTime = DateTimeOffset.Now;

            this.user = await this.GetCurrentAccount();

            if (this.user != null)
            {
                if (!string.IsNullOrEmpty(ChannelSession.Settings.JustGivingPageShortName))
                {
                    IEnumerable <JustGivingFundraiser> fundraisers = await this.GetCurrentFundraisers();

                    this.fundraiser = fundraisers.FirstOrDefault(f => f.pageShortName.Equals(ChannelSession.Settings.JustGivingPageShortName));
                }

                AsyncRunner.RunBackgroundTask(this.cancellationTokenSource.Token, 60000, this.BackgroundDonationCheck);
                this.TrackServiceTelemetry("JustGiving");
                return(new Result());
            }
            return(new Result("Unable to get User data"));
        }
Exemple #2
0
        public async Task PerformTradeCommand(UserViewModel user, IEnumerable <string> arguments = null, StreamingPlatformTypeEnum platform = StreamingPlatformTypeEnum.None)
        {
            try
            {
                if (ChannelSession.Services.Chat != null && arguments != null)
                {
                    if (this.tradeReceiver == null && arguments.Count() >= 2)
                    {
                        UserViewModel targetUser = await SpecialIdentifierStringBuilder.GetUserFromArgument(arguments.First(), platform);

                        if (targetUser == null)
                        {
                            await ChannelSession.Services.Chat.SendMessage("The specified user does not exist");

                            return;
                        }

                        int amount = 1;
                        IEnumerable <string>   itemArgs = arguments.Skip(1);
                        UserInventoryItemModel item     = this.GetItem(string.Join(" ", itemArgs));

                        if (item == null && itemArgs.Count() > 1)
                        {
                            itemArgs = itemArgs.Take(itemArgs.Count() - 1);
                            item     = this.GetItem(string.Join(" ", itemArgs));
                            if (item != null)
                            {
                                if (!int.TryParse(arguments.Last(), out amount) || amount <= 0)
                                {
                                    await ChannelSession.Services.Chat.SendMessage("A valid amount greater than 0 must be specified");

                                    return;
                                }
                            }
                        }

                        if (item == null)
                        {
                            await ChannelSession.Services.Chat.SendMessage("The item you specified does not exist");

                            return;
                        }

                        if (!this.HasAmount(user.Data, item, amount))
                        {
                            await ChannelSession.Services.Chat.SendMessage(string.Format("You do not have the required {0} {1} to trade", amount, item.Name));

                            return;
                        }

                        this.tradeSender = new UserInventoryTradeModel()
                        {
                            User   = user,
                            Item   = item,
                            Amount = amount
                        };

                        this.tradeReceiver = new UserInventoryTradeModel()
                        {
                            User = targetUser
                        };

                        this.tradeTimeCheckToken = new CancellationTokenSource();
#pragma warning disable CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
                        AsyncRunner.RunBackgroundTask(this.tradeTimeCheckToken.Token, async(token) =>
                        {
                            await Task.Delay(60000);
                            if (!token.IsCancellationRequested)
                            {
                                this.tradeSender         = null;
                                this.tradeReceiver       = null;
                                this.tradeTimeCheckToken = null;
                                await ChannelSession.Services.Chat.SendMessage("The trade could not be completed in time and was cancelled...");
                            }
                        });
#pragma warning restore CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed

                        await ChannelSession.Services.Chat.SendMessage(string.Format("@{0} has started a trade with @{1} for {2} {3}. Type {4} <ITEM NAME> [AMOUNT] in chat to reply back with your offer in the next 60 seconds.", this.tradeSender.User.Username, this.tradeReceiver.User.Username, this.tradeSender.Amount, this.tradeSender.Item.Name, this.TradeCommand));

                        return;
                    }
                    else if (this.tradeSender != null && this.tradeReceiver != null && this.tradeReceiver.User.Equals(user) && this.tradeReceiver.Amount == 0 && arguments.Count() >= 1)
                    {
                        int amount = 1;
                        IEnumerable <string>   itemArgs = arguments.ToList();
                        UserInventoryItemModel item     = this.GetItem(string.Join(" ", itemArgs));

                        if (item == null && itemArgs.Count() > 1)
                        {
                            itemArgs = itemArgs.Take(itemArgs.Count() - 1);
                            item     = this.GetItem(string.Join(" ", itemArgs));
                            if (item != null)
                            {
                                if (!int.TryParse(arguments.Last(), out amount) || amount <= 0)
                                {
                                    await ChannelSession.Services.Chat.SendMessage("A valid amount greater than 0 must be specified");

                                    return;
                                }
                            }
                        }

                        if (item == null)
                        {
                            await ChannelSession.Services.Chat.SendMessage("The item you specified does not exist");

                            return;
                        }

                        if (!this.HasAmount(user.Data, item, amount))
                        {
                            await ChannelSession.Services.Chat.SendMessage(string.Format("You do not have the required {0} {1} to trade", amount, item.Name));

                            return;
                        }

                        this.tradeReceiver.Item   = item;
                        this.tradeReceiver.Amount = amount;

                        await ChannelSession.Services.Chat.SendMessage(string.Format("@{0} has replied back to the offer by @{1} with {2} {3}. Type {4} in chat to accept the trade.", this.tradeReceiver.User.Username, this.tradeSender.User.Username, this.tradeReceiver.Amount, this.tradeReceiver.Item.Name, this.TradeCommand));

                        return;
                    }
                    else if (this.tradeSender != null && this.tradeReceiver != null && this.tradeReceiver.Amount > 0 && this.tradeSender.User.Equals(user))
                    {
                        int senderItemMaxAmount = (this.tradeReceiver.Item.HasMaxAmount) ? this.tradeReceiver.Item.MaxAmount : this.DefaultMaxAmount;
                        if ((this.GetAmount(this.tradeSender.User.Data, this.tradeReceiver.Item) + this.tradeReceiver.Amount) > senderItemMaxAmount)
                        {
                            await ChannelSession.Services.Chat.SendMessage(string.Format("You can only have {0} {1} in total", senderItemMaxAmount, this.tradeReceiver.Item.Name));

                            return;
                        }

                        int receiverItemMaxAmount = (this.tradeSender.Item.HasMaxAmount) ? this.tradeSender.Item.MaxAmount : this.DefaultMaxAmount;
                        if ((this.GetAmount(this.tradeReceiver.User.Data, this.tradeSender.Item) + this.tradeSender.Amount) > receiverItemMaxAmount)
                        {
                            await ChannelSession.Services.Chat.SendMessage(string.Format("You can only have {0} {1} in total", receiverItemMaxAmount, this.tradeSender.Item.Name));

                            return;
                        }

                        this.SubtractAmount(this.tradeSender.User.Data, this.tradeSender.Item, this.tradeSender.Amount);
                        this.AddAmount(this.tradeReceiver.User.Data, this.tradeSender.Item, this.tradeSender.Amount);

                        this.SubtractAmount(this.tradeReceiver.User.Data, this.tradeReceiver.Item, this.tradeReceiver.Amount);
                        this.AddAmount(this.tradeSender.User.Data, this.tradeReceiver.Item, this.tradeReceiver.Amount);

                        if (this.ItemsTradedCommand != null)
                        {
                            Dictionary <string, string> specialIdentifiers = new Dictionary <string, string>();
                            specialIdentifiers["itemtotal"]       = this.tradeSender.Amount.ToString();
                            specialIdentifiers["itemname"]        = this.tradeSender.Item.Name;
                            specialIdentifiers["targetitemtotal"] = this.tradeReceiver.Amount.ToString();
                            specialIdentifiers["targetitemname"]  = this.tradeReceiver.Item.Name;
                            await this.ItemsTradedCommand.Perform(user, arguments : new string[] { this.tradeReceiver.User.Username }, extraSpecialIdentifiers : specialIdentifiers);
                        }

                        this.tradeSender   = null;
                        this.tradeReceiver = null;
                        this.tradeTimeCheckToken.Cancel();
                        this.tradeTimeCheckToken = null;

                        return;
                    }
                    else if (this.tradeSender != null && this.tradeReceiver != null && !this.tradeReceiver.User.Equals(user))
                    {
                        await ChannelSession.Services.Chat.SendMessage("A trade is already underway, please wait until it is completed");

                        return;
                    }
                }
                await ChannelSession.Services.Chat.SendMessage(this.TradeCommand + " <USERNAME> <ITEM NAME> [AMOUNT] = Trades 1 or the amount specified of the item to the specified user");
            }
            catch (Exception ex) { Logger.Log(ex); }
        }
        public async Task <Result> Connect()
        {
            this.IsConnected = false;
            if (ChannelSession.TwitchUserConnection != null)
            {
                return(await this.AttemptConnect((Func <Task <Result> >)(async() =>
                {
                    try
                    {
                        this.pubSub = new PubSubClient(ChannelSession.TwitchUserConnection.Connection);

                        if (ChannelSession.AppSettings.DiagnosticLogging)
                        {
                            this.pubSub.OnSentOccurred += PubSub_OnSentOccurred;
                            this.pubSub.OnTextReceivedOccurred += PubSub_OnTextReceivedOccurred;
                            this.pubSub.OnMessageReceived += PubSub_OnMessageReceived;
                        }
                        this.pubSub.OnReconnectReceived += PubSub_OnReconnectReceived;
                        this.pubSub.OnDisconnectOccurred += PubSub_OnDisconnectOccurred;
                        this.pubSub.OnPongReceived += PubSub_OnPongReceived;
                        this.pubSub.OnResponseReceived += PubSub_OnResponseReceived;

                        this.pubSub.OnWhisperReceived += PubSub_OnWhisperReceived;
                        this.pubSub.OnBitsV2Received += PubSub_OnBitsV2Received;
                        this.pubSub.OnSubscribedReceived += PubSub_OnSubscribedReceived;
                        this.pubSub.OnSubscriptionsGiftedReceived += PubSub_OnSubscriptionsGiftedReceived;
                        this.pubSub.OnChannelPointsRedeemed += PubSub_OnChannelPointsRedeemed;

                        await this.pubSub.Connect();

                        await Task.Delay(1000);

                        List <PubSubListenTopicModel> topics = new List <PubSubListenTopicModel>();
                        foreach (PubSubTopicsEnum topic in TwitchEventService.topicTypes)
                        {
                            topics.Add(new PubSubListenTopicModel(topic, (string)ChannelSession.TwitchUserNewAPI.id));
                        }

                        await this.pubSub.Listen(topics);

                        await Task.Delay(1000);

                        await this.pubSub.Ping();

                        this.cancellationTokenSource = new CancellationTokenSource();

                        AsyncRunner.RunBackgroundTask(this.cancellationTokenSource.Token, 60000, this.BackgroundEventChecks);

                        this.IsConnected = true;

                        return new Result();
                    }
                    catch (Exception ex)
                    {
                        Logger.Log(ex);
                        return new Result(ex);
                    }
                })));
            }
            return(new Result("Twitch connection has not been established"));
        }
Exemple #4
0
        public static async Task <bool> InitializeSession()
        {
            try
            {
                TwitchNewAPI.Users.UserModel twitchChannelNew = await ChannelSession.TwitchUserConnection.GetNewAPICurrentUser();

                TwitchV5API.Channel.ChannelModel twitchChannelv5 = await ChannelSession.TwitchUserConnection.GetCurrentV5APIChannel();

                if (twitchChannelNew != null && twitchChannelv5 != null)
                {
                    try
                    {
                        ChannelSession.TwitchUserNewAPI   = twitchChannelNew;
                        ChannelSession.TwitchChannelV5    = twitchChannelv5;
                        ChannelSession.TwitchStreamNewAPI = await ChannelSession.TwitchUserConnection.GetStream(ChannelSession.TwitchUserNewAPI);

                        ChannelSession.TwitchStreamV5 = await ChannelSession.TwitchUserConnection.GetV5LiveStream(ChannelSession.TwitchChannelV5);

                        IEnumerable <TwitchV5API.Users.UserModel> channelEditors = await ChannelSession.TwitchUserConnection.GetV5APIChannelEditors(ChannelSession.TwitchChannelV5);

                        if (channelEditors != null)
                        {
                            foreach (TwitchV5API.Users.UserModel channelEditor in channelEditors)
                            {
                                ChannelSession.TwitchChannelEditorsV5.Add(channelEditor.id);
                            }
                        }

                        if (ChannelSession.Settings == null)
                        {
                            IEnumerable <SettingsV2Model> currentSettings = await ChannelSession.Services.Settings.GetAllSettings();

                            if (currentSettings.Any(s => !string.IsNullOrEmpty(s.TwitchChannelID) && string.Equals(s.TwitchChannelID, twitchChannelNew.id)))
                            {
                                GlobalEvents.ShowMessageBox($"There already exists settings for the account {twitchChannelNew.display_name}. Please sign in with a different account or re-launch Mix It Up to select those settings from the drop-down.");
                                return(false);
                            }

                            ChannelSession.Settings = await ChannelSession.Services.Settings.Create(twitchChannelNew.display_name, isStreamer : true);
                        }
                        await ChannelSession.Services.Settings.Initialize(ChannelSession.Settings);

                        if (!string.IsNullOrEmpty(ChannelSession.Settings.TwitchUserID) && !string.Equals(ChannelSession.TwitchUserNewAPI.id, ChannelSession.Settings.TwitchUserID))
                        {
                            Logger.Log(LogLevel.Error, $"Signed in account does not match settings account: {ChannelSession.TwitchUserNewAPI.display_name} - {ChannelSession.TwitchUserNewAPI.id} - {ChannelSession.Settings.TwitchUserID}");
                            GlobalEvents.ShowMessageBox("The account you are logged in as on Twitch does not match the account for this settings. Please log in as the correct account on Twitch.");
                            ChannelSession.Settings.TwitchUserOAuthToken.accessToken  = string.Empty;
                            ChannelSession.Settings.TwitchUserOAuthToken.refreshToken = string.Empty;
                            ChannelSession.Settings.TwitchUserOAuthToken.expiresIn    = 0;
                            return(false);
                        }

                        ChannelSession.Settings.Name = ChannelSession.TwitchUserNewAPI.display_name;

                        ChannelSession.Settings.TwitchUserID    = ChannelSession.TwitchUserNewAPI.id;
                        ChannelSession.Settings.TwitchChannelID = ChannelSession.TwitchUserNewAPI.id;
                    }
                    catch (Exception ex)
                    {
                        Logger.Log(ex);
                        Logger.Log(LogLevel.Error, "Initialize Settings - " + JSONSerializerHelper.SerializeToString(ex));
                        await DialogHelper.ShowMessage("Failed to initialize settings. If this continues, please visit the Mix It Up Discord for assistance." +
                                                       Environment.NewLine + Environment.NewLine + "Error Details: " + ex.Message);

                        return(false);
                    }

                    try
                    {
                        await ChannelSession.Services.Telemetry.Connect();

                        ChannelSession.Services.Telemetry.SetUserID(ChannelSession.Settings.TelemetryUserID);

                        TwitchChatService  twitchChatService  = new TwitchChatService();
                        TwitchEventService twitchEventService = new TwitchEventService();

                        List <Task <Result> > twitchPlatformServiceTasks = new List <Task <Result> >();
                        twitchPlatformServiceTasks.Add(twitchChatService.ConnectUser());
                        twitchPlatformServiceTasks.Add(twitchEventService.Connect());

                        await Task.WhenAll(twitchPlatformServiceTasks);

                        if (twitchPlatformServiceTasks.Any(c => !c.Result.Success))
                        {
                            string errors = string.Join(Environment.NewLine, twitchPlatformServiceTasks.Where(c => !c.Result.Success).Select(c => c.Result.Message));
                            GlobalEvents.ShowMessageBox("Failed to connect to Twitch services:" + Environment.NewLine + Environment.NewLine + errors);
                            return(false);
                        }

                        await ChannelSession.Services.Chat.Initialize(twitchChatService);

                        await ChannelSession.Services.Events.Initialize(twitchEventService);
                    }
                    catch (Exception ex)
                    {
                        Logger.Log(ex);
                        Logger.Log(LogLevel.Error, "Twitch Services - " + JSONSerializerHelper.SerializeToString(ex));
                        await DialogHelper.ShowMessage("Failed to connect to Twitch services. If this continues, please visit the Mix It Up Discord for assistance." +
                                                       Environment.NewLine + Environment.NewLine + "Error Details: " + ex.Message);

                        return(false);
                    }

                    if (ChannelSession.IsStreamer)
                    {
                        Result result = await ChannelSession.InitializeBotInternal();

                        if (!result.Success)
                        {
                            await DialogHelper.ShowMessage("Failed to initialize Bot account");

                            return(false);
                        }

                        try
                        {
                            // Connect External Services
                            Dictionary <IExternalService, OAuthTokenModel> externalServiceToConnect = new Dictionary <IExternalService, OAuthTokenModel>();
                            if (ChannelSession.Settings.StreamlabsOAuthToken != null)
                            {
                                externalServiceToConnect[ChannelSession.Services.Streamlabs] = ChannelSession.Settings.StreamlabsOAuthToken;
                            }
                            if (ChannelSession.Settings.StreamElementsOAuthToken != null)
                            {
                                externalServiceToConnect[ChannelSession.Services.StreamElements] = ChannelSession.Settings.StreamElementsOAuthToken;
                            }
                            if (ChannelSession.Settings.StreamJarOAuthToken != null)
                            {
                                externalServiceToConnect[ChannelSession.Services.StreamJar] = ChannelSession.Settings.StreamJarOAuthToken;
                            }
                            if (ChannelSession.Settings.TipeeeStreamOAuthToken != null)
                            {
                                externalServiceToConnect[ChannelSession.Services.TipeeeStream] = ChannelSession.Settings.TipeeeStreamOAuthToken;
                            }
                            if (ChannelSession.Settings.TreatStreamOAuthToken != null)
                            {
                                externalServiceToConnect[ChannelSession.Services.TreatStream] = ChannelSession.Settings.TreatStreamOAuthToken;
                            }
                            if (ChannelSession.Settings.StreamlootsOAuthToken != null)
                            {
                                externalServiceToConnect[ChannelSession.Services.Streamloots] = ChannelSession.Settings.StreamlootsOAuthToken;
                            }
                            if (ChannelSession.Settings.TiltifyOAuthToken != null)
                            {
                                externalServiceToConnect[ChannelSession.Services.Tiltify] = ChannelSession.Settings.TiltifyOAuthToken;
                            }
                            if (ChannelSession.Settings.JustGivingOAuthToken != null)
                            {
                                externalServiceToConnect[ChannelSession.Services.JustGiving] = ChannelSession.Settings.JustGivingOAuthToken;
                            }
                            if (ChannelSession.Settings.IFTTTOAuthToken != null)
                            {
                                externalServiceToConnect[ChannelSession.Services.IFTTT] = ChannelSession.Settings.IFTTTOAuthToken;
                            }
                            if (ChannelSession.Settings.ExtraLifeTeamID > 0)
                            {
                                externalServiceToConnect[ChannelSession.Services.ExtraLife] = new OAuthTokenModel();
                            }
                            if (ChannelSession.Settings.PatreonOAuthToken != null)
                            {
                                externalServiceToConnect[ChannelSession.Services.Patreon] = ChannelSession.Settings.PatreonOAuthToken;
                            }
                            if (ChannelSession.Settings.DiscordOAuthToken != null)
                            {
                                externalServiceToConnect[ChannelSession.Services.Discord] = ChannelSession.Settings.DiscordOAuthToken;
                            }
                            if (ChannelSession.Settings.TwitterOAuthToken != null)
                            {
                                externalServiceToConnect[ChannelSession.Services.Twitter] = ChannelSession.Settings.TwitterOAuthToken;
                            }
                            if (ChannelSession.Services.OBSStudio.IsEnabled)
                            {
                                externalServiceToConnect[ChannelSession.Services.OBSStudio] = null;
                            }
                            if (ChannelSession.Services.StreamlabsOBS.IsEnabled)
                            {
                                externalServiceToConnect[ChannelSession.Services.StreamlabsOBS] = null;
                            }
                            if (ChannelSession.Services.XSplit.IsEnabled)
                            {
                                externalServiceToConnect[ChannelSession.Services.XSplit] = null;
                            }
                            if (!string.IsNullOrEmpty(ChannelSession.Settings.OvrStreamServerIP))
                            {
                                externalServiceToConnect[ChannelSession.Services.OvrStream] = null;
                            }
                            if (ChannelSession.Settings.EnableOverlay)
                            {
                                externalServiceToConnect[ChannelSession.Services.Overlay] = null;
                            }
                            if (ChannelSession.Settings.EnableDeveloperAPI)
                            {
                                externalServiceToConnect[ChannelSession.Services.DeveloperAPI] = null;
                            }

                            if (externalServiceToConnect.Count > 0)
                            {
                                Dictionary <IExternalService, Task <Result> > externalServiceTasks = new Dictionary <IExternalService, Task <Result> >();
                                foreach (var kvp in externalServiceToConnect)
                                {
                                    Logger.Log(LogLevel.Debug, "Trying automatic OAuth service connection: " + kvp.Key.Name);

                                    try
                                    {
                                        if (kvp.Key is IOAuthExternalService && kvp.Value != null)
                                        {
                                            externalServiceTasks[kvp.Key] = ((IOAuthExternalService)kvp.Key).Connect(kvp.Value);
                                        }
                                        else
                                        {
                                            externalServiceTasks[kvp.Key] = kvp.Key.Connect();
                                        }
                                    }
                                    catch (Exception sex)
                                    {
                                        Logger.Log(LogLevel.Error, "Error in external service initial connection: " + kvp.Key.Name);
                                        Logger.Log(sex);
                                    }
                                }

                                try
                                {
                                    await Task.WhenAll(externalServiceTasks.Values);
                                }
                                catch (Exception sex)
                                {
                                    Logger.Log(LogLevel.Error, "Error in batch external service connection");
                                    Logger.Log(sex);
                                }

                                List <IExternalService> failedServices = new List <IExternalService>();
                                foreach (var kvp in externalServiceTasks)
                                {
                                    try
                                    {
                                        if (kvp.Value.Result != null && !kvp.Value.Result.Success && kvp.Key is IOAuthExternalService)
                                        {
                                            Logger.Log(LogLevel.Debug, "Automatic OAuth token connection failed, trying manual connection: " + kvp.Key.Name);
                                            result = await kvp.Key.Connect();

                                            if (!result.Success)
                                            {
                                                failedServices.Add(kvp.Key);
                                            }
                                        }
                                    }
                                    catch (Exception sex)
                                    {
                                        Logger.Log(LogLevel.Error, "Error in external service failed re-connection: " + kvp.Key.Name);
                                        Logger.Log(sex);
                                        failedServices.Add(kvp.Key);
                                    }
                                }

                                if (failedServices.Count > 0)
                                {
                                    Logger.Log(LogLevel.Debug, "Connection failed for services: " + string.Join(", ", failedServices.Select(s => s.Name)));

                                    StringBuilder message = new StringBuilder();
                                    message.AppendLine("The following services could not be connected:");
                                    message.AppendLine();
                                    foreach (IExternalService service in failedServices)
                                    {
                                        message.AppendLine(" - " + service.Name);
                                    }
                                    message.AppendLine();
                                    message.Append("Please go to the Services page to reconnect them manually.");
                                    await DialogHelper.ShowMessage(message.ToString());
                                }
                            }
                        }
                        catch (Exception ex)
                        {
                            Logger.Log(ex);
                            Logger.Log(LogLevel.Error, "External Services - " + JSONSerializerHelper.SerializeToString(ex));
                            await DialogHelper.ShowMessage("Failed to initialize external services. If this continues, please visit the Mix It Up Discord for assistance." +
                                                           Environment.NewLine + Environment.NewLine + "Error Details: " + ex.Message);

                            return(false);
                        }

                        try
                        {
                            //if (ChannelSession.Settings.RemoteHostConnection != null)
                            //{
                            //    await ChannelSession.Services.RemoteService.InitializeConnection(ChannelSession.Settings.RemoteHostConnection);
                            //}

                            foreach (CurrencyModel currency in ChannelSession.Settings.Currency.Values)
                            {
                                if (currency.ShouldBeReset())
                                {
                                    await currency.Reset();
                                }
                            }

                            if (ChannelSession.Settings.ModerationResetStrikesOnLaunch)
                            {
                                foreach (UserDataModel userData in ChannelSession.Settings.UserData.Values)
                                {
                                    if (userData.ModerationStrikes > 0)
                                    {
                                        userData.ModerationStrikes = 0;
                                        ChannelSession.Settings.UserData.ManualValueChanged(userData.ID);
                                    }
                                }
                            }

                            ChannelSession.PreMadeChatCommands.Clear();
                            foreach (PreMadeChatCommand command in ReflectionHelper.CreateInstancesOfImplementingType <PreMadeChatCommand>())
                            {
#pragma warning disable CS0612 // Type or member is obsolete
                                if (!(command is ObsoletePreMadeCommand))
                                {
                                    ChannelSession.PreMadeChatCommands.Add(command);
                                }
#pragma warning restore CS0612 // Type or member is obsolete
                            }

                            foreach (PreMadeChatCommandSettings commandSetting in ChannelSession.Settings.PreMadeChatCommandSettings)
                            {
                                PreMadeChatCommand command = ChannelSession.PreMadeChatCommands.FirstOrDefault(c => c.Name.Equals(commandSetting.Name));
                                if (command != null)
                                {
                                    command.UpdateFromSettings(commandSetting);
                                }
                            }
                            ChannelSession.Services.Chat.RebuildCommandTriggers();

                            ChannelSession.Services.TimerService.Initialize();
                            await ChannelSession.Services.Moderation.Initialize();
                        }
                        catch (Exception ex)
                        {
                            Logger.Log(ex);
                            Logger.Log(LogLevel.Error, "Streamer Services - " + JSONSerializerHelper.SerializeToString(ex));
                            await DialogHelper.ShowMessage("Failed to initialize streamer-based services. If this continues, please visit the Mix It Up Discord for assistance." +
                                                           Environment.NewLine + Environment.NewLine + "Error Details: " + ex.Message);

                            return(false);
                        }
                    }

                    try
                    {
                        ChannelSession.Services.Statistics.Initialize();

                        ChannelSession.Services.InputService.HotKeyPressed += InputService_HotKeyPressed;

                        foreach (RedemptionStoreProductModel product in ChannelSession.Settings.RedemptionStoreProducts.Values)
                        {
                            product.ReplenishAmount();
                        }

                        foreach (RedemptionStorePurchaseModel purchase in ChannelSession.Settings.RedemptionStorePurchases.ToList())
                        {
                            if (purchase.State != RedemptionStorePurchaseRedemptionState.ManualRedeemNeeded)
                            {
                                ChannelSession.Settings.RedemptionStorePurchases.Remove(purchase);
                            }
                        }

                        ChannelSession.Services.Telemetry.TrackLogin(ChannelSession.Settings.TelemetryUserID, ChannelSession.TwitchUserNewAPI?.broadcaster_type);

                        await ChannelSession.SaveSettings();

                        await ChannelSession.Services.Settings.SaveLocalBackup(ChannelSession.Settings);

                        await ChannelSession.Services.Settings.PerformAutomaticBackupIfApplicable(ChannelSession.Settings);

                        AsyncRunner.RunBackgroundTask(sessionBackgroundCancellationTokenSource.Token, 60000, SessionBackgroundTask);
                    }
                    catch (Exception ex)
                    {
                        Logger.Log(ex);
                        Logger.Log(LogLevel.Error, "Finalize Initialization - " + JSONSerializerHelper.SerializeToString(ex));
                        await DialogHelper.ShowMessage("Failed to finalize initialization. If this continues, please visit the Mix It Up Discord for assistance." +
                                                       Environment.NewLine + Environment.NewLine + "Error Details: " + ex.Message);

                        return(false);
                    }

                    return(true);
                }
            }
            catch (Exception ex)
            {
                Logger.Log(ex);
                Logger.Log(LogLevel.Error, "Channel Information - " + JSONSerializerHelper.SerializeToString(ex));
                await DialogHelper.ShowMessage("Failed to get channel information. If this continues, please visit the Mix It Up Discord for assistance." +
                                               Environment.NewLine + Environment.NewLine + "Error Details: " + ex.Message);
            }
            return(false);
        }