Changeset 69 in code for trunk/downstream.go
- Timestamp:
- Feb 19, 2020, 5:25:19 PM (5 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/downstream.go
r68 r69 40 40 } 41 41 42 type consumption struct { 43 consumer *RingConsumer 44 upstreamConn *upstreamConn 45 } 46 42 47 type downstreamConn struct { 43 net net.Conn44 irc *irc.Conn45 srv *Server46 logger Logger47 messages chan *irc.Message48 consum ers chan *RingConsumer49 closed chan struct{}48 net net.Conn 49 irc *irc.Conn 50 srv *Server 51 logger Logger 52 messages chan *irc.Message 53 consumptions chan consumption 54 closed chan struct{} 50 55 51 56 registered bool … … 58 63 func newDownstreamConn(srv *Server, netConn net.Conn) *downstreamConn { 59 64 dc := &downstreamConn{ 60 net: netConn,61 irc: irc.NewConn(netConn),62 srv: srv,63 logger: &prefixLogger{srv.Logger, fmt.Sprintf("downstream %q: ", netConn.RemoteAddr())},64 messages: make(chan *irc.Message, 64),65 consum ers: make(chan *RingConsumer),66 closed: make(chan struct{}),65 net: netConn, 66 irc: irc.NewConn(netConn), 67 srv: srv, 68 logger: &prefixLogger{srv.Logger, fmt.Sprintf("downstream %q: ", netConn.RemoteAddr())}, 69 messages: make(chan *irc.Message, 64), 70 consumptions: make(chan consumption), 71 closed: make(chan struct{}), 67 72 } 68 73 … … 87 92 // TODO: fill the host? 88 93 } 94 } 95 96 func (dc *downstreamConn) marshalChannel(uc *upstreamConn, name string) string { 97 return name 98 } 99 100 func (dc *downstreamConn) unmarshalChannel(name string) (*upstreamConn, string, error) { 101 // TODO: extract network name from channel name 102 ch, err := dc.user.getChannel(name) 103 if err != nil { 104 return nil, "", err 105 } 106 return ch.conn, ch.Name, nil 107 } 108 109 func (dc *downstreamConn) marshalNick(uc *upstreamConn, nick string) string { 110 if nick == uc.nick { 111 return dc.nick 112 } 113 return nick 114 } 115 116 func (dc *downstreamConn) marshalUserPrefix(uc *upstreamConn, prefix *irc.Prefix) *irc.Prefix { 117 if prefix.Name == uc.nick { 118 return dc.prefix() 119 } 120 return prefix 89 121 } 90 122 … … 139 171 } 140 172 err = dc.irc.WriteMessage(msg) 141 case consumer := <-dc.consumers: 173 case consumption := <-dc.consumptions: 174 consumer, uc := consumption.consumer, consumption.upstreamConn 142 175 for { 143 176 msg := consumer.Peek() 144 177 if msg == nil { 145 178 break 179 } 180 msg = msg.Copy() 181 switch msg.Command { 182 case "PRIVMSG": 183 // TODO: detect whether it's a user or a channel 184 msg.Params[0] = dc.marshalChannel(uc, msg.Params[0]) 185 default: 186 panic("expected to consume a PRIVMSG message") 146 187 } 147 188 if dc.srv.Debug { … … 304 345 select { 305 346 case <-ch: 306 dc.consum ers <- consumer347 dc.consumptions <- consumption{consumer, uc} 307 348 case <-dc.closed: 308 349 closed = true … … 339 380 uc.SendMessage(msg) 340 381 }) 341 case "JOIN" :382 case "JOIN", "PART": 342 383 var name string 343 384 if err := parseMessageParams(msg, &name); err != nil { … … 345 386 } 346 387 347 if ch, _ := dc.user.getChannel(name); ch != nil { 348 break // already joined 349 } 350 351 // TODO: extract network name from channel name 352 return ircError{&irc.Message{ 353 Command: irc.ERR_NOSUCHCHANNEL, 354 Params: []string{name, "Channel name ambiguous"}, 355 }} 356 case "PART": 357 var name string 358 if err := parseMessageParams(msg, &name); err != nil { 359 return err 360 } 361 362 ch, err := dc.user.getChannel(name) 388 uc, upstreamName, err := dc.unmarshalChannel(name) 363 389 if err != nil { 364 return err 365 } 366 367 ch.conn.SendMessage(msg) 368 // TODO: remove channel from upstream config 390 return ircError{&irc.Message{ 391 Command: irc.ERR_NOSUCHCHANNEL, 392 Params: []string{name, err.Error()}, 393 }} 394 } 395 396 uc.SendMessage(&irc.Message{ 397 Command: msg.Command, 398 Params: []string{upstreamName}, 399 }) 400 // TODO: add/remove channel from upstream config 369 401 case "MODE": 402 if msg.Prefix == nil { 403 return fmt.Errorf("missing prefix") 404 } 405 370 406 var name string 371 407 if err := parseMessageParams(msg, &name); err != nil { … … 379 415 380 416 if msg.Prefix.Name != name { 381 ch, err := dc.user.getChannel(name)417 uc, upstreamName, err := dc.unmarshalChannel(name) 382 418 if err != nil { 383 419 return err … … 385 421 386 422 if modeStr != "" { 387 ch.conn.SendMessage(msg) 423 uc.SendMessage(&irc.Message{ 424 Prefix: uc.prefix(), 425 Command: "MODE", 426 Params: []string{upstreamName, modeStr}, 427 }) 388 428 } else { 429 ch, ok := uc.channels[upstreamName] 430 if !ok { 431 return ircError{&irc.Message{ 432 Command: irc.ERR_NOSUCHCHANNEL, 433 Params: []string{name, "No such channel"}, 434 }} 435 } 436 389 437 dc.SendMessage(&irc.Message{ 390 438 Prefix: dc.srv.prefix(), 391 439 Command: irc.RPL_CHANNELMODEIS, 392 Params: []string{ ch.Name, string(ch.modes)},440 Params: []string{name, string(ch.modes)}, 393 441 }) 394 442 } … … 403 451 if modeStr != "" { 404 452 dc.user.forEachUpstream(func(uc *upstreamConn) { 405 uc.SendMessage(msg) 453 uc.SendMessage(&irc.Message{ 454 Prefix: uc.prefix(), 455 Command: "MODE", 456 Params: []string{uc.nick, modeStr}, 457 }) 406 458 }) 407 459 } else { … … 420 472 421 473 for _, name := range strings.Split(targetsStr, ",") { 422 ch, err := dc.user.getChannel(name)474 uc, upstreamName, err := dc.unmarshalChannel(name) 423 475 if err != nil { 424 476 return err 425 477 } 426 478 427 ch.conn.SendMessage(&irc.Message{428 Prefix: msg.Prefix,479 uc.SendMessage(&irc.Message{ 480 Prefix: uc.prefix(), 429 481 Command: "PRIVMSG", 430 Params: []string{ name, text},482 Params: []string{upstreamName, text}, 431 483 }) 432 484 }
Note:
See TracChangeset
for help on using the changeset viewer.