qwtf_discord_bot 6.0.2 → 6.1.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 3aa1a2ddb68ecfd49c3847bf33c895cdea6123f94357798113ff1a77a979c21d
4
- data.tar.gz: 3305bd05dc697bd054f694dcc8297ff4304cc346515a9fa21584a14b7c42b59b
3
+ metadata.gz: 6ac5cd6d9034e9742121d3a1f73e2b7b4dcfdd88f6d38ac4092857b1c73a1cb2
4
+ data.tar.gz: af41c6aa3d43e94a8e9834d087716df7f7913dea4e5366c416673ed995a53571
5
5
  SHA512:
6
- metadata.gz: 82f451732d151e209d4140a7b81295cf0f5ee7c5706494a27c73a06db2718f53b73b8aa0eb50a48d66c42eaeccf71e8e487c3da53284a1f785910df1b42f9b8c
7
- data.tar.gz: 628df776e5aa66cea1c0b4b33fb89420d643862af59d922788bb220cf7f0654bce2f4200809747caa08b85385f0ad8f576202442874d3056ce14548c7bee0050
6
+ metadata.gz: edc080da2401d91e932fe1a0afc338503e58773fafbaff1290827829e3c30006c529a9cc0f0d9ae0b460feb6d1ef440e12fd8cdebcda74fca941ffa6361c690d
7
+ data.tar.gz: 3864eddf20434aa1e22baf84848b76a871f51453eb95979b5738b275d9438252596eb3ab08c171caa2f2824d77dfcb5e26ef15cf5a9a4f83081b6b4c0f2031b6
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- qwtf_discord_bot (6.0.2)
4
+ qwtf_discord_bot (6.1.2)
5
5
  discordrb (= 3.4.0)
6
6
  redis (~> 4.2)
7
7
  thor (~> 1.1)
data/README.md CHANGED
@@ -140,6 +140,14 @@ Push:
140
140
  gem push qwtf_discord_bot-$(cat VERSION).gem
141
141
 
142
142
 
143
+ ## Develop
144
+
145
+ ```
146
+ bundle install
147
+ bundle exec bin/qwtf_discord_bot
148
+ ```
149
+
150
+
143
151
  ## Docker
144
152
 
145
153
  Run:
data/VERSION CHANGED
@@ -1 +1 @@
1
- 6.0.2
1
+ 6.1.2
data/lib/dashboard.rb CHANGED
@@ -4,7 +4,6 @@ class Dashboard
4
4
  @endpoints = dashboard_config["endpoints"]
5
5
  @messages = {}
6
6
 
7
-
8
7
  channel_name = dashboard_config["name"]
9
8
 
10
9
  old_dashboard_channel = @server.channels.find do |chan|
data/lib/pug.rb CHANGED
@@ -11,17 +11,28 @@ class Pug
11
11
  end
12
12
 
13
13
  def join(player_id)
14
- redis.setnx(pug_key, Time.now.to_i)
15
- redis.sadd(team_key(0), player_id)
14
+ timestamp = Time.now.to_i
15
+ redis.setnx(pug_key, timestamp)
16
+ redis.zadd(queue_key, timestamp, player_id, nx: true)
16
17
  end
17
18
 
18
19
  def join_team(team_no:, player_id:)
19
- redis.setnx(pug_key, Time.now.to_i)
20
- leave_teams(player_id)
20
+ join(player_id)
21
+ unteam(player_id)
21
22
  redis.sadd(team_key(team_no), player_id)
22
23
  end
23
24
 
24
- def joined_players
25
+ def up_now_players
26
+ players[0, maxplayers]
27
+ end
28
+
29
+ def destroy_teams
30
+ teamed_players.each do |player_id|
31
+ unteam(player_id)
32
+ end
33
+ end
34
+
35
+ def teamed_players
25
36
  teams_keys.inject([]) do |players, team|
26
37
  players + redis.smembers(team).map(&:to_i)
27
38
  end
@@ -55,16 +66,24 @@ class Pug
55
66
  redis.set(teamsize_key, teamsize)
