source: code/trunk/bridge.go@ 822

Last change on this file since 822 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
RevLine 
[804]1package suika
[32]2
3import (
[781]4 "context"
5 "fmt"
[405]6 "strconv"
7 "strings"
8
[32]9 "gopkg.in/irc.v3"
10)
11
[781]12func forwardChannel(ctx context.Context, dc *downstreamConn, ch *upstreamChannel) {
[32]13 if !ch.complete {
14 panic("Tried to forward a partial channel")
15 }
16
[764]17 // RPL_NOTOPIC shouldn't be sent on JOIN
18 if ch.Topic != "" {
19 sendTopic(dc, ch)
20 }
[781]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 {
[784]30 timestampStr = fmt.Sprintf("timestamp=%s", formatServerTime(r.Timestamp))
[781]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
[160]40 sendNames(dc, ch)
41}
42
43func sendTopic(dc *downstreamConn, ch *upstreamChannel) {
[260]44 downstreamName := dc.marshalEntity(ch.conn.network, ch.Name)
[69]45
[32]46 if ch.Topic != "" {
[54]47 dc.SendMessage(&irc.Message{
[32]48 Prefix: dc.srv.prefix(),
49 Command: irc.RPL_TOPIC,
[69]50 Params: []string{dc.nick, downstreamName, ch.Topic},
[54]51 })
[405]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 }
[32]61 } else {
[54]62 dc.SendMessage(&irc.Message{
[32]63 Prefix: dc.srv.prefix(),
64 Command: irc.RPL_NOTOPIC,
[69]65 Params: []string{dc.nick, downstreamName, "No topic is set"},
[54]66 })
[32]67 }
[140]68}
[32]69
[140]70func sendNames(dc *downstreamConn, ch *upstreamChannel) {
[260]71 downstreamName := dc.marshalEntity(ch.conn.network, ch.Name)
[140]72
[346]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
[478]81 for _, entry := range ch.Members.innerMap {
82 nick := entry.originalKey
83 memberships := entry.value.(*memberships)
[292]84 s := memberships.Format(dc) + dc.marshalEntity(ch.conn.network, nick)
[32]85
[349]86 n := buf.Len() + 1 + len(s)
87 if buf.Len() != 0 && n > maxLength {
[346]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 {
[54]104 dc.SendMessage(&irc.Message{
[32]105 Prefix: dc.srv.prefix(),
106 Command: irc.RPL_NAMREPLY,
[346]107 Params: []string{dc.nick, string(ch.Status), downstreamName, buf.String()},
[54]108 })
[32]109 }
110
[54]111 dc.SendMessage(&irc.Message{
[32]112 Prefix: dc.srv.prefix(),
113 Command: irc.RPL_ENDOFNAMES,
[69]114 Params: []string{dc.nick, downstreamName, "End of /NAMES list"},
[54]115 })
[32]116}
Note: See TracBrowser for help on using the repository browser.