Files
elmprodvpn/selective-vpn-api/app/transport_singbox_profiles_runtime_select.go

86 lines
1.8 KiB
Go

package app
import (
"sort"
"strings"
)
func findSingBoxProfileIndexForClient(st singBoxProfilesState, clientID string) int {
cid := sanitizeID(clientID)
if cid == "" {
return -1
}
best := -1
for i := range st.Items {
meta := st.Items[i].Meta
if meta == nil {
continue
}
if sanitizeID(asString(meta["client_id"])) != cid {
continue
}
if best < 0 || st.Items[i].ProfileRevision > st.Items[best].ProfileRevision {
best = i
}
}
if best >= 0 {
return best
}
for i := range st.Items {
if sanitizeID(st.Items[i].ID) == cid {
return i
}
}
if len(st.Items) == 1 {
return 0
}
return -1
}
func resolveSingBoxApplyClient(reqClientID, fallbackClientID string) (*TransportClient, string, string) {
target := strings.TrimSpace(reqClientID)
if target == "" {
target = strings.TrimSpace(fallbackClientID)
}
transportMu.Lock()
st := loadTransportClientsState()
transportMu.Unlock()
if len(st.Items) == 0 {
return nil, singBoxProfileCodeNoClient, "transport client not found"
}
if target != "" {
idx := findTransportClientIndex(st.Items, target)
if idx < 0 {
return nil, singBoxProfileCodeNoClient, "transport client not found"
}
cl := st.Items[idx]
if cl.Kind != TransportClientSingBox {
return nil, singBoxProfileCodeClientKind, "target client is not singbox"
}
return &cl, "", ""
}
candidates := make([]TransportClient, 0)
for _, it := range st.Items {
if it.Kind == TransportClientSingBox {
candidates = append(candidates, it)
}
}
if len(candidates) == 0 {
return nil, singBoxProfileCodeNoClient, "singbox client not found"
}
sort.Slice(candidates, func(i, j int) bool {
if candidates[i].Enabled != candidates[j].Enabled {
return candidates[i].Enabled
}
return candidates[i].ID < candidates[j].ID
})
cl := candidates[0]
return &cl, "", ""
}