using System; using System.Collections.Generic; using System.Linq; using System.Text; using Ionic.Zip; using System.IO; using System.Reflection; using System.Diagnostics; using System.Threading; namespace Aiwaz.Common { public class FileSystem : IDisposable { private Dictionary> attachedFiles = new Dictionary>(); private ZipFile zipFile; private FileSystemWatcher watcher; private string directory; public FileSystem() { directory = Path.GetDirectoryName(Process.GetCurrentProcess().MainModule.FileName); this.watcher = new FileSystemWatcher(directory); this.watcher.NotifyFilter = NotifyFilters.LastWrite; this.watcher.IncludeSubdirectories = true; this.watcher.Changed += watcher_Changed; this.watcher.EnableRaisingEvents = true; if (File.Exists(Path.Combine(directory, "data.pak"))) { zipFile = ZipFile.Read(Path.Combine(directory, "data.pak")); } } void watcher_Changed(object sender, FileSystemEventArgs e) { foreach (var entry in attachedFiles) { if (e.FullPath == entry.Key) { while (true) { try { var stream = new FileStream(e.FullPath, FileMode.Open); entry.Value(stream); break; } catch (IOException) { Thread.Sleep(100); } } } } } ~FileSystem() { this.Dispose(); } public void Attach(string argFileName, Action onLoaded) { if (File.Exists(Path.Combine(directory, argFileName))) { Stream fileStream = new FileStream(Path.Combine(directory, argFileName), FileMode.Open); if (fileStream != null && onLoaded != null) { var fullPath = Path.Combine(directory, argFileName).Replace('/', '\\'); attachedFiles[fullPath] = onLoaded; onLoaded(fileStream); } } else if (zipFile != null) { var file = zipFile[argFileName]; if (file != null) { Stream outputStream = new MemoryStream(); file.Extract(outputStream); if (onLoaded != null) onLoaded(outputStream); } } else { throw new FileNotFoundException(argFileName); } } #region IDisposable Members public void Dispose() { if (zipFile != null) { zipFile.Dispose(); } } #endregion } public static class BinaryReaderExtensions { public static string ReadNullTerminatedString(this BinaryReader reader) { string result = string.Empty; char readChar = '\0'; do { readChar = reader.ReadChar(); if (readChar != '\0') result += readChar; } while (readChar != '\0'); return result; } } }