Expressions are used for Matchmaking , Serverbrowser and Lobby. They can be configured in the ZCP.
Types
Expressions are dealing with these types; float64
, bool
, string
and arrays.
All numeric literals, with or without a radix, will be converted to float64
for evaluation. For instance; in practice, there is no difference between the literals "1.0" and "1", they both end up as float64
. This matters to users because if you intend to return numeric values from your expressions, then the returned value will be float64
, not any other numeric type.
Any string literal (not parameter) which is interpretable as a date will be converted to a float64
representation of that date's unix time. Any time.Time
parameters will not be operable with these date literals; such parameters will need to use the time.Time.Unix()
method to get a numeric representation.
Arrays are untyped, and can be mixed-type. Internally they're all just interface{}
. Only two operators can interact with arrays, IN
and ,
. All other operators will refuse to operate on arrays.
Operators
Modifiers
Addition, concatenation +
+
If either left or right sides of the +
operator are a string
, then this operator will perform string concatenation and return that result. If neither are string, then both must be numeric, and this will return a numeric result.
Any other case is invalid.
Arithmetic -
*
/
**
%
-
*
/
**
%
**
refers to "take to the power of". For instance, 3 ** 4
== 81.
- Left side: numeric
- Right side: numeric
- Returns: numeric
Bitwise shifts, masks >>
<<
|
&
^
>>
<<
|
&
^
All of these operators convert their float64
left and right sides to int64
, perform their operation, and then convert back.
Given how this library assumes numeric are represented (as float64
), it is unlikely that this behavior will change, even though it may cause havoc with extremely large or small numbers.
- Left side: numeric
- Right side: numeric
- Returns: numeric
Negation -
-
Prefix only. This can never have a left-hand value.
- Right side: numeric
- Returns: numeric
Inversion !
!
Prefix only. This can never have a left-hand value.
- Right side: bool
- Returns: bool
Bitwise NOT ~
~
Prefix only. This can never have a left-hand value.
- Right side: numeric
- Returns: numeric
Logical Operators
For all logical operators, this library will short-circuit the operation if the left-hand side is sufficient to determine what to do. For instance, true || expensiveOperation()
will not actually call expensiveOperation()
, since it knows the left-hand side is true
.
Logical AND/OR &&
||
&&
||
- Left side: bool
- Right side: bool
- Returns: bool
Ternary true ?
?
Checks if the left side is true
. If so, returns the right side. If the left side is false
, returns nil
.
In practice, this is commonly used with the other ternary operator.
- Left side: bool
- Right side: Any type.
- Returns: Right side or
nil
Ternary false :
:
Checks if the left side is nil
. If so, returns the right side. If the left side is non-nil, returns the left side.
In practice, this is commonly used with the other ternary operator.
- Left side: Any type.
- Right side: Any type.
- Returns: Right side or
nil
Null coalescence ??
??
Similar to the C# operator. If the left value is non-nil, it returns that. If not, then the right-value is returned.
- Left side: Any type.
- Right side: Any type.
- Returns: No specific type - whichever is passed to it.
Comparators
Numeric/lexicographic comparators >
<
>=
<=
>
<
>=
<=
If both sides are numeric, this returns the usual greater/lesser behavior that would be expected.
If both sides are string, this returns the lexicographic comparison of the strings. This uses Go's standard lexicographic compare.
- Accepts: Left and right side must either be both string, or both numeric.
- Returns: bool
Regex comparators =~
!~
=~
!~
These use go's standard regexp
flavor of regex. The left side is expected to be the candidate string, the right side is the pattern. =~
returns whether or not the candidate string matches the regex pattern given on the right. !~
is the inverted version of the same logic.
- Left side: string
- Right side: string
- Returns: bool
Arrays
Separator ,
,
The separator, always paired with parenthesis, creates arrays. It must always have both a left and right-hand value, so for instance (, 0)
and (0,)
are invalid uses of it.
Again, this should always be used with parenthesis; like (1, 2, 3, 4)
.
Membership IN
IN
The only operator with a text name, this operator checks the right-hand side array to see if it contains a value that is equal to the left-side value.
Equality is determined by the use of the ==
operator, and this library doesn't check types between the values. Any two values, when cast to interface{}
, and can still be checked for equality with ==
will act as expected.
- Left side: Any type.
- Right side: array
- Returns: bool
Escaping characters
Sometimes you'll have parameters that have spaces, slashes, pluses, ampersands or some other character
that this library interprets as something special. For example, the following expression will not
act as one might expect:
"response-time < 100"
As written, the library will parse it as "[response] minus [time] is less than 100". In reality,
"response-time" is meant to be one variable that just happens to have a dash in it.
There are two ways to work around this. First, you can escape the entire parameter name:
"[response-time] < 100"
Or you can use backslashes to escape only the minus sign.
"response\\-time < 100"
Backslashes can be used anywhere in an expression to escape the very next character. Square bracketed parameter names can be used instead of plain parameter names at any time.
Functions
Currently the following functions are defined:
strlen("string")
- returns length of string as numbertolower("string")
- returns lowercase stringrndf()
- returns random float in [0,1]pow(x,y)
- returns a to the ymin(x,…)
- returns the min of all parametersmax(x,…)
- returns the max of all parameterscontains("string","piece")
returns true if piece is found in stringnamematch("name", "matcher")
empty matcher matches any name, equality matches, matcher can be a comma separated list, for example:namematch("US","US,EU")==true
Feel free to ask us for more functions, if needed.
Updated about a month ago