private async Task <ChatMessageViewModel> AddMessage(ChatMessageEventModel messageEvent)
        {
            UserViewModel user = await ChannelSession.ActiveUsers.AddOrUpdateUser(messageEvent.GetUser());

            if (user == null)
            {
                user = new UserViewModel(messageEvent);
            }
            else
            {
                await user.RefreshDetails();
            }
            user.UpdateLastActivity();

            ChatMessageViewModel message = new ChatMessageViewModel(messageEvent, user);

            Util.Logger.LogDiagnostic(string.Format("Message Received - {0}", message.ToString()));

            if (!message.IsWhisper && !this.userEntranceCommands.Contains(user.ID))
            {
                this.userEntranceCommands.Add(user.ID);
                if (user.Data.EntranceCommand != null)
                {
                    await user.Data.EntranceCommand.Perform(user);
                }
            }

            if (this.Messages.ContainsKey(message.ID))
            {
                return(null);
            }
            this.Messages[message.ID] = message;

            if (this.DisableChat && !message.ID.Equals(Guid.Empty))
            {
                Util.Logger.LogDiagnostic(string.Format("Deleting Message As Chat Disabled - {0}", message.Message));
                await this.DeleteMessage(message);

                return(message);
            }

            if (!ModerationHelper.MeetsChatInteractiveParticipationRequirement(user) || !ModerationHelper.MeetsChatEmoteSkillsOnlyParticipationRequirement(user, message))
            {
                Util.Logger.LogDiagnostic(string.Format("Deleting Message As User does not meet requirement - {0} - {1}", ChannelSession.Settings.ModerationChatInteractiveParticipation, message.Message));

                await this.DeleteMessage(message);

                await ModerationHelper.SendChatInteractiveParticipationWhisper(user, isChat : true);

                return(message);
            }

            string moderationReason = await message.ShouldBeModerated();

            if (!string.IsNullOrEmpty(moderationReason))
            {
                Util.Logger.LogDiagnostic(string.Format("Message Should Be Moderated - {0}", message.ToString()));

                bool shouldBeModerated         = true;
                PermissionsCommandBase command = this.CheckMessageForCommand(message);
                if (command != null && string.IsNullOrEmpty(await ModerationHelper.ShouldBeFilteredWordModerated(user, message.Message)))
                {
                    shouldBeModerated = false;
                }

                if (shouldBeModerated)
                {
                    Util.Logger.LogDiagnostic(string.Format("Moderation Being Performed - {0}", message.ToString()));

                    message.ModerationReason = moderationReason;
                    await this.DeleteMessage(message);

                    return(message);
                }
            }

            if (!string.IsNullOrEmpty(ChannelSession.Settings.NotificationChatWhisperSoundFilePath) && message.IsWhisper)
            {
                await ChannelSession.Services.AudioService.Play(ChannelSession.Settings.NotificationChatWhisperSoundFilePath, 100);
            }
            else if (!string.IsNullOrEmpty(ChannelSession.Settings.NotificationChatTaggedSoundFilePath) && message.IsUserTagged)
            {
                await ChannelSession.Services.AudioService.Play(ChannelSession.Settings.NotificationChatTaggedSoundFilePath, 100);
            }
            else if (!string.IsNullOrEmpty(ChannelSession.Settings.NotificationChatMessageSoundFilePath))
            {
                await ChannelSession.Services.AudioService.Play(ChannelSession.Settings.NotificationChatMessageSoundFilePath, 100);
            }

            GlobalEvents.ChatMessageReceived(message);

            if (!await this.CheckMessageForCommandAndRun(message))
            {
                if (message.IsWhisper && ChannelSession.Settings.TrackWhispererNumber && !message.IsStreamerOrBot())
                {
                    await this.whisperNumberLock.WaitAndRelease(() =>
                    {
                        if (!whisperMap.ContainsKey(message.User.ID))
                        {
                            whisperMap[message.User.ID] = whisperMap.Count + 1;
                        }
                        message.User.WhispererNumber = whisperMap[message.User.ID];
                        return(Task.FromResult(0));
                    });

                    await ChannelSession.Chat.Whisper(message.User.UserName, $"You are whisperer #{message.User.WhispererNumber}.", false);
                }
            }

            return(message);
        }
