source: code/trunk/bridge.go@ 816

Last change on this file since 816 was 804, checked in by koizumi.aoi, 2 years ago

Drunk as I like

Signed-off-by: Aoi K <koizumi.aoi@…>

File size: 3.0 KB
Line 
1package suika
2
3import (
4 "context"
5 "fmt"
6 "strconv"
7 "strings"
8
9 "gopkg.in/irc.v3"
10)
11
12func forwardChannel(ctx context.Context, dc *downstreamConn, ch *upstreamChannel) {
13 if !ch.complete {
14 panic("Tried to forward a partial channel")
15 }
16
17 // RPL_NOTOPIC shouldn't be sent on JOIN
18 if ch.Topic != "" {
19 sendTopic(dc, ch)
20 }
21
22 if dc.caps["soju.im/read"] {
23 channelCM := ch.conn.network.casemap(ch.Name)
24 r, err := dc.srv.db.GetReadReceipt(ctx, ch.conn.network.ID, channelCM)
25 if err != nil {
26 dc.logger.Printf("failed to get the read receipt for %q: %v", ch.Name, err)
27 } else {
28 timestampStr := "*"
29 if r != nil {
30 timestampStr = fmt.Sprintf("timestamp=%s", formatServerTime(r.Timestamp))
31 }
32 dc.SendMessage(&irc.Message{
33 Prefix: dc.prefix(),
34 Command: "READ",
35 Params: []string{dc.marshalEntity(ch.conn.network, ch.Name), timestampStr},
36 })
37 }
38 }
39
40 sendNames(dc, ch)
41}
42
43func sendTopic(dc *downstreamConn, ch *upstreamChannel) {
44 downstreamName := dc.marshalEntity(ch.conn.network, ch.Name)
45
46 if ch.Topic != "" {
47 dc.SendMessage(&irc.Message{
48 Prefix: dc.srv.prefix(),
49 Command: irc.RPL_TOPIC,
50 Params: []string{dc.nick, downstreamName, ch.Topic},
51 })
52 if ch.TopicWho != nil {
53 topicWho := dc.marshalUserPrefix(ch.conn.network, ch.TopicWho)
54 topicTime := strconv.FormatInt(ch.TopicTime.Unix(), 10)
55 dc.SendMessage(&irc.Message{
56 Prefix: dc.srv.prefix(),
57 Command: rpl_topicwhotime,
58 Params: []string{dc.nick, downstreamName, topicWho.String(), topicTime},
59 })
60 }
61 } else {
62 dc.SendMessage(&irc.Message{
63 Prefix: dc.srv.prefix(),
64 Command: irc.RPL_NOTOPIC,
65 Params: []string{dc.nick, downstreamName, "No topic is set"},
66 })
67 }
68}
69
70func sendNames(dc *downstreamConn, ch *upstreamChannel) {
71 downstreamName := dc.marshalEntity(ch.conn.network, ch.Name)
72
73 emptyNameReply := &irc.Message{
74 Prefix: dc.srv.prefix(),
75 Command: irc.RPL_NAMREPLY,
76 Params: []string{dc.nick, string(ch.Status), downstreamName, ""},
77 }
78 maxLength := maxMessageLength - len(emptyNameReply.String())
79
80 var buf strings.Builder
81 for _, entry := range ch.Members.innerMap {
82 nick := entry.originalKey
83 memberships := entry.value.(*memberships)
84 s := memberships.Format(dc) + dc.marshalEntity(ch.conn.network, nick)
85
86 n := buf.Len() + 1 + len(s)
87 if buf.Len() != 0 && n > maxLength {
88 // There's not enough space for the next space + nick.
89 dc.SendMessage(&irc.Message{
90 Prefix: dc.srv.prefix(),
91 Command: irc.RPL_NAMREPLY,
92 Params: []string{dc.nick, string(ch.Status), downstreamName, buf.String()},
93 })
94 buf.Reset()
95 }
96
97 if buf.Len() != 0 {
98 buf.WriteByte(' ')
99 }
100 buf.WriteString(s)
101 }
102
103 if buf.Len() != 0 {
104 dc.SendMessage(&irc.Message{
105 Prefix: dc.srv.prefix(),
106 Command: irc.RPL_NAMREPLY,
107 Params: []string{dc.nick, string(ch.Status), downstreamName, buf.String()},
108 })
109 }
110
111 dc.SendMessage(&irc.Message{
112 Prefix: dc.srv.prefix(),
113 Command: irc.RPL_ENDOFNAMES,
114 Params: []string{dc.nick, downstreamName, "End of /NAMES list"},
115 })
116}
Note: See TracBrowser for help on using the repository browser.