3
0
mirror of https://github.com/ergochat/ergo.git synced 2024-11-10 22:19:31 +01:00

move modes code to its own file; fix SQL (un)marshalling

This commit is contained in:
Jeremy Latt 2014-03-13 13:18:40 -07:00
parent 4ed0d78d87
commit d85e6681d9
7 changed files with 173 additions and 136 deletions

View File

@ -444,8 +444,8 @@ func (channel *Channel) Persist() (err error) {
(name, flags, key, topic, user_limit, ban_list, except_list, (name, flags, key, topic, user_limit, ban_list, except_list,
invite_list) invite_list)
VALUES (?, ?, ?, ?, ?, ?, ?, ?)`, VALUES (?, ?, ?, ?, ?, ?, ?, ?)`,
channel.name, channel.flags.String(), channel.key, channel.topic, channel.name.String(), channel.flags.String(), channel.key.String(),
channel.userLimit, channel.lists[BanMask].String(), channel.topic.String(), channel.userLimit, channel.lists[BanMask].String(),
channel.lists[ExceptMask].String(), channel.lists[InviteMask].String()) channel.lists[ExceptMask].String(), channel.lists[InviteMask].String())
} else { } else {
_, err = channel.server.db.Exec(` _, err = channel.server.db.Exec(`

View File

@ -153,7 +153,7 @@ func NewClientDB() *ClientDB {
func (db *ClientDB) Add(client *Client) { func (db *ClientDB) Add(client *Client) {
_, err := db.db.Exec(`INSERT INTO client (nickname, userhost) VALUES (?, ?)`, _, err := db.db.Exec(`INSERT INTO client (nickname, userhost) VALUES (?, ?)`,
client.Nick(), client.UserHost()) client.Nick().String(), client.UserHost().String())
if err != nil { if err != nil {
Log.error.Println("ClientDB.Add:", err) Log.error.Println("ClientDB.Add:", err)
} }
@ -161,7 +161,7 @@ func (db *ClientDB) Add(client *Client) {
func (db *ClientDB) Remove(client *Client) { func (db *ClientDB) Remove(client *Client) {
_, err := db.db.Exec(`DELETE FROM client WHERE nickname = ?`, _, err := db.db.Exec(`DELETE FROM client WHERE nickname = ?`,
client.Nick()) client.Nick().String())
if err != nil { if err != nil {
Log.error.Println("ClientDB.Remove:", err) Log.error.Println("ClientDB.Remove:", err)
} }

View File

@ -1,14 +1,5 @@
package irc package irc
import (
"errors"
)
var (
// errors
ErrAlreadyDestroyed = errors.New("already destroyed")
)
const ( const (
SEM_VER = "ergonomadic-1.3.1" SEM_VER = "ergonomadic-1.3.1"
CRLF = "\r\n" CRLF = "\r\n"
@ -184,35 +175,4 @@ const (
ERR_NOOPERHOST NumericCode = 491 ERR_NOOPERHOST NumericCode = 491
ERR_UMODEUNKNOWNFLAG NumericCode = 501 ERR_UMODEUNKNOWNFLAG NumericCode = 501
ERR_USERSDONTMATCH NumericCode = 502 ERR_USERSDONTMATCH NumericCode = 502
Add ModeOp = '+'
List ModeOp = '='
Remove ModeOp = '-'
Away UserMode = 'a'
Invisible UserMode = 'i'
LocalOperator UserMode = 'O'
Operator UserMode = 'o'
Restricted UserMode = 'r'
ServerNotice UserMode = 's' // deprecated
WallOps UserMode = 'w'
Anonymous ChannelMode = 'a' // flag
BanMask ChannelMode = 'b' // arg
ChannelCreator ChannelMode = 'O' // flag
ChannelOperator ChannelMode = 'o' // arg
ExceptMask ChannelMode = 'e' // arg
InviteMask ChannelMode = 'I' // arg
InviteOnly ChannelMode = 'i' // flag
Key ChannelMode = 'k' // flag arg
Moderated ChannelMode = 'm' // flag
NoOutside ChannelMode = 'n' // flag
OpOnlyTopic ChannelMode = 't' // flag
Persistent ChannelMode = 'P' // flag
Private ChannelMode = 'p' // flag
Quiet ChannelMode = 'q' // flag
ReOp ChannelMode = 'r' // flag
Secret ChannelMode = 's' // flag, deprecated
UserLimit ChannelMode = 'l' // flag arg
Voice ChannelMode = 'v' // arg
) )

162
irc/modes.go Normal file
View File

@ -0,0 +1,162 @@
package irc
import (
"strings"
)
// user mode flags
type UserMode rune
func (mode UserMode) String() string {
return string(mode)
}
type UserModes []UserMode
func (modes UserModes) String() string {
strs := make([]string, len(modes))
for index, mode := range modes {
strs[index] = mode.String()
}
return strings.Join(strs, "")
}
// channel mode flags
type ChannelMode rune
func (mode ChannelMode) String() string {
return string(mode)
}
type ChannelModes []ChannelMode
func (modes ChannelModes) String() string {
strs := make([]string, len(modes))
for index, mode := range modes {
strs[index] = mode.String()
}
return strings.Join(strs, "")
}
type ModeOp rune
func (op ModeOp) String() string {
return string(op)
}
const (
Add ModeOp = '+'
List ModeOp = '='
Remove ModeOp = '-'
)
const (
Away UserMode = 'a'
Invisible UserMode = 'i'
LocalOperator UserMode = 'O'
Operator UserMode = 'o'
Restricted UserMode = 'r'
ServerNotice UserMode = 's' // deprecated
WallOps UserMode = 'w'
)
var (
SupportedUserModes = UserModes{
Away, Invisible, Operator,
}
)
const (
Anonymous ChannelMode = 'a' // flag
BanMask ChannelMode = 'b' // arg
ChannelCreator ChannelMode = 'O' // flag
ChannelOperator ChannelMode = 'o' // arg
ExceptMask ChannelMode = 'e' // arg
InviteMask ChannelMode = 'I' // arg
InviteOnly ChannelMode = 'i' // flag
Key ChannelMode = 'k' // flag arg
Moderated ChannelMode = 'm' // flag
NoOutside ChannelMode = 'n' // flag
OpOnlyTopic ChannelMode = 't' // flag
Persistent ChannelMode = 'P' // flag
Private ChannelMode = 'p' // flag
Quiet ChannelMode = 'q' // flag
ReOp ChannelMode = 'r' // flag
Secret ChannelMode = 's' // flag, deprecated
UserLimit ChannelMode = 'l' // flag arg
Voice ChannelMode = 'v' // arg
)
var (
SupportedChannelModes = ChannelModes{
BanMask, ExceptMask, InviteMask, InviteOnly, Key, NoOutside,
OpOnlyTopic, Persistent, Private, UserLimit,
}
)
//
// commands
//
func (m *ModeCommand) HandleServer(s *Server) {
client := m.Client()
target := s.clients.Get(m.nickname)
if target == nil {
client.ErrNoSuchNick(m.nickname)
return
}
if client != target && !client.flags[Operator] {
client.ErrUsersDontMatch()
return
}
changes := make(ModeChanges, 0, len(m.changes))
for _, change := range m.changes {
switch change.mode {
case Invisible, ServerNotice, WallOps:
switch change.op {
case Add:
if target.flags[change.mode] {
continue
}
target.flags[change.mode] = true
changes = append(changes, change)
case Remove:
if !target.flags[change.mode] {
continue
}
delete(target.flags, change.mode)
changes = append(changes, change)
}
case Operator, LocalOperator:
if change.op == Remove {
if !target.flags[change.mode] {
continue
}
delete(target.flags, change.mode)
changes = append(changes, change)
}
}
}
// Who should get these replies?
if len(changes) > 0 {
client.Reply(RplMode(client, target, changes))
}
}
func (msg *ChannelModeCommand) HandleServer(server *Server) {
client := msg.Client()
channel := server.channels.Get(msg.channel)
if channel == nil {
client.ErrNoSuchChannel(msg.channel)
return
}
channel.Mode(client, msg.changes)
}

View File

@ -181,7 +181,8 @@ func (target *Client) RplCreated() {
func (target *Client) RplMyInfo() { func (target *Client) RplMyInfo() {
target.NumericReply(RPL_MYINFO, target.NumericReply(RPL_MYINFO,
"%s %s aiOorsw abeIikmntpqrsl", target.server.name, SEM_VER) "%s %s %s %s",
target.server.name, SEM_VER, SupportedUserModes, SupportedChannelModes)
} }
func (target *Client) RplUModeIs(client *Client) { func (target *Client) RplUModeIs(client *Client) {

View File

@ -94,9 +94,7 @@ func (server *Server) loadChannels() {
log.Fatal("error loading channels: ", err) log.Fatal("error loading channels: ", err)
} }
for rows.Next() { for rows.Next() {
var name Name var name, flags, key, topic string
var flags string
var key, topic Text
var userLimit uint64 var userLimit uint64
var banList, exceptList, inviteList string var banList, exceptList, inviteList string
err = rows.Scan(&name, &flags, &key, &topic, &userLimit, &banList, err = rows.Scan(&name, &flags, &key, &topic, &userLimit, &banList,
@ -106,12 +104,12 @@ func (server *Server) loadChannels() {
continue continue
} }
channel := NewChannel(server, name) channel := NewChannel(server, NewName(name))
for _, flag := range flags { for _, flag := range flags {
channel.flags[ChannelMode(flag)] = true channel.flags[ChannelMode(flag)] = true
} }
channel.key = key channel.key = NewText(key)
channel.topic = topic channel.topic = NewText(topic)
channel.userLimit = userLimit channel.userLimit = userLimit
loadChannelList(channel, banList, BanMask) loadChannelList(channel, banList, BanMask)
loadChannelList(channel, exceptList, ExceptMask) loadChannelList(channel, exceptList, ExceptMask)
@ -339,7 +337,7 @@ func (msg *RFC2812UserCommand) HandleRegServer(server *Server) {
} }
flags := msg.Flags() flags := msg.Flags()
if len(flags) > 0 { if len(flags) > 0 {
for _, mode := range msg.Flags() { for _, mode := range flags {
client.flags[mode] = true client.flags[mode] = true
} }
client.RplUModeIs(client) client.RplUModeIs(client)
@ -491,58 +489,6 @@ func (msg *PrivMsgCommand) HandleServer(server *Server) {
} }
} }
func (m *ModeCommand) HandleServer(s *Server) {
client := m.Client()
target := s.clients.Get(m.nickname)
if target == nil {
client.ErrNoSuchNick(m.nickname)
return
}
if client != target && !client.flags[Operator] {
client.ErrUsersDontMatch()
return
}
changes := make(ModeChanges, 0, len(m.changes))
for _, change := range m.changes {
switch change.mode {
case Invisible, ServerNotice, WallOps:
switch change.op {
case Add:
if target.flags[change.mode] {
continue
}
target.flags[change.mode] = true
changes = append(changes, change)
case Remove:
if !target.flags[change.mode] {
continue
}
delete(target.flags, change.mode)
changes = append(changes, change)
}
case Operator, LocalOperator:
if change.op == Remove {
if !target.flags[change.mode] {
continue
}
delete(target.flags, change.mode)
changes = append(changes, change)
}
}
}
// Who should get these replies?
if len(changes) > 0 {
client.Reply(RplMode(client, target, changes))
}
}
func (client *Client) WhoisChannelsNames() []string { func (client *Client) WhoisChannelsNames() []string {
chstrs := make([]string, len(client.channels)) chstrs := make([]string, len(client.channels))
index := 0 index := 0
@ -579,17 +525,6 @@ func (m *WhoisCommand) HandleServer(server *Server) {
} }
} }
func (msg *ChannelModeCommand) HandleServer(server *Server) {
client := msg.Client()
channel := server.channels.Get(msg.channel)
if channel == nil {
client.ErrNoSuchChannel(msg.channel)
return
}
channel.Mode(client, msg.changes)
}
func whoChannel(client *Client, channel *Channel, friends ClientSet) { func whoChannel(client *Client, channel *Channel, friends ClientSet) {
for member := range channel.members { for member := range channel.members {
if !client.flags[Invisible] || friends[client] { if !client.flags[Invisible] || friends[client] {

View File

@ -9,27 +9,6 @@ import (
// simple types // simple types
// //
// add, remove, list modes
type ModeOp rune
func (op ModeOp) String() string {
return string(op)
}
// user mode flags
type UserMode rune
func (mode UserMode) String() string {
return string(mode)
}
// channel mode flags
type ChannelMode rune
func (mode ChannelMode) String() string {
return string(mode)
}
type ChannelNameMap map[Name]*Channel type ChannelNameMap map[Name]*Channel
func (channels ChannelNameMap) Get(name Name) *Channel { func (channels ChannelNameMap) Get(name Name) *Channel {