qwtf_discord_bot 5.1.5 → 5.2.5
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 +1 -1
- data/Gemfile.lock +1 -1
- data/README.md +6 -2
- data/VERSION +1 -1
- data/bin/bundle +24 -20
- data/bin/coderay +7 -7
- data/bin/console +0 -0
- data/bin/htmldiff +7 -7
- data/bin/ldiff +7 -7
- data/bin/pry +7 -7
- data/bin/qwtf_discord_bot +7 -7
- data/bin/restclient +7 -7
- data/bin/rspec +7 -7
- data/bin/thor +7 -7
- data/lib/endpoint.rb +1 -1
- data/lib/event_decorator.rb +8 -1
- data/lib/player.rb +2 -1
- data/lib/pug.rb +83 -24
- data/lib/qstat_request.rb +51 -49
- data/lib/qwtf_discord_bot.rb +1 -0
- data/lib/qwtf_discord_bot/config.rb +4 -4
- data/lib/qwtf_discord_bot/qwtf_discord_bot_pug.rb +221 -123
- data/lib/qwtf_discord_bot/qwtf_discord_bot_server.rb +0 -1
- data/lib/qwtf_discord_bot/qwtf_discord_bot_watcher.rb +1 -1
- data/lib/qwtf_discord_bot/version.rb +1 -1
- data/lib/team.rb +27 -24
- metadata +2 -2
data/lib/qstat_request.rb
CHANGED
@@ -23,12 +23,14 @@ class QstatRequest
|
|
23
23
|
|
24
24
|
def to_message
|
25
25
|
return server_summary if is_empty?
|
26
|
+
|
26
27
|
[server_summary, player_table].join("\n")
|
27
28
|
end
|
28
29
|
|
29
30
|
def server_summary
|
30
31
|
return "#{@endpoint} isn't responding" unless game_map
|
31
32
|
return "#{name} | #{@endpoint} | #{game_map} | #{numplayers}/#{maxplayers}" unless has_spectators?
|
33
|
+
|
32
34
|
"#{name} | #{@endpoint} | #{game_map} | #{numplayers}/#{maxplayers} players | #{numspectators}/#{maxspectators} spectators"
|
33
35
|
end
|
34
36
|
|
@@ -46,70 +48,70 @@ class QstatRequest
|
|
46
48
|
|
47
49
|
private
|
48
50
|
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
def teams
|
54
|
-
@teams ||= build_roster
|
55
|
-
end
|
51
|
+
def has_spectators?
|
52
|
+
numspectators && numspectators > 0
|
53
|
+
end
|
56
54
|
|
57
|
-
|
58
|
-
|
59
|
-
|
55
|
+
def teams
|
56
|
+
@teams ||= build_roster
|
57
|
+
end
|
60
58
|
|
61
|
-
|
62
|
-
|
63
|
-
|
59
|
+
def data
|
60
|
+
@data ||= JSON.parse(result).first
|
61
|
+
end
|
64
62
|
|
65
|
-
|
66
|
-
|
67
|
-
|
63
|
+
def execute
|
64
|
+
`qstat -json -P -qws #{@endpoint}`
|
65
|
+
end
|
68
66
|
|
69
|
-
|
70
|
-
|
71
|
-
|
67
|
+
def player_table
|
68
|
+
players.sort_by { |player| player.team.number }.map(&:to_row).join("\n")
|
69
|
+
end
|
72
70
|
|
73
|
-
|
74
|
-
|
75
|
-
|
71
|
+
def name
|
72
|
+
data['name']
|
73
|
+
end
|
76
74
|
|
77
|
-
|
78
|
-
|
79
|
-
|
75
|
+
def address
|
76
|
+
data['address']
|
77
|
+
end
|
80
78
|
|
81
|
-
|
82
|
-
|
83
|
-
|
79
|
+
def game_map
|
80
|
+
data['map']
|
81
|
+
end
|
84
82
|
|
85
|
-
|
86
|
-
|
87
|
-
|
83
|
+
def numplayers
|
84
|
+
data['numplayers']
|
85
|
+
end
|
88
86
|
|
89
|
-
|
90
|
-
|
91
|
-
|
87
|
+
def maxplayers
|
88
|
+
data['maxplayers']
|
89
|
+
end
|
92
90
|
|
93
|
-
|
94
|
-
|
95
|
-
|
91
|
+
def numspectators
|
92
|
+
data['numspectators']
|
93
|
+
end
|
96
94
|
|
97
|
-
|
98
|
-
|
95
|
+
def maxspectators
|
96
|
+
data['maxspectators']
|
97
|
+
end
|
99
98
|
|
100
|
-
|
99
|
+
def build_roster
|
100
|
+
return nil if is_empty?
|
101
101
|
|
102
|
-
|
103
|
-
player = Player.new(player_data)
|
104
|
-
roster.enroll(player)
|
105
|
-
end
|
102
|
+
roster = Roster.new
|
106
103
|
|
107
|
-
|
104
|
+
data['players'].map do |player_data|
|
105
|
+
player = Player.new(player_data)
|
106
|
+
roster.enroll(player)
|
108
107
|
end
|
109
108
|
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
109
|
+
roster.teams.sort_by { |team| team.number }
|
110
|
+
end
|
111
|
+
|
112
|
+
def players
|
113
|
+
data['players'].map do |player_data|
|
114
|
+
Player.new(player_data)
|
114
115
|
end
|
116
|
+
end
|
115
117
|
end
|
data/lib/qwtf_discord_bot.rb
CHANGED
@@ -21,6 +21,7 @@ module QwtfDiscordBot # :nodoc:
|
|
21
21
|
def self.config_file
|
22
22
|
return ENV['QWTF_DISCORD_BOT_CONFIG_FILE'] if ENV['QWTF_DISCORD_BOT_CONFIG_FILE']
|
23
23
|
return "#{Dir.pwd}/config.yaml" if FileTest.exist?("#{Dir.pwd}/config.yaml")
|
24
|
+
|
24
25
|
"#{Dir.home}/.config/qwtf_discord_bot/config.yaml"
|
25
26
|
end
|
26
27
|
|
@@ -6,20 +6,20 @@ class Config
|
|
6
6
|
end
|
7
7
|
|
8
8
|
def token
|
9
|
-
@token ||= @config[
|
9
|
+
@token ||= @config['token']
|
10
10
|
end
|
11
11
|
|
12
12
|
def client_id
|
13
|
-
@client_id ||= @config[
|
13
|
+
@client_id ||= @config['client_id']
|
14
14
|
end
|
15
15
|
|
16
16
|
def endpoints
|
17
|
-
@endpoints ||= @config[
|
17
|
+
@endpoints ||= @config['endpoints'].map do |endpoint|
|
18
18
|
Endpoint.new(endpoint)
|
19
19
|
end
|
20
20
|
end
|
21
21
|
|
22
22
|
def emojis
|
23
|
-
@emojis ||= @config[
|
23
|
+
@emojis ||= @config['emojis']
|
24
24
|
end
|
25
25
|
end
|
@@ -6,7 +6,7 @@ require 'event_decorator'
|
|
6
6
|
class QwtfDiscordBotPug # :nodoc:
|
7
7
|
include QwtfDiscordBot
|
8
8
|
|
9
|
-
|
9
|
+
MSG_SNIPPET_DELIMITER = ' · '
|
10
10
|
|
11
11
|
def run
|
12
12
|
bot = Discordrb::Commands::CommandBot.new(
|
@@ -17,157 +17,200 @@ class QwtfDiscordBotPug # :nodoc:
|
|
17
17
|
)
|
18
18
|
|
19
19
|
bot.command :join do |event, *args|
|
20
|
-
|
21
|
-
if pug.
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
pug.join(e.user_id)
|
26
|
-
|
27
|
-
message = if pug.joined_player_count == 1
|
28
|
-
[
|
29
|
-
"#{e.display_name} creates a PUG",
|
30
|
-
pug.player_slots,
|
31
|
-
pug.notify_roles
|
32
|
-
].join(' | ')
|
33
|
-
elsif pug.slots_left.between?(1,3)
|
34
|
-
[
|
35
|
-
"#{e.display_name} joins the PUG",
|
36
|
-
pug.player_slots,
|
37
|
-
"#{pug.slots_left} more",
|
38
|
-
pug.notify_roles
|
39
|
-
].join(' | ')
|
40
|
-
else
|
41
|
-
[
|
42
|
-
"#{e.display_name} joins the PUG",
|
43
|
-
pug.player_slots
|
44
|
-
].join(' | ')
|
45
|
-
end
|
46
|
-
|
47
|
-
send_and_log_message(message, e.channel)
|
48
|
-
|
49
|
-
if pug.full?
|
50
|
-
message = start_pug(
|
51
|
-
pug.player_slots,
|
52
|
-
e.mentions_for(pug.joined_players)
|
53
|
-
)
|
54
|
-
|
55
|
-
send_and_log_message(message, e.channel)
|
56
|
-
end
|
57
|
-
end
|
20
|
+
setup_pug(event) do |e, pug|
|
21
|
+
return send_msg("You've already joined", e.channel) if pug.joined?(e.user_id)
|
22
|
+
|
23
|
+
join_pug(e, pug)
|
24
|
+
start_pug(pug, e) if pug.full?
|
58
25
|
end
|
59
26
|
end
|
60
27
|
|
61
28
|
bot.command :status do |event, *args|
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
send_and_log_message(message, e.channel)
|
29
|
+
setup_pug(event) do |e, pug|
|
30
|
+
return send_msg('No PUG has been started. `!join` to create', e.channel) unless pug.active?
|
31
|
+
|
32
|
+
send_msg(
|
33
|
+
[
|
34
|
+
"#{pug.player_slots} joined",
|
35
|
+
pug_teams_message(pug, e).join("\n")
|
36
|
+
].join("\n"),
|
37
|
+
e.channel
|
38
|
+
)
|
73
39
|
end
|
74
40
|
end
|
75
41
|
|
76
|
-
bot.command :
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
message = if new_maxplayers
|
81
|
-
pug.maxplayers = new_maxplayers
|
82
|
-
"Max number of players set to #{pug.maxplayers} | #{pug.player_slots} joined"
|
83
|
-
else
|
84
|
-
"Current max number of players is #{pug.maxplayers} | #{pug.player_slots} joined"
|
85
|
-
end
|
42
|
+
bot.command :teamsize do |event, *args|
|
43
|
+
setup_pug(event) do |e, pug|
|
44
|
+
new_teamsize = args[0].to_i
|
45
|
+
return send_msg('Team size should be a number higher than 0', e.channel) unless new_teamsize > 0
|
86
46
|
|
87
|
-
|
47
|
+
if new_teamsize
|
48
|
+
pug.teamsize = new_teamsize
|
88
49
|
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
50
|
+
send_msg(
|
51
|
+
[
|
52
|
+
"Team size set to #{pug.teamsize}",
|
53
|
+
"#{pug.player_slots} joined"
|
54
|
+
].join(MSG_SNIPPET_DELIMITER),
|
55
|
+
e.channel
|
93
56
|
)
|
94
57
|
|
95
|
-
|
58
|
+
start_pug(pug, e) if pug.full?
|
59
|
+
else
|
60
|
+
send_msg(
|
61
|
+
[
|
62
|
+
"Current team size is #{pug.teamsize}",
|
63
|
+
"#{pug.player_slots} joined"
|
64
|
+
].join(MSG_SNIPPET_DELIMITER),
|
65
|
+
e.channel
|
66
|
+
)
|
96
67
|
end
|
97
68
|
end
|
98
69
|
end
|
99
70
|
|
100
71
|
bot.command :leave do |event, *args|
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
send_and_log_message(message, e.channel)
|
105
|
-
elsif !pug.joined_players.include?(e.user_id)
|
106
|
-
message = "You're not in the PUG"
|
107
|
-
send_and_log_message(message, e.channel)
|
108
|
-
else
|
109
|
-
pug.leave(e.user_id)
|
110
|
-
message = "#{e.display_name} leaves the PUG | #{pug.player_slots} remain"
|
111
|
-
send_and_log_message(message, e.channel)
|
72
|
+
setup_pug(event) do |e, pug|
|
73
|
+
return send_msg(no_active_pug_message, e.channel) unless pug.active?
|
74
|
+
return send_msg("You're not in the PUG", e.channel) unless pug.joined?(e.user_id)
|
112
75
|
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
76
|
+
pug.leave(e.user_id)
|
77
|
+
|
78
|
+
snippets = [
|
79
|
+
"#{e.display_name} leaves the PUG",
|
80
|
+
"#{pug.player_slots} remain"
|
81
|
+
]
|
82
|
+
|
83
|
+
snippets << "#{pug.slots_left} more #{pug.notify_roles}" if pug.slots_left == 1
|
84
|
+
|
85
|
+
send_msg(
|
86
|
+
snippets.join(MSG_SNIPPET_DELIMITER),
|
87
|
+
e.channel
|
88
|
+
)
|
89
|
+
|
90
|
+
send_msg(end_pug_message, e.channel) unless pug.active?
|
118
91
|
end
|
119
92
|
end
|
120
93
|
|
121
94
|
bot.command :kick do |event, *args|
|
122
|
-
|
123
|
-
|
124
|
-
message = "There's no active PUG"
|
125
|
-
return send_and_log_message(message, e.channel)
|
126
|
-
end
|
95
|
+
setup_pug(event) do |e, pug|
|
96
|
+
return send_msg(no_active_pug_message, e.channel) unless pug.active?
|
127
97
|
|
128
|
-
|
129
|
-
|
98
|
+
args.each do |arg|
|
99
|
+
unless arg.match(/<@!\d+>/)
|
100
|
+
send_msg("#{arg} isn't a valid mention", e.channel)
|
101
|
+
next
|
102
|
+
end
|
130
103
|
|
131
|
-
|
132
|
-
|
133
|
-
send_and_log_message(message, e.channel)
|
134
|
-
else
|
135
|
-
pug.leave(user_id)
|
136
|
-
message = "#{e.display_name} is kicked from the PUG | #{pug.player_slots} remain"
|
137
|
-
send_and_log_message(message, e.channel)
|
104
|
+
user_id = arg[3..-2].to_i
|
105
|
+
display_name = e.display_name_for(user_id) || arg
|
138
106
|
|
139
|
-
|
140
|
-
|
141
|
-
|
107
|
+
unless pug.joined?(user_id)
|
108
|
+
send_msg("#{display_name} isn't in the PUG", e.channel)
|
109
|
+
next
|
142
110
|
end
|
111
|
+
|
112
|
+
pug.leave(user_id)
|
113
|
+
|
114
|
+
snippets = [
|
115
|
+
"#{display_name} is kicked from the PUG",
|
116
|
+
"#{pug.player_slots} remain"
|
117
|
+
]
|
118
|
+
|
119
|
+
snippets << "#{pug.slots_left} more #{pug.notify_roles}" if pug.slots_left == 1
|
120
|
+
|
121
|
+
send_msg(
|
122
|
+
snippets.join(MSG_SNIPPET_DELIMITER),
|
123
|
+
e.channel
|
124
|
+
)
|
125
|
+
|
126
|
+
break send_msg(end_pug_message, e.channel) unless pug.active?
|
127
|
+
end
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
bot.command :team do |event, *args|
|
132
|
+
setup_pug(event) do |e, pug|
|
133
|
+
team_no = args[0].to_i
|
134
|
+
return send_msg("Choose a team between 1 and 4", e.channel) unless team_no.between?(1, 4)
|
135
|
+
|
136
|
+
user_id = e.user_id
|
137
|
+
return send_msg("You're already in team #{team_no}", e.channel) if pug.team(team_no).include?(user_id)
|
138
|
+
|
139
|
+
join_pug(e, pug) unless pug.joined?(user_id)
|
140
|
+
pug.join_team(team_no: team_no, player_id: user_id)
|
141
|
+
|
142
|
+
send_msg(
|
143
|
+
[
|
144
|
+
"#{e.display_name} joins team #{team_no}",
|
145
|
+
"#{pug.team_player_count(team_no)}/#{pug.teamsize}"
|
146
|
+
].join(MSG_SNIPPET_DELIMITER), e.channel
|
147
|
+
)
|
148
|
+
|
149
|
+
start_pug(pug, e) if pug.full?
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
153
|
+
bot.command :unteam do |event, *args|
|
154
|
+
setup_pug(event) do |e, pug|
|
155
|
+
user_id = e.user_id
|
156
|
+
return send_msg('No PUG has been started. `!join` to create', e.channel) unless pug.active?
|
157
|
+
return send_msg("You aren't in this PUG", e.channel) unless pug.joined?(user_id)
|
158
|
+
return send_msg("You aren't in a team", e.channel) if pug.team(0).include?(user_id)
|
159
|
+
|
160
|
+
pug.join_team(team_no: 0, player_id: user_id)
|
161
|
+
send_msg("#{e.display_name} has no team", e.channel)
|
162
|
+
end
|
163
|
+
end
|
164
|
+
|
165
|
+
bot.command :win do |event, *args|
|
166
|
+
setup_pug(event) do |e, pug|
|
167
|
+
return send_msg(no_active_pug_message, e.channel) unless pug.active?
|
168
|
+
|
169
|
+
winning_team_no = args[0]
|
170
|
+
|
171
|
+
return send_msg("Not a valid team", e.channel) unless pug.team(winning_team_no).any?
|
172
|
+
|
173
|
+
pug.won_by(winning_team_no)
|
174
|
+
|
175
|
+
winning_team = pug.team(winning_team_no).map do |player_id|
|
176
|
+
e.display_name_for(player_id)
|
143
177
|
end
|
178
|
+
|
179
|
+
non_winning_teams = pug.actual_teams.tap { |team| team.delete(winning_team_no) }
|
180
|
+
|
181
|
+
losing_players = non_winning_teams.values.flatten.map do |player_id|
|
182
|
+
e.display_name_for(player_id)
|
183
|
+
end
|
184
|
+
|
185
|
+
send_msg(
|
186
|
+
"#{winning_team.join(', ')} defeat #{losing_players.join(', ')}",
|
187
|
+
e.channel
|
188
|
+
)
|
144
189
|
end
|
145
190
|
end
|
146
191
|
|
147
192
|
bot.command :end do |event, *args|
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
send_and_log_message(message, e.channel)
|
193
|
+
setup_pug(event) do |e, pug|
|
194
|
+
return send_msg(no_active_pug_message, e.channel) unless pug.active?
|
195
|
+
|
196
|
+
pug.end_pug
|
197
|
+
|
198
|
+
send_msg(end_pug_message, e.channel)
|
156
199
|
end
|
157
200
|
end
|
158
201
|
|
159
202
|
bot.command :notify do |event, *args|
|
160
|
-
|
203
|
+
setup_pug(event) do |e, pug|
|
161
204
|
roles = args.join(' ')
|
162
205
|
pug.notify_roles = roles
|
163
206
|
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
207
|
+
msg = if roles.empty?
|
208
|
+
'Notification removed'
|
209
|
+
else
|
210
|
+
"Notification role set to #{roles}"
|
211
|
+
end
|
169
212
|
|
170
|
-
|
213
|
+
send_msg(msg, e.channel)
|
171
214
|
end
|
172
215
|
end
|
173
216
|
|
@@ -176,26 +219,81 @@ class QwtfDiscordBotPug # :nodoc:
|
|
176
219
|
|
177
220
|
private
|
178
221
|
|
179
|
-
def
|
222
|
+
def join_pug(e, pug)
|
223
|
+
pug.join(e.user_id)
|
224
|
+
|
225
|
+
if pug.joined_player_count == 1
|
226
|
+
snippets = ["#{e.display_name} creates a PUG", pug.player_slots, pug.notify_roles]
|
227
|
+
else
|
228
|
+
snippets = ["#{e.display_name} joins the PUG", pug.player_slots]
|
229
|
+
snippets << "#{pug.slots_left} more #{pug.notify_roles}" if pug.slots_left.between?(1, 3)
|
230
|
+
end
|
231
|
+
|
232
|
+
send_msg(snippets.join(MSG_SNIPPET_DELIMITER), e.channel)
|
233
|
+
end
|
234
|
+
|
235
|
+
def setup_pug(event)
|
180
236
|
e = EventDecorator.new(event)
|
181
237
|
pug = Pug.for(e.channel_id)
|
182
238
|
yield(e, pug)
|
239
|
+
nil # stop discordrb printing return value
|
183
240
|
end
|
184
241
|
|
185
|
-
def start_pug(
|
186
|
-
|
242
|
+
def start_pug(pug, event)
|
243
|
+
pug_teams = pug.teams.map do |team_no, player_ids|
|
244
|
+
team_mentions = player_ids.map do |player_id|
|
245
|
+
event.mention_for(player_id)
|
246
|
+
end
|
247
|
+
|
248
|
+
team_status_line(
|
249
|
+
team_no: team_no.to_i,
|
250
|
+
names: team_mentions,
|
251
|
+
teamsize: pug.teamsize
|
252
|
+
)
|
253
|
+
end
|
254
|
+
|
255
|
+
msg = [
|
187
256
|
'Time to play!',
|
188
|
-
|
189
|
-
|
190
|
-
|
257
|
+
pug_teams
|
258
|
+
].join("\n")
|
259
|
+
|
260
|
+
send_msg(msg, event.channel)
|
191
261
|
end
|
192
262
|
|
193
|
-
def
|
194
|
-
pug.
|
263
|
+
def pug_teams_message(pug, event)
|
264
|
+
pug.teams.map do |team_no, player_ids|
|
265
|
+
team_display_names = player_ids.map do |player_id|
|
266
|
+
event.display_name_for(player_id)
|
267
|
+
end
|
268
|
+
|
269
|
+
team_status_line(
|
270
|
+
team_no: team_no.to_i,
|
271
|
+
names: team_display_names,
|
272
|
+
teamsize: pug.teamsize
|
273
|
+
)
|
274
|
+
end
|
275
|
+
end
|
276
|
+
|
277
|
+
def team_status_line(team_no:, names:, teamsize:)
|
278
|
+
if team_no.to_i.zero?
|
279
|
+
["No team: #{names.join(', ')}"]
|
280
|
+
else
|
281
|
+
[
|
282
|
+
"Team #{team_no}: #{names.join(', ')}",
|
283
|
+
"#{names.count}/#{teamsize}"
|
284
|
+
].join(MSG_SNIPPET_DELIMITER)
|
285
|
+
end
|
286
|
+
end
|
287
|
+
|
288
|
+
def end_pug_message
|
195
289
|
'PUG ended'
|
196
290
|
end
|
197
291
|
|
198
|
-
def
|
292
|
+
def no_active_pug_message
|
293
|
+
"There's no active PUG"
|
294
|
+
end
|
295
|
+
|
296
|
+
def send_msg(message, channel)
|
199
297
|
channel.send_message(message) && puts(message)
|
200
298
|
end
|
201
299
|
end
|