commit e56baed

Hubert Hirtz  ·  2020-08-05 20:04:50 +0000 UTC
parent 713dd4a
Add a -debug flag and show raw messages
6 files changed,  +128, -35
M app.go
M app.go
+8, -1
 1@@ -44,6 +44,7 @@ func NewApp(cfg Config) (app *App, err error) {
 2 		Username: cfg.User,
 3 		RealName: cfg.Real,
 4 		Auth:     auth,
 5+		Debug:    cfg.Debug,
 6 	})
 7 	if err != nil {
 8 		return
 9@@ -79,8 +80,14 @@ func (app *App) Run() {
10 
11 func (app *App) handleIRCEvent(ev irc.Event) {
12 	switch ev := ev.(type) {
13+	case irc.RawMessageEvent:
14+		head := "DEBUG  IN --"
15+		if ev.Outgoing {
16+			head = "DEBUG OUT --"
17+		}
18+		app.win.AddLine(ui.Home, ui.NewLineNow(head, ev.Message), false)
19 	case irc.RegisteredEvent:
20-		app.win.AddLine("", ui.NewLineNow("--", "Connected to the server"), false)
21+		app.win.AddLine(ui.Home, ui.NewLineNow("--", "Connected to the server"), false)
22 		if app.cfg.Highlights == nil {
23 			app.highlights[0] = app.s.LNick()
24 		}
+4, -0
 1@@ -19,7 +19,9 @@ func main() {
 2 	tcell.SetEncodingFallback(tcell.EncodingFallbackASCII)
 3 
 4 	var configPath string
 5+	var debug bool
 6 	flag.StringVar(&configPath, "config", "", "path to the configuration file")
 7+	flag.BoolVar(&debug, "debug", false, "show raw protocol data in the home buffer")
 8 	flag.Parse()
 9 
10 	if configPath == "" {
11@@ -35,6 +37,8 @@ func main() {
12 		log.Panicln(err)
13 	}
14 
15+	cfg.Debug = cfg.Debug || debug
16+
17 	app, err := senpai.NewApp(cfg)
18 	if err != nil {
19 		log.Panicln(err)
+2, -0
1@@ -13,6 +13,8 @@ type Config struct {
2 	User       string
3 	Password   *string
4 	Highlights []string
5+
6+	Debug bool
7 }
8 
9 func ParseConfig(buf []byte) (cfg Config, err error) {
+5, -0
 1@@ -7,6 +7,11 @@ import (
 2 
 3 type Event interface{}
 4 
 5+type RawMessageEvent struct {
 6+	Message  string
 7+	Outgoing bool
 8+}
 9+
10 type RegisteredEvent struct{}
11 
12 type UserEvent struct {
+29, -31
  1@@ -120,6 +120,8 @@ type SessionParams struct {
  2 	RealName string
  3 
  4 	Auth SASLClient
  5+
  6+	Debug bool
  7 }
  8 
  9 type Session struct {
 10@@ -128,6 +130,8 @@ type Session struct {
 11 	acts chan action
 12 	evts chan Event
 13 
 14+	debug bool
 15+
 16 	running      atomic.Value // bool
 17 	state        ConnectionState
 18 	typingStamps map[string]time.Time
 19@@ -140,9 +144,6 @@ type Session struct {
 20 	host  string
 21 	auth  SASLClient
 22 
 23-	mode string
 24-	motd string
 25-
 26 	availableCaps map[string]string
 27 	enabledCaps   map[string]struct{}
 28 	features      map[string]string
 29@@ -158,6 +159,7 @@ func NewSession(conn io.ReadWriteCloser, params SessionParams) (s Session, err e
 30 		msgs:          make(chan Message, 16),
 31 		acts:          make(chan action, 16),
 32 		evts:          make(chan Event, 16),
 33+		debug:         params.Debug,
 34 		typingStamps:  map[string]time.Time{},
 35 		nick:          params.Nickname,
 36 		lNick:         strings.ToLower(params.Nickname),
 37@@ -360,6 +362,10 @@ func (s *Session) run() {
 38 }
 39 
 40 func (s *Session) handleStart(msg Message) (err error) {
 41+	if s.debug {
 42+		s.evts <- RawMessageEvent{Message: msg.String()}
 43+	}
 44+
 45 	switch msg.Command {
 46 	case "AUTHENTICATE":
 47 		if s.auth != nil {
 48@@ -445,8 +451,6 @@ func (s *Session) handleStart(msg Message) (err error) {
 49 				}
 50 			}
 51 		}
 52-	case errNomotd:
 53-		s.motd += "\n" + strings.TrimPrefix(msg.Params[1], "- ")
 54 	case errNicknameinuse:
 55 		s.nick = s.nick + "_"
 56 
 57@@ -455,13 +459,20 @@ func (s *Session) handleStart(msg Message) (err error) {
 58 			return
 59 		}
 60 	default:
 61-		err = s.handle(msg)
 62+		err = s.handleInner(msg)
 63 	}
 64 
 65 	return
 66 }
 67 
 68 func (s *Session) handle(msg Message) (err error) {
 69+	if s.debug {
 70+		s.evts <- RawMessageEvent{Message: msg.String()}
 71+	}
 72+	return s.handleInner(msg)
 73+}
 74+
 75+func (s *Session) handleInner(msg Message) (err error) {
 76 	if id, ok := msg.Tags["batch"]; ok {
 77 		if b, ok := s.chBatches[id]; ok {
 78 			s.chBatches[id] = HistoryEvent{
 79@@ -745,6 +756,7 @@ func (s *Session) handle(msg Message) (err error) {
 80 		s.state = ConnQuit
 81 	default:
 82 	}
 83+
 84 	return
 85 }
 86 
 87@@ -812,34 +824,20 @@ func (s *Session) updateFeatures(features []string) {
 88 	}
 89 }
 90 
 91-/*
 92-func (cli *Session) send(format string, args ...interface{}) (err error) {
 93+func (s *Session) send(format string, args ...interface{}) (err error) {
 94 	msg := fmt.Sprintf(format, args...)
 95-
 96-	for _, line := range strings.Split(msg, "\r\n") {
 97-		if line != "" {
 98-			fmt.Println("<  ", line)
 99+	_, err = s.conn.Write([]byte(msg))
100+
101+	if s.debug {
102+		for _, line := range strings.Split(msg, "\r\n") {
103+			if line != "" {
104+				s.evts <- RawMessageEvent{
105+					Message:  line,
106+					Outgoing: true,
107+				}
108+			}
109 		}
110 	}
111 
112-	_, err = cli.conn.Write([]byte(msg))
113-
114-	return
115-}
116-
117-// */
118-
119-//*
120-func (s *Session) send(format string, args ...interface{}) (err error) {
121-	_, err = fmt.Fprintf(s.conn, format, args...)
122-	return
123-}
124-
125-// */
126-
127-/*
128-func (s *Session) send(format string, args ...interface{}) (err error) {
129-	go fmt.Fprintf(s.conn, format, args...)
130 	return
131 }
132-// */
+80, -3
  1@@ -38,7 +38,7 @@ func tagEscape(c rune) (escape rune) {
  2 	return
  3 }
  4 
  5-func unescapeTagValue(escaped string) (unescaped string) {
  6+func unescapeTagValue(escaped string) string {
  7 	var builder strings.Builder
  8 	builder.Grow(len(escaped))
  9 	escape := false
 10@@ -60,8 +60,36 @@ func unescapeTagValue(escaped string) (unescaped string) {
 11 		}
 12 	}
 13 
 14-	unescaped = builder.String()
 15-	return
 16+	return builder.String()
 17+}
 18+
 19+func escapeTagValue(unescaped string) string {
 20+	var sb strings.Builder
 21+	sb.Grow(len(unescaped) * 2)
 22+
 23+	for _, c := range unescaped {
 24+		switch c {
 25+		case ';':
 26+			sb.WriteRune('\\')
 27+			sb.WriteRune(':')
 28+		case ' ':
 29+			sb.WriteRune('\\')
 30+			sb.WriteRune('s')
 31+		case '\r':
 32+			sb.WriteRune('\\')
 33+			sb.WriteRune('r')
 34+		case '\n':
 35+			sb.WriteRune('\\')
 36+			sb.WriteRune('n')
 37+		case '\\':
 38+			sb.WriteRune('\\')
 39+			sb.WriteRune('\\')
 40+		default:
 41+			sb.WriteRune(c)
 42+		}
 43+	}
 44+
 45+	return sb.String()
 46 }
 47 
 48 func parseTags(s string) (tags map[string]string) {
 49@@ -154,6 +182,55 @@ func Tokenize(line string) (msg Message, err error) {
 50 	return
 51 }
 52 
 53+func (msg *Message) IsReply() bool {
 54+	if len(msg.Command) != 3 {
 55+		return false
 56+	}
 57+	for _, r := range msg.Command {
 58+		if !('0' <= r && r <= '9') {
 59+			return false
 60+		}
 61+	}
 62+	return true
 63+}
 64+
 65+func (msg *Message) String() string {
 66+	var sb strings.Builder
 67+
 68+	if msg.Tags != nil {
 69+		sb.WriteRune('@')
 70+		for k, v := range msg.Tags {
 71+			sb.WriteString(k)
 72+			if v != "" {
 73+				sb.WriteRune('=')
 74+				sb.WriteString(escapeTagValue(v))
 75+			}
 76+			sb.WriteRune(';')
 77+		}
 78+		sb.WriteRune(' ')
 79+	}
 80+
 81+	if msg.Prefix != "" {
 82+		sb.WriteRune(':')
 83+		sb.WriteString(msg.Prefix)
 84+		sb.WriteRune(' ')
 85+	}
 86+
 87+	sb.WriteString(msg.Command)
 88+
 89+	if len(msg.Params) != 0 {
 90+		for _, p := range msg.Params[:len(msg.Params)-1] {
 91+			sb.WriteRune(' ')
 92+			sb.WriteString(p)
 93+		}
 94+		sb.WriteRune(' ')
 95+		sb.WriteRune(':')
 96+		sb.WriteString(msg.Params[len(msg.Params)-1])
 97+	}
 98+
 99+	return sb.String()
100+}
101+
102 func (msg *Message) Validate() (err error) {
103 	switch msg.Command {
104 	case rplWelcome: