package games.strategy.net; import java.awt.Component; import java.io.IOException; import java.io.InputStream; import java.net.Inet4Address; import java.net.InetAddress; import java.net.NetworkInterface; import java.net.ServerSocket; import java.net.Socket; import java.net.SocketException; import java.net.SocketTimeoutException; import java.util.Enumeration; import javax.swing.JOptionPane; import javax.swing.JScrollPane; import javax.swing.JTextArea; import net.sbbi.upnp.impls.InternetGatewayDevice; import net.sbbi.upnp.messages.UPNPResponseException; public class UniversalPlugAndPlayHelper { private int port = 3300; private InetAddress local = null; private InternetGatewayDevice m_device = null; public UniversalPlugAndPlayHelper(final int port) { this.port = port; } public static boolean attemptAddingPortForwarding(final Component parent, final int port) { final UniversalPlugAndPlayHelper upnpHelper = new UniversalPlugAndPlayHelper(port); final JTextArea textArea = new JTextArea(); textArea.setEditable(false); final String error = upnpHelper.attemptAddingPortForwarding(textArea); textArea.append("\r\n \r\n \r\n \r\n"); final boolean worked = (error == null); final String textResult; if (worked) { textResult = "It looks like it worked. This program will close now.\r\n" + "Please try hosting again, to see if it 'really' worked.\r\n" + "Remember that your firewall must allow TripleA, or else you still won't be able to host.\r\n"; } else { textResult = "It appears TripleA failed to set your Port Forwarding.\r\n" + "Please make sure UPnP is turned on, in your router's settings.\r\n\r\n" + "If you still cannot get TripleA to set them correctly, then you must set them yourself!\r\n" + "See 'How To Host...' in the help menu, at the top of the lobby screen in order to manually set " + "them.\r\n\r\n" + "\r\nThis program will close now.\r\n"; } System.out.println(textResult); textArea.append(textResult); JOptionPane.showMessageDialog(parent, new JScrollPane(textArea), "Setting Port Forwarding with UPnP", JOptionPane.INFORMATION_MESSAGE); return worked; } public String attemptAddingPortForwarding(final JTextArea textArea) { System.out.println("Starting Universal Plug and Play (UPnP) add port forward map script."); textArea.append("Starting Universal Plug and Play (UPnP) add port forward map script.\r\n"); final String localError = findLocalInetAddress(); if (localError != null) { textArea.append(localError + "\r\n"); return localError; } textArea.append("Found Local IP/Inet Address to use: " + local + "\r\n"); final String gatewayError = findInternetGatewayDevice(); if (gatewayError != null) { textArea.append(gatewayError + "\r\n"); return gatewayError; } textArea.append("Internet Gateway Device (normally a router) found!\r\n"); final String addPortError = addPortForwardUPNP(); if (addPortError != null) { textArea.append(addPortError + "\r\n"); return addPortError; } textArea.append("Port Forwarding map added successfully.\r\n"); return null; } public String testConnection() { System.out.println("Waiting for a connection"); final int internalPort = port; boolean connection = false; // boolean bytes = false; try (ServerSocket ss = new ServerSocket(internalPort)) { ss.setSoTimeout(5000); try { final Socket s = ss.accept(); connection = true; final InputStream in = s.getInputStream(); while (in.available() > 0) { System.out.println("byte : " + in.read()); // bytes = true; } } catch (final SocketTimeoutException stoe) { System.out.println("Connection Test Timed Out. Port Forward may still work anyway."); return "Connection Test Timed Out. Port Forward may still work anyway."; } } catch (final IOException e) { System.out.println("Connection Test Timed Out. Port Forward may still work anyway. \r\n " + e.getMessage()); return "Connection Test Timed Out. Port Forward may still work anyway. \r\n " + e.getMessage(); } if (!connection) { System.out.println("Connection Test Timed Out. Port Forward may still work anyway."); return "Connection Test Timed Out. Port Forward may still work anyway."; } System.out.println("Connection made!"); return null; } public String removePortForwardUPNP() { System.out.println("Attempting to remove Port Forwarding"); final int externalPort = port; boolean removed = false; try { removed = m_device.deletePortMapping(null, externalPort, "TCP"); } catch (final IOException e) { System.out.println("Failed to remove port mapping! \r\n " + e.getMessage()); return "Failed to remove port mapping! \r\n " + e.getMessage(); } catch (final UPNPResponseException e) { System.out.println("Failed to remove port mapping! \r\n " + e.getMessage()); return "Failed to remove port mapping! \r\n " + e.getMessage(); } if (!removed) { System.out.println("Failed to remove port mapping!"); return "Failed to remove port mapping!"; } System.out.println("Success. Port Forwarding map removed."); return null; } private String addPortForwardUPNP() { final int internalPort = port; final int externalPort = port; // System.out.println("Attempting to map port on " + m_device.msgFactory.service.serviceType + " service"); System.out.print("Adding mapping from "); try { System.out.print(m_device.getExternalIPAddress()); } catch (final UPNPResponseException | IOException e1) { // ignore } System.out.println(":" + externalPort); System.out.println("To " + local.getHostAddress() + ":" + internalPort); boolean mapped = false; try { mapped = m_device.addPortMapping("TripleA Game Hosting", "TCP", null, externalPort, local.getHostAddress(), internalPort, 0); } catch (final IOException e) { System.out.println("Port Mapping Failed! Please try to Forward Ports manually! \r\n " + e.getMessage()); return "Port Mapping Failed! Please try to Forward Ports manually! \r\n " + e.getMessage(); } catch (final UPNPResponseException e) { System.out.println("Port Mapping Failed! Please try to Forward Ports manually! \r\n " + e.getMessage()); return "Port Mapping Failed! Please try to Forward Ports manually! \r\n " + e.getMessage(); } if (!mapped) { System.out.println("Port Mapping Failed! Please try to Forward Ports manually!"); return "Port Mapping Failed! Please try to Forward Ports manually!"; } System.out.println("Success. Port Forwarding map added."); return null; } private String findInternetGatewayDevice() { System.out.println("Attempting to find internet gateway device (normally a router)."); InternetGatewayDevice[] devices = null; try { devices = InternetGatewayDevice.getDevices(2000); } catch (final IOException e) { System.out.println("Router/Device UPnP turned off. Or no Routers/Devices found. " + "Please make sure your router's UPNP is turned on! \r\n " + e.getMessage()); return "Router/Device UPnP turned off. Or no Routers/Devices found. " + "Please make sure your router's UPNP is turned on! \r\n " + e.getMessage(); } if (devices == null || 1 > devices.length) { System.out.println("Router/Device UPnP turned off. Or no Routers/Devices found. " + "Please make sure your router's UPNP is turned on!"); return "Router/Device UPnP turned off. Or no Routers/Devices found. " + "Please make sure your router's UPNP is turned on!"; } m_device = devices[0]; System.out.println("Device found!"); return null; } private String findLocalInetAddress() { local = null; System.out.println("Attempting to find local ip/inet address."); try { final Enumeration<NetworkInterface> ifaces = NetworkInterface.getNetworkInterfaces(); while (ifaces.hasMoreElements() && local == null) { final NetworkInterface iface = ifaces.nextElement(); final Enumeration<InetAddress> addresses = iface.getInetAddresses(); while (addresses.hasMoreElements() && local == null) { final InetAddress addr = addresses.nextElement(); if (addr instanceof Inet4Address && !addr.isLoopbackAddress()) { local = addr; } } } } catch (final SocketException e) { local = null; System.out.println("Could not determine local ip/inet address!"); return "Could not determine local ip/inet address! \r\n " + e.getMessage(); } if (local == null) { System.out.println("Could not determine local ip/inet address!"); return "Could not determine local ip/inet address!"; } System.out.println("Local Address to use: " + local); return null; } }