(失敗)Among UsのMod開発のために、Hazelをプロジェクトに組み込む
あとがき注意
この手順を踏んでも目的としていた問題の解決は達成できませんでした。
はじめに
AmongUsのModを開発する際に、プレイヤーの挙動を模倣するために新たにコネクションを作成したいタイミングがあった。
が、ConnectionのMessageReceiverの設定で Action<DataReceivedEventArgs> 型が登場する。
この Action<T> 型のキャストがUnhollowerでは曲者で、 () => {} に変換されてしまう。
どうなるかというと、引数が捨てられず割り当てられるどうしようもなくなってExceptionを吐く。
じゃあどうするか、Unhollower経由でAmongUsのHazelではなく、
オリジナルのHazelを追加して実行しようという作戦。
Hazelをsubmoduleとしてソリューションに追加する
AmongUsで使われているHazelはこれっぽい。
NuGetがあれば楽に取り込めたかもやけど、どうもなさそうなので、
gitのsubmodule機能を使ってソリューションの中に入れてしまって、
依存関係にソリューション内のプロジェクトを入れてしまうことで解決する。
$ git submodule add git@github.com:willardf/Hazel-Networking.git NpcMode.Hazel
みたいな感じで、NpcMode.Hazelディレクトリに、Hazelのソリューションを取り込んだ。
そもそもgit submoduleとは?というと、別のgitリポジトリを、自分のgitリポジトリの一部のように使う機能で、
設定した時点でのコミットを参照するかを設定することで、gitで依存関係を解決する方法。
分かりやすい記事があったので詳しく知りたい人はどうぞ。
依存関係の解決と名前重複の解決
submoduleで取ってきたHazelへの参照を追加します。
.csprojを直接触ってもいいけど、IDE経由で触ったほうが補完的にも便利なのでIDE経由でやる。
IDEはJetbrains製のRiderやけど、多分他のIDEでも同じようにできると思う。
ExplorerをSolutionにし、ソリューションを右クリック > Add > Add Existing Project を選択する
https://scrapbox.io/files/61b39d90bf6ec300233874b1.png
submoduleで取ってきた NpcMode.Hazel/Hazel/Hazel.csprojを選択する
これで、ソリューション内の一つのプロジェクトとして扱えるようになる
依存したいプロジェクトを右クリック > Add > Add Reference を選択する
https://scrapbox.io/files/61b39e5eea382d001d29b0ad.png
Hazelが選べるようになっているので、Hazelを選んで Add する
https://scrapbox.io/files/61b39e8b65e1e10022913fe2.png
さて、新しいHazelを読み込めるようになったけど、unhollowerが吐いたHazelとぶつかってて、
use Hazel しても読み込みたい方が読み込めない。
こうなると、どちらかに別名を付けるしかない。
<Reference Include="$(AmongUs)/BepInEx/unhollowed/*.dll"/> を
code:.csproj
<Reference Include="$(AmongUs)/BepInEx/unhollowed/*.dll">
<Aliases>bepinex</Aliases>
</Reference>
という感じで、別名を付けるようにする。
プロジェクトごと読み込んでる <ProjectReference Include="..\NpcMode.Hazel\Hazel\Hazel.csproj"/> でもAliasは使えそう。
別名を付けたので、.csでuseするときにも変更が必要。
code:.cs
extern alias bepinex;
using AmongUsClient = bepinex::AmongUsClient;
namespace NpcMode
{
public class Npc
{
private readonly AmongUsClient _client;
}
}
という感じで、aliasのbepinexを使うと、AmongUsClientはbepinex::AmongUsClientを使うよってのと書いてあげる必要がある。
冗長やけど、しゃーないね。
.NET Framework 4.5をインストールする
Hazelは.NET Framework 4.5をターゲットにしてる。
ってことで、.NET4.5を入れよう!!!
と言ってもそんな楽にはいかない。
まず、2021/12/11時点で4.5のDeveloper Packが公式から提供されていない。
4.5.1とか、4.5.2はあるのに。
ってことで別の方法でとる必要がある。
C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework ディレクトリがない人は、
まずこのディレクトリを作るところからやけど、このディレクトリは.NET Frameworkをインストールしたときに作られる。
なので、適当な.NET Frameworkをインストールする必要がある。
僕は試行錯誤の際に.NET Framework4.5.2をいれた。
Developer Packがあればどのバージョンでもいい。
インストールが終わったら、
C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework
に、インストールしたバージョンのディレクトリがあることを確認する。
次に4.5自体を取ってくる。
Download Package というところから圧縮された状態でとってこれる。
これをZIP解凍すれば、解凍したディレクトリ/build/.NETFramework/v4.5として取れる。
このv4.5を C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework に設置すればOK。
IDEを再起動でもしたら.NET Framework 4.5のパスが解決されるようになる。
同じ簡易名の解決
さあ、いざコンパイル!ってなってまだエラーがでる。
下記2つはcoreとunhollowedの両方にあって、基本的にはunhollowedを見ておけば問題ない。
たぶん、Aliasをちゃんと指定していないところがあるんだと思う。
UnhollowerBaseLib.dll
UnhollowerRuntimeLib.dll
下記は新たにパッケージを追加したことによる重複。
読み込みたくないから、Excludeで吹き飛ばす。
Hazel
code:.csproj
<Reference Include="$(AmongUs)/BepInEx/unhollowed/*.dll" Exclude="$(AmongUs)/BepInEx/unhollowed/Hazel.dll">
<Aliases>bepinex</Aliases>
</Reference>
コンパイル通るようになったはず。
おわりに
この手順を踏んでも何にも解決しません!
なんていうかさ、期待してたのは、
サブプロジェクトのソースも含んだ大きなDLLを作ってくれると思ってた。
でも実際は、サブプロジェクトのDLLと別に、作ったDLLが生成されるだけ。
そうなると、どのDLLに依存するかはDLLの利用側の解釈に委ねられてしまって、
結局意図しないDLLが読み込まれて意図しない関数に渡されちゃう。
C#むずかしいね
参考
更新履歴