SHARE
TWEET

Untitled

a guest Apr 21st, 2019 83 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. const steem = require("steem");
  2. const fetch = require("node-fetch");
  3. const md5 = require("md5");
  4. const KEYS = require("./keys.json");
  5. const cardData = require("./cardData.json");
  6.  
  7. class Battle {
  8.  
  9.   constructor(callback, appName = "steemmonsters", matchType = "Ranked") {
  10.     this.callback = callback;
  11.     this.status = {};
  12.     this.submittedTeam = false;
  13.     //broadcast sm_find_match
  14.     steem.broadcast.customJson(KEYS.posting, [], [KEYS.username], "sm_find_match", JSON.stringify({
  15.       match_type: matchType,
  16.       app: appName
  17.     }), (err, result) => {
  18.       if (err) throw err;
  19.       console.log("Broadcasted sm_find_match");
  20.       this.findMatchId = result.id;
  21.     });
  22.     //start /battle/status check loop
  23.     this._checkInterval = setInterval(() => {
  24.       this._checkBattleStatus();
  25.     }, 2500);
  26.     //
  27.   }
  28.   end() {
  29.     this.ended = true;
  30.     clearInterval(this._checkInterval);
  31.     delete this;
  32.   }
  33.  
  34.   setTeam(team) {
  35.     this.team = team;
  36.   }
  37.   broadcastTeam(summoner, monsters, skipReveal = false) {
  38.     const secret = Battle.generatePassword();
  39.     const teamHash = md5(summoner + "," + monsters.join() + "," + secret)
  40.     const team = {
  41.       summoner,
  42.       monsters,
  43.       secret
  44.     };
  45.  
  46.     this.submittedTeam = true;
  47.     var data = {
  48.       trx_id: this.findMatchId,
  49.       team_hash: teamHash,
  50.       app: this.appName
  51.     };
  52.     if (skipReveal) {
  53.       data.summoner = summoner;
  54.       data.monsters = monsters;
  55.       data.secret = secret;
  56.     }
  57.     steem.broadcast.customJson(KEYS.posting, [], [KEYS.username], "sm_submit_team", JSON.stringify(data), async (err, result) => {
  58.       if (err) throw err;
  59.       console.log("Broadcasted sm_submit_team");
  60.       this.findMatchId = result.id;
  61.       if (!skipReveal) {
  62.         await new Promise(resolve => setTimeout(resolve, 3300));
  63.         console.log("Revealing team...");
  64.         steem.broadcast.customJson(KEYS.posting, [], [KEYS.username], "sm_team_reveal", JSON.stringify({
  65.           ...data,
  66.           summoner: summoner,
  67.           monsters: monsters,
  68.           secret: secret
  69.         }), (err, result) => {
  70.           console.log("Revealed team!");
  71.         });
  72.       }
  73.     });
  74.   }
  75.  
  76.   _revealTeam() {
  77.  
  78.   }
  79.   async _checkBattleStatus() {
  80.     if (!this.findMatchId) return;
  81.     const rawResponse = await fetch("https://api.steemmonsters.io/battle/status?id=" + this.findMatchId);
  82.     const json = await rawResponse.json();
  83.     this.status.data = json;
  84.  
  85.     if ((typeof json) === "string") {
  86.       console.log(json);
  87.       this.status.statusName = "battleTxProcessing";
  88.       this.callback(this.status);
  89.       return;
  90.     }
  91.  
  92.     if (json.error) {
  93.       this.status.statusName = "error";
  94.     } else if (json.status === 0) {
  95.       this.status.statusName = "searchingForEnemy";
  96.     } else if (json.status === 1) {
  97.       this.status.statusName = "enemyFound";
  98.     } else if (json.status === 3) {
  99.       this.status.statusName = "noEnemyFound";
  100.     }
  101.     this.callback(this.status);
  102.   }
  103.   _checkBattleTrxStatus() {
  104.  
  105.   }
  106.   static generatePassword(length = 10) {
  107.     var charset = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789",
  108.       retVal = "";
  109.     for (var i = 0, n = charset.length; i < length; ++i) {
  110.       retVal += charset.charAt(Math.floor(Math.random() * n));
  111.     }
  112.     return retVal;
  113.   }
  114. }
  115. async function getSMJson(url) {
  116.   const res = await (fetch("https://api.steemmonsters.io" + url));
  117.   const text = await res.text();
  118.   try {
  119.     return JSON.parse(text);
  120.   } catch (e) {
  121.     console.log("Invalid JSON; retrying", text)
  122.     await new Promise((resolve) => setTimeout(resolve, 1000));
  123.     return await getSMJson();
  124.   }
  125. }
  126.  
  127. function cardBcx(xp, rarity, edition, gold) {
  128.   if (edition === 3) edition = 1; //reward cards are same as beta
  129.   var cards = 0;
  130.   if (edition == 0 && gold == 0 && rarity == 4)
  131.     cards = (xp / 1000) + 1
  132.   if (edition == 0 && gold == 0 && rarity == 3)
  133.     cards = (xp / 250) + 1
  134.   if (edition == 0 && gold == 0 && rarity == 2)
  135.     cards = (xp / 100) + 1
  136.   if (edition == 0 && gold == 0 && rarity == 1)
  137.     cards = (xp / 20) + 1
  138.   if (edition == 0 && gold == 1 && rarity == 4)
  139.     cards = xp / 2500
  140.   if (edition == 0 && gold == 1 && rarity == 3)
  141.     cards = xp / 1000
  142.   if (edition == 0 && gold == 1 && rarity == 2)
  143.     cards = xp / 500
  144.   if (edition == 0 && gold == 1 && rarity == 1)
  145.     cards = xp / 250
  146.  
  147.   // Beta Edition Cards per XP
  148.   if (edition == 1 && gold == 0 && rarity == 4)
  149.     cards = (xp / 750) + 1
  150.   if (edition == 1 && gold == 0 && rarity == 3)
  151.     cards = (xp / 175) + 1
  152.   if (edition == 1 && gold == 0 && rarity == 2)
  153.     cards = (xp / 75) + 1
  154.   if (edition == 1 && gold == 0 && rarity == 1)
  155.     cards = (xp / 15) + 1
  156.   if (edition == 1 && gold == 1 && rarity == 4)
  157.     cards = xp / 2000
  158.   if (edition == 1 && gold == 1 && rarity == 3)
  159.     cards = xp / 800
  160.   if (edition == 1 && gold == 1 && rarity == 2)
  161.     cards = xp / 400
  162.   if (edition == 1 && gold == 1 && rarity == 1)
  163.     cards = xp / 200
  164.   // Promo Edition Cards per XP
  165.   if (edition == 2 && gold == 0 && rarity == 4)
  166.     cards = (xp / 1000) + 1
  167.   if (edition == 2 && gold == 0 && rarity == 3)
  168.     cards = (xp / 250) + 1
  169.   if (edition == 2 && gold == 0 && rarity == 2)
  170.     cards = (xp / 100) + 1
  171.   if (edition == 2 && gold == 0 && rarity == 1)
  172.     cards = (xp / 20) + 1
  173.   if (edition == 2 && gold == 1 && rarity == 4)
  174.     cards = xp / 2500
  175.   if (edition == 2 && gold == 1 && rarity == 3)
  176.     cards = xp / 1000
  177.   if (edition == 2 && gold == 1 && rarity == 2)
  178.     cards = xp / 500
  179.   if (edition == 2 && gold == 1 && rarity == 1)
  180.     cards = xp / 250
  181.   if (cards === 0) throw new Error("Unable to find card BCX");
  182.   return cards
  183. }
  184.  
  185. async function main() {
  186.   let curBlock = -1;
  187.   steem.api.streamBlockNumber((err, b) => curBlock = b);
  188.   let ourCollection = (await getSMJson("/cards/collection/" + KEYS.username)).cards;
  189.   setInterval(async () => {
  190.     ourCollection = (await getSMJson("/cards/collection/" + KEYS.username)).cards;
  191.     scanCollection();
  192.   }, 1200000);
  193.  
  194.   function scanCollection() {
  195.     ourCollection = ourCollection.filter(card => canPlayCard(card));
  196.   }
  197.   scanCollection();
  198.   setInterval(() => scanCollection(), 25000);
  199.  
  200.   function bestCard(id) {
  201.     return ourCollection.filter(card => (card.card_detail_id === id))
  202.       .map(card => ({
  203.         ...card,
  204.         rarity: cardData.filter(cardD => card.card_detail_id === cardD.id)[0].rarity
  205.       }))
  206.       .sort((a, b) => {
  207.         console.log(a, b);
  208.         return cardBcx(a.xp, a.rarity, a.edition, a.gold) - cardBcx(b.xp, b.rarity, b.edition, b.gold)
  209.       }).reverse()[0];
  210.   }
  211.  
  212.   function canPlayCard(card) {
  213.     if (card.market_id)
  214.       return false;
  215.     if (!card.last_transferred_block || !card.last_used_block)
  216.       return true;
  217.  
  218.     if (curBlock === -1) return true;
  219.     var last_block = curBlock;
  220.     return card.last_transferred_block <= last_block - 201600 || card.last_used_block <= last_block - 201600;
  221.   }
  222.   var submittedTeam = false;
  223.   const battle = new Battle(async status => {
  224.     console.log(status.statusName);
  225.     if (!submittedTeam && (status.statusName === "enemyFound")) {
  226.       var manaUsed = 3; //for summoner
  227.       var colorSummoners = {
  228.         Red: 5,
  229.         Blue: 16,
  230.         Green: 27,
  231.         White: 38,
  232.         Black: 49
  233.       };
  234.       let bestSpliner = "Blue";
  235.       let cardsToScore = possibleCards(bestSpliner, status.data)
  236.  
  237.       function possibleCards(Blue, battle = {}) {
  238.         return cards.filter(card => {
  239.           if (card.type !== "Monster") return;
  240.           if ((card.color !== "Blue") && (card.color !== "Gray")) return;
  241.           if (battle.ruleset === "Lost Legendaries" && card.rarity === 4) return;
  242.           if (battle.ruleset === "Rise of the Commons" && card.rarity > 2) return;
  243.           if (battle.ruleset === "Taking Sides" && card.color === "Gray") return;
  244.           //these should actually take in to account the level of the card. creeping ooze becomes a melee monster @ level 4, but this never allows it
  245.           if (battle.ruleset === "Up Close & Personal" && card.stats.attack[0] === 0) return;
  246.           if (battle.ruleset === "Broken Arrows" && card.stats.ranged[card.stats.ranged.length - 1] > 0) return;
  247.           if (battle.ruleset === "Little League" && (card.stats.mana[0] > 4)) return;
  248.           return true;
  249.         });
  250.  
  251.       };
  252.       var summoner = cardData.filter(card => card.id === colorSummoners[bestSpliner])[0];
  253.       for (let i = 0; i < cardsToScore.length; i++) {
  254.         const card = cardsToScore[i];
  255.         const cardMana = card.stats.mana[0] ? card.stats.mana[0] : card.stats.mana;
  256.         //verify it's in our collection
  257.         if (ourCollection.filter(colCard => card.id === colCard.card_detail_id)[0] === undefined) continue;
  258.         if ((manaUsed + cardMana) > status.data.mana_cap) {
  259.           if (team.length < 6) continue;
  260.           let lastCardMana = team[team.length - 1].stats.mana[0] ? team[team.length - 1].stats.mana[0] : team[team.length - 1].stats.mana;
  261.           if (((manaUsed - lastCardMana + cardMana) <= status.data.mana_cap) && (cardMana > lastCardMana)) {
  262.             team[team.length - 1] = card;
  263.           } else {
  264.             continue;
  265.           }
  266.         } else if (team.length < 6) {
  267.           if (card.stats.ranged[0] === 0) {
  268.             //not a ranged monster
  269.             if (card.id !== 91) nonRangedUsed++; //ignore ooze
  270.           } else if ((nonRangedUsed < 2) && (team.length > 4)) {
  271.             //Ranged monster, and we have more than 4 monsters already. We need more melee monsters now, as we have either only 0 or 1, so skip this
  272.             continue;
  273.           }
  274.           team.push(card);
  275.         }
  276.         manaUsed += cardMana;
  277.         battle.broadcastTeam(bestCard(summoner.id).uid, team.map(card => {
  278.           return bestCard(card.id).uid
  279.         }));
  280.         submittedTeam = true;
  281.       }
  282.     }
  283.   });
  284.  
  285. }
  286. main();
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
Not a member of Pastebin yet?
Sign Up, it unlocks many cool features!
 
Top