-
Notifications
You must be signed in to change notification settings - Fork 0
Trade Bridge TH
Trade Bridge ให้ส่วนขยายเบราว์เซอร์ทำงานทั้งหมดที่เกี่ยวกับเว็บเทรด (live search, การดึงข้อมูล, การ whisper) ในขณะที่ POEFixer ทำเฉพาะการซื้อในเกมเท่านั้น วิธีนี้ทำให้ทราฟฟิกของเว็บเทรดอยู่ภายในเซสชันเบราว์เซอร์จริงของคุณ — ไม่ต้องคัดลอก cookie ไม่ต้องยุ่งกับ cf_clearance — และเป็นรากฐานสำหรับโหมด "รัน POEFixer บนพีซีอีกเครื่อง" ในอนาคต
คุณสามารถใช้ ส่วนขยายทางการแบบฟรี หรือสร้าง ส่วนขยายของคุณเอง ตามโปรโตคอลที่ระบุไว้ด้านล่างนี้ก็ได้
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) ที่ส่วนขยายเชื่อมต่อเข้ามา
- ในโหมดนี้
tls-clientที่มีอยู่ในตัวของ POEFixer จะไม่ถูกใช้ และตัวควบคุมเว็บเทรด (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
การติดตั้งแบบเงียบในคลิกเดียวอย่างสมบูรณ์เป็นไปไม่ได้ — เบราว์เซอร์จงใจบล็อกการติดตั้งส่วนขยายแบบอัตโนมัติ คุณต้องแตกไฟล์สำหรับเบราว์เซอร์ของคุณและโหลดมันหนึ่งครั้ง ปุ่ม Assisted install… ของ POEFixer (Configuration → Trade) จะทำส่วนของ Chrome/Edge ให้คุณ โดยจะคัดลอกพาธของโฟลเดอร์
chrome\ที่แตกไฟล์แล้วไปยังคลิปบอร์ดและเปิดคู่มือนี้ขึ้นมา เพื่อให้คุณข้ามขั้นตอนการแตกไฟล์ได้
-
แตกไฟล์
Resources\extension\poefixer-extension-chrome.zipไปยังโฟลเดอร์ใดก็ได้ (ให้manifest.jsonอยู่ที่ระดับบนสุดของโฟลเดอร์) หรือ คลิก Assisted install… ใน POEFixer แล้วใช้พาธที่คัดลอกมา — จากนั้นข้ามไปขั้นตอนที่ 4 - เปิด
chrome://extensions(Edge:edge://extensions) - เปิดใช้งาน Developer mode (มุมขวาบน)
- คลิก Load unpacked แล้วเลือกโฟลเดอร์นั้น (หรือวางพาธจาก Assisted install)
- ไอคอนส่วนขยายจะปรากฏบนแถบเครื่องมือ และจะยังคงโหลดอยู่หลังการรีสตาร์ท
หลังจากอัปเดต POEFixer ส่วนขยายที่มาในตัวจะถูกรีเฟรช — เปิด
chrome://extensionsแล้วคลิก Reload บนการ์ดของส่วนขยายเพื่อรับเวอร์ชันใหม่ (หรือแตกไฟล์ใหม่แล้ว Load unpacked)
Firefox รุ่น release จะติดตั้งเฉพาะส่วนขยายที่เซ็นโดย Mozilla เท่านั้น ดังนั้นให้ใช้การโหลดแบบชั่วคราว:
-
แตกไฟล์
Resources\extension\poefixer-extension-firefox.zipไปยังโฟลเดอร์ใดก็ได้ - เปิด
about:debugging#/runtime/this-firefox - คลิก Load Temporary Add-on… แล้วเลือก
manifest.jsonจากโฟลเดอร์ที่แตกไฟล์แล้ว - มันจะยังคงโหลดอยู่จนกว่าคุณจะรีสตาร์ท Firefox (ทำซ้ำหลังการรีสตาร์ท)
-
แบบถาวร: ติดตั้งไฟล์
.xpiที่เซ็นโดย Mozilla/AMO โดยเปิดมันใน Firefox และยืนยันคำขอสิทธิ์
- ใน POEFixer: Configuration → Trade → Trade data source → Browser extension จดค่า Port เอาไว้ (ค่าเริ่มต้น
47362) แล้วคลิก Start bridge - ในป็อปอัปของส่วนขยาย ให้ตั้งค่า Port เดียวกัน — มันควรแสดง Host: connected และสถานะใน POEFixer จะเปลี่ยนเป็น สีเขียว พร้อมแสดงชื่อและเวอร์ชันจริงของส่วนขยาย เช่น "Extension connected (PoeFixerExt/1.1.2)" (เวอร์ชันมาจากไฟล์ manifest ของส่วนขยาย — ส่วนขยายที่ล้าสมัยจะถูกแจ้งเตือนตรงนี้)
- ล็อกอินเข้าเว็บเทรดในเบราว์เซอร์นั้น จากนั้นเพิ่ม Trade Links ของคุณแล้วกด Play (ดู §3)
ทุกอย่างควบคุมจาก POEFixer — ป็อปอัปของส่วนขยายตั้งได้แค่ Port ของการเชื่อมต่อเท่านั้น
- ใน POEFixer: Configuration → Trade → Data source = Browser extension ตั้งค่า Port คลิก Start bridge
- ในป็อปอัปของส่วนขยาย ยืนยัน Host: connected และ Port เดียวกัน
- ล็อกอินเข้าเว็บเทรดในเบราว์เซอร์เดียวกัน
- ใน Trade Links (แท็บ Connections) ของ POEFixer ให้เพิ่ม URL การค้นหา trade2 ของคุณแล้วกด Play — การค้นหาจะถูกส่งไปยังส่วนขยายและทำงานที่นั่น Stop จะลบมันออก
- ตั้งค่าพฤติกรรมใน POEFixer (Configuration → Trade): Force teleport, Item is in demand → teleport anyway, Rate limiting — POEFixer จะส่งค่าเหล่านี้ไปยังส่วนขยาย ซึ่งทำหน้าที่แค่ปฏิบัติตาม
- เมื่อมีรายการที่ตรงกัน ส่วนขยายจะ whisper และ POEFixer จะซื้อในเกม กิจกรรมทั้งหมดของส่วนขยายจะปรากฏใน Logs ของ POEFixer (หมวด Trade)
ฟีดสดที่เชื่อถือได้ (อัตโนมัติ): สำหรับการค้นหาที่ใช้งานอยู่แต่ละรายการ ส่วนขยายจะ เปิดแท็บพื้นหลังที่ปักหมุดไว้ ไปยังหน้าเทรดและเชื่อมต่อ live WebSocket ภายในหน้านั้น (Origin ที่ถูกต้อง + cookie เซสชันของคุณ — เหมือนกับที่เว็บไซต์ทำเอง) เพียงแค่คงสถานะล็อกอินในเว็บเทรดไว้ คุณไม่ต้องเปิด Live Search เอง Trade Link จะแสดง Connecting… จนกว่า live WS จะพร้อม จากนั้นจึงเป็น Live การปิดแท็บที่ปักหมุดนั้นจะหยุดการค้นหา
Manual Buy (ซื้อการค้นหาแบบเหมาทันที): แทนที่จะรอรายการสด ให้กดไอคอน Shopping Cart บน Trade Link ใดก็ได้เพื่อซื้อแบบเหมาทันที ส่วนขยายจะดึงรายการที่ตรงและถูกที่สุดสำหรับการค้นหานั้น (ไม่เกิน item count ที่คุณตั้งไว้ โดยเคารพ currency filters ของลิงก์นั้น) จัดกลุ่มตามผู้ขาย และ whisper + ซื้อแต่ละกลุ่มผ่าน POEFixer — โดยใช้ spend limits และ auto-stash เดียวกัน พร้อมการกลับ hideout เพียงครั้งเดียวในตอนท้าย Manual Buy และ live search (Play) ใช้ร่วมกันไม่ได้: หยุด live search ของคุณก่อนเริ่ม Manual Buy และในทางกลับกันด้วย ปุ่มรถเข็นจะเปิดใช้งานได้เฉพาะตอนที่ส่วนขยายเชื่อมต่ออยู่เท่านั้น
โปรโตคอลนี้เป็น JSON ธรรมดาผ่าน WebSocket ใครก็สามารถนำไปใช้ได้ POEFixer เป็นโฮสต์ของเซิร์ฟเวอร์ ไคลเอนต์ของคุณเชื่อมต่อไปยัง ws://127.0.0.1:<port> (ค่าเริ่มต้น 47362 ตั้งค่าได้ใน Settings)
โฮสต์จะดำเนินการซื้อเฉพาะเมื่อใบอนุญาตของคุณมี entitlement Trade เท่านั้น มิฉะนั้นคุณจะได้รับ
{"type":"error","code":"entitlement_required"}(รายละเอียดการยืนยันตัวตนจงใจไม่ระบุไว้)
ส่ง hello ก่อน จากนั้นโฮสต์จะตอบ welcome
-
versionคือเวอร์ชันจากไฟล์ manifest ของส่วนขยาย (สตริง semver เช่น"1.1.0") หากส่วนขยายของคุณเก่ากว่าเวอร์ชันที่ POEFixer คาดหวัง มันจะตรวจพบความไม่ตรงกัน ระงับ live search และปิดการซื้อจนกว่าคุณจะติดตั้งส่วนขยายเวอร์ชันล่าสุดใหม่ POEFixer จะแสดงคำเตือนใน Settings → Trade การพยายามซื้อขณะที่ส่วนขยายล้าสมัยจะได้รับ{"type":"error","code":"outdated_extension"} -
allowed:false→ ไม่มีสิทธิ์ (ให้ถือว่า "ต้องซื้อคีย์") โฮสต์จะปฏิเสธการซื้อด้วยentitlement_required -
tokenจำเป็นเฉพาะเมื่อผู้ใช้เปิดใช้ pairing 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 }คุณต้อง whisper/teleport เฉพาะเมื่อ status.ready === true ล่าสุดเท่านั้น ready = entitled && attached && in-game && !busy การ whisper ขณะที่ยังไม่ ready จะเทเลพอร์ตตัวละครไปโดยไม่มีผู้ซื้อขับเคลื่อนการเทรด
หลังจาก 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 มัน อาจส่ง progress ออกมา จากนั้นจึงส่งผลลัพธ์เพียงครั้งเดียว:
{ "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 ที่ถูกต้อง (หากละไว้จะ fall back ไปยังการค้นหาที่ใช้งานอยู่อันแรก) ให้ส่งมันเพื่อให้พฤติกรรมแบบหลายการค้นหาถูกต้อง -
stashX/stashYคือพิกัดของไอเทมในร้านของผู้ขายw/hคือขนาดของมัน — ค่าเหล่านี้ขับเคลื่อนการคลิกในเกม - ราคาส่งได้ทั้งแบบแบน (
currency/amountตามด้านบน) หรือแบบซ้อน ("price":{"currency","amount"}) — โฮสต์รับทั้งสองแบบ -
hideoutTokenถูกส่งมาเพื่อการบันทึก log เท่านั้น (คุณใช้มัน whisper ไปแล้ว) - คุณ ต้อง ack ทุก
buy_result: ส่ง{"type":"ack","ackSeq":<buy_result.seq>}
ผลลัพธ์ในช่วง whisper (เพื่อให้ logs ของ 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= รายการของผู้ขายยังคง in demand แม้หลังจากบังคับ whisper ซ้ำแล้ว เมื่อส่งมาพร้อมitemPOEFixer จะบันทึกมันใน Trade Logs ในฐานะ Teleport Fail ส่วนfetch_error/whisper_failed/in_demandเป็นข้อมูลทั่วไปและจะไปอยู่ใน Logs ทั่วไป (หมวด Trade)
ส่งต่อกิจกรรมของคุณไปยัง log ของ POEFixer (แนะนำ — log ทั้งหมดของส่วนขยายควรปรากฏในโปรแกรม):
{ "type":"log", "level":"info", "message":"…" } // shown in POEFixer Logs (category Trade)รายงานสถานะ live-WS ของการค้นหาแต่ละอันเพื่อให้ Trade Link ของ POEFixer แสดง Connecting…/Live:
{ "type":"search_status", "searchId":"…", "state":"connected" } // state ∈ connected | closed | errorเมื่อผู้ใช้คลิก Manual Buy (ไอคอนรถเข็น) บน Trade Link โฮสต์จะส่ง manual_buy ส่วนขยายของคุณจะทำการซื้อแบบเหมาครั้งเดียวสำหรับการค้นหานั้น และรายงาน lifecycle/progress ด้วย manual_buy_status การซื้อต่อผู้ขายแต่ละรายใช้ขั้นตอน buy_request ปกติ (§4.3) ด้วย isLastGroup:false โฮสต์จะส่ง /hideout ครั้งสุดท้ายเมื่อได้รับ state:"done"
// 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_statusstartedที่จุดเริ่มต้นprogressเมื่อแต่ละกลุ่มเสร็จสิ้น และส่ง terminaldone/cancelled/errorเพียงหนึ่งเดียวเท่านั้น
-
buy_requestและtrade_eventมีseqที่เพิ่มขึ้นเรื่อย ๆ โฮสต์จะ ack มัน เก็บเฟรมที่ยังไม่ได้ ack ไว้และ ส่งซ้ำเมื่อ reconnect (เรียงตามseq) -
buy_request.idคือ idempotency key — id ที่ส่งซ้ำจะคืนbuy_resultที่บันทึกไว้ (หรือerror: duplicateขณะที่ยังดำเนินการอยู่) ใช้ id ที่เสถียรและไม่ซ้ำต่อการซื้อแต่ละครั้ง -
buy_resultมีseqที่ คุณ เป็นผู้ ack
{ "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 ยังไม่ได้ attach/ยังไม่อยู่ในเกม รอstatus.ready - Live search ไม่ทำงานเลย — ตรวจสอบให้แน่ใจว่าคุณล็อกอินเข้าเว็บเทรดในเบราว์เซอร์เดียวกัน ส่วนขยายจะเปิดแท็บพื้นหลังที่ปักหมุดของตัวเองต่อการค้นหาแต่ละอันโดยอัตโนมัติ และรัน live WebSocket ภายในหน้านั้น Trade Link จะแสดง Connecting… จากนั้นจึงเป็น Live หากมันค้างอยู่ที่ Connecting… ให้เปิดแท็บที่ปักหมุดเพื่อตรวจสอบว่าคุณล็อกอินอยู่
- Port in use — เปลี่ยนพอร์ตใน Settings → Trade และในป็อปอัป จากนั้นรีสตาร์ทบริดจ์