bdoap 0.0.3 → 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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 2fabb7eadd3b5446aa42832f5ce1164777c8ed9669c1679a16d61138e9be9de7
4
- data.tar.gz: 20232aec55bb79082273f1dcdadcc04347d83948b9f3cd2977143672a247d19e
3
+ metadata.gz: d3741f33638b6173720937040a4345070a3e34dbbbf5605946a331d80e221a11
4
+ data.tar.gz: a1c0f458b655495ba8a23b92c611346fac20850d7894704f48719ce16d4746e2
5
5
  SHA512:
6
- metadata.gz: d7ce743bbc6e663ae0967e4a4a1117611ed87d83c3a6b793a76b5c635aafc8270652e4fc489644f87bb70cc0d5b5a73865314c56a6d0a4150a42baa08e2ccdfd
7
- data.tar.gz: 1af804e8da23ec52a1551e1e0db2da5fc2b975a7da9ada2ef1ef0b51ed2df46f4fbf4251226aa0002e4e25c1d198e2ac8e78d873332c7238eb6fb072b567e979
6
+ metadata.gz: 97061a30ef4e2b951d6ee26eabb51e28ba1170fa4208d0a3d1507ca3c29956fd0ac871e712df2bd06d4af480026203ae49b06109b1c335608631f6212dbad550
7
+ data.tar.gz: 00a37e50db4bb906d4a90c749e0614a37fc1f8216075c5dd5f6a6d8c8283ccffd5295b27380c0d159008ca978c4d2bce0348c3c2f7607342bdf7a82f5516db69
@@ -24,6 +24,7 @@
24
24
  # SOFTWARE.
25
25
 
26
26
  require 'optparse'
27
+ require 'httparty'
27
28
 
28
29
  require_relative './utils/user_cli'
29
30
  require_relative './central_market/market_searcher'
@@ -35,8 +36,61 @@ module BDOAP
35
36
  class BDOAlchemyProfits
36
37
  include Utils
37
38
 
39
+ def start_enhance(search_string, enhance_starting_level, region, cli)
40
+ items_at_level = []
41
+ root_url = ENVData.get_root_url region
42
+ search_url = "#{root_url}#{ENVData::MARKET_SEARCH_LIST}"
43
+ sub_url = "#{root_url}#{ENVData::MARKET_SUB_LIST}"
44
+ category_opts = {
45
+ url: search_url,
46
+ query_string: "#{ENVData::RVT}&searchText=#{URI.encode_www_form_component search_string}",
47
+ update: ->(data) { data['list'] }
48
+ }
49
+
50
+ data = HTTParty.post(
51
+ URI(category_opts[:url].to_s),
52
+ headers: ENVData.get_central_market_headers(ENVData.get_incap_cookie(@region_subdomain)),
53
+ body: category_opts[:query_string],
54
+ content_type: 'application/x-www-form-urlencoded'
55
+ )
56
+
57
+ resolved = category_opts[:update].call(data) if data
58
+
59
+ return unless resolved
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
+
68
+ resolved.each do |item|
69
+ subdata = HTTParty.post(
70
+ URI(sub_url),
71
+ headers: ENVData.get_central_market_headers(ENVData.get_incap_cookie(@region_subdomain)),
72
+ body: "#{ENVData::RVT}&mainKey=#{item['mainKey']}&usingCleint=0",
73
+ content_type: 'application/x-www-form-urlencoded'
74
+ )
75
+
76
+ sleep rand
77
+
78
+ if subdata&.dig('detailList')
79
+ result = subdata['detailList'].find { |e| e['subKey'].to_s == enhance_starting_level.to_s }
80
+ if result
81
+ constructed = " #{result['count']} #{cli.yellow result['name'].downcase} @ #{level_map_to_bdo[result['subKey']]}"
82
+ items_at_level.push constructed unless result['count'].to_i == 0
83
+ end
84
+ end
85
+ end
86
+
87
+ puts "\nthe results are in!\n"
88
+ items_at_level.each { |item| puts item }
89
+ puts
90
+ end
91
+
38
92
  # begin the configuration and search process
