diff --git a/plugin_interact.go b/plugin_interact.go new file mode 100644 index 0000000..6b4b146 --- /dev/null +++ b/plugin_interact.go @@ -0,0 +1,57 @@ +package proxy + +import ( + "sync" + + "github.com/anon55555/mt" +) + +// A InteractionHandler holds information on how to handle a Minetest Interaction. +type InteractionHandler struct { + Type mt.Interaction // can be 255 to register on all interactions + Handler func(*ClientConn, *mt.ToSrvInteract) bool +} + +var interactionHandlers []InteractionHandler +var interactionHandlerMu sync.RWMutex +var interactionHandlerOnce sync.Once + +// RegisterInteractionHandler adds a new InteractionHandler. +func RegisterInteractionHandler(handler InteractionHandler) { + initInteractionHandlers() + + chatCmdsMu.Lock() + defer chatCmdsMu.Unlock() + + interactionHandlers = append(interactionHandlers, handler) +} + +func initInteractionHandlers() { + chatCmdsOnce.Do(func() { + interactionHandlerMu.Lock() + defer interactionHandlerMu.Unlock() + + interactionHandlers = make([]InteractionHandler, 0) + }) +} + +func handleInteraction(cmd *mt.ToSrvInteract, cc *ClientConn) bool { + handled := false + handle := func(cond bool) { + if(cond) { + handled = true + } + } + + for _, handler := range interactionHandlers { + if handler.Type == 255 { + handle(handler.Handler(cc, cmd)) + } + if cmd.Action == handler.Type { + handle(handler.Handler(cc, cmd)) + } + + } + + return handled +} diff --git a/process.go b/process.go index 60f4f1a..b576143 100644 --- a/process.go +++ b/process.go @@ -438,6 +438,10 @@ func (cc *ClientConn) process(pkt mt.Pkt) { return } + if handleInteraction(cmd, cc) { // if return true: already handled + return + } + if _, ok := cmd.Pointed.(*mt.PointedAO); ok { srv.swapAOID(&cmd.Pointed.(*mt.PointedAO).ID) } @@ -736,6 +740,8 @@ func (sc *ServerConn) process(pkt mt.Pkt) { return case *mt.ToCltMediaPush: + prepend(sc.mediaPool, &cmd.Filename) + var exit bool for _, f := range clt.media { if f.name == cmd.Filename { @@ -748,7 +754,6 @@ func (sc *ServerConn) process(pkt mt.Pkt) { break } - prepend(sc.mediaPool, &cmd.Filename) if cmd.ShouldCache { cacheMedia(mediaFile{ name: cmd.Filename,