// accept handles the initial negotiation phase for connecting to the // server. This is basically in 4 parts: // // * PASS // * NICK // * USER // // On success a RPL_WELCOME response is returned to the new client. func (s *Server) accept(conn net.Conn) bool { r := bufio.NewReader(conn) line, err := r.ReadBytes('\n') if err != nil { log.Println(err) return false } parsed := message.Parse(string(line)) if parsed.Command != "PASS" { return false } if !parsed.Params.Any() { conn.Write([]byte(errors.NeedMoreParams(s.Name(), "PASS").String())) return false } password := parsed.Params.Get(0) if password != "test" { return false } client := NewClient("", conn, s) s.clients.Add(client) return true }
func Whois(c Client, s Server, args []string) { if len(args) < 1 { c.Send(errors.NeedMoreParams(s.Name(), "WHOIS")) return } subject, ok := s.Find(args[0]) user, isClient := subject.(Client) if !ok || !isClient { c.Send(errors.NoSuchNick(s.Name(), args[0])) c.Send(reply.EndOfWhois(s.Name(), args[0])) return } if user.AwayMessage() != "" { c.Send(reply.Away(s.Name(), user.Name(), user.AwayMessage())) } c.Send(reply.WhoIsUser(s.Name(), user.Name(), user.UserName(), user.RealName())) c.Send(reply.WhoIsServer(s.Name(), user.Name())) if user.Channels().Any() { resp := reply.WhoIsChannels(s.Name(), user.Name(), user.Channels().Names()) for _, part := range resp.Parts() { c.Send(part) } } c.Send(reply.WhoIsIdle(s.Name(), user.Name(), 0)) c.Send(reply.EndOfWhois(s.Name(), args[0])) }
func Invite(c Client, s Server, args []string) { if len(args) < 2 { c.Send(errors.NeedMoreParams(s.Name(), "INVITE")) return } subject, ok := s.Find(args[0]) user, isClient := subject.(Client) if !ok || !isClient { c.Send(errors.NoSuchNick(s.Name(), args[0])) return } if _, ok := c.Channels().Find(args[1]); !ok { c.Send(errors.NotOnChannel(s.Name(), args[1])) return } if _, ok := user.Channels().Find(args[1]); ok { c.Send(errors.UserOnChannel(s.Name(), user.Name(), args[1])) return } subject.Send(reply.Invite(c.Name(), c.UserName(), s.Name(), subject.Name(), args[1])) }
func Notice(c Client, s Server, args []string) { if len(args) < 2 { c.Send(errors.NeedMoreParams(s.Name(), "NOTICE")) return } subject, ok := s.Find(args[0]) if ok { msg := reply.Notice(c.Name(), c.UserName(), s.Name(), args[0], args[1]) subject.SendExcept(msg, c.Name()) } }
func Join(c Client, s Server, args []string) { if len(args) < 1 { c.Send(errors.NeedMoreParams(s.Name(), "JOIN")) return } names := strings.Split(args[0], ",") for _, name := range names { channel := s.Join(c, name) channel.Send(reply.Join(c.Name(), c.UserName(), s.Name(), channel.Name())) c.Channels().Add(channel) Topic(c, s, []string{name}) } }
func Part(c Client, s Server, args []string) { if len(args) < 1 { c.Send(errors.NeedMoreParams(s.Name(), "PART")) return } channel, ok := c.Channels().Find(args[0]) if !ok { c.Send(errors.NotOnChannel(s.Name(), args[0])) return } channel.Send(reply.Part(c.Name(), c.UserName(), s.Name(), channel.Name())) s.Part(c, args[0]) }
func PrivMsg(c Client, s Server, args []string) { if len(args) < 2 { c.Send(errors.NeedMoreParams(s.Name(), "PRIVMSG")) return } subject, ok := s.Find(args[0]) if ok { msg := reply.PrivMsg(c.Name(), c.UserName(), s.Name(), args[0], args[1]) subject.SendExcept(msg, c.Name()) if other, ok := subject.(Client); ok && other.AwayMessage() != "" { c.Send(reply.Away(s.Name(), subject.Name(), other.AwayMessage())) } } }
func Names(c Client, s Server, args []string) { if len(args) < 1 { c.Send(errors.NeedMoreParams(s.Name(), "NAMES")) return } channel := s.FindChannel(args[0]) resp := reply.NameReply(s.Name(), c.Name(), channel.Name(), channel.Names()) for _, part := range resp.Parts() { c.Send(part) } c.Send(reply.EndOfNames(s.Name(), c.Name(), channel.Name())) }
func User(c Client, s Server, args []string) { if len(args) < 4 { c.Send(errors.NeedMoreParams(s.Name(), "USER")) return } if c.RealName() != "" { c.Send(errors.AlreadyRegistered(s.Name())) return } // <user> <mode> <unused> <realname> c.SetUserName(args[0]) c.SetMode(args[1]) c.SetRealName(args[3]) c.Send(reply.Welcome(s.Name(), c.Name())) }
func Topic(c Client, s Server, args []string) { switch len(args) { case 1: channel := s.FindChannel(args[0]) if channel.Topic == "" { c.Send(reply.NoTopic(s.Name(), channel.Name())) } else { c.Send(reply.Topic(s.Name(), channel.Name(), channel.Topic)) } case 2: channel := s.FindChannel(args[0]) channel.Topic = args[1] channel.Send(reply.TopicChange(c.Name(), c.UserName(), s.Name(), channel.Name(), channel.Topic)) default: c.Send(errors.NeedMoreParams(s.Name(), "TOPIC")) } }
func Mode(c Client, s Server, args []string) { if len(args) < 1 { c.Send(errors.NeedMoreParams(s.Name(), "MODE")) return } subject, ok := s.Find(args[0]) if !ok { return } if _, ok := subject.(Client); ok { c.Send(reply.UserModeIs(s.Name(), c.Name())) } else { if len(args) == 2 && strings.Contains(args[1], "b") { c.Send(reply.EndOfBanList(s.Name(), c.Name(), subject.Name())) } else { c.Send(reply.ChannelModeIs(s.Name(), c.Name(), subject.Name())) } } }
func Who(c Client, s Server, args []string) { if len(args) < 1 { c.Send(errors.NeedMoreParams(s.Name(), "WHO")) return } subject, ok := s.Find(args[0]) if ok { if user, ok := subject.(Client); ok { c.Send(reply.WhoReply(s.Name(), c.Name(), args[0], user.UserName(), user.Name(), user.RealName())) } else { channel, _ := subject.(*channel.Channel) for _, client := range channel.Clients() { user, _ := client.(Client) c.Send(reply.WhoReply(s.Name(), c.Name(), args[0], user.UserName(), user.Name(), user.RealName())) } } } c.Send(reply.EndOfWho(s.Name(), c.Name(), args[0])) }