sorare-rewards 1.0.0.beta7 → 1.0.2

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: f38e7364844a7fbec826d33001af0388606ce9969c78448de29f8bae49ffd353
4
- data.tar.gz: f85cc53fb913a25977617773f6fb83cb459b5bc33174f469f02f400dbf7ca88a
3
+ metadata.gz: 503bd2bc5d9b16f6c2ba4e9209c14920dc000730dc3466eea88534abe97187c2
4
+ data.tar.gz: c03342737d6af15c514932029928fb26acd255700811e8bd9de53f62f7a5a91e
5
5
  SHA512:
6
- metadata.gz: f158ca5054549b5d9b3951c68c9e14bac9f9575f69e04d3c430f9b918d7d293b114574b8c24fc25832c7e0a0b7db3c646f44945dd1ac54f08bc1122e533e5835
7
- data.tar.gz: 219d23b96f3d94a97b017dca5e4716b7da81fd1f2e2e6bf3a06a9d475482745ef65c419e41c1d07c4e24b5b0891f83e9f7d5a31f486651ee88e0f515e80aa57d
6
+ metadata.gz: 496c0f02f3c3735895c314d5f680a36fd3a2965a63d196f209efdd6cefcb6c9eaf5a8f5995c90a27ad36963cd68eb071f5467abf998738b856ca1a389dba87c6
7
+ data.tar.gz: 5386e7e1e7f95c9b703882e5623c0aeec9ce71b4d9d46e85f807601e2f918b76c095dbac01f26ccfacd2262a0384d4f83ec22857810629e5b29ff274bc6a2d66
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- sorare-rewards (1.0.0.beta7)
4
+ sorare-rewards (1.0.2)
5
5
  activesupport (~> 6.1)
6
6
  interactor (~> 3.0)
7
7
  json (~> 2)
@@ -23,12 +23,15 @@ GEM
23
23
  i18n (1.8.10)
24
24
  concurrent-ruby (~> 1.0)
25
25
  interactor (3.1.2)
26
+ io-wait (0.1.0)
26
27
  json (2.5.1)
27
28
  minitest (5.14.4)
28
29
  net-http (0.1.1)
29
30
  net-protocol
30
31
  uri
31
- net-protocol (0.1.0)
32
+ net-protocol (0.1.1)
33
+ io-wait
34
+ timeout
32
35
  ostruct (0.2.0)
33
36
  parallel (1.20.1)
34
37
  parser (3.0.1.0)
@@ -67,6 +70,7 @@ GEM
67
70
  rubocop (~> 1.0)
68
71
  rubocop-ast (>= 1.1.0)
69
72
  ruby-progressbar (1.11.0)
73
+ timeout (0.1.1)
70
74
  tzinfo (2.0.4)
71
75
  concurrent-ruby (~> 1.0)
72
76
  unicode-display_width (2.0.0)
data/README.md CHANGED
@@ -1,9 +1,5 @@
1
1
  # Sorare::Rewards
2
2
 
3
- Welcome to your new gem! In this directory, you'll find the files you need to be able to package up your Ruby library into a gem. Put your Ruby code in the file `lib/sorare/rewards`. To experiment with that code, run `bin/console` for an interactive prompt.
4
-
5
- TODO: Delete this and the text above, and describe your gem
6
-
7
3
  ## Installation
8
4
 
9
5
  Add this line to your application's Gemfile:
@@ -22,13 +18,31 @@ Or install it yourself as:
22
18
 
23
19
  ## Usage
24
20
 
25
- To compute the rewards distribution for a given Game Week :
21
+
22
+ First you need to load a game week
26
23
 
27
24
  ```ruby
28
- Sorare::Rewards::build_rewards(slug)
25
+ game_week = Sorare::Rewards::GameWeek.new(hash: 'QmbwCo1fuhRN1T2DyEQtETefsBH6yCj8h7VjMW5iGfT11Z', salt: 'dce0053984405687efcdf3d1a61ffa67')
29
26
  ```
30
27
 
