fix(dual-screen): listen for game telemetry on 127.0.0.1, not ::1

Android's InetAddress.getLoopbackAddress() always returns the IPv6
loopback (libcore InetAddress.java, "Android-changed"), so the listeners
were bound to [::1] and never saw the games' IPv4 packets to 127.0.0.1.
A listener bound to 127.0.0.1:20777 on the same Duo received DiRT
Showdown's packets.
This commit is contained in:
The412Banner committed 2026-10-31 19:49:41 +00:00
1 parent 42df3a78b3
commit 5eaa6a76cc
3 files changed
+10 -2

No files matched your search

@@ -33,6 +33,9 @@ object GameTelemetry {
const val OUTGAUGE_PORT = 4444
val PORTS = listOf(CODEMASTERS_PORT, FORZA_PORT, OUTGAUGE_PORT)
// Games send to 127.0.0.1; on Android InetAddress.getLoopbackAddress() is ::1, which IPv4 packets never reach.
val LISTEN_ADDRESS: java.net.InetAddress = java.net.InetAddress.getByAddress(byteArrayOf(127, 0, 0, 1))
fun parse(port: Int, data: ByteArray, length: Int): Telemetry? = runCatching {
val buf = ByteBuffer.wrap(data, 0, length).order(ByteOrder.LITTLE_ENDIAN)
when (port) {
@@ -49,7 +49,6 @@ import java.io.File
import java.net.DatagramPacket
import java.net.DatagramSocket
import java.net.HttpURLConnection
import java.net.InetAddress
import java.net.InetSocketAddress
import java.net.SocketTimeoutException
import java.net.URL
@@ -92,7 +91,7 @@ fun BottomTelemetryPage(fps: () -> Float?) {
DatagramSocket(null).apply {
reuseAddress = true
soTimeout = 500
bind(InetSocketAddress(InetAddress.getLoopbackAddress(), port))
bind(InetSocketAddress(GameTelemetry.LISTEN_ADDRESS, port))
}
}.getOrNull()
if (socket == null) {
@@ -2,6 +2,7 @@ package com.droiddeck.launcher.session
import org.junit.Assert.assertEquals
import org.junit.Assert.assertNull
import org.junit.Assert.assertTrue
import org.junit.Test
import org.junit.runner.RunWith
import org.robolectric.RobolectricTestRunner
@@ -112,6 +113,11 @@ class GameTelemetryTest {
assertEquals(4000f, t.rpm!!, 0.01f)
}
@Test fun listensOnIpv4Loopback() {
assertTrue(GameTelemetry.LISTEN_ADDRESS is java.net.Inet4Address)
assertEquals("127.0.0.1", GameTelemetry.LISTEN_ADDRESS.hostAddress)
}
@Test fun shortPacketsAreIgnored() {
assertNull(GameTelemetry.parse(GameTelemetry.CODEMASTERS_PORT, ByteArray(148), 148))
assertNull(GameTelemetry.parse(GameTelemetry.OUTGAUGE_PORT, ByteArray(40), 40))