mirror of
https://github.com/ergochat/ergo.git
synced 2024-11-10 22:19:31 +01:00
OPER command
This commit is contained in:
parent
85e2f65b1b
commit
41e79e3b09
@ -6,17 +6,27 @@ import (
|
||||
)
|
||||
|
||||
type Client struct {
|
||||
// communication
|
||||
conn net.Conn
|
||||
hostname string
|
||||
send chan<- Reply
|
||||
recv <-chan string
|
||||
// basic info
|
||||
username string
|
||||
realname string
|
||||
hostname string
|
||||
nick string
|
||||
serverPass bool
|
||||
// modes
|
||||
away bool
|
||||
registered bool
|
||||
invisible bool
|
||||
channels ChannelSet
|
||||
wallOps bool
|
||||
restricted bool
|
||||
operator bool
|
||||
localOperator bool
|
||||
// relations
|
||||
server *Server
|
||||
channels ChannelSet
|
||||
}
|
||||
|
||||
type ClientSet map[*Client]bool
|
||||
|
@ -13,8 +13,8 @@ type Message interface {
|
||||
}
|
||||
|
||||
var (
|
||||
ErrNotEnoughArgs = errors.New("not enough arguments")
|
||||
ErrUModeUnknownFlag = errors.New("unknown umode flag")
|
||||
NotEnoughArgsError = errors.New("not enough arguments")
|
||||
UModeUnknownFlagError = errors.New("unknown umode flag")
|
||||
)
|
||||
|
||||
// unknown
|
||||
@ -38,7 +38,7 @@ type PingMessage struct {
|
||||
|
||||
func NewPingMessage(args []string) (Message, error) {
|
||||
if len(args) < 1 {
|
||||
return nil, ErrNotEnoughArgs
|
||||
return nil, NotEnoughArgsError
|
||||
}
|
||||
msg := &PingMessage{server: args[0]}
|
||||
if len(args) > 1 {
|
||||
@ -60,7 +60,7 @@ type PongMessage struct {
|
||||
|
||||
func NewPongMessage(args []string) (Message, error) {
|
||||
if len(args) < 1 {
|
||||
return nil, ErrNotEnoughArgs
|
||||
return nil, NotEnoughArgsError
|
||||
}
|
||||
message := &PongMessage{server1: args[0]}
|
||||
if len(args) > 1 {
|
||||
@ -73,6 +73,27 @@ func (m *PongMessage) Handle(s *Server, c *Client) {
|
||||
// no-op
|
||||
}
|
||||
|
||||
// PASS <password>
|
||||
|
||||
type PassMessage struct {
|
||||
password string
|
||||
}
|
||||
|
||||
func NewPassMessage(args []string) (Message, error) {
|
||||
if len(args) < 1 {
|
||||
return nil, NotEnoughArgsError
|
||||
}
|
||||
return &PassMessage{password: args[0]}
|
||||
}
|
||||
|
||||
func (m *PassMessage) Handle(s *Server, c *Client) {
|
||||
if m.password == server.password {
|
||||
c.serverPass = true
|
||||
} else {
|
||||
c.send <- ErrPass
|
||||
}
|
||||
}
|
||||
|
||||
// NICK
|
||||
|
||||
type NickMessage struct {
|
||||
@ -81,7 +102,7 @@ type NickMessage struct {
|
||||
|
||||
func NewNickMessage(args []string) (Message, error) {
|
||||
if len(args) != 1 {
|
||||
return nil, ErrNotEnoughArgs
|
||||
return nil, NotEnoughArgsError
|
||||
}
|
||||
return &NickMessage{args[0]}, nil
|
||||
}
|
||||
@ -101,7 +122,7 @@ type UserMessage struct {
|
||||
|
||||
func NewUserMessage(args []string) (Message, error) {
|
||||
if len(args) != 4 {
|
||||
return nil, ErrNotEnoughArgs
|
||||
return nil, NotEnoughArgsError
|
||||
}
|
||||
msg := &UserMessage{
|
||||
user: args[0],
|
||||
@ -119,7 +140,7 @@ func (m *UserMessage) Handle(s *Server, c *Client) {
|
||||
s.UserLogin(c, m.user, m.realname)
|
||||
}
|
||||
|
||||
// QUIT
|
||||
// QUIT [ <Quit Message> ]
|
||||
|
||||
type QuitMessage struct {
|
||||
message string
|
||||
@ -137,18 +158,19 @@ func (m *QuitMessage) Handle(s *Server, c *Client) {
|
||||
s.Quit(c, m.message)
|
||||
}
|
||||
|
||||
// MODE
|
||||
// MODE <nickname> *( ( "+" / "-" ) *( "i" / "w" / "o" / "O" / "r" ) )
|
||||
|
||||
type ModeMessage struct {
|
||||
nickname string
|
||||
modes []string
|
||||
}
|
||||
|
||||
var MODE_RE = regexp.MustCompile("^[-+][a-zA-Z]+$")
|
||||
// mode s is accepted but ignored, like some other modes
|
||||
var MODE_RE = regexp.MustCompile("^[-+][iwroOs]+$")
|
||||
|
||||
func NewModeMessage(args []string) (Message, error) {
|
||||
if len(args) < 1 {
|
||||
return nil, ErrNotEnoughArgs
|
||||
return nil, NotEnoughArgsError
|
||||
}
|
||||
msg := &ModeMessage{
|
||||
nickname: args[0],
|
||||
@ -174,7 +196,7 @@ func (m *ModeMessage) Handle(s *Server, c *Client) {
|
||||
s.ChangeUserMode(c, m.modes)
|
||||
}
|
||||
|
||||
// JOIN
|
||||
// JOIN ( <channel> *( "," <channel> ) [ <key> *( "," <key> ) ] ) / "0"
|
||||
|
||||
type JoinMessage struct {
|
||||
channels []string
|
||||
@ -224,7 +246,7 @@ type PartMessage struct {
|
||||
|
||||
func NewPartMessage(args []string) (Message, error) {
|
||||
if len(args) < 1 {
|
||||
return nil, ErrNotEnoughArgs
|
||||
return nil, NotEnoughArgsError
|
||||
}
|
||||
msg := &PartMessage{channels: strings.Split(args[0], ",")}
|
||||
if len(args) > 1 {
|
||||
@ -255,7 +277,7 @@ type PrivMsgMessage struct {
|
||||
|
||||
func NewPrivMsgMessage(args []string) (Message, error) {
|
||||
if len(args) < 2 {
|
||||
return nil, ErrNotEnoughArgs
|
||||
return nil, NotEnoughArgsError
|
||||
}
|
||||
return &PrivMsgMessage{
|
||||
target: args[0],
|
||||
@ -298,7 +320,7 @@ type TopicMessage struct {
|
||||
|
||||
func NewTopicMessage(args []string) (Message, error) {
|
||||
if len(args) < 1 {
|
||||
return nil, ErrNotEnoughArgs
|
||||
return nil, NotEnoughArgsError
|
||||
}
|
||||
msg := &TopicMessage{channel: args[0]}
|
||||
if len(args) > 1 {
|
||||
@ -329,7 +351,7 @@ type InviteMessage struct {
|
||||
|
||||
func NewInviteMessage(args []string) (Message, error) {
|
||||
if len(args) < 2 {
|
||||
return nil, ErrNotEnoughArgs
|
||||
return nil, NotEnoughArgsError
|
||||
}
|
||||
return &InviteMessage{
|
||||
nickname: args[0],
|
||||
@ -352,3 +374,28 @@ func (m *InviteMessage) Handle(s *Server, c *Client) {
|
||||
|
||||
channel.Invite(c, invitee)
|
||||
}
|
||||
|
||||
// OPER <name> <password>
|
||||
|
||||
type OperMessage struct {
|
||||
name string
|
||||
password string
|
||||
}
|
||||
|
||||
func NewOperMessage(args []string) Message {
|
||||
if len(args) < 2 {
|
||||
return nil, NotEnoughArgsError
|
||||
}
|
||||
return &OperMessage{
|
||||
name: args[0],
|
||||
password: args[1],
|
||||
}
|
||||
}
|
||||
|
||||
func (m *OperMessage) Handle(s *Server, c *Client) {
|
||||
if s.operators[m.name] == m.password {
|
||||
c.send <- RplYoureOper(s)
|
||||
} else {
|
||||
c.send <- ErrPasswdMismatch(s)
|
||||
}
|
||||
}
|
||||
|
@ -15,12 +15,14 @@ var (
|
||||
"MODE": NewModeMessage,
|
||||
"NICK": NewNickMessage,
|
||||
"PART": NewPartMessage,
|
||||
"PASS": NewPassMessage,
|
||||
"PING": NewPingMessage,
|
||||
"PONG": NewPongMessage,
|
||||
"PRIVMSG": NewPrivMsgMessage,
|
||||
"QUIT": NewQuitMessage,
|
||||
"TOPIC": NewTopicMessage,
|
||||
"USER": NewUserMessage,
|
||||
"OPER": NewOperMessage,
|
||||
}
|
||||
)
|
||||
|
||||
|
@ -77,7 +77,7 @@ func RplCreated(server *Server) Reply {
|
||||
|
||||
func RplMyInfo(server *Server) Reply {
|
||||
return NewReply(server, RPL_MYINFO,
|
||||
fmt.Sprintf("%s %s i ik", server.name, VERSION))
|
||||
fmt.Sprintf("%s %s iwroO ik", server.name, VERSION))
|
||||
}
|
||||
|
||||
func RplUModeIs(server *Server, client *Client) Reply {
|
||||
@ -122,6 +122,12 @@ func RplPong(server *Server) Reply {
|
||||
return NewReply(server, RPL_PONG, "")
|
||||
}
|
||||
|
||||
// server functions
|
||||
|
||||
func RplYoureOper(server *Server) Reply {
|
||||
return NewReply(server, RPL_YOUREOPER, ":You are now an IRC operator")
|
||||
}
|
||||
|
||||
// errors
|
||||
|
||||
func ErrAlreadyRegistered(source Identifier) Reply {
|
||||
@ -177,3 +183,7 @@ func ErrNoSuchNick(source Identifier, nick string) Reply {
|
||||
return NewReply(source, ERR_NOSUCHNICK,
|
||||
nick+" :No such nick/channel")
|
||||
}
|
||||
|
||||
func ErrPasswdMismatch(server *Server) Reply {
|
||||
return NewReply(server, ERR_PASSWDMISMATCH, ":Password incorrect")
|
||||
}
|
||||
|
@ -13,6 +13,8 @@ type Server struct {
|
||||
recv chan<- *ClientMessage
|
||||
nicks map[string]*Client
|
||||
channels map[string]*Channel
|
||||
password string
|
||||
operators map[string]string
|
||||
}
|
||||
|
||||
type ClientMessage struct {
|
||||
@ -68,6 +70,10 @@ func (s *Server) GetOrMakeChannel(name string) *Channel {
|
||||
return channel
|
||||
}
|
||||
|
||||
func (s *Server) AddOperator(name string, password string) {
|
||||
s.operators[name] = password
|
||||
}
|
||||
|
||||
// Send a message to clients of channels fromClient is a member.
|
||||
func (s *Server) SendToInterestedClients(fromClient *Client, reply Reply) {
|
||||
clients := make(map[*Client]bool)
|
||||
@ -114,7 +120,7 @@ func (s *Server) UserLogin(c *Client, user string, realName string) {
|
||||
}
|
||||
|
||||
func (s *Server) tryRegister(c *Client) {
|
||||
if !c.registered && c.HasNick() && c.HasUser() {
|
||||
if !c.registered && c.HasNick() && c.HasUser() && (s.password == "" || c.serverAuth) {
|
||||
c.registered = true
|
||||
c.send <- RplWelcome(s, c)
|
||||
c.send <- RplYourHost(s, c)
|
||||
@ -134,10 +140,21 @@ func (s *Server) Quit(c *Client, message string) {
|
||||
|
||||
func (s *Server) ChangeUserMode(c *Client, modes []string) {
|
||||
for _, mode := range modes {
|
||||
if mode == "+i" {
|
||||
switch mode {
|
||||
case "+i":
|
||||
c.invisible = true
|
||||
} else if mode == "-i" {
|
||||
case "-i":
|
||||
c.invisible = false
|
||||
case "-o":
|
||||
c.operator = false
|
||||
case "-O":
|
||||
c.localOperator = false
|
||||
case "+r":
|
||||
c.restricted = true
|
||||
case "+w":
|
||||
c.wallOps = true
|
||||
case "-w":
|
||||
c.wallOps = false
|
||||
}
|
||||
}
|
||||
c.send <- RplUModeIs(s, c)
|
||||
|
Loading…
Reference in New Issue
Block a user