31
- With `slug` being the Fixture slug.
28
+ Game Week's `hash` and `salt` can be retrieved using the GQL API, the salt is made public after the rewards have been distributed.
29
+
30
+
31
+ To compute the number of rewards for the game week :
32
+
33
+ ```ruby
34
+ # Card rewards :
35
+ game_week.card_allocations
36
+
37
+ # Eth rewards :
38
+ game_week.prize_pools
39
+ ```
40
+
41
+ To get the cards rewarded for a GameWeek :
42
+
43
+ ```ruby
44
+ game_week.cards_picked
45
+ ```
32
46
 
33
47
  ## Development
34
48
 
@@ -1,64 +1,96 @@
1
+ limited: &limited
2
+ tier_0:
3
+ - pct: 0
4
+ - pct: 0
5
+ - pct: 0
6
+ - pct: 0
7
+ - pct: 0.33
8
+ tier_1:
9
+ - pct: 0
10
+ - pct: 0
11
+ - pct: 0
12
+ - pct: 0
13
+ - pct: 0.33
14
+ tier_2:
15
+ - pct: 0
16
+ - pct: 0
17
+ - pct: 0
18
+ - pct: 0
19
+ - pct: 0.8
20
+ tier_3:
21
+ - pct: 0
22
+ - pct: 0
23
+ - pct: 0
24
+ - pct: 0
25
+ - pct: 1
26
+
1
27
  rare: &rare
2
28
  tier_0:
3
- - loop: 0
4
- - loop: 0
5
- - loop: 2
6
- - loop: 1
29
+ - cards_per_loop: 0
30
+ - cards_per_loop: 0
31
+ - cards_per_loop: 2
32
+ - cards_per_loop: 1
7
33
  tier_1:
8
- - loop: 0
9
- - loop: 0
10
- - loop: 2
11
- - loop: 1
34
+ - cards_per_loop: 0
35
+ - cards_per_loop: 0
36
+ - cards_per_loop: 2
37
+ - cards_per_loop: 1
12
38
  tier_2:
13
- - loop: 0
14
- - loop: 0
15
- - loop: 0
16
- - loop: 1
39
+ - cards_per_loop: 0
40
+ - cards_per_loop: 0
41
+ - cards_per_loop: 1
42
+ - cards_per_loop: 4
17
43
  tier_3:
18
- - loop: 0
19
- - loop: 0
20
- - loop: 0
21
- - loop: 1
44
+ - cards_per_loop: 0
45
+ - cards_per_loop: 0
46
+ - cards_per_loop: 0
47
+ - cards_per_loop: 1
22
48
 
23
49
  super_rare: &super_rare
24
50
  tier_0:
25
- - loop: 2
26
- - loop: 1
27
- - loop: 0
28
- - loop: 0
51
+ - cards_per_loop: 2
52
+ - cards_per_loop: 1
53
+ - cards_per_loop: 0
54
+ - cards_per_loop: 0
29
55
  tier_1:
30
- - loop: 1
31
- - loop: 1
32
- - loop: 0
33
- - loop: 0
56
+ - cards_per_loop: 1
57
+ - cards_per_loop: 1
58
+ - cards_per_loop: 0
59
+ - cards_per_loop: 0
34
60
  tier_2:
35
- - loop: 0
36
- - loop: 1
37
- - loop: 0
38
- - loop: 0
61
+ - cards_per_loop: 0
62
+ - cards_per_loop: 1
63
+ - cards_per_loop: 0
64
+ - cards_per_loop: 0
39
65
  tier_3:
40
- - loop: 0
41
- - loop: 1
42
- - loop: 0
43
- - loop: 0
66
+ - cards_per_loop: 0
67
+ - cards_per_loop: 1
68
+ - cards_per_loop: 0
69
+ - cards_per_loop: 0
44
70
 
45
71
  leagues:
46
72
  global-all_star:
73
+ limited: *limited
47
74
  rare: *rare
48
75
  super_rare: *super_rare
49
76
  global-under_twenty_one:
77
+ limited: *limited
50
78
  rare: *rare
51
79
  super_rare: *super_rare
52
80
  champion-europe:
81
+ limited: *limited
53
82
  rare: *rare
54
83
  super_rare: *super_rare
55
84
  challenger-europe:
85
+ limited: *limited
56
86
  rare: *rare
57
87
  super_rare: *super_rare
58
88
  champion-asia:
89
+ limited: *limited
59
90
  rare: *rare
60
91
  super_rare: *super_rare
61
92
  champion-america:
93
+ limited: *limited
62
94
  rare: *rare
63
95
  super_rare: *super_rare
64
96
  special-weekly:
@@ -2,17 +2,20 @@
2
2
 
3
3
  require 'json'
4
4
  require 'net/http'
5
+ require 'active_support/core_ext/module/delegation'
5
6
 
6
7
  module Sorare
7
8
  module Rewards
8
9
  # GameWeek stores the reward data of a game week
9
10
  class GameWeek
10
- attr_reader :data, :config, :salt
11
+ attr_reader :salt
12
+
13
+ delegate :card_allocations, :prize_pools, to: :reward_allocations
14
+ delegate :cards_picked, to: :card_rewards
11
15
 
12
16
  def initialize(data: nil, hash: nil, salt: nil)
13
- uri = URI("#{Sorare::Rewards.configuration.gateway}#{hash}")
14
- @data = data || JSON.parse(::Net::HTTP.get(uri))
15
- @config = GameWeekConfig.new(@data['config'])
17
+ @uri = URI("#{Sorare::Rewards.configuration.gateway}#{hash}")
18
+ @data = data
16
19
  @salt = salt
17
20
  end
18
21
 
@@ -22,6 +25,14 @@ module Sorare
22
25
  end
23
26
  end
24
27
 
28
+ def data
29
+ @data ||= JSON.parse(::Net::HTTP.get(@uri))
30
+ end
31
+
32
+ def config
33
+ @config ||= GameWeekConfig.new(@data['config'])
34
+ end
35
+
25
36
  def supply_for(league, rarity: nil, player: nil)
26
37
  return (supply.dig(league, rarity, player) || 0) if rarity && player
27
38
  return (supply.dig(league, rarity) || {}) if rarity
@@ -37,14 +48,14 @@ module Sorare
37
48
  end
38
49
  end
39
50
 
40
- def rewards
51
+ def reward_allocations
41
52
  raise 'Salt required' unless salt
42
53
 
43
- @rewards ||= Sorare::Rewards::Build.call!(game_week: self, salt: salt)
54
+ @reward_allocations ||= Sorare::Rewards::Build.call!(game_week: self, salt: salt)
44
55
  end
45
56
 
46
57
  def card_rewards
47
- @card_rewards ||= Sorare::Rewards::Pick.call!(rewards.to_h)
58
+ @card_rewards ||= Sorare::Rewards::Pick.call!(reward_allocations.to_h)
48
59
  end
49
60
 
50
61
  def league(name)
@@ -29,7 +29,7 @@ module Sorare
29
29
  allocate_cards
30
30
  allocate_pct if has?('pct')
31
31
  allocate_extra if has?('pct')
32
- allocate_loop if has?('loop')
32
+ allocate_loop if has?('cards_per_loop')
33
33
  end
34
34
 
35
35
  def allocate_divisions(&block)
@@ -55,7 +55,7 @@ module Sorare
55
55
  def allocate_loop
56
56
  while remaining_supply.positive?
57
57
  allocate_divisions do |division_config, division|
58
- allocated[division] += [division_config['loop'] || 0, remaining_supply].min
58
+ allocated[division] += [division_config['cards_per_loop'] || 0, remaining_supply].min
59
59
  end
60
60
  end
61
61
  end
@@ -85,7 +85,7 @@ module Sorare
85
85
  end
86
86
 
87
87
  def check_config!
88
- return if config && [0, 1].include?(config.sum { |q| q['pct'] || 0 })
88
+ return if config
89
89
 
90
90
  context.fail!(error: 'Invalid config')
91
91
  end
@@ -25,13 +25,13 @@ module Sorare
25
25
  delegate :league, :allocations, :pickers, :qualified_players, to: :context
26
26
 
27
27
  def call
28
- context.division_picks = allocations.keys.index_with do |rarity|
28
+ context.cards_picked = allocations.keys.index_with do |rarity|
29
29
  PickForDivisionAndRarity.call!(
30
30
  **context.to_h,
31
31
  rarity: rarity,
32
32
  pickers: pickers[rarity],
33
33
  allocations: allocations[rarity]
34
- ).rarity_picks
34
+ ).cards_picked
35
35
  end
