platform: Add group expand status
This commit is contained in:
@@ -9,6 +9,7 @@ import (
|
||||
"github.com/sagernet/sing-box/adapter"
|
||||
"github.com/sagernet/sing-box/common/urltest"
|
||||
"github.com/sagernet/sing-box/outbound"
|
||||
E "github.com/sagernet/sing/common/exceptions"
|
||||
"github.com/sagernet/sing/common/rw"
|
||||
"github.com/sagernet/sing/service"
|
||||
)
|
||||
@@ -18,6 +19,7 @@ type OutboundGroup struct {
|
||||
Type string
|
||||
Selectable bool
|
||||
Selected string
|
||||
isExpand int8
|
||||
items []*OutboundGroupItem
|
||||
}
|
||||
|
||||
@@ -25,6 +27,19 @@ func (g *OutboundGroup) GetItems() OutboundGroupItemIterator {
|
||||
return newIterator(g.items)
|
||||
}
|
||||
|
||||
func (g *OutboundGroup) IsExpand() bool {
|
||||
switch g.isExpand {
|
||||
case -1:
|
||||
return g.Selectable
|
||||
case 0:
|
||||
return false
|
||||
case 1:
|
||||
return true
|
||||
default:
|
||||
panic("unexpected expand value")
|
||||
}
|
||||
}
|
||||
|
||||
type OutboundGroupIterator interface {
|
||||
Next() *OutboundGroup
|
||||
HasNext() bool
|
||||
@@ -114,6 +129,11 @@ func readGroups(reader io.Reader) (OutboundGroupIterator, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
err = binary.Read(reader, binary.BigEndian, &group.isExpand)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var itemLength uint16
|
||||
err = binary.Read(reader, binary.BigEndian, &itemLength)
|
||||
if err != nil {
|
||||
@@ -152,6 +172,10 @@ func readGroups(reader io.Reader) (OutboundGroupIterator, error) {
|
||||
|
||||
func writeGroups(writer io.Writer, boxService *BoxService) error {
|
||||
historyStorage := service.PtrFromContext[urltest.HistoryStorage](boxService.ctx)
|
||||
var cacheFile adapter.ClashCacheFile
|
||||
if clashServer := boxService.instance.Router().ClashServer(); clashServer != nil {
|
||||
cacheFile = clashServer.CacheFile()
|
||||
}
|
||||
|
||||
outbounds := boxService.instance.Router().Outbounds()
|
||||
var iGroups []adapter.OutboundGroup
|
||||
@@ -167,6 +191,15 @@ func writeGroups(writer io.Writer, boxService *BoxService) error {
|
||||
group.Type = iGroup.Type()
|
||||
_, group.Selectable = iGroup.(*outbound.Selector)
|
||||
group.Selected = iGroup.Now()
|
||||
if cacheFile != nil {
|
||||
if isExpand, loaded := cacheFile.LoadGroupExpand(group.Tag); !loaded {
|
||||
group.isExpand = -1
|
||||
} else if isExpand {
|
||||
group.isExpand = 1
|
||||
} else {
|
||||
group.isExpand = 0
|
||||
}
|
||||
}
|
||||
|
||||
for _, itemTag := range iGroup.All() {
|
||||
itemOutbound, isLoaded := boxService.instance.Router().Outbound(itemTag)
|
||||
@@ -207,6 +240,10 @@ func writeGroups(writer io.Writer, boxService *BoxService) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = binary.Write(writer, binary.BigEndian, group.isExpand)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = binary.Write(writer, binary.BigEndian, uint16(len(group.items)))
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -232,3 +269,50 @@ func writeGroups(writer io.Writer, boxService *BoxService) error {
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *CommandClient) SetGroupExpand(groupTag string, isExpand bool) error {
|
||||
conn, err := c.directConnect()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer conn.Close()
|
||||
err = binary.Write(conn, binary.BigEndian, uint8(CommandGroupExpand))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = rw.WriteVString(conn, groupTag)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = binary.Write(conn, binary.BigEndian, isExpand)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return readError(conn)
|
||||
}
|
||||
|
||||
func (s *CommandServer) handleSetGroupExpand(conn net.Conn) error {
|
||||
defer conn.Close()
|
||||
groupTag, err := rw.ReadVString(conn)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
var isExpand bool
|
||||
err = binary.Read(conn, binary.BigEndian, &isExpand)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
service := s.service
|
||||
if service == nil {
|
||||
return writeError(conn, E.New("service not ready"))
|
||||
}
|
||||
if clashServer := service.instance.Router().ClashServer(); clashServer != nil {
|
||||
if cacheFile := clashServer.CacheFile(); cacheFile != nil {
|
||||
err = cacheFile.StoreGroupExpand(groupTag, isExpand)
|
||||
if err != nil {
|
||||
return writeError(conn, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
return writeError(conn, nil)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user