diff options
author | HimbeerserverDE <himbeerserverde@gmail.com> | 2021-09-05 19:19:27 +0200 |
---|---|---|
committer | HimbeerserverDE <himbeerserverde@gmail.com> | 2021-09-05 19:19:27 +0200 |
commit | 1de8660e9d4c8f14a3b887e6f137d1c44a2664ef (patch) | |
tree | e8e6d717300f7eaca9d94a4c1aa42c7755b86cbe | |
parent | e2815094d1a00476ad0ab051e812b12c795dd5d2 (diff) |
Add plugin API (#48)
-rw-r--r-- | client_conn.go | 44 | ||||
-rw-r--r-- | config.go | 4 | ||||
-rw-r--r-- | doc/config.md | 7 | ||||
-rw-r--r-- | log.go | 4 | ||||
-rw-r--r-- | main.go | 6 | ||||
-rw-r--r-- | plugin.go | 45 |
6 files changed, 107 insertions, 3 deletions
diff --git a/client_conn.go b/client_conn.go index 29db611..4898518 100644 --- a/client_conn.go +++ b/client_conn.go @@ -553,7 +553,49 @@ func handleClt(cc *clientConn) { cc.log("-->", "no server") break } - cc.server().SendCmd(cmd) + + var handled bool + if strings.HasPrefix(cmd.Msg, conf().CmdPrefix) { + substrs := strings.Split(cmd.Msg, " ") + cmdName := strings.Replace(substrs[0], conf().CmdPrefix, "", 1) + + var args []string + if len(substrs) > 1 { + args = substrs[1:] + } + + cc.log("-->", append([]string{"cmd", cmdName}, args...)) + + pluginsMu.RLock() + for _, p := range plugins { + sym, err := p.Lookup("HandleChatCmd") + if err != nil { + cc.log("-->", err) + continue + } + + if handler, ok := sym.(func(string, []string) bool); ok { + if handler(cmdName, args) { + handled = true + break + } + } + } + pluginsMu.RUnlock() + + if !handled { + cc.SendCmd(&mt.ToCltChatMsg{ + Type: mt.SysMsg, + Text: "Command not found.", + Timestamp: time.Now().Unix(), + }) + handled = true + } + } + + if !handled { + cc.server().SendCmd(cmd) + } case *mt.ToSrvDeletedBlks: if cc.server() == nil { cc.log("-->", "no server") @@ -14,6 +14,7 @@ const maxPlayerNameLen = 20 const playerNameChars = "^[a-zA-Z0-9-_]+$" const bytesPerMediaBunch = 5000 +const defaultCmdPrefix = ">" const defaultSendInterval = 0.09 const defaultUserLimit = 10 const defaultAuthBackend = "sqlite3" @@ -23,6 +24,8 @@ var config Config var configMu sync.RWMutex type Config struct { + NoPlugins bool + CmdPrefix string RequirePasswd bool SendInterval float32 UserLimit int @@ -56,6 +59,7 @@ func loadConfig() error { oldConf := config + config.CmdPrefix = defaultCmdPrefix config.SendInterval = defaultSendInterval config.UserLimit = defaultUserLimit config.AuthBackend = defaultAuthBackend diff --git a/doc/config.md b/doc/config.md index 39164ed..47ef4a6 100644 --- a/doc/config.md +++ b/doc/config.md @@ -5,6 +5,13 @@ The file name is `config.json`. ## Format The configuration file contains JSON data. The fields are as follows. +> `NoPlugins` +``` +Type: bool +Default: false +Description: Plugins are not loaded if this is true. +``` + > `RequirePasswd` ``` Type: bool @@ -22,13 +22,13 @@ func (lw *LogWriter) Write(p []byte) (n int, err error) { func init() { executable, err := os.Executable() if err != nil { - log.Fatal(err) + log.Fatal("{←|⇶} ", err) } path := filepath.Dir(executable) + "/latest.log" f, err := os.OpenFile(path, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0666) if err != nil { - log.Fatal(err) + log.Fatal("{←|⇶} ", err) } go func() { @@ -17,6 +17,12 @@ func main() { log.Fatal("{←|⇶} ", err) } + if !conf().NoPlugins { + if err := loadPlugins(); err != nil { + log.Fatal("{←|⇶} ", err) + } + } + var err error switch conf().AuthBackend { case "sqlite3": diff --git a/plugin.go b/plugin.go new file mode 100644 index 0000000..d4e3d27 --- /dev/null +++ b/plugin.go @@ -0,0 +1,45 @@ +package main + +import ( + "log" + "os" + "path/filepath" + "plugin" + "sync" +) + +var plugins []*plugin.Plugin +var pluginsMu sync.RWMutex + +func loadPlugins() error { + executable, err := os.Executable() + if err != nil { + return err + } + + path := filepath.Dir(executable) + "/plugins" + os.Mkdir(path, 0777) + + dir, err := os.ReadDir(path) + if err != nil { + return err + } + + pluginsMu.Lock() + defer pluginsMu.Unlock() + + plugins = []*plugin.Plugin{} + + for _, file := range dir { + p, err := plugin.Open(path + "/" + file.Name()) + if err != nil { + log.Print("{←|⇶} ", err) + continue + } + + plugins = append(plugins, p) + } + + log.Print("{←|⇶} load plugins") + return nil +} |