3
0
mirror of https://github.com/ergochat/ergo.git synced 2024-11-28 23:19:30 +01:00

Update a bunch of messages and fix reply struct embedding.

This commit is contained in:
Jeremy Latt 2013-05-11 18:28:18 -07:00
parent 8e5ff51257
commit c42cd92f91
9 changed files with 292 additions and 218 deletions

View File

@ -4,6 +4,10 @@ import (
"log"
)
const (
DEBUG_CHANNEL = true
)
type Channel struct {
server *Server
commands chan<- ChannelCommand
@ -51,6 +55,9 @@ func NewChannel(s *Server, name string) *Channel {
// Forward `Reply`s to all `User`s of the `Channel`.
func (ch *Channel) receiveReplies(replies <-chan Reply) {
for reply := range replies {
if DEBUG_CHANNEL {
log.Printf("%s → %s", ch, reply)
}
for user := range ch.members {
if user != reply.Source() {
user.replies <- reply
@ -61,7 +68,9 @@ func (ch *Channel) receiveReplies(replies <-chan Reply) {
func (ch *Channel) receiveCommands(commands <-chan ChannelCommand) {
for command := range commands {
log.Printf("%s %T %+v", ch.Id(), command, command)
if DEBUG_CHANNEL {
log.Printf("%s ← %s %s", ch, command.Source(), command)
}
command.HandleChannel(ch)
}
}
@ -89,18 +98,26 @@ func (channel *Channel) GetTopic(replier Replier) {
replier.Replies() <- RplTopic(channel)
}
func (channel Channel) Id() string {
func (channel *Channel) Id() string {
return channel.name
}
func (channel Channel) PublicId() string {
func (channel *Channel) PublicId() string {
return channel.name
}
func (channel Channel) Commands() chan<- ChannelCommand {
func (channel *Channel) Commands() chan<- ChannelCommand {
return channel.commands
}
func (channel *Channel) Replies() chan<- Reply {
return channel.replies
}
func (channel *Channel) String() string {
return channel.Id()
}
//
// commands
//
@ -170,5 +187,5 @@ func (m *TopicCommand) HandleChannel(channel *Channel) {
}
func (m *PrivMsgCommand) HandleChannel(channel *Channel) {
channel.replies <- RplPrivMsgChannel(channel, m.Client().user, m.message)
channel.Replies() <- RplPrivMsgChannel(channel, m.Client().user, m.message)
}

View File

@ -35,7 +35,7 @@ func NewClient(server *Server, conn net.Conn) *Client {
client := &Client{
conn: conn,
hostname: LookupHostname(conn.RemoteAddr()),
hostname: conn.RemoteAddr().String(),
server: server,
replies: replies,
}
@ -73,57 +73,57 @@ func (c *Client) writeConn(write chan<- string, replies <-chan Reply) {
}
}
func (c Client) Replies() chan<- Reply {
func (c *Client) Replies() chan<- Reply {
return c.replies
}
func (c Client) Server() *Server {
func (c *Client) Server() *Server {
return c.server
}
func (c Client) Nick() string {
func (c *Client) Nick() string {
if c.user != nil {
return c.user.nick
return c.user.Nick()
}
if c.nick != "" {
return c.nick
}
return "*"
return "guest"
}
func (c Client) UModeString() string {
func (c *Client) UModeString() string {
return ""
}
func (c Client) HasNick() bool {
return c.nick != ""
func (c *Client) HasNick() bool {
return c.Nick() != ""
}
func (c Client) HasUser() bool {
func (c *Client) HasUsername() bool {
return c.username != ""
}
func (c Client) Username() string {
if c.HasUser() {
func (c *Client) Username() string {
if c.HasUsername() {
return c.username
}
return "*"
return "guest"
}
func (c Client) UserHost() string {
func (c *Client) UserHost() string {
return fmt.Sprintf("%s!%s@%s", c.Nick(), c.Username(), c.hostname)
}
func (c Client) Id() string {
func (c *Client) Id() string {
return c.UserHost()
}
func (c Client) String() string {
return c.Id()
func (c *Client) String() string {
return c.hostname
}
func (c Client) PublicId() string {
func (c *Client) PublicId() string {
return fmt.Sprintf("%s!%s@%s", c.Nick(), c.Nick(), c.server.Id())
}

View File

@ -9,6 +9,7 @@ import (
type Command interface {
Client() *Client
Source() Identifier
HandleServer(*Server)
}
@ -39,7 +40,7 @@ type BaseCommand struct {
client *Client
}
func (command BaseCommand) Client() *Client {
func (command *BaseCommand) Client() *Client {
return command.client
}
@ -50,6 +51,17 @@ func (command *BaseCommand) SetClient(c *Client) {
command.client = c
}
func (command *BaseCommand) Source() Identifier {
client := command.Client()
if client == nil {
return nil
}
if client.user != nil {
return client.user
}
return client
}
func ParseCommand(line string) (EditableCommand, error) {
command, args := parseLine(line)
constructor := parseCommandFuncs[command]
@ -93,6 +105,10 @@ type UnknownCommand struct {
args []string
}
func (cmd *UnknownCommand) String() string {
return fmt.Sprintf("UNKNOWN(command=%s, args=%s)", cmd.command, cmd.args)
}
func NewUnknownCommand(command string, args []string) *UnknownCommand {
return &UnknownCommand{
BaseCommand: BaseCommand{},
@ -109,7 +125,7 @@ type PingCommand struct {
server2 string
}
func (cmd PingCommand) String() string {
func (cmd *PingCommand) String() string {
return fmt.Sprintf("PING(server=%s, server2=%s)", cmd.server, cmd.server2)
}
@ -135,7 +151,7 @@ type PongCommand struct {
server2 string
}
func (cmd PongCommand) String() string {
func (cmd *PongCommand) String() string {
return fmt.Sprintf("PONG(server1=%s, server2=%s)", cmd.server1, cmd.server2)
}
@ -160,6 +176,10 @@ type PassCommand struct {
password string
}
func (cmd *PassCommand) String() string {
return fmt.Sprintf("PASS(password=%s)", cmd.password)
}
func NewPassCommand(args []string) (EditableCommand, error) {
if len(args) < 1 {
return nil, NotEnoughArgsError
@ -177,7 +197,7 @@ type NickCommand struct {
nickname string
}
func (m NickCommand) String() string {
func (m *NickCommand) String() string {
return fmt.Sprintf("NICK(nickname=%s)", m.nickname)
}
@ -201,7 +221,7 @@ type UserMsgCommand struct {
realname string
}
func (cmd UserMsgCommand) String() string {
func (cmd *UserMsgCommand) String() string {
return fmt.Sprintf("USER(user=%s, mode=%o, unused=%s, realname=%s)",
cmd.user, cmd.mode, cmd.unused, cmd.realname)
}
@ -230,7 +250,7 @@ type QuitCommand struct {
message string
}
func (cmd QuitCommand) String() string {
func (cmd *QuitCommand) String() string {
return fmt.Sprintf("QUIT(message=%s)", cmd.message)
}
@ -252,6 +272,10 @@ type JoinCommand struct {
zero bool
}
func (cmd *JoinCommand) String() string {
return fmt.Sprintf("JOIN(channels=%s, zero=%t)", cmd.channels, cmd.zero)
}
func NewJoinCommand(args []string) (EditableCommand, error) {
msg := &JoinCommand{
BaseCommand: BaseCommand{},
@ -289,6 +313,10 @@ type PartCommand struct {
message string
}
func (cmd *PartCommand) String() string {
return fmt.Sprintf("PART(channels=%s, message=%s)", cmd.channels, cmd.message)
}
func NewPartCommand(args []string) (EditableCommand, error) {
if len(args) < 1 {
return nil, NotEnoughArgsError
@ -311,7 +339,7 @@ type PrivMsgCommand struct {
message string
}
func (cmd PrivMsgCommand) String() string {
func (cmd *PrivMsgCommand) String() string {
return fmt.Sprintf("PRIVMSG(target=%s, message=%s)", cmd.target, cmd.message)
}
@ -342,6 +370,10 @@ type TopicCommand struct {
topic string
}
func (cmd *TopicCommand) String() string {
return fmt.Sprintf("TOPIC(channel=%s, topic=%s)", cmd.channel, cmd.topic)
}
func NewTopicCommand(args []string) (EditableCommand, error) {
if len(args) < 1 {
return nil, NotEnoughArgsError
@ -362,7 +394,7 @@ type ModeCommand struct {
modes string
}
func (cmd ModeCommand) String() string {
func (cmd *ModeCommand) String() string {
return fmt.Sprintf("MODE(nickname=%s, modes=%s)", cmd.nickname, cmd.modes)
}

View File

@ -6,142 +6,142 @@ const (
const (
// numeric codes
RPL_WELCOME = "001"
RPL_YOURHOST = "002"
RPL_CREATED = "003"
RPL_MYINFO = "004"
RPL_BOUNCE = "005"
RPL_TRACELINK = "200"
RPL_TRACECONNECTING = "201"
RPL_TRACEHANDSHAKE = "202"
RPL_TRACEUNKNOWN = "203"
RPL_TRACEOPERATOR = "204"
RPL_TRACEUSER = "205"
RPL_TRACESERVER = "206"
RPL_TRACESERVICE = "207"
RPL_TRACENEWTYPE = "208"
RPL_TRACECLASS = "209"
RPL_TRACERECONNECT = "210"
RPL_STATSLINKINFO = "211"
RPL_STATSCOMMANDS = "212"
RPL_ENDOFSTATS = "219"
RPL_UMODEIS = "221"
RPL_SERVLIST = "234"
RPL_SERVLISTEND = "235"
RPL_STATSUPTIME = "242"
RPL_STATSOLINE = "243"
RPL_LUSERCLIENT = "251"
RPL_LUSEROP = "252"
RPL_LUSERUNKNOWN = "253"
RPL_LUSERCHANNELS = "254"
RPL_LUSERME = "255"
RPL_ADMINME = "256"
RPL_ADMINLOC1 = "257"
RPL_ADMINLOC2 = "258"
RPL_ADMINEMAIL = "259"
RPL_TRACELOG = "261"
RPL_TRACEEND = "262"
RPL_TRYAGAIN = "263"
RPL_AWAY = "301"
RPL_USERHOST = "302"
RPL_ISON = "303"
RPL_UNAWAY = "305"
RPL_NOWAWAY = "306"
RPL_WHOISUSER = "311"
RPL_WHOISSERVER = "312"
RPL_WHOISOPERATOR = "313"
RPL_WHOWASUSER = "314"
RPL_ENDOFWHO = "315"
RPL_WHOISIDLE = "317"
RPL_ENDOFWHOIS = "318"
RPL_WHOISCHANNELS = "319"
RPL_LIST = "322"
RPL_LISTEND = "323"
RPL_CHANNELMODEIS = "324"
RPL_UNIQOPIS = "325"
RPL_NOTOPIC = "331"
RPL_TOPIC = "332"
RPL_INVITING = "341"
RPL_SUMMONING = "342"
RPL_INVITELIST = "346"
RPL_ENDOFINVITELIST = "347"
RPL_EXCEPTLIST = "348"
RPL_ENDOFEXCEPTLIST = "349"
RPL_VERSION = "351"
RPL_WHOREPLY = "352"
RPL_NAMREPLY = "353"
RPL_LINKS = "364"
RPL_ENDOFLINKS = "365"
RPL_ENDOFNAMES = "366"
RPL_BANLIST = "367"
RPL_ENDOFBANLIST = "368"
RPL_ENDOFWHOWAS = "369"
RPL_INFO = "371"
RPL_MOTD = "372"
RPL_ENDOFINFO = "374"
RPL_MOTDSTART = "375"
RPL_ENDOFMOTD = "376"
RPL_YOUREOPER = "381"
RPL_REHASHING = "382"
RPL_YOURESERVICE = "383"
RPL_TIME = "391"
RPL_USERSSTART = "392"
RPL_USERS = "393"
RPL_ENDOFUSERS = "394"
RPL_NOUSERS = "395"
ERR_NOSUCHNICK = "401"
ERR_NOSUCHSERVER = "402"
ERR_NOSUCHCHANNEL = "403"
ERR_CANNOTSENDTOCHAN = "404"
ERR_TOOMANYCHANNELS = "405"
ERR_WASNOSUCHNICK = "406"
ERR_TOOMANYTARGETS = "407"
ERR_NOSUCHSERVICE = "408"
ERR_NOORIGIN = "409"
ERR_NORECIPIENT = "411"
ERR_NOTEXTTOSEND = "412"
ERR_NOTOPLEVEL = "413"
ERR_WILDTOPLEVEL = "414"
ERR_BADMASK = "415"
ERR_UNKNOWNCOMMAND = "421"
ERR_NOMOTD = "422"
ERR_NOADMININFO = "423"
ERR_FILEERROR = "424"
ERR_NONICKNAMEGIVEN = "431"
ERR_ERRONEUSNICKNAME = "432"
ERR_NICKNAMEINUSE = "433"
ERR_NICKCOLLISION = "436"
ERR_UNAVAILRESOURCE = "437"
ERR_USERNOTINCHANNEL = "441"
ERR_NOTONCHANNEL = "442"
ERR_USERONCHANNEL = "443"
ERR_NOLOGIN = "444"
ERR_SUMMONDISABLED = "445"
ERR_USERSDISABLED = "446"
ERR_NOTREGISTERED = "451"
ERR_NEEDMOREPARAMS = "461"
ERR_ALREADYREGISTRED = "462"
ERR_NOPERMFORHOST = "463"
ERR_PASSWDMISMATCH = "464"
ERR_YOUREBANNEDCREEP = "465"
ERR_YOUWILLBEBANNED = "466"
ERR_KEYSET = "467"
ERR_CHANNELISFULL = "471"
ERR_UNKNOWNMODE = "472"
ERR_INVITEONLYCHAN = "473"
ERR_BANNEDFROMCHAN = "474"
ERR_BADCHANNELKEY = "475"
ERR_BADCHANMASK = "476"
ERR_NOCHANMODES = "477"
ERR_BANLISTFULL = "478"
ERR_NOPRIVILEGES = "481"
ERR_CHANOPRIVSNEEDED = "482"
ERR_CANTKILLSERVER = "483"
ERR_RESTRICTED = "484"
ERR_UNIQOPPRIVSNEEDED = "485"
ERR_NOOPERHOST = "491"
ERR_UMODEUNKNOWNFLAG = "501"
ERR_USERSDONTMATCH = "502"
RPL_WELCOME = 1
RPL_YOURHOST = 2
RPL_CREATED = 3
RPL_MYINFO = 4
RPL_BOUNCE = 5
RPL_TRACELINK = 200
RPL_TRACECONNECTING = 201
RPL_TRACEHANDSHAKE = 202
RPL_TRACEUNKNOWN = 203
RPL_TRACEOPERATOR = 204
RPL_TRACEUSER = 205
RPL_TRACESERVER = 206
RPL_TRACESERVICE = 207
RPL_TRACENEWTYPE = 208
RPL_TRACECLASS = 209
RPL_TRACERECONNECT = 210
RPL_STATSLINKINFO = 211
RPL_STATSCOMMANDS = 212
RPL_ENDOFSTATS = 219
RPL_UMODEIS = 221
RPL_SERVLIST = 234
RPL_SERVLISTEND = 235
RPL_STATSUPTIME = 242
RPL_STATSOLINE = 243
RPL_LUSERCLIENT = 251
RPL_LUSEROP = 252
RPL_LUSERUNKNOWN = 253
RPL_LUSERCHANNELS = 254
RPL_LUSERME = 255
RPL_ADMINME = 256
RPL_ADMINLOC1 = 257
RPL_ADMINLOC2 = 258
RPL_ADMINEMAIL = 259
RPL_TRACELOG = 261
RPL_TRACEEND = 262
RPL_TRYAGAIN = 263
RPL_AWAY = 301
RPL_USERHOST = 302
RPL_ISON = 303
RPL_UNAWAY = 305
RPL_NOWAWAY = 306
RPL_WHOISUSER = 311
RPL_WHOISSERVER = 312
RPL_WHOISOPERATOR = 313
RPL_WHOWASUSER = 314
RPL_ENDOFWHO = 315
RPL_WHOISIDLE = 317
RPL_ENDOFWHOIS = 318
RPL_WHOISCHANNELS = 319
RPL_LIST = 322
RPL_LISTEND = 323
RPL_CHANNELMODEIS = 324
RPL_UNIQOPIS = 325
RPL_NOTOPIC = 331
RPL_TOPIC = 332
RPL_INVITING = 341
RPL_SUMMONING = 342
RPL_INVITELIST = 346
RPL_ENDOFINVITELIST = 347
RPL_EXCEPTLIST = 348
RPL_ENDOFEXCEPTLIST = 349
RPL_VERSION = 351
RPL_WHOREPLY = 352
RPL_NAMREPLY = 353
RPL_LINKS = 364
RPL_ENDOFLINKS = 365
RPL_ENDOFNAMES = 366
RPL_BANLIST = 367
RPL_ENDOFBANLIST = 368
RPL_ENDOFWHOWAS = 369
RPL_INFO = 371
RPL_MOTD = 372
RPL_ENDOFINFO = 374
RPL_MOTDSTART = 375
RPL_ENDOFMOTD = 376
RPL_YOUREOPER = 381
RPL_REHASHING = 382
RPL_YOURESERVICE = 383
RPL_TIME = 391
RPL_USERSSTART = 392
RPL_USERS = 393
RPL_ENDOFUSERS = 394
RPL_NOUSERS = 395
ERR_NOSUCHNICK = 401
ERR_NOSUCHSERVER = 402
ERR_NOSUCHCHANNEL = 403
ERR_CANNOTSENDTOCHAN = 404
ERR_TOOMANYCHANNELS = 405
ERR_WASNOSUCHNICK = 406
ERR_TOOMANYTARGETS = 407
ERR_NOSUCHSERVICE = 408
ERR_NOORIGIN = 409
ERR_NORECIPIENT = 411
ERR_NOTEXTTOSEND = 412
ERR_NOTOPLEVEL = 413
ERR_WILDTOPLEVEL = 414
ERR_BADMASK = 415
ERR_UNKNOWNCOMMAND = 421
ERR_NOMOTD = 422
ERR_NOADMININFO = 423
ERR_FILEERROR = 424
ERR_NONICKNAMEGIVEN = 431
ERR_ERRONEUSNICKNAME = 432
ERR_NICKNAMEINUSE = 433
ERR_NICKCOLLISION = 436
ERR_UNAVAILRESOURCE = 437
ERR_USERNOTINCHANNEL = 441
ERR_NOTONCHANNEL = 442
ERR_USERONCHANNEL = 443
ERR_NOLOGIN = 444
ERR_SUMMONDISABLED = 445
ERR_USERSDISABLED = 446
ERR_NOTREGISTERED = 451
ERR_NEEDMOREPARAMS = 461
ERR_ALREADYREGISTRED = 462
ERR_NOPERMFORHOST = 463
ERR_PASSWDMISMATCH = 464
ERR_YOUREBANNEDCREEP = 465
ERR_YOUWILLBEBANNED = 466
ERR_KEYSET = 467
ERR_CHANNELISFULL = 471
ERR_UNKNOWNMODE = 472
ERR_INVITEONLYCHAN = 473
ERR_BANNEDFROMCHAN = 474
ERR_BADCHANNELKEY = 475
ERR_BADCHANMASK = 476
ERR_NOCHANMODES = 477
ERR_BANLISTFULL = 478
ERR_NOPRIVILEGES = 481
ERR_CHANOPRIVSNEEDED = 482
ERR_CANTKILLSERVER = 483
ERR_RESTRICTED = 484
ERR_UNIQOPPRIVSNEEDED = 485
ERR_NOOPERHOST = 491
ERR_UMODEUNKNOWNFLAG = 501
ERR_USERSDONTMATCH = 502
// message codes
RPL_INVITE = "INVITE"
RPL_JOIN = "JOIN"

View File

@ -74,7 +74,7 @@ type RegisterCommand struct {
email string
}
func (m RegisterCommand) String() string {
func (m *RegisterCommand) String() string {
return fmt.Sprintf("REGISTER(email=%s, password=%s)", m.email, m.password)
}
@ -107,11 +107,11 @@ func (m *RegisterCommand) HandleNickServ(ns *NickServ) {
}
user := NewUser(client.nick, m.password, ns.server)
ns.server.users[client.nick] = user
ns.Reply(client, "You have registered.")
if !user.Login(client, client.nick, m.password) {
ns.Reply(client, "Login failed.")
return
}
ns.Reply(client, "Logged in.")
}
@ -121,7 +121,7 @@ type IdentifyCommand struct {
password string
}
func (m IdentifyCommand) String() string {
func (m *IdentifyCommand) String() string {
return fmt.Sprintf("IDENTIFY(password=%s)", m.password)
}

View File

@ -22,78 +22,88 @@ type Reply interface {
Source() Identifier
}
type BasicReply struct {
type BaseReply struct {
source Identifier
code string
message string
}
func NewBasicReply(source Identifier, code string,
format string, args ...interface{}) *BasicReply {
message := fmt.Sprintf(format, args...)
fullMessage := fmt.Sprintf(":%s %s %s", source.Id(), code, message)
return &BasicReply{source, code, fullMessage}
func (reply *BaseReply) Source() Identifier {
return reply.source
}
func (reply BasicReply) String() string {
type StringReply struct {
BaseReply
code string
}
func NewStringReply(source Identifier, code string,
format string, args ...interface{}) *StringReply {
message := fmt.Sprintf(format, args...)
fullMessage := fmt.Sprintf(":%s %s %s", source.Id(), code, message)
return &StringReply{BaseReply{source, fullMessage}, code}
}
func (reply *StringReply) Format(client *Client) string {
return reply.message
}
func (reply *StringReply) String() string {
return fmt.Sprintf("Reply(source=%s, code=%s, message=%s)",
reply.source, reply.code, reply.message)
}
func (reply BasicReply) Format(client *Client) string {
return reply.message
}
func (reply BasicReply) Source() Identifier {
return reply.source
}
type NumericReply struct {
BasicReply
BaseReply
code int
}
func NewNumericReply(source Identifier, code string,
func NewNumericReply(source Identifier, code int,
format string, args ...interface{}) *NumericReply {
return &NumericReply{BasicReply{source, code, fmt.Sprintf(format, args...)}}
return &NumericReply{BaseReply{source, fmt.Sprintf(format, args...)}, code}
}
func (reply NumericReply) Format(client *Client) string {
return fmt.Sprintf(":%s %s %s %s\r\n", reply.source.Id(), reply.code, client.Nick(),
reply.message)
func (reply *NumericReply) Format(client *Client) string {
return fmt.Sprintf(":%s %03d %s %s", reply.Source().Id(), reply.code,
client.Nick(), reply.message)
}
func (reply *NumericReply) String() string {
return fmt.Sprintf("Reply(source=%s, code=%d, message=%s)",
reply.source, reply.code, reply.message)
}
// messaging replies
func RplPrivMsg(source Identifier, target Identifier, message string) Reply {
return NewBasicReply(source, RPL_PRIVMSG, "%s :%s", target.Nick(), message)
return NewStringReply(source, RPL_PRIVMSG, "%s :%s", target.Nick(), message)
}
func RplNick(client *Client, newNick string) Reply {
return NewBasicReply(client, RPL_NICK, newNick)
return NewStringReply(client, RPL_NICK, newNick)
}
func RplPrivMsgChannel(channel *Channel, source Identifier, message string) Reply {
return NewBasicReply(source, RPL_PRIVMSG, "%s :%s", channel.name, message)
return NewStringReply(source, RPL_PRIVMSG, "%s :%s", channel.name, message)
}
func RplJoin(channel *Channel, user *User) Reply {
return NewBasicReply(user, RPL_JOIN, channel.name)
return NewStringReply(user, RPL_JOIN, channel.name)
}
func RplPart(channel *Channel, user *User, message string) Reply {
return NewBasicReply(user, RPL_PART, "%s :%s", channel.name, message)
return NewStringReply(user, RPL_PART, "%s :%s", channel.name, message)
}
func RplPong(server *Server) Reply {
return NewBasicReply(server, RPL_PONG, server.Id())
return NewStringReply(server, RPL_PONG, server.Id())
}
func RplQuit(client *Client, message string) Reply {
return NewBasicReply(client, RPL_QUIT, ":%", message)
return NewStringReply(client, RPL_QUIT, ":%s", message)
}
func RplInviteMsg(channel *Channel, inviter *Client) Reply {
return NewBasicReply(inviter, RPL_INVITE, channel.name)
return NewStringReply(inviter, RPL_INVITE, channel.name)
}
// numeric replies

View File

@ -99,7 +99,7 @@ func (s Server) InterestedUsers(fromUser *User) UserSet {
// server functionality
func (s *Server) tryRegister(c *Client) {
if !c.registered && c.HasNick() && c.HasUser() && (s.password == nil || c.serverPass) {
if !c.registered && c.HasNick() && c.HasUsername() && (s.password == nil || c.serverPass) {
c.registered = true
replies := []Reply{RplWelcome(s, c), RplYourHost(s, c), RplCreated(s), RplMyInfo(s)}
for _, reply := range replies {
@ -112,15 +112,15 @@ func (s Server) Id() string {
return s.name
}
func (s Server) String() string {
func (s *Server) String() string {
return s.Id()
}
func (s Server) PublicId() string {
func (s *Server) PublicId() string {
return s.Id()
}
func (s Server) Nick() string {
func (s *Server) Nick() string {
return s.name
}
@ -132,7 +132,7 @@ func (s *Server) DeleteChannel(channel *Channel) {
// commands
//
func (m UnknownCommand) HandleServer(s *Server) {
func (m *UnknownCommand) HandleServer(s *Server) {
m.Client().Replies() <- ErrUnknownCommand(s, m.command)
}

View File

@ -50,19 +50,19 @@ func receiveCommands(service Service, commands <-chan ServiceCommand) {
}
}
func (service BaseService) Id() string {
func (service *BaseService) Id() string {
return fmt.Sprintf("%s!%s@%s", service.name, service.name, service.server.name)
}
func (service BaseService) String() string {
func (service *BaseService) String() string {
return service.Id()
}
func (service BaseService) PublicId() string {
func (service *BaseService) PublicId() string {
return service.Id()
}
func (service BaseService) Nick() string {
func (service *BaseService) Nick() string {
return service.name
}
@ -70,10 +70,14 @@ func (service *BaseService) Reply(client *Client, message string) {
client.Replies() <- RplPrivMsg(service, client, message)
}
func (service BaseService) Commands() chan<- ServiceCommand {
func (service *BaseService) Commands() chan<- ServiceCommand {
return service.commands
}
//
// commands
//
func (m *PrivMsgCommand) HandleService(service Service) {
service.HandlePrivMsg(m)
}

View File

@ -6,6 +6,10 @@ import (
"log"
)
const (
DEBUG_USER = true
)
type UserCommand interface {
Command
HandleUser(*User)
@ -44,6 +48,7 @@ func NewUser(nick string, password string, server *Server) *User {
user.SetPassword(password)
go user.receiveCommands(commands)
go user.receiveReplies(replies)
server.users[nick] = user
return user
}
@ -57,7 +62,9 @@ func (user *User) SetPassword(password string) {
func (user *User) receiveCommands(commands <-chan UserCommand) {
for command := range commands {
log.Printf("%s %T %+v", user.Id(), command, command)
if DEBUG_USER {
log.Printf("%s ← %s %s", user, command.Client(), command)
}
command.HandleUser(user)
}
}
@ -65,7 +72,7 @@ func (user *User) receiveCommands(commands <-chan UserCommand) {
// Distribute replies to clients.
func (user *User) receiveReplies(replies <-chan Reply) {
for reply := range replies {
log.Printf("%s %T %+v", user.Id(), reply, reply)
log.Printf("%s ← %s", user, reply)
for client := range user.clients {
client.Replies() <- reply
}
@ -74,19 +81,23 @@ func (user *User) receiveReplies(replies <-chan Reply) {
// Identifier
func (user User) Id() string {
func (user *User) Id() string {
return fmt.Sprintf("%s!%s@%s", user.nick, user.nick, user.server.Id())
}
func (user User) PublicId() string {
func (user *User) PublicId() string {
return user.Id()
}
func (user User) Nick() string {
func (user *User) Nick() string {
return user.nick
}
func (user User) Commands() chan<- UserCommand {
func (user *User) String() string {
return user.Id()
}
func (user *User) Commands() chan<- UserCommand {
return user.commands
}
@ -123,11 +134,11 @@ func (user *User) LogoutClient(c *Client) bool {
return false
}
func (user User) HasClients() bool {
func (user *User) HasClients() bool {
return len(user.clients) > 0
}
func (user User) Replies() chan<- Reply {
func (user *User) Replies() chan<- Reply {
return user.replies
}