1回だけ発動するClickEventを作る ~Spigot~
ちょっとしたメモ程度に書くことにします。
初めての投稿なので読みにくくなってしまっているかもしれませんがどうぞ。
ClickEventが何度も発動してしまう
「一度だけクリックして処理を行うことのできるチャットメッセージ」を送信できるようにしたいなと思い様々なところのスレッドを覗いてみて、どうにかこうにか
- クリックしたら様々な処理が実行されるメッセージ
を作成することができた。
しかしそのメッセージはクリックされると何度でも処理を行ってしまう。
一度だけ行いたい処理を任せようと思っていたがこれではいけない。
「only once」など私の貧相なボキャブラリの中から絞り出した英単語を並べて検索をしてみるも、Javaに触れ始めて1週間も経っていない私にはなんだか難しい魔法の解説をしているようにしか見えなかった。
早い話が理解することができなかったのだ。
というわけで、無い頭からアイデアを絞りだしてどうにかこうにか形になるものを作ってみたので書き残してみる。
ClickEventと独自コマンドのリレー
これから説明する方法はClickEventを何度も発生させる。
しかしその先の処理にちょっとした細工をすることで目的の処理を一度しか発動しないようにしてみた。
流れとしては
- 引数を複数個持ったコマンドを作成
- UUIDを生成
- setClickEventのClickEvent.Action.RUNCOMMANDを用いてクリックされた時に実行するコマンドを作成
(この時、実行するコマンドにUUIDを引数として記述)
となる。
核となる0のみ解説をしていく。
まず0の「引数を複数個持ったコマンドを生成」について。
これは2で実行されるコマンドとなる。
ちなみにこいつが今回のミソである。
引数を複数個持つ、と書いたが実際にはUUIDのみを引数に持つ、でも構わない。
どのようなコマンドにするか自分と相談して引数の個数は決めよう。
肝心の処理部分はというと
1, (引数で送り込まれてきたUUID).txt という名前のファイルが存在するかチェック
2, 1で存在すると返ってきたらreturn false;で処理を抜ける。
以下2でファイルが存在しないと返ってきたときの処理↓
3, 行いたい処理をここに記述
4, (引数で送り込まれてきたUUID).txt という名前のファイルを作成
というような構造になっている。
要するに「UUIDをメッセージに割り振り、目的の処理を実行したら生成されるテキストファイルの有無で処理を変えている」ということである。
なぜファイル名で判定するのか
ファイルの中身を読むよりも処理が速く済みそうだったからです。
それ以上の理由はありません。(浅はか)
さいごに & 書き忘れの補足
もちろんClickEventから実行されるコマンドはplugin.ymlのdefaultをtrueにしなくてはならない。
加えて、そのまま放置していては膨大な量の中身のないテキストファイルが生成されてしまうのでonDisable時に生成したファイルを消去するようにしたりしなくてはならないだろう。
UUIDを用いているのでユーザーが自由にアクセスできるコマンドとはいえ悪用されることはほぼないと言っていいところが数少ない利点なのかもしれない。
※クリックされただけClickEventが出るので、画面上では最初の1回以外反応していないように見えるもののサーバーコンソールにはissued server commandのログがめちゃくちゃ吐かれてたりします。
5/30追記分
読み返してみたらめちゃくちゃ分かりづらいような気がするので近いうちに書き直してみようと思います。
日本語へたっぴでごめんなさい。