/// <summary>
        /// Joins the room with the settings passed in.
        /// </summary>
        public void JoinRoom(InstallationSettings settings)
        {
            // Copy over the settings into this class so this class can use it.
            this.settings = settings;

            // Create the ChatMessageProcessor.
            cmp = new ChatMessageProcessor(settings);
            cmp.StopBotCommandIssued += cmp_StopBotCommandIssued;

            // Logic to join the chat room.
            chatClient = new Client(settings.Email, settings.Password);
            cvChatRoom = chatClient.JoinRoom(settings.ChatRoomUrl);
            ChatBotStats.LoginDate = DateTime.Now;
            cvChatRoom.StripMention = false;

            // Say the startup message?
            if (!settings.StartUpMessage.IsNullOrWhiteSpace())
            {
                // This is the one of the few instances to not using the "OrThrow" method.
                var startMessage = cvChatRoom.PostMessage(settings.StartUpMessage);

                if (startMessage == null)
                {
                    throw new InvalidOperationException("Unable to post start up message to room.");
                }
            }

            cvChatRoom.EventManager.ConnectListener(EventType.MessagePosted, new Action<Message>(cvChatRoom_NewMessage));
            cvChatRoom.EventManager.ConnectListener(EventType.MessageEdited, new Action<Message>(cvChatRoom_NewMessage));
        }
Exemple #2
0
        public void ProcessMessage(Message msg, ref Room rm)
        {
            var up = msg.Content.Remove(0, 1);
            ulong upInt = 0;

            if (!ulong.TryParse(up, out upInt) || upInt == 0)
            {
                rm.PostReplyLight(msg, string.Format(errorPhrases.PickRandom(), msg.Author.Name));
                return;
            }

            var nBytes = new byte[8];
            Extensions.RNG.GetBytes(nBytes);
            var n = (BitConverter.ToUInt64(nBytes, 0) % upInt) + 1;

            if (n % 25 == 0)
            {
                rm.PostReplyLight(msg, "http://imgs.xkcd.com/comics/random_number.png");
                return;
            }

            if (upInt == 100)
            {
                rm.PostReplyLight(msg, n == 1 ? "**CRITICAL SUCCESS**" : n == 100 ? "**CRITICAL FAILURE**" : n.ToString());
            }
            else
            {
                rm.PostReplyLight(msg, n);
            }
        }
Exemple #3
0
        public static void Main(string[] args)
        {
            Console.Title = "Hatman";
            Console.Write("Reading config...");

            if (!File.Exists("Config.txt"))
            {
                Console.WriteLine("Config.txt not found." +
                    " \nPlease ensure the file can be found within the working directory.");
                Console.Read();
                return;
            }

            var email = "";
            var pass = "";
            ReadConfig(out email, out pass);

            Console.Write("done.\nLogging into SE...");
            chatClient = new Client(email, pass);

            Console.Write("done.\nJoining room...");
            chatRoom = chatClient.JoinRoom(roomURL, true);
            Extensions.SelfID = chatRoom.Me.ID;

            ChatEventRouter router = new ChatEventRouter(chatRoom);

            Console.WriteLine("done.\n");
            chatRoom.PostMessageLight("Hiya");

            router.ShutdownMre.WaitOne();

            chatRoom.PostMessageLight("Cya");
            chatRoom.Leave();
        }
        /// <summary>
        /// Gets the tags from the SEDE query. If the email and password has not already
        /// been set then those credentials will be saved and used. Will also tell
        /// the chat room if the tags are being refreshed (because it takes some time).
        /// </summary>
        /// <param name="chatRoom"></param>
        /// <param name="email"></param>
        /// <param name="password"></param>
        /// <returns></returns>
        public static Dictionary<string, int> GetTags(Room chatRoom, string email, string password)
        {
            // Set the email/password if not set.
            if (loginEmail == null)
            {
                loginEmail = email;
                loginPassword = password;
            }

            // If tags have not been gotten yet or its been more than 30 minutes since the last get
            // then refresh the tag listing.
            if (tags == null || (DateTime.UtcNow - lastRevIdCheckTime).TotalMinutes > 30)
            {
                chatRoom.PostMessageOrThrow("Refreshing the tag listing. Please wait...");

                var currentID = "";

                if ((currentID = Client.GetSedeQueryRunUrl(236526)) != lastRevision || tags == null)
                {
                    lastRevision = currentID;
                    tags = Client.GetTags(lastRevision);
                }

                lastRevIdCheckTime = DateTime.UtcNow;
            }
            return tags;
        }
