ページ 1 / 2
【解決】メインメニューを改変するプラグイン:YEP Main Menu Manager分解
Posted: 2020年3月12日(木) 19:25
by ムノクラ
メインメニューを改変するプラグイン:YEP Main Menu Manager分解
YEP Main Menu Managerにあるコマンドウィンドウを改変する機能のプラグインを希望いたします。
同じ機能のプラグインの情報もお待ちいたします。
https://fungamemake.com/archives/8238
自分で作ってみたプラグインがあります。
概ね、考えたとおりに作れたのですが、下記プラグインと競合してしまいました。
▼メニュー画面のサブコマンド(トリアコンタン様作)
https://raw.githubusercontent.com/triac ... Command.js
プラグインの並び順を
MNKR_MenuCommand
MenuSubCommand
にすることで、解消は出来ました。
しかし、同じようにメインメニュー画面を大きく変える下記のプラグインと「メニュー画面のサブコマンド」とは上下関係なく競合しませんでした。
▼Simple Menu Layout(ツミオ様作)
https://raw.githubusercontent.com/Tsumi ... uLayout.js
そんな訳で、他のメニュー関連のプラグインと競合しにくい作りのプラグインを希望いたします。
下記2つには対応いただきたいです。
メニュー画面のサブコマンド(トリアコンタン様作)
https://raw.githubusercontent.com/triac ... Command.js
コモンコマンド(tomoaky様作)
https://hikimoki.sakura.ne.jp/plugin/TMCommonCommand.js
プラグインの作成方法を学ぶために質問に書くべきかを迷いましたが、自分はプラグインのコードを読んで比較して覚えるタイプと思うので、こちらに投稿いたしました。
よろしくお願いいたします。
Re: メインメニューを改変するプラグイン:YEP Main Menu Manager分解
Posted: 2020年3月12日(木) 21:23
by Plasma Dark
プラグインの並び順を
MNKR_MenuCommand
MenuSubCommand
にすることで、解消は出来ました。
競合の原因を探るためには、当然ですが競合しているプラグイン同士のコードを見比べる必要があります。
今回の競合の原因はまず、 Window_MenuCommand.prototype.initialize の再定義部分にあります。
先頭で Window_Command.prototype.initialize を呼び出していますが、これをすると先に読み込んだプラグインで定義された Window_MenuCommand.prototype.initialize をすっ飛ばしてしまいます。
ですので、面倒かとは思いますが、しっかり Window_MenuCommand.prototype.initialize を控えておいて、それを呼び出したほうが良いでしょう。
コード: 全て選択
const _Window_MenuCommand_initialize = Window_MenuCommand.prototype.initialize;
Window_MenuCommand.prototype.initialize = function () {
_Window_MenuCommand_initialize.call(this, eval(WindowX), eval(WindowY));
};
ただ、ここまでやっても MenuSubCommand (2.7.0) とはまだ競合します。
MenuSubCommand では Window_MenuCommand.prototype.initialize が引数を無視するように再定義されてしまっているため、せっかくウィンドウの位置を渡しても捨てられてしまうのです。
これは MenuSubCommand 側の問題ですので、あちらに修正PRを送るか、issueでも立てて直してもらうのが筋ですね。
ついでにコードレビューしてしまうと、eval周りにバグがあります。
Stringの中身、右側にデフォルト値を書くのは良いのですが、カッコの中は先に評価されるため、クォートなりダブルクォートなりで囲んでしっかり文字列にしてあげないと、デフォルト値が評価されるタイミングでエラーになります。(実は、ここが評価されるタイミングはあんまりないんですが)
また、ゲームでほとんど問題になることはないかと思いますが、evalはバグや脆弱性の温床なので、あまり使用をオススメしたくはありません。
Re: メインメニューを改変するプラグイン:YEP Main Menu Manager分解
Posted: 2020年3月13日(金) 00:46
by トリアコンタン
こんにちは!
ご指摘の件は、『メニュー画面のサブコマンドプラグイン』の実装ミスのため修正しました。
ご確認ありがとうございました!
2.7.1 2020/03/13 Window_MenuCommandの初期化で引数を渡し忘れていたのを修正
https://raw.githubusercontent.com/triac ... Command.js
Re: メインメニューを改変するプラグイン:YEP Main Menu Manager分解
Posted: 2020年3月13日(金) 08:09
by ムノクラ
Plasma Dark さんが書きました:
競合の原因を探るためには、当然ですが競合しているプラグイン同士のコードを見比べる必要があります。
今回の競合の原因はまず、 Window_MenuCommand.prototype.initialize の再定義部分にあります。
先頭で Window_Command.prototype.initialize を呼び出していますが、これをすると先に読み込んだプラグインで定義された Window_MenuCommand.prototype.initialize をすっ飛ばしてしまいます。
ですので、面倒かとは思いますが、しっかり Window_MenuCommand.prototype.initialize を控えておいて、それを呼び出したほうが良いでしょう。
コード: 全て選択
const _Window_MenuCommand_initialize = Window_MenuCommand.prototype.initialize;
Window_MenuCommand.prototype.initialize = function () {
_Window_MenuCommand_initialize.call(this, eval(WindowX), eval(WindowY));
};
ただ、ここまでやっても MenuSubCommand (2.7.0) とはまだ競合します。
MenuSubCommand では Window_MenuCommand.prototype.initialize が引数を無視するように再定義されてしまっているため、せっかくウィンドウの位置を渡しても捨てられてしまうのです。
これは MenuSubCommand 側の問題ですので、あちらに修正PRを送るか、issueでも立てて直してもらうのが筋ですね。
ついでにコードレビューしてしまうと、eval周りにバグがあります。
Stringの中身、右側にデフォルト値を書くのは良いのですが、カッコの中は先に評価されるため、クォートなりダブルクォートなりで囲んでしっかり文字列にしてあげないと、デフォルト値が評価されるタイミングでエラーになります。(実は、ここが評価されるタイミングはあんまりないんですが)
また、ゲームでほとんど問題になることはないかと思いますが、evalはバグや脆弱性の温床なので、あまり使用をオススメしたくはありません。
ご指導いただき、ありがとうございます。
内容は半分くらいは理解できた?と思います。
試行錯誤した結果、指摘された箇所の競合対策とそれ以外も(必要かどうかは分かりませんが)同様の処理を追加することが出来ました。
また、潜在的なバグについても理解できたと思います。
evalが推奨されないとなると、代替手法があると思うのですが、それは複雑化してしまうので、ここで書かれていないのでしょうか?
パラメーターで式を使えるようにするのに、ベターな方法があればご指導ください。
Re: メインメニューを改変するプラグイン:YEP Main Menu Manager分解
Posted: 2020年3月13日(金) 08:10
by ムノクラ
Re: メインメニューを改変するプラグイン:YEP Main Menu Manager分解
Posted: 2020年3月13日(金) 12:27
by Plasma Dark
試行錯誤した結果、指摘された箇所の競合対策とそれ以外も(必要かどうかは分かりませんが)同様の処理を追加することが出来ました。
また、潜在的なバグについても理解できたと思います。
完全に上書きすると競合しやすくなるのは事実ですが、処理的に上書きせざるを得ないというか、元の処理を呼び出したところで意味がなかったり、かえってバグってしまうこともあるので、考えなしに追加すれば良いものではないというところはご注意ください。
evalが推奨されないとなると、代替手法があると思うのですが、それは複雑化してしまうので、ここで書かれていないのでしょうか?
パラメーターで式を使えるようにするのに、ベターな方法があればご指導ください。
代替があるというより、可能な限り使用箇所を減らしたほうが良い、ということです。
evalそのものはコアスクリプトでもダメージ計算で使われていたりしますし、RPGツクールMV製ゲームであればevalの脆弱性で問題になることは(よっぽど変な使い方をしない限り)まずないので、絶対使っちゃいけないというものではないです。
ですが、例えばメニュー画面の maxCols や numVisibleRows の戻り値を動的に変える必要があるでしょうか。
メニュー画面はゲームにおいて頻繁に開かれる場所ですので、コロコロ変わってしまってはプレイヤーの混乱を招きかねません。
本当にevalを使うべき場所であるかどうか注意深く検討した上で、それでも必要であった場合のみ使うべきだと考えています。
Re: メインメニューを改変するプラグイン:YEP Main Menu Manager分解
Posted: 2020年3月13日(金) 12:40
by ムノクラ
Plasma Dark さんが書きました:試行錯誤した結果、指摘された箇所の競合対策とそれ以外も(必要かどうかは分かりませんが)同様の処理を追加することが出来ました。
また、潜在的なバグについても理解できたと思います。
完全に上書きすると競合しやすくなるのは事実ですが、処理的に上書きせざるを得ないというか、元の処理を呼び出したところで意味がなかったり、かえってバグってしまうこともあるので、考えなしに追加すれば良いものではないというところはご注意ください。
evalが推奨されないとなると、代替手法があると思うのですが、それは複雑化してしまうので、ここで書かれていないのでしょうか?
パラメーターで式を使えるようにするのに、ベターな方法があればご指導ください。
代替があるというより、可能な限り使用箇所を減らしたほうが良い、ということです。
evalそのものはコアスクリプトでもダメージ計算で使われていたりしますし、RPGツクールMV製ゲームであればevalの脆弱性で問題になることは(よっぽど変な使い方をしない限り)まずないので、絶対使っちゃいけないというものではないです。
ですが、例えばメニュー画面の maxCols や numVisibleRows の戻り値を動的に変える必要があるでしょうか。
メニュー画面はゲームにおいて頻繁に開かれる場所ですので、コロコロ変わってしまってはプレイヤーの混乱を招きかねません。
本当にevalを使うべき場所であるかどうか注意深く検討した上で、それでも必要であった場合のみ使うべきだと考えています。
こちらの返信を読む前に、色々いじったものをアップします。
1.プラグインパラメーターの初期値指定を修正しました。
2.Window_MenuCommand.prototype.initialize 以外にもconst処理を入れました。
これは、return で返してしまっているので、あまり効果がないかもしれませんが、同じ関数を使っているプラグインと競合した時にエラー回避くらいにはなるかな?という考えです。(合ってますか?)
同じ関数の置き換え処理がされているプラグインがある場合、プラグイン管理で下にある方が上書きされると解釈していますが、合っているのでしょうか?
3.初期ウィンドウのY位置をコマンド表示とウィンドウサイズに合わせて最下部に表示したいのですが、どうしても連動した動作をする式が作れませんでした。
もし現状で「この式で動く」というものがありましたら、ご指導ください。
おっしゃるとおり、メニューの位置や項目数が色々変わるというのは、考えにくいですね…。
機能に囚われて思考が「選択肢が多いほうが良いんだろ」というYEP的な方向に向いてしまっていたようです。
後ほど、再考します。
2.については、全く効果がないのでしょうか?
Re: メインメニューを改変するプラグイン:YEP Main Menu Manager分解
Posted: 2020年3月13日(金) 13:27
by Plasma Dark
1.プラグインパラメーターの初期値指定を修正しました。
LGTM
2.Window_MenuCommand.prototype.initialize 以外にもconst処理を入れました。
これは、return で返してしまっているので、あまり効果がないかもしれませんが、同じ関数を使っているプラグインと競合した時にエラー回避くらいにはなるかな?という考えです。(合ってますか?)
.call(this); が抜けているので、何も呼ばれない気がします。
maxCols や numVisibleRows は値を返す以外に何もしないというか、するべきでない関数なので、完全に上書きしてしまうくらいでも良いと思っています。
あるいは、プラグインパラメータで設定されるデフォルト値を空にしておいて、空だった場合は上書き前の関数を呼んでその戻り値を返す、としても良いかと思います。
いずれにせよ、何も考えずに上書き前の関数を控えて呼び出すだけ、というのは筋が良くないというか、これで回避されるような競合であればむしろそちらが悪いので、わざわざ対応してあげないほうが良いまであります。
同じ関数の置き換え処理がされているプラグインがある場合、プラグイン管理で下にある方が上書きされると解釈していますが、合っているのでしょうか?
この認識は正しいです。
3.初期ウィンドウのY位置をコマンド表示とウィンドウサイズに合わせて最下部に表示したいのですが、どうしても連動した動作をする式が作れませんでした。
もし現状で「この式で動く」というものがありましたら、ご指導ください。
Graphics.boxHeight - this.windowHeight() になるんじゃないでしょうか。
ゴールドウィンドウとかぶってしまうので、そこは工夫しないといけないですが。
そして、ウィンドウの位置を設定する汎用的なプラグインが実はすでに存在します。
トリアコンタンさんの GraphicalDesignMode.js に任せて、ウィンドウ位置は特に設定させなくても良いと割り切ってしまう手もありだと思います。
https://github.com/triacontane/RPGMaker ... ignMode.js
Re: メインメニューを改変するプラグイン:YEP Main Menu Manager分解
Posted: 2020年3月14日(土) 16:19
by ムノクラ
Plasma Dark さんが書きました:1.プラグインパラメーターの初期値指定を修正しました。
LGTM
2.Window_MenuCommand.prototype.initialize 以外にもconst処理を入れました。
これは、return で返してしまっているので、あまり効果がないかもしれませんが、同じ関数を使っているプラグインと競合した時にエラー回避くらいにはなるかな?という考えです。(合ってますか?)
.call(this); が抜けているので、何も呼ばれない気がします。
maxCols や numVisibleRows は値を返す以外に何もしないというか、するべきでない関数なので、完全に上書きしてしまうくらいでも良いと思っています。
あるいは、プラグインパラメータで設定されるデフォルト値を空にしておいて、空だった場合は上書き前の関数を呼んでその戻り値を返す、としても良いかと思います。
いずれにせよ、何も考えずに上書き前の関数を控えて呼び出すだけ、というのは筋が良くないというか、これで回避されるような競合であればむしろそちらが悪いので、わざわざ対応してあげないほうが良いまであります。
同じ関数の置き換え処理がされているプラグインがある場合、プラグイン管理で下にある方が上書きされると解釈していますが、合っているのでしょうか?
この認識は正しいです。
3.初期ウィンドウのY位置をコマンド表示とウィンドウサイズに合わせて最下部に表示したいのですが、どうしても連動した動作をする式が作れませんでした。
もし現状で「この式で動く」というものがありましたら、ご指導ください。
Graphics.boxHeight - this.windowHeight() になるんじゃないでしょうか。
ゴールドウィンドウとかぶってしまうので、そこは工夫しないといけないですが。
そして、ウィンドウの位置を設定する汎用的なプラグインが実はすでに存在します。
トリアコンタンさんの GraphicalDesignMode.js に任せて、ウィンドウ位置は特に設定させなくても良いと割り切ってしまう手もありだと思います。
https://github.com/triacontane/RPGMaker ... ignMode.js
再考すべき点が多数あると自覚しました。
まずは、このままの仕様で指摘された明らかなバグを修正しました(したつもり…)。
こちらをレビューいただければ幸いです。
Re: メインメニューを改変するプラグイン:YEP Main Menu Manager分解
Posted: 2020年3月14日(土) 23:11
by ムノクラ
多分、これで完成と考えています。
バグがないかレビューをお願いいたします。
コード: 全て選択
/*:
* @param Max Cols
* @text 横コマンド数
* @type number
* @min 1
* @desc ツクールデフォルト:1
* @default 2
*
* @param Command Alignment
* @text コマンド行揃え
* @type select
* @option 左
* @value left
* @option 中央
* @value center
* @option 右
* @value right
* @desc 左:left / 中央:center / 右:right
* ツクールデフォルト:left
* @default left
*
* @plugindesc メインメニューのコマンドウィンドウの表示を設定します。
* @author munokura
*
* @help
* メインメニューのコマンドウィンドウの表示を設定します。
*
* プラグインコマンドはありません。
*
* 他の要素については「GUI画面デザインプラグイン(トリアコンタン様作)」で
* 設定することをお勧めします。
*
* ---------------------------------------------------------------------------
* https://triacontane.blogspot.com/2016/03/gui.html
* 1. ウィンドウの横幅
* 2. ウィンドウの高さ
* 3. ウィンドウの余白
* 4. ウィンドウのフォントサイズ
* 5. ウィンドウの1行のあたりの高さ
* 6. ウィンドウの背景透明度
* 7. ウィンドウの行数
* 8. ウィンドウの背景画像ファイル名
* 9. ウィンドウのフォント名
* ---------------------------------------------------------------------------
*
* 利用規約
* 作者としての著作権を放棄します。
* パブリックドメインです。
*/