TrueAchievements improver

Improves the TrueAchievements interface in various ways

当前为 2016-04-07 提交的版本,查看 最新版本

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Greasemonkey 油猴子Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Userscripts ,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==UserScript==
// @name         TrueAchievements improver
// @namespace    mobiusevalon.tibbius.com
// @version      0.6
// @description  Improves the TrueAchievements interface in various ways
// @author       Mobius Evalon
// @require      https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js
// @include      /^https{0,1}:\/\/\w{0,}\.?trueachievements\.com.*$/
// @grant        none
// ==/UserScript==

var hide_ads = 1,
    normalize_dates = 1,
    improve_chat = 1,
    minimalize_chat = 1,
    session_user_links = 1,
    session_user_status = 1,
    feed_permalinks = 1,
    fix_spoilers = 1;

Date.prototype.getShortMonthString = function()
{
    switch(this.getMonth())
    {
        case 0: return "Jan";
        case 1: return "Feb";
        case 2: return "Mar";
        case 3: return "Apr";
        case 4: return "May";
        case 5: return "Jun";
        case 6: return "Jul";
        case 7: return "Aug";
        case 8: return "Sep";
        case 9: return "Oct";
        case 10: return "Nov";
        case 11: return "Dec";
    }
};

Date.prototype.getTwoDigitHours = function()
{
    var n = this.getHours();
    if(n < 10) return ("0"+n);
    else return n.toString();
};

Date.prototype.getTwoDigitMinutes = function()
{
    var n = this.getMinutes();
    if(n < 10) return ("0"+n);
    else return n.toString();
};

Date.prototype.getTwoDigitDate = function()
{
    var n = this.getDate();
    if(n < 10) return ("0"+n);
    else return n.toString();
};

Date.prototype.adjustDate = function(n)
{
    this.setDate(this.getDate()+n);
};

Date.prototype.getDateAfterAdjustment = function(n)
{
    this.adjustDate(n);
    return this.getDate();
};

Date.prototype.shortDate = function()
{
    return (this.getTwoDigitDate()+" "+this.getShortMonthString()+" "+this.getFullYear());
};

Date.prototype.shortDateTime = function()
{
    return (this.getTwoDigitDate()+" "+this.getShortMonthString()+" "+this.getFullYear()+", "+this.getTwoDigitHours()+":"+this.getTwoDigitMinutes());
};

function datetime_master(obj)
{
    var date = new Date();

    if(!obj.hasOwnProperty("minute") || obj.minute === undefined) obj.minute = "00";
    if(!obj.hasOwnProperty("hour") || obj.hour === undefined) obj.hour = "00";
    if($.type(obj.day) === "string") obj.day = obj.day.toLowerCase();
    if(!obj.hasOwnProperty("day") || obj.day === undefined || obj.day === "today") obj.day = date.getDate();
    else if(obj.day === "yesterday") obj.day = date.getDateAfterAdjustment(-1);
    else if(obj.day === "tomorrow") obj.day = date.getDateAfterAdjustment(+1);
    if(!obj.hasOwnProperty("month") || obj.month === undefined) obj.month = date.getShortMonthString();
    if(!obj.hasOwnProperty("year") || obj.year === undefined) obj.year = date.getFullYear();
    else if(obj.year.length === 2) obj.year = ("20"+obj.year);

    date = new Date(obj.month+" "+obj.day+" "+obj.year+" "+obj.hour+":"+obj.minute);

    return date;
}

function short_datetime_callback() // mon, jan 1 1900 at 00:00
{
    var len = arguments.length;
    var date = datetime_master({year:arguments[len-5],month:arguments[len-6],day:(arguments[len-7]||arguments[len-8]),hour:arguments[len-4],minute:arguments[len-3]});
    return date.shortDateTime();
}

function short_date_callback() // 1 jan 1900
{
    var len = arguments.length;
    var date = datetime_master({year:arguments[len-3],month:arguments[len-4],day:(arguments[len-5]||arguments[len-6])});
    return date.shortDate();
}

function uri()
{
	var m = window.location.href.match(/\/([\w-]*\.aspx)(?:\?|$)/i);
	if(m !== null) return m[1];
	return "";
}

