SHOW:
|
|
- or go back to the newest paste.
| 1 | // Constants | |
| 2 | - | var rom_code = '4a2339ad-2b50-11e7-ae4c-61eeb6253594'; |
| 2 | + | var rom_code = ''; //redacted |
| 3 | var version = 'v2.3'; | |
| 4 | var rom = {channels: {pysstatus: '298589684492140546'}};
| |
| 5 | var iv = Array.apply(null, new Array(252)).map(Number.prototype.valueOf,1); | |
| 6 | // var r = Array.apply(null, new Array(252)).map(Number.prototype.valueOf,100); | |
| 7 | // var home_lat = 51.507406; var home_lng = -0.127675; | |
| 8 | var known = []; // keeps track of Pokemon already notified | |
| 9 | var overload = 0; // tracks Discord notification overload | |
| 10 | ||
| 11 | ||
| 12 | // 1) converts timecodes into legible times (call with no parameter for time now) | |
| 13 | function time(timecode) {
| |
| 14 | if (typeof timecode == 'undefined') {var date = new Date();} else {var date = new Date(timecode);};
| |
| 15 | var hours = date.getHours(); | |
| 16 | var minutes = "0" + date.getMinutes(); | |
| 17 | var seconds = "0" + date.getSeconds(); | |
| 18 | return hours + ':' + minutes.substr(-2) + ':' + seconds.substr(-2); | |
| 19 | } | |
| 20 | ||
| 21 | ||
| 22 | // 2) converts Pokemon spawns into text notifications for Discord | |
| 23 | function tellD(pokemon) {
| |
| 24 | var iv_text = ''; | |
| 25 | if (pokemon.attack != -1 && pokemon.defence != -1 && pokemon.stamina != -1){
| |
| 26 | iv_text = Math.round(((pokemon.attack + pokemon.defence + pokemon.stamina)/45)*100) + '% | '; | |
| 27 | } | |
| 28 | ||
| 29 | // tries to retrieve postcode and suburb from OpenStreetMap | |
| 30 | urlrg = 'https://nominatim.openstreetmap.org/reverse?format=json&lat='+pokemon.center.lat+'&lon='+pokemon.center.lng | |
| 31 | var xhs = new XMLHttpRequest(); | |
| 32 | xhs.open('GET', urlrg, false);
| |
| 33 | xhs.onload = function() {if (xhs.status != 200) {notifyD("Failure: OSM; "+xhs.status, rom.channels.pysstatus)}};
| |
| 34 | xhs.send(); | |
| 35 | try {var address = JSON.parse(xhs.response).address; var suburb = address.suburb; var postcode = address.postcode;} catch(error) {}
| |
| 36 | if (typeof postcode == 'undefined') {var postcode = "?"; };
| |
| 37 | if (typeof suburb == 'undefined') {var suburb = ""; } else {var suburb = ' ' + suburb};
| |
| 38 | if (postcode.indexOf(' ') != -1) {postcode = postcode.substr(0,postcode.indexOf(' '));};
| |
| 39 | ||
| 40 | // tries to retrieve more-accurate postcode from postcodes.io, and replaces OSM postcode if successful, adds ? if not | |
| 41 | urlps = 'https://api.postcodes.io/postcodes?lat='+pokemon.center.lat+'&lon='+pokemon.center.lng | |
| 42 | var xht = new XMLHttpRequest(); | |
| 43 | xht.open('GET', urlps, false);
| |
| 44 | xht.onload = function() {if (xht.status != 200) {notifyD("Failure: postcodes.io; "+xht.status,rom.channels.pysstatus)}};
| |
| 45 | xht.send(); | |
| 46 | try {postcode = JSON.parse(xht.response).result[0].outcode;} catch(error) {postcode += '?'; };
| |
| 47 | ||
| 48 | url = 'http://www.google.com/maps/place/' + pokemon.center.lat + ',' + pokemon.center.lng; | |
| 49 | ||
| 50 | var name = pokeDict[pokemon.id].name; | |
| 51 | if (pokemon.id == 201 && pokemon.form != 0) {name = name + ' ' + String.fromCharCode(pokemon.form + 64)}
| |
| 52 | ||
| 53 | var expiry_time = time(pokemon.despawn*1000); | |
| 54 | var rem_time = timeToString(pokemon.remainingTime()); | |
| 55 | ||
| 56 | return name+' | '+iv_text+postcode+suburb+' | '+rem_time+' (until '+expiry_time+') | '+url; | |
| 57 | } | |
| 58 | ||
| 59 | ||
| 60 | // 3) converts Pokemon spawns into map image url | |
| 61 | function StatIm(pokemon) {
| |
| 62 | return 'https://maps.googleapis.com/maps/api/staticmap?markers='+pokemon.center.lat+','+pokemon.center.lng+'&zoom=15&size=400x400&sensor=false&key='+rom.keys.google; | |
| 63 | } | |
| 64 | ||
| 65 | ||
| 66 | // 4) sends messages to Discord | |
| 67 | function notifyD(content, channel, embed_url) {
| |
| 68 | var xhr = new XMLHttpRequest(); | |
| 69 | xhr.open('POST', "https://discordapp.com/api/channels/"+channel+"/messages", false);
| |
| 70 | xhr.setRequestHeader('Authorization', 'Bot '+rom.keys.bot);
| |
| 71 | xhr.setRequestHeader('Content-Type', 'application/json');
| |
| 72 | xhr.onload = function() {
| |
| 73 | if (xhr.status != 200) {
| |
| 74 | console.log('Failed to post; ' + xhr.status);
| |
| 75 | if (xhr.status == 429) {overload++};
| |
| 76 | } | |
| 77 | }; | |
| 78 | var sender = '{"content":"'+content+'"';
| |
| 79 | if (!!embed_url) {sender += ',"embed": {"image": {"url":"'+embed_url+'"}}}'} else {sender += '}'};
| |
| 80 | xhr.send(sender); | |
| 81 | if (!!embed_url) {console.log('[I] ['+channel+'] '+content)} else {console.log('['+channel+'] '+content)};
| |
| 82 | } | |
| 83 | ||
| 84 | ||
| 85 | // 5) polls map for new desired Pokemon and returns list of Pokemon to notify | |
| 86 | function poll() {
| |
| 87 | output = []; | |
| 88 | for (i = 0, len = this.pokemons.length; i < len; i++) {
| |
| 89 | test = this.pokemons[i]; | |
| 90 | test_iv = (test.attack + test.defence + test.stamina) - 45; | |
| 91 | if (test_iv >= iv[test.id]) {
| |
| 92 | // test_x = Math.abs(test.center.lat - home_lat)*110.574; | |
| 93 | // test_y = Math.abs(test.center.lng - home_lng)*69.298; | |
| 94 | // if (test_x*test_x + test_y*test_y < r[test.id]*r[test.id]) {
| |
| 95 | if (indexOfPokemons(test,known) == -1) {
| |
| 96 | test.iv = test_iv; | |
| 97 | known.push(test); | |
| 98 | output.push(test); | |
| 99 | }; | |
| 100 | //} | |
| 101 | }; | |
| 102 | }; | |
| 103 | return output | |
| 104 | } | |
| 105 | ||
| 106 | ||
| 107 | // 6) for each Pokemon in list, runs tellD and StatIm, then selects channels and posts to them | |
| 108 | function mail(list) {
| |
| 109 | if (list.length != 0) {
| |
| 110 | item = list.pop(); | |
| 111 | var notif = tellD(item); var urlim = StatIm(item); | |
| 112 | // channel selection and posting | |
| 113 | if (!!rom.allTarget[item.id]) {
| |
| 114 | notifyD(notif, rom.channels[rom.allTarget[item.id]], urlim); | |
| 115 | if (!!rom.secondTarget[item.id]) {
| |
| 116 | if (!rom.secondIV[item.id] || (!!rom.secondIV[item.id] && item.iv >= rom.secondIV[item.id])) {
| |
| 117 | notifyD(notif, rom.channels[rom.secondTarget[item.id]], urlim); | |
| 118 | }; | |
| 119 | }; | |
| 120 | }; | |
| 121 | var highIVfilter = 0; if (!!rom.highIV[item.id]) {highIVfilter = rom.highIV[item.id]};
| |
| 122 | if (item.iv >= highIVfilter) {notifyD(notif, rom.channels[rom.highchannel], urlim)};
| |
| 123 | // continue through list with delay = postdelay | |
| 124 | setTimeout(function(){mail(list)}, rom.postdelay*1000);
| |
| 125 | } | |
| 126 | } | |
| 127 | ||
| 128 | ||
| 129 | // A) updates ROM from internet and refreshes Discord connection (every 20 minutes) | |
| 130 | function load() {
| |
| 131 | // sets map filters (IV filter = 100%; select all) | |
| 132 | try {
| |
| 133 | min_iv = 100; | |
| 134 | for (i = 1, len = 252; i < len; i++) {localStorage.setItem(i,1)};
| |
| 135 | } catch(error) {};
| |
| 136 | ||
| 137 | // updates ROM | |
| 138 | var xhr = new XMLHttpRequest; | |
| 139 | xhr.open('GET', 'https://jsonblob.com/api/jsonBlob/'+rom_code, false);
| |
| 140 | xhr.onload = function() {
| |
| 141 | if (xhr.status == 200) {
| |
| 142 | try {rom = JSON.parse(xhr.response)} catch(error) {notifyD("Failed to parse ROM", rom.channels.pysstatus)}
| |
| 143 | } else {
| |
| 144 | notifyD("Failed to fetch ROM; "+xhr.status, rom.channels.pysstatus)
| |
| 145 | } | |
| 146 | }; | |
| 147 | xhr.send(); | |
| 148 | ||
| 149 | // refreshes Discord connection | |
| 150 | var ws = new WebSocket('wss://gateway.discord.gg');
| |
| 151 | gateway = JSON.stringify({
| |
| 152 | "op": 2, | |
| 153 | "d": {
| |
| 154 | "token": rom.keys.bot, | |
| 155 | "properties": {"$os": "linux", "$browser": "sometestingbrowser", "$device": "sometestingdevice", "$referrer": "", "$referring_domain": "",},
| |
| 156 | "compress": true, | |
| 157 | "large_threshold": 250, | |
| 158 | } | |
| 159 | }); | |
| 160 | setTimeout(function(){ws.send(gateway)}, 2 * 1000);
| |
| 161 | ||
| 162 | // updates bot IV filter based on ROM | |
| 163 | for (i = 1, len = iv.length; i < len; i++) {
| |
| 164 | if (!!rom.allTarget[i]) {
| |
| 165 | iv[i] = -48; | |
| 166 | if (!!rom.allIV[i]) {iv[i] = rom.allIV[i]};
| |
| 167 | } else {
| |
| 168 | iv[i] = 0; | |
| 169 | if (!!rom.highIV[i]) {iv[i] = rom.highIV[i]};
| |
| 170 | } | |
| 171 | } | |
| 172 | ||
| 173 | // clears expired Pokemon | |
| 174 | j = known.length; | |
| 175 | while(j--){
| |
| 176 | if (known[j].remainingTime() < 0) {known.splice(j,1)}
| |
| 177 | }; | |
| 178 | ||
| 179 | // checks overload and posts OK status | |
| 180 | var stat = version+' | '+rom.changelog+' | '+time()+' | '+known.length; | |
| 181 | if (overload != 0) {stat += (' | overload: ' + overload); overload = 0;};
| |
| 182 | setTimeout(function(){notifyD(stat, rom.channels.pysstatus)}, 4 * 1000);
| |
| 183 | } | |
| 184 | ||
| 185 | ||
| 186 | // B) updates map, polls map, and mails Pokemon (every 20 seconds) | |
| 187 | function loop(){
| |
| 188 | try {reloadPokemons();} catch(error) {};
| |
| 189 | setTimeout(function(){mail(poll())},2*1000);
| |
| 190 | console.log('Ran at '+time());
| |
| 191 | } | |
| 192 | ||
| 193 | ||
| 194 | // run load() every 20 minutes | |
| 195 | load(); loader = setInterval(load, 20*60*1000); | |
| 196 | // run loop() (poll() first time) every 20 seconds with 5 second offset | |
| 197 | setTimeout(function() {poll(); timer = setInterval(loop, 20*1000);}, 5*1000); |