package client import ( "time" CM "github.com/sagernet/sing-box/service/manager/constant" pb "github.com/sagernet/sing-box/service/manager_api/grpc/manager" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" ) func mapError(err error) error { if err == nil { return nil } if st, ok := status.FromError(err); ok && st.Code() == codes.NotFound { return CM.ErrNotFound } return err } func toIntSlice(values []int32) []int { out := make([]int, len(values)) for i, v := range values { out[i] = int(v) } return out } func toInt32Slice(values []int) []int32 { out := make([]int32, len(values)) for i, v := range values { out[i] = int32(v) } return out } func timeFromNano(ns int64) time.Time { return time.Unix(0, ns) } func convertSquad(v *pb.Squad) CM.Squad { return CM.Squad{ ID: int(v.GetId()), Name: v.GetName(), CreatedAt: timeFromNano(v.GetCreatedAt()), UpdatedAt: timeFromNano(v.GetUpdatedAt()), } } func convertNode(v *pb.Node) CM.Node { return CM.Node{ UUID: v.GetUuid(), Name: v.GetName(), SquadIDs: toIntSlice(v.GetSquadIds()), CreatedAt: timeFromNano(v.GetCreatedAt()), UpdatedAt: timeFromNano(v.GetUpdatedAt()), } } func convertUser(v *pb.User) CM.User { return CM.User{ ID: int(v.GetId()), SquadIDs: toIntSlice(v.GetSquadIds()), Username: v.GetUsername(), Inbound: v.GetInbound(), Type: v.GetType(), UUID: v.GetUuid(), Password: v.GetPassword(), Secret: v.GetSecret(), Flow: v.GetFlow(), AlterID: int(v.GetAlterId()), CreatedAt: timeFromNano(v.GetCreatedAt()), UpdatedAt: timeFromNano(v.GetUpdatedAt()), } } func convertBandwidthLimiter(v *pb.BandwidthLimiter) CM.BandwidthLimiter { return CM.BandwidthLimiter{ ID: int(v.GetId()), SquadIDs: toIntSlice(v.GetSquadIds()), Username: v.GetUsername(), Outbound: v.GetOutbound(), Strategy: v.GetStrategy(), ConnectionType: v.GetConnectionType(), Mode: v.GetMode(), FlowKeys: v.GetFlowKeys(), Speed: v.GetSpeed(), RawSpeed: v.GetRawSpeed(), CreatedAt: timeFromNano(v.GetCreatedAt()), UpdatedAt: timeFromNano(v.GetUpdatedAt()), } } func convertTrafficLimiter(v *pb.TrafficLimiter) CM.TrafficLimiter { return CM.TrafficLimiter{ ID: int(v.GetId()), SquadIDs: toIntSlice(v.GetSquadIds()), Username: v.GetUsername(), Outbound: v.GetOutbound(), Strategy: v.GetStrategy(), Mode: v.GetMode(), RawUsed: v.GetRawUsed(), Quota: v.GetQuota(), RawQuota: v.GetRawQuota(), CreatedAt: timeFromNano(v.GetCreatedAt()), UpdatedAt: timeFromNano(v.GetUpdatedAt()), } } func convertConnectionLimiter(v *pb.ConnectionLimiter) CM.ConnectionLimiter { return CM.ConnectionLimiter{ ID: int(v.GetId()), SquadIDs: toIntSlice(v.GetSquadIds()), Username: v.GetUsername(), Outbound: v.GetOutbound(), Strategy: v.GetStrategy(), ConnectionType: v.GetConnectionType(), LockType: v.GetLockType(), Count: v.GetCount(), CreatedAt: timeFromNano(v.GetCreatedAt()), UpdatedAt: timeFromNano(v.GetUpdatedAt()), } } func convertRateLimiter(v *pb.RateLimiter) CM.RateLimiter { return CM.RateLimiter{ ID: int(v.GetId()), SquadIDs: toIntSlice(v.GetSquadIds()), Username: v.GetUsername(), Outbound: v.GetOutbound(), Strategy: v.GetStrategy(), ConnectionType: v.GetConnectionType(), Count: v.GetCount(), Interval: v.GetInterval(), CreatedAt: timeFromNano(v.GetCreatedAt()), UpdatedAt: timeFromNano(v.GetUpdatedAt()), } } func convertFilters(filters map[string][]string) *pb.Filters { values := make(map[string]*pb.StringList, len(filters)) for k, v := range filters { values[k] = &pb.StringList{Values: append([]string(nil), v...)} } return &pb.Filters{Values: values} }