// ==UserScript== // @name High-Low // @namespace http://tampermonkey.net/ // @version 0.1.3 // @description try to take over the world! // @author You // @match https://www.torn.com/loader.php?sid=high*ow // @require https://cdnjs.cloudflare.com/ajax/libs/vue/2.3.3/vue.js // @resource sourceCodePro https://fonts.googleapis.com/css?family=Source+Code+Pro // @require https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.10.0/highlight.min.js // @resource json-formatter_css https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.10.0/styles/default.min.css // @grant GM_getResourceText // @grant GM_addStyle // @grant GM_setValue // @grant GM_getValue // ==/UserScript== /* jshint -W097 */ /*global $, console, Raven, GM_addStyle, GM_getResourceText, Vue, hljs */ (function() { 'use strict'; var sourceCodePro = GM_getResourceText("codeSourcePro"); GM_addStyle(sourceCodePro); GM_addStyle("pre,code {font-family: 'Source Code Pro', monospace; font-size: 14px;}"); var js_css = GM_getResourceText("json-formatter_css"); GM_addStyle(js_css); //var bootstrap_css = GM_getResourceText("bootstrap_css"); //GM_addStyle(bootstrap_css); GM_addStyle(".hljs-number { color: blue; }"); var formatterConfig = { hoverPreviewEnabled: false, hoverPreviewArrayCount: 100, hoverPreviewFieldCount: 5, theme: 'dark', animateOpen: true, animateClose: true, open: 20 }; var changeTimeout = function() { var oldTimeout = setTimeout; /*global setTimeout:true */ setTimeout = function(a, b) { return oldTimeout(a, b/3); }; console.log("setTimout: changed"); }; let script = document.createElement('script'); script.appendChild(document.createTextNode('('+ changeTimeout +')();')); (document.head || document.body || document.documentElement).appendChild(script); class Card { constructor(number) { this.number = parseInt(number, 10); let card = this.getCardFromNumber(this.number); this.color = card[0]; this.rank = card[1]; } getCardFromNumber(number) { let mod = (number-1) % 4; let color = ""; if (mod === 0) { color = "spades"; } if (mod === 1) { color = "diamonds"; } if (mod === 2) { color = "hearts"; } if (mod === 3) { color = "clubs"; } let offset = 0; offset += 4; // Counter for 2 being first card, not 1 offset += 3; // Counter for using floor let rank = Math.floor((parseInt(number, 10)+offset)/4); return [color, rank]; } toString() { let rank = this.rank.toString(); console.log("rank:", rank); /* if (rank === "10") { rank = "T"; } */ if (rank === "11") { rank = "J"; } if (rank === "12") { rank = "Q"; } if (rank === "13") { rank = "K"; } if (rank === "14") { rank = "A"; } return this.color + "-" + rank; } toValue() { return this.rank; } } /* Initialize deck */ let deck = GM_getValue('deck', []); let createDeck = (deck) => { for (let i = 2; i < 54; i++) { deck.push(i); } GM_setValue('deck', deck); console.warn('new deck.length:', deck.length); // console.log(deck); return deck; } if (deck.length === 0) { deck = createDeck(deck); } let removeCard = (deck, card) => { /* console.log('[removeCard] card:', card); console.log('typeof card:', typeof card); console.log('typeof deck[5]:', typeof deck[5]); */ for( var i = 0; i < deck.length; i++) { if ( deck[i] === card) { deck.splice(i, 1); } } GM_setValue('deck', deck); // console.log('deck.length:', deck.length); } //******** // Controller //******** let processStartGame = function(db) { let formulaStats = db.DB.formulaStats[0]; let previousMultiplier = 0; let currentMultiplier = 0; if (formulaStats) { currentMultiplier = formulaStats.currentRatio; previousMultiplier = formulaStats.previousRatio; if (previousMultiplier !== currentMultiplier) { console.log("Multiplier changed!. Old: " + previousMultiplier + " => New: " + currentMultiplier); } } console.log("Multiplier:", currentMultiplier); //$("pre code.json").empty().append(JSON.stringify(db, null, 4)); console.log('myVue:', myVue); myVue.jsonobject = JSON.stringify(db, null, 4); // myVue.jsonobject = "Test"; // action.header = "Test"; Vue.nextTick(function() { hljs.initHighlighting.called = false; hljs.initHighlighting(); }); }; let processGameStarted = function(db) { // dealerCard is revealed; player picks High or Low // Note: Player also has the option to cash in but that is never considered // console.log("dealerCard:", db.currentGame[0].dealerCard); let dealerCard = new Card(db.currentGame[0].dealerCard); // console.warn('dealerCard.number:', dealerCard.number); removeCard(deck, dealerCard.number); if ('result' in db.currentGame[0]) { console.log('LOST'); removeCard(deck, parseInt(db.currentGame[0].playerCard, 10)); } if ('deckShuffled' in db.DB) { console.warn('db.DB.deckShuffled:', db.DB.deckShuffled); if (db.DB.deckShuffled === true) { deck = []; deck = createDeck(deck); } } console.assert(dealerCard.toString() === db.currentGame[0].dealerCardInfo.classCode, "Mismatch dealerCard " + dealerCard + " <-> " + db.currentGame[0].dealerCardInfo.classCode); console.log("dealerCard:", dealerCard.toString()); let arrayWithOdds = calculateOdds(dealerCard, deck); let lower = arrayWithOdds[0]; let higher = arrayWithOdds[1]; let numberOfCards = arrayWithOdds[2]; // testing //$('div.action-c.action-btn-wrap.active.low').addClass('iconPulseExpiring'); //$('div.action-r.action-btn-wrap.active.high').removeClass('active'); }; let processMakeChoice = function(db) { // The deal has ended. The choice is cash in or play on. if (db.currentGame[0].dealerCard !== db.currentGame[0].lastDealerCard) { // Reveal dealerCard of next deal // Page has been refreshed // There is no playerCard (there is a lastPlayerCard) db.currentGame[0].playerCard = db.currentGame[0].lastPlayerCard; db.currentGame[0].playerCardInfo = db.currentGame[0].lastPlayerCardInfo; // dealerCard assert will fail! } console.log("step:", db.currentGame[0].step); let dealerCard = new Card(db.currentGame[0].dealerCard); console.assert(dealerCard.toString() === db.currentGame[0].dealerCardInfo.classCode, "Mismatch dealerCard " + dealerCard + " <-> " + db.currentGame[0].dealerCardInfo.classCode); let playerCard = new Card(db.currentGame[0].playerCard); console.assert(playerCard.toString() === db.currentGame[0].playerCardInfo.classCode, "Mismatch playerCard " + playerCard + " <-> " + db.currentGame[0].playerCardInfo.classCode); console.log("playerCard:", playerCard.toString()); removeCard(deck, parseInt(db.currentGame[0].playerCard, 10)); if (db.DB.deckShuffled) { console.log('[processMakeChoice] deckShuffled', db.DB.deckShuffled); // New deck deck = []; deck = createDeck(deck); } }; $(document).ajaxSuccess( // On every detected Ajax communication function(event, jqxhr, settings, data) { // Make sure it was to or from /loader.php?sid=hiloJson&rfcv= if (settings.url.indexOf("loader.php?sid=hiloJson") != -1) { //console.log("event:", event); //console.log("jqxhr:", jqxhr); //console.log("settings:", settings); let db = JSON.parse(data); $("pre code.json").empty().append(JSON.stringify(db.currentGame, null, 4)); hljs.initHighlighting.called = false; hljs.initHighlighting(); console.log("db:", db); let status = db.status; console.log("db.status:", db.status); if (status === "startGame") { processStartGame(db); } if (status === "gameStarted") { processGameStarted(db); } if (status === "makeChoice") { processMakeChoice(db); } //console.log("db.currentGame:", db.currentGame); } }); //******** // VIEW //******** let boxTitle = "Let's play High-Low"; let boxHTML = "
" + "
" + "" + "" + boxTitle + "" + "
" + "
"+ "
" + "
" + "" + "
"+ //"
" + "" + "
" + "
" + "
"; $('.highlow-main-wrap').after(boxHTML); // Vue.js template //creating component var currentAction = Vue.extend({ template: '

