diff options
| author | Hubert Hirtz <hubert@hirtzfr.eu> | 2020-08-05 22:04:50 +0200 |
|---|---|---|
| committer | Hubert Hirtz <hubert@hirtzfr.eu> | 2020-08-05 22:04:50 +0200 |
| commit | e56baed4fc8f53047cbe216347d57171001e0a6e (patch) | |
| tree | 641a3f84fe824681842407801608993b892a0fa1 | |
| parent | Don't request history of the home buffer (diff) | |
Add a -debug flag and show raw messages
| -rw-r--r-- | app.go | 9 | ||||
| -rw-r--r-- | cmd/irc/main.go | 4 | ||||
| -rw-r--r-- | config.go | 2 | ||||
| -rw-r--r-- | irc/events.go | 5 | ||||
| -rw-r--r-- | irc/states.go | 60 | ||||
| -rw-r--r-- | irc/tokens.go | 83 |
6 files changed, 128 insertions, 35 deletions
@@ -44,6 +44,7 @@ func NewApp(cfg Config) (app *App, err error) { Username: cfg.User, RealName: cfg.Real, Auth: auth, + Debug: cfg.Debug, }) if err != nil { return @@ -79,8 +80,14 @@ func (app *App) Run() { func (app *App) handleIRCEvent(ev irc.Event) { switch ev := ev.(type) { + case irc.RawMessageEvent: + head := "DEBUG IN --" + if ev.Outgoing { + head = "DEBUG OUT --" + } + app.win.AddLine(ui.Home, ui.NewLineNow(head, ev.Message), false) case irc.RegisteredEvent: - app.win.AddLine("", ui.NewLineNow("--", "Connected to the server"), false) + app.win.AddLine(ui.Home, ui.NewLineNow("--", "Connected to the server"), false) if app.cfg.Highlights == nil { app.highlights[0] = app.s.LNick() } diff --git a/cmd/irc/main.go b/cmd/irc/main.go index cd9c263..fab5bc5 100644 --- a/cmd/irc/main.go +++ b/cmd/irc/main.go @@ -19,7 +19,9 @@ func main() { tcell.SetEncodingFallback(tcell.EncodingFallbackASCII) var configPath string + var debug bool flag.StringVar(&configPath, "config", "", "path to the configuration file") + flag.BoolVar(&debug, "debug", false, "show raw protocol data in the home buffer") flag.Parse() if configPath == "" { @@ -35,6 +37,8 @@ func main() { log.Panicln(err) } + cfg.Debug = cfg.Debug || debug + app, err := senpai.NewApp(cfg) if err != nil { log.Panicln(err) @@ -13,6 +13,8 @@ type Config struct { User string Password *string Highlights []string + + Debug bool } func ParseConfig(buf []byte) (cfg Config, err error) { diff --git a/irc/events.go b/irc/events.go index faabe41..72a5880 100644 --- a/irc/events.go +++ b/irc/events.go @@ -7,6 +7,11 @@ import ( type Event interface{} +type RawMessageEvent struct { + Message string + Outgoing bool +} + type RegisteredEvent struct{} type UserEvent struct { diff --git a/irc/states.go b/irc/states.go index 9e5ed56..727dfa3 100644 --- a/irc/states.go +++ b/irc/states.go @@ -120,6 +120,8 @@ type SessionParams struct { RealName string Auth SASLClient + + Debug bool } type Session struct { @@ -128,6 +130,8 @@ type Session struct { acts chan action evts chan Event + debug bool + running atomic.Value // bool state ConnectionState typingStamps map[string]time.Time @@ -140,9 +144,6 @@ type Session struct { host string auth SASLClient - mode string - motd string - availableCaps map[string]string enabledCaps map[string]struct{} features map[string]string @@ -158,6 +159,7 @@ func NewSession(conn io.ReadWriteCloser, params SessionParams) (s Session, err e msgs: make(chan Message, 16), acts: make(chan action, 16), evts: make(chan Event, 16), + debug: params.Debug, typingStamps: map[string]time.Time{}, nick: params.Nickname, lNick: strings.ToLower(params.Nickname), @@ -360,6 +362,10 @@ func (s *Session) run() { } func (s *Session) handleStart(msg Message) (err error) { + if s.debug { + s.evts <- RawMessageEvent{Message: msg.String()} + } + switch msg.Command { case "AUTHENTICATE": if s.auth != nil { @@ -445,8 +451,6 @@ func (s *Session) handleStart(msg Message) (err error) { } } } - case errNomotd: - s.motd += "\n" + strings.TrimPrefix(msg.Params[1], "- ") case errNicknameinuse: s.nick = s.nick + "_" @@ -455,13 +459,20 @@ func (s *Session) handleStart(msg Message) (err error) { return } default: - err = s.handle(msg) + err = s.handleInner(msg) } return } func (s *Session) handle(msg Message) (err error) { + if s.debug { + s.evts <- RawMessageEvent{Message: msg.String()} + } + return s.handleInner(msg) +} + +func (s *Session) handleInner(msg Message) (err error) { if id, ok := msg.Tags["batch"]; ok { if b, ok := s.chBatches[id]; ok { s.chBatches[id] = HistoryEvent{ @@ -745,6 +756,7 @@ func (s *Session) handle(msg Message) (err error) { s.state = ConnQuit default: } + return } @@ -812,34 +824,20 @@ func (s *Session) updateFeatures(features []string) { } } -/* -func (cli *Session) send(format string, args ...interface{}) (err error) { +func (s *Session) send(format string, args ...interface{}) (err error) { msg := fmt.Sprintf(format, args...) - - for _, line := range strings.Split(msg, "\r\n") { - if line != "" { - fmt.Println("< ", line) + _, err = s.conn.Write([]byte(msg)) + + if s.debug { + for _, line := range strings.Split(msg, "\r\n") { + if line != "" { + s.evts <- RawMessageEvent{ + Message: line, + Outgoing: true, + } + } } } - _, err = cli.conn.Write([]byte(msg)) - - return -} - -// */ - -//* -func (s *Session) send(format string, args ...interface{}) (err error) { - _, err = fmt.Fprintf(s.conn, format, args...) - return -} - -// */ - -/* -func (s *Session) send(format string, args ...interface{}) (err error) { - go fmt.Fprintf(s.conn, format, args...) return } -// */ diff --git a/irc/tokens.go b/irc/tokens.go index 53deaee..064e4c5 100644 --- a/irc/tokens.go +++ b/irc/tokens.go @@ -38,7 +38,7 @@ func tagEscape(c rune) (escape rune) { return } -func unescapeTagValue(escaped string) (unescaped string) { +func unescapeTagValue(escaped string) string { var builder strings.Builder builder.Grow(len(escaped)) escape := false @@ -60,8 +60,36 @@ func unescapeTagValue(escaped string) (unescaped string) { } } - unescaped = builder.String() - return + return builder.String() +} + +func escapeTagValue(unescaped string) string { + var sb strings.Builder + sb.Grow(len(unescaped) * 2) + + for _, c := range unescaped { + switch c { + case ';': + sb.WriteRune('\\') + sb.WriteRune(':') + case ' ': + sb.WriteRune('\\') + sb.WriteRune('s') + case '\r': + sb.WriteRune('\\') + sb.WriteRune('r') + case '\n': + sb.WriteRune('\\') + sb.WriteRune('n') + case '\\': + sb.WriteRune('\\') + sb.WriteRune('\\') + default: + sb.WriteRune(c) + } + } + + return sb.String() } func parseTags(s string) (tags map[string]string) { @@ -154,6 +182,55 @@ func Tokenize(line string) (msg Message, err error) { return } +func (msg *Message) IsReply() bool { + if len(msg.Command) != 3 { + return false + } + for _, r := range msg.Command { + if !('0' <= r && r <= '9') { + return false + } + } + return true +} + +func (msg *Message) String() string { + var sb strings.Builder + + if msg.Tags != nil { + sb.WriteRune('@') + for k, v := range msg.Tags { + sb.WriteString(k) + if v != "" { + sb.WriteRune('=') + sb.WriteString(escapeTagValue(v)) + } + sb.WriteRune(';') + } + sb.WriteRune(' ') + } + + if msg.Prefix != "" { + sb.WriteRune(':') + sb.WriteString(msg.Prefix) + sb.WriteRune(' ') + } + + sb.WriteString(msg.Command) + + if len(msg.Params) != 0 { + for _, p := range msg.Params[:len(msg.Params)-1] { + sb.WriteRune(' ') + sb.WriteString(p) + } + sb.WriteRune(' ') + sb.WriteRune(':') + sb.WriteString(msg.Params[len(msg.Params)-1]) + } + + return sb.String() +} + func (msg *Message) Validate() (err error) { switch msg.Command { case rplWelcome: |
