qwtf_discord_bot 4.2.6 → 5.0.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.lock +2 -2
- data/README.md +40 -1
- data/VERSION +1 -1
- data/docker-compose.yml +12 -0
- data/exe/qwtf_discord_bot +7 -0
- data/lib/event_wrapper.rb +58 -0
- data/lib/qwtf_discord_bot.rb +13 -3
- data/lib/qwtf_discord_bot/qwtf_discord_bot_pug.rb +138 -0
- data/lib/qwtf_discord_bot/qwtf_discord_bot_watcher.rb +2 -10
- metadata +5 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1952a9bb33cf18bcda01f202ed5900cb5168f0c3e1ad8aa083b1ee0ae54b6ed0
|
4
|
+
data.tar.gz: 31ab6af67990f6479640402bf20ec90fdcfad9943b5cc84697ea2c18776e9676
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3ae59b76eda7fe87baa54c6b79d5d0d32de7f2cb947d2631eed2b2d2a3769376727c855a8ba1293c5e00fd23376357a5153cd3bdfa00e328868ee2f1b669f3e3
|
7
|
+
data.tar.gz: c0fd9ef59318cde38734e3f28d9f8a41a9c6ad0a829aae70ee48a07aeb5f509b6a22a58e6e6148a6c4324a1733f6d9d3c7e0104994ccbfd6d4ef6305cda803fb
|
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -66,7 +66,7 @@ A Discord bot for checking the status of QuakeWorld Team Fortress servers
|
|
66
66
|
|
67
67
|
### Commands
|
68
68
|
|
69
|
-
There are
|
69
|
+
There are three modules:
|
70
70
|
|
71
71
|
|
72
72
|
#### Server
|
@@ -81,6 +81,18 @@ This responds to discord messages:
|
|
81
81
|

