Jelajahi Sumber

prototype for plugins

Darien Raymond 8 tahun lalu
induk
melakukan
6069b77baa
3 mengubah file dengan 73 tambahan dan 0 penghapusan
  1. 12 0
      common/platform/platform.go
  2. 8 0
      main/main.go
  3. 53 0
      plugin.go

+ 12 - 0
common/platform/platform.go

@@ -53,8 +53,20 @@ func getExecutableDir() string {
 	return filepath.Dir(exec)
 }
 
+func getExecuableSubDir(dir string) func() string {
+	return func() string {
+		return filepath.Join(getExecutableDir(), dir)
+	}
+}
+
 func GetAssetLocation(file string) string {
 	const name = "v2ray.location.asset"
 	assetPath := EnvFlag{Name: name, AltName: NormalizeEnvName(name)}.GetValue(getExecutableDir)
 	return filepath.Join(assetPath, file)
 }
+
+func GetPluginDirectory() string {
+	const name = "v2ray.location.plugin"
+	pluginDir := EnvFlag{Name: name, AltName: NormalizeEnvName(name)}.GetValue(getExecuableSubDir("plugins"))
+	return pluginDir
+}

+ 8 - 0
main/main.go

@@ -22,6 +22,7 @@ var (
 	version    = flag.Bool("version", false, "Show current version of V2Ray.")
 	test       = flag.Bool("test", false, "Test config file only, without launching V2Ray server.")
 	format     = flag.String("format", "json", "Format of input file.")
+	plugin     = flag.Bool("plugin", false, "True to load plugins.")
 )
 
 func init() {
@@ -82,6 +83,13 @@ func main() {
 		return
 	}
 
+	if *plugin {
+		if err := core.LoadPlugins(); err != nil {
+			fmt.Println("Failed to load plugins:", err.Error())
+			return
+		}
+	}
+
 	server, err := startV2Ray()
 	if err != nil {
 		fmt.Println(err.Error())

+ 53 - 0
plugin.go

@@ -0,0 +1,53 @@
+package core
+
+import (
+	"os"
+	"path/filepath"
+	"plugin"
+	"strings"
+
+	"v2ray.com/core/app/log"
+	"v2ray.com/core/common/platform"
+)
+
+type PluginMetadata struct {
+	Name string
+}
+
+const GetMetadataFuncName = "GetPluginMetadata"
+
+type GetMetadataFunc func() PluginMetadata
+
+func LoadPlugins() error {
+	pluginPath := platform.GetPluginDirectory()
+
+	dir, err := os.Open(pluginPath)
+	if err != nil {
+		return err
+	}
+	defer dir.Close()
+
+	files, err := dir.Readdir(-1)
+	if err != nil {
+		return err
+	}
+
+	for _, file := range files {
+		if !file.IsDir() && strings.HasSuffix(file.Name(), ".so") {
+			p, err := plugin.Open(filepath.Join(pluginPath, file.Name()))
+			if err != nil {
+				return err
+			}
+			f, err := p.Lookup(GetMetadataFuncName)
+			if err != nil {
+				return err
+			}
+			if gmf, ok := f.(GetMetadataFunc); ok {
+				metadata := gmf()
+				log.Trace(newError("plugin (", metadata.Name, ") loaded."))
+			}
+		}
+	}
+
+	return nil
+}