Reconnection works now
This commit is contained in:
+7
-1
@@ -26,6 +26,7 @@ import com.github.manevolent.ts3j.util.Ts3Debugging;
|
|||||||
import com.github.manevolent.ts3j.util.Pair;
|
import com.github.manevolent.ts3j.util.Pair;
|
||||||
import org.bouncycastle.crypto.InvalidCipherTextException;
|
import org.bouncycastle.crypto.InvalidCipherTextException;
|
||||||
|
|
||||||
|
import java.io.EOFException;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.net.DatagramPacket;
|
import java.net.DatagramPacket;
|
||||||
import java.net.SocketTimeoutException;
|
import java.net.SocketTimeoutException;
|
||||||
@@ -225,6 +226,8 @@ public abstract class AbstractTeamspeakClientSocket
|
|||||||
for (PacketKind kind : PacketKind.values()) {
|
for (PacketKind kind : PacketKind.values()) {
|
||||||
packetStatistics.put(kind, new PacketStatistics());
|
packetStatistics.put(kind, new PacketStatistics());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
setTransformation(new InitPacketTransformation());
|
||||||
}
|
}
|
||||||
|
|
||||||
public ClientConnectionState getState() {
|
public ClientConnectionState getState() {
|
||||||
@@ -762,7 +765,7 @@ public abstract class AbstractTeamspeakClientSocket
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
throw new IllegalStateException("no longer reading");
|
throw new EOFException();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -900,6 +903,8 @@ public abstract class AbstractTeamspeakClientSocket
|
|||||||
while (isReading()) {
|
while (isReading()) {
|
||||||
try {
|
try {
|
||||||
readQueue.put(readPacket());
|
readQueue.put(readPacket());
|
||||||
|
} catch (EOFException e) {
|
||||||
|
break;
|
||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
if (e instanceof InterruptedException) {
|
if (e instanceof InterruptedException) {
|
||||||
Thread.yield();
|
Thread.yield();
|
||||||
@@ -912,6 +917,7 @@ public abstract class AbstractTeamspeakClientSocket
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
if (getState() != ClientConnectionState.DISCONNECTED)
|
||||||
setState(ClientConnectionState.DISCONNECTED);
|
setState(ClientConnectionState.DISCONNECTED);
|
||||||
} catch (Throwable e1) {
|
} catch (Throwable e1) {
|
||||||
exceptionHandler.accept(e1);
|
exceptionHandler.accept(e1);
|
||||||
|
|||||||
+49
-15
@@ -24,6 +24,7 @@ import com.github.manevolent.ts3j.util.HighPrecisionRecurrentTask;
|
|||||||
import com.github.manevolent.ts3j.util.Ts3Debugging;
|
import com.github.manevolent.ts3j.util.Ts3Debugging;
|
||||||
import com.github.manevolent.ts3j.util.Pair;
|
import com.github.manevolent.ts3j.util.Pair;
|
||||||
|
|
||||||
|
import java.io.EOFException;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.net.*;
|
import java.net.*;
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
@@ -37,15 +38,7 @@ public class LocalTeamspeakClientSocket
|
|||||||
extends AbstractTeamspeakClientSocket
|
extends AbstractTeamspeakClientSocket
|
||||||
implements CommandProcessor {
|
implements CommandProcessor {
|
||||||
|
|
||||||
private final DatagramSocket socket;
|
private DatagramSocket socket;
|
||||||
|
|
||||||
{
|
|
||||||
try {
|
|
||||||
socket = new DatagramSocket();
|
|
||||||
} catch (SocketException e) {
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private final DatagramPacket packet = new DatagramPacket(new byte[500], 500);
|
private final DatagramPacket packet = new DatagramPacket(new byte[500], 500);
|
||||||
|
|
||||||
@@ -53,6 +46,7 @@ public class LocalTeamspeakClientSocket
|
|||||||
private final ExecutorService commandExecutionService = Executors.newCachedThreadPool();
|
private final ExecutorService commandExecutionService = Executors.newCachedThreadPool();
|
||||||
private final Object commandSendLock = new Object();
|
private final Object commandSendLock = new Object();
|
||||||
|
|
||||||
|
private volatile InetSocketAddress remote;
|
||||||
|
|
||||||
private Microphone microphone;
|
private Microphone microphone;
|
||||||
private Thread microphoneThread;
|
private Thread microphoneThread;
|
||||||
@@ -161,9 +155,23 @@ public class LocalTeamspeakClientSocket
|
|||||||
protected NetworkPacket readNetworkPacket(int timeout) throws
|
protected NetworkPacket readNetworkPacket(int timeout) throws
|
||||||
IOException,
|
IOException,
|
||||||
SocketTimeoutException {
|
SocketTimeoutException {
|
||||||
|
DatagramSocket socket = this.socket;
|
||||||
|
InetSocketAddress remote = this.remote;
|
||||||
|
|
||||||
|
while (socket.isBound()) {
|
||||||
socket.setSoTimeout(timeout);
|
socket.setSoTimeout(timeout);
|
||||||
|
|
||||||
|
try {
|
||||||
socket.receive(packet);
|
socket.receive(packet);
|
||||||
|
} catch (SocketException ex) {
|
||||||
|
if (socket.isClosed()) throw new EOFException();
|
||||||
|
else throw ex;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (remote == null || getState() == ClientConnectionState.DISCONNECTED)
|
||||||
|
break;
|
||||||
|
else if (!packet.getAddress().equals(remote.getAddress()) || packet.getPort() != remote.getPort())
|
||||||
|
continue;
|
||||||
|
|
||||||
PacketHeader header;
|
PacketHeader header;
|
||||||
|
|
||||||
@@ -191,12 +199,25 @@ public class LocalTeamspeakClientSocket
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
throw new IOException("disconnected");
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void writeNetworkPacket(NetworkPacket packet) throws IOException {
|
protected void writeNetworkPacket(NetworkPacket packet) throws IOException {
|
||||||
|
InetSocketAddress remote = this.remote;
|
||||||
|
ClientConnectionState state = this.getState();
|
||||||
|
|
||||||
|
if (state == ClientConnectionState.DISCONNECTED)
|
||||||
|
throw new IllegalStateException(state.name());
|
||||||
|
else if (remote == null)
|
||||||
|
throw new IOException(new NullPointerException("remote"));
|
||||||
|
|
||||||
Ts3Debugging.debug("[NETWORK] WRITE id=" + packet.getHeader().getPacketId() + " len=" +
|
Ts3Debugging.debug("[NETWORK] WRITE id=" + packet.getHeader().getPacketId() + " len=" +
|
||||||
packet.getDatagram().getLength()
|
packet.getDatagram().getLength()
|
||||||
+ " to " +
|
+ " to " +
|
||||||
socket.getRemoteSocketAddress());
|
remote.toString());
|
||||||
|
|
||||||
|
packet.getDatagram().setSocketAddress(remote);
|
||||||
|
|
||||||
socket.send(packet.getDatagram());
|
socket.send(packet.getDatagram());
|
||||||
}
|
}
|
||||||
@@ -227,6 +248,8 @@ public class LocalTeamspeakClientSocket
|
|||||||
}
|
}
|
||||||
|
|
||||||
serverId = null;
|
serverId = null;
|
||||||
|
|
||||||
|
remote = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -239,15 +262,22 @@ public class LocalTeamspeakClientSocket
|
|||||||
public void connect(InetSocketAddress remote, String password, long timeout)
|
public void connect(InetSocketAddress remote, String password, long timeout)
|
||||||
throws IOException, TimeoutException {
|
throws IOException, TimeoutException {
|
||||||
try {
|
try {
|
||||||
Ts3Debugging.debug("Connecting to " + remote + "...");
|
|
||||||
|
|
||||||
ClientConnectionState connectionState = getState();
|
ClientConnectionState connectionState = getState();
|
||||||
|
|
||||||
if (connectionState != ClientConnectionState.DISCONNECTED)
|
if (connectionState != ClientConnectionState.DISCONNECTED)
|
||||||
throw new IllegalStateException(connectionState.name());
|
throw new IllegalStateException(connectionState.name());
|
||||||
|
|
||||||
|
Ts3Debugging.debug("Connecting to " + remote + "...");
|
||||||
|
|
||||||
setClientId(0);
|
setClientId(0);
|
||||||
|
|
||||||
|
if (remote.isUnresolved())
|
||||||
|
remote = new InetSocketAddress(remote.getAddress().getHostAddress(), remote.getPort());
|
||||||
|
|
||||||
|
if (socket != null) socket.close();
|
||||||
|
socket = new DatagramSocket();
|
||||||
|
|
||||||
|
this.remote = remote;
|
||||||
serverId = null;
|
serverId = null;
|
||||||
awaitingCommands.clear();
|
awaitingCommands.clear();
|
||||||
acceptingReturnCode = 0;
|
acceptingReturnCode = 0;
|
||||||
@@ -256,8 +286,6 @@ public class LocalTeamspeakClientSocket
|
|||||||
|
|
||||||
if (password != null) setOption("client.password", password);
|
if (password != null) setOption("client.password", password);
|
||||||
|
|
||||||
socket.connect(remote);
|
|
||||||
|
|
||||||
setState(ClientConnectionState.CONNECTING);
|
setState(ClientConnectionState.CONNECTING);
|
||||||
|
|
||||||
waitForState(ClientConnectionState.CONNECTED, timeout);
|
waitForState(ClientConnectionState.CONNECTED, timeout);
|
||||||
@@ -282,7 +310,7 @@ public class LocalTeamspeakClientSocket
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected boolean isReading() {
|
protected boolean isReading() {
|
||||||
return socket.isConnected();
|
return super.isReading();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -931,6 +959,7 @@ public class LocalTeamspeakClientSocket
|
|||||||
throws
|
throws
|
||||||
IOException, TimeoutException,
|
IOException, TimeoutException,
|
||||||
ExecutionException, InterruptedException {
|
ExecutionException, InterruptedException {
|
||||||
|
try {
|
||||||
switch (getState()) {
|
switch (getState()) {
|
||||||
case CONNECTING:
|
case CONNECTING:
|
||||||
case RETRIEVING_DATA:
|
case RETRIEVING_DATA:
|
||||||
@@ -941,8 +970,13 @@ public class LocalTeamspeakClientSocket
|
|||||||
new SingleCommand("clientdisconnect", ProtocolRole.CLIENT))
|
new SingleCommand("clientdisconnect", ProtocolRole.CLIENT))
|
||||||
);
|
);
|
||||||
|
|
||||||
|
waitForState(ClientConnectionState.DISCONNECTED, 30000L);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
} finally {
|
||||||
|
setState(ClientConnectionState.DISCONNECTED);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,8 +17,9 @@ import static org.junit.Assert.assertEquals;
|
|||||||
|
|
||||||
public class ServerConnectionTest {
|
public class ServerConnectionTest {
|
||||||
public static void main(String[] args) throws Exception {
|
public static void main(String[] args) throws Exception {
|
||||||
while (true) {
|
|
||||||
try {
|
LocalTeamspeakClientSocket client = new LocalTeamspeakClientSocket();
|
||||||
|
|
||||||
Ts3Debugging.setEnabled(true);
|
Ts3Debugging.setEnabled(true);
|
||||||
|
|
||||||
LocalIdentity identity = LocalIdentity.load(
|
LocalIdentity identity = LocalIdentity.load(
|
||||||
@@ -26,9 +27,8 @@ public class ServerConnectionTest {
|
|||||||
);
|
);
|
||||||
|
|
||||||
identity.improveSecurity(10);
|
identity.improveSecurity(10);
|
||||||
|
while (true) {
|
||||||
LocalTeamspeakClientSocket client = new LocalTeamspeakClientSocket();
|
try {
|
||||||
|
|
||||||
client.setIdentity(identity);
|
client.setIdentity(identity);
|
||||||
|
|
||||||
client.setNickname("Hello from Java");
|
client.setNickname("Hello from Java");
|
||||||
|
|||||||
Reference in New Issue
Block a user