您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Calculates stats in DripStat, and provides a control panel for automation.
当前为
- // ==UserScript==
- // @name DripStat DropOut
- // @namespace anonycat
- // @version 0.5.303
- // @description Calculates stats in DripStat, and provides a control panel for automation.
- // @match https://dripstat.com/game/
- // @grant none
- // ==/UserScript==
- //Throttle auto purchases to one every 5 seconds, to minimize risk of desyncs with the server
- var lastBuy = 0;
- //Track how many manual clicks have been made by second over the last 60 seconds
- var clickHistory = [];
- while (lastBuy < 60)
- {clickHistory[lastBuy++] = 0;}
- var oldByteCount = 0;
- var first = 1;
- function init()
- {
- //Should powerups and upgrades be automatically purchased as they become affordable?
- //(As of level 5, also includes facilities for grabbing spring beans that appear)
- crypto.autoPurchase=0;
- //Should the BPS rate be increased to simulate automatic cup clicks?
- crypto.autoClick=0;
- //Should memory automatically be dripped?
- //0 = no auto-drip, 1 = auto-drip when buffer is full, 2 = auto-drip as needed to create enough space to pay for upgrades
- crypto.autoDrip=0;
- //Should we take manual clicks into account when figuring out the payback rate of powerups?
- crypto.clickRate=1;
- //If autoclicking is enabled, each second will pick a random multiplier and count off that many cup clicks.
- //A multiplier of 0 means no clicking, only natural BPS intake.
- //Multipliers greater than 20 are rejected by the server, so we won't ever generate such a thing here.
- //Lowest possible multiplier to select
- crypto.cupmultl = 0;
- //Average multiplier
- crypto.cupmultm = 5;
- //There is no variable for the highest multiplier; it's automatically figured as 2*Middle - Low (but capped at 20).
- //Keep track of the original names and descriptions
- localStats.powerUps.slice(0).forEach(function(powerUp){
- powerUp.upgrades.forEach(function(upgrade){
- upgrade.originalName = upgrade.name;
- upgrade.originalDesc = upgrade.desc;
- });
- powerUp.originalName = powerUp.name;
- powerUp.originalDesc = powerUp.desc;
- });
- //string (int) seconds to formatted time
- String.prototype.toHHMMSS = function () {
- var seconds = parseInt(this, 10); // don't forget the second param
- if(seconds <= 0)
- return "no time";
- var days = Math.floor(seconds / 86400);
- seconds -= days*86400;
- var hours = Math.floor(seconds / 3600);
- seconds -= hours*3600;
- var minutes = Math.floor(seconds / 60);
- seconds -= minutes*60;
- if (hours < 10 && days) {hours = "0"+hours;}
- if (minutes < 10 && hours) {minutes = "0"+minutes;}
- if (seconds < 10) {seconds = "0"+seconds;}
- var output = "";
- if(days)
- output = days+"d "+hours+":"+minutes+":"+seconds;
- else if(hours)
- output = hours+":"+minutes+":"+seconds;
- else
- output = minutes+":"+seconds;
- return output;
- }
- //function to update the control panel
- crypto.updatehud = function(type) {
- if(type & 1)
- {
- if(this.autoPurchase)
- {
- $(".apn").css('background-color', '');
- $(".apy").css('background-color', '#AFA');
- }
- else
- {
- $(".apy").css('background-color', '');
- $(".apn").css('background-color', '#FAA');
- }
- }
- if(type & 2)
- {
- if(crypto.autoClick)
- {
- $(".acn").css('background-color', '');
- $(".acy").css('background-color', '#AFA');
- }
- else
- {
- $(".acy").css('background-color', '');
- $(".acn").css('background-color', '#FAA');
- }
- }
- if(type & 4)
- {
- if(crypto.autoDrip==2)
- {
- $(".drip0").css('background-color', '');
- $(".drip1").css('background-color', '');
- $(".drip2").css('background-color', '#AFA');
- }
- else if(crypto.autoDrip)
- {
- $(".drip2").css('background-color', '');
- $(".drip0").css('background-color', '');
- $(".drip1").css('background-color', '#AAF');
- }
- else
- {
- $(".drip2").css('background-color', '');
- $(".drip1").css('background-color', '');
- $(".drip0").css('background-color', '#FAA');
- }
- }
- if(type & 8)
- {
- if(crypto.clickRate)
- {
- $(".crn").css('background-color', '');
- $(".cry").css('background-color', '#AFA');
- }
- else
- {
- $(".cry").css('background-color', '');
- $(".crn").css('background-color', '#FAA');
- }
- }
- if(type & 16)
- $("#multl").html("Min. Rate: "+String(crypto.cupmultl));
- if(type & 32)
- $("#multm").html("Avg. Rate: "+String(crypto.cupmultm));
- }
- //Create the control panel with divs
- $('#bpsChartContainer').parent().append("<table style='width:100%; height:105px; border-collapse: collapse;'><tr>"
- +"<td rowspan=2 style='width:30%; border: 2px solid black;'><div id='next-purchase-container'></div></td>"
- +"<td colspan=2 style='width:12%; height:35px; border: 2px solid black; border-bottom: none;' class='apy apn' onclick='crypto.autoPurchase = 1 - crypto.autoPurchase; crypto.updatehud(1)'>Auto Buy</td>"
- +"<td colspan=3 style='width:21%; border: 2px solid black; border-bottom: none' class='drip0 drip1 drip2' onclick='crypto.autoDrip = (1 + crypto.autoDrip) % 3; crypto.updatehud(4)'>Auto Drip</td>"
- +"<td colspan=2 style='width:12%; border: 2px solid black; border-bottom: none' class='acy acn' onclick='crypto.autoClick = 1 - crypto.autoClick; crypto.updatehud(2)'>Auto Click</td>"
- +"<td style='width:15%; border: 2px solid black; border-right:1px solid black'> Auto Click <div id='multl'></div></td>"
- +"<td style='width:5%; border-top: 2px solid black; border-bottom: 2px solid black; background-color: #AFA;' onclick='crypto.cupmultl = Math.min(crypto.cupmultl + 1, crypto.cupmultm); crypto.updatehud(16)'> + </td>"
- +"<td style='width:5%; border: 2px solid black; border-left: 1px solid black; background-color: #FAA;' onclick='crypto.cupmultl = Math.max(crypto.cupmultl - 1, 0); crypto.updatehud(16)'> - </td></tr>"
- +"<tr><td style='width:6%; height:35px; border: 2px solid black; border-top: 1px solid black;' class='apn' onclick='crypto.autoPurchase = 0; crypto.updatehud(1)'> Off </td>"
- +"<td style='width:6%; border: 2px solid black; border-top: 1px solid black;' class='apy' onclick='crypto.autoPurchase = 1; crypto.updatehud(1)'> On </td>"
- +"<td style='width:7%; border: 2px solid black; border-top: 1px solid black;' class='drip0' onclick='crypto.autoDrip = 0; crypto.updatehud(4)'> Never </td>"
- +"<td style='width:7%; border: 2px solid black; border-top: 1px solid black;' class='drip1' onclick='crypto.autoDrip = 1; crypto.updatehud(4)'> At <br /> Limit </td>"
- +"<td style='width:7%; border: 2px solid black; border-top: 1px solid black;' class='drip2' onclick='crypto.autoDrip = 2; crypto.updatehud(4)'> For <br /> Costs </td>"
- +"<td style='width:6%; border: 2px solid black; border-top: 1px solid black;' class='acn' onclick='crypto.autoClick = 0; crypto.updatehud(2)'> Off </td>"
- +"<td style='width:6%; border: 2px solid black; border-top: 1px solid black;' class='acy' onclick='crypto.autoClick = 1; crypto.updatehud(2)'> On </td>"
- +"<td style='width:15%; border: 2px solid black; border-right:1px solid black'> Auto Click <div id='multm'></div></td>"
- +"<td style='width:5%; border-top: 2px solid black; border-bottom: 2px solid black; background-color: #AFA;' onclick='crypto.cupmultm = Math.min(crypto.cupmultm + 1, 20); crypto.updatehud(32)'> + </td>"
- +"<td style='width:5%; border: 2px solid black; border-left: 1px solid black; background-color: #FAA;' onclick='crypto.cupmultm = Math.max(crypto.cupmultm - 1, crypto.cupmultl); crypto.updatehud(32)'> - </td></tr>"
- +"<tr><td style='height:35px; border: 2px solid black; border-right: none'> Average Click Rate - Last 10s: </td>"
- +"<td style='border: 2px solid black; border-left: none'><strong><div id='click-rate-10'></div></strong></td>"
- +"<td colspan=2 style='border: 2px solid black; border-right: none'> Last 60s: </td>"
- +"<td style='border: 2px solid black; border-left: none'><strong><div id='click-rate-60'></div></strong></td>"
- +"<td colspan=4 style='border: 2px solid black; border-right: none' class='cry crn' onclick='crypto.clickRate = 1 - crypto.clickRate; crypto.updatehud(8)'> Take click rate into account? </td>"
- +"<td style='border: 2px solid black; border-left: 1px solid black; border-right: 1px solid black' class='cry' onclick='crypto.clickRate = 1; crypto.updatehud(8)'> Yes </td>"
- +"<td style='border: 2px solid black; border-left: none' class='crn' onclick='crypto.clickRate = 0; crypto.updatehud(8)'> No </td></tr></table>");
- $("#next-purchase-container").html("<div id='next-purchase-label'></div><div id='next-purchase-payback'></div><div id='next-purchase-time'></div><div id='max-space-label'></div>");
- crypto.updatehud(63);
- }
- function loop()
- {
- var upgradeCounter = 1;
- var powerupCounter = 1;
- var mult = 0;
- var multm = 0;
- var bpc = CoffeeCup.calcBytesPerClick();
- var bpcBoosts = localStats.powerUps[0].purchasedUpgrades.length;
- var bpsDiff = localStats.byteCount - oldByteCount;
- if(first)
- first=0;
- else
- {
- clickHistory.shift();
- clickHistory.push(Math.round(Math.max(0,(bpsDiff - localStats.bps)/bpc)));
- }
- var avg10 = 0;
- var avg60 = 0;
- for(var a = 0; a < 60; a++)
- {
- avg60 += clickHistory[a];
- if(a>49)
- avg10 += clickHistory[a];
- }
- avg10 /= 10;
- avg60 /= 60;
- if (crypto.autoClick)
- {
- multm = crypto.cupmultm;
- mult = Math.min(20,Math.floor(Math.random()*(2 * multm - crypto.cupmultl)+crypto.cupmultl));
- if(mult)
- localStats.byteCount += bpc * mult;
- if(localStats.byteCount >= localStats.memoryCapacity)
- localStats.byteCount = localStats.memoryCapacity;
- }
- if (crypto.clickRate)
- var bps = bpc * (multm + avg60) + localStats.bps;
- else
- var bps = bpc * multm + localStats.bps;
- if (crypto.autoDrip && localStats.byteCount == localStats.memoryCapacity)
- dripper.dripGlobal();
- var data = Array();
- var min = 1e+308;
- var bytesNeeded=0;
- var next = min;
- var minObj = {};
- localStats.powerUps.slice(0).forEach(function(powerUp) {
- powerUp.position = "pu"+powerupCounter;
- var hasUpgrade = false;
- powerUp.upgrades.forEach(function(upgrade) {
- hasUpgrade = true;
- upgrade.position = "upg"+upgradeCounter;
- //Let's see which upgrade provides the biggest bang for the buck
- //(computed as "time taken before this upgrade will recoup its own cost").
- //If the price is so high that the current buffer can't possibly hold enough
- //(even if we cashed out for more space right now),
- //the "real" price includes what it takes to earn that extra buffer space.
- //If there's an object we can afford right now,
- //which will pay itself back in 2 hours,
- //and another object that would nominally pay itself back in 1h50m,
- //except that we can't afford it for 20 more minutes,
- //we should account for that in the time before recouping.
- //Add the time spent waiting to accrue sufficient funds.
- //Oh, and if we need 100MB for something, but can only hold 80MB
- //(with 70MB of it filled already), we can't just drip 20MB and keep the rest.
- //We have to drip everything at once, shooting all the way to 150MB.
- //Thus we can't make any progress on affording the item until a drip,
- //and then it costs a full additional 100MB after starting from scratch.
- if(upgrade.price > localStats.byteCount + localStats.memoryCapacity)
- bytesNeeded = 2 * upgrade.price - (localStats.memoryCapacity + localStats.byteCount);
- else if(upgrade.price > localStats.memoryCapacity)
- bytesNeeded = upgrade.price;
- else if(upgrade.price > localStats.byteCount)
- bytesNeeded = upgrade.price - localStats.byteCount;
- else
- bytesNeeded = 0;
- //Cursor upgrades boost clicking too, so if autoclicks are on, take the rate
- //and overall BPS into account when determining its value.
- if(powerupCounter == 1)
- upgrade.value = upgrade.price/((powerUp.totalBps * (1 + crypto.clickRate * (avg60 + multm) * bpcBoosts * 0.1) + (crypto.clickRate * avg60 + multm) * bpc) / 10) + bytesNeeded / bps;
- else
- upgrade.value = upgrade.price/(powerUp.totalBps * (0.1 + crypto.clickRate * (avg60 + multm) * bpcBoosts * 0.01)) + bytesNeeded / bps;
- min = Math.min(min, upgrade.value);
- if(upgrade.value == min)
- minObj = upgrade;
- upgrade.desc = "Pays for itself in "+String(upgrade.value).toHHMMSS() + "<br>" + upgrade.originalDesc;
- });
- if(hasUpgrade)
- upgradeCounter++;
- powerupCounter++;
- //Same procedure on the main power-ups themselves.
- if(powerUp.currentPrice > localStats.byteCount + localStats.memoryCapacity)
- bytesNeeded = 2 * powerUp.currentPrice - (localStats.memoryCapacity + localStats.byteCount);
- else if(powerUp.currentPrice > localStats.memoryCapacity)
- bytesNeeded = powerUp.currentPrice;
- else if(powerUp.currentPrice > localStats.byteCount)
- bytesNeeded = powerUp.currentPrice - localStats.byteCount;
- else
- bytesNeeded = 0;
- powerUp.value = powerUp.currentPrice/(powerUp.currentBps * (1 + crypto.clickRate * (avg60 + multm) * bpcBoosts * 0.1)) + bytesNeeded / bps;
- data.push(powerUp.value);
- if(!(powerUp.name == "Spring Framework" && springPowerup.isLocked))
- {
- min = Math.min(min, powerUp.value);
- if(powerUp.value == min)
- minObj = powerUp;
- }
- });
- $('.storeItem, .upgcontainer').css('background-color', '');
- var selector = minObj.position;
- $("#"+selector).css('background-color', '#B2EDED');
- $('.storePrice').each(function(index){
- $(this).find('p').remove();
- var content = "<p style=\"display:inline; font-size:0.7em;\"> ("+String(data[index]).toHHMMSS()+")</p>";
- $(this).append(content);
- });
- var label = minObj.name;
- if(minObj.powerup) //Is our best deal an upgrade or a powerup? They use different syntax.
- {
- label += " (Upgrade)";
- var price = minObj.price;
- }
- else
- var price = minObj.currentPrice;
- var limitTime = Number((localStats.memoryCapacity - localStats.byteCount)/bps).toFixed(0);
- var limitstr = "";
- if(price > localStats.byteCount + localStats.memoryCapacity)
- {
- var time = Number((2 * price - (localStats.memoryCapacity + localStats.byteCount))/bps).toFixed(0);
- if(localStats.memoryCapacity==localStats.byteCount)
- limitstr = " (Drip NOW!)";
- }
- else if(price > localStats.memoryCapacity)
- {
- var time = Number(price/bps).toFixed(0);
- limitstr = " (Drip NOW!)";
- if(crypto.autoDrip >= 2)
- dripper.dripGlobal();
- }
- else
- var time = Number((price - localStats.byteCount)/bps).toFixed(0);
- //Now to fill the control panel.
- $("#next-purchase-label").html("Next Purchase: <strong>"+label+"</strong>");
- $("#next-purchase-payback").html("Pays for itself in "+String(minObj.value).toHHMMSS());
- if(time <= 0)
- $("#next-purchase-time").html("Affordable now");
- else
- $("#next-purchase-time").html("Affordable in "+String(time).toHHMMSS()+limitstr);
- if(limitTime <= 0)
- $("#max-space-label").html("Capacity is maxed out!");
- else
- $("#max-space-label").html("Capacity maxes out in "+String(limitTime).toHHMMSS());
- $("#click-rate-10").html(String(avg10.toFixed(1)));
- $("#click-rate-60").html(String(avg60.toFixed(1)));
- if(crypto.autoPurchase && price<=localStats.byteCount && lastBuy >= 5)
- {
- minObj.buy(localStats);
- lastBuy = 0;
- }
- else if (lastBuy < 5)
- lastBuy += 1;
- if(crypto.autoPurchase && springPowerup.isLocked && mine.beanCount > 0 && AnonymousUserManager.canGrabBean())
- {
- if($('.vex').length)
- vex.closeAll();
- Mine.onGrab();
- }
- if($("#networkError")[0].style['cssText'] == "display: block;")
- window.location.reload(false);
- oldByteCount = localStats.byteCount;
- }
- init();
- setInterval(function(){loop();}, 1000);