/********* ** Private methods *********/ /// <summary>Get the mod version numbers for the given mod.</summary> /// <param name="mod">The mod to check.</param> /// <param name="subkey">The optional update subkey to match in available files. (If no file names or descriptions contain the subkey, it'll be ignored.)</param> /// <param name="allowNonStandardVersions">Whether to allow non-standard versions.</param> /// <param name="mapRemoteVersions">Maps remote versions to a semantic version for update checks.</param> /// <param name="main">The main mod version.</param> /// <param name="preview">The latest prerelease version, if newer than <paramref name="main"/>.</param> private bool TryGetLatestVersions(IModPage mod, string subkey, bool allowNonStandardVersions, IDictionary <string, string> mapRemoteVersions, out ISemanticVersion main, out ISemanticVersion preview) { main = null; preview = null; ISemanticVersion ParseVersion(string raw) { raw = this.NormalizeVersion(raw); return(this.GetMappedVersion(raw, mapRemoteVersions, allowNonStandardVersions)); } if (mod != null) { // get mod version if (subkey == null) { main = ParseVersion(mod.Version); } // get file versions foreach (IModDownload download in mod.Downloads) { // check for subkey if specified if (subkey != null && download.Name?.Contains(subkey, StringComparison.OrdinalIgnoreCase) != true && download.Description?.Contains(subkey, StringComparison.OrdinalIgnoreCase) != true) { continue; } // parse version ISemanticVersion cur = ParseVersion(download.Version); if (cur == null) { continue; } // track highest versions if (main == null || cur.IsNewerThan(main)) { main = cur; } if (cur.IsPrerelease() && (preview == null || cur.IsNewerThan(preview))) { preview = cur; } } if (preview != null && !preview.IsNewerThan(main)) { preview = null; } } return(main != null); }
/// <summary>The method invoked when the player loads the game.</summary> /// <param name="sender">The event sender.</param> /// <param name="e">The event arguments.</param> private void GameEvents_GameLoaded(object sender, EventArgs e) { // check for mod update if (this.Config.CheckForUpdates) { try { Task.Factory.StartNew(() => { Task.Factory.StartNew(() => { ISemanticVersion latest = UpdateHelper.LogVersionCheck(this.Monitor, this.ModManifest.Version, "Automate").Result; if (latest.IsNewerThan(this.CurrentVersion)) { this.NewRelease = latest; } }); }); } catch (Exception ex) { this.HandleError(ex, "checking for a new version"); } } }
////Taken from https://github.com/Pathoschild/SMAPI/blob/924c3a5d3fe6bfad483834112883156bdf202b57/src/SMAPI/Framework/SCore.cs#L669 /// <summary>Get whether a given version should be offered to the user as an update.</summary> /// <param name="currentVersion">The current semantic version.</param> /// <param name="newVersion">The target semantic version.</param> /// <param name="useBetaChannel">Whether the user enabled the beta channel and should be offered pre-release updates.</param> private bool IsValidUpdate(ISemanticVersion currentVersion, ISemanticVersion newVersion, bool useBetaChannel) { return (newVersion != null && newVersion.IsNewerThan(currentVersion) && (useBetaChannel || !newVersion.IsPrerelease())); }
/********* ** Private methods *********/ /// <summary>The method invoked when the player loads the game.</summary> private void ReceiveGameLoaded() { // validate game version string versionError = this.ValidateGameVersion(); if (versionError != null) { this.Monitor.Log(versionError, LogLevel.Error); CommonHelper.ShowErrorMessage(versionError); } // check for mod update if (this.Config.CheckForUpdates) { try { Task.Factory.StartNew(() => { Task.Factory.StartNew(() => { ISemanticVersion latest = UpdateHelper.LogVersionCheck(this.Monitor, this.ModManifest.Version, "ChestsAnywhere").Result; if (latest.IsNewerThan(this.CurrentVersion)) { this.NewRelease = latest; } }); }); } catch (Exception ex) { this.HandleError(ex, "checking for a new version"); } } }
public async Task <object> PostAsync([FromBody] ModSearchModel model) { // parse request data ISemanticVersion apiVersion = this.GetApiVersion(); ModSearchEntryModel[] searchMods = this.GetSearchMods(model, apiVersion).ToArray(); // fetch wiki data WikiCompatibilityEntry[] wikiData = await this.GetWikiDataAsync(); // fetch data IDictionary <string, ModEntryModel> mods = new Dictionary <string, ModEntryModel>(StringComparer.CurrentCultureIgnoreCase); foreach (ModSearchEntryModel mod in searchMods) { if (string.IsNullOrWhiteSpace(mod.ID)) { continue; } ModEntryModel result = await this.GetModData(mod, wikiData, model.IncludeExtendedMetadata); result.SetBackwardsCompatibility(apiVersion); mods[mod.ID] = result; } // return in expected structure return(apiVersion.IsNewerThan("2.6-beta.18") ? mods.Values : (object)mods); }
/// <summary>Get the mods for which the API should return data.</summary> /// <param name="model">The search model.</param> /// <param name="apiVersion">The requested API version.</param> private IEnumerable <ModSearchEntryModel> GetSearchMods(ModSearchModel model, ISemanticVersion apiVersion) { if (model == null) { yield break; } // yield standard entries if (model.Mods != null) { foreach (ModSearchEntryModel mod in model.Mods) { yield return(mod); } } // yield mod update keys if backwards compatible if (model.ModKeys != null && model.ModKeys.Any() && !apiVersion.IsNewerThan("2.6-beta.17")) { foreach (string updateKey in model.ModKeys.Distinct()) { yield return(new ModSearchEntryModel(updateKey, new[] { updateKey })); } } }
private void Multiplayer_ModMessageReceived(object sender, StardewModdingAPI.Events.ModMessageReceivedEventArgs e) { if (!string.Equals(e.FromModID, CurrentModId, StringComparison.OrdinalIgnoreCase)) { return; } ISemanticVersion ver = Helper.Multiplayer.GetConnectedPlayer(e.FromPlayerID)?.GetMod(CurrentModId)?.Version ?? null; bool compatible = ver?.IsNewerThan(CurrentVersion) ?? false; if (!compatible) { Monitor.Log(string.Format("Cannot use this mod during this online session because the host is currently using a more recent version of the mod. Update this mod to enable it on this server. RemoteVer: {0}. LocalVer: {1}", ver?.ToString() ?? "Null", CurrentVersion)); Settings.Remote = Settings.DefaultDisabled; return; } foreach (Farmer farmer in Game1.getAllFarmers()) { if (farmer.UniqueMultiplayerID == e.FromPlayerID) { if (farmer.IsMainPlayer) { // Message received from server if (string.Equals(e.Type, MultiplayerSettingsMessageType, StringComparison.OrdinalIgnoreCase)) { try { Settings data = e.ReadAs <Settings>(); if (data != null) { Settings.Remote = data; Monitor.Log(string.Format("Remote settings updated from server. FarmerId: {0}.", e.FromPlayerID)); } } catch (Exception ex) { Monitor.Log(string.Format("Remote settings cannot be updated from server. FarmerId: {0}. Ex: {1}. Msg: {2}. InnerEx: {3}", e.FromPlayerID, ex.GetType().Name, ex.Message, ex.InnerException?.GetType().Name ?? "None")); } } else { Monitor.Log(string.Format("Unknown mod message received from server. FarmerId: {0}. Type: {1}.", e.FromPlayerID, e.Type)); } } else { Monitor.Log(string.Format("Remote mod message received from a non-host farmer. FarmerId: {0}. Type: {1}.", e.FromPlayerID, e.Type)); } return; } } Monitor.Log(string.Format("Remote mod message received from an unknown farmer. PlayerId: {0}. Type: {1}", e.FromPlayerID, e.Type)); }
/********* ** Public methods *********/ /// <summary>Get whether the specified version is compatible according to this metadata.</summary> /// <param name="version">The current version of the matching mod.</param> public bool IsCompatible(ISemanticVersion version) { ISemanticVersion incompatibleVersion = new SemanticVersion(this.Version); // allow newer versions if (version.IsNewerThan(incompatibleVersion)) { return(true); } // allow versions matching override return(!string.IsNullOrWhiteSpace(this.ForceCompatibleVersion) && Regex.IsMatch(version.ToString(), this.ForceCompatibleVersion, RegexOptions.IgnoreCase)); }
/********* ** Private methods *********/ /**** ** Event handlers ****/ /// <summary>The method invoked when the player loads the game.</summary> private void ReceiveGameLoaded() { // check for an updated version if (this.Config.CheckForUpdates) { Task.Factory.StartNew(() => { ISemanticVersion latest = UpdateHelper.LogVersionCheck(this.Monitor, this.ModManifest.Version, "LookupAnything").Result; if (latest.IsNewerThan(this.CurrentVersion)) { this.NewRelease = latest; } }); } }
/// <summary>Loads handlers for integration of other mods</summary> private static void IntegrateMods() { if (SHelper.ModRegistry.IsLoaded("Paritee.BetterFarmAnimalVariety")) { ISemanticVersion bfavVersion = SHelper.ModRegistry.Get("Paritee.BetterFarmAnimalVariety").Manifest.Version; if (bfavVersion.IsNewerThan("2.2.6")) { ModEntry.BFAV300Worker = new BFAV300Integrator(); } else { ModEntry.BFAV226Worker = new BFAV226Integrator(); } } }
/********* ** Public methods *********/ /// <summary>Get whether the specified version is compatible according to this metadata.</summary> /// <param name="version">The current version of the matching mod.</param> public bool IsCompatible(ISemanticVersion version) { ISemanticVersion lowerVersion = this.LowerVersion != null ? new SemanticVersion(this.LowerVersion) : null; ISemanticVersion upperVersion = new SemanticVersion(this.UpperVersion); // ignore versions not in range if (lowerVersion != null && version.IsOlderThan(lowerVersion)) { return(true); } if (version.IsNewerThan(upperVersion)) { return(true); } // allow versions matching override return(!string.IsNullOrWhiteSpace(this.ForceCompatibleVersion) && Regex.IsMatch(version.ToString(), this.ForceCompatibleVersion, RegexOptions.IgnoreCase)); }
private async void GameEvents_GameLoaded(object sender, EventArgs e) { // check for mod update if (_config.CheckForUpdates && !_config.Debug) { try { ISemanticVersion latest = await UpdateHelper.LogVersionCheck(_mod.Monitor, _mod.ModManifest.Version); if (latest.IsNewerThan(_currentVersion)) { _newRelease = latest; } } catch (Exception ex) { ModHelper.HandleError(_mod, ex, "checking for a new version"); } } }
/// <summary>Get whether a given version is contained within this compatibility range.</summary> /// <param name="version">The version to check.</param> public bool MatchesVersion(ISemanticVersion version) { return ((this.LowerVersion == null || !version.IsOlderThan(this.LowerVersion)) && (this.UpperVersion == null || !version.IsNewerThan(this.UpperVersion))); }
/// <summary>Get metadata about a mod.</summary> /// <param name="id">The ModDrop mod ID.</param> /// <returns>Returns the mod info if found, else <c>null</c>.</returns> public async Task <ModDropMod> GetModAsync(long id) { // get raw data ModListModel response = await this.Client .PostAsync("") .WithBody(new { ModIDs = new[] { id }, Files = true, Mods = true }) .As <ModListModel>(); ModModel mod = response.Mods[id]; if (mod.Mod?.Title == null || mod.Mod.ErrorCode.HasValue) { return(null); } // get latest versions ISemanticVersion latest = null; ISemanticVersion optional = null; foreach (FileDataModel file in mod.Files) { if (file.IsOld || file.IsDeleted || file.IsHidden) { continue; } if (!SemanticVersion.TryParse(file.Version, out ISemanticVersion version)) { continue; } if (file.IsDefault) { if (latest == null || version.IsNewerThan(latest)) { latest = version; } } else if (optional == null || version.IsNewerThan(optional)) { optional = version; } } if (latest == null) { latest = optional; optional = null; } if (optional != null && latest.IsNewerThan(optional)) { optional = null; } // generate result return(new ModDropMod { Name = mod.Mod?.Title, LatestDefaultVersion = latest, LatestOptionalVersion = optional, Url = string.Format(this.ModUrlFormat, id) }); }