-
Notifications
You must be signed in to change notification settings - Fork 0
Trade Bridge ES
El Trade Bridge permite que una extension de navegador haga todo el trabajo del sitio de comercio (busqueda en vivo, fetch, whisper), mientras que POEFixer solo se encarga de la compra dentro del juego. Asi todo el trafico del sitio de comercio queda dentro de tu sesion de navegador real — sin copiar cookies, sin lidiar con cf_clearance — y es la base para un futuro modo «ejecutar POEFixer en otro PC».
Puedes usar la extension oficial gratuita o escribir la tuya propia segun el protocolo documentado mas abajo.
El Trade Bridge requiere que tu licencia de POEFixer tenga la funcion Trade. Si en el servidor Trade esta configurada como de pago, necesitas una clave valida; si es gratuita, puede usarla cualquiera. Sin derechos, el puente responde
entitlement_requiredy rechaza las compras.
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
- La extension controla todo lo que toca el sitio de comercio.
- POEFixer controla todo lo del cliente del juego y expone un servidor WebSocket local (el Trade Bridge) al que se conecta la extension.
- En este modo no se usa el
tls-clientintegrado de POEFixer, y los controles del sitio de comercio (Connections, Trade Cookies, Force teleport, In-demand, Rate limiting) se trasladan a la extension y quedan ocultos/desactivados en POEFixer.
La extension viene incluida dentro de POEFixer. En tu carpeta de POEFixer abre 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
Una instalacion totalmente silenciosa de un solo clic no es posible — los navegadores bloquean deliberadamente la instalacion programatica de extensiones. Descomprimes el archivo de tu navegador y lo cargas una vez. El boton Assisted install… de POEFixer (Configuration → Trade) hace la parte de Chrome/Edge por ti: copia al portapapeles la ruta de la carpeta descomprimida
chrome\y abre esta guia, para que puedas saltarte la descompresion.
-
Descomprime
Resources\extension\poefixer-extension-chrome.zipen cualquier carpeta (de modo quemanifest.jsonquede en su raiz). O haz clic en Assisted install… en POEFixer y usa la ruta copiada — luego salta al paso 4. - Abre
chrome://extensions(Edge:edge://extensions). - Activa el Modo de desarrollador (arriba a la derecha).
- Haz clic en Cargar extension sin empaquetar y selecciona esa carpeta (o pega la ruta de Assisted install).
- El icono de la extension aparece en la barra de herramientas; se mantiene cargado entre reinicios.
Tras una actualizacion de POEFixer, la extension incluida se actualiza — abre
chrome://extensionsy haz clic en Recargar en la tarjeta de la extension para tomar la nueva version (o vuelve a descomprimir y Cargar extension sin empaquetar).
El Firefox de version final solo instala extensiones firmadas por Mozilla, asi que usa la carga temporal:
-
Descomprime
Resources\extension\poefixer-extension-firefox.zipen cualquier carpeta. - Abre
about:debugging#/runtime/this-firefox. - Haz clic en Cargar complemento temporal… y elige el
manifest.jsonde la carpeta descomprimida. - Se mantiene cargado hasta que reinicies Firefox (repite tras un reinicio).
-
Persistente: instala un
.xpifirmado por Mozilla/AMO abriendolo en Firefox y confirmando la solicitud de permisos.
- En POEFixer: Configuration → Trade → Trade data source → Browser extension, anota el Port (por defecto
47362) y haz clic en Start bridge. - En el popup de la extension, indica el mismo Port — deberia mostrar Host: connected, y el estado en POEFixer se pone verde y muestra el nombre y la version real de la extension, por ejemplo "Extension connected (PoeFixerExt/1.1.2)" (la version viene del manifiesto de la extension — una extension desactualizada se marca aqui).
- Inicia sesion en el sitio de comercio en ese navegador, luego agrega tus Trade Links y pulsa Play (ver §3).
Todo se controla desde POEFixer — el popup de la extension solo establece el Port de conexion.
- En POEFixer: Configuration → Trade → Data source = Browser extension, indica el Port, haz clic en Start bridge.
- En el popup de la extension, confirma Host: connected y el mismo Port.
- Inicia sesion en el sitio de comercio en el mismo navegador.
- En los Trade Links (pestana Connections) de POEFixer agrega tus URLs de busqueda trade2 y pulsa Play — la busqueda se envia a la extension y se ejecuta alli; Stop la quita.
- Configura el comportamiento en POEFixer (Configuration → Trade): Force teleport, Item is in demand → teleport anyway, Rate limiting — POEFixer los envia a la extension, que simplemente obedece.
- Cuando un listado coincide, la extension envia el whisper y POEFixer compra dentro del juego. Toda la actividad de la extension aparece en los Logs de POEFixer (categoria Trade).
Feed en vivo fiable (automatico): para cada busqueda activa la extension abre una pestana de fondo fijada en la pagina de comercio y conecta el WebSocket en vivo dentro de esa pagina (Origin correcto + tus cookies de sesion — exactamente como lo hace el sitio). Solo manten la sesion iniciada en el sitio de comercio; no abres Live Search manualmente. El Trade Link muestra Connecting… hasta que el WS en vivo esta listo, luego Live. Cerrar esa pestana fijada detiene la busqueda.
Manual Buy (comprar una busqueda al por mayor, ahora): en vez de esperar listados en vivo, pulsa el icono del Carrito de compra en cualquier Trade Link para comprar al por mayor de inmediato. La extension obtiene los listados coincidentes mas baratos de esa busqueda (hasta el numero de objetos que fijaste, respetando los filtros de moneda de ese link), los agrupa por vendedor y envia whisper + compra cada uno mediante POEFixer — aplicando los mismos limites de gasto y auto-stash, con un unico regreso al refugio al final. Manual Buy y la busqueda en vivo (Play) son mutuamente excluyentes: detén tus busquedas en vivo antes de iniciar una Manual Buy, y viceversa. El boton del carrito solo esta habilitado mientras la extension esta conectada.
El protocolo es JSON plano sobre un WebSocket. Cualquiera puede implementarlo. POEFixer aloja el servidor; tu cliente se conecta a ws://127.0.0.1:<port> (por defecto 47362, configurable en Settings).
El host solo realiza compras cuando tu licencia tiene el entitlement Trade. De lo contrario recibes
{"type":"error","code":"entitlement_required"}. (Los detalles de autenticacion no se documentan a proposito.)
Primero envias hello; el host responde welcome.
-
versiones la version del manifiesto de la extension (cadena semver, p. ej."1.1.0"). Si tu extension es mas antigua que la version que POEFixer espera, detecta el desajuste, suprime las busquedas en vivo y desactiva la compra hasta que reinstales la ultima extension. POEFixer muestra una advertencia en Settings → Trade. Una compra intentada con una extension desactualizada recibe{"type":"error","code":"outdated_extension"}. -
allowed:false→ sin derechos (tratalo como «compra una clave»); el host rechazara las compras conentitlement_required. -
tokensolo es necesario si el usuario activo un token de emparejamiento en POEFixer (desactivado por defecto).
Tras welcome (y cada vez que el usuario cambia algo en POEFixer), el host envia un mensaje config. El programa es la unica superficie de control, asi que tu extension debe monitorear exactamente estas busquedas y obedecer este comportamiento:
// host → client
{ "type":"config",
"behavior":{ "forceTeleport":false, "inDemandRetry":true, "rateLimit":true },
"searches":[ { "realm":"poe2", "league":"Standard", "searchId":"…", "note":"…" } ] }El host envia status periodicamente:
{ "type":"status", "ready":true, "inGame":true, "attached":true, "busy":false }SOLO DEBES enviar whisper/teleport cuando el ultimo status.ready === true. ready = entitled && attached && in-game && !busy. Enviar whisper cuando no esta ready teletransporta al personaje sin un comprador que conduzca la operacion.
Despues de que tu whisper tenga exito (el personaje se esta teletransportando), envia 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":"..."
} ] } }El host lo confirma, opcionalmente emite progreso, y luego un unico resultado:
{ "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.searchIdes la busqueda de la que vino el listado; el host lo usa para vincular la compra al Trade Link correcto (recurre a la primera busqueda activa si se omite). Envialo para un comportamiento correcto con varias busquedas. -
stashX/stashYson las coordenadas del objeto en la tienda del vendedor;w/hsu tamaño — estos dirigen el clic dentro del juego. - El precio puede enviarse plano (
currency/amount, como arriba) o anidado ("price":{"currency","amount"}) — el host acepta ambos. -
hideoutTokense transporta solo para el log (ya lo usaste para enviar el whisper). -
Debes confirmar cada
buy_result: envia{"type":"ack","ackSeq":<buy_result.seq>}.
Resultados de la etapa whisper (manten completos los logs de POEFixer):
{ "type":"trade_event", "seq":8, "stage":"whisper", "outcome":"in_demand", "itemId":"...", "detail":"" }
// outcome ∈ in_demand | whisper_failed | teleport_failed | fetch_errorUn
trade_eventtambien puede llevar el objetoitemcompleto (los mismos campos que un item debuy_request).teleport_failed= el listado del vendedor seguia in demand incluso tras un re-whisper forzado; enviado con suitem, POEFixer lo registra en Trade Logs como un Teleport Fail.fetch_error/whisper_failed/in_demandson informativos y van al Log general (categoria Trade).
Reenvia tu actividad al log de POEFixer (recomendado — todos los logs de la extension deberian aparecer en el programa):
{ "type":"log", "level":"info", "message":"…" } // shown in POEFixer Logs (category Trade)Informa el estado del WS en vivo de cada busqueda para que el Trade Link de POEFixer muestre Connecting…/Live:
{ "type":"search_status", "searchId":"…", "state":"connected" } // state ∈ connected | closed | errorCuando el usuario hace clic en Manual Buy (el icono del carrito) en un Trade Link, el host envia manual_buy; tu extension realiza una compra al por mayor de una sola vez de esa busqueda e informa del ciclo de vida/progreso con manual_buy_status. Las compras por vendedor usan el flujo ordinario de buy_request (§4.3) con isLastGroup:false; el host dispara el /hideout final una vez que recibe 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":"" }- Resuelve la busqueda, obtén los listados coincidentes mas baratos, aplica
filters, limita aitemCount(0 = todos), agrupa por vendedor y compra cada grupo mediantebuy_request(isLastGroup:false). - Envia
manual_buy_statusstartedal inicio,progressa medida que los grupos se completan, y exactamente un terminaldone/cancelled/error.
-
buy_requestytrade_eventllevan unseqincremental; el host los confirma. Conserva los frames sin confirmar y reenvialos al reconectar (ordenados porseq). -
buy_request.ides la clave de idempotencia — un id reenviado devuelve elbuy_resultregistrado (oerror: duplicatemientras aun esta en curso). Usa un id estable y unico por compra. -
buy_resultlleva unseqque confirmas tu.
{ "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 no esta en ejecucion, el puente no se inicio, o el puerto es incorrecto. Inicia el puente en Settings → Trade; haz coincidir el puerto en el popup.
-
entitlement_required— tu licencia carece de la funcion Trade (de pago en el servidor). -
not_in_game— POEFixer no esta adjunto/en el juego; espera astatus.ready. - La busqueda en vivo nunca se dispara — asegurate de tener la sesion iniciada en el sitio de comercio en el mismo navegador. La extension abre automaticamente su propia pestana de fondo fijada por busqueda y ejecuta el WebSocket en vivo dentro de esa pagina; el Trade Link muestra Connecting… y luego Live. Si se queda en Connecting…, abre la pestana fijada para comprobar que tienes la sesion iniciada.
- Puerto en uso — cambia el puerto en Settings → Trade y en el popup, luego reinicia el puente.