qwtf_discord_bot 5.4.10 → 5.5.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/VERSION +1 -1
- data/docker-compose.yml +13 -0
- data/exe/qwtf_discord_bot +6 -0
- data/lib/dashboard.rb +42 -0
- data/lib/qstat_request.rb +49 -3
- data/lib/qwtf_discord_bot.rb +4 -3
- data/lib/qwtf_discord_bot/config.rb +5 -0
- data/lib/qwtf_discord_bot/qwtf_discord_bot_dashboard.rb +41 -0
- data/lib/qwtf_discord_bot/qwtf_discord_bot_pug.rb +58 -23
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b1d76ac11d350eb38fbb60579e3ce26d561066f17e1bcda29029791afd98d36f
|
4
|
+
data.tar.gz: 1e75a7c3cecf17134bd41e2a9370bce29f82260319cd4d78bd9e9638e1c8e3af
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d13de4098fde37b346b4a668befed0c59ba73cae7a7640b69356064d1446c081af3b0552ef651896bd4c08b2548882a1386508992f12022717e9519eb5317dd2
|
7
|
+
data.tar.gz: c0868734a288588818370904904a407789857c74164d4b4ef42e27bafc68724238dcd4235bd7c625d79f72949109eef08ead1f03e2dea5a9ab39472132d2e1be
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
5.
|
1
|
+
5.5.1
|
data/docker-compose.yml
CHANGED
@@ -39,3 +39,16 @@ services:
|
|
39
39
|
- type: bind
|
40
40
|
source: "/home/ubuntu/.config/qwtf_discord_bot/config.yaml"
|
41
41
|
target: /discord-bot/config.yaml
|
42
|
+
discord-dashboard-bot:
|
43
|
+
image: fortressone/discord-bot:latest
|
44
|
+
command: dashboard
|
45
|
+
restart: always
|
46
|
+
depends_on:
|
47
|
+
- redis
|
48
|
+
environment:
|
49
|
+
- REDIS_URL=redis://redis
|
50
|
+
- RATINGS_API_URL
|
51
|
+
volumes:
|
52
|
+
- type: bind
|
53
|
+
source: "/home/ubuntu/.config/qwtf_discord_bot/config.yaml"
|
54
|
+
target: /discord-bot/config.yaml
|
data/exe/qwtf_discord_bot
CHANGED
@@ -26,6 +26,12 @@ class QwtfDiscordBotExe < Thor
|
|
26
26
|
watcher_bot = QwtfDiscordBotWatcher.new
|
27
27
|
watcher_bot.run
|
28
28
|
end
|
29
|
+
|
30
|
+
desc 'dashboard', 'A live dashboard with active server information'
|
31
|
+
def dashboard
|
32
|
+
dashboard_bot = QwtfDiscordBotDashboard.new
|
33
|
+
dashboard_bot.run
|
34
|
+
end
|
29
35
|
end
|
30
36
|
|
31
37
|
QwtfDiscordBotExe.start
|
data/lib/dashboard.rb
ADDED
@@ -0,0 +1,42 @@
|
|
1
|
+
class Dashboard
|
2
|
+
def initialize(channel, bot)
|
3
|
+
@channel_id = channel["id"]
|
4
|
+
@endpoints = channel["endpoints"]
|
5
|
+
@bot = bot
|
6
|
+
@messages = {}
|
7
|
+
end
|
8
|
+
|
9
|
+
def update
|
10
|
+
@endpoints.each do |endpoint|
|
11
|
+
qstat_request = QstatRequest.new(endpoint)
|
12
|
+
|
13
|
+
if qstat_request.is_empty?
|
14
|
+
if @messages[endpoint]
|
15
|
+
@messages[endpoint].delete
|
16
|
+
@messages.delete(endpoint)
|
17
|
+
end
|
18
|
+
|
19
|
+
next
|
20
|
+
end
|
21
|
+
|
22
|
+
embed = qstat_request.to_full_embed
|
23
|
+
|
24
|
+
@messages[endpoint] = if @messages[endpoint]
|
25
|
+
@messages[endpoint].edit(nil, embed)
|
26
|
+
else
|
27
|
+
channel.send_embed(nil, embed)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
private
|
33
|
+
|
34
|
+
def channel
|
35
|
+
data = Discordrb::API::Channel.resolve(
|
36
|
+
"Bot #{QwtfDiscordBot.config.token}",
|
37
|
+
@channel_id
|
38
|
+
)
|
39
|
+
|
40
|
+
Discordrb::Channel.new(JSON.parse(data), @bot)
|
41
|
+
end
|
42
|
+
end
|
data/lib/qstat_request.rb
CHANGED
@@ -1,4 +1,6 @@
|
|
1
1
|
class QstatRequest
|
2
|
+
MSG_SNIPPET_DELIMITER = ' · '
|
3
|
+
|
2
4
|
attr_accessor :result
|
3
5
|
|
4
6
|
def initialize(endpoint)
|
@@ -21,6 +23,19 @@ class QstatRequest
|
|
21
23
|
embed
|
22
24
|
end
|
23
25
|
|
26
|
+
def to_full_embed
|
27
|
+
Discordrb::Webhooks::Embed.new.tap do |embed|
|
28
|
+
embed.add_field(
|
29
|
+
name: name,
|
30
|
+
value: embed_summary,
|
31
|
+
)
|
32
|
+
|
33
|
+
teams.each do |team|
|
34
|
+
embed.add_field(team.to_embed_field)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
24
39
|
def to_message
|
25
40
|
return server_summary if is_empty?
|
26
41
|
|
@@ -29,9 +44,40 @@ class QstatRequest
|
|
29
44
|
|
30
45
|
def server_summary
|
31
46
|
return "#{@endpoint} isn't responding" unless game_map
|
32
|
-
return "#{name} | #{@endpoint} | #{game_map} | #{numplayers}/#{maxplayers}" unless has_spectators?
|
33
47
|
|
34
|
-
|
48
|
+
if !has_spectators?
|
49
|
+
return [
|
50
|
+
name,
|
51
|
+
@endpoint,
|
52
|
+
game_map,
|
53
|
+
"#{numplayers}/#{maxplayers}"
|
54
|
+
].join(MSG_SNIPPET_DELIMITER)
|
55
|
+
end
|
56
|
+
|
57
|
+
[
|
58
|
+
name,
|
59
|
+
@endpoint,
|
60
|
+
game_map,
|
61
|
+
"#{numplayers}/#{maxplayers} players",
|
62
|
+
"#{numspectators}/#{maxspectators} spectators"
|
63
|
+
].join(MSG_SNIPPET_DELIMITER)
|
64
|
+
end
|
65
|
+
|
66
|
+
def embed_summary
|
67
|
+
if !has_spectators?
|
68
|
+
return [
|
69
|
+
@endpoint,
|
70
|
+
game_map,
|
71
|
+
"#{numplayers}/#{maxplayers}"
|
72
|
+
].join(MSG_SNIPPET_DELIMITER)
|
73
|
+
end
|
74
|
+
|
75
|
+
[
|
76
|
+
@endpoint,
|
77
|
+
game_map,
|
78
|
+
"#{numplayers}/#{maxplayers} players",
|
79
|
+
"#{numspectators}/#{maxspectators} spectators"
|
80
|
+
].join(MSG_SNIPPET_DELIMITER)
|
35
81
|
end
|
36
82
|
|
37
83
|
def is_empty?
|
@@ -97,7 +143,7 @@ class QstatRequest
|
|
97
143
|
end
|
98
144
|
|
99
145
|
def build_roster
|
100
|
-
return
|
146
|
+
return [] if is_empty?
|
101
147
|
|
102
148
|
roster = Roster.new
|
103
149
|
|
data/lib/qwtf_discord_bot.rb
CHANGED
@@ -1,11 +1,12 @@
|
|
1
|
+
require 'discordrb'
|
2
|
+
require 'yaml'
|
3
|
+
require 'redis'
|
1
4
|
require 'qwtf_discord_bot/version'
|
2
5
|
require 'qwtf_discord_bot/qwtf_discord_bot_server'
|
3
6
|
require 'qwtf_discord_bot/qwtf_discord_bot_pug'
|
4
7
|
require 'qwtf_discord_bot/qwtf_discord_bot_watcher'
|
8
|
+
require 'qwtf_discord_bot/qwtf_discord_bot_dashboard'
|
5
9
|
require 'qwtf_discord_bot/config'
|
6
|
-
require 'discordrb'
|
7
|
-
require 'yaml'
|
8
|
-
require 'redis'
|
9
10
|
|
10
11
|
require 'qstat_request'
|
11
12
|
require 'player'
|
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'endpoint'
|
2
|
+
require 'dashboard'
|
2
3
|
|
3
4
|
class Config
|
4
5
|
def initialize(config)
|
@@ -19,6 +20,10 @@ class Config
|
|
19
20
|
end
|
20
21
|
end
|
21
22
|
|
23
|
+
def dashboards
|
24
|
+
@dashboards ||= @config['dashboards']
|
25
|
+
end
|
26
|
+
|
22
27
|
def emojis
|
23
28
|
@emojis ||= @config['emojis']
|
24
29
|
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
class QwtfDiscordBotDashboard
|
2
|
+
THIRTY_SECONDS = 30
|
3
|
+
|
4
|
+
def run
|
5
|
+
bot = Discordrb::Commands::CommandBot.new(
|
6
|
+
token: QwtfDiscordBot.config.token,
|
7
|
+
client_id: QwtfDiscordBot.config.client_id,
|
8
|
+
help_command: false,
|
9
|
+
prefix: proc do |message|
|
10
|
+
match = /^\!(\w+)(.*)/.match(message.content)
|
11
|
+
if match
|
12
|
+
first = match[1]
|
13
|
+
rest = match[2]
|
14
|
+
# Return the modified string with the first word lowercase:
|
15
|
+
"#{first.downcase}#{rest}"
|
16
|
+
end
|
17
|
+
end
|
18
|
+
)
|
19
|
+
|
20
|
+
@dashboards ||= QwtfDiscordBot.config.dashboards.map do |channel|
|
21
|
+
Dashboard.new(channel, bot)
|
22
|
+
end
|
23
|
+
|
24
|
+
every(THIRTY_SECONDS) do
|
25
|
+
@dashboards.each do |dashboard|
|
26
|
+
dashboard.update
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
private
|
32
|
+
|
33
|
+
def every(n_seconds)
|
34
|
+
loop do
|
35
|
+
before = Time.now
|
36
|
+
yield
|
37
|
+
interval = n_seconds - (Time.now - before)
|
38
|
+
sleep(interval) if interval > 0
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -288,26 +288,47 @@ class QwtfDiscordBotPug # :nodoc:
|
|
288
288
|
)
|
289
289
|
end
|
290
290
|
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
|
291
|
+
if args.empty?
|
292
|
+
unless pug.joined?(user_id)
|
293
|
+
return send_embedded_message(
|
294
|
+
description: "You aren't in this PUG",
|
295
|
+
channel: e.channel
|
296
|
+
)
|
297
|
+
end
|
297
298
|
|
298
|
-
|
299
|
-
|
300
|
-
|
299
|
+
if pug.team(0).include?(user_id)
|
300
|
+
return send_embedded_message(
|
301
|
+
description: "You aren't in a team",
|
302
|
+
channel: e.channel
|
303
|
+
)
|
304
|
+
end
|
305
|
+
|
306
|
+
pug.join_team(team_no: 0, player_id: user_id)
|
307
|
+
|
308
|
+
send_embedded_message(
|
309
|
+
description: "#{e.display_name} leaves team",
|
301
310
|
channel: e.channel
|
302
311
|
)
|
303
|
-
|
312
|
+
else
|
313
|
+
args.each do |mention|
|
314
|
+
unless mention.match(/<@!\d+>/)
|
315
|
+
send_embedded_message(
|
316
|
+
description: "#{arg} isn't a valid mention",
|
317
|
+
channel: e.channel
|
318
|
+
)
|
319
|
+
next
|
320
|
+
end
|
304
321
|
|
305
|
-
|
322
|
+
user_id = mention_to_user_id(mention)
|
323
|
+
display_name = e.display_name_for(user_id) || arg
|
324
|
+
pug.join_team(team_no: 0, player_id: user_id)
|
306
325
|
|
307
|
-
|
308
|
-
|
309
|
-
|
310
|
-
|
326
|
+
send_embedded_message(
|
327
|
+
description: "#{display_name} leaves team",
|
328
|
+
channel: e.channel
|
329
|
+
)
|
330
|
+
end
|
331
|
+
end
|
311
332
|
end
|
312
333
|
end
|
313
334
|
|
@@ -320,6 +341,13 @@ class QwtfDiscordBotPug # :nodoc:
|
|
320
341
|
)
|
321
342
|
end
|
322
343
|
|
344
|
+
if !pug.full?
|
345
|
+
return send_embedded_message(
|
346
|
+
description: "Can't report unless PUG is full",
|
347
|
+
channel: event.channel
|
348
|
+
)
|
349
|
+
end
|
350
|
+
|
323
351
|
unless args.any?
|
324
352
|
return send_embedded_message(
|
325
353
|
description: "Specify winning team; e.g. `!win 1`",
|
@@ -352,7 +380,7 @@ class QwtfDiscordBotPug # :nodoc:
|
|
352
380
|
teams.merge({ name => { players: players, result: result } })
|
353
381
|
end
|
354
382
|
|
355
|
-
post_results(
|
383
|
+
id = post_results(
|
356
384
|
{
|
357
385
|
match: {
|
358
386
|
map: pug.game_map,
|
@@ -363,10 +391,10 @@ class QwtfDiscordBotPug # :nodoc:
|
|
363
391
|
}
|
364
392
|
}
|
365
393
|
}.to_json
|
366
|
-
)
|
394
|
+
).body
|
367
395
|
|
368
396
|
send_embedded_message(
|
369
|
-
description: "#{TEAM_NAMES[winning_team_no]} wins. [Ratings](http://ratings.fortressone.org)",
|
397
|
+
description: "#{TEAM_NAMES[winning_team_no]} wins game ##{id}. [Ratings](http://ratings.fortressone.org)",
|
370
398
|
channel: e.channel
|
371
399
|
)
|
372
400
|
end
|
@@ -381,6 +409,13 @@ class QwtfDiscordBotPug # :nodoc:
|
|
381
409
|
)
|
382
410
|
end
|
383
411
|
|
412
|
+
if !pug.full?
|
413
|
+
return send_embedded_message(
|
414
|
+
description: "Can't report unless PUG is full",
|
415
|
+
channel: event.channel
|
416
|
+
)
|
417
|
+
end
|
418
|
+
|
384
419
|
if pug.actual_teams.count < 2
|
385
420
|
return send_embedded_message(
|
386
421
|
description: "There must be at least two teams with players to submit a result",
|
@@ -396,7 +431,7 @@ class QwtfDiscordBotPug # :nodoc:
|
|
396
431
|
teams.merge({ name => { players: players, result: 0 } })
|
397
432
|
end
|
398
433
|
|
399
|
-
post_results(
|
434
|
+
id = post_results(
|
400
435
|
{
|
401
436
|
match: {
|
402
437
|
map: pug.game_map,
|
@@ -407,10 +442,10 @@ class QwtfDiscordBotPug # :nodoc:
|
|
407
442
|
}
|
408
443
|
}
|
409
444
|
}.to_json
|
410
|
-
)
|
445
|
+
).body
|
411
446
|
|
412
447
|
send_embedded_message(
|
413
|
-
description: "Match drawn. [Ratings](http://ratings.fortressone.org)",
|
448
|
+
description: "Match ##{id} drawn. [Ratings](http://ratings.fortressone.org)",
|
414
449
|
channel: e.channel
|
415
450
|
)
|
416
451
|
end
|
@@ -628,8 +663,8 @@ class QwtfDiscordBotPug # :nodoc:
|
|
628
663
|
|
629
664
|
def status(pug:, event:, message_obj: nil)
|
630
665
|
footer = [
|
631
|
-
pug.game_map,
|
632
|
-
"#{pug.player_slots} joined"
|
666
|
+
pug.game_map || "No map selected",
|
667
|
+
"#{pug.player_slots} joined",
|
633
668
|
].compact.join(MSG_SNIPPET_DELIMITER)
|
634
669
|
|
635
670
|
send_embedded_message(
|
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: 5.
|
4
|
+
version: 5.5.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Sheldon Johnson
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-
|
11
|
+
date: 2020-11-15 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: discordrb
|
@@ -102,6 +102,7 @@ files:
|
|
102
102
|
- emoji/red_soldier.png
|
103
103
|
- emoji/red_spy.png
|
104
104
|
- exe/qwtf_discord_bot
|
105
|
+
- lib/dashboard.rb
|
105
106
|
- lib/emoji.rb
|
106
107
|
- lib/endpoint.rb
|
107
108
|
- lib/event_decorator.rb
|
@@ -110,6 +111,7 @@ files:
|
|
110
111
|
- lib/qstat_request.rb
|
111
112
|
- lib/qwtf_discord_bot.rb
|
112
113
|
- lib/qwtf_discord_bot/config.rb
|
114
|
+
- lib/qwtf_discord_bot/qwtf_discord_bot_dashboard.rb
|
113
115
|
- lib/qwtf_discord_bot/qwtf_discord_bot_pug.rb
|
114
116
|
- lib/qwtf_discord_bot/qwtf_discord_bot_server.rb
|
115
117
|
- lib/qwtf_discord_bot/qwtf_discord_bot_watcher.rb
|