Browse Source

Document all code with YARDoc

Marrub 2 years ago
parent
commit
e912898dd0
8 changed files with 184 additions and 32 deletions
  1. 1
    0
      .gitignore
  2. 1
    0
      .yardopts
  3. 6
    1
      README
  4. 17
    3
      source/common.rb
  5. 4
    0
      source/main.rb
  6. 64
    11
      source/module.rb
  7. 69
    14
      source/server.rb
  8. 22
    3
      source/sv_discord.rb

+ 1
- 0
.gitignore View File

@@ -1,3 +1,4 @@
1
+*doc
1 2
 working
2 3
 *.yml
3 4
 *.swp

+ 1
- 0
.yardopts View File

@@ -0,0 +1 @@
1
+--protected source/*.rb - README

+ 6
- 1
README View File

@@ -1 +1,6 @@
1
-words
1
+Mod_Audio requires:
2
+- youtube-dl.rb
3
+- streamio-ffmpeg
4
+
5
+Sv_Discord requires:
6
+- discordrb

+ 17
- 3
source/common.rb View File

@@ -1,10 +1,19 @@
1
+# Module for the main vrobot4 program and global info.
1 2
 module Vrobot4
3
+   # The current program version.
2 4
    Version = "4.00".freeze
3 5
 
4
-   @@debug = 0
5
-   def self.debug= set; @@debug = set; end
6
-   def self.debug     ; @@debug;       end
6
+   def self.debug=(set) @@debug = set end # Sets the current debug level.
7
+   def self.debug (   ) @@debug       end # Gets the current debug level.
7 8
 
9
+   # Logs to the console.
10
+   #
11
+   # @param lv [Symbol]
12
+   #  - If +:DEBUG+, this message will not be printed if the global debug
13
+   #    level is less than 1.
14
+   #  - If +:DEBUGV+, this message will not be printed if the global debug
15
+   #    level is less than 2.
16
+   # @return [Boolean] true if the message was printed, false otherwise
8 17
    def self.log lv, *text
9 18
       if (lv != :DEBUG  || @@debug >= 1) &&
10 19
          (lv != :DEBUGV || @@debug >= 2)
@@ -15,9 +24,14 @@ module Vrobot4
15 24
       end
16 25
    end
17 26
 
27
+   # Checks if the argument +s+ is a numeric string.
28
+   # @param str [String] the string to check
18 29
    def self.is_num? str
19 30
       /\A[-+]?[0-9]*\.?[0-9]+\Z/ === str
20 31
    end
32
+
33
+   private
34
+   @@debug = 0
21 35
 end
22 36
 
23 37
 ## EOF

+ 4
- 0
source/main.rb View File

@@ -5,6 +5,7 @@ require './server.rb'
5 5
 require 'yaml'
6 6
 
7 7
 module Vrobot4
8
+   private
8 9
    def self.loadServer servinfo
9 10
       type = servinfo["type"]
10 11
 
@@ -30,6 +31,9 @@ module Vrobot4
30 31
       thrds.each {|th| th.join}
31 32
    end
32 33
 
34
+   public
35
+   # Runs the program.
36
+   # @param cfg [IO] configuration file to load
33 37
    def self.main cfg
34 38
       log :INFO, "vrobot version", Version
35 39
 

+ 64
- 11
source/module.rb View File

@@ -1,13 +1,20 @@
1
+# Module for vrobot4 bot modules.
1 2
 module Vrobot4::Module
3
+   # A command function. Holds extra info for i.e. permissions.
2 4
    class Command
3
-      attr_reader :help_str
5
+      attr_reader :help_str # Help string for this command.
4 6
 
7
+      # @param fn [Method] method to be called on run
8
+      # @param help [String] help string for this command
9
+      # @param roles [String] list of roles that can use this command
5 10
       def initialize fn, help, roles
6 11
          @function = fn
7 12
          @help_str = help
8 13
          @roles    = /[#{roles}]/
9 14
       end
10 15
 
16
+      # Checks if this command is usable in a given context.
17
+      # @param m [Vrobot4::Server::Message] message for context
11 18
       def usable_in? m
12 19
          type = @function.owner
13 20
          role = m.user.roles
@@ -19,27 +26,33 @@ module Vrobot4::Module
19 26
          role.scan(@roles).any? and (retm or retc or retr)
20 27
       end
21 28
 
29
+      # Calls the method attached to this command.
22 30
       def run m, argv
23 31
          @function.call(m, argv)
24 32
       end
25 33
    end
26 34
 
35
+   # A bot module. Holds commands and callbacks.
27 36
    class Module
37
+      # @param info [Hash] arbitrary extra information for this module
28 38
       def initialize info
29 39
          @commands = {}
30 40
          @info = info
31 41
          Vrobot4.log :DEBUG, "initialized", self.to_s
32 42
       end
33 43
 
34
-      def register fn, cnam, help = nil, roles: "v"
35
-         help = "No help available for this command." if help == nil
36
-         @commands[cnam] = Command.new(self.method(fn), help, roles).freeze
37
-      end
38
-
44
+      # Callback for message receiving.
45
+      # @param m [Vrobot4::Server::Message] message received
46
+      # @return [Boolean] if this should block further message callbacks
39 47
       def on_message m
40 48
          false
41 49
       end
42 50
 
51
+      # Callback for command receiving.
52
+      # @param m [Vrobot4::Server::Message] message that triggered this call
53
+      # @param cnam [String] name of command to call
54
+      # @param argv [Array] array of string arguments
55
+      # @return [Boolean] if this should block further command callbacks
43 56
       def on_command m, cnam, argv
44 57
          if (cmd = get_cmd m, cnam)
45 58
             begin;  cmd.run(m, argv)
@@ -50,16 +63,48 @@ module Vrobot4::Module
50 63
          end
51 64
       end
52 65
 
66
+      # Gets all commands usable in a specified context.
67
+      # @param m [Vrobot4::Server::Message] message for context
68
+      # @return [Hash] a hash of all commands by name
53 69
       def all_cmds m
54 70
          @commands.select {|name, cmd| cmd.usable_in? m}
55 71
       end
56 72
 
73
+      # Gets a command by name in a specified context.
74
+      # @param m [Vrobot4::Server::Message] message for context
75
+      # @return [Vrobot4::Module::Command] command if found, nil if not
57 76
       def get_cmd m, name
58 77
          cmds = all_cmds(m)
59 78
          cmds[name] if cmds.key? name
60 79
       end
61 80
 
62 81
       protected
82
+      # Registers a command into this module.
83
+      # @param fn [Symbol] name of method to add
84
+      # @param names [String, Array] name(s) to add this command by
85
+      # @param help [String] help string to use for this command
86
+      # @param roles [String] roles to allow this command to use
87
+      # @return [Vrobot4::Module::Command] command added
88
+      def register fn, names, help = nil, roles: "v"
89
+         help = "No help available for this command." if help == nil
90
+         cmd = Command.new(self.method(fn), help, roles).freeze
91
+         if names.is_a? String
92
+            @commands[names] = cmd
93
+         else
94
+            names.each {|name| @commands[name] = cmd}
95
+         end
96
+         cmd
97
+      end
98
+
99
+      # Check argument validity and count.
100
+      #
101
+      # Specifiers include:
102
+      # [N] A number.
103
+      # [S] An arbitrary string.
104
+      #
105
+      # @param argv [Array] array of arguments
106
+      # @param req [String] specifier string of required arguments
107
+      # @param opt [String] specifier string of optional arguments
63 108
       def check_args argv, req, opt = ""
64 109
          if argv.length < req.length
65 110
             raise ArgumentError, "Not enough arguments"
@@ -80,15 +125,17 @@ module Vrobot4::Module
80 125
       def check_arg arg, i, req
81 126
          case req
82 127
          when 'N'
83
-            unless Vrobot4.is_num? arg
128
+            unless Vrobot4.is_num? arg.strip
84 129
                raise ArgumentError, "Expected a number for arg " + i.to_s
85 130
             end
86 131
          end
87 132
       end
88 133
    end
89 134
 
90
-   @@module_types = {}
91
-
135
+   # Adds a module type to the global list.
136
+   # @param type [Class] module type to add
137
+   # @param server [String] server type this module is restricted to (or none)
138
+   # @param servflags [String] flags the server must have to use this (or none)
92 139
    def self.add_module_type type, server: nil, servflags: nil
93 140
       @@module_types[type.type] = {
94 141
          type:      type,
@@ -98,9 +145,15 @@ module Vrobot4::Module
98 145
       Vrobot4.log :INFO, "added module type:", type.type
99 146
    end
100 147
 
101
-   def self.get_module_type s
102
-      @@module_types[s]
148
+   # Gets a module type by name from the global list.
149
+   # @param name [String] name of the module type to find
150
+   # @return [Hash] a hash containing info about the type
151
+   def self.get_module_type name
152
+      @@module_types[name]
103 153
    end
154
+
155
+   private
156
+   @@module_types = {}
104 157
 end
105 158
 
106 159
 ## EOF

+ 69
- 14
source/server.rb View File

@@ -1,3 +1,4 @@
1
+# Module for vrobot4 server interfaces.
1 2
 module Vrobot4::Server
2 3
    class Mod_Base < Vrobot4::Module::Module
3 4
       def initialize info
@@ -10,6 +11,7 @@ module Vrobot4::Server
10 11
          register :c_dbg,  "dbg",  "Sets the debug level.",    roles: "o"
11 12
       end
12 13
 
14
+      # @!visibility private
13 15
       def c_help m, argv
14 16
          check_args argv, "", "S"
15 17
          if argv.length == 0
@@ -28,6 +30,7 @@ module Vrobot4::Server
28 30
          end
29 31
       end
30 32
 
33
+      # @!visibility private
31 34
       def c_die m, argv
32 35
          m.serv.voice_quit m if m.serv.flags.include? "A"
33 36
          m.reply \
@@ -42,6 +45,7 @@ module Vrobot4::Server
42 45
          exit
43 46
       end
44 47
 
48
+      # @!visibility private
45 49
       def c_modr m, argv
46 50
          check_args argv, "S", "S"
47 51
          m.serv.drop_mod argv[0]
@@ -49,38 +53,57 @@ module Vrobot4::Server
49 53
          m.serv.load_mod argv[0]
50 54
       end
51 55
 
56
+      # @!visibility private
52 57
       def c_modl m, argv
53 58
          check_args argv, "S"
54 59
          m.serv.load_mod argv[0]
55 60
       end
56 61
 
62
+      # @!visibility private
57 63
       def c_modu m, argv
58 64
          check_args argv, "S"
59 65
          m.serv.drop_mod argv[0]
60 66
       end
61 67
 
68
+      # @!visibility private
62 69
       def c_dbg m, argv
63 70
          check_args argv, "N"
64 71
          Vrobot4.debug = argv[0].to_i
65 72
       end
66 73
 
74
+      # @!visibility private
67 75
       def on_command m, cnam, argv
68 76
          Vrobot4.log :DEBUGV, "command", cnam.to_s, argv.to_s
69 77
          super
70 78
       end
71 79
    end
80
+   private_constant :Mod_Base
72 81
 
82
+   # Generic user information. May be extended.
73 83
    class User
74
-      attr_reader :name, :roles
84
+      attr_reader :name  # Plaintext name of the user.
85
+      attr_reader :roles # List of user's roles.
75 86
    end
76 87
 
88
+   # Generic channel information. May be extended.
77 89
    class Channel
78
-      attr_reader :name
90
+      attr_reader :name # Plaintext name of the channel.
79 91
    end
80 92
 
93
+   # Generic event information. May not be extended.
81 94
    class Message
82
-      attr_reader :msg, :user, :chan, :serv
83
-
95
+      attr_reader :msg  # Plaintext of message (if any.)
96
+      attr_reader :user # User that triggered this message (if any.)
97
+      attr_reader :chan # Channel this message was sent to (if any.)
98
+      attr_reader :serv # Server this message was sent to.
99
+
100
+      # @param info [Hash] A hash containing message info. Keys may be omitted.
101
+      #  [:msg]     Plaintext of message.
102
+      #  [:user]    User that triggered this message.
103
+      #  [:chan]    Channel that this message was sent to.
104
+      #  [:serv]    Server this message was sent to.
105
+      #  [:reply]   Method that sends a message to the specified channel.
106
+      #  [:reply_b] Method that sends a large message to the specified channel.
84 107
       def initialize(**info)
85 108
          @msg     = info[:msg]     if info.key? :msg
86 109
          @user    = info[:user]    if info.key? :user
@@ -90,24 +113,29 @@ module Vrobot4::Server
90 113
          @reply_b = info[:reply_b] if info.key? :reply_b
91 114
       end
92 115
 
116
+      # Sends a message to the channel this message originated from.
93 117
       def reply *args
94 118
          @reply.call args.join(" ")
95 119
       end
96 120
 
121
+      # Sends a large message to the channel this message originated from.
97 122
       def reply_b *args
98 123
          @reply_b.call args.join(" ")
99 124
       end
100 125
    end
101 126
 
127
+   # Generic server interface.
102 128
    class Server
103
-      attr_reader :mprm
129
+      attr_reader :mprm # Module permissions for this server.
104 130
 
131
+      # @param info [Hash] arbitrary extra information for this server
105 132
       def initialize info
106 133
          @info = info
107 134
          @modules = [Mod_Base.new(nil)]
108 135
          load_permissions info["permissions"] if info.key? "permissions"
109 136
       end
110 137
 
138
+      # Loads and initializes a module into the load list.
111 139
       def load_mod mod
112 140
          mt = Vrobot4::Module.get_module_type(mod)
113 141
          if mt[:server]    and mt[:server]    != self.class.type or
@@ -117,6 +145,7 @@ module Vrobot4::Server
117 145
          @modules << mt[:type].new(@info.key?(mod) ? @info[mod] : nil)
118 146
       end
119 147
 
148
+      # Drops a module from the load list.
120 149
       def drop_mod mod
121 150
          mt = Vrobot4::Module.get_module_type(mod)
122 151
          @modules.each_index do |i|
@@ -124,60 +153,86 @@ module Vrobot4::Server
124 153
          end
125 154
       end
126 155
 
156
+      # Yields for every module loaded in the server.
127 157
       def each_mod
128 158
          @modules.each {|mod| yield mod}
129 159
       end
130 160
 
161
+      # (see Vrobot4::Module::Module#on_message)
162
+      # @note Passes information to all modules.
131 163
       def on_message m
132 164
          @modules.each {|mod| break if mod.on_message m}
133 165
       end
134 166
 
167
+      # (see Vrobot4::Module::Module#on_command)
168
+      # @note Passes information to all modules.
135 169
       def on_command m, cnam, argv
136 170
          @modules.each {|mod| break if mod.on_command m, cnam, argv}
137 171
       end
138 172
 
173
+      # Connect to the server.
174
+      def connect
175
+         raise NotImplementedError, "Server#connect not implemented"
176
+      end
177
+
178
+      # Flags for this server.
179
+      # @return [String]
139 180
       def flags
140 181
          ""
141 182
       end
142 183
 
143 184
       protected
185
+      # Implementation defined permission loader.
186
+      # Loads information into +@mprm+.
144 187
       def load_permissions pinf
145
-         raise NotImplementedError, "Server::#load_permissions not implemented"
188
+         raise NotImplementedError, "Server#load_permissions not implemented"
146 189
       end
147 190
    end
148 191
 
192
+   # Basis for an audio-enabled server interface.
149 193
    class AudioServer < Server
194
+      # Joins a voice channel, using a message for context.
150 195
       def voice_join m
151
-         raise NotImplementedError, "AudioServer::#voice_join not implemented"
196
+         raise NotImplementedError, "AudioServer#voice_join not implemented"
152 197
       end
153 198
 
199
+      # Quits a voice channel, using a message for context.
154 200
       def voice_quit m
155
-         raise NotImplementedError, "AudioServer::#voice_quit not implemented"
201
+         raise NotImplementedError, "AudioServer#voice_quit not implemented"
156 202
       end
157 203
 
204
+      # Plays an arbitrary audio file in a given context.
158 205
       def play m, io
159
-         raise NotImplementedError, "AudioServer::#play not implemented"
206
+         raise NotImplementedError, "AudioServer#play not implemented"
160 207
       end
161 208
 
209
+      # Check if the bot is playing audio in a given context.
162 210
       def is_playing? m
163
-         raise NotImplementedError, "AudioServer::#is_playing? not implemented"
211
+         raise NotImplementedError, "AudioServer#is_playing? not implemented"
164 212
       end
165 213
 
214
+      # (see Vrobot4::Server::Server#flags)
166 215
       def flags
167 216
          "A"
168 217
       end
169 218
    end
170 219
 
171
-   @@server_types = {}
172
-
220
+   # Adds a server type to the global list.
221
+   # @param type [Class] server type to add
173 222
    def self.add_server_type type
174 223
       @@server_types[type.type] = type
175 224
       Vrobot4.log :INFO, "added server type:", type.type
176 225
    end
177 226
 
178
-   def self.get_server_type s
179
-      @@server_types[s]
227
+   # Gets a server type by name from the global list.
228
+   # @param name [String] name of the server type to find
229
+   # @return [Vrobot4::Server::Server] the server type
230
+   def self.get_server_type name
231
+      @@server_types[name]
180 232
    end
233
+
234
+   private
235
+   @@server_types = {}
181 236
 end
182 237
 
183 238
 ## EOF

+ 22
- 3
source/sv_discord.rb View File

@@ -1,14 +1,17 @@
1 1
 require 'discordrb'
2 2
 
3
+# A server implementation for Discord using discordrb.
3 4
 class Sv_Discord < Vrobot4::Server::AudioServer
5
+   # The server type name.
4 6
    def self.type
5 7
       "Discord"
6 8
    end
7 9
 
8 10
    Vrobot4::Server.add_server_type self
9 11
 
10
-   attr_reader :bot
12
+   attr_reader :bot # The Discordrb::Bot instance.
11 13
 
14
+   # (see Vrobot4::Server::Server#initialize)
12 15
    def initialize info
13 16
       super
14 17
 
@@ -41,16 +44,19 @@ class Sv_Discord < Vrobot4::Server::AudioServer
41 44
       end
42 45
    end
43 46
 
47
+   # (see Vrobot4::Server::AudioServer#voice_join)
44 48
    def voice_join m
45 49
       chan = m.user.real.voice_channel
46 50
       raise RuntimeError, "You're not in a voice channel" unless chan
47 51
       @bot.voice_connect chan
48 52
    end
49 53
 
54
+   # (see Vrobot4::Server::AudioServer#voice_join)
50 55
    def voice_quit m
51 56
       @bot.voice_destroy m.chan.real.server.id
52 57
    end
53 58
 
59
+   # (see Vrobot4::Server::AudioServer#play)
54 60
    def play m, io
55 61
       v = @bot.voice(m.chan.real)
56 62
       raise ArgumentError, "Invalid i/o stream" unless io
@@ -58,20 +64,24 @@ class Sv_Discord < Vrobot4::Server::AudioServer
58 64
       v.play_stream io
59 65
    end
60 66
 
67
+   # (see Vrobot4::Server::AudioServer#is_playing?)
61 68
    def is_playing? m
62 69
       v = @bot.voice(m.chan.real)
63 70
       v != nil and v.playing?
64 71
    end
65 72
 
73
+   # (see Vrobot4::Server::Server#connect)
66 74
    def connect
67 75
       @bot.run
68 76
    end
69 77
 
78
+   # (see Vrobot4::Server::Server#flags)
70 79
    def flags
71 80
       "AD"
72 81
    end
73 82
 
74 83
    protected
84
+   # (see Vrobot4::Server::Server#load_permissions)
75 85
    def load_permissions pinf
76 86
       @mprm = {chan: {}, role: {}, glob: {}}
77 87
       pinf.each do |perm|
@@ -92,19 +102,26 @@ class Sv_Discord < Vrobot4::Server::AudioServer
92 102
          @cprm = {}
93 103
       end
94 104
 
105
+      # Returns true if the channel is enabled, false otherwise.
95 106
       def [] chan
96 107
          (@cprm.key? chan.name    and @cprm[chan.name]) or
97 108
          (@cprm.key? chan.real.id and @cprm[chan.real.id])
98 109
       end
99 110
 
111
+      # Sets a channel's permission on/off.
100 112
       def []= chan, set
101 113
          @cprm[chan] = set
102 114
       end
103 115
    end
116
+   private_constant :ChannelPerms
104 117
 
118
+   # A Discord user.
105 119
    class User < Vrobot4::Server::User
106
-      attr_reader :real
120
+      attr_reader :real # The Discordrb::User instance.
107 121
 
122
+      # @param user [Discordrb::User] the discord user
123
+      # @param ops [Array] list of operator role IDs
124
+      # @param hop [Array] list of half-operator role IDs
108 125
       def initialize user, ops, hop
109 126
          @real  = user
110 127
          @name  = user.name
@@ -121,9 +138,11 @@ class Sv_Discord < Vrobot4::Server::AudioServer
121 138
       end
122 139
    end
123 140
 
141
+   # A Discord channel.
124 142
    class Channel < Vrobot4::Server::Channel
125
-      attr_reader :real
143
+      attr_reader :real # The Discordrb::Channel instance.
126 144
 
145
+      # @param chan [Discordrb::Channel] the discord channel
127 146
       def initialize chan
128 147
          @real = chan
129 148
          @name = "#" + chan.name

Loading…
Cancel
Save