39
- def start_cli
93
+ def start_cli(search_string = nil, enhance_starting_level = nil, enhancing = false)
40
94
  begin
41
95
  options = {}
42
96
 
@@ -47,10 +101,20 @@ module BDOAP
47
101
  # option setup
48
102
  cli = UserCLI.new options
49
103
 
50
- category = cli.choose_category
51
- cli.end_cli if category == 'exit'
104
+ unless enhancing
105
+ category = cli.choose_category
106
+ cli.end_cli if category == 'exit'
107
+ end
108
+
52
109
  region = cli.choose_region
53
110
  cli.end_cli if region == 'exit'
111
+
112
+ # start enhancing
113
+ if enhancing && search_string && enhance_starting_level
114
+ start_enhance(search_string, enhance_starting_level, region, cli)
115
+ return
116
+ end
117
+
54
118
  lang = cli.choose_lang
55
119
  cli.end_cli if lang == 'exit'
56
120
  aggression = cli.choose_aggression
@@ -79,11 +143,10 @@ module BDOAP
79
143
 
80
144
  recipe_prices = market_searcher.get_all_recipe_prices item_codex_data, category
81
145
 
82
- mapped_prices = recipe_prices.reverse.sort_by { |recipe| recipe[:gain].to_i }.map { |recipe| recipe[:information] }
146
+ mapped_prices = recipe_prices.sort_by { |recipe| recipe[:gain].to_i }.map { |recipe| recipe[:information] }
83
147
 
84
148
  out_of_stock = recipe_prices.dig(0, :out_of_stock) || []
85
- out_of_stock_list = ""
86
- 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
87
150
 
88
151
  if mapped_prices.length > 0
89
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
- original_ingredient_indices = original_recipe.map do |item|
70
- recipe_with_substitute_ids.find_index { |id| id == item[:id] }
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
- puts @cli.red("if you're not messing with the code, you should never see this. get_item_recipes broke.")
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
- puts @cli.red("if you're not messing with the code, you should never see this. get_item_codex_data broke.")
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
@@ -10,6 +10,7 @@ module MarketSearchTools
10
10
  offensive: 1,
11
11
  defensive: 2,
12
12
  functional: 3,
13
+ food: 4,
13
14
  potion: 5,
14
15
  other: 8,
15
16
  all: [1, 2, 3, 5, 8]
@@ -87,6 +88,13 @@ module MarketSearchTools
87
88
  "#{ENVData::RVT}&mainCategory=#{CONSUMABLE_CATEGORY}&subCategory=#{CONSUMABLE_SUBCATEGORIES[:offensive]}",
88
89
  update: ->(data) { data['marketList'] }
89
90
  },
91
+ {
92
+ name: 'food',
93
+ url: url,
94
+ query_string:
95
+ "#{ENVData::RVT}&mainCategory=#{CONSUMABLE_CATEGORY}&subCategory=#{CONSUMABLE_SUBCATEGORIES[:food]}",
96
+ update: ->(data) { data['marketList'] }
97
+ },
90
98
  {
91
99
  name: 'defensive',
92
100
  url: url,
@@ -132,7 +140,14 @@ module MarketSearchTools
132
140
  query_string: "#{ENVData::RVT}&searchText=purified+lightstone+of",
133
141
  # update: ->(data) { { otherResponse: data['marketList'] } },
134
142
  update: ->(data) { data['list'] }
135
- }
143
+ },
144
+ # {
145
+ # name: 'stuffed animals',
146
+ # url: search_url,
147
+ # query_string: "#{ENVData::RVT}&searchText=stuffed",
148
+ # # update: ->(data) { { otherResponse: data['marketList'] } },
149
+ # update: ->(data) { data['list'] }
150
+ # }
136
151
  ]
137
152
  end
138
153
  end
@@ -24,22 +24,36 @@ class MarketSearcher
24
24
  @market_sub_url = "#{@root_url}#{ENVData::MARKET_SUB_LIST}"
25
25
  @market_sell_buy_url = "#{@root_url}#{ENVData::MARKET_SELL_BUY_INFO}"
26
26
  @cli = cli
27
+ # cache used to store all ingredients for which the price has already been checked
27
28
  @ingredient_cache = {}