36
36
  end
37
37
  end
@@ -20,7 +20,7 @@ module Sorare
20
20
  delegate :league, :rarity, :allocations, :pickers, to: :context
21
21
 
22
22
  def call
23
- context.rarity_picks = supply!
23
+ context.cards_picked = supply!
24
24
  end
25
25
 
26
26
  def supply!
@@ -28,7 +28,7 @@ module Sorare
28
28
  next [] if pickers&.dig(tier).nil?
29
29
 
30
30
  PickForDivisionRarityAndQuality.call!(**context.to_h, allocations: allocations[tier],
31
- picker: pickers[tier]).picks
31
+ picker: pickers[tier]).cards_picked
32
32
  end
33
33
  end
34
34
  end
@@ -15,11 +15,11 @@ module Sorare
15
15
 
16
16
  MISSING_CARDS = 'There are not enough cards to fulfill the requirements'
17
17
 
18
- delegate :picker, :allocations, :league, :rarity, :force, :picks, to: :context
18
+ delegate :picker, :allocations, :league, :rarity, :force, :cards_picked, to: :context
19
19
  delegate :game_week, to: :league
20
20
 
21
21
  def call
22
- context.picks = []
22
+ context.cards_picked = []
23
23
 
24
24
  pick!
25
25
  check_length! unless force
@@ -27,24 +27,24 @@ module Sorare
27
27
  end
28
28
 
29
29
  def pick!
30
- pick_if_available! while picks.length != allocations && picker.length.positive?
30
+ pick_if_available! while cards_picked.length != allocations && picker.length.positive?
31
31
  end
32
32
 
33
33
  def pick_if_available!
34
34
  player = picker.pick
35
- return if picker.player_counter[player] > game_week.player(player).supply(league, rarity).ceil
35
+ return if picker.player_counter[player] > game_week.player(player).pickable_supply(league, rarity)
36
36
 
37
- picks.push(player)
37
+ cards_picked.push(player)
38
38
  end
39
39
 
40
40
  def reorder!
41
- picks.sort! do |a, b|
41
+ cards_picked.sort! do |a, b|
42
42
  game_week.player(a).rank(league, rarity) <=> game_week.player(b).rank(league, rarity)
43
43
  end
44
44
  end
45
45
 
46
46
  def check_length!
47
- return if picks.length == allocations
47
+ return if cards_picked.length == allocations
48
48
 
49
49
  context.fail!(error: MISSING_CARDS)
50
50
  end
@@ -22,14 +22,14 @@ module Sorare
22
22
  delegate :game_week, :allocations, :salt, :picks, to: :context
23
23
 
24
24
  def call
25
- context.picks = picks
25
+ context.cards_picked = pick!
26
26
  end
27
27
 
28
- def picks
28
+ def pick!
29
29
  allocations.each_league_allocations.each_with_object({}) do |(league_name, league_allocations), picks|
30
30
  picks[league_name] = PickForLeague.call!(
31
31
  **context.to_h, league: game_week.league(league_name), allocations: league_allocations
32
- ).league_picks
32
+ ).cards_picked
33
33
  end
34
34
  end
35
35
  end
@@ -24,10 +24,10 @@ module Sorare
24
24
  context.pickers = {}
25
25
  add_pickers!
26
26
 
27
- context.league_picks = allocations.keys.index_with do |division|
27
+ context.cards_picked = allocations.keys.index_with do |division|
28
28
  PickForDivision.call!(
29
29
  **context.to_h, pickers: pickers, allocations: allocations[division]
30
- ).division_picks
30
+ ).cards_picked
31
31
  end
32
32
  end
33
33
 
@@ -24,11 +24,11 @@ module Sorare
24
24
  # Depending on the way the allocations interpreter is implemented it could be done by him or we
25
25
  # update the allocations process to match the structure
26
26
  def call
27
- context.picks = Sorare::Rewards::Cards::PickForGameWeek.call!(
27
+ context.cards_picked = Sorare::Rewards::Cards::PickForGameWeek.call!(
28
28
  **context.to_h,
29
29
  salt: salt,
30
30
  allocations: transposed_allocations
31
- ).picks
31
+ ).cards_picked
32
32
  end
