Files
go-ts/pkg/protocol/commands.go

91 lines
1.5 KiB
Go
Raw Normal View History

2026-01-15 16:49:16 +01:00
package protocol
import (
"strings"
)
// Command Parsing Helpers
func ParseCommand(data []byte) (string, map[string]string) {
s := string(data)
parts := strings.Split(s, " ")
cmd := parts[0]
args := make(map[string]string)
for _, p := range parts[1:] {
kv := strings.SplitN(p, "=", 2)
if len(kv) == 2 {
val := Unescape(kv[1])
args[kv[0]] = val
} else {
args[p] = ""
}
}
return cmd, args
}
// Unescape TS3 string
func Unescape(s string) string {
r := strings.NewReplacer(
`\/`, `/`,
`\s`, ` `,
`\p`, `|`,
`\a`, "\a",
`\b`, "\b",
`\f`, "\f",
`\n`, "\n",
`\r`, "\r",
`\t`, "\t",
`\v`, "\v",
`\\`, `\`,
)
return r.Replace(s)
}
func Escape(s string) string {
r := strings.NewReplacer(
`\`, `\\`,
`/`, `\/`,
` `, `\s`,
`|`, `\p`,
"\a", `\a`,
"\b", `\b`,
"\f", `\f`,
"\n", `\n`,
"\r", `\r`,
"\t", `\t`,
"\v", `\v`,
)
return r.Replace(s)
}
// Command represents a TeamSpeak 3 command for building/encoding
type Command struct {
Name string
Params map[string]string
}
func NewCommand(name string) *Command {
return &Command{
Name: name,
Params: make(map[string]string),
}
}
func (c *Command) AddParam(key, value string) {
c.Params[key] = value
}
func (c *Command) Encode() string {
var sb strings.Builder
sb.WriteString(c.Name)
for k, v := range c.Params {
sb.WriteString(" ")
sb.WriteString(k)
if v != "" {
sb.WriteString("=")
sb.WriteString(Escape(v))
}
}
return sb.String()
}