Exemple #5
0
 public ChatEventArgs(EventType t, Message m, User u, Room r, string rawData)
 {
     this.Type = t;
     this.Message = m;
     this.User = u;
     this.Room = r;
     this.Handled = false;
 }
Exemple #6
0
 public void ProcessMessage(Message msg, ref Room rm)
 {
     if (!quotaReached || (quotaReached && (DateTime.UtcNow - lastTry).TotalHours > 1))
     {
         var message = GetMessageNewMethod(msg);
         rm.PostReplyLight(msg, message);
     }
 }
Exemple #7
0
 public override void RunAction(Message incommingChatMessage, Room chatRoom, InstallationSettings roomSettings)
 {
     var message = "This is a chat bot for the SO Close Vote Reviewers chat room, developed by [gunr2171](http://stackoverflow.com/users/1043380/gunr2171) and the other members of the SO Close Vote Reviewers chat room. " +
         "For more information see the [github page](https://github.com/SO-Close-Vote-Reviewers/SOCVR-Chatbot). " +
         "Reply with `{0}` to see a list of commands."
             .FormatInline(ChatbotActionRegister.GetChatBotActionUsage<Commands>());
     chatRoom.PostMessageOrThrow(message);
 }
Exemple #8
0
        public void ProcessMessage(Message msg, ref Room rm)
        {
            var users = rm.GetCurrentUsers();
            var userX = users.PickRandom().GetChatFriendlyUsername();
            var userY = users.PickRandom().GetChatFriendlyUsername();
            while (userX == userY)
            {
                userY = users.PickRandom().GetChatFriendlyUsername();
            }
            var message = string.Format(phrases.PickRandom(), userX, userY);

            rm.PostReplyFast(msg, message);
        }
Exemple #9
0
 public Chat()
 {
     chatClient = new Client(Configuration.LoginEmail, Configuration.LoginPassword, Configuration.ProxyUrl, Configuration.ProxyUsername, Configuration.ProxyPassword);
     try
     {
         chatRoom = chatClient.JoinRoom(Configuration.RoomUrl);
     }
     catch (AuthenticationException)
     {
         Console.WriteLine("Cannot Login");
         chatClient.Dispose();
     }
 }
Exemple #10
0
 public void Execute(string command, string arguments, User user, Room room, Client client)
 {
     if (!AdaPermissions.IsAuthorized(permissionLevel, user))
     {
         var messageBuilder = new MessageBuilder();
         messageBuilder.AppendPing(user);
         messageBuilder.AppendText("You are not authorised to make this command.");
         room.PostMessage(messageBuilder);
     }
     else
     {
         Action(command, arguments, user, room, client);
     }
 }
Exemple #11
0
        public void ProcessMessage(Message msg, ref Room rm)
        {
            var cmdsMsg = new MessageBuilder(MultiLineMessageType.Code, false);
            cmdsMsg.AppendPing(msg.Author);

            foreach (var cmd in commands)
            {
                cmdsMsg.AppendText("\n" + cmd.Usage + " - " + cmd.Description);
            }

            cmdsMsg.AppendText("\n" + Usage + " - " + Description);

            rm.PostMessageFast(cmdsMsg);
        }
        /// <summary>
        /// Main entry point for the class.
        /// Takes a message revived from chat, determines what action should be taken, then performs that action.
        /// </summary>
        /// <param name="incommingChatMessage">The chat message that was said.</param>
        /// <param name="chatRoom">The room the chat message was said in.</param>
        public void ProcessChatMessage(Message incommingChatMessage, Room chatRoom)
        {
            // Do this first so I only have to find the result once per chat message.
            bool isReplyToChatbot = MessageIsReplyToChatbot(incommingChatMessage, chatRoom);

            // Determine the list of possible actions that work from the message.
            var possibleChatbotActionsToRun = ChatbotActionRegister.AllChatActions
                .Where(x => x.DoesChatMessageActiveAction(incommingChatMessage, isReplyToChatbot))
                .ToList();

            if (possibleChatbotActionsToRun.Count > 1)
                throw new Exception("More than one possible chat bot action to run for the input '{0}'"
                    .FormatSafely(incommingChatMessage.Content));

            if (!possibleChatbotActionsToRun.Any())
            {
                // Didn't find an action to run, what to do next depends of if the message was
                // a reply to the chatbot or not.
                if (isReplyToChatbot)
                {
                    // User was trying to make a command.
                    SendUnrecognizedCommandToDatabase(incommingChatMessage.GetContentsWithStrippedMentions());
                    chatRoom.PostReplyOrThrow(incommingChatMessage, "Sorry, I don't understand that. Use `{0}` for a list of commands."
                        .FormatInline(ChatbotActionRegister.GetChatBotActionUsage<Commands>()));
                }
                // Else it's a trigger, do nothing.

                return;
            }

            // You have a single item to run.
            var chatbotActionToRun = possibleChatbotActionsToRun.Single();

            // Now, do you have permission to run it? If you are a mod the answer is yes, else you need to check.
            if (incommingChatMessage.Author.IsMod || DoesUserHavePermissionToRunAction(chatbotActionToRun, incommingChatMessage.Author.ID))
            {
                // Have permission, run it.
                RunChatbotAction(chatbotActionToRun, incommingChatMessage, chatRoom);
            }
            else
            {
                // Don't have permission, tell the user only if it's a command.
                if (isReplyToChatbot)
                {
                    chatRoom.PostReplyOrThrow(incommingChatMessage, "Sorry, you need more permissions to run that command.");
                }
                // Don't do anything for triggers.
            }
        }
