Beispiel #1
0
        /// <summary>
        /// Saves the changes of the encapsulated addon to its file stream.
        /// </summary>
        /// <exception cref="IOException">Happens if there is a problem with creating the addon into its stream.</exception>
        public void Save()
        {
            OpenAddon.Sort();
            try
            {
                // It is needed to create a new, temporary file where we write the addon first
                // Without it, we would "undermount" the current file
                // And end up overwriting the addon from where ContentFile.Content gets the data we would write.
                using (FileStream newAddon = new FileStream(AddonStream.Name + "_create",
                    FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.None))
                {
                    Writer.Create(OpenAddon, newAddon);

                    // Copy the contents to the real file
                    newAddon.Seek(0, SeekOrigin.Begin);
                    AddonStream.Seek(0, SeekOrigin.Begin);
                    AddonStream.SetLength(0);
                    newAddon.CopyTo(AddonStream);
                    AddonStream.Flush();
                }
            }
            catch (IOException)
            {
                throw;
            }

            // If there were no errors creating and copying the temporary file,
            // I assume it is safe to delete.
            File.Delete(AddonStream.Name + "_create");

            _modified = false;

            // Reload the content database of the open addon
            if (AddonReader == null)
            {
                try
                {
                    AddonReader = new Reader(AddonStream);
                }
                catch (IOException)
                {
                    throw;
                }
            }
            else
            {
                AddonReader.Reparse();
            }

            // Convert all files in the open addon to addon-backed content storages
            // So after save, the application knows the file is now in the addon.
            // This also updates the fileIDs in case of a file was reordered when Sort() happened.
            foreach (Reader.IndexEntry entry in AddonReader.Index)
            {
                OpenAddon.Files.Where(f => f.Path == entry.Path).First().SwitchToAddonInstance(AddonReader, entry);
            }
        }
Beispiel #2
0
        /// <summary>
        /// Loads the specified addon from the local filesystem and encapsulates it within a realtime instance.
        /// </summary>
        /// <param name="filename">The path to the file on the local filesystem.</param>
        /// <returns>A RealtimeAddon instance.</returns>
        /// <exception cref="FileNotFoundException">Happens if the specified file does not exist.</exception>
        /// <exception cref="IOException">Thrown if there is a problem opening the specified file.</exception>
        /// <exception cref="ReaderException">Thrown if the addon reader and parser encounters an error.</exception>
        /// <exception cref="ArgumentException">Happens if a file with the same path is already added.</exception>
        /// <exception cref="WhitelistException">There is a file prohibited from storing by the global whitelist.</exception>
        /// <exception cref="IgnoredException">There is a file prohibited from storing by the addon's ignore list.</exception>
        public static RealtimeAddon Load(string filename)
        {
            if (!File.Exists(filename))
            {
                throw new FileNotFoundException("The specified file " + filename + " does not exist.");
            }

            FileStream fs;
            try
            {
                fs = new FileStream(filename, FileMode.Open, FileAccess.ReadWrite, FileShare.None);
            }
            catch (IOException)
            {
                throw;
            }

            Reader r;
            try
            {
                r = new Reader(fs);
            }
            catch (IOException)
            {
                throw;
            }
            catch (ReaderException)
            {
                throw;
            }

            Addon addon;
            try
            {
                addon = new Addon(r);
            }
            catch (ArgumentException)
            {
                throw;
            }
            catch (WhitelistException)
            {
                throw;
            }
            catch (IgnoredException)
            {
                throw;
            }

            RealtimeAddon realtime = new RealtimeAddon(addon, fs);
            realtime.AddonReader = r;
            return realtime;
        }
Beispiel #3
0
        /// <summary>
        /// Initializes a new content file using an already existing file from an addon as storage.
        /// </summary>
        /// <param name="reader">The reader of the addon.</param>
        /// <param name="index">The index of the file to use.</param>
        public ContentFile(Reader reader, Reader.IndexEntry index)
        {
            Path = index.Path;

            Storage = ContentStorageType.AddonInstance;
            AssociatedReader = reader;
            ReaderFileEntry = index.FileNumber;
        }
Beispiel #4
0
        /// <summary>
        /// Switches the current ContentFile to represent a file saved into an addon.
        /// Used after saving addons so that previous externally-saved entries are dropped in time.
        /// </summary>
        /// <param name="reader">The reader of the addon.</param>
        /// <param name="index">The index of the file to use.</param>
        public void SwitchToAddonInstance(Reader reader, Reader.IndexEntry index)
        {
            if (Storage == ContentStorageType.Filesystem)
            {
                AssociatedReader = reader;
                ReaderFileEntry = index.FileNumber;
                DisposeExternal();

                Storage = ContentStorageType.AddonInstance;
            }
            else if (Storage == ContentStorageType.AddonInstance)
            {
                // Update the entry itself. There is no need to touch files on disk.
                AssociatedReader = reader;
                ReaderFileEntry = index.FileNumber;
            }
        }
Beispiel #5
0
        /// <summary>
        /// Sets up a new instance of Addon using the data provided by the specified addon reader.
        /// </summary>
        /// <param name="reader">The addon reader which handled reading the addon file.</param>
        /// <exception cref="ArgumentException">Happens if a file with the same path is already added.</exception>
        /// <exception cref="WhitelistException">The file is prohibited from storing by the global whitelist.</exception>
        /// <exception cref="IgnoredException">The file is prohibited from storing by the addon's ignore list.</exception>
        public Addon(Reader reader)
            : this()
        {
            Author = reader.Author;
            Title = reader.Name;
            Description = reader.Description;
            Type = reader.Type;
            Tags = reader.Tags;
            AddonVersion = reader.Version;
            FormatVersion = reader.FormatVersion;
            SteamID = reader.SteamID;
            Timestamp = reader.Timestamp;

            foreach (Reader.IndexEntry file in reader.Index)
            {
                try
                {
                    CheckRestrictions(file.Path);

                    ContentFile contentFile = new ContentFile(reader, file);
                    Files.Add(contentFile);
                }
                catch (WhitelistException)
                {
                    throw;
                }
                catch (IgnoredException)
                {
                    throw;
                }
                catch (ArgumentException)
                {
                    throw;
                }
            }
        }