using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace axXez.TS3.Protocol
{
public partial class QueryClient
{
///
/// Authenticates with the TeamSpeak 3 Server instance using the given ServerQuery credentials.
///
/// Required permission: b_serverquery_login
/// The ServerQuery login name (client_login_name).
/// The ServerQuery login password (client_login_password).
/// true on success, false on error.
public bool Login(string loginName, string password)
=> SendCommand($"login client_login_name={loginName.ToTsFormat()} client_login_password={password.ToTsFormat()}");
///
/// Deselects the active virtual server and logs out from the server instance.
///
/// Required permission: b_serverquery_login
/// true on success, false on error.
public bool Logout()
=> SendCommand($"logout");
///
/// Displays version, build number, and platform of the server.
///
///
/// A object, or null on error.
public VersionInfo Version()
{
if (SendCommand($"version", out QueryResponse res))
return res.Get();
return null;
}
///
/// Displays detailed connection info about the server instance including uptime, number of
/// virtual servers online, and traffic statistics.
///
/// Required permission: b_serverinstance_info_view
/// A object, or null on error.
public HostInfo Hostinfo()
{
if (SendCommand($"hostinfo", out QueryResponse res))
return res.Get();
return null;
}
///
/// Displays the server instance configuration including database revision, file transfer
/// port, and default group IDs.
///
/// Required permission: b_serverinstance_info_view
/// An object, or null on error.
public InstanceInfo InstanceInfo()
{
if (SendCommand($"instanceinfo", out QueryResponse res))
return res.Get();
return null;
}
///
/// Changes the server instance configuration using the given properties.
///
/// Required permission: b_serverinstance_modify_settings
/// Dictionary of instance property key-value pairs to update.
/// true on success, false on error.
public bool InstanceEdit(Dictionary properties = null)
=> SendCommand("instanceedit", properties);
///
/// Displays a list of IP addresses used by the server instance on multi-homed machines.
///
/// Required permission: b_serverinstance_binding_list
///
/// The subsystem to list bindings for: "voice", "query", or
/// "filetransfer". Defaults to "voice" when empty.
///
/// A list of dictionaries containing IP entries, or null on error.
public List> BindingList(string subsystem = "")
{
string option = !string.IsNullOrEmpty(subsystem) ? $"subsystem={subsystem}" : "";
if (SendCommand($"bindinglist {option}", out QueryResponse res))
return res.ToDictionaryList();
return null;
}
///
/// Selects the virtual server specified by or .
/// The ServerQuery client appears on the server like a real client, but cannot send or receive voice.
///
/// Required permission: b_virtualserver_select
/// The virtual server database ID (sid). Use -1 to select by port instead.
/// The virtual server UDP port (port). Used when is -1.
///
/// When true, sends the -virtual flag. Starts the server in virtual mode
/// (allows configuration without clients connecting).
///
///
/// Sets the ServerQuery client's display name on the virtual server (client_nickname).
///
/// true on success, false on error.
public bool Use(int serverID = -1, int port = -1, bool virtualServer = false, string clientNickname = null)
{
var sb = new StringBuilder();
if (serverID != -1)
sb.Append($"sid={serverID} ");
if (port != -1)
sb.Append($"port={port} ");
if (virtualServer)
sb.Append("-virtual ");
if (!string.IsNullOrEmpty(clientNickname))
sb.Append($"client_nickname={clientNickname.ToTsFormat()} ");
return SendCommand($"use {sb}");
}
///
/// Displays a list of virtual servers including their ID, status, and number of clients online.
///
/// Required permission: b_serverinstance_virtualserver_list
///
/// When true, sends -short to exclude clients online, max clients, uptime,
/// name, autostart, and machine ID fields.
///
/// When true, sends -all to list all servers regardless of machine ID.
/// When true, sends -onlyoffline to list only offline servers.
/// When true, sends -uid to include the unique identifier.
/// A list of objects, or null on error.
public List ServerList(bool simple = false, bool all = false, bool onlyOffline = false, bool uid = false)
{
var sb = new StringBuilder();
if (simple) sb.Append("-short ");
if (all) sb.Append("-all ");
if (onlyOffline) sb.Append("-onlyoffline ");
if (uid) sb.Append("-uid ");
if (SendCommand($"serverlist {sb}", out QueryResponse res))
return res.GetAll();
return null;
}
///
/// Displays the database ID of the virtual server running on the given UDP port.
///
/// Required permission: b_serverinstance_virtualserver_list
/// The virtual server's UDP port (virtualserver_port).
/// The server database ID, or -1 on error.
public int GetServerIDByPort(int port)
{
if (SendCommand($"serveridgetbyport virtualserver_port={port}", out QueryResponse res))
return res.Get("server_id");
return -1;
}
///
/// Deletes the virtual server with the given ID. The server must be in a stopped state.
///
/// Required permission: b_virtualserver_delete
/// The virtual server database ID (sid).
/// true on success, false on error.
public bool DeleteServer(int ID)
=> SendCommand($"serverdelete sid={ID}");
///
/// Creates a new virtual server and returns its ID, port, and initial administrator privilege key.
/// If virtualserver_port is not specified in , the first
/// available UDP port starting from 9987 is used.
///
/// Required permission: b_virtualserver_create
/// The name of the new virtual server (virtualserver_name).
/// Additional server properties to set on creation.
/// A object with sid, port, and token, or null on error.
public ServerCreatedInfo CreateServer(string name, EditServerProperties properties)
{
if (SendCommand($"servercreate virtualserver_name={TsEncoding.Escape(name)}", properties.changes, out QueryResponse res))
return res.Get();
return null;
}
///
/// Starts the virtual server with the given ID.
///
/// Required permissions: b_virtualserver_start_any, b_virtualserver_start
/// The virtual server database ID (sid).
/// true on success, false on error.
public bool StartServer(int ID)
=> SendCommand($"serverstart sid={ID}");
///
/// Stops the virtual server with the given ID. Optionally sends a reason message to
/// connected clients before they are disconnected.
///
/// Required permissions: b_virtualserver_stop_any, b_virtualserver_stop
/// The virtual server database ID (sid).
///
/// Text message sent to all connected clients before disconnect (reasonmsg).
/// Leave empty to send no message.
///
/// true on success, false on error.
public bool StopServer(int ID, string reasonMsg = "")
{
string option = !string.IsNullOrEmpty(reasonMsg) ? $"reasonmsg={reasonMsg.ToTsFormat()}" : "";
return SendCommand($"serverstop sid={ID} {option}");
}
///
/// Stops the entire TeamSpeak 3 Server instance by shutting down the process. Optionally
/// sends a reason message to all connected clients before disconnect.
///
/// Required permission: b_serverinstance_stop
///
/// Text message sent to all connected clients before disconnect (reasonmsg).
/// Leave empty to send no message.
///
/// true on success, false on error.
public bool StopServerProcess(string reasonMsg = "")
{
string option = !string.IsNullOrEmpty(reasonMsg) ? $"reasonmsg={reasonMsg.ToTsFormat()}" : "";
return SendCommand($"serverprocessstop {option}");
}
///
/// Displays detailed configuration of the currently selected virtual server.
///
/// Required permission: b_virtualserver_info_view
/// A object, or null on error.
public ServerInfo ServerInfo()
{
if (SendCommand($"serverinfo", out QueryResponse res))
return res.Get();
return null;
}
///
/// Displays detailed connection info of the selected virtual server including uptime and traffic.
///
/// Required permission: b_virtualserver_connectioninfo_view
/// A object, or null on error.
public ConnectionInfo ServerRequestConnectionInfo()
{
if (SendCommand($"serverrequestconnectioninfo", out QueryResponse res))
return res.Get();
return null;
}
///
/// Changes the selected virtual server's configuration using the given properties.
///
/// Requires various b_virtualserver_modify_* permissions.
/// Server properties to modify.
/// true on success, false on error.
public bool EditServer(EditServerProperties properties)
=> SendCommand("serveredit", properties.changes);
///
/// Displays a list of server groups available on the selected virtual server.
///
///
/// Required permissions: b_serverinstance_modify_querygroup,
/// b_serverinstance_modify_templates, b_virtualserver_servergroup_list
///
/// A list of objects, or null on error.
public List ListServerGroups()
{
if (SendCommand($"servergrouplist", out QueryResponse res))
return res.GetAll();
return null;
}
///
/// Creates a new server group with the given name and returns its ID.
///
/// Required permission: b_virtualserver_servergroup_create
/// The name of the new server group (name).
/// The new group ID (sgid), or -1 on error.
public int AddServerGroup(string name)
{
if (SendCommand($"servergroupadd name={name.ToTsFormat()}", out QueryResponse res))
return res.Get("sgid");
return -1;
}
///
/// Creates a new server group with the given name and type, and returns its ID.
///
/// Required permission: b_virtualserver_servergroup_create
/// The name of the new server group (name).
///
/// The group database type (type): "0" = template, "1" = regular,
/// "2" = query. Default is 1.
///
/// The new group ID (sgid), or -1 on error.
public int AddServerGroup(string name, string type)
{
if (SendCommand($"servergroupadd name={name.ToTsFormat()} type={type}", out QueryResponse res))
return res.Get("sgid");
return -1;
}
///
/// Deletes the server group with the given ID.
///
/// Required permission: b_virtualserver_servergroup_delete
/// The server group ID (sgid).
///
/// Set to 1 to delete even if clients are assigned to the group (force).
///
/// true on success, false on error.
public bool DeleteServerGroup(int sgid, int force = 0)
=> SendCommand($"servergroupdel sgid={sgid} force={force}");
///
/// Creates a copy of the server group into .
/// If is 0, a new group is created. If a target group is set, the
/// parameter is ignored.
///
///
/// Required permissions: b_virtualserver_servergroup_create,
/// i_group_modify_power, i_group_needed_modify_power
///
/// The source server group ID (ssgid).
/// The target server group ID (tsgid). Use 0 to create a new group.
/// The name of the new group (name). Ignored if is set.
///
/// The group database type (type): "0" = template, "1" = regular, "2" = query.
///
/// The new group ID (sgid), or -1 on error.
public int CopyServerGroup(int ssgid, int tsgid, string name, string type)
{
if (SendCommand($"servergroupcopy ssgid={ssgid} tsgid={tsgid} name={name.ToTsFormat()} type={type}", out QueryResponse res))
return res.Get("sgid");
return -1;
}
///
/// Changes the name of the server group with the given ID.
///
///
/// Required permissions: i_group_modify_power, i_group_needed_modify_power
///
/// The server group ID (sgid).
/// The new name for the group (name).
/// true on success, false on error.
public bool SetServerGroupName(int sgid, string name)
=> SendCommand($"servergrouprename sgid={sgid} name={name.ToTsFormat()}");
///
/// Displays a list of permissions assigned to the given server group.
///
/// Required permission: b_virtualserver_servergroup_permission_list
/// The server group ID (sgid).
///
/// When true, sends -permsid to include permission name strings instead of
/// numeric IDs in the response.
///
/// A list of objects, or null on error.
public List ListServerGroupPermissions(int sgid, bool permsid = false)
{
if (SendCommand($"servergrouppermlist sgid={sgid} {(permsid ? "-permsid" : "")}", out QueryResponse res))
return res.GetAll();
return null;
}
///
/// Adds a permission to the given server group.
///
///
/// Required permissions: i_group_modify_power, i_group_needed_modify_power,
/// i_permission_modify_power
///
/// The server group ID (sgid).
/// The numeric permission ID (permid).
/// The permission value (permvalue).
/// Set to 1 to negate the permission (permnegated).
/// Set to 1 to skip the permission check (permskip).
/// true on success, false on error.
public bool AddPermissionToServerGroup(int sgid, int permid, int permValue, int permNegated, int permSkip)
=> SendCommand($"servergroupaddperm sgid={sgid} permid={permid} permvalue={permValue} permnegated={permNegated} permskip={permSkip}");
///
/// Removes a permission from the given server group.
///
///
/// Required permissions: i_group_modify_power, i_group_needed_modify_power,
/// i_permission_modify_power
///
/// The server group ID (sgid).
/// The numeric permission ID to remove (permid).
/// true on success, false on error.
public bool RemovePermissionFromServerGroup(int sgid, int permid)
=> SendCommand($"servergroupdelperm sgid={sgid} permid={permid}");
///
/// Adds a client to the given server group.
///
///
/// Required permissions: i_group_member_add_power, i_group_needed_member_add_power
///
/// The server group ID (sgid).
/// The client's database ID (cldbid).
/// true on success, false on error.
public bool AddClientToServerGroup(int sgid, int clientDBID)
=> SendCommand($"servergroupaddclient sgid={sgid} cldbid={clientDBID}");
///
/// Removes a client from the given server group.
///
///
/// Required permissions: i_group_member_remove_power, i_group_needed_member_remove_power
///
/// The server group ID (sgid).
/// The client's database ID (cldbid).
/// true on success, false on error.
public bool RemoveClientFromServerGroup(int sgid, int clientDBID)
=> SendCommand($"servergroupdelclient sgid={sgid} cldbid={clientDBID}");
///
/// Displays the database IDs of all clients currently in the given server group.
///
/// Required permission: b_virtualserver_servergroup_client_list
/// The server group ID (sgid).
///
/// When true, sends -names to also include last nickname and UID in the response.
/// Note: extra fields are not reflected in the returned List<int>.
///
/// A list of client database IDs (cldbid), or null on error.
public List ListClientsWithServerGroup(int sgid, bool names = false)
{
string option = names ? "-names" : "";
if (SendCommand($"servergroupclientlist sgid={sgid} {option}", out QueryResponse res))
return res.GetAll("cldbid");
return null;
}
///
/// Displays all server groups the client with the given database ID is currently in.
///
///
/// The client's database ID (cldbid).
/// A list of server group IDs (sgid), or null on error.
public List GetServerGroupsByClientID(int clientDBID)
{
if (SendCommand($"servergroupsbyclientid cldbid={clientDBID}", out QueryResponse res))
return res.GetAll("sgid");
return null;
}
///
/// Globally adds a permission to ALL regular server groups of the given auto-update type on
/// all virtual servers. The target groups are identified by their
/// i_group_auto_update_type permission value.
///
/// Required permission: b_permission_modify_power_ignore
///
/// The auto-update type value (sgtype), NOT a group ID:
/// 10=Channel Guest, 15=Server Guest, 20=Query Guest,
/// 25=Channel Voice, 30=Server Normal, 35=Channel Operator,
/// 40=Channel Admin, 45=Server Admin, 50=Query Admin.
///
/// The numeric permission ID (permid).
/// The permission value (permvalue).
/// Set to 1 to negate the permission (permnegated).
/// Set to 1 to skip the permission check (permskip).
/// true on success, false on error.
public bool AutoAddPermissionForServerGroup(int sgtype, int permid, int permValue, int permNegated, int permSkip)
=> SendCommand($"servergroupautoaddperm sgtype={sgtype} permid={permid} permvalue={permValue} permnegated={permNegated} permskip={permSkip}");
///
/// Globally removes a permission from ALL regular server groups of the given auto-update type
/// on all virtual servers.
///
/// Required permission: b_permission_modify_power_ignore
///
/// The auto-update type value (sgtype), NOT a group ID.
/// See for valid values.
///
/// The numeric permission ID to remove (permid).
/// true on success, false on error.
public bool AutoDeletePermissionForServerGroup(int sgtype, int permid)
=> SendCommand($"servergroupautodelperm sgtype={sgtype} permid={permid}");
///
/// Creates and displays a snapshot of the selected virtual server containing all settings,
/// groups, and known client identities. The data can be used with
/// to restore the server.
///
/// Required permission: b_virtualserver_snapshot_create
///
/// When set, the snapshot data will be encrypted with this password (password).
/// The same password must be provided when deploying the snapshot.
///
///
/// A dictionary with version and data keys (and salt if a password was set),
/// or null on error.
///
public Dictionary CreateServerSnapshot(string password = "")
{
string option = !string.IsNullOrEmpty(password) ? $"password={password.ToTsFormat()}" : "";
if (SendCommand($"serversnapshotcreate {option}", out QueryResponse res))
return res.ToDictionary();
return null;
}
///
/// Restores the selected virtual server from a previously created snapshot.
/// Pass the raw snapshot data string as returned by
/// (e.g. "version=3 data=KLUv/..." or "version=3 salt=... data=..." for encrypted).
///
/// Required permission: b_virtualserver_snapshot_deploy
///
/// The raw snapshot data to restore from. Contains the full output of
/// as a single string.
///
///
/// When true, sends -mapping flag. The response will include old-to-new
/// channel ID mappings (ocid/ncid).
///
///
/// When true, sends -keepfiles flag. Channels present in both the virtual
/// server and the snapshot will have their files preserved.
///
///
/// The decryption password (password) if the snapshot was created with one.
///
///
/// A dictionary (empty on normal deploy, or with channel mappings if
/// is true), or null on error.
///
public Dictionary DeployServerSnapshot(string snapshot, bool mapping = false, bool keepFiles = false, string password = "")
{
var sb = new StringBuilder();
if (mapping) sb.Append("-mapping ");
if (keepFiles) sb.Append("-keepfiles ");
if (!string.IsNullOrEmpty(password)) sb.Append($"password={password.ToTsFormat()} ");
if (SendCommand($"serversnapshotdeploy {sb}{snapshot}", out QueryResponse res))
return res.ToDictionary();
return null;
}
///
/// Registers for a specified category of event notifications. The server will send
/// notification messages for each matching event in the ServerQuery client's view.
///
/// Required permission: b_virtualserver_notify_register
///
/// The event category to subscribe to (event):
/// "server", "channel", "textserver", "textchannel",
/// or "textprivate".
///
///
/// Limits notifications to a specific channel (id). Required for
/// "channel" event type; use -1 to omit.
///
/// true on success, false on error.
public bool ServerNotifyRegister(string eventType, int channelID = -1)
{
string option = channelID != -1 ? $"id={channelID}" : "";
return SendCommand($"servernotifyregister event={eventType} {option}");
}
///
/// Unregisters from all event notifications previously registered with
/// .
///
/// Required permission: b_virtualserver_notify_unregister
/// true on success, false on error.
public bool ServerNotifyUnregister()
=> SendCommand($"servernotifyunregister");
///
/// Sends a text message to the specified target.
///
///
/// Required permissions: i_client_private_textmessage_power,
/// i_client_needed_private_textmessage_power,
/// b_client_server_textmessage_send, b_client_channel_textmessage_send
///
///
/// The target mode (targetmode): 1 = client, 2 = channel, 3 = server.
///
///
/// The target client ID (target). Ignored when is 2 or 3.
///
/// The message text (msg).
/// true on success, false on error.
public bool SendTextMessage(MessageTargetMode targetmode, int target, string text)
=> SendCommand($"sendtextmessage targetmode={(int)targetmode} target={target} msg={text.ToTsMessageFormat()}");
///
/// Displays a specified number of entries from the server log.
///
///
/// Required permissions: b_serverinstance_log_view, b_virtualserver_log_view
///
/// Number of log lines to return (lines), max 100. Leave empty for default.
/// Set to "1" to reverse the line order (reverse).
/// Set to "1" to read from the master instance log instead of the virtual server log (instance).
/// Number of lines to skip from the beginning (begin_pos). Leave empty to start from the current end.
/// A list of log entry dictionaries, or null on error.
public List> ViewLog(string lines = "", string reverse = "", string instance = "", string beginPos = "")
{
var sb = new StringBuilder();
if (!string.IsNullOrEmpty(lines)) sb.Append($"lines={lines} ");
if (!string.IsNullOrEmpty(reverse)) sb.Append($"reverse={reverse} ");
if (!string.IsNullOrEmpty(instance)) sb.Append($"instance={instance} ");
if (!string.IsNullOrEmpty(beginPos)) sb.Append($"begin_pos={beginPos} ");
if (SendCommand($"logview {sb}", out QueryResponse res))
return res.ToDictionaryList();
return null;
}
///
/// Writes a custom entry into the server log.
///
///
/// Required permissions: b_serverinstance_log_add, b_virtualserver_log_add
///
///
/// The log level (loglevel): "1" = error, "2" = warning,
/// "3" = debug, "4" = info.
///
/// The log message text (logmsg).
/// true on success, false on error.
public bool AddLog(string loglevel, string text)
=> SendCommand($"logadd loglevel={loglevel} logmsg={text.ToTsFormat()}");
///
/// Sends a global text message to all clients on all virtual servers in the instance.
/// Alias for .
///
/// Required permission: b_serverinstance_textmessage_send
/// The message text.
/// true on success, false on error.
public bool SendGlobalTextMessage(string text) => GM(text);
///
/// Sends a global text message to all clients on all virtual servers in the instance.
///
/// Required permission: b_serverinstance_textmessage_send
/// The message text (msg).
/// true on success, false on error.
public bool GM(string text)
=> SendCommand($"gm msg={text.ToTsMessageFormat()}");
///
/// Displays a list of channels on the current virtual server.
/// Each flag adds extra fields to the response.
///
/// Required permission: b_virtualserver_channel_list
/// When true, sends -topic to include channel_topic.
/// When true, sends -secondsempty to include seconds_empty.
/// When true, sends -flags to include default/password/permanent/semi-permanent flags.
/// When true, sends -voice to include codec, codec quality, and talk power.
/// When true, sends -limits to include total_clients_family.
/// When true, sends -icon to include channel_icon_id.
/// When true, sends -banners to include banner URL and mode.
/// A list of objects, or null on error.
public List ListChannels(bool secondsEmpty = false, bool topic = false, bool flags = false, bool voice = false, bool limits = false, bool icon = false, bool banners = false)
{
var sb = new StringBuilder();
if (topic) sb.Append("-topic ");
if (secondsEmpty) sb.Append("-secondsempty ");
if (flags) sb.Append("-flags ");
if (voice) sb.Append("-voice ");
if (limits) sb.Append("-limits ");
if (icon) sb.Append("-icon ");
if (banners) sb.Append("-banners ");
if (SendCommand($"channellist {sb}", out QueryResponse res))
return res.GetAll();
return null;
}
///
/// Displays detailed configuration of the given channel including topic, description, and codec.
///
/// Required permission: b_channel_info_view
/// The channel ID (cid).
/// A object with ID set, or null on error.
public ChannelInfo GetChannelInfo(int channelID)
{
if (SendCommand($"channelinfo cid={channelID}", out QueryResponse res))
{
var ch = res.Get();
if (ch != null)
ch.Update("cid", channelID.ToString());
return ch;
}
return null;
}
///
/// Displays a list of channels matching the given name pattern (case-insensitive).
///
/// Required permission: b_virtualserver_channel_search
///
/// Pattern that must be part of the channel name (pattern). Case-insensitive.
/// Leave empty to match all channels.
///
/// A list of matching channel IDs (cid), or null on error.
public List ChannelFind(string pattern = "")
{
string option = !string.IsNullOrEmpty(pattern) ? $"pattern={pattern.ToTsFormat()}" : "";
if (SendCommand($"channelfind {option}", out QueryResponse res))
return res.GetAll("cid");
return null;
}
///
/// Moves a channel to a new parent channel.
///
///
/// Required permissions: i_channel_min_depth, i_channel_max_depth,
/// b_channel_modify_parent, b_channel_modify_sortorder
///
/// The channel to move (cid).
/// The new parent channel ID (cpid).
///
/// Sort order: ID of the sibling channel this channel will be placed directly below (order).
/// Use "0" to place it as the first child of the new parent.
/// Leave empty to omit.
///
/// true on success, false on error.
public bool MoveChannel(int channelID, int targetID, string order = "")
{
string option = !string.IsNullOrEmpty(order) ? $"order={order}" : "";
return SendCommand($"channelmove cid={channelID} cpid={targetID} {option}");
}
///
/// Creates a new channel and returns its ID.
///
/// Requires various b_channel_create_* permissions.
/// The channel name (channel_name).
/// Additional channel properties to set on creation.
/// The new channel ID (cid), or -1 on error.
public int CreateChannel(EditChannelProperties properties)
{
if (SendCommand("channelcreate", properties.changes, out QueryResponse res))
return res.Get("cid");
return -1;
}
///
/// Deletes the given channel. If clients are present, use to kick
/// them to the default channel.
///
///
/// Required permissions: b_channel_delete_permanent, b_channel_delete_semi_permanent,
/// b_channel_delete_temporary, b_channel_delete_flag_force
///
/// The channel ID (cid).
///
/// Set to "1" to delete even if clients are in the channel (force).
/// Clients are kicked to the default channel.
///
/// true on success, false on error.
public bool DeleteChannel(int channelID, string force = "0")
=> SendCommand($"channeldelete cid={channelID} force={force}");
///
/// Changes a channel's configuration. All properties in are applied at once.
///
/// Requires various b_channel_modify_* and i_channel_* permissions.
/// The channel ID (cid).
/// Channel properties to modify.
/// true on success, false on error.
public bool EditChannel(int channelID, EditChannelProperties properties)
=> SendCommand($"channeledit cid={channelID}", properties.changes);
///
/// Displays a list of channel groups available on the selected virtual server.
///
///
/// Required permissions: b_virtualserver_channelgroup_list,
/// b_serverinstance_modify_templates
///
/// A list of objects, or null on error.
public List ListChannelGroups()
{
if (SendCommand($"channelgrouplist", out QueryResponse res))
return res.GetAll();
return null;
}
///
/// Creates a new channel group and returns its ID.
///
/// Required permission: b_virtualserver_channelgroup_create
/// The name of the new channel group (name).
/// The new group ID (cgid), or -1 on error.
public int AddChannelGroup(string groupName)
{
if (SendCommand($"channelgroupadd name={groupName.ToTsFormat()}", out QueryResponse res))
return res.Get("cgid");
return -1;
}
///
/// Creates a new channel group with the given type and returns its ID.
///
/// Required permission: b_virtualserver_channelgroup_create
/// The name of the new channel group (name).
///
/// The group database type (type): "0" = template, "1" = regular,
/// "2" = query. Default is 1.
///
/// The new group ID (cgid), or -1 on error.
public int AddChannelGroup(string groupName, string type)
{
if (SendCommand($"channelgroupadd name={groupName.ToTsFormat()} type={type}", out QueryResponse res))
return res.Get("cgid");
return -1;
}
///
/// Deletes the given channel group.
///
/// Required permission: b_virtualserver_channelgroup_delete
/// The channel group ID (cgid).
///
/// Set to 1 to delete even if clients are assigned to the group (force).
///
/// true on success, false on error.
public bool DeleteChannelGroup(int groupID, int force = 0)
=> SendCommand($"channelgroupdel cgid={groupID} force={force}");
///
/// Creates a copy of channel group into .
/// If is 0, a new group is created. If a target group is set, the
/// parameter is ignored.
///
///
/// Required permissions: b_virtualserver_channelgroup_create,
/// i_group_modify_power, i_group_needed_modify_power
///
/// The source channel group ID (scgid).
/// The target channel group ID (tcgid). Use 0 to create a new group.
/// The name for the new group (name). Ignored if is set.
///
/// The group database type (type): "0" = template, "1" = regular, "2" = query.
///
/// The new group ID (cgid), or -1 on error.
public int CopyChannelGroup(int scgid, int tsgid, string name, string type)
{
if (SendCommand($"channelgroupcopy scgid={scgid} tcgid={tsgid} name={name.ToTsFormat()} type={type}", out QueryResponse res))
return res.Get("cgid");
return -1;
}
///
/// Changes the name of the given channel group.
///
///
/// Required permissions: i_group_modify_power, i_group_needed_modify_power
///
/// The channel group ID (cgid).
/// The new name for the group (name).
/// true on success, false on error.
public bool SetChannelGroupName(int groupID, string name)
=> SendCommand($"channelgrouprename cgid={groupID} name={name.ToTsFormat()}");
///
/// Adds a permission to the given channel group.
///
///
/// Required permissions: i_group_modify_power, i_group_needed_modify_power,
/// i_permission_modify_power
///
/// The channel group ID (cgid).
/// The numeric permission ID (permid).
/// The permission value (permvalue).
/// true on success, false on error.
public bool AddPermissionToChannelGroup(int groupID, int permid, string permValue)
=> SendCommand($"channelgroupaddperm cgid={groupID} permid={permid} permvalue={permValue}");
///
/// Displays a list of permissions assigned to the given channel group.
///
/// Required permission: b_virtualserver_channelgroup_permission_list
/// The channel group ID (cgid).
///
/// When true, sends -permsid to include permission name strings instead of
/// numeric IDs in the response.
///
/// A list of objects, or null on error.
public List ListChannelGroupPermissions(int groupID, bool permsid = false)
{
string option = permsid ? "-permsid" : "";
if (SendCommand($"channelgrouppermlist cgid={groupID} {option}", out QueryResponse res))
return res.GetAll();
return null;
}
///
/// Removes a permission from the given channel group.
///
///
/// Required permissions: i_group_modify_power, i_group_needed_modify_power,
/// i_permission_modify_power
///
/// The channel group ID (cgid).
/// The numeric permission ID to remove (permid).
/// true on success, false on error.
public bool RemovePermissionFromChannelGroup(int groupID, int permid)
=> SendCommand($"channelgroupdelperm cgid={groupID} permid={permid}");
///
/// Displays all client/channel/group assignments for channel groups. All parameters are
/// optional — omit all to return every assignment on the server.
///
/// Required permission: b_virtualserver_channelgroup_client_list
/// Filter by channel ID (cid). Use -1 to omit.
/// Filter by client database ID (cldbid). Use -1 to omit.
/// Filter by channel group ID (cgid). Use -1 to omit.
///
/// A list of tuples with (ChannelID, ClientDBID, ChannelGroupID), or null on error.
///
public List<(int ChannelID, int ClientDBID, int ChannelGroupID)> ListClientsByChannelGroup(int channelID = -1, int clientDBID = -1, int groupID = -1)
{
var sb = new StringBuilder();
if (channelID != -1) sb.Append($"cid={channelID} ");
if (clientDBID != -1) sb.Append($"cldbid={clientDBID} ");
if (groupID != -1) sb.Append($"cgid={groupID} ");
if (SendCommand($"channelgroupclientlist {sb}", out QueryResponse res))
return res.Entries.Select(x => (x.GetValue("cid"), x.GetValue("cldbid"), x.GetValue("cgid"))).ToList();
return null;
}
///
/// Sets the channel group of a client in a specific channel.
///
///
/// Required permissions: i_group_member_add_power, i_group_needed_member_add_power,
/// i_group_member_remove_power, i_group_needed_member_remove_power
///
/// The channel group ID to assign (cgid).
/// The channel in which to set the group (cid).
/// The client's database ID (cldbid).
/// true on success, false on error.
public bool SetClientChannelGroup(int groupID, int channelID, int clientDBID)
=> SendCommand($"setclientchannelgroup cgid={groupID} cid={channelID} cldbid={clientDBID}");
///
/// Displays a list of permissions defined for the given channel.
///
/// Required permission: b_virtualserver_channel_permission_list
/// The channel ID (cid).
///
/// When true, sends -permsid to include permission name strings instead of
/// numeric IDs in the response.
///
/// A list of objects, or null on error.
public List ListChannelPermissions(int channelID, bool permsid = false)
{
string option = permsid ? "-permsid" : "";
if (SendCommand($"channelpermlist cid={channelID} {option}", out QueryResponse res))
return res.GetAll();
return null;
}
///
/// Adds a permission to the given channel.
///
///
/// Required permissions: i_group_modify_power, i_group_needed_modify_power,
/// i_permission_modify_power
///
/// The channel ID (cid).
/// The numeric permission ID (permid).
/// The permission value (permvalue).
/// true on success, false on error.
public bool AddChannelPermission(int channelID, int permid, string permvalue)
=> SendCommand($"channeladdperm cid={channelID} permid={permid} permvalue={permvalue}");
///
/// Removes a permission from the given channel.
///
///
/// Required permissions: i_group_modify_power, i_group_needed_modify_power,
/// i_permission_modify_power
///
/// The channel ID (cid).
/// The numeric permission ID to remove (permid).
/// true on success, false on error.
public bool DeleteChannelPermission(int channelID, int permid)
=> SendCommand($"channeldelperm cid={channelID} permid={permid}");
///
/// Displays a list of clients currently online. Each flag adds extra fields to the server
/// response. Note: only returns a list of client IDs regardless of flags used.
///
///
/// Required permissions: b_virtualserver_client_list,
/// i_channel_subscribe_power, i_channel_needed_subscribe_power
///
/// When true, sends -uid to include client unique identifiers.
/// When true, sends -away to include away status and message.
/// When true, sends -voice to include talking/mute/recording status.
/// When true, sends -times to include idle, created, and last connected times.
/// When true, sends -groups to include server and channel group info.
/// When true, sends -info to include client version and platform.
/// When true, sends -country to include country code.
/// When true, sends -ip to include client IP (requires b_client_remoteaddress_view).
/// When true, sends -icon to include client icon ID.
/// When true, sends -badges to include client badges.
/// A list of objects, or null on error.
public List ClientList(bool uid = false, bool away = false, bool voice = false, bool times = false, bool groups = false, bool info = false, bool country = false, bool ip = false, bool icon = false, bool badges = false)
{
var sb = new StringBuilder();
if (uid) sb.Append("-uid ");
if (away) sb.Append("-away ");
if (voice) sb.Append("-voice ");
if (times) sb.Append("-times ");
if (groups) sb.Append("-groups ");
if (info) sb.Append("-info ");
if (country) sb.Append("-country ");
if (ip) sb.Append("-ip ");
if (icon) sb.Append("-icon ");
if (badges) sb.Append("-badges ");
if (!SendCommand($"clientlist {sb}", out QueryResponse res))
return null;
return res.GetAll();
}
///
/// Displays detailed configuration of a single client including UID, nickname, version, and groups.
///
/// Required permission: b_client_info_view
/// The online client ID (clid).
/// A object with ID set, or null on error.
public ClientInfo GetClientInfo(int clientID)
{
if (SendCommand($"clientinfo clid={clientID}", out QueryResponse res))
{
var client = res.Get();
if (client != null)
client.Update("clid", clientID.ToString());
return client;
}
return null;
}
///
/// Displays detailed configuration for multiple clients in a single batch request.
///
/// Required permission: b_client_info_view
/// One or more online client IDs (clid).
///
/// A list of objects in the same order as ,
/// or null on error or count mismatch.
///
public List GetClientInfo(params IEnumerable clientIDs)
{
string cmd = "clientinfo " + string.Join("|", clientIDs.Select(id => $"clid={id}"));
if (!SendCommand(cmd, out QueryResponse res))
return null;
var entries = res.GetAll();
if (entries.Count != clientIDs.Count())
{
GlobalLogger.Log("ServerQuery", "GetClientInfo response mismatch!", LogType.Warning);
return null;
}
for (int i = 0; i < clientIDs.Count(); i++)
entries[i].Update("clid", clientIDs.ElementAt(i).ToString());
return entries;
}
///
/// Displays a list of clients matching the given nickname pattern.
///
/// Required permission: b_virtualserver_client_search
/// Regex pattern to match against client nicknames (pattern).
/// A list of matching client IDs (clid), or null on error.
public List ClientFind(string pattern)
{
if (SendCommand($"clientfind pattern={pattern.ToTsFormat()}", out QueryResponse res))
return res.GetAll("clid");
return null;
}
///
/// Changes a connected client's settings such as description, talk power, and channel commander status.
///
///
/// Required permissions: b_client_modify_description, b_client_set_talk_power
///
/// The online client ID (clid).
/// Client properties to modify.
/// true on success, false on error.
public bool EditClient(int clientID, EditClientProperties properties)
=> SendCommand($"clientedit clid={clientID}", properties.changes);
///
/// Displays a list of client database entries known by the server.
///
/// Required permission: b_virtualserver_client_dblist
/// Skip the first n entries (start). Leave empty to start from the beginning.
/// Return at most n entries (duration). Leave empty for default.
/// When true, sends -count to also return total number of entries.
/// A list of objects, or null on error.
public List ListDBClients(string start = "", string duration = "", bool count = false)
{
var sb = new StringBuilder();
if (!string.IsNullOrEmpty(start)) sb.Append($"start={start} ");
if (!string.IsNullOrEmpty(duration)) sb.Append($"duration={duration} ");
if (count) sb.Append("-count ");
if (SendCommand($"clientdblist {sb}", out QueryResponse res))
return res.GetAll();
return null;
}
///
/// Displays detailed database information about the client with the given database ID.
///
/// Required permission: b_virtualserver_client_dbinfo
/// The client's database ID (cldbid).
/// A object, or null on error.
public ClientDBInfo GetClientDBInfo(int clientDBID)
{
if (SendCommand($"clientdbinfo cldbid={clientDBID}", out QueryResponse res))
return res.Get();
return null;
}
///
/// Displays a list of client database IDs matching the given pattern.
///
/// Required permission: b_virtualserver_client_dbsearch
///
/// Pattern to match against client nickname or UID (pattern).
/// SQL wildcard characters (e.g. %) are supported.
///
///
/// When true, sends -uid to search by unique identifier instead of nickname.
///
/// A list of matching client database IDs (cldbid), or null on error.
public List ClientDBFind(string pattern, bool uid)
{
string option = uid ? "-uid" : "";
if (SendCommand($"clientdbfind pattern={pattern} {option}", out QueryResponse res))
return res.GetAll("cldbid");
return null;
}
///
/// Changes a client's database properties such as description.
///
///
/// Required permissions: b_client_modify_dbproperties, b_client_modify_description,
/// b_client_set_talk_power
///
/// The client's database ID (cldbid).
/// Dictionary of client database property key-value pairs to update.
/// true on success, false on error.
public bool EditDBClient(int clientDBID, Dictionary properties = null)
=> SendCommand($"clientdbedit cldbid={clientDBID}", properties);
///
/// Deletes the client's properties from the database.
///
/// Required permission: b_client_delete_dbproperties
/// The client's database ID (cldbid).
/// true on success, false on error.
public bool DeleteDBClient(int clientDBID)
=> SendCommand($"clientdbdelete cldbid={clientDBID}");
///
/// Displays all online client IDs matching the given unique identifier.
///
///
/// The client's unique identifier (cluid).
/// A list of matching online client IDs (clid), or null on error.
public List ClientGetIDs(string clientUID)
{
if (SendCommand($"clientgetids cluid={clientUID.ToTsFormat()}", out QueryResponse res))
return res.GetAll("clid");
return null;
}
///
/// Displays the database ID of the client with the given unique identifier.
///
///
/// The client's unique identifier (cluid).
/// The client database ID (cldbid), or -1 on error.
public int GetClientDBIDFromUID(string clientUID)
{
if (SendCommand($"clientgetdbidfromuid cluid={clientUID.ToTsFormat()}", out QueryResponse res))
return res.Get("cldbid");
return -1;
}
///
/// Displays the database ID and last known nickname of the client with the given unique identifier.
///
///
/// The client's unique identifier (cluid).
/// The last known nickname (name), or null on error.
public string GetClientNameFromUID(string clientUID)
{
if (SendCommand($"clientgetnamefromuid cluid={clientUID.ToTsFormat()}", out QueryResponse res))
return res["name"];
return null;
}
///
/// Displays the unique identifier and last known nickname of the client with the given database ID.
///
///
/// The client's database ID (cldbid).
/// The last known nickname (name), or null on error.
public string GetClientNameFromDBID(int clientDBID)
{
if (SendCommand($"clientgetnamefromdbid cldbid={clientDBID}", out QueryResponse res))
return res["name"];
return null;
}
///
/// Displays the unique identifier of the online client with the given client ID.
///
///
/// The online client ID (clid).
/// The client's unique identifier (cluid), or null on error.
public string ClientGetUIDFromClientID(int clientID)
{
if (SendCommand($"clientgetuidfromclid clid={clientID}", out QueryResponse res))
return res["cluid"];
return null;
}
///
/// Updates the ServerQuery login credentials using the given username. The password is
/// auto-generated by the server.
///
/// Required permission: b_client_create_modify_serverquery_login
/// The requested login name (client_login_name).
/// The auto-generated password (client_login_password), or null on error.
public string SetClientServerQueryLogin(string username)
{
if (SendCommand($"clientsetserverquerylogin client_login_name={username.ToTsFormat()}", out QueryResponse res))
return res["client_login_password"];
return null;
}
///
/// Changes your own ServerQuery client settings such as nickname.
///
///
/// Client properties to update (e.g. client_nickname).
/// true on success, false on error.
public bool UpdateClient(EditClientProperties properties)
=> SendCommand("clientupdate", properties.changes);
///
/// Moves a client to the specified channel.
///
///
/// Required permissions: i_client_move_power, i_client_needed_move_power
///
/// The online client ID (clid).
/// The target channel ID (cid).
/// true on success, false on error.
public bool MoveClient(int clientID, int channelID)
=> SendCommand($"clientmove clid={clientID} cid={channelID}");
///
/// Moves a client to a password-protected channel.
///
///
/// Required permissions: i_client_move_power, i_client_needed_move_power
///
/// The online client ID (clid).
/// The target channel ID (cid).
/// The channel password (cpw).
/// true on success, false on error.
public bool MoveClient(int clientID, int channelID, string password)
=> SendCommand($"clientmove clid={clientID} cid={channelID} cpw={password.ToTsFormat()}");
///
/// Kicks a client from their current channel or from the server.
///
///
/// Required permissions: i_client_kick_from_server_power,
/// i_client_kick_from_channel_power, i_client_needed_kick_from_server_power,
/// i_client_needed_kick_from_channel_power
///
/// The online client ID (clid).
///
/// The kick target: or .
///
/// true on success, false on error.
public bool KickClient(int clientID, EventReason reasonID)
=> SendCommand($"clientkick clid={clientID} reasonid={(int)reasonID}");
///
/// Kicks a client from their current channel or from the server with a reason message.
///
///
/// Required permissions: i_client_kick_from_server_power,
/// i_client_kick_from_channel_power, i_client_needed_kick_from_server_power,
/// i_client_needed_kick_from_channel_power
///
/// The online client ID (clid).
///
/// The kick target: or .
///
/// Reason message displayed to the kicked client (reasonmsg). Max 40 characters.
/// true on success, false on error.
public bool KickClient(int clientID, EventReason reasonID, string reasonMsg)
=> SendCommand($"clientkick clid={clientID} reasonid={(int)reasonID} reasonmsg={reasonMsg.ToTsMessageFormat()}");
///
/// Sends a poke message to the given client.
///
///
/// Required permissions: i_client_poke_power, i_client_needed_poke_power
///
/// The online client ID (clid).
/// The poke message (msg).
/// true on success, false on error.
public bool PokeClient(int clientID, string msg)
=> SendCommand($"clientpoke clid={clientID} msg={msg.ToTsMessageFormat()}");
///
/// Displays permissions assigned to the given client.
///
/// Required permission: b_virtualserver_client_permission_list
/// The client's database ID (cldbid).
///
/// When true, sends -permsid to include permission name strings instead of
/// numeric IDs in the response.
///
/// A list of objects, or null on error.
public List ListClientPermissions(int clientDBID, bool permsid = false)
{
string option = permsid ? "-permsid" : "";
if (SendCommand($"clientpermlist cldbid={clientDBID} {option}", out QueryResponse res))
return res.GetAll();
return null;
}
///
/// Adds a permission to the given client.
///
///
/// Required permissions: i_group_modify_power, i_group_needed_modify_power,
/// i_permission_modify_power
///
/// The client's database ID (cldbid).
/// The numeric permission ID (permid).
/// The permission value (permvalue).
/// Set to "1" to skip the permission check (permskip).
/// true on success, false on error.
public bool AddClientPermission(int clientDBID, int permid, string permvalue, string permSkip = "0")
=> SendCommand($"clientaddperm cldbid={clientDBID} permid={permid} permvalue={permvalue} permskip={permSkip}");
///
/// Removes a permission from the given client.
///
///
/// Required permissions: i_group_modify_power, i_group_needed_modify_power,
/// i_permission_modify_power
///
/// The client's database ID (cldbid).
/// The numeric permission ID to remove (permid).
/// true on success, false on error.
public bool DeleteClientPermission(int clientDBID, int permid)
=> SendCommand($"clientdelperm cldbid={clientDBID} permid={permid}");
///
/// Displays channel-specific permissions assigned to the given client in the given channel.
///
/// Required permission: b_virtualserver_channelclient_permission_list
/// The channel ID (cid).
/// The client's database ID (cldbid).
///
/// When true, sends -permsid to include permission name strings instead of
/// numeric IDs in the response.
///
/// A list of objects, or null on error.
public List ListChannelClientPermissions(int channelID, int clientDBID, bool permsid = false)
{
string option = permsid ? "-permsid" : "";
if (SendCommand($"channelclientpermlist cid={channelID} cldbid={clientDBID} {option}", out QueryResponse res))
return res.GetAll();
return null;
}
///
/// Adds a channel-specific permission to a client in a specific channel.
///
///
/// Required permissions: i_group_modify_power, i_group_needed_modify_power,
/// i_permission_modify_power
///
/// The channel ID (cid).
/// The client's database ID (cldbid).
/// The numeric permission ID (permid).
/// The permission value (permvalue).
/// true on success, false on error.
public bool AddChannelClientPermission(int channelID, int clientDBID, int permid, string permvalue)
=> SendCommand($"channelclientaddperm cid={channelID} cldbid={clientDBID} permid={permid} permvalue={permvalue}");
///
/// Removes a channel-specific permission from a client in a specific channel.
///
///
/// Required permissions: i_group_modify_power, i_group_needed_modify_power,
/// i_permission_modify_power
///
/// The channel ID (cid).
/// The client's database ID (cldbid).
/// The numeric permission ID to remove (permid).
/// true on success, false on error.
public bool DeleteChannelClientPermission(int channelID, int clientDBID, int permid)
=> SendCommand($"channelclientdelperm cid={channelID} cldbid={clientDBID} permid={permid}");
///
/// Displays a list of all permissions available on the server instance including ID, name,
/// and description.
///
/// Required permission: b_serverinstance_permission_list
/// A list of objects, or null on error.
public List ListPermissions()
{
if (SendCommand($"permissionlist", out QueryResponse res))
return res.GetAll();
return null;
}
///
/// Displays the numeric database ID of the permission with the given name string.
///
/// Required permission: b_serverinstance_permission_list
/// The permission name string (permsid), e.g. "b_serverquery_login".
/// The numeric permission ID (permid), or -1 on error.
public int GetPermissionIDByName(string name)
{
if (SendCommand($"permidgetbyname permsid={name}", out QueryResponse res))
return res.Get("permid");
return -1;
}
///
/// Displays all permissions assigned to a client for the given channel.
/// Pass permid=0 to return all permissions.
///
/// Required permission: b_client_permissionoverview_view
/// The channel ID (cid).
/// The client's database ID (cldbid).
///
/// The numeric permission ID to look up (permid). Set to 0 to return all permissions.
///
/// A list of permission assignment dictionaries, or null on error.
public List> GetPermissionOverview(int channelID, int clientDBID, int permID)
{
if (SendCommand($"permoverview cid={channelID} cldbid={clientDBID} permid={permID}", out QueryResponse res))
return res.ToDictionaryList();
return null;
}
///
/// Displays the current value of the given permission for your own connection.
///
/// Required permission: b_client_permissionoverview_own
/// The numeric permission ID (permid).
/// A object with Name, ID, and Value populated, or null on error.
public SetPermissionInfo GetPermissionInfo(int permID)
{
if (SendCommand($"permget permid={permID}", out QueryResponse res))
return res.Get();
return null;
}
///
/// Displays all assignments of the given permission across clients, channels, and groups.
///
///
/// Required permissions: b_virtualserver_permission_find,
/// b_serverinstance_permission_find
///
/// The numeric permission ID (permid).
/// A list of assignment dictionaries, or null on error.
public List> FindPermission(int permID)
{
if (SendCommand($"permfind permid={permID}", out QueryResponse res))
return res.ToDictionaryList();
return null;
}
///
/// Restores default permission settings on the selected virtual server and creates a new
/// initial administrator token. WARNING: Deletes all server and channel groups.
///
/// Required permission: b_virtualserver_permission_reset
/// true on success, false on error.
public bool ResetPermissions()
=> SendCommand($"permreset");
///
/// Displays a list of privilege keys (tokens) available on the current virtual server.
///
/// Required permission: b_virtualserver_token_list
/// A list of token dictionaries, or null on error.
public List> ListPrivilegeKeys()
{
if (SendCommand($"privilegekeylist", out QueryResponse res))
return res.ToDictionaryList();
return null;
}
///
/// Creates a new privilege key (token) to grant access to a server or channel group.
///
///
/// Required permissions: b_virtualserver_token_add,
/// i_group_needed_member_add_power, i_group_member_add_power
///
///
/// Token type (tokentype): "0" = server group token (use as server group ID,
/// set to 0); "1" = channel group token (use
/// as channel group ID, must be a valid channel).
///
/// The server or channel group ID (tokenid1).
/// The channel ID (tokenid2). Required for channel group tokens; set to 0 for server group tokens.
/// Optional description for the token (tokendescription).
///
/// Optional custom client property set (tokencustomset). Format:
/// "ident=key1 value=val1|ident=key2 value=val2".
///
/// A dictionary with the generated token string, or null on error.
public Dictionary AddPrivilegeKey(string tokentype, int groupID, int channelID, string description = "", string customFields = "")
{
var sb = new StringBuilder($"privilegekeyadd tokentype={tokentype} tokenid1={groupID} tokenid2={channelID}");
if (!string.IsNullOrEmpty(description)) sb.Append($" tokendescription={description.ToTsFormat()}");
if (!string.IsNullOrEmpty(customFields)) sb.Append($" tokencustomset={customFields.ToTsFormat()}");
if (SendCommand(sb.ToString(), out QueryResponse res))
return res.ToDictionary();
return null;
}
///
/// Deletes the privilege key (token) with the given token string.
///
/// Required permission: b_virtualserver_token_delete
/// The token string to delete (token).
/// true on success, false on error.
public bool DeletePrivilegeKey(string tokenKey)
=> SendCommand($"privilegekeydelete token={tokenKey}");
///
/// Redeems a privilege key (token) to gain access to the associated server or channel group.
/// The token is automatically deleted after use.
///
/// Required permission: b_virtualserver_token_use
/// The token string to redeem (token).
/// true on success, false on error.
public bool UsePrivilegeKey(string tokenKey)
=> SendCommand($"privilegekeyuse token={tokenKey}");
///
/// Displays a list of offline messages in your inbox including sender UID, subject, timestamp,
/// and read flag.
///
///
/// A list of message dictionaries, or null on error.
public List> ListMessages()
{
if (SendCommand($"messagelist", out QueryResponse res))
return res.ToDictionaryList();
return null;
}
///
/// Sends an offline message to the client with the given unique identifier.
///
///
/// The recipient's unique identifier (cluid).
/// The message subject (subject).
/// The message body (message).
/// true on success, false on error.
public bool AddMessage(string clientUID, string subject, string message)
=> SendCommand($"messageadd cluid={clientUID.ToTsFormat()} subject={subject.ToTsMessageFormat()} message={message.ToTsMessageFormat()}");
///
/// Deletes the offline message with the given ID from your inbox.
///
///
/// The message ID (msgid).
/// true on success, false on error.
public bool DeleteMessage(int messageID)
=> SendCommand($"messagedel msgid={messageID}");
///
/// Displays an offline message from your inbox. Does not automatically mark it as read.
///
///
/// The message ID (msgid).
/// A dictionary with msgid, cluid, subject, and message, or null on error.
public Dictionary GetMessage(int messageID)
{
if (SendCommand($"messageget msgid={messageID}", out QueryResponse res))
return res.ToDictionary();
return null;
}
///
/// Updates the read flag of the given offline message.
///
///
/// The message ID (msgid).
/// Set to "1" to mark as read, "0" to mark as unread (flag).
/// true on success, false on error.
public bool UpdateMessageFlag(int messageID, string flag)
=> SendCommand($"messageupdateflag msgid={messageID} flag={flag}");
///
/// Displays a list of complaints on the selected virtual server. If
/// is specified, only complaints about that client are shown.
///
/// Required permission: b_client_complain_list
///
/// The database ID of the client to filter complaints for (tcldbid).
/// Use -1 to list all complaints on the server.
///
/// A list of complaint dictionaries, or null on error.
public List> ListComplaints(int targetClientDBID = -1)
{
string option = targetClientDBID != -1 ? $"tcldbid={targetClientDBID}" : "";
if (SendCommand($"complainlist {option}", out QueryResponse res))
return res.ToDictionaryList();
return null;
}
///
/// Submits a complaint about the client with the given database ID.
///
///
/// Required permissions: i_client_complain_power, i_client_needed_complain_power
///
/// The database ID of the client to complain about (tcldbid).
/// The complaint message (message).
/// true on success, false on error.
public bool AddComplaint(int targetClientDBID, string message)
=> SendCommand($"complainadd tcldbid={targetClientDBID} message={message.ToTsFormat()}");
///
/// Deletes all complaints about the client with the given database ID.
///
/// Required permission: b_client_complain_delete
/// The database ID of the target client (tcldbid).
/// true on success, false on error.
public bool DeleteAllComplaints(int targetClientDBID)
=> SendCommand($"complaindelall tcldbid={targetClientDBID}");
///
/// Deletes a specific complaint about submitted by
/// .
///
///
/// Required permissions: b_client_complain_delete, b_client_complain_delete_own
///
/// The database ID of the client who was complained about (tcldbid).
/// The database ID of the client who submitted the complaint (fcldbid).
/// true on success, false on error.
public bool DeleteComplaint(int targetClientDBID, int formClientDBID)
=> SendCommand($"complaindel tcldbid={targetClientDBID} fcldbid={formClientDBID}");
///
/// Bans one or more clients by ID. Creates separate ban rules for the client's IP address,
/// unique identifier, and mytsid (if available).
///
///
/// Required permissions: i_client_ban_power, i_client_needed_ban_power
///
/// The online client ID (clid).
/// Ban duration in seconds (time). Leave empty for a permanent ban.
/// Reason for the ban (banreason).
/// A list of created ban IDs (one per rule: IP, UID, mytsid), or null on error.
public List BanClient(int clientID, string time = "", string reason = "")
{
var sb = new StringBuilder();
if (!string.IsNullOrEmpty(time)) sb.Append($"time={time} ");
if (!string.IsNullOrEmpty(reason)) sb.Append($"banreason={reason.ToTsFormat()} ");
if (SendCommand($"banclient clid={clientID} {sb}", out QueryResponse res))
return res.GetAll("banid");
return null;
}
///
/// Displays a list of active ban rules on the current virtual server.
///
/// Required permission: b_client_ban_list
/// Skip the first n entries (start). Use -1 to omit.
/// Return at most n entries (duration), capped at 200. Use -1 to omit.
/// When true, sends -count to also return the total number of entries.
/// A list of objects, or null on error.
public List ListBans(int start = -1, int duration = -1, bool count = false)
{
var sb = new StringBuilder();
if (start != -1) sb.Append($"start={start} ");
if (duration != -1) sb.Append($"duration={duration} ");
if (count) sb.Append("-count ");
if (SendCommand($"banlist {sb}", out QueryResponse res))
return res.GetAll();
return null;
}
///
/// Creates a ban rule matching by client unique identifier (UID).
/// At least one of uid, ip, name, or mytsid must be set.
///
/// Required permission: b_client_ban_create
/// The client's unique identifier to ban (uid).
/// Ban duration in seconds (time). Leave empty for a permanent ban.
/// Reason for the ban (banreason).
/// Last known nickname to associate with the ban rule (lastnickname).
/// The created ban rule ID (banid), or -1 on error.
public int AddBan(string clientUID, string time = "", string reason = "", string lastNickname = "")
{
var sb = new StringBuilder();
if (!string.IsNullOrEmpty(time)) sb.Append($"time={time} ");
if (!string.IsNullOrEmpty(reason)) sb.Append($"banreason={reason.ToTsFormat()} ");
if (!string.IsNullOrEmpty(lastNickname)) sb.Append($"lastnickname={lastNickname.ToTsFormat()} ");
if (SendCommand($"banadd uid={clientUID} {sb}", out QueryResponse res))
return res.Get("banid");
return -1;
}
///
/// Creates a ban rule matching by IP address regex.
/// At least one of uid, ip, name, or mytsid must be set.
///
/// Required permission: b_client_ban_create
/// Regular expression matching the client's IP address (ip).
/// Ban duration in seconds (time). Leave empty for a permanent ban.
/// Reason for the ban (banreason).
/// Last known nickname to associate with the ban rule (lastnickname).
/// The created ban rule ID (banid), or -1 on error.
public int AddBanIP(string ipRegExp, string time = "", string reason = "", string lastNickname = "")
{
var sb = new StringBuilder();
if (!string.IsNullOrEmpty(time)) sb.Append($"time={time} ");
if (!string.IsNullOrEmpty(reason)) sb.Append($"banreason={reason.ToTsFormat()} ");
if (!string.IsNullOrEmpty(lastNickname)) sb.Append($"lastnickname={lastNickname.ToTsFormat()} ");
if (SendCommand($"banadd ip={ipRegExp} {sb}", out QueryResponse res))
return res.Get("banid");
return -1;
}
///
/// Creates a ban rule matching by client nickname regex.
/// At least one of uid, ip, name, or mytsid must be set.
///
/// Required permission: b_client_ban_create
/// Regular expression matching the client's nickname (name).
/// Ban duration in seconds (time). Leave empty for a permanent ban.
/// Reason for the ban (banreason).
/// Last known nickname to associate with the ban rule (lastnickname).
/// The created ban rule ID (banid), or -1 on error.
public int AddBanName(string nameRegExp, string time = "", string reason = "", string lastNickname = "")
{
var sb = new StringBuilder();
if (!string.IsNullOrEmpty(time)) sb.Append($"time={time} ");
if (!string.IsNullOrEmpty(reason)) sb.Append($"banreason={reason.ToTsFormat()} ");
if (!string.IsNullOrEmpty(lastNickname)) sb.Append($"lastnickname={lastNickname.ToTsFormat()} ");
if (SendCommand($"banadd name={nameRegExp} {sb}", out QueryResponse res))
return res.Get("banid");
return -1;
}
///
/// Creates a ban rule matching by myTeamSpeak ID.
/// At least one of uid, ip, name, or mytsid must be set. Pass "empty" to match
/// clients without a myTS ID.
///
/// Required permission: b_client_ban_create
/// The myTeamSpeak ID to ban (mytsid), or "empty" to match clients without one.
/// Ban duration in seconds (time). Leave empty for a permanent ban.
/// Reason for the ban (banreason).
/// Last known nickname to associate with the ban rule (lastnickname).
/// The created ban rule ID (banid), or -1 on error.
public int AddBanMyTsID(string myTsID, string time = "", string reason = "", string lastNickname = "")
{
var sb = new StringBuilder();
if (!string.IsNullOrEmpty(time)) sb.Append($"time={time} ");
if (!string.IsNullOrEmpty(reason)) sb.Append($"banreason={reason.ToTsFormat()} ");
if (!string.IsNullOrEmpty(lastNickname)) sb.Append($"lastnickname={lastNickname.ToTsFormat()} ");
if (SendCommand($"banadd mytsid={myTsID} {sb}", out QueryResponse res))
return res.Get("banid");
return -1;
}
///
/// Deletes the ban rule with the given ID.
///
///
/// Required permissions: b_client_ban_delete, b_client_ban_delete_own
///
/// The ban rule ID (banid).
/// true on success, false on error.
public bool DeleteBan(int banID)
=> SendCommand($"bandel banid={banID}");
///
/// Deletes all active ban rules from the current virtual server.
///
/// Required permission: b_client_ban_delete
/// true on success, false on error.
public bool DeleteAllBans()
=> SendCommand($"bandelall");
///
/// Displays information about the current ServerQuery connection including login name,
/// virtual server status, client ID, and channel ID.
///
///
/// A object with the current session details, or null on error.
public WhoAmIInfo WhoAmI()
{
if (SendCommand($"whoami", out QueryResponse res))
return res.Get();
return null;
}
///
/// Creates a new API key for the invoking user with the specified access scope.
/// A default lifetime of 14 days is used if not specified. A zero lifetime means no expiration.
///
///
/// Required permissions: b_virtualserver_apikey_add, b_virtualserver_apikey_manage
///
/// The access scope (scope): "manage", "write", or "read".
/// Lifetime of the key in days (lifetime). Use 0 for unlimited. Use -1 to omit (server default of 14 days applies).
/// Create the key for another client by their database ID (cldbid). Requires b_virtualserver_apikey_manage. Use -1 to create for the invoking user.
/// An with the created key (including the token), or null on error.
public ApiKeyInfo AddApiKey(string scope, int lifetime = -1, int cldbid = -1)
{
var sb = new StringBuilder($"apikeyadd scope={scope}");
if (lifetime != -1) sb.Append($" lifetime={lifetime}");
if (cldbid != -1) sb.Append($" cldbid={cldbid}");
if (SendCommand(sb.ToString(), out QueryResponse res))
return res.Get();
return null;
}
///
/// Deletes the API key with the given numeric ID. Any key owned by the current user can
/// always be deleted. Deleting keys of other users requires b_virtualserver_apikey_manage.
///
/// Required permission: b_virtualserver_apikey_manage
/// The numeric API key ID (id).
/// true on success, false on error.
public bool DeleteApiKey(int id)
=> SendCommand($"apikeydel id={id}");
///
/// Lists API keys. By default lists only keys owned by the invoking user.
///
/// Required permission: b_virtualserver_apikey_manage
///
/// Filter by owner client database ID (cldbid). Pass "*" to list keys of all
/// clients (requires b_virtualserver_apikey_manage). Leave empty for invoking user's keys.
///
/// Skip the first n entries (start). Use -1 to omit.
/// Return at most n entries (duration). Use -1 to omit.
/// When true, sends -count to also return the total number of entries.
/// A list of objects, or null on error.
public List ListApiKeys(string cldbid = "", int start = -1, int duration = -1, bool count = false)
{
var sb = new StringBuilder("apikeylist");
if (!string.IsNullOrEmpty(cldbid)) sb.Append($" cldbid={cldbid}");
if (start != -1) sb.Append($" start={start}");
if (duration != -1) sb.Append($" duration={duration}");
if (count) sb.Append(" -count");
if (SendCommand(sb.ToString(), out QueryResponse res))
return res.GetAll();
return null;
}
///
/// Adds a new ServerQuery login or enables query login for an existing client.
/// Without a selected virtual server, creates a global query login.
/// With a selected virtual server, must be specified to enable
/// query login for an existing client.
///
/// Required permission: b_serverquery_login_create
/// The requested login name (client_login_name).
///
/// The client's database ID to enable query login for (cldbid).
/// Required when a virtual server is selected. Use -1 to omit (global login).
///
///
/// A dictionary with cldbid, sid, client_login_name, and
/// client_login_password, or null on error.
///
public Dictionary AddQueryLogin(string loginName, int cldbid = -1)
{
var sb = new StringBuilder($"queryloginadd client_login_name={loginName.ToTsFormat()}");
if (cldbid != -1) sb.Append($" cldbid={cldbid}");
if (SendCommand(sb.ToString(), out QueryResponse res))
return res.ToDictionary();
return null;
}
///
/// Deletes the ServerQuery login for the client with the given database ID. When no virtual
/// server is selected, deletes global query logins instead.
///
/// Required permission: b_serverquery_login_delete
/// The client's database ID (cldbid).
/// true on success, false on error.
public bool DeleteQueryLogin(int cldbid)
=> SendCommand($"querylogindel cldbid={cldbid}");
///
/// Lists existing ServerQuery logins. Shows only logins for the selected virtual server,
/// or all logins when no virtual server is selected.
///
/// Required permission: b_serverquery_login_list
///
/// Filter by login name pattern (pattern). SQL wildcard characters (e.g. %)
/// are supported. Leave empty to list all.
///
/// Skip the first n entries (start). Use -1 to omit.
/// Return at most n entries (duration). Use -1 to omit.
/// When true, sends -count to also return the total number of entries.
/// A list of login dictionaries with cldbid, sid, and client_login_name, or null on error.
public List> ListQueryLogins(string pattern = "", int start = -1, int duration = -1, bool count = false)
{
var sb = new StringBuilder("queryloginlist");
if (!string.IsNullOrEmpty(pattern)) sb.Append($" pattern={pattern.ToTsFormat()}");
if (start != -1) sb.Append($" start={start}");
if (duration != -1) sb.Append($" duration={duration}");
if (count) sb.Append(" -count");
if (SendCommand(sb.ToString(), out QueryResponse res))
return res.ToDictionaryList();
return null;
}
///
/// Creates a new temporary server password. Clients connecting with this password will
/// automatically join the specified channel.
///
/// Required permission: b_virtualserver_modify_password
/// The temporary password (pw).
/// A descriptive label for the password (desc).
/// The number of seconds the password is valid for (duration).
///
/// The channel clients will automatically join when using this password (tcid).
/// Set to 0 to use the server's default channel.
///
/// The password of the target channel (tcpw). Leave empty if the channel has no password.
/// true on success, false on error.
public bool AddTempServerPassword(string password, string description, int duration, int channelID = 0, string channelPW = "")
=> SendCommand($"servertemppasswordadd pw={password.ToTsFormat()} desc={description.ToTsFormat()} duration={duration} tcid={channelID} tcpw={channelPW.ToTsFormat()}");
///
/// Deletes the temporary server password with the given plain-text password string.
///
/// Required permission: b_virtualserver_modify_password
/// The temporary password to delete (pw).
/// true on success, false on error.
public bool DeleteTempServerPassword(string password)
=> SendCommand($"servertemppassworddel pw={password.ToTsFormat()}");
///
/// Returns a list of active temporary server passwords including their clear-text value,
/// creator nickname/UID, expiry time, and target channel.
///
/// Required permission: b_virtualserver_modify_password
/// A list of temporary password dictionaries, or null on error.
public List> ListTempServerPasswords()
{
if (SendCommand($"servertemppasswordlist", out QueryResponse res))
return res.ToDictionaryList();
return null;
}
}
}