Hunter0x7c7
2022-08-11 a82f9cb69f63aaeba40c024960deda7d75b9fece
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
package v4
 
import (
    "encoding/json"
    "strings"
 
    "github.com/golang/protobuf/proto"
 
    "github.com/v2fly/v2ray-core/v5/common/protocol"
    "github.com/v2fly/v2ray-core/v5/common/serial"
    "github.com/v2fly/v2ray-core/v5/infra/conf/cfgcommon"
    "github.com/v2fly/v2ray-core/v5/proxy/vmess"
    "github.com/v2fly/v2ray-core/v5/proxy/vmess/inbound"
    "github.com/v2fly/v2ray-core/v5/proxy/vmess/outbound"
)
 
type VMessAccount struct {
    ID          string `json:"id"`
    AlterIds    uint16 `json:"alterId"`
    Security    string `json:"security"`
    Experiments string `json:"experiments"`
}
 
// Build implements Buildable
func (a *VMessAccount) Build() *vmess.Account {
    var st protocol.SecurityType
    switch strings.ToLower(a.Security) {
    case "aes-128-gcm":
        st = protocol.SecurityType_AES128_GCM
    case "chacha20-poly1305":
        st = protocol.SecurityType_CHACHA20_POLY1305
    case "auto":
        st = protocol.SecurityType_AUTO
    case "none":
        st = protocol.SecurityType_NONE
    case "zero":
        st = protocol.SecurityType_ZERO
    default:
        st = protocol.SecurityType_AUTO
    }
    return &vmess.Account{
        Id:      a.ID,
        AlterId: uint32(a.AlterIds),
        SecuritySettings: &protocol.SecurityConfig{
            Type: st,
        },
        TestsEnabled: a.Experiments,
    }
}
 
type VMessDetourConfig struct {
    ToTag string `json:"to"`
}
 
// Build implements Buildable
func (c *VMessDetourConfig) Build() *inbound.DetourConfig {
    return &inbound.DetourConfig{
        To: c.ToTag,
    }
}
 
type FeaturesConfig struct {
    Detour *VMessDetourConfig `json:"detour"`
}
 
type VMessDefaultConfig struct {
    AlterIDs uint16 `json:"alterId"`
    Level    byte   `json:"level"`
}
 
// Build implements Buildable
func (c *VMessDefaultConfig) Build() *inbound.DefaultConfig {
    config := new(inbound.DefaultConfig)
    config.AlterId = uint32(c.AlterIDs)
    config.Level = uint32(c.Level)
    return config
}
 
type VMessInboundConfig struct {
    Users        []json.RawMessage   `json:"clients"`
    Features     *FeaturesConfig     `json:"features"`
    Defaults     *VMessDefaultConfig `json:"default"`
    DetourConfig *VMessDetourConfig  `json:"detour"`
    SecureOnly   bool                `json:"disableInsecureEncryption"`
}
 
// Build implements Buildable
func (c *VMessInboundConfig) Build() (proto.Message, error) {
    config := &inbound.Config{
        SecureEncryptionOnly: c.SecureOnly,
    }
 
    if c.Defaults != nil {
        config.Default = c.Defaults.Build()
    }
 
    if c.DetourConfig != nil {
        config.Detour = c.DetourConfig.Build()
    } else if c.Features != nil && c.Features.Detour != nil {
        config.Detour = c.Features.Detour.Build()
    }
 
    config.User = make([]*protocol.User, len(c.Users))
    for idx, rawData := range c.Users {
        user := new(protocol.User)
        if err := json.Unmarshal(rawData, user); err != nil {
            return nil, newError("invalid VMess user").Base(err)
        }
        account := new(VMessAccount)
        if err := json.Unmarshal(rawData, account); err != nil {
            return nil, newError("invalid VMess user").Base(err)
        }
        user.Account = serial.ToTypedMessage(account.Build())
        config.User[idx] = user
    }
 
    return config, nil
}
 
type VMessOutboundTarget struct {
    Address *cfgcommon.Address `json:"address"`
    Port    uint16             `json:"port"`
    Users   []json.RawMessage  `json:"users"`
}
 
type VMessOutboundConfig struct {
    Receivers []*VMessOutboundTarget `json:"vnext"`
}
 
// Build implements Buildable
func (c *VMessOutboundConfig) Build() (proto.Message, error) {
    config := new(outbound.Config)
 
    if len(c.Receivers) == 0 {
        return nil, newError("0 VMess receiver configured")
    }
    serverSpecs := make([]*protocol.ServerEndpoint, len(c.Receivers))
    for idx, rec := range c.Receivers {
        if len(rec.Users) == 0 {
            return nil, newError("0 user configured for VMess outbound")
        }
        if rec.Address == nil {
            return nil, newError("address is not set in VMess outbound config")
        }
        spec := &protocol.ServerEndpoint{
            Address: rec.Address.Build(),
            Port:    uint32(rec.Port),
        }
        for _, rawUser := range rec.Users {
            user := new(protocol.User)
            if err := json.Unmarshal(rawUser, user); err != nil {
                return nil, newError("invalid VMess user").Base(err)
            }
            account := new(VMessAccount)
            if err := json.Unmarshal(rawUser, account); err != nil {
                return nil, newError("invalid VMess user").Base(err)
            }
            user.Account = serial.ToTypedMessage(account.Build())
            spec.User = append(spec.User, user)
        }
        serverSpecs[idx] = spec
    }
    config.Receiver = serverSpecs
    return config, nil
}