Find out prices of items in your inventory by hovering over them while at the Marketplace
// ==UserScript==
// @name Marketplace Hover Prices
// @namespace http://tampermonkey.net/
// @version 3.1
// @description Find out prices of items in your inventory by hovering over them while at the Marketplace
// @author SilverBeam
// @match https://fairview.deadfrontier.com/onlinezombiemmo/index.php?page=35
// ==/UserScript==
(function() {
'use strict';
function parseAmmo(ammo){
let resp = "";
switch(ammo){
case '32ammo': resp = '.32 Handgun Bullets'; break;
case '35ammo': resp = '9 mm Handgun Bullets'; break;
case '38ammo': resp = '.38 Handgun Bullets'; break;
case '40ammo': resp = '.40 Handgun Bullets'; break;
case '357ammo': resp = '.357 Handgun Bullets'; break;
case '45ammo': resp = '.45 Handgun Bullets'; break;
case '50ammo': resp = '.50 Handgun Bullets'; break;
case '55ammo': resp = '.55 Handgun Bullets'; break;
case '55rifleammo': resp = '5.5mm Rifle Bullets'; break;
case '75rifleammo': resp = '7.5mm Rifle Bullets'; break;
case '9rifleammo': resp = '9mm Rifle Bullets'; break;
case '127rifleammo': resp = '12.7mm Rifle Bullets'; break;
case '14rifleammo': resp = '14mm Rifle Bullets'; break;
case '12gaugeammo': resp = '12 Gauge Shells'; break;
case '16gaugeammo': resp = '16 Gauge Shells'; break;
case '20gaugeammo': resp = '20 Gauge Shells'; break;
case '10gaugeammo': resp = '10 Gauge Shells'; break;
case 'heavygrenadeammo': resp = 'Heavy Grenades'; break;
case 'grenadeammo': resp = 'Grenades'; break;
default: resp = 'Sum Ting Wong';
}
return resp;
}
function capitalizeFirstLetter(string) {
return string.charAt(0).toUpperCase() + string.slice(1);
}
function fillDataBank(id,extraInfo,name,type){
let found = false;
//console.log("Entering dataBank fill with: "+dataBank);
for(let x of dataBank){
if(x.id == id){
found = true;
break;
}
}
if(!found){
let item = {};
item.id = id;
item.extraInfo = extraInfo;
item.name = name;
item.type = type;
dataBank.push(item);
}
}
function filterParams(vars){
let tmp = {};
let globData = {};
let category = "";
occupiedInvSlots = 0;
tmp.tradeZone = vars.DFSTATS_df_tradezone;
tmp.slotNum = parseInt(vars.DFSTATS_df_invslots);
tmp.invArr = [];
for(let i=1;i<=tmp.slotNum;i++){
let item = {};
let baseItemId;
item.id = vars["DFSTATS_df_inv" + i + "_type"];
item.extraInfo = "";
item.type = "";
if(item.id.indexOf("_") != -1){
item.extraInfo = capitalizeFirstLetter(item.id.split("_")[1]);
item.id = item.id.split("_")[0];
}
if(item.id != ""){
if(item.id.indexOf("ammo") != -1){
item.code = "";
item.name = parseAmmo(item.id);
item.quantity = parseInt(vars["DFSTATS_df_inv" + i + "_quantity"]);
item.type = "Ammo";
}else{
globData = globalData[item.id];
category = globData.itemcat;
if(category == "armour"){ //Check the item is an armor
item.code = globData.code;
item.name = globData.name;
item.quantity = 1;
item.type = "Armour";
}else if(category == "weapon"){ //Check if the item is a weapon
item.code = globData.code;
item.name = globData.name;
item.quantity = parseInt(vars["DFSTATS_df_inv" + i + "_quantity"]);
item.type = "Weapon";
}else{ //Default to item or implant
item.code = globData.code;
item.name = globData.name;
if(item.extraInfo){
item.name = item.extraInfo + " " + item.name;
}
item.quantity = parseInt(vars["DFSTATS_df_inv" + i + "_quantity"]);
item.type = "Item";
}
}
fillDataBank(item.id,item.extraInfo,item.name,item.type);
occupiedInvSlots += 1;
}else{
item.code = "";
item.name = "";
item.quantity = 0;
}
//console.log(item);
tmp.invArr.push(item);
}
//console.log("Params:");
//console.log(tmp);
return tmp;
}
function removeInvItem(index){
//console.log("Deleting index "+index+" in ");
//console.log(params);
params.invArr[index].id = "";
params.invArr[index].extraInfo = "";
params.invArr[index].code = "";
params.invArr[index].name = "";
delete params.invArr[index].bestPricePerUnit;
delete params.invArr[index].averagePricePerUnit;
}
function requestItem(tradezone,data,items){
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
data.rawServerResponse = this.responseText;
//console.log("Logging item: "+data.name);
//console.log(data);
filterResponseText(data);
updateParams(data,items);
requestsCompleted += 1;
//console.log(requestsCompleted);
if(requestsCompleted >= requestsNum){console.log(dataBank);console.log(items);requestsAllDone = 1;}
//console.log(calculateAvailableOffers(this.responseText));
}
};
let itemName = data.name;
if(data.extraInfo.indexOf("Colour") != -1){
itemName = itemName.split(" ")[1];
}
xhttp.open("POST", "trade_search.php", true);
xhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
xhttp.send("hash=16cc837c932e96f694b012566cddec40&pagetime=1558282908&tradezone="+tradezone+"&searchname="+encodeURI(itemName.substring(0,15))+"&category=&profession=&memID=&searchtype=buyinglistitemname&search=trades");
//console.log("hash=16cc837c932e96f694b012566cddec40&pagetime=1558282908&tradezone="+tradezone+"&searchname="+encodeURI(item.name)+"&category=&profession=&memID=&searchtype=buyinglistitemname&search=trades");
}
function requestInvItems(items,databank){
requestsNum = databank.length;
for(let i=0;i<databank.length;i++){
if(databank[i].name != ""){
requestItem(items.tradeZone,databank[i],items);
}else{
databank[i].rawServerResponse = "";
}
}
}
function calculateAvailableOffers(resp){
let matches = resp.match(/tradelist_[0-9]+_trade_id=/g);
if(matches != null){
return matches.length;
}else{
return 0;
}
}
function filterResponseText(item){
let itemRawResponse = item.rawServerResponse;
if(itemRawResponse != ""){
let maxTrades = calculateAvailableOffers(itemRawResponse);
let firstOccurence;
if(itemRawResponse.indexOf("tradelist_maxresults=0") == -1){
if(item.extraInfo != ""){
firstOccurence = parseInt(itemRawResponse.match(new RegExp("tradelist_[0-9]+_item="+item.id))[0].split("=")[0].match(/[0-9]+/)[0]);
}else{
firstOccurence = parseInt(itemRawResponse.match(new RegExp("tradelist_[0-9]+_item="+item.id+"&"))[0].split("=")[0].match(/[0-9]+/)[0]);
}
}else{
firstOccurence = 1;
}
let availableTrades = maxTrades - firstOccurence + 1;
let avgPrice = 0;
let examinedTrades = 0;
for(;(examinedTrades<availableTrades)&&(examinedTrades<10);examinedTrades++){
//console.log("Examination "+examinedTrades);
let pricePerUnit;
if(item.type == "Armour"){
pricePerUnit = parseInt(itemRawResponse.match(new RegExp("tradelist_"+(firstOccurence+examinedTrades)+"_price=[0-9]+&"))[0].split("=")[1].match(/[0-9]+/)[0]);
}else{
pricePerUnit = parseInt(itemRawResponse.match(new RegExp("tradelist_"+(firstOccurence+examinedTrades)+"_price=[0-9]+&"))[0].split("=")[1].match(/[0-9]+/)[0]) /
parseInt(itemRawResponse.match(new RegExp("tradelist_"+(firstOccurence+examinedTrades)+"_quantity=[0-9]+&"))[0].split("=")[1].match(/[0-9]+/)[0]);
}
avgPrice += pricePerUnit;
if(examinedTrades == 0){
item.bestPricePerUnit = pricePerUnit;
}
}
item.averagePricePerUnit = avgPrice / examinedTrades;
if(avgPrice == 0 && examinedTrades == 0){
item.averagePricePerUnit = 0;
item.bestPricePerUnit = 0;
}
//console.log(item.id +": "+item.averagePricePerUnit+" "+item.bestPricePerUnit);
}
}
function updateParams(data,params){
for(let x of params.invArr){
if(x.id == data.id){
x.bestPricePerUnit = data.bestPricePerUnit;
x.averagePricePerUnit = data.averagePricePerUnit;
}
}
}
function swapInvSlots(from,to){
let tmp = params.invArr[to];
params.invArr[to] = params.invArr[from];
params.invArr[from] = tmp;
}
function addSlotEnterListeners(){
for(let i=0;i<params.slotNum;i++){
let slot = document.getElementsByClassName("validSlot")[i];
slot.addEventListener("mouseenter",mouseEnterHandler);
}
}
function mouseEnterHandler(e){
let slot = e.target.dataset.slot;
if(params.invArr[slot-1].id != "" && lastSlotHovered != slot){
lastSlotHovered = slot;
setTimeout(function(){fillHoverBox(slot);},40);
}
}
function fillHoverBox(cellNum){
let blank = document.createElement("div");
blank.className = "itemData";
blank.innerHTML = "Silver Stats";
blank.style.opacity = 0;
infoBox.appendChild(blank);
let bpu = document.createElement("div");
bpu.className = "itemData";
bpu.innerHTML = "Best price per unit: " + params.invArr[cellNum-1].bestPricePerUnit.toFixed(2);
infoBox.appendChild(bpu);
let bps = document.createElement("div");
bps.className = "itemData";
bps.innerHTML = "Best price this stack: " + (params.invArr[cellNum-1].bestPricePerUnit*params.invArr[cellNum-1].quantity).toFixed(2);
infoBox.appendChild(bps);
let apu = document.createElement("div");
apu.className = "itemData";
apu.innerHTML = "Average price per unit: " + params.invArr[cellNum-1].averagePricePerUnit.toFixed(2);
infoBox.appendChild(apu);
let aps = document.createElement("div");
aps.className = "itemData";
aps.innerHTML = "Average price this stack: " + (params.invArr[cellNum-1].averagePricePerUnit*params.invArr[cellNum-1].quantity).toFixed(2);
infoBox.appendChild(aps);
}
//////////////////////////////////////
//Meaty Deposit/Withdraw integration//
//////////////////////////////////////
function addDepositFocusListener(event){
document.addEventListener("keydown",depositListener,false);
}
function addDepositFocusOutListener(event){
document.removeEventListener("keydown",depositListener,false);
}
function depositListener(e){
let key = e.key || e.keyIdentifier;
if(key != "Enter"){
return;
}
let input;
let inputs = document.getElementsByTagName("input");
for (let i=0;i<inputs.length;i++){
input = inputs[i];
if(input.type == "button" && input.value=="Deposit"){
input.click();
break;
}
}
}
function addWithdrawFocusListener(event){
document.addEventListener("keydown",withdrawListener,false);
}
function addWithdrawFocusOutListener(event){
document.removeEventListener("keydown",withdrawListener,false);
}
function withdrawListener(e){
let key = e.key || e.keyIdentifier;
if(key != "Enter"){
return;
}
let input;
let inputs = document.getElementsByTagName("input");
for (let i=0;i<inputs.length;i++){
input = inputs[i];
if(input.type == "button" && input.value=="Withdraw"){
input.click();
break;
}
}
}
function addMeatyIntegration(){
let input;
let inputs = document.getElementsByTagName("input");
for (let i=0;i<inputs.length;i++){
input = inputs[i];
if(input.type == "button" && input.value=="Deposit"){
input.parentNode.firstChild.addEventListener("focus",addDepositFocusListener,true);
input.parentNode.firstChild.addEventListener("focusout",addDepositFocusOutListener,true);
}else if(input.type == "button" && input.value=="Withdraw"){
input.parentNode.firstChild.addEventListener("focus",addWithdrawFocusListener,true);
input.parentNode.firstChild.addEventListener("focusout",addWithdrawFocusOutListener,true);
}
}
}
//////////////////////////////////////
function startScript(){
requestInvItems(params,dataBank);
lastOccupiedInvSlots = occupiedInvSlots;
addSlotEnterListeners();
reqTimer = setInterval(function(){params = filterParams(rawParams);
for(let x of dataBank){
updateParams(x,params);
}
if(lastOccupiedInvSlots != occupiedInvSlots){
requestInvItems(params,dataBank);
}
lastOccupiedInvSlots = occupiedInvSlots;
},2000);
//addMeatyIntegration();
}
var rawParams = unsafeWindow.userVars;
var globalData = unsafeWindow.globalData;
var infoBox = unsafeWindow.infoBox;
var dataBank = [];
var params = filterParams(rawParams);
var requestsNum = 0;
var requestsCompleted = 0;
var requestsAllDone = 0;
var reqTimer;
var occupiedInvSlots = 0;
var lastOccupiedInvSlots = 0;
var lastSlotHovered = 0;
startScript();
})();