Issue #1

Gatherer advanced searchは壊れているようで、しばらく前から(少なくとも6ヶ月は)そうなっています。 Google を通してそれについて話している人を見つけることができませんでした。 このことから、私が何か間違ったことをしているのか、誰も気づいていないのか、あるいは、私が十分に検索していないために以前の議論を見つけることができないのではないかと思いました。 私は少し調査してみることにしました。

私が見た Gatherer の 2 つの主要な問題。

  1. 2 つ以上の条件で詳細検索を行う(たとえば、すべての青、黒、および赤のカードを検索することです。 次に、検索結果ページで、それらの条件の1つの横にあるxをクリックします。
  2. 1つまたは複数の条件で詳細検索を行います(例:色:青を含むカード)。 その後、[絞り込み検索]をクリックします。 詳細検索の条件ボックスには、以前のパラメータは表示されません。

3 番目の問題は、高度な検索ページの条件の入力に関するものだったように記憶していますが、それが何だったのか思い出せません。 複数のデバイス (ラップトップ、2 台のデスクトップ、および電話) でテストしました。

クライアント側のコードを見て分かる限り、これは、サーバーの応答が Gatherer UI で処理される方法の問題だと思います (そしておそらく、サーバーが応答する方法の問題でもあると思います)。

AdvancedSearch.js::AdvSearchConditionCallback の 872 行目では、Gatherer UI がサーバーからの応答をどのように処理することを期待しているかを確認できます:

var results = eval("(" + transport.responseText + ")");

ここでサーバーが送信する応答は JSON です。 たとえば、すべての青、黒、および赤のカードを検索し、x をクリックして “DOES contain Red” 基準を解除すると、次のような応答が返されます:

{ "LCID": 0, "CommandName": null, "CommandListPath": null, "SearchTerms": null, "SubQueryDelimiter": "Union", "SearchTermDelimiter": "And", "EscapeInputDelimiters": true, "EncodedSerializedQuery": "YwBvAGwAbwByAD0AKwBbAFUAXQArAFsAQgBdAA==", "ExtraSafeKeys": , "IncludeSpecial": false, "Filters": { "color": { "Identifier": "fe329dcb-d64a-4939-bfd6-7af5c102d655", "LogicalOperator": "Intersect", "From": "color", "Terms": ", "LogicalOperator": "And", "State": "+" }, { "Identifier": "b622e49d-87de-439f-ac75-0e99ffee07c6", "FormatString": "color", "Value": "", "LogicalOperator": "And", "State": "+" } ], "State": null, "FormatString": "color", "Value": ", "LogicalOperator": "And", "State": "+" }, { "Identifier": "b622e49d-87de-439f-ac75-0e99ffee07c6", "FormatString": "color", "Value": "", "LogicalOperator": "And", "State": "+" } ] } }, "State": "color=++"} 

JSON には表示すべきカードに関する情報がないようです。

そこで、これに対して eval("(" + transport.responseText + ")") を呼び出すと、JSON 文字列を JSON オブジェクトに変換して正常に動作します。 AdvancedSearch.js では、その JSON オブジェクトを使用して、検索条件ボックスの表示を更新しています。 しかし、現在の URL は更新されません (たとえば、”?action=advanced&color=++” から “?action=advanced&color=++” へ)。

Prototype.js は、応答の評価も試みるように構成されます。 しかし、Prototype.jsはレスポンスがJSONであることを前提に書かれているわけではありません。 そのため、Prototype.js::respondToReadyState(1498行目)でPrototype.jsはこのJSON文字列をJavaScriptとしてevalevalResponse(1533行目))試み、JSON文字列が括弧で囲まれていないため、evalは失敗しているのです。

SyntaxError: Unexpected token : at klass.evalResponse (Prototype.js:1533) at klass.respondToReadyState (Prototype.js:1501) at klass.onStateChange (Prototype.js:1436) at XMLHttpRequest.<anonymous> (Prototype.js:291)

しかし、Prototype.js を変更して文字列を括弧で囲んでも、文字列を JSON オブジェクトに変換するだけで、何もしないことは注目に値します。 また、AdvancedSearch.jsを修正してPrototype.jsが応答を評価しないように設定しても、そのまま先に進み、最終結果は同じになります。

つまり、私が知る限りでは、2つの問題が考えられます。

  1. Gatherer UI (特に AdvancedSearch.js) は、新しい検索結果に移動して、現在の URL を変更することになっています。
  2. Gatherer UI は、バックグラウンドで返された URL を照会し (または、サーバーは応答にすべてのカードを含めることになっている)、次にカード リストを動的に更新することになっています。

