基本完善SBProxy-MC
This commit is contained in:
@@ -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 {}
|
||||
}
|
||||
|
||||
@@ -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) }
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user