コード例 #1
0
        /// <summary>
        /// Returns a list of files with the given extension, or an empty list if no files are found. Searches
        /// all child directories recursively to look for files.
        /// </summary>
        /// <param name="extension">File extension (including period, ie: ".arc")</param>
        /// <returns>List of files matching that extension</returns>
        public List <VirtualFilesystemFile> FindByExtension(params string[] extensions)
        {
            if (extensions.Length == 0)
            {
                throw new ArgumentException("You must specify at least one extension", "extensions");
            }

            List <VirtualFilesystemFile> validFiles = new List <VirtualFilesystemFile>();

            foreach (var child in Children)
            {
                if (child.Type == NodeType.File)
                {
                    VirtualFilesystemFile file = (VirtualFilesystemFile)child;
                    for (int i = 0; i < extensions.Length; i++)
                    {
                        string extension = extensions[i];
                        if (string.Compare(file.Extension, extension, System.StringComparison.InvariantCultureIgnoreCase) == 0)
                        {
                            validFiles.Add(file);
                            break;
                        }
                    }
                }
                else if (child.Type == NodeType.Directory)
                {
                    VirtualFilesystemDirectory dir = (VirtualFilesystemDirectory)child;
                    validFiles.AddRange(dir.FindByExtension(extensions));
                }
            }

            return(validFiles);
        }
コード例 #2
0
        private void ImportFromDiskRecursive(string folder, VirtualFilesystemDirectory dir)
        {
            if (!Directory.Exists(folder))
            {
                throw new ArgumentException("You must specify a directory that exists", "folder");
            }

            // For each directory that is a child of the specified folder into ourselves, and then import the contents.
            DirectoryInfo dirInfo = new DirectoryInfo(folder);

            foreach (var diskDir in dirInfo.GetDirectories())
            {
                VirtualFilesystemDirectory vfDir = new VirtualFilesystemDirectory(diskDir.Name);
                dir.Children.Add(vfDir);

                ImportFromDiskRecursive(diskDir.FullName, vfDir);
            }

            foreach (var diskFile in dirInfo.GetFiles())
            {
                using (BinaryReader reader = new BinaryReader(File.Open(diskFile.FullName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)))
                {
                    string fileName = Path.GetFileNameWithoutExtension(diskFile.Name);
                    string fileExt  = Path.GetExtension(diskFile.Name);

                    byte[] data = reader.ReadBytes((int)reader.BaseStream.Length);
                    VirtualFilesystemFile vfFile = new VirtualFilesystemFile(fileName, fileExt, new VirtualFileContents(data));
                    dir.Children.Add(vfFile);
                }
            }
        }
コード例 #3
0
        private void ExportToDiskRecursive(string folder, VirtualFilesystemDirectory dir)
        {
            // Create the directory that this node represents.
            // If it's a directory, append the directory name to the folder and onwards!
            folder = string.Format("{0}{1}/", folder, dir.Name);
            try
            {
                Directory.CreateDirectory(folder);
            }
            catch (Exception ex)
            {
                Console.WriteLine("Caught exception while trying to create folder {0}: {1}", folder, ex.ToString());
            }

            foreach (var node in dir.Children)
            {
                VirtualFilesystemDirectory vfDir  = node as VirtualFilesystemDirectory;
                VirtualFilesystemFile      vfFile = node as VirtualFilesystemFile;

                if (vfDir != null)
                {
                    ExportToDiskRecursive(folder, vfDir);
                }
                else if (vfFile != null)
                {
                    // However, if it's a file we're going to write it to disk.
                    string filePath = string.Format("{0}{1}{2}", folder, vfFile.Name, vfFile.Extension);
                    try
                    {
                        using (EndianBinaryWriter writer = new EndianBinaryWriter(File.Create(filePath), Endian.Big))
                        {
                            writer.Write(vfFile.File.GetData());
                        }
                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine("Caught exception while trying to write file {0}: {1}", filePath, ex.ToString());
                    }
                }
            }
        }
