104 lines
2.5 KiB
Go
104 lines
2.5 KiB
Go
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.
|
|
// Only works if plugin is installed and enabled but not yet active.
|
|
func (m *Manager) ActivatePlugin(name string) {
|
|
for i := range m.plugins {
|
|
p := &m.plugins[i]
|
|
if p.Meta.Name != name || p.Active {
|
|
continue
|
|
}
|
|
if !p.Enabled {
|
|
log.Printf("[plugins] %s: cannot activate — not enabled", name)
|
|
return
|
|
}
|
|
if p.HasInstall && !p.Installed {
|
|
log.Printf("[plugins] %s: cannot activate — not installed", name)
|
|
return
|
|
}
|
|
|
|
vm, err := NewLuaVM(p)
|
|
if err != nil {
|
|
log.Printf("[plugins] %s: activate VM error: %v", name, err)
|
|
return
|
|
}
|
|
p.vm = vm
|
|
if m.Services != nil {
|
|
vm.SetServices(m.Services)
|
|
}
|
|
|
|
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)
|
|
}
|
|
}
|
|
|
|
p.Active = true
|
|
log.Printf("[plugins] %s: activated", name)
|
|
return
|
|
}
|
|
}
|
|
|
|
// DeactivatePlugin stops a plugin's runtime without removing it from enabled list.
|
|
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
|
|
}
|