summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHubert Hirtz <hubert@hirtzfr.eu>2020-08-05 22:04:50 +0200
committerHubert Hirtz <hubert@hirtzfr.eu>2020-08-05 22:04:50 +0200
commite56baed4fc8f53047cbe216347d57171001e0a6e (patch)
tree641a3f84fe824681842407801608993b892a0fa1
parentDon't request history of the home buffer (diff)
Add a -debug flag and show raw messages
-rw-r--r--app.go9
-rw-r--r--cmd/irc/main.go4
-rw-r--r--config.go2
-rw-r--r--irc/events.go5
-rw-r--r--irc/states.go60
-rw-r--r--irc/tokens.go83
6 files changed, 128 insertions, 35 deletions
diff --git a/app.go b/app.go
index e2de723..e57d176 100644
--- a/app.go
+++ b/app.go
@@ -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)
diff --git a/config.go b/config.go
index ee76473..216655a 100644
--- a/config.go
+++ b/config.go
@@ -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: