Add plugin API (#48)
parent
e2815094d1
commit
1de8660e9d
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
4
log.go
4
log.go
|
@ -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() {
|
||||
|
|
6
main.go
6
main.go
|
@ -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":
|
||||
|
|
|
@ -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
|
||||
}
|
Loading…
Reference in New Issue