func TestRoomDoesntBroadcastAnnounceMessagesWhenQuiet(t *testing.T) { u := message.NewUser(message.SimpleId("foo")) u.Config = message.UserConfig{ Quiet: true, } ch := NewRoom() defer ch.Close() _, err := ch.Join(u) if err != nil { t.Fatal(err) } // Drain the initial Join message <-ch.broadcast go func() { for msg := range u.ConsumeChan() { if _, ok := msg.(*message.AnnounceMsg); ok { t.Errorf("Got unexpected `%T`", msg) } } }() // Call with an AnnounceMsg and all the other types // and assert we received only non-announce messages ch.HandleMsg(message.NewAnnounceMsg("Ignored")) // Assert we still get all other types of messages ch.HandleMsg(message.NewEmoteMsg("hello", u)) ch.HandleMsg(message.NewSystemMsg("hello", u)) ch.HandleMsg(message.NewPrivateMsg("hello", u, u)) ch.HandleMsg(message.NewPublicMsg("hello", u)) }
// InitCommands adds host-specific commands to a Commands container. These will // override any existing commands. func (h *Host) InitCommands(c *chat.Commands) { c.Add(chat.Command{ Prefix: "/msg", PrefixHelp: "USER MESSAGE", Help: "Send MESSAGE to USER.", Handler: func(room *chat.Room, msg message.CommandMsg) error { args := msg.Args() switch len(args) { case 0: return errors.New("must specify user") case 1: return errors.New("must specify message") } target, ok := h.GetUser(args[0]) if !ok { return errors.New("user not found") } m := message.NewPrivateMsg(strings.Join(args[1:], " "), msg.From(), target) room.Send(m) return nil }, }) c.Add(chat.Command{ Prefix: "/reply", PrefixHelp: "MESSAGE", Help: "Reply with MESSAGE to the previous private message.", Handler: func(room *chat.Room, msg message.CommandMsg) error { args := msg.Args() switch len(args) { case 0: return errors.New("must specify message") } target := msg.From().ReplyTo() if target == nil { return errors.New("no message to reply to") } m := message.NewPrivateMsg(strings.Join(args, " "), msg.From(), target) room.Send(m) return nil }, }) c.Add(chat.Command{ Prefix: "/whois", PrefixHelp: "USER", Help: "Information about USER.", Handler: func(room *chat.Room, msg message.CommandMsg) error { args := msg.Args() if len(args) == 0 { return errors.New("must specify user") } target, ok := h.GetUser(args[0]) if !ok { return errors.New("user not found") } id := target.Identifier.(*Identity) room.Send(message.NewSystemMsg(id.Whois(), msg.From())) return nil }, }) // Hidden commands c.Add(chat.Command{ Prefix: "/version", Handler: func(room *chat.Room, msg message.CommandMsg) error { room.Send(message.NewSystemMsg(buildCommit, msg.From())) return nil }, }) timeStarted := time.Now() c.Add(chat.Command{ Prefix: "/uptime", Handler: func(room *chat.Room, msg message.CommandMsg) error { room.Send(message.NewSystemMsg(time.Now().Sub(timeStarted).String(), msg.From())) return nil }, }) // Op commands c.Add(chat.Command{ Op: true, Prefix: "/kick", PrefixHelp: "USER", Help: "Kick USER from the server.", Handler: func(room *chat.Room, msg message.CommandMsg) error { if !room.IsOp(msg.From()) { return errors.New("must be op") } args := msg.Args() if len(args) == 0 { return errors.New("must specify user") } target, ok := h.GetUser(args[0]) if !ok { return errors.New("user not found") } body := fmt.Sprintf("%s was kicked by %s.", target.Name(), msg.From().Name()) room.Send(message.NewAnnounceMsg(body)) target.Close() return nil }, }) c.Add(chat.Command{ Op: true, Prefix: "/ban", PrefixHelp: "USER [DURATION]", Help: "Ban USER from the server.", Handler: func(room *chat.Room, msg message.CommandMsg) error { // TODO: Would be nice to specify what to ban. Key? Ip? etc. if !room.IsOp(msg.From()) { return errors.New("must be op") } args := msg.Args() if len(args) == 0 { return errors.New("must specify user") } target, ok := h.GetUser(args[0]) if !ok { return errors.New("user not found") } var until time.Duration = 0 if len(args) > 1 { until, _ = time.ParseDuration(args[1]) } id := target.Identifier.(*Identity) h.auth.Ban(id.PublicKey(), until) h.auth.BanAddr(id.RemoteAddr(), until) body := fmt.Sprintf("%s was banned by %s.", target.Name(), msg.From().Name()) room.Send(message.NewAnnounceMsg(body)) target.Close() logger.Debugf("Banned: \n-> %s", id.Whois()) return nil }, }) c.Add(chat.Command{ Op: true, Prefix: "/motd", PrefixHelp: "MESSAGE", Help: "Set the MESSAGE of the day.", Handler: func(room *chat.Room, msg message.CommandMsg) error { if !room.IsOp(msg.From()) { return errors.New("must be op") } motd := "" args := msg.Args() if len(args) > 0 { motd = strings.Join(args, " ") } h.motd = motd body := fmt.Sprintf("New message of the day set by %s:", msg.From().Name()) room.Send(message.NewAnnounceMsg(body)) if motd != "" { room.Send(message.NewAnnounceMsg(motd)) } return nil }, }) c.Add(chat.Command{ Op: true, Prefix: "/op", PrefixHelp: "USER [DURATION]", Help: "Set USER as admin.", Handler: func(room *chat.Room, msg message.CommandMsg) error { if !room.IsOp(msg.From()) { return errors.New("must be op") } args := msg.Args() if len(args) == 0 { return errors.New("must specify user") } var until time.Duration = 0 if len(args) > 1 { until, _ = time.ParseDuration(args[1]) } member, ok := room.MemberById(args[0]) if !ok { return errors.New("user not found") } member.Op = true id := member.Identifier.(*Identity) h.auth.Op(id.PublicKey(), until) body := fmt.Sprintf("Made op by %s.", msg.From().Name()) room.Send(message.NewSystemMsg(body, member.User)) return nil }, }) }