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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 724d0971cb9732c8095fa84f03c9be9ab7e215515ee9f65dcbe117fa8dc409c5
4
- data.tar.gz: 2c81f16c2ed703ec9d3671eb0f0731ffaa34f7590bf1a3241e729aa7bd13bcb5
3
+ metadata.gz: 1952a9bb33cf18bcda01f202ed5900cb5168f0c3e1ad8aa083b1ee0ae54b6ed0
4
+ data.tar.gz: 31ab6af67990f6479640402bf20ec90fdcfad9943b5cc84697ea2c18776e9676
5
5
  SHA512:
6
- metadata.gz: d314677b730b1fdce5866120c97eb7448bcbab24ea46d2263f5dee35f8dacaec1ec433b4a5303942d80f2429a626673a7d1306956740f1579b3767993fb2181f
7
- data.tar.gz: 9499263c0c76de7590a2aacb0956fb7083d04ce378a17497b259b90ef3adbe6eb2c505a1e7077568c48391547e09e493d10c514d14c3d1b8e888619b1d629f0a
6
+ metadata.gz: 3ae59b76eda7fe87baa54c6b79d5d0d32de7f2cb947d2631eed2b2d2a3769376727c855a8ba1293c5e00fd23376357a5153cd3bdfa00e328868ee2f1b669f3e3
7
+ data.tar.gz: c0fd9ef59318cde38734e3f28d9f8a41a9c6ad0a829aae70ee48a07aeb5f509b6a22a58e6e6148a6c4324a1733f6d9d3c7e0104994ccbfd6d4ef6305cda803fb
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- qwtf_discord_bot (4.2.4)
4
+ qwtf_discord_bot (4.2.6)
5
5
  discordrb (~> 3.3)
6
6
  redis (~> 4.1)
7
7
  thor (~> 0.20)
@@ -95,4 +95,4 @@ DEPENDENCIES
95
95
  thor
96
96
 
97
97
  BUNDLED WITH
98
- 1.17.1
98
+ 1.17.2
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 two modules:
69
+ There are three modules:
70
70
 
71
71
 
72
72
  #### Server
@@ -81,6 +81,18 @@ This responds to discord messages:
81
81
  ![screenshot of bot responding to !server command](server_screenshot.png)
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
- 4.2.6
1
+ 5.0.1
@@ -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
@@ -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
@@ -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(CONFIG_FILE)
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 = "#{address}:#{name}"
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} has joined #{server_summary}"
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.2.6
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-01-19 00:00:00.000000000 Z
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
- rubyforge_project:
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,