コード例 #4
0
ファイル: RARC.cs プロジェクト: CryZe/WindEditor2
        public VirtualFilesystemDirectory ReadFile(EndianBinaryReader reader)
        {
            if (reader.ReadUInt32() != 0x52415243) // "RARC"
                throw new InvalidDataException("Invalid Magic, not a RARC File");

            uint fileSize = reader.ReadUInt32();
            reader.SkipUInt32(); // Unknown
            uint dataOffset = reader.ReadUInt32() + 0x20;
            reader.Skip(16); // Unknown - 4 unsigned ints
            uint numNodes = reader.ReadUInt32();
            reader.Skip(8); // Unknown - 2 unsigned ints
            uint fileEntryOffset = reader.ReadUInt32() + 0x20;
            reader.SkipUInt32(); // Unknown
            uint stringTableOffset = reader.ReadUInt32() + 0x20;
            reader.Skip(8); // Unknown - 2 unsigned ints.

            // Read all of the node headers.
            Node[] nodes = new Node[numNodes];

            for(int i = 0; i < numNodes; i++)
            {
                nodes[i] = new Node
                {
                    Type = new string(reader.ReadChars(4)),
                    Name = ReadStringAtOffset(reader, stringTableOffset, reader.ReadUInt32()),
                    NameHashcode = reader.ReadUInt16(),
                    Entries = new FileEntry[reader.ReadUInt16()],
                    FirstFileOffset = reader.ReadUInt32()
                };
            }

            // Create a virtual directory for every folder within the ARC before we process any of them.
            List<VirtualFilesystemDirectory> allDirs = new List<VirtualFilesystemDirectory>(nodes.Length);
            foreach(Node node in nodes)
            {
                VirtualFilesystemDirectory vfDir = new VirtualFilesystemDirectory(node.Name);
                allDirs.Add(vfDir);
            }

            for(int k = 0; k < nodes.Length; k++)
            {
                Node node = nodes[k];
                VirtualFilesystemDirectory curDir = allDirs[k];

                for(int i = 0; i < node.Entries.Length; i++)
                {
                    // Jump to the entry's offset in the file.
                    reader.BaseStream.Position = fileEntryOffset + ((node.FirstFileOffset + i) * 0x14); // 0x14 is the size of a File Entry in bytes
                    node.Entries[i] = new FileEntry
                    {
                        ID = reader.ReadUInt16(),
                        NameHashcode = reader.ReadUInt16(),
                        Type = reader.ReadByte(),
                        Padding = reader.ReadByte(),
                        Name = ReadStringAtOffset(reader, stringTableOffset, reader.ReadUInt16())
                    };

                    // Skip these ones cause I don't know how computers work.
                    if (node.Entries[i].Name == "." || node.Entries[i].Name == "..")
                        continue;

                    uint entryDataOffset = reader.ReadUInt32();
                    uint dataSize = reader.ReadUInt32();

                    // If it's a directory, then entryDataOffset contains the index of the parent node
                    if(node.Entries[i].IsDirectory)
                    {
                        node.Entries[i].SubDirIndex = entryDataOffset;
                        var newSubDir = allDirs[(int)entryDataOffset];
                        curDir.Children.Add(newSubDir);
                    }
                    else
                    {
                        node.Entries[i].Data = reader.ReadBytesAt(dataOffset + entryDataOffset, (int)dataSize);

                        string fileName = Path.GetFileNameWithoutExtension(node.Entries[i].Name);
                        string extension = Path.GetExtension(node.Entries[i].Name);

                        var vfFileContents = new VirtualFileContents(node.Entries[i].Data);
                        VirtualFilesystemFile vfFile = new VirtualFilesystemFile(fileName, extension, vfFileContents);
                        curDir.Children.Add(vfFile);
                    }
                    node.Entries[i].ZeroPadding = reader.ReadUInt32();
                }
            }

            // The ROOT directory should always be the first node. We don't have access to the node's TYPE anymore
            // so we're going to assume its always the first one listed.
            return allDirs.Count > 0 ? allDirs[0] : null;
        }
コード例 #5
0
        private void ImportFromDiskRecursive(string folder, VirtualFilesystemDirectory dir)
        {
            if (!Directory.Exists(folder))
                throw new ArgumentException("You must specify a directory that exists", "folder");

            // For each directory that is a child of the specified folder into ourselves, and then import the contents.
            DirectoryInfo dirInfo = new DirectoryInfo(folder);
            foreach(var diskDir in dirInfo.GetDirectories())
            {
                VirtualFilesystemDirectory vfDir = new VirtualFilesystemDirectory(diskDir.Name);
                dir.Children.Add(vfDir);

                ImportFromDiskRecursive(diskDir.FullName, vfDir);
            }

            foreach(var diskFile in dirInfo.GetFiles())
            {
                using(BinaryReader reader = new BinaryReader(File.Open(diskFile.FullName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)))
                {
                    string fileName = Path.GetFileNameWithoutExtension(diskFile.Name);
                    string fileExt = Path.GetExtension(diskFile.Name);

                    byte[] data = reader.ReadBytes((int)reader.BaseStream.Length);
                    VirtualFilesystemFile vfFile = new VirtualFilesystemFile(fileName, fileExt, new VirtualFileContents(data));
                    dir.Children.Add(vfFile);
                }
            }
        }
