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