3
0
mirror of https://github.com/ergochat/ergo.git synced 2024-12-22 10:42:52 +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:
Jeremy Latt 2014-03-12 17:52:25 -07:00
parent 0126edc7af
commit 2006aff9f7
6 changed files with 85 additions and 96 deletions

View File

@ -6,6 +6,12 @@ import (
"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 {
return NicknameExpr.MatchString(nick)
}
@ -26,9 +32,9 @@ type Client struct {
idleTimer *time.Timer
loginTimer *time.Timer
nick string
phase Phase
quitTimer *time.Timer
realname string
registered bool
server *Server
socket *Socket
username string
@ -45,7 +51,6 @@ func NewClient(server *Server, conn net.Conn) *Client {
commands: make(chan Command),
ctime: now,
flags: make(map[UserMode]bool),
phase: Registration,
server: server,
}
client.socket = NewSocket(conn, client.commands)
@ -118,7 +123,10 @@ func (client *Client) Idle() {
}
func (client *Client) Register() {
client.phase = Normal
if client.registered {
return
}
client.registered = true
client.loginTimer.Stop()
client.Touch()
}

View File

@ -9,6 +9,13 @@ import (
"strings"
)
type Command interface {
Client() *Client
Code() StringCode
SetClient(*Client)
SetCode(StringCode)
}
type checkPasswordCommand interface {
LoadPassword(*Server)
CheckPassword()

View File

@ -3,7 +3,6 @@ package irc
import (
"errors"
"regexp"
"time"
)
var (
@ -21,10 +20,6 @@ const (
CRLF = "\r\n"
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
AWAY StringCode = "AWAY"
CAP StringCode = "CAP"
@ -227,8 +222,3 @@ const (
UserLimit ChannelMode = 'l' // flag arg
Voice ChannelMode = 'v' // arg
)
const (
Registration Phase = iota
Normal Phase = iota
)

View File

@ -6,7 +6,23 @@ import (
"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 {
var header string
if source == nil {
@ -79,15 +95,15 @@ func (target *Client) MultilineReply(names []string, code NumericCode, format st
// 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)
}
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)
}
func RplNick(source Identifier, newNick string) string {
func RplNick(source Identifiable, newNick string) string {
return NewStringReply(source, NICK, newNick)
}
@ -108,11 +124,11 @@ func RplChannelMode(client *Client, channel *Channel,
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)
}
func RplPing(target Identifier) string {
func RplPing(target Identifiable) string {
return NewStringReply(nil, PING, ":%s", target.Nick())
}

View File

@ -16,10 +16,15 @@ import (
"time"
)
var (
SERVER_SIGNALS = []os.Signal{syscall.SIGINT, syscall.SIGHUP,
syscall.SIGTERM, syscall.SIGQUIT}
)
type ServerCommand interface {
Command
HandleServer(*Server)
}
type RegServerCommand interface {
Command
HandleRegServer(*Server)
}
type Server struct {
channels ChannelNameMap
@ -37,6 +42,11 @@ type Server struct {
whoWas *WhoWasList
}
var (
SERVER_SIGNALS = []os.Signal{syscall.SIGINT, syscall.SIGHUP,
syscall.SIGTERM, syscall.SIGQUIT}
)
func NewServer(config *Config) *Server {
server := &Server{
channels: make(ChannelNameMap),
@ -111,34 +121,33 @@ func (server *Server) processCommand(cmd Command) {
client := cmd.Client()
Log.debug.Printf("%s → %s %s", client, server, cmd)
switch client.phase {
case Registration:
if !client.registered {
regCmd, ok := cmd.(RegServerCommand)
if !ok {
client.Quit("unexpected command")
return
}
regCmd.HandleRegServer(server)
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)
return
}
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() {
@ -197,14 +206,17 @@ func (s *Server) listen(addr string) {
//
func (s *Server) tryRegister(c *Client) {
if c.HasNick() && c.HasUsername() && (c.capState != CapNegotiating) {
c.Register()
c.RplWelcome()
c.RplYourHost()
c.RplCreated()
c.RplMyInfo()
s.MOTD(c)
if c.registered || !c.HasNick() || !c.HasUsername() ||
(c.capState == CapNegotiating) {
return
}
c.Register()
c.RplWelcome()
c.RplYourHost()
c.RplCreated()
c.RplMyInfo()
s.MOTD(c)
}
func (server *Server) MOTD(client *Client) {

View File

@ -23,24 +23,6 @@ func (mode UserMode) String() string {
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
type ChannelMode rune
@ -143,33 +125,7 @@ func (channels ChannelSet) First() *Channel {
// interfaces
//
type Identifier interface {
type Identifiable interface {
Id() 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)
}