summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/SMAPI.Common/Models/ModSeachModel.cs7
-rw-r--r--src/SMAPI.Common/SemanticVersionImpl.cs5
-rw-r--r--src/SMAPI.Installer/unix-launcher.sh4
-rw-r--r--src/SMAPI.ModBuildConfig/build/smapi.targets4
-rw-r--r--src/SMAPI.ModBuildConfig/package.nuspec5
-rw-r--r--src/SMAPI.Mods.ConsoleCommands/Framework/Commands/Player/AddCommand.cs4
-rw-r--r--src/SMAPI.Mods.ConsoleCommands/Framework/Commands/Player/SetColorCommand.cs10
-rw-r--r--src/SMAPI.Mods.ConsoleCommands/Framework/Commands/Player/SetNameCommand.cs6
-rw-r--r--src/SMAPI.Mods.ConsoleCommands/Framework/Commands/World/DownMineLevelCommand.cs6
-rw-r--r--src/SMAPI.Mods.ConsoleCommands/Framework/Commands/World/SetMineLevelCommand.cs6
-rw-r--r--src/SMAPI.Mods.ConsoleCommands/Framework/ItemRepository.cs83
-rw-r--r--src/SMAPI.Mods.ConsoleCommands/manifest.json2
-rw-r--r--src/SMAPI.Web/Controllers/ModsApiController.cs24
-rw-r--r--src/SMAPI.Web/Framework/Clients/Chucklefish/ChucklefishClient.cs19
-rw-r--r--src/SMAPI.Web/Framework/Clients/Nexus/NexusClient.cs2
-rw-r--r--src/SMAPI.Web/Framework/Clients/Nexus/NexusMod.cs4
-rw-r--r--src/SMAPI.Web/Framework/Clients/Nexus/NexusWebScrapeClient.cs106
-rw-r--r--src/SMAPI.Web/Framework/LogParsing/LogParser.cs12
-rw-r--r--src/SMAPI.Web/Framework/LogParsing/Models/ParsedLog.cs4
-rw-r--r--src/SMAPI.Web/Framework/ModRepositories/NexusRepository.cs8
-rw-r--r--src/SMAPI.Web/Startup.cs12
-rw-r--r--src/SMAPI.Web/Views/LogParser/Index.cshtml22
-rw-r--r--src/SMAPI.Web/appsettings.json2
-rw-r--r--src/SMAPI.Web/wwwroot/Content/js/log-parser.js6
-rw-r--r--src/SMAPI/Constants.cs28
-rw-r--r--src/SMAPI/Events/EventArgsGameLocationsChanged.cs6
-rw-r--r--src/SMAPI/Events/EventArgsInput.cs2
-rw-r--r--src/SMAPI/Events/EventArgsInventoryChanged.cs12
-rw-r--r--src/SMAPI/Events/EventArgsLocationObjectsChanged.cs19
-rw-r--r--src/SMAPI/Framework/ContentCore.cs (renamed from src/SMAPI/Framework/SContentManager.cs)186
-rw-r--r--src/SMAPI/Framework/ContentManagerShim.cs68
-rw-r--r--src/SMAPI/Framework/GameVersion.cs20
-rw-r--r--src/SMAPI/Framework/ModData/ModDataField.cs2
-rw-r--r--src/SMAPI/Framework/ModData/ModDataRecord.cs11
-rw-r--r--src/SMAPI/Framework/ModData/ModDatabase.cs2
-rw-r--r--src/SMAPI/Framework/ModData/ParsedModDataRecord.cs2
-rw-r--r--src/SMAPI/Framework/ModHelpers/ContentHelper.cs43
-rw-r--r--src/SMAPI/Framework/ModHelpers/ReflectionHelper.cs3
-rw-r--r--src/SMAPI/Framework/ModLoading/AssemblyDefinitionResolver.cs2
-rw-r--r--src/SMAPI/Framework/ModLoading/AssemblyLoader.cs32
-rw-r--r--src/SMAPI/Framework/ModLoading/Finders/ReferenceToMemberWithUnexpectedTypeFinder.cs157
-rw-r--r--src/SMAPI/Framework/ModLoading/Finders/ReferenceToMissingMemberFinder.cs109
-rw-r--r--src/SMAPI/Framework/ModLoading/ModResolver.cs5
-rw-r--r--src/SMAPI/Framework/ModLoading/Rewriters/FieldToPropertyRewriter.cs18
-rw-r--r--src/SMAPI/Framework/ModLoading/Rewriters/StaticFieldToConstantRewriter.cs63
-rw-r--r--src/SMAPI/Framework/Reflection/ReflectedField.cs5
-rw-r--r--src/SMAPI/Framework/Reflection/ReflectedMethod.cs5
-rw-r--r--src/SMAPI/Framework/Reflection/ReflectedProperty.cs5
-rw-r--r--src/SMAPI/Framework/SGame.cs672
-rw-r--r--src/SMAPI/Framework/WebApiClient.cs2
-rw-r--r--src/SMAPI/IPrivateField.cs2
-rw-r--r--src/SMAPI/IPrivateMethod.cs2
-rw-r--r--src/SMAPI/IPrivateProperty.cs2
-rw-r--r--src/SMAPI/IReflectionHelper.cs2
-rw-r--r--src/SMAPI/Metadata/CoreAssets.cs68
-rw-r--r--src/SMAPI/Metadata/InstructionMetadata.cs74
-rw-r--r--src/SMAPI/Program.cs98
-rw-r--r--src/SMAPI/StardewModdingAPI.config.json375
-rw-r--r--src/SMAPI/StardewModdingAPI.csproj5
59 files changed, 2025 insertions, 445 deletions
diff --git a/src/SMAPI.Common/Models/ModSeachModel.cs b/src/SMAPI.Common/Models/ModSeachModel.cs
index 13b05d2d..3c33d0b6 100644
--- a/src/SMAPI.Common/Models/ModSeachModel.cs
+++ b/src/SMAPI.Common/Models/ModSeachModel.cs
@@ -12,6 +12,9 @@ namespace StardewModdingAPI.Common.Models
/// <summary>The namespaced mod keys to search.</summary>
public string[] ModKeys { get; set; }
+ /// <summary>Whether to allow non-semantic versions, instead of returning an error for those.</summary>
+ public bool AllowInvalidVersions { get; set; }
+
/*********
** Public methods
@@ -24,9 +27,11 @@ namespace StardewModdingAPI.Common.Models
/// <summary>Construct an instance.</summary>
/// <param name="modKeys">The namespaced mod keys to search.</param>
- public ModSearchModel(IEnumerable<string> modKeys)
+ /// <param name="allowInvalidVersions">Whether to allow non-semantic versions, instead of returning an error for those.</param>
+ public ModSearchModel(IEnumerable<string> modKeys, bool allowInvalidVersions)
{
this.ModKeys = modKeys.ToArray();
+ this.AllowInvalidVersions = allowInvalidVersions;
}
}
}
diff --git a/src/SMAPI.Common/SemanticVersionImpl.cs b/src/SMAPI.Common/SemanticVersionImpl.cs
index 1c713b47..084f56a3 100644
--- a/src/SMAPI.Common/SemanticVersionImpl.cs
+++ b/src/SMAPI.Common/SemanticVersionImpl.cs
@@ -22,6 +22,9 @@ namespace StardewModdingAPI.Common
/// <summary>An optional prerelease tag.</summary>
public string Tag { get; }
+ /// <summary>A regex pattern matching a version within a larger string.</summary>
+ internal const string UnboundedVersionPattern = @"(?>(?<major>0|[1-9]\d*))\.(?>(?<minor>0|[1-9]\d*))(?>(?:\.(?<patch>0|[1-9]\d*))?)(?:-(?<prerelease>(?>[a-z0-9]+[\-\.]?)+))?";
+
/// <summary>A regular expression matching a semantic version string.</summary>
/// <remarks>
/// This pattern is derived from the BNF documentation in the <a href="https://github.com/mojombo/semver">semver repo</a>,
@@ -30,7 +33,7 @@ namespace StardewModdingAPI.Common
/// - allows hyphens in prerelease tags as synonyms for dots (like "-unofficial-update.3");
/// - doesn't allow '+build' suffixes.
/// </remarks>
- internal static readonly Regex Regex = new Regex(@"^(?>(?<major>0|[1-9]\d*))\.(?>(?<minor>0|[1-9]\d*))(?>(?:\.(?<patch>0|[1-9]\d*))?)(?:-(?<prerelease>(?>[a-z0-9]+[\-\.]?)+))?$", RegexOptions.CultureInvariant | RegexOptions.IgnoreCase | RegexOptions.Compiled | RegexOptions.ExplicitCapture);
+ internal static readonly Regex Regex = new Regex($@"^{SemanticVersionImpl.UnboundedVersionPattern}$", RegexOptions.CultureInvariant | RegexOptions.IgnoreCase | RegexOptions.Compiled | RegexOptions.ExplicitCapture);
/*********
** Public methods
diff --git a/src/SMAPI.Installer/unix-launcher.sh b/src/SMAPI.Installer/unix-launcher.sh
index 2542a286..6e796461 100644
--- a/src/SMAPI.Installer/unix-launcher.sh
+++ b/src/SMAPI.Installer/unix-launcher.sh
@@ -71,12 +71,12 @@ else
else
x-terminal-emulator -e "$LAUNCHER"
fi
+ elif $COMMAND xterm 2>/dev/null; then
+ xterm -e "$LAUNCHER"
elif $COMMAND xfce4-terminal 2>/dev/null; then
xfce4-terminal -e "$LAUNCHER"
elif $COMMAND gnome-terminal 2>/dev/null; then
gnome-terminal -e "$LAUNCHER"
- elif $COMMAND xterm 2>/dev/null; then
- xterm -e "$LAUNCHER"
elif $COMMAND konsole 2>/dev/null; then
konsole -e "$LAUNCHER"
elif $COMMAND terminal 2>/dev/null; then
diff --git a/src/SMAPI.ModBuildConfig/build/smapi.targets b/src/SMAPI.ModBuildConfig/build/smapi.targets
index 83f0dcbd..7e8bbfc3 100644
--- a/src/SMAPI.ModBuildConfig/build/smapi.targets
+++ b/src/SMAPI.ModBuildConfig/build/smapi.targets
@@ -67,6 +67,10 @@
<Reference Include="Microsoft.Xna.Framework.Xact, Version=4.0.0.0, Culture=neutral, PublicKeyToken=842cf8be1de50553, processorArchitecture=x86">
<Private>false</Private>
</Reference>
+ <Reference Include="Netcode" Condition="Exists('$(GamePath)\Netcode.dll')">
+ <HintPath>$(GamePath)\Netcode.dll</HintPath>
+ <Private>False</Private>
+ </Reference>
<Reference Include="Stardew Valley">
<HintPath>$(GamePath)\Stardew Valley.exe</HintPath>
<Private>false</Private>
diff --git a/src/SMAPI.ModBuildConfig/package.nuspec b/src/SMAPI.ModBuildConfig/package.nuspec
index 91f38a29..8393ab61 100644
--- a/src/SMAPI.ModBuildConfig/package.nuspec
+++ b/src/SMAPI.ModBuildConfig/package.nuspec
@@ -2,7 +2,7 @@
<package xmlns="http://schemas.microsoft.com/packaging/2013/05/nuspec.xsd">
<metadata>
<id>Pathoschild.Stardew.ModBuildConfig</id>
- <version>2.0.2</version>
+ <version>2.0.3-alpha20180307</version>
<title>Build package for SMAPI mods</title>
<authors>Pathoschild</authors>
<owners>Pathoschild</owners>
@@ -26,6 +26,9 @@
2.0.2:
- Fixed compatibility issue on Linux.
+
+ 2.0.3:
+ - Added support for Stardew Valley 1.3.
</releaseNotes>
</metadata>
<files>
diff --git a/src/SMAPI.Mods.ConsoleCommands/Framework/Commands/Player/AddCommand.cs b/src/SMAPI.Mods.ConsoleCommands/Framework/Commands/Player/AddCommand.cs
index 14a519fb..a6f42b98 100644
--- a/src/SMAPI.Mods.ConsoleCommands/Framework/Commands/Player/AddCommand.cs
+++ b/src/SMAPI.Mods.ConsoleCommands/Framework/Commands/Player/AddCommand.cs
@@ -54,7 +54,11 @@ namespace StardewModdingAPI.Mods.ConsoleCommands.Framework.Commands.Player
// apply quality
if (match.Item is Object obj)
+#if STARDEW_VALLEY_1_3
+ obj.Quality = quality;
+#else
obj.quality = quality;
+#endif
else if (match.Item is Tool tool)
tool.UpgradeLevel = quality;
diff --git a/src/SMAPI.Mods.ConsoleCommands/Framework/Commands/Player/SetColorCommand.cs b/src/SMAPI.Mods.ConsoleCommands/Framework/Commands/Player/SetColorCommand.cs
index 5d098593..aa4fd105 100644
--- a/src/SMAPI.Mods.ConsoleCommands/Framework/Commands/Player/SetColorCommand.cs
+++ b/src/SMAPI.Mods.ConsoleCommands/Framework/Commands/Player/SetColorCommand.cs
@@ -1,4 +1,4 @@
-using Microsoft.Xna.Framework;
+using Microsoft.Xna.Framework;
using StardewValley;
namespace StardewModdingAPI.Mods.ConsoleCommands.Framework.Commands.Player
@@ -36,7 +36,11 @@ namespace StardewModdingAPI.Mods.ConsoleCommands.Framework.Commands.Player
switch (target)
{
case "hair":
+#if STARDEW_VALLEY_1_3
+ Game1.player.hairstyleColor.Value = color;
+#else
Game1.player.hairstyleColor = color;
+#endif
monitor.Log("OK, your hair color is updated.", LogLevel.Info);
break;
@@ -46,7 +50,11 @@ namespace StardewModdingAPI.Mods.ConsoleCommands.Framework.Commands.Player
break;
case "pants":
+#if STARDEW_VALLEY_1_3
+ Game1.player.pantsColor.Value = color;
+#else
Game1.player.pantsColor = color;
+#endif
monitor.Log("OK, your pants color is updated.", LogLevel.Info);
break;
}
diff --git a/src/SMAPI.Mods.ConsoleCommands/Framework/Commands/Player/SetNameCommand.cs b/src/SMAPI.Mods.ConsoleCommands/Framework/Commands/Player/SetNameCommand.cs
index 5b1225e8..71e17f71 100644
--- a/src/SMAPI.Mods.ConsoleCommands/Framework/Commands/Player/SetNameCommand.cs
+++ b/src/SMAPI.Mods.ConsoleCommands/Framework/Commands/Player/SetNameCommand.cs
@@ -1,4 +1,4 @@
-using StardewValley;
+using StardewValley;
namespace StardewModdingAPI.Mods.ConsoleCommands.Framework.Commands.Player
{
@@ -39,7 +39,11 @@ namespace StardewModdingAPI.Mods.ConsoleCommands.Framework.Commands.Player
case "farm":
if (!string.IsNullOrWhiteSpace(name))
{
+#if STARDEW_VALLEY_1_3
+ Game1.player.farmName.Value = args[1];
+#else
Game1.player.farmName = args[1];
+#endif
monitor.Log($"OK, your farm's name is now {Game1.player.farmName}.", LogLevel.Info);
}
else
diff --git a/src/SMAPI.Mods.ConsoleCommands/Framework/Commands/World/DownMineLevelCommand.cs b/src/SMAPI.Mods.ConsoleCommands/Framework/Commands/World/DownMineLevelCommand.cs
index da117006..c83c3b07 100644
--- a/src/SMAPI.Mods.ConsoleCommands/Framework/Commands/World/DownMineLevelCommand.cs
+++ b/src/SMAPI.Mods.ConsoleCommands/Framework/Commands/World/DownMineLevelCommand.cs
@@ -1,4 +1,4 @@
-using StardewValley;
+using StardewValley;
using StardewValley.Locations;
namespace StardewModdingAPI.Mods.ConsoleCommands.Framework.Commands.World
@@ -21,7 +21,11 @@ namespace StardewModdingAPI.Mods.ConsoleCommands.Framework.Commands.World
{
int level = (Game1.currentLocation as MineShaft)?.mineLevel ?? 0;
monitor.Log($"OK, warping you to mine level {level + 1}.", LogLevel.Info);
+#if STARDEW_VALLEY_1_3
+ Game1.enterMine(level + 1);
+#else
Game1.enterMine(false, level + 1, "");
+#endif
}
}
}
diff --git a/src/SMAPI.Mods.ConsoleCommands/Framework/Commands/World/SetMineLevelCommand.cs b/src/SMAPI.Mods.ConsoleCommands/Framework/Commands/World/SetMineLevelCommand.cs
index 1024b7b6..5947af1a 100644
--- a/src/SMAPI.Mods.ConsoleCommands/Framework/Commands/World/SetMineLevelCommand.cs
+++ b/src/SMAPI.Mods.ConsoleCommands/Framework/Commands/World/SetMineLevelCommand.cs
@@ -1,4 +1,4 @@
-using System;
+using System;
using StardewValley;
namespace StardewModdingAPI.Mods.ConsoleCommands.Framework.Commands.World
@@ -26,7 +26,11 @@ namespace StardewModdingAPI.Mods.ConsoleCommands.Framework.Commands.World
// handle
level = Math.Max(1, level);
monitor.Log($"OK, warping you to mine level {level}.", LogLevel.Info);
+#if STARDEW_VALLEY_1_3
+ Game1.enterMine(level);
+#else
Game1.enterMine(true, level, "");
+#endif
}
}
}
diff --git a/src/SMAPI.Mods.ConsoleCommands/Framework/ItemRepository.cs b/src/SMAPI.Mods.ConsoleCommands/Framework/ItemRepository.cs
index b5fe9f2f..9c0981c4 100644
--- a/src/SMAPI.Mods.ConsoleCommands/Framework/ItemRepository.cs
+++ b/src/SMAPI.Mods.ConsoleCommands/Framework/ItemRepository.cs
@@ -1,4 +1,4 @@
-using System.Collections.Generic;
+using System.Collections.Generic;
using Microsoft.Xna.Framework;
using StardewModdingAPI.Mods.ConsoleCommands.Framework.ItemData;
using StardewValley;
@@ -95,39 +95,90 @@ namespace StardewModdingAPI.Mods.ConsoleCommands.Framework
// fruit products
if (item.category == SObject.FruitsCategory)
{
- yield return new SearchableItem(ItemType.Object, this.CustomIDOffset + id, new SObject(348, 1)
+ // wine
+#if STARDEW_VALLEY_1_3
+ SObject wine =
+ new SObject(348, 1)
+ {
+ Name = $"{item.Name} Wine",
+ Price = item.price * 3
+ };
+ wine.preserve.Value = SObject.PreserveType.Wine;
+ wine.preservedParentSheetIndex.Value = item.parentSheetIndex;
+#else
+ SObject wine = new SObject(348, 1)
{
name = $"{item.Name} Wine",
price = item.price * 3,
preserve = SObject.PreserveType.Wine,
preservedParentSheetIndex = item.parentSheetIndex
- });
- yield return new SearchableItem(ItemType.Object, this.CustomIDOffset * 2 + id, new SObject(344, 1)
+ };
+#endif
+ yield return new SearchableItem(ItemType.Object, this.CustomIDOffset + id, wine);
+
+ // jelly
+#if STARDEW_VALLEY_1_3
+ SObject jelly = new SObject(344, 1)
+ {
+ Name = $"{item.Name} Jelly",
+ Price = 50 + item.Price * 2
+ };
+ jelly.preserve.Value = SObject.PreserveType.Jelly;
+ jelly.preservedParentSheetIndex.Value = item.parentSheetIndex;
+#else
+ SObject jelly = new SObject(344, 1)
{
name = $"{item.Name} Jelly",
price = 50 + item.Price * 2,
preserve = SObject.PreserveType.Jelly,
preservedParentSheetIndex = item.parentSheetIndex
- });
+ };
+#endif
+ yield return new SearchableItem(ItemType.Object, this.CustomIDOffset * 2 + id, jelly);
}
// vegetable products
else if (item.category == SObject.VegetableCategory)
{
- yield return new SearchableItem(ItemType.Object, this.CustomIDOffset * 3 + id, new SObject(350, 1)
+ // juice
+#if STARDEW_VALLEY_1_3
+ SObject juice = new SObject(350, 1)
+ {
+ Name = $"{item.Name} Juice",
+ Price = (int)(item.price * 2.25d)
+ };
+ juice.preserve.Value = SObject.PreserveType.Juice;
+ juice.preservedParentSheetIndex.Value = item.parentSheetIndex;
+#else
+ SObject juice = new SObject(350, 1)
{
name = $"{item.Name} Juice",
price = (int)(item.price * 2.25d),
preserve = SObject.PreserveType.Juice,
preservedParentSheetIndex = item.parentSheetIndex
- });
- yield return new SearchableItem(ItemType.Object, this.CustomIDOffset * 4 + id, new SObject(342, 1)
+ };
+#endif
+ yield return new SearchableItem(ItemType.Object, this.CustomIDOffset * 3 + id, juice);
+
+ // pickled
+#if STARDEW_VALLEY_1_3
+ SObject pickled = new SObject(342, 1)
+ {
+ Name = $"Pickled {item.Name}",
+ Price = 50 + item.Price * 2
+ };
+ pickled.preserve.Value = SObject.PreserveType.Pickle;
+ pickled.preservedParentSheetIndex.Value = item.parentSheetIndex;
+#else
+ SObject pickled = new SObject(342, 1)
{
name = $"Pickled {item.Name}",
price = 50 + item.Price * 2,
preserve = SObject.PreserveType.Pickle,
preservedParentSheetIndex = item.parentSheetIndex
- });
+ };
+#endif
+ yield return new SearchableItem(ItemType.Object, this.CustomIDOffset * 4 + id, pickled);
}
// flower honey
@@ -160,6 +211,19 @@ namespace StardewModdingAPI.Mods.ConsoleCommands.Framework
// yield honey
if (type != null)
{
+#if STARDEW_VALLEY_1_3
+ SObject honey = new SObject(Vector2.Zero, 340, item.Name + " Honey", false, true, false, false)
+ {
+ Name = "Wild Honey"
+ };
+ honey.honeyType.Value = type;
+
+ if (type != SObject.HoneyType.Wild)
+ {
+ honey.Name = $"{item.Name} Honey";
+ honey.Price += item.Price * 2;
+ }
+#else
SObject honey = new SObject(Vector2.Zero, 340, item.Name + " Honey", false, true, false, false)
{
name = "Wild Honey",
@@ -170,6 +234,7 @@ namespace StardewModdingAPI.Mods.ConsoleCommands.Framework
honey.name = $"{item.Name} Honey";
honey.price += item.price * 2;
}
+#endif
yield return new SearchableItem(ItemType.Object, this.CustomIDOffset * 5 + id, honey);
}
}
diff --git a/src/SMAPI.Mods.ConsoleCommands/manifest.json b/src/SMAPI.Mods.ConsoleCommands/manifest.json
index f4b3884d..785af01a 100644
--- a/src/SMAPI.Mods.ConsoleCommands/manifest.json
+++ b/src/SMAPI.Mods.ConsoleCommands/manifest.json
@@ -1,7 +1,7 @@
{
"Name": "Console Commands",
"Author": "SMAPI",
- "Version": "2.5.2",
+ "Version": "2.5.3",
"Description": "Adds SMAPI console commands that let you manipulate the game.",
"UniqueID": "SMAPI.ConsoleCommands",
"EntryDll": "ConsoleCommands.dll"
diff --git a/src/SMAPI.Web/Controllers/ModsApiController.cs b/src/SMAPI.Web/Controllers/ModsApiController.cs
index dcb4ec52..abae7db7 100644
--- a/src/SMAPI.Web/Controllers/ModsApiController.cs
+++ b/src/SMAPI.Web/Controllers/ModsApiController.cs
@@ -64,14 +64,15 @@ namespace StardewModdingAPI.Web.Controllers
/// <summary>Fetch version metadata for the given mods.</summary>
/// <param name="modKeys">The namespaced mod keys to search as a comma-delimited array.</param>
+ /// <param name="allowInvalidVersions">Whether to allow non-semantic versions, instead of returning an error for those.</param>
[HttpGet]
- public async Task<IDictionary<string, ModInfoModel>> GetAsync(string modKeys)
+ public async Task<IDictionary<string, ModInfoModel>> GetAsync(string modKeys, bool allowInvalidVersions = false)
{
string[] modKeysArray = modKeys?.Split(',').ToArray();
if (modKeysArray == null || !modKeysArray.Any())
return new Dictionary<string, ModInfoModel>();
- return await this.PostAsync(new ModSearchModel(modKeysArray));
+ return await this.PostAsync(new ModSearchModel(modKeysArray, allowInvalidVersions));
}
/// <summary>Fetch version metadata for the given mods.</summary>
@@ -79,7 +80,8 @@ namespace StardewModdingAPI.Web.Controllers
[HttpPost]
public async Task<IDictionary<string, ModInfoModel>> PostAsync([FromBody] ModSearchModel search)
{
- // sort & filter keys
+ // parse model
+ bool allowInvalidVersions = search?.AllowInvalidVersions ?? false;
string[] modKeys = (search?.ModKeys?.ToArray() ?? new string[0])
.Distinct(StringComparer.CurrentCultureIgnoreCase)
.OrderBy(p => p, StringComparer.CurrentCultureIgnoreCase)
@@ -106,12 +108,20 @@ namespace StardewModdingAPI.Web.Controllers
// fetch mod info
result[modKey] = await this.Cache.GetOrCreateAsync($"{repository.VendorKey}:{modID}".ToLower(), async entry =>
{
- entry.AbsoluteExpiration = DateTimeOffset.UtcNow.AddMinutes(this.CacheMinutes);
-
+ // fetch info
ModInfoModel info = await repository.GetModInfoAsync(modID);
- if (info.Error == null && (info.Version == null || !Regex.IsMatch(info.Version, this.VersionRegex, RegexOptions.CultureInvariant | RegexOptions.IgnoreCase)))
- info = new ModInfoModel(info.Name, info.Version, info.Url, info.Version == null ? "Mod has no version number." : $"Mod has invalid semantic version '{info.Version}'.");
+ // validate
+ if (info.Error == null)
+ {
+ if (info.Version == null)
+ info = new ModInfoModel(info.Name, info.Version, info.Url, "Mod has no version number.");
+ if (!allowInvalidVersions && !Regex.IsMatch(info.Version, this.VersionRegex, RegexOptions.CultureInvariant | RegexOptions.IgnoreCase))
+ info = new ModInfoModel(info.Name, info.Version, info.Url, $"Mod has invalid semantic version '{info.Version}'.");
+ }
+
+ // cache & return
+ entry.AbsoluteExpiration = DateTimeOffset.UtcNow.AddMinutes(this.CacheMinutes);
return info;
});
}
diff --git a/src/SMAPI.Web/Framework/Clients/Chucklefish/ChucklefishClient.cs b/src/SMAPI.Web/Framework/Clients/Chucklefish/ChucklefishClient.cs
ind