package sbproxy import ( "bytes" "context" "encoding/binary" "encoding/json" "io" "net" "github.com/sagernet/sing-box/adapter" N "github.com/sagernet/sing/common/network" ) func (h *Inbound) handleJavaConnection(ctx context.Context, conn net.Conn, metadata adapter.InboundContext, onClose N.CloseHandlerFunc) { _, _, err := ReadVarInt(conn) // packet len if err != nil { conn.Close() return } packetID, _, err := ReadVarInt(conn) if err != nil || packetID != 0x00 { conn.Close() return } ReadVarInt(conn) // protocol version ReadString(conn) // server address binary.Read(conn, binary.BigEndian, new(uint16)) nextState, _, _ := ReadVarInt(conn) switch nextState { case 1: // Status h.handleJavaStatus(conn) case 2: // Login h.handleJavaLogin(ctx, conn, metadata, onClose) default: conn.Close() } } func (h *Inbound) handleJavaStatus(conn net.Conn) { for { packetLen, _, err := ReadVarInt(conn) if err != nil { return } packetID, _, err := ReadVarInt(conn) if err != nil { return } if packetID == 0x00 { // Status Request motd := h.options.MOTD if motd == "" { motd = "A Minecraft Server" } ver := h.options.Version if ver == "" { ver = "1.20.1" } resp := map[string]any{ "version": map[string]any{"name": ver, "protocol": 763}, "players": map[string]any{"max": h.options.MaxPlayers, "online": 0, "sample": []any{}}, "description": map[string]any{"text": motd}, } data, _ := json.Marshal(resp) var body bytes.Buffer WriteVarInt(&body, 0x00) // Response ID WriteString(&body, string(data)) WriteVarInt(conn, int32(body.Len())) conn.Write(body.Bytes()) } else if packetID == 0x01 { // Ping var b [8]byte if _, err := io.ReadFull(conn, b[:]); err != nil { return } var body bytes.Buffer WriteVarInt(&body, 0x01) body.Write(b[:]) WriteVarInt(conn, int32(body.Len())) conn.Write(body.Bytes()) return } else { io.CopyN(io.Discard, conn, int64(packetLen)-1) } } } func (h *Inbound) handleJavaLogin(ctx context.Context, conn net.Conn, metadata adapter.InboundContext, onClose N.CloseHandlerFunc) { // Login Start _, _, err := ReadVarInt(conn) if err != nil { conn.Close() return } packetID, _, err := ReadVarInt(conn) if err != nil || packetID != 0x00 { conn.Close() return } user, _ := ReadString(conn) // Offline Mode: No encryption/auth sequence, just Login Success var loginSuccess bytes.Buffer WriteVarInt(&loginSuccess, 0x02) // Login Success ID // UUID (offline) loginSuccess.Write(make([]byte, 16)) WriteString(&loginSuccess, user) WriteVarInt(&loginSuccess, 0) // No properties WriteVarInt(conn, int32(loginSuccess.Len())) conn.Write(loginSuccess.Bytes()) h.handlePlay(ctx, conn, user, metadata, onClose) }