Created
November 20, 2019 12:41
-
-
Save ephphatha/e661e01d42134573bdcd5b1bbabb7988 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// ==UserScript== | |
// @name Baseball Tips Tracker | |
// @namespace https://thelettereph.com/ | |
// @version 1.0 | |
// @description Tracks baseball earnings and owed tips in OBL | |
// @author ephphatha | |
// @match *://politicsandwar.com/* | |
// @grant none | |
// ==/UserScript== | |
(function() { | |
'use strict'; | |
class NationStats { | |
constructor() { | |
this.allNationStats = new Map(JSON.parse(localStorage.getItem('f-goons-paw-nations'))); | |
} | |
save() { | |
localStorage.setItem('f-goons-paw-nations', JSON.stringify([...this.allNationStats])); | |
return true; | |
} | |
get(id, createMissing = true) { | |
id = parseInt(id); | |
if (!isNaN(id)) { | |
if (!this.allNationStats.has(id) && createMissing) { | |
this.allNationStats.set(id, {id: id, revenue: 0}); | |
} | |
return this.allNationStats.get(id); | |
} | |
} | |
set(id, nation) { | |
id = parseInt(id); | |
if (!isNaN(id)) { | |
this.allNationStats.set(id, nation); | |
return this.save(); | |
} | |
return false; | |
} | |
updateRevenue(id, delta) { | |
const nation = this.get(id); | |
nation.revenue = (nation.revenue || 0) + parseFloat(delta); | |
nation.balance = nation.revenue * 0.3 - (nation.income || 0); | |
this.save(); | |
} | |
updateIncome(id, delta) { | |
const nation = this.get(id); | |
nation.income = (nation.income || 0) + parseFloat(delta); | |
nation.balance = (nation.revenue || 0) * 0.3 - nation.income; | |
this.save(); | |
} | |
clearRevenue(id) { | |
const nation = this.get(id); | |
nation.revenue = 0; | |
delete nation.income; | |
delete nation.balance; | |
this.save(); | |
} | |
list(orderBy = null, defaultDir = true) { | |
if (!orderBy) { | |
return [...this.allNationStats.values()]; | |
} else { | |
return [...this.allNationStats.values()].sort((a, b) => { | |
if (defaultDir) { | |
return compare(a[orderBy], b[orderBy]); | |
} else { | |
return compare(b[orderBy], a[orderBy]); | |
} | |
}); | |
} | |
} | |
baseList(balanceThreshold = 1) { | |
return this.list('revenue').filter(nation => (typeof nation.balance !== "undefined" ? nation.balance : (nation.revenue * 0.3)) >= balanceThreshold); | |
} | |
} | |
class ControlVariables { | |
constructor() { | |
this.controlVars = new Map(JSON.parse(localStorage.getItem('f-goons-paw-controls'))); | |
} | |
save() { | |
localStorage.setItem('f-goons-paw-controls', JSON.stringify([...this.controlVars])); | |
return true; | |
} | |
get(key) { | |
return this.controlVars.get(key); | |
} | |
set(key, value) { | |
this.controlVars.set(key, value); | |
return this.save(); | |
} | |
} | |
const nationStats = new NationStats(); | |
const controlVariables = new ControlVariables(); | |
function compare(a, b) { | |
if (typeof a === 'number' && typeof b === 'number') { | |
return b - a; | |
} else { | |
return a > b ? 1 : a < b ? -1 : 0; | |
} | |
} | |
function createChildElement(tag, parent) { | |
const element = document.createElement(tag); | |
parent.appendChild(element); | |
return element; | |
} | |
function addTextToElement(element, text) { | |
const textNode = document.createTextNode(text); | |
element.appendChild(textNode); | |
} | |
function createTab(parent, name, text) { | |
const tab = createChildElement('li', parent); | |
tab.id = "f-goons-paw-tab-" + name; | |
const tabLink = createChildElement('a', tab); | |
tabLink.href = "#"; | |
tabLink.innerText = text; | |
tabLink.dataset.tabName = name; | |
return tab; | |
} | |
function clearChildren(node) { | |
const clearedNode = node.cloneNode(false); | |
node.parentNode.replaceChild(clearedNode, node); | |
return clearedNode; | |
} | |
function renderControlPanel() { | |
const helperStyle = document.createElement('style'); | |
helperStyle.type = 'text/css'; | |
helperStyle.id = 'paw-goons'; | |
helperStyle.innerText = '#f-goons-paw-main {position:fixed; right:0; bottom:0;}' + | |
'#f-goons-paw-main ul.nav {background:#ddd; border-top-left-radius:4px;}' + | |
'#f-goons-paw-container {border-left:1px solid #ddd; background:white; overflow:auto;}'; | |
document.head.appendChild(helperStyle); | |
const mainDiv = document.createElement('div'); | |
mainDiv.id = 'f-goons-paw-main'; | |
// render tabs | |
const mainNav = createChildElement('ul', mainDiv); | |
mainNav.className = 'nav nav-tabs'; | |
const baseballTab = createTab(mainNav, 'baseball', '⚾'); | |
const minMaxTab = createTab(mainNav, 'min-max', '🗕'); | |
minMaxTab.style = 'float: right;'; | |
mainNav.addEventListener('click', handleTabClick); | |
// panel container | |
const panel = createChildElement('div', mainDiv); | |
panel.id = 'f-goons-paw-container'; | |
panel.style = 'max-height: ' + window.innerHeight * 0.6 + 'px;'; | |
renderActivePanel(mainDiv); | |
document.body.appendChild(mainDiv); | |
} | |
function renderActivePanel(context) { | |
if (!context) { | |
context = document.querySelector('#f-goons-paw-main'); | |
} | |
context.querySelectorAll('.nav li.active').forEach( it => { it.className = '' } ); | |
const minimised = controlVariables.get('minimised'); | |
const minMaxTab = context.querySelector('#f-goons-paw-tab-min-max'); | |
const panel = context.querySelector('#f-goons-paw-container'); | |
if (minimised) { | |
//panel is minimised | |
minMaxTab.firstElementChild.innerText = '🗖'; | |
clearChildren(panel); | |
} else { | |
minMaxTab.firstElementChild.innerText = '🗕'; | |
const activeTabElement = context.querySelector('#f-goons-paw-tab-baseball'); | |
activeTabElement.className = 'active'; | |
renderRevenueTable(panel); | |
} | |
} | |
function renderRevenueTable(parent) { | |
const table = document.createElement('table'); | |
table.className = 'nationtable'; | |
const thead = createChildElement('thead', table); | |
let tr = createChildElement('tr', thead); | |
for (const text of ['Nation', 'Revenue', 'Tips Owed', 'Tips Received']) { | |
const th = createChildElement('th', tr); | |
th.innerText = text; | |
} | |
const tbody = createChildElement('tbody', table); | |
const numberFormat = new Intl.NumberFormat('en-US', { style: 'currency', currency: 'USD' }); | |
for (const nation of nationStats.baseList()) { | |
tr = createChildElement('tr', tbody); | |
let td = createChildElement('td', tr); | |
const nationLink = createChildElement('a', td); | |
nationLink.innerText = nation.name || nation.id; | |
nationLink.href = "https://politicsandwar.com/nation/id=" + nation.id; | |
td = createChildElement('td', tr); | |
td.className = 'right'; | |
addTextToElement(td, numberFormat.format(nation.revenue) + ' '); | |
const clearLink = createChildElement('a', td); | |
clearLink.innerText = '(clear)'; | |
clearLink.dataset.nationId = nation.id; | |
clearLink.addEventListener('click', handleClearClick); | |
td = createChildElement('td', tr); | |
td.className = 'right'; | |
addTextToElement(td, numberFormat.format((typeof nation.balance !== "undefined" ? nation.balance : (nation.revenue * 0.3)))); | |
td = createChildElement('td', tr); | |
const tipInput = createChildElement('input', td); | |
tipInput.type = 'number'; | |
tipInput.dataset.nationId = nation.id; | |
} | |
table.addEventListener('change', handleIncomeChange); | |
parent = clearChildren(parent); | |
parent.appendChild(table); | |
} | |
function handleTabClick(event) { | |
if (event.target.tagName == 'A') { | |
const tabName = event.target.dataset.tabName; | |
if (tabName == 'min-max') { | |
controlVariables.set('minimised', !controlVariables.get('minimised')); | |
} else { | |
controlVariables.set('minimised', false); | |
} | |
renderActivePanel(); | |
} | |
} | |
function handleClearClick(event) { | |
nationStats.clearRevenue(event.target.dataset.nationId); | |
event.target.parentNode.parentNode.remove(); | |
} | |
function handleIncomeChange(event) { | |
nationStats.updateIncome(event.target.dataset.nationId, event.target.value); | |
event.target.value = null; | |
const numberFormat = new Intl.NumberFormat('en-US', { style: 'currency', currency: 'USD' }) | |
const nation = nationStats.get(event.target.dataset.nationId); | |
event.target.parentNode.previousSibling.innerText = numberFormat.format((typeof nation.balance !== "undefined" ? nation.balance : (nation.revenue * 0.3))); | |
} | |
if (window.location.pathname.startsWith('/obl/play')) { | |
// Look for a table cell that contains the text "Game Results", this indicates we're on the results screen of an away game (most likely) | |
const gameResultsHeader = document.evaluate('.//th[text()="Game Results"]', document.body, null, XPathResult.ANY_UNORDERED_NODE_TYPE, null).singleNodeValue; | |
if (gameResultsHeader) { | |
const gameResultsTable = gameResultsHeader.parentNode.parentNode; // Up two levels is the table itself | |
const hostNationLink = gameResultsTable.querySelector('tr:nth-child(3) td:nth-child(2) a'); // Second cell of the third row has the host nation link | |
const hostNation = nationStats.get(hostNationLink.href.split('id=')[1]); // grab the ID from the end of the url | |
hostNation.name = hostNationLink.innerText; | |
// Fifth row has the scores | |
const awayScore = parseInt(gameResultsTable.querySelector('tr:nth-child(5) td:nth-child(2)').textContent); | |
const homeScore = parseInt(gameResultsTable.querySelector('tr:nth-child(5) td:nth-child(3)').textContent); | |
// Seventh row has the revenue (fourth cell) | |
let homeTeamRevenue = parseFloat(gameResultsTable.querySelector('tr:nth-child(7) td:nth-child(4)').textContent.substr(1).replace(',','')); | |
// If the home team won also include the game winnings (second cell) | |
if (homeScore >= awayScore) { | |
homeTeamRevenue += parseFloat(gameResultsTable.querySelector('tr:nth-child(7) td:nth-child(2)').textContent.substr(1).replace(',','')) | |
} | |
// Just keep track of the total so far. | |
nationStats.updateRevenue(hostNation.id, homeTeamRevenue); // this method performs a save so it'll also persist the name change above. | |
} | |
} | |
renderControlPanel(); | |
})(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment