環境
- Paper API :
1.20-R1-SNAPSHOT
- JDK :
JDK 17
Paper API は基本的に Spigot API と互換性がありますが、一部機能については独自の実装がされています。
そのため、本記事に掲載しているコードをそのまま使用しても動作しない恐れがあります。その場合は Spigot の公式 JavaDoc をご確認の上ご利用ください。
カスタムヘッド(Custom Head)とは?
プレイヤーの頭やゲーム内に存在するモブ以外の絵柄の頭のこと。
Minecraft-Heads などに多数掲載されています。
頭を描画するには
(実在する)プレイヤーの頭を描画するには以下のコードだけで済みます。
// name = プレイヤー名を示す文字列
ItemStack head = new ItemStack(Material.PLAYER_HEAD);
SkullMeta skullMeta = (SkullMeta) head.getItemMeta();
skullMeta.setOwningPlayer(Bukkit.getOfflinePlayer(name));
head.setItemMeta(skullMeta);
カスタムヘッドを描画するには
最終的に SkullMeta#setPlayerProfile(profile);
でプレイヤー情報 (PlayerProfile
) を SkullMeta へ登録することになります。
そのために
- PlayerProfile の作成
- PlayerTextures の作成
- SkullMeta へ情報を登録
の3段階を踏む必要があります。
PlayerProfile の作成
PlayerProfile はプレイヤーの UUID, 名前、テクスチャなどのデータを持つクラスです。
PlayerProfile profile = Bukkit.createProfile(null, UUID.randomUUID().toString());
Bukkit#createProfile
より取得します。第 1 引数はプレイヤーの UUID, 第 2 引数はプレイヤーの名前を示します。
今回は実在しないプレイヤーのデータを作成するので UUID を入れておきます。
(Bukkit#createProfile
は 2 つある引数のどちらかが null 以外であれば大丈夫なので、適宜設定してください。)
これらの引数は画像データをキャッシュとして保存する際のキーとして、また、完成時の「~~~ の頭」というアイテム名に使用されます。
(そのため、ランダム性を持った UUID を使用することが好ましいです。)
PlayerTextures の作成
文字通りプレイヤーのテクスチャに関するデータを持つクラスです。
スキンの種類(CLASSIC, SLIM)、マント、スキンに関してのデータを持ちますが、後ろ 2 つに関しては生の画像データではなく、画像が置かれている URL になります。
カスタムヘッドの絵柄を指定するにはMinecraft-Heads の For Developers セクションの Value を使用するのですが、これはテクスチャが置かれている URL を含んだ json データを Base64 でエンコードしたものになります。
そのため、Base 64 でデコードしてから正規表現で URL のみを抜き出しています。
// urlStr = 描画したいカスタムヘッドの URL (Base64 でエンコード済み)
PlayerTextures texture = profile.getTextures();
URL url;
try {
String prepare = new String(Base64.getDecoder().decode(urlStr));
// {"textures":{"SKIN":{"url":"テクスチャの URL"}}}
Matcher matcher = Pattern.compile("[\"{a-zA-Z:]+(http://[a-zA-Z0-9./]+)[}\"]+").matcher(prepare);
if (!matcher.matches()) return;
url = new URL(matcher.group(1));
} catch (Exception e) {
e.printStackTrace();
return;
}
texture.setSkin(url);
SkullMeta と PlayerProfile に情報を登録する
作成した PlayerTextures を PlayerProfile に設定し、そのまま SkullMeta に登録します。
profile.setTextures(texture);
meta.setPlayerProfile(profile);
head.setItemMeta(skullMeta);
終わりです。
終わりに
初めてカスタムヘッドを呼び出す際にデータを取りに行ってキャッシュを作成する時間 (1 秒くらい?) があるので、可能であればプラグインの起動時にまとめてロードさせると良いでしょう。
やり方を調べてみても海外勢が「自分のライブラリを使って!」としか言っていなかったので、1時間ほど JavaDoc とにらめっこしながら書きました。詳しく書かれているわけでもなかったのでかなり疲れました。