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 +4 -4
- data/Gemfile.lock +1 -1
- data/README.md +21 -7
- data/lib/sorare/rewards/allocation_configuration.yml +32 -105
- data/lib/sorare/rewards/game_week.rb +18 -7
- data/lib/sorare/rewards/interactors/allocations/compute_for_league.rb +1 -1
- data/lib/sorare/rewards/interactors/allocations/compute_for_quality.rb +2 -2
- data/lib/sorare/rewards/interactors/cards/pick_for_division.rb +2 -2
- data/lib/sorare/rewards/interactors/cards/pick_for_division_and_rarity.rb +2 -2
- data/lib/sorare/rewards/interactors/cards/pick_for_division_rarity_and_quality.rb +7 -7
- data/lib/sorare/rewards/interactors/cards/pick_for_game_week.rb +3 -3
- data/lib/sorare/rewards/interactors/cards/pick_for_league.rb +5 -5
- data/lib/sorare/rewards/interactors/pick.rb +2 -2
- data/lib/sorare/rewards/interactors/prize_pools/compute_for_division.rb +1 -1
- data/lib/sorare/rewards/interactors/supply/compute_for_rarity.rb +1 -1
- data/lib/sorare/rewards/interactors/tiers/qualify_players.rb +4 -5
- data/lib/sorare/rewards/league.rb +1 -1
- data/lib/sorare/rewards/picker.rb +1 -2
- data/lib/sorare/rewards/player.rb +13 -4
- data/lib/sorare/rewards/version.rb +1 -1
- metadata +4 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8cc85589244de6f453ed70184da06e8c679ec19b4b2c5fe86ee1ea4936c2c402
|
4
|
+
data.tar.gz: 521385c5b0b1e917d7be61eaef02d2284c24082fb18eeec561f9da6160ea650f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4b998f1b6bca4cbb8ca9fc9fcab6b2d9f2f32b7f4384e4b736ec2dcd3b51b9e1e17d62daf7f85b715e21a060445abd5e495342a01bc725994847ca028a991733
|
7
|
+
data.tar.gz: fff45a44fc25d684adeb45985aac4fde3b876977feca1f9fd3b4f9cd7b3e60f82b3f3f0294df25cc28aead951ee16f0b287192d4bb44fb1cd823602067f3ac42
|
data/Gemfile.lock
CHANGED
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
|
-
|
21
|
+
|
22
|
+
First you need to load a game week
|
26
23
|
|
27
24
|
```ruby
|
28
|
-
Sorare::Rewards::
|
25
|
+
game_week = Sorare::Rewards::GameWeek.new(hash: 'QmbwCo1fuhRN1T2DyEQtETefsBH6yCj8h7VjMW5iGfT11Z', salt: 'dce0053984405687efcdf3d1a61ffa67')
|
29
26
|
```
|
30
27
|
|
31
|
-
|
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
|
-
-
|
4
|
-
-
|
5
|
-
-
|
6
|
-
-
|
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
|
-
-
|
9
|
-
-
|
10
|
-
-
|
11
|
-
-
|
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
|
-
-
|
14
|
-
-
|
15
|
-
-
|
16
|
-
-
|
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
|
-
-
|
19
|
-
-
|
20
|
-
-
|
21
|
-
-
|
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
|
-
-
|
26
|
-
-
|
27
|
-
-
|
28
|
-
-
|
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
|
-
-
|
31
|
-
-
|
32
|
-
-
|
33
|
-
-
|
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
|
-
-
|
36
|
-
-
|
37
|
-
-
|
38
|
-
-
|
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
|
-
-
|
41
|
-
-
|
42
|
-
-
|
43
|
-
-
|
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 :
|
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
|
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
|
51
|
+
def reward_allocations
|
41
52
|
raise 'Salt required' unless salt
|
42
53
|
|
43
|
-
@
|
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!(
|
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?('
|
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['
|
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.
|
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
|
-
).
|
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.
|
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]).
|
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, :
|
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.
|
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
|
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).
|
35
|
+
return if picker.player_counter[player] > game_week.player(player).pickable_supply(league, rarity)
|
36
36
|
|
37
|
-
|
37
|
+
cards_picked.push(player)
|
38
38
|
end
|
39
39
|
|
40
40
|
def reorder!
|
41
|
-
|
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
|
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.
|
25
|
+
context.cards_picked = pick!
|
26
26
|
end
|
27
27
|
|
28
|
-
def
|
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
|
-
).
|
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.
|
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
|
-
).
|
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(
|
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(
|
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.
|
27
|
+
context.cards_picked = Sorare::Rewards::Cards::PickForGameWeek.call!(
|
28
28
|
**context.to_h,
|
29
29
|
salt: salt,
|
30
30
|
allocations: transposed_allocations
|
31
|
-
).
|
31
|
+
).cards_picked
|
32
32
|
end
|
33
33
|
|
34
34
|
def transposed_allocations
|
@@ -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
|
-
|
22
|
-
|
23
|
-
|
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
|
@@ -25,11 +25,18 @@ module Sorare
|
|
25
25
|
@game_data.present?
|
26
26
|
end
|
27
27
|
|
28
|
-
def
|
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),
|
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
|
-
(
|
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[
|
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
|
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.
|
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-
|
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:
|
225
|
+
version: '0'
|
226
226
|
requirements: []
|
227
227
|
rubygems_version: 3.1.6
|
228
228
|
signing_key:
|