- Timestamp:
- Feb 19, 2020, 5:25:19 PM (5 years ago)
- Location:
- trunk
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/bridge.go
r54 r69 10 10 } 11 11 12 downstreamName := dc.marshalChannel(ch.conn, ch.Name) 13 12 14 dc.SendMessage(&irc.Message{ 13 15 Prefix: dc.prefix(), 14 16 Command: "JOIN", 15 Params: []string{ ch.Name},17 Params: []string{downstreamName}, 16 18 }) 17 19 … … 20 22 Prefix: dc.srv.prefix(), 21 23 Command: irc.RPL_TOPIC, 22 Params: []string{dc.nick, ch.Name, ch.Topic},24 Params: []string{dc.nick, downstreamName, ch.Topic}, 23 25 }) 24 26 } else { … … 26 28 Prefix: dc.srv.prefix(), 27 29 Command: irc.RPL_NOTOPIC, 28 Params: []string{dc.nick, ch.Name, "No topic is set"},30 Params: []string{dc.nick, downstreamName, "No topic is set"}, 29 31 }) 30 32 } … … 34 36 // TODO: send multiple members in each message 35 37 for nick, membership := range ch.Members { 36 s := nick38 s := dc.marshalNick(ch.conn, nick) 37 39 if membership != 0 { 38 s = string(membership) + nick40 s = string(membership) + s 39 41 } 40 42 … … 42 44 Prefix: dc.srv.prefix(), 43 45 Command: irc.RPL_NAMREPLY, 44 Params: []string{dc.nick, string(ch.Status), ch.Name, s},46 Params: []string{dc.nick, string(ch.Status), downstreamName, s}, 45 47 }) 46 48 } … … 49 51 Prefix: dc.srv.prefix(), 50 52 Command: irc.RPL_ENDOFNAMES, 51 Params: []string{dc.nick, ch.Name, "End of /NAMES list"},53 Params: []string{dc.nick, downstreamName, "End of /NAMES list"}, 52 54 }) 53 55 } -
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 } -
trunk/upstream.go
r68 r69 92 92 } 93 93 94 func (uc *upstreamConn) prefix() *irc.Prefix { 95 return &irc.Prefix{ 96 Name: uc.nick, 97 User: uc.upstream.Username, 98 // TODO: fill the host? 99 } 100 } 101 94 102 func (uc *upstreamConn) Close() error { 95 103 if uc.closed { … … 118 126 return nil 119 127 case "MODE": 128 if msg.Prefix == nil { 129 return fmt.Errorf("missing prefix") 130 } 131 120 132 var name, modeStr string 121 133 if err := parseMessageParams(msg, &name, &modeStr); err != nil { … … 136 148 return err 137 149 } 138 } 139 140 uc.user.forEachDownstream(func(dc *downstreamConn) { 141 dc.SendMessage(msg) 142 }) 150 151 uc.user.forEachDownstream(func(dc *downstreamConn) { 152 dc.SendMessage(&irc.Message{ 153 Prefix: dc.marshalUserPrefix(uc, msg.Prefix), 154 Command: "MODE", 155 Params: []string{dc.marshalChannel(uc, name), modeStr}, 156 }) 157 }) 158 } 143 159 case "NOTICE": 144 160 uc.logger.Print(msg) … … 177 193 } 178 194 } 179 180 uc.user.forEachDownstream(func(dc *downstreamConn) {181 dc.SendMessage(msg)182 })183 195 case "JOIN": 196 if msg.Prefix == nil { 197 return fmt.Errorf("expected a prefix") 198 } 199 184 200 var channels string 185 201 if err := parseMessageParams(msg, &channels); err != nil { … … 202 218 ch.Members[msg.Prefix.Name] = 0 203 219 } 204 } 205 206 uc.user.forEachDownstream(func(dc *downstreamConn) { 207 dc.SendMessage(msg) 208 }) 220 221 uc.user.forEachDownstream(func(dc *downstreamConn) { 222 dc.SendMessage(&irc.Message{ 223 Prefix: dc.marshalUserPrefix(uc, msg.Prefix), 224 Command: "JOIN", 225 Params: []string{dc.marshalChannel(uc, ch)}, 226 }) 227 }) 228 } 209 229 case "PART": 230 if msg.Prefix == nil { 231 return fmt.Errorf("expected a prefix") 232 } 233 210 234 var channels string 211 235 if err := parseMessageParams(msg, &channels); err != nil { … … 224 248 delete(ch.Members, msg.Prefix.Name) 225 249 } 226 } 227 228 uc.user.forEachDownstream(func(dc *downstreamConn) { 229 dc.SendMessage(msg) 230 }) 250 251 uc.user.forEachDownstream(func(dc *downstreamConn) { 252 dc.SendMessage(&irc.Message{ 253 Prefix: dc.marshalUserPrefix(uc, msg.Prefix), 254 Command: "PART", 255 Params: []string{dc.marshalChannel(uc, ch)}, 256 }) 257 }) 258 } 231 259 case irc.RPL_TOPIC, irc.RPL_NOTOPIC: 232 260 var name, topic string … … 311 339 }) 312 340 case "PRIVMSG": 341 if err := parseMessageParams(msg, nil, nil); err != nil { 342 return err 343 } 313 344 uc.ring.Produce(msg) 314 345 case irc.RPL_YOURHOST, irc.RPL_CREATED: … … 332 363 uc.SendMessage(&irc.Message{ 333 364 Command: "NICK", 334 Params: []string{uc. upstream.Nick},365 Params: []string{uc.nick}, 335 366 }) 336 367 uc.SendMessage(&irc.Message{
Note:
See TracChangeset
for help on using the changeset viewer.