mirror of
https://github.com/Maschell/HIDtoVPADNetworkClient.git
synced 2024-11-22 14:09:17 +01:00
Improved the reconnecting and fixes some issues about the connection.
This should be pretty stable now =) Code is not really beautiful atm, but better commit it before I break it again!
This commit is contained in:
parent
3918a71627
commit
a479bb14ee
@ -44,6 +44,7 @@ public class GuiInputControls extends JPanel implements ActionListener {
|
||||
|
||||
private static final String CONNECT = "Connect";
|
||||
private static final String DISCONNECT = "Disconnect";
|
||||
private static final String RECONNECTING = "Reconnecting";
|
||||
|
||||
private JButton connectButton;
|
||||
private JTextField ipTextBox;
|
||||
@ -93,10 +94,15 @@ public class GuiInputControls extends JPanel implements ActionListener {
|
||||
int delay = 100; //milliseconds
|
||||
ActionListener taskPerformer = new ActionListener() {
|
||||
public void actionPerformed(ActionEvent evt) {
|
||||
if(NetworkManager.getInstance().isConnected()){
|
||||
if(NetworkManager.getInstance().isReconnecting()){
|
||||
connectButton.setText(RECONNECTING);
|
||||
connectButton.setEnabled(false);
|
||||
}else if(NetworkManager.getInstance().isConnected()){
|
||||
connectButton.setText(DISCONNECT);
|
||||
connectButton.setEnabled(true);
|
||||
}else{
|
||||
connectButton.setText(CONNECT);
|
||||
connectButton.setEnabled(true);
|
||||
}
|
||||
}
|
||||
};
|
||||
@ -127,10 +133,14 @@ public class GuiInputControls extends JPanel implements ActionListener {
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
SwingUtilities.invokeLater(new Runnable() {
|
||||
public void run() {
|
||||
if(NetworkManager.getInstance().isConnected()){
|
||||
NetworkManager.getInstance().disconnect();
|
||||
}else{
|
||||
NetworkManager.getInstance().connect(ipTextBox.getText());
|
||||
if(NetworkManager.getInstance().isReconnecting()){
|
||||
|
||||
}else{
|
||||
if(NetworkManager.getInstance().isConnected()){
|
||||
NetworkManager.getInstance().disconnect();
|
||||
}else{
|
||||
NetworkManager.getInstance().connect(ipTextBox.getText());
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
@ -129,4 +129,13 @@ public class ActiveControllerManager implements Runnable{
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void attachAllActiveControllers() {
|
||||
synchronized (activeControllers) {
|
||||
for(Entry<Controller, NetworkHIDDevice> entry : activeControllers.entrySet()){
|
||||
NetworkHIDDevice device = entry.getValue();
|
||||
device.sendAttach();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -65,7 +65,10 @@ public class ControllerManager{
|
||||
connectedDevices.putAll(detectWindowsControllers());
|
||||
}
|
||||
|
||||
//TODO: Enable HID4Java again
|
||||
/*TODO: Enable HID4Java again. Currently it's disabled because
|
||||
* We can either use the WiiU directly OR have XInput anyway.
|
||||
* Adding an option menu for enabling it?
|
||||
*/
|
||||
//connectedDevices.putAll(detectHIDDevices());
|
||||
|
||||
//Remove detached devices
|
||||
@ -100,9 +103,15 @@ public class ControllerManager{
|
||||
//e.printStackTrace();
|
||||
}
|
||||
break;
|
||||
/*
|
||||
* TODO:
|
||||
* Currently the XInput will be set active automatically.
|
||||
* But this should move to something for the settings?
|
||||
*/
|
||||
case XINPUT14:
|
||||
try {
|
||||
c = new XInput14Controller(deviceIdentifier);
|
||||
c.setActive(true);
|
||||
} catch (ControllerInitializationFailedException e) {
|
||||
//e.printStackTrace();
|
||||
}
|
||||
@ -110,6 +119,7 @@ public class ControllerManager{
|
||||
case XINPUT13:
|
||||
try {
|
||||
c = new XInput13Controller(deviceIdentifier);
|
||||
c.setActive(true);
|
||||
} catch (ControllerInitializationFailedException e) {
|
||||
//e.printStackTrace();
|
||||
}
|
||||
|
@ -44,6 +44,9 @@ public class NetworkManager implements Runnable{
|
||||
private UDPClient udpClient = null;
|
||||
|
||||
private static NetworkManager instance = null;
|
||||
|
||||
private List<DeviceCommand> ownCommands = new ArrayList<>();
|
||||
|
||||
private NetworkManager() {
|
||||
|
||||
}
|
||||
@ -80,8 +83,8 @@ public class NetworkManager implements Runnable{
|
||||
int i = 0;
|
||||
while(true){
|
||||
proccessCommands();
|
||||
Utilities.sleep(10);
|
||||
if(i++ > 1000/10){
|
||||
Utilities.sleep(10);//TODO: move magic value to Settings
|
||||
if(i++ > 1000/10){//TODO: move magic value to Settings
|
||||
ping();
|
||||
i = 0;
|
||||
}
|
||||
@ -89,11 +92,13 @@ public class NetworkManager implements Runnable{
|
||||
}
|
||||
|
||||
private void ping() {
|
||||
if(isConnected())sendingCommand(new PingCommand());
|
||||
if(isConnected() || tcpClient.isShouldRetry())sendingCommand(new PingCommand());
|
||||
}
|
||||
|
||||
|
||||
public void proccessCommands(){
|
||||
List<DeviceCommand> commands = new ArrayList<>();
|
||||
commands.addAll(ownCommands); //TODO: Does this need a synchronized block? It _should_ be only access from this thread. Need to think about it
|
||||
ownCommands.clear();
|
||||
synchronized (toRemove) {
|
||||
synchronized (devices) {
|
||||
for(NetworkHIDDevice device : getDevices()){
|
||||
@ -135,15 +140,30 @@ public class NetworkManager implements Runnable{
|
||||
}
|
||||
|
||||
private void sendingCommand(DeviceCommand command) {
|
||||
if(command instanceof AttachCommand){
|
||||
sendAttach((AttachCommand) command);
|
||||
}else if(command instanceof DetachCommand){
|
||||
sendDetach((DetachCommand) command);
|
||||
}else if(command instanceof PingCommand){
|
||||
sendPing((PingCommand) command);
|
||||
boolean result = false;
|
||||
if(isConnected() || tcpClient.isShouldRetry()){
|
||||
if(command instanceof AttachCommand){
|
||||
result = sendAttach((AttachCommand) command);
|
||||
}else if(command instanceof DetachCommand){
|
||||
result = sendDetach((DetachCommand) command);
|
||||
}else if(command instanceof PingCommand){
|
||||
sendPing((PingCommand) command);
|
||||
result = true;
|
||||
}else{
|
||||
log.info("UNKNOWN COMMAND!");
|
||||
result = true;
|
||||
}
|
||||
}else{
|
||||
Utilities.sleep(500); //TODO: move magic value to Settings
|
||||
}
|
||||
|
||||
//Add the command again on errors
|
||||
if(!result){
|
||||
addCommand(command);
|
||||
}
|
||||
}
|
||||
|
||||
//TODO: PONG from WiiU? Hey Quark ;)
|
||||
private void sendPing(PingCommand command) {
|
||||
if(sendTCP(Protocol.getRawPingDataToSend(command))){
|
||||
log.info("PING");
|
||||
@ -152,27 +172,32 @@ public class NetworkManager implements Runnable{
|
||||
}
|
||||
}
|
||||
|
||||
private void sendDetach(DetachCommand command) {
|
||||
private boolean sendDetach(DetachCommand command) {
|
||||
byte[] sendData;
|
||||
try {
|
||||
sendData = Protocol.getRawDetachDataToSend(command);
|
||||
if(!sendTCP(sendData)){
|
||||
if(sendTCP(sendData)){
|
||||
log.info("Success detach command for device (" + command.getSender() + ") sent!");
|
||||
}else{
|
||||
log.info("Sending the detach command for device (" + command.getSender() + ") failed. sendTCP failed");
|
||||
return false;
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private void sendAttach(AttachCommand command) {
|
||||
//TODO: Maybe move it into the Protocol class?
|
||||
private boolean sendAttach(AttachCommand command) {
|
||||
//Send the TCP command
|
||||
byte[] sendData = null;
|
||||
try {
|
||||
sendData = Protocol.getRawAttachDataToSend(command);
|
||||
}catch (IOException e) {
|
||||
log.info("Building the attach command for device (" + command.getSender() + ") failed." + e.getMessage());
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
if(sendTCP(sendData)){
|
||||
byte configFound = 0;
|
||||
@ -182,13 +207,14 @@ public class NetworkManager implements Runnable{
|
||||
e1.printStackTrace();
|
||||
}
|
||||
if(configFound == Protocol.TCP_CMD_ATTACH_CONFIG_FOUND){
|
||||
log.info("Config on the console found!");
|
||||
//log.info("Config on the console found!");
|
||||
}else if(configFound == Protocol.TCP_CMD_ATTACH_CONFIG_NOT_FOUND){
|
||||
log.info("NO CONFIG FOUND.");
|
||||
return;
|
||||
return false;
|
||||
}else if (configFound == 0){
|
||||
log.info("Failed to get byte.");
|
||||
disconnect();
|
||||
return false;
|
||||
}
|
||||
|
||||
byte userDataOkay = 0;
|
||||
@ -198,13 +224,14 @@ public class NetworkManager implements Runnable{
|
||||
e1.printStackTrace();
|
||||
}
|
||||
if(userDataOkay == Protocol.TCP_CMD_ATTACH_USERDATA_OKAY){
|
||||
log.info("userdata okay!");
|
||||
//log.info("userdata okay!");
|
||||
}else if(userDataOkay == Protocol.TCP_CMD_ATTACH_USERDATA_BAD){
|
||||
log.info("USERDATA BAD.");
|
||||
return;
|
||||
return false;
|
||||
}else if (userDataOkay == 0){
|
||||
log.info("Failed to get byte.");
|
||||
disconnect();
|
||||
return false;
|
||||
}
|
||||
|
||||
//We receive our device slot and pad slot
|
||||
@ -215,11 +242,13 @@ public class NetworkManager implements Runnable{
|
||||
padslot = recvTCPByte();
|
||||
} catch (IOException e) {
|
||||
log.info("Recieving data after sending a attach failed for device (" + command.getSender() + ") failed." + e.getMessage());
|
||||
return false;
|
||||
}
|
||||
|
||||
if(deviceslot < 0 || padslot < 0){
|
||||
log.info("Recieving data after sending a attach failed for device (" + command.getSender() + ") failed. We need to disconnect =(");
|
||||
disconnect();
|
||||
return false;
|
||||
}
|
||||
|
||||
//Let's save them for later.
|
||||
@ -229,10 +258,13 @@ public class NetworkManager implements Runnable{
|
||||
sender.setPadslot(padslot);
|
||||
}else{
|
||||
log.info("Something really went wrong. Got an attach event with out an " + NetworkHIDDevice.class.getSimpleName());
|
||||
return false;
|
||||
}
|
||||
log.info("Attaching done!");
|
||||
return true;
|
||||
}else{
|
||||
log.info("Sending the attach command for device (" + command.getSender() + ") failed. sendTCP failed");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@ -268,7 +300,6 @@ public class NetworkManager implements Runnable{
|
||||
tcpClient.send(rawCommand);
|
||||
result = true;
|
||||
} catch (Exception e) {
|
||||
//
|
||||
result = false;
|
||||
}
|
||||
}
|
||||
@ -276,7 +307,7 @@ public class NetworkManager implements Runnable{
|
||||
}
|
||||
|
||||
public void disconnect() {
|
||||
ControllerManager.deactivateAllAttachedControllers();
|
||||
//ControllerManager.deactivateAllAttachedControllers();
|
||||
tcpClient.abort();
|
||||
}
|
||||
|
||||
@ -287,7 +318,6 @@ public class NetworkManager implements Runnable{
|
||||
private byte recvTCPByte() throws IOException {
|
||||
return tcpClient.recvByte();
|
||||
}
|
||||
|
||||
|
||||
public boolean isConnected() {
|
||||
return (tcpClient != null && tcpClient.isConnected());
|
||||
@ -308,4 +338,12 @@ public class NetworkManager implements Runnable{
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public void addCommand(DeviceCommand command) {
|
||||
this.ownCommands.add(command);
|
||||
}
|
||||
|
||||
public boolean isReconnecting() {
|
||||
return !tcpClient.isConnected() && tcpClient.isShouldRetry();
|
||||
}
|
||||
}
|
||||
|
@ -29,51 +29,69 @@ import java.net.Socket;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.concurrent.SynchronousQueue;
|
||||
|
||||
import lombok.AccessLevel;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import lombok.extern.java.Log;
|
||||
import net.ash.HIDToVPADNetworkClient.manager.ActiveControllerManager;
|
||||
import net.ash.HIDToVPADNetworkClient.network.Protocol.HandshakeReturnCode;
|
||||
import net.ash.HIDToVPADNetworkClient.util.HandleFoundry;
|
||||
import net.ash.HIDToVPADNetworkClient.util.Settings;
|
||||
|
||||
@Log
|
||||
public class TCPClient {
|
||||
private Socket sock;
|
||||
private DataInputStream in;
|
||||
private DataOutputStream out;
|
||||
@Getter private int clientID = HandleFoundry.next();
|
||||
|
||||
@Getter @Setter(AccessLevel.PRIVATE)
|
||||
private int shouldRetry = Settings.MAXIMUM_TRIES_FOR_RECONNECTING;
|
||||
|
||||
private String ip;
|
||||
|
||||
public TCPClient() {
|
||||
}
|
||||
|
||||
public synchronized void connect(String ip) throws Exception {
|
||||
this.ip = ip;
|
||||
|
||||
sock = new Socket();
|
||||
sock.connect(new InetSocketAddress(ip, Protocol.TCP_PORT), 30000);
|
||||
sock.connect(new InetSocketAddress(ip, Protocol.TCP_PORT), 2000);
|
||||
in = new DataInputStream(sock.getInputStream());
|
||||
out = new DataOutputStream(sock.getOutputStream());
|
||||
|
||||
if(doHandshake() == HandshakeReturnCode.BAD_HANDSHAKE){
|
||||
throw new Exception();
|
||||
}
|
||||
HandshakeReturnCode resultHandshake = doHandshake();
|
||||
if(resultHandshake == HandshakeReturnCode.BAD_HANDSHAKE){
|
||||
log.info("[TCP] Handshaking failed");
|
||||
throw new Exception();
|
||||
}else{
|
||||
if(resultHandshake == HandshakeReturnCode.NEW_CLIENT && this.ip != null){
|
||||
//We check the IP to be sure it's the first time we connect to a WiiU. //TODO: Sending a ID from the WiiU which will be compared?
|
||||
//we are new to the client.
|
||||
ActiveControllerManager.getInstance().attachAllActiveControllers();
|
||||
}else if(resultHandshake == HandshakeReturnCode.SAME_CLIENT){
|
||||
|
||||
}
|
||||
this.ip = ip;
|
||||
shouldRetry = 0;
|
||||
}
|
||||
}
|
||||
|
||||
private synchronized HandshakeReturnCode doHandshake() throws Exception {
|
||||
if (recvByte() != Protocol.TCP_HANDSHAKE) return HandshakeReturnCode.BAD_HANDSHAKE;
|
||||
|
||||
if (recvByte() != Protocol.TCP_HANDSHAKE) return HandshakeReturnCode.BAD_HANDSHAKE;
|
||||
send(clientID);
|
||||
System.out.println("clientID:" + clientID);
|
||||
|
||||
System.out.println("[TCP] Handshaking...");
|
||||
log.info("[TCP] Handshaking...");
|
||||
HandshakeReturnCode test = (recvByte() == Protocol.TCP_NEW_CLIENT) ? HandshakeReturnCode.NEW_CLIENT : HandshakeReturnCode.SAME_CLIENT;
|
||||
System.out.println(test);
|
||||
return test;
|
||||
}
|
||||
|
||||
public synchronized boolean abort(){
|
||||
try {
|
||||
shouldRetry = Settings.MAXIMUM_TRIES_FOR_RECONNECTING;
|
||||
sock.close();
|
||||
clientID = HandleFoundry.next();
|
||||
} catch (IOException e) {
|
||||
System.out.println(e.getMessage());
|
||||
System.out.println(e.getMessage()); //TODO: handle
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
@ -85,10 +103,15 @@ public class TCPClient {
|
||||
out.flush();
|
||||
}catch(IOException e){
|
||||
try {
|
||||
connect(ip); //TODO: this is for reconnecting when the WiiU switches the application. But this breaks disconnecting, woops.
|
||||
if(shouldRetry++ < Settings.MAXIMUM_TRIES_FOR_RECONNECTING){
|
||||
System.out.println("Trying again to connect! Attempt number " + shouldRetry);
|
||||
connect(ip); //TODO: this is for reconnecting when the WiiU switches the application. But this breaks disconnecting, woops.
|
||||
}else{
|
||||
abort();
|
||||
}
|
||||
} catch (Exception e1) {
|
||||
e1.printStackTrace();
|
||||
}
|
||||
//e1.printStackTrace();
|
||||
}
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
@ -118,4 +141,8 @@ public class TCPClient {
|
||||
public synchronized boolean isConnected(){
|
||||
return (sock != null && sock.isConnected() && !sock.isClosed());
|
||||
}
|
||||
|
||||
public boolean isShouldRetry() {
|
||||
return this.shouldRetry < Settings.MAXIMUM_TRIES_FOR_RECONNECTING;
|
||||
}
|
||||
}
|
||||
|
@ -24,6 +24,7 @@ package net.ash.HIDToVPADNetworkClient.util;
|
||||
public class Settings {
|
||||
public static final int DETECT_CONTROLLER_INTERVAL = 1000;
|
||||
public static final int HANDLE_INPUTS_INTERVAL = 15;
|
||||
public static final int MAXIMUM_TRIES_FOR_RECONNECTING = 10;
|
||||
|
||||
private Settings(){}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user