package plugins import ( "log" "os" "path/filepath" lua "github.com/yuin/gopher-lua" ) // ActivatePlugin fully activates a plugin: creates Lua VM, loads main.lua, starts scheduler. func (m *Manager) ActivatePlugin(name string) { for i := range m.plugins { p := &m.plugins[i] if p.Meta.Name != name || p.Active { continue } p.Active = true vm, err := NewLuaVM(p) if err != nil { log.Printf("[plugins] %s: activate VM error: %v", name, err) p.Active = false return } p.vm = vm mainPath := filepath.Join(p.Dir, "main.lua") if _, err := os.Stat(mainPath); err == nil { if err := vm.LoadScript("main.lua"); err != nil { log.Printf("[plugins] %s: load main.lua: %v", name, err) } } p.scheduler = NewScheduler(p, vm) for _, bg := range p.Meta.Background { if err := p.scheduler.AddTask(bg); err != nil { log.Printf("[plugins] %s: add task %s: %v", name, bg.ID, err) } } p.scheduler.Start() if hookName, ok := p.Meta.Hooks["on_init"]; ok { if err := vm.CallHook(hookName); err != nil { log.Printf("[plugins] %s: on_init error: %v", name, err) } } log.Printf("[plugins] %s: activated", name) return } } // DeactivatePlugin stops a plugin's runtime without removing it. func (m *Manager) DeactivatePlugin(name string) { for i := range m.plugins { p := &m.plugins[i] if p.Meta.Name != name || !p.Active { continue } if p.scheduler != nil { p.scheduler.Stop() p.scheduler = nil } if hookName, ok := p.Meta.Hooks["on_shutdown"]; ok && p.vm != nil { _ = p.vm.CallHook(hookName) } if p.vm != nil { p.vm.Close() p.vm = nil } p.Active = false log.Printf("[plugins] %s: deactivated", name) return } } // CallPluginHook calls a named Lua function on a specific plugin. func (m *Manager) CallPluginHook(name, hookName string, args ...lua.LValue) (lua.LValue, error) { for i := range m.plugins { if m.plugins[i].Meta.Name == name && m.plugins[i].Active && m.plugins[i].vm != nil { if fn, ok := m.plugins[i].Meta.Hooks[hookName]; ok { return m.plugins[i].vm.CallHookWithResult(fn, args...) } return m.plugins[i].vm.CallHookWithResult(hookName, args...) } } return lua.LNil, nil }