Last active
December 14, 2024 00:21
-
-
Save brunolm/94d60440d1b469cadff5eccdececd350 to your computer and use it in GitHub Desktop.
Path of Exile Trade Autofill
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// ==UserScript== | |
// @name Path of Exile Trade Autofill | |
// @namespace http://tampermonkey.net/ | |
// @version 2024-12-13 | |
// @description Copy and item in-game (CTRL+C) and click the button to process clipboard text | |
// @author BrunoLM | |
// @match https://www.pathofexile.com/trade2/search/poe2/Standard | |
// @icon https://www.google.com/s2/favicons?sz=64&domain=pathofexile.com | |
// @grant none | |
// ==/UserScript== | |
(function () { | |
"use strict"; | |
function parseItem(itemString) { | |
const result = {}; | |
const sections = itemString.split("--------"); | |
const itemClassSection = sections.find((s) => /Item Class:/.test(s)); | |
result.itemClass = itemClassSection.match(/Item Class: ([^\n]+)\n/)[1]; | |
result.rarity = itemClassSection.match(/Rarity: ([^\n]+)\n/)[1]; | |
result.name = itemClassSection.split(/\r?\n/)[2]; | |
result.type = itemClassSection.split(/\r?\n/)[3]; | |
result.quality = +itemString.match(/Quality: [+-](\d+)/)?.[1]; | |
if (result.quality === null) { | |
delete result.quality; | |
} | |
result.pdps = itemString.match(/Physical Damage: (\d+)-(\d+)/); | |
if (result.pdps) { | |
result.pdps = (+result.pdps[1] + +result.pdps[2]) / 2; | |
} | |
if (!result.pdps) { | |
delete result.pdps; | |
} | |
result.implicit = itemString.match(/^(.*?) \(implicit\)\n/m)?.[1]; | |
result.rune = itemString.match(/^(.*?) \(rune\)\n/m)?.[1]; | |
const modSection = itemString.split( | |
/--------\r?\nItem Level: \d+\r?\n--------\r?\n/ | |
)[1]; | |
const modLines = modSection.split(/\n/); | |
if (result.implicit) { | |
modLines.splice(0, 2); | |
} | |
if (result.rune) { | |
modLines.splice(0, 2); | |
} | |
const descriptionLine = modLines.indexOf("--------"); | |
if (descriptionLine >= 0) { | |
modLines.splice(descriptionLine, modLines.length); | |
} | |
const mods = modLines.filter(Boolean); | |
result.mods = mods.reduce((acc, next) => { | |
const range = next.match(/(\d+) to (\d+)/); | |
const [, min, max] = range ?? [0, 0, 0]; | |
const minAvg = (+min + +max) / 2; | |
acc.push({ | |
name: next, | |
min: +next.match(/\d+/)?.[0], | |
minAvg, | |
}); | |
return acc; | |
}, []); | |
return result; | |
} | |
async function processTextFromClipboard() { | |
try { | |
const text = await navigator.clipboard.readText(); | |
const itemInfo = parseItem(text); | |
console.log("i", itemInfo); | |
for (const mod of itemInfo.mods) { | |
const inputElement = document.querySelector( | |
'.filter-body input[placeholder*="Stat"]' | |
); | |
inputElement.focus(); | |
await new Promise((resolve) => setTimeout(resolve, 50)); | |
inputElement.value = mod.name.replace(/\d+/g, "#").replace(/^[+-]/, ""); | |
const inputEvent = new Event("input", { | |
bubbles: true, | |
cancelable: true, | |
}); | |
inputElement.dispatchEvent(inputEvent); | |
await new Promise((resolve) => setTimeout(resolve, 50)); | |
const it = | |
inputElement.parentElement.nextElementSibling.querySelectorAll( | |
"li" | |
)?.[1]; | |
it?.querySelector("span")?.click(); | |
await new Promise((resolve) => setTimeout(resolve, 100)); | |
const minMaxEls = Array.from(document.querySelectorAll(".minmax")); | |
const rowMin = minMaxEls.slice(-2)[0]; | |
rowMin.focus(); | |
await new Promise((resolve) => setTimeout(resolve, 50)); | |
rowMin.value = mod.minAvg || mod.min; | |
rowMin.dispatchEvent( | |
new Event("change", { bubbles: true, cancelable: true }) | |
); | |
} | |
} catch (err) { | |
console.error("Failed to read from clipboard: ", err); | |
} | |
} | |
async function addButton() { | |
await new Promise((resolve) => setTimeout(resolve, 1000)); | |
// Select the container element where the button will be appended | |
const container = document.querySelector(".btn.search-btn")?.parentElement; | |
if (!container) { | |
alert( | |
"[Path of Exile Trade Autofill] could not add button, try refreshing the page" | |
); | |
return; | |
} | |
// Create the button element | |
const button = document.createElement("button"); | |
button.textContent = "Process Clipboard Text"; | |
button.className = "btn process-btn"; | |
// Add an event listener to trigger the processTextFromClipboard function on click | |
button.addEventListener("click", processTextFromClipboard); | |
// Append the button to the container | |
container.appendChild(button); | |
} | |
// Append the button to the page | |
addButton(); | |
})(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment