qwtf_discord_bot 6.0.3 → 6.1.3

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: 151d77adaf69b8f02ce8cba749eee97bdc6927956169d673d72917563bb07b91
4
- data.tar.gz: 781ddacc6d1f792df33553581cdc9a00f583872de3ed6f4581f2024fab7a83bd
3
+ metadata.gz: ef8bda609c0735d9ba3ba074c3f53a963c2d2cc7f933af4965ba9fb797b7d151
4
+ data.tar.gz: de760869c4380aa7d14ec16b7828655b1534c41aa3808a6c26d8f36a5694e7dd
5
5
  SHA512:
6
- metadata.gz: b034cd067bc60caaa168f175debfb55f607416a7b7a4efd37f9a0e00b49a693a9722d021989fd3518c8e56134ada4379c9273106fac0a0d8083d493f01d040ec
7
- data.tar.gz: 74436d2a147f42297fa21f7e20429c8e902bda52535089a6dd8f97ac452686d19ff78702ee413efc69c4f2e1248691456de78c84ba779e79819a04bb077d1363
6
+ metadata.gz: ec8f53ff7b12188bab9059db811c478b7010a105e7d37e626816da5d03003502030515e7ab918b521ec0d6dd7998c1a776be332d8a1fdc1fa2a8935df4fb272b
7
+ data.tar.gz: 4812904a6c1dd2824f08bd376239760c8506329438c26dae718ac809a123e6201547ad40f77de1bd3cab91781234022f6f914ba4f1abc21eba9c19c6f0e7999b
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.3)
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.3
1
+ 6.1.3
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
@@ -257,13 +250,6 @@ class QwtfDiscordBotPug # :nodoc:
257
250
  )
258
251
  else
259
252
  args[1..-1].each do |mention|
260
- if pug.team(team_no).size >= pug.teamsize
261
- return send_embedded_message(
262
- description: "Team is full",
263
- channel: e.channel
264
- )
265
- end
266
-
267
253
  unless mention.match(/<@!\d+>/)
268
254
  send_embedded_message(
269
255
  description: "#{arg} isn't a valid mention",
@@ -286,7 +272,7 @@ class QwtfDiscordBotPug # :nodoc:
286
272
  end
287
273
  end
288
274
 
289
- start_pug(pug, e) if !pug_already_full && pug.full?
275
+ start_pug(pug, e) if !pug_already_full && pug.has_exactly_maxplayers?
290
276
  end
291
277
  end
292
278
 
@@ -309,14 +295,14 @@ class QwtfDiscordBotPug # :nodoc:
309
295
  )
310
296
  end
311
297
 
312
- if pug.team(0).include?(user_id)
298
+ if !pug.teamed_players.include?(user_id)
313
299
  return send_embedded_message(
314
300
  description: "You aren't in a team",
315
301
  channel: e.channel
316
302
  )
317
303
  end
318
304
 
319
- pug.join_team(team_no: 0, player_id: user_id)
305
+ pug.unteam(user_id)
320
306
 
