前回投稿した内容(Discord(Vesktop)でFlatpak経由のRPCを取得してみる)の調査中にMinecraftのmodpackであるATM(AllTheMods)のDiscord RPCがおかしな挙動をしていることに気が付いた。
ATM9、ATM10でこの問題を再現することができた。
問題点
/run/user/$UID/discord-ipc-* が UNIXソケットではなく通常ファイルとして次々作られ、DiscordクライアントがRich Presenceを取得できない。
画像のdiscord-ipc-0はDiscordによって生成された通常のソケットだが、1-9はこの事象によって生成されたファイルだ。

既に存在しているソケットの上書きは行われないものの、ソケットが作成される前に通常ファイルが作成されてしまった場合、Discordクライアントはソケットを作成することができず、結果としてRPCを取得できなくなってしまう。
また、このファイルはゲームを終了しても削除されないため手動で削除を行わないかい限り問題は修正されないという厄介な性質を持っている。
対処方法
AllTheMods環境ではAllTheTweaksがDiscord RPCとの仲介を担っているため、このModのconfigを変更し機能を無効にすることで対処することができる。
# /config/allthetweaks-common.toml
[discord]
#Enable Discord Rich Prescence
discord = false
また、問題点セクションで記載があるようにすでに生成されてしまっているファイルに関しては手動で削除する必要がある。
プロセスがネイティブ環境で実行されている場合
/run/user/$UID/discord-ipc-*
プロセスがFlatpak+discord-flatpak-rpc-bridge環境で実行されている場合
/run/user/$UID/app/com.discordapp.Discord/discord-ipc-*
挙動
上記の設定で問題は解決するのだが、せっかくなのでどのような挙動をしているのか調べてみた。
AllTheTweaksのjarファイルを調査したところ、依存ライブラリとしてDiscordIPCをバンドルしていることがわかった。
https://github.com/jagrosh/DiscordIPC
WindowsPipe.javaを確認すると以下のようなコードが存在した。
// /tree/master/src/main/java/com/jagrosh/discordipc/entities/pipe/WindowsPipe.java
WindowsPipe(IPCClient ipcClient, HashMap<String, Callback> callbacks, String location) {
super(ipcClient, callbacks);
try {
this.file = new RandomAccessFile(location, "rw");
} catch (FileNotFoundException e) {
throw new RuntimeException(e);
}
}
RandomAccessFile(location, “rw”) は、指定パスが存在しなければ 通常ファイルを新規作成し、読み書きで開く。
そのためLinux 上でdiscord-ipc-*を ソケットではなく”通常ファイル”として量産する。
今回の挙動と一致しているため、おそらく何らかの理由によりLinuxで起動しているにもかかわらず、本来呼ばれるはずのUnixPipeではなくWindowsPipeが呼ばれてしまっているのだろう。
ATM9のJVM OSログを出力してみたがos.name = Linux, os.arch = amd64と出力され、Windowsとして認識されているわけではないためUnixPipe が呼ばれず WindowsPipe が呼ばれる理由は未解明である。
おわり
Javaについての知識が乏しいため今回はこの程度の調査になってしまったが、いずれ原因を特定したい。