From 2cacca7a979eb99bed7594b9093c2a5e4ac96b5f Mon Sep 17 00:00:00 2001 From: "Marcel M. Otte" Date: Tue, 11 Apr 2023 16:05:24 +0200 Subject: [PATCH] Working on the packeteditor --- internal/ui/newobjectdialog.go | 6 +- internal/ui/packeteditor.go | 42 +++++++++- internal/ui/packetfieldeditor.go | 53 +++++++++++++ internal/ui/packetfilehandler.go | 35 +++++++++ internal/ui/protocolfilehandler.go | 2 +- packet/fieldvalue.go | 17 ++++ packet/packet.go | 24 ++++++ packet/packetmetadata.go | 4 + packetctl/packetctl.go | 122 +++++++++++++++++++++++++++++ protocol/field.go | 5 ++ protocol/protocol.go | 5 ++ protocolctl/protocolctl.go | 2 +- 12 files changed, 311 insertions(+), 6 deletions(-) create mode 100644 internal/ui/packetfieldeditor.go create mode 100644 internal/ui/packetfilehandler.go create mode 100644 packet/packetmetadata.go diff --git a/internal/ui/newobjectdialog.go b/internal/ui/newobjectdialog.go index 6fbe9aa..b7b68e1 100644 --- a/internal/ui/newobjectdialog.go +++ b/internal/ui/newobjectdialog.go @@ -11,9 +11,9 @@ import ( type NewObjectDialog struct { representation *fyne.Container // views - selection *fyne.Container // 4buttons grid - protocolChooser *container.AppTabs - packetChooser *fyne.Container + selection *fyne.Container // 4buttons grid + //protocolChooser *container.AppTabs + //packetChooser *fyne.Container } var pnod *NewObjectDialog diff --git a/internal/ui/packeteditor.go b/internal/ui/packeteditor.go index 206adc3..1633fac 100644 --- a/internal/ui/packeteditor.go +++ b/internal/ui/packeteditor.go @@ -1,7 +1,47 @@ package ui -import "fyne.io/fyne/v2" +import ( + "fmt" + + "fyne.io/fyne/v2" + "fyne.io/fyne/v2/container" + "gitea.mmo.to/ProtocolPacketForger/ppf/packet" + "gitea.mmo.to/ProtocolPacketForger/ppf/packetctl" +) type PacketEditor struct { Representation *fyne.Container + FieldContainer *fyne.Container + Metadata *PacketMetadata + Fields []*PacketFieldEditor + + ShowShortHints bool + + Reference *packet.PacketStructure +} + +func NewPacketEditor(ref *packet.PacketStructure) *PacketEditor { + metadata := NewMetadataPacket() + fields := container.NewGridWrap(fyne.NewSize(300, 200)) + container := container.NewBorder(nil, nil, metadata.Representation, nil, container.NewVScroll(fields)) + packetEditor := &PacketEditor{container, fields, metadata, []*PacketFieldEditor{}, false, ref} + packetEditor.Redraw() + return packetEditor +} + +func (ed *PacketEditor) Redraw() { + json := packetctl.ToJson(ed.Reference) + fmt.Printf("%s\n", json) + + ed.FieldContainer.RemoveAll() + // existing fields + k := 0 + for i, v := range ed.Reference.Layers { + for j, vv := range v.Values { + ed.FieldContainer.Add(CreatePacketFieldEditor(ed, k, i, j, &vv).Representation) + k++ + } + } + // metadata + //ed.Metadata.SetPacket(ed.Reference) } diff --git a/internal/ui/packetfieldeditor.go b/internal/ui/packetfieldeditor.go new file mode 100644 index 0000000..c8bbe27 --- /dev/null +++ b/internal/ui/packetfieldeditor.go @@ -0,0 +1,53 @@ +package ui + +import ( + "fyne.io/fyne/v2" + "fyne.io/fyne/v2/container" + "fyne.io/fyne/v2/widget" + "gitea.mmo.to/ProtocolPacketForger/ppf/packet" + "gitea.mmo.to/ProtocolPacketForger/ppf/packetctl" +) + +type PacketFieldEditor struct { + Representation *fyne.Container + Value *widget.Entry + + Reference *packet.FieldValue + + GlobalIndex int + Index int +} + +func CreatePacketFieldEditor( + ed *PacketEditor, + gblidx int, + lyridx int, + index int, + ref *packet.FieldValue, +) *PacketFieldEditor { + pfe := &PacketFieldEditor{} + pfe.Reference = ref + pfe.Index = index + pfe.GlobalIndex = gblidx + + setfunc := func(s string) { + //todo + packetctl.UpdateField(&ed.Reference.Layers[lyridx], index, packetctl.NewFieldValue(s)) + } + + elements := []fyne.CanvasObject{} + + elements = append(elements, widget.NewLabel(ref.GetProtocolField().Name)) + if ed.ShowShortHints { + elements = append(elements, widget.NewLabel(ref.GetProtocolField().Regex)) // todo: implement real shorthints if feasible + } + + // depending on the input stuff, entry for now + pfe.Value = widget.NewEntry() + pfe.Value.OnChanged = setfunc + + elements = append(elements, pfe.Value) + + pfe.Representation = container.NewHBox(elements...) + return pfe +} diff --git a/internal/ui/packetfilehandler.go b/internal/ui/packetfilehandler.go new file mode 100644 index 0000000..26b36bb --- /dev/null +++ b/internal/ui/packetfilehandler.go @@ -0,0 +1,35 @@ +package ui + +import ( + "fyne.io/fyne/v2/container" + "gitea.mmo.to/ProtocolPacketForger/ppf/packet" + "gitea.mmo.to/ProtocolPacketForger/ppf/packetctl" +) + +// implements TabProvider, FileHandler +type PacketFileHandler struct { + PacketEditor *PacketEditor + name string + path string + changed bool + tab *container.TabItem + + Reference *packet.PacketStructure +} + +func NewPacketFileHandler() *PacketFileHandler { + pfh := PacketFileHandler{} + pfh.name = "*new" + pfh.changed = true + pfh.Reference = packetctl.NewPacketStructure() + pfh.PacketEditor = NewPacketEditor(pfh.Reference) + return &pfh +} + +func (pfh *PacketFileHandler) SetTab(tab *container.TabItem) { + pfh.tab = tab +} + +func (pfh *PacketFileHandler) Tab() *container.TabItem { + return pfh.tab +} diff --git a/internal/ui/protocolfilehandler.go b/internal/ui/protocolfilehandler.go index 13c9262..7abff9d 100644 --- a/internal/ui/protocolfilehandler.go +++ b/internal/ui/protocolfilehandler.go @@ -9,7 +9,7 @@ import ( "gitea.mmo.to/ProtocolPacketForger/ppf/protocolctl" ) -// implements FileHandler +// implements FileHandler, TabProvider type ProtocolFileHandler struct { ProtocolEditor *ProtocolEditor name string diff --git a/packet/fieldvalue.go b/packet/fieldvalue.go index 9c40969..8a7cf98 100644 --- a/packet/fieldvalue.go +++ b/packet/fieldvalue.go @@ -1 +1,18 @@ package packet + +import "gitea.mmo.to/ProtocolPacketForger/ppf/protocol" + +// implements protocol.ProtocolFieldReferencer +type FieldValue struct { + fieldReference *protocol.Field + + Value string +} + +func (fv *FieldValue) GetProtocolField() *protocol.Field { + return fv.fieldReference +} + +func (fv *FieldValue) SetProtocolField(pf *protocol.Field) { + fv.fieldReference = pf +} diff --git a/packet/packet.go b/packet/packet.go index 9c40969..fe8ce1c 100644 --- a/packet/packet.go +++ b/packet/packet.go @@ -1 +1,25 @@ package packet + +import "gitea.mmo.to/ProtocolPacketForger/ppf/protocol" + +// implements protocol.ProtocolReferencer +type PacketLayer struct { + // needs a reference to a protocol + protocolReference *protocol.ProtocolStructure + + ProtocolName string + Values []FieldValue +} + +type PacketStructure struct { + MetaData PacketMetadata + Layers []PacketLayer +} + +func (pl *PacketLayer) GetProtocol() *protocol.ProtocolStructure { + return pl.protocolReference +} + +func (pl *PacketLayer) Setprotocol(ps *protocol.ProtocolStructure) { + pl.protocolReference = ps +} diff --git a/packet/packetmetadata.go b/packet/packetmetadata.go new file mode 100644 index 0000000..9fd1c89 --- /dev/null +++ b/packet/packetmetadata.go @@ -0,0 +1,4 @@ +package packet + +type PacketMetadata struct { +} diff --git a/packetctl/packetctl.go b/packetctl/packetctl.go index 53325c8..be1f0da 100644 --- a/packetctl/packetctl.go +++ b/packetctl/packetctl.go @@ -1 +1,123 @@ package packetctl + +import ( + "encoding/json" + "io/fs" + "os" + + "gitea.mmo.to/ProtocolPacketForger/ppf/packet" +) + +func NewPacketStructure() *packet.PacketStructure { + p := packet.PacketStructure{} + return &p +} + +func UpdateMetaData( + pack *packet.PacketStructure, +) { + // still empty +} + +func NewPacketLayer() *packet.PacketLayer { + p := packet.PacketLayer{} + return &p +} + +func NewEmptyFieldValue() *packet.FieldValue { + f := packet.FieldValue{} + return &f +} + +func NewFieldValue( + value string, +) *packet.FieldValue { + f := packet.FieldValue{ + Value: value, + } + return &f +} + +func AppendField(pack *packet.PacketLayer, field *packet.FieldValue) int { + i := len(pack.Values) + pack.Values = append(pack.Values, *field) + return i + 1 +} + +func AddField(pack *packet.PacketLayer, index int, field *packet.FieldValue) { + if len(pack.Values) == index { + AppendField(pack, field) + return + } + ret := make([]packet.FieldValue, 0) + ret = append(ret, pack.Values[:index]...) + ret = append(ret, *field) + ret = append(ret, pack.Values[index:]...) + pack.Values = ret +} + +func AppendLayer(pack *packet.PacketStructure, layer *packet.PacketLayer) { + pack.Layers = append(pack.Layers, *layer) +} + +func Addlayer(pack *packet.PacketStructure, index int, layer *packet.PacketLayer) { + if len(pack.Layers) == index { + AppendLayer(pack, layer) + return + } + ret := make([]packet.PacketLayer, 0) + ret = append(ret, pack.Layers[:index]...) + ret = append(ret, *layer) + ret = append(ret, pack.Layers[index:]...) + pack.Layers = ret +} + +func UpdateField(pack *packet.PacketLayer, e int, field *packet.FieldValue) { + pack.Values[e] = *field +} + +func UpdateLayer(pack *packet.PacketStructure, e int, layer *packet.PacketLayer) { + pack.Layers[e] = *layer +} + +func RemoveField(pack *packet.PacketLayer, e int) { + l := len(pack.Values) - 1 + ret := make([]packet.FieldValue, l) + ret = append(ret, pack.Values[:e]...) + ret = append(ret, pack.Values[e+1:]...) + pack.Values = ret +} + +func RemoveLayer(pack *packet.PacketStructure, e int) { + l := len(pack.Layers) - 1 + ret := make([]packet.PacketLayer, l) + ret = append(ret, pack.Layers[:e]...) + ret = append(ret, pack.Layers[e+1:]...) + pack.Layers = ret +} + +func Load(pack *packet.PacketStructure, path string) error { + data, err := os.ReadFile(path) + if err != nil { + return err + } + err = json.Unmarshal(data, pack) + return err +} + +func ToJson(pack *packet.PacketStructure) string { + data, err := json.MarshalIndent(*pack, "", " ") + if err != nil { + return "" + } + return string(data) +} + +func Save(pack *packet.PacketStructure, path string) error { + data, err := json.MarshalIndent(*pack, "", " ") + if err != nil { + return err + } + err = os.WriteFile(path, data, fs.ModeAppend) + return err +} diff --git a/protocol/field.go b/protocol/field.go index 586d107..f1f3d5f 100644 --- a/protocol/field.go +++ b/protocol/field.go @@ -12,6 +12,11 @@ type Field struct { Payload bool // Is this field the payload or next protocol level? } +type ProtocolFieldReferencer interface { + GetProtocolField() *Field + SetProtocolField(f *Field) +} + func (f *Field) ToJson() string { b, err := json.Marshal(*f) if err != nil { diff --git a/protocol/protocol.go b/protocol/protocol.go index ef0df5b..b9721f8 100644 --- a/protocol/protocol.go +++ b/protocol/protocol.go @@ -6,3 +6,8 @@ type ProtocolStructure struct { DefaultValues []DefaultValue JavaScript string } + +type ProtocolReferencer interface { + GetProtocol() *ProtocolStructure + SetProtocol(prot *ProtocolStructure) +} diff --git a/protocolctl/protocolctl.go b/protocolctl/protocolctl.go index 814a540..de51d1c 100644 --- a/protocolctl/protocolctl.go +++ b/protocolctl/protocolctl.go @@ -59,7 +59,7 @@ func NewField( func AppendField(prot *protocol.ProtocolStructure, field *protocol.Field) int { i := len(prot.Structure) prot.Structure = append(prot.Structure, field) - return i + return i + 1 } func AddField(prot *protocol.ProtocolStructure, index int, field *protocol.Field) { if len(prot.Structure) == index {