Skip to content

Instantly share code, notes, and snippets.

@ghostiam
Last active December 17, 2018 09:59
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ghostiam/dbbca3404e048dbaec5c87b2124dc64b to your computer and use it in GitHub Desktop.
Save ghostiam/dbbca3404e048dbaec5c87b2124dc64b to your computer and use it in GitHub Desktop.
Battlelog battlefield 4: true player count userscript
// ==UserScript==
// @name Battlelog keeper fixer
// @namespace battlelog
// @version 0.1
// @description Changes the keeper endpoint to https one so the match info and scoreboard starts working again
// @author xfileFIN
// @match http://battlelog.battlefield.com/bf4/*
// @match https://battlelog.battlefield.com/bf4/*
// @grant none
// ==/UserScript==
(function() {
'use strict';
S.globalContext.staticContext.keeperQueryEndpoint = "https://keeper.battlelog.com."
})();
// ==UserScript==
// @name Battlelog True Player Counts
// @namespace battlelog
// @version 0.9
// @description Shows the true player count on the server.
// @author ghostiam
// @source https://gist.github.com/ghostiam/dbbca3404e048dbaec5c87b2124dc64b
// @updateURL https://gist.github.com/ghostiam/dbbca3404e048dbaec5c87b2124dc64b/raw/BattlelogTruePlayerCounts.user.js
//
// @match http://battlelog.battlefield.com/bf4/*
// @match https://battlelog.battlefield.com/bf4/*
// @grant GM_addStyle
// ==/UserScript==
(function() {
'use strict';
// Settings
const hideServerMinPlayersCount = 0 // Change me, if you need. "-1" - not hidded servers
const useRealPlayersCountSorting = true
const diffCountLow = 2
const diffCountMid = 5
const diffColorLow = "#39b54a"
const diffColorMid = "#99b839"
const diffColorHigh = "#ff0000"
const teamsColor = ["", "#94cdf3", "#ff9f80", "", ""]
//
function sizeObject(obj) {
var size = 0, key;
for (key in obj) {
if (obj.hasOwnProperty(key)) size++;
}
return size;
};
function loadServerInfo(guid, snapshotCallback) {
var endpoint = "https://keeper.battlelog.com." // or - S.globalContext.staticContext.keeperQueryEndpoint
var url = endpoint + "/snapshot/" + guid
fetch(url).then(function(r){
return r.json()
}).then(function(r){
return r.snapshot
}).then(snapshotCallback)
}
function showPlayesCount(el, showingCount, realCount) {
var diff = Math.abs(showingCount - realCount);
var color = diffColorHigh
if (diff <= diffCountLow) {
color = diffColorLow
}
if (diff <= diffCountMid) {
color = diffColorMid
}
// find exist div
var div = el.querySelector(".realPlayersCount")
// create new div if not exist
if (!div) {
div = document.createElement('div');
div.className = "realPlayersCount"
// el.appendChild(div)
el.insertBefore(div, el.firstChild)
}
// update info in DOM
div.style.color = color
div.innerHTML = realCount
}
function showRoundInfo(el, snapshot) {
// find exist div
var div = el.querySelector(".roundInfo")
// create new div if not exist
if (!div) {
div = document.createElement('div');
div.className = "roundInfo"
el.appendChild(div)
}
// update info in DOM
var inner = "<span>"
// conquest
for(let key in snapshot.conquest) {
inner += "<span style=\"color: "+teamsColor[key]+"\">"
+ snapshot.conquest[key].tickets + "/" + snapshot.conquest[key].ticketsMax
+ "</span> | "
}
// deathmatch
for(let key in snapshot.deathmatch) {
if (snapshot.teamInfo[key] && sizeObject(snapshot.teamInfo[key].players)) {
inner += "<span style=\"color: "+teamsColor[key]+"\">"
+ snapshot.deathmatch[key].kills + "/" + snapshot.deathmatch[key].killsMax
+ "</span> | "
}
}
// captureTheFlag
for(let key in snapshot.captureTheFlag) {
inner += "<span style=\"color: "+teamsColor[key]+"\">"
+ snapshot.captureTheFlag[key].flags + "/" + snapshot.captureTheFlag[key].flagsMax
+ "</span> | "
}
// carrierAssault
for(let key in snapshot.carrierAssault) {
inner += "<span style=\"color: "+teamsColor[key]+"\">"
+ snapshot.carrierAssault[key].destroyedCrates + "/" + snapshot.carrierAssault[key].carrierHealth + "%"
+ "</span> | "
}
// rush
if(snapshot.rush) {
inner += "<span style=\"color: "+teamsColor[1]+"\">"
+ snapshot.rush.attackers.tickets + "/" + snapshot.rush.attackers.ticketsMax
+ "</span> | "
inner += "<span style=\"color: "+teamsColor[2]+"\">"
+ snapshot.rush.defenders.bases + "/" + snapshot.rush.defenders.basesMax
+ "</span> | "
}
// gunmaster
if(snapshot.gunmaster) {
let maxPlayerLevel = 0
for(let key in snapshot.gunmaster) {
if (key != "max_level" && snapshot.gunmaster[key] > maxPlayerLevel) maxPlayerLevel = snapshot.gunmaster[key]
}
inner += maxPlayerLevel + "/" + snapshot.gunmaster.max_level
}
inner += "</span>"
div.innerHTML = inner
}
function playersCount(teamInfo) {
var totalPlayers = 0
for(var i in teamInfo) {
var players = teamInfo[i].players
for(var key in players) {
totalPlayers++
}
}
return totalPlayers
}
function updatePlayersCountByElement(el) {
var guid = el.getAttribute("data-guid")
loadServerInfo(guid, function(snapshot) {
var showingCount = parseInt(el.querySelector(".players > .occupied").textContent)
var realCount = playersCount(snapshot.teamInfo)
if (realCount <= hideServerMinPlayersCount) {
el.style.display = "none"
return
}
showPlayesCount(el.querySelector(".players"), showingCount, realCount)
// Set data for sorter
if (useRealPlayersCountSorting) {
$(el).data("server").slots[2].current = realCount
}
var m = el.querySelector(".server .server-details")
showRoundInfo(m, snapshot)
})
}
function updatePlayersCountOnServerPage() {
var el = document.querySelector("#server-page")
if (el == null) {
return
}
var guid = el.getAttribute("data-guid")
loadServerInfo(guid, function(snapshot) {
var sec = el.querySelector("#server-page-info > div:nth-child(2) > div:nth-child(1) > section")
var showingCount = parseInt(sec.querySelector("h5").textContent)
showPlayesCount(sec, showingCount, playersCount(snapshot.teamInfo))
})
}
function observeDOM() {
function isUpdatedDOMServerInfo(mutation) {
var isServerRow = mutation.target.className.includes("server-row")
var isAdded = mutation.addedNodes.length > 0
return isServerRow && isAdded
}
function isNewDOMServerInfo(mutation) {
var isTableBody = mutation.target.nodeName == "TBODY"
var isAddedServerRow = false
if (isTableBody && mutation.addedNodes.length > 0) {
isAddedServerRow = mutation.addedNodes.item(0).className.includes("server-row")
}
return isTableBody && isAddedServerRow
}
function isOpenServerPage(mutation) {
var isContent = mutation.target.className == "content"
var isServerPage = false
if (isContent && mutation.addedNodes.length > 0) {
mutation.addedNodes.forEach(function(node) {
if (node.id == "server-page") {
isServerPage = true
}
})
}
return isContent && isServerPage
}
var targetNode = document.querySelector("#base-container #content");
var observer = new MutationObserver(function(mutationList) {
mutationList.forEach((mutation) => {
if (isUpdatedDOMServerInfo(mutation)) {
//console.log("isUpdatedDOMServerInfo", mutation)
updatePlayersCountByElement(mutation.target)
}
else if(isNewDOMServerInfo(mutation)) {
//console.log("isNewDOMServerInfo", mutation)
mutation.addedNodes.forEach(function(el){
updatePlayersCountByElement(el)
})
}
else if (isOpenServerPage(mutation)) {
//console.log("isOpenServerPage", mutation)
updatePlayersCountOnServerPage()
} else {
// for debuging
/*if(!mutation.target.className.includes("ping") && !mutation.target.className.includes("realPlayersCount") && !mutation.target.className.includes("players")) {
console.log("just", mutation)
}*/
}
})
});
var config = { childList: true, subtree: true };
observer.observe(targetNode, config);
}
// update all after load
document.querySelectorAll(".server-row").forEach(function(el){
updatePlayersCountByElement(el)
})
// update player count if server page opened
updatePlayersCountOnServerPage()
// start observe
observeDOM()
GM_addStyle(`
#server-page-info .realPlayersCount {
padding-top: 10px;
font-size: 22px;
}
#serverbrowser .servers-list tbody .server-row td.players {
line-height: 20px;
}
`)
})();
@ghostiam
Copy link
Author

default

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment