fix typos and inconsistent spelling
This commit is contained in:
parent
3f6865e830
commit
fd77ae93d5
|
@ -1,3 +1,3 @@
|
|||
# normalise line endings
|
||||
# normalize line endings
|
||||
* text=auto
|
||||
README.txt text=crlf
|
||||
|
|
|
@ -29,6 +29,7 @@ These changes have not been released yet.
|
|||
* Fixed map reloads resetting tilesheet seasons.
|
||||
* Fixed map reloads not updating door warps.
|
||||
* Fixed outdoor tilesheets being seasonalised when added to an indoor location.
|
||||
* Fixed typos and inconsistent spelling.
|
||||
|
||||
* For the mod compatibility list:
|
||||
* Now loads faster (since data is fetched in a background service).
|
||||
|
@ -43,7 +44,7 @@ These changes have not been released yet.
|
|||
* Added support for referencing a schema in a JSON Schema-compatible text editor.
|
||||
|
||||
* For modders:
|
||||
* Mods are now loaded much earlier in the game launch. This lets mods intercept any content asset, but the game is not fully initialised when `Entry` is called (use the `GameLaunched` event if you need to run code when the game is initialised).
|
||||
* Mods are now loaded much earlier in the game launch. This lets mods intercept any content asset, but the game is not fully initialized when `Entry` is called (use the `GameLaunched` event if you need to run code when the game is initialized).
|
||||
* Added support for content pack translations.
|
||||
* Added fields and methods: `IContentPack.HasFile`, `Context.IsGameLaunched`, and `SemanticVersion.TryParse`.
|
||||
* Added separate `LogNetworkTraffic` option to make verbose logging less overwhelmingly verbose.
|
||||
|
@ -53,7 +54,7 @@ These changes have not been released yet.
|
|||
* Trace logs when loading mods are now more clear.
|
||||
* Clarified update-check errors for mods with multiple update keys.
|
||||
* Fixed custom maps loaded from `.xnb` files not having their tilesheet paths automatically adjusted.
|
||||
* Fixed custom maps loaded from the mod folder with tilesheets in a subfolder not working crossplatform. All tilesheet paths are now normalised for the OS automatically.
|
||||
* Fixed custom maps loaded from the mod folder with tilesheets in a subfolder not working crossplatform. All tilesheet paths are now normalized for the OS automatically.
|
||||
* Removed all deprecated APIs.
|
||||
* Removed the `Monitor.ExitGameImmediately` method.
|
||||
* Updated dependencies (including Json.NET 11.0.2 → 12.0.2, Mono.Cecil 0.10.1 → 0.10.4).
|
||||
|
@ -73,7 +74,7 @@ Released 13 September 2019 for Stardew Valley 1.3.36.
|
|||
* For the web UI:
|
||||
* When filtering the mod list, clicking a mod link now automatically adds it to the visible mods.
|
||||
* Added log parser instructions for Android.
|
||||
* Fixed log parser failing in some cases due to time format localisation.
|
||||
* Fixed log parser failing in some cases due to time format localization.
|
||||
|
||||
* For modders:
|
||||
* `this.Monitor.Log` now defaults to the `Trace` log level instead of `Debug`. The change will only take effect when you recompile the mod.
|
||||
|
@ -141,12 +142,12 @@ Released 09 January 2019 for Stardew Valley 1.3.32–33.
|
|||
* Added locale to context trace logs.
|
||||
* Fixed error loading custom map tilesheets in some cases.
|
||||
* Fixed error when swapping maps mid-session for a location with interior doors.
|
||||
* Fixed `Constants.SaveFolderName` and `CurrentSavePath` not available during early load stages when using `Specialised.LoadStageChanged` event.
|
||||
* Fixed `Constants.SaveFolderName` and `CurrentSavePath` not available during early load stages when using `Specialized.LoadStageChanged` event.
|
||||
* Fixed `LoadStage.SaveParsed` raised before the parsed save data is available.
|
||||
* Fixed 'unknown mod' deprecation warnings showing the wrong stack trace.
|
||||
* Fixed `e.Cursor` in input events showing wrong grab tile when player using a controller moves without moving the viewpoint.
|
||||
* Fixed incorrect 'bypassed safety checks' warning for mods using the new `Specialised.LoadStageChanged` event in 2.10.
|
||||
* Deprecated `EntryDll` values whose capitalisation don't match the actual file. (This works on Windows, but causes errors for Linux/Mac players.)
|
||||
* Fixed incorrect 'bypassed safety checks' warning for mods using the new `Specialized.LoadStageChanged` event in 2.10.
|
||||
* Deprecated `EntryDll` values whose capitalization don't match the actual file. (This works on Windows, but causes errors for Linux/Mac players.)
|
||||
|
||||
## 2.10.1
|
||||
Released 30 December 2018 for Stardew Valley 1.3.32–33.
|
||||
|
@ -163,9 +164,9 @@ Released 29 December 2018 for Stardew Valley 1.3.32–33.
|
|||
* Tweaked installer to reduce antivirus false positives.
|
||||
|
||||
* For modders:
|
||||
* Added [events](https://stardewvalleywiki.com/Modding:Modder_Guide/APIs/Events): `GameLoop.OneSecondUpdateTicking`, `GameLoop.OneSecondUpdateTicked`, and `Specialised.LoadStageChanged`.
|
||||
* Added [events](https://stardewvalleywiki.com/Modding:Modder_Guide/APIs/Events): `GameLoop.OneSecondUpdateTicking`, `GameLoop.OneSecondUpdateTicked`, and `Specialized.LoadStageChanged`.
|
||||
* Added `e.IsCurrentLocation` event arg to `World` events.
|
||||
* You can now use `helper.Data.Read/WriteSaveData` as soon as the save is loaded (instead of once the world is initialised).
|
||||
* You can now use `helper.Data.Read/WriteSaveData` as soon as the save is loaded (instead of once the world is initialized).
|
||||
* Increased deprecation levels to _info_ for the upcoming SMAPI 3.0.
|
||||
|
||||
* For the web UI:
|
||||
|
@ -338,7 +339,7 @@ Released 14 August 2018 for Stardew Valley 1.3.28.
|
|||
* dialogue;
|
||||
* map tilesheets.
|
||||
* Added `--mods-path` CLI command-line argument to switch between mod folders.
|
||||
* All enums are now JSON-serialised by name instead of numeric value. (Previously only a few enums were serialised that way. JSON files which already have numeric enum values will still be parsed fine.)
|
||||
* All enums are now JSON-serialized by name instead of numeric value. (Previously only a few enums were serialized that way. JSON files which already have numeric enum values will still be parsed fine.)
|
||||
* Fixed false compatibility error when constructing multidimensional arrays.
|
||||
* Fixed `.ToSButton()` methods not being public.
|
||||
|
||||
|
@ -365,7 +366,7 @@ Released 01 August 2018 for Stardew Valley 1.3.27.
|
|||
* Improved the Console Commands mod:
|
||||
* Added `player_add name`, which adds items to your inventory by name instead of ID.
|
||||
* Fixed `world_setseason` not running season-change logic.
|
||||
* Fixed `world_setseason` not normalising the season value.
|
||||
* Fixed `world_setseason` not normalizing the season value.
|
||||
* Fixed `world_settime` sometimes breaking NPC schedules (e.g. so they stay in bed).
|
||||
* Removed the `player_setlevel` and `player_setspeed` commands, which weren't implemented in a useful way. Use a mod like CJB Cheats Menu if you need those.
|
||||
* Fixed `SEHException` errors for some players.
|
||||
|
@ -456,7 +457,7 @@ Released 11 April 2018 for Stardew Valley 1.2.30–1.2.33.
|
|||
* Fixed mod update alerts not shown if one mod has an invalid remote version.
|
||||
* Fixed SMAPI update alerts linking to the GitHub repository instead of [smapi.io](https://smapi.io).
|
||||
* Fixed SMAPI update alerts for draft releases.
|
||||
* Fixed error when two content packs use different capitalisation for the same required mod ID.
|
||||
* Fixed error when two content packs use different capitalization for the same required mod ID.
|
||||
* Fixed rare crash if the game duplicates an item.
|
||||
|
||||
* For the [log parser](https://log.smapi.io):
|
||||
|
@ -531,8 +532,8 @@ Released 24 February 2018 for Stardew Valley 1.2.30–1.2.33.
|
|||
* For modders:
|
||||
* Added support for content packs and new APIs to read them.
|
||||
* Added support for `ISemanticVersion` in JSON models.
|
||||
* Added `SpecialisedEvents.UnvalidatedUpdateTick` event for specialised use cases.
|
||||
* Added path normalising to `ReadJsonFile` and `WriteJsonFile` helpers (so no longer need `Path.Combine` with those).
|
||||
* Added `SpecializedEvents.UnvalidatedUpdateTick` event for specialized use cases.
|
||||
* Added path normalizing to `ReadJsonFile` and `WriteJsonFile` helpers (so no longer need `Path.Combine` with those).
|
||||
* Fixed deadlock in rare cases with asset loaders.
|
||||
* Fixed unhelpful error when a mod exposes a non-public API.
|
||||
* Fixed unhelpful error when a translation file has duplicate keys due to case-insensitivity.
|
||||
|
@ -585,11 +586,11 @@ Released 26 December 2017 for Stardew Valley 1.2.30–1.2.33.
|
|||
|
||||
* For modders:
|
||||
* **Added mod-provided APIs** to allow simple integrations between mods, even without direct assembly references.
|
||||
* Added `GameEvents.FirstUpdateTick` event (called once after all mods are initialised).
|
||||
* Added `GameEvents.FirstUpdateTick` event (called once after all mods are initialized).
|
||||
* Added `IsSuppressed` to input events so mods can optionally avoid handling keys another mod has already handled.
|
||||
* Added trace message for mods with no update keys.
|
||||
* Adjusted reflection API to match actual usage (e.g. renamed `GetPrivate*` to `Get*`), and deprecated previous methods.
|
||||
* Fixed `GraphicsEvents.OnPostRenderEvent` not being raised in some specialised cases.
|
||||
* Fixed `GraphicsEvents.OnPostRenderEvent` not being raised in some specialized cases.
|
||||
* Fixed reflection API error for properties missing a `get` and `set`.
|
||||
* Fixed issue where a mod could change the cursor position reported to other mods.
|
||||
* Updated compatibility list.
|
||||
|
@ -614,7 +615,7 @@ Released 02 December 2017 for Stardew Valley 1.2.30–1.2.33.
|
|||
* Slightly improved the UI.
|
||||
|
||||
* For modders:
|
||||
* Added `helper.Content.NormaliseAssetName` method.
|
||||
* Added `helper.Content.NormalizeAssetName` method.
|
||||
* Added `SDate.DaysSinceStart` property.
|
||||
* Fixed input events' `e.SuppressButton(button)` method ignoring specified button.
|
||||
* Fixed input events' `e.SuppressButton()` method not working with mouse buttons.
|
||||
|
@ -769,7 +770,7 @@ For mod developers:
|
|||
* Added content helper properties for the game's current language.
|
||||
* Fixed `Context.IsPlayerFree` being false if the player is performing an action.
|
||||
* Fixed `GraphicsEvents.Resize` being raised before the game updates its window data.
|
||||
* Fixed `SemanticVersion` not being deserialisable through Json.NET.
|
||||
* Fixed `SemanticVersion` not being deserializable through Json.NET.
|
||||
* Fixed terminal not launching on Xfce Linux.
|
||||
|
||||
For SMAPI developers:
|
||||
|
@ -840,7 +841,7 @@ For modders:
|
|||
* SMAPI now automatically fixes tilesheet references for maps loaded from the mod folder.
|
||||
<small>_When loading a map from the mod folder, SMAPI will automatically use tilesheets relative to the map file if they exists. Otherwise it will default to tilesheets in the game content._</small>
|
||||
* Added `Context.IsPlayerFree` for mods that need to check if the player can act (i.e. save is loaded, no menu is displayed, no cutscene is in progress, etc).
|
||||
* Added `Context.IsInDrawLoop` for specialised mods.
|
||||
* Added `Context.IsInDrawLoop` for specialized mods.
|
||||
* Fixed `smapi-crash.txt` being copied from the default log even if a different path is specified with `--log-path`.
|
||||
* Fixed the content API not matching XNB filenames with two dots (like `a.b.xnb`) if you don't specify the `.xnb` extension.
|
||||
* Fixed `debug` command output not printed to console.
|
||||
|
@ -867,7 +868,7 @@ For players:
|
|||
|
||||
For mod developers:
|
||||
* Added a `Context.IsWorldReady` flag for mods to use.
|
||||
<small>_This indicates whether a save is loaded and the world is finished initialising, which starts at the same point that `SaveEvents.AfterLoad` and `TimeEvents.AfterDayStarted` are raised. This is mainly useful for events which can be raised before the world is loaded (like update tick)._</small>
|
||||
<small>_This indicates whether a save is loaded and the world is finished initializing, which starts at the same point that `SaveEvents.AfterLoad` and `TimeEvents.AfterDayStarted` are raised. This is mainly useful for events which can be raised before the world is loaded (like update tick)._</small>
|
||||
* Added a `debug` console command which lets you run the game's debug commands (e.g. `debug warp FarmHouse 1 1` warps you to the farmhouse).
|
||||
* Added basic context info to logs to simplify troubleshooting.
|
||||
* Added a `Mod.Dispose` method which can be overriden to clean up before exit. This method isn't guaranteed to be called on every exit.
|
||||
|
@ -905,8 +906,8 @@ For players:
|
|||
For mod developers:
|
||||
* Added a content API which loads custom textures/maps/data from the mod's folder (`.xnb` or `.png` format) or game content.
|
||||
* `Console.Out` messages are now written to the log file.
|
||||
* `Monitor.ExitGameImmediately` now aborts SMAPI initialisation and events more quickly.
|
||||
* Fixed value-changed events being raised when the player loads a save due to values being initialised.
|
||||
* `Monitor.ExitGameImmediately` now aborts SMAPI initialization and events more quickly.
|
||||
* Fixed value-changed events being raised when the player loads a save due to values being initialized.
|
||||
|
||||
## 1.10
|
||||
Released 24 April 2017 for Stardew Valley 1.2.26.
|
||||
|
@ -922,7 +923,7 @@ For players:
|
|||
* Replaced `player_addmelee` with `player_addweapon` with support for non-melee weapons.
|
||||
|
||||
For mod developers:
|
||||
* Mods are now initialised after the `Initialize`/`LoadContent` phase, which means the `GameEvents.Initialize` and `GameEvents.LoadContent` events are deprecated. You can move any logic in those methods to your mod's `Entry` method.
|
||||
* Mods are now initialized after the `Initialize`/`LoadContent` phase, which means the `GameEvents.Initialize` and `GameEvents.LoadContent` events are deprecated. You can move any logic in those methods to your mod's `Entry` method.
|
||||
* Added `IsBetween` and string overloads to the `ISemanticVersion` methods.
|
||||
* Fixed mouse-changed event never updating prior mouse position.
|
||||
* Fixed `monitor.ExitGameImmediately` not working correctly.
|
||||
|
@ -961,7 +962,7 @@ For mod developers:
|
|||
* The SMAPI log now has a simpler filename.
|
||||
* The SMAPI log now shows the OS caption (like "Windows 10") instead of its internal version when available.
|
||||
* The SMAPI log now always uses `\r\n` line endings to simplify crossplatform viewing.
|
||||
* Fixed `SaveEvents.AfterLoad` being raised during the new-game intro before the player is initialised.
|
||||
* Fixed `SaveEvents.AfterLoad` being raised during the new-game intro before the player is initialized.
|
||||
* Fixed SMAPI not recognising `Mod` instances that don't subclass `Mod` directly.
|
||||
* Several obsolete APIs have been removed (see [migration guides](https://stardewvalleywiki.com/Modding:Index#Migration_guides)),
|
||||
and all _notice_-level deprecations have been increased to _info_.
|
||||
|
@ -1006,7 +1007,7 @@ For mod developers:
|
|||
* Added a mod registry which provides metadata about loaded mods.
|
||||
* The `Entry(…)` method is now deferred until all mods are loaded.
|
||||
* Fixed `SaveEvents.BeforeSave` and `.AfterSave` not triggering on days when the player shipped something.
|
||||
* Fixed `PlayerEvents.LoadedGame` and `SaveEvents.AfterLoad` being fired before the world finishes initialising.
|
||||
* Fixed `PlayerEvents.LoadedGame` and `SaveEvents.AfterLoad` being fired before the world finishes initializing.
|
||||
* Fixed some `LocationEvents`, `PlayerEvents`, and `TimeEvents` being fired during game startup.
|
||||
* Increased deprecation levels for `SObject`, `LogWriter` (not `Log`), and `Mod.Entry(ModHelper)` (not `Mod.Entry(IModHelper)`) to _pending removal_. Increased deprecation levels for `Mod.PerSaveConfigFolder`, `Mod.PerSaveConfigPath`, and `Version.VersionString` to _info_.
|
||||
|
||||
|
|
|
@ -106,7 +106,7 @@ namespace StardewModdingApi.Installer
|
|||
/// <summary>Run the install or uninstall script.</summary>
|
||||
/// <param name="args">The command line arguments.</param>
|
||||
/// <remarks>
|
||||
/// Initialisation flow:
|
||||
/// Initialization flow:
|
||||
/// 1. Collect information (mainly OS and install path) and validate it.
|
||||
/// 2. Ask the user whether to install or uninstall.
|
||||
///
|
||||
|
@ -218,7 +218,7 @@ namespace StardewModdingApi.Installer
|
|||
****/
|
||||
// get theme writers
|
||||
var lightBackgroundWriter = new ColorfulConsoleWriter(EnvironmentUtility.DetectPlatform(), MonitorColorScheme.LightBackground);
|
||||
var darkDarkgroundWriter = new ColorfulConsoleWriter(EnvironmentUtility.DetectPlatform(), MonitorColorScheme.DarkBackground);
|
||||
var darkBackgroundWriter = new ColorfulConsoleWriter(EnvironmentUtility.DetectPlatform(), MonitorColorScheme.DarkBackground);
|
||||
|
||||
// print question
|
||||
this.PrintPlain("Which text looks more readable?");
|
||||
|
@ -226,7 +226,7 @@ namespace StardewModdingApi.Installer
|
|||
Console.Write(" [1] ");
|
||||
lightBackgroundWriter.WriteLine("Dark text on light background", ConsoleLogLevel.Info);
|
||||
Console.Write(" [2] ");
|
||||
darkDarkgroundWriter.WriteLine("Light text on dark background", ConsoleLogLevel.Info);
|
||||
darkBackgroundWriter.WriteLine("Light text on dark background", ConsoleLogLevel.Info);
|
||||
Console.WriteLine();
|
||||
|
||||
// handle choice
|
||||
|
@ -239,7 +239,7 @@ namespace StardewModdingApi.Installer
|
|||
break;
|
||||
case "2":
|
||||
scheme = MonitorColorScheme.DarkBackground;
|
||||
this.ConsoleWriter = darkDarkgroundWriter;
|
||||
this.ConsoleWriter = darkBackgroundWriter;
|
||||
break;
|
||||
default:
|
||||
throw new InvalidOperationException($"Unexpected action key '{choice}'.");
|
||||
|
@ -646,7 +646,7 @@ namespace StardewModdingApi.Installer
|
|||
|
||||
/// <summary>Delete a file or folder regardless of file permissions, and block until deletion completes.</summary>
|
||||
/// <param name="entry">The file or folder to reset.</param>
|
||||
/// <remarks>This method is mirred from <c>FileUtilities.ForceDelete</c> in the toolkit.</remarks>
|
||||
/// <remarks>This method is mirrored from <c>FileUtilities.ForceDelete</c> in the toolkit.</remarks>
|
||||
private void ForceDelete(FileSystemInfo entry)
|
||||
{
|
||||
// ignore if already deleted
|
||||
|
@ -762,7 +762,7 @@ namespace StardewModdingApi.Installer
|
|||
continue;
|
||||
}
|
||||
|
||||
// normalise path
|
||||
// normalize path
|
||||
if (platform == Platform.Windows)
|
||||
path = path.Replace("\"", ""); // in Windows, quotes are used to escape spaces and aren't part of the file path
|
||||
if (platform == Platform.Linux || platform == Platform.Mac)
|
||||
|
|
|
@ -36,7 +36,7 @@ namespace StardewModdingApi.Installer
|
|||
FileInfo zipFile = new FileInfo(Path.Combine(Program.InstallerPath, $"{(platform == PlatformID.Win32NT ? "windows" : "unix")}-install.dat"));
|
||||
if (!zipFile.Exists)
|
||||
{
|
||||
Console.WriteLine($"Oops! Some of the installer files are missing; try redownloading the installer. (Missing file: {zipFile.FullName})");
|
||||
Console.WriteLine($"Oops! Some of the installer files are missing; try re-downloading the installer. (Missing file: {zipFile.FullName})");
|
||||
Console.ReadLine();
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -126,7 +126,7 @@ namespace StardewModdingAPI.Internal.ConsoleWriting
|
|||
case ConsoleColor.Black:
|
||||
case ConsoleColor.Blue:
|
||||
case ConsoleColor.DarkBlue:
|
||||
case ConsoleColor.DarkMagenta: // Powershell
|
||||
case ConsoleColor.DarkMagenta: // PowerShell
|
||||
case ConsoleColor.DarkRed:
|
||||
case ConsoleColor.Red:
|
||||
return true;
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
namespace Netcode
|
||||
{
|
||||
/// <summary>A simplified version of Stardew Valley's <c>Netcode.NetFieldBase</c> for unit testing.</summary>
|
||||
/// <typeparam name="T">The type of the synchronised value.</typeparam>
|
||||
/// <typeparam name="T">The type of the synchronized value.</typeparam>
|
||||
/// <typeparam name="TSelf">The type of the current instance.</typeparam>
|
||||
public class NetFieldBase<T, TSelf> where TSelf : NetFieldBase<T, TSelf>
|
||||
{
|
||||
|
|
|
@ -199,7 +199,7 @@ namespace StardewModdingAPI.ModBuildConfig.Analyzer
|
|||
/*********
|
||||
** Private methods
|
||||
*********/
|
||||
/// <summary>Analyse a member access syntax node and add a diagnostic message if applicable.</summary>
|
||||
/// <summary>Analyze a member access syntax node and add a diagnostic message if applicable.</summary>
|
||||
/// <param name="context">The analysis context.</param>
|
||||
/// <returns>Returns whether any warnings were added.</returns>
|
||||
private void AnalyzeMemberAccess(SyntaxNodeAnalysisContext context)
|
||||
|
@ -231,7 +231,7 @@ namespace StardewModdingAPI.ModBuildConfig.Analyzer
|
|||
});
|
||||
}
|
||||
|
||||
/// <summary>Analyse an explicit cast or 'x as y' node and add a diagnostic message if applicable.</summary>
|
||||
/// <summary>Analyze an explicit cast or 'x as y' node and add a diagnostic message if applicable.</summary>
|
||||
/// <param name="context">The analysis context.</param>
|
||||
/// <returns>Returns whether any warnings were added.</returns>
|
||||
private void AnalyzeCast(SyntaxNodeAnalysisContext context)
|
||||
|
@ -248,7 +248,7 @@ namespace StardewModdingAPI.ModBuildConfig.Analyzer
|
|||
});
|
||||
}
|
||||
|
||||
/// <summary>Analyse a binary comparison syntax node and add a diagnostic message if applicable.</summary>
|
||||
/// <summary>Analyze a binary comparison syntax node and add a diagnostic message if applicable.</summary>
|
||||
/// <param name="context">The analysis context.</param>
|
||||
/// <returns>Returns whether any warnings were added.</returns>
|
||||
private void AnalyzeBinaryComparison(SyntaxNodeAnalysisContext context)
|
||||
|
@ -288,7 +288,7 @@ namespace StardewModdingAPI.ModBuildConfig.Analyzer
|
|||
}
|
||||
|
||||
/// <summary>Handle exceptions raised while analyzing a node.</summary>
|
||||
/// <param name="node">The node being analysed.</param>
|
||||
/// <param name="node">The node being analyzed.</param>
|
||||
/// <param name="action">The callback to invoke.</param>
|
||||
private void HandleErrors(SyntaxNode node, Action action)
|
||||
{
|
||||
|
|
|
@ -67,7 +67,7 @@ namespace StardewModdingAPI.ModBuildConfig.Analyzer
|
|||
/*********
|
||||
** Private methods
|
||||
*********/
|
||||
/// <summary>Analyse a syntax node and add a diagnostic message if it references an obsolete field.</summary>
|
||||
/// <summary>Analyze a syntax node and add a diagnostic message if it references an obsolete field.</summary>
|
||||
/// <param name="context">The analysis context.</param>
|
||||
private void AnalyzeObsoleteFields(SyntaxNodeAnalysisContext context)
|
||||
{
|
||||
|
|
|
@ -3,8 +3,8 @@ using System.Collections.Generic;
|
|||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text.RegularExpressions;
|
||||
using StardewModdingAPI.Toolkit.Serialisation;
|
||||
using StardewModdingAPI.Toolkit.Serialisation.Models;
|
||||
using StardewModdingAPI.Toolkit.Serialization;
|
||||
using StardewModdingAPI.Toolkit.Serialization.Models;
|
||||
using StardewModdingAPI.Toolkit.Utilities;
|
||||
|
||||
namespace StardewModdingAPI.ModBuildConfig.Framework
|
||||
|
|
|
@ -15,7 +15,7 @@ namespace StardewModdingAPI.Mods.ConsoleCommands.Framework.Commands.Player
|
|||
/// <summary>Provides methods for searching and constructing items.</summary>
|
||||
private readonly ItemRepository Items = new ItemRepository();
|
||||
|
||||
/// <summary>The type names recognised by this command.</summary>
|
||||
/// <summary>The type names recognized by this command.</summary>
|
||||
private readonly string[] ValidTypes = Enum.GetNames(typeof(ItemType)).Concat(new[] { "Name" }).ToArray();
|
||||
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
using System;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using StardewModdingAPI.Mods.ConsoleCommands.Framework.ItemData;
|
||||
|
@ -58,7 +58,7 @@ namespace StardewModdingAPI.Mods.ConsoleCommands.Framework.Commands.Player
|
|||
/// <param name="searchWords">The search string to find.</param>
|
||||
private IEnumerable<SearchableItem> GetItems(string[] searchWords)
|
||||
{
|
||||
// normalise search term
|
||||
// normalize search term
|
||||
searchWords = searchWords?.Where(word => !string.IsNullOrWhiteSpace(word)).ToArray();
|
||||
if (searchWords?.Any() == false)
|
||||
searchWords = null;
|
||||
|
|
|
@ -60,7 +60,7 @@ namespace StardewModdingAPI.Mods.ConsoleCommands.Framework.Commands.World
|
|||
{
|
||||
for (int i = 0; i > intervals; i--)
|
||||
{
|
||||
Game1.timeOfDay = FromTimeSpan(ToTimeSpan(Game1.timeOfDay).Subtract(TimeSpan.FromMinutes(20))); // offset 20 mins so game updates to next interval
|
||||
Game1.timeOfDay = FromTimeSpan(ToTimeSpan(Game1.timeOfDay).Subtract(TimeSpan.FromMinutes(20))); // offset 20 minutes so game updates to next interval
|
||||
Game1.performTenMinuteClockUpdate();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,7 +9,7 @@ using StardewModdingAPI.Framework;
|
|||
using StardewModdingAPI.Framework.ModLoading;
|
||||
using StardewModdingAPI.Toolkit;
|
||||
using StardewModdingAPI.Toolkit.Framework.ModData;
|
||||
using StardewModdingAPI.Toolkit.Serialisation.Models;
|
||||
using StardewModdingAPI.Toolkit.Serialization.Models;
|
||||
|
||||
namespace StardewModdingAPI.Tests.Core
|
||||
{
|
||||
|
@ -55,7 +55,7 @@ namespace StardewModdingAPI.Tests.Core
|
|||
Assert.IsNotNull(mod.Error, "The mod metadata did not have an error message set.");
|
||||
}
|
||||
|
||||
[Test(Description = "Assert that the resolver correctly reads manifest data from a randomised file.")]
|
||||
[Test(Description = "Assert that the resolver correctly reads manifest data from a randomized file.")]
|
||||
public void ReadBasicManifest_CanReadFile()
|
||||
{
|
||||
// create manifest data
|
||||
|
@ -468,7 +468,7 @@ namespace StardewModdingAPI.Tests.Core
|
|||
return Path.Combine(Path.GetTempPath(), "smapi-unit-tests", Guid.NewGuid().ToString("N"));
|
||||
}
|
||||
|
||||
/// <summary>Get a randomised basic manifest.</summary>
|
||||
/// <summary>Get a randomized basic manifest.</summary>
|
||||
/// <param name="id">The <see cref="IManifest.UniqueID"/> value, or <c>null</c> for a generated value.</param>
|
||||
/// <param name="name">The <see cref="IManifest.Name"/> value, or <c>null</c> for a generated value.</param>
|
||||
/// <param name="version">The <see cref="IManifest.Version"/> value, or <c>null</c> for a generated value.</param>
|
||||
|
@ -492,14 +492,14 @@ namespace StardewModdingAPI.Tests.Core
|
|||
};
|
||||
}
|
||||
|
||||
/// <summary>Get a randomised basic manifest.</summary>
|
||||
/// <summary>Get a randomized basic manifest.</summary>
|
||||
/// <param name="uniqueID">The mod's name and unique ID.</param>
|
||||
private Mock<IModMetadata> GetMetadata(string uniqueID)
|
||||
{
|
||||
return this.GetMetadata(this.GetManifest(uniqueID, "1.0"));
|
||||
}
|
||||
|
||||
/// <summary>Get a randomised basic manifest.</summary>
|
||||
/// <summary>Get a randomized basic manifest.</summary>
|
||||
/// <param name="uniqueID">The mod's name and unique ID.</param>
|
||||
/// <param name="dependencies">The dependencies this mod requires.</param>
|
||||
/// <param name="allowStatusChange">Whether the code being tested is allowed to change the mod status.</param>
|
||||
|
@ -509,7 +509,7 @@ namespace StardewModdingAPI.Tests.Core
|
|||
return this.GetMetadata(manifest, allowStatusChange);
|
||||
}
|
||||
|
||||
/// <summary>Get a randomised basic manifest.</summary>
|
||||
/// <summary>Get a randomized basic manifest.</summary>
|
||||
/// <param name="manifest">The mod manifest.</param>
|
||||
/// <param name="allowStatusChange">Whether the code being tested is allowed to change the mod status.</param>
|
||||
private Mock<IModMetadata> GetMetadata(IManifest manifest, bool allowStatusChange = false)
|
||||
|
|
|
@ -245,7 +245,7 @@ namespace StardewModdingAPI.Tests.Core
|
|||
[TestCase("{{value}}", "value")]
|
||||
[TestCase("{{VaLuE}}", "vAlUe")]
|
||||
[TestCase("{{VaLuE }}", " vAlUe")]
|
||||
public void Translation_Tokens_KeysAreNormalised(string text, string key)
|
||||
public void Translation_Tokens_KeysAreNormalized(string text, string key)
|
||||
{
|
||||
// arrange
|
||||
string value = Guid.NewGuid().ToString("N");
|
||||
|
|
|
@ -25,7 +25,7 @@ namespace StardewModdingAPI.Tests.Toolkit
|
|||
return string.Join("|", PathUtilities.GetSegments(path));
|
||||
}
|
||||
|
||||
[Test(Description = "Assert that NormalisePathSeparators returns the expected values.")]
|
||||
[Test(Description = "Assert that NormalizePathSeparators returns the expected values.")]
|
||||
#if SMAPI_FOR_WINDOWS
|
||||
[TestCase("", ExpectedResult = "")]
|
||||
[TestCase("/", ExpectedResult = "")]
|
||||
|
@ -47,9 +47,9 @@ namespace StardewModdingAPI.Tests.Toolkit
|
|||
[TestCase("C:/boop", ExpectedResult = "C:/boop")]
|
||||
[TestCase(@"C:\usr\bin//.././boop.exe", ExpectedResult = "C:/usr/bin/.././boop.exe")]
|
||||
#endif
|
||||
public string NormalisePathSeparators(string path)
|
||||
public string NormalizePathSeparators(string path)
|
||||
{
|
||||
return PathUtilities.NormalisePathSeparators(path);
|
||||
return PathUtilities.NormalizePathSeparators(path);
|
||||
}
|
||||
|
||||
[Test(Description = "Assert that GetRelativePath returns the expected values.")]
|
||||
|
|
|
@ -243,19 +243,19 @@ namespace StardewModdingAPI.Tests.Utilities
|
|||
}
|
||||
|
||||
/****
|
||||
** Serialisable
|
||||
** Serializable
|
||||
****/
|
||||
[Test(Description = "Assert that SemanticVersion can be round-tripped through JSON with no special configuration.")]
|
||||
[TestCase("1.0")]
|
||||
public void Serialisable(string versionStr)
|
||||
public void Serializable(string versionStr)
|
||||
{
|
||||
// act
|
||||
string json = JsonConvert.SerializeObject(new SemanticVersion(versionStr));
|
||||
SemanticVersion after = JsonConvert.DeserializeObject<SemanticVersion>(json);
|
||||
|
||||
// assert
|
||||
Assert.IsNotNull(after, "The semantic version after deserialisation is unexpectedly null.");
|
||||
Assert.AreEqual(versionStr, after.ToString(), "The semantic version after deserialisation doesn't match the input version.");
|
||||
Assert.IsNotNull(after, "The semantic version after deserialization is unexpectedly null.");
|
||||
Assert.AreEqual(versionStr, after.ToString(), "The semantic version after deserialization doesn't match the input version.");
|
||||
}
|
||||
|
||||
/****
|
||||
|
|
|
@ -24,7 +24,7 @@ namespace StardewModdingAPI
|
|||
/*********
|
||||
** Accessors
|
||||
*********/
|
||||
/// <summary>Whether this is a pre-release version.</summary>
|
||||
/// <summary>Whether this is a prerelease version.</summary>
|
||||
bool IsPrerelease();
|
||||
|
||||
/// <summary>Get whether this version is older than the specified version.</summary>
|
||||
|
|
|
@ -48,7 +48,7 @@ namespace StardewModdingAPI.Toolkit.Framework.Clients.WebApi
|
|||
[JsonConverter(typeof(StringEnumConverter))]
|
||||
public WikiCompatibilityStatus? CompatibilityStatus { get; set; }
|
||||
|
||||
/// <summary>The human-readable summary of the compatibility status or workaround, without HTML formatitng.</summary>
|
||||
/// <summary>The human-readable summary of the compatibility status or workaround, without HTML formatting.</summary>
|
||||
public string CompatibilitySummary { get; set; }
|
||||
|
||||
/// <summary>The game or SMAPI version which broke this mod, if applicable.</summary>
|
||||
|
@ -62,7 +62,7 @@ namespace StardewModdingAPI.Toolkit.Framework.Clients.WebApi
|
|||
[JsonConverter(typeof(StringEnumConverter))]
|
||||
public WikiCompatibilityStatus? BetaCompatibilityStatus { get; set; }
|
||||
|
||||
/// <summary>The human-readable summary of the compatibility status or workaround for the Stardew Valley beta (if any), without HTML formatitng.</summary>
|
||||
/// <summary>The human-readable summary of the compatibility status or workaround for the Stardew Valley beta (if any), without HTML formatting.</summary>
|
||||
public string BetaCompatibilitySummary { get; set; }
|
||||
|
||||
/// <summary>The beta game or SMAPI version which broke this mod, if applicable.</summary>
|
||||
|
|
|
@ -21,7 +21,7 @@ namespace StardewModdingAPI.Toolkit.Framework.Clients.WebApi
|
|||
/// <summary>Construct an empty instance.</summary>
|
||||
public ModSearchModel()
|
||||
{
|
||||
// needed for JSON deserialising
|
||||
// needed for JSON deserializing
|
||||
}
|
||||
|
||||
/// <summary>Construct an instance.</summary>
|
||||
|
|
|
@ -19,7 +19,7 @@ namespace StardewModdingAPI.Toolkit.Framework.Clients.WebApi
|
|||
/// <summary>Construct an empty instance.</summary>
|
||||
public ModSearchEntryModel()
|
||||
{
|
||||
// needed for JSON deserialising
|
||||
// needed for JSON deserializing
|
||||
}
|
||||
|
||||
/// <summary>Construct an instance.</summary>
|
||||
|
|
|
@ -3,7 +3,7 @@ using System.Collections.Generic;
|
|||
using System.Linq;
|
||||
using System.Net;
|
||||
using Newtonsoft.Json;
|
||||
using StardewModdingAPI.Toolkit.Serialisation;
|
||||
using StardewModdingAPI.Toolkit.Serialization;
|
||||
|
||||
namespace StardewModdingAPI.Toolkit.Framework.Clients.WebApi
|
||||
{
|
||||
|
|
|
@ -29,7 +29,7 @@ namespace StardewModdingAPI.Toolkit.Framework.GameScanning
|
|||
IEnumerable<string> paths = this
|
||||
.GetCustomInstallPaths(platform)
|
||||
.Concat(this.GetDefaultInstallPaths(platform))
|
||||
.Select(PathUtilities.NormalisePathSeparators)
|
||||
.Select(PathUtilities.NormalizePathSeparators)
|
||||
.Distinct(StringComparer.InvariantCultureIgnoreCase);
|
||||
|
||||
// yield valid folders
|
||||
|
|
|
@ -112,8 +112,8 @@ namespace StardewModdingAPI.Toolkit.Framework.ModData
|
|||
/*********
|
||||
** Private methods
|
||||
*********/
|
||||
/// <summary>The method invoked after JSON deserialisation.</summary>
|
||||
/// <param name="context">The deserialisation context.</param>
|
||||
/// <summary>The method invoked after JSON deserialization.</summary>
|
||||
/// <param name="context">The deserialization context.</param>
|
||||
[OnDeserialized]
|
||||
private void OnDeserialized(StreamingContext context)
|
||||
{
|
||||
|
|
|
@ -68,7 +68,7 @@ namespace StardewModdingAPI.Toolkit.Framework.ModData
|
|||
}
|
||||
|
||||
/// <summary>Get a semantic local version for update checks.</summary>
|
||||
/// <param name="version">The remote version to normalise.</param>
|
||||
/// <param name="version">The remote version to normalize.</param>
|
||||
public ISemanticVersion GetLocalVersionForUpdateChecks(ISemanticVersion version)
|
||||
{
|
||||
return this.MapLocalVersions != null && this.MapLocalVersions.TryGetValue(version.ToString(), out string newVersion)
|
||||
|
@ -77,10 +77,10 @@ namespace StardewModdingAPI.Toolkit.Framework.ModData
|
|||
}
|
||||
|
||||
/// <summary>Get a semantic remote version for update checks.</summary>
|
||||
/// <param name="version">The remote version to normalise.</param>
|
||||
/// <param name="version">The remote version to normalize.</param>
|
||||
public string GetRemoteVersionForUpdateChecks(string version)
|
||||
{
|
||||
// normalise version if possible
|
||||
// normalize version if possible
|
||||
if (SemanticVersion.TryParse(version, out ISemanticVersion parsed))
|
||||
version = parsed.ToString();
|
||||
|
||||
|
|
|
@ -32,14 +32,14 @@ namespace StardewModdingAPI.Toolkit.Framework.ModData
|
|||
** Public methods
|
||||
*********/
|
||||
/// <summary>Get a semantic local version for update checks.</summary>
|
||||
/// <param name="version">The remote version to normalise.</param>
|
||||
/// <param name="version">The remote version to normalize.</param>
|
||||
public ISemanticVersion GetLocalVersionForUpdateChecks(ISemanticVersion version)
|
||||
{
|
||||
return this.DataRecord.GetLocalVersionForUpdateChecks(version);
|
||||
}
|
||||
|
||||
/// <summary>Get a semantic remote version for update checks.</summary>
|
||||
/// <param name="version">The remote version to normalise.</param>
|
||||
/// <param name="version">The remote version to normalize.</param>
|
||||
public ISemanticVersion GetRemoteVersionForUpdateChecks(ISemanticVersion version)
|
||||
{
|
||||
if (version == null)
|
||||
|
|
|
@ -13,7 +13,7 @@ namespace StardewModdingAPI.Toolkit.Framework.ModData
|
|||
BrokenCodeLoaded = 1,
|
||||
|
||||
/// <summary>The mod affects the save serializer in a way that may make saves unloadable without the mod.</summary>
|
||||
ChangesSaveSerialiser = 2,
|
||||
ChangesSaveSerializer = 2,
|
||||
|
||||
/// <summary>The mod patches the game in a way that may impact stability.</summary>
|
||||
PatchesGame = 4,
|
||||
|
@ -21,7 +21,7 @@ namespace StardewModdingAPI.Toolkit.Framework.ModData
|
|||
/// <summary>The mod uses the <c>dynamic</c> keyword which won't work on Linux/Mac.</summary>
|
||||
UsesDynamic = 8,
|
||||
|
||||
/// <summary>The mod references specialised 'unvalided update tick' events which may impact stability.</summary>
|
||||
/// <summary>The mod references specialized 'unvalidated update tick' events which may impact stability.</summary>
|
||||
UsesUnvalidatedUpdateTick = 16,
|
||||
|
||||
/// <summary>The mod has no update keys set.</summary>
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using StardewModdingAPI.Toolkit.Serialisation.Models;
|
||||
using StardewModdingAPI.Toolkit.Serialization.Models;
|
||||
using StardewModdingAPI.Toolkit.Utilities;
|
||||
|
||||
namespace StardewModdingAPI.Toolkit.Framework.ModScanning
|
||||
|
|
|
@ -3,8 +3,8 @@ using System.Collections.Generic;
|
|||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text.RegularExpressions;
|
||||
using StardewModdingAPI.Toolkit.Serialisation;
|
||||
using StardewModdingAPI.Toolkit.Serialisation.Models;
|
||||
using StardewModdingAPI.Toolkit.Serialization;
|
||||
using StardewModdingAPI.Toolkit.Serialization.Models;
|
||||
|
||||
namespace StardewModdingAPI.Toolkit.Framework.ModScanning
|
||||
{
|
||||
|
@ -118,7 +118,7 @@ namespace StardewModdingAPI.Toolkit.Framework.ModScanning
|
|||
}
|
||||
}
|
||||
|
||||
// normalise display fields
|
||||
// normalize display fields
|
||||
if (manifest != null)
|
||||
{
|
||||
manifest.Name = this.StripNewlines(manifest.Name);
|
||||
|
|
|
@ -8,7 +8,7 @@ using StardewModdingAPI.Toolkit.Framework.Clients.Wiki;
|
|||
using StardewModdingAPI.Toolkit.Framework.GameScanning;
|
||||
using StardewModdingAPI.Toolkit.Framework.ModData;
|
||||
using StardewModdingAPI.Toolkit.Framework.ModScanning;
|
||||
using StardewModdingAPI.Toolkit.Serialisation;
|
||||
using StardewModdingAPI.Toolkit.Serialization;
|
||||
|
||||
namespace StardewModdingAPI.Toolkit
|
||||
{
|
||||
|
|
|
@ -56,7 +56,7 @@ namespace StardewModdingAPI.Toolkit
|
|||
this.MajorVersion = major;
|
||||
this.MinorVersion = minor;
|
||||
this.PatchVersion = patch;
|
||||
this.PrereleaseTag = this.GetNormalisedTag(prereleaseTag);
|
||||
this.PrereleaseTag = this.GetNormalizedTag(prereleaseTag);
|
||||
|
||||
this.AssertValid();
|
||||
}
|
||||
|
@ -89,16 +89,16 @@ namespace StardewModdingAPI.Toolkit
|
|||
if (!match.Success)
|
||||
throw new FormatException($"The input '{version}' isn't a valid semantic version.");
|
||||
|
||||
// initialise
|
||||
// initialize
|
||||
this.MajorVersion = int.Parse(match.Groups["major"].Value);
|
||||
this.MinorVersion = match.Groups["minor"].Success ? int.Parse(match.Groups["minor"].Value) : 0;
|
||||
this.PatchVersion = match.Groups["patch"].Success ? int.Parse(match.Groups["patch"].Value) : 0;
|
||||
this.PrereleaseTag = match.Groups["prerelease"].Success ? this.GetNormalisedTag(match.Groups["prerelease"].Value) : null;
|
||||
this.PrereleaseTag = match.Groups["prerelease"].Success ? this.GetNormalizedTag(match.Groups["prerelease"].Value) : null;
|
||||
|
||||
this.AssertValid();
|
||||
}
|
||||
|
||||
/// <summary>Get an integer indicating whether this version precedes (less than 0), supercedes (more than 0), or is equivalent to (0) the specified version.</summary>
|
||||
/// <summary>Get an integer indicating whether this version precedes (less than 0), supersedes (more than 0), or is equivalent to (0) the specified version.</summary>
|
||||
/// <param name="other">The version to compare with this instance.</param>
|
||||
/// <exception cref="ArgumentNullException">The <paramref name="other"/> value is null.</exception>
|
||||
public int CompareTo(ISemanticVersion other)
|
||||
|
@ -116,7 +116,7 @@ namespace StardewModdingAPI.Toolkit
|
|||
return other != null && this.CompareTo(other) == 0;
|
||||
}
|
||||
|
||||
/// <summary>Whether this is a pre-release version.</summary>
|
||||
/// <summary>Whether this is a prerelease version.</summary>
|
||||
public bool IsPrerelease()
|
||||
{
|
||||
return !string.IsNullOrWhiteSpace(this.PrereleaseTag);
|
||||
|
@ -206,15 +206,15 @@ namespace StardewModdingAPI.Toolkit
|
|||
/*********
|
||||
** Private methods
|
||||
*********/
|
||||
/// <summary>Get a normalised build tag.</summary>
|
||||
/// <param name="tag">The tag to normalise.</param>
|
||||
private string GetNormalisedTag(string tag)
|
||||
/// <summary>Get a normalized build tag.</summary>
|
||||
/// <param name="tag">The tag to normalize.</param>
|
||||
private string GetNormalizedTag(string tag)
|
||||
{
|
||||
tag = tag?.Trim();
|
||||
return !string.IsNullOrWhiteSpace(tag) ? tag : null;
|
||||
}
|
||||
|
||||
/// <summary>Get an integer indicating whether this version precedes (less than 0), supercedes (more than 0), or is equivalent to (0) the specified version.</summary>
|
||||
/// <summary>Get an integer indicating whether this version precedes (less than 0), supersedes (more than 0), or is equivalent to (0) the specified version.</summary>
|
||||
/// <param name="otherMajor">The major version to compare with this instance.</param>
|
||||
/// <param name="otherMinor">The minor version to compare with this instance.</param>
|
||||
/// <param name="otherPatch">The patch version to compare with this instance.</param>
|
||||
|
@ -235,7 +235,7 @@ namespace StardewModdingAPI.Toolkit
|
|||
if (this.PrereleaseTag == otherTag)
|
||||
return same;
|
||||
|
||||
// stable supercedes pre-release
|
||||
// stable supersedes prerelease
|
||||
bool curIsStable = string.IsNullOrWhiteSpace(this.PrereleaseTag);
|
||||
bool otherIsStable = string.IsNullOrWhiteSpace(otherTag);
|
||||
if (curIsStable)
|
||||
|
@ -243,12 +243,12 @@ namespace StardewModdingAPI.Toolkit
|
|||
if (otherIsStable)
|
||||
return curOlder;
|
||||
|
||||
// compare two pre-release tag values
|
||||
// compare two prerelease tag values
|
||||
string[] curParts = this.PrereleaseTag.Split('.', '-');
|
||||
string[] otherParts = otherTag.Split('.', '-');
|
||||
for (int i = 0; i < curParts.Length; i++)
|
||||
{
|
||||
// longer prerelease tag supercedes if otherwise equal
|
||||
// longer prerelease tag supersedes if otherwise equal
|
||||
if (otherParts.Length <= i)
|
||||
return curNewer;
|
||||
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
using System;
|
||||
using Newtonsoft.Json;
|
||||
using StardewModdingAPI.Toolkit.Serialisation.Models;
|
||||
using StardewModdingAPI.Toolkit.Serialization.Models;
|
||||
|
||||
namespace StardewModdingAPI.Toolkit.Serialisation.Converters
|
||||
namespace StardewModdingAPI.Toolkit.Serialization.Converters
|
||||
{
|
||||
/// <summary>Handles deserialisation of <see cref="ManifestContentPackFor"/> arrays.</summary>
|
||||
/// <summary>Handles deserialization of <see cref="ManifestContentPackFor"/> arrays.</summary>
|
||||
public class ManifestContentPackForConverter : JsonConverter
|
||||
{
|
||||
/*********
|
|
@ -2,11 +2,11 @@ using System;
|
|||
using System.Collections.Generic;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using StardewModdingAPI.Toolkit.Serialisation.Models;
|
||||
using StardewModdingAPI.Toolkit.Serialization.Models;
|
||||
|
||||
namespace StardewModdingAPI.Toolkit.Serialisation.Converters
|
||||
namespace StardewModdingAPI.Toolkit.Serialization.Converters
|
||||
{
|
||||
/// <summary>Handles deserialisation of <see cref="ManifestDependency"/> arrays.</summary>
|
||||
/// <summary>Handles deserialization of <see cref="ManifestDependency"/> arrays.</summary>
|
||||
internal class ManifestDependencyArrayConverter : JsonConverter
|
||||
{
|
||||
/*********
|
|
@ -2,9 +2,9 @@ using System;
|
|||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
|
||||
namespace StardewModdingAPI.Toolkit.Serialisation.Converters
|
||||
namespace StardewModdingAPI.Toolkit.Serialization.Converters
|
||||
{
|
||||
/// <summary>Handles deserialisation of <see cref="ISemanticVersion"/>.</summary>
|
||||
/// <summary>Handles deserialization of <see cref="ISemanticVersion"/>.</summary>
|
||||
internal class SemanticVersionConverter : JsonConverter
|
||||
{
|
||||
/*********
|
|
@ -2,10 +2,10 @@ using System;
|
|||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
|
||||
namespace StardewModdingAPI.Toolkit.Serialisation.Converters
|
||||
namespace StardewModdingAPI.Toolkit.Serialization.Converters
|
||||
{
|
||||
/// <summary>The base implementation for simplified converters which deserialise <typeparamref name="T"/> without overriding serialisation.</summary>
|
||||
/// <typeparam name="T">The type to deserialise.</typeparam>
|
||||
/// <summary>The base implementation for simplified converters which deserialize <typeparamref name="T"/> without overriding serialization.</summary>
|
||||
/// <typeparam name="T">The type to deserialize.</typeparam>
|
||||
internal abstract class SimpleReadOnlyConverter<T> : JsonConverter
|
||||
{
|
||||
/*********
|
|
@ -1,7 +1,7 @@
|
|||
using System;
|
||||
using Newtonsoft.Json.Linq;
|
||||
|
||||
namespace StardewModdingAPI.Toolkit.Serialisation
|
||||
namespace StardewModdingAPI.Toolkit.Serialization
|
||||
{
|
||||
/// <summary>Provides extension methods for parsing JSON.</summary>
|
||||
public static class JsonExtensions
|
|
@ -3,9 +3,9 @@ using System.Collections.Generic;
|
|||
using System.IO;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Converters;
|
||||
using StardewModdingAPI.Toolkit.Serialisation.Converters;
|
||||
using StardewModdingAPI.Toolkit.Serialization.Converters;
|
||||
|
||||
namespace StardewModdingAPI.Toolkit.Serialisation
|
||||
namespace StardewModdingAPI.Toolkit.Serialization
|
||||
{
|
||||
/// <summary>Encapsulates SMAPI's JSON file parsing.</summary>
|
||||
public class JsonHelper
|
||||
|
@ -13,7 +13,7 @@ namespace StardewModdingAPI.Toolkit.Serialisation
|
|||
/*********
|
||||
** Accessors
|
||||
*********/
|
||||
/// <summary>The JSON settings to use when serialising and deserialising files.</summary>
|
||||
/// <summary>The JSON settings to use when serializing and deserializing files.</summary>
|
||||
public JsonSerializerSettings JsonSettings { get; } = new JsonSerializerSettings
|
||||
{
|
||||
Formatting = Formatting.Indented,
|
||||
|
@ -31,7 +31,7 @@ namespace StardewModdingAPI.Toolkit.Serialisation
|
|||
*********/
|
||||
/// <summary>Read a JSON file.</summary>
|
||||
/// <typeparam name="TModel">The model type.</typeparam>
|
||||
/// <param name="fullPath">The absolete file path.</param>
|
||||
/// <param name="fullPath">The absolute file path.</param>
|
||||
/// <param name="result">The parsed content model.</param>
|
||||
/// <returns>Returns false if the file doesn't exist, else true.</returns>
|
||||
/// <exception cref="ArgumentException">The given <paramref name="fullPath"/> is empty or invalid.</exception>
|
||||
|
@ -54,10 +54,10 @@ namespace StardewModdingAPI.Toolkit.Serialisation
|
|||
return false;
|
||||
}
|
||||
|
||||
// deserialise model
|
||||
// deserialize model
|
||||
try
|
||||
{
|
||||
result = this.Deserialise<TModel>(json);
|
||||
result = this.Deserialize<TModel>(json);
|
||||
return true;
|
||||
}
|
||||
catch (Exception ex)
|
||||
|
@ -77,7 +77,7 @@ namespace StardewModdingAPI.Toolkit.Serialisation
|
|||
|
||||
/// <summary>Save to a JSON file.</summary>
|
||||
/// <typeparam name="TModel">The model type.</typeparam>
|
||||
/// <param name="fullPath">The absolete file path.</param>
|
||||
/// <param name="fullPath">The absolute file path.</param>
|
||||
/// <param name="model">The model to save.</param>
|
||||
/// <exception cref="InvalidOperationException">The given path is empty or invalid.</exception>
|
||||
public void WriteJsonFile<TModel>(string fullPath, TModel model)
|
||||
|
@ -95,14 +95,14 @@ namespace StardewModdingAPI.Toolkit.Serialisation
|
|||
Directory.CreateDirectory(dir);
|
||||
|
||||
// write file
|
||||
string json = this.Serialise(model);
|
||||
string json = this.Serialize(model);
|
||||
File.WriteAllText(fullPath, json);
|
||||
}
|
||||
|
||||
/// <summary>Deserialize JSON text if possible.</summary>
|
||||
/// <typeparam name="TModel">The model type.</typeparam>
|
||||
/// <param name="json">The raw JSON text.</param>
|
||||
public TModel Deserialise<TModel>(string json)
|
||||
public TModel Deserialize<TModel>(string json)
|
||||
{
|
||||
try
|
||||
{
|
||||
|
@ -126,9 +126,9 @@ namespace StardewModdingAPI.Toolkit.Serialisation
|
|||
|
||||
/// <summary>Serialize a model to JSON text.</summary>
|
||||
/// <typeparam name="TModel">The model type.</typeparam>
|
||||
/// <param name="model">The model to serialise.</param>
|
||||
/// <param name="model">The model to serialize.</param>
|
||||
/// <param name="formatting">The formatting to apply.</param>
|
||||
public string Serialise<TModel>(TModel model, Formatting formatting = Formatting.Indented)
|
||||
public string Serialize<TModel>(TModel model, Formatting formatting = Formatting.Indented)
|
||||
{
|
||||
return JsonConvert.SerializeObject(model, formatting, this.JsonSettings);
|
||||
}
|
|
@ -1,8 +1,8 @@
|
|||
using System.Collections.Generic;
|
||||
using Newtonsoft.Json;
|
||||
using StardewModdingAPI.Toolkit.Serialisation.Converters;
|
||||
using StardewModdingAPI.Toolkit.Serialization.Converters;
|
||||
|
||||
namespace StardewModdingAPI.Toolkit.Serialisation.Models
|
||||
namespace StardewModdingAPI.Toolkit.Serialization.Models
|
||||
{
|
||||
/// <summary>A manifest which describes a mod for SMAPI.</summary>
|
||||
public class Manifest : IManifest
|
|
@ -1,4 +1,4 @@
|
|||
namespace StardewModdingAPI.Toolkit.Serialisation.Models
|
||||
namespace StardewModdingAPI.Toolkit.Serialization.Models
|
||||
{
|
||||
/// <summary>Indicates which mod can read the content pack represented by the containing manifest.</summary>
|
||||
public class ManifestContentPackFor : IManifestContentPackFor
|
|
@ -1,4 +1,4 @@
|
|||
namespace StardewModdingAPI.Toolkit.Serialisation.Models
|
||||
namespace StardewModdingAPI.Toolkit.Serialization.Models
|
||||
{
|
||||
/// <summary>A mod dependency listed in a mod manifest.</summary>
|
||||
public class ManifestDependency : IManifestDependency
|
|
@ -1,6 +1,6 @@
|
|||
using System;
|
||||
|
||||
namespace StardewModdingAPI.Toolkit.Serialisation
|
||||
namespace StardewModdingAPI.Toolkit.Serialization
|
||||
{
|
||||
/// <summary>A format exception which provides a user-facing error message.</summary>
|
||||
internal class SParseException : FormatException
|
|
@ -6,7 +6,7 @@ using System.Text.RegularExpressions;
|
|||
|
||||
namespace StardewModdingAPI.Toolkit.Utilities
|
||||
{
|
||||
/// <summary>Provides utilities for normalising file paths.</summary>
|
||||
/// <summary>Provides utilities for normalizing file paths.</summary>
|
||||
public static class PathUtilities
|
||||
{
|
||||
/*********
|
||||
|
@ -15,14 +15,14 @@ namespace StardewModdingAPI.Toolkit.Utilities
|
|||
/// <summary>The possible directory separator characters in a file path.</summary>
|
||||
private static readonly char[] PossiblePathSeparators = new[] { '/', '\\', Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar }.Distinct().ToArray();
|
||||
|
||||
/// <summary>The preferred directory separator chaeacter in an asset key.</summary>
|
||||
/// <summary>The preferred directory separator character in an asset key.</summary>
|
||||
private static readonly string PreferredPathSeparator = Path.DirectorySeparatorChar.ToString();
|
||||
|
||||
|
||||
/*********
|
||||
** Public methods
|
||||
*********/
|
||||
/// <summary>Get the segments from a path (e.g. <c>/usr/bin/boop</c> => <c>usr</c>, <c>bin</c>, and <c>boop</c>).</summary>
|
||||
/// <summary>Get the segments from a path (e.g. <c>/usr/bin/example</c> => <c>usr</c>, <c>bin</c>, and <c>example</c>).</summary>
|
||||
/// <param name="path">The path to split.</param>
|
||||
/// <param name="limit">The number of segments to match. Any additional segments will be merged into the last returned part.</param>
|
||||
public static string[] GetSegments(string path, int? limit = null)
|
||||
|
@ -32,16 +32,16 @@ namespace StardewModdingAPI.Toolkit.Utilities
|
|||
: path.Split(PathUtilities.PossiblePathSeparators, StringSplitOptions.RemoveEmptyEntries);
|
||||
}
|
||||
|
||||
/// <summary>Normalise path separators in a file path.</summary>
|
||||
/// <param name="path">The file path to normalise.</param>
|
||||
/// <summary>Normalize path separators in a file path.</summary>
|
||||
/// <param name="path">The file path to normalize.</param>
|
||||
[Pure]
|
||||
public static string NormalisePathSeparators(string path)
|
||||
public static string NormalizePathSeparators(string path)
|
||||
{
|
||||
string[] parts = PathUtilities.GetSegments(path);
|
||||
string normalised = string.Join(PathUtilities.PreferredPathSeparator, parts);
|
||||
string normalized = string.Join(PathUtilities.PreferredPathSeparator, parts);
|
||||
if (path.StartsWith(PathUtilities.PreferredPathSeparator))
|
||||
normalised = PathUtilities.PreferredPathSeparator + normalised; // keep root slash
|
||||
return normalised;
|
||||
normalized = PathUtilities.PreferredPathSeparator + normalized; // keep root slash
|
||||
return normalized;
|
||||
}
|
||||
|
||||
/// <summary>Get a directory or file path relative to a given source path.</summary>
|
||||
|
@ -57,7 +57,7 @@ namespace StardewModdingAPI.Toolkit.Utilities
|
|||
throw new InvalidOperationException($"Can't get path for '{targetPath}' relative to '{sourceDir}'.");
|
||||
|
||||
// get relative path
|
||||
string relative = PathUtilities.NormalisePathSeparators(Uri.UnescapeDataString(from.MakeRelativeUri(to).ToString()));
|
||||
string relative = PathUtilities.NormalizePathSeparators(Uri.UnescapeDataString(from.MakeRelativeUri(to).ToString()));
|
||||
if (relative == "")
|
||||
relative = "./";
|
||||
return relative;
|
||||
|
|
|
@ -11,7 +11,7 @@ using StardewModdingAPI.Web.Framework.Caching.Wiki;
|
|||
namespace StardewModdingAPI.Web
|
||||
{
|
||||
/// <summary>A hosted service which runs background data updates.</summary>
|
||||
/// <remarks>Task methods need to be static, since otherwise Hangfire will try to serialise the entire instance.</remarks>
|
||||
/// <remarks>Task methods need to be static, since otherwise Hangfire will try to serialize the entire instance.</remarks>
|
||||
internal class BackgroundService : IHostedService, IDisposable
|
||||
{
|
||||
/*********
|
||||
|
@ -94,8 +94,8 @@ namespace StardewModdingAPI.Web
|
|||
/*********
|
||||
** Private method
|
||||
*********/
|
||||
/// <summary>Initialise the background service if it's not already initialised.</summary>
|
||||
/// <exception cref="InvalidOperationException">The background service is already initialised.</exception>
|
||||
/// <summary>Initialize the background service if it's not already initialized.</summary>
|
||||
/// <exception cref="InvalidOperationException">The background service is already initialized.</exception>
|
||||
private void TryInit()
|
||||
{
|
||||
if (BackgroundService.JobServer != null)
|
||||
|
|
|
@ -79,7 +79,7 @@ namespace StardewModdingAPI.Web.Controllers
|
|||
[Route("json/{schemaName}/{id}")]
|
||||
public async Task<ViewResult> Index(string schemaName = null, string id = null)
|
||||
{
|
||||
schemaName = this.NormaliseSchemaName(schemaName);
|
||||
schemaName = this.NormalizeSchemaName(schemaName);
|
||||
|
||||
var result = new JsonValidatorModel(this.SectionUrl, id, schemaName, this.SchemaFormats);
|
||||
if (string.IsNullOrWhiteSpace(id))
|
||||
|
@ -143,8 +143,8 @@ namespace StardewModdingAPI.Web.Controllers
|
|||
if (request == null)
|
||||
return this.View("Index", new JsonValidatorModel(this.SectionUrl, null, null, this.SchemaFormats).SetUploadError("The request seems to be invalid."));
|
||||
|
||||
// normalise schema name
|
||||
string schemaName = this.NormaliseSchemaName(request.SchemaName);
|
||||
// normalize schema name
|
||||
string schemaName = this.NormalizeSchemaName(request.SchemaName);
|
||||
|
||||
// get raw log text
|
||||
string input = request.Content;
|
||||
|
@ -178,9 +178,9 @@ namespace StardewModdingAPI.Web.Controllers
|
|||
return response;
|
||||
}
|
||||
|
||||
/// <summary>Get a normalised schema name, or the <see cref="DefaultSchemaID"/> if blank.</summary>
|
||||
/// <param name="schemaName">The raw schema name to normalise.</param>
|
||||
private string NormaliseSchemaName(string schemaName)
|
||||
/// <summary>Get a normalized schema name, or the <see cref="DefaultSchemaID"/> if blank.</summary>
|
||||
/// <param name="schemaName">The raw schema name to normalize.</param>
|
||||
private string NormalizeSchemaName(string schemaName)
|
||||
{
|
||||
schemaName = schemaName?.Trim().ToLower();
|
||||
return !string.IsNullOrWhiteSpace(schemaName)
|
||||
|
@ -192,7 +192,7 @@ namespace StardewModdingAPI.Web.Controllers
|
|||
/// <param name="id">The schema ID.</param>
|
||||
private FileInfo FindSchemaFile(string id)
|
||||
{
|
||||
// normalise ID
|
||||
// normalize ID
|
||||
id = id?.Trim().ToLower();
|
||||
if (string.IsNullOrWhiteSpace(id))
|
||||
return null;
|
||||
|
|
|
@ -120,7 +120,7 @@ namespace StardewModdingAPI.Web.Controllers
|
|||
/// <returns>Returns the mod data if found, else <c>null</c>.</returns>
|
||||
private async Task<ModEntryModel> GetModData(ModSearchEntryModel search, WikiModEntry[] wikiData, bool includeExtendedMetadata)
|
||||
{
|
||||
// crossreference data
|
||||
// cross-reference data
|
||||
ModDataRecord record = this.ModDatabase.Get(search.ID);
|
||||
WikiModEntry wikiEntry = wikiData.FirstOrDefault(entry => entry.ID.Contains(search.ID.Trim(), StringComparer.InvariantCultureIgnoreCase));
|
||||
UpdateKey[] updateKeys = this.GetUpdateKeys(search.UpdateKeys, record, wikiEntry).ToArray();
|
||||
|
|
|
@ -36,7 +36,7 @@ namespace StardewModdingAPI.Web.Framework
|
|||
}
|
||||
|
||||
/// <summary>Called early in the filter pipeline to confirm request is authorized.</summary>
|
||||
/// <param name="context">The authorisation filter context.</param>
|
||||
/// <param name="context">The authorization filter context.</param>
|
||||
public void OnAuthorization(AuthorizationFilterContext context)
|
||||
{
|
||||
IFeatureCollection features = context.HttpContext.Features;
|
||||
|
|
|
@ -40,7 +40,7 @@ namespace StardewModdingAPI.Web.Framework.Caching.Mods
|
|||
public bool TryGetMod(ModRepositoryKey site, string id, out CachedMod mod, bool markRequested = true)
|
||||
{
|
||||
// get mod
|
||||
id = this.NormaliseId(id);
|
||||
id = this.NormalizeId(id);
|
||||
mod = this.Mods.Find(entry => entry.ID == id && entry.Site == site).FirstOrDefault();
|
||||
if (mod == null)
|
||||
return false;
|
||||
|
@ -62,7 +62,7 @@ namespace StardewModdingAPI.Web.Framework.Caching.Mods
|
|||
/// <param name="cachedMod">The stored mod record.</param>
|
||||
public void SaveMod(ModRepositoryKey site, string id, ModInfoModel mod, out CachedMod cachedMod)
|
||||
{
|
||||
id = this.NormaliseId(id);
|
||||
id = this.NormalizeId(id);
|
||||
|
||||
cachedMod = this.SaveMod(new CachedMod(site, id, mod));
|
||||
}
|
||||
|
@ -83,7 +83,7 @@ namespace StardewModdingAPI.Web.Framework.Caching.Mods
|
|||
/// <param name="mod">The mod data.</param>
|
||||
public CachedMod SaveMod(CachedMod mod)
|
||||
{
|
||||
string id = this.NormaliseId(mod.ID);
|
||||
string id = this.NormalizeId(mod.ID);
|
||||
|
||||
this.Mods.ReplaceOne(
|
||||
entry => entry.ID == id && entry.Site == mod.Site,
|
||||
|
@ -94,9 +94,9 @@ namespace StardewModdingAPI.Web.Framework.Caching.Mods
|
|||
return mod;
|
||||
}
|
||||
|
||||
/// <summary>Normalise a mod ID for case-insensitive search.</summary>
|
||||
/// <summary>Normalize a mod ID for case-insensitive search.</summary>
|
||||
/// <param name="id">The mod ID.</param>
|
||||
public string NormaliseId(string id)
|
||||
public string NormalizeId(string id)
|
||||
{
|
||||
return id.Trim().ToLower();
|
||||
}
|
||||
|
|
|
@ -5,7 +5,7 @@ using MongoDB.Bson.Serialization.Serializers;
|
|||
|
||||
namespace StardewModdingAPI.Web.Framework.Caching
|
||||
{
|
||||
/// <summary>Serialises <see cref="DateTimeOffset"/> to a UTC date field instead of the default array.</summary>
|
||||
/// <summary>Serializes <see cref="DateTimeOffset"/> to a UTC date field instead of the default array.</summary>
|
||||
public class UtcDateTimeOffsetSerializer : StructSerializerBase<DateTimeOffset>
|
||||
{
|
||||
/*********
|
||||
|
|
|
@ -2,7 +2,7 @@ using Hangfire.Dashboard;
|
|||
|
||||
namespace StardewModdingAPI.Web.Framework
|
||||
{
|
||||
/// <summary>Authorises requests to access the Hangfire job dashboard.</summary>
|
||||
/// <summary>Authorizes requests to access the Hangfire job dashboard.</summary>
|
||||
internal class JobDashboardAuthorizationFilter : IDashboardAuthorizationFilter
|
||||
{
|
||||
/*********
|
||||
|
@ -15,7 +15,7 @@ namespace StardewModdingAPI.Web.Framework
|
|||
/*********
|
||||
** Public methods
|
||||
*********/
|
||||
/// <summary>Authorise a request.</summary>
|
||||
/// <summary>Authorize a request.</summary>
|
||||
/// <param name="context">The dashboard context.</param>
|
||||
public bool Authorize(DashboardContext context)
|
||||
{
|
||||
|
|
|
@ -221,7 +221,7 @@ namespace StardewModdingAPI.Web.Framework.LogParsing
|
|||
}
|
||||
}
|
||||
|
||||
// finalise log
|
||||
// finalize log
|
||||
gameMod.Version = log.GameVersion;
|
||||
log.Mods = new[] { gameMod, smapiMod }.Concat(mods.Values.OrderBy(p => p.Name)).ToArray();
|
||||
return log;
|
||||
|
|
|
@ -34,9 +34,9 @@ namespace StardewModdingAPI.Web.Framework.ModRepositories
|
|||
this.VendorKey = vendorKey;
|
||||
}
|
||||
|
||||
/// <summary>Normalise a version string.</summary>
|
||||
/// <param name="version">The version to normalise.</param>
|
||||
protected string NormaliseVersion(string version)
|
||||
/// <summary>Normalize a version string.</summary>
|
||||
/// <param name="version">The version to normalize.</param>
|
||||
protected string NormalizeVersion(string version)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(version))
|
||||
return null;
|
||||
|
|
|
@ -39,7 +39,7 @@ namespace StardewModdingAPI.Web.Framework.ModRepositories
|
|||
{
|
||||
var mod = await this.Client.GetModAsync(realID);
|
||||
return mod != null
|
||||
? new ModInfoModel(name: mod.Name, version: this.NormaliseVersion(mod.Version), url: mod.Url)
|
||||
? new ModInfoModel(name: mod.Name, version: this.NormalizeVersion(mod.Version), url: mod.Url)
|
||||
: new ModInfoModel().SetError(RemoteModStatus.DoesNotExist, "Found no Chucklefish mod with this ID.");
|
||||
}
|
||||
catch (Exception ex)
|
||||
|
|
|
@ -65,7 +65,7 @@ namespace StardewModdingAPI.Web.Framework.ModRepositories
|
|||
}
|
||||
|
||||
// return data
|
||||
return result.SetVersions(version: this.NormaliseVersion(latest.Tag), previewVersion: this.NormaliseVersion(preview?.Tag));
|
||||
return result.SetVersions(version: this.NormalizeVersion(latest.Tag), previewVersion: this.NormalizeVersion(preview?.Tag));
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
|
|
@ -48,7 +48,7 @@ namespace StardewModdingAPI.Web.Framework.ModRepositories
|
|||
return new ModInfoModel().SetError(remoteStatus, mod.Error);
|
||||
}
|
||||
|
||||
return new ModInfoModel(name: mod.Name, version: this.NormaliseVersion(mod.Version), previewVersion: mod.LatestFileVersion?.ToString(), url: mod.Url);
|
||||
return new ModInfoModel(name: mod.Name, version: this.NormalizeVersion(mod.Version), previewVersion: mod.LatestFileVersion?.ToString(), url: mod.Url);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
|
|
@ -10,7 +10,7 @@ using Microsoft.Extensions.DependencyInjection;
|
|||
using MongoDB.Bson.Serialization;
|
||||
using MongoDB.Driver;
|
||||
using Newtonsoft.Json;
|
||||
using StardewModdingAPI.Toolkit.Serialisation;
|
||||
using StardewModdingAPI.Toolkit.Serialization;
|
||||
using StardewModdingAPI.Web.Framework;
|
||||
using StardewModdingAPI.Web.Framework.Caching;
|
||||
using StardewModdingAPI.Web.Framework.Caching.Mods;
|
||||
|
|
|
@ -81,7 +81,7 @@ namespace StardewModdingAPI.Web.ViewModels
|
|||
.ToDictionary(group => group.Key, group => group.ToArray());
|
||||
}
|
||||
|
||||
/// <summary>Get a sanitised mod name that's safe to use in anchors, attributes, and URLs.</summary>
|
||||
/// <summary>Get a sanitized mod name that's safe to use in anchors, attributes, and URLs.</summary>
|
||||
/// <param name="modName">The mod name.</param>
|
||||
public string GetSlug(string modName)
|
||||
{
|
||||
|
|
|
@ -120,7 +120,7 @@ smapi.jsonValidator = function (sectionUrl, pasteID) {
|
|||
};
|
||||
|
||||
/**
|
||||
* Initialise the JSON validator page.
|
||||
* Initialize the JSON validator page.
|
||||
*/
|
||||
var init = function () {
|
||||
// set initial code formatting
|
||||
|
|
|
@ -107,7 +107,7 @@
|
|||
},
|
||||
"Target": {
|
||||
"title": "Target asset",
|
||||
"description": "The game asset you want to patch (or multiple comma-delimited assets). This is the file path inside your game's Content folder, without the file extension or language (like Animals/Dinosaur to edit Content/Animals/Dinosaur.xnb). This field supports tokens and capitalisation doesn't matter. Your changes are applied in all languages unless you specify a language condition.",
|
||||
"description": "The game asset you want to patch (or multiple comma-delimited assets). This is the file path inside your game's Content folder, without the file extension or language (like Animals/Dinosaur to edit Content/Animals/Dinosaur.xnb). This field supports tokens and capitalization doesn't matter. Your changes are applied in all languages unless you specify a language condition.",
|
||||
"type": "string",
|
||||
"not": {
|
||||
"pattern": "^ *[cC][oO][nN][tT][eE][nN][tT]/|\\.[xX][nN][bB] *$|\\.[a-zA-Z][a-zA-Z]-[a-zA-Z][a-zA-Z](?:.xnb)? *$"
|
||||
|
@ -140,7 +140,7 @@
|
|||
},
|
||||
"FromFile": {
|
||||
"title": "Source file",
|
||||
"description": "The relative file path in your content pack folder to load instead (like 'assets/dinosaur.png'). This can be a .json (data), .png (image), .tbin (map), or .xnb file. This field supports tokens and capitalisation doesn't matter.",
|
||||
"description": "The relative file path in your content pack folder to load instead (like 'assets/dinosaur.png'). This can be a .json (data), .png (image), .tbin (map), or .xnb file. This field supports tokens and capitalization doesn't matter.",
|
||||
"type": "string",
|
||||
"allOf": [
|
||||
{
|
||||
|
@ -310,7 +310,7 @@
|
|||
"then": {
|
||||
"properties": {
|
||||
"FromFile": {
|
||||
"description": "The relative path to the map in your content pack folder from which to copy (like assets/town.tbin). This can be a .tbin or .xnb file. This field supports tokens and capitalisation doesn't matter.\nContent Patcher will handle tilesheets referenced by the FromFile map for you if it's a .tbin file:\n - If a tilesheet isn't referenced by the target map, Content Patcher will add it for you (with a z_ ID prefix to avoid conflicts with hardcoded game logic). If the source map has a custom version of a tilesheet that's already referenced, it'll be added as a separate tilesheet only used by your tiles.\n - If you include the tilesheet file in your mod folder, Content Patcher will use that one automatically; otherwise it will be loaded from the game's Content/Maps folder."
|
||||
"description": "The relative path to the map in your content pack folder from which to copy (like assets/town.tbin). This can be a .tbin or .xnb file. This field supports tokens and capitalization doesn't matter.\nContent Patcher will handle tilesheets referenced by the FromFile map for you if it's a .tbin file:\n - If a tilesheet isn't referenced by the target map, Content Patcher will add it for you (with a z_ ID prefix to avoid conflicts with hardcoded game logic). If the source map has a custom version of a tilesheet that's already referenced, it'll be added as a separate tilesheet only used by your tiles.\n - If you include the tilesheet file in your mod folder, Content Patcher will use that one automatically; otherwise it will be loaded from the game's Content/Maps folder."
|
||||
},
|
||||
"FromArea": {
|
||||
"description": "The part of the source map to copy. Defaults to the whole source map."
|
||||
|
|
|
@ -23,4 +23,46 @@
|
|||
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ESettingsUpgrade_002ECSharpPlaceAttributeOnSameLineMigration/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ESettingsUpgrade_002EMigrateBlankLinesAroundFieldToBlankLinesAroundProperty/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ESettingsUpgrade_002EMigrateThisQualifierSettings/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=analytics/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=Chucklefish/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=clickable/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=craftable/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=craftables/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=crossplatform/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=cutscene/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=decoratable/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=devs/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=fallbacks/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=filenames/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=gamepad/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=Hangfire/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=initializers/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=Junimo/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=modder/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=modders/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=Mongo/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=multiplayer/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=Netcode/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=overworld/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=Pastebin/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=Pathoschild/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=premultiplied/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=premultiply/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=prerelease/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=pufferchick/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=rewriter/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=rewriters/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=SMAPI/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=spawnable/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=spritesheet/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=stackable/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=Stardew/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=subdomain/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=synchronised/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=textbox/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=thumbstick/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=tilesheet/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=tilesheets/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=unloadable/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/UserDictionary/Words/=virally/@EntryIndexedValue">True</s:Boolean>
|
||||
</wpf:ResourceDictionary>
|
|
@ -14,10 +14,10 @@ namespace StardewModdingAPI
|
|||
/****
|
||||
** Public
|
||||
****/
|
||||
/// <summary>Whether the game has performed core initialisation. This becomes true right before the first update tick..</summary>
|
||||
/// <summary>Whether the game has performed core initialization. This becomes true right before the first update tick.</summary>
|
||||
public static bool IsGameLaunched { get; internal set; }
|
||||
|
||||
/// <summary>Whether the player has loaded a save and the world has finished initialising.</summary>
|
||||
/// <summary>Whether the player has loaded a save and the world has finished initializing.</summary>
|
||||
public static bool IsWorldReady { get; internal set; }
|
||||
|
||||
/// <summary>Whether <see cref="IsWorldReady"/> is true and the player is free to act in the world (no menu is displayed, no cutscene is in progress, etc).</summary>
|
||||
|
|
|
@ -6,10 +6,10 @@ namespace StardewModdingAPI.Enums
|
|||
/// <summary>A save is not loaded or loading.</summary>
|
||||
None,
|
||||
|
||||
/// <summary>The game is creating a new save slot, and has initialised the basic save info.</summary>
|
||||
/// <summary>The game is creating a new save slot, and has initialized the basic save info.</summary>
|
||||
CreatedBasicInfo,
|
||||
|
||||
/// <summary>The game is creating a new save slot, and has initialised the in-game locations.</summary>
|
||||
/// <summary>The game is creating a new save slot, and has initialized the in-game locations.</summary>
|
||||
CreatedLocations,
|
||||
|
||||
/// <summary>The game is creating a new save slot, and has created the physical save files.</summary>
|
||||
|
@ -18,7 +18,7 @@ namespace StardewModdingAPI.Enums
|
|||
/// <summary>The game is loading a save slot, and has read the raw save data into <see cref="StardewValley.SaveGame.loaded"/>. Not applicable when connecting to a multiplayer host. This is equivalent to <see cref="StardewValley.SaveGame.getLoadEnumerator"/> value 20.</summary>
|
||||
SaveParsed,
|
||||
|
||||
/// <summary>The game is loading a save slot, and has applied the basic save info (including player data). Not applicable when connecting to a multiplayer host. Note that some basic info (like daily luck) is not initialised at this point. This is equivalent to <see cref="StardewValley.SaveGame.getLoadEnumerator"/> value 36.</summary>
|
||||
/// <summary>The game is loading a save slot, and has applied the basic save info (including player data). Not applicable when connecting to a multiplayer host. Note that some basic info (like daily luck) is not initialized at this point. This is equivalent to <see cref="StardewValley.SaveGame.getLoadEnumerator"/> value 36.</summary>
|
||||
SaveLoadedBasicInfo,
|
||||
|
||||
/// <summary>The game is loading a save slot, and has applied the in-game location data. Not applicable when connecting to a multiplayer host. This is equivalent to <see cref="StardewValley.SaveGame.getLoadEnumerator"/> value 50.</summary>
|
||||
|
@ -27,10 +27,10 @@ namespace StardewModdingAPI.Enums
|
|||
/// <summary>The final metadata has been loaded from the save file. This happens before the game applies problem fixes, checks for achievements, starts music, etc. Not applicable when connecting to a multiplayer host.</summary>
|
||||
Preloaded,
|
||||
|
||||
/// <summary>The save is fully loaded, but the world may not be fully initialised yet.</summary>
|
||||
/// <summary>The save is fully loaded, but the world may not be fully initialized yet.</summary>
|
||||
Loaded,
|
||||
|
||||
/// <summary>The save is fully loaded, the world has been initialised, and <see cref="Context.IsWorldReady"/> is now true.</summary>
|
||||
/// <summary>The save is fully loaded, the world has been initialized, and <see cref="Context.IsWorldReady"/> is now true.</summary>
|
||||
Ready
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,7 +5,7 @@ namespace StardewModdingAPI.Events
|
|||
/// <summary>Events linked to the game's update loop. The update loop runs roughly ≈60 times/second to run game logic like state changes, action handling, etc. These can be useful, but you should consider more semantic events like <see cref="IInputEvents"/> if possible.</summary>
|
||||
public interface IGameLoopEvents
|
||||
{
|
||||
/// <summary>Raised after the game is launched, right before the first update tick. This happens once per game session (unrelated to loading saves). All mods are loaded and initialised at this point, so this is a good time to set up mod integrations.</summary>
|
||||
/// <summary>Raised after the game is launched, right before the first update tick. This happens once per game session (unrelated to loading saves). All mods are loaded and initialized at this point, so this is a good time to set up mod integrations.</summary>
|
||||
event EventHandler<GameLaunchedEventArgs> GameLaunched;
|
||||
|
||||
/// <summary>Raised before the game state is updated (≈60 times per second).</summary>
|
||||
|
@ -32,7 +32,7 @@ namespace StardewModdingAPI.Events
|
|||
/// <summary>Raised after the game finishes writing data to the save file (except the initial save creation).</summary>
|
||||
event EventHandler<SavedEventArgs> Saved;
|
||||
|
||||
/// <summary>Raised after the player loads a save slot and the world is initialised.</summary>
|
||||
/// <summary>Raised after the player loads a save slot and the world is initialized.</summary>
|
||||
event EventHandler<SaveLoadedEventArgs> SaveLoaded;
|
||||
|
||||
/// <summary>Raised after the game begins a new day (including when the player loads a save).</summary>
|
||||
|
|
|
@ -21,7 +21,7 @@ namespace StardewModdingAPI.Events
|
|||
/// <summary>Events raised when something changes in the world.</summary>
|
||||
IWorldEvents World { get; }
|
||||
|
||||
/// <summary>Events serving specialised edge cases that shouldn't be used by most mods.</summary>
|
||||
ISpecialisedEvents Specialised { get; }
|
||||
/// <summary>Events serving specialized edge cases that shouldn't be used by most mods.</summary>
|
||||
ISpecializedEvents Specialized { get; }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,8 +2,8 @@ using System;
|
|||
|
||||
namespace StardewModdingAPI.Events
|
||||
{
|
||||
/// <summary>Events serving specialised edge cases that shouldn't be used by most mods.</summary>
|
||||
public interface ISpecialisedEvents
|
||||
/// <summary>Events serving specialized edge cases that shouldn't be used by most mods.</summary>
|
||||
public interface ISpecializedEvents
|
||||
{
|
||||
/// <summary>Raised when the low-level stage in the game's loading process has changed. This is an advanced event for mods which need to run code at specific points in the loading process. The available stages or when they happen might change without warning in future versions (e.g. due to changes in the game's load process), so mods using this event are more likely to break or have bugs. Most mods should use <see cref="IGameLoopEvents"/> instead.</summary>
|
||||
event EventHandler<LoadStageChangedEventArgs> LoadStageChanged;
|
||||
|
|
|
@ -3,7 +3,7 @@ using StardewModdingAPI.Enums;
|
|||
|
||||
namespace StardewModdingAPI.Events
|
||||
{
|
||||
/// <summary>Event arguments for an <see cref="ISpecialisedEvents.LoadStageChanged"/> event.</summary>
|
||||
/// <summary>Event arguments for an <see cref="ISpecializedEvents.LoadStageChanged"/> event.</summary>
|
||||
public class LoadStageChangedEventArgs : EventArgs
|
||||
{
|
||||
/*********
|
||||
|
|
|
@ -3,7 +3,7 @@ using StardewModdingAPI.Framework;
|
|||
|
||||
namespace StardewModdingAPI.Events
|
||||
{
|
||||
/// <summary>Event arguments for an <see cref="ISpecialisedEvents.UnvalidatedUpdateTicked"/> event.</summary>
|
||||
/// <summary>Event arguments for an <see cref="ISpecializedEvents.UnvalidatedUpdateTicked"/> event.</summary>
|
||||
public class UnvalidatedUpdateTickedEventArgs : EventArgs
|
||||
{
|
||||
/*********
|
||||
|
|
|
@ -3,7 +3,7 @@ using StardewModdingAPI.Framework;
|
|||
|
||||
namespace StardewModdingAPI.Events
|
||||
{
|
||||
/// <summary>Event arguments for an <see cref="ISpecialisedEvents.UnvalidatedUpdateTicking"/> event.</summary>
|
||||
/// <summary>Event arguments for an <see cref="ISpecializedEvents.UnvalidatedUpdateTicking"/> event.</summary>
|
||||
public class UnvalidatedUpdateTickingEventArgs : EventArgs
|
||||
{
|
||||
/*********
|
||||
|
|
|
@ -29,7 +29,7 @@ namespace StardewModdingAPI.Framework
|
|||
/// <exception cref="ArgumentException">There's already a command with that name.</exception>
|
||||
public void Add(IModMetadata mod, string name, string documentation, Action<string, string[]> callback, bool allowNullCallback = false)
|
||||
{
|
||||
name = this.GetNormalisedName(name);
|
||||
name = this.GetNormalizedName(name);
|
||||
|
||||
// validate format
|
||||
if (string.IsNullOrWhiteSpace(name))
|
||||
|
@ -52,7 +52,7 @@ namespace StardewModdingAPI.Framework
|
|||
/// <returns>Returns the matching command, or <c>null</c> if not found.</returns>
|
||||
public Command Get(string name)
|
||||
{
|
||||
name = this.GetNormalisedName(name);
|
||||
name = this.GetNormalizedName(name);
|
||||
this.Commands.TryGetValue(name, out Command command);
|
||||
return command;
|
||||
}
|
||||
|
@ -84,7 +84,7 @@ namespace StardewModdingAPI.Framework
|
|||
|
||||
// parse input
|
||||
args = this.ParseArgs(input);
|
||||
name = this.GetNormalisedName(args[0]);
|
||||
name = this.GetNormalizedName(args[0]);
|
||||
args = args.Skip(1).ToArray();
|
||||
|
||||
// get command
|
||||
|
@ -97,8 +97,8 @@ namespace StardewModdingAPI.Framework
|
|||
/// <returns>Returns whether a matching command was triggered.</returns>
|
||||
public bool Trigger(string name, string[] arguments)
|
||||
{
|
||||
// get normalised name
|
||||
name = this.GetNormalisedName(name);
|
||||
// get normalized name
|
||||
name = this.GetNormalizedName(name);
|
||||
if (name == null)
|
||||
return false;
|
||||
|
||||
|
@ -140,9 +140,9 @@ namespace StardewModdingAPI.Framework
|
|||
return args.Where(item => !string.IsNullOrWhiteSpace(item)).ToArray();
|
||||
}
|
||||
|
||||
/// <summary>Get a normalised command name.</summary>
|
||||
/// <summary>Get a normalized command name.</summary>
|
||||
/// <param name="name">The command name.</param>
|
||||
private string GetNormalisedName(string name)
|
||||
private string GetNormalizedName(string name)
|
||||
{
|
||||
name = name?.Trim().ToLower();
|
||||
return !string.IsNullOrWhiteSpace(name)
|
||||
|
|
|
@ -24,13 +24,13 @@ namespace StardewModdingAPI.Framework.Content
|
|||
** Public methods
|
||||
*********/
|
||||
/// <summary>Construct an instance.</summary>
|
||||
/// <param name="locale">The content's locale code, if the content is localised.</param>
|
||||
/// <param name="assetName">The normalised asset name being read.</param>
|
||||
/// <param name="locale">The content's locale code, if the content is localized.</param>
|
||||
/// <param name="assetName">The normalized asset name being read.</param>
|
||||
/// <param name="data">The content data being read.</param>
|
||||
/// <param name="getNormalisedPath">Normalises an asset key to match the cache key.</param>
|
||||
/// <param name="getNormalizedPath">Normalizes an asset key to match the cache key.</param>
|
||||
/// <param name="onDataReplaced">A callback to invoke when the data is replaced (if any).</param>
|
||||
public AssetData(string locale, string assetName, TValue data, Func<string, string> getNormalisedPath, Action<TValue> onDataReplaced)
|
||||
: base(locale, assetName, data.GetType(), getNormalisedPath)
|
||||
public AssetData(string locale, string assetName, TValue data, Func<string, string> getNormalizedPath, Action<TValue> onDataReplaced)
|
||||
: base(locale, assetName, data.GetType(), getNormalizedPath)
|
||||
{
|
||||
this.Data = data;
|
||||
this.OnDataReplaced = onDataReplaced;
|
||||
|
|
|
@ -10,12 +10,12 @@ namespace StardewModdingAPI.Framework.Content
|
|||
** Public methods
|
||||
*********/
|
||||
/// <summary>Construct an instance.</summary>
|
||||
/// <param name="locale">The content's locale code, if the content is localised.</param>
|
||||
/// <param name="assetName">The normalised asset name being read.</param>
|
||||
/// <param name="locale">The content's locale code, if the content is localized.</param>
|
||||
/// <param name="assetName">The normalized asset name being read.</param>
|
||||
/// <param name="data">The content data being read.</param>
|
||||
/// <param name="getNormalisedPath">Normalises an asset key to match the cache key.</param>
|
||||
/// <param name="getNormalizedPath">Normalizes an asset key to match the cache key.</param>
|
||||
/// <param name="onDataReplaced">A callback to invoke when the data is replaced (if any).</param>
|
||||
public AssetDataForDictionary(string locale, string assetName, IDictionary<TKey, TValue> data, Func<string, string> getNormalisedPath, Action<IDictionary<TKey, TValue>> onDataReplaced)
|
||||
: base(locale, assetName, data, getNormalisedPath, onDataReplaced) { }
|
||||
public AssetDataForDictionary(string locale, string assetName, IDictionary<TKey, TValue> data, Func<string, string> getNormalizedPath, Action<IDictionary<TKey, TValue>> onDataReplaced)
|
||||
: base(locale, assetName, data, getNormalizedPath, onDataReplaced) { }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,13 +19,13 @@ namespace StardewModdingAPI.Framework.Content
|
|||
** Public methods
|
||||
*********/
|
||||
/// <summary>Construct an instance.</summary>
|
||||
/// <param name="locale">The content's locale code, if the content is localised.</param>
|
||||
/// <param name="assetName">The normalised asset name being read.</param>
|
||||
/// <param name="locale">The content's locale code, if the content is localized.</param>
|
||||
/// <param name="assetName">The normalized asset name being read.</param>
|
||||
/// <param name="data">The content data being read.</param>
|
||||
/// <param name="getNormalisedPath">Normalises an asset key to match the cache key.</param>
|
||||
/// <param name="getNormalizedPath">Normalizes an asset key to match the cache key.</param>
|
||||
/// <param name="onDataReplaced">A callback to invoke when the data is replaced (if any).</param>
|
||||
public AssetDataForImage(string locale, string assetName, Texture2D data, Func<string, string> getNormalisedPath, Action<Texture2D> onDataReplaced)
|
||||
: base(locale, assetName, data, getNormalisedPath, onDataReplaced) { }
|
||||
public AssetDataForImage(string locale, string assetName, Texture2D data, Func<string, string> getNormalizedPath, Action<Texture2D> onDataReplaced)
|
||||
: base(locale, assetName, data, getNormalizedPath, onDataReplaced) { }
|
||||
|
||||
/// <summary>Overwrite part of the image.</summary>
|
||||
/// <param name="source">The image to patch into the content.</param>
|
||||
|
|
|
@ -11,19 +11,19 @@ namespace StardewModdingAPI.Framework.Content
|
|||
** Public methods
|
||||
*********/
|
||||
/// <summary>Construct an instance.</summary>
|
||||
/// <param name="locale">The content's locale code, if the content is localised.</param>
|
||||
/// <param name="assetName">The normalised asset name being read.</param>
|
||||
/// <param name="locale">The content's locale code, if the content is localized.</param>
|
||||
/// <param name="assetName">The normalized asset name being read.</param>
|
||||
/// <param name="data">The content data being read.</param>
|
||||
/// <param name="getNormalisedPath">Normalises an asset key to match the cache key.</param>
|
||||
public AssetDataForObject(string locale, string assetName, object data, Func<string, string> getNormalisedPath)
|
||||
: base(locale, assetName, data, getNormalisedPath, onDataReplaced: null) { }
|
||||
/// <param name="getNormalizedPath">Normalizes an asset key to match the cache key.</param>
|
||||
public AssetDataForObject(string locale, string assetName, object data, Func<string, string> getNormalizedPath)
|
||||
: base(locale, assetName, data, getNormalizedPath, onDataReplaced: null) { }
|
||||
|
||||
/// <summary>Construct an instance.</summary>
|
||||
/// <param name="info">The asset metadata.</param>
|
||||
/// <param name="data">The content data being read.</param>
|
||||
/// <param name="getNormalisedPath">Normalises an asset key to match the cache key.</param>
|
||||
public AssetDataForObject(IAssetInfo info, object data, Func<string, string> getNormalisedPath)
|
||||
: this(info.Locale, info.AssetName, data, getNormalisedPath) { }
|
||||
/// <param name="getNormalizedPath">Normalizes an asset key to match the cache key.</param>
|
||||
public AssetDataForObject(IAssetInfo info, object data, Func<string, string> getNormalizedPath)
|
||||
: this(info.Locale, info.AssetName, data, getNormalizedPath) { }
|
||||
|
||||
/// <summary>Get a helper to manipulate the data as a dictionary.</summary>
|
||||
/// <typeparam name="TKey">The expected dictionary key.</typeparam>
|
||||
|
@ -31,14 +31,14 @@ namespace StardewModdingAPI.Framework.Content
|
|||
/// <exception cref="InvalidOperationException">The content being read isn't a dictionary.</exception>
|
||||
public IAssetDataForDictionary<TKey, TValue> AsDictionary<TKey, TValue>()
|
||||
{
|
||||
return new AssetDataForDictionary<TKey, TValue>(this.Locale, this.AssetName, this.GetData<IDictionary<TKey, TValue>>(), this.GetNormalisedPath, this.ReplaceWith);
|
||||
return new AssetDataForDictionary<TKey, TValue>(this.Locale, this.AssetName, this.GetData<IDictionary<TKey, TValue>>(), this.GetNormalizedPath, this.ReplaceWith);
|
||||
}
|
||||
|
||||
/// <summary>Get a helper to manipulate the data as an image.</summary>
|
||||
/// <exception cref="InvalidOperationException">The content being read isn't an image.</exception>
|
||||
public IAssetDataForImage AsImage()
|
||||
{
|
||||
return new AssetDataForImage(this.Locale, this.AssetName, this.GetData<Texture2D>(), this.GetNormalisedPath, this.ReplaceWith);
|
||||
return new AssetDataForImage(this.Locale, this.AssetName, this.GetData<Texture2D>(), this.GetNormalizedPath, this.ReplaceWith);
|
||||
}
|
||||
|
||||
/// <summary>Get the data as a given type.</summary>
|
||||
|
|
|
@ -9,17 +9,17 @@ namespace StardewModdingAPI.Framework.Content
|
|||
/*********
|
||||
** Fields
|
||||
*********/
|
||||
/// <summary>Normalises an asset key to match the cache key.</summary>
|
||||
protected readonly Func<string, string> GetNormalisedPath;
|
||||
/// <summary>Normalizes an asset key to match the cache key.</summary>
|
||||
protected readonly Func<string, string> GetNormalizedPath;
|
||||
|
||||
|
||||
/*********
|
||||
** Accessors
|
||||
*********/
|
||||
/// <summary>The content's locale code, if the content is localised.</summary>
|
||||
/// <summary>The content's locale code, if the content is localized.</summary>
|
||||
public string Locale { get; }
|
||||
|
||||
/// <summary>The normalised asset name being read. The format may change between platforms; see <see cref="AssetNameEquals"/> to compare with a known path.</summary>
|
||||
/// <summary>The normalized asset name being read. The format may change between platforms; see <see cref="AssetNameEquals"/> to compare with a known path.</summary>
|
||||
public string AssetName { get; }
|
||||
|
||||
/// <summary>The content data type.</summary>
|
||||
|
@ -30,23 +30,23 @@ namespace StardewModdingAPI.Framework.Content
|
|||
** Public methods
|
||||
*********/
|
||||
/// <summary>Construct an instance.</summary>
|
||||
/// <param name="locale">The content's locale code, if the content is localised.</param>
|
||||
/// <param name="assetName">The normalised asset name being read.</param>
|
||||
/// <param name="locale">The content's locale code, if the content is localized.</param>
|
||||
/// <param name="assetName">The normalized asset name being read.</param>
|
||||
/// <param name="type">The content type being read.</param>
|
||||
/// <param name="getNormalisedPath">Normalises an asset key to match the cache key.</param>
|
||||
public AssetInfo(string locale, string assetName, Type type, Func<string, string> getNormalisedPath)
|
||||
/// <param name="getNormalizedPath">Normalizes an asset key to match the cache key.</param>
|
||||
public AssetInfo(string locale, string assetName, Type type, Func<string, string> getNormalizedPath)
|
||||
{
|
||||
this.Locale = locale;
|
||||
this.AssetName = assetName;
|
||||
this.DataType = type;
|
||||
this.GetNormalisedPath = getNormalisedPath;
|
||||
this.GetNormalizedPath = getNormalizedPath;
|
||||
}
|
||||
|
||||
/// <summary>Get whether the asset name being loaded matches a given name after normalisation.</summary>
|
||||
/// <summary>Get whether the asset name being loaded matches a given name after normalization.</summary>
|
||||
/// <param name="path">The expected asset path, relative to the game's content folder and without the .xnb extension or locale suffix (like 'Data\ObjectInformation').</param>
|
||||
public bool AssetNameEquals(string path)
|
||||
{
|
||||
path = this.GetNormalisedPath(path);
|
||||
path = this.GetNormalizedPath(path);
|
||||
return this.AssetName.Equals(path, StringComparison.InvariantCultureIgnoreCase);
|
||||
}
|
||||
|
||||
|
|
|
@ -10,7 +10,7 @@ using StardewValley;
|
|||
|
||||
namespace StardewModdingAPI.Framework.Content
|
||||
{
|
||||
/// <summary>A low-level wrapper around the content cache which handles reading, writing, and invalidating entries in the cache. This doesn't handle any higher-level logic like localisation, loading content, etc. It assumes all keys passed in are already normalised.</summary>
|
||||
/// <summary>A low-level wrapper around the content cache which handles reading, writing, and invalidating entries in the cache. This doesn't handle any higher-level logic like localization, loading content, etc. It assumes all keys passed in are already normalized.</summary>
|
||||
internal class ContentCache
|
||||
{
|
||||
/*********
|
||||
|
@ -19,8 +19,8 @@ namespace StardewModdingAPI.Framework.Content
|
|||
/// <summary>The underlying asset cache.</summary>
|
||||
private readonly IDictionary<string, object> Cache;
|
||||
|
||||
/// <summary>Applies platform-specific asset key normalisation so it's consistent with the underlying cache.</summary>
|
||||
private readonly Func<string, string> NormaliseAssetNameForPlatform;
|
||||
/// <summary>Applies platform-specific asset key normalization so it's consistent with the underlying cache.</summary>
|
||||
private readonly Func<string, string> NormalizeAssetNameForPlatform;
|
||||
|
||||
|
||||
/*********
|
||||
|
@ -52,14 +52,14 @@ namespace StardewModdingAPI.Framework.Content
|
|||
// init
|
||||
this.Cache = reflection.GetField<Dictionary<string, object>>(contentManager, "loadedAssets").GetValue();
|
||||
|
||||
// get key normalisation logic
|
||||
// get key normalization logic
|
||||
if (Constants.Platform == Platform.Windows)
|
||||
{
|
||||
IReflectedMethod method = reflection.GetMethod(typeof(TitleContainer), "GetCleanPath");
|
||||
this.NormaliseAssetNameForPlatform = path => method.Invoke<string>(path);
|
||||
this.NormalizeAssetNameForPlatform = path => method.Invoke<string>(path);
|
||||
}
|
||||
else
|
||||
this.NormaliseAssetNameForPlatform = key => key.Replace('\\', '/'); // based on MonoGame's ContentManager.Load<T> logic
|
||||
this.NormalizeAssetNameForPlatform = key => key.Replace('\\', '/'); // based on MonoGame's ContentManager.Load<T> logic
|
||||
}
|
||||
|
||||
/****
|
||||
|
@ -74,25 +74,25 @@ namespace StardewModdingAPI.Framework.Content
|
|||
|
||||
|
||||
/****
|
||||
** Normalise
|
||||
** Normalize
|
||||
****/
|
||||
/// <summary>Normalise path separators in a file path. For asset keys, see <see cref="NormaliseKey"/> instead.</summary>
|
||||
/// <param name="path">The file path to normalise.</param>
|
||||
/// <summary>Normalize path separators in a file path. For asset keys, see <see cref="NormalizeKey"/> instead.</summary>
|
||||
/// <param name="path">The file path to normalize.</param>
|
||||
[Pure]
|
||||
public string NormalisePathSeparators(string path)
|
||||
public string NormalizePathSeparators(string path)
|
||||
{
|
||||
return PathUtilities.NormalisePathSeparators(path);
|
||||
return PathUtilities.NormalizePathSeparators(path);
|
||||
}
|
||||
|
||||
/// <summary>Normalise a cache key so it's consistent with the underlying cache.</summary>
|
||||
/// <summary>Normalize a cache key so it's consistent with the underlying cache.</summary>
|
||||
/// <param name="key">The asset key.</param>
|
||||
[Pure]
|
||||
public string NormaliseKey(string key)
|
||||
public string NormalizeKey(string key)
|
||||
{
|
||||
key = this.NormalisePathSeparators(key);
|
||||
key = this.NormalizePathSeparators(key);
|
||||
return key.EndsWith(".xnb", StringComparison.InvariantCultureIgnoreCase)
|
||||
? key.Substring(0, key.Length - 4)
|
||||
: this.NormaliseAssetNameForPlatform(key);
|
||||
: this.NormalizeAssetNameForPlatform(key);
|
||||
}
|
||||
|
||||
/****
|
||||
|
|
|
@ -9,7 +9,7 @@ using StardewModdingAPI.Framework.Content;
|
|||
using StardewModdingAPI.Framework.ContentManagers;
|
||||
using StardewModdingAPI.Framework.Reflection;
|
||||
using StardewModdingAPI.Metadata;
|
||||
using StardewModdingAPI.Toolkit.Serialisation;
|
||||
using StardewModdingAPI.Toolkit.Serialization;
|
||||
using StardewModdingAPI.Toolkit.Utilities;
|
||||
using StardewValley;
|
||||
|
||||
|
@ -74,7 +74,7 @@ namespace StardewModdingAPI.Framework
|
|||
/// <summary>Construct an instance.</summary>
|
||||
/// <param name="serviceProvider">The service provider to use to locate services.</param>
|
||||
/// <param name="rootDirectory">The root directory to search for content.</param>
|
||||
/// <param name="currentCulture">The current culture for which to localise content.</param>
|
||||
/// <param name="currentCulture">The current culture for which to localize content.</param>
|
||||
/// <param name="monitor">Encapsulates monitoring and logging.</param>
|
||||
/// <param name="reflection">Simplifies access to private code.</param>
|
||||
/// <param name="jsonHelper">Encapsulates SMAPI's JSON file parsing.</param>
|
||||
|
@ -89,7 +89,7 @@ namespace StardewModdingAPI.Framework
|
|||
this.ContentManagers.Add(
|
||||
this.MainContentManager = new GameContentManager("Game1.content", serviceProvider, rootDirectory, currentCulture, this, monitor, reflection, this.OnDisposing, onLoadingFirstAsset)
|
||||
);
|
||||
this.CoreAssets = new CoreAssetPropagator(this.MainContentManager.AssertAndNormaliseAssetName, reflection, monitor);
|
||||
this.CoreAssets = new CoreAssetPropagator(this.MainContentManager.AssertAndNormalizeAssetName, reflection, monitor);
|
||||
}
|
||||
|
||||
/// <summary>Get a new content manager which handles reading files from the game content folder with support for interception.</summary>
|
||||
|
@ -250,7 +250,7 @@ namespace StardewModdingAPI.Framework
|
|||
string locale = this.GetLocale();
|
||||
return this.InvalidateCache((assetName, type) =>
|
||||
{
|
||||
IAssetInfo info = new AssetInfo(locale, assetName, type, this.MainContentManager.AssertAndNormaliseAssetName);
|
||||
IAssetInfo info = new AssetInfo(locale, assetName, type, this.MainContentManager.AssertAndNormalizeAssetName);
|
||||
return predicate(info);
|
||||
}, dispose);
|
||||
}
|
||||
|
|
|
@ -64,7 +64,7 @@ namespace StardewModdingAPI.Framework.ContentManagers
|
|||
/// <param name="name">A name for the mod manager. Not guaranteed to be unique.</param>
|
||||
/// <param name="serviceProvider">The service provider to use to locate services.</param>
|
||||
/// <param name="rootDirectory">The root directory to search for content.</param>
|
||||
/// <param name="currentCulture">The current culture for which to localise content.</param>
|
||||
/// <param name="currentCulture">The current culture for which to localize content.</param>
|
||||
/// <param name="coordinator">The central coordinator which manages content managers.</param>
|
||||
/// <param name="monitor">Encapsulates monitoring and logging.</param>
|
||||
/// <param name="reflection">Simplifies access to private code.</param>
|
||||
|
@ -109,7 +109,7 @@ namespace StardewModdingAPI.Framework.ContentManagers
|
|||
/// <param name="useCache">Whether to read/write the loaded asset to the asset cache.</param>
|
||||
public abstract T Load<T>(string assetName, LocalizedContentManager.LanguageCode language, bool useCache);
|
||||
|
||||
/// <summary>Load the base asset without localisation.</summary>
|
||||
/// <summary>Load the base asset without localization.</summary>
|
||||
/// <typeparam name="T">The type of asset to load.</typeparam>
|
||||
/// <param name="assetName">The asset path relative to the loader root directory, not including the <c>.xnb</c> extension.</param>
|
||||
[Obsolete("This method is implemented for the base game and should not be used directly. To load an asset from the underlying content manager directly, use " + nameof(BaseContentManager.RawLoad) + " instead.")]
|
||||
|
@ -121,19 +121,19 @@ namespace StardewModdingAPI.Framework.ContentManagers
|
|||
/// <summary>Perform any cleanup needed when the locale changes.</summary>
|
||||
public virtual void OnLocaleChanged() { }
|
||||
|
||||
/// <summary>Normalise path separators in a file path. For asset keys, see <see cref="AssertAndNormaliseAssetName"/> instead.</summary>
|
||||
/// <param name="path">The file path to normalise.</param>
|
||||
/// <summary>Normalize path separators in a file path. For asset keys, see <see cref="AssertAndNormalizeAssetName"/> instead.</summary>
|
||||
/// <param name="path">The file path to normalize.</param>
|
||||
[Pure]
|
||||
public string NormalisePathSeparators(string path)
|
||||
public string NormalizePathSeparators(string path)
|
||||
{
|
||||
return this.Cache.NormalisePathSeparators(path);
|
||||
return this.Cache.NormalizePathSeparators(path);
|
||||
}
|
||||
|
||||
/// <summary>Assert that the given key has a valid format and return a normalised form consistent with the underlying cache.</summary>
|
||||
/// <summary>Assert that the given key has a valid format and return a normalized form consistent with the underlying cache.</summary>
|
||||
/// <param name="assetName">The asset key to check.</param>
|
||||
/// <exception cref="SContentLoadException">The asset key is empty or contains invalid characters.</exception>
|
||||
[SuppressMessage("ReSharper", "ParameterOnlyUsedForPreconditionCheck.Local", Justification = "Parameter is only used for assertion checks by design.")]
|
||||
public string AssertAndNormaliseAssetName(string assetName)
|
||||
public string AssertAndNormalizeAssetName(string assetName)
|
||||
{
|
||||
// NOTE: the game checks for ContentLoadException to handle invalid keys, so avoid
|
||||
// throwing other types like ArgumentException here.
|
||||
|
@ -142,7 +142,7 @@ namespace StardewModdingAPI.Framework.ContentManagers
|
|||
if (assetName.Intersect(Path.GetInvalidPathChars()).Any())
|
||||
throw new SContentLoadException("The asset key or local path contains invalid characters.");
|
||||
|
||||
return this.Cache.NormaliseKey(assetName);
|
||||
return this.Cache.NormalizeKey(assetName);
|
||||
}
|
||||
|
||||
/****
|
||||
|
@ -165,8 +165,8 @@ namespace StardewModdingAPI.Framework.ContentManagers
|
|||
/// <param name="assetName">The asset path relative to the loader root directory, not including the <c>.xnb</c> extension.</param>
|
||||
public bool IsLoaded(string assetName)
|
||||
{
|
||||
assetName = this.Cache.NormaliseKey(assetName);
|
||||
return this.IsNormalisedKeyLoaded(assetName);
|
||||
assetName = this.Cache.NormalizeKey(assetName);
|
||||
return this.IsNormalizedKeyLoaded(assetName);
|
||||
}
|
||||
|
||||
/// <summary>Get the cached asset keys.</summary>
|
||||
|
@ -248,7 +248,7 @@ namespace StardewModdingAPI.Framework.ContentManagers
|
|||
*********/
|
||||
/// <summary>Load an asset file directly from the underlying content manager.</summary>
|
||||
/// <typeparam name="T">The type of asset to load.</typeparam>
|
||||
/// <param name="assetName">The normalised asset key.</param>
|
||||
/// <param name="assetName">The normalized asset key.</param>
|
||||
/// <param name="useCache">Whether to read/write the loaded asset to the asset cache.</param>
|
||||
protected virtual T RawLoad<T>(string assetName, bool useCache)
|
||||
{
|
||||
|
@ -264,17 +264,17 @@ namespace StardewModdingAPI.Framework.ContentManagers
|
|||
/// <param name="language">The language code for which to inject the asset.</param>
|
||||
protected virtual void Inject<T>(string assetName, T value, LanguageCode language)
|
||||
{
|
||||
assetName = this.AssertAndNormaliseAssetName(assetName);
|
||||
assetName = this.AssertAndNormalizeAssetName(assetName);
|
||||
this.Cache[assetName] = value;
|
||||
}
|
||||
|
||||
/// <summary>Parse a cache key into its component parts.</summary>
|
||||
/// <param name="cacheKey">The input cache key.</param>
|
||||
/// <param name="assetName">The original asset name.</param>
|
||||
/// <param name="localeCode">The asset locale code (or <c>null</c> if not localised).</param>
|
||||
/// <param name="localeCode">The asset locale code (or <c>null</c> if not localized).</param>
|
||||
protected void ParseCacheKey(string cacheKey, out string assetName, out string localeCode)
|
||||
{
|
||||
// handle localised key
|
||||
// handle localized key
|
||||
if (!string.IsNullOrWhiteSpace(cacheKey))
|
||||
{
|
||||
int lastSepIndex = cacheKey.LastIndexOf(".", StringComparison.InvariantCulture);
|
||||
|
@ -296,8 +296,8 @@ namespace StardewModdingAPI.Framework.ContentManagers
|
|||
}
|
||||
|
||||
/// <summary>Get whether an asset has already been loaded.</summary>
|
||||
/// <param name="normalisedAssetName">The normalised asset name.</param>
|
||||
protected abstract bool IsNormalisedKeyLoaded(string normalisedAssetName);
|
||||
/// <param name="normalizedAssetName">The normalized asset name.</param>
|
||||
protected abstract bool IsNormalizedKeyLoaded(string normalizedAssetName);
|
||||
|
||||
/// <summary>Get the locale codes (like <c>ja-JP</c>) used in asset keys.</summary>
|
||||
private IDictionary<LanguageCode, string> GetKeyLocales()
|
||||
|
|
|
@ -26,8 +26,8 @@ namespace StardewModdingAPI.Framework.ContentManagers
|
|||
/// <summary>Interceptors which edit matching assets after they're loaded.</summary>
|
||||
private IDictionary<IModMetadata, IList<IAssetEditor>> Editors => this.Coordinator.Editors;
|
||||
|
||||
/// <summary>A lookup which indicates whether the asset is localisable (i.e. the filename contains the locale), if previously loaded.</summary>
|
||||
private readonly IDictionary<string, bool> IsLocalisableLookup;
|
||||
/// <summary>A lookup which indicates whether the asset is localizable (i.e. the filename contains the locale), if previously loaded.</summary>
|
||||
private readonly IDictionary<string, bool> IsLocalizableLookup;
|
||||
|
||||
/// <summary>Whether the next load is the first for any game content manager.</summary>
|
||||
private static bool IsFirstLoad = true;
|
||||
|
@ -43,7 +43,7 @@ namespace StardewModdingAPI.Framework.ContentManagers
|
|||
/// <param name="name">A name for the mod manager. Not guaranteed to be unique.</param>
|
||||
/// <param name="serviceProvider">The service provider to use to locate services.</param>
|
||||
/// <param name="rootDirectory">The root directory to search for content.</param>
|
||||
/// <param name="currentCulture">The current culture for which to localise content.</param>
|
||||
/// <param name="currentCulture">The current culture for which to localize content.</param>
|
||||
/// <param name="coordinator">The central coordinator which manages content managers.</param>
|
||||
/// <param name="monitor">Encapsulates monitoring and logging.</param>
|
||||
/// <param name="reflection">Simplifies access to private code.</param>
|
||||
|
@ -52,7 +52,7 @@ namespace StardewModdingAPI.Framework.ContentManagers
|
|||
public GameContentManager(string name, IServiceProvider serviceProvider, string rootDirectory, CultureInfo currentCulture, ContentCoordinator coordinator, IMonitor monitor, Reflector reflection, Action<BaseContentManager> onDisposing, Action onLoadingFirstAsset)
|
||||
: base(name, serviceProvider, rootDirectory, currentCulture, coordinator, monitor, reflection, onDisposing, isNamespaced: false)
|
||||
{
|
||||
this.IsLocalisableLookup = reflection.GetField<IDictionary<string, bool>>(this, "_localizedAsset").GetValue();
|
||||
this.IsLocalizableLookup = reflection.GetField<IDictionary<string, bool>>(this, "_localizedAsset").GetValue();
|
||||
this.OnLoadingFirstAsset = onLoadingFirstAsset;
|
||||
}
|
||||
|
||||
|
@ -70,8 +70,8 @@ namespace StardewModdingAPI.Framework.ContentManagers
|
|||
this.OnLoadingFirstAsset();
|
||||
}
|
||||
|
||||
// normalise asset name
|
||||
assetName = this.AssertAndNormaliseAssetName(assetName);
|
||||
// normalize asset name
|
||||
assetName = this.AssertAndNormalizeAssetName(assetName);
|
||||
if (this.TryParseExplicitLanguageAssetKey(assetName, out string newAssetName, out LanguageCode newLanguage))
|
||||
return this.Load<T>(newAssetName, newLanguage, useCache);
|
||||
|
||||
|
@ -101,10 +101,10 @@ namespace StardewModdingAPI.Framework.ContentManagers
|
|||
data = this.AssetsBeingLoaded.Track(assetName, () =>
|
||||
{
|
||||
string locale = this.GetLocale(language);
|
||||
IAssetInfo info = new AssetInfo(locale, assetName, typeof(T), this.AssertAndNormaliseAssetName);
|
||||
IAssetInfo info = new AssetInfo(locale, assetName, typeof(T), this.AssertAndNormalizeAssetName);
|
||||
IAssetData asset =
|
||||
this.ApplyLoader<T>(info)
|
||||
?? new AssetDataForObject(info, this.RawLoad<T>(assetName, language, useCache), this.AssertAndNormaliseAssetName);
|
||||
?? new AssetDataForObject(info, this.RawLoad<T>(assetName, language, useCache), this.AssertAndNormalizeAssetName);
|
||||
asset = this.ApplyEditors<T>(info, asset);
|
||||
return (T)asset.Data;
|
||||
});
|
||||
|
@ -122,7 +122,7 @@ namespace StardewModdingAPI.Framework.ContentManagers
|
|||
|
||||
// find assets for which a translatable version was loaded
|
||||
HashSet<string> removeAssetNames = new HashSet<string>(StringComparer.InvariantCultureIgnoreCase);
|
||||
foreach (string key in this.IsLocalisableLookup.Where(p => p.Value).Select(p => p.Key))
|
||||
foreach (string key in this.IsLocalizableLookup.Where(p => p.Value).Select(p => p.Key))
|
||||
removeAssetNames.Add(this.TryParseExplicitLanguageAssetKey(key, out string assetName, out _) ? assetName : key);
|
||||
|
||||
// invalidate translatable assets
|
||||
|
@ -149,20 +149,20 @@ namespace StardewModdingAPI.Framework.ContentManagers
|
|||
** Private methods
|
||||
*********/
|
||||
/// <summary>Get whether an asset has already been loaded.</summary>
|
||||
/// <param name="normalisedAssetName">The normalised asset name.</param>
|
||||
protected override bool IsNormalisedKeyLoaded(string normalisedAssetName)
|
||||
/// <param name="normalizedAssetName">The normalized asset name.</param>
|
||||
protected override bool IsNormalizedKeyLoaded(string normalizedAssetName)
|
||||
{
|
||||
// default English
|
||||
if (this.Language == LocalizedContentManager.LanguageCode.en || this.Coordinator.IsManagedAssetKey(normalisedAssetName))
|
||||
return this.Cache.ContainsKey(normalisedAssetName);
|
||||
if (this.Language == LocalizedContentManager.LanguageCode.en || this.Coordinator.IsManagedAssetKey(normalizedAssetName))
|
||||
return this.Cache.ContainsKey(normalizedAssetName);
|
||||
|
||||
// translated
|
||||
string keyWithLocale = $"{normalisedAssetName}.{this.GetLocale(this.GetCurrentLanguage())}";
|
||||
if (this.IsLocalisableLookup.TryGetValue(keyWithLocale, out bool localisable))
|
||||
string keyWithLocale = $"{normalizedAssetName}.{this.GetLocale(this.GetCurrentLanguage())}";
|
||||
if (this.IsLocalizableLookup.TryGetValue(keyWithLocale, out bool localizable))
|
||||
{
|
||||
return localisable
|
||||
return localizable
|
||||
? this.Cache.ContainsKey(keyWithLocale)
|
||||
: this.Cache.ContainsKey(normalisedAssetName);
|
||||
: this.Cache.ContainsKey(normalizedAssetName);
|
||||
}
|
||||
|
||||
// not loaded yet
|
||||
|
@ -190,13 +190,13 @@ namespace StardewModdingAPI.Framework.ContentManagers
|
|||
string keyWithLocale = $"{assetName}.{this.GetLocale(language)}";
|
||||
if (this.Cache.ContainsKey(keyWithLocale))
|
||||
{
|
||||
this.IsLocalisableLookup[assetName] = true;
|
||||
this.IsLocalisableLookup[keyWithLocale] = true;
|
||||
this.IsLocalizableLookup[assetName] = true;
|
||||
this.IsLocalizableLookup[keyWithLocale] = true;
|
||||
}
|
||||
else if (this.Cache.ContainsKey(assetName))
|
||||
{
|
||||
this.IsLocalisableLookup[assetName] = false;
|
||||
this.IsLocalisableLookup[keyWithLocale] = false;
|
||||
this.IsLocalizableLookup[assetName] = false;
|
||||
this.IsLocalizableLookup[keyWithLocale] = false;
|
||||
}
|
||||
else
|
||||
this.Monitor.Log($"Asset '{assetName}' could not be found in the cache immediately after injection.", LogLevel.Error);
|
||||
|
@ -204,7 +204,7 @@ namespace StardewModdingAPI.Framework.ContentManagers
|
|||
|
||||
/// <summary>Load an asset file directly from the underlying content manager.</summary>
|
||||
/// <typeparam name="T">The type of asset to load.</typeparam>
|
||||
/// <param name="assetName">The normalised asset key.</param>
|
||||
/// <param name="assetName">The normalized asset key.</param>
|
||||
/// <param name="language">The language code for which to load content.</param>
|
||||
/// <param name="useCache">Whether to read/write the loaded asset to the asset cache.</param>
|
||||
/// <remarks>Derived from <see cref="LocalizedContentManager.Load{T}(string, LocalizedContentManager.LanguageCode)"/>.</remarks>
|
||||
|
@ -214,19 +214,19 @@ namespace StardewModdingAPI.Framework.ContentManagers
|
|||
if (language != LocalizedContentManager.LanguageCode.en)
|
||||
{
|
||||
string translatedKey = $"{assetName}.{this.GetLocale(language)}";
|
||||
if (!this.IsLocalisableLookup.TryGetValue(translatedKey, out bool isTranslatable) || isTranslatable)
|
||||
if (!this.IsLocalizableLookup.TryGetValue(translatedKey, out bool isTranslatable) || isTranslatable)
|
||||
{
|
||||
try
|
||||
{
|
||||
T obj = base.RawLoad<T>(translatedKey, useCache);
|
||||
this.IsLocalisableLookup[assetName] = true;
|
||||
this.IsLocalisableLookup[translatedKey] = true;
|
||||
this.IsLocalizableLookup[assetName] = true;
|
||||
this.IsLocalizableLookup[translatedKey] = true;
|
||||
return obj;
|
||||
}
|
||||
catch (ContentLoadException)
|
||||
{
|
||||
this.IsLocalisableLookup[assetName] = false;
|
||||
this.IsLocalisableLookup[translatedKey] = false;
|
||||
this.IsLocalizableLookup[assetName] = false;
|
||||
this.IsLocalizableLookup[translatedKey] = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -313,7 +313,7 @@ namespace StardewModdingAPI.Framework.ContentManagers
|
|||
}
|
||||
|
||||
// return matched asset
|
||||
return new AssetDataForObject(info, data, this.AssertAndNormaliseAssetName);
|
||||
return new AssetDataForObject(info, data, this.AssertAndNormalizeAssetName);
|
||||
}
|
||||
|
||||
/// <summary>Apply any <see cref="Editors"/> to a loaded asset.</summary>
|
||||
|
@ -322,7 +322,7 @@ namespace StardewModdingAPI.Framework.ContentManagers
|
|||
/// <param name="asset">The loaded asset.</param>
|
||||
private IAssetData ApplyEditors<T>(IAssetInfo info, IAssetData asset)
|
||||
{
|
||||
IAssetData GetNewData(object data) => new AssetDataForObject(info, data, this.AssertAndNormaliseAssetName);
|
||||
IAssetData GetNewData(object data) => new AssetDataForObject(info, data, this.AssertAndNormalizeAssetName);
|
||||
|
||||
// edit asset
|
||||
foreach (var entry in this.GetInterceptors(this.Editors))
|
||||
|
|
|
@ -39,15 +39,15 @@ namespace StardewModdingAPI.Framework.ContentManagers
|
|||
/// <summary>Perform any cleanup needed when the locale changes.</summary>
|
||||
void OnLocaleChanged();
|
||||
|
||||
/// <summary>Normalise path separators in a file path. For asset keys, see <see cref="AssertAndNormaliseAssetName"/> instead.</summary>
|
||||
/// <param name="path">The file path to normalise.</param>
|
||||
/// <summary>Normalize path separators in a file path. For asset keys, see <see cref="AssertAndNormalizeAssetName"/> instead.</summary>
|
||||
/// <param name="path">The file path to normalize.</param>
|
||||
[Pure]
|
||||
string NormalisePathSeparators(string path);
|
||||
string NormalizePathSeparators(string path);
|
||||
|
||||
/// <summary>Assert that the given key has a valid format and return a normalised form consistent with the underlying cache.</summary>
|
||||
/// <summary>Assert that the given key has a valid format and return a normalized form consistent with the underlying cache.</summary>
|
||||
/// <param name="assetName">The asset key to check.</param>
|
||||
/// <exception cref="SContentLoadException">The asset key is empty or contains invalid characters.</exception>
|
||||
string AssertAndNormaliseAssetName(string assetName);
|
||||
string AssertAndNormalizeAssetName(string assetName);
|
||||
|
||||
/// <summary>Get the current content locale.</summary>
|
||||
string GetLocale();
|
||||
|
|
|
@ -7,7 +7,7 @@ using Microsoft.Xna.Framework.Content;
|
|||
using Microsoft.Xna.Framework.Graphics;
|
||||
using StardewModdingAPI.Framework.Exceptions;
|
||||
using StardewModdingAPI.Framework.Reflection;
|
||||
using StardewModdingAPI.Toolkit.Serialisation;
|
||||
using StardewModdingAPI.Toolkit.Serialization;
|
||||
using StardewModdingAPI.Toolkit.Utilities;
|
||||
using StardewValley;
|
||||
using xTile;
|
||||
|
@ -41,7 +41,7 @@ namespace StardewModdingAPI.Framework.ContentManagers
|
|||
/// <param name="gameContentManager">The game content manager used for map tilesheets not provided by the mod.</param>
|
||||
/// <param name="serviceProvider">The service provider to use to locate services.</param>
|
||||
/// <param name="rootDirectory">The root directory to search for content.</param>
|
||||
/// <param name="currentCulture">The current culture for which to localise content.</param>
|
||||
/// <param name="currentCulture">The current culture for which to localize content.</param>
|
||||
/// <param name="coordinator">The central coordinator which manages content managers.</param>
|
||||
/// <param name="monitor">Encapsulates monitoring and logging.</param>
|
||||
/// <param name="reflection">Simplifies access to private code.</param>
|
||||
|
@ -78,7 +78,7 @@ namespace StardewModdingAPI.Framework.ContentManagers
|
|||
/// <param name="useCache">Whether to read/write the loaded asset to the asset cache.</param>
|
||||
public override T Load<T>(string assetName, LanguageCode language, bool useCache)
|
||||
{
|
||||
assetName = this.AssertAndNormaliseAssetName(assetName);
|
||||
assetName = this.AssertAndNormalizeAssetName(assetName);
|
||||
|
||||
// disable caching
|
||||
// This is necessary to avoid assets being shared between content managers, which can
|
||||
|
@ -91,7 +91,7 @@ namespace StardewModdingAPI.Framework.ContentManagers
|
|||
// disable language handling
|
||||
// Mod files don't support automatic translation logic, so this should never happen.
|
||||
if (language != this.DefaultLanguage)
|
||||
throw new InvalidOperationException("Localised assets aren't supported by the mod content manager.");
|
||||
throw new InvalidOperationException("Localized assets aren't supported by the mod content manager.");
|
||||
|
||||
// resolve managed asset key
|
||||
{
|
||||
|
@ -121,7 +121,7 @@ namespace StardewModdingAPI.Framework.ContentManagers
|
|||
T data = this.RawLoad<T>(assetName, useCache: false);
|
||||
if (data is Map map)
|
||||
{
|
||||
this.NormaliseTilesheetPaths(map);
|
||||
this.NormalizeTilesheetPaths(map);
|
||||
this.FixCustomTilesheetPaths(map, relativeMapPath: assetName);
|
||||
}
|
||||
return data;
|
||||
|
@ -161,7 +161,7 @@ namespace StardewModdingAPI.Framework.ContentManagers
|
|||
// fetch & cache
|
||||
FormatManager formatManager = FormatManager.Instance;
|
||||
Map map = formatManager.LoadMap(file.FullName);
|
||||
this.NormaliseTilesheetPaths(map);
|
||||
this.NormalizeTilesheetPaths(map);
|
||||
this.FixCustomTilesheetPaths(map, relativeMapPath: assetName);
|
||||
return (T)(object)map;
|
||||
}
|
||||
|
@ -199,10 +199,10 @@ namespace StardewModdingAPI.Framework.ContentManagers
|
|||
** Private methods
|
||||
*********/
|
||||
/// <summary>Get whether an asset has already been loaded.</summary>
|
||||
/// <param name="normalisedAssetName">The normalised asset name.</param>
|
||||
protected override bool IsNormalisedKeyLoaded(string normalisedAssetName)
|
||||
/// <param name="normalizedAssetName">The normalized asset name.</param>
|
||||
protected override bool IsNormalizedKeyLoaded(string normalizedAssetName)
|
||||
{
|
||||
return this.Cache.ContainsKey(normalisedAssetName);
|
||||
return this.Cache.ContainsKey(normalizedAssetName);
|
||||
}
|
||||
|
||||
/// <summary>Get a file from the mod folder.</summary>
|
||||
|
@ -245,12 +245,12 @@ namespace StardewModdingAPI.Framework.ContentManagers
|
|||
return texture;
|
||||
}
|
||||
|
||||
/// <summary>Normalise map tilesheet paths for the current platform.</summary>
|
||||
/// <summary>Normalize map tilesheet paths for the current platform.</summary>
|
||||
/// <param name="map">The map whose tilesheets to fix.</param>
|
||||
private void NormaliseTilesheetPaths(Map map)
|
||||
private void NormalizeTilesheetPaths(Map map)
|
||||
{
|
||||
foreach (TileSheet tilesheet in map.TileSheets)
|
||||
tilesheet.ImageSource = this.NormalisePathSeparators(tilesheet.ImageSource);
|
||||
tilesheet.ImageSource = this.NormalizePathSeparators(tilesheet.ImageSource);
|
||||
}
|
||||
|
||||
/// <summary>Fix custom map tilesheet paths so they can be found by the content manager.</summary>
|
||||
|
@ -258,7 +258,7 @@ namespace StardewModdingAPI.Framework.ContentManagers
|
|||
/// <param name="relativeMapPath">The relative map path within the mod folder.</param>
|
||||
/// <exception cref="ContentLoadException">A map tilesheet couldn't be resolved.</exception>
|
||||
/// <remarks>
|
||||
/// The game's logic for tilesheets in <see cref="Game1.setGraphicsForSeason"/> is a bit specialised. It boils
|
||||
/// The game's logic for tilesheets in <see cref="Game1.setGraphicsForSeason"/> is a bit specialized. It boils
|
||||
/// down to this:
|
||||
/// * If the location is indoors or the desert, or the image source contains 'path' or 'object', it's loaded
|
||||
/// as-is relative to the <c>Content</c> folder.
|
||||
|
@ -276,7 +276,7 @@ namespace StardewModdingAPI.Framework.ContentManagers
|
|||
// get map info
|
||||
if (!map.TileSheets.Any())
|
||||
return;
|
||||
relativeMapPath = this.AssertAndNormaliseAssetName(relativeMapPath); // Mono's Path.GetDirectoryName doesn't handle Windows dir separators
|
||||
relativeMapPath = this.AssertAndNormalizeAssetName(relativeMapPath); // Mono's Path.GetDirectoryName doesn't handle Windows dir separators
|
||||
string relativeMapFolder = Path.GetDirectoryName(relativeMapPath) ?? ""; // folder path containing the map, relative to the mod folder
|
||||
bool isOutdoors = map.Properties.TryGetValue("Outdoors", out PropertyValue outdoorsProperty) && outdoorsProperty != null;
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@ using System;
|
|||
using System.IO;
|
||||
using Microsoft.Xna.Framework.Content;
|
||||
using Microsoft.Xna.Framework.Graphics;
|
||||
using StardewModdingAPI.Toolkit.Serialisation;
|
||||
using StardewModdingAPI.Toolkit.Serialization;
|
||||
using StardewModdingAPI.Toolkit.Utilities;
|
||||
using xTile;
|
||||
|
||||
|
@ -63,14 +63,14 @@ namespace StardewModdingAPI.Framework
|
|||
|
||||
/// <summary>Read a JSON file from the content pack folder.</summary>
|
||||
/// <typeparam name="TModel">The model type.</typeparam>
|
||||
/// <param name="path">The file path relative to the contnet directory.</param>
|
||||
/// <returns>Returns the deserialised model, or <c>null</c> if the file doesn't exist or is empty.</returns>
|
||||
/// <param name="path">The file path relative to the content directory.</param>
|
||||
/// <returns>Returns the deserialized model, or <c>null</c> if the file doesn't exist or is empty.</returns>
|
||||
/// <exception cref="InvalidOperationException">The <paramref name="path"/> is not relative or contains directory climbing (../).</exception>
|
||||
public TModel ReadJsonFile<TModel>(string path) where TModel : class
|
||||
{
|
||||
this.AssertRelativePath(path, nameof(this.ReadJsonFile));
|
||||
|
||||
path = Path.Combine(this.DirectoryPath, PathUtilities.NormalisePathSeparators(path));
|
||||
path = Path.Combine(this.DirectoryPath, PathUtilities.NormalizePathSeparators(path));
|
||||
return this.JsonHelper.ReadJsonFileIfExists(path, out TModel model)
|
||||
? model
|
||||
: null;
|
||||
|
@ -85,7 +85,7 @@ namespace StardewModdingAPI.Framework
|
|||
{
|
||||
this.AssertRelativePath(path, nameof(this.WriteJsonFile));
|
||||
|
||||
path = Path.Combine(this.DirectoryPath, PathUtilities.NormalisePathSeparators(path));
|
||||
path = Path.Combine(this.DirectoryPath, PathUtilities.NormalizePathSeparators(path));
|
||||
this.JsonHelper.WriteJsonFile(path, data);
|
||||
}
|
||||
|
||||
|
|
|
@ -73,7 +73,7 @@ namespace StardewModdingAPI.Framework.Events
|
|||
/// <summary>Raised after the game finishes writing data to the save file (except the initial save creation).</summary>
|
||||
public readonly ManagedEvent<SavedEventArgs> Saved;
|
||||
|
||||
/// <summary>Raised after the player loads a save slot and the world is initialised.</summary>
|
||||
/// <summary>Raised after the player loads a save slot and the world is initialized.</summary>
|
||||
public readonly ManagedEvent<SaveLoadedEventArgs> SaveLoaded;
|
||||
|
||||
/// <summary>Raised after the game begins a new day, including when loading a save.</summary>
|
||||
|
@ -152,15 +152,15 @@ namespace StardewModdingAPI.Framework.Events
|
|||
public readonly ManagedEvent<TerrainFeatureListChangedEventArgs> TerrainFeatureListChanged;
|
||||
|
||||
/****
|
||||
** Specialised
|
||||
** Specialized
|
||||
****/
|
||||
/// <summary>Raised when the low-level stage in the game's loading process has changed. See notes on <see cref="ISpecialisedEvents.LoadStageChanged"/>.</summary>
|
||||
/// <summary>Raised when the low-level stage in the game's loading process has changed. See notes on <see cref="ISpecializedEvents.LoadStageChanged"/>.</summary>
|
||||
public readonly ManagedEvent<LoadStageChangedEventArgs> LoadStageChanged;
|
||||
|
||||
/// <summary>Raised before the game performs its overall update tick (≈60 times per second). See notes on <see cref="ISpecialisedEvents.UnvalidatedUpdateTicking"/>.</summary>
|
||||
/// <summary>Raised before the game performs its overall update tick (≈60 times per second). See notes on <see cref="ISpecializedEvents.UnvalidatedUpdateTicking"/>.</summary>
|
||||
public readonly ManagedEvent<UnvalidatedUpdateTickingEventArgs> UnvalidatedUpdateTicking;
|
||||
|
||||
/// <summary>Raised after the game performs its overall update tick (≈60 times per second). See notes on <see cref="ISpecialisedEvents.UnvalidatedUpdateTicked"/>.</summary>
|
||||
/// <summary>Raised after the game performs its overall update tick (≈60 times per second). See notes on <see cref="ISpecializedEvents.UnvalidatedUpdateTicked"/>.</summary>
|
||||
public readonly ManagedEvent<UnvalidatedUpdateTickedEventArgs> UnvalidatedUpdateTicked;
|
||||
|
||||
|
||||
|
@ -172,7 +172,7 @@ namespace StardewModdingAPI.Framework.Events
|
|||
/// <param name="modRegistry">The mod registry with which to identify mods.</param>
|
||||
public EventManager(IMonitor monitor, ModRegistry modRegistry)
|
||||
{
|
||||
// create shortcut initialisers
|
||||
// create shortcut initializers
|
||||
ManagedEvent<TEventArgs> ManageEventOf<TEventArgs>(string typeName, string eventName) => new ManagedEvent<TEventArgs>($"{typeName}.{eventName}", monitor, modRegistry);
|
||||
|
||||
// init events (new)
|
||||
|
@ -223,9 +223,9 @@ namespace StardewModdingAPI.Framework.Events
|
|||
this.ObjectListChanged = ManageEventOf<ObjectListChangedEventArgs>(nameof(IModEvents.World), nameof(IWorldEvents.ObjectListChanged));
|
||||
this.TerrainFeatureListChanged = ManageEventOf<TerrainFeatureListChangedEventArgs>(nameof(IModEvents.World), nameof(IWorldEvents.TerrainFeatureListChanged));
|
||||
|
||||
this.LoadStageChanged = ManageEventOf<LoadStageChangedEventArgs>(nameof(IModEvents.Specialised), nameof(ISpecialisedEvents.LoadStageChanged));
|
||||
this.UnvalidatedUpdateTicking = ManageEventOf<UnvalidatedUpdateTickingEventArgs>(nameof(IModEvents.Specialised), nameof(ISpecialisedEvents.UnvalidatedUpdateTicking));
|
||||
this.UnvalidatedUpdateTicked = ManageEventOf<UnvalidatedUpdateTickedEventArgs>(nameof(IModEvents.Specialised), nameof(ISpecialisedEvents.UnvalidatedUpdateTicked));
|
||||
this.LoadStageChanged = ManageEventOf<LoadStageChangedEventArgs>(nameof(IModEvents.Specialized), nameof(ISpecializedEvents.LoadStageChanged));
|
||||
this.UnvalidatedUpdateTicking = ManageEventOf<UnvalidatedUpdateTickingEventArgs>(nameof(IModEvents.Specialized), nameof(ISpecializedEvents.UnvalidatedUpdateTicking));
|
||||
this.UnvalidatedUpdateTicked = ManageEventOf<UnvalidatedUpdateTickedEventArgs>(nameof(IModEvents.Specialized), nameof(ISpecializedEvents.UnvalidatedUpdateTicked));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,8 +26,8 @@ namespace StardewModdingAPI.Framework.Events
|
|||
/// <summary>Events raised when something changes in the world.</summary>
|
||||
public IWorldEvents World { get; }
|
||||
|
||||
/// <summary>Events serving specialised edge cases that shouldn't be used by most mods.</summary>
|
||||
public ISpecialisedEvents Specialised { get; }
|
||||
/// <summary>Events serving specialized edge cases that shouldn't be used by most mods.</summary>
|
||||
public ISpecializedEvents Specialized { get; }
|
||||
|
||||
|
||||
/*********
|
||||
|
@ -44,7 +44,7 @@ namespace StardewModdingAPI.Framework.Events
|
|||
this.Multiplayer = new ModMultiplayerEvents(mod, eventManager);
|
||||
this.Player = new ModPlayerEvents(mod, eventManager);
|
||||
this.World = new ModWorldEvents(mod, eventManager);
|
||||
this.Specialised = new ModSpecialisedEvents(mod, eventManager);
|
||||
this.Specialized = new ModSpecializedEvents(mod, eventManager);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -72,7 +72,7 @@ namespace StardewModdingAPI.Framework.Events
|
|||
remove => this.EventManager.Saved.Remove(value);
|
||||
}
|
||||
|
||||
/// <summary>Raised after the player loads a save slot and the world is initialised.</summary>
|
||||
/// <summary>Raised after the player loads a save slot and the world is initialized.</summary>
|
||||
public event EventHandler<SaveLoadedEventArgs> SaveLoaded
|
||||
{
|
||||
add => this.EventManager.SaveLoaded.Add(value);
|
||||
|
|
|
@ -3,8 +3,8 @@ using StardewModdingAPI.Events;
|
|||
|
||||
namespace StardewModdingAPI.Framework.Events
|
||||
{
|
||||
/// <summary>Events serving specialised edge cases that shouldn't be used by most mods.</summary>
|
||||
internal class ModSpecialisedEvents : ModEventsBase, ISpecialisedEvents
|
||||
/// <summary>Events serving specialized edge cases that shouldn't be used by most mods.</summary>
|
||||
internal class ModSpecializedEvents : ModEventsBase, ISpecializedEvents
|
||||
{
|
||||
/*********
|
||||
** Accessors
|
||||
|
@ -37,7 +37,7 @@ namespace StardewModdingAPI.Framework.Events
|
|||
/// <summary>Construct an instance.</summary>
|
||||
/// <param name="mod">The mod which uses this instance.</param>
|
||||
/// <param name="eventManager">The underlying event manager.</param>
|
||||
internal ModSpecialisedEvents(IModMetadata mod, EventManager eventManager)
|
||||
internal ModSpecializedEvents(IModMetadata mod, EventManager eventManager)
|
||||
: base(mod, eventManager) { }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,7 +18,7 @@ namespace StardewModdingAPI.Framework
|
|||
["1.04"] = "1.0.4",
|
||||
["1.05"] = "1.0.5",
|
||||
["1.051"] = "1.0.6-prerelease1", // not a very good mapping, but good enough for SMAPI's purposes.
|
||||
["1.051b"] = "1.0.6-prelease2",
|
||||
["1.051b"] = "1.0.6-prerelease2",
|
||||
["1.06"] = "1.0.6",
|
||||
["1.07"] = "1.0.7",
|
||||
["1.07a"] = "1.0.8-prerelease1",
|
||||
|
|
|
@ -55,7 +55,7 @@ namespace StardewModdingAPI.Framework
|
|||
** Exceptions
|
||||
****/
|
||||
/// <summary>Get a string representation of an exception suitable for writing to the error log.</summary>
|
||||
/// <param name="exception">The error to summarise.</param>
|
||||
/// <param name="exception">The error to summarize.</param>
|
||||
public static string GetLogSummary(this Exception exception)
|
||||
{
|
||||
switch (exception)
|
||||
|
|
|
@ -87,7 +87,7 @@ namespace StardewModdingAPI.Framework.ModHelpers
|
|||
{
|
||||
try
|
||||
{
|
||||
this.AssertAndNormaliseAssetName(key);
|
||||
this.AssertAndNormalizeAssetName(key);
|
||||
switch (source)
|
||||
{
|
||||
case ContentSource.GameContent:
|
||||
|
@ -106,12 +106,12 @@ namespace StardewModdingAPI.Framework.ModHelpers
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>Normalise an asset name so it's consistent with those generated by the game. This is mainly useful for string comparisons like <see cref="string.StartsWith(string)"/> on generated asset names, and isn't necessary when passing asset names into other content helper methods.</summary>
|
||||
/// <summary>Normalize an asset name so it's consistent with those generated by the game. This is mainly useful for string comparisons like <see cref="string.StartsWith(string)"/> on generated asset names, and isn't necessary when passing asset names into other content helper methods.</summary>
|
||||
/// <param name="assetName">The asset key.</param>
|
||||
[Pure]
|
||||
public string NormaliseAssetName(string assetName)
|
||||
public string NormalizeAssetName(string assetName)
|
||||
{
|
||||
return this.ModContentManager.AssertAndNormaliseAssetName(assetName);
|
||||
return this.ModContentManager.AssertAndNormalizeAssetName(assetName);
|
||||
}
|
||||
|
||||
/// <summary>Get the underlying key in the game's content cache for an asset. This can be used to load custom map tilesheets, but should be avoided when you can use the content API instead. This does not validate whether the asset exists.</summary>
|
||||
|
@ -123,7 +123,7 @@ namespace StardewModdingAPI.Framework.ModHelpers
|
|||
switch (source)
|
||||
{
|
||||
case ContentSource.GameContent:
|
||||
return this.GameContentManager.AssertAndNormaliseAssetName(key);
|
||||
return this.GameContentManager.AssertAndNormalizeAssetName(key);
|
||||
|
||||
case ContentSource.ModFolder:
|
||||
return this.ModContentManager.GetInternalAssetKey(key);
|
||||
|
@ -170,9 +170,9 @@ namespace StardewModdingAPI.Framework.ModHelpers
|
|||
/// <param name="key">The asset key to check.</param>
|
||||
/// <exception cref="ArgumentException">The asset key is empty or contains invalid characters.</exception>
|
||||
[SuppressMessage("ReSharper", "ParameterOnlyUsedForPreconditionCheck.Local", Justification = "Parameter is only used for assertion checks by design.")]
|
||||
private void AssertAndNormaliseAssetName(string key)
|
||||
private void AssertAndNormalizeAssetName(string key)
|
||||
{
|
||||
this.ModContentManager.AssertAndNormaliseAssetName(key);
|
||||
this.ModContentManager.AssertAndNormalizeAssetName(key);
|
||||
if (Path.IsPathRooted(key))
|
||||
throw new ArgumentException("The asset key must not be an absolute path.");
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using StardewModdingAPI.Toolkit.Serialisation.Models;
|
||||
using StardewModdingAPI.Toolkit.Serialization.Models;
|
||||
|
||||
namespace StardewModdingAPI.Framework.ModHelpers
|
||||
{
|
||||
|
@ -38,7 +38,7 @@ namespace StardewModdingAPI.Framework.ModHelpers
|
|||
return this.ContentPacks.Value;
|
||||
}
|
||||
|
||||
/// <summary>Create a temporary content pack to read files from a directory, using randomised manifest fields. This will generate fake manifest data; any <c>manifest.json</c> in the directory will be ignored. Temporary content packs will not appear in the SMAPI log and update checks will not be performed.</summary>
|
||||
/// <summary>Create a temporary content pack to read files from a directory, using randomized manifest fields. This will generate fake manifest data; any <c>manifest.json</c> in the directory will be ignored. Temporary content packs will not appear in the SMAPI log and update checks will not be performed.</summary>
|
||||
/// <param name="directoryPath">The absolute directory path containing the content pack files.</param>
|
||||
public IContentPack CreateFake(string directoryPath)
|
||||
{
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
using System;
|
||||
using System.IO;
|
||||
using Newtonsoft.Json;
|
||||
using StardewModdingAPI.Toolkit.Serialisation;
|
||||
using StardewModdingAPI.Toolkit.Serialization;
|
||||
using StardewModdingAPI.Toolkit.Utilities;
|
||||
using StardewValley;
|
||||
|
||||
|
@ -40,14 +40,14 @@ namespace StardewModdingAPI.Framework.ModHelpers
|
|||
/// <summary>Read data from a JSON file in the mod's folder.</summary>
|
||||
/// <typeparam name="TModel">The model type. This should be a plain class that has public properties for the data you want. The properties can be complex types.</typeparam>
|
||||
/// <param name="path">The file path relative to the mod folder.</param>
|
||||
/// <returns>Returns the deserialised model, or <c>null</c> if the file doesn't exist or is empty.</returns>
|
||||
/// <returns>Returns the deserialized model, or <c>null</c> if the file doesn't exist or is empty.</returns>
|
||||
/// <exception cref="InvalidOperationException">The <paramref name="path"/> is not relative or contains directory climbing (../).</exception>
|
||||
public TModel ReadJsonFile<TModel>(string path) where TModel : class
|
||||
{
|
||||
if (!PathUtilities.IsSafeRelativePath(path))
|
||||
throw new InvalidOperationException($"You must call {nameof(IModHelper.Data)}.{nameof(this.ReadJsonFile)} with a relative path.");
|
||||
|
||||
path = Path.Combine(this.ModFolderPath, PathUtilities.NormalisePathSeparators(path));
|
||||
path = Path.Combine(this.ModFolderPath, PathUtilities.NormalizePathSeparators(path));
|
||||
return this.JsonHelper.ReadJsonFileIfExists(path, out TModel data)
|
||||
? data
|
||||
: null;
|
||||
|
@ -63,7 +63,7 @@ namespace StardewModdingAPI.Framework.ModHelpers
|
|||
if (!PathUtilities.IsSafeRelativePath(path))
|
||||
throw new InvalidOperationException($"You must call {nameof(IMod.Helper)}.{nameof(IModHelper.Data)}.{nameof(this.WriteJsonFile)} with a relative path (without directory climbing).");
|
||||
|
||||
path = Path.Combine(this.ModFolderPath, PathUtilities.NormalisePathSeparators(path));
|
||||
path = Path.Combine(this.ModFolderPath, PathUtilities.NormalizePathSeparators(path));
|
||||
this.JsonHelper.WriteJsonFile(path, data);
|
||||
}
|
||||
|
||||
|
@ -83,7 +83,7 @@ namespace StardewModdingAPI.Framework.ModHelpers
|
|||
throw new InvalidOperationException($"Can't use {nameof(IMod.Helper)}.{nameof(IModHelper.Data)}.{nameof(this.ReadSaveData)} because this isn't the main player. (Save files are stored on the main player's computer.)");
|
||||
|
||||
return Game1.CustomData.TryGetValue(this.GetSaveFileKey(key), out string value)
|
||||
? this.JsonHelper.Deserialise<TModel>(value)
|
||||
? this.JsonHelper.Deserialize<TModel>(value)
|
||||
: null;
|
||||
}
|
||||
|
||||
|
@ -101,7 +101,7 @@ namespace StardewModdingAPI.Framework.ModHelpers
|
|||
|
||||
string internalKey = this.GetSaveFileKey(key);
|
||||
if (data != null)
|
||||
Game1.CustomData[internalKey] = this.JsonHelper.Serialise(data, Formatting.None);
|
||||
Game1.CustomData[internalKey] = this.JsonHelper.Serialize(data, Formatting.None);
|
||||
else
|
||||
Game1.CustomData.Remove(internalKey);
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@ using System;
|
|||
using System.IO;
|
||||
using StardewModdingAPI.Events;
|
||||
using StardewModdingAPI.Framework.Input;
|
||||
using StardewModdingAPI.Toolkit.Serialisation;
|
||||
using StardewModdingAPI.Toolkit.Serialization;
|
||||
|
||||
namespace StardewModdingAPI.Framework.ModHelpers
|
||||
{
|
||||
|
@ -73,7 +73,7 @@ namespace StardewModdingAPI.Framework.ModHelpers
|
|||
if (!Directory.Exists(modDirectory))
|
||||
throw new InvalidOperationException("The specified mod directory does not exist.");
|
||||
|
||||
// initialise
|
||||
// initialize
|
||||
this.DirectoryPath = modDirectory;
|
||||
this.Content = contentHelper ?? throw new ArgumentNullException(nameof(contentHelper));
|
||||
this.ContentPacks = contentPackHelper ?? throw new ArgumentNullException(nameof(contentPackHelper));
|
||||
|
|
|
@ -75,9 +75,9 @@ namespace StardewModdingAPI.Framework.ModHelpers
|
|||
public TInterface GetApi<TInterface>(string uniqueID) where TInterface : class
|
||||
{
|
||||
// validate
|
||||
if (!this.Registry.AreAllModsInitialised)
|
||||
if (!this.Registry.AreAllModsInitialized)
|
||||
{
|
||||
this.Monitor.Log("Tried to access a mod-provided API before all mods were initialised.", LogLevel.Error);
|
||||
this.Monitor.Log("Tried to access a mod-provided API before all mods were initialized.", LogLevel.Error);
|
||||
return null;
|
||||
}
|
||||
if (!typeof(TInterface).IsInterface)
|
||||
|
|
|
@ -5,7 +5,7 @@ using StardewModdingAPI.Framework.Reflection;
|
|||
namespace StardewModdingAPI.Framework.ModHelpers
|
||||
{
|
||||
/// <summary>Provides helper methods for accessing private game code.</summary>
|
||||
/// <remarks>This implementation searches up the type hierarchy, and caches the reflected fields and methods with a sliding expiry (to optimise performance without unnecessary memory usage).</remarks>
|
||||
/// <remarks>This implementation searches up the type hierarchy, and caches the reflected fields and methods with a sliding expiry (to optimize performance without unnecessary memory usage).</remarks>
|
||||
internal class ReflectionHelper : BaseHelper, IReflectionHelper
|
||||
{
|
||||
/*********
|
||||
|
|
|
@ -317,7 +317,7 @@ namespace StardewModdingAPI.Framework.ModLoading
|
|||
}
|
||||
|
||||
/// <summary>Process the result from an instruction handler.</summary>
|
||||
/// <param name="mod">The mod being analysed.</param>
|
||||
/// <param name="mod">The mod being analyzed.</param>
|
||||
/// <param name="handler">The instruction handler.</param>
|
||||
/// <param name="result">The result returned by the handler.</param>
|
||||
/// <param name="loggedMessages">The messages already logged for the current mod.</param>
|
||||
|
@ -341,9 +341,9 @@ namespace StardewModdingAPI.Framework.ModLoading
|
|||
mod.SetWarning(ModWarning.PatchesGame);
|
||||
break;
|
||||
|
||||
case InstructionHandleResult.DetectedSaveSerialiser:
|
||||
this.Monitor.LogOnce(loggedMessages, $"{logPrefix}Detected possible save serialiser change ({handler.NounPhrase}) in assembly {filename}.");
|
||||
mod.SetWarning(ModWarning.ChangesSaveSerialiser);
|
||||
case InstructionHandleResult.DetectedSaveSerializer:
|
||||
this.Monitor.LogOnce(loggedMessages, $"{logPrefix}Detected possible save serializer change ({handler.NounPhrase}) in assembly {filename}.");
|
||||
mod.SetWarning(ModWarning.ChangesSaveSerializer);
|
||||
break;
|
||||
|
||||
case InstructionHandleResult.DetectedUnvalidatedUpdateTick:
|
||||
|
@ -370,7 +370,7 @@ namespace StardewModdingAPI.Framework.ModLoading
|
|||
break;
|
||||
|
||||
default:
|
||||
throw new NotSupportedException($"Unrecognised instruction handler result '{result}'.");
|
||||
throw new NotSupportedException($"Unrecognized instruction handler result '{result}'.");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -73,7 +73,7 @@ namespace StardewModdingAPI.Framework.ModLoading.Finders
|
|||
** Protected methods
|
||||
*********/
|
||||
/// <summary>Get whether a CIL instruction matches.</summary>
|
||||
/// <param name="method">The method deifnition.</param>
|
||||
/// <param name="method">The method definition.</param>
|
||||
protected bool IsMatch(MethodDefinition method)
|
||||
{
|
||||
if (this.IsMatch(method.ReturnType))
|
||||
|
|
|
@ -18,12 +18,12 @@ namespace StardewModdingAPI.Framework.ModLoading
|
|||
DetectedGamePatch,
|
||||
|
||||
/// <summary>The instruction is compatible, but affects the save serializer in a way that may make saves unloadable without the mod.</summary>
|
||||
DetectedSaveSerialiser,
|
||||
DetectedSaveSerializer,
|
||||
|
||||
/// <summary>The instruction is compatible, but uses the <c>dynamic</c> keyword which won't work on Linux/Mac.</summary>
|
||||
DetectedDynamic,
|
||||
|
||||
/// <summary>The instruction is compatible, but references <see cref="ISpecialisedEvents.UnvalidatedUpdateTicking"/> or <see cref="ISpecialisedEvents.UnvalidatedUpdateTicked"/> which may impact stability.</summary>
|
||||
/// <summary>The instruction is compatible, but references <see cref="ISpecializedEvents.UnvalidatedUpdateTicking"/> or <see cref="ISpecializedEvents.UnvalidatedUpdateTicked"/> which may impact stability.</summary>
|
||||
DetectedUnvalidatedUpdateTick,
|
||||
|
||||
/// <summary>The instruction accesses the filesystem directly.</summary>
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
namespace StardewModdingAPI.Framework.ModLoading
|
||||
namespace StardewModdingAPI.Framework.ModLoading
|
||||
{
|
||||
/// <summary>The status of a given mod in the dependency-sorting algorithm.</summary>
|
||||
internal enum ModDependencyStatus
|
||||
|
@ -6,7 +6,7 @@
|
|||
/// <summary>The mod hasn't been visited yet.</summary>
|
||||
Queued,
|
||||
|
||||
/// <summary>The mod is currently being analysed as part of a dependency chain.</summary>
|
||||
/// <summary>The mod is currently being analyzed as part of a dependency chain.</summary>
|
||||
Checking,
|
||||
|
||||
/// <summary>The mod has already been sorted.</summary>
|
||||
|
|
|
@ -5,7 +5,7 @@ using System.Linq;
|
|||
using StardewModdingAPI.Toolkit;
|
||||
using StardewModdingAPI.Toolkit.Framework.ModData;
|
||||
using StardewModdingAPI.Toolkit.Framework.ModScanning;
|
||||
using StardewModdingAPI.Toolkit.Serialisation.Models;
|
||||
using StardewModdingAPI.Toolkit.Serialization.Models;
|
||||
using StardewModdingAPI.Toolkit.Utilities;
|
||||
|
||||
namespace StardewModdingAPI.Framework.ModLoading
|
||||
|
@ -143,11 +143,11 @@ namespace StardewModdingAPI.Framework.ModLoading
|
|||
continue;
|
||||
}
|
||||
|
||||
// invalid capitalisation
|
||||
// invalid capitalization
|
||||
string actualFilename = new DirectoryInfo(mod.DirectoryPath).GetFiles(mod.Manifest.EntryDll).FirstOrDefault()?.Name;
|
||||
if (actualFilename != mod.Manifest.EntryDll)
|
||||
{
|
||||
mod.SetStatus(ModMetadataStatus.Failed, $"its {nameof(IManifest.EntryDll)} value '{mod.Manifest.EntryDll}' doesn't match the actual file capitalisation '{actualFilename}'. The capitalisation must match for crossplatform compatibility.");
|
||||
mod.SetStatus(ModMetadataStatus.Failed, $"its {nameof(IManifest.EntryDll)} value '{mod.Manifest.EntryDll}' doesn't match the actual file capitalization '{actualFilename}'. The capitalization must match for crossplatform compatibility.");
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
@ -216,7 +216,7 @@ namespace StardewModdingAPI.Framework.ModLoading
|
|||
/// <param name="modDatabase">Handles access to SMAPI's internal mod metadata list.</param>
|
||||
public IEnumerable<IModMetadata> ProcessDependencies(IEnumerable<IModMetadata> mods, ModDatabase modDatabase)
|
||||
{
|
||||
// initialise metadata
|
||||
// initialize metadata
|
||||
mods = mods.ToArray();
|
||||
var sortedMods = new Stack<IModMetadata>();
|
||||
var states = mods.ToDictionary(mod => mod, mod => ModDependencyStatus.Queued);
|
||||
|
|
|
@ -54,7 +54,7 @@ namespace StardewModdingAPI.Framework.ModLoading
|
|||
{
|
||||
bool HeuristicallyEquals(string typeNameA, string typeNameB, IDictionary<string, string> tokenMap)
|
||||
{
|
||||
// analyse type names
|
||||
// analyze type names
|
||||
bool hasTokensA = typeNameA.Contains("!");
|
||||
bool hasTokensB = typeNameB.Contains("!");
|
||||
bool isTokenA = hasTokensA && typeNameA[0] == '!';
|
||||
|
|
|
@ -21,8 +21,8 @@ namespace StardewModdingAPI.Framework
|
|||
/// <summary>Whether all mod assemblies have been loaded.</summary>
|
||||
public bool AreAllModsLoaded { get; set; }
|
||||
|
||||
/// <summary>Whether all mods have been initialised and their <see cref="IMod.Entry"/> method called.</summary>
|
||||
public bool AreAllModsInitialised { get; set; }
|
||||
/// <summary>Whether all mods have been initialized and their <see cref="IMod.Entry"/> method called.</summary>
|
||||
public bool AreAllModsInitialized { get; set; }
|
||||
|
||||
|
||||
/*********
|
||||
|
@ -62,7 +62,7 @@ namespace StardewModdingAPI.Framework
|
|||
/// <returns>Returns the matching mod's metadata, or <c>null</c> if not found.</returns>
|
||||
public IModMetadata Get(string uniqueID)
|
||||
{
|
||||
// normalise search ID
|
||||
// normalize search ID
|
||||
if (string.IsNullOrWhiteSpace(uniqueID))
|
||||
return null;
|
||||
uniqueID = uniqueID.Trim();
|
||||
|
|
|
@ -58,7 +58,7 @@ namespace StardewModdingAPI.Framework
|
|||
if (string.IsNullOrWhiteSpace(source))
|
||||
throw new ArgumentException("The log source cannot be empty.");
|
||||
|
||||
// initialise
|
||||
// initialize
|
||||
this.Source = source;
|
||||
this.LogFile = logFile ?? throw new ArgumentNullException(nameof(logFile), "The log file manager cannot be null.");
|
||||
this.ConsoleWriter = new ColorfulConsoleWriter(Constants.Platform, colorScheme);
|
||||
|
|
|
@ -2,7 +2,7 @@ using StardewValley;
|
|||
|
||||
namespace StardewModdingAPI.Framework.Networking
|
||||
{
|
||||
/// <summary>Network message types recognised by SMAPI and Stardew Valley.</summary>
|
||||
/// <summary>Network message types recognized by SMAPI and Stardew Valley.</summary>
|
||||
internal enum MessageType : byte
|
||||
{
|
||||
/*********
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue