public static void Write(this BinaryWriter writer, AccurateVersion version)
 {
     writer.Write(version.Main);
     writer.Write(version.Major);
     writer.Write(version.Minor);
     writer.Write(version.Revision);
 }
예제 #2
0
        /// <summary>
        /// Saves a JSON string to a settings file.
        /// </summary>
        /// <param name="json">The string to save.</param>
        /// <param name="fileName">The file name to save to.</param>
        /// <param name="fileVersion">The desired file version.</param>
        public static FileInfo SaveToFile(string json, string fileName, AccurateVersion fileVersion)
        {
            var file = new FileInfo(fileName);

            SaveToFile(json, file, fileVersion);
            return(file);
        }
예제 #3
0
        /// <param name="factorioVersion">
        /// The version of Factorio getting managed<br/>
        /// Only considers major version
        /// </param>
        public ModManager(AccurateVersion factorioVersion)
        {
            _families = new Dictionary <string, ModFamily>();
            Families  = _families.Values;

            FactorioVersion = factorioVersion.ToFactorioMajor();
        }
예제 #4
0
        /// <summary>
        /// Loads a mod settings file into a JSON string.
        /// </summary>
        /// <param name="file">The file to load.</param>
        /// <param name="fileVersion">Out. The version of the file.</param>
        /// <param name="formatting">Optional. Formatting of the JSON string.</param>
        public static string LoadFile(FileInfo file, out AccurateVersion fileVersion, Formatting formatting = Formatting.Indented)
        {
            using (var stream = file.OpenRead())
            {
                using (var reader = new AccurateBinaryReader(stream))
                {
                    fileVersion = reader.ReadVersion();
                    if (!FileVersionSupported(fileVersion))
                    {
                        throw new SerializerException("File version not supported.");
                    }
                    if (fileVersion >= ByteSwitch)
                    {
                        reader.ReadByte();
                    }

                    var sb     = new StringBuilder();
                    var sw     = new StringWriter(sb);
                    var writer = new JsonTextWriter(sw)
                    {
                        Formatting = formatting
                    };

                    try
                    {
                        ReadPropertyTree(reader, writer);
                        return(sw.ToString());
                    }
                    catch (Exception ex) when(ex is EndOfStreamException || ex is JsonException)
                    {
                        throw new SerializerException("Specified file is not a valid settings file.", ex);
                    }
                }
            }
        }
예제 #5
0
        /// <summary>
        /// Saves a JSON string to a settings file.
        /// </summary>
        /// <param name="json">The string to save.</param>
        /// <param name="file">The file to save to.</param>
        /// <param name="fileVersion">The desired file version.</param>
        public static void SaveToFile(string json, FileInfo file, AccurateVersion fileVersion)
        {
            if (!file.Directory.Exists)
            {
                file.Directory.Create();
            }
            using (var stream = file.OpenWrite())
            {
                using (var writer = new AccurateBinaryWriter(stream))
                {
                    writer.Write(fileVersion);
                    if (fileVersion > ByteSwitch)
                    {
                        writer.Write(byte.MinValue);
                    }

                    if (string.IsNullOrWhiteSpace(json))
                    {
                        writer.Write((byte)PropertyTreeType.None);
                        return;
                    }

                    try
                    {
                        var token = JObject.Parse(json);
                        WritePropertyTree(writer, token);
                    }
                    catch (Exception ex) when(ex is InvalidEnumArgumentException || ex is JsonException)
                    {
                        throw new ArgumentException("Invalid JSON string.", nameof(file), ex);
                    }
                }
            }
        }
예제 #6
0
 private ModDefinition(int uid, string name, ExportMode exportMode, AccurateVersion version, AccurateVersion factorioVersion)
 {
     Uid             = uid;
     Name            = name;
     ExportMode      = exportMode;
     Version         = version;
     FactorioVersion = factorioVersion;
 }
