Moving further along with the connection-level commands that are received, and now have model objects to store variables. No callbacks to the server yet, but that will happen soon. Right now I have channel listings and basic client information done.
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
package com.github.manevolent.ts3j.command;
|
||||
|
||||
import com.github.manevolent.ts3j.command.part.CommandParameter;
|
||||
import com.github.manevolent.ts3j.command.parameter.CommandParameter;
|
||||
import com.github.manevolent.ts3j.protocol.ProtocolRole;
|
||||
|
||||
public interface Command {
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
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;
|
||||
|
||||
@@ -15,19 +18,28 @@ public final class CommandHandler implements CommandProcessor {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void process(AbstractTeamspeakClientSocket socket, ComplexCommand complexCommand)
|
||||
public void process(AbstractTeamspeakClientSocket socket, MultiCommand multiCommand)
|
||||
throws CommandProcessException {
|
||||
Ts3Debugging.debug("[COMMAND] " + complexCommand.build());
|
||||
|
||||
CommandProcessor processor = commandProcessors.get(complexCommand.getName().toLowerCase());
|
||||
CommandProcessor processor = commandProcessors.get(multiCommand.getName().toLowerCase());
|
||||
if (processor != null)
|
||||
processor.process(socket, complexCommand);
|
||||
processor.process(socket, multiCommand);
|
||||
}
|
||||
|
||||
public static CommandHandler createLocalClient() {
|
||||
@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;
|
||||
}
|
||||
|
||||
@@ -3,6 +3,14 @@ package com.github.manevolent.ts3j.command;
|
||||
import com.github.manevolent.ts3j.protocol.socket.client.AbstractTeamspeakClientSocket;
|
||||
|
||||
public interface CommandProcessor {
|
||||
void process(AbstractTeamspeakClientSocket socket, ComplexCommand complexCommand)
|
||||
throws CommandProcessException;
|
||||
default void process(AbstractTeamspeakClientSocket client,
|
||||
MultiCommand multiCommand)
|
||||
throws CommandProcessException {
|
||||
for (SingleCommand singleCommand : multiCommand.simplify()) process(client, singleCommand);
|
||||
}
|
||||
|
||||
|
||||
default void process(AbstractTeamspeakClientSocket client,
|
||||
SingleCommand singleCommand)
|
||||
throws CommandProcessException { }
|
||||
}
|
||||
|
||||
@@ -1,90 +0,0 @@
|
||||
package com.github.manevolent.ts3j.command;
|
||||
|
||||
import com.github.manevolent.ts3j.command.part.CommandOption;
|
||||
import com.github.manevolent.ts3j.command.part.CommandParameter;
|
||||
import com.github.manevolent.ts3j.command.part.CommandSingleParameter;
|
||||
import com.github.manevolent.ts3j.protocol.ProtocolRole;
|
||||
import com.github.manevolent.ts3j.util.Ts3String;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
public class ComplexCommand implements Command {
|
||||
private final String name;
|
||||
private final ProtocolRole role;
|
||||
private final List<CommandParameter> params;
|
||||
|
||||
public ComplexCommand(String name, ProtocolRole role, CommandParameter... params) {
|
||||
this(name, role, Arrays.asList(params));
|
||||
}
|
||||
|
||||
public ComplexCommand(String name, ProtocolRole role, List<CommandParameter> params) {
|
||||
this.name = name;
|
||||
this.role = role;
|
||||
this.params = new LinkedList<>();
|
||||
|
||||
for (CommandParameter parameter : params) add(parameter);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ProtocolRole getRole() {
|
||||
return role;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterable<CommandParameter> getParameters() {
|
||||
return Collections.unmodifiableCollection(params);
|
||||
}
|
||||
|
||||
public boolean has(String key) {
|
||||
return params.stream().anyMatch(x -> x.getName().equalsIgnoreCase(key));
|
||||
}
|
||||
|
||||
public void add(CommandParameter parameter) {
|
||||
if (parameter.getName().trim().length() <= 0)
|
||||
throw new IllegalArgumentException("invalid key (empty)");
|
||||
|
||||
this.params.add(parameter);
|
||||
}
|
||||
|
||||
public SimpleCommand simplify() {
|
||||
return new SimpleCommand(
|
||||
name,
|
||||
role,
|
||||
params
|
||||
);
|
||||
}
|
||||
|
||||
public static ComplexCommand parse(ProtocolRole role, String commandText) {
|
||||
String[] commandParts = commandText.split(" ");
|
||||
|
||||
String commandLabel = commandParts[0].toLowerCase();
|
||||
|
||||
List<CommandParameter> parameterList = new LinkedList<>();
|
||||
|
||||
for (int i = 1; i < commandParts.length; i ++) {
|
||||
String commandParamText = commandParts[i].trim();
|
||||
if (commandParamText.length() <= 0) continue;
|
||||
|
||||
if (commandParamText.startsWith("-")) { // Option
|
||||
parameterList.add(new CommandOption(commandParamText.substring(1)));
|
||||
} else {
|
||||
String[] commandParamParts = commandParamText.split("=", 2);
|
||||
|
||||
parameterList.add(new CommandSingleParameter(
|
||||
commandParamParts[0].toLowerCase(),
|
||||
commandParamParts.length > 1 ?
|
||||
Ts3String.unescape(commandParamParts[1]) :
|
||||
null
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return new ComplexCommand(commandLabel, role, parameterList);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,117 @@
|
||||
package com.github.manevolent.ts3j.command;
|
||||
|
||||
import com.github.manevolent.ts3j.command.parameter.CommandOption;
|
||||
import com.github.manevolent.ts3j.command.parameter.CommandParameter;
|
||||
import com.github.manevolent.ts3j.command.parameter.CommandSingleParameter;
|
||||
import com.github.manevolent.ts3j.protocol.ProtocolRole;
|
||||
import com.github.manevolent.ts3j.util.Ts3String;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
public class MultiCommand implements Command {
|
||||
private final String name;
|
||||
private final ProtocolRole role;
|
||||
private final List<SingleCommand> commands;
|
||||
|
||||
public MultiCommand(String name, ProtocolRole role, SingleCommand... params) {
|
||||
this(name, role, Arrays.asList(params));
|
||||
}
|
||||
|
||||
public MultiCommand(String name, ProtocolRole role, List<SingleCommand> params) {
|
||||
this.name = name;
|
||||
this.role = role;
|
||||
this.commands = Collections.unmodifiableList(params);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ProtocolRole getRole() {
|
||||
return role;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterable<CommandParameter> getParameters() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void add(CommandParameter parameter) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
public List<SingleCommand> simplify() {
|
||||
return Collections.unmodifiableList(commands);
|
||||
}
|
||||
|
||||
public SingleCommand simplifyFirst() {
|
||||
return commands.stream().findFirst().orElse(null);
|
||||
}
|
||||
|
||||
public SingleCommand simplifyOne() {
|
||||
if (commands.size() > 1) throw new IllegalArgumentException("ambiguous; more than one command");
|
||||
return commands.stream().findFirst().orElse(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String build() {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
|
||||
builder.append(getName().toLowerCase());
|
||||
|
||||
List<SingleCommand> singleCommands = simplify();
|
||||
|
||||
for (int i = 0; i < singleCommands.size(); i ++) {
|
||||
boolean first = i == 0;
|
||||
boolean last = i == singleCommands.size() - 1;
|
||||
|
||||
if (!first) builder.append("\\p");
|
||||
|
||||
for (CommandParameter parameter : singleCommands.get(i).getParameters()) {
|
||||
builder.append(" " + (parameter.toString()).trim());
|
||||
}
|
||||
}
|
||||
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
public static MultiCommand parse(ProtocolRole role, String text) {
|
||||
String[] labelAndText = text.split(" ", 2);
|
||||
String label = labelAndText[0].toLowerCase();
|
||||
String[] commands = labelAndText.length > 1 ? labelAndText[1].split("\\|") : new String[0];
|
||||
|
||||
List<SingleCommand> singleCommands = new LinkedList<>();
|
||||
|
||||
for (String commandText : commands) {
|
||||
String[] commandParts = commandText.split(" ");
|
||||
|
||||
List<CommandParameter> parameterList = new LinkedList<>();
|
||||
|
||||
for (int i = 0; i < commandParts.length; i++) {
|
||||
String commandParamText = commandParts[i].trim();
|
||||
if (commandParamText.length() <= 0) continue;
|
||||
|
||||
if (commandParamText.startsWith("-")) { // Option
|
||||
parameterList.add(new CommandOption(commandParamText.substring(1)));
|
||||
} else {
|
||||
String[] commandParamParts = commandParamText.split("=", 2);
|
||||
|
||||
parameterList.add(new CommandSingleParameter(
|
||||
commandParamParts[0].toLowerCase(),
|
||||
commandParamParts.length > 1 ?
|
||||
Ts3String.unescape(commandParamParts[1]) :
|
||||
null
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
singleCommands.add(new SingleCommand(label, role, parameterList));
|
||||
}
|
||||
|
||||
return new MultiCommand(label, role, singleCommands);
|
||||
}
|
||||
}
|
||||
+7
-10
@@ -1,23 +1,20 @@
|
||||
package com.github.manevolent.ts3j.command;
|
||||
|
||||
import com.github.manevolent.ts3j.command.part.CommandOption;
|
||||
import com.github.manevolent.ts3j.command.part.CommandParameter;
|
||||
import com.github.manevolent.ts3j.command.part.CommandSingleParameter;
|
||||
import com.github.manevolent.ts3j.command.parameter.CommandParameter;
|
||||
import com.github.manevolent.ts3j.protocol.ProtocolRole;
|
||||
import com.github.manevolent.ts3j.util.Ts3String;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
public class SimpleCommand implements Command {
|
||||
public class SingleCommand implements Command {
|
||||
private final String name;
|
||||
private final ProtocolRole role;
|
||||
private final Map<String, CommandParameter> params;
|
||||
|
||||
public SimpleCommand(String name, ProtocolRole role, CommandParameter... params) {
|
||||
public SingleCommand(String name, ProtocolRole role, CommandParameter... params) {
|
||||
this(name, role, Arrays.asList(params));
|
||||
}
|
||||
|
||||
public SimpleCommand(String name, ProtocolRole role, List<CommandParameter> params) {
|
||||
public SingleCommand(String name, ProtocolRole role, List<CommandParameter> params) {
|
||||
this.name = name;
|
||||
this.role = role;
|
||||
|
||||
@@ -47,7 +44,7 @@ public class SimpleCommand implements Command {
|
||||
|
||||
public void add(CommandParameter parameter) {
|
||||
CommandParameter existing = get(parameter.getName());
|
||||
if (existing != null) throw new IllegalArgumentException(parameter.getName() + " already set");
|
||||
if (existing != null) throw new IllegalArgumentException(getName() + ": " + parameter.getName() + " already set");
|
||||
|
||||
if (parameter.getName().trim().length() <= 0)
|
||||
throw new IllegalArgumentException("invalid key (empty)");
|
||||
@@ -63,7 +60,7 @@ public class SimpleCommand implements Command {
|
||||
return this.params.remove(key);
|
||||
}
|
||||
|
||||
public static SimpleCommand parse(ProtocolRole role, String commandText) {
|
||||
return ComplexCommand.parse(role, commandText).simplify();
|
||||
public static SingleCommand parse(ProtocolRole role, String commandText) {
|
||||
return MultiCommand.parse(role, commandText).simplifyFirst();
|
||||
}
|
||||
}
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
+45
@@ -0,0 +1,45 @@
|
||||
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);
|
||||
}
|
||||
}
|
||||
+34
-12
@@ -2,24 +2,46 @@ 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.ComplexCommand;
|
||||
import com.github.manevolent.ts3j.command.SimpleCommand;
|
||||
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;
|
||||
import com.github.manevolent.ts3j.util.Ts3Debugging;
|
||||
|
||||
public class ClientInitServerProcessor implements CommandProcessor {
|
||||
@Override
|
||||
public void process(AbstractTeamspeakClientSocket socket, ComplexCommand complexCommand) throws CommandProcessException {
|
||||
SimpleCommand command = complexCommand.simplify();
|
||||
public void process(AbstractTeamspeakClientSocket client,
|
||||
MultiCommand multiCommand) throws CommandProcessException {
|
||||
SingleCommand command = multiCommand.simplifyOne();
|
||||
|
||||
Ts3Debugging.debug(command.get("virtualserver_welcomemessage").getValue());
|
||||
VirtualServer server = new VirtualServer();
|
||||
|
||||
if (socket.getState() == ClientConnectionState.RETRIEVING_DATA)
|
||||
try {
|
||||
socket.setState(ClientConnectionState.CONNECTED);
|
||||
} catch (Exception e) {
|
||||
throw new CommandProcessException(e);
|
||||
}
|
||||
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()));
|
||||
}
|
||||
}
|
||||
|
||||
+71
@@ -0,0 +1,71 @@
|
||||
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);
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
package com.github.manevolent.ts3j.command.part;
|
||||
package com.github.manevolent.ts3j.command.parameter;
|
||||
|
||||
public class CommandOption implements CommandParameter {
|
||||
private final String key;
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
package com.github.manevolent.ts3j.command.part;
|
||||
package com.github.manevolent.ts3j.command.parameter;
|
||||
|
||||
import java.util.Base64;
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
package com.github.manevolent.ts3j.command.part;
|
||||
package com.github.manevolent.ts3j.command.parameter;
|
||||
|
||||
import com.github.manevolent.ts3j.util.Ts3String;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package com.github.manevolent.ts3j.command.response;
|
||||
|
||||
import com.github.manevolent.ts3j.command.Command;
|
||||
import com.github.manevolent.ts3j.command.ComplexCommand;
|
||||
import com.github.manevolent.ts3j.command.MultiCommand;
|
||||
|
||||
import java.util.concurrent.TimeoutException;
|
||||
|
||||
@@ -11,7 +11,7 @@ public class CommandResponse {
|
||||
private final int returnCode;
|
||||
|
||||
private long dispatchedTime;
|
||||
private ComplexCommand returnedCommand;
|
||||
private MultiCommand returnedCommand;
|
||||
|
||||
public CommandResponse(Command command, int returnCode) {
|
||||
this.command = command;
|
||||
@@ -26,12 +26,12 @@ public class CommandResponse {
|
||||
return returnCode;
|
||||
}
|
||||
|
||||
public ComplexCommand getResponse()
|
||||
public MultiCommand getResponse()
|
||||
throws InterruptedException, TimeoutException {
|
||||
return getResponse(Integer.MAX_VALUE);
|
||||
}
|
||||
|
||||
public ComplexCommand getResponse(int millis)
|
||||
public MultiCommand getResponse(int millis)
|
||||
throws InterruptedException, TimeoutException {
|
||||
if (returnCode < 0) return null;
|
||||
|
||||
@@ -59,11 +59,11 @@ public class CommandResponse {
|
||||
this.dispatchedTime = dispatchedTime;
|
||||
}
|
||||
|
||||
public ComplexCommand getReturnedCommand() {
|
||||
public MultiCommand getReturnedCommand() {
|
||||
return returnedCommand;
|
||||
}
|
||||
|
||||
public void setReturnedCommand(ComplexCommand 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");
|
||||
|
||||
@@ -21,7 +21,7 @@ public class Identity {
|
||||
}
|
||||
|
||||
private final ECPoint publicKey;
|
||||
private final String fingerprint;
|
||||
private final Uid uid;
|
||||
private final String publicKeyString;
|
||||
|
||||
private long keyOffset = 0L, lastCheckedKeyOffset = 0L;
|
||||
@@ -29,7 +29,7 @@ public class Identity {
|
||||
public Identity(ECPoint publicKey) {
|
||||
this.publicKey = publicKey;
|
||||
this.publicKeyString = Base64.getEncoder().encodeToString(Ts3Crypt.encodePublicKey(publicKey));
|
||||
this.fingerprint = generateFingerprint();
|
||||
this.uid = generateUid();
|
||||
}
|
||||
|
||||
public ECPoint getPublicKey() {
|
||||
@@ -40,8 +40,8 @@ public class Identity {
|
||||
return publicKeyString;
|
||||
}
|
||||
|
||||
public String getFingerprint() {
|
||||
return fingerprint;
|
||||
public Uid getUid() {
|
||||
return uid;
|
||||
}
|
||||
|
||||
public long getLastCheckedKeyOffset() {
|
||||
@@ -129,11 +129,9 @@ public class Identity {
|
||||
return curr;
|
||||
}
|
||||
|
||||
private String generateFingerprint() {
|
||||
private Uid generateUid() {
|
||||
synchronized (sha1) {
|
||||
return Base64.getEncoder().encodeToString(
|
||||
sha1.digest(getPublicKeyString().getBytes(Charset.forName("ASCII")))
|
||||
);
|
||||
return new Uid(sha1.digest(getPublicKeyString().getBytes(Charset.forName("ASCII"))));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
package com.github.manevolent.ts3j.identity;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Base64;
|
||||
|
||||
public final class Uid {
|
||||
private final byte[] uidBytes;
|
||||
private final String base64;
|
||||
|
||||
public Uid(String base64) {
|
||||
this.base64 = base64;
|
||||
this.uidBytes = Base64.getDecoder().decode(base64);
|
||||
}
|
||||
|
||||
public Uid(byte[] bytes) {
|
||||
this.uidBytes = bytes;
|
||||
this.base64 = Base64.getEncoder().encodeToString(bytes);
|
||||
}
|
||||
|
||||
public String toBase64() {
|
||||
return base64;
|
||||
}
|
||||
|
||||
public byte[] toByteArray() {
|
||||
return uidBytes;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Arrays.hashCode(toByteArray());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object b) {
|
||||
if (b == null || !(b instanceof Uid)) return false;
|
||||
return equals((Uid) b);
|
||||
}
|
||||
|
||||
public boolean equals(Uid b) {
|
||||
return b != null && Arrays.equals(b.toByteArray(), toByteArray());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,201 @@
|
||||
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;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,261 @@
|
||||
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<Integer> 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<Integer> serverGroupIds) {
|
||||
synchronized (serverGroupIds) {
|
||||
this.serverGroupIds.clear();
|
||||
this.serverGroupIds.addAll(serverGroupIds);
|
||||
}
|
||||
}
|
||||
|
||||
public void setServerGroupIds(Integer... serverGroupIds) {
|
||||
setServerGroupIds(Arrays.asList(serverGroupIds));
|
||||
}
|
||||
|
||||
public Iterable<Integer> 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;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,322 @@
|
||||
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<Integer, Client> clients = new HashMap<>();
|
||||
|
||||
/**
|
||||
* Server channels
|
||||
*/
|
||||
private final Map<Integer, Channel> 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<Channel> 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<Channel> getChannels() {
|
||||
return Collections.unmodifiableCollection(channels.values());
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the channel list as ordered by the server.
|
||||
* @return Iterable list of ordered channels.
|
||||
*/
|
||||
public Collection<Channel> 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<Client> getClients() {
|
||||
throw new UnsupportedOperationException(); // TODO
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a list of connected clients.
|
||||
* @return connected clients.
|
||||
*/
|
||||
public Collection<Client> getConnectedClients() {
|
||||
return Collections.unmodifiableCollection(clients.values());
|
||||
}
|
||||
|
||||
public List<Client> 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);
|
||||
}
|
||||
}
|
||||
@@ -1,8 +1,7 @@
|
||||
package com.github.manevolent.ts3j.protocol.packet;
|
||||
|
||||
import com.github.manevolent.ts3j.command.Command;
|
||||
import com.github.manevolent.ts3j.command.ComplexCommand;
|
||||
import com.github.manevolent.ts3j.command.SimpleCommand;
|
||||
import com.github.manevolent.ts3j.command.MultiCommand;
|
||||
import com.github.manevolent.ts3j.protocol.ProtocolRole;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
@@ -29,8 +28,8 @@ public class PacketBody2Command extends PacketBody {
|
||||
return text;
|
||||
}
|
||||
|
||||
public ComplexCommand parse() {
|
||||
return ComplexCommand.parse(getRole(), getText());
|
||||
public MultiCommand parse() {
|
||||
return MultiCommand.parse(getRole(), getText());
|
||||
}
|
||||
|
||||
public void setText(String text) {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package com.github.manevolent.ts3j.protocol.packet;
|
||||
|
||||
import com.github.manevolent.ts3j.command.Command;
|
||||
import com.github.manevolent.ts3j.command.ComplexCommand;
|
||||
import com.github.manevolent.ts3j.command.MultiCommand;
|
||||
import com.github.manevolent.ts3j.protocol.ProtocolRole;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
@@ -28,8 +28,8 @@ public class PacketBody3CommandLow extends PacketBody {
|
||||
return text;
|
||||
}
|
||||
|
||||
public ComplexCommand parse() {
|
||||
return ComplexCommand.parse(getRole(), getText());
|
||||
public MultiCommand parse() {
|
||||
return MultiCommand.parse(getRole(), getText());
|
||||
}
|
||||
|
||||
public void setText(String text) {
|
||||
|
||||
+7
-7
@@ -1,8 +1,8 @@
|
||||
package com.github.manevolent.ts3j.protocol.packet.handler.local;
|
||||
|
||||
import com.github.manevolent.ts3j.command.CommandHandler;
|
||||
import com.github.manevolent.ts3j.command.SimpleCommand;
|
||||
import com.github.manevolent.ts3j.command.part.CommandSingleParameter;
|
||||
import com.github.manevolent.ts3j.command.SingleCommand;
|
||||
import com.github.manevolent.ts3j.command.parameter.CommandSingleParameter;
|
||||
import com.github.manevolent.ts3j.protocol.Packet;
|
||||
import com.github.manevolent.ts3j.protocol.ProtocolRole;
|
||||
import com.github.manevolent.ts3j.protocol.client.ClientConnectionState;
|
||||
@@ -116,7 +116,7 @@ public class LocalClientHandlerConnecting extends LocalClientHandler {
|
||||
alphaBytes = new byte[10];
|
||||
new Random().nextBytes(alphaBytes);
|
||||
|
||||
SimpleCommand initiv = new SimpleCommand("clientinitiv", ProtocolRole.CLIENT);
|
||||
SingleCommand initiv = new SingleCommand("clientinitiv", ProtocolRole.CLIENT);
|
||||
|
||||
initiv.add(new CommandSingleParameter("alpha", Base64.getEncoder().encodeToString(alphaBytes)));
|
||||
|
||||
@@ -142,7 +142,7 @@ public class LocalClientHandlerConnecting extends LocalClientHandler {
|
||||
|
||||
}
|
||||
} else if (packet.getBody() instanceof PacketBody2Command) {
|
||||
SimpleCommand command = ((PacketBody2Command) packet.getBody()).parse().simplify();
|
||||
SingleCommand command = ((PacketBody2Command) packet.getBody()).parse().simplifyOne();
|
||||
|
||||
if (command.getName().equalsIgnoreCase("initivexpand2")) {
|
||||
// 3.2.2 initivexpand2 (Client <- Server)
|
||||
@@ -177,7 +177,7 @@ public class LocalClientHandlerConnecting extends LocalClientHandler {
|
||||
);
|
||||
|
||||
getClient().sendCommand(
|
||||
new SimpleCommand(
|
||||
new SingleCommand(
|
||||
"clientek", ProtocolRole.CLIENT,
|
||||
new CommandSingleParameter("ek", Base64.getEncoder().encodeToString(keyPair.getKey())),
|
||||
new CommandSingleParameter("proof", Base64.getEncoder().encodeToString(signature))
|
||||
@@ -186,7 +186,7 @@ public class LocalClientHandlerConnecting extends LocalClientHandler {
|
||||
|
||||
getClient().setSecureParameters(Ts3Crypt.cryptoInit2(license, alphaBytes, beta, keyPair.getValue()));
|
||||
|
||||
getClient().sendCommand(new SimpleCommand(
|
||||
getClient().sendCommand(new SingleCommand(
|
||||
"clientinit",
|
||||
ProtocolRole.CLIENT,
|
||||
new CommandSingleParameter("client_nickname", getClient().getNickname()),
|
||||
@@ -229,7 +229,7 @@ public class LocalClientHandlerConnecting extends LocalClientHandler {
|
||||
)
|
||||
);
|
||||
|
||||
getClient().setCommandProcessor(CommandHandler.createLocalClient());
|
||||
getClient().setCommandProcessor(CommandHandler.createLocalClientHandler());
|
||||
getClient().setState(ClientConnectionState.RETRIEVING_DATA);
|
||||
} else if (command.getName().equals("error")) {
|
||||
getClient().setState(ClientConnectionState.DISCONNECTED);
|
||||
|
||||
+6
-4
@@ -2,11 +2,12 @@ package com.github.manevolent.ts3j.protocol.packet.handler.local;
|
||||
|
||||
import com.github.manevolent.ts3j.command.CommandProcessException;
|
||||
import com.github.manevolent.ts3j.command.CommandProcessor;
|
||||
import com.github.manevolent.ts3j.command.ComplexCommand;
|
||||
import com.github.manevolent.ts3j.command.MultiCommand;
|
||||
import com.github.manevolent.ts3j.protocol.Packet;
|
||||
import com.github.manevolent.ts3j.protocol.packet.PacketBody2Command;
|
||||
import com.github.manevolent.ts3j.protocol.packet.PacketBody3CommandLow;
|
||||
import com.github.manevolent.ts3j.protocol.socket.client.LocalTeamspeakClientSocket;
|
||||
import com.github.manevolent.ts3j.util.Ts3Debugging;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
@@ -16,7 +17,7 @@ public abstract class LocalClientHandlerFull extends LocalClientHandler {
|
||||
super(client);
|
||||
}
|
||||
|
||||
protected void handleCommand(ComplexCommand command) throws CommandProcessException {
|
||||
protected void handleCommand(MultiCommand command) throws CommandProcessException {
|
||||
CommandProcessor processor = getClient().getCommandProcessor();
|
||||
if (processor != null) processor.process(getClient(), command);
|
||||
}
|
||||
@@ -25,8 +26,9 @@ public abstract class LocalClientHandlerFull extends LocalClientHandler {
|
||||
public void handlePacket(Packet packet) throws IOException, TimeoutException {
|
||||
switch (packet.getBody().getType()) {
|
||||
case COMMAND:
|
||||
Ts3Debugging.debug(((PacketBody2Command) packet.getBody()).getText());
|
||||
try {
|
||||
handleCommand(ComplexCommand.parse(
|
||||
handleCommand(MultiCommand.parse(
|
||||
packet.getRole(),
|
||||
((PacketBody2Command) packet.getBody()).getText()
|
||||
));
|
||||
@@ -36,7 +38,7 @@ public abstract class LocalClientHandlerFull extends LocalClientHandler {
|
||||
break;
|
||||
case COMMAND_LOW:
|
||||
try {
|
||||
handleCommand(ComplexCommand.parse(
|
||||
handleCommand(MultiCommand.parse(
|
||||
packet.getRole(),
|
||||
((PacketBody3CommandLow) packet.getBody()).getText()
|
||||
));
|
||||
|
||||
+87
-21
@@ -2,9 +2,11 @@ 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.part.CommandSingleParameter;
|
||||
import com.github.manevolent.ts3j.command.parameter.CommandSingleParameter;
|
||||
import com.github.manevolent.ts3j.command.response.CommandResponse;
|
||||
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;
|
||||
@@ -43,10 +45,13 @@ public abstract class AbstractTeamspeakClientSocket
|
||||
private final Map<PacketBodyType, Reassembly> reassemblyQueue = new ConcurrentHashMap<>();
|
||||
private final Map<String, Object> clientOptions = new ConcurrentHashMap<>();
|
||||
private final Map<Integer, PacketResponse> sendQueue = new ConcurrentHashMap<>();
|
||||
private final Map<PacketBodyType, PacketCounter> sendCounter = new ConcurrentHashMap<>();
|
||||
private final Map<PacketBodyType, PacketCounter> localSendCounter = new ConcurrentHashMap<>();
|
||||
private final Map<PacketBodyType, PacketCounter> remoteSendCounter = new ConcurrentHashMap<>();
|
||||
|
||||
private CommandProcessor commandProcessor;
|
||||
|
||||
private VirtualServer virtualServer;
|
||||
|
||||
private Identity identity = null;
|
||||
private ClientConnectionState connectionState = null;
|
||||
private PacketTransformation transformation = new DefaultPacketTransformation();
|
||||
@@ -80,10 +85,13 @@ public abstract class AbstractTeamspeakClientSocket
|
||||
|
||||
// Initialize counters
|
||||
for (PacketBodyType bodyType : PacketBodyType.values())
|
||||
if (bodyType == PacketBodyType.INIT1)
|
||||
sendCounter.put(PacketBodyType.INIT1, new PacketCounterZero());
|
||||
else
|
||||
sendCounter.put(bodyType, new PacketCounterFull());
|
||||
if (bodyType == PacketBodyType.INIT1) {
|
||||
localSendCounter.put(PacketBodyType.INIT1, new PacketCounterZero());
|
||||
remoteSendCounter.put(PacketBodyType.INIT1, new PacketCounterZero());
|
||||
} else {
|
||||
localSendCounter.put(bodyType, new PacketCounterFull());
|
||||
remoteSendCounter.put(bodyType, new PacketCounterFull(-1));
|
||||
}
|
||||
}
|
||||
|
||||
protected void start() {
|
||||
@@ -228,7 +236,7 @@ public abstract class AbstractTeamspeakClientSocket
|
||||
// Set header values
|
||||
packet.getBody().setHeaderValues(packet.getHeader());
|
||||
|
||||
Pair<Integer, Integer> counterResult = sendCounter.get(packet.getHeader().getType()).next();
|
||||
Pair<Integer, Integer> counterResult = localSendCounter.get(packet.getHeader().getType()).next();
|
||||
if (packet.getHeader() instanceof ClientPacketHeader)
|
||||
((ClientPacketHeader) packet.getHeader()).setClientId(clientId);
|
||||
|
||||
@@ -460,11 +468,22 @@ public abstract class AbstractTeamspeakClientSocket
|
||||
}
|
||||
|
||||
// Find if the packet must be reassembled
|
||||
if (packet.getBody() instanceof PacketBodyFragment) {
|
||||
if (packet.getHeader().getType().isSplittable()) {
|
||||
packet = reassemblyQueue.get(packet.getHeader().getType()).put(packet);
|
||||
if (packet == null) continue;
|
||||
}
|
||||
|
||||
if (packet.getHeader().getType().canResend() && packet.getHeader().getType() != PacketBodyType.INIT1)
|
||||
// Find if we already acknowledged this packet
|
||||
if (!remoteSendCounter
|
||||
.get(packet.getHeader().getType())
|
||||
.setPacketId(packet.getHeader().getPacketId())) {
|
||||
Ts3Debugging.debug("[PROTOCOL] Ignoring handling resent packet: " +
|
||||
packet.getHeader().getType().name() + " id=" +
|
||||
packet.getHeader().getPacketId());
|
||||
continue; // Drop the packet
|
||||
}
|
||||
|
||||
// Find if the packet is itself an acknowledgement
|
||||
boolean handle;
|
||||
PacketResponse response;
|
||||
@@ -580,6 +599,18 @@ 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() {
|
||||
@@ -692,6 +723,8 @@ public abstract class AbstractTeamspeakClientSocket
|
||||
|
||||
private interface PacketCounter {
|
||||
Pair<Integer, Integer> next();
|
||||
int getPacketId();
|
||||
boolean setPacketId(int packetId);
|
||||
int getGenerationId();
|
||||
}
|
||||
|
||||
@@ -701,6 +734,16 @@ public abstract class AbstractTeamspeakClientSocket
|
||||
return new Pair<>(0,0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getPacketId() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean setPacketId(int packetId) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getGenerationId() {
|
||||
return 0;
|
||||
@@ -712,10 +755,34 @@ public abstract class AbstractTeamspeakClientSocket
|
||||
private int packetId = 0;
|
||||
private int generationId = 0;
|
||||
|
||||
public PacketCounterFull() {
|
||||
|
||||
}
|
||||
|
||||
public PacketCounterFull(int start) {
|
||||
setPacketId(start);
|
||||
}
|
||||
|
||||
public int getPacketId() {
|
||||
return packetId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean setPacketId(int packetId) {
|
||||
synchronized (sendLock) {
|
||||
if (this.packetId == packetId) return false;
|
||||
|
||||
if (packetId >= 65536) {
|
||||
packetId = 0;
|
||||
generationId++;
|
||||
} else {
|
||||
this.packetId = packetId;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
public int getGenerationId() {
|
||||
return generationId;
|
||||
}
|
||||
@@ -723,13 +790,7 @@ public abstract class AbstractTeamspeakClientSocket
|
||||
@Override
|
||||
public Pair<Integer, Integer> next() {
|
||||
synchronized (sendLock) {
|
||||
packetId++;
|
||||
|
||||
if (packetId >= 65536) {
|
||||
packetId = 0;
|
||||
generationId++;
|
||||
}
|
||||
|
||||
setPacketId(packetId + 1);
|
||||
return new Pair<>(packetId, generationId);
|
||||
}
|
||||
}
|
||||
@@ -781,6 +842,8 @@ public abstract class AbstractTeamspeakClientSocket
|
||||
}
|
||||
|
||||
public Packet put(Packet packet) {
|
||||
Packet reassembled;
|
||||
|
||||
if (packet.getHeader().getPacketFlag(HeaderFlag.FRAGMENTED)) {
|
||||
boolean oldState = state;
|
||||
|
||||
@@ -791,19 +854,22 @@ public abstract class AbstractTeamspeakClientSocket
|
||||
|
||||
queue.put(packet.getHeader().getPacketId(), packet);
|
||||
|
||||
if (oldState)
|
||||
return reassemble(packet);
|
||||
|
||||
return null;
|
||||
if (oldState) {
|
||||
reassembled = reassemble(packet);
|
||||
} else {
|
||||
reassembled = null;
|
||||
}
|
||||
} else {
|
||||
if (state) {
|
||||
queue.put(packet.getHeader().getPacketId(), packet);
|
||||
|
||||
return null;
|
||||
reassembled = null;
|
||||
} else {
|
||||
return packet;
|
||||
reassembled = packet;
|
||||
}
|
||||
}
|
||||
|
||||
return reassembled;
|
||||
}
|
||||
|
||||
public boolean isReassembling() {
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package com.github.manevolent.ts3j;
|
||||
|
||||
import com.github.manevolent.ts3j.identity.LocalIdentity;
|
||||
import com.github.manevolent.ts3j.util.Ts3Crypt;
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import java.math.BigInteger;
|
||||
@@ -26,7 +25,7 @@ public class ClientUidGenerationTest extends TestCase {
|
||||
assertEquals("MEsDAgcAAgEgAiBpPRbTliVt9KxtIz8saYdwcnNgcwaKLb" +
|
||||
"KYSpDNO87u9gIgSWWPKcSJ9P6VZKJfRdpWwcfMdJv+NA9/hXUtz1uwRVI=", keyPair.getPublicKeyString());
|
||||
|
||||
assertEquals("27QHSPRzQe+enxh56eUokkLmsFg=", keyPair.getFingerprint());
|
||||
assertEquals("27QHSPRzQe+enxh56eUokkLmsFg=", keyPair.getUid().toBase64());
|
||||
|
||||
assertEquals(
|
||||
"MEsDAgcAAgEgAiBpPRbTliVt9KxtIz8saYdwcnNgcwaKLbKY" +
|
||||
|
||||
@@ -1,27 +1,24 @@
|
||||
package com.github.manevolent.ts3j;
|
||||
|
||||
import com.github.manevolent.ts3j.identity.LocalIdentity;
|
||||
import com.github.manevolent.ts3j.model.Channel;
|
||||
import com.github.manevolent.ts3j.protocol.client.ClientConnectionState;
|
||||
import com.github.manevolent.ts3j.protocol.socket.client.LocalTeamspeakClientSocket;
|
||||
import com.github.manevolent.ts3j.util.Ts3Crypt;
|
||||
import com.github.manevolent.ts3j.util.Ts3Debugging;
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import java.math.BigInteger;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.util.Base64;
|
||||
import java.util.Collections;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
public class ServerConnectionTest {
|
||||
public static void main(String[] args) throws Exception {
|
||||
try {
|
||||
/**LocalIdentity localIdentity = LocalIdentity.load(
|
||||
Ts3Crypt.decodePublicKey(Base64.getDecoder()
|
||||
.decode("MEsDAgcAAgEgAiBpPRbTliVt9KxtIz8saYdwcnNgcwaKLbKYSpDNO87u9gIgSWWPKcSJ9P6VZKJfRdpWwcfMdJv+NA9/hXUtz1uwRVI=")),
|
||||
new BigInteger(Base64.getDecoder().decode("Tj6YXM3qyRv8n25L2pH+OEJnRUl4auQf8+znjYrOmWU=")),
|
||||
2294,
|
||||
2295
|
||||
);**/
|
||||
LocalIdentity localIdentity = LocalIdentity.generateNew(10);
|
||||
|
||||
LocalTeamspeakClientSocket client = new LocalTeamspeakClientSocket();
|
||||
@@ -40,6 +37,13 @@ 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())
|
||||
);
|
||||
} catch (Throwable ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user