001package com.github.theholywaffle.teamspeak3;
002
003/*
004 * #%L
005 * TeamSpeak 3 Java API
006 * %%
007 * Copyright (C) 2014 Bert De Geyter
008 * %%
009 * Permission is hereby granted, free of charge, to any person obtaining a copy
010 * of this software and associated documentation files (the "Software"), to deal
011 * in the Software without restriction, including without limitation the rights
012 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
013 * copies of the Software, and to permit persons to whom the Software is
014 * furnished to do so, subject to the following conditions:
015 * 
016 * The above copyright notice and this permission notice shall be included in
017 * all copies or substantial portions of the Software.
018 * 
019 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
020 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
021 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
022 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
023 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
024 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
025 * THE SOFTWARE.
026 * #L%
027 */
028
029import com.github.theholywaffle.teamspeak3.api.*;
030import com.github.theholywaffle.teamspeak3.api.event.TS3EventType;
031import com.github.theholywaffle.teamspeak3.api.event.TS3Listener;
032import com.github.theholywaffle.teamspeak3.api.exception.TS3CommandFailedException;
033import com.github.theholywaffle.teamspeak3.api.exception.TS3ConnectionFailedException;
034import com.github.theholywaffle.teamspeak3.api.exception.TS3FileTransferFailedException;
035import com.github.theholywaffle.teamspeak3.api.wrapper.*;
036
037import java.io.InputStream;
038import java.io.OutputStream;
039import java.util.List;
040import java.util.Map;
041import java.util.regex.Pattern;
042
043/**
044 * API to interact with the {@link TS3Query} synchronously.
045 * <p>
046 * This class is used to easily interact with a {@link TS3Query}. It constructs commands,
047 * sends them to the TeamSpeak3 server, processes the response and returns the result.
048 * </p><p>
049 * All methods in this class are synchronous, so they will block until the response arrives.
050 * Calls to this API will usually take about 50 milliseconds to complete (plus ping),
051 * but delays can range up to 4 seconds.
052 * If a command takes longer than 4 seconds to complete, a {@link TS3ConnectionFailedException}
053 * will be thrown.
054 * </p><p>
055 * You won't be able to execute most commands while you're not logged in due to missing permissions.
056 * Make sure to either pass your login credentials to the {@link TS3Config} object when
057 * creating the {@code TS3Query} or to call {@link #login(String, String)} to log in.
058 * </p><p>
059 * After that, most commands also require you to select a {@linkplain VirtualServer virtual server}.
060 * To do so, call either {@link #selectVirtualServerByPort(int)} or {@link #selectVirtualServerById(int)}.
061 * </p><p>
062 * Be aware that many methods in this class will return {@code null} or {@code -1} if a command fails.
063 * </p>
064 *
065 * @see TS3ApiAsync The asynchronous version of the API
066 */
067public class TS3Api {
068
069        private final TS3ApiAsync asyncApi;
070
071        /**
072         * Creates a new synchronous API object for the given {@code TS3Query}.
073         * <p>
074         * <b>Usually, this constructor should not be called.</b> Use {@link TS3Query#getApi()} instead.
075         * </p>
076         *
077         * @param asyncApi
078         *              the asynchronous version of the API this class routes its method calls through
079         */
080        public TS3Api(TS3ApiAsync asyncApi) {
081                this.asyncApi = asyncApi;
082        }
083
084        /**
085         * Adds a new ban entry. At least one of the parameters {@code ip}, {@code name} or {@code uid} needs to be non-null.
086         * Returns the ID of the newly created ban entry.
087         *
088         * @param ip
089         *              a RegEx pattern to match a client's IP against, can be {@code null}
090         * @param name
091         *              a RegEx pattern to match a client's name against, can be {@code null}
092         * @param uid
093         *              the unique identifier of a client, can be {@code null}
094         * @param timeInSeconds
095         *              the duration of the ban in seconds. 0 equals a permanent ban
096         * @param reason
097         *              the reason for the ban, can be {@code null}
098         *
099         * @return the ID of the newly created ban entry
100         *
101         * @throws TS3CommandFailedException
102         *              if the execution of a command fails
103         * @querycommands 1
104         * @see Pattern RegEx Pattern
105         * @see #addBan(String, String, String, String, long, String)
106         * @see Client#getId()
107         * @see Client#getUniqueIdentifier()
108         * @see ClientInfo#getIp()
109         */
110        public int addBan(String ip, String name, String uid, long timeInSeconds, String reason) {
111                return asyncApi.addBan(ip, name, uid, timeInSeconds, reason).getUninterruptibly();
112        }
113
114        /**
115         * Adds a new ban entry. At least one of the parameters {@code ip}, {@code name}, {@code uid}, or
116         * {@code myTSId} needs to be non-null. Returns the ID of the newly created ban entry.
117         * <p>
118         * Note that creating a ban entry for the {@code "empty"} "myTeamSpeak" ID will ban all clients who
119         * don't have a linked "myTeamSpeak" account.
120         * </p>
121         *
122         * @param ip
123         *              a RegEx pattern to match a client's IP against, can be {@code null}
124         * @param name
125         *              a RegEx pattern to match a client's name against, can be {@code null}
126         * @param uid
127         *              the unique identifier of a client, can be {@code null}
128         * @param myTSId
129         *              the "myTeamSpeak" ID of a client, the string {@code "empty"}, or {@code null}
130         * @param timeInSeconds
131         *              the duration of the ban in seconds. 0 equals a permanent ban
132         * @param reason
133         *              the reason for the ban, can be {@code null}
134         *
135         * @return the ID of the newly created ban entry
136         *
137         * @throws TS3CommandFailedException
138         *              if the execution of a command fails
139         * @querycommands 1
140         * @see Pattern RegEx Pattern
141         * @see Client#getId()
142         * @see Client#getUniqueIdentifier()
143         * @see ClientInfo#getIp()
144         */
145        public int addBan(String ip, String name, String uid, String myTSId, long timeInSeconds, String reason) {
146                return asyncApi.addBan(ip, name, uid, myTSId, timeInSeconds, reason).getUninterruptibly();
147        }
148
149        /**
150         * Adds a specified permission to a client in a specific channel.
151         *
152         * @param channelId
153         *              the ID of the channel wherein the permission should be granted
154         * @param clientDBId
155         *              the database ID of the client to add a permission to
156         * @param permName
157         *              the name of the permission to grant
158         * @param permValue
159         *              the numeric value of the permission (or for boolean permissions: 1 = true, 0 = false)
160         *
161         * @throws TS3CommandFailedException
162         *              if the execution of a command fails
163         * @querycommands 1
164         * @see Channel#getId()
165         * @see Client#getDatabaseId()
166         * @see Permission
167         */
168        public void addChannelClientPermission(int channelId, int clientDBId, String permName, int permValue) {
169                asyncApi.addChannelClientPermission(channelId, clientDBId, permName, permValue).getUninterruptibly();
170        }
171
172        /**
173         * Creates a new channel group for clients using a given name and returns its ID.
174         * <p>
175         * To create channel group templates or ones for server queries,
176         * use {@link #addChannelGroup(String, PermissionGroupDatabaseType)}.
177         * </p>
178         *
179         * @param name
180         *              the name of the new channel group
181         *
182         * @return the ID of the newly created channel group
183         *
184         * @throws TS3CommandFailedException
185         *              if the execution of a command fails
186         * @querycommands 1
187         * @see ChannelGroup
188         */
189        public int addChannelGroup(String name) {
190                return asyncApi.addChannelGroup(name).getUninterruptibly();
191        }
192
193        /**
194         * Creates a new channel group using a given name and returns its ID.
195         *
196         * @param name
197         *              the name of the new channel group
198         * @param type
199         *              the desired type of channel group
200         *
201         * @return the ID of the newly created channel group
202         *
203         * @throws TS3CommandFailedException
204         *              if the execution of a command fails
205         * @querycommands 1
206         * @see ChannelGroup
207         */
208        public int addChannelGroup(String name, PermissionGroupDatabaseType type) {
209                return asyncApi.addChannelGroup(name, type).getUninterruptibly();
210        }
211
212        /**
213         * Adds a specified permission to a channel group.
214         *
215         * @param groupId
216         *              the ID of the channel group to grant the permission
217         * @param permName
218         *              the name of the permission to be granted
219         * @param permValue
220         *              the numeric value of the permission (or for boolean permissions: 1 = true, 0 = false)
221         *
222         * @throws TS3CommandFailedException
223         *              if the execution of a command fails
224         * @querycommands 1
225         * @see ChannelGroup#getId()
226         * @see Permission
227         */
228        public void addChannelGroupPermission(int groupId, String permName, int permValue) {
229                asyncApi.addChannelGroupPermission(groupId, permName, permValue).getUninterruptibly();
230        }
231
232        /**
233         * Adds a specified permission to a channel.
234         *
235         * @param channelId
236         *              the ID of the channel wherein the permission should be granted
237         * @param permName
238         *              the name of the permission to grant
239         * @param permValue
240         *              the numeric value of the permission (or for boolean permissions: 1 = true, 0 = false)
241         *
242         * @throws TS3CommandFailedException
243         *              if the execution of a command fails
244         * @querycommands 1
245         * @see Channel#getId()
246         * @see Permission
247         */
248        public void addChannelPermission(int channelId, String permName, int permValue) {
249                asyncApi.addChannelPermission(channelId, permName, permValue).getUninterruptibly();
250        }
251
252        /**
253         * Adds a specified permission to a channel.
254         *
255         * @param clientDBId
256         *              the database ID of the client to grant the permission
257         * @param permName
258         *              the name of the permission to grant
259         * @param value
260         *              the numeric value of the permission (or for boolean permissions: 1 = true, 0 = false)
261         * @param skipped
262         *              if set to {@code true}, the permission will not be overridden by channel group permissions
263         *
264         * @throws TS3CommandFailedException
265         *              if the execution of a command fails
266         * @querycommands 1
267         * @see Client#getDatabaseId()
268         * @see Permission
269         */
270        public void addClientPermission(int clientDBId, String permName, int value, boolean skipped) {
271                asyncApi.addClientPermission(clientDBId, permName, value, skipped).getUninterruptibly();
272        }
273
274        /**
275         * Adds a client to the specified server group.
276         * <p>
277         * Please note that a client cannot be added to default groups or template groups.
278         * </p>
279         *
280         * @param groupId
281         *              the ID of the server group to add the client to
282         * @param clientDatabaseId
283         *              the database ID of the client to add
284         *
285         * @throws TS3CommandFailedException
286         *              if the execution of a command fails
287         * @querycommands 1
288         * @see ServerGroup#getId()
289         * @see Client#getDatabaseId()
290         */
291        public void addClientToServerGroup(int groupId, int clientDatabaseId) {
292                asyncApi.addClientToServerGroup(groupId, clientDatabaseId).getUninterruptibly();
293        }
294
295        /**
296         * Submits a complaint about the specified client.
297         * The length of the message is limited to 200 UTF-8 bytes and BB codes in it will be ignored.
298         *
299         * @param clientDBId
300         *              the database ID of the client
301         * @param message
302         *              the message of the complaint, may not contain BB codes
303         *
304         * @throws TS3CommandFailedException
305         *              if the execution of a command fails
306         * @querycommands 1
307         * @see Client#getDatabaseId()
308         * @see Complaint#getMessage()
309         */
310        public void addComplaint(int clientDBId, String message) {
311                asyncApi.addComplaint(clientDBId, message).getUninterruptibly();
312        }
313
314        /**
315         * Adds a specified permission to all server groups of the type specified by {@code type} on all virtual servers.
316         *
317         * @param type
318         *              the kind of server group this permission should be added to
319         * @param permName
320         *              the name of the permission to be granted
321         * @param value
322         *              the numeric value of the permission (or for boolean permissions: 1 = true, 0 = false)
323         * @param negated
324         *              if set to true, the lowest permission value will be selected instead of the highest
325         * @param skipped
326         *              if set to true, this permission will not be overridden by client or channel group permissions
327         *
328         * @throws TS3CommandFailedException
329         *              if the execution of a command fails
330         * @querycommands 1
331         * @see ServerGroupType
332         * @see Permission
333         */
334        public void addPermissionToAllServerGroups(ServerGroupType type, String permName, int value, boolean negated, boolean skipped) {
335                asyncApi.addPermissionToAllServerGroups(type, permName, value, negated, skipped).getUninterruptibly();
336        }
337
338        /**
339         * Create a new privilege key that allows one client to join a server or channel group.
340         * <ul>
341         * <li>If {@code type} is set to {@linkplain PrivilegeKeyType#SERVER_GROUP SERVER_GROUP},
342         * {@code groupId} is used as a server group ID and {@code channelId} is ignored.</li>
343         * <li>If {@code type} is set to {@linkplain PrivilegeKeyType#CHANNEL_GROUP CHANNEL_GROUP},
344         * {@code groupId} is used as a channel group ID and {@code channelId} is used as the channel in which the group should be set.</li>
345         * </ul>
346         *
347         * @param type
348         *              the type of token that should be created
349         * @param groupId
350         *              the ID of the server or channel group
351         * @param channelId
352         *              the ID of the channel, in case the token is channel group token
353         * @param description
354         *              the description for the token, can be null
355         *
356         * @return the created token for a client to use
357         *
358         * @throws TS3CommandFailedException
359         *              if the execution of a command fails
360         * @querycommands 1
361         * @see PrivilegeKeyType
362         * @see #addPrivilegeKeyServerGroup(int, String)
363         * @see #addPrivilegeKeyChannelGroup(int, int, String)
364         */
365        public String addPrivilegeKey(PrivilegeKeyType type, int groupId, int channelId, String description) {
366                return asyncApi.addPrivilegeKey(type, groupId, channelId, description).getUninterruptibly();
367        }
368
369        /**
370         * Creates a new privilege key for a channel group.
371         *
372         * @param channelGroupId
373         *              the ID of the channel group
374         * @param channelId
375         *              the ID of the channel in which the channel group should be set
376         * @param description
377         *              the description for the token, can be null
378         *
379         * @return the created token for a client to use
380         *
381         * @throws TS3CommandFailedException
382         *              if the execution of a command fails
383         * @querycommands 1
384         * @see ChannelGroup#getId()
385         * @see Channel#getId()
386         * @see #addPrivilegeKey(PrivilegeKeyType, int, int, String)
387         * @see #addPrivilegeKeyServerGroup(int, String)
388         */
389        public String addPrivilegeKeyChannelGroup(int channelGroupId, int channelId, String description) {
390                return asyncApi.addPrivilegeKeyChannelGroup(channelGroupId, channelId, description).getUninterruptibly();
391        }
392
393        /**
394         * Creates a new privilege key for a server group.
395         *
396         * @param serverGroupId
397         *              the ID of the server group
398         * @param description
399         *              the description for the token, can be null
400         *
401         * @return the created token for a client to use
402         *
403         * @throws TS3CommandFailedException
404         *              if the execution of a command fails
405         * @querycommands 1
406         * @see ServerGroup#getId()
407         * @see #addPrivilegeKey(PrivilegeKeyType, int, int, String)
408         * @see #addPrivilegeKeyChannelGroup(int, int, String)
409         */
410        public String addPrivilegeKeyServerGroup(int serverGroupId, String description) {
411                return asyncApi.addPrivilegeKeyServerGroup(serverGroupId, description).getUninterruptibly();
412        }
413
414        /**
415         * Creates a new server group for clients using a given name and returns its ID.
416         * <p>
417         * To create server group templates or ones for server queries,
418         * use {@link #addServerGroup(String, PermissionGroupDatabaseType)}.
419         * </p>
420         *
421         * @param name
422         *              the name of the new server group
423         *
424         * @return the ID of the newly created server group
425         *
426         * @throws TS3CommandFailedException
427         *              if the execution of a command fails
428         * @querycommands 1
429         * @see ServerGroup
430         */
431        public int addServerGroup(String name) {
432                return asyncApi.addServerGroup(name).getUninterruptibly();
433        }
434
435        /**
436         * Creates a new server group using a given name and returns its ID.
437         *
438         * @param name
439         *              the name of the new server group
440         * @param type
441         *              the desired type of server group
442         *
443         * @return the ID of the newly created server group
444         *
445         * @throws TS3CommandFailedException
446         *              if the execution of a command fails
447         * @querycommands 1
448         * @see ServerGroup
449         * @see PermissionGroupDatabaseType
450         */
451        public int addServerGroup(String name, PermissionGroupDatabaseType type) {
452                return asyncApi.addServerGroup(name, type).getUninterruptibly();
453        }
454
455        /**
456         * Adds a specified permission to a server group.
457         *
458         * @param groupId
459         *              the ID of the channel group to which the permission should be added
460         * @param permName
461         *              the name of the permission to add
462         * @param value
463         *              the numeric value of the permission (or for boolean permissions: 1 = true, 0 = false)
464         * @param negated
465         *              if set to true, the lowest permission value will be selected instead of the highest
466         * @param skipped
467         *              if set to true, this permission will not be overridden by client or channel group permissions
468         *
469         * @throws TS3CommandFailedException
470         *              if the execution of a command fails
471         * @querycommands 1
472         * @see ServerGroup#getId()
473         * @see Permission
474         */
475        public void addServerGroupPermission(int groupId, String permName, int value, boolean negated, boolean skipped) {
476                asyncApi.addServerGroupPermission(groupId, permName, value, negated, skipped).getUninterruptibly();
477        }
478
479        /**
480         * Adds one or more {@link TS3Listener}s to the event manager of the query.
481         * These listeners will be notified when the TS3 server fires an event.
482         * <p>
483         * Note that for the TS3 server to fire events, you must first also register
484         * the event types you want to listen to.
485         * </p>
486         *
487         * @param listeners
488         *              one or more listeners to register
489         *
490         * @see #registerAllEvents()
491         * @see #registerEvent(TS3EventType, int)
492         * @see TS3Listener
493         * @see TS3EventType
494         */
495        public void addTS3Listeners(TS3Listener... listeners) {
496                asyncApi.addTS3Listeners(listeners);
497        }
498
499        /**
500         * Bans a client with a given client ID for a given time.
501         * <p>
502         * Please note that this will create 2 or 3 separate ban rules,
503         * one for the targeted client's IP address, one for their unique identifier,
504         * and potentially one more for their "myTeamSpeak" ID.
505         * </p><p>
506         * <i>Exception:</i> If the banned client connects via a loopback address
507         * (i.e. {@code 127.0.0.1} or {@code localhost}), no IP ban is created
508         * and the returned array will only have 1 entry.
509         * </p>
510         *
511         * @param clientId
512         *              the ID of the client
513         * @param timeInSeconds
514         *              the duration of the ban in seconds. 0 equals a permanent ban
515         *
516         * @return an array containing the IDs of the created ban entries
517         *
518         * @throws TS3CommandFailedException
519         *              if the execution of a command fails
520         * @querycommands 1
521         * @see Client#getId()
522         * @see #addBan(String, String, String, long, String)
523         */
524        public int[] banClient(int clientId, long timeInSeconds) {
525                return asyncApi.banClient(clientId, timeInSeconds).getUninterruptibly();
526        }
527
528        /**
529         * Bans a client with a given client ID for a given time for the specified reason.
530         * <p>
531         * Please note that this will create two separate ban rules,
532         * one for the targeted client's IP address and their unique identifier.
533         * </p><p>
534         * <i>Exception:</i> If the banned client connects via a loopback address
535         * (i.e. {@code 127.0.0.1} or {@code localhost}), no IP ban is created
536         * and the returned array will only have 1 entry.
537         * </p>
538         *
539         * @param clientId
540         *              the ID of the client
541         * @param timeInSeconds
542         *              the duration of the ban in seconds. 0 equals a permanent ban
543         * @param reason
544         *              the reason for the ban, can be null
545         *
546         * @return an array containing the IDs of the first and the second ban entry
547         *
548         * @throws TS3CommandFailedException
549         *              if the execution of a command fails
550         * @querycommands 1
551         * @see Client#getId()
552         * @see #addBan(String, String, String, long, String)
553         */
554        public int[] banClient(int clientId, long timeInSeconds, String reason) {
555                return asyncApi.banClient(clientId, timeInSeconds, reason).getUninterruptibly();
556        }
557
558        /**
559         * Bans a client with a given client ID permanently for the specified reason.
560         * <p>
561         * Please note that this will create two separate ban rules,
562         * one for the targeted client's IP address and their unique identifier.
563         * </p><p>
564         * <i>Exception:</i> If the banned client connects via a loopback address
565         * (i.e. {@code 127.0.0.1} or {@code localhost}), no IP ban is created
566         * and the returned array will only have 1 entry.
567         * </p>
568         *
569         * @param clientId
570         *              the ID of the client
571         * @param reason
572         *              the reason for the ban, can be null
573         *
574         * @return an array containing the IDs of the first and the second ban entry
575         *
576         * @throws TS3CommandFailedException
577         *              if the execution of a command fails
578         * @querycommands 1
579         * @see Client#getId()
580         * @see #addBan(String, String, String, long, String)
581         */
582        public int[] banClient(int clientId, String reason) {
583                return asyncApi.banClient(clientId, reason).getUninterruptibly();
584        }
585
586        /**
587         * Sends a text message to all clients on all virtual servers.
588         * These messages will appear to clients in the tab for server messages.
589         *
590         * @param message
591         *              the message to be sent
592         *
593         * @throws TS3CommandFailedException
594         *              if the execution of a command fails
595         * @querycommands 1
596         */
597        public void broadcast(String message) {
598                asyncApi.broadcast(message).getUninterruptibly();
599        }
600
601        /**
602         * Creates a copy of the channel group specified by {@code sourceGroupId},
603         * overwriting any other channel group specified by {@code targetGroupId}.
604         * <p>
605         * The parameter {@code type} can be used to create server query and template groups.
606         * </p>
607         *
608         * @param sourceGroupId
609         *              the ID of the channel group to copy
610         * @param targetGroupId
611         *              the ID of another channel group to overwrite
612         * @param type
613         *              the desired type of channel group
614         *
615         * @throws TS3CommandFailedException
616         *              if the execution of a command fails
617         * @querycommands 1
618         * @see ChannelGroup#getId()
619         */
620        public void copyChannelGroup(int sourceGroupId, int targetGroupId, PermissionGroupDatabaseType type) {
621                asyncApi.copyChannelGroup(sourceGroupId, targetGroupId, type).getUninterruptibly();
622        }
623
624        /**
625         * Creates a copy of the channel group specified by {@code sourceGroupId} with a given name
626         * and returns the ID of the newly created channel group.
627         *
628         * @param sourceGroupId
629         *              the ID of the channel group to copy
630         * @param targetName
631         *              the name for the copy of the channel group
632         * @param type
633         *              the desired type of channel group
634         *
635         * @return the ID of the newly created channel group
636         *
637         * @throws TS3CommandFailedException
638         *              if the execution of a command fails
639         * @querycommands 1
640         * @see ChannelGroup#getId()
641         */
642        public int copyChannelGroup(int sourceGroupId, String targetName, PermissionGroupDatabaseType type) {
643                return asyncApi.copyChannelGroup(sourceGroupId, targetName, type).getUninterruptibly();
644        }
645
646        /**
647         * Creates a copy of the server group specified by {@code sourceGroupId},
648         * overwriting another server group specified by {@code targetGroupId}.
649         * <p>
650         * The parameter {@code type} can be used to create server query and template groups.
651         * </p>
652         *
653         * @param sourceGroupId
654         *              the ID of the server group to copy
655         * @param targetGroupId
656         *              the ID of another server group to overwrite
657         * @param type
658         *              the desired type of server group
659         *
660         * @return the ID of the newly created server group
661         *
662         * @throws TS3CommandFailedException
663         *              if the execution of a command fails
664         * @querycommands 1
665         * @see ServerGroup#getId()
666         */
667        public int copyServerGroup(int sourceGroupId, int targetGroupId, PermissionGroupDatabaseType type) {
668                return asyncApi.copyServerGroup(sourceGroupId, targetGroupId, type).getUninterruptibly();
669        }
670
671        /**
672         * Creates a copy of the server group specified by {@code sourceGroupId} with a given name
673         * and returns the ID of the newly created server group.
674         *
675         * @param sourceGroupId
676         *              the ID of the server group to copy
677         * @param targetName
678         *              the name for the copy of the server group
679         * @param type
680         *              the desired type of server group
681         *
682         * @return the ID of the newly created server group
683         *
684         * @throws TS3CommandFailedException
685         *              if the execution of a command fails
686         * @querycommands 1
687         * @see ServerGroup#getId()
688         */
689        public int copyServerGroup(int sourceGroupId, String targetName, PermissionGroupDatabaseType type) {
690                return asyncApi.copyServerGroup(sourceGroupId, targetName, type).getUninterruptibly();
691        }
692
693        /**
694         * Creates a new channel with a given name using the given properties and returns its ID.
695         *
696         * @param name
697         *              the name for the new channel
698         * @param options
699         *              a map of options that should be set for the channel
700         *
701         * @return the ID of the newly created channel
702         *
703         * @throws TS3CommandFailedException
704         *              if the execution of a command fails
705         * @querycommands 1
706         * @see Channel
707         */
708        public int createChannel(String name, Map<ChannelProperty, String> options) {
709                return asyncApi.createChannel(name, options).getUninterruptibly();
710        }
711
712        /**
713         * Creates a new directory on the file repository in the specified channel.
714         *
715         * @param directoryPath
716         *              the path to the directory that should be created
717         * @param channelId
718         *              the ID of the channel the directory should be created in
719         *
720         * @throws TS3CommandFailedException
721         *              if the execution of a command fails
722         * @querycommands 1
723         * @see FileInfo#getPath()
724         * @see Channel#getId()
725         */
726        public void createFileDirectory(String directoryPath, int channelId) {
727                asyncApi.createFileDirectory(directoryPath, channelId).getUninterruptibly();
728        }
729
730        /**
731         * Creates a new directory on the file repository in the specified channel.
732         *
733         * @param directoryPath
734         *              the path to the directory that should be created
735         * @param channelId
736         *              the ID of the channel the directory should be created in
737         * @param channelPassword
738         *              the password of that channel
739         *
740         * @throws TS3CommandFailedException
741         *              if the execution of a command fails
742         * @querycommands 1
743         * @see FileInfo#getPath()
744         * @see Channel#getId()
745         */
746        public void createFileDirectory(String directoryPath, int channelId, String channelPassword) {
747                asyncApi.createFileDirectory(directoryPath, channelId, channelPassword).getUninterruptibly();
748        }
749
750        /**
751         * Creates a new virtual server with the given name and returns an object containing the ID of the newly
752         * created virtual server, the default server admin token and the virtual server's voice port. Usually,
753         * the virtual server is also automatically started. This can be turned off on the TS3 server, though.
754         * <p>
755         * If {@link VirtualServerProperty#VIRTUALSERVER_PORT} is not specified in the virtual server properties,
756         * the server will test for the first unused UDP port.
757         * </p><p>
758         * Please also note that creating virtual servers usually requires the server query admin account
759         * and that there is a limit to how many virtual servers can be created, which is dependent on your license.
760         * Unlicensed TS3 server instances are limited to 1 virtual server with up to 32 client slots.
761         * </p>
762         *
763         * @param name
764         *              the name for the new virtual server
765         * @param options
766         *              a map of options that should be set for the virtual server
767         *
768         * @return information about the newly created virtual server
769         *
770         * @throws TS3CommandFailedException
771         *              if the execution of a command fails
772         * @querycommands 1
773         * @see VirtualServer
774         */
775        public CreatedVirtualServer createServer(String name, Map<VirtualServerProperty, String> options) {
776                return asyncApi.createServer(name, options).getUninterruptibly();
777        }
778
779        /**
780         * Creates a {@link Snapshot} of the selected virtual server containing all settings,
781         * groups and known client identities. The data from a server snapshot can be
782         * used to restore a virtual servers configuration.
783         *
784         * @return a snapshot of the virtual server
785         *
786         * @throws TS3CommandFailedException
787         *              if the execution of a command fails
788         * @querycommands 1
789         * @see #deployServerSnapshot(Snapshot)
790         */
791        public Snapshot createServerSnapshot() {
792                return asyncApi.createServerSnapshot().getUninterruptibly();
793        }
794
795        /**
796         * Deletes all active ban rules from the server. Use with caution.
797         *
798         * @throws TS3CommandFailedException
799         *              if the execution of a command fails
800         * @querycommands 1
801         */
802        public void deleteAllBans() {
803                asyncApi.deleteAllBans().getUninterruptibly();
804        }
805
806        /**
807         * Deletes all complaints about the client with specified database ID from the server.
808         *
809         * @param clientDBId
810         *              the database ID of the client
811         *
812         * @throws TS3CommandFailedException
813         *              if the execution of a command fails
814         * @querycommands 1
815         * @see Client#getDatabaseId()
816         * @see Complaint
817         */
818        public void deleteAllComplaints(int clientDBId) {
819                asyncApi.deleteAllComplaints(clientDBId).getUninterruptibly();
820        }
821
822        /**
823         * Deletes the ban rule with the specified ID from the server.
824         *
825         * @param banId
826         *              the ID of the ban to delete
827         *
828         * @throws TS3CommandFailedException
829         *              if the execution of a command fails
830         * @querycommands 1
831         * @see Ban#getId()
832         */
833        public void deleteBan(int banId) {
834                asyncApi.deleteBan(banId).getUninterruptibly();
835        }
836
837        /**
838         * Deletes an existing channel specified by its ID, kicking all clients out of the channel.
839         *
840         * @param channelId
841         *              the ID of the channel to delete
842         *
843         * @throws TS3CommandFailedException
844         *              if the execution of a command fails
845         * @querycommands 1
846         * @see Channel#getId()
847         * @see #deleteChannel(int, boolean)
848         * @see #kickClientFromChannel(String, int...)
849         */
850        public void deleteChannel(int channelId) {
851                asyncApi.deleteChannel(channelId).getUninterruptibly();
852        }
853
854        /**
855         * Deletes an existing channel with a given ID.
856         * If {@code force} is true, the channel will be deleted even if there are clients within,
857         * else the command will fail in this situation.
858         *
859         * @param channelId
860         *              the ID of the channel to delete
861         * @param force
862         *              whether clients should be kicked out of the channel
863         *
864         * @throws TS3CommandFailedException
865         *              if the execution of a command fails
866         * @querycommands 1
867         * @see Channel#getId()
868         * @see #kickClientFromChannel(String, int...)
869         */
870        public void deleteChannel(int channelId, boolean force) {
871                asyncApi.deleteChannel(channelId, force).getUninterruptibly();
872        }
873
874        /**
875         * Removes a specified permission from a client in a specific channel.
876         *
877         * @param channelId
878         *              the ID of the channel wherein the permission should be removed
879         * @param clientDBId
880         *              the database ID of the client
881         * @param permName
882         *              the name of the permission to revoke
883         *
884         * @throws TS3CommandFailedException
885         *              if the execution of a command fails
886         * @querycommands 1
887         * @see Channel#getId()
888         * @see Client#getDatabaseId()
889         * @see Permission#getName()
890         */
891        public void deleteChannelClientPermission(int channelId, int clientDBId, String permName) {
892                asyncApi.deleteChannelClientPermission(channelId, clientDBId, permName).getUninterruptibly();
893        }
894
895        /**
896         * Removes the channel group with the given ID.
897         *
898         * @param groupId
899         *              the ID of the channel group
900         *
901         * @throws TS3CommandFailedException
902         *              if the execution of a command fails
903         * @querycommands 1
904         * @see ChannelGroup#getId()
905         */
906        public void deleteChannelGroup(int groupId) {
907                asyncApi.deleteChannelGroup(groupId).getUninterruptibly();
908        }
909
910        /**
911         * Removes the channel group with the given ID.
912         * If {@code force} is true, the channel group will be deleted even if it still contains clients,
913         * else the command will fail in this situation.
914         *
915         * @param groupId
916         *              the ID of the channel group
917         * @param force
918         *              whether the channel group should be deleted even if it still contains clients
919         *
920         * @throws TS3CommandFailedException
921         *              if the execution of a command fails
922         * @querycommands 1
923         * @see ChannelGroup#getId()
924         */
925        public void deleteChannelGroup(int groupId, boolean force) {
926                asyncApi.deleteChannelGroup(groupId, force).getUninterruptibly();
927        }
928
929        /**
930         * Removes a permission from the channel group with the given ID.
931         *
932         * @param groupId
933         *              the ID of the channel group
934         * @param permName
935         *              the name of the permission to revoke
936         *
937         * @throws TS3CommandFailedException
938         *              if the execution of a command fails
939         * @querycommands 1
940         * @see ChannelGroup#getId()
941         * @see Permission#getName()
942         */
943        public void deleteChannelGroupPermission(int groupId, String permName) {
944                asyncApi.deleteChannelGroupPermission(groupId, permName).getUninterruptibly();
945        }
946
947        /**
948         * Removes a permission from the channel with the given ID.
949         *
950         * @param channelId
951         *              the ID of the channel
952         * @param permName
953         *              the name of the permission to revoke
954         *
955         * @throws TS3CommandFailedException
956         *              if the execution of a command fails
957         * @querycommands 1
958         * @see Channel#getId()
959         * @see Permission#getName()
960         */
961        public void deleteChannelPermission(int channelId, String permName) {
962                asyncApi.deleteChannelPermission(channelId, permName).getUninterruptibly();
963        }
964
965        /**
966         * Removes a permission from a client.
967         *
968         * @param clientDBId
969         *              the database ID of the client
970         * @param permName
971         *              the name of the permission to revoke
972         *
973         * @throws TS3CommandFailedException
974         *              if the execution of a command fails
975         * @querycommands 1
976         * @see Client#getDatabaseId()
977         * @see Permission#getName()
978         */
979        public void deleteClientPermission(int clientDBId, String permName) {
980                asyncApi.deleteClientPermission(clientDBId, permName).getUninterruptibly();
981        }
982
983        /**
984         * Deletes the complaint about the client with database ID {@code targetClientDBId} submitted by
985         * the client with database ID {@code fromClientDBId} from the server.
986         *
987         * @param targetClientDBId
988         *              the database ID of the client the complaint is about
989         * @param fromClientDBId
990         *              the database ID of the client who added the complaint
991         *
992         * @throws TS3CommandFailedException
993         *              if the execution of a command fails
994         * @querycommands 1
995         * @see Complaint
996         * @see Client#getDatabaseId()
997         */
998        public void deleteComplaint(int targetClientDBId, int fromClientDBId) {
999                asyncApi.deleteComplaint(targetClientDBId, fromClientDBId).getUninterruptibly();
1000        }
1001
1002        /**
1003         * Removes the {@code key} custom client property from a client.
1004         *
1005         * @param clientDBId
1006         *              the database ID of the target client
1007         * @param key
1008         *              the key of the custom property to delete, cannot be {@code null}
1009         *
1010         * @throws TS3CommandFailedException
1011         *              if the execution of a command fails
1012         * @querycommands 1
1013         * @see Client#getDatabaseId()
1014         */
1015        public void deleteCustomClientProperty(int clientDBId, String key) {
1016                asyncApi.deleteCustomClientProperty(clientDBId, key).getUninterruptibly();
1017        }
1018
1019        /**
1020         * Removes all stored database information about the specified client.
1021         * Please note that this data is also automatically removed after a configured time (usually 90 days).
1022         * <p>
1023         * See {@link DatabaseClientInfo} for a list of stored information about a client.
1024         * </p>
1025         *
1026         * @param clientDBId
1027         *              the database ID of the client
1028         *
1029         * @throws TS3CommandFailedException
1030         *              if the execution of a command fails
1031         * @querycommands 1
1032         * @see Client#getDatabaseId()
1033         * @see #getDatabaseClientInfo(int)
1034         * @see DatabaseClientInfo
1035         */
1036        public void deleteDatabaseClientProperties(int clientDBId) {
1037                asyncApi.deleteDatabaseClientProperties(clientDBId).getUninterruptibly();
1038        }
1039
1040        /**
1041         * Deletes a file or directory from the file repository in the specified channel.
1042         *
1043         * @param filePath
1044         *              the path to the file or directory
1045         * @param channelId
1046         *              the ID of the channel the file or directory resides in
1047         *
1048         * @throws TS3CommandFailedException
1049         *              if the execution of a command fails
1050         * @querycommands 1
1051         * @see FileInfo#getPath()
1052         * @see Channel#getId()
1053         */
1054        public void deleteFile(String filePath, int channelId) {
1055                asyncApi.deleteFile(filePath, channelId).getUninterruptibly();
1056        }
1057
1058        /**
1059         * Deletes a file or directory from the file repository in the specified channel.
1060         *
1061         * @param filePath
1062         *              the path to the file or directory
1063         * @param channelId
1064         *              the ID of the channel the file or directory resides in
1065         * @param channelPassword
1066         *              the password of that channel
1067         *
1068         * @throws TS3CommandFailedException
1069         *              if the execution of a command fails
1070         * @querycommands 1
1071         * @see FileInfo#getPath()
1072         * @see Channel#getId()
1073         */
1074        public void deleteFile(String filePath, int channelId, String channelPassword) {
1075                asyncApi.deleteFile(filePath, channelId, channelPassword).getUninterruptibly();
1076        }
1077
1078        /**
1079         * Deletes multiple files or directories from the file repository in the specified channel.
1080         *
1081         * @param filePaths
1082         *              the paths to the files or directories
1083         * @param channelId
1084         *              the ID of the channel the file or directory resides in
1085         *
1086         * @throws TS3CommandFailedException
1087         *              if the execution of a command fails
1088         * @querycommands 1
1089         * @see FileInfo#getPath()
1090         * @see Channel#getId()
1091         */
1092        public void deleteFiles(String[] filePaths, int channelId) {
1093                asyncApi.deleteFiles(filePaths, channelId).getUninterruptibly();
1094        }
1095
1096        /**
1097         * Deletes multiple files or directories from the file repository in the specified channel.
1098         *
1099         * @param filePaths
1100         *              the paths to the files or directories
1101         * @param channelId
1102         *              the ID of the channel the file or directory resides in
1103         * @param channelPassword
1104         *              the password of that channel
1105         *
1106         * @throws TS3CommandFailedException
1107         *              if the execution of a command fails
1108         * @querycommands 1
1109         * @see FileInfo#getPath()
1110         * @see Channel#getId()
1111         */
1112        public void deleteFiles(String[] filePaths, int channelId, String channelPassword) {
1113                asyncApi.deleteFiles(filePaths, channelId, channelPassword).getUninterruptibly();
1114        }
1115
1116        /**
1117         * Deletes an icon from the icon directory in the file repository.
1118         *
1119         * @param iconId
1120         *              the ID of the icon to delete
1121         *
1122         * @throws TS3CommandFailedException
1123         *              if the execution of a command fails
1124         * @querycommands 1
1125         * @see IconFile#getIconId()
1126         */
1127        public void deleteIcon(long iconId) {
1128                asyncApi.deleteIcon(iconId).getUninterruptibly();
1129        }
1130
1131        /**
1132         * Deletes multiple icons from the icon directory in the file repository.
1133         *
1134         * @param iconIds
1135         *              the IDs of the icons to delete
1136         *
1137         * @throws TS3CommandFailedException
1138         *              if the execution of a command fails
1139         * @querycommands 1
1140         * @see IconFile#getIconId()
1141         */
1142        public void deleteIcons(long... iconIds) {
1143                asyncApi.deleteIcons(iconIds).getUninterruptibly();
1144        }
1145
1146        /**
1147         * Deletes the offline message with the specified ID.
1148         *
1149         * @param messageId
1150         *              the ID of the offline message to delete
1151         *
1152         * @throws TS3CommandFailedException
1153         *              if the execution of a command fails
1154         * @querycommands 1
1155         * @see Message#getId()
1156         */
1157        public void deleteOfflineMessage(int messageId) {
1158                asyncApi.deleteOfflineMessage(messageId).getUninterruptibly();
1159        }
1160
1161        /**
1162         * Removes a specified permission from all server groups of the type specified by {@code type} on all virtual servers.
1163         *
1164         * @param type
1165         *              the kind of server group this permission should be removed from
1166         * @param permName
1167         *              the name of the permission to remove
1168         *
1169         * @throws TS3CommandFailedException
1170         *              if the execution of a command fails
1171         * @querycommands 1
1172         * @see ServerGroupType
1173         * @see Permission#getName()
1174         */
1175        public void deletePermissionFromAllServerGroups(ServerGroupType type, String permName) {
1176                asyncApi.deletePermissionFromAllServerGroups(type, permName).getUninterruptibly();
1177        }
1178
1179        /**
1180         * Deletes the privilege key with the given token.
1181         *
1182         * @param token
1183         *              the token of the privilege key
1184         *
1185         * @throws TS3CommandFailedException
1186         *              if the execution of a command fails
1187         * @querycommands 1
1188         * @see PrivilegeKey
1189         */
1190        public void deletePrivilegeKey(String token) {
1191                asyncApi.deletePrivilegeKey(token).getUninterruptibly();
1192        }
1193
1194        /**
1195         * Deletes the virtual server with the specified ID.
1196         * <p>
1197         * Only stopped virtual servers can be deleted.
1198         * </p>
1199         *
1200         * @param serverId
1201         *              the ID of the virtual server
1202         *
1203         * @throws TS3CommandFailedException
1204         *              if the execution of a command fails
1205         * @querycommands 1
1206         * @see VirtualServer#getId()
1207         * @see #stopServer(int)
1208         */
1209        public void deleteServer(int serverId) {
1210                asyncApi.deleteServer(serverId).getUninterruptibly();
1211        }
1212
1213        /**
1214         * Deletes the server group with the specified ID, even if the server group still contains clients.
1215         *
1216         * @param groupId
1217         *              the ID of the server group
1218         *
1219         * @throws TS3CommandFailedException
1220         *              if the execution of a command fails
1221         * @querycommands 1
1222         * @see ServerGroup#getId()
1223         */
1224        public void deleteServerGroup(int groupId) {
1225                asyncApi.deleteServerGroup(groupId).getUninterruptibly();
1226        }
1227
1228        /**
1229         * Deletes a server group with the specified ID.
1230         * <p>
1231         * If {@code force} is true, the server group will be deleted even if it contains clients,
1232         * else the command will fail in this situation.
1233         * </p>
1234         *
1235         * @param groupId
1236         *              the ID of the server group
1237         * @param force
1238         *              whether the server group should be deleted if it still contains clients
1239         *
1240         * @throws TS3CommandFailedException
1241         *              if the execution of a command fails
1242         * @querycommands 1
1243         * @see ServerGroup#getId()
1244         */
1245        public void deleteServerGroup(int groupId, boolean force) {
1246                asyncApi.deleteServerGroup(groupId, force).getUninterruptibly();
1247        }
1248
1249        /**
1250         * Removes a permission from the server group with the given ID.
1251         *
1252         * @param groupId
1253         *              the ID of the server group
1254         * @param permName
1255         *              the name of the permission to revoke
1256         *
1257         * @throws TS3CommandFailedException
1258         *              if the execution of a command fails
1259         * @querycommands 1
1260         * @see ServerGroup#getId()
1261         * @see Permission#getName()
1262         */
1263        public void deleteServerGroupPermission(int groupId, String permName) {
1264                asyncApi.deleteServerGroupPermission(groupId, permName).getUninterruptibly();
1265        }
1266
1267        /**
1268         * Restores the selected virtual servers configuration using the data from a
1269         * previously created server snapshot.
1270         *
1271         * @param snapshot
1272         *              the snapshot to restore
1273         *
1274         * @throws TS3CommandFailedException
1275         *              if the execution of a command fails
1276         * @querycommands 1
1277         * @see #createServerSnapshot()
1278         */
1279        public void deployServerSnapshot(Snapshot snapshot) {
1280                asyncApi.deployServerSnapshot(snapshot).getUninterruptibly();
1281        }
1282
1283        /**
1284         * Restores the configuration of the selected virtual server using the data from a
1285         * previously created server snapshot.
1286         *
1287         * @param snapshot
1288         *              the snapshot to restore
1289         *
1290         * @throws TS3CommandFailedException
1291         *              if the execution of a command fails
1292         * @querycommands 1
1293         * @see #createServerSnapshot()
1294         */
1295        public void deployServerSnapshot(String snapshot) {
1296                asyncApi.deployServerSnapshot(snapshot).getUninterruptibly();
1297        }
1298
1299        /**
1300         * Downloads a file from the file repository at a given path and channel
1301         * and writes the file's bytes to an open {@link OutputStream}.
1302         * <p>
1303         * It is the user's responsibility to ensure that the given {@code OutputStream} is
1304         * open and to close the stream again once the download has finished.
1305         * </p><p>
1306         * Note that this method will not read the entire file to memory and can thus
1307         * download arbitrarily sized files from the file repository.
1308         * </p>
1309         *
1310         * @param dataOut
1311         *              a stream that the downloaded data should be written to
1312         * @param filePath
1313         *              the path of the file on the file repository
1314         * @param channelId
1315         *              the ID of the channel to download the file from
1316         *
1317         * @return how many bytes were downloaded
1318         *
1319         * @throws TS3CommandFailedException
1320         *              if the execution of a command fails
1321         * @throws TS3FileTransferFailedException
1322         *              if the file transfer fails for any reason
1323         * @querycommands 1
1324         * @see FileInfo#getPath()
1325         * @see Channel#getId()
1326         * @see #downloadFileDirect(String, int)
1327         */
1328        public long downloadFile(OutputStream dataOut, String filePath, int channelId) {
1329                return asyncApi.downloadFile(dataOut, filePath, channelId).getUninterruptibly();
1330        }
1331
1332        /**
1333         * Downloads a file from the file repository at a given path and channel
1334         * and writes the file's bytes to an open {@link OutputStream}.
1335         * <p>
1336         * It is the user's responsibility to ensure that the given {@code OutputStream} is
1337         * open and to close the stream again once the download has finished.
1338         * </p><p>
1339         * Note that this method will not read the entire file to memory and can thus
1340         * download arbitrarily sized files from the file repository.
1341         * </p>
1342         *
1343         * @param dataOut
1344         *              a stream that the downloaded data should be written to
1345         * @param filePath
1346         *              the path of the file on the file repository
1347         * @param channelId
1348         *              the ID of the channel to download the file from
1349         * @param channelPassword
1350         *              that channel's password
1351         *
1352         * @return how many bytes were downloaded
1353         *
1354         * @throws TS3CommandFailedException
1355         *              if the execution of a command fails
1356         * @throws TS3FileTransferFailedException
1357         *              if the file transfer fails for any reason
1358         * @querycommands 1
1359         * @see FileInfo#getPath()
1360         * @see Channel#getId()
1361         * @see #downloadFileDirect(String, int, String)
1362         */
1363        public long downloadFile(OutputStream dataOut, String filePath, int channelId, String channelPassword) {
1364                return asyncApi.downloadFile(dataOut, filePath, channelId, channelPassword).getUninterruptibly();
1365        }
1366
1367        /**
1368         * Downloads a file from the file repository at a given path and channel
1369         * and returns the file's bytes as a byte array.
1370         * <p>
1371         * Note that this method <strong>will read the entire file to memory</strong>.
1372         * That means that if a file is larger than 2<sup>31</sup>-1 bytes in size,
1373         * the download will fail.
1374         * </p>
1375         *
1376         * @param filePath
1377         *              the path of the file on the file repository
1378         * @param channelId
1379         *              the ID of the channel to download the file from
1380         *
1381         * @return a byte array containing the file's data
1382         *
1383         * @throws TS3CommandFailedException
1384         *              if the execution of a command fails
1385         * @throws TS3FileTransferFailedException
1386         *              if the file transfer fails for any reason
1387         * @querycommands 1
1388         * @see FileInfo#getPath()
1389         * @see Channel#getId()
1390         * @see #downloadFile(OutputStream, String, int)
1391         */
1392        public byte[] downloadFileDirect(String filePath, int channelId) {
1393                return asyncApi.downloadFileDirect(filePath, channelId).getUninterruptibly();
1394        }
1395
1396        /**
1397         * Downloads a file from the file repository at a given path and channel
1398         * and returns the file's bytes as a byte array.
1399         * <p>
1400         * Note that this method <strong>will read the entire file to memory</strong>.
1401         * That means that if a file is larger than 2<sup>31</sup>-1 bytes in size,
1402         * the download will fail.
1403         * </p>
1404         *
1405         * @param filePath
1406         *              the path of the file on the file repository
1407         * @param channelId
1408         *              the ID of the channel to download the file from
1409         * @param channelPassword
1410         *              that channel's password
1411         *
1412         * @return a byte array containing the file's data
1413         *
1414         * @throws TS3CommandFailedException
1415         *              if the execution of a command fails
1416         * @throws TS3FileTransferFailedException
1417         *              if the file transfer fails for any reason
1418         * @querycommands 1
1419         * @see FileInfo#getPath()
1420         * @see Channel#getId()
1421         * @see #downloadFile(OutputStream, String, int, String)
1422         */
1423        public byte[] downloadFileDirect(String filePath, int channelId, String channelPassword) {
1424                return asyncApi.downloadFileDirect(filePath, channelId, channelPassword).getUninterruptibly();
1425        }
1426
1427        /**
1428         * Downloads an icon from the icon directory in the file repository
1429         * and writes the file's bytes to an open {@link OutputStream}.
1430         * <p>
1431         * It is the user's responsibility to ensure that the given {@code OutputStream} is
1432         * open and to close the stream again once the download has finished.
1433         * </p>
1434         *
1435         * @param dataOut
1436         *              a stream that the downloaded data should be written to
1437         * @param iconId
1438         *              the ID of the icon that should be downloaded
1439         *
1440         * @return a byte array containing the icon file's data
1441         *
1442         * @throws TS3CommandFailedException
1443         *              if the execution of a command fails
1444         * @throws TS3FileTransferFailedException
1445         *              if the file transfer fails for any reason
1446         * @querycommands 1
1447         * @see IconFile#getIconId()
1448         * @see #downloadIconDirect(long)
1449         * @see #uploadIcon(InputStream, long)
1450         */
1451        public long downloadIcon(OutputStream dataOut, long iconId) {
1452                return asyncApi.downloadIcon(dataOut, iconId).getUninterruptibly();
1453        }
1454
1455        /**
1456         * Downloads an icon from the icon directory in the file repository
1457         * and returns the file's bytes as a byte array.
1458         * <p>
1459         * Note that this method <strong>will read the entire file to memory</strong>.
1460         * </p>
1461         *
1462         * @param iconId
1463         *              the ID of the icon that should be downloaded
1464         *
1465         * @return a byte array containing the icon file's data
1466         *
1467         * @throws TS3CommandFailedException
1468         *              if the execution of a command fails
1469         * @throws TS3FileTransferFailedException
1470         *              if the file transfer fails for any reason
1471         * @querycommands 1
1472         * @see IconFile#getIconId()
1473         * @see #downloadIcon(OutputStream, long)
1474         * @see #uploadIconDirect(byte[])
1475         */
1476        public byte[] downloadIconDirect(long iconId) {
1477                return asyncApi.downloadIconDirect(iconId).getUninterruptibly();
1478        }
1479
1480        /**
1481         * Changes a channel's configuration using the given properties.
1482         *
1483         * @param channelId
1484         *              the ID of the channel to edit
1485         * @param options
1486         *              the map of properties to modify
1487         *
1488         * @throws TS3CommandFailedException
1489         *              if the execution of a command fails
1490         * @querycommands 1
1491         * @see Channel#getId()
1492         */
1493        public void editChannel(int channelId, Map<ChannelProperty, String> options) {
1494                asyncApi.editChannel(channelId, options).getUninterruptibly();
1495        }
1496
1497        /**
1498         * Changes a single property of the given channel.
1499         * <p>
1500         * Note that one can set many properties at once with the overloaded method that
1501         * takes a map of channel properties and strings.
1502         * </p>
1503         *
1504         * @param channelId
1505         *              the ID of the channel to edit
1506         * @param property
1507         *              the channel property to modify, make sure it is editable
1508         * @param value
1509         *              the new value of the property
1510         *
1511         * @throws TS3CommandFailedException
1512         *              if the execution of a command fails
1513         * @querycommands 1
1514         * @see Channel#getId()
1515         * @see #editChannel(int, Map)
1516         */
1517        public void editChannel(int channelId, ChannelProperty property, String value) {
1518                asyncApi.editChannel(channelId, property, value).getUninterruptibly();
1519        }
1520
1521        /**
1522         * Changes a client's configuration using given properties.
1523         * <p>
1524         * Only {@link ClientProperty#CLIENT_DESCRIPTION} can be changed for other clients.
1525         * To update the current client's properties, use {@link #updateClient(Map)}
1526         * or {@link #updateClient(ClientProperty, String)}.
1527         * </p>
1528         *
1529         * @param clientId
1530         *              the ID of the client to edit
1531         * @param options
1532         *              the map of properties to modify
1533         *
1534         * @throws TS3CommandFailedException
1535         *              if the execution of a command fails
1536         * @querycommands 1
1537         * @see Client#getId()
1538         * @see #updateClient(Map)
1539         */
1540        public void editClient(int clientId, Map<ClientProperty, String> options) {
1541                asyncApi.editClient(clientId, options).getUninterruptibly();
1542        }
1543
1544        /**
1545         * Changes a single property of the given client.
1546         * <p>
1547         * Only {@link ClientProperty#CLIENT_DESCRIPTION} can be changed for other clients.
1548         * To update the current client's properties, use {@link #updateClient(Map)}
1549         * or {@link #updateClient(ClientProperty, String)}.
1550         * </p>
1551         *
1552         * @param clientId
1553         *              the ID of the client to edit
1554         * @param property
1555         *              the client property to modify, make sure it is editable
1556         * @param value
1557         *              the new value of the property
1558         *
1559         * @throws TS3CommandFailedException
1560         *              if the execution of a command fails
1561         * @querycommands 1
1562         * @see Client#getId()
1563         * @see #editClient(int, Map)
1564         * @see #updateClient(Map)
1565         */
1566        public void editClient(int clientId, ClientProperty property, String value) {
1567                asyncApi.editClient(clientId, property, value).getUninterruptibly();
1568        }
1569
1570        /**
1571         * Changes a client's database settings using given properties.
1572         *
1573         * @param clientDBId
1574         *              the database ID of the client to edit
1575         * @param options
1576         *              the map of properties to modify
1577         *
1578         * @throws TS3CommandFailedException
1579         *              if the execution of a command fails
1580         * @querycommands 1
1581         * @see DatabaseClientInfo
1582         * @see Client#getDatabaseId()
1583         */
1584        public void editDatabaseClient(int clientDBId, Map<ClientProperty, String> options) {
1585                asyncApi.editDatabaseClient(clientDBId, options).getUninterruptibly();
1586        }
1587
1588        /**
1589         * Changes the server instance configuration using given properties.
1590         * If the given property is not changeable, {@code IllegalArgumentException} will be thrown.
1591         *
1592         * @param property
1593         *              the property to edit, must be changeable
1594         * @param value
1595         *              the new value for the edit
1596         *
1597         * @throws IllegalArgumentException
1598         *              if {@code property} is not changeable
1599         * @throws TS3CommandFailedException
1600         *              if the execution of a command fails
1601         * @querycommands 1
1602         * @see ServerInstanceProperty#isChangeable()
1603         */
1604        public void editInstance(ServerInstanceProperty property, String value) {
1605                asyncApi.editInstance(property, value).getUninterruptibly();
1606        }
1607
1608        /**
1609         * Changes the configuration of the selected virtual server using given properties.
1610         *
1611         * @param options
1612         *              the map of properties to edit
1613         *
1614         * @throws TS3CommandFailedException
1615         *              if the execution of a command fails
1616         * @querycommands 1
1617         * @see VirtualServerProperty
1618         */
1619        public void editServer(Map<VirtualServerProperty, String> options) {
1620                asyncApi.editServer(options).getUninterruptibly();
1621        }
1622
1623        /**
1624         * Gets a list of all bans on the selected virtual server.
1625         *
1626         * @return a list of all bans on the virtual server
1627         *
1628         * @throws TS3CommandFailedException
1629         *              if the execution of a command fails
1630         * @querycommands 1
1631         * @see Ban
1632         */
1633        public List<Ban> getBans() {
1634                return asyncApi.getBans().getUninterruptibly();
1635        }
1636
1637        /**
1638         * Gets a list of IP addresses used by the server instance.
1639         *
1640         * @return the list of bound IP addresses
1641         *
1642         * @throws TS3CommandFailedException
1643         *              if the execution of a command fails
1644         * @querycommands 1
1645         * @see Binding
1646         */
1647        public List<Binding> getBindings() {
1648                return asyncApi.getBindings().getUninterruptibly();
1649        }
1650
1651        /**
1652         * Finds and returns the channel matching the given name exactly.
1653         *
1654         * @param name
1655         *              the name of the channel
1656         * @param ignoreCase
1657         *              whether the case of the name should be ignored
1658         *
1659         * @return the found channel or {@code null} if no channel was found
1660         *
1661         * @throws TS3CommandFailedException
1662         *              if the execution of a command fails
1663         * @querycommands 1
1664         * @see Channel
1665         * @see #getChannelsByName(String)
1666         */
1667        public Channel getChannelByNameExact(String name, boolean ignoreCase) {
1668                return asyncApi.getChannelByNameExact(name, ignoreCase).getUninterruptibly();
1669        }
1670
1671        /**
1672         * Gets a list of channels whose names contain the given search string.
1673         *
1674         * @param name
1675         *              the name to search
1676         *
1677         * @return a list of all channels with names matching the search pattern
1678         *
1679         * @throws TS3CommandFailedException
1680         *              if the execution of a command fails
1681         * @querycommands 2
1682         * @see Channel
1683         * @see #getChannelByNameExact(String, boolean)
1684         */
1685        public List<Channel> getChannelsByName(String name) {
1686                return asyncApi.getChannelsByName(name).getUninterruptibly();
1687        }
1688
1689        /**
1690         * Displays a list of permissions defined for a client in a specific channel.
1691         *
1692         * @param channelId
1693         *              the ID of the channel
1694         * @param clientDBId
1695         *              the database ID of the client
1696         *
1697         * @return a list of permissions for the user in the specified channel
1698         *
1699         * @throws TS3CommandFailedException
1700         *              if the execution of a command fails
1701         * @querycommands 1
1702         * @see Channel#getId()
1703         * @see Client#getDatabaseId()
1704         * @see Permission
1705         */
1706        public List<Permission> getChannelClientPermissions(int channelId, int clientDBId) {
1707                return asyncApi.getChannelClientPermissions(channelId, clientDBId).getUninterruptibly();
1708        }
1709
1710        /**
1711         * Gets all client / channel ID combinations currently assigned to channel groups.
1712         * All three parameters are optional and can be turned off by setting it to {@code -1}.
1713         *
1714         * @param channelId
1715         *              restricts the search to the channel with a specified ID. Set to {@code -1} to ignore.
1716         * @param clientDBId
1717         *              restricts the search to the client with a specified database ID. Set to {@code -1} to ignore.
1718         * @param groupId
1719         *              restricts the search to the channel group with the specified ID. Set to {@code -1} to ignore.
1720         *
1721         * @return a list of combinations of channel ID, client database ID and channel group ID
1722         *
1723         * @throws TS3CommandFailedException
1724         *              if the execution of a command fails
1725         * @querycommands 1
1726         * @see Channel#getId()
1727         * @see Client#getDatabaseId()
1728         * @see ChannelGroup#getId()
1729         * @see ChannelGroupClient
1730         */
1731        public List<ChannelGroupClient> getChannelGroupClients(int channelId, int clientDBId, int groupId) {
1732                return asyncApi.getChannelGroupClients(channelId, clientDBId, groupId).getUninterruptibly();
1733        }
1734
1735        /**
1736         * Gets all client / channel ID combinations currently assigned to the specified channel group.
1737         *
1738         * @param groupId
1739         *              the ID of the channel group whose client / channel assignments should be returned.
1740         *
1741         * @return a list of combinations of channel ID, client database ID and channel group ID
1742         *
1743         * @throws TS3CommandFailedException
1744         *              if the execution of a command fails
1745         * @querycommands 1
1746         * @see ChannelGroup#getId()
1747         * @see ChannelGroupClient
1748         * @see #getChannelGroupClients(int, int, int)
1749         */
1750        public List<ChannelGroupClient> getChannelGroupClientsByChannelGroupId(int groupId) {
1751                return asyncApi.getChannelGroupClientsByChannelGroupId(groupId).getUninterruptibly();
1752        }
1753
1754        /**
1755         * Gets all channel group assignments in the specified channel.
1756         *
1757         * @param channelId
1758         *              the ID of the channel whose channel group assignments should be returned.
1759         *
1760         * @return a list of combinations of channel ID, client database ID and channel group ID
1761         *
1762         * @throws TS3CommandFailedException
1763         *              if the execution of a command fails
1764         * @querycommands 1
1765         * @see Channel#getId()
1766         * @see ChannelGroupClient
1767         * @see #getChannelGroupClients(int, int, int)
1768         */
1769        public List<ChannelGroupClient> getChannelGroupClientsByChannelId(int channelId) {
1770                return asyncApi.getChannelGroupClientsByChannelId(channelId).getUninterruptibly();
1771        }
1772
1773        /**
1774         * Gets all channel group assignments for the specified client.
1775         *
1776         * @param clientDBId
1777         *              the database ID of the client whose channel group
1778         *
1779         * @return a list of combinations of channel ID, client database ID and channel group ID
1780         *
1781         * @throws TS3CommandFailedException
1782         *              if the execution of a command fails
1783         * @querycommands 1
1784         * @see Client#getDatabaseId()
1785         * @see ChannelGroupClient
1786         * @see #getChannelGroupClients(int, int, int)
1787         */
1788        public List<ChannelGroupClient> getChannelGroupClientsByClientDBId(int clientDBId) {
1789                return asyncApi.getChannelGroupClientsByClientDBId(clientDBId).getUninterruptibly();
1790        }
1791
1792        /**
1793         * Gets a list of all permissions assigned to the specified channel group.
1794         *
1795         * @param groupId
1796         *              the ID of the channel group.
1797         *
1798         * @return a list of permissions assigned to the channel group
1799         *
1800         * @throws TS3CommandFailedException
1801         *              if the execution of a command fails
1802         * @querycommands 1
1803         * @see ChannelGroup#getId()
1804         * @see Permission
1805         */
1806        public List<Permission> getChannelGroupPermissions(int groupId) {
1807                return asyncApi.getChannelGroupPermissions(groupId).getUninterruptibly();
1808        }
1809
1810        /**
1811         * Gets a list of all channel groups on the selected virtual server.
1812         *
1813         * @return a list of all channel groups on the virtual server
1814         *
1815         * @throws TS3CommandFailedException
1816         *              if the execution of a command fails
1817         * @querycommands 1
1818         * @see ChannelGroup
1819         */
1820        public List<ChannelGroup> getChannelGroups() {
1821                return asyncApi.getChannelGroups().getUninterruptibly();
1822        }
1823
1824        /**
1825         * Gets detailed configuration information about the channel specified channel.
1826         *
1827         * @param channelId
1828         *              the ID of the channel
1829         *
1830         * @return information about the channel
1831         *
1832         * @throws TS3CommandFailedException
1833         *              if the execution of a command fails
1834         * @querycommands 1
1835         * @see Channel#getId()
1836         * @see ChannelInfo
1837         */
1838        public ChannelInfo getChannelInfo(int channelId) {
1839                return asyncApi.getChannelInfo(channelId).getUninterruptibly();
1840        }
1841
1842        /**
1843         * Gets a list of all permissions assigned to the specified channel.
1844         *
1845         * @param channelId
1846         *              the ID of the channel
1847         *
1848         * @return a list of all permissions assigned to the channel
1849         *
1850         * @throws TS3CommandFailedException
1851         *              if the execution of a command fails
1852         * @querycommands 1
1853         * @see Channel#getId()
1854         * @see Permission
1855         */
1856        public List<Permission> getChannelPermissions(int channelId) {
1857                return asyncApi.getChannelPermissions(channelId).getUninterruptibly();
1858        }
1859
1860        /**
1861         * Gets a list of all channels on the selected virtual server.
1862         *
1863         * @return a list of all channels on the virtual server
1864         *
1865         * @throws TS3CommandFailedException
1866         *              if the execution of a command fails
1867         * @querycommands 1
1868         * @see Channel
1869         */
1870        public List<Channel> getChannels() {
1871                return asyncApi.getChannels().getUninterruptibly();
1872        }
1873
1874        /**
1875         * Finds and returns the client whose nickname matches the given name exactly.
1876         *
1877         * @param name
1878         *              the name of the client
1879         * @param ignoreCase
1880         *              whether the case of the name should be ignored
1881         *
1882         * @return the found client or {@code null} if no client was found
1883         *
1884         * @throws TS3CommandFailedException
1885         *              if the execution of a command fails
1886         * @querycommands 1
1887         * @see Client
1888         * @see #getClientsByName(String)
1889         */
1890        public Client getClientByNameExact(String name, boolean ignoreCase) {
1891                return asyncApi.getClientByNameExact(name, ignoreCase).getUninterruptibly();
1892        }
1893
1894        /**
1895         * Gets a list of clients whose nicknames contain the given search string.
1896         *
1897         * @param name
1898         *              the name to search
1899         *
1900         * @return a list of all clients with nicknames matching the search pattern
1901         *
1902         * @throws TS3CommandFailedException
1903         *              if the execution of a command fails
1904         * @querycommands 2
1905         * @see Client
1906         * @see #getClientByNameExact(String, boolean)
1907         */
1908        public List<Client> getClientsByName(String name) {
1909                return asyncApi.getClientsByName(name).getUninterruptibly();
1910        }
1911
1912        /**
1913         * Gets information about the client with the specified unique identifier.
1914         *
1915         * @param clientUId
1916         *              the unique identifier of the client
1917         *
1918         * @return information about the client
1919         *
1920         * @throws TS3CommandFailedException
1921         *              if the execution of a command fails
1922         * @querycommands 2
1923         * @see Client#getUniqueIdentifier()
1924         * @see ClientInfo
1925         */
1926        public ClientInfo getClientByUId(String clientUId) {
1927                return asyncApi.getClientByUId(clientUId).getUninterruptibly();
1928        }
1929
1930        /**
1931         * Gets information about the client with the specified client ID.
1932         *
1933         * @param clientId
1934         *              the client ID of the client
1935         *
1936         * @return information about the client
1937         *
1938         * @throws TS3CommandFailedException
1939         *              if the execution of a command fails
1940         * @querycommands 1
1941         * @see Client#getId()
1942         * @see ClientInfo
1943         */
1944        public ClientInfo getClientInfo(int clientId) {
1945                return asyncApi.getClientInfo(clientId).getUninterruptibly();
1946        }
1947
1948        /**
1949         * Gets a list of all permissions assigned to the specified client.
1950         *
1951         * @param clientDBId
1952         *              the database ID of the client
1953         *
1954         * @return a list of all permissions assigned to the client
1955         *
1956         * @throws TS3CommandFailedException
1957         *              if the execution of a command fails
1958         * @querycommands 1
1959         * @see Client#getDatabaseId()
1960         * @see Permission
1961         */
1962        public List<Permission> getClientPermissions(int clientDBId) {
1963                return asyncApi.getClientPermissions(clientDBId).getUninterruptibly();
1964        }
1965
1966        /**
1967         * Gets a list of all clients on the selected virtual server.
1968         *
1969         * @return a list of all clients on the virtual server
1970         *
1971         * @throws TS3CommandFailedException
1972         *              if the execution of a command fails
1973         * @querycommands 1
1974         * @see Client
1975         */
1976        public List<Client> getClients() {
1977                return asyncApi.getClients().getUninterruptibly();
1978        }
1979
1980        /**
1981         * Gets a list of all complaints on the selected virtual server.
1982         *
1983         * @return a list of all complaints on the virtual server
1984         *
1985         * @throws TS3CommandFailedException
1986         *              if the execution of a command fails
1987         * @querycommands 1
1988         * @see Complaint
1989         * @see #getComplaints(int)
1990         */
1991        public List<Complaint> getComplaints() {
1992                return asyncApi.getComplaints().getUninterruptibly();
1993        }
1994
1995        /**
1996         * Gets a list of all complaints about the specified client.
1997         *
1998         * @param clientDBId
1999         *              the database ID of the client
2000         *
2001         * @return a list of all complaints about the specified client
2002         *
2003         * @throws TS3CommandFailedException
2004         *              if the execution of a command fails
2005         * @querycommands 1
2006         * @see Client#getDatabaseId()
2007         * @see Complaint
2008         */
2009        public List<Complaint> getComplaints(int clientDBId) {
2010                return asyncApi.getComplaints(clientDBId).getUninterruptibly();
2011        }
2012
2013        /**
2014         * Gets detailed connection information about the selected virtual server.
2015         *
2016         * @return connection information about the selected virtual server
2017         *
2018         * @throws TS3CommandFailedException
2019         *              if the execution of a command fails
2020         * @querycommands 1
2021         * @see ConnectionInfo
2022         * @see #getServerInfo()
2023         */
2024        public ConnectionInfo getConnectionInfo() {
2025                return asyncApi.getConnectionInfo().getUninterruptibly();
2026        }
2027
2028        /**
2029         * Gets a map of all custom client properties and their values
2030         * assigned to the client with database ID {@code clientDBId}.
2031         *
2032         * @param clientDBId
2033         *              the database ID of the target client
2034         *
2035         * @return a map of the client's custom client property assignments
2036         *
2037         * @throws TS3CommandFailedException
2038         *              if the execution of a command fails
2039         * @querycommands 1
2040         * @see Client#getDatabaseId()
2041         * @see #searchCustomClientProperty(String)
2042         * @see #searchCustomClientProperty(String, String)
2043         */
2044        public Map<String, String> getCustomClientProperties(int clientDBId) {
2045                return asyncApi.getCustomClientProperties(clientDBId).getUninterruptibly();
2046        }
2047
2048        /**
2049         * Gets all clients in the database whose last nickname matches the specified name <b>exactly</b>.
2050         *
2051         * @param name
2052         *              the nickname for the clients to match
2053         *
2054         * @return a list of all clients with a matching nickname
2055         *
2056         * @throws TS3CommandFailedException
2057         *              if the execution of a command fails
2058         * @querycommands 1 + n,
2059         * where n is the amount of database clients with a matching nickname
2060         * @see Client#getNickname()
2061         */
2062        public List<DatabaseClientInfo> getDatabaseClientsByName(String name) {
2063                return asyncApi.getDatabaseClientsByName(name).getUninterruptibly();
2064        }
2065
2066        /**
2067         * Gets information about the client with the specified unique identifier in the server database.
2068         *
2069         * @param clientUId
2070         *              the unique identifier of the client
2071         *
2072         * @return the database client or {@code null} if no client was found
2073         *
2074         * @throws TS3CommandFailedException
2075         *              if the execution of a command fails
2076         * @querycommands 2
2077         * @see Client#getUniqueIdentifier()
2078         * @see DatabaseClientInfo
2079         */
2080        public DatabaseClientInfo getDatabaseClientByUId(String clientUId) {
2081                return asyncApi.getDatabaseClientByUId(clientUId).getUninterruptibly();
2082        }
2083
2084        /**
2085         * Gets information about the client with the specified database ID in the server database.
2086         *
2087         * @param clientDBId
2088         *              the database ID of the client
2089         *
2090         * @return the database client or {@code null} if no client was found
2091         *
2092         * @throws TS3CommandFailedException
2093         *              if the execution of a command fails
2094         * @querycommands 1
2095         * @see Client#getDatabaseId()
2096         * @see DatabaseClientInfo
2097         */
2098        public DatabaseClientInfo getDatabaseClientInfo(int clientDBId) {
2099                return asyncApi.getDatabaseClientInfo(clientDBId).getUninterruptibly();
2100        }
2101
2102        /**
2103         * Gets information about all clients in the server database.
2104         * <p>
2105         * As this method uses internal commands which can only return 200 clients at once,
2106         * this method can take quite some time to execute.
2107         * </p><p>
2108         * Also keep in mind that the client database can easily accumulate several thousand entries.
2109         * </p>
2110         *
2111         * @return a {@link List} of all database clients
2112         *
2113         * @throws TS3CommandFailedException
2114         *              if the execution of a command fails
2115         * @querycommands 1 + n,
2116         * where n = Math.ceil([amount of database clients] / 200)
2117         * @see DatabaseClient
2118         */
2119        public List<DatabaseClient> getDatabaseClients() {
2120                return asyncApi.getDatabaseClients().getUninterruptibly();
2121        }
2122
2123        /**
2124         * Gets information about a set number of clients in the server database, starting at {@code offset}.
2125         *
2126         * @param offset
2127         *              the index of the first database client to be returned.
2128         *              Note that this is <b>not</b> a database ID, but an arbitrary, 0-based index.
2129         * @param count
2130         *              the number of database clients that should be returned.
2131         *              Any integer greater than 200 might cause problems with the connection
2132         *
2133         * @return a {@link List} of database clients
2134         *
2135         * @throws TS3CommandFailedException
2136         *              if the execution of a command fails
2137         * @querycommands 1
2138         * @see DatabaseClient
2139         */
2140        public List<DatabaseClient> getDatabaseClients(int offset, int count) {
2141                return asyncApi.getDatabaseClients(offset, count).getUninterruptibly();
2142        }
2143
2144        /**
2145         * Gets information about a file on the file repository in the specified channel.
2146         * <p>
2147         * Note that this method does not work on directories and the information returned by this
2148         * method is identical to the one returned by {@link #getFileList(String, int, String)}
2149         * </p>
2150         *
2151         * @param filePath
2152         *              the path to the file
2153         * @param channelId
2154         *              the ID of the channel the file resides in
2155         *
2156         * @return some information about the file
2157         *
2158         * @throws TS3CommandFailedException
2159         *              if the execution of a command fails
2160         * @querycommands 1
2161         * @see FileInfo#getPath()
2162         * @see Channel#getId()
2163         */
2164        public FileInfo getFileInfo(String filePath, int channelId) {
2165                return asyncApi.getFileInfo(filePath, channelId).getUninterruptibly();
2166        }
2167
2168        /**
2169         * Gets information about a file on the file repository in the specified channel.
2170         * <p>
2171         * Note that this method does not work on directories and the information returned by this
2172         * method is identical to the one returned by {@link #getFileList(String, int, String)}
2173         * </p>
2174         *
2175         * @param filePath
2176         *              the path to the file
2177         * @param channelId
2178         *              the ID of the channel the file resides in
2179         * @param channelPassword
2180         *              the password of that channel
2181         *
2182         * @return some information about the file
2183         *
2184         * @throws TS3CommandFailedException
2185         *              if the execution of a command fails
2186         * @querycommands 1
2187         * @see FileInfo#getPath()
2188         * @see Channel#getId()
2189         */
2190        public FileInfo getFileInfo(String filePath, int channelId, String channelPassword) {
2191                return asyncApi.getFileInfo(filePath, channelId, channelPassword).getUninterruptibly();
2192        }
2193
2194        /**
2195         * Gets information about multiple files on the file repository in the specified channel.
2196         * <p>
2197         * Note that this method does not work on directories and the information returned by this
2198         * method is identical to the one returned by {@link #getFileList(String, int, String)}
2199         * </p>
2200         *
2201         * @param filePaths
2202         *              the paths to the files
2203         * @param channelId
2204         *              the ID of the channel the file resides in
2205         *
2206         * @return some information about the file
2207         *
2208         * @throws TS3CommandFailedException
2209         *              if the execution of a command fails
2210         * @querycommands 1
2211         * @see FileInfo#getPath()
2212         * @see Channel#getId()
2213         */
2214        public List<FileInfo> getFileInfos(String[] filePaths, int channelId) {
2215                return asyncApi.getFileInfos(filePaths, channelId).getUninterruptibly();
2216        }
2217
2218        /**
2219         * Gets information about multiple files on the file repository in the specified channel.
2220         * <p>
2221         * Note that this method does not work on directories and the information returned by this
2222         * method is identical to the one returned by {@link #getFileList(String, int, String)}
2223         * </p>
2224         *
2225         * @param filePaths
2226         *              the paths to the files
2227         * @param channelId
2228         *              the ID of the channel the file resides in
2229         * @param channelPassword
2230         *              the password of that channel
2231         *
2232         * @return some information about the file
2233         *
2234         * @throws TS3CommandFailedException
2235         *              if the execution of a command fails
2236         * @querycommands 1
2237         * @see FileInfo#getPath()
2238         * @see Channel#getId()
2239         */
2240        public List<FileInfo> getFileInfos(String[] filePaths, int channelId, String channelPassword) {
2241                return asyncApi.getFileInfos(filePaths, channelId, channelPassword).getUninterruptibly();
2242        }
2243
2244        /**
2245         * Gets information about multiple files on the file repository in multiple channels.
2246         * <p>
2247         * Note that this method does not work on directories and the information returned by this
2248         * method is identical to the one returned by {@link #getFileList(String, int, String)}
2249         * </p>
2250         *
2251         * @param filePaths
2252         *              the paths to the files, may not be {@code null} and may not contain {@code null} elements
2253         * @param channelIds
2254         *              the IDs of the channels the file resides in, may not be {@code null}
2255         * @param channelPasswords
2256         *              the passwords of those channels, may be {@code null} and may contain {@code null} elements
2257         *
2258         * @return some information about the files
2259         *
2260         * @throws IllegalArgumentException
2261         *              if the dimensions of {@code filePaths}, {@code channelIds} and {@code channelPasswords} don't match
2262         * @throws TS3CommandFailedException
2263         *              if the execution of a command fails
2264         * @querycommands 1
2265         * @see FileInfo#getPath()
2266         * @see Channel#getId()
2267         */
2268        public List<FileInfo> getFileInfos(String[] filePaths, int[] channelIds, String[] channelPasswords) {
2269                return asyncApi.getFileInfos(filePaths, channelIds, channelPasswords).getUninterruptibly();
2270        }
2271
2272        /**
2273         * Gets a list of files and directories in the specified parent directory and channel.
2274         *
2275         * @param directoryPath
2276         *              the path to the parent directory
2277         * @param channelId
2278         *              the ID of the channel the directory resides in
2279         *
2280         * @return the files and directories in the parent directory
2281         *
2282         * @throws TS3CommandFailedException
2283         *              if the execution of a command fails
2284         * @querycommands 1
2285         * @see FileInfo#getPath()
2286         * @see Channel#getId()
2287         */
2288        public List<FileListEntry> getFileList(String directoryPath, int channelId) {
2289                return asyncApi.getFileList(directoryPath, channelId).getUninterruptibly();
2290        }
2291
2292        /**
2293         * Gets a list of files and directories in the specified parent directory and channel.
2294         *
2295         * @param directoryPath
2296         *              the path to the parent directory
2297         * @param channelId
2298         *              the ID of the channel the directory resides in
2299         * @param channelPassword
2300         *              the password of that channel
2301         *
2302         * @return the files and directories in the parent directory
2303         *
2304         * @throws TS3CommandFailedException
2305         *              if the execution of a command fails
2306         * @querycommands 1
2307         * @see FileInfo#getPath()
2308         * @see Channel#getId()
2309         */
2310        public List<FileListEntry> getFileList(String directoryPath, int channelId, String channelPassword) {
2311                return asyncApi.getFileList(directoryPath, channelId, channelPassword).getUninterruptibly();
2312        }
2313
2314        /**
2315         * Gets a list of active or recently active file transfers.
2316         *
2317         * @return a list of file transfers
2318         *
2319         * @throws TS3CommandFailedException
2320         *              if the execution of a command fails
2321         * @querycommands 1
2322         */
2323        public List<FileTransfer> getFileTransfers() {
2324                return asyncApi.getFileTransfers().getUninterruptibly();
2325        }
2326
2327        /**
2328         * Displays detailed configuration information about the server instance including
2329         * uptime, number of virtual servers online, traffic information, etc.
2330         *
2331         * @return information about the host
2332         *
2333         * @throws TS3CommandFailedException
2334         *              if the execution of a command fails
2335         * @querycommands 1
2336         */
2337        public HostInfo getHostInfo() {
2338                return asyncApi.getHostInfo().getUninterruptibly();
2339        }
2340
2341        /**
2342         * Gets a list of all icon files on this virtual server.
2343         *
2344         * @return a list of all icons
2345         */
2346        public List<IconFile> getIconList() {
2347                return asyncApi.getIconList().getUninterruptibly();
2348        }
2349
2350        /**
2351         * Displays the server instance configuration including database revision number,
2352         * the file transfer port, default group IDs, etc.
2353         *
2354         * @return information about the TeamSpeak server instance.
2355         *
2356         * @throws TS3CommandFailedException
2357         *              if the execution of a command fails
2358         * @querycommands 1
2359         */
2360        public InstanceInfo getInstanceInfo() {
2361                return asyncApi.getInstanceInfo().getUninterruptibly();
2362        }
2363
2364        /**
2365         * Fetches the specified amount of log entries from the server log.
2366         *
2367         * @param lines
2368         *              the amount of log entries to fetch, in the range between 1 and 100.
2369         *              Returns 100 entries if the argument is not in range
2370         *
2371         * @return a list of the latest log entries
2372         *
2373         * @throws TS3CommandFailedException
2374         *              if the execution of a command fails
2375         * @querycommands 1
2376         */
2377        public List<String> getInstanceLogEntries(int lines) {
2378                return asyncApi.getInstanceLogEntries(lines).getUninterruptibly();
2379        }
2380
2381        /**
2382         * Fetches the last 100 log entries from the server log.
2383         *
2384         * @return a list of up to 100 log entries
2385         *
2386         * @throws TS3CommandFailedException
2387         *              if the execution of a command fails
2388         * @querycommands 1
2389         */
2390        public List<String> getInstanceLogEntries() {
2391                return asyncApi.getInstanceLogEntries().getUninterruptibly();
2392        }
2393
2394        /**
2395         * Reads the message body of a message. This will not set the read flag, though.
2396         *
2397         * @param messageId
2398         *              the ID of the message to be read
2399         *
2400         * @return the body of the message with the specified ID or {@code null} if there was no message with that ID
2401         *
2402         * @throws TS3CommandFailedException
2403         *              if the execution of a command fails
2404         * @querycommands 1
2405         * @see Message#getId()
2406         * @see #setMessageRead(int)
2407         */
2408        public String getOfflineMessage(int messageId) {
2409                return asyncApi.getOfflineMessage(messageId).getUninterruptibly();
2410        }
2411
2412        /**
2413         * Reads the message body of a message. This will not set the read flag, though.
2414         *
2415         * @param message
2416         *              the message to be read
2417         *
2418         * @return the body of the message with the specified ID or {@code null} if there was no message with that ID
2419         *
2420         * @throws TS3CommandFailedException
2421         *              if the execution of a command fails
2422         * @querycommands 1
2423         * @see Message#getId()
2424         * @see #setMessageRead(Message)
2425         */
2426        public String getOfflineMessage(Message message) {
2427                return asyncApi.getOfflineMessage(message).getUninterruptibly();
2428        }
2429
2430        /**
2431         * Gets a list of all offline messages for the server query.
2432         * The returned messages lack their message body, though.
2433         * To read the actual message, use {@link #getOfflineMessage(int)} or {@link #getOfflineMessage(Message)}.
2434         *
2435         * @return a list of all offline messages this server query has received
2436         *
2437         * @throws TS3CommandFailedException
2438         *              if the execution of a command fails
2439         * @querycommands 1
2440         */
2441        public List<Message> getOfflineMessages() {
2442                return asyncApi.getOfflineMessages().getUninterruptibly();
2443        }
2444
2445        /**
2446         * Displays detailed information about all assignments of the permission specified
2447         * with {@code permName}. The output includes the type and the ID of the client,
2448         * channel or group associated with the permission.
2449         *
2450         * @param permName
2451         *              the name of the permission
2452         *
2453         * @return a list of permission assignments
2454         *
2455         * @throws TS3CommandFailedException
2456         *              if the execution of a command fails
2457         * @querycommands 1
2458         * @see #getPermissionOverview(int, int)
2459         */
2460        public List<PermissionAssignment> getPermissionAssignments(String permName) {
2461                return asyncApi.getPermissionAssignments(permName).getUninterruptibly();
2462        }
2463
2464        /**
2465         * Gets the ID of the permission specified by {@code permName}.
2466         * <p>
2467         * Note that the use of numeric permission IDs is deprecated
2468         * and that this API only uses the string variant of the IDs.
2469         * </p>
2470         *
2471         * @param permName
2472         *              the name of the permission
2473         *
2474         * @return the numeric ID of the specified permission
2475         *
2476         * @throws TS3CommandFailedException
2477         *              if the execution of a command fails
2478         * @querycommands 1
2479         */
2480        public int getPermissionIdByName(String permName) {
2481                return asyncApi.getPermissionIdByName(permName).getUninterruptibly();
2482        }
2483
2484        /**
2485         * Gets the IDs of the permissions specified by {@code permNames}.
2486         * <p>
2487         * Note that the use of numeric permission IDs is deprecated
2488         * and that this API only uses the string variant of the IDs.
2489         * </p>
2490         *
2491         * @param permNames
2492         *              the names of the permissions
2493         *
2494         * @return the numeric IDs of the specified permission
2495         *
2496         * @throws IllegalArgumentException
2497         *              if {@code permNames} is {@code null}
2498         * @throws TS3CommandFailedException
2499         *              if the execution of a command fails
2500         * @querycommands 1
2501         */
2502        public int[] getPermissionIdsByName(String... permNames) {
2503                return asyncApi.getPermissionIdsByName(permNames).getUninterruptibly();
2504        }
2505
2506        /**
2507         * Gets a list of all assigned permissions for a client in a specified channel.
2508         * If you do not care about channel permissions, set {@code channelId} to {@code 0}.
2509         *
2510         * @param channelId
2511         *              the ID of the channel
2512         * @param clientDBId
2513         *              the database ID of the client to create the overview for
2514         *
2515         * @return a list of all permission assignments for the client in the specified channel
2516         *
2517         * @throws TS3CommandFailedException
2518         *              if the execution of a command fails
2519         * @querycommands 1
2520         * @see Channel#getId()
2521         * @see Client#getDatabaseId()
2522         */
2523        public List<PermissionAssignment> getPermissionOverview(int channelId, int clientDBId) {
2524                return asyncApi.getPermissionOverview(channelId, clientDBId).getUninterruptibly();
2525        }
2526
2527        /**
2528         * Displays a list of all permissions, including ID, name and description.
2529         *
2530         * @return a list of all permissions
2531         *
2532         * @throws TS3CommandFailedException
2533         *              if the execution of a command fails
2534         * @querycommands 1
2535         */
2536        public List<PermissionInfo> getPermissions() {
2537                return asyncApi.getPermissions().getUninterruptibly();
2538        }
2539
2540        /**
2541         * Displays the current value of the specified permission for this server query instance.
2542         *
2543         * @param permName
2544         *              the name of the permission
2545         *
2546         * @return the permission value, usually ranging from 0 to 100
2547         *
2548         * @throws TS3CommandFailedException
2549         *              if the execution of a command fails
2550         * @querycommands 1
2551         */
2552        public int getPermissionValue(String permName) {
2553                return asyncApi.getPermissionValue(permName).getUninterruptibly();
2554        }
2555
2556        /**
2557         * Displays the current values of the specified permissions for this server query instance.
2558         *
2559         * @param permNames
2560         *              the names of the permissions
2561         *
2562         * @return the permission values, usually ranging from 0 to 100
2563         *
2564         * @throws IllegalArgumentException
2565         *              if {@code permNames} is {@code null}
2566         * @throws TS3CommandFailedException
2567         *              if the execution of a command fails
2568         * @querycommands 1
2569         */
2570        public int[] getPermissionValues(String... permNames) {
2571                return asyncApi.getPermissionValues(permNames).getUninterruptibly();
2572        }
2573
2574        /**
2575         * Gets a list of all available tokens to join channel or server groups,
2576         * including their type and group IDs.
2577         *
2578         * @return a list of all generated, but still unclaimed privilege keys
2579         *
2580         * @throws TS3CommandFailedException
2581         *              if the execution of a command fails
2582         * @querycommands 1
2583         * @see #addPrivilegeKey(PrivilegeKeyType, int, int, String)
2584         * @see #usePrivilegeKey(String)
2585         */
2586        public List<PrivilegeKey> getPrivilegeKeys() {
2587                return asyncApi.getPrivilegeKeys().getUninterruptibly();
2588        }
2589
2590        /**
2591         * Gets a list of all clients in the specified server group.
2592         *
2593         * @param serverGroupId
2594         *              the ID of the server group for which the clients should be looked up
2595         *
2596         * @return a list of all clients in the server group
2597         *
2598         * @throws TS3CommandFailedException
2599         *              if the execution of a command fails
2600         * @querycommands 1
2601         */
2602        public List<ServerGroupClient> getServerGroupClients(int serverGroupId) {
2603                return asyncApi.getServerGroupClients(serverGroupId).getUninterruptibly();
2604        }
2605
2606        /**
2607         * Gets a list of all clients in the specified server group.
2608         *
2609         * @param serverGroup
2610         *              the server group for which the clients should be looked up
2611         *
2612         * @return a list of all clients in the server group
2613         *
2614         * @throws TS3CommandFailedException
2615         *              if the execution of a command fails
2616         * @querycommands 1
2617         */
2618        public List<ServerGroupClient> getServerGroupClients(ServerGroup serverGroup) {
2619                return asyncApi.getServerGroupClients(serverGroup).getUninterruptibly();
2620        }
2621
2622        /**
2623         * Gets a list of all permissions assigned to the specified server group.
2624         *
2625         * @param serverGroupId
2626         *              the ID of the server group for which the permissions should be looked up
2627         *
2628         * @return a list of all permissions assigned to the server group
2629         *
2630         * @throws TS3CommandFailedException
2631         *              if the execution of a command fails
2632         * @querycommands 1
2633         * @see ServerGroup#getId()
2634         * @see #getServerGroupPermissions(ServerGroup)
2635         */
2636        public List<Permission> getServerGroupPermissions(int serverGroupId) {
2637                return asyncApi.getServerGroupPermissions(serverGroupId).getUninterruptibly();
2638        }
2639
2640        /**
2641         * Gets a list of all permissions assigned to the specified server group.
2642         *
2643         * @param serverGroup
2644         *              the server group for which the permissions should be looked up
2645         *
2646         * @return a list of all permissions assigned to the server group
2647         *
2648         * @throws TS3CommandFailedException
2649         *              if the execution of a command fails
2650         * @querycommands 1
2651         */
2652        public List<Permission> getServerGroupPermissions(ServerGroup serverGroup) {
2653                return asyncApi.getServerGroupPermissions(serverGroup).getUninterruptibly();
2654        }
2655
2656        /**
2657         * Gets a list of all server groups on the virtual server.
2658         * <p>
2659         * Depending on your permissions, the output may also contain
2660         * global server query groups and template groups.
2661         * </p>
2662         *
2663         * @return a list of all server groups
2664         *
2665         * @throws TS3CommandFailedException
2666         *              if the execution of a command fails
2667         * @querycommands 1
2668         */
2669        public List<ServerGroup> getServerGroups() {
2670                return asyncApi.getServerGroups().getUninterruptibly();
2671        }
2672
2673        /**
2674         * Gets a list of all server groups set for a client.
2675         *
2676         * @param clientDatabaseId
2677         *              the database ID of the client for which the server groups should be looked up
2678         *
2679         * @return a list of all server groups set for the client
2680         *
2681         * @throws TS3CommandFailedException
2682         *              if the execution of a command fails
2683         * @querycommands 2
2684         * @see Client#getDatabaseId()
2685         * @see #getServerGroupsByClient(Client)
2686         */
2687        public List<ServerGroup> getServerGroupsByClientId(int clientDatabaseId) {
2688                return asyncApi.getServerGroupsByClientId(clientDatabaseId).getUninterruptibly();
2689        }
2690
2691        /**
2692         * Gets a list of all server groups set for a client.
2693         *
2694         * @param client
2695         *              the client for which the server groups should be looked up
2696         *
2697         * @return a list of all server group set for the client
2698         *
2699         * @throws TS3CommandFailedException
2700         *              if the execution of a command fails
2701         * @querycommands 2
2702         * @see #getServerGroupsByClientId(int)
2703         */
2704        public List<ServerGroup> getServerGroupsByClient(Client client) {
2705                return asyncApi.getServerGroupsByClient(client).getUninterruptibly();
2706        }
2707
2708        /**
2709         * Gets the ID of a virtual server by its port.
2710         *
2711         * @param port
2712         *              the port of a virtual server
2713         *
2714         * @return the ID of the virtual server
2715         *
2716         * @throws TS3CommandFailedException
2717         *              if the execution of a command fails
2718         * @querycommands 1
2719         * @see VirtualServer#getPort()
2720         * @see VirtualServer#getId()
2721         */
2722        public int getServerIdByPort(int port) {
2723                return asyncApi.getServerIdByPort(port).getUninterruptibly();
2724        }
2725
2726        /**
2727         * Gets detailed information about the virtual server the server query is currently in.
2728         *
2729         * @return information about the current virtual server
2730         *
2731         * @throws TS3CommandFailedException
2732         *              if the execution of a command fails
2733         * @querycommands 1
2734         */
2735        public VirtualServerInfo getServerInfo() {
2736                return asyncApi.getServerInfo().getUninterruptibly();
2737        }
2738
2739        /**
2740         * Gets the version, build number and platform of the TeamSpeak3 server.
2741         *
2742         * @return the version information of the server
2743         *
2744         * @throws TS3CommandFailedException
2745         *              if the execution of a command fails
2746         * @querycommands 1
2747         */
2748        public Version getVersion() {
2749                return asyncApi.getVersion().getUninterruptibly();
2750        }
2751
2752        /**
2753         * Gets a list of all virtual servers including their ID, status, number of clients online, etc.
2754         *
2755         * @return a list of all virtual servers
2756         *
2757         * @throws TS3CommandFailedException
2758         *              if the execution of a command fails
2759         * @querycommands 1
2760         */
2761        public List<VirtualServer> getVirtualServers() {
2762                return asyncApi.getVirtualServers().getUninterruptibly();
2763        }
2764
2765        /**
2766         * Fetches the specified amount of log entries from the currently selected virtual server.
2767         * If no virtual server is selected, the entries will be read from the server log instead.
2768         *
2769         * @param lines
2770         *              the amount of log entries to fetch, in the range between 1 and 100.
2771         *              Returns 100 entries if the argument is not in range
2772         *
2773         * @return a list of the latest log entries
2774         *
2775         * @throws TS3CommandFailedException
2776         *              if the execution of a command fails
2777         * @querycommands 1
2778         */
2779        public List<String> getVirtualServerLogEntries(int lines) {
2780                return asyncApi.getVirtualServerLogEntries(lines).getUninterruptibly();
2781        }
2782
2783        /**
2784         * Fetches the last 100 log entries from the currently selected virtual server.
2785         * If no virtual server is selected, the entries will be read from the server log instead.
2786         *
2787         * @return a list of up to 100 log entries
2788         *
2789         * @throws TS3CommandFailedException
2790         *              if the execution of a command fails
2791         * @querycommands 1
2792         */
2793        public List<String> getVirtualServerLogEntries() {
2794                return asyncApi.getVirtualServerLogEntries().getUninterruptibly();
2795        }
2796
2797        /**
2798         * Checks whether the client with the specified client ID is online.
2799         * <p>
2800         * Please note that there is no guarantee that the client will still be
2801         * online by the time the next command is executed.
2802         * </p>
2803         *
2804         * @param clientId
2805         *              the ID of the client
2806         *
2807         * @return {@code true} if the client is online, {@code false} otherwise
2808         *
2809         * @querycommands 1
2810         * @see #getClientInfo(int)
2811         */
2812        public boolean isClientOnline(int clientId) {
2813                return asyncApi.isClientOnline(clientId).getUninterruptibly();
2814        }
2815
2816        /**
2817         * Checks whether the client with the specified unique identifier is online.
2818         * <p>
2819         * Please note that there is no guarantee that the client will still be
2820         * online by the time the next command is executed.
2821         * </p>
2822         *
2823         * @param clientUId
2824         *              the unique ID of the client
2825         *
2826         * @return {@code true} if the client is online, {@code false} otherwise
2827         *
2828         * @querycommands 1
2829         * @see #getClientByUId(String)
2830         */
2831        public boolean isClientOnline(String clientUId) {
2832                return asyncApi.isClientOnline(clientUId).getUninterruptibly();
2833        }
2834
2835        /**
2836         * Kicks one or more clients from their current channels.
2837         * This will move the kicked clients into the default channel and
2838         * won't do anything if the clients are already in the default channel.
2839         *
2840         * @param clientIds
2841         *              the IDs of the clients to kick
2842         *
2843         * @throws TS3CommandFailedException
2844         *              if the execution of a command fails
2845         * @querycommands 1
2846         * @see #kickClientFromChannel(Client...)
2847         * @see #kickClientFromChannel(String, int...)
2848         */
2849        public void kickClientFromChannel(int... clientIds) {
2850                asyncApi.kickClientFromChannel(clientIds).getUninterruptibly();
2851        }
2852
2853        /**
2854         * Kicks one or more clients from their current channels.
2855         * This will move the kicked clients into the default channel and
2856         * won't do anything if the clients are already in the default channel.
2857         *
2858         * @param clients
2859         *              the clients to kick
2860         *
2861         * @throws TS3CommandFailedException
2862         *              if the execution of a command fails
2863         * @querycommands 1
2864         * @see #kickClientFromChannel(int...)
2865         * @see #kickClientFromChannel(String, Client...)
2866         */
2867        public void kickClientFromChannel(Client... clients) {
2868                asyncApi.kickClientFromChannel(clients).getUninterruptibly();
2869        }
2870
2871        /**
2872         * Kicks one or more clients from their current channels for the specified reason.
2873         * This will move the kicked clients into the default channel and
2874         * won't do anything if the clients are already in the default channel.
2875         *
2876         * @param message
2877         *              the reason message to display to the clients
2878         * @param clientIds
2879         *              the IDs of the clients to kick
2880         *
2881         * @throws TS3CommandFailedException
2882         *              if the execution of a command fails
2883         * @querycommands 1
2884         * @see Client#getId()
2885         * @see #kickClientFromChannel(int...)
2886         * @see #kickClientFromChannel(String, Client...)
2887         */
2888        public void kickClientFromChannel(String message, int... clientIds) {
2889                asyncApi.kickClientFromChannel(message, clientIds).getUninterruptibly();
2890        }
2891
2892        /**
2893         * Kicks one or more clients from their current channels for the specified reason.
2894         * This will move the kicked clients into the default channel and
2895         * won't do anything if the clients are already in the default channel.
2896         *
2897         * @param message
2898         *              the reason message to display to the clients
2899         * @param clients
2900         *              the clients to kick
2901         *
2902         * @throws TS3CommandFailedException
2903         *              if the execution of a command fails
2904         * @querycommands 1
2905         * @see #kickClientFromChannel(Client...)
2906         * @see #kickClientFromChannel(String, int...)
2907         */
2908        public void kickClientFromChannel(String message, Client... clients) {
2909                asyncApi.kickClientFromChannel(message, clients).getUninterruptibly();
2910        }
2911
2912        /**
2913         * Kicks one or more clients from the server.
2914         *
2915         * @param clientIds
2916         *              the IDs of the clients to kick
2917         *
2918         * @throws TS3CommandFailedException
2919         *              if the execution of a command fails
2920         * @querycommands 1
2921         * @see Client#getId()
2922         * @see #kickClientFromServer(Client...)
2923         * @see #kickClientFromServer(String, int...)
2924         */
2925        public void kickClientFromServer(int... clientIds) {
2926                asyncApi.kickClientFromServer(clientIds).getUninterruptibly();
2927        }
2928
2929        /**
2930         * Kicks one or more clients from the server.
2931         *
2932         * @param clients
2933         *              the clients to kick
2934         *
2935         * @throws TS3CommandFailedException
2936         *              if the execution of a command fails
2937         * @querycommands 1
2938         * @see #kickClientFromServer(int...)
2939         * @see #kickClientFromServer(String, Client...)
2940         */
2941        public void kickClientFromServer(Client... clients) {
2942                asyncApi.kickClientFromServer(clients).getUninterruptibly();
2943        }
2944
2945        /**
2946         * Kicks one or more clients from the server for the specified reason.
2947         *
2948         * @param message
2949         *              the reason message to display to the clients
2950         * @param clientIds
2951         *              the IDs of the clients to kick
2952         *
2953         * @throws TS3CommandFailedException
2954         *              if the execution of a command fails
2955         * @querycommands 1
2956         * @see Client#getId()
2957         * @see #kickClientFromServer(int...)
2958         * @see #kickClientFromServer(String, Client...)
2959         */
2960        public void kickClientFromServer(String message, int... clientIds) {
2961                asyncApi.kickClientFromServer(message, clientIds).getUninterruptibly();
2962        }
2963
2964        /**
2965         * Kicks one or more clients from the server for the specified reason.
2966         *
2967         * @param message
2968         *              the reason message to display to the clients
2969         * @param clients
2970         *              the clients to kick
2971         *
2972         * @throws TS3CommandFailedException
2973         *              if the execution of a command fails
2974         * @querycommands 1
2975         * @see #kickClientFromServer(Client...)
2976         * @see #kickClientFromServer(String, int...)
2977         */
2978        public void kickClientFromServer(String message, Client... clients) {
2979                asyncApi.kickClientFromServer(message, clients).getUninterruptibly();
2980        }
2981
2982        /**
2983         * Logs the server query in using the specified username and password.
2984         * <p>
2985         * Note that you can also set the login in the {@link TS3Config},
2986         * so that you will be logged in right after the connection is established.
2987         * </p>
2988         *
2989         * @param username
2990         *              the username of the server query
2991         * @param password
2992         *              the password to use
2993         *
2994         * @throws TS3CommandFailedException
2995         *              if the execution of a command fails
2996         * @querycommands 1
2997         * @see #logout()
2998         */
2999        public void login(String username, String password) {
3000                asyncApi.login(username, password).getUninterruptibly();
3001        }
3002
3003        /**
3004         * Logs the server query out and deselects the current virtual server.
3005         *
3006         * @throws TS3CommandFailedException
3007         *              if the execution of a command fails
3008         * @querycommands 1
3009         * @see #login(String, String)
3010         */
3011        public void logout() {
3012                asyncApi.logout().getUninterruptibly();
3013        }
3014
3015        /**
3016         * Moves a channel to a new parent channel specified by its ID.
3017         * To move a channel to root level, set {@code channelTargetId} to {@code 0}.
3018         * <p>
3019         * This will move the channel right below the specified parent channel, above all other child channels.
3020         * This command will fail if the channel already has the specified target channel as the parent channel.
3021         * </p>
3022         *
3023         * @param channelId
3024         *              the channel to move
3025         * @param channelTargetId
3026         *              the new parent channel for the specified channel
3027         *
3028         * @throws TS3CommandFailedException
3029         *              if the execution of a command fails
3030         * @querycommands 1
3031         * @see Channel#getId()
3032         * @see #moveChannel(int, int, int)
3033         */
3034        public void moveChannel(int channelId, int channelTargetId) {
3035                asyncApi.moveChannel(channelId, channelTargetId).getUninterruptibly();
3036        }
3037
3038        /**
3039         * Moves a channel to a new parent channel specified by its ID.
3040         * To move a channel to root level, set {@code channelTargetId} to {@code 0}.
3041         * <p>
3042         * The channel will be ordered below the channel with the ID specified by {@code order}.
3043         * To move the channel right below the parent channel, set {@code order} to {@code 0}.
3044         * </p><p>
3045         * Note that you can't re-order a channel without also changing its parent channel with this method.
3046         * Use {@link #editChannel(int, ChannelProperty, String)} to change {@link ChannelProperty#CHANNEL_ORDER} instead.
3047         * </p>
3048         *
3049         * @param channelId
3050         *              the channel to move
3051         * @param channelTargetId
3052         *              the new parent channel for the specified channel
3053         * @param order
3054         *              the channel to sort the specified channel below
3055         *
3056         * @throws TS3CommandFailedException
3057         *              if the execution of a command fails
3058         * @querycommands 1
3059         * @see Channel#getId()
3060         * @see #moveChannel(int, int)
3061         */
3062        public void moveChannel(int channelId, int channelTargetId, int order) {
3063                asyncApi.moveChannel(channelId, channelTargetId, order).getUninterruptibly();
3064        }
3065
3066        /**
3067         * Moves a single client into a channel.
3068         * <p>
3069         * Consider using {@link #moveClients(int[], int)} to move multiple clients.
3070         * </p>
3071         *
3072         * @param clientId
3073         *              the ID of the client to move
3074         * @param channelId
3075         *              the ID of the channel to move the client into
3076         *
3077         * @throws TS3CommandFailedException
3078         *              if the execution of a command fails
3079         * @querycommands 1
3080         * @see Client#getId()
3081         * @see Channel#getId()
3082         */
3083        public void moveClient(int clientId, int channelId) {
3084                asyncApi.moveClient(clientId, channelId).getUninterruptibly();
3085        }
3086
3087        /**
3088         * Moves multiple clients into a channel.
3089         * Immediately returns {@code true} for an empty client ID array.
3090         * <p>
3091         * Use this method instead of {@link #moveClient(int, int)} for moving
3092         * several clients as this will only send 1 command to the server and thus complete faster.
3093         * </p>
3094         *
3095         * @param clientIds
3096         *              the IDs of the clients to move, cannot be {@code null}
3097         * @param channelId
3098         *              the ID of the channel to move the clients into
3099         *
3100         * @throws IllegalArgumentException
3101         *              if {@code clientIds} is {@code null}
3102         * @throws TS3CommandFailedException
3103         *              if the execution of a command fails
3104         * @querycommands 1
3105         * @see Client#getId()
3106         * @see Channel#getId()
3107         */
3108        public void moveClients(int[] clientIds, int channelId) {
3109                asyncApi.moveClients(clientIds, channelId).getUninterruptibly();
3110        }
3111
3112        /**
3113         * Moves a single client into a channel.
3114         * <p>
3115         * Consider using {@link #moveClients(Client[], ChannelBase)} to move multiple clients.
3116         * </p>
3117         *
3118         * @param client
3119         *              the client to move, cannot be {@code null}
3120         * @param channel
3121         *              the channel to move the client into, cannot be {@code null}
3122         *
3123         * @throws IllegalArgumentException
3124         *              if {@code client} or {@code channel} is {@code null}
3125         * @throws TS3CommandFailedException
3126         *              if the execution of a command fails
3127         * @querycommands 1
3128         */
3129        public void moveClient(Client client, ChannelBase channel) {
3130                asyncApi.moveClient(client, channel).getUninterruptibly();
3131        }
3132
3133        /**
3134         * Moves multiple clients into a channel.
3135         * Immediately returns {@code true} for an empty client array.
3136         * <p>
3137         * Use this method instead of {@link #moveClient(Client, ChannelBase)} for moving
3138         * several clients as this will only send 1 command to the server and thus complete faster.
3139         * </p>
3140         *
3141         * @param clients
3142         *              the clients to move, cannot be {@code null}
3143         * @param channel
3144         *              the channel to move the clients into, cannot be {@code null}
3145         *
3146         * @throws IllegalArgumentException
3147         *              if {@code clients} or {@code channel} is {@code null}
3148         * @throws TS3CommandFailedException
3149         *              if the execution of a command fails
3150         * @querycommands 1
3151         */
3152        public void moveClients(Client[] clients, ChannelBase channel) {
3153                asyncApi.moveClients(clients, channel).getUninterruptibly();
3154        }
3155
3156        /**
3157         * Moves a single client into a channel using the specified password.
3158         * <p>
3159         * Consider using {@link #moveClients(int[], int, String)} to move multiple clients.
3160         * </p>
3161         *
3162         * @param clientId
3163         *              the ID of the client to move
3164         * @param channelId
3165         *              the ID of the channel to move the client into
3166         * @param channelPassword
3167         *              the password of the channel, can be {@code null}
3168         *
3169         * @throws TS3CommandFailedException
3170         *              if the execution of a command fails
3171         * @querycommands 1
3172         * @see Client#getId()
3173         * @see Channel#getId()
3174         */
3175        public void moveClient(int clientId, int channelId, String channelPassword) {
3176                asyncApi.moveClient(clientId, channelId, channelPassword).getUninterruptibly();
3177        }
3178
3179        /**
3180         * Moves multiple clients into a channel using the specified password.
3181         * Immediately returns {@code true} for an empty client ID array.
3182         * <p>
3183         * Use this method instead of {@link #moveClient(int, int, String)} for moving
3184         * several clients as this will only send 1 command to the server and thus complete faster.
3185         * </p>
3186         *
3187         * @param clientIds
3188         *              the IDs of the clients to move, cannot be {@code null}
3189         * @param channelId
3190         *              the ID of the channel to move the clients into
3191         * @param channelPassword
3192         *              the password of the channel, can be {@code null}
3193         *
3194         * @throws IllegalArgumentException
3195         *              if {@code clientIds} is {@code null}
3196         * @throws TS3CommandFailedException
3197         *              if the execution of a command fails
3198         * @querycommands 1
3199         * @see Client#getId()
3200         * @see Channel#getId()
3201         */
3202        public void moveClients(int[] clientIds, int channelId, String channelPassword) {
3203                asyncApi.moveClients(clientIds, channelId, channelPassword).getUninterruptibly();
3204        }
3205
3206        /**
3207         * Moves a single client into a channel using the specified password.
3208         * <p>
3209         * Consider using {@link #moveClients(Client[], ChannelBase, String)} to move multiple clients.
3210         * </p>
3211         *
3212         * @param client
3213         *              the client to move, cannot be {@code null}
3214         * @param channel
3215         *              the channel to move the client into, cannot be {@code null}
3216         * @param channelPassword
3217         *              the password of the channel, can be {@code null}
3218         *
3219         * @throws IllegalArgumentException
3220         *              if {@code client} or {@code channel} is {@code null}
3221         * @throws TS3CommandFailedException
3222         *              if the execution of a command fails
3223         * @querycommands 1
3224         */
3225        public void moveClient(Client client, ChannelBase channel, String channelPassword) {
3226                asyncApi.moveClient(client, channel, channelPassword).getUninterruptibly();
3227        }
3228
3229        /**
3230         * Moves multiple clients into a channel using the specified password.
3231         * Immediately returns {@code true} for an empty client array.
3232         * <p>
3233         * Use this method instead of {@link #moveClient(Client, ChannelBase, String)} for moving
3234         * several clients as this will only send 1 command to the server and thus complete faster.
3235         * </p>
3236         *
3237         * @param clients
3238         *              the clients to move, cannot be {@code null}
3239         * @param channel
3240         *              the channel to move the clients into, cannot be {@code null}
3241         * @param channelPassword
3242         *              the password of the channel, can be {@code null}
3243         *
3244         * @throws IllegalArgumentException
3245         *              if {@code clients} or {@code channel} is {@code null}
3246         * @throws TS3CommandFailedException
3247         *              if the execution of a command fails
3248         * @querycommands 1
3249         */
3250        public void moveClients(Client[] clients, ChannelBase channel, String channelPassword) {
3251                asyncApi.moveClients(clients, channel, channelPassword).getUninterruptibly();
3252        }
3253
3254        /**
3255         * Moves and renames a file on the file repository within the same channel.
3256         *
3257         * @param oldPath
3258         *              the current path to the file
3259         * @param newPath
3260         *              the desired new path
3261         * @param channelId
3262         *              the ID of the channel the file resides in
3263         *
3264         * @throws TS3CommandFailedException
3265         *              if the execution of a command fails
3266         * @querycommands 1
3267         * @see FileInfo#getPath()
3268         * @see Channel#getId()
3269         * @see #moveFile(String, String, int, int) moveFile to a different channel
3270         */
3271        public void moveFile(String oldPath, String newPath, int channelId) {
3272                asyncApi.moveFile(oldPath, newPath, channelId).getUninterruptibly();
3273        }
3274
3275        /**
3276         * Renames a file on the file repository and moves it to a new path in a different channel.
3277         *
3278         * @param oldPath
3279         *              the current path to the file
3280         * @param newPath
3281         *              the desired new path
3282         * @param oldChannelId
3283         *              the ID of the channel the file currently resides in
3284         * @param newChannelId
3285         *              the ID of the channel the file should be moved to
3286         *
3287         * @throws TS3CommandFailedException
3288         *              if the execution of a command fails
3289         * @querycommands 1
3290         * @see FileInfo#getPath()
3291         * @see Channel#getId()
3292         * @see #moveFile(String, String, int) moveFile within the same channel
3293         */
3294        public void moveFile(String oldPath, String newPath, int oldChannelId, int newChannelId) {
3295                asyncApi.moveFile(oldPath, newPath, oldChannelId, newChannelId).getUninterruptibly();
3296        }
3297
3298        /**
3299         * Moves and renames a file on the file repository within the same channel.
3300         *
3301         * @param oldPath
3302         *              the current path to the file
3303         * @param newPath
3304         *              the desired new path
3305         * @param channelId
3306         *              the ID of the channel the file resides in
3307         * @param channelPassword
3308         *              the password of the channel
3309         *
3310         * @throws TS3CommandFailedException
3311         *              if the execution of a command fails
3312         * @querycommands 1
3313         * @see FileInfo#getPath()
3314         * @see Channel#getId()
3315         * @see #moveFile(String, String, int, String, int, String) moveFile to a different channel
3316         */
3317        public void moveFile(String oldPath, String newPath, int channelId, String channelPassword) {
3318                asyncApi.moveFile(oldPath, newPath, channelId, channelPassword).getUninterruptibly();
3319        }
3320
3321        /**
3322         * Renames a file on the file repository and moves it to a new path in a different channel.
3323         *
3324         * @param oldPath
3325         *              the current path to the file
3326         * @param newPath
3327         *              the desired new path
3328         * @param oldChannelId
3329         *              the ID of the channel the file currently resides in
3330         * @param oldPassword
3331         *              the password of the current channel
3332         * @param newChannelId
3333         *              the ID of the channel the file should be moved to
3334         * @param newPassword
3335         *              the password of the new channel
3336         *
3337         * @throws TS3CommandFailedException
3338         *              if the execution of a command fails
3339         * @querycommands 1
3340         * @see FileInfo#getPath()
3341         * @see Channel#getId()
3342         * @see #moveFile(String, String, int, String) moveFile within the same channel
3343         */
3344        public void moveFile(String oldPath, String newPath, int oldChannelId, String oldPassword, int newChannelId, String newPassword) {
3345                asyncApi.moveFile(oldPath, newPath, oldChannelId, oldPassword, newChannelId, newPassword).getUninterruptibly();
3346        }
3347
3348        /**
3349         * Moves the server query into a channel.
3350         *
3351         * @param channelId
3352         *              the ID of the channel to move the server query into
3353         *
3354         * @throws TS3CommandFailedException
3355         *              if the execution of a command fails
3356         * @querycommands 1
3357         * @see Channel#getId()
3358         */
3359        public void moveQuery(int channelId) {
3360                asyncApi.moveQuery(channelId).getUninterruptibly();
3361        }
3362
3363        /**
3364         * Moves the server query into a channel.
3365         *
3366         * @param channel
3367         *              the channel to move the server query into, cannot be {@code null}
3368         *
3369         * @throws IllegalArgumentException
3370         *              if {@code channel} is {@code null}
3371         * @throws TS3CommandFailedException
3372         *              if the execution of a command fails
3373         * @querycommands 1
3374         */
3375        public void moveQuery(ChannelBase channel) {
3376                asyncApi.moveQuery(channel).getUninterruptibly();
3377        }
3378
3379        /**
3380         * Moves the server query into a channel using the specified password.
3381         *
3382         * @param channelId
3383         *              the ID of the channel to move the client into
3384         * @param channelPassword
3385         *              the password of the channel, can be {@code null}
3386         *
3387         * @throws TS3CommandFailedException
3388         *              if the execution of a command fails
3389         * @querycommands 1
3390         * @see Channel#getId()
3391         */
3392        public void moveQuery(int channelId, String channelPassword) {
3393                asyncApi.moveQuery(channelId, channelPassword).getUninterruptibly();
3394        }
3395
3396        /**
3397         * Moves the server query into a channel using the specified password.
3398         *
3399         * @param channel
3400         *              the channel to move the client into, cannot be {@code null}
3401         * @param channelPassword
3402         *              the password of the channel, can be {@code null}
3403         *
3404         * @throws IllegalArgumentException
3405         *              if {@code channel} is {@code null}
3406         * @throws TS3CommandFailedException
3407         *              if the execution of a command fails
3408         * @querycommands 1
3409         */
3410        public void moveQuery(ChannelBase channel, String channelPassword) {
3411                asyncApi.moveQuery(channel, channelPassword).getUninterruptibly();
3412        }
3413
3414        /**
3415         * Pokes the client with the specified client ID.
3416         * This opens up a small popup window for the client containing your message and plays a sound.
3417         * The displayed message will be formatted like this: <br>
3418         * {@code hh:mm:ss - "Your Nickname" poked you: <your message in green color>}
3419         * <p>
3420         * The displayed message length is limited to 100 UTF-8 bytes.
3421         * If a client has already received a poke message, all subsequent pokes will simply add a line
3422         * to the already opened popup window and will still play a sound.
3423         * </p>
3424         *
3425         * @param clientId
3426         *              the ID of the client to poke
3427         * @param message
3428         *              the message to send, may contain BB codes
3429         *
3430         * @throws TS3CommandFailedException
3431         *              if the execution of a command fails
3432         * @querycommands 1
3433         * @see Client#getId()
3434         */
3435        public void pokeClient(int clientId, String message) {
3436                asyncApi.pokeClient(clientId, message).getUninterruptibly();
3437        }
3438
3439        /**
3440         * Terminates the connection with the TeamSpeak3 server.
3441         * <p>
3442         * This command should never be executed by a user of this API,
3443         * as it leaves the query in an undefined state. To terminate
3444         * a connection regularly, use {@link TS3Query#exit()}.
3445         * </p>
3446         *
3447         * @throws TS3CommandFailedException
3448         *              if the execution of a command fails
3449         * @querycommands 1
3450         */
3451        void quit() {
3452                asyncApi.quit().getUninterruptibly();
3453        }
3454
3455        /**
3456         * Registers the server query to receive notifications about all server events.
3457         * <p>
3458         * This means that the following actions will trigger event notifications:
3459         * </p>
3460         * <ul>
3461         * <li>A client joins the server or disconnects from it</li>
3462         * <li>A client switches channels</li>
3463         * <li>A client sends a server message</li>
3464         * <li>A client sends a channel message <b>in the channel the query is in</b></li>
3465         * <li>A client sends a private message to <b>the server query</b></li>
3466         * <li>A client uses a privilege key</li>
3467         * </ul>
3468         * <p>
3469         * The limitations to when the query receives notifications about chat events cannot be circumvented.
3470         * </p>
3471         * To be able to process these events in your application, register an event listener.
3472         *
3473         * @throws TS3CommandFailedException
3474         *              if the execution of a command fails
3475         * @querycommands 6
3476         * @see #addTS3Listeners(TS3Listener...)
3477         */
3478        public void registerAllEvents() {
3479                asyncApi.registerAllEvents().getUninterruptibly();
3480        }
3481
3482        /**
3483         * Registers the server query to receive notifications about a given event type.
3484         * <p>
3485         * If used with {@link TS3EventType#TEXT_CHANNEL}, this will listen to chat events in the current channel.
3486         * If used with {@link TS3EventType#CHANNEL}, this will listen to <b>all</b> channel events.
3487         * To specify a different channel for channel events, use {@link #registerEvent(TS3EventType, int)}.
3488         * </p>
3489         *
3490         * @param eventType
3491         *              the event type to be notified about
3492         *
3493         * @throws TS3CommandFailedException
3494         *              if the execution of a command fails
3495         * @querycommands 1
3496         * @see #addTS3Listeners(TS3Listener...)
3497         * @see #registerEvent(TS3EventType, int)
3498         * @see #registerAllEvents()
3499         */
3500        public void registerEvent(TS3EventType eventType) {
3501                asyncApi.registerEvent(eventType).getUninterruptibly();
3502        }
3503
3504        /**
3505         * Registers the server query to receive notifications about a given event type.
3506         *
3507         * @param eventType
3508         *              the event type to be notified about
3509         * @param channelId
3510         *              the ID of the channel to listen to, will be ignored if set to {@code -1}.
3511         *              Can be set to {@code 0} for {@link TS3EventType#CHANNEL} to receive notifications about all channel switches.
3512         *
3513         * @throws TS3CommandFailedException
3514         *              if the execution of a command fails
3515         * @querycommands 1
3516         * @see Channel#getId()
3517         * @see #addTS3Listeners(TS3Listener...)
3518         * @see #registerAllEvents()
3519         */
3520        public void registerEvent(TS3EventType eventType, int channelId) {
3521                asyncApi.registerEvent(eventType, channelId).getUninterruptibly();
3522        }
3523
3524        /**
3525         * Registers the server query to receive notifications about multiple given event types.
3526         * <p>
3527         * If used with {@link TS3EventType#TEXT_CHANNEL}, this will listen to chat events in the current channel.
3528         * If used with {@link TS3EventType#CHANNEL}, this will listen to <b>all</b> channel events.
3529         * To specify a different channel for channel events, use {@link #registerEvent(TS3EventType, int)}.
3530         * </p>
3531         *
3532         * @param eventTypes
3533         *              the event types to be notified about
3534         *
3535         * @throws TS3CommandFailedException
3536         *              if the execution of a command fails
3537         * @querycommands n, one command per TS3EventType
3538         * @see #addTS3Listeners(TS3Listener...)
3539         * @see #registerEvent(TS3EventType, int)
3540         * @see #registerAllEvents()
3541         */
3542        public void registerEvents(TS3EventType... eventTypes) {
3543                asyncApi.registerEvents(eventTypes).getUninterruptibly();
3544        }
3545
3546        /**
3547         * Removes the client specified by its database ID from the specified server group.
3548         *
3549         * @param serverGroupId
3550         *              the ID of the server group
3551         * @param clientDatabaseId
3552         *              the database ID of the client
3553         *
3554         * @throws TS3CommandFailedException
3555         *              if the execution of a command fails
3556         * @querycommands 1
3557         * @see ServerGroup#getId()
3558         * @see Client#getDatabaseId()
3559         * @see #removeClientFromServerGroup(ServerGroup, Client)
3560         */
3561        public void removeClientFromServerGroup(int serverGroupId, int clientDatabaseId) {
3562                asyncApi.removeClientFromServerGroup(serverGroupId, clientDatabaseId).getUninterruptibly();
3563        }
3564
3565        /**
3566         * Removes the specified client from the specified server group.
3567         *
3568         * @param serverGroup
3569         *              the server group to remove the client from
3570         * @param client
3571         *              the client to remove from the server group
3572         *
3573         * @throws TS3CommandFailedException
3574         *              if the execution of a command fails
3575         * @querycommands 1
3576         * @see #removeClientFromServerGroup(int, int)
3577         */
3578        public void removeClientFromServerGroup(ServerGroup serverGroup, Client client) {
3579                asyncApi.removeClientFromServerGroup(serverGroup, client).getUninterruptibly();
3580        }
3581
3582        /**
3583         * Removes one or more {@link TS3Listener}s to the event manager of the query.
3584         * <p>
3585         * If a listener was not actually registered, it will be ignored and no exception will be thrown.
3586         * </p>
3587         *
3588         * @param listeners
3589         *              one or more listeners to remove
3590         *
3591         * @see #addTS3Listeners(TS3Listener...)
3592         * @see TS3Listener
3593         * @see TS3EventType
3594         */
3595        public void removeTS3Listeners(TS3Listener... listeners) {
3596                asyncApi.removeTS3Listeners(listeners);
3597        }
3598
3599        /**
3600         * Renames the channel group with the specified ID.
3601         *
3602         * @param channelGroupId
3603         *              the ID of the channel group to rename
3604         * @param name
3605         *              the new name for the channel group
3606         *
3607         * @throws TS3CommandFailedException
3608         *              if the execution of a command fails
3609         * @querycommands 1
3610         * @see ChannelGroup#getId()
3611         * @see #renameChannelGroup(ChannelGroup, String)
3612         */
3613        public void renameChannelGroup(int channelGroupId, String name) {
3614                asyncApi.renameChannelGroup(channelGroupId, name).getUninterruptibly();
3615        }
3616
3617        /**
3618         * Renames the specified channel group.
3619         *
3620         * @param channelGroup
3621         *              the channel group to rename
3622         * @param name
3623         *              the new name for the channel group
3624         *
3625         * @throws TS3CommandFailedException
3626         *              if the execution of a command fails
3627         * @querycommands 1
3628         * @see #renameChannelGroup(int, String)
3629         */
3630        public void renameChannelGroup(ChannelGroup channelGroup, String name) {
3631                asyncApi.renameChannelGroup(channelGroup, name).getUninterruptibly();
3632        }
3633
3634        /**
3635         * Renames the server group with the specified ID.
3636         *
3637         * @param serverGroupId
3638         *              the ID of the server group to rename
3639         * @param name
3640         *              the new name for the server group
3641         *
3642         * @throws TS3CommandFailedException
3643         *              if the execution of a command fails
3644         * @querycommands 1
3645         * @see ServerGroup#getId()
3646         * @see #renameServerGroup(ServerGroup, String)
3647         */
3648        public void renameServerGroup(int serverGroupId, String name) {
3649                asyncApi.renameServerGroup(serverGroupId, name).getUninterruptibly();
3650        }
3651
3652        /**
3653         * Renames the specified server group.
3654         *
3655         * @param serverGroup
3656         *              the server group to rename
3657         * @param name
3658         *              the new name for the server group
3659         *
3660         * @throws TS3CommandFailedException
3661         *              if the execution of a command fails
3662         * @querycommands 1
3663         * @see #renameServerGroup(int, String)
3664         */
3665        public void renameServerGroup(ServerGroup serverGroup, String name) {
3666                asyncApi.renameServerGroup(serverGroup, name).getUninterruptibly();
3667        }
3668
3669        /**
3670         * Resets all permissions and deletes all server / channel groups. Use carefully.
3671         *
3672         * @return a token for a new administrator account
3673         *
3674         * @throws TS3CommandFailedException
3675         *              if the execution of a command fails
3676         * @querycommands 1
3677         */
3678        public String resetPermissions() {
3679                return asyncApi.resetPermissions().getUninterruptibly();
3680        }
3681
3682        /**
3683         * Finds all clients that have any value associated with the {@code key} custom client property,
3684         * and returns the client's database ID and the key and value of the matching custom property.
3685         *
3686         * @param key
3687         *              the key to search for, cannot be {@code null}
3688         *
3689         * @return a list of client database IDs and their matching custom client properties
3690         *
3691         * @throws TS3CommandFailedException
3692         *              if the execution of a command fails
3693         * @querycommands 1
3694         * @see Client#getDatabaseId()
3695         * @see #searchCustomClientProperty(String, String)
3696         * @see #getCustomClientProperties(int)
3697         */
3698        public List<CustomPropertyAssignment> searchCustomClientProperty(String key) {
3699                return asyncApi.searchCustomClientProperty(key).getUninterruptibly();
3700        }
3701
3702        /**
3703         * Finds all clients whose value associated with the {@code key} custom client property matches the
3704         * SQL-like pattern {@code valuePattern}, and returns the client's database ID and the key and value
3705         * of the matching custom property.
3706         * <p>
3707         * Patterns are case insensitive. They support the wildcard characters {@code %}, which matches any sequence of
3708         * zero or more characters, and {@code _}, which matches exactly one arbitrary character.
3709         * </p>
3710         *
3711         * @param key
3712         *              the key to search for, cannot be {@code null}
3713         * @param valuePattern
3714         *              the pattern that values need to match to be included
3715         *
3716         * @return a list of client database IDs and their matching custom client properties
3717         *
3718         * @throws TS3CommandFailedException
3719         *              if the execution of a command fails
3720         * @querycommands 1
3721         * @see Client#getDatabaseId()
3722         * @see #searchCustomClientProperty(String)
3723         * @see #getCustomClientProperties(int)
3724         */
3725        public List<CustomPropertyAssignment> searchCustomClientProperty(String key, String valuePattern) {
3726                return asyncApi.searchCustomClientProperty(key, valuePattern).getUninterruptibly();
3727        }
3728
3729        /**
3730         * Moves the server query into the virtual server with the specified ID.
3731         *
3732         * @param id
3733         *              the ID of the virtual server
3734         *
3735         * @throws TS3CommandFailedException
3736         *              if the execution of a command fails
3737         * @querycommands 1
3738         * @see VirtualServer#getId()
3739         * @see #selectVirtualServerById(int, String)
3740         * @see #selectVirtualServerByPort(int)
3741         * @see #selectVirtualServer(VirtualServer)
3742         */
3743        public void selectVirtualServerById(int id) {
3744                asyncApi.selectVirtualServerById(id).getUninterruptibly();
3745        }
3746
3747        /**
3748         * Moves the server query into the virtual server with the specified ID
3749         * and sets the server query's nickname.
3750         * <p>
3751         * The nickname must be between 3 and 30 UTF-8 bytes long. BB codes will be ignored.
3752         * </p>
3753         *
3754         * @param id
3755         *              the ID of the virtual server
3756         * @param nickname
3757         *              the nickname, or {@code null} if the nickname should not be set
3758         *
3759         * @throws TS3CommandFailedException
3760         *              if the execution of a command fails
3761         * @querycommands 1
3762         * @see VirtualServer#getId()
3763         * @see #selectVirtualServerById(int)
3764         * @see #selectVirtualServerByPort(int, String)
3765         * @see #selectVirtualServer(VirtualServer, String)
3766         */
3767        public void selectVirtualServerById(int id, String nickname) {
3768                asyncApi.selectVirtualServerById(id, nickname).getUninterruptibly();
3769        }
3770
3771        /**
3772         * Moves the server query into the virtual server with the specified voice port.
3773         *
3774         * @param port
3775         *              the voice port of the virtual server
3776         *
3777         * @throws TS3CommandFailedException
3778         *              if the execution of a command fails
3779         * @querycommands 1
3780         * @see VirtualServer#getPort()
3781         * @see #selectVirtualServerById(int)
3782         * @see #selectVirtualServerByPort(int, String)
3783         * @see #selectVirtualServer(VirtualServer)
3784         */
3785        public void selectVirtualServerByPort(int port) {
3786                asyncApi.selectVirtualServerByPort(port).getUninterruptibly();
3787        }
3788
3789        /**
3790         * Moves the server query into the virtual server with the specified voice port
3791         * and sets the server query's nickname.
3792         * <p>
3793         * The nickname must be between 3 and 30 UTF-8 bytes long. BB codes will be ignored.
3794         * </p>
3795         *
3796         * @param port
3797         *              the voice port of the virtual server
3798         * @param nickname
3799         *              the nickname, or {@code null} if the nickname should not be set
3800         *
3801         * @throws TS3CommandFailedException
3802         *              if the execution of a command fails
3803         * @querycommands 1
3804         * @see VirtualServer#getPort()
3805         * @see #selectVirtualServerById(int, String)
3806         * @see #selectVirtualServerByPort(int)
3807         * @see #selectVirtualServer(VirtualServer, String)
3808         */
3809        public void selectVirtualServerByPort(int port, String nickname) {
3810                asyncApi.selectVirtualServerByPort(port, nickname).getUninterruptibly();
3811        }
3812
3813        /**
3814         * Moves the server query into the specified virtual server.
3815         *
3816         * @param server
3817         *              the virtual server to move into
3818         *
3819         * @throws TS3CommandFailedException
3820         *              if the execution of a command fails
3821         * @querycommands 1
3822         * @see #selectVirtualServerById(int)
3823         * @see #selectVirtualServerByPort(int)
3824         * @see #selectVirtualServer(VirtualServer, String)
3825         */
3826        public void selectVirtualServer(VirtualServer server) {
3827                asyncApi.selectVirtualServer(server).getUninterruptibly();
3828        }
3829
3830        /**
3831         * Moves the server query into the specified virtual server
3832         * and sets the server query's nickname.
3833         * <p>
3834         * The nickname must be between 3 and 30 UTF-8 bytes long. BB codes will be ignored.
3835         * </p>
3836         *
3837         * @param server
3838         *              the virtual server to move into
3839         * @param nickname
3840         *              the nickname, or {@code null} if the nickname should not be set
3841         *
3842         * @throws TS3CommandFailedException
3843         *              if the execution of a command fails
3844         * @querycommands 1
3845         * @see #selectVirtualServerById(int, String)
3846         * @see #selectVirtualServerByPort(int, String)
3847         * @see #selectVirtualServer(VirtualServer)
3848         */
3849        public void selectVirtualServer(VirtualServer server, String nickname) {
3850                asyncApi.selectVirtualServer(server, nickname).getUninterruptibly();
3851        }
3852
3853        /**
3854         * Sends an offline message to the client with the given unique identifier.
3855         * <p>
3856         * The message subject's length is limited to 200 UTF-8 bytes and BB codes in it will be ignored.
3857         * The message body's length is limited to 4096 UTF-8 bytes and accepts BB codes
3858         * </p>
3859         *
3860         * @param clientUId
3861         *              the unique identifier of the client to send the message to
3862         * @param subject
3863         *              the subject for the message, may not contain BB codes
3864         * @param message
3865         *              the actual message body, may contain BB codes
3866         *
3867         * @throws TS3CommandFailedException
3868         *              if the execution of a command fails
3869         * @querycommands 1
3870         * @see Client#getUniqueIdentifier()
3871         * @see Message
3872         */
3873        public void sendOfflineMessage(String clientUId, String subject, String message) {
3874                asyncApi.sendOfflineMessage(clientUId, subject, message).getUninterruptibly();
3875        }
3876
3877        /**
3878         * Sends a text message either to the whole virtual server, a channel or specific client.
3879         * Your message may contain BB codes, but its length is limited to 1024 UTF-8 bytes.
3880         * <p>
3881         * To send a message to all virtual servers, use {@link #broadcast(String)}.
3882         * To send an offline message, use {@link #sendOfflineMessage(String, String, String)}.
3883         * </p>
3884         *
3885         * @param targetMode
3886         *              where the message should be sent to
3887         * @param targetId
3888         *              the client ID of the recipient of this message. This value is ignored unless {@code targetMode} is {@code CLIENT}
3889         * @param message
3890         *              the text message to send
3891         *
3892         * @throws TS3CommandFailedException
3893         *              if the execution of a command fails
3894         * @querycommands 1
3895         * @see Client#getId()
3896         */
3897        public void sendTextMessage(TextMessageTargetMode targetMode, int targetId, String message) {
3898                asyncApi.sendTextMessage(targetMode, targetId, message).getUninterruptibly();
3899        }
3900
3901        /**
3902         * Sends a text message to the channel with the specified ID.
3903         * Your message may contain BB codes, but its length is limited to 1024 UTF-8 bytes.
3904         * <p>
3905         * This will move the client into the channel with the specified channel ID,
3906         * <b>but will not move it back to the original channel!</b>
3907         * </p>
3908         *
3909         * @param channelId
3910         *              the ID of the channel to which the message should be sent to
3911         * @param message
3912         *              the text message to send
3913         *
3914         * @throws TS3CommandFailedException
3915         *              if the execution of a command fails
3916         * @querycommands 1
3917         * @see #sendChannelMessage(String)
3918         * @see Channel#getId()
3919         */
3920        public void sendChannelMessage(int channelId, String message) {
3921                asyncApi.sendChannelMessage(channelId, message).getUninterruptibly();
3922        }
3923
3924        /**
3925         * Sends a text message to the channel the server query is currently in.
3926         * Your message may contain BB codes, but its length is limited to 1024 UTF-8 bytes.
3927         *
3928         * @param message
3929         *              the text message to send
3930         *
3931         * @throws TS3CommandFailedException
3932         *              if the execution of a command fails
3933         * @querycommands 1
3934         */
3935        public void sendChannelMessage(String message) {
3936                asyncApi.sendChannelMessage(message).getUninterruptibly();
3937        }
3938
3939        /**
3940         * Sends a text message to the virtual server with the specified ID.
3941         * Your message may contain BB codes, but its length is limited to 1024 UTF-8 bytes.
3942         * <p>
3943         * This will move the client to the virtual server with the specified server ID,
3944         * <b>but will not move it back to the original virtual server!</b>
3945         * </p>
3946         *
3947         * @param serverId
3948         *              the ID of the virtual server to which the message should be sent to
3949         * @param message
3950         *              the text message to send
3951         *
3952         * @throws TS3CommandFailedException
3953         *              if the execution of a command fails
3954         * @querycommands 1
3955         * @see #sendServerMessage(String)
3956         * @see VirtualServer#getId()
3957         */
3958        public void sendServerMessage(int serverId, String message) {
3959                asyncApi.sendServerMessage(serverId, message).getUninterruptibly();
3960        }
3961
3962        /**
3963         * Sends a text message to the virtual server the server query is currently in.
3964         * Your message may contain BB codes, but its length is limited to 1024 UTF-8 bytes.
3965         *
3966         * @param message
3967         *              the text message to send
3968         *
3969         * @throws TS3CommandFailedException
3970         *              if the execution of a command fails
3971         * @querycommands 1
3972         */
3973        public void sendServerMessage(String message) {
3974                asyncApi.sendServerMessage(message).getUninterruptibly();
3975        }
3976
3977        /**
3978         * Sends a private message to the client with the specified client ID.
3979         * Your message may contain BB codes, but its length is limited to 1024 UTF-8 bytes.
3980         *
3981         * @param clientId
3982         *              the ID of the client to send the message to
3983         * @param message
3984         *              the text message to send
3985         *
3986         * @throws TS3CommandFailedException
3987         *              if the execution of a command fails
3988         * @querycommands 1
3989         * @see Client#getId()
3990         */
3991        public void sendPrivateMessage(int clientId, String message) {
3992                asyncApi.sendPrivateMessage(clientId, message).getUninterruptibly();
3993        }
3994
3995        /**
3996         * Sets a channel group for a client in a specific channel.
3997         *
3998         * @param groupId
3999         *              the ID of the group the client should join
4000         * @param channelId
4001         *              the ID of the channel where the channel group should be assigned
4002         * @param clientDBId
4003         *              the database ID of the client for which the channel group should be set
4004         *
4005         * @throws TS3CommandFailedException
4006         *              if the execution of a command fails
4007         * @querycommands 1
4008         * @see ChannelGroup#getId()
4009         * @see Channel#getId()
4010         * @see Client#getDatabaseId()
4011         */
4012        public void setClientChannelGroup(int groupId, int channelId, int clientDBId) {
4013                asyncApi.setClientChannelGroup(groupId, channelId, clientDBId).getUninterruptibly();
4014        }
4015
4016        /**
4017         * Sets the value of the multiple custom client properties for a client.
4018         * <p>
4019         * If any key present in the map already has a value assigned for this client,
4020         * the existing value will be overwritten.
4021         * This method does not delete keys not present in the map.
4022         * </p><p>
4023         * If {@code properties} contains an entry with {@code null} as its key,
4024         * that entry will be ignored and no exception will be thrown.
4025         * </p>
4026         *
4027         * @param clientDBId
4028         *              the database ID of the target client
4029         * @param properties
4030         *              the map of properties to set, cannot be {@code null}
4031         *
4032         * @throws TS3CommandFailedException
4033         *              if the execution of a command fails
4034         * @querycommands properties.size()
4035         * @see Client#getDatabaseId()
4036         * @see #setCustomClientProperty(int, String, String)
4037         * @see #deleteCustomClientProperty(int, String)
4038         */
4039        public void setCustomClientProperties(int clientDBId, Map<String, String> properties) {
4040                asyncApi.setCustomClientProperties(clientDBId, properties).getUninterruptibly();
4041        }
4042
4043        /**
4044         * Sets the value of the {@code key} custom client property for a client.
4045         * <p>
4046         * If there is already an assignment of the {@code key} custom client property
4047         * for this client, the existing value will be overwritten.
4048         * </p>
4049         *
4050         * @param clientDBId
4051         *              the database ID of the target client
4052         * @param key
4053         *              the key of the custom property to set, cannot be {@code null}
4054         * @param value
4055         *              the (new) value of the custom property to set
4056         *
4057         * @throws TS3CommandFailedException
4058         *              if the execution of a command fails
4059         * @querycommands 1
4060         * @see Client#getDatabaseId()
4061         * @see #setCustomClientProperties(int, Map)
4062         * @see #deleteCustomClientProperty(int, String)
4063         */
4064        public void setCustomClientProperty(int clientDBId, String key, String value) {
4065                asyncApi.setCustomClientProperty(clientDBId, key, value).getUninterruptibly();
4066        }
4067
4068        /**
4069         * Sets the read flag to {@code true} for a given message. This will not delete the message.
4070         *
4071         * @param messageId
4072         *              the ID of the message for which the read flag should be set
4073         *
4074         * @throws TS3CommandFailedException
4075         *              if the execution of a command fails
4076         * @querycommands 1
4077         * @see #setMessageReadFlag(int, boolean)
4078         */
4079        public void setMessageRead(int messageId) {
4080                asyncApi.setMessageRead(messageId).getUninterruptibly();
4081        }
4082
4083        /**
4084         * Sets the read flag to {@code true} for a given message. This will not delete the message.
4085         *
4086         * @param message
4087         *              the message for which the read flag should be set
4088         *
4089         * @throws TS3CommandFailedException
4090         *              if the execution of a command fails
4091         * @querycommands 1
4092         * @see #setMessageRead(int)
4093         * @see #setMessageReadFlag(Message, boolean)
4094         * @see #deleteOfflineMessage(int)
4095         */
4096        public void setMessageRead(Message message) {
4097                asyncApi.setMessageRead(message).getUninterruptibly();
4098        }
4099
4100        /**
4101         * Sets the read flag for a given message. This will not delete the message.
4102         *
4103         * @param messageId
4104         *              the ID of the message for which the read flag should be set
4105         * @param read
4106         *              the boolean value to which the read flag should be set
4107         *
4108         * @throws TS3CommandFailedException
4109         *              if the execution of a command fails
4110         * @querycommands 1
4111         * @see #setMessageRead(int)
4112         * @see #setMessageReadFlag(Message, boolean)
4113         * @see #deleteOfflineMessage(int)
4114         */
4115        public void setMessageReadFlag(int messageId, boolean read) {
4116                asyncApi.setMessageReadFlag(messageId, read).getUninterruptibly();
4117        }
4118
4119        /**
4120         * Sets the read flag for a given message. This will not delete the message.
4121         *
4122         * @param message
4123         *              the message for which the read flag should be set
4124         * @param read
4125         *              the boolean value to which the read flag should be set
4126         *
4127         * @throws TS3CommandFailedException
4128         *              if the execution of a command fails
4129         * @querycommands 1
4130         * @see #setMessageRead(Message)
4131         * @see #setMessageReadFlag(int, boolean)
4132         * @see #deleteOfflineMessage(int)
4133         */
4134        public void setMessageReadFlag(Message message, boolean read) {
4135                asyncApi.setMessageReadFlag(message, read).getUninterruptibly();
4136        }
4137
4138        /**
4139         * Sets the nickname of the server query client.
4140         * <p>
4141         * The nickname must be between 3 and 30 UTF-8 bytes long. BB codes will be ignored.
4142         * </p>
4143         *
4144         * @param nickname
4145         *              the new nickname, may not be {@code null}
4146         *
4147         * @throws TS3CommandFailedException
4148         *              if the execution of a command fails
4149         * @querycommands 1
4150         * @see #updateClient(Map)
4151         */
4152        public void setNickname(String nickname) {
4153                asyncApi.setNickname(nickname).getUninterruptibly();
4154        }
4155
4156        /**
4157         * Starts the virtual server with the specified ID.
4158         *
4159         * @param serverId
4160         *              the ID of the virtual server
4161         *
4162         * @throws TS3CommandFailedException
4163         *              if the execution of a command fails
4164         * @querycommands 1
4165         */
4166        public void startServer(int serverId) {
4167                asyncApi.startServer(serverId).getUninterruptibly();
4168        }
4169
4170        /**
4171         * Starts the specified virtual server.
4172         *
4173         * @param virtualServer
4174         *              the virtual server to start
4175         *
4176         * @throws TS3CommandFailedException
4177         *              if the execution of a command fails
4178         * @querycommands 1
4179         */
4180        public void startServer(VirtualServer virtualServer) {
4181                asyncApi.startServer(virtualServer).getUninterruptibly();
4182        }
4183
4184        /**
4185         * Stops the virtual server with the specified ID.
4186         *
4187         * @param serverId
4188         *              the ID of the virtual server
4189         *
4190         * @throws TS3CommandFailedException
4191         *              if the execution of a command fails
4192         * @querycommands 1
4193         */
4194        public void stopServer(int serverId) {
4195                asyncApi.stopServer(serverId).getUninterruptibly();
4196        }
4197
4198        /**
4199         * Stops the virtual server with the specified ID.
4200         *
4201         * @param serverId
4202         *              the ID of the virtual server
4203         * @param reason
4204         *              the reason message to display to clients when they are disconnected
4205         *
4206         * @throws TS3CommandFailedException
4207         *              if the execution of a command fails
4208         * @querycommands 1
4209         */
4210        public void stopServer(int serverId, String reason) {
4211                asyncApi.stopServer(serverId, reason).getUninterruptibly();
4212        }
4213
4214        /**
4215         * Stops the specified virtual server.
4216         *
4217         * @param virtualServer
4218         *              the virtual server to stop
4219         *
4220         * @throws TS3CommandFailedException
4221         *              if the execution of a command fails
4222         * @querycommands 1
4223         */
4224        public void stopServer(VirtualServer virtualServer) {
4225                asyncApi.stopServer(virtualServer).getUninterruptibly();
4226        }
4227
4228        /**
4229         * Stops the specified virtual server.
4230         *
4231         * @param virtualServer
4232         *              the virtual server to stop
4233         * @param reason
4234         *              the reason message to display to clients when they are disconnected
4235         *
4236         * @throws TS3CommandFailedException
4237         *              if the execution of a command fails
4238         * @querycommands 1
4239         */
4240        public void stopServer(VirtualServer virtualServer, String reason) {
4241                asyncApi.stopServer(virtualServer, reason).getUninterruptibly();
4242        }
4243
4244        /**
4245         * Stops the entire TeamSpeak 3 Server instance by shutting down the process.
4246         * <p>
4247         * To have permission to use this command, you need to use the server query admin login.
4248         * </p>
4249         *
4250         * @throws TS3CommandFailedException
4251         *              if the execution of a command fails
4252         * @querycommands 1
4253         */
4254        public void stopServerProcess() {
4255                asyncApi.stopServerProcess().getUninterruptibly();
4256        }
4257
4258        /**
4259         * Stops the entire TeamSpeak 3 Server instance by shutting down the process.
4260         * <p>
4261         * To have permission to use this command, you need to use the server query admin login.
4262         * </p>
4263         *
4264         * @param reason
4265         *              the reason message to display to clients when they are disconnected
4266         *
4267         * @throws TS3CommandFailedException
4268         *              if the execution of a command fails
4269         * @querycommands 1
4270         */
4271        public void stopServerProcess(String reason) {
4272                asyncApi.stopServerProcess(reason).getUninterruptibly();
4273        }
4274
4275        /**
4276         * Unregisters the server query from receiving any event notifications.
4277         *
4278         * @throws TS3CommandFailedException
4279         *              if the execution of a command fails
4280         * @querycommands 1
4281         */
4282        public void unregisterAllEvents() {
4283                asyncApi.unregisterAllEvents().getUninterruptibly();
4284        }
4285
4286        /**
4287         * Updates several client properties for this server query instance.
4288         *
4289         * @param options
4290         *              the map of properties to update
4291         *
4292         * @throws TS3CommandFailedException
4293         *              if the execution of a command fails
4294         * @querycommands 1
4295         * @see #updateClient(ClientProperty, String)
4296         * @see #editClient(int, Map)
4297         */
4298        public void updateClient(Map<ClientProperty, String> options) {
4299                asyncApi.updateClient(options).getUninterruptibly();
4300        }
4301
4302        /**
4303         * Changes a single client property for this server query instance.
4304         * <p>
4305         * Note that one can set many properties at once with the overloaded method that
4306         * takes a map of client properties and strings.
4307         * </p>
4308         *
4309         * @param property
4310         *              the client property to modify, make sure it is editable
4311         * @param value
4312         *              the new value of the property
4313         *
4314         * @throws TS3CommandFailedException
4315         *              if the execution of a command fails
4316         * @querycommands 1
4317         * @see #updateClient(Map)
4318         * @see #editClient(int, Map)
4319         */
4320        public void updateClient(ClientProperty property, String value) {
4321                asyncApi.updateClient(property, value).getUninterruptibly();
4322        }
4323
4324        /**
4325         * Generates new login credentials for the currently connected server query instance, using the given name.
4326         * <p>
4327         * <b>This will remove the current login credentials!</b> You won't be logged out, but after disconnecting,
4328         * the old credentials will no longer work. Make sure to not lock yourselves out!
4329         * </p>
4330         *
4331         * @param loginName
4332         *              the name for the server query login
4333         *
4334         * @return the generated password for the server query login
4335         *
4336         * @throws TS3CommandFailedException
4337         *              if the execution of a command fails
4338         * @querycommands 1
4339         */
4340        public String updateServerQueryLogin(String loginName) {
4341                return asyncApi.updateServerQueryLogin(loginName).getUninterruptibly();
4342        }
4343
4344        /**
4345         * Uploads a file to the file repository at a given path and channel
4346         * by reading {@code dataLength} bytes from an open {@link InputStream}.
4347         * <p>
4348         * It is the user's responsibility to ensure that the given {@code InputStream} is
4349         * open and that {@code dataLength} bytes can eventually be read from it. The user is
4350         * also responsible for closing the stream once the upload has finished.
4351         * </p><p>
4352         * Note that this method will not read the entire file to memory and can thus
4353         * upload arbitrarily sized files to the file repository.
4354         * </p>
4355         *
4356         * @param dataIn
4357         *              a stream that contains the data that should be uploaded
4358         * @param dataLength
4359         *              how many bytes should be read from the stream
4360         * @param filePath
4361         *              the path the file should have after being uploaded
4362         * @param overwrite
4363         *              if {@code false}, fails if there's already a file at {@code filePath}
4364         * @param channelId
4365         *              the ID of the channel to upload the file to
4366         *
4367         * @throws TS3CommandFailedException
4368         *              if the execution of a command fails
4369         * @throws TS3FileTransferFailedException
4370         *              if the file transfer fails for any reason
4371         * @querycommands 1
4372         * @see FileInfo#getPath()
4373         * @see Channel#getId()
4374         * @see #uploadFileDirect(byte[], String, boolean, int, String)
4375         */
4376        public void uploadFile(InputStream dataIn, long dataLength, String filePath, boolean overwrite, int channelId) {
4377                asyncApi.uploadFile(dataIn, dataLength, filePath, overwrite, channelId).getUninterruptibly();
4378        }
4379
4380        /**
4381         * Uploads a file to the file repository at a given path and channel
4382         * by reading {@code dataLength} bytes from an open {@link InputStream}.
4383         * <p>
4384         * It is the user's responsibility to ensure that the given {@code InputStream} is
4385         * open and that {@code dataLength} bytes can eventually be read from it. The user is
4386         * also responsible for closing the stream once the upload has finished.
4387         * </p><p>
4388         * Note that this method will not read the entire file to memory and can thus
4389         * upload arbitrarily sized files to the file repository.
4390         * </p>
4391         *
4392         * @param dataIn
4393         *              a stream that contains the data that should be uploaded
4394         * @param dataLength
4395         *              how many bytes should be read from the stream
4396         * @param filePath
4397         *              the path the file should have after being uploaded
4398         * @param overwrite
4399         *              if {@code false}, fails if there's already a file at {@code filePath}
4400         * @param channelId
4401         *              the ID of the channel to upload the file to
4402         * @param channelPassword
4403         *              that channel's password
4404         *
4405         * @throws TS3CommandFailedException
4406         *              if the execution of a command fails
4407         * @throws TS3FileTransferFailedException
4408         *              if the file transfer fails for any reason
4409         * @querycommands 1
4410         * @see FileInfo#getPath()
4411         * @see Channel#getId()
4412         * @see #uploadFileDirect(byte[], String, boolean, int, String)
4413         */
4414        public void uploadFile(InputStream dataIn, long dataLength, String filePath, boolean overwrite, int channelId, String channelPassword) {
4415                asyncApi.uploadFile(dataIn, dataLength, filePath, overwrite, channelId, channelPassword).getUninterruptibly();
4416        }
4417
4418        /**
4419         * Uploads a file that is already stored in memory to the file repository
4420         * at a given path and channel.
4421         *
4422         * @param data
4423         *              the file's data as a byte array
4424         * @param filePath
4425         *              the path the file should have after being uploaded
4426         * @param overwrite
4427         *              if {@code false}, fails if there's already a file at {@code filePath}
4428         * @param channelId
4429         *              the ID of the channel to upload the file to
4430         *
4431         * @throws TS3CommandFailedException
4432         *              if the execution of a command fails
4433         * @throws TS3FileTransferFailedException
4434         *              if the file transfer fails for any reason
4435         * @querycommands 1
4436         * @see FileInfo#getPath()
4437         * @see Channel#getId()
4438         * @see #uploadFile(InputStream, long, String, boolean, int)
4439         */
4440        public void uploadFileDirect(byte[] data, String filePath, boolean overwrite, int channelId) {
4441                asyncApi.uploadFileDirect(data, filePath, overwrite, channelId).getUninterruptibly();
4442        }
4443
4444        /**
4445         * Uploads a file that is already stored in memory to the file repository
4446         * at a given path and channel.
4447         *
4448         * @param data
4449         *              the file's data as a byte array
4450         * @param filePath
4451         *              the path the file should have after being uploaded
4452         * @param overwrite
4453         *              if {@code false}, fails if there's already a file at {@code filePath}
4454         * @param channelId
4455         *              the ID of the channel to upload the file to
4456         * @param channelPassword
4457         *              that channel's password
4458         *
4459         * @throws TS3CommandFailedException
4460         *              if the execution of a command fails
4461         * @throws TS3FileTransferFailedException
4462         *              if the file transfer fails for any reason
4463         * @querycommands 1
4464         * @see FileInfo#getPath()
4465         * @see Channel#getId()
4466         * @see #uploadFile(InputStream, long, String, boolean, int, String)
4467         */
4468        public void uploadFileDirect(byte[] data, String filePath, boolean overwrite, int channelId, String channelPassword) {
4469                asyncApi.uploadFileDirect(data, filePath, overwrite, channelId, channelPassword).getUninterruptibly();
4470        }
4471
4472        /**
4473         * Uploads an icon to the icon directory in the file repository
4474         * by reading {@code dataLength} bytes from an open {@link InputStream}.
4475         * <p>
4476         * It is the user's responsibility to ensure that the given {@code InputStream} is
4477         * open and that {@code dataLength} bytes can eventually be read from it. The user is
4478         * also responsible for closing the stream once the upload has finished.
4479         * </p><p>
4480         * Note that unlike the file upload methods, this <strong>will read the entire file to memory</strong>.
4481         * This is because the CRC32 hash must be calculated before the icon can be uploaded.
4482         * That means that all icon files must be less than 2<sup>31</sup>-1 bytes in size.
4483         * </p>
4484         * Uploads  that is already stored in memory to the icon directory
4485         * in the file repository. If this icon has already been uploaded or
4486         * if a hash collision occurs (CRC32), this command will fail.
4487         *
4488         * @param dataIn
4489         *              a stream that contains the data that should be uploaded
4490         * @param dataLength
4491         *              how many bytes should be read from the stream
4492         *
4493         * @return the ID of the uploaded icon
4494         *
4495         * @throws TS3CommandFailedException
4496         *              if the execution of a command fails
4497         * @throws TS3FileTransferFailedException
4498         *              if the file transfer fails for any reason
4499         * @querycommands 1
4500         * @see IconFile#getIconId()
4501         * @see #uploadIconDirect(byte[])
4502         * @see #downloadIcon(OutputStream, long)
4503         */
4504        public long uploadIcon(InputStream dataIn, long dataLength) {
4505                return asyncApi.uploadIcon(dataIn, dataLength).getUninterruptibly();
4506        }
4507
4508        /**
4509         * Uploads an icon that is already stored in memory to the icon directory
4510         * in the file repository. If this icon has already been uploaded or
4511         * if a CRC32 hash collision occurs, this command will fail.
4512         *
4513         * @param data
4514         *              the icon's data as a byte array
4515         *
4516         * @return the ID of the uploaded icon
4517         *
4518         * @throws TS3CommandFailedException
4519         *              if the execution of a command fails
4520         * @throws TS3FileTransferFailedException
4521         *              if the file transfer fails for any reason
4522         * @querycommands 1
4523         * @see IconFile#getIconId()
4524         * @see #uploadIcon(InputStream, long)
4525         * @see #downloadIconDirect(long)
4526         */
4527        public long uploadIconDirect(byte[] data) {
4528                return asyncApi.uploadIconDirect(data).getUninterruptibly();
4529        }
4530
4531        /**
4532         * Uses an existing privilege key to join a server or channel group.
4533         *
4534         * @param token
4535         *              the privilege key to use
4536         *
4537         * @throws TS3CommandFailedException
4538         *              if the execution of a command fails
4539         * @querycommands 1
4540         * @see PrivilegeKey
4541         * @see #addPrivilegeKey(PrivilegeKeyType, int, int, String)
4542         * @see #usePrivilegeKey(PrivilegeKey)
4543         */
4544        public void usePrivilegeKey(String token) {
4545                asyncApi.usePrivilegeKey(token).getUninterruptibly();
4546        }
4547
4548        /**
4549         * Uses an existing privilege key to join a server or channel group.
4550         *
4551         * @param privilegeKey
4552         *              the privilege key to use
4553         *
4554         * @throws TS3CommandFailedException
4555         *              if the execution of a command fails
4556         * @querycommands 1
4557         * @see PrivilegeKey
4558         * @see #addPrivilegeKey(PrivilegeKeyType, int, int, String)
4559         * @see #usePrivilegeKey(String)
4560         */
4561        public void usePrivilegeKey(PrivilegeKey privilegeKey) {
4562                asyncApi.usePrivilegeKey(privilegeKey).getUninterruptibly();
4563        }
4564
4565        /**
4566         * Gets information about the current server query instance.
4567         *
4568         * @return information about the server query instance
4569         *
4570         * @throws TS3CommandFailedException
4571         *              if the execution of a command fails
4572         * @querycommands 1
4573         * @see #getClientInfo(int)
4574         */
4575        public ServerQueryInfo whoAmI() {
4576                return asyncApi.whoAmI().getUninterruptibly();
4577        }
4578}