X-Git-Url: http://www.git.cypherpunks.ru/?p=goircd.git;a=blobdiff_plain;f=room.go;h=276397fd44f6e823671f94824225289dfafc48ec;hp=4bdb4b2f18427c728c762d74b85e6149bc7215f2;hb=7770e09e68f8dd0991ecd5a32383a89ac3e50857;hpb=ad68cf29f652c5bfa7822a10000e9da658fbf1d5 diff --git a/room.go b/room.go index 4bdb4b2..276397f 100644 --- a/room.go +++ b/room.go @@ -28,6 +28,10 @@ import ( var ( RERoom = regexp.MustCompile("^#[^\x00\x07\x0a\x0d ,:/]{1,200}$") + + rooms map[string]*Room = make(map[string]*Room) + + roomSinks map[*Room]chan ClientEvent = make(map[*Room]chan ClientEvent) ) // Sanitize room's name. It can consist of 1 to 50 ASCII symbols @@ -37,40 +41,36 @@ func RoomNameValid(name string) bool { } type Room struct { - Verbose bool - name string - topic string - key string - members map[*Client]bool - hostname *string - logSink chan<- LogEvent - stateSink chan<- StateEvent + name *string + topic *string + key *string + members map[*Client]struct{} } func (room Room) String() string { - return room.name + return *room.name } -func NewRoom(hostname *string, name string, logSink chan<- LogEvent, stateSink chan<- StateEvent) *Room { - room := Room{name: name} - room.members = make(map[*Client]bool) - room.topic = "" - room.key = "" - room.hostname = hostname - room.logSink = logSink - room.stateSink = stateSink - return &room +func NewRoom(name string) *Room { + topic := "" + key := "" + return &Room{ + name: &name, + topic: &topic, + key: &key, + members: make(map[*Client]struct{}), + } } func (room *Room) SendTopic(client *Client) { - if room.topic == "" { - client.ReplyNicknamed("331", room.name, "No topic is set") + if *room.topic == "" { + client.ReplyNicknamed("331", *room.name, "No topic is set") } else { - client.ReplyNicknamed("332", room.name, room.topic) + client.ReplyNicknamed("332", *room.name, *room.topic) } } -// Send message to all room's subscribers, possibly excluding someone +// Send message to all room's subscribers, possibly excluding someone. func (room *Room) Broadcast(msg string, clientToIgnore ...*Client) { for member := range room.members { if (len(clientToIgnore) > 0) && member == clientToIgnore[0] { @@ -81,7 +81,7 @@ func (room *Room) Broadcast(msg string, clientToIgnore ...*Client) { } func (room *Room) StateSave() { - room.stateSink <- StateEvent{room.name, room.topic, room.key} + stateSink <- StateEvent{*room.name, *room.topic, *room.key} } func (room *Room) Processor(events <-chan ClientEvent) { @@ -89,46 +89,50 @@ func (room *Room) Processor(events <-chan ClientEvent) { for event := range events { client = event.client switch event.eventType { + case EventTerm: + roomsGroup.Done() + return case EventNew: - room.members[client] = true - if room.Verbose { + room.members[client] = struct{}{} + if *verbose { log.Println(client, "joined", room.name) } room.SendTopic(client) - room.Broadcast(fmt.Sprintf(":%s JOIN %s", client, room.name)) - room.logSink <- LogEvent{room.name, client.nickname, "joined", true} - nicknames := []string{} + room.Broadcast(fmt.Sprintf(":%s JOIN %s", client, *room.name)) + logSink <- LogEvent{*room.name, *client.nickname, "joined", true} + nicknames := make([]string, 0) for member := range room.members { - nicknames = append(nicknames, member.nickname) + nicknames = append(nicknames, *member.nickname) } sort.Strings(nicknames) - client.ReplyNicknamed("353", "=", room.name, strings.Join(nicknames, " ")) - client.ReplyNicknamed("366", room.name, "End of NAMES list") + client.ReplyNicknamed("353", "=", *room.name, strings.Join(nicknames, " ")) + client.ReplyNicknamed("366", *room.name, "End of NAMES list") case EventDel: if _, subscribed := room.members[client]; !subscribed { - client.ReplyNicknamed("442", room.name, "You are not on that channel") + client.ReplyNicknamed("442", *room.name, "You are not on that channel") continue } delete(room.members, client) - msg := fmt.Sprintf(":%s PART %s :%s", client, room.name, client.nickname) + msg := fmt.Sprintf(":%s PART %s :%s", client, *room.name, *client.nickname) room.Broadcast(msg) - room.logSink <- LogEvent{room.name, client.nickname, "left", true} + logSink <- LogEvent{*room.name, *client.nickname, "left", true} case EventTopic: if _, subscribed := room.members[client]; !subscribed { - client.ReplyParts("442", room.name, "You are not on that channel") + client.ReplyParts("442", *room.name, "You are not on that channel") continue } if event.text == "" { - go room.SendTopic(client) + room.SendTopic(client) continue } - room.topic = strings.TrimLeft(event.text, ":") - msg := fmt.Sprintf(":%s TOPIC %s :%s", client, room.name, room.topic) - go room.Broadcast(msg) - room.logSink <- LogEvent{ - room.name, - client.nickname, - "set topic to " + room.topic, + topic := strings.TrimLeft(event.text, ":") + room.topic = &topic + msg := fmt.Sprintf(":%s TOPIC %s :%s", client, *room.name, *room.topic) + room.Broadcast(msg) + logSink <- LogEvent{ + *room.name, + *client.nickname, + "set topic to " + *room.topic, true, } room.StateSave() @@ -136,32 +140,32 @@ func (room *Room) Processor(events <-chan ClientEvent) { for m := range room.members { client.ReplyNicknamed( "352", - room.name, - m.username, - m.conn.RemoteAddr().String(), - *room.hostname, - m.nickname, + *room.name, + *m.username, + m.Host(), + *hostname, + *m.nickname, "H", - "0 "+m.realname, + "0 "+*m.realname, ) } - client.ReplyNicknamed("315", room.name, "End of /WHO list") + client.ReplyNicknamed("315", *room.name, "End of /WHO list") case EventMode: if event.text == "" { mode := "+" - if room.key != "" { + if *room.key != "" { mode = mode + "k" } - client.Msg(fmt.Sprintf("324 %s %s %s", client.nickname, room.name, mode)) + client.Msg(fmt.Sprintf("324 %s %s %s", *client.nickname, *room.name, mode)) continue } if strings.HasPrefix(event.text, "b") { - client.ReplyNicknamed("368", room.name, "End of channel ban list") + client.ReplyNicknamed("368", *room.name, "End of channel ban list") continue } if strings.HasPrefix(event.text, "-k") || strings.HasPrefix(event.text, "+k") { if _, subscribed := room.members[client]; !subscribed { - client.ReplyParts("442", room.name, "You are not on that channel") + client.ReplyParts("442", *room.name, "You are not on that channel") continue } } else { @@ -176,16 +180,17 @@ func (room *Room) Processor(events <-chan ClientEvent) { client.ReplyNotEnoughParameters("MODE") continue } - room.key = cols[1] - msg = fmt.Sprintf(":%s MODE %s +k %s", client, room.name, room.key) - msgLog = "set channel key to " + room.key - } else if strings.HasPrefix(event.text, "-k") { - room.key = "" - msg = fmt.Sprintf(":%s MODE %s -k", client, room.name) + room.key = &cols[1] + msg = fmt.Sprintf(":%s MODE %s +k %s", client, *room.name, *room.key) + msgLog = "set channel key to " + *room.key + } else { + key := "" + room.key = &key + msg = fmt.Sprintf(":%s MODE %s -k", client, *room.name) msgLog = "removed channel key" } - go room.Broadcast(msg) - room.logSink <- LogEvent{room.name, client.nickname, msgLog, true} + room.Broadcast(msg) + logSink <- LogEvent{*room.name, *client.nickname, msgLog, true} room.StateSave() case EventMsg: sep := strings.Index(event.text, " ") @@ -193,13 +198,13 @@ func (room *Room) Processor(events <-chan ClientEvent) { ":%s %s %s :%s", client, event.text[:sep], - room.name, + *room.name, event.text[sep+1:]), client, ) - room.logSink <- LogEvent{ - room.name, - client.nickname, + logSink <- LogEvent{ + *room.name, + *client.nickname, event.text[sep+1:], false, }