mirror of
https://github.com/ergochat/ergo.git
synced 2024-12-22 10:42:52 +01:00
move modes code to its own file; fix SQL (un)marshalling
This commit is contained in:
parent
4ed0d78d87
commit
d85e6681d9
@ -444,8 +444,8 @@ func (channel *Channel) Persist() (err error) {
|
||||
(name, flags, key, topic, user_limit, ban_list, except_list,
|
||||
invite_list)
|
||||
VALUES (?, ?, ?, ?, ?, ?, ?, ?)`,
|
||||
channel.name, channel.flags.String(), channel.key, channel.topic,
|
||||
channel.userLimit, channel.lists[BanMask].String(),
|
||||
channel.name.String(), channel.flags.String(), channel.key.String(),
|
||||
channel.topic.String(), channel.userLimit, channel.lists[BanMask].String(),
|
||||
channel.lists[ExceptMask].String(), channel.lists[InviteMask].String())
|
||||
} else {
|
||||
_, err = channel.server.db.Exec(`
|
||||
|
@ -153,7 +153,7 @@ func NewClientDB() *ClientDB {
|
||||
|
||||
func (db *ClientDB) Add(client *Client) {
|
||||
_, err := db.db.Exec(`INSERT INTO client (nickname, userhost) VALUES (?, ?)`,
|
||||
client.Nick(), client.UserHost())
|
||||
client.Nick().String(), client.UserHost().String())
|
||||
if err != nil {
|
||||
Log.error.Println("ClientDB.Add:", err)
|
||||
}
|
||||
@ -161,7 +161,7 @@ func (db *ClientDB) Add(client *Client) {
|
||||
|
||||
func (db *ClientDB) Remove(client *Client) {
|
||||
_, err := db.db.Exec(`DELETE FROM client WHERE nickname = ?`,
|
||||
client.Nick())
|
||||
client.Nick().String())
|
||||
if err != nil {
|
||||
Log.error.Println("ClientDB.Remove:", err)
|
||||
}
|
||||
|
@ -1,14 +1,5 @@
|
||||
package irc
|
||||
|
||||
import (
|
||||
"errors"
|
||||
)
|
||||
|
||||
var (
|
||||
// errors
|
||||
ErrAlreadyDestroyed = errors.New("already destroyed")
|
||||
)
|
||||
|
||||
const (
|
||||
SEM_VER = "ergonomadic-1.3.1"
|
||||
CRLF = "\r\n"
|
||||
@ -184,35 +175,4 @@ const (
|
||||
ERR_NOOPERHOST NumericCode = 491
|
||||
ERR_UMODEUNKNOWNFLAG NumericCode = 501
|
||||
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
162
irc/modes.go
Normal 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)
|
||||
}
|
@ -181,7 +181,8 @@ func (target *Client) RplCreated() {
|
||||
|
||||
func (target *Client) RplMyInfo() {
|
||||
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) {
|
||||
|
@ -94,9 +94,7 @@ func (server *Server) loadChannels() {
|
||||
log.Fatal("error loading channels: ", err)
|
||||
}
|
||||
for rows.Next() {
|
||||
var name Name
|
||||
var flags string
|
||||
var key, topic Text
|
||||
var name, flags, key, topic string
|
||||
var userLimit uint64
|
||||
var banList, exceptList, inviteList string
|
||||
err = rows.Scan(&name, &flags, &key, &topic, &userLimit, &banList,
|
||||
@ -106,12 +104,12 @@ func (server *Server) loadChannels() {
|
||||
continue
|
||||
}
|
||||
|
||||
channel := NewChannel(server, name)
|
||||
channel := NewChannel(server, NewName(name))
|
||||
for _, flag := range flags {
|
||||
channel.flags[ChannelMode(flag)] = true
|
||||
}
|
||||
channel.key = key
|
||||
channel.topic = topic
|
||||
channel.key = NewText(key)
|
||||
channel.topic = NewText(topic)
|
||||
channel.userLimit = userLimit
|
||||
loadChannelList(channel, banList, BanMask)
|
||||
loadChannelList(channel, exceptList, ExceptMask)
|
||||
@ -339,7 +337,7 @@ func (msg *RFC2812UserCommand) HandleRegServer(server *Server) {
|
||||
}
|
||||
flags := msg.Flags()
|
||||
if len(flags) > 0 {
|
||||
for _, mode := range msg.Flags() {
|
||||
for _, mode := range flags {
|
||||
client.flags[mode] = true
|
||||
}
|
||||
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 {
|
||||
chstrs := make([]string, len(client.channels))
|
||||
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) {
|
||||
for member := range channel.members {
|
||||
if !client.flags[Invisible] || friends[client] {
|
||||
|
21
irc/types.go
21
irc/types.go
@ -9,27 +9,6 @@ import (
|
||||
// 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
|
||||
|
||||
func (channels ChannelNameMap) Get(name Name) *Channel {
|
||||
|
Loading…
Reference in New Issue
Block a user