|
82
82
|
|
83
83
|
|
84
|
+
#### Pug
|
85
|
+
|
86
|
+
qwtf-discord-bot pug
|
87
|
+
|
88
|
+
This responds to discord messages:
|
89
|
+
- `!join`
|
90
|
+
- `!leave`
|
91
|
+
- `!status`
|
92
|
+
- `!maxplayers <no_of_players>`
|
93
|
+
- `!leave`
|
94
|
+
|
95
|
+
|
84
96
|
#### Watcher
|
85
97
|
|
86
98
|
qwtf-discord-bot watcher
|
@@ -99,6 +111,12 @@ Build:
|
|
99
111
|
gem build qwtf_discrd_bot.gemspec
|
100
112
|
|
101
113
|
|
114
|
+
Install:
|
115
|
+
|
116
|
+
|
117
|
+
gem install --local qwtf_discord_bot-$(cat VERSION).gem
|
118
|
+
|
119
|
+
|
102
120
|
Push:
|
103
121
|
|
104
122
|
gem push qwtf_discord_bot-$(cat VERSION).gem
|
@@ -129,6 +147,14 @@ Only discord-bot watcher:
|
|
129
147
|
discord-bot watcher
|
130
148
|
|
131
149
|
|
150
|
+
Only discord-bot pug:
|
151
|
+
|
152
|
+
docker run -it \
|
153
|
+
--env QWTF_DISCORD_BOT_CONFIG_FILE=config.yaml \
|
154
|
+
--mount type=bind,source="$(pwd)"/config.yaml,target=/discord-bot/config.yaml \
|
155
|
+
discord-bot pug
|
156
|
+
|
157
|
+
|
132
158
|
Build:
|
133
159
|
|
134
160
|
docker build --tag=discord-bot .
|
@@ -140,6 +166,19 @@ Push:
|
|
140
166
|
docker push fortressone/discord-bot:latest
|
141
167
|
|
142
168
|
|
169
|
+
Create AWS instance:
|
170
|
+
|
171
|
+
```
|
172
|
+
docker-machine create \
|
173
|
+
--driver amazonec2 \
|
174
|
+
--amazonec2-access-key <AWS_ACCESS_KEY> \
|
175
|
+
--amazonec2-secret-key <AWS_SECRET_KEY> \
|
176
|
+
--amazonec2-root-size 30 \
|
177
|
+
--amazonec2-region ap-southeast-2 \
|
178
|
+
discord-bot
|
179
|
+
```
|
180
|
+
|
181
|
+
|
143
182
|
## License
|
144
183
|
|
145
184
|
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
|
1
|
+
5.0.1
|
data/docker-compose.yml
CHANGED
@@ -26,3 +26,15 @@ services:
|
|
26
26
|
- type: bind
|
27
27
|
source: "/home/ubuntu/.config/qwtf_discord_bot/config.yaml"
|
28
28
|
target: /discord-bot/config.yaml
|
29
|
+
discord-pug-bot:
|
30
|
+
image: fortressone/discord-bot:latest
|
31
|
+
command: pug
|
32
|
+
restart: always
|
33
|
+
depends_on:
|
34
|
+
- redis
|
35
|
+
environment:
|
36
|
+
- REDIS_URL=redis://redis
|
37
|
+
volumes:
|
38
|
+
- type: bind
|
39
|
+
source: "/home/ubuntu/.config/qwtf_discord_bot/config.yaml"
|
40
|
+
target: /discord-bot/config.yaml
|
data/exe/qwtf_discord_bot
CHANGED
@@ -2,6 +2,7 @@
|
|
2
2
|
|
3
3
|
require 'qwtf_discord_bot'
|
4
4
|
require 'thor'
|
5
|
+
require 'pry'
|
5
6
|
|
6
7
|
class QwtfDiscordBotExe < Thor
|
7
8
|
def self.exit_on_failure?
|
@@ -14,6 +15,12 @@ class QwtfDiscordBotExe < Thor
|
|
14
15
|
server_bot.run
|
15
16
|
end
|
16
17
|
|
18
|
+
desc 'pug', 'Start, join, leave, record pick-up games.'
|
19
|
+
def pug
|
20
|
+
pug_bot = QwtfDiscordBotPug.new
|
21
|
+
pug_bot.run
|
22
|
+
end
|
23
|
+
|
17
24
|
desc 'watcher', 'Watches servers and accounces when a player joins'
|
18
25
|
def watcher
|
19
26
|
watcher_bot = QwtfDiscordBotWatcher.new
|
@@ -0,0 +1,58 @@
|
|
1
|
+
class EventWrapper
|
2
|
+
include QwtfDiscordBot
|
3
|
+
|
4
|
+
DEFAULT_MAXPLAYERS = 8
|
5
|
+
|
6
|
+
def initialize(event)
|
7
|
+
@event = event
|
8
|
+
end
|
9
|
+
|
10
|
+
def user_id
|
11
|
+
@event.user.id
|
12
|
+
end
|
13
|
+
|
14
|
+
def username
|
15
|
+
@event.user.username
|
16
|
+
end
|
17
|
+
|
18
|
+
def maxplayers_key
|
19
|
+
[pug_key, "maxplayers"].join(":")
|
20
|
+
end
|
21
|
+
|
22
|
+
def maxplayers
|
23
|
+
redis.setnx(maxplayers_key, DEFAULT_MAXPLAYERS)
|
24
|
+
redis.get(maxplayers_key).to_i
|
25
|
+
end
|
26
|
+
|
27
|
+
def joined_player_count
|
28
|
+
redis.scard(players_key).to_i
|
29
|
+
end
|
30
|
+
|
31
|
+
def slots_left
|
32
|
+
maxplayers - joined_player_count
|
33
|
+
end
|
34
|
+
|
35
|
+
def pug_key
|
36
|
+
["pug", "channel", @event.channel.id].join(":")
|
37
|
+
end
|
38
|
+
|
39
|
+
def players_key
|
40
|
+
[pug_key, "players"].join(":")
|
41
|
+
end
|
42
|
+
|
43
|
+
def player_slots
|
44
|
+
"#{joined_player_count}/#{maxplayers}"
|
45
|
+
end
|
46
|
+
|
47
|
+
def users
|
48
|
+
@event.server.users
|
49
|
+
end
|
50
|
+
|
51
|
+
def role_key
|
52
|
+
[pug_key, "role"].join(":")
|
53
|
+
end
|
54
|
+
|
55
|
+
def role
|
56
|
+
redis.get(role_key) || "@here"
|
57
|
+
end
|
58
|
+
end
|
data/lib/qwtf_discord_bot.rb
CHANGED
@@ -1,9 +1,11 @@
|
|
1
1
|
require 'qwtf_discord_bot/version'
|
2
2
|
require 'qwtf_discord_bot/qwtf_discord_bot_server'
|
3
|
+
require 'qwtf_discord_bot/qwtf_discord_bot_pug'
|
3
4
|
require 'qwtf_discord_bot/qwtf_discord_bot_watcher'
|
4
5
|
require 'qwtf_discord_bot/config'
|
5
6
|
require 'discordrb'
|
6
7
|
require 'yaml'
|
8
|
+
require 'redis'
|
7
9
|
|
8
10
|
require 'qstat_request'
|
9
11
|
require 'player'
|
@@ -12,9 +14,17 @@ require 'emoji'
|
|
12
14
|
require 'roster'
|
13
15
|
|
14
16
|
module QwtfDiscordBot # :nodoc:
|
15
|
-
CONFIG_FILE = ENV['QWTF_DISCORD_BOT_CONFIG_FILE'] || "#{Dir.pwd}/config.yaml"
|
16
|
-
|
17
17
|
def self.config
|
18
|
-
@config ||= Config.new(
|
18
|
+
@config ||= Config.new(config_file)
|
19
|
+
end
|
20
|
+
|
21
|
+
def self.config_file
|
22
|
+
return ENV['QWTF_DISCORD_BOT_CONFIG_FILE'] if ENV['QWTF_DISCORD_BOT_CONFIG_FILE']
|
23
|
+
return "#{Dir.pwd}/config.yaml" if FileTest.exist?("#{Dir.pwd}/config.yaml")
|
24
|
+
"#{Dir.home}/.config/qwtf_discord_bot/config.yaml"
|
25
|
+
end
|
26
|
+
|
27
|
+
def redis
|
28
|
+
Redis.current
|
19
29
|
end
|
20
30
|
end
|
@@ -0,0 +1,138 @@
|
|
1
|
+
require 'event_wrapper'
|
2
|
+
|
3
|
+
class QwtfDiscordBotPug
|
4
|
+
include QwtfDiscordBot
|
5
|
+
|
6
|
+
FOUR_HOURS = 4 * 60 * 60
|
7
|
+
|
8
|
+
def run
|
9
|
+
bot = Discordrb::Commands::CommandBot.new(
|
10
|
+
token: QwtfDiscordBot.config.token,
|
11
|
+
client_id: QwtfDiscordBot.config.client_id,
|
12
|
+
prefix: '!'
|
13
|
+
)
|
14
|
+
|
15
|
+
bot.command :join do |event, *args|
|
16
|
+
e = EventWrapper.new(event)
|
17
|
+
|
18
|
+
redis.setnx(e.pug_key, Time.now)
|
19
|
+
redis.sadd(e.players_key, e.user_id)
|
20
|
+
|
21
|
+
message = if e.joined_player_count == e.maxplayers
|
22
|
+
mentions = joined_users(e).map do |user|
|
23
|
+
user.mention
|
24
|
+
end
|
25
|
+
"Time to play! #{mentions.join(" ")}"
|
26
|
+
elsif (e.joined_player_count == 1)
|
27
|
+
[
|
28
|
+
"#{e.username} creates a PUG",
|
29
|
+
e.player_slots,
|
30
|
+
e.role,
|
31
|
+
].join(" | ")
|
32
|
+
elsif e.slots_left <= 3
|
33
|
+
[
|
34
|
+
"#{e.username} joins the PUG",
|
35
|
+
e.player_slots,
|
36
|
+
"#{e.slots_left} more",
|
37
|
+
e.role,
|
38
|
+
].join(" | ")
|
39
|
+
else
|
40
|
+
[
|
41
|
+
"#{e.username} joins the PUG",
|
42
|
+
e.player_slots,
|
43
|
+
].join(" | ")
|
44
|
+
end
|
45
|
+
|
46
|
+
send_and_log_message(message, event)
|
47
|
+
end
|
48
|
+
|
49
|
+
bot.command :status do |event, *args|
|
50
|
+
e = EventWrapper.new(event)
|
51
|
+
usernames = joined_users(e).map(&:username)
|
52
|
+
|
53
|
+
message = [
|
54
|
+
"#{usernames.join(", ")} joined",
|
55
|
+
e.player_slots
|
56
|
+
].join(" | ")
|
57
|
+
|
58
|
+
send_and_log_message(message, event)
|
59
|
+
end
|
60
|
+
|
61
|
+
bot.command :maxplayers do |event, *args|
|
62
|
+
e = EventWrapper.new(event)
|
63
|
+
new_maxplayers = args[0]
|
64
|
+
|
65
|
+
message = if new_maxplayers
|
66
|
+
redis.set(e.maxplayers_key, new_maxplayers)
|
67
|
+
"Max number of players set to #{e.maxplayers} | #{e.player_slots}"
|
68
|
+
else
|
69
|
+
"Current max number of players is #{e.maxplayers} | #{e.player_slots}"
|
70
|
+
end
|
71
|
+
|
72
|
+
send_and_log_message(message, event)
|
73
|
+
|
74
|
+
if e.joined_player_count >= e.maxplayers
|
75
|
+
mentions = joined_users(e).map do |user|
|
76
|
+
user.mention
|
77
|
+
end
|
78
|
+
|
79
|
+
message = "Time to play! #{mentions.join(" ")}"
|
80
|
+
send_and_log_message(message, event)
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
bot.command :leave do |event, *args|
|
85
|
+
e = EventWrapper.new(event)
|
86
|
+
|
87
|
+
redis.srem(e.players_key, e.user_id)
|
88
|
+
|
89
|
+
message = "#{e.username} leaves the PUG | #{e.player_slots}"
|
90
|
+
|
91
|
+
send_and_log_message(message, event)
|
92
|
+
|
93
|
+
if e.joined_player_count == 0
|
94
|
+
redis.del(e.pug_key)
|
95
|
+
|
96
|
+
message = "PUG ended"
|
97
|
+
send_and_log_message(message, event)
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
bot.command :end do |event, *args|
|
102
|
+
e = EventWrapper.new(event)
|
103
|
+
|
104
|
+
redis.del(e.pug_key)
|
105
|
+
redis.del(e.players_key)
|
106
|
+
|
107
|
+
message = "PUG ended"
|
108
|
+
send_and_log_message(message, event)
|
109
|
+
end
|
110
|
+
|
111
|
+
bot.command :role do |event, *args|
|
112
|
+
e = EventWrapper.new(event)
|
113
|
+
role = args[0]
|
114
|
+
|
115
|
+
redis.set(e.role_key, role)
|
116
|
+
|
117
|
+
message = "Notification role set to #{role}"
|
118
|
+
send_and_log_message(message, event)
|
119
|
+
end
|
120
|
+
|
121
|
+
bot.run
|
122
|
+
end
|
123
|
+
|
124
|
+
private
|
125
|
+
|
126
|
+
def send_and_log_message(message, event)
|
127
|
+
event.channel.send_message(message)
|
128
|
+
puts message
|
129
|
+
end
|
130
|
+
|
131
|
+
def joined_users(event)
|
132
|
+
redis.smembers(event.players_key).map do |user_id|
|
133
|
+
event.users.find do |user|
|
134
|
+
user.id.to_s == user_id
|
135
|
+
end
|
136
|
+
end
|
137
|
+
end
|
138
|
+
end
|
@@ -1,5 +1,3 @@
|
|
1
|
-
require "redis"
|
2
|
-
|
3
1
|
class QwtfDiscordBotWatcher
|
4
2
|
include QwtfDiscordBot
|
5
3
|
|
@@ -14,7 +12,7 @@ class QwtfDiscordBotWatcher
|
|
14
12
|
next if request.is_empty?
|
15
13
|
|
16
14
|
request.player_names.each do |name|
|
17
|
-
redis_key = "
|
15
|
+
redis_key = ["watcher", address, name].join(":")
|
18
16
|
|
19
17
|
unless seen_recently?(redis_key)
|
20
18
|
endpoint.channel_ids.each do |channel_id|
|
@@ -51,7 +49,7 @@ class QwtfDiscordBotWatcher
|
|
51
49
|
end
|
52
50
|
|
53
51
|
def report_joined(name:, channel_id:, server_summary:)
|
54
|
-
message = "#{name}
|
52
|
+
message = "#{name} joins #{server_summary}"
|
55
53
|
|
56
54
|
Discordrb::API::Channel.create_message(
|
57
55
|
"Bot #{QwtfDiscordBot.config.token}",
|
@@ -61,10 +59,4 @@ class QwtfDiscordBotWatcher
|
|
61
59
|
|
62
60
|
puts message
|
63
61
|
end
|
64
|
-
|
65
|
-
private
|
66
|
-
|
67
|
-
def redis
|
68
|
-
@redis ||= Redis.new
|
69
|
-
end
|
70
62
|
end
|
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:
|
4
|
+
version: 5.0.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-08-23 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: discordrb
|
@@ -104,10 +104,12 @@ files:
|
|
104
104
|
- exe/qwtf_discord_bot
|
105
105
|
- lib/emoji.rb
|
106
106
|
- lib/endpoint.rb
|
107
|
+
- lib/event_wrapper.rb
|
107
108
|
- lib/player.rb
|
108
109
|
- lib/qstat_request.rb
|
109
110
|
- lib/qwtf_discord_bot.rb
|
110
111
|
- lib/qwtf_discord_bot/config.rb
|
112
|
+
- lib/qwtf_discord_bot/qwtf_discord_bot_pug.rb
|
111
113
|
- lib/qwtf_discord_bot/qwtf_discord_bot_server.rb
|
112
114
|
- lib/qwtf_discord_bot/qwtf_discord_bot_watcher.rb
|
113
115
|
- lib/qwtf_discord_bot/version.rb
|
@@ -135,8 +137,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
135
137
|
- !ruby/object:Gem::Version
|
136
138
|
version: '0'
|
137
139
|
requirements: []
|
138
|
-
|
139
|
-
rubygems_version: 2.7.6.2
|
140
|
+
rubygems_version: 3.1.2
|
140
141
|
signing_key:
|
141
142
|
specification_version: 4
|
142
143
|
summary: Works by wrapping the excellent CLI server query tool qstat. Accepts !server,
|