v0.3.0-prod

This commit is contained in:
Mateusz Gruszczyński committed 2026-11-04 14:57:48 +01:00
1 parent 387933957e
commit 9d093b691c
21 files changed
+1239 -180

No files matched your search

+58 -1
View File
@@ -166,6 +166,55 @@ func (q *Query) CountOnline(ctx context.Context) (int, error) {
return len(clients), nil
}
// ServerInfo describes the virtual server the query connection selects via
// "use port=...". Only the fields the UI needs are parsed; everything else
// returned by the TS3 server is ignored.
type ServerInfo struct {
Name string
Version string
Platform string
Uptime time.Duration
ClientsOnline int
MaxClients int
}
func (q *Query) ServerInfo(ctx context.Context) (ServerInfo, error) {
var info ServerInfo
err := q.withConn(ctx, func(qc *queryConn) error {
lines, err := qc.run(ctx, "serverinfo")
if err != nil {
return err
}
for _, line := range lines {
for _, row := range strings.Split(line, "|") {
f := parseFields(row)
if v, ok := f["virtualserver_name"]; ok {
info.Name = v
}
if v, ok := f["virtualserver_version"]; ok {
info.Version = strings.Fields(v)[0]
}
if v, ok := f["virtualserver_platform"]; ok {
info.Platform = v
}
if v, ok := f["virtualserver_uptime"]; ok {
if secs, err := strconv.Atoi(v); err == nil {
info.Uptime = time.Duration(secs) * time.Second
}
}
if v, ok := f["virtualserver_clientsonline"]; ok {
info.ClientsOnline, _ = strconv.Atoi(v)
}
if v, ok := f["virtualserver_maxclients"]; ok {
info.MaxClients, _ = strconv.Atoi(v)
}
}
}
return nil
})
return info, err
}
func (q *Query) SendPrivateMessage(ctx context.Context, clid int, message string) error {
return q.withConn(ctx, func(qc *queryConn) error {
_, err := qc.run(ctx, "sendtextmessage targetmode=1 target="+strconv.Itoa(clid)+" msg="+escape(message))
@@ -173,7 +222,7 @@ func (q *Query) SendPrivateMessage(ctx context.Context, clid int, message string
})
}
func (q *Query) CreateChannelForClient(ctx context.Context, expected Client, adminGroupID int, name, topic, password string) (int, error) {
func (q *Query) CreateChannelForClient(ctx context.Context, expected Client, adminGroupID int, name, topic, password string, maxClients, codecQuality int) (int, error) {
var cid int
err := q.withConn(ctx, func(qc *queryConn) error {
clients, err := listClients(ctx, qc)
@@ -200,6 +249,14 @@ func (q *Query) CreateChannelForClient(ctx context.Context, expected Client, adm
if password != "" {
cmd += " channel_password=" + escape(password)
}
if maxClients > 0 {
cmd += " channel_maxclients=" + strconv.Itoa(maxClients) + " channel_flag_maxclients_unlimited=0"
} else {
cmd += " channel_flag_maxclients_unlimited=1"
}
if codecQuality > 0 {
cmd += " channel_codec_quality=" + strconv.Itoa(codecQuality)
}
lines, err := qc.run(ctx, cmd)
if err != nil {
return err
+1 -1
View File
@@ -77,7 +77,7 @@ func TestCreateChannelUsesDatabaseIDAndRefreshesClientID(t *testing.T) {
q := &Query{Addr: ln.Addr().String(), User: "u", Password: "p", VoicePort: 9987, Timeout: 2 * time.Second}
ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second)
defer cancel()
cid, err := q.CreateChannelForClient(ctx, Client{ID: 7, DatabaseID: 42, Nick: "old", UID: "abc", IP: "1.2.3.4"}, 5, "Moj kanal", "temat", "haslo")
cid, err := q.CreateChannelForClient(ctx, Client{ID: 7, DatabaseID: 42, Nick: "old", UID: "abc", IP: "1.2.3.4"}, 5, "Moj kanal", "temat", "haslo", 0, 0)
if err != nil {
t.Fatal(err)
}