33
33
 
34
34
  def transposed_allocations
@@ -13,7 +13,7 @@ module Sorare
13
13
 
14
14
  def call
15
15
  context.division_prize_pools = available_prize_pools.map do |available_prize_pool|
16
- available_prize_pool * percentage_rewarded
16
+ (available_prize_pool * percentage_rewarded).round(2)
17
17
  end
18
18
  end
19
19
 
@@ -44,7 +44,7 @@ module Sorare
44
44
  end
45
45
 
46
46
  def player_supply(slug)
47
- game_week.player(slug).supply(league, rarity)
47
+ game_week.player(slug).reward_pool_supply_contribution(league, rarity)
48
48
  end
49
49
 
50
50
  def rounded_supply(float_supply)
@@ -18,12 +18,11 @@ module Sorare
18
18
 
19
19
  # Use the tier specified within the data
20
20
  def qualified_players_by_tier
21
- tiers = Sorare::Rewards.configuration.tiers.times.map { |_| {} }
22
- sorted_supply.each do |slug, data|
23
- tiers[data['tier']][slug] = data
21
+ Sorare::Rewards.configuration.tiers.times.map do |tier|
22
+ sorted_supply.keys.filter do |slug|
23
+ sorted_supply.dig(slug, 'tier') == tier
24
+ end
24
25
  end
25
-
26
- tiers
27
26
  end
28
27
 
29
28
  # Use the rank in the array
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'time'
3
+ require 'active_support/core_ext/module/delegation'
4
4
 
5
5
  module Sorare
6
6
  module Rewards
@@ -1,7 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'json'
4
- require 'net/http'
3
+ require 'active_support/core_ext/module/delegation'
5
4
 
6
5
  module Sorare
7
6
  module Rewards
@@ -25,11 +25,18 @@ module Sorare
25
25
  @game_data.present?
26
26
  end
27
27
 
28
- def supply(league, rarity)
28
+ def reward_pool_supply_contribution(league, rarity)
29
29
  return 0 unless playing? && remaining_games_for_supply.positive?
30
30
 
31
31
  [
32
- uncapped_supply_for_game_week(league, rarity), # Remaining supply
32
+ uncapped_supply_for_game_week(league, rarity),
33
+ pickable_supply(league, rarity)
34
+ ].min
35
+ end
36
+
37
+ def pickable_supply(league, rarity)
38
+ [
39
+ overall_supply(league, rarity), # Remaining supply
33
40
  available_during_cooldown(league, rarity), # Cooldown limit
34
41
  @config.distribution_limit(rarity) # Hard limit
35
42
  ].min
@@ -52,10 +59,12 @@ module Sorare
52
59
  end
53
60
 
54
61
  def rewarded_during_cooldown(league, rarity)
55
- (rewards&.dig(league) || []).count { |at| (Time.parse(at) + @config.cooldown_since(rarity)) < Time.now }
62
+ (@game_data&.dig(league.name, rarity) || []).count do |at|
63
+ (Time.parse(at) + @config.cooldown_since(rarity)) > Time.now
64
+ end
56
65
  end
57
66
 
58
- %w[rewards remaining_games_for_supply remaining_games].each do |key|
67
+ %w[remaining_games_for_supply remaining_games].each do |key|
59
68
  define_method(key) do
60
69
  @game_data&.dig(key)
61
70
  end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Sorare
4
4
  module Rewards
5
- VERSION = '1.0.0.beta7'
5
+ VERSION = '1.0.2'
6
6
  end
7
7
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sorare-rewards
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0.beta7
4
+ version: 1.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - pierre
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2021-06-30 00:00:00.000000000 Z
11
+ date: 2021-08-17 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -220,9 +220,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
220
220
  version: 2.7.1
221
221
  required_rubygems_version: !ruby/object:Gem::Requirement
222
222
  requirements:
223
- - - ">"
223
+ - - ">="
224
224
  - !ruby/object:Gem::Version
225
- version: 1.3.1
225
+ version: '0'
226
226
  requirements: []
227
227
  rubygems_version: 3.1.6
228
228
  signing_key: