-
Notifications
You must be signed in to change notification settings - Fork 0
Trade Bridge JA
Trade Bridge は、トレードサイト関連の作業 (live 検索、fetch、whisper) をすべてブラウザ拡張機能に任せ、POEFixer はゲーム内での購入だけを担当する仕組みです。これによりトレードサイトのトラフィックは実際のブラウザセッション内で完結し、cookie のコピーも cf_clearance の手間も不要になります。さらに、将来の「POEFixer を別の PC で動かす」モードの基盤にもなります。
無料の公式拡張機能 を使うことも、下記のドキュメント化されたプロトコルに沿って 自作 することもできます。
Trade Bridge を利用するには、POEFixer ライセンスに Trade 機能が含まれている必要があります。サーバー側で Trade が有料に設定されている場合は有効なキーが必要です。無料設定なら誰でも利用できます。権限がない場合、ブリッジは
entitlement_requiredを返し、購入を拒否します。
Browser extension POEFixer
live-search WebSocket ─┐
fetch item details │ ws://127.0.0.1:PORT in-game buying:
whisper (teleport) ├─────────────────────► wait teleport → click → verify
(Force teleport, │ buy_request → auto-stash → /hideout
In-demand retry, │ ◄───────────────────── → report result
Rate limiting) ─┘ buy_result
- 拡張機能 はトレードサイトに触れるすべてを担います。
- POEFixer はゲームクライアント内のすべてを担い、拡張機能が接続するためのローカル WebSocket サーバー (Trade Bridge) を公開します。
- このモードでは POEFixer 内蔵の
tls-clientは使われず、トレードサイト関連のコントロール (Connections、Trade Cookies、Force teleport、In-demand、Rate limiting) は拡張機能側へ移り、POEFixer 内では非表示/無効になります。
拡張機能は POEFixer に同梱されています。POEFixer フォルダ内の Resources\extension\ を開いてください:
<POEFixer folder>\Resources\extension\
├─ poefixer-extension-chrome.zip ← Chrome / Edge
├─ poefixer-extension-firefox.zip ← Firefox
└─ chrome\ ← unpacked copy used by the "Assisted install" button
完全に無音のワンクリックインストールはできません。ブラウザは仕様として、プログラムによる拡張機能インストールをブロックします。自分のブラウザ用のファイルを解凍し、一度だけ読み込みます。POEFixer の Assisted install… ボタン (Configuration → Trade) は Chrome/Edge 向けの作業を代行します。解凍済みの
chrome\フォルダのパスをクリップボードにコピーし、このガイドを開くので、解凍を省略できます。
-
Resources\extension\poefixer-extension-chrome.zipを任意のフォルダに 解凍 します (manifest.jsonがその最上位に来るように)。または POEFixer で Assisted install… をクリックし、コピーされたパスを使います。その場合は手順 4 へ進んでください。 -
chrome://extensionsを開きます (Edge:edge://extensions)。 - デベロッパーモード を有効にします (右上)。
- パッケージ化されていない拡張機能を読み込む をクリックし、そのフォルダを選択します (または Assisted install のパスを貼り付けます)。
- 拡張機能のアイコンがツールバーに表示されます。再起動後も読み込まれたままになります。
POEFixer の更新後は同梱の拡張機能も更新されます。
chrome://extensionsを開き、拡張機能カードの 再読み込み をクリックして新しいバージョンを反映してください (または再度解凍して「パッケージ化されていない拡張機能を読み込む」を実行)。
リリース版 Firefox は Mozilla 署名済みの拡張機能しかインストールできないため、一時的な読み込みを使います:
-
Resources\extension\poefixer-extension-firefox.zipを任意のフォルダに 解凍 します。 -
about:debugging#/runtime/this-firefoxを開きます。 -
一時的なアドオンを読み込む… をクリックし、解凍したフォルダの
manifest.jsonを選びます。 - Firefox を再起動するまで読み込まれたままになります (再起動後はやり直してください)。
-
恒久的にする場合: Mozilla/AMO 署名済みの
.xpiを Firefox で開き、権限の確認に同意してインストールします。
- POEFixer で: Configuration → Trade → Trade data source → Browser extension を選び、Port (デフォルト
47362) を確認して Start bridge をクリックします。 - 拡張機能のポップアップで 同じ Port を設定します。Host: connected と表示され、POEFixer 側のステータスが 緑 になり、拡張機能の名前と実際のバージョンが表示されます。例: "Extension connected (PoeFixerExt/1.1.2)" (バージョンは拡張機能のマニフェストから取得され、古い拡張機能はここで警告されます)。
- そのブラウザでトレードサイトにログインし、Trade Links を追加して Play を押します (§3 参照)。
すべての操作は POEFixer から制御します。拡張機能のポップアップでは接続用の Port を設定するだけです。
- POEFixer で: Configuration → Trade → Data source = Browser extension を選び、Port を設定して Start bridge をクリックします。
- 拡張機能のポップアップで Host: connected と同じ Port を確認します。
- 同じブラウザでトレードサイトにログインします。
- POEFixer の Trade Links (Connections タブ) に trade2 の検索 URL を追加して Play を押します。検索が拡張機能へ送られ、そこで実行されます。Stop で削除されます。
- POEFixer (Configuration → Trade) で動作を設定します: Force teleport、Item is in demand → teleport anyway、Rate limiting。POEFixer がこれらを拡張機能へ送り、拡張機能は従うだけです。
- リスティングが一致すると、拡張機能が whisper を送り、POEFixer がゲーム内で購入します。拡張機能のすべての活動は POEFixer の Logs に表示されます (カテゴリ Trade)。
信頼性の高い live フィード (自動): アクティブな検索ごとに、拡張機能はトレードページへの ピン留めされたバックグラウンドタブを開き、live WebSocket を そのページ内で 接続します (正しい Origin + セッション cookie — サイト自体と同じ動作です)。トレードサイトにログインしたままにするだけで、Live Search を手動で開く必要はありません。Trade Link は live WS が確立するまで Connecting…、確立後は Live と表示します。そのピン留めタブを閉じると検索が停止します。
Manual Buy (検索結果を今すぐまとめ買い): live リスティングを待つ代わりに、任意の Trade Link の Shopping Cart アイコンを押すと即座にまとめ買いできます。拡張機能はその検索で最も安い一致リスティングを取得し (設定した item count まで、そのリンクの currency filters に従う)、出品者ごとにグループ化し、POEFixer を通じてそれぞれ whisper + 購入します。同じ spend limits と auto-stash を適用し、最後に一度だけ hideout へ戻ります。Manual Buy と live 検索 (Play) は排他的です。Manual Buy を始める前に live 検索を停止し、その逆も同様にしてください。カートボタンは拡張機能が接続されているときだけ有効になります。
プロトコルは WebSocket 上の素の JSON です。誰でも実装できます。サーバーは POEFixer が立てます。あなたのクライアントは ws://127.0.0.1:<port> へ接続します (デフォルト 47362、Settings で変更可能)。
ホストは、ライセンスに Trade entitlement がある場合にのみ購入を実行します。そうでなければ
{"type":"error","code":"entitlement_required"}を受け取ります。(認証の詳細は意図的にドキュメント化していません。)
まず hello を送り、ホストが welcome を返します。
-
versionは拡張機能のマニフェストのバージョンです (semver 文字列、例"1.1.0")。拡張機能が POEFixer の期待するバージョンより古い場合、POEFixer は不一致を検出して live 検索を抑制し、最新の拡張機能を再インストールするまで購入を無効にします。POEFixer は Settings → Trade に警告を表示します。古い状態で購入を試みると{"type":"error","code":"outdated_extension"}を受け取ります。 -
allowed:false→ 権限なし (「キーを購入」と扱う)。ホストは購入をentitlement_requiredで拒否します。 -
tokenは、ユーザーが POEFixer でペアリングトークンを有効にした場合にのみ必要です (デフォルトはオフ)。
welcome の後 (およびユーザーが POEFixer で何かを変更するたびに)、ホストは config メッセージを送ります。プログラムが唯一の操作面なので、拡張機能はまさにこれらの検索を監視し、この behavior に従う必要があります:
// host → client
{ "type":"config",
"behavior":{ "forceTeleport":false, "inDemandRetry":true, "rateLimit":true },
"searches":[ { "realm":"poe2", "league":"Standard", "searchId":"…", "note":"…" } ] }ホストは定期的に status を送ります:
{ "type":"status", "ready":true, "inGame":true, "attached":true, "busy":false }最後の status.ready === true のときにのみ whisper/teleport しなければなりません。 ready = entitled && attached && in-game && !busy です。ready でないときに whisper すると、取引を進める購入者がいないままキャラクターがテレポートしてしまいます。
whisper が成功した後 (キャラクターがテレポート中)、buy_request を送ります:
// client → host
{ "type":"buy_request", "id":"r-42", "seq":7,
"group":{
"searchId":"…", "groupId":"g-9", "isLastGroup":true,
"items":[ {
"itemId":"...", "stashX":3, "stashY":1, "w":1, "h":1,
"currency":"chaos", "amount":50,
"seller":"AccountName", "stashName":"~price 50 chaos",
"name":"...", "typeLine":"...", "baseType":"...", "rarity":"Rare",
"iconUrl":"https://...", "ilvl":82, "corrupted":false, "identified":true,
"explicitMods":[ "..." ], "implicitMods":[ "..." ],
"league":"Standard", "realm":"poe2",
"hideoutToken":"...", "indexedTime":"..."
} ] } }ホストはこれを ack し、必要に応じて進捗を送り、最後に 1 つの結果を送ります:
{ "type":"ack", "ackSeq":7 }
{ "type":"buy_progress", "id":"r-42", "phase":"teleporting" }
{ "type":"buy_result", "id":"r-42", "seq":11,
"items":[ { "itemId":"...", "ok":true, "reason":"verified" } ],
"summary":{ "bought":1, "failed":0 } }-
group.searchIdはリスティングの出所となる検索です。ホストはこれを使って購入を正しい Trade Link に紐付けます (省略時は最初のアクティブな検索にフォールバック)。複数検索を正しく扱うために指定してください。 -
stashX/stashYは出品者のショップ内でのアイテムの座標、w/hはそのサイズです。これらがゲーム内のクリックを駆動します。 - 価格はフラット (
currency/amount、上記のとおり) でも、ネスト ("price":{"currency","amount"}) でも送れます。ホストは両方を受け付けます。 -
hideoutTokenはログ用にのみ運ばれます (whisper にはすでに使用済みです)。 - 各
buy_resultは 必ず ack してください:{"type":"ack","ackSeq":<buy_result.seq>}を送ります。
whisper 段階の結果 (POEFixer のログを完全に保つため):
{ "type":"trade_event", "seq":8, "stage":"whisper", "outcome":"in_demand", "itemId":"...", "detail":"" }
// outcome ∈ in_demand | whisper_failed | teleport_failed | fetch_error
trade_eventは完全なitemオブジェクト (buy_requestのアイテムと同じフィールド) を含むこともあります。teleport_failed= 強制的な再 whisper の後でも出品者のリスティングがまだ in demand だったことを意味します。item付きで送られると、POEFixer はそれを Trade Logs に Teleport Fail として記録します。fetch_error/whisper_failed/in_demandは情報用で、一般の Logs (カテゴリ Trade) に送られます。
自分の活動を POEFixer のログへ転送してください (推奨 — 拡張機能のすべてのログはプログラムに表示されるべきです):
{ "type":"log", "level":"info", "message":"…" } // shown in POEFixer Logs (category Trade)各検索の live-WS の状態を報告し、POEFixer の Trade Link が Connecting…/Live を表示できるようにします:
{ "type":"search_status", "searchId":"…", "state":"connected" } // state ∈ connected | closed | errorユーザーが Trade Link で Manual Buy (カートアイコン) をクリックすると、ホストは manual_buy を送ります。拡張機能はその検索のワンショットまとめ買いを実行し、ライフサイクル/進捗を manual_buy_status で報告します。出品者ごとの購入は通常の buy_request フロー (§4.3) を isLastGroup:false で使います。ホストは state:"done" を受け取ると、最後の /hideout を一度だけ発火します。
// host → client: start a one-shot bulk buy of one saved search
{ "type":"manual_buy", "id":"mb-…", "seq":12,
"search":{ "realm":"poe2", "league":"Standard", "searchId":"…", "note":"…" },
"itemCount":10, // 0 = all results
"filters":{ "chaos":{ "min":0, "max":0 } } } // currency → {min,max}; 0 = unbounded
// host → client: cancel an in-progress bulk buy
{ "type":"manual_buy_cancel", "id":"mb-…", "seq":13 }
// client → host: lifecycle + progress (ack-tracked like trade_event)
{ "type":"manual_buy_status", "id":"mb-…", "seq":4,
"state":"started|progress|done|cancelled|error",
"processed":3, "bought":2, "failed":1, "total":10, "detail":"" }- 検索を解決し、最も安い一致リスティングを取得し、
filtersを適用し、itemCountで上限を設け (0 = すべて)、出品者ごとにグループ化し、各グループをbuy_request(isLastGroup:false) で購入します。 - 最初に
manual_buy_statusのstartedを送り、グループ完了ごとにprogressを送り、最後にちょうど 1 つの終端done/cancelled/errorを送ります。
-
buy_requestとtrade_eventは増加するseqを持ち、ホストがそれらを ack します。ack されていないフレームを保持し、再接続時に再送してください (seq順)。 -
buy_request.idは 冪等性キー です。再送された id は記録済みのbuy_resultを返します (または処理中の間はerror: duplicate)。購入ごとに安定した一意の id を使ってください。 -
buy_resultは あなたが ack するseqを持ちます。
{ "type":"error", "code":"entitlement_required|not_in_game|busy|duplicate|bad_request|unauthorized|proto_unsupported|outdated_extension", "id":"r-42", "detail":"..." }const ws = new WebSocket("ws://127.0.0.1:47362");
let ready = false, seq = 0, behavior = {}, searches = [];
const log = (message) => ws.send(JSON.stringify({ type:"log", level:"info", message }));
ws.onopen = () => ws.send(JSON.stringify({ type:"hello", proto:1, client:"MyExt/1.0", version:"1.1.0" }));
ws.onmessage = (e) => {
const m = JSON.parse(e.data);
if (m.type === "welcome" && !m.allowed) console.warn("Trade entitlement required");
if (m.type === "config") { behavior = m.behavior; searches = m.searches; } // program controls you
if (m.type === "status") ready = m.ready;
if (m.type === "buy_result") ws.send(JSON.stringify({ type:"ack", ackSeq:m.seq }));
};
// monitor `searches`, obey `behavior`; after YOUR whisper succeeds and ready === true:
function buy(items) {
ws.send(JSON.stringify({ type:"buy_request", id:"r-"+Date.now(), seq:++seq,
group:{ groupId:"g", isLastGroup:true, items } }));
}- Host: disconnected — POEFixer が起動していない、ブリッジが開始されていない、またはポートが間違っています。Settings → Trade でブリッジを開始し、ポップアップのポートを一致させてください。
-
entitlement_required— ライセンスに Trade 機能がありません (サーバー側で有料)。 -
not_in_game— POEFixer がアタッチ/ゲーム内になっていません。status.readyを待ってください。 - Live 検索が発火しない — 同じブラウザでトレードサイトにログインしているか確認してください。拡張機能は検索ごとに専用のピン留めバックグラウンドタブを自動的に開き、そのページ内で live WebSocket を実行します。Trade Link は Connecting…、その後 Live と表示します。Connecting… のまま止まる場合は、ピン留めタブを開いてログイン状態を確認してください。
- Port in use — Settings → Trade とポップアップでポートを変更し、ブリッジを再起動してください。