pokeplot 0.2.0beta
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.rspec +4 -0
- data/LICENSE.txt +621 -0
- data/README.md +99 -0
- data/Rakefile +9 -0
- data/bin/pokeplot +223 -0
- data/lib/pokeplot/api.rb +109 -0
- data/lib/pokeplot/database.rb +22 -0
- data/lib/pokeplot/helpers/array.rb +5 -0
- data/lib/pokeplot/helpers/cell_ids.rb +14 -0
- data/lib/pokeplot/helpers/math.rb +20 -0
- data/lib/pokeplot/helpers/time.rb +15 -0
- data/lib/pokeplot/miner.rb +241 -0
- data/lib/pokeplot/pushbullet.rb +41 -0
- data/lib/pokeplot/socket.rb +65 -0
- data/lib/pokeplot/version.rb +3 -0
- data/lib/pokeplot/web/canvasjs.min.js +555 -0
- data/lib/pokeplot/web/index.html +158 -0
- data/lib/pokeplot/web.rb +26 -0
- data/lib/pokeplot.rb +7 -0
- data/spec/api_spec.rb +148 -0
- data/spec/database_spec.rb +33 -0
- data/spec/miner_spec.rb +110 -0
- data/spec/pushbullet_spec.rb +31 -0
- data/spec/socket_spec.rb +45 -0
- data/spec/spec_helper.rb +115 -0
- data/spec/web_spec.rb +18 -0
- metadata +240 -0
data/README.md
ADDED
@@ -0,0 +1,99 @@
|
|
1
|
+
# Pokeplot
|
2
|
+
|
3
|
+
[![Gem Version](https://badge.fury.io/rb/pokeplot.svg)](https://badge.fury.io/rb/pokeplot) [![Test Coverage](https://codeclimate.com/github/xssc/pokeplot/badges/coverage.svg)](https://codeclimate.com/github/xssc/pokeplot/coverage) [![Dependency Status](https://gemnasium.com/badges/github.com/xssc/pokeplot.svg)](https://gemnasium.com/github.com/xssc/pokeplot) [![Gem](https://img.shields.io/gem/dt/pokeplot.svg?maxAge=2592000)](https://rubygems.org/gems/pokeplot)
|
4
|
+
|
5
|
+
Pokeplot is a gem to collect Pokemon Go spawning data and visualize it. It is currently a pre-release, expect frequent updates.
|
6
|
+
|
7
|
+
![Graph Example](http://i.imgur.com/XRp14KV.png)
|
8
|
+
|
9
|
+
### Contents
|
10
|
+
|
11
|
+
[**Getting Started**](https://github.com/xssc/pokeplot#getting-started)
|
12
|
+
|
13
|
+
[**Usage**](https://github.com/xssc/pokeplot#usage)
|
14
|
+
|
15
|
+
[**Features**](https://github.com/xssc/pokeplot#features)
|
16
|
+
|
17
|
+
[**Notifications**](https://github.com/xssc/pokeplot#notifications)
|
18
|
+
|
19
|
+
[**Updating**](https://github.com/xssc/pokeplot#updating)
|
20
|
+
|
21
|
+
[**Future and TODO**](https://github.com/xssc/pokeplot#future--todo)
|
22
|
+
|
23
|
+
[**Contanct, Requests, and Issues**](https://github.com/xssc/pokeplot#contact-requests-and-issues)
|
24
|
+
|
25
|
+
[**Contributing**](https://github.com/xssc/pokeplot#contributing)
|
26
|
+
|
27
|
+
## Getting Started
|
28
|
+
|
29
|
+
Installing pokeplot is insanley easy. All you need is ruby 2.3.1. Don't have it? [Follow our easy Ruby install guide!](https://github.com/xssc/pokeplot/wiki/Install-Ruby-2.3.1)
|
30
|
+
|
31
|
+
We use MongoDB to quickly store large numbers of encounters. Download and install it from [HERE](https://www.mongodb.com/download-center?jmp=nav#community). Don't worry, it's easy!
|
32
|
+
|
33
|
+
Once done the only installation command is:
|
34
|
+
|
35
|
+
$ gem install pokeplot --pre
|
36
|
+
|
37
|
+
## Usage
|
38
|
+
|
39
|
+
Open a terminal/cmd and make a folder for Pokeplot configuration to be stored
|
40
|
+
|
41
|
+
$ mkdir pokeplot
|
42
|
+
$ cd pokeplot
|
43
|
+
|
44
|
+
Then to generate the default config.json file, run
|
45
|
+
|
46
|
+
$ pokeplot config
|
47
|
+
|
48
|
+
Then go to the pokeplot folder you just made and open config.json in your favorite text editor. There are `_info` lines to help you along the way.
|
49
|
+
|
50
|
+
Then simply run
|
51
|
+
|
52
|
+
$ pokeplot
|
53
|
+
|
54
|
+
Real time graphs will be available at `http://localhost:5001` while pokeplot is running.
|
55
|
+
|
56
|
+
## Features
|
57
|
+
* Single or Multithread
|
58
|
+
* Divides coordinates in a way that doesn't cause larger teleportations due to more accounts
|
59
|
+
* Multiple accounts (Combo lists also supported)
|
60
|
+
* Configurable config.json
|
61
|
+
* Real time website with graphs
|
62
|
+
* Ability to handle real time data yourslef with Ruby (Examples soon)
|
63
|
+
* Notifications
|
64
|
+
* A developer who has tons of freetime to work on this project!
|
65
|
+
|
66
|
+
|
67
|
+
## Notifications
|
68
|
+
|
69
|
+
Currently Pokeplt only supports Pushbullet. [Follow the easy setup guide here](https://github.com/xssc/pokeplot/wiki/Pushbullet)
|
70
|
+
|
71
|
+
|
72
|
+
## Updating
|
73
|
+
|
74
|
+
When a update is available for pokeplot, only one command is needed to install it
|
75
|
+
|
76
|
+
$ gem update pokeplot
|
77
|
+
|
78
|
+
Pokeplot will be updated frequently, I have lots of spare time.
|
79
|
+
|
80
|
+
## Future & TODO
|
81
|
+
The following is planned (but not guarenteed)
|
82
|
+
|
83
|
+
* Maps
|
84
|
+
* More graphs
|
85
|
+
* Get Cell Ids in Ruby
|
86
|
+
* Add more notification services
|
87
|
+
* Fix any issues that arrise
|
88
|
+
* Lots more
|
89
|
+
|
90
|
+
## Contact, Requests, and Issues
|
91
|
+
If you have any problems using this, I will do whatever I can to help you get up and running. Your options are
|
92
|
+
|
93
|
+
* Create an issue [HERE](https://github.com/xssc/pokeplot/issues)
|
94
|
+
* Email me @ xssc820@gmail.com
|
95
|
+
* Or PM me on reddit at [/u/xssc](https://www.reddit.com/message/compose?to=xssc)
|
96
|
+
|
97
|
+
## Contributing
|
98
|
+
|
99
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/xssc/pokeplot
|
data/Rakefile
ADDED
data/bin/pokeplot
ADDED
@@ -0,0 +1,223 @@
|
|
1
|
+
#!usr/bin/env ruby
|
2
|
+
require 'pokeplot'
|
3
|
+
require 'json'
|
4
|
+
|
5
|
+
|
6
|
+
default_config = %{ {
|
7
|
+
"_info": "Enter your accounts here, as many as you want",
|
8
|
+
"accounts": [
|
9
|
+
{
|
10
|
+
"username": "account1",
|
11
|
+
"password": "password1",
|
12
|
+
"provider": "ptc"
|
13
|
+
},
|
14
|
+
{
|
15
|
+
"username": "account2@gmail.com",
|
16
|
+
"password": "password2",
|
17
|
+
"provider": "google"
|
18
|
+
}
|
19
|
+
],
|
20
|
+
|
21
|
+
"_info": "Enter the origin scan coordinates below [lat, lng]",
|
22
|
+
"location": [
|
23
|
+
40.7829,
|
24
|
+
-73.9654
|
25
|
+
],
|
26
|
+
|
27
|
+
"_info": "settings for API",
|
28
|
+
"api": {
|
29
|
+
"encryption_path": "/path/to/encryption/file",
|
30
|
+
"log": true
|
31
|
+
},
|
32
|
+
|
33
|
+
"_info": "settings for mongoDB (default host is already set)",
|
34
|
+
"mongo": {
|
35
|
+
"host": "127.0.0.1:27017"
|
36
|
+
},
|
37
|
+
|
38
|
+
"_info": "settings for the data miner",
|
39
|
+
"miner": {
|
40
|
+
"enabled": true,
|
41
|
+
"threaded": true,
|
42
|
+
"range": 40,
|
43
|
+
"interval": 900,
|
44
|
+
"pokemon": true,
|
45
|
+
"forts": true,
|
46
|
+
"log": true
|
47
|
+
},
|
48
|
+
|
49
|
+
"_info": "Pushbullet settings - see the wiki for easy set-up guide",
|
50
|
+
"pushbullet": {
|
51
|
+
"enabled": false,
|
52
|
+
"api_key": "apiKey",
|
53
|
+
"pokemon": [
|
54
|
+
"SNORLAX",
|
55
|
+
"DRATINI",
|
56
|
+
"DRAGONITE",
|
57
|
+
"MEWTWO"
|
58
|
+
]
|
59
|
+
},
|
60
|
+
|
61
|
+
"_info": "settings for socket for real time webpage updates RECOMENDED YOU DONT CHANGE THIS",
|
62
|
+
"socket": {
|
63
|
+
"enabled": true,
|
64
|
+
"host": "0.0.0.0",
|
65
|
+
"port": "9090",
|
66
|
+
"log": true
|
67
|
+
},
|
68
|
+
|
69
|
+
"_info": "Web server settings",
|
70
|
+
"webserver": {
|
71
|
+
"enabled": true,
|
72
|
+
"host": "0.0.0.0",
|
73
|
+
"port": 5001
|
74
|
+
},
|
75
|
+
|
76
|
+
"_info": "optional ptc account combo list",
|
77
|
+
"combos": [
|
78
|
+
"SToCQSyJuVXj:BGyoYefXjQQZ",
|
79
|
+
"hdOMuITMabLF:kscSpsGGzBxu",
|
80
|
+
"vMpPCulIYkcT:GBbUdGlstxeW",
|
81
|
+
"FZmcNpLdbxha:CurAriesqPFZ",
|
82
|
+
"wVkKQBGmYJXK:XmZoKXLfvNvU",
|
83
|
+
"vgsqGbfVeawM:QhzXnffDjgAt",
|
84
|
+
"dJdUmaNsvuMC:HsHytSfNyvnS",
|
85
|
+
"UPmlEpbNFGYk:tZJMwBeDRAMs",
|
86
|
+
"xcxcPjUKRPal:iFCBrsSjHFRF",
|
87
|
+
"dldjzYhsQbLz:oaQaggnrVIjK",
|
88
|
+
"gZEekjgrBQCK:vUWhIaEHAclX",
|
89
|
+
"wLOToXHcLJBZ:RNIoYdwvDFTH",
|
90
|
+
"tBOjNYBHIJIo:CTqmQaCWaRRT",
|
91
|
+
"pbAGNZsvGnMC:TVWLsmdRRJjG",
|
92
|
+
"cneIEKBIGevh:CnFKUkBDJECj",
|
93
|
+
"WworruNrwycr:gYzkXQnHyPxy",
|
94
|
+
"YtbiVCtnYCIQ:jiBNmgTBWTBw",
|
95
|
+
"rwmUhrHCbWGW:gKdPdvUzbXEB",
|
96
|
+
"kdgqEBIsKMhO:rvESvQkNQtGs",
|
97
|
+
"PssVOTYjurWz:gSMXWHoFkvPq",
|
98
|
+
"kHlinSczQEim:rqFePFPryvUe",
|
99
|
+
"AIAVmolzTbQJ:mxvWoSJNrNRC",
|
100
|
+
"iBESkcpbrIdY:KQnQTqClDykQ",
|
101
|
+
"AXwyjTgvYIfn:vINTlbsjdtCx",
|
102
|
+
"yuHRAgIfVWTZ:VTTnyPBZSojM",
|
103
|
+
"nFrgKgQLzrRe:ooplsOvhQNFQ",
|
104
|
+
"iRFsCpCMUlte:koKrBewFLMxo",
|
105
|
+
"pOqWlFdPGYEl:gkhKikkcwpmh",
|
106
|
+
"NByvaUQkNchO:nPmVzbMPtXWY",
|
107
|
+
"RftfDbyWXmSe:wYLELjKLjkIJ",
|
108
|
+
"gLJMMYXGJibG:AnHNRvNmSkuA",
|
109
|
+
"zBCKrZlciUiV:SZJdvkMSkgRT",
|
110
|
+
"TyqcusJxatgm:EqKtdTEybJpz",
|
111
|
+
"fDDaoMvaOMOs:bmcEVoNcKyJC",
|
112
|
+
"dEgUOTTPOQpQ:elCgIExqkWOp",
|
113
|
+
"ZjZZftPIHKVj:gHzweZzDICAA",
|
114
|
+
"XuinqBhqynbE:PDfXbdSBkoJV",
|
115
|
+
"eYPkNTSSRngF:EShbqUEutCqQ",
|
116
|
+
"PvmFqqXdRnwG:IhDzJDSknest",
|
117
|
+
"CvbgGcNdKumE:gzmlCjYgybpZ",
|
118
|
+
"FiHNyzzpKmOs:tbIXrdCecmlB",
|
119
|
+
"dUsdcfxGJAlf:NTWKivTOeABd",
|
120
|
+
"BvVqSybVGuoD:xhCgeXTtsFST",
|
121
|
+
"GamYBkRElCCY:CFRHRROHlsrY",
|
122
|
+
"zeGrfdhyrtfY:AwSFrczizYsZ",
|
123
|
+
"bivTEnLISOyR:DQLoKikEWJON",
|
124
|
+
"FWMGCfVJcJjV:IJFxXGDqhDRK",
|
125
|
+
"yqDulLursWuk:CKieNAUmgcZM",
|
126
|
+
"TeXIZDsXBEJJ:gQSevIHOVxrd",
|
127
|
+
"iYgqvHkNlGjJ:WbSYJNhlJxbZ"
|
128
|
+
]
|
129
|
+
|
130
|
+
|
131
|
+
}
|
132
|
+
}
|
133
|
+
|
134
|
+
|
135
|
+
if ARGV[0] == 'config'
|
136
|
+
File.open('config.json', 'w+') do |f|
|
137
|
+
f.puts default_config
|
138
|
+
puts "[+] config.json made, you can now edit it"
|
139
|
+
exit
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
143
|
+
|
144
|
+
|
145
|
+
|
146
|
+
|
147
|
+
begin
|
148
|
+
$conf = JSON.parse(File.read("config.json"))
|
149
|
+
rescue Exception
|
150
|
+
puts "[-] Something went wrong loading your config.json file"
|
151
|
+
exit
|
152
|
+
end
|
153
|
+
|
154
|
+
#Make ctrl+c exit whole script
|
155
|
+
trap "INT" do
|
156
|
+
Thread.list.each do |thread|
|
157
|
+
thread.exit unless thread == Thread.current
|
158
|
+
end
|
159
|
+
exit
|
160
|
+
end
|
161
|
+
|
162
|
+
#get rid of annoying messages
|
163
|
+
ouput_manager = StringIO.new
|
164
|
+
$stdout = ouput_manager
|
165
|
+
$stderr = ouput_manager
|
166
|
+
|
167
|
+
module Kernel
|
168
|
+
def puts(msg)
|
169
|
+
#if msg[0] == "["
|
170
|
+
::STDOUT.printf(msg + "\n")
|
171
|
+
#end
|
172
|
+
end
|
173
|
+
end
|
174
|
+
|
175
|
+
|
176
|
+
module Pokeplot
|
177
|
+
include Database
|
178
|
+
|
179
|
+
Database.mongo_host = $conf["mongo"]["host"]
|
180
|
+
|
181
|
+
#Socket and notifications must come before miner to capture its database requests
|
182
|
+
if $conf["socket"]["enabled"]
|
183
|
+
s = Socket.new($conf["socket"]["host"], $conf["socket"]["port"], $conf["socket"]["log"])
|
184
|
+
Database.mongo_monitor(s)
|
185
|
+
end
|
186
|
+
|
187
|
+
if $conf["pushbullet"]["enabled"]
|
188
|
+
pb = Pushbullet.new($conf["pushbullet"]["api_key"], $conf["pushbullet"]["pokemon"])
|
189
|
+
Database.mongo_monitor(pb)
|
190
|
+
end
|
191
|
+
|
192
|
+
if $conf['combos'].is_a?(Array) && $conf['combos'].count > 0
|
193
|
+
$conf['combos'].each do |c|
|
194
|
+
c = c.split(':')
|
195
|
+
$conf['accounts'] << {'username' => c[0], 'password' => c[1], 'provider' => 'ptc'}
|
196
|
+
end
|
197
|
+
end
|
198
|
+
|
199
|
+
|
200
|
+
if $conf["miner"]["enabled"]
|
201
|
+
miner = Miner.new($conf['accounts'], $conf['location'][0], $conf['location'][1], $conf['miner']['range'], $conf['miner']['interval'], $conf['miner']['pokemon'], $conf['miner']['forts'], $conf['miner']['threaded'], $conf['api']['encryption_path'], $conf['miner']['log'], $conf['api']['log'])
|
202
|
+
miner.start
|
203
|
+
end
|
204
|
+
|
205
|
+
if $conf["webserver"]["enabled"]
|
206
|
+
web = Thread.new do
|
207
|
+
Web.config($conf["webserver"]["host"], $conf["webserver"]["port"])
|
208
|
+
Web.run!
|
209
|
+
end
|
210
|
+
end
|
211
|
+
|
212
|
+
# Join thread so it doesnt exit script
|
213
|
+
if miner.is_a?(Miner) && miner.miner.is_a?(Thread)
|
214
|
+
puts "[+] Joining thread"
|
215
|
+
miner.miner.join
|
216
|
+
end
|
217
|
+
|
218
|
+
if web && web.is_a?(Thread)
|
219
|
+
puts "[+] Joining thread"
|
220
|
+
web.join
|
221
|
+
end
|
222
|
+
|
223
|
+
end
|
data/lib/pokeplot/api.rb
ADDED
@@ -0,0 +1,109 @@
|
|
1
|
+
require 'poke-api'
|
2
|
+
require 'pokeplot/helpers/cell_ids'
|
3
|
+
|
4
|
+
module Pokeplot
|
5
|
+
class API
|
6
|
+
|
7
|
+
def initialize(lat, lng, encryption, logging = true)
|
8
|
+
Poke::API::Logging.log_level = :FATAL
|
9
|
+
@api = Poke::API::Client.new
|
10
|
+
set_location(lat, lng)
|
11
|
+
@encryption = encryption
|
12
|
+
@logging = logging
|
13
|
+
end
|
14
|
+
|
15
|
+
def login(username, password, provider)
|
16
|
+
puts "[+] Logging in #{username} with #{provider}" if @logging
|
17
|
+
loop do
|
18
|
+
begin
|
19
|
+
@username = username
|
20
|
+
@password = password
|
21
|
+
@provider = provider
|
22
|
+
@api.login(username, password, provider)
|
23
|
+
@api.activate_signature(@encryption)
|
24
|
+
basic_request
|
25
|
+
break
|
26
|
+
rescue Poke::API::Errors::UnknownProtoFault
|
27
|
+
|
28
|
+
puts "[-] Login for #{username} failed, retrying in 5 seconds" if @logging
|
29
|
+
sleep(5)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def map_heartbeat
|
35
|
+
|
36
|
+
loop do
|
37
|
+
@api.get_player
|
38
|
+
@api.get_hatched_eggs
|
39
|
+
@api.get_inventory(last_timestamp_ms: (Time.now.to_f * 1000).to_i)
|
40
|
+
@api.check_awarded_badges
|
41
|
+
@api.download_settings(hash: "05daf51635c82611d1aac95c0b051d3ec088a930")
|
42
|
+
|
43
|
+
cell_ids = Helpers::CellIds.get(@api.lat, @api.lng)
|
44
|
+
@api.get_map_objects(
|
45
|
+
latitude: lat,
|
46
|
+
longitude: lng,
|
47
|
+
since_timestamp_ms: [0] * cell_ids.count,
|
48
|
+
cell_id: cell_ids
|
49
|
+
)
|
50
|
+
|
51
|
+
begin
|
52
|
+
response = @api.call.response
|
53
|
+
rescue StandardError
|
54
|
+
puts "[-] Error.. Re-logging in" if @logging
|
55
|
+
login(@username, @password, @provider)
|
56
|
+
next
|
57
|
+
end
|
58
|
+
|
59
|
+
case response[:status_code]
|
60
|
+
when 1
|
61
|
+
return response
|
62
|
+
when 2
|
63
|
+
puts "[-] Error... Retrying..." if @logging
|
64
|
+
basic_request
|
65
|
+
when 102
|
66
|
+
puts "[-] Error, re-logging in" if @logging
|
67
|
+
login(@username, @password, @provider)
|
68
|
+
else
|
69
|
+
puts "[-] Heartbeat error: status code #{response[:status_code]}" if @logging
|
70
|
+
puts "[+] Retrying in 2 seconds..." if @logging
|
71
|
+
sleep(2)
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
def set_location(latitude, longitude)
|
77
|
+
@api.lat = latitude
|
78
|
+
@api.lng = longitude
|
79
|
+
end
|
80
|
+
|
81
|
+
def lat
|
82
|
+
return @api.lat
|
83
|
+
end
|
84
|
+
|
85
|
+
def lng
|
86
|
+
return @api.lng
|
87
|
+
end
|
88
|
+
|
89
|
+
def lat=(lat)
|
90
|
+
@api.lat = lat
|
91
|
+
end
|
92
|
+
|
93
|
+
def lng=(lng)
|
94
|
+
@api.lng = lng
|
95
|
+
end
|
96
|
+
|
97
|
+
|
98
|
+
private
|
99
|
+
|
100
|
+
def basic_request
|
101
|
+
@api.get_player
|
102
|
+
@api.get_hatched_eggs
|
103
|
+
@api.get_inventory
|
104
|
+
@api.check_awarded_badges
|
105
|
+
@api.call
|
106
|
+
end
|
107
|
+
|
108
|
+
end
|
109
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'mongo'
|
2
|
+
|
3
|
+
module Pokeplot
|
4
|
+
module Database
|
5
|
+
|
6
|
+
@@mongo_host = '127.0.0.1:27017'
|
7
|
+
|
8
|
+
def self.mongo
|
9
|
+
Mongo::Logger.level = Logger::FATAL
|
10
|
+
return Mongo::Client.new([ @@mongo_host ], :database => 'pokeplot')
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.mongo_host=(host)
|
14
|
+
@@mongo_host = host
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.mongo_monitor(class_instance)
|
18
|
+
Mongo::Monitoring::Global.subscribe(Mongo::Monitoring::COMMAND, class_instance)
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module Pokeplot
|
2
|
+
module Helpers
|
3
|
+
class Math
|
4
|
+
class << self
|
5
|
+
|
6
|
+
def deg_to_rad(deg)
|
7
|
+
return deg * (::Math::PI / 180)
|
8
|
+
end
|
9
|
+
|
10
|
+
def get_earth_radius(lat)
|
11
|
+
earth_radius_max = 6378137.0
|
12
|
+
earth_radius_min = 6356752.3
|
13
|
+
latrad = deg_to_rad(lat)
|
14
|
+
return (1.0/(((::Math.cos(latrad))/earth_radius_max)**(2) + ((::Math.sin(latrad))/earth_radius_min)**(2)))**(1.0/2)
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|