Last active
December 11, 2016 02:51
-
-
Save dot-mike/7a0d80c459f94dcd3d63b12f885d0f96 to your computer and use it in GitHub Desktop.
This file contains hidden or 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
/** | |
* Advanced Scoreboard | |
* | |
* @author Cr1N | |
* @version 1.0.1 | |
*/ | |
BBLog.handle("add.plugin", { | |
/* Plugin Infos */ | |
id : "bf4-advanced-scoreboard-plugin-dev-1-0", | |
name : "Advanced Scoreboard", | |
version : '1.0', | |
build: '20141216', | |
/* Plugin load */ | |
init : function(instance) | |
{ | |
//Store the path at initizliation | |
instance.data.currentPath = location.pathname; | |
instance.debug("Plugin Initialized on path " + location.pathname); | |
if ( location.pathname.match(new RegExp("^/bf4/(|[a-z]{2}/)(servers|serverbrowserwarsaw)/show/pc/.*","i")) ) | |
{ | |
instance.debug("Server paged detected, initializing main handler"); | |
instance.handler(instance); | |
} | |
}, | |
domchange : function(instance) { | |
if( location.pathname !== instance.data.currentPath ) | |
{ | |
instance.debug("Changed path from " + instance.data.currentPath + ' to ' + location.pathname); | |
if( instance.data.pluginLoaded ) | |
{ | |
instance.debug("Calling plugin unload func"); | |
instance.unloadPlugin(instance); //URL has changed, unload the plugin. | |
} | |
instance.data.currentPath = location.pathname; | |
console.log("Path Changed: " + location.pathname); | |
if( location.pathname.match(new RegExp("^/bf4/(|[a-z]{2}/)(servers|serverbrowserwarsaw)/show/pc/.*","i")) ) | |
{ | |
instance.debug("Calling main handler"); | |
$(document).ready(function() | |
{ | |
instance.handler(instance); | |
}) | |
} | |
} else { | |
console.log("Path did not change on domchange"); | |
$(document).ready(function () { | |
if (instance.data.pluginLoaded && $("#live-header").is(":visible")) { | |
console.log("Plugin is loaded though, scoreboard not initialised..."); | |
instance.unloadPlugin(instance); //URL has changed, unload the plugin. | |
instance.handler(instance); | |
} | |
}) | |
} | |
}, | |
data: { | |
advancedViewPlayer : 0, //Persona ID of player to show advanced statistics for | |
animationActive : false, | |
asLiveUpdate : false, | |
asTrackerUpdate : false, | |
charts : {"skillDistribution" : false, "tickets" : false,}, | |
currentChart : false, | |
currentPath : '', | |
drawMode: "player", | |
gameServerWarsaw : gamedatawarsaw.function_warsawgameserver(), | |
latestScoreboardData: {}, //Holds the most recently retrieved set of scoreboard data to present unneccessary requests | |
mode: 'scoreboard', //Mode of the plugin | |
onServerPage : false, | |
pluginLoaded: false, | |
tracker : {"tickets" : {}, "kills" : {},}, //Track various aspects of the round over time | |
updateIntervalMs : 5000, | |
}, | |
//Holds player statistics | |
playerStats : {}, | |
translations: | |
{ | |
"en": | |
{ | |
"settings-title" : "Settings", | |
}, | |
"de": | |
{ | |
"settings-title" : "Einstellungen", | |
} | |
}, | |
/* Main handler */ | |
handler : function(instance) { | |
instance.debug("Handler Executed"); | |
console.log(Surface.globalContext); | |
//Clear any previous tickers | |
instance.data.asLiveUpdate = false; | |
instance.data.pluginLoaded = true; | |
//Check if this is the first plugin return | |
//instance.storage('isConfigured', false); | |
if(!instance.storage('isConfigured')) { //If not run before, this will return false | |
instance.debug('Initial setup!') | |
instance.storage('hilightingEnabled', true); | |
instance.storage('liveEnabled', true); | |
instance.storage('displayStat', 'kdRatio'); | |
instance.storage('isConfigured', true); | |
instance.storage('hilightFriends', true); | |
instance.storage('liveTracking', false); | |
instance.storage('sortAttribute', "score"); | |
instance.storage('sortMode', "desc"); | |
instance.storage('useResetKdr', false); | |
instance.storage('pollingIntervalMs', 5000); | |
alert("Configuration Parameters Successfully Set"); | |
} | |
//Charting is disabled in this version... | |
///Add the custom css | |
//$('head').append('<link rel="stylesheet" href="http://indiangamingleagues.com/i242clan/blog_plugin/main/c3.css" type="text/css" />'); | |
$('head').append('<link rel="stylesheet" href="https://aa9de85e6af703e53a9804a161a1197964182874.googledrive.com/host/0Bx16wo_LcoPLfkw3a3R4bmNOMEdyQzlqN0c2N3VBVUJLak5GSnVmRERFUk9VeXplUFlLZ0E/advanced_scoreboard.css" type="text/css" />'); | |
//Load charting library - disabled | |
/* | |
$.ajax({ | |
url: 'http://indiangamingleagues.com/i242clan/blog_plugin/main/d3.min.js', | |
success: instance.debug("Loaded D3"), | |
dataType: "script", | |
cache: true | |
}); | |
$.ajax({ | |
url: 'http://indiangamingleagues.com/i242clan/blog_plugin/main/c3.min.js', | |
success: instance.debug("Loaded C3"), | |
dataType: "script", | |
cache: true | |
}); | |
*/ | |
//Load items library from battlelog if not present | |
if (!window.items) { | |
instance.debug("Loading items library") | |
var path = "/public/gamedatawarsaw/warsaw.items.js"; | |
var loadedLib = $.ajax( | |
{ | |
type: "GET", | |
dataType: "script", | |
url: base.asset(path), | |
cache: true | |
}); | |
} else { | |
instance.debug("Items Library already present!") | |
} | |
//Hide the server info | |
//$("#server-page-details div").hide(); | |
//Hide the default scoreboard and insert wrapper DIV for custom scoreboard | |
$("#server-players-list").hide(); | |
$("#serverbrowser-page").after('<div id="as-container"></div>'); | |
var roundInfoHeader = instance.drawRoundInfo(instance); | |
$("#as-container").html(roundInfoHeader); | |
var selectors = instance.drawSelectors(instance); | |
$("#as-container").append(selectors); | |
$("#as-container").append('<div id="as-scoreboard-container"></div>'); | |
console.log("Okay, instance.storage"); | |
var settingsLog = "Current configuration:<br /><br/>"; | |
settingsLog += 'Hilighting : ' + instance.storage('hilightingEnabled') + "<br/>" + | |
'Live Updates : ' + instance.storage('liveEnabled') + "<br />" + | |
'Displayed Stat : ' + instance.storage('displayStat') + "<br />" + | |
'Live Tracking : ' + instance.storage('liveTracking') + "<br />" + | |
'Sorting Attribute : ' + instance.storage('sortAttribute') + "<br />" + | |
'Sorting Mode : ' + instance.storage('sortMode') + "<br />" + | |
'Allow Reset Stats : ' + instance.storage('useResetKdr') + "<br />" + | |
'Configuration flag : ' + instance.storage('isConfigured') + "<br />" + | |
'Tickrate : ' + instance.storage('pollingIntervalMs') + "<br/>"; | |
console.log(BBLog._storage[instance.id + '.pollingIntervalMs']); | |
//Draw settings/config box | |
//instance.renderSettings(instance); | |
//Create scoreboard from data | |
instance.updateAll(instance); | |
//Charting | |
//instance.drawCharts(instance); | |
//Live update interval | |
if (instance.storage('liveEnabled')) { | |
instance.data.asLiveUpdate = setInterval(function () { | |
instance.updateAll(instance); | |
}, 5000); | |
instance.debug("Live update started by main handler") | |
} else { | |
instance.debug("Live update disabled"); | |
} | |
/** EVENT HANDLERS **/ | |
//Scoreboard | |
//Settings | |
//Change player view | |
$("#as-show-squads").click(function () { | |
instance.data.drawMode = "squad"; | |
instance.updateHTML(instance); | |
instance.debug("Switched drawing mode to Squad"); | |
}); | |
//Handler for selector hilighting | |
$(".view-selector").click(function () | |
{ | |
$(".view-selector").removeClass("btn-primary"); | |
$(this).addClass("btn-primary"); | |
}); | |
//Handler for clicking on a player row | |
$("#as-container").on('click', '.as-player', function() | |
{ | |
var personaId = $(this).attr('personaid'); | |
instance.debug("Player row has been clicked: " + personaId); | |
var thisRow = $(this); | |
if($(this).hasClass('as-advanced-stats-selected')) | |
{ | |
instance.data.advancedViewPlayer = false; | |
instance.data.animationActive = true; | |
$(".as-advanced-player-view").slideUp("fast", function() | |
{ | |
$(".as-scoreboard-advanced-stats-row").remove(); | |
$(".as-advanced-stats-selected").removeClass("as-advanced-stats-selected"); | |
instance.data.animationActive = false; | |
}); | |
return; | |
} | |
var existingRows = $(".as-scoreboard-advanced-stats-row"); | |
//Remove all instances | |
if( existingRows.length > 0 ) | |
{ | |
var attRows = $(".as-advanced-stats-selected"); | |
$(".as-advanced-player-view").slideUp("fast", function() | |
{ | |
console.log("Slid up"); | |
existingRows.remove(); | |
attRows.removeClass("as-advanced-stats-selected"); | |
}); | |
instance.data.advancedViewPlayer = personaId; | |
var html = instance.createAdvancedPlayerView(instance, personaId, false); | |
console.log(html); | |
thisRow.addClass('as-advanced-stats-selected').after(html); | |
instance.data.animationActive = true; | |
$(".as-advanced-player-view").slideDown("fast", function() | |
{ | |
instance.data.animationActive = false; | |
}); | |
} else { | |
instance.data.advancedViewPlayer = personaId; | |
var html = instance.createAdvancedPlayerView(instance, personaId, false); | |
$(this).addClass('as-advanced-stats-selected').after(html); | |
instance.data.animationActive = true; | |
$(".as-advanced-player-view").slideDown("fast", function() | |
{ | |
instance.data.animationActive = false; | |
}); | |
} | |
}); | |
//Handler for clicking a role title and expanding the top players | |
$("#as-container").on('click', '.as-role-title-row', function () { | |
console.log("Clicked role title row"); | |
var roleRow = $(this).next("tr").find(".as-role-top-players"); | |
if( roleRow.is(":visible") ) | |
{ | |
roleRow.slideUp("fast"); | |
} else { | |
roleRow.slideDown("fast"); | |
} | |
}); | |
//Handler for clicking the player join button | |
$("#as-container").on('click', '#as-ao-join', function(){ | |
var personaId = $(this).attr('persona-id'); | |
instance.joinPlayer(personaId); | |
}) | |
$("#as-container").on('click', '#as-ao-radar', function() | |
{ | |
if ( $("div.as-ao-confirm").is(":visible")) { | |
return; | |
} | |
var personaId = $(this).attr("persona-id"); | |
var radarSoldiers = BBLog._storage["radar.soldier"]; | |
var isPresent = false; | |
if (radarSoldiers) { | |
for (var i = 0; i < radarSoldiers.length; i++) { | |
if (radarSoldiers[i]['id'] == personaId) { | |
isPresent = true; | |
} | |
} | |
} | |
if (!isPresent) { | |
var html = '<div class="as-ao-confirm"><span>Add to radar?</span><button id="as-ao-radar-yes">Yes</button><button id="as-ao-radar-no">No</button></div>'; | |
} else { | |
var html = '<div class="as-ao-confirm"><span>Remove from radar?</span><button id="as-ao-remove-yes">Yes</button><button id="as-ao-radar-no">No</button></div>'; | |
} | |
$(this).parent().after(html); | |
instance.data.animationActive = true; | |
$(".as-ao-confirm").slideDown('fast'); | |
}); | |
$("#as-container").on('click', '#as-ao-radar-yes', function () { | |
var parent = $(this).parent(); | |
var personaId = $("#as-ao-radar").attr("persona-id"); | |
var name = $("#as-ao-name").html(); | |
if (name.split("]").length > 1) { | |
name = name.split("]")[1]; | |
} | |
var radarSoldier = { | |
id: personaId, | |
name: name, | |
source: 'bf4' | |
} | |
if (!BBLog._storage["radar.soldier"]) { | |
BBLog._storage["radar.soldier"] = []; | |
} | |
var radarSoldiers = BBLog._storage["radar.soldier"]; | |
BBLog._storage["radar.soldier"].push(radarSoldier); | |
parent.slideUp('fast', function () { | |
instance.data.animationActive = false; | |
parent.remove(); | |
instance.updateHTML(instance); | |
}); | |
}); | |
$("#as-container").on('click', '#as-ao-remove-yes', function () { | |
var personaId = $("#as-ao-radar").attr("persona-id"); | |
var name = $("#as-ao-name").html(); | |
if (name.split("]").length > 1) { | |
name = name.split("]")[1]; | |
} | |
var radarSoldiers = BBLog._storage["radar.soldier"]; | |
for (var i = 0; i < radarSoldiers.length; i++) { | |
if (radarSoldiers[i]['id'] == personaId) { | |
radarSoldiers.splice(i, 1); | |
} | |
} | |
$(".as-ao-confirm").slideUp('fast', function () { | |
$(".as-ao-confirm").remove(); | |
instance.data.animationActive = false; | |
instance.updateHTML(instance); | |
}); | |
}); | |
$("#as-container").on('click', '#as-ao-radar-no', function () { | |
var parent = $(this).parent(); | |
parent.slideUp('fast', function () { | |
parent.remove(); | |
instance.data.animationActive = false; | |
instance.updateHTML(instance); | |
}); | |
}); | |
$("#as-container").on('click', '#as-show-squads', function () { | |
instance.data.drawMode = "squad"; | |
instance.updateHTML(instance); | |
}); | |
$("#as-container").on('click', '#as-show-players', function () { | |
instance.data.drawMode = "player"; | |
instance.updateHTML(instance); | |
}); | |
$("#as-container").on('click', '#as-show-roles', function () { | |
instance.data.drawMode = "role"; | |
instance.updateHTML(instance); | |
}); | |
$("#as-container").on('click', '#as-show-charts', function () { | |
alert("Charts disabled for now."); | |
}); | |
$("#as-container").on('click', '#as-settings', function () { | |
instance.data.drawMode = "settings"; | |
instance.drawSettings(instance); | |
}); | |
$("#as-container").on('click', '#as-quit-game', function () { | |
var game = gamemanager.gameState.game; | |
console.log("Quitting game " + game); | |
gamemanager._killGame(gamemanager.gameState.game); | |
}); | |
//Handler for showing the advanced stats window | |
$("#as-container").on('click', '#as-ao-advanced', function () { | |
//instance.data.mode = 'stats'; | |
//instance.drawAdvancedStats(instance, $(this).attr('persona-id')); | |
//Test animations | |
var overview = $(this).parent().parent().parent(); | |
var slideUp = $(".as-scoreboard-wrapper").slideUp('slow'); | |
$.when(slideUp).done(function () { | |
$("#as-scoreboard-container").html(overview.html()); | |
}) | |
}); | |
//Handler for hiding the stats window | |
$("#server-page").on('click', '.as-stats-close', function () { | |
$("#as-stats-container").animate({ | |
opacity: 0, | |
height: 'toggle' | |
}, | |
1000, function () | |
{ | |
$("#as-stats-container").remove(); | |
instance.data.mode = 'scoreboard'; | |
instance.data.animationActive = true; | |
$("#as-container").animate({ | |
opacity: 1, | |
height: 'toggle' | |
}, 1000, function () | |
{ | |
instance.data.animationActive = false; | |
instance.updateHTML(instance); | |
}); | |
$('html, body').animate({ scrollTop: $("#as-scoreboard-container").offset().top }, 1000); | |
}); | |
}); | |
//Settings | |
//Event handler for the display stat select menu | |
$("#as-select-display-stat").on('change', function(){ | |
instance.storage('displayStat', this.value); | |
instance.updateHTML(instance); | |
}); | |
$("#content").on('click', '#as-settings-close', function () | |
{ | |
$("#as-settings-container").remove(); | |
}) | |
//Sorting event handlers | |
$("#as-container").on('click', '.as-scoreboard-head td', function() | |
{ | |
var elem = $(this); | |
if( elem.hasClass("sort-desc") ) | |
{ | |
console.log("has sort-desc") | |
elem.removeClass("sort-desc").addClass("sort-asc"); | |
instance.storage('sortMode', 'asc' ); | |
} | |
else if( elem.hasClass("sort-asc") ) | |
{ | |
console.log("has sort-asc") | |
elem.removeClass("sort-asc").addClass("sort-desc"); | |
instance.storage('sortMode', 'desc' ); | |
} | |
else | |
{ | |
console.log("unclassed") | |
elem.addClass("sort-desc"); | |
instance.storage('sortMode', 'desc'); | |
} | |
instance.storage('sortAttribute', this.getAttribute("sort")); | |
instance.updateHTML(instance); | |
}); | |
//Event handler for hilighting checkbox | |
$("#as-container").on('change', '#as-enable-hilighting', function(){ | |
if(this.checked) { | |
instance.storage('hilightingEnabled', true); | |
} else { | |
instance.storage('hilightingEnabled', false); | |
} | |
instance.updateHTML(instance); | |
}); | |
//Event handler for friend hilighting | |
$("#as-enable-friend-hilighting").change(function(){ | |
if(this.checked) { | |
instance.storage('hilightingEnabled', true); | |
} else { | |
instance.storage('hilightingEnabled', false); | |
} | |
instance.updateHTML(instance); | |
}); | |
//Scroll right in the advanced view | |
//Event handler for the live update checkbox | |
$("#content").on('change', '#as-enable-live', function() | |
{ | |
if(this.checked) { | |
instance.storage('liveEnabled', true); | |
if(!instance.data.asLiveUpdate) { | |
instance.data.asLiveUpdate = setInterval(function(){ | |
instance.updateAll(instance); | |
}, 5000); | |
instance.updateAll(instance); | |
instance.debug("Live update started via event handler") | |
} | |
} else { | |
instance.storage('liveEnabled', false); | |
if(instance.data.asLiveUpdate) { | |
clearInterval(instance.data.asLiveUpdate); | |
instance.data.asLiveUpdate = false; | |
instance.debug("Live update stopped") | |
} | |
} | |
}) | |
//Stats | |
$("#server-page").on('click', '.as-stats-select-weapons', function () | |
{ | |
$(".as-stats-vehicles").slideUp('fast', function () { | |
$(".as-stats-weapons").slideDown('fast'); | |
}); | |
}); | |
$("#server-page").on('click', '.as-stats-select-vehicles', function () { | |
$(".as-stats-weapons").slideUp('fast', function () { | |
$(".as-stats-vehicles").slideDown('fast'); | |
}); | |
}); | |
//Join on a specific team | |
$("#as-container").on('click', '.join-team', function () { | |
var teamId = $(this).attr('team-id'); | |
//alert("I want to join " + teamId); | |
var teams = instance.data.latestScoreboardData.teams; | |
var team = {}; | |
for (var i = 0; i < teams.length; i++) { | |
if(teams[i].status.teamId == teamId) { | |
team = teams[i]; | |
break; | |
} | |
} | |
//Iterate team and find lowest ranked played | |
var lowestRank = 140; | |
var lowestPlayer = {}; | |
for (var i = 0; i < team.players.length; i++) { | |
var player = team.players[i]; | |
if (player.rank < lowestRank) { | |
lowestRank = player.rank; | |
lowestPlayer = player; | |
} | |
} | |
console.log("The team is:") | |
console.log(team); | |
console.log("The player is:"); | |
console.log(lowestPlayer); | |
console.log("Okay latest data is:") | |
console.log(team); | |
instance.joinPlayer(lowestPlayer.personaId); | |
}); | |
$("#as-render-scorboard-button").click(function(){ | |
instance.updateAll(instance); | |
}); | |
}, | |
/** | |
* Allows the user to join the server on any player regardless of if they are on your friends list | |
* | |
* @param personaId The Battlelog Persona ID of the player to join | |
* | |
*/ | |
joinPlayer : function(personaId) | |
{ | |
var elem = document.getElementById("server-page-join-buttons"); | |
var guid = elem.getAttribute("data-guid"); | |
var platform = elem.getAttribute("data-platform"); | |
var game = elem.getAttribute("data-game"); | |
window.gamemanager.joinServerByGuid(guid, platform, game, personaId, 1); | |
}, | |
drawCharts : function(instance) | |
{ | |
//Disabled | |
return false; | |
instance.debug("Okay, drawing charts..."); | |
//Create a div to hold the test chart | |
if($("#as-scoreboard-container").is(':visible')) { | |
$("#as-scoreboard-container").html('<div id="as-charting-container"></div>') | |
} else { //Catch issue with navigation | |
instance.unloadPlugin(instance); | |
instance.handler(instance); | |
} | |
//Put tracking data into array | |
var chartData = []; | |
for( var dataSet in instance.data.tracker.tickets ) | |
{ | |
var data = instance.data.tracker.tickets[dataSet]; | |
instance.debug(data); | |
chartData.push(data); | |
} | |
/* | |
instance.data.currentChart = c3.generate({ | |
bindto: '#as-charting-container', | |
data: { | |
columns: chartData | |
}, | |
type: 'spline' | |
}); | |
*/ | |
instance.debug("Here's the player stats"); | |
instance.debug(instance.playerStats); | |
instance.debug("Here's the scoreboardData"); | |
instance.debug(instance.data.latestScoreboardData); | |
//Okay get the latest scoreboarddata | |
var teamPlot = []; | |
var teamNames = {}; | |
for(var team in instance.data.latestScoreboardData.teams) | |
{ | |
var teamObject = instance.data.latestScoreboardData.teams[team]; | |
var teamName = instance.lookup.teamName(instance.data.latestScoreboardData.gameMode, teamObject.status); | |
var skillStats = [teamName + ' skill']; | |
var kdStats = [teamName + ' kd']; | |
for (var player in teamObject.players) | |
{ | |
instance.debug("Looping player in sbdata players"); | |
var playerObject = teamObject.players[player]; | |
var personaId = playerObject.personaId; | |
skillStats.push(instance.playerStats[personaId].overviewStats.skill); | |
kdStats.push(instance.playerStats[personaId].overviewStats.kdRatio); | |
} | |
teamPlot.push(skillStats, kdStats); | |
teamNames[teamName + " skill"] = teamName + ' kd'; | |
} | |
instance.debug(teamPlot); | |
instance.data.charts.skillDistribution = c3.generate({ | |
bindto: '#as-charting-container', | |
data : { | |
xs: teamNames, | |
columns: teamPlot, | |
type: 'scatter' | |
}, | |
axis: { | |
x: { | |
label: 'KD Ratio', | |
min: 0, | |
tick: { | |
fit: false, | |
centered: true | |
} | |
}, | |
y: { | |
label: 'Skill', | |
min: 0, | |
}, | |
}, | |
tooltip: { | |
format: { | |
title: function (d) { return 'Data' + teamNames[0]; }, | |
} | |
}, | |
}) | |
}, | |
/** | |
* Refreshes all data and redraws scoreboard | |
* | |
* @param instance Plugin object instance | |
* | |
*/ | |
updateAll : function(instance){ | |
var serverInfo = instance.getServerAttributes(); // Server attributes | |
instance.queryServerScoreboard(serverInfo, function(queryResult) | |
{ | |
instance.debug(queryResult); | |
//Store the result of the query | |
instance.data.latestScoreboardData = queryResult; | |
//Cache player statistics | |
instance.updatePlayerStats(instance, queryResult); | |
//Render the scoreboard with this data | |
if( !instance.data.animationActive && instance.data.mode == 'scoreboard' ) | |
{ | |
if( instance.data.drawMode == "player" ) { | |
instance.drawPlayerScoreBoard(instance, queryResult); | |
} | |
else if ( instance.data.drawMode == "squad" ) { | |
instance.drawSquadScoreBoard(instance, queryResult); // Draw the scoreboard using the query result | |
} else if ( instance.data.drawMode == "role" ) { | |
instance.drawRoleScoreBoard(instance, queryResult); | |
} | |
else if ( instance.data.drawMode == "charts" ) { | |
instance.updateTracker(instance, queryResult, function(instance) | |
{ | |
instance.updateCharts(instance); | |
}); | |
} | |
} | |
//Update the round header | |
instance.updateRoundHeader(instance, queryResult); | |
}); | |
}, | |
/** | |
* Redraws HTML without refreshing data sources | |
* | |
* @param instance Plugin object instance | |
* | |
*/ | |
updateHTML : function(instance) { | |
if(!instance.data.animationActive && instance.data.mode == 'scoreboard') | |
{ | |
if(instance.data.drawMode == "player") | |
{ | |
instance.drawPlayerScoreBoard(instance, instance.data.latestScoreboardData); | |
} else if ( instance.data.drawMode == "role" ) { | |
instance.drawRoleScoreBoard(instance, instance.data.latestScoreboardData); | |
} else if (instance.data.drawMode == "squad") { | |
instance.drawSquadScoreBoard(instance, instance.data.latestScoreboardData); // Draw the scoreboard using the query result | |
} | |
} | |
}, | |
/** | |
* Updates the tracking object with data from the server | |
* | |
* @param instance Plugin object instance | |
* @param serverData Data from the server | |
* @param callback Callback function | |
*/ | |
updateTracker : function(instance, serverData, callback) | |
{ | |
for(i = 0; i < serverData.teams.length; i++) | |
{ | |
var team = serverData.teams[i]; | |
var teamId = team.status.teamId; | |
var tickets = team.status.tickets; | |
if( instance.data.tracker.tickets.hasOwnProperty(teamId) ) | |
{ | |
instance.data.tracker.tickets[teamId].push(tickets); | |
} | |
else | |
{ | |
instance.data.tracker.tickets[teamId] = [instance.lookup.teamName(serverData.gameMode, team.status), tickets]; | |
} | |
} | |
instance.debug(instance.data.tracker); | |
callback(instance); | |
}, | |
/** | |
* Updates the charts | |
* | |
* @param instance Plugin object instance | |
*/ | |
updateCharts : function(instance) | |
{ | |
if( instance.data.currentChart ) { | |
var chartData = []; | |
for( var dataSet in instance.data.tracker.tickets ) | |
{ | |
var data = instance.data.tracker.tickets[dataSet]; | |
instance.debug(data); | |
chartData.push(data); | |
} | |
instance.data.currentChart.load({ | |
columns : chartData | |
}); | |
} | |
}, | |
/** | |
* Returns an object containing the team data for the round and the total stats for each team | |
* | |
* @param instance Plugin Object Instance | |
* @param scoreboardData JSON Object containing the information received from the gameserver | |
*/ | |
calculateTeamTotals : function(instance, scoreboardData) | |
{ | |
var s = scoreboardData; | |
console.log("Gimme commander feature pls"); | |
console.log(s); | |
var teams = []; | |
$.each(s.teams, function(teamID, team) | |
{ | |
var players = team.players; | |
var status = team.status; | |
var teamObj = { | |
'players' : [], | |
'status' : team.status, | |
'totalPlayers' : 0, | |
'totalRank' : 0, | |
'totalKills' : 0, | |
'totalDeaths' : 0, | |
'totalScore' : 0, | |
'playersLoaded' : 0, | |
'totalPDisplayStat': 0, | |
'commander': false | |
}; | |
$.each(team.players, function(playerId, player) | |
{ | |
var playerObj = | |
{ | |
'id': player.personaId, | |
'tag': player.tag, | |
'name': player.name, | |
'rank': player.rank, | |
'role': player.role, | |
'squad': player.squad, | |
'score': player.score, | |
'kills': player.kills, | |
'deaths': player.deaths, | |
'kd': (player.deaths == 0) ? player.kills : player.kills / player.deaths, | |
'statsLoaded' : false, | |
'pDisplayStat': 0 | |
} | |
if (player.role == 2) { | |
console.log("COMMANDER FOUND!"); | |
console.log(player); | |
teamObj.commander = playerObj; | |
} else { | |
teamObj.totalRank += player.rank; | |
teamObj.totalKills += player.kills; | |
teamObj.totalDeaths += player.deaths; | |
teamObj.totalScore += player.score; | |
teamObj.totalPlayers++; | |
//Load the players statistics from the | |
if (instance.playerStats.hasOwnProperty(player.personaId)) { | |
playerObj.statsLoaded = true; | |
var pStats = instance.playerStats[player.personaId]; | |
var displayStat = instance.storage('displayStat'); | |
if (displayStat == 'kdRatio' && !instance.storage('useResetKdr')) { | |
if (pStats.overviewStats.deaths == 0) { | |
playerObj.pDisplayStat = pStats.overviewStats.kills | |
} else { | |
playerObj.pDisplayStat = Math.round((pStats.overviewStats.kills / pStats.overviewStats.deaths) * 100) / 100; | |
} | |
} else if (displayStat == 'strength') { | |
var strength = (pStats.overviewStats.skill * pStats.overviewStats.kdRatio * pStats.overviewStats.killsPerMinute * pStats.overviewStats.scorePerMinute) / 1000; | |
playerObj.pDisplayStat = Math.floor(strength); | |
} else { | |
playerObj.pDisplayStat = pStats.overviewStats[displayStat]; | |
} | |
teamObj.totalPDisplayStat += playerObj.pDisplayStat; | |
teamObj.playersLoaded++; | |
} | |
teamObj.players.push(playerObj); | |
} | |
}) | |
teams.push(teamObj); | |
}) | |
return teams; | |
}, | |
/** | |
* Returns an object detailing the role specializations of the team. i.e. top players by vehicle type/weapon type | |
* | |
* @param instance Plugin Object Instance | |
* @param scoreboardData JSON Object cotnaining the information received from the gameserver | |
*/ | |
calculateRoles: function(instance, scoreboardData) | |
{ | |
var start = new Date().getTime(); | |
var s = scoreboardData; | |
var teamRoles = []; | |
instance.debug("Starting roles calc"); | |
$.each(s.teams, function(teamId, team) | |
{ | |
var players = team.players; | |
var status = team.status; | |
var commander = false; | |
var vehicles = {}; | |
$.each(players, function(playerId, player) | |
{ | |
//If the user's overviewstats have been loaded | |
if( instance.playerStats.hasOwnProperty(player.personaId) ) { | |
var pStats = instance.playerStats[player.personaId]; | |
//Iterate over the top play vehicles and add them to the role totals for the team | |
for (var i = 0; i < pStats.topVehicles.length; i++) { | |
var vehicle = pStats.topVehicles[i]; | |
var vehicleName = vehicle.category.replace('Vehicle ', ''); | |
if (vehicle.kills > 100) { | |
if ( vehicles.hasOwnProperty(vehicleName) ) { | |
var playerPresent = false; | |
//Check if player already exists in this category, e.g. AH6-J kills logged under scout category, but Z-11 have not yet been processed | |
for (var j = 0; j < vehicles[vehicleName].topPlayers.length; j++) { | |
if (vehicles[vehicleName].topPlayers[j].personaId == player.personaId) { | |
playerPresent = true; | |
vehicles[vehicleName].topPlayers[j].kills += vehicle.kills; | |
vehicles[vehicleName].topPlayers[j].time += vehicle.timeIn; | |
break; | |
} | |
} | |
if (!playerPresent) { | |
var playerVehicleStats = { | |
personaId: player.personaId, | |
kills: vehicle.kills, | |
rank: player.rank, | |
time: vehicle.time | |
} | |
vehicles[vehicleName].topPlayers.push(playerVehicleStats); | |
} | |
vehicles[vehicleName].totalKills += vehicle.kills; | |
vehicles[vehicleName].totalTime += vehicle.timeIn; | |
} else { | |
vehicles[vehicleName] = { | |
topPlayers: [], | |
totalKills: 0, | |
totalTime: 0, | |
}; | |
var playerVehicleStats = { | |
personaId: player.personaId, | |
kills: vehicle.kills, | |
rank: player.rank, | |
time: vehicle.time | |
} | |
vehicles[vehicleName].totalKills += vehicle.kills; | |
vehicles[vehicleName].totalTime += vehicle.timeIn; | |
vehicles[vehicleName].topPlayers.push(playerVehicleStats); | |
var vehicleDisplay = window.items.game_data.compact.vehicles[vehicle.guid] | |
vehicleDisplay = vehicleDisplay.see[0]; | |
var lineartSlug = window.items.game_data.compact.vehicles[vehicleDisplay]; | |
lineartSlug = lineartSlug.imageConfig.slug; | |
if (!vehicles[vehicleName].lineartSlug) { | |
vehicles[vehicleName].lineart = lineartSlug; | |
} | |
} | |
} | |
} | |
console.log(pStats); | |
} | |
}); | |
teamRoles.push(vehicles); | |
}); | |
var end = new Date().getTime(); | |
var time = end - start; | |
console.log("Calculating roles took " + time + "ms"); | |
return teamRoles; | |
}, | |
/** | |
* A refactored version of the scoreboard rendering function to allow for more flexible output and design | |
* | |
* @param instance Plugin Object Instance | |
* @param s JSON Object containing the information received from the gameserver | |
*/ | |
drawPlayerScoreBoard : function(instance, scoreboardData) | |
{ | |
instance.debug('Drawing player scoreboard'); | |
var start = new Date().getTime(); | |
var s = scoreboardData; | |
var teams = instance.calculateTeamTotals(instance, scoreboardData); | |
instance.debug('Here are the team totals:') | |
instance.debug(teams); | |
//Disabled, fixed next version | |
/* Load in the BBLog radar and check if any of the players on the server match | |
if (BBLog._storage["radar.soldier"]) { | |
var radar = BBLog._storage["radar.soldier"]; | |
} | |
else { | |
var radar = false; | |
} | |
var radarSoldiers = []; | |
if (radar) { | |
for (var i = 0; i < radar.length; i++) { | |
var radarSoldier = radar[i]; | |
radarSoldiers[radarSoldier.id] = true; | |
} | |
} | |
*/ | |
//We now have our custom teams object with all the relevant information | |
var html = ""; | |
//Iterate over each team | |
for( i = 0; i < teams.length; i++ ) | |
{ | |
var team = teams[i]; | |
var teamName = instance.lookup.teamName(s.gameMode, team.status); | |
var teamFlag = instance.lookup.teamFlag(teamName); | |
//Create wrapper and table for team | |
html += '<div class="as-scoreboard-wrapper" teamId = "' + team.status.teamId + '">' + | |
'<table class="table as-scoreboard-table" teamId="' + team.status.teamId + '">' + | |
'<thead><tr class="as-scoreboard-details">' + | |
'<td colspan="7"><span style="vertical-align: top; display: inline-block; margin: 5px; bottom: 5px;">'; | |
var progressBarWidth = Math.floor((team.status.tickets/team.status.ticketsMax) * 100); | |
var progressBar ='<div class="progress-bar thicker no-border '+instance.lookup.teamType(team.status.teamId)+'" style="position: relative; display: inline-block; width: 100px; margin: 5px;"><div class="home progress-bar-inner" style="width:'+progressBarWidth+'%"></div></div>'; | |
//html += '<thead><tr class="as-scoreboard-details"><td colspan="7"><span style="vertical-align: top; display: inline-block; margin: 5px; bottom: 5px;">'; | |
if ( teamFlag ) { | |
html += '<img alt="flag" class="as-team-flag" src="' + teamFlag + '"></img>'; | |
} | |
html += teamName + ' : ' + team.status.tickets + | |
'</span>' + progressBar + | |
'<span style="vertical-align: top; display: inline-block; margin: 5px; bottom: 5px;">Players: [' + team.players.length + '/' + (s.maxPlayers/2).toFixed(0) + ']</span>' + | |
'<button class="btn join-team" team-id="' + team.status.teamId + '">Join</button>' + | |
'</td>'; | |
//HTML for table header | |
html += '<tr class="as-scoreboard-head">'//<td sort="rank">Rank</td><td sort="name">Name</td><td sort="kills">K</td><td sort="deaths">D</td><td sort="score" class="sort-desc">Score</td><td sort="kd">K/D</td><td sort="pDisplayStat">' + instance.lookup.displayStat(instance.storage('displayStat')) +'</td></tr></thead>'; | |
var columns = [ | |
{header : "Rank", sortAttribute : "rank"}, | |
{header : "Name", sortAttribute : "name"}, | |
{header : "K", sortAttribute : "kills"}, | |
{header : "D", sortAttribute : "deaths"}, | |
{header : "Score", sortAttribute : "score"}, | |
{header : "K/D", sortAttribute : "kd"}, | |
{header : instance.lookup.displayStat(instance.storage('displayStat')), sortAttribute : "pDisplayStat"} | |
] | |
var sortAttribute = instance.storage('sortAttribute'); | |
var sortMode = instance.storage('sortMode'); | |
for( j = 0; j < columns.length; j++) | |
{ | |
var column = columns[j]; | |
html += '<td ' + (column.sortAttribute == sortAttribute ? 'class="sort-' + sortMode + '"' : '') +' sort="' + column.sortAttribute + '">' + column.header + (column.sortAttribute == sortAttribute ? '<div class="sort-' + sortMode + '"></div>' : '') + '</td>'; | |
} | |
html += '</tr></thead>'; | |
//Here we decide the order in which players will be displayed.. | |
team.players.sort(function (a, b) { | |
if (sortMode == 'desc') { | |
return a[sortAttribute] == b[sortAttribute] ? 0 : +(a[sortAttribute] < b[sortAttribute]) || -1; | |
} else { | |
return a[sortAttribute] == b[sortAttribute] ? 0 : +(a[sortAttribute] > b[sortAttribute]) || -1; | |
} | |
}); | |
//Iterate over the players on the team and create a table row for them | |
for( j = 0; j < team.players.length; j++ ) { | |
var player = team.players[j]; | |
//Rank display html | |
var pRank = '<div class="bf4-rank rank small r' + player.rank + ' rank_icon" data-rank="' + player.rank +'"></div>' | |
//Player name including tags | |
var pName = player.tag.length > 0 ? '[' + player.tag + ']' + player.name : player.name; | |
pName = '<a href="/bf4/user/' + player.name + '/">' + pName + '</a>'; | |
//Player K/D | |
var pKD = player.deaths == 0 ? player.kills : player.kills/player.deaths; | |
//Set hilighting class | |
var hilightingType = false; | |
if (instance.storage('hilightingEnabled') && player.statsLoaded) { | |
hilightingType = instance.lookup.hilightingClass(instance.storage('displayStat'), player.pDisplayStat); | |
} | |
/* | |
if( radarSoldiers.hasOwnProperty(player.id)) { | |
hilightingType += " radar" | |
} | |
*/ | |
var friends = comcenter.getFriendsListFromLs(); | |
var isFriend = false; | |
for ( var k = 0; k < friends.length; k++ ) | |
{ | |
if(friends[k].username == player.name) { | |
isFriend = true; | |
break; | |
} | |
} | |
var displayStat = player.statsLoaded ? player.pDisplayStat : '<div class="loader small"></div>'; | |
//Generate table row | |
html += '<tr class="as-player' + (player.id == instance.data.advancedViewPlayer ? ' as-advanced-stats-selected' : '') + (isFriend ? ' friend' : '') + (hilightingType ? ' ' + hilightingType : '') + '" personaid="' + player.id + '"><td>' + pRank + '</td><td>' + pName + '</td><td>' + player.kills + '</td><td>' + player.deaths + '</td><td>' + player.score +'</td><td>' + pKD.toFixed(2) + '</td><td>' + displayStat + '</td></tr>' | |
//If a specific player is selected for the advanced view, inject the HTML here | |
if (player.id == instance.data.advancedViewPlayer ) { | |
html += instance.createAdvancedPlayerView(instance, player.id, true); | |
} | |
} | |
/*** Create tfoot from averages ***/ | |
//Average rank display html | |
var avgRank = '<div class="bf4-rank rank small r' + Math.floor(team.totalRank/team.players.length) + ' rank_icon" data-rank="' + Math.floor(team.totalRank/team.players.length) +'"></div>' | |
//Average KD | |
var avgKD = team.totalDeaths == 0 ? team.totalKills : team.totalKills/team.totalDeaths; | |
//Average pDisplayStat | |
var avgpDisplayStat = team.totalPDisplayStat == 0 ? '...' : (team.totalPDisplayStat/team.playersLoaded).toFixed(2); | |
//HTML for scoreboard foot | |
html += '<tfoot><tr class="as-scoreboard-foot"><td>'+ avgRank +'</td><td></td><td>'+ team.totalKills +'</td><td>' + team.totalDeaths + '</td><td>' + team.totalScore +'</td><td>' + avgKD.toFixed(2) + '</td><td>' + avgpDisplayStat + '</td></tr></tfoot>'; | |
html += '</table>'; | |
if (team.commander) { | |
var commander = team.commander; | |
var cRank = '<div class="bf4-rank rank small r' + commander.rank + ' rank_icon" data-rank="' + commander.rank + '"></div>' | |
var cKd = commander.deaths == 0 ? commander.kills : commander.kills / commander.deaths; | |
//Player name including tags | |
var cName = commander.tag.length > 0 ? '[' + commander.tag + ']' + commander.name : commander.name; | |
pName = '<a href="/bf4/user/' + commander.name + '/">' + cName + '</a>'; | |
html += '<table class="table as-commander-scoreboard"><tbody><tr><td>' + cRank + '</td><td>' + cName + '</td><td>' + commander.kills + '</td><td>' + commander.deaths + '</td><td>' + commander.score + '</td><td>' + cKd + '</td><td>' + commander.pDisplayStat + '</td></tr></tbody></table>'; | |
} | |
html += '</div>'; | |
} | |
console.log("Update Log:"); | |
console.log(s); | |
console.log(instance.data.gameServerWarsaw.mapLookup); | |
//Update the map name | |
var displayMap = '<img class="current-map" src="//eaassets-a.akamaihd.net/bl-cdn/cdnprefix/9c0b010cd947f38bf5e87df5e82af64e0ffdc12fh/public/base/bf4/map_images/195x79/' + s.mapName.toLowerCase() + '.jpg"></img>' + | |
'<div id="as-map-name">' + instance.data.gameServerWarsaw.mapLookup[s.mapName].label + '</div>' + | |
'<div id="as-map-mode">' + instance.lookup.gameMode(s.gameMode) + '</div>'; | |
$("#as-scoreboard-mapinfo").html(displayMap); | |
var serverInfo = '<table class="as-server-properties">' + | |
'<tr><th>Players</th><td>' + + '</td></tr>' + | |
'</table>'; | |
$("#as-round-properties").html(serverInfo); | |
var defaultRoundtimeSeconds = 3600; | |
var currentRoundTime = 3600 * (s.defaultRoundTimeMultiplier/100); | |
var expiredTime = s.roundTime; | |
var secondsRemaining = currentRoundTime - expiredTime; | |
var timeLeft = Math.floor(secondsRemaining/60) + 'M ' + (Math.round((secondsRemaining%60) * 100)/100) + 'S'; | |
$("span#as-server-time-remaining").html(timeLeft) | |
//HTML For the round status | |
var totalPlayers = 0; | |
for (var i = 0; i < s.teams.length; i++) { | |
var team = s.teams[i]; | |
totalPlayers += team.players.length; | |
} | |
var roundProperties = '<table class="as-round-properties">' + | |
'<tr><td>Players</td><td>' + totalPlayers + '/' + s.maxPlayers + (s.queueingPlayers > 0 ? '[' + s.queueingPlayers + ']' : '') + '</td></tr>' + | |
'</table>'; | |
$("#as-scoreboard-round-properties").html(roundProperties) | |
if ($("#as-scoreboard-container").is(':visible')) { | |
$("#as-scoreboard-container").html(html) | |
} else { //Catch issue with navigation | |
instance.unloadPlugin(instance); | |
instance.handler(instance); | |
} | |
var end = new Date().getTime(); | |
var time = end - start; | |
console.log("Drawing took " + time + "msg"); | |
}, | |
drawSquadScoreBoard : function(instance, scoreboardData) | |
{ | |
var start = new Date().getTime(); | |
instance.debug('Beginning render process for squad view'); | |
var s = scoreboardData; | |
var teams = instance.calculateTeamTotals(instance, scoreboardData); | |
console.log(teams); | |
html = ""; | |
for(var i = 0; i < teams.length; i++) | |
{ | |
var team = teams[i]; | |
var teamName = instance.lookup.teamName(s.gameMode, team.status); | |
var teamFlag = instance.lookup.teamFlag(teamName); | |
instance.debug("Drawing team " + i) | |
var squads = {}; //Squads object | |
var squadNames = []; | |
//Sort the team players into squads, and calculate their respective totals | |
for(j = 0; j < team.players.length; j++) | |
{ | |
var player = team.players[j]; | |
var playerSquadName = instance.lookup.squadName(player.squad); | |
if(squads.hasOwnProperty(instance.lookup.squadName(player.squad))) | |
{ | |
squads[playerSquadName].players.push(player); | |
} | |
else | |
{ | |
squadNames.push(playerSquadName); | |
squads[playerSquadName] = {}; | |
squads[playerSquadName]["rank"] = 0; | |
squads[playerSquadName]["kills"] = 0; | |
squads[playerSquadName]["deaths"] = 0; | |
squads[playerSquadName]["score"] = 0; | |
squads[playerSquadName]["sTotal"] = 0; | |
squads[playerSquadName]["players"] = []; | |
squads[playerSquadName].players.push(player); | |
} | |
//Add player stats to squad total | |
squads[playerSquadName]["kills"] += player.kills; | |
squads[playerSquadName]["deaths"] += player.deaths; | |
squads[playerSquadName]["score"] += player.score; | |
squads[playerSquadName]["rank"] += player.rank; | |
if(instance.playerStats.hasOwnProperty(player.id)) { | |
var pStats = instance.playerStats[player.id]; | |
var pDisplayStat = pStats.overviewStats[instance.storage('displayStat')]; | |
squads[playerSquadName]["sTotal"] += pDisplayStat; | |
} | |
} | |
console.log(squads); | |
html += '<div class="as-scoreboard-wrapper" teamId = "' + team.status.teamId + '"><table class="table as-scoreboard-table" teamId="' + team.status.teamId + '">'; | |
//Progress bar HTML for GFX representation of tickets | |
var progressBarWidth = Math.floor((team.status.tickets/team.status.ticketsMax) * 100); | |
var progressBar ='<div class="progress-bar thicker no-border '+instance.lookup.teamType(team.status.teamId)+'" style="position: relative; display: inline-block; width: 100px; margin: 5px;"><div class="home progress-bar-inner" style="width:'+progressBarWidth+'%"></div></div>'; | |
html += '<thead><tr class="as-scoreboard-details"><td colspan="7"><span style="vertical-align: top; display: inline-block; margin: 5px; bottom: 5px;">'; | |
if (teamFlag) { | |
html += '<img alt="flag" class="as-team-flag" src="' + teamFlag + '"></img>'; | |
} | |
html += teamName + ' : ' + team.status.tickets + | |
'</span>' + progressBar + | |
'<span style="vertical-align: top; display: inline-block; margin: 5px; bottom: 5px;">Players: [' + team.players.length + '/' + (s.maxPlayers / 2).toFixed(0) + ']</span></td>'; | |
//HTML for table header | |
//html += '<tr class="as-scoreboard-head"><td>Rank</td><td>Name</td><td>K</td><td>D</td><td>Score</td><td>K/D</td><td>' + instance.lookup.displayStat(instance.storage('displayStat')) +'</td></tr></thead>'; | |
//Sort the array of squadnames alphabeticaly | |
squadNames.sort(); | |
for (var j = 0; j < squadNames.length; j++) | |
{ | |
var squadName = squadNames[j]; | |
var squad = squads[squadName]; | |
var sKD = squad.deaths == 0 ? squad.kills : squad.kills/squad.deaths; | |
//html += '<tr class="spacer"><td colspan="7"></td></tr>'; | |
html += '<tr class="as-squad-row"><td colspan="7">' + squadName.toUpperCase() + ' [' + squad.players.length + '/5]</td/></tr>'; | |
for(var k = 0; k < squad.players.length; k++) | |
{ | |
var player = squad.players[k]; | |
var pRank = '<div class="bf4-rank rank small r' + player.rank + ' rank_icon" data-rank="' + player.rank +'"></div>'; | |
var pName = player.tag.length > 0 ? '[' + player.tag + ']' + player.name : player.name; | |
var pKD = player.deaths == 0 ? player.kills : player.kills/player.deaths; | |
var hilightingType = false; | |
if( instance.storage('hilightingEnabled') && pDisplayStat !== '...' ) { | |
if(instance.storage('displayStat') == 'kdRatio') { | |
if(player.pDisplayStat < 1) { | |
hilightingType = 'low'; | |
} else if(player.pDisplayStat < 2) { | |
hilightingType = 'average'; | |
} else if(player.pDisplayStat < 3) { | |
hilightingType = 'good'; | |
} else if(player.pDisplayStat < 4) { | |
hilightingType = 'high'; | |
} else if(player.pDisplayStat >= 4) { | |
hilightingType = 'v-high'; | |
} | |
} else if(instance.storage('displayStat') == 'skill') { | |
if(player.pDisplayStat < 200) { | |
hilightingType = 'low'; | |
} else if(player.pDisplayStat < 300) { | |
hilightingType = 'average'; | |
} else if(player.pDisplayStat < 400) { | |
hilightingType = 'good'; | |
} else if(player.pDisplayStat < 550) { | |
hilightingType = 'high'; | |
} else if(player.pDisplayStat >= 550) { | |
hilightingType = 'v-high'; | |
} | |
} | |
} | |
//Generate table row | |
html += '<tr class="as-player' + (player.id == instance.data.advancedViewPlayer ? ' as-advanced-stats-selected' : '') + (isFriend ? ' friend' : '') + (hilightingType ? ' ' + hilightingType : '') + '" personaid="' + player.id + '"><td>' + pRank + '</td><td>' + pName + '</td><td>' + player.kills + '</td><td>' + player.deaths + '</td><td>' + player.score +'</td><td>' + pKD.toFixed(2) + '</td><td>' + player.pDisplayStat + '</td></tr>'; | |
if (player.id == instance.data.advancedViewPlayer) { | |
instance.debug("Creating advanced player view"); | |
html += instance.createAdvancedPlayerView(instance, player.id, true); | |
} | |
var friends = comcenter.getFriendsListFromLs(); | |
var isFriend = false; | |
for (var l = 0; l < friends.length; l++) | |
{ | |
if(friends[i].username == player.name) | |
{ | |
isFriend = true; | |
break; | |
} | |
} | |
} | |
var avgSquadRank = Math.floor(squad.rank / squad.players.length); | |
var avgRank = '<div class="bf4-rank rank small r' + avgSquadRank + ' rank_icon" data-rank="' + avgSquadRank + '"></div>'; | |
html += '<tr class="as-squad-summary"><td>' + avgRank + '<td></td><td>' + squad.kills + '</td><td>' + squad.deaths + '</td><td>' + squad.score + '</td><td>' + sKD.toFixed(2) + '</td><td>' + (squad.sTotal / squad.players.length).toFixed(2) + '</td></tr>'; | |
for(var k = squad.players.length; k < 5; k++) | |
{ | |
html += '<tr class="as-squad-spacer"><td colspan="7"></td></tr>'; | |
} | |
} | |
/*** Create tfoot from averages ***/ | |
//Average rank display html | |
var avgRank = '<div class="bf4-rank rank small r' + Math.floor(team.totalRank/team.totalPlayers) + ' rank_icon" data-rank="' + Math.floor(team.totalRank/team.totalPlayers) +'"></div>' | |
//Average KD | |
var avgKD = team.totalDeaths == 0 ? team.totalKills : team.totalKills/team.totalDeaths; | |
//Average pDisplayStat | |
var avgpDisplayStat = team.totalPDisplayStat == 0 ? '...' : (team.totalPDisplayStat/team.playersLoaded).toFixed(2); | |
//HTML for scoreboard foot | |
//html += '<tfoot><tr class="as-scoreboard-foot"><td>'+ avgRank +'</td><td></td><td>'+ team.totalKills +'</td><td>' + team.totalDeaths + '</td><td>' + team.totalScore +'</td><td>' + avgKD.toFixed(2) + '</td><td>' + avgpDisplayStat + '</td></tr></tfoot>'; | |
html += '</table>' | |
html += '</div>'; | |
} | |
if($("#as-scoreboard-container").is(':visible')) { | |
$("#as-scoreboard-container").html(html) | |
} else { //Catch issue with navigation | |
instance.unloadPlugin(instance); | |
instance.handler(instance); | |
} | |
}, | |
drawRoleScoreBoard : function(instance, scoreboardData) | |
{ | |
var start = new Date().getTime(); | |
instance.debug("Beginning render process for role scoreboard"); | |
var s = scoreboardData; | |
console.log("Calculating role data for both teams") | |
var vehicleRoles = instance.calculateRoles(instance, s); | |
console.log("Role Data:"); | |
console.log(vehicleRoles); | |
console.log("Calculating team data"); | |
var teams = instance.calculateTeamTotals(instance, scoreboardData); | |
console.log("Team data:"); | |
console.log(teams); | |
//We now have our custom teams object with all the relevant information | |
var html = ""; | |
//Iterate by vehicle type | |
for (i = 0; i < vehicleRoles.length; i++) { | |
var teamVehicleRoles = vehicleRoles[i]; | |
var team = teams[i]; | |
var teamName = instance.lookup.teamName(s.gameMode, team.status); | |
var teamFlag = instance.lookup.teamFlag(teamName); | |
//Players lookup object | |
var teamPlayers = {}; | |
for (var playerId in team.players) { | |
var player = team.players[playerId]; | |
teamPlayers[player.id] = player; | |
} | |
console.log("Here is team:"); | |
console.log(team); | |
html += '<div class="as-scoreboard-wrapper" teamId = "' + team.status.teamId + '"><table class="table as-scoreboard-table" teamId="' + team.status.teamId + '">'; | |
var progressBarWidth = Math.floor((team.status.tickets / team.status.ticketsMax) * 100); | |
var progressBar = '<div class="progress-bar thicker no-border ' + instance.lookup.teamType(team.status.teamId) + '" style="position: relative; display: inline-block; width: 100px; margin: 5px;"><div class="home progress-bar-inner" style="width:' + progressBarWidth + '%"></div></div>'; | |
html += '<thead>' + | |
'<tr class="as-scoreboard-details"><td colspan="7"><span style="vertical-align: top; display: inline-block; margin: 5px; bottom: 5px;">' + | |
'<img alt="flag" class="as-team-flag" src="' + teamFlag + '"></img>' + teamName + ' : ' + team.status.tickets + | |
'</span>' + progressBar + | |
'<span style="vertical-align: top; display: inline-block; margin: 5px; bottom: 5px;">Players: [' + team.players.length + '/' + (s.maxPlayers / 2).toFixed(0) + ']</span></td></tr></thead>'; | |
for (var vehicleRole in teamVehicleRoles) { | |
var vehicle = teamVehicleRoles[vehicleRole]; | |
console.log("Vehicle is here:") | |
console.log(vehicle); | |
//Sort by top players | |
vehicle.topPlayers.sort(function (a, b) { | |
return a.kills == b.kills ? 0 : +(a.kills < b.kills) || -1; | |
}); | |
html += '<tr class="as-role-title-row"><td class="as-role-title" colspan="7"><div class="as-role-title-text">' + vehicleRole + '</div><div class="vehicle small ' + vehicle.lineart + ' image"></div></td></tr>'; | |
html += '<tr><td colspan="7" style="padding: 0px;"><div class="as-role-top-players"><table style="width:100%; border: 0px;">'; | |
for (var key in vehicle.topPlayers) { | |
var topPlayer = vehicle.topPlayers[key]; | |
var personaId = topPlayer.personaId; | |
var kills = topPlayer.kills; | |
var playerStats = teamPlayers[personaId]; | |
console.log(playerStats); | |
if(!playerStats) | |
continue; | |
var pRank = '<div class="bf4-rank rank small r' + playerStats.rank + ' rank_icon" data-rank="' + playerStats.rank + '"></div>' | |
//Player name including tags | |
var pName = playerStats.tag.length > 0 ? '[' + playerStats.tag + ']' + playerStats.name : playerStats.name; | |
pName = '<a href="/bf4/user/' + playerStats.name + '/">' + pName + '</a>'; | |
//Player K/D | |
var pKD = playerStats.deaths == 0 ? playerStats.kills : playerStats.kills / playerStats.deaths; | |
//Set hilighting class | |
var hilightingType = false; | |
if (instance.storage('hilightingEnabled')) { | |
hilightingType = instance.lookup.hilightingClass(instance.storage('displayStat'), playerStats.pDisplayStat); | |
} | |
var friends = comcenter.getFriendsListFromLs(); | |
var isFriend = false; | |
for (var k = 0; k < friends.length; k++) { | |
if (friends[k].username == player.name) { | |
isFriend = true; | |
break; | |
} | |
} | |
html += '<tr class="as-player' + (playerStats.id == instance.data.advancedViewPlayer ? ' as-advanced-stats-selected' : '') + (isFriend ? ' friend' : '') + (hilightingType ? ' ' + hilightingType : '') + '" personaid="' + playerStats.id + '"><td>' + pRank + '</td><td>' + pName + '</td><td>' + playerStats.kills + '</td><td>' + playerStats.deaths + '</td><td>' + playerStats.score + '</td><td>' + pKD.toFixed(2) + '</td><td>' + topPlayer.kills + '</td></tr>' | |
//If a specific player is selected for the advanced view, inject the HTML here | |
if (playerStats.id == instance.data.advancedViewPlayer) { | |
instance.debug("Creating advanced player view"); | |
html += instance.createAdvancedPlayerView(instance, playerStats.id, true); | |
} | |
} | |
html += '</table></div></td></tr>' | |
} | |
html += '</table></div>' | |
} | |
//Iterate over each team | |
for (i = teams.length; i < teams.length; i++) | |
{ | |
var team = teams[i]; //The team | |
var teamVehicles = vehicleRoles[i]; | |
var teamName = instance.lookup.teamName(s.gameMode, team.status); | |
var teamFlag = instance.lookup.teamFlag(teamName); | |
//Create wrapper and table for team | |
html += '<div class="as-scoreboard-wrapper" teamId = "' + team.status.teamId + '"><table class="table as-scoreboard-table" teamId="' + team.status.teamId + '">' | |
var progressBarWidth = Math.floor((team.status.tickets / team.status.ticketsMax) * 100); | |
var progressBar = '<div class="progress-bar thicker no-border ' + instance.lookup.teamType(team.status.teamId) + '" style="position: relative; display: inline-block; width: 100px; margin: 5px;"><div class="home progress-bar-inner" style="width:' + progressBarWidth + '%"></div></div>'; | |
html += '<thead>' + | |
'<tr class="as-scoreboard-details"><td colspan="7"><span style="vertical-align: top; display: inline-block; margin: 5px; bottom: 5px;">' + | |
'<img alt="flag" class="as-team-flag" src="' + teamFlag + '"></img>' + teamName + ' : ' + team.status.tickets + | |
'</span>' + progressBar + | |
'<span style="vertical-align: top; display: inline-block; margin: 5px; bottom: 5px;">Players: [' + team.players.length + '/' + (s.maxPlayers / 2).toFixed(0) + ']</span></td></tr></thead>'; | |
//HTML for table header | |
console.log("The team:"); | |
console.log(team); | |
var playerLookup = {}; | |
for (var j = 0; j < team.players.length; j++) | |
{ | |
playerLookup[team.players[j].id] = team.players[j]; | |
} | |
console.log("Player Lookup:"); | |
console.log(playerLookup); | |
//Output players | |
console.log("Team vehicles:"); | |
console.log(teamVehicles); | |
for (var k in teamVehicles) { | |
var vehiclePlayers = teamVehicles[k].topPlayers; | |
var vehicle = teamVehicles[k]; | |
console.log("Vehicle players"); | |
console.log(teamVehicles); | |
//Sort vehicle players | |
vehiclePlayers.sort(function (a, b) { | |
return a.kills == b.kills ? 0 : +(a.kills < b.kills) || -1; | |
}); | |
console.log("Okay, vehicle shit:"); | |
console.log(teamVehicles); | |
html += '<tr class="as-role-title-row"><td class="as-role-title" colspan="7"><div class="as-role-title-text">' + k + '</div><div class="vehicle small '+ vehicle.lineart + ' image"></div></td></tr>'; | |
html += '<tr><td colspan="7" style="padding: 0px;"><div class="as-role-top-players"><table style="width:100%; border: 0px;">'; | |
//For each player in that category | |
for (var l in vehiclePlayers) { | |
console.log("VehiclePlayers"); | |
console.log(vehiclePlayers) | |
var player = playerLookup[vehiclePlayers[l].personaId]; | |
console.log("PlayerLookup:"); | |
console.log(playerLookup); | |
console.log("Player"); | |
console.log(player); | |
console.log("playerLookup"); | |
console.log(playerLookup); | |
console.log("vehiclePlayers[l].personaId"); | |
console.log(vehiclePlayers[l].personaId); | |
var vehiclePlayer = vehiclePlayers[l]; | |
console.log("The Vehicle Player:"); | |
console.log(vehiclePlayer); | |
//Rank display html | |
var pRank = '<div class="bf4-rank rank small r' + vehiclePlayer.rank + ' rank_icon" data-rank="' + vehiclePlayer.rank + '"></div>' | |
//Player name including tags | |
var pName = player.tag.length > 0 ? '[' + player.tag + ']' + player.name : player.name; | |
pName = '<a href="/bf4/user/' + player.name + '/">' + pName + '</a>'; | |
//Player K/D | |
var pKD = player.deaths == 0 ? player.kills : player.kills / player.deaths; | |
//Set hilighting class | |
var hilightingType = false; | |
if (instance.storage('hilightingEnabled')) { | |
hilightingType = instance.lookup.hilightingClass(instance.storage('displayStat'), player.pDisplayStat); | |
} | |
var friends = comcenter.getFriendsListFromLs(); | |
var isFriend = false; | |
for (var k = 0; k < friends.length; k++) { | |
if (friends[k].username == player.name) { | |
isFriend = true; | |
break; | |
} | |
} | |
//Generate table row | |
html += '<tr class="as-player' + (player.id == instance.data.advancedViewPlayer ? ' as-advanced-stats-selected' : '') + (isFriend ? ' friend' : '') + (hilightingType ? ' ' + hilightingType : '') + '" personaid="' + player.id + '"><td>' + pRank + '</td><td>' + pName + '</td><td>' + player.kills + '</td><td>' + player.deaths + '</td><td>' + player.score + '</td><td>' + pKD.toFixed(2) + '</td><td>' + vehiclePlayer.kills + '</td></tr>' | |
//If a specific player is selected for the advanced view, inject the HTML here | |
if (player.id == instance.data.advancedViewPlayer) { | |
instance.debug("Creating advanced player view"); | |
html += instance.createAdvancedPlayerView(instance, player.id, true); | |
} | |
} | |
html += '</table></div></td></tr>'; | |
} | |
/*** Create tfoot from averages ***/ | |
//Average rank display html | |
var avgRank = '<div class="bf4-rank rank small r' + Math.floor(team.totalRank / team.players.length) + ' rank_icon" data-rank="' + Math.floor(team.totalRank / team.players.length) + '"></div>' | |
//Average KD | |
var avgKD = team.totalDeaths == 0 ? team.totalKills : team.totalKills / team.totalDeaths; | |
//Average pDisplayStat | |
var avgpDisplayStat = team.totalPDisplayStat == 0 ? '...' : (team.totalPDisplayStat / team.playersLoaded).toFixed(2); | |
//HTML for scoreboard foot | |
html += '<tfoot><tr class="as-scoreboard-foot"><td>' + avgRank + '</td><td></td><td>' + team.totalKills + '</td><td>' + team.totalDeaths + '</td><td>' + team.totalScore + '</td><td>' + avgKD.toFixed(2) + '</td><td>' + avgpDisplayStat + '</td></tr></tfoot>'; | |
html += '</table>' | |
html += '</div>'; | |
} | |
//Update the map name | |
var displayMap = '<img class="current-map" src="//eaassets-a.akamaihd.net/bl-cdn/cdnprefix/9c0b010cd947f38bf5e87df5e82af64e0ffdc12fh/public/base/bf4/map_images/195x79/' + s.mapName.toLowerCase() + '.jpg"></img><br><span>' + instance.data.gameServerWarsaw.mapLookup[s.mapName].label + '</span>'; | |
$("#as-scoreboard-mapinfo").html(displayMap); | |
var defaultRoundtimeSeconds = 3600; | |
var currentRoundTime = 3600 * (s.defaultRoundTimeMultiplier / 100); | |
var expiredTime = s.roundTime; | |
var secondsRemaining = currentRoundTime - expiredTime; | |
var timeLeft = Math.floor(secondsRemaining / 60) + 'M ' + (Math.round((secondsRemaining % 60) * 100) / 100) + 'S'; | |
$("span#as-time-remaining").html(timeLeft) | |
if ($("#as-scoreboard-container").is(':visible')) { | |
$("#as-scoreboard-container").html(html) | |
} else { //Catch issue with navigation | |
instance.unloadPlugin(instance); | |
instance.handler(instance); | |
} | |
var end = new Date().getTime(); | |
var time = end - start; | |
console.log("Role Scoreboard took " + time + "ms"); | |
}, | |
//Updates the round header | |
updateRoundHeader : function(instance, s) | |
{ | |
var totalPlayers = 0; | |
console.log("updating header"); | |
console.log(s); | |
for (var i = 0; i < s.teams.length; i++) | |
{ | |
var team = s.teams[i]; | |
totalPlayers += team.players.length; | |
} | |
$("#as-server-players").html(totalPlayers + '/' + s.maxPlayers + (s.queueingPlayers > 0 ? '[' + s.queueingPlayers + ']' : '')); | |
}, | |
/** | |
* Creates the HTML for the advanced player view, detailing the soldiers statistics | |
* | |
* | |
* | |
*/ | |
createAdvancedPlayerView : function(instance, personaId, displayDefault){ | |
instance.debug(instance.playerStats); | |
var html = '<tr class="as-scoreboard-advanced-stats-row"><td colspan="7">' + | |
'<div class="as-advanced-player-view"' + (displayDefault ? '' : ' style="display:none"') +'>' | |
//Ensure statistics are present locally | |
if(!instance.playerStats.hasOwnProperty(personaId)) { | |
html += '<div class="loader small"></div></div></td></tr>' | |
} else { | |
//Create stats overview here | |
var pStats = instance.playerStats[personaId]; | |
var playerName = pStats.name; | |
var timePlayed = pStats.overviewStats.timePlayed; | |
var timePlayedHours = (timePlayed/60)/60; | |
var timePlayedMinutes = (timePlayedHours - Math.floor(timePlayedHours)) * 60; | |
if (pStats.activeEmblem) { | |
var emblemPath = pStats.activeEmblem.cdnUrl; | |
emblemPath = emblemPath.replace('[SIZE]', '128'); | |
emblemPath = emblemPath.replace('[FORMAT]', 'png'); | |
} | |
//Player name, gravatar, and emblem | |
html += '<div class="as-ao-header"><span id="as-ao-name">' + pStats.name + (pStats.activeEmblem ? '</span><img class="as-ao-emblem" src="' + emblemPath + '"></img>' : '') + | |
'<button id="as-ao-join" persona-id="' + personaId + '" class="as-ao-btn btn">Join</button>' + | |
'<button id="as-ao-advanced" persona-id="' + personaId + '" class="as-ao-btn btn">Advanced</button>' + | |
'</div>'; | |
//Top kits | |
var topKits = '<table class="table as-advanced-overview-top-kits">' + | |
'<tr><th><div class="kit-icon xsmall kit-1"></div></th><th><div class="kit-icon xsmall kit-2"></div></th><th><div class="kit-icon xsmall kit-32"></div></th><th><div class="kit-icon xsmall kit-8"></div></th></tr>' + | |
'<tr><td>' + pStats.overviewStats.serviceStars["1"] + '</td><td>' + pStats.overviewStats.serviceStars["2"] + '</td><td>' + pStats.overviewStats.serviceStars["32"] + '</td><td>' + pStats.overviewStats.serviceStars["8"] + '</td>' + | |
'</table>'; | |
//Stats overviewhttp://battlelog.battlefield.com/bf4/platoons/view/3353238464465530114/ | |
console.log(pStats); | |
//Viewport | |
html += '<div class="as-ao-view">'; | |
html += '<div class="as-ao-stats">'; | |
html += '<div class="as-advanced-overview-top-stats">' + | |
'<table class="table as-advanced-overview-top-stats">' + | |
'<tr><th>Kills</th><th>Deaths</td><th>Skill</td><th>Accuracy</td></tr>' + | |
'<tr><td>' + instance.commaFormat(pStats.overviewStats.kills) + '</td><td>' + instance.commaFormat(pStats.overviewStats.deaths) + '</td><td>' + pStats.overviewStats.skill + '</td><td>' + pStats.overviewStats.accuracy.toFixed(2) + '%</td></tr>' + | |
'<tr><th>KPM</th><th>SPM</td><th>KDR</td><th>Time</td></tr>' + | |
'<tr><td>' + pStats.overviewStats.killsPerMinute + '</td><td>' + pStats.overviewStats.scorePerMinute + '</td><td>' + (pStats.overviewStats.kills/pStats.overviewStats.deaths).toFixed(2) + '</td><td>' + timePlayedHours.toFixed(0) + 'H ' + timePlayedMinutes.toFixed(0) +'M </td></tr>' + | |
'</table>'; | |
html += topKits; | |
html += '</div>' | |
//Overview Stats | |
//Overview Table | |
html += '<div class="as-advanced-overview-top-roles">' + | |
'<table class="table as-advanced-overview-top-vehicles">' + | |
'<tr><th colspan="2">Vehicle</th><th>Kills</th><th>KPM</th></tr>'; | |
//Top vehicles | |
$.each(pStats.topVehicles, function (id, vehicle) { | |
//Get vehicle name for image | |
var vehicleDisplay = window.items.game_data.compact.vehicles[vehicle.guid]; | |
vehicleDisplay = vehicleDisplay.see[0]; | |
var lineartSlug = window.items.game_data.compact.vehicles[vehicleDisplay]; | |
lineartSlug = lineartSlug.imageConfig.slug; | |
console.log(vehicle); | |
html += '<tr><td>' + vehicle.slug.toUpperCase() + '</td><td><div class="vehicle xsmall ' + lineartSlug + ' image"></div></td><td>' + instance.commaFormat(vehicle.kills) + '</td><td>' + (vehicle.kills/(vehicle.timeIn/60)).toFixed(2) + '</td></tr>' | |
}); | |
html += '</table><table class="table as-advanced-overview-top-weapons">' + | |
'<tr><th colspan="2">Weapon</th><th>Kills</th><th>Accuracy</th></tr>'; | |
$.each(pStats.topWeapons, function(id, weapon){ | |
//Get vehicle name for image | |
var weaponDisplay = window.items.game_data.compact.weapons[weapon.guid]; | |
weaponDisplay = weaponDisplay.see[0]; | |
var lineartSlug = window.items.game_data.compact.weapons[weaponDisplay]; | |
lineartSlug = lineartSlug.imageConfig.slug; | |
html += '<tr><td>' + weapon.slug.toUpperCase() + '</td><td><div class="weapon xsmall ' + lineartSlug + ' image"></div></td><td>' + instance.commaFormat(weapon.kills) + '</td><td>' + ((weapon.shotsHit / weapon.shotsFired) * 100).toFixed(2) + '%</td></tr>' | |
}); | |
html += '</table></div>'; | |
html += '</div>' | |
//End of as-ao-stats | |
//Get Dogtag Information | |
var dogtagBasic = pStats.dogTagBasic.imageConfig.slug; | |
var dogtagAdvanced = pStats.dogTagAdvanced.imageConfig.slug; | |
html += '</div>'; | |
} | |
//Test for a rough skill calculation | |
//var skillCalc = (pStats.overviewStats.scorePerMinute * pStats.overviewStats.kdRatio * pStats.overviewStats.killsPerMinute)/100 | |
//html += '<div>' + skillCalc + '</div>'; | |
return html; | |
}, | |
//Draw the advanced statistics overview | |
drawAdvancedStats : function (instance, personaId) { | |
var player = instance.playerStats[personaId]; | |
//Load the players weapon stats | |
var playerVehicleStats = {}; | |
instance.loadPlayerVehicleStats(personaId, function (data) | |
{ | |
playerVehicleStats = data.data; | |
}); | |
var playerWeaponStats = {}; | |
instance.loadPlayerWeaponStats(personaId, function (data) { | |
playerWeaponStats = data.data; | |
$("#as-container").fadeOut('slow', function () { | |
var html = '<div id="as-stats-container">' + '<button class="as-stats-close">Back</button>'; | |
html += '<h3>' + player.name + '</h3>'; | |
html += '<div class="as-stats-selectors"><button class="btn as-stats-select-weapons">Weapons</button><button class="btn as-stats-select-vehicles">Vehicles</button></div>'; | |
//Container to list possible cheating flags | |
html += '<div class="as-stats-overview">' | |
html += '<div class="as-stats-weapons">' + | |
'<table class="table as-stats-weapons-table">'; | |
html += '<tr><th>Weapon</th><th>Kills</th><th>Accuracy</th><th>HSKR</th><th>KPM</th></tr>'; | |
for (var i = 0; i < playerWeaponStats.mainWeaponStats.length; i++) | |
{ | |
var weapon = playerWeaponStats.mainWeaponStats[i]; | |
if (weapon.kills > 100) { | |
var weaponDisplay = window.items.game_data.compact.weapons[weapon.guid]; | |
weaponDisplay = weaponDisplay.see[0]; | |
var lineartSlug = window.items.game_data.compact.weapons[weaponDisplay]; | |
lineartSlug = lineartSlug.imageConfig.slug; | |
var w_accuracy = 0; | |
if (weapon.shotsFired > 0 && weapon.shotsHit > 0) { | |
w_accuracy = (weapon.shotsHit / weapon.shotsFired) * 100; | |
} | |
var w_kpm = 0; | |
if (weapon.kills > 0 && weapon.timeEquipped > 0) { | |
w_kpm = (weapon.kills / (weapon.timeEquipped / 60)); | |
} | |
var w_hskr = 0; | |
if (weapon.kills > 0 && weapon.headshots > 0) { | |
w_hskr = ((weapon.headshots / weapon.kills) * 100); | |
} | |
html += '<tr class="as-stats-weapon"><td><div class="weapon xsmall ' + lineartSlug + ' image"></div><div>' + weapon.slug.toUpperCase() + '</div></td><td>' + weapon.kills + '</td><td>' + w_accuracy.toFixed(2) + '%</td><td>' + w_hskr.toFixed(2) + '%</td><td>' + w_kpm.toFixed(2) + '</td></tr>'; | |
console.log(weapon.slug); | |
console.log(weapon); | |
} | |
} | |
html += '</table></div><div class="as-stats-vehicles" style="display: none;"><table class="table as-stats-vehicles-table">'; | |
html += '<tr><th>Vehicle</th><th>Kills</th><th>Vehicles Destroyed</th><th>KPM</th><th>Time</th></tr>'; | |
console.log(playerVehicleStats); | |
for (var i = 0; i < playerVehicleStats.mainVehicleStats.length; i++) { | |
var vehicle = playerVehicleStats.mainVehicleStats[i]; | |
if (vehicle.kills > 100) { | |
var vehicleDisplay = window.items.game_data.compact.vehicles[vehicle.guid]; | |
vehicleDisplay = vehicleDisplay.see[0]; | |
var lineartSlug = window.items.game_data.compact.vehicles[vehicleDisplay]; | |
lineartSlug = lineartSlug.imageConfig.slug; | |
var v_vehiclesDestroyed = 0; | |
if (vehicle.destroyXinY > 0) { | |
v_vehiclesDestroyed = vehicle.destroyXinY; | |
} | |
var v_kpm = 0; | |
if (vehicle.timeIn > 0 && vehicle.kills > 0) | |
{ | |
v_kpm = (vehicle.kills / (vehicle.timeIn / 60)); | |
} | |
var v_time = (vehicle.timeIn / 60).toFixed(2); | |
html += '<tr class="as-stats-vehicle"><td><div class="vehicle xsmall ' + lineartSlug + ' image"></div><div>' + vehicle.slug.toUpperCase() + '</div></td><td>' + vehicle.kills + '</td><td>' + v_vehiclesDestroyed + '</td><td>' + v_kpm.toFixed(2) + '%</td><td>' + v_time + '</td></tr>'; | |
} | |
} | |
html += '</table></div></div>'; | |
$("#serverbrowser-page").after(html); | |
console.log(playerWeaponStats); | |
console.log(playerVehicleStats); | |
}); | |
}); | |
}, | |
drawSettings : function(instance) { | |
var html = '<div id="as-settings-container"><header class="as-settings-header"><h1>' + instance.t("settings-title") + '</h1></header>' + | |
'<div id="as-settings-options">'; | |
//Get the settings | |
console.log(instance.storage('hilightingEnabled')); | |
var hilightingEnabled = instance.storage('hilightingEnabled') ? (instance.storage('hilightingEnabled') == true ? true : false) : false; | |
/** Check box for the live update **/ | |
html += '<table class="as-settings-table">' + | |
'<tr><td class="as-settings-table-header" colspan="3">General</td></tr>' + | |
'<tr><th>Live Scoreboard</h><td>' + | |
'<div class="switch-container pull-right clearfix">' + | |
'<div class="switch pull-left">' + | |
'<input type="checkbox" id="as-enable-live" name="as-enable-live" value="' + instance.storage('liveEnabled').toString() + '" ' + (instance.storage('liveEnabled') == true ? 'checked' : '') + '>' + | |
'<div class="handle"></div>' + | |
'</div>' + | |
'</div></td>' + | |
'<td class="option-description">Determines whether or not the scoreboard automatically updates as the game progresses</td>' + | |
'</tr>' + | |
'<tr><th>Hilighting</th><td>' + | |
'<div class="switch-container pull-right clearfix">' + | |
'<div class="switch pull-left">' + | |
'<input type="checkbox" id="as-enable-hilighting" name="as-enable-hilighting" value="' + hilightingEnabled.toString() + '" ' + (hilightingEnabled == true ? 'checked' : '') + '>' + | |
'<div class="handle"></div>' + | |
'</div>' + | |
'</div></td>' + | |
'<td class="option-description">Enables hilighting based off the strength of player statistics</td>' + | |
'</tr>' + | |
'<tr><th>Polling Rate (ms)</th><td><input id="as-polling-rate" type="number" name="as-polling-rate" value="' + instance.storage('pollingIntervalMs').toString() + '"></td>' + | |
'<td class="option-description">The frequency the scoreboard queries the gameserver for information. 5000ms is the default</td>' + | |
'</tr>'; | |
html += '</table>'; | |
/** Input field for polling rate **/ | |
/** Check box for hilighting **/ | |
$('#as-scoreboard-container').html(html); | |
}, | |
/** | |
* Draws settings HTML | |
* | |
*/ | |
renderSettings : function(instance){ | |
var html = ''; | |
html += '<div id="advs_scoreboard_settings">'; | |
html += '<h4 class="advs_title">' + instance.t("settings-title") + '</h4>'; | |
/** Check box for live update **/ | |
html += '<div class="as-settings-option"><label class="as-settings-label" for="as-enable-live">Live Scoreboard</label>'; | |
html += '<input id="as-enable-live" type="checkbox" name="as-enable-live" value="'+ instance.storage('liveEnabled').toString() +'" '+ (instance.storage('liveEnabled') == true ? 'checked' : '') + '>'; | |
html += '</div>'; | |
/** Check box for hilighting **/ | |
html += '<div class="as-settings-option"><label class="as-settings-label" for="as-enable-hilighting">Enable Hilighting</label>'; | |
html += '<input id="as-enable-hilighting" type="checkbox" name="as-enable-hilighting" value="'+ instance.storage('hilightingEnabled').toString() +'" '+ (instance.storage('hilightingEnabled') == true ? 'checked' : '') + '>'; | |
html += '</div>'; | |
/** Check box for hilighting friends **/ | |
html += '<div class="as-settings-option"><label class="as-settings-label" for="as-enable-friend-hilighting">Hilight Friends</label>'; | |
html += '<input id="as-enable-friend-hilighting" type="checkbox" name="as-enable-friend-hilighting" value="'+ instance.storage('hilightFriends').toString() +'" '+ (instance.storage('hilightFriends') == true ? 'checked' : '') + '>'; | |
html += '</div>'; | |
/** **/ | |
html += '<div class="as-about" style="font-size: 10px;"><p>Advanced Scoreboard 0.1.1 Beta</p><p>Developed by Cr1N</p></div>'; | |
html += '</div>'; | |
$("#content").append(html); | |
}, | |
drawRoundInfo : function(instance) | |
{ | |
var serverHeader = '<div id="as-scoreboard-roundinfo">'; | |
serverHeader += '<div id="as-scoreboard-mapinfo"></div>'; | |
serverHeader += '<div id="as-scoreboard-round-properties">' + | |
'<div><span>Players : </span><span id="as-server-players"></span></div>' + | |
'<div><span>Time : </span><span id="as-server-time-remaining"></span></div>' + | |
'</div>'; | |
serverHeader += '<div id="as-scoreboard-options">' + | |
'<div class="as-sort-option"><label class="as-settings-label" for="as-select-display-stat">Show: </label><select id="as-select-display-stat">'; | |
var existingDisplayStat = instance.storage('displayStat'); | |
var customStats = ['skill', 'kdRatio', 'kills', 'deaths', 'strength']; | |
for(var i = 0; i < customStats.length; i++) | |
{ | |
if(customStats[i] !== existingDisplayStat) { | |
serverHeader += '<option value="' + customStats[i] + '">' + instance.lookup.displayStat(customStats[i]) + '</option>'; | |
} else { | |
serverHeader += '<option value="' + customStats[i] + '" selected>' + instance.lookup.displayStat(customStats[i]) + '</option>'; | |
} | |
} | |
serverHeader += '</select></div></div>'; | |
return serverHeader; | |
}, | |
drawSelectors : function(instance) { | |
var selectors = [ | |
{ htmlId: 'as-show-players', htmlText: 'Show Players', drawMode: 'player' }, | |
{ htmlId: 'as-show-squads', htmlText: 'Show Squads', drawMode: 'squad' }, | |
{ htmlId: 'as-show-roles', htmlText: 'Show Vehicles', drawMode: 'role' }, | |
{ htmlId: 'as-show-charts', htmlText: 'Show Charts', drawMode: 'charts' }, | |
]; | |
selectorHtml = '<div id="as-scoreboard-selectors">'; | |
for (var i = 0; i < selectors.length; i++) { | |
var selector = selectors[i]; | |
selectorHtml += '<button class="btn view-selector ' + (instance.data.drawMode === selector.drawMode ? 'btn-primary' : '') + '" id="' + selector.htmlId + '">' + selector.htmlText + '</button>'; | |
} | |
selectorHtml += '<button class="btn view-selector" id="as-settings">Settings</button>'; | |
selectorHtml += '</div>'; | |
return selectorHtml; | |
}, | |
/** | |
* Simple debugging | |
* | |
* @param msg Debug message | |
*/ | |
debug: function(msg) { | |
if(true) | |
console.log(msg); | |
}, | |
/** | |
* Returns JSON object containing server attributes extracted from the DOM | |
* | |
* @return JSON object containing server data | |
*/ | |
getServerAttributes : function() { | |
var $joinMpServerButton = $("#server-page-join-buttons"); | |
var server = { | |
ip: $joinMpServerButton.data("ip"), | |
gameId: $joinMpServerButton.attr("data-gameid"), | |
port: $joinMpServerButton.data("port"), | |
game: $joinMpServerButton.data("game"), | |
guid: $joinMpServerButton.data("guid") | |
}; | |
return server; | |
}, | |
/** | |
* Returns scoreboard data from the game server | |
* | |
* @callback callback Callback function | |
* @param serverInfo Server information in JSON format | |
* | |
*/ | |
queryServerScoreboard : function(serverInfo, callback) { | |
launcher.queryServer(serverInfo, function(queryInfo) { | |
if(!queryInfo) { | |
console.log("Could not obtain query info from the server!"); | |
} else { | |
if(queryInfo.status == "OK") { | |
callback(queryInfo.result) | |
} else { | |
$("#as-scoreboard-container").html('<div class="as-scoreboard-roundfinished">Round is over. Waiting for next round to start...</div>'); | |
console.log("Round has not started"); | |
} | |
} | |
}); | |
}, | |
/** | |
* Checks for players who don't't have their statistics cached and fetches them | |
* | |
* @param scoreboardData Scoreboard data from the game server | |
* @param instance Plugin instance | |
* | |
*/ | |
updatePlayerStats: function (instance, scoreboardData) | |
{ | |
var updatePlayers = []; | |
var toLoad = 0; | |
var loaded = 0; | |
//For each team | |
$.each(scoreboardData.teams, function (teamID, team) { | |
$.each(team.players, function (playerId, player) { | |
if (!instance.playerStats.hasOwnProperty(player.personaId)) { | |
toLoad++; | |
} | |
}); | |
}); | |
$.each(scoreboardData.teams, function (teamID, team) | |
{ | |
//For each player in the team | |
$.each(team.players, function (playerID, player) | |
{ | |
//Only load the statistics if they are not already present in the database | |
if (!instance.playerStats.hasOwnProperty(player.personaId)) { | |
var playerName = player.tag ? '[' + player.tag + ']' + player.name : player.name; | |
instance.loadPlayerStats(player.personaId, playerName, function (overviewStats, playerName) | |
{ | |
instance.playerStats[player.personaId] = overviewStats.data; | |
instance.playerStats[player.personaId]["name"] = playerName; | |
loaded++; | |
if (loaded == toLoad) { | |
instance.updateHTML(instance); | |
} | |
}) | |
} | |
}); | |
}) | |
}, | |
/** | |
* Return player status | |
* | |
* @callback callback Callback function | |
* @param personaId Persona ID of the player to be queried | |
* | |
*/ | |
loadPlayerStats: function (personaId, playerName, callback) | |
{ | |
$.ajax({ | |
url: "http://battlelog.battlefield.com/bf4/warsawoverviewpopulate/" + personaId + "/1/", | |
type: 'GET', | |
async: true, | |
cache: false, | |
timeout: 30000, | |
success: function(data) { | |
callback(data, playerName); | |
} | |
}); | |
}, | |
/** | |
* Returns a players weapon stats | |
* | |
* @callback callback Callback function | |
* @param personaId Persona ID of the player to fetch | |
*/ | |
loadPlayerWeaponStats: function (personaId, callback) | |
{ | |
$.ajax({ | |
url: "http://battlelog.battlefield.com/bf4/warsawWeaponsPopulateStats/" + personaId + "/1/stats/", | |
type: 'GET', | |
async: true, | |
cache: false, | |
timeout: 30000, | |
success: function(data) { | |
callback(data); | |
} | |
}); | |
}, | |
/** | |
* Returns a players vehicle stats stats | |
* | |
* @callback callback Callback function | |
* @param personaId Persona ID of the player to fetch | |
*/ | |
loadPlayerVehicleStats : function(personaId, callback) | |
{ | |
$.ajax({ | |
url: "http://battlelog.battlefield.com/bf4/warsawvehiclesPopulateStats/" + personaId + "/1/stats/", | |
type: 'GET', | |
async: true, | |
cache: false, | |
timeout: 30000, | |
success: function (data) { | |
callback(data); | |
} | |
}); | |
}, | |
lookup : { | |
displayStat : function(displayStatValue){ | |
var displayStatsLookup = { | |
'skill' : 'Skill', | |
'kdRatio' : 'K/D (G)', | |
'kills' : 'Kills', | |
'deaths': 'Deaths', | |
'strength' : 'Strength' | |
}; | |
return displayStatsLookup[displayStatValue]; | |
}, | |
teamName : function(gameMode, status) { | |
if(gameMode == 2) return status.teamType.charAt(0).toUpperCase() + status.teamType.slice(1); | |
var factions = ["US", "RU", "CN"]; | |
return factions[status.faction]; | |
}, | |
teamType : function(teamId) { | |
if(teamId == 1) { | |
var type = 'home' | |
} else { | |
var type = 'away'; | |
} | |
return type; | |
}, | |
teamFlag : function(teamName) | |
{ | |
var urlPrefix = "http://eaassets-a.akamaihd.net/bl-cdn/cdnprefix/2e8fa20e7dba3f4aecb727fc8dcb902f1efef569b/public/common/flags/"; | |
if (teamName == "US" || teamName == "RU" || teamName == "CN") { | |
return urlPrefix + teamName.toLowerCase() + '.gif'; | |
} else { | |
return false | |
} | |
}, | |
squadName : function(squadId) { | |
var squads = ["No Squad", "Alpha", "Bravo", "Charlie", "Delta", "Echo", "Foxtrot", "Golf", "Hotel", "India", "Juliett", "Kilo", "Lima", "Mike"]; | |
return squads[squadId]; | |
}, | |
gameMode: function (mode) | |
{ | |
var gameModes = { 2: "Rush", 64: "Conquest Large" } | |
if( gameModes.hasOwnProperty(mode) ) { | |
return gameModes[mode]; | |
} else { | |
return "Unknown Gamemode"; | |
} | |
}, | |
/* | |
* Match the players stat to a hilighting class based on a defined statistic | |
* | |
*/ | |
hilightingClass: function (displayStat, pDisplayStat) { | |
if (displayStat == 'kdRatio') { | |
if (pDisplayStat < 1) { | |
hilightingType = 'low'; | |
} else if (pDisplayStat < 2) { | |
hilightingType = 'average'; | |
} else if (pDisplayStat < 3) { | |
hilightingType = 'good'; | |
} else if (pDisplayStat < 4) { | |
hilightingType = 'high'; | |
} else if (pDisplayStat < 5) { | |
hilightingType = 'v-high'; | |
} else if (pDisplayStat >= 5) { | |
hilightingType = 'pro'; | |
} | |
} else if (displayStat == 'skill') { | |
if (pDisplayStat < 200) { | |
hilightingType = 'low'; | |
} else if (pDisplayStat < 300) { | |
hilightingType = 'average'; | |
} else if (pDisplayStat < 400) { | |
hilightingType = 'good'; | |
} else if (pDisplayStat < 550) { | |
hilightingType = 'high'; | |
} else if (pDisplayStat >= 550) { | |
hilightingType = 'v-high'; | |
} | |
} | |
else if (displayStat == 'strength') { | |
if (pDisplayStat < 200) { | |
hilightingType = 'low'; | |
} else if (pDisplayStat < 300) { | |
hilightingType = 'average'; | |
} else if (pDisplayStat < 400) { | |
hilightingType = 'good'; | |
} else if (pDisplayStat < 550) { | |
hilightingType = 'high'; | |
} else if (pDisplayStat >= 550) { | |
hilightingType = 'v-high'; | |
} | |
} | |
return hilightingType; | |
} | |
}, | |
sortBy : function(field, reverse, primer) | |
{ | |
var key = function (x) {return primer ? primer(x[field]) : x[field]}; | |
return function (a,b) { | |
var A = key(a), B = key(b); | |
return ( (A < B) ? -1 : ((A > B) ? 1 : 0) ) * [-1,1][+!!reverse]; | |
} | |
}, | |
commaFormat : function(number) | |
{ | |
return number.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ","); | |
}, | |
/** | |
* | |
* Unloads plugin by clearing variables and intervals | |
* | |
* @param instance Plugin Instance | |
*/ | |
unloadPlugin : function(instance) { | |
//Clear interval | |
if(instance.data.asLiveUpdate) { | |
clearInterval(instance.data.asLiveUpdate); | |
} | |
//instance.data.latestScoreboardData = {}; | |
instance.data.advancedViewPlayer = 0; | |
instance.data.asLiveUpdate = false; | |
instance.data.pluginLoaded = false; | |
instance.data.currentChart = false; | |
for(var tracked in instance.data.tracker) | |
{ | |
instance.data.tracker[tracked] = {}; | |
} | |
instance.debug("Plugin unloaded") | |
} | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment