基本完善SBProxy-MC

This commit is contained in:
CN-JS-HuiBai
2026-04-21 17:15:37 +08:00
parent 5910b7c019
commit 39f9a7592c
7 changed files with 58 additions and 14 deletions

View File

@@ -20,6 +20,25 @@ func (h *Inbound) startBedrockListener() {
}
defer l.Close()
// Setup RakNet Pong Data (Active scanning response)
motd := h.options.MOTD
if motd == "" {
motd = "A Minecraft Server"
}
ver := h.options.Version
if ver == "" {
ver = "1.20.1"
}
// Bedrock Pong format: MCPE;MOTD;Protocol;Version;Online;Max;ServerID;SubMOTD;GameMode;1;Port;Port;
pongData := fmt.Sprintf("MCPE;%s;594;%s;0;%d;%d;SBProxy;Creative;1;19132;19132;",
motd, ver, h.options.MaxPlayers, time.Now().UnixNano())
l.ExpirablePongData(func(p net.Addr) []byte {
return []byte(pongData)
})
h.logger.Info("Bedrock listener started with Version: ", ver)
for {
conn, err := l.Accept()
if err != nil {
@@ -31,5 +50,17 @@ func (h *Inbound) startBedrockListener() {
func (h *Inbound) handleBedrockConnection(conn net.Conn) {
defer conn.Close()
// Placeholder for Bedrock handshake and tunneling
h.logger.Info("Bedrock connection accepted from: ", conn.RemoteAddr())
// For Bedrock, we eventually want to do a similar handshake
// using Bedrock-specific packets (e.g., Login, RequestChunkRadius, etc.)
// and then a custom Play-state packet for encapsulated proxy data.
// Implementation follows the same pattern as Java:
// Handle Handshake -> Handle Login -> Handle Play -> Tunnel data.
// KeepAlive is handled by RakNet itself.
// Placeholder for Bedrock-specific tunneling logic
select {}
}

View File

@@ -41,10 +41,14 @@ func NewInbound(ctx context.Context, router adapter.Router, logger log.ContextLo
options: options,
users: options.Users,
}
networks := []string{N.NetworkTCP}
if options.ProtocolType == "bedrock" {
networks = nil // Handled by separate raknet listener
}
inbound.listener = listener.New(listener.Options{
Context: ctx,
Logger: logger,
Network: []string{N.NetworkTCP, N.NetworkUDP},
Network: networks,
Listen: options.ListenOptions,
ConnectionHandler: inbound,
PacketHandler: inbound,
@@ -58,11 +62,11 @@ func (h *Inbound) Start(stage adapter.StartStage) error {
if stage != adapter.StartStateStart {
return nil
}
err := h.listener.Start()
if err == nil && h.options.ProtocolType == "bedrock" {
if h.options.ProtocolType == "bedrock" {
go h.startBedrockListener()
return nil
}
return err
return h.listener.Start()
}
func (h *Inbound) Close() error { return common.Close(h.listener) }

View File

@@ -75,7 +75,9 @@ func (h *Inbound) handleJavaStatus(conn net.Conn) {
conn.Write(body.Bytes())
} else if packetID == 0x01 { // Ping
var b [8]byte
io.ReadFull(conn, b[:])
if _, err := io.ReadFull(conn, b[:]); err != nil {
return
}
var body bytes.Buffer
WriteVarInt(&body, 0x01)
@@ -90,10 +92,9 @@ func (h *Inbound) handleJavaStatus(conn net.Conn) {
}
}
func (h *Inbound) handleJavaLogin(ctx context.Context, conn net.Conn, username string, metadata adapter.InboundContext, onClose N.CloseHandlerFunc) {
// Note: Packet length is already read in switch or caller
func (h *Inbound) handleJavaLogin(ctx context.Context, conn net.Conn, metadata adapter.InboundContext, onClose N.CloseHandlerFunc) {
// Login Start
packetLen, _, err := ReadVarInt(conn)
_, _, err := ReadVarInt(conn)
if err != nil {
conn.Close()
return

View File

@@ -68,13 +68,19 @@ func (c *javaTunnelConn) SetDeadline(t time.Time) error { return nil }
func (c *javaTunnelConn) SetReadDeadline(t time.Time) error { return nil }
func (c *javaTunnelConn) SetWriteDeadline(t time.Time) error { return nil }
func (h *Inbound) startJavaTunnel(ctx context.Context, conn net.Conn, username string, encrypter, decrypter cipher.Stream, metadata adapter.InboundContext) *javaTunnelConn {
func (h *Inbound) startJavaTunnel(ctx context.Context, conn net.Conn, username string, encrypter, decrypter cipher.Stream, inboundMetadata adapter.InboundContext) *javaTunnelConn {
tunnel := &javaTunnelConn{
h: h,
conn: conn,
encrypter: encrypter,
}
tunnel.readCond = sync.NewCond(&tunnel.readMutex)
go h.router.RouteConnectionEx(ctx, tunnel, metadata, M.Metadata{}, nil)
metadata := M.Metadata{}
if h.options.Dest != "" {
metadata.Destination = M.ParseAddress(h.options.Dest)
}
go h.router.RouteConnectionEx(ctx, tunnel, inboundMetadata, metadata, nil)
return tunnel
}