예제 #7
0
 ModManager GetModManager(AccurateVersion factorioVersion)
 {
     if (!_modManagers.TryGetValue(factorioVersion, out var result))
     {
         result = new ModManager(factorioVersion);
         _modManagers.Add(factorioVersion, result);
     }
     return(result);
 }
예제 #8
0
        /// <summary>
        /// Checks if a mod with the specified name and version is managed by this manager
        /// </summary>
        public bool Contains(string name, AccurateVersion version)
        {
            if (TryGetFamily(name, out var family))
            {
                return(family.Contains(version));
            }

            return(false);
        }
예제 #9
0
        private async static Task <string?> GetPackageLinkAsync(Platform platform, AccurateVersion from, AccurateVersion to, string username, string token)
        {
            string url      = $"{DownloadUrl}?apiVersion=2&username={username}&token={token}&package={platform.ToActualString()}&from={from}&to={to}";
            string document = await WebHelper.RequestDocumentAsync(url);

            var response = JsonConvert.DeserializeObject <string[]>(document);

            return(response?[0]);
        }
예제 #10
0
        /// <summary>
        /// Downloads a specific release of Factorio.
        /// </summary>
        /// <param name="version">The version of Factorio.</param>
        /// <param name="build">The build of Factorio.</param>
        /// <param name="platform">The target platform.</param>
        /// <param name="username">Username for authentication.</param>
        /// <param name="token">Login token for authentication.</param>
        /// <param name="fileName">The destination file name.</param>
        public async static Task <FileInfo> DownloadReleaseAsync(AccurateVersion version, FactorioBuild build, Platform platform, string username, string token, string fileName,
                                                                 CancellationToken cancellationToken = default, IProgress <double>?progress = null)
        {
            var file = new FileInfo(fileName);

            await DownloadReleaseAsync(version, build, platform, username, token, file, cancellationToken, progress);

            return(file);
        }
예제 #11
0
 internal ModReleaseInfo(AccurateVersion version, string downloadUrl, string fileName, DateTime releaseDate, string checksum, BaseTypes.ModInfo info)
 {
     Version     = version;
     DownloadUrl = ModApi.BaseUrl + downloadUrl;
     FileName    = fileName;
     ReleaseDate = releaseDate;
     Checksum    = checksum;
     Info        = info;
 }
예제 #12
0
        /// <summary>
        /// Checks if a mod with the specified name and version is managed by this manager
        /// </summary>
        public bool Contains(string name, AccurateVersion version, [NotNullWhen(true)] out Mod?mod)
        {
            if (TryGetFamily(name, out var family))
            {
                return(family.Contains(version, out mod));
            }

            mod = null;
            return(false);
        }
예제 #13
0
        /// <summary>
        /// Downloads an update package.
        /// </summary>
        /// <param name="platform">The target platform.</param>
        /// <param name="from">The version to update from.</param>
        /// <param name="to">The version to update to.</param>
        /// <param name="fileName">The destination file name.</param>
        /// <param name="username">Username for authentication.</param>
        /// <param name="token">Login token for authentication.</param>
        public async static Task <FileInfo> DownloadUpdatePackageAsync(
            Platform platform, AccurateVersion from, AccurateVersion to, string fileName, string username, string token,
            CancellationToken cancellationToken = default, IProgress <double>?progress = null)
        {
            var file = new FileInfo(fileName);

            await DownloadUpdatePackageAsync(platform, from, to, file, username, token, cancellationToken, progress);

            return(file);
        }
예제 #14
0
 private SemaphoreSlim GetSync(AccurateVersion factorioVersion)
 {
     factorioVersion = factorioVersion.ToFactorioMajor();
     if (!_syncs.TryGetValue(factorioVersion, out var sync))
     {
         sync = new SemaphoreSlim(1, 1);
         _syncs.Add(factorioVersion, sync);
     }
     return(sync);
 }
