您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Digital Emergency Exit 2 Entry Grid Layout Formatter and Client-Side Sorter
// ==UserScript== // @name DEE2 Formatter // @namespace http://tampermonkey.net/ // @version 1.1 // @description Digital Emergency Exit 2 Entry Grid Layout Formatter and Client-Side Sorter // @author Noisysundae // @match *manbow.nothing.sh/event/event.cgi* // @icon https://www.google.com/s2/favicons?sz=64&domain=nothing.sh // @grant none // @license MIT // ==/UserScript== /* jshint esversion: 11 */ (() => { const sortEntries = (by) => entries .sort((a, b) => { switch (by) { case 'index': return a[by] - b[by]; case 'title': case 'artists': case 'genre': case 'production': return a[by].localeCompare(b[by]); case 'updated': case 'impressions': case 'total': case 'median': case 'avg': case 'weighted': case 'fs': case 'dq': return b[by] - a[by]; case 'random': return Math.random() > 0.5 ? 1 : -1; } }) .reduce( (last, current, i, arr) => { const lastInfo = { order: last.value === (current[by] ?? 0) ? last.order : i, value: current[by], }; const isRankedSort = [ 'impressions', 'total', 'median', 'avg', 'weighted', ].includes(by); const topPct = ((isRankedSort ? lastInfo.order : current.index) / arr.length) * 100; list.appendChild(current.element.base); if (current.element.ranking) current.element.ranking.innerHTML = `${ isRankedSort ? `<i class="icon-trophy"></i>${ lastInfo.order + 1 }` : `#${current.index}` }${ isRankedSort ? ' <small>(top' + (topPct ? ` <b>${topPct.toFixed(2)}</b> %` : '') + ')</small>' : '' }`; return lastInfo; }, { order: -1, value: null } ); const list = document.getElementById('modern_list'); const teams = document.querySelectorAll('.team_information'); const entries = Array.from( document.querySelectorAll('.team_information .row > div[style]') ) .filter( (e) => !e.querySelector('.pricing-title h4.textOverflow span#notready') ) .map((base) => { const title = base.querySelector( '.pricing-title .center > *:nth-child(2) a' ); const artists = base.querySelector( '.pricing-title .center > *:nth-child(3)' ); const genre = base.querySelector( '.pricing-title .center > *:nth-child(1)' ); const ranking = base.querySelector( '.pricing-features:nth-child(2) .tleft.textOverflow span:nth-child(1)' ); const stats = base.querySelector( '.pricing-features > .bofu_meters' ); const info = base.querySelector('.pricing-action small'); const total = stats.querySelector('p:nth-child(1) > span'); const avg = stats.querySelector('p:nth-child(3) > span'); const median = stats.querySelector('p:nth-child(2) > span'); const entry = { element: { base, title, artists, genre, ranking, stats, info, total, median, avg, }, index: parseInt(info?.innerHTML.match(/No\.([\d]+?)\ /)[1]), title: title.innerHTML, artists: artists.innerHTML.replace('(mov:', ' (mov: '), genre: genre.innerHTML, production: info?.innerHTML.match(/ \/ ([\w]+?)\ /)[1], updated: new Date( `${info?.innerHTML.match(/update : (.+?)$/)[1]} GMT+9` ), impressions: parseInt(ranking?.innerHTML), total: parseFloat( (total?.innerHTML.match(/Total : ([\d\.]+?) /) ?? [ '', '0', ])[1] ), median: parseFloat( (median?.innerHTML.match(/Median : ([\d\.]+?) /) ?? [ '', '0', ])[1] ), avg: 0, weighted: 0, fs: base.firstElementChild.id === 'ace_mus', dq: false, }; if (entry.fs) entry.total *= 2 / 3; entry.avg = entry.total / entry.impressions; if (entry.total) entry.weighted = entry.avg * 0.5 + entry.median * 0.5; else entry.dq = true; return entry; }); const styles = document.createElement('style'); const sortLabel = document.createElement('label'); const sortOptions = document.createElement('select'); /* * Prefixed by https://autoprefixer.github.io * PostCSS: v8.4.14, * Autoprefixer: v10.4.7 * Browsers: last 4 version */ styles.innerHTML = ` div#modern_list { display: -webkit-box; display: -ms-flexbox; display: flex; -ms-flex-wrap: wrap; flex-wrap: wrap; -webkit-box-pack: center; -ms-flex-pack: center; justify-content: center; } div#modern_list * { font-family: 'Yanone Kaffeesatz'; letter-spacing: 0.03em; } div#modern_list .label { letter-spacing: 0.12em; font-size: 0.9em; } div#modern_list > div { width: 8.8cm; padding: 0; } div#modern_list .header_grad .pricing-title > .center { display: -webkit-box; display: -ms-flexbox; display: flex; -webkit-box-orient: vertical; -webkit-box-direction: normal; -ms-flex-direction: column; flex-direction: column; -webkit-box-align: end; -ms-flex-align: end; align-items: end; font-size: 1.2em; } div#modern_list .header_grad .pricing-title > .center > * { width: 90%; text-align: right; font-size: 1em; letter-spacing: 0.04em; } div#modern_list .header_grad .header_alpha .pricing-title > .center > *:nth-child(1) { padding-right: 0.6rem; } div#modern_list .header_grad .header_alpha .pricing-title > .center > *:nth-child(2) { padding-right: 1.4rem; } div#modern_list .header_grad .header_alpha .pricing-title > .center > *:nth-child(3) { padding-right: 2.2rem; } h4.textOverflow > strong { font-size: 1.4em; } .bmsinfo.textOverflow { text-align: right; } .header_alpha .bmsinfo.textOverflow { padding-right: 3rem; } .header_grad { margin: 0.4em; border-radius: 0.8em; } div#modern_list .pricing-box.best-price, .header_grad { overflow: hidden; } div#modern_list .pricing-box.best-price { margin: 0.6em; padding: 0.4em; border-radius: 1.6em; } .dark .pricing-box.best-price:not(#ace_mus) { background: #222; color: #bbb; } div#modern_list .pricing-box.best-price > .pricing-features .tleft.textOverflow { margin: 0; } div#modern_list .pricing-box.best-price > .pricing-features .tleft.textOverflow .icon-trophy { margin-right: 0.1em; } div#modern_list .pricing-box.best-price > .pricing-features span > small { font-size: 10pt; } div#modern_list .pricing-features > .bofu_meters, .pricing-action > span { padding: 0 2rem; } div#modern_list .pricing-features > .bofu_meters { display: -webkit-box; display: -ms-flexbox; display: flex; height: 7.5em; -ms-flex-wrap: wrap; flex-wrap: wrap; font-size: 1.2em; margin: 0; } div#modern_list .pricing-features > .bofu_meters > p { width: 100%; display: -webkit-box; display: -ms-flexbox; display: flex; -webkit-box-pack: start; -ms-flex-pack: start; justify-content: flex-start; line-height: 1; } div#modern_list .pricing-features > .bofu_meters > p > *:first-child { width: 5em; font-size: inherit; } div#modern_list .pricing-features > .bofu_meters > p > *:nth-child(3) { max-width: 7.2em; -webkit-box-flex: 1; -ms-flex: 1; flex: 1; margin-left: auto; font-size: inherit; } .textOverflow { margin: 0.2em 0.6em; } #ace_mus { background: -o-linear-gradient( 30deg, rgba(131, 58, 180, 0.2) 0%, rgba(253, 29, 29, 0.2) 40%, rgba(252, 176, 69, 0.2) 100% ); background: linear-gradient( 60deg, rgba(131, 58, 180, 0.2) 0%, rgba(253, 29, 29, 0.2) 40%, rgba(252, 176, 69, 0.2) 100% ); } .dark #ace_mus { color: #ddd; } .header_alpha { background: -o-linear-gradient( 285deg, transparent 2.4em, #fffd 2.45em, #fff8 14em, transparent 14.05em ); background: -o-linear-gradient( 165deg, transparent 2.4em, #fffd 2.45em, #fff8 14em, transparent 14.05em ); background: linear-gradient( 285deg, transparent 2.4em, #fffd 2.45em, #fff8 14em, transparent 14.05em ); } .header_alpha_dark { background: -o-linear-gradient( 285deg, transparent 2.4em, #000e 2.45em, #0004 14em, transparent 14.05em ); background: -o-linear-gradient( 165deg, transparent 2.4em, #000e 2.45em, #0004 14em, transparent 14.05em ); background: linear-gradient( 285deg, transparent 2.4em, #000e 2.45em, #0004 14em, transparent 14.05em ); } .pricing-box.best-price .header_alpha .pricing-title { text-shadow: none; -webkit-filter: drop-shadow(0 0 0.4em white) drop-shadow(0 0 0.8em white) drop-shadow(0 0 1.2em white); filter: drop-shadow(0 0 0.4em white) drop-shadow(0 0 0.8em white) drop-shadow(0 0 1.2em white); } .pricing-box.best-price .header_alpha_dark .pricing-title { text-shadow: none; -webkit-filter: drop-shadow(0 0 0.4em #2228) drop-shadow(0 0 0.8em #2228) drop-shadow(0 0 1.2em #2228); filter: drop-shadow(0 0 0.4em #2228) drop-shadow(0 0 0.8em #2228) drop-shadow(0 0 1.2em #2228); } .pricing-action { margin-top: 0.4em; padding: 0; } .pricing-action > span { display: -webkit-box; display: -ms-flexbox; display: flex; -webkit-box-pack: justify; -ms-flex-pack: justify; justify-content: space-between; } .pricing-action small { font-size: 1.2em; } div.TeamJumpArea { margin: 0.6em; -webkit-filter: drop-shadow(0 0 0.6em #0002); filter: drop-shadow(0 0 0.6em #0002); } [class^='icon-'] { font-family: 'font-icons' !important; } `; // add sorting dropdown sortLabel.innerHTML = '<i class="icon-sort-by-attributes"></i> Sort by'; sortOptions.className = 'sm-form-control'; sortOptions.onchange = (e) => { const { value } = e.target; sortEntries(value); localStorage.setItem('dee2formatter_sortby', value); }; sortOptions.innerHTML = ` <option value="fs">Final Strikers First</option> <option value="index">Entry No.</option> <option value="title">Title</option> <option value="artists">Artists</option> <option value="genre">Genre</option> <option value="updated">Latest Activity</option> <option value="impressions">Impressions</option> <option value="total">Total Points</option> <option value="median">Median Points</option> ${entries[0].element.avg ? '<option value="avg">Average Points</option>' : ''} <option value="weighted">Weighted Score</option> <option value="random">Random</option> `; sortOptions.value = localStorage.getItem('dee2formatter_sortby') ?? 'random'; document.querySelector('.TeamJumpArea').innerHTML = ''; document.querySelector('.TeamJumpArea').appendChild(sortLabel); document.querySelector('.TeamJumpArea').appendChild(sortOptions); document .querySelector('#musiclist .content-wrap') .removeChild( document.querySelector('#musiclist .content-wrap>*:first-child') ); for (let t of teams) { list.removeChild(t); // t.outerHTML = ''; } list.appendChild(styles); for (let e of entries) { if (!isNaN(e.impressions)) { const total = e.element.stats.querySelector('p'); const ranking = e.element.ranking; const rankingParent = ranking?.parentElement; const newImpressionElement = document.createElement('p'); const weightedScoreElement = document.createElement('p'); newImpressionElement.innerHTML = `<span>Impressions</span><b>${e.impressions}</b>`; total.innerHTML = `<span>Total</span><b>${e.total.toFixed(2)}</b>${ e.fs ? `<span>× 1.5 = <b>${(e.total * 1.5).toFixed( 2 )}</b></span>` : '' }`; total.parentElement.insertBefore(newImpressionElement, total); if (rankingParent) rankingParent.innerHTML = `<span style="font-size:220%;font-family: 'Yanone Kaffeesatz', sans-serif; color:#FA8072;"></span>`; e.element.ranking = rankingParent?.firstElementChild; if (e.element.avg) e.element.avg.parentElement.innerHTML = `<span>Average</span><b>${e.avg.toFixed( 2 )}</b><meter value="${ e.avg }" min="100" max="1000" low="500" high="850" optimum="1000"></meter>`; if (e.element.median) e.element.median.parentElement.innerHTML = `<span>Median</span><b>${e.median}</b><meter value="${e.median}" min="100" max="1000" low="700" high="950" optimum="1000"></meter>`; weightedScoreElement.innerHTML = `<span>Weighted</span><b>${e.weighted.toFixed( 2 )}</b><meter value="${e.weighted.toFixed( 2 )}" min="100" max="1000" low="600" high="900" optimum="1000"></meter>`; e.element.stats.appendChild(weightedScoreElement); e.element.total = total; e.element.avg = e.element.avg?.parentElement; e.element.median = e.element.median?.parentElement; } else { e.element.stats.innerHTML = ''; e.element.total = null; e.element.avg = null; e.element.median = null; } e.element.base.removeAttribute('style'); e.element.base.removeAttribute('class'); e.element.title.title = e.title; e.element.artists.title = e.artists; e.element.genre.title = e.genre; e.element.artists.innerHTML = e.artists; e.element.info.parentElement.parentElement.removeAttribute('style'); e.element.info.innerHTML = e.element.info.innerHTML.replace( /No\.\d+? \/ /, '' ); e.element.info.outerHTML = `<small> <i class="icon-music2"></i> ${e.production} </small><small> <i class="icon-clock"></i> ${e.updated.toLocaleString(undefined, { timeZone: 'JST', })} </small>`; } sortEntries(sortOptions.value); // .sort((a, b) => b.pts.avg - a.pts.avg) return entries; })();