Exemple #13
0
        public Message(Room room, int messageID, User author, int parentID = -1)
        {
            if (room == null) { throw new ArgumentException("room"); }
            if (messageID < 0) { throw new ArgumentOutOfRangeException("messageID", "'messageID' can not be less than 0."); }
            if (author == null) { throw new ArgumentNullException("author"); }

            Content = GetMessageContent(room.Host, messageID, room.StripMention);
            Host = room.Host;
            RoomID = room.ID;
            ID = messageID;
            ParentID = parentID;
            Author = author;

            var historyHtml = RequestManager.Get("", "http://chat." + Host + "/messages/" + ID + "/history");

            SetStarPinCount(historyHtml);
            EditCount = GetEditCount(historyHtml);
        }
Exemple #14
0
        public void ProcessMessage(Message msg, ref Room rm)
        {
            if (au == null) { return; }

            rm.PostReplyFast(msg, "Updating, one sec...");

            if (!au.Update())
            {
                rm.PostReplyFast(msg, "I'm already up to date.");
            }
            else
            {
                rm.PostReplyFast(msg, "Update successful, starting new version...");

                au.StartNewVersion();

                Process.GetCurrentProcess().CloseMainWindow();
            }
        }
Exemple #15
0
        public void ProcessMessage(Message msg, ref Room rm)
        {
            var n = new byte[4];
            rng.GetBytes(n);
            var message = "";

            if (BitConverter.ToUInt32(n, 0) % 100 > 50)
            {
                // Pick any date within 10 years from now.
                var date = DateTime.UtcNow.Add(TimeSpan.FromDays(r.Next(-3652, 3652)));
                message = date.ToString("yyyy-MM-dd", CultureInfo.InvariantCulture);
            }
            else
            {
                message = phrases.PickRandom();
            }

            rm.PostReplyFast(msg, message);
        }
        public override void RunAction(Message incomingChatMessage, ChatExchangeDotNet.Room chatRoom)
        {
            var runningCommands = RunningChatbotActionsManager.GetRunningChatbotActions();
            var now             = DateTimeOffset.Now;

            var tableMessage = runningCommands
                               .Select(x => new
            {
                Command = x.ChatbotActionName,
                ForUser = $"{x.RunningForUserName} ({x.RunningForUserId})",
                Started = (now - x.StartTs).ToUserFriendlyString() + " ago",
            })
                               .ToStringTable(new[] { "Command", "For User", "Started" },
                                              x => x.Command,
                                              x => x.ForUser,
                                              x => x.Started);

            chatRoom.PostReplyOrThrow(incomingChatMessage, "The following is a list of commands that I'm currently running:");
            chatRoom.PostMessageOrThrow(tableMessage);
        }
Exemple #17
0
        public ChatEventRouter(Room chatRoom, string token)
        {
            monitoredRoom = chatRoom;

            PopulateCommands(token);
            PopulateTriggers();

            chatRoom.EventManager.ConnectListener(EventType.UserMentioned, new Action<Message>(m =>
            {
                EventCallback(EventType.UserMentioned, m, null, monitoredRoom, null);
            }));
            chatRoom.EventManager.ConnectListener(EventType.MessagePosted, new Action<Message>(m =>
            {
                EventCallback(EventType.MessagePosted, m, null, monitoredRoom, null);
            }));
            chatRoom.EventManager.ConnectListener(EventType.UserEntered, new Action<User>(u =>
            {
                EventCallback(EventType.UserEntered, null, u, monitoredRoom, null);
            }));
            chatRoom.EventManager.ConnectListener(EventType.UserLeft, new Action<User>(u =>
            {
                EventCallback(EventType.UserLeft, null, u, monitoredRoom, null);
            }));
        }
