Example #1
0
 private IFile OpenFile(UPath file)
 {
     if (file.GetName() == ".manifest")
     {
         throw new UnauthorizedAccessException("Unable to open manifest file.");
     }
     return(new File(this, new FileEntry(this.RootFileSystem, file),
                     this.GetGuid(file.GetName())));
 }
Example #2
0
        public static void SetPath(this IFileRef self, FileEntry file)
        {
            UPath value = file.Path;

            self.dir      = "" + value.GetDirectory();
            self.fileName = value.GetName();
        }
Example #3
0
        public async Task Load(IFileSystem fileSystem, UPath filePath, LoadContext loadContext)
        {
            Stream dataStream;
            Stream indexStream;

            switch (filePath.GetName())
            {
            case "mcb1.bln":
                dataStream = await fileSystem.OpenFileAsync(filePath);

                indexStream = await fileSystem.OpenFileAsync(filePath.GetDirectory() / "mcb0.bln");

                break;

            default:
                indexStream = await fileSystem.OpenFileAsync(filePath);

                dataStream = await fileSystem.OpenFileAsync(filePath.GetDirectory() / "mcb1.bln");

                break;
            }

            if (dataStream == null || indexStream == null)
            {
                throw new InvalidOperationException("This is no Bln archive.");
            }

            Files = _bln.Load(indexStream, dataStream);
        }
Example #4
0
        internal (Guid guid, bool isLink) RetrieveManifestRecord(UPath file, bool updateLink)
        {
            this.CheckDeleted();
            var fileName = file.GetName();

            lock (this.DatabaseLock)
            {
                return(this.Manifest.Query <(Guid, bool)>(conn =>
                {
                    var record = conn.Query <ManifestRecord>(@"SELECT uuid, is_link FROM directory_manifest WHERE filename = @fileName",
                                                             new { fileName });

                    if (!record.Any() || updateLink)
                    {
                        // New file encountered.
                        bool isLink = this.CheckIsLink(file);
                        Guid guid = record.Any() ? new Guid(record.First().uuid) : Guid.NewGuid();
                        conn.Execute(@"INSERT OR REPLACE INTO directory_manifest (uuid, is_link, filename) VALUES (@guid, @isLink, @fileName)",
                                     new { guid, fileName, isLink });

                        record = conn.Query <ManifestRecord>(@"SELECT uuid, is_link FROM directory_manifest WHERE filename = @fileName",
                                                             new { fileName });
                    }

                    var _record = record.First();
                    return (new Guid(_record.uuid), _record.is_link);
                }));
            }
        }
Example #5
0
        public void TestExtensions()
        {
            {
                var path = new UPath("/a/b/c/d.txt");
                Assert.Equal(new UPath("/a/b/c"), path.GetDirectory());
                Assert.Equal("d.txt", path.GetName());
                Assert.Equal("d", path.GetNameWithoutExtension());
                Assert.Equal(".txt", path.GetExtensionWithDot());
                var newPath = path.ChangeExtension(".zip");
                Assert.Equal("/a/b/c/d.zip", newPath.FullName);
                Assert.Equal(new UPath("a/b/c/d.txt"), path.ToRelative());
                Assert.Equal(path, path.AssertAbsolute());
                Assert.Throws <ArgumentNullException>(() => new UPath().AssertNotNull());
                Assert.Throws <ArgumentException>(() => new UPath("not_absolute").AssertAbsolute());
            }

            {
                var path = new UPath("d.txt");
                Assert.Equal(UPath.Empty, path.GetDirectory());
                Assert.Equal("d.txt", path.GetName());
                Assert.Equal("d", path.GetNameWithoutExtension());
                Assert.Equal(".txt", path.GetExtensionWithDot());
                var newPath = path.ChangeExtension(".zip");
                Assert.Equal("d.zip", newPath.FullName);
                Assert.Equal(new UPath("d.txt"), path.ToRelative());
            }
        }
Example #6
0
        public FileRenamedEventArgs(IFileSystem fileSystem, WatcherChangeTypes changeType, UPath fullPath, UPath oldFullPath)
            : base(fileSystem, changeType, fullPath)
        {
            fullPath.AssertNotNull(nameof(oldFullPath));
            fullPath.AssertAbsolute(nameof(oldFullPath));

            OldFullPath = oldFullPath;
            OldName     = oldFullPath.GetName();
        }
Example #7
0
        /// <summary>
        /// Determines whether the specified mount name is mounted.
        /// </summary>
        /// <param name="name">The mount name.</param>
        /// <returns><c>true</c> if the specified name is mounted; otherwise, <c>false</c>.</returns>
        public bool IsMounted(UPath name)
        {
            AssertMountName(name);
            var mountName = name.GetName();

            lock (_mounts)
            {
                return(_mounts.ContainsKey(mountName));
            }
        }
Example #8
0
        public Task Save(IFileSystem fileSystem, UPath savePath, SaveContext saveContext)
        {
            var texPath = savePath;
            var pltPath = $"{savePath.GetDirectory()}/../Palettes(NW4R)/{savePath.GetName()}";

            var texStream = fileSystem.OpenFile(texPath, FileMode.Create, FileAccess.Write);
            var pltStream = Images[0].ImageInfo.HasPaletteInformation ? fileSystem.OpenFile(pltPath, FileMode.Create, FileAccess.Write) : null;

            _img.Save(texStream, pltStream, Images[0].ImageInfo);

            return(Task.CompletedTask);
        }
Example #9
0
        public async Task Load(IFileSystem fileSystem, UPath filePath, LoadContext loadContext)
        {
            var texPath = filePath;
            var pltPath = $"{filePath.GetDirectory()}/../Palettes(NW4R)/{filePath.GetName()}";

            var texStream = await fileSystem.OpenFileAsync(texPath);

            var pltStream = fileSystem.FileExists(pltPath) ? await fileSystem.OpenFileAsync(pltPath) : null;

            Images = new List <IKanvasImage> {
                new KanvasImage(EncodingDefinition, _img.Load(texStream, pltStream))
            };
        }
Example #10
0
        /// <summary>
        /// Unmounts the specified mount name and its attached filesystem.
        /// </summary>
        /// <param name="name">The mount name.</param>
        /// <exception cref="System.ArgumentException">The mount with the name `{mountName}` was not found</exception>
        public void Unmount(UPath name)
        {
            AssertMountName(name);
            var mountName = name.GetName();

            lock (_mounts)
            {
                if (!_mounts.Remove(mountName))
                {
                    throw new ArgumentException("The mount with the name `{mountName}` was not found");
                }
            }
        }
Example #11
0
        internal void UpdateLinkCache(UPath filePath, bool isLink)
        {
            this.CheckDeleted();

            lock (this.DatabaseLock)
            {
                this.Manifest.Execute(connection =>
                {
                    connection.Execute(
                        @"UPDATE directory_manifest SET is_link = @isLink WHERE filename = @file",
                        new { isLink, file = filePath.GetName() });
                });
            }
        }
