From 33e5475c770a9fda9ca98bb9d4d012349e4b5beb Mon Sep 17 00:00:00 2001 From: ilotterytea Date: Sun, 3 Aug 2025 10:32:41 +0500 Subject: feat: join channels --- cmd/irclogs/main.go | 10 ++++++---- internal/client.go | 54 +++++++++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 58 insertions(+), 6 deletions(-) diff --git a/cmd/irclogs/main.go b/cmd/irclogs/main.go index 509447f..1090e66 100644 --- a/cmd/irclogs/main.go +++ b/cmd/irclogs/main.go @@ -22,7 +22,7 @@ func main() { clients := []irclogs.IRCClient{} for { - rows, err := db.Query("SELECT host, port, nick, pass, capabilities FROM servers") + rows, err := db.Query("SELECT id, host, port, nick, pass, capabilities FROM servers") if err != nil { log.Fatalf("Failed to get servers: %v\n", err) continue @@ -30,8 +30,8 @@ func main() { for rows.Next() { var host, nick, pass, caps string - var port int - if err = rows.Scan(&host, &port, &nick, &pass, &caps); err != nil { + var dbid, port int + if err = rows.Scan(&dbid, &host, &port, &nick, &pass, &caps); err != nil { log.Fatalf("Failed to scan rows: %v\n", err) continue } @@ -40,7 +40,7 @@ func main() { return c.Host == host }) { log.Printf("Connecting to %s:%d...\n", host, port) - c := irclogs.NewIRCClient(host, port, nick, pass, strings.Split(caps, "\n")) + c := irclogs.NewIRCClient(dbid, host, port, nick, pass, strings.Split(caps, "\n")) go func() { if err = c.Connect(); err != nil { @@ -48,6 +48,8 @@ func main() { } }() + go c.JoinChannels(db) + clients = append(clients, c) } } diff --git a/internal/client.go b/internal/client.go index 092504e..c0373a0 100644 --- a/internal/client.go +++ b/internal/client.go @@ -2,24 +2,31 @@ package irclogs import ( "bufio" + "database/sql" "fmt" "log" "net" "net/textproto" + "slices" ) type IRCClient struct { + dbid int + Host string port int nick string pass string caps []string + rooms []string + conn net.Conn } -func NewIRCClient(host string, port int, nick string, pass string, capabilities []string) IRCClient { +func NewIRCClient(dbid int, host string, port int, nick string, pass string, capabilities []string) IRCClient { return IRCClient{ + dbid: dbid, Host: host, port: port, nick: nick, @@ -36,6 +43,9 @@ func (c *IRCClient) Connect() (err error) { c.conn = conn c.authorize() + for _, r := range c.rooms { + c.SendRaw(fmt.Sprintf("JOIN %s", r)) + } tp := textproto.NewReader(bufio.NewReader(c.conn)) @@ -57,5 +67,45 @@ func (c *IRCClient) authorize() { } func (c *IRCClient) SendRaw(message string) { - fmt.Fprintf(c.conn, "%s\r\n", message) + if c.conn != nil { + fmt.Fprintf(c.conn, "%s\r\n", message) + } +} + +func (c *IRCClient) JoinChannels(db *sql.DB) { + for { + rooms := []string{} + rows, err := db.Query("SELECT name FROM rooms WHERE server_id = ? AND departed_at IS NULL", c.dbid) + if err != nil { + log.Fatalf("Failed to get rooms: %v\n", err) + continue + } + + for rows.Next() { + var room string + if err = rows.Scan(&room); err != nil { + log.Fatalf("Failed to scan rows: %v\n", err) + continue + } + rooms = append(rooms, room) + } + + rows.Close() + + for _, r := range rooms { + if !slices.Contains(c.rooms, r) { + log.Printf("[%s] Joining %s...", c.Host, r) + c.SendRaw(fmt.Sprintf("JOIN %s", r)) + c.rooms = append(c.rooms, r) + } + } + + for _, r := range c.rooms { + if !slices.Contains(rooms, r) { + log.Printf("[%s] Departing %s...", c.Host, r) + c.SendRaw(fmt.Sprintf("PART %s", r)) + c.rooms = slices.DeleteFunc(c.rooms, func(s string) bool { return s == r }) + } + } + } } -- cgit v1.2.3