qwtf_discord_bot 5.1.6 → 5.2.6
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 +4 -1
- 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 -5
- 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 +222 -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,158 +17,202 @@ 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
|
-
|
42
|
+
bot.command :teamsize do |event, *args|
|
43
|
+
setup_pug(event) do |e, pug|
|
44
|
+
return send_msg("Team size is #{pug.teamsize}", e.channel) unless args.any?
|
79
45
|
|
80
|
-
|
81
|
-
|
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
|
46
|
+
new_teamsize = args[0].to_i
|
47
|
+
return send_msg('Team size should be a number higher than 0', e.channel) unless new_teamsize > 0
|
86
48
|
|
87
|
-
|
49
|
+
if new_teamsize
|
50
|
+
pug.teamsize = new_teamsize
|
88
51
|
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
52
|
+
send_msg(
|
53
|
+
[
|
54
|
+
"Team size set to #{pug.teamsize}",
|
55
|
+
"#{pug.player_slots} joined"
|
56
|
+
].join(MSG_SNIPPET_DELIMITER),
|
57
|
+
e.channel
|
93
58
|
)
|
94
59
|
|
95
|
-
|
60
|
+
start_pug(pug, e) if pug.full?
|
61
|
+
else
|
62
|
+
send_msg(
|
63
|
+
[
|
64
|
+
"Current team size is #{pug.teamsize}",
|
65
|
+
"#{pug.player_slots} joined"
|
66
|
+
].join(MSG_SNIPPET_DELIMITER),
|
67
|
+
e.channel
|
68
|
+
)
|
96
69
|
end
|
97
70
|
end
|
98
71
|
end
|
99
72
|
|
100
73
|
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)
|
74
|
+
setup_pug(event) do |e, pug|
|
75
|
+
return send_msg(no_active_pug_message, e.channel) unless pug.active?
|
76
|
+
return send_msg("You're not in the PUG", e.channel) unless pug.joined?(e.user_id)
|
112
77
|
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
78
|
+
pug.leave(e.user_id)
|
79
|
+
|
80
|
+
snippets = [
|
81
|
+
"#{e.display_name} leaves the PUG",
|
82
|
+
"#{pug.player_slots} remain"
|
83
|
+
]
|
84
|
+
|
85
|
+
snippets << "#{pug.slots_left} more #{pug.notify_roles}" if pug.slots_left == 1
|
86
|
+
|
87
|
+
send_msg(
|
88
|
+
snippets.join(MSG_SNIPPET_DELIMITER),
|
89
|
+
e.channel
|
90
|
+
)
|
91
|
+
|
92
|
+
send_msg(end_pug_message, e.channel) unless pug.active?
|
118
93
|
end
|
119
94
|
end
|
120
95
|
|
121
96
|
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
|
97
|
+
setup_pug(event) do |e, pug|
|
98
|
+
return send_msg(no_active_pug_message, e.channel) unless pug.active?
|
127
99
|
|
128
|
-
|
129
|
-
|
130
|
-
|
100
|
+
args.each do |arg|
|
101
|
+
unless arg.match(/<@!\d+>/)
|
102
|
+
send_msg("#{arg} isn't a valid mention", e.channel)
|
103
|
+
next
|
104
|
+
end
|
131
105
|
|
132
|
-
|
133
|
-
|
134
|
-
send_and_log_message(message, e.channel)
|
135
|
-
else
|
136
|
-
pug.leave(user_id)
|
137
|
-
message = "#{display_name} is kicked from the PUG | #{pug.player_slots} remain"
|
138
|
-
send_and_log_message(message, e.channel)
|
106
|
+
user_id = arg[3..-2].to_i
|
107
|
+
display_name = e.display_name_for(user_id) || arg
|
139
108
|
|
140
|
-
|
141
|
-
|
142
|
-
|
109
|
+
unless pug.joined?(user_id)
|
110
|
+
send_msg("#{display_name} isn't in the PUG", e.channel)
|
111
|
+
next
|
143
112
|
end
|
113
|
+
|
114
|
+
pug.leave(user_id)
|
115
|
+
|
116
|
+
snippets = [
|
117
|
+
"#{display_name} is kicked from the PUG",
|
118
|
+
"#{pug.player_slots} remain"
|
119
|
+
]
|
120
|
+
|
121
|
+
snippets << "#{pug.slots_left} more #{pug.notify_roles}" if pug.slots_left == 1
|
122
|
+
|
123
|
+
send_msg(
|
124
|
+
snippets.join(MSG_SNIPPET_DELIMITER),
|
125
|
+
e.channel
|
126
|
+
)
|
127
|
+
|
128
|
+
break send_msg(end_pug_message, e.channel) unless pug.active?
|
144
129
|
end
|
145
130
|
end
|
146
131
|
end
|
147
132
|
|
133
|
+
bot.command :team do |event, *args|
|
134
|
+
setup_pug(event) do |e, pug|
|
135
|
+
team_no = args[0].to_i
|
136
|
+
return send_msg("Choose a team between 1 and 4", e.channel) unless team_no.between?(1, 4)
|
137
|
+
|
138
|
+
user_id = e.user_id
|
139
|
+
return send_msg("You're already in team #{team_no}", e.channel) if pug.team(team_no).include?(user_id)
|
140
|
+
|
141
|
+
join_pug(e, pug) unless pug.joined?(user_id)
|
142
|
+
pug.join_team(team_no: team_no, player_id: user_id)
|
143
|
+
|
144
|
+
send_msg(
|
145
|
+
[
|
146
|
+
"#{e.display_name} joins team #{team_no}",
|
147
|
+
"#{pug.team_player_count(team_no)}/#{pug.teamsize}"
|
148
|
+
].join(MSG_SNIPPET_DELIMITER), e.channel
|
149
|
+
)
|
150
|
+
|
151
|
+
start_pug(pug, e) if pug.full?
|
152
|
+
end
|
153
|
+
end
|
154
|
+
|
155
|
+
bot.command :unteam do |event, *args|
|
156
|
+
setup_pug(event) do |e, pug|
|
157
|
+
user_id = e.user_id
|
158
|
+
return send_msg('No PUG has been started. `!join` to create', e.channel) unless pug.active?
|
159
|
+
return send_msg("You aren't in this PUG", e.channel) unless pug.joined?(user_id)
|
160
|
+
return send_msg("You aren't in a team", e.channel) if pug.team(0).include?(user_id)
|
161
|
+
|
162
|
+
pug.join_team(team_no: 0, player_id: user_id)
|
163
|
+
send_msg("#{e.display_name} has no team", e.channel)
|
164
|
+
end
|
165
|
+
end
|
166
|
+
|
167
|
+
bot.command :win do |event, *args|
|
168
|
+
setup_pug(event) do |e, pug|
|
169
|
+
return send_msg(no_active_pug_message, e.channel) unless pug.active?
|
170
|
+
|
171
|
+
winning_team_no = args[0]
|
172
|
+
|
173
|
+
return send_msg("Not a valid team", e.channel) unless pug.team(winning_team_no).any?
|
174
|
+
|
175
|
+
pug.won_by(winning_team_no)
|
176
|
+
|
177
|
+
winning_team = pug.team(winning_team_no).map do |player_id|
|
178
|
+
e.display_name_for(player_id)
|
179
|
+
end
|
180
|
+
|
181
|
+
non_winning_teams = pug.actual_teams.tap { |team| team.delete(winning_team_no) }
|
182
|
+
|
183
|
+
losing_players = non_winning_teams.values.flatten.map do |player_id|
|
184
|
+
e.display_name_for(player_id)
|
185
|
+
end
|
186
|
+
|
187
|
+
send_msg(
|
188
|
+
"#{winning_team.join(', ')} defeat #{losing_players.join(', ')}",
|
189
|
+
e.channel
|
190
|
+
)
|
191
|
+
end
|
192
|
+
end
|
193
|
+
|
148
194
|
bot.command :end do |event, *args|
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
send_and_log_message(message, e.channel)
|
195
|
+
setup_pug(event) do |e, pug|
|
196
|
+
return send_msg(no_active_pug_message, e.channel) unless pug.active?
|
197
|
+
|
198
|
+
pug.end_pug
|
199
|
+
|
200
|
+
send_msg(end_pug_message, e.channel)
|
157
201
|
end
|
158
202
|
end
|
159
203
|
|
160
204
|
bot.command :notify do |event, *args|
|
161
|
-
|
205
|
+
setup_pug(event) do |e, pug|
|
162
206
|
roles = args.join(' ')
|
163
207
|
pug.notify_roles = roles
|
164
208
|
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
209
|
+
msg = if roles.empty?
|
210
|
+
'Notification removed'
|
211
|
+
else
|
212
|
+
"Notification role set to #{roles}"
|
213
|
+
end
|
170
214
|
|
171
|
-
|
215
|
+
send_msg(msg, e.channel)
|
172
216
|
end
|
173
217
|
end
|
174
218
|
|
@@ -177,26 +221,81 @@ class QwtfDiscordBotPug # :nodoc:
|
|
177
221
|
|
178
222
|
private
|
179
223
|
|
180
|
-
def
|
224
|
+
def join_pug(e, pug)
|
225
|
+
pug.join(e.user_id)
|
226
|
+
|
227
|
+
if pug.joined_player_count == 1
|
228
|
+
snippets = ["#{e.display_name} creates a PUG", pug.player_slots, pug.notify_roles]
|
229
|
+
else
|
230
|
+
snippets = ["#{e.display_name} joins the PUG", pug.player_slots]
|
231
|
+
snippets << "#{pug.slots_left} more #{pug.notify_roles}" if pug.slots_left.between?(1, 3)
|
232
|
+
end
|
233
|
+
|
234
|
+
send_msg(snippets.join(MSG_SNIPPET_DELIMITER), e.channel)
|
235
|
+
end
|
236
|
+
|
237
|
+
def setup_pug(event)
|
181
238
|
e = EventDecorator.new(event)
|
182
239
|
pug = Pug.for(e.channel_id)
|
183
240
|
yield(e, pug)
|
241
|
+
nil # stop discordrb printing return value
|
184
242
|
end
|
185
243
|
|
186
|
-
def start_pug(
|
187
|
-
|
244
|
+
def start_pug(pug, event)
|
245
|
+
pug_teams = pug.teams.map do |team_no, player_ids|
|
246
|
+
team_mentions = player_ids.map do |player_id|
|
247
|
+
event.mention_for(player_id)
|
248
|
+
end
|
249
|
+
|
250
|
+
team_status_line(
|
251
|
+
team_no: team_no.to_i,
|
252
|
+
names: team_mentions,
|
253
|
+
teamsize: pug.teamsize
|
254
|
+
)
|
255
|
+
end
|
256
|
+
|
257
|
+
msg = [
|
188
258
|
'Time to play!',
|
189
|
-
|
190
|
-
|
191
|
-
|
259
|
+
pug_teams
|
260
|
+
].join("\n")
|
261
|
+
|
262
|
+
send_msg(msg, event.channel)
|
192
263
|
end
|
193
264
|
|
194
|
-
def
|
195
|
-
pug.
|
265
|
+
def pug_teams_message(pug, event)
|
266
|
+
pug.teams.map do |team_no, player_ids|
|
267
|
+
team_display_names = player_ids.map do |player_id|
|
268
|
+
event.display_name_for(player_id)
|
269
|
+
end
|
270
|
+
|
271
|
+
team_status_line(
|
272
|
+
team_no: team_no.to_i,
|
273
|
+
names: team_display_names,
|
274
|
+
teamsize: pug.teamsize
|
275
|
+
)
|
276
|
+
end
|
277
|
+
end
|
278
|
+
|
279
|
+
def team_status_line(team_no:, names:, teamsize:)
|
280
|
+
if team_no.to_i.zero?
|
281
|
+
["No team: #{names.join(', ')}"]
|
282
|
+
else
|
283
|
+
[
|
284
|
+
"Team #{team_no}: #{names.join(', ')}",
|
285
|
+
"#{names.count}/#{teamsize}"
|
286
|
+
].join(MSG_SNIPPET_DELIMITER)
|
287
|
+
end
|
288
|
+
end
|
289
|
+
|
290
|
+
def end_pug_message
|
196
291
|
'PUG ended'
|
197
292
|
end
|
198
293
|
|
199
|
-
def
|
294
|
+
def no_active_pug_message
|
295
|
+
"There's no active PUG"
|
296
|
+
end
|
297
|
+
|
298
|
+
def send_msg(message, channel)
|
200
299
|
channel.send_message(message) && puts(message)
|
201
300
|
end
|
202
301
|
end
|