diff --git a/main/commands/all/convert/protobuf.go b/main/commands/all/convert/protobuf.go index c77df963..74272c57 100644 --- a/main/commands/all/convert/protobuf.go +++ b/main/commands/all/convert/protobuf.go @@ -3,6 +3,7 @@ package convert import ( "fmt" "os" + "strings" "github.com/xtls/xray-core/common/cmdarg" creflect "github.com/xtls/xray-core/common/reflect" @@ -14,15 +15,18 @@ import ( var cmdProtobuf = &base.Command{ CustomFlags: true, - UsageLine: "{{.Exec}} convert pb [-debug] [-type] [json file] [json file] ...", + UsageLine: "{{.Exec}} convert pb [-outpbfile file] [-debug] [-type] [json file] [json file] ...", Short: "Convert multiple json configs to protobuf", Long: ` -Convert multiple json configs to protobuf. +Convert multiple configs to ProtoBuf. JSON, YAML and TOML can be used. Arguments: + -o file, -outpbfile file + Write the ProtoBuf output (eg. mix.pb) to specified file location. + -d, -debug - Show mix.pb as json. + Show mix.pb as JSON format. FOR DEBUGGING ONLY! DO NOT PASS THIS OUTPUT TO XRAY-CORE! @@ -31,16 +35,20 @@ Arguments: Examples: - {{.Exec}} convert pb config.json c1.json c2.json c3.json > mix.pb + {{.Exec}} convert pb -outpbfile output.pb config.json c1.json c2.json c3.json + {{.Exec}} convert pb -debug mix.pb `, Run: executeConvertConfigsToProtobuf, } func executeConvertConfigsToProtobuf(cmd *base.Command, args []string) { + var optFile string var optDump bool var optType bool + cmd.Flag.StringVar(&optFile, "o", "", "") + cmd.Flag.StringVar(&optFile, "outpbfile", "", "") cmd.Flag.BoolVar(&optDump, "d", false, "") cmd.Flag.BoolVar(&optDump, "debug", false, "") cmd.Flag.BoolVar(&optType, "t", false, "") @@ -52,6 +60,17 @@ func executeConvertConfigsToProtobuf(cmd *base.Command, args []string) { unnamedArgs.Set(v) } + if len(optFile) > 0 { + switch core.GetFormatByExtension(getFileExtension(optFile)){ + case "protobuf", "": + fmt.Println("Output ProtoBuf file is ", optFile) + default: + base.Fatalf("-outpbfile followed by a possible original config.") + } + } else if !optDump { + base.Fatalf("-outpbfile not specified") + } + if len(unnamedArgs) < 1 { base.Fatalf("invalid config list length: %d", len(unnamedArgs)) } @@ -70,12 +89,28 @@ func executeConvertConfigsToProtobuf(cmd *base.Command, args []string) { } } - bytesConfig, err := proto.Marshal(pbConfig) - if err != nil { - base.Fatalf("failed to marshal proto config: %s", err) - } + if len(optFile) > 0 { + bytesConfig, err := proto.Marshal(pbConfig) + if err != nil { + base.Fatalf("failed to marshal proto config: %s", err) + } - if _, err := os.Stdout.Write(bytesConfig); err != nil { - base.Fatalf("failed to write proto config: %s", err) + f, err := os.Create(optFile) + if err != nil { + base.Fatalf("failed to create proto file: %s", err) + } + defer f.Close() + + if _, err := f.Write(bytesConfig); err != nil { + base.Fatalf("failed to write proto file: %s", err) + } } } + +func getFileExtension(filename string) string { + idx := strings.LastIndexByte(filename, '.') + if idx == -1 { + return "" + } + return filename[idx+1:] +}