From ab4cb120101ad76379770023db09d4dad99f3dc3 Mon Sep 17 00:00:00 2001 From: Manevolent Date: Fri, 27 Jul 2018 16:30:49 -0400 Subject: [PATCH] Command processing started --- .../ts3j/command/CommandHandler.java | 11 +++ .../ts3j/command/CommandProcessException.java | 11 +++ .../ts3j/command/CommandProcessor.java | 8 ++ .../ts3j/command/ComplexCommand.java | 90 +++++++++++++++++++ .../ts3j/command/SimpleCommand.java | 27 +----- .../client/ClientConnectionState.java | 3 +- .../protocol/packet/PacketBody2Command.java | 5 +- .../packet/handler/PacketHandler.java | 5 ++ .../handler/local/LocalClientHandler.java | 5 ++ .../local/LocalClientHandlerConnected.java | 8 +- .../local/LocalClientHandlerConnecting.java | 4 +- .../handler/local/LocalClientHandlerFull.java | 32 +++++++ ... => LocalClientHandlerRetrievingData.java} | 7 +- .../client/AbstractTeamspeakClientSocket.java | 11 +++ 14 files changed, 191 insertions(+), 36 deletions(-) create mode 100644 src/main/java/com/github/manevolent/ts3j/command/CommandHandler.java create mode 100644 src/main/java/com/github/manevolent/ts3j/command/CommandProcessException.java create mode 100644 src/main/java/com/github/manevolent/ts3j/command/CommandProcessor.java create mode 100644 src/main/java/com/github/manevolent/ts3j/command/ComplexCommand.java create mode 100644 src/main/java/com/github/manevolent/ts3j/protocol/packet/handler/local/LocalClientHandlerFull.java rename src/main/java/com/github/manevolent/ts3j/protocol/packet/handler/local/{LocalClientHandlerNegotiating.java => LocalClientHandlerRetrievingData.java} (50%) diff --git a/src/main/java/com/github/manevolent/ts3j/command/CommandHandler.java b/src/main/java/com/github/manevolent/ts3j/command/CommandHandler.java new file mode 100644 index 0000000..b6f0a67 --- /dev/null +++ b/src/main/java/com/github/manevolent/ts3j/command/CommandHandler.java @@ -0,0 +1,11 @@ +package com.github.manevolent.ts3j.command; + +import com.github.manevolent.ts3j.protocol.socket.client.AbstractTeamspeakClientSocket; + +public final class CommandHandler implements CommandProcessor { + @Override + public void process(AbstractTeamspeakClientSocket socket, ComplexCommand complexCommand) + throws CommandProcessException { + + } +} diff --git a/src/main/java/com/github/manevolent/ts3j/command/CommandProcessException.java b/src/main/java/com/github/manevolent/ts3j/command/CommandProcessException.java new file mode 100644 index 0000000..0adb99a --- /dev/null +++ b/src/main/java/com/github/manevolent/ts3j/command/CommandProcessException.java @@ -0,0 +1,11 @@ +package com.github.manevolent.ts3j.command; + +public class CommandProcessException extends Exception { + public CommandProcessException(Exception cause) { + super(cause); + } + + public CommandProcessException(String message) { + super(message); + } +} diff --git a/src/main/java/com/github/manevolent/ts3j/command/CommandProcessor.java b/src/main/java/com/github/manevolent/ts3j/command/CommandProcessor.java new file mode 100644 index 0000000..cf931d3 --- /dev/null +++ b/src/main/java/com/github/manevolent/ts3j/command/CommandProcessor.java @@ -0,0 +1,8 @@ +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; +} diff --git a/src/main/java/com/github/manevolent/ts3j/command/ComplexCommand.java b/src/main/java/com/github/manevolent/ts3j/command/ComplexCommand.java new file mode 100644 index 0000000..0087dac --- /dev/null +++ b/src/main/java/com/github/manevolent/ts3j/command/ComplexCommand.java @@ -0,0 +1,90 @@ +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 params; + + public ComplexCommand(String name, ProtocolRole role, CommandParameter... params) { + this(name, role, Arrays.asList(params)); + } + + public ComplexCommand(String name, ProtocolRole role, List 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 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 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); + } +} diff --git a/src/main/java/com/github/manevolent/ts3j/command/SimpleCommand.java b/src/main/java/com/github/manevolent/ts3j/command/SimpleCommand.java index 6dbb0b3..3d95660 100644 --- a/src/main/java/com/github/manevolent/ts3j/command/SimpleCommand.java +++ b/src/main/java/com/github/manevolent/ts3j/command/SimpleCommand.java @@ -64,31 +64,6 @@ public class SimpleCommand implements Command { } public static SimpleCommand parse(ProtocolRole role, String commandText) { - String[] commandParts = commandText.split(" "); - - String commandLabel = commandParts[0].toLowerCase(); - - List 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 SimpleCommand(commandLabel, role, parameterList); + return ComplexCommand.parse(role, commandText).simplify(); } } 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 3e8ea2e..455f423 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 @@ -3,13 +3,12 @@ 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.socket.client.AbstractTeamspeakClientSocket; import com.github.manevolent.ts3j.protocol.socket.client.TeamspeakClientSocket; import org.apache.commons.lang.reflect.ConstructorUtils; public enum ClientConnectionState { CONNECTING(LocalClientHandlerConnecting.class), - NEGOTIATING(LocalClientHandlerNegotiating.class), + RETRIEVING_DATA(LocalClientHandlerRetrievingData.class), CONNECTED(LocalClientHandlerConnected.class), DISCONNECTED(LocalClientHandlerDisconnected.class); diff --git a/src/main/java/com/github/manevolent/ts3j/protocol/packet/PacketBody2Command.java b/src/main/java/com/github/manevolent/ts3j/protocol/packet/PacketBody2Command.java index e47f9e9..142de7e 100644 --- a/src/main/java/com/github/manevolent/ts3j/protocol/packet/PacketBody2Command.java +++ b/src/main/java/com/github/manevolent/ts3j/protocol/packet/PacketBody2Command.java @@ -1,6 +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.protocol.ProtocolRole; @@ -28,8 +29,8 @@ public class PacketBody2Command extends PacketBody { return text; } - public SimpleCommand parse() { - return SimpleCommand.parse(getRole(), getText()); + public ComplexCommand parse() { + return ComplexCommand.parse(getRole(), getText()); } public void setText(String text) { 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 10ff149..460b965 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 @@ -1,5 +1,6 @@ package com.github.manevolent.ts3j.protocol.packet.handler; +import com.github.manevolent.ts3j.command.Command; import com.github.manevolent.ts3j.protocol.Packet; import com.github.manevolent.ts3j.protocol.socket.client.TeamspeakClientSocket; @@ -25,6 +26,10 @@ 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/local/LocalClientHandler.java index 3dd883a..c3d4697 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/local/LocalClientHandler.java @@ -1,10 +1,15 @@ package com.github.manevolent.ts3j.protocol.packet.handler.local; +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/local/LocalClientHandlerConnected.java index 3d2d9a1..0a59ff6 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/local/LocalClientHandlerConnected.java @@ -1,9 +1,15 @@ package com.github.manevolent.ts3j.protocol.packet.handler.local; +import com.github.manevolent.ts3j.command.ComplexCommand; import com.github.manevolent.ts3j.protocol.socket.client.LocalTeamspeakClientSocket; -public class LocalClientHandlerConnected extends LocalClientHandler { +public class LocalClientHandlerConnected extends LocalClientHandlerFull { public LocalClientHandlerConnected(LocalTeamspeakClientSocket client) { super(client); } + + @Override + protected void handleCommand(ComplexCommand command) { + + } } 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/local/LocalClientHandlerConnecting.java index 14b522f..a50b1e6 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/local/LocalClientHandlerConnecting.java @@ -141,7 +141,7 @@ public class LocalClientHandlerConnecting extends LocalClientHandler { } } else if (packet.getBody() instanceof PacketBody2Command) { - SimpleCommand command = ((PacketBody2Command) packet.getBody()).parse(); + SimpleCommand command = ((PacketBody2Command) packet.getBody()).parse().simplify(); if (command.getName().equalsIgnoreCase("initivexpand2")) { // 3.2.2 initivexpand2 (Client <- Server) @@ -228,7 +228,7 @@ public class LocalClientHandlerConnecting extends LocalClientHandler { ) ); - getClient().setState(ClientConnectionState.CONNECTED); + 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/LocalClientHandlerFull.java b/src/main/java/com/github/manevolent/ts3j/protocol/packet/handler/local/LocalClientHandlerFull.java new file mode 100644 index 0000000..c5dc4d2 --- /dev/null +++ b/src/main/java/com/github/manevolent/ts3j/protocol/packet/handler/local/LocalClientHandlerFull.java @@ -0,0 +1,32 @@ +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.protocol.Packet; +import com.github.manevolent.ts3j.protocol.packet.PacketBody2Command; +import com.github.manevolent.ts3j.protocol.socket.client.LocalTeamspeakClientSocket; + +import java.io.IOException; +import java.util.concurrent.TimeoutException; + +public abstract class LocalClientHandlerFull extends LocalClientHandler { + protected LocalClientHandlerFull(LocalTeamspeakClientSocket client) { + super(client); + } + + protected void handleCommand(ComplexCommand command) throws CommandProcessException { + CommandProcessor processor = getClient().getCommandProcessor(); + if (processor != null) processor.process(getClient(), command); + } + + @Override + public void handlePacket(Packet packet) throws IOException, TimeoutException { + if (packet.getBody() instanceof PacketBody2Command) + try { + handleCommand(ComplexCommand.parse(packet.getRole(), ((PacketBody2Command) packet.getBody()).getText())); + } catch (CommandProcessException e) { + throw new IOException(e); + } + } +} diff --git a/src/main/java/com/github/manevolent/ts3j/protocol/packet/handler/local/LocalClientHandlerNegotiating.java b/src/main/java/com/github/manevolent/ts3j/protocol/packet/handler/local/LocalClientHandlerRetrievingData.java similarity index 50% rename from src/main/java/com/github/manevolent/ts3j/protocol/packet/handler/local/LocalClientHandlerNegotiating.java rename to src/main/java/com/github/manevolent/ts3j/protocol/packet/handler/local/LocalClientHandlerRetrievingData.java index 57bd4bf..fbbdf47 100644 --- a/src/main/java/com/github/manevolent/ts3j/protocol/packet/handler/local/LocalClientHandlerNegotiating.java +++ b/src/main/java/com/github/manevolent/ts3j/protocol/packet/handler/local/LocalClientHandlerRetrievingData.java @@ -1,17 +1,18 @@ package com.github.manevolent.ts3j.protocol.packet.handler.local; +import com.github.manevolent.ts3j.command.ComplexCommand; import com.github.manevolent.ts3j.protocol.socket.client.LocalTeamspeakClientSocket; import java.io.IOException; import java.util.concurrent.TimeoutException; -public class LocalClientHandlerNegotiating extends LocalClientHandler { - public LocalClientHandlerNegotiating(LocalTeamspeakClientSocket client) { +public class LocalClientHandlerRetrievingData extends LocalClientHandlerFull { + public LocalClientHandlerRetrievingData(LocalTeamspeakClientSocket client) { super(client); } @Override - public void onAssigned() throws IOException, TimeoutException { + protected void handleCommand(ComplexCommand command) { } } 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 9d99af4..eb1f51f 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,6 +1,7 @@ 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.response.CommandResponse; import com.github.manevolent.ts3j.identity.Identity; import com.github.manevolent.ts3j.protocol.NetworkPacket; @@ -41,6 +42,8 @@ public abstract class AbstractTeamspeakClientSocket private final Map clientOptions = new ConcurrentHashMap<>(); private final Map sendQueue = new ConcurrentHashMap<>(); + private CommandProcessor commandProcessor; + private Identity identity = null; private ClientConnectionState connectionState = null; private PacketTransformation transformation = new DefaultPacketTransformation(); @@ -551,6 +554,14 @@ public abstract class AbstractTeamspeakClientSocket setOption("client.nickname", name); } + public CommandProcessor getCommandProcessor() { + return commandProcessor; + } + + public void setCommandProcessor(CommandProcessor commandProcessor) { + this.commandProcessor = commandProcessor; + } + private class NetworkHandler implements Runnable { @Override public void run() {