56
67
  end
57
68
 
69
+ def total_player_count
70
+ players.count
71
+ end
72
+
58
73
  def full?
59
- joined_player_count >= maxplayers
74
+ total_player_count >= maxplayers
75
+ end
76
+
77
+ def has_exactly_maxplayers?
78
+ total_player_count == maxplayers
60
79
  end
61
80
 
62
81
  def empty?
63
- joined_player_count.zero?
82
+ total_player_count.zero?
64
83
  end
65
84
 
66
- def joined_player_count
67
- joined_players.count
85
+ def teamed_player_count
86
+ teamed_players.count
68
87
  end
69
88
 
70
89
  def team_player_count(team_no)
@@ -72,11 +91,11 @@ class Pug
72
91
  end
73
92
 
74
93
  def player_slots
75
- "#{joined_player_count}/#{maxplayers}"
94
+ "#{total_player_count}/#{maxplayers}"
76
95
  end
77
96
 
78
97
  def slots_left
79
- maxplayers - joined_player_count
98
+ maxplayers - total_player_count
80
99
  end
81
100
 
82
101
  def game_map=(map)
@@ -104,7 +123,8 @@ class Pug
104
123
  end
105
124
 
106
125
  def leave(player_id)
107
- leave_teams(player_id)
126
+ leave_queue(player_id)
127
+ unteam(player_id)
108
128
  end
109
129
 
110
130
  def end_pug
@@ -114,13 +134,17 @@ class Pug
114
134
  end
115
135
 
116
136
  def joined?(player_id)
117
- joined_players.include?(player_id)
137
+ redis.zrank(queue_key, player_id)
118
138
  end
119
139
 
120
140
  def maxplayers
121
141
  teamsize * no_of_teams
122
142
  end
123
143
 
144
+ def queued_players
145
+ players - teamed_players
146
+ end
147
+
124
148
  def teams
125
149
  all_teams = teams_keys.inject({}) do |teams, team|
126
150
  teams.merge({ team.split(':').last.to_i => redis.smembers(team).map(&:to_i) })
@@ -129,16 +153,6 @@ class Pug
129
153
  all_teams.sort.to_h
130
154
  end
131
155
 
132
- def actual_teams
133
- teams.tap { |team| team.delete(0) }
134
- end
135
-
136
- def unteam_all_players
137
- joined_players.each do |player_id|
138
- join_team(team_no: 0, player_id: player_id)
139
- end
140
- end
141
-
142
156
  def update_last_result_time
143
157
  redis.set(last_result_time_key, Time.now.to_i)
144
158
  end
@@ -148,25 +162,37 @@ class Pug
148
162
  end
149
163
 
150
164
  def equal_number_of_players_on_each_team?
151
- team_player_counts = actual_teams.map do |_name, players|
165
+ team_player_counts = teams.map do |_name, players|
152
166
  players.size
153
167
  end
154
168
 
155
169
  team_player_counts.uniq.size == 1
156
170
  end
157
171
 
158
- private
159
-
160
- def leave_teams(player_id)
172
+ def unteam(player_id)
161
173
  teams_keys.each do |team|
162
174
  redis.srem(team, player_id)
163
175
  end
164
176
  end
165
177
 
178
+ def players
179
+ redis.zrange(queue_key, 0, -1).map(&:to_i)
180
+ end
181
+
182
+ private
183
+
184
+ def leave_queue(player_id)
185
+ redis.zrem(queue_key, player_id)
186
+ end
187
+
166
188
  def teams_keys
167
189
  redis.keys([pug_key, 'teams:*'].join(':'))
168
190
  end
169
191
 
192
+ def queue_key
193
+ [pug_key, 'queue'].join(':')
194
+ end
195
+
170
196
  def team_key(team_no)
171
197
  [pug_key, 'teams', team_no].join(':')
172
198
  end
@@ -208,6 +234,6 @@ class Pug
208
234
  end
209
235
 
210
236
  def no_of_teams
