Files
OpenRA/OpenRA.Game/Platform.cs
RoosterDragon 9cd55df584 Ensure editorconfig naming styles align with StyleCop SA13XX style rules.
Aligns the naming conventions defined in editorconfig (dotnet_naming_style, dotnet_naming_symbols, dotnet_naming_rule) which are reported under the IDE1006 rule with the existing StyleCop rules from the SA13XX range.

This ensures the two rulesets agree when rejecting and accepting naming conventions within the IDE, with a few edges cases where only one ruleset can enforce the convention. IDE1006 allows use to specify a naming convention for type parameters, const locals and protected readonly fields which SA13XX cannot enforce. Some StyleCop SA13XX rules such as SA1309 'Field names should not begin with underscore' are not possible to enforce with the naming rules of IDE1006.

Therefore we enable the IDE1006 as a build time warning to enforce conventions and extend them. We disable SA13XX rules that can now be covered by IDE1006 to avoid double-reporting but leave the remaining SA13XX rules that cover additional cases enabled.

We also re-enable the SA1311 rule convention but enforce it via IDE1006, requiring some violations to be fixed or duplication of existing suppressions. Most violations fixes are trivial renames with the following exception. In ActorInitializer.cs, we prefer to make the fields private instead. ValueActorInit provides a publicly accessible property for access and OwnerInit provides a publicly accessible method. Health.cs is adjusted to access the property base instead when overriding. The reflection calls must be adjusted to target the base class specifically, as searching for a private field from the derived class will fail to locate it on the base class.

Unused suppressions were removed.
2022-02-07 19:14:45 +01:00

257 lines
8.0 KiB
C#

