ts3-nodejs-library
Version:
TeamSpeak Server Query API
1,187 lines • 88.4 kB
JavaScript
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.QueryProtocol = exports.TeamSpeak = void 0;
const events_1 = require("events");
const buffer_crc32_1 = __importDefault(require("buffer-crc32"));
const TeamSpeakQuery_1 = require("./transport/TeamSpeakQuery");
const FileTransfer_1 = require("./transport/FileTransfer");
const Client_1 = require("./node/Client");
const Server_1 = require("./node/Server");
const Channel_1 = require("./node/Channel");
const ServerGroup_1 = require("./node/ServerGroup");
const ChannelGroup_1 = require("./node/ChannelGroup");
const Command_1 = require("./transport/Command");
const context_1 = require("./types/context");
const EventError_1 = require("./exception/EventError");
const enum_1 = require("./types/enum");
const Permission_1 = require("./util/Permission");
class TeamSpeak extends events_1.EventEmitter {
constructor(config) {
super();
this.clients = {};
this.servers = {};
this.servergroups = {};
this.channels = {};
this.channelgroups = {};
this.priorizeNextCommand = false;
this.context = {
selectType: context_1.SelectType.NONE,
selected: 0,
events: []
};
this.config = {
protocol: TeamSpeak.QueryProtocol.RAW,
host: "127.0.0.1",
queryport: config.protocol === TeamSpeak.QueryProtocol.SSH ? 10022 : 10011,
readyTimeout: 10000,
ignoreQueries: false,
keepAlive: true,
keepAliveTimeout: 250,
autoConnect: true,
...config
};
this.query = new TeamSpeakQuery_1.TeamSpeakQuery(this.config);
this.query.on("cliententerview", this.evcliententerview.bind(this));
this.query.on("clientleftview", this.evclientleftview.bind(this));
this.query.on("tokenused", this.evtokenused.bind(this));
this.query.on("serveredited", this.evserveredited.bind(this));
this.query.on("channeledited", this.evchanneledited.bind(this));
this.query.on("channelmoved", this.evchannelmoved.bind(this));
this.query.on("channeldeleted", this.evchanneldeleted.bind(this));
this.query.on("channelcreated", this.evchannelcreated.bind(this));
this.query.on("clientmoved", this.evclientmoved.bind(this));
this.query.on("textmessage", this.evtextmessage.bind(this));
this.query.on("ready", this.handleReady.bind(this));
this.query.on("close", (e) => super.emit("close", e));
this.query.on("error", (e) => super.emit("error", e));
this.query.on("flooding", (e) => super.emit("flooding", e));
this.query.on("debug", (data) => super.emit("debug", data));
//@ts-ignore
this.on("newListener", this.handleNewListener.bind(this));
if (this.config.autoConnect)
/** can be dropped silently since errors are getting emitted via the error event */
this.connect().catch(() => null);
}
/**
* connects via a Promise wrapper
* @param config config options to connect
*/
static connect(config) {
return new TeamSpeak({
...config,
autoConnect: false
}).connect();
}
/**
* attempts a reconnect to the teamspeak server with full context features
* @param attempts the amount of times it should try to reconnect (-1 = try forever)
* @param timeout time in ms to wait inbetween reconnect
*/
async reconnect(attempts = 1, timeout = 2000) {
let attempt = 0;
let error = null;
while (attempts === -1 || attempt++ < attempts) {
try {
await TeamSpeak.wait(timeout);
if (this.query.isConnected())
throw new Error("already connected");
await this.connect();
return this;
}
catch (e) {
error = e;
}
}
throw error ? error : new Error(`reconnecting failed after ${attempts} attempt(s)`);
}
/**
* waits a set time of ms
* @param time time in ms to wait
*/
static wait(time) {
return new Promise(fulfill => setTimeout(fulfill, time));
}
/**
* connects to the TeamSpeak Server
*/
connect() {
return new Promise((fulfill, reject) => {
const removeListeners = () => {
this.removeListener("ready", readyCallback);
this.removeListener("error", errorCallback);
this.removeListener("close", closeCallback);
};
const readyCallback = () => {
removeListeners();
fulfill(this);
};
const errorCallback = (error) => {
removeListeners();
this.forceQuit();
reject(error);
};
const closeCallback = (error) => {
removeListeners();
if (error instanceof Error)
return reject(error);
reject(new Error("TeamSpeak Server prematurely closed the connection"));
};
this.once("ready", readyCallback);
this.once("error", errorCallback);
this.once("close", closeCallback);
this.query.connect();
});
}
/** subscribes to some query events if necessary */
handleNewListener(event) {
const commands = [];
switch (event) {
case "clientconnect":
case "clientdisconnect":
case "serveredit":
if (this.isSubscribedToEvent("server"))
break;
commands.push(this.registerEvent("server"));
break;
case "tokenused":
if (this.isSubscribedToEvent("tokenused"))
break;
commands.push(this.registerEvent("tokenused"));
break;
case "channeledit":
case "channelmoved":
case "channeldelete":
case "channelcreate":
case "clientmoved":
if (this.isSubscribedToEvent("channel", "0"))
break;
commands.push(this.registerEvent("channel", "0"));
break;
case "textmessage":
if (!this.isSubscribedToEvent("textserver"))
commands.push(this.registerEvent("textserver"));
if (!this.isSubscribedToEvent("textchannel"))
commands.push(this.registerEvent("textchannel"));
if (!this.isSubscribedToEvent("textprivate"))
commands.push(this.registerEvent("textprivate"));
}
Promise.all(commands).catch(e => this.emit("error", e));
}
/** handles initial commands after successfully connecting to a TeamSpeak Server */
handleReady() {
const exec = [];
if (this.context.login && this.config.protocol === TeamSpeak.QueryProtocol.RAW) {
exec.push(this.priorize().login(this.context.login.username, this.context.login.password));
}
else if (this.config.username && this.config.password && this.config.protocol === TeamSpeak.QueryProtocol.RAW) {
exec.push(this.priorize().login(this.config.username, this.config.password));
}
if (this.context.selectType !== context_1.SelectType.NONE) {
if (this.context.selectType === context_1.SelectType.PORT) {
exec.push(this.priorize().useByPort(this.context.selected, this.context.clientNickname || this.config.nickname));
}
else if (this.context.selectType === context_1.SelectType.SID) {
exec.push(this.priorize().useBySid(this.context.selected, this.context.clientNickname || this.config.nickname));
}
}
else if (this.config.serverport) {
exec.push(this.priorize().useByPort(this.config.serverport, this.config.nickname));
}
exec.push(...this.context.events.map(ev => this.priorize().registerEvent(ev.event, ev.id)));
exec.push(this.priorize().version());
this.query.pause(false);
return Promise.all(exec)
.then(() => super.emit("ready"))
.catch(e => super.emit("error", e));
}
/**
* Gets called when a client connects to the TeamSpeak Server
* @param event the raw teamspeak event
*/
evcliententerview(event) {
this.clientList().then(clients => {
const client = clients.find(client => client.clid === event.clid);
if (!client)
throw new EventError_1.EventError(`could not fetch client with id ${event.clid}`, "cliententerview");
if (this.ignoreQueryClient(client.type))
return;
super.emit("clientconnect", { client, cid: event.ctid });
})
.catch(error => this.emit("error", error));
}
/**
* Gets called when a client discconnects from the TeamSpeak Server
* @param event the raw teamspeak event
*/
evclientleftview(event) {
const { clid } = event;
const client = this.clients[clid];
if (client && this.ignoreQueryClient(client.type))
return;
super.emit("clientdisconnect", { client, event });
Reflect.deleteProperty(this.clients, clid);
}
/**
* Gets called when a client uses a privilege key
* @param event the raw teamspeak event
*/
evtokenused(event) {
this.getClientById(event.clid).then(client => {
if (!client)
throw new EventError_1.EventError(`could not fetch client with id ${event.clid}`, "tokenused");
if (this.ignoreQueryClient(client.type))
return;
super.emit("tokenused", { client, token: event.token, token1: event.token1, token2: event.token2, tokencustomset: event.tokencustomset });
}).catch(e => super.emit("error", e));
}
/**
* Gets called when a chat message gets received
* @param event the raw teamspeak event
*/
evtextmessage(event) {
this.getClientById(event.invokerid).then(invoker => {
if (!invoker)
throw new EventError_1.EventError(`could not fetch client with id ${event.invokerid}`, "textmessage");
if (this.ignoreQueryClient(invoker.type))
return;
super.emit("textmessage", { invoker, msg: event.msg, targetmode: event.targetmode });
}).catch(e => super.emit("error", e));
}
/**
* Gets called when a client moves to a different channel
* @param event the raw teamspeak event
*/
evclientmoved(event) {
Promise.all([
this.getClientById(event.clid),
this.getChannelById(event.ctid)
]).then(([client, channel]) => {
if (!client)
throw new EventError_1.EventError(`could not fetch client with id ${event.clid}`, "clientmoved");
if (!channel)
throw new EventError_1.EventError(`could not fetch channel with id ${event.ctid}`, "clientmoved");
if (this.ignoreQueryClient(client.type))
return;
this.emit("clientmoved", { client, channel, reasonid: event.reasonid });
}).catch(e => this.emit("error", e));
}
/**
* Gets called when the server has been edited
* @param event the raw teamspeak event
*/
async evserveredited(event) {
this.getClientById(event.invokerid).then(invoker => {
if (!invoker)
throw new EventError_1.EventError(`could not fetch client with id ${event.invokerid}`, "serveredited");
if (this.ignoreQueryClient(invoker.type))
return;
const modified = {};
Object.keys(event)
.filter(k => k.startsWith("virtualserver"))
.forEach(k => modified[k] = event[k]);
this.emit("serveredit", { invoker, modified, reasonid: event.reasonid });
}).catch(e => this.emit("error", e));
}
/**
* Gets called when a channel gets edited
* @param event the raw teamspeak event
*/
evchanneledited(event) {
Promise.all([
this.getClientById(event.invokerid),
this.getChannelById(event.cid)
]).then(([invoker, channel]) => {
if (!invoker)
throw new EventError_1.EventError(`could not fetch client with id ${event.invokerid}`, "channeledited");
if (this.ignoreQueryClient(invoker.type))
return;
if (!channel)
throw new EventError_1.EventError(`could not fetch channel with id ${event.cid}`, "channeledited");
const modified = {};
Object.keys(event)
.filter(k => k.startsWith("channel"))
.forEach(k => modified[k] = event[k]);
this.emit("channeledit", {
invoker,
channel,
modified,
reasonid: event.reasonid
});
}).catch(e => this.emit("error", e));
}
/**
* Gets called when a channel gets edited
* @param event the raw teamspeak event
*/
evchannelcreated(event) {
Promise.all([
this.getClientById(event.invokerid),
this.getChannelById(event.cid)
]).then(([invoker, channel]) => {
if (!invoker)
throw new EventError_1.EventError(`could not fetch client with id ${event.invokerid}`, "channelcreated");
if (this.ignoreQueryClient(invoker.type))
return;
if (!channel)
throw new EventError_1.EventError(`could not fetch channel with id ${event.cid}`, "channelcreated");
const modified = {};
Object.keys(event)
.filter(k => k.startsWith("channel"))
.forEach(k => modified[k] = event[k]);
this.emit("channelcreate", {
invoker,
channel,
modified,
cpid: event.cpid
});
}).catch(e => this.emit("error", e));
}
/**
* Gets called when a channel gets moved
* @param event the raw teamspeak event
*/
evchannelmoved(event) {
Promise.all([
this.getClientById(event.invokerid),
this.getChannelById(event.cid),
this.getChannelById(event.cpid)
]).then(([invoker, channel, parent]) => {
if (!invoker)
throw new EventError_1.EventError(`could not fetch client with id ${event.invokerid}`, "channelmoved");
if (this.ignoreQueryClient(invoker.type))
return;
if (!channel)
throw new EventError_1.EventError(`could not fetch channel with id ${event.cid}`, "channelmoved");
this.emit("channelmoved", { invoker, channel, parent, order: event.order });
}).catch(e => this.emit("error", e));
}
/**
* Gets called when a channel gets deleted
* @param event the raw teamspeak event
*/
async evchanneldeleted(event) {
this.getClientById(event.invokerid).then(invoker => {
if (invoker && this.ignoreQueryClient(invoker.type))
return;
this.emit("channeldelete", { invoker, cid: event.cid });
})
.catch(e => this.emit("error", e));
}
/** priorizes the next command, this commands will be first in execution */
priorize() {
this.priorizeNextCommand = true;
return this;
}
/**
* Sends a raw command to the TeamSpeak Server.
* @param {...any} args the command which should get executed on the teamspeak server
* @example
* ts3.execute("clientlist", ["-ip"])
* ts3.execute("use", [9987], { clientnickname: "test" })
*/
execute(cmd, ...args) {
if (this.priorizeNextCommand) {
this.priorizeNextCommand = false;
return this.query.executePrio(cmd, ...args);
}
else {
return this.query.execute(cmd, ...args);
}
}
/**
* Adds a new query client login, or enables query login for existing clients.
* When no virtual server has been selected, the command will create global query logins.
* Otherwise the command enables query login for existing client, and cldbid must be specified.
* @param clientLoginName the login name
* @param client optional database id or teamspeak client
*/
queryLoginAdd(clientLoginName, client) {
return this.execute("queryloginadd", {
clientLoginName,
cldbid: Client_1.TeamSpeakClient.getDbid(client)
}).then(TeamSpeak.singleResponse);
}
/**
* Deletes an existing server query login on selected server.
* When no virtual server has been selected, deletes global query logins instead.
* @param client client database id or teamspeak client object
*/
queryLoginDel(client) {
return this.execute("querylogindel", { cldbid: Client_1.TeamSpeakClient.getDbid(client) });
}
/**
* List existing query client logins.
* The pattern parameter can include regular characters and SQL wildcard characters (e.g. %).
* Only displays query logins of the selected virtual server, or all query logins when no virtual server have been selected.
* @param pattern the pattern to filter for client login names
* @param start the offset from where clients should be listed
* @param duration how many clients should be listed
*/
queryLoginList(pattern, start, duration) {
return this.execute("queryloginlist", { pattern, start, duration }, ["-count"])
.then(TeamSpeak.toArray);
}
apiKeyAdd(props) {
return this.execute("apikeyadd", props)
.then(TeamSpeak.singleResponse);
}
/**
* Lists all apikeys owned by the user, or of all users using cldbid=*.
* Usage of cldbid=... requires bVirtualserverApikeyManage.
*/
apiKeyList(props = {}) {
return this.execute("apikeylist", props, ["-count"])
.then(TeamSpeak.toArray);
}
/**
* Deletes an apikey. Any apikey owned by the current user, can always be deleted
* Deleting apikeys from other requires bVirtualserverApikeyManage
* @param id the key id to delete
*/
apiKeyDel(id) {
return this.execute("apikeydel", { id });
}
/**
* Updates your own ServerQuery login credentials using a specified username.
* The password will be auto-generated.
* @param name
*/
clientSetServerQueryLogin(name) {
return this.execute("clientsetserverquerylogin", { clientLoginName: name })
.then(TeamSpeak.singleResponse);
}
/**
* Change your ServerQuery clients settings using given properties.
* @param props the properties which should be changed
*/
clientUpdate(props) {
return this.execute("clientupdate", props)
.then(this.updateContextResolve({
clientNickname: props.clientNickname ? props.clientNickname : this.context.clientNickname
}));
}
/**
* Subscribes to an Event
* @param event the event on which should be subscribed
* @param id the channel id, only required when subscribing to the "channel" event
*/
registerEvent(event, id) {
return this.execute("servernotifyregister", { event, id })
.then(this.updateContextResolve({ events: [{ event, id }] }));
}
/**
* Subscribes to an Event.
*/
unregisterEvent() {
return this.execute("servernotifyunregister")
.then(this.updateContextResolve({ events: [] }));
}
/**
* Authenticates with the TeamSpeak 3 Server instance using given ServerQuery login credentials.
* @param username the username which you want to login with
* @param password the password you want to login with
*/
login(username, password) {
return this.execute("login", [username, password])
.then(this.updateContextResolve({ login: { username, password } }))
.catch(this.updateContextReject({ login: undefined }));
}
/** Deselects the active virtual server and logs out from the server instance. */
logout() {
return this.execute("logout")
.then(this.updateContextResolve({
selectType: context_1.SelectType.NONE,
clientNickname: this.config.nickname,
login: undefined,
events: []
}));
}
/**
* Displays the servers version information including platform and build number.
* @param refresh if this parameter has been set it will send a command to the server otherwise will use the cached info
*/
async version(refresh = false) {
if (refresh || !this.serverVersion) {
this.serverVersion = await this.execute("version").then(TeamSpeak.singleResponse);
}
return this.serverVersion;
}
/**
* Displays detailed connection information about the server instance including uptime,
* number of virtual servers online, traffic information, etc.
*/
hostInfo() {
return this.execute("hostinfo")
.then(TeamSpeak.singleResponse);
}
/**
* Displays the server instance configuration including database revision number,
* the file transfer port, default group IDs, etc.
*/
instanceInfo() {
return this.execute("instanceinfo")
.then(TeamSpeak.singleResponse);
}
/**
* Changes the server instance configuration using given properties.
* @param properties the props you want to change
*/
instanceEdit(properties) {
return this.execute("instanceedit", properties);
}
/** returns a list of IP addresses used by the server instance on multi-homed machines. */
bindingList() {
return this.execute("bindinglist")
.then(TeamSpeak.toArray);
}
/**
* Selects the virtual server specified with the port to allow further interaction.
* @param port the port the server runs on
* @param clientNickname set nickname when selecting a server
*/
useByPort(port, clientNickname) {
return this.execute("use", { port, clientNickname }, ["-virtual"])
.then(this.updateContextResolve({
selectType: context_1.SelectType.PORT,
selected: port,
clientNickname,
events: []
}))
.catch(this.updateContextReject({ selectType: context_1.SelectType.NONE }));
}
/**
* Selects the virtual server specified with the sid to allow further interaction.
* @param server the server id
* @param clientNickname set nickname when selecting a server
*/
useBySid(server, clientNickname) {
return this.execute("use", [Server_1.TeamSpeakServer.getId(server), "-virtual"], { clientNickname })
.then(this.updateContextResolve({
selectType: context_1.SelectType.SID,
selected: Server_1.TeamSpeakServer.getId(server),
clientNickname,
events: []
}));
}
/** returns information about your current ServerQuery connection including your loginname, etc. */
whoami() {
return this.execute("whoami")
.then(TeamSpeak.singleResponse);
}
/** retrieves the own query client as TeamSpeakClient instance */
async self() {
const { clientId } = await this.whoami();
let client = this.clients[clientId];
if (client)
return client;
client = await this.getClientById(clientId);
if (client)
return client;
throw new Error("could not find own query client");
}
/**
* Displays detailed configuration information about the selected virtual server
* including unique ID, number of clients online, configuration, etc.
*/
serverInfo() {
return this.execute("serverinfo")
.then(TeamSpeak.singleResponse);
}
/**
* Displays the database ID of the virtual server running on the UDP port
* @param virtualserverPort the server port where data should be retrieved
*/
serverIdGetByPort(virtualserverPort) {
return this.execute("serveridgetbyport", { virtualserverPort })
.then(TeamSpeak.singleResponse);
}
/**
* Changes the selected virtual servers configuration using given properties.
* Note that this command accepts multiple properties which means that you're able to change all settings of the selected virtual server at once.
*/
serverEdit(properties) {
return this.execute("serveredit", properties);
}
/**
* Stops the entire TeamSpeak 3 Server instance by shutting down the process.
* @param reasonmsg specifies a text message that is sent to the clients before the client disconnects (requires TeamSpeak Server 3.2.0 or newer).
*/
serverProcessStop(reasonmsg) {
return this.execute("serverprocessstop", { reasonmsg });
}
/**
* returns detailed connection information about the selected virtual server including uptime, traffic information, etc.
*/
connectionInfo() {
return this.execute("serverrequestconnectioninfo")
.then(TeamSpeak.singleResponse);
}
/**
* Creates a new virtual server using the given properties and displays its ID, port and initial administrator privilege key.
* If virtualserverPort is not specified, the server will test for the first unused UDP port
* @param properties the server properties
*/
serverCreate(properties) {
let servertoken = "";
return this.execute("servercreate", properties)
.then(TeamSpeak.singleResponse)
.then(({ token, sid }) => {
servertoken = token;
return this.serverList({ virtualserverId: sid });
})
.then(([server]) => ({ server, token: servertoken }));
}
/**
* deletes the teamspeak server
* @param server the server id to delete
*/
serverDelete(server) {
return this.execute("serverdelete", { sid: Server_1.TeamSpeakServer.getId(server) });
}
/**
* Starts the virtual server. Depending on your permissions,
* you're able to start either your own virtual server only or all virtual servers in the server instance.
* @param server the server id to start
*/
serverStart(server) {
return this.execute("serverstart", { sid: Server_1.TeamSpeakServer.getId(server) });
}
/**
* Stops the virtual server. Depending on your permissions,
* you're able to stop either your own virtual server only or all virtual servers in the server instance.
* @param server the server id to stop
* @param reasonmsg Specifies a text message that is sent to the clients before the client disconnects (requires TeamSpeak Server 3.2.0 or newer).
*/
serverStop(server, reasonmsg) {
return this.execute("serverstop", { sid: Server_1.TeamSpeakServer.getId(server), reasonmsg });
}
/**
* Creates a new server group using the name specified with name.
* The optional type parameter can be used to create ServerQuery groups and template groups.
* @param name the name of the servergroup
* @param type type of the servergroup
*/
serverGroupCreate(name, type = 1) {
return this.execute("servergroupadd", { name, type })
.then(TeamSpeak.singleResponse)
.then(({ sgid }) => this.serverGroupList({ sgid }))
.then(group => group[0]);
}
/**
* returns the IDs of all clients currently residing in the server group.
* @param group the servergroup id
*/
serverGroupClientList(group) {
return this.execute("servergroupclientlist", { sgid: ServerGroup_1.TeamSpeakServerGroup.getId(group) }, ["-names"])
.then(TeamSpeak.toArray);
}
/**
* Adds one or more clients to a server group specified with sgid.
* Please note that a client cannot be added to default groups or template groups
* @param client one or more client database ids which should be added
* @param group the servergroup id which the client(s) should be added to
*/
serverGroupAddClient(client, group) {
return this.execute("servergroupaddclient", {
sgid: ServerGroup_1.TeamSpeakServerGroup.getId(group),
cldbid: Client_1.TeamSpeakClient.getMultipleDbids(client)
});
}
/**
* Removes one or more clients from the server group specified with sgid.
* @param client one or more client database ids which should be added
* @param group the servergroup id which the client(s) should be removed from
*/
serverGroupDelClient(client, group) {
return this.execute("servergroupdelclient", {
sgid: ServerGroup_1.TeamSpeakServerGroup.getId(group),
cldbid: Client_1.TeamSpeakClient.getMultipleDbids(client)
});
}
/**
* displays all server groups the client specified with cldbid is currently residing in
* @param client the client database id to check
*/
serverGroupsByClientId(client) {
return this.execute("servergroupsbyclientid", { cldbid: Client_1.TeamSpeakClient.getMultipleDbids(client) })
.then(TeamSpeak.toArray);
}
/**
* Adds one or more servergroups to a client.
* Please note that a client cannot be added to default groups or template groups
* @param client one or more client database ids which should be added
* @param group one or more servergroup ids which the client should be added to
*/
clientAddServerGroup(client, group) {
return this.execute("clientaddservergroup", {
cldbid: Client_1.TeamSpeakClient.getDbid(client),
sgid: ServerGroup_1.TeamSpeakServerGroup.getMultipleIds(group)
});
}
/**
* Removes one or more servergroups from the client.
* @param client one or more client database ids which should be added
* @param groups one or more servergroup ids which the client should be removed from
*/
clientDelServerGroup(client, groups) {
return this.execute("clientdelservergroup", {
cldbid: Client_1.TeamSpeakClient.getDbid(client),
sgid: ServerGroup_1.TeamSpeakServerGroup.getMultipleIds(groups)
});
}
/**
* Deletes the server group. If force is set to 1, the server group will be deleted even if there are clients within.
* @param group the servergroup id
* @param force if set to 1 the servergoup will be deleted even when clients stil belong to this group
*/
serverGroupDel(group, force = false) {
return this.execute("servergroupdel", { sgid: ServerGroup_1.TeamSpeakServerGroup.getId(group), force });
}
/**
* Creates a copy of the server group specified with ssgid.
* If tsgid is set to 0, the server will create a new group.
* To overwrite an existing group, simply set tsgid to the ID of a designated target group.
* If a target group is set, the name parameter will be ignored.
* @param sourceGroup the source ServerGroup
* @param targetGroup the target ServerGroup, 0 to create a new Group
* @param type the type of the servergroup (0 = Query Group | 1 = Normal Group)
* @param name name of the group
*/
serverGroupCopy(sourceGroup, targetGroup = "0", type = 1, name = "foo") {
return this.execute("servergroupcopy", {
ssgid: ServerGroup_1.TeamSpeakServerGroup.getId(sourceGroup),
tsgid: ServerGroup_1.TeamSpeakServerGroup.getId(targetGroup),
type,
name
}).then(TeamSpeak.singleResponse);
}
/**
* Changes the name of the server group
* @param group the servergroup id
* @param name new name of the servergroup
*/
serverGroupRename(group, name) {
return this.execute("servergrouprename", { sgid: ServerGroup_1.TeamSpeakServerGroup.getId(group), name });
}
/**
* Displays a list of permissions assigned to the server group specified with sgid.
* @param sgid the servergroup id
* @param permsid if the permsid option is set to true the output will contain the permission names
*/
serverGroupPermList(group, permsid = false) {
const sgid = ServerGroup_1.TeamSpeakServerGroup.getId(group);
return this.execute("servergrouppermlist", { sgid }, [permsid ? "-permsid" : null]).then(response => {
return response.map(perm => {
return this.createServerGroupPermBuilder(sgid)
.perm(perm.permsid || perm.permid)
.value(perm.permvalue)
.skip(perm.permskip)
.negate(perm.permnegated);
});
});
}
serverGroupAddPerm(group, perm) {
const builder = this.createServerGroupPermBuilder(ServerGroup_1.TeamSpeakServerGroup.getId(group));
if (!perm)
return builder;
if (perm.permskip)
builder.skip(perm.permskip);
if (perm.permnegated)
builder.negate(perm.permnegated);
return builder.perm(perm.permname).value(perm.permvalue).update();
}
/**
* Removes a set of specified permissions from the server group.
* A permission can be specified by permid or permsid.
* @param group the servergroup id
* @param perm the permid or permsid
*/
serverGroupDelPerm(group, perm) {
const properties = { sgid: ServerGroup_1.TeamSpeakServerGroup.getId(group) };
properties[typeof perm === "string" ? "permsid" : "permid"] = perm;
return this.execute("servergroupdelperm", properties);
}
/**
* Sets a new temporary server password specified with pw. The temporary
* password will be valid for the number of seconds specified with duration. The
* client connecting with this password will automatically join the channel
* specified with tcid. If tcid is set to 0, the client will join the default
* channel.
*/
serverTempPasswordAdd(props) {
return this.execute("servertemppasswordadd", { tcid: "0", tcpw: "", desc: "", ...props });
}
/**
* Deletes the temporary server password specified with pw.
* @param pw the password to delete
*/
serverTempPasswordDel(pw) {
return this.execute("servertemppassworddel", { pw });
}
/**
* Returns a list of active temporary server passwords. The output contains the
* clear-text password, the nickname and unique identifier of the creating
* client.
*/
serverTempPasswordList() {
return this.execute("servertemppasswordlist")
.then(TeamSpeak.toArray);
}
/**
* Creates a new channel using the given properties.
* Note that this command accepts multiple properties which means that you're able to specifiy all settings of the new channel at once.
* @param name the name of the channel
* @param properties properties of the channel
*/
channelCreate(name, properties = {}) {
properties.channelName = name;
return this.execute("channelcreate", properties)
.then(TeamSpeak.singleResponse)
.then(({ cid }) => this.channelList({ cid }))
.then(([channel]) => channel);
}
/**
* Creates a new channel group using a given name.
* The optional type parameter can be used to create ServerQuery groups and template groups.
* @param name the name of the channelgroup
* @param type type of the channelgroup
*/
channelGroupCreate(name, type = 1) {
return this.execute("channelgroupadd", { name, type })
.then(TeamSpeak.singleResponse)
.then(({ cgid }) => this.channelGroupList({ cgid }))
.then(([group]) => group);
}
/**
* Retrieves a Single Channel by the given Channel ID
* @param channel the channel id
*/
getChannelById(channel) {
return this.channelList({ cid: Channel_1.TeamSpeakChannel.getId(channel) }).then(([channel]) => channel);
}
/**
* Retrieves a Single Channel by the given Channel Name
* @param channelName the name of the channel
*/
getChannelByName(channelName) {
return this.channelList({ channelName }).then(([channel]) => channel);
}
/**
* displays a list of channels matching a given name pattern
* @param pattern the channel name pattern to search for
*/
channelFind(pattern) {
return this.execute("channelfind", { pattern }).then(TeamSpeak.toArray);
}
/**
* Displays detailed configuration information about a channel including ID, topic, description, etc.
* @param channel the channel id
*/
channelInfo(channel) {
return this.execute("channelinfo", { cid: Channel_1.TeamSpeakChannel.getId(channel) }).then(TeamSpeak.singleResponse);
}
/**
* Moves a channel to a new parent channel with the ID cpid.
* If order is specified, the channel will be sorted right under the channel with the specified ID.
* If order is set to 0, the channel will be sorted right below the new parent.
* @param channel the channel id
* @param parent channel parent id
* @param order channel sort order
*/
channelMove(channel, parent, order = 0) {
return this.execute("channelmove", {
cid: Channel_1.TeamSpeakChannel.getId(channel),
cpid: Channel_1.TeamSpeakChannel.getId(parent),
order
});
}
/**
* Deletes an existing channel by ID.
* If force is set to 1, the channel will be deleted even if there are clients within.
* The clients will be kicked to the default channel with an appropriate reason message.
* @param channel the channel id
* @param force if set to 1 the channel will be deleted even when client are in it
*/
channelDelete(channel, force = false) {
return this.execute("channeldelete", { cid: Channel_1.TeamSpeakChannel.getId(channel), force });
}
/**
* Changes a channels configuration using given properties.
* Note that this command accepts multiple properties which means that you're able to change all settings of the channel specified with cid at once.
* @param channel the channel id
* @param properties the properties of the channel which should get changed
*/
async channelEdit(channel, properties = {}) {
const cid = Channel_1.TeamSpeakChannel.getId(channel);
if (typeof properties.channelName === "string") {
if (!this.isSubscribedToEvent("server") || Object.keys(this.channels).length === 0)
await this.channelList();
const c = await this.channels[cid];
if (c && properties.channelName === c.name)
delete properties.channelName;
if (Object.keys(properties).length === 0)
return [];
}
properties.cid = cid;
return this.execute("channeledit", properties);
}
/**
* Displays a list of permissions defined for a channel.
* @param channel the channel id
* @param permsid whether the permsid should be displayed aswell
*/
channelPermList(channel, permsid = false) {
const cid = Channel_1.TeamSpeakChannel.getId(channel);
return this.execute("channelpermlist", { cid }, [permsid ? "-permsid" : null]).then(response => {
return response.map(perm => {
return this.createChannelPermBuilder(cid)
.perm(perm.permsid || perm.permid)
.value(perm.permvalue);
});
});
}
channelSetPerm(channel, perm) {
const builder = this.createChannelPermBuilder(Channel_1.TeamSpeakChannel.getId(channel));
if (!perm)
return builder;
return builder.perm(perm.permname).value(perm.permvalue).update();
}
/**
* Adds a set of specified permissions to a channel.
* A permission can be specified by permid or permsid.
* @param channel the channel id
* @param permissions the permissions to assign
* @example
* TeamSpeak.channelSetPerms(5, [{ permsid: "i_channel_needed_modify_power", permvalue: 75 }])
*/
channelSetPerms(channel, permissions) {
return this.execute("channeladdperm", { cid: Channel_1.TeamSpeakChannel.getId(channel) }, permissions);
}
/**
* Removes a set of specified permissions from a channel.
* Multiple permissions can be removed at once.
* A permission can be specified by permid or permsid.
* @param channel the channel id
* @param perm the permid or permsid
*/
channelDelPerm(channel, perm) {
const prop = { cid: Channel_1.TeamSpeakChannel.getId(channel) };
prop[typeof perm === "string" ? "permsid" : "permid"] = perm;
return this.execute("channeldelperm", prop);
}
/**
* Retrieves a Single Client by the given Client ID
* @param client the client id
*/
getClientById(client) {
return this.clientList({ clid: Client_1.TeamSpeakClient.getId(client) })
.then(([client]) => client);
}
/**
* Retrieves a Single Client by the given Client Database ID
* @param client the client database Id
*/
getClientByDbid(client) {
return this.clientList({ clientDatabaseId: Client_1.TeamSpeakClient.getDbid(client) })
.then(([client]) => client);
}
/**
* Retrieves a Single Client by the given Client Unique Identifier
* @param client the client unique identifier
*/
getClientByUid(client) {
return this.clientList({ clientUniqueIdentifier: Client_1.TeamSpeakClient.getUid(client) })
.then(([client]) => client);
}
/**
* Retrieves a Single Client by the given Client Unique Identifier
* @param clientNickname the nickname of the client
*/
getClientByName(clientNickname) {
return this.clientList({ clientNickname })
.then(([client]) => client);
}
/**
* Returns General Info of the Client, requires the Client to be online
* @param clients one or more client ids to get
*/
clientInfo(clients) {
return this.execute("clientinfo", { clid: Client_1.TeamSpeakClient.getMultipleIds(clients) })
.then(TeamSpeak.toArray);
}
/**
* Returns the Clients Database List
* @param start start offset
* @param duration amount of entries which should get retrieved
* @param count retrieve the count of entries
*/
clientDbList(start = 0, duration = 1000, count = true) {
return this.execute("clientdblist", { start, duration }, [count ? "-count" : null])
.then(TeamSpeak.toArray);
}
/**
* Returns the Clients Database Info
* @param clients one or more client database ids to get
*/
clientDbInfo(clients) {
return this.execute("clientdbinfo", { cldbid: Client_1.TeamSpeakClient.getMultipleDbids(clients) })
.then(TeamSpeak.toArray);
}
/**
* Kicks the Client from the Server
* @param client the client id
* @param reasonid the reasonid
* @param reasonmsg the message the client should receive when getting kicked
* @param continueOnError ignore errors
*/
clientKick(client, reasonid, reasonmsg, continueOnError = false) {
const flags = [];
if (continueOnError)
flags.push("-continueonerror");
return this.execute("clientkick", {
clid: Client_1.TeamSpeakClient.getId(client),
reasonid,
reasonmsg
}, flags);
}
/**
* Moves the Client to a different Channel
* @param client the client id
* @param channel channel id in which the client should get moved
* @param cpw the channel password
* @param continueOnError ignore errors
*/
clientMove(client, channel, cpw, continueOnError = false) {
const flags = [];
if (continueOnError)
flags.push("-continueonerror");
return this.execute("clientmove", {
clid: Client_1.TeamSpeakClient.getId(client),
cid: Channel_1.TeamSpeakChannel.getId(channel),
cpw
}, flags);
}
/**
* Pokes the Client with a certain message
* @param client the client id
* @param msg the message the client should receive
*/
clientPoke(client, msg) {
return this.execute("clientpoke", { clid: Client_1.TeamSpeakClient.getId(client), msg });
}
/**
* Displays a list of permissions defined for a client
* @param client the client database id
* @param permsid if the permsid option is set to true the output will contain the permission names
*/
clientPermList(client, permsid = false) {
const cldbid = Client_1.TeamSpeakClient.getDbid(client);
return this.execute("clientpermlist", { cldbid }, [permsid ? "-permsid" : null]).then(response => {
return response.map(perm => {
return this.createClientPermBuilder(cldbid)
.perm(perm.permsid || perm.permid)
.value(perm.permvalue)
.skip(perm.permskip)
.negate(perm.permnegated);
});
});
}
clientAddPerm(client, perm) {
const builder = this.createClientPermBuilder(Client_1.TeamSpeakClient.getDbid(client));
if (!perm)
return builder;
if (perm.permskip)
builder.skip(perm.permskip);
if (perm.permnegated)
builder.negate(perm.permnegated);
return builder.perm(perm.permname).value(perm.permvalue).update();
}
/**
* Removes a set of specified permissions from a client.
* Multiple permissions can be removed at once.
* A permission can be specified by permid or permsid
* @param client the client database id
* @param perm the permid or permsid
*/
clientDelPerm(client, perm) {
const properties = { cldbid: Client_1.TeamSpeakClient.getDbid(client) };
properties[typeof perm === "string" ? "permsid" : "permid"] = perm;
return this.execute("clientdelperm", properties);
}
/**
* Searches for custom client properties specified by ident and value.
* The value parameter can include regular characters and SQL wildcard characters (e.g. %).
* @param ident the key to search for
* @param pattern the search pattern to use
*/
async customSearch(ident, pattern) {
try {
return await this.execute("customsearch", { ident, pattern });
}
catch (e) {
if (e.id !== "1281")
return []; //empty result set
throw e;
}
}
/**
* returns a list of custom properties for the client specified with cldbid.
* @param client the Client Database ID which should be retrieved
*/
async customInfo(client) {
try {
return await this.execute("custominfo", { cldbid: Client_1.TeamSpeakClient.getDbid(client) });
}
catch (e) {
if (e.id === "1281")
return []; //empty result set
throw e;
}
}
/**
* Removes a custom property from a client specified by the cldbid.
* This requires TeamSpeak Server Version 3.2.0 or newer.
* @param client the client Database ID which should be changed
* @param ident the key which should be deleted
*/
customDelete(client, ident) {
return this.execute("customdelete", { cldbid: Client_1.TeamSpeakClient.getDbid(client), ident });
}
/**
* Creates or updates a custom property for client specified by the cldbid.
* Ident and value can be any value, and are the key value pair of the custom property.
* This requires TeamSpeak Server Version 3.2.0 or newer.
* @param client the client database id which should be changed
* @param ident the key which should be set
* @param value the value which should be set
*/
customSet(client, ident, value) {
return this.execute("customset", { cldbid: Client_1.TeamSpeakClient.getDbid(client), ident, value });
}
sendTextMessage(target, targetmode, msg) {
let selectedTarget = "0";
if (targetmode === enum_1.TextMessageTargetMode.CLIENT) {
selectedTarget = Client_1.TeamSpeakClient.getId(target);
}
else if (targetmode === enum_1.TextMessageTargetMode.CHANNEL) {
selectedTarget = Channel_1.TeamSpeakChannel.getId(target);
}
return this.execute("sendtextmessage", { target: selectedTarget, targetmode, msg });
}
/**
* sends a message to a teamspeak channel,
* if the client is not in this channel he will move into the channel, send the message and move back after
* @param target the target channel to send the message
* @param msg the message which should be sent
*/
async sendChannelMessage(target, msg) {
const self = await this.self();
const sourceChannel = self.cid;
const cid = Channel_1.TeamSpeakChannel.getId(target);
const orders = [];
if (sourceChannel !== cid)
orders.push(self.move(cid));
orders.push(this