diff options
author | Jesse Plamondon-Willard <github@jplamondonw.com> | 2018-08-01 11:07:29 -0400 |
---|---|---|
committer | Jesse Plamondon-Willard <github@jplamondonw.com> | 2018-08-01 11:07:29 -0400 |
commit | 60b41195778af33fd609eab66d9ae3f1d1165e8f (patch) | |
tree | 7128b906d40e94c56c34ed6058f27bc31c31a08b /src/SMAPI.Internal | |
parent | b9bc1a6d17cafa0a97b46ffecda432cfc2f23b51 (diff) | |
parent | 52cf953f685c65b2b6814e375ec9a5ffa03c440a (diff) | |
download | SMAPI-60b41195778af33fd609eab66d9ae3f1d1165e8f.tar.gz SMAPI-60b41195778af33fd609eab66d9ae3f1d1165e8f.tar.bz2 SMAPI-60b41195778af33fd609eab66d9ae3f1d1165e8f.zip |
Merge branch 'develop' into stable
Diffstat (limited to 'src/SMAPI.Internal')
-rw-r--r-- | src/SMAPI.Internal/ConsoleWriting/ColorfulConsoleWriter.cs | 138 | ||||
-rw-r--r-- | src/SMAPI.Internal/ConsoleWriting/LogLevel.cs | 30 | ||||
-rw-r--r-- | src/SMAPI.Internal/ConsoleWriting/MonitorColorScheme.cs | 15 | ||||
-rw-r--r-- | src/SMAPI.Internal/EnvironmentUtility.cs | 112 | ||||
-rw-r--r-- | src/SMAPI.Internal/Platform.cs | 15 | ||||
-rw-r--r-- | src/SMAPI.Internal/SMAPI.Internal.projitems | 18 | ||||
-rw-r--r-- | src/SMAPI.Internal/StardewModdingAPI.Internal.shproj | 13 |
7 files changed, 341 insertions, 0 deletions
diff --git a/src/SMAPI.Internal/ConsoleWriting/ColorfulConsoleWriter.cs b/src/SMAPI.Internal/ConsoleWriting/ColorfulConsoleWriter.cs new file mode 100644 index 00000000..c04cf0e7 --- /dev/null +++ b/src/SMAPI.Internal/ConsoleWriting/ColorfulConsoleWriter.cs @@ -0,0 +1,138 @@ +using System; +using System.Collections.Generic; + +namespace StardewModdingAPI.Internal.ConsoleWriting +{ + /// <summary>Provides a wrapper for writing color-coded text to the console.</summary> + internal class ColorfulConsoleWriter + { + /********* + ** Properties + *********/ + /// <summary>The console text color for each log level.</summary> + private readonly IDictionary<ConsoleLogLevel, ConsoleColor> Colors; + + /// <summary>Whether the current console supports color formatting.</summary> + private readonly bool SupportsColor; + + + /********* + ** Public methods + *********/ + /// <summary>Construct an instance.</summary> + /// <param name="platform">The target platform.</param> + /// <param name="colorScheme">The console color scheme to use.</param> + public ColorfulConsoleWriter(Platform platform, MonitorColorScheme colorScheme) + { + this.SupportsColor = this.TestColorSupport(); + this.Colors = this.GetConsoleColorScheme(platform, colorScheme); + } + + /// <summary>Write a message line to the log.</summary> + /// <param name="message">The message to log.</param> + /// <param name="level">The log level.</param> + public void WriteLine(string message, ConsoleLogLevel level) + { + if (this.SupportsColor) + { + if (level == ConsoleLogLevel.Critical) + { + Console.BackgroundColor = ConsoleColor.Red; + Console.ForegroundColor = ConsoleColor.White; + Console.WriteLine(message); + Console.ResetColor(); + } + else + { + Console.ForegroundColor = this.Colors[level]; + Console.WriteLine(message); + Console.ResetColor(); + } + } + else + Console.WriteLine(message); + } + + + /********* + ** Private methods + *********/ + /// <summary>Test whether the current console supports color formatting.</summary> + private bool TestColorSupport() + { + try + { + Console.ForegroundColor = Console.ForegroundColor; + return true; + } + catch (Exception) + { + return false; // Mono bug + } + } + + /// <summary>Get the color scheme to use for the current console.</summary> + /// <param name="platform">The target platform.</param> + /// <param name="colorScheme">The console color scheme to use.</param> + private IDictionary<ConsoleLogLevel, ConsoleColor> GetConsoleColorScheme(Platform platform, MonitorColorScheme colorScheme) + { + // auto detect color scheme + if (colorScheme == MonitorColorScheme.AutoDetect) + { + colorScheme = platform == Platform.Mac + ? MonitorColorScheme.LightBackground // MacOS doesn't provide console background color info, but it's usually white. + : ColorfulConsoleWriter.IsDark(Console.BackgroundColor) ? MonitorColorScheme.DarkBackground : MonitorColorScheme.LightBackground; + } + + // get colors for scheme + switch (colorScheme) + { + case MonitorColorScheme.DarkBackground: + return new Dictionary<ConsoleLogLevel, ConsoleColor> + { + [ConsoleLogLevel.Trace] = ConsoleColor.DarkGray, + [ConsoleLogLevel.Debug] = ConsoleColor.DarkGray, + [ConsoleLogLevel.Info] = ConsoleColor.White, + [ConsoleLogLevel.Warn] = ConsoleColor.Yellow, + [ConsoleLogLevel.Error] = ConsoleColor.Red, + [ConsoleLogLevel.Alert] = ConsoleColor.Magenta, + [ConsoleLogLevel.Success] = ConsoleColor.DarkGreen + }; + + case MonitorColorScheme.LightBackground: + return new Dictionary<ConsoleLogLevel, ConsoleColor> + { + [ConsoleLogLevel.Trace] = ConsoleColor.DarkGray, + [ConsoleLogLevel.Debug] = ConsoleColor.DarkGray, + [ConsoleLogLevel.Info] = ConsoleColor.Black, + [ConsoleLogLevel.Warn] = ConsoleColor.DarkYellow, + [ConsoleLogLevel.Error] = ConsoleColor.Red, + [ConsoleLogLevel.Alert] = ConsoleColor.DarkMagenta, + [ConsoleLogLevel.Success] = ConsoleColor.DarkGreen + }; + + default: + throw new NotSupportedException($"Unknown color scheme '{colorScheme}'."); + } + } + + /// <summary>Get whether a console color should be considered dark, which is subjectively defined as 'white looks better than black on this text'.</summary> + /// <param name="color">The color to check.</param> + private static bool IsDark(ConsoleColor color) + { + switch (color) + { + case ConsoleColor.Black: + case ConsoleColor.Blue: + case ConsoleColor.DarkBlue: + case ConsoleColor.DarkMagenta: // Powershell + case ConsoleColor.DarkRed: + case ConsoleColor.Red: + return true; + + default: + return false; + } + } + } +} diff --git a/src/SMAPI.Internal/ConsoleWriting/LogLevel.cs b/src/SMAPI.Internal/ConsoleWriting/LogLevel.cs new file mode 100644 index 00000000..54564111 --- /dev/null +++ b/src/SMAPI.Internal/ConsoleWriting/LogLevel.cs @@ -0,0 +1,30 @@ +namespace StardewModdingAPI.Internal.ConsoleWriting +{ + /// <summary>The log severity levels.</summary> + internal enum ConsoleLogLevel + { + /// <summary>Tracing info intended for developers.</summary> + Trace, + + /// <summary>Troubleshooting info that may be relevant to the player.</summary> + Debug, + + /// <summary>Info relevant to the player. This should be used judiciously.</summary> + Info, + + /// <summary>An issue the player should be aware of. This should be used rarely.</summary> + Warn, + + /// <summary>A message indicating something went wrong.</summary> + Error, + + /// <summary>Important information to highlight for the player when player action is needed (e.g. new version available). This should be used rarely to avoid alert fatigue.</summary> + Alert, + + /// <summary>A critical issue that generally signals an immediate end to the application.</summary> + Critical, + + /// <summary>A success message that generally signals a successful end to a task.</summary> + Success + } +} diff --git a/src/SMAPI.Internal/ConsoleWriting/MonitorColorScheme.cs b/src/SMAPI.Internal/ConsoleWriting/MonitorColorScheme.cs new file mode 100644 index 00000000..bccb56d7 --- /dev/null +++ b/src/SMAPI.Internal/ConsoleWriting/MonitorColorScheme.cs @@ -0,0 +1,15 @@ +namespace StardewModdingAPI.Internal.ConsoleWriting +{ + /// <summary>A monitor color scheme to use.</summary> + internal enum MonitorColorScheme + { + /// <summary>Choose a color scheme automatically.</summary> + AutoDetect, + + /// <summary>Use lighter text colors that look better on a black or dark background.</summary> + DarkBackground, + + /// <summary>Use darker text colors that look better on a white or light background.</summary> + LightBackground + } +} 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 +{ + /// <summary>Provides methods for fetching environment information.</summary> + internal static class EnvironmentUtility + { + /********* + ** Properties + *********/ + /// <summary>Get the OS name from the system uname command.</summary> + /// <param name="buffer">The buffer to fill with the resulting string.</param> + [DllImport("libc")] + static extern int uname(IntPtr buffer); + + + /********* + ** Public methods + *********/ + /// <summary>Detect the current OS.</summary> + 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; + } + } + + + /// <summary>Get the human-readable OS name and version.</summary> + /// <param name="platform">The current platform.</param> + [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<ManagementObject>() + .Select(entry => entry.GetPropertyValue("Caption").ToString()) + .FirstOrDefault(); + } + catch { } +#endif + return (platform == Platform.Mac ? "MacOS " : "") + Environment.OSVersion; + } + + /// <summary>Get the name of the Stardew Valley executable.</summary> + /// <param name="platform">The current platform.</param> + public static string GetExecutableName(Platform platform) + { + return platform == Platform.Windows + ? "Stardew Valley.exe" + : "StardewValley.exe"; + } + + /// <summary>Get whether the platform uses Mono.</summary> + /// <param name="platform">The current platform.</param> + public static bool IsMono(this Platform platform) + { + return platform == Platform.Linux || platform == Platform.Mac; + } + + /********* + ** Private methods + *********/ + /// <summary>Detect whether the code is running on Mac.</summary> + /// <remarks> + /// This code is derived from the Mono project (see System.Windows.Forms/System.Windows.Forms/XplatUI.cs). It detects Mac by calling the + /// <c>uname</c> system command and checking the response, which is always 'Darwin' for MacOS. + /// </remarks> + 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/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 +{ + /// <summary>The game's platform version.</summary> + internal enum Platform + { + /// <summary>The Linux version of the game.</summary> + Linux, + + /// <summary>The Mac version of the game.</summary> + Mac, + + /// <summary>The Windows version of the game.</summary> + Windows + } +} diff --git a/src/SMAPI.Internal/SMAPI.Internal.projitems b/src/SMAPI.Internal/SMAPI.Internal.projitems new file mode 100644 index 00000000..54b12003 --- /dev/null +++ b/src/SMAPI.Internal/SMAPI.Internal.projitems @@ -0,0 +1,18 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <PropertyGroup> + <MSBuildAllProjects>$(MSBuildAllProjects);$(MSBuildThisFileFullPath)</MSBuildAllProjects> + <HasSharedItems>true</HasSharedItems> + <SharedGUID>85208f8d-6fd1-4531-be05-7142490f59fe</SharedGUID> + </PropertyGroup> + <PropertyGroup Label="Configuration"> + <Import_RootNamespace>SMAPI.Internal</Import_RootNamespace> + </PropertyGroup> + <ItemGroup> + <Compile Include="$(MSBuildThisFileDirectory)ConsoleWriting\ColorfulConsoleWriter.cs" /> + <Compile Include="$(MSBuildThisFileDirectory)EnvironmentUtility.cs" /> + <Compile Include="$(MSBuildThisFileDirectory)ConsoleWriting\LogLevel.cs" /> + <Compile Include="$(MSBuildThisFileDirectory)ConsoleWriting\MonitorColorScheme.cs" /> + <Compile Include="$(MSBuildThisFileDirectory)Platform.cs" /> + </ItemGroup> +</Project>
\ No newline at end of file diff --git a/src/SMAPI.Internal/StardewModdingAPI.Internal.shproj b/src/SMAPI.Internal/StardewModdingAPI.Internal.shproj new file mode 100644 index 00000000..a098828a --- /dev/null +++ b/src/SMAPI.Internal/StardewModdingAPI.Internal.shproj @@ -0,0 +1,13 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <PropertyGroup Label="Globals"> + <ProjectGuid>85208f8d-6fd1-4531-be05-7142490f59fe</ProjectGuid> + <MinimumVisualStudioVersion>14.0</MinimumVisualStudioVersion> + </PropertyGroup> + <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" /> + <Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\CodeSharing\Microsoft.CodeSharing.Common.Default.props" /> + <Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\CodeSharing\Microsoft.CodeSharing.Common.props" /> + <PropertyGroup /> + <Import Project="SMAPI.Internal.projitems" Label="Shared" /> + <Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\CodeSharing\Microsoft.CodeSharing.CSharp.targets" /> +</Project> |