From 02c36c06ca876799848714b6b130cf2dea826580 Mon Sep 17 00:00:00 2001 From: Abhorrent_Anger Date: Thu, 7 Mar 2024 16:13:33 +0200 Subject: [PATCH] Works --- README.md | 2 +- favicon.ico | Bin 0 -> 15406 bytes index.html | 20 +++++++++ script.js | 117 +++++++++++++++++++++++++++++++++++++++++++++++++++ style.css | 119 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 257 insertions(+), 1 deletion(-) create mode 100644 favicon.ico create mode 100644 index.html create mode 100644 script.js create mode 100644 style.css diff --git a/README.md b/README.md index 62b3d61..57028c6 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,3 @@ # BackpackDecalSpotter -Finds decaled items on Backpack.tf \ No newline at end of file +Finds decaled items on Backpack.tf. Relies on legacy soon-to-be-deprecated endpoints. Should be hosted to avoid "Access to Image from origin 'null' has been blocked by CORS policy" errors when fetching accounts with decaled item listings. \ No newline at end of file diff --git a/favicon.ico b/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..8acd1876faef922b4998d53e8f01d31659b1f611 GIT binary patch literal 15406 zcmeHN30Ra>_aFQI^(mNUWh$~WFo5j4%BpO$z_6%TsO4^km6iKODTKIVqNu5$1|lGc zEGqlH%*JdC42ysZg{AqGOA6;ZcgE@SGa-<&zUR;TJokCudEdMI?z!ijd*=Kug))rt z56Ww=QSh!yS@wSviUWm0(bZM{HXcKv9K&~3R*%0MQ79E-DHLO@gH5o7@;%=EHrJ?8 zQ|yNiH`aX~KohCkHFc>wZ;c+~aaT=^>Nl`H!e7!g+L>?dSOM0KwVK4EPzSYMRgjsacWO~C(k)Kyvgg5-&QgTYn~Z!TcjVf&O{mN0(ud!s=Bbp}qU^ z@!AFvjkc4kz}&X7+t@OTrD|7DAfxTuC(PQoF{x+X+%#+>0`KW5!0_hbvslpwoe|$* zW}OaJjx}Ivnftk_Ex8vKw!XGugSay!SPXQpN^BIekbmFH;}WnL67XXPAt>kwq-UnVdkas&;sr8cZEXwf*{zjtqoU+m8AxA4tPU(BD|&~-AgiP!esji&IOac`==_2&)% z!&+NghqrxuEkkleZrz_Y&#F^eT8fta_rHjr(Z%A9h4`nT>;Ja|-qe^$8~Lhj+6Z;p zY6@kX`U{rEFdc))g10ml!w5A~7(T+VapXwqq!)!jm$u_WUFsf~WR(Tl`k#aPNE;Y2 z!l>(c_qu`L)}uvO=uo%cH8hC_2bX$qbd`gtRXV&iVF8R8~%#r|w& zTZQv4xI;BPX4+TV-o7=pHQ8on$+IIP1w9;|=>6X6=^01)Y3oP!m{_Es+=XC2r4Fnd zYQfaHxQAw*G_$vMy}fU4Z?-$1Da~B*VQ$a#X}iGHB?h9SDt_c}INDFQ(a~8yLC0Y0 zxB9e$U^|r$4$eZ1YdBzHT>>P5nGqOD_WBigH|YF|IuqCfSr?jFFR1q4d7jKZ%2^Z&Gr3X4nU* z-2nj+Fefwu*vx#4TS)w)EG%CkELki74qyDPs;v%n(g~2j5cF>+N1%Q*L$WNLK2ig(th`&OHFD*X)LnnP(O8l4@MVoq-rg!B}d~ZqfIN z8HpONzZL8=QG3+`qe*CM&OFq0E?C%AgNaq)eM8ek$KJ*y?`17Ai_}z6N?2G{_nbNV zVfE@SVA-;GjCn}BCdK%x7<@ddfZ@eO+1CM!A$>f)4E&j5NK50TPnfvkimt&nu$^2D z4j4~bVJwUK1~jvjWqplZP$)mTZmpm@DoO|!vWju+SYWdr%i6adS^6r6hVEgN36QgYLrtCx;5_97__5bP`}J0cIn>l+H$~EEYMn3DF+5=MdvjNPXEMvp*evNawnC?5 z7^haj)X8z+>2VQb=Qv>aTvV(#`R-4bC}ht-Y_86!U}L)&%Bo7>=Iw7`YxISlYOa9% z59n81s~Vr&eS9jY{tQVok^QXTTJZE-2%ghF!}uefIGwnGnDf36wT=0mnuC^AVx^MY!%#g)Xw0 zQtbe{iD~ITr=Le%lt7@r1S%`9?CS5BPuJVOzf9w!u*PI?HqJf3Po^kLoTIBtJVfu>13%rr1DEo1VY=@Ew3%91x3)o^nAp0qR45!&oL*kj zXtiRw{EouMpzhJVi*U`k%Kt$0YWQqzG<4qVfV;o^3}-SgbVuwc&&|Djg_)e3{G0z_ zPtUKvzjJb0{1?6}e?)8|fc2lUY84l_5&_(MbPvjFD`EM%y$k!>=RoTvC(A#1C*(h4 z&j^&l`CM5~=Z`m`;adB{t^1D$47AUI)<1r%_0ZDA@<-dYHfCPTm;1GK-MD@2hwnhz z+Pr3U-f`+m=XLRg(hGyq z@827zx9>GVo?Bn}g5KH-wZW%i>o8lXk2x5qq!7{=_`Zj^98mYrfsm{Lk+D@dtQ6P z7xR0@B)|7iP0jF_nwri8#4+IiK`#(HMVGqGNzZ8S4Sm{S(4+2v*WV1nIhf%bj7W|! zAJ@Y2MdBIASX#8z8oI`NE447kW@LIA|MwSRUhgc7(^v{>>Xu{<-6PbDQb&z4eSIMP zzKFV1>WY6-jdy;jZ4mj3E;R=Ev&)z}Xa*-YIp#2mLC;PknG|V;e!O2yMxkfqIJ2!$Q=KBmModF%a&-oK4F47!G-+y*p zEv+yOedFCN+WKFDp~(r%SMf1VC;>-jDL!*CPs#&xI}YY)3%jVsN0H0@Ew}hbV63aF zQ!kU1y*iM-UZ<`YrDwb+LrZ@f=o=ltylNHV7Gi!`s>pd+Io4s$t%UHv_YF->el(E2 z`&&07BjeS!&Nfy>tvtTGTC$DIqd#qJZI`^PPmBB*Ipd#osk<;ongjNjCnR}!`zZp% z&j(YIr?oEn#mM69P6}no%l+whAaz6{o}F0Mp0RhI==*u0RdC>d;K%&pa_|21p=Y$o zQrGaycA_^lv(u>aJk)s!&OwCOd0=K+hH@{#oO@O}m3j<8|QE!|@iu}5j1KO%J z>Wx+Y4+bVDNj_%KdoJ=CHbPNzT6Ai_U$V1AYoW$wxB? zN5F#(>xB=C%j>qO)_>%9`dDqfwMm+~>wEMJ_oA;XQ|JxxIW~Ca#LTu*iQg)>Lf_=L zp$gAH?s+A778mnN&#qaQ{GA^&t|vI~E7-Ip7Pf@%g1K`O5L>k(hy0|xe|;vo_Fsz> zbGrgKb-Mm%%%S??p7YAs@w4JJG(UQztsj9ppNE_Z2lrRPDb--CL%0>>H!O3z3`~xi z4Fq#VMa78n8opIYsrc~GH@7u=7L~|j_s0l3mM<&o3Hu-yzS#N=$~yvv&D|sVi~s74tIYV5@+#Q zVQ%PYZ!t+l)hr!up6-;xx0KVQ_#7^eN$6UM+i}>-GDjDYI>yfV# zBOg@=b`FP-`$|UtQi!^f1s1m13SVi4TqN<8#^&icnx;nw6c?jjzEW1vesIwO;lsov z5wunh5sxJJG+R+{qs0Dnsl%jLWz{GtUGgi}Y(6`dfa(JNIWD2rqOZ zp(TFl;_B{CSBfCePprU>=fo6Pi7%Y)fpYe&MO{byC{r>A^4`fI8ac=WoL4d0D&a+y z{3G$H3@-u7y%OBr(!t3QZU4Q^a5|X>?=86olil0FZfYa0K@Aw0rC&ERJ{a5|ti9El z5mXcr%qB8KUIMuh6=%mnIZkuU01vlwh@Ye22g$iPmQST(4on~95`B>0M7a~6$wu5v zZxQ%-@z5?f$fupdImUqdv`^uD_Ic!%{slZyJIq;F+Gg#*y^i+UVrZ5WWNRBYsJJYM zUZ}}t3G)#DqX3kZO~50d{~H|;Z=t` zWeM2XM1zg>GT0rnA8!4t3vT~(6Hc5t4{-_ksmG2bk9Bu<@AaHtZ?f*~y`Oi5F`H3$ zo?ub=j^F?hgoJ#Jx*Gv*ZacuoI~?b;2mMU(Z}1cBY_t`IH)40ch;okw6Vp)mXytn7 zxX}W4?%sm*oXZe0Ckr-ha^kY~YJ(6`Wutp9>3?W+?0? zh$V#7)W)uyf`UHJNj}d!==7>lOkdt1#C4y{A;2#O{Uz#)!uO!6yS{J@(ZZry-{I>IEzM(ygZfI%>ROLo^a{1WS8&?Yn_KusKH-&NuImby8Y7mZ;s<5dedYszbC btp19#JA=VJ)OJV$LlPL0z>oy~Hzn|Ih2JNV literal 0 HcmV?d00001 diff --git a/index.html b/index.html new file mode 100644 index 0000000..dff5e64 --- /dev/null +++ b/index.html @@ -0,0 +1,20 @@ + + + + Backpack Decal Spotter + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/script.js b/script.js new file mode 100644 index 0000000..f19ac14 --- /dev/null +++ b/script.js @@ -0,0 +1,117 @@ +var checkable_accounts = { '76561198311319887': 'Weapon Crusher' }; +decaled_objects = { 'Conscientious Objector': '3.66', 'Clan Pride': '2.11', 'Flair!': '4.22', 'Photo Badge': '2.44' } +backpack_page_limit = 3; + +function fetchAccounts() { + var deferred = new $.Deferred(); + for (const [item, price] of Object.entries(decaled_objects)) { + handleItem(item, price); + } + deferred.resolve(checkable_accounts); + return deferred.promise() +} + +function handleItem(item, price) { + for (let i = 1; i <= backpack_page_limit; i++) { + $.ajax({ + dataType: 'html', + url: 'https://backpack.tf/classifieds', + data: 'page=' + i + '&item=' + encodeURIComponent(item) + '&quality=6&tradable=1&craftable=1&australium=-1&killstreak_tier=0&numeric=price&comparison=lt&value=' + price + '&low=' + price, + async: false, + tryCount: 0, + retryLimit: 3, + success: function (msg) { + if ($('.col-md-6:first .alert', msg).length > 0) { + return false; + } + $('.col-md-6:first .user-link', msg).each(function () { + checkable_accounts[$(this).attr('data-id')] = $(this).attr('data-name'); + }); + }, + error: function (response, status, error) { + if (response.status == 429) { + this.tryCount++; + if (this.tryCount <= this.retryLimit) { + setTimeout(() => { + $.ajax(this); + }, 3000); + return; + } + } + } + }); + } +} + +function handleAccounts() { + for (const [steamid64, name] of Object.entries(checkable_accounts)) { + handleAccount(steamid64, name); + } +} + +function handleAccount(steamid64, name) { + var url = "https://backpack.tf/_inventory/" + steamid64; + $.ajax({ + dataType: 'json', + url: url, + async: false, + tryCount: 0, + retryLimit: 3, + success: function (msg) { handleHTML(steamid64, name, msg['html']); }, + error: function (response, status, error) { + if (response.status == 429) { + this.tryCount++; + if (this.tryCount <= this.retryLimit) { + setTimeout(() => { + $.ajax(this); + }, 3000); + return; + } + } + } + }); +} + +function handleHTML(steamid64, name, html_string) { + html = $.parseHTML(html_string); + var decaled_items = $('div.decal', html); + if (decaled_items.length == 0) { + var empty_accounts = $('#empty-accounts'); + empty_accounts.append('' + name + '; '); + empty_accounts.fadeIn(); + return false; + } + var inventory = $('
'); + inventory.append('

