using System; using System.Collections.Generic; using System.IO; using System.Linq; using Ceras; using Compression.BSA; using Wabbajack.Common; using Wabbajack.Lib.Downloaders; using Wabbajack.VirtualFileSystem; namespace Wabbajack.Lib { public class RawSourceFile { // ToDo // Make readonly public string Path; public RawSourceFile(VirtualFile file, string path) { File = file; Path = path; } public string AbsolutePath => File.StagedPath; public VirtualFile File { get; } public string Hash => File.Hash; public T EvolveTo<T>() where T : Directive, new() { var v = new T(); v.To = Path; v.Hash = Hash; v.Size = File.Size; return v; } } public class ModList { /// <summary> /// Archives required by this modlist /// </summary> public List<Archive> Archives; /// <summary> /// The Mod Manager used to create the modlist /// </summary> public ModManager ModManager; /// <summary> /// The game variant to which this game applies /// </summary> public Game GameType; /// <summary> /// The build version of Wabbajack used when compiling the Modlist /// </summary> public string WabbajackVersion; /// <summary> /// Install directives /// </summary> public List<Directive> Directives; /// <summary> /// Name of the ModList /// </summary> public string Name; /// <summary> /// Author of the ModList /// </summary> public string Author; /// <summary> /// Description of the ModList /// </summary> public string Description; /// <summary> /// Hash of the banner-image /// </summary> public string Image; /// <summary> /// Website of the ModList /// </summary> public string Website; /// <summary> /// readme path or website /// </summary> public string Readme; /// <summary> /// The size of all the archives once they're downloaded /// </summary> public long DownloadSize => Archives.Sum(a => a.Size); /// <summary> /// The size of all the files once they are installed (excluding downloaded archives) /// </summary> public long InstallSize => Directives.Sum(s => s.Size); /// <summary> /// Estimate of the amount of space required in the VFS staging folders during installation /// </summary> public long ScratchSpaceSize => Archives.OrderByDescending(a => a.Size) .Take(Environment.ProcessorCount) .Sum(a => a.Size) * 2; /// <summary> /// Whether readme is a website /// </summary> public bool ReadmeIsWebsite; public ModList Clone() { return new MemoryStream(this.ToCERAS(CerasConfig.Config)).FromCERAS<ModList>(CerasConfig.Config); } } public class Directive { /// <summary> /// location the file will be copied to, relative to the install path. /// </summary> public string To; public long Size; public string Hash; } public class IgnoredDirectly : Directive { public string Reason; } public class NoMatch : IgnoredDirectly { } public class InlineFile : Directive { /// <summary> /// Data that will be written as-is to the destination location; /// </summary> public string SourceDataID; } public class ArchiveMeta : Directive { public string SourceDataID; } public enum PropertyType { Banner, Readme } /// <summary> /// File meant to be extracted before the installation /// </summary> public class PropertyFile : InlineFile { public PropertyType Type; } public class CleanedESM : InlineFile { public string SourceESMHash; } /// <summary> /// A file that has the game and MO2 folders remapped on installation /// </summary> public class RemappedInlineFile : InlineFile { } public class SteamMeta : ArchiveMeta { public int ItemID; /// <summary> /// Size is in bytes /// </summary> public int Size; } [MemberConfig(TargetMember.All)] public class FromArchive : Directive { private string _fullPath; /// <summary> /// MurMur3 hash of the archive this file comes from /// </summary> public string[] ArchiveHashPath; [Exclude] public VirtualFile FromFile; [Exclude] public string FullPath { get { if (_fullPath == null) _fullPath = string.Join("|", ArchiveHashPath); return _fullPath; } } } public class CreateBSA : Directive { public string TempID; public uint Type; public ArchiveStateObject State { get; set; } public List<FileStateObject> FileStates { get; set; } } public class PatchedFromArchive : FromArchive { /// <summary> /// The file to apply to the source file to patch it /// </summary> public string PatchID; [Exclude] public string FromHash; } public class SourcePatch { public string RelativePath; public string Hash; } public class MergedPatch : Directive { public List<SourcePatch> Sources; public string PatchID; } public class Archive { /// <summary> /// MurMur3 Hash of the archive /// </summary> public string Hash { get; set; } /// <summary> /// Meta INI for the downloaded archive /// </summary> public string Meta { get; set; } /// <summary> /// Human friendly name of this archive /// </summary> public string Name { get; set; } public long Size { get; set; } public AbstractDownloadState State { get; set; } } public class IndexedArchive { public dynamic IniData; public string Meta; public string Name; public VirtualFile File { get; internal set; } } /// <summary> /// A archive entry /// </summary> public class IndexedEntry { /// <summary> /// MurMur3 hash of this file /// </summary> public string Hash; /// <summary> /// Path in the archive to this file /// </summary> public string Path; /// <summary> /// Size of the file (uncompressed) /// </summary> public long Size; } public class IndexedArchiveEntry : IndexedEntry { public string[] HashPath; } /// <summary> /// Data found inside a BSA file in an archive /// </summary> public class BSAIndexedEntry : IndexedEntry { /// <summary> /// MurMur3 hash of the BSA this file comes from /// </summary> public string BSAHash; } }