211
- [actual_teams.count, MIN_NO_OF_TEAMS].max
237
+ [teams.count, MIN_NO_OF_TEAMS].max
212
238
  end
213
239
  end
data/lib/qstat_request.rb CHANGED
@@ -11,28 +11,26 @@ class QstatRequest
11
11
  @result ||= execute
12
12
  end
13
13
 
14
- def to_embed
15
- return nil if is_empty?
16
-
17
- embed = Discordrb::Webhooks::Embed.new
18
-
19
- teams.each do |team|
20
- embed << team.to_embed_field
21
- end
22
-
23
- embed
24
- end
25
-
26
14
  def to_full_embed
27
15
  Discordrb::Webhooks::Embed.new.tap do |embed|
28
16
  embed.add_field(
29
17
  name: name,
30
- value: embed_summary,
18
+ value: join_link,
31
19
  )
32
20
 
33
21
  teams.each do |team|
34
22
  embed << team.to_embed_field
35
23
  end
24
+
25
+ footer = [game_map, "#{numplayers}/#{maxplayers} players"]
26
+
27
+ if has_spectators?
28
+ footer << "#{numspectators}/#{maxspectators} spectators"
29
+ end
30
+
31
+ embed.footer = Discordrb::Webhooks::EmbedFooter.new(
32
+ text: footer.join(MSG_SNIPPET_DELIMITER)
33
+ )
36
34
  end
37
35
  end
38
36
 
@@ -43,9 +41,7 @@ class QstatRequest
43
41
  end
44
42
 
45
43
  def server_summary
46
- return "#{@endpoint} isn't responding" unless game_map
47
-
48
- info = [name, @endpoint, game_map]
44
+ info = [name, game_map]
49
45
 
50
46
  info += if !has_spectators?
51
47
  ["#{numplayers}/#{maxplayers}"]
@@ -56,28 +52,13 @@ class QstatRequest
56
52
  ]
57
53
  end
58
54
 
55
+ info << join_link
56
+
59
57
  info.join(MSG_SNIPPET_DELIMITER)
60
58
  end
61
59
 
62
60
  def join_link
63
- "[Join](http://phobos.baseq.fr:9999/join?url=#{@endpoint})"
64
- end
65
-
66
- def embed_summary
67
- info = [@endpoint, game_map]
68
-
69
- info += if !has_spectators?
70
- ["#{numplayers}/#{maxplayers}"]
71
- else
72
- [
73
- "#{numplayers}/#{maxplayers} players",
74
- "#{numspectators}/#{maxspectators} spectators"
75
- ]
76
- end
77
-
78
- info << join_link
79
-
80
- info.join(MSG_SNIPPET_DELIMITER)
61
+ "<qw://#{@endpoint}>"
81
62
  end
82
63
 
83
64
  def is_empty?
@@ -92,6 +73,10 @@ class QstatRequest
92
73
  numplayers && numplayers > 0
93
74
  end
94
75
 
76
+ def live_server?
77
+ !game_map.nil?
78
+ end
79
+
95
80
  private
96
81
 
97
82
  def has_spectators?
@@ -40,22 +40,15 @@ class QwtfDiscordBotPug # :nodoc:
40
40
  end
41
41
 
42
42
  join_pug(e, pug)
43
- start_pug(pug, e) if pug.full?
43
+ start_pug(pug, e) if pug.has_exactly_maxplayers?
44
44
  end
45
45
  end
46
46
 
47
47
  bot.command :choose do |event, *args|
48
48
  setup_pug(event) do |e, pug|
49
- if pug.joined_players.count > pug.maxplayers
50
- return send_embedded_message(
51
- description: "Too many players, increase `!teamsize` or `!kick` extras",
52
- channel: event.channel
53
- )
54
- end
55
-
56
- if pug.joined_players.count.odd?
49
+ if !pug.full?
57
50
  return send_embedded_message(
58
- description: "Can't choose teams with odd number of players",
51
+ description: "Not enough players, reduce !teamsize",
59
52
  channel: event.channel
60
53
  )