Beispiel #2
0
        public async Task AddMessage(ChatMessageViewModel message)
        {
            try
            {
                message.ProcessingStartTime = DateTimeOffset.Now;
                Logger.Log(LogLevel.Debug, string.Format("Message Received - {0} - {1} - {2}", message.ID.ToString(), message.ProcessingStartTime, message));

                // Pre message processing

                if (message is UserChatMessageViewModel)
                {
                    if (message.User != null)
                    {
                        if (message.Platform == StreamingPlatformTypeEnum.Twitch)
                        {
                            UserViewModel activeUser = ChannelSession.Services.User.GetUserByTwitchID(message.User.TwitchID);
                            if (activeUser != null)
                            {
                                message.User = activeUser;
                            }
                        }

                        message.User.UpdateLastActivity();
                        if (message.IsWhisper && ChannelSession.Settings.TrackWhispererNumber && !message.IsStreamerOrBot && message.User.WhispererNumber == 0)
                        {
                            await this.whisperNumberLock.WaitAndRelease(() =>
                            {
                                if (!whisperMap.ContainsKey(message.User.ID))
                                {
                                    whisperMap[message.User.ID] = whisperMap.Count + 1;
                                }
                                message.User.WhispererNumber = whisperMap[message.User.ID];
                                return(Task.FromResult(0));
                            });
                        }
                    }
                }

                // Add message to chat list
                bool showMessage = true;
                if (ChannelSession.Settings.HideBotMessages && message.User != null && ChannelSession.TwitchBotNewAPI != null && message.User.TwitchID.Equals(ChannelSession.TwitchBotNewAPI.id))
                {
                    showMessage = false;
                }

                if (!(message is AlertChatMessageViewModel) || !ChannelSession.Settings.OnlyShowAlertsInDashboard)
                {
                    this.messagesLookup[message.ID] = message;
                    if (showMessage)
                    {
                        if (ChannelSession.Settings.LatestChatAtTop)
                        {
                            this.Messages.Insert(0, message);
                        }
                        else
                        {
                            this.Messages.Add(message);
                        }
                    }

                    if (this.Messages.Count > ChannelSession.Settings.MaxMessagesInChat)
                    {
                        ChatMessageViewModel removedMessage = (ChannelSession.Settings.LatestChatAtTop) ? this.Messages.Last() : this.Messages.First();
                        this.messagesLookup.Remove(removedMessage.ID);
                        this.Messages.Remove(removedMessage);
                    }
                }

                // Post message processing

                if (message is UserChatMessageViewModel && message.User != null)
                {
                    if (message.IsWhisper && !message.IsStreamerOrBot)
                    {
                        if (!string.IsNullOrEmpty(ChannelSession.Settings.NotificationChatWhisperSoundFilePath))
                        {
                            await ChannelSession.Services.AudioService.Play(ChannelSession.Settings.NotificationChatWhisperSoundFilePath, ChannelSession.Settings.NotificationChatWhisperSoundVolume, ChannelSession.Settings.NotificationsAudioOutput);
                        }

                        if (!string.IsNullOrEmpty(message.PlainTextMessage))
                        {
                            EventTrigger trigger = new EventTrigger(EventTypeEnum.ChatWhisperReceived, message.User);
                            trigger.SpecialIdentifiers["message"] = message.PlainTextMessage;
                            await ChannelSession.Services.Events.PerformEvent(trigger);
                        }

                        // Don't send this if it's in response to another "You are whisperer #" message
                        if (ChannelSession.Settings.TrackWhispererNumber && message.User.WhispererNumber > 0 && !message.PlainTextMessage.StartsWith("You are whisperer #", StringComparison.InvariantCultureIgnoreCase))
                        {
                            await ChannelSession.Services.Chat.Whisper(message.User, $"You are whisperer #{message.User.WhispererNumber}.", sendAsStreamer : false);
                        }
                    }
                    else
                    {
                        if (this.DisableChat)
                        {
                            Logger.Log(LogLevel.Debug, string.Format("Deleting Message As Chat Disabled - {0} - {1}", message.ID, message));
                            await this.DeleteMessage(message);

                            return;
                        }

                        if (!string.IsNullOrEmpty(ChannelSession.Settings.NotificationChatTaggedSoundFilePath) && message.IsStreamerTagged)
                        {
                            await ChannelSession.Services.AudioService.Play(ChannelSession.Settings.NotificationChatTaggedSoundFilePath, ChannelSession.Settings.NotificationChatTaggedSoundVolume, ChannelSession.Settings.NotificationsAudioOutput);
                        }
                        else if (!string.IsNullOrEmpty(ChannelSession.Settings.NotificationChatMessageSoundFilePath))
                        {
                            await ChannelSession.Services.AudioService.Play(ChannelSession.Settings.NotificationChatMessageSoundFilePath, ChannelSession.Settings.NotificationChatMessageSoundVolume, ChannelSession.Settings.NotificationsAudioOutput);
                        }

                        if (message.User != null && !this.userEntranceCommands.Contains(message.User.ID))
                        {
                            this.userEntranceCommands.Add(message.User.ID);
                            if (ChannelSession.Settings.GetCommand(message.User.Data.EntranceCommandID) != null)
                            {
                                await ChannelSession.Settings.GetCommand(message.User.Data.EntranceCommandID).Perform(new CommandParametersModel(message.User, message.Platform, message.ToArguments()));
                            }
                        }

                        if (!string.IsNullOrEmpty(message.PlainTextMessage))
                        {
                            EventTrigger trigger = new EventTrigger(EventTypeEnum.ChatMessageReceived, message.User);
                            trigger.SpecialIdentifiers["message"] = message.PlainTextMessage;
                            await ChannelSession.Services.Events.PerformEvent(trigger);
                        }

                        message.User.Data.TotalChatMessageSent++;

                        string primaryTaggedUsername = message.PrimaryTaggedUsername;
                        if (!string.IsNullOrEmpty(primaryTaggedUsername))
                        {
                            UserViewModel primaryTaggedUser = ChannelSession.Services.User.GetUserByUsername(primaryTaggedUsername, message.Platform);
                            if (primaryTaggedUser != null)
                            {
                                primaryTaggedUser.Data.TotalTimesTagged++;
                            }
                        }
                    }

                    await message.User.RefreshDetails();

                    if (!message.IsWhisper && await message.CheckForModeration())
                    {
                        await this.DeleteMessage(message);

                        return;
                    }

                    IEnumerable <string> arguments = null;
                    if (!string.IsNullOrEmpty(message.PlainTextMessage) && message.User != null && !message.User.UserRoles.Contains(UserRoleEnum.Banned))
                    {
                        if (!ChannelSession.Settings.AllowCommandWhispering && message.IsWhisper)
                        {
                            return;
                        }

                        if (ChannelSession.Settings.IgnoreBotAccountCommands)
                        {
                            if (ChannelSession.TwitchBotNewAPI != null && message.User.TwitchID.Equals(ChannelSession.TwitchBotNewAPI.id))
                            {
                                return;
                            }
                        }

                        Logger.Log(LogLevel.Debug, string.Format("Checking Message For Command - {0} - {1}", message.ID, message));

                        bool commandTriggered = false;
                        if (message.User.Data.CustomCommandIDs.Count > 0)
                        {
                            Dictionary <string, CommandModelBase> userOnlyTriggersToCommands = new Dictionary <string, CommandModelBase>();
                            List <ChatCommandModel> userOnlyWildcardCommands = new List <ChatCommandModel>();
                            foreach (Guid commandID in message.User.Data.CustomCommandIDs)
                            {
                                ChatCommandModel command = (ChatCommandModel)ChannelSession.Settings.GetCommand(commandID);
                                if (command != null && command.IsEnabled)
                                {
                                    if (command.Wildcards)
                                    {
                                        userOnlyWildcardCommands.Add(command);
                                    }
                                    else
                                    {
                                        foreach (string trigger in command.GetFullTriggers())
                                        {
                                            userOnlyTriggersToCommands[trigger.ToLower()] = command;
                                        }
                                    }
                                }
                            }

                            if (!commandTriggered && userOnlyWildcardCommands.Count > 0)
                            {
                                foreach (ChatCommandModel command in userOnlyWildcardCommands)
                                {
                                    if (command.DoesMessageMatchWildcardTriggers(message, out arguments))
                                    {
                                        await this.RunChatCommand(message, command, arguments);

                                        commandTriggered = true;
                                        break;
                                    }
                                }
                            }

                            if (!commandTriggered && userOnlyTriggersToCommands.Count > 0)
                            {
                                commandTriggered = await this.CheckForChatCommandAndRun(message, userOnlyTriggersToCommands);
                            }
                        }

                        if (!commandTriggered)
                        {
                            foreach (ChatCommandModel command in this.wildcardCommands)
                            {
                                if (command.DoesMessageMatchWildcardTriggers(message, out arguments))
                                {
                                    await this.RunChatCommand(message, command, arguments);

                                    commandTriggered = true;
                                    break;
                                }
                            }
                        }

                        if (!commandTriggered)
                        {
                            commandTriggered = await this.CheckForChatCommandAndRun(message, this.triggersToCommands);
                        }
                    }

                    foreach (InventoryModel inventory in ChannelSession.Settings.Inventory.Values.ToList())
                    {
                        if (inventory.ShopEnabled && ChatCommandModel.DoesMessageMatchTriggers(message, new List <string>()
                        {
                            inventory.ShopCommand
                        }, out arguments))
                        {
                            await inventory.PerformShopCommand(message.User, arguments, message.Platform);
                        }
                        else if (inventory.TradeEnabled && ChatCommandModel.DoesMessageMatchTriggers(message, new List <string>()
                        {
                            inventory.TradeCommand
                        }, out arguments))
                        {
                            await inventory.PerformTradeCommand(message.User, arguments, message.Platform);
                        }
                    }

                    if (ChannelSession.Settings.RedemptionStoreEnabled)
                    {
                        if (ChatCommandModel.DoesMessageMatchTriggers(message, new List <string>()
                        {
                            ChannelSession.Settings.RedemptionStoreChatPurchaseCommand
                        }, out arguments))
                        {
                            await RedemptionStorePurchaseModel.Purchase(message.User, arguments);
                        }
                        else if (ChatCommandModel.DoesMessageMatchTriggers(message, new List <string>()
                        {
                            ChannelSession.Settings.RedemptionStoreModRedeemCommand
                        }, out arguments))
                        {
                            await RedemptionStorePurchaseModel.Redeem(message.User, arguments);
                        }
                    }

                    GlobalEvents.ChatMessageReceived(message);

                    await this.WriteToChatEventLog(message);
                }

                Logger.Log(LogLevel.Debug, string.Format("Message Processing Complete: {0} - {1} ms", message.ID, message.ProcessingTime));
                if (message.ProcessingTime > 500)
                {
                    Logger.Log(LogLevel.Error, string.Format("Long processing time detected for the following message: {0} - {1} ms - {2}", message.ID.ToString(), message.ProcessingTime, message));
                }
            }
            catch (Exception ex)
            {
                Logger.Log(ex);
            }
        }