protonbot 0.1.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.
Files changed (54) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +13 -0
  3. data/.rubocop.yml +38 -0
  4. data/CODE_OF_CONDUCT.md +74 -0
  5. data/CONFIG.md +45 -0
  6. data/CORE_PLUGIN.md +128 -0
  7. data/Gemfile +7 -0
  8. data/LICENSE.txt +21 -0
  9. data/PLUGIN.md +45 -0
  10. data/README.md +81 -0
  11. data/Rakefile +2 -0
  12. data/bin/console +14 -0
  13. data/bin/setup +8 -0
  14. data/exe/protonbot-gencert +7 -0
  15. data/lib/protonbot/bot.rb +64 -0
  16. data/lib/protonbot/bot_conf.rb +48 -0
  17. data/lib/protonbot/bot_plugins.rb +110 -0
  18. data/lib/protonbot/core_plugin/apis/help.rb +54 -0
  19. data/lib/protonbot/core_plugin/apis/index.rb +2 -0
  20. data/lib/protonbot/core_plugin/apis/perms.rb +118 -0
  21. data/lib/protonbot/core_plugin/codes/index.rb +3 -0
  22. data/lib/protonbot/core_plugin/codes/names.rb +21 -0
  23. data/lib/protonbot/core_plugin/codes/welcome.rb +7 -0
  24. data/lib/protonbot/core_plugin/codes/whois.rb +9 -0
  25. data/lib/protonbot/core_plugin/commands/admin.rb +107 -0
  26. data/lib/protonbot/core_plugin/commands/basic.rb +9 -0
  27. data/lib/protonbot/core_plugin/commands/cross.rb +40 -0
  28. data/lib/protonbot/core_plugin/commands/help.rb +25 -0
  29. data/lib/protonbot/core_plugin/commands/index.rb +6 -0
  30. data/lib/protonbot/core_plugin/commands/joinpart.rb +25 -0
  31. data/lib/protonbot/core_plugin/commands/perms.rb +50 -0
  32. data/lib/protonbot/core_plugin/hooks/ctcp.rb +9 -0
  33. data/lib/protonbot/core_plugin/hooks/index.rb +7 -0
  34. data/lib/protonbot/core_plugin/hooks/joinpart.rb +42 -0
  35. data/lib/protonbot/core_plugin/hooks/kick.rb +17 -0
  36. data/lib/protonbot/core_plugin/hooks/nick.rb +10 -0
  37. data/lib/protonbot/core_plugin/hooks/ping.rb +3 -0
  38. data/lib/protonbot/core_plugin/hooks/privmsg.rb +62 -0
  39. data/lib/protonbot/core_plugin/hooks/raw.rb +32 -0
  40. data/lib/protonbot/core_plugin/plugin.rb +10 -0
  41. data/lib/protonbot/event_lock.rb +25 -0
  42. data/lib/protonbot/hook.rb +22 -0
  43. data/lib/protonbot/log.rb +182 -0
  44. data/lib/protonbot/log_wrapper.rb +52 -0
  45. data/lib/protonbot/numeric.rb +140 -0
  46. data/lib/protonbot/plug.rb +118 -0
  47. data/lib/protonbot/plug_events.rb +51 -0
  48. data/lib/protonbot/plug_io.rb +99 -0
  49. data/lib/protonbot/plug_utils.rb +242 -0
  50. data/lib/protonbot/plugin.rb +101 -0
  51. data/lib/protonbot/version.rb +4 -0
  52. data/lib/protonbot.rb +38 -0
  53. data/protonbot.gemspec +31 -0
  54. 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,2 @@
1
+ run 'apis/perms'
2
+ run 'apis/help'
@@ -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,3 @@
1
+ run 'codes/names'
2
+ run 'codes/welcome'
3
+ run 'codes/whois'
@@ -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,7 @@
1
+ hook(type: :code, code: @numeric::WELCOME) do |dat|
2
+ if dat[:plug].conf['autojoin']
3
+ dat[:plug].conf['autojoin'].map do |e|
4
+ dat[:plug].join(e.to_s)
5
+ end
6
+ end
7
+ 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,9 @@
1
+ core.help_add('basic', 'ping', 'ping', 'Ping!')
2
+ cmd(cmd: 'ping') do |dat|
3
+ dat.reply("#{dat[:nick]}: pong!")
4
+ end
5
+
6
+ core.help_add('basic', 'echo', 'echo', 'Sends given message back')
7
+ cmd(cmd: 'echo') do |dat|
8
+ dat.reply("#{dat[:split].join(' ')}")
9
+ end
@@ -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,6 @@
1
+ run 'commands/admin'
2
+ run 'commands/basic'
3
+ run 'commands/cross'
4
+ run 'commands/joinpart'
5
+ run 'commands/help'
6
+ run 'commands/perms'
@@ -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,7 @@
1
+ run 'hooks/raw'
2
+ run 'hooks/ping'
3
+ run 'hooks/kick'
4
+ run 'hooks/privmsg'
5
+ run 'hooks/ctcp'
6
+ run 'hooks/joinpart'
7
+ run 'hooks/nick'
@@ -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