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); } }
public void Dispose() { Close(); _state = LogFileState.Disposed; }
public void Close() { CheckIfDisposed(); if (_writer == null) return; try { _writer.Flush(); _writer.Close(); _writer.Dispose(); } finally { _state = LogFileState.Unknown; _writer = null; } }
private void RefreshState() { if (_writer == null) return; if (_state == LogFileState.OpenAvailable && _writer.BaseStream.Position >= _sizeInBytes) _state = LogFileState.OpenExhausted; }
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; } }
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); } } }