feat: use separate process for classifying

This commit is contained in:
Anna 2021-01-30 16:02:37 -05:00
parent b2e719faa0
commit 87c5602319
21 changed files with 236 additions and 134 deletions

View File

@ -1,36 +0,0 @@
using System;
using System.IO;
using Microsoft.ML;
using NoSoliciting.Interface;
namespace NoSoliciting.CursedWorkaround {
[Serializable]
public class CursedWorkaround : MarshalByRefObject, IClassifier, IDisposable {
private MLContext Context { get; set; } = null!;
private ITransformer Model { get; set; } = null!;
private DataViewSchema Schema { get; set; } = null!;
private PredictionEngine<Data, Prediction> PredictionEngine { get; set; } = null!;
public override object? InitializeLifetimeService() {
return null;
}
public void Initialise(byte[] data) {
this.Context = new MLContext();
this.Context.ComponentCatalog.RegisterAssembly(typeof(Data).Assembly);
using var stream = new MemoryStream(data);
var model = this.Context.Model.Load(stream, out var schema);
this.Model = model;
this.Schema = schema;
this.PredictionEngine = this.Context.Model.CreatePredictionEngine<Data, Prediction>(this.Model, this.Schema);
}
public string Classify(ushort channel, string message) {
return this.PredictionEngine.Predict(new Data(channel, message)).Category;
}
public void Dispose() {
this.PredictionEngine.Dispose();
}
}
}

View File

@ -0,0 +1,32 @@
using System.Text;
using JKang.IpcServiceFramework;
using JKang.IpcServiceFramework.Services;
using Newtonsoft.Json;
namespace NoSoliciting.Interface {
public class BetterIpcSerialiser : IIpcMessageSerializer {
private static readonly JsonSerializerSettings Settings = new() {
TypeNameHandling = TypeNameHandling.Auto,
};
public byte[] SerializeRequest(IpcRequest request) {
var json = JsonConvert.SerializeObject(request, Formatting.None, Settings);
return Encoding.UTF8.GetBytes(json);
}
public IpcResponse? DeserializeResponse(byte[] binary) {
var json = Encoding.UTF8.GetString(binary);
return JsonConvert.DeserializeObject<IpcResponse>(json, Settings);
}
public IpcRequest? DeserializeRequest(byte[] binary) {
var json = Encoding.UTF8.GetString(binary);
return JsonConvert.DeserializeObject<IpcRequest>(json, Settings);
}
public byte[] SerializeResponse(IpcResponse response) {
var json = JsonConvert.SerializeObject(response, Formatting.None, Settings);
return Encoding.UTF8.GetBytes(json);
}
}
}

6
NoSoliciting.Interface/NoSoliciting.Interface.csproj Normal file → Executable file
View File

@ -1,13 +1,13 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net48</TargetFramework>
<LangVersion>8</LangVersion>
<TargetFrameworks>net48;netcoreapp3.1</TargetFrameworks>
<LangVersion>latest</LangVersion>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.ML" Version="1.5.4" />
<PackageReference Include="JKang.IpcServiceFramework.Core" Version="3.1.0" />
</ItemGroup>
</Project>

View File

