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