/// <summary> /// Applies the spam delay. If the delay wasn't respected, <see cref="Fail"/> them. /// </summary> /// <param name="message">The message to analyze.</param> private static void ApplySpamDelay(Entites.Message message) { Debug.Assert(message.UserToChannel.Privileges.Rules.SpamDelay != null, "message.UserToChannel.Privileges.Rules.SpamDelay != null"); if (message.SentOn - UserToChannel.GetMessageBefore(message.UserToChannel, message.SentOn).SentOn < message.UserToChannel.Privileges.Rules.SpamDelay.Value) { Fail(message, "You are sending messages too quickly. Be careful or you will be kicked."); } }
/// <summary> /// Creates a new message for a user, in a channel, with a specified text (not in the database). /// </summary> /// <param name="text">The text.</param> /// <param name="userToChannel">The user to channel.</param> /// <returns>The newly created message.</returns> public static Entites.Message Create(string text, Entites.UserToChannel userToChannel) { Entites.Message message = new Entites.Message(userToChannel.Application, null, DateTime.Now, userToChannel, null); message.Texts = new List <Entites.Text> { new Entites.Text(text, message.SentOn, message) }; return(message); }
/// <summary> /// Given a message, make Terministrator answers to it. /// </summary> /// <param name="original">The original message.</param> /// <param name="text">The text.</param> /// <returns>The answering message.</returns> public static Entites.Message Answer(Entites.Message original, string text) { Entites.Message message = new Entites.Message(original.Application, null, DateTime.UtcNow, original.UserToChannel, MessageType.Get("Text"), original); message.Texts = new List <Entites.Text> { new Entites.Text(text, message.SentOn, message) }; return(message); }
/// <summary> /// Adds the references of the second arguement in the first one. /// </summary> /// <param name="message">The message to add the references in.</param> /// <param name="reference">The references.</param> /// <returns>The first arguement.</returns> private static Entites.Message AddReferences(Entites.Message message, Entites.Message reference) { message.Application = reference.Application; message.UserToChannel = reference.UserToChannel; message.RepliesTo = reference.RepliesTo; message.MessageType = reference.MessageType; message.JoinedUserToChannel = reference.JoinedUserToChannel; return(message); }
/// <summary> /// Loads the text collection of a message. /// </summary> /// <param name="message">The message.</param> /// <returns>The same message with the text collection loaded.</returns> public static Entites.Message LoadTexts(Entites.Message message) { using (TerministratorContext context = new TerministratorContext(true)) { context.Message.Attach(message); context.Entry(message).Collection(p => p.Texts).Load(); } return(message); }
/// <summary> /// Loads the application of the message. /// </summary> /// <param name="message">The message.</param> /// <returns>The same message with the application instance initialized.</returns> public static Entites.Message LoadApplication(Entites.Message message) { using (TerministratorContext context = new TerministratorContext(true)) { context.Message.Attach(message); context.Entry(message).Reference(p => p.Application).Load(); } return(message); }
/// <summary> /// Attributes the points to a user from the channel's policies. Called upon receiving a new message. /// </summary> /// <param name="message">The message.</param> /// <param name="core">The core.</param> /// <returns>How many points were given to that user.</returns> public static float AttributePoints(Entites.Message message, Core core = null) { float points = DAL.PointSystem.LoadMessageTypes(DAL.Channel.LoadPointSystem(message.UserToChannel.Channel).PointSystem) ?.MessageTypeToPointSystem.FirstOrDefault(x => x.MessageTypeId == message.MessageTypeId)?.Reward ?? 0; message.UserToChannel.Points += points; Update(message.UserToChannel); return(points); }
/// <summary> /// Creates the specified message. /// </summary> /// <param name="message">The message.</param> /// <returns>The same message with an updated ID.</returns> public static Entites.Message Create(Entites.Message message) { Entites.Message reference = ClearReferences(message); using (TerministratorContext context = new TerministratorContext(true)) { message.MessageId = context.Message.Add(message).MessageId; context.SaveChanges(); } return(AddReferences(message, reference)); }
/// <summary> /// Applies the blocked words filter. If a blocked word is found in the message, <see cref="Fail"/> them. /// </summary> /// <param name="message">The message to analyze.</param> private static void ApplyBlockedWords(Entites.Message message) { foreach (Entites.BlockedWord blockedWord in message.UserToChannel.Privileges.Rules.BlockedWords) { if (message.Text.IndexOf(blockedWord.Word, StringComparison.InvariantCultureIgnoreCase) >= 0) { Fail(message, "Your message contains a blocked word. Be careful or you will be kicked."); return; } } }
/// <summary> /// Clears the references of the message. /// </summary> /// <param name="message">The message.</param> /// <returns>A copy of the message given in entry with only the references.</returns> private static Entites.Message ClearReferences(Entites.Message message) { Entites.Message reference = new Entites.Message(message.Application, null, DateTime.MinValue, message.UserToChannel, message.MessageType, message.RepliesTo, false, message.JoinedUserToChannel); message.Application = null; message.UserToChannel = null; message.RepliesTo = null; message.MessageType = null; message.JoinedUserToChannel = null; return(reference); }
/// <summary> /// Loads the message being replied to. /// </summary> /// <param name="message">The message.</param> /// <returns>The same message with the replied message loaded.</returns> public static Entites.Message LoadRepliesTo(Entites.Message message) { using (TerministratorContext context = new TerministratorContext(true)) { if (context.Entry(message).State == EntityState.Detached) { context.Message.Attach(message); } context.Entry(message).Reference(p => p.RepliesTo).Load(); } return(message); }
/// <summary> /// Applies the r9k filter. If a message with an identical r9k text is found, <see cref="Fail"/> them. /// </summary> /// <param name="message">The message to analyze.</param> private static void ApplyR9K(Entites.Message message) { Entites.Text text = message.Texts.OrderByDescending(x => x.SetOn).First(); text.R9KText = ToR9KText(text.ZeText); // Check if not enough content or if we know the message if (text.ZeText.Length == 0 || text.ZeText.Length > 10 && (text.R9KText.Length / Convert.ToDouble(text.ZeText.Length) < SignalRatio || Text.SearchAndLink(text).SimilarContent != null)) { Fail(message, "Your privileges group makes you in r9k mode and the message you attempted to send is not unique. Be careful or you will be kicked."); } }
/// <summary> /// Loads the user to channel of a message. /// </summary> /// <param name="message">The message.</param> /// <returns>The same message with the user to channel loaded.</returns> public static Entites.Message LoadUserToChannel(Entites.Message message) { using (TerministratorContext context = new TerministratorContext(true)) { if (message.UserToChannel != null) { message.UserToChannel = null; } context.Entry(context.Message.Find(message.MessageId)).State = EntityState.Detached; context.Message.Attach(message); context.Entry(message).Reference(p => p.UserToChannel).Load(); } return(message); }
/// <summary> /// Fails the user due to the specified message. Warn them if they weren't muted, kick them otherwise. /// </summary> /// <param name="message">The message.</param> /// <param name="reason">The reason.</param> private static void Fail(Entites.Message message, string reason) { message.UserToChannel.NbSilences++; TimeSpan muteTime = GetMuteTime(message.UserToChannel.NbSilences); // Someone abusing the system in some way or if someone gets failed while already muted if (muteTime > TimeoutLimit || message.UserToChannel.SilencedTo - DateTime.UtcNow > TimeSpan.FromSeconds(1)) { Kick(message.UserToChannel); return; } message.UserToChannel.SilencedTo = DateTime.UtcNow + muteTime; UserToChannel.Update(message.UserToChannel); DAL.UserToChannel.LoadChannel(message.UserToChannel); Entites.Message.SendMessage(Message.Answer(message, reason)); }
/// <summary> /// Apply the rules on a newly received message. /// </summary> /// <param name="message">The message.</param> /// <param name="isCommand">If the message was recognized as a command.</param> internal static void ReceivedMessage(Entites.Message message, bool isCommand) { if (!isCommand && message.Texts.Any() && DateTime.UtcNow - message.SentOn <= Configuration.MaxDelayToAct) { if (message.UserToChannel?.Privileges?.Rules?.R9KEnabled ?? false) { ApplyR9K(message); } if (message.UserToChannel?.Privileges?.Rules?.BlockedWordsEnabled ?? false) { ApplyBlockedWords(message); } if ((message.UserToChannel?.Privileges?.Rules?.SpamDelay.HasValue ?? false) && message.UserToChannel.Privileges.Rules.SpamDelay > TimeSpan.Zero) { ApplySpamDelay(message); } } }
/// <summary> /// Creates the specified message. /// </summary> /// <param name="iMessage">The imessage.</param> /// <returns>The newly created message.</returns> public static Entites.Message Create(IMessage iMessage) { //TODO: Actually process the real message types. Entites.Message message = DAL.Message.Create( new Entites.Message(Application.UpdateOrCreate(iMessage.Channel.Application), iMessage.ApplicationId, iMessage.SentDate, UserToChannel.UpdateOrCreate(iMessage.Channel.Application, iMessage.From, iMessage.Channel), MessageType.Get("Text"), iMessage.RepliesTo != null ? GetOrCreate(iMessage.RepliesTo) : null, false, iMessage.JoinedUser == null ? null : UserToChannel.GetOrCreate(iMessage.Channel.Application, iMessage.JoinedUser, iMessage.Channel))); if (!string.IsNullOrEmpty(iMessage.Text)) { message.Texts = new List <Entites.Text> { Text.Create(new Entites.Text(iMessage.Text, iMessage.SentDate, message, string.IsNullOrEmpty(iMessage.Text) ? null : Rules.ToR9KText(iMessage.Text))) }; } // If the user was invited back, we make sure to reboot their consequences. if (message.JoinedUserToChannel != null && (message.JoinedUserToChannel.NbSilences != 0 || message.JoinedUserToChannel.SilencedTo != null)) { message.JoinedUserToChannel.NbSilences = 0; message.JoinedUserToChannel.SilencedTo = null; UserToChannel.Update(message.JoinedUserToChannel); } return(message); }