예제 #15
0
        /// <summary>
        /// Gets the mod manager associated with a specific version of Factorio<br/>
        /// Creates a new mod manager if none has been created for the specified version yet
        /// </summary>
        public ModManager GetModManager(AccurateVersion factorioVersion)
        {
            factorioVersion = factorioVersion.ToFactorioMajor();

            if (!_modManagers.TryGetValue(factorioVersion, out var result))
            {
                result = new ModManager(factorioVersion);
                _modManagers.Add(factorioVersion, result);

                OnModManagerCreated(result);
            }
            return(result);
        }
예제 #16
0
        /// <summary>
        /// Downloads an update package.
        /// </summary>
        /// <param name="platform">The target platform.</param>
        /// <param name="from">The version to update from.</param>
        /// <param name="to">The version to update to.</param>
        /// <param name="file">The destination file.</param>
        /// <param name="username">Username for authentication.</param>
        /// <param name="token">Login token for authentication.</param>
        public async static Task DownloadUpdatePackageAsync(Platform platform, AccurateVersion from, AccurateVersion to, FileInfo file, string username, string token,
                                                            CancellationToken cancellationToken = default, IProgress <double> progress = null)
        {
            try
            {
                string url = await GetPackageLinkAsync(platform, from, to, username, token);

                await WebHelper.DownloadFileAsync(url, file, cancellationToken, progress);
            }
            catch (WebException ex)
            {
                throw ApiException.FromWebException(ex);
            }
        }
예제 #17
0
        /// <summary>
        /// Gets the latest release of the mod that is compatible with a given version of Factorio
        /// </summary>
        public static ModReleaseInfo?GetLatestRelease(this ApiModInfo info, AccurateVersion factorioVersion)
        {
            ModReleaseInfo?max = null;

            if (!(info.Releases is null))
            {
                foreach (var release in info.Releases.Where(r => r.Info.FactorioVersion == factorioVersion))
                {
                    if ((max is null) || (release.Version > max.Value.Version))
                    {
                        max = release;
                    }
                }
            }
            return(max);
        }
예제 #18
0
        /// <summary>
        /// Downloads a specific release of Factorio.
        /// </summary>
        /// <param name="version">The version of Factorio.</param>
        /// <param name="build">The build of Factorio.</param>
        /// <param name="platform">The target platform.</param>
        /// <param name="username">Username for authentication.</param>
        /// <param name="token">Login token for authentication.</param>
        /// <param name="file">The destination file.</param>
        public async static Task DownloadReleaseAsync(AccurateVersion version, FactorioBuild build, Platform platform, string username, string token, FileInfo file,
                                                      CancellationToken cancellationToken = default, IProgress <double>?progress = null)
        {
            string versionStr  = version.ToString(3);
            string buildStr    = build.ToActualString();
            string platformStr = platform.ToActualString();
            string url         = $"{DownloadUrl}/{versionStr}/{buildStr}/{platformStr}?username={username}&token={token}";

            try
            {
                await WebHelper.DownloadFileAsync(url, file, cancellationToken, progress);
            }
            catch (WebException ex)
            {
                throw ApiException.FromWebException(ex);
            }
        }
