コード例 #1
0
        public void HandleMessage(Player player, TaggedMessage taggedmsg)
        {
            switch (taggedmsg.tag)
            {
            case Tag.msg:
                Console.WriteLine($"<{player.ID}>" + taggedmsg.tag);
                Console.WriteLine($"<{player.ID}>" + taggedmsg.message);
                break;

            case Tag.sun:
                player.UserName = taggedmsg.message;
                break;

            case Tag.cns:
                int     newSessionID = ++sessionID;
                Session newSession   = new Session(newSessionID);
                newSession.AddPlayer(lobby, player);
                sessions.TryAdd(newSessionID, newSession);
                break;

            case Tag.jas:
                break;

            default:
                Console.WriteLine($"<{player.ID}>" + "Something went Wrong in the Tag...");
                Console.WriteLine($"<{player.ID}>" + taggedmsg.tag);
                break;
            }
        }
コード例 #2
0
        public async Task <MailMessageStatus> Enqueue(TaggedMessage message)
        {
            if (string.IsNullOrWhiteSpace(message.To))
            {
                throw new Exception("invalid-recipient");
            }

            var status = new MailMessageStatus
            {
                ReferenceId = message.ReferenceId,
                MessageId   = message.MessageId,
                Timestamp   = DateTime.UtcNow,
                Status      = MessageStatus.pending.ToString()
            };

            string errorMessage = "";

            if (!_queue.TryAdd(message))
            {
                status.Status = MessageStatus.failure.ToString();
                errorMessage  = "Unable to add message to queue.";
            }

            await _cache.SetStringAsync(
                status.ReferenceId,
                JsonSerializer.Serialize(status),
                _cacheOptions
                );

            _logger.LogDebug(logMsg, message.To, message.ClientName, status.Status, errorMessage);
            return(status);
        }
コード例 #3
0
        //private void BroadcastThread()
        //{
        //    while (running)
        //    {
        //        string input = Console.ReadLine();
        //        BroadCast(input);
        //    }

        //}

        private async void HandlePlayerClient(object obj)
        {
            Player player = obj as Player;

            if (player == null)
            {
                return;
            }

            Console.WriteLine($"<{player.ID}>Client connected");

            NetworkStream nws = player.Client.GetStream();

            SendTaggedMessage(nws, Tag.msg, "Testing... Attention please!");

            bool done = false;

            while (!done)
            {
                Task <TaggedMessage> read     = ReadTaggedMessageAsync(nws);
                TaggedMessage        recieved = await read;
                this.HandleMessage(player, recieved);
            }


            player.Client.Close();
            Console.WriteLine("Connection closed");
            nws.Close();
            Console.WriteLine("Networkstream closed");
        }
コード例 #4
0
        public static void HandlePacket(TaggedMessage taggedmsg)
        {
            switch (taggedmsg.tag)
            {
            case Tag.msg:
                Console.WriteLine(taggedmsg.message);
                break;

            default:
                Console.WriteLine("Something went Wrong in the Tag...");
                Console.WriteLine(taggedmsg.tag);
                Console.WriteLine(taggedmsg.message);
                break;
            }
        }
コード例 #5
0
        public async void HandleRead(object o)
        {
            NetworkStream nws = o as NetworkStream;

            if (nws == null)
            {
                return;
            }


            while (!done)
            {
                Task <TaggedMessage> read = ReadTaggedMessageAsync(nws);
                TaggedMessage        msg  = await read;
                HandlePacket(msg);
            }
        }
コード例 #6
0
 public static MimeMessage ToMimeMessage(this TaggedMessage source)
 {
     return(((MailMessage)source).ToMimeMessage());
 }
コード例 #7
0
ファイル: Program.cs プロジェクト: Davnit/SBLogAnalyzer
        static void Main(string[] args)
        {
            Console.WriteLine("StealthBot Log Analyzer");
            Console.WriteLine("by Pyro");
            Console.WriteLine();

            // Make sure the log storage directory exists.
            DirectoryInfo logDir = new DirectoryInfo(Path.Combine(Environment.CurrentDirectory, "Logs"));

            if (!logDir.Exists)
            {
                Console.WriteLine("Log file directory doesn't exist.");
                Console.WriteLine("Storage created at '{0}'", logDir.FullName);
                logDir.Create();
                Console.ReadKey();
                return;
            }

            // Strings to indicate that a file should not be processed.
            string[] doNotProcess = new string[4] {
                "WHISPERS", "PACKETLOG", "master", "commands"
            };

            List <LogMessage> messages = new List <LogMessage>();
            StringComparison  sComp    = StringComparison.OrdinalIgnoreCase;
            StringComparer    comparer = StringComparer.OrdinalIgnoreCase;

            #region File Processing

            // Number of files, lines, and bytes.
            int  fileCount = 0, totalLines = 0;
            long totalSize = 0;

            // Largest file and its size.
            string largestFile = String.Empty;
            long   largestSize = 0;

            foreach (FileInfo file in logDir.EnumerateFiles("*.txt").OrderBy(f => f.CreationTime))
            {
                if (file.Name.ContainsAny(doNotProcess))
                {
                    continue;
                }

                // How big is this file?
                long fileSize = file.Length;
                if (fileSize > largestSize)
                {
                    largestFile = file.Name;
                    largestSize = fileSize;
                }

                totalSize += fileSize;
                Console.Write("Processing file: {0} [{1} KB] ...", file.Name, (fileSize / 1000));

                int lineNumber = 0;
                fileCount++;

                // Get the date from the file name.
                DateTime fileDate = DateTime.Parse(Path.GetFileNameWithoutExtension(file.Name).Split(LogMessage.WordSeparator)[0]).Date;

                // Read the file
                using (StreamReader reader = file.OpenText())
                {
                    while (!reader.EndOfStream)
                    {
                        lineNumber++;
                        totalLines++;

                        string line = reader.ReadLine();

                        // Make sure the line is at least somewhat valid
                        //   Some messages are shown without timestamps, such as plugin system /updates
                        //   We don't really care about these, so they shouldn't be parsed.
                        if (LogMessage.QuickCheck(line))
                        {
                            try
                            {
                                LogMessage msg = LogMessage.Parse(line);
                                msg.SetDate(fileDate);

                                // is there... more?
                                #region Upgrade Checks

                                if (TaggedMessage.QuickCheck(msg))
                                {
                                    TaggedMessage tagged;
                                    if (TaggedMessage.TryParse(msg, out tagged))
                                    {
                                        msg = tagged;
                                    }
                                }
                                else if (ChannelJoinMessage.QuickCheck(msg))
                                {
                                    ChannelJoinMessage join;
                                    if (ChannelJoinMessage.TryParse(msg, out join))
                                    {
                                        msg = join;
                                    }
                                }
                                else if (JoinLeaveMessage.QuickCheck(msg))
                                {
                                    JoinLeaveMessage jlm;
                                    if (JoinLeaveMessage.TryParse(msg, out jlm))
                                    {
                                        msg = jlm;

                                        if (ClanMemberJoin.QuickCheck(jlm))
                                        {
                                            ClanMemberJoin cmj;
                                            if (ClanMemberJoin.TryParse(jlm, out cmj))
                                            {
                                                msg = cmj;
                                            }
                                        }
                                    }
                                }
                                else if (UserTalkMessage.QuickCheck(msg))
                                {
                                    UserTalkMessage utm;
                                    if (UserTalkMessage.TryParse(msg, out utm))
                                    {
                                        msg = utm;
                                    }
                                }
                                else if (KickBanMessage.QuickCheck(msg))
                                {
                                    KickBanMessage kbm;
                                    if (KickBanMessage.TryParse(msg, out kbm))
                                    {
                                        msg = kbm;
                                    }
                                }

                                #endregion

                                messages.Add(msg);
                            }
                            catch
                            {
                                Console.WriteLine();
                                Console.WriteLine("Exception raised while parsing message.");
                                Console.WriteLine(" - Current file: {0}", file.Name);
                                Console.WriteLine(" -  Line number: {0}", lineNumber);
                                throw;
                            }
                        }
                    }
                }


                Console.WriteLine("... {0} lines.", lineNumber);
            }

            #endregion

            // Did we actually find anything useful?
            if (fileCount == 0)
            {
                Console.WriteLine("No log files were found.");
                Console.ReadKey();
                return;
            }

            // Put all of the resulting messages into a list ordered from earliest to latest.
            messages = messages.OrderBy(m => m.Time).ToList();

            Console.WriteLine();

            Console.WriteLine("        Files: {0}", fileCount);
            Console.WriteLine("  Total Lines: {0}", totalLines);
            Console.WriteLine("   Total Size: {0:n2} MB", ((double)(totalSize / 1000) / 1000));
            Console.WriteLine(" Largest file: {0} @ {1:n0} KB", largestFile, (largestSize / 1000));
            Console.WriteLine(" Average size: {0:n0} KB", ((totalSize / fileCount) / 1000));

            Console.WriteLine("    Messages: {0}", messages.Count);
            Console.WriteLine("   Time Span: {0:n0} days", (messages.Last().Time - messages.First().Time).TotalDays);

            Console.WriteLine();

            Console.Write("Processing complete. Press enter to begin analysis. ");
            Console.ReadLine();
            Console.WriteLine();

            // Now that all of the files have been read and parsed, look at them a little more closely.
            //   If we can figure out anything else about a message, it'll happen here.

            Console.WriteLine("Beginning analysis ...");

            Dictionary <string, ChannelStats> channelStats = new Dictionary <string, ChannelStats>(comparer);

            // Go through all the messages and figure out what channels they are from, if any.
            #region Channel Linking

            string       currentChannel = String.Empty;
            string       unknownChannel = "## Unknown Channel ##";
            ChannelStats currentStats   = null;
            foreach (LogMessage message in messages)
            {
                // This indicates a new channel was joined.
                if (message is ChannelJoinMessage)
                {
                    currentChannel = message.Channel;

                    if (!channelStats.ContainsKey(currentChannel))
                    {
                        channelStats.Add(currentChannel, new ChannelStats(currentChannel));
                    }

                    currentStats = channelStats[currentChannel];

                    currentStats.LastJoined = message.Time;
                    currentStats.TimesJoined++;
                }

                // Figure out if we've left whatever channel we were in.
                bool haveLeftChannel = false;
                if (message.Type == MessageType.Tagged)
                {
                    // This indicates the bot was disconnected from the server, and by extension the channel.
                    if (((TaggedMessage)message).Tag.Equals("BNCS", sComp) && message.Content.Equals("Disconnected.", sComp))
                    {
                        haveLeftChannel = true;
                    }
                }

                // This indicates the user disconnected the bot.
                if (message.Content.Equals("All connections closed.", sComp))
                {
                    haveLeftChannel = true;
                }

                #region Statistics Tracking

                if (currentStats != null)
                {
                    if (message.Type == MessageType.Chat)
                    {
                        currentStats.TotalChatMessages++;
                        currentStats.WordCount += message.Content.Split(LogMessage.WordSeparator).Count(w => w.Length > 1);
                    }

                    if (message.Type == MessageType.JoinLeave)
                    {
                        switch (((JoinLeaveMessage)message).EventType)
                        {
                        case EventType.UserJoin:
                            currentStats.TotalUserJoins++;
                            break;

                        case EventType.UserLeft:
                            currentStats.TotalUserLeaves++;
                            break;
                        }
                    }

                    if (message.Type == MessageType.KickBan)
                    {
                        currentStats.TotalRemoved++;
                    }
                }

                #endregion

                // Assign the channel
                message.Channel = currentChannel;

                if (message.Type == MessageType.Chat || message.Type == MessageType.JoinLeave || message.Type == MessageType.KickBan)
                {
                    if (message.Channel.Length == 0)
                    {
                        message.Channel = unknownChannel;
                    }
                }

                if (haveLeftChannel)
                {
                    if (currentStats != null)
                    {
                        currentStats.TimeInChannel += (message.Time - currentStats.LastJoined).TotalSeconds;
                        currentStats = null;
                    }

                    currentChannel = String.Empty;
                }
            }

            #endregion

            // Get some sub-enums
            var chat     = messages.Where(m => m is UserTalkMessage).Select(m => (UserTalkMessage)m);;
            var joins    = messages.Where(m => m is JoinLeaveMessage).Select(m => (JoinLeaveMessage)m);;
            var channels = messages.Where(m => m is ChannelJoinMessage).Select(m => (ChannelJoinMessage)m);
            var removals = messages.Where(m => m is KickBanMessage).Select(m => (KickBanMessage)m);

            var clanMembers = messages.Where(m => m is ClanMemberJoin).Select(m => (ClanMemberJoin)m);

            string blizzPostfix = "@Blizzard";
            var    blizzReps    = chat.Where(m => m.Username.EndsWith(blizzPostfix)).Select(m => new Tuple <string, LogMessage>(m.Username, m));
            blizzReps = blizzReps.Concat(joins.Where(m => m.Username.EndsWith(blizzPostfix)).Select(m => new Tuple <string, LogMessage>(m.Username, m)));
            blizzReps = blizzReps.Concat(removals.Where(m => m.KickedBy.EndsWith(blizzPostfix)).Select(m => new Tuple <string, LogMessage>(m.KickedBy, m)));

            Console.WriteLine(" - {0} chat messages", chat.Count());
            Console.WriteLine(" - {0} channels", channels.Select(m => m.Channel).Distinct(comparer).Count());
            Console.WriteLine(" - {0} unique users", chat.Select(m => m.Username).Concat(joins.Select(m => m.Username)).Distinct(comparer).Count());
            Console.WriteLine(" - {0} operator actions", removals.Count());
            Console.WriteLine(" - {0} clan members from {1} clans", clanMembers.Select(m => m.Username).Distinct(comparer).Count(), clanMembers.Select(m => m.ClanTag).Distinct(comparer).Count());
            Console.WriteLine(" - {0} blizzard employees seen {1} times", blizzReps.Select(r => r.Item1).Distinct(comparer).Count(), blizzReps.Count());
            Console.WriteLine();

            // this function orders the elements by number of occurrences
            Func <IEnumerable <string>, IOrderedEnumerable <Tuple <string, int> > > OrderByCount = (e) => e.GroupBy(s => s, comparer).Select(g => new Tuple <string, int>(g.Key, g.Count())).OrderByDescending(r => r.Item2);

            // Get the leaderboards
            var mostJoined      = OrderByCount(channels.Select(c => c.Channel));
            var activeChannels  = OrderByCount(chat.Select(c => c.Channel));
            var activeUsers     = OrderByCount(chat.Select(c => c.Username));
            var mostKicked      = OrderByCount(removals.Where(r => r.EventType == EventType.Kick).Select(c => c.Username));
            var mostBanned      = OrderByCount(removals.Where(r => r.EventType == EventType.Ban).Select(c => c.Username));
            var activeOps       = OrderByCount(removals.Select(c => c.KickedBy));
            var mostCommonClans = OrderByCount(clanMembers.Select(c => c.ClanTag));

            var channelsByTimeSpent = channelStats.Select(c => new Tuple <string, int>(c.Key, (int)c.Value.TimeInChannel)).OrderByDescending(x => x.Item2);

            #region Leaderboards

            // this function shows the first X elements
            #region ShowLeaders() function
            Action <string, IOrderedEnumerable <Tuple <string, int> >, int> ShowLeaders = (title, items, count) =>
            {
                int position = 0;
                Console.WriteLine(title + ": ");
                foreach (var item in items)
                {
                    position++;
                    Console.WriteLine(" - #{0} -> {1}: {2}", position, item.Item1, item.Item2);

                    if (position == 10)
                    {
                        break;
                    }
                }
                Console.WriteLine();
            };
            #endregion

            ShowLeaders("Most joined channels", mostJoined, 10);
            ShowLeaders("Most active channels", activeChannels, 10);
            ShowLeaders("Most active users", activeUsers, 10);
            ShowLeaders("Most kicked users", mostKicked, 10);
            ShowLeaders("Most banned users", mostBanned, 10);
            ShowLeaders("Most active operators", activeOps, 10);
            ShowLeaders("Most common clan tags", mostCommonClans, 10);
            ShowLeaders("Channels by time spent", channelsByTimeSpent, 10);

            #endregion

            Console.Write("Analysis complete. Press enter to begin writing output. ");
            Console.ReadLine();
            Console.WriteLine();

            Console.WriteLine("Writing data to output... this could take a while.");

            // Create writer for the output directory
            CollectionWriter writer = new CollectionWriter("Output");

            // Write the master output file (this will be big)
            Console.WriteLine("Writing master file...");
            writer.WriteFile("Master.txt", messages.Where(m => m.Type != MessageType.Generic), m => m.ToString());

            // Write list of all clan tags found and when they were first seen
            writer.WriteFile("ClanTags.txt", clanMembers.GroupBy(m => m.ClanTag, comparer).Select(m => m.First()),
                             m => String.Format("{0} -> {1} on {2} in '{3}'.", m.ClanTag, m.Username.Split('@')[0], m.Time.ToString("MMM d, yyyy"), m.Channel));

            // What has Blizzard been up to?
            writer.WriteFile("BlizzardEmployees.txt", blizzReps, r => String.Format("[{0}] {1} >> {2}", r.Item2.Time, r.Item1, r.Item2.Content));

            // Output leaderboards
            Console.WriteLine("Writing leaderboards...");

            #region WriteCounts() method
            Action <string, IOrderedEnumerable <Tuple <string, int> > > WriteCounts = (fileName, items) =>
            {
                writer.WriteFileWithPosition(fileName, items, item => String.Format("#%POSITION% -> {0}: {1}", item.Item1, item.Item2));
            };
            #endregion

            WriteCounts("JoinedChannels.txt", mostJoined);
            WriteCounts("ActiveChannels.txt", activeChannels);
            WriteCounts("ActiveUsers.txt", activeUsers);
            WriteCounts("ActiveOperators.txt", activeOps);
            WriteCounts("MostPopularClans.txt", mostCommonClans);
            WriteCounts("ChannelsByTime.txt", channelsByTimeSpent);

            // Output per-channel logs
            Console.WriteLine("Writing individual channel logs...");
            foreach (var channel in activeChannels)
            {
                string channelName = channel.Item1;

                writer.CurrentDirectory = "Output\\Channels";
                writer.CurrentDirectory = Path.Combine(writer.CurrentDirectory, channelName);
                Console.WriteLine(" - {0}", channelName);

                // Get a collection of messages from this channel
                var channelMessages = messages.Where(m => m.Channel.Equals(channelName, sComp));

                // Sub collections
                var channelJoins = joins.Where(m => m.Channel.Equals(channelName, sComp));
                var channelChat  = chat.Where(m => m.Channel.Equals(channelName, sComp));

                // Write a list of users seen in this channel
                writer.WriteFile("Users.txt", channelJoins.Select(j => j.Username).Concat(channelChat.Select(c => c.Username)).Distinct(comparer), m => m);

                // Is it a clan? If so, who have we seen that's a member?
                if (ChannelJoinMessage.IsClanChannel(channel.Item1))
                {
                    string tag          = channelName.Split(LogMessage.WordSeparator)[1];
                    var    localMembers = clanMembers.Where(c => c.ClanTag.Equals(tag, sComp)).GroupBy(m => m.Username, comparer).Select(m => m.Last());

                    writer.WriteFile("Members.txt", localMembers, m => String.Format("{0} -> {1} in {2}", m.Username.Split('@')[0], m.Time, m.Channel));
                }

                // Write some misc statistics
                if (channelStats.ContainsKey(channelName))
                {
                    ChannelStats stats      = channelStats[channelName];
                    string[]     statOutput = new string[9]
                    {
                        "First joined: " + channelMessages.Where(m => m.Type == MessageType.ChannelJoin).First().Time.ToString(),
                        "Last joined: " + stats.LastJoined.ToString(),
                        "Number of times joined: " + stats.TimesJoined,
                        "Total joins: " + stats.TotalUserJoins,
                        "Total leaves: " + stats.TotalUserLeaves,
                        "Total removed: " + stats.TotalRemoved,
                        "Total chat messages: " + stats.TotalChatMessages,
                        "Word count: " + stats.WordCount,
                        "Time spent in channel: " + stats.TimeInChannel + " seconds"
                    };
                    writer.WriteFile("Statistics.txt", statOutput, s => s);
                }

                // Write a separate log file for each date (same as source format)
                MessageType[] includedMessages = new MessageType[4]
                {
                    MessageType.ChannelJoin,
                    MessageType.Chat,
                    MessageType.JoinLeave,
                    MessageType.KickBan
                };

                foreach (var date in channelMessages.Select(m => m.Time.Date).Distinct())
                {
                    string fileName = date.ToString("yyyy-MM-dd") + ".txt";

                    var tempMessages = channelMessages.Where(m => m.Time.Date.Equals(date) && includedMessages.Contains(m.Type));
                    if (tempMessages.Count() > 0)
                    {
                        writer.WriteFile(fileName, tempMessages, m => m.ToString());
                    }
                }
            }

            Console.WriteLine("Work complete!");
            Console.ReadLine();
        }