Skip to content

Commit

Permalink
Ashe のインターフェイス整備
Browse files Browse the repository at this point in the history
  • Loading branch information
azyobuzin committed Oct 15, 2018
1 parent 4651e36 commit 6147f7e
Show file tree
Hide file tree
Showing 14 changed files with 263 additions and 32 deletions.
16 changes: 16 additions & 0 deletions src/Ashe.Contract/Ashe.Contract.csproj
@@ -0,0 +1,16 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<AssemblyName>WagahighChoices.Ashe.Contract</AssemblyName>
<RootNamespace>WagahighChoices.Ashe</RootNamespace>
<LangVersion>latest</LangVersion>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="MagicOnion" Version="0.5.3" />
<PackageReference Include="MessagePackAnalyzer" Version="1.6.0" PrivateAssets="All" />
<PackageReference Include="System.Collections.Immutable" Version="1.5.0" />
</ItemGroup>

</Project>
8 changes: 8 additions & 0 deletions src/Ashe.Contract/ChoiceAction.cs
@@ -0,0 +1,8 @@
namespace WagahighChoices.Ashe
{
public enum ChoiceAction
{
SelectUpper,
SelectLower,
}
}
14 changes: 14 additions & 0 deletions src/Ashe.Contract/Heroine.cs
@@ -0,0 +1,14 @@
namespace WagahighChoices.Ashe
{
public enum Heroine
{
/// <summary>鹿苑寺かおるこ</summary>
Kaoruko,
/// <summary>桜木・R・アーシェ</summary>
Ashe,
/// <summary>鳴海兎亜</summary>
Toa,
/// <summary>宮瀬未尋</summary>
Mihiro,
}
}
40 changes: 40 additions & 0 deletions src/Ashe.Contract/SearchDirector.cs
@@ -0,0 +1,40 @@
using System;
using System.Collections.Generic;
using System.Threading.Tasks;

namespace WagahighChoices.Ashe
{
public abstract class SearchDirector : IDisposable
{
protected bool IsDisposed { get; private set; }

protected virtual void Dispose(bool disposing)
{
this.IsDisposed = true;
}

public void Dispose()
{
this.Dispose(true);
GC.SuppressFinalize(this);
}

/// <summary>
/// 新しい指示をもらいます。
/// </summary>
public abstract Task<SeekDirectionResult> SeekDirection();

/// <summary>
/// 探索結果をレポートします。
/// </summary>
/// <param name="jobId"><see cref="SeekDirectionResult.JobId"/></param>
/// <param name="heroine">誰のルートに至ったか</param>
/// <param name="selectionIds">通過した選択画面のリスト</param>
public abstract Task ReportResult(Guid jobId, Heroine heroine, IReadOnlyList<int> selectionIds);

/// <summary>
/// ログを送信します。
/// </summary>
public abstract Task Log(string message, DateTimeOffset timestamp);
}
}
42 changes: 42 additions & 0 deletions src/Ashe.Contract/SeekDirectionResult.cs
@@ -0,0 +1,42 @@
using System;
using MessagePack;

namespace WagahighChoices.Ashe
{
[MessagePackObject]
public class SeekDirectionResult
{
[Key(0)]
public SeekDirectionResultKind Kind { get; }

[Key(1)]
public Guid JobId { get; set; }

[Key(2)]
public ChoiceAction[] Actions { get; }

[SerializationConstructor]
public SeekDirectionResult(SeekDirectionResultKind kind, Guid jobId, ChoiceAction[] actions)
{
this.Kind = kind;
this.JobId = jobId;
this.Actions = actions;
}
}

public enum SeekDirectionResultKind
{
/// <summary>
/// 指示が <see cref="SeekDirectionResult.Actions"/> に代入されています。
/// </summary>
Ok,
/// <summary>
/// すべてのジョブがワーカーに割り当てられているので、今は手を付けられる新しいジョブがありません。
/// </summary>
NotAvailable,
/// <summary>
/// 探索は終了しました。
/// </summary>
Finished,
}
}
55 changes: 55 additions & 0 deletions src/Ashe.Contract/SelectionInfo.cs
@@ -0,0 +1,55 @@
using System;
using System.Collections.Immutable;

