diff --git a/src/main/java/com/github/manevolent/ts3j/api/Ban.java b/src/main/java/com/github/manevolent/ts3j/api/Ban.java new file mode 100644 index 0000000..a84907a --- /dev/null +++ b/src/main/java/com/github/manevolent/ts3j/api/Ban.java @@ -0,0 +1,85 @@ +package com.github.manevolent.ts3j.api; + +/* + * #%L + * TeamSpeak 3 Java API + * %% + * Copyright (C) 2014 Bert De Geyter + * %% + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * #L% + */ + +import java.util.Date; +import java.util.Map; + +public class Ban extends Wrapper { + + public Ban(Map map) { + super(map); + } + + public int getId() { + return getInt("banid"); + } + + public String getBannedIp() { + return get("ip"); + } + + public String getBannedName() { + return get("name"); + } + + public String getBannedUId() { + return get("uid"); + } + + public String getLastNickname() { + return get("lastnickname"); + } + + public Date getCreatedDate() { + return new Date(getLong("created") * 1000); + } + + public long getDuration() { + return getLong("duration"); + } + + public String getInvokerName() { + return get("invokername"); + } + + public int getInvokerClientDBId() { + return getInt("invokercldbid"); + } + + public String getInvokerUId() { + return get("invokeruid"); + } + + public String getReason() { + return get("reason"); + } + + public int getEnforcements() { + return getInt("enforcements"); + } +} diff --git a/src/main/java/com/github/manevolent/ts3j/api/Binding.java b/src/main/java/com/github/manevolent/ts3j/api/Binding.java new file mode 100644 index 0000000..e4100b2 --- /dev/null +++ b/src/main/java/com/github/manevolent/ts3j/api/Binding.java @@ -0,0 +1,41 @@ +package com.github.manevolent.ts3j.api; + +/* + * #%L + * TeamSpeak 3 Java API + * %% + * Copyright (C) 2014 Bert De Geyter + * %% + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * #L% + */ + +import java.util.Map; + +public class Binding extends Wrapper { + + public Binding(Map map) { + super(map); + } + + public String getIp() { + return get("ip"); + } + +} diff --git a/src/main/java/com/github/manevolent/ts3j/api/Channel.java b/src/main/java/com/github/manevolent/ts3j/api/Channel.java new file mode 100644 index 0000000..d0319af --- /dev/null +++ b/src/main/java/com/github/manevolent/ts3j/api/Channel.java @@ -0,0 +1,65 @@ +package com.github.manevolent.ts3j.api; + +/* + * #%L + * TeamSpeak 3 Java API + * %% + * Copyright (C) 2014 Bert De Geyter + * %% + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * #L% + */ + +import java.util.Map; + +public class Channel extends ChannelBase { + + public Channel(Map map) { + super(map); + } + + @Override + public int getId() { + return getInt(ChannelProperty.CID); + } + + public int getTotalClientsFamily() { + return getInt("total_clients_family"); + } + + public int getTotalClients() { + return getInt("total_clients"); + } + + public int getNeededSubscribePower() { + return getInt(ChannelProperty.CHANNEL_NEEDED_SUBSCRIBE_POWER); + } + + /** + * @return {@code true}, if the channel is empty, {@code false} otherwise. + */ + public boolean isEmpty() { + return (getTotalClients() == 0); + } + + @Override + public boolean isFamilyEmpty() { + return (getTotalClientsFamily() == 0); + } +} diff --git a/src/main/java/com/github/manevolent/ts3j/api/ChannelBase.java b/src/main/java/com/github/manevolent/ts3j/api/ChannelBase.java new file mode 100644 index 0000000..a2bd759 --- /dev/null +++ b/src/main/java/com/github/manevolent/ts3j/api/ChannelBase.java @@ -0,0 +1,109 @@ +package com.github.manevolent.ts3j.api; + +/* + * #%L + * TeamSpeak 3 Java API + * %% + * Copyright (C) 2014 - 2015 Bert De Geyter, Roger Baumgartner + * %% + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * #L% + */ + +import java.util.Map; + +public abstract class ChannelBase extends Wrapper { + + protected ChannelBase(Map map) { + super(map); + } + + public abstract int getId(); + + public int getParentChannelId() { + return getInt(ChannelProperty.PID); + } + + public int getOrder() { + return getInt(ChannelProperty.CHANNEL_ORDER); + } + + public String getName() { + return get(ChannelProperty.CHANNEL_NAME); + } + + public String getTopic() { + return get(ChannelProperty.CHANNEL_TOPIC); + } + + public boolean isDefault() { + return getBoolean(ChannelProperty.CHANNEL_FLAG_DEFAULT); + } + + public boolean hasPassword() { + return getBoolean(ChannelProperty.CHANNEL_FLAG_PASSWORD); + } + + public boolean isPermanent() { + return getBoolean(ChannelProperty.CHANNEL_FLAG_PERMANENT); + } + + public boolean isSemiPermanent() { + return getBoolean(ChannelProperty.CHANNEL_FLAG_SEMI_PERMANENT); + } + + public Codec getCodec() { + final int codec = getInt(ChannelProperty.CHANNEL_CODEC); + for (final Codec c : Codec.values()) { + if (c.getIndex() == codec) { + return c; + } + } + return Codec.UNKNOWN; + } + + public int getCodecQuality() { + return getInt(ChannelProperty.CHANNEL_CODEC_QUALITY); + } + + public int getNeededTalkPower() { + return getInt(ChannelProperty.CHANNEL_NEEDED_TALK_POWER); + } + + public long getIconId() { + return getLong(ChannelProperty.CHANNEL_ICON_ID); + } + + public int getMaxClients() { + return getInt(ChannelProperty.CHANNEL_MAXCLIENTS); + } + + public int getMaxFamilyClients() { + return getInt(ChannelProperty.CHANNEL_MAXFAMILYCLIENTS); + } + + public int getSecondsEmpty() { + return getInt(ChannelProperty.SECONDS_EMPTY); + } + + /** + * @return {@code true}, if the channel and all child channels are empty, {@code false} otherwise. + */ + abstract public boolean isFamilyEmpty(); +} diff --git a/src/main/java/com/github/manevolent/ts3j/api/ChannelGroup.java b/src/main/java/com/github/manevolent/ts3j/api/ChannelGroup.java new file mode 100644 index 0000000..40b2bac --- /dev/null +++ b/src/main/java/com/github/manevolent/ts3j/api/ChannelGroup.java @@ -0,0 +1,83 @@ +package com.github.manevolent.ts3j.api; + +/* + * #%L + * TeamSpeak 3 Java API + * %% + * Copyright (C) 2014 Bert De Geyter + * %% + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * #L% + */ + +import java.util.Map; + +public class ChannelGroup extends Wrapper { + + public ChannelGroup(Map map) { + super(map); + } + + public int getId() { + return getInt("cgid"); + } + + public String getName() { + return get("name"); + } + + public PermissionGroupDatabaseType getType() { + final int type = getInt("type"); + for (final PermissionGroupDatabaseType t : PermissionGroupDatabaseType.values()) { + if (t.getIndex() == type) { + return t; + } + } + return null; + } + + public long getIconId() { + return getLong("iconid"); + } + + public boolean isSavedInDatabase() { + return getBoolean("savedb"); + } + + public int getSortId() { + return getInt("sortid"); + } + + public int getNameMode() { + return getInt("namemode"); + } + + public int getModifyPower() { + return getInt("n_modifyp"); + } + + public int getMemberAddPower() { + return getInt("n_member_addp"); + } + + public int getMemberRemovePower() { + return getInt("n_member_removep"); + } + +} diff --git a/src/main/java/com/github/manevolent/ts3j/api/ChannelGroupClient.java b/src/main/java/com/github/manevolent/ts3j/api/ChannelGroupClient.java new file mode 100644 index 0000000..814cc8c --- /dev/null +++ b/src/main/java/com/github/manevolent/ts3j/api/ChannelGroupClient.java @@ -0,0 +1,49 @@ +package com.github.manevolent.ts3j.api; + +/* + * #%L + * TeamSpeak 3 Java API + * %% + * Copyright (C) 2014 Bert De Geyter + * %% + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * #L% + */ + +import java.util.Map; + +public class ChannelGroupClient extends Wrapper { + + public ChannelGroupClient(Map map) { + super(map); + } + + public int getChannelId() { + return getInt("cid"); + } + + public int getClientDatabaseId() { + return getInt("cldbid"); + } + + public int getChannelGroupId() { + return getInt("cgid"); + } + +} diff --git a/src/main/java/com/github/manevolent/ts3j/api/ChannelInfo.java b/src/main/java/com/github/manevolent/ts3j/api/ChannelInfo.java new file mode 100644 index 0000000..70e8eb6 --- /dev/null +++ b/src/main/java/com/github/manevolent/ts3j/api/ChannelInfo.java @@ -0,0 +1,89 @@ +package com.github.manevolent.ts3j.api; + +/* + * #%L + * TeamSpeak 3 Java API + * %% + * Copyright (C) 2014 Bert De Geyter + * %% + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * #L% + */ + +import java.util.Map; + +public class ChannelInfo extends ChannelBase { + + private final int channelId; + + public ChannelInfo(int channelId, Map map) { + super(map); + this.channelId = channelId; + } + + @Override + public int getId() { + return channelId; + } + + public String getDescription() { + return get(ChannelProperty.CHANNEL_DESCRIPTION); + } + + public String getPassword() { + return get(ChannelProperty.CHANNEL_PASSWORD); + } + + public int getCodecLatencyFactor() { + return getInt(ChannelProperty.CHANNEL_CODEC_LATENCY_FACTOR); + } + + public boolean isEncrypted() { + return !getBoolean(ChannelProperty.CHANNEL_CODEC_IS_UNENCRYPTED); + } + + public boolean hasUnlimitedClients() { + return getBoolean(ChannelProperty.CHANNEL_FLAG_MAXCLIENTS_UNLIMITED); + } + + public boolean hasUnlimitedFamilyClients() { + return getBoolean(ChannelProperty.CHANNEL_FLAG_MAXFAMILYCLIENTS_UNLIMITED); + } + + public boolean hasInheritedMaxFamilyClients() { + return getBoolean(ChannelProperty.CHANNEL_FLAG_MAXFAMILYCLIENTS_INHERITED); + } + + public String getFilePath() { + return get(ChannelProperty.CHANNEL_FILEPATH); + } + + public boolean isForcedSilence() { + return getBoolean(ChannelProperty.CHANNEL_FORCED_SILENCE); + } + + public String getPhoneticName() { + return get(ChannelProperty.CHANNEL_NAME_PHONETIC); + } + + @Override + public boolean isFamilyEmpty() { + return (getSecondsEmpty() >= 0); + } +} diff --git a/src/main/java/com/github/manevolent/ts3j/api/ChannelProperty.java b/src/main/java/com/github/manevolent/ts3j/api/ChannelProperty.java new file mode 100644 index 0000000..408dc1a --- /dev/null +++ b/src/main/java/com/github/manevolent/ts3j/api/ChannelProperty.java @@ -0,0 +1,79 @@ +package com.github.manevolent.ts3j.api; + +/* + * #%L + * TeamSpeak 3 Java API + * %% + * Copyright (C) 2014 Bert De Geyter + * %% + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * #L% + */ + +import java.util.Locale; + +public enum ChannelProperty implements Property { + + CHANNEL_CODEC(true), + CHANNEL_CODEC_IS_UNENCRYPTED(true), + CHANNEL_CODEC_LATENCY_FACTOR(false), + CHANNEL_CODEC_QUALITY(true), + CHANNEL_DELETE_DELAY(true), + CHANNEL_DESCRIPTION(true), + CHANNEL_FILEPATH(false), + CHANNEL_FLAG_DEFAULT(true), + CHANNEL_FLAG_MAXCLIENTS_UNLIMITED(true), + CHANNEL_FLAG_MAXFAMILYCLIENTS_INHERITED(true), + CHANNEL_FLAG_MAXFAMILYCLIENTS_UNLIMITED(true), + CHANNEL_FLAG_PASSWORD(false), + CHANNEL_FLAG_PERMANENT(true), + CHANNEL_FLAG_SEMI_PERMANENT(true), + CHANNEL_FLAG_TEMPORARY(true), + CHANNEL_FORCED_SILENCE(false), + CHANNEL_ICON_ID(true), + CHANNEL_MAXCLIENTS(true), + CHANNEL_MAXFAMILYCLIENTS(true), + CHANNEL_NAME(true), + CHANNEL_NAME_PHONETIC(true), + CHANNEL_NEEDED_SUBSCRIBE_POWER(false), + CHANNEL_NEEDED_TALK_POWER(true), + CHANNEL_ORDER(true), + CHANNEL_PASSWORD(true), + CHANNEL_TOPIC(true), + SECONDS_EMPTY(false), + CID(false), + PID(false), + CPID(true); + + private final boolean changeable; + + ChannelProperty(boolean changeable) { + this.changeable = changeable; + } + + @Override + public String getName() { + return name().toLowerCase(Locale.ROOT); + } + + @Override + public boolean isChangeable() { + return changeable; + } +} diff --git a/src/main/java/com/github/manevolent/ts3j/api/Client.java b/src/main/java/com/github/manevolent/ts3j/api/Client.java new file mode 100644 index 0000000..4909e59 --- /dev/null +++ b/src/main/java/com/github/manevolent/ts3j/api/Client.java @@ -0,0 +1,243 @@ +package com.github.manevolent.ts3j.api; + +/* + * #%L + * TeamSpeak 3 Java API + * %% + * Copyright (C) 2014 Bert De Geyter + * %% + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * #L% + */ + +import java.io.UnsupportedEncodingException; +import java.net.URLEncoder; +import java.util.Date; +import java.util.Map; + +public class Client extends Wrapper { + + public Client(Map map) { + super(map); + } + + public boolean canTalk() { + return getBoolean(ClientProperty.CLIENT_IS_TALKER); + } + + public String getAwayMessage() { + return get(ClientProperty.CLIENT_AWAY_MESSAGE); + } + + public String[] getBadgeGUIDs() { + String raw = get(ClientProperty.CLIENT_BADGES); + String[] properties = raw.split("[\\s:;]"); + for (String property : properties) { + if (!property.startsWith("badges=")) continue; + String commaSepBadges = property.substring("badges=".length()); + return commaSepBadges.split(","); + } + return new String[0]; + } + + public int getChannelGroupId() { + return getInt(ClientProperty.CLIENT_CHANNEL_GROUP_ID); + } + + public int getChannelId() { + return getInt(ClientProperty.CID); + } + + /** + * Utility method. This method will return a client URI. + * A client URI can be used to reference a client in descriptions or just via chat. + * Example: {@code client:///~} + * + * @return Client's URI + */ + public String getClientURI() { + StringBuilder sb = new StringBuilder(); + sb.append("client://").append(getId()).append('/'); + sb.append(getUniqueIdentifier()).append('~'); + try { + // We will encode the nickname, so characters like spaces work with this. + sb.append(URLEncoder.encode(getNickname(), "UTF-8")); + } catch (UnsupportedEncodingException e) { + throw new IllegalStateException("JVM doesn't support UTF-8", e); + } + return sb.toString(); + } + + public String getCountry() { + return get(ClientProperty.CLIENT_COUNTRY); + } + + public Date getCreatedDate() { + return new Date(getLong(ClientProperty.CLIENT_CREATED) * 1000); + } + + public int getDatabaseId() { + return getInt(ClientProperty.CLIENT_DATABASE_ID); + } + + public long getIconId() { + return getLong(ClientProperty.CLIENT_ICON_ID); + } + + public int getId() { + return getInt("clid"); + } + + public long getIdleTime() { + return getLong(ClientProperty.CLIENT_IDLE_TIME); + } + + public int getInheritedChannelGroupId() { + return getInt(ClientProperty.CLIENT_CHANNEL_GROUP_INHERITED_CHANNEL_ID); + } + + public String getIp() { + return get(ClientProperty.CONNECTION_CLIENT_IP); + } + + public Date getLastConnectedDate() { + return new Date(getLong(ClientProperty.CLIENT_LASTCONNECTED) * 1000); + } + + public String getNickname() { + return get(ClientProperty.CLIENT_NICKNAME); + } + + public String getPlatform() { + return get(ClientProperty.CLIENT_PLATFORM); + } + + public int[] getServerGroups() { + final String str = get(ClientProperty.CLIENT_SERVERGROUPS); + final String[] arr = str.split(","); + final int[] groups = new int[arr.length]; + for (int i = 0; i < groups.length; i++) { + groups[i] = Integer.parseInt(arr[i]); + } + return groups; + } + + public int getTalkPower() { + return getInt(ClientProperty.CLIENT_TALK_POWER); + } + + public int getType() { + return getInt(ClientProperty.CLIENT_TYPE); + } + + public String getUniqueIdentifier() { + return get(ClientProperty.CLIENT_UNIQUE_IDENTIFIER); + } + + public String getVersion() { + return get(ClientProperty.CLIENT_VERSION); + } + + public boolean hasOverwolf() { + String raw = get(ClientProperty.CLIENT_BADGES); + String[] properties = raw.split("[\\s:;]"); + for (String property : properties) { + if (!(property.startsWith("overwolf=") || property.startsWith("Overwolf="))) continue; + String overwolfValue = property.substring("overwolf=".length()); + return overwolfValue.equals("1"); + } + return false; + } + + public boolean isAway() { + return getBoolean(ClientProperty.CLIENT_AWAY); + } + + public boolean isChannelCommander() { + return getBoolean(ClientProperty.CLIENT_IS_CHANNEL_COMMANDER); + } + + /** + * Utility method that does a linear search on the array of server group IDs returned + * by {@link #getServerGroups()} and returns {@code true} if that array contains + * the given server group ID. + * + * @param serverGroupId + * the ID of the server group to search for + * + * @return whether this client is a member of the given server group + */ + public boolean isInServerGroup(int serverGroupId) { + int[] serverGroupIds = getServerGroups(); + for (int s : serverGroupIds) { + if (s == serverGroupId) return true; + } + return false; + } + + /** + * Utility method that does a linear search on the array of server group IDs returned + * by {@link #getServerGroups()} and returns {@code true} if that array contains + * the ID of the given server group. + * + * @param serverGroup + * the server group to search for + * + * @return whether this client is a member of the given server group + */ + public boolean isInServerGroup(ServerGroup serverGroup) { + return isInServerGroup(serverGroup.getId()); + } + + public boolean isInputHardware() { + return getBoolean(ClientProperty.CLIENT_INPUT_HARDWARE); + } + + public boolean isInputMuted() { + return getBoolean(ClientProperty.CLIENT_INPUT_MUTED); + } + + public boolean isOutputHardware() { + return getBoolean(ClientProperty.CLIENT_OUTPUT_HARDWARE); + } + + public boolean isOutputMuted() { + return getBoolean(ClientProperty.CLIENT_OUTPUT_MUTED); + } + + public boolean isPrioritySpeaker() { + return getBoolean(ClientProperty.CLIENT_IS_PRIORITY_SPEAKER); + } + + public boolean isRecording() { + return getBoolean(ClientProperty.CLIENT_IS_RECORDING); + } + + public boolean isRegularClient() { + return getType() == 0; + } + + public boolean isServerQueryClient() { + return getType() == 1; + } + + public boolean isTalking() { + return getBoolean(ClientProperty.CLIENT_FLAG_TALKING); + } +} diff --git a/src/main/java/com/github/manevolent/ts3j/api/ClientInfo.java b/src/main/java/com/github/manevolent/ts3j/api/ClientInfo.java new file mode 100644 index 0000000..29299e2 --- /dev/null +++ b/src/main/java/com/github/manevolent/ts3j/api/ClientInfo.java @@ -0,0 +1,167 @@ +package com.github.manevolent.ts3j.api; + +/* + * #%L + * TeamSpeak 3 Java API + * %% + * Copyright (C) 2014 Bert De Geyter + * %% + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * #L% + */ +import java.util.Map; + +public class ClientInfo extends Client { + + private final int clientId; + + public ClientInfo(int clientId, Map map) { + super(map); + this.clientId = clientId; + } + + @Override + public int getId() { + return clientId; + } + + public String getAvatar() { + return get(ClientProperty.CLIENT_FLAG_AVATAR); + } + + public long getBandwidthReceivedLastMinute() { + return getLong(ClientProperty.CONNECTION_BANDWIDTH_RECEIVED_LAST_MINUTE_TOTAL); + } + + public long getBandwidthReceivedLastSecond() { + return getLong(ClientProperty.CONNECTION_BANDWIDTH_RECEIVED_LAST_SECOND_TOTAL); + } + + public long getBandwidthSentlastMinute() { + return getLong(ClientProperty.CONNECTION_BANDWIDTH_SENT_LAST_MINUTE_TOTAL); + } + + public long getBandwidthSentLastSecond() { + return getLong(ClientProperty.CONNECTION_BANDWIDTH_SENT_LAST_SECOND_TOTAL); + } + + public String getBase64ClientUId() { + return get("client_base64HashClientUID"); + } + + public int getDefaultChannel() { + // TeamSpeak decided to prefix the channel ID with a forward slash (/)... + final String channelId = get(ClientProperty.CLIENT_DEFAULT_CHANNEL); + if (channelId.isEmpty()) return -1; + return Integer.parseInt(channelId.substring(1)); + } + + public String getDefaultToken() { + return get(ClientProperty.CLIENT_DEFAULT_TOKEN); + } + + public String getDescription() { + return get(ClientProperty.CLIENT_DESCRIPTION); + } + + public long getFiletransferBandwidthReceived() { + return getLong(ClientProperty.CONNECTION_FILETRANSFER_BANDWIDTH_RECEIVED); + } + + public long getFiletransferBandwidthSent() { + return getLong(ClientProperty.CONNECTION_FILETRANSFER_BANDWIDTH_SENT); + } + + public String getLoginName() { + return get(ClientProperty.CLIENT_LOGIN_NAME); + } + + public String getMetaData() { + return get(ClientProperty.CLIENT_META_DATA); + } + + public long getMonthlyBytesDownloaded() { + return getLong(ClientProperty.CLIENT_MONTH_BYTES_DOWNLOADED); + } + + public long getMonthlyBytesUploaded() { + return getLong(ClientProperty.CLIENT_MONTH_BYTES_UPLOADED); + } + + public int getNeededServerQueryViewPower() { + return getInt(ClientProperty.CLIENT_NEEDED_SERVERQUERY_VIEW_POWER); + } + + public String getPhoneticNickname() { + return get(ClientProperty.CLIENT_NICKNAME_PHONETIC); + } + + public String getTalkRequestMessage() { + return get(ClientProperty.CLIENT_TALK_REQUEST_MSG); + } + + public long getTimeConnected() { // milliseconds + return getLong(ClientProperty.CONNECTION_CONNECTED_TIME); + } + + public long getTotalBytesDownloaded() { + return getLong(ClientProperty.CLIENT_TOTAL_BYTES_DOWNLOADED); + } + + public long getTotalBytesReceived() { + return getLong(ClientProperty.CONNECTION_BYTES_RECEIVED_TOTAL); + } + + public long getTotalBytesSent() { + return getLong(ClientProperty.CONNECTION_BYTES_SENT_TOTAL); + } + + public long getTotalBytesUploaded() { + return getLong(ClientProperty.CLIENT_TOTAL_BYTES_UPLOADED); + } + + public int getTotalConnections() { + return getInt(ClientProperty.CLIENT_TOTALCONNECTIONS); + } + + public long getTotalPacketsReceived() { + return getLong(ClientProperty.CONNECTION_PACKETS_RECEIVED_TOTAL); + } + + public long getTotalPacketsSent() { + return getLong(ClientProperty.CONNECTION_PACKETS_SENT_TOTAL); + } + + public int getUnreadMessages() { + return getInt(ClientProperty.CLIENT_UNREAD_MESSAGES); + } + + public boolean isOutputOnlyMuted() { + return getBoolean(ClientProperty.CLIENT_OUTPUTONLY_MUTED); + } + + public boolean isRequestingToTalk() { + return getBoolean(ClientProperty.CLIENT_TALK_REQUEST); + } + + @Override + public boolean isTalking() { + throw new UnsupportedOperationException(); + } +} diff --git a/src/main/java/com/github/manevolent/ts3j/api/ClientProperty.java b/src/main/java/com/github/manevolent/ts3j/api/ClientProperty.java new file mode 100644 index 0000000..922df02 --- /dev/null +++ b/src/main/java/com/github/manevolent/ts3j/api/ClientProperty.java @@ -0,0 +1,116 @@ +package com.github.manevolent.ts3j.api; + +/* + * #%L + * TeamSpeak 3 Java API + * %% + * Copyright (C) 2014 Bert De Geyter + * %% + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * #L% + */ + +import java.util.Locale; +import java.util.Map; + +public enum ClientProperty implements Property { + + CID(false), + CLIENT_AWAY(false), + CLIENT_AWAY_MESSAGE(false), + /** + * Property for the Overwolf badge and any myTeamSpeak badges. + * Can be changed only for the own client by using {@link TS3Api#updateClient(Map)}. + *

+ * String format: {@code overwolf=n:badges=guid,guid,guid(,guid...)}
+ * where {@code n} is 0 or 1 and {@code guid} is 128-bit badge GUIDs + *

+ */ + CLIENT_BADGES(true), + CLIENT_BASE64HASHCLIENTUID(false), + CLIENT_CHANNEL_GROUP_ID(false), + CLIENT_CHANNEL_GROUP_INHERITED_CHANNEL_ID(false), + CLIENT_COUNTRY(false), + CLIENT_CREATED(false), + CLIENT_DATABASE_ID(false), + CLIENT_DEFAULT_CHANNEL(false), + CLIENT_DEFAULT_TOKEN(false), + CLIENT_DESCRIPTION(true), + CLIENT_FLAG_AVATAR(false), + CLIENT_FLAG_TALKING(false), + CLIENT_ICON_ID(true), + CLIENT_IDLE_TIME(false), + CLIENT_INPUT_HARDWARE(false), + CLIENT_INPUT_MUTED(false), + CLIENT_IS_CHANNEL_COMMANDER(true), + CLIENT_IS_PRIORITY_SPEAKER(false), + CLIENT_IS_RECORDING(false), + CLIENT_IS_TALKER(true), + CLIENT_LASTCONNECTED(false), + CLIENT_LOGIN_NAME(false), + CLIENT_META_DATA(false), + CLIENT_MONTH_BYTES_DOWNLOADED(false), + CLIENT_MONTH_BYTES_UPLOADED(false), + CLIENT_NEEDED_SERVERQUERY_VIEW_POWER(false), + CLIENT_NICKNAME(true), + CLIENT_NICKNAME_PHONETIC(false), + CLIENT_OUTPUT_HARDWARE(false), + CLIENT_OUTPUT_MUTED(false), + CLIENT_OUTPUTONLY_MUTED(false), + CLIENT_PLATFORM(false), + CLIENT_SERVERGROUPS(false), + CLIENT_TALK_POWER(false), + CLIENT_TALK_REQUEST(false), + CLIENT_TALK_REQUEST_MSG(false), + CLIENT_TOTAL_BYTES_DOWNLOADED(false), + CLIENT_TOTAL_BYTES_UPLOADED(false), + CLIENT_TOTALCONNECTIONS(false), + CLIENT_TYPE(false), + CLIENT_UNIQUE_IDENTIFIER(false), + CLIENT_UNREAD_MESSAGES(false), + CLIENT_VERSION(false), + CONNECTION_BANDWIDTH_RECEIVED_LAST_MINUTE_TOTAL(false), + CONNECTION_BANDWIDTH_RECEIVED_LAST_SECOND_TOTAL(false), + CONNECTION_BANDWIDTH_SENT_LAST_MINUTE_TOTAL(false), + CONNECTION_BANDWIDTH_SENT_LAST_SECOND_TOTAL(false), + CONNECTION_BYTES_RECEIVED_TOTAL(false), + CONNECTION_BYTES_SENT_TOTAL(false), + CONNECTION_CLIENT_IP(false), + CONNECTION_CONNECTED_TIME(false), + CONNECTION_FILETRANSFER_BANDWIDTH_RECEIVED(false), + CONNECTION_FILETRANSFER_BANDWIDTH_SENT(false), + CONNECTION_PACKETS_RECEIVED_TOTAL(false), + CONNECTION_PACKETS_SENT_TOTAL(false); + + private final boolean changeable; + + ClientProperty(boolean changeable) { + this.changeable = changeable; + } + + @Override + public String getName() { + return name().toLowerCase(Locale.ROOT); + } + + @Override + public boolean isChangeable() { + return changeable; + } +} diff --git a/src/main/java/com/github/manevolent/ts3j/api/Codec.java b/src/main/java/com/github/manevolent/ts3j/api/Codec.java new file mode 100644 index 0000000..0623229 --- /dev/null +++ b/src/main/java/com/github/manevolent/ts3j/api/Codec.java @@ -0,0 +1,130 @@ +package com.github.manevolent.ts3j.api; + +/* + * #%L + * TeamSpeak 3 Java API + * %% + * Copyright (C) 2014 Bert De Geyter + * %% + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * #L% + */ + +import java.util.Map; + +/** + * Voice codecs currently used by TeamSpeak3. + *

+ * A channel's codec may be edited by using {@link TS3Api#editChannel(int, Map)}. + * All voice data may also be encrypted. + *

+ */ +public enum Codec { + + /** + * The Speex narrowband codec with a sampling rate of 8kHz. + *

+ * All Speex codecs are basically obsolete as Opus is better + * in every aspect and has a comparable required bandwidth. + *

    + *
  • Bandwidth per client with codec quality 0: 2.49 KiB/s
  • + *
  • Bandwidth per client with codec quality 10: 5.22 KiB/s
  • + *
+ */ + SPEEX_NARROWBAND(0), + + /** + * The Speex wideband codec with a sampling rate of 16kHz. + *

+ * All Speex codecs are basically obsolete as Opus is better + * in every aspect and has a comparable required bandwidth. + *

    + *
  • Bandwidth per client with codec quality 0: 2.69 KiB/s
  • + *
  • Bandwidth per client with codec quality 10: 7.37 KiB/s
  • + *
+ */ + SPEEX_WIDEBAND(1), + + /** + * The Speex ultra-wideband codec with a sampling rate of 32kHz. + *

+ * All Speex codecs are basically obsolete as Opus is better + * in every aspect and has a comparable required bandwidth. + *

    + *
  • Bandwidth per client with codec quality 0: 2.73 KiB/s
  • + *
  • Bandwidth per client with codec quality 10: 7.57 KiB/s
  • + *
+ */ + SPEEX_ULTRAWIDEBAND(2), + + /** + * The CELT Mono codec. It is optimised for music but still generates very good + * results in voice transmission. + *

+ * Note that this codec requires the most bandwidth of all currently available codecs. + *

    + *
  • Bandwidth per client with codec quality 0: 6.10 KiB/s
  • + *
  • Bandwidth per client with codec quality 10: 13.92 KiB/s
  • + *
+ */ + CELT_MONO(3), + + /** + * The Opus codec optimised for voice transmission. + *

+ * This is the default codec used by TeamSpeak and usually achieves the + * best results for voice transmission. + *

    + *
  • Bandwidth per client with codec quality 0: 2.73 KiB/s
  • + *
  • Bandwidth per client with codec quality 10: 7.71 KiB/s
  • + *
+ */ + OPUS_VOICE(4), + + /** + * The Opus codec optimised for music transmission. + *

+ * Please note that if used only to transmit speech, this codec can + * sound worse than Opus Voice despite a higher bandwidth. + *

    + *
  • Bandwidth per client with codec quality 0: 3.08 KiB/s
  • + *
  • Bandwidth per client with codec quality 10: 11.87 KiB/s
  • + *
+ */ + OPUS_MUSIC(5), + + /** + * An unknown codec. + *

+ * If you ever encounter an unknown codec, please tell us! + * We may have to update the API. + *

+ */ + UNKNOWN(-1); + + private final int i; + + Codec(int i) { + this.i = i; + } + + public int getIndex() { + return i; + } +} diff --git a/src/main/java/com/github/manevolent/ts3j/api/CodecEncryptionMode.java b/src/main/java/com/github/manevolent/ts3j/api/CodecEncryptionMode.java new file mode 100644 index 0000000..73afca8 --- /dev/null +++ b/src/main/java/com/github/manevolent/ts3j/api/CodecEncryptionMode.java @@ -0,0 +1,74 @@ +package com.github.manevolent.ts3j.api; + +/* + * #%L + * TeamSpeak 3 Java API + * %% + * Copyright (C) 2014 Bert De Geyter + * %% + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * #L% + */ + +import java.util.Map; + +/** + * Describes how the virtual server manages audio encryption. + *

+ * Can be edited with {@link TS3Api#editServer(Map)}. + *

+ */ +public enum CodecEncryptionMode { + + /** + * Each channel manages audio encryption on its own. + * + * @see TS3Api#editChannel(int, Map) + */ + CODEC_CRYPT_INDIVIDUAL(0), + + /** + * Audio encryption is globally disabled on this virtual server. + */ + CODEC_CRYPT_DISABLED(1), + + /** + * Audio encryption is globally enabled on this virtual server. + */ + CODEC_CRYPT_ENABLED(2), + + /** + * An unknown codec encryption mode. + *

+ * If you ever encounter an unknown mode, please tell us! + * We may have to update the API. + *

+ */ + UNKNOWN(-1); + + private final int i; + + CodecEncryptionMode(int i) { + this.i = i; + } + + public int getIndex() { + return i; + } +} diff --git a/src/main/java/com/github/manevolent/ts3j/api/Complaint.java b/src/main/java/com/github/manevolent/ts3j/api/Complaint.java new file mode 100644 index 0000000..155d64e --- /dev/null +++ b/src/main/java/com/github/manevolent/ts3j/api/Complaint.java @@ -0,0 +1,62 @@ +package com.github.manevolent.ts3j.api; + +/* + * #%L + * TeamSpeak 3 Java API + * %% + * Copyright (C) 2014 Bert De Geyter + * %% + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * #L% + */ + +import java.util.Date; +import java.util.Map; + +public class Complaint extends Wrapper { + + public Complaint(Map map) { + super(map); + } + + public int getTargetClientDatabaseId() { + return getInt("tcldbid"); + } + + public String getTargetName() { + return get("tname"); + } + + public int getSourceClientDatabaseId() { + return getInt("fcldbid"); + } + + public String getSourceName() { + return get("fname"); + } + + public String getMessage() { + return get("message"); + } + + public Date getTimestamp() { + return new Date(getLong("timestamp") * 1000); + } + +} diff --git a/src/main/java/com/github/manevolent/ts3j/api/ConnectionInfo.java b/src/main/java/com/github/manevolent/ts3j/api/ConnectionInfo.java new file mode 100644 index 0000000..d1c9d0d --- /dev/null +++ b/src/main/java/com/github/manevolent/ts3j/api/ConnectionInfo.java @@ -0,0 +1,97 @@ +package com.github.manevolent.ts3j.api; + +/* + * #%L + * TeamSpeak 3 Java API + * %% + * Copyright (C) 2014 Bert De Geyter + * %% + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * #L% + */ + +import java.util.Map; + +public class ConnectionInfo extends Wrapper { + + public ConnectionInfo(Map map) { + super(map); + } + + public long getFiletransferBandwidthSent() { + return getLong(VirtualServerProperty.CONNECTION_FILETRANSFER_BANDWIDTH_SENT); + } + + public long getFiletransferBandwidthReceived() { + return getLong(VirtualServerProperty.CONNECTION_FILETRANSFER_BANDWIDTH_RECEIVED); + } + + public long getFiletransferBytesSent() { + return getLong(VirtualServerProperty.CONNECTION_FILETRANSFER_BYTES_SENT_TOTAL); + } + + public long getFiletransferBytesReceived() { + return getLong(VirtualServerProperty.CONNECTION_FILETRANSFER_BYTES_RECEIVED_TOTAL); + } + + public long getTotalPacketsSent() { + return getLong(VirtualServerProperty.CONNECTION_PACKETS_SENT_TOTAL); + } + + public long getTotalBytesSent() { + return getLong(VirtualServerProperty.CONNECTION_BYTES_SENT_TOTAL); + } + + public long getTotalPacketsReceived() { + return getLong(VirtualServerProperty.CONNECTION_PACKETS_RECEIVED_TOTAL); + } + + public long getTotalBytesReceived() { + return getLong(VirtualServerProperty.CONNECTION_BYTES_RECEIVED_TOTAL); + } + + public long getBandwidthSentLastSecond() { + return getLong(VirtualServerProperty.CONNECTION_BANDWIDTH_SENT_LAST_SECOND_TOTAL); + } + + public long getBandwidthSentLastMinute() { + return getLong(VirtualServerProperty.CONNECTION_BANDWIDTH_SENT_LAST_MINUTE_TOTAL); + } + + public long getBandwidthReceivedLastSecond() { + return getLong(VirtualServerProperty.CONNECTION_BANDWIDTH_RECEIVED_LAST_SECOND_TOTAL); + } + + public long getBandwidthReceivedLastMinute() { + return getLong(VirtualServerProperty.CONNECTION_BANDWIDTH_RECEIVED_LAST_MINUTE_TOTAL); + } + + public long getConnectedTime() { + return getLong("connection_connected_time"); + } + + public double getPacketLoss() { + return getDouble("connection_packetloss_total"); + } + + public double getPing() { + return getDouble("connection_ping"); + } + +} diff --git a/src/main/java/com/github/manevolent/ts3j/api/CreatedVirtualServer.java b/src/main/java/com/github/manevolent/ts3j/api/CreatedVirtualServer.java new file mode 100644 index 0000000..a6993e5 --- /dev/null +++ b/src/main/java/com/github/manevolent/ts3j/api/CreatedVirtualServer.java @@ -0,0 +1,48 @@ +package com.github.manevolent.ts3j.api; + +/* + * #%L + * TeamSpeak 3 Java API + * %% + * Copyright (C) 2014 Bert De Geyter + * %% + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * #L% + */ + +import java.util.Map; + +public class CreatedVirtualServer extends Wrapper { + + public CreatedVirtualServer(Map map) { + super(map); + } + + public int getId() { + return getInt("sid"); + } + + public int getPort() { + return getInt("virtualserver_port"); + } + + public String getServerAdminToken() { + return get("token"); + } +} diff --git a/src/main/java/com/github/manevolent/ts3j/api/DatabaseClient.java b/src/main/java/com/github/manevolent/ts3j/api/DatabaseClient.java new file mode 100644 index 0000000..ce7dd98 --- /dev/null +++ b/src/main/java/com/github/manevolent/ts3j/api/DatabaseClient.java @@ -0,0 +1,69 @@ +package com.github.manevolent.ts3j.api; + +/* + * #%L + * TeamSpeak 3 Java API + * %% + * Copyright (C) 2014 Bert De Geyter + * %% + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * #L% + */ + +import java.util.Date; +import java.util.Map; + +public class DatabaseClient extends Wrapper { + + public DatabaseClient(Map map) { + super(map); + } + + public int getDatabaseId() { + return getInt("cldbid"); + } + + public String getUniqueIdentifier() { + return get(ClientProperty.CLIENT_UNIQUE_IDENTIFIER); + } + + public String getNickname() { + return get(ClientProperty.CLIENT_NICKNAME); + } + + public Date getCreatedDate() { + return new Date(getLong(ClientProperty.CLIENT_CREATED) * 1000); + } + + public Date getLastConnectedDate() { + return new Date(getLong(ClientProperty.CLIENT_LASTCONNECTED) * 1000); + } + + public int getTotalConnections() { + return getInt(ClientProperty.CLIENT_TOTALCONNECTIONS); + } + + public String getDescription() { + return get(ClientProperty.CLIENT_DESCRIPTION); + } + + public String getLastIp() { + return get("client_lastip"); + } +} diff --git a/src/main/java/com/github/manevolent/ts3j/api/DatabaseClientInfo.java b/src/main/java/com/github/manevolent/ts3j/api/DatabaseClientInfo.java new file mode 100644 index 0000000..9b0669a --- /dev/null +++ b/src/main/java/com/github/manevolent/ts3j/api/DatabaseClientInfo.java @@ -0,0 +1,69 @@ +package com.github.manevolent.ts3j.api; + +/* + * #%L + * TeamSpeak 3 Java API + * %% + * Copyright (C) 2014 Bert De Geyter + * %% + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * #L% + */ + +import java.util.Map; + +public class DatabaseClientInfo extends DatabaseClient { + + public DatabaseClientInfo(Map map) { + super(map); + } + + @Override + public int getDatabaseId() { + return getInt(ClientProperty.CLIENT_DATABASE_ID); + } + + public String getAvatar() { + return get(ClientProperty.CLIENT_FLAG_AVATAR); + } + + public long getMonthlyBytesUploaded() { + return getLong(ClientProperty.CLIENT_MONTH_BYTES_UPLOADED); + } + + public long getMonthlyBytesDownloaded() { + return getLong(ClientProperty.CLIENT_MONTH_BYTES_DOWNLOADED); + } + + public long getTotalBytesUploaded() { + return getLong(ClientProperty.CLIENT_TOTAL_BYTES_UPLOADED); + } + + public long getTotalBytesDownloaded() { + return getLong(ClientProperty.CLIENT_TOTAL_BYTES_DOWNLOADED); + } + + public long getIconId() { + return getLong(ClientProperty.CLIENT_ICON_ID); + } + + public String getBase64HashClientUID() { + return get("client_base64HashClientUID"); + } +} diff --git a/src/main/java/com/github/manevolent/ts3j/api/FileInfo.java b/src/main/java/com/github/manevolent/ts3j/api/FileInfo.java new file mode 100644 index 0000000..0d407af --- /dev/null +++ b/src/main/java/com/github/manevolent/ts3j/api/FileInfo.java @@ -0,0 +1,134 @@ +package com.github.manevolent.ts3j.api; + +/* + * #%L + * TeamSpeak 3 Java API + * %% + * Copyright (C) 2016 Bert De Geyter, Roger Baumgartner + * %% + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * #L% + */ + +import java.util.Date; +import java.util.Map; + +public class FileInfo extends Wrapper { + + public FileInfo(Map map) { + super(map); + } + + /** + * Gets the ID of the channel this file is stored on. + * + * @return the ID of the file's channel + */ + public int getChannelId() { + return getInt("cid"); + } + + /** + * Gets the path to this file or directory, including its name. + * This path can be used in other file transfer commands. + * + * @return the path to the file or directory + */ + public String getPath() { + return get("name"); + } + + /** + * Gets the name of this file or directory. + * + * @return the name of this file or directory + */ + public String getName() { + String fullPath = getPath(); + int slashPos = fullPath.lastIndexOf('/'); + if (slashPos < 0) return fullPath; + return fullPath.substring(slashPos + 1); + } + + /** + * Gets the path of the directory containing this file or directory. + * + * @return the path to the parent directory + * + * @see #getPath() + */ + public String getParentPath() { + String fullPath = getPath(); + int slashPos = fullPath.lastIndexOf('/'); + if (slashPos < 0) return "/"; + return fullPath.substring(0, slashPos + 1); + } + + /** + * Gets the size of the file in bytes. + * Note that this can return wrong values if the file is still being uploaded + * or if the upload has been paused by the uploading client. + * + * @return the file's size + */ + public long getFileSize() { + return getLong("size"); + } + + /** + * Gets the date of the last modification to this file. + * The date has a one-second resolution. + * + * @return the file's last modification date + */ + public Date getLastModifiedDate() { + return new Date(getLong("datetime") * 1000); + } + + /** + * Gets whether this entry is a directory or a file. + * {@code 0} stands for a directory, {@code 1} for a file. + *

+ * Consider using {@link #isFile} and {@link #isDirectory} instead. + *

+ * + * @return the type of this file entry + */ + public int getType() { + return 1; + } + + /** + * Returns {@code true} if this entry is a file and not a directory. + * + * @return whether this is a file + */ + public boolean isFile() { + return true; + } + + /** + * Returns {@code true} if this entry is a directory and not a file. + * + * @return whether this is a directory + */ + public boolean isDirectory() { + return false; + } +} diff --git a/src/main/java/com/github/manevolent/ts3j/api/FileListEntry.java b/src/main/java/com/github/manevolent/ts3j/api/FileListEntry.java new file mode 100644 index 0000000..da706c6 --- /dev/null +++ b/src/main/java/com/github/manevolent/ts3j/api/FileListEntry.java @@ -0,0 +1,94 @@ +package com.github.manevolent.ts3j.api; + +/* + * #%L + * TeamSpeak 3 Java API + * %% + * Copyright (C) 2016 Bert De Geyter, Roger Baumgartner + * %% + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * #L% + */ + +import java.util.Map; + +public class FileListEntry extends FileInfo { + + public FileListEntry(Map map) { + super(map); + } + + @Override + public String getPath() { + return getParentPath() + getName(); + } + + @Override + public String getName() { + return get("name"); + } + + @Override + public String getParentPath() { + return get("path"); + } + + @Override + public long getFileSize() { + // Present if still uploading and returns + final long finishedSize = getLong("incompletesize"); + return (finishedSize > 0) ? finishedSize : super.getFileSize(); + } + + @Override + public int getType() { + return getInt("type"); + } + + @Override + public boolean isFile() { + return getType() == 1; + } + + @Override + public boolean isDirectory() { + return getType() == 0; + } + + /** + * Returns {@code true} if this file was actively being uploaded at the time + * this object was created. Note that this will return {@code false} if a + * client has paused an upload. + * + * @return whether this file is actively being uploaded + */ + public boolean isStillUploading() { + return getLong("incompletesize") > 0; + } + + /** + * If this file is still uploading, this method will return how many bytes have already + * been uploaded. Otherwise the normal file size is returned. + * + * @return how many bytes of this file have been uploaded + */ + public long getUploadedBytes() { + return super.getFileSize(); + } +} diff --git a/src/main/java/com/github/manevolent/ts3j/api/FileTransfer.java b/src/main/java/com/github/manevolent/ts3j/api/FileTransfer.java new file mode 100644 index 0000000..58f48a1 --- /dev/null +++ b/src/main/java/com/github/manevolent/ts3j/api/FileTransfer.java @@ -0,0 +1,166 @@ +package com.github.manevolent.ts3j.api; + +/* + * #%L + * TeamSpeak 3 Java API + * %% + * Copyright (C) 2016 Bert De Geyter, Roger Baumgartner + * %% + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * #L% + */ + +import java.util.Map; + +public class FileTransfer extends Wrapper { + + public FileTransfer(Map map) { + super(map); + } + + /** + * Gets the ID of the client who started this file transfer. + * + * @return the ID of the involved client + */ + public int getClientId() { + return getInt("clid"); + } + + /** + * Gets the path of the folder that the file which is being transferred is stored in on disk. + * This path seems to be relative to the folder the TS3 server is installed in. + * + * @return the disk path of the folder containing the transferring file + */ + public String getDiskFilePath() { + return get("path"); + } + + /** + * Returns the name of the file on the TS3 server without its full path. + * + * @return the file's name + */ + public String getFileName() { + return get("name"); + } + + /** + * Gets the size in bytes the file will have once it is fully transferred. + * + * @return the final file size in bytes + */ + public long getTotalFileSize() { + return getLong("size"); + } + + /** + * Gets the amount of bytes that have already been transferred. + * + * @return the amount of transferred bytes + */ + public long getTransferredFileSize() { + return getLong("sizedone"); + } + + /** + * Returns the key that the client has sent to the server to identify their file transfer. + * + * @return the client's file transfer ID + */ + public int getClientTransferId() { + return getInt("clientftfid"); + } + + /** + * Returns an internal ID that the server uses to identify their file transfer. + * This is not the key that can be used to request a file from the file server. + * + * @return the server's file transfer ID + */ + public int getServerTransferId() { + return getInt("serverftfid"); + } + + /** + * Returns the current status of the file transfer. + *

+ * Currently known status codes: + *

+ *
    + *
  • 0 - Not started
  • + *
  • 1 - Active
  • + *
  • 2 - Inactive (paused, stalled or done)
  • + *
+ * + * @return the current transfer status + */ + public int getStatus() { + return getInt("status"); + } + + /** + * Returns {@code true} if the file transfer has started. + * + * @return whether the file transfer has started + */ + public boolean hasStarted() { + return getStatus() > 0; + } + + /** + * Returns {@code true} if the file transfer is still active. + * This is the case when the transfer has started and is not done or paused. + * + * @return whether the file transfer is active + */ + public boolean isActive() { + return getStatus() == 1; + } + + /** + * Returns the current file transfer speed in bytes per second. + * + * @return the current transfer speed + */ + public double getCurrentSpeed() { + return getDouble("current_speed"); + } + + /** + * Returns the current file transfer speed in bytes per second. + * + * @return the current transfer speed + */ + public double getAverageSpeed() { + return getDouble("average_speed"); + } + + /** + * Returns how many milliseconds have elapsed since the file transfer was first announced to + * the server. This value will count up even if the file transfer has not yet been started, + * but will stop if the transfer has been paused or is complete. + * + * @return the transfer runtime in milliseconds + */ + public long getRuntime() { + return getLong("runtime"); + } +} diff --git a/src/main/java/com/github/manevolent/ts3j/api/FileTransferParameters.java b/src/main/java/com/github/manevolent/ts3j/api/FileTransferParameters.java new file mode 100644 index 0000000..8eb8d14 --- /dev/null +++ b/src/main/java/com/github/manevolent/ts3j/api/FileTransferParameters.java @@ -0,0 +1,127 @@ +package com.github.manevolent.ts3j.api; + +/* + * #%L + * TeamSpeak 3 Java API + * %% + * Copyright (C) 2016 Bert De Geyter, Roger Baumgartner + * %% + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * #L% + */ + +import java.util.HashMap; +import java.util.Map; + +/** + * Represents an internally started file transfer and encapsulates the command response. + */ +public class FileTransferParameters extends Wrapper { + + public FileTransferParameters(Map map) { + super(map); + } + + /** + * Returns the key that the client has sent to the server to identify their file transfer. + * + * @return the client's file transfer ID + */ + public int getClientTransferId() { + return getInt("clientftfid"); + } + + /** + * Returns an internal ID that the server uses to identify their file transfer. + * This is not the key that can be used to request a file from the file server. + * + * @return the server's file transfer ID + */ + public int getServerTransferId() { + return getInt("serverftfid"); + } + + /** + * Gets the key needed identify ourselves to the file server and to start the file transfer. + * + * @return the file transfer key + */ + public String getFileTransferKey() { + return get("ftkey"); + } + + /** + * Gets the IP address or hostname of the file server the TS3 instance wants us to send our data to. + * + * @return the IP address of the file server + */ + public String getFileServerHost() { + return get("ip"); + } + + /** + * Gets the port of the file server the TS3 instance wants us to send our data to. + * + * @return the port of the file server + */ + public int getFileServerPort() { + return getInt("port"); + } + + /** + * Gets the size of the file being downloaded in bytes. + * Only present if this is a successfully started download. + * + * @return the size of the file being downloaded. + */ + public long getFileSize() { + return getLong("size"); + } + + /** + * Gets a {@link QueryError} that can be used when throwing an exception. + * + * @return a query error for this command's success value + */ + public QueryError getQueryError() { + Map errorMap = new HashMap<>(2); + errorMap.put("id", String.valueOf(getStatus())); + errorMap.put("msg", getMessage()); + return new QueryError(errorMap); + } + + /** + * Gets the status / error code of this command. Only present if the command failed. + * + * @return the command's status value + */ + public int getStatus() { + final int status = getInt("status"); + return status == -1 ? 0 : status; + } + + /** + * Gets the message that is provided in case the command fails. + * + * @return the failure message + */ + public String getMessage() { + return get("msg"); + } +} diff --git a/src/main/java/com/github/manevolent/ts3j/api/HostBannerMode.java b/src/main/java/com/github/manevolent/ts3j/api/HostBannerMode.java new file mode 100644 index 0000000..d6e373d --- /dev/null +++ b/src/main/java/com/github/manevolent/ts3j/api/HostBannerMode.java @@ -0,0 +1,45 @@ +package com.github.manevolent.ts3j.api; + +/* + * #%L + * TeamSpeak 3 Java API + * %% + * Copyright (C) 2014 Bert De Geyter + * %% + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * #L% + */ + +public enum HostBannerMode { + NO_ADJUST(0), + IGNORE_ASPECT(1), + KEEP_ASPECT(2), + UNKNOWN(-1); + + private final int i; + + HostBannerMode(int i) { + this.i = i; + } + + public int getIndex() { + return i; + } + +} diff --git a/src/main/java/com/github/manevolent/ts3j/api/HostInfo.java b/src/main/java/com/github/manevolent/ts3j/api/HostInfo.java new file mode 100644 index 0000000..846aa18 --- /dev/null +++ b/src/main/java/com/github/manevolent/ts3j/api/HostInfo.java @@ -0,0 +1,110 @@ +package com.github.manevolent.ts3j.api; + +/* + * #%L + * TeamSpeak 3 Java API + * %% + * Copyright (C) 2014 Bert De Geyter + * %% + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * #L% + */ + +import java.util.Date; +import java.util.Map; + +public class HostInfo extends Wrapper { + + public HostInfo(Map map) { + super(map); + } + + public long getUptime() { + return getLong(ServerInstanceProperty.INSTANCE_UPTIME); + } + + public Date getTimeStamp() { + return new Date(getLong(ServerInstanceProperty.HOST_TIMESTAMP_UTC) * 1000); + } + + public int getTotalRunningServers() { + return getInt(ServerInstanceProperty.VIRTUALSERVERS_RUNNING_TOTAL); + } + + public int getTotalMaxClients() { + return getInt(ServerInstanceProperty.VIRTUALSERVERS_TOTAL_MAXCLIENTS); + } + + public int getTotalClientsOnline() { + return getInt(ServerInstanceProperty.VIRTUALSERVERS_TOTAL_CLIENTS_ONLINE); + } + + public int getTotalChannels() { + return getInt(ServerInstanceProperty.VIRTUALSERVERS_TOTAL_CHANNELS_ONLINE); + } + + public long getFileTransferBandwidthSent() { + return getLong(ServerInstanceProperty.CONNECTION_FILETRANSFER_BANDWIDTH_SENT); + } + + public long getFileTransferBandwidthReceived() { + return getLong(ServerInstanceProperty.CONNECTION_FILETRANSFER_BANDWIDTH_RECEIVED); + } + + public long getFileTransferBytesSent() { + return getLong(ServerInstanceProperty.CONNECTION_FILETRANSFER_BYTES_SENT_TOTAL); + } + + public long getFileTransferBytesReceived() { + return getLong(ServerInstanceProperty.CONNECTION_FILETRANSFER_BYTES_RECEIVED_TOTAL); + } + + public long getPacketsSentTotal() { + return getLong(ServerInstanceProperty.CONNECTION_PACKETS_SENT_TOTAL); + } + + public long getBytesSentTotal() { + return getLong(ServerInstanceProperty.CONNECTION_BYTES_SENT_TOTAL); + } + + public long getPacketsReceivedTotal() { + return getLong(ServerInstanceProperty.CONNECTION_PACKETS_RECEIVED_TOTAL); + } + + public long getBytesReceivedTotal() { + return getLong(ServerInstanceProperty.CONNECTION_BYTES_RECEIVED_TOTAL); + } + + public long getBandwidthSentLastSecond() { + return getLong(ServerInstanceProperty.CONNECTION_BANDWIDTH_SENT_LAST_SECOND_TOTAL); + } + + public long getBandwidthSentLastMinute() { + return getLong(ServerInstanceProperty.CONNECTION_BANDWIDTH_SENT_LAST_MINUTE_TOTAL); + } + + public long getBandwidthReceivedLastSecond() { + return getLong(ServerInstanceProperty.CONNECTION_BANDWIDTH_RECEIVED_LAST_SECOND_TOTAL); + } + + public long getBandwidthReceivedLastMinute() { + return getLong(ServerInstanceProperty.CONNECTION_BANDWIDTH_RECEIVED_LAST_MINUTE_TOTAL); + } + +} diff --git a/src/main/java/com/github/manevolent/ts3j/api/HostMessageMode.java b/src/main/java/com/github/manevolent/ts3j/api/HostMessageMode.java new file mode 100644 index 0000000..2d0aed0 --- /dev/null +++ b/src/main/java/com/github/manevolent/ts3j/api/HostMessageMode.java @@ -0,0 +1,46 @@ +package com.github.manevolent.ts3j.api; + +/* + * #%L + * TeamSpeak 3 Java API + * %% + * Copyright (C) 2014 Bert De Geyter + * %% + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * #L% + */ + +public enum HostMessageMode { + + LOG(1), + MODAL(2), + MODAL_QUIT(3), + UNKNOWN(-1); + + private final int i; + + HostMessageMode(int i) { + this.i = i; + } + + public int getIndex() { + return i; + } + +} diff --git a/src/main/java/com/github/manevolent/ts3j/api/IconFile.java b/src/main/java/com/github/manevolent/ts3j/api/IconFile.java new file mode 100644 index 0000000..89446aa --- /dev/null +++ b/src/main/java/com/github/manevolent/ts3j/api/IconFile.java @@ -0,0 +1,50 @@ +package com.github.manevolent.ts3j.api; + +/* + * #%L + * TeamSpeak 3 Java API + * %% + * Copyright (C) 2016 Bert De Geyter, Roger Baumgartner + * %% + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * #L% + */ + +import java.util.Map; + +public class IconFile extends FileListEntry { + + public IconFile(Map map) { + super(map); + } + + /** + * Gets the icon ID corresponding to this file, or {@code -1} if the file name + * doesn't follow the standard format. + * + * @return this file's icon ID + */ + public long getIconId() { + String fileName = getName(); + if (!fileName.matches("icon_\\d{1,10}")) return -1L; // Doesn't match standard pattern + long id = Long.parseLong(fileName.substring("icon_".length())); + if ((id & 0xFFFF_FFFF_0000_0000L) != 0) return -1L; // CRC32 is 32 bits, so needs to fit into an int + return id; + } +} diff --git a/src/main/java/com/github/manevolent/ts3j/api/InstanceInfo.java b/src/main/java/com/github/manevolent/ts3j/api/InstanceInfo.java new file mode 100644 index 0000000..f9b54a5 --- /dev/null +++ b/src/main/java/com/github/manevolent/ts3j/api/InstanceInfo.java @@ -0,0 +1,88 @@ +package com.github.manevolent.ts3j.api; + +/* + * #%L + * TeamSpeak 3 Java API + * %% + * Copyright (C) 2014 Bert De Geyter + * %% + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * #L% + */ + +import java.util.Map; + +public class InstanceInfo extends Wrapper { + + public InstanceInfo(Map map) { + super(map); + } + + public int getDatabaseVersion() { + return getInt(ServerInstanceProperty.SERVERINSTANCE_DATABASE_VERSION); + } + + public int getFileTransferPort() { + return getInt(ServerInstanceProperty.SERVERINSTANCE_FILETRANSFER_PORT); + } + + public long getMaxDownloadBandwidth() { + return getLong(ServerInstanceProperty.SERVERINSTANCE_MAX_DOWNLOAD_TOTAL_BANDWIDTH); + } + + public long getMaxUploadBandwidth() { + return getLong(ServerInstanceProperty.SERVERINSTANCE_MAX_UPLOAD_TOTAL_BANDWIDTH); + } + + public int getGuestServerQueryGroup() { + return getInt(ServerInstanceProperty.SERVERINSTANCE_GUEST_SERVERQUERY_GROUP); + } + + public int getMaxFloodCommands() { + return getInt(ServerInstanceProperty.SERVERINSTANCE_SERVERQUERY_FLOOD_COMMANDS); + } + + public int getMaxFloodTime() { // SECONDS + return getInt(ServerInstanceProperty.SERVERINSTANCE_SERVERQUERY_FLOOD_TIME); + } + + public int getFloodBanTime() {// SECONDS + return getInt(ServerInstanceProperty.SERVERINSTANCE_SERVERQUERY_BAN_TIME); + } + + public int getServerAdminGroup() { + return getInt(ServerInstanceProperty.SERVERINSTANCE_TEMPLATE_SERVERADMIN_GROUP); + } + + public int getDefaultServerGroup() { + return getInt(ServerInstanceProperty.SERVERINSTANCE_TEMPLATE_SERVERDEFAULT_GROUP); + } + + public int getChannelAdminGroup() { + return getInt(ServerInstanceProperty.SERVERINSTANCE_TEMPLATE_CHANNELADMIN_GROUP); + } + + public int getDefaultChannelGroup() { + return getInt(ServerInstanceProperty.SERVERINSTANCE_TEMPLATE_CHANNELDEFAULT_GROUP); + } + + public int getPermissionsVersion() { + return getInt(ServerInstanceProperty.SERVERINSTANCE_PERMISSIONS_VERSION); + } +} diff --git a/src/main/java/com/github/manevolent/ts3j/api/Message.java b/src/main/java/com/github/manevolent/ts3j/api/Message.java new file mode 100644 index 0000000..6a9759c --- /dev/null +++ b/src/main/java/com/github/manevolent/ts3j/api/Message.java @@ -0,0 +1,57 @@ +package com.github.manevolent.ts3j.api; + +/* + * #%L + * TeamSpeak 3 Java API + * %% + * Copyright (C) 2014 Bert De Geyter + * %% + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * #L% + */ + +import java.util.Date; +import java.util.Map; + +public class Message extends Wrapper { + + public Message(Map map) { + super(map); + } + + public int getId() { + return getInt("msgid"); + } + + public String getSenderUniqueIdentifier() { + return get("cluid"); + } + + public String getSubject() { + return get("subject"); + } + + public Date getReceivedDate() { + return new Date(getLong("timestamp") * 1000); + } + + public boolean hasBeenRead() { + return getBoolean("flag_read"); + } +} diff --git a/src/main/java/com/github/manevolent/ts3j/api/Permission.java b/src/main/java/com/github/manevolent/ts3j/api/Permission.java new file mode 100644 index 0000000..7f79a4b --- /dev/null +++ b/src/main/java/com/github/manevolent/ts3j/api/Permission.java @@ -0,0 +1,110 @@ +package com.github.manevolent.ts3j.api; + +/* + * #%L + * TeamSpeak 3 Java API + * %% + * Copyright (C) 2014 Bert De Geyter + * %% + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * #L% + */ + +import java.util.Map; + +/** + * Describes a permission that has been assigned to a client, + * a channel group or a server group. + *

+ * For a complete description of the TS3 permission system, refer to + * + * this post on the TeamSpeak forums. + *

+ */ +public class Permission extends Wrapper { + + public Permission(Map map) { + super(map); + } + + /** + * Gets the name of this permission. + *

+ * Boolean permissions are prefixed with {@code b_}
+ * Integer permissions are prefixed with {@code i_} + *

+ * + * @return this permission's name + */ + public String getName() { + return get("permsid"); + } + + /** + * Gets the value of this permission assignment. + *

+ * Please note that this value doesn't necessarily have to be + * the effective permission value for a client, as this assignment + * can be overridden by another assignment. + *

+ * Integer permissions usually have values between 0 and 100, + * but any integer value is theoretically valid. + *

+ * Boolean permissions have a value of {@code 0} to represent + * {@code false} and {@code 1} to represent {@code true}. + *

+ * + * @return the value of this permission assignment + */ + public int getValue() { + return getInt("permvalue"); + } + + /** + * Returns {@code true} if this permission is negated. + *

+ * Negated means that instead of the highest value, the lowest + * value will be selected for this permission instead. + *

+ * + * @return whether this permission is negated or not + */ + public boolean isNegated() { + return getBoolean("permnegated"); + } + + /** + * Returns {@code true} if this permission is skipped. + *

+ * Skipped only exists for server group and client permissions, + * therefore this value will always be false for channel group permissions. + *

+ * If a client permission is skipped, it won't be overridden by channel + * group permissions.
+ * If a server group permission is skipped, it won't be overridden by + * channel group or client permissions. + *

+ * + * @return whether this permission is negated or not + */ + public boolean isSkipped() { + return getBoolean("permskip"); + } + +} diff --git a/src/main/java/com/github/manevolent/ts3j/api/PermissionAssignment.java b/src/main/java/com/github/manevolent/ts3j/api/PermissionAssignment.java new file mode 100644 index 0000000..9b5494b --- /dev/null +++ b/src/main/java/com/github/manevolent/ts3j/api/PermissionAssignment.java @@ -0,0 +1,160 @@ +package com.github.manevolent.ts3j.api; + +/* + * #%L + * TeamSpeak 3 Java API + * %% + * Copyright (C) 2014 Bert De Geyter + * %% + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * #L% + */ + +import java.util.Map; + +/** + * Describes a single permission that is assigned to a varying target. + *

+ * This class is used when a lot of permissions are sent at once. + * To reduce bandwidth usage, the TS3 server only transmit the numeric + * permission ID and not the permission name. + *

+ * For a complete description of the TS3 permission system, refer to + * + * this post on the TeamSpeak forums. + *

+ */ +public class PermissionAssignment extends Wrapper { + + public PermissionAssignment(Map map) { + super(map); + } + + /** + * Where this permission assignment originates from. + * + * @return the type of this permission assignment + */ + public PermissionGroupType getType() { + final int type = getInt("t"); + for (final PermissionGroupType p : PermissionGroupType.values()) { + if (p.getIndex() == type) { + return p; + } + } + return null; + } + + /** + * Specifies where this permission assignment originates from, + * depending on the {@linkplain #getType() type} of this assignment. + *

+ * {@code x -> y} := In case {@code type} is {@code x}, {@code majorId} means {@code y} + *

+ * {@linkplain PermissionGroupType#SERVER_GROUP SERVER_GROUP} {@code ->} {@linkplain ServerGroup#getId() Server group ID}
+ * {@linkplain PermissionGroupType#GLOBAL_CLIENT GLOBAL_CLIENT} {@code ->} {@linkplain Client#getDatabaseId() Client database ID}
+ * {@linkplain PermissionGroupType#CHANNEL CHANNEL} {@code ->} {@linkplain Channel#getId() Channel ID}
+ * {@linkplain PermissionGroupType#CHANNEL_GROUP CHANNEL_GROUP} {@code ->} {@linkplain Channel#getId() Channel ID}
+ * {@linkplain PermissionGroupType#CHANNEL_CLIENT CHANNEL_CLIENT} {@code ->} {@linkplain Channel#getId() Channel ID} + *

+ * + * @return the major ID of the source of this assignment as described above + */ + public int getMajorId() { + return getInt("id1"); + } + + /** + * Specifies where this permission assignment originates from, + * depending on the {@linkplain #getType() type} of this assignment. + *

+ * {@code x -> y} := In case {@code type} is {@code x}, {@code minorId} means {@code y} + *

+ * {@linkplain PermissionGroupType#CHANNEL_GROUP CHANNEL_GROUP} {@code ->} {@linkplain ChannelGroup#getId() Channel group ID}
+ * {@linkplain PermissionGroupType#CHANNEL_CLIENT CHANNEL_CLIENT} {@code ->} {@linkplain Client#getDatabaseId() Client database ID} + *

+ * Otherwise {@code getMinorId()} is undefined should return {@code 0}. + *

+ * + * @return the minor ID of the source of this assignment as described above + */ + public int getMinorId() { + return getInt("id2"); + } + + /** + * Gets the numerical ID of this permission. + * + * @return this permission's numerical ID + */ + public int getId() { + return getInt("p"); + } + + /** + * Gets the value of this permission assignment. + *

+ * Please note that this value doesn't necessarily have to be + * the effective permission value for a client, as this assignment + * can be overridden by another assignment. + *

+ * Integer permissions usually have values between 0 and 100, + * but any integer value is theoretically valid. + *

+ * Boolean permissions have a value of {@code 0} to represent + * {@code false} and {@code 1} to represent {@code true}. + *

+ * + * @return the value of this permission assignment + */ + public int getValue() { + return getInt("v"); + } + + /** + * Returns {@code true} if this permission is negated. + *

+ * Negated means that instead of the highest value, the lowest + * value will be selected for this permission instead. + *

+ * + * @return whether this permission is negated or not + */ + public boolean isNegated() { + return getBoolean("n"); + } + + /** + * Returns {@code true} if this permission is skipped. + *

+ * Skipped only exists for server group and client permissions, + * therefore this value will always be false for channel group permissions. + *

+ * If a client permission is skipped, it won't be overridden by channel + * group permissions.
+ * If a server group permission is skipped, it won't be overridden by + * channel group or client permissions. + *

+ * + * @return whether this permission is negated or not + */ + public boolean isSkipped() { + return getBoolean("s"); + } +} diff --git a/src/main/java/com/github/manevolent/ts3j/api/PermissionGroupDatabaseType.java b/src/main/java/com/github/manevolent/ts3j/api/PermissionGroupDatabaseType.java new file mode 100644 index 0000000..946c874 --- /dev/null +++ b/src/main/java/com/github/manevolent/ts3j/api/PermissionGroupDatabaseType.java @@ -0,0 +1,45 @@ +package com.github.manevolent.ts3j.api; + +/* + * #%L + * TeamSpeak 3 Java API + * %% + * Copyright (C) 2014 Bert De Geyter + * %% + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * #L% + */ + +public enum PermissionGroupDatabaseType { + + TEMPLATE(0), + REGULAR(1), + QUERY(2); + + private final int i; + + PermissionGroupDatabaseType(int i) { + this.i = i; + } + + public int getIndex() { + return i; + } + +} diff --git a/src/main/java/com/github/manevolent/ts3j/api/PermissionGroupType.java b/src/main/java/com/github/manevolent/ts3j/api/PermissionGroupType.java new file mode 100644 index 0000000..6c896df --- /dev/null +++ b/src/main/java/com/github/manevolent/ts3j/api/PermissionGroupType.java @@ -0,0 +1,76 @@ +package com.github.manevolent.ts3j.api; + +/* + * #%L + * TeamSpeak 3 Java API + * %% + * Copyright (C) 2014 Bert De Geyter + * %% + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * #L% + */ + +/** + * An enum describing where a {@link PermissionAssignment} originates from. + */ +public enum PermissionGroupType { + + /** + * A permission assigned to a server group. + */ + SERVER_GROUP(0), + + /** + * A permission assigned to a client on a server-wide level. + */ + GLOBAL_CLIENT(1), + + /** + * A permission requirement for certain actions in a channel. + *

+ * Examples: Join, talk, subscribe and file upload permission requirements + *

+ */ + CHANNEL(2), + + /** + * A permission assigned to a channel group. + */ + CHANNEL_GROUP(3), + + /** + * A permission assigned to a client in a specific channel. + *

+ * This is mostly used for the priority speaker feature by granting + * {@code b_client_is_priority_speaker} to a client in a channel. + *

+ */ + CHANNEL_CLIENT(4); + + private final int i; + + PermissionGroupType(int i) { + this.i = i; + } + + public int getIndex() { + return i; + } + +} diff --git a/src/main/java/com/github/manevolent/ts3j/api/PermissionInfo.java b/src/main/java/com/github/manevolent/ts3j/api/PermissionInfo.java new file mode 100644 index 0000000..6f78ecd --- /dev/null +++ b/src/main/java/com/github/manevolent/ts3j/api/PermissionInfo.java @@ -0,0 +1,88 @@ +package com.github.manevolent.ts3j.api; + +/* + * #%L + * TeamSpeak 3 Java API + * %% + * Copyright (C) 2014 Bert De Geyter + * %% + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * #L% + */ + +import java.util.Map; + +/** + * Describes a single permission on the TS3 server. + *

+ * Includes the numerical ID and the name of the permission, as well + * as an optional short description of this permission. Does not + * include any information about any possible permission assignments. + *

+ * For a complete description of the TS3 permission system, refer to + * + * this post on the TeamSpeak forums. + *

+ */ +public class PermissionInfo extends Wrapper { + + public PermissionInfo(Map map) { + super(map); + } + + /** + * Gets the numerical ID of this permission. + *

+ * In most cases, the name of the permission should be + * preferred over the numerical ID. + *

+ * + * @return this permission's numerical ID + */ + public int getId() { + return getInt("permid"); + } + + /** + * Gets the name of this permission. + *

+ * Boolean permissions are prefixed with {@code b_}
+ * Integer permissions are prefixed with {@code i_} + *

+ * + * @return this permission's name + */ + public String getName() { + return get("permname"); + } + + /** + * A short description about what this permission does. + *

+ * Does not exist for all permissions. In that case, an + * empty String will be returned instead. + *

+ * + * @return a short description of this permission + */ + public String getDescription() { + return get("permdesc"); + } + +} diff --git a/src/main/java/com/github/manevolent/ts3j/api/PrivilegeKey.java b/src/main/java/com/github/manevolent/ts3j/api/PrivilegeKey.java new file mode 100644 index 0000000..8b2dc1a --- /dev/null +++ b/src/main/java/com/github/manevolent/ts3j/api/PrivilegeKey.java @@ -0,0 +1,69 @@ +package com.github.manevolent.ts3j.api; + +/* + * #%L + * TeamSpeak 3 Java API + * %% + * Copyright (C) 2014 Bert De Geyter + * %% + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * #L% + */ + +import java.util.Date; +import java.util.Map; + +public class PrivilegeKey extends Wrapper { + + public PrivilegeKey(Map map) { + super(map); + } + + public String getToken() { + return get("token"); + } + + public int getType() { + return getInt("token_type"); + } + + public boolean isServerGroupToken() { + return getType() == 0; + } + + public boolean isChannelGroupToken() { + return !isServerGroupToken(); + } + + public int getGroupId() { + return getInt("token_id1"); + } + + public int getChannelId() { + return getInt("token_id2"); + } + + public Date getCreated() { + return new Date(getLong("token_created") * 1000); + } + + public String getDescription() { + return get("token_description"); + } +} diff --git a/src/main/java/com/github/manevolent/ts3j/api/PrivilegeKeyType.java b/src/main/java/com/github/manevolent/ts3j/api/PrivilegeKeyType.java new file mode 100644 index 0000000..8a2d498 --- /dev/null +++ b/src/main/java/com/github/manevolent/ts3j/api/PrivilegeKeyType.java @@ -0,0 +1,44 @@ +package com.github.manevolent.ts3j.api; + +/* + * #%L + * TeamSpeak 3 Java API + * %% + * Copyright (C) 2014 Bert De Geyter + * %% + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * #L% + */ + +public enum PrivilegeKeyType { + + SERVER_GROUP(0), + CHANNEL_GROUP(1); + + private final int i; + + PrivilegeKeyType(int i) { + this.i = i; + } + + public int getIndex() { + return i; + } + +} diff --git a/src/main/java/com/github/manevolent/ts3j/api/Property.java b/src/main/java/com/github/manevolent/ts3j/api/Property.java new file mode 100644 index 0000000..e326914 --- /dev/null +++ b/src/main/java/com/github/manevolent/ts3j/api/Property.java @@ -0,0 +1,34 @@ +package com.github.manevolent.ts3j.api; + +/* + * #%L + * TeamSpeak 3 Java API + * %% + * Copyright (C) 2014 Bert De Geyter + * %% + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * #L% + */ + +public interface Property { + + String getName(); + + boolean isChangeable(); +} diff --git a/src/main/java/com/github/manevolent/ts3j/api/QueryError.java b/src/main/java/com/github/manevolent/ts3j/api/QueryError.java new file mode 100644 index 0000000..2cdab6d --- /dev/null +++ b/src/main/java/com/github/manevolent/ts3j/api/QueryError.java @@ -0,0 +1,60 @@ +package com.github.manevolent.ts3j.api; + +/* + * #%L + * TeamSpeak 3 Java API + * %% + * Copyright (C) 2014 Bert De Geyter + * %% + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * #L% + */ + +import java.util.Map; + +public class QueryError extends Wrapper { + + private static final int ERROR_ID_OK = 0; + private static final int ERROR_ID_EMPTY_RESULT_SET = 1281; + + public QueryError(Map map) { + super(map); + } + + public int getId() { + return getInt("id"); + } + + public String getMessage() { + return get("msg"); + } + + public String getExtraMessage() { + return get("extra_msg"); + } + + public int getFailedPermissionId() { + return getInt("failed_permid"); + } + + public boolean isSuccessful() { + final int id = getId(); + return (id == ERROR_ID_OK || id == ERROR_ID_EMPTY_RESULT_SET); + } +} diff --git a/src/main/java/com/github/manevolent/ts3j/api/ReasonIdentifier.java b/src/main/java/com/github/manevolent/ts3j/api/ReasonIdentifier.java new file mode 100644 index 0000000..cfd2b10 --- /dev/null +++ b/src/main/java/com/github/manevolent/ts3j/api/ReasonIdentifier.java @@ -0,0 +1,44 @@ +package com.github.manevolent.ts3j.api; + +/* + * #%L + * TeamSpeak 3 Java API + * %% + * Copyright (C) 2014 Bert De Geyter + * %% + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * #L% + */ + +public enum ReasonIdentifier { + + REASON_KICK_CHANNEL(4), + REASON_KICK_SERVER(5); + + private final int i; + + ReasonIdentifier(int i) { + this.i = i; + } + + public int getIndex() { + return i; + } + +} diff --git a/src/main/java/com/github/manevolent/ts3j/api/ServerGroup.java b/src/main/java/com/github/manevolent/ts3j/api/ServerGroup.java new file mode 100644 index 0000000..c9c5097 --- /dev/null +++ b/src/main/java/com/github/manevolent/ts3j/api/ServerGroup.java @@ -0,0 +1,83 @@ +package com.github.manevolent.ts3j.api; + +/* + * #%L + * TeamSpeak 3 Java API + * %% + * Copyright (C) 2014 Bert De Geyter + * %% + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * #L% + */ + +import java.util.Map; + +public class ServerGroup extends Wrapper { + + public ServerGroup(Map map) { + super(map); + } + + public int getId() { + return getInt("sgid"); + } + + public String getName() { + return get("name"); + } + + public PermissionGroupDatabaseType getType() { + final int type = getInt("type"); + for (final PermissionGroupDatabaseType p : PermissionGroupDatabaseType.values()) { + if (p.getIndex() == type) { + return p; + } + } + return null; + } + + public long getIconId() { + return getLong("iconid"); + } + + public int getSaveDb() { + return getInt("savedb"); + } + + public int getSortId() { + return getInt("sortid"); + } + + public int getNameMode() { + return getInt("namemode"); + } + + public int getModifyPower() { + return getInt("n_modifyp"); + } + + public int getMemberAddPower() { + return getInt("n_member_addp"); + } + + public int getMemberRemovePower() { + return getInt("n_member_removep"); + } + +} diff --git a/src/main/java/com/github/manevolent/ts3j/api/ServerGroupClient.java b/src/main/java/com/github/manevolent/ts3j/api/ServerGroupClient.java new file mode 100644 index 0000000..a4729db --- /dev/null +++ b/src/main/java/com/github/manevolent/ts3j/api/ServerGroupClient.java @@ -0,0 +1,49 @@ +package com.github.manevolent.ts3j.api; + +/* + * #%L + * TeamSpeak 3 Java API + * %% + * Copyright (C) 2014 Bert De Geyter + * %% + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * #L% + */ + +import java.util.Map; + +public class ServerGroupClient extends Wrapper { + + public ServerGroupClient(Map map) { + super(map); + } + + public int getClientDatabaseId() { + return getInt("cldbid"); + } + + public String getNickname() { + return get("client_nickname"); + } + + public String getUniqueIdentifier() { + return get("client_unique_identifier"); + } + +} diff --git a/src/main/java/com/github/manevolent/ts3j/api/ServerInstanceProperty.java b/src/main/java/com/github/manevolent/ts3j/api/ServerInstanceProperty.java new file mode 100644 index 0000000..98e11cf --- /dev/null +++ b/src/main/java/com/github/manevolent/ts3j/api/ServerInstanceProperty.java @@ -0,0 +1,80 @@ +package com.github.manevolent.ts3j.api; + +/* + * #%L + * TeamSpeak 3 Java API + * %% + * Copyright (C) 2014 Bert De Geyter + * %% + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * #L% + */ + +import java.util.Locale; + +public enum ServerInstanceProperty implements Property { + + CONNECTION_BANDWIDTH_RECEIVED_LAST_MINUTE_TOTAL(false), + CONNECTION_BANDWIDTH_RECEIVED_LAST_SECOND_TOTAL(false), + CONNECTION_BANDWIDTH_SENT_LAST_MINUTE_TOTAL(false), + CONNECTION_BANDWIDTH_SENT_LAST_SECOND_TOTAL(false), + CONNECTION_BYTES_RECEIVED_TOTAL(false), + CONNECTION_BYTES_SENT_TOTAL(false), + CONNECTION_FILETRANSFER_BANDWIDTH_RECEIVED(false), + CONNECTION_FILETRANSFER_BANDWIDTH_SENT(false), + CONNECTION_FILETRANSFER_BYTES_RECEIVED_TOTAL(false), + CONNECTION_FILETRANSFER_BYTES_SENT_TOTAL(false), + CONNECTION_PACKETS_RECEIVED_TOTAL(false), + CONNECTION_PACKETS_SENT_TOTAL(false), + HOST_TIMESTAMP_UTC(false), + INSTANCE_UPTIME(false), + SERVERINSTANCE_DATABASE_VERSION(false), + SERVERINSTANCE_FILETRANSFER_PORT(true), + SERVERINSTANCE_GUEST_SERVERQUERY_GROUP(true), + SERVERINSTANCE_MAX_DOWNLOAD_TOTAL_BANDWIDTH(true), + SERVERINSTANCE_MAX_UPLOAD_TOTAL_BANDWIDTH(true), + SERVERINSTANCE_PERMISSIONS_VERSION(false), + SERVERINSTANCE_SERVERQUERY_BAN_TIME(true), + SERVERINSTANCE_SERVERQUERY_FLOOD_COMMANDS(true), + SERVERINSTANCE_SERVERQUERY_FLOOD_TIME(true), + SERVERINSTANCE_TEMPLATE_CHANNELADMIN_GROUP(true), + SERVERINSTANCE_TEMPLATE_CHANNELDEFAULT_GROUP(true), + SERVERINSTANCE_TEMPLATE_SERVERADMIN_GROUP(true), + SERVERINSTANCE_TEMPLATE_SERVERDEFAULT_GROUP(true), + VIRTUALSERVERS_RUNNING_TOTAL(false), + VIRTUALSERVERS_TOTAL_CHANNELS_ONLINE(false), + VIRTUALSERVERS_TOTAL_CLIENTS_ONLINE(false), + VIRTUALSERVERS_TOTAL_MAXCLIENTS(false); + + private final boolean changeable; + + ServerInstanceProperty(boolean changeable) { + this.changeable = changeable; + } + + @Override + public String getName() { + return name().toLowerCase(Locale.ROOT); + } + + @Override + public boolean isChangeable() { + return changeable; + } +} diff --git a/src/main/java/com/github/manevolent/ts3j/api/Snapshot.java b/src/main/java/com/github/manevolent/ts3j/api/Snapshot.java new file mode 100644 index 0000000..3126e09 --- /dev/null +++ b/src/main/java/com/github/manevolent/ts3j/api/Snapshot.java @@ -0,0 +1,41 @@ +package com.github.manevolent.ts3j.api; + +/* + * #%L + * TeamSpeak 3 Java API + * %% + * Copyright (C) 2014 Bert De Geyter + * %% + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * #L% + */ + +public class Snapshot { + + private final String snapshot; + + public Snapshot(String snapshot) { + this.snapshot = snapshot; + } + + public String get() { + return snapshot; + } + +} diff --git a/src/main/java/com/github/manevolent/ts3j/api/TextMessageTargetMode.java b/src/main/java/com/github/manevolent/ts3j/api/TextMessageTargetMode.java new file mode 100644 index 0000000..582c274 --- /dev/null +++ b/src/main/java/com/github/manevolent/ts3j/api/TextMessageTargetMode.java @@ -0,0 +1,45 @@ +package com.github.manevolent.ts3j.api; + +/* + * #%L + * TeamSpeak 3 Java API + * %% + * Copyright (C) 2014 Bert De Geyter + * %% + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * #L% + */ + +public enum TextMessageTargetMode { + + CLIENT(1), + CHANNEL(2), + SERVER(3); + + private final int i; + + TextMessageTargetMode(int i) { + this.i = i; + } + + public int getIndex() { + return i; + } + +} diff --git a/src/main/java/com/github/manevolent/ts3j/api/Version.java b/src/main/java/com/github/manevolent/ts3j/api/Version.java new file mode 100644 index 0000000..1c63328 --- /dev/null +++ b/src/main/java/com/github/manevolent/ts3j/api/Version.java @@ -0,0 +1,49 @@ +package com.github.manevolent.ts3j.api; + +/* + * #%L + * TeamSpeak 3 Java API + * %% + * Copyright (C) 2014 Bert De Geyter + * %% + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * #L% + */ + +import java.util.Map; + +public class Version extends Wrapper { + + public Version(Map map) { + super(map); + } + + public String getVersion() { + return get("version"); + } + + public String getBuild() { + return get("build"); + } + + public String getPlatform() { + return get("platform"); + } + +} diff --git a/src/main/java/com/github/manevolent/ts3j/api/VirtualServer.java b/src/main/java/com/github/manevolent/ts3j/api/VirtualServer.java new file mode 100644 index 0000000..4c1cbac --- /dev/null +++ b/src/main/java/com/github/manevolent/ts3j/api/VirtualServer.java @@ -0,0 +1,82 @@ +package com.github.manevolent.ts3j.api; + +/* + * #%L + * TeamSpeak 3 Java API + * %% + * Copyright (C) 2014 Bert De Geyter + * %% + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * #L% + */ + +import java.util.Map; + +public class VirtualServer extends Wrapper { + + public VirtualServer(Map map) { + super(map); + } + + public int getId() { + return getInt(VirtualServerProperty.VIRTUALSERVER_ID); + } + + public int getPort() { + return getInt(VirtualServerProperty.VIRTUALSERVER_PORT); + } + + public VirtualServerStatus getStatus() { + final String status = get(VirtualServerProperty.VIRTUALSERVER_STATUS); + for (final VirtualServerStatus s : VirtualServerStatus.values()) { + if (status.equals(s.getName())) { + return s; + } + } + return VirtualServerStatus.UNKNOWN; + } + + public int getClientsOnline() { + return getInt(VirtualServerProperty.VIRTUALSERVER_CLIENTSONLINE); + } + + public int getQueryClientsOnline() { + return getInt(VirtualServerProperty.VIRTUALSERVER_QUERYCLIENTSONLINE); + } + + public int getMaxClients() { + return getInt(VirtualServerProperty.VIRTUALSERVER_MAXCLIENTS); + } + + public String getUniqueIdentifier() { + return get(VirtualServerProperty.VIRTUALSERVER_UNIQUE_IDENTIFIER); + } + + public long getUptime() { + return getLong(VirtualServerProperty.VIRTUALSERVER_UPTIME); // in seconds + } + + public String getName() { + return get(VirtualServerProperty.VIRTUALSERVER_NAME); + } + + public boolean isAutoStart() { + return getBoolean(VirtualServerProperty.VIRTUALSERVER_AUTOSTART); + } +} diff --git a/src/main/java/com/github/manevolent/ts3j/api/VirtualServerInfo.java b/src/main/java/com/github/manevolent/ts3j/api/VirtualServerInfo.java new file mode 100644 index 0000000..4f1a3c9 --- /dev/null +++ b/src/main/java/com/github/manevolent/ts3j/api/VirtualServerInfo.java @@ -0,0 +1,387 @@ +package com.github.manevolent.ts3j.api; + +/* + * #%L + * TeamSpeak 3 Java API + * %% + * Copyright (C) 2014 Bert De Geyter + * %% + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * #L% + */ + +import java.util.Date; +import java.util.Map; + +public class VirtualServerInfo extends VirtualServer { + + public VirtualServerInfo(Map map) { + super(map); + } + + public int getAntifloodPointsNeededCommandBlock() { + return getInt(VirtualServerProperty.VIRTUALSERVER_ANTIFLOOD_POINTS_NEEDED_COMMAND_BLOCK); + } + + public int getAntifloodPointsNeedIpBlock() { + return getInt(VirtualServerProperty.VIRTUALSERVER_ANTIFLOOD_POINTS_NEEDED_IP_BLOCK); + } + + public int getAntifloodPointsTickReduce() { + return getInt(VirtualServerProperty.VIRTUALSERVER_ANTIFLOOD_POINTS_TICK_REDUCE); + } + + public long getBandwidthReceivedLastMinute() { + return getInt(VirtualServerProperty.CONNECTION_BANDWIDTH_RECEIVED_LAST_MINUTE_TOTAL); + } + + public long getBandwidthReceivedLastSecond() { + return getLong(VirtualServerProperty.CONNECTION_BANDWIDTH_RECEIVED_LAST_SECOND_TOTAL); + } + + public long getBandwidthSentLastMinute() { + return getLong(VirtualServerProperty.CONNECTION_BANDWIDTH_SENT_LAST_MINUTE_TOTAL); + } + + public long getBandwidthSentLastSecond() { + return getLong(VirtualServerProperty.CONNECTION_BANDWIDTH_SENT_LAST_SECOND_TOTAL); + } + + public int getChannelsOnline() { + return getInt(VirtualServerProperty.VIRTUALSERVER_CHANNELSONLINE); + } + + public CodecEncryptionMode getCodecEncryptionMode() { + final int encryptionMode = getInt(VirtualServerProperty.VIRTUALSERVER_CODEC_ENCRYPTION_MODE); + for (final CodecEncryptionMode m : CodecEncryptionMode.values()) { + if (m.getIndex() == encryptionMode) { + return m; + } + } + return CodecEncryptionMode.UNKNOWN; + } + + public int getComplaintAutobanCount() { + return getInt(VirtualServerProperty.VIRTUALSERVER_COMPLAIN_AUTOBAN_COUNT); + } + + public long getComplaintAutobanTime() {// SEC + return getLong(VirtualServerProperty.VIRTUALSERVER_COMPLAIN_AUTOBAN_TIME); + } + + public long getComplaintRemoveTime() { + return getLong(VirtualServerProperty.VIRTUALSERVER_COMPLAIN_REMOVE_TIME); + } + + public long getControlBytesReceived() { + return getLong(VirtualServerProperty.CONNECTION_BYTES_RECEIVED_CONTROL); + } + + public long getControlBytesSent() { + return getLong(VirtualServerProperty.CONNECTION_BYTES_SENT_CONTROL); + } + + public long getControlPacketsReceived() { + return getLong(VirtualServerProperty.CONNECTION_PACKETS_RECEIVED_CONTROL); + } + + public long getControlPacketsSent() { + return getLong(VirtualServerProperty.CONNECTION_PACKETS_SENT_CONTROL); + } + + public Date getCreatedDate() { + return new Date(getLong(VirtualServerProperty.VIRTUALSERVER_CREATED) * 1000); + } + + public int getDefaultChannelAdminGroup() { + return getInt(VirtualServerProperty.VIRTUALSERVER_DEFAULT_CHANNEL_ADMIN_GROUP); + } + + public int getDefaultChannelGroup() { + return getInt(VirtualServerProperty.VIRTUALSERVER_DEFAULT_CHANNEL_GROUP); + } + + public int getDefaultServerGroup() { + return getInt(VirtualServerProperty.VIRTUALSERVER_DEFAULT_SERVER_GROUP); + } + + public long getDownloadQuota() { + return getLong(VirtualServerProperty.VIRTUALSERVER_DOWNLOAD_QUOTA); + } + + public String getFileBase() { + return get(VirtualServerProperty.VIRTUALSERVER_FILEBASE); + } + + public long getFiletransferBandwidthReceived() { + return getLong(VirtualServerProperty.CONNECTION_FILETRANSFER_BANDWIDTH_RECEIVED); + } + + public long getFiletransferBandwidthSent() { + return getLong(VirtualServerProperty.CONNECTION_FILETRANSFER_BANDWIDTH_SENT); + } + + public long getFiletransferBytesReceived() { + return getLong(VirtualServerProperty.CONNECTION_FILETRANSFER_BYTES_RECEIVED_TOTAL); + } + + public long getFiletransferBytesSent() { + return getLong(VirtualServerProperty.CONNECTION_FILETRANSFER_BYTES_SENT_TOTAL); + } + + public int getHostbannerGfxInterval() { + return getInt(VirtualServerProperty.VIRTUALSERVER_HOSTBANNER_GFX_INTERVAL); + } + + public String getHostbannerGfxUrl() { + return get(VirtualServerProperty.VIRTUALSERVER_HOSTBANNER_GFX_URL); + } + + public HostBannerMode getHostbannerMode() { + final int hostbannerMode = getInt(VirtualServerProperty.VIRTUALSERVER_HOSTBANNER_MODE); + for (final HostBannerMode m : HostBannerMode.values()) { + if (m.getIndex() == hostbannerMode) { + return m; + } + } + return HostBannerMode.UNKNOWN; + } + + public String getHostbannerUrl() { + return get(VirtualServerProperty.VIRTUALSERVER_HOSTBANNER_URL); + } + + public String getHostbuttonGfxUrl() { + return get(VirtualServerProperty.VIRTUALSERVER_HOSTBUTTON_GFX_URL); + } + + public String getHostbuttonTooltip() { + return get(VirtualServerProperty.VIRTUALSERVER_HOSTBUTTON_TOOLTIP); + } + + public String getHostbuttonUrl() { + return get(VirtualServerProperty.VIRTUALSERVER_HOSTBUTTON_URL); + } + + public String getHostMessage() { + return get(VirtualServerProperty.VIRTUALSERVER_HOSTMESSAGE); + } + + public HostMessageMode getHostMessageMode() { + final int hostmessageMode = getInt(VirtualServerProperty.VIRTUALSERVER_HOSTMESSAGE_MODE); + for (final HostMessageMode m : HostMessageMode.values()) { + if (m.getIndex() == hostmessageMode) { + return m; + } + } + return HostMessageMode.UNKNOWN; + } + + public long getIconId() { + return getLong(VirtualServerProperty.VIRTUALSERVER_ICON_ID); + } + + public String getIp() { + return get(VirtualServerProperty.VIRTUALSERVER_IP); + } + + public long getKeepAliveBytesReceived() { + return getLong(VirtualServerProperty.CONNECTION_BYTES_RECEIVED_KEEPALIVE); + } + + public long getKeepAliveBytesSent() { + return getLong(VirtualServerProperty.CONNECTION_BYTES_SENT_KEEPALIVE); + } + + public long getKeepAlivePacketsReceived() { + return getLong(VirtualServerProperty.CONNECTION_PACKETS_RECEIVED_KEEPALIVE); + } + + public long getKeepAlivePacketsSent() { + return getLong(VirtualServerProperty.CONNECTION_PACKETS_SENT_KEEPALIVE); + } + + public String getMachineId() { + return get(VirtualServerProperty.VIRTUALSERVER_MACHINE_ID); + } + + public long getMaxDownloadBandwidth() { + return getLong(VirtualServerProperty.VIRTUALSERVER_MAX_DOWNLOAD_TOTAL_BANDWIDTH); + } + + public long getMaxUploadBandwidth() { + return getLong(VirtualServerProperty.VIRTUALSERVER_MAX_UPLOAD_TOTAL_BANDWIDTH); + } + + public int getMinClientsInChannelBeforeForcedSilence() { + return getInt(VirtualServerProperty.VIRTUALSERVER_MIN_CLIENTS_IN_CHANNEL_BEFORE_FORCED_SILENCE); + } + + public int getMinimumClientVersion() { + return getInt(VirtualServerProperty.VIRTUALSERVER_MIN_CLIENT_VERSION); + } + + public long getMonthlyBytesDownloaded() { + return getLong(VirtualServerProperty.VIRTUALSERVER_MONTH_BYTES_DOWNLOADED); + } + + public long getMonthlyBytesUploaded() { + return getLong(VirtualServerProperty.VIRTUALSERVER_MONTH_BYTES_UPLOADED); + } + + public int getNeededIdentitySecurityLevel() { + return getInt(VirtualServerProperty.VIRTUALSERVER_NEEDED_IDENTITY_SECURITY_LEVEL); + } + + public String getPassword() { + return get(VirtualServerProperty.VIRTUALSERVER_PASSWORD); + } + + public String getPhoneticName() { + return get(VirtualServerProperty.VIRTUALSERVER_NAME_PHONETIC); + } + + public double getPing() { + return getDouble(VirtualServerProperty.VIRTUALSERVER_TOTAL_PING); + } + + public String getPlatform() { + return get(VirtualServerProperty.VIRTUALSERVER_PLATFORM); + } + + public double getPrioritySpeakerDimmModificator() { + return getDouble(VirtualServerProperty.VIRTUALSERVER_PRIORITY_SPEAKER_DIMM_MODIFICATOR); + } + + public int getReservedSlots() { + return getInt(VirtualServerProperty.VIRTUALSERVER_RESERVED_SLOTS); + } + + public long getSpeechBytesReceived() { + return getLong(VirtualServerProperty.CONNECTION_BYTES_RECEIVED_SPEECH); + } + + public long getSpeechBytesSent() { + return getLong(VirtualServerProperty.CONNECTION_BYTES_SENT_SPEECH); + } + + public long getSpeechPacketsReceived() { + return getLong(VirtualServerProperty.CONNECTION_PACKETS_RECEIVED_SPEECH); + } + + public long getSpeechPacketsSent() { + return getLong(VirtualServerProperty.CONNECTION_PACKETS_SENT_SPEECH); + } + + public long getTotalBytesDownloaded() { + return getLong(VirtualServerProperty.VIRTUALSERVER_TOTAL_BYTES_DOWNLOADED); + } + + public long getTotalBytesReceived() { + return getLong(VirtualServerProperty.CONNECTION_BYTES_RECEIVED_TOTAL); + } + + public long getTotalBytesSent() { + return getLong(VirtualServerProperty.CONNECTION_BYTES_SENT_TOTAL); + } + + public long getTotalBytesUploaded() { + return getLong(VirtualServerProperty.VIRTUALSERVER_TOTAL_BYTES_UPLOADED); + } + + public int getTotalClientConnections() { + return getInt(VirtualServerProperty.VIRTUALSERVER_CLIENT_CONNECTIONS); + } + + public double getTotalControlPacketloss() { + return getDouble(VirtualServerProperty.VIRTUALSERVER_TOTAL_PACKETLOSS_CONTROL); + } + + public double getTotalKeepAlivePacketloss() { + return getDouble(VirtualServerProperty.VIRTUALSERVER_TOTAL_PACKETLOSS_KEEPALIVE); + } + + public double getTotalPacketloss() { + return getDouble(VirtualServerProperty.VIRTUALSERVER_TOTAL_PACKETLOSS_TOTAL); + } + + public long getTotalPacketsReceived() { + return getLong(VirtualServerProperty.CONNECTION_PACKETS_RECEIVED_TOTAL); + } + + public long getTotalPacketsSent() { + return getLong(VirtualServerProperty.CONNECTION_PACKETS_SENT_TOTAL); + } + + public int getTotalQueryClientConnections() { + return getInt(VirtualServerProperty.VIRTUALSERVER_QUERY_CLIENT_CONNECTIONS); + } + + public double getTotalSpeechPacketloss() { + return getDouble(VirtualServerProperty.VIRTUALSERVER_TOTAL_PACKETLOSS_SPEECH); + } + + public long getUploadQuota() { + return getLong(VirtualServerProperty.VIRTUALSERVER_UPLOAD_QUOTA); + } + + public String getVersion() { + return get(VirtualServerProperty.VIRTUALSERVER_VERSION); + } + + public String getWelcomeMessage() { + return get(VirtualServerProperty.VIRTUALSERVER_WELCOMEMESSAGE); + } + + public boolean hasPassword() { + return getBoolean(VirtualServerProperty.VIRTUALSERVER_FLAG_PASSWORD); + } + + public boolean isAskingPrivilegeKey() { + return getBoolean(VirtualServerProperty.VIRTUALSERVER_ASK_FOR_PRIVILEGEKEY); + } + + public boolean isLoggingChannel() { + return getBoolean(VirtualServerProperty.VIRTUALSERVER_LOG_CHANNEL); + } + + public boolean isLoggingClient() { + return getBoolean(VirtualServerProperty.VIRTUALSERVER_LOG_CLIENT); + } + + public boolean isLoggingFileTransfer() { + return getBoolean(VirtualServerProperty.VIRTUALSERVER_LOG_FILETRANSFER); + } + + public boolean isLoggingPermissions() { + return getBoolean(VirtualServerProperty.VIRTUALSERVER_LOG_PERMISSIONS); + } + + public boolean isLoggingQuery() { + return getBoolean(VirtualServerProperty.VIRTUALSERVER_LOG_QUERY); + } + + public boolean isLoggingServer() { + return getBoolean(VirtualServerProperty.VIRTUALSERVER_LOG_SERVER); + } + + public boolean isWeblistEnabled() { + return getBoolean(VirtualServerProperty.VIRTUALSERVER_WEBLIST_ENABLED); + } +} diff --git a/src/main/java/com/github/manevolent/ts3j/api/VirtualServerProperty.java b/src/main/java/com/github/manevolent/ts3j/api/VirtualServerProperty.java new file mode 100644 index 0000000..91721b0 --- /dev/null +++ b/src/main/java/com/github/manevolent/ts3j/api/VirtualServerProperty.java @@ -0,0 +1,142 @@ +package com.github.manevolent.ts3j.api; + +/* + * #%L + * TeamSpeak 3 Java API + * %% + * Copyright (C) 2014 Bert De Geyter + * %% + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * #L% + */ + +import java.util.Locale; + +public enum VirtualServerProperty implements Property { + + CONNECTION_BANDWIDTH_RECEIVED_LAST_MINUTE_TOTAL(false), + CONNECTION_BANDWIDTH_RECEIVED_LAST_SECOND_TOTAL(false), + CONNECTION_BANDWIDTH_SENT_LAST_MINUTE_TOTAL(false), + CONNECTION_BANDWIDTH_SENT_LAST_SECOND_TOTAL(false), + CONNECTION_BYTES_RECEIVED_CONTROL(false), + CONNECTION_BYTES_RECEIVED_KEEPALIVE(false), + CONNECTION_BYTES_RECEIVED_SPEECH(false), + CONNECTION_BYTES_RECEIVED_TOTAL(false), + CONNECTION_BYTES_SENT_CONTROL(false), + CONNECTION_BYTES_SENT_KEEPALIVE(false), + CONNECTION_BYTES_SENT_SPEECH(false), + CONNECTION_BYTES_SENT_TOTAL(false), + CONNECTION_FILETRANSFER_BANDWIDTH_RECEIVED(false), + CONNECTION_FILETRANSFER_BANDWIDTH_SENT(false), + CONNECTION_FILETRANSFER_BYTES_RECEIVED_TOTAL(false), + CONNECTION_FILETRANSFER_BYTES_SENT_TOTAL(false), + CONNECTION_PACKETS_RECEIVED_CONTROL(false), + CONNECTION_PACKETS_RECEIVED_KEEPALIVE(false), + CONNECTION_PACKETS_RECEIVED_SPEECH(false), + CONNECTION_PACKETS_RECEIVED_TOTAL(false), + CONNECTION_PACKETS_SENT_CONTROL(false), + CONNECTION_PACKETS_SENT_KEEPALIVE(false), + CONNECTION_PACKETS_SENT_SPEECH(false), + CONNECTION_PACKETS_SENT_TOTAL(false), + VIRTUALSERVER_ANTIFLOOD_POINTS_NEEDED_COMMAND_BLOCK(true), + VIRTUALSERVER_ANTIFLOOD_POINTS_NEEDED_IP_BLOCK(true), + VIRTUALSERVER_ANTIFLOOD_POINTS_TICK_REDUCE(true), + VIRTUALSERVER_ASK_FOR_PRIVILEGEKEY(false), + VIRTUALSERVER_AUTOSTART(true), + VIRTUALSERVER_CHANNELSONLINE(false), + VIRTUALSERVER_CLIENT_CONNECTIONS(false), + VIRTUALSERVER_CLIENTSONLINE(false), + VIRTUALSERVER_CODEC_ENCRYPTION_MODE(true), + VIRTUALSERVER_COMPLAIN_AUTOBAN_COUNT(true), + VIRTUALSERVER_COMPLAIN_AUTOBAN_TIME(true), + VIRTUALSERVER_COMPLAIN_REMOVE_TIME(true), + VIRTUALSERVER_CREATED(false), + VIRTUALSERVER_DEFAULT_CHANNEL_ADMIN_GROUP(true), + VIRTUALSERVER_DEFAULT_CHANNEL_GROUP(true), + VIRTUALSERVER_DEFAULT_SERVER_GROUP(true), + VIRTUALSERVER_DOWNLOAD_QUOTA(true), + VIRTUALSERVER_FILEBASE(false), + VIRTUALSERVER_FLAG_PASSWORD(false), + VIRTUALSERVER_HOSTBANNER_GFX_INTERVAL(true), + VIRTUALSERVER_HOSTBANNER_GFX_URL(true), + VIRTUALSERVER_HOSTBANNER_MODE(true), + VIRTUALSERVER_HOSTBANNER_URL(true), + VIRTUALSERVER_HOSTBUTTON_GFX_URL(true), + VIRTUALSERVER_HOSTBUTTON_TOOLTIP(true), + VIRTUALSERVER_HOSTBUTTON_URL(true), + VIRTUALSERVER_HOSTMESSAGE(true), + VIRTUALSERVER_HOSTMESSAGE_MODE(true), + VIRTUALSERVER_ICON_ID(true), + VIRTUALSERVER_ID(false), + VIRTUALSERVER_IP(false), + VIRTUALSERVER_LOG_CHANNEL(true), + VIRTUALSERVER_LOG_CLIENT(true), + VIRTUALSERVER_LOG_FILETRANSFER(true), + VIRTUALSERVER_LOG_PERMISSIONS(true), + VIRTUALSERVER_LOG_QUERY(true), + VIRTUALSERVER_LOG_SERVER(true), + VIRTUALSERVER_MACHINE_ID(true), + VIRTUALSERVER_MAX_DOWNLOAD_TOTAL_BANDWIDTH(true), + VIRTUALSERVER_MAX_UPLOAD_TOTAL_BANDWIDTH(true), + VIRTUALSERVER_MAXCLIENTS(true), + VIRTUALSERVER_MIN_CLIENT_VERSION(true), + VIRTUALSERVER_MIN_CLIENTS_IN_CHANNEL_BEFORE_FORCED_SILENCE(true), + VIRTUALSERVER_MONTH_BYTES_DOWNLOADED(false), + VIRTUALSERVER_MONTH_BYTES_UPLOADED(false), + VIRTUALSERVER_NAME(true), + VIRTUALSERVER_NAME_PHONETIC(true), + VIRTUALSERVER_NEEDED_IDENTITY_SECURITY_LEVEL(true), + VIRTUALSERVER_PASSWORD(true), + VIRTUALSERVER_PLATFORM(false), + VIRTUALSERVER_PORT(true), + VIRTUALSERVER_PRIORITY_SPEAKER_DIMM_MODIFICATOR(true), + VIRTUALSERVER_QUERY_CLIENT_CONNECTIONS(false), + VIRTUALSERVER_QUERYCLIENTSONLINE(false), + VIRTUALSERVER_RESERVED_SLOTS(true), + VIRTUALSERVER_STATUS(true), + VIRTUALSERVER_TOTAL_BYTES_DOWNLOADED(false), + VIRTUALSERVER_TOTAL_BYTES_UPLOADED(false), + VIRTUALSERVER_TOTAL_PACKETLOSS_CONTROL(false), + VIRTUALSERVER_TOTAL_PACKETLOSS_KEEPALIVE(false), + VIRTUALSERVER_TOTAL_PACKETLOSS_SPEECH(false), + VIRTUALSERVER_TOTAL_PACKETLOSS_TOTAL(false), + VIRTUALSERVER_TOTAL_PING(false), + VIRTUALSERVER_UNIQUE_IDENTIFIER(false), + VIRTUALSERVER_UPLOAD_QUOTA(true), + VIRTUALSERVER_UPTIME(false), + VIRTUALSERVER_VERSION(false), + VIRTUALSERVER_WEBLIST_ENABLED(true), + VIRTUALSERVER_WELCOMEMESSAGE(true); + + private final boolean changeable; + + VirtualServerProperty(boolean changeable) { + this.changeable = changeable; + } + + @Override + public String getName() { + return name().toLowerCase(Locale.ROOT); + } + + @Override + public boolean isChangeable() { + return changeable; + } +} diff --git a/src/main/java/com/github/manevolent/ts3j/api/VirtualServerStatus.java b/src/main/java/com/github/manevolent/ts3j/api/VirtualServerStatus.java new file mode 100644 index 0000000..631debe --- /dev/null +++ b/src/main/java/com/github/manevolent/ts3j/api/VirtualServerStatus.java @@ -0,0 +1,48 @@ +package com.github.manevolent.ts3j.api; + +/* + * #%L + * TeamSpeak 3 Java API + * %% + * Copyright (C) 2014 Bert De Geyter + * %% + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * #L% + */ + +public enum VirtualServerStatus { + + ONLINE("online"), + OFFLINE("offline"), + DEPLOY_RUNNING("deploy running"), + BOOTING_UP("booting up"), + SHUTTING_DOWN("shutting down"), + VIRTUAL_ONLINE("virtual online"), + UNKNOWN("unknown"); + + private final String name; + + VirtualServerStatus(String name) { + this.name = name; + } + + public String getName() { + return name; + } +} diff --git a/src/main/java/com/github/manevolent/ts3j/api/Wrapper.java b/src/main/java/com/github/manevolent/ts3j/api/Wrapper.java new file mode 100644 index 0000000..52c448a --- /dev/null +++ b/src/main/java/com/github/manevolent/ts3j/api/Wrapper.java @@ -0,0 +1,215 @@ +package com.github.manevolent.ts3j.api; + +/* + * #%L + * TeamSpeak 3 Java API + * %% + * Copyright (C) 2014 Bert De Geyter + * %% + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * #L% + */ + +import java.util.Collections; +import java.util.Map; + +/** + * A wrapper class around a {@link Map}. + *

+ * We use wrapper classes instead of just passing around plain Maps because + *

    + *
  • it's more descriptive
  • + *
  • there's no confusion between types (e.g. {@code Client} and {@code Channel})
  • + *
  • we can create getters for the specific use-cases
  • + *
  • we don't have to check for {@code null} each time
  • + *
+ */ +public class Wrapper { + + public static final Wrapper EMPTY = new Wrapper(Collections.emptyMap()); + + private final Map map; + + /** + * Creates a new wrapper around the given map. + * + * @param map + * the Map to abstract, cannot be {@code null} + */ + public Wrapper(Map map) { + this.map = map; + } + + /** + * Gets the map underlying this {@code Wrapper}. + * + * @return the underlying map + */ + public Map getMap() { + return map; + } + + /** + * Gets a property as a boolean from the underlying map. + * Returns {@code true} if the property exists in the map and its value is {@code "1"}. + * + * @param propertyName + * the name of the property + * + * @return the boolean value of the property or {@code false} if the property doesn't exist + */ + public boolean getBoolean(String propertyName) { + return getInt(propertyName) == 1; + } + + /** + * Gets a property as a boolean from the underlying map. + * Returns {@code true} if the property exists in the map and its value is {@code "1"}. + * + * @param property + * the property + * + * @return the boolean value of the property or {@code false} if the property doesn't exist + */ + public boolean getBoolean(Property property) { + return getBoolean(property.getName()); + } + + /** + * Gets a property as a double from the underlying map. + * If the property doesn't exist in the underlying map, {@code -1.0} is returned. + * + * @param propertyName + * the name of the property + * + * @return the double value of the property or {@code -1.0} if the property doesn't exist + */ + public double getDouble(String propertyName) { + final String value = get(propertyName); + if (value == null || value.isEmpty()) { + return -1D; + } + return Double.valueOf(value); + } + + /** + * Gets a property as a double from the underlying map. + * If the property doesn't exist in the underlying map, {@code -1.0} is returned. + * + * @param property + * the property + * + * @return the double value of the property or {@code -1.0} if the property doesn't exist + */ + public double getDouble(Property property) { + return getDouble(property.getName()); + } + + /** + * Gets a property as a long from the underlying map. + * If the property doesn't exist in the underlying map, {@code -1} is returned. + * + * @param propertyName + * the name of the property + * + * @return the long value of the property or {@code -1} if the property doesn't exist + */ + public long getLong(String propertyName) { + final String value = get(propertyName); + if (value == null || value.isEmpty()) { + return -1L; + } + return Long.parseLong(value); + } + + /** + * Gets a property as a long from the underlying map. + * If the property doesn't exist in the underlying map, {@code -1} is returned. + * + * @param property + * the property + * + * @return the long value of the property or {@code -1} if the property doesn't exist + */ + public long getLong(Property property) { + return getLong(property.getName()); + } + + /** + * Gets a property as an integer from the underlying map. + * If the property doesn't exist in the underlying map, {@code -1} is returned. + * + * @param propertyName + * the name of the property + * + * @return the integer value of the property or {@code -1} if the property doesn't exist + */ + public int getInt(String propertyName) { + final String value = get(propertyName); + if (value == null || value.isEmpty()) { + return -1; + } + return Integer.parseInt(value); + } + + /** + * Gets a property as an integer from the underlying map. + * If the property doesn't exist in the underlying map, {@code -1} is returned. + * + * @param property + * the property + * + * @return the integer value of the property or {@code -1} if the property doesn't exist + */ + public int getInt(Property property) { + return getInt(property.getName()); + } + + /** + * Gets a property as a String from the underlying map. + * If the property doesn't exist in the underlying map, an empty String is returned. + * + * @param propertyName + * the name of the property + * + * @return the String value of the property or an empty String if the property doesn't exist + */ + public String get(String propertyName) { + final String result = map.get(propertyName); + return result != null ? result : ""; + } + + /** + * Gets a property as a {@code String} from the underlying map. + * If the property doesn't exist in the underlying map, an empty String is returned. + * + * @param property + * the property + * + * @return the String value of the property or an empty String if the property doesn't exist + */ + public String get(Property property) { + return get(property.getName()); + } + + @Override + public String toString() { + return map.toString(); + } +} diff --git a/src/main/java/com/github/manevolent/ts3j/command/Command.java b/src/main/java/com/github/manevolent/ts3j/command/Command.java index 5347f73..73567fc 100644 --- a/src/main/java/com/github/manevolent/ts3j/command/Command.java +++ b/src/main/java/com/github/manevolent/ts3j/command/Command.java @@ -3,6 +3,9 @@ package com.github.manevolent.ts3j.command; import com.github.manevolent.ts3j.command.parameter.CommandParameter; import com.github.manevolent.ts3j.protocol.ProtocolRole; +import java.util.LinkedHashMap; +import java.util.Map; + public interface Command { /** * Gets the name, or label, of this command. @@ -22,12 +25,14 @@ public interface Command { */ Iterable getParameters(); - /** - * Finds if the command is expected to be responded to with a specific return_code. - * This is handled by supporting protocol handlers, not by the command code itself. - * @return true if the command is expected to support a return_code. - */ - default boolean willExpectResponse() { return false; } + default Map toMap() { + Map map = new LinkedHashMap<>(); + + for (CommandParameter parameter : getParameters()) + map.put(parameter.getName(), parameter.getValue()); + + return map; + } void add(CommandParameter parameter); diff --git a/src/main/java/com/github/manevolent/ts3j/command/CommandException.java b/src/main/java/com/github/manevolent/ts3j/command/CommandException.java new file mode 100644 index 0000000..4eab255 --- /dev/null +++ b/src/main/java/com/github/manevolent/ts3j/command/CommandException.java @@ -0,0 +1,19 @@ +package com.github.manevolent.ts3j.command; + +public class CommandException extends Exception { + private final int errorId; + + public CommandException(Throwable cause, int errorId) { + super(cause); + this.errorId = errorId; + } + + public CommandException(String message, int errorId) { + super(message); + this.errorId = errorId; + } + + public int getErrorId() { + return errorId; + } +} diff --git a/src/main/java/com/github/manevolent/ts3j/command/CommandHandler.java b/src/main/java/com/github/manevolent/ts3j/command/CommandHandler.java deleted file mode 100644 index dddeddb..0000000 --- a/src/main/java/com/github/manevolent/ts3j/command/CommandHandler.java +++ /dev/null @@ -1,46 +0,0 @@ -package com.github.manevolent.ts3j.command; - -import com.github.manevolent.ts3j.command.client.ClientChannelListFinishedProcessor; -import com.github.manevolent.ts3j.command.client.ClientChannelListProcessor; -import com.github.manevolent.ts3j.command.client.ClientInitServerProcessor; -import com.github.manevolent.ts3j.command.client.ClientNotifyClientEnterViewProcessor; -import com.github.manevolent.ts3j.protocol.socket.client.AbstractTeamspeakClientSocket; -import com.github.manevolent.ts3j.util.Ts3Debugging; - -import java.util.HashMap; -import java.util.Map; - -public final class CommandHandler implements CommandProcessor { - private final Map commandProcessors = new HashMap<>(); - - protected CommandHandler() { - - } - - @Override - public void process(AbstractTeamspeakClientSocket socket, MultiCommand multiCommand) - throws CommandProcessException { - CommandProcessor processor = commandProcessors.get(multiCommand.getName().toLowerCase()); - if (processor != null) - processor.process(socket, multiCommand); - } - - @Override - public void process(AbstractTeamspeakClientSocket socket, SingleCommand command) - throws CommandProcessException { - CommandProcessor processor = commandProcessors.get(command.getName().toLowerCase()); - if (processor != null) - processor.process(socket, command); - } - - public static CommandHandler createLocalClientHandler() { - CommandHandler handler = new CommandHandler(); - - handler.commandProcessors.put("initserver", new ClientInitServerProcessor()); - handler.commandProcessors.put("channellist", new ClientChannelListProcessor()); - handler.commandProcessors.put("notifycliententerview", new ClientNotifyClientEnterViewProcessor()); - handler.commandProcessors.put("channellistfinished", new ClientChannelListFinishedProcessor()); - - return handler; - } -} diff --git a/src/main/java/com/github/manevolent/ts3j/command/CommandProcessor.java b/src/main/java/com/github/manevolent/ts3j/command/CommandProcessor.java index 21ca334..373bbea 100644 --- a/src/main/java/com/github/manevolent/ts3j/command/CommandProcessor.java +++ b/src/main/java/com/github/manevolent/ts3j/command/CommandProcessor.java @@ -9,7 +9,6 @@ public interface CommandProcessor { for (SingleCommand singleCommand : multiCommand.simplify()) process(client, singleCommand); } - default void process(AbstractTeamspeakClientSocket client, SingleCommand singleCommand) throws CommandProcessException { } diff --git a/src/main/java/com/github/manevolent/ts3j/command/MultiCommand.java b/src/main/java/com/github/manevolent/ts3j/command/MultiCommand.java index 3e325d6..0e66d28 100644 --- a/src/main/java/com/github/manevolent/ts3j/command/MultiCommand.java +++ b/src/main/java/com/github/manevolent/ts3j/command/MultiCommand.java @@ -68,19 +68,25 @@ public class MultiCommand implements Command { boolean first = i == 0; boolean last = i == singleCommands.size() - 1; - if (!first) builder.append("\\p"); + if (!first) builder.append("|"); for (CommandParameter parameter : singleCommands.get(i).getParameters()) { builder.append(" " + (parameter.toString()).trim()); } } - return builder.toString(); + return builder.toString().trim(); } public static MultiCommand parse(ProtocolRole role, String text) { String[] labelAndText = text.split(" ", 2); String label = labelAndText[0].toLowerCase(); + + if (label.contains("=")) { + label = ""; + labelAndText[1] = text; // No command label! + } + String[] commands = labelAndText.length > 1 ? labelAndText[1].split("\\|") : new String[0]; List singleCommands = new LinkedList<>(); @@ -109,7 +115,15 @@ public class MultiCommand implements Command { } } - singleCommands.add(new SingleCommand(label, role, parameterList)); + // Replace static variables + SingleCommand command = new SingleCommand(label, role, parameterList); + + if (singleCommands.size() > 0) { + for (CommandParameter parameter : singleCommands.get(0).getParameters()) + if (!command.has(parameter.getName())) command.add(parameter); + } + + singleCommands.add(command); } return new MultiCommand(label, role, singleCommands); diff --git a/src/main/java/com/github/manevolent/ts3j/command/client/ClientChannelListFinishedProcessor.java b/src/main/java/com/github/manevolent/ts3j/command/client/ClientChannelListFinishedProcessor.java deleted file mode 100644 index c840367..0000000 --- a/src/main/java/com/github/manevolent/ts3j/command/client/ClientChannelListFinishedProcessor.java +++ /dev/null @@ -1,20 +0,0 @@ -package com.github.manevolent.ts3j.command.client; - -import com.github.manevolent.ts3j.command.CommandProcessException; -import com.github.manevolent.ts3j.command.CommandProcessor; -import com.github.manevolent.ts3j.command.MultiCommand; -import com.github.manevolent.ts3j.protocol.client.ClientConnectionState; -import com.github.manevolent.ts3j.protocol.socket.client.AbstractTeamspeakClientSocket; - -public class ClientChannelListFinishedProcessor implements CommandProcessor { - @Override - public void process(AbstractTeamspeakClientSocket client, - MultiCommand command) throws CommandProcessException { - if (client.getState() == ClientConnectionState.RETRIEVING_DATA) - try { - client.setState(ClientConnectionState.CONNECTED); - } catch (Exception e) { - throw new CommandProcessException(e); - } - } -} diff --git a/src/main/java/com/github/manevolent/ts3j/command/client/ClientChannelListProcessor.java b/src/main/java/com/github/manevolent/ts3j/command/client/ClientChannelListProcessor.java deleted file mode 100644 index 4f77589..0000000 --- a/src/main/java/com/github/manevolent/ts3j/command/client/ClientChannelListProcessor.java +++ /dev/null @@ -1,45 +0,0 @@ -package com.github.manevolent.ts3j.command.client; - -import com.github.manevolent.ts3j.command.CommandProcessException; -import com.github.manevolent.ts3j.command.CommandProcessor; -import com.github.manevolent.ts3j.command.SingleCommand; -import com.github.manevolent.ts3j.enums.CodecType; -import com.github.manevolent.ts3j.model.Channel; -import com.github.manevolent.ts3j.protocol.socket.client.AbstractTeamspeakClientSocket; - -public class ClientChannelListProcessor implements CommandProcessor { - @Override - public void process(AbstractTeamspeakClientSocket client, - SingleCommand command) throws CommandProcessException { - int cid = Integer.parseInt(command.get("cid").getValue()); - - Channel channel = client.getVirtualServer().getChannelById(cid); - if (channel == null) - channel = new Channel( - client.getVirtualServer(), Integer.parseInt(command.get("cid").getValue()) - ); - - channel.setName(command.get("channel_name").getValue()); - channel.setCodec(CodecType.fromId(Integer.parseInt(command.get("channel_codec").getValue()))); - channel.setCodecQuality(Integer.parseInt(command.get("channel_codec_quality").getValue())); - channel.setMaxClients(Integer.parseInt(command.get("channel_maxclients").getValue())); - channel.setMaxFamilyClients(Integer.parseInt(command.get("channel_maxfamilyclients").getValue())); - channel.setOrder(Integer.parseInt(command.get("channel_order").getValue())); - channel.setPermanent(command.get("channel_flag_permanent").getValue().equals("1")); - channel.setSemiPermanent(command.get("channel_flag_semi_permanent").getValue().equals("1")); - channel.setServerDefault(command.get("channel_flag_default").getValue().equals("1")); - channel.setHasPassword(command.get("channel_flag_password").getValue().equals("1")); - channel.setCodecLatencyFactor(command.get("channel_codec_latency_factor").getValue().equals("1")); - channel.setUnencrypted(command.get("channel_codec_is_unencrypted").getValue().equals("1")); - channel.setDeleteDelay(Integer.parseInt(command.get("channel_delete_delay").getValue())); - channel.setUnlimited(command.get("channel_flag_maxclients_unlimited").getValue().equals("1")); - channel.setFamilyUnlimited(command.get("channel_flag_maxfamilyclients_unlimited").getValue().equals("1")); - channel.setInheritingMaxfamilyUnlimited(command.get("channel_flag_maxfamilyclients_inherited").getValue().equals("1")); - channel.setNeededTalkPower(Integer.parseInt(command.get("channel_needed_talk_power").getValue())); - channel.setForcingSilence(command.get("channel_forced_silence").getValue().equals("1")); - channel.setIconId(Integer.parseInt(command.get("channel_icon_id").getValue())); - channel.setPrivated(command.get("channel_flag_private").getValue().equals("1")); - - client.getVirtualServer().updateChannel(channel); - } -} diff --git a/src/main/java/com/github/manevolent/ts3j/command/client/ClientInitServerProcessor.java b/src/main/java/com/github/manevolent/ts3j/command/client/ClientInitServerProcessor.java deleted file mode 100644 index 8e47a02..0000000 --- a/src/main/java/com/github/manevolent/ts3j/command/client/ClientInitServerProcessor.java +++ /dev/null @@ -1,47 +0,0 @@ -package com.github.manevolent.ts3j.command.client; - -import com.github.manevolent.ts3j.command.CommandProcessException; -import com.github.manevolent.ts3j.command.CommandProcessor; -import com.github.manevolent.ts3j.command.MultiCommand; -import com.github.manevolent.ts3j.command.SingleCommand; -import com.github.manevolent.ts3j.enums.HostBannerMode; -import com.github.manevolent.ts3j.enums.HostMessageMode; -import com.github.manevolent.ts3j.enums.VoiceEncryptionMode; -import com.github.manevolent.ts3j.model.VirtualServer; -import com.github.manevolent.ts3j.protocol.client.ClientConnectionState; -import com.github.manevolent.ts3j.protocol.socket.client.AbstractTeamspeakClientSocket; - -public class ClientInitServerProcessor implements CommandProcessor { - @Override - public void process(AbstractTeamspeakClientSocket client, - MultiCommand multiCommand) throws CommandProcessException { - SingleCommand command = multiCommand.simplifyOne(); - - VirtualServer server = new VirtualServer(); - - server.setName(command.get("virtualserver_name").getValue()); - server.setWelcomeMessage(command.get("virtualserver_welcomemessage").getValue()); - server.setPlatform(command.get("virtualserver_platform").getValue()); - server.setVersion(command.get("virtualserver_version").getValue()); - server.setMaxClients(Integer.parseInt(command.get("virtualserver_maxclients").getValue())); - server.setCreated(Long.parseLong(command.get("virtualserver_created").getValue())); - server.setEncryptionMode(VoiceEncryptionMode.fromId(Integer.parseInt(command.get("virtualserver_codec_encryption_mode").getValue()))); - server.setHostMessageMode(HostMessageMode.fromId(Integer.parseInt(command.get("virtualserver_hostmessage_mode").getValue()))); - server.setDefaultGroupId(Integer.parseInt(command.get("virtualserver_default_server_group").getValue())); - server.setDefaultChannelGroupId(Integer.parseInt(command.get("virtualserver_default_channel_group").getValue())); - server.setHostbannerUrl(command.get("virtualserver_hostbanner_gfx_url").getValue()); - server.setPrioritySpeakerDimmModifier(Double.parseDouble(command.get("virtualserver_priority_speaker_dimm_modificator").getValue())); - server.setId(Integer.parseInt(command.get("virtualserver_id").getValue())); - server.setNamePhonetic(command.get("virtualserver_name_phonetic").getValue()); - server.setIconId(Long.parseLong(command.get("virtualserver_icon_id").getValue())); - server.setServerIp(command.get("virtualserver_ip").getValue()); - server.setAskForPriviledgeKey(Integer.parseInt(command.get("virtualserver_ask_for_privilegekey").getValue()) == 1); - server.setHostBannerMode(HostBannerMode.fromId(Integer.parseInt(command.get("virtualserver_hostbanner_mode").getValue()))); - server.setDefaultTempChannelDeleteDelay(Integer.parseInt(command.get("virtualserver_channel_temp_delete_delay_default").getValue())); - server.setNickname(command.get("virtualserver_nickname").getValue()); - - client.setVirtualServer(server); - - client.setClientId(Integer.parseInt(command.get("aclid").getValue())); - } -} diff --git a/src/main/java/com/github/manevolent/ts3j/command/client/ClientNotifyClientEnterViewProcessor.java b/src/main/java/com/github/manevolent/ts3j/command/client/ClientNotifyClientEnterViewProcessor.java deleted file mode 100644 index 9fe4d9e..0000000 --- a/src/main/java/com/github/manevolent/ts3j/command/client/ClientNotifyClientEnterViewProcessor.java +++ /dev/null @@ -1,71 +0,0 @@ -package com.github.manevolent.ts3j.command.client; - -import com.github.manevolent.ts3j.command.CommandProcessException; -import com.github.manevolent.ts3j.command.CommandProcessor; -import com.github.manevolent.ts3j.command.SingleCommand; -import com.github.manevolent.ts3j.enums.ClientType; -import com.github.manevolent.ts3j.identity.Uid; -import com.github.manevolent.ts3j.model.Client; -import com.github.manevolent.ts3j.protocol.socket.client.AbstractTeamspeakClientSocket; - -import java.util.Arrays; -import java.util.stream.Collectors; - -public class ClientNotifyClientEnterViewProcessor implements CommandProcessor { - @Override - public void process(AbstractTeamspeakClientSocket client, - SingleCommand command) throws CommandProcessException { - int clientId = Integer.parseInt(command.get("clid").getValue()); - - Client newClient = client.getVirtualServer().getClientById(clientId); - if (newClient == null) - newClient = new Client( - Integer.parseInt(command.get("clid").getValue()), - Integer.parseInt(command.get("client_database_id").getValue()), - client.getVirtualServer(), - new Uid(command.get("client_unique_identifier").getValue()), - ClientType.fromId(Integer.parseInt(command.get("client_type").getValue()))); - - newClient.setNickname(command.get("client_nickname").getValue()); - - newClient.setInputMuted(command.get("client_input_muted").getValue().equals("1")); - newClient.setOutputMuted(command.get("client_output_muted").getValue().equals("1")); - - newClient.setInputHardware(command.get("client_input_hardware").getValue().equals("1")); - newClient.setOutputHardware(command.get("client_output_hardware").getValue().equals("1")); - - newClient.setRecording(command.get("client_is_recording").getValue().equals("1")); - - newClient.setChannelGroupId(Integer.parseInt(command.get("client_channel_group_id").getValue())); - - newClient.setServerGroupIds( - Arrays.stream(command.get("client_servergroups").getValue().split(",")).map( - Integer::parseInt - ).collect(Collectors.toList()) - ); - - newClient.setAway(command.get("client_away").getValue().equals("1")); - - newClient.setTalkPower(Integer.parseInt(command.get("client_talk_power").getValue())); - - newClient.setTalkRequested(command.get("client_talk_request").getValue().equals("1")); - - newClient.setTalker(command.get("client_is_talker").getValue().equals("1")); - - newClient.setPrioritySpeaker(command.get("client_is_priority_speaker").getValue().equals("1")); - - newClient.setUnreadMessages(Integer.parseInt(command.get("client_unread_messages").getValue())); - - newClient.setNeededServerQueryViewPower(Integer.parseInt(command.get("client_needed_serverquery_view_power").getValue())); - - newClient.setIconId(Integer.parseInt(command.get("client_icon_id").getValue())); - - newClient.setChannelCommander(command.get("client_is_channel_commander").getValue().equals("1")); - - newClient.setCountry(command.get("client_country").getValue()); - - newClient.setInheritedChannelGroupChannelId(Integer.parseInt(command.get("client_channel_group_inherited_channel_id").getValue())); - - client.getVirtualServer().updateConnectedClient(newClient); - } -} diff --git a/src/main/java/com/github/manevolent/ts3j/command/response/AbstractCommandResponse.java b/src/main/java/com/github/manevolent/ts3j/command/response/AbstractCommandResponse.java new file mode 100644 index 0000000..df10467 --- /dev/null +++ b/src/main/java/com/github/manevolent/ts3j/command/response/AbstractCommandResponse.java @@ -0,0 +1,59 @@ +package com.github.manevolent.ts3j.command.response; + +import com.github.manevolent.ts3j.command.MultiCommand; + +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; +import java.util.function.Function; + +public abstract class AbstractCommandResponse implements CommandResponse { + private final Function, T> processor; + + private CompletableFuture> future = + new CompletableFuture<>(); + + public AbstractCommandResponse(Function, T> processor) { + this.processor = processor; + } + + /** + * Completes the command without any post-mapping processing, lowering overhead. + */ + @Override + public void complete() + throws ExecutionException, InterruptedException { + future.get(); + } + + @Override + public T get(long timeoutMillis) + throws TimeoutException, ExecutionException, InterruptedException { + return map(future.get(timeoutMillis, TimeUnit.MILLISECONDS)); + } + + @Override + public T get() + throws ExecutionException, InterruptedException { + return map(future.get()); + } + + protected void completeSuccess(Iterable commands) { + future.complete(commands); + } + + protected void completeFailure(Throwable thrown) { + future.completeExceptionally(thrown); + } + + /** + * Maps the result of the command. Executes post-retrieval on the end-user thread, a nifty trick to to increase + * parallel execution speed and handling. + * @param result result to process. + * @return mapped result. + */ + private T map(Iterable result) { + return processor.apply(result); + } +} diff --git a/src/main/java/com/github/manevolent/ts3j/command/response/CommandResponse.java b/src/main/java/com/github/manevolent/ts3j/command/response/CommandResponse.java index 68e7666..8712dcb 100644 --- a/src/main/java/com/github/manevolent/ts3j/command/response/CommandResponse.java +++ b/src/main/java/com/github/manevolent/ts3j/command/response/CommandResponse.java @@ -1,76 +1,16 @@ package com.github.manevolent.ts3j.command.response; -import com.github.manevolent.ts3j.command.Command; -import com.github.manevolent.ts3j.command.MultiCommand; - +import java.util.concurrent.ExecutionException; import java.util.concurrent.TimeoutException; -public class CommandResponse { - private final Object returnLock = new Object(); - private final Command command; - private final int returnCode; +public interface CommandResponse { - private long dispatchedTime; - private MultiCommand returnedCommand; - - public CommandResponse(Command command, int returnCode) { - this.command = command; - this.returnCode = returnCode; + default void complete() + throws ExecutionException, InterruptedException { + get(); } - public Command getCommand() { - return command; - } + T get(long timeoutMillis) throws TimeoutException, ExecutionException, InterruptedException; + T get() throws ExecutionException, InterruptedException; - public int getReturnCode() { - return returnCode; - } - - public MultiCommand getResponse() - throws InterruptedException, TimeoutException { - return getResponse(Integer.MAX_VALUE); - } - - public MultiCommand getResponse(int millis) - throws InterruptedException, TimeoutException { - if (returnCode < 0) return null; - - synchronized (returnLock) { - long waited, toWait; - - while (getReturnedCommand() == null) { - waited = System.currentTimeMillis() - getDispatchedTime(); - toWait = millis - waited; - - if (toWait <= 0) throw new TimeoutException(); - - returnLock.wait(toWait); - } - - return getReturnedCommand(); - } - } - - public long getDispatchedTime() { - return dispatchedTime; - } - - public void setDispatchedTime(long dispatchedTime) { - this.dispatchedTime = dispatchedTime; - } - - public MultiCommand getReturnedCommand() { - return returnedCommand; - } - - public void setReturnedCommand(MultiCommand returnedCommand) { - synchronized (returnLock) { - if (this.returnCode < 0 ) throw new IllegalArgumentException("not expecting return command"); - if (this.returnedCommand != null) throw new IllegalArgumentException("already set return command"); - - this.returnedCommand = returnedCommand; - - returnLock.notifyAll(); - } - } } diff --git a/src/main/java/com/github/manevolent/ts3j/enums/ClientListOptions.java b/src/main/java/com/github/manevolent/ts3j/enums/ClientListOptions.java deleted file mode 100644 index 6d3f3de..0000000 --- a/src/main/java/com/github/manevolent/ts3j/enums/ClientListOptions.java +++ /dev/null @@ -1,29 +0,0 @@ -package com.github.manevolent.ts3j.enums; - -public enum ClientListOptions { - UID(1 << 0), - AWAY(1 << 1), - VOICE(1 << 2), - TIMES(1 << 3), - GROUPS(1 << 4), - INFO(1 << 5), - ICON(1 << 6), - COUNTRY(1 << 7); - - private final int index; - - ClientListOptions(int index) { - this.index = index; - } - - public int getIndex() { - return index; - } - - public static ClientListOptions fromId(int index) { - for (ClientListOptions value : values()) - if (value.getIndex() == index) return value; - - throw new IllegalArgumentException("invalid index: " + index); - } -} diff --git a/src/main/java/com/github/manevolent/ts3j/enums/ClientType.java b/src/main/java/com/github/manevolent/ts3j/enums/ClientType.java deleted file mode 100644 index 69e44a7..0000000 --- a/src/main/java/com/github/manevolent/ts3j/enums/ClientType.java +++ /dev/null @@ -1,23 +0,0 @@ -package com.github.manevolent.ts3j.enums; - -public enum ClientType { - FULL(0), - QUERY(1); - - private final int index; - - ClientType(int index) { - this.index = index; - } - - public int getIndex() { - return index; - } - - public static ClientType fromId(int index) { - for (ClientType value : values()) - if (value.getIndex() == index) return value; - - throw new IllegalArgumentException("invalid index: " + index); - } -} diff --git a/src/main/java/com/github/manevolent/ts3j/enums/CommandPartType.java b/src/main/java/com/github/manevolent/ts3j/enums/CommandPartType.java deleted file mode 100644 index f5044bc..0000000 --- a/src/main/java/com/github/manevolent/ts3j/enums/CommandPartType.java +++ /dev/null @@ -1,7 +0,0 @@ -package com.github.manevolent.ts3j.enums; - -public enum CommandPartType { - SINGLE_PARAMETER, - MULTI_PAREMTER, - OPTION; -} diff --git a/src/main/java/com/github/manevolent/ts3j/enums/DisconnectReason.java b/src/main/java/com/github/manevolent/ts3j/enums/DisconnectReason.java deleted file mode 100644 index a621047..0000000 --- a/src/main/java/com/github/manevolent/ts3j/enums/DisconnectReason.java +++ /dev/null @@ -1,35 +0,0 @@ -package com.github.manevolent.ts3j.enums; - -public enum DisconnectReason { - USER_ACTION(0), - USER_OR_CHANNEL_MOVED(1), - SUBSCRIPTION_CHANGED(2), - TIMEOUT(3), - KICKED_FROM_CHANNEL(4), - KICKED_FROM_SERVER(5), - BANNED(6), - SERVER_STOPPED(7), - LEFT_SERVER(8), - CHANNEL_UPDATED(9), - SERVER_OR_CHANNEL_EDITED(10), - SERVER_SHUTDOWN(11) - - ; - - private final int index; - - DisconnectReason(int index) { - this.index = index; - } - - public int getIndex() { - return index; - } - - public static DisconnectReason fromId(int index) { - for (DisconnectReason value : values()) - if (value.getIndex() == index) return value; - - throw new IllegalArgumentException("invalid index: " + index); - } -} diff --git a/src/main/java/com/github/manevolent/ts3j/enums/GroupNamingMode.java b/src/main/java/com/github/manevolent/ts3j/enums/GroupNamingMode.java deleted file mode 100644 index 3506c7c..0000000 --- a/src/main/java/com/github/manevolent/ts3j/enums/GroupNamingMode.java +++ /dev/null @@ -1,29 +0,0 @@ -package com.github.manevolent.ts3j.enums; - -public enum GroupNamingMode { - UID(1 << 0), - AWAY(1 << 1), - VOICE(1 << 2), - TIMES(1 << 3), - GROUPS(1 << 4), - INFO(1 << 5), - ICON(1 << 6), - COUNTRY(1 << 7); - - private final int index; - - GroupNamingMode(int index) { - this.index = index; - } - - public int getIndex() { - return index; - } - - public static GroupNamingMode fromId(int index) { - for (GroupNamingMode value : values()) - if (value.getIndex() == index) return value; - - throw new IllegalArgumentException("invalid index: " + index); - } -} diff --git a/src/main/java/com/github/manevolent/ts3j/enums/GroupType.java b/src/main/java/com/github/manevolent/ts3j/enums/GroupType.java deleted file mode 100644 index e950104..0000000 --- a/src/main/java/com/github/manevolent/ts3j/enums/GroupType.java +++ /dev/null @@ -1,26 +0,0 @@ -package com.github.manevolent.ts3j.enums; - -public enum GroupType { - TEMPLATE(0), - REGULAR(1), - QUERY(2) - - ; - - private final int index; - - GroupType(int index) { - this.index = index; - } - - public int getIndex() { - return index; - } - - public static GroupType fromId(int index) { - for (GroupType value : values()) - if (value.getIndex() == index) return value; - - throw new IllegalArgumentException("invalid index: " + index); - } -} diff --git a/src/main/java/com/github/manevolent/ts3j/enums/GroupWhisperType.java b/src/main/java/com/github/manevolent/ts3j/enums/GroupWhisperType.java deleted file mode 100644 index 6b63ab7..0000000 --- a/src/main/java/com/github/manevolent/ts3j/enums/GroupWhisperType.java +++ /dev/null @@ -1,29 +0,0 @@ -package com.github.manevolent.ts3j.enums; - -public enum GroupWhisperType { - ALL_CHANNELS(0), - CURRENT_CHANNEL(1), - ALL_PARENT_CHANNEL(2), - CHANNEL_FAMILY(3), - COMPLETE_CHANNEL_FAMILY(4), - SUBCHANNELS(5) - - ; - - private final int index; - - GroupWhisperType(int index) { - this.index = index; - } - - public int getIndex() { - return index; - } - - public static GroupWhisperType fromId(int index) { - for (GroupWhisperType value : values()) - if (value.getIndex() == index) return value; - - throw new IllegalArgumentException("invalid index: " + index); - } -} diff --git a/src/main/java/com/github/manevolent/ts3j/enums/HostBannerMode.java b/src/main/java/com/github/manevolent/ts3j/enums/HostBannerMode.java deleted file mode 100644 index 3e4f106..0000000 --- a/src/main/java/com/github/manevolent/ts3j/enums/HostBannerMode.java +++ /dev/null @@ -1,26 +0,0 @@ -package com.github.manevolent.ts3j.enums; - -public enum HostBannerMode { - NO_ADJUST(0), - IGNORE_ASPECT_RATIO(1), - KEEP_ASPECT(2) - - ; - - private final int index; - - HostBannerMode(int index) { - this.index = index; - } - - public int getIndex() { - return index; - } - - public static HostBannerMode fromId(int index) { - for (HostBannerMode value : values()) - if (value.getIndex() == index) return value; - - throw new IllegalArgumentException("invalid index: " + index); - } -} diff --git a/src/main/java/com/github/manevolent/ts3j/enums/HostMessageMode.java b/src/main/java/com/github/manevolent/ts3j/enums/HostMessageMode.java deleted file mode 100644 index df3a35c..0000000 --- a/src/main/java/com/github/manevolent/ts3j/enums/HostMessageMode.java +++ /dev/null @@ -1,27 +0,0 @@ -package com.github.manevolent.ts3j.enums; - -public enum HostMessageMode { - NONE(0), - LOG(1), - MODAL(2), - MODAL_QUIT(3) - - ; - - private final int index; - - HostMessageMode(int index) { - this.index = index; - } - - public int getIndex() { - return index; - } - - public static HostMessageMode fromId(int index) { - for (HostMessageMode value : values()) - if (value.getIndex() == index) return value; - - throw new IllegalArgumentException("invalid index: " + index); - } -} diff --git a/src/main/java/com/github/manevolent/ts3j/enums/KickIdentifier.java b/src/main/java/com/github/manevolent/ts3j/enums/KickIdentifier.java deleted file mode 100644 index 7b1c878..0000000 --- a/src/main/java/com/github/manevolent/ts3j/enums/KickIdentifier.java +++ /dev/null @@ -1,25 +0,0 @@ -package com.github.manevolent.ts3j.enums; - -public enum KickIdentifier { - CHANNEL(4), - SERVER(5) - - ; - - private final int index; - - KickIdentifier(int index) { - this.index = index; - } - - public int getIndex() { - return index; - } - - public static KickIdentifier fromId(int index) { - for (KickIdentifier value : values()) - if (value.getIndex() == index) return value; - - throw new IllegalArgumentException("invalid index: " + index); - } -} diff --git a/src/main/java/com/github/manevolent/ts3j/enums/LogLevel.java b/src/main/java/com/github/manevolent/ts3j/enums/LogLevel.java deleted file mode 100644 index 9669f53..0000000 --- a/src/main/java/com/github/manevolent/ts3j/enums/LogLevel.java +++ /dev/null @@ -1,27 +0,0 @@ -package com.github.manevolent.ts3j.enums; - -public enum LogLevel { - ERROR(1), - WARNING(2), - DEBUG(3), - INFO(4) - - ; - - private final int index; - - LogLevel(int index) { - this.index = index; - } - - public int getIndex() { - return index; - } - - public static LogLevel fromId(int index) { - for (LogLevel value : values()) - if (value.getIndex() == index) return value; - - throw new IllegalArgumentException("invalid index: " + index); - } -} diff --git a/src/main/java/com/github/manevolent/ts3j/enums/PermissionGroupType.java b/src/main/java/com/github/manevolent/ts3j/enums/PermissionGroupType.java deleted file mode 100644 index 96c73fc..0000000 --- a/src/main/java/com/github/manevolent/ts3j/enums/PermissionGroupType.java +++ /dev/null @@ -1,28 +0,0 @@ -package com.github.manevolent.ts3j.enums; - -public enum PermissionGroupType { - SERVER_GROUP(0), - GLOBAL_CLIENT(1), - CHANNEL(2), - CHANNEL_GROUP(3), - CHANNEL_CLIENT(4) - - ; - - private final int index; - - PermissionGroupType(int index) { - this.index = index; - } - - public int getIndex() { - return index; - } - - public static PermissionGroupType fromId(int index) { - for (PermissionGroupType value : values()) - if (value.getIndex() == index) return value; - - throw new IllegalArgumentException("invalid index: " + index); - } -} diff --git a/src/main/java/com/github/manevolent/ts3j/enums/PluginTargetMode.java b/src/main/java/com/github/manevolent/ts3j/enums/PluginTargetMode.java deleted file mode 100644 index 5e8aabb..0000000 --- a/src/main/java/com/github/manevolent/ts3j/enums/PluginTargetMode.java +++ /dev/null @@ -1,27 +0,0 @@ -package com.github.manevolent.ts3j.enums; - -public enum PluginTargetMode { - CURRENT_CHANNEL(0), - SERVER(1), - CLIENT(2), - CURRENT_CHANNEL_SUBSCRIBED_CLIENTS(3) - - ; - - private final int index; - - PluginTargetMode(int index) { - this.index = index; - } - - public int getIndex() { - return index; - } - - public static PluginTargetMode fromId(int index) { - for (PluginTargetMode value : values()) - if (value.getIndex() == index) return value; - - throw new IllegalArgumentException("invalid index: " + index); - } -} diff --git a/src/main/java/com/github/manevolent/ts3j/enums/PriviledgeTokenType.java b/src/main/java/com/github/manevolent/ts3j/enums/PriviledgeTokenType.java deleted file mode 100644 index 39789b7..0000000 --- a/src/main/java/com/github/manevolent/ts3j/enums/PriviledgeTokenType.java +++ /dev/null @@ -1,25 +0,0 @@ -package com.github.manevolent.ts3j.enums; - -public enum PriviledgeTokenType { - SERVER_GROUP(0), - CHANNEL_GROUP(1) - - ; - - private final int index; - - PriviledgeTokenType(int index) { - this.index = index; - } - - public int getIndex() { - return index; - } - - public static PriviledgeTokenType fromId(int index) { - for (PriviledgeTokenType value : values()) - if (value.getIndex() == index) return value; - - throw new IllegalArgumentException("invalid index: " + index); - } -} diff --git a/src/main/java/com/github/manevolent/ts3j/enums/TextMessageTargetMode.java b/src/main/java/com/github/manevolent/ts3j/enums/TextMessageTargetMode.java deleted file mode 100644 index 6ff6386..0000000 --- a/src/main/java/com/github/manevolent/ts3j/enums/TextMessageTargetMode.java +++ /dev/null @@ -1,26 +0,0 @@ -package com.github.manevolent.ts3j.enums; - -public enum TextMessageTargetMode { - PRIVATE(1), - CHANNEL(2), - SERVER(3) - - ; - - private final int index; - - TextMessageTargetMode(int index) { - this.index = index; - } - - public int getIndex() { - return index; - } - - public static TextMessageTargetMode fromId(int index) { - for (TextMessageTargetMode value : values()) - if (value.getIndex() == index) return value; - - throw new IllegalArgumentException("invalid index: " + index); - } -} diff --git a/src/main/java/com/github/manevolent/ts3j/enums/VoiceEncryptionMode.java b/src/main/java/com/github/manevolent/ts3j/enums/VoiceEncryptionMode.java deleted file mode 100644 index 0b05eb7..0000000 --- a/src/main/java/com/github/manevolent/ts3j/enums/VoiceEncryptionMode.java +++ /dev/null @@ -1,26 +0,0 @@ -package com.github.manevolent.ts3j.enums; - -public enum VoiceEncryptionMode { - INDIVIDUAL(0), - DISABLED(1), - ENABLED(2) - - ; - - private final int index; - - VoiceEncryptionMode(int index) { - this.index = index; - } - - public int getIndex() { - return index; - } - - public static VoiceEncryptionMode fromId(int index) { - for (VoiceEncryptionMode value : values()) - if (value.getIndex() == index) return value; - - throw new IllegalArgumentException("invalid index: " + index); - } -} diff --git a/src/main/java/com/github/manevolent/ts3j/event/BaseEvent.java b/src/main/java/com/github/manevolent/ts3j/event/BaseEvent.java new file mode 100644 index 0000000..ad24eae --- /dev/null +++ b/src/main/java/com/github/manevolent/ts3j/event/BaseEvent.java @@ -0,0 +1,131 @@ +package com.github.manevolent.ts3j.event; + +/* + * #%L + * TeamSpeak 3 Java API + * %% + * Copyright (C) 2014 - 2015 Bert De Geyter + * %% + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * #L% + */ + +import com.github.manevolent.ts3j.api.Wrapper; + +import java.util.Collections; +import java.util.Map; + +public abstract class BaseEvent extends Wrapper implements TS3Event { + + protected BaseEvent(Map map) { + super(Collections.unmodifiableMap(map)); + } + + /** + * Gets the ID of the client who caused this event to happen. + *

+ * Because not all events are caused by clients, not all events have an invoker.
+ * Most importantly, client events (i.e. {@link ClientJoinEvent}, {@link ClientLeaveEvent} + * {@link ClientMovedEvent}) do not have an invoker if a client joined, + * quit or changed channels themselves. These values are only present if another client + * caused the event to happen by moving, kicking or banning a client. + *

+ * If the event response does not contain an invoker, this method will return {@code -1}. + *

+ * + * @return the client ID of the invoker or {@code -1} if the event does not contain an invoker + */ + public int getInvokerId() { + return getInt("invokerid"); + } + + /** + * Gets the nickname of the client who caused this event to happen. + *

+ * Because not all events are caused by clients, not all events have an invoker.
+ * Most importantly, client events (i.e. {@link ClientJoinEvent}, {@link ClientLeaveEvent} + * {@link ClientMovedEvent}) do not have an invoker if a client joined, + * quit or changed channels themselves. These values are only present if another client + * caused the event to happen by moving, kicking or banning a client. + *

+ * If the event response does not contain an invoker, this method will return an empty string. + *

+ * + * @return the nickname of the invoker or an empty string if the event does not contain an invoker + */ + public String getInvokerName() { + return get("invokername"); + } + + /** + * Gets the unique identifier of the client who caused this event to happen. + *

+ * Because not all events are caused by clients, not all events have an invoker.
+ * Most importantly, client events (i.e. {@link ClientJoinEvent}, {@link ClientLeaveEvent} + * {@link ClientMovedEvent}) do not have an invoker if a client joined, + * quit or changed channels themselves. These values are only present if another client + * caused the event to happen by moving, kicking or banning a client. + *

+ * If the event response does not contain an invoker, this method will return an empty string. + *

+ * + * @return the unique ID the invoker or an empty string if the event does not contain an invoker + */ + public String getInvokerUniqueId() { + return get("invokeruid"); + } + + /** + * Gets the reason ID of the cause of this event. + *

+ * Here's an incomplete list of known reason IDs: + *

+ * + * + * + * + * + * + * + * + * + * + * + * + *
IDDescription
-1No reason present
0No external cause
1Client was moved (by other client / by creating a new channel)
3Client timed out
4Client kicked from a channel or channel deleted
5Client kicked from the server
6Client banned from the server
8Client left the server (no external cause)
10Virtual server or channel edited
11Server shut down
+ * + * @return the reason ID for this event + */ + public int getReasonId() { + return getInt("reasonid"); + } + + /** + * Gets the reason for this event. + * This field is rarely present, even if the reason ID is non-zero. + *

+ * In case of a client getting kicked or banned, this will return the user-provided reason. + *

+ * + * @return the reason for this event or an empty string if no reason message is present + */ + public String getReasonMessage() { + return get("reasonmsg"); + } +} diff --git a/src/main/java/com/github/manevolent/ts3j/event/ChannelCreateEvent.java b/src/main/java/com/github/manevolent/ts3j/event/ChannelCreateEvent.java new file mode 100644 index 0000000..dba14ff --- /dev/null +++ b/src/main/java/com/github/manevolent/ts3j/event/ChannelCreateEvent.java @@ -0,0 +1,47 @@ +package com.github.manevolent.ts3j.event; + +/* + * #%L + * TeamSpeak 3 Java API + * %% + * Copyright (C) 2014 Bert De Geyter + * %% + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * #L% + */ + +import com.github.manevolent.ts3j.api.ChannelProperty; + +import java.util.Map; + +public class ChannelCreateEvent extends BaseEvent { + + public ChannelCreateEvent(Map map) { + super(map); + } + + public int getChannelId() { + return getInt(ChannelProperty.CID); + } + + @Override + public void fire(TS3Listener listener) { + listener.onChannelCreate(this); + } +} diff --git a/src/main/java/com/github/manevolent/ts3j/event/ChannelDeletedEvent.java b/src/main/java/com/github/manevolent/ts3j/event/ChannelDeletedEvent.java new file mode 100644 index 0000000..463d8a1 --- /dev/null +++ b/src/main/java/com/github/manevolent/ts3j/event/ChannelDeletedEvent.java @@ -0,0 +1,47 @@ +package com.github.manevolent.ts3j.event; + +/* + * #%L + * TeamSpeak 3 Java API + * %% + * Copyright (C) 2014 Bert De Geyter + * %% + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * #L% + */ + +import com.github.manevolent.ts3j.api.ChannelProperty; + +import java.util.Map; + +public class ChannelDeletedEvent extends BaseEvent { + + public ChannelDeletedEvent(Map map) { + super(map); + } + + public int getChannelId() { + return getInt(ChannelProperty.CID); + } + + @Override + public void fire(TS3Listener listener) { + listener.onChannelDeleted(this); + } +} diff --git a/src/main/java/com/github/manevolent/ts3j/event/ChannelDescriptionEditedEvent.java b/src/main/java/com/github/manevolent/ts3j/event/ChannelDescriptionEditedEvent.java new file mode 100644 index 0000000..89f22bd --- /dev/null +++ b/src/main/java/com/github/manevolent/ts3j/event/ChannelDescriptionEditedEvent.java @@ -0,0 +1,47 @@ +package com.github.manevolent.ts3j.event; + +/* + * #%L + * TeamSpeak 3 Java API + * %% + * Copyright (C) 2014 Bert De Geyter + * %% + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * #L% + */ + +import com.github.manevolent.ts3j.api.ChannelProperty; + +import java.util.Map; + +public class ChannelDescriptionEditedEvent extends BaseEvent { + + public ChannelDescriptionEditedEvent(Map map) { + super(map); + } + + public int getChannelId() { + return getInt(ChannelProperty.CID); + } + + @Override + public void fire(TS3Listener listener) { + listener.onChannelDescriptionChanged(this); + } +} diff --git a/src/main/java/com/github/manevolent/ts3j/event/ChannelEditedEvent.java b/src/main/java/com/github/manevolent/ts3j/event/ChannelEditedEvent.java new file mode 100644 index 0000000..dff621d --- /dev/null +++ b/src/main/java/com/github/manevolent/ts3j/event/ChannelEditedEvent.java @@ -0,0 +1,47 @@ +package com.github.manevolent.ts3j.event; + +/* + * #%L + * TeamSpeak 3 Java API + * %% + * Copyright (C) 2014 Bert De Geyter + * %% + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * #L% + */ + +import com.github.manevolent.ts3j.api.ChannelProperty; + +import java.util.Map; + +public class ChannelEditedEvent extends BaseEvent { + + public ChannelEditedEvent(Map map) { + super(map); + } + + public int getChannelId() { + return getInt(ChannelProperty.CID); + } + + @Override + public void fire(TS3Listener listener) { + listener.onChannelEdit(this); + } +} diff --git a/src/main/java/com/github/manevolent/ts3j/event/ChannelGroupListEvent.java b/src/main/java/com/github/manevolent/ts3j/event/ChannelGroupListEvent.java new file mode 100644 index 0000000..b92b630 --- /dev/null +++ b/src/main/java/com/github/manevolent/ts3j/event/ChannelGroupListEvent.java @@ -0,0 +1,40 @@ +package com.github.manevolent.ts3j.event; + +/* + * #%L + * TeamSpeak 3 Java API + * %% + * Copyright (C) 2014 Bert De Geyter + * %% + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * #L% + */ + +import java.util.Map; + +public class ChannelGroupListEvent extends BaseEvent { + protected ChannelGroupListEvent(Map map) { + super(map); + } + + @Override + public void fire(TS3Listener listener) { + listener.onChannelGroupList(this); + } +} diff --git a/src/main/java/com/github/manevolent/ts3j/event/ChannelMovedEvent.java b/src/main/java/com/github/manevolent/ts3j/event/ChannelMovedEvent.java new file mode 100644 index 0000000..f029c46 --- /dev/null +++ b/src/main/java/com/github/manevolent/ts3j/event/ChannelMovedEvent.java @@ -0,0 +1,55 @@ +package com.github.manevolent.ts3j.event; + +/* + * #%L + * TeamSpeak 3 Java API + * %% + * Copyright (C) 2014 Bert De Geyter + * %% + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * #L% + */ + +import com.github.manevolent.ts3j.api.ChannelProperty; + +import java.util.Map; + +public class ChannelMovedEvent extends BaseEvent { + + public ChannelMovedEvent(Map map) { + super(map); + } + + public int getChannelId() { + return getInt(ChannelProperty.CID); + } + + public int getChannelParentId() { + return getInt(ChannelProperty.CPID); + } + + public int getChannelOrder() { + return getInt(ChannelProperty.CHANNEL_ORDER); + } + + @Override + public void fire(TS3Listener listener) { + listener.onChannelMoved(this); + } +} diff --git a/src/main/java/com/github/manevolent/ts3j/event/ChannelPasswordChangedEvent.java b/src/main/java/com/github/manevolent/ts3j/event/ChannelPasswordChangedEvent.java new file mode 100644 index 0000000..16f5c7f --- /dev/null +++ b/src/main/java/com/github/manevolent/ts3j/event/ChannelPasswordChangedEvent.java @@ -0,0 +1,47 @@ +package com.github.manevolent.ts3j.event; + +/* + * #%L + * TeamSpeak 3 Java API + * %% + * Copyright (C) 2014 Bert De Geyter + * %% + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * #L% + */ + +import com.github.manevolent.ts3j.api.ChannelProperty; + +import java.util.Map; + +public class ChannelPasswordChangedEvent extends BaseEvent { + + public ChannelPasswordChangedEvent(Map map) { + super(map); + } + + public int getChannelId() { + return getInt(ChannelProperty.CID); + } + + @Override + public void fire(TS3Listener listener) { + listener.onChannelPasswordChanged(this); + } +} diff --git a/src/main/java/com/github/manevolent/ts3j/event/ClientJoinEvent.java b/src/main/java/com/github/manevolent/ts3j/event/ClientJoinEvent.java new file mode 100644 index 0000000..5f0c0a1 --- /dev/null +++ b/src/main/java/com/github/manevolent/ts3j/event/ClientJoinEvent.java @@ -0,0 +1,179 @@ +package com.github.manevolent.ts3j.event; + +/* + * #%L + * TeamSpeak 3 Java API + * %% + * Copyright (C) 2014 Bert De Geyter + * %% + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * #L% + */ + +import com.github.manevolent.ts3j.api.ClientProperty; + +import java.util.Map; + +public class ClientJoinEvent extends BaseEvent { + + public ClientJoinEvent(Map map) { + super(map); + } + + public int getClientFromId() { + return getInt("cfid"); + } + + public int getClientTargetId() { + return getInt("ctid"); + } + + public int getClientId() { + return getInt("clid"); + } + + public String getUniqueClientIdentifier() { + return get(ClientProperty.CLIENT_UNIQUE_IDENTIFIER); + } + + public String getClientNickname() { + return get(ClientProperty.CLIENT_NICKNAME); + } + + public boolean isClientInputMuted() { + return getBoolean(ClientProperty.CLIENT_INPUT_MUTED); + } + + public boolean isClientOutputMuted() { + return getBoolean(ClientProperty.CLIENT_OUTPUT_MUTED); + } + + public boolean isClientOutputOnlyMuted() { + return getBoolean(ClientProperty.CLIENT_OUTPUTONLY_MUTED); + } + + public boolean isClientUsingHardwareInput() { + return getBoolean(ClientProperty.CLIENT_INPUT_HARDWARE); + } + + public boolean isClientUsingHardwareOutput() { + return getBoolean(ClientProperty.CLIENT_OUTPUT_HARDWARE); + } + + public String getClientMetadata() { + return get(ClientProperty.CLIENT_META_DATA); + } + + public boolean isClientRecording() { + return getBoolean(ClientProperty.CLIENT_IS_RECORDING); + } + + public int getClientDatabaseId() { + return getInt(ClientProperty.CLIENT_DATABASE_ID); + } + + public int getClientChannelGroupId() { + return getInt(ClientProperty.CLIENT_CHANNEL_GROUP_ID); + } + + public int getAmountOfServerGroups() { + //getInt was turning the String 1,2,3,.. to a int which wasn't right. + //Now it gets the Amount even if the ID is <=10 + String[] split = get(ClientProperty.CLIENT_SERVERGROUPS).split(","); + return split.length; + } + + public String getClientServerGroups() { + //getClientServerGroups returns a string containing the server group ID for example 1,2,3,... + return get(ClientProperty.CLIENT_SERVERGROUPS); + } + + public boolean isClientAway() { + return getBoolean(ClientProperty.CLIENT_AWAY); + } + + public String getClientAwayMessage() { + return get(ClientProperty.CLIENT_AWAY_MESSAGE); + } + + public int getClientType() { + return getInt(ClientProperty.CLIENT_TYPE); + } + + public String getClientFlagAvatarId() { + return get(ClientProperty.CLIENT_FLAG_AVATAR); + } + + public int getClientTalkPower() { + return getInt(ClientProperty.CLIENT_TALK_POWER); + } + + public boolean isClientRequestingToTalk() { + return getBoolean(ClientProperty.CLIENT_TALK_REQUEST); + } + + public String getClientTalkRequestMessage() { + return get(ClientProperty.CLIENT_TALK_REQUEST_MSG); + } + + public String getClientDescription() { + return get(ClientProperty.CLIENT_DESCRIPTION); + } + + public boolean isClientTalking() { + return getBoolean(ClientProperty.CLIENT_IS_TALKER); + } + + public boolean isClientPrioritySpeaker() { + return getBoolean(ClientProperty.CLIENT_IS_PRIORITY_SPEAKER); + } + + public int getClientUnreadMessages() { + return getInt(ClientProperty.CLIENT_UNREAD_MESSAGES); + } + + public String getClientPhoneticNickname() { + return get(ClientProperty.CLIENT_NICKNAME_PHONETIC); + } + + public int getClientNeededServerQueryViewPower() { + return getInt(ClientProperty.CLIENT_NEEDED_SERVERQUERY_VIEW_POWER); + } + + public long getClientIconId() { + return getLong(ClientProperty.CLIENT_ICON_ID); + } + + public boolean isClientChannelCommander() { + return getBoolean(ClientProperty.CLIENT_IS_CHANNEL_COMMANDER); + } + + public String getClientCountry() { + return get(ClientProperty.CLIENT_COUNTRY); + } + + public int getClientInheritedChannelGroupId() { + return getInt(ClientProperty.CLIENT_CHANNEL_GROUP_INHERITED_CHANNEL_ID); + } + + @Override + public void fire(TS3Listener listener) { + listener.onClientJoin(this); + } +} diff --git a/src/main/java/com/github/manevolent/ts3j/event/ClientLeaveEvent.java b/src/main/java/com/github/manevolent/ts3j/event/ClientLeaveEvent.java new file mode 100644 index 0000000..4933c9e --- /dev/null +++ b/src/main/java/com/github/manevolent/ts3j/event/ClientLeaveEvent.java @@ -0,0 +1,53 @@ +package com.github.manevolent.ts3j.event; + +/* + * #%L + * TeamSpeak 3 Java API + * %% + * Copyright (C) 2014 Bert De Geyter + * %% + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * #L% + */ + +import java.util.Map; + +public class ClientLeaveEvent extends BaseEvent { + + public ClientLeaveEvent(Map map) { + super(map); + } + + public int getClientFromId() { + return getInt("cfid"); + } + + public int getClientTargetId() { + return getInt("ctid"); + } + + public int getClientId() { + return getInt("clid"); + } + + @Override + public void fire(TS3Listener listener) { + listener.onClientLeave(this); + } +} diff --git a/src/main/java/com/github/manevolent/ts3j/event/ClientMovedEvent.java b/src/main/java/com/github/manevolent/ts3j/event/ClientMovedEvent.java new file mode 100644 index 0000000..29e0b8b --- /dev/null +++ b/src/main/java/com/github/manevolent/ts3j/event/ClientMovedEvent.java @@ -0,0 +1,56 @@ +package com.github.manevolent.ts3j.event; + +/* + * #%L + * TeamSpeak 3 Java API + * %% + * Copyright (C) 2014 Bert De Geyter + * %% + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * #L% + */ + +import java.util.Map; + +public class ClientMovedEvent extends BaseEvent { + + public ClientMovedEvent(Map map) { + super(map); + } + + /** + * Gets the ID of the channel the client has moved to. + * + * @return the ID of the target channel + * + * @see Channel#getId() + */ + public int getTargetChannelId() { + return getInt("ctid"); + } + + public int getClientId() { + return getInt("clid"); + } + + @Override + public void fire(TS3Listener listener) { + listener.onClientMoved(this); + } +} diff --git a/src/main/java/com/github/manevolent/ts3j/event/ClientNeededPermissionsEvent.java b/src/main/java/com/github/manevolent/ts3j/event/ClientNeededPermissionsEvent.java new file mode 100644 index 0000000..79727dd --- /dev/null +++ b/src/main/java/com/github/manevolent/ts3j/event/ClientNeededPermissionsEvent.java @@ -0,0 +1,40 @@ +package com.github.manevolent.ts3j.event; + +/* + * #%L + * TeamSpeak 3 Java API + * %% + * Copyright (C) 2014 Bert De Geyter + * %% + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * #L% + */ + +import java.util.Map; + +public class ClientNeededPermissionsEvent extends BaseEvent { + protected ClientNeededPermissionsEvent(Map map) { + super(map); + } + + @Override + public void fire(TS3Listener listener) { + listener.onClientNeededPermissions(this); + } +} diff --git a/src/main/java/com/github/manevolent/ts3j/event/PrivilegeKeyUsedEvent.java b/src/main/java/com/github/manevolent/ts3j/event/PrivilegeKeyUsedEvent.java new file mode 100644 index 0000000..d6e5714 --- /dev/null +++ b/src/main/java/com/github/manevolent/ts3j/event/PrivilegeKeyUsedEvent.java @@ -0,0 +1,75 @@ +package com.github.manevolent.ts3j.event; + +/* + * #%L + * TeamSpeak 3 Java API + * %% + * Copyright (C) 2016 Bert De Geyter, Roger Baumgartner + * %% + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * #L% + */ + +import com.github.manevolent.ts3j.api.PrivilegeKeyType; + +import java.util.Map; + +public class PrivilegeKeyUsedEvent extends BaseEvent { + + public PrivilegeKeyUsedEvent(Map map) { + super(map); + } + + public int getClientId() { + return getInt("clid"); + } + + public int getClientDatabaseId() { + return getInt("cldbid"); + } + + public String getClientUniqueIdentifier() { + return get("cluid"); + } + + public String getPrivilegeKey() { + return get("token"); + } + + public PrivilegeKeyType getPrivilegeKeyType() { + if (getPrivilegeKeyChannelId() == 0) { + return PrivilegeKeyType.SERVER_GROUP; + } else { + return PrivilegeKeyType.CHANNEL_GROUP; + } + } + + public int getPrivilegeKeyGroupId() { + return getInt("token1"); + } + + public int getPrivilegeKeyChannelId() { + return getInt("token2"); + } + + @Override + public void fire(TS3Listener listener) { + listener.onPrivilegeKeyUsed(this); + } +} diff --git a/src/main/java/com/github/manevolent/ts3j/event/ServerEditedEvent.java b/src/main/java/com/github/manevolent/ts3j/event/ServerEditedEvent.java new file mode 100644 index 0000000..6169f59 --- /dev/null +++ b/src/main/java/com/github/manevolent/ts3j/event/ServerEditedEvent.java @@ -0,0 +1,41 @@ +package com.github.manevolent.ts3j.event; + +/* + * #%L + * TeamSpeak 3 Java API + * %% + * Copyright (C) 2014 Bert De Geyter + * %% + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * #L% + */ + +import java.util.Map; + +public class ServerEditedEvent extends BaseEvent { + + public ServerEditedEvent(Map map) { + super(map); + } + + @Override + public void fire(TS3Listener listener) { + listener.onServerEdit(this); + } +} diff --git a/src/main/java/com/github/manevolent/ts3j/event/ServerGroupListEvent.java b/src/main/java/com/github/manevolent/ts3j/event/ServerGroupListEvent.java new file mode 100644 index 0000000..bc0c0c7 --- /dev/null +++ b/src/main/java/com/github/manevolent/ts3j/event/ServerGroupListEvent.java @@ -0,0 +1,41 @@ +package com.github.manevolent.ts3j.event; + +/* + * #%L + * TeamSpeak 3 Java API + * %% + * Copyright (C) 2014 Bert De Geyter + * %% + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * #L% + */ + + +import java.util.Map; + +public class ServerGroupListEvent extends BaseEvent { + protected ServerGroupListEvent(Map map) { + super(map); + } + + @Override + public void fire(TS3Listener listener) { + listener.onServerGroupList(this); + } +} diff --git a/src/main/java/com/github/manevolent/ts3j/event/TS3Event.java b/src/main/java/com/github/manevolent/ts3j/event/TS3Event.java new file mode 100644 index 0000000..f9fd8bd --- /dev/null +++ b/src/main/java/com/github/manevolent/ts3j/event/TS3Event.java @@ -0,0 +1,70 @@ +package com.github.manevolent.ts3j.event; + +/* + * #%L + * TeamSpeak 3 Java API + * %% + * Copyright (C) 2014 Bert De Geyter + * %% + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * #L% + */ + +import com.github.manevolent.ts3j.command.Command; + +public interface TS3Event { + void fire(TS3Listener listener); + + static TS3Event createEvent(Command command) { + switch (command.getName()) { + case "notifytextmessage": + return new TextMessageEvent(command.toMap()); + case "notifycliententerview": + return new ClientJoinEvent(command.toMap()); + case "notifyclientleftview": + return new ClientLeaveEvent(command.toMap()); + case "notifyserveredited": + return new ServerEditedEvent(command.toMap()); + case "notifychanneledited": + return new ChannelEditedEvent(command.toMap()); + case "notifychanneldescriptionchanged": + return new ChannelDescriptionEditedEvent(command.toMap()); + case "notifyclientmoved": + return new ClientMovedEvent(command.toMap()); + case "notifychannelcreated": + return new ChannelCreateEvent(command.toMap()); + case "notifychanneldeleted": + return new ChannelDeletedEvent(command.toMap()); + case "notifychannelmoved": + return new ChannelMovedEvent(command.toMap()); + case "notifychannelpasswordchanged": + return new ChannelPasswordChangedEvent(command.toMap()); + case "notifytokenused": + return new PrivilegeKeyUsedEvent(command.toMap()); + case "notifyservergrouplist": // CLIENT + return new ServerGroupListEvent(command.toMap()); + case "notifychannelgrouplist": // CLIENT + return new ChannelGroupListEvent(command.toMap()); + case "notifyclientneededpermissions": // CLIENT + return new ClientNeededPermissionsEvent(command.toMap()); + default: + throw new IllegalArgumentException("unknown event: " + command.getName()); + } + } +} diff --git a/src/main/java/com/github/manevolent/ts3j/event/TS3Listener.java b/src/main/java/com/github/manevolent/ts3j/event/TS3Listener.java new file mode 100644 index 0000000..60572e1 --- /dev/null +++ b/src/main/java/com/github/manevolent/ts3j/event/TS3Listener.java @@ -0,0 +1,60 @@ +package com.github.manevolent.ts3j.event; + +/* + * #%L + * TeamSpeak 3 Java API + * %% + * Copyright (C) 2014 Bert De Geyter + * %% + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * #L% + */ + +public interface TS3Listener { + + void onTextMessage(TextMessageEvent e); + + void onClientJoin(ClientJoinEvent e); + + void onClientLeave(ClientLeaveEvent e); + + void onServerEdit(ServerEditedEvent e); + + void onChannelEdit(ChannelEditedEvent e); + + void onChannelDescriptionChanged(ChannelDescriptionEditedEvent e); + + void onClientMoved(ClientMovedEvent e); + + void onChannelCreate(ChannelCreateEvent e); + + void onChannelDeleted(ChannelDeletedEvent e); + + void onChannelMoved(ChannelMovedEvent e); + + void onChannelPasswordChanged(ChannelPasswordChangedEvent e); + + void onPrivilegeKeyUsed(PrivilegeKeyUsedEvent e); + + void onChannelGroupList(ChannelGroupListEvent e); + + void onServerGroupList(ServerGroupListEvent e); + + void onClientNeededPermissions(ClientNeededPermissionsEvent e); +} diff --git a/src/main/java/com/github/manevolent/ts3j/event/TeamspeakListener.java b/src/main/java/com/github/manevolent/ts3j/event/TeamspeakListener.java new file mode 100644 index 0000000..b70db2c --- /dev/null +++ b/src/main/java/com/github/manevolent/ts3j/event/TeamspeakListener.java @@ -0,0 +1,29 @@ +package com.github.manevolent.ts3j.event; + +public interface TeamspeakListener { + + void onTextMessage(TextMessageEvent e); + + void onClientJoin(ClientJoinEvent e); + + void onClientLeave(ClientLeaveEvent e); + + void onServerEdit(ServerEditedEvent e); + + void onChannelEdit(ChannelEditedEvent e); + + void onChannelDescriptionChanged(ChannelDescriptionEditedEvent e); + + void onClientMoved(ClientMovedEvent e); + + void onChannelCreate(ChannelCreateEvent e); + + void onChannelDeleted(ChannelDeletedEvent e); + + void onChannelMoved(ChannelMovedEvent e); + + void onChannelPasswordChanged(ChannelPasswordChangedEvent e); + + void onPrivilegeKeyUsed(PrivilegeKeyUsedEvent e); + +} diff --git a/src/main/java/com/github/manevolent/ts3j/event/TextMessageEvent.java b/src/main/java/com/github/manevolent/ts3j/event/TextMessageEvent.java new file mode 100644 index 0000000..a5da822 --- /dev/null +++ b/src/main/java/com/github/manevolent/ts3j/event/TextMessageEvent.java @@ -0,0 +1,71 @@ +package com.github.manevolent.ts3j.event; + +/* + * #%L + * TeamSpeak 3 Java API + * %% + * Copyright (C) 2014 Bert De Geyter + * %% + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * #L% + */ + +import com.github.manevolent.ts3j.api.TextMessageTargetMode; + +import java.util.Map; + +public class TextMessageEvent extends BaseEvent { + + public TextMessageEvent(Map map) { + super(map); + } + + public TextMessageTargetMode getTargetMode() { + int mode = getInt("targetmode"); + for (TextMessageTargetMode m : TextMessageTargetMode.values()) { + if (m.getIndex() == mode) { + return m; + } + } + return null; + } + + public String getMessage() { + return get("msg"); + } + + /** + * Gets the client ID of the recipient of a private message. + *
    + *
  • If the private message was sent to the query, the target ID will be the query's client ID
  • + *
  • If the private message was sent by the query, the target ID will be the recipient's client ID
  • + *
  • If this is not an event for a private message, this method will return {@code -1}
  • + *
+ * + * @return the client ID of the recipient + */ + public int getTargetClientId() { + return getInt("target"); + } + + @Override + public void fire(TS3Listener listener) { + listener.onTextMessage(this); + } +} diff --git a/src/main/java/com/github/manevolent/ts3j/model/Channel.java b/src/main/java/com/github/manevolent/ts3j/model/Channel.java deleted file mode 100644 index 0925d6e..0000000 --- a/src/main/java/com/github/manevolent/ts3j/model/Channel.java +++ /dev/null @@ -1,201 +0,0 @@ -package com.github.manevolent.ts3j.model; - -import com.github.manevolent.ts3j.enums.CodecType; - -public class Channel { - private final VirtualServer server; - private final int channelId; - private String name; - private CodecType codec; - private int codecQuality; - private int maxClients; - private int maxFamilyClients; - private int order; - private boolean permanent; - private boolean semiPermanent; - private boolean serverDefault; - private boolean hasPassword; - private boolean codecLatencyFactor; - private boolean unencrypted; - private int deleteDelay; - private boolean unlimited; - private boolean familyUnlimited; - private boolean inheritingMaxfamilyUnlimited; - private int neededTalkPower; - private boolean forcingSilence; - private int iconId; - private boolean privated; - - public Channel(VirtualServer server, int channelId) { - this.server = server; - this.channelId = channelId; - } - - public int getChannelId() { - return channelId; - } - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - public CodecType getCodec() { - return codec; - } - - public void setCodec(CodecType codec) { - this.codec = codec; - } - - public int getCodecQuality() { - return codecQuality; - } - - public void setCodecQuality(int codecQuality) { - this.codecQuality = codecQuality; - } - - public int getMaxClients() { - return maxClients; - } - - public void setMaxClients(int maxClients) { - this.maxClients = maxClients; - } - - public int getMaxFamilyClients() { - return maxFamilyClients; - } - - public void setMaxFamilyClients(int maxFamilyClients) { - this.maxFamilyClients = maxFamilyClients; - } - - public int getOrder() { - return order; - } - - public void setOrder(int order) { - this.order = order; - } - - public boolean isPermanent() { - return permanent; - } - - public void setPermanent(boolean permanent) { - this.permanent = permanent; - } - - public boolean isSemiPermanent() { - return semiPermanent; - } - - public void setSemiPermanent(boolean semiPermanent) { - this.semiPermanent = semiPermanent; - } - - public boolean isServerDefault() { - return serverDefault; - } - - public void setServerDefault(boolean serverDefault) { - this.serverDefault = serverDefault; - } - - public boolean hasPassword() { - return hasPassword; - } - - public void setHasPassword(boolean hasPassword) { - this.hasPassword = hasPassword; - } - - public boolean isCodecLatencyFactor() { - return codecLatencyFactor; - } - - public void setCodecLatencyFactor(boolean codecLatencyFactor) { - this.codecLatencyFactor = codecLatencyFactor; - } - - public boolean isUnencrypted() { - return unencrypted; - } - - public void setUnencrypted(boolean unencrypted) { - this.unencrypted = unencrypted; - } - - public int getDeleteDelay() { - return deleteDelay; - } - - public void setDeleteDelay(int deleteDelay) { - this.deleteDelay = deleteDelay; - } - - public boolean isUnlimited() { - return unlimited; - } - - public void setUnlimited(boolean unlimited) { - this.unlimited = unlimited; - } - - public boolean isFamilyUnlimited() { - return familyUnlimited; - } - - public void setFamilyUnlimited(boolean familyUnlimited) { - this.familyUnlimited = familyUnlimited; - } - - public boolean isInheritingMaxfamilyUnlimited() { - return inheritingMaxfamilyUnlimited; - } - - public void setInheritingMaxfamilyUnlimited(boolean inheritingMaxfamilyUnlimited) { - this.inheritingMaxfamilyUnlimited = inheritingMaxfamilyUnlimited; - } - - public int getNeededTalkPower() { - return neededTalkPower; - } - - public void setNeededTalkPower(int neededTalkPower) { - this.neededTalkPower = neededTalkPower; - } - - public boolean isForcingSilence() { - return forcingSilence; - } - - public void setForcingSilence(boolean forcingSilence) { - this.forcingSilence = forcingSilence; - } - - public int getIconId() { - return iconId; - } - - public void setIconId(int iconId) { - this.iconId = iconId; - } - - public boolean isPrivated() { - return privated; - } - - public void setPrivated(boolean privated) { - this.privated = privated; - } - - public VirtualServer getServer() { - return server; - } -} diff --git a/src/main/java/com/github/manevolent/ts3j/model/Client.java b/src/main/java/com/github/manevolent/ts3j/model/Client.java deleted file mode 100644 index 632cb87..0000000 --- a/src/main/java/com/github/manevolent/ts3j/model/Client.java +++ /dev/null @@ -1,261 +0,0 @@ -package com.github.manevolent.ts3j.model; - -import com.github.manevolent.ts3j.enums.ClientType; -import com.github.manevolent.ts3j.identity.Uid; - -import java.util.*; - -public class Client { - private final int id; - private final int databaseId; - private final VirtualServer server; - private final Uid uid; - private final ClientType clientType; - - private String nickname; - - private int channelId; - private int channelGroupId; - - private boolean speaking; - private boolean outputMuted, inputMuted; - private boolean recording; - private boolean inputHardware, outputHardware; - - private boolean away; - private int talkPower; - private boolean talkRequested; - private boolean talker; - private boolean prioritySpeaker; - private int unreadMessages; - private int neededServerQueryViewPower; - private int iconId; - private boolean channelCommander; - private String country; - private int inheritedChannelGroupChannelId; - - private List serverGroupIds = new ArrayList<>(); - - public Client(int id, int databaseId, VirtualServer server, Uid uid, ClientType clientType) { - this.id = id; - this.databaseId = databaseId; - this.server = server; - this.uid = uid; - this.clientType = clientType; - } - - public VirtualServer getServer() { - return server; - } - - public Uid getUid() { - return uid; - } - - public String getNickname() { - return nickname; - } - - public void setNickname(String nickname) { - this.nickname = nickname; - } - - /** - * Gets the client's current client connection ID. - * @return client ID. - */ - public int getId() { - return id; - } - - /** - * Gets the current connected-to channel. - * @return channel currently connected to by the client. - */ - public Channel getChannel() { - return server.getChannelById(getChannelId()); - } - - /** - * Gets the channel ID currently connected to. - * @return channel currently connected to by the client. - */ - public int getChannelId() { - return channelId; - } - - public void setChannelId(int channelId) { - this.channelId = channelId; - } - - public boolean isSpeaking() { - return speaking; - } - - public void setSpeaking(boolean speaking) { - this.speaking = speaking; - } - - public boolean isInputMuted() { - return inputMuted; - } - - public void setInputMuted(boolean inputMuted) { - this.inputMuted = inputMuted; - } - - public boolean isOutputMuted() { - return outputMuted; - } - - public void setOutputMuted(boolean outputMuted) { - this.outputMuted = outputMuted; - } - - public boolean hasOutputHardware() { - return outputHardware; - } - - public void setOutputHardware(boolean outputHardware) { - this.outputHardware = outputHardware; - } - - public boolean hasInputHardware() { - return inputHardware; - } - - public void setInputHardware(boolean inputHardware) { - this.inputHardware = inputHardware; - } - - public int getDatabaseId() { - return databaseId; - } - - public boolean isRecording() { - return recording; - } - - public void setRecording(boolean recording) { - this.recording = recording; - } - - public boolean isInServerGroup(int serverGroupId) { - return serverGroupIds.contains(serverGroupId); - } - - public void setServerGroupIds(Collection serverGroupIds) { - synchronized (serverGroupIds) { - this.serverGroupIds.clear(); - this.serverGroupIds.addAll(serverGroupIds); - } - } - - public void setServerGroupIds(Integer... serverGroupIds) { - setServerGroupIds(Arrays.asList(serverGroupIds)); - } - - public Iterable getServerGroupIds() { - return Collections.unmodifiableList(serverGroupIds); - } - - public int getChannelGroupId() { - return channelGroupId; - } - - public void setChannelGroupId(int channelGroupId) { - this.channelGroupId = channelGroupId; - } - - public boolean isAway() { - return away; - } - - public void setAway(boolean away) { - this.away = away; - } - - public int getTalkPower() { - return talkPower; - } - - public void setTalkPower(int talkPower) { - this.talkPower = talkPower; - } - - public boolean isTalkRequested() { - return talkRequested; - } - - public void setTalkRequested(boolean talkRequested) { - this.talkRequested = talkRequested; - } - - public boolean isTalker() { - return talker; - } - - public void setTalker(boolean talker) { - this.talker = talker; - } - - public boolean isPrioritySpeaker() { - return prioritySpeaker; - } - - public void setPrioritySpeaker(boolean prioritySpeaker) { - this.prioritySpeaker = prioritySpeaker; - } - - public int getUnreadMessages() { - return unreadMessages; - } - - public void setUnreadMessages(int unreadMessages) { - this.unreadMessages = unreadMessages; - } - - public int getNeededServerQueryViewPower() { - return neededServerQueryViewPower; - } - - public void setNeededServerQueryViewPower(int neededServerQueryViewPower) { - this.neededServerQueryViewPower = neededServerQueryViewPower; - } - - public int getIconId() { - return iconId; - } - - public void setIconId(int iconId) { - this.iconId = iconId; - } - - public boolean isChannelCommander() { - return channelCommander; - } - - public void setChannelCommander(boolean channelCommander) { - this.channelCommander = channelCommander; - } - - public int getInheritedChannelGroupChannelId() { - return inheritedChannelGroupChannelId; - } - - public void setInheritedChannelGroupChannelId(int inheritedChannelGroupChannelId) { - this.inheritedChannelGroupChannelId = inheritedChannelGroupChannelId; - } - - public ClientType getClientType() { - return clientType; - } - - public String getCountry() { - return country; - } - - public void setCountry(String country) { - this.country = country; - } -} diff --git a/src/main/java/com/github/manevolent/ts3j/model/VirtualServer.java b/src/main/java/com/github/manevolent/ts3j/model/VirtualServer.java deleted file mode 100644 index 46257f7..0000000 --- a/src/main/java/com/github/manevolent/ts3j/model/VirtualServer.java +++ /dev/null @@ -1,322 +0,0 @@ -package com.github.manevolent.ts3j.model; - -import com.github.manevolent.ts3j.enums.HostBannerMode; -import com.github.manevolent.ts3j.enums.HostMessageMode; -import com.github.manevolent.ts3j.enums.VoiceEncryptionMode; -import com.github.manevolent.ts3j.identity.Uid; - -import java.util.*; -import java.util.stream.Collectors; - -public class VirtualServer { - private int id; - private String name; - private String nickname; - private String welcomeMessage; - private String platform; - private String version; - private int maxClients; - private long created; - private VoiceEncryptionMode encryptionMode; - private HostMessageMode hostMessageMode; - private int defaultGroupId; - private int defaultChannelGroupId; - private String hostbannerUrl; - private int hostBannerInterval; - private double prioritySpeakerDimmModifier; - private String namePhonetic; - private long iconId; - private String serverIp; - private boolean askForPriviledgeKey; - private HostBannerMode hostBannerMode; - private int defaultTempChannelDeleteDelay; - - /** - * Connected clients - */ - private final Map clients = new HashMap<>(); - - /** - * Server channels - */ - private final Map channels = new HashMap<>(); - - public VirtualServer() { - - } - - public int getId() { - return id; - } - - public void setId(int id) { - this.id = id; - } - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - public String getNickname() { - return nickname; - } - - public void setNickname(String nickname) { - this.nickname = nickname; - } - - public String getWelcomeMessage() { - return welcomeMessage; - } - - public void setWelcomeMessage(String welcomeMessage) { - this.welcomeMessage = welcomeMessage; - } - - public String getPlatform() { - return platform; - } - - public void setPlatform(String platform) { - this.platform = platform; - } - - public String getVersion() { - return version; - } - - public void setVersion(String version) { - this.version = version; - } - - public int getMaxClients() { - return maxClients; - } - - public void setMaxClients(int maxClients) { - this.maxClients = maxClients; - } - - public long getCreated() { - return created; - } - - public void setCreated(long created) { - this.created = created; - } - - public VoiceEncryptionMode getEncryptionMode() { - return encryptionMode; - } - - public void setEncryptionMode(VoiceEncryptionMode encryptionMode) { - this.encryptionMode = encryptionMode; - } - - public HostMessageMode getHostMessageMode() { - return hostMessageMode; - } - - public void setHostMessageMode(HostMessageMode hostMessageMode) { - this.hostMessageMode = hostMessageMode; - } - - /** - * Gets the default server group ID users are assigned to when connecting to the server for the first time. - * @return default server group ID. - */ - public int getDefaultGroupId() { - return defaultGroupId; - } - - public void setDefaultGroupId(int defaultGroupId) { - this.defaultGroupId = defaultGroupId; - } - - public int getDefaultChannelGroupId() { - return defaultChannelGroupId; - } - - public void setDefaultChannelGroupId(int defaultChannelGroupId) { - this.defaultChannelGroupId = defaultChannelGroupId; - } - - public String getHostbannerUrl() { - return hostbannerUrl; - } - - public void setHostbannerUrl(String hostbannerUrl) { - this.hostbannerUrl = hostbannerUrl; - } - - public int getHostBannerInterval() { - return hostBannerInterval; - } - - public void setHostBannerInterval(int hostBannerInterval) { - this.hostBannerInterval = hostBannerInterval; - } - - public double getPrioritySpeakerDimmModifier() { - return prioritySpeakerDimmModifier; - } - - public void setPrioritySpeakerDimmModifier(double prioritySpeakerDimmModifier) { - this.prioritySpeakerDimmModifier = prioritySpeakerDimmModifier; - } - - public String getNamePhonetic() { - return namePhonetic; - } - - public void setNamePhonetic(String namePhonetic) { - this.namePhonetic = namePhonetic; - } - - public long getIconId() { - return iconId; - } - - public void setIconId(long iconId) { - this.iconId = iconId; - } - - public String getServerIp() { - return serverIp; - } - - public void setServerIp(String serverIp) { - this.serverIp = serverIp; - } - - public boolean isAskForPriviledgeKey() { - return askForPriviledgeKey; - } - - public void setAskForPriviledgeKey(boolean askForPriviledgeKey) { - this.askForPriviledgeKey = askForPriviledgeKey; - } - - public HostBannerMode getHostBannerMode() { - return hostBannerMode; - } - - public void setHostBannerMode(HostBannerMode hostBannerMode) { - this.hostBannerMode = hostBannerMode; - } - - public int getDefaultTempChannelDeleteDelay() { - return defaultTempChannelDeleteDelay; - } - - public void setDefaultTempChannelDeleteDelay(int defaultTempChannelDeleteDelay) { - this.defaultTempChannelDeleteDelay = defaultTempChannelDeleteDelay; - } - - /** - * Gets a channel by its numeric ID. - * @param id channel ID. - * @return the corresponding channel, if such a channel exists, null otherwise. - */ - public Channel getChannelById(int id) { - return channels.get(id); - } - - /** - * Tries to add a new channel to the server. If the channel ID is already in use, IllegalStateException is thrown. - * @param channel channel to add. - */ - public void updateChannel(Channel channel) { - synchronized (channels) { - this.channels.put(channel.getChannelId(), channel); - } - } - - /** - * Gets all channels by a specific name. - * @param name Name to search for. - * @return List of channels with the specified name. - */ - public List getChannelsByName(String name) { - return this.channels.values() - .stream() - .filter(x -> x.getName().equalsIgnoreCase(name)) - .collect(Collectors.toList()); - } - - /** - * Gets the first channel by a specific name. - * @param name Name to search for. - * @return List of channels with the specified name. - */ - public Channel getChannelByName(String name) throws IllegalArgumentException { - return getChannelsOrderd() - .stream() - .filter(x -> x.getName().equalsIgnoreCase(name)) - .findFirst() - .orElseThrow(() -> new IllegalArgumentException("channel not found")); - } - - /** - * Gets a real channel list, potentially unordered. - * @return Unordered channel list. - */ - public Collection getChannels() { - return Collections.unmodifiableCollection(channels.values()); - } - - /** - * Gets the channel list as ordered by the server. - * @return Iterable list of ordered channels. - */ - public Collection getChannelsOrderd() { - return Collections.unmodifiableCollection(channels.values() - .stream() - .sorted(Comparator.comparingInt(Channel::getOrder)) - .collect(Collectors.toList()) - ); - } - - /** - * Gets a list of known clients to the server. - * @return clients - */ - public Collection getClients() { - throw new UnsupportedOperationException(); // TODO - } - - /** - * Gets a list of connected clients. - * @return connected clients. - */ - public Collection getConnectedClients() { - return Collections.unmodifiableCollection(clients.values()); - } - - public List getClientsByUid(Uid uid) { - return getConnectedClients().stream().filter(x -> x.getUid().equals(uid)).collect(Collectors.toList()); - } - - public void updateConnectedClient(Client client) { - synchronized (clients) { - this.clients.put(client.getId(), client); - } - } - - public void removeConnectedClient(Client client) { - synchronized (clients) { - if (this.clients.containsKey(client.getId())) - this.clients.remove(client.getId()); - else - throw new IllegalStateException("client ID doesn't exist"); - } - } - - public Client getClientById(int clientId) { - return this.clients.get(clientId); - } -} diff --git a/src/main/java/com/github/manevolent/ts3j/protocol/Packet.java b/src/main/java/com/github/manevolent/ts3j/protocol/Packet.java index a1d43d9..6a5565d 100644 --- a/src/main/java/com/github/manevolent/ts3j/protocol/Packet.java +++ b/src/main/java/com/github/manevolent/ts3j/protocol/Packet.java @@ -119,7 +119,7 @@ public final class Packet { } } - getBody().read(buffer); + getBody().read(getHeader(), buffer); return buffer; } diff --git a/src/main/java/com/github/manevolent/ts3j/protocol/client/ClientConnectionState.java b/src/main/java/com/github/manevolent/ts3j/protocol/client/ClientConnectionState.java index 455f423..b4884c7 100644 --- a/src/main/java/com/github/manevolent/ts3j/protocol/client/ClientConnectionState.java +++ b/src/main/java/com/github/manevolent/ts3j/protocol/client/ClientConnectionState.java @@ -2,7 +2,7 @@ package com.github.manevolent.ts3j.protocol.client; import com.github.manevolent.ts3j.protocol.packet.handler.PacketHandler; -import com.github.manevolent.ts3j.protocol.packet.handler.local.*; +import com.github.manevolent.ts3j.protocol.packet.handler.client.*; import com.github.manevolent.ts3j.protocol.socket.client.TeamspeakClientSocket; import org.apache.commons.lang.reflect.ConstructorUtils; diff --git a/src/main/java/com/github/manevolent/ts3j/protocol/packet/PacketBody.java b/src/main/java/com/github/manevolent/ts3j/protocol/packet/PacketBody.java index 9b8055f..c30ef33 100644 --- a/src/main/java/com/github/manevolent/ts3j/protocol/packet/PacketBody.java +++ b/src/main/java/com/github/manevolent/ts3j/protocol/packet/PacketBody.java @@ -22,6 +22,10 @@ public abstract class PacketBody { return role; } + public void read(PacketHeader header, ByteBuffer buffer) { + read(buffer); + } + public abstract void read(ByteBuffer buffer); public abstract void write(ByteBuffer buffer); diff --git a/src/main/java/com/github/manevolent/ts3j/protocol/packet/PacketBody0Voice.java b/src/main/java/com/github/manevolent/ts3j/protocol/packet/PacketBody0Voice.java new file mode 100644 index 0000000..85ec51b --- /dev/null +++ b/src/main/java/com/github/manevolent/ts3j/protocol/packet/PacketBody0Voice.java @@ -0,0 +1,83 @@ +package com.github.manevolent.ts3j.protocol.packet; + +import com.github.manevolent.ts3j.enums.CodecType; +import com.github.manevolent.ts3j.protocol.ProtocolRole; + +import java.nio.ByteBuffer; + +public class PacketBody0Voice extends PacketBody { + private int packetId; + private int clientId; + private CodecType codecType; + private byte[] codecData; + + public PacketBody0Voice(ProtocolRole role) { + super(PacketBodyType.VOICE, role); + } + + public int getPacketId() { + return packetId; + } + + public void setPacketId(int packetId) { + this.packetId = packetId; + } + + public CodecType getCodecType() { + return codecType; + } + + public void setCodecType(CodecType codecType) { + this.codecType = codecType; + } + + public byte[] getCodecData() { + return codecData; + } + + public void setCodecData(byte[] codecData) { + this.codecData = codecData; + } + + public int getClientId() { + return clientId; + } + + public void setClientId(int clientId) { + if (getRole() != ProtocolRole.SERVER) + throw new IllegalStateException("cannot set client ID field on non-server packet"); + + this.clientId = clientId; + } + + @Override + public void read(ByteBuffer buffer) { + packetId = buffer.getShort() & 0x0000FFFF; + + if (getRole() == ProtocolRole.SERVER) + clientId = buffer.getShort() & 0x0000FFFF; + + codecType = CodecType.fromId((int) (buffer.get() & 0xFF)); + + codecData = new byte[buffer.remaining()]; + + buffer.get(codecData); + } + + @Override + public void write(ByteBuffer buffer) { + buffer.putShort((short) (packetId & 0xFFFF)); + + if (getRole() == ProtocolRole.SERVER) + buffer.putShort((short) (clientId & 0xFFFF)); + + buffer.put((byte)(codecType.getIndex() & 0xFF)); + + buffer.put(codecData); + } + + @Override + public int getSize() { + return 2 + (getRole() == ProtocolRole.SERVER ? 2 : 0) + 1 + codecData.length; + } +} diff --git a/src/main/java/com/github/manevolent/ts3j/protocol/packet/PacketBody1VoiceWhisper.java b/src/main/java/com/github/manevolent/ts3j/protocol/packet/PacketBody1VoiceWhisper.java new file mode 100644 index 0000000..84fa05d --- /dev/null +++ b/src/main/java/com/github/manevolent/ts3j/protocol/packet/PacketBody1VoiceWhisper.java @@ -0,0 +1,122 @@ +package com.github.manevolent.ts3j.protocol.packet; + +import com.github.manevolent.ts3j.enums.CodecType; +import com.github.manevolent.ts3j.protocol.ProtocolRole; +import com.github.manevolent.ts3j.protocol.header.HeaderFlag; +import com.github.manevolent.ts3j.protocol.header.PacketHeader; + +import java.nio.ByteBuffer; +import java.util.ArrayList; +import java.util.List; + +public class PacketBody1VoiceWhisper extends PacketBody { + private int packetId; + private int clientId; + private CodecType codecType; + private byte[] codecData; + + public PacketBody1VoiceWhisper(ProtocolRole role) { + super(PacketBodyType.VOICE_WHISPER, role); + } + + @Override + public void read(PacketHeader header, ByteBuffer buffer) { + packetId = buffer.getShort() & 0x0000FFFF; + + if (getRole() == ProtocolRole.SERVER) + clientId = buffer.getShort() & 0x0000FFFF; + + codecType = CodecType.fromId((int) (buffer.get() & 0xFF)); + + + if (getRole() == ProtocolRole.CLIENT) { + if (header.getPacketFlag(HeaderFlag.NEW_PROTOCOL)) { + int groupWhisperType = buffer.get() & 0xFF; + int groupWhisperTarget = buffer.get() & 0xFF; + long targetChannelIdorGroupId = buffer.getLong(); + + // TODO + } else { + int channelIdCount = buffer.get() & 0xFF; + int clientIdCount = buffer.get() & 0xFF; + + List channelIds = new ArrayList<>(channelIdCount); + for (int i = 0; i < channelIdCount; i ++) channelIds.add(buffer.getLong()); + + List clientIds = new ArrayList<>(clientIdCount); + for (int i = 0; i < clientIdCount; i ++) clientIds.add(buffer.getShort() & 0xFFFF); + + // TODO + } + } + + codecData = new byte[buffer.remaining()]; + + buffer.get(codecData); + } + + @Override + public void read(ByteBuffer buffer) { + throw new UnsupportedOperationException(); + } + + @Override + public void write(ByteBuffer buffer) { + buffer.putShort((short) (packetId & 0xFFFF)); + + if (getRole() == ProtocolRole.SERVER) + buffer.putShort((short) (clientId & 0xFFFF)); + + buffer.put((byte)(codecType.getIndex() & 0xFF)); + + buffer.put(codecData); + } + + @Override + public int getSize() { + switch (getRole()) { + case CLIENT: + // TODO + throw new UnsupportedOperationException(); + case SERVER: + return 2 + 2 + 1 + codecData.length; + default: + throw new IllegalArgumentException("unknown role"); + } + } + + public int getPacketId() { + return packetId; + } + + public void setPacketId(int packetId) { + this.packetId = packetId; + } + + public CodecType getCodecType() { + return codecType; + } + + public void setCodecType(CodecType codecType) { + this.codecType = codecType; + } + + public byte[] getCodecData() { + return codecData; + } + + public void setCodecData(byte[] codecData) { + this.codecData = codecData; + } + + public int getClientId() { + return clientId; + } + + public void setClientId(int clientId) { + if (getRole() != ProtocolRole.SERVER) + throw new IllegalStateException("cannot set client ID field on non-server packet"); + + this.clientId = clientId; + } +} diff --git a/src/main/java/com/github/manevolent/ts3j/protocol/packet/PacketBodyType.java b/src/main/java/com/github/manevolent/ts3j/protocol/packet/PacketBodyType.java index 69ec83e..96c9624 100644 --- a/src/main/java/com/github/manevolent/ts3j/protocol/packet/PacketBodyType.java +++ b/src/main/java/com/github/manevolent/ts3j/protocol/packet/PacketBodyType.java @@ -1,12 +1,12 @@ package com.github.manevolent.ts3j.protocol.packet; public enum PacketBodyType { - VOICE(0x0, null, null, false, false, false, false, false), - VOICE_WHISPER(0x1, null, null, false, false, false, false, false), + VOICE(0x0, PacketBody0Voice.class, null, false, false, false, false, false), + VOICE_WHISPER(0x1, PacketBody1VoiceWhisper.class, null, false, false, false, false, false), PONG(0x5, PacketBody5Pong.class, null, false, false, false, false, false), PING(0x4, PacketBody4Ping.class, PONG, false, false, false, false, false), - ACK(0x6, PacketBody6Ack.class, null, true, true, false, false, true), - ACK_LOW(0x7, PacketBody7AckLow.class, null, true, true, false, false, true), + ACK(0x6, PacketBody6Ack.class, null, true, true, false, false, false), + ACK_LOW(0x7, PacketBody7AckLow.class, null, true, true, false, false, false), INIT1(0x8, PacketBody8Init1.class, null, false, true, false, false, false), COMMAND_LOW(0x3, PacketBody3CommandLow.class, ACK_LOW, true, true, true, true, true), COMMAND(0x2, PacketBody2Command.class, ACK, true, true, true, true, true); @@ -22,7 +22,8 @@ public enum PacketBodyType { boolean encrypted, boolean resend, boolean splittable, - boolean compressible, boolean mustEncrypt) { + boolean compressible, + boolean mustEncrypt) { this.index = index; this.packetClass = packetClass; this.acknolwedgedBy = acknolwedgedBy; diff --git a/src/main/java/com/github/manevolent/ts3j/protocol/packet/handler/PacketHandler.java b/src/main/java/com/github/manevolent/ts3j/protocol/packet/handler/PacketHandler.java index 460b965..306b9b4 100644 --- a/src/main/java/com/github/manevolent/ts3j/protocol/packet/handler/PacketHandler.java +++ b/src/main/java/com/github/manevolent/ts3j/protocol/packet/handler/PacketHandler.java @@ -26,10 +26,6 @@ public abstract class PacketHandler { } - public void handleCommand(Command command) { - - } - public TeamspeakClientSocket getClient() { return clientSocket; } diff --git a/src/main/java/com/github/manevolent/ts3j/protocol/packet/handler/local/LocalClientHandler.java b/src/main/java/com/github/manevolent/ts3j/protocol/packet/handler/client/LocalClientHandler.java similarity index 71% rename from src/main/java/com/github/manevolent/ts3j/protocol/packet/handler/local/LocalClientHandler.java rename to src/main/java/com/github/manevolent/ts3j/protocol/packet/handler/client/LocalClientHandler.java index c3d4697..ce7280b 100644 --- a/src/main/java/com/github/manevolent/ts3j/protocol/packet/handler/local/LocalClientHandler.java +++ b/src/main/java/com/github/manevolent/ts3j/protocol/packet/handler/client/LocalClientHandler.java @@ -1,15 +1,10 @@ -package com.github.manevolent.ts3j.protocol.packet.handler.local; +package com.github.manevolent.ts3j.protocol.packet.handler.client; -import com.github.manevolent.ts3j.protocol.Packet; import com.github.manevolent.ts3j.protocol.client.ClientConnectionState; -import com.github.manevolent.ts3j.protocol.packet.PacketBody2Command; import com.github.manevolent.ts3j.protocol.packet.handler.PacketHandler; import com.github.manevolent.ts3j.protocol.socket.client.LocalTeamspeakClientSocket; -import java.io.IOException; -import java.util.concurrent.TimeoutException; - public abstract class LocalClientHandler extends PacketHandler { private final LocalTeamspeakClientSocket client; diff --git a/src/main/java/com/github/manevolent/ts3j/protocol/packet/handler/local/LocalClientHandlerConnected.java b/src/main/java/com/github/manevolent/ts3j/protocol/packet/handler/client/LocalClientHandlerConnected.java similarity index 80% rename from src/main/java/com/github/manevolent/ts3j/protocol/packet/handler/local/LocalClientHandlerConnected.java rename to src/main/java/com/github/manevolent/ts3j/protocol/packet/handler/client/LocalClientHandlerConnected.java index 4aafcac..1febd3a 100644 --- a/src/main/java/com/github/manevolent/ts3j/protocol/packet/handler/local/LocalClientHandlerConnected.java +++ b/src/main/java/com/github/manevolent/ts3j/protocol/packet/handler/client/LocalClientHandlerConnected.java @@ -1,4 +1,4 @@ -package com.github.manevolent.ts3j.protocol.packet.handler.local; +package com.github.manevolent.ts3j.protocol.packet.handler.client; import com.github.manevolent.ts3j.protocol.socket.client.LocalTeamspeakClientSocket; diff --git a/src/main/java/com/github/manevolent/ts3j/protocol/packet/handler/local/LocalClientHandlerConnecting.java b/src/main/java/com/github/manevolent/ts3j/protocol/packet/handler/client/LocalClientHandlerConnecting.java similarity index 96% rename from src/main/java/com/github/manevolent/ts3j/protocol/packet/handler/local/LocalClientHandlerConnecting.java rename to src/main/java/com/github/manevolent/ts3j/protocol/packet/handler/client/LocalClientHandlerConnecting.java index 191e306..cd194a8 100644 --- a/src/main/java/com/github/manevolent/ts3j/protocol/packet/handler/local/LocalClientHandlerConnecting.java +++ b/src/main/java/com/github/manevolent/ts3j/protocol/packet/handler/client/LocalClientHandlerConnecting.java @@ -1,6 +1,5 @@ -package com.github.manevolent.ts3j.protocol.packet.handler.local; +package com.github.manevolent.ts3j.protocol.packet.handler.client; -import com.github.manevolent.ts3j.command.CommandHandler; import com.github.manevolent.ts3j.command.SingleCommand; import com.github.manevolent.ts3j.command.parameter.CommandSingleParameter; import com.github.manevolent.ts3j.protocol.Packet; @@ -176,17 +175,20 @@ public class LocalClientHandlerConnecting extends LocalClientHandler { getClient().getIdentity() ); - getClient().sendCommand( + getClient().writePacket(new PacketBody2Command( + ProtocolRole.CLIENT, new SingleCommand( "clientek", ProtocolRole.CLIENT, new CommandSingleParameter("ek", Base64.getEncoder().encodeToString(keyPair.getKey())), new CommandSingleParameter("proof", Base64.getEncoder().encodeToString(signature)) ) - ); + )); getClient().setSecureParameters(Ts3Crypt.cryptoInit2(license, alphaBytes, beta, keyPair.getValue())); - getClient().sendCommand(new SingleCommand( + getClient().writePacket(new PacketBody2Command( + ProtocolRole.CLIENT, + new SingleCommand( "clientinit", ProtocolRole.CLIENT, new CommandSingleParameter("client_nickname", getClient().getNickname()), @@ -227,9 +229,9 @@ public class LocalClientHandlerConnecting extends LocalClientHandler { "+LyYqbDqOvEEpN5pdAbF8/v5kZ0=" ) ) - ); + )); - getClient().setCommandProcessor(CommandHandler.createLocalClientHandler()); + getClient().setCommandProcessor(getClient()); getClient().setState(ClientConnectionState.RETRIEVING_DATA); } else if (command.getName().equals("error")) { getClient().setState(ClientConnectionState.DISCONNECTED); diff --git a/src/main/java/com/github/manevolent/ts3j/protocol/packet/handler/local/LocalClientHandlerDisconnected.java b/src/main/java/com/github/manevolent/ts3j/protocol/packet/handler/client/LocalClientHandlerDisconnected.java similarity index 80% rename from src/main/java/com/github/manevolent/ts3j/protocol/packet/handler/local/LocalClientHandlerDisconnected.java rename to src/main/java/com/github/manevolent/ts3j/protocol/packet/handler/client/LocalClientHandlerDisconnected.java index 30e6faa..d894b33 100644 --- a/src/main/java/com/github/manevolent/ts3j/protocol/packet/handler/local/LocalClientHandlerDisconnected.java +++ b/src/main/java/com/github/manevolent/ts3j/protocol/packet/handler/client/LocalClientHandlerDisconnected.java @@ -1,4 +1,4 @@ -package com.github.manevolent.ts3j.protocol.packet.handler.local; +package com.github.manevolent.ts3j.protocol.packet.handler.client; import com.github.manevolent.ts3j.protocol.socket.client.LocalTeamspeakClientSocket; diff --git a/src/main/java/com/github/manevolent/ts3j/protocol/packet/handler/local/LocalClientHandlerFull.java b/src/main/java/com/github/manevolent/ts3j/protocol/packet/handler/client/LocalClientHandlerFull.java similarity index 96% rename from src/main/java/com/github/manevolent/ts3j/protocol/packet/handler/local/LocalClientHandlerFull.java rename to src/main/java/com/github/manevolent/ts3j/protocol/packet/handler/client/LocalClientHandlerFull.java index 0359a78..f00e152 100644 --- a/src/main/java/com/github/manevolent/ts3j/protocol/packet/handler/local/LocalClientHandlerFull.java +++ b/src/main/java/com/github/manevolent/ts3j/protocol/packet/handler/client/LocalClientHandlerFull.java @@ -1,4 +1,4 @@ -package com.github.manevolent.ts3j.protocol.packet.handler.local; +package com.github.manevolent.ts3j.protocol.packet.handler.client; import com.github.manevolent.ts3j.command.CommandProcessException; import com.github.manevolent.ts3j.command.CommandProcessor; diff --git a/src/main/java/com/github/manevolent/ts3j/protocol/packet/handler/local/LocalClientHandlerRetrievingData.java b/src/main/java/com/github/manevolent/ts3j/protocol/packet/handler/client/LocalClientHandlerRetrievingData.java similarity index 80% rename from src/main/java/com/github/manevolent/ts3j/protocol/packet/handler/local/LocalClientHandlerRetrievingData.java rename to src/main/java/com/github/manevolent/ts3j/protocol/packet/handler/client/LocalClientHandlerRetrievingData.java index dd6a037..3804d90 100644 --- a/src/main/java/com/github/manevolent/ts3j/protocol/packet/handler/local/LocalClientHandlerRetrievingData.java +++ b/src/main/java/com/github/manevolent/ts3j/protocol/packet/handler/client/LocalClientHandlerRetrievingData.java @@ -1,4 +1,4 @@ -package com.github.manevolent.ts3j.protocol.packet.handler.local; +package com.github.manevolent.ts3j.protocol.packet.handler.client; import com.github.manevolent.ts3j.protocol.socket.client.LocalTeamspeakClientSocket; diff --git a/src/main/java/com/github/manevolent/ts3j/protocol/packet/transformation/DefaultPacketTransformation.java b/src/main/java/com/github/manevolent/ts3j/protocol/packet/transformation/InitPacketTransformation.java similarity index 84% rename from src/main/java/com/github/manevolent/ts3j/protocol/packet/transformation/DefaultPacketTransformation.java rename to src/main/java/com/github/manevolent/ts3j/protocol/packet/transformation/InitPacketTransformation.java index fe5e38d..b245fcb 100644 --- a/src/main/java/com/github/manevolent/ts3j/protocol/packet/transformation/DefaultPacketTransformation.java +++ b/src/main/java/com/github/manevolent/ts3j/protocol/packet/transformation/InitPacketTransformation.java @@ -4,14 +4,14 @@ package com.github.manevolent.ts3j.protocol.packet.transformation; import com.github.manevolent.ts3j.protocol.header.PacketHeader; import javafx.util.Pair; -public class DefaultPacketTransformation extends PacketTransformation { +public class InitPacketTransformation extends PacketTransformation { private static final byte[] key = {0x63, 0x3A, 0x5C, 0x77, 0x69, 0x6E, 0x64, 0x6F, 0x77, 0x73, 0x5C, 0x73, 0x79, 0x73, 0x74, 0x65}; private static final byte[] nonce = {0x6D, 0x5C, 0x66, 0x69, 0x72, 0x65, 0x77, 0x61, 0x6C, 0x6C, 0x33, 0x32, 0x2E, 0x63, 0x70, 0x6C}; - public DefaultPacketTransformation() { + public InitPacketTransformation() { super(key, new byte[8]); } diff --git a/src/main/java/com/github/manevolent/ts3j/protocol/socket/client/AbstractTeamspeakClientSocket.java b/src/main/java/com/github/manevolent/ts3j/protocol/socket/client/AbstractTeamspeakClientSocket.java index 5f997bd..1fba3bb 100644 --- a/src/main/java/com/github/manevolent/ts3j/protocol/socket/client/AbstractTeamspeakClientSocket.java +++ b/src/main/java/com/github/manevolent/ts3j/protocol/socket/client/AbstractTeamspeakClientSocket.java @@ -1,15 +1,9 @@ package com.github.manevolent.ts3j.protocol.socket.client; -import com.github.manevolent.ts3j.command.Command; -import com.github.manevolent.ts3j.command.CommandProcessor; -import com.github.manevolent.ts3j.command.parameter.CommandSingleParameter; -import com.github.manevolent.ts3j.command.response.CommandResponse; +import com.github.manevolent.ts3j.command.*; import com.github.manevolent.ts3j.identity.Identity; -import com.github.manevolent.ts3j.model.Client; -import com.github.manevolent.ts3j.model.VirtualServer; import com.github.manevolent.ts3j.protocol.NetworkPacket; import com.github.manevolent.ts3j.protocol.Packet; -import com.github.manevolent.ts3j.protocol.ProtocolRole; import com.github.manevolent.ts3j.protocol.SocketRole; import com.github.manevolent.ts3j.protocol.client.ClientConnectionState; import com.github.manevolent.ts3j.protocol.header.ClientPacketHeader; @@ -17,8 +11,8 @@ import com.github.manevolent.ts3j.protocol.header.HeaderFlag; import com.github.manevolent.ts3j.protocol.header.PacketHeader; import com.github.manevolent.ts3j.protocol.packet.*; import com.github.manevolent.ts3j.protocol.packet.handler.PacketHandler; -import com.github.manevolent.ts3j.protocol.packet.handler.local.LocalClientHandler; -import com.github.manevolent.ts3j.protocol.packet.transformation.DefaultPacketTransformation; +import com.github.manevolent.ts3j.protocol.packet.handler.client.LocalClientHandler; +import com.github.manevolent.ts3j.protocol.packet.transformation.InitPacketTransformation; import com.github.manevolent.ts3j.protocol.packet.transformation.PacketTransformation; import com.github.manevolent.ts3j.protocol.socket.AbstractTeamspeakSocket; import com.github.manevolent.ts3j.util.QuickLZ; @@ -50,17 +44,14 @@ public abstract class AbstractTeamspeakClientSocket private CommandProcessor commandProcessor; - private VirtualServer virtualServer; - private Identity identity = null; private ClientConnectionState connectionState = null; - private PacketTransformation transformation = new DefaultPacketTransformation(); + private PacketTransformation transformation = new InitPacketTransformation(); private PacketHandler handler; private int generationId = 0; private int clientId = 0; private int packetId = 0; - private int commandReturnCode = 0; private final NetworkReader networkReader = new NetworkReader(); private final NetworkHandler networkHandler = new NetworkHandler(); @@ -175,34 +166,6 @@ public abstract class AbstractTeamspeakClientSocket return connectionState == ClientConnectionState.CONNECTED; } - /** - * Sends a command to the remote. - * @param command Command to send. - * @return Command response object to track command response. - * @throws IOException - */ - public CommandResponse sendCommand(Command command) throws IOException, TimeoutException { - if (command.willExpectResponse() && !isConnected()) - throw new IOException("not connected"); - - CommandResponse response; - - if (command.willExpectResponse()) { - int returnCode = commandReturnCode++; - response = new CommandResponse(command, returnCode++); - command.add(new CommandSingleParameter("return_code", Integer.toString(returnCode))); - } else { - response = new CommandResponse(command, -1); - } - - response.setDispatchedTime(System.currentTimeMillis()); - - writePacket(new PacketBody2Command(ProtocolRole.CLIENT, command)); - - return response; - } - - @Override public void writePacket(PacketBody body) throws IOException, TimeoutException { PacketHeader header; @@ -311,9 +274,6 @@ public abstract class AbstractTeamspeakClientSocket ByteBuffer outputBuffer; if (!packet.getHeader().getPacketFlag(HeaderFlag.UNENCRYPTED)) { - if (!packet.getHeader().getType().canEncrypt()) - throw new IllegalArgumentException("packet flagged as encrypted but this would be a violation"); - outputBuffer = getTransformation().encrypt(packet); } else { if (packet.getHeader().getType() == PacketBodyType.INIT1) { @@ -392,13 +352,19 @@ public abstract class AbstractTeamspeakClientSocket if (networkPacket.getHeader().getType().isSplittable()) { fragment = fragment || reassemblyQueue.get(networkPacket.getHeader().getType()).isReassembling(); } else if (fragment) - throw new IllegalArgumentException("packet is fragment, but not splittable"); + throw new IllegalArgumentException( + networkPacket.getHeader().getType() + + "packet is fragment, but not splittable" + ); boolean encrypted = !networkPacket.getHeader().getPacketFlag(HeaderFlag.UNENCRYPTED) && networkPacket.getHeader().getType().canEncrypt(); if (networkPacket.getHeader().getType().mustEncrypt() && !encrypted) - throw new IllegalArgumentException("packet is unencrypted, but must be encrypted"); + throw new IllegalArgumentException( + networkPacket.getHeader().getType() + + " is unencrypted, but must be encrypted" + ); ByteBuffer packetBuffer = (ByteBuffer) networkPacket.getBuffer().position(networkPacket.getHeader().getSize()); @@ -599,18 +565,6 @@ public abstract class AbstractTeamspeakClientSocket this.commandProcessor = commandProcessor; } - public VirtualServer getVirtualServer() { - return virtualServer; - } - - public void setVirtualServer(VirtualServer virtualServer) { - this.virtualServer = virtualServer; - } - - public Client getSelf() { - return virtualServer.getClientById(clientId); - } - private class NetworkHandler implements Runnable { @Override public void run() { diff --git a/src/main/java/com/github/manevolent/ts3j/protocol/socket/client/LocalTeamspeakClientSocket.java b/src/main/java/com/github/manevolent/ts3j/protocol/socket/client/LocalTeamspeakClientSocket.java index 8801451..d601b36 100644 --- a/src/main/java/com/github/manevolent/ts3j/protocol/socket/client/LocalTeamspeakClientSocket.java +++ b/src/main/java/com/github/manevolent/ts3j/protocol/socket/client/LocalTeamspeakClientSocket.java @@ -1,9 +1,18 @@ package com.github.manevolent.ts3j.protocol.socket.client; +import com.github.manevolent.ts3j.api.Channel; +import com.github.manevolent.ts3j.command.*; +import com.github.manevolent.ts3j.command.parameter.CommandSingleParameter; +import com.github.manevolent.ts3j.command.response.AbstractCommandResponse; +import com.github.manevolent.ts3j.command.response.CommandResponse; +import com.github.manevolent.ts3j.event.TS3Event; +import com.github.manevolent.ts3j.event.TS3Listener; import com.github.manevolent.ts3j.identity.LocalIdentity; import com.github.manevolent.ts3j.protocol.NetworkPacket; +import com.github.manevolent.ts3j.protocol.ProtocolRole; import com.github.manevolent.ts3j.protocol.client.ClientConnectionState; import com.github.manevolent.ts3j.protocol.header.PacketHeader; +import com.github.manevolent.ts3j.protocol.packet.PacketBody2Command; import com.github.manevolent.ts3j.util.Ts3Debugging; import java.io.IOException; @@ -13,13 +22,15 @@ import java.net.InetSocketAddress; import java.net.SocketException; import java.nio.ByteBuffer; import java.nio.ByteOrder; +import java.util.*; import java.util.concurrent.TimeoutException; +import java.util.function.Function; -public class LocalTeamspeakClientSocket extends AbstractTeamspeakClientSocket { +public class LocalTeamspeakClientSocket + extends AbstractTeamspeakClientSocket + implements CommandProcessor { private final DatagramSocket socket; - private final DatagramPacket packet = new DatagramPacket(new byte[500], 500); - { try { socket = new DatagramSocket(); @@ -28,8 +39,31 @@ public class LocalTeamspeakClientSocket extends AbstractTeamspeakClientSocket { } } + private final DatagramPacket packet = new DatagramPacket(new byte[500], 500); + + private final Map namedProcessors = new HashMap<>(); + private final Object commandSendLock = new Object(); + + private List listeners = new LinkedList<>(); + + private int acceptingReturnCode = 0; + private int lastReturnCode = 0; + private Map awaitingCommands = new HashMap<>(); + public LocalTeamspeakClientSocket() { super(); + + namedProcessors.put("initserver", new InitServerHandler()); + namedProcessors.put("channellist", new NullRouteHandler()); + namedProcessors.put("channellistfinished", new ChannelListFinishedHandler()); + } + + public void addListener(TS3Listener listener) { + this.listeners.add(listener); + } + + public boolean removeListener(TS3Listener listener) { + return this.listeners.remove(listener); } @Override @@ -101,7 +135,8 @@ public class LocalTeamspeakClientSocket extends AbstractTeamspeakClientSocket { setGenerationId(0); setOption("client.hostname", remote.getHostString()); - //setOption("client.password", password); + + if (password != null) setOption("client.password", password); socket.connect(remote); @@ -133,4 +168,167 @@ public class LocalTeamspeakClientSocket extends AbstractTeamspeakClientSocket { public void close() throws IOException { socket.close(); } + + @Override + public void process(AbstractTeamspeakClientSocket client, + SingleCommand singleCommand) + throws CommandProcessException { + CommandProcessor processor = namedProcessors.get(singleCommand.getName()); + if (processor != null) { + processor.process(client, singleCommand); + } else if (singleCommand.getName().startsWith("notify")) { + TS3Event event = TS3Event.createEvent(singleCommand); + for (TS3Listener listener : listeners) event.fire(listener); + } else { + CommandProcessor awaitingCommandProcessor; + + synchronized (commandSendLock) { + awaitingCommandProcessor = awaitingCommands.get(acceptingReturnCode); + } + + if (awaitingCommandProcessor != null) + awaitingCommandProcessor.process(client, singleCommand); + } + } + + public CommandResponse> getChannels() throws IOException, TimeoutException { + return executeMappedCommand( + new SingleCommand("channellist", ProtocolRole.CLIENT), + command -> new Channel(command.toMap()) + ); + } + + private CommandResponse> executeCommand(Command command) + throws IOException, TimeoutException { + return executeCommand(command, Function.identity()); + } + + private CommandResponse executeCommand( + Command command, + Function, T> processor + ) throws IOException, TimeoutException { + int returnCode; + + ClientCommandResponse response; + + // sync may not be necessary here + synchronized (commandSendLock) { + returnCode = lastReturnCode++; + awaitingCommands.put(returnCode, response = new ClientCommandResponse<>(returnCode, processor)); + } + + command.add(new CommandSingleParameter("return_code", Integer.toString(returnCode))); + + try { + writePacket(new PacketBody2Command(getRole().getOut(), command)); + } catch (Throwable e) { + awaitingCommands.remove(returnCode); + + throw e; + } + + return response; + } + + private CommandResponse> executeMappedCommand( + Command command, + Function processor + ) throws IOException, TimeoutException { + int returnCode; + + // sync may not be necessary here + synchronized (commandSendLock) { + returnCode = lastReturnCode++; + } + + command.add(new CommandSingleParameter("return_code", Integer.toString(returnCode))); + + ClientCommandResponse> response; + + awaitingCommands.put(returnCode, response = new ClientCommandResponse<>(returnCode, multiCommands -> { + List commands = new LinkedList<>(); + for (MultiCommand multiCommand : multiCommands) commands.addAll(multiCommand.simplify()); + + List results = new LinkedList<>(); + for (SingleCommand command1 : commands) + results.add(processor.apply(command1)); + + return results; + })); + + try { + writePacket(new PacketBody2Command(getRole().getOut(), command)); + } catch (Throwable e) { + awaitingCommands.remove(returnCode); + + throw e; + } + + return response; + } + + private class ClientCommandResponse + extends AbstractCommandResponse + implements CommandProcessor { + private final int returnCode; + private final List commands = new LinkedList<>(); + + public ClientCommandResponse(int returnCode, + Function, T> processor) { + super(processor); + this.returnCode = returnCode; + } + + @Override + public void process(AbstractTeamspeakClientSocket client, + MultiCommand multiCommand) + throws CommandProcessException { + if (multiCommand.getName().equalsIgnoreCase("error")) { + SingleCommand command = multiCommand.simplifyFirst(); + int errorId = Integer.parseInt(command.get("id").getValue()); + + switch (errorId) { + case 0: + completeSuccess(commands); + break; + default: + completeFailure(new CommandException(command.get("msg").getValue(), errorId)); + break; + } + + synchronized (awaitingCommands) { + awaitingCommands.remove(returnCode); + } + } else + commands.add(multiCommand); + } + + public int getReturnCode() { + return returnCode; + } + } + + private class ChannelListFinishedHandler implements CommandProcessor { + + } + + private class NullRouteHandler implements CommandProcessor { + @Override + public void process(AbstractTeamspeakClientSocket client, SingleCommand singleCommand) + throws CommandProcessException { + // Do nothing + } + } + + private class InitServerHandler implements CommandProcessor { + @Override + public void process(AbstractTeamspeakClientSocket client, SingleCommand singleCommand) + throws CommandProcessException { + try { + setState(ClientConnectionState.CONNECTED); + } catch (Exception e) { + throw new CommandProcessException(e); + } + } + } } diff --git a/src/test/java/com/github/manevolent/ts3j/ServerConnectionTest.java b/src/test/java/com/github/manevolent/ts3j/ServerConnectionTest.java index 5a8f599..414c2fd 100644 --- a/src/test/java/com/github/manevolent/ts3j/ServerConnectionTest.java +++ b/src/test/java/com/github/manevolent/ts3j/ServerConnectionTest.java @@ -1,7 +1,8 @@ package com.github.manevolent.ts3j; +import com.github.manevolent.ts3j.command.SingleCommand; import com.github.manevolent.ts3j.identity.LocalIdentity; -import com.github.manevolent.ts3j.model.Channel; +import com.github.manevolent.ts3j.protocol.ProtocolRole; import com.github.manevolent.ts3j.protocol.client.ClientConnectionState; import com.github.manevolent.ts3j.protocol.socket.client.LocalTeamspeakClientSocket; import com.github.manevolent.ts3j.util.Ts3Crypt; @@ -38,12 +39,7 @@ public class ServerConnectionTest { assertEquals(client.getState(), ClientConnectionState.CONNECTED); - Ts3Debugging.info("Connected to " + client.getVirtualServer().getName() + "."); - Ts3Debugging.info(" Client name: " + client.getSelf().getNickname()); - Ts3Debugging.info(" Channels: " + - client.getVirtualServer().getChannelsOrderd() - .stream().map(Channel::getName).collect(Collectors.toList()) - ); + client.getChannels().complete(); } catch (Throwable ex) { ex.printStackTrace(); }