qwtf_discord_bot 5.1.9 → 5.3.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/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 +13 -8
- data/lib/player.rb +2 -1
- data/lib/pug.rb +100 -29
- 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 +284 -79
- 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/player.rb
CHANGED
data/lib/pug.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
class Pug
|
2
|
-
|
3
|
-
|
2
|
+
DEFAULT_TEAMSIZE = 4
|
3
|
+
MIN_NO_OF_TEAMS = 2
|
4
4
|
|
5
5
|
def self.for(channel_id)
|
6
6
|
new(channel_id)
|
@@ -10,18 +10,45 @@ class Pug
|
|
10
10
|
@channel_id = channel_id
|
11
11
|
end
|
12
12
|
|
13
|
-
def join(
|
13
|
+
def join(player_id)
|
14
14
|
redis.setnx(pug_key, Time.now)
|
15
|
-
|
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)
|
16
22
|
end
|
17
23
|
|
18
24
|
def joined_players
|
19
|
-
|
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)
|
20
44
|
end
|
21
45
|
|
22
|
-
def
|
23
|
-
|
24
|
-
|
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)
|
25
52
|
end
|
26
53
|
|
27
54
|
def teamsize=(teamsize)
|
@@ -32,8 +59,16 @@ class Pug
|
|
32
59
|
joined_player_count >= maxplayers
|
33
60
|
end
|
34
61
|
|
62
|
+
def empty?
|
63
|
+
joined_player_count.zero?
|
64
|
+
end
|
65
|
+
|
35
66
|
def joined_player_count
|
36
|
-
|
67
|
+
joined_players.count
|
68
|
+
end
|
69
|
+
|
70
|
+
def team_player_count(team_no)
|
71
|
+
redis.scard(team_key(team_no)).to_i
|
37
72
|
end
|
38
73
|
|
39
74
|
def player_slots
|
@@ -44,20 +79,24 @@ class Pug
|
|
44
79
|
maxplayers - joined_player_count
|
45
80
|
end
|
46
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
|
+
|
47
90
|
def notify_roles=(roles)
|
48
91
|
redis.set(notify_roles_key, roles)
|
49
92
|
end
|
50
93
|
|
51
94
|
def notify_roles
|
52
|
-
redis.get(notify_roles_key) ||
|
53
|
-
end
|
54
|
-
|
55
|
-
def teamsize=(teamsize)
|
56
|
-
redis.set(teamsize_key, teamsize)
|
95
|
+
redis.get(notify_roles_key) || '@here'
|
57
96
|
end
|
58
97
|
|
59
98
|
def teamsize
|
60
|
-
(redis.get(teamsize_key) ||
|
99
|
+
(redis.get(teamsize_key) || DEFAULT_TEAMSIZE).to_i
|
61
100
|
end
|
62
101
|
|
63
102
|
def active?
|
@@ -65,13 +104,13 @@ class Pug
|
|
65
104
|
end
|
66
105
|
|
67
106
|
def leave(player_id)
|
68
|
-
|
69
|
-
end_pug if empty?
|
107
|
+
leave_teams(player_id)
|
70
108
|
end
|
71
109
|
|
72
110
|
def end_pug
|
73
|
-
redis.
|
74
|
-
|
111
|
+
redis.keys([pug_key, "*"].join).each do |key|
|
112
|
+
redis.del(key)
|
113
|
+
end
|
75
114
|
end
|
76
115
|
|
77
116
|
def joined?(player_id)
|
@@ -79,36 +118,68 @@ class Pug
|
|
79
118
|
end
|
80
119
|
|
81
120
|
def maxplayers
|
82
|
-
teamsize *
|
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") }
|
83
132
|
end
|
84
133
|
|
85
134
|
private
|
86
135
|
|
87
|
-
def
|
88
|
-
|
136
|
+
def leave_teams(player_id)
|
137
|
+
teams_keys.each do |team|
|
138
|
+
redis.srem(team, player_id)
|
139
|
+
end
|
89
140
|
end
|
90
141
|
|
91
|
-
def
|
92
|
-
[pug_key,
|
142
|
+
def teams_keys
|
143
|
+
redis.keys([pug_key, 'teams:*'].join(':'))
|
93
144
|
end
|
94
145
|
|
95
|
-
def
|
96
|
-
[pug_key,
|
146
|
+
def team_key(team_no)
|
147
|
+
[pug_key, 'teams', team_no].join(':')
|
97
148
|
end
|
98
149
|
|
99
150
|
def pug_key
|
100
|
-
[
|
151
|
+
[channel_key, 'pug'].join(':')
|
152
|
+
end
|
153
|
+
|
154
|
+
def maps_key
|
155
|
+
[channel_key, 'maps'].join(':')
|
101
156
|
end
|
102
157
|
|
103
158
|
def notify_roles_key
|
104
|
-
[
|
159
|
+
[channel_key, 'role'].join(':')
|
105
160
|
end
|
106
161
|
|
107
162
|
def teamsize_key
|
108
|
-
[
|
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(':')
|
109
176
|
end
|
110
177
|
|
111
178
|
def redis
|
112
179
|
Redis.current
|
113
180
|
end
|
181
|
+
|
182
|
+
def no_of_teams
|
183
|
+
[actual_teams.count, MIN_NO_OF_TEAMS].max
|
184
|
+
end
|
114
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,65 +18,53 @@ 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)
|
21
|
+
return send_msg("You've already joined", e.channel) if pug.joined?(e.user_id)
|
44
22
|
|
23
|
+
join_pug(e, pug)
|
45
24
|
start_pug(pug, e) if pug.full?
|
46
25
|
end
|
47
26
|
end
|
48
27
|
|
49
28
|
bot.command :status do |event, *args|
|
50
29
|
setup_pug(event) do |e, pug|
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
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
|
+
)
|
61
40
|
end
|
62
41
|
end
|
63
42
|
|
64
43
|
bot.command :teamsize do |event, *args|
|
65
44
|
setup_pug(event) do |e, pug|
|
66
|
-
|
45
|
+
return send_msg("Team size is #{pug.teamsize}", e.channel) unless args.any?
|
46
|
+
|
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
|
67
49
|
|
68
50
|
if new_teamsize
|
69
51
|
pug.teamsize = new_teamsize
|
70
|
-
|
71
|
-
|
52
|
+
|
53
|
+
send_msg(
|
54
|
+
[
|
55
|
+
"Team size set to #{pug.teamsize}",
|
56
|
+
"#{pug.player_slots} joined"
|
57
|
+
].join(MSG_SNIPPET_DELIMITER),
|
72
58
|
e.channel
|
73
59
|
)
|
60
|
+
|
74
61
|
start_pug(pug, e) if pug.full?
|
75
62
|
else
|
76
|
-
|
77
|
-
|
63
|
+
send_msg(
|
64
|
+
[
|
65
|
+
"Current team size is #{pug.teamsize}",
|
66
|
+
"#{pug.player_slots} joined"
|
67
|
+
].join(MSG_SNIPPET_DELIMITER),
|
78
68
|
e.channel
|
79
69
|
)
|
80
70
|
end
|
@@ -83,56 +73,217 @@ class QwtfDiscordBotPug # :nodoc:
|
|
83
73
|
|
84
74
|
bot.command :leave do |event, *args|
|
85
75
|
setup_pug(event) do |e, pug|
|
86
|
-
return
|
87
|
-
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)
|
88
78
|
|
89
79
|
pug.leave(e.user_id)
|
90
80
|
|
91
|
-
|
92
|
-
"#{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),
|
93
90
|
e.channel
|
94
91
|
)
|
95
92
|
|
96
|
-
|
93
|
+
end_pug(pug, e.channel) if pug.empty?
|
97
94
|
end
|
98
95
|
end
|
99
96
|
|
100
97
|
bot.command :kick do |event, *args|
|
101
98
|
setup_pug(event) do |e, pug|
|
102
|
-
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?
|
101
|
+
|
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
|
103
107
|
|
104
|
-
|
105
|
-
|
106
|
-
display_name = e.display_name_for(user_id)
|
108
|
+
user_id = arg[3..-2].to_i
|
109
|
+
display_name = e.display_name_for(user_id) || arg
|
107
110
|
|
108
111
|
unless pug.joined?(user_id)
|
109
|
-
|
110
|
-
"#{display_name} isn't in the PUG",
|
111
|
-
e.channel
|
112
|
-
)
|
113
|
-
|
112
|
+
send_msg("#{display_name} isn't in the PUG", e.channel)
|
114
113
|
next
|
115
114
|
end
|
116
115
|
|
117
116
|
pug.leave(user_id)
|
118
117
|
|
119
|
-
|
120
|
-
"#{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),
|
121
127
|
e.channel
|
122
128
|
)
|
123
129
|
|
124
|
-
break
|
130
|
+
break end_pug(pug, e.channel) if pug.empty?
|
125
131
|
end
|
126
132
|
end
|
127
133
|
end
|
128
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
|
+
team_results = pug.teams.inject({}) do |teams, (name, player_ids)|
|
178
|
+
players = player_ids.inject({}) do |memo, id|
|
179
|
+
memo.merge({ id => e.display_name_for(id) })
|
180
|
+
end
|
181
|
+
|
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
|
+
team_results = pug.teams.inject({}) do |teams, (name, player_ids)|
|
214
|
+
players = player_ids.inject({}) do |memo, id|
|
215
|
+
memo.merge({ id => e.display_name_for(id) })
|
216
|
+
end
|
217
|
+
|
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)
|
231
|
+
end
|
232
|
+
end
|
233
|
+
|
129
234
|
bot.command :end do |event, *args|
|
130
235
|
setup_pug(event) do |e, pug|
|
131
|
-
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
|
241
|
+
|
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?
|
246
|
+
|
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?
|
132
276
|
|
133
|
-
|
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)
|
134
283
|
|
135
|
-
|
284
|
+
pug.game_map = game_map
|
285
|
+
send_msg("Map set to #{game_map}", e.channel)
|
286
|
+
end
|
136
287
|
end
|
137
288
|
end
|
138
289
|
|
@@ -141,13 +292,13 @@ class QwtfDiscordBotPug # :nodoc:
|
|
141
292
|
roles = args.join(' ')
|
142
293
|
pug.notify_roles = roles
|
143
294
|
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
295
|
+
msg = if roles.empty?
|
296
|
+
'Notification removed'
|
297
|
+
else
|
298
|
+
"Notification role set to #{roles}"
|
299
|
+
end
|
149
300
|
|
150
|
-
|
301
|
+
send_msg(msg, e.channel)
|
151
302
|
end
|
152
303
|
end
|
153
304
|
|
@@ -156,6 +307,19 @@ class QwtfDiscordBotPug # :nodoc:
|
|
156
307
|
|
157
308
|
private
|
158
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
|
+
|
159
323
|
def setup_pug(event)
|
160
324
|
e = EventDecorator.new(event)
|
161
325
|
pug = Pug.for(e.channel_id)
|
@@ -164,29 +328,70 @@ class QwtfDiscordBotPug # :nodoc:
|
|
164
328
|
end
|
165
329
|
|
166
330
|
def start_pug(pug, event)
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
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
|
175
363
|
end
|
176
364
|
|
177
|
-
def
|
178
|
-
|
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
|