您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
inclues game info on strikeout.co main page
// ==UserScript== // @name strikeout.co scores // @namespace http://your.homepage/ // @version 1.0 // @description inclues game info on strikeout.co main page // @author muffleyd // @match http://www.strikeout.co/ // @grant $ // ==/UserScript== /** Copywrite David Muffley 2015-2016. * Use however you like, with acknowledgement. */ (function () { // TODO more styling for info text? //remove crap at the top of the content if ("#content #accordian") { $("#content > *:not(:has(#accordion))").remove(); } //just, stop $('#toTop').remove(); //_main() won't run through if tab is hidden, this stores when that occurs so on tab visibility it can run again var SKIPPED = false; //_main() will always run the first time through even if the tab is hidden var firstGet = true; //completed inning value to display no hitter info (middle of previous inning for away hitters) var NOHITATBATS = 6; var addedClasses = ['_tmMLBFree', '_tmESPN']; var selectorParent = '#content h1[league="Major League Baseball"]'; function parseTime(time) { //time can be in format of "10:35" or timezone like "-03:30" or "+9:30" var mod = 1; if (time[0] == '-' || time[0] == '+') { if (time[0] == '-') { mod = -1; } time = time.substring(1); } time = time.split(':'); return mod * ((parseInt(time[0]) * 60) + parseInt(time[1])); } //set "mlbgday" attr to match mlb.com's scoreboard since "gday" attribute may not match mlb's date, based on timezone (function () { var timezoneMod = parseTime(timezone) + 240; // + 240 makes this effectively eastern time, close enough $(selectorParent + ' .matchtime').each(function (index, el) { var val = el.getAttribute('gday'); //even at -12:00 it can't be behind by a day, it can only ever be ahead by a day all the way to +13:00 if (parseTime(el.innerText) - timezoneMod < 0) { var dateObj = new Date(val); dateObj.setTime(dateObj.getTime() - (86400 * 1000)); val = dateObj.toJSON().slice(0, 10); } el.setAttribute('mlbgday', val); }) })(); //pass an optional delay in // when waking up from sleep the network connection is not immediately active, this allows you to compensate for that function main(delay) { if (!delay) { delay = 0; } setTimeout(_main, delay * 1000); } // 5 hours in the past, for when it's after midnight, not sure if needed function _main() { //skip when tab is hidden or window is minimized, and set so event is later told to run main() if (!firstGet && document.hidden) { SKIPPED = true; return; } firstGet = false; var dateObj = new Date(); //offset the computer's timezone to get UTC, then go back 10 hours to guarantee you use the correct date for mlb.com var date = new Date(dateObj.getTime() + (dateObj.getTimezoneOffset() * 60 * 1000) - (1000 * 60 * 60 * 10)); var year = date.getFullYear().toString(); //January is 0, etc, so add 1 var month = date.getMonth() + 1; if (month < 10) { month = "0" + month.toString(); } else { month = month.toString(); } var day = date.getDate(); if (day < 10) { day = "0" + day.toString(); } else { day = day.toString(); } $.getJSON('http://gd2.mlb.com/components/game/mlb/year_' + year + '/month_' + month + '/day_' + day + '/miniscoreboard.json', function (resp, type) { if (type == 'success') { $(document).ready(function () { //clear previously added classes to elements addedClasses.forEach(function (item) { $(selectorParent).removeClass(item); }); var info = resp.data.games.game; if (info.length === undefined) { //if only one game, it's not passed back as an array info = [info]; } var gameObj = {}; //on later runs, remove added text immediately $(selectorParent + ' a ._tmInfo').remove(); //get all team names from today $(selectorParent + ' a:has(span[mlbgday="' + year + '-' + month + '-' + day + '"])').each(function (index, el) { var gameText = el.lastChild.textContent.trim(); //later regex now checks for hyphens, so deal with it in D-backs gameText = gameText.replace('D-backs', 'Diamondbacks'); //Find games missing the colon before "Game #" and add it in // But don't for ones using a hyphen gameText = gameText.replace(/([^:\-])(\s+[Gg]ame\s+[0-9]+)$/, '$1:$2'); //Turn "Team vsTeam" into "Team vs Team". Not truely needed since only the team name, not city is used, but just in case gameText = gameText.replace(/(\s+[Vv][Ss])([A-Z])/, '$1 $2'); //this match regex handles things like: // Team vs Team // Team vs Team: Game 2 // MLB Wildcard: Team vs Team // ALDS: Team vs Team: Game 1 // Team vs Team - Game 2 //regex split is for occasional non-space blank character (tab has been there) var txt = gameText.match(/([^:]+:|^)(.*?vs[^:\-$]+)(.*)/i); if (txt === null) { console.log('not a game', gameText); //something like "MLB on Fox Sports 1 Pregame" return; } var texts = txt[2].split(/\s+vs\s+/i); texts.forEach(function (item) { var splitItems = item.trim().split(/\s+/); //strip out this special thing that has appeared during spring training if (splitItems[splitItems.length-1] == '(ss)') { splitItems.pop(); } splitItems.forEach(function (item, index, arr) { //combine all words after the first, getting smaller and smaller, //because of things like "Chicago White Sox" while avoiding "Los Angeles Dodgers" if (index == 0) { return; } var key = arr.slice(index).join(' '); if (!gameObj.hasOwnProperty(key)) { gameObj[key] = []; } //sometimes a game appears as "A vs B - Game 2", so keep the spaces around the "-" if (txt[3][0] == '-') { var txt2end = txt[2].substr(-1); if (txt2end.match(/\s/)) { txt[3] = txt2end + txt[3]; txt[2] = txt[2].slice(0, -1); } } //place at the head since the (reversed) game array goes from the beginning of gameObj[key] //include the original text so extra stuff can stay when rewriting it later gameObj[key].unshift([el, txt]); }); }); }); //fix differences if (gameObj.hasOwnProperty('Diamondbacks')) { gameObj['D-backs'] = gameObj['Diamondbacks']; } console.log(gameObj); //sort handles out of order games in the info list which happens sometimes with resumed games or double headers info.sort(function (a, b) { //test for NaN because sometimes "time" is like "Game 2" var t1 = a.time.split(':'); t1 = (t1[0] * 60) + (1*t1[1]); if (isNaN(t1)) { return 0; } var t2 = b.time.split(':'); t2 = (t2[0] * 60) + (1*t2[1]); if (isNaN(t2)) { return 0; } //note that mlb.com returns all times as ET //some games start at 12:35pm, and rarely in the 11am hour, while never being 11pm or later //since there's no 24 hour time these need to be set as being before 1pm if (t1 >= 11*60) { t1 -= (12*60); } if (t2 >= 11*60) { t2 -= (12*60); } // if (t1 < t2) { return -1; } if (t1 > t2) { return 1; } return 0; }); info.reverse(); info.forEach(function (item, index, arr) { var unknownStatus = false; var delayed = false; var postponed = false; var stop = false; var media = true; var final = false; var checkAwayNoHit = false; var checkHomeNoHit = false; var includeReason = false; if (item.status == 'Pre-Game' || item.status == 'Preview') { //after removing the first item and managing media info this will return stop = true; } else if (item.status == 'In Progress' || item.status == 'Review' || item.status == 'Manager Challenge') { //good } else if (item.status == 'Game Over' || item.status == 'Final' || item.status == 'Completed Early') { //good if (item.status == 'Completed Early') { includeReason = true; } media = false; final = true; } else if (item.status == 'Delayed Start' || item.status == 'Delayed') { //delay, but good includeReason = true; delayed = true; } else if (item.status == 'Warmup') { //good } else if (item.status == 'Postponed' || item.status == 'Suspended' || item.status == 'Cancelled') { includeReason = true; postponed = true; } else { unknownStatus = true; console.log('other status:', item.status, item); } console.log(item.away_team_name, item.home_team_name); if (!gameObj.hasOwnProperty(item.away_team_name) || !gameObj.hasOwnProperty(item.home_team_name)) { return; } var gameEl = gameObj[item.away_team_name][0]; if (gameEl === undefined) { //likely a double header's first game that's fallen off the top of the list console.log('game gone', item); return; } else { gameEl = gameEl[0] } var originalMainText = gameObj[item.away_team_name][0][1]; if (gameEl !== gameObj[item.home_team_name][0][0]) { //cry console.log('mismatch', item); } else if (gameEl) { //pop off the game values, in case of double header gameObj[item.away_team_name].shift(); gameObj[item.home_team_name].shift(); console.log(item, gameEl); if (media) { handle_game_media(item, gameEl); } //for double headers, now that the game is popped off we can return if (stop) { return; } var text = ''; var cls = ''; if (item.status == 'Warmup') { text = 'Warmup'; cls = 'warmup'; } else { var status = item.status; if (status != 'Game Over' && status != 'Final') { if (postponed) { cls = 'postponed'; } //Top 3, Bottom 5, Middle 7, etc. //also determine if no hitter worth mentioning //if home team is ahead in the middle or later of inning 9 or greater, it's actually over //same if score is different at end of inning 9 or greater if (item.hasOwnProperty('inning')) { cls += ' inprogress'; //check for no-hitter through NOHITATBATS number of at-bats for a team if (item.inning > NOHITATBATS) { checkAwayNoHit = true; checkHomeNoHit = true; } if (item.top_inning == "Y") { if (item.outs == 3) { var topbottom = 'Middle'; if (item.inning >= item.scheduled_innings && item.away_team_runs < item.home_team_runs) { final = true; } if (item.inning >= NOHITATBATS) { checkAwayNoHit = true; } } else { topbottom = 'Top'; } } else { if (item.outs == 3) { topbottom = 'End'; if (item.inning >= item.scheduled_innings && item.away_team_runs != item.home_team_runs) { final = true; } if (item.inning >= NOHITATBATS) { checkAwayNoHit = true; checkHomeNoHit = true; } } else { topbottom = 'Bottom'; if (item.inning >= item.scheduled_innings && item.away_team_runs < item.home_team_runs) { final = true; } if (item.inning >= NOHITATBATS) { checkAwayNoHit = true; } } } if (!final) { if (topbottom) { text = topbottom + ' ' } text += item.inning; } } } if (final) { text = 'Final'; //usually extra innings, perhaps rain-shortened? if (item.inning != 9) { text += ' (' + item.inning + ')'; } cls = 'final'; } if ((checkHomeNoHit && item.home_team_hits == 0) || (checkAwayNoHit && item.away_team_hits == 0)) { cls += ' noHitter'; } if (item.hasOwnProperty('away_team_runs') && item.hasOwnProperty('home_team_runs')) { text += ', ' + item.away_team_runs + '-' + item.home_team_runs; var parens = true; } else { parens = false; } if (includeReason) { text += ' '; if (parens) { text += '('; } text += item.status; if (item.reason) { text += ': ' + item.reason; } if (parens) { text += ')'; } } } if (unknownStatus) { text += ' DEBUG:' + item.status; } //get original text surrounding the 'Team vs Team' to include along with the reordering of the Teams to Away vs Home gameEl.lastChild.textContent = originalMainText[1] + ' ' + getTeamName(item, 'away') + ' vs ' + getTeamName(item, 'home') + originalMainText[3]; if (text) { $('<span class="_tmInfo">, <span class="_tmText ' + cls + '">' + text + '</span></span>').appendTo(gameEl); } } }); }); } }); } function handle_game_media(item, gameEl) { if (item.game_media && item.game_media.media) { var media = item.game_media.media; if ($.isArray(item.game_media.media)) { media = item.game_media.media[0]; } if (media.free != "NO") { if (media.free != "ALL") { console.log('different media free info', media); } gameEl.parentElement.classList.add('_tmMLBFree'); } } if (item.tv_station) { item.tv_station.split(', ').forEach(function (station) { //TODO find ESPN more generally if (station == 'ESPN' || station == 'ESPN2' || station == 'ESPN (out-of-market only)') { gameEl.parentElement.classList.add('_tmESPN'); } }); } } //example why this is needed: //team_city: 'NY Yankees' //team_name: 'Yankees' //Should return 'NY Yankees' rather than 'NY Yankees Yankees' function getTeamName(item, homeaway) { var city = item[homeaway + '_team_city']; var name = item[homeaway + '_team_name']; if (city.slice(-name.length) == name) { return city; } else { return city + ' ' + name; } } var initial_delay = 6; var constant_delay = 120; main(); //this blob compensates for 'initial_delay' // e.g. main loop runs every 2 minutes, with a 6 second initial delay, // this will wait 114 seconds to run main(6) and register the Interval of 120 seconds at the same time to run main(6) setTimeout(function () { main(initial_delay); setInterval(main, 1000 * constant_delay, initial_delay); }, 1000 * (constant_delay - initial_delay)); //since we don't do anything when the tab is invisible, force an update when made visible if one was skipped document.addEventListener('visibilitychange', function () { if (!document.hidden) { if (SKIPPED) { SKIPPED = false; main(); } } }); function addGlobalStyle(css) { var head, style; head = document.getElementsByTagName('head')[0]; if (!head) { return; } style = document.createElement('style'); style.type = 'text/css'; style.innerHTML = css; head.appendChild(style); } $(document).ready(function () { //do an awful job of figuring out which theme is running if ($('body').css('background-color').replace(/\s/g, '') == 'rgb(0,0,0)') { //golden midnight $('body').addClass('_tmDark'); addGlobalStyle('body._tmDark ._tmInfo ._tmText.inprogress { color: lightblue; }'); addGlobalStyle('body._tmDark ' + selectorParent + '._tmMLBFree { background: green; }'); addGlobalStyle('body._tmDark ' + selectorParent + '._tmESPN { background: rgba(255,7,7,.35); }'); addGlobalStyle('body._tmDark ._tmInfo ._tmText.noHitter { background: crimson; }'); } else { //white magic or failure } addGlobalStyle('._tmInfo ._tmText.inprogress { color: red; }'); addGlobalStyle('._tmInfo ._tmText.warmup { color: goldenrod; }'); addGlobalStyle('._tmInfo ._tmText.final { color: grey; }'); addGlobalStyle('._tmInfo ._tmText.postponed { color: blue; }'); addGlobalStyle('._tmInfo ._tmText.noHitter { background: chartreuse; }'); addGlobalStyle(selectorParent + '._tmMLBFree { background: gold; }'); addGlobalStyle(selectorParent + '._tmESPN { background: rgba(255,7,7,.25); }'); }); })()
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址