Most plugins offer configuration options, and it is helpful to make sure the user sets these to sensible values. Otherwise the plugin may behave badly, causing unpredictable results or even game errors.
Each plugin has the option to define a check_config
method in its plugin module file. For example:
module AresMUSH
module Who
...
def self.check_config
validator = WhoConfigValidator.new
validator.validate
end
...
end
end
The internals of this method are entirely up to you. All you need to do is return either:
Although you can do whatever you want within your check_config
method, the ConfigValidator
class makes your life easier.
To start with, you define your own custom validator class. For example, WhoConfigValidator
.
module AresMUSH
module Who
class WhoConfigValidator
end
end
end
Next we create a copy of the base validator for us to use. The parameter is the name of the configuration section you want to verify. This is the same value you would pass to Global.read_config(SECTION, ...)
, typically the name of your plugin.
class WhoConfigValidator
attr_accessor :validator
def initialize
@validator = Manage::ConfigValidator.new("who")
end
end
Then we implement the validate
method to perform the actual validation. The ConfigValidator class has a lot of utilities to help us out. These are described further in the next section. Always end your method with @validator.errors
. This will return the error list.
class WhoConfigValidator
...
def validate
@validator.require_list('who_fields')
@validator.errors
end
end
Finally we use this new class in our check_config
method, as shown in the example in the previous section.
There are more than a dozen validator helpers in the ConfigValidator
class. See the code for all of them. A few examples are given below just to show you how it works.
All of these require that you pass in the name of the field. This is the same thing you would pass to Global.read_config("your_section", FIELD)
.
require_text(field) |
The field must be a text string, though it may be empty. |
require_nonblank_text(field) |
The field must be a non-blank/empty text string. |
require_int(field, min, max) |
The field must be an integer between the specified min/max values (non-inclusive). Either min or max may be nil to omit that check. |
check_cron(field) |
Checks to be sure that all the fields of a cron job are valid. |
check_channel_exists(field) |
Checks to be sure that the value, if not blank, is actually a chat channel. |
You can have as many validation checks as you want in your validate
method. For example:
@validator.require_boolean('use_advantages')
@validator.require_nonblank_text('default_linked_attr')
@validator.require_int('advantages_cost', 1)
@validator.require_boolean('allow_incapable_action_skills')
... it goes on for awhile ...
You can also do your own custom checks by calling add_error
when something’s wrong. For example:
abilities.each do |name|
if (FS3Skills.check_ability_name(name))
@validator.add_error "fs3skills:attributes #{name} cannot contain special characters."
end
end
One caveat… if you’re going to do advanced checks on hashes and arrays, put them inside a begin/rescue so you don’t cause the validator to throw an error if those values are nil.
# We want to warn them if it's nil
@validator.require_hash('starting_skills')
# But also guard ourselves against it being nil.
begin
start_skills = Global.read_config('fs3skills', 'starting_skills')
...
rescue Exception => ex
@validator.add_error "Unknown FS3Skills config error. Fix other errors first and try again. #{ex} #{ex.backtrace[0]}"
end