diff options
author | Himbeer <himbeer@disroot.org> | 2024-12-07 13:57:39 +0100 |
---|---|---|
committer | Himbeer <himbeer@disroot.org> | 2024-12-07 13:57:39 +0100 |
commit | 2fe0cd17e14473f0d7ffd5a1f5f100bd2419b018 (patch) | |
tree | 8ff7eb5375e9a9a59af4a6f1f6d0d0ee5f2c203e | |
parent | aee7c77cb835299f7e0a96bc971a182619f91296 (diff) |
Implement inventory plugin API
This change adds an API to retrieve a read-only copy of the current
inventory and listen for and modify inventory actions.
Closes #90.
-rw-r--r-- | plugin_inv.go | 45 | ||||
-rw-r--r-- | process.go | 11 |
2 files changed, 56 insertions, 0 deletions
diff --git a/plugin_inv.go b/plugin_inv.go new file mode 100644 index 0000000..6a8ffa5 --- /dev/null +++ b/plugin_inv.go @@ -0,0 +1,45 @@ +package proxy + +import ( + "bytes" + "sync" + + "github.com/HimbeerserverDE/mt" +) + +var ( + onInvAction []func(*ClientConn, string) string + onInvActionMu sync.RWMutex +) + +// Inv returns a copy of the current server-provided inventory of the client +// or nil if the client is not connected to a server. +func (cc *ClientConn) Inv() mt.Inv { + sc := cc.server() + if sc == nil { + return nil + } + + var ret mt.Inv + + sb := &bytes.Buffer{} + sc.inv.Serialize(sb) + ret.Deserialize(sb) + + return ret +} + +// RegisterOnInvAction registers a handler that is called +// when a client attempts to perform an inventory action. +// The returned string overrides the original action. +// Later handlers will receive the modified action. +// Handlers are called in registration order. +// If the final action string is empty, the action is not forwarded +// to the upstream server. +// You may use the mt package to interact with the action strings. +func RegisterOnInvAction(handler func(*ClientConn, string) string) { + onInvActionMu.Lock() + defer onInvActionMu.Unlock() + + onInvAction = append(onInvAction, handler) +} @@ -484,6 +484,17 @@ func (cc *ClientConn) process(pkt mt.Pkt) { case *mt.ToSrvCltInfo: // Store for any future hops (need to send it to the new server). cc.cltInfo = cmd + case *mt.ToSrvInvAction: + onInvActionMu.RLock() + defer onInvActionMu.RUnlock() + + for _, handler := range onInvAction { + cmd.Action = handler(cc, cmd.Action) + } + + if cmd.Action == "" { + return + } case *mt.ToSrvInvFields: if handleOnPlayerReceiveFields(cc, cmd) { return |