您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Shows active player data in table format. Based on Opal's Action Scraper: https://greasyfork.org/en/scripts/31091-action-scraper
// ==UserScript== // @name Gates of Survival - Active Players scraper // @namespace https://www.gatesofsurvival.com // @version 0.11 // @author dang // @homepage https://github.com/dang-nabbit/gos-active-players-scraper // @description Shows active player data in table format. Based on Opal's Action Scraper: https://greasyfork.org/en/scripts/31091-action-scraper // @match https://www.gatesofsurvival.com/game/online.php // @icon https://www.google.com/s2/favicons?domain=https://www.gatesofsurvival.com/ // @grant none // ==/UserScript== // Settings var summaryShortSkillNames = true; // Turn off if you want full skill names on summary header var ldLNOnTop = true; // Turn off if you don't want LD/LN to be first clans listed var italicSkills = ['Agility']; // Make listed skills italic in player list var boldSkills = ['Not skilling']; // Make listed skills bold in player list var underlineSkills = ['Fishing']; // Make listed skills underlined in player list // Settings end var profileURL = 'https://www.gatesofsurvival.com/game/user2.php?user='; var errors = []; var clans = []; var noClan = { initials: 'None', players: [], skills: [] }; var hardcore = { initials: 'HC', players: [], skills: [] }; var ironman = { initials: 'IM', players: [], skills: [] }; var totals = { initials: 'Total', players: [], skills: [] }; var ld; var ln; var playerTypes = [ 'Hardcore Ironman', 'Ironman' ]; var numPlayerTypes = playerTypes.length; var skills = [ { name: 'Agility', short: 'Agil' }, { name: 'Arcane', short: 'Arcn' }, { name: 'Archery', short: 'Arch' }, { name: 'Baking', short: 'Bakn' }, { name: 'Botany', short: 'Bota' }, { name: 'Cooking', short: 'Cook' }, { name: 'Crafting', short: 'Crft' }, { name: 'Divination', short: 'Divn' }, { name: 'Exploration', short: 'Expl' }, { name: 'Fighting', short: 'Fght' }, { name: 'Firemaking', short: 'Fire' }, { name: 'Fishing', short: 'Fish' }, { name: 'Fletching', short: 'Flet' }, { name: 'Forestry', short: 'Frst' }, { name: 'Forging', short: 'Forg' }, { name: 'Gathering', short: 'Gthr' }, { name: 'Hunting', short: 'Hunt' }, { name: 'Jewelcrafting', short: 'Jwel' }, { name: 'Looting', short: 'Loot' }, { name: 'Mining', short: 'Mini' }, { name: 'Prayer', short: 'Pray' }, { name: 'Runebinding', short: 'Rnbd' }, { name: 'Skinning', short: 'Skin' }, { name: 'Slaying', short: 'Slay' }, { name: 'Smelting', short: 'Smlt' }, { name: 'Spellcraft', short: 'Spll' }, { name: 'Summoning', short: 'Smmn' }, { name: 'Thieving', short: 'Thvn' }, { name: 'Transmutation', short: 'Tran' }, { name: 'Woodworking', short: 'Wood' }, { name: 'Not skilling', short: 'None' } ]; var numSkills = skills.length; function addGlobalStyle(css, head) { var style; head = head || document.getElementsByTagName('head')[0]; style = document.createElement('style'); style.type = 'text/css'; style.innerHTML = css; head.appendChild(style); } function formatPercentage(number) { return (number * 100).toFixed(1) + '%'; } function addClanSkillCount(clan) { var skill; for (var i = 0; i < numSkills; i++) { skill = skills[i]; clan.skills.push({ name: skill.name, count: 0 }); } } function scrapePlayer(tdInnerHTML) { var mainRegEx = /<img src="images\/crowns\/(.+?)\.png".*?>.*?<input value="(\d+)".*?><input.*?>(.+?)<\/.*?<\/form>.*?\(Last Active: (.+?)\)/; var activityRegEx = /<b>Currently<\/b>: (.+?)<br>/; var clanRegex = /<b>Clan<\/b>: \[(.+?)\]/; var result = mainRegEx.exec(tdInnerHTML); var player = {}; var crown; var activityResult; var activity; var skill; var type; var clanResult; var i; if (result === null) { return { error: 'Player data not recognized', content: tdInnerHTML }; } else { player = { id: result[2], name: result[3], lastActive: result[4] }; crown = result[1]; if (crown.indexOf('crown_') > -1) { player.rank = crown.replace('crown_', ''); } else if (crown === 'sponsor') { player.rank = 'Sponsor'; } else { player.rank = 'Unidentified'; } activityResult = activityRegEx.exec(tdInnerHTML); if (activityResult !== null) { activity = activityResult[1]; for (i = 0; i < numSkills; i++) { skillName = skills[i].name; if (activity.indexOf(skillName) > -1) { player.skill = skillName; if (skillName === 'Fighting') { player.mob = activity.replace('Fighting a ', ''); } break; } } } if (!player.skill) { player.skill = 'Not skilling'; player.activity = activity || 'None'; } for (i = 0; i < numPlayerTypes; i++) { type = playerTypes[i]; if (tdInnerHTML.indexOf(type) > -1) { player.type = type; break; } } clanResult = clanRegex.exec(tdInnerHTML); if (clanResult !== null) { player.clan = clanResult[1]; } } return player; } function addPlayerToList(td) { var player = scrapePlayer(td.innerHTML); var playerClan = player.clan; var playerType = player.type; var clan = {}; var skill; var skillObj; if (player.error) { errors.push(player); } else if (playerClan) { clan = clans.find(function(clan) {return clan.initials === playerClan;}); if (!clan) { clan = { initials: playerClan, players: [], skills: [] }; addClanSkillCount(clan); if (['LD', 'LN'].indexOf(playerClan) > -1) { if (playerClan === 'LD') { ld = clan; } else if (playerClan === 'LN') { ln = clan; } if (ldLNOnTop) { clans.splice(0, 0, clan); } } else { clans.push(clan); } } } else if (playerType === 'Hardcore Ironman') { clan = hardcore; } else if (playerType === 'Ironman') { clan = ironman; } else { clan = noClan; } skillObj = clan.skills.find(function(skill) {return skill.name === player.skill;}); skillObj.count++; skillObj = totals.skills.find(function(skill) {return skill.name === player.skill;}); skillObj.count++; clan.players.push(player); totals.players.push(player); } function scrapeAll() { document.querySelectorAll('#third-container5 td').forEach(addPlayerToList); } function getErrorsTable() { var numErrors = errors.length; var div = document.createElement('div'); if (numErrors > 0) { var title = document.createElement('b'); title.appendChild(document.createTextNode('Errors')); div.appendChild(title); var table = document.createElement('table'); div.appendChild(table); div.appendChild(document.createElement('hr')); var row = table.insertRow(); var errorCell = row.insertCell(); errorCell.outerHTML = '<th>Error</th>'; var errorContentCell = row.insertCell(); errorContentCell.outerHTML = '<th>Content</th>'; var error; for (var i = 0; i < numErrors; i++) { error = errors[i]; row = table.insertRow(); errorCell = row.insertCell(); errorCell.appendChild(document.createTextNode(error.error || '')); errorContentCell = row.insertCell(); errorContentCell.appendChild(document.createTextNode(error.content || '')); } } return div; } function getPlayerTable(clan) { var players = clan.players; var numPlayers = players.length; var div = document.createElement('div'); if (numPlayers > 0) { var title = document.createElement('b'); title.appendChild(document.createTextNode(clan.initials)); div.appendChild(title); var table = document.createElement('table'); div.appendChild(table); div.appendChild(document.createElement('hr')); var row = table.insertRow(); var nameCell = row.insertCell(); nameCell.outerHTML = '<th>Name</th>'; var idCell = row.insertCell(); idCell.outerHTML = '<th>ID</th>'; var lastActiveCell = row.insertCell(); lastActiveCell.outerHTML = '<th>Last active</th>'; var rankCell = row.insertCell(); rankCell.outerHTML = '<th>Rank</th>'; var skillCell = row.insertCell(); skillCell.outerHTML = '<th>Skill</th>'; var mobCell = row.insertCell(); mobCell.outerHTML = '<th>Enemy</th>'; var activityCell = row.insertCell(); activityCell.outerHTML = '<th>Activity</th>'; var player; var playerAnchor; var playerSkill; for (var i = 0; i < numPlayers; i++) { player = players[i]; row = table.insertRow(); nameCell = row.insertCell(); playerAnchor = document.createElement('a'); playerAnchor.href = profileURL + (player.name || ''); playerAnchor.target = '_blank'; playerAnchor.appendChild(document.createTextNode(player.name || '')); nameCell.appendChild(playerAnchor); idCell = row.insertCell(); idCell.classList.add('number-cell'); idCell.appendChild(document.createTextNode(player.id || '')); lastActiveCell = row.insertCell(); lastActiveCell.appendChild(document.createTextNode(player.lastActive || '')); rankCell = row.insertCell(); rankCell.classList.add('number-cell'); rankCell.appendChild(document.createTextNode(player.rank || '')); playerSkill = player.skill; skillCell = row.insertCell(); skillCell.appendChild(document.createTextNode(playerSkill || '')); if (italicSkills.indexOf(playerSkill) > -1) { skillCell.classList.add('italic'); } if (boldSkills.indexOf(playerSkill) > -1) { skillCell.classList.add('bold'); } if (underlineSkills.indexOf(playerSkill) > -1) { skillCell.classList.add('underline'); } mobCell = row.insertCell(); mobCell.appendChild(document.createTextNode(player.mob || '')); activityCell = row.insertCell(); activityCell.appendChild(document.createTextNode(player.activity || '')); } } return div; } function getSummary() { // In summary, show clans and add other categories at end var summaryClans = clans.concat([noClan, ironman, hardcore, totals]); var numSummaryClans = summaryClans.length; var i; var j; var div = document.createElement('div'); // Title var title = document.createElement('b'); title.appendChild(document.createTextNode('Summary')); div.appendChild(title); var table = document.createElement('table'); div.appendChild(table); // Header row var row = table.insertRow(); // Clan name header var clanCell = row.insertCell(); clanCell.outerHTML = '<th>Clan</th>'; // Skill headers var skillCell; var skillHeader = (summaryShortSkillNames) ? 'short' : 'name' for (i = 0; i < numSkills; i++) { skillCell = row.insertCell(); skillCell.outerHTML = '<th>' + skills[i][skillHeader] + '</th>'; } // Total column header var clanTotalCell = row.insertCell(); clanTotalCell.outerHTML = '<th>Total</th>'; // Total % column header var clanTotalPercCell = row.insertCell(); clanTotalPercCell.outerHTML = '<th>%</th>'; // Lucky % row row = table.insertRow(); // Lucky % "clan name" clanCell = row.insertCell(); clanCell.appendChild(document.createTextNode('L%')); // Lucky % skill numbers var totalPlayers = ld.players.length + ln.players.length; for (i = 0; i < numSkills; i++) { skillCell = row.insertCell(); skillCell.classList.add('number-cell'); skillCell.appendChild(document.createTextNode(formatPercentage((ld.skills[i].count + ln.skills[i].count)/totalPlayers))); } // Empty total and total % cells for Lucky % clanTotalCell = row.insertCell(); clanTotalCell.classList.add('number-cell'); clanTotalPercCell = row.insertCell(); clanTotalPercCell.classList.add('number-cell'); var clan; totalPlayers = totals.players.length; for (i = 0; i < numSummaryClans; i++) { clan = summaryClans[i]; // Clan row row = table.insertRow(); // Clan name cell clanCell = row.insertCell(); clanCell.appendChild(document.createTextNode(clan.initials)); // Clan skill numbers for (j = 0; j < numSkills; j++) { skillCell = row.insertCell(); skillCell.classList.add('number-cell'); skillCell.appendChild(document.createTextNode(clan.skills[j].count)); } // Clan total count clanTotalCell = row.insertCell(); clanTotalCell.classList.add('number-cell'); clanTotalCell.appendChild(document.createTextNode(clan.players.length)); // Clan total % clanTotalPercCell = row.insertCell(); clanTotalPercCell.classList.add('number-cell'); clanTotalPercCell.appendChild(document.createTextNode(formatPercentage(clan.players.length/totalPlayers))); } // % row row = table.insertRow(); // % name cell clanCell = row.insertCell(); clanCell.appendChild(document.createTextNode('%')); // % skill numbers for (j = 0; j < numSkills; j++) { skillCell = row.insertCell(); skillCell.classList.add('number-cell'); skillCell.appendChild(document.createTextNode(formatPercentage(totals.skills[j].count/totalPlayers))); } // Empty total and total % cells for Lucky % clanTotalCell = row.insertCell(); clanTotalCell.classList.add('number-cell'); clanTotalPercCell = row.insertCell(); clanTotalPercCell.classList.add('number-cell'); return div; } function addReportStyles(doc) { var css = '.italic {\n' + ' font-style: italic;\n' + '}\n\n' + '.bold {\n' + ' font-weight: bold;\n' + '}\n\n' + '.underline {\n' + ' text-decoration: underline;\n' + '}\n\n' + '.number-cell {\n' + ' text-align: right;\n' + ' padding-right: 3px;\n' + '}'; addGlobalStyle(css, doc.head); } function printDataTables() { addClanSkillCount(noClan); addClanSkillCount(ironman); addClanSkillCount(hardcore); addClanSkillCount(totals); scrapeAll(); var reportDoc = window.open().document; addReportStyles(reportDoc); var reportBody = reportDoc.body; reportBody.appendChild(getErrorsTable()); var numClans = clans.length; for (var i = 0; i < numClans; i++) { reportBody.appendChild(getPlayerTable(clans[i])); } reportBody.appendChild(getPlayerTable(noClan)); reportBody.appendChild(getPlayerTable(ironman)); reportBody.appendChild(getPlayerTable(hardcore)); reportBody.appendChild(getSummary()); } printDataTables();