~emersion/soju

0e9ef1f97cabf0b9cdb8cbc59de5c443456891c3 — Gregory Anders 3 days ago 2fe0a57
Forward user mode changes in single-upstream mode

References: https://todo.sr.ht/~emersion/soju/20
2 files changed, 41 insertions(+), 13 deletions(-)

M downstream.go
M upstream.go
M downstream.go => downstream.go +13 -2
@@ 1102,6 1102,13 @@ func (dc *downstreamConn) welcome() error {
	for _, msg := range generateIsupport(dc.srv.prefix(), dc.nick, isupport) {
		dc.SendMessage(msg)
	}
	if uc := dc.upstream(); uc != nil {
		dc.SendMessage(&irc.Message{
			Prefix:  dc.srv.prefix(),
			Command: irc.RPL_UMODEIS,
			Params:  []string{dc.nick, string(uc.modes)},
		})
	}
	dc.SendMessage(&irc.Message{
		Prefix:  dc.srv.prefix(),
		Command: irc.ERR_NOMOTD,


@@ 1601,11 1608,15 @@ func (dc *downstreamConn) handleMessageRegistered(msg *irc.Message) error {
					})
				})
			} else {
				// TODO: only do this in multi-upstream mode
				var userMode string
				if uc := dc.upstream(); uc != nil {
					userMode = string(uc.modes)
				}

				dc.SendMessage(&irc.Message{
					Prefix:  dc.srv.prefix(),
					Command: irc.RPL_UMODEIS,
					Params:  []string{dc.nick, ""}, // TODO
					Params:  []string{dc.nick, userMode},
				})
			}
			return nil

M upstream.go => upstream.go +28 -11
@@ 672,11 672,11 @@ func (uc *upstreamConn) handleMessage(msg *irc.Message) error {
			return nil
		}

		uc.forEachDownstreamByID(downstreamID, func (dc *downstreamConn) {
			dc.SendMessage(&irc.Message {
				Prefix: uc.srv.prefix(),
		uc.forEachDownstreamByID(downstreamID, func(dc *downstreamConn) {
			dc.SendMessage(&irc.Message{
				Prefix:  uc.srv.prefix(),
				Command: msg.Command,
				Params: msg.Params,
				Params:  msg.Params,
			})
		})
	case "BATCH":


@@ 932,8 932,18 @@ func (uc *upstreamConn) handleMessage(msg *irc.Message) error {
			if name != uc.nick {
				return fmt.Errorf("received MODE message for unknown nick %q", name)
			}
			return uc.modes.Apply(modeStr)
			// TODO: notify downstreams about user mode change?

			if err := uc.modes.Apply(modeStr); err != nil {
				return err
			}

			uc.forEachDownstream(func(dc *downstreamConn) {
				if dc.upstream() == nil {
					return
				}

				dc.SendMessage(msg)
			})
		} else { // channel mode change
			ch, err := uc.getChannel(name)
			if err != nil {


@@ 982,7 992,14 @@ func (uc *upstreamConn) handleMessage(msg *irc.Message) error {
		if err := uc.modes.Apply(modeStr); err != nil {
			return err
		}
		// TODO: send RPL_UMODEIS to downstream connections when applicable

		uc.forEachDownstream(func(dc *downstreamConn) {
			if dc.upstream() == nil {
				return
			}

			dc.SendMessage(msg)
		})
	case irc.RPL_CHANNELMODEIS:
		var channel string
		if err := parseMessageParams(msg, nil, &channel); err != nil {


@@ 1442,11 1459,11 @@ func (uc *upstreamConn) handleMessage(msg *irc.Message) error {
			return nil
		}

		uc.forEachDownstreamByID(downstreamID, func (dc *downstreamConn) {
			dc.SendMessage(&irc.Message {
				Prefix: uc.srv.prefix(),
		uc.forEachDownstreamByID(downstreamID, func(dc *downstreamConn) {
			dc.SendMessage(&irc.Message{
				Prefix:  uc.srv.prefix(),
				Command: msg.Command,
				Params: msg.Params,
				Params:  msg.Params,
			})
		})
	case irc.RPL_LISTSTART: