您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Stores and displays information on player profile pages
当前为
// ==UserScript== // @name Profile Info // @namespace sullenProfileInfo // @version 0.6.1 // @description Stores and displays information on player profile pages // @author sullengenie [1946152] // @match *://*.torn.com/profiles.php?XID=* // @grant GM_addStyle // ==/UserScript== // Some code kindly contributed by miros [1848626] (function() { 'use strict'; const tag_colors = { tbd: 'inherited', easy: 'rgba(161, 248, 161, 1)', medium: 'rgba(231, 231, 104, 1)', impossible: 'rgba(242, 140, 140, 0.7)' }; // Utility code from Peaceful Elimination by Mauk [1494436] const create_html = (html) => document.createRange().createContextualFragment(html); const insert_before = (nodes, target) => target.parentNode.insertBefore(nodes, target); const insert_after = (nodes, target) => target.parentNode.insertBefore(nodes, target.nextSibling); const button_style = (color) => `.profile-button-attack { background: linear-gradient(180deg, #ebebeb, ${color}) !important; }`; const color_button = function(color) { document.getElementById('difficulty-profile-button-style').innerText = button_style(color); }; // A button which other scripts can click to update attack button color const invis_elt = create_html('<div id="sullen-update-button" style="display:none"></div>'); const automatic_tags = JSON.parse(localStorage.automaticProfileInfo || '{}'); const manual_tags = JSON.parse(localStorage.sullenProfileInfo || '{}'); const player_id = parseInt(window.location.href.match(/XID=(\d+)/)[1]); const initial_player_info = Object.assign({}, automatic_tags, manual_tags)[player_id] || {}; const initial_manual_difficulty = (manual_tags[player_id] && manual_tags[player_id].difficulty) || 'tbd'; const initial_difficulty = initial_player_info.difficulty || 'tbd'; const initial_notes = initial_player_info.notes || 'Write player notes here. They will automatically save!'; function update_button() { const difficulty = get_player_difficulty(); color_button(tag_colors[difficulty]); if (document.getElementById('difficulty-profile-title')) { update_panel_title(); } } function update_tags(f) { let tags = JSON.parse(localStorage.sullenProfileInfo || '{}'); f(tags); localStorage.sullenProfileInfo = JSON.stringify(tags); } function update_player(vals) { update_tags(tags => tags[player_id] = Object.assign({}, tags[player_id], vals)); } function update_hidden(val) { update_tags(tags => tags.hidden = val); } function player_info() { const auto_tags = JSON.parse(localStorage.automaticProfileInfo || '{}'); const manual_tags = JSON.parse(localStorage.sullenProfileInfo || '{}'); return Object.assign({}, auto_tags[player_id], manual_tags[player_id]); } function get_player_difficulty() { return (player_info().difficulty) || 'tbd'; } function get_player_notes() { return player_info().notes || ''; } function update_difficulty(menu) { const difficulty = menu.value; update_tags((tags) => { if (difficulty === 'tbd' && tags[player_id] && tags[player_id].difficulty) { delete tags[player_id].difficulty; delete tags[player_id].difficultyTimestamp; } else { if (tags[player_id] === undefined) { tags[player_id] = {}; } tags[player_id].difficulty = difficulty; tags[player_id].difficultyTimestamp = Date.now(); } }); color_button(tag_colors[get_player_difficulty()]); } function update_notes(notes) { update_player({notes: notes.value}); } String.prototype.capitalize = function() { return this.charAt(0).toUpperCase() + this.slice(1); }; const MAX_NOTES_LENGTH = 58; function summarize(notes) { if (notes.length <= MAX_NOTES_LENGTH) { return notes; } else { return notes.substring(0, MAX_NOTES_LENGTH - 3) + '...'; } } const title_arrow = '<div class="arrow-wrap"><i class="accordion-header-arrow right" id="profile-info-arrow"></i></div>'; function age_string(timestamp) { return `${Math.floor((Date.now() - timestamp) / 1000 / 60 / 60 / 24)} days ago`; } function panel_title() { const tags = player_info(); let difficulty_timestamp; if (tags.difficultyTimestamp) { difficulty_timestamp = new Date(); difficulty_timestamp.setTime(tags.difficultyTimestamp); } const difficulty = get_player_difficulty(); return ` ${title_arrow} Profile Info <span class="panel-title-difficulty ptd-${difficulty}">${difficulty === 'tbd' ? '' : difficulty.capitalize() + ' (' + (difficulty_timestamp ? age_string(difficulty_timestamp) : 'automatic') + ')'}</span> <span class="panel-title-notes">${summarize(get_player_notes())}</span>`; } function update_panel_title() { document.getElementById('difficulty-profile-title').innerHTML = panel_title(); } const profile_info_panel = () => create_html(` <div class="profile-wrapper m-top10"> <div> <div class="title-black top-round ${manual_tags.hidden ? 'all-round' : 'active'}" id="difficulty-profile-title"> ${panel_title()} </div> <div class="cont bottom-round"> <div class="profile-container basic-info bottom-round" id="difficulty-profile-body" style="display:${manual_tags.hidden ? 'none' : 'block'}"> <div style="padding: 10px"> <select id="difficulty-dropdown" style="margin: 0px 10px 0px 0px" onchange="update_difficulty(this)"> <option ${initial_manual_difficulty === 'tbd' ? 'selected="selected"' : ''} value="tbd">Difficulty</option> <option ${initial_manual_difficulty === 'easy' ? 'selected="selected"' : ''} value="easy">Easy</option> <option ${initial_manual_difficulty === 'medium' ? 'selected="selected"' : ''} value="medium">Medium</option> <option ${initial_manual_difficulty === 'impossible' ? 'selected="selected"' : ''} value="impossible">Impossible</option> </select> <textarea id="difficulty-notes" rows="10" cols="50">${initial_notes}</textarea> </div> </div> </div> </div> </div>`); function add_title_toggle_onclick() { const title_node = document.getElementById('difficulty-profile-title'); const body_node = document.getElementById('difficulty-profile-body'); title_node.onclick = function() { if (body_node.style.display !== 'none') { body_node.style.display = 'none'; update_hidden(true); title_node.classList.add('all-round'); title_node.classList.remove('active'); } else { body_node.style.display = 'block'; update_hidden(false); title_node.classList.remove('all-round'); title_node.classList.add('active'); } }; } function add_difficulty_onchange() { const dropdown = document.getElementById('difficulty-dropdown'); dropdown.onchange = () => { update_difficulty(dropdown); update_panel_title(); }; } function add_notes_oninput() { const notes = document.getElementById('difficulty-notes'); notes.oninput = () => { update_notes(notes); update_panel_title(); }; } function add_info_panel(medal_wrapper) { insert_before(profile_info_panel(), medal_wrapper); add_title_toggle_onclick(); add_difficulty_onchange(); add_notes_oninput(); } const is_medals_wrapper = (node) => node.classList !== undefined && node.classList.contains('medals-wrapper'); // Adds the profile info panel once the medals wrapper has loaded function wait_for_medals_wrapper() { let target = document.querySelector('div.user-profile'); let observer = new MutationObserver(function(mutations) { mutations.forEach(function(mutation) { for (let i = 0; i < mutation.addedNodes.length; i++) { const node = mutation.addedNodes.item(i); if (is_medals_wrapper(node)) { add_info_panel(node); this.disconnect(); break; } } }.bind(this)); }); let config = { attributes: true, childList: true, characterData: true }; observer.observe(target, config); } // Waits for the medals wrapper panel once the page has loaded initially function wait_for_page_load() { let target = document.getElementById('profileroot').firstElementChild; let observer = new MutationObserver(function(mutations) { wait_for_medals_wrapper(); this.disconnect(); }); let config = { attributes: true, childList: true, characterData: true }; observer.observe(target, config); } function init() { // Wait for enough elements to load so that we can add the profile info panel wait_for_page_load(); GM_addStyle(` #difficulty-profile-title { cursor: pointer; } #difficulty-profile-body * { vertical-align:top; } .all-round { border-radius: 5px !important; } .active #profile-info-arrow { margin: 11px 10px 0 0; } #profile-info-arrow { margin: 9px 12px 0 0; } .panel-title-difficulty { margin-left: 1em; } .ptd-easy { color: ${tag_colors.easy}; } .ptd-medium { color: ${tag_colors.medium}; } .ptd-impossible { color: ${tag_colors.impossible}; } .panel-title-notes { margin-left: 2em; font-size: 90%; } `); // Add button style element document.body.appendChild(create_html('<style id="difficulty-profile-button-style"></style>')); color_button(tag_colors[initial_difficulty || 'tbd']); // Add invisible button which other scripts can click to update attack button color document.body.appendChild(invis_elt); document.getElementById('sullen-update-button').onclick = update_button; } init(); })();
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址