pokeplot 0.2.0beta

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,241 @@
1
+ require 'pokeplot/helpers/math'
2
+ require 'pokeplot/helpers/array'
3
+ require 'pokeplot/api'
4
+ module Pokeplot
5
+ class Miner
6
+
7
+ include Database
8
+
9
+ attr_accessor :miner, :db
10
+
11
+ def initialize(accounts, lat, lng, range = 20, interval = 600, pokemon = true, forts = true, threaded = false, encryption = '', log = true, apilog = true)
12
+ @apis = []
13
+ @accounts = accounts
14
+ @lat = lat
15
+ @lng = lng
16
+ @db = Database.mongo
17
+ @range = range
18
+ @interval = interval
19
+ @pokemon = pokemon
20
+ @forts = forts
21
+ @threaded = threaded
22
+ @encryption = encryption
23
+ @logging = log
24
+ @apilog = apilog
25
+ @miner = nil
26
+ @coords = []
27
+
28
+ get_all_coords
29
+ end
30
+
31
+ def start
32
+ if !@miner.is_a?(Thread)
33
+ @miner = Thread.new {
34
+ puts "[+] Starting miner on new thread" if @logging
35
+
36
+ puts "[+] #{@coords.count} coords to scan using #{@accounts.count} accounts" if @logging
37
+ puts "[+] Logging in all accounts" if @logging
38
+
39
+ if @threaded
40
+ @threads = []
41
+ @accounts.each_with_index do |account, index|
42
+ @threads << Thread.new do
43
+ api = API.new(@lat, @lng, @encryption, @apilog)
44
+ api.login(account['username'], account['password'], account['provider'])
45
+ sleep(1)
46
+
47
+ loop do
48
+ current_time = Time.now.to_i
49
+
50
+ groups = @coords.in_groups(@accounts.count)
51
+
52
+ groups[index].each do |coord|
53
+ api.set_location(coord[:lat], coord[:lng])
54
+ response = api.map_heartbeat
55
+ parse_map_objects(response)
56
+ sleep(10)
57
+ end
58
+ scan_time = Time.now.to_i - current_time
59
+ puts "[+] Scan finnished for account #{account['username']} in #{scan_time} seconds" if @logging
60
+ sleep_time = @interval - scan_time
61
+ sleep_time = [sleep_time, 0].max
62
+ puts "[+] Thread sleeping for #{sleep_time} seconds..." if @logging
63
+ sleep(sleep_time)
64
+ end
65
+
66
+ end
67
+ end
68
+
69
+ else #NOT THEADED
70
+
71
+ @accounts.each do |account|
72
+ api = API.new(@lat, @lng, @encryption, @apilog)
73
+ api.login(account['username'], account['password'], account['provider'])
74
+ @apis.push(api)
75
+ sleep(2)
76
+ end
77
+
78
+ loop do
79
+ current_time = Time.now.to_i
80
+
81
+ groups = @coords.in_groups(@apis.count)
82
+ diff = groups.first.count - groups.last.count
83
+ groups.last.push(*([0] * diff)) if diff > 0
84
+
85
+ groups = groups.transpose
86
+ groups.each_with_index do |group, n|
87
+ puts "[+] Starting group #{n + 1} of #{groups.count}" if @logging
88
+ group_time = Time.now.to_i
89
+ group.each_with_index do |coord, index|
90
+ if coord.is_a?(Hash)
91
+ api = @apis[index]
92
+ api.set_location(coord[:lat], coord[:lng])
93
+ response = api.map_heartbeat
94
+ parse_map_objects(response)
95
+ end
96
+ end
97
+ group_time = Time.now.to_i - group_time
98
+ puts "[+] Group finnished in #{group_time} seconds" if @logging
99
+ end
100
+
101
+ scan_time = Time.now.to_i - current_time
102
+ puts "[+] Scan Time: #{scan_time} s'" if @logging
103
+ sleep_time = @interval - scan_time
104
+ sleep_time = [sleep_time, 0].max
105
+ puts "[+] Sleeping for #{sleep_time} seconds..." if @logging
106
+ sleep(sleep_time)
107
+ end
108
+ end
109
+ }
110
+ end
111
+ end
112
+
113
+ def stop
114
+ Thread.kill(@miner) if @miner.is_a?(Thread)
115
+ if @threads.is_a?(Array)
116
+ @threads.each {|t| Thread.kill(t) if t.is_a?(Thread) }
117
+ end
118
+ @miner = nil
119
+ end
120
+
121
+ private
122
+
123
+ def get_all_coords
124
+ origin = {:lat => @lat, :lng => @lng}
125
+ @coords = [origin]
126
+
127
+ float_lat = @lat
128
+ float_lng = @lng
129
+
130
+ latrad = Helpers::Math.deg_to_rad(float_lat)
131
+
132
+ hex_r = 70.0 #range of detection for pokemon = 100m || changed to 70
133
+ hex_m = 3.0**(0.5)/2.0*hex_r
134
+
135
+ (1...(@range+1)).to_a.each do |a|
136
+ (0...(a*6)).to_a.each do |i|
137
+ x_un=1.5*hex_r/Helpers::Math.get_earth_radius(float_lat)/Math.cos(latrad)*180/Math::PI
138
+ y_un=1.0*hex_m/Helpers::Math.get_earth_radius(float_lat)*180/Math::PI
139
+ if i < a
140
+ lat = float_lat+y_un*(-2*a+i)
141
+ lng = float_lng+x_un*i
142
+ elsif i < 2*a
143
+ lat = float_lat+y_un*(-3*a+2*i)
144
+ lng = float_lng+x_un*a
145
+ elsif i < 3*a
146
+ lat = float_lat+y_un*(-a+i)
147
+ lng = float_lng+x_un*(3*a-i)
148
+ elsif i < 4*a
149
+ lat = float_lat+y_un*(5*a-i)
150
+ lng = float_lng+x_un*(3*a-i)
151
+ elsif i < 5*a
152
+ lat = float_lat+y_un*(9*a-2*i)
153
+ lng = float_lng+x_un*-a
154
+ else
155
+ lat = float_lat+y_un*(4*a-i)
156
+ lng = float_lng+x_un*(-6*a+i)
157
+ end
158
+ @coords << {:lat => lat, :lng => lng}
159
+ end
160
+ end
161
+ @coords
162
+ end
163
+
164
+ def parse_map_objects(response)
165
+ if response[:GET_MAP_OBJECTS][:status] == :SUCCESS
166
+ response[:GET_MAP_OBJECTS][:map_cells].each do |cell|
167
+
168
+ cell[:wild_pokemons].each do |pokemon|
169
+ if pokemon[:time_till_hidden_ms] < 0
170
+ puts "[+] Saving possible long spawn: #{pokemon[:spawn_point_id]}" if @logging
171
+ longspawn(cell, pokemon)
172
+ else
173
+ if new_encounter?(pokemon[:encounter_id].to_s, pokemon[:spawn_point_id], pokemon[:latitude].to_s, pokemon[:longitude].to_s) && @pokemon
174
+ @db[:encounters].insert_one({
175
+ cell_id: cell[:s2_cell_id].to_s,
176
+ current_timestamp_ms: cell[:current_timestamp_ms].to_s,
177
+ encounter_id: pokemon[:encounter_id].to_s,
178
+ latitude: pokemon[:latitude].to_s,
179
+ longitude: pokemon[:longitude].to_s,
180
+ spawn_point_id: pokemon[:spawn_point_id],
181
+ pokemon: pokemon[:pokemon_data][:pokemon_id].to_s,
182
+ time_till_hidden_ms: pokemon[:time_till_hidden_ms].to_s
183
+ })
184
+ puts "[+] Found a \e[36m#{pokemon[:pokemon_data][:pokemon_id]}\e[0m" if @logging
185
+ end
186
+ end
187
+ end
188
+
189
+ cell[:forts].each do |fort|
190
+ if new_fort?(fort[:id].to_s) && @forts
191
+ @db[:forts].insert_one({
192
+ cell_id: cell[:s2_cell_id].to_s,
193
+ current_timestamp_ms: cell[:current_timestamp_ms].to_s,
194
+ fort_id: fort[:id],
195
+ enabled: fort[:enabled].to_s,
196
+ latitude: fort[:latitude].to_s,
197
+ longitude: fort[:longitude].to_s,
198
+ type: fort[:type].to_s
199
+ })
200
+ puts "[+] Found a fort: #{fort[:type]}" if @logging
201
+ end
202
+ end
203
+
204
+ end
205
+ else
206
+ puts "[-] UNSUCCESSFUL RESPONSE STATUS #{response[:GET_MAP_OBJECTS][:status]}" if @logging
207
+ end
208
+ end
209
+
210
+ def new_encounter?(encounter_id, spawn_point_id, lat, lng)
211
+ if @db[:encounters].find({encounter_id: encounter_id, spawn_point_id: spawn_point_id, latitude: lat, longitude: lng}).count == 0
212
+ true
213
+ else
214
+ false
215
+ end
216
+ end
217
+
218
+ def new_fort?(fort_id)
219
+ if @db[:forts].find({fort_id: fort_id}).count == 0
220
+ true
221
+ else
222
+ false
223
+ end
224
+ end
225
+
226
+ def longspawn(cell, pokemon)
227
+ @db[:longspawn].insert_one({
228
+ cell_id: cell[:s2_cell_id].to_s,
229
+ current_timestamp_ms: cell[:current_timestamp_ms].to_s,
230
+ encounter_id: pokemon[:encounter_id].to_s,
231
+ latitude: pokemon[:latitude].to_s,
232
+ longitude: pokemon[:longitude].to_s,
233
+ spawn_point_id: pokemon[:spawn_point_id],
234
+ pokemon: pokemon[:pokemon_data][:pokemon_id].to_s,
235
+ time_till_hidden_ms: pokemon[:time_till_hidden_ms].to_s
236
+ })
237
+ puts "[+] Found a \e[36m#{pokemon[:pokemon_data][:pokemon_id]}\e[0m (Long spawn)" if @logging
238
+ end
239
+
240
+ end
241
+ end
@@ -0,0 +1,41 @@
1
+ require 'washbullet'
2
+ require 'pokeplot/helpers/time'
3
+
4
+ module Pokeplot
5
+ class Pushbullet
6
+
7
+ def initialize(api_key, pokemon = [])
8
+ @pokemon = pokemon
9
+ @client = Washbullet::Client.new(api_key)
10
+ end
11
+
12
+ def started(event)
13
+ if event.command.has_key?('insert')
14
+ if event.command.fetch('insert') == 'encounters'
15
+ if @pokemon.include?(event.command.fetch('documents')[0][:pokemon])
16
+ text = "Found a #{event.command.fetch('documents')[0][:pokemon]}! "
17
+ time = Helpers::Time.to_s(Time.now.to_i - ((event.command.fetch('documents')[0][:current_timestamp_ms].to_i / 1000) -(event.command.fetch('documents')[0][:time_till_hidden_ms].to_i / 1000)))
18
+ text += "It expires in #{time}. "
19
+ text += "Google maps: http://www.google.com/maps/place/#{event.command.fetch('documents')[0][:latitude]},#{event.command.fetch('documents')[0][:longitude]}"
20
+
21
+
22
+ @client.devices.each do |device|
23
+ @client.push_note(
24
+ receiver: :device,
25
+ identifier: device.body['iden'],
26
+ params: {
27
+ title: 'Pokeplot',
28
+ body: text
29
+ }
30
+ )
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
36
+
37
+ def failed(_); end
38
+ def succeeded(_); end
39
+
40
+ end
41
+ end
@@ -0,0 +1,65 @@
1
+ require 'em-websocket'
2
+ require 'json'
3
+
4
+ module Pokeplot
5
+ class Socket
6
+ include Database
7
+
8
+ def initialize(host = "0.0.0.0", port = 9090, log = false)
9
+ @clients = []
10
+ Thread.new do
11
+ EM.run do
12
+
13
+ db = Database.mongo
14
+ EM::WebSocket.run(:host => host, :port => port) do |ws|
15
+ ws.onopen do |handshake|
16
+ puts "[+] WebSocket connection open" if @log
17
+ pokemon = {:type => "count", :data => {}}
18
+ spawns = {:type => "spawn_points", :data => {}}
19
+
20
+ db[:encounters].find().each do |bson|
21
+ #get initial pokemon
22
+ if pokemon[:data].has_key?(bson[:pokemon])
23
+ pokemon[:data][bson[:pokemon]] += 1
24
+ else
25
+ pokemon[:data][bson[:pokemon]] = 1
26
+ end
27
+
28
+ #get spawn points
29
+ if spawns[:data].has_key?(bson[:spawn_point_id])
30
+ spawns[:data][bson[:spawn_point_id]] += 1
31
+ else
32
+ spawns[:data][bson[:spawn_point_id]] = 1
33
+ end
34
+ end
35
+
36
+ ws.send(pokemon.to_json)
37
+ ws.send(spawns.to_json)
38
+ @clients << ws
39
+ end
40
+
41
+ ws.onclose { @clients.delete(ws) }
42
+
43
+ end
44
+
45
+ end
46
+ end
47
+ end
48
+
49
+ #Mongo
50
+ def started(event)
51
+ if event.command.has_key?('insert')
52
+ if event.command.fetch('insert') == 'encounters'
53
+ @clients.each do |c|
54
+ c.send({:type => "pokemon", :data => event.command.fetch('documents')[0]}.to_json)
55
+ end
56
+ end
57
+ end
58
+ end
59
+
60
+ def failed(_); end
61
+ def succeeded(_); end
62
+
63
+
64
+ end
65
+ end
@@ -0,0 +1,3 @@
1
+ module Pokeplot
2
+ VERSION = "0.2.0beta"
3
+ end