1 が当てはまる場合、検索条件リストを動的に更新するすべてのロジックは無意味になります。ブラウザが新しい URL に移動するとすぐに、条件リストがすでに入力され、新しいカードが表示されたまったく新しいページがロードされます。 UIはサーバーが返す情報をすでに持っており、そのURLに直接ナビゲートすることができるからです。

2 の場合、サーバーが最初に結果のカード リストを返すことになっているところに問題がある可能性が高いと思います。 そうでない場合、この最初のクエリは、UI がすでに持っていないものを含んでいないため、無意味なように思えます。 いずれにせよ、UIには、カードリストを動的に更新するコードがない(らしい)という問題があります。

これはさらに複雑で、常に起こるわけではありません。 検索の絞り込み] をクリックすると、正しく動作することがあります。 しかし、たいていの場合、そうではありません。 これは、ソフトウェア開発業界では「レースコンディション」と呼ばれるもので、2つのことが同時に起こり、最終的な結果はその順序に依存します。 (これはマジックにおけるスタックのようなもので、2つの効果の順番が劇的に異なる結果をもたらすことがあります)。

私が問題の核心と見ているのはここです。

上記の例で、すべての青、黒、赤のカードを検索する場合を考えてみましょう。 検索を絞り込む] ボタンをクリックすると、このように表示されます。

<a href="/Pages/Advanced.aspx?action=advanced&amp;color=+++" class="refineSearchLink">Refine Search</a>

ですから、これはかなり簡単なことだと思います。 同じ検索条件で高度な検索ページに戻ってください。 問題は、それで実際に何が起こるかです。 リンク先のページに移動する場合、[検索の絞り込み] ボタンをクリックするか、この投稿に追加したリンクをクリックするか、アドレス バーに URL をコピー ペーストしても、(通常は)うまくいきません。 興味深いのは、やはりサーバーとUIのどちらか(おそらく両方)に問題があるように見えるということです。

ブラウザの開発者ツールでネットワーク タブを開き、そのページに移動すると、アクティビティ リストに表示される最初のエントリは、「Pages/Advanced.Aspx?action=advanced&color=+++」に対する要求です。 レスポンスを表示するためにクリックすると、最初に返されたときに表示されたページの完全なHTMLが表示されます。 検索条件] が入力されるべき場所に、

<div class="filters" ><span style="display: none;">None yet.</span>

その下に、そのリストを入力することを意図していると思われるスクリプトへの呼び出しがあります。

<script type="text/javascript">RetrieveCurrentSearchConditions();</script>

AdvancedSearch.jsRetrieveCurrentSearchConditions を見ると、次のパラメータで Ajax 要求しようとしています(406 行目)。

parameters: { cacheBust: new Date().getTime(), encodedSerializedPrevious: $(ClientIDs.encodedSerializedParameters).value }

問題は、この行でブレークポイントすると (またはサーバーからの生の HTML 応答を読むと)、encodedSerializedParameters が参照する要素はこの応答で値を持っていない、ということです。 そこで、encodedSerializedParameters: "" でこのリクエストを行うと、予想通り、空の検索フィルターが返されます。 では、なぜこのようなことが起こるのでしょうか。 検索結果に戻り、ソースを見ると、encodedSerializedParameters には値があることがわかります。 YwBvAGwAbwByAD0AKwBbAFUAXQArAFsAQgBdACsAWwBSAF0A (「color=+++」のベース64エンコーディング)。

つまり、このコードは検索結果ページで呼び出されることを期待して書かれているようですが、ブラウザがすでに高度な検索ページに移動して戻ってくるまで、実際には呼び出されないのです。

つまり、サーバーは encodedSerializedParameters 要素の value フィールドがすでに入力されている状態で応答することになっているようですが、そうではありません。 または、UI がナビゲートする前に何らかの方法でその値を収集し、次のページで使用するためにナビゲーションを介してその値を渡すことになっているようです。 または、おそらく UI は URL (クエリ情報が入力されている場所) から検索情報を取得し、検索条件ボックスに追加する機能を備えているはずです。

このすべてがある時点で動作していたことを知っています。したがって、どのようにしてこのような壊れたコードがリリースされ、長い間壊れたままになっているのか、見当もつきません。 これを投稿する直前に、私は r/magicTCG で特に検索を行うことにし、これらの同じ問題に言及していると思われる投稿を見つけました (例: Gatherer の ‘Advanced Search’ 検索条件は半不規則にリセットされます。 Help?, Trouble with Gatherer Advanced Search)、あまりに古いので驚きました(上記の例ではそれぞれ1年、3年です)。 ということは、もし同じ問題を指しているのであれば、これらはずいぶん前から出ていたことになりますね。

そこで質問なのですが、Wizards of the CoastはGathererを見捨てたのでしょうか? (少なくともその詳細検索は?)

Leave a Reply