Files
2026-07-02 13:10:12 +08:00

126 lines
3.2 KiB
Go

package serverObj
import (
"fmt"
jsoniter "github.com/json-iterator/go"
"github.com/v2rayA/v2rayA/conf"
"github.com/v2rayA/v2rayA/kernel/coreObj"
"github.com/v2rayA/v2rayA/pkg/util/log"
"os/exec"
"strconv"
"strings"
)
var ErrUnsupportedPlugin = fmt.Errorf("unsupported plugin")
const PluginManagerScheme = "plugin-manager"
func init() {
FromLinkRegister(PluginManagerScheme, NewPlugin)
EmptyRegister(PluginManagerScheme, func() (ServerObj, error) {
return new(Plugin), nil
})
}
type Plugin struct {
Name string `json:"pm_name"`
Host string `json:"pm_add"`
Port string `json:"pm_port"`
ProtocolToShow string `json:"pm_protocol"`
Link string `json:"pm_link"`
Protocol string `json:"protocol"`
}
func NewPlugin(link string) (ServerObj, error) {
if pm := conf.GetEnvironmentConfig().PluginManager; pm != "" {
b, err := exec.Command(pm,
"--stage=parse",
fmt.Sprintf("--link=%v", link),
fmt.Sprintf("--v2raya-confdir=%v", conf.GetEnvironmentConfig().Config),
).CombinedOutput()
if err != nil {
log.Info("[PluginManager] failed to parse %v: %v", link, string(b))
return nil, err
}
nExpected := 4
fields := strings.SplitN(strings.TrimSpace(string(b)), ";", nExpected)
if len(fields) < nExpected {
return nil, fmt.Errorf("[PluginManager] insufficient return value: %v. Expected number: %v", fields, nExpected)
}
return &Plugin{
Name: fields[0],
Host: fields[1],
Port: fields[2],
ProtocolToShow: fields[3],
Link: link,
Protocol: PluginManagerScheme,
}, nil
}
return nil, ErrUnsupportedPlugin
}
func (v *Plugin) Configuration(info PriorInfo) (c Configuration, err error) {
if pm := conf.GetEnvironmentConfig().PluginManager; pm != "" {
b, err := exec.Command(pm,
"--stage=configuration",
fmt.Sprintf("--link=%v", v.Link),
fmt.Sprintf("--port=%v", info.PluginPort),
fmt.Sprintf("--v2raya-confdir=%v", conf.GetEnvironmentConfig().Config),
).CombinedOutput()
sOut := strings.TrimSpace(string(b))
if err != nil {
return Configuration{}, fmt.Errorf("[PluginManager] Error when Configuration: %w: %v", err, sOut)
}
var core coreObj.OutboundObject
if err := jsoniter.UnmarshalFromString(sOut, &core); err != nil {
return Configuration{}, fmt.Errorf("[PluginManager] Error when Configuration: failed to parse json output")
}
core.Tag = info.Tag
return Configuration{
CoreOutbound: core,
PluginChain: "",
UDPSupport: true,
PluginManagerServerLink: v.Link,
}, nil
} else {
return Configuration{}, ErrUnsupportedPlugin
}
}
func (v *Plugin) ExportToURL() string {
if v.Link == "" {
log.Warn("You may need to re-import the node for PluginManager to take effect")
}
return v.Link
}
func (v *Plugin) NeedPluginPort() bool {
return true
}
func (v *Plugin) ProtoToShow() string {
return v.ProtocolToShow + "(plugin)"
}
func (v *Plugin) GetProtocol() string {
return v.ProtocolToShow
}
func (v *Plugin) GetHostname() string {
return v.Host
}
func (v *Plugin) GetPort() int {
p, _ := strconv.Atoi(v.Port)
return p
}
func (v *Plugin) GetName() string {
return v.Name
}
func (v *Plugin) SetName(name string) {
v.Name = name
}