ControlledCvars

Custom Packages that plugins can require for common usages.
User avatar
iPlayer
Developer
Posts: 445
Joined: Sat Nov 14, 2015 8:37 am
Location: Moscow
Contact:

ControlledCvars

Postby iPlayer » Sat Mar 26, 2016 7:20 pm

Source.Python ControlledCvars (custom package)
Download: https://github.com/KirillMysnik/sp-controlled-cvars-package/releases/latest

What's this?
Sometimes I feel kind of uncomfortable with reading config cvars values right from the ConVar instances in my code.
Because imagine if you store some RGB value or another list in the cvar. You'll probably do something like this

Syntax: Select all

r, g, b = map(int, cvar.get_string().split(','))


But then you should also be ready to handle invalid values:

Syntax: Select all

try:
r, g, b = map(int, cvar.get_string().split(','))
except (TypeError, ValueError):
r, g, b = 0, 0, 0


Or, instead of setting r, g, b to zeros, you could've reverted them to their previous (valid) values - if any. That's even more code.
Now what if you require this list every tick? All these checks, try-excepts, resetting to default values would happen every tick.

While you could've just saved valid cvar value once it's changed in some variable:

Syntax: Select all

@Event('server_cvar')
def on_server_cvar(game_event):
if game_event['cvarname'] != cvar.name:
return

global rgb

try:
rgb = list(map(int, cvar.get_string().split(',')))
except (TypeError, ValueError):
rgb = 0, 0, 0

And then you're free from doing all these unnecessary checks every tick.

But what if you have tens of such variables? Longer server_cvar handler with more global variables? Or you could go with a dictionary - still I'm not happy.

So I made this ControlledCvars package which basically includes one class - ControlledConfigManager.

Usage

Syntax: Select all

from commands.server import ServerCommand
from core import echo_console

from controlled_cvars import ControlledConfigManager, InvalidValue


config_manager = ControlledConfigManager("cvars_test", cvar_prefix='test_')


def test_cvar_handler(cvar):
try:
r, g, b = map(int, cvar.get_string().split(','))
return r, g, b
except (TypeError, ValueError):
raise InvalidValue


test_cvar = config_manager.controlled_cvar(test_cvar_handler, "my_cvar", default="255,255,255")

config_manager.write()
config_manager.execute()


@ServerCommand('print_my_cvar')
def srv_print_my_cvar(command):
echo_console("Saved value: {}".format(config_manager["my_cvar"]))


Code: Select all

] print_my_cvar
Saved value: (255, 255, 255)
] test_my_cvar 150,150,150
Variable was updated successfully
] print_my_cvar
Saved value: (150, 150, 150)
] test_my_cvar some_invalid_value
Failed to update variable with the given value
] print_my_cvar
Saved value: (150, 150, 150)


You create a cvar with a handler that:
1. Returns value you'd want to be associated with your variable
2. Raises InvalidValue if new value doesn't fit your requirements

And then just require that value this way

Syntax: Select all

config_manager["my_cvar"]


This package also includes some pre-defined cvar handlers that may be useful
You can find them in controlled_cvars.handlers module.

bool_handler
Tries to convert variable to an integer, then to boolean.
Fails if it's impossible to convert variable to an integer.
Valid cvar example: my_boolean_cvar 1

color_handler
Tries to convert a comma-separated triple (or quadruple) variable to an Color object.
Fails if:
1. Too many integers in a list
2. Impossible to convert one of the list items to an integer
3. List integers overflow valid color component value (e.g. > 255 or < 0).
Valid cvar example: my_color_cvar 255,0,0

float_handler
Tries to convert variable to a float value.
Fails if it's impossible to do so.
Valid cvar example: my_float_cvar 42.0

int_handler
Tries to convert variable to an integer value.
Fails if it's impossible to do so.
Valid cvar example: my_integer_cvar 7

list_handler
Converts a comma-separated variable to a list object.
Does not fail.
Valid cvar example: my_list_cvar item1,item2,item3

sound_handler
Converts a path variable to a Sound object.
Does not fail.
Valid cvar example: my_sound_cvar player/suit_sprint.wav

sound_nullable_handler
Converts variable to None if it contains empty string, otherwise to Sound object.
Does not fail.
Valid cvar example: my_sound_nullable_cvar ""

string_handler
Converts variable to a string.
Does not fail.
Valid cvar example: my_string_cvar Hello, world

Hope somebody finds this useful.
Last edited by iPlayer on Sun Jul 10, 2016 9:08 am, edited 2 times in total.
Image /id/its_iPlayer
My plugins: Map Cycle • Killstreaker • DeadChat • Infinite Jumping • TripMines • arcadmin • AdPurge

Hail, Companion. [...] Hands to yourself, sneak thief. Image
User avatar
iPlayer
Developer
Posts: 445
Joined: Sat Nov 14, 2015 8:37 am
Location: Moscow
Contact:

Postby iPlayer » Sun Mar 27, 2016 6:25 pm

Moved functionality to .controlled_cvar method thus allowing to access classic .cvar method

ControlledCvars package release v1.0.0
Image /id/its_iPlayer
My plugins: Map Cycle • Killstreaker • DeadChat • Infinite Jumping • TripMines • arcadmin • AdPurge

Hail, Companion. [...] Hands to yourself, sneak thief. Image
User avatar
Ayuto
Project Leader
Posts: 1543
Joined: Sat Jul 07, 2012 8:17 am
Location: Germany

Postby Ayuto » Mon Mar 28, 2016 3:20 pm

This might be interesting for you:
https://github.com/Source-Python-Dev-Team/Source.Python/commit/3ad0dbf8127f81ab0344938923c09069abc20586

With this listener you don't need to add the notify flag anymore.
User avatar
iPlayer
Developer
Posts: 445
Joined: Sat Nov 14, 2015 8:37 am
Location: Moscow
Contact:

Postby iPlayer » Mon Mar 28, 2016 5:19 pm

Thanks, Ayuto

ControlledCvars package no longer sets "notify" flag on the cvars it controls.

ControlledCvars package release v1.1.0
Image /id/its_iPlayer
My plugins: Map Cycle • Killstreaker • DeadChat • Infinite Jumping • TripMines • arcadmin • AdPurge

Hail, Companion. [...] Hands to yourself, sneak thief. Image
User avatar
iPlayer
Developer
Posts: 445
Joined: Sat Nov 14, 2015 8:37 am
Location: Moscow
Contact:

Postby iPlayer » Tue Mar 29, 2016 7:25 pm

Added some pre-defined cvar handlers.
Package now is literally a package, not a module, thus to upgrade you need to delete controlled_cvars.py in addons/source-python/packages/custom

ControlledCvars package release v1.2.0
Image /id/its_iPlayer
My plugins: Map Cycle • Killstreaker • DeadChat • Infinite Jumping • TripMines • arcadmin • AdPurge

Hail, Companion. [...] Hands to yourself, sneak thief. Image

Return to “Custom Packages”

Who is online

Users browsing this forum: No registered users and 1 guest