feat: 添加在线设备统计功能并优化订阅相关逻辑

- 在DeviceManager中添加GetOnlineDeviceCount方法用于获取在线设备数
- 在统计接口中增加在线设备数返回
- 优化订阅查询逻辑,增加服务组关联节点数量计算
- 添加AnyTLS协议支持及相关URI生成功能
- 重构邀请佣金计算逻辑,支持首购/年付/非首购不同比例
- 修复用户基本信息更新中IsAdmin和Enable字段类型不匹配问题
- 更新数据库迁移脚本和配置文件中邀请相关配置项
This commit is contained in:
2025-08-12 07:46:45 -07:00
parent c8de30f78c
commit a52c7142ee
16 changed files with 224 additions and 27 deletions
+32
View File
@@ -63,6 +63,8 @@ func buildProxy(data proxy.Proxy, uuid string) string {
return Hysteria2Uri(data, uuid)
case "tuic":
return TuicUri(data, uuid)
case "anytls":
return AnyTLSUri(data, uuid)
default:
return ""
}
@@ -271,6 +273,36 @@ func TuicUri(data proxy.Proxy, uuid string) string {
return u.String()
}
func AnyTLSUri(data proxy.Proxy, uuid string) string {
anytls, ok := data.Option.(proxy.AnyTLS)
if !ok {
return ""
}
securityConfig := anytls.SecurityConfig
var query = make(url.Values)
// 根据AnyTLS官方URI规范实现
// 格式: anytls://[auth@]hostname[:port]/?[key=value]&[key=value]...
// TLS配置
setQuery(&query, "sni", securityConfig.SNI)
// 是否允许不安全连接
if securityConfig.AllowInsecure {
setQuery(&query, "insecure", "1")
}
u := url.URL{
Scheme: "anytls",
User: url.User(uuid),
Host: net.JoinHostPort(data.Server, strconv.Itoa(anytls.Port)),
RawQuery: query.Encode(),
Fragment: data.Name,
}
return u.String()
}
func setQuery(q *url.Values, k, v string) {
if v != "" {
q.Set(k, v)
+13
View File
@@ -2,6 +2,7 @@ package adapter
import (
"encoding/json"
"fmt"
"log"
"strings"
@@ -83,7 +84,19 @@ func addNode(data *server.Server, host string, port int) *proxy.Proxy {
node.Port = tuic.Port
}
option = tuic
case "anytls":
var anytls proxy.AnyTLS
if err := json.Unmarshal([]byte(data.Config), &anytls); err != nil {
logger.Errorw("解析AnyTLS配置失败", logger.Field("error", err.Error()), logger.Field("node", data.Name))
return nil
}
if port == 0 {
node.Port = anytls.Port
}
option = anytls
logger.Infow("成功处理AnyTLS节点", logger.Field("node", data.Name), logger.Field("port", anytls.Port))
default:
fmt.Printf("[Error] 不支持的协议: %s", data.Protocol)
return nil
}
node.Option = option
+5
View File
@@ -340,6 +340,11 @@ func (dm *DeviceManager) Broadcast(message string) {
}
// GetOnlineDeviceCount returns the total number of online devices
func (dm *DeviceManager) GetOnlineDeviceCount() int64 {
return int64(atomic.LoadInt32(&dm.totalOnline))
}
// Gracefully shut down all WebSocket connections
func (dm *DeviceManager) Shutdown(ctx context.Context) {
<-ctx.Done()