Selaa lähdekoodia

MetaData, and Object

Steve Thielemann 3 kuukautta sitten
vanhempi
commit
b0cdcec56c
6 muutettua tiedostoa jossa 496 lisäystä ja 0 poistoa
  1. 6 0
      server/go.mod
  2. 6 0
      server/go.sum
  3. 29 0
      server/main.go
  4. 6 0
      server/meta.go
  5. 235 0
      server/metadata.go
  6. 214 0
      server/object.go

+ 6 - 0
server/go.mod

@@ -1,3 +1,9 @@
 module git.red-green.com/david/mud-server
 
 go 1.22.0
+
+require (
+	github.com/aarzilli/golua v0.0.0-20210507130708-11106aa57765 // indirect
+	github.com/fiatjaf/lunatico v1.5.1 // indirect
+	github.com/stevedonovan/luar v0.0.0-20170518170841-22d247e53660 // indirect
+)

+ 6 - 0
server/go.sum

@@ -0,0 +1,6 @@
+github.com/aarzilli/golua v0.0.0-20210507130708-11106aa57765 h1:N6gB4UCRBZz8twlJbMFiCKj0zX5Et2nFU/LRafT4x80=
+github.com/aarzilli/golua v0.0.0-20210507130708-11106aa57765/go.mod h1:hMjfaJVSqVnxenMlsxrq3Ni+vrm9Hs64tU4M7dhUoO4=
+github.com/fiatjaf/lunatico v1.5.1 h1:+GITY3Sb/PUMJpFpBUCUm+C8e4imh53KFvcrDtEj4R8=
+github.com/fiatjaf/lunatico v1.5.1/go.mod h1:dwBFpzqlNH0kKwMHofhlnD6/Sjl5eUf6ADdHe7XBeIk=
+github.com/stevedonovan/luar v0.0.0-20170518170841-22d247e53660 h1:BQU7miOzJXmSUHa5oLf0b88kRgUgTeFsoc8i9uAV8zA=
+github.com/stevedonovan/luar v0.0.0-20170518170841-22d247e53660/go.mod h1:LtHI5GcaXL3NPbZWY1Z6FAG62hWY8syhRGtD7feyN7E=

+ 29 - 0
server/main.go

@@ -0,0 +1,29 @@
+package main
+
+import "fmt"
+
+func main() {
+	o := NewObject()
+	o.Set(".id", uint64(1))
+	o.Set("name", "New Object")
+	o.Set("description", "A new object")
+	o.Set("on_look", `
+	log("call: '%#v'", call)
+	log("safe: '%#v'", safe)
+	log("self: '%#v'", self)
+	log("param1: '%#v'", param1)
+	log("param2: '%#v'", param2)
+	log("name: '%s'", self.String("name"))
+	log("desc: '%s'", self.String("description"))
+	pass()
+	`)
+
+	msg, ok := o.Call("on_look", nil, nil)
+	fmt.Printf("o: '%#v'\n", o)
+	fmt.Printf("metadata: '%#v'\n", o.meta.metadata)
+	if !ok {
+		fmt.Println("Err: ", msg)
+		return
+	}
+	fmt.Println("Ok")
+}

+ 6 - 0
server/meta.go

@@ -515,6 +515,12 @@ func NewMeta() *Meta {
 	}
 }
 
