Last active
January 23, 2024 12:14
-
-
Save yohanesyuen/d7fb34326be848b78a11d968a5a7c66c to your computer and use it in GitHub Desktop.
This file contains 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
// Donation address: 17Ez2fRkxxwwTh6W8njm4rhWdrphxRiDa1 | |
// Sign up link: https://freebitco.in/?r=3329532 | |
function Random(seed) { | |
this.m = Math.pow(2, 32); | |
this.maxIdx = 128; | |
this.buf = new Uint32Array(this.maxIdx); | |
this.idx = 0; | |
window.crypto.getRandomValues(this.buf); | |
} | |
Random.prototype.next = function() { | |
if (this.idx >= this.maxIdx) { | |
window.crypto.getRandomValues(this.buf); | |
this.idx = 0; | |
} | |
return this.buf[this.idx++]; | |
}; | |
Random.prototype.nextFloat = function() { | |
return this.next() / this.m; | |
}; | |
var rand = new Random(); | |
function messify() { | |
var maxMessCount = rand.nextFloat() * rand.maxIdx; | |
var messCount = Math.floor(rand.nextFloat() * maxMessCount); | |
var seed = ''; | |
for (var i = 0; i < messCount; i++) { | |
// rand.next(); | |
seed = reseed(true, seed); | |
} | |
reseed(false, seed); | |
} | |
function formatTime(seconds) { | |
var sign = ""; | |
if (seconds < 0) { | |
sign = "-"; | |
} | |
var quotient, _seconds, _minutes, _hours, _days, _str; | |
quotient = Math.floor(Math.abs(seconds)); | |
_seconds = quotient % 60; | |
quotient -= _seconds; | |
quotient /= 60; | |
_minutes = quotient % 60; | |
quotient -= _minutes; | |
quotient /= 60; | |
_hours = quotient % 24; | |
quotient -= _hours; | |
quotient /= 24; | |
_days = quotient; | |
_str = sign + (_days > 0 ? _days + "d " : ""); | |
_str += _hours < 10 ? "0" + _hours : _hours; | |
_str += ":"; | |
_str += _minutes < 10 ? "0" + _minutes : _minutes; | |
_str += ":"; | |
_str += _seconds < 10 ? "0" + _seconds : _seconds; | |
return _str; | |
} | |
var startValue = "0.00000001", | |
seed = "", | |
extraSeed = 0, | |
targetLs = 17, | |
ls = targetLs, | |
minimumBalance = Math.pow(2, ls) * 1e-8, | |
multiplier = 2.1, | |
stopPercentage = 0.01, | |
minWaitDefault = 3, | |
maxWaitDefault = minWaitDefault * 2, | |
minWait = minWaitDefault, | |
maxWait = maxWaitDefault, | |
stopped = false, | |
stopBefore = 3, | |
originalBalance = 0, | |
beforeStreakBalance = 0, | |
averageStartTime = Date.now(), | |
gameStartTime = Date.now(), | |
wageredAmount = 0, | |
resetThreshold = 3e-8, | |
targetHitCount = 0, | |
targetValue = 0.00242780, | |
autoset_payout = false, | |
run_period = 10 * 60 * 1000, | |
pause_period = 5 * 60 * 1000, | |
btcsgd = 3e4; | |
var bets = 0, | |
lossStreak = 0, | |
maxLossStreak = [], | |
streakProfit = 0, | |
wins = 0, | |
loss = 0; | |
var $loButton = $("#double_your_btc_bet_lo_button"), | |
$hiButton = $("#double_your_btc_bet_hi_button"), | |
$stake = $("#double_your_btc_stake"), | |
$payout = $("#double_your_btc_payout_multiplier"), | |
$lose = $("#double_your_btc_bet_lose"), | |
$win = $("#double_your_btc_bet_win"), | |
$err = $("#double_your_btc_error"), | |
$bal = $("#balance"), | |
$baBal = $("#bonus_account_balance"), | |
$funBuyPrice = $("#fun_buy_price"), | |
$buyFunCount = $("#buy_fun_count"), | |
$buyFunConfirm = $("#buy_fun_confirm"), | |
$btn = $loButton, | |
thresholds = [0, 1], | |
payoutTable = [4, 3]; | |
var timeouts = { | |
'win': -1, | |
'lose': -1, | |
'start': -1, | |
'stop': -1 | |
}; | |
var intervals = { | |
'statPrinter': -1, | |
} | |
var lastBetWin = false, | |
side = "lo"; | |
var BettingProfile, BettingProfiles; | |
BettingProfile = function(startBet, options) { | |
var options = options || {}; | |
this.startValue = typeof startBet === 'number' ? startBet.toFixed(8) : startBet; | |
this.multiplier = options.multiplier || 2.0; | |
this.minimumBalance = 0; | |
this.safetyAmount = 0; | |
this.targetValue = 0; | |
this.maxLoss = 0; | |
this.maxBetCount = 0; | |
this.balanceAfterLoss = 0; | |
this.balance = options.balance; | |
var currentBet = parseFloat(this.startValue); | |
while (this.maxLoss + currentBet < this.balance) { | |
this.maxBetCount += 1; | |
this.maxLoss += currentBet; | |
currentBet *= this.multiplier; | |
currentBet = parseFloat(currentBet.toFixed(8)); | |
} | |
this.minimumBalance = this.maxLoss.toFixed(8); | |
this.balanceAfterLoss = (this.balance - this.maxLoss).toFixed(8); | |
this.targetValue = parseFloat((currentBet + this.maxLoss).toFixed(8)); | |
} | |
BettingProfiles = (function() { | |
var getForBalance, getProfiles; | |
getForBalance = function(balance) { | |
var profiles = getProfiles(balance); | |
return profiles[profiles.length - 1]; | |
} | |
getStartValue = function(balance) { | |
var mul = Math.floor(balance / (Math.pow(2, targetLs) * 1e-8)); | |
return mul > 0 ? mul * 1e-8 : 1e-8; | |
} | |
getProfiles = function(balance) { | |
console.log('getProfiles called'); | |
var profiles = []; | |
var multipliers = []; | |
var increment = 0.001; | |
var startValue = getStartValue(balance); | |
for (var i = 0; i <= 10000; i++) { | |
multipliers.push(2 + i * increment); | |
} | |
multipliers.forEach(multiplier => { | |
profiles.push( | |
new BettingProfile(startValue, { | |
multiplier: multiplier, | |
balance: balance | |
}) | |
); | |
}); | |
var maxBetCountValue = Math.max.apply(Math, profiles.map(p => p.maxBetCount)); | |
profiles = profiles.filter(p => p.maxBetCount >= maxBetCountValue - 1) | |
profiles = profiles.sort((a, b) => (a.balanceAfterLoss > b.balanceAfterLoss) ? 1 : -1); | |
return profiles; | |
} | |
return { | |
getForBalance: getForBalance, | |
getProfiles: getProfiles | |
}; | |
})(); | |
function clearBindings() { | |
$lose.unbind(); | |
$win.unbind(); | |
$err.unbind(); | |
} | |
function getBalance() { | |
var mainBal = parseFloat($bal.text()); | |
var baBal = parseFloat($baBal.text()); | |
return mainBal + baBal; | |
} | |
function getLs() { | |
desiredLS = 17; | |
ls = Math.floor(Math.log2(getBalance() / 1e-8)) | |
ls = ls > desiredLS - 1 ? desiredLS : ls; | |
return ls; | |
} | |
function randomIntFromInterval(min, max) { | |
return Math.floor(rand.nextFloat() * (max - min + 1) + min); | |
} | |
function bufferToHex(buffer) { | |
return Array | |
.from(buffer) | |
.map(b => b.toString(16).padStart(2, "0")) | |
.join(""); | |
} | |
function reseed(virtual = false, seed = '') { | |
var buf = new Uint32Array(8), | |
hexbuf = '' | |
suffix = ''; | |
window.crypto.getRandomValues(buf); | |
hexbuf = bufferToHex(buf); | |
suffix = Date.now().toString(16) + rand.next().toString(16) | |
seed += hexbuf.substr(0, hexbuf.length - suffix.length) + Date.now() + rand.next() + extraSeed; | |
seed = CryptoJS.SHA256(seed).toString() | |
if (!virtual) { | |
$("#next_client_seed").val(seed); | |
} else { | |
return seed; | |
} | |
} | |
function resetProfileOnStakeEqBal(stake) { | |
if (stake > getBalance() || stake == getBalance()) { | |
clearTimeout(timeouts.lose); | |
resetProfile(); | |
stake = parseFloat(startValue); | |
} | |
} | |
function multiply() { | |
var current = $stake.val(); | |
var x = current * multiplier; | |
resetProfileOnStakeEqBal(x); | |
$stake.val(x.toFixed(8)); | |
CalculateWinAmount(); | |
} | |
function getRandomWait() { | |
var wait = randomIntFromInterval(minWait, maxWait); | |
console.log("Waiting for " + wait + " ms"); | |
return wait; | |
} | |
function reset() { | |
$stake.val(startValue); | |
CalculateWinAmount(); | |
lossStreak = 0; | |
beforeStreakBalance = getBalance(); | |
} | |
function resetStartValues() { | |
originalBalance = getBalance(); | |
wageredAmount = 0; | |
gameStartTime = Date.now(); | |
} | |
function resetProfile() { | |
var profile = BettingProfiles.getForBalance(getBalance()); | |
multiplier = profile.multiplier; | |
startValue = profile.startValue; | |
targetValue = profile.targetValue; | |
} | |
function initGame() { | |
originalBalance = getBalance(); | |
// ls = getBalance() > Math.pow(2, 15) * 1e-8 ? getLs() - 1 : getLs(); | |
ls = getLs(); | |
minimumBalance = Math.pow(2, 11) * 1e-8; | |
if (originalBalance < minimumBalance) { | |
return; | |
} | |
resetProfile(); | |
reseed(); | |
reset(); | |
} | |
function startGame() { | |
console.log("Game started!"); | |
initGame(); | |
$btn.trigger("click"); | |
timeouts.stop = setTimeout(stopGame, run_period); | |
} | |
function stopGame() { | |
console.log("Game will stop soon! Let me finish."); | |
stopped = true; | |
timeouts.start = setTimeout(startGame, pause_period); | |
} | |
function deexponentize(number) { | |
return number * 1000000; | |
} | |
function iHaveEnoughMoney() { | |
var balance = deexponentize(getBalance()); | |
var current = deexponentize($stake.val()); | |
return ((balance * multiplier) / 100) * (current * multiplier) > stopPercentage / 100; | |
} | |
function stopBeforeRedirect() { | |
var minutes = parseInt($("title").text()); | |
if (minutes < stopBefore) { | |
console.log("Approaching redirect! Stop the game so we don't get redirected while losing."); | |
stopGame(); | |
} | |
} | |
function switchSide() { | |
side = side === "lo" ? "hi" : "lo"; | |
} | |
function nextClick() { | |
var x = parseFloat($stake.val()); | |
var a = parseFloat(startValue); | |
// var proposedPayoutValue = 2 + Math.floor(ls / 6 - lossStreak) | |
// $payout.val((proposedPayoutValue) > 2 ? proposedPayoutValue : 2 ); | |
printStats(); | |
if (lastBetWin) { | |
switchSide(); | |
$btn = $("#double_your_btc_bet_" + side + "_button"); | |
} else { | |
reseed(); | |
} | |
$btn.trigger("click"); | |
} | |
function getProfit() { | |
return getBalance() - originalBalance; | |
} | |
function incrementStartValue() { | |
startValue = parseFloat(startValue) + 1e-8; | |
startValue = startValue.toFixed(8); | |
resetStartValues(); | |
} | |
function decrementStartValue() { | |
startValue = parseFloat(startValue) - 1e-8; | |
startValue = startValue.toFixed(8); | |
resetStartValues(); | |
} | |
function stopOnBonusCrossBalance() { | |
var baBal = parseFloat($baBal.text()); | |
if (baBal >= balance) { | |
stopped == true; | |
clearBindings(); | |
} | |
} | |
function resetOnTargetHit() { | |
if (getBalance() >= targetValue) { | |
ls = Math.floor(Math.log2(getBalance() / 1e-8)) | |
ls = ls > targetLs - 1 ? targetLs : ls; | |
resetProfile(); | |
if (ls >= targetLs) { | |
return; | |
} | |
targetHitCount += 1; | |
if (getBalance() < Math.pow(2, targetLs) * 1e-8 && targetHitCount > (targetLs - ls)) { | |
stopped = true; | |
clearBindings(); | |
clearInterval(intervals.statPrinter); | |
document.location.reload(); | |
return; | |
} | |
} | |
} | |
function printStats() { | |
console.clear(); | |
var css = "background-color: black; color: #0f0; font-size: 10pt"; | |
var elapsedTime = Date.now() - gameStartTime; | |
var elapsedSeconds = Math.floor(elapsedTime / 1000); | |
var sgdBalance = getBalance() * btcsgd; | |
var sgdProfit = (getBalance() - originalBalance) * btcsgd; | |
var perSecondSgdProfit = sgdProfit / elapsedSeconds; | |
perSecondSgdProfit -= (perSecondSgdProfit / elapsedSeconds); | |
var perMinuteSgdProfit = perSecondSgdProfit * 60; | |
var perHourSgdProfit = perMinuteSgdProfit * 60; | |
targetValueSgd = targetValue * btcsgd; | |
var str = "Balance:\t\t\t\tS$ " + sgdBalance.toFixed(4) + "\t| "; | |
str += "Profit since start:\tS$ " + sgdProfit.toFixed(4) + "\t| "; | |
str += "Rate of earnings: S$ " + perHourSgdProfit.toFixed(4) + "/hour"; | |
str += "\n"; | |
str += "Time before S$" + targetValueSgd.toFixed(2) + ":\t"; | |
str += formatTime((targetValueSgd - sgdBalance) / perSecondSgdProfit) + "\t| "; | |
str += "Total Wagered:\tBTC " + wageredAmount.toFixed(8) + "\t| "; | |
str += "Time since start:\t" + formatTime(elapsedSeconds); | |
str += "\n"; | |
str += "Multiplier: " + multiplier.toFixed(4) + "\t\t\t\t\t| "; | |
// str += "Extra Seed: " + extraSeed.toString() + "\t\t\t\t| "; | |
str += "Distance to next: BTC " + (( | |
Math.ceil( | |
getBalance() / Math.pow(2,targetLs) / 1e-8) * Math.pow(2, targetLs) * 1e-8 | |
) - getBalance()).toFixed(8) + "\t| "; | |
str += "Fun Budget: " + parseFloat(localStorage.getItem("pendingFunBudget")).toFixed(8); | |
str = "%c" + str; | |
console.log(str, css); | |
} | |
clearBindings(); | |
function buyFunIfBudgetAllows() { | |
var currentPrice = parseFloat($funBuyPrice.text()); | |
if (wins % 4 == 0) { | |
var currentBudget = localStorage.getItem("pendingFunBudget"); | |
var currentPrice; | |
if (currentBudget === null) { | |
localStorage.setItem("pendingFunBudget", 1e-8.toFixed(8)); | |
} else { | |
currentBudget = parseFloat(currentBudget); | |
var buyCount = Math.floor(currentBudget / currentPrice); | |
var spending = buyCount * currentPrice; | |
if (buyCount > 0) { | |
$buyFunCount.val(buyCount); | |
$buyFunConfirm.click(); | |
localStorage.setItem( | |
"pendingFunBudget", | |
(parseFloat(localStorage.getItem("pendingFunBudget")) + parseFloat(startValue) - spending).toFixed(8)); | |
} else { | |
localStorage.setItem( | |
"pendingFunBudget", | |
(parseFloat(localStorage.getItem("pendingFunBudget")) + parseFloat(startValue)).toFixed(8)); | |
} | |
} | |
} | |
} | |
$lose.bind("DOMSubtreeModified", function(event) { | |
if ($(event.currentTarget).is(':contains("lose")')) { | |
lossStreak++; | |
loss++; | |
bets++; | |
wageredAmount += $stake.val() * 1; | |
lastBetWin = false; | |
if (lossStreak > Math.floor(Math.sqrt(Math.log2(balance / 1e-8)))) { | |
$payout.val(2); | |
} | |
minWait = Math.ceil(minWait * (1 + rand.nextFloat())); | |
maxWait = Math.ceil(minWait * (1 + rand.nextFloat())); | |
messify(); | |
streakProfit -= $stake.val(); | |
// console.log('Lose - StreakProfit: ' + streakProfit.toFixed(8)); | |
multiply(); | |
if (getBalance() > minimumBalance) { | |
timeouts.lose = setTimeout(nextClick, randomIntFromInterval(minWait, maxWait)); | |
} | |
} | |
}); | |
$win.bind("DOMSubtreeModified", function(event) { | |
if ($(event.currentTarget).is(":contains('win')")) { | |
if (maxLossStreak[lossStreak]) { | |
maxLossStreak[lossStreak] = maxLossStreak[lossStreak] + 1; | |
} else { | |
maxLossStreak[lossStreak] = 1; | |
} | |
wins++; | |
bets++; | |
lastBetWin = true; | |
wageredAmount += $stake.val() * 1; | |
streakProfit += parseFloat($win.text().split(' ')[6]); | |
// console.log('Win - StreakProfit: ' + streakProfit.toFixed(8)); | |
minWait = minWaitDefault; | |
maxWait = maxWaitDefault; | |
resetOnTargetHit(); | |
stopOnBonusCrossBalance(); | |
stopBeforeRedirect(); | |
buyFunIfBudgetAllows(); | |
if (stopped) { | |
stopped = true; | |
clearBindings(); | |
clearInterval(intervals.statPrinter); | |
return; | |
} | |
if (iHaveEnoughMoney()) { | |
reset(); | |
} | |
timeouts.win = setTimeout(nextClick, randomIntFromInterval(minWait, maxWait)); | |
} | |
}); | |
$err.bind("DOMSubtreeModified", function(event) { | |
if ($(event.currentTarget).is(':contains("timed out")')) { | |
console.log("Request timed out! :( But we're betting again!"); | |
nextClick(); | |
} | |
}); | |
setInterval(function() { | |
if ($('#bonus_eligible_msg').is(':visible')) { | |
$('#claim_bonus_link').click(); | |
setTimeout(function() { | |
$('#accept_bonus_terms').prop('checked', true); | |
$('#claim_bonus_button').click(); | |
}, 2000); | |
} | |
}, 10000); | |
window.onmousemove = e => { | |
extraSeed = e.clientX * e.clientY; | |
reseed(true); | |
}; | |
function updatePrice() { | |
fetch('https://api.gemini.com/v1/pubticker/btcsgd') | |
.then(res => res.json()) | |
.then(data => { | |
btcsgd = data.last; | |
console.log(data.last); | |
}); | |
setTimeout(updatePrice, 5000); | |
} | |
run_period = 500 * 6e4; | |
pause_period = 5 * 6e4; | |
SwitchPageTabs("double_your_btc"); | |
// btcsgd = 3.7e4; | |
// targetLs -= 1; | |
startGame(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment