sorare-rewards 1.4.6 → 1.6.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +12 -0
- data/Gemfile.lock +4 -6
- data/lib/sorare/rewards/card_picker.rb +31 -22
- data/lib/sorare/rewards/configuration.rb +1 -1
- data/lib/sorare/rewards/flat_picker.rb +56 -0
- data/lib/sorare/rewards/game_week.rb +8 -0
- data/lib/sorare/rewards/game_week_rewards.rb +7 -3
- data/lib/sorare/rewards/interactor.rb +1 -0
- data/lib/sorare/rewards/interactors/cards/pick_for_division.rb +4 -9
- data/lib/sorare/rewards/interactors/cards/pick_for_division_and_rarity.rb +7 -8
- data/lib/sorare/rewards/interactors/cards/pick_for_division_rarity_and_quality.rb +3 -3
- data/lib/sorare/rewards/interactors/cards/pick_for_game_week.rb +1 -0
- data/lib/sorare/rewards/interactors/cards/pick_for_league.rb +3 -33
- data/lib/sorare/rewards/interactors/concerns/with_picker_options.rb +16 -0
- data/lib/sorare/rewards/interactors/supply/compute_for_rarity.rb +2 -2
- data/lib/sorare/rewards/league.rb +22 -6
- data/lib/sorare/rewards/player.rb +53 -45
- data/lib/sorare/rewards/version.rb +1 -1
- data/sorare-rewards.gemspec +1 -1
- metadata +6 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7fdc6ffec6880ea7d786427427f64c3a360eddf15fc6b9d1fc116e714ba14c28
|
4
|
+
data.tar.gz: d65afecddd570ddcce250d98142dfa0928a85759afc2ab2b6be01f80ab51ee99
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f1f39c17511050c7870261c524707001b48897d79d0ee1ab19fe699b8165202fce4345a62574d69132dfab3d81bf95000963af4b5318d4a8815b6c7b412e7d5d
|
7
|
+
data.tar.gz: d5a363cf277ecf27fa0f18a2ac3cb4e6f2eae071088985b53536b5ccbafb2761b1864678b250c996f6e79735bfee1407e646094fa9220e050656c02564bf2ef1
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,15 @@
|
|
1
|
+
## [1.6.0] - 2022-08-12
|
2
|
+
|
3
|
+
### Added
|
4
|
+
|
5
|
+
- Expose `rarity_limit` and `cooldown_limit` on `GameWeekRewards`
|
6
|
+
|
7
|
+
## [1.5.0] - 2022-03-07
|
8
|
+
|
9
|
+
### Added
|
10
|
+
|
11
|
+
- Expose `CardPicker` as `picker_of(rarity, tier, **args)` on `League`. `args` can be used to toggle off `rarity_limit` and `cooldown_limit`
|
12
|
+
|
1
13
|
## [1.4.1] - 2021-12-14
|
2
14
|
|
3
15
|
### Fixes
|
data/Gemfile.lock
CHANGED
@@ -1,8 +1,8 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
sorare-rewards (1.
|
5
|
-
activesupport (
|
4
|
+
sorare-rewards (1.6.0)
|
5
|
+
activesupport (>= 6.1.4)
|
6
6
|
interactor_with_steroids (>= 1.0.0)
|
7
7
|
json (~> 2)
|
8
8
|
yaml (~> 0.2.0)
|
@@ -10,12 +10,11 @@ PATH
|
|
10
10
|
GEM
|
11
11
|
remote: https://rubygems.org/
|
12
12
|
specs:
|
13
|
-
activesupport (
|
13
|
+
activesupport (7.0.2.2)
|
14
14
|
concurrent-ruby (~> 1.0, >= 1.0.2)
|
15
15
|
i18n (>= 1.6, < 2)
|
16
16
|
minitest (>= 5.1)
|
17
17
|
tzinfo (~> 2.0)
|
18
|
-
zeitwerk (~> 2.3)
|
19
18
|
addressable (2.8.0)
|
20
19
|
public_suffix (>= 2.0.2, < 5.0)
|
21
20
|
ast (2.4.2)
|
@@ -24,7 +23,7 @@ GEM
|
|
24
23
|
rexml
|
25
24
|
diff-lcs (1.4.4)
|
26
25
|
hashdiff (1.0.1)
|
27
|
-
i18n (1.
|
26
|
+
i18n (1.10.0)
|
28
27
|
concurrent-ruby (~> 1.0)
|
29
28
|
interactor_with_steroids (1.1.2)
|
30
29
|
activesupport
|
@@ -76,7 +75,6 @@ GEM
|
|
76
75
|
crack (>= 0.3.2)
|
77
76
|
hashdiff (>= 0.4.0, < 2.0.0)
|
78
77
|
yaml (0.2.0)
|
79
|
-
zeitwerk (2.5.3)
|
80
78
|
|
81
79
|
PLATFORMS
|
82
80
|
ruby
|
@@ -1,39 +1,48 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require '
|
3
|
+
require './lib/sorare/rewards/flat_picker'
|
4
4
|
|
5
5
|
module Sorare
|
6
6
|
module Rewards
|
7
|
-
# CardPicker allows to randomly pick a
|
8
|
-
class CardPicker
|
9
|
-
|
10
|
-
|
11
|
-
|
7
|
+
# CardPicker allows to randomly pick card rewards for a league
|
8
|
+
class CardPicker < FlatPicker
|
9
|
+
attr_reader :league, :rarity, :quality, :limits
|
10
|
+
|
11
|
+
def initialize(league, rarity, quality, rarity_limit: true, cooldown_limit: true)
|
12
|
+
super(league.public_seed, league.salt)
|
13
|
+
@league = league
|
14
|
+
@rarity = rarity
|
15
|
+
@quality = quality
|
16
|
+
@limits = %i[overall].tap do |l|
|
17
|
+
l << :cooldowned if cooldown_limit
|
18
|
+
l << :limited if rarity_limit
|
19
|
+
end
|
12
20
|
|
13
|
-
|
14
|
-
@random = Random.new(seed, salt)
|
15
|
-
@cards = []
|
16
|
-
@player_counter = Hash.new(0)
|
17
|
-
@shuffled = false
|
21
|
+
load_picker
|
18
22
|
end
|
19
23
|
|
20
|
-
def
|
21
|
-
|
24
|
+
def pick
|
25
|
+
player = super
|
26
|
+
return player if valid_pick?(player)
|
22
27
|
|
23
|
-
|
28
|
+
pick
|
24
29
|
end
|
25
30
|
|
26
|
-
def
|
27
|
-
|
31
|
+
def valid_pick?(player)
|
32
|
+
current_player_limit = limits.map { |l| supply_for(player).send(l) }.min
|
33
|
+
picked_count(player) <= current_player_limit
|
34
|
+
end
|
28
35
|
|
29
|
-
|
30
|
-
|
31
|
-
|
36
|
+
private
|
37
|
+
|
38
|
+
def supply_for(player_slug)
|
39
|
+
league.game_week.player(player_slug).supply_for(league, rarity)
|
32
40
|
end
|
33
41
|
|
34
|
-
def
|
35
|
-
|
36
|
-
|
42
|
+
def load_picker
|
43
|
+
league.qualified_supply(rarity, quality).each do |player_slug|
|
44
|
+
add(player_slug, supply_for(player_slug).overall)
|
45
|
+
end
|
37
46
|
end
|
38
47
|
end
|
39
48
|
end
|
@@ -11,7 +11,7 @@ module Sorare
|
|
11
11
|
|
12
12
|
def initialize
|
13
13
|
@tiers = 4
|
14
|
-
@gateway = 'https://
|
14
|
+
@gateway = 'https://sorare.mypinata.cloud/ipfs/'
|
15
15
|
@transform_tier = ->(tier) { "tier_#{tier}" }
|
16
16
|
@transform_division = ->(division) { "D#{division}" }
|
17
17
|
@allocation_configuration = load_yaml_configuration_file('allocation_configuration.yml')['leagues']
|
@@ -0,0 +1,56 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'active_support/core_ext/module/delegation'
|
4
|
+
|
5
|
+
module Sorare
|
6
|
+
module Rewards
|
7
|
+
# FlatPicker allows to randomly pick an element in a flat array
|
8
|
+
class FlatPicker
|
9
|
+
attr_accessor :elements, :counter
|
10
|
+
|
11
|
+
class NoSupplyError < StandardError; end
|
12
|
+
|
13
|
+
delegate :length, to: :elements
|
14
|
+
|
15
|
+
def initialize(seed, salt)
|
16
|
+
@random = Random.new(seed, salt)
|
17
|
+
@elements = []
|
18
|
+
@counter = Hash.new(0)
|
19
|
+
@shuffled = false
|
20
|
+
end
|
21
|
+
|
22
|
+
def add(slug, count)
|
23
|
+
raise "Can't add an element to a started draw" if @shuffled
|
24
|
+
|
25
|
+
@elements += Array.new(count, slug)
|
26
|
+
end
|
27
|
+
|
28
|
+
def pick
|
29
|
+
shuffle! unless @shuffled
|
30
|
+
|
31
|
+
@elements.shift.tap do |element|
|
32
|
+
@counter[element] += 1 if element
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def pick!
|
37
|
+
pick.tap do |picked|
|
38
|
+
raise NoSupplyError unless picked
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def picked_count(element)
|
43
|
+
@counter[element]
|
44
|
+
end
|
45
|
+
|
46
|
+
private
|
47
|
+
|
48
|
+
def shuffle!
|
49
|
+
return if @shuffled
|
50
|
+
|
51
|
+
@elements.shuffle!(random: @random)
|
52
|
+
@shuffled = true
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
@@ -56,6 +56,14 @@ module Sorare
|
|
56
56
|
def player(slug)
|
57
57
|
Player.new(slug, self)
|
58
58
|
end
|
59
|
+
|
60
|
+
def inspect
|
61
|
+
format('#<%<class>s %<data>s>', { class: self.class.name, data: { loaded: loaded?, hash: hash, salt: salt } })
|
62
|
+
end
|
63
|
+
|
64
|
+
def loaded?
|
65
|
+
data.present?
|
66
|
+
end
|
59
67
|
end
|
60
68
|
end
|
61
69
|
end
|
@@ -12,21 +12,25 @@ module Sorare
|
|
12
12
|
# }
|
13
13
|
# }
|
14
14
|
class GameWeekRewards
|
15
|
-
attr_reader :game_week, :salt, :card_allocations
|
15
|
+
attr_reader :game_week, :salt, :card_allocations, :rarity_limit, :cooldown_limit
|
16
16
|
|
17
17
|
MISSING_PARAMETER = '%s parameter required'
|
18
18
|
|
19
|
-
def initialize(game_week:, salt: nil, card_allocations: nil)
|
19
|
+
def initialize(game_week:, salt: nil, card_allocations: nil, rarity_limit: true, cooldown_limit: true)
|
20
20
|
@game_week = game_week
|
21
21
|
@salt = salt || game_week.salt
|
22
22
|
@card_allocations = card_allocations || computed_card_allocations
|
23
|
+
@rarity_limit = rarity_limit
|
24
|
+
@cooldown_limit = cooldown_limit
|
23
25
|
end
|
24
26
|
|
25
27
|
def cards
|
26
28
|
@cards ||= Sorare::Rewards::Pick.call!(
|
27
29
|
salt: salt,
|
28
30
|
game_week: game_week,
|
29
|
-
card_allocations: card_allocations
|
31
|
+
card_allocations: card_allocations,
|
32
|
+
rarity_limit: rarity_limit,
|
33
|
+
cooldown_limit: cooldown_limit
|
30
34
|
).cards_picked
|
31
35
|
end
|
32
36
|
|
@@ -7,13 +7,8 @@ require 'yaml'
|
|
7
7
|
module Sorare
|
8
8
|
module Rewards
|
9
9
|
module Cards
|
10
|
-
# PickForDivision picks the rewards for a given
|
11
|
-
#
|
12
|
-
# {
|
13
|
-
# 'rare' => { 'tier_0' => CardPicker, 'tier_1' => CardPicker },
|
14
|
-
# 'super_rare' => { 'tier_0' => CardPicker, 'tier_1' => CardPicker }
|
15
|
-
# }
|
16
|
-
# And a reward allocations
|
10
|
+
# PickForDivision picks the rewards for a given league
|
11
|
+
# And a division reward allocations
|
17
12
|
# {
|
18
13
|
# 'rare' => [5, 15, 0, 0],
|
19
14
|
# 'super_rare' => [1, 4, 0, 0],
|
@@ -21,8 +16,9 @@ module Sorare
|
|
21
16
|
# }
|
22
17
|
class PickForDivision
|
23
18
|
include Interactor
|
19
|
+
include WithPickerOptions
|
24
20
|
|
25
|
-
receive :league, :allocations
|
21
|
+
receive :league, :allocations
|
26
22
|
hold :cards_picked
|
27
23
|
|
28
24
|
def call
|
@@ -30,7 +26,6 @@ module Sorare
|
|
30
26
|
PickForDivisionAndRarity.call!(
|
31
27
|
**context.to_h,
|
32
28
|
rarity: rarity,
|
33
|
-
pickers: pickers[rarity],
|
34
29
|
allocations: allocations[rarity]
|
35
30
|
).cards_picked
|
36
31
|
end
|
@@ -7,17 +7,14 @@ module Sorare
|
|
7
7
|
module Rewards
|
8
8
|
module Cards
|
9
9
|
# PickForDivisionAndRarity picks the rewards for a given division and rarity
|
10
|
-
# Receive a list of pickers for each tiers
|
11
|
-
# {
|
12
|
-
# 'tier_0' => CardPicker, 'tier_1' => CardPicker
|
13
|
-
# }
|
14
10
|
# A game week data
|
15
11
|
# And a reward allocations
|
16
12
|
# { 'tier_0' => 1, 'tier_1' => 2 }
|
17
13
|
class PickForDivisionAndRarity
|
18
14
|
include Interactor
|
15
|
+
include WithPickerOptions
|
19
16
|
|
20
|
-
receive :league, :rarity, :allocations
|
17
|
+
receive :league, :rarity, :allocations
|
21
18
|
hold :cards_picked
|
22
19
|
|
23
20
|
def call
|
@@ -26,10 +23,12 @@ module Sorare
|
|
26
23
|
|
27
24
|
def supply!
|
28
25
|
allocations.keys.index_with do |tier|
|
29
|
-
|
26
|
+
picker = league.picker_of(rarity, tier, rarity_limit: rarity_limit, cooldown_limit: cooldown_limit)
|
27
|
+
next [] unless picker
|
30
28
|
|
31
|
-
PickForDivisionRarityAndQuality.call!(
|
32
|
-
|
29
|
+
PickForDivisionRarityAndQuality.call!(
|
30
|
+
**context.to_h, allocations: allocations[tier], picker: picker
|
31
|
+
).cards_picked
|
33
32
|
end
|
34
33
|
end
|
35
34
|
end
|
@@ -13,7 +13,7 @@ module Sorare
|
|
13
13
|
class PickForDivisionRarityAndQuality
|
14
14
|
include Interactor
|
15
15
|
|
16
|
-
MISSING_CARDS = 'There are not enough cards to fulfill the requirements'
|
16
|
+
MISSING_CARDS = 'There are not enough cards to fulfill the requirements for %<league>s %<rarity>s'
|
17
17
|
|
18
18
|
receive :picker, :allocations, :league, :rarity, force: false
|
19
19
|
hold :cards_picked
|
@@ -34,7 +34,7 @@ module Sorare
|
|
34
34
|
|
35
35
|
def pick_if_available!
|
36
36
|
player = picker.pick
|
37
|
-
return if picker.
|
37
|
+
return if picker.picked_count(player) > game_week.player(player).supply_for(league, rarity).available
|
38
38
|
|
39
39
|
cards_picked.push(player)
|
40
40
|
end
|
@@ -48,7 +48,7 @@ module Sorare
|
|
48
48
|
def check_length!
|
49
49
|
return if cards_picked.length == allocations
|
50
50
|
|
51
|
-
context.fail!(error: MISSING_CARDS)
|
51
|
+
context.fail!(error: format(MISSING_CARDS, { league: league, rarity: rarity }))
|
52
52
|
end
|
53
53
|
end
|
54
54
|
end
|
@@ -16,51 +16,21 @@ module Sorare
|
|
16
16
|
# }
|
17
17
|
class PickForLeague
|
18
18
|
include Interactor
|
19
|
+
include WithPickerOptions
|
19
20
|
|
20
21
|
receive :league, :allocations
|
21
|
-
hold :
|
22
|
+
hold :cards_picked
|
22
23
|
|
23
24
|
delegate :game_week, to: :league
|
24
25
|
delegate :public_seed, :salt, to: :game_week
|
25
26
|
|
26
27
|
def call
|
27
|
-
context.pickers = {}
|
28
|
-
add_pickers!
|
29
|
-
|
30
28
|
context.cards_picked = allocations.keys.index_with do |division|
|
31
29
|
PickForDivision.call!(
|
32
|
-
**context.to_h,
|
30
|
+
**context.to_h, allocations: allocations[division]
|
33
31
|
).cards_picked
|
34
32
|
end
|
35
33
|
end
|
36
|
-
|
37
|
-
def add_pickers!
|
38
|
-
league.supply.keys.index_with do |rarity|
|
39
|
-
pickers[rarity] = {}
|
40
|
-
qualify_and_add!(rarity)
|
41
|
-
end
|
42
|
-
end
|
43
|
-
|
44
|
-
def qualify_and_add!(rarity)
|
45
|
-
sorted_supply = league.supply[rarity]
|
46
|
-
qualified_players = Tiers::QualifyPlayers.call!(sorted_supply: sorted_supply).players
|
47
|
-
qualified_players.each_with_index.map do |players, tier|
|
48
|
-
transformed_tier = Sorare::Rewards.configuration.transform_tier.call(tier)
|
49
|
-
initialize_tier_picker(players, rarity, transformed_tier)
|
50
|
-
end
|
51
|
-
end
|
52
|
-
|
53
|
-
def initialize_tier_picker(players, rarity, tier)
|
54
|
-
pickers[rarity][tier] = CardPicker.new(public_seed, salt)
|
55
|
-
|
56
|
-
players.each do |slug, _|
|
57
|
-
pickers[rarity][tier].add_player(slug, player_supply(rarity, slug))
|
58
|
-
end
|
59
|
-
end
|
60
|
-
|
61
|
-
def player_supply(rarity, slug)
|
62
|
-
game_week.player(slug).overall_supply(league, rarity)
|
63
|
-
end
|
64
34
|
end
|
65
35
|
end
|
66
36
|
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'active_support/concern'
|
4
|
+
|
5
|
+
module Sorare
|
6
|
+
module Rewards
|
7
|
+
# WithPickerOptions is included by interactor that takes picker options as a parameter
|
8
|
+
module WithPickerOptions
|
9
|
+
extend ActiveSupport::Concern
|
10
|
+
|
11
|
+
included do
|
12
|
+
receive rarity_limit: true, cooldown_limit: true
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -55,11 +55,11 @@ module Sorare
|
|
55
55
|
end
|
56
56
|
|
57
57
|
def player_contribution(slug)
|
58
|
-
game_week.player(slug).
|
58
|
+
game_week.player(slug).supply_for(league, rarity).pool_contribution
|
59
59
|
end
|
60
60
|
|
61
61
|
def player_pickable_supply(slug)
|
62
|
-
game_week.player(slug).
|
62
|
+
game_week.player(slug).supply_for(league, rarity).available
|
63
63
|
end
|
64
64
|
|
65
65
|
def remaining_supply(reward_probability)
|
@@ -8,7 +8,7 @@ module Sorare
|
|
8
8
|
class League
|
9
9
|
attr_reader :name, :supply, :config, :game_week
|
10
10
|
|
11
|
-
delegate :salt, to: :game_week
|
11
|
+
delegate :salt, :public_seed, to: :game_week
|
12
12
|
|
13
13
|
def initialize(name:, config:, supply:, game_week:)
|
14
14
|
@name = name
|
@@ -54,16 +54,32 @@ module Sorare
|
|
54
54
|
end
|
55
55
|
|
56
56
|
def each_rarity_tier_supply
|
57
|
-
each_rarity_supply do |rarity,
|
58
|
-
qualified_supply
|
59
|
-
qualified_supply.each_key.map do |tier|
|
57
|
+
each_rarity_supply do |rarity, _|
|
58
|
+
qualified_supply(rarity).each do |tier, qualified_supply|
|
60
59
|
return to_enum(:each_rarity_tier_supply) unless block_given?
|
61
60
|
|
62
|
-
|
63
|
-
yield(rarity, transformed_tier, qualified_supply[tier])
|
61
|
+
yield(rarity, tier, qualified_supply)
|
64
62
|
end
|
65
63
|
end
|
66
64
|
end
|
65
|
+
|
66
|
+
def qualified_supply(rarity, tier = nil)
|
67
|
+
@qualified_supplies ||= {}
|
68
|
+
@qualified_supplies[rarity] ||= Tiers::QualifyPlayers.call!(sorted_supply: supply[rarity]).players
|
69
|
+
.each_with_index.to_h do |supply, supply_tier|
|
70
|
+
[Sorare::Rewards.configuration.transform_tier.call(supply_tier), supply]
|
71
|
+
end
|
72
|
+
tier ? @qualified_supplies[rarity][tier] : @qualified_supplies[rarity]
|
73
|
+
end
|
74
|
+
|
75
|
+
def picker_of(rarity, tier, **kwargs)
|
76
|
+
scenario = kwargs.sort.to_h.to_json
|
77
|
+
|
78
|
+
@pickers ||= {}
|
79
|
+
@pickers[rarity] ||= {}
|
80
|
+
@pickers[rarity][tier] ||= {}
|
81
|
+
@pickers[rarity][tier][scenario] ||= CardPicker.new(self, rarity, tier, **kwargs)
|
82
|
+
end
|
67
83
|
end
|
68
84
|
end
|
69
85
|
end
|
@@ -7,7 +7,21 @@ module Sorare
|
|
7
7
|
module Rewards
|
8
8
|
# Player stores the reward data of a player for a game week
|
9
9
|
class Player
|
10
|
-
attr_reader :slug
|
10
|
+
attr_reader :slug, :supply
|
11
|
+
|
12
|
+
Supply = Struct.new(:overall, :projected, :cooldowned, :limited, keyword_init: true) do
|
13
|
+
def initialize(overall: 0, projected: 0, cooldowned: 0, limited: 0)
|
14
|
+
super(overall: overall, projected: projected, cooldowned: cooldowned, limited: limited)
|
15
|
+
end
|
16
|
+
|
17
|
+
def pool_contribution
|
18
|
+
[projected, available].min || 0
|
19
|
+
end
|
20
|
+
|
21
|
+
def available
|
22
|
+
[overall, cooldowned, limited].min || 0
|
23
|
+
end
|
24
|
+
end
|
11
25
|
|
12
26
|
def initialize(slug, reward_data)
|
13
27
|
@slug = slug
|
@@ -17,45 +31,22 @@ module Sorare
|
|
17
31
|
load_supply(reward_data)
|
18
32
|
end
|
19
33
|
|
20
|
-
|
21
|
-
|
34
|
+
%w[remaining_games_for_supply remaining_games latest_rewarded].each do |key|
|
35
|
+
define_method(key) do
|
36
|
+
@game_data&.dig(key)
|
37
|
+
end
|
22
38
|
end
|
23
39
|
|
24
40
|
def playing?
|
25
41
|
@game_data.present?
|
26
42
|
end
|
27
43
|
|
28
|
-
def reward_pool_supply_contribution(league, rarity)
|
29
|
-
return 0 unless playing? && remaining_games_for_supply.positive?
|
30
|
-
|
31
|
-
[
|
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
|
40
|
-
available_during_cooldown(league, rarity), # Cooldown limit
|
41
|
-
@config.distribution_limit(rarity) # Hard limit
|
42
|
-
].min
|
43
|
-
end
|
44
|
-
|
45
44
|
def rank(league, rarity)
|
46
45
|
@supply.dig(league.name, rarity, 'rank')
|
47
46
|
end
|
48
47
|
|
49
|
-
def
|
50
|
-
|
51
|
-
end
|
52
|
-
|
53
|
-
def uncapped_supply_for_game_week(league, rarity)
|
54
|
-
overall_supply(league, rarity) / remaining_games_for_supply.to_f
|
55
|
-
end
|
56
|
-
|
57
|
-
def available_during_cooldown(league, rarity)
|
58
|
-
[@config.cooldown_limit(rarity) - rewarded_under_cooldown(league, rarity), 0].max
|
48
|
+
def supply_for(league, rarity)
|
49
|
+
supply.dig(league.name, rarity, 'supply') || Supply.new
|
59
50
|
end
|
60
51
|
|
61
52
|
def rewarded_under_cooldown(league, rarity)
|
@@ -64,28 +55,45 @@ module Sorare
|
|
64
55
|
end
|
65
56
|
end
|
66
57
|
|
67
|
-
|
68
|
-
return (@game_data&.dig(league.name, rarity) || []) if @config.cooldown_per_league?(rarity)
|
58
|
+
private
|
69
59
|
|
70
|
-
|
60
|
+
def load_supply(reward_data)
|
61
|
+
reward_data.each_league do |league|
|
62
|
+
league.each_rarity_supply do |rarity, league_supply|
|
63
|
+
next unless league_supply[slug]
|
64
|
+
|
65
|
+
player_cards = league_supply.dig(slug, 'supply') || 0
|
66
|
+
@supply[league.name][rarity] = {
|
67
|
+
**league_supply[slug],
|
68
|
+
supply: parse_supply(league, rarity, player_cards)
|
69
|
+
}.with_indifferent_access
|
70
|
+
end
|
71
|
+
end
|
71
72
|
end
|
72
73
|
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
74
|
+
def parse_supply(league, rarity, total_cards)
|
75
|
+
Supply.new(
|
76
|
+
overall: total_cards,
|
77
|
+
projected: projected_for_game_week(total_cards),
|
78
|
+
cooldowned: available_during_cooldown(league, rarity),
|
79
|
+
limited: @config.distribution_limit(rarity)
|
80
|
+
)
|
77
81
|
end
|
78
82
|
|
79
|
-
|
83
|
+
def projected_for_game_week(total_cards)
|
84
|
+
return 0 unless playing? && remaining_games_for_supply.positive?
|
80
85
|
|
81
|
-
|
82
|
-
|
83
|
-
league.each_rarity_supply do |rarity, supply|
|
84
|
-
next unless supply[slug]
|
86
|
+
total_cards / remaining_games_for_supply.to_f
|
87
|
+
end
|
85
88
|
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
+
def available_during_cooldown(league, rarity)
|
90
|
+
[@config.cooldown_limit(rarity) - rewarded_under_cooldown(league, rarity), 0].max
|
91
|
+
end
|
92
|
+
|
93
|
+
def rewarded(league, rarity)
|
94
|
+
return (@game_data&.dig(league.name, rarity) || []) if @config.cooldown_per_league?(rarity)
|
95
|
+
|
96
|
+
latest_rewarded&.dig(rarity) || []
|
89
97
|
end
|
90
98
|
end
|
91
99
|
end
|
data/sorare-rewards.gemspec
CHANGED
@@ -29,7 +29,7 @@ Gem::Specification.new do |spec|
|
|
29
29
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
30
30
|
spec.require_paths = ['lib']
|
31
31
|
|
32
|
-
spec.add_dependency 'activesupport', '
|
32
|
+
spec.add_dependency 'activesupport', '>= 6.1.4'
|
33
33
|
spec.add_dependency 'interactor_with_steroids', '>= 1.0.0'
|
34
34
|
spec.add_dependency 'json', '~> 2'
|
35
35
|
spec.add_dependency 'yaml', '~> 0.2.0'
|
metadata
CHANGED
@@ -1,27 +1,27 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: sorare-rewards
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.6.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Sorare team
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-
|
11
|
+
date: 2022-09-13 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- - "
|
17
|
+
- - ">="
|
18
18
|
- !ruby/object:Gem::Version
|
19
19
|
version: 6.1.4
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
|
-
- - "
|
24
|
+
- - ">="
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: 6.1.4
|
27
27
|
- !ruby/object:Gem::Dependency
|
@@ -174,6 +174,7 @@ files:
|
|
174
174
|
- lib/sorare/rewards/allocation_configuration.yml
|
175
175
|
- lib/sorare/rewards/card_picker.rb
|
176
176
|
- lib/sorare/rewards/configuration.rb
|
177
|
+
- lib/sorare/rewards/flat_picker.rb
|
177
178
|
- lib/sorare/rewards/game_week.rb
|
178
179
|
- lib/sorare/rewards/game_week_allocations.rb
|
179
180
|
- lib/sorare/rewards/game_week_config.rb
|
@@ -189,6 +190,7 @@ files:
|
|
189
190
|
- lib/sorare/rewards/interactors/cards/pick_for_division_rarity_and_quality.rb
|
190
191
|
- lib/sorare/rewards/interactors/cards/pick_for_game_week.rb
|
191
192
|
- lib/sorare/rewards/interactors/cards/pick_for_league.rb
|
193
|
+
- lib/sorare/rewards/interactors/concerns/with_picker_options.rb
|
192
194
|
- lib/sorare/rewards/interactors/pick.rb
|
193
195
|
- lib/sorare/rewards/interactors/prize_pools/compute_for_division.rb
|
194
196
|
- lib/sorare/rewards/interactors/prize_pools/compute_for_game_week.rb
|