{{ action.header }}

', data: function() { return { // action: "Current Action", actionStyle: { marginTop: "0px" } }; }, props: ['action'] }); var vueObject = Vue.extend({ template: '
', data: function() { return { vueObjectStyle: { marginTop: "0px" } }; }, props: ['jsonobject'] }); //registering component Vue.component('current-action', currentAction); Vue.component('vue-object', vueObject); //initializing the Vue application let action = {}; action.header = "Current Action"; let myVue = new Vue({ el: "#app", data: function() { return { jsonobject: "Start", action: action }; } }); //******** // MODEL //******** /** * @param {array} deck, cards by number * @return {array} number of cards by rank where key is the rank \ * and val is the number of that rank in the deck */ let parseDeck = function(deck) { // Create new parsedDeck from deck let parsedDeck = []; // parsedDeck runs from 0 to 14 where 0 and 1 are always 0. // Real deck values count from 2 to 14 (ace) for (let i = 0; i <= 15; i++) { parsedDeck[i] = 0; } let deckLength = deck.length; for (let i = 0; i < deckLength; i++) { /* if (i < 10) { console.log('first cards:', deck[i]); } */ let offset = 0; offset += 4; // Counter for 2 being first card, not 1 offset += 3; // Counter for using floor let rank = Math.floor((parseInt(deck[i], 10)+offset)/4); parsedDeck[rank]++; } if (deckLength === 0) { // Shuffle -> create new deck for (let i = 2; i < 15; i++) { parsedDeck[i] = 4; } } return parsedDeck; }; let calculateOdds = function(dealerCard, deck) { let parsedDeck = parseDeck(deck); let deckLength = parsedDeck.length; let numberOfCards = 0; let lowerDoesNotLose = 0; // Equals count as 'not lose' let higherDoesNotLose = 0; // Equals count as 'not lose' for (let i = 0; i < deckLength; i++) { if (i <= dealerCard.rank) { lowerDoesNotLose += parsedDeck[i]; } if (i >= dealerCard.rank) { higherDoesNotLose += parsedDeck[i]; } numberOfCards += parsedDeck[i]; } console.assert(deck.length === numberOfCards, 'deck.length: '+deck.length+' <> numberOfCards: '+numberOfCards); // console.log("[calculteOdds] parsedDeck;", parsedDeck); console.log("[calculateOdds] lowerDoesNotLose:", lowerDoesNotLose); console.log("[calculateOdds] higherDoesNotLose:", higherDoesNotLose); console.log("[calculateodds] numberOfCards:", numberOfCards); return [lowerDoesNotLose, higherDoesNotLose, numberOfCards]; }; })();