diff --git a/build.gradle b/build.gradle index a73f9920..5455f2a7 100644 --- a/build.gradle +++ b/build.gradle @@ -34,6 +34,7 @@ dependencies { implementation 'com.google.code.gson:gson:2.8.9' implementation 'com.google.protobuf:protobuf-java:3.19.3' implementation 'com.squareup.okhttp3:okhttp:3.14.9' + implementation 'commons-validator:commons-validator:1.7' implementation 'org.apache.commons:commons-lang3:3.12.0' implementation 'org.java-websocket:Java-WebSocket:1.5.2' testCompile 'com.squareup.okhttp3:mockwebserver:3.14.9' diff --git a/src/main/java/in/dragonbra/javasteam/steam/discovery/ServerRecord.java b/src/main/java/in/dragonbra/javasteam/steam/discovery/ServerRecord.java index b85a2a99..74eb28a6 100644 --- a/src/main/java/in/dragonbra/javasteam/steam/discovery/ServerRecord.java +++ b/src/main/java/in/dragonbra/javasteam/steam/discovery/ServerRecord.java @@ -1,6 +1,7 @@ package in.dragonbra.javasteam.steam.discovery; import in.dragonbra.javasteam.networking.steam3.ProtocolTypes; +import in.dragonbra.javasteam.util.NetHelpers; import java.net.InetSocketAddress; import java.util.EnumSet; @@ -55,6 +56,24 @@ public static ServerRecord createSocketServer(InetSocketAddress endpoint) { return new ServerRecord(endpoint, EnumSet.of(ProtocolTypes.TCP, ProtocolTypes.UDP)); } + /** + * Creates a Socket server given an IP endpoint. + * + * @param address The IP address and port of the server, as a string. + * @return A new [ServerRecord], if the address was able to be parsed. **null** otherwise. + */ + public static ServerRecord tryCreateSocketServer(String address) { + InetSocketAddress endpoint; + + endpoint = NetHelpers.tryParseIPEndPoint(address); + + if (endpoint == null) { + return null; + } + + return new ServerRecord(endpoint, EnumSet.of(ProtocolTypes.TCP, ProtocolTypes.UDP)); + } + public static ServerRecord createWebSocketServer(String address) { if (address == null) { throw new IllegalArgumentException("address is null"); diff --git a/src/main/java/in/dragonbra/javasteam/steam/webapi/SteamDirectory.java b/src/main/java/in/dragonbra/javasteam/steam/webapi/SteamDirectory.java index c90e06ba..ae3fe55d 100644 --- a/src/main/java/in/dragonbra/javasteam/steam/webapi/SteamDirectory.java +++ b/src/main/java/in/dragonbra/javasteam/steam/webapi/SteamDirectory.java @@ -4,9 +4,9 @@ import in.dragonbra.javasteam.steam.discovery.ServerRecord; import in.dragonbra.javasteam.steam.steamclient.configuration.SteamConfiguration; import in.dragonbra.javasteam.types.KeyValue; +import in.dragonbra.javasteam.util.NetHelpers; import java.io.IOException; -import java.net.InetSocketAddress; import java.util.ArrayList; import java.util.HashMap; import java.util.List; @@ -65,8 +65,10 @@ public static List load(SteamConfiguration configuration, int maxS List records = new ArrayList<>(); for (KeyValue socket : socketList.getChildren()) { - String[] split = socket.getValue().split(":"); - records.add(ServerRecord.createSocketServer(new InetSocketAddress(split[0], Integer.parseInt(split[1])))); + ServerRecord record = ServerRecord.tryCreateSocketServer(socket.getValue()); + if (record != null) { + records.add(record); + } } for (KeyValue socket : webSocketList.getChildren()) { diff --git a/src/main/java/in/dragonbra/javasteam/util/NetHelpers.java b/src/main/java/in/dragonbra/javasteam/util/NetHelpers.java index f23b1d12..01b00e27 100644 --- a/src/main/java/in/dragonbra/javasteam/util/NetHelpers.java +++ b/src/main/java/in/dragonbra/javasteam/util/NetHelpers.java @@ -1,6 +1,9 @@ package in.dragonbra.javasteam.util; +import org.apache.commons.validator.routines.InetAddressValidator; + import java.net.InetAddress; +import java.net.InetSocketAddress; import java.net.UnknownHostException; import java.nio.ByteBuffer; @@ -27,4 +30,27 @@ public static int getIPAddress(InetAddress ip) { final ByteBuffer buff = ByteBuffer.wrap(ip.getAddress()); return (int) (buff.getInt() & 0xFFFFFFFFL); } + + + public static InetSocketAddress tryParseIPEndPoint(String address) { + if (address == null) { + return null; + } + + String[] split = address.split(":"); + + if (!InetAddressValidator.getInstance().isValidInet4Address(split[0])) { + return null; + } + + try { + if (split.length > 1) { + return new InetSocketAddress(split[0], Integer.parseInt(split[1])); + } + } catch (IllegalArgumentException exception) { + // no-op + } + + return null; + } } diff --git a/src/test/java/in/dragonbra/javasteam/steam/discovery/ServerRecordTest.java b/src/test/java/in/dragonbra/javasteam/steam/discovery/ServerRecordTest.java index 996f1e90..62d8845f 100644 --- a/src/test/java/in/dragonbra/javasteam/steam/discovery/ServerRecordTest.java +++ b/src/test/java/in/dragonbra/javasteam/steam/discovery/ServerRecordTest.java @@ -4,6 +4,9 @@ import in.dragonbra.javasteam.networking.steam3.ProtocolTypes; import org.junit.Test; +import java.net.InetSocketAddress; +import java.util.EnumSet; + import static org.junit.Assert.*; /** @@ -55,4 +58,39 @@ public void SameEndPointsAndProtocolsAreEqual() { assertEquals(l.hashCode(), r.hashCode()); } + + @Test + public void canTryCreateSocketServer() { + ServerRecord record = ServerRecord.tryCreateSocketServer("127.0.0.1:1234"); + + assertNotNull(record); + assertEquals(new InetSocketAddress("127.0.0.1", 1234), record.getEndpoint()); + assertEquals(EnumSet.of(ProtocolTypes.TCP, ProtocolTypes.UDP), record.getProtocolTypes()); + + record = ServerRecord.tryCreateSocketServer("192.168.0.1:5678"); + + assertNotNull(record); + assertEquals(new InetSocketAddress("192.168.0.1", 5678), record.getEndpoint()); + assertEquals(EnumSet.of(ProtocolTypes.TCP, ProtocolTypes.UDP), record.getProtocolTypes()); + } + + @Test + public void cannotTryCreateSocketServer() { + ServerRecord record; + + record = ServerRecord.tryCreateSocketServer("127.0.0.1"); + assertNull(record); + + record = ServerRecord.tryCreateSocketServer("127.0.0.1:123456789"); + assertNull(record); + + record = ServerRecord.tryCreateSocketServer("127.0.0.1:-1234"); + assertNull(record); + + record = ServerRecord.tryCreateSocketServer("127.0.0.1:notanint"); + assertNull(record); + + record = ServerRecord.tryCreateSocketServer("volvopls.valvesoftware.com:1234"); + assertNull(record); + } } \ No newline at end of file