Exemple #18
0
        public void ProcessMessage(Message msg, ref Room rm)
        {
            var users = rm.CurrentUsers;
            var userX = users.PickRandom().Name;
            var userY = users.PickRandom().Name;
            while (userX == userY)
            {
                userY = users.PickRandom().Name;
            }

            if (userX == rm.Me.Name)
            {
                userX = "me";
            }

            if (userY == rm.Me.Name)
            {
                userY = "me";
            }

            var message = string.Format(phrases.PickRandom(), userX, userY);

            rm.PostReplyLight(msg, message);
        }
        /// <summary>
        /// Records the end of a review session for a user. Returns true if the session was successfully marked as finished.
        /// </summary>
        /// <param name="userMessage"></param>
        /// <param name="chatRoom"></param>
        /// <param name="itemsReviewed"></param>
        /// <returns></returns>
        protected bool EndSession(Message userMessage, Room chatRoom, int? itemsReviewed, InstallationSettings settings)
        {
            var da = new DatabaseAccessor(settings.DatabaseConnectionString);

            // Find the latest session by that user.
            var latestSession = da.GetLatestOpenSessionForUser(userMessage.Author.ID);

            // First, check if there is a session.
            if (latestSession == null)
            {
                chatRoom.PostReplyOrThrow(userMessage, "I don't seem to have the start of your review session on record. I might have not been running when you started, or some error happened.");
                return false;
            }

            // Check if session is greater than [MAX_REVIEW_TIME].
            var maxReviewTimeHours = settings.MaxReviewLengthHours;

            var timeThreshold = DateTimeOffset.Now.AddHours(-maxReviewTimeHours);

            if (latestSession.SessionStart < timeThreshold)
            {
                var timeDelta = DateTimeOffset.Now - latestSession.SessionStart;

                var message = "Your last uncompleted review session was {0} ago. Because it has exceeded my threshold ({1} hours), I can't mark that session with this information. "
                    .FormatInline(timeDelta.ToUserFriendlyString(), maxReviewTimeHours) +
                    "Use the command '{0}' to forcefully end that session."
                    .FormatInline(ChatbotActionRegister.GetChatBotActionUsage<EndSession>());

                chatRoom.PostReplyOrThrow(userMessage, message);
                return false;
            }

            // It's all good, mark the info as done.
            da.EndReviewSession(latestSession.Id, itemsReviewed);
            return true;
        }
Exemple #20
0
        private static void HandleChatCommand(Room room, Message command)
        {
            try
            {
                if (UserAccess.Owners.Any(id => id == command.Author.ID) ||
                    command.Author.IsRoomOwner || command.Author.IsMod)
                {
                    var cmdMatches = HandleOwnerCommand(room, command);

                    if (!cmdMatches)
                    {
                        cmdMatches = HandlePrivilegedUserCommand(room, command);

                        if (!cmdMatches)
                        {
                            HandleNormalUserCommand(room, command);
                        }
                    }
                }
                else if (command.Author.Reputation >= 3000)
                {
                    var cmdMatches = HandlePrivilegedUserCommand(room, command);

                    if (!cmdMatches)
                    {
                        HandleNormalUserCommand(room, command);
                    }
                }
                else
                {
                    HandleNormalUserCommand(room, command);
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex);
                room.PostReplyFast(command, $"`Unable to execute command: {ex.Message}`");
            }
        }
Exemple #21
0
 public void ProcessMessage(Message msg, ref Room rm)
 {
     rm.PostReplyFast(msg, faces.PickRandom());
 }
Exemple #22
0
 public void ProcessMessage(Message msg, ref Room rm) => rm.PostReplyLight(msg, pics.PickRandom());
 internal void HandleEvent(EventType eventType, Room room, ref EventManager evMan, Dictionary<string, object> data)
 {
     events[eventType].Execute(room, ref evMan, data);
 }
Exemple #24
0
 public static void EchoMessage(string command, string arguments, User user, Room room, Client client)
 {
     var messageBuilder = new MessageBuilder();
     messageBuilder.PingAndMessage(user, command + "!! :D");
     room.PostMessageLight(messageBuilder);
 }
Exemple #25
0
 public static void LeaveChat(string command, string arguments, User user, Room room, Client client)
 {
     room.PostMessageLight("Bye, sleeps for me!");
     room.Leave();
     client.Dispose();
     AdaRunner.Shutdown();
 }
