aboutsummaryrefslogtreecommitdiff
path: root/plugin_formspec.go
diff options
context:
space:
mode:
Diffstat (limited to 'plugin_formspec.go')
-rw-r--r--plugin_formspec.go82
1 files changed, 82 insertions, 0 deletions
diff --git a/plugin_formspec.go b/plugin_formspec.go
new file mode 100644
index 0000000..7803108
--- /dev/null
+++ b/plugin_formspec.go
@@ -0,0 +1,82 @@
+package proxy
+
+import (
+ "strings"
+ "sync"
+
+ "github.com/HimbeerserverDE/mt"
+)
+
+var (
+ onPlayerReceiveFields map[string][]func(*ClientConn, []mt.Field)
+ onPlayerReceiveFieldsMu sync.Mutex
+ onPlayerReceiveFieldsOnce sync.Once
+)
+
+// ShowFormspec opens a formspec on the client.
+// The form name should follow the standard minetest naming convention,
+// i.e. "pluginname:formname".
+// If formname is empty, it reshows the inventory formspec
+// without updating it for future opens.
+// If formspec is empty, the formspec is closed.
+// If formname is empty at the same time, any formspec is closed
+// regardless of its name.
+func (cc *ClientConn) ShowFormspec(formname string, formspec string) {
+ cc.SendCmd(&mt.ToCltShowFormspec{
+ Formspec: cc.FormspecPrepend + formspec,
+ Formname: formname,
+ })
+}
+
+// FormspecEscape escapes characters that cannot be used in formspecs.
+func FormspecEscape(formspec string) string {
+ formspec = strings.ReplaceAll(formspec, "\\", "\\\\")
+ formspec = strings.ReplaceAll(formspec, "[", "\\[")
+ formspec = strings.ReplaceAll(formspec, "]", "\\]")
+ formspec = strings.ReplaceAll(formspec, ";", "\\;")
+ formspec = strings.ReplaceAll(formspec, ",", "\\,")
+ formspec = strings.ReplaceAll(formspec, "$", "\\$")
+ return formspec
+}
+
+// RegisterOnPlayerReceiveFields registers a callback that is called
+// when a client submits a specific formspec.
+// Events triggering this callback include a button being pressed,
+// Enter being pressed while a text field is focused,
+// a checkbox being toggled, an item being selected in a dropdown list,
+// selecting a new tab, changing the selection in a textlist or table,
+// selecting an entry in a textlist or table, a scrollbar being moved
+// or the form actively being closed by the player.
+func RegisterOnPlayerReceiveFields(formname string, handler func(*ClientConn, []mt.Field)) {
+ initOnPlayerReceiveFields()
+
+ onPlayerReceiveFieldsMu.Lock()
+ defer onPlayerReceiveFieldsMu.Unlock()
+
+ onPlayerReceiveFields[formname] = append(onPlayerReceiveFields[formname], handler)
+}
+
+func handleOnPlayerReceiveFields(cc *ClientConn, cmd *mt.ToSrvInvFields) bool {
+ onPlayerReceiveFieldsMu.Lock()
+ defer onPlayerReceiveFieldsMu.Unlock()
+
+ handlers, ok := onPlayerReceiveFields[cmd.Formname]
+ if !ok || len(handlers) == 0 {
+ return false
+ }
+
+ for _, handler := range handlers {
+ handler(cc, cmd.Fields)
+ }
+
+ return true
+}
+
+func initOnPlayerReceiveFields() {
+ onPlayerReceiveFieldsOnce.Do(func() {
+ onPlayerReceiveFieldsMu.Lock()
+ defer onPlayerReceiveFieldsMu.Unlock()
+
+ onPlayerReceiveFields = make(map[string][]func(*ClientConn, []mt.Field))
+ })
+}