61
54
  end
@@ -73,7 +66,6 @@ class QwtfDiscordBotPug # :nodoc:
73
66
  0
74
67
  end
75
68
 
76
-
77
69
  message_obj = choose_fair_teams(pug: pug, event: e, iteration: iteration)
78
70
  status(pug: pug, event: e, message_obj: message_obj) if message_obj
79
71
  end
@@ -258,13 +250,6 @@ class QwtfDiscordBotPug # :nodoc:
258
250
  )
259
251
  else
260
252
  args[1..-1].each do |mention|
261
- if pug.team(team_no).size >= pug.teamsize
262
- return send_embedded_message(
263
- description: "Team is full",
264
- channel: e.channel
265
- )
266
- end
267
-
268
253
  unless mention.match(/<@!\d+>/)
269
254
  send_embedded_message(
270
255
  description: "#{arg} isn't a valid mention",
@@ -287,7 +272,7 @@ class QwtfDiscordBotPug # :nodoc:
287
272
  end
288
273
  end
289
274
 
290
- start_pug(pug, e) if !pug_already_full && pug.full?
275
+ start_pug(pug, e) if !pug_already_full && pug.has_exactly_maxplayers?
291
276
  end
292
277
  end
293
278
 
@@ -310,14 +295,14 @@ class QwtfDiscordBotPug # :nodoc:
310
295
  )
311
296
  end
312
297
 
313
- if pug.team(0).include?(user_id)
298
+ if !pug.teamed_players.include?(user_id)
314
299
  return send_embedded_message(
315
300
  description: "You aren't in a team",
316
301
  channel: e.channel
317
302
  )
318
303
  end
319
304
 
320
- pug.join_team(team_no: 0, player_id: user_id)
305
+ pug.unteam(user_id)
321
306
 
322
307
  send_embedded_message(
323
308
  description: "#{e.display_name} leaves team",
@@ -335,7 +320,7 @@ class QwtfDiscordBotPug # :nodoc:
335
320
 
336
321
  user_id = mention_to_user_id(mention)
337
322
  display_name = e.display_name_for(user_id) || arg
338
- pug.join_team(team_no: 0, player_id: user_id)
323
+ pug.unteam(user_id)
339
324
 
340
325
  send_embedded_message(
341
326
  description: "#{display_name} leaves team",
@@ -392,14 +377,14 @@ class QwtfDiscordBotPug # :nodoc:
392
377
 
393
378
  winning_team_no = args.first.to_i
394
379
 
395
- if pug.actual_teams.count < 2
380
+ if pug.teams.count < 2
396
381
  return send_embedded_message(
397
382
  description: "There must be at least two teams with players to submit a result",
398
383
  channel: e.channel
399
384
  )
400
385
  end
401
386
 
402
- team_results = pug.actual_teams.inject({}) do |teams, (name, player_ids)|
387
+ team_results = pug.teams.inject({}) do |teams, (name, player_ids)|
403
388
  players = player_ids.inject({}) do |memo, id|
404
389
  memo.merge({ id => e.display_name_for(id) })
405
390
  end
@@ -452,7 +437,7 @@ class QwtfDiscordBotPug # :nodoc:
452
437
  )
453
438
  end
454
439
 
455
- if pug.actual_teams.count < 2
440
+ if pug.teams.count < 2
456
441
  return send_embedded_message(
457
442
  description: "There must be at least two teams with players to submit a result",
458
443
  channel: e.channel
@@ -468,7 +453,7 @@ class QwtfDiscordBotPug # :nodoc:
468
453
  )
469
454
  end
470
455
 
471
- team_results = pug.actual_teams.inject({}) do |teams, (name, player_ids)|
456
+ team_results = pug.teams.inject({}) do |teams, (name, player_ids)|
472
457
  players = player_ids.inject({}) do |memo, id|
473
458
  memo.merge({ id => e.display_name_for(id) })
474
459
  end
@@ -652,7 +637,7 @@ class QwtfDiscordBotPug # :nodoc:
652
637
  def join_pug(e, pug)
653
638
  pug.join(e.user_id)
654
639
 
655
- if pug.joined_player_count == 1
640
+ if pug.total_player_count == 1
656
641
  snippets = ["#{e.display_name} creates a PUG", "#{pug.player_slots} joined"]
657
642
  message = pug.notify_roles
658
643
  else
@@ -677,7 +662,7 @@ class QwtfDiscordBotPug # :nodoc:
677
662
  def choose_fair_teams(pug:, event:, iteration: 0)
678
663
  if !pug.full?
679
664
  return send_embedded_message(
680
- description: "Can't choose teams until PUG is full",
665
+ description: "Not enough players, reduce !teamsize",
681
666
  channel: event.channel
682
667
  ) && nil
683
668
  end
@@ -688,7 +673,7 @@ class QwtfDiscordBotPug # :nodoc:
688
673
  )
