protonbot 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
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