View difference between Paste ID: wM8gfu2f and TQhp8K72
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);