689
674
 
690
675
  combinations = get_fair_teams(
691
- channel_id: event.channel.id, players: pug.joined_players
676
+ channel_id: event.channel.id, players: pug.up_now_players
692
677
  )
693
678
 
694
679
  teams = combinations[iteration]
@@ -701,6 +686,8 @@ class QwtfDiscordBotPug # :nodoc:
701
686
  ) && nil
702
687
  end
703
688
 
689
+ pug.destroy_teams
690
+
704
691
  teams.each do |team_no, player_ids|
705
692
  player_ids.each do |player_id|
706
693
  pug.join_team(team_no: team_no, player_id: player_id)
@@ -725,6 +712,18 @@ class QwtfDiscordBotPug # :nodoc:
725
712
  text: footer
726
713
  )
727
714
 
715
+ if pug.queued_players.any?
716
+ queue_display_names = pug.queued_players.map do |player_id|
717
+ event.display_name_for(player_id)
718
+ end
719
+
720
+ embed.add_field(
721
+ inline: true,
722
+ name: "Queue",
723
+ value: queue_display_names.join("\n")
724
+ )
725
+ end
726
+
728
727
  pug.teams.each do |team_no, player_ids|
729
728
  team_display_names = player_ids.map do |player_id|
730
729
  event.display_name_for(player_id)
@@ -740,14 +739,14 @@ class QwtfDiscordBotPug # :nodoc:
740
739
  end
741
740
 
742
741
  def start_pug(pug, event)
743
- choose_fair_teams(pug: pug, event: event) unless pug.actual_teams.any?
742
+ choose_fair_teams(pug: pug, event: event) unless pug.teams.any?
744
743
 
745
744
  footer = [
746
745
  pug.game_map,
747
746
  "#{pug.player_slots} joined",
748
747
  ].compact.join(MSG_SNIPPET_DELIMITER)
749
748
 
750
- mentions = pug.joined_players.map do |player_id|
749
+ mentions = pug.players.map do |player_id|
751
750
  event.mention_for(player_id)
752
751
  end
753
752
 
@@ -761,6 +760,18 @@ class QwtfDiscordBotPug # :nodoc:
761
760
  text: footer
762
761
  )
763
762
 
763
+ if pug.queued_players.any?
764
+ queue_display_names = pug.queued_players.map do |player_id|
765
+ event.display_name_for(player_id)
766
+ end
767
+
768
+ embed.add_field(
769
+ inline: true,
770
+ name: "Queue",
771
+ value: queue_display_names.join("\n")
772
+ )
773
+ end
774
+
764
775
  pug.teams.each do |team_no, player_ids|
765
776
  team_mentions = player_ids.map do |player_id|
766
777
  event.display_name_for(player_id)
@@ -16,20 +16,17 @@ class QwtfDiscordBotServer
16
16
  message = 'Provide a server address e.g. `!server ' \
17
17
  'sydney.fortressone.org` or use `!active` or `!all`'
18
18
  event.channel.send_message(message)
