// // SDLHoleMessageDecoder.swift // punchnet // // Created by 安礼成 on 2026/4/15. // import Foundation import NIOCore import NIOPosix import SwiftProtobuf // --MARK: 进来的消息, 这里需要采用代数类型来表示 enum SDLHoleMessage { case data(SDLData) case register(SDLRegister) case registerAck(SDLRegisterAck) case stunProbeReply(SDLStunProbeReply) case stunReply(SDLStunReply) } enum SDLHoleControlMessage { case register(SDLRegister) case registerAck(SDLRegisterAck) case stunProbeReply(SDLStunProbeReply) case stunReply(SDLStunReply) } enum SDLHoleInboundMessage { case control(SDLHoleControlMessage) case data(SDLData) } extension SDLHoleMessage { var inboundMessage: SDLHoleInboundMessage { switch self { case .data(let data): return .data(data) case .register(let register): return .control(.register(register)) case .registerAck(let registerAck): return .control(.registerAck(registerAck)) case .stunProbeReply(let stunProbeReply): return .control(.stunProbeReply(stunProbeReply)) case .stunReply(let stunReply): return .control(.stunReply(stunReply)) } } } extension SDLHoleMessage { static func decode(buffer: inout ByteBuffer) throws -> SDLHoleMessage? { guard let type = buffer.readInteger(as: UInt8.self), let packetType = SDLPacketType(rawValue: type) else { return nil } switch packetType { case .data: guard let bytes = buffer.readBytes(length: buffer.readableBytes), let dataPacket = try? SDLData(serializedBytes: bytes) else { return nil } return .data(dataPacket) case .register: guard let bytes = buffer.readBytes(length: buffer.readableBytes), let registerPacket = try? SDLRegister(serializedBytes: bytes) else { return nil } return .register(registerPacket) case .registerAck: guard let bytes = buffer.readBytes(length: buffer.readableBytes), let registerAck = try? SDLRegisterAck(serializedBytes: bytes) else { return nil } return .registerAck(registerAck) case .stunProbeReply: guard let bytes = buffer.readBytes(length: buffer.readableBytes), let stunProbeReply = try? SDLStunProbeReply(serializedBytes: bytes) else { return nil } return .stunProbeReply(stunProbeReply) case .stunReply: guard let bytes = buffer.readBytes(length: buffer.readableBytes), let stunReply = try? SDLStunReply(serializedBytes: bytes) else { return nil } return .stunReply(stunReply) default: SDLLogger.log("[SDLUDPHole] decode miss type: \(type)", for: .debug) return nil } } }