28
29
  @free_ingredients = free_ingredients
29
30
  @out_of_stock_items = []
30
31
  end
31
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
+
32
51
  def get_alchemy_market_data(category)
33
52
  construct_item_data(category, category == 'all')
34
53
  end
35
54
 
36
55
  def get_price_data(elem)
37
- data = HTTParty.post(
38
- URI(@market_sub_url),
39
- headers: ENVData.get_central_market_headers(ENVData.get_incap_cookie(@region_subdomain)),
40
- body: "#{ENVData::RVT}&mainKey=#{elem['mainKey']}&usingCleint=0",
41
- content_type: 'application/x-www-form-urlencoded'
42
- )
56
+ data = market_post(@market_sub_url, "#{ENVData::RVT}&mainKey=#{elem['mainKey']}&usingCleint=0")
43
57
 
44
58
  sleep 1
45
59
 
@@ -57,9 +71,7 @@ class MarketSearcher
57
71
  def construct_item_data(subcategory, all_subcategories)
58
72
  aggregate = aggregate_category_data(@market_list_url, @market_search_url, subcategory, all_subcategories)
59
73
 
60
- filtered_aggregate = aggregate.filter do |elem|
61
- elem != nil
62
- end
74
+ filtered_aggregate = aggregate.compact
63
75
 
64
76
  # TODO: this is probably not a smart way to do this type of retry logic
65
77
  puts
@@ -77,13 +89,7 @@ class MarketSearcher
77
89
  begin
78
90
  get_price_data elem
79
91
  rescue StandardError => error
80
- puts @cli.red("this could be a network failure. construct_item_data broke.")
81
-
82
- File.open(ENVData::ERROR_LOG, 'a+') do |file|
83
- file.write(error.full_message)
84
- file.write("\n\r")
85
- end
86
-
92
+ log_error error, "this could be a network failure. construct_item_data broke."
87
93
  []
88
94
  end
89
95
  end
@@ -91,9 +97,7 @@ class MarketSearcher
91
97
 
92
98
  puts "\n\n" unless mapped_aggregate.empty?
93
99
 
94
- mapped_aggregate.sort do |a, b|
95
- b['pricePerOne'] - a['pricePerOne']
96
- end
100
+ mapped_aggregate.sort_by { |a| -a['pricePerOne'] }
97
101
  end
98
102
 
99
103
  def aggregate_category_data(url, search_url, subcategory, all_subcategories)
@@ -110,24 +114,13 @@ class MarketSearcher
110
114
  category_search_options(url, search_url).each do |category_opts|
111
115
  do_if_category_matches(make_match_options.call(category_opts[:name])) do
112
116
  begin
113
- data = HTTParty.post(
114
- URI(category_opts[:url]),
115
- headers: ENVData.get_central_market_headers(ENVData.get_incap_cookie(@region_subdomain)),
116
- body: category_opts[:query_string],
117
- content_type: 'application/x-www-form-urlencoded'
118
- )
117
+ data = market_post(category_opts[:url], category_opts[:query_string])
119
118
 
120
119
  sleep 1
121
120
 
122
121
  aggregate_response.push category_opts[:update].call(data) if data
123
122
  rescue StandardError => error
124
- puts @cli.red("this could be a network failure. aggregate_category_data broke.")
125
-
126
- File.open(ENVData::ERROR_LOG, 'a+') do |file|
127
- file.write(error.full_message)
128
- file.write("\n\r")
129
- end
130
-
123
+ log_error error, "this could be a network failure. aggregate_category_data broke."
131
124
  []
132
125
  end
133
126
  end
@@ -146,22 +139,12 @@ class MarketSearcher
146
139
  ingredient_data = {}
147
140
 
148
141
  begin
149
- ingredient_data = HTTParty.post(
150
- URI(@market_sub_url),
151
- headers: ENVData.get_central_market_headers(ENVData.get_incap_cookie(@region_subdomain)),
152
- body: "#{ENVData::RVT}&mainKey=#{ingredient_id}&usingCleint=0",
153
- content_type: 'application/x-www-form-urlencoded'
154
- )
142
+ ingredient_data = market_post(@market_sub_url, "#{ENVData::RVT}&mainKey=#{ingredient_id}&usingCleint=0")
155
143
 
