Add Enable Air option support
Use proper method to pass client address to server. Fix possible memory leak.pull/1/head
parent
815cf3cadf
commit
45bc2fa054
|
@ -13,6 +13,16 @@ class BrokenithmApplication : Application() {
|
|||
config.edit().putString("server", value).apply()
|
||||
}
|
||||
|
||||
var enableAir: Boolean
|
||||
get() {
|
||||
val config = getSharedPreferences(settings_preference, MODE_PRIVATE)
|
||||
return config.getBoolean("enable_air", true)
|
||||
}
|
||||
set(value) {
|
||||
val config = getSharedPreferences(settings_preference, MODE_PRIVATE)
|
||||
config.edit().putBoolean("enable_air", value).apply()
|
||||
}
|
||||
|
||||
var simpleAir: Boolean
|
||||
get() {
|
||||
val config = getSharedPreferences(settings_preference, MODE_PRIVATE)
|
||||
|
|
|
@ -46,7 +46,7 @@ class MainActivity : AppCompatActivity() {
|
|||
private var mTestButton = false
|
||||
private var mServiceButton = false
|
||||
private data class InputEvent(val keys: MutableSet<Int>? = null, val airHeight : Int = 6, val testButton: Boolean = false, val serviceButton: Boolean = false)
|
||||
private var mInputQueue = ArrayDeque<InputEvent>()
|
||||
//private var mInputQueue = ArrayDeque<InputEvent>()
|
||||
|
||||
// LEDs
|
||||
private lateinit var mLEDBitmap: Bitmap
|
||||
|
@ -241,26 +241,38 @@ class MainActivity : AppCompatActivity() {
|
|||
|
||||
findViewById<Button>(R.id.button_coin).setOnClickListener {
|
||||
if(!mExitFlag)
|
||||
sendFunctionKey(parseAddress(editServer.text.toString()), FUNCTION_BUTTON.FUNCTION_COIN)
|
||||
sendFunctionKey(parseAddress(editServer.text.toString()), FunctionButton.FUNCTION_COIN)
|
||||
}
|
||||
findViewById<Button>(R.id.button_card).setOnClickListener {
|
||||
if(!mExitFlag)
|
||||
sendFunctionKey(parseAddress(editServer.text.toString()), FUNCTION_BUTTON.FUNCTION_CARD)
|
||||
sendFunctionKey(parseAddress(editServer.text.toString()), FunctionButton.FUNCTION_CARD)
|
||||
}
|
||||
findViewById<CheckBox>(R.id.check_simple_air).apply {
|
||||
|
||||
val checkSimpleAir = findViewById<CheckBox>(R.id.check_simple_air)
|
||||
findViewById<CheckBox>(R.id.check_enable_air).apply {
|
||||
setOnCheckedChangeListener { _, isChecked ->
|
||||
mEnableAir = isChecked
|
||||
checkSimpleAir.isEnabled = isChecked
|
||||
app.enableAir = isChecked
|
||||
}
|
||||
isChecked = app.enableAir
|
||||
}
|
||||
checkSimpleAir.apply {
|
||||
setOnCheckedChangeListener { _, isChecked ->
|
||||
mSimpleAir = isChecked
|
||||
app.simpleAir = isChecked
|
||||
}
|
||||
isChecked = app.simpleAir
|
||||
}
|
||||
mEnableAir = app.enableAir
|
||||
mSimpleAir = app.simpleAir
|
||||
|
||||
findViewById<View>(R.id.button_test).setOnTouchListener { view, event ->
|
||||
mTestButton = when(event.actionMasked) {
|
||||
MotionEvent.ACTION_MOVE, MotionEvent.ACTION_DOWN -> true
|
||||
else -> false
|
||||
}
|
||||
mInputQueue.add(InputEvent(serviceButton = mServiceButton, testButton = mTestButton))
|
||||
//mInputQueue.add(InputEvent(serviceButton = mServiceButton, testButton = mTestButton))
|
||||
view.performClick()
|
||||
}
|
||||
findViewById<View>(R.id.button_service).setOnTouchListener { view, event ->
|
||||
|
@ -268,7 +280,7 @@ class MainActivity : AppCompatActivity() {
|
|||
MotionEvent.ACTION_MOVE, MotionEvent.ACTION_DOWN -> true
|
||||
else -> false
|
||||
}
|
||||
mInputQueue.add(InputEvent(serviceButton = mServiceButton, testButton = mTestButton))
|
||||
//mInputQueue.add(InputEvent(serviceButton = mServiceButton, testButton = mTestButton))
|
||||
view.performClick()
|
||||
}
|
||||
|
||||
|
@ -382,7 +394,7 @@ class MainActivity : AppCompatActivity() {
|
|||
}
|
||||
} else {
|
||||
val socket = try {
|
||||
DatagramSocket(52468).apply {
|
||||
DatagramSocket(serverPort).apply {
|
||||
reuseAddress = true
|
||||
soTimeout = 1000
|
||||
}
|
||||
|
@ -497,7 +509,7 @@ class MainActivity : AppCompatActivity() {
|
|||
)
|
||||
}
|
||||
|
||||
enum class FUNCTION_BUTTON {
|
||||
enum class FunctionButton {
|
||||
UNDEFINED, FUNCTION_COIN, FUNCTION_CARD
|
||||
}
|
||||
|
||||
|
@ -510,33 +522,20 @@ class MainActivity : AppCompatActivity() {
|
|||
var serviceBtn = false
|
||||
}
|
||||
|
||||
private fun sendAir(server: String, port: Int) {
|
||||
val address = InetSocketAddress(server, port)
|
||||
val socket = DatagramSocket()
|
||||
val buffer = byteArrayOf(0x04, 'A'.toByte(), 'I'.toByte(), 'R'.toByte(), if (mEnableAir) 0x01 else 0x00)
|
||||
val packet = DatagramPacket(buffer, buffer.size)
|
||||
socket.apply {
|
||||
connect(address)
|
||||
send(packet)
|
||||
close()
|
||||
}
|
||||
}
|
||||
|
||||
private fun getLocalIPAddress(useIPv4: Boolean): String {
|
||||
private fun getLocalIPAddress(useIPv4: Boolean): ByteArray {
|
||||
try {
|
||||
val interfaces: List<NetworkInterface> = Collections.list(NetworkInterface.getNetworkInterfaces())
|
||||
for (intf in interfaces) {
|
||||
val addrs: List<InetAddress> = Collections.list(intf.inetAddresses)
|
||||
for (addr in addrs) {
|
||||
if (!addr.isLoopbackAddress) {
|
||||
val sAddr = addr.hostAddress
|
||||
val isIPv4 = sAddr.indexOf(':') < 0
|
||||
val sAddr = addr.address
|
||||
val isIPv4 = sAddr.size == 4
|
||||
if (useIPv4) {
|
||||
if (isIPv4) return sAddr
|
||||
} else {
|
||||
if (!isIPv4) {
|
||||
val delim = sAddr.indexOf('%') // drop ip6 zone suffix
|
||||
return if (delim < 0) sAddr.toUpperCase(Locale.ROOT) else sAddr.substring(0, delim).toUpperCase(Locale.ROOT)
|
||||
return sAddr
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -544,17 +543,21 @@ class MainActivity : AppCompatActivity() {
|
|||
}
|
||||
} catch (e: Exception) {
|
||||
}
|
||||
return ""
|
||||
return byteArrayOf()
|
||||
}
|
||||
|
||||
private fun sendConnect(address: InetSocketAddress?) {
|
||||
address ?: return
|
||||
thread {
|
||||
val selfAddress = getLocalIPAddress(true)
|
||||
val buffer = ByteArray(24)
|
||||
byteArrayOf(23, 'C'.toByte(), 'O'.toByte(), 'N'.toByte()).copyInto(buffer)
|
||||
selfAddress.toByteArray().copyInto(buffer, 4)
|
||||
serverPort.toString().toByteArray().copyInto(buffer, 4 + 15)
|
||||
if (selfAddress.isEmpty()) return@thread
|
||||
val buffer = ByteArray(21)
|
||||
byteArrayOf('C'.toByte(), 'O'.toByte(), 'N'.toByte()).copyInto(buffer, 1)
|
||||
ByteBuffer.wrap(buffer)
|
||||
.put(4, if (selfAddress.size == 4) 1.toByte() else 2.toByte())
|
||||
.putShort(5, serverPort.toShort())
|
||||
selfAddress.copyInto(buffer, 7)
|
||||
buffer[0] = (3 + 1 + 2 + selfAddress.size).toByte()
|
||||
try {
|
||||
val socket = DatagramSocket()
|
||||
val packet = DatagramPacket(buffer, buffer.size)
|
||||
|
@ -596,7 +599,7 @@ class MainActivity : AppCompatActivity() {
|
|||
}
|
||||
}
|
||||
|
||||
private fun sendFunctionKey(address: InetSocketAddress?, function: FUNCTION_BUTTON) {
|
||||
private fun sendFunctionKey(address: InetSocketAddress?, function: FunctionButton) {
|
||||
address ?: return
|
||||
thread {
|
||||
val buffer = byteArrayOf(4, 'F'.toByte(), 'N'.toByte(), 'C'.toByte(), function.ordinal.toByte())
|
||||
|
@ -667,7 +670,8 @@ class MainActivity : AppCompatActivity() {
|
|||
val realBuf = ByteArray(44)
|
||||
realBuf[0] = buffer.length.toByte()
|
||||
buffer.header.copyInto(realBuf, 1)
|
||||
buffer.air.copyInto(realBuf, 4)
|
||||
if (mEnableAir)
|
||||
buffer.air.copyInto(realBuf, 4)
|
||||
buffer.slider.copyInto(realBuf, 10)
|
||||
realBuf[42] = if (buffer.testBtn) 0x01 else 0x00
|
||||
realBuf[43] = if (buffer.serviceBtn) 0x01 else 0x00
|
||||
|
@ -684,7 +688,6 @@ class MainActivity : AppCompatActivity() {
|
|||
private var mLastAirUpdateTime = 0L
|
||||
private fun applyKeys(event: InputEvent, buffer: IoBuffer): IoBuffer {
|
||||
return buffer.apply {
|
||||
buffer.length = 43
|
||||
buffer.header = byteArrayOf('I'.toByte(), 'N'.toByte(), 'P'.toByte())
|
||||
if (event.keys != null && event.keys.isNotEmpty()) {
|
||||
for (i in 0 until 32) {
|
||||
|
@ -692,16 +695,20 @@ class MainActivity : AppCompatActivity() {
|
|||
}
|
||||
}
|
||||
|
||||
val currentTime = System.currentTimeMillis()
|
||||
if (currentTime - mLastAirUpdateTime > airUpdateInterval) {
|
||||
mLastAirHeight += if (mLastAirHeight < mCurrentAirHeight) 1 else if (mLastAirHeight > mCurrentAirHeight) -1 else 0
|
||||
mLastAirUpdateTime = currentTime
|
||||
}
|
||||
if (mLastAirHeight != 6) {
|
||||
for (i in mLastAirHeight..5) {
|
||||
buffer.air[mAirIdx[i]] = 1
|
||||
buffer.length = if (mEnableAir) {
|
||||
val currentTime = System.currentTimeMillis()
|
||||
if (currentTime - mLastAirUpdateTime > airUpdateInterval) {
|
||||
mLastAirHeight += if (mLastAirHeight < mCurrentAirHeight) 1 else if (mLastAirHeight > mCurrentAirHeight) -1 else 0
|
||||
mLastAirUpdateTime = currentTime
|
||||
}
|
||||
}
|
||||
if (mLastAirHeight != 6) {
|
||||
for (i in mLastAirHeight..5) {
|
||||
buffer.air[mAirIdx[i]] = 1
|
||||
}
|
||||
}
|
||||
43
|
||||
} else 37
|
||||
|
||||
buffer.serviceBtn = event.serviceButton
|
||||
buffer.testBtn = event.testButton
|
||||
}
|
||||
|
|
|
@ -111,12 +111,12 @@
|
|||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<CheckBox
|
||||
android:id="@+id/check_simple_air"
|
||||
android:id="@+id/check_enable_air"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="8dp"
|
||||
android:layout_marginTop="8dp"
|
||||
android:text="@string/simple_air"
|
||||
android:text="Enable Air"
|
||||
android:textColor="@color/white"
|
||||
app:layout_constraintStart_toEndOf="@+id/button_card"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
@ -168,10 +168,10 @@
|
|||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="8dp"
|
||||
android:background="@drawable/highlight_border_1dp"
|
||||
android:text="@string/test"
|
||||
android:textColor="@color/white"
|
||||
android:clickable="true"
|
||||
android:focusable="true"
|
||||
android:text="@string/test"
|
||||
android:textColor="@color/white"
|
||||
app:layout_constraintStart_toEndOf="@id/check_debug"
|
||||
app:layout_constraintTop_toTopOf="@+id/check_debug" />
|
||||
|
||||
|
@ -192,7 +192,7 @@
|
|||
android:id="@+id/check_show_delay"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="8dp"
|
||||
android:layout_marginStart="4dp"
|
||||
android:text="@string/show_delay"
|
||||
android:textColor="@color/white"
|
||||
app:layout_constraintStart_toEndOf="@+id/button_service"
|
||||
|
@ -202,12 +202,22 @@
|
|||
android:id="@+id/check_vibrate"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="8dp"
|
||||
android:layout_marginStart="4dp"
|
||||
android:text="@string/enable_vibration"
|
||||
android:textColor="@color/white"
|
||||
app:layout_constraintStart_toEndOf="@+id/check_show_delay"
|
||||
app:layout_constraintTop_toTopOf="@+id/check_show_delay" />
|
||||
|
||||
<CheckBox
|
||||
android:id="@+id/check_simple_air"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="4dp"
|
||||
android:text="@string/simple_air"
|
||||
android:textColor="@color/white"
|
||||
app:layout_constraintStart_toEndOf="@+id/check_vibrate"
|
||||
app:layout_constraintTop_toTopOf="@+id/check_vibrate" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/text_mode"
|
||||
android:layout_width="wrap_content"
|
||||
|
@ -222,9 +232,9 @@
|
|||
android:textColor="@color/white"
|
||||
android:textSize="16sp"
|
||||
android:textStyle="bold"
|
||||
app:layout_constraintBottom_toBottomOf="@+id/check_vibrate"
|
||||
app:layout_constraintStart_toEndOf="@+id/check_vibrate"
|
||||
app:layout_constraintTop_toTopOf="@+id/check_vibrate" />
|
||||
app:layout_constraintBottom_toBottomOf="@+id/check_simple_air"
|
||||
app:layout_constraintStart_toEndOf="@+id/check_simple_air"
|
||||
app:layout_constraintTop_toTopOf="@+id/check_simple_air" />
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
</net.cachapa.expandablelayout.ExpandableLayout>
|
||||
|
|
|
@ -11,13 +11,13 @@
|
|||
<string name="collapse"> Control ↑ </string>
|
||||
<string name="test">Test</string>
|
||||
<string name="service">Service</string>
|
||||
<string name="show_debug_info">Show Debug Info</string>
|
||||
<string name="show_debug_info">Debug</string>
|
||||
<string name="debug_info">touched: air:%d %s\n%s</string>
|
||||
<string name="current_latency">Current Latency: %f ms</string>
|
||||
<string name="press_again_to_exit">Press again to exit</string>
|
||||
<string name="show_delay">Show Delay</string>
|
||||
<string name="address">Address</string>
|
||||
<string name="enable_vibration">Enable Vibration</string>
|
||||
<string name="enable_vibration">Vibration</string>
|
||||
|
||||
<string name="tcp">TCP</string>
|
||||
<string name="udp">UDP</string>
|
||||
|
|
Loading…
Reference in New Issue