예제 #19
0
        public ModDefinition(string name, ExportMode exportMode, AccurateVersion versionOrFactorioVersion = default)
        {
            Uid = GlobalUid;
            GlobalUid++;

            Name       = name;
            ExportMode = exportMode;

            exportMode &= ExportMode.Mask;
            if (exportMode == ExportMode.SpecificVersion)
            {
                Version = versionOrFactorioVersion;
            }
            else if (exportMode == ExportMode.FactorioVersion)
            {
                FactorioVersion = versionOrFactorioVersion;
            }
        }
        /// <summary>
        /// Loads mods into the manager from the location specified by the location manager
        /// </summary>
        public static async Task LoadModsAsync(this Manager manager, LocationManager locations)
        {
            var dir = locations.GetModDir();

            foreach (var subDir in dir.EnumerateDirectories())
            {
                // Directory is only valid if its name is a major version
                if (AccurateVersion.TryParse(subDir.Name, out var version) &&
                    (version.ToMajor() == version))
                {
                    var modManager = manager.GetModManager(version);

                    foreach (var fsi in subDir.EnumerateFileSystemInfos())
                    {
                        var(success, mod) = await Mod.TryLoadAsync(fsi);

                        if (success)
                        {
                            modManager.Add(mod);
                            Log.Verbose($"Successfully loaded mod {mod.Name} version {mod.Version}");
                        }
                    }

                    // Load state
                    var file = new FileInfo(Path.Combine(subDir.FullName, "mod-list.json"));
                    if (file.Exists)
                    {
                        try
                        {
                            var state = await ModFamilyStateGrouping.FromFileAsync(file);

                            state.ApplyToManager(modManager);
                            Log.Verbose($"Successfully loaded mod list file '{file.FullName}'");
                        }
                        catch (Exception ex)
                        {
                            Log.Warning(ex, $"Unable to load mod list file '{file.FullName}'");
                        }
                    }
                }
            }
        }
예제 #21
0
        /// <summary>
        /// Creates state information for a mod family.
        /// </summary>
        public static ModFamilyStateInfo FromFamily(ModFamily family)
        {
            var             name    = family.FamilyName;
            bool            enabled = false;
            AccurateVersion version = default;

            var enabledMod = family.EnabledMod;

            if (enabledMod != null)
            {
                enabled = true;
                var defaultMod = family.GetDefaultMod();
                if (enabledMod != defaultMod)
                {
                    version = enabledMod.Version;                           // Only store version if enabled mod is not default
                }
            }

            return(new ModFamilyStateInfo(name, enabled, version));
        }
예제 #22
0
        internal static bool TryParseFileName(string fileName, out string name, out AccurateVersion version)
        {
            name    = null;
            version = default;

            int index = fileName.LastIndexOf('_');

            if ((index < 1) || (index >= fileName.Length - 1))
            {
                return(false);
            }

            name = fileName.Substring(0, index);
            if (string.IsNullOrWhiteSpace(name))
            {
                return(false);
            }

            var versionString = fileName.Substring(index + 1);

            return(AccurateVersion.TryParse(versionString, out version));
        }
예제 #23
0
 public ModDefinitionIdentifier(string modName, ExportMode exportMode, AccurateVersion version)
 => (ModName, ExportMode, Version) = (modName, exportMode, version);
예제 #24
0
 internal static bool TryParseFileName(string fileName, out string name, out AccurateVersion version)
 {
     (name, version) = (null, default);
예제 #25
0
 internal static bool TryParseFileName(string fileName, [NotNullWhen(true)] out string?name, out AccurateVersion version)
 {
     (name, version) = (null, default);
예제 #26
0
 /// <summary>
 /// Tries to gets the mod manager associated with a specific version of Factorio<br/>
 /// Fails if no mod manager has been created for the specified version yet
 /// </summary>
 public bool TryGetModManager(AccurateVersion factorioVersion, [NotNullWhen(true)] out ModManager?result)
 {
     factorioVersion = factorioVersion.ToFactorioMajor();
     return(_modManagers.TryGetValue(factorioVersion, out result));
 }
예제 #27
0
 private ModFamilyStateInfo(string name, bool enabled, AccurateVersion version)
 {
     FamilyName = name;
     Enabled    = enabled;
     Version    = version;
 }
예제 #28
0
 internal ModReleaseInfo(AccurateVersion version, string downloadUrl, string fileName,
                         DateTime releaseDate, string checksum, ModInfo info)
 => (Version, DownloadUrl, FileName, ReleaseDate, Checksum, Info)
예제 #29
0
        // -------------- File version 1 --------------

        public ModDefinition(string name, AccurateVersion version = default)
        {
            Uid     = -1;
            Name    = name;
            Version = version;
        }
예제 #30
0
 private ModFamilyStateInfo(string name, bool enabled, AccurateVersion version)
 => (FamilyName, Enabled, Version) = (name, enabled, version);