156
144
  sleep rand
157
145
  rescue StandardError => error
158
- puts @cli.red("this could be a network failure. get_item_price_info broke.")
159
-
160
- File.open(ENVData::ERROR_LOG, 'a+') do |file|
161
- file.write(error.full_message)
162
- file.write("\n\r")
146
+ log_error error, "this could be a network failure. get_item_price_info broke."
163
147
  ingredient_data = {}
164
- end
165
148
  end
166
149
 
167
150
  # TODO: actually implement a normal way of handling malformed results
@@ -177,31 +160,19 @@ class MarketSearcher
177
160
  detailed_price_list = {}
178
161
 
179
162
  begin
180
- detailed_price_list = HTTParty.post(
181
- URI(@market_sell_buy_url),
182
- headers: ENVData.get_central_market_headers(ENVData.get_incap_cookie(@region_subdomain)),
183
- body: body_string,
184
- content_type: 'application/x-www-form-urlencoded'
185
- )
163
+ detailed_price_list = market_post(@market_sell_buy_url, body_string)
186
164
 
187
165
  detailed_price_list = {} if detailed_price_list.to_s.downcase.include? 'incapsula incident'
188
166
 
189
167
  sleep rand
190
168
  rescue StandardError => error
191
- puts @cli.red("this could be a network failure. get_item_price_info broke.")
192
-
193
- File.open(ENVData::ERROR_LOG, 'a+') do |file|
194
- file.write(error&.full_message || error)
195
- file.write("\n\r")
196
- detailed_price_list = {}
197
- end
169
+ log_error error, "this could be a network failure. get_item_price_info broke."
170
+ detailed_price_list = {}
198
171
  end
199
172
 
200
- optimal_prices = detailed_price_list&.dig('marketConditionList')&.sort do |a, b|
201
- b['sellCount'] - a['sellCount']
202
- end
173
+ optimal_prices = detailed_price_list&.dig('marketConditionList')&.sort_by { |p| -p['sellCount'] }
203
174
 
204
- total_stock = optimal_prices.to_a.map { |price| price["sellCount"] }.sum
175
+ total_stock = optimal_prices.to_a.sum { |price| price["sellCount"] }
205
176
 
206
177
  optimal_price = optimal_prices.to_a.first
207
178
 
@@ -234,12 +205,10 @@ class MarketSearcher
234
205
  potential_recipe = []
235
206
 
236
207
  recipe.each.with_index do |ingredient, ing_index|
237
- ingredient_id = ingredient['id'] ? ingredient['id'] : ingredient[:id]
238
- quant = ingredient['quant'] ? ingredient['quant'] : ingredient[:quant]
239
- enhance_level = ingredient['enhance_level'] ? ingredient['enhance_level'] : ingredient[:enhance_level]
240
- is_m_recipe = ingredient['is_m_recipe'] ? ingredient['is_m_recipe'] : ingredient[:is_m_recipe]
241
- quant = 1 if quant.nil?
242
- 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]
243
212
 
244
213
  if @ingredient_cache[ingredient_id] && EXCHANGE_ITEMS[ingredient_id].nil? == true
245
214
  cached_ingredient = { **@ingredient_cache[ingredient_id], quant: quant, for_recipe_id: recipe_id, is_m_recipe: is_m_recipe }
@@ -258,9 +227,7 @@ class MarketSearcher
258
227
  item_price_info_hash = exchange_info
259
228
  end
260
229
 
261
- item_price_info = item_price_info_hash.transform_keys { |key|
262
- key.to_s.gsub(/(.)([A-Z])/,'\1_\2').downcase.to_sym
263
- }
230
+ item_price_info = item_price_info_hash.transform_keys { |key| Utils.snake_sym(key) }
264
231
 
265
232
  # gathering out of stock items to show to the user
266
233
  stock_string = "#{quant}x [#{item_price_info[:main_key]}] #{item_price_info[:name].downcase}"
