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