Welcome
Smallest complete Go plugin: one native and one hook.
- Kind
- Go reference
- Status
- reference implementation
- Natives
WelcomeCountWelcomeJoins- Hooks
player::connect
Enable
Add the path to server.plugins (or `plugins` in server.cfg).
knight
server.plugins = ["examples/plugins/welcome"];Workflow
flowchart LR A["plugin.Register in init()"] --> B["Init(api)"] B -->|RegisterNative| C["WelcomeCount / WelcomeJoins"] B -->|Hook| D["player::connect"] D --> E["Log the join"] C --> F["Gamemode reads counters"]
Source
examples/plugins/welcome/welcome.go
60 lines
go
// Package welcome is a reference Knight Go plugin.
//
// It shows the two things a plugin can do:
//
// - expose a native to .sa gamemodes (WelcomeCount)
// - observe/participate in an event with a hook (player::connect)
//
// Build it into a server by blank-importing this package from a small main:
//
// import _ "knight/examples/plugins/welcome"
package welcome
import (
"fmt"
"knight/pkg/plugin"
)
type welcome struct {
api plugin.API
joins int64
}
func init() { plugin.Register(func() plugin.Plugin { return &welcome{} }) }
func (w *welcome) Info() plugin.Info {
return plugin.Info{Name: "welcome", Version: "1.0.0", Author: "Knight examples"}
}
func (w *welcome) Init(api plugin.API) error {
w.api = api
// Callable from .sa: let n = WelcomeCount();
api.RegisterNative("WelcomeCount", w.count)
// Callable from .sa: let n = WelcomeJoins();
api.RegisterNative("WelcomeJoins", w.joinsSoFar)
// Runs before gamemode handlers thanks to PriorityEarly.
api.Hook("player::connect", plugin.PriorityEarly, w.onConnect)
return nil
}
func (w *welcome) onConnect(ctx plugin.Ctx) bool {
w.joins++
name, _ := ctx.PlayerName(int(ctx.Int(0)))
w.api.Log("welcome: %s joined (%d total)", name, w.joins)
return true // true = keep going; false would veto the event
}
func (w *welcome) count(ctx plugin.Ctx, args []plugin.Value) plugin.Value {
return plugin.IntV(int64(ctx.PlayerCount()))
}
func (w *welcome) joinsSoFar(ctx plugin.Ctx, args []plugin.Value) plugin.Value {
return plugin.IntV(w.joins)
}
func (w *welcome) Shutdown() {}
// Format is a helper used by the example tests.
func Format(name string) string { return fmt.Sprintf("Welcome, %s!", name) }