package plugin import ( "context" "encoding/json" "fmt" "io/fs" "os" "path/filepath" "plugin" "reflect" "runtime" "strconv" "strings" "sync" ) // Plugin 插件接口 type Plugin interface { // Name 插件名称 Name() string // Version 插件版本 Version() string // Description 插件描述 Description() string // Author 插件作者 Author() string // Type 插件类型 Type() PluginType // Init 初始化插件 Init(ctx context.Context, config map[string]interface{}) error // Start 启动插件 Start(ctx context.Context) error // Stop 停止插件 Stop(ctx context.Context) error // IsEnabled 插件是否启用 IsEnabled() bool // SetEnabled 设置插件启用状态 SetEnabled(enabled bool) // Execute 执行插件功能 // action: 要执行的操作名称 // params: 操作所需的参数 // 返回操作结果和可能的错误 Execute(ctx context.Context, action string, params map[string]interface{}) (interface{}, error) // GetOperationInfo 获取操作的参数信息 GetOperationInfo(operation string) (map[string]interface{}, error) // GetAllOperations 获取所有操作及其参数信息 GetAllOperations() map[string]map[string]interface{} } // PluginHelper 插件辅助器 // 用于自动发现和注册插件方法,简化Execute方法的实现 type PluginHelper struct { instance interface{} // 插件实例 methods map[string]reflect.Method // 注册的方法 methodParams map[string][]reflect.Type // 方法的参数类型 methodRetValues map[string][]reflect.Type // 方法的返回值类型 } // NewPluginHelper 创建一个新的插件辅助器 func NewPluginHelper(instance interface{}) *PluginHelper { helper := &PluginHelper{ instance: instance, methods: make(map[string]reflect.Method), methodParams: make(map[string][]reflect.Type), methodRetValues: make(map[string][]reflect.Type), } helper.discoverMethods() return helper } // discoverMethods 发现插件的所有可用方法 func (h *PluginHelper) discoverMethods() { instanceType := reflect.TypeOf(h.instance) // 遍历实例的所有方法 for i := 0; i < instanceType.NumMethod(); i++ { method := instanceType.Method(i) // 跳过特定的内部方法和接口方法 if shouldSkipMethod(method.Name) { continue } // 获取方法的参数和返回值类型 var paramTypes []reflect.Type var returnTypes []reflect.Type // 跳过接收者参数 (第一个参数) for j := 1; j < method.Type.NumIn(); j++ { paramTypes = append(paramTypes, method.Type.In(j)) } for j := 0; j < method.Type.NumOut(); j++ { returnTypes = append(returnTypes, method.Type.Out(j)) } // 注册方法 actionName := strings.ToLower(method.Name) h.methods[actionName] = method h.methodParams[actionName] = paramTypes h.methodRetValues[actionName] = returnTypes } } // shouldSkipMethod 检查是否应该跳过某些方法 func shouldSkipMethod(name string) bool { // 跳过Plugin接口的方法和特定的内部方法 skipMethods := map[string]bool{ "Name": true, "Version": true, "Description": true, "Author": true, "Type": true, "Init": true, "Start": true, "Stop": true, "IsEnabled": true, "SetEnabled": true, "Execute": true, } return skipMethods[name] } // GetAvailableActions 获取所有可用的动作 func (h *PluginHelper) GetAvailableActions() []string { actions := make([]string, 0, len(h.methods)) for action := range h.methods { actions = append(actions, action) } return actions } // ValidateParams 验证传入的参数是否符合操作的参数定义 func ValidateParams(paramsDef map[string]interface{}, params map[string]interface{}) error { // 检查参数定义是否存在 if paramsDef == nil { return nil // 没有参数定义,不需要验证 } // 获取参数定义中的每个参数 paramsInfo, ok := paramsDef["parameters"].(map[string]interface{}) if !ok { return nil // 参数定义格式不正确,跳过验证 } // 遍历每个参数定义进行验证 errors := make([]string, 0) for paramName, paramInfo := range paramsInfo { info, ok := paramInfo.(map[string]interface{}) if !ok { continue // 参数信息格式不正确,跳过 } // 检查是否为必需参数 required, ok := info["required"].(bool) if ok && required { // 对于结构体参数,要检查至少有一个字段被提供 if info["type"] == "struct" { // 结构体参数的验证 if fields, ok := info["fields"].(map[string]interface{}); ok { // 检查必填的结构体字段 for fieldName, fieldInfo := range fields { if fieldInfoMap, ok := fieldInfo.(map[string]interface{}); ok { fieldRequired, ok := fieldInfoMap["required"].(bool) if ok && fieldRequired { if _, exists := params[fieldName]; !exists { errors = append(errors, fmt.Sprintf("缺少必需的结构体字段: %s", fieldName)) } } } } } } else { // 普通参数验证是否存在 if _, exists := params[paramName]; !exists { errors = append(errors, fmt.Sprintf("缺少必需参数: %s", paramName)) } } } // 如果参数存在,验证其类型 if value, exists := params[paramName]; exists && info["type"] != nil { expectedType := info["type"].(string) // 根据期望的类型验证参数 switch expectedType { case "string": if _, ok := value.(string); !ok { errors = append(errors, fmt.Sprintf("参数 %s 类型错误,应为字符串", paramName)) } case "integer": // 支持多种整数类型 switch value.(type) { case int, int8, int16, int32, int64, uint, uint8, uint16, uint32, uint64: // 这些类型都是可接受的 default: errors = append(errors, fmt.Sprintf("参数 %s 类型错误,应为整数", paramName)) } case "float": switch value.(type) { case float32, float64: // 这些类型是可接受的 default: errors = append(errors, fmt.Sprintf("参数 %s 类型错误,应为浮点数", paramName)) } case "boolean": if _, ok := value.(bool); !ok { errors = append(errors, fmt.Sprintf("参数 %s 类型错误,应为布尔值", paramName)) } case "array": if _, ok := value.([]interface{}); !ok { errors = append(errors, fmt.Sprintf("参数 %s 类型错误,应为数组", paramName)) } case "object": if _, ok := value.(map[string]interface{}); !ok { errors = append(errors, fmt.Sprintf("参数 %s 类型错误,应为对象", paramName)) } } } } // 如果有错误,返回组合的错误信息 if len(errors) > 0 { return fmt.Errorf("参数验证失败: %s", strings.Join(errors, "; ")) } return nil } // ExecuteAction 执行指定的动作 func (h *PluginHelper) ExecuteAction(ctx context.Context, action string, params map[string]interface{}) (interface{}, error) { // 转换为小写以实现不区分大小写的匹配 action = strings.ToLower(action) method, exists := h.methods[action] if !exists { return nil, fmt.Errorf("未知的操作: %s", action) } // 获取操作的参数信息并验证参数 opInfo, err := h.GetParameterInfo(action) if err == nil { // 验证参数 if err := ValidateParams(opInfo, params); err != nil { return nil, err } } paramTypes := h.methodParams[action] // 准备参数 var args []reflect.Value // 添加接收者参数 args = append(args, reflect.ValueOf(h.instance)) // 处理context参数 if len(paramTypes) > 0 && paramTypes[0].String() == "context.Context" { args = append(args, reflect.ValueOf(ctx)) paramTypes = paramTypes[1:] // 移除已处理的context参数 } // 处理其他参数 for i, paramType := range paramTypes { paramName := fmt.Sprintf("arg%d", i) // 如果是结构体参数,尝试将整个params映射转换为该结构体 if paramType.Kind() == reflect.Struct { structValue := reflect.New(paramType).Elem() if err := mapToStruct(params, structValue); err != nil { return nil, fmt.Errorf("转换参数失败: %v", err) } args = append(args, structValue) continue } // 从params中获取参数 paramValue, ok := params[paramName] if !ok { // 尝试使用参数类型名称作为键 typeName := paramType.Name() paramValue, ok = params[strings.ToLower(typeName)] if !ok { return nil, fmt.Errorf("缺少必需参数: %s", paramName) } } // 转换参数类型 convertedValue, err := convertParamValue(paramValue, paramType) if err != nil { return nil, err } args = append(args, convertedValue) } // 调用方法 result := method.Func.Call(args) // 处理返回值 if len(result) == 0 { return nil, nil } else if len(result) == 1 { return result[0].Interface(), nil } else { // 处理多个返回值,通常最后一个是error lastIndex := len(result) - 1 if result[lastIndex].Type().Implements(reflect.TypeOf((*error)(nil)).Elem()) { if !result[lastIndex].IsNil() { return nil, result[lastIndex].Interface().(error) } if lastIndex == 0 { return nil, nil } return result[lastIndex-1].Interface(), nil } // 将所有返回值打包成一个映射 resultMap := make(map[string]interface{}) for i, v := range result { resultMap[fmt.Sprintf("result%d", i)] = v.Interface() } return resultMap, nil } } // mapToStruct 将map转换为结构体 func mapToStruct(m map[string]interface{}, structValue reflect.Value) error { structType := structValue.Type() for i := 0; i < structType.NumField(); i++ { field := structType.Field(i) fieldValue := structValue.Field(i) if !fieldValue.CanSet() { continue } // 尝试不同的命名方式 fieldName := field.Name jsonTag := field.Tag.Get("json") if jsonTag != "" && jsonTag != "-" { parts := strings.Split(jsonTag, ",") fieldName = parts[0] } // 检查不同大小写 value, ok := m[fieldName] if !ok { value, ok = m[strings.ToLower(fieldName)] } if !ok { continue // 跳过未找到的字段 } // 转换并设置字段值 convertedValue, err := convertParamValue(value, field.Type) if err != nil { return err } fieldValue.Set(convertedValue) } return nil } // convertParamValue 将接口值转换为指定类型 func convertParamValue(value interface{}, targetType reflect.Type) (reflect.Value, error) { // 处理nil值 if value == nil { return reflect.Zero(targetType), nil } valueType := reflect.TypeOf(value) // 如果类型已经匹配,直接返回 if valueType.AssignableTo(targetType) { return reflect.ValueOf(value), nil } // 类型转换 switch targetType.Kind() { case reflect.String: return reflect.ValueOf(fmt.Sprintf("%v", value)), nil case reflect.Bool: switch v := value.(type) { case bool: return reflect.ValueOf(v), nil case string: b, err := strconv.ParseBool(v) if err != nil { return reflect.Value{}, fmt.Errorf("无法将 %v 转换为布尔值", value) } return reflect.ValueOf(b), nil case float64: return reflect.ValueOf(v != 0), nil } case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: var intVal int64 switch v := value.(type) { case int: intVal = int64(v) case int8: intVal = int64(v) case int16: intVal = int64(v) case int32: intVal = int64(v) case int64: intVal = v case float32: intVal = int64(v) case float64: intVal = int64(v) case string: var err error intVal, err = strconv.ParseInt(v, 10, 64) if err != nil { return reflect.Value{}, fmt.Errorf("无法将 %v 转换为整数", value) } default: return reflect.Value{}, fmt.Errorf("无法将 %v 转换为整数", value) } switch targetType.Kind() { case reflect.Int: return reflect.ValueOf(int(intVal)), nil case reflect.Int8: return reflect.ValueOf(int8(intVal)), nil case reflect.Int16: return reflect.ValueOf(int16(intVal)), nil case reflect.Int32: return reflect.ValueOf(int32(intVal)), nil case reflect.Int64: return reflect.ValueOf(intVal), nil } case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: var uintVal uint64 switch v := value.(type) { case uint: uintVal = uint64(v) case uint8: uintVal = uint64(v) case uint16: uintVal = uint64(v) case uint32: uintVal = uint64(v) case uint64: uintVal = v case int: if v < 0 { return reflect.Value{}, fmt.Errorf("无法将负数 %v 转换为无符号整数", value) } uintVal = uint64(v) case float64: if v < 0 { return reflect.Value{}, fmt.Errorf("无法将负数 %v 转换为无符号整数", value) } uintVal = uint64(v) case string: var err error uintVal, err = strconv.ParseUint(v, 10, 64) if err != nil { return reflect.Value{}, fmt.Errorf("无法将 %v 转换为无符号整数", value) } default: return reflect.Value{}, fmt.Errorf("无法将 %v 转换为无符号整数", value) } switch targetType.Kind() { case reflect.Uint: return reflect.ValueOf(uint(uintVal)), nil case reflect.Uint8: return reflect.ValueOf(uint8(uintVal)), nil case reflect.Uint16: return reflect.ValueOf(uint16(uintVal)), nil case reflect.Uint32: return reflect.ValueOf(uint32(uintVal)), nil case reflect.Uint64: return reflect.ValueOf(uintVal), nil } case reflect.Float32, reflect.Float64: var floatVal float64 switch v := value.(type) { case float32: floatVal = float64(v) case float64: floatVal = v case int: floatVal = float64(v) case int64: floatVal = float64(v) case string: var err error floatVal, err = strconv.ParseFloat(v, 64) if err != nil { return reflect.Value{}, fmt.Errorf("无法将 %v 转换为浮点数", value) } default: return reflect.Value{}, fmt.Errorf("无法将 %v 转换为浮点数", value) } if targetType.Kind() == reflect.Float32 { return reflect.ValueOf(float32(floatVal)), nil } return reflect.ValueOf(floatVal), nil case reflect.Slice: // 处理切片类型 srcVal := reflect.ValueOf(value) if srcVal.Kind() == reflect.Slice { // 创建目标类型的新切片 elemType := targetType.Elem() newSlice := reflect.MakeSlice(targetType, srcVal.Len(), srcVal.Cap()) // 转换每个元素 for i := 0; i < srcVal.Len(); i++ { elemValue, err := convertParamValue(srcVal.Index(i).Interface(), elemType) if err != nil { return reflect.Value{}, err } newSlice.Index(i).Set(elemValue) } return newSlice, nil } case reflect.Map: // 处理映射类型 srcVal := reflect.ValueOf(value) if srcVal.Kind() == reflect.Map { keyType := targetType.Key() elemType := targetType.Elem() newMap := reflect.MakeMap(targetType) iter := srcVal.MapRange() for iter.Next() { k := iter.Key() v := iter.Value() newKey, err := convertParamValue(k.Interface(), keyType) if err != nil { return reflect.Value{}, err } newValue, err := convertParamValue(v.Interface(), elemType) if err != nil { return reflect.Value{}, err } newMap.SetMapIndex(newKey, newValue) } return newMap, nil } case reflect.Ptr: // 处理指针类型 elemType := targetType.Elem() elemValue, err := convertParamValue(value, elemType) if err != nil { return reflect.Value{}, err } ptrValue := reflect.New(elemType) ptrValue.Elem().Set(elemValue) return ptrValue, nil } return reflect.Value{}, fmt.Errorf("不支持将 %T 类型转换为 %s", value, targetType) } // GetParameterInfo 获取操作的参数信息 func (h *PluginHelper) GetParameterInfo(action string) (map[string]interface{}, error) { action = strings.ToLower(action) method, exists := h.methods[action] if !exists { return nil, fmt.Errorf("未知的操作: %s", action) } paramTypes := h.methodParams[action] returnTypes := h.methodRetValues[action] result := map[string]interface{}{ "name": action, "description": fmt.Sprintf("%s 操作", method.Name), "parameters": make(map[string]interface{}), "returns": make(map[string]interface{}), } // 处理参数信息 paramsInfo := make(map[string]interface{}) // 首先检查是否有context参数 hasContext := false if len(paramTypes) > 0 && paramTypes[0].String() == "context.Context" { hasContext = true result["hasContext"] = true paramTypes = paramTypes[1:] // 跳过context参数 } for i, paramType := range paramTypes { // 如果是结构体参数,展开其字段 if paramType.Kind() == reflect.Struct { structInfo := getStructInfo(paramType) structInfo["position"] = i + 1 // 考虑到接收者和可能的context if hasContext { structInfo["position"] = i + 2 } paramsInfo[paramType.Name()] = structInfo } else { // 基本类型参数 paramName := fmt.Sprintf("arg%d", i) typeInfo := getTypeInfo(paramType) typeInfo["position"] = i + 1 // 考虑到接收者 if hasContext { typeInfo["position"] = i + 2 } paramsInfo[paramName] = typeInfo } } result["parameters"] = paramsInfo // 处理返回值信息 returnsInfo := make(map[string]interface{}) for i, returnType := range returnTypes { returnName := fmt.Sprintf("return%d", i) if i == len(returnTypes)-1 && returnType.String() == "error" { returnName = "error" } else if i == 0 && len(returnTypes) == 2 && returnTypes[1].String() == "error" { returnName = "result" } returnsInfo[returnName] = getTypeInfo(returnType) } result["returns"] = returnsInfo return result, nil } // getStructInfo 获取结构体类型的详细信息 func getStructInfo(t reflect.Type) map[string]interface{} { info := map[string]interface{}{ "type": "struct", "name": t.Name(), "package": t.PkgPath(), "fields": make(map[string]interface{}), "fieldCount": t.NumField(), } fields := make(map[string]interface{}) for i := 0; i < t.NumField(); i++ { field := t.Field(i) // 跳过非导出字段 if field.PkgPath != "" { continue } fieldName := field.Name jsonTag := field.Tag.Get("json") if jsonTag != "" && jsonTag != "-" { parts := strings.Split(jsonTag, ",") if parts[0] != "" { fieldName = parts[0] } } fieldInfo := getTypeInfo(field.Type) fieldInfo["name"] = field.Name fieldInfo["jsonName"] = fieldName fieldInfo["position"] = i fieldInfo["tags"] = string(field.Tag) fields[fieldName] = fieldInfo } info["fields"] = fields return info } // getTypeInfo 获取类型的基本信息 func getTypeInfo(t reflect.Type) map[string]interface{} { info := map[string]interface{}{ "typeName": t.String(), "kind": t.Kind().String(), "type": typeKindToString(t.Kind()), } // 为不同类型添加特定信息 switch t.Kind() { case reflect.Slice, reflect.Array: info["elemType"] = getTypeInfo(t.Elem()) case reflect.Map: info["keyType"] = getTypeInfo(t.Key()) info["valueType"] = getTypeInfo(t.Elem()) case reflect.Ptr: info["elemType"] = getTypeInfo(t.Elem()) case reflect.Struct: // 对于结构体,提供简略信息 info["structName"] = t.Name() info["package"] = t.PkgPath() info["fieldCount"] = t.NumField() } return info } // typeKindToString 将类型Kind转换为字符串表示 func typeKindToString(kind reflect.Kind) string { switch kind { case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: return "integer" case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: return "unsigned integer" case reflect.Float32, reflect.Float64: return "float" case reflect.Bool: return "boolean" case reflect.String: return "string" case reflect.Slice, reflect.Array: return "array" case reflect.Map: return "map" case reflect.Struct: return "object" case reflect.Ptr: return "pointer" case reflect.Interface: return "interface" default: return kind.String() } } // BasePluginImpl 提供插件接口的基本实现,用于适配Plugin接口 // 这个结构体包装了BasePlugin,以便兼容context参数 type BasePluginImpl struct { *BasePlugin helper *PluginHelper // 添加插件辅助器 } // NewPlugin 创建一个基本插件实现,带有插件类型 func NewPlugin(name, version, description, author string, pluginType PluginType) *BasePluginImpl { plugin := &BasePluginImpl{ BasePlugin: NewBasePlugin(name, version, description, author, pluginType), } plugin.helper = NewPluginHelper(plugin) return plugin } // NewPluginWithDefaultType 创建一个基本插件实现,使用默认的通用插件类型 func NewPluginWithDefaultType(name, version, description, author string) *BasePluginImpl { plugin := &BasePluginImpl{ BasePlugin: NewBasePluginWithDefaultType(name, version, description, author), } plugin.helper = NewPluginHelper(plugin) return plugin } // Init 适配Init方法以支持context参数 func (p *BasePluginImpl) Init(ctx context.Context, config map[string]interface{}) error { return p.BasePlugin.Init(config) } // Start 适配Start方法以支持context参数 func (p *BasePluginImpl) Start(ctx context.Context) error { return p.BasePlugin.Start() } // Stop 适配Stop方法以支持context参数 func (p *BasePluginImpl) Stop(ctx context.Context) error { return p.BasePlugin.Stop() } // Execute 通过辅助器自动执行插件方法 func (p *BasePluginImpl) Execute(ctx context.Context, action string, params map[string]interface{}) (interface{}, error) { // 首先尝试通过辅助器执行方法 result, err := p.helper.ExecuteAction(ctx, action, params) if err == nil { return result, nil } // 如果辅助器执行失败,检查错误类型 if strings.Contains(err.Error(), "未知的操作") { // 回退到基础实现 return p.BasePlugin.Execute(action, params) } return nil, err } // GetAvailableActions 获取插件支持的所有操作 func (p *BasePluginImpl) GetAvailableActions() []string { return p.helper.GetAvailableActions() } // GetOperationInfo 获取操作的参数信息 func (p *BasePluginImpl) GetOperationInfo(operation string) (map[string]interface{}, error) { return p.helper.GetParameterInfo(operation) } // GetAllOperations 获取所有操作及其参数信息 func (p *BasePluginImpl) GetAllOperations() map[string]map[string]interface{} { operations := make(map[string]map[string]interface{}) for _, action := range p.helper.GetAvailableActions() { info, err := p.helper.GetParameterInfo(action) if err == nil { operations[action] = info } } return operations } // PluginInfo 插件信息 type PluginInfo struct { Name string `json:"name"` Version string `json:"version"` Description string `json:"description"` Author string `json:"author"` Type PluginType `json:"type"` Enabled bool `json:"enabled"` Config map[string]interface{} `json:"config,omitempty"` } // PluginManager 插件管理器 type PluginManager struct { pluginsDir string plugins map[string]Plugin pluginsByType map[PluginType]map[string]Plugin configs map[string]map[string]interface{} mu sync.RWMutex dynamicLoadingSupported bool // 是否支持动态加载插件 } // NewPluginManager 创建插件管理器 func NewPluginManager(pluginsDir string) *PluginManager { // 检查当前系统是否支持动态加载插件 dynamicLoadingSupported := runtime.GOOS == "linux" || runtime.GOOS == "darwin" return &PluginManager{ pluginsDir: pluginsDir, plugins: make(map[string]Plugin), pluginsByType: make(map[PluginType]map[string]Plugin), configs: make(map[string]map[string]interface{}), dynamicLoadingSupported: dynamicLoadingSupported, } } // IsDynamicLoadingSupported 检查是否支持动态加载插件 func (pm *PluginManager) IsDynamicLoadingSupported() bool { return pm.dynamicLoadingSupported } // LoadPlugins 加载插件 func (pm *PluginManager) LoadPlugins() error { // 确保插件目录存在 if err := os.MkdirAll(pm.pluginsDir, 0o755); err != nil { return fmt.Errorf("创建插件目录失败: %v", err) } // 加载插件配置 if err := pm.loadPluginConfigs(); err != nil { return fmt.Errorf("加载插件配置失败: %v", err) } // 如果不支持动态加载,则返回 if !pm.dynamicLoadingSupported { fmt.Printf("警告: 当前系统(%s)不支持动态加载插件,跳过加载\n", runtime.GOOS) return nil } // 遍历插件目录 err := filepath.Walk(pm.pluginsDir, func(path string, info fs.FileInfo, err error) error { if err != nil { return err } // 跳过目录和非.so文件 if info.IsDir() || filepath.Ext(path) != ".so" { return nil } // 加载插件 if err := pm.loadPlugin(path); err != nil { fmt.Printf("加载插件 %s 失败: %v\n", path, err) } return nil }) return err } // loadPluginConfigs 加载插件配置 func (pm *PluginManager) loadPluginConfigs() error { configPath := filepath.Join(pm.pluginsDir, "plugins.json") // 如果配置文件不存在,创建一个空的 if _, err := os.Stat(configPath); os.IsNotExist(err) { file, err := os.Create(configPath) if err != nil { return fmt.Errorf("创建插件配置文件失败: %v", err) } file.Write([]byte("{}")) file.Close() return nil } // 读取配置文件 data, err := os.ReadFile(configPath) if err != nil { return fmt.Errorf("读取插件配置文件失败: %v", err) } // 解析配置 var configs map[string]map[string]interface{} if err := json.Unmarshal(data, &configs); err != nil { return fmt.Errorf("解析插件配置文件失败: %v", err) } pm.configs = configs return nil } // savePluginConfigs 保存插件配置 func (pm *PluginManager) savePluginConfigs() error { configPath := filepath.Join(pm.pluginsDir, "plugins.json") // 创建配置数据 configs := make(map[string]map[string]interface{}) pm.mu.RLock() for name, plugin := range pm.plugins { config := pm.configs[name] if config == nil { config = make(map[string]interface{}) } config["enabled"] = plugin.IsEnabled() config["type"] = string(plugin.Type()) // 保存插件类型 configs[name] = config } pm.mu.RUnlock() // 序列化配置 data, err := json.MarshalIndent(configs, "", " ") if err != nil { return fmt.Errorf("序列化插件配置失败: %v", err) } // 写入文件 if err := os.WriteFile(configPath, data, 0o644); err != nil { return fmt.Errorf("写入插件配置文件失败: %v", err) } return nil } // loadPlugin 加载单个插件 func (pm *PluginManager) loadPlugin(path string) error { // 打开插件文件 p, err := plugin.Open(path) if err != nil { return fmt.Errorf("打开插件失败: %v", err) } // 查找Plugin变量 symPlugin, err := p.Lookup("Plugin") if err != nil { return fmt.Errorf("查找Plugin变量失败: %v", err) } // 使用反射检查插件对象 pluginValue := reflect.ValueOf(symPlugin) fmt.Printf("加载插件: %s, 类型: %s\n", path, pluginValue.Type()) // 查找基本字段或方法 var pluginName, pluginVersion, pluginAuthor, pluginDesc string var pluginType PluginType = PluginTypeGeneral var enabled = true // 直接检查方法 // 尝试通过方法获取信息 nameFound := false if nameMethod := pluginValue.MethodByName("Name"); nameMethod.IsValid() { results := nameMethod.Call(nil) if len(results) > 0 && results[0].Kind() == reflect.String { pluginName = results[0].String() nameFound = true } } if versionMethod := pluginValue.MethodByName("Version"); versionMethod.IsValid() { results := versionMethod.Call(nil) if len(results) > 0 && results[0].Kind() == reflect.String { pluginVersion = results[0].String() } } if descMethod := pluginValue.MethodByName("Description"); descMethod.IsValid() { results := descMethod.Call(nil) if len(results) > 0 && results[0].Kind() == reflect.String { pluginDesc = results[0].String() } } if authorMethod := pluginValue.MethodByName("Author"); authorMethod.IsValid() { results := authorMethod.Call(nil) if len(results) > 0 && results[0].Kind() == reflect.String { pluginAuthor = results[0].String() } } if typeMethod := pluginValue.MethodByName("Type"); typeMethod.IsValid() { results := typeMethod.Call(nil) if len(results) > 0 { // 尝试匹配插件类型 typeStr := fmt.Sprint(results[0].Interface()) switch typeStr { case "storage": pluginType = PluginTypeStorage case "security": pluginType = PluginTypeSecurity case "network": pluginType = PluginTypeNetwork case "utils": pluginType = PluginTypeUtils case "hardware": pluginType = PluginTypeHardware case "ui": pluginType = PluginTypeUI } } } // 直接检查字段(仅在方法不可用时) if !nameFound && pluginValue.Kind() == reflect.Ptr && !pluginValue.IsNil() { elemValue := pluginValue.Elem() // 检查elemValue是否为结构体 if elemValue.Kind() == reflect.Struct { // 检查是否有name字段 if nameField := elemValue.FieldByName("name"); nameField.IsValid() && nameField.Kind() == reflect.String { pluginName = nameField.String() } // 检查是否有version字段 if versionField := elemValue.FieldByName("version"); versionField.IsValid() && versionField.Kind() == reflect.String { pluginVersion = versionField.String() } // 检查是否有description字段 if descField := elemValue.FieldByName("description"); descField.IsValid() && descField.Kind() == reflect.String { pluginDesc = descField.String() } // 检查是否有author字段 if authorField := elemValue.FieldByName("author"); authorField.IsValid() && authorField.Kind() == reflect.String { pluginAuthor = authorField.String() } // 检查是否有pluginType字段 if typeField := elemValue.FieldByName("pluginType"); typeField.IsValid() { // 转换为字符串并尝试匹配已知类型 typeStr := fmt.Sprint(typeField.Interface()) switch typeStr { case "storage": pluginType = PluginTypeStorage case "security": pluginType = PluginTypeSecurity case "network": pluginType = PluginTypeNetwork case "utils": pluginType = PluginTypeUtils case "hardware": pluginType = PluginTypeHardware case "ui": pluginType = PluginTypeUI } } // 检查是否有enabled字段 if enabledField := elemValue.FieldByName("enabled"); enabledField.IsValid() && enabledField.Kind() == reflect.Bool { enabled = enabledField.Bool() } } } // 如果名称仍为空,则使用文件名 if pluginName == "" { // 从路径中提取文件名并去掉扩展名 fileName := filepath.Base(path) pluginName = strings.TrimSuffix(fileName, filepath.Ext(fileName)) } fmt.Printf("创建适配器插件: 名称=%s, 版本=%s, 作者=%s, 类型=%s\n", pluginName, pluginVersion, pluginAuthor, pluginType) // 创建一个自定义插件结构体 customPlugin := &DynamicPlugin{ original: symPlugin, name: pluginName, version: pluginVersion, description: pluginDesc, author: pluginAuthor, pluginType: pluginType, enabled: enabled, } // 检查插件名称是否已存在 pm.mu.Lock() defer pm.mu.Unlock() if _, exists := pm.plugins[customPlugin.Name()]; exists { return fmt.Errorf("插件 %s 已存在", customPlugin.Name()) } // 设置插件启用状态 if config, exists := pm.configs[customPlugin.Name()]; exists { if enabled, ok := config["enabled"].(bool); ok { customPlugin.enabled = enabled } } // 注册插件 pm.registerPlugin(customPlugin) fmt.Printf("已成功注册插件: %s\n", customPlugin.Name()) return nil } // DynamicPlugin 完全动态的插件实现 type DynamicPlugin struct { original interface{} name string version string description string author string pluginType PluginType enabled bool } // Name 返回插件名称 func (p *DynamicPlugin) Name() string { return p.name } // Version 返回插件版本 func (p *DynamicPlugin) Version() string { return p.version } // Description 返回插件描述 func (p *DynamicPlugin) Description() string { return p.description } // Author 返回插件作者 func (p *DynamicPlugin) Author() string { return p.author } // Type 返回插件类型 func (p *DynamicPlugin) Type() PluginType { return p.pluginType } // IsEnabled 返回插件是否启用 func (p *DynamicPlugin) IsEnabled() bool { return p.enabled } // SetEnabled 设置插件启用状态 func (p *DynamicPlugin) SetEnabled(enabled bool) { p.enabled = enabled // 尝试调用原始插件的SetEnabled方法 method := reflect.ValueOf(p.original).MethodByName("SetEnabled") if method.IsValid() { method.Call([]reflect.Value{reflect.ValueOf(enabled)}) } } // Init 初始化插件 func (p *DynamicPlugin) Init(ctx context.Context, config map[string]interface{}) error { method := reflect.ValueOf(p.original).MethodByName("Init") if !method.IsValid() { return nil // 如果方法不存在,就不做任何事情 } // 确定方法参数数量和类型 methodType := method.Type() numParams := methodType.NumIn() // 准备参数 var args []reflect.Value // 对于不同参数数量的处理 switch numParams { case 0: // 无参数 case 1: // 只有一个参数,可能是配置 args = append(args, reflect.ValueOf(config)) case 2: // 两个参数,可能是上下文和配置 args = append(args, reflect.ValueOf(ctx), reflect.ValueOf(config)) default: // 不支持更多参数 return fmt.Errorf("不支持的Init方法参数数量: %d", numParams) } // 调用方法 results := method.Call(args) // 处理返回值 if len(results) > 0 && results[0].Type().Implements(reflect.TypeOf((*error)(nil)).Elem()) { if !results[0].IsNil() { return results[0].Interface().(error) } } return nil } // Start 启动插件 func (p *DynamicPlugin) Start(ctx context.Context) error { method := reflect.ValueOf(p.original).MethodByName("Start") if !method.IsValid() { return nil // 如果方法不存在,就不做任何事情 } // 确定方法参数数量和类型 methodType := method.Type() numParams := methodType.NumIn() // 准备参数 var args []reflect.Value // 对于不同参数数量的处理 switch numParams { case 0: // 无参数 case 1: // 一个参数,可能是上下文 args = append(args, reflect.ValueOf(ctx)) default: // 不支持更多参数 return fmt.Errorf("不支持的Start方法参数数量: %d", numParams) } // 调用方法 results := method.Call(args) // 处理返回值 if len(results) > 0 && results[0].Type().Implements(reflect.TypeOf((*error)(nil)).Elem()) { if !results[0].IsNil() { return results[0].Interface().(error) } } return nil } // Stop 停止插件 func (p *DynamicPlugin) Stop(ctx context.Context) error { method := reflect.ValueOf(p.original).MethodByName("Stop") if !method.IsValid() { return nil // 如果方法不存在,就不做任何事情 } // 确定方法参数数量和类型 methodType := method.Type() numParams := methodType.NumIn() // 准备参数 var args []reflect.Value // 对于不同参数数量的处理 switch numParams { case 0: // 无参数 case 1: // 一个参数,可能是上下文 args = append(args, reflect.ValueOf(ctx)) default: // 不支持更多参数 return fmt.Errorf("不支持的Stop方法参数数量: %d", numParams) } // 调用方法 results := method.Call(args) // 处理返回值 if len(results) > 0 && results[0].Type().Implements(reflect.TypeOf((*error)(nil)).Elem()) { if !results[0].IsNil() { return results[0].Interface().(error) } } return nil } // Execute 执行插件功能 func (p *DynamicPlugin) Execute(ctx context.Context, action string, params map[string]interface{}) (interface{}, error) { method := reflect.ValueOf(p.original).MethodByName("Execute") if !method.IsValid() { return nil, fmt.Errorf("插件不支持Execute方法") } // 确定方法参数数量和类型 methodType := method.Type() numParams := methodType.NumIn() // 准备参数 var args []reflect.Value // 对于不同参数数量的处理 switch numParams { case 2: // 两个参数,可能是action和params args = append(args, reflect.ValueOf(action), reflect.ValueOf(params)) case 3: // 三个参数,可能是ctx、action和params args = append(args, reflect.ValueOf(ctx), reflect.ValueOf(action), reflect.ValueOf(params)) default: // 不支持其他参数数量 return nil, fmt.Errorf("不支持的Execute方法参数数量: %d", numParams) } // 调用方法 results := method.Call(args) // 处理返回值 var result interface{} var err error switch len(results) { case 1: // 只有一个返回值,检查是否为错误 if results[0].Type().Implements(reflect.TypeOf((*error)(nil)).Elem()) { if !results[0].IsNil() { err = results[0].Interface().(error) } } else { result = results[0].Interface() } case 2: // 两个返回值,第一个是结果,第二个是错误 if !results[0].IsNil() { result = results[0].Interface() } if results[1].Type().Implements(reflect.TypeOf((*error)(nil)).Elem()) { if !results[1].IsNil() { err = results[1].Interface().(error) } } } return result, err } // GetOperationInfo 获取操作的参数信息 func (p *DynamicPlugin) GetOperationInfo(operation string) (map[string]interface{}, error) { method := reflect.ValueOf(p.original).MethodByName("GetOperationInfo") if !method.IsValid() { return map[string]interface{}{}, nil } results := method.Call([]reflect.Value{reflect.ValueOf(operation)}) var result map[string]interface{} var err error if len(results) > 0 && !results[0].IsNil() { if m, ok := results[0].Interface().(map[string]interface{}); ok { result = m } else { result = map[string]interface{}{} } } else { result = map[string]interface{}{} } if len(results) > 1 && results[1].Type().Implements(reflect.TypeOf((*error)(nil)).Elem()) { if !results[1].IsNil() { err = results[1].Interface().(error) } } return result, err } // GetAllOperations 获取所有操作及其参数信息 func (p *DynamicPlugin) GetAllOperations() map[string]map[string]interface{} { method := reflect.ValueOf(p.original).MethodByName("GetAllOperations") if !method.IsValid() { return map[string]map[string]interface{}{} } results := method.Call(nil) if len(results) > 0 && !results[0].IsNil() { if m, ok := results[0].Interface().(map[string]map[string]interface{}); ok { return m } } return map[string]map[string]interface{}{} } // registerPlugin 注册插件到插件管理器 func (pm *PluginManager) registerPlugin(plugin Plugin) { pluginType := plugin.Type() // 将插件添加到按名称索引的映射 pm.plugins[plugin.Name()] = plugin // 将插件添加到按类型索引的映射 if pm.pluginsByType[pluginType] == nil { pm.pluginsByType[pluginType] = make(map[string]Plugin) } pm.pluginsByType[pluginType][plugin.Name()] = plugin } // RegisterPlugin 注册内置插件 // 用于在不支持动态加载的平台上注册插件 func (pm *PluginManager) RegisterPlugin(plugin Plugin) error { pm.mu.Lock() defer pm.mu.Unlock() if _, exists := pm.plugins[plugin.Name()]; exists { return fmt.Errorf("插件 %s 已存在", plugin.Name()) } // 设置插件启用状态 if config, exists := pm.configs[plugin.Name()]; exists { if enabled, ok := config["enabled"].(bool); ok { plugin.SetEnabled(enabled) } else { plugin.SetEnabled(true) // 默认启用 } } else { plugin.SetEnabled(true) // 默认启用 } // 注册插件 pm.registerPlugin(plugin) return nil } // GetPlugin 获取插件 func (pm *PluginManager) GetPlugin(name string) (Plugin, bool) { pm.mu.RLock() defer pm.mu.RUnlock() plugin, exists := pm.plugins[name] return plugin, exists } // GetPluginsByType 按类型获取插件 func (pm *PluginManager) GetPluginsByType(pluginType PluginType) []Plugin { pm.mu.RLock() defer pm.mu.RUnlock() plugins := make([]Plugin, 0) if typePlugins, exists := pm.pluginsByType[pluginType]; exists { for _, plugin := range typePlugins { if plugin.IsEnabled() { plugins = append(plugins, plugin) } } } return plugins } // GetAllPluginsByType 获取所有指定类型的插件,无论是否启用 func (pm *PluginManager) GetAllPluginsByType(pluginType PluginType) []Plugin { pm.mu.RLock() defer pm.mu.RUnlock() plugins := make([]Plugin, 0) if typePlugins, exists := pm.pluginsByType[pluginType]; exists { for _, plugin := range typePlugins { plugins = append(plugins, plugin) } } return plugins } // GetAllPlugins 获取所有插件 func (pm *PluginManager) GetAllPlugins() []Plugin { pm.mu.RLock() defer pm.mu.RUnlock() plugins := make([]Plugin, 0, len(pm.plugins)) for _, plugin := range pm.plugins { plugins = append(plugins, plugin) } return plugins } // GetPluginInfos 获取所有插件信息 func (pm *PluginManager) GetPluginInfos() []PluginInfo { pm.mu.RLock() defer pm.mu.RUnlock() infos := make([]PluginInfo, 0, len(pm.plugins)) for name, plugin := range pm.plugins { info := PluginInfo{ Name: plugin.Name(), Version: plugin.Version(), Description: plugin.Description(), Author: plugin.Author(), Type: plugin.Type(), Enabled: plugin.IsEnabled(), Config: pm.configs[name], } infos = append(infos, info) } return infos } // GetPluginInfosByType 按类型获取插件信息 func (pm *PluginManager) GetPluginInfosByType(pluginType PluginType) []PluginInfo { pm.mu.RLock() defer pm.mu.RUnlock() infos := make([]PluginInfo, 0) if typePlugins, exists := pm.pluginsByType[pluginType]; exists { for name, plugin := range typePlugins { info := PluginInfo{ Name: plugin.Name(), Version: plugin.Version(), Description: plugin.Description(), Author: plugin.Author(), Type: plugin.Type(), Enabled: plugin.IsEnabled(), Config: pm.configs[name], } infos = append(infos, info) } } return infos } // EnablePlugin 启用插件 func (pm *PluginManager) EnablePlugin(name string) error { pm.mu.Lock() defer pm.mu.Unlock() plugin, exists := pm.plugins[name] if !exists { return fmt.Errorf("插件 %s 不存在", name) } plugin.SetEnabled(true) // 更新配置 if pm.configs[name] == nil { pm.configs[name] = make(map[string]interface{}) } pm.configs[name]["enabled"] = true // 保存配置 return pm.savePluginConfigs() } // DisablePlugin 禁用插件 func (pm *PluginManager) DisablePlugin(name string) error { pm.mu.Lock() defer pm.mu.Unlock() plugin, exists := pm.plugins[name] if !exists { return fmt.Errorf("插件 %s 不存在", name) } plugin.SetEnabled(false) // 更新配置 if pm.configs[name] == nil { pm.configs[name] = make(map[string]interface{}) } pm.configs[name]["enabled"] = false // 保存配置 return pm.savePluginConfigs() } // InitPlugins 初始化所有插件 func (pm *PluginManager) InitPlugins(ctx context.Context) error { pm.mu.RLock() defer pm.mu.RUnlock() for name, plugin := range pm.plugins { if !plugin.IsEnabled() { continue } config := pm.configs[name] if err := plugin.Init(ctx, config); err != nil { return fmt.Errorf("初始化插件 %s 失败: %v", name, err) } } return nil } // InitPluginsByType 初始化指定类型的所有插件 func (pm *PluginManager) InitPluginsByType(ctx context.Context, pluginType PluginType) error { pm.mu.RLock() defer pm.mu.RUnlock() if typePlugins, exists := pm.pluginsByType[pluginType]; exists { for name, plugin := range typePlugins { if !plugin.IsEnabled() { continue } config := pm.configs[name] if err := plugin.Init(ctx, config); err != nil { return fmt.Errorf("初始化插件 %s 失败: %v", name, err) } } } return nil } // StartPlugins 启动所有插件 func (pm *PluginManager) StartPlugins(ctx context.Context) error { pm.mu.RLock() defer pm.mu.RUnlock() for name, plugin := range pm.plugins { if !plugin.IsEnabled() { continue } if err := plugin.Start(ctx); err != nil { return fmt.Errorf("启动插件 %s 失败: %v", name, err) } } return nil } // StartPluginsByType 启动指定类型的所有插件 func (pm *PluginManager) StartPluginsByType(ctx context.Context, pluginType PluginType) error { pm.mu.RLock() defer pm.mu.RUnlock() if typePlugins, exists := pm.pluginsByType[pluginType]; exists { for name, plugin := range typePlugins { if !plugin.IsEnabled() { continue } if err := plugin.Start(ctx); err != nil { return fmt.Errorf("启动插件 %s 失败: %v", name, err) } } } return nil } // StopPlugins 停止所有插件 func (pm *PluginManager) StopPlugins(ctx context.Context) error { pm.mu.RLock() defer pm.mu.RUnlock() for name, plugin := range pm.plugins { if !plugin.IsEnabled() { continue } if err := plugin.Stop(ctx); err != nil { return fmt.Errorf("停止插件 %s 失败: %v", name, err) } } return nil } // StopPluginsByType 停止指定类型的所有插件 func (pm *PluginManager) StopPluginsByType(ctx context.Context, pluginType PluginType) error { pm.mu.RLock() defer pm.mu.RUnlock() if typePlugins, exists := pm.pluginsByType[pluginType]; exists { for name, plugin := range typePlugins { if !plugin.IsEnabled() { continue } if err := plugin.Stop(ctx); err != nil { return fmt.Errorf("停止插件 %s 失败: %v", name, err) } } } return nil } // SetPluginConfig 设置插件配置 func (pm *PluginManager) SetPluginConfig(name string, config map[string]interface{}) error { pm.mu.Lock() defer pm.mu.Unlock() if _, exists := pm.plugins[name]; !exists { return fmt.Errorf("插件 %s 不存在", name) } pm.configs[name] = config return pm.savePluginConfigs() } // GetPluginConfig 获取插件配置 func (pm *PluginManager) GetPluginConfig(name string) (map[string]interface{}, error) { pm.mu.RLock() defer pm.mu.RUnlock() if _, exists := pm.plugins[name]; !exists { return nil, fmt.Errorf("插件 %s 不存在", name) } config := pm.configs[name] if config == nil { config = make(map[string]interface{}) } return config, nil } // ExecutePlugin 执行指定插件的操作 func (pm *PluginManager) ExecutePlugin(ctx context.Context, name string, action string, params map[string]interface{}) (interface{}, error) { pm.mu.RLock() defer pm.mu.RUnlock() plugin, exists := pm.plugins[name] if !exists { return nil, fmt.Errorf("插件 %s 不存在", name) } if !plugin.IsEnabled() { return nil, fmt.Errorf("插件 %s 已禁用", name) } return plugin.Execute(ctx, action, params) } // ExecutePluginsByType 对指定类型的所有插件执行操作 func (pm *PluginManager) ExecutePluginsByType(ctx context.Context, pluginType PluginType, action string, params map[string]interface{}) map[string]interface{} { pm.mu.RLock() defer pm.mu.RUnlock() results := make(map[string]interface{}) if typePlugins, exists := pm.pluginsByType[pluginType]; exists { for name, plugin := range typePlugins { if !plugin.IsEnabled() { continue } result, err := plugin.Execute(ctx, action, params) results[name] = map[string]interface{}{ "result": result, "error": err, } } } return results } // ExecuteAllPlugins 对所有插件执行操作 func (pm *PluginManager) ExecuteAllPlugins(ctx context.Context, action string, params map[string]interface{}) map[string]interface{} { pm.mu.RLock() defer pm.mu.RUnlock() results := make(map[string]interface{}) for name, plugin := range pm.plugins { if !plugin.IsEnabled() { continue } result, err := plugin.Execute(ctx, action, params) results[name] = map[string]interface{}{ "result": result, "error": err, } } return results } // GetPluginOperationInfo 获取插件特定操作的参数信息 func (pm *PluginManager) GetPluginOperationInfo(name string, operation string) (map[string]interface{}, error) { pm.mu.RLock() defer pm.mu.RUnlock() plugin, exists := pm.plugins[name] if !exists { return nil, fmt.Errorf("插件 %s 不存在", name) } if !plugin.IsEnabled() { return nil, fmt.Errorf("插件 %s 已禁用", name) } return plugin.GetOperationInfo(operation) } // GetPluginAllOperations 获取插件所有操作及其参数信息 func (pm *PluginManager) GetPluginAllOperations(name string) (map[string]map[string]interface{}, error) { pm.mu.RLock() defer pm.mu.RUnlock() plugin, exists := pm.plugins[name] if !exists { return nil, fmt.Errorf("插件 %s 不存在", name) } if !plugin.IsEnabled() { return nil, fmt.Errorf("插件 %s 已禁用", name) } return plugin.GetAllOperations(), nil } // GetOperationsByType 获取指定类型插件的所有操作信息 func (pm *PluginManager) GetOperationsByType(pluginType PluginType) map[string]map[string]map[string]interface{} { pm.mu.RLock() defer pm.mu.RUnlock() result := make(map[string]map[string]map[string]interface{}) if typePlugins, exists := pm.pluginsByType[pluginType]; exists { for name, plugin := range typePlugins { if !plugin.IsEnabled() { continue } result[name] = plugin.GetAllOperations() } } return result } // GetAllPluginsOperations 获取所有插件的所有操作信息 func (pm *PluginManager) GetAllPluginsOperations() map[string]map[string]map[string]interface{} { pm.mu.RLock() defer pm.mu.RUnlock() result := make(map[string]map[string]map[string]interface{}) for name, plugin := range pm.plugins { if !plugin.IsEnabled() { continue } result[name] = plugin.GetAllOperations() } return result }