From 45f4f85b7e74e0cffd345310d6aabc95c12dac26 Mon Sep 17 00:00:00 2001 From: Jesse Plamondon-Willard Date: Fri, 13 Apr 2018 23:47:24 -0400 Subject: add MacOS detection --- src/SMAPI/Framework/Content/ContentCache.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/SMAPI/Framework/Content') diff --git a/src/SMAPI/Framework/Content/ContentCache.cs b/src/SMAPI/Framework/Content/ContentCache.cs index 533da398..d95de4fe 100644 --- a/src/SMAPI/Framework/Content/ContentCache.cs +++ b/src/SMAPI/Framework/Content/ContentCache.cs @@ -3,7 +3,7 @@ using System.Collections.Generic; using System.Diagnostics.Contracts; using System.Linq; using Microsoft.Xna.Framework; -using StardewModdingAPI.Framework.ModLoading; +using StardewModdingAPI.Common; using StardewModdingAPI.Framework.Reflection; using StardewModdingAPI.Framework.Utilities; using StardewValley; -- cgit From 009a387526ee10b18d0ed3030d6e8868edf17203 Mon Sep 17 00:00:00 2001 From: Jesse Plamondon-Willard Date: Tue, 1 May 2018 18:44:39 -0400 Subject: unify SMAPI.AssemblyRewriters and SMAPI.Common projects --- build/common.targets | 2 +- build/prepare-install-package.targets | 4 +- docs/technical-docs.md | 6 +- .../Properties/AssemblyInfo.cs | 4 - src/SMAPI.AssemblyRewriters/SpriteBatchMethods.cs | 59 ------ .../StardewModdingAPI.AssemblyRewriters.csproj | 44 ----- src/SMAPI.Common/EnvironmentUtility.cs | 112 ------------ src/SMAPI.Common/Models/ModInfoModel.cs | 56 ------ src/SMAPI.Common/Models/ModSeachModel.cs | 37 ---- src/SMAPI.Common/Platform.cs | 15 -- src/SMAPI.Common/SemanticVersionImpl.cs | 199 --------------------- .../StardewModdingAPI.Common.projitems | 21 --- src/SMAPI.Common/StardewModdingAPI.Common.shproj | 13 -- src/SMAPI.Installer/InteractiveInstaller.cs | 5 +- .../StardewModdingAPI.Installer.csproj | 9 +- src/SMAPI.Internal/EnvironmentUtility.cs | 112 ++++++++++++ src/SMAPI.Internal/Models/ModInfoModel.cs | 56 ++++++ src/SMAPI.Internal/Models/ModSeachModel.cs | 37 ++++ src/SMAPI.Internal/Platform.cs | 15 ++ src/SMAPI.Internal/Properties/AssemblyInfo.cs | 9 + .../RewriteFacades/SpriteBatchMethods.cs | 59 ++++++ src/SMAPI.Internal/SemanticVersionImpl.cs | 199 +++++++++++++++++++++ .../StardewModdingAPI.Internal.csproj | 49 +++++ .../Framework/ModFileManager.cs | 2 +- .../StardewModdingAPI.ModBuildConfig.csproj | 7 +- src/SMAPI.Web/Controllers/IndexController.cs | 2 +- src/SMAPI.Web/Controllers/ModsApiController.cs | 2 +- src/SMAPI.Web/Framework/LogParsing/LogParser.cs | 2 +- .../Framework/ModRepositories/BaseRepository.cs | 2 +- .../ModRepositories/ChucklefishRepository.cs | 2 +- .../Framework/ModRepositories/GitHubRepository.cs | 2 +- .../Framework/ModRepositories/IModRepository.cs | 2 +- .../Framework/ModRepositories/NexusRepository.cs | 2 +- src/SMAPI.Web/Framework/VersionConstraint.cs | 2 +- src/SMAPI.Web/StardewModdingAPI.Web.csproj | 4 +- src/SMAPI.sln | 12 +- src/SMAPI/Constants.cs | 2 +- src/SMAPI/Framework/Content/ContentCache.cs | 2 +- src/SMAPI/Framework/ModLoading/AssemblyLoader.cs | 2 +- .../Framework/ModLoading/PlatformAssemblyMap.cs | 2 +- src/SMAPI/Framework/Monitor.cs | 2 +- src/SMAPI/Framework/WebApiClient.cs | 2 +- src/SMAPI/Metadata/InstructionMetadata.cs | 2 +- src/SMAPI/Program.cs | 4 +- src/SMAPI/SemanticVersion.cs | 2 +- src/SMAPI/StardewModdingAPI.csproj | 5 +- 46 files changed, 585 insertions(+), 605 deletions(-) delete mode 100644 src/SMAPI.AssemblyRewriters/Properties/AssemblyInfo.cs delete mode 100644 src/SMAPI.AssemblyRewriters/SpriteBatchMethods.cs delete mode 100644 src/SMAPI.AssemblyRewriters/StardewModdingAPI.AssemblyRewriters.csproj delete mode 100644 src/SMAPI.Common/EnvironmentUtility.cs delete mode 100644 src/SMAPI.Common/Models/ModInfoModel.cs delete mode 100644 src/SMAPI.Common/Models/ModSeachModel.cs delete mode 100644 src/SMAPI.Common/Platform.cs delete mode 100644 src/SMAPI.Common/SemanticVersionImpl.cs delete mode 100644 src/SMAPI.Common/StardewModdingAPI.Common.projitems delete mode 100644 src/SMAPI.Common/StardewModdingAPI.Common.shproj create mode 100644 src/SMAPI.Internal/EnvironmentUtility.cs create mode 100644 src/SMAPI.Internal/Models/ModInfoModel.cs create mode 100644 src/SMAPI.Internal/Models/ModSeachModel.cs create mode 100644 src/SMAPI.Internal/Platform.cs create mode 100644 src/SMAPI.Internal/Properties/AssemblyInfo.cs create mode 100644 src/SMAPI.Internal/RewriteFacades/SpriteBatchMethods.cs create mode 100644 src/SMAPI.Internal/SemanticVersionImpl.cs create mode 100644 src/SMAPI.Internal/StardewModdingAPI.Internal.csproj (limited to 'src/SMAPI/Framework/Content') diff --git a/build/common.targets b/build/common.targets index 588eea1b..54e24c74 100644 --- a/build/common.targets +++ b/build/common.targets @@ -98,7 +98,7 @@ - + diff --git a/build/prepare-install-package.targets b/build/prepare-install-package.targets index 8d10fc2e..8410f60e 100644 --- a/build/prepare-install-package.targets +++ b/build/prepare-install-package.targets @@ -29,7 +29,7 @@ - + @@ -43,7 +43,7 @@ - + diff --git a/docs/technical-docs.md b/docs/technical-docs.md index 52c3f96d..a988eefc 100644 --- a/docs/technical-docs.md +++ b/docs/technical-docs.md @@ -78,8 +78,9 @@ on the wiki for the first-time setup. Mono.Cecil.dll Newtonsoft.Json.dll StardewModdingAPI - StardewModdingAPI.AssemblyRewriters.dll StardewModdingAPI.config.json + StardewModdingAPI.Internal.dll + StardewModdingAPI.metadata.json StardewModdingAPI.exe StardewModdingAPI.pdb StardewModdingAPI.xml @@ -91,8 +92,9 @@ on the wiki for the first-time setup. Mods/* Mono.Cecil.dll Newtonsoft.Json.dll - StardewModdingAPI.AssemblyRewriters.dll StardewModdingAPI.config.json + StardewModdingAPI.Internal.dll + StardewModdingAPI.metadata.json StardewModdingAPI.exe StardewModdingAPI.pdb StardewModdingAPI.xml diff --git a/src/SMAPI.AssemblyRewriters/Properties/AssemblyInfo.cs b/src/SMAPI.AssemblyRewriters/Properties/AssemblyInfo.cs deleted file mode 100644 index f456a30d..00000000 --- a/src/SMAPI.AssemblyRewriters/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,4 +0,0 @@ -using System.Reflection; - -[assembly: AssemblyTitle("SMAPI.AssemblyRewriters")] -[assembly: AssemblyDescription("Contains internal SMAPI classes used during assembly rewriting that need to be public for technical reasons, but shouldn't be visible to modders.")] diff --git a/src/SMAPI.AssemblyRewriters/SpriteBatchMethods.cs b/src/SMAPI.AssemblyRewriters/SpriteBatchMethods.cs deleted file mode 100644 index a7f100f2..00000000 --- a/src/SMAPI.AssemblyRewriters/SpriteBatchMethods.cs +++ /dev/null @@ -1,59 +0,0 @@ -using System.Diagnostics.CodeAnalysis; -using Microsoft.Xna.Framework; -using Microsoft.Xna.Framework.Graphics; - -namespace StardewModdingAPI.AssemblyRewriters -{ - /// Provides method signatures that can be injected into mod code for compatibility between Linux/Mac or Windows. - public class SpriteBatchMethods : SpriteBatch - { - /********* - ** Public methods - *********/ - /// Construct an instance. - public SpriteBatchMethods(GraphicsDevice graphicsDevice) : base(graphicsDevice) { } - - - /**** - ** MonoGame signatures - ****/ - [SuppressMessage("ReSharper", "CS0109", Justification = "The 'new' modifier applies when compiled on Linux/Mac.")] - public new void Begin(SpriteSortMode sortMode, BlendState blendState, SamplerState samplerState, DepthStencilState depthStencilState, RasterizerState rasterizerState, Effect effect, Matrix? matrix) - { - base.Begin(sortMode, blendState, samplerState, depthStencilState, rasterizerState, effect, matrix ?? Matrix.Identity); - } - - /**** - ** XNA signatures - ****/ - [SuppressMessage("ReSharper", "CS0109", Justification = "The 'new' modifier applies when compiled on Windows.")] - public new void Begin() - { - base.Begin(); - } - - [SuppressMessage("ReSharper", "CS0109", Justification = "The 'new' modifier applies when compiled on Windows.")] - public new void Begin(SpriteSortMode sortMode, BlendState blendState) - { - base.Begin(sortMode, blendState); - } - - [SuppressMessage("ReSharper", "CS0109", Justification = "The 'new' modifier applies when compiled on Windows.")] - public new void Begin(SpriteSortMode sortMode, BlendState blendState, SamplerState samplerState, DepthStencilState depthStencilState, RasterizerState rasterizerState) - { - base.Begin(sortMode, blendState, samplerState, depthStencilState, rasterizerState); - } - - [SuppressMessage("ReSharper", "CS0109", Justification = "The 'new' modifier applies when compiled on Windows.")] - public new void Begin(SpriteSortMode sortMode, BlendState blendState, SamplerState samplerState, DepthStencilState depthStencilState, RasterizerState rasterizerState, Effect effect) - { - base.Begin(sortMode, blendState, samplerState, depthStencilState, rasterizerState, effect); - } - - [SuppressMessage("ReSharper", "CS0109", Justification = "The 'new' modifier applies when compiled on Windows.")] - public new void Begin(SpriteSortMode sortMode, BlendState blendState, SamplerState samplerState, DepthStencilState depthStencilState, RasterizerState rasterizerState, Effect effect, Matrix transformMatrix) - { - base.Begin(sortMode, blendState, samplerState, depthStencilState, rasterizerState, effect, transformMatrix); - } - } -} diff --git a/src/SMAPI.AssemblyRewriters/StardewModdingAPI.AssemblyRewriters.csproj b/src/SMAPI.AssemblyRewriters/StardewModdingAPI.AssemblyRewriters.csproj deleted file mode 100644 index 651b822d..00000000 --- a/src/SMAPI.AssemblyRewriters/StardewModdingAPI.AssemblyRewriters.csproj +++ /dev/null @@ -1,44 +0,0 @@ - - - - - Debug - x86 - {10DB0676-9FC1-4771-A2C8-E2519F091E49} - Library - Properties - StardewModdingAPI.AssemblyRewriters - StardewModdingAPI.AssemblyRewriters - v4.5 - 512 - - - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - - - pdbonly - true - bin\Release\ - TRACE - prompt - 4 - - - - - - - Properties\GlobalAssemblyInfo.cs - - - - - - - \ No newline at end of file diff --git a/src/SMAPI.Common/EnvironmentUtility.cs b/src/SMAPI.Common/EnvironmentUtility.cs deleted file mode 100644 index 9d9e91e6..00000000 --- a/src/SMAPI.Common/EnvironmentUtility.cs +++ /dev/null @@ -1,112 +0,0 @@ -using System; -using System.Diagnostics.CodeAnalysis; -using System.Linq; -#if SMAPI_FOR_WINDOWS -using System.Management; -#endif -using System.Runtime.InteropServices; - -namespace StardewModdingAPI.Common -{ - /// Provides methods for fetching environment information. - internal static class EnvironmentUtility - { - /********* - ** Properties - *********/ - /// Get the OS name from the system uname command. - /// The buffer to fill with the resulting string. - [DllImport("libc")] - static extern int uname(IntPtr buffer); - - - /********* - ** Public methods - *********/ - /// Detect the current OS. - public static Platform DetectPlatform() - { - switch (Environment.OSVersion.Platform) - { - case PlatformID.MacOSX: - return Platform.Mac; - - case PlatformID.Unix: - return EnvironmentUtility.IsRunningMac() - ? Platform.Mac - : Platform.Linux; - - default: - return Platform.Windows; - } - } - - - /// Get the human-readable OS name and version. - /// The current platform. - [SuppressMessage("ReSharper", "EmptyGeneralCatchClause", Justification = "Error suppressed deliberately to fallback to default behaviour.")] - public static string GetFriendlyPlatformName(Platform platform) - { -#if SMAPI_FOR_WINDOWS - try - { - return new ManagementObjectSearcher("SELECT Caption FROM Win32_OperatingSystem") - .Get() - .Cast() - .Select(entry => entry.GetPropertyValue("Caption").ToString()) - .FirstOrDefault(); - } - catch { } -#endif - return (platform == Platform.Mac ? "MacOS " : "") + Environment.OSVersion; - } - - /// Get the name of the Stardew Valley executable. - /// The current platform. - public static string GetExecutableName(Platform platform) - { - return platform == Platform.Windows - ? "Stardew Valley.exe" - : "StardewValley.exe"; - } - - /// Get whether the platform uses Mono. - /// The current platform. - public static bool IsMono(this Platform platform) - { - return platform == Platform.Linux || platform == Platform.Mac; - } - - /********* - ** Private methods - *********/ - /// Detect whether the code is running on Mac. - /// - /// This code is derived from the Mono project (see System.Windows.Forms/System.Windows.Forms/XplatUI.cs). It detects Mac by calling the - /// uname system command and checking the response, which is always 'Darwin' for MacOS. - /// - private static bool IsRunningMac() - { - IntPtr buffer = IntPtr.Zero; - try - { - buffer = Marshal.AllocHGlobal(8192); - if (uname(buffer) == 0) - { - string os = Marshal.PtrToStringAnsi(buffer); - return os == "Darwin"; - } - return false; - } - catch - { - return false; // default to Linux - } - finally - { - if (buffer != IntPtr.Zero) - Marshal.FreeHGlobal(buffer); - } - } - } -} diff --git a/src/SMAPI.Common/Models/ModInfoModel.cs b/src/SMAPI.Common/Models/ModInfoModel.cs deleted file mode 100644 index 48df235a..00000000 --- a/src/SMAPI.Common/Models/ModInfoModel.cs +++ /dev/null @@ -1,56 +0,0 @@ -namespace StardewModdingAPI.Common.Models -{ - /// Generic metadata about a mod. - internal class ModInfoModel - { - /********* - ** Accessors - *********/ - /// The mod name. - public string Name { get; set; } - - /// The semantic version for the mod's latest release. - public string Version { get; set; } - - /// The semantic version for the mod's latest preview release, if available and different from . - public string PreviewVersion { get; set; } - - /// The mod's web URL. - public string Url { get; set; } - - /// The error message indicating why the mod is invalid (if applicable). - public string Error { get; set; } - - - /********* - ** Public methods - *********/ - /// Construct an empty instance. - public ModInfoModel() - { - // needed for JSON deserialising - } - - /// Construct an instance. - /// The mod name. - /// The semantic version for the mod's latest release. - /// The semantic version for the mod's latest preview release, if available and different from . - /// The mod's web URL. - /// The error message indicating why the mod is invalid (if applicable). - public ModInfoModel(string name, string version, string url, string previewVersion = null, string error = null) - { - this.Name = name; - this.Version = version; - this.PreviewVersion = previewVersion; - this.Url = url; - this.Error = error; // mainly initialised here for the JSON deserialiser - } - - /// Construct an instance. - /// The error message indicating why the mod is invalid. - public ModInfoModel(string error) - { - this.Error = error; - } - } -} diff --git a/src/SMAPI.Common/Models/ModSeachModel.cs b/src/SMAPI.Common/Models/ModSeachModel.cs deleted file mode 100644 index 3c33d0b6..00000000 --- a/src/SMAPI.Common/Models/ModSeachModel.cs +++ /dev/null @@ -1,37 +0,0 @@ -using System.Collections.Generic; -using System.Linq; - -namespace StardewModdingAPI.Common.Models -{ - /// Specifies mods whose update-check info to fetch. - internal class ModSearchModel - { - /********* - ** Accessors - *********/ - /// The namespaced mod keys to search. - public string[] ModKeys { get; set; } - - /// Whether to allow non-semantic versions, instead of returning an error for those. - public bool AllowInvalidVersions { get; set; } - - - /********* - ** Public methods - *********/ - /// Construct an empty instance. - public ModSearchModel() - { - // needed for JSON deserialising - } - - /// Construct an instance. - /// The namespaced mod keys to search. - /// Whether to allow non-semantic versions, instead of returning an error for those. - public ModSearchModel(IEnumerable modKeys, bool allowInvalidVersions) - { - this.ModKeys = modKeys.ToArray(); - this.AllowInvalidVersions = allowInvalidVersions; - } - } -} diff --git a/src/SMAPI.Common/Platform.cs b/src/SMAPI.Common/Platform.cs deleted file mode 100644 index 08b4545f..00000000 --- a/src/SMAPI.Common/Platform.cs +++ /dev/null @@ -1,15 +0,0 @@ -namespace StardewModdingAPI.Common -{ - /// The game's platform version. - internal enum Platform - { - /// The Linux version of the game. - Linux, - - /// The Mac version of the game. - Mac, - - /// The Windows version of the game. - Windows - } -} diff --git a/src/SMAPI.Common/SemanticVersionImpl.cs b/src/SMAPI.Common/SemanticVersionImpl.cs deleted file mode 100644 index 084f56a3..00000000 --- a/src/SMAPI.Common/SemanticVersionImpl.cs +++ /dev/null @@ -1,199 +0,0 @@ -using System; -using System.Text.RegularExpressions; - -namespace StardewModdingAPI.Common -{ - /// A low-level implementation of a semantic version with an optional release tag. - /// The implementation is defined by Semantic Version 2.0 (http://semver.org/). - internal class SemanticVersionImpl - { - /********* - ** Accessors - *********/ - /// The major version incremented for major API changes. - public int Major { get; } - - /// The minor version incremented for backwards-compatible changes. - public int Minor { get; } - - /// The patch version for backwards-compatible bug fixes. - public int Patch { get; } - - /// An optional prerelease tag. - public string Tag { get; } - - /// A regex pattern matching a version within a larger string. - internal const string UnboundedVersionPattern = @"(?>(?0|[1-9]\d*))\.(?>(?0|[1-9]\d*))(?>(?:\.(?0|[1-9]\d*))?)(?:-(?(?>[a-z0-9]+[\-\.]?)+))?"; - - /// A regular expression matching a semantic version string. - /// - /// This pattern is derived from the BNF documentation in the semver repo, - /// with three important deviations intended to support Stardew Valley mod conventions: - /// - allows short-form "x.y" versions; - /// - allows hyphens in prerelease tags as synonyms for dots (like "-unofficial-update.3"); - /// - doesn't allow '+build' suffixes. - /// - internal static readonly Regex Regex = new Regex($@"^{SemanticVersionImpl.UnboundedVersionPattern}$", RegexOptions.CultureInvariant | RegexOptions.IgnoreCase | RegexOptions.Compiled | RegexOptions.ExplicitCapture); - - /********* - ** Public methods - *********/ - /// Construct an instance. - /// The major version incremented for major API changes. - /// The minor version incremented for backwards-compatible changes. - /// The patch version for backwards-compatible bug fixes. - /// An optional prerelease tag. - public SemanticVersionImpl(int major, int minor, int patch, string tag = null) - { - this.Major = major; - this.Minor = minor; - this.Patch = patch; - this.Tag = this.GetNormalisedTag(tag); - } - - /// Construct an instance. - /// The assembly version. - /// The is null. - public SemanticVersionImpl(Version version) - { - if (version == null) - throw new ArgumentNullException(nameof(version), "The input version can't be null."); - - this.Major = version.Major; - this.Minor = version.Minor; - this.Patch = version.Build; - } - - /// Construct an instance. - /// The semantic version string. - /// The is null. - /// The is not a valid semantic version. - public SemanticVersionImpl(string version) - { - // parse - if (version == null) - throw new ArgumentNullException(nameof(version), "The input version string can't be null."); - var match = SemanticVersionImpl.Regex.Match(version.Trim()); - if (!match.Success) - throw new FormatException($"The input '{version}' isn't a valid semantic version."); - - // initialise - this.Major = int.Parse(match.Groups["major"].Value); - this.Minor = match.Groups["minor"].Success ? int.Parse(match.Groups["minor"].Value) : 0; - this.Patch = match.Groups["patch"].Success ? int.Parse(match.Groups["patch"].Value) : 0; - this.Tag = match.Groups["prerelease"].Success ? this.GetNormalisedTag(match.Groups["prerelease"].Value) : null; - } - - /// Get an integer indicating whether this version precedes (less than 0), supercedes (more than 0), or is equivalent to (0) the specified version. - /// The version to compare with this instance. - /// The value is null. - public int CompareTo(SemanticVersionImpl other) - { - if (other == null) - throw new ArgumentNullException(nameof(other)); - return this.CompareTo(other.Major, other.Minor, other.Patch, other.Tag); - } - - - /// Get an integer indicating whether this version precedes (less than 0), supercedes (more than 0), or is equivalent to (0) the specified version. - /// The major version to compare with this instance. - /// The minor version to compare with this instance. - /// The patch version to compare with this instance. - /// The prerelease tag to compare with this instance. - public int CompareTo(int otherMajor, int otherMinor, int otherPatch, string otherTag) - { - const int same = 0; - const int curNewer = 1; - const int curOlder = -1; - - // compare stable versions - if (this.Major != otherMajor) - return this.Major.CompareTo(otherMajor); - if (this.Minor != otherMinor) - return this.Minor.CompareTo(otherMinor); - if (this.Patch != otherPatch) - return this.Patch.CompareTo(otherPatch); - if (this.Tag == otherTag) - return same; - - // stable supercedes pre-release - bool curIsStable = string.IsNullOrWhiteSpace(this.Tag); - bool otherIsStable = string.IsNullOrWhiteSpace(otherTag); - if (curIsStable) - return curNewer; - if (otherIsStable) - return curOlder; - - // compare two pre-release tag values - string[] curParts = this.Tag.Split('.', '-'); - string[] otherParts = otherTag.Split('.', '-'); - for (int i = 0; i < curParts.Length; i++) - { - // longer prerelease tag supercedes if otherwise equal - if (otherParts.Length <= i) - return curNewer; - - // compare if different - if (curParts[i] != otherParts[i]) - { - // compare numerically if possible - { - if (int.TryParse(curParts[i], out int curNum) && int.TryParse(otherParts[i], out int otherNum)) - return curNum.CompareTo(otherNum); - } - - // else compare lexically - return string.Compare(curParts[i], otherParts[i], StringComparison.OrdinalIgnoreCase); - } - } - - // fallback (this should never happen) - return string.Compare(this.ToString(), new SemanticVersionImpl(otherMajor, otherMinor, otherPatch, otherTag).ToString(), StringComparison.InvariantCultureIgnoreCase); - } - - /// Get a string representation of the version. - public override string ToString() - { - // version - string result = this.Patch != 0 - ? $"{this.Major}.{this.Minor}.{this.Patch}" - : $"{this.Major}.{this.Minor}"; - - // tag - string tag = this.Tag; - if (tag != null) - result += $"-{tag}"; - return result; - } - - /// Parse a version string without throwing an exception if it fails. - /// The version string. - /// The parsed representation. - /// Returns whether parsing the version succeeded. - internal static bool TryParse(string version, out SemanticVersionImpl parsed) - { - try - { - parsed = new SemanticVersionImpl(version); - return true; - } - catch - { - parsed = null; - return false; - } - } - - - /********* - ** Private methods - *********/ - /// Get a normalised build tag. - /// The tag to normalise. - private string GetNormalisedTag(string tag) - { - tag = tag?.Trim(); - return !string.IsNullOrWhiteSpace(tag) ? tag : null; - } - } -} diff --git a/src/SMAPI.Common/StardewModdingAPI.Common.projitems b/src/SMAPI.Common/StardewModdingAPI.Common.projitems deleted file mode 100644 index 0b89f092..00000000 --- a/src/SMAPI.Common/StardewModdingAPI.Common.projitems +++ /dev/null @@ -1,21 +0,0 @@ - - - - $(MSBuildAllProjects);$(MSBuildThisFileFullPath) - true - 2aa02fb6-ff03-41cf-a215-2ee60ab4f5dc - - - StardewModdingAPI.Common - - - - - - - - - - - - \ No newline at end of file diff --git a/src/SMAPI.Common/StardewModdingAPI.Common.shproj b/src/SMAPI.Common/StardewModdingAPI.Common.shproj deleted file mode 100644 index 0ef29144..00000000 --- a/src/SMAPI.Common/StardewModdingAPI.Common.shproj +++ /dev/null @@ -1,13 +0,0 @@ - - - - 2aa02fb6-ff03-41cf-a215-2ee60ab4f5dc - 14.0 - - - - - - - - diff --git a/src/SMAPI.Installer/InteractiveInstaller.cs b/src/SMAPI.Installer/InteractiveInstaller.cs index 0d602b57..c0bc8f2c 100644 --- a/src/SMAPI.Installer/InteractiveInstaller.cs +++ b/src/SMAPI.Installer/InteractiveInstaller.cs @@ -7,7 +7,7 @@ using System.Reflection; using System.Threading; using Microsoft.Win32; using StardewModdingApi.Installer.Enums; -using StardewModdingAPI.Common; +using StardewModdingAPI.Internal; namespace StardewModdingApi.Installer { @@ -83,7 +83,7 @@ namespace StardewModdingApi.Installer yield return GetInstallPath("StardewModdingAPI.exe"); yield return GetInstallPath("StardewModdingAPI.config.json"); yield return GetInstallPath("StardewModdingAPI.data.json"); - yield return GetInstallPath("StardewModdingAPI.AssemblyRewriters.dll"); + yield return GetInstallPath("StardewModdingAPI.Internal.dll"); yield return GetInstallPath("System.ValueTuple.dll"); yield return GetInstallPath("steam_appid.txt"); @@ -102,6 +102,7 @@ namespace StardewModdingApi.Installer yield return GetInstallPath(Path.Combine("Mods", "TrainerMod")); // *–2.0 (renamed to ConsoleCommands) yield return GetInstallPath("Mono.Cecil.Rocks.dll"); // 1.3–1.8 yield return GetInstallPath("StardewModdingAPI-settings.json"); // 1.0-1.4 + yield return GetInstallPath("StardewModdingAPI.AssemblyRewriters.dll"); // 1.3-2.5.5 if (modsDir.Exists) { foreach (DirectoryInfo modDir in modsDir.EnumerateDirectories()) diff --git a/src/SMAPI.Installer/StardewModdingAPI.Installer.csproj b/src/SMAPI.Installer/StardewModdingAPI.Installer.csproj index 7a71bef9..4f849b9b 100644 --- a/src/SMAPI.Installer/StardewModdingAPI.Installer.csproj +++ b/src/SMAPI.Installer/StardewModdingAPI.Installer.csproj @@ -9,7 +9,7 @@ Properties StardewModdingAPI.Installer StardewModdingAPI.Installer - v4.0 + v4.5 512 true @@ -57,7 +57,12 @@ PreserveNewest - + + + {10db0676-9fc1-4771-a2c8-e2519f091e49} + StardewModdingAPI.Internal + + diff --git a/src/SMAPI.Internal/EnvironmentUtility.cs b/src/SMAPI.Internal/EnvironmentUtility.cs new file mode 100644 index 00000000..a3581898 --- /dev/null +++ b/src/SMAPI.Internal/EnvironmentUtility.cs @@ -0,0 +1,112 @@ +using System; +using System.Diagnostics.CodeAnalysis; +using System.Linq; +#if SMAPI_FOR_WINDOWS +using System.Management; +#endif +using System.Runtime.InteropServices; + +namespace StardewModdingAPI.Internal +{ + /// Provides methods for fetching environment information. + internal static class EnvironmentUtility + { + /********* + ** Properties + *********/ + /// Get the OS name from the system uname command. + /// The buffer to fill with the resulting string. + [DllImport("libc")] + static extern int uname(IntPtr buffer); + + + /********* + ** Public methods + *********/ + /// Detect the current OS. + public static Platform DetectPlatform() + { + switch (Environment.OSVersion.Platform) + { + case PlatformID.MacOSX: + return Platform.Mac; + + case PlatformID.Unix: + return EnvironmentUtility.IsRunningMac() + ? Platform.Mac + : Platform.Linux; + + default: + return Platform.Windows; + } + } + + + /// Get the human-readable OS name and version. + /// The current platform. + [SuppressMessage("ReSharper", "EmptyGeneralCatchClause", Justification = "Error suppressed deliberately to fallback to default behaviour.")] + public static string GetFriendlyPlatformName(Platform platform) + { +#if SMAPI_FOR_WINDOWS + try + { + return new ManagementObjectSearcher("SELECT Caption FROM Win32_OperatingSystem") + .Get() + .Cast() + .Select(entry => entry.GetPropertyValue("Caption").ToString()) + .FirstOrDefault(); + } + catch { } +#endif + return (platform == Platform.Mac ? "MacOS " : "") + Environment.OSVersion; + } + + /// Get the name of the Stardew Valley executable. + /// The current platform. + public static string GetExecutableName(Platform platform) + { + return platform == Platform.Windows + ? "Stardew Valley.exe" + : "StardewValley.exe"; + } + + /// Get whether the platform uses Mono. + /// The current platform. + public static bool IsMono(this Platform platform) + { + return platform == Platform.Linux || platform == Platform.Mac; + } + + /********* + ** Private methods + *********/ + /// Detect whether the code is running on Mac. + /// + /// This code is derived from the Mono project (see System.Windows.Forms/System.Windows.Forms/XplatUI.cs). It detects Mac by calling the + /// uname system command and checking the response, which is always 'Darwin' for MacOS. + /// + private static bool IsRunningMac() + { + IntPtr buffer = IntPtr.Zero; + try + { + buffer = Marshal.AllocHGlobal(8192); + if (EnvironmentUtility.uname(buffer) == 0) + { + string os = Marshal.PtrToStringAnsi(buffer); + return os == "Darwin"; + } + return false; + } + catch + { + return false; // default to Linux + } + finally + { + if (buffer != IntPtr.Zero) + Marshal.FreeHGlobal(buffer); + } + } + } +} diff --git a/src/SMAPI.Internal/Models/ModInfoModel.cs b/src/SMAPI.Internal/Models/ModInfoModel.cs new file mode 100644 index 00000000..725c88bb --- /dev/null +++ b/src/SMAPI.Internal/Models/ModInfoModel.cs @@ -0,0 +1,56 @@ +namespace StardewModdingAPI.Internal.Models +{ + /// Generic metadata about a mod. + internal class ModInfoModel + { + /********* + ** Accessors + *********/ + /// The mod name. + public string Name { get; set; } + + /// The semantic version for the mod's latest release. + public string Version { get; set; } + + /// The semantic version for the mod's latest preview release, if available and different from . + public string PreviewVersion { get; set; } + + /// The mod's web URL. + public string Url { get; set; } + + /// The error message indicating why the mod is invalid (if applicable). + public string Error { get; set; } + + + /********* + ** Public methods + *********/ + /// Construct an empty instance. + public ModInfoModel() + { + // needed for JSON deserialising + } + + /// Construct an instance. + /// The mod name. + /// The semantic version for the mod's latest release. + /// The semantic version for the mod's latest preview release, if available and different from . + /// The mod's web URL. + /// The error message indicating why the mod is invalid (if applicable). + public ModInfoModel(string name, string version, string url, string previewVersion = null, string error = null) + { + this.Name = name; + this.Version = version; + this.PreviewVersion = previewVersion; + this.Url = url; + this.Error = error; // mainly initialised here for the JSON deserialiser + } + + /// Construct an instance. + /// The error message indicating why the mod is invalid. + public ModInfoModel(string error) + { + this.Error = error; + } + } +} diff --git a/src/SMAPI.Internal/Models/ModSeachModel.cs b/src/SMAPI.Internal/Models/ModSeachModel.cs new file mode 100644 index 00000000..fac72135 --- /dev/null +++ b/src/SMAPI.Internal/Models/ModSeachModel.cs @@ -0,0 +1,37 @@ +using System.Collections.Generic; +using System.Linq; + +namespace StardewModdingAPI.Internal.Models +{ + /// Specifies mods whose update-check info to fetch. + internal class ModSearchModel + { + /********* + ** Accessors + *********/ + /// The namespaced mod keys to search. + public string[] ModKeys { get; set; } + + /// Whether to allow non-semantic versions, instead of returning an error for those. + public bool AllowInvalidVersions { get; set; } + + + /********* + ** Public methods + *********/ + /// Construct an empty instance. + public ModSearchModel() + { + // needed for JSON deserialising + } + + /// Construct an instance. + /// The namespaced mod keys to search. + /// Whether to allow non-semantic versions, instead of returning an error for those. + public ModSearchModel(IEnumerable modKeys, bool allowInvalidVersions) + { + this.ModKeys = modKeys.ToArray(); + this.AllowInvalidVersions = allowInvalidVersions; + } + } +} diff --git a/src/SMAPI.Internal/Platform.cs b/src/SMAPI.Internal/Platform.cs new file mode 100644 index 00000000..81ca5c1f --- /dev/null +++ b/src/SMAPI.Internal/Platform.cs @@ -0,0 +1,15 @@ +namespace StardewModdingAPI.Internal +{ + /// The game's platform version. + internal enum Platform + { + /// The Linux version of the game. + Linux, + + /// The Mac version of the game. + Mac, + + /// The Windows version of the game. + Windows + } +} diff --git a/src/SMAPI.Internal/Properties/AssemblyInfo.cs b/src/SMAPI.Internal/Properties/AssemblyInfo.cs new file mode 100644 index 00000000..b314b353 --- /dev/null +++ b/src/SMAPI.Internal/Properties/AssemblyInfo.cs @@ -0,0 +1,9 @@ +using System.Reflection; +using System.Runtime.CompilerServices; + +[assembly: AssemblyTitle("SMAPI.Internal")] +[assembly: AssemblyDescription("Contains internal SMAPI code that's shared between its projects.")] +[assembly: InternalsVisibleTo("StardewModdingAPI")] +[assembly: InternalsVisibleTo("StardewModdingAPI.ModBuildConfig")] +[assembly: InternalsVisibleTo("StardewModdingAPI.Installer")] +[assembly: InternalsVisibleTo("StardewModdingAPI.Web")] diff --git a/src/SMAPI.Internal/RewriteFacades/SpriteBatchMethods.cs b/src/SMAPI.Internal/RewriteFacades/SpriteBatchMethods.cs new file mode 100644 index 00000000..5e5d117e --- /dev/null +++ b/src/SMAPI.Internal/RewriteFacades/SpriteBatchMethods.cs @@ -0,0 +1,59 @@ +using System.Diagnostics.CodeAnalysis; +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; + +namespace StardewModdingAPI.Internal.RewriteFacades +{ + /// Provides method signatures that can be injected into mod code for compatibility between Linux/Mac or Windows. + public class SpriteBatchMethods : SpriteBatch + { + /********* + ** Public methods + *********/ + /// Construct an instance. + public SpriteBatchMethods(GraphicsDevice graphicsDevice) : base(graphicsDevice) { } + + + /**** + ** MonoGame signatures + ****/ + [SuppressMessage("ReSharper", "CS0109", Justification = "The 'new' modifier applies when compiled on Linux/Mac.")] + public new void Begin(SpriteSortMode sortMode, BlendState blendState, SamplerState samplerState, DepthStencilState depthStencilState, RasterizerState rasterizerState, Effect effect, Matrix? matrix) + { + base.Begin(sortMode, blendState, samplerState, depthStencilState, rasterizerState, effect, matrix ?? Matrix.Identity); + } + + /**** + ** XNA signatures + ****/ + [SuppressMessage("ReSharper", "CS0109", Justification = "The 'new' modifier applies when compiled on Windows.")] + public new void Begin() + { + base.Begin(); + } + + [SuppressMessage("ReSharper", "CS0109", Justification = "The 'new' modifier applies when compiled on Windows.")] + public new void Begin(SpriteSortMode sortMode, BlendState blendState) + { + base.Begin(sortMode, blendState); + } + + [SuppressMessage("ReSharper", "CS0109", Justification = "The 'new' modifier applies when compiled on Windows.")] + public new void Begin(SpriteSortMode sortMode, BlendState blendState, SamplerState samplerState, DepthStencilState depthStencilState, RasterizerState rasterizerState) + { + base.Begin(sortMode, blendState, samplerState, depthStencilState, rasterizerState); + } + + [SuppressMessage("ReSharper", "CS0109", Justification = "The 'new' modifier applies when compiled on Windows.")] + public new void Begin(SpriteSortMode sortMode, BlendState blendState, SamplerState samplerState, DepthStencilState depthStencilState, RasterizerState rasterizerState, Effect effect) + { + base.Begin(sortMode, blendState, samplerState, depthStencilState, rasterizerState, effect); + } + + [SuppressMessage("ReSharper", "CS0109", Justification = "The 'new' modifier applies when compiled on Windows.")] + public new void Begin(SpriteSortMode sortMode, BlendState blendState, SamplerState samplerState, DepthStencilState depthStencilState, RasterizerState rasterizerState, Effect effect, Matrix transformMatrix) + { + base.Begin(sortMode, blendState, samplerState, depthStencilState, rasterizerState, effect, transformMatrix); + } + } +} diff --git a/src/SMAPI.Internal/SemanticVersionImpl.cs b/src/SMAPI.Internal/SemanticVersionImpl.cs new file mode 100644 index 00000000..6da16336 --- /dev/null +++ b/src/SMAPI.Internal/SemanticVersionImpl.cs @@ -0,0 +1,199 @@ +using System; +using System.Text.RegularExpressions; + +namespace StardewModdingAPI.Internal +{ + /// A low-level implementation of a semantic version with an optional release tag. + /// The implementation is defined by Semantic Version 2.0 (http://semver.org/). + internal class SemanticVersionImpl + { + /********* + ** Accessors + *********/ + /// The major version incremented for major API changes. + public int Major { get; } + + /// The minor version incremented for backwards-compatible changes. + public int Minor { get; } + + /// The patch version for backwards-compatible bug fixes. + public int Patch { get; } + + /// An optional prerelease tag. + public string Tag { get; } + + /// A regex pattern matching a version within a larger string. + internal const string UnboundedVersionPattern = @"(?>(?0|[1-9]\d*))\.(?>(?0|[1-9]\d*))(?>(?:\.(?0|[1-9]\d*))?)(?:-(?(?>[a-z0-9]+[\-\.]?)+))?"; + + /// A regular expression matching a semantic version string. + /// + /// This pattern is derived from the BNF documentation in the semver repo, + /// with three important deviations intended to support Stardew Valley mod conventions: + /// - allows short-form "x.y" versions; + /// - allows hyphens in prerelease tags as synonyms for dots (like "-unofficial-update.3"); + /// - doesn't allow '+build' suffixes. + /// + internal static readonly Regex Regex = new Regex($@"^{SemanticVersionImpl.UnboundedVersionPattern}$", RegexOptions.CultureInvariant | RegexOptions.IgnoreCase | RegexOptions.Compiled | RegexOptions.ExplicitCapture); + + /********* + ** Public methods + *********/ + /// Construct an instance. + /// The major version incremented for major API changes. + /// The minor version incremented for backwards-compatible changes. + /// The patch version for backwards-compatible bug fixes. + /// An optional prerelease tag. + public SemanticVersionImpl(int major, int minor, int patch, string tag = null) + { + this.Major = major; + this.Minor = minor; + this.Patch = patch; + this.Tag = this.GetNormalisedTag(tag); + } + + /// Construct an instance. + /// The assembly version. + /// The is null. + public SemanticVersionImpl(Version version) + { + if (version == null) + throw new ArgumentNullException(nameof(version), "The input version can't be null."); + + this.Major = version.Major; + this.Minor = version.Minor; + this.Patch = version.Build; + } + + /// Construct an instance. + /// The semantic version string. + /// The is null. + /// The is not a valid semantic version. + public SemanticVersionImpl(string version) + { + // parse + if (version == null) + throw new ArgumentNullException(nameof(version), "The input version string can't be null."); + var match = SemanticVersionImpl.Regex.Match(version.Trim()); + if (!match.Success) + throw new FormatException($"The input '{version}' isn't a valid semantic version."); + + // initialise + this.Major = int.Parse(match.Groups["major"].Value); + this.Minor = match.Groups["minor"].Success ? int.Parse(match.Groups["minor"].Value) : 0; + this.Patch = match.Groups["patch"].Success ? int.Parse(match.Groups["patch"].Value) : 0; + this.Tag = match.Groups["prerelease"].Success ? this.GetNormalisedTag(match.Groups["prerelease"].Value) : null; + } + + /// Get an integer indicating whether this version precedes (less than 0), supercedes (more than 0), or is equivalent to (0) the specified version. + /// The version to compare with this instance. + /// The value is null. + public int CompareTo(SemanticVersionImpl other) + { + if (other == null) + throw new ArgumentNullException(nameof(other)); + return this.CompareTo(other.Major, other.Minor, other.Patch, other.Tag); + } + + + /// Get an integer indicating whether this version precedes (less than 0), supercedes (more than 0), or is equivalent to (0) the specified version. + /// The major version to compare with this instance. + /// The minor version to compare with this instance. + /// The patch version to compare with this instance. + /// The prerelease tag to compare with this instance. + public int CompareTo(int otherMajor, int otherMinor, int otherPatch, string otherTag) + { + const int same = 0; + const int curNewer = 1; + const int curOlder = -1; + + // compare stable versions + if (this.Major != otherMajor) + return this.Major.CompareTo(otherMajor); + if (this.Minor != otherMinor) + return this.Minor.CompareTo(otherMinor); + if (this.Patch != otherPatch) + return this.Patch.CompareTo(otherPatch); + if (this.Tag == otherTag) + return same; + + // stable supercedes pre-release + bool curIsStable = string.IsNullOrWhiteSpace(this.Tag); + bool otherIsStable = string.IsNullOrWhiteSpace(otherTag); + if (curIsStable) + return curNewer; + if (otherIsStable) + return curOlder; + + // compare two pre-release tag values + string[] curParts = this.Tag.Split('.', '-'); + string[] otherParts = otherTag.Split('.', '-'); + for (int i = 0; i < curParts.Length; i++) + { + // longer prerelease tag supercedes if otherwise equal + if (otherParts.Length <= i) + return curNewer; + + // compare if different + if (curParts[i] != otherParts[i]) + { + // compare numerically if possible + { + if (int.TryParse(curParts[i], out int curNum) && int.TryParse(otherParts[i], out int otherNum)) + return curNum.CompareTo(otherNum); + } + + // else compare lexically + return string.Compare(curParts[i], otherParts[i], StringComparison.OrdinalIgnoreCase); + } + } + + // fallback (this should never happen) + return string.Compare(this.ToString(), new SemanticVersionImpl(otherMajor, otherMinor, otherPatch, otherTag).ToString(), StringComparison.InvariantCultureIgnoreCase); + } + + /// Get a string representation of the version. + public override string ToString() + { + // version + string result = this.Patch != 0 + ? $"{this.Major}.{this.Minor}.{this.Patch}" + : $"{this.Major}.{this.Minor}"; + + // tag + string tag = this.Tag; + if (tag != null) + result += $"-{tag}"; + return result; + } + + /// Parse a version string without throwing an exception if it fails. + /// The version string. + /// The parsed representation. + /// Returns whether parsing the version succeeded. + internal static bool TryParse(string version, out SemanticVersionImpl parsed) + { + try + { + parsed = new SemanticVersionImpl(version); + return true; + } + catch + { + parsed = null; + return false; + } + } + + + /********* + ** Private methods + *********/ + /// Get a normalised build tag. + /// The tag to normalise. + private string GetNormalisedTag(string tag) + { + tag = tag?.Trim(); + return !string.IsNullOrWhiteSpace(tag) ? tag : null; + } + } +} diff --git a/src/SMAPI.Internal/StardewModdingAPI.Internal.csproj b/src/SMAPI.Internal/StardewModdingAPI.Internal.csproj new file mode 100644 index 00000000..6e7fa368 --- /dev/null +++ b/src/SMAPI.Internal/StardewModdingAPI.Internal.csproj @@ -0,0 +1,49 @@ + + + + + Debug + x86 + {10DB0676-9FC1-4771-A2C8-E2519F091E49} + Library + Properties + StardewModdingAPI.Internal + StardewModdingAPI.Internal + v4.5 + 512 + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + + + + Properties\GlobalAssemblyInfo.cs + + + + + + + + + + + + \ No newline at end of file diff --git a/src/SMAPI.ModBuildConfig/Framework/ModFileManager.cs b/src/SMAPI.ModBuildConfig/Framework/ModFileManager.cs index 64262dc2..ba2e671d 100644 --- a/src/SMAPI.ModBuildConfig/Framework/ModFileManager.cs +++ b/src/SMAPI.ModBuildConfig/Framework/ModFileManager.cs @@ -3,7 +3,7 @@ using System.Collections.Generic; using System.IO; using System.Linq; using System.Web.Script.Serialization; -using StardewModdingAPI.Common; +using StardewModdingAPI.Internal; namespace StardewModdingAPI.ModBuildConfig.Framework { diff --git a/src/SMAPI.ModBuildConfig/StardewModdingAPI.ModBuildConfig.csproj b/src/SMAPI.ModBuildConfig/StardewModdingAPI.ModBuildConfig.csproj index 2e3ba356..02564409 100644 --- a/src/SMAPI.ModBuildConfig/StardewModdingAPI.ModBuildConfig.csproj +++ b/src/SMAPI.ModBuildConfig/StardewModdingAPI.ModBuildConfig.csproj @@ -55,7 +55,12 @@ - + + + {10db0676-9fc1-4771-a2c8-e2519f091e49} + StardewModdingAPI.Internal + + \ No newline at end of file diff --git a/src/SMAPI.Web/Controllers/IndexController.cs b/src/SMAPI.Web/Controllers/IndexController.cs index 0464e50a..92b4f2c0 100644 --- a/src/SMAPI.Web/Controllers/IndexController.cs +++ b/src/SMAPI.Web/Controllers/IndexController.cs @@ -3,7 +3,7 @@ using System.Text.RegularExpressions; using System.Threading.Tasks; using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Caching.Memory; -using StardewModdingAPI.Common; +using StardewModdingAPI.Internal; using StardewModdingAPI.Web.Framework.Clients.GitHub; using StardewModdingAPI.Web.ViewModels; diff --git a/src/SMAPI.Web/Controllers/ModsApiController.cs b/src/SMAPI.Web/Controllers/ModsApiController.cs index 24517263..fc90d067 100644 --- a/src/SMAPI.Web/Controllers/ModsApiController.cs +++ b/src/SMAPI.Web/Controllers/ModsApiController.cs @@ -6,7 +6,7 @@ using System.Threading.Tasks; using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Caching.Memory; using Microsoft.Extensions.Options; -using StardewModdingAPI.Common.Models; +using StardewModdingAPI.Internal.Models; using StardewModdingAPI.Web.Framework.Clients.Chucklefish; using StardewModdingAPI.Web.Framework.Clients.GitHub; using StardewModdingAPI.Web.Framework.Clients.Nexus; diff --git a/src/SMAPI.Web/Framework/LogParsing/LogParser.cs b/src/SMAPI.Web/Framework/LogParsing/LogParser.cs index f49fb05c..b5603bd9 100644 --- a/src/SMAPI.Web/Framework/LogParsing/LogParser.cs +++ b/src/SMAPI.Web/Framework/LogParsing/LogParser.cs @@ -3,7 +3,7 @@ using System.Collections.Generic; using System.IO; using System.Linq; using System.Text.RegularExpressions; -using StardewModdingAPI.Common; +using StardewModdingAPI.Internal; using StardewModdingAPI.Web.Framework.LogParsing.Models; namespace StardewModdingAPI.Web.Framework.LogParsing diff --git a/src/SMAPI.Web/Framework/ModRepositories/BaseRepository.cs b/src/SMAPI.Web/Framework/ModRepositories/BaseRepository.cs index edb00454..bd27d624 100644 --- a/src/SMAPI.Web/Framework/ModRepositories/BaseRepository.cs +++ b/src/SMAPI.Web/Framework/ModRepositories/BaseRepository.cs @@ -1,6 +1,6 @@ using System.Text.RegularExpressions; using System.Threading.Tasks; -using StardewModdingAPI.Common.Models; +using StardewModdingAPI.Internal.Models; namespace StardewModdingAPI.Web.Framework.ModRepositories { diff --git a/src/SMAPI.Web/Framework/ModRepositories/ChucklefishRepository.cs b/src/SMAPI.Web/Framework/ModRepositories/ChucklefishRepository.cs index 3e5a4272..2782e2b9 100644 --- a/src/SMAPI.Web/Framework/ModRepositories/ChucklefishRepository.cs +++ b/src/SMAPI.Web/Framework/ModRepositories/ChucklefishRepository.cs @@ -1,6 +1,6 @@ using System; using System.Threading.Tasks; -using StardewModdingAPI.Common.Models; +using StardewModdingAPI.Internal.Models; using StardewModdingAPI.Web.Framework.Clients.Chucklefish; namespace StardewModdingAPI.Web.Framework.ModRepositories diff --git a/src/SMAPI.Web/Framework/ModRepositories/GitHubRepository.cs b/src/SMAPI.Web/Framework/ModRepositories/GitHubRepository.cs index 59eb8cd1..b12b24e2 100644 --- a/src/SMAPI.Web/Framework/ModRepositories/GitHubRepository.cs +++ b/src/SMAPI.Web/Framework/ModRepositories/GitHubRepository.cs @@ -1,6 +1,6 @@ using System; using System.Threading.Tasks; -using StardewModdingAPI.Common.Models; +using StardewModdingAPI.Internal.Models; using StardewModdingAPI.Web.Framework.Clients.GitHub; namespace StardewModdingAPI.Web.Framework.ModRepositories diff --git a/src/SMAPI.Web/Framework/ModRepositories/IModRepository.cs b/src/SMAPI.Web/Framework/ModRepositories/IModRepository.cs index 4496400c..79fe8f87 100644 --- a/src/SMAPI.Web/Framework/ModRepositories/IModRepository.cs +++ b/src/SMAPI.Web/Framework/ModRepositories/IModRepository.cs @@ -1,6 +1,6 @@ using System; using System.Threading.Tasks; -using StardewModdingAPI.Common.Models; +using StardewModdingAPI.Internal.Models; namespace StardewModdingAPI.Web.Framework.ModRepositories { diff --git a/src/SMAPI.Web/Framework/ModRepositories/NexusRepository.cs b/src/SMAPI.Web/Framework/ModRepositories/NexusRepository.cs index 6411ad4c..87a87ab7 100644 --- a/src/SMAPI.Web/Framework/ModRepositories/NexusRepository.cs +++ b/src/SMAPI.Web/Framework/ModRepositories/NexusRepository.cs @@ -1,6 +1,6 @@ using System; using System.Threading.Tasks; -using StardewModdingAPI.Common.Models; +using StardewModdingAPI.Internal.Models; using StardewModdingAPI.Web.Framework.Clients.Nexus; namespace StardewModdingAPI.Web.Framework.ModRepositories diff --git a/src/SMAPI.Web/Framework/VersionConstraint.cs b/src/SMAPI.Web/Framework/VersionConstraint.cs index cffb1092..1502f5d8 100644 --- a/src/SMAPI.Web/Framework/VersionConstraint.cs +++ b/src/SMAPI.Web/Framework/VersionConstraint.cs @@ -1,5 +1,5 @@ using Microsoft.AspNetCore.Routing.Constraints; -using StardewModdingAPI.Common; +using StardewModdingAPI.Internal; namespace StardewModdingAPI.Web.Framework { diff --git a/src/SMAPI.Web/StardewModdingAPI.Web.csproj b/src/SMAPI.Web/StardewModdingAPI.Web.csproj index e2eee8a8..bc337e7e 100644 --- a/src/SMAPI.Web/StardewModdingAPI.Web.csproj +++ b/src/SMAPI.Web/StardewModdingAPI.Web.csproj @@ -22,6 +22,8 @@ - + + + diff --git a/src/SMAPI.sln b/src/SMAPI.sln index d84ce589..ff953751 100644 --- a/src/SMAPI.sln +++ b/src/SMAPI.sln @@ -24,7 +24,7 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StardewModdingAPI.Installer {F1A573B0-F436-472C-AE29-0B91EA6B9F8F} = {F1A573B0-F436-472C-AE29-0B91EA6B9F8F} EndProjectSection EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StardewModdingAPI.AssemblyRewriters", "SMAPI.AssemblyRewriters\StardewModdingAPI.AssemblyRewriters.csproj", "{10DB0676-9FC1-4771-A2C8-E2519F091E49}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StardewModdingAPI.Internal", "SMAPI.Internal\StardewModdingAPI.Internal.csproj", "{10DB0676-9FC1-4771-A2C8-E2519F091E49}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StardewModdingAPI.Tests", "SMAPI.Tests\StardewModdingAPI.Tests.csproj", "{36CCB19E-92EB-48C7-9615-98EEFD45109B}" EndProject @@ -32,8 +32,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "StardewModdingAPI.Web", "SM EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Internal", "Internal", "{82D22ED7-A0A7-4D64-8E92-4B6A5E74ED11}" EndProject -Project("{D954291E-2A0B-460D-934E-DC6B0785DB48}") = "StardewModdingAPI.Common", "SMAPI.Common\StardewModdingAPI.Common.shproj", "{2AA02FB6-FF03-41CF-A215-2EE60AB4F5DC}" -EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "docs", "docs", "{EB35A917-67B9-4EFA-8DFC-4FB49B3949BB}" ProjectSection(SolutionItems) = preProject ..\docs\CONTRIBUTING.md = ..\docs\CONTRIBUTING.md @@ -61,12 +59,6 @@ EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SMAPI.ModBuildConfig.Analyzer.Tests", "SMAPI.ModBuildConfig.Analyzer.Tests\SMAPI.ModBuildConfig.Analyzer.Tests.csproj", "{0CF97929-B0D0-4D73-B7BF-4FF7191035F9}" EndProject Global - GlobalSection(SharedMSBuildProjectFiles) = preSolution - SMAPI.Common\StardewModdingAPI.Common.projitems*{2aa02fb6-ff03-41cf-a215-2ee60ab4f5dc}*SharedItemsImports = 13 - SMAPI.Common\StardewModdingAPI.Common.projitems*{443ddf81-6aaf-420a-a610-3459f37e5575}*SharedItemsImports = 4 - SMAPI.Common\StardewModdingAPI.Common.projitems*{ea4f1e80-743f-4a1d-9757-ae66904a196a}*SharedItemsImports = 4 - SMAPI.Common\StardewModdingAPI.Common.projitems*{f1a573b0-f436-472c-ae29-0b91ea6b9f8f}*SharedItemsImports = 4 - EndGlobalSection GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU Debug|Mixed Platforms = Debug|Mixed Platforms @@ -177,9 +169,7 @@ Global HideSolutionNode = FALSE EndGlobalSection GlobalSection(NestedProjects) = preSolution - {10DB0676-9FC1-4771-A2C8-E2519F091E49} = {82D22ED7-A0A7-4D64-8E92-4B6A5E74ED11} {36CCB19E-92EB-48C7-9615-98EEFD45109B} = {82D22ED7-A0A7-4D64-8E92-4B6A5E74ED11} - {2AA02FB6-FF03-41CF-A215-2EE60AB4F5DC} = {82D22ED7-A0A7-4D64-8E92-4B6A5E74ED11} {EB35A917-67B9-4EFA-8DFC-4FB49B3949BB} = {86C452BE-D2D8-45B4-B63F-E329EB06CEDA} {09CF91E5-5BAB-4650-A200-E5EA9A633046} = {86C452BE-D2D8-45B4-B63F-E329EB06CEDA} {0CF97929-B0D0-4D73-B7BF-4FF7191035F9} = {82D22ED7-A0A7-4D64-8E92-4B6A5E74ED11} diff --git a/src/SMAPI/Constants.cs b/src/SMAPI/Constants.cs index 9f2ebdb2..0116ac42 100644 --- a/src/SMAPI/Constants.cs +++ b/src/SMAPI/Constants.cs @@ -3,9 +3,9 @@ using System.Collections.Generic; using System.IO; using System.Linq; using System.Reflection; -using StardewModdingAPI.Common; using StardewModdingAPI.Framework; using StardewModdingAPI.Framework.ModLoading; +using StardewModdingAPI.Internal; using StardewValley; namespace StardewModdingAPI diff --git a/src/SMAPI/Framework/Content/ContentCache.cs b/src/SMAPI/Framework/Content/ContentCache.cs index d95de4fe..8851fc7d 100644 --- a/src/SMAPI/Framework/Content/ContentCache.cs +++ b/src/SMAPI/Framework/Content/ContentCache.cs @@ -3,9 +3,9 @@ using System.Collections.Generic; using System.Diagnostics.Contracts; using System.Linq; using Microsoft.Xna.Framework; -using StardewModdingAPI.Common; using StardewModdingAPI.Framework.Reflection; using StardewModdingAPI.Framework.Utilities; +using StardewModdingAPI.Internal; using StardewValley; namespace StardewModdingAPI.Framework.Content diff --git a/src/SMAPI/Framework/ModLoading/AssemblyLoader.cs b/src/SMAPI/Framework/ModLoading/AssemblyLoader.cs index feaee047..6c0e1c14 100644 --- a/src/SMAPI/Framework/ModLoading/AssemblyLoader.cs +++ b/src/SMAPI/Framework/ModLoading/AssemblyLoader.cs @@ -5,8 +5,8 @@ using System.Linq; using System.Reflection; using Mono.Cecil; using Mono.Cecil.Cil; -using StardewModdingAPI.Common; using StardewModdingAPI.Framework.Exceptions; +using StardewModdingAPI.Internal; using StardewModdingAPI.Metadata; namespace StardewModdingAPI.Framework.ModLoading diff --git a/src/SMAPI/Framework/ModLoading/PlatformAssemblyMap.cs b/src/SMAPI/Framework/ModLoading/PlatformAssemblyMap.cs index 9499b538..f0a28b4a 100644 --- a/src/SMAPI/Framework/ModLoading/PlatformAssemblyMap.cs +++ b/src/SMAPI/Framework/ModLoading/PlatformAssemblyMap.cs @@ -2,7 +2,7 @@ using System.Collections.Generic; using System.Linq; using System.Reflection; using Mono.Cecil; -using StardewModdingAPI.Common; +using StardewModdingAPI.Internal; namespace StardewModdingAPI.Framework.ModLoading { diff --git a/src/SMAPI/Framework/Monitor.cs b/src/SMAPI/Framework/Monitor.cs index cc511ed4..73915824 100644 --- a/src/SMAPI/Framework/Monitor.cs +++ b/src/SMAPI/Framework/Monitor.cs @@ -2,9 +2,9 @@ using System; using System.Collections.Generic; using System.Linq; using System.Threading; -using StardewModdingAPI.Common; using StardewModdingAPI.Framework.Logging; using StardewModdingAPI.Framework.Models; +using StardewModdingAPI.Internal; namespace StardewModdingAPI.Framework { diff --git a/src/SMAPI/Framework/WebApiClient.cs b/src/SMAPI/Framework/WebApiClient.cs index 7f0122cf..e33b2681 100644 --- a/src/SMAPI/Framework/WebApiClient.cs +++ b/src/SMAPI/Framework/WebApiClient.cs @@ -2,7 +2,7 @@ using System; using System.Collections.Generic; using System.Net; using Newtonsoft.Json; -using StardewModdingAPI.Common.Models; +using StardewModdingAPI.Internal.Models; namespace StardewModdingAPI.Framework { diff --git a/src/SMAPI/Metadata/InstructionMetadata.cs b/src/SMAPI/Metadata/InstructionMetadata.cs index 0b532a18..c7abfbef 100644 --- a/src/SMAPI/Metadata/InstructionMetadata.cs +++ b/src/SMAPI/Metadata/InstructionMetadata.cs @@ -1,10 +1,10 @@ using System.Collections.Generic; using Microsoft.Xna.Framework.Graphics; -using StardewModdingAPI.AssemblyRewriters; using StardewModdingAPI.Events; using StardewModdingAPI.Framework.ModLoading; using StardewModdingAPI.Framework.ModLoading.Finders; using StardewModdingAPI.Framework.ModLoading.Rewriters; +using StardewModdingAPI.Internal.RewriteFacades; using StardewValley; namespace StardewModdingAPI.Metadata diff --git a/src/SMAPI/Program.cs b/src/SMAPI/Program.cs index acff0545..6b7c1ad3 100644 --- a/src/SMAPI/Program.cs +++ b/src/SMAPI/Program.cs @@ -14,8 +14,6 @@ using System.Threading; using System.Windows.Forms; #endif using Newtonsoft.Json; -using StardewModdingAPI.Common; -using StardewModdingAPI.Common.Models; using StardewModdingAPI.Events; using StardewModdingAPI.Framework; using StardewModdingAPI.Framework.Events; @@ -28,6 +26,8 @@ using StardewModdingAPI.Framework.ModLoading; using StardewModdingAPI.Framework.Reflection; using StardewModdingAPI.Framework.Serialisation; using StardewModdingAPI.Framework.Utilities; +using StardewModdingAPI.Internal; +using StardewModdingAPI.Internal.Models; using StardewValley; using Monitor = StardewModdingAPI.Framework.Monitor; using SObject = StardewValley.Object; diff --git a/src/SMAPI/SemanticVersion.cs b/src/SMAPI/SemanticVersion.cs index 4826c947..0f2a5cb0 100644 --- a/src/SMAPI/SemanticVersion.cs +++ b/src/SMAPI/SemanticVersion.cs @@ -1,6 +1,6 @@ using System; using Newtonsoft.Json; -using StardewModdingAPI.Common; +using StardewModdingAPI.Internal; namespace StardewModdingAPI { diff --git a/src/SMAPI/StardewModdingAPI.csproj b/src/SMAPI/StardewModdingAPI.csproj index e0125c9b..a06056f9 100644 --- a/src/SMAPI/StardewModdingAPI.csproj +++ b/src/SMAPI/StardewModdingAPI.csproj @@ -302,11 +302,10 @@ false - - + {10db0676-9fc1-4771-a2c8-e2519f091e49} - StardewModdingAPI.AssemblyRewriters + StardewModdingAPI.Internal -- cgit From b1a24452eef782332d699ef8193c01e0da8ffa01 Mon Sep 17 00:00:00 2001 From: Jesse Plamondon-Willard Date: Tue, 1 May 2018 19:15:56 -0400 Subject: add public platform constant for mods --- docs/release-notes.md | 1 + src/SMAPI/Constants.cs | 5 ++++- src/SMAPI/Framework/Content/ContentCache.cs | 2 +- src/SMAPI/Framework/Monitor.cs | 2 +- src/SMAPI/GamePlatform.cs | 17 +++++++++++++++++ src/SMAPI/Program.cs | 4 ++-- src/SMAPI/StardewModdingAPI.csproj | 1 + 7 files changed, 27 insertions(+), 5 deletions(-) create mode 100644 src/SMAPI/GamePlatform.cs (limited to 'src/SMAPI/Framework/Content') diff --git a/docs/release-notes.md b/docs/release-notes.md index 8064a34e..cde9cbc2 100644 --- a/docs/release-notes.md +++ b/docs/release-notes.md @@ -11,6 +11,7 @@ * For modders: * Added code analysis to mod build config package to flag common issues as warnings. * Added `Context.IsMultiplayer` and `Context.IsMainPlayer` flags. + * Added `Constants.TargetPlatform` which says whether the game is running on Linux, Mac, or Windows. * Fixed assets loaded by temporary content managers not being editable by mods. * Fixed assets not reloaded consistently when the player switches language. * Fixed console command input not saved to the log. diff --git a/src/SMAPI/Constants.cs b/src/SMAPI/Constants.cs index 0116ac42..2ef26704 100644 --- a/src/SMAPI/Constants.cs +++ b/src/SMAPI/Constants.cs @@ -46,6 +46,9 @@ namespace StardewModdingAPI /// The maximum supported version of Stardew Valley. public static ISemanticVersion MaximumGameVersion { get; } = null; + /// The target game platform. + public static GamePlatform TargetPlatform => (GamePlatform)Constants.Platform; + /// The path to the game folder. public static string ExecutionPath { get; } = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location); @@ -92,7 +95,7 @@ namespace StardewModdingAPI internal static ISemanticVersion GameVersion { get; } = new GameVersion(Constants.GetGameVersion()); /// The target game platform. - internal static Platform TargetPlatform { get; } = EnvironmentUtility.DetectPlatform(); + internal static Platform Platform { get; } = EnvironmentUtility.DetectPlatform(); /********* diff --git a/src/SMAPI/Framework/Content/ContentCache.cs b/src/SMAPI/Framework/Content/ContentCache.cs index 8851fc7d..c2818cdd 100644 --- a/src/SMAPI/Framework/Content/ContentCache.cs +++ b/src/SMAPI/Framework/Content/ContentCache.cs @@ -53,7 +53,7 @@ namespace StardewModdingAPI.Framework.Content this.Cache = reflection.GetField>(contentManager, "loadedAssets").GetValue(); // get key normalisation logic - if (Constants.TargetPlatform == Platform.Windows) + if (Constants.Platform == Platform.Windows) { IReflectedMethod method = reflection.GetMethod(typeof(TitleContainer), "GetCleanPath"); this.NormaliseAssetNameForPlatform = path => method.Invoke(path); diff --git a/src/SMAPI/Framework/Monitor.cs b/src/SMAPI/Framework/Monitor.cs index 73915824..8df2e59b 100644 --- a/src/SMAPI/Framework/Monitor.cs +++ b/src/SMAPI/Framework/Monitor.cs @@ -167,7 +167,7 @@ namespace StardewModdingAPI.Framework // auto detect color scheme if (colorScheme == MonitorColorScheme.AutoDetect) { - if (Constants.TargetPlatform == Platform.Mac) + if (Constants.Platform == Platform.Mac) colorScheme = MonitorColorScheme.LightBackground; // MacOS doesn't provide console background color info, but it's usually white. else colorScheme = Monitor.IsDark(Console.BackgroundColor) ? MonitorColorScheme.DarkBackground : MonitorColorScheme.LightBackground; diff --git a/src/SMAPI/GamePlatform.cs b/src/SMAPI/GamePlatform.cs new file mode 100644 index 00000000..3bd74462 --- /dev/null +++ b/src/SMAPI/GamePlatform.cs @@ -0,0 +1,17 @@ +using StardewModdingAPI.Internal; + +namespace StardewModdingAPI +{ + /// The game's platform version. + public enum GamePlatform + { + /// The Linux version of the game. + Linux = Platform.Linux, + + /// The Mac version of the game. + Mac = Platform.Mac, + + /// The Windows version of the game. + Windows = Platform.Windows + } +} diff --git a/src/SMAPI/Program.cs b/src/SMAPI/Program.cs index 6b7c1ad3..ba3e238d 100644 --- a/src/SMAPI/Program.cs +++ b/src/SMAPI/Program.cs @@ -172,7 +172,7 @@ namespace StardewModdingAPI try { // init logging - this.Monitor.Log($"SMAPI {Constants.ApiVersion} with Stardew Valley {Constants.GameVersion} on {EnvironmentUtility.GetFriendlyPlatformName(Constants.TargetPlatform)}", LogLevel.Info); + this.Monitor.Log($"SMAPI {Constants.ApiVersion} with Stardew Valley {Constants.GameVersion} on {EnvironmentUtility.GetFriendlyPlatformName(Constants.Platform)}", LogLevel.Info); this.Monitor.Log($"Mods go here: {Constants.ModPath}"); this.Monitor.Log($"Log started at {DateTime.UtcNow:s} UTC", LogLevel.Trace); @@ -741,7 +741,7 @@ namespace StardewModdingAPI ); // get assembly loaders - AssemblyLoader modAssemblyLoader = new AssemblyLoader(Constants.TargetPlatform, this.Monitor, this.Settings.DeveloperMode); + AssemblyLoader modAssemblyLoader = new AssemblyLoader(Constants.Platform, this.Monitor, this.Settings.DeveloperMode); AppDomain.CurrentDomain.AssemblyResolve += (sender, e) => modAssemblyLoader.ResolveAssembly(e.Name); InterfaceProxyFactory proxyFactory = new InterfaceProxyFactory(); diff --git a/src/SMAPI/StardewModdingAPI.csproj b/src/SMAPI/StardewModdingAPI.csproj index a06056f9..31bfd6fd 100644 --- a/src/SMAPI/StardewModdingAPI.csproj +++ b/src/SMAPI/StardewModdingAPI.csproj @@ -262,6 +262,7 @@ + -- cgit From 93274deb4aba6eb60b5471a81819eb92e23de30b Mon Sep 17 00:00:00 2001 From: Jesse Plamondon-Willard Date: Thu, 24 May 2018 18:15:02 -0400 Subject: minor fixes --- src/SMAPI/Framework/Content/AssetDataForImage.cs | 6 +++--- src/SMAPI/IAssetDataForImage.cs | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) (limited to 'src/SMAPI/Framework/Content') diff --git a/src/SMAPI/Framework/Content/AssetDataForImage.cs b/src/SMAPI/Framework/Content/AssetDataForImage.cs index 1eef2afb..5c7b87de 100644 --- a/src/SMAPI/Framework/Content/AssetDataForImage.cs +++ b/src/SMAPI/Framework/Content/AssetDataForImage.cs @@ -4,7 +4,7 @@ using Microsoft.Xna.Framework.Graphics; namespace StardewModdingAPI.Framework.Content { - /// Encapsulates access and changes to dictionary content being read from a data file. + /// Encapsulates access and changes to image content being read from a data file. internal class AssetDataForImage : AssetData, IAssetDataForImage { /********* @@ -29,6 +29,8 @@ namespace StardewModdingAPI.Framework.Content public void PatchImage(Texture2D source, Rectangle? sourceArea = null, Rectangle? targetArea = null, PatchMode patchMode = PatchMode.Replace) { // get texture + if (source == null) + throw new ArgumentNullException(nameof(source), "Can't patch from a null source texture."); Texture2D target = this.Data; // get areas @@ -36,8 +38,6 @@ namespace StardewModdingAPI.Framework.Content targetArea = targetArea ?? new Rectangle(0, 0, Math.Min(sourceArea.Value.Width, target.Width), Math.Min(sourceArea.Value.Height, target.Height)); // validate - if (source == null) - throw new ArgumentNullException(nameof(source), "Can't patch from a null source texture."); if (sourceArea.Value.X < 0 || sourceArea.Value.Y < 0 || sourceArea.Value.Right > source.Width || sourceArea.Value.Bottom > source.Height) throw new ArgumentOutOfRangeException(nameof(sourceArea), "The source area is outside the bounds of the source texture."); if (targetArea.Value.X < 0 || targetArea.Value.Y < 0 || targetArea.Value.Right > target.Width || targetArea.Value.Bottom > target.Height) diff --git a/src/SMAPI/IAssetDataForImage.cs b/src/SMAPI/IAssetDataForImage.cs index 4584a20e..1109194f 100644 --- a/src/SMAPI/IAssetDataForImage.cs +++ b/src/SMAPI/IAssetDataForImage.cs @@ -1,10 +1,10 @@ -using System; +using System; using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; namespace StardewModdingAPI { - /// Encapsulates access and changes to dictionary content being read from a data file. + /// Encapsulates access and changes to image content being read from a data file. public interface IAssetDataForImage : IAssetData { /********* -- cgit From 69b17f1db87d9aeb5dd6d6f9c81ac9ac62f2a6d3 Mon Sep 17 00:00:00 2001 From: Jesse Plamondon-Willard Date: Fri, 25 May 2018 02:06:28 -0400 Subject: move PathUtilities into toolkit (#532) --- src/SMAPI.Tests/Core/PathUtilitiesTests.cs | 70 ---------------------- src/SMAPI.Tests/StardewModdingAPI.Tests.csproj | 8 ++- src/SMAPI.Tests/Toolkit/PathUtilitiesTests.cs | 70 ++++++++++++++++++++++ src/SMAPI/Framework/Content/ContentCache.cs | 2 +- src/SMAPI/Framework/ContentCoordinator.cs | 3 +- src/SMAPI/Framework/ContentPack.cs | 2 +- src/SMAPI/Framework/ModHelpers/ContentHelper.cs | 2 +- src/SMAPI/Framework/ModHelpers/ModHelper.cs | 10 ++-- src/SMAPI/Framework/ModLoading/ModResolver.cs | 2 +- src/SMAPI/Framework/Utilities/PathUtilities.cs | 65 -------------------- src/SMAPI/Program.cs | 2 +- src/SMAPI/StardewModdingAPI.csproj | 1 - .../Utilities/PathUtilities.cs | 65 ++++++++++++++++++++ 13 files changed, 152 insertions(+), 150 deletions(-) delete mode 100644 src/SMAPI.Tests/Core/PathUtilitiesTests.cs create mode 100644 src/SMAPI.Tests/Toolkit/PathUtilitiesTests.cs delete mode 100644 src/SMAPI/Framework/Utilities/PathUtilities.cs create mode 100644 src/StardewModdingAPI.Toolkit/Utilities/PathUtilities.cs (limited to 'src/SMAPI/Framework/Content') diff --git a/src/SMAPI.Tests/Core/PathUtilitiesTests.cs b/src/SMAPI.Tests/Core/PathUtilitiesTests.cs deleted file mode 100644 index 268ba504..00000000 --- a/src/SMAPI.Tests/Core/PathUtilitiesTests.cs +++ /dev/null @@ -1,70 +0,0 @@ -using NUnit.Framework; -using StardewModdingAPI.Framework.Utilities; - -namespace StardewModdingAPI.Tests.Core -{ - /// Unit tests for . - [TestFixture] - public class PathUtilitiesTests - { - /********* - ** Unit tests - *********/ - [Test(Description = "Assert that GetSegments returns the expected values.")] - [TestCase("", ExpectedResult = "")] - [TestCase("/", ExpectedResult = "")] - [TestCase("///", ExpectedResult = "")] - [TestCase("/usr/bin", ExpectedResult = "usr|bin")] - [TestCase("/usr//bin//", ExpectedResult = "usr|bin")] - [TestCase("/usr//bin//.././boop.exe", ExpectedResult = "usr|bin|..|.|boop.exe")] - [TestCase(@"C:", ExpectedResult = "C:")] - [TestCase(@"C:/boop", ExpectedResult = "C:|boop")] - [TestCase(@"C:\boop\/usr//bin//.././boop.exe", ExpectedResult = "C:|boop|usr|bin|..|.|boop.exe")] - public string GetSegments(string path) - { - return string.Join("|", PathUtilities.GetSegments(path)); - } - - [Test(Description = "Assert that NormalisePathSeparators returns the expected values.")] -#if SMAPI_FOR_WINDOWS - [TestCase("", ExpectedResult = "")] - [TestCase("/", ExpectedResult = "")] - [TestCase("///", ExpectedResult = "")] - [TestCase("/usr/bin", ExpectedResult = @"usr\bin")] - [TestCase("/usr//bin//", ExpectedResult = @"usr\bin")] - [TestCase("/usr//bin//.././boop.exe", ExpectedResult = @"usr\bin\..\.\boop.exe")] - [TestCase("C:", ExpectedResult = "C:")] - [TestCase("C:/boop", ExpectedResult = @"C:\boop")] - [TestCase(@"C:\usr\bin//.././boop.exe", ExpectedResult = @"C:\usr\bin\..\.\boop.exe")] -#else - [TestCase("", ExpectedResult = "")] - [TestCase("/", ExpectedResult = "/")] - [TestCase("///", ExpectedResult = "/")] - [TestCase("/usr/bin", ExpectedResult = "/usr/bin")] - [TestCase("/usr//bin//", ExpectedResult = "/usr/bin")] - [TestCase("/usr//bin//.././boop.exe", ExpectedResult = "/usr/bin/.././boop.exe")] - [TestCase("C:", ExpectedResult = "C:")] - [TestCase("C:/boop", ExpectedResult = "C:/boop")] - [TestCase(@"C:\usr\bin//.././boop.exe", ExpectedResult = "C:/usr/bin/.././boop.exe")] -#endif - public string NormalisePathSeparators(string path) - { - return PathUtilities.NormalisePathSeparators(path); - } - - [Test(Description = "Assert that GetRelativePath returns the expected values.")] -#if SMAPI_FOR_WINDOWS - [TestCase(@"C:\", @"C:\", ExpectedResult = "./")] - [TestCase(@"C:\grandparent\parent\child", @"C:\grandparent\parent\sibling", ExpectedResult = @"..\sibling")] - [TestCase(@"C:\grandparent\parent\child", @"C:\cousin\file.exe", ExpectedResult = @"..\..\..\cousin\file.exe")] -#else - [TestCase("/", "/", ExpectedResult = "./")] - [TestCase("/grandparent/parent/child", "/grandparent/parent/sibling", ExpectedResult = "../sibling")] - [TestCase("/grandparent/parent/child", "/cousin/file.exe", ExpectedResult = "../../../cousin/file.exe")] -#endif - public string GetRelativePath(string sourceDir, string targetPath) - { - return PathUtilities.GetRelativePath(sourceDir, targetPath); - } - } -} diff --git a/src/SMAPI.Tests/StardewModdingAPI.Tests.csproj b/src/SMAPI.Tests/StardewModdingAPI.Tests.csproj index f4d7b3e3..04c8d12f 100644 --- a/src/SMAPI.Tests/StardewModdingAPI.Tests.csproj +++ b/src/SMAPI.Tests/StardewModdingAPI.Tests.csproj @@ -1,4 +1,4 @@ - + @@ -56,7 +56,7 @@ Properties\GlobalAssemblyInfo.cs - + @@ -73,6 +73,10 @@ {f1a573b0-f436-472c-ae29-0b91ea6b9f8f} StardewModdingAPI + + {ea5cfd2e-9453-4d29-b80f-8e0ea23f4ac6} + StardewModdingAPI.Toolkit + diff --git a/src/SMAPI.Tests/Toolkit/PathUtilitiesTests.cs b/src/SMAPI.Tests/Toolkit/PathUtilitiesTests.cs new file mode 100644 index 00000000..229b9a14 --- /dev/null +++ b/src/SMAPI.Tests/Toolkit/PathUtilitiesTests.cs @@ -0,0 +1,70 @@ +using NUnit.Framework; +using StardewModdingAPI.Toolkit.Utilities; + +namespace StardewModdingAPI.Tests.Toolkit +{ + /// Unit tests for . + [TestFixture] + public class PathUtilitiesTests + { + /********* + ** Unit tests + *********/ + [Test(Description = "Assert that GetSegments returns the expected values.")] + [TestCase("", ExpectedResult = "")] + [TestCase("/", ExpectedResult = "")] + [TestCase("///", ExpectedResult = "")] + [TestCase("/usr/bin", ExpectedResult = "usr|bin")] + [TestCase("/usr//bin//", ExpectedResult = "usr|bin")] + [TestCase("/usr//bin//.././boop.exe", ExpectedResult = "usr|bin|..|.|boop.exe")] + [TestCase(@"C:", ExpectedResult = "C:")] + [TestCase(@"C:/boop", ExpectedResult = "C:|boop")] + [TestCase(@"C:\boop\/usr//bin//.././boop.exe", ExpectedResult = "C:|boop|usr|bin|..|.|boop.exe")] + public string GetSegments(string path) + { + return string.Join("|", PathUtilities.GetSegments(path)); + } + + [Test(Description = "Assert that NormalisePathSeparators returns the expected values.")] +#if SMAPI_FOR_WINDOWS + [TestCase("", ExpectedResult = "")] + [TestCase("/", ExpectedResult = "")] + [TestCase("///", ExpectedResult = "")] + [TestCase("/usr/bin", ExpectedResult = @"usr\bin")] + [TestCase("/usr//bin//", ExpectedResult = @"usr\bin")] + [TestCase("/usr//bin//.././boop.exe", ExpectedResult = @"usr\bin\..\.\boop.exe")] + [TestCase("C:", ExpectedResult = "C:")] + [TestCase("C:/boop", ExpectedResult = @"C:\boop")] + [TestCase(@"C:\usr\bin//.././boop.exe", ExpectedResult = @"C:\usr\bin\..\.\boop.exe")] +#else + [TestCase("", ExpectedResult = "")] + [TestCase("/", ExpectedResult = "/")] + [TestCase("///", ExpectedResult = "/")] + [TestCase("/usr/bin", ExpectedResult = "/usr/bin")] + [TestCase("/usr//bin//", ExpectedResult = "/usr/bin")] + [TestCase("/usr//bin//.././boop.exe", ExpectedResult = "/usr/bin/.././boop.exe")] + [TestCase("C:", ExpectedResult = "C:")] + [TestCase("C:/boop", ExpectedResult = "C:/boop")] + [TestCase(@"C:\usr\bin//.././boop.exe", ExpectedResult = "C:/usr/bin/.././boop.exe")] +#endif + public string NormalisePathSeparators(string path) + { + return PathUtilities.NormalisePathSeparators(path); + } + + [Test(Description = "Assert that GetRelativePath returns the expected values.")] +#if SMAPI_FOR_WINDOWS + [TestCase(@"C:\", @"C:\", ExpectedResult = "./")] + [TestCase(@"C:\grandparent\parent\child", @"C:\grandparent\parent\sibling", ExpectedResult = @"..\sibling")] + [TestCase(@"C:\grandparent\parent\child", @"C:\cousin\file.exe", ExpectedResult = @"..\..\..\cousin\file.exe")] +#else + [TestCase("/", "/", ExpectedResult = "./")] + [TestCase("/grandparent/parent/child", "/grandparent/parent/sibling", ExpectedResult = "../sibling")] + [TestCase("/grandparent/parent/child", "/cousin/file.exe", ExpectedResult = "../../../cousin/file.exe")] +#endif + public string GetRelativePath(string sourceDir, string targetPath) + { + return PathUtilities.GetRelativePath(sourceDir, targetPath); + } + } +} diff --git a/src/SMAPI/Framework/Content/ContentCache.cs b/src/SMAPI/Framework/Content/ContentCache.cs index c2818cdd..a5dfac9d 100644 --- a/src/SMAPI/Framework/Content/ContentCache.cs +++ b/src/SMAPI/Framework/Content/ContentCache.cs @@ -4,8 +4,8 @@ using System.Diagnostics.Contracts; using System.Linq; using Microsoft.Xna.Framework; using StardewModdingAPI.Framework.Reflection; -using StardewModdingAPI.Framework.Utilities; using StardewModdingAPI.Internal; +using StardewModdingAPI.Toolkit.Utilities; using StardewValley; namespace StardewModdingAPI.Framework.Content diff --git a/src/SMAPI/Framework/ContentCoordinator.cs b/src/SMAPI/Framework/ContentCoordinator.cs index c2614001..1a57dd22 100644 --- a/src/SMAPI/Framework/ContentCoordinator.cs +++ b/src/SMAPI/Framework/ContentCoordinator.cs @@ -9,10 +9,9 @@ using Microsoft.Xna.Framework.Graphics; using StardewModdingAPI.Framework.Content; using StardewModdingAPI.Framework.ContentManagers; using StardewModdingAPI.Framework.Reflection; -using StardewModdingAPI.Framework.Utilities; using StardewModdingAPI.Metadata; +using StardewModdingAPI.Toolkit.Utilities; using StardewValley; -using xTile; namespace StardewModdingAPI.Framework { diff --git a/src/SMAPI/Framework/ContentPack.cs b/src/SMAPI/Framework/ContentPack.cs index 071fb872..ee6df1ec 100644 --- a/src/SMAPI/Framework/ContentPack.cs +++ b/src/SMAPI/Framework/ContentPack.cs @@ -3,7 +3,7 @@ using System.IO; using Microsoft.Xna.Framework.Content; using Microsoft.Xna.Framework.Graphics; using StardewModdingAPI.Framework.Serialisation; -using StardewModdingAPI.Framework.Utilities; +using StardewModdingAPI.Toolkit.Utilities; using xTile; namespace StardewModdingAPI.Framework diff --git a/src/SMAPI/Framework/ModHelpers/ContentHelper.cs b/src/SMAPI/Framework/ModHelpers/ContentHelper.cs index ce26c980..671dc21e 100644 --- a/src/SMAPI/Framework/ModHelpers/ContentHelper.cs +++ b/src/SMAPI/Framework/ModHelpers/ContentHelper.cs @@ -9,7 +9,7 @@ using Microsoft.Xna.Framework.Content; using Microsoft.Xna.Framework.Graphics; using StardewModdingAPI.Framework.ContentManagers; using StardewModdingAPI.Framework.Exceptions; -using StardewModdingAPI.Framework.Utilities; +using StardewModdingAPI.Toolkit.Utilities; using StardewValley; using xTile; using xTile.Format; diff --git a/src/SMAPI/Framework/ModHelpers/ModHelper.cs b/src/SMAPI/Framework/ModHelpers/ModHelper.cs index 26fe7198..61d2075c 100644 --- a/src/SMAPI/Framework/ModHelpers/ModHelper.cs +++ b/src/SMAPI/Framework/ModHelpers/ModHelper.cs @@ -4,7 +4,7 @@ using System.IO; using System.Linq; using StardewModdingAPI.Framework.Models; using StardewModdingAPI.Framework.Serialisation; -using StardewModdingAPI.Framework.Utilities; +using StardewModdingAPI.Toolkit.Utilities; namespace StardewModdingAPI.Framework.ModHelpers { @@ -157,13 +157,13 @@ namespace StardewModdingAPI.Framework.ModHelpers this.DeprecationManager.Warn($"{nameof(IModHelper)}.{nameof(IModHelper.CreateTransitionalContentPack)}", "2.5", DeprecationLevel.Notice); // validate - if(string.IsNullOrWhiteSpace(directoryPath)) + if (string.IsNullOrWhiteSpace(directoryPath)) throw new ArgumentNullException(nameof(directoryPath)); - if(string.IsNullOrWhiteSpace(id)) + if (string.IsNullOrWhiteSpace(id)) throw new ArgumentNullException(nameof(id)); - if(string.IsNullOrWhiteSpace(name)) + if (string.IsNullOrWhiteSpace(name)) throw new ArgumentNullException(nameof(name)); - if(!Directory.Exists(directoryPath)) + if (!Directory.Exists(directoryPath)) throw new ArgumentException($"Can't create content pack for directory path '{directoryPath}' because no such directory exists."); // create manifest diff --git a/src/SMAPI/Framework/ModLoading/ModResolver.cs b/src/SMAPI/Framework/ModLoading/ModResolver.cs index b5339183..d46caa55 100644 --- a/src/SMAPI/Framework/ModLoading/ModResolver.cs +++ b/src/SMAPI/Framework/ModLoading/ModResolver.cs @@ -7,7 +7,7 @@ using StardewModdingAPI.Framework.Exceptions; using StardewModdingAPI.Framework.ModData; using StardewModdingAPI.Framework.Models; using StardewModdingAPI.Framework.Serialisation; -using StardewModdingAPI.Framework.Utilities; +using StardewModdingAPI.Toolkit.Utilities; namespace StardewModdingAPI.Framework.ModLoading { diff --git a/src/SMAPI/Framework/Utilities/PathUtilities.cs b/src/SMAPI/Framework/Utilities/PathUtilities.cs deleted file mode 100644 index 51d45ebd..00000000 --- a/src/SMAPI/Framework/Utilities/PathUtilities.cs +++ /dev/null @@ -1,65 +0,0 @@ -using System; -using System.Diagnostics.Contracts; -using System.IO; -using System.Linq; - -namespace StardewModdingAPI.Framework.Utilities -{ - /// Provides utilities for normalising file paths. - internal static class PathUtilities - { - /********* - ** Properties - *********/ - /// The possible directory separator characters in a file path. - private static readonly char[] PossiblePathSeparators = new[] { '/', '\\', Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar }.Distinct().ToArray(); - - /// The preferred directory separator chaeacter in an asset key. - private static readonly string PreferredPathSeparator = Path.DirectorySeparatorChar.ToString(); - - - /********* - ** Public methods - *********/ - /// Get the segments from a path (e.g. /usr/bin/boop => usr, bin, and boop). - /// The path to split. - /// The number of segments to match. Any additional segments will be merged into the last returned part. - public static string[] GetSegments(string path, int? limit = null) - { - return limit.HasValue - ? path.Split(PathUtilities.PossiblePathSeparators, limit.Value, StringSplitOptions.RemoveEmptyEntries) - : path.Split(PathUtilities.PossiblePathSeparators, StringSplitOptions.RemoveEmptyEntries); - } - - /// Normalise path separators in a file path. - /// The file path to normalise. - [Pure] - public static string NormalisePathSeparators(string path) - { - string[] parts = PathUtilities.GetSegments(path); - string normalised = string.Join(PathUtilities.PreferredPathSeparator, parts); - if (path.StartsWith(PathUtilities.PreferredPathSeparator)) - normalised = PathUtilities.PreferredPathSeparator + normalised; // keep root slash - return normalised; - } - - /// Get a directory or file path relative to a given source path. - /// The source folder path. - /// The target folder or file path. - [Pure] - public static string GetRelativePath(string sourceDir, string targetPath) - { - // convert to URIs - Uri from = new Uri(sourceDir.TrimEnd(PathUtilities.PossiblePathSeparators) + "/"); - Uri to = new Uri(targetPath.TrimEnd(PathUtilities.PossiblePathSeparators) + "/"); - if (from.Scheme != to.Scheme) - 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())); - if (relative == "") - relative = "./"; - return relative; - } - } -} diff --git a/src/SMAPI/Program.cs b/src/SMAPI/Program.cs index aeb9b9fb..a1cfcf0c 100644 --- a/src/SMAPI/Program.cs +++ b/src/SMAPI/Program.cs @@ -25,9 +25,9 @@ using StardewModdingAPI.Framework.ModHelpers; using StardewModdingAPI.Framework.ModLoading; using StardewModdingAPI.Framework.Reflection; using StardewModdingAPI.Framework.Serialisation; -using StardewModdingAPI.Framework.Utilities; using StardewModdingAPI.Internal; using StardewModdingAPI.Internal.Models; +using StardewModdingAPI.Toolkit.Utilities; using StardewValley; using Monitor = StardewModdingAPI.Framework.Monitor; using SObject = StardewValley.Object; diff --git a/src/SMAPI/StardewModdingAPI.csproj b/src/SMAPI/StardewModdingAPI.csproj index 926bcbbc..3e6fdb24 100644 --- a/src/SMAPI/StardewModdingAPI.csproj +++ b/src/SMAPI/StardewModdingAPI.csproj @@ -157,7 +157,6 @@ - diff --git a/src/StardewModdingAPI.Toolkit/Utilities/PathUtilities.cs b/src/StardewModdingAPI.Toolkit/Utilities/PathUtilities.cs new file mode 100644 index 00000000..2e74e7d9 --- /dev/null +++ b/src/StardewModdingAPI.Toolkit/Utilities/PathUtilities.cs @@ -0,0 +1,65 @@ +using System; +using System.Diagnostics.Contracts; +using System.IO; +using System.Linq; + +namespace StardewModdingAPI.Toolkit.Utilities +{ + /// Provides utilities for normalising file paths. + public static class PathUtilities + { + /********* + ** Properties + *********/ + /// The possible directory separator characters in a file path. + private static readonly char[] PossiblePathSeparators = new[] { '/', '\\', Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar }.Distinct().ToArray(); + + /// The preferred directory separator chaeacter in an asset key. + private static readonly string PreferredPathSeparator = Path.DirectorySeparatorChar.ToString(); + + + /********* + ** Public methods + *********/ + /// Get the segments from a path (e.g. /usr/bin/boop => usr, bin, and boop). + /// The path to split. + /// The number of segments to match. Any additional segments will be merged into the last returned part. + public static string[] GetSegments(string path, int? limit = null) + { + return limit.HasValue + ? path.Split(PathUtilities.PossiblePathSeparators, limit.Value, StringSplitOptions.RemoveEmptyEntries) + : path.Split(PathUtilities.PossiblePathSeparators, StringSplitOptions.RemoveEmptyEntries); + } + + /// Normalise path separators in a file path. + /// The file path to normalise. + [Pure] + public static string NormalisePathSeparators(string path) + { + string[] parts = PathUtilities.GetSegments(path); + string normalised = string.Join(PathUtilities.PreferredPathSeparator, parts); + if (path.StartsWith(PathUtilities.PreferredPathSeparator)) + normalised = PathUtilities.PreferredPathSeparator + normalised; // keep root slash + return normalised; + } + + /// Get a directory or file path relative to a given source path. + /// The source folder path. + /// The target folder or file path. + [Pure] + public static string GetRelativePath(string sourceDir, string targetPath) + { + // convert to URIs + Uri from = new Uri(sourceDir.TrimEnd(PathUtilities.PossiblePathSeparators) + "/"); + Uri to = new Uri(targetPath.TrimEnd(PathUtilities.PossiblePathSeparators) + "/"); + if (from.Scheme != to.Scheme) + 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())); + if (relative == "") + relative = "./"; + return relative; + } + } +} -- cgit