Example #12
0
        private IFile OpenFile(UPath file, bool updateLink)
        {
            this.CheckDeleted();
            if (file.GetName() == ".manifest")
            {
                throw new UnauthorizedAccessException("Unable to open manifest file.");
            }

            (Guid guid, bool isLink) = this.RetrieveManifestRecord(file, updateLink);

            return(isLink switch
            {
                false => new File(this, new FileEntry(this.RootFileSystem, file), guid),
                true => new Link(this, new FileEntry(this.RootFileSystem, file), guid)
            });
Example #13
0
        public FileChangedEventArgs(IFileSystem fileSystem, WatcherChangeTypes changeType, UPath fullPath)
        {
            if (fileSystem == null)
            {
                throw new ArgumentNullException(nameof(fileSystem));
            }

            fullPath.AssertNotNull(nameof(fullPath));
            fullPath.AssertAbsolute(nameof(fullPath));

            FileSystem = fileSystem;
            ChangeType = changeType;
            FullPath   = fullPath;
            Name       = fullPath.GetName();
        }
Example #14
0
        private void SaveFileAs()
        {
            var sfd = new SaveFileDialog
            {
                InitialDirectory = _openedFile.GetDirectory().FullName,
                FileName         = _openedFile.GetName()
            };

            if (sfd.ShowDialog() != DialogResult.OK)
            {
                MessageBox.Show("An error occurred when selecting a save path.", "Save Error", MessageBoxButtons.OK,
                                MessageBoxIcon.Error);
                return;
            }

            SaveFile(sfd.FileName);
        }
Example #15
0
        public Task <LoadResult> LoadFile(string file, Guid pluginId, LoadFileContext loadFileContext)
        {
            // 1. Get UPath
            var path = new UPath(file);

            // If file is already loaded
            if (IsLoaded(path))
            {
                return(Task.FromResult(new LoadResult(GetLoadedFile(path))));
            }

            // 2. Create file system action
            var fileSystemAction = new Func <IStreamManager, IFileSystem>(streamManager =>
                                                                          FileSystemFactory.CreatePhysicalFileSystem(path.GetDirectory(), streamManager));

            // 3. Load file
            // Physical files don't have a parent, if loaded like this
            return(LoadFile(fileSystemAction, path.GetName(), null, pluginId, loadFileContext));
        }
Example #16
0
        public async Task Load(IFileSystem fileSystem, UPath filePath, LoadContext loadContext)
        {
            Stream texStream;
            Stream texListStream;

            if (filePath.GetName() == "textures")
            {
                texStream = await fileSystem.OpenFileAsync(filePath);

                texListStream = await fileSystem.OpenFileAsync(filePath.GetDirectory() / "texture_table");
            }
            else
            {
                texStream = await fileSystem.OpenFileAsync(filePath.GetDirectory() / "textures");

                texListStream = await fileSystem.OpenFileAsync(filePath);
            }

            Files = _arc.Load(texStream, texListStream);
        }
Example #17
0
        public Task Save(IFileSystem fileSystem, UPath savePath, SaveContext saveContext)
        {
            Stream texStream;
            Stream texListStream;

            if (savePath.GetName() == "textures")
            {
                texStream     = fileSystem.OpenFile(savePath, FileMode.Create, FileAccess.Write);
                texListStream = fileSystem.OpenFile(savePath.GetDirectory() / "texture_table", FileMode.Create, FileAccess.Write);
            }
            else
            {
                texStream     = fileSystem.OpenFile(savePath.GetDirectory() / "textures", FileMode.Create, FileAccess.Write);
                texListStream = fileSystem.OpenFile(savePath, FileMode.Create, FileAccess.Write);
            }

            _arc.Save(texStream, texListStream, Files);

            return(Task.CompletedTask);
        }
Example #18
0
        private IFile OpenFile(UPath file, Guid inheritGuid)
        {
            this.CheckDeleted();
            if (this.ContainsDirectory(file.GetName()))
            {
                throw new IOException("Tried to open a directory as a file.");
            }
            var fileEntry = new FileEntry(this.RootFileSystem, file);
            var rawInfo   = new FileInfo(this.RootFileSystem.ConvertPathToInternal(fileEntry.Path));

            if (this.FileGuidProvider.TryGetGuid(rawInfo, out Guid guid))
            {
                return(new File(this, fileEntry, guid));
            }
            guid = inheritGuid;
            if (rawInfo.Exists)
            {
                this.FileGuidProvider.SetGuid(rawInfo, guid);
            }
            return(new File(this, fileEntry, guid));
        }
Example #19
0
        /// <summary>
        /// Mounts a filesystem for the specified mount name.
        /// </summary>
        /// <param name="name">The mount name.</param>
        /// <param name="fileSystem">The file system.</param>
        /// <exception cref="System.ArgumentNullException">fileSystem</exception>
        /// <exception cref="System.ArgumentException">
        /// Cannot recursively mount the filesystem to self - fileSystem
        /// or
        /// There is already a mount with the same name: `{mountName}` - name
        /// </exception>
        public void Mount(UPath name, IFileSystem fileSystem)
        {
            if (fileSystem == null)
            {
                throw new ArgumentNullException(nameof(fileSystem));
            }
            if (fileSystem == this)
            {
                throw new ArgumentException("Cannot recursively mount the filesystem to self", nameof(fileSystem));
            }
            AssertMountName(name);
            var mountName = name.GetName();

            lock (_mounts)
            {
                if (_mounts.ContainsKey(mountName))
                {
                    throw new ArgumentException("There is already a mount with the same name: `{mountName}`", nameof(name));
                }
                _mounts.Add(mountName, fileSystem);
            }
        }
Example #20
0
        public Task Save(IFileSystem fileSystem, UPath savePath, SaveContext saveContext)
        {
            Stream dataOutput;
            Stream indexOutput;

            switch (savePath.GetName())
            {
            case "mcb1.bln":
                dataOutput  = fileSystem.OpenFile(savePath, FileMode.Create);
                indexOutput = fileSystem.OpenFile(savePath.GetDirectory() / "mcb0.bln", FileMode.Create);
                break;

            default:
                indexOutput = fileSystem.OpenFile(savePath, FileMode.Create);
                dataOutput  = fileSystem.OpenFile(savePath.GetDirectory() / "mcb1.bln", FileMode.Create);
                break;
            }

            _bln.Save(indexOutput, dataOutput, Files);

            return(Task.CompletedTask);
        }
Example #21
0
        private static bool SpecialDirectoryExists(UPath path)
        {
            // /drive or / can be read
            if (path == PathDrivePrefixOnWindows || path == UPath.Root)
            {
                return(true);
            }

            // If /xxx, invalid (parent folder is /)
            var parentDirectory = path.GetDirectory();

            if (parentDirectory == UPath.Root)
            {
                return(false);
            }

            var dirName = path.GetName();

            // Else check that we have a valid drive path (e.g /drive/c)
            return(parentDirectory == PathDrivePrefixOnWindows &&
                   dirName.Length == 1 &&
                   DriveInfo.GetDrives().Any(p => char.ToLowerInvariant(p.Name[0]) == char.ToLowerInvariant(dirName[0])));
        }
Example #22
0
        private async Task <SaveResult> ReloadInternalAsync(IStateInfo stateInfo, IFileSystem destinationFileSystem, UPath savePath,
                                                            IProgressContext progress)
        {
            // 1. Reload current state
            var temporaryStreamProvider = stateInfo.StreamManager.CreateTemporaryStreamProvider();

            savePath = stateInfo.HasParent ? savePath : savePath.GetName();

            var internalDialogManager = new InternalDialogManager(_dialogManager, stateInfo.DialogOptions);
            var loadContext           = new LoadContext(temporaryStreamProvider, progress, internalDialogManager);
            var reloadResult          = await TryLoadStateAsync(stateInfo.PluginState, destinationFileSystem, savePath, loadContext);

            if (!reloadResult.IsSuccessful)
            {
                return(new SaveResult(reloadResult.Exception));
            }

            // 2. Set new file input, if state was loaded from a physical medium
            if (!stateInfo.HasParent)
            {
                stateInfo.SetNewFileInput(destinationFileSystem, savePath);
            }

            // 3. Reload all child states
            foreach (var archiveChild in stateInfo.ArchiveChildren)
            {
                var destination       = CreateDestinationFileSystem(archiveChild, archiveChild.FilePath);
                var reloadChildResult = await ReloadInternalAsync(archiveChild, destination, archiveChild.FilePath, progress);

                if (!reloadChildResult.IsSuccessful)
                {
                    return(reloadChildResult);
                }
            }

            return(SaveResult.SuccessfulResult);
        }
Example #23
0
        private SearchPattern(ref UPath path, ref string searchPattern)
        {
            path.AssertAbsolute();
            if (searchPattern == null)
            {
                throw new ArgumentNullException(nameof(searchPattern));
            }

            _exactMatch = null;
            _regexMatch = null;

            //Optimized path, most common case
            if (searchPattern == "*" && path == UPath.Root)
            {
                return;
            }

            if (searchPattern.StartsWith("/"))
            {
                throw new ArgumentException($"The search pattern `{searchPattern}` cannot start by an absolute path `/`");
            }

            searchPattern = searchPattern.Replace('\\', '/');

            // If the path contains any directory, we need to concatenate the directory part with the input path
            if (searchPattern.IndexOf('/') > 0)
            {
                var pathPattern = new UPath(searchPattern);
                var directory   = pathPattern.GetDirectory();
                if (!directory.IsNull && !directory.IsEmpty)
                {
                    path /= directory;
                }
                searchPattern = pathPattern.GetName();

                // If the search pattern is again a plain any, optimized path
                if (searchPattern == "*")
                {
                    return;
                }
            }

            var           startIndex = 0;
            StringBuilder builder    = null;

            try
            {
                int nextIndex;
                while ((nextIndex = searchPattern.IndexOfAny(SpecialChars, startIndex)) >= 0)
                {
                    if (builder == null)
                    {
                        builder = new StringBuilder();
                        builder.Append("^");
                    }

                    var lengthToEscape = nextIndex - startIndex;
                    if (lengthToEscape > 0)
                    {
                        var toEscape = Regex.Escape(searchPattern.Substring(startIndex, lengthToEscape));
                        builder.Append(toEscape);
                    }

                    var c = searchPattern[nextIndex];
                    var regexPatternPart = c == '*' ? ".*" : ".";
                    builder.Append(regexPatternPart);

                    startIndex = nextIndex + 1;
                }
                if (builder == null)
                {
                    _exactMatch = searchPattern;
                }
                else
                {
                    var length = searchPattern.Length - startIndex;
                    if (length > 0)
                    {
                        var toEscape = Regex.Escape(searchPattern.Substring(startIndex, length));
                        builder.Append(toEscape);
                    }

                    builder.Append("$");

                    var regexPattern = builder.ToString();
                    _regexMatch = new Regex(regexPattern);
                }
            }
            finally
            {
                if (builder != null)
                {
                    builder.Length = 0;
                }
            }
        }
Example #24
0
        private void ExtractImage(string imageIndexArgument, UPath filePath)
        {
            if (!int.TryParse(imageIndexArgument, out var imageIndex))
            {
                Console.WriteLine($"'{imageIndexArgument}' is not a valid number.");
                return;
            }

            if (imageIndex >= _imageState.Images.Count)
            {
                Console.WriteLine($"Index '{imageIndex}' was out of bounds.");
                return;
            }

            var destinationFileSystem = FileSystemFactory.CreateSubFileSystem(filePath.GetDirectory().FullName, new StreamManager());

            ExtractImageInternal(_imageState.Images[imageIndex], destinationFileSystem, filePath.GetName());
        }
Example #25
0
        private async Task <SaveResult> SaveAndReplaceStateAsync(IStateInfo stateInfo, IFileSystem destinationFileSystem, UPath savePath, SaveInfo saveInfo)
        {
            var saveState = stateInfo.PluginState as ISaveFiles;

            // 1. Save state to a temporary destination
            var temporaryContainer = _streamMonitor.CreateTemporaryFileSystem();
            var saveStateResult    = await TrySaveState(saveState, temporaryContainer, savePath.GetName(), saveInfo);

            if (!saveStateResult.IsSuccessful)
            {
                return(saveStateResult);
            }

            // TODO: If reload fails then the original files get closed already, which makes future save actions impossible due to disposed streams

            // 2. Dispose of all streams in this state
            _streamMonitor.GetStreamManager(temporaryContainer).ReleaseAll();
            stateInfo.StreamManager.ReleaseAll();

            // 3. Replace files in destination file system
            var moveResult = await MoveFiles(stateInfo, temporaryContainer, destinationFileSystem);

            if (!moveResult.IsSuccessful)
            {
                return(moveResult);
            }

            // 4. Release temporary destination
            _streamMonitor.ReleaseTemporaryFileSystem(temporaryContainer);

            return(SaveResult.SuccessfulResult);
        }
Example #26
0
        private SearchPattern(ref UPath path, ref string searchPattern)
        {
            path.AssertAbsolute();
            if (searchPattern == null)
            {
                throw new ArgumentNullException(nameof(searchPattern));
            }

            _exactMatch = null;
            _regexMatch = null;

            //Optimized path, most common case
            if (searchPattern == "*" && path == UPath.Root)
            {
                return;
            }

            if (searchPattern.StartsWith("/"))
            {
                throw new ArgumentException($"The search pattern `{searchPattern}` cannot start by an absolute path `/`");
            }

            // Normalize path separators
            searchPattern = searchPattern.Replace('\\', '/');

            // If the path contains any directory, we need to concatenate the directory part with the input path (?)
            if (searchPattern.IndexOf('/') > 0)
            {
                var pathPattern = new UPath(searchPattern);
                var directory   = pathPattern.GetDirectory();
                if (!directory.IsNull && !directory.IsEmpty)
                {
                    path /= directory;
                }
                searchPattern = pathPattern.GetName();

                // If the search pattern is again a plain any, optimized path
                if (searchPattern == "*")
                {
                    return;
                }
            }

            var  regexBuilder      = new StringBuilder("^");
            bool containsWildcards = false;

            // Loop through parts of searchPattern separated by wildcards
            for (int index = 0, nextWildcard = 0; nextWildcard != -1; index = nextWildcard + 1)
            {
                // Next wildcard occurence
                nextWildcard = searchPattern.IndexOfAny(WildcardChars, index);

                // Escape & append text up to next wildcard
                // If no new wildcard, append up to end of string
                var endOfPart = nextWildcard != -1 ? nextWildcard : searchPattern.Length;
                regexBuilder.Append(Regex.Escape(searchPattern.Substring(index, endOfPart - index)));

                // Convert & append wildcard, if applicable
                if (nextWildcard != -1)
                {
                    var wc = searchPattern[nextWildcard];
                    var regexPatternPart = wc switch
                    {
                        '*' => ".*",
                        '?' => ".",
                        _ => throw new ArgumentException($"Unknown wildcard: {wc}")
                    };
                    regexBuilder.Append(regexPatternPart);
                    containsWildcards = true;
                }
            }

            regexBuilder.Append("$");

            if (!containsWildcards)
            {
                _exactMatch = searchPattern;
            }
            else
            {
                _regexMatch = new Regex(regexBuilder.ToString());
            }
        }
    }
Example #27
0
        private void ListFiles(IFileSystem fileSystem, UPath listPath, int iteration = 0)
        {
            var prefix = new string(' ', iteration * 2);

            Console.WriteLine(prefix + (iteration == 0 ? _stateInfo.FilePath.ToRelative() : listPath.GetName()));

            // Print files
            foreach (var file in fileSystem.EnumeratePaths(listPath, "*", SearchOption.TopDirectoryOnly, SearchTarget.File))
            {
                Console.WriteLine(prefix + "  " + file.GetName());
            }

            // Print directories
            foreach (var dir in fileSystem.EnumeratePaths(listPath, "*", SearchOption.AllDirectories, SearchTarget.Directory))
            {
                if (listPath != dir && listPath == dir.GetDirectory())
                {
                    ListFiles(fileSystem, dir, iteration + 1);
                }
            }
        }
Example #28
0
        public async Task Load(IFileSystem fileSystem, UPath filePath, LoadContext loadContext)
        {
            var fileStream = await fileSystem.OpenFileAsync(filePath);

            Files = _hfs.Load(fileStream, filePath.GetName());
        }