protonbot 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +13 -0
- data/.rubocop.yml +38 -0
- data/CODE_OF_CONDUCT.md +74 -0
- data/CONFIG.md +45 -0
- data/CORE_PLUGIN.md +128 -0
- data/Gemfile +7 -0
- data/LICENSE.txt +21 -0
- data/PLUGIN.md +45 -0
- data/README.md +81 -0
- data/Rakefile +2 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/exe/protonbot-gencert +7 -0
- data/lib/protonbot/bot.rb +64 -0
- data/lib/protonbot/bot_conf.rb +48 -0
- data/lib/protonbot/bot_plugins.rb +110 -0
- data/lib/protonbot/core_plugin/apis/help.rb +54 -0
- data/lib/protonbot/core_plugin/apis/index.rb +2 -0
- data/lib/protonbot/core_plugin/apis/perms.rb +118 -0
- data/lib/protonbot/core_plugin/codes/index.rb +3 -0
- data/lib/protonbot/core_plugin/codes/names.rb +21 -0
- data/lib/protonbot/core_plugin/codes/welcome.rb +7 -0
- data/lib/protonbot/core_plugin/codes/whois.rb +9 -0
- data/lib/protonbot/core_plugin/commands/admin.rb +107 -0
- data/lib/protonbot/core_plugin/commands/basic.rb +9 -0
- data/lib/protonbot/core_plugin/commands/cross.rb +40 -0
- data/lib/protonbot/core_plugin/commands/help.rb +25 -0
- data/lib/protonbot/core_plugin/commands/index.rb +6 -0
- data/lib/protonbot/core_plugin/commands/joinpart.rb +25 -0
- data/lib/protonbot/core_plugin/commands/perms.rb +50 -0
- data/lib/protonbot/core_plugin/hooks/ctcp.rb +9 -0
- data/lib/protonbot/core_plugin/hooks/index.rb +7 -0
- data/lib/protonbot/core_plugin/hooks/joinpart.rb +42 -0
- data/lib/protonbot/core_plugin/hooks/kick.rb +17 -0
- data/lib/protonbot/core_plugin/hooks/nick.rb +10 -0
- data/lib/protonbot/core_plugin/hooks/ping.rb +3 -0
- data/lib/protonbot/core_plugin/hooks/privmsg.rb +62 -0
- data/lib/protonbot/core_plugin/hooks/raw.rb +32 -0
- data/lib/protonbot/core_plugin/plugin.rb +10 -0
- data/lib/protonbot/event_lock.rb +25 -0
- data/lib/protonbot/hook.rb +22 -0
- data/lib/protonbot/log.rb +182 -0
- data/lib/protonbot/log_wrapper.rb +52 -0
- data/lib/protonbot/numeric.rb +140 -0
- data/lib/protonbot/plug.rb +118 -0
- data/lib/protonbot/plug_events.rb +51 -0
- data/lib/protonbot/plug_io.rb +99 -0
- data/lib/protonbot/plug_utils.rb +242 -0
- data/lib/protonbot/plugin.rb +101 -0
- data/lib/protonbot/version.rb +4 -0
- data/lib/protonbot.rb +38 -0
- data/protonbot.gemspec +31 -0
- metadata +181 -0
@@ -0,0 +1,110 @@
|
|
1
|
+
class ProtonBot::Bot
|
2
|
+
# @!group Plugins
|
3
|
+
|
4
|
+
# Use it to load external plugins. You cannot provide both arguments
|
5
|
+
# @param file [String] Filename
|
6
|
+
# @param block [Proc]
|
7
|
+
# @example
|
8
|
+
# plugin_loader do
|
9
|
+
# plugin('foo') # Will load plugin from ./plugins/foo/main.rb
|
10
|
+
# gem('bar') # Will load plugin from path_to_gem_bar/lib/bar/plugin.rb
|
11
|
+
# end
|
12
|
+
# @example
|
13
|
+
# plugin_loader 'foo' # Will load plugin from ./plugins/foo/main.rb
|
14
|
+
def plugin_loader(file = nil, &block)
|
15
|
+
raise(ArgumentError, 'Both filename and load-block are nil!') if
|
16
|
+
file.nil? && block.nil?
|
17
|
+
|
18
|
+
raise(ArgumentError, 'Both filename and load-block are not nil!') if
|
19
|
+
!file.nil? && !block.nil?
|
20
|
+
|
21
|
+
if file
|
22
|
+
@plugin_loader = lambda do
|
23
|
+
load(File.expand_path('./' + file))
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
@plugin_loader = block if block
|
28
|
+
self
|
29
|
+
end
|
30
|
+
|
31
|
+
# Basically clears plugin hash
|
32
|
+
# @return [Bot] self
|
33
|
+
def plugins_unload
|
34
|
+
@plugins = {}
|
35
|
+
self
|
36
|
+
end
|
37
|
+
|
38
|
+
# Loads all plugins by calling `@plugin_loader` and initializing
|
39
|
+
# each plugin
|
40
|
+
# @return [Bot] self
|
41
|
+
def plugins_load
|
42
|
+
@plugins['core'] =
|
43
|
+
pluginr "#{Gem.loaded_specs['protonbot'].lib_dirs_glob.split(':')[0]}/protonbot/core_plugin/plugin.rb"
|
44
|
+
@plugin_loader.call if @plugin_loader
|
45
|
+
@plugins.each do |k, v|
|
46
|
+
v.bot = self
|
47
|
+
v.log = @_log.wrap("?#{k}")
|
48
|
+
v.launch
|
49
|
+
end
|
50
|
+
self
|
51
|
+
end
|
52
|
+
|
53
|
+
# Loads given plugin by name
|
54
|
+
# @param dat [String] Plugin name in file system
|
55
|
+
# @return [Bot] self
|
56
|
+
def plugin(dat)
|
57
|
+
pl = nil
|
58
|
+
if dat.instance_of? Array
|
59
|
+
dat.each do |i|
|
60
|
+
pl = pluginr(File.expand_path("plugins/#{i}/plugin.rb"))
|
61
|
+
raise ProtonBot::PluginError, "`plugins/#{i}/plugin.rb` did not return plugin!" unless
|
62
|
+
pl.instance_of? ProtonBot::Plugin
|
63
|
+
end
|
64
|
+
elsif dat.instance_of? String
|
65
|
+
pl = pluginr(File.expand_path("plugins/#{dat}/plugin.rb"))
|
66
|
+
raise ProtonBot::PluginError, "`plugins/#{dat}/plugin.rb` did not return plugin!" unless
|
67
|
+
pl.instance_of? ProtonBot::Plugin
|
68
|
+
else
|
69
|
+
raise ArgumentError, 'Unknown type of `dat` plugin! Use Array or String!'
|
70
|
+
end
|
71
|
+
@plugins[pl.name] = pl
|
72
|
+
self
|
73
|
+
end
|
74
|
+
|
75
|
+
# Loads plugin from gem
|
76
|
+
# @param gemname [String] Name of gem
|
77
|
+
# @return [Bot] self
|
78
|
+
def gem(gemname)
|
79
|
+
if Gem.loaded_specs[gemname]
|
80
|
+
path = "#{Gem.loaded_specs[gemname].lib_dirs_glob.split(':')[0]}/" \
|
81
|
+
"#{gemname.gsub(/-/, '/')}/plugin.rb"
|
82
|
+
if File.exist? path
|
83
|
+
pl = pluginr(path)
|
84
|
+
raise ProtonBot::PluginError, "`#{path}` did not return plugin!" unless
|
85
|
+
pl.instance_of? ProtonBot::Plugin
|
86
|
+
@plugins[gemname] = pl
|
87
|
+
else
|
88
|
+
raise IOError, "No such file or directory: #{path}"
|
89
|
+
end
|
90
|
+
else
|
91
|
+
raise ArgumentError, "No such gem: #{gemname}"
|
92
|
+
end
|
93
|
+
self
|
94
|
+
end
|
95
|
+
|
96
|
+
# Loads plugin by path
|
97
|
+
# @param path [String] Path
|
98
|
+
# @return [Plugin] Loaded plugin
|
99
|
+
def pluginr(path)
|
100
|
+
if File.exist? path
|
101
|
+
pl = eval(File.read(path), nil, %r{.*/(.+/.+)}.match(path)[1])
|
102
|
+
pl.path = File.dirname(path)
|
103
|
+
pl
|
104
|
+
else
|
105
|
+
raise IOError, 'No such file or directory: #{path}'
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
# @!endgroup
|
110
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
@help = {}
|
2
|
+
|
3
|
+
fun :help_render do |query = nil, ehash = nil|
|
4
|
+
if query
|
5
|
+
done = nil
|
6
|
+
@help.each do |group, items|
|
7
|
+
items.each do |item, h|
|
8
|
+
next unless item == query
|
9
|
+
hook = nil
|
10
|
+
@bot.plugins.each do |_, p|
|
11
|
+
p.hooks.each do |hk|
|
12
|
+
next if hook
|
13
|
+
next unless hk
|
14
|
+
if hk.pattern[:type] == :command && hk.pattern[:cmd] == h[:name] && hk.extra[:needed_perms]
|
15
|
+
hook = hk
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
done =
|
20
|
+
if hook && ehash && ehash[:perms]
|
21
|
+
perms = ehash[:perms]
|
22
|
+
needed = hook.extra[:needed_perms]
|
23
|
+
not_enough = needed - perms
|
24
|
+
available = needed - not_enough
|
25
|
+
available_ = available.map{|i|'%C%GREEN' + i + '%N'}
|
26
|
+
not_enough_ = not_enough.map{|i|'%C%RED' + i + '%N'}
|
27
|
+
permstatus = (available_ + not_enough_).join(' ')
|
28
|
+
"%B#{group}/#{item} |%N #{h[:syntax]} %B|%N Perms: #{permstatus} %B|%N #{h[:description]}"
|
29
|
+
else
|
30
|
+
"%B#{group}/#{item} |%N #{h[:syntax]} %B|%N #{h[:description]}"
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
if done
|
35
|
+
done
|
36
|
+
else
|
37
|
+
"No such command: %B#{query}%N"
|
38
|
+
end
|
39
|
+
else
|
40
|
+
'Use %Blist%N command to list all groups. Use %Blist <group>%N ' +
|
41
|
+
'command to list all items in group. Use %Bhelp <command>%N to read ' +
|
42
|
+
'help for given command. ' +
|
43
|
+
'Parameter syntax: %B<required> [optional] {0 or more} (1 or more)%N'
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
fun :help_add do |group, name, syntax, description|
|
48
|
+
@help[group] = {} unless @help[group]
|
49
|
+
@help[group][name] = {
|
50
|
+
name: name,
|
51
|
+
syntax: syntax,
|
52
|
+
description: description
|
53
|
+
}
|
54
|
+
end
|
@@ -0,0 +1,118 @@
|
|
1
|
+
class ProtonBot::Hook
|
2
|
+
# Basic hook modifier for checking permissions. Added by core plugin.
|
3
|
+
# @param perms [String] Permission names
|
4
|
+
# @return [Hook] self
|
5
|
+
def perm!(*perms)
|
6
|
+
self.extra[:needed_perms] = perms
|
7
|
+
self.chain << proc do |dat, hook|
|
8
|
+
perms = dat[:perms]
|
9
|
+
canrun = true
|
10
|
+
needed = hook.extra[:needed_perms]
|
11
|
+
not_enough = needed - perms
|
12
|
+
available = needed - not_enough
|
13
|
+
if not_enough == []
|
14
|
+
canrun = true
|
15
|
+
else
|
16
|
+
canrun = false
|
17
|
+
available_ = available.map{|i|'%C%GREEN' + i + '%N'}
|
18
|
+
not_enough_ = not_enough.map{|i|'%C%RED' + i + '%N'}
|
19
|
+
status = (available_ + not_enough_).join(' ')
|
20
|
+
dat.nreply("Not enough permissions to use this! (#{status})")
|
21
|
+
end
|
22
|
+
canrun
|
23
|
+
#
|
24
|
+
end
|
25
|
+
self
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
@permhash = {
|
30
|
+
'owner' => %w(
|
31
|
+
reload
|
32
|
+
eval
|
33
|
+
exec
|
34
|
+
raw
|
35
|
+
cross
|
36
|
+
admin
|
37
|
+
perms
|
38
|
+
),
|
39
|
+
'admin' => %w(
|
40
|
+
joinpart
|
41
|
+
nick
|
42
|
+
msg
|
43
|
+
ctcp
|
44
|
+
notice
|
45
|
+
nctcp
|
46
|
+
flushq
|
47
|
+
),
|
48
|
+
'cross' => %w(
|
49
|
+
crossuser
|
50
|
+
crosschan
|
51
|
+
crossplug
|
52
|
+
)
|
53
|
+
}
|
54
|
+
|
55
|
+
fun :process_perms do |a|
|
56
|
+
out = nil
|
57
|
+
loop do
|
58
|
+
out = a
|
59
|
+
a.each do |i|
|
60
|
+
next unless @permhash.keys.include? i
|
61
|
+
canrun = true
|
62
|
+
@permhash[i].each do |ii|
|
63
|
+
canrun = false if a.include? ii
|
64
|
+
end
|
65
|
+
a += @permhash[i] if canrun
|
66
|
+
end
|
67
|
+
break if out == a
|
68
|
+
end
|
69
|
+
out
|
70
|
+
end
|
71
|
+
|
72
|
+
fun :getperms! do |plug, host|
|
73
|
+
getperms(plug, host) or []
|
74
|
+
end
|
75
|
+
|
76
|
+
fun :getperms do |plug, host|
|
77
|
+
dat = plug.db.query('perms').ensure.select('host' => host).finish
|
78
|
+
if dat.empty?
|
79
|
+
nil
|
80
|
+
else
|
81
|
+
dat[0].to_h['perms']
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
fun :hasperm? do |plug, host, perm|
|
86
|
+
dat = plug.db.query('perms').ensure.select('host' => host).finish
|
87
|
+
perms = dat[0].to_h['perms'] unless dat.empty?
|
88
|
+
perms = [] if dat.empty?
|
89
|
+
perms.include?(perm) || dat.include?('owner')
|
90
|
+
end
|
91
|
+
|
92
|
+
fun :addperm do |plug, host, perm|
|
93
|
+
perms = getperms(plug, host)
|
94
|
+
if !perms
|
95
|
+
plug.db.query('perms').ensure.insert(
|
96
|
+
'host' => host, 'perms' => [perm]
|
97
|
+
).write.finish
|
98
|
+
else
|
99
|
+
unless perms.include? perm
|
100
|
+
plug.db.query('perms').ensure.update(
|
101
|
+
{ 'host' => host }, 'perms' => (perms + [perm]).uniq
|
102
|
+
).write.finish
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
fun :delperm do |plug, host, perm|
|
108
|
+
perms = getperms(plug, host)
|
109
|
+
if perms && perms.include?(perm)
|
110
|
+
plug.db.query('perms').ensure.update(
|
111
|
+
{ 'host' => host }, 'perms' => perms - [perm]
|
112
|
+
).write.finish
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
fun :permhash do
|
117
|
+
@permhash
|
118
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
hook(type: :code, code: @numeric::NAMREPLY) do |dat|
|
2
|
+
m = /[=*@] (.+?) :(.+)/.match(dat[:extra])
|
3
|
+
|
4
|
+
if !dat[:plug].chans[m[1]] || !dat[:plug].chans[m[1]][:collecting]
|
5
|
+
dat[:plug].chans[m[1]] = {}
|
6
|
+
dat[:plug].chans[m[1]][:collecting] = true
|
7
|
+
dat[:plug].chans[m[1]][:users] = []
|
8
|
+
end
|
9
|
+
users = m[2].split(' ')
|
10
|
+
users.each do |user|
|
11
|
+
user = /[@+%&]*(.+)/.match(user)[1]
|
12
|
+
dat[:plug].chans[m[1]][:users] << user
|
13
|
+
dat[:plug].users[user] = { nick: user }
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
hook(type: :code, code: @numeric::ENDOFNAMES) do |dat|
|
18
|
+
m = /(.+?) :.*/.match(dat[:extra])
|
19
|
+
|
20
|
+
dat[:plug].chans[m[1]][:collecting] = false
|
21
|
+
end
|
@@ -0,0 +1,9 @@
|
|
1
|
+
hook(type: :code, code: @numeric::WHOISUSER) do |dat|
|
2
|
+
m = /(.+?) (.+?) (.+?) \* :.*/.match(dat[:extra])
|
3
|
+
dat[:plug].users[m[1]] = {} unless dat[:plug].users[m[1]]
|
4
|
+
u = dat[:plug].users[m[1]]
|
5
|
+
u[:nick] = m[1]
|
6
|
+
u[:user] = m[2]
|
7
|
+
u[:host] = m[3]
|
8
|
+
emit(dat.merge(type: :code_whoisuser, nick: u[:nick], user: u[:user], host: u[:host]))
|
9
|
+
end
|
@@ -0,0 +1,107 @@
|
|
1
|
+
@key = nil
|
2
|
+
|
3
|
+
core.help_add('owner', 'key', 'key [key]', 'Generates unique key. If correct key is ' +
|
4
|
+
'provided, gives owner privileges')
|
5
|
+
cmd(cmd: 'key') do |dat|
|
6
|
+
if !dat[:split].empty?
|
7
|
+
if dat[:split][0] == @key && !@key.nil?
|
8
|
+
dat.reply "#{dat[:nick]}: given key is valid! You are an owner now!"
|
9
|
+
addperm(dat[:plug], dat[:host], 'owner')
|
10
|
+
else
|
11
|
+
dat.reply "#{dat[:nick]}: given key is invalid!"
|
12
|
+
end
|
13
|
+
@key = nil
|
14
|
+
else
|
15
|
+
@key = Random.rand(44**44..55**55).to_s(36)
|
16
|
+
log.debug 'Use this key to auth yourself: ' + @key
|
17
|
+
dat.reply "#{dat[:nick]}: generated your key and outputted to console!" \
|
18
|
+
' Use `key <key>` to make yourself owner!'
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
core.help_add('owner', 'rb', 'rb {code}', 'Evaluates given ruby code')
|
23
|
+
cmd(cmd: 'rb') do |dat|
|
24
|
+
if dat[:split]
|
25
|
+
out = eval(dat[:split].join(' ')).inspect
|
26
|
+
dat.reply "%BOutput%N: #{out}"
|
27
|
+
else
|
28
|
+
dat.reply '%BOutput%N: nil'
|
29
|
+
end
|
30
|
+
end.perm!('eval')
|
31
|
+
|
32
|
+
core.help_add('owner', 'exec', 'exec {command}', 'Executes given command')
|
33
|
+
cmd(cmd: 'exec') do |dat|
|
34
|
+
if dat[:split]
|
35
|
+
stdout, stderr, status = Open3.capture3(dat[:split].join(' '))
|
36
|
+
STDERR.puts stderr
|
37
|
+
if status.success?
|
38
|
+
dat.reply stdout
|
39
|
+
else
|
40
|
+
dat.nreply 'Err: ' + stderr
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end.perm!('exec')
|
44
|
+
|
45
|
+
core.help_add('owner', 'raw', 'raw {message}', 'Sends raw message to an IRC server')
|
46
|
+
cmd(cmd: 'raw') do |dat|
|
47
|
+
dat[:plug].write(dat[:split].join(' '))
|
48
|
+
end.perm!('raw')
|
49
|
+
|
50
|
+
core.help_add('admin', 'nick', 'nick <nick>', 'Changes nick')
|
51
|
+
cmd(cmd: 'nick') do |dat|
|
52
|
+
if dat[:split].empty?
|
53
|
+
dat.nreply ProtonBot::Messages::NOT_ENOUGH_PARAMETERS
|
54
|
+
else
|
55
|
+
dat[:plug].change_nick(dat[:split][0])
|
56
|
+
end
|
57
|
+
end.perm!('nick')
|
58
|
+
|
59
|
+
core.help_add('admin', 'msg', 'msg [target] <message>', 'Sends given message to target')
|
60
|
+
cmd(cmd: 'msg') do |dat|
|
61
|
+
if dat[:split].empty?
|
62
|
+
dat.nreply ProtonBot::Messages::NOT_ENOUGH_PARAMETERS
|
63
|
+
else
|
64
|
+
dat[:plug].privmsg(dat[:split][0], dat[:split][1, dat[:split].length - 1].join(' '))
|
65
|
+
end
|
66
|
+
end.perm!('msg')
|
67
|
+
|
68
|
+
core.help_add('admin', 'ctcp', 'ctcp [target] <message>', 'Sends given ctcp to target')
|
69
|
+
cmd(cmd: 'ctcp') do |dat|
|
70
|
+
if dat[:split].empty?
|
71
|
+
dat.nreply ProtonBot::Messages::NOT_ENOUGH_PARAMETERS
|
72
|
+
else
|
73
|
+
dat[:plug].ctcp(dat[:split][0], dat[:split][1, dat[:split].length - 1].join(' '))
|
74
|
+
end
|
75
|
+
end.perm!('ctcp')
|
76
|
+
|
77
|
+
core.help_add('admin', 'notice', 'notice [target] <message>', 'Sends given notice to target')
|
78
|
+
cmd(cmd: 'notice') do |dat|
|
79
|
+
if dat[:split].empty?
|
80
|
+
dat.nreply ProtonBot::Messages::NOT_ENOUGH_PARAMETERS
|
81
|
+
else
|
82
|
+
dat[:plug].notice(dat[:split][0], dat[:split][1, dat[:split].length - 1].join(' '))
|
83
|
+
end
|
84
|
+
end.perm!('notice')
|
85
|
+
|
86
|
+
core.help_add('admin', 'nctcp', 'nctcp [target] <message>', 'Sends given nctcp to target')
|
87
|
+
cmd(cmd: 'nctcp') do |dat|
|
88
|
+
if dat[:split].empty?
|
89
|
+
dat.nreply ProtonBot::Messages::NOT_ENOUGH_PARAMETERS
|
90
|
+
else
|
91
|
+
dat[:plug].nctcp(dat[:split][0], dat[:split][1, dat[:split].length - 1].join(' '))
|
92
|
+
end
|
93
|
+
end.perm!('nctcp')
|
94
|
+
|
95
|
+
core.help_add('admin', 'flushq', 'flushq', 'Flushes queue')
|
96
|
+
cmd(cmd: 'flushq') do |dat|
|
97
|
+
dat[:plug].queue.clear
|
98
|
+
end.perm!('flushq')
|
99
|
+
|
100
|
+
core.help_add('owner', 'r', 'r', 'Reloads all plugins')
|
101
|
+
hook(type: :command, cmd: 'r') do |dat|
|
102
|
+
dat[:bot].log.info 'Reload: START'
|
103
|
+
dat[:bot].plugins_unload
|
104
|
+
dat[:bot].plugins_load
|
105
|
+
dat[:bot].log.info 'Reload: END'
|
106
|
+
dat.nreply 'Done!'
|
107
|
+
end.perm!('reload')
|
@@ -0,0 +1,40 @@
|
|
1
|
+
core.help_add('cross', 'as', 'as <nickname> {message}', 'Processes given message as given user')
|
2
|
+
cmd(cmd: 'as', perm_crossuser: true) do |dat|
|
3
|
+
nick = dat[:split][0]
|
4
|
+
if dat[:plug].users[nick]
|
5
|
+
user = dat[:plug].getuser(nick)
|
6
|
+
host = dat[:plug].gethost(nick)
|
7
|
+
message = dat[:split][1..dat[:split].length - 1].join(' ')
|
8
|
+
dat[:plug].emit(dat.merge(type: :privmsg, nick: nick, user: user, host: host,
|
9
|
+
message: message, target: dat[:target], reply_to: dat[:reply_to]))
|
10
|
+
else
|
11
|
+
dat.nreply 'No such user!'
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
core.help_add('cross', 'at', 'at <channel> {message}', 'Processes given message at given channel')
|
16
|
+
cmd(cmd: 'at', perm_crossuser: true) do |dat|
|
17
|
+
chan = dat[:split][0]
|
18
|
+
if dat[:plug].chans[chan]
|
19
|
+
nick = dat[:nick]
|
20
|
+
user = dat[:plug].getuser(nick)
|
21
|
+
host = dat[:plug].gethost(nick)
|
22
|
+
message = dat[:split][1..dat[:split].length - 1].join(' ')
|
23
|
+
dat[:plug].emit(dat.merge(type: :privmsg, nick: nick, user: user, host: host,
|
24
|
+
message: message, target: chan, reply_to: chan))
|
25
|
+
else
|
26
|
+
dat.nreply 'No such chan!'
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
core.help_add('cross', 'on', 'on <server> {message}', 'Processes given message on given server')
|
31
|
+
cmd(cmd: 'on', perm_crossuser: true) do |dat|
|
32
|
+
plug = dat[:split][0]
|
33
|
+
if bot.plugs[plug] && bot.plugs[plug].running
|
34
|
+
message = dat[:split][1..dat[:split].length - 1].join(' ')
|
35
|
+
bot.plugs[plug].emit(dat.merge(type: :privmsg, nick: nil, user: nil, host: nil,
|
36
|
+
message: message, plug: bot.plugs[plug]))
|
37
|
+
else
|
38
|
+
dat.nreply 'No such plug!'
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
core.help_add('help', 'help', 'help {commands}', 'Shows help for given commands')
|
2
|
+
cmd(cmd: 'help') do |dat|
|
3
|
+
if dat[:split].empty?
|
4
|
+
dat.nreply(help_render)
|
5
|
+
else
|
6
|
+
dat[:split].each do |i|
|
7
|
+
dat.nreply(help_render(i, dat))
|
8
|
+
end
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
core.help_add('help', 'list', 'list {groups}', 'Lists groups or items in groups')
|
13
|
+
cmd(cmd: 'list') do |dat|
|
14
|
+
if dat[:split].empty?
|
15
|
+
dat.nreply "%BGroups%N: #{@help.keys.join(', ')}"
|
16
|
+
else
|
17
|
+
dat[:split].each do |i|
|
18
|
+
if @help[i]
|
19
|
+
dat.nreply "Items in %B#{i}%N: #{@help[i].keys.join(', ')}"
|
20
|
+
else
|
21
|
+
dat.nreply "No such group: %B#{i}%N"
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
core.help_add('admin', 'join', 'join (chans|sep=,) [pass]', 'Joins given chans')
|
2
|
+
hook(type: :command, cmd: 'join') do |dat|
|
3
|
+
if dat[:split].empty?
|
4
|
+
m.nreply 'Not enough parameters!'
|
5
|
+
else
|
6
|
+
(pass = dat[:split][1]) || ''
|
7
|
+
chans = dat[:split][0].split(',')
|
8
|
+
chans.each do |chan|
|
9
|
+
dat[:plug].join(chan, pass)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end.perm!('joinpart')
|
13
|
+
|
14
|
+
core.help_add('admin', 'part', 'part (chans|sep=,) [reason]', 'Parts given chans')
|
15
|
+
hook(type: :command, cmd: 'part') do |dat|
|
16
|
+
if dat[:split].empty?
|
17
|
+
dat[:plug].part(dat[:target], '')
|
18
|
+
else
|
19
|
+
(reason = dat[:split][1]) || ''
|
20
|
+
chans = dat[:split][0].split(',')
|
21
|
+
chans.each do |chan|
|
22
|
+
dat[:plug].part(chan, reason)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end.perm!('joinpart')
|
@@ -0,0 +1,50 @@
|
|
1
|
+
core.help_add('owner', 'perms', 'perms {groups}', 'Lists permissions/permisssion-groups')
|
2
|
+
cmd(cmd: 'perms') do |dat|
|
3
|
+
if dat[:split].empty?
|
4
|
+
dat.nreply "Perm groups: #{@permhash.keys.join(', ')}"
|
5
|
+
else
|
6
|
+
dat[:split].each do |g|
|
7
|
+
if @permhash[g]
|
8
|
+
dat.nreply "Perms in group %B#{g}%N: #{@permhash[g].join(', ')}"
|
9
|
+
else
|
10
|
+
dat.nreply "No such group: %B#{g}%N"
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
core.help_add('owner', 'uperms', 'uperms <+|-|?> <user> {perms}', '%B+%N - gives perms. ' \
|
17
|
+
'%B-%N - removes perms. %B?%N - checks perms.')
|
18
|
+
cmd(cmd: 'uperms') do |dat|
|
19
|
+
case dat[:split][0]
|
20
|
+
when nil
|
21
|
+
dat.nreply 'Not enough parameters!'
|
22
|
+
when '+'
|
23
|
+
if dat[:plug].users[dat[:split][1]]
|
24
|
+
dat[:split][2..dat[:split].length-1].each do |perm|
|
25
|
+
addperm(dat[:plug], dat[:plug].gethost(dat[:split][1]), perm)
|
26
|
+
end
|
27
|
+
dat.nreply 'Done!'
|
28
|
+
else
|
29
|
+
dat.nreply "No such user: #{dat[:split][1]}"
|
30
|
+
end
|
31
|
+
when '-'
|
32
|
+
if dat[:plug].users[dat[:split][1]]
|
33
|
+
dat[:split][2..dat[:split].length-1].each do |perm|
|
34
|
+
delperm(dat[:plug], dat[:plug].gethost(dat[:split][1]), perm)
|
35
|
+
end
|
36
|
+
dat.nreply 'Done!'
|
37
|
+
else
|
38
|
+
dat.nreply "No such user: #{dat[:split][1]}"
|
39
|
+
end
|
40
|
+
when '?'
|
41
|
+
if dat[:plug].users[dat[:split][1]]
|
42
|
+
dat.nreply "%B#{dat[:split][1]}%N's perms: " \
|
43
|
+
"#{getperms!(dat[:plug], dat[:plug].gethost(dat[:split][1])).join(', ')}"
|
44
|
+
else
|
45
|
+
dat.nreply "No such user: #{dat[:split][1]}"
|
46
|
+
end
|
47
|
+
else
|
48
|
+
dat.nreply "No such action: #{dat[:split][0]}"
|
49
|
+
end
|
50
|
+
end.perm!('perms')
|
@@ -0,0 +1,9 @@
|
|
1
|
+
hook(type: :ctcp, cmd: 'VERSION') do |dat|
|
2
|
+
dat[:plug].nctcp(dat[:nick], %(VERSION ProtonBot v#{ProtonBot::VERSION} on Ruby ) +
|
3
|
+
%(v#{RUBY_VERSION}.#{RUBY_PATCHLEVEL}/#{RUBY_PLATFORM} and Heliodor ) +
|
4
|
+
%(v#{Gem.loaded_specs['heliodor'].version.version}))
|
5
|
+
end
|
6
|
+
|
7
|
+
hook(type: :ctcp, cmd: 'PING') do |dat|
|
8
|
+
dat[:plug].nctcp(dat[:nick], %(PING #{dat[:split][0]}))
|
9
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
hook(type: :ujoin) do |dat|
|
2
|
+
dat[:plug].users[dat[:nick]] = {} unless dat[:plug].users[dat[:nick]]
|
3
|
+
u = dat[:plug].users[dat[:nick]]
|
4
|
+
u[:nick] = dat[:nick]
|
5
|
+
u[:user] = dat[:user]
|
6
|
+
u[:host] = dat[:host]
|
7
|
+
|
8
|
+
unless dat[:plug].chans[dat[:channel]]
|
9
|
+
dat[:plug].chans[dat[:channel]] = {}
|
10
|
+
dat[:plug].chans[dat[:channel]][:users] = []
|
11
|
+
end
|
12
|
+
|
13
|
+
dat[:plug].chans[dat[:channel]][:users] << u[:nick] unless
|
14
|
+
dat[:plug].chans[dat[:channel]][:users].include? u[:nick]
|
15
|
+
end
|
16
|
+
|
17
|
+
hook(type: :upart) do |dat|
|
18
|
+
dat[:plug].users[dat[:nick]] = {} unless dat[:plug].users[dat[:nick]]
|
19
|
+
u = dat[:plug].users[dat[:nick]]
|
20
|
+
u[:nick] = dat[:nick]
|
21
|
+
u[:user] = dat[:user]
|
22
|
+
u[:host] = dat[:host]
|
23
|
+
|
24
|
+
unless dat[:plug].chans[dat[:channel]]
|
25
|
+
dat[:plug].chans[dat[:channel]] = {}
|
26
|
+
dat[:plug].chans[dat[:channel]][:users] = []
|
27
|
+
end
|
28
|
+
|
29
|
+
dat[:plug].chans[dat[:channel]][:users].delete u[:nick] if
|
30
|
+
dat[:plug].chans[dat[:channel]][:users].include? u[:nick]
|
31
|
+
|
32
|
+
if dat[:nick] == dat[:plug].nick && /requested by .*/.match(dat[:message])
|
33
|
+
dat[:plug].join(dat[:channel])
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
hook(type: :uqit) do |dat|
|
38
|
+
dat[:plug].chans.each do |chan|
|
39
|
+
chan[:users].delete(dat[:nick]) if chan[:users]
|
40
|
+
end
|
41
|
+
dat[:plug].users.delete(dat[:nick])
|
42
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
hook(type: :ukick) do |dat|
|
2
|
+
dat[:plug].users[dat[:nick]] = {} unless dat[:plug].users[dat[:nick]]
|
3
|
+
u = dat[:plug].users[dat[:nick]]
|
4
|
+
u[:nick] = dat[:nick]
|
5
|
+
u[:user] = dat[:user]
|
6
|
+
u[:host] = dat[:host]
|
7
|
+
|
8
|
+
unless dat[:plug].chans[dat[:channel]]
|
9
|
+
dat[:plug].chans[dat[:channel]] = {}
|
10
|
+
dat[:plug].chans[dat[:channel]][:users] = []
|
11
|
+
end
|
12
|
+
|
13
|
+
dat[:plug].chans[dat[:channel]][:users].delete dat[:target] if
|
14
|
+
dat[:plug].chans[dat[:channel]][:users].include? dat[:target]
|
15
|
+
|
16
|
+
dat[:plug].join(dat[:channel]) if dat[:target] == dat[:plug].nick
|
17
|
+
end
|