@ -7,8 +7,11 @@ using System.Text.RegularExpressions;
using Microsoft.ML.Data;
using Microsoft.ML.Transforms;
namespace NoSoliciting.Interface {
namespace NoSoliciting.Internal.Interface {
[SuppressMessage("ReSharper", "UnusedMember.Global")]
[SuppressMessage("ReSharper", "AutoPropertyCanBeMadeGetOnly.Global")]
[SuppressMessage("ReSharper", "UnusedAutoPropertyAccessor.Global")]
[SuppressMessage("ReSharper", "MemberCanBePrivate.Global")]
public class Data {
[LoadColumn(0)]
public string? Category { get; set; }
@ -30,6 +33,7 @@ namespace NoSoliciting.Interface {
#region computed
[CustomMappingFactoryAttribute("Compute")]
[SuppressMessage("ReSharper", "UnusedType.Global")]
public class ComputeContext : CustomMappingFactory<Data, Computed> {
private Dictionary<string, float> Weights { get; }
@ -51,18 +55,18 @@ namespace NoSoliciting.Interface {
}
private static readonly Regex[] PlotWords = {
new Regex(@"\bplot\b", RegexOptions.Compiled | RegexOptions.IgnoreCase),
new Regex(@"\bapartment\b", RegexOptions.Compiled | RegexOptions.IgnoreCase),
new Regex(@"\bapt\b", RegexOptions.Compiled | RegexOptions.IgnoreCase),
new Regex(@"p.{0,2}\d", RegexOptions.Compiled | RegexOptions.IgnoreCase),
new(@"\bplot\b", RegexOptions.Compiled | RegexOptions.IgnoreCase),
new(@"\bapartment\b", RegexOptions.Compiled | RegexOptions.IgnoreCase),
new(@"\bapt\b", RegexOptions.Compiled | RegexOptions.IgnoreCase),
new(@"p.{0,2}\d", RegexOptions.Compiled | RegexOptions.IgnoreCase),
};
private static readonly Regex[] WardWords = {
new Regex(@"\bward\b", RegexOptions.Compiled | RegexOptions.IgnoreCase),
new Regex(@"w.{0,2}\d", RegexOptions.Compiled | RegexOptions.IgnoreCase),
new(@"\bward\b", RegexOptions.Compiled | RegexOptions.IgnoreCase),
new(@"w.{0,2}\d", RegexOptions.Compiled | RegexOptions.IgnoreCase),
};
private static readonly Regex NumbersRegex = new Regex(@"\d{1,2}.{0,2}\d{1,2}", RegexOptions.Compiled);
private static readonly Regex NumbersRegex = new(@"\d{1,2}.{0,2}\d{1,2}", RegexOptions.Compiled);
private static readonly string[] TradeWords = {
"B> ",
@ -73,8 +77,9 @@ namespace NoSoliciting.Interface {
"WTS",
};
private static readonly Regex SketchUrlRegex = new Regex(@"\.com-\w+\.\w+", RegexOptions.IgnoreCase | RegexOptions.Compiled);
private static readonly Regex SketchUrlRegex = new(@"\.com-\w+\.\w+", RegexOptions.IgnoreCase | RegexOptions.Compiled);
[SuppressMessage("ReSharper", "UnusedAutoPropertyAccessor.Global")]
public class Computed {
public float Weight { get; set; } = 1;
@ -110,12 +115,14 @@ namespace NoSoliciting.Interface {
#endregion
}
[SuppressMessage("ReSharper", "AutoPropertyCanBeMadeGetOnly.Global")]
[SuppressMessage("ReSharper", "UnusedMember.Global")]
public class Prediction {
[ColumnName("PredictedLabel")]
public string Category { get; set; }
public string Category { get; set; } = "UNKNOWN";
[ColumnName("Score")]
public float[] Probabilities { get; set; }
public float[] Probabilities { get; set; } = new float[0];
}
internal static class Ext {

View File

@ -0,0 +1,13 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>netcoreapp3.1;net48</TargetFrameworks>
<LangVersion>latest</LangVersion>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.ML" Version="1.5.4" />
</ItemGroup>
</Project>

View File

@ -1,9 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<Weavers xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="FodyWeavers.xsd">
<Costura>
<ExcludeAssemblies>
Costura
NoSoliciting.Interface
</ExcludeAssemblies>
</Costura>
<Costura>
<ExcludeAssemblies>
Costura
</ExcludeAssemblies>
</Costura>
</Weavers>

View File

@ -1,30 +1,30 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net48</TargetFramework>
<LangVersion>8</LangVersion>
<LangVersion>latest</LangVersion>
<Nullable>enable</Nullable>
<PlatformTarget>x64</PlatformTarget>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Costura.Fody" Version="4.1.0">
<PrivateAssets>all</PrivateAssets>
</PackageReference>
<ProjectReference Include="..\NoSoliciting.Interface\NoSoliciting.Interface.csproj" />
<ProjectReference Include="..\NoSoliciting.Internal.Interface\NoSoliciting.Internal.Interface.csproj" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Costura.Fody" Version="4.1.0" PrivateAssets="all" />
<PackageReference Include="Fody" Version="6.3.0">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="JKang.IpcServiceFramework.Hosting.NamedPipe" Version="3.1.0" />
<PackageReference Include="Microsoft.Extensions.Hosting" Version="5.0.0" />
<PackageReference Include="Microsoft.ML" Version="1.5.4" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\NoSoliciting.Interface\NoSoliciting.Interface.csproj" />
</ItemGroup>
<ItemGroup>
<None Remove="costura64\CpuMathNative.dll" />
<EmbeddedResource Include="costura64\CpuMathNative.dll" />
<EmbeddedResource Include="costura64\*.dll" />
</ItemGroup>
</Project>

View File

@ -0,0 +1,57 @@
using System;
using System.IO;
using JKang.IpcServiceFramework.Hosting;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.ML;
using NoSoliciting.Interface;
using NoSoliciting.Internal.Interface;
namespace NoSoliciting.MessageClassifier {
internal static class Program {
private static void Main() {
Host.CreateDefaultBuilder()
.ConfigureServices(services => {
services.AddSingleton<IClassifier, ClassifierService>();
})
.ConfigureIpcHost(builder => {
builder.AddNamedPipeEndpoint<IClassifier>(options => {
options.PipeName = "NoSoliciting.MessageClassifier";
options.Serializer = new BetterIpcSerialiser();
});
})
.Build()
.Run();
}
}
internal class ClassifierService : IClassifier, IDisposable {
private MLContext Context { get; set; } = null!;
private ITransformer Model { get; set; } = null!;
private DataViewSchema Schema { get; set; } = null!;
private PredictionEngine<Data, Prediction>? PredictionEngine { get; set; }
public void Initialise(byte[] data) {
if (this.PredictionEngine != null) {
this.PredictionEngine.Dispose();
this.PredictionEngine = null;
}
this.Context = new MLContext();
this.Context.ComponentCatalog.RegisterAssembly(typeof(Data).Assembly);
using var stream = new MemoryStream(data);
var model = this.Context.Model.Load(stream, out var schema);
this.Model = model;
this.Schema = schema;
this.PredictionEngine = this.Context.Model.CreatePredictionEngine<Data, Prediction>(this.Model, this.Schema);
}
public string Classify(ushort channel, string message) {
return this.PredictionEngine?.Predict(new Data(channel, message))?.Category ?? "UNKNOWN";
}
public void Dispose() {
this.PredictionEngine?.Dispose();
}
}
}

Binary file not shown.

View File

@ -3,17 +3,18 @@
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp3.1</TargetFramework>
<LangVersion>latest</LangVersion>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="ConsoleTables" Version="2.4.2" />
<PackageReference Include="CsvHelper" Version="19.0.0" />
<PackageReference Include="CsvHelper" Version="21.3.1" />
<PackageReference Include="Microsoft.ML" Version="1.5.4" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\NoSoliciting.Interface\NoSoliciting.Interface.csproj" />
<ProjectReference Include="..\NoSoliciting.Internal.Interface\NoSoliciting.Internal.Interface.csproj" />
</ItemGroup>
</Project>

View File

@ -9,7 +9,7 @@ using CsvHelper.Configuration;
using Microsoft.ML;
using Microsoft.ML.Data;
using Microsoft.ML.Transforms.Text;
using NoSoliciting.Interface;
using NoSoliciting.Internal.Interface;
namespace NoSoliciting.Trainer {
internal static class Program {
@ -36,7 +36,7 @@ namespace NoSoliciting.Trainer {
using (var fileStream = new FileStream("../../../data.csv", FileMode.Create)) {
using var stream = new StreamWriter(fileStream);
using var csv = new CsvWriter(stream, new CsvConfiguration(CultureInfo.InvariantCulture) {
NewLine = NewLine.LF,
NewLine = "\n",
});
csv.WriteRecords(records);
}
@ -179,10 +179,4 @@ namespace NoSoliciting.Trainer {
}
}
}
internal static class Ext {
public static bool ContainsIgnoreCase(this string haystack, string needle) {
return CultureInfo.InvariantCulture.CompareInfo.IndexOf(haystack, needle, CompareOptions.IgnoreCase) >= 0;
}
}
}

View File

@ -4,7 +4,7 @@ using System.Text;
namespace NoSoliciting.Trainer {
public static class Util {
private static readonly Dictionary<char, string> Replacements = new Dictionary<char, string> {
private static readonly Dictionary<char, string> Replacements = new() {
// numerals
['\ue055'] = "1",
['\ue056'] = "2",

18
NoSoliciting.sln Normal file → Executable file
View File

@ -9,12 +9,14 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NoSoliciting.Tests", "NoSoliciting.Tests\NoSoliciting.Tests.csproj", "{1962D91F-543A-4214-88FD-788BB7ACECE3}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NoSoliciting.CursedWorkaround", "NoSoliciting.CursedWorkaround\NoSoliciting.CursedWorkaround.csproj", "{F3238422-A9D8-4E71-9365-9EFFEC85CB59}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NoSoliciting.Interface", "NoSoliciting.Interface\NoSoliciting.Interface.csproj", "{E88E57AB-EFB8-4F2F-93DB-F63123638C44}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NoSoliciting.Trainer", "NoSoliciting.Trainer\NoSoliciting.Trainer.csproj", "{3D774127-F7A9-4B6D-AB2F-3AAF80D15586}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NoSoliciting.MessageClassifier", "NoSoliciting.MessageClassifier\NoSoliciting.MessageClassifier.csproj", "{16689469-6A74-4197-818A-EA44697BD815}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NoSoliciting.Internal.Interface", "NoSoliciting.Internal.Interface\NoSoliciting.Internal.Interface.csproj", "{742F1B3F-030F-4886-B05D-0D41D4DDA8FD}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@ -29,10 +31,6 @@ Global
{1962D91F-543A-4214-88FD-788BB7ACECE3}.Debug|Any CPU.Build.0 = Debug|Any CPU
{1962D91F-543A-4214-88FD-788BB7ACECE3}.Release|Any CPU.ActiveCfg = Release|Any CPU
{1962D91F-543A-4214-88FD-788BB7ACECE3}.Release|Any CPU.Build.0 = Release|Any CPU
{F3238422-A9D8-4E71-9365-9EFFEC85CB59}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{F3238422-A9D8-4E71-9365-9EFFEC85CB59}.Debug|Any CPU.Build.0 = Debug|Any CPU
{F3238422-A9D8-4E71-9365-9EFFEC85CB59}.Release|Any CPU.ActiveCfg = Release|Any CPU
{F3238422-A9D8-4E71-9365-9EFFEC85CB59}.Release|Any CPU.Build.0 = Release|Any CPU
{E88E57AB-EFB8-4F2F-93DB-F63123638C44}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{E88E57AB-EFB8-4F2F-93DB-F63123638C44}.Debug|Any CPU.Build.0 = Debug|Any CPU
{E88E57AB-EFB8-4F2F-93DB-F63123638C44}.Release|Any CPU.ActiveCfg = Release|Any CPU
@ -41,6 +39,14 @@ Global
{3D774127-F7A9-4B6D-AB2F-3AAF80D15586}.Debug|Any CPU.Build.0 = Debug|Any CPU
{3D774127-F7A9-4B6D-AB2F-3AAF80D15586}.Release|Any CPU.ActiveCfg = Release|Any CPU
{3D774127-F7A9-4B6D-AB2F-3AAF80D15586}.Release|Any CPU.Build.0 = Release|Any CPU
{16689469-6A74-4197-818A-EA44697BD815}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{16689469-6A74-4197-818A-EA44697BD815}.Debug|Any CPU.Build.0 = Debug|Any CPU
{16689469-6A74-4197-818A-EA44697BD815}.Release|Any CPU.ActiveCfg = Release|Any CPU
{16689469-6A74-4197-818A-EA44697BD815}.Release|Any CPU.Build.0 = Release|Any CPU
{742F1B3F-030F-4886-B05D-0D41D4DDA8FD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{742F1B3F-030F-4886-B05D-0D41D4DDA8FD}.Debug|Any CPU.Build.0 = Debug|Any CPU
{742F1B3F-030F-4886-B05D-0D41D4DDA8FD}.Release|Any CPU.ActiveCfg = Release|Any CPU
{742F1B3F-030F-4886-B05D-0D41D4DDA8FD}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE

View File

@ -5,6 +5,6 @@
AssemblyName="$(AssemblyName)"
VersionComponents="3"
MakeZip="true"
Include="NoSoliciting.json;NoSoliciting.dll;NoSoliciting.Interface.dll;NoSoliciting.CursedWorkaround.dll;YamlDotNet.dll"/>
Include="NoSoliciting.json;NoSoliciting.dll;NoSoliciting.pdb"/>
</Target>
</Project>

4
NoSoliciting/FodyWeavers.xml Executable file
View File

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<Weavers xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="FodyWeavers.xsd">
<Resourcer />
</Weavers>

23
NoSoliciting/ILRepack.targets Executable file
View File

@ -0,0 +1,23 @@
<?xml version="1.0" encoding="utf-8" ?>
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Target Name="ILRepacker" AfterTargets="Build" Condition="'$(Configuration)' == 'Release'">
<ItemGroup>
<InputAssemblies Include="$(OutputPath)\NoSoliciting.dll"/>
<InputAssemblies Include="$(OutputPath)\NoSoliciting.Interface.dll"/>
<InputAssemblies Include="$(OutputPath)\J*.dll"/>
<InputAssemblies Include="$(OutputPath)\M*.dll"/>
<InputAssemblies Include="$(OutputPath)\S*.dll"/>
<InputAssemblies Include="$(OutputPath)\Y*.dll"/>
</ItemGroup>
<ILRepack
Parallel="true"
Internalize="true"
InputAssemblies="@(InputAssemblies)"
LibraryPath="$(OutputPath)"
TargetKind="Dll"
OutputFile="$(OutputPath)\$(AssemblyName).dll"
/>
</Target>
</Project>

View File

@ -1,10 +1,14 @@
using System;
using System.Diagnostics;
using System.IO;
using System.Net;
using System.Text;
using System.Threading.Tasks;
using Dalamud.Plugin;
using JKang.IpcServiceFramework.Client;
using Microsoft.Extensions.DependencyInjection;
using NoSoliciting.Interface;
using Resourcer;
using YamlDotNet.Core;
using YamlDotNet.Serialization;
using YamlDotNet.Serialization.NamingConventions;
@ -22,37 +26,25 @@ namespace NoSoliciting.Ml {
#endif
public uint Version { get; }
private IClassifier Classifier { get; }
private MlFilter(uint version, IClassifier classifier) {
this.Version = version;
private Process Process { get; }
private IIpcClient<IClassifier> Classifier { get; }
private MlFilter(uint version, Process process, IIpcClient<IClassifier> classifier) {
this.Process = process;
this.Classifier = classifier;
this.Version = version;
}
// private MLContext Context { get; }
// private ITransformer Model { get; }
// private DataViewSchema Schema { get; }
// private PredictionEngine<MessageData, MessagePrediction> PredictionEngine { get; }
//
// private MlFilter(uint version, MLContext context, ITransformer model, DataViewSchema schema) {
// this.Version = version;
// this.Context = context;
// this.Model = model;
// this.Schema = schema;
// this.PredictionEngine = this.Context.Model.CreatePredictionEngine<MessageData, MessagePrediction>(this.Model, this.Schema);
// }
public MessageCategory ClassifyMessage(ushort channel, string message) {
// var data = new MessageData(channel, message);
// var pred = this.PredictionEngine.Predict(data);
var rawCategory = this.Classifier.Classify(channel, message);
var category = MessageCategoryExt.FromString(rawCategory);
var prediction = this.Classifier.InvokeAsync(classifier => classifier.Classify(channel, message)).Result;
var category = MessageCategoryExt.FromString(prediction);
if (category != null) {
return (MessageCategory) category;
}
PluginLog.LogWarning($"Unknown message category: {rawCategory}");
PluginLog.LogWarning($"Unknown message category: {prediction}");
return MessageCategory.Normal;
}
@ -82,18 +74,33 @@ namespace NoSoliciting.Ml {
UpdateCachedFile(plugin, ModelName, data);
UpdateCachedFile(plugin, ManifestName, Encoding.UTF8.GetBytes(manifest.Item2));
// var context = new MLContext();
// using var stream = new MemoryStream(data);
// var model = context.Model.Load(stream, out var schema);
using var exe = Resource.AsStream("NoSoliciting.NoSoliciting.MessageClassifier.exe");
var pluginFolder = Util.PluginFolder(plugin);
Directory.CreateDirectory(pluginFolder);
var exePath = Path.Combine(pluginFolder, "NoSoliciting.MessageClassifier.exe");
using (var exeFile = File.Create(exePath)) {
await exe.CopyToAsync(exeFile);
}
// return new MlFilter(manifest.Item1.Version, context, model, schema);
var startInfo = new ProcessStartInfo(exePath) {
CreateNoWindow = true,
UseShellExecute = false,
};
var process = Process.Start(startInfo);
plugin.Classifier.Initialise(data);
var serviceProvider = new ServiceCollection()
.AddNamedPipeIpcClient<IClassifier>("client", (_, options) => {
options.PipeName = "NoSoliciting.MessageClassifier";
options.Serializer = new BetterIpcSerialiser();
})
.BuildServiceProvider();
return new MlFilter(
manifest.Item1.Version,
plugin.Classifier
);
var clientFactory = serviceProvider.GetRequiredService<IIpcClientFactory<IClassifier>>();
var client = clientFactory.CreateClient("client");
await client.InvokeAsync(classifier => classifier.Initialise(data));
return new MlFilter(manifest.Item1.Version, process!, client);
}
private static async Task<byte[]?> DownloadModel(Uri url) {
@ -167,7 +174,8 @@ namespace NoSoliciting.Ml {
}
public void Dispose() {
// this.PredictionEngine.Dispose();
this.Process.Kill();
this.Process.Dispose();
}
}
}

View File

@ -1,7 +1,4 @@
using System;
using System.Linq;
using System.Text.RegularExpressions;
using Microsoft.ML.Data;
namespace NoSoliciting.Ml {
public enum MessageCategory {

View File

@ -36,7 +36,15 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="DalamudPackager" Version="1.2.0" />
<PackageReference Include="YamlDotNet" Version="9.1.1" />
<PackageReference Include="Fody" Version="6.3.0">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="ILRepack.Lib.MSBuild.Task" Version="2.0.18.2" />
<PackageReference Include="JKang.IpcServiceFramework.Client.NamedPipe" Version="3.1.0" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="5.0.0" />
<PackageReference Include="Resourcer.Fody" Version="1.8.0" PrivateAssets="all" />
<PackageReference Include="YamlDotNet" Version="9.1.4" />
</ItemGroup>
<ItemGroup>
<Compile Update="Properties\Resources.Designer.cs">
@ -50,8 +58,9 @@
<Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
</EmbeddedResource>
<EmbeddedResource Include="..\NoSoliciting.MessageClassifier\bin\Release\net48\NoSoliciting.MessageClassifier.exe" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\NoSoliciting.CursedWorkaround\NoSoliciting.CursedWorkaround.csproj" />
<ProjectReference Include="..\NoSoliciting.Interface\NoSoliciting.Interface.csproj" />
</ItemGroup>
</Project>

View File

@ -41,15 +41,6 @@ namespace NoSoliciting {
public IClassifier Classifier { get; private set; } = null!;
public void Initialize(DalamudPluginInterface pluginInterface) {
// FIXME: eventually this cursed workaround for old System.Numerics.Vectors should be destroyed
this.InnerDomain = AppDomain.CreateDomain(LibraryName, AppDomain.CurrentDomain.Evidence, new AppDomainSetup {
ApplicationName = LibraryName,
ConfigurationFile = $"{LibraryName}.dll.config",
ApplicationBase = Path.GetDirectoryName(this.AssemblyLocation),
});
this.InnerDomain.InitializeLifetimeService();
this.Classifier = (IClassifier) this.InnerDomain.CreateInstanceAndUnwrap(LibraryName, $"{LibraryName}.CursedWorkaround");
string path = Environment.GetEnvironmentVariable("PATH")!;
string newPath = Path.GetDirectoryName(this.AssemblyLocation)!;
Environment.SetEnvironmentVariable("PATH", $"{path};{newPath}");
@ -141,9 +132,6 @@ namespace NoSoliciting {
this.Interface.UiBuilder.OnBuildUi -= this.Ui.Draw;
this.Interface.UiBuilder.OnOpenConfigUi -= this.Ui.OpenSettings;
this.Interface.CommandManager.RemoveHandler("/prmt");
// AppDomain.CurrentDomain.AssemblyResolve -= this.ResolveAssembly;
AppDomain.Unload(this.InnerDomain);
}
this._disposedValue = true;