com.github.theholywaffle.teamspeak3.TS3ApiAsync Maven / Gradle / Ivy
Show all versions of teamspeak3-api Show documentation
package com.github.theholywaffle.teamspeak3;
/*
* #%L
* TeamSpeak 3 Java API
* %%
* Copyright (C) 2014 Bert De Geyter
* %%
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
* #L%
*/
import com.github.theholywaffle.teamspeak3.api.*;
import com.github.theholywaffle.teamspeak3.api.event.TS3EventType;
import com.github.theholywaffle.teamspeak3.api.event.TS3Listener;
import com.github.theholywaffle.teamspeak3.api.exception.TS3CommandFailedException;
import com.github.theholywaffle.teamspeak3.api.exception.TS3FileTransferFailedException;
import com.github.theholywaffle.teamspeak3.api.wrapper.*;
import com.github.theholywaffle.teamspeak3.commands.*;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.regex.Pattern;
/**
* Asynchronous version of {@link TS3Api} to interact with the {@link TS3Query}.
*
* This class is used to easily interact with a {@link TS3Query}. It constructs commands,
* sends them to the TeamSpeak3 server, processes the response and returns the result.
*
* All methods in this class are asynchronous (so they won't block) and
* will return a {@link CommandFuture} of the corresponding return type in {@link TS3Api}.
* If a command fails, no exception will be thrown directly. It will however be rethrown in
* {@link CommandFuture#get()} and {@link CommandFuture#get(long, TimeUnit)}.
* Usually, the thrown exception is a {@link TS3CommandFailedException}, which will get you
* access to the {@link QueryError} from which more information about the error can be obtained.
*
* Also note that while these methods are asynchronous, the commands will still be sent through a
* synchronous command pipeline. That means if an asynchronous method is called immediately
* followed by a synchronous method, the synchronous method will first have to wait until the
* asynchronous method completed until it its command is sent.
*
* You won't be able to execute most commands while you're not logged in due to missing permissions.
* Make sure to either pass your login credentials to the {@link TS3Config} object when
* creating the {@code TS3Query} or to call {@link #login(String, String)} to log in.
*
* After that, most commands also require you to select a {@linkplain VirtualServer virtual server}.
* To do so, call either {@link #selectVirtualServerByPort(int)} or {@link #selectVirtualServerById(int)}.
*
*
* @see TS3Api The synchronous version of the API
*/
public class TS3ApiAsync {
/**
* The TS3 query to which this API sends its commands.
*/
private final TS3Query query;
/**
* Creates a new asynchronous API object for the given {@code TS3Query}.
*
* Usually, this constructor should not be called. Use {@link TS3Query#getAsyncApi()} instead.
*
*
* @param query
* the TS3Query to call
*/
public TS3ApiAsync(TS3Query query) {
this.query = query;
}
/**
* Adds a new ban entry. At least one of the parameters {@code ip}, {@code name} or {@code uid} needs to be not null.
* Returns the ID of the newly created ban.
*
* @param ip
* a RegEx pattern to match a client's IP against, can be null
* @param name
* a RegEx pattern to match a client's name against, can be null
* @param uid
* the unique identifier of a client, can be null
* @param timeInSeconds
* the duration of the ban in seconds. 0 equals a permanent ban
* @param reason
* the reason for the ban, can be null
*
* @return the ID of the newly created ban entry
*
* @querycommands 1
* @see Pattern RegEx Pattern
* @see Client#getId()
* @see Client#getUniqueIdentifier()
* @see ClientInfo#getIp()
*/
public CommandFuture addBan(String ip, String name, String uid, long timeInSeconds, String reason) {
if (ip == null && name == null && uid == null) {
throw new IllegalArgumentException("Either IP, Name or UID must be set");
}
final CBanAdd add = new CBanAdd(ip, name, uid, timeInSeconds, reason);
return executeAndReturnIntProperty(add, "banid");
}
/**
* Adds a specified permission to a client in a specific channel.
*
* @param channelId
* the ID of the channel wherein the permission should be granted
* @param clientDBId
* the database ID of the client to add a permission to
* @param permName
* the name of the permission to grant
* @param permValue
* the numeric value of the permission (or for boolean permissions: 1 = true, 0 = false)
*
* @return whether the command succeeded or not
*
* @querycommands 1
* @see Channel#getId()
* @see Client#getDatabaseId()
* @see Permission
*/
public CommandFuture addChannelClientPermission(int channelId, int clientDBId, String permName, int permValue) {
final CChannelClientAddPerm add = new CChannelClientAddPerm(channelId, clientDBId, permName, permValue);
return executeAndReturnError(add);
}
/**
* Creates a new channel group for clients using a given name and returns its ID.
*
* To create channel group templates or ones for server queries,
* use {@link #addChannelGroup(String, PermissionGroupDatabaseType)}.
*
*
* @param name
* the name of the new channel group
*
* @return the ID of the newly created channel group
*
* @querycommands 1
* @see ChannelGroup
*/
public CommandFuture addChannelGroup(String name) {
return addChannelGroup(name, null);
}
/**
* Creates a new channel group using a given name and returns its ID.
*
* @param name
* the name of the new channel group
* @param type
* the desired type of channel group
*
* @return the ID of the newly created channel group
*
* @querycommands 1
* @see ChannelGroup
*/
public CommandFuture addChannelGroup(String name, PermissionGroupDatabaseType type) {
final CChannelGroupAdd add = new CChannelGroupAdd(name, type);
return executeAndReturnIntProperty(add, "cgid");
}
/**
* Adds a specified permission to a channel group.
*
* @param groupId
* the ID of the channel group to grant the permission
* @param permName
* the name of the permission to be granted
* @param permValue
* the numeric value of the permission (or for boolean permissions: 1 = true, 0 = false)
*
* @return whether the command succeeded or not
*
* @querycommands 1
* @see ChannelGroup#getId()
* @see Permission
*/
public CommandFuture addChannelGroupPermission(int groupId, String permName, int permValue) {
final CChannelGroupAddPerm add = new CChannelGroupAddPerm(groupId, permName, permValue);
return executeAndReturnError(add);
}
/**
* Adds a specified permission to a channel.
*
* @param channelId
* the ID of the channel wherein the permission should be granted
* @param permName
* the name of the permission to grant
* @param permValue
* the numeric value of the permission (or for boolean permissions: 1 = true, 0 = false)
*
* @return whether the command succeeded or not
*
* @querycommands 1
* @see Channel#getId()
* @see Permission
*/
public CommandFuture addChannelPermission(int channelId, String permName, int permValue) {
final CChannelAddPerm perm = new CChannelAddPerm(channelId, permName, permValue);
return executeAndReturnError(perm);
}
/**
* Adds a specified permission to a channel.
*
* @param clientDBId
* the database ID of the client to grant the permission
* @param permName
* the name of the permission to grant
* @param value
* the numeric value of the permission (or for boolean permissions: 1 = true, 0 = false)
* @param skipped
* if set to {@code true}, the permission will not be overridden by channel group permissions
*
* @return whether the command succeeded or not
*
* @querycommands 1
* @see Client#getDatabaseId()
* @see Permission
*/
public CommandFuture addClientPermission(int clientDBId, String permName, int value, boolean skipped) {
final CClientAddPerm add = new CClientAddPerm(clientDBId, permName, value, skipped);
return executeAndReturnError(add);
}
/**
* Adds a client to the specified server group.
*
* Please note that a client cannot be added to default groups or template groups.
*
*
* @param groupId
* the ID of the server group to add the client to
* @param clientDatabaseId
* the database ID of the client to add
*
* @return whether the command succeeded or not
*
* @querycommands 1
* @see ServerGroup#getId()
* @see Client#getDatabaseId()
*/
public CommandFuture addClientToServerGroup(int groupId, int clientDatabaseId) {
final CServerGroupAddClient add = new CServerGroupAddClient(groupId, clientDatabaseId);
return executeAndReturnError(add);
}
/**
* Submits a complaint about the specified client.
* The length of the message is limited to 200 UTF-8 bytes and BB codes in it will be ignored.
*
* @param clientDBId
* the database ID of the client
* @param message
* the message of the complaint, may not contain BB codes
*
* @return whether the command succeeded or not
*
* @querycommands 1
* @see Client#getDatabaseId()
* @see Complaint#getMessage()
*/
public CommandFuture addComplaint(int clientDBId, String message) {
final CComplainAdd add = new CComplainAdd(clientDBId, message);
return executeAndReturnError(add);
}
/**
* Adds a specified permission to all server groups of the type specified by {@code type} on all virtual servers.
*
* @param type
* the kind of server group this permission should be added to
* @param permName
* the name of the permission to be granted
* @param value
* the numeric value of the permission (or for boolean permissions: 1 = true, 0 = false)
* @param negated
* if set to true, the lowest permission value will be selected instead of the highest
* @param skipped
* if set to true, this permission will not be overridden by client or channel group permissions
*
* @return whether the command succeeded or not
*
* @querycommands 1
* @see ServerGroupType
* @see Permission
*/
public CommandFuture addPermissionToAllServerGroups(ServerGroupType type, String permName, int value, boolean negated, boolean skipped) {
final CServerGroupAutoAddPerm add = new CServerGroupAutoAddPerm(type, permName, value, negated, skipped);
return executeAndReturnError(add);
}
/**
* Create a new privilege key that allows one client to join a server or channel group.
*
* - If {@code type} is set to {@linkplain PrivilegeKeyType#SERVER_GROUP SERVER_GROUP},
* {@code groupId} is used as a server group ID and {@code channelId} is ignored.
* - If {@code type} is set to {@linkplain PrivilegeKeyType#CHANNEL_GROUP CHANNEL_GROUP},
* {@code groupId} is used as a channel group ID and {@code channelId} is used as the channel in which the group should be set.
*
*
* @param type
* the type of token that should be created
* @param groupId
* the ID of the server or channel group
* @param channelId
* the ID of the channel, in case the token is channel group token
* @param description
* the description for the token, can be null
*
* @return the created token for a client to use
*
* @querycommands 1
* @see PrivilegeKeyType
* @see #addPrivilegeKeyServerGroup(int, String)
* @see #addPrivilegeKeyChannelGroup(int, int, String)
*/
public CommandFuture addPrivilegeKey(PrivilegeKeyType type, int groupId, int channelId, String description) {
final CPrivilegeKeyAdd add = new CPrivilegeKeyAdd(type, groupId, channelId, description);
return executeAndReturnStringProperty(add, "token");
}
/**
* Creates a new privilege key for a channel group.
*
* @param channelGroupId
* the ID of the channel group
* @param channelId
* the ID of the channel in which the channel group should be set
* @param description
* the description for the token, can be null
*
* @return the created token for a client to use
*
* @querycommands 1
* @see ChannelGroup#getId()
* @see Channel#getId()
* @see #addPrivilegeKey(PrivilegeKeyType, int, int, String)
* @see #addPrivilegeKeyServerGroup(int, String)
*/
public CommandFuture addPrivilegeKeyChannelGroup(int channelGroupId, int channelId, String description) {
return addPrivilegeKey(PrivilegeKeyType.CHANNEL_GROUP, channelGroupId, channelId, description);
}
/**
* Creates a new privilege key for a server group.
*
* @param serverGroupId
* the ID of the server group
* @param description
* the description for the token, can be null
*
* @return the created token for a client to use
*
* @querycommands 1
* @see ServerGroup#getId()
* @see #addPrivilegeKey(PrivilegeKeyType, int, int, String)
* @see #addPrivilegeKeyChannelGroup(int, int, String)
*/
public CommandFuture addPrivilegeKeyServerGroup(int serverGroupId, String description) {
return addPrivilegeKey(PrivilegeKeyType.SERVER_GROUP, serverGroupId, 0, description);
}
/**
* Creates a new server group for clients using a given name and returns its ID.
*
* To create server group templates or ones for server queries,
* use {@link #addServerGroup(String, PermissionGroupDatabaseType)}.
*
*
* @param name
* the name of the new server group
*
* @return the ID of the newly created server group
*
* @querycommands 1
* @see ServerGroup
*/
public CommandFuture addServerGroup(String name) {
return addServerGroup(name, PermissionGroupDatabaseType.REGULAR);
}
/**
* Creates a new server group using a given name and returns its ID.
*
* @param name
* the name of the new server group
* @param type
* the desired type of server group
*
* @return the ID of the newly created server group
*
* @querycommands 1
* @see ServerGroup
* @see PermissionGroupDatabaseType
*/
public CommandFuture addServerGroup(String name, PermissionGroupDatabaseType type) {
final CServerGroupAdd add = new CServerGroupAdd(name, type);
return executeAndReturnIntProperty(add, "sgid");
}
/**
* Adds a specified permission to a server group.
*
* @param groupId
* the ID of the channel group to which the permission should be added
* @param permName
* the name of the permission to add
* @param value
* the numeric value of the permission (or for boolean permissions: 1 = true, 0 = false)
* @param negated
* if set to true, the lowest permission value will be selected instead of the highest
* @param skipped
* if set to true, this permission will not be overridden by client or channel group permissions
*
* @return whether the command succeeded or not
*
* @querycommands 1
* @see ServerGroup#getId()
* @see Permission
*/
public CommandFuture addServerGroupPermission(int groupId, String permName, int value, boolean negated, boolean skipped) {
final CServerGroupAddPerm add = new CServerGroupAddPerm(groupId, permName, value, negated, skipped);
return executeAndReturnError(add);
}
/**
* Adds one or more {@link TS3Listener}s to the event manager of the query.
* These listeners will be notified when the TS3 server fires an event.
*
* Note that for the TS3 server to fire events, you must first also register
* the event types you want to listen to.
*
*
* @param listeners
* one or more listeners to register
*
* @see #registerAllEvents()
* @see #registerEvent(TS3EventType, int)
* @see TS3Listener
* @see TS3EventType
*/
public void addTS3Listeners(TS3Listener... listeners) {
query.getEventManager().addListeners(listeners);
}
/**
* Bans a client with a given client ID for a given time.
*
* Please note that this will create two separate ban rules,
* one for the targeted client's IP address and their unique identifier.
*
* Exception: If the banned client connects via a loopback address
* (i.e. {@code 127.0.0.1} or {@code localhost}), no IP ban is created
* and the returned array will only have 1 entry.
*
*
* @param clientId
* the ID of the client
* @param timeInSeconds
* the duration of the ban in seconds. 0 equals a permanent ban
*
* @return an array containing the IDs of the first and the second ban entry
*
* @querycommands 1
* @see Client#getId()
* @see #addBan(String, String, String, long, String)
*/
public CommandFuture banClient(int clientId, long timeInSeconds) {
return banClient(clientId, timeInSeconds, null);
}
/**
* Bans a client with a given client ID for a given time for the specified reason.
*
* Please note that this will create two separate ban rules,
* one for the targeted client's IP address and their unique identifier.
*
* Exception: If the banned client connects via a loopback address
* (i.e. {@code 127.0.0.1} or {@code localhost}), no IP ban is created
* and the returned array will only have 1 entry.
*
*
* @param clientId
* the ID of the client
* @param timeInSeconds
* the duration of the ban in seconds. 0 equals a permanent ban
* @param reason
* the reason for the ban, can be null
*
* @return an array containing the IDs of the first and the second ban entry
*
* @querycommands 1
* @see Client#getId()
* @see #addBan(String, String, String, long, String)
*/
public CommandFuture banClient(int clientId, long timeInSeconds, String reason) {
final CBanClient client = new CBanClient(clientId, timeInSeconds, reason);
final CommandFuture future = new CommandFuture<>();
query.doCommandAsync(client, new Callback() {
@Override
public void handle() {
if (hasFailed(client, future)) return;
final List response = client.getResponse();
final int[] banIds = new int[response.size()];
for (int i = 0; i < banIds.length; ++i) {
banIds[i] = response.get(i).getInt("banid");
}
future.set(banIds);
}
});
return future;
}
/**
* Bans a client with a given client ID permanently for the specified reason.
*
* Please note that this will create two separate ban rules,
* one for the targeted client's IP address and their unique identifier.
*
* Exception: If the banned client connects via a loopback address
* (i.e. {@code 127.0.0.1} or {@code localhost}), no IP ban is created
* and the returned array will only have 1 entry.
*
*
* @param clientId
* the ID of the client
* @param reason
* the reason for the ban, can be null
*
* @return an array containing the IDs of the first and the second ban entry
*
* @querycommands 1
* @see Client#getId()
* @see #addBan(String, String, String, long, String)
*/
public CommandFuture banClient(int clientId, String reason) {
return banClient(clientId, 0, reason);
}
/**
* Sends a text message to all clients on all virtual servers.
* These messages will appear to clients in the tab for server messages.
*
* @param message
* the message to be sent
*
* @return whether the command succeeded or not
*
* @querycommands 1
*/
public CommandFuture broadcast(String message) {
final CGM broadcast = new CGM(message);
return executeAndReturnError(broadcast);
}
/**
* Creates a copy of the channel group specified by {@code sourceGroupId},
* overwriting any other channel group specified by {@code targetGroupId}.
*
* The parameter {@code type} can be used to create server query and template groups.
*
*
* @param sourceGroupId
* the ID of the channel group to copy
* @param targetGroupId
* the ID of another channel group to overwrite
* @param type
* the desired type of channel group
*
* @return whether the command succeeded or not
*
* @querycommands 1
* @see ChannelGroup#getId()
*/
public CommandFuture copyChannelGroup(int sourceGroupId, int targetGroupId, PermissionGroupDatabaseType type) {
if (targetGroupId <= 0) {
throw new IllegalArgumentException("To create a new channel group, use the method with a String argument");
}
final CChannelGroupCopy copy = new CChannelGroupCopy(sourceGroupId, targetGroupId, type);
return executeAndReturnError(copy);
}
/**
* Creates a copy of the channel group specified by {@code sourceGroupId} with a given name
* and returns the ID of the newly created channel group.
*
* @param sourceGroupId
* the ID of the channel group to copy
* @param targetName
* the name for the copy of the channel group
* @param type
* the desired type of channel group
*
* @return the ID of the newly created channel group
*
* @querycommands 1
* @see ChannelGroup#getId()
*/
public CommandFuture copyChannelGroup(int sourceGroupId, String targetName, PermissionGroupDatabaseType type) {
final CChannelGroupCopy copy = new CChannelGroupCopy(sourceGroupId, targetName, type);
return executeAndReturnIntProperty(copy, "cgid");
}
/**
* Creates a copy of the server group specified by {@code sourceGroupId},
* overwriting another server group specified by {@code targetGroupId}.
*
* The parameter {@code type} can be used to create server query and template groups.
*
*
* @param sourceGroupId
* the ID of the server group to copy
* @param targetGroupId
* the ID of another server group to overwrite
* @param type
* the desired type of server group
*
* @return whether the command succeeded or not
*
* @querycommands 1
* @see ServerGroup#getId()
*/
public CommandFuture copyServerGroup(int sourceGroupId, int targetGroupId, PermissionGroupDatabaseType type) {
if (targetGroupId <= 0) {
throw new IllegalArgumentException("To create a new server group, use the method with a String argument");
}
final CServerGroupCopy copy = new CServerGroupCopy(sourceGroupId, targetGroupId, type);
return executeAndReturnIntProperty(copy, "sgid");
}
/**
* Creates a copy of the server group specified by {@code sourceGroupId} with a given name
* and returns the ID of the newly created server group.
*
* @param sourceGroupId
* the ID of the server group to copy
* @param targetName
* the name for the copy of the server group
* @param type
* the desired type of server group
*
* @return the ID of the newly created server group
*
* @querycommands 1
* @see ServerGroup#getId()
*/
public CommandFuture copyServerGroup(int sourceGroupId, String targetName, PermissionGroupDatabaseType type) {
final CServerGroupCopy copy = new CServerGroupCopy(sourceGroupId, targetName, type);
return executeAndReturnIntProperty(copy, "sgid");
}
/**
* Creates a new channel with a given name using the given properties and returns its ID.
*
* @param name
* the name for the new channel
* @param options
* a map of options that should be set for the channel
*
* @return the ID of the newly created channel
*
* @querycommands 1
* @see Channel
*/
public CommandFuture createChannel(String name, Map options) {
final CChannelCreate create = new CChannelCreate(name, options);
return executeAndReturnIntProperty(create, "cid");
}
/**
* Creates a new directory on the file repository in the specified channel.
*
* @param directoryPath
* the path to the directory that should be created
* @param channelId
* the ID of the channel the directory should be created in
*
* @return whether the command succeeded or not
*
* @querycommands 1
* @see FileInfo#getPath()
* @see Channel#getId()
*/
public CommandFuture createFileDirectory(String directoryPath, int channelId) {
return createFileDirectory(directoryPath, channelId, null);
}
/**
* Creates a new directory on the file repository in the specified channel.
*
* @param directoryPath
* the path to the directory that should be created
* @param channelId
* the ID of the channel the directory should be created in
* @param channelPassword
* the password of that channel
*
* @return whether the command succeeded or not
*
* @querycommands 1
* @see FileInfo#getPath()
* @see Channel#getId()
*/
public CommandFuture createFileDirectory(String directoryPath, int channelId, String channelPassword) {
final CFtCreateDir create = new CFtCreateDir(directoryPath, channelId, channelPassword);
return executeAndReturnError(create);
}
/**
* Creates a new virtual server with the given name and returns an object containing the ID of the newly
* created virtual server, the default server admin token and the virtual server's voice port. Usually,
* the virtual server is also automatically started. This can be turned off on the TS3 server, though.
*
* If {@link VirtualServerProperty#VIRTUALSERVER_PORT} is not specified in the virtual server properties,
* the server will test for the first unused UDP port.
*
* Please also note that creating virtual servers usually requires the server query admin account
* and that there is a limit to how many virtual servers can be created, which is dependent on your license.
* Unlicensed TS3 server instances are limited to 1 virtual server with up to 32 client slots.
*
*
* @param name
* the name for the new virtual server
* @param options
* a map of options that should be set for the virtual server
*
* @return information about the newly created virtual server
*
* @querycommands 1
* @see VirtualServer
*/
public CommandFuture createServer(String name, Map options) {
final CServerCreate create = new CServerCreate(name, options);
final CommandFuture future = new CommandFuture<>();
query.doCommandAsync(create, new Callback() {
@Override
public void handle() {
if (hasFailed(create, future)) return;
future.set(new CreatedVirtualServer(create.getFirstResponse().getMap()));
}
});
return future;
}
/**
* Creates a {@link Snapshot} of the selected virtual server containing all settings,
* groups and known client identities. The data from a server snapshot can be
* used to restore a virtual servers configuration.
*
* @return a snapshot of the virtual server
*
* @querycommands 1
* @see #deployServerSnapshot(Snapshot)
*/
public CommandFuture createServerSnapshot() {
final CServerSnapshotCreate create = new CServerSnapshotCreate();
final CommandFuture future = new CommandFuture<>();
query.doCommandAsync(create, new Callback() {
@Override
public void handle() {
if (hasFailed(create, future)) return;
future.set(new Snapshot(create.getRawResponse()));
}
});
return future;
}
/**
* Deletes all active ban rules from the server. Use with caution.
*
* @return whether the command succeeded or not
*
* @querycommands 1
*/
public CommandFuture deleteAllBans() {
final CBanDelAll del = new CBanDelAll();
return executeAndReturnError(del);
}
/**
* Deletes all complaints about the client with specified database ID from the server.
*
* @param clientDBId
* the database ID of the client
*
* @return whether the command succeeded or not
*
* @querycommands 1
* @see Client#getDatabaseId()
* @see Complaint
*/
public CommandFuture deleteAllComplaints(int clientDBId) {
final CComplainDelAll del = new CComplainDelAll(clientDBId);
return executeAndReturnError(del);
}
/**
* Deletes the ban rule with the specified ID from the server.
*
* @param banId
* the ID of the ban to delete
*
* @return whether the command succeeded or not
*
* @querycommands 1
* @see Ban#getId()
*/
public CommandFuture deleteBan(int banId) {
final CBanDel del = new CBanDel(banId);
return executeAndReturnError(del);
}
/**
* Deletes an existing channel specified by its ID, kicking all clients out of the channel.
*
* @param channelId
* the ID of the channel to delete
*
* @return whether the command succeeded or not
*
* @querycommands 1
* @see Channel#getId()
* @see #deleteChannel(int, boolean)
* @see #kickClientFromChannel(String, int...)
*/
public CommandFuture deleteChannel(int channelId) {
return deleteChannel(channelId, true);
}
/**
* Deletes an existing channel with a given ID.
* If {@code force} is true, the channel will be deleted even if there are clients within,
* else the command will fail in this situation.
*
* @param channelId
* the ID of the channel to delete
* @param force
* whether clients should be kicked out of the channel
*
* @return whether the command succeeded or not
*
* @querycommands 1
* @see Channel#getId()
* @see #kickClientFromChannel(String, int...)
*/
public CommandFuture deleteChannel(int channelId, boolean force) {
final CChannelDelete del = new CChannelDelete(channelId, force);
return executeAndReturnError(del);
}
/**
* Removes a specified permission from a client in a specific channel.
*
* @param channelId
* the ID of the channel wherein the permission should be removed
* @param clientDBId
* the database ID of the client
* @param permName
* the name of the permission to revoke
*
* @return whether the command succeeded or not
*
* @querycommands 1
* @see Channel#getId()
* @see Client#getDatabaseId()
* @see Permission#getName()
*/
public CommandFuture deleteChannelClientPermission(int channelId, int clientDBId, String permName) {
final CChannelClientDelPerm del = new CChannelClientDelPerm(channelId, clientDBId, permName);
return executeAndReturnError(del);
}
/**
* Removes the channel group with the given ID.
*
* @param groupId
* the ID of the channel group
*
* @return whether the command succeeded or not
*
* @querycommands 1
* @see ChannelGroup#getId()
*/
public CommandFuture deleteChannelGroup(int groupId) {
return deleteChannelGroup(groupId, true);
}
/**
* Removes the channel group with the given ID.
* If {@code force} is true, the channel group will be deleted even if it still contains clients,
* else the command will fail in this situation.
*
* @param groupId
* the ID of the channel group
* @param force
* whether the channel group should be deleted even if it still contains clients
*
* @return whether the command succeeded or not
*
* @querycommands 1
* @see ChannelGroup#getId()
*/
public CommandFuture deleteChannelGroup(int groupId, boolean force) {
final CChannelGroupDel del = new CChannelGroupDel(groupId, force);
return executeAndReturnError(del);
}
/**
* Removes a permission from the channel group with the given ID.
*
* @param groupId
* the ID of the channel group
* @param permName
* the name of the permission to revoke
*
* @return whether the command succeeded or not
*
* @querycommands 1
* @see ChannelGroup#getId()
* @see Permission#getName()
*/
public CommandFuture deleteChannelGroupPermission(int groupId, String permName) {
final CChannelGroupDelPerm del = new CChannelGroupDelPerm(groupId, permName);
return executeAndReturnError(del);
}
/**
* Removes a permission from the channel with the given ID.
*
* @param channelId
* the ID of the channel
* @param permName
* the name of the permission to revoke
*
* @return whether the command succeeded or not
*
* @querycommands 1
* @see Channel#getId()
* @see Permission#getName()
*/
public CommandFuture deleteChannelPermission(int channelId, String permName) {
final CChannelDelPerm del = new CChannelDelPerm(channelId, permName);
return executeAndReturnError(del);
}
/**
* Removes a permission from a client.
*
* @param clientDBId
* the database ID of the client
* @param permName
* the name of the permission to revoke
*
* @return whether the command succeeded or not
*
* @querycommands 1
* @see Client#getDatabaseId()
* @see Permission#getName()
*/
public CommandFuture deleteClientPermission(int clientDBId, String permName) {
final CClientDelPerm del = new CClientDelPerm(clientDBId, permName);
return executeAndReturnError(del);
}
/**
* Deletes the complaint about the client with database ID {@code targetClientDBId} submitted by
* the client with database ID {@code fromClientDBId} from the server.
*
* @param targetClientDBId
* the database ID of the client the complaint is about
* @param fromClientDBId
* the database ID of the client who added the complaint
*
* @return whether the command succeeded or not
*
* @querycommands 1
* @see Complaint
* @see Client#getDatabaseId()
*/
public CommandFuture deleteComplaint(int targetClientDBId, int fromClientDBId) {
final CComplainDel del = new CComplainDel(targetClientDBId, fromClientDBId);
return executeAndReturnError(del);
}
/**
* Removes all stored database information about the specified client.
* Please note that this data is also automatically removed after a configured time (usually 90 days).
*
* See {@link DatabaseClientInfo} for a list of stored information about a client.
*
*
* @param clientDBId
* the database ID of the client
*
* @return whether the command succeeded or not
*
* @querycommands 1
* @see Client#getDatabaseId()
* @see #getDatabaseClientInfo(int)
* @see DatabaseClientInfo
*/
public CommandFuture deleteDatabaseClientProperties(int clientDBId) {
final CClientDBDelete del = new CClientDBDelete(clientDBId);
return executeAndReturnError(del);
}
/**
* Deletes a file or directory from the file repository in the specified channel.
*
* @param filePath
* the path to the file or directory
* @param channelId
* the ID of the channel the file or directory resides in
*
* @return whether the command succeeded or not
*
* @querycommands 1
* @see FileInfo#getPath()
* @see Channel#getId()
*/
public CommandFuture deleteFile(String filePath, int channelId) {
return deleteFile(filePath, channelId, null);
}
/**
* Deletes a file or directory from the file repository in the specified channel.
*
* @param filePath
* the path to the file or directory
* @param channelId
* the ID of the channel the file or directory resides in
* @param channelPassword
* the password of that channel
*
* @return whether the command succeeded or not
*
* @querycommands 1
* @see FileInfo#getPath()
* @see Channel#getId()
*/
public CommandFuture deleteFile(String filePath, int channelId, String channelPassword) {
final CFtDeleteFile delete = new CFtDeleteFile(channelId, channelPassword, filePath);
return executeAndReturnError(delete);
}
/**
* Deletes multiple files or directories from the file repository in the specified channel.
*
* @param filePaths
* the paths to the files or directories
* @param channelId
* the ID of the channel the file or directory resides in
*
* @return whether the command succeeded or not
*
* @querycommands 1
* @see FileInfo#getPath()
* @see Channel#getId()
*/
public CommandFuture deleteFiles(String[] filePaths, int channelId) {
return deleteFiles(filePaths, channelId, null);
}
/**
* Deletes multiple files or directories from the file repository in the specified channel.
*
* @param filePaths
* the paths to the files or directories
* @param channelId
* the ID of the channel the file or directory resides in
* @param channelPassword
* the password of that channel
*
* @return whether the command succeeded or not
*
* @querycommands 1
* @see FileInfo#getPath()
* @see Channel#getId()
*/
public CommandFuture deleteFiles(String[] filePaths, int channelId, String channelPassword) {
final CFtDeleteFile delete = new CFtDeleteFile(channelId, channelPassword, filePaths);
return executeAndReturnError(delete);
}
/**
* Deletes an icon from the icon directory in the file repository.
*
* @param iconId
* the ID of the icon to delete
*
* @return whether the command succeeded or not
*
* @querycommands 1
* @see IconFile#getIconId()
*/
public CommandFuture deleteIcon(long iconId) {
final String iconPath = "/icon_" + iconId;
return deleteFile(iconPath, 0);
}
/**
* Deletes multiple icons from the icon directory in the file repository.
*
* @param iconIds
* the IDs of the icons to delete
*
* @return whether the command succeeded or not
*
* @querycommands 1
* @see IconFile#getIconId()
*/
public CommandFuture deleteIcons(long[] iconIds) {
final String[] iconPaths = new String[iconIds.length];
for (int i = 0; i < iconIds.length; ++i) {
iconPaths[i] = "/icon_" + iconIds[i];
}
return deleteFiles(iconPaths, 0);
}
/**
* Deletes the offline message with the specified ID.
*
* @param messageId
* the ID of the offline message to delete
*
* @return whether the command succeeded or not
*
* @querycommands 1
* @see Message#getId()
*/
public CommandFuture deleteOfflineMessage(int messageId) {
final CMessageDel del = new CMessageDel(messageId);
return executeAndReturnError(del);
}
/**
* Removes a specified permission from all server groups of the type specified by {@code type} on all virtual servers.
*
* @param type
* the kind of server group this permission should be removed from
* @param permName
* the name of the permission to remove
*
* @return whether the command succeeded or not
*
* @querycommands 1
* @see ServerGroupType
* @see Permission#getName()
*/
public CommandFuture deletePermissionFromAllServerGroups(ServerGroupType type, String permName) {
final CServerGroupAutoDelPerm del = new CServerGroupAutoDelPerm(type, permName);
return executeAndReturnError(del);
}
/**
* Deletes the privilege key with the given token.
*
* @param token
* the token of the privilege key
*
* @return whether the command succeeded or not
*
* @querycommands 1
* @see PrivilegeKey
*/
public CommandFuture deletePrivilegeKey(String token) {
final CPrivilegeKeyDelete del = new CPrivilegeKeyDelete(token);
return executeAndReturnError(del);
}
/**
* Deletes the virtual server with the specified ID.
*
* Only stopped virtual servers can be deleted.
*
*
* @param serverId
* the ID of the virtual server
*
* @return whether the command succeeded or not
*
* @querycommands 1
* @see VirtualServer#getId()
* @see #stopServer(int)
*/
public CommandFuture deleteServer(int serverId) {
final CServerDelete delete = new CServerDelete(serverId);
return executeAndReturnError(delete);
}
/**
* Deletes the server group with the specified ID, even if the server group still contains clients.
*
* @param groupId
* the ID of the server group
*
* @return whether the command succeeded or not
*
* @querycommands 1
* @see ServerGroup#getId()
*/
public CommandFuture deleteServerGroup(int groupId) {
return deleteServerGroup(groupId, true);
}
/**
* Deletes a server group with the specified ID.
*
* If {@code force} is true, the server group will be deleted even if it contains clients,
* else the command will fail in this situation.
*
*
* @param groupId
* the ID of the server group
* @param force
* whether the server group should be deleted if it still contains clients
*
* @return whether the command succeeded or not
*
* @querycommands 1
* @see ServerGroup#getId()
*/
public CommandFuture deleteServerGroup(int groupId, boolean force) {
final CServerGroupDel del = new CServerGroupDel(groupId, force);
return executeAndReturnError(del);
}
/**
* Removes a permission from the server group with the given ID.
*
* @param groupId
* the ID of the server group
* @param permName
* the name of the permission to revoke
*
* @return whether the command succeeded or not
*
* @querycommands 1
* @see ServerGroup#getId()
* @see Permission#getName()
*/
public CommandFuture deleteServerGroupPermission(int groupId, String permName) {
final CServerGroupDelPerm del = new CServerGroupDelPerm(groupId, permName);
return executeAndReturnError(del);
}
/**
* Restores the selected virtual servers configuration using the data from a
* previously created server snapshot.
*
* @param snapshot
* the snapshot to restore
*
* @return whether the command succeeded or not
*
* @querycommands 1
* @see #createServerSnapshot()
*/
public CommandFuture deployServerSnapshot(Snapshot snapshot) {
return deployServerSnapshot(snapshot.get());
}
/**
* Restores the configuration of the selected virtual server using the data from a
* previously created server snapshot.
*
* @param snapshot
* the snapshot to restore
*
* @return whether the command succeeded or not
*
* @querycommands 1
* @see #createServerSnapshot()
*/
public CommandFuture deployServerSnapshot(String snapshot) {
final CServerSnapshotDeploy deploy = new CServerSnapshotDeploy(snapshot);
return executeAndReturnError(deploy);
}
/**
* Downloads a file from the file repository at a given path and channel
* and writes the file's bytes to an open {@link OutputStream}.
*
* It is the user's responsibility to ensure that the given {@code OutputStream} is
* open and to close the stream again once the download has finished.
*
* Note that this method will not read the entire file to memory and can thus
* download arbitrarily sized files from the file repository.
*
*
* @param dataOut
* a stream that the downloaded data should be written to
* @param filePath
* the path of the file on the file repository
* @param channelId
* the ID of the channel to download the file from
*
* @return how many bytes were downloaded
*
* @throws TS3FileTransferFailedException
* if the file transfer fails for any reason
* @querycommands 1
* @see FileInfo#getPath()
* @see Channel#getId()
* @see #downloadFileDirect(String, int)
*/
public CommandFuture downloadFile(OutputStream dataOut, String filePath, int channelId) {
return downloadFile(dataOut, filePath, channelId, null);
}
/**
* Downloads a file from the file repository at a given path and channel
* and writes the file's bytes to an open {@link OutputStream}.
*
* It is the user's responsibility to ensure that the given {@code OutputStream} is
* open and to close the stream again once the download has finished.
*
* Note that this method will not read the entire file to memory and can thus
* download arbitrarily sized files from the file repository.
*
*
* @param dataOut
* a stream that the downloaded data should be written to
* @param filePath
* the path of the file on the file repository
* @param channelId
* the ID of the channel to download the file from
* @param channelPassword
* that channel's password
*
* @return how many bytes were downloaded
*
* @throws TS3FileTransferFailedException
* if the file transfer fails for any reason
* @querycommands 1
* @see FileInfo#getPath()
* @see Channel#getId()
* @see #downloadFileDirect(String, int, String)
*/
public CommandFuture downloadFile(final OutputStream dataOut, String filePath, int channelId, String channelPassword) {
final FileTransferHelper helper = query.getFileTransferHelper();
final int transferId = helper.getClientTransferId();
final CFtInitDownload download = new CFtInitDownload(transferId, filePath, channelId, channelPassword);
final CommandFuture future = new CommandFuture<>();
query.doCommandAsync(download, new Callback() {
@Override
public void handle() {
if (hasFailed(download, future)) return;
FileTransferParameters params = new FileTransferParameters(download.getFirstResponse().getMap());
QueryError error = params.getQueryError();
if (!error.isSuccessful()) {
future.fail(new TS3CommandFailedException(error));
return;
}
try {
query.getFileTransferHelper().downloadFile(dataOut, params);
} catch (IOException e) {
future.fail(new TS3FileTransferFailedException("Download failed", e));
return;
}
future.set(params.getFileSize());
}
});
return future;
}
/**
* Downloads a file from the file repository at a given path and channel
* and returns the file's bytes as a byte array.
*
* Note that this method will read the entire file to memory.
* That means that if a file is larger than 231-1 bytes in size,
* the download will fail.
*
*
* @param filePath
* the path of the file on the file repository
* @param channelId
* the ID of the channel to download the file from
*
* @return a byte array containing the file's data
*
* @throws TS3FileTransferFailedException
* if the file transfer fails for any reason
* @querycommands 1
* @see FileInfo#getPath()
* @see Channel#getId()
* @see #downloadFile(OutputStream, String, int)
*/
public CommandFuture downloadFileDirect(String filePath, int channelId) {
return downloadFileDirect(filePath, channelId, null);
}
/**
* Downloads a file from the file repository at a given path and channel
* and returns the file's bytes as a byte array.
*
* Note that this method will read the entire file to memory.
* That means that if a file is larger than 231-1 bytes in size,
* the download will fail.
*
*
* @param filePath
* the path of the file on the file repository
* @param channelId
* the ID of the channel to download the file from
* @param channelPassword
* that channel's password
*
* @return a byte array containing the file's data
*
* @throws TS3FileTransferFailedException
* if the file transfer fails for any reason
* @querycommands 1
* @see FileInfo#getPath()
* @see Channel#getId()
* @see #downloadFile(OutputStream, String, int, String)
*/
public CommandFuture downloadFileDirect(String filePath, int channelId, String channelPassword) {
final FileTransferHelper helper = query.getFileTransferHelper();
final int transferId = helper.getClientTransferId();
final CFtInitDownload download = new CFtInitDownload(transferId, filePath, channelId, channelPassword);
final CommandFuture future = new CommandFuture<>();
query.doCommandAsync(download, new Callback() {
@Override
public void handle() {
if (hasFailed(download, future)) return;
FileTransferParameters params = new FileTransferParameters(download.getFirstResponse().getMap());
QueryError error = params.getQueryError();
if (!error.isSuccessful()) {
future.fail(new TS3CommandFailedException(error));
return;
}
long fileSize = params.getFileSize();
if (fileSize > Integer.MAX_VALUE) {
future.fail(new TS3FileTransferFailedException("File too big for byte array"));
return;
}
ByteArrayOutputStream dataOut = new ByteArrayOutputStream((int) fileSize);
try {
query.getFileTransferHelper().downloadFile(dataOut, params);
} catch (IOException e) {
future.fail(new TS3FileTransferFailedException("Download failed", e));
return;
}
future.set(dataOut.toByteArray());
}
});
return future;
}
/**
* Downloads an icon from the icon directory in the file repository
* and writes the file's bytes to an open {@link OutputStream}.
*
* It is the user's responsibility to ensure that the given {@code OutputStream} is
* open and to close the stream again once the download has finished.
*
*
* @param dataOut
* a stream that the downloaded data should be written to
* @param iconId
* the ID of the icon that should be downloaded
*
* @return a byte array containing the icon file's data
*
* @throws TS3FileTransferFailedException
* if the file transfer fails for any reason
* @querycommands 1
* @see IconFile#getIconId()
* @see #downloadIconDirect(long)
* @see #uploadIcon(InputStream, long)
*/
public CommandFuture downloadIcon(OutputStream dataOut, long iconId) {
final String iconPath = "/icon_" + iconId;
return downloadFile(dataOut, iconPath, 0);
}
/**
* Downloads an icon from the icon directory in the file repository
* and returns the file's bytes as a byte array.
*
* Note that this method will read the entire file to memory.
*
*
* @param iconId
* the ID of the icon that should be downloaded
*
* @return a byte array containing the icon file's data
*
* @throws TS3FileTransferFailedException
* if the file transfer fails for any reason
* @querycommands 1
* @see IconFile#getIconId()
* @see #downloadIcon(OutputStream, long)
* @see #uploadIconDirect(byte[])
*/
public CommandFuture downloadIconDirect(long iconId) {
final String iconPath = "/icon_" + iconId;
return downloadFileDirect(iconPath, 0);
}
/**
* Changes a channel's configuration using the given properties.
*
* @param channelId
* the ID of the channel to edit
* @param options
* the map of properties to modify
*
* @return whether the command succeeded or not
*
* @querycommands 1
* @see Channel#getId()
*/
public CommandFuture editChannel(int channelId, Map options) {
final CChannelEdit edit = new CChannelEdit(channelId, options);
return executeAndReturnError(edit);
}
/**
* Changes a client's configuration using given properties.
*
* Only {@link ClientProperty#CLIENT_DESCRIPTION} can be changed for other clients.
* To update the current client's properties, use {@link #updateClient(Map)}.
*
*
* @param clientId
* the ID of the client to edit
* @param options
* the map of properties to modify
*
* @return whether the command succeeded or not
*
* @querycommands 1
* @see Client#getId()
* @see #updateClient(Map)
*/
public CommandFuture editClient(int clientId, Map options) {
final CClientEdit edit = new CClientEdit(clientId, options);
return executeAndReturnError(edit);
}
/**
* Changes a client's database settings using given properties.
*
* @param clientDBId
* the database ID of the client to edit
* @param options
* the map of properties to modify
*
* @return whether the command succeeded or not
*
* @querycommands 1
* @see DatabaseClientInfo
* @see Client#getDatabaseId()
*/
public CommandFuture editDatabaseClient(int clientDBId, Map options) {
final CClientDBEdit edit = new CClientDBEdit(clientDBId, options);
return executeAndReturnError(edit);
}
/**
* Changes the server instance configuration using given properties.
* If the given property is not changeable, {@code IllegalArgumentException} will be thrown.
*
* @param property
* the property to edit, must be changeable
* @param value
* the new value for the edit
*
* @return whether the command succeeded or not
*
* @throws IllegalArgumentException
* if {@code property} is not changeable
* @querycommands 1
* @see ServerInstanceProperty#isChangeable()
*/
public CommandFuture editInstance(ServerInstanceProperty property, String value) {
if (!property.isChangeable()) {
throw new IllegalArgumentException("Property is not changeable");
}
final CInstanceEdit edit = new CInstanceEdit(property, value);
return executeAndReturnError(edit);
}
/**
* Changes the configuration of the selected virtual server using given properties.
*
* @param options
* the map of properties to edit
*
* @return whether the command succeeded or not
*
* @querycommands 1
* @see VirtualServerProperty
*/
public CommandFuture editServer(Map options) {
final CServerEdit edit = new CServerEdit(options);
return executeAndReturnError(edit);
}
/**
* Gets a list of all bans on the selected virtual server.
*
* @return a list of all bans on the virtual server
*
* @querycommands 1
* @see Ban
*/
public CommandFuture> getBans() {
final CBanList list = new CBanList();
final CommandFuture> future = new CommandFuture<>();
query.doCommandAsync(list, new Callback() {
@Override
public void handle() {
if (hasFailed(list, future)) return;
final List responses = list.getResponse();
final List bans = new ArrayList<>(responses.size());
for (final Wrapper response : responses) {
bans.add(new Ban(response.getMap()));
}
future.set(bans);
}
});
return future;
}
/**
* Gets a list of IP addresses used by the server instance.
*
* @return the list of bound IP addresses
*
* @querycommands 1
* @see Binding
*/
public CommandFuture> getBindings() {
final CBindingList list = new CBindingList();
final CommandFuture> future = new CommandFuture<>();
query.doCommandAsync(list, new Callback() {
@Override
public void handle() {
if (hasFailed(list, future)) return;
final List responses = list.getResponse();
final List bindings = new ArrayList<>(responses.size());
for (final Wrapper response : responses) {
bindings.add(new Binding(response.getMap()));
}
future.set(bindings);
}
});
return future;
}
/**
* Finds and returns the channel matching the given name exactly.
*
* @param name
* the name of the channel
* @param ignoreCase
* whether the case of the name should be ignored
*
* @return the found channel or {@code null} if no channel was found
*
* @querycommands 1
* @see Channel
* @see #getChannelsByName(String)
*/
public CommandFuture getChannelByNameExact(String name, final boolean ignoreCase) {
final CommandFuture future = new CommandFuture<>();
final String caseName = ignoreCase ? name.toLowerCase(Locale.ROOT) : name;
getChannels().onSuccess(new CommandFuture.SuccessListener>() {
@Override
public void handleSuccess(final List allChannels) {
for (final Channel c : allChannels) {
final String channelName = ignoreCase ? c.getName().toLowerCase(Locale.ROOT) : c.getName();
if (caseName.equals(channelName)) {
future.set(c);
return;
}
}
future.set(null); // Not found
}
}).forwardFailure(future);
return future;
}
/**
* Gets a list of channels whose names contain the given search string.
*
* @param name
* the name to search
*
* @return a list of all channels with names matching the search pattern
*
* @querycommands 2
* @see Channel
* @see #getChannelByNameExact(String, boolean)
*/
public CommandFuture> getChannelsByName(String name) {
final CChannelFind find = new CChannelFind(name);
final CommandFuture> future = new CommandFuture<>();
getChannels().onSuccess(new CommandFuture.SuccessListener>() {
@Override
public void handleSuccess(final List allChannels) {
query.doCommandAsync(find, new Callback() {
@Override
public void handle() {
if (hasFailed(find, future)) return;
final List responses = find.getResponse();
final List channels = new ArrayList<>(responses.size());
for (final Wrapper response : responses) {
final int channelId = response.getInt("cid");
for (final Channel c : allChannels) {
if (c.getId() == channelId) {
channels.add(c);
break;
}
}
}
future.set(channels);
}
});
}
}).forwardFailure(future);
return future;
}
/**
* Displays a list of permissions defined for a client in a specific channel.
*
* @param channelId
* the ID of the channel
* @param clientDBId
* the database ID of the client
*
* @return a list of permissions for the user in the specified channel
*
* @querycommands 1
* @see Channel#getId()
* @see Client#getDatabaseId()
* @see Permission
*/
public CommandFuture> getChannelClientPermissions(int channelId, int clientDBId) {
final CChannelClientPermList list = new CChannelClientPermList(channelId, clientDBId);
final CommandFuture> future = new CommandFuture<>();
query.doCommandAsync(list, new Callback() {
@Override
public void handle() {
if (hasFailed(list, future)) return;
final List responses = list.getResponse();
final List permissions = new ArrayList<>(responses.size());
for (final Wrapper response : responses) {
permissions.add(new Permission(response.getMap()));
}
future.set(permissions);
}
});
return future;
}
/**
* Gets all client / channel ID combinations currently assigned to channel groups.
* All three parameters are optional and can be turned off by setting it to {@code -1}.
*
* @param channelId
* restricts the search to the channel with a specified ID. Set to {@code -1} to ignore.
* @param clientDBId
* restricts the search to the client with a specified database ID. Set to {@code -1} to ignore.
* @param groupId
* restricts the search to the channel group with the specified ID. Set to {@code -1} to ignore.
*
* @return a list of combinations of channel ID, client database ID and channel group ID
*
* @querycommands 1
* @see Channel#getId()
* @see Client#getDatabaseId()
* @see ChannelGroup#getId()
* @see ChannelGroupClient
*/
public CommandFuture> getChannelGroupClients(int channelId, int clientDBId, int groupId) {
final CChannelGroupClientList list = new CChannelGroupClientList(channelId, clientDBId, groupId);
final CommandFuture> future = new CommandFuture<>();
query.doCommandAsync(list, new Callback() {
@Override
public void handle() {
if (hasFailed(list, future)) return;
final List responses = list.getResponse();
final List clients = new ArrayList<>(responses.size());
for (final Wrapper response : responses) {
clients.add(new ChannelGroupClient(response.getMap()));
}
future.set(clients);
}
});
return future;
}
/**
* Gets all client / channel ID combinations currently assigned to the specified channel group.
*
* @param groupId
* the ID of the channel group whose client / channel assignments should be returned.
*
* @return a list of combinations of channel ID, client database ID and channel group ID
*
* @querycommands 1
* @see ChannelGroup#getId()
* @see ChannelGroupClient
* @see #getChannelGroupClients(int, int, int)
*/
public CommandFuture> getChannelGroupClientsByChannelGroupId(int groupId) {
return getChannelGroupClients(-1, -1, groupId);
}
/**
* Gets all channel group assignments in the specified channel.
*
* @param channelId
* the ID of the channel whose channel group assignments should be returned.
*
* @return a list of combinations of channel ID, client database ID and channel group ID
*
* @querycommands 1
* @see Channel#getId()
* @see ChannelGroupClient
* @see #getChannelGroupClients(int, int, int)
*/
public CommandFuture> getChannelGroupClientsByChannelId(int channelId) {
return getChannelGroupClients(channelId, -1, -1);
}
/**
* Gets all channel group assignments for the specified client.
*
* @param clientDBId
* the database ID of the client whose channel group
*
* @return a list of combinations of channel ID, client database ID and channel group ID
*
* @querycommands 1
* @see Client#getDatabaseId()
* @see ChannelGroupClient
* @see #getChannelGroupClients(int, int, int)
*/
public CommandFuture> getChannelGroupClientsByClientDBId(int clientDBId) {
return getChannelGroupClients(-1, clientDBId, -1);
}
/**
* Gets a list of all permissions assigned to the specified channel group.
*
* @param groupId
* the ID of the channel group.
*
* @return a list of permissions assigned to the channel group
*
* @querycommands 1
* @see ChannelGroup#getId()
* @see Permission
*/
public CommandFuture> getChannelGroupPermissions(int groupId) {
final CChannelGroupPermList list = new CChannelGroupPermList(groupId);
final CommandFuture> future = new CommandFuture<>();
query.doCommandAsync(list, new Callback() {
@Override
public void handle() {
if (hasFailed(list, future)) return;
final List responses = list.getResponse();
final List permissions = new ArrayList<>(responses.size());
for (final Wrapper response : responses) {
permissions.add(new Permission(response.getMap()));
}
future.set(permissions);
}
});
return future;
}
/**
* Gets a list of all channel groups on the selected virtual server.
*
* @return a list of all channel groups on the virtual server
*
* @querycommands 1
* @see ChannelGroup
*/
public CommandFuture> getChannelGroups() {
final CChannelGroupList list = new CChannelGroupList();
final CommandFuture> future = new CommandFuture<>();
query.doCommandAsync(list, new Callback() {
@Override
public void handle() {
if (hasFailed(list, future)) return;
final List responses = list.getResponse();
final List groups = new ArrayList<>(responses.size());
for (final Wrapper response : responses) {
groups.add(new ChannelGroup(response.getMap()));
}
future.set(groups);
}
});
return future;
}
/**
* Gets detailed configuration information about the channel specified channel.
*
* @param channelId
* the ID of the channel
*
* @return information about the channel
*
* @querycommands 1
* @see Channel#getId()
* @see ChannelInfo
*/
public CommandFuture getChannelInfo(final int channelId) {
final CChannelInfo info = new CChannelInfo(channelId);
final CommandFuture future = new CommandFuture<>();
query.doCommandAsync(info, new Callback() {
@Override
public void handle() {
if (hasFailed(info, future)) return;
future.set(new ChannelInfo(channelId, info.getFirstResponse().getMap()));
}
});
return future;
}
/**
* Gets a list of all permissions assigned to the specified channel.
*
* @param channelId
* the ID of the channel
*
* @return a list of all permissions assigned to the channel
*
* @querycommands 1
* @see Channel#getId()
* @see Permission
*/
public CommandFuture> getChannelPermissions(int channelId) {
final CChannelPermList list = new CChannelPermList(channelId);
final CommandFuture> future = new CommandFuture<>();
query.doCommandAsync(list, new Callback() {
@Override
public void handle() {
if (hasFailed(list, future)) return;
final List responses = list.getResponse();
final List permissions = new ArrayList<>(responses.size());
for (final Wrapper response : responses) {
permissions.add(new Permission(response.getMap()));
}
future.set(permissions);
}
});
return future;
}
/**
* Gets a list of all channels on the selected virtual server.
*
* @return a list of all channels on the virtual server
*
* @querycommands 1
* @see Channel
*/
public CommandFuture> getChannels() {
final CChannelList list = new CChannelList();
final CommandFuture> future = new CommandFuture<>();
query.doCommandAsync(list, new Callback() {
@Override
public void handle() {
if (hasFailed(list, future)) return;
final List responses = list.getResponse();
final List channels = new ArrayList<>(responses.size());
for (final Wrapper response : responses) {
channels.add(new Channel(response.getMap()));
}
future.set(channels);
}
});
return future;
}
/**
* Finds and returns the client whose nickname matches the given name exactly.
*
* @param name
* the name of the client
* @param ignoreCase
* whether the case of the name should be ignored
*
* @return the found client or {@code null} if no client was found
*
* @querycommands 1
* @see Client
* @see #getClientsByName(String)
*/
public CommandFuture getClientByNameExact(String name, final boolean ignoreCase) {
final CommandFuture future = new CommandFuture<>();
final String caseName = ignoreCase ? name.toLowerCase(Locale.ROOT) : name;
getClients().onSuccess(new CommandFuture.SuccessListener>() {
@Override
public void handleSuccess(final List allClients) {
for (final Client c : allClients) {
final String clientName = ignoreCase ? c.getNickname().toLowerCase(Locale.ROOT) : c.getNickname();
if (caseName.equals(clientName)) {
future.set(c);
return;
}
}
future.set(null); // Not found
}
}).forwardFailure(future);
return future;
}
/**
* Gets a list of clients whose nicknames contain the given search string.
*
* @param name
* the name to search
*
* @return a list of all clients with nicknames matching the search pattern
*
* @querycommands 2
* @see Client
* @see #getClientByNameExact(String, boolean)
*/
public CommandFuture> getClientsByName(String name) {
final CClientFind find = new CClientFind(name);
final CommandFuture> future = new CommandFuture<>();
getClients().onSuccess(new CommandFuture.SuccessListener>() {
@Override
public void handleSuccess(final List allClients) {
query.doCommandAsync(find, new Callback() {
@Override
public void handle() {
if (hasFailed(find, future)) return;
final List responses = find.getResponse();
final List clients = new ArrayList<>(responses.size());
for (final Wrapper response : responses) {
for (final Client c : allClients) {
if (c.getId() == response.getInt("clid")) {
clients.add(c);
break;
}
}
}
future.set(clients);
}
});
}
}).forwardFailure(future);
return future;
}
/**
* Gets information about the client with the specified unique identifier.
*
* @param clientUId
* the unique identifier of the client
*
* @return the client or {@code null} if no client was found
*
* @querycommands 2
* @see Client#getUniqueIdentifier()
* @see ClientInfo
*/
public CommandFuture getClientByUId(String clientUId) {
final CClientGetIds get = new CClientGetIds(clientUId);
final CommandFuture future = new CommandFuture<>();
query.doCommandAsync(get, new Callback() {
@Override
public void handle() {
if (hasFailed(get, future)) return;
getClientInfo(get.getFirstResponse().getInt("clid")).forwardResult(future);
}
});
return future;
}
/**
* Gets information about the client with the specified client ID.
*
* @param clientId
* the client ID of the client
*
* @return the client or {@code null} if no client was found
*
* @querycommands 1
* @see Client#getId()
* @see ClientInfo
*/
public CommandFuture getClientInfo(final int clientId) {
final CClientInfo info = new CClientInfo(clientId);
final CommandFuture future = new CommandFuture<>();
query.doCommandAsync(info, new Callback() {
@Override
public void handle() {
if (hasFailed(info, future)) return;
future.set(new ClientInfo(clientId, info.getFirstResponse().getMap()));
}
});
return future;
}
/**
* Gets a list of all permissions assigned to the specified client.
*
* @param clientDBId
* the database ID of the client
*
* @return a list of all permissions assigned to the client
*
* @querycommands 1
* @see Client#getDatabaseId()
* @see Permission
*/
public CommandFuture> getClientPermissions(int clientDBId) {
final CClientPermList list = new CClientPermList(clientDBId);
final CommandFuture> future = new CommandFuture<>();
query.doCommandAsync(list, new Callback() {
@Override
public void handle() {
if (hasFailed(list, future)) return;
final List responses = list.getResponse();
final List permissions = new ArrayList<>(responses.size());
for (final Wrapper response : responses) {
permissions.add(new Permission(response.getMap()));
}
future.set(permissions);
}
});
return future;
}
/**
* Gets a list of all clients on the selected virtual server.
*
* @return a list of all clients on the virtual server
*
* @querycommands 1
* @see Client
*/
public CommandFuture> getClients() {
final CClientList list = new CClientList();
final CommandFuture> future = new CommandFuture<>();
query.doCommandAsync(list, new Callback() {
@Override
public void handle() {
if (hasFailed(list, future)) return;
final List responses = list.getResponse();
final List clients = new ArrayList<>(responses.size());
for (final Wrapper response : responses) {
clients.add(new Client(response.getMap()));
}
future.set(clients);
}
});
return future;
}
/**
* Gets a list of all complaints on the selected virtual server.
*
* @return a list of all complaints on the virtual server
*
* @querycommands 1
* @see Complaint
* @see #getComplaints(int)
*/
public CommandFuture> getComplaints() {
return getComplaints(-1);
}
/**
* Gets a list of all complaints about the specified client.
*
* @param clientDBId
* the database ID of the client
*
* @return a list of all complaints about the specified client
*
* @querycommands 1
* @see Client#getDatabaseId()
* @see Complaint
*/
public CommandFuture> getComplaints(int clientDBId) {
final CComplainList list = new CComplainList(clientDBId);
final CommandFuture> future = new CommandFuture<>();
query.doCommandAsync(list, new Callback() {
@Override
public void handle() {
if (hasFailed(list, future)) return;
final List responses = list.getResponse();
final List complaints = new ArrayList<>(responses.size());
for (final Wrapper response : responses) {
complaints.add(new Complaint(response.getMap()));
}
future.set(complaints);
}
});
return future;
}
/**
* Gets detailed connection information about the selected virtual server.
*
* @return connection information about the selected virtual server
*
* @querycommands 1
* @see ConnectionInfo
* @see #getServerInfo()
*/
public CommandFuture getConnectionInfo() {
final CServerRequestConnectionInfo info = new CServerRequestConnectionInfo();
final CommandFuture future = new CommandFuture<>();
query.doCommandAsync(info, new Callback() {
@Override
public void handle() {
if (hasFailed(info, future)) return;
future.set(new ConnectionInfo(info.getFirstResponse().getMap()));
}
});
return future;
}
/**
* Gets all clients in the database whose last nickname matches the specified name exactly.
*
* @param name
* the nickname for the clients to match
*
* @return a list of all clients with a matching nickname
*
* @querycommands 1 + n,
* where n is the amount of database clients with a matching nickname
* @see Client#getNickname()
*/
public CommandFuture> getDatabaseClientsByName(String name) {
final CClientDBFind find = new CClientDBFind(name, false);
final CommandFuture> future = new CommandFuture<>();
query.doCommandAsync(find, new Callback() {
@Override
public void handle() {
if (hasFailed(find, future)) return;
final List responses = find.getResponse();
final Collection> infoFutures = new ArrayList<>(responses.size());
for (Wrapper response : responses) {
final int databaseId = response.getInt("cldbid");
infoFutures.add(getDatabaseClientInfo(databaseId));
}
CommandFuture.ofAll(infoFutures).forwardResult(future);
}
});
return future;
}
/**
* Gets information about the client with the specified unique identifier in the server database.
*
* @param clientUId
* the unique identifier of the client
*
* @return the database client or {@code null} if no client was found
*
* @querycommands 2
* @see Client#getUniqueIdentifier()
* @see DatabaseClientInfo
*/
public CommandFuture getDatabaseClientByUId(String clientUId) {
final CClientGetDBIdFromUId get = new CClientGetDBIdFromUId(clientUId);
final CommandFuture future = new CommandFuture<>();
query.doCommandAsync(get, new Callback() {
@Override
public void handle() {
if (hasFailed(get, future)) return;
getDatabaseClientInfo(get.getFirstResponse().getInt("cldbid")).forwardResult(future);
}
});
return future;
}
/**
* Gets information about the client with the specified database ID in the server database.
*
* @param clientDBId
* the database ID of the client
*
* @return the database client or {@code null} if no client was found
*
* @querycommands 1
* @see Client#getDatabaseId()
* @see DatabaseClientInfo
*/
public CommandFuture getDatabaseClientInfo(int clientDBId) {
final CClientDBInfo info = new CClientDBInfo(clientDBId);
final CommandFuture future = new CommandFuture<>();
query.doCommandAsync(info, new Callback() {
@Override
public void handle() {
if (hasFailed(info, future)) return;
future.set(new DatabaseClientInfo(info.getFirstResponse().getMap()));
}
});
return future;
}
/**
* Gets information about all clients in the server database.
*
* As this method uses internal commands which can only return 200 clients at once,
* this method can take quite some time to execute.
*
* Also keep in mind that the client database can easily accumulate several thousand entries.
*
*
* @return a {@link List} of all database clients
*
* @querycommands 1 + n,
* where n = Math.ceil([amount of database clients] / 200)
* @see DatabaseClient
*/
public CommandFuture> getDatabaseClients() {
final CClientDBList countList = new CClientDBList(0, 1, true);
final CommandFuture> future = new CommandFuture<>();
query.doCommandAsync(countList, new Callback() {
@Override
public void handle() {
if (hasFailed(countList, future)) return;
final int count = countList.getFirstResponse().getInt("count");
final int futuresCount = ((count - 1) / 200) + 1;
final Collection>> futures = new ArrayList<>(futuresCount);
for (int i = 0; i < count; i += 200) {
futures.add(getDatabaseClients(i, 200));
}
CommandFuture.ofAll(futures).onSuccess(new CommandFuture.SuccessListener>>() {
@Override
public void handleSuccess(List> result) {
int total = 0;
for (List list : result) {
total += list.size();
}
final List combination = new ArrayList<>(total);
for (List list : result) {
combination.addAll(list);
}
future.set(combination);
}
}).forwardFailure(future);
}
});
return future;
}
/**
* Gets information about a set number of clients in the server database, starting at {@code offset}.
*
* @param offset
* the index of the first database client to be returned.
* Note that this is not a database ID, but an arbitrary, 0-based index.
* @param count
* the number of database clients that should be returned.
* Any integer greater than 200 might cause problems with the connection
*
* @return a {@link List} of database clients
*
* @querycommands 1
* @see DatabaseClient
*/
public CommandFuture> getDatabaseClients(final int offset, final int count) {
final CClientDBList list = new CClientDBList(offset, count, false);
final CommandFuture> future = new CommandFuture<>();
query.doCommandAsync(list, new Callback() {
@Override
public void handle() {
if (hasFailed(list, future)) return;
final List clients = new ArrayList<>(count);
for (final Wrapper response : list.getResponse()) {
clients.add(new DatabaseClient(response.getMap()));
}
future.set(clients);
}
});
return future;
}
/**
* Gets information about a file on the file repository in the specified channel.
*
* Note that this method does not work on directories and the information returned by this
* method is identical to the one returned by {@link #getFileList(String, int, String)}
*
*
* @param filePath
* the path to the file
* @param channelId
* the ID of the channel the file resides in
*
* @return some information about the file
*
* @querycommands 1
* @see FileInfo#getPath()
* @see Channel#getId()
*/
public CommandFuture getFileInfo(String filePath, int channelId) {
return getFileInfo(filePath, channelId, null);
}
/**
* Gets information about a file on the file repository in the specified channel.
*
* Note that this method does not work on directories and the information returned by this
* method is identical to the one returned by {@link #getFileList(String, int, String)}
*
*
* @param filePath
* the path to the file
* @param channelId
* the ID of the channel the file resides in
* @param channelPassword
* the password of that channel
*
* @return some information about the file
*
* @querycommands 1
* @see FileInfo#getPath()
* @see Channel#getId()
*/
public CommandFuture getFileInfo(String filePath, int channelId, String channelPassword) {
final CFtGetFileInfo info = new CFtGetFileInfo(channelId, channelPassword, filePath);
final CommandFuture future = new CommandFuture<>();
query.doCommandAsync(info, new Callback() {
@Override
public void handle() {
if (hasFailed(info, future)) return;
future.set(new FileInfo(info.getFirstResponse().getMap()));
}
});
return future;
}
/**
* Gets information about multiple files on the file repository in the specified channel.
*
* Note that this method does not work on directories and the information returned by this
* method is identical to the one returned by {@link #getFileList(String, int, String)}
*
*
* @param filePaths
* the paths to the files
* @param channelId
* the ID of the channel the file resides in
*
* @return some information about the file
*
* @querycommands 1
* @see FileInfo#getPath()
* @see Channel#getId()
*/
public CommandFuture> getFileInfos(String filePaths[], int channelId) {
return getFileInfos(filePaths, channelId, null);
}
/**
* Gets information about multiple files on the file repository in the specified channel.
*
* Note that this method does not work on directories and the information returned by this
* method is identical to the one returned by {@link #getFileList(String, int, String)}
*
*
* @param filePaths
* the paths to the files
* @param channelId
* the ID of the channel the file resides in
* @param channelPassword
* the password of that channel
*
* @return some information about the file
*
* @querycommands 1
* @see FileInfo#getPath()
* @see Channel#getId()
*/
public CommandFuture> getFileInfos(String filePaths[], int channelId, String channelPassword) {
final CFtGetFileInfo info = new CFtGetFileInfo(channelId, channelPassword, filePaths);
final CommandFuture> future = new CommandFuture<>();
query.doCommandAsync(info, new Callback() {
@Override
public void handle() {
if (hasFailed(info, future)) return;
final List responses = info.getResponse();
final List files = new ArrayList<>(responses.size());
for (final Wrapper response : responses) {
files.add(new FileInfo(response.getMap()));
}
future.set(files);
}
});
return future;
}
/**
* Gets information about multiple files on the file repository in multiple channels.
*
* Note that this method does not work on directories and the information returned by this
* method is identical to the one returned by {@link #getFileList(String, int, String)}
*
*
* @param filePaths
* the paths to the files, may not be {@code null} and may not contain {@code null} elements
* @param channelIds
* the IDs of the channels the file resides in, may not be {@code null}
* @param channelPasswords
* the passwords of those channels, may be {@code null} and may contain {@code null} elements
*
* @return some information about the files
*
* @throws IllegalArgumentException
* if the dimensions of {@code filePaths}, {@code channelIds} and {@code channelPasswords} don't match
* @querycommands 1
* @see FileInfo#getPath()
* @see Channel#getId()
*/
public CommandFuture> getFileInfos(String filePaths[], int[] channelIds, String[] channelPasswords) {
final CFtGetFileInfo info = new CFtGetFileInfo(channelIds, channelPasswords, filePaths);
final CommandFuture> future = new CommandFuture<>();
query.doCommandAsync(info, new Callback() {
@Override
public void handle() {
if (hasFailed(info, future)) return;
final List responses = info.getResponse();
final List files = new ArrayList<>(responses.size());
for (final Wrapper response : responses) {
files.add(new FileInfo(response.getMap()));
}
future.set(files);
}
});
return future;
}
/**
* Gets a list of files and directories in the specified parent directory and channel.
*
* @param directoryPath
* the path to the parent directory
* @param channelId
* the ID of the channel the directory resides in
*
* @return the files and directories in the parent directory
*
* @querycommands 1
* @see FileInfo#getPath()
* @see Channel#getId()
*/
public CommandFuture> getFileList(String directoryPath, int channelId) {
return getFileList(directoryPath, channelId, null);
}
/**
* Gets a list of files and directories in the specified parent directory and channel.
*
* @param directoryPath
* the path to the parent directory
* @param channelId
* the ID of the channel the directory resides in
* @param channelPassword
* the password of that channel
*
* @return the files and directories in the parent directory
*
* @querycommands 1
* @see FileInfo#getPath()
* @see Channel#getId()
*/
public CommandFuture> getFileList(final String directoryPath, final int channelId, String channelPassword) {
final CFtGetFileList list = new CFtGetFileList(directoryPath, channelId, channelPassword);
final CommandFuture> future = new CommandFuture<>();
query.doCommandAsync(list, new Callback() {
@Override
public void handle() {
if (hasFailed(list, future)) return;
final List responses = list.getResponse();
final List files = new ArrayList<>(responses.size());
for (final Wrapper response : responses) {
files.add(new FileListEntry(response.getMap(), channelId, directoryPath));
}
future.set(files);
}
});
return future;
}
/**
* Gets a list of active or recently active file transfers.
*
* @return a list of file transfers
*/
public CommandFuture> getFileTransfers() {
final CFtList list = new CFtList();
final CommandFuture> future = new CommandFuture<>();
query.doCommandAsync(list, new Callback() {
@Override
public void handle() {
if (hasFailed(list, future)) return;
final List responses = list.getResponse();
final List transfers = new ArrayList<>(responses.size());
for (final Wrapper response : responses) {
transfers.add(new FileTransfer(response.getMap()));
}
future.set(transfers);
}
});
return future;
}
/**
* Displays detailed configuration information about the server instance including
* uptime, number of virtual servers online, traffic information, etc.
*
* @return information about the host
*
* @querycommands 1
*/
public CommandFuture getHostInfo() {
final CHostInfo info = new CHostInfo();
final CommandFuture future = new CommandFuture<>();
query.doCommandAsync(info, new Callback() {
@Override
public void handle() {
if (hasFailed(info, future)) return;
future.set(new HostInfo(info.getFirstResponse().getMap()));
}
});
return future;
}
/**
* Gets a list of all icon files on this virtual server.
*
* @return a list of all icons
*/
public CommandFuture> getIconList() {
final CommandFuture> future = new CommandFuture<>();
getFileList("/icons/", 0).onSuccess(new CommandFuture.SuccessListener>() {
@Override
public void handleSuccess(List result) {
List icons = new ArrayList<>(result.size());
for (FileListEntry file : result) {
if (file.isDirectory() || file.isStillUploading()) continue;
icons.add(new IconFile(file.getMap(), 0, "/icons/"));
}
future.set(icons);
}
}).forwardFailure(future);
return future;
}
/**
* Displays the server instance configuration including database revision number,
* the file transfer port, default group IDs, etc.
*
* @return information about the TeamSpeak server instance.
*
* @querycommands 1
*/
public CommandFuture getInstanceInfo() {
final CInstanceInfo info = new CInstanceInfo();
final CommandFuture future = new CommandFuture<>();
query.doCommandAsync(info, new Callback() {
@Override
public void handle() {
if (hasFailed(info, future)) return;
future.set(new InstanceInfo(info.getFirstResponse().getMap()));
}
});
return future;
}
/**
* Reads the message body of a message. This will not set the read flag, though.
*
* @param messageId
* the ID of the message to be read
*
* @return the body of the message with the specified ID or {@code null} if there was no message with that ID
*
* @querycommands 1
* @see Message#getId()
* @see #setMessageRead(int)
*/
public CommandFuture getOfflineMessage(int messageId) {
final CMessageGet get = new CMessageGet(messageId);
return executeAndReturnStringProperty(get, "message");
}
/**
* Reads the message body of a message. This will not set the read flag, though.
*
* @param message
* the message to be read
*
* @return the body of the message with the specified ID or {@code null} if there was no message with that ID
*
* @querycommands 1
* @see Message#getId()
* @see #setMessageRead(Message)
*/
public CommandFuture getOfflineMessage(Message message) {
return getOfflineMessage(message.getId());
}
/**
* Gets a list of all offline messages for the server query.
* The returned messages lack their message body, though.
* To read the actual message, use {@link #getOfflineMessage(int)} or {@link #getOfflineMessage(Message)}.
*
* @return a list of all offline messages this server query has received
*
* @querycommands 1
*/
public CommandFuture> getOfflineMessages() {
final CMessageList list = new CMessageList();
final CommandFuture> future = new CommandFuture<>();
query.doCommandAsync(list, new Callback() {
@Override
public void handle() {
if (hasFailed(list, future)) return;
final List responses = list.getResponse();
final List msg = new ArrayList<>(responses.size());
for (final Wrapper response : responses) {
msg.add(new Message(response.getMap()));
}
future.set(msg);
}
});
return future;
}
/**
* Displays detailed information about all assignments of the permission specified
* with {@code permName}. The output includes the type and the ID of the client,
* channel or group associated with the permission.
*
* @param permName
* the name of the permission
*
* @return a list of permission assignments
*
* @querycommands 1
* @see #getPermissionOverview(int, int)
*/
public CommandFuture> getPermissionAssignments(String permName) {
final CPermFind find = new CPermFind(permName);
final CommandFuture> future = new CommandFuture<>();
query.doCommandAsync(find, new Callback() {
@Override
public void handle() {
if (hasFailed(find, future)) return;
final List responses = find.getResponse();
final List assignments = new ArrayList<>(responses.size());
for (final Wrapper response : responses) {
assignments.add(new PermissionAssignment(response.getMap()));
}
future.set(assignments);
}
});
return future;
}
/**
* Gets the ID of the permission specified by {@code permName}.
*
* Note that the use of numeric permission IDs is deprecated
* and that this API only uses the string variant of the IDs.
*
*
* @param permName
* the name of the permission
*
* @return the numeric ID of the specified permission
*
* @querycommands 1
*/
public CommandFuture getPermissionIdByName(String permName) {
final CPermIdGetByName get = new CPermIdGetByName(permName);
return executeAndReturnIntProperty(get, "permid");
}
/**
* Gets the IDs of the permissions specified by {@code permNames}.
*
* Note that the use of numeric permission IDs is deprecated
* and that this API only uses the string variant of the IDs.
*
*
* @param permNames
* the names of the permissions
*
* @return the numeric IDs of the specified permission
*
* @throws IllegalArgumentException
* if {@code permNames} is {@code null}
* @querycommands 1
*/
public CommandFuture getPermissionIdsByName(String[] permNames) {
if (permNames == null) throw new IllegalArgumentException("permNames was null");
final CPermIdGetByName get = new CPermIdGetByName(permNames);
final CommandFuture future = new CommandFuture<>();
query.doCommandAsync(get, new Callback() {
@Override
public void handle() {
if (hasFailed(get, future)) return;
final List responses = get.getResponse();
int[] ids = new int[responses.size()];
int i = 0;
for (final Wrapper response : get.getResponse()) {
ids[i++] = response.getInt("permid");
}
future.set(ids);
}
});
return future;
}
/**
* Gets a list of all assigned permissions for a client in a specified channel.
* If you do not care about channel permissions, set {@code channelId} to {@code -1}.
*
* @param channelId
* the ID of the channel
* @param clientDBId
* the database ID of the client to create the overview for
*
* @return a list of all permission assignments for the client in the specified channel
*
* @querycommands 1
* @see Channel#getId()
* @see Client#getDatabaseId()
*/
public CommandFuture> getPermissionOverview(int channelId, int clientDBId) {
final CPermOverview overview = new CPermOverview(channelId, clientDBId);
final CommandFuture> future = new CommandFuture<>();
query.doCommandAsync(overview, new Callback() {
@Override
public void handle() {
if (hasFailed(overview, future)) return;
final List responses = overview.getResponse();
final List permissions = new ArrayList<>(responses.size());
for (final Wrapper response : responses) {
permissions.add(new PermissionAssignment(response.getMap()));
}
future.set(permissions);
}
});
return future;
}
/**
* Displays a list of all permissions, including ID, name and description.
*
* @return a list of all permissions
*
* @querycommands 1
*/
public CommandFuture> getPermissions() {
final CPermissionList list = new CPermissionList();
final CommandFuture> future = new CommandFuture<>();
query.doCommandAsync(list, new Callback() {
@Override
public void handle() {
if (hasFailed(list, future)) return;
final List responses = list.getResponse();
final List permissions = new ArrayList<>(responses.size());
for (final Wrapper response : responses) {
permissions.add(new PermissionInfo(response.getMap()));
}
future.set(permissions);
}
});
return future;
}
/**
* Displays the current value of the specified permission for this server query instance.
*
* @param permName
* the name of the permission
*
* @return the permission value, usually ranging from 0 to 100
*
* @querycommands 1
*/
public CommandFuture getPermissionValue(String permName) {
final CPermGet get = new CPermGet(permName);
return executeAndReturnIntProperty(get, "permvalue");
}
/**
* Displays the current values of the specified permissions for this server query instance.
*
* @param permNames
* the names of the permissions
*
* @return the permission values, usually ranging from 0 to 100
*
* @throws IllegalArgumentException
* if {@code permNames} is {@code null}
* @querycommands 1
*/
public CommandFuture getPermissionValues(String[] permNames) {
if (permNames == null) throw new IllegalArgumentException("permNames was null");
final CPermGet get = new CPermGet(permNames);
final CommandFuture future = new CommandFuture<>();
query.doCommandAsync(get, new Callback() {
@Override
public void handle() {
if (hasFailed(get, future)) return;
final List responses = get.getResponse();
int[] values = new int[responses.size()];
int i = 0;
for (final Wrapper response : get.getResponse()) {
values[i++] = response.getInt("permvalue");
}
future.set(values);
}
});
return future;
}
/**
* Gets a list of all available tokens to join channel or server groups,
* including their type and group IDs.
*
* @return a list of all generated, but still unclaimed privilege keys
*
* @querycommands 1
* @see #addPrivilegeKey(PrivilegeKeyType, int, int, String)
* @see #usePrivilegeKey(String)
*/
public CommandFuture> getPrivilegeKeys() {
final CPrivilegeKeyList list = new CPrivilegeKeyList();
final CommandFuture> future = new CommandFuture<>();
query.doCommandAsync(list, new Callback() {
@Override
public void handle() {
if (hasFailed(list, future)) return;
final List responses = list.getResponse();
final List keys = new ArrayList<>(responses.size());
for (final Wrapper response : responses) {
keys.add(new PrivilegeKey(response.getMap()));
}
future.set(keys);
}
});
return future;
}
/**
* Gets a list of all clients in the specified server group.
*
* @param serverGroupId
* the ID of the server group for which the clients should be looked up
*
* @return a list of all clients in the server group
*
* @querycommands 1
*/
public CommandFuture> getServerGroupClients(int serverGroupId) {
final CServerGroupClientList list = new CServerGroupClientList(serverGroupId);
final CommandFuture> future = new CommandFuture<>();
query.doCommandAsync(list, new Callback() {
@Override
public void handle() {
if (hasFailed(list, future)) return;
final List responses = list.getResponse();
final List clients = new ArrayList<>(responses.size());
for (final Wrapper response : responses) {
clients.add(new ServerGroupClient(response.getMap()));
}
future.set(clients);
}
});
return future;
}
/**
* Gets a list of all clients in the specified server group.
*
* @param serverGroup
* the server group for which the clients should be looked up
*
* @return a list of all clients in the server group
*
* @querycommands 1
*/
public CommandFuture> getServerGroupClients(ServerGroup serverGroup) {
return getServerGroupClients(serverGroup.getId());
}
/**
* Gets a list of all permissions assigned to the specified server group.
*
* @param serverGroupId
* the ID of the server group for which the permissions should be looked up
*
* @return a list of all permissions assigned to the server group
*
* @querycommands 1
* @see ServerGroup#getId()
* @see #getServerGroupPermissions(ServerGroup)
*/
public CommandFuture> getServerGroupPermissions(int serverGroupId) {
final CServerGroupPermList list = new CServerGroupPermList(serverGroupId);
final CommandFuture> future = new CommandFuture<>();
query.doCommandAsync(list, new Callback() {
@Override
public void handle() {
if (hasFailed(list, future)) return;
final List responses = list.getResponse();
final List permissions = new ArrayList<>(responses.size());
for (final Wrapper response : responses) {
permissions.add(new Permission(response.getMap()));
}
future.set(permissions);
}
});
return future;
}
/**
* Gets a list of all permissions assigned to the specified server group.
*
* @param serverGroup
* the server group for which the permissions should be looked up
*
* @return a list of all permissions assigned to the server group
*
* @querycommands 1
*/
public CommandFuture> getServerGroupPermissions(ServerGroup serverGroup) {
return getServerGroupPermissions(serverGroup.getId());
}
/**
* Gets a list of all server groups on the virtual server.
*
* Depending on your permissions, the output may also contain
* global server query groups and template groups.
*
*
* @return a list of all server groups
*
* @querycommands 1
*/
public CommandFuture> getServerGroups() {
final CServerGroupList list = new CServerGroupList();
final CommandFuture> future = new CommandFuture<>();
query.doCommandAsync(list, new Callback() {
@Override
public void handle() {
if (hasFailed(list, future)) return;
final List responses = list.getResponse();
final List groups = new ArrayList<>(responses.size());
for (final Wrapper response : responses) {
groups.add(new ServerGroup(response.getMap()));
}
future.set(groups);
}
});
return future;
}
/**
* Gets a list of all server groups set for a client.
*
* @param clientDatabaseId
* the database ID of the client for which the server groups should be looked up
*
* @return a list of all server groups set for the client
*
* @querycommands 2
* @see Client#getDatabaseId()
* @see #getServerGroupsByClient(Client)
*/
public CommandFuture> getServerGroupsByClientId(int clientDatabaseId) {
final CServerGroupsByClientId client = new CServerGroupsByClientId(clientDatabaseId);
final CommandFuture> future = new CommandFuture<>();
getServerGroups().onSuccess(new CommandFuture.SuccessListener