@@ -313,14 +280,14 @@ class MarketSearcher
313
280
  mapped_recipe_prices.push map_recipe_prices(potential_recipes, item_with_recipe, subcategory)
314
281
  end
315
282
 
316
- mapped_recipe_prices.filter { |e| !e.nil? && !!e }
283
+ mapped_recipe_prices.compact
317
284
  end
318
285
 
319
286
  def map_recipe_prices(potential_recipes, item, category)
320
287
  average_procs = 1
321
288
 
322
289
  if [25, 35].include? item[:main_category]
323
- unless /oil of|draught|\[mix\]|\[party\]|immortal:|perfume|indignation|flame of|essence of dawn/im.match item[:name].downcase
290
+ unless /oil of|draught|\[mix\]|\[party\]|immortal:|perfume|indignation|flame of|essence of dawn|mystical cleaning oil|whale tendon|leather glaze/im.match item[:name].downcase
324
291
  average_procs = 2.5
325
292
  end
326
293
 
@@ -369,7 +336,7 @@ class MarketSearcher
369
336
  # are some seriously mysterious alchemy recipes out there...
370
337
  ingredients_already_appeared = []
371
338
  filtered_selected_recipe = selected_recipe.filter do |ingredient|
372
- return false if ingredients_already_appeared.include? ingredient[:name]
339
+ next false if ingredients_already_appeared.include? ingredient[:name]
373
340
  ingredients_already_appeared.push(ingredient[:name])
374
341
  true
375
342
  end
@@ -382,12 +349,7 @@ class MarketSearcher
382
349
 
383
350
  body_string = "#{ENVData::RVT}&mainKey=#{item[:id]}&subKey=0&chooseKey=0&isUp=true&keyType=0&name=#{URI.encode_www_form_component(item[:name])}"
384
351
 
385
- item_price_data = HTTParty.post(
386
- URI(@market_sell_buy_url),
387
- headers: ENVData.get_central_market_headers(ENVData.get_incap_cookie(@region_subdomain)),
388
- body: body_string,
389
- content_type: 'application/x-www-form-urlencoded'
390
- )
352
+ item_price_data = market_post(@market_sell_buy_url, body_string)
391
353
 
392
354
  item_price_data = {} if item_price_data.to_s.downcase.include? 'incapsula incident'
393
355
 
@@ -448,7 +410,6 @@ class MarketSearcher
448
410
  end
449
411
 
450
412
  def do_if_category_matches(options, &procedure)
451
- procedure.call if options[:all_subcategories]
452
- procedure.call if options[:subcategory] == options[:subcat_to_match]
413
+ procedure.call if options[:all_subcategories] || (options[:subcategory] == options[:subcat_to_match])
453
414
  end
454
415
  end
@@ -18,4 +18,8 @@ module Utils
18
18
  make_permutations input, limit
19
19
  end
20
20
  end
21
+
22
+ def self.snake_sym(key)
23
+ key.to_s.gsub(/(.)([A-Z])/, '\1_\2').downcase.to_sym
24
+ end
21
25
  end
@@ -2,7 +2,20 @@
2
2
 
3
3
  require 'date'
4
4
 
5
- $request_verification_token = '__RequestVerificationToken=aVYGQPovG8EI6bRIagh8tbHJUhZlM-nH3UKVQaV9R9N0vODzmWcB747BHEsHaphwANvzsaNi5TCPlB-72-e1LadqAlL-bdkDkTqVh4gMnu81' # rubocop:disable Layout/LineLength
5
+ require_relative '../../environment'
6
+
7
+ if ENV['rvt_dom'].length == 0
8
+ puts "empty DOM environment variable! set ENV['rvt_dom'] in environment.rb."
9
+ end
10
+
11
+ if ENV['rvt_cookie'].length == 0
12
+ puts "empty cookie environment variable! set ENV['rvt_cookie'] in environment.rb."
13
+ end
14
+
15
+ if ENV['rvt_dom'].length == 0 || ENV['rvt_cookie'].length == 0
16
+ puts ''
17
+ exit
18
+ end
6
19
 
7
20
  module Utils
8
21
  # constants to use when user is configuring the tool
