package main import ( "fmt" "github.com/TwiN/go-color" "github.com/jroimartin/gocui" "log" "strings" "time" "unicode" ) func printable(r rune) rune { if r == rune('\u000d') || r == rune('\u000a') { // ctrl-r or ctrl-n return rune('\u000a') //ctrl-n } if unicode.IsGraphic(r) { return r } return rune('\u002e') // dot } func Ternary(condition bool, valueIfTrue, valueIfFalse interface{}) interface{} { if condition { return valueIfTrue } return valueIfFalse } func layout(g *gocui.Gui) error { maxX, maxY := g.Size() lwX := int(float32(maxX) * 0.8) // "data" view: Top-left large view if v, err := g.SetView("data", 0, 0, lwX-1, maxY/2-1); err != nil { if err != gocui.ErrUnknownView { return err } v.Title = "Data" v.Wrap = true v.Autoscroll = true } // "protocol" view: Bottom-left large view if v, err := g.SetView("protocol", 0, maxY/2, lwX-1, maxY-1); err != nil { if err != gocui.ErrUnknownView { return err } v.Title = "Protocol" v.Wrap = true v.Autoscroll = true } // "status" view: Smaller view on the right if v, err := g.SetView("status", lwX, 0, maxX-1, maxY-1); err != nil { if err != gocui.ErrUnknownView { return err } v.Title = "Status" } return nil } func keybindings(g *gocui.Gui) error { // Quit the application with Ctrl+C if err := g.SetKeybinding("", gocui.KeyCtrlC, gocui.ModNone, quit); err != nil { return err } if err := g.SetKeybinding("", gocui.KeyCtrlT, gocui.ModNone, toggleMode); err != nil { return err } return nil } func protocolUpdate(g *gocui.Gui) { for { msg := <-s.Protocol g.Update(func(g *gocui.Gui) error { v, err := g.View("protocol") if err != nil { log.Println(err.Error()) return err } fmt.Fprint(v, msg) return nil }) } } func pactorUpdate(g *gocui.Gui) { for { if s.ToPactor.GetLen() > 0 { msg, err := s.ToPactor.Dequeue(256) if err != nil { log.Println(err.Error()) continue } g.Update(func(g *gocui.Gui) error { v, err := g.View("data") if err != nil { log.Println(err.Error()) return err } fmt.Fprint(v, strings.Map(printable, string(msg))) return nil }) } if s.FromPactor.GetLen() > 0 { msg, err := s.FromPactor.Dequeue(256) if err != nil { log.Println(err.Error()) continue } g.Update(func(g *gocui.Gui) error { v, err := g.View("data") if err != nil { log.Println(err.Error()) return err } fmt.Fprint(v, color.InRed(strings.Map(printable, string(msg)))) return nil }) } time.Sleep(3 * time.Second) } } func statusUpdate(g *gocui.Gui) { for { time.Sleep(1 * time.Second) g.Update(func(g *gocui.Gui) error { v, err := g.View("status") if err != nil { log.Println(err.Error()) } else { v.Clear() fmt.Fprintln(v, time.Now().Format("15:04:05")) fmt.Fprintln(v, Ternary(s.VARAMode, "VARA", "TCP")) fmt.Fprintln(v, Ternary(s.Status&StatusTCPCmdActive != 0, color.InGreen("TCP CMD"), color.InRed("TCP CMD"))) fmt.Fprintln(v, Ternary(s.Status&StatusTCPDataActive != 0, color.InGreen("TCP DATA"), color.InRed("TCP DATA"))) fmt.Fprintln(v, fmt.Sprintf("\nCMD S: %d\nCMD R: %d\nDTA S: %d\nDTA R: %d", s.Command.Cmd.GetLen(), s.Command.Response.GetLen(), s.Data.Data.GetLen(), s.Data.Response.GetLen())) } return nil }) } } func quit(g *gocui.Gui, v *gocui.View) error { return gocui.ErrQuit } func toggleMode(g *gocui.Gui, v *gocui.View) error { s.Protocol <- fmt.Sprintf(color.InPurple("Toggle mode\n")) s.VARAMode = !s.VARAMode return nil }