321
307
  send_embedded_message(
322
308
  description: "#{e.display_name} leaves team",
@@ -334,7 +320,15 @@ class QwtfDiscordBotPug # :nodoc:
334
320
 
335
321
  user_id = mention_to_user_id(mention)
336
322
  display_name = e.display_name_for(user_id) || arg
337
- pug.join_team(team_no: 0, player_id: user_id)
323
+
324
+ unless pug.joined?(user_id)
325
+ return send_embedded_message(
326
+ description: "#{display_name} isn't in this PUG",
327
+ channel: e.channel
328
+ )
329
+ end
330
+
331
+ pug.unteam(user_id)
338
332
 
339
333
  send_embedded_message(
340
334
  description: "#{display_name} leaves team",
@@ -391,14 +385,14 @@ class QwtfDiscordBotPug # :nodoc:
391
385
 
392
386
  winning_team_no = args.first.to_i
393
387
 
394
- if pug.actual_teams.count < 2
388
+ if pug.teams.count < 2
395
389
  return send_embedded_message(
396
390
  description: "There must be at least two teams with players to submit a result",
397
391
  channel: e.channel
398
392
  )
399
393
  end
400
394
 
401
- team_results = pug.actual_teams.inject({}) do |teams, (name, player_ids)|
395
+ team_results = pug.teams.inject({}) do |teams, (name, player_ids)|
402
396
  players = player_ids.inject({}) do |memo, id|
403
397
  memo.merge({ id => e.display_name_for(id) })
404
398
  end
@@ -451,7 +445,7 @@ class QwtfDiscordBotPug # :nodoc:
451
445
  )
452
446
  end
453
447
 
454
- if pug.actual_teams.count < 2
448
+ if pug.teams.count < 2
455
449
  return send_embedded_message(
456
450
  description: "There must be at least two teams with players to submit a result",
457
451
  channel: e.channel
@@ -467,7 +461,7 @@ class QwtfDiscordBotPug # :nodoc:
467
461
  )
468
462
  end
469
463
 
470
- team_results = pug.actual_teams.inject({}) do |teams, (name, player_ids)|
464
+ team_results = pug.teams.inject({}) do |teams, (name, player_ids)|
471
465
  players = player_ids.inject({}) do |memo, id|
472
466
  memo.merge({ id => e.display_name_for(id) })
473
467
  end
@@ -651,7 +645,7 @@ class QwtfDiscordBotPug # :nodoc:
651
645
  def join_pug(e, pug)
652
646
  pug.join(e.user_id)
653
647
 
654
- if pug.joined_player_count == 1
648
+ if pug.total_player_count == 1
655
649
  snippets = ["#{e.display_name} creates a PUG", "#{pug.player_slots} joined"]
656
650
  message = pug.notify_roles
657
651
  else
@@ -676,7 +670,7 @@ class QwtfDiscordBotPug # :nodoc:
676
670
  def choose_fair_teams(pug:, event:, iteration: 0)
677
671
  if !pug.full?
678
672
  return send_embedded_message(
679
- description: "Can't choose teams until PUG is full",
673
+ description: "Not enough players, reduce !teamsize",
680
674
  channel: event.channel
681
675
  ) && nil
682
676
  end
@@ -687,7 +681,7 @@ class QwtfDiscordBotPug # :nodoc:
687
681
  )
688
682
 
689
683
  combinations = get_fair_teams(
690
- channel_id: event.channel.id, players: pug.joined_players
684
+ channel_id: event.channel.id, players: pug.up_now_players
691
685
  )
692
686
 
693
687
  teams = combinations[iteration]
@@ -700,6 +694,8 @@ class QwtfDiscordBotPug # :nodoc:
700
694
  ) && nil
701
695
  end
702
696
 
697
+ pug.destroy_teams
698
+
703
699
  teams.each do |team_no, player_ids|
704
700
  player_ids.each do |player_id|
705
701
  pug.join_team(team_no: team_no, player_id: player_id)
@@ -724,6 +720,18 @@ class QwtfDiscordBotPug # :nodoc:
724
720
  text: footer
725
721
  )
726
722
 
723
+ if pug.queued_players.any?
724
+ queue_display_names = pug.queued_players.map do |player_id|
725
+ event.display_name_for(player_id)
726
+ end
727
+
728
+ embed.add_field(
729
+ inline: true,
730
+ name: "Queue",
731
+ value: queue_display_names.join("\n")
732
+ )
733
+ end
734
+
727
735
  pug.teams.each do |team_no, player_ids|
728
736
  team_display_names = player_ids.map do |player_id|
729
737
  event.display_name_for(player_id)
@@ -739,14 +747,14 @@ class QwtfDiscordBotPug # :nodoc:
739
747
  end
740
748
 
741
749
  def start_pug(pug, event)
742
- choose_fair_teams(pug: pug, event: event) unless pug.actual_teams.any?
750
+ choose_fair_teams(pug: pug, event: event) unless pug.teams.any?
743
751
 
744
752
  footer = [
745
753
  pug.game_map,
746
754
  "#{pug.player_slots} joined",
747
755
  ].compact.join(MSG_SNIPPET_DELIMITER)
748
756
 
749
- mentions = pug.joined_players.map do |player_id|
757
+ mentions = pug.players.map do |player_id|
750
758
  event.mention_for(player_id)
751
759
  end
752
760
 
@@ -760,6 +768,18 @@ class QwtfDiscordBotPug # :nodoc:
760
768
  text: footer
761
769
  )
762
770
 
771
+ if pug.queued_players.any?
772
+ queue_display_names = pug.queued_players.map do |player_id|
773
+ event.display_name_for(player_id)
774
+ end
775
+
776
+ embed.add_field(
777
+ inline: true,
778
+ name: "Queue",
779
+ value: queue_display_names.join("\n")
780
+ )
781
+ end
782
+
763
783
  pug.teams.each do |team_no, player_ids|
764
784
  team_mentions = player_ids.map do |player_id|
765
785
  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.3
4
+ version: 6.1.3
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-05-16 00:00:00.000000000 Z
11
+ date: 2021-06-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: discordrb