namespace WagahighChoices.Ashe
{
public class SelectionInfo
{
public int Id { get; }
public byte[] ScreenshotHash { get; } // ImmutableArray にしたい

protected SelectionInfo(int id, string screenshotHash)
{
this.Id = id;

// Blockhash 256bit なので、 64 文字なはず
if (screenshotHash?.Length != 64) throw new ArgumentException();

var hash = new byte[32];
for (var i = 0; i < hash.Length; i++)
{
uint HexToUInt(char c)
{
if (c >= '0' && c <= '9') return c - (uint)'0';
if (c >= 'a' && c <= 'f') return c - (uint)'a' + 10;
if (c >= 'A' && c <= 'F') return c - (uint)'A' + 10;
throw new FormatException();
}

hash[i] = (byte)(HexToUInt(screenshotHash[i * 2]) << 4 | HexToUInt(screenshotHash[i * 2 + 1]));
}

this.ScreenshotHash = hash;
}

public override string ToString() => nameof(SelectionInfo) + " " + this.Id;

// (ここに選択肢の文字列を入れてしまうと MIT License で配布するということに問題が発生してしまうので入れないぞ)
public static ImmutableArray<SelectionInfo> Selections { get; } = ImmutableArray.Create(
new SelectionInfo(1, "24f604760c3f6c3f2e7628162ef629b66dbf20097c478d4707c607c407c0cfff"),
new SelectionInfo(2, "6b006a307f70ffb07fb06db06e706d207ff307e0872606e407600fe003c0ffff"),
new SelectionInfo(3, "f01df81df80df00df21cf10cfffc0380319f119607b60fa70be00fe00fe3c7e6"),
new SelectionInfo(4, "1e001000fb8fffbffc0ff81f7e3f00000fc703c783c7c3c683c0c1c0c3c0ffff"),
new SelectionInfo(5, "fc01fc01fc07fc07fe77fc070ff50000fffc83f9b0039003f00390038e03ffff"),
new SelectionInfo(6, "e780ff900fc12fc80ff80fd0bff88d00afc00fc0ff40ff406fc03d931ddb09d0"),
new SelectionInfo(7, "e47ee07ee25c82c44fdcc1c88f70c7e0d7e157017701ff80ff80bea0fe22bc20"),
new SelectionInfo(8, "81f81ff8bff221808fc2a020bef3a1f3f5b7f933f103c100718ce10f0100ffff"),
new SelectionInfo(9, "43f009f08fe60bee0ff80ff00ff083f0e34ff7c107c106e100e302670057ffff"),
new SelectionInfo(10, "001ff9ff031f03170ff709b30ff20256035f03d3b3d293ca580c400c7836ffff"),
new SelectionInfo(11, "21ff00ff00ff08dc0afe017e2d3838afdbc9ece9e360f200f010c0dcc2ff44fe"),
new SelectionInfo(12, "01fc1fea33f233c00ff281f03ff013f0b382ff90bfb2848208fc47400780ffff")
);

public static SelectionInfo GetSelectionById(int id) => Selections[id - 1]; // データ依存ハック
}
}
21 changes: 21 additions & 0 deletions src/Ashe/Ashe.csproj
@@ -0,0 +1,21 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp2.1</TargetFramework>
<AssemblyName>ashe</AssemblyName>
<RootNamespace>WagahighChoices.Ashe</RootNamespace>
<LangVersion>latest</LangVersion>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="McMaster.Extensions.CommandLineUtils" Version="2.2.5" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\Ashe.Contract\Ashe.Contract.csproj" />
<ProjectReference Include="..\Toa.Core\Toa.Core.csproj" />
<ProjectReference Include="..\Toa.Grpc\Toa.Grpc.csproj" />
</ItemGroup>

</Project>
35 changes: 35 additions & 0 deletions src/Ashe/Program.cs
@@ -0,0 +1,35 @@
using System;
using McMaster.Extensions.CommandLineUtils;
using WagahighChoices.Toa.Grpc;