Exemple #26
0
        private static bool HandleOwnerCommand(Room room, Message command)
        {
            var cmd = command.Content.Trim().ToUpperInvariant();

            if (cmd == "STOP")
            {
                shutdownMre.Set();
                return true;
            }
            if (cmd.StartsWith("SET THRESHOLD"))
            {
                var th = 0F;

                if (!float.TryParse(cmd.Remove(0, 14), out th))
                {
                    room.PostReplyFast(command, "Try using your hands to type a valid number between 0 and 1.");
                    return true;
                }

                if (th < 0 || th > 1)
                {
                    room.PostReplyFast(command, "Threshold must be between 0 and 1 (and *don't* include the % sign).");
                    return true;
                }

                cvClassifier.Threshold = th;
                qdvClassifier.Threshold = th;
                advClassifier.Threshold = th;

                room.PostReplyFast(command, "Threshold updated.");

                return true;
            }

            //case "UPDATE":
            //{
            //    UpdateBot(room, command);
            //    return true;
            //}

            return false;
        }
Exemple #27
0
        private static bool HandlePrivilegedUserCommand(Room room, Message command)
        {
            var cmd = command.Content.Trim().ToUpperInvariant();

            switch (cmd)
            {
                case "DEL":
                {
                    room.DeleteMessage(command.ParentID);
                    return true;
                }
                default:
                {
                    return false;
                }
            }
        }
Exemple #28
0
        private static bool HandleNormalUserCommand(Room room, Message command)
        {
            var cmd = command.Content.Trim().ToUpperInvariant();

            switch (cmd)
            {
                case "ALIVE":
                {
                    var statusReport = $"Yes, I'm alive (`{DateTime.UtcNow - startTime}`).";
                    room.PostMessageFast(statusReport);
                    return true;
                }
                case "COMMANDS":
                {
                    var msg = $"See [here]({wikiCmdsLink} \"Chat Commands Wiki\").";
                    room.PostReplyFast(command, msg);
                    return true;
                }
                case "THRESHOLD":
                {
                    var msg = $"My current threshold is: `{cvClassifier.Threshold * 100}`%.";
                    room.PostMessageFast(msg);
                    return true;
                }
                //case "VERSION":
                //{
                //    var msg = $"My current version is: `{updater.CurrentVersion}`.";
                //    room.PostReplyFast(command, msg);
                //    return true;
                //}
                default:
                {
                    return false;
                }
            }
        }
Exemple #29
0
        private static void JoinRooms()
        {
            var cr = new ConfigReader();

            socvr = chatClient.JoinRoom(cr.GetSetting("room"));

            socvr.EventManager.ConnectListener(EventType.UserMentioned,
                new Action<Message>(m => HandleChatCommand(socvr, m)));

            socvr.EventManager.ConnectListener(EventType.MessageReply,
                new Action<Message, Message>((p, c) => HandleChatCommand(socvr, c)));

            lqphq = chatClient.JoinRoom("http://chat.meta.stackexchange.com/rooms/773");

            lqphq.EventManager.ConnectListener(EventType.UserMentioned,
                new Action<Message>(m => HandleChatCommand(lqphq, m)));

            lqphq.EventManager.ConnectListener(EventType.MessageReply,
                new Action<Message, Message>((p, c) => HandleChatCommand(lqphq, c)));
        }
Exemple #30
0
        private void PrintCommandListReply(Message m, Room r)
        {
            StringBuilder sb = new StringBuilder();

            for (int i = 0; i < router.Commands.Count; i++)
            {
                sb.AppendFormat("{0}. ({1}) {2}\n", i + 1, router.CommandStates[router.Commands[i]] ? "Enabled" : "Disabled", router.Commands[i].Usage);
            }
            r.PostReplyLight(m, sb.ToString());
        }
Exemple #31
0
        public Room JoinRoom(string roomUrl)
        {
            var host = hostParser.Replace(roomUrl, "");
            var id = int.Parse(idParser.Replace(roomUrl, ""));

            if (Rooms.Any(room => room.Host == host && room.ID == id))
            {
                throw new Exception("Cannot join a room you are already in.");
            }

            if (Rooms.All(room => room.Host != host))
            {
                if (host.ToLowerInvariant() == "stackexchange.com")
                {
                    SEChatLogin();
                }
                else
                {
                    SiteLogin(host);
                }
            }

            var r = new Room(cookieKey, host, id);

            Rooms.Add(r);

            return r;
        }