Command processing started
This commit is contained in:
@@ -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 {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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;
|
||||||
|
}
|
||||||
@@ -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<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);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -64,31 +64,6 @@ public class SimpleCommand implements Command {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static SimpleCommand parse(ProtocolRole role, String commandText) {
|
public static SimpleCommand parse(ProtocolRole role, String commandText) {
|
||||||
String[] commandParts = commandText.split(" ");
|
return ComplexCommand.parse(role, commandText).simplify();
|
||||||
|
|
||||||
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 SimpleCommand(commandLabel, role, parameterList);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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.PacketHandler;
|
||||||
import com.github.manevolent.ts3j.protocol.packet.handler.local.*;
|
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 com.github.manevolent.ts3j.protocol.socket.client.TeamspeakClientSocket;
|
||||||
import org.apache.commons.lang.reflect.ConstructorUtils;
|
import org.apache.commons.lang.reflect.ConstructorUtils;
|
||||||
|
|
||||||
public enum ClientConnectionState {
|
public enum ClientConnectionState {
|
||||||
CONNECTING(LocalClientHandlerConnecting.class),
|
CONNECTING(LocalClientHandlerConnecting.class),
|
||||||
NEGOTIATING(LocalClientHandlerNegotiating.class),
|
RETRIEVING_DATA(LocalClientHandlerRetrievingData.class),
|
||||||
CONNECTED(LocalClientHandlerConnected.class),
|
CONNECTED(LocalClientHandlerConnected.class),
|
||||||
DISCONNECTED(LocalClientHandlerDisconnected.class);
|
DISCONNECTED(LocalClientHandlerDisconnected.class);
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package com.github.manevolent.ts3j.protocol.packet;
|
package com.github.manevolent.ts3j.protocol.packet;
|
||||||
|
|
||||||
import com.github.manevolent.ts3j.command.Command;
|
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.SimpleCommand;
|
||||||
import com.github.manevolent.ts3j.protocol.ProtocolRole;
|
import com.github.manevolent.ts3j.protocol.ProtocolRole;
|
||||||
|
|
||||||
@@ -28,8 +29,8 @@ public class PacketBody2Command extends PacketBody {
|
|||||||
return text;
|
return text;
|
||||||
}
|
}
|
||||||
|
|
||||||
public SimpleCommand parse() {
|
public ComplexCommand parse() {
|
||||||
return SimpleCommand.parse(getRole(), getText());
|
return ComplexCommand.parse(getRole(), getText());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setText(String text) {
|
public void setText(String text) {
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package com.github.manevolent.ts3j.protocol.packet.handler;
|
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.Packet;
|
||||||
import com.github.manevolent.ts3j.protocol.socket.client.TeamspeakClientSocket;
|
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() {
|
public TeamspeakClientSocket getClient() {
|
||||||
return clientSocket;
|
return clientSocket;
|
||||||
}
|
}
|
||||||
|
|||||||
+5
@@ -1,10 +1,15 @@
|
|||||||
package com.github.manevolent.ts3j.protocol.packet.handler.local;
|
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.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.packet.handler.PacketHandler;
|
||||||
import com.github.manevolent.ts3j.protocol.socket.client.LocalTeamspeakClientSocket;
|
import com.github.manevolent.ts3j.protocol.socket.client.LocalTeamspeakClientSocket;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.concurrent.TimeoutException;
|
||||||
|
|
||||||
public abstract class LocalClientHandler extends PacketHandler {
|
public abstract class LocalClientHandler extends PacketHandler {
|
||||||
private final LocalTeamspeakClientSocket client;
|
private final LocalTeamspeakClientSocket client;
|
||||||
|
|
||||||
|
|||||||
+7
-1
@@ -1,9 +1,15 @@
|
|||||||
package com.github.manevolent.ts3j.protocol.packet.handler.local;
|
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 com.github.manevolent.ts3j.protocol.socket.client.LocalTeamspeakClientSocket;
|
||||||
|
|
||||||
public class LocalClientHandlerConnected extends LocalClientHandler {
|
public class LocalClientHandlerConnected extends LocalClientHandlerFull {
|
||||||
public LocalClientHandlerConnected(LocalTeamspeakClientSocket client) {
|
public LocalClientHandlerConnected(LocalTeamspeakClientSocket client) {
|
||||||
super(client);
|
super(client);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void handleCommand(ComplexCommand command) {
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-2
@@ -141,7 +141,7 @@ public class LocalClientHandlerConnecting extends LocalClientHandler {
|
|||||||
|
|
||||||
}
|
}
|
||||||
} else if (packet.getBody() instanceof PacketBody2Command) {
|
} else if (packet.getBody() instanceof PacketBody2Command) {
|
||||||
SimpleCommand command = ((PacketBody2Command) packet.getBody()).parse();
|
SimpleCommand command = ((PacketBody2Command) packet.getBody()).parse().simplify();
|
||||||
|
|
||||||
if (command.getName().equalsIgnoreCase("initivexpand2")) {
|
if (command.getName().equalsIgnoreCase("initivexpand2")) {
|
||||||
// 3.2.2 initivexpand2 (Client <- Server)
|
// 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")) {
|
} else if (command.getName().equals("error")) {
|
||||||
getClient().setState(ClientConnectionState.DISCONNECTED);
|
getClient().setState(ClientConnectionState.DISCONNECTED);
|
||||||
|
|
||||||
|
|||||||
+32
@@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+4
-3
@@ -1,17 +1,18 @@
|
|||||||
package com.github.manevolent.ts3j.protocol.packet.handler.local;
|
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 com.github.manevolent.ts3j.protocol.socket.client.LocalTeamspeakClientSocket;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.concurrent.TimeoutException;
|
import java.util.concurrent.TimeoutException;
|
||||||
|
|
||||||
public class LocalClientHandlerNegotiating extends LocalClientHandler {
|
public class LocalClientHandlerRetrievingData extends LocalClientHandlerFull {
|
||||||
public LocalClientHandlerNegotiating(LocalTeamspeakClientSocket client) {
|
public LocalClientHandlerRetrievingData(LocalTeamspeakClientSocket client) {
|
||||||
super(client);
|
super(client);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onAssigned() throws IOException, TimeoutException {
|
protected void handleCommand(ComplexCommand command) {
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+11
@@ -1,6 +1,7 @@
|
|||||||
package com.github.manevolent.ts3j.protocol.socket.client;
|
package com.github.manevolent.ts3j.protocol.socket.client;
|
||||||
|
|
||||||
import com.github.manevolent.ts3j.command.Command;
|
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.command.response.CommandResponse;
|
||||||
import com.github.manevolent.ts3j.identity.Identity;
|
import com.github.manevolent.ts3j.identity.Identity;
|
||||||
import com.github.manevolent.ts3j.protocol.NetworkPacket;
|
import com.github.manevolent.ts3j.protocol.NetworkPacket;
|
||||||
@@ -41,6 +42,8 @@ public abstract class AbstractTeamspeakClientSocket
|
|||||||
private final Map<String, Object> clientOptions = new ConcurrentHashMap<>();
|
private final Map<String, Object> clientOptions = new ConcurrentHashMap<>();
|
||||||
private final Map<Integer, PacketResponse> sendQueue = new ConcurrentHashMap<>();
|
private final Map<Integer, PacketResponse> sendQueue = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
|
private CommandProcessor commandProcessor;
|
||||||
|
|
||||||
private Identity identity = null;
|
private Identity identity = null;
|
||||||
private ClientConnectionState connectionState = null;
|
private ClientConnectionState connectionState = null;
|
||||||
private PacketTransformation transformation = new DefaultPacketTransformation();
|
private PacketTransformation transformation = new DefaultPacketTransformation();
|
||||||
@@ -551,6 +554,14 @@ public abstract class AbstractTeamspeakClientSocket
|
|||||||
setOption("client.nickname", name);
|
setOption("client.nickname", name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public CommandProcessor getCommandProcessor() {
|
||||||
|
return commandProcessor;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCommandProcessor(CommandProcessor commandProcessor) {
|
||||||
|
this.commandProcessor = commandProcessor;
|
||||||
|
}
|
||||||
|
|
||||||
private class NetworkHandler implements Runnable {
|
private class NetworkHandler implements Runnable {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
|
|||||||
Reference in New Issue
Block a user