// Set the user's nick. func (u *User) SetNick(nick string) os.Error { if !parser.ValidNick(nick) { return parser.NewNumeric(parser.ERR_ERRONEUSNICKNAME, nick) } lownick := parser.ToLower(nick) userMutex.Lock() defer userMutex.Unlock() if id, used := userNicks[lownick]; used { if id == u.ID() { return nil } return parser.NewNumeric(parser.ERR_NICKNAMEINUSE, nick) } userNicks[lownick] = u.ID() lownick = parser.ToLower(u.nick) userNicks[lownick] = "", false u.mutex.Lock() defer u.mutex.Unlock() u.nick = nick u.ts = time.Nanoseconds() return nil }
// Get the Channel structure for the given channel. If it does not exist and // create is true, it is created. func Get(name string, create bool) (*Channel, os.Error) { chanMutex.Lock() defer chanMutex.Unlock() if !parser.ValidChannel(name) { return nil, parser.NewNumeric(parser.ERR_NOSUCHCHANNEL, name) } lowname := parser.ToLower(name) // Database lookup? if c, ok := chanMap[lowname]; ok { return c, nil } else if !create { return nil, parser.NewNumeric(parser.ERR_NOSUCHCHANNEL, name) } c := &Channel{ mutex: new(sync.RWMutex), name: name, users: make(map[string]string), } chanMap[lowname] = c return c, nil }
// Join a user to the channel. func (c *Channel) Join(uids ...string) (notify []string, err os.Error) { c.mutex.Lock() defer c.mutex.Unlock() for _, uid := range uids { if _, on := c.users[uid]; on { return nil, parser.NewNumeric(parser.ERR_USERONCHANNEL, uid, c.name) } // TODO(kevlar): Check hostmask c.users[uid] = "host@mask" c.ts = time.Nanoseconds() } notify = make([]string, 0, len(c.users)) for id := range c.users { notify = append(notify, id) } // Make sure that this channel exists (bad news if it doesn't) chanMutex.Lock() defer chanMutex.Unlock() if _, exist := chanMap[c.name]; !exist { chanMap[c.name] = c } return }
// Set the user's type (immutable once set). func (u *User) SetType(newType userType) os.Error { if u.utyp != Unregistered { return parser.NewNumeric(parser.ERR_ALREADYREGISTRED) } u.utyp = newType u.ts = time.Nanoseconds() return nil }
// Set the user and gecos (immutable once set). func (u *User) SetUser(user, name string) os.Error { if len(u.user) > 0 { return parser.NewNumeric(parser.ERR_ALREADYREGISTRED) } if !parser.ValidNick(user) || len(name) == 0 { // BUG(kevlar): Document this behavior return parser.NewNumeric(parser.ERR_NEEDMOREPARAMS) } u.mutex.Lock() defer u.mutex.Unlock() u.user, u.name = user, name u.ts = time.Nanoseconds() return nil }
func sendSignon(u *user.User, ircd *IRCd) { log.Info.Printf("[%s] ** Registered\n", u.ID()) u.SetType(user.RegisteredAsUser) destIDs := []string{u.ID()} // RPL_WELCOME msg := parser.NewNumeric(parser.RPL_WELCOME).Message() msg.Args[1] = "Welcome to the " + Config.Network.Name + " network, " + u.Nick() + "!" msg.DestIDs = destIDs ircd.ToClient <- msg // RPL_YOURHOST msg = parser.NewNumeric(parser.RPL_YOURHOST).Message() msg.Args[1] = "Your host is " + Config.Name + ", running " + REPO_VERSION msg.DestIDs = destIDs ircd.ToClient <- msg // RPL_CREATED // RPL_MYINFO // RPL_ISUPPORT // RPL_LUSERCLIENT // RPL_LUSEROP // RPL_LUSERUNKNOWN // RPL_LUSERCHANNELS // RPL_LUSERME // RPL_LOCALUSERS // RPL_GLOBALUSERS // RPL_NOMOTD msg = parser.NewNumeric(parser.ERR_NOMOTD).Message() msg.DestIDs = destIDs ircd.ToClient <- msg msg = &parser.Message{ Command: parser.CMD_MODE, Prefix: "*", Args: []string{ "*", "+i", }, DestIDs: destIDs, } ircd.ToClient <- msg }
// Get the ID for a particular nick. func GetID(nick string) (id string, err os.Error) { userMutex.RLock() defer userMutex.RUnlock() lownick := parser.ToLower(nick) if _, ok := userMap[nick]; ok { return nick, nil } var ok bool if id, ok = userNicks[lownick]; !ok { err = parser.NewNumeric(parser.ERR_NOSUCHNICK, nick) } return }
// Part a user from the channel. func (c *Channel) Part(uid string) (notify []string, err os.Error) { c.mutex.Lock() defer c.mutex.Unlock() if _, on := c.users[uid]; !on { return nil, parser.NewNumeric(parser.ERR_NOTONCHANNEL, c.name) } notify = make([]string, 0, len(c.users)) for id := range c.users { notify = append(notify, id) } c.users[uid] = "", false c.ts = time.Nanoseconds() if len(c.users) == 0 { chanMutex.Lock() defer chanMutex.Unlock() chanMap[c.name] = nil, false } return }
Chans int Notify []string }{ { ID: "A", Command: parser.CMD_JOIN, Channel: "#chan", Error: nil, Chans: 1, Notify: []string{"A"}, }, { ID: "B", Command: parser.CMD_PART, Channel: "#chan", Error: parser.NewNumeric(parser.ERR_NOTONCHANNEL, ""), Chans: 1, Notify: nil, }, { ID: "B", Command: parser.CMD_JOIN, Channel: "#chan", Error: nil, Chans: 1, Notify: []string{"A", "B"}, }, { ID: "A", Command: parser.CMD_PART, Channel: "#chan",