qwtf_discord_bot 5.1.8 → 5.3.0
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 +11 -3
- 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/docker-compose.yml +1 -0
- data/lib/endpoint.rb +1 -1
- data/lib/event_decorator.rb +12 -5
- data/lib/player.rb +2 -1
- data/lib/pug.rb +113 -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 +293 -88
- 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/pug.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
class Pug
|
2
|
-
|
2
|
+
DEFAULT_TEAMSIZE = 4
|
3
|
+
MIN_NO_OF_TEAMS = 2
|
3
4
|
|
4
5
|
def self.for(channel_id)
|
5
6
|
new(channel_id)
|
@@ -9,21 +10,65 @@ class Pug
|
|
9
10
|
@channel_id = channel_id
|
10
11
|
end
|
11
12
|
|
12
|
-
def join(
|
13
|
+
def join(player_id)
|
13
14
|
redis.setnx(pug_key, Time.now)
|
14
|
-
|
15
|
+
|
16
|
+
redis.sadd(team_key(0), player_id)
|
17
|
+
end
|
18
|
+
|
19
|
+
def join_team(team_no:, player_id:)
|
20
|
+
leave_teams(player_id)
|
21
|
+
redis.sadd(team_key(team_no), player_id)
|
15
22
|
end
|
16
23
|
|
17
24
|
def joined_players
|
18
|
-
|
25
|
+
teams_keys.inject([]) do |players, team|
|
26
|
+
players + redis.smembers(team).map(&:to_i)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def add_maps(maps)
|
31
|
+
redis.sadd(maps_key, maps)
|
32
|
+
end
|
33
|
+
|
34
|
+
def remove_maps(maps)
|
35
|
+
redis.srem(maps_key, maps)
|
36
|
+
end
|
37
|
+
|
38
|
+
def maps
|
39
|
+
redis.smembers(maps_key)
|
40
|
+
end
|
41
|
+
|
42
|
+
def vote(player_id:, map:)
|
43
|
+
redis.sadd(votes_key(map), player_id)
|
44
|
+
end
|
45
|
+
|
46
|
+
def vote_count(map)
|
47
|
+
redis.scard(votes_key(map)).to_i
|
48
|
+
end
|
49
|
+
|
50
|
+
def team(number)
|
51
|
+
redis.smembers(team_key(number)).map(&:to_i)
|
52
|
+
end
|
53
|
+
|
54
|
+
def teamsize=(teamsize)
|
55
|
+
redis.set(teamsize_key, teamsize)
|
19
56
|
end
|
20
57
|
|
21
58
|
def full?
|
22
59
|
joined_player_count >= maxplayers
|
23
60
|
end
|
24
61
|
|
62
|
+
def empty?
|
63
|
+
joined_player_count.zero?
|
64
|
+
end
|
65
|
+
|
25
66
|
def joined_player_count
|
26
|
-
|
67
|
+
joined_players.count
|
68
|
+
end
|
69
|
+
|
70
|
+
def team_player_count(team_no)
|
71
|
+
redis.scard(team_key(team_no)).to_i
|
27
72
|
end
|
28
73
|
|
29
74
|
def player_slots
|
@@ -34,20 +79,24 @@ class Pug
|
|
34
79
|
maxplayers - joined_player_count
|
35
80
|
end
|
36
81
|
|
82
|
+
def game_map=(map)
|
83
|
+
redis.set([pug_key, 'map'].join(':'), map)
|
84
|
+
end
|
85
|
+
|
86
|
+
def game_map
|
87
|
+
redis.get([pug_key, 'map'].join(':'))
|
88
|
+
end
|
89
|
+
|
37
90
|
def notify_roles=(roles)
|
38
91
|
redis.set(notify_roles_key, roles)
|
39
92
|
end
|
40
93
|
|
41
94
|
def notify_roles
|
42
|
-
redis.get(notify_roles_key) ||
|
43
|
-
end
|
44
|
-
|
45
|
-
def maxplayers=(maxplayers)
|
46
|
-
redis.set(maxplayers_key, maxplayers)
|
95
|
+
redis.get(notify_roles_key) || '@here'
|
47
96
|
end
|
48
97
|
|
49
|
-
def
|
50
|
-
(redis.get(
|
98
|
+
def teamsize
|
99
|
+
(redis.get(teamsize_key) || DEFAULT_TEAMSIZE).to_i
|
51
100
|
end
|
52
101
|
|
53
102
|
def active?
|
@@ -55,42 +104,82 @@ class Pug
|
|
55
104
|
end
|
56
105
|
|
57
106
|
def leave(player_id)
|
58
|
-
|
59
|
-
end_pug if empty?
|
107
|
+
leave_teams(player_id)
|
60
108
|
end
|
61
109
|
|
62
110
|
def end_pug
|
63
|
-
redis.
|
64
|
-
|
111
|
+
redis.keys([pug_key, "*"].join).each do |key|
|
112
|
+
redis.del(key)
|
113
|
+
end
|
65
114
|
end
|
66
115
|
|
67
116
|
def joined?(player_id)
|
68
117
|
joined_players.include?(player_id)
|
69
118
|
end
|
70
119
|
|
120
|
+
def maxplayers
|
121
|
+
teamsize * no_of_teams
|
122
|
+
end
|
123
|
+
|
124
|
+
def teams
|
125
|
+
teams_keys.inject({}) do |teams, team|
|
126
|
+
teams.merge({ team.split(':').last => redis.smembers(team).map(&:to_i) })
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
def actual_teams
|
131
|
+
teams.tap { |team| team.delete("0") }
|
132
|
+
end
|
133
|
+
|
71
134
|
private
|
72
135
|
|
73
|
-
def
|
74
|
-
|
136
|
+
def leave_teams(player_id)
|
137
|
+
teams_keys.each do |team|
|
138
|
+
redis.srem(team, player_id)
|
139
|
+
end
|
75
140
|
end
|
76
141
|
|
77
|
-
def
|
78
|
-
[pug_key,
|
142
|
+
def teams_keys
|
143
|
+
redis.keys([pug_key, 'teams:*'].join(':'))
|
79
144
|
end
|
80
145
|
|
81
|
-
def
|
82
|
-
[pug_key,
|
146
|
+
def team_key(team_no)
|
147
|
+
[pug_key, 'teams', team_no].join(':')
|
83
148
|
end
|
84
149
|
|
85
150
|
def pug_key
|
86
|
-
[
|
151
|
+
[channel_key, 'pug'].join(':')
|
152
|
+
end
|
153
|
+
|
154
|
+
def maps_key
|
155
|
+
[channel_key, 'maps'].join(':')
|
87
156
|
end
|
88
157
|
|
89
158
|
def notify_roles_key
|
90
|
-
[
|
159
|
+
[channel_key, 'role'].join(':')
|
160
|
+
end
|
161
|
+
|
162
|
+
def teamsize_key
|
163
|
+
[channel_key, 'teamsize'].join(':')
|
164
|
+
end
|
165
|
+
|
166
|
+
def votes_keys
|
167
|
+
redis.keys([pug_key, 'votes:*'].join(':'))
|
168
|
+
end
|
169
|
+
|
170
|
+
def votes_key(map)
|
171
|
+
[channel_key, 'votes', map].join(':')
|
172
|
+
end
|
173
|
+
|
174
|
+
def channel_key
|
175
|
+
['channel', @channel_id].join(':')
|
91
176
|
end
|
92
177
|
|
93
178
|
def redis
|
94
179
|
Redis.current
|
95
180
|
end
|
181
|
+
|
182
|
+
def no_of_teams
|
183
|
+
[actual_teams.count, MIN_NO_OF_TEAMS].max
|
184
|
+
end
|
96
185
|
end
|
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,6 +6,8 @@ require 'event_decorator'
|
|
6
6
|
class QwtfDiscordBotPug # :nodoc:
|
7
7
|
include QwtfDiscordBot
|
8
8
|
|
9
|
+
MSG_SNIPPET_DELIMITER = ' · '
|
10
|
+
|
9
11
|
def run
|
10
12
|
bot = Discordrb::Commands::CommandBot.new(
|
11
13
|
token: QwtfDiscordBot.config.token,
|
@@ -16,134 +18,272 @@ class QwtfDiscordBotPug # :nodoc:
|
|
16
18
|
|
17
19
|
bot.command :join do |event, *args|
|
18
20
|
setup_pug(event) do |e, pug|
|
19
|
-
return
|
20
|
-
|
21
|
-
pug.join(e.user_id)
|
22
|
-
|
23
|
-
message = if pug.joined_player_count == 1
|
24
|
-
[
|
25
|
-
"#{e.display_name} creates a PUG",
|
26
|
-
pug.player_slots,
|
27
|
-
pug.notify_roles
|
28
|
-
].join(' | ')
|
29
|
-
elsif pug.slots_left.between?(1, 3)
|
30
|
-
[
|
31
|
-
"#{e.display_name} joins the PUG",
|
32
|
-
pug.player_slots,
|
33
|
-
"#{pug.slots_left} more",
|
34
|
-
pug.notify_roles
|
35
|
-
].join(' | ')
|
36
|
-
else
|
37
|
-
[
|
38
|
-
"#{e.display_name} joins the PUG",
|
39
|
-
pug.player_slots
|
40
|
-
].join(' | ')
|
41
|
-
end
|
42
|
-
|
43
|
-
message(message, e.channel)
|
44
|
-
|
45
|
-
if pug.full?
|
46
|
-
message = start_pug_message(
|
47
|
-
player_slots: pug.player_slots,
|
48
|
-
mentions: e.mentions_for(pug.joined_players)
|
49
|
-
)
|
21
|
+
return send_msg("You've already joined", e.channel) if pug.joined?(e.user_id)
|
50
22
|
|
51
|
-
|
52
|
-
|
23
|
+
join_pug(e, pug)
|
24
|
+
start_pug(pug, e) if pug.full?
|
53
25
|
end
|
54
26
|
end
|
55
27
|
|
56
28
|
bot.command :status do |event, *args|
|
57
29
|
setup_pug(event) do |e, pug|
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
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
|
+
"Map: #{pug.game_map}",
|
36
|
+
pug_teams_message(pug, e).join("\n")
|
37
|
+
].join("\n"),
|
38
|
+
e.channel
|
39
|
+
)
|
68
40
|
end
|
69
41
|
end
|
70
42
|
|
71
|
-
bot.command :
|
43
|
+
bot.command :teamsize do |event, *args|
|
72
44
|
setup_pug(event) do |e, pug|
|
73
|
-
|
45
|
+
return send_msg("Team size is #{pug.teamsize}", e.channel) unless args.any?
|
74
46
|
|
75
|
-
|
76
|
-
|
77
|
-
"Max number of players set to #{pug.maxplayers} | #{pug.player_slots} joined"
|
78
|
-
else
|
79
|
-
"Current max number of players is #{pug.maxplayers} | #{pug.player_slots} joined"
|
80
|
-
end
|
47
|
+
new_teamsize = args[0].to_i
|
48
|
+
return send_msg('Team size should be a number higher than 0', e.channel) unless new_teamsize > 0
|
81
49
|
|
82
|
-
|
50
|
+
if new_teamsize
|
51
|
+
pug.teamsize = new_teamsize
|
83
52
|
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
53
|
+
send_msg(
|
54
|
+
[
|
55
|
+
"Team size set to #{pug.teamsize}",
|
56
|
+
"#{pug.player_slots} joined"
|
57
|
+
].join(MSG_SNIPPET_DELIMITER),
|
58
|
+
e.channel
|
88
59
|
)
|
89
60
|
|
90
|
-
|
61
|
+
start_pug(pug, e) if pug.full?
|
62
|
+
else
|
63
|
+
send_msg(
|
64
|
+
[
|
65
|
+
"Current team size is #{pug.teamsize}",
|
66
|
+
"#{pug.player_slots} joined"
|
67
|
+
].join(MSG_SNIPPET_DELIMITER),
|
68
|
+
e.channel
|
69
|
+
)
|
91
70
|
end
|
92
71
|
end
|
93
72
|
end
|
94
73
|
|
95
74
|
bot.command :leave do |event, *args|
|
96
75
|
setup_pug(event) do |e, pug|
|
97
|
-
return
|
98
|
-
return
|
76
|
+
return send_msg(no_active_pug_message, e.channel) unless pug.active?
|
77
|
+
return send_msg("You're not in the PUG", e.channel) unless pug.joined?(e.user_id)
|
99
78
|
|
100
79
|
pug.leave(e.user_id)
|
101
80
|
|
102
|
-
|
103
|
-
"#{e.display_name} leaves the PUG
|
81
|
+
snippets = [
|
82
|
+
"#{e.display_name} leaves the PUG",
|
83
|
+
"#{pug.player_slots} remain"
|
84
|
+
]
|
85
|
+
|
86
|
+
snippets << "#{pug.slots_left} more #{pug.notify_roles}" if pug.slots_left == 1
|
87
|
+
|
88
|
+
send_msg(
|
89
|
+
snippets.join(MSG_SNIPPET_DELIMITER),
|
104
90
|
e.channel
|
105
91
|
)
|
106
92
|
|
107
|
-
|
93
|
+
end_pug(pug, e.channel) if pug.empty?
|
108
94
|
end
|
109
95
|
end
|
110
96
|
|
111
97
|
bot.command :kick do |event, *args|
|
112
98
|
setup_pug(event) do |e, pug|
|
113
|
-
return
|
99
|
+
return send_msg("Kick who? e.g. `!kick @#{e.display_name}`", e.channel) unless args.any?
|
100
|
+
return send_msg(no_active_pug_message, e.channel) unless pug.active?
|
114
101
|
|
115
|
-
args.each do |
|
116
|
-
|
117
|
-
|
102
|
+
args.each do |arg|
|
103
|
+
unless arg.match(/<@!\d+>/)
|
104
|
+
send_msg("#{arg} isn't a valid mention", e.channel)
|
105
|
+
next
|
106
|
+
end
|
118
107
|
|
119
|
-
|
120
|
-
|
121
|
-
"#{display_name} isn't in the PUG",
|
122
|
-
e.channel
|
123
|
-
)
|
108
|
+
user_id = arg[3..-2].to_i
|
109
|
+
display_name = e.display_name_for(user_id) || arg
|
124
110
|
|
111
|
+
unless pug.joined?(user_id)
|
112
|
+
send_msg("#{display_name} isn't in the PUG", e.channel)
|
125
113
|
next
|
126
114
|
end
|
127
115
|
|
128
116
|
pug.leave(user_id)
|
129
117
|
|
130
|
-
|
131
|
-
"#{display_name} is kicked from the PUG
|
118
|
+
snippets = [
|
119
|
+
"#{display_name} is kicked from the PUG",
|
120
|
+
"#{pug.player_slots} remain"
|
121
|
+
]
|
122
|
+
|
123
|
+
snippets << "#{pug.slots_left} more #{pug.notify_roles}" if pug.slots_left == 1
|
124
|
+
|
125
|
+
send_msg(
|
126
|
+
snippets.join(MSG_SNIPPET_DELIMITER),
|
132
127
|
e.channel
|
133
128
|
)
|
134
129
|
|
135
|
-
break
|
130
|
+
break end_pug(pug, e.channel) if pug.empty?
|
131
|
+
end
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
bot.command :team do |event, *args|
|
136
|
+
setup_pug(event) do |e, pug|
|
137
|
+
team_no = args[0].to_i
|
138
|
+
return send_msg("Choose a team between 1 and 4", e.channel) unless team_no.between?(1, 4)
|
139
|
+
|
140
|
+
user_id = e.user_id
|
141
|
+
return send_msg("You're already in team #{team_no}", e.channel) if pug.team(team_no).include?(user_id)
|
142
|
+
|
143
|
+
join_pug(e, pug) unless pug.joined?(user_id)
|
144
|
+
pug.join_team(team_no: team_no, player_id: user_id)
|
145
|
+
|
146
|
+
send_msg(
|
147
|
+
[
|
148
|
+
"#{e.display_name} joins team #{team_no}",
|
149
|
+
"#{pug.team_player_count(team_no)}/#{pug.teamsize}"
|
150
|
+
].join(MSG_SNIPPET_DELIMITER), e.channel
|
151
|
+
)
|
152
|
+
|
153
|
+
start_pug(pug, e) if pug.full?
|
154
|
+
end
|
155
|
+
end
|
156
|
+
|
157
|
+
bot.command :unteam do |event, *args|
|
158
|
+
setup_pug(event) do |e, pug|
|
159
|
+
user_id = e.user_id
|
160
|
+
return send_msg('No PUG has been started. `!join` to create', e.channel) unless pug.active?
|
161
|
+
return send_msg("You aren't in this PUG", e.channel) unless pug.joined?(user_id)
|
162
|
+
return send_msg("You aren't in a team", e.channel) if pug.team(0).include?(user_id)
|
163
|
+
|
164
|
+
pug.join_team(team_no: 0, player_id: user_id)
|
165
|
+
send_msg("#{e.display_name} has no team", e.channel)
|
166
|
+
end
|
167
|
+
end
|
168
|
+
|
169
|
+
bot.command :win do |event, *args|
|
170
|
+
setup_pug(event) do |e, pug|
|
171
|
+
return send_msg(no_active_pug_message, e.channel) unless pug.active?
|
172
|
+
|
173
|
+
winning_team_no = args[0]
|
174
|
+
|
175
|
+
return send_msg("Not a valid team", e.channel) unless pug.team(winning_team_no).any?
|
176
|
+
|
177
|
+
players = pug.joined_players.inject({}) do |memo, id|
|
178
|
+
memo.merge({ id => e.display_name_for(id) })
|
179
|
+
end
|
180
|
+
|
181
|
+
team_results = pug.teams.inject({}) do |teams, (name, player_ids)|
|
182
|
+
result = winning_team_no.to_i == name.to_i ? 1 : -1
|
183
|
+
teams.merge({ name => { players: players, result: result } })
|
184
|
+
end
|
185
|
+
|
186
|
+
post_results(
|
187
|
+
{
|
188
|
+
match: {
|
189
|
+
map: pug.game_map,
|
190
|
+
teams: team_results
|
191
|
+
}
|
192
|
+
}.to_json
|
193
|
+
)
|
194
|
+
|
195
|
+
# winning_team = pug.team(winning_team_no).map do |player_id|
|
196
|
+
# e.display_name_for(player_id)
|
197
|
+
# end
|
198
|
+
|
199
|
+
# non_winning_teams = pug.actual_teams.tap { |team| team.delete(winning_team_no) }
|
200
|
+
|
201
|
+
# losing_players = non_winning_teams.values.flatten.map do |player_id|
|
202
|
+
# e.display_name_for(player_id)
|
203
|
+
# end
|
204
|
+
|
205
|
+
send_msg("Team #{winning_team_no} wins", e.channel)
|
206
|
+
end
|
207
|
+
end
|
208
|
+
|
209
|
+
bot.command :draw do |event, *args|
|
210
|
+
setup_pug(event) do |e, pug|
|
211
|
+
return send_msg(no_active_pug_message, e.channel) unless pug.active?
|
212
|
+
|
213
|
+
players = pug.joined_players.inject({}) do |memo, id|
|
214
|
+
memo.merge({ id => e.display_name_for(id) })
|
136
215
|
end
|
216
|
+
|
217
|
+
team_results = pug.teams.inject({}) do |teams, (name, player_ids)|
|
218
|
+
teams.merge({ name => { players: players, result: 0 } })
|
219
|
+
end
|
220
|
+
|
221
|
+
post_results(
|
222
|
+
{
|
223
|
+
match: {
|
224
|
+
map: pug.game_map,
|
225
|
+
teams: team_results
|
226
|
+
}
|
227
|
+
}.to_json
|
228
|
+
)
|
229
|
+
|
230
|
+
send_msg("Match drawn", e.channel)
|
137
231
|
end
|
138
232
|
end
|
139
233
|
|
140
234
|
bot.command :end do |event, *args|
|
141
235
|
setup_pug(event) do |e, pug|
|
142
|
-
return
|
236
|
+
return send_msg(no_active_pug_message, e.channel) unless pug.active?
|
237
|
+
|
238
|
+
end_pug(pug, e.channel)
|
239
|
+
end
|
240
|
+
end
|
143
241
|
|
144
|
-
|
242
|
+
bot.command :addmap do |event, *args|
|
243
|
+
setup_pug(event) do |e, pug|
|
244
|
+
maps = args
|
245
|
+
return send_msg("What map? e.g. `!addmap 2fort5r`", e.channel) unless maps.any?
|
145
246
|
|
146
|
-
|
247
|
+
pug.add_maps(maps)
|
248
|
+
send_msg("#{maps.join(', ')} added to maps", e.channel)
|
249
|
+
end
|
250
|
+
end
|
251
|
+
|
252
|
+
bot.command :removemap do |event, *args|
|
253
|
+
setup_pug(event) do |e, pug|
|
254
|
+
maps = args
|
255
|
+
return send_msg("What map? e.g. `!removemap 2fort5r`", e.channel) unless maps.any?
|
256
|
+
|
257
|
+
pug.remove_maps(maps)
|
258
|
+
send_msg("#{maps.join(', ')} removed from maps", e.channel)
|
259
|
+
end
|
260
|
+
end
|
261
|
+
|
262
|
+
bot.command :maps do |event, *args|
|
263
|
+
setup_pug(event) do |e, pug|
|
264
|
+
maps = pug.maps
|
265
|
+
return send_msg('No maps have been added. `!addmap`', e.channel) unless maps.any?
|
266
|
+
|
267
|
+
send_msg(maps.join(', '), e.channel)
|
268
|
+
end
|
269
|
+
end
|
270
|
+
|
271
|
+
bot.command :map do |event, *args|
|
272
|
+
setup_pug(event) do |e, pug|
|
273
|
+
maps = pug.maps
|
274
|
+
return send_msg('No maps have been added. `!addmap`', e.channel) unless maps.any?
|
275
|
+
return send_msg(no_active_pug_message, e.channel) unless pug.active?
|
276
|
+
|
277
|
+
if args.empty?
|
278
|
+
return send_msg('No map has been set for the current PUG', e.channel) unless pug.game_map
|
279
|
+
send_msg("Current map is #{pug.game_map}", e.channel)
|
280
|
+
else
|
281
|
+
game_map = args.first
|
282
|
+
return send_msg("#{game_map} isn't in the map list. `!addmap` to add it.", e.channel) unless maps.include?(game_map)
|
283
|
+
|
284
|
+
pug.game_map = game_map
|
285
|
+
send_msg("Map set to #{game_map}", e.channel)
|
286
|
+
end
|
147
287
|
end
|
148
288
|
end
|
149
289
|
|
@@ -152,13 +292,13 @@ class QwtfDiscordBotPug # :nodoc:
|
|
152
292
|
roles = args.join(' ')
|
153
293
|
pug.notify_roles = roles
|
154
294
|
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
295
|
+
msg = if roles.empty?
|
296
|
+
'Notification removed'
|
297
|
+
else
|
298
|
+
"Notification role set to #{roles}"
|
299
|
+
end
|
160
300
|
|
161
|
-
|
301
|
+
send_msg(msg, e.channel)
|
162
302
|
end
|
163
303
|
end
|
164
304
|
|
@@ -167,6 +307,19 @@ class QwtfDiscordBotPug # :nodoc:
|
|
167
307
|
|
168
308
|
private
|
169
309
|
|
310
|
+
def join_pug(e, pug)
|
311
|
+
pug.join(e.user_id)
|
312
|
+
|
313
|
+
if pug.joined_player_count == 1
|
314
|
+
snippets = ["#{e.display_name} creates a PUG", pug.player_slots, pug.notify_roles]
|
315
|
+
else
|
316
|
+
snippets = ["#{e.display_name} joins the PUG", pug.player_slots]
|
317
|
+
snippets << "#{pug.slots_left} more #{pug.notify_roles}" if pug.slots_left.between?(1, 3)
|
318
|
+
end
|
319
|
+
|
320
|
+
send_msg(snippets.join(MSG_SNIPPET_DELIMITER), e.channel)
|
321
|
+
end
|
322
|
+
|
170
323
|
def setup_pug(event)
|
171
324
|
e = EventDecorator.new(event)
|
172
325
|
pug = Pug.for(e.channel_id)
|
@@ -174,19 +327,71 @@ class QwtfDiscordBotPug # :nodoc:
|
|
174
327
|
nil # stop discordrb printing return value
|
175
328
|
end
|
176
329
|
|
177
|
-
def
|
178
|
-
|
330
|
+
def start_pug(pug, event)
|
331
|
+
pug_teams = pug.teams.map do |team_no, player_ids|
|
332
|
+
team_mentions = player_ids.map do |player_id|
|
333
|
+
event.mention_for(player_id)
|
334
|
+
end
|
335
|
+
|
336
|
+
team_status_line(
|
337
|
+
team_no: team_no.to_i,
|
338
|
+
names: team_mentions,
|
339
|
+
teamsize: pug.teamsize
|
340
|
+
)
|
341
|
+
end
|
342
|
+
|
343
|
+
msg = [
|
344
|
+
'Time to play!',
|
345
|
+
pug_teams
|
346
|
+
].join("\n")
|
347
|
+
|
348
|
+
send_msg(msg, event.channel)
|
349
|
+
end
|
350
|
+
|
351
|
+
def pug_teams_message(pug, event)
|
352
|
+
pug.teams.map do |team_no, player_ids|
|
353
|
+
team_display_names = player_ids.map do |player_id|
|
354
|
+
event.display_name_for(player_id)
|
355
|
+
end
|
356
|
+
|
357
|
+
team_status_line(
|
358
|
+
team_no: team_no.to_i,
|
359
|
+
names: team_display_names,
|
360
|
+
teamsize: pug.teamsize
|
361
|
+
)
|
362
|
+
end
|
363
|
+
end
|
364
|
+
|
365
|
+
def team_status_line(team_no:, names:, teamsize:)
|
366
|
+
if team_no.to_i.zero?
|
367
|
+
["No team: #{names.join(', ')}"]
|
368
|
+
else
|
369
|
+
[
|
370
|
+
"Team #{team_no}: #{names.join(', ')}",
|
371
|
+
"#{names.count}/#{teamsize}"
|
372
|
+
].join(MSG_SNIPPET_DELIMITER)
|
373
|
+
end
|
179
374
|
end
|
180
375
|
|
181
|
-
def
|
182
|
-
|
376
|
+
def end_pug(pug, channel_id)
|
377
|
+
pug.end_pug
|
378
|
+
send_msg('PUG ended', channel_id)
|
183
379
|
end
|
184
380
|
|
185
381
|
def no_active_pug_message
|
186
382
|
"There's no active PUG"
|
187
383
|
end
|
188
384
|
|
189
|
-
def
|
385
|
+
def send_msg(message, channel)
|
190
386
|
channel.send_message(message) && puts(message)
|
191
387
|
end
|
388
|
+
|
389
|
+
def post_results(json)
|
390
|
+
uri = URI("#{ENV['RATINGS_API_URL']}matches/")
|
391
|
+
req = Net::HTTP::Post.new(uri, 'Content-Type' => 'application/json')
|
392
|
+
req.body = json
|
393
|
+
res = Net::HTTP.start(uri.hostname, uri.port) do |http|
|
394
|
+
http.request(req)
|
395
|
+
end
|
396
|
+
end
|
192
397
|
end
|