您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
description
// ==UserScript== // @name Company Helper // @namespace namespace // @version 0.5.1 // @description description // @author tos // @match *.torn.com/companies.php* // @grant GM_addStyle // @grant GM_xmlhttpRequest // ==/UserScript== const apiKey = 'YOUR_API_KEY' const torn_api = async (args) => { const a = args.split('.') if (a.length!==3) throw(`Bad argument in torn_api(args, key): ${args}`) return new Promise((resolve, reject) => { GM_xmlhttpRequest ( { method: "POST", url: `https://api.torn.com/${a[0]}/${a[1]}?selections=${a[2]}&key=${apiKey}`, headers: { "Content-Type": "application/json" }, onload: (response) => { try { const resjson = JSON.parse(response.responseText) resolve(resjson) } catch(err) { reject(err) } }, onerror: (err) => { reject(err) } }) }) } GM_addStyle(` .last_action_icon { cursor: pointer; vertical-align: middle; display: inline-block; background-image: url(/images/v2/sidebar_icons_desktop_2017.png); background-repeat: no-repeat; background-position-y: -783px; width: 34px; height: 30px; } .last-action { cursor: pointer; width: 103px; padding-left: 10px; margin-top: -1px; position: relative; float: left; height: 33px; line-height: 33px; border-left: 1px solid #fff; border-right: 1px solid #ccc; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } .la_pointer { cursor: pointer; } .employees_alert { background-color: #f8e0da; border-radius: 0px 5px 5px 0px; color: red; font-weight: bold; width: 60%; } .trains_alert { background-color: #d7e1cc; border-radius: 0px 5px 5px 0px; color: green; font-weight: bold; width: 60%; } .eff_alert { background: #f8e0da !important; } .employee_idle { color: #e39500; } .employee_away { color: red; } `) function company_details() { const detailsUL = document.querySelector('.company-stats-list.company-info') const total_employees = parseInt(detailsUL.querySelector('.total-employees').innerText) const limit_employees = parseInt(detailsUL.querySelector('.limit-employees').innerText) if (total_employees < limit_employees) detailsUL.children[0].children[3].classList.add('employees_alert') const trains = detailsUL.querySelector('.trains') const max_trains = parseInt(trains.nextSibling.nodeValue.replace('/', '')) let rating = 0 for (const star of detailsUL.querySelector('.company-rating').children) star.classList.contains('active') ? rating += 1 : null if (parseInt(trains.innerText) + rating >= max_trains) trains.parentNode.classList.add('trains_alert') torn_api(`company..employees`).then((res) => { const employee = res.company_employees let maxEff = true for (const i in employee) if (employee[i].effectiveness < 5) maxEff = false if (!maxEff) document.querySelector('.company-tabs').children[1].classList.add('eff_alert') }) } const toggle_last_action = (n) => { while (n && !n.querySelector('.stats')) {n = n.parentNode} const statsDIV = n.querySelector('.stats') const lastActionDIV = n.querySelector('.last-action') const employeeID = lastActionDIV.getAttribute('data-employeeID') statsDIV.classList.toggle('hide') lastActionDIV.classList.toggle('hide') if (lastActionDIV.classList.contains('hide')) lastActionDIV.innerHTML = '<img src="/images/v2/main/ajax-loader.gif">' else torn_api(`user.${employeeID}.profile`).then((res) => { lastActionDIV.innerHTML = res.last_action.relative if (res.last_action.relative.includes('day')) { lastActionDIV.classList.add('employee_idle') if (parseInt(res.last_action.relative.split(' ')[0]) > 2) lastActionDIV.classList.replace('employee_idle', 'employee_away') } }) } const toggleLastActionALL = (statsTitle, employeeUL) => { if (statsTitle.innerText === 'Stats (M/I/E)') { statsTitle.childNodes[0].nodeValue = 'Last Action' for (const i of employeeUL.querySelectorAll('.stats')) i.classList.add('hide') for (const j of employeeUL.querySelectorAll('.last-action')) j.classList.remove('hide') for (const unloaded of employeeUL.querySelectorAll('.last-action img')) { const lastActionDIV = unloaded.parentNode const employeeID = lastActionDIV.getAttribute('data-employeeID') torn_api(`user.${employeeID}.profile`).then((res) => { lastActionDIV.innerHTML = res.last_action.relative if (res.last_action.relative.includes('day')) { lastActionDIV.classList.add('employee_idle') if (parseInt(res.last_action.relative.split(' ')[0]) > 2) lastActionDIV.classList.replace('employee_idle', 'employee_away') } }) } } else { statsTitle.childNodes[0].nodeValue = 'Stats (M/I/E)' for (const i of employeeUL.querySelectorAll('.last-action')) i.classList.add('hide'), i.innerHTML = '<img src="/images/v2/main/ajax-loader.gif">' for (const j of employeeUL.querySelectorAll('.stats')) j.classList.remove('hide') } } const observer = new MutationObserver((mutations) => { for (const mutation of mutations) { for (const node of mutation.addedNodes) { if ( node.tagName && node.tagName === 'FORM') { switch (node.action) { case 'https://www.torn.com/companies.php?step=employees&update=true': const statsTitle = node.querySelector('.employee-list-title .stats') const employeeUL = node.querySelector('.employee-list') statsTitle.insertAdjacentHTML('beforeend', `<i class="last_action_icon right"></i>`) statsTitle.querySelector('.last_action_icon').addEventListener('click', () => { toggleLastActionALL(statsTitle, employeeUL) }) for (const employeeLI of employeeUL.children) { const statsDIV = employeeLI.querySelector('.stats') const employeeID = employeeLI.getAttribute('data-user') statsDIV.classList.add('la_pointer') statsDIV.insertAdjacentHTML('afterend', `<div class="last-action hide" data-employeeID="${employeeID}"><img src="/images/v2/main/ajax-loader.gif"></div>`) const lastActionDIV = statsDIV.parentNode.querySelector('.last-action') statsDIV.addEventListener('click', (e) => {toggle_last_action(e.target)}) lastActionDIV.addEventListener('click', (e) => {toggle_last_action(e.target)}) } break default: console.log(node.action) break } } } } }); const wrapper = document.querySelector('.company-wrap') observer.observe(wrapper, { subtree: true, childList: true }) company_details()