+func NewMetaFrom(val any) *Meta {
+	m := NewMeta()
+	m.Set(val)
+	return m
+}
+
 func NewMetaFromJSON(payload []byte) (*Meta, error) {
 	in := map[string]any{}
 	err := json.Unmarshal(payload, &in)

+ 235 - 0
server/metadata.go

@@ -0,0 +1,235 @@
+package main
+
+import "strings"
+
+type MetaData struct {
+	metadata map[string]*Meta
+	safe     bool
+}
+
+func NewMetaData() *MetaData {
+	return &MetaData{
+		metadata: make(map[string]*Meta),
+		safe:     true,
+	}
+}
+
+func (m *MetaData) Safe() bool {
+	return m.safe
+}
+
+func (m *MetaData) Unsafe() {
+	m.safe = false
+}
+
+func (m *MetaData) Set(key string, val any) {
+	if !m.Has(key) {
+		m.metadata[key] = NewMetaFrom(val)
+		return
+	}
+	if m.Private(key) || m.Restricted(key) {
+		return
+	}
+	m.metadata[key].Set(val)
+}
+
+func (m *MetaData) Has(key string) bool {
+	return m.metadata[key] != nil
+}
+
+func (m *MetaData) Private(key string) bool {
+	return strings.HasPrefix(key, ".") && m.Has(key) && !m.safe
+}
+
+func (m *MetaData) Restricted(key string) bool {
+	return strings.HasPrefix(key, "*") && m.Has(key) && !m.safe
+}
+
+func (m *MetaData) Type(key string) string {
+	if !m.Has(key) {
+		return ""
+	}
+	return m.metadata[key].data_type
+}
+
+func (m *MetaData) String(key string) string {
+	if m.Restricted(key) {
+		return ""
+	}
+	return m.metadata[key].String()
+}
+
+func (m *MetaData) Int32(key string) int32 {
+	if m.Restricted(key) {
+		return 0
+	}
+	return m.metadata[key].Int32()
+}
+
+func (m *MetaData) Int64(key string) int64 {
+	if m.Restricted(key) {
+		return 0
+	}
+	return m.metadata[key].Int64()
+}
+
+func (m *MetaData) Uint32(key string) uint32 {
+	if m.Restricted(key) {
+		return 0
+	}
+	return m.metadata[key].Uint32()
+}
+
+func (m *MetaData) Uint64(key string) uint64 {
+	if m.Restricted(key) {
+		return 0
+	}
+	return m.metadata[key].Uint64()
+}
+
+func (m *MetaData) Float32(key string) float32 {
+	if m.Restricted(key) {
+		return 0.0
+	}
+	return m.metadata[key].Float32()
+}
+
+func (m *MetaData) Float64(key string) float64 {
+	if m.Restricted(key) {
+		return 0.0
+	}
+	return m.metadata[key].Float64()
+}
+
+func (m *MetaData) Bool(key string) bool {
+	if m.Restricted(key) {
+		return false
+	}
+	return m.metadata[key].Bool()
+}
+
+func (m *MetaData) VecString(key string) []string {
+	if m.Restricted(key) {
+		return nil
+	}
+	return m.metadata[key].VecString()
+}
+
+func (m *MetaData) VecInt32(key string) []int32 {
+	if m.Restricted(key) {
+		return nil
+	}
+	return m.metadata[key].VecInt32()
+}
+
+func (m *MetaData) VecInt64(key string) []int64 {
+	if m.Restricted(key) {
+		return nil
+	}
+	return m.metadata[key].VecInt64()
+}
+
+func (m *MetaData) VecUint32(key string) []uint32 {
+	if m.Restricted(key) {
+		return nil
+	}
+	return m.metadata[key].VecUint32()
+}
+
+func (m *MetaData) VecUint64(key string) []uint64 {
+	if m.Restricted(key) {
+		return nil
+	}
+	return m.metadata[key].VecUint64()
+}
+
+func (m *MetaData) VecFloat32(key string) []float32 {
+	if m.Restricted(key) {
+		return nil
+	}
+	return m.metadata[key].VecFloat32()
+}
+
+func (m *MetaData) VecFloat64(key string) []float64 {
+	if m.Restricted(key) {
+		return nil
+	}
+	return m.metadata[key].VecFloat64()
+}
+
+func (m *MetaData) VecBool(key string) []bool {
+	if m.Restricted(key) {
+		return nil
+	}
+	return m.metadata[key].VecBool()
+}
+
+func (m *MetaData) VecMeta(key string) []Meta {
+	if m.Restricted(key) {
+		return nil
+	}
+	return m.metadata[key].VecMeta()
+}
+
+func (m *MetaData) MapString(key string) map[string]string {
+	if m.Restricted(key) {
+		return nil
+	}
+	return m.metadata[key].MapString()
+}
+
+func (m *MetaData) MapInt32(key string) map[string]int32 {
+	if m.Restricted(key) {
+		return nil
+	}
+	return m.metadata[key].MapInt32()
+}
+
+func (m *MetaData) MapInt64(key string) map[string]int64 {
+	if m.Restricted(key) {
+		return nil
+	}
+	return m.metadata[key].MapInt64()
+}
+
+func (m *MetaData) MapUint32(key string) map[string]uint32 {
+	if m.Restricted(key) {
+		return nil
+	}
+	return m.metadata[key].MapUint32()
+}
+
+func (m *MetaData) MapUint64(key string) map[string]uint64 {
+	if m.Restricted(key) {
+		return nil
+	}
+	return m.metadata[key].MapUint64()
+}
+
+func (m *MetaData) MapFloat32(key string) map[string]float32 {
+	if m.Restricted(key) {
+		return nil
+	}
+	return m.metadata[key].MapFloat32()
+}
+
+func (m *MetaData) MapFloat64(key string) map[string]float64 {
+	if m.Restricted(key) {
+		return nil
+	}
+	return m.metadata[key].MapFloat64()
+}
+
+func (m *MetaData) MapBool(key string) map[string]bool {
+	if m.Restricted(key) {
+		return nil
+	}
+	return m.metadata[key].MapBool()
+}
+
+func (m *MetaData) MapMeta(key string) map[string]Meta {
+	if m.Restricted(key) {
+		return nil
+	}
+	return m.metadata[key].MapMeta()
+}

+ 214 - 0
server/object.go

@@ -0,0 +1,214 @@
+package main
+
+import (
+	"fmt"
+	"log"
+
+	"github.com/aarzilli/golua/lua"
+	"github.com/fiatjaf/lunatico"
+	"github.com/stevedonovan/luar"
+)
+
+type Object struct {
+	meta *MetaData
+}
+
+func NewObject() *Object {
+	return &Object{
+		meta: NewMetaData(),
+	}
+}
+
+func (o *Object) Safe() bool {
+	return o.meta.Safe()
+}
+
+func (o *Object) Unsafe() {
+	o.meta.Unsafe()
+}
+
+func (o *Object) Id() uint64 {
+	return o.Uint64(".id")
+}
+
+func (o *Object) Name() string {
+	return o.String("name")
+}
+
+func (o *Object) Description() string {
+	return o.String("description")
+}
+
+func (o *Object) Is(key string) bool {
+	return o.Group(key) != 0
+}
+
+func (o *Object) Group(key string) uint32 {
+	return o.Uint32(key)
+}
+
+func (o *Object) Set(key string, val any) {
+	o.meta.Set(key, val)
+}
+
+func (o *Object) Has(key string) bool {
+	return o.meta.Has(key)
+}
+
+func (o *Object) String(key string) string {
+	return o.meta.String(key)
+}
+
+func (o *Object) Int32(key string) int32 {
+	return o.meta.Int32(key)
+}
+
+func (o *Object) Int64(key string) int64 {
+	return o.meta.Int64(key)
+}
+
+func (o *Object) Uint32(key string) uint32 {
+	return o.meta.Uint32(key)
+}
+
+func (o *Object) Uint64(key string) uint64 {
+	return o.meta.Uint64(key)
+}
+
+func (o *Object) Float32(key string) float32 {
+	return o.meta.Float32(key)
+}
+
+func (o *Object) Float64(key string) float64 {
+	return o.meta.Float64(key)
+}
+
+func (o *Object) Bool(key string) bool {
+	return o.meta.Bool(key)
+}
+
+func (o *Object) VecString(key string) []string {
+	return o.meta.VecString(key)
+}
+
+func (o *Object) VecInt32(key string) []int32 {
+	return o.meta.VecInt32(key)
+}
+
+func (o *Object) VecInt64(key string) []int64 {
+	return o.meta.VecInt64(key)
+}
+
+func (o *Object) VecUint32(key string) []uint32 {
+	return o.meta.VecUint32(key)
+}
+
+func (o *Object) VecUint64(key string) []uint64 {
+	return o.meta.VecUint64(key)
+}
+
+func (o *Object) VecFloat32(key string) []float32 {
+	return o.meta.VecFloat32(key)
+}
+
+func (o *Object) VecFloat64(key string) []float64 {
+	return o.meta.VecFloat64(key)
+}
+
+func (o *Object) VecBool(key string) []bool {
+	return o.meta.VecBool(key)
+}
+
+func (o *Object) MapString(key string) map[string]string {
+	return o.meta.MapString(key)
+}
+
+func (o *Object) MapInt32(key string) map[string]int32 {
+	return o.meta.MapInt32(key)
+}
+
+func (o *Object) MapInt64(key string) map[string]int64 {
+	return o.meta.MapInt64(key)
+}
+
+func (o *Object) MapUint32(key string) map[string]uint32 {
+	return o.meta.MapUint32(key)
+}
+
+func (o *Object) MapUint64(key string) map[string]uint64 {
+	return o.meta.MapUint64(key)
+}
+
+func (o *Object) MapFloat32(key string) map[string]float32 {
+	return o.meta.MapFloat32(key)
+}
+
+func (o *Object) MapFloat64(key string) map[string]float64 {
+	return o.meta.MapFloat64(key)
+}
+
+func (o *Object) MapBool(key string) map[string]bool {
+	return o.meta.MapBool(key)
+}
+
+func (o *Object) Call(key string, param1, param2 *Object) (string, bool) {
+	if !o.Has(key) || o.String(key) == "" {
+		return fmt.Sprintf("missing '%s'", key), false
+	}
+	var (
+		L           *lua.State = luar.Init()
+		ERRMSG      string     = ""
+		RESULT      bool       = false
+		old_safe    bool       = o.meta.safe
+		old_p1_safe bool
+		old_p1      bool = param1 != nil
+		old_p2_safe bool
+		old_p2      bool = param2 != nil
+	)
+	if !old_safe {
+		if old_p1 {
+			old_p1_safe = param1.meta.safe
+		}
+		if old_p2 {
+			old_p2_safe = param2.meta.safe
+		}
+		param1.meta.safe = false
+		param2.meta.safe = false
+	}
+	lunatico.SetGlobals(L, map[string]any{
+		"log": log.Printf,
+		"fail": func(msg string, args ...any) {
+			RESULT = false
+			ERRMSG = fmt.Sprintf(msg, args...)
+		},
+		"pass": func() {
+			RESULT = true
+			ERRMSG = ""
+		},
+
+		"call": key,
+		"safe": old_safe,
+
+		"self":   o,
+		"param1": param1,
+		"param2": param2,
+	})
+	err := L.DoString(o.String(key))
+	if err != nil {
+		return fmt.Sprintf("'%s': %v", key, err), false
+	}
+	output := lunatico.GetGlobals(L, "self", "param1", "param2")
+	o = output["self"].(*Object)
+	param1 = output["param1"].(*Object)
+	param2 = output["param2"].(*Object)
+	if old_p1 {
+		param1.meta.safe = old_p1_safe
+	}
+	if old_p2 {
+		param2.meta.safe = old_p2_safe
+	}
+	if o.meta.safe != old_safe {
+		o.meta.safe = old_safe
+	}
+	return ERRMSG, RESULT
+}