strikeout.co scores

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或关注我们的公众号极客氢云获取最新地址