19
- puts message
19
+
20
+ return puts message
21
+ end
22
+
23
+ endpoint = args.first
24
+ request = QstatRequest.new(endpoint)
25
+
26
+ if !request.live_server?
27
+ event.channel.send_message("#{endpoint} isn't responding")
20
28
  else
21
- endpoint = args.first
22
- qstat_response = QstatRequest.new(endpoint)
23
- message = qstat_response.server_summary
24
- embed = qstat_response.to_embed
25
-
26
- if embed
27
- event.channel.send_embed(message, embed)
28
- puts message
29
- else
30
- event.channel.send_message(message)
31
- puts message
32
- end
29
+ event.channel.send_embed(nil, request.to_full_embed)
33
30
  end
34
31
  end
35
32
 
@@ -43,20 +40,16 @@ class QwtfDiscordBotServer
43
40
  if endpoints_for_this_channel.empty?
44
41
  message = 'There are no servers associated with this channel'
45
42
  event.channel.send_message(message)
46
- puts message
47
- else
48
- endpoints_for_this_channel.each do |endpoint|
49
- qstat_request = QstatRequest.new(endpoint.address)
50
- message = qstat_request.server_summary
51
- embed = qstat_request.to_embed
52
-
53
- if embed
54
- event.channel.send_embed(message, embed)
55
- puts message
56
- else
57
- event.channel.send_message(message)
58
- puts message
59
- end
43
+ return puts message
44
+ end
45
+
46
+ endpoints_for_this_channel.each do |endpoint|
47
+ request = QstatRequest.new(endpoint.address)
48
+
49
+ if !request.live_server?
50
+ event.channel.send_message("#{endpoint} isn't responding")
51
+ else
52
+ event.channel.send_embed(nil, request.to_full_embed)
60
53
  end
61
54
  end
62
55
 
@@ -73,35 +66,27 @@ class QwtfDiscordBotServer
73
66
  if endpoints_for_this_channel.empty?
74
67
  message = 'There are no servers associated with this channel'
75
68
  event.channel.send_message(message)
76
- puts message
77
- else
78
- qstat_requests = endpoints_for_this_channel.map do |endpoint|
79
- QstatRequest.new(endpoint.address)
80
- end
69
+ return puts message
70
+ end
81
71
 
82
- servers_with_players = qstat_requests.reject do |server|
83
- server.is_empty?
84
- end
72
+ qstat_requests = endpoints_for_this_channel.map do |endpoint|
73
+ QstatRequest.new(endpoint.address)
74
+ end
85
75
 
86
- if servers_with_players.empty?
87
- message = "All ##{event.channel.name} servers are empty"
88
- event.channel.send_message(message)
89
- puts message
90
- else
91
- servers_with_players.each do |server|
92
- message = server.server_summary
93
- embed = server.to_embed
94
-
95
- if embed
96
- event.channel.send_embed(message, embed)
97
- puts message
98
- else
99
- event.channel.send_message(message)
100
- puts message
101
- end
102
- end
103
- end
76
+ servers_with_players = qstat_requests.reject do |server|
77
+ server.is_empty?
104
78
  end
79
+
80
+ if servers_with_players.empty?
81
+ message = "All ##{event.channel.name} servers are empty"
82
+ event.channel.send_message(message)
83
+ return puts message
84
+ end
85
+
86
+ servers_with_players.each do |server|
87
+ event.channel.send_embed(nil, server.to_full_embed)
88
+ end
89
+
105
90
  return nil
106
91
  end
107
92
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: qwtf_discord_bot
3
3
  version: !ruby/object:Gem::Version
4
- version: 6.0.2
4
+ version: 6.1.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sheldon Johnson
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2021-03-07 00:00:00.000000000 Z
11
+ date: 2021-06-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: discordrb
@@ -61,6 +61,7 @@ extensions: []
61
61
  extra_rdoc_files: []
62
62
  files:
63
63
  - ".dockerignore"
64
+ - ".env.example"
64
65
  - ".gitignore"
65
66
  - ".rspec"
66
67
  - ".travis.yml"