mirror of
https://github.com/ergochat/ergo.git
synced 2024-12-22 18:52:41 +01:00
break up types.go
- remove old interfaces, move to relevant files - remove Phase in favor of a boolean flag
This commit is contained in:
parent
0126edc7af
commit
2006aff9f7
@ -6,6 +6,12 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
LOGIN_TIMEOUT = time.Minute / 2 // how long the client has to login
|
||||||
|
IDLE_TIMEOUT = time.Minute // how long before a client is considered idle
|
||||||
|
QUIT_TIMEOUT = time.Minute // how long after idle before a client is kicked
|
||||||
|
)
|
||||||
|
|
||||||
func IsNickname(nick string) bool {
|
func IsNickname(nick string) bool {
|
||||||
return NicknameExpr.MatchString(nick)
|
return NicknameExpr.MatchString(nick)
|
||||||
}
|
}
|
||||||
@ -26,9 +32,9 @@ type Client struct {
|
|||||||
idleTimer *time.Timer
|
idleTimer *time.Timer
|
||||||
loginTimer *time.Timer
|
loginTimer *time.Timer
|
||||||
nick string
|
nick string
|
||||||
phase Phase
|
|
||||||
quitTimer *time.Timer
|
quitTimer *time.Timer
|
||||||
realname string
|
realname string
|
||||||
|
registered bool
|
||||||
server *Server
|
server *Server
|
||||||
socket *Socket
|
socket *Socket
|
||||||
username string
|
username string
|
||||||
@ -45,7 +51,6 @@ func NewClient(server *Server, conn net.Conn) *Client {
|
|||||||
commands: make(chan Command),
|
commands: make(chan Command),
|
||||||
ctime: now,
|
ctime: now,
|
||||||
flags: make(map[UserMode]bool),
|
flags: make(map[UserMode]bool),
|
||||||
phase: Registration,
|
|
||||||
server: server,
|
server: server,
|
||||||
}
|
}
|
||||||
client.socket = NewSocket(conn, client.commands)
|
client.socket = NewSocket(conn, client.commands)
|
||||||
@ -118,7 +123,10 @@ func (client *Client) Idle() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (client *Client) Register() {
|
func (client *Client) Register() {
|
||||||
client.phase = Normal
|
if client.registered {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
client.registered = true
|
||||||
client.loginTimer.Stop()
|
client.loginTimer.Stop()
|
||||||
client.Touch()
|
client.Touch()
|
||||||
}
|
}
|
||||||
|
@ -9,6 +9,13 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type Command interface {
|
||||||
|
Client() *Client
|
||||||
|
Code() StringCode
|
||||||
|
SetClient(*Client)
|
||||||
|
SetCode(StringCode)
|
||||||
|
}
|
||||||
|
|
||||||
type checkPasswordCommand interface {
|
type checkPasswordCommand interface {
|
||||||
LoadPassword(*Server)
|
LoadPassword(*Server)
|
||||||
CheckPassword()
|
CheckPassword()
|
||||||
|
@ -3,7 +3,6 @@ package irc
|
|||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"regexp"
|
"regexp"
|
||||||
"time"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@ -21,10 +20,6 @@ const (
|
|||||||
CRLF = "\r\n"
|
CRLF = "\r\n"
|
||||||
MAX_REPLY_LEN = 512 - len(CRLF)
|
MAX_REPLY_LEN = 512 - len(CRLF)
|
||||||
|
|
||||||
LOGIN_TIMEOUT = time.Minute / 2 // how long the client has to login
|
|
||||||
IDLE_TIMEOUT = time.Minute // how long before a client is considered idle
|
|
||||||
QUIT_TIMEOUT = time.Minute // how long after idle before a client is kicked
|
|
||||||
|
|
||||||
// string codes
|
// string codes
|
||||||
AWAY StringCode = "AWAY"
|
AWAY StringCode = "AWAY"
|
||||||
CAP StringCode = "CAP"
|
CAP StringCode = "CAP"
|
||||||
@ -227,8 +222,3 @@ const (
|
|||||||
UserLimit ChannelMode = 'l' // flag arg
|
UserLimit ChannelMode = 'l' // flag arg
|
||||||
Voice ChannelMode = 'v' // arg
|
Voice ChannelMode = 'v' // arg
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
|
||||||
Registration Phase = iota
|
|
||||||
Normal Phase = iota
|
|
||||||
)
|
|
||||||
|
28
irc/reply.go
28
irc/reply.go
@ -6,7 +6,23 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
func NewStringReply(source Identifier, code StringCode,
|
type ReplyCode interface {
|
||||||
|
String() string
|
||||||
|
}
|
||||||
|
|
||||||
|
type StringCode string
|
||||||
|
|
||||||
|
func (code StringCode) String() string {
|
||||||
|
return string(code)
|
||||||
|
}
|
||||||
|
|
||||||
|
type NumericCode uint
|
||||||
|
|
||||||
|
func (code NumericCode) String() string {
|
||||||
|
return fmt.Sprintf("%03d", code)
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewStringReply(source Identifiable, code StringCode,
|
||||||
format string, args ...interface{}) string {
|
format string, args ...interface{}) string {
|
||||||
var header string
|
var header string
|
||||||
if source == nil {
|
if source == nil {
|
||||||
@ -79,15 +95,15 @@ func (target *Client) MultilineReply(names []string, code NumericCode, format st
|
|||||||
// messaging replies
|
// messaging replies
|
||||||
//
|
//
|
||||||
|
|
||||||
func RplPrivMsg(source Identifier, target Identifier, message string) string {
|
func RplPrivMsg(source Identifiable, target Identifiable, message string) string {
|
||||||
return NewStringReply(source, PRIVMSG, "%s :%s", target.Nick(), message)
|
return NewStringReply(source, PRIVMSG, "%s :%s", target.Nick(), message)
|
||||||
}
|
}
|
||||||
|
|
||||||
func RplNotice(source Identifier, target Identifier, message string) string {
|
func RplNotice(source Identifiable, target Identifiable, message string) string {
|
||||||
return NewStringReply(source, NOTICE, "%s :%s", target.Nick(), message)
|
return NewStringReply(source, NOTICE, "%s :%s", target.Nick(), message)
|
||||||
}
|
}
|
||||||
|
|
||||||
func RplNick(source Identifier, newNick string) string {
|
func RplNick(source Identifiable, newNick string) string {
|
||||||
return NewStringReply(source, NICK, newNick)
|
return NewStringReply(source, NICK, newNick)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -108,11 +124,11 @@ func RplChannelMode(client *Client, channel *Channel,
|
|||||||
return NewStringReply(client, MODE, "%s %s", channel, changes)
|
return NewStringReply(client, MODE, "%s %s", channel, changes)
|
||||||
}
|
}
|
||||||
|
|
||||||
func RplTopicMsg(source Identifier, channel *Channel) string {
|
func RplTopicMsg(source Identifiable, channel *Channel) string {
|
||||||
return NewStringReply(source, TOPIC, "%s :%s", channel, channel.topic)
|
return NewStringReply(source, TOPIC, "%s :%s", channel, channel.topic)
|
||||||
}
|
}
|
||||||
|
|
||||||
func RplPing(target Identifier) string {
|
func RplPing(target Identifiable) string {
|
||||||
return NewStringReply(nil, PING, ":%s", target.Nick())
|
return NewStringReply(nil, PING, ":%s", target.Nick())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -16,10 +16,15 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
type ServerCommand interface {
|
||||||
SERVER_SIGNALS = []os.Signal{syscall.SIGINT, syscall.SIGHUP,
|
Command
|
||||||
syscall.SIGTERM, syscall.SIGQUIT}
|
HandleServer(*Server)
|
||||||
)
|
}
|
||||||
|
|
||||||
|
type RegServerCommand interface {
|
||||||
|
Command
|
||||||
|
HandleRegServer(*Server)
|
||||||
|
}
|
||||||
|
|
||||||
type Server struct {
|
type Server struct {
|
||||||
channels ChannelNameMap
|
channels ChannelNameMap
|
||||||
@ -37,6 +42,11 @@ type Server struct {
|
|||||||
whoWas *WhoWasList
|
whoWas *WhoWasList
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
SERVER_SIGNALS = []os.Signal{syscall.SIGINT, syscall.SIGHUP,
|
||||||
|
syscall.SIGTERM, syscall.SIGQUIT}
|
||||||
|
)
|
||||||
|
|
||||||
func NewServer(config *Config) *Server {
|
func NewServer(config *Config) *Server {
|
||||||
server := &Server{
|
server := &Server{
|
||||||
channels: make(ChannelNameMap),
|
channels: make(ChannelNameMap),
|
||||||
@ -111,34 +121,33 @@ func (server *Server) processCommand(cmd Command) {
|
|||||||
client := cmd.Client()
|
client := cmd.Client()
|
||||||
Log.debug.Printf("%s → %s %s", client, server, cmd)
|
Log.debug.Printf("%s → %s %s", client, server, cmd)
|
||||||
|
|
||||||
switch client.phase {
|
if !client.registered {
|
||||||
case Registration:
|
|
||||||
regCmd, ok := cmd.(RegServerCommand)
|
regCmd, ok := cmd.(RegServerCommand)
|
||||||
if !ok {
|
if !ok {
|
||||||
client.Quit("unexpected command")
|
client.Quit("unexpected command")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
regCmd.HandleRegServer(server)
|
regCmd.HandleRegServer(server)
|
||||||
|
return
|
||||||
case Normal:
|
|
||||||
srvCmd, ok := cmd.(ServerCommand)
|
|
||||||
if !ok {
|
|
||||||
client.ErrUnknownCommand(cmd.Code())
|
|
||||||
return
|
|
||||||
}
|
|
||||||
switch srvCmd.(type) {
|
|
||||||
case *PingCommand, *PongCommand:
|
|
||||||
client.Touch()
|
|
||||||
|
|
||||||
case *QuitCommand:
|
|
||||||
// no-op
|
|
||||||
|
|
||||||
default:
|
|
||||||
client.Active()
|
|
||||||
client.Touch()
|
|
||||||
}
|
|
||||||
srvCmd.HandleServer(server)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
srvCmd, ok := cmd.(ServerCommand)
|
||||||
|
if !ok {
|
||||||
|
client.ErrUnknownCommand(cmd.Code())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
switch srvCmd.(type) {
|
||||||
|
case *PingCommand, *PongCommand:
|
||||||
|
client.Touch()
|
||||||
|
|
||||||
|
case *QuitCommand:
|
||||||
|
// no-op
|
||||||
|
|
||||||
|
default:
|
||||||
|
client.Active()
|
||||||
|
client.Touch()
|
||||||
|
}
|
||||||
|
srvCmd.HandleServer(server)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (server *Server) Shutdown() {
|
func (server *Server) Shutdown() {
|
||||||
@ -197,14 +206,17 @@ func (s *Server) listen(addr string) {
|
|||||||
//
|
//
|
||||||
|
|
||||||
func (s *Server) tryRegister(c *Client) {
|
func (s *Server) tryRegister(c *Client) {
|
||||||
if c.HasNick() && c.HasUsername() && (c.capState != CapNegotiating) {
|
if c.registered || !c.HasNick() || !c.HasUsername() ||
|
||||||
c.Register()
|
(c.capState == CapNegotiating) {
|
||||||
c.RplWelcome()
|
return
|
||||||
c.RplYourHost()
|
|
||||||
c.RplCreated()
|
|
||||||
c.RplMyInfo()
|
|
||||||
s.MOTD(c)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
c.Register()
|
||||||
|
c.RplWelcome()
|
||||||
|
c.RplYourHost()
|
||||||
|
c.RplCreated()
|
||||||
|
c.RplMyInfo()
|
||||||
|
s.MOTD(c)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (server *Server) MOTD(client *Client) {
|
func (server *Server) MOTD(client *Client) {
|
||||||
|
46
irc/types.go
46
irc/types.go
@ -23,24 +23,6 @@ func (mode UserMode) String() string {
|
|||||||
return string(mode)
|
return string(mode)
|
||||||
}
|
}
|
||||||
|
|
||||||
type Phase uint
|
|
||||||
|
|
||||||
type ReplyCode interface {
|
|
||||||
String() string
|
|
||||||
}
|
|
||||||
|
|
||||||
type StringCode string
|
|
||||||
|
|
||||||
func (code StringCode) String() string {
|
|
||||||
return string(code)
|
|
||||||
}
|
|
||||||
|
|
||||||
type NumericCode uint
|
|
||||||
|
|
||||||
func (code NumericCode) String() string {
|
|
||||||
return fmt.Sprintf("%03d", code)
|
|
||||||
}
|
|
||||||
|
|
||||||
// channel mode flags
|
// channel mode flags
|
||||||
type ChannelMode rune
|
type ChannelMode rune
|
||||||
|
|
||||||
@ -143,33 +125,7 @@ func (channels ChannelSet) First() *Channel {
|
|||||||
// interfaces
|
// interfaces
|
||||||
//
|
//
|
||||||
|
|
||||||
type Identifier interface {
|
type Identifiable interface {
|
||||||
Id() string
|
Id() string
|
||||||
Nick() string
|
Nick() string
|
||||||
}
|
}
|
||||||
|
|
||||||
type Replier interface {
|
|
||||||
Reply(...string)
|
|
||||||
}
|
|
||||||
|
|
||||||
type Command interface {
|
|
||||||
Code() StringCode
|
|
||||||
Client() *Client
|
|
||||||
SetCode(StringCode)
|
|
||||||
SetClient(*Client)
|
|
||||||
}
|
|
||||||
|
|
||||||
type ServerCommand interface {
|
|
||||||
Command
|
|
||||||
HandleServer(*Server)
|
|
||||||
}
|
|
||||||
|
|
||||||
type AuthServerCommand interface {
|
|
||||||
Command
|
|
||||||
HandleAuthServer(*Server)
|
|
||||||
}
|
|
||||||
|
|
||||||
type RegServerCommand interface {
|
|
||||||
Command
|
|
||||||
HandleRegServer(*Server)
|
|
||||||
}
|
|
||||||
|
Loading…
Reference in New Issue
Block a user