@@ -19,12 +32,14 @@ module Utils
19
32
  'alchemy stone': "searches 'imperfect alchemy stone of'",
20
33
  reagent: "searches 'reagent'",
21
34
  'black stone': 'category 30, subcategory 1',
35
+ 'food': 'category 35, subcategory 4',
22
36
  'misc': 'category 25, subcategory 8',
23
37
  'other tools': 'category 40, subcategory 10',
24
38
  'manos': "searches 'manos'",
25
39
  'purified lightstone': "searches 'purified lightstone of' (requires guru 1 alchemy)",
26
40
  'combined crystals': 'category 50, subcategory 4',
27
41
  'essences of dawn': "searches 'essence of dawn'",
42
+ # 'stuffed animals': "searches 'stuffed'",
28
43
  # 'magic crystal': "searches 'magic crystal'",
29
44
  exit: 'stops the search',
30
45
  }.freeze
@@ -42,7 +57,7 @@ module Utils
42
57
  jp: 'trade.jp.playblackdesert.com',
43
58
  th: 'trade.th.playblackdesert.com',
44
59
  tw: 'trade.tw.playblackdesert.com',
45
- sa: 'blackdesert-tradeweb.playredfox.com',
60
+ sa: 'trade.sa.playblackdesert.com',
46
61
  exit: 'stops the search',
47
62
  }.freeze
48
63
 
@@ -76,10 +91,6 @@ module Utils
76
91
  no: false,
77
92
  yes: true,
78
93
  }.freeze
79
-
80
- def self.set_rvt(rvt)
81
- $request_verification_token = rvt
82
- end
83
94
  end
84
95
 
85
96
  # constants that will be used in by search / scraping scripts
@@ -89,8 +100,8 @@ module Utils
89
100
  ERROR_LOG = './error.log'
90
101
  # note that the following two tokens are different!! the first one is from a request cookie
91
102
  # the second is from the dom of the actual BDO central market interface
92
- COOKIE = '__RequestVerificationToken=aVYGQPovG8EI6bRIagh8tbHJUhZlM-nH3UKVQaV9R9N0vODzmWcB747BHEsHaphwANvzsaNi5TCPlB-72-e1LadqAlL-bdkDkTqVh4gMnu81' # rubocop:disable Layout/LineLength
93
- RVT = '__RequestVerificationToken=yWbqJmiU4wcp2IRQGkbDfqMFs2fjCYx4UqVxg4umK8CvdbLhweMLZ1es-4SFWD8J1UfoqwbaQyo_YuzAkSzHWY8Wjyx4ttwZBvtu_pd--9U1' # rubocop:disable Layout/LineLength
103
+ COOKIE = ENV['rvt_cookie']
104
+ RVT = ENV['rvt_dom']
94
105
  WORLD_MARKET_LIST = '/GetWorldMarketList'
95
106
  MARKET_SUB_LIST = '/GetWorldMarketSubList'
96
107
  MARKET_SEARCH_LIST = '/GetWorldMarketSearchList'
@@ -23,12 +23,8 @@ module Utils
23
23
  end
24
24
 
25
25
  def write(data)
26
- item_map = read_all
27
- File.open(@cache_file, 'w') do |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
@@ -75,7 +75,7 @@ module Utils
75
75
  },
76
76
  7304 => {
77
77
  name: 'Strawberry',
78
- id: 9008,
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
- sub_category_: 8,
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
- sub_category_: 5,
486
+ sub_category: 5,
487
487
  },
488
488
  521 => {
489
489
  name: 'HP Potion (Medium)',
490
- id: 517,
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
- sub_category_: 5,
497
+ sub_category: 5,
498
498
  },
499
499
  519 => {
500
500
  name: 'HP Potion (Large)',
501
- id: 517,
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
- sub_category_: 5,
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
- sub_category_: 5,
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
- sub_category_: 5,
530
+ sub_category: 5,
531
531
  },
532
532
  522 => {
533
533
  name: 'MP Potion (Large)',
data/lib/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module BDOAP
4
- VERSION = "0.0.3"
4
+ VERSION = "0.0.5"
5
5
  end
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.3
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: 2025-04-21 00:00:00.000000000 Z
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.7
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: []