namespace WagahighChoices.Ashe
{
[Command(Name = "ashe", FullName = "Ashe", Description = "探索ワーカー")]
public class Program
{
public static int Main(string[] args)
{
return CommandLineApplication.Execute<Program>(args);
}

[Option("--kaoruko-host <host>", Description = "接続する Kaoruko のホスト名。指定しない場合はコンソールから指示を受け付けます")]
public string KaorukoHost { get; set; }

[Option("--kaoruko-port <port>", Description = "接続する Kaoruko のポート番号(デフォルト: 50222)")]
public int KaorukoPort { get; set; }

[Option("--toa-host <host>", Description = "接続する Toa のホスト名。指定しない場合はワガママハイスペックを起動します")]
public string ToaHost { get; set; }

[Option("--toa-port <port>", Description = "接続する Toa のポート番号(デフォルト: 51203)")]
public int ToaPort { get; set; } = GrpcToaServer.DefaultPort;

[Option("-d|--directory <dir>", Description = "ワガママハイスペック.exe が存在するディレクトリ(Toa を使用しない場合)")]
public string Directory { get; set; }

private void OnExecute()
{

}
}
}
2 changes: 1 addition & 1 deletion src/Blockhash.Cli/Program.cs
Expand Up @@ -17,7 +17,7 @@ public static int Main(string[] args)
[Argument(0), Required]
public string[] InputFiles { get; set; }

[Option]
[Option("--bits <N>", Description = "N^2 ビットのハッシュを作成します(デフォルト: 16)")]
public int Bits { get; set; } = 16;

private int OnExecute()
Expand Down
5 changes: 4 additions & 1 deletion src/Toa.Core/LocalWagahighOperator.cs
Expand Up @@ -3,6 +3,7 @@
using System.IO;
using System.Reactive.Linq;
using System.Threading.Tasks;
using McMaster.Extensions.CommandLineUtils;
using WagahighChoices.Toa.X11;

namespace WagahighChoices.Toa
Expand Down Expand Up @@ -40,7 +41,9 @@ public static async Task<LocalWagahighOperator> StartProcessAsync(string directo
private void StartProcess(string directory)
{
const string exeName = "ワガママハイスペック.exe";
this._process = Process.Start("wine", "\"" + JoinPathInWindows(directory, exeName) + "\" -forcelog=clear");
this._process = Process.Start(
"wine",
ArgumentEscaper.EscapeAndConcatenate(new[] { JoinPathInWindows(directory, exeName), "-forcelog=clear" }));

var logFilePath = Path.Combine(ToUnixPath(directory), "savedata", "krkr.console.log");

Expand Down
1 change: 1 addition & 0 deletions src/Toa.Core/Toa.Core.csproj
Expand Up @@ -9,6 +9,7 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="McMaster.Extensions.CommandLineUtils" Version="2.2.5" />
<PackageReference Include="System.Buffers" Version="4.5.0" />
<PackageReference Include="System.Memory" Version="4.5.1" />
<PackageReference Include="System.Reactive" Version="4.1.2" />
Expand Down
1 change: 1 addition & 0 deletions src/Toa.Grpc/GrpcToaServer.cs
Expand Up @@ -33,6 +33,7 @@ public GrpcToaServer(string host, int port, WagahighOperator wagahighOperator)
Services = { service },
Ports = { new ServerPort(host, port, ServerCredentials.Insecure) }
};

this._wagahighOperator = wagahighOperator;
}

Expand Down
41 changes: 12 additions & 29 deletions src/Toa.Standalone/Program.cs
Expand Up @@ -9,34 +9,22 @@

