mirror of
https://github.com/ergochat/ergo.git
synced 2024-11-25 05:19:25 +01:00
Update a bunch of messages and fix reply struct embedding.
This commit is contained in:
parent
8e5ff51257
commit
c42cd92f91
@ -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)
|
||||
}
|
||||
|
@ -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())
|
||||
}
|
||||
|
@ -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)
|
||||
}
|
||||
|
||||
|
@ -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"
|
||||
|
@ -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)
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
}
|
||||
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user