コード例 #6
0
        private void ExportToDiskRecursive(string folder, VirtualFilesystemDirectory dir)
        {
            // Create the directory that this node represents.
            // If it's a directory, append the directory name to the folder and onwards!
            folder = string.Format("{0}{1}/", folder, dir.Name);
            try
            {
                Directory.CreateDirectory(folder);
            }
            catch (Exception ex)
            {
                Console.WriteLine("Caught exception while trying to create folder {0}: {1}", folder, ex.ToString());
            }

            foreach (var node in dir.Children)
            {
                VirtualFilesystemDirectory vfDir = node as VirtualFilesystemDirectory;
                VirtualFilesystemFile vfFile = node as VirtualFilesystemFile;

                if (vfDir != null)
                {
                    ExportToDiskRecursive(folder, vfDir);
                }
                else if (vfFile != null)
                {
                    // However, if it's a file we're going to write it to disk.
                    string filePath = string.Format("{0}{1}{2}", folder, vfFile.Name, vfFile.Extension);
                    try
                    {
                        using (EndianBinaryWriter writer = new EndianBinaryWriter(File.Create(filePath), Endian.Big))
                        {
                            writer.Write(vfFile.File.GetData());
                        }
                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine("Caught exception while trying to write file {0}: {1}", filePath, ex.ToString());
                    }
                }
            }
        }
コード例 #7
0
ファイル: MapLoader.cs プロジェクト: CryZe/WindEditor2
        public Map CreateFromDirectory(WWorld world, EditorCore editorCore, string folderPath)
        {
            if (world == null)
                throw new ArgumentNullException("world", "No world to load map into specified.");

            if (string.IsNullOrEmpty(folderPath))
                throw new ArgumentException("folderPath is null or empty!");

            if (!System.IO.Directory.Exists(folderPath))
                throw new System.IO.DirectoryNotFoundException("folderPath not found, ensure the directory exists first!");

            // Calculate the Map Name from the folderPath - it should be the last segment of the folder path.s
            System.IO.DirectoryInfo rootFolderInfo = new System.IO.DirectoryInfo(folderPath);
            string mapName = rootFolderInfo.Name;

            // Sort the directories in rootFolderInfo into natural order, instead of alphabetical order which solves issues
            // where room indexes were getting remapped to the wrong one.
            IEnumerable<System.IO.DirectoryInfo> subFolders = rootFolderInfo.GetDirectories().OrderByNatural(x => x.Name);
            IEnumerable<System.IO.FileInfo> subFiles = rootFolderInfo.GetFiles().OrderByNatural(x => x.Name);

            // Maps are stored in two distinct parts. A Stage which encompasses global data for all rooms, and then
            // one or more rooms. We're going to load both the room and stage into ZArchives and then load the data
            // stored in them into different data.
            var archiveFolderMap = new Dictionary<string, VirtualFilesystemDirectory>();
            foreach (var dirInfo in subFolders)
            {
                VirtualFilesystemDirectory archive = null;

                string folderName = dirInfo.Name;
                if (folderName.ToLower().StartsWith("stage"))
                {
                    archive = new VirtualFilesystemDirectory(folderName);

                    if (archiveFolderMap.ContainsKey("stage"))
                    {
                        WLog.Warning(LogCategory.EditorCore, null, "{0} contains more than one stage archive, ignoring second...", folderPath);
                        continue;
                    }
                }
                else if (folderName.ToLower().StartsWith("room"))
                {
                    archive = new VirtualFilesystemDirectory(folderName);
                }

                // sea has LOD folders which don't have the right sub-folder setup, boo. This skips them for now,
                // maybe later we can add an ArchiveType.LOD.
                if (archive == null)
                    continue;

                // Fill the archives with their contents.
                archive.ImportFromDisk(dirInfo.FullName);
                archiveFolderMap[folderName.ToLower()] = archive;
            }

            // We're also going to try and process the files inside the folder to see if they're archives.
            foreach (var fileInfo in subFiles)
            {
                VirtualFilesystemDirectory archive = WArchiveTools.ArcUtilities.LoadArchive(fileInfo.FullName);

                // File wasn't a valid RARC archive.
                if (archive == null)
                    continue;

                if (archive.Name.ToLower().StartsWith("stage"))
                {
                    if (archiveFolderMap.ContainsKey("stage"))
                    {
                        WLog.Warning(LogCategory.EditorCore, null, "{0} contains more than one stage archive, ignoring second...", folderPath);
                        continue;
                    }
                }

                string arcName = System.IO.Path.GetFileNameWithoutExtension(fileInfo.FullName).ToLower();
                archiveFolderMap[arcName] = archive;
            }

            Map newMap = new Map();
            newMap.Name = mapName;
            newMap.ProjectFilePath = System.IO.Path.GetDirectoryName(folderPath);

            var sceneMap = CreateScenesFromArchives(newMap, archiveFolderMap);
            LoadEntities(newMap, editorCore, sceneMap, world);
            LoadModels(sceneMap);

            return newMap;
        }