sorare-rewards 1.0.0.beta5 → 1.0.1

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: 0a70b22851cb74e28254ed02396bcb2663b0af657ea7b91ab95517d8be764e27
4
- data.tar.gz: 8bee3c9c69e8e7cbf16ad0f612b9cbbde502582cc657e4b952ded56e6c11fce5
3
+ metadata.gz: 8cc85589244de6f453ed70184da06e8c679ec19b4b2c5fe86ee1ea4936c2c402
4
+ data.tar.gz: 521385c5b0b1e917d7be61eaef02d2284c24082fb18eeec561f9da6160ea650f
5
5
  SHA512:
6
- metadata.gz: 9ccfd7fa498eb3c7795a0c658a6921703bcd25bd536f3742aac1492e7d7e0963bb6828b4ed3836e40aab6d1844542353c137c447e461af3ca88da3eb67969936
7
- data.tar.gz: 6baec2fd1cec6cbdb0c3493c64169afabe0d07df70920b6f8a8a253a8a330053feed8a1a03ed62e0d4034b6aab601a4fe90dd8a213c514fdf77bf56fddf2d59e
6
+ metadata.gz: 4b998f1b6bca4cbb8ca9fc9fcab6b2d9f2f32b7f4384e4b736ec2dcd3b51b9e1e17d62daf7f85b715e21a060445abd5e495342a01bc725994847ca028a991733
7
+ data.tar.gz: fff45a44fc25d684adeb45985aac4fde3b876977feca1f9fd3b4f9cd7b3e60f82b3f3f0294df25cc28aead951ee16f0b287192d4bb44fb1cd823602067f3ac42
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- sorare-rewards (1.0.0.beta5)
4
+ sorare-rewards (1.0.1)
5
5
  activesupport (~> 6.1)
6
6
  interactor (~> 3.0)
7
7
  json (~> 2)
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,116 +1,66 @@
1
1
  rare: &rare
2
2
  tier_0:
3
- - loop: 0
4
- - loop: 0
5
- - loop: 2
6
- - loop: 1
3
+ - cards_per_loop: 0
4
+ - cards_per_loop: 0
5
+ - cards_per_loop: 2
6
+ - cards_per_loop: 1
7
7
  tier_1:
8
- - loop: 0
9
- - loop: 0
10
- - loop: 2
11
- - loop: 1
8
+ - cards_per_loop: 0
9
+ - cards_per_loop: 0
10
+ - cards_per_loop: 2
11
+ - cards_per_loop: 1
12
12
  tier_2:
13
- - loop: 0
14
- - loop: 0
15
- - loop: 0
16
- - loop: 1
13
+ - cards_per_loop: 0
14
+ - cards_per_loop: 0
15
+ - cards_per_loop: 1
16
+ - cards_per_loop: 4
17
17
  tier_3:
18
- - loop: 0
19
- - loop: 0
20
- - loop: 0
21
- - loop: 1
18
+ - cards_per_loop: 0
19
+ - cards_per_loop: 0
20
+ - cards_per_loop: 0
21
+ - cards_per_loop: 1
22
22
 
23
23
  super_rare: &super_rare
24
24
  tier_0:
25
- - loop: 2
26
- - loop: 1
27
- - loop: 0
28
- - loop: 0
25
+ - cards_per_loop: 2
26
+ - cards_per_loop: 1
27
+ - cards_per_loop: 0
28
+ - cards_per_loop: 0
29
29
  tier_1:
30
- - loop: 1
31
- - loop: 1
32
- - loop: 0
33
- - loop: 0
30
+ - cards_per_loop: 1
31
+ - cards_per_loop: 1
32
+ - cards_per_loop: 0
33
+ - cards_per_loop: 0
34
34
  tier_2:
35
- - loop: 0
36
- - loop: 1
37
- - loop: 0
38
- - loop: 0
35
+ - cards_per_loop: 0
36
+ - cards_per_loop: 1
37
+ - cards_per_loop: 0
38
+ - cards_per_loop: 0
39
39
  tier_3:
40
- - loop: 0
41
- - loop: 1
42
- - loop: 0
43
- - loop: 0
44
-
45
- unique: &unique
46
- tier_0:
47
- - cards: 0
48
- - cards: 0
49
- - cards: 0
50
- - cards: 0
51
- tier_1:
52
- - cards: 0
53
- - cards: 0
54
- - cards: 0
55
- - cards: 0
56
- tier_2:
57
- - cards: 0
58
- - cards: 0
59
- - cards: 0
60
- - cards: 0
61
- tier_3:
62
- - cards: 0
63
- - cards: 0
64
- - cards: 0
65
- - cards: 0
66
-
67
- empty: &empty
68
- tier_0:
69
- - cards: 0
70
- - cards: 0
71
- - cards: 0
72
- - cards: 0
73
- tier_1:
74
- - cards: 0
75
- - cards: 0
76
- - cards: 0
77
- - cards: 0
78
- tier_2:
79
- - cards: 0
80
- - cards: 0
81
- - cards: 0
82
- - cards: 0
83
- tier_3:
84
- - cards: 0
85
- - cards: 0
86
- - cards: 0
87
- - cards: 0
40
+ - cards_per_loop: 0
41
+ - cards_per_loop: 1
42
+ - cards_per_loop: 0
43
+ - cards_per_loop: 0
88
44
 
89
45
  leagues:
90
46
  global-all_star:
91
47
  rare: *rare
92
48
  super_rare: *super_rare
93
- unique: *unique
94
49
  global-under_twenty_one:
95
50
  rare: *rare
96
51
  super_rare: *super_rare
97
- unique: *unique
98
52
  champion-europe:
99
53
  rare: *rare
100
54
  super_rare: *super_rare
101
- unique: *unique
102
55
  challenger-europe:
103
56
  rare: *rare
104
57
  super_rare: *super_rare
105
- unique: *unique
106
58
  champion-asia:
107
59
  rare: *rare
108
60
  super_rare: *super_rare
109
- unique: *unique
110
61
  champion-america:
111
62
  rare: *rare
112
63
  super_rare: *super_rare
113
- unique: *unique
114
64
  special-weekly:
115
65
  rare:
116
66
  tier_0:
@@ -130,26 +80,7 @@ leagues:
130
80
  - pct: 1
131
81
  tier_3:
132
82
  - pct: 1
133
- unique: *empty
134
83
  starter-rookie:
135
- unique:
136
- tier_0:
137
- - cards: 0
138
- tier_1:
139
- - cards: 0
140
- tier_2:
141
- - cards: 0
142
- tier_3:
143
- - cards: 0
144
- super_rare:
145
- tier_0:
146
- - cards: 0
147
- tier_1:
148
- - cards: 0
149
- tier_2:
150
- - cards: 0
151
- tier_3:
152
- - cards: 0
153
84
  rare:
154
85
  tier_0:
155
86
  - cards: 0
@@ -159,7 +90,3 @@ leagues:
159
90
  - cards: 2
160
91
  tier_3:
161
92
  - cards: 0
162
- global-unique_only:
163
- rare: *empty
164
- super_rare: *empty
165
- unique: *empty
@@ -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
  end
30
30
 
31
31
  def allocate!
32
- supply.keys.index_with do |rarity|
32
+ (config || {}).keys.index_with do |rarity|
33
33
  ComputeForRarity.call!(**context.to_h, supply: supply[rarity], config: config[rarity]).rarity_allocations
34
34
  end
35
35
  end
@@ -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
@@ -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
 
@@ -50,12 +50,12 @@ module Sorare
50
50
  def initialize_tier_picker(players, rarity, tier)
51
51
  pickers[rarity][tier] = Picker.new(game_week.public_seed, salt)
52
52
 
53
- players.each do |slug|
54
- pickers[rarity][tier].add_player(slug, player_supply(league, rarity, slug))
53
+ players.each do |slug, _|
54
+ pickers[rarity][tier].add_player(slug, player_supply(rarity, slug))
55
55
  end
56
56
  end
57
57
 
58
- def player_supply(league, rarity, slug)
58
+ def player_supply(rarity, slug)
59
59
  game_week.player(slug).overall_supply(league, rarity)
60
60
  end
61
61
  end
@@ -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.beta5'
5
+ VERSION = '1.0.1'
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.beta5
4
+ version: 1.0.1
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-07-10 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: