升级
This commit is contained in:
parent
1e8889aecc
commit
411204b1ac
@ -38,7 +38,7 @@ namespace HashCalculator.GUI
|
|||||||
{
|
{
|
||||||
if (element == null)
|
if (element == null)
|
||||||
{
|
{
|
||||||
throw new ArgumentNullException($"{nameof(element)} is null");
|
throw new ArgumentNullException(nameof(element));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (element.Name.Namespace != ModXml.EalaAsset)
|
if (element.Name.Namespace != ModXml.EalaAsset)
|
||||||
@ -62,7 +62,7 @@ namespace HashCalculator.GUI
|
|||||||
{
|
{
|
||||||
if (asset is null)
|
if (asset is null)
|
||||||
{
|
{
|
||||||
throw new ArgumentNullException($"{nameof(asset)} is null");
|
throw new ArgumentNullException(nameof(asset));
|
||||||
}
|
}
|
||||||
Type = asset.TypeName;
|
Type = asset.TypeName;
|
||||||
Name = asset.InstanceName;
|
Name = asset.InstanceName;
|
||||||
@ -74,13 +74,13 @@ namespace HashCalculator.GUI
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool Equals(AssetEntry entry)
|
public bool Equals(AssetEntry? entry)
|
||||||
{
|
{
|
||||||
return this == entry;
|
return this == entry;
|
||||||
}
|
}
|
||||||
|
|
||||||
// override object.Equals
|
// override object.Equals
|
||||||
public override bool Equals(object obj)
|
public override bool Equals(object? obj)
|
||||||
{
|
{
|
||||||
//
|
//
|
||||||
// See the full list of guidelines at
|
// See the full list of guidelines at
|
||||||
@ -97,7 +97,7 @@ namespace HashCalculator.GUI
|
|||||||
return this == entry;
|
return this == entry;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static bool operator ==(AssetEntry a, AssetEntry b)
|
public static bool operator ==(AssetEntry? a, AssetEntry? b)
|
||||||
{
|
{
|
||||||
if (a is null || b is null)
|
if (a is null || b is null)
|
||||||
{
|
{
|
||||||
@ -112,7 +112,7 @@ namespace HashCalculator.GUI
|
|||||||
return a.Type == b.Type && a.InstanceId == b.InstanceId;
|
return a.Type == b.Type && a.InstanceId == b.InstanceId;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static bool operator !=(AssetEntry a, AssetEntry b)
|
public static bool operator !=(AssetEntry? a, AssetEntry? b)
|
||||||
{
|
{
|
||||||
return !(a == b);
|
return !(a == b);
|
||||||
}
|
}
|
||||||
@ -123,31 +123,31 @@ namespace HashCalculator.GUI
|
|||||||
return HashCode.Combine(Type, InstanceId);
|
return HashCode.Combine(Type, InstanceId);
|
||||||
}
|
}
|
||||||
|
|
||||||
public int CompareTo(AssetEntry other)
|
public int CompareTo(AssetEntry? other)
|
||||||
{
|
{
|
||||||
if (other is null)
|
if (other is null)
|
||||||
{
|
{
|
||||||
throw new ArgumentNullException($"{nameof(other)} is null");
|
throw new ArgumentNullException(nameof(other));
|
||||||
}
|
}
|
||||||
return string.CompareOrdinal(NameString, other.NameString);
|
return string.CompareOrdinal(NameString, other.NameString);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static bool operator <(AssetEntry left, AssetEntry right)
|
public static bool operator <(AssetEntry? left, AssetEntry? right)
|
||||||
{
|
{
|
||||||
return left is null ? right is object : left.CompareTo(right) < 0;
|
return left is null ? right is object : left.CompareTo(right) < 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static bool operator <=(AssetEntry left, AssetEntry right)
|
public static bool operator <=(AssetEntry? left, AssetEntry? right)
|
||||||
{
|
{
|
||||||
return left is null || left.CompareTo(right) <= 0;
|
return left is null || left.CompareTo(right) <= 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static bool operator >(AssetEntry left, AssetEntry right)
|
public static bool operator >(AssetEntry? left, AssetEntry? right)
|
||||||
{
|
{
|
||||||
return left is object && left.CompareTo(right) > 0;
|
return left is object && left.CompareTo(right) > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static bool operator >=(AssetEntry left, AssetEntry right)
|
public static bool operator >=(AssetEntry? left, AssetEntry? right)
|
||||||
{
|
{
|
||||||
return left is null ? right is null : left.CompareTo(right) >= 0;
|
return left is null ? right is null : left.CompareTo(right) >= 0;
|
||||||
}
|
}
|
||||||
|
10
Command.cs
10
Command.cs
@ -1,5 +1,4 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Diagnostics.CodeAnalysis;
|
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using System.Windows;
|
using System.Windows;
|
||||||
using System.Windows.Input;
|
using System.Windows.Input;
|
||||||
@ -34,19 +33,18 @@ namespace HashCalculator.GUI
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool CanExecute(object parameter)
|
public bool CanExecute(object? parameter)
|
||||||
{
|
{
|
||||||
return _canExecute;
|
return _canExecute;
|
||||||
}
|
}
|
||||||
|
|
||||||
[SuppressMessage("Globalization", "CA1303:请不要将文本作为本地化参数传递", Justification = "<挂起>")]
|
public void Execute(object? parameter)
|
||||||
public void Execute(object parameter)
|
|
||||||
{
|
{
|
||||||
if (!_canExecute)
|
if (!_canExecute)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if(!(parameter is T typed))
|
if (!(parameter is T typed))
|
||||||
{
|
{
|
||||||
throw new ArgumentException($"{nameof(parameter)} wrong type");
|
throw new ArgumentException($"{nameof(parameter)} wrong type");
|
||||||
}
|
}
|
||||||
@ -56,7 +54,6 @@ namespace HashCalculator.GUI
|
|||||||
|
|
||||||
public Task ExecuteTask(T parameter) => _action(parameter);
|
public Task ExecuteTask(T parameter) => _action(parameter);
|
||||||
|
|
||||||
[SuppressMessage("Design", "CA1031:不捕获常规异常类型", Justification = "<挂起>")]
|
|
||||||
private async void ExecuteTaskInternal(Task task)
|
private async void ExecuteTaskInternal(Task task)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
@ -115,7 +112,6 @@ namespace HashCalculator.GUI
|
|||||||
|
|
||||||
public Task ExecuteTask() => _action();
|
public Task ExecuteTask() => _action();
|
||||||
|
|
||||||
[SuppressMessage("Design", "CA1031:不捕获常规异常类型", Justification = "<挂起>")]
|
|
||||||
private async void ExecuteTaskInternal(Task task)
|
private async void ExecuteTaskInternal(Task task)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
|
@ -34,7 +34,6 @@ namespace HashCalculator.GUI
|
|||||||
TracerListener.StartListening(s => action(() => ViewModel.TraceText += s));
|
TracerListener.StartListening(s => action(() => ViewModel.TraceText += s));
|
||||||
}
|
}
|
||||||
|
|
||||||
[SuppressMessage("Design", "CA1031:不捕获常规异常类型", Justification = "<挂起>")]
|
|
||||||
public async Task OnMainInputDecided(InputEntry selected)
|
public async Task OnMainInputDecided(InputEntry selected)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
@ -78,7 +77,6 @@ namespace HashCalculator.GUI
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[SuppressMessage("Design", "CA1031:不捕获常规异常类型", Justification = "<挂起>")]
|
|
||||||
private static Task<string> CalculateBinaryHash(string filePath, CancellationToken cancel)
|
private static Task<string> CalculateBinaryHash(string filePath, CancellationToken cancel)
|
||||||
{
|
{
|
||||||
return Task.Run(() =>
|
return Task.Run(() =>
|
||||||
@ -201,7 +199,6 @@ namespace HashCalculator.GUI
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[SuppressMessage("Reliability", "CA2000:丢失范围之前释放对象", Justification = "<挂起>")]
|
|
||||||
private async Task LoadXml(string path)
|
private async Task LoadXml(string path)
|
||||||
{
|
{
|
||||||
await CancelLoadingXml().ConfigureAwait(true);
|
await CancelLoadingXml().ConfigureAwait(true);
|
||||||
@ -234,7 +231,6 @@ namespace HashCalculator.GUI
|
|||||||
}, "SAGE FastHash 计算器 - XML 加载失败…", "XML 文件加载失败,也许,你选择的 XML 文件并不是红警3使用的那种……\r\n").ConfigureAwait(true);
|
}, "SAGE FastHash 计算器 - XML 加载失败…", "XML 文件加载失败,也许,你选择的 XML 文件并不是红警3使用的那种……\r\n").ConfigureAwait(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
[SuppressMessage("Design", "CA1031:不捕获常规异常类型", Justification = "<挂起>")]
|
|
||||||
private async Task LoadXmlInternal(string path, CancellationToken token)
|
private async Task LoadXmlInternal(string path, CancellationToken token)
|
||||||
{
|
{
|
||||||
var modXml = new ModXml(path, token);
|
var modXml = new ModXml(path, token);
|
||||||
@ -343,14 +339,15 @@ namespace HashCalculator.GUI
|
|||||||
throw new NotSupportedException();
|
throw new NotSupportedException();
|
||||||
}
|
}
|
||||||
|
|
||||||
baseDirectory.GetFiles("*.csf");
|
var searchFrom = new List<DirectoryInfo> { baseDirectory };
|
||||||
var parent = baseDirectory.Parent;
|
if (baseDirectory.Parent is { } parent)
|
||||||
var searchDirectories =
|
{
|
||||||
parent.GetDirectories($"{baseDirectory.Name[0]}*")
|
searchFrom.AddRange(parent.GetDirectories($"{baseDirectory.Name[0]}*"));
|
||||||
.Prepend(parent.Parent)
|
searchFrom.Add(parent);
|
||||||
.Prepend(baseDirectory);
|
}
|
||||||
searchDirectories = searchDirectories
|
var searchDirectories = new[] { "Additional", "Misc" }
|
||||||
.Concat(searchDirectories.SelectMany(x => x.GetDirectories("Additional")));
|
.SelectMany(n => searchFrom.SelectMany(x => x.GetDirectories(n)))
|
||||||
|
.Concat(searchFrom);
|
||||||
var csfs = from directories in searchDirectories
|
var csfs = from directories in searchDirectories
|
||||||
from data in directories.GetDirectories("Data")
|
from data in directories.GetDirectories("Data")
|
||||||
from csf in data.GetFiles("*.csf")
|
from csf in data.GetFiles("*.csf")
|
||||||
@ -415,7 +412,6 @@ namespace HashCalculator.GUI
|
|||||||
return VirtualFileSystem.GetFileName(path).StartsWith(what, StringComparison.OrdinalIgnoreCase);
|
return VirtualFileSystem.GetFileName(path).StartsWith(what, StringComparison.OrdinalIgnoreCase);
|
||||||
}
|
}
|
||||||
|
|
||||||
[SuppressMessage("Design", "CA1031:不捕获常规异常类型", Justification = "<挂起>")]
|
|
||||||
private static async Task ExceptionWrapepr(Func<Task> action, string errorTitle, string preErrorMessage)
|
private static async Task ExceptionWrapepr(Func<Task> action, string errorTitle, string preErrorMessage)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
|
@ -105,7 +105,7 @@ namespace HashCalculator.GUI
|
|||||||
|
|
||||||
CloseCommand = new Command<CopyableBox>(async window =>
|
CloseCommand = new Command<CopyableBox>(async window =>
|
||||||
{
|
{
|
||||||
CloseCommand.CanExecuteValue = false;
|
CloseCommand!.CanExecuteValue = false;
|
||||||
Notify(nameof(CloseButtonText));
|
Notify(nameof(CloseButtonText));
|
||||||
|
|
||||||
if (_task != null)
|
if (_task != null)
|
||||||
|
@ -22,7 +22,7 @@ namespace HashCalculator.GUI
|
|||||||
{
|
{
|
||||||
Timer = new DispatcherTimer(interval, DispatcherPriority.Normal, (s, e) =>
|
Timer = new DispatcherTimer(interval, DispatcherPriority.Normal, (s, e) =>
|
||||||
{
|
{
|
||||||
if (Timer.IsEnabled && (TimeSinceCreation > wait))
|
if (Timer!.IsEnabled && (TimeSinceCreation > wait))
|
||||||
{
|
{
|
||||||
action(this);
|
action(this);
|
||||||
}
|
}
|
||||||
|
@ -1,9 +1,8 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk.WindowsDesktop">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
|
<UseWPF>true</UseWPF>
|
||||||
<OutputType>WinExe</OutputType>
|
<OutputType>WinExe</OutputType>
|
||||||
<TargetFramework>net472</TargetFramework>
|
<TargetFramework>net5.0-windows</TargetFramework>
|
||||||
<RootNamespace>HashCalculator.GUI</RootNamespace>
|
|
||||||
<LangVersion>8.0</LangVersion>
|
<LangVersion>8.0</LangVersion>
|
||||||
<Nullable>enable</Nullable>
|
<Nullable>enable</Nullable>
|
||||||
<UseWPF>true</UseWPF>
|
<UseWPF>true</UseWPF>
|
||||||
@ -11,30 +10,14 @@
|
|||||||
<UserSecretsId>bf77c300-44f6-46ea-be94-f50d6993b55b</UserSecretsId>
|
<UserSecretsId>bf77c300-44f6-46ea-be94-f50d6993b55b</UserSecretsId>
|
||||||
<StartupObject>HashCalculator.GUI.Program</StartupObject>
|
<StartupObject>HashCalculator.GUI.Program</StartupObject>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Microsoft.Bcl.AsyncInterfaces" Version="1.1.0" />
|
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="3.11.0" />
|
||||||
<PackageReference Include="Microsoft.Bcl.HashCode" Version="1.1.0" />
|
<PackageReference Include="Mvp.Xml.NetStandard" Version="1.1.1" />
|
||||||
<PackageReference Include="Microsoft.CodeAnalysis.FxCopAnalyzers" Version="2.9.8">
|
<PackageReference Include="System.Threading.Tasks.Dataflow" Version="5.0.0" />
|
||||||
<PrivateAssets>all</PrivateAssets>
|
|
||||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
|
||||||
</PackageReference>
|
|
||||||
<PackageReference Include="Mvp.Xml" Version="2.3.0" />
|
|
||||||
<PackageReference Include="System.Threading.Tasks.Dataflow" Version="4.11.0" />
|
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Reference Include="System.Windows.Presentation" />
|
|
||||||
<Reference Include="TechnologyAssembler.Core">
|
<Reference Include="TechnologyAssembler.Core">
|
||||||
<HintPath>TechnologyAssembler.Core.dll</HintPath>
|
<HintPath>TechnologyAssembler.Core.dll</HintPath>
|
||||||
</Reference>
|
</Reference>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<Target Name="CustomAfterResolveReferences" AfterTargets="AfterResolveReferences">
|
|
||||||
<ItemGroup>
|
|
||||||
<EmbeddedResource Include="@(ReferenceCopyLocalPaths)" Condition="'%(ReferenceCopyLocalPaths.Extension)' == '.dll'">
|
|
||||||
<LogicalName>%(ReferenceCopyLocalPaths.DestinationSubDirectory)%(ReferenceCopyLocalPaths.Filename)%(ReferenceCopyLocalPaths.Extension)</LogicalName>
|
|
||||||
</EmbeddedResource>
|
|
||||||
</ItemGroup>
|
|
||||||
</Target>
|
|
||||||
</Project>
|
</Project>
|
31
HashCalculator.GUI.sln
Normal file
31
HashCalculator.GUI.sln
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
|
||||||
|
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||||
|
# Visual Studio Version 16
|
||||||
|
VisualStudioVersion = 16.0.30907.101
|
||||||
|
MinimumVisualStudioVersion = 10.0.40219.1
|
||||||
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "HashCalculator.GUI", "HashCalculator.GUI.csproj", "{C214AFC4-5969-42D6-9524-7C5AF0719188}"
|
||||||
|
EndProject
|
||||||
|
Global
|
||||||
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
|
Debug|Any CPU = Debug|Any CPU
|
||||||
|
Debug|x86 = Debug|x86
|
||||||
|
Release|Any CPU = Release|Any CPU
|
||||||
|
Release|x86 = Release|x86
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||||
|
{C214AFC4-5969-42D6-9524-7C5AF0719188}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{C214AFC4-5969-42D6-9524-7C5AF0719188}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{C214AFC4-5969-42D6-9524-7C5AF0719188}.Debug|x86.ActiveCfg = Debug|x86
|
||||||
|
{C214AFC4-5969-42D6-9524-7C5AF0719188}.Debug|x86.Build.0 = Debug|x86
|
||||||
|
{C214AFC4-5969-42D6-9524-7C5AF0719188}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{C214AFC4-5969-42D6-9524-7C5AF0719188}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{C214AFC4-5969-42D6-9524-7C5AF0719188}.Release|x86.ActiveCfg = Release|x86
|
||||||
|
{C214AFC4-5969-42D6-9524-7C5AF0719188}.Release|x86.Build.0 = Release|x86
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
|
HideSolutionNode = FALSE
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||||
|
SolutionGuid = {DCF48A50-EE93-433D-A957-650FEB2779E9}
|
||||||
|
EndGlobalSection
|
||||||
|
EndGlobal
|
42
ModXml.cs
42
ModXml.cs
@ -44,12 +44,14 @@ namespace HashCalculator.GUI
|
|||||||
public ModXml(string xmlPath, CancellationToken token)
|
public ModXml(string xmlPath, CancellationToken token)
|
||||||
{
|
{
|
||||||
BaseDirectory = new DirectoryInfo(FindBaseDirectory(xmlPath));
|
BaseDirectory = new DirectoryInfo(FindBaseDirectory(xmlPath));
|
||||||
var allMods = BaseDirectory.Parent;
|
var allMods = BaseDirectory.Parent
|
||||||
|
?? throw new ArgumentException($"{nameof(xmlPath)}'s {nameof(BaseDirectory)} doesn't have a parent");
|
||||||
if (!allMods.Name.Equals("Mods", StringComparison.OrdinalIgnoreCase))
|
if (!allMods.Name.Equals("Mods", StringComparison.OrdinalIgnoreCase))
|
||||||
{
|
{
|
||||||
throw new DirectoryNotFoundException();
|
throw new DirectoryNotFoundException();
|
||||||
}
|
}
|
||||||
var allModsParent = allMods.Parent;
|
var allModsParent = allMods.Parent
|
||||||
|
?? throw new ArgumentException($"SDK Mods folder doesn't have a parent");
|
||||||
using var hklm = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry32);
|
using var hklm = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry32);
|
||||||
if (!(hklm.GetValue(RegistryPath) is string sdkRootPath))
|
if (!(hklm.GetValue(RegistryPath) is string sdkRootPath))
|
||||||
{
|
{
|
||||||
@ -129,7 +131,9 @@ namespace HashCalculator.GUI
|
|||||||
}
|
}
|
||||||
|
|
||||||
var document = GetFile(fullPath);
|
var document = GetFile(fullPath);
|
||||||
if (document.Root.Name != EalaAsset + "AssetDeclaration" && document.Root.Name != "AssetDeclaration")
|
var rootName = document.Root?.Name
|
||||||
|
?? throw new InvalidDataException("Document doesn't have a root");
|
||||||
|
if (rootName != EalaAsset + "AssetDeclaration" && rootName != "AssetDeclaration")
|
||||||
{
|
{
|
||||||
throw new NotSupportedException();
|
throw new NotSupportedException();
|
||||||
}
|
}
|
||||||
@ -204,11 +208,13 @@ namespace HashCalculator.GUI
|
|||||||
private static string FindBaseDirectory(string currentPath)
|
private static string FindBaseDirectory(string currentPath)
|
||||||
{
|
{
|
||||||
var file = new FileInfo(currentPath);
|
var file = new FileInfo(currentPath);
|
||||||
if (File.Exists(Path.Combine(file.DirectoryName, "Data", "mod.xml")))
|
var directoryName = file.DirectoryName
|
||||||
|
?? throw new ArgumentException($"{nameof(currentPath)} doens't have a directory");
|
||||||
|
if (File.Exists(Path.Combine(directoryName, "Data", "mod.xml")))
|
||||||
{
|
{
|
||||||
return file.DirectoryName;
|
return directoryName;
|
||||||
}
|
}
|
||||||
return FindBaseDirectory(file.DirectoryName);
|
return FindBaseDirectory(directoryName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -221,11 +227,11 @@ namespace HashCalculator.GUI
|
|||||||
Paths = paths;
|
Paths = paths;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override object GetEntity(Uri absoluteUri, string role, Type ofObjectToReturn)
|
public override object GetEntity(Uri? absoluteUri, string? role, Type? ofObjectToReturn)
|
||||||
{
|
{
|
||||||
if (absoluteUri == null)
|
if (absoluteUri == null)
|
||||||
{
|
{
|
||||||
throw new ArgumentNullException($"{nameof(absoluteUri)} is null");
|
throw new ArgumentNullException(nameof(absoluteUri));
|
||||||
}
|
}
|
||||||
if (ofObjectToReturn != null && ofObjectToReturn != typeof(Stream))
|
if (ofObjectToReturn != null && ofObjectToReturn != typeof(Stream))
|
||||||
{
|
{
|
||||||
@ -234,8 +240,7 @@ namespace HashCalculator.GUI
|
|||||||
return File.OpenRead(absoluteUri.LocalPath);
|
return File.OpenRead(absoluteUri.LocalPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
[SuppressMessage("Globalization", "CA1303:请不要将文本作为本地化参数传递", Justification = "<挂起>")]
|
public override Uri ResolveUri(Uri? baseUri, string? relativeUri)
|
||||||
public override Uri ResolveUri(Uri baseUri, string relativeUri)
|
|
||||||
{
|
{
|
||||||
if (baseUri == null)
|
if (baseUri == null)
|
||||||
{
|
{
|
||||||
@ -247,22 +252,13 @@ namespace HashCalculator.GUI
|
|||||||
}
|
}
|
||||||
if (relativeUri == null)
|
if (relativeUri == null)
|
||||||
{
|
{
|
||||||
throw new ArgumentNullException($"{nameof(relativeUri)} is null");
|
throw new ArgumentNullException(nameof(relativeUri));
|
||||||
}
|
}
|
||||||
return new Uri(Path.GetFullPath(ResolvePath(relativeUri, Path.GetDirectoryName(baseUri.LocalPath))));
|
var localPath = Path.GetDirectoryName(baseUri.LocalPath)
|
||||||
|
?? throw new ArgumentException($"{nameof(baseUri)} doesn't have a local path");
|
||||||
|
return new Uri(Path.GetFullPath(ResolvePath(relativeUri, localPath)));
|
||||||
}
|
}
|
||||||
|
|
||||||
public override Task<object> GetEntityAsync(Uri absoluteUri, string role, Type ofObjectToReturn)
|
|
||||||
{
|
|
||||||
return base.GetEntityAsync(absoluteUri, role, ofObjectToReturn);
|
|
||||||
}
|
|
||||||
|
|
||||||
public override bool SupportsType(Uri absoluteUri, Type type)
|
|
||||||
{
|
|
||||||
return base.SupportsType(absoluteUri, type);
|
|
||||||
}
|
|
||||||
|
|
||||||
[SuppressMessage("Globalization", "CA1303:请不要将文本作为本地化参数传递", Justification = "<挂起>")]
|
|
||||||
private string ResolvePath(string href, string currentDirectory)
|
private string ResolvePath(string href, string currentDirectory)
|
||||||
{
|
{
|
||||||
var splitted = href.Split(new[] { ':' }, 2);
|
var splitted = href.Split(new[] { ':' }, 2);
|
||||||
|
@ -19,16 +19,17 @@ namespace HashCalculator.GUI
|
|||||||
}
|
}
|
||||||
catch(Exception exception)
|
catch(Exception exception)
|
||||||
{
|
{
|
||||||
ErrorBox($"发生了无法处理的错误:\r\n{exception.ToString()}\r\n可以尝试在百度红警3吧联系岚依");
|
ErrorBox($"发生了无法处理的错误:\r\n{exception}\r\n可以尝试在百度红警3吧联系岚依");
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Assembly OnResolveAssembly(object sender, ResolveEventArgs args)
|
private static Assembly OnResolveAssembly(object? sender, ResolveEventArgs args)
|
||||||
{
|
{
|
||||||
var executingAssembly = Assembly.GetExecutingAssembly();
|
var executingAssembly = Assembly.GetExecutingAssembly();
|
||||||
var assemblyName = new AssemblyName(args.Name);
|
var assemblyName = new AssemblyName(args.Name);
|
||||||
var nameString = assemblyName.Name;
|
var nameString = assemblyName.Name
|
||||||
|
?? throw new InvalidOperationException("Assembly does not have an name");
|
||||||
|
|
||||||
var paths = new[] { $"{nameString}.dll" }.AsEnumerable();
|
var paths = new[] { $"{nameString}.dll" }.AsEnumerable();
|
||||||
const string resourceExtenstion = ".resources";
|
const string resourceExtenstion = ".resources";
|
||||||
@ -36,7 +37,7 @@ namespace HashCalculator.GUI
|
|||||||
{
|
{
|
||||||
paths = paths.Append(nameString.Insert(nameString.Length - resourceExtenstion.Length, ".g"));
|
paths = paths.Append(nameString.Insert(nameString.Length - resourceExtenstion.Length, ".g"));
|
||||||
}
|
}
|
||||||
if (!assemblyName.CultureInfo.Equals(CultureInfo.InvariantCulture))
|
if (!Equals(assemblyName.CultureInfo, CultureInfo.InvariantCulture))
|
||||||
{
|
{
|
||||||
paths = paths.Select(x => $"{assemblyName.CultureInfo}\\{x}").Concat(paths);
|
paths = paths.Select(x => $"{assemblyName.CultureInfo}\\{x}").Concat(paths);
|
||||||
}
|
}
|
||||||
|
65
ScriptCompiler.cs
Normal file
65
ScriptCompiler.cs
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
using Microsoft.CodeAnalysis;
|
||||||
|
using Microsoft.CodeAnalysis.CSharp;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Diagnostics;
|
||||||
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
using TechnologyAssembler;
|
||||||
|
|
||||||
|
namespace HashCalculator.GUI
|
||||||
|
{
|
||||||
|
internal class ScriptCompiler
|
||||||
|
{
|
||||||
|
private static readonly MetadataReference[] _references = new[]
|
||||||
|
{
|
||||||
|
typeof(object), // core
|
||||||
|
typeof(Trace), // make sure trace is availaible
|
||||||
|
typeof(Enumerable), // linq
|
||||||
|
typeof(ScriptCompiler), // this
|
||||||
|
typeof(TechnologyAssemblerCoreModule) // wed
|
||||||
|
}.Select(t => MetadataReference.CreateFromFile(t.Assembly.Location)).ToArray();
|
||||||
|
|
||||||
|
public static IEnumerable<(string Id, string Message)> CheckSyntax(string code)
|
||||||
|
{
|
||||||
|
var syntaxTree = CSharpSyntaxTree.ParseText(code);
|
||||||
|
return syntaxTree.GetDiagnostics().Select(diagnostic => (diagnostic.Id, diagnostic.GetMessage()));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static bool Compile(string code, object[] arguments, out IEnumerable<(string Id, string Message)> messages)
|
||||||
|
{
|
||||||
|
// define source code, then parse it (to the type used for compilation)
|
||||||
|
var syntaxTree = CSharpSyntaxTree.ParseText(code);
|
||||||
|
|
||||||
|
// define other necessary objects for compilation
|
||||||
|
var assemblyName = $"Gen{Guid.NewGuid()}.dll";
|
||||||
|
|
||||||
|
// analyse and generate IL code from syntax tree
|
||||||
|
var compilation =
|
||||||
|
CSharpCompilation.Create(assemblyName,
|
||||||
|
syntaxTrees: new[] { syntaxTree },
|
||||||
|
references: _references,
|
||||||
|
options: new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary));
|
||||||
|
|
||||||
|
using var ms = new MemoryStream();
|
||||||
|
// write IL code into memory
|
||||||
|
var result = compilation.Emit(ms);
|
||||||
|
messages = result.Diagnostics.Select(diagnostic => (diagnostic.Id, diagnostic.GetMessage()));
|
||||||
|
|
||||||
|
if (!result.Success)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// load this 'virtual' DLL so that we can use
|
||||||
|
ms.Seek(0, SeekOrigin.Begin);
|
||||||
|
var domain = AppDomain.CreateDomain($"runtime code {assemblyName}");
|
||||||
|
var assembly = domain.Load(ms.ToArray());
|
||||||
|
// create instance of the desired class and call the desired function
|
||||||
|
var entryPoint = assembly.EntryPoint
|
||||||
|
?? throw new InvalidOperationException("Compiled assembly does not have an entry point");
|
||||||
|
entryPoint.Invoke(null, arguments);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,5 +1,4 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Collections.Concurrent;
|
using System.Collections.Concurrent;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using TechnologyAssembler.Core.Language;
|
using TechnologyAssembler.Core.Language;
|
||||||
@ -18,7 +17,7 @@ namespace HashCalculator.GUI
|
|||||||
? null
|
? null
|
||||||
: new CachedCsfTranslationProvider(value);
|
: new CachedCsfTranslationProvider(value);
|
||||||
Interlocked.Exchange(ref _provider, provider);
|
Interlocked.Exchange(ref _provider, provider);
|
||||||
ProviderChanged?.Invoke(null, null);
|
ProviderChanged?.Invoke(null, EventArgs.Empty);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -28,7 +27,7 @@ namespace HashCalculator.GUI
|
|||||||
public static string Translate(string what)
|
public static string Translate(string what)
|
||||||
{
|
{
|
||||||
var provider = Provider;
|
var provider = Provider;
|
||||||
if(provider is null)
|
if (provider is null)
|
||||||
{
|
{
|
||||||
return $"NoProvider:{what}";
|
return $"NoProvider:{what}";
|
||||||
}
|
}
|
||||||
@ -50,7 +49,7 @@ namespace HashCalculator.GUI
|
|||||||
|
|
||||||
public string GetString(string str)
|
public string GetString(string str)
|
||||||
{
|
{
|
||||||
if(!_cache.TryGetValue(str, out var value))
|
if (!_cache.TryGetValue(str, out var value))
|
||||||
{
|
{
|
||||||
value = _provider.GetString(str);
|
value = _provider.GetString(str);
|
||||||
_cache.TryAdd(str, value);
|
_cache.TryAdd(str, value);
|
||||||
|
40
ViewModel.cs
40
ViewModel.cs
@ -1,14 +1,13 @@
|
|||||||
using System;
|
using Microsoft.Win32;
|
||||||
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Collections.ObjectModel;
|
using System.Collections.ObjectModel;
|
||||||
using System.Collections.Specialized;
|
|
||||||
using System.ComponentModel;
|
using System.ComponentModel;
|
||||||
using System.Diagnostics.CodeAnalysis;
|
using System.Diagnostics.CodeAnalysis;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Runtime.CompilerServices;
|
using System.Runtime.CompilerServices;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Microsoft.Win32;
|
|
||||||
using TechnologyAssembler.Core.IO;
|
using TechnologyAssembler.Core.IO;
|
||||||
|
|
||||||
namespace HashCalculator.GUI
|
namespace HashCalculator.GUI
|
||||||
@ -133,19 +132,19 @@ namespace HashCalculator.GUI
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
CancelXml.CanExecuteValue = false;
|
CancelXml!.CanExecuteValue = false;
|
||||||
await controller.CancelLoadingXml().ConfigureAwait(true);
|
await controller.CancelLoadingXml().ConfigureAwait(true);
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
CancelXml.CanExecuteValue = true;
|
CancelXml!.CanExecuteValue = true;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
LoadCsf = new Command<MainWindow>(async window =>
|
LoadCsf = new Command<MainWindow>(async window =>
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
LoadCsf.CanExecuteValue = false;
|
LoadCsf!.CanExecuteValue = false;
|
||||||
var dialog = new OpenFileDialog
|
var dialog = new OpenFileDialog
|
||||||
{
|
{
|
||||||
Multiselect = false,
|
Multiselect = false,
|
||||||
@ -159,7 +158,7 @@ namespace HashCalculator.GUI
|
|||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
LoadCsf.CanExecuteValue = true;
|
LoadCsf!.CanExecuteValue = true;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
FilterDisplayEntries = new Command(() =>
|
FilterDisplayEntries = new Command(() =>
|
||||||
@ -221,9 +220,9 @@ namespace HashCalculator.GUI
|
|||||||
|
|
||||||
private bool FilterDisplayEntry(AssetEntry entry)
|
private bool FilterDisplayEntry(AssetEntry entry)
|
||||||
{
|
{
|
||||||
if(GameObjectOnly)
|
if (GameObjectOnly)
|
||||||
{
|
{
|
||||||
if(entry.Type != "GameObject")
|
if (entry.Type != "GameObject")
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -298,7 +297,7 @@ namespace HashCalculator.GUI
|
|||||||
{
|
{
|
||||||
if (value == 0)
|
if (value == 0)
|
||||||
{
|
{
|
||||||
if (Items.Count() <= 1)
|
if (Items?.Count() <= 1)
|
||||||
{
|
{
|
||||||
value = -1;
|
value = -1;
|
||||||
}
|
}
|
||||||
@ -353,13 +352,13 @@ namespace HashCalculator.GUI
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
BrowseCommand.CanExecuteValue = false;
|
BrowseCommand.CanExecuteValue = false;
|
||||||
SelectCommand.CanExecuteValue = false;
|
SelectCommand!.CanExecuteValue = false;
|
||||||
await controller.OnMainInputDecided(SelectedItem).ConfigureAwait(true);
|
await controller.OnMainInputDecided(SelectedItem).ConfigureAwait(true);
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
BrowseCommand.CanExecuteValue = true;
|
BrowseCommand.CanExecuteValue = true;
|
||||||
SelectCommand.CanExecuteValue = true;
|
SelectCommand!.CanExecuteValue = true;
|
||||||
SelectedIndex = -1;
|
SelectedIndex = -1;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -417,7 +416,7 @@ namespace HashCalculator.GUI
|
|||||||
base.Text = value;
|
base.Text = value;
|
||||||
if (value != SelectedItem?.ToString())
|
if (value != SelectedItem?.ToString())
|
||||||
{
|
{
|
||||||
if(AllManifests != null)
|
if (AllManifests != null)
|
||||||
{
|
{
|
||||||
UpdateList(value);
|
UpdateList(value);
|
||||||
}
|
}
|
||||||
@ -448,7 +447,6 @@ namespace HashCalculator.GUI
|
|||||||
|
|
||||||
public Command<ViewModel> SelectCommand { get; }
|
public Command<ViewModel> SelectCommand { get; }
|
||||||
|
|
||||||
[SuppressMessage("Design", "CA1031:不捕获常规异常类型", Justification = "<挂起>")]
|
|
||||||
public BigInputViewModel(Controller controller)
|
public BigInputViewModel(Controller controller)
|
||||||
{
|
{
|
||||||
SelectCommand = new Command<ViewModel>(async viewModel =>
|
SelectCommand = new Command<ViewModel>(async viewModel =>
|
||||||
@ -456,7 +454,7 @@ namespace HashCalculator.GUI
|
|||||||
var mainInput = viewModel.MainInput;
|
var mainInput = viewModel.MainInput;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
SelectCommand.CanExecuteValue = false;
|
SelectCommand!.CanExecuteValue = false;
|
||||||
mainInput.BrowseCommand.CanExecuteValue = false;
|
mainInput.BrowseCommand.CanExecuteValue = false;
|
||||||
mainInput.SelectCommand.CanExecuteValue = false;
|
mainInput.SelectCommand.CanExecuteValue = false;
|
||||||
LastProcessedManifest = SelectedItem;
|
LastProcessedManifest = SelectedItem;
|
||||||
@ -464,14 +462,14 @@ namespace HashCalculator.GUI
|
|||||||
}
|
}
|
||||||
catch (Exception exception)
|
catch (Exception exception)
|
||||||
{
|
{
|
||||||
CopyableBox.ShowDialog("SAGE FastHash 计算器的错误" , _ =>
|
CopyableBox.ShowDialog("SAGE FastHash 计算器的错误", _ =>
|
||||||
{
|
{
|
||||||
return Task.FromResult($"在加载 manifest 时发生错误:{exception}");
|
return Task.FromResult($"在加载 manifest 时发生错误:{exception}");
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
SelectCommand.CanExecuteValue = true;
|
SelectCommand!.CanExecuteValue = true;
|
||||||
mainInput.BrowseCommand.CanExecuteValue = true;
|
mainInput.BrowseCommand.CanExecuteValue = true;
|
||||||
mainInput.SelectCommand.CanExecuteValue = true;
|
mainInput.SelectCommand.CanExecuteValue = true;
|
||||||
}
|
}
|
||||||
@ -526,7 +524,7 @@ namespace HashCalculator.GUI
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
foreach(var i in Enumerable.Range(0, base.Count).Reverse())
|
foreach (var i in Enumerable.Range(0, base.Count).Reverse())
|
||||||
{
|
{
|
||||||
var item = base[i];
|
var item = base[i];
|
||||||
if (ifRemove(item))
|
if (ifRemove(item))
|
||||||
|
Loading…
x
Reference in New Issue
Block a user