// ==UserScript==
// @name Crypto Kitty Info Extension
// @namespace https://github.com/HaJaeKyung/KittyExtension
// @version 0.34
// @description Adds stat info to the site
// @author HaJaeKyung
// @match *.cryptokitties.co/*
// @match *kittytools.herokuapp.com/*
// @match *kittygenerations.herokuapp.com/*
// @grant none
// @require https://cdnjs.cloudflare.com/ajax/libs/babel-standalone/6.18.2/babel.js
// @require http://code.jquery.com/jquery-3.2.1.min.js
// ==/UserScript==
$(document).ready(() => {
console.log('CryptoKitties Extension Loaded');
$("head").append("");
$("head").append("");
$("head").append("");
$("head").append("");
$("head").append("");
$("head").append("");
$("head").append("");
$("head").append("");
$("head").append("");
const version = "0.34";
let foundId = [];
let curCat = 'n/a';
let curId = 'n/a';
let hasChanged = false;
let ethPrice = false;
let url = location.pathname;
let restrictAPI = 0;
document.body.addEventListener('click', () => {
requestAnimationFrame(()=> {
if (url !== location.pathname) {
//Clears id cache on page change
foundId = [];
url = location.pathname;
}
});
}, true);
let tbl = {"Genesis":{"count":' (One)'},"BugCat":{"count":' (Three)'},"Mistletoe":{"count":0.009},"Dracula":{"count":0.062},"ShipCat":{"count":0.2194},"DuCat":{"count":1.0496},"royalblue":{"count":0.0828},"wingtips":{"count":0.3132},"wolfgrey":{"count":0.3915},"oldlace":{"count":0.513},"mainecoon":{"count":0.6337},"violet":{"count":1.0166},"gerbil":{"count":1.0467},"cerulian":{"count":1.1275},"fabulous":{"count":1.4981},"cottoncandy":{"count":1.5491},"chartreux":{"count":1.7489},"jaguar":{"count":2.0837},"dali":{"count":3.2633},"bubblegum":{"count":3.2756},"whixtensions":{"count":3.3428},"peach":{"count":3.9973},"otaku":{"count":4.1494},"googly":{"count":4.2248},"tigerpunk":{"count":4.77},"skyblue":{"count":4.803},"limegreen":{"count":5.5166},"bloodred":{"count":6.0443},"scarlet":{"count":6.0761},"beard":{"count":6.3582},"cloudwhite":{"count":6.5947},"calicool":{"count":7.1994},"laperm":{"count":7.3071},"barkbrown":{"count":7.5338},"tongue":{"count":8.2172},"emeraldgreen":{"count":8.3669},"chestnut":{"count":8.4015},"gold":{"count":8.9369},"spock":{"count":9.056},"mauveover":{"count":11.0459},"shadowgrey":{"count":12.9477},"coffee":{"count":13.3334},"cymric":{"count":13.4623},"salmon":{"count":14.3589},"royalpurple":{"count":14.9657},"mintgreen":{"count":15.0105},"swampgreen":{"count":15.6626},"lemonade":{"count":15.6752},"chocolate":{"count":15.8619},"topaz":{"count":15.9411},"sphynx":{"count":15.9704},"greymatter":{"count":16.1274},"simple":{"count":16.1511},"saycheese":{"count":16.3916},"orangesoda":{"count":16.5409},"aquamarine":{"count":16.8679},"munchkin":{"count":17.429},"raisedbrow":{"count":17.8955},"happygokitty":{"count":18.3734},"soserious":{"count":18.3819},"ragamuffin":{"count":19.6109},"sizzurp":{"count":19.6501},"strawberry":{"count":19.7618},"himalayan":{"count":20.4016},"pouty":{"count":21.0919},"crazy":{"count":25.6307},"thicccbrowz":{"count":26.6106},"luckystripe":{"count":27.4069},"kittencream":{"count":38.2094},"granitegrey":{"count":39.8877},"totesbasic":{"count":45.9613}};
function saveStorage(id, cattributes) {
if (window.location.pathname == "/my-kitties") {
storageMyTbl['id'+id] = cattributes;
localStorage.setItem('kittyExtensionMyTbl', JSON.stringify(storageMyTbl));
} else {
storageTbl['id'+id] = cattributes;
if (Object.keys(storageTbl).length > 1000) {
for (let first in storageTbl) break;
delete storageTbl[first];
}
localStorage.setItem('kittyExtensionTbl', JSON.stringify(storageTbl));
}
}
function checkVersion(){
if(hasLocalStorage){
let savedVersion = localStorage.getItem('kittyExtensionVersion') || 0;
if (savedVersion !== version){
localStorage.setItem('kittyExtensionTbl', JSON.stringify({}));
localStorage.setItem('kittyExtensionMyTbl', JSON.stringify({}));
localStorage.setItem('kittyExtensionVersion', version);
console.log('New version loaded:',version);
}
}
}
let hasLocalStorage = typeof(Storage) !== "undefined";
checkVersion();
let storageTbl = JSON.parse(localStorage.getItem('kittyExtensionTbl')) || {};
let storageMyTbl = JSON.parse(localStorage.getItem('kittyExtensionMyTbl')) || {};
let currency = localStorage.getItem('kittyExtensionEtherUSD') || "💲👎";
$.get("https://api.coinmarketcap.com/v1/ticker/ethereum/", data => {
ethPrice = parseFloat(data[0].price_usd);
if (window.location.hostname == 'www.cryptokitties.co') {
$("body").append("");
}
changePrices();
});
function getColor(catt) {
let color, count;
if (catt == 'Fancy' || catt == 'Exclusive') {
//To Do?
} else if (tbl[catt]) {
let uniqe = typeof tbl[catt].count == 'string';
if (uniqe || tbl[catt].count <= 0.27) {
color = "#ff0dbf"; // legendary
} else if (tbl[catt].count <= 1.8) {
color = "#ff8000"; // very rare
} else if (tbl[catt].count < 8) {
color = "#a335ee"; // rare
} else if (tbl[catt].count <= 16) {
color = "#0070ff"; // uncommon
} else if (tbl[catt].count <= 20) {
color = "white"; // common
} else {
color = "white"; // common
}
if (uniqe) {
count = tbl[catt].count;
} else {
count = tbl[catt].count < 1 ? tbl[catt].count.toFixed(3) : tbl[catt].count.toFixed(1);
count = tbl[catt].count <= 20 ? " ("+ count +"%)" : " (20%+)";
}
} else {
color = "#ff0dbf";
count = " (Ultra%)";
}
return [color, count];
}
function requestId(element, stats) {
$.getJSON( "https://api.cryptokitties.co/kitties/"+stats.id, data => {
finalizeOverlay(data.cattributes, element, stats);
if (hasLocalStorage) {
if (data.children.length === 0) {
let ul = element.getElementsByClassName("extWrapper")[0];
if (ul) {
ul.innerHTML += "
";
}
}
if (!data.status.is_ready) {
let note = element.getElementsByClassName('KittyStatus-note');
if (note.length !== 0) {
let cd = (((data.status.cooldown - Date.now())/6000/600));
let time = timeDisplay(cd * 3600);
note[note[1] ? 1 : 0].textContent = time;
}
}
saveStorage(stats.id, data.cattributes);
}
}).fail(() => {
//let ul = element.getElementsByClassName("extAttUl")[0];
//ul.classList.remove("extBounce");
//ul.innerHTML = "😿";
setTimeout(() => {
requestId(element, stats);
}, 1000);
});
}
function timeDisplay(seconds) {
if (typeof seconds === "number") {
seconds = Math.floor(seconds);
let hourS = seconds / 3600;
let minute = Math.floor(seconds / 60);
let second = seconds % 60;
second = second < 10 ? '0'+second : second;
if (hourS> 1) {
let hour = Math.floor(seconds / 3600);
minute = minute % 60;
minute = minute < 10 ? '0' + minute : minute;
if (hourS > 24) {
return hour + ' hours';
} else {
return hour + ':' + minute;
}
} else {
return minute + ' minutes';
}
} else {
return '';
}
}
function finalizeOverlay(cattributes, element, stats) {
let ul = element.getElementsByClassName("extAttUl")[0];
ul.classList.remove("extBounce");
ul.innerHTML = "";
for (let x in cattributes) {
if (cattributes[x]) {
let background_color = getColor(cattributes[x].description)[0];
let color = background_color == 'white' ? 'rgba(0,0,0, 0.76)' : 'rgba(255,255,255, 0.98)';
ul.innerHTML += ""+cattributes[x].description+"";
}
}
//if (window.location.hostname == 'www.cryptokitties.co') {
//calcPrice(stats.id , cattributes, stats, element);
//}
}
function isValidId(id) {
return !isNaN(id) && id !== "" && id.substring(0,2) != "0x" && id != curId && !foundId.includes(id) && !document.URL.includes("activity");
}
//Creates overlay on hover
var timer = Date.now();
function overlay() {
let nativeElement = $( this )[0];
let id = /[^/]*$/.exec(nativeElement)[0];
if (isValidId(id)) {
curId = id;
foundId.push(id);
let mainSite = window.location.hostname == 'www.cryptokitties.co';
let toolsSite = window.location.hostname == 'kittytools.herokuapp.com';
let element = mainSite ? nativeElement.getElementsByClassName('KittyCard')[0] : toolsSite ? nativeElement.parentElement : nativeElement;
if (element) {
let stats = {"id": curId, "fast":false, "gen": false, "cd": false};
if (mainSite) {
let status = nativeElement.getElementsByClassName('KittyCard-status')[0];
if (status) {
stats.cd = status.innerHTML.includes("Resting");
}
let speed = nativeElement.getElementsByClassName('KittyCard-coldown')[0];
if (speed) {
let cdTbl = ["Fast", "Swift", "Snappy", "Brisk", "Plodding", "Slow", "Sluggish", "Catatonic"];
stats.fast = cdTbl.indexOf(speed.innerText);
}
stats.gen = nativeElement.getElementsByClassName('KittyCard-subname')[0].innerText.split('Gen ').pop();
}
element.innerHTML += "";
if (toolsSite) {
let wrapper = element.getElementsByClassName("extWrapper")[0];
wrapper.classList.remove("extWrapper");
wrapper.classList.add("extKittyWrapper");
}
setTimeout(()=> {
console.log('KittyExtension: Requesting - '+ id);
requestId(element, stats);
}, timer - Date.now());
restrictAPI += 250;
setTimeout(()=> {
restrictAPI -= 250;
}, 250);
timer = Date.now() + restrictAPI;
}
}
}
$( "body").on( "mouseover", "a", overlay);
//Updates attributes on specific kitty page
setInterval(() => {
let curPage = document.getElementsByClassName("KittyHeader-details");
if (curPage.length > 0 && curPage[0].innerHTML.substr(0, curPage[0].innerHTML.indexOf('')) != curCat) {
curCat = curPage[0].innerHTML.substr(0, curPage[0].innerHTML.indexOf(''));
if (document.getElementsByClassName("ListAttributes-item").length > 0) {
let cattributes = document.getElementsByClassName("ListAttributes-item");
for (let att in cattributes) {
if (cattributes[att].style) {
let catt = cattributes[att].innerText;
let arr = getColor(catt);
let color = arr[0];
let num = arr[1];
cattributes[att].style.backgroundColor = color;
if (num) {
cattributes[att].style.color = color == 'white' ? '#000' : '#fff';
}
cattributes[att].innerHTML += num ? num : '';
}
}
}
}
}, 2000);
function calcPrice(id, cattributes, stats, element) {
let base = "https://api.cryptokitties.co/auctions";
let query = "?type=sale&limit=15&sorting=cheap&orderBy=current_price&orderDirection=asc&sorting=cheap&status=open&search=";
let totalGen = ' gen:'+stats.gen;
if (stats.gen >= 10) {
totalGen += ' gen:'+(stats.gen-1)+' gen:';
totalGen += parseInt(stats.gen)+1;
}
let rareTbl = getBestRares(cattributes);
let search = totalGen + rareTbl[0];
function finishPrice(data, index) {
let newMultiplier = stats.id == data.auctions[index].kitty.id ? 1 : rareTbl[1];
let nomralizePrice = data.auctions[index].current_price/1000000000000000000;
return (nomralizePrice*newMultiplier).toFixed(2);
}
$.getJSON( base+query+search, (data) => {
if (data.total > 0) {
if (data.total == 1) {
if (data.auctions[0].kitty.id == id) {
renderPrice(element, 'Name your price', query + search, false);
} else {
renderPrice(element, finishPrice(data, 0), query + search, true);
}
} else {
let cdTbl = ["Fast", "Swift", "Snappy", "Brisk", "Plodding", "Slow", "Sluggish", "Catatonic"];
let cdValueTbl = ["Fast","Swift","Swift","Snappy","Snappy","Brisk","Brisk","Plodding","Plodding","Slow","Slow","Sluggish","Sluggish","Catatonic"];
for (let x in data.auctions) {
let cdValue = cdTbl.indexOf(cdValueTbl[data.auctions[x].kitty.status.cooldown_index]);
if (stats.cd && stats.fast > 1) {
renderPrice(element, finishPrice(data, x), query + search, false);
return;
} else if (stats.fast > 4 || stats.fast >= cdValue) {
renderPrice(element, finishPrice(data, x), query + search, false);
return;
} else if (stats.cd && data.auctions[x].kitty.status.is_ready) {
renderPrice(element, finishPrice(data, x), query + search, false);
return;
} if (x == data.auctions.length - 1) {
renderPrice(element, finishPrice(data, x), query + search, true);
return;
}
}
}
} else {
renderPrice(element, 'Name your price', query + search, false);
}
}).fail(() => {
});
}
function renderPrice(element, price, url, fast) {
if (price >= 50) {
price = Math.ceil(price / 10) * 10;
price += '+';
} else if (fast) {
price += '+';
}
let ul = element.getElementsByClassName("extWrapper")[0];
ul.innerHTML += "";
}
function getBestRares(cattributes, adjust) {
let newCatts = [];
for (let single in cattributes) {
newCatts.push(cattributes[single].description);
}
cattributes = newCatts;
let best = '';
let hasRare = false;
let count = adjust || 0;
if (cattributes.length === 0) {
hasRare = ' type:fancy';
}
for (let x in cattributes) {
if (!tbl[cattributes[x]]) {
best += ' ' + x;
count += 3;
hasRare = ' ' + x;
}
}
let score = 0;
let multiplier = 1;
let multCount = 0;
for (let key1 in tbl) {
if (tbl[key1].count) {
for (let key in cattributes) {
if (tbl[key1].count <= 0.4) {
multiplier *= 1.55;
} else if(tbl[key1].count <= 1.8) {
multiplier *= 1.25;
} else if (tbl[key1].count <= 5) {
multiplier *= 1.05;
} else if (tbl[key1].count <= 10) {
multiplier *= 1.025;
}
}
}
}
console.log(multiplier);
for (let key in tbl) {
if (cattributes.includes(key)) {
if (tbl[key].count <= 1.2) {
} else if (tbl[key].count <= 6) {
}
}
if (count >= 3) {
return [' ' + best, multiplier];
}
}
let attrCount = 0;
cattributes.forEach((key)=>{
if (tbl[key]) {
if (tbl[key].count <= 0.4) {
attrCount += 3;
} else if(tbl[key].count <= 1.8) {
attrCount += 2;
} else if (tbl[key].count <= 5) {
attrCount += 1;
} else if (tbl[key].count <= 10) {
attrCount += 1;
} else {
score += 0;
}
} else {
attrCount += 5;
}
score = ((attrCount/6)*7)+1;
console.log(score);
if (cattributes.length === 0) {
score = 8;
} else if (cattributes.length > 8) {
score -= cattributes.length - 8;
}
});
console.log('score',score);
return score;
}
document.searchSimilarKitties = (e, query) => {
e.preventDefault();
window.location.href = "https://www.cryptokitties.co/marketplace/sale" + query;
};
function changePrices() {
let items = document.getElementsByClassName('KittyStatus-itemText');
if (ethPrice && items.length > 0 && document.getElementsByClassName('extUSD').length > 0) {
for (let item of items) {
if (item.parentElement.parentElement.className == "KittyStatus" || item.parentElement.parentElement.className == "KittyStatus KittyStatus--list") {
if (!item.parentElement.innerHTML.includes("Icon--timer") && !item.parentElement.innerHTML.includes('Bun in oven')) {
let cur = item.getElementsByTagName('span')[0].innerText.split(' ');
if (currency == "💲👍" && cur[0] != "$") {
let endPrice = (cur[1] * ethPrice ).toFixed(2);
if (endPrice != 'NaN') {
item.getElementsByTagName('span')[0].innerText = '$ ' + endPrice;
}
} else if (currency == "💲👎" && cur[0] != "Ξ") {
let endPrice = (cur[1] / ethPrice ).toFixed(4);
if (endPrice != 'NaN') {
item.getElementsByTagName('span')[0].innerText = 'Ξ ' + endPrice;
}
}
} else {
}
}
}
}
}
let saleNum = 0;
document.switchPrice = (e) => {
e.preventDefault();
hasChanged = true;
let element = document.getElementsByClassName('extUSD')[0];
currency = currency == "💲👍" ? "💲👎" : "💲👍";
localStorage.setItem('kittyExtensionEtherUSD', currency);
element.innerText = currency;
changePrices();
};
$(document).bind('DOMSubtreeModified',function(){
let items = document.getElementsByClassName('KittyStatus-itemText');
if (items.length != saleNum) {
saleNum = items.length;
if (hasChanged || currency == "💲👍") {
changePrices();
}
}
let mItems = document.getElementsByClassName('KittyStatus KittyStatus--multiple');
[...mItems].forEach((i)=>{
let replace = i.children[1].innerHTML.replace("Resting", "");
let hasText = i.children[1].getElementsByClassName("KittyStatus-note")[0];
if(hasText && hasText.textContent && hasText.textContent !== '') {
i.children[1].innerHTML = replace;
}
i.classList.remove('KittyStatus--multiple');
});
});
});