mirror of
https://github.com/space-wizards/RobustToolbox.git
synced 2026-02-15 03:30:53 +01:00
192 lines
6.0 KiB
C#
192 lines
6.0 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Diagnostics;
|
|
using System.IO;
|
|
using System.Threading;
|
|
using Robust.Shared.Utility;
|
|
|
|
namespace Robust.Shared.ContentPack
|
|
{
|
|
/// <inheritdoc />
|
|
internal sealed class WritableDirProvider : IWritableDirProvider
|
|
{
|
|
private readonly bool _hideRootDir;
|
|
|
|
public string RootDir { get; }
|
|
|
|
string? IWritableDirProvider.RootDir => _hideRootDir ? null : RootDir;
|
|
|
|
/// <summary>
|
|
/// Constructs an instance of <see cref="WritableDirProvider"/>.
|
|
/// </summary>
|
|
/// <param name="rootDir">Root file system directory to allow writing.</param>
|
|
/// <param name="hideRootDir">If true, <see cref="IWritableDirProvider.RootDir"/> is reported as null.</param>
|
|
public WritableDirProvider(DirectoryInfo rootDir, bool hideRootDir)
|
|
{
|
|
// FullName does not have a trailing separator, and we MUST have a separator.
|
|
RootDir = rootDir.FullName + Path.DirectorySeparatorChar.ToString();
|
|
_hideRootDir = hideRootDir;
|
|
}
|
|
|
|
#region File Access
|
|
|
|
/// <inheritdoc />
|
|
public void CreateDir(ResPath path)
|
|
{
|
|
var fullPath = GetFullPath(path);
|
|
Directory.CreateDirectory(fullPath);
|
|
}
|
|
|
|
/// <inheritdoc />
|
|
public void Delete(ResPath path)
|
|
{
|
|
var fullPath = GetFullPath(path);
|
|
if (Directory.Exists(fullPath))
|
|
{
|
|
Directory.Delete(fullPath, true);
|
|
}
|
|
else if (File.Exists(fullPath))
|
|
{
|
|
File.Delete(fullPath);
|
|
}
|
|
}
|
|
|
|
/// <inheritdoc />
|
|
public bool Exists(ResPath path)
|
|
{
|
|
var fullPath = GetFullPath(path);
|
|
return Directory.Exists(fullPath) || File.Exists(fullPath);
|
|
}
|
|
|
|
/// <inheritdoc />
|
|
public (IEnumerable<ResPath> files, IEnumerable<ResPath> directories) Find(string pattern, bool recursive = true)
|
|
{
|
|
if (pattern.Contains(".."))
|
|
throw new InvalidOperationException($"Pattern may not contain '..'. Pattern: {pattern}.");
|
|
|
|
var rootLen = RootDir.Length - 1;
|
|
var option = recursive ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly;
|
|
|
|
var files = Directory.GetFiles(RootDir, pattern, option);
|
|
var dirs = Directory.GetDirectories(RootDir, pattern, option);
|
|
|
|
var resFiles = new List<ResPath>(files.Length);
|
|
var resDirs = new List<ResPath>(dirs.Length);
|
|
|
|
foreach (var file in files)
|
|
{
|
|
if (file.Contains("\\..") || file.Contains("/.."))
|
|
continue;
|
|
|
|
resFiles.Add(ResPath.FromRelativeSystemPath(file.Substring(rootLen)).ToRootedPath());
|
|
}
|
|
|
|
foreach (var dir in dirs)
|
|
{
|
|
if (dir.Contains("\\..") || dir.Contains("/.."))
|
|
continue;
|
|
|
|
resDirs.Add(ResPath.FromRelativeSystemPath(dir.Substring(rootLen)).ToRootedPath());
|
|
}
|
|
|
|
return (resFiles, resDirs);
|
|
}
|
|
|
|
public IEnumerable<string> DirectoryEntries(ResPath path)
|
|
{
|
|
var fullPath = GetFullPath(path);
|
|
|
|
if (!Directory.Exists(fullPath))
|
|
yield break;
|
|
|
|
foreach (var entry in Directory.EnumerateFileSystemEntries(fullPath))
|
|
{
|
|
yield return Path.GetRelativePath(fullPath, entry);
|
|
}
|
|
}
|
|
|
|
/// <inheritdoc />
|
|
public bool IsDir(ResPath path)
|
|
{
|
|
return Directory.Exists(GetFullPath(path));
|
|
}
|
|
|
|
/// <inheritdoc />
|
|
public Stream Open(ResPath path, FileMode fileMode, FileAccess access, FileShare share)
|
|
{
|
|
var fullPath = GetFullPath(path);
|
|
return File.Open(fullPath, fileMode, access, share);
|
|
}
|
|
|
|
public IWritableDirProvider OpenSubdirectory(ResPath path)
|
|
{
|
|
if (!IsDir(path))
|
|
throw new FileNotFoundException();
|
|
|
|
var dirInfo = new DirectoryInfo(GetFullPath(path));
|
|
return new WritableDirProvider(dirInfo, _hideRootDir);
|
|
}
|
|
|
|
/// <inheritdoc />
|
|
public void Rename(ResPath oldPath, ResPath newPath)
|
|
{
|
|
var fullOldPath = GetFullPath(oldPath);
|
|
var fullNewPath = GetFullPath(newPath);
|
|
File.Move(fullOldPath, fullNewPath);
|
|
}
|
|
|
|
public void OpenOsWindow(ResPath path)
|
|
{
|
|
if (!IsDir(path))
|
|
path = path.Directory;
|
|
|
|
var fullPath = GetFullPath(path);
|
|
if (OperatingSystem.IsWindows())
|
|
{
|
|
Process.Start(new ProcessStartInfo
|
|
{
|
|
FileName = $"{Environment.GetEnvironmentVariable("SystemRoot")}\\explorer.exe",
|
|
Arguments = ".",
|
|
WorkingDirectory = fullPath,
|
|
});
|
|
}
|
|
else if (OperatingSystem.IsMacOS())
|
|
{
|
|
Process.Start(new ProcessStartInfo
|
|
{
|
|
FileName = "open",
|
|
Arguments = ".",
|
|
WorkingDirectory = fullPath,
|
|
});
|
|
}
|
|
else if (OperatingSystem.IsLinux() || OperatingSystem.IsFreeBSD())
|
|
{
|
|
Process.Start(new ProcessStartInfo
|
|
{
|
|
FileName = "xdg-open",
|
|
Arguments = ".",
|
|
WorkingDirectory = fullPath,
|
|
});
|
|
}
|
|
else
|
|
{
|
|
throw new NotSupportedException("Opening OS windows not supported on this OS");
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
|
|
public string GetFullPath(ResPath path)
|
|
{
|
|
if (!path.IsRooted)
|
|
{
|
|
throw new ArgumentException($"Path must be rooted. Path: {path}");
|
|
}
|
|
|
|
path = path.Clean();
|
|
|
|
return PathHelpers.SafeGetResourcePath(RootDir, path);
|
|
}
|
|
}
|
|
}
|