예제 #1
0
        static void HandleForwardedLog(string logMessage, LogFileState state)
        {
            const string FMT_STR = "0000.00.00 00:00:00 ";

            string trimmedStr = logMessage.Substring(FMT_STR.Length);

            string message        = trimmedStr.Substring(trimmedStr.IndexOf('-') + 2);
            string trimmedMessage = message.TrimStart(' ', '\t');

            string prefixStr = trimmedMessage;

            if (!prefixStr.StartsWith("[VRCWorldPersistency]"))
            {
                Console.WriteLine("Other message: " + message);
                return;
            }
            else
            {
                Console.WriteLine(message);
            }
        }
예제 #2
0
 public void Dispose()
 {
     Close();
     _state = LogFileState.Disposed;
 }
예제 #3
0
        public void Close()
        {
            CheckIfDisposed();

            if (_writer == null)
                return;

            try
            {
                _writer.Flush();
                _writer.Close();
                _writer.Dispose();
            }
            finally
            {
                _state = LogFileState.Unknown;
                _writer = null;
            }
        }
예제 #4
0
        private void RefreshState()
        {
            if (_writer == null)
                return;

            if (_state == LogFileState.OpenAvailable && _writer.BaseStream.Position >= _sizeInBytes)
                _state = LogFileState.OpenExhausted;
        }
예제 #5
0
        public void Open()
        {
            CheckIfDisposed();

            if (_state != LogFileState.Unknown)
                throw new InvalidOperationException("Cannot open an already opened file");

            CreateStreamWriter();

            var firstNullPosition = FindFirstNull();
            if (firstNullPosition < 0 || firstNullPosition >= _sizeInBytes)
            {
                _writer.WriteLine("Cutover");
                State = LogFileState.OpenExhausted;
            }
            else if (firstNullPosition == 0)
            {
                _writer.BaseStream.Position = 0;
                State = LogFileState.OpenAvailable;
            }
            else
            {
                _writer.BaseStream.Position = firstNullPosition;
                _writer.WriteLine();
                State = LogFileState.OpenAvailable;
            }
        }
예제 #6
0
        internal static void Update()
        {
            if (!InitializeScriptLookup())
            {
                Console.WriteLine("Could not initialize log file watcher");
                return;
            }

            if (lineMatch == null)
            {
                lineMatch = new Regex(MATCH_STR, RegexOptions.Compiled);
            }

            List <(string, string)> modifiedFilesAndContents = null;

            lock (logModifiedLock)
            {
                if (modifiedLogPaths.Count > 0)
                {
                    Console.WriteLine("Files have changed!");
                    modifiedFilesAndContents = new List <(string, string)>();
                    HashSet <string> newLogPaths = new HashSet <string>();

                    foreach (string logPath in modifiedLogPaths)
                    {
                        if (!logFileStates.TryGetValue(logPath, out LogFileState logState))
                        {
                            logFileStates.Add(logPath, new LogFileState());
                        }

                        logState = logFileStates[logPath];

                        string newLogContent = "";

                        newLogPaths.Add(logPath);

                        try
                        {
                            FileInfo fileInfo = new FileInfo(logPath);

                            using (var stream = fileInfo.Open(FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
                            {
                                using (StreamReader reader = new StreamReader(stream))
                                {
                                    if (logState.playerName == null) // Search for the player name that this log belongs to
                                    {
                                        string fullFileContents = reader.ReadToEnd();

                                        const string SEARCH_STR = "[VRCFlowManagerVRC] User Authenticated: ";
                                        int          userIdx    = fullFileContents.IndexOf(SEARCH_STR);
                                        if (userIdx != -1)
                                        {
                                            userIdx += SEARCH_STR.Length;

                                            int endIdx = userIdx;

                                            while (fullFileContents[endIdx] != '\r' && fullFileContents[endIdx] != '\n')
                                            {
                                                endIdx++;                                                                          // Seek to end of name
                                            }
                                            string username = fullFileContents.Substring(userIdx, endIdx - userIdx);

                                            logState.playerName = username;

                                            // Use the log path as well since Build & Test can have multiple of the same display named users
                                            System.Random random = new System.Random((username + logPath).GetHashCode());
                                        }
                                    }

                                    if (logState.lineOffset == -1)
                                    {
                                        reader.BaseStream.Seek(0, SeekOrigin.End);
                                    }
                                    else
                                    {
                                        reader.BaseStream.Seek(logState.lineOffset - 4 < 0 ? 0 : logState.lineOffset - 4, SeekOrigin.Begin); // Subtract 4 characters to pick up the newlines from the prior line for the log forwarding
                                    }

                                    newLogContent = reader.ReadToEnd();

                                    logFileStates[logPath].lineOffset = reader.BaseStream.Position;
                                    reader.Close();
                                }

                                stream.Close();
                            }

                            newLogPaths.Remove(logPath);

                            if (newLogContent != "")
                            {
                                modifiedFilesAndContents.Add((logPath, newLogContent));
                            }
                        }
                        catch (System.IO.IOException)
                        { }
                    }

                    modifiedLogPaths = newLogPaths;
                }
            }

            if (modifiedFilesAndContents != null)
            {
                foreach (var modifiedFile in modifiedFilesAndContents)
                {
                    LogFileState state = logFileStates[modifiedFile.Item1];

                    // Log forwarding
                    int   currentIdx = 0;
                    Match match      = null;

                    do
                    {
                        currentIdx = (match?.Index ?? -1);

                        match = lineMatch.Match(modifiedFile.Item2, currentIdx + 1);

                        string logStr = null;

                        if (currentIdx == -1)
                        {
                            if (match.Success)
                            {
                                Match nextMatch = lineMatch.Match(modifiedFile.Item2, match.Index + 1);

                                if (nextMatch.Success)
                                {
                                    logStr = modifiedFile.Item2.Substring(0, nextMatch.Index);
                                }
                                else
                                {
                                    logStr = modifiedFile.Item2;
                                }

                                match = nextMatch;
                            }
                        }
                        else if (match.Success)
                        {
                            logStr = modifiedFile.Item2.Substring(currentIdx < 0 ? 0 : currentIdx, match.Index - currentIdx);
                        }
                        else if (currentIdx != -1)
                        {
                            logStr = modifiedFile.Item2.Substring(currentIdx < 0 ? 0 : currentIdx, modifiedFile.Item2.Length - currentIdx);
                        }

                        if (logStr != null)
                        {
                            logStr = logStr.Trim('\n', '\r');

                            HandleForwardedLog(logStr, state);
                        }
                    } while (match.Success);
                }
            }
        }