Changeset 435 in code for trunk/user.go


Ignore:
Timestamp:
Dec 14, 2020, 7:54:02 PM (4 years ago)
Author:
delthas
Message:

Add customizable auto-detaching, auto-reattaching, relaying.

This uses the fields added previously to the Channel struct to implement
the actual detaching/reattaching/relaying logic.

The FilterDefault values of the messages filters are currently
hardcoded.

The values of the message filters are not currently user-settable.

This introduces a new user event, eventChannelDetach, which stores an
upstreamConn (which might become invalid at the time of processing), and
a channel name, used for auto-detaching. Every time the channel detach
timer is refreshed (by receveing a message, etc.), a new timer is
created on the upstreamChannel, which will dispatch this event after the
duration (and discards the previous timer, if any).

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/user.go

    r423 r435  
    4747type eventDownstreamDisconnected struct {
    4848        dc *downstreamConn
     49}
     50
     51type eventChannelDetach struct {
     52        uc   *upstreamConn
     53        name string
    4954}
    5055
     
    177182}
    178183
    179 func (net *network) createUpdateChannel(ch *Channel) error {
    180         if current, ok := net.channels[ch.Name]; ok {
    181                 ch.ID = current.ID // update channel if it already exists
    182         }
    183         if err := net.user.srv.db.StoreChannel(net.ID, ch); err != nil {
    184                 return err
    185         }
    186         prev := net.channels[ch.Name]
    187         net.channels[ch.Name] = ch
    188 
    189         if prev != nil && prev.Detached != ch.Detached {
    190                 history := net.history[ch.Name]
    191                 if ch.Detached {
    192                         net.user.srv.Logger.Printf("network %q: detaching channel %q", net.GetName(), ch.Name)
    193                         net.forEachDownstream(func(dc *downstreamConn) {
    194                                 net.offlineClients[dc.clientName] = struct{}{}
    195 
    196                                 dc.SendMessage(&irc.Message{
    197                                         Prefix:  dc.prefix(),
    198                                         Command: "PART",
    199                                         Params:  []string{dc.marshalEntity(net, ch.Name), "Detach"},
    200                                 })
    201                         })
    202                 } else {
    203                         net.user.srv.Logger.Printf("network %q: attaching channel %q", net.GetName(), ch.Name)
    204 
    205                         var uch *upstreamChannel
    206                         if net.conn != nil {
    207                                 uch = net.conn.channels[ch.Name]
    208                         }
    209 
    210                         net.forEachDownstream(func(dc *downstreamConn) {
    211                                 dc.SendMessage(&irc.Message{
    212                                         Prefix:  dc.prefix(),
    213                                         Command: "JOIN",
    214                                         Params:  []string{dc.marshalEntity(net, ch.Name)},
    215                                 })
    216 
    217                                 if uch != nil {
    218                                         forwardChannel(dc, uch)
    219                                 }
    220 
    221                                 if history != nil {
    222                                         dc.sendNetworkHistory(net)
    223                                 }
    224                         })
    225                 }
    226         }
    227 
    228         return nil
     184func (net *network) detach(ch *Channel) {
     185        if ch.Detached {
     186                return
     187        }
     188        ch.Detached = true
     189        net.user.srv.Logger.Printf("network %q: detaching channel %q", net.GetName(), ch.Name)
     190
     191        if net.conn != nil {
     192                if uch, ok := net.conn.channels[ch.Name]; ok {
     193                        uch.updateAutoDetach(0)
     194                }
     195        }
     196
     197        net.forEachDownstream(func(dc *downstreamConn) {
     198                net.offlineClients[dc.clientName] = struct{}{}
     199
     200                dc.SendMessage(&irc.Message{
     201                        Prefix:  dc.prefix(),
     202                        Command: "PART",
     203                        Params:  []string{dc.marshalEntity(net, ch.Name), "Detach"},
     204                })
     205        })
     206}
     207
     208func (net *network) attach(ch *Channel) {
     209        if !ch.Detached {
     210                return
     211        }
     212        ch.Detached = false
     213        net.user.srv.Logger.Printf("network %q: attaching channel %q", net.GetName(), ch.Name)
     214
     215        var uch *upstreamChannel
     216        if net.conn != nil {
     217                uch = net.conn.channels[ch.Name]
     218
     219                net.conn.updateChannelAutoDetach(ch.Name)
     220        }
     221
     222        net.forEachDownstream(func(dc *downstreamConn) {
     223                dc.SendMessage(&irc.Message{
     224                        Prefix:  dc.prefix(),
     225                        Command: "JOIN",
     226                        Params:  []string{dc.marshalEntity(net, ch.Name)},
     227                })
     228
     229                if uch != nil {
     230                        forwardChannel(dc, uch)
     231                }
     232
     233                if net.history[ch.Name] != nil {
     234                        dc.sendNetworkHistory(net)
     235                }
     236        })
    229237}
    230238
     
    234242                return fmt.Errorf("unknown channel %q", name)
    235243        }
     244        if net.conn != nil {
     245                if uch, ok := net.conn.channels[ch.Name]; ok {
     246                        uch.updateAutoDetach(0)
     247                }
     248        }
     249
    236250        if err := net.user.srv.db.DeleteChannel(ch.ID); err != nil {
    237251                return err
     
    399413                                uc.logger.Printf("failed to handle message %q: %v", msg, err)
    400414                        }
     415                case eventChannelDetach:
     416                        uc, name := e.uc, e.name
     417                        c, ok := uc.network.channels[name]
     418                        if !ok || c.Detached {
     419                                continue
     420                        }
     421                        uc.network.detach(c)
     422                        if err := uc.srv.db.StoreChannel(uc.network.ID, c); err != nil {
     423                                u.srv.Logger.Printf("failed to store updated detached channel %q: %v", c.Name, err)
     424                        }
    401425                case eventDownstreamConnected:
    402426                        dc := e.dc
     
    476500        uc.endPendingLISTs(true)
    477501
     502        for _, uch := range uc.channels {
     503                uch.updateAutoDetach(0)
     504        }
     505
    478506        uc.forEachDownstream(func(dc *downstreamConn) {
    479507                dc.updateSupportedCaps()
Note: See TracChangeset for help on using the changeset viewer.