最近、全くLinuxに触れていなかったですね。
なので、結構無理やりだけどこういうのを作ることに・・・
ちなみに、ネットでそういうのアルカナ~と調べたけどなかった。
いや。実はMCStackerにコマンドをぶち込むと勝手に変換してくれたはずなんだけど、functionみたいなファイルに数百行とかってあるコマンドを変換するとなると話は変わってくる。
というわけでシェルスクリプト自体を作って、function一括変換できるシステムを作る。
まず、変換用テストファイルを作成する。
実際に使用していたのをもとにシェルスクリプトを作ってもムラが出るからね。
ある程度基本的な変換が出来るようにして、でそっから修正を加えていく感じにする。
という訳で
テストファイルが完成しました。なんと!この時点で午後四時。
ヤバイぞ・・・時間使い過ぎ
というわけで、とっととサーバーにぶち込んで起動確認。
あ、サーバーはpaperを使用しています。Geyserとfloodgate入れて統合版からでも入れるようになってるけど、コマンドはちゃんとJava版ベースとなっております。
無事エラー吐いて読み込みませんでした。
execute関係ないけど・・・(xpコマンドの記述方式が違うので、そこが引っかかってるらしい)
というわけでやっていきませう。
※初心者なのでオブジェクト指向プログラミングとか全く意識してないのでクソコードになっております。
まず、大体で流れを決めておきたい。
スクリプトで変換したいファイルのパスを入力しておく→for i=1,i++で一行目の文字列を変数に代入する→変換する→返還後の文字列が入った変数を別のファイルにi行目に記述する
これを繰り返す。
よし、変換以外の機構をまず記述しよう
・・・あれえ
for文をシェルスクリプトで使ったことがない!!
存在しないのかな?調べるのが面倒臭いのでとりあえずwhile文で実装する。
で飽きて別記事を書いていたと。w
とりあえずここまでできた。
あとは、変換するメイン機構を作らなければ。
滅茶苦茶長くなってるので、まあ切り取りつつ紹介していく。
てか俺が見て意味が分からんからコメント行が多いw
まずはこれ。これは何をするのかというと、execute ~ってセレクター部分をまず抜き取るというところ。
maintextにはファイル一行目から文字列を収納し、一文字目が「#」ならコメント行として判断しそのまま出力し、「e」であればexecuteと記述してあるかを検証し、executeと記述されているのであればその行はexecuteコマンドの行なんだと判断し、本変換処理に移動します。
で、なんやかんやして、大まかに説明するとセレクターの部分を最初の一文字目から二文字目、三文字目、四文字目・・・と比較してって
引数の終わりである「]」記号があったとき、引数が存在せず2文字前が「@」であり、この時点で空白を検知した場合は@a @p @r @e等のどれかと判別し、セレクターの抜き取りを終了します。
ちなみに通知システムとしては、前者をoutcheck break.と通知するようにして、@であればatcheck break.として通知します。
そして一日が経過した!!!!!!!!!!
今日も開発は続く。
そんで、少し気付いたことが。declare -aで配列を作るときにSyntax errorを吐いてて、コピペしたのに実行できないし、何故・・・?と思ったら
#!/bin/sh
って記述してありました。
うわああああ!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
#!/bin/bashじゃないと・・・bashはshの改良版と言われてて、C言語ベースのcshやksh等いろいろあるんですけど有名なのはbashみたいで、
まあ、うん。設定ミス。行き詰ったら根本的に何か間違えているのではないかと疑うことも大切だという事ですね.ハイ(自己解決)
灯台下暗しって奴だ。
二日が経過した。
現在開発しているのが、座標取得エリア。
てか、マジでオブジェクト指向とまではいかないが、関数化すべきだったわ・・・
後々ダルくなるよ。
・・・。
やっぱ関数にしよ!!!!!!!!!!(また開発に時間かかる)
でも後々助かるはずだから、何とか元取れるっしょ
ただ、bashだと関数を呼び出す「前に」存在させないといけないという制約があるので(C言語なら後述しても使えるが、この制約は一括で変換してくれないインタプリタだからだろう)場所をちゃんと考えておきます。
セレクター部分の抜き取りを行う関数をまず記述しました。
何故かemptyCheckがmptyCheckになってたけど、そこさえ修正したらちゃんと動作しました。
あと、問題は、だ。
座標取得において配列を扱おうとしてたら見事にミスってたね
配列Pos3[0]から順次格納していくって流れを作ったはずなんだけど、どういう訳かPos3[1]にYとZでそれぞれ別に入るはずの値が一緒に入っている。
ちなみにこれはexecute セレクタ 座標 commandの「座標」の部分です。抜き取ってpositioned 座標 として移植します。
「配列~ ~ ~ Z」という出力だけ見ると、「配列の要素数がXYZの3つじゃなくて、何故か4つになってZが移動している・・・!?」と解釈できてしまってこんがらがっていたわけだが、冷静に考えりゃそんなことあり得ないし分かる事だった。
じゃあ何が問題化というと、if [ "$posCheck" = " " ]; thenに入れていないから無限ループが起きているという事。
ちなみにアレイカウントが2になっていて、3になっていないので、すなわちifで空白検知する上記文が二回しか検知できていないのが問題点。
~ ~ ~という座標において、
アレイカウントが2になった時点で文字数が
あ・・・・分かったわ
文字数カウントをリセットしていない。
どういうことかというと、
123456748904 という文字列において、「4が来たら順に配列にぶち込む」という処理の場合、1234 5674 8904 の三つの要素として保存しなければならない。
私はそのために、1234の4の時点で文字数カウントが4なので、cutコマンドで1から4文字目を切り取り、その後削除処理してるんですね。
で、何かというと、削除処理後のテキストは56748904という文字列になるのですが、この状態で文字数カウントを初期化していないので5文字目以降から4がどこにあるかを検索し続けるんですね。
56748904 の8の部分から右に検索が逝ってしまうわけですね。
やっと今理解できた。
if文は言った時点でposCnt=0するようにしてみる。
成功!!!!!!
ちなみに、空白の数を検知しているので座標が直接指定してあっても対応できる。
ただ、私はexecute セレクタ ~ ~ ~ コマンド って記述方法が基本なんだけど、稀に省略してexecute セレクタ ~~~ コマンド
と空白を省略して記述している人も居るんですよね。
~~1~とかになるとさらに検知が面倒臭すぎるので、
~~という文字列を検出したら空白を入れる分を追加してみるかな。
…と思ったが、これは今度にしよう。私は省略技法は全く使用していないので、この処理が出来れば私が持つfunctionの変換では困らないだろう。
じゃあ次は、execute重ね掛け技法とdetect処理を実装しなければ。
セレクタと実行座標を抜き取った後、さらにcaseしませう。
座標を抜き取りました-- detect ~ ~-1 ~ stone 0 say 基本�
と出力されていたので、この二つの関数を実行した後1-6文字をカットしてdetectと記述してあればまた別の処理を実行する、という感じに。
「別の処理」は完全にpull_positionと同じ
ただ、そのまま使いまわすとif条件式だったり配列管理がだるいので、全く同じ関数を作り全て名前にdetect_を付けて別者として処理するようにしてみる。
ついでにブロックID取得もこの関数内で完結させよう。
できた。
detectはブロックIDも取得してるので関数名をpull_detect_positionからpull_detectに変更しておこう。こちらの方がわかりやすい。
execute @a[r=5,rm=0] ~ ~ ~ detect ~ ~-1 ~ stone 0 say 基本羅列変換10
この文字列から、
この要素が抜き取れるようになった。
ふへへ('ω')
でだ。ついにいよいよ最終処理の「コマンド構築」が始ま
らない。
引数にも一部互換性が粉砕されていたのだ。
こちらも関数を作っておこう。
後、この記事は前編として出すことにした。説明は後編で、完成した後に行う感じで。
前編はまあ、苦しい開発時の独り言って感じになるんかね?w
functionでargument_convertっていうのを作る。argumentっていうのは引数って意味があり、セレクター内の引数について、変換の必要がある場合は変換を行うもの。
・・・あれ?別にpull_selector関数の末端にぶち込んでも良くね?
・・・・・・・・。
いや、多分クソ長コードになるので一応分割しておきましょ。ハイ。
引数表についてはこちらを参照する。(ちなみにマイクラのフレンドが記述した記事。)
関数についちゃ結局大本のトリガーが「executeコマンドだと識別した場合」に関数を実行して(pull_selector,pull_position)、必要に応じて別の関数(pull_detect)も呼び出しているので、selectorには現在処理中のexecuteコマンド変換のために利用するセレクターをそんままひっぱってきて編集し再構築するって流れになるかな。
いきなりそのままselector変数は持ってくる(ただしこの関数はpull_selector関数より後に呼び出す。)
argCheckとしてテスト出力。これは、Selector変数に入っているセレクター記述情報の前から3文字目をカットしたもの。
セレクターは@a.@r.@e.@p.@sもしくはそれ以降に[引数]で追加記述するパターンのみとなる。
なので、三文字目が空白なら引数無し、三文字目が「[」なら引数ありと判断できる。
引数をどうやって確認し置き換えるか。これが問題だ。
今まで通りの方法で行くかねえ~~
で、コンマが必ず次引数に行くときに存在するのでそれを目安にしよう。
引数最初の2文字を確認すればある程度目星が付くので、識別できなければif文で処理しよう。ザーッと書く。
左側 変換後
右側 変換前
まあ拡大してもらえりゃわかると思うんですが・・・
○コメント行の出力がバグっている
○すべての行で末尾数十文字が消滅している
○コメントじゃない行全てexecuteにされている(scoreboardコマンドのライン等も)
しかし、超大方には出来てきたかなって感じ
execute @a[name="Nekoyama 030330",tag=!sushi] ~ ~ ~ say 基本羅列変換8
execute @a[m=!adventure,scores={test987j9uq34=!7..23}] ~ ~ ~ say 基本羅列変換9
execute @a[r=5,rm=0] ~ ~ ~ detect ~ ~-1 ~ stone 0 say 基本羅列変換10
を変換スクリプトに掛けた結果が画像の通り。
分かる人にはわかると思うんだけど、結構型的にはできあがってきてるんよね。detectもif blockサブコマンドで記述できているし。
後は!!!!!!後日!!!!!!!やります!!!!!!!!!!!!!!!!!!
VSCodeで見たらクソ長手書きコードになってた。
しかしまだ完成には程遠い。
続編は後程、いつか、機会があれば、モチベがあれば、飽きてなければ、Apexに再燃してなければ、多分、きっと、おそらく、もしかしたら
続きます(?)
※ちゃんと完成させます。
今日四月十日なのに、この記事書き始めたの四月七日になってた。どんだけ時間かけてんだ・・・
この記事へのコメント
JosephSakly