-
-
Save zeeres/2bdcc309598d743d4d20de0d65cbcd86 to your computer and use it in GitHub Desktop.
TagPro Chat Scroller
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 TagPro Chat Scroller | |
// @description Changes the default chat into a scrollable, whole-game chat. Optionally shows last-game chat between games. | |
// @version 0.6.3.2(Ko) | |
// - v0.6.3.Ko: Add a fadeTime option, to fade the time after 20 secs. | |
// I've labeled all changes with Ko: for reference | |
// - v0.6.3: Fix the 'serverHost' bug. | |
// - v0.6.2: Added 'bwep' sound on all chat messages option. Fixed a teamcount bug. | |
// - v0.6.0: Added caps timeline. | |
// - Made compatible with new TagPro site design. | |
// - Added team totals to chat log scoreboard. | |
// - Added score when player joins/leaves the games. | |
// - Added click name in chat to report. | |
// - Added player join/left sounds. | |
// @include http://tagpro-*.koalabeast.com* | |
// @include http://*.newcompte.fr:* | |
// @include http://tangent.jukejuice.com* | |
// @author nabby | |
// @require http://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js | |
// @require http://ajax.googleapis.com/ajax/libs/jqueryui/1.11.4/jquery-ui.min.js | |
// @resource jqUI_CSS http://ajax.googleapis.com/ajax/libs/jqueryui/1.11.4/themes/smoothness/jquery-ui.css | |
// @updateURL https://gist.github.com/zeeres/2bdcc309598d743d4d20de0d65cbcd86/raw/01b060e0b1a001cbf3c5bdc86c8377a707afec16/TagPro_Chat_Scroller.user.js | |
// @downloadURL https://gist.github.com/zeeres/2bdcc309598d743d4d20de0d65cbcd86/raw/01b060e0b1a001cbf3c5bdc86c8377a707afec16/TagPro_Chat_Scroller.user.js | |
// @grant GM_getResourceText | |
// @grant GM_getValue | |
// @grant GM_setValue | |
// @grant GM_deleteValue | |
// @grant GM_addStyle | |
// ==/UserScript== | |
console.log('START: ' + GM_info.script.name + ' (v' + GM_info.script.version + ' by ' + GM_info.script.author + ')'); | |
var $uHome = $('#userscript-home'); | |
var $uTop = $('#userscript-top'); | |
var $uBottom = $('#userscript-bottom'); | |
tagpro.ready(function() { | |
/*************************************/ | |
/* Options */ | |
/*************************************/ | |
var showTime = true; //show the countdown timer time in chat log window [Default: true] | |
var fadeTime = false; //Ko: fades the time after 20 seconds, which is when the message disappears for 'normal' players [Default: true] | |
var hideTimeOnSystemChat = true; //hides the time on system chat messages (like "Since there aren't many players in this game yet") [Default: true] | |
var showPlayerAuthTick = true; //put a green tick next to authenticated player names [Default: true] | |
var showCaps = true; //shows when a cap was made [Default: true] | |
var showScoreOnJoinLeft = true; //shows the score & team counts when a player joins or leaves the game [Default: true] | |
var playSoundOnJoin = false; //plays a "dink" sound when a player joins the game [Default: true] | |
var playSoundOnLeft = false; //plays a "donk" sound when a player leaves the game [Default: true] | |
var playSoundOnMessage = false; //plays a "bwep" sound on all chat messages [Default: false] | |
var ignoreMuteSoundIcon = true; //will play sounds even if the tagpro sounds are off [Default: true] | |
var showBorder = false; //show a dashed border around the chat window [Default: true] | |
var showScollBar = false; //show a scrollbar on the chat window [Default: true] | |
var showLastGameOnHome = false; //shows the last game's chat log on the server home page [Default: false] | |
var showLastGameOnJoiner = true; //shows the last game's chat log on the joining page [Default: true] | |
var showScoreboardOnHome = true; //shows the last game's scoreboard at the end of the chat log on the server/joiner pages [Default: true] | |
var showScoreboardOnEOG = false; //shows the current game's scoreboard at the end of the chat log when the game ends [Default: true] | |
var showTeamTotals = true; //shows the totals for Red/Blue stats on the scoreboard [Default: true] | |
var showSummaryOnHome = true; //shows the game summary & caps timeline at the end of the chat log on the server/joiner pages [Default: true] | |
var showSummaryOnEOG = true; //shows the current game's summary (& caps timeline) at the end of the chat log when the game ends [Default: true] | |
var showTimelineOnSummary = true; //shows a timeline of the game caps (`showCaps` must also be `true`) [Default: true] | |
var showLJSOnTimeline = false; //shows all leavers, joiners & switchers on the game summary timeline (`showTimelineOnSummary` must also be `true`) [Default: false] | |
var hideNormalChat = true; //hide the normal chat window (good for testing) [Default: true] | |
//Colors... | |
var redTextColor = '#F8B0B8'; //Default: #F8B0B8 | |
var blueTextColor = '#C9C9F8'; //Default: #C9C9F8 | |
var timeColor = '#FFA500'; //Default: #FFA500 | |
var fadeColor = '#C09E60'; //Default: #C09E60 Ko: | |
var defaultBorder = '1px dashed gray'; //Default: 1px dashed gray | |
var defaultBackground = 'rgba(100,100,100,0.05)'; //Default: rgba(100,100,100,0.05) (grey with 0.8 transparency) | |
/*************************************/ | |
GM_addStyle('.CS_Red { color:'+redTextColor+'; }'); | |
GM_addStyle('.CS_Blue { color:'+blueTextColor+'; }'); | |
GM_addStyle('.CS_Font7 { font-size:7px; }'); | |
GM_addStyle('.CS_Font9 { font-size:9px; }'); | |
GM_addStyle('.CS_Bold { font-weight:bold; }'); | |
GM_addStyle('.CS_Underline { text-decoration:underline; }'); | |
GM_addStyle('.CS_Auth { color:#77ff00; }'); | |
GM_addStyle('.CS_Cap { color:#333; background:#3D0; border-radius:4px; text-shadow:none; font-weight:bold; font-size:10px; padding:0 2px; margin-right:2px; }'); | |
var $CS_ChatHistory, $CS_ChatHistory_Container; | |
var PageLoc = WhichPageAreWeOn(); | |
// add to page: | |
if (PageLoc === 'ingame') { | |
$('body').append('<div id="CS_ChatHistory_Container" style="position:absolute; padding:5px 0; height:'+GM_getValue('size', {height:310}).height+'px; width:'+GM_getValue('size', {width:310}).width+'px; left:'+GM_getValue('position', {left:5}).left+'px; top:'+GM_getValue('position', {top:430}).top+'px;'+(showBorder ? ' border:'+defaultBorder+'; ' : '')+' font:11px Arial; text-shadow:1px 1px 1px black; background:'+defaultBackground+'; overflow-x:hidden; overflow-y:auto;"><div id="CS_ChatHistory"></div></div>'); | |
} else { | |
$uBottom.find('.row').append('<div id="CS_ChatHistory_Container" style="position:absolute; padding:5px 0; height:'+GM_getValue('size', {height:310}).height+'px; width:'+GM_getValue('size', {width:310}).width+'px; left:'+GM_getValue('position', {left:5}).left+'px; top:'+GM_getValue('position', {top:430}).top+'px;'+(showBorder ? ' border:'+defaultBorder+'; ' : '')+' font:11px Arial; text-shadow:1px 1px 1px black; background:#333; overflow-x:hidden; overflow-y:auto;"><div id="CS_ChatHistory"></div></div>'); | |
$uBottom.removeClass('hidden'); | |
} | |
$CS_ChatHistory = $('#CS_ChatHistory'); | |
$CS_ChatHistory_Container = $('#CS_ChatHistory_Container'); | |
GM_addStyle('#CS_ChatHistory_Container::-webkit-scrollbar { width:'+(showScollBar?'2px':'0px')+' }'); | |
GM_addStyle('#CS_ChatHistory_Container::-webkit-scrollbar-thumb { background:#b0b; }'); | |
GM_addStyle('#CS_ChatHistory_Container::-webkit-scrollbar-track { background:#ddd; }'); | |
GM_addStyle('.CS_Link { text-decoration:underline; color:palegoldenrod !important }'); | |
function showLastGameLog() { | |
var lastChatLog = $.parseHTML( GM_getValue('lastChatLog', '') ); | |
if (lastChatLog) { | |
if ($(lastChatLog).find('.CS_Kickable').length) { | |
$(lastChatLog).find('.CS_Kickable').removeData('kickid').removeAttr('data-kickid').removeAttr('title').removeClass(); | |
$CS_ChatHistory.append(lastChatLog); | |
GM_setValue('lastChatLog', $CS_ChatHistory.html()); | |
} else { | |
$CS_ChatHistory.append(lastChatLog); | |
} | |
$CS_ChatHistory.prepend('<div style="text-align:center; margin-bottom:5px; text-decoration:underline">Last Game Chat Log...</div>'); | |
} | |
} | |
function showSummary() { | |
var scoreboard = ''; | |
if ( ( (PageLoc !== 'ingame' && showScoreboardOnHome) || (PageLoc === 'ingame' && showScoreboardOnEOG) || (PageLoc !== 'ingame' && showSummaryOnHome) || (PageLoc === 'ingame' && showSummaryOnEOG) ) && GM_getValue('gameData') ) { | |
var stats = [ 'score', 'tags', 'pops', 'grabs', 'drops', 'hold', 'captures', 'prevent', 'returns', 'support', 'powerups', 'points' ]; | |
var rStats = { score:0, tags:0, pops:0, grabs:0, drops:0, hold:0, captures:0, prevent:0, returns:0, support:0, powerups:0, points:0 }; | |
var bStats = { score:0, tags:0, pops:0, grabs:0, drops:0, hold:0, captures:0, prevent:0, returns:0, support:0, powerups:0, points:0 }; | |
var game = GM_getValue('gameData'); | |
var playedFor = (game.timePlayed / game.fullGameLength * 100).toFixed(2); | |
if (playedFor > 100) playedFor = 100; | |
$CS_ChatHistory_Container.append('<div id="CS_GameSummary" style="border-top:1px solid white; border-bottom:1px solid white; margin:20px 1px 5px 1px"></div>'); | |
if ((PageLoc !== 'ingame' && showScoreboardOnHome) || (PageLoc === 'ingame' && showScoreboardOnEOG)) { | |
scoreboard = '<table id="CS_Scoreboard"><tr id="CS_Scoreboard_Header"><td></td><td>Sc</td><td>Ta</td><td>Po</td><td>Gr</td><td>Dr</td><td>Ho</td><td>Ca</td><td>Pr</td><td>Re</td><td>Su</td><td>PU</td><td>Pt</td></tr>'; | |
$.each(game.playersData, function(key, value) { | |
scoreboard += '<tr'+(value.self === true ? ' class="CS_SB_HighlightSelf"' : '')+' data-team="'+value.team+'"><td style="color:'+(value.team === 1 ? redTextColor : blueTextColor)+'">'+(value.auth ? '<span class="CS_Auth CS_Font7">✔</span>' : '')+value.name+'</td><td data-raw="'+value.score+'">'+value.score+'</td><td data-raw="'+value.tags+'">'+value.tags+'</td><td data-raw="'+value.pops+'">'+value.pops+'</td><td data-raw="'+value.grabs+'">'+value.grabs+'</td><td data-raw="'+value.drops+'">'+value.drops+'</td><td data-raw="'+value.hold+'">'+secondsToHMS(value.hold)+'</td><td data-raw="'+value.captures+'">'+value.captures+'</td><td data-raw="'+value.prevent+'">'+secondsToHMS(value.prevent)+'</td><td data-raw="'+value.returns+'">'+value.returns+'</td><td data-raw="'+value.support+'">'+value.support+'</td><td data-raw="'+value.powerups+'">'+value.powerups+'</td><td data-raw="'+value.points+'">'+(value.points ? value.points : '-')+'</td></tr>'; | |
if (showTeamTotals) { | |
$.each(stats, function(k, v) { | |
if (value.team === 1) { | |
rStats[v] += value[v]; | |
} else { | |
bStats[v] += value[v]; | |
} | |
}); | |
} | |
}); | |
scoreboard += '</table>'; | |
setTimeout(function() { | |
var $table = $('#CS_Scoreboard'), $column, prevMax; | |
for (var i=2; i<=13; i++) { | |
$column = $('#CS_Scoreboard tr:gt(0) td:nth-child('+i+')'); | |
prevMax = 0; | |
$( $column ).each(function(k, v) { | |
if ($(this).data('raw') > prevMax) { | |
$($column).removeClass('CS_Max'); | |
$(this).addClass('CS_Max'); | |
prevMax = $(this).data('raw'); | |
} else if ($(this).data('raw') === prevMax) { | |
$(this).addClass('CS_Max'); | |
} | |
}); | |
} | |
if (showTeamTotals) { | |
$('#CS_Scoreboard').append('<tr style="background:#777"><td colspan="13" style="border:3px solid transparent;"></td></tr>'); | |
$('#CS_Scoreboard').append('<tr style="background:rgba(255,0,0,0.2)"><td style="color:'+redTextColor+'; text-align:right">Red Total:</td><td'+(rStats.score>bStats.score?' class="CS_Max_Red"':'')+'>'+rStats.score+'</td><td'+(rStats.tags>bStats.tags?' class="CS_Max_Red"':'')+'>'+rStats.tags+'</td><td'+(rStats.pops>bStats.pops?' class="CS_Max_Red"':'')+'>'+rStats.pops+'</td><td'+(rStats.grabs>bStats.grabs?' class="CS_Max_Red"':'')+'>'+rStats.grabs+'</td><td'+(rStats.drops>bStats.drops?' class="CS_Max_Red"':'')+'>'+rStats.drops+'</td><td'+(rStats.hold>bStats.hold?' class="CS_Max_Red"':'')+'>'+secondsToHMS(rStats.hold)+'</td><td'+(rStats.captures>bStats.captures?' class="CS_Max_Red"':'')+'>'+rStats.captures+'</td><td'+(rStats.prevent>bStats.prevent?' class="CS_Max_Red"':'')+'>'+secondsToHMS(rStats.prevent)+'</td><td'+(rStats.returns>bStats.returns?' class="CS_Max_Red"':'')+'>'+rStats.returns+'</td><td'+(rStats.support>bStats.support?' class="CS_Max_Red"':'')+'>'+rStats.support+'</td><td'+(rStats.powerups>bStats.powerups?' class="CS_Max_Red"':'')+'>'+rStats.powerups+'</td><td'+(rStats.points>bStats.points?' class="CS_Max_Red"':'')+'>'+(rStats.points ? rStats.points : '-')+'</td></tr>'); | |
$('#CS_Scoreboard').append('<tr style="background:rgba(0,0,255,0.2)"><td style="color:'+blueTextColor+'; text-align:right">Blue Total:</td><td'+(bStats.score>rStats.score?' class="CS_Max_Blue"':'')+'>'+bStats.score+'</td><td'+(bStats.tags>rStats.tags?' class="CS_Max_Blue"':'')+'>'+bStats.tags+'</td><td'+(bStats.pops>rStats.pops?' class="CS_Max_Blue"':'')+'>'+bStats.pops+'</td><td'+(bStats.grabs>rStats.grabs?' class="CS_Max_Blue"':'')+'>'+bStats.grabs+'</td><td'+(bStats.drops>rStats.drops?' class="CS_Max_Blue"':'')+'>'+bStats.drops+'</td><td'+(bStats.hold>rStats.hold?' class="CS_Max_Blue"':'')+'>'+secondsToHMS(bStats.hold)+'</td><td'+(bStats.captures>rStats.captures?' class="CS_Max_Blue"':'')+'>'+bStats.captures+'</td><td'+(bStats.prevent>rStats.prevent?' class="CS_Max_Blue"':'')+'>'+secondsToHMS(bStats.prevent)+'</td><td'+(bStats.returns>rStats.returns?' class="CS_Max_Blue"':'')+'>'+bStats.returns+'</td><td'+(bStats.support>rStats.support?' class="CS_Max_Blue"':'')+'>'+bStats.support+'</td><td'+(bStats.powerups>rStats.powerups?' class="CS_Max_Blue"':'')+'>'+bStats.powerups+'</td><td'+(bStats.points>rStats.points?' class="CS_Max_Blue"':'')+'>'+(bStats.points ? bStats.points : '-')+'</td></tr>'); | |
} | |
}, 100); | |
GM_addStyle('#CS_Scoreboard { margin:5px 0; font-size:10px; color:#bbb; line-height:8px; width:100%; text-align:center; border-collapse:collapse; border-spacing:1px; }'); | |
GM_addStyle('#CS_Scoreboard_Header { color:#fff; }'); | |
GM_addStyle('#CS_Scoreboard td { border:1px solid #555; }'); | |
GM_addStyle("#CS_Scoreboard tr.CS_SB_HighlightSelf { background:rgba(50,200,50,0.2) }"); | |
GM_addStyle('#CS_Scoreboard .CS_Max { color:gold }'); | |
GM_addStyle('#CS_Scoreboard .CS_Max_Red { color:white; background:rgba(220,0,0,0.6) }'); | |
GM_addStyle('#CS_Scoreboard .CS_Max_Blue { color:white; background:rgba(0,0,240,0.7) }'); | |
$('#CS_GameSummary').append(scoreboard); | |
} | |
if ((PageLoc !== 'ingame' && showSummaryOnHome) || (PageLoc === 'ingame' && showSummaryOnEOG)) { | |
$('#CS_GameSummary').prepend('<div id="CS_GameSummary_Header" style="margin:2px 10px; border:1px solid #bbb; border-radius:7px; box-shadow:1px 1px 1px #999;"></div>'); | |
$('#CS_GameSummary_Header').append('<div style="text-align:center; color:#ccc; font-size:11px; font-weight:bold;">' + (game.spectator ? '<span style="background:' + (game.spectatorTeam === 1 ? 'red' : game.spectatorTeam === 2 ? '#46F' : 'none') + '; display:inline-block; border-radius:50%; width:15px; height:13px; line-height:10px;" title="You were watching: '+game.spectator+'">👀</span> ' : '') + '<span style="text-decoration:underline;">' + game.mapName + ' by ' + game.mapAuthor + ' (' + game.gameMode + ')</span></div>'); | |
$('#CS_GameSummary_Header').append('<div style="text-align:center; color:#bbb; font-size:10px">' + new Date(parseInt(Date.parse(game.played))).toLocaleTimeString() + ' (' + new Date(parseInt(Date.parse(game.played))).toDateString() + (game.serverName ? ') on ' + game.serverName : ')') + '</div>'); | |
$('#CS_GameSummary_Header').append('<div style="text-align:center; color:#bbb; font-size:10px; font-style:italic">You '+(game.spectator ? 'watched' : 'played')+' for ' + secondsToHMS(game.timePlayed) + ' of ' + secondsToHMS(game.fullGameLength) + ' ('+ playedFor + '%)</div>'); | |
if (game.allCaps.length && showTimelineOnSummary) { | |
var timePlayed = game.timePlayed*1000; | |
var gameLength = game.fullGameLength*1000; | |
if (gameLength > 720000) gameLength = 720000; | |
var startTime = Date.parse(game.played); | |
var joinTime = startTime + gameLength - timePlayed; | |
var endTime = startTime + gameLength; | |
var fullTime = startTime + 720000; | |
var joinPoint = 100 - ((fullTime - joinTime) / 720000) * 100; | |
var endPoint = 100 - ((fullTime - endTime) / 720000) * 100; | |
var gameWidth = endPoint - joinPoint; | |
var endWidth = 100 - endPoint; | |
$('#CS_GameSummary').append('<div id="CS_TL_Outer"></div>'); | |
$('#CS_TL_Outer').append('<div id="CS_TL"></div>'); | |
if (joinPoint > 0) $('#CS_TL').append('<div id="CS_TL_Pre" style="width:'+joinPoint+'%"></div>'); | |
$('#CS_TL').append('<div id="CS_TL_Game" style="left:'+joinPoint+'%; width:'+gameWidth+'%;"></div>'); | |
if (endPoint < 100) $('#CS_TL').append('<div id="CS_TL_Post" style="left:'+endPoint+'%; width:'+endWidth+'%;"></div>'); | |
var resultClass='CS_TL_MyTeam', title=''; | |
$('#CS_TL_Outer').append('<div id="CS_TL_RedLabel">'+game.redScore+'</div>'); | |
$('#CS_TL_Outer').append('<div id="CS_TL_BlueLabel">'+game.blueScore+'</div>'); | |
if (game.result === 'Win') { | |
if (game.team === 1) $('#CS_TL_RedLabel').attr('title', 'We (Red) Won '+game.redScore+':'+game.blueScore).addClass('CS_TL_MyTeamWin'); | |
else $('#CS_TL_BlueLabel').attr('title', 'We (Blue) Won '+game.redScore+':'+game.blueScore).addClass('CS_TL_MyTeamWin'); | |
} else if (game.result === 'Loss') { | |
if (game.team === 1) $('#CS_TL_RedLabel').attr('title', 'We (Red) Lost '+game.redScore+':'+game.blueScore).addClass('CS_TL_MyTeamLoss'); | |
else $('#CS_TL_BlueLabel').attr('title', 'We (Blue) Lost '+game.redScore+':'+game.blueScore).addClass('CS_TL_MyTeamLoss'); | |
} else if (game.result === 'Tie') { | |
if (game.team === 1) $('#CS_TL_RedLabel').attr('title', 'Game Tied '+game.redScore+':'+game.blueScore).addClass('CS_TL_MyTeam'); | |
else $('#CS_TL_BlueLabel').attr('title', 'Game Tied '+game.redScore+':'+game.blueScore).addClass('CS_TL_MyTeam'); | |
} | |
$.each(game.allCaps, function(key, value) { | |
var thisPoint = joinPoint + (100 - ((fullTime - value.time) / 720000) * 100); | |
if (!value.hasOwnProperty('what') || value.what === 'cap') { | |
$('#CS_TL').append('<div class="'+(value.team===1?'CS_TL_CapRed':'CS_TL_CapBlue')+'" style="left:'+thisPoint+'%;" title="Cap: '+value.name+'\nHold: '+value.holdTime+'\nTimer: '+value.timer+'\nTeams: '+value.redCount+'v'+value.blueCount+'\nScore: '+value.redScore+':'+value.blueScore+'"></div>'); | |
} else if (value.what === 'left') { | |
$('#CS_TL').append('<div class="'+(value.team===1?'CS_TL_Left_Red':'CS_TL_Left_Blue')+'" style="left:'+thisPoint+'%;" title="Left: '+value.name+'\nTimer: '+value.timer+'\nTeams: '+value.redCount+'v'+value.blueCount+'\nScore: '+value.redScore+':'+value.blueScore+'"></div>'); | |
} else if (value.what === 'joined') { | |
$('#CS_TL').append('<div class="'+(value.team===1?'CS_TL_Joined_Red':'CS_TL_Joined_Blue')+'" style="left:'+thisPoint+'%;" title="Joined: '+value.name+'\nTimer: '+value.timer+'\nTeams: '+value.redCount+'v'+value.blueCount+'\nScore: '+value.redScore+':'+value.blueScore+'"></div>'); | |
} else if (value.what === 'switched') { | |
$('#CS_TL').append('<div class="'+(value.team===1?'CS_TL_Switched_Red':'CS_TL_Switched_Blue')+'" style="left:'+thisPoint+'%;" title="Switched: '+value.name+'\nTimer: '+value.timer+'\nTeams: '+value.redCount+'v'+value.blueCount+'\nScore: '+value.redScore+':'+value.blueScore+'"></div>'); | |
} | |
}); | |
GM_addStyle('#CS_TL_Outer { position:relative; margin:0 6px 0 20px; padding:16px 0 20px 0; text-align:left; }'); | |
GM_addStyle('#CS_TL { position:absolute; display:inline-block; width:100%; }'); | |
GM_addStyle('#CS_TL_Pre { position:absolute; display:inline-block; left:0px; border-bottom:1px dotted #666; }'); | |
GM_addStyle('#CS_TL_Game { position:absolute; display:inline-block; border-bottom:1px solid #ddd; }'); | |
GM_addStyle('#CS_TL_Post { position:absolute; display:inline-block; border-bottom:1px dashed #a33; }'); | |
GM_addStyle('.CS_TL_CapRed { position:absolute; display:inline-block; margin-top:-2px; width:2px; height:5px; background:#f33 }'); | |
GM_addStyle('.CS_TL_CapBlue { position:absolute; display:inline-block; margin-top:-2px; width:2px; height:5px; background:deepskyblue }'); | |
GM_addStyle('.CS_TL_Left_Red { position:absolute; display:inline-block; margin-top:-4px; width:1px; height:2px; background:#ff65f2 }'); | |
GM_addStyle('.CS_TL_Joined_Red { position:absolute; display:inline-block; margin-top:-4px; width:1px; height:2px; background:limegreen }'); | |
GM_addStyle('.CS_TL_Switched_Red { position:absolute; display:inline-block; margin-top:-4px; width:1px; height:2px; background:yellow }'); | |
GM_addStyle('.CS_TL_Left_Blue { position:absolute; display:inline-block; margin-top:3px; width:1px; height:2px; background:#ff65f2 }'); | |
GM_addStyle('.CS_TL_Joined_Blue { position:absolute; display:inline-block; margin-top:3px; width:1px; height:2px; background:limegreen }'); | |
GM_addStyle('.CS_TL_Switched_Blue { position:absolute; display:inline-block; margin-top:3px; width:1px; height:2px; background:yellow }'); | |
GM_addStyle('#CS_TL_RedLabel { position:absolute; display:inline-block; width:16px; height:17px; text-align:center; color:#f33; font:14px Arial; margin:-17px -18px; cursor:default; }'); | |
GM_addStyle('#CS_TL_BlueLabel { position:absolute; display:inline-block; width:16px; height:17px; text-align:center; color:deepskyblue; font:14px Arial; margin:2px -18px; cursor:default; }'); | |
GM_addStyle('.CS_TL_MyTeam { border:1px dashed #fff; border-radius:50%; }'); | |
GM_addStyle('.CS_TL_MyTeamWin { border:1px dashed #0d0; border-radius:50%; }'); | |
GM_addStyle('.CS_TL_MyTeamLoss { border:1px dashed #e00; border-radius:50%; }'); | |
} | |
} | |
setTimeout(function() { | |
window.requestAnimationFrame(function() { | |
$CS_ChatHistory_Container.animate({scrollTop: $CS_ChatHistory_Container.get(0).scrollHeight}, 500); | |
}); | |
}, 600); | |
} | |
} | |
if (showLastGameOnHome && PageLoc === 'server') { | |
showLastGameLog(); | |
showSummary(); | |
} else if (showLastGameOnJoiner && PageLoc === 'joining') { | |
showLastGameLog(); | |
showSummary(); | |
} else if (PageLoc === 'ingame') { | |
var joinTime; | |
var gameData = {}; | |
var mapName='', mapAuthor='', mapType=''; | |
var pupsCount = 0; | |
var escape = document.createElement('textarea'); | |
var allCaps = []; | |
var teamCounts = { Red:0, Blue:0 }; | |
var jqUI_CssSrc = GM_getResourceText("jqUI_CSS"); //so we can drag/resize the chat window | |
GM_addStyle(jqUI_CssSrc); | |
var updateChatHistory = function(from, message, to, c, mod) { | |
var playerId = null; | |
var playerName = ''; | |
var playerAuth = false; | |
var showTimer = showTime; | |
var name = ''; | |
var playerColor = '#ffffff', messageColor = '#ffffff'; | |
var timerText = '--:--'; | |
var messageStyle = ''; | |
if (!message) return; | |
if (/[<>&"]/.test(message)) { | |
escape.textContent = message; | |
message = escape.innerHTML; | |
} | |
message = linkify(message); | |
if ((tagpro.ui.sprites.hasOwnProperty('timer')) && (tagpro.ui.sprites.timer.hasOwnProperty('_text'))) { | |
timerText = tagpro.ui.sprites.timer.text; | |
if (timerText.includes(':-')) timerText = '00:00'; //timer has gone into negatives (after end of game) | |
} | |
if ($.isNumeric(from)) { | |
playerId = from; | |
playerName = tagpro.players[from].name; | |
if (tagpro.players[from].auth && showPlayerAuthTick) playerAuth = true; | |
if (tagpro.players[from].team === 1) playerColor = redTextColor; | |
else playerColor = blueTextColor; | |
if (to === 'team') { | |
if (tagpro.players[from].team === 1) messageColor = redTextColor; | |
else messageColor = blueTextColor; | |
} | |
} else if ($.type(from) === 'string') { | |
playerName = from; | |
playerColor = '#e7e700'; | |
messageColor = '#e7e700'; | |
} else if (from === null) { | |
var hasLeft = message.indexOf('has left the '); | |
var hasJoined = message.indexOf('has joined the'); | |
var hasSwitched = message.indexOf('has switched to'); | |
var teamColor = 'Red'; | |
messageStyle = '; font-style:italic'; | |
if (hasLeft >= 0 || hasJoined >= 0 || hasSwitched >= 0) { | |
if (message.indexOf('Blue') > 10) teamColor = 'Blue'; | |
if (hasLeft >= 0) { | |
name = message.substr(1, hasLeft - 3); | |
message = message.replace(teamColor, '<span class="CS_Underline">'+teamColor+'</span>').replace(name, '<span class="CS_Underline">'+name+'</span>').replace('left', '<span class="CS_Underline">left</span>'); | |
teamCounts[teamColor]--; | |
} else if (hasJoined >= 0) { | |
name = message.substr(1, hasJoined - 3); | |
message = message.replace(teamColor, '<span class="CS_Underline">'+teamColor+'</span>').replace(name, '<span class="CS_Underline">'+name+'</span>').replace('joined', '<span class="CS_Underline">joined</span>'); | |
teamCounts[teamColor]++; | |
} else if (hasSwitched >= 0) { | |
name = message.substr(1, hasSwitched - 3); | |
message = message.replace(teamColor, '<span class="CS_Underline">'+teamColor+'</span>').replace(name, '<span class="CS_Underline">'+name+'</span>').replace('switched', '<span class="CS_Underline">switched</span>'); | |
teamCounts[teamColor]++; | |
if (teamColor === 'Red') teamCounts.Blue--; | |
else teamCounts.Red--; | |
} | |
if ((tagpro.state === 1)) { // || (tagpro.state === 3) | |
if ((teamCounts.Red < 1) || (teamCounts.Red > 4) || (teamCounts.Blue < 1) || (teamCounts.Blue > 4)) { //sometimes happens when we join a game | |
getTeamCounts(); | |
} | |
if (showScoreOnJoinLeft) message += ' [' + tagpro.score.r + ':' + tagpro.score.b + ', ' + teamCounts.Red + 'v' + teamCounts.Blue + ']'; | |
if (tagpro.state === 1) { | |
if (playSoundOnJoin && (tagpro.sound || ignoreMuteSoundIcon) && (hasJoined >= 0 || hasSwitched >= 0)) { | |
(new Audio('data:audio/wav;base64,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Xa0lrXnW5iq7oijh0o0xjpZkRk3p/////13/9da9rot9TFf+tH3cz+/2oSRPc6GMjVRsur6ndEKPz5oZmQAAd6cAmAPdWwd4dwZWiYw9IQAgb+JfmbJ4uWttS5KlcqGaZbP///0yv//3oRlLYpUu7JhkUP/7gMTogBYuQRnuCNuh5sYkPA4JLZuj0VqornMV9VNO76uORLnq1iojbf/////r6bU6zNstVRCz+u2lvSXZlU6IzS7zC7UKRWRrozWbshSiSRfoRdmVAAAGoAWAOBGge8h9tFX2WVGSZhtwajk7sua6/0ttCQRTf//9cF////q7ciuqOZ3c6PSpXozGU5SkY+ik87F90e6TI//////9XdDGZLqy2KkwtZlkc2jmexkc7o7OyaNWynnRTEOpZSKjaGK7MYg7qp7sax1KwJlxDMwAFTdgUyBx/YHrPm4YZWnIW7MAOrtwEPgzoNxpbaZa/UttN////0//T/v3Yx0e8IDouNWfSw0InhusUOScUDwSmEXu//6K7lEDTTxE6fFQqUb1/7PS3uqShenfoeoACquwCwAAv1D////1nhm/jD0hCz5jHU7sGTQU1WcvdqUyrH/+k971VUUx5iplarGQhLlIYWiikLZlD6OzlImz//tQxP8ADhInI+BsRanXROQ8DYi1lbL//////tsdE6JRzlyESOU+79f78eqtPZ3duAE0BxtoHhTu4xNHztKYOoeM/NrFiTuxqy9y////r//9vX6v32u/U+hksWeZGcMUHU7WBc3FU3f//sofdaDy2i4EBkGf//2dbnouYsWrgagAAJvAWqA4/0D7qVvoreXsAI2pAZBZMscQ1caWrqd2HrL6////r//83ZK5cpEZw52fIjEVyotY4uJAdAjWAsomEiO+r///2QEDqnuIFBEGCP/7YMTpAA8+MR/gbEkpdJblPA0ItP9n+3VqufVflNyWBAACYqgCg9gf9ComxlBC4YgAFBlwcsDBMQdQfOqWr703mOyqz1diMio5TuzSnSVTIdGKjTo7pr0dk0VDbW/////9G+yl+8HZFmDKFIKLt6Ovu3ENegUkUdA9MleLKoiImEABa/2MgAoMZEDBTiMQOB4ADEWuasB7jpoCPLjpOA5CwZf40KIB56gfL3Qh1360OM9QGL7X+uR5V3w0xCUssaOtdgDmLngZdkOrEglx4AgR95G7EVZwaFlED0yCgREnRB0ysQm6M9mZGPuYXTZ72W942PV16aaYusft4+tn9NOOzd8f+v/7UMT1ggttnSnsgFMhPp1lPAyJJO253+f//vuf//vv//fP8//7f43btXY2N+XcN+VvP1RubMfZqMfd2vymOOl+6kKJlmS0SfqXaETEbIokEH7p5CbUxo8yzQG+hLKRAjvfMJa7QrsIAD/6pAAGOzkY5GJlAdiMhGnygY8UICNpicjGZw2Z9TBjUUmeD6IAMYbBgiDZhwKgUzGx4QasO4OHBhMJF8zDAVkF8mEncMmklgryad8HSzfRzMEjesgafNobAiM1Akw6QOdGQQiSAy7/+1DE/YCLiNsp4GhHYW+zZP1ACmRoBAzLEUXwERHQQYKCwMeAgkEqMCAWHpEs8TqYStVaTQlbYHVK7Cxpt+Y9FojPQzRQ1Tw7MQ9Qz0RnYatxmpGqGHpuM0Euq2Ka6LROJPh2nXJyT4ck3lquWruRyt9bWkcJLmKZJ0Wp2r0+VT5WVv/nK9efXn/ubP7HS2motpFRqLPLEtlyMmo5TzVHU852NI5VaCgGAUAwSS9EgYjKOU5qMSRkijjmkdyq9EgEFEQCRmZlGaqnIolJVUxB//ugxP6AGsZBF+xszaSQR+G9zRo8TUUzLjk5LjVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVUxBTUUzLjk5LjVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV//sQxNYDwAAB/gAAACAAADSAAAAEVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVU=')).play(); | |
} else if (playSoundOnLeft && (tagpro.sound || ignoreMuteSoundIcon) && hasLeft >= 0) { | |
(new Audio('data:audio/wav;base64,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')).play(); | |
} | |
} | |
if (showLJSOnTimeline) { | |
var what = ''; | |
if (hasLeft >= 0) what = 'left'; | |
else if (hasJoined >= 0) what = 'joined'; | |
else if (hasSwitched >= 0) what = 'switched'; | |
allCaps.push( { what:what, time:Date.now(), name:name, team:(teamColor==='Red'?1:2), timer:timerText, redScore:tagpro.score.r, blueScore:tagpro.score.b, redCount:teamCounts.Red, blueCount:teamCounts.Blue } ); | |
} | |
} | |
} else { | |
//var joinedAsSpec = message.indexOf('joined a game as a spectator'); | |
var isSaveAttempt = message.startsWith('This is a save attempt!'); | |
var youHaveReported = message.startsWith('You have reported'); | |
var hasVotedYou = message.startsWith('Someone has voted'); | |
var hasBanned = message.includes('(mod) has banned'); | |
var joinedAsSBFromSpec = message.startsWith("Hi! You're currently"); | |
if (isSaveAttempt) { | |
c = '#ff77ff'; | |
} else if ((youHaveReported) || (hasVotedYou) || (hasBanned)) { | |
c = '#ff5599'; | |
} else if (joinedAsSBFromSpec) { | |
let oldTCR = teamCounts.Red; | |
let oldTCB = teamCounts.Blue; | |
getTeamCounts(); //sometimes happens when we join a game from spec (as a sb?) | |
message = 'Was:' + oldTCR + ':' + oldTCB + ' |Now:' + teamCounts.Red + ':' + teamCounts.Blue + ' || ' + message; | |
alert('joined from spec - check player counts!!!'); | |
} else { | |
message = message.replace(/�/g, '\'').trim(); | |
if (hideTimeOnSystemChat) showTimer = false; | |
} | |
} | |
} | |
if (mod) { | |
playerColor = '#00aa00'; | |
messageColor = '#00aa00'; | |
} | |
if (c) { | |
playerColor = c; | |
messageColor = c; | |
} | |
var fadeId = new Date().getTime(); // Ko: we need to be able to identify message after 20 seconds (that's when the message dissapears for 'normal' players) | |
$CS_ChatHistory.append('<div>' + | |
(showTimer ? '<span id='+fadeId+' style="color:'+timeColor+'">'+timerText+' </span>' : '') + // Ko: give the time an id | |
(playerName ? (playerAuth ? '<span class="CS_Auth CS_Font9">✔</span>' : '') + '<span'+(playerId ? ' class="CS_Kickable" data-kickid="'+playerId+'" title="Report '+playerName+'"' : '')+' style="color:'+playerColor+'">'+playerName+'</span>: ' : '') + | |
'<span style="color:'+messageColor+messageStyle+'">'+message + '</span>' + | |
'</div>'); | |
if (fadeTime) setTimeout( function() { document.getElementById(fadeId).style.color= fadeColor; } , 20000); // Ko: Fade the time after 20 seconds | |
//only autoscroll down if we're already at/near the bottom (otherwise user is reading previous chat and autoscroll is painful)... | |
if ($CS_ChatHistory_Container.get(0).scrollTop + 40 > $CS_ChatHistory_Container.get(0).scrollHeight - $CS_ChatHistory_Container.innerHeight()) { | |
window.requestAnimationFrame(function() { | |
$CS_ChatHistory_Container.animate({scrollTop: $CS_ChatHistory_Container.get(0).scrollHeight}, 500); | |
}); | |
} | |
if (playSoundOnMessage && (tagpro.sound || ignoreMuteSoundIcon)) { | |
(new Audio('data:audio/wav;base64,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')).play(); | |
} | |
GM_setValue('lastChatLog', $CS_ChatHistory.html()); | |
}; | |
var addToChatHistory = function(message, eog) { //this is used to add other messages to the chat history (like caps) | |
var timerText = '--:--'; | |
if ((tagpro.ui.sprites.hasOwnProperty('timer')) && (tagpro.ui.sprites.timer.hasOwnProperty('_text'))) { | |
timerText = tagpro.ui.sprites.timer.text; | |
if (timerText.includes(':-')) timerText = '00:00'; //timer has gone into negatives (after end of game) | |
} | |
var fadeId = new Date().getTime(); // Ko: we need to be able to identify message after 20 seconds (that's when the message dissapears for 'normal' players) | |
$CS_ChatHistory.append('<div'+(eog ? ' id="CS_EOG" style="border-top:1px solid white; border-bottom:1px solid white"' : '')+'>' + | |
(showTime ? '<span id='+fadeId+' style="color:'+timeColor+'">'+timerText+' </span>' : '') + // Ko: add the id to the time | |
message + | |
'</div>'); | |
if (fadeTime) setTimeout( function() { document.getElementById(fadeId).style.color= fadeColor; } , 20000); // Ko: Fade the time after 20 seconds | |
window.requestAnimationFrame(function() { | |
$CS_ChatHistory_Container.animate({scrollTop: $CS_ChatHistory_Container.get(0).scrollHeight}, 500); | |
}); | |
GM_setValue('lastChatLog', $CS_ChatHistory.html()); | |
}; | |
var friendlyGrabTime = 0; | |
var enemyGrabTime = 0; | |
var grabCheckFlagsDelay = 120; | |
var redHolder = 0; | |
var blueHolder = 0; | |
var whoHasFlags = function() { | |
redHolder=0; | |
blueHolder=0; | |
for (var playerId in tagpro.players) { | |
if (tagpro.players.hasOwnProperty(playerId)) { | |
if (tagpro.players[playerId].flag === 1) { | |
blueHolder = Number(playerId); | |
} else if (tagpro.players[playerId].flag === 2) { | |
redHolder = Number(playerId); | |
} else if (tagpro.players[playerId].flag === 3) { | |
if (tagpro.players[playerId].team === 1) { | |
redHolder = Number(playerId); | |
} else { | |
blueHolder = Number(playerId); | |
} | |
} | |
} | |
} | |
}; | |
var getPlayerCaps = function() { | |
var playerCaps = {}; | |
for (var playerId in tagpro.players) { | |
if (tagpro.players.hasOwnProperty(playerId)) { | |
playerCaps[playerId] = { caps:tagpro.players[playerId]['s-captures'], team:tagpro.players[playerId].team, name:tagpro.players[playerId].name }; | |
} | |
} | |
return playerCaps; | |
}; | |
var getTeamCounts = function() { | |
teamCounts.Red = 0; | |
teamCounts.Blue = 0; | |
for (var playerId in tagpro.players) { | |
if (tagpro.players.hasOwnProperty(playerId)) { | |
if (tagpro.players[playerId].team === 1) teamCounts.Red++; | |
else teamCounts.Blue++; | |
} | |
} | |
}; | |
if (tagpro.group.socket !== null) { //save all group chat events (if we're in a group)... | |
tagpro.group.socket.on('chat', function(data) { | |
updateChatHistory(data.from, data.message, data.to, null, null); | |
}); | |
} | |
tagpro.socket.on('chat', function(data) { //save all regular chat events... | |
updateChatHistory(data.from, data.message, data.to, data.c, data.mod); | |
}); | |
tagpro.socket.on('spectator', function(spectator) { | |
if (!spectator) { | |
joinTime = Date.now(); | |
} | |
}); | |
tagpro.socket.on('time', function(message) { | |
if (tagpro.state === 3) { //before the actual start | |
joinTime = Date.now(); | |
} else if (tagpro.state === 1) { //game has started | |
if (joinTime) { | |
joinTime = Date.parse(tagpro.gameEndsAt) - 720000; | |
} else { | |
joinTime = Date.now(); | |
whoHasFlags(); | |
} | |
setTimeout(function() { | |
getTeamCounts(); | |
}, 200); | |
} | |
}); | |
tagpro.socket.on('map', function(data) { | |
if (hideNormalChat) $('#chatHistory').hide(0); | |
mapName = data.info.name; | |
mapAuthor = data.info.author; | |
for (var i=0; i<tagpro.map.length; i++) { //find the flags which will tell us if it's a CTF or NF map... | |
for (var j=0; j<tagpro.map[i].length; j++) { | |
if (tagpro.map[i][j] == 16 || (tagpro.map[i][j] == 16.1)) { //yellow flag found | |
mapType = 'NF'; | |
} else if ((tagpro.map[i][j] == 3) || (tagpro.map[i][j] == 3.1) || (tagpro.map[i][j] == 4) || (tagpro.map[i][j] == 4.1)) { //red or blue flag found | |
mapType = 'CTF'; | |
} | |
} | |
} | |
GM_deleteValue('lastChatLog'); | |
GM_deleteValue('gameData'); | |
$CS_ChatHistory_Container.resizable({ | |
delay: 50, | |
distance: 3, | |
containment: 'document', | |
handles: 'n, e, s, w, ne, se, sw, nw', | |
resize: function(event, ui) { | |
$CS_ChatHistory_Container.css('border', '1px dashed white'); | |
}, | |
stop: function(event, ui) { | |
GM_setValue('size', {'width':ui.size.width, 'height':ui.size.height}); | |
GM_setValue('position', {'top':ui.position.top, 'left':ui.position.left}); | |
if (!showBorder) $CS_ChatHistory_Container.css('border', 'none'); | |
$CS_ChatHistory_Container.css('background', defaultBorder); | |
} | |
}); | |
$CS_ChatHistory_Container.draggable({ | |
delay: 50, | |
containment: 'window', | |
scroll: false, | |
drag: function(event, ui) { | |
$CS_ChatHistory_Container.css('border', '1px dashed white'); | |
}, | |
stop: function(event, ui) { | |
GM_setValue('position', {'top':ui.position.top, 'left':ui.position.left}); | |
if (!showBorder) $CS_ChatHistory_Container.css('border', 'none'); | |
$CS_ChatHistory_Container.css('background', defaultBorder); | |
} | |
}); | |
$CS_ChatHistory.on('click', '.CS_Kickable', function() { | |
tagpro.kick.player( tagpro.players[$(this).data('kickid')] ); | |
}); | |
GM_addStyle('.CS_Kickable:hover { text-decoration:underline; cursor:pointer; }'); | |
}); | |
if (showCaps) { | |
tagpro.socket.on('sound', function(data) { | |
var capTime, capperId, capperColor, capMessage; | |
var playerCaps; | |
var timerText = ''; | |
var holdTime; | |
grabCheckFlagsDelay = tagpro.ping.avg + 30; | |
if (isNaN(grabCheckFlagsDelay) || grabCheckFlagsDelay <= 80) grabCheckFlagsDelay = 80; | |
//Friendly Grab... | |
if ((data.s === 'friendlyalert') && (data.hasOwnProperty('v'))) { | |
friendlyGrabTime = Date.now(); | |
whoHasFlags(); | |
//Enemy Grab... | |
} else if ((data.s === 'alert') && (data.hasOwnProperty('v'))) { | |
enemyGrabTime = Date.now(); | |
whoHasFlags(); | |
//Friendly Cap... | |
} else if (data.s === 'cheering') { | |
capTime = Date.now(); | |
playerCaps = getPlayerCaps(); | |
setTimeout(function(friendlyGrabTime) { | |
var done = false; | |
for (var playerId in tagpro.players) { | |
if (tagpro.players.hasOwnProperty(playerId) && playerCaps.hasOwnProperty(playerId)) { | |
if (tagpro.players[playerId]['s-captures'] === playerCaps[playerId].caps + 1) { | |
playerCaps[playerId].caps++; | |
capperId = playerId; | |
if (tagpro.players[playerId].team === 1) capperColor = redTextColor; | |
else capperColor = blueTextColor; | |
done = true; | |
break; | |
} | |
} | |
} | |
if (!done) { | |
if (tagpro.players[tagpro.playerId].team === 1) { | |
capperId = redHolder; | |
capperColor = redTextColor; | |
} else { | |
capperId = blueHolder; | |
capperColor = blueTextColor; | |
} | |
if (capperId) { | |
addToChatHistory('<span style="color:#9A5">FRIENDLY -- NOT DONE: ' + playerCaps[capperId].name + ' |caps:' + playerCaps[capperId].caps + '</span>'); | |
playerCaps[capperId].caps++; | |
} | |
} | |
if ((tagpro.ui.sprites.hasOwnProperty('timer')) && (tagpro.ui.sprites.timer.hasOwnProperty('_text'))) timerText = tagpro.ui.sprites.timer.text; | |
if (capperId) { | |
//if (tagpro.players[capperId]['s-captures'] === 0) addToChatHistory('<span style="color:#B0B">0th! </span><span style="color:'+capperColor+'">' + tagpro.players[capperId].name + ' (' + ordinal_suffix_of(tagpro.players[capperId]['s-captures']) + ', ' + (friendlyGrabTime ? '<span title="Hold Time">'+secondsToHMS((capTime-friendlyGrabTime)/1000)+'</span>, ' : '') + tagpro.score.r + ':' + tagpro.score.b + ', ' + teamCounts.Red+'v'+teamCounts.Blue + ')</span>'); | |
addToChatHistory('<span class="CS_Cap">CAP!</span><span style="color:'+capperColor+'">' + tagpro.players[capperId].name + ' (' + ordinal_suffix_of(playerCaps[capperId].caps||1) + ', ' + (friendlyGrabTime ? '<span title="Hold Time">'+secondsToHMS((capTime-friendlyGrabTime)/1000)+'</span>, ' : '') + tagpro.score.r + ':' + tagpro.score.b + ', ' + teamCounts.Red+'v'+teamCounts.Blue + ')</span>'); | |
holdTime = secondsToHMS((capTime-friendlyGrabTime)/1000); | |
allCaps.push( { what:'cap', time:capTime, id:capperId, name:tagpro.players[capperId].name, team:tagpro.players[capperId].team, holdTime:holdTime, timer:timerText, redScore:tagpro.score.r, blueScore:tagpro.score.b, redCount:teamCounts.Red, blueCount:teamCounts.Blue } ); | |
} else { | |
addToChatHistory('<span class="CS_Cap">CAP!</span><span style="color:'+(tagpro.players[tagpro.playerId].team === 1 ? redTextColor : blueTextColor)+'">Unknown (' + (friendlyGrabTime ? '<span title="Hold Time">'+secondsToHMS((capTime-friendlyGrabTime)/1000)+'</span>, ' : '') + tagpro.score.r + ':' + tagpro.score.b + ', ' + teamCounts.Red+'v'+teamCounts.Blue + ')</span>'); | |
allCaps.push( { what:'cap', time:capTime, id:0, name:'Unknown', team:(tagpro.players[tagpro.playerId].team === 1 ? 1 : 2), holdTime:0, timer:'', redScore:tagpro.score.r, blueScore:tagpro.score.b, redCount:teamCounts.Red, blueCount:teamCounts.Blue } ); | |
} | |
whoHasFlags(); | |
}, 200, friendlyGrabTime); | |
//Enemy Cap... | |
} else if (data.s === 'sigh') { | |
capTime = Date.now(); | |
playerCaps = getPlayerCaps(); | |
setTimeout(function(enemyGrabTime) { | |
var done = false; | |
for (var playerId in tagpro.players) { | |
if (tagpro.players.hasOwnProperty(playerId) && playerCaps.hasOwnProperty(playerId)) { | |
if (tagpro.players[playerId]['s-captures'] === playerCaps[playerId].caps + 1) { | |
playerCaps[playerId].caps++; | |
capperId = playerId; | |
if (tagpro.players[playerId].team === 1) capperColor = redTextColor; | |
else capperColor = blueTextColor; | |
done = true; | |
break; | |
} | |
} | |
} | |
if (!done) { | |
if (tagpro.players[tagpro.playerId].team === 1) { | |
capperId = blueHolder; | |
capperColor = blueTextColor; | |
} else { | |
capperId = redHolder; | |
capperColor = redTextColor; | |
} | |
if (capperId) { | |
addToChatHistory('<span style="color:#9A5">ENEMY -- NOT DONE: ' + playerCaps[capperId].name + ' |caps:' + playerCaps[capperId].caps + '</span>'); | |
playerCaps[capperId].caps++; | |
} | |
} | |
if ((tagpro.ui.sprites.hasOwnProperty('timer')) && (tagpro.ui.sprites.timer.hasOwnProperty('_text'))) timerText = tagpro.ui.sprites.timer.text; | |
if (capperId) { | |
//if (tagpro.players[capperId]['s-captures'] === 0) addToChatHistory('<span style="color:#B0B">0th! </span><span style="color:'+capperColor+'">' + tagpro.players[capperId].name + ' (' + ordinal_suffix_of(tagpro.players[capperId]['s-captures']) + ', ' + (enemyGrabTime ? '<span title="Hold Time">'+secondsToHMS((capTime-enemyGrabTime)/1000)+'</span>, ' : '') + tagpro.score.r + ':' + tagpro.score.b + ', ' + teamCounts.Red+'v'+teamCounts.Blue + ')</span>'); | |
addToChatHistory('<span class="CS_Cap">CAP!</span><span style="color:'+capperColor+'">' + (tagpro.players[capperId].name) + ' (' + ordinal_suffix_of(playerCaps[capperId].caps||1) + ', ' + (enemyGrabTime ? '<span title="Hold Time">'+secondsToHMS((capTime-enemyGrabTime)/1000)+'</span>, ' : '') + tagpro.score.r + ':' + tagpro.score.b + ', ' + teamCounts.Red+'v'+teamCounts.Blue + ')</span>'); | |
holdTime = secondsToHMS((capTime-enemyGrabTime)/1000); | |
allCaps.push( { what:'cap', time:capTime, id:capperId, name:tagpro.players[capperId].name, team:tagpro.players[capperId].team, holdTime:holdTime, timer:timerText, redScore:tagpro.score.r, blueScore:tagpro.score.b, redCount:teamCounts.Red, blueCount:teamCounts.Blue } ); | |
} else { | |
addToChatHistory('<span class="CS_Cap">CAP!</span><span style="color:'+(tagpro.players[tagpro.playerId].team === 1 ? blueTextColor : redTextColor)+'">Unknown (' + (enemyGrabTime ? '<span title="Hold Time">'+secondsToHMS((capTime-enemyGrabTime)/1000)+'</span>, ' : '') + tagpro.score.r + ':' + tagpro.score.b + ', ' + teamCounts.Red+'v'+teamCounts.Blue + ')</span>'); | |
allCaps.push( { what:'cap', time:capTime, id:0, name:'Unknown', team:(tagpro.players[tagpro.playerId].team === 1 ? 2 : 1), holdTime:0, timer:'', redScore:tagpro.score.r, blueScore:tagpro.score.b, redCount:teamCounts.Red, blueCount:teamCounts.Blue } ); | |
} | |
whoHasFlags(); | |
}, 200, enemyGrabTime); | |
} | |
}); | |
} | |
tagpro.socket.on('end', function(data) { | |
var fullTime = Date.parse(tagpro.gameEndsAt); //expected end of game time after 12 mins | |
var endTime = Date.now(); //actual end of game time | |
var startTime = fullTime - 12 * 60 * 1000; //start of game time | |
var fullGameLength = (endTime-startTime)/1000; //how long the whole game lasted (with or without us) | |
if (fullGameLength > 720) fullGameLength = 720; | |
var playedGameLength = (endTime-joinTime)/1000; //how long we played for | |
var capTrickMessage = ''; | |
var eogMessage = ''; | |
var playerId; | |
//GM_deleteValue('lastChatLog'); | |
//GM_deleteValue('gameData'); | |
gameData.mapName = mapName; | |
gameData.mapAuthor = mapAuthor; | |
gameData.gameMode = mapType; | |
gameData.played = new Date(joinTime).toISOString(); | |
gameData.timePlayed = playedGameLength; | |
gameData.fullGameLength = fullGameLength; | |
gameData.spectator = (tagpro.spectator ? tagpro.players[tagpro.playerId].name : false); | |
gameData.spectatorTeam = (tagpro.spectator ? tagpro.players[tagpro.playerId].team : false); | |
if (tagpro.serverHost === null) tagpro.serverHost = document.URL.replace('http://', '').replace(/:(.*)/, ''); | |
if (tagpro.serverHost.startsWith('tagpro-')) { | |
gameData.serverName = capitaliseFirstLetter(tagpro.serverHost.replace('tagpro-', '').replace('.koalabeast.com', '')); | |
} else { | |
gameData.serverName = document.URL; | |
} | |
//save scoreboard... | |
gameData.playersData = []; | |
for (playerId in tagpro.players) { | |
gameData.playersData.push({ | |
name:tagpro.players[playerId].name, | |
id:tagpro.players[playerId].id, | |
team:tagpro.players[playerId].team, | |
auth:tagpro.players[playerId].auth, | |
self:(tagpro.playerId === tagpro.players[playerId].id && !tagpro.spectator ? true : false), | |
tags:tagpro.players[playerId]["s-tags"], | |
pops:tagpro.players[playerId]["s-pops"], | |
grabs:tagpro.players[playerId]["s-grabs"], | |
drops:tagpro.players[playerId]["s-drops"], | |
hold:tagpro.players[playerId]["s-hold"], | |
captures:tagpro.players[playerId]["s-captures"], | |
prevent:tagpro.players[playerId]["s-prevent"], | |
returns:tagpro.players[playerId]["s-returns"], | |
support:tagpro.players[playerId]["s-support"], | |
powerups:tagpro.players[playerId]["s-powerups"], | |
score:tagpro.players[playerId].score, | |
points:tagpro.players[playerId].points | |
}); | |
} | |
gameData.playersData.sort(function(a, b) { | |
return (b.score - a.score ? b.score - a.score : a.id - b.id); | |
}); | |
gameData.allCaps = allCaps; | |
//Look for Cap-Tricks... | |
for (playerId in tagpro.players) { | |
if (tagpro.players[playerId]['s-captures'] >= 3) capTrickMessage = 'CapTrick ('+tagpro.players[playerId]['s-captures']+' caps!) by ' + tagpro.players[playerId].name; | |
} | |
setTimeout(function() { | |
if (tagpro.score.r > tagpro.score.b) { | |
if (tagpro.players[tagpro.playerId].team === 1) { | |
eogMessage += '<span style="color:limegreen">End of Game | Score ' + tagpro.score.r + ':' + tagpro.score.b + (tagpro.spectator ? ' | Red Won (Spec 👀)' : ' | We (Red) Won!</span>'); | |
} else { | |
eogMessage += '<span style="color:#f33">End of Game | Score ' + tagpro.score.r + ':' + tagpro.score.b + (tagpro.spectator ? ' | Red Won (Spec 👀)' : ' | We (Blue) Lost :(</span>'); | |
} | |
} else if (tagpro.score.r < tagpro.score.b) { | |
if (tagpro.players[tagpro.playerId].team === 1) { | |
eogMessage += '<span style="color:#f33">End of Game | Score ' + tagpro.score.r + ':' + tagpro.score.b + (tagpro.spectator ? ' | Blue Won (Spec 👀)' : ' | We (Red) Lost :(</span>'); | |
} else { | |
eogMessage += '<span style="color:limegreen">End of Game | Score ' + tagpro.score.r + ':' + tagpro.score.b + (tagpro.spectator ? ' | Blue Won (Spec 👀)' : ' | We (Blue) Won!</span>'); | |
} | |
} else if (tagpro.score.r === tagpro.score.b) { | |
if (tagpro.players[tagpro.playerId].team === 1) { | |
eogMessage += '<span style="color:cadetblue">End of Game | Score ' + tagpro.score.r + ':' + tagpro.score.b + (tagpro.spectator ? ' | Tie! (Spec 👀)' : ' | Tie! We were on Red</span>'); | |
} else { | |
eogMessage += '<span style="color:cadetblue">End of Game | Score ' + tagpro.score.r + ':' + tagpro.score.b + (tagpro.spectator ? ' | Tie! (Spec 👀)' : ' | Tie! We were on Blue</span>'); | |
} | |
} | |
gameData.eogMessage = eogMessage; | |
var result = '', resultText = ''; | |
if (data.winner === 'tie') { | |
result = 'Tie'; | |
resultText = 'Tie!' + (tagpro.players[tagpro.playerId].team === 1 ? ' We were on Red' : ' We were on Blue'); | |
} else if ((data.winner === 'red') && (tagpro.players[tagpro.playerId].team === 1)) { | |
result = 'Win'; | |
resultText = 'We (Red) Won!'; | |
} else if ((data.winner === 'red') && (tagpro.players[tagpro.playerId].team === 2)) { | |
result = 'Loss'; | |
resultText = 'We (Blue) Lost'; | |
} else if ((data.winner === 'blue') && (tagpro.players[tagpro.playerId].team === 1)) { | |
result = 'Loss'; | |
resultText = 'We (Red) Lost'; | |
} else if ((data.winner === 'blue') && (tagpro.players[tagpro.playerId].team === 2)) { | |
result = 'Win'; | |
resultText = 'We (Blue) Won!'; | |
} | |
gameData.result = result; | |
gameData.redScore = tagpro.score.r; | |
gameData.blueScore = tagpro.score.b; | |
gameData.team = tagpro.players[tagpro.playerId].team; | |
GM_setValue('gameData', gameData); | |
if (capTrickMessage) eogMessage += '<div style="text-align:center; background:#0c0; color:white; width:90%; margin:2px auto; border-radius:5px;">' + capTrickMessage + '</div>'; | |
addToChatHistory(eogMessage, true); | |
showSummary(); | |
}, 250); | |
}); | |
} | |
}); | |
//helper functions... | |
function secondsToHMS(d) { | |
d = Number(d); | |
var h = Math.floor(d / 3600); | |
var m = Math.floor(d % 3600 / 60); | |
var s = Math.floor(d % 3600 % 60); | |
return ((h > 0 ? h + ":" : "") + (m > 0 ? (h > 0 && m < 10 ? "0" : "") + m + ":" : "0:") + (s < 10 ? "0" : "") + s); | |
} | |
function ordinal_suffix_of(i) { | |
var j = i % 10, k = i % 100; | |
if (j == 1 && k != 11) return i + "st"; | |
if (j == 2 && k != 12) return i + "nd"; | |
if (j == 3 && k != 13) return i + "rd"; | |
return i + "th"; | |
} | |
function capitaliseFirstLetter(string) { | |
return string.charAt(0).toUpperCase() + string.slice(1); | |
} | |
function linkify(string) { | |
var urlPattern = /\b(?:https?|ftp):\/\/[a-z0-9-+&@#\/%?=~_|!:,.;]*[a-z0-9-+&@#\/%=~_|]/gim; | |
var pseudoUrlPattern = /(^|[^\/])(www\.[\S]+(\b|$))/gim; | |
var emailAddressPattern = /[\w.]+@[a-zA-Z_-]+?(?:\.[a-zA-Z]{2,6})+/gim; | |
return string | |
.replace(urlPattern, '<a href="$&" class="CS_Link" target="_blank">$&</a>') | |
.replace(pseudoUrlPattern, '$1<a href="http://$2" class="CS_Link" target="_blank">$2</a>') | |
.replace(emailAddressPattern, '<a href="mailto:$&" class="CS_Link">$&</a>'); | |
} | |
function WhichPageAreWeOn() { | |
if (window.location.port) { //In a real game | |
return('ingame'); | |
} else if (document.URL.includes('/games/find')) { //Joining page | |
return('joining'); | |
} else if ($('#userscript-home').length) { //Chosen server homepage | |
return('server'); | |
} else if (document.URL.includes('/profile/')) { | |
if ($('#saveSettings').length) { | |
return('profile'); //Profile page and logged in | |
} else { | |
return('profileNotOurs'); //Profile page, but not our one (or we're logged out) | |
} | |
} else if (document.URL.includes('/groups')) { | |
return('groups'); | |
} else if (document.URL.includes('/boards')) { | |
return('boards'); | |
} else if (document.URL.includes('/maps')) { | |
return('maps'); | |
} else if (document.URL.includes('/settings')) { | |
return('settings'); | |
} | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment