package conf import ( "encoding/json" "strings" v2net "v2ray.com/core/common/net" "v2ray.com/core/common/protocol" ) type StringList []string func NewStringList(raw []string) *StringList { list := StringList(raw) return &list } func (v StringList) Len() int { return len(v) } func (v *StringList) UnmarshalJSON(data []byte) error { var strarray []string if err := json.Unmarshal(data, &strarray); err == nil { *v = *NewStringList(strarray) return nil } var rawstr string if err := json.Unmarshal(data, &rawstr); err == nil { strlist := strings.Split(rawstr, ",") *v = *NewStringList(strlist) return nil } return newError("unknown format of a string list: " + string(data)) } type Address struct { v2net.Address } func (v *Address) UnmarshalJSON(data []byte) error { var rawStr string if err := json.Unmarshal(data, &rawStr); err != nil { return err } v.Address = v2net.ParseAddress(rawStr) return nil } func (v *Address) Build() *v2net.IPOrDomain { return v2net.NewIPOrDomain(v.Address) } type Network string func (v Network) Build() v2net.Network { return v2net.ParseNetwork(string(v)) } type NetworkList []Network func (v *NetworkList) UnmarshalJSON(data []byte) error { var strarray []Network if err := json.Unmarshal(data, &strarray); err == nil { nl := NetworkList(strarray) *v = nl return nil } var rawstr Network if err := json.Unmarshal(data, &rawstr); err == nil { strlist := strings.Split(string(rawstr), ",") nl := make([]Network, len(strlist)) for idx, network := range strlist { nl[idx] = Network(network) } *v = nl return nil } return newError("unknown format of a string list: " + string(data)) } func (v *NetworkList) Build() *v2net.NetworkList { if v == nil { return &v2net.NetworkList{ Network: []v2net.Network{v2net.Network_TCP}, } } list := new(v2net.NetworkList) for _, network := range *v { list.Network = append(list.Network, network.Build()) } return list } func parseIntPort(data []byte) (v2net.Port, error) { var intPort uint32 err := json.Unmarshal(data, &intPort) if err != nil { return v2net.Port(0), err } return v2net.PortFromInt(intPort) } func parseStringPort(data []byte) (v2net.Port, v2net.Port, error) { var s string err := json.Unmarshal(data, &s) if err != nil { return v2net.Port(0), v2net.Port(0), err } pair := strings.SplitN(s, "-", 2) if len(pair) == 0 { return v2net.Port(0), v2net.Port(0), newError("Config: Invalid port range: ", s) } if len(pair) == 1 { port, err := v2net.PortFromString(pair[0]) return port, port, err } fromPort, err := v2net.PortFromString(pair[0]) if err != nil { return v2net.Port(0), v2net.Port(0), err } toPort, err := v2net.PortFromString(pair[1]) if err != nil { return v2net.Port(0), v2net.Port(0), err } return fromPort, toPort, nil } type PortRange struct { From uint32 To uint32 } func (v *PortRange) Build() *v2net.PortRange { return &v2net.PortRange{ From: v.From, To: v.To, } } // UnmarshalJSON implements encoding/json.Unmarshaler.UnmarshalJSON func (v *PortRange) UnmarshalJSON(data []byte) error { port, err := parseIntPort(data) if err == nil { v.From = uint32(port) v.To = uint32(port) return nil } from, to, err := parseStringPort(data) if err == nil { v.From = uint32(from) v.To = uint32(to) if v.From > v.To { return newError("invalid port range ", v.From, " -> ", v.To) } return nil } return newError("invalid port range: ", string(data)) } type User struct { EmailString string `json:"email"` LevelByte byte `json:"level"` } func (v *User) Build() *protocol.User { return &protocol.User{ Email: v.EmailString, Level: uint32(v.LevelByte), } }