[buff/c5game/igxe]饰品比例筛选脚本

支持[buff/c5game/igxe]饰品比例筛选,支持多种筛选规则

安装此脚本?
作者推荐脚本

您可能也喜欢饰品比例计算脚本

安装此脚本
  1. // ==UserScript==
  2. // @name [buff/c5game/igxe]饰品比例筛选脚本
  3. // @namespace http://tampermonkey.net/
  4. // @icon https://store.steampowered.com/favicon.ico
  5. // @version 1.3
  6. // @description 支持[buff/c5game/igxe]饰品比例筛选,支持多种筛选规则
  7. // @author wsz987
  8. // @match *://buff.163.com/market/*
  9. // @match *://buff.163.com/goods/*
  10. // @match *://www.c5game.com/*
  11. // @match *://www.igxe.cn/*
  12. // @match *://www.igxe.cn/product/*
  13. // @require https://cdn.staticfile.org/jquery/1.12.4/jquery.min.js
  14. // @grant GM_getValue
  15. // @grant GM_setValue
  16. // @grant GM_openInTab
  17. // @grant GM_addStyle
  18. // @grant GM_listValues
  19. // @grant GM_deleteValue
  20. // @grant GM_notification
  21. // @grant GM_xmlhttpRequest
  22. // @supportURL https://keylol.com/t577669-1-1
  23. // ==/UserScript==
  24.  
  25. (function() {
  26. initWebConfig()
  27. const INIT={
  28. RULES:[
  29. {
  30. name:'全都要',
  31. key:'by_hbr_lsr',
  32. desc:'出售及求购都符合条件',
  33. func({ lsr, hbr },{ MIX_NUMBER, MAX_NUMBER }){
  34. let sell_num = getVal(MIX_NUMBER),
  35. wbuy_num = getVal(MAX_NUMBER)
  36. if(lsr>1 || hbr>1) window.close()
  37. lsr>sell_num && window.close()
  38. hbr>wbuy_num && window.close()
  39. }
  40. },
  41. {
  42. name:'仅出售',
  43. key:'by_lsr',
  44. desc:'仅依据出售比例
即低于理想比例',
  45. func({ lsr },{ MIX_NUMBER }){
  46. lsr>1 && window.close()
  47. lsr>getVal(MIX_NUMBER) && window.close()
  48. }
  49. },
  50. {
  51. name:'仅求购',
  52. key:'by_hbr',
  53. desc:'仅依据求购比例
即低于最高比例',
  54. func({ hbr },{ MAX_NUMBER }){
  55. hbr>1 && window.close()
  56. hbr>getVal(MAX_NUMBER) && window.close()
  57. }
  58. }
  59. ],
  60. Header_DOM:{
  61. KET_COMMAND:{
  62. id:'KET_COMMAND',
  63. tips:'支持按键指令哦
A 上一页
D 下一页
W 居中
S 过滤
E 过滤后全部打开',
  64. name:'快捷指令提示',
  65. template(){
  66. return `<label title="${this.tips}">
  67. <button style="padding: 0.2rem 0.3rem;">${this.name}
  68. </button>
  69. </label>`
  70. }
  71. },
  72. AUTH:{
  73. id:'AUTH',
  74. tips:'作者: wsz987&#10;此脚本于Keylol论坛免费发布且仅供学习参考&#10;点击了解脚本&#10;问题反馈&#10;打赏&#10;',
  75. name:'auth',
  76. func(){
  77. GM_openInTab("https://keylol.com/t577669-1-1")
  78. GM_notification(
  79. {
  80. text :'如果有用请帮忙加点体力(点这里)\r\n不介意打赏( ̄y▽, ̄)╭\r\n提交BUG请附上console输出',
  81. title :'饰品自动筛选脚本',
  82. highlight: true,
  83. timeout: 5000
  84. },
  85. function(){ GM_openInTab("https://keylol.com/t577669-1-1", { active: true }); }
  86. )
  87. },
  88. template(){
  89. return `<label title="${this.tips}" style="float: right !important;margin-left:5px;">
  90. <span>作</span>
  91. <button id="${this.id}" style="padding: 0.2rem 0.3rem;" id="${this.id}">者
  92. </button>
  93. </label>`
  94. }
  95. },
  96. CONNECT_STATUS:{
  97. id:'CONNECT_STATUS',
  98. tips:'社区连接状态检索',
  99. name:'社区访问',
  100. func(){
  101. tryCatch(()=>{
  102. let connectBtn = $('.connect-status-btn')
  103. connectBtn && GM_xmlhttpRequest({
  104. url: "https://steamcommunity.com/market/",
  105. timeout: 15000,
  106. method: "get",
  107. onloadstart: function (event) {
  108. //readyState: 1
  109. //status: 0
  110. console.log("onloadstart", event);
  111. event.readyState==1 && connectBtn.html('<span style="color:#fff;">响应中…</span>')
  112. },
  113. onload: function (res) {
  114. //status: 200
  115. //statusText: "OK"
  116. //readyState: 4
  117. console.log("onload", res);
  118. res && res.status == 200 && res.readyState && connectBtn.text('访问正常')
  119. },
  120. onerror: function (err) {
  121. //readyState: 4
  122. //status: 0
  123. connectBtn.text('网络错误')
  124. console.log("检测steam连接性出错:连接错误", err);
  125. },
  126. ontimeout: function (res) {
  127. connectBtn.text('请求超时')
  128. console.log("检测steam连接性出错:请求超时",res);
  129. }
  130. })
  131. })
  132. },
  133. template(){
  134. return `<label title="${this.tips}" class='connect-status'>${this.name}&nbsp;
  135. <button id="${this.id}" style="padding: 0.2rem 0.3rem;" class="connect-status-btn"><span style="color:#fffffe;">连接检测</span>
  136. </button>
  137. </label>`
  138. }
  139. }
  140. },
  141. DOM:{
  142. RULES_TYPE:{
  143. name:'筛选规则',
  144. tips:'筛选规则选择',
  145. defaultVal:1,
  146. key:'RULES_TYPE',
  147. foreignKey:'RULES',
  148. template(){
  149. return `
  150. <label title="${this.tips}">${this.name}&nbsp;
  151. <select data-key='${this.key}'>
  152. ${this.foreignKey.map((rule,index)=>`<option value="${index}" ${this.defaultVal==index ? 'selected':''}>${rule.name}</option>`)}
  153. </select>
  154. </label>
  155. `
  156. }
  157. },
  158. ON_SALE_COUNT:{
  159. name:'在售数量',
  160. tips:'较大的基数便于快速出手&#10;避免误差',
  161. defaultVal:300,
  162. key:'ON_SALE_COUNT',
  163. template(){
  164. return `<label title="${this.tips}">${this.name}&nbsp;<input type='number' min='0' step='10' max='9999' placeholder='最低在售' value='${this.defaultVal}' data-key='${this.key}'/></label>`
  165. }
  166. },
  167. MIX_NUMBER:{
  168. name:'出售比例',
  169. tips:'实质上是避免&#10;出售-收购 比例差距过大&#10;避免JS抬价而造成损失',
  170. defaultVal:0.7,
  171. key:'MIX_NUMBER',
  172. template(){
  173. return `<label title="${this.tips}">${this.name}&nbsp;<input type='number' step='0.01' min='0.6' max='1' placeholder=' 0.6~1' value='${this.defaultVal}' data-key='${this.key}'/></label>`
  174. }
  175. },
  176. MAX_NUMBER:{
  177. name:'求购比例',
  178. tips:'最终筛选不超过比例',
  179. defaultVal:0.75,
  180. key:'MAX_NUMBER',
  181. template(){
  182. return `<label title="${this.tips}">${this.name}&nbsp;<input type='number' step='0.01' min='0.6' max='1' placeholder=' 0.61~1' value='${this.defaultVal}' data-key='${this.key}'/></label>`
  183. }
  184. }
  185. },
  186. Footer_DOM:{
  187. PREV_PAGE:{
  188. id:'PREV_PAGE',
  189. func(){
  190. tryCatch(()=>$(webConfig.preBtn)[0].click())
  191. },
  192. template(){
  193. return `<button id="${this.id}">&lt;</button>`
  194. }
  195. },
  196. RESET_BUTTON:{
  197. id:'RESET_BUTTON',
  198. func(){
  199. GM_listValues().map( name => GM_deleteValue(name) )
  200. $('.card-body').children().remove()
  201. $('.card-body').html(INIT.render('DOM'))
  202. alert('重置成功')
  203. },
  204. template(){
  205. return `<button id="${this.id}">重置</button>`
  206. }
  207. },
  208. SYNC_DATA:{
  209. id:'SYNC_DATA',
  210. tips:'同步最新数据&#10;避免页面众多导致混乱',
  211. func(){
  212. tryCatch(()=>{
  213. $('.card-body').children().remove()
  214. $('.card-body').html(INIT.render('DOM'))
  215. })
  216. },
  217. template(){
  218. return `<label title="${this.tips}" class="syncData-btn">
  219. <button id="${this.id}" style="padding: 0.2rem 0.3rem;">
  220. <svg t="1627656092949" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1182" width="16" height="16"><path d="M1017.576727 326.493091l-87.226182 151.272727c0.256 3.677091 0.558545 7.284364 0.558546 10.961455h-6.842182a46.545455 46.545455 0 0 1-28.392727 21.736727h-0.395637a46.289455 46.289455 0 0 1-8.424727 1.419636h-2.327273a29.137455 29.137455 0 0 1-11.264-1.210181c-1.466182-0.325818-2.955636-0.512-4.398545-1.000728a46.685091 46.685091 0 0 1-8.634182-3.886545l-161.908363-93.626182a46.801455 46.801455 0 0 1 46.731636-81.082182l70.842182 40.96A325.352727 325.352727 0 0 0 217.949091 349.090909H209.454545a46.545455 46.545455 0 1 1-78.08-34.048 417.861818 417.861818 0 0 1 771.048728 23.994182l34.210909-59.345455a46.754909 46.754909 0 1 1 80.942545 46.801455z m-124.951272 382.464a417.838545 417.838545 0 0 1-771.048728-23.994182l-34.210909 59.345455A46.778182 46.778182 0 1 1 6.4 697.483636l87.249455-151.272727C93.393455 542.557091 93.090909 538.949818 93.090909 535.272727h6.842182a46.545455 46.545455 0 0 1 28.369454-21.736727h0.395637A47.104 47.104 0 0 1 137.146182 512h2.327273a29.137455 29.137455 0 0 1 11.264 1.210182c1.466182 0.325818 2.955636 0.512 4.398545 1.000727a46.685091 46.685091 0 0 1 8.634182 3.886546l161.908363 93.626181a46.801455 46.801455 0 0 1-46.731636 81.082182l-70.842182-40.96A325.352727 325.352727 0 0 0 806.050909 674.909091H814.545455a46.545455 46.545455 0 1 1 78.08 34.048z" p-id="1183" fill="#fffffe"></path></svg>
  221. </button>
  222. </label>`
  223. }
  224. },
  225. NEXT_PAGE:{
  226. id:'NEXT_PAGE',
  227. func(){
  228. tryCatch(()=>$(webConfig.nextBtn)[0].click())
  229. },
  230. template(){
  231. return `<button id="${this.id}">&gt;</button>`
  232. }
  233. },
  234. },
  235. render(TYPE){
  236. let Template=''
  237. Object.values(this[TYPE]).map(item=>{
  238. if(TYPE==='DOM')
  239. Template+=item.template.call({...item,defaultVal: getVal(item),foreignKey :this[item.foreignKey] })
  240. else {
  241. Template+=item.template()
  242. item.func && $(document).on('click', `#${item.id}`, ()=> {
  243. item.func()
  244. });
  245. }
  246. })
  247. return Template
  248. }
  249. }
  250. // 数据绑定
  251. $(document).on('input', '#tool-card > .card-body input,#tool-card > .card-body select', ({target:{dataset:{ key },value}})=> {
  252. if(!value.toString()) return alert(`数据错误: "${key}" -- ${value}`)
  253. setVal(key,value)
  254. let actionDOM=document.querySelector(`.card-body span#${key}`)
  255. actionDOM && tryCatch(()=>actionDOM.innerText=getVal({key}))
  256. });
  257. // DOM 挂载
  258. $("body").append(`
  259. <div id='tool-card'>
  260. <div class="card-header">
  261. ${INIT.render('Header_DOM')}
  262. </div>
  263. <div class="card-body">
  264. ${INIT.render('DOM')}
  265. </div>
  266. <div class="card-footer">
  267. ${INIT.render('Footer_DOM')}
  268. </div>
  269. </div>
  270. `)
  271. onkeydownListener(INIT)
  272. ondetailMountdedListener( data => execRules(INIT,data))
  273. dargCard()
  274. })();
  275.  
  276. function dargCard(){
  277. tryCatch(()=>{
  278. $("#tool-card").mousedown(function() {
  279. $("#tool-card").on({ // 要移动拖拽的目标DOM
  280. mousedown: function(e){
  281. var el = $(this);
  282. var os = el.offset();
  283. var dx = e.pageX - os.left
  284. var dy = e.pageY - os.top;
  285. $(document).on('mousemove.drag', function(e){
  286. el.offset({
  287. top: e.pageY-dy,
  288. left: e.pageX-dx
  289. });
  290. });
  291. },
  292. mouseup: function(e){
  293. $(document).off('mousemove.drag');
  294. }})
  295. })
  296. })
  297. }
  298.  
  299. function ondetailMountdedListener(callBack){
  300. let detail = {}
  301. $(document).on("DOMNodeInserted",".detail-summ,.afkout .price", (e)=>{
  302. let { innerText: value, className} = e.target
  303. //value.includes('Steam302') && alert(value)
  304. detail[className]= value - ''
  305. detail && detail.lsr && detail.hbr && callBack && callBack(detail)
  306. })
  307. }
  308.  
  309. function execRules({ DOM, RULES },data){
  310. RULES[getVal(DOM.RULES_TYPE)].func(data,DOM)
  311. }
  312.  
  313. function onkeydownListener({Footer_DOM:Event,DOM}){
  314. tryCatch(()=>{
  315. document.onkeydown=function(event){
  316. var e = event || window.event || arguments.callee.caller.arguments[0];
  317. // S
  318. if(e && e.keyCode==83){
  319. middle()
  320. filter(DOM,Event)
  321. }
  322. // D
  323. if(e && e.keyCode==68){
  324. Event.NEXT_PAGE.func()
  325. }
  326. // A
  327. if(e && e.keyCode==65){
  328. Event.PREV_PAGE.func()
  329. }
  330. // W
  331. if(e && e.keyCode==87){
  332. middle();
  333. }
  334. // E
  335. if(e && e.keyCode==69){
  336. filter(DOM,Event)
  337. openALLInTab()
  338. }
  339. }
  340. })
  341. }
  342.  
  343. function middle(){
  344. tryCatch(()=>{
  345. const { goodsContainer } =webConfig
  346. const Rules =['buff.163.com/market/','igxe.cn/market/','c5game.com/']
  347. if(Rules.some(rule=>location.href.includes(rule))){
  348. //if(!location.href.includes('buff.163.com/market/')||!location.href.includes('product')||!location.href.includes('www.c5game.com/dota/')){
  349. if($(goodsContainer).width()>$(window).height()){
  350. $(this).scrollTop($(goodsContainer).offset().top)
  351. }else{
  352. $(this).scrollTop($(goodsContainer).offset().top+($(window).height()-$(goodsContainer).width())/2);
  353. }
  354. }
  355. })
  356. }
  357.  
  358. function initWebConfig(){
  359. let config={}
  360. switch(location.host){
  361. case "buff.163.com":
  362. config={
  363. goodsContainer:'.market-card',
  364. onSaleCount:'.f_Bold.c_Gray',
  365. goodsItemHref:"ul[class^='card_']>li:not(.script_no)>a",
  366. goodsCount:20,
  367. preBtn:'.page-link.prev',
  368. nextBtn:'.page-link.next',
  369. currentGoodsNode:(el)=>el.parentNode.parentNode
  370. }
  371. break;
  372. case "www.igxe.cn":
  373. config={
  374. goodsContainer:'.list',
  375. onSaleCount:'.info .stock',
  376. goodsItemHref:'.list a.item:not(.script_no)',
  377. goodsCount:20,
  378. preBtn:'.btn-prev',
  379. nextBtn:'.btn-next',
  380. currentGoodsNode:(el)=>el.parentNode.parentNode
  381. }
  382. break;
  383. case "www.c5game.com":
  384. config={
  385. goodsContainer:'#market_index .list',
  386. onSaleCount:'.count',
  387. goodsItemHref:'.list .el-col:not(.script_no) a.mb20',
  388. goodsCount:42,
  389. preBtn:'.btn-prev',
  390. nextBtn:'.btn-next',
  391. currentGoodsNode:(el)=>el.parentNode.parentNode.parentNode.parentNode.parentNode.parentNode.parentNode.parentNode
  392. }
  393. c5game_goodsDetailPageFix()
  394. c5game_listenListDataLoad()
  395. break;
  396. }
  397. if(JSON.stringify(config) == "{}") console.error('script config init error')
  398. else window.webConfig = config
  399. }
  400.  
  401. function openALLInTab(){
  402. for(let i of $(webConfig.goodsItemHref)){
  403. i?.href && GM_openInTab(i?.href)
  404. }
  405. }
  406.  
  407. function filter({ON_SALE_COUNT},Event){
  408. let { onSaleCount, goodsCount,currentGoodsNode }=webConfig
  409. let n=0
  410. Array.from($(onSaleCount)).filter(x=>{
  411. if(eval(x.innerHTML.replace(/[^0-9]/g, ''))>=parseInt(getVal(ON_SALE_COUNT)))
  412. return
  413. ++n;
  414. currentGoodsNode(x).className += ' script_no'
  415. })
  416. if(n==goodsCount){
  417. Event.NEXT_PAGE.func()
  418. }
  419. }
  420.  
  421. function c5game_listenListDataLoad(){
  422. tryCatch(()=>{
  423. const mutation = new MutationObserver(function(mutationRecoards, observer) {
  424. if(mutationRecoards[0]?.oldValue=="list el-loading-parent--relative"){
  425. console.log('c5game list data loaded');
  426. $('.script_no').removeClass('script_no')
  427. }
  428. })
  429. mutation.observe(document.querySelector("#market_index > ul.list"), {
  430. attributes: true,
  431. characterDataOldValue :true,
  432. attributeFilter: ['class'],
  433. attributeOldValue: true
  434. });
  435. })
  436. }
  437.  
  438. function c5game_goodsDetailPageFix(){
  439. tryCatch(()=>{
  440. let href = document.querySelector("div.bottom-info > a")?.attributes?.href?.value
  441. $("body").append(`<div class ='steamUrl scriptFix' style="display:none;"><a href='${href}'></a></div>`)
  442. $("body").append("<div class='hero-fix scriptFix'><div class ='hero'></div></div>")
  443. $("body").append(`<tbody class='scriptFix' style="display:none;"><td class='ft-orange'><span></span></td></tbody>`)
  444. $(document).on("DOMNodeInserted",".onsale-table", (e)=>{
  445. let firstPrice = $('.onsale-table-item .text-price:first').text()
  446. $('tbody.scriptFix .ft-orange:first span').text(firstPrice)
  447. })
  448. })
  449. }
  450.  
  451. function setVal(key,val){
  452. console.log('setVal',key,val)
  453. GM_setValue(key,val)
  454. }
  455. function getVal({key,defaultVal}){
  456. return GM_getValue(key,defaultVal) - ''
  457. }
  458.  
  459. function tryCatch(callBack){
  460. try{
  461. callBack && callBack()
  462. }catch(e){
  463. console.log(e)
  464. }
  465. }
  466. GM_addStyle(`
  467. #tool-card{
  468. z-index:998;
  469. position:fixed;
  470. left:10px;
  471. top:400px;
  472. background-color: #0f0e17;
  473. color:#a7a9be;
  474. display: flex;
  475. flex-direction: column;
  476. padding: 0.75rem 1rem 0.4rem;
  477. font-size: 1rem;
  478. font-weight: 600;
  479. border-radius: 7px;
  480. border: 2px solid #ff8906;
  481. min-width:160px;
  482. }
  483. .card-header label{
  484. margin-bottom: 0.2rem;
  485. }
  486. .card-body{
  487. display: flex;
  488. flex-direction: column;
  489. }
  490. .card-footer{
  491. display: flex;
  492. justify-content: space-around;
  493. margin-top: 0.3rem;
  494. }
  495. #tool-card button{
  496. background-color: #ff8906;
  497. color:#fffffe;
  498. padding: 0.3rem 0.5rem;
  499. border:none;
  500. border-radius: 3px;
  501. font-size: 1rem;
  502. font-weight: 600;
  503. cursor: pointer;
  504. }
  505. #tool-card input,
  506. #tool-card button{
  507. margin-bottom: 0.2rem;
  508. }
  509. #tool-card button:active{
  510. position: relative;
  511. top: 1px;
  512. }
  513. .card-body input{
  514. color: #fffffe;
  515. background-color: transparent;
  516. border: none;
  517. font-weight: 600;
  518. font-size: 1rem;
  519. border-bottom: 0.1rem solid #ff8906;
  520. text-align: center;
  521. min-width:59px;
  522. }
  523. .card-body label{
  524. display: flex;
  525. align-items: center;
  526. justify-content: space-around;
  527. }
  528. .card-body select{
  529. color: #fffffe;
  530. background-color: transparent;
  531. border: none;
  532. font-weight: 600;
  533. font-size: 1rem;
  534. border-bottom: 0.1rem solid #ff8906;
  535. text-align-last:center;
  536. }
  537. .card-body option{
  538. background-color: #0f0e17;
  539. color: #a7a9be;
  540. text-align:center;
  541. }
  542. .connect-status{
  543. display: flex;
  544. align-items: center;
  545. justify-content: space-around;
  546. margin-top: 0.2rem;
  547. }
  548. .connect-status-btn{
  549. margin-bottom: 0 !important;
  550. color:#0f0e17 !important;
  551. }
  552. .syncData-btn{
  553. margin-bottom: 0.2rem !important;
  554. }
  555. .syncData-btn button{
  556. height: 100%;
  557. display: flex;
  558. align-items: center;
  559. }
  560. #AUTH{
  561. color: #0f0e17 !important;
  562. }
  563. .script_no{
  564. display:none !important;
  565. }
  566. .hero-fix{
  567. position: absolute;
  568. top: 25%;
  569. right: 30%;
  570. color:white;
  571. font-weight: bold;
  572. z-index:999;
  573. }
  574. `)

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址