namespace WagahighChoices.Toa.Standalone
{
public static class Program
[Command(Name = "toa", FullName = "Toa", Description = "ワガママハイスペック ウィンドウ操作サービス")]
public class Program
{
public static int Main(string[] args)
{
var app = new CommandLineApplication()
{
FullName = "Toa",
Description = "ワガママハイスペック ウィンドウ操作サービス",
};

app.HelpOption("-?|-h|--help");
return CommandLineApplication.Execute<Program>(args);
}

var directoryOption = app.Option(
"-d|--directory <dir>",
"ワガママハイスペック.exe が存在するディレクトリ",
CommandOptionType.SingleValue
);
[Option("-d|--directory <dir>", Description = "ワガママハイスペック.exe が存在するディレクトリ")]
public string Directory { get; set; }

var portOption = app.Option(
"-p|--port <port>",
"使用するポート番号",
CommandOptionType.SingleValue
);
[Option("-p|--port <port>", Description = "使用するポート番号(デフォルト: 51203)")]
public int Port { get; set; } = GrpcToaServer.DefaultPort;

app.OnExecute(() =>
private void OnExecute()
{
var directory = directoryOption.Value() ?? "";
var port = portOption.HasValue() ? int.Parse(portOption.Value()) : GrpcToaServer.DefaultPort;
var display = DisplayIdentifier.Parse(Environment.GetEnvironmentVariable("DISPLAY"));

// Ctrl + C が押されたときの動作を設定しておく
Expand All @@ -56,18 +44,13 @@ public static int Main(string[] args)

// サーバー開始
// 0.0.0.0 を指定: https://github.com/grpc/grpc/issues/10570
using (var wagahighOperator = LocalWagahighOperator.StartProcessAsync(directory, display).Result)
using (var server = new GrpcToaServer("0.0.0.0", port, wagahighOperator))
using (var wagahighOperator = LocalWagahighOperator.StartProcessAsync(this.Directory ?? "", display).Result)
using (var server = new GrpcToaServer("0.0.0.0", this.Port, wagahighOperator))
{
server.Start();
Log.WriteMessage("Listening " + port);
Log.WriteMessage("Listening " + this.Port);
w.WaitOne();
}
return 0;
});

return app.Execute(args);
}
}
}
14 changes: 13 additions & 1 deletion src/WagahighChoices.sln
Expand Up @@ -15,7 +15,11 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Toa.Grpc", "Toa.Grpc\Toa.Gr
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Toa.Standalone", "Toa.Standalone\Toa.Standalone.csproj", "{E7B7A49B-2FAF-4217-A3E4-D9F873D2E412}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Blockhash.Cli", "Blockhash.Cli\Blockhash.Cli.csproj", "{15BF0521-E6A2-4294-BAE5-9A2F7357D846}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Blockhash.Cli", "Blockhash.Cli\Blockhash.Cli.csproj", "{15BF0521-E6A2-4294-BAE5-9A2F7357D846}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ashe", "Ashe\Ashe.csproj", "{44BE79C7-D6D2-4D2A-A04B-BE6E7F971565}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ashe.Contract", "Ashe.Contract\Ashe.Contract.csproj", "{8A6DF50E-3B81-4D41-8E61-C00BCAADECF8}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Expand Down Expand Up @@ -51,6 +55,14 @@ Global
{15BF0521-E6A2-4294-BAE5-9A2F7357D846}.Debug|Any CPU.Build.0 = Debug|Any CPU
{15BF0521-E6A2-4294-BAE5-9A2F7357D846}.Release|Any CPU.ActiveCfg = Release|Any CPU
{15BF0521-E6A2-4294-BAE5-9A2F7357D846}.Release|Any CPU.Build.0 = Release|Any CPU
{44BE79C7-D6D2-4D2A-A04B-BE6E7F971565}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{44BE79C7-D6D2-4D2A-A04B-BE6E7F971565}.Debug|Any CPU.Build.0 = Debug|Any CPU
{44BE79C7-D6D2-4D2A-A04B-BE6E7F971565}.Release|Any CPU.ActiveCfg = Release|Any CPU
{44BE79C7-D6D2-4D2A-A04B-BE6E7F971565}.Release|Any CPU.Build.0 = Release|Any CPU
{8A6DF50E-3B81-4D41-8E61-C00BCAADECF8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{8A6DF50E-3B81-4D41-8E61-C00BCAADECF8}.Debug|Any CPU.Build.0 = Debug|Any CPU
{8A6DF50E-3B81-4D41-8E61-C00BCAADECF8}.Release|Any CPU.ActiveCfg = Release|Any CPU
{8A6DF50E-3B81-4D41-8E61-C00BCAADECF8}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down

0 comments on commit 6147f7e

Please sign in to comment.