using System; using System.IO; using System.Threading; namespace MinecraftClient.Protocol.Session { /// /// Monitor session file changes on disk /// class SessionFileMonitor { private FileSystemWatcher monitor; private Thread polling; /// /// Create a new SessionFileMonitor and start monitoring /// /// Folder to monitor /// Filename inside folder /// Callback for file changes public SessionFileMonitor(string folder, string filename, FileSystemEventHandler handler) { if (Settings.DebugMessages) ConsoleIO.WriteLineFormatted("§8Initializing disk session cache using FileSystemWatcher"); try { monitor = new FileSystemWatcher(); monitor.Path = folder; monitor.IncludeSubdirectories = false; monitor.Filter = filename; monitor.NotifyFilter = NotifyFilters.LastWrite; monitor.Changed += handler; monitor.EnableRaisingEvents = true; } catch { if (Settings.DebugMessages) ConsoleIO.WriteLineFormatted("§8Failed to initialize FileSystemWatcher, retrying using Polling"); polling = new Thread(() => PollingThread(folder, filename, handler)); polling.Start(); } } /// /// Fallback polling thread for use when operating system does not support FileSystemWatcher /// /// Folder to monitor /// File name to monitor /// Callback when file changes private void PollingThread(string folder, string filename, FileSystemEventHandler handler) { string filePath = String.Concat(folder, Path.DirectorySeparatorChar, filename); DateTime lastWrite = GetLastWrite(filePath); while (true) { Thread.Sleep(5000); DateTime lastWriteNew = GetLastWrite(filePath); if (lastWriteNew != lastWrite) { lastWrite = lastWriteNew; handler(this, new FileSystemEventArgs(WatcherChangeTypes.Changed, folder, filename)); } } } /// /// Get last write for a given file /// /// File path to get last write from /// Last write time, or DateTime.MinValue if the file does not exist private DateTime GetLastWrite(string path) { FileInfo fileInfo = new FileInfo(path); if (fileInfo.Exists) { return fileInfo.LastWriteTime; } else return DateTime.MinValue; } } }