aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHimbeer <himbeer@disroot.org>2024-12-07 13:57:39 +0100
committerHimbeer <himbeer@disroot.org>2024-12-07 13:57:39 +0100
commit2fe0cd17e14473f0d7ffd5a1f5f100bd2419b018 (patch)
tree8ff7eb5375e9a9a59af4a6f1f6d0d0ee5f2c203e
parentaee7c77cb835299f7e0a96bc971a182619f91296 (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.go45
-rw-r--r--process.go11
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)
+}
diff --git a/process.go b/process.go
index 1d8263f..b7623b5 100644
--- a/process.go
+++ b/process.go
@@ -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