mirror of
https://github.com/ergochat/ergo.git
synced 2024-12-22 10:42:52 +01:00
continue work reorganising and redoing EVERYTHING
This commit is contained in:
parent
31c1df55a3
commit
08225c201d
@ -6,17 +6,8 @@ package irc
|
||||
|
||||
import (
|
||||
"strings"
|
||||
)
|
||||
|
||||
type CapSubCommand string
|
||||
|
||||
const (
|
||||
CAP_LS CapSubCommand = "LS"
|
||||
CAP_LIST CapSubCommand = "LIST"
|
||||
CAP_REQ CapSubCommand = "REQ"
|
||||
CAP_ACK CapSubCommand = "ACK"
|
||||
CAP_NAK CapSubCommand = "NAK"
|
||||
CAP_END CapSubCommand = "END"
|
||||
"github.com/DanielOaks/girc-go/ircmsg"
|
||||
)
|
||||
|
||||
// Capabilities are optional features a client may request from a server.
|
||||
@ -81,65 +72,56 @@ func (set CapabilitySet) DisableString() string {
|
||||
return strings.Join(parts, " ")
|
||||
}
|
||||
|
||||
func (msg *CapCommand) HandleRegServer(server *Server) {
|
||||
client := msg.Client()
|
||||
// CAP <subcmd> [<caps>]
|
||||
func capHandler(server *Server, client *Client, msg ircmsg.IrcMessage) bool {
|
||||
subCommand := strings.ToUpper(msg.Params[0])
|
||||
capabilities := make(CapabilitySet)
|
||||
var capString string
|
||||
|
||||
switch msg.subCommand {
|
||||
case CAP_LS:
|
||||
client.capState = CapNegotiating
|
||||
client.Reply(RplCap(client, CAP_LS, SupportedCapabilities))
|
||||
|
||||
case CAP_LIST:
|
||||
client.Reply(RplCap(client, CAP_LIST, client.capabilities))
|
||||
|
||||
case CAP_REQ:
|
||||
for capability := range msg.capabilities {
|
||||
if !SupportedCapabilities[capability] {
|
||||
client.Reply(RplCap(client, CAP_NAK, msg.capabilities))
|
||||
return
|
||||
if len(msg.Params) > 1 {
|
||||
capString = msg.Params[1]
|
||||
strs := strings.Split(capString, " ")
|
||||
for _, str := range strs {
|
||||
if len(str) > 0 {
|
||||
capabilities[Capability(str)] = true
|
||||
}
|
||||
}
|
||||
for capability := range msg.capabilities {
|
||||
client.capabilities[capability] = true
|
||||
}
|
||||
client.Reply(RplCap(client, CAP_ACK, msg.capabilities))
|
||||
|
||||
case CAP_END:
|
||||
client.capState = CapNegotiated
|
||||
server.tryRegister(client)
|
||||
|
||||
default:
|
||||
client.ErrInvalidCapCmd(msg.subCommand)
|
||||
}
|
||||
}
|
||||
|
||||
func (msg *CapCommand) HandleServer(server *Server) {
|
||||
client := msg.Client()
|
||||
switch subCommand {
|
||||
case "LS":
|
||||
if !client.registered {
|
||||
client.capState = CapNegotiating
|
||||
}
|
||||
// client.server needs to be here to workaround a parsing bug in weechat 1.4
|
||||
// and let it connect to the server (otherwise it doesn't respond to the CAP
|
||||
// message with anything and just hangs on connection)
|
||||
client.Send(nil, server.name, "CAP", client.nickString, subCommand, SupportedCapabilities.String())
|
||||
|
||||
switch msg.subCommand {
|
||||
case CAP_LS:
|
||||
client.Reply(RplCap(client, CAP_LS, SupportedCapabilities))
|
||||
case "LIST":
|
||||
client.Send(nil, server.name, "CAP", client.nickString, subCommand, client.capabilities.String())
|
||||
|
||||
case CAP_LIST:
|
||||
client.Reply(RplCap(client, CAP_LIST, client.capabilities))
|
||||
|
||||
case CAP_REQ:
|
||||
for capability := range msg.capabilities {
|
||||
case "REQ":
|
||||
// make sure all capabilities actually exist
|
||||
for capability := range capabilities {
|
||||
if !SupportedCapabilities[capability] {
|
||||
client.Reply(RplCap(client, CAP_NAK, msg.capabilities))
|
||||
return
|
||||
client.Send(nil, server.name, "CAP", client.nickString, subCommand, capString)
|
||||
return false
|
||||
}
|
||||
}
|
||||
for capability := range msg.capabilities {
|
||||
for capability := range capabilities {
|
||||
client.capabilities[capability] = true
|
||||
}
|
||||
client.Reply(RplCap(client, CAP_ACK, msg.capabilities))
|
||||
client.Send(nil, server.name, "CAP", client.nickString, subCommand, capString)
|
||||
|
||||
case CAP_END:
|
||||
// no-op after registration performed
|
||||
return
|
||||
case "END":
|
||||
if !client.registered {
|
||||
client.capState = CapNegotiated
|
||||
server.tryRegister(client)
|
||||
}
|
||||
|
||||
default:
|
||||
client.ErrInvalidCapCmd(msg.subCommand)
|
||||
client.Send(nil, server.name, ERR_INVALIDCAPCMD, client.nickString, subCommand, "Invalid CAP subcommand")
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
@ -32,12 +32,14 @@ type Client struct {
|
||||
hostname Name
|
||||
idleTimer *time.Timer
|
||||
nick Name
|
||||
nickString string // cache for nick string since it's used with every reply
|
||||
quitTimer *time.Timer
|
||||
realname Text
|
||||
registered bool
|
||||
server *Server
|
||||
socket *Socket
|
||||
username Name
|
||||
isDestroyed bool
|
||||
}
|
||||
|
||||
func NewClient(server *Server, conn net.Conn) *Client {
|
||||
@ -83,20 +85,26 @@ func (client *Client) run() {
|
||||
break
|
||||
}
|
||||
|
||||
msg, err = ParseLine(line)
|
||||
msg, err = ircmsg.ParseLine(line)
|
||||
if err != nil {
|
||||
client.Quit("received malformed command")
|
||||
break
|
||||
}
|
||||
|
||||
isExiting = Run(client.server, client, msg)
|
||||
cmd, exists := Commands[msg.Command]
|
||||
if !exists {
|
||||
//TODO(dan): Reply with 400 or whatever unknown cmd is
|
||||
client.Quit("Received unknown command")
|
||||
}
|
||||
|
||||
isExiting = cmd.Run(client.server, client, msg)
|
||||
if isExiting {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
// ensure client connection gets closed
|
||||
client.Destroy()
|
||||
client.destroy()
|
||||
}
|
||||
|
||||
//
|
||||
@ -246,8 +254,9 @@ func (client *Client) Reply(reply string) error {
|
||||
return client.socket.WriteLine(reply)
|
||||
}
|
||||
|
||||
func (client *Client) Quit(message Text) {
|
||||
client.Send("QUIT", message)
|
||||
func (client *Client) Quit(message string) {
|
||||
client.Send(nil, client.nickString, "QUIT", message)
|
||||
client.Send(nil, client.nickString, "ERROR", message)
|
||||
}
|
||||
|
||||
func (client *Client) destroy() {
|
||||
@ -277,11 +286,24 @@ func (client *Client) destroy() {
|
||||
}
|
||||
|
||||
client.socket.Close()
|
||||
|
||||
if len(friends) > 0 {
|
||||
reply := RplQuit(client, message)
|
||||
for friend := range friends {
|
||||
friend.Reply(reply)
|
||||
}
|
||||
for friend := range client.Friends() {
|
||||
//TODO(dan): store quit message in user, if exists use that instead here
|
||||
friend.Send(nil, client.nickString, "QUIT", "Exited")
|
||||
}
|
||||
}
|
||||
|
||||
// Send sends an IRC line to the client.
|
||||
func (client *Client) Send(tags *map[string]ircmsg.TagValue, prefix string, command string, params ...string) error {
|
||||
ircmsg := ircmsg.MakeMessage(tags, prefix, command, params...)
|
||||
line, err := ircmsg.Line()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
client.socket.Write(line)
|
||||
return nil
|
||||
}
|
||||
|
||||
// Notice sends the client a notice from the server.
|
||||
func (client *Client) Notice(text string) {
|
||||
client.Send(nil, client.server.name, "NOTICE", client.nickString, text)
|
||||
}
|
||||
|
@ -120,7 +120,7 @@ func (cs *ClientSocket) processIncomingLine(line string) bool {
|
||||
command, canBeParsed := Commands[msg.Command]
|
||||
|
||||
if canBeParsed {
|
||||
return command.Run(cs, msg)
|
||||
return command.Run(cs.client.server, &cs.client, msg)
|
||||
}
|
||||
//TODO(dan): This is an error+disconnect purely for reasons of testing.
|
||||
// Later it may be downgraded to not-that-bad.
|
||||
|
@ -5,19 +5,7 @@
|
||||
|
||||
package irc
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/DanielOaks/girc-go/ircmsg"
|
||||
)
|
||||
|
||||
// NICK <nickname>
|
||||
func nickHandler(server *Server, client *Client, msg ircmsg.IrcMessage) bool {
|
||||
// check NICK validity
|
||||
// send NICK change to primary server thread for processing
|
||||
// |-> ensure no other client exists with that nickname
|
||||
return true
|
||||
}
|
||||
import "fmt"
|
||||
|
||||
type ModeChange struct {
|
||||
mode UserMode
|
||||
|
@ -9,35 +9,26 @@ import "github.com/DanielOaks/girc-go/ircmsg"
|
||||
|
||||
// Command represents a command accepted on a listener.
|
||||
type Command struct {
|
||||
handler func(client *Client, msg ircmsg.IrcMessage) bool
|
||||
handler func(server *Server, client *Client, msg ircmsg.IrcMessage) bool
|
||||
usablePreReg bool
|
||||
minParams int
|
||||
}
|
||||
|
||||
// Run runs this command with the given listener/message.
|
||||
func (cmd *Command) Run(server *Server, client *Client, msg ircmsg.IrcMessage) bool {
|
||||
if !client.Registered && !cmd.usablePreReg {
|
||||
if !client.registered && !cmd.usablePreReg {
|
||||
// command silently ignored
|
||||
return false
|
||||
}
|
||||
if len(msg.Params) < cmd.minParams {
|
||||
listener.Send(nil, "", "461", client.Nick, msg.Command, "Not enough parameters")
|
||||
client.Send(nil, server.name, ERR_NEEDMOREPARAMS, client.nickString, msg.Command, "Not enough parameters")
|
||||
return false
|
||||
}
|
||||
exiting := cmd.handler(server, client, msg)
|
||||
|
||||
// after each command, see if we can send registration to the client
|
||||
if !client.Registered {
|
||||
isRegistered := true
|
||||
for _, fulfilled := range client.regLocks {
|
||||
if !fulfilled {
|
||||
isRegistered = false
|
||||
break
|
||||
}
|
||||
}
|
||||
if isRegistered {
|
||||
client.DumpRegistration()
|
||||
}
|
||||
if !client.registered {
|
||||
server.tryRegister(client)
|
||||
}
|
||||
|
||||
return exiting
|
||||
@ -82,10 +73,11 @@ var Commands = map[string]Command{
|
||||
handler: listHandler,
|
||||
minParams: 0,
|
||||
},
|
||||
/*TODO(dan): ADD THIS BACK.
|
||||
"MODE": Command{
|
||||
handler: modeHandler,
|
||||
minParams: 1,
|
||||
},
|
||||
},*/
|
||||
"MOTD": Command{
|
||||
handler: motdHandler,
|
||||
minParams: 0,
|
||||
@ -103,10 +95,11 @@ var Commands = map[string]Command{
|
||||
handler: noticeHandler,
|
||||
minParams: 2,
|
||||
},
|
||||
/*TODO(dan): ADD THIS BACK
|
||||
"ONICK": Command{
|
||||
handler: onickHandler,
|
||||
minParams: 2,
|
||||
},
|
||||
},*/
|
||||
"OPER": Command{
|
||||
handler: operHandler,
|
||||
minParams: 2,
|
||||
@ -144,10 +137,11 @@ var Commands = map[string]Command{
|
||||
usablePreReg: true,
|
||||
minParams: 0,
|
||||
},
|
||||
/*TODO(dan): ADD THIS BACK IN
|
||||
"THEATRE": Command{
|
||||
handler: theatreHandler,
|
||||
minParams: 1,
|
||||
},
|
||||
},*/
|
||||
"TIME": Command{
|
||||
handler: timeHandler,
|
||||
minParams: 0,
|
||||
|
35
irc/debug.go
35
irc/debug.go
@ -4,6 +4,7 @@
|
||||
package irc
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"runtime"
|
||||
"runtime/debug"
|
||||
@ -13,9 +14,10 @@ import (
|
||||
"github.com/DanielOaks/girc-go/ircmsg"
|
||||
)
|
||||
|
||||
// DEBUG GCSTATS/NUMGOROUTINE/etc
|
||||
func debugHandler(server *Server, client *Client, msg ircmsg.IrcMessage) bool {
|
||||
if !client.flags[Operator] {
|
||||
return
|
||||
return false
|
||||
}
|
||||
|
||||
switch msg.Params[0] {
|
||||
@ -26,47 +28,48 @@ func debugHandler(server *Server, client *Client, msg ircmsg.IrcMessage) bool {
|
||||
}
|
||||
debug.ReadGCStats(&stats)
|
||||
|
||||
server.Replyf(client, "last GC: %s", stats.LastGC.Format(time.RFC1123))
|
||||
server.Replyf(client, "num GC: %d", stats.NumGC)
|
||||
server.Replyf(client, "pause total: %s", stats.PauseTotal)
|
||||
server.Replyf(client, "pause quantiles min%%: %s", stats.PauseQuantiles[0])
|
||||
server.Replyf(client, "pause quantiles 25%%: %s", stats.PauseQuantiles[1])
|
||||
server.Replyf(client, "pause quantiles 50%%: %s", stats.PauseQuantiles[2])
|
||||
server.Replyf(client, "pause quantiles 75%%: %s", stats.PauseQuantiles[3])
|
||||
server.Replyf(client, "pause quantiles max%%: %s", stats.PauseQuantiles[4])
|
||||
client.Notice(fmt.Sprintf("last GC: %s", stats.LastGC.Format(time.RFC1123)))
|
||||
client.Notice(fmt.Sprintf("num GC: %d", stats.NumGC))
|
||||
client.Notice(fmt.Sprintf("pause total: %s", stats.PauseTotal))
|
||||
client.Notice(fmt.Sprintf("pause quantiles min%%: %s", stats.PauseQuantiles[0]))
|
||||
client.Notice(fmt.Sprintf("pause quantiles 25%%: %s", stats.PauseQuantiles[1]))
|
||||
client.Notice(fmt.Sprintf("pause quantiles 50%%: %s", stats.PauseQuantiles[2]))
|
||||
client.Notice(fmt.Sprintf("pause quantiles 75%%: %s", stats.PauseQuantiles[3]))
|
||||
client.Notice(fmt.Sprintf("pause quantiles max%%: %s", stats.PauseQuantiles[4]))
|
||||
|
||||
case "NUMGOROUTINE":
|
||||
count := runtime.NumGoroutine()
|
||||
server.Replyf(client, "num goroutines: %d", count)
|
||||
client.Notice(fmt.Sprintf("num goroutines: %d", count))
|
||||
|
||||
case "PROFILEHEAP":
|
||||
profFile := "ergonomadic.mprof"
|
||||
file, err := os.Create(profFile)
|
||||
if err != nil {
|
||||
server.Replyf(client, "error: %s", err)
|
||||
client.Notice(fmt.Sprintf("error: %s", err))
|
||||
break
|
||||
}
|
||||
defer file.Close()
|
||||
pprof.Lookup("heap").WriteTo(file, 0)
|
||||
server.Replyf(client, "written to %s", profFile)
|
||||
client.Notice(fmt.Sprintf("written to %s", profFile))
|
||||
|
||||
case "STARTCPUPROFILE":
|
||||
profFile := "ergonomadic.prof"
|
||||
file, err := os.Create(profFile)
|
||||
if err != nil {
|
||||
server.Replyf(client, "error: %s", err)
|
||||
client.Notice(fmt.Sprintf("error: %s", err))
|
||||
break
|
||||
}
|
||||
if err := pprof.StartCPUProfile(file); err != nil {
|
||||
defer file.Close()
|
||||
server.Replyf(client, "error: %s", err)
|
||||
client.Notice(fmt.Sprintf("error: %s", err))
|
||||
break
|
||||
}
|
||||
|
||||
server.Replyf(client, "CPU profile writing to %s", profFile)
|
||||
client.Notice(fmt.Sprintf("CPU profile writing to %s", profFile))
|
||||
|
||||
case "STOPCPUPROFILE":
|
||||
pprof.StopCPUProfile()
|
||||
server.Reply(client, "CPU profiling stopped")
|
||||
client.Notice(fmt.Sprintf("CPU profiling stopped"))
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
@ -4,6 +4,17 @@
|
||||
|
||||
package irc
|
||||
|
||||
import "github.com/DanielOaks/girc-go/ircmsg"
|
||||
|
||||
// NICK <nickname>
|
||||
func nickHandler(server *Server, client *Client, msg ircmsg.IrcMessage) bool {
|
||||
// check NICK validity
|
||||
// send NICK change to primary server thread for processing
|
||||
// |-> ensure no other client exists with that nickname
|
||||
//TODO(dan): SET client.nickString APPROPRIATELY
|
||||
return true
|
||||
}
|
||||
|
||||
/*
|
||||
type NickCommand struct {
|
||||
BaseCommand
|
||||
@ -17,6 +28,7 @@ func (m *NickCommand) HandleRegServer(s *Server) {
|
||||
client.Quit("bad password")
|
||||
return
|
||||
}
|
||||
//TODO(dan): SET client.nickString APPROPRIATELY
|
||||
|
||||
if m.nickname == "" {
|
||||
client.ErrNoNicknameGiven()
|
||||
@ -39,6 +51,7 @@ func (m *NickCommand) HandleRegServer(s *Server) {
|
||||
|
||||
func (msg *NickCommand) HandleServer(server *Server) {
|
||||
client := msg.Client()
|
||||
//TODO(dan): SET client.nickString APPROPRIATELY
|
||||
|
||||
if msg.nickname == "" {
|
||||
client.ErrNoNicknameGiven()
|
||||
@ -71,6 +84,7 @@ type OperNickCommand struct {
|
||||
|
||||
func (msg *OperNickCommand) HandleServer(server *Server) {
|
||||
client := msg.Client()
|
||||
//TODO(dan): SET client.nickString APPROPRIATELY
|
||||
|
||||
if !client.flags[Operator] {
|
||||
client.ErrNoPrivileges()
|
||||
|
276
irc/numerics.go
276
irc/numerics.go
@ -6,142 +6,142 @@
|
||||
package irc
|
||||
|
||||
const (
|
||||
RPL_WELCOME NumericCode = 1
|
||||
RPL_YOURHOST NumericCode = 2
|
||||
RPL_CREATED NumericCode = 3
|
||||
RPL_MYINFO NumericCode = 4
|
||||
RPL_ISUPPORT NumericCode = 5
|
||||
RPL_BOUNCE NumericCode = 10
|
||||
RPL_TRACELINK NumericCode = 200
|
||||
RPL_TRACECONNECTING NumericCode = 201
|
||||
RPL_TRACEHANDSHAKE NumericCode = 202
|
||||
RPL_TRACEUNKNOWN NumericCode = 203
|
||||
RPL_TRACEOPERATOR NumericCode = 204
|
||||
RPL_TRACEUSER NumericCode = 205
|
||||
RPL_TRACESERVER NumericCode = 206
|
||||
RPL_TRACESERVICE NumericCode = 207
|
||||
RPL_TRACENEWTYPE NumericCode = 208
|
||||
RPL_TRACECLASS NumericCode = 209
|
||||
RPL_TRACERECONNECT NumericCode = 210
|
||||
RPL_STATSLINKINFO NumericCode = 211
|
||||
RPL_STATSCOMMANDS NumericCode = 212
|
||||
RPL_ENDOFSTATS NumericCode = 219
|
||||
RPL_UMODEIS NumericCode = 221
|
||||
RPL_SERVLIST NumericCode = 234
|
||||
RPL_SERVLISTEND NumericCode = 235
|
||||
RPL_STATSUPTIME NumericCode = 242
|
||||
RPL_STATSOLINE NumericCode = 243
|
||||
RPL_LUSERCLIENT NumericCode = 251
|
||||
RPL_LUSEROP NumericCode = 252
|
||||
RPL_LUSERUNKNOWN NumericCode = 253
|
||||
RPL_LUSERCHANNELS NumericCode = 254
|
||||
RPL_LUSERME NumericCode = 255
|
||||
RPL_ADMINME NumericCode = 256
|
||||
RPL_ADMINLOC1 NumericCode = 257
|
||||
RPL_ADMINLOC2 NumericCode = 258
|
||||
RPL_ADMINEMAIL NumericCode = 259
|
||||
RPL_TRACELOG NumericCode = 261
|
||||
RPL_TRACEEND NumericCode = 262
|
||||
RPL_TRYAGAIN NumericCode = 263
|
||||
RPL_AWAY NumericCode = 301
|
||||
RPL_USERHOST NumericCode = 302
|
||||
RPL_ISON NumericCode = 303
|
||||
RPL_UNAWAY NumericCode = 305
|
||||
RPL_NOWAWAY NumericCode = 306
|
||||
RPL_WHOISUSER NumericCode = 311
|
||||
RPL_WHOISSERVER NumericCode = 312
|
||||
RPL_WHOISOPERATOR NumericCode = 313
|
||||
RPL_WHOWASUSER NumericCode = 314
|
||||
RPL_ENDOFWHO NumericCode = 315
|
||||
RPL_WHOISIDLE NumericCode = 317
|
||||
RPL_ENDOFWHOIS NumericCode = 318
|
||||
RPL_WHOISCHANNELS NumericCode = 319
|
||||
RPL_LIST NumericCode = 322
|
||||
RPL_LISTEND NumericCode = 323
|
||||
RPL_CHANNELMODEIS NumericCode = 324
|
||||
RPL_UNIQOPIS NumericCode = 325
|
||||
RPL_NOTOPIC NumericCode = 331
|
||||
RPL_TOPIC NumericCode = 332
|
||||
RPL_INVITING NumericCode = 341
|
||||
RPL_SUMMONING NumericCode = 342
|
||||
RPL_INVITELIST NumericCode = 346
|
||||
RPL_ENDOFINVITELIST NumericCode = 347
|
||||
RPL_EXCEPTLIST NumericCode = 348
|
||||
RPL_ENDOFEXCEPTLIST NumericCode = 349
|
||||
RPL_VERSION NumericCode = 351
|
||||
RPL_WHOREPLY NumericCode = 352
|
||||
RPL_NAMREPLY NumericCode = 353
|
||||
RPL_LINKS NumericCode = 364
|
||||
RPL_ENDOFLINKS NumericCode = 365
|
||||
RPL_ENDOFNAMES NumericCode = 366
|
||||
RPL_BANLIST NumericCode = 367
|
||||
RPL_ENDOFBANLIST NumericCode = 368
|
||||
RPL_ENDOFWHOWAS NumericCode = 369
|
||||
RPL_INFO NumericCode = 371
|
||||
RPL_MOTD NumericCode = 372
|
||||
RPL_ENDOFINFO NumericCode = 374
|
||||
RPL_MOTDSTART NumericCode = 375
|
||||
RPL_ENDOFMOTD NumericCode = 376
|
||||
RPL_YOUREOPER NumericCode = 381
|
||||
RPL_REHASHING NumericCode = 382
|
||||
RPL_YOURESERVICE NumericCode = 383
|
||||
RPL_TIME NumericCode = 391
|
||||
RPL_USERSSTART NumericCode = 392
|
||||
RPL_USERS NumericCode = 393
|
||||
RPL_ENDOFUSERS NumericCode = 394
|
||||
RPL_NOUSERS NumericCode = 395
|
||||
ERR_NOSUCHNICK NumericCode = 401
|
||||
ERR_NOSUCHSERVER NumericCode = 402
|
||||
ERR_NOSUCHCHANNEL NumericCode = 403
|
||||
ERR_CANNOTSENDTOCHAN NumericCode = 404
|
||||
ERR_TOOMANYCHANNELS NumericCode = 405
|
||||
ERR_WASNOSUCHNICK NumericCode = 406
|
||||
ERR_TOOMANYTARGETS NumericCode = 407
|
||||
ERR_NOSUCHSERVICE NumericCode = 408
|
||||
ERR_NOORIGIN NumericCode = 409
|
||||
ERR_INVALIDCAPCMD NumericCode = 410
|
||||
ERR_NORECIPIENT NumericCode = 411
|
||||
ERR_NOTEXTTOSEND NumericCode = 412
|
||||
ERR_NOTOPLEVEL NumericCode = 413
|
||||
ERR_WILDTOPLEVEL NumericCode = 414
|
||||
ERR_BADMASK NumericCode = 415
|
||||
ERR_UNKNOWNCOMMAND NumericCode = 421
|
||||
ERR_NOMOTD NumericCode = 422
|
||||
ERR_NOADMININFO NumericCode = 423
|
||||
ERR_FILEERROR NumericCode = 424
|
||||
ERR_NONICKNAMEGIVEN NumericCode = 431
|
||||
ERR_ERRONEUSNICKNAME NumericCode = 432
|
||||
ERR_NICKNAMEINUSE NumericCode = 433
|
||||
ERR_NICKCOLLISION NumericCode = 436
|
||||
ERR_UNAVAILRESOURCE NumericCode = 437
|
||||
ERR_USERNOTINCHANNEL NumericCode = 441
|
||||
ERR_NOTONCHANNEL NumericCode = 442
|
||||
ERR_USERONCHANNEL NumericCode = 443
|
||||
ERR_NOLOGIN NumericCode = 444
|
||||
ERR_SUMMONDISABLED NumericCode = 445
|
||||
ERR_USERSDISABLED NumericCode = 446
|
||||
ERR_NOTREGISTERED NumericCode = 451
|
||||
ERR_NEEDMOREPARAMS NumericCode = 461
|
||||
ERR_ALREADYREGISTRED NumericCode = 462
|
||||
ERR_NOPERMFORHOST NumericCode = 463
|
||||
ERR_PASSWDMISMATCH NumericCode = 464
|
||||
ERR_YOUREBANNEDCREEP NumericCode = 465
|
||||
ERR_YOUWILLBEBANNED NumericCode = 466
|
||||
ERR_KEYSET NumericCode = 467
|
||||
ERR_CHANNELISFULL NumericCode = 471
|
||||
ERR_UNKNOWNMODE NumericCode = 472
|
||||
ERR_INVITEONLYCHAN NumericCode = 473
|
||||
ERR_BANNEDFROMCHAN NumericCode = 474
|
||||
ERR_BADCHANNELKEY NumericCode = 475
|
||||
ERR_BADCHANMASK NumericCode = 476
|
||||
ERR_NOCHANMODES NumericCode = 477
|
||||
ERR_BANLISTFULL NumericCode = 478
|
||||
ERR_NOPRIVILEGES NumericCode = 481
|
||||
ERR_CHANOPRIVSNEEDED NumericCode = 482
|
||||
ERR_CANTKILLSERVER NumericCode = 483
|
||||
ERR_RESTRICTED NumericCode = 484
|
||||
ERR_UNIQOPPRIVSNEEDED NumericCode = 485
|
||||
ERR_NOOPERHOST NumericCode = 491
|
||||
ERR_UMODEUNKNOWNFLAG NumericCode = 501
|
||||
ERR_USERSDONTMATCH NumericCode = 502
|
||||
RPL_WELCOME = "001"
|
||||
RPL_YOURHOST = "002"
|
||||
RPL_CREATED = "003"
|
||||
RPL_MYINFO = "004"
|
||||
RPL_ISUPPORT = "005"
|
||||
RPL_BOUNCE = "010"
|
||||
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_INVALIDCAPCMD = "410"
|
||||
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"
|
||||
)
|
||||
|
@ -5,11 +5,7 @@
|
||||
|
||||
package irc
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
/*
|
||||
|
||||
type ReplyCode interface {
|
||||
String() string
|
||||
@ -585,3 +581,4 @@ func (target *Client) ErrInviteOnlyChan(channel *Channel) {
|
||||
target.NumericReply(ERR_INVITEONLYCHAN,
|
||||
"%s :Cannot join channel (+i)", channel)
|
||||
}
|
||||
*/
|
||||
|
@ -31,7 +31,7 @@ type Server struct {
|
||||
db *sql.DB
|
||||
idle chan *Client
|
||||
motdLines []string
|
||||
name Name
|
||||
name string
|
||||
newConns chan net.Conn
|
||||
operators map[Name][]byte
|
||||
password []byte
|
||||
@ -324,6 +324,7 @@ func (s *Server) tryRegister(c *Client) {
|
||||
(c.capState == CapNegotiating) {
|
||||
return
|
||||
}
|
||||
c.registered = true
|
||||
|
||||
c.Send("Intro to the network")
|
||||
c.Register()
|
||||
@ -1015,7 +1016,6 @@ func whowasHandler(server *Server, client *Client, msg ircmsg.IrcMessage) bool {
|
||||
client.Send("send")
|
||||
}
|
||||
}
|
||||
client.RplEndOfWhoWas(nickname)
|
||||
client.Send("send")
|
||||
client.Send(nil, server.Name, RPL_ENDOFWHOWAS, nickname, "End of WHOWAS")
|
||||
}
|
||||
}
|
||||
|
@ -14,17 +14,7 @@ func (c TheaterClient) Nick() Name {
|
||||
return Name(c)
|
||||
}
|
||||
|
||||
type TheaterSubCommand string
|
||||
|
||||
type theaterSubCommand interface {
|
||||
String() string
|
||||
}
|
||||
|
||||
type TheaterIdentifyCommand struct {
|
||||
PassCommand
|
||||
channel Name
|
||||
}
|
||||
|
||||
/*
|
||||
func (m *TheaterIdentifyCommand) LoadPassword(s *Server) {
|
||||
m.hash = s.theaters[m.channel]
|
||||
}
|
||||
@ -118,3 +108,4 @@ func (m *TheaterActionCommand) HandleServer(s *Server) {
|
||||
member.Reply(reply)
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
Loading…
Reference in New Issue
Block a user