Created
May 3, 2025 15:36
-
-
Save Muska-Ami/69c4c9ccd201e3f9af8d67f8506b2c0f to your computer and use it in GitHub Desktop.
Revisions
-
Muska-Ami renamed this gist
May 3, 2025 . 1 changed file with 0 additions and 0 deletions.There are no files selected for viewing
File renamed without changes. -
Muska-Ami created this gist
May 3, 2025 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,137 @@ import java.net.DatagramPacket import java.net.DatagramSocket import java.net.InetAddress import java.nio.ByteBuffer import java.nio.ByteOrder import java.util.concurrent.TimeUnit class BedrockMotd { /*** * Ping * * @param timeout 超时时间 * @param address 服务器地址 */ fun ping(timeout: Int, address: String): BedrockMotdResponse { return send(timeout, address) } /*** * Ping * * @param timeout 超时时间 * @param address 服务器端口 */ fun ping(timeout: Int, address: String, port: Int): BedrockMotdResponse { return send(timeout, address, port) } /** * 发送请求 */ private fun send(timeout: Int, address: String, port: Int = 19132): BedrockMotdResponse { val socket = DatagramSocket() val dataResponse: ByteArray val startTime: Long val endTime: Long try { startTime = System.nanoTime() sendData(socket, InetAddress.getByName(address), port) dataResponse = receive(socket, timeout) endTime = System.nanoTime() } catch (_: Exception) { return BedrockMotdResponse(status = "offline") } val delay: Long = (endTime - startTime) / 1000000 return parseResult(dataResponse, delay) } /** * 发送数据 */ private fun sendData(socket: DatagramSocket, address: InetAddress, port: Int) { fun createSendData(): ByteArray { val packetId = byteArrayOf(0x01) val clientSendTime = ByteBuffer.allocate(8) .order(ByteOrder.BIG_ENDIAN) .putLong(TimeUnit.MILLISECONDS.toMillis(System.currentTimeMillis())) .array() val magic = byteArrayOf( 0x00, 0xFF.toByte(), 0xFF.toByte(), 0x00, 0xFE.toByte(), 0xFE.toByte(), 0xFE.toByte(), 0xFE.toByte(), 0xFD.toByte(), 0xFD.toByte(), 0xFD.toByte(), 0xFD.toByte() ) val clientId = byteArrayOf(0x12, 0x34, 0x56, 0x78, 0x00) val clientGuid = ByteArray(8) // Initialize with zeros return packetId + clientSendTime + magic + clientId + clientGuid } val bytesData = createSendData() val packet = DatagramPacket(bytesData, bytesData.size, address, port) socket.send(packet) } /** * 接收数据 */ private fun receive(socket: DatagramSocket, timeout: Int): ByteArray { val receiveData = ByteArray(256) socket.soTimeout = timeout val receivePacket = DatagramPacket(receiveData, receiveData.size) socket.receive(receivePacket) return receiveData } /** * 解析结果 */ private fun parseResult(response: ByteArray, delay: Long): BedrockMotdResponse { val serverInfo = response.sliceArray(33 until response.size) val motdData = String(serverInfo).split(";") val motdLine1 = motdData[1] val motdLine2 = motdData[7] val protocolVersion = motdData[2].toInt() val versionName = motdData[3] val players = motdData[4].toInt() val maxPlayers = motdData[5].toInt() val serverUniqueId = motdData[6] val gameMode = motdData[8] return BedrockMotdResponse( status = "online", motds = arrayListOf(motdLine1, motdLine2), protocol = protocolVersion, version = versionName, onlinePlayers = players, maxPlayers = maxPlayers, gameMode = gameMode, uniqueId = serverUniqueId, delay = delay, ) } data class BedrockMotdResponse( val status: String, val motds: List<String>? = null, val protocol: Int? = null, val version: String? = null, val onlinePlayers: Int? = null, val maxPlayers: Int? = null, val gameMode: String? = null, val uniqueId: String? = null, val delay: Long? = null ) }