forked from Ehco1996/v2scar
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathservices.go
102 lines (96 loc) · 2.92 KB
/
services.go
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
package v2scar
import (
"context"
"log"
"strings"
"github.com/golang/protobuf/proto"
v2proxyman "github.com/v2fly/v2ray-core/v4/app/proxyman/command"
v2stats "github.com/v2fly/v2ray-core/v4/app/stats/command"
"github.com/v2fly/v2ray-core/v4/common/protocol"
"github.com/v2fly/v2ray-core/v4/common/serial"
"github.com/v2fly/v2ray-core/v4/proxy/trojan"
"github.com/v2fly/v2ray-core/v4/proxy/vmess"
)
// GetAndResetUserTraffic 统计所有user的上行下行流量
// V2ray的stats的统计模块设计的非常奇怪,具体规则如下
// 上传流量:"user>>>" + user.Email + ">>>traffic>>>uplink"
// 下载流量:"user>>>" + user.Email + ">>>traffic>>>downlink"
func GetAndResetUserTraffic(c v2stats.StatsServiceClient, up *UserPool) {
req := &v2stats.QueryStatsRequest{
Pattern: "user>>>",
Reset_: true,
}
resp, err := c.QueryStats(context.Background(), req)
if err != nil {
log.Println("[ERROR]:", err)
} else {
for _, stat := range resp.Stat {
email, trafficType := getEmailAndTrafficType(stat.Name)
user, err := up.GetUserByEmail(email)
if err != nil {
log.Println(err)
} else {
switch trafficType {
case "uplink":
user.setUploadTraffic(stat.Value)
case "downlink":
user.setDownloadTraffic(stat.Value)
}
}
}
}
}
func getEmailAndTrafficType(input string) (string, string) {
s := strings.Split(input, ">>>")
return s[1], s[len(s)-1]
}
// AddInboundUser add user to inbound by tag
func AddInboundUser(c v2proxyman.HandlerServiceClient, tag string, user *User) {
var protoAccount proto.Message
if user.Trojan {
protoAccount = &trojan.Account{
Password: user.UUID,
}
} else {
protoAccount = &vmess.Account{
Id: user.UUID,
AlterId: user.AlterId,
SecuritySettings: &protocol.SecurityConfig{Type: protocol.SecurityType_AUTO},
}
}
_, err := c.AlterInbound(context.Background(), &v2proxyman.AlterInboundRequest{
Tag: tag,
Operation: serial.ToTypedMessage(&v2proxyman.AddUserOperation{
User: &protocol.User{
Level: user.Level,
Email: user.Email,
Account: serial.ToTypedMessage(protoAccount),
},
}),
})
if err != nil {
log.Println("[ERROR]:", err)
if strings.Contains(err.Error(), "already exists.") {
// TODO 优化这里的逻辑 这里针对side car重启而v2ray没重启的状态
user.setRunning(true)
}
} else {
log.Printf("[INFO] User: %v Add To V2ray Server Tag: %v", user.Email, tag)
user.setRunning(true)
}
}
//RemoveInboundUser remove user from inbound by tag
func RemoveInboundUser(c v2proxyman.HandlerServiceClient, tag string, user *User) {
_, err := c.AlterInbound(context.Background(), &v2proxyman.AlterInboundRequest{
Tag: tag,
Operation: serial.ToTypedMessage(&v2proxyman.RemoveUserOperation{
Email: user.Email,
}),
})
if err != nil {
log.Println("[ERROR]:", err)
} else {
log.Printf("[INFO] User: %v Removed From V2ray Server Tag: %v", user.Email, tag)
user.setRunning(false)
}
}