bdoap 0.0.4 → 0.0.5
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.
- checksums.yaml +4 -4
- data/lib/bdo_alchemy_profits.rb +10 -52
- data/lib/bdo_codex/bdo_codex_searcher.rb +14 -21
- data/lib/central_market/market_searcher.rb +40 -80
- data/lib/utils/array_utils.rb +4 -0
- data/lib/utils/hash_cache.rb +2 -6
- data/lib/utils/npc_item_index.rb +9 -9
- data/lib/version.rb +1 -1
- metadata +3 -3
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: d3741f33638b6173720937040a4345070a3e34dbbbf5605946a331d80e221a11
|
|
4
|
+
data.tar.gz: a1c0f458b655495ba8a23b92c611346fac20850d7894704f48719ce16d4746e2
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 97061a30ef4e2b951d6ee26eabb51e28ba1170fa4208d0a3d1507ca3c29956fd0ac871e712df2bd06d4af480026203ae49b06109b1c335608631f6212dbad550
|
|
7
|
+
data.tar.gz: 00a37e50db4bb906d4a90c749e0614a37fc1f8216075c5dd5f6a6d8c8283ccffd5295b27380c0d159008ca978c4d2bce0348c3c2f7607342bdf7a82f5516db69
|
data/lib/bdo_alchemy_profits.rb
CHANGED
|
@@ -58,6 +58,13 @@ module BDOAP
|
|
|
58
58
|
|
|
59
59
|
return unless resolved
|
|
60
60
|
|
|
61
|
+
level_map_to_bdo = {
|
|
62
|
+
0 => 0, 1 => 1, 2 => 2, 3 => 3, 4 => 4, 5 => 5,
|
|
63
|
+
6 => 6, 7 => 7, 8 => 8, 9 => 9, 10 => 10, 11 => 11,
|
|
64
|
+
12 => 12, 13 => 13, 14 => 14, 15 => 15,
|
|
65
|
+
16 => 'PRI', 17 => 'DUO', 18 => 'TRI', 19 => 'TET', 20 => 'PEN',
|
|
66
|
+
}.freeze
|
|
67
|
+
|
|
61
68
|
resolved.each do |item|
|
|
62
69
|
subdata = HTTParty.post(
|
|
63
70
|
URI(sub_url),
|
|
@@ -69,55 +76,7 @@ module BDOAP
|
|
|
69
76
|
sleep rand
|
|
70
77
|
|
|
71
78
|
if subdata&.dig('detailList')
|
|
72
|
-
|
|
73
|
-
0 => 0,
|
|
74
|
-
1 => 1,
|
|
75
|
-
2 => 2,
|
|
76
|
-
3 => 3,
|
|
77
|
-
4 => 4,
|
|
78
|
-
5 => 5,
|
|
79
|
-
6 => 6,
|
|
80
|
-
7 => 7,
|
|
81
|
-
8 => 8,
|
|
82
|
-
9 => 9,
|
|
83
|
-
10 => 10,
|
|
84
|
-
11 => 11,
|
|
85
|
-
12 => 12,
|
|
86
|
-
13 => 13,
|
|
87
|
-
14 => 14,
|
|
88
|
-
15 => 15,
|
|
89
|
-
16 => 16,
|
|
90
|
-
17 => 17,
|
|
91
|
-
18 => 18,
|
|
92
|
-
19 => 19,
|
|
93
|
-
20 => 20,
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
level_map_to_bdo = {
|
|
97
|
-
0 => 0,
|
|
98
|
-
1 => 1,
|
|
99
|
-
2 => 2,
|
|
100
|
-
3 => 3,
|
|
101
|
-
4 => 4,
|
|
102
|
-
5 => 5,
|
|
103
|
-
6 => 6,
|
|
104
|
-
7 => 7,
|
|
105
|
-
8 => 8,
|
|
106
|
-
9 => 9,
|
|
107
|
-
10 => 10,
|
|
108
|
-
11 => 11,
|
|
109
|
-
12 => 12,
|
|
110
|
-
13 => 13,
|
|
111
|
-
14 => 14,
|
|
112
|
-
15 => 15,
|
|
113
|
-
16 => 'PRI',
|
|
114
|
-
17 => 'DUO',
|
|
115
|
-
18 => 'TRI',
|
|
116
|
-
19 => 'TET',
|
|
117
|
-
20 => 'PEN',
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
result = subdata['detailList'] .find { |e| e['subKey'].to_s == level_map[enhance_starting_level.to_i].to_s }
|
|
79
|
+
result = subdata['detailList'].find { |e| e['subKey'].to_s == enhance_starting_level.to_s }
|
|
121
80
|
if result
|
|
122
81
|
constructed = " #{result['count']} #{cli.yellow result['name'].downcase} @ #{level_map_to_bdo[result['subKey']]}"
|
|
123
82
|
items_at_level.push constructed unless result['count'].to_i == 0
|
|
@@ -184,11 +143,10 @@ module BDOAP
|
|
|
184
143
|
|
|
185
144
|
recipe_prices = market_searcher.get_all_recipe_prices item_codex_data, category
|
|
186
145
|
|
|
187
|
-
mapped_prices = recipe_prices.
|
|
146
|
+
mapped_prices = recipe_prices.sort_by { |recipe| recipe[:gain].to_i }.map { |recipe| recipe[:information] }
|
|
188
147
|
|
|
189
148
|
out_of_stock = recipe_prices.dig(0, :out_of_stock) || []
|
|
190
|
-
out_of_stock_list = ""
|
|
191
|
-
out_of_stock.each { |item| out_of_stock_list += "\n\t #{cli.yellow item}" }
|
|
149
|
+
out_of_stock_list = out_of_stock.map { |item| "\n\t #{cli.yellow item}" }.join
|
|
192
150
|
|
|
193
151
|
if mapped_prices.length > 0
|
|
194
152
|
cli.vipiko_overwrite "done!"
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
1
|
+
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
require 'json'
|
|
4
4
|
require 'httparty'
|
|
@@ -46,6 +46,14 @@ class BDOCodexSearcher
|
|
|
46
46
|
@hyper_aggressive = hyper_aggressive
|
|
47
47
|
end
|
|
48
48
|
|
|
49
|
+
def log_error(error, message = nil)
|
|
50
|
+
puts @cli.red(message) if message
|
|
51
|
+
File.open(ENVData::ERROR_LOG, 'a+') do |file|
|
|
52
|
+
file.write(error&.full_message || error.to_s)
|
|
53
|
+
file.write("\n\r")
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
|
|
49
57
|
def get_recipe_url(url, item_name)
|
|
50
58
|
begin
|
|
51
59
|
data = HTTParty.get(
|
|
@@ -66,9 +74,8 @@ class BDOCodexSearcher
|
|
|
66
74
|
all_recipe_substitutions = []
|
|
67
75
|
all_potion_recipes.each do |recipe|
|
|
68
76
|
original_recipe = recipe[RECIPE_INGREDIENTS_INDEX]
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
end
|
|
77
|
+
sub_id_index = recipe_with_substitute_ids.each_with_index.to_h { |id, i| [id, i] }
|
|
78
|
+
original_ingredient_indices = original_recipe.map { |item| sub_id_index[item[:id]] }
|
|
72
79
|
|
|
73
80
|
chunked_by_substitution_groups = []
|
|
74
81
|
|
|
@@ -197,13 +204,7 @@ class BDOCodexSearcher
|
|
|
197
204
|
parsed
|
|
198
205
|
end
|
|
199
206
|
rescue StandardError => error
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
File.open(ENVData::ERROR_LOG, 'a+') do |file|
|
|
203
|
-
file.write(error.full_message)
|
|
204
|
-
file.write("\n\r")
|
|
205
|
-
end
|
|
206
|
-
|
|
207
|
+
log_error error, "if you're not messing with the code, you should never see this. get_item_recipes broke."
|
|
207
208
|
[]
|
|
208
209
|
end
|
|
209
210
|
end
|
|
@@ -267,9 +268,7 @@ class BDOCodexSearcher
|
|
|
267
268
|
# newline because vipiko is about to start carriage returning
|
|
268
269
|
puts "\n"
|
|
269
270
|
item_list.each.with_index do |item_hash, index|
|
|
270
|
-
item = item_hash.transform_keys { |key|
|
|
271
|
-
key.gsub(/(.)([A-Z])/,'\1_\2').downcase.to_sym
|
|
272
|
-
}
|
|
271
|
+
item = item_hash.transform_keys { |key| Utils.snake_sym(key) }
|
|
273
272
|
|
|
274
273
|
next unless item[:main_key]
|
|
275
274
|
|
|
@@ -302,13 +301,7 @@ class BDOCodexSearcher
|
|
|
302
301
|
recipes.push recipe_hash
|
|
303
302
|
end
|
|
304
303
|
rescue StandardError => error
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
File.open(ENVData::ERROR_LOG, 'a+') do |file|
|
|
308
|
-
file.write(error.full_message)
|
|
309
|
-
file.write("\n\r")
|
|
310
|
-
end
|
|
311
|
-
|
|
304
|
+
log_error error, "if you're not messing with the code, you should never see this. get_item_codex_data broke."
|
|
312
305
|
next
|
|
313
306
|
end
|
|
314
307
|
end
|
|
@@ -30,17 +30,30 @@ class MarketSearcher
|
|
|
30
30
|
@out_of_stock_items = []
|
|
31
31
|
end
|
|
32
32
|
|
|
33
|
+
def market_post(url, body)
|
|
34
|
+
HTTParty.post(
|
|
35
|
+
URI(url),
|
|
36
|
+
headers: ENVData.get_central_market_headers(ENVData.get_incap_cookie(@region_subdomain)),
|
|
37
|
+
body: body,
|
|
38
|
+
content_type: 'application/x-www-form-urlencoded'
|
|
39
|
+
)
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
# DRY helper: log an error message to the CLI and append to the error log file
|
|
43
|
+
def log_error(error, message = nil)
|
|
44
|
+
puts @cli.red(message) if message
|
|
45
|
+
File.open(ENVData::ERROR_LOG, 'a+') do |file|
|
|
46
|
+
file.write(error&.full_message || error.to_s)
|
|
47
|
+
file.write("\n\r")
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
|
|
33
51
|
def get_alchemy_market_data(category)
|
|
34
52
|
construct_item_data(category, category == 'all')
|
|
35
53
|
end
|
|
36
54
|
|
|
37
55
|
def get_price_data(elem)
|
|
38
|
-
data =
|
|
39
|
-
URI(@market_sub_url),
|
|
40
|
-
headers: ENVData.get_central_market_headers(ENVData.get_incap_cookie(@region_subdomain)),
|
|
41
|
-
body: "#{ENVData::RVT}&mainKey=#{elem['mainKey']}&usingCleint=0",
|
|
42
|
-
content_type: 'application/x-www-form-urlencoded'
|
|
43
|
-
)
|
|
56
|
+
data = market_post(@market_sub_url, "#{ENVData::RVT}&mainKey=#{elem['mainKey']}&usingCleint=0")
|
|
44
57
|
|
|
45
58
|
sleep 1
|
|
46
59
|
|
|
@@ -58,9 +71,7 @@ class MarketSearcher
|
|
|
58
71
|
def construct_item_data(subcategory, all_subcategories)
|
|
59
72
|
aggregate = aggregate_category_data(@market_list_url, @market_search_url, subcategory, all_subcategories)
|
|
60
73
|
|
|
61
|
-
filtered_aggregate = aggregate.
|
|
62
|
-
elem != nil
|
|
63
|
-
end
|
|
74
|
+
filtered_aggregate = aggregate.compact
|
|
64
75
|
|
|
65
76
|
# TODO: this is probably not a smart way to do this type of retry logic
|
|
66
77
|
puts
|
|
@@ -78,13 +89,7 @@ class MarketSearcher
|
|
|
78
89
|
begin
|
|
79
90
|
get_price_data elem
|
|
80
91
|
rescue StandardError => error
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
File.open(ENVData::ERROR_LOG, 'a+') do |file|
|
|
84
|
-
file.write(error.full_message)
|
|
85
|
-
file.write("\n\r")
|
|
86
|
-
end
|
|
87
|
-
|
|
92
|
+
log_error error, "this could be a network failure. construct_item_data broke."
|
|
88
93
|
[]
|
|
89
94
|
end
|
|
90
95
|
end
|
|
@@ -92,9 +97,7 @@ class MarketSearcher
|
|
|
92
97
|
|
|
93
98
|
puts "\n\n" unless mapped_aggregate.empty?
|
|
94
99
|
|
|
95
|
-
mapped_aggregate.
|
|
96
|
-
b['pricePerOne'] - a['pricePerOne']
|
|
97
|
-
end
|
|
100
|
+
mapped_aggregate.sort_by { |a| -a['pricePerOne'] }
|
|
98
101
|
end
|
|
99
102
|
|
|
100
103
|
def aggregate_category_data(url, search_url, subcategory, all_subcategories)
|
|
@@ -111,24 +114,13 @@ class MarketSearcher
|
|
|
111
114
|
category_search_options(url, search_url).each do |category_opts|
|
|
112
115
|
do_if_category_matches(make_match_options.call(category_opts[:name])) do
|
|
113
116
|
begin
|
|
114
|
-
data =
|
|
115
|
-
URI(category_opts[:url]),
|
|
116
|
-
headers: ENVData.get_central_market_headers(ENVData.get_incap_cookie(@region_subdomain)),
|
|
117
|
-
body: category_opts[:query_string],
|
|
118
|
-
content_type: 'application/x-www-form-urlencoded'
|
|
119
|
-
)
|
|
117
|
+
data = market_post(category_opts[:url], category_opts[:query_string])
|
|
120
118
|
|
|
121
119
|
sleep 1
|
|
122
120
|
|
|
123
121
|
aggregate_response.push category_opts[:update].call(data) if data
|
|
124
122
|
rescue StandardError => error
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
File.open(ENVData::ERROR_LOG, 'a+') do |file|
|
|
128
|
-
file.write(error.full_message)
|
|
129
|
-
file.write("\n\r")
|
|
130
|
-
end
|
|
131
|
-
|
|
123
|
+
log_error error, "this could be a network failure. aggregate_category_data broke."
|
|
132
124
|
[]
|
|
133
125
|
end
|
|
134
126
|
end
|
|
@@ -147,22 +139,12 @@ class MarketSearcher
|
|
|
147
139
|
ingredient_data = {}
|
|
148
140
|
|
|
149
141
|
begin
|
|
150
|
-
ingredient_data =
|
|
151
|
-
URI(@market_sub_url),
|
|
152
|
-
headers: ENVData.get_central_market_headers(ENVData.get_incap_cookie(@region_subdomain)),
|
|
153
|
-
body: "#{ENVData::RVT}&mainKey=#{ingredient_id}&usingCleint=0",
|
|
154
|
-
content_type: 'application/x-www-form-urlencoded'
|
|
155
|
-
)
|
|
142
|
+
ingredient_data = market_post(@market_sub_url, "#{ENVData::RVT}&mainKey=#{ingredient_id}&usingCleint=0")
|
|
156
143
|
|
|
157
144
|
sleep rand
|
|
158
145
|
rescue StandardError => error
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
File.open(ENVData::ERROR_LOG, 'a+') do |file|
|
|
162
|
-
file.write(error.full_message)
|
|
163
|
-
file.write("\n\r")
|
|
146
|
+
log_error error, "this could be a network failure. get_item_price_info broke."
|
|
164
147
|
ingredient_data = {}
|
|
165
|
-
end
|
|
166
148
|
end
|
|
167
149
|
|
|
168
150
|
# TODO: actually implement a normal way of handling malformed results
|
|
@@ -178,31 +160,19 @@ class MarketSearcher
|
|
|
178
160
|
detailed_price_list = {}
|
|
179
161
|
|
|
180
162
|
begin
|
|
181
|
-
detailed_price_list =
|
|
182
|
-
URI(@market_sell_buy_url),
|
|
183
|
-
headers: ENVData.get_central_market_headers(ENVData.get_incap_cookie(@region_subdomain)),
|
|
184
|
-
body: body_string,
|
|
185
|
-
content_type: 'application/x-www-form-urlencoded'
|
|
186
|
-
)
|
|
163
|
+
detailed_price_list = market_post(@market_sell_buy_url, body_string)
|
|
187
164
|
|
|
188
165
|
detailed_price_list = {} if detailed_price_list.to_s.downcase.include? 'incapsula incident'
|
|
189
166
|
|
|
190
167
|
sleep rand
|
|
191
168
|
rescue StandardError => error
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
File.open(ENVData::ERROR_LOG, 'a+') do |file|
|
|
195
|
-
file.write(error&.full_message || error)
|
|
196
|
-
file.write("\n\r")
|
|
197
|
-
detailed_price_list = {}
|
|
198
|
-
end
|
|
169
|
+
log_error error, "this could be a network failure. get_item_price_info broke."
|
|
170
|
+
detailed_price_list = {}
|
|
199
171
|
end
|
|
200
172
|
|
|
201
|
-
optimal_prices = detailed_price_list&.dig('marketConditionList')&.
|
|
202
|
-
b['sellCount'] - a['sellCount']
|
|
203
|
-
end
|
|
173
|
+
optimal_prices = detailed_price_list&.dig('marketConditionList')&.sort_by { |p| -p['sellCount'] }
|
|
204
174
|
|
|
205
|
-
total_stock = optimal_prices.to_a.
|
|
175
|
+
total_stock = optimal_prices.to_a.sum { |price| price["sellCount"] }
|
|
206
176
|
|
|
207
177
|
optimal_price = optimal_prices.to_a.first
|
|
208
178
|
|
|
@@ -235,12 +205,10 @@ class MarketSearcher
|
|
|
235
205
|
potential_recipe = []
|
|
236
206
|
|
|
237
207
|
recipe.each.with_index do |ingredient, ing_index|
|
|
238
|
-
ingredient_id = ingredient['id']
|
|
239
|
-
quant
|
|
240
|
-
enhance_level = ingredient['enhance_level']
|
|
241
|
-
is_m_recipe
|
|
242
|
-
quant = 1 if quant.nil?
|
|
243
|
-
enhance_level = 0 if enhance_level.nil?
|
|
208
|
+
ingredient_id = ingredient['id'] || ingredient[:id]
|
|
209
|
+
quant = ingredient['quant'] || ingredient[:quant] || 1
|
|
210
|
+
enhance_level = ingredient['enhance_level']|| ingredient[:enhance_level] || 0
|
|
211
|
+
is_m_recipe = ingredient['is_m_recipe'] || ingredient[:is_m_recipe]
|
|
244
212
|
|
|
245
213
|
if @ingredient_cache[ingredient_id] && EXCHANGE_ITEMS[ingredient_id].nil? == true
|
|
246
214
|
cached_ingredient = { **@ingredient_cache[ingredient_id], quant: quant, for_recipe_id: recipe_id, is_m_recipe: is_m_recipe }
|
|
@@ -259,9 +227,7 @@ class MarketSearcher
|
|
|
259
227
|
item_price_info_hash = exchange_info
|
|
260
228
|
end
|
|
261
229
|
|
|
262
|
-
item_price_info = item_price_info_hash.transform_keys { |key|
|
|
263
|
-
key.to_s.gsub(/(.)([A-Z])/,'\1_\2').downcase.to_sym
|
|
264
|
-
}
|
|
230
|
+
item_price_info = item_price_info_hash.transform_keys { |key| Utils.snake_sym(key) }
|
|
265
231
|
|
|
266
232
|
# gathering out of stock items to show to the user
|
|
267
233
|
stock_string = "#{quant}x [#{item_price_info[:main_key]}] #{item_price_info[:name].downcase}"
|
|
@@ -314,7 +280,7 @@ class MarketSearcher
|
|
|
314
280
|
mapped_recipe_prices.push map_recipe_prices(potential_recipes, item_with_recipe, subcategory)
|
|
315
281
|
end
|
|
316
282
|
|
|
317
|
-
mapped_recipe_prices.
|
|
283
|
+
mapped_recipe_prices.compact
|
|
318
284
|
end
|
|
319
285
|
|
|
320
286
|
def map_recipe_prices(potential_recipes, item, category)
|
|
@@ -370,7 +336,7 @@ class MarketSearcher
|
|
|
370
336
|
# are some seriously mysterious alchemy recipes out there...
|
|
371
337
|
ingredients_already_appeared = []
|
|
372
338
|
filtered_selected_recipe = selected_recipe.filter do |ingredient|
|
|
373
|
-
|
|
339
|
+
next false if ingredients_already_appeared.include? ingredient[:name]
|
|
374
340
|
ingredients_already_appeared.push(ingredient[:name])
|
|
375
341
|
true
|
|
376
342
|
end
|
|
@@ -383,12 +349,7 @@ class MarketSearcher
|
|
|
383
349
|
|
|
384
350
|
body_string = "#{ENVData::RVT}&mainKey=#{item[:id]}&subKey=0&chooseKey=0&isUp=true&keyType=0&name=#{URI.encode_www_form_component(item[:name])}"
|
|
385
351
|
|
|
386
|
-
item_price_data =
|
|
387
|
-
URI(@market_sell_buy_url),
|
|
388
|
-
headers: ENVData.get_central_market_headers(ENVData.get_incap_cookie(@region_subdomain)),
|
|
389
|
-
body: body_string,
|
|
390
|
-
content_type: 'application/x-www-form-urlencoded'
|
|
391
|
-
)
|
|
352
|
+
item_price_data = market_post(@market_sell_buy_url, body_string)
|
|
392
353
|
|
|
393
354
|
item_price_data = {} if item_price_data.to_s.downcase.include? 'incapsula incident'
|
|
394
355
|
|
|
@@ -449,7 +410,6 @@ class MarketSearcher
|
|
|
449
410
|
end
|
|
450
411
|
|
|
451
412
|
def do_if_category_matches(options, &procedure)
|
|
452
|
-
procedure.call if options[:all_subcategories]
|
|
453
|
-
procedure.call if options[:subcategory] == options[:subcat_to_match]
|
|
413
|
+
procedure.call if options[:all_subcategories] || (options[:subcategory] == options[:subcat_to_match])
|
|
454
414
|
end
|
|
455
415
|
end
|
data/lib/utils/array_utils.rb
CHANGED
data/lib/utils/hash_cache.rb
CHANGED
|
@@ -23,12 +23,8 @@ module Utils
|
|
|
23
23
|
end
|
|
24
24
|
|
|
25
25
|
def write(data)
|
|
26
|
-
|
|
27
|
-
File.
|
|
28
|
-
new_data = { **item_map, **data }
|
|
29
|
-
|
|
30
|
-
file.write new_data.to_json
|
|
31
|
-
end
|
|
26
|
+
@all_content.merge!(data)
|
|
27
|
+
File.write(@cache_file, @all_content.to_json)
|
|
32
28
|
end
|
|
33
29
|
end
|
|
34
30
|
end
|
data/lib/utils/npc_item_index.rb
CHANGED
|
@@ -75,7 +75,7 @@ module Utils
|
|
|
75
75
|
},
|
|
76
76
|
7304 => {
|
|
77
77
|
name: 'Strawberry',
|
|
78
|
-
id:
|
|
78
|
+
id: 7304,
|
|
79
79
|
price: 700,
|
|
80
80
|
price_per_one: 700,
|
|
81
81
|
count: Float::INFINITY,
|
|
@@ -472,7 +472,7 @@ module Utils
|
|
|
472
472
|
is_npc_item: true,
|
|
473
473
|
npc_type: 'general goods',
|
|
474
474
|
main_category: 25,
|
|
475
|
-
|
|
475
|
+
sub_category: 8,
|
|
476
476
|
},
|
|
477
477
|
517 => {
|
|
478
478
|
name: 'HP Potion (Small)',
|
|
@@ -483,29 +483,29 @@ module Utils
|
|
|
483
483
|
is_npc_item: true,
|
|
484
484
|
npc_type: 'general goods',
|
|
485
485
|
main_category: 35,
|
|
486
|
-
|
|
486
|
+
sub_category: 5,
|
|
487
487
|
},
|
|
488
488
|
521 => {
|
|
489
489
|
name: 'HP Potion (Medium)',
|
|
490
|
-
id:
|
|
490
|
+
id: 521,
|
|
491
491
|
price: 200,
|
|
492
492
|
price_per_one: 200,
|
|
493
493
|
count: Float::INFINITY,
|
|
494
494
|
is_npc_item: true,
|
|
495
495
|
npc_type: 'general goods',
|
|
496
496
|
main_category: 35,
|
|
497
|
-
|
|
497
|
+
sub_category: 5,
|
|
498
498
|
},
|
|
499
499
|
519 => {
|
|
500
500
|
name: 'HP Potion (Large)',
|
|
501
|
-
id:
|
|
501
|
+
id: 519,
|
|
502
502
|
price: 500,
|
|
503
503
|
price_per_one: 500,
|
|
504
504
|
count: Float::INFINITY,
|
|
505
505
|
is_npc_item: true,
|
|
506
506
|
npc_type: 'general goods',
|
|
507
507
|
main_category: 35,
|
|
508
|
-
|
|
508
|
+
sub_category: 5,
|
|
509
509
|
},
|
|
510
510
|
524 => {
|
|
511
511
|
name: 'HP Potion (Extra Large)',
|
|
@@ -516,7 +516,7 @@ module Utils
|
|
|
516
516
|
is_npc_item: true,
|
|
517
517
|
npc_type: 'general goods',
|
|
518
518
|
main_category: 35,
|
|
519
|
-
|
|
519
|
+
sub_category: 5,
|
|
520
520
|
},
|
|
521
521
|
520 => {
|
|
522
522
|
name: 'MP Potion (Small)',
|
|
@@ -527,7 +527,7 @@ module Utils
|
|
|
527
527
|
is_npc_item: true,
|
|
528
528
|
npc_type: 'general goods',
|
|
529
529
|
main_category: 35,
|
|
530
|
-
|
|
530
|
+
sub_category: 5,
|
|
531
531
|
},
|
|
532
532
|
522 => {
|
|
533
533
|
name: 'MP Potion (Large)',
|
data/lib/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: bdoap
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.0.
|
|
4
|
+
version: 0.0.5
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- jpegzilla
|
|
8
8
|
bindir: bin
|
|
9
9
|
cert_chain: []
|
|
10
|
-
date:
|
|
10
|
+
date: 2026-09-27 00:00:00.000000000 Z
|
|
11
11
|
dependencies: []
|
|
12
12
|
description: this script allows you to find alchemy recipes from bdocodex.com, compare
|
|
13
13
|
them with live central market prices, and use that information to determine what
|
|
@@ -50,7 +50,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
50
50
|
- !ruby/object:Gem::Version
|
|
51
51
|
version: '0'
|
|
52
52
|
requirements: []
|
|
53
|
-
rubygems_version: 3.6.
|
|
53
|
+
rubygems_version: 3.6.9
|
|
54
54
|
specification_version: 4
|
|
55
55
|
summary: this is a tool used to aggregate price and profit data for black desert alchemists.
|
|
56
56
|
test_files: []
|