' + name + '

'); + decaled_items.each(function () { + var url = "https://next.backpack.tf/item/" + $(this).parent().attr('data-id'); + var a = $(''); + a.append($(this).parent()); + inventory.append(a); + }); + var inventories = $('.inventory'); + if (inventories.length > 0) { + var child_count = inventory.children().length; + inventory.attr('data-items', child_count); + var last_div = null; + inventories.each(function () { + if (child_count > $(this).children().length) { + return false; + } + last_div = $(this); + }); + if (last_div) { + last_div.after(inventory); + } else { + $('body').prepend(inventory); + } + } else { + $('#empty-accounts').before(inventory); + } +} + +$(document).ready(function () { + $.when(fetchAccounts()).done(function () { + handleAccounts(); + }); +}); \ No newline at end of file diff --git a/style.css b/style.css new file mode 100644 index 0000000..f3c8bee --- /dev/null +++ b/style.css @@ -0,0 +1,119 @@ +body { + background-color: #111; + color: #eee; + font-family: Verdana, Geneva, sans-serif; + font-size: 0.85em; + margin: 0px; + text-align: justify; + text-justify: inter-word; + word-wrap: break-word; + word-break: break-all; + white-space: normal; + text-align: center; +} + +div { + display: inline-block; +} + +h3 { + text-align: center; + padding: 0.5em; +} + +h4 { + color: #555; + text-align: center; + padding: 5em; +} + +li { + display: inline-block; + width: 140px; + height: 140px; + position: relative; + border-radius: 3px; + margin: 10px; + border: 3px solid; + margin-bottom: 38px; +} + +.decal { + width: 128px; + height: 128px; + margin: auto; + z-index: 2; + position: absolute; + top: 6px; + left: 6px; +} + +.item-icon { + width: 24px; + height: 24px; + bottom: -38px; + left: -3px; + background-size: 24px; + z-index: 1; + position: absolute; + border-radius: 3px; + border: 3px solid; +} + +.q-440-6, +.q-440-6 .item-icon, +.q-440-6 .bottom-right { + background-color: rgb(119, 101, 3); + border-color: rgb(181, 154, 5); +} + +.q-440-11, +.q-440-11 .item-icon , +.q-440-11 .bottom-right { + background-color: rgb(110, 56, 26); + border-color: rgb(144, 73, 34); +} + +.nocraft { + border-style: dashed; +} + +.top-left { + display: none; +} + +.bottom-right { + position: absolute; + width: 105px; + height: 24px; + bottom: -38px; + left: 32px; + border-radius: 3px; + border: 3px solid; + margin: auto; +} + +.bottom-right span { + text-align: center; + display: block; + margin-top: 3px; +} + +a, +a:link, +a:visited, +a:hover, +a:active { + text-decoration: none; + color: #eee; +} + +h4 a, +h4 a:link, +h4 a:visited, +h4 a:hover, +h4 a:active { + text-decoration: none; + color: #555; + font-style: italic; +} \ No newline at end of file