NOTICE: By continued use of this site you understand and agree to the binding Terms of Service and Privacy Policy.
// ==UserScript== // @name Mannco.Store - Item Page Enhancer // @namespace https://github.com/LucasHenriqueDiniz // @version 0.3 // @description Mannco Store Enhancer is a browser extension that enhances the Mannco Store website with a range of features to make your shopping experience more efficient and streamlined. // @author Lucas Diniz // @license MIT // @match *://mannco.store/item/* // @icon https://www.google.com/s2/favicons?sz=64&domain=mannco.store // @grant GM_getValue // @grant GM_setValue // @grant GM.xmlHttpRequest // @grant GM_setClipboard // @require https://cdnjs.cloudflare.com/ajax/libs/GM_config/1.6.0/gm_config.min.js // @homepageURL https://github.com/LucasHenriqueDiniz/Mannco.Store-Item_Page_Enhancer // @supportURL https://github.com/LucasHenriqueDiniz/Mannco.Store-Item_Page_Enhancer/issues // @downloadURL https://github.com/LucasHenriqueDiniz/Mannco.Store-Item_Page_Enhancer/raw/main/Mannco.Store-Item_Page_Enhancer // @updateURL https://github.com/LucasHenriqueDiniz/Mannco.Store-Item_Page_Enhancer/raw/main/Mannco.Store-Item_Page_Enhancer // ==/UserScript== (function () { ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //def const DOMS const itemPriceBox = document.querySelector("#content > div:nth-child(4) > div > div > div.col-xl-4.col-lg-7 > div.input-group.mb-3 > input"); const quantityBox = document.querySelector("#content > div:nth-child(4) > div > div > div.col-xl-4.col-lg-7 > div.form-group > input") const itemPriceBoxBox = document.querySelector("#content > div:nth-child(4) > div > div > div.col-xl-4.col-lg-7") const pageSidebar = document.querySelector("#page-sidebar") let highestBuyOrder = Number(document.querySelector("#content > div:nth-child(4) > div > div > div.col-xl-8.col-lg-5.mt-md-3 > table > tbody > tr:nth-child(2) > td:nth-child(1)").textContent.slice(1)) if (isNaN(highestBuyOrder)) { highestBuyOrder = 0.00 } const itemPrice = parseFloat(document.querySelector("#content > div.row > div:nth-child(1) > div > div > span.important-text > span").textContent.slice(1)) const quantidadeBuyOrders = document.querySelector("#content > div:nth-child(4) > div > div > div.col-xl-8.col-lg-5.mt-md-3 > table > tbody").childElementCount - 1 const moneyAvaible = parseFloat(document.querySelector("#account-dropdown > div > span.account-balance.ecurrency").textContent.replace('$','').trim()) const parentDiv = document.querySelector("#content > div:nth-child(4) > div > div > div.col-xl-4.col-lg-7 > div.input-group.mb-3") const firstItemConteiner = document.querySelector("#page-sidebar > div.card.mb-0 > div > div.item-info > ul > li:nth-child(1) > dl > dd").textContent const utmSource = '&utm_source=https://github.com/LucasHenriqueDiniz' const currency = 1 //1 = $ | 2 = £ | 3 Euro | 4 CHLF | 5 py6 | 6 polony | 7 R$ const itemName = document.querySelector("#page-sidebar > div > div > div.card-item > h2 > span").textContent.trim() var appID = window.location.href.match(/(?<=\/)[0-9]{3,6}/g) if (appID != 440 && appID != 730 && appID != 252490 && appID != 570) { var dt = document.querySelectorAll('dt') if (dt[dt.length - 1].textContent === "SKU") { appID = 440; console.log(appID) } else if (dt[dt.length - 2].textContent === "Hero") { appID = 570; console.log(appID) } else if (dt.length === 2) { appID = 252490; console.log("lenght = 2 - appID = " + appID) } else if (dt.length === 4) { appID = 730; console.log(appID) } else { console.log("SKU NOT FOUND") appID = null; } } //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //Maps // Translator appID -> gameName var gameIdMap = { 440: 'tf2', 730: 'csgo', 252490: 'rust', 570: 'dota2' } // Mapeamento de sites para links e imagens const siteMap = { 'Tradeit.gg': { link: '', imgSrc: 'https://tradeit.gg/_nuxt/img/logo_horizontal.8189732.svg', fees: '5' }, 'Market CSGO': { link: '', imgSrc: 'https://i.imgur.com/SucZNHt.png', fees: '5' }, 'ShadowPay': { link: '', imgSrc: 'https://docs.shadowpay.com/images/logo.png', fees: '5' }, 'DMarket':{ link: `https://dmarket.com/ingame-items/item-list/${gameIdMap[appID]}-skins?title=${encodeURIComponent(itemName)}`, imgSrc: 'https://cdn.freebiesupply.com/logos/large/2x/dmarket-logo-svg-vector.svg', fees: '3' }, 'Bitskins': { link: '', imgSrc: 'https://csgo-bets.org/wp-content/uploads/2021/07/bitskins.png', fees: '2' }, 'BUFF163': { link: '', imgSrc: 'https://i.imgur.com/OgdAZZ2.png', fees: '5' }, 'Mannco.store': { link: '', imgSrc: 'https://mannco.store/statics/img/logo.svg', fees: '5' }, 'Skinport': { link: '', imgSrc: 'https://docs.skinport.com/source/images/logo.png', fees: '0' }, 'Steam': { link: `https://steamcommunity.com/market/listings/${appID}/${itemName}`, imgSrc: 'https://logodownload.org/wp-content/uploads/2018/01/steam-logo-2.png', fees: '5' }, 'CSGOFloat': { link: '', imgSrc: 'https://csgofloat.com/assets/full_logo.png', fees: '5' }, 'WAXPEER': { link: '', imgSrc: 'https://globalcsgo.com/wp-content/uploads/2021/02/waxpeer-logo-1.png', fees: '5' }, 'GamerPay': { link: '', imgSrc: 'https://i.imgur.com/uaBBvGh.png', fees: '5' }, 'Lis Skins': { link: '', imgSrc: 'https://csgo.steamanalyst.com/images/lisskins-logo.png', fees: '5' }, 'SkinBid': { link: '', imgSrc: 'https://s3.eu-west-3.amazonaws.com/skinsnipe.com/img/common/logos/markets/logo-skinbid.png', fees: '5' }, 'SkinBaron': { link: '', imgSrc: 'https://tradeplz.com/wp-content/uploads/2016/06/skinbaron-logo.png', fees: '5' }, 'CS.DEALS': { link: '', imgSrc: 'https://cs.deals/pt/assets/media-kit/logo-horizontal-full.png', fees: '5' }, 'SWAP.GG': { link: '', imgSrc: 'https://blog.swap.gg/content/images/2019/04/logo.png', fees: '2' }, 'CS.MONEY': { link: '', imgSrc: 'https://assets.csgocaptain.com/cs-money.png', fees: '3' }, 'BUFF Market': { link: '', imgSrc: 'https://i.imgur.com/Wijajmv.png', fees: '2' }, 'BitSkins': { link: '', imgSrc: 'https://csgo-bets.org/wp-content/uploads/2021/07/bitskins.png', fees: '1' }, 'CS.TRADE': { link: '', imgSrc: 'https://cs.trade/images/page/cstrade-logo.png', fees: '2' }, 'LOOT.FARM': { link: `https://loot.farm/#skin=${appID}_${itemName}`, imgSrc: 'https://i.imgur.com/IQ5VVGr.png', fees: '2' }, 'TF2.tm': { link: '', imgSrc: 'https://i.imgur.com/VMONvM3.png', fees: '2' }, /* '': { link: '', imgSrc: '', fees: '' }, */ }; // create an array of objects with necessary information const items = [ //{ imgSrc: '...', fees: '...', volume: '...', price: 10, link: '...' }, ]; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //styles var title = 'font-weight: 700;font-size: 1.5rem;color: #fff;margin-bottom: 3px;-webkit-text-stroke-width: thin;' var text = 'font-weight: 700;font-size: 1.20rem;color: #fff;' //css STYLES const cssStyles = ` .overlay { position: fixed; top: 0px; width: 100%; height: 100%; background-color: rgba(0, 0, 0, 0.5); color: white; z-index: 9; display: none; } .whiteboard { display: inline-flex; position: fixed; top: 50%; left: 50%; height: 50%; text-align: start; font-size: 20px; font-weight: 700; transform: translate(-50%, -50%); padding: 10px; background: linear-gradient(45deg, #6197a3, #7db0bd); color: white; border-radius: 10px; align-items: left; white-space: nowrap; flex-direction: column; box-shadow: 0 0 20px rgba(0, 0, 0, 0.5); overflow-y: scroll; flex-wrap: nowrap; justify-content: flex-start; white-space: nowrap; box-shadow: 0 0 20px rgba(0, 0, 0, 0.5), inset 0 0 20px rgba(255, 255, 255, 0.5); margin-top: 20px; } .close-config-button { position: absolute; top: 5px; right: 10px; background-color: transparent; cursor: pointer; } @keyframes spinner { 0% { transform: rotate(0deg); } 100% { transform: rotate(1080deg); } } .back-to-top { position: fixed; bottom: 20px; width: 50px; height: 50px; right: 1%; border: none; display: none; -webkit-text-stroke: thick; color: white; border-radius: 50%; background-color: rgb(50, 51, 81); font-size: 20px; text-align: center; box-shadow: 4px 4px 6px rgba(0, 0, 0, 0.5); cursor: pointer; transform: translateY(0%); transition: ease-out 250ms; transition-property: transform, background-color, text-decoration, color, display; } .back-to-top.show { display: block; } .hover-full-button { transition-property: color,background-color,border-color,fill,stroke,opacity,box-shadow,transform,filter,backdrop-filter,font-size; transition-timing-function: cubic-bezier(.4,0,.2,1); transition-duration: .5s; margin-top: 5%; font-weight: 700; font-size: 22px; line-height: 25px; box-sizing: border-box; padding-bottom: 0.5rem; padding-left: 1rem; padding-right: 1rem; padding-top: 3px; text-align-last: center; background-color: rgba(255, 255, 255, 0); text-align: center; color: rgb(255, 255, 255); outline: white; outline-width: thin; outline-style: auto; cursor: pointer; border-radius: 0.4em; } .hover-full-button:hover { background-color: rgba(255, 255, 255, 1); color: black; font-size: 23px; } #next-arrow { font-size: 50px; color: white; position: absolute; top: 50%;left: 7%; transition: ease-out 250ms; transition-property: transform, font-size, color, box-shadow, backgroundColor; transform: translate(-50%, -50%); border-radius: 2rem; } #next-arrow:target { transform: translate(-50%, -50%) scale(0.5); } #next-arrow:hover { transform: translate(-50%, -50%) scale(1.5); color: #2dc5e2; } .volume-wrapper { display: flex; justify-content: space-between; align-items: flex-end; width: 100%; border-radius: 0rem 0rem 1rem 1rem; padding: 0px 0px 0px 0px; transition: ease-out 400ms; transition-property: all; } .volume-wrapper:hover { transform: scale(1.005); padding: 0px 5px 0px 5px; background-color: #5ad1e8; } .vertical-market { overflow-y: scroll; max-height: 425px; overflow-x: clip; margin-top: 5px; transition: height 200ms ease-out 0s; } .vertical-market::-webkit-scrollbar { width: 5px; } .vertical-market::-webkit-scrollbar-track { background: #f1f1f1; } .vertical-market::-webkit-scrollbar-thumb { background-color: #888; border-radius: 5px; border: 1px solid #555; } .vertical-market::-webkit-scrollbar-thumb { transition: all 0.3s ease-in-out; } .vertical-market::-webkit-scrollbar-thumb:hover { background-color: #555; transform: scale(1.2); } [id^="hide-arrow"] { } [id^="hide-arrow"]:hover { transform: scale(1.5) translateY(1.5px); color: rgba(255, 255, 255, 1)!important; } .button-configs { padding: 0.5rem 1rem; font-size: 0rem; font-weight: 700; color: white; transition: height 200ms ease-out 0s; transition-property: transform, font-size, color, width; vertical-align: middle; display: flex; align-items: center; justify-content: center; background-color: #38c8e3; border-color: #2dc5e2; line-height: 1.5; border-radius: 2rem; text-align: center; -webkit-appearance: button; } .button-configs:hover { background-color: #1ba6c1; border-color: #1ba6c1; font-size: 1rem; } [id^="scale-arrow"] { transition: height 200ms ease-out 0s; transition-property: transform; } [id^="scale-arrow"]:hover { transform: scale(1.25); } .config-header { display: flex; flex-direction: column; } .config-title { background-color: #323351; text-align: center; padding: 10px; display: flex; justify-content: space-between; margin-bottom: 0px; } .config-ul { border-style: none groove groove groove; border-color: #323351; overflow-y: hidden; max-height: 0px; transition: 300ms ease-in-out 0s; transition-property: height, max-height; border-radius: 0rem 0rem 1rem 1rem; } `; const backToTopGoogleIcon = ` font-size: 45; transform: rotate(-90deg); text-align: center; display: flex; justify-content: center; ` const style = document.createElement('style'); style.appendChild(document.createTextNode(cssStyles)); document.head.appendChild(style); ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // GM settings // Objeto que armazena os valores de configuração const settings = GM_getValue('settings', {}); // Função para criar uma checkbox com valor booleano const createCheckbox = (text, name, defaultValue, title, appendElement) => { // Cria a checkbox const checkbox = document.createElement('input'); checkbox.type = 'checkbox'; checkbox.title = title checkbox.checked = settings[name] ?? defaultValue; checkbox.style.marginRight = '10px'; // Atualiza o valor da configuração correspondente quando a checkbox é clicada checkbox.addEventListener('change', () => { settings[name] = checkbox.checked; localStorage.setItem('settings', JSON.stringify(settings)); }); // Cria a label const label = document.createElement('label'); label.innerText = text; label.style.fontSize = "calc(0.5em + 0.5vw)"; label.title = title if (appendElement.children.length === 2) { label.style.marginTop = '4rem'; } label.style.marginRight = '10px'; label.style.marginBottom = '0.5rem'; label.style.display = 'flex'; const space = document.createElement('span'); space.title = title space.style.marginRight = '10px' label.appendChild(space); label.appendChild(checkbox); appendElement.appendChild(label); // Retorna o valor da configuração correspondente à checkbox return checkbox.checked; } //create a selector using a funtion, define optins before! const selector = (text, options, defaultValue, appendElement, title, name) => { // Cria a div que contém a label e o select const container = document.createElement('div'); container.style.display = 'flex'; container.title = title container.style.alignItems = 'center'; container.style.marginBottom = '10px'; // Cria a label const label = document.createElement('div'); label.innerText = text; label.style.fontSize = "calc(0.5em + 0.5vw)"; label.title = title if (appendElement.children.length === 2) { label.style.marginTop = '4rem'; } label.style.marginRight = '10px'; label.style.marginBottom = '0.5rem'; label.style.display = 'flex'; container.appendChild(label); // Cria o select const select = document.createElement('select'); select.style.marginRight = '10px'; select.name = name; // Define o nome do select como o nome da configuração // Adiciona as opções options.forEach((option) => { const optionElement = document.createElement('option'); optionElement.value = option; optionElement.text = option; select.add(optionElement); }); // Recupera o valor da configuração correspondente do armazenamento local const savedValue = localStorage.getItem(name); // Seleciona o valor salvo ou o valor padrão select.value = savedValue ?? defaultValue; // Atualiza o valor da configuração correspondente quando a opção é selecionada select.addEventListener('change', () => { settings[name] = select.value; localStorage.setItem('settings', JSON.stringify(settings)); // Salva o objeto completo no armazenamento local }); // Adiciona o select à div do container container.appendChild(select); // Adiciona a div do container ao elemento de destino appendElement.appendChild(container); // Recupera as configurações salvas do armazenamento local const savedSettings = JSON.parse(localStorage.getItem('settings')); if (savedSettings && savedSettings[name]) { // Se a configuração específica já foi salva, usa o valor salvo em vez do valor padrão select.value = savedSettings[name]; settings[name] = savedSettings[name]; } else { // Senão, usa o valor padrão e adiciona a configuração ao objeto settings[name] = defaultValue; } // Retorna o valor da configuração correspondente à opção selecionada return select.value; }; //create a valuebox using a fucntion const createNumberInput = (text, name, defaultValue, minValue, title, appendElement) => { // Cria o input de número const numberInput = document.createElement('input'); numberInput.type = 'number'; numberInput.title = title; numberInput.value = settings[name] ?? defaultValue; numberInput.min = minValue; numberInput.style.marginRight = '10px'; // Atualiza o valor da configuração correspondente quando o input é alterado numberInput.addEventListener('change', () => { settings[name] = Number(numberInput.value); localStorage.setItem('settings', JSON.stringify(settings)); }); // Cria a label const label = document.createElement('label'); label.innerText = text; label.style.fontSize = "calc(0.5em + 0.5vw)"; label.title = title if (appendElement.children.length === 2) { label.style.marginTop = '4rem'; } label.style.marginRight = '10px'; label.style.marginBottom = '0.5rem'; label.style.display = 'flex'; const space = document.createElement('span'); space.title = title; space.style.marginRight = '10px'; label.appendChild(space); label.appendChild(numberInput); appendElement.appendChild(label); // Retorna o valor da configuração correspondente ao input de número return Number(numberInput.value); } // Função para salvar as configurações const saveSettings = () => { console.log('saving...') console.log(GM_setValue('settings', settings)) GM_setValue('settings', settings); Type.alert.success('Configs Updated','') } ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //iziToast question function function showQuestionToast(title, onYes, onNo) { iziToast.question({ timeout: 10000, transitionIn: 'bounceInUp', transitionOut: 'bounceInDown', layout: 1, close: false, overlay: true, displayMode: 'once', id: 'question', backgroundColor: 'red', iconColor: 'white', titleSize: '25', titleColor: 'white', messageSize: '25', zindex: 999, title: title, closeOnEscape: true, message: '', position: 'center', buttons: [ ['<button><b>YES</b></button>', function (instance, toast) { onYes(); instance.hide({ transitionOut: 'fadeOut' }, toast, 'button'); }, true], ['<button>NO</button>', function (instance, toast) { onNo(); instance.hide({ transitionOut: 'fadeOut' }, toast, 'button'); }], ], onClosing: function (instance, toast, closedBy) { console.info('Closing | closedBy: ' + closedBy); }, onClosed: function (instance, toast, closedBy) { console.info('Closed | closedBy: ' + closedBy); } }); } ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //Buttons FUnctions //refresh page function RefreshPage() { console.log('funcion called') window.location.reload(); } // Função para adicionar 1 centavo à maior buy order function plusOneCent() { quantityBox.value = quantidade; itemPriceBox.value = (highestBuyOrder + 0.01).toFixed(2); Item.addBuyOrder() switch (RefreshAfterButton) { case true: window.location.reload(); break; case false: break; default: console.log('error with the refreshAfter button', RefreshAfterButton) } } //function to calculate a profit from a buy order function calculateFees(x) { var valor = 0 if (typeof x === 'string' && x.indexOf(',') !== -1) { valor = parseFloat(x.replace(',','.')) } else { valor = parseFloat(x) } if (valor <= 0.00) { return parseFloat(0.00) } else if (valor === 0.01) { return parseFloat(valor).toFixed(2) } else if (valor <= 0.10) { return parseFloat(valor - 0.01).toFixed(2) } else if (valor <= 0.20) { return parseFloat(valor - 0.02).toFixed(2) } else { return parseFloat(valor - (valor * 5/100)).toFixed(2) } } // function CheckLucro(BuyOrder) { let FixedOrder = parseFloat(BuyOrder).toFixed(2) var AfterFees = parseFloat(calculateFees(itemPrice)); var profit = (AfterFees - FixedOrder).toFixed(2); console.log(FixedOrder, AfterFees, profit); return parseFloat(profit); } //function to update the value of the afterFees function function updateAfterFees() { var value = parseFloat(itemPriceBox.value); var afterFees = parseFloat(calculateFees(value)).toFixed(2); var profit = parseFloat(CheckLucro(value)) let quantity = quantityBox.value if (quantityBox.value === '') { quantity = 1 } var totalProfit = (profit * quantity).toFixed(2) // verificação do valor de afterFees if (isNaN(afterFees)) { afterFeesElement.textContent = "After fees: $NaN"; } else { afterFeesElement.textContent = `After fees: ${afterFees}` afterFeesElement.title = `Basically, the fees are calculated as follows: for amounts greater than 0.10, a fee of -0.01 is applied; for amounts greater than 0.20, a fee of -0.02 is applied; for amounts less than 0.20, a fee of -5% is applied`; } if (isNaN(profit)) { ProfitElement.textContent = "Profit: $NaN" } else { ProfitElement.textContent = `Profit - One: ${profit}, Total: ${totalProfit}` ProfitElement.title = `The profit is calculated by \nsubtracting the fees (after fees = ${calculateFees(itemPrice)}) and your buy order (${value}) from the current selling price (${itemPrice}),\n and then multiplying the result by the current quantity (${quantity}). This gives the total profit (${profit}).`; } } //adds a function for just one cent function justOneCentFunction() { itemPriceBox.value = 0.01 try { quantidade = customQuantityJustOneCent; } catch (err) { quantidade = 50 console.log('error with customQuantityJustOneCent, value:', customQuantityJustOneCent) } switch (ajustWithAvaibleMoney) { case true: // Verifica se é necessário diminuir a quantidade if ((0.01) * quantidade > moneyAvaible) { quantidade = Math.floor(moneyAvaible / (0.01)); } break; case false: break; default: console.log('error with ajustWithAvaibleMoney, value:', ajustWithAvaibleMoney) } } //function to a loading circle function loadingCircle(element) { var loader = document.createElement('div'); // add the "loader" class to the div element loader.classList.add('loader'); loader.id = 'loadingCircle' // set the styles for the loader loader.style.margin = 'auto'; loader.style.border = '5px solid #5ad1e8'; loader.style.borderRadius = '50%'; loader.style.borderTop = '5px solid #0f111e'; loader.style.width = '25px'; loader.style.height = '25px'; loader.style.animation = 'spinner 4s linear infinite'; element.appendChild(loader); } ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // GOOGLE ICONS //Adds google icons to the page const link = document.createElement('link'); link.rel = 'stylesheet'; link.href = 'https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@48,400,0,0'; document.head.appendChild(link); // function to create a google icon and append to the element function googleIcon(iconName,IDname , element, cssStyle) { //iconName the name of the icon 'navigate_next, navigate_before' //iconSize the size of the icon "INT" //element = where you want the icon to be appeneded const icon = document.createElement('span'); if (cssStyle != 'none' && cssStyle != 0) { icon.style.cssText = cssStyle } icon.classList.add('icon-asset', 'material-symbols-outlined'); icon.id = IDname icon.textContent = iconName.toLowerCase() element.appendChild(icon); } ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // APICALLS functions //add decimal 420 -> 4.20 699 -> 6.99 function addDecimal(num) { // Converte o número em uma string let numStr = num.toString(); // Adiciona um zero à esquerda se o número for menor do que 100 if (numStr.length < 3) { numStr = '0' + numStr; } // Insere um ponto duas casas à esquerda do final da string let resultStr = numStr.slice(0, -2) + '.' + numStr.slice(-2); // Converte a string resultante de volta em um número e retorna return parseFloat(resultStr); } // function createRow(imgSrc, fees, volume, price, link) { let marketRow = document.createElement('div'); marketRow.style.cssText = ` align-items: center; position: relative; background: rgb(51, 51, 81); border-radius: 1rem; width: 100%; margin-bottom: 4px!important; margin-right: 0!important; padding: 0; margin: 12px 0; `; let imgHolder = document.createElement('div'); imgHolder.style.display = 'flex'; imgHolder.style.justifyContent = 'center'; marketRow.appendChild(imgHolder) let icon = document.createElement('img'); icon.src = imgSrc; icon.style.maxWidth = '80%'; icon.style.maxHeight = '80px'; icon.style.paddingTop = '10px'; imgHolder.appendChild(icon); let feesValue = document.createElement('div'); feesValue.innerText = fees + "%"; feesValue.style.fontSize = '16px'; feesValue.style.padding = '0px 0px 0px 10px'; feesValue.style.color = 'white'; feesValue.style.display = 'flex'; feesValue.style.flexDirection = 'column'; feesValue.style.justifyContent = 'center'; feesValue.title = "This value is the current fees from the marketplace"; imgHolder.appendChild(feesValue); googleIcon('Info', 'back-arrow', feesValue, 'font-size: 15px; margin-left: 3px; color: #9EA7B3') let divider = document.createElement('hr'); divider.style.border = 'none'; divider.style.borderTop = '1px solid rgba(16,24,34,.5)'; divider.style.marginTop = '8px'; divider.style.marginBottom = '0px'; marketRow.appendChild(divider); let priceVolumeWrapper = document.createElement('div'); priceVolumeWrapper.className = 'volume-wrapper' priceVolumeWrapper.addEventListener('click', function() { //ex -> `https://steamcommunity.com/market/listings/${appID}/${encodeURIComponent(itemName)}`; window.open(link) }) marketRow.appendChild(priceVolumeWrapper); let itemVolume = document.createElement('div'); itemVolume.innerText = volume + " available"; itemVolume.style.fontSize = '16px'; itemVolume.style.color = 'white'; itemVolume.style.padding = '0px 15px 15px 15px' itemVolume.style.display = 'flex' itemVolume.style.flexDirection = 'column-reverse' priceVolumeWrapper.appendChild(itemVolume); let buy = document.createElement('span'); buy.innerText = "Buy"; buy.style.fontSize = '12px'; buy.style.color = '#3b84af'; buy.style.marginRight = '5px'; buy.style.margiTop = '5px'; buy.style.transform = 'translateY(10%)'; itemVolume.appendChild(buy); let itemPrice = document.createElement('div'); itemPrice.innerText = price; itemPrice.style.fontSize = '24px'; itemPrice.style.fontWeight = 'bold'; itemPrice.style.color = 'white'; itemPrice.style.padding = '10px 15px 15px 0px' itemPrice.style.display = 'flex'; itemPrice.style.flexDirection = 'row-reverse'; itemPrice.style.alignItems = 'flex-end'; priceVolumeWrapper.appendChild(itemPrice); let from = document.createElement('span'); from.innerText = "from"; from.style.fontSize = '12px'; from.style.color = '#3b84af'; from.style.transform = 'translateY(-15%)'; from.style.marginRight = '5px'; itemPrice.appendChild(from); verticalMarkets.appendChild(marketRow); } //WEBSCRAPPER async function webScrapping(name, url, mode, volumeElement, priceElement) { return new Promise(resolve => { GM.xmlHttpRequest({ method: "GET", url: url, onload: async function(response) { let parser = new DOMParser(); let htmlDocument = parser.parseFromString(response.responseText, "text/html"); console.log(`Requesting value for ${name}`) let volume = null; let price = null; let link = null; let count = 0; const intervalId = setInterval(async function() { if (count < 5) { console.log(`${name} | waiting to load...`) if (htmlDocument.querySelector(priceElement)) { console.log(`${name} | price element check pass`) switch (mode) { case 'count': volume = htmlDocument.querySelectorAll(volumeElement).length break; case 'text': volume = volumeElement.textContent break; case 'command': volume = volumeElement break; case 'children': volume = volumeElement.children.length break; default: console.log(`\n \u001b[31m ${name} | Not a valid mode, please use "count" to count how many child elements, "text" to take an textContent from the elemnet and 'command' to use a command \n`) break; } let test = htmlDocument.querySelector(priceElement); try{ price = test.textContent.replaceAll('\n', '').trim() } catch (err) { console.log(`\n \u001b[31m ${name} | error with the price element in the webscrapping of the site ${name} \n`) } link = url + utmSource if (price) { console.log(`${name} - Encontrado! O item "${itemName}" custa: ${price} | volume: ${volume}`); const { imgSrc, fees } = siteMap[name] items.push({ imgSrc, fees, volume, price, link }); displayItems() } else { console.log("\n O item não foi encontrado na lista de resultados. \n"); } clearInterval(intervalId) } count++; } else { clearInterval(intervalId); console.log(`\n \u001b[31m give up in the webscrapping of the site ${name} \n`) console.log('url : ', url) console.log('priceElem: ', priceElement) console.log('volumeElem: ', volumeElement) } }, 10000); resolve(); }, onerror: function(error) { console.error(error); resolve(); } }); }); } //Create a row using items arr function displayItems() { const verticalMarket = document.querySelector(".vertical-market") console.log('Updating items arr and display box') document.querySelector("#page-sidebar > div.vertical-market").innerHTML = ""; items.sort((a, b) => parseFloat(a.price.replace('$','').trim()) - parseFloat(b.price.replace('$','').trim())); items.forEach(item => { createRow(item.imgSrc, item.fees, item.volume, item.price, item.link); }); if (verticalMarket.children >= 3) { verticalMarket.style.maxHeight = verticalMarket.children[0].clientHeight + verticalMarket.children[1].clientHeight + verticalMarket.children[2].clientHeight + 10 * 3 + 'px' } if (verticalMarket.children.length === 4 && !document.querySelector("#hide-arrow\\ markets")) { console.log('3 children') var colapseButton = document.createElement('div') pageSidebar.appendChild(colapseButton) googleIcon('expand_more', 'hide-arrow markets' , colapseButton, 'font-size: 50px; transition: height 200ms ease-out 0s; transition-property: transform, color; color: rgba(0,0,0,0.5);}') colapseButton.addEventListener('click', () => { if (itemHideButton.dataset.value === "off") { itemHideButton.dataset.value = "on"; document.querySelector("#hide-arrow\\ markets").innerHTML = 'expand_more' itemHideButton.title = "Colapse markets box"; document.querySelector("#page-sidebar > div.vertical-market").style.maxHeight = verticalMarket.children[0].clientHeight + verticalMarket.children[1].clientHeight + verticalMarket.children[2].clientHeight + 10 * 3 + 'px'; } else { itemHideButton.dataset.value = "off"; document.querySelector("#hide-arrow\\ markets").innerHTML = 'expand_less' itemHideButton.title = "Hide markets box"; document.querySelector("#page-sidebar > div.vertical-market").style.maxHeight = '5000px'; } }) } } //DMarket function DMarketAPI() { const apiUrl = `https://api.dmarket.com/exchange/v1/market/items?gameId=${gameIdMap[appID]}&limit=100&title=${encodeURIComponent(itemName)}¤cy=USD&bestPrice=true&orderBy=price&orderDir=asc`; fetch(apiUrl) .then(response => response.json()) .then(data => { console.log('Requesting value for DMarket'); let volume = null; let price = null; const { imgSrc, fees, link } = siteMap["DMarket"]; const { objects } = data; volume = objects.length; price = `$${addDecimal(objects[0].price.USD)}`; if (volume || price) { console.log(`DMakert | Encontrado! O item "${itemName}" custa: ${price} | volume: ${volume}`); items.push({ imgSrc, fees, volume, price, link }); displayItems(); } else { console.log(`\n \u001b[31m Dmarket | problem finding the price for DMkaret \n`) } }) .catch(error => console.error(error)); } //SWAP.GG function SwapGGAPI () { GM.xmlHttpRequest({ method: "GET", url: `https://market-api.swap.gg/v1/pricing/lowest?appId=${appID}`, onload: function(response) { const obj = JSON.parse(response.responseText); console.log('Requesting Swap.gg item price') // Converter o objeto JSON em um array JSON let arr = Object.entries(obj.result); // Encontrar o primeiro item que corresponde ao critério de pesquisa let result = arr.find(([name]) => name.includes(itemName)); // Verificar se o item foi encontrado e obter suas propriedades if (result) { let [name, { price, quantity, link }] = result; // Formatar o preço como uma string com separador de milhares e casas decimais let formattedPrice = String(`$` + addDecimal(price)); let fullLink = link + utmSource console.log(`SWAP.GG | Encontrado! O item "${name}" custa: ${formattedPrice} | volume: ${quantity} | link: ${link}`); // Adicionar o item à lista de itens e exibir a lista let { imgSrc, fees } = siteMap["SWAP.GG"]; items.push({ imgSrc, fees, volume: quantity, price: formattedPrice, link: fullLink }); displayItems(); } else { console.log(`\n \u001b[31m SWAP.GG | problem finding the price for SWAP.gg \n`) } } }); } //SkinportAPI function SkinportAPI() { GM.xmlHttpRequest({ method: "GET", url: `https://api.skinport.com/v1/items?app_id=${appID}¤cy=USD&tradable=0`, responseType: "json", onload: function(response) { const obj = JSON.parse(response.responseText); // Converter o objeto JSON em um array JSON console.log("Requesting Skinport items"); let volume = null let price = null let link = null const filteredResults = obj.filter(item => item.market_hash_name === itemName); volume = filteredResults[0].quantity price = filteredResults[0].min_price link = filteredResults[0].market_page + utmSource console.log(volume, price, link) console.log(filteredResults) const { imgSrc, fees } = siteMap["Skinport"]; if (price || volume) { console.log(`Skinport | Encontrado! O item ${itemName} custa: $${price} | volume: ${volume} | link: ${link}`); items.push({ imgSrc, fees, volume, price: '$' + price, link }); displayItems(); } else { console.log(`\n \u001b[31m Skinport | Problem finding the price for Skinport \n`) } }, onerror: function(error) { console.error(error); } }); } //CSTRADE function CSTRADE() { GM.xmlHttpRequest({ method: "GET", url: `https://cdn.cs.trade:8443/api/getInventoryCmp?order_by=price_desc&bot=all`, responseType: "json", onload: function(response) { const obj = JSON.parse(response.responseText).inventory; // Converter o objeto JSON em um array JSON console.log("Requesting CS.trade items"); let link = `https://cs.trade/?sort_by=price_asc&market_name=${itemName}` + utmSource let result = obj.find(item => item.n === itemName); let price = result ? result.p : null; let volume = obj.reduce((count, item) => item.n === itemName ? count + 1 : count, 1); const { imgSrc, fees } = siteMap["CS.TRADE"]; if (price) { let formattedPrice = price.toLocaleString('en-US', {style: 'currency', currency: 'USD', minimumFractionDigits: 2}) console.log(`CS.TRADE | Encontrado! O item ${itemName} custa: $${price} | volume: ${volume} | link: ${link}`); items.push({ imgSrc, fees, volume, price: formattedPrice, link }); displayItems(); } else { console.log("CS.TRADE | O item não foi encontrado na lista de resultados."); } }, onerror: function(error) { console.error(error); } }); } //LOOTFARM api function LOOTFARM() { GM.xmlHttpRequest({ method: "GET", url: `https://loot.farm/botsInventory_${appID}.json`, onload: function(response) { // Analisa a resposta em JSON let obj = Object.values(JSON.parse(response.responseText).result); // Imprime os dados no console let result = obj.find(item => item.n === itemName); let price = result ? result.p : null; let arrayCount = 0; let volume = 0; for (let key in result.u) { let value = result.u[key]; if (Array.isArray(value)) { arrayCount++; volume += value.length; } } console.log("LOOT.FARM | Soma dos comprimentos dos arrays em u:", volume); let formattedPrice = `$${addDecimal(price)}`; const { imgSrc, fees } = siteMap["LOOT.FARM"]; if (price) { console.log(`LOOT.FARM |Encontrado! O item ${itemName} custa: $${price} | volume: ${volume} | link: ${link}`); items.push({ imgSrc, fees, volume, price: formattedPrice, link }); //displayItems(); } else { console.log(`\n \u001b[31m LOOT.FARM | Problem finding the price for LOOT.FARM \n`) } }, onerror: function(error) { console.error(error); } }); } //Reqeust steam prices function SteamAPI() { var apiLink = `https://steamcommunity.com/market/priceoverview/?appid=${appID}¤cy=${currency}&market_hash_name=${encodeURIComponent(itemName)}` GM.xmlHttpRequest({ method: "GET", url: apiLink, responseType: "json", onload: function (response) { var obj = JSON.parse(response.responseText); let volumeSteam = obj.volume ? obj.volume : 0; let lowestPriceSteam = obj.lowest_price ? obj.lowest_price : null; const { imgSrc, fees, link } = siteMap["Steam"]; if (lowestPriceSteam) { console.log(`Encontrado! O item "${itemName}" custa: ${lowestPriceSteam} | volume: ${volumeSteam}`); items.push({ imgSrc, fees, volume: volumeSteam, price: lowestPriceSteam, link }); displayItems(); } else { console.log("O item não foi encontrado na lista de resultados."); } } }); } ////WEB-SCRAPPERS //TRade it GG async function TradeITgg() { await webScrapping('Tradeit.gg', `https://tradeit.gg/${gameIdMap[appID]}/store?search=${encodeURIComponent(itemName)}&aff=SIH`, 'text', "#siteInventoryContainer .item-details .flex span", "#siteInventoryContainer .store-price-wrapper .price") } //BITSKINS async function Bitskins() { await webScrapping('Bitskins', `https://bitskins.com/?market_hash_name=${encodeURIComponent(itemName)}&advanced=1&appid=${appID}&show_trade_delayed_items=0&sort_by=bumped_at&sort_by=price&order=asc`, 'count',".col-lg-3.col-md-4.col-sm-5.col-xs-12.item-solo", "body > div:nth-child(10) > div > div:nth-child(3) > div > div > div:nth-child(1) > div > div.item-icon.lazy > h5 > span") } //Call for csgoskins. function requestCsgoSkins() { // Criando um objeto com as informações de float e seus respectivos links const floatMap = { 'Factory New': 'factory-new', 'Minimal Wear': 'minimal-wear', 'Field-Tested': 'field-tested', 'Well-Worn': 'well-worn', 'Battle-Scarred': 'battle-scarred' }; function getFloat(itemName) { for (let float in floatMap) { if (itemName.includes(float)) { return floatMap[float]; } } } const result = []; let float = getFloat(itemName); let link = `https://csgoskins.gg/items/${itemName.replace(' |', '').replace(/StatTrak™ ?/, '').replace(/\(.*\)/, '').replace(/★ /, '').trim().replace(/ /g, '-').toLowerCase()}/`; if ((itemName.includes('StatTrak™'))) { link += 'stattrak-' } if (float) { link += `${float}`; } GM.xmlHttpRequest({ method: 'GET', url: link, onload: function(response) { const parser = new DOMParser(); const doc = parser.parseFromString(response.responseText, 'text/html'); const elements = doc.querySelectorAll('.my-4'); const offerNodes = Array.from(elements).filter(el => el.tagName != 'BUTTON'); offerNodes.forEach(offer => { const site = offer.querySelector('.w-1\\/2.sm\\:w-1\\/4.p-4.flex-none').firstElementChild.textContent.trim(); const activeOffers = offer.querySelector('.w-1\\/4.p-4.flex-none.hidden.sm\\:block').lastElementChild?.textContent?.trim() || "N/A"; const price = offer.querySelector(".font-bold.text-xl").textContent.trim(); result.push({ site, activeOffers, price }); }); console.log(result) const rows = result.map(({ site, activeOffers, price }) => { const { link, imgSrc, fees } = siteMap[site] || {}; // Obter o link e imagem correspondentes const volume = activeOffers; //return createRow(imgSrc, fees, volume, price, link); // Chamar a função createRow com os valores apropriados items.push({ imgSrc, fees, volume, price, link }); displayItems() }); }, onerror: function(error) { console.error(error); } }); } ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // make the extenion button for configs document.querySelector("#content > h2").style.display = 'flex'; document.querySelector("#content > h2").style.justifyContent = 'space-between'; let ItemPageConfigsButton = document.createElement('button'); ItemPageConfigsButton.className = "button-configs"; ItemPageConfigsButton.textContent = "Item Page Enhancer Configs"; ItemPageConfigsButton.title = "Open configuration menu for the extension (item page enhancer)" //gear icon googleIcon('Settings','scale-arrow settings' , ItemPageConfigsButton, 'font-size: 2rem; padding: 5px') document.querySelector("#content > h2").appendChild(ItemPageConfigsButton); ItemPageConfigsButton.addEventListener('click', () => { showOverlay() }) //create a black overlay const overlay = document.createElement('div'); overlay.className = 'overlay' document.body.appendChild(overlay); //creates que whiteboard for all the elements be shown const whiteboard = document.createElement('div'); whiteboard.className = 'whiteboard'; overlay.appendChild(whiteboard); //Title const ConfigTitle = document.createElement('h2'); ConfigTitle.textContent = 'Mannco.Store - Item Page Enhancer'; whiteboard.appendChild(ConfigTitle); //clsoe button for the whiteboard const closeButton = document.createElement('span'); googleIcon('Close','scale-arrow close' , closeButton, 'font-size: 2rem; color: red') closeButton.className = 'close-config-button' whiteboard.appendChild(closeButton) closeButton.addEventListener('click', function () { hideOverlay(); saveSettings() showQuestionToast( 'Refresh the page? (recommended)', RefreshPage, function() { console.log('NO clicked'); } ); }); ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //Configs Options function addColapse(button, element) { var colapseButton = document.querySelector(button) var heightElem = document.querySelector(element) colapseButton.addEventListener('click', () => { if (colapseButton.dataset.value === "off") { colapseButton.dataset.value = "on"; colapseButton.style.transform = 'rotate(0deg)'; colapseButton.title = "Expand Menu"; heightElem.style.maxHeight = '' } else { colapseButton.dataset.value = "off"; colapseButton.style.transform = 'rotate(90deg)'; colapseButton.title = "Hide menu"; heightElem.style.maxHeight = '1000px' } }) } ////////////////////////////////////////////////////////////////////////////////////////// //BUTTONS const BuyOrderButtons = document.createElement('div') BuyOrderButtons.className = 'config-header buyorder-buttons' whiteboard.appendChild(BuyOrderButtons) const ulBuyOrderButtons = document.createElement('ul'); ulBuyOrderButtons.className = 'config-ul buyorder-buttons' // cria um cabeçalho para page configs const headerButtonBuyOrder = document.createElement('h4'); headerButtonBuyOrder.className = 'config-title buyorder-buttons' headerButtonBuyOrder.textContent = 'BuyOrder buttons'; BuyOrderButtons.appendChild(headerButtonBuyOrder) const BoB1 = document.createElement('li'); const BoB2 = document.createElement('li'); const BoB3 = document.createElement('li'); ulBuyOrderButtons.appendChild(BoB1) ulBuyOrderButtons.appendChild(BoB2) ulBuyOrderButtons.appendChild(BoB3) // adiciona o ul de page configs ao elemento whiteboard BuyOrderButtons.appendChild(ulBuyOrderButtons); googleIcon('chevron_right','scale-arrow buttons-colapse' , headerButtonBuyOrder, 'font-size: 2.5rem') addColapse("#scale-arrow\\ buttons-colapse", ".config-ul.buyorder-buttons") //buttons const Add1CentButton = createCheckbox('"Boost Order" button: ', '+1cent', true, 'Adds a button to automatically create a buy order for the highest value plus 0.01 cents.', BoB1); const AddJustOneCentButton = createCheckbox('"Buy for One Cent" button: ', 'JustOneCent', false, '"Adds a button to automatically create a buy order for 0.01 cents.', BoB2); const AddMatchButton = createCheckbox('"Create Matching Order" button: ', 'MatchBuyOrder', false, '"Adds a button to automatically create a buyorder with the same value as the highest buy order', BoB3); ////////////////////////////////////////////////////////////////////////////////////////// //BUTTON CONFIGS const ButtonsConfigsDiv = document.createElement('div') ButtonsConfigsDiv.className = 'config-header buttons-config' whiteboard.appendChild(ButtonsConfigsDiv) // cria outro elemento ul para button configs const ulButtonConfigs = document.createElement('ul'); ulButtonConfigs.className = 'config-ul buttons-config' // cria um cabeçalho para button configs const headerButtonConfigs = document.createElement('h4'); headerButtonConfigs.className = 'config-title buttons-config' headerButtonConfigs.textContent = 'Button Configs'; const BC1 = document.createElement('li'); const BC2 = document.createElement('li'); const BC3 = document.createElement('li'); const BC4 = document.createElement('li'); const BC5 = document.createElement('li'); const BC6 = document.createElement('li'); const BC7 = document.createElement('li'); const BC8 = document.createElement('li'); ButtonsConfigsDiv.appendChild(headerButtonConfigs) ulButtonConfigs.appendChild(BC1) ulButtonConfigs.appendChild(BC2) ulButtonConfigs.appendChild(BC3) ulButtonConfigs.appendChild(BC4) ulButtonConfigs.appendChild(BC5) ulButtonConfigs.appendChild(BC6) ulButtonConfigs.appendChild(BC7) ulButtonConfigs.appendChild(BC8) ButtonsConfigsDiv.appendChild(ulButtonConfigs); googleIcon('chevron_right','scale-arrow configs-colapse' , headerButtonConfigs, 'font-size: 2.5rem') addColapse("#scale-arrow\\ configs-colapse", ".config-ul.buttons-config") //buttons organize and configs const OrganizeButtons = createCheckbox('Organize buttons layout: ', 'OrganizeButtons', true, 'Changes the layout for the buttons making better ( in my opnion )', BC1); // in future more options nad make a selection box const RefreshAfterButton = createCheckbox('Auto Refresh page after +1cent/JustOneCent/MatchBuyOrder click: ', 'Refresh+1andJust', false,'Automatically refreshes the page after clicking the Boost Order, Buy for One Cent, or Match Buy Order buttons, to ensure that the buy order has been added or updated.', BC2); const OnKeyPress1Cent = createCheckbox('Activate +1cent feature on keypress: ', '1CentOnKeyPress', false,'In Development', BC3); const OnKeyPressJustOneCent = createCheckbox('Activate JustOneCent feature on keypress: ', 'JustOneCentOnKeyPress', false,'In Development', BC4); const customQuantity1Cent = createNumberInput('Custom "Boost Order" BuyOrder quantity: ', 'customQuantity1Cent', '0', '0', 'Enables customization of the quantity for buy orders from the "Boost Order" button. The default values are: 20 for 0.02 or less, 10 for 0.05 or less, 5 for 3.00 or less, and 1 for prices above that. Entering a value will make all buy orders have the same quantity, independent of the item price. ( 0 = default )', BC5) const customQuantityJustOneCent = createNumberInput('Custom "Buy for One Cent" BuyOrder quantity: ', 'customQuantityJustOneCent', '50', '0', 'Enables customization of the quantity for buy orders from the "Boost Order" button. The default value is (50) entering a value will make all buy orders have that quantity', BC6) const customQuantityMatchingOrder = createNumberInput('Custom "Create Matching Order" BuyOrder quantity: ', 'customQuantityMatchingBuyOrder', '10', '0', 'Enables customization of the quantity for buy orders from the "Create Matching Order" button. The default value is (10) entering a value will make all buy orders have that quantity', BC7) const ajustWithAvaibleMoney = createCheckbox('Automatically adjust the buy order quantity based on the available funds in the wallet: ', 'ajustWithAvaibleMoney', true, 'Automatically adjust the buy orders from the buttons based on the available funds in the wallet. For example, if you have $5.00 in your wallet and the buy order is for 10 items at $1.00 each, the order will be adjusted to 5 items.', BC8) ///////////////////////////////////////////////////////////////////////////////////////////////////////////////// //page configuration const pageConfigDiv = document.createElement('div') pageConfigDiv.className = 'config-header page-config' whiteboard.appendChild(pageConfigDiv) // cria outro elemento ul para button configs const ulPageConfig = document.createElement('ul'); ulPageConfig.className = 'config-ul page-config' // cria um cabeçalho para button configs const headerPageConfig = document.createElement('h4'); headerPageConfig.className = 'config-title page-config' headerPageConfig.textContent = 'Misc page configuration'; const PG1 = document.createElement('li'); const PG2 = document.createElement('li'); const PG3 = document.createElement('li'); const PG4 = document.createElement('li'); const PG5 = document.createElement('li'); const PG6 = document.createElement('li'); const PG7 = document.createElement('li'); const PG8 = document.createElement('li'); pageConfigDiv.appendChild(headerPageConfig) ulPageConfig.appendChild(PG1) ulPageConfig.appendChild(PG2) ulPageConfig.appendChild(PG3) ulPageConfig.appendChild(PG4) ulPageConfig.appendChild(PG5) ulPageConfig.appendChild(PG6) ulPageConfig.appendChild(PG7) ulPageConfig.appendChild(PG8) pageConfigDiv.appendChild(ulPageConfig); const ChangeBackGroundForNoBuyOrderOptions = ['Red/Green Background', 'Red/Green border', 'none']; const ChangeBackGroundForNoBuyOrder = selector("Changes buy orders background if no matching buy order: ", ChangeBackGroundForNoBuyOrderOptions, "Red/Green Background", PG1,'Select between a Red/Green border, Red/Green background, or none. The chosen selection will create a green or red highlight depending on whether you have the highest buy order (green) or not (red).' ,"ChangeBackGroundForNoBuyOrderOptions"); const backToTheTopButton = createCheckbox('Add a button to go to the top of the page: ', 'backToTheTopButton', true, 'add back to the top button', PG2) const ProfitCalculator = createCheckbox('Profit Calculator :', 'ProfitCalculator', true,'Displays an estimate of profits based on the buy orders, current sell value, and fees for buy orders made by other users. ( from the buy orders box )', PG3); const FeesCalculator = createCheckbox('Show fees value in itemPrice', 'FeesCalcualtor', true,'Adds text showing the fees value and the profit with the current buy order.', PG4); const viewOnSwapGG = createCheckbox('add a button to open csgo skin in swap.gg', 'viewOnSwapGG', true, 'adds a button who open a link with the swap.gg inspect tool.', PG5); const smallFixes = createCheckbox('Small Fixes: ', 'smallFixes', true,'Fix some small things that annoy me', PG6); const GraphButtonOptions = ['button', 'remove', 'default']; const GraphButton = selector('Button/Remove Sales Graph: ', GraphButtonOptions, "button", PG7, "This selection box allows you to customize the display of the sales chart on the website. Choose 'default' to keep it as it is, 'none' to remove the sales chart altogether, or 'button' to create a button that can expand and collapse the chart as needed."); const copyPriceToClipboard = createCheckbox('Add button to copy item price to cliboard: ', 'copyPriceToClipboard', true,'add a button to copy the price from the page', PG8); googleIcon('chevron_right','scale-arrow page-configs-colapse' , headerPageConfig, 'font-size: 2.5rem') addColapse("#scale-arrow\\ page-configs-colapse", ".config-ul.page-config") //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// const marketplacesDiv = document.createElement('div') marketplacesDiv.className = 'config-header marketplaces' whiteboard.appendChild(marketplacesDiv) const ulMarketplaces = document.createElement('ul'); ulMarketplaces.className = 'config-ul marketplaces' // cria um cabeçalho para page configs const headerMarketplaces = document.createElement('h4'); headerMarketplaces.className = 'config-title marketplaces' headerMarketplaces.textContent = 'Marketplaces information configuration'; marketplacesDiv.appendChild(headerMarketplaces) const M1 = document.createElement('li'); const M2 = document.createElement('li'); const M3 = document.createElement('li'); ulMarketplaces.appendChild(M1) ulMarketplaces.appendChild(M2) ulMarketplaces.appendChild(M3) // adiciona o ul de page configs ao elemento whiteboard marketplacesDiv.appendChild(ulMarketplaces); googleIcon('chevron_right','scale-arrow marketplaces-colapse' , headerMarketplaces, 'font-size: 2.5rem') addColapse("#scale-arrow\\ marketplaces-colapse", ".config-ul.marketplaces") //Marktplaces status const SteamStatus = createCheckbox('SteamStatus: ', 'SteamStatus', true,'Adds a box showing the values for in steam for the item', M1); const backpackTFstatus = createCheckbox('Backpack.tf item status: ', 'BPTFstatus', true, 'AddDesc', M2); const ExtraStatus = createCheckbox('Show Status for more sites?', 'ExtraStatus', false,'In Development', M3);/* //bitskins Bitskins() //DMarket DMarketAPI() //SWAP.GG SwapGGAPI() //Skinport SkinportAPI() //CS.TRADE CSTRADE() //LOOTFARM LOOTFARM() //TradeITgg TradeITgg()*/ //const chooseCurrencyOptions = ['$ - Dolar', 'Euro', '3', '4', '5', '6', 'R$ - Real'] //const chooseCurrency = selector('choose the currency for the steamStatus and others', chooseCurrencyOptions, "$- Dolar", whiteboard, 'Choose the currency for the steam price and such') ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //functions for the close button function showOverlay() { overlay.style.display = 'block'; whiteboard.style.display = 'flex'; ; } function hideOverlay() { overlay.style.display = 'none'; whiteboard.style.display = 'none'; } ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //Show/Hide Graph Button switch (GraphButton) { case 'remove': document.querySelector("#content > div:nth-child(3)").style.display = 'none' break; case 'button': var header = document.querySelector("#content > div:nth-child(3) > div > h3"); var content = document.querySelector("#content > div:nth-child(3) > div"); //Makes default hide content.style.maxHeight = "50px"; content.style.transitionProperty = 'max-height, height' content.style.transition = 'ease-out 200ms' // Cria o botão var salesGraphicBtn = document.createElement('button'); salesGraphicBtn.textContent = "Show sales graphic"; salesGraphicBtn.style.position = 'absolute'; salesGraphicBtn.style.top = '15px'; salesGraphicBtn.style.right = '20px'; salesGraphicBtn.className = "btn btn-primary salesGraphicBtn"; salesGraphicBtn.title = "Show the sales History graphic with the sales details for this item"; //salesGraphicBtn.classList.add(""); header.appendChild(salesGraphicBtn); // Define o comportamento do botão salesGraphicBtn.addEventListener('click', () => { if (salesGraphicBtn.dataset.value === "off") { salesGraphicBtn.dataset.value = "on"; salesGraphicBtn.textContent = "Show sales graphic"; content.style.maxHeight = "50px"; } else { salesGraphicBtn.dataset.value = "off"; salesGraphicBtn.textContent = "Hide sales graphic"; content.style.maxHeight = "500px"; } }); break; case 'default': console.log('default') break; default: console.log('problem with the GraphButton, value: ', GraphButton) break; } ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //1+CentButton switch (Add1CentButton) { case true: // Definir quantidade de buy orders de maneira segura var quantidade; if (customQuantity1Cent === 0) { quantidade = (highestBuyOrder < 0.02) ? 20 : (highestBuyOrder < 0.10) ? 10 : (highestBuyOrder < 1) ? 5 : 1; } else { quantidade = customQuantity1Cent; } switch (ajustWithAvaibleMoney) { case true: // Verifica se é necessário diminuir a quantidade if ((highestBuyOrder + 0.01) * quantidade > moneyAvaible) { quantidade = Math.floor(moneyAvaible / (highestBuyOrder + 0.01)); } break; case false: break; default: console.log('error with ajustWithAvaibleMoney, value:', ajustWithAvaibleMoney) } // Cria botão para a ordem de compra de 1 centavo var centOrder = document.createElement("button"); centOrder.id = "AutoOrder"; centOrder.className = "btn btn-primary AutoOrder"; centOrder.style.marginTop = '5px'; centOrder.innerHTML = "Boost Order"; centOrder.title = 'Create a buy order using the (highest buy order value + 0.01)' itemPriceBoxBox.appendChild(centOrder); centOrder.addEventListener("click", plusOneCent); break; case false: break; default: console.log('Problem with the Add1Cent, value:', Add1CentButton) break } ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //Just One Cent Button switch (AddJustOneCentButton) { case true: var justOneCent = document.createElement("button"); justOneCent.id = "AutoOrder"; justOneCent.className = "btn btn-primary AutoOrder"; justOneCent.style.marginTop = '5px' justOneCent.innerHTML = "Buy for One Cent" justOneCent.title = "Create a buy order for 0.01"; itemPriceBoxBox.appendChild(justOneCent); justOneCent.addEventListener("click", justOneCentFunction); break; case false: break; default: console.log('Error with AddJustOneCentButton, value:',AddJustOneCentButton) } ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //Create Matching Order //switch ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //Organize Buttons switch (OrganizeButtons) { case true: itemPriceBoxBox.childNodes[11].style.marginLeft = '0' itemPriceBoxBox.childNodes[11].style.display = 'flex'; itemPriceBoxBox.childNodes[11].style.flexDirection = 'column'; document.querySelector("#content > div:nth-child(4) > div > div > div.col-xl-4.col-lg-7 > form > button").style.marginTop = '5px'; itemPriceBoxBox.style.display = 'flex'; itemPriceBoxBox.style.flexDirection = 'column'; break; case false: console.log('dont organize sadpepe') break; default: console.log('Problem with OrganizeButtons value:', OrganizeButtons) break; } ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //SteamStatus switch (SteamStatus) { case true: var verticalMarkets = document.createElement('div'); verticalMarkets.className = 'vertical-market' pageSidebar.appendChild(verticalMarkets); if (appID == 730) { requestCsgoSkins() } else { //STEAM SteamAPI() //bitskins Bitskins() //DMarket DMarketAPI() //SWAP.GG SwapGGAPI() //Skinport SkinportAPI() //CS.TRADE CSTRADE() //LOOTFARM LOOTFARM() //TradeITgg TradeITgg() } break; case false: break; default: console.log('Problem with the vertical markets.') } ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //ExtraStatus //switch ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //onKeyPress exec 1+ cent //switch ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //Red/Green Border/NoBorder None background for box //switch switch (ChangeBackGroundForNoBuyOrder) { case 'Red/Green Background': if (itemPriceBox.value === highestBuyOrder) { itemPriceBoxBox.parentElement.parentElement.style.backgroundColor = 'green' } else { itemPriceBoxBox.parentElement.parentElement.style.backgroundColor = 'red' } break; case 'Red/Green border': if (itemPriceBox.value === highestBuyOrder) { itemPriceBoxBox.parentElement.parentElement.style.borderStyle = 'inset'; itemPriceBoxBox.parentElement.parentElement.style.borderRadius = 'inherit'; itemPriceBoxBox.parentElement.parentElement.style.borderColor = 'green'; } else { itemPriceBoxBox.parentElement.parentElement.style.borderStyle = 'inset'; itemPriceBoxBox.parentElement.parentElement.style.borderRadius = 'inherit'; itemPriceBoxBox.parentElement.parentElement.style.borderColor = 'red'; } break; case 'none': break; default: console.log('error in ChangeBackGroundForNoBuyOrder', ChangeBackGroundForNoBuyOrder) } ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //Profit Calculator switch (ProfitCalculator) { case true: var ProfitLabel = document.createElement('th') ProfitLabel.scope = 'col' ProfitLabel.title = 'The profit is calculated by [(fees - BuyValue) - SellValue]' ProfitLabel.textContent = "Profit" document.querySelector("#content > div:nth-child(4) > div > div > div.col-xl-8.col-lg-5.mt-md-3 > table > tbody > tr:nth-child(1)").appendChild(ProfitLabel) for (var i = 1; quantidadeBuyOrders >= i; i++) { let currentBuyOrderRaw = document.querySelector(`#content > div:nth-child(4) > div > div > div.col-xl-8.col-lg-5.mt-md-3 > table > tbody > tr:nth-child(${i + 1}) > td:nth-child(1)`); let currentBuyOrder = currentBuyOrderRaw.textContent.slice(1).replace(' or less', ''); currentBuyOrderRaw.parentElement.addEventListener('click', () => { itemPriceBox.value = currentBuyOrder; try { updateAfterFees() } catch(err) { console.log(updateAfterFees()) console.log(err) } }); currentBuyOrderRaw.parentNode.addEventListener('mouseover', () => { currentBuyOrderRaw.parentNode.style.backgroundColor = 'rgba(255, 255, 255, 0.3)'; currentBuyOrderRaw.parentNode.style.transition = 'background-color 0.2s ease 0s'; }); currentBuyOrderRaw.parentNode.addEventListener('mouseout', () => { currentBuyOrderRaw.parentNode.style.backgroundColor = 'rgba(0, 0, 0, 0)'; currentBuyOrderRaw.parentNode.style.transition = 'background-color 0.2s ease 0s'; }); var NewElement = document.createElement('td') NewElement.textContent = ("$" + CheckLucro(currentBuyOrder)) document.querySelector("#content > div:nth-child(4) > div > div > div.col-xl-8.col-lg-5.mt-md-3 > table > tbody").children[i].appendChild(NewElement) try { if (i % 2 != 0) { currentBuyOrder.style.backgroundColor = 'rgba(0, 0, 0, 0.5)' } } catch (TypeError) { } } break; case false: break; default: console.log('some error with the profit calculator, value: ', ProfitCalculator) } ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //AfterFees and PRofit with current BUy Order switch (FeesCalculator) { case true: var afterFeesElement = document.createElement("div"); afterFeesElement.textContent = "After fees: $NaN"; // definindo o conteúdo inicial afterFeesElement.style.color = "gray"; afterFeesElement.style.position = "absolute"; afterFeesElement.style.bottom = "0"; afterFeesElement.style.left = "0"; afterFeesElement.style.width = "100%"; afterFeesElement.style.textAlign = "center"; afterFeesElement.style.paddingBottom = '5px'; itemPriceBox.parentNode.appendChild(afterFeesElement); afterFeesElement.style.height = (afterFeesElement.offsetHeight * 2 + 'px') var ProfitElement = document.createElement("div"); ProfitElement.textContent = "Profit: $NaN"; // definindo o conteúdo inicial ProfitElement.style.color = "gray"; ProfitElement.style.position = "absolute"; ProfitElement.style.bottom = "0"; ProfitElement.style.left = "0"; ProfitElement.style.width = "100%"; ProfitElement.style.textAlign = "center"; ProfitElement.style.paddingBottom = '5px'; itemPriceBox.parentNode.appendChild(ProfitElement); // small fixes itemPriceBoxBox.childNodes[1].style.marginBottom = '25px'; itemPriceBoxBox.childNodes[1].style.fontSize = '1.5rem' itemPriceBox.style.backgroundColor = 'rgba(0, 0, 0, 0.3)'; itemPriceBox.style.borderRadius = '1rem 0 1rem 0' //add update function to itemPricebox itemPriceBox.addEventListener("input", updateAfterFees); itemPriceBox.addEventListener("change", updateAfterFees); var parentHeight = itemPriceBox.offsetHeight + afterFeesElement.offsetHeight + 10; parentDiv.style.height = parentHeight + "px"; parentDiv.style.backgroundColor = '#202334' parentDiv.style.borderRadius = '1rem'; document.querySelector("#recipient-username-addon").style.borderBottomRightRadius = '2rem' document.querySelector("#recipient-username-addon").style.borderTopRightRadius = '1rem' break; case false: break; default: console.log('error in the fees calculator') } ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //small fixes switch (smallFixes) { case true: document.querySelector("#header-navbar > ul.navbar-nav.header__navbar-links > li:nth-child(1)").remove() document.querySelector("#content > div:nth-child(4) > div > div > div.col-xl-4.col-lg-7 > p").style.display = 'none' itemPriceBoxBox.parentElement.parentElement.style.borderRadius = '1rem' itemPriceBoxBox.childNodes[1].style.marginBottom = '10px'; itemPriceBoxBox.childNodes[1].style.fontSize = '1.5rem' var cardBodies = document.querySelectorAll('.card-body'); cardBodies.forEach(cardBody => { cardBody.style.boxShadow = '3 3 15px rgba(0, 0, 0, 0.3)'; }); break; case false: break; default: console.log('Problem with smallFixes, value:', smallFixes) break } ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //options ask if want to RefreshPage() after the +1cent and JustOneCent // in the plusOneCent and JustOneCent functions ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Back to the top button switch (backToTheTopButton) { case true: var backToTopButton = document.createElement("button"); backToTopButton.innerHTML = ""; googleIcon('navigate_next', 'navigateNext', backToTopButton, backToTopGoogleIcon) backToTopButton.title = 'go back to the top of the page' backToTopButton.classList.add("back-to-top"); document.body.appendChild(backToTopButton); // had a hardtime working with cssstyles so i decided just implemente everything using js fuckit backToTopButton.addEventListener("click", function() { window.scrollTo({ top: 0, behavior: "smooth" }); }); backToTopButton.addEventListener('mouseover', () => { backToTopButton.style.backgroundColor = 'rgb(90 209 232)' backToTopButton.style.color = 'black' backToTopButton.style.borderTopStyle = 'outset' backToTopButton.style.borderTopColor = 'rgba(255,255,255,0.3)' backToTopButton.style.borderTopWidth = 'medium' backToTopButton.style.borderBottomStyle = 'outset' backToTopButton.style.borderBottomColor = 'rgba(0,0,0,0.5)' backToTopButton.style.borderBottomWidht = 'medium' backToTopButton.style.boxShadow = '4px 4px 10px rgba(255, 255, 255, 0.3)' backToTopButton.style.transform = "translateY(-22%)"; }); backToTopButton.addEventListener('mouseout', () => { backToTopButton.style.boxShadow = '4px 4px 10px rgba(0, 0, 0, 0.5)' backToTopButton.style.backgroundColor = 'rgb(50, 51, 81)' backToTopButton.style.border = 'none' backToTopButton.style.color = 'white' backToTopButton.style.transform = "translateY(0%)"; }); window.addEventListener("scroll", function() { // Calcula a posição atual da rolagem em relação à altura total da página const scrollPosition = window.scrollY; const totalHeight = document.body.clientHeight - window.innerHeight; const scrollPercentage = scrollPosition / totalHeight * 100; // Atualiza a classe do botão com base na posição atual da rolagem if (scrollPercentage > 75) { backToTopButton.classList.add("show"); } else { backToTopButton.classList.remove("show"); } }); break; case false: break; default: console.log('problem with back to the top, value: ', backToTheTopButton) } ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //copy prices switch (copyPriceToClipboard) { case true: var itemPriceText = document.querySelector("#content > div.row > div:nth-child(1) > div > div > span.important-text") googleIcon('content_copy', 'scale-arrow copy-icon', itemPriceText, 'font-size: 1.25rem; translate: 0px -1rem;') document.querySelector("#scale-arrow\\ copy-icon").addEventListener('click', () => { console.log(`copied the price to the clipboard, price = ${itemPrice}`) GM_setClipboard(itemPrice) }) break; case false: break; default: console.log('problem with copy to clipboard') } ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //Header beautify // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //hide/show item status //switch (hideShowItemStatus) { pageSidebar.style.display = 'flex' pageSidebar.style.flexDirection = 'column' pageSidebar.style.alignItems = 'center' const itemCard = document.querySelector("#page-sidebar > div.card.mb-0") const total = itemCard.clientHeight itemCard.style.height = document.querySelector("#page-sidebar > div.card.mb-0 > div > div.card-item").clientHeight + 60 + 'px' itemCard.style.overflow = 'hidden' itemCard.style.transition = 'ease-out 200ms' itemCard.style.transitionProperty = 'height' var itemHideButton = document.createElement('div') googleIcon('expand_more', 'hide-arrow item' , itemHideButton, 'font-size: 25px; transition: height 200ms ease-out 0s; transition-property: transform, color; color: rgba(0,0,0,0.5);}') itemHideButton.style.transform = "translateY(-100%)" if (document.querySelector('.vertical-market')) { document.querySelector("#page-sidebar").insertBefore(itemHideButton, document.querySelector('.vertical-market')) } else { document.querySelector("#page-sidebar").appendChild(itemHideButton) } itemHideButton.addEventListener('click', () => { if (itemHideButton.dataset.value === "off") { itemHideButton.dataset.value = "on"; document.querySelector("#hide-arrow\\ item").innerHTML = 'expand_more' itemHideButton.title = "Show item status"; itemCard.style.height = document.querySelector("#page-sidebar > div.card.mb-0 > div > div.card-item").clientHeight + 60 + 'px' } else { itemHideButton.dataset.value = "off"; document.querySelector("#hide-arrow\\ item").innerHTML = 'expand_less' itemHideButton.title = "Hide item status"; itemCard.style.height = total +'px' } }); ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //View on swap.gg switch(viewOnSwapGG) { case true: if (appID == 730) { let itemssactions = document.querySelectorAll("#transacContent > tr > td.table-itemsactions.table-items__actions") for (let i=0;i < itemssactions.length;i++) { let inspectLink = itemssactions[i].lastElementChild.previousElementSibling.getAttribute('href'); let button = document.createElement('button') button.textContent = 'view on swap.gg' button.className = 'btn btn-secondary' button.onclick = function() { window.open(`https://market.swap.gg/screenshot?inspectLink=${inspectLink}`) }; itemssactions[i].appendChild(button) } } break; case false: break; default: console.log('problem with th e swap.gg button, value: ', viewOnSwapGG) } })();