$(document).ready(function() {
    if(hide_ads) $("#topad-wrap, #divTAProHolder, #divGiftProPanel, .followuson, .internalad, .rightintergi, .sharepanel").remove(); // oops, the ads disappeared
    if(normalize_dates)
    {
        $("td.lastpostdate, td.posted, div.info, td.time, td.sentdate, div.coveritem, td.ta, div.boostingdate, div.gamingsession h3, div.subcommentinfo, td.lastpost, div.links").each(function() {
            $(this).html($(this).html().replace(/(?:on )?(?:[A-Z]{1}[a-z]{2,8}, )?(today|yesterday|tomorrow|(?:\d{1,2}) ([A-Z]{1}[a-z]{2,8}) ?(\d{2,4})?) at (\d{2}):(\d{2})/g,short_datetime_callback));
        });
        $("div.addedby, td.hwr, table.comparison td.green, .maincolumnpanel .itemright h3").each(function() {
            $(this).html($(this).html().replace(/(?:on )?(?:[A-Z]{1}[a-z]{2,8}, )?(today|yesterday|tomorrow|(\d{1,2}) ([A-Z]{1}[a-z]{2,8}) (\d{2,4}))/g,short_date_callback));
        });
    }
    // fix spoilers
    if(fix_spoilers) $("div.spoiler").each(function() {
        $(this)
            .css("border","1px solid #000")
            .children("a").first().replaceWith($("<span/>")
                                               .text("SPOILER: click to toggle")
                                               .css("display","inline-block")
                                               .css("width","100%")
                                               .css("cursor","pointer")
                                               .click(function() {var $span_content = $(this).siblings("span.spoiler").first();

                                                                  if($span_content.css("display") === "none") $span_content.show();
                                                                  else $span_content.hide();
                                                                 })
                                              );
    });
    // friend feed permalinks
    if(feed_permalinks) $("#oFriendFeed div.Comment p").each(function() {$(this).prepend($("<a/>")
                                                                                         .attr("href",("?gfcid="+$(this).parent().attr("id").slice(5)))
                                                                                         .append($("<img/>")
                                                                                                 .attr("src","/images/icons/permalink.png")
                                                                                                 .attr("class","AddComment")
                                                                                                 .attr("title","Permalink")
                                                                                                 .attr("alt","Permalink")
                                                                                                )
                                                                                        );
                                                                        });

    switch(uri())
    {
        case "gamingsessionfeedback.aspx":
            $(".gsdisclaimer").remove();
            break;
        case "gamingsession.aspx":
            $(".gsdisclaimer").remove();

            if(session_user_links && $("#mnuMyPages").length) // change gamertag links to compare page
            {
                var game_id = $("h4 a[title='View on session calendar']").first().attr("href"),
                    user_id = $("#mnuMyPages li a[href*='/gamerstats.aspx?gamerid=']").attr("href");
                game_id = game_id.slice(game_id.lastIndexOf("=")+1);
                user_id = user_id.slice(user_id.lastIndexOf("=")+1);

                $("#oGamingSessionGamerList td.gamer").each(function() {
                    var $gamer_anchor = $(this).children("a").first(),
                        other_id = $gamer_anchor.attr("href");
                    other_id = other_id.slice(other_id.lastIndexOf("=")+1);

                    if(other_id != user_id) $gamer_anchor.attr("href",("/comparison.aspx?gameid="+game_id+"&gamerid="+user_id+"&friendid="+other_id));
                    $gamer_anchor.attr("target","_blank");
                });

                if(session_user_status) $("span.sitestatus").remove();
            }
            break;
        case "chat.aspx":
            var css = "";

            if(improve_chat)
            {
                // this whole css section is overriding the default styling of the page when viewing the chatroom to change a whole
                // bunch of things, including:
                // # changing the font of the whole chat interface
                // # extending the height of the userlist to be the same as the chatbox
                // # shrinking the vertical display slightly so it all fits on the page at the same time (i always had to scroll a
                //   bit to get to the textbox)
                // # extending the width of the input box
                // # giving the timestamp a fixed width
                // # giving the gamertag a fixed width
                // # positioning the buttons we'll be adding after the text input later
                // # preventing long words (spam) from adding horizontal scrolling
                css = css +
                    "div#divChatHolder {font-family: 'Droid Sans Mono',monospace !important} "+
                    "div#divChatList {width: 175px !important; height: 450px !important;}" +
                    "div#divChatBody {margin-right: 190px !important; height: 450px !important; overflow-wrap: break-word !important;} "+
                    "input#txtChatMessage {width: 720px !important;} "+
                    "span.chattime {display: inline-block !important; width: 65px !important; font-style: normal !important;} "+
                    "span.gamertag {display: inline-block !important; width: 105px !important;} "+
                    "a#btnClearChat {position: relative !important; top: -4px !important; right: auto !important; padding-right: 8px !important;} "+
                    "img#btnChatRules {position: relative !important; top: -4px !important;} ";

                // this section moves the clear chat button and creates a new rules button to the right of the input box at the bottom
                $("#btnClearChat")
                    .insertBefore($("#divChatKey"))
                    .after($("<a/>")
                           .attr("href","chatpolicy.aspx")
                           .attr("target","_blank")
                           .append($("<img/>")
                                   .attr("src","/images/itemflags/MainStoryline.png")
                                   .attr("id","btnChatRules")
                                   .attr("title","Chat guidelines")
                                   .attr("alt","Chat guidelines")
                                  )
                          );
                $("#divChatKey, #divChatInformation").remove();
            }
            if(minimalize_chat)
            {
                // this section enforces additional options that leaves basically nothing on the page besides the chat
                // elements, collapsing vertical space and removing elements from the page to even fit the whole thing
                // on one screen and prevent vertical scrolling
                css = css +
                    "div#main-holder {padding-bottom: 0 !important;} "+
                    "div#main {padding: 10px 10px 0px 10px !important; min-height: 0 !important;} "+
                    "div#page-wrap {padding-bottom: 0 !important;} "+
                    "div#page {min-height: 0 !important;}";
                // the "header" variable points to the large bold text at the top of the page that says "TrueAchievements Chat"
                // the footer is a huge bar of information that stretches the page
                $("h1.pagetitle, #footer-wrap").remove();
            }

            // simply injecting the above css rules into the document
            if(css.length) $("head").append($("<style/>")
                                            .attr("type","text/css")
                                            .text(css)
                                           );
            break;
    }
});