74 lines
1.2 KiB
Go
74 lines
1.2 KiB
Go
package commands
|
|
|
|
import (
|
|
"strings"
|
|
)
|
|
|
|
func ParseCommand(s string) *Command {
|
|
if s == "" {
|
|
return nil
|
|
}
|
|
|
|
startIndex := 0
|
|
for i := range len(s) {
|
|
if s[i] >= 32 && s[i] <= 126 {
|
|
startIndex = i
|
|
|
|
break
|
|
}
|
|
}
|
|
if startIndex > 0 {
|
|
s = s[startIndex:]
|
|
}
|
|
|
|
parts := strings.Split(s, " ")
|
|
if len(parts) == 0 {
|
|
return nil
|
|
}
|
|
|
|
cmd := &Command{
|
|
Params: make(map[string]string),
|
|
}
|
|
|
|
// TS3 list responses (clientlist, channellist) arrive as nameless rows of
|
|
// key=value pairs. Only treat the first token as a command name when it is
|
|
// NOT a key=value pair; otherwise every token is a parameter.
|
|
start := 0
|
|
if !strings.Contains(parts[0], "=") {
|
|
cmd.Name = parts[0]
|
|
start = 1
|
|
}
|
|
|
|
for _, p := range parts[start:] {
|
|
if p == "" {
|
|
continue
|
|
}
|
|
kv := strings.SplitN(p, "=", 2)
|
|
if len(kv) == 2 {
|
|
cmd.Params[Unescape(kv[0])] = Unescape(kv[1])
|
|
} else {
|
|
cmd.Params[Unescape(p)] = ""
|
|
}
|
|
}
|
|
|
|
return cmd
|
|
}
|
|
|
|
var unescaper = strings.NewReplacer(
|
|
"\\\\", "\\",
|
|
"\\/", "/",
|
|
"\\s", " ",
|
|
"\\p", "|",
|
|
"\\a", "\a",
|
|
"\\b", "\b",
|
|
"\\f", "\f",
|
|
"\\n", "\n",
|
|
"\\r", "\r",
|
|
"\\t", "\t",
|
|
"\\v", "\v",
|
|
)
|
|
|
|
func Unescape(s string) string {
|
|
return unescaper.Replace(s)
|
|
}
|