#region Copyright & License Information
/*
* Copyright 2007-2021 The OpenRA Developers (see AUTHORS)
* This file is part of OpenRA, which is free software. It is made
* available to you under the terms of the GNU General Public License
* as published by the Free Software Foundation, either version 3 of
* the License, or (at your option) any later version. For more
* information, see COPYING.
*/
#endregion
using System;
using System.Diagnostics;
using System.IO;
using System.Reflection;
namespace OpenRA
{
public enum PlatformType { Unknown, Windows, OSX, Linux }
public enum SupportDirType { System, ModernUser, LegacyUser, User }
public static class Platform
{
public static PlatformType CurrentPlatform => LazyCurrentPlatform.Value;
public static readonly Guid SessionGUID = Guid.NewGuid();
static readonly Lazy<PlatformType> LazyCurrentPlatform = Exts.Lazy(GetCurrentPlatform);
static bool engineDirAccessed;
static string engineDir;
static bool supportDirInitialized;
static string systemSupportPath;
static string legacyUserSupportPath;
static string modernUserSupportPath;
static string userSupportPath;
static PlatformType GetCurrentPlatform()
{
if (Environment.OSVersion.Platform == PlatformID.Win32NT)
return PlatformType.Windows;
try
{
var psi = new ProcessStartInfo("uname", "-s")
{
UseShellExecute = false,
RedirectStandardOutput = true
};
var p = Process.Start(psi);
var kernelName = p.StandardOutput.ReadToEnd();
if (kernelName.Contains("Darwin"))
return PlatformType.OSX;
return PlatformType.Linux;
}
catch { }
return PlatformType.Unknown;
}
public static string RuntimeVersion
{
get
{
var mono = Type.GetType("Mono.Runtime");
if (mono == null)
return $".NET CLR {Environment.Version}";
var version = mono.GetMethod("GetDisplayName", BindingFlags.NonPublic | BindingFlags.Static);
if (version == null)
return $"Mono (unknown version) CLR {Environment.Version}";
return $"Mono {version.Invoke(null, null)} CLR {Environment.Version}";
}
}
/// <summary>
/// Directory containing user-specific support files (settings, maps, replays, game data, etc).
/// </summary>
public static string SupportDir => GetSupportDir(SupportDirType.User);
public static string GetSupportDir(SupportDirType type)
{
if (!supportDirInitialized)
InitializeSupportDir();
switch (type)
{
case SupportDirType.System: return systemSupportPath;
case SupportDirType.LegacyUser: return legacyUserSupportPath;
case SupportDirType.ModernUser: return modernUserSupportPath;
default: return userSupportPath;
}
}
static void InitializeSupportDir()
{
// The preferred support dir location for Windows and Linux was changed in mid 2019 to match modern platform conventions
switch (CurrentPlatform)
{
case PlatformType.Windows:
{
modernUserSupportPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "OpenRA") + Path.DirectorySeparatorChar;
legacyUserSupportPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Personal), "OpenRA") + Path.DirectorySeparatorChar;
systemSupportPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData), "OpenRA") + Path.DirectorySeparatorChar;
break;
}
case PlatformType.OSX:
{
modernUserSupportPath = legacyUserSupportPath = Path.Combine(
Environment.GetFolderPath(Environment.SpecialFolder.Personal),
"Library", "Application Support", "OpenRA") + Path.DirectorySeparatorChar;
systemSupportPath = "/Library/Application Support/OpenRA/";
break;
}
case PlatformType.Linux:
{
legacyUserSupportPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Personal), ".openra") + Path.DirectorySeparatorChar;
var xdgConfigHome = Environment.GetEnvironmentVariable("XDG_CONFIG_HOME");
if (string.IsNullOrEmpty(xdgConfigHome))
xdgConfigHome = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Personal), ".config") + Path.DirectorySeparatorChar;
modernUserSupportPath = Path.Combine(xdgConfigHome, "openra") + Path.DirectorySeparatorChar;
systemSupportPath = "/var/games/openra/";
break;
}
default:
{
modernUserSupportPath = legacyUserSupportPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Personal), ".openra") + Path.DirectorySeparatorChar;
systemSupportPath = "/var/games/openra/";
break;
}
}
// Use a local directory in the game root if it exists (shared with the system support dir)
var localSupportDir = Path.Combine(EngineDir, "Support") + Path.DirectorySeparatorChar;
if (Directory.Exists(localSupportDir))
userSupportPath = systemSupportPath = localSupportDir;
// Use the fallback directory if it exists and the preferred one does not
else if (!Directory.Exists(modernUserSupportPath) && Directory.Exists(legacyUserSupportPath))
userSupportPath = legacyUserSupportPath;
else
userSupportPath = modernUserSupportPath;
supportDirInitialized = true;
}
/// <summary>
/// Specify a custom support directory that already exists on the filesystem.
/// Cannot be called after Platform.SupportDir / GetSupportDir have been accessed.
/// </summary>
public static void OverrideSupportDir(string path)
{
if (supportDirInitialized)
throw new InvalidOperationException("Attempted to override user support directory after it has already been accessed.");
if (!Directory.Exists(path))
throw new DirectoryNotFoundException(path);
if (!path.EndsWith(Path.DirectorySeparatorChar.ToString(), StringComparison.Ordinal) &&
!path.EndsWith(Path.AltDirectorySeparatorChar.ToString(), StringComparison.Ordinal))
path += Path.DirectorySeparatorChar;
InitializeSupportDir();
userSupportPath = path;
}
public static string EngineDir
{
get
{
// Engine directory defaults to the location of the binaries,
// unless OverrideGameDir is called during startup.
if (!engineDirAccessed)
engineDir = BinDir;
engineDirAccessed = true;
return engineDir;
}
}
/// <summary>
/// Specify a custom engine directory that already exists on the filesystem.
/// Cannot be called after Platform.EngineDir has been accessed.
/// </summary>
public static void OverrideEngineDir(string path)
{
if (engineDirAccessed)
throw new InvalidOperationException("Attempted to override engine directory after it has already been accessed.");
// Note: Relative paths are interpreted as being relative to BinDir, not the current working dir.
if (!Path.IsPathRooted(path))
path = Path.Combine(BinDir, path);
if (!Directory.Exists(path))
throw new DirectoryNotFoundException(path);
if (!path.EndsWith(Path.DirectorySeparatorChar.ToString(), StringComparison.Ordinal) &&
!path.EndsWith(Path.AltDirectorySeparatorChar.ToString(), StringComparison.Ordinal))
path += Path.DirectorySeparatorChar;
engineDirAccessed = true;
engineDir = path;
}
public static string BinDir
{
get
{
var dir = AppDomain.CurrentDomain.BaseDirectory;
// Add trailing DirectorySeparator for some buggy AppPool hosts
if (!dir.EndsWith(Path.DirectorySeparatorChar.ToString(), StringComparison.Ordinal))
dir += Path.DirectorySeparatorChar;
return dir;
}
}
/// <summary>Replaces special character prefixes with full paths.</summary>
public static string ResolvePath(string path)
{
path = path.TrimEnd(' ', '\t');
if (path == "^SupportDir")
return SupportDir;
if (path == "^EngineDir")
return EngineDir;
if (path == "^BinDir")
return BinDir;
if (path.StartsWith("^SupportDir|", StringComparison.Ordinal))
path = SupportDir + path.Substring(12);
if (path.StartsWith("^EngineDir|", StringComparison.Ordinal))
path = EngineDir + path.Substring(11);
if (path.StartsWith("^BinDir|", StringComparison.Ordinal))
path = BinDir + path.Substring(8);
return path;
}
}
}