mirror of
				https://github.com/ergochat/ergo.git
				synced 2025-11-04 07:47:25 +01:00 
			
		
		
		
	Merge pull request #453 from oragono/master+acc-updates
Update ACC to latest spec
This commit is contained in:
		
						commit
						b11b34b793
					
				@ -15,6 +15,12 @@ from collections import namedtuple
 | 
			
		||||
CapDef = namedtuple("CapDef", ['identifier', 'name', 'url', 'standard'])
 | 
			
		||||
 | 
			
		||||
CAPDEFS = [
 | 
			
		||||
    CapDef(
 | 
			
		||||
        identifier="Acc",
 | 
			
		||||
        name="draft/acc",
 | 
			
		||||
        url="https://github.com/ircv3/ircv3-specifications/pull/276",
 | 
			
		||||
        standard="proposed IRCv3",
 | 
			
		||||
    ),
 | 
			
		||||
    CapDef(
 | 
			
		||||
        identifier="AccountNotify",
 | 
			
		||||
        name="account-notify",
 | 
			
		||||
 | 
			
		||||
@ -7,12 +7,16 @@ package caps
 | 
			
		||||
 | 
			
		||||
const (
 | 
			
		||||
	// number of recognized capabilities:
 | 
			
		||||
	numCapabs = 21
 | 
			
		||||
	numCapabs = 22
 | 
			
		||||
	// length of the uint64 array that represents the bitset:
 | 
			
		||||
	bitsetLen = 1
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
const (
 | 
			
		||||
	// Acc is the proposed IRCv3 capability named "draft/acc":
 | 
			
		||||
	// https://github.com/ircv3/ircv3-specifications/pull/276
 | 
			
		||||
	Acc Capability = iota
 | 
			
		||||
 | 
			
		||||
	// AccountNotify is the IRCv3 capability named "account-notify":
 | 
			
		||||
	// https://ircv3.net/specs/extensions/account-notify-3.1.html
 | 
			
		||||
	AccountNotify Capability = iota
 | 
			
		||||
@ -101,6 +105,7 @@ const (
 | 
			
		||||
// `capabilityNames[capab]` is the string name of the capability `capab`
 | 
			
		||||
var (
 | 
			
		||||
	capabilityNames = [numCapabs]string{
 | 
			
		||||
		"draft/acc",
 | 
			
		||||
		"account-notify",
 | 
			
		||||
		"account-tag",
 | 
			
		||||
		"away-notify",
 | 
			
		||||
 | 
			
		||||
@ -71,8 +71,9 @@ var Commands map[string]Command
 | 
			
		||||
func init() {
 | 
			
		||||
	Commands = map[string]Command{
 | 
			
		||||
		"ACC": {
 | 
			
		||||
			handler:   accHandler,
 | 
			
		||||
			minParams: 3,
 | 
			
		||||
			handler:      accHandler,
 | 
			
		||||
			usablePreReg: true,
 | 
			
		||||
			minParams:    1,
 | 
			
		||||
		},
 | 
			
		||||
		"AMBIANCE": {
 | 
			
		||||
			handler:   sceneHandler,
 | 
			
		||||
 | 
			
		||||
@ -13,6 +13,7 @@ import (
 | 
			
		||||
	"net"
 | 
			
		||||
	"os"
 | 
			
		||||
	"regexp"
 | 
			
		||||
	"sort"
 | 
			
		||||
	"strings"
 | 
			
		||||
	"time"
 | 
			
		||||
 | 
			
		||||
@ -609,6 +610,7 @@ func LoadConfig(filename string) (config *Config, err error) {
 | 
			
		||||
			config.Accounts.Registration.EnabledCallbacks[i] = "*"
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	sort.Strings(config.Accounts.Registration.EnabledCallbacks)
 | 
			
		||||
 | 
			
		||||
	config.Accounts.RequireSasl.exemptedNets, err = utils.ParseNetList(config.Accounts.RequireSasl.Exempted)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										128
									
								
								irc/handlers.go
									
									
									
									
									
								
							
							
						
						
									
										128
									
								
								irc/handlers.go
									
									
									
									
									
								
							@ -31,15 +31,40 @@ import (
 | 
			
		||||
	"golang.org/x/crypto/bcrypt"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// ACC [REGISTER|VERIFY] ...
 | 
			
		||||
// ACC [LS|REGISTER|VERIFY] ...
 | 
			
		||||
func accHandler(server *Server, client *Client, msg ircmsg.IrcMessage, rb *ResponseBuffer) bool {
 | 
			
		||||
	// make sure reg is enabled
 | 
			
		||||
	if !server.AccountConfig().Registration.Enabled {
 | 
			
		||||
		rb.Add(nil, server.name, ERR_REG_UNSPECIFIED_ERROR, client.nick, "*", client.t("Account registration is disabled"))
 | 
			
		||||
	subcommand := strings.ToLower(msg.Params[0])
 | 
			
		||||
 | 
			
		||||
	if subcommand == "ls" {
 | 
			
		||||
		config := server.Config().Accounts
 | 
			
		||||
 | 
			
		||||
		rb.Add(nil, server.name, "ACC", "LS", "SUBCOMMANDS", "LS REGISTER VERIFY")
 | 
			
		||||
 | 
			
		||||
		// this list is sorted by the config loader, yay
 | 
			
		||||
		rb.Add(nil, server.name, "ACC", "LS", "CALLBACKS", strings.Join(config.Registration.EnabledCallbacks, " "))
 | 
			
		||||
 | 
			
		||||
		rb.Add(nil, server.name, "ACC", "LS", "CREDTYPES", "passphrase certfp")
 | 
			
		||||
 | 
			
		||||
		flags := []string{"nospaces"}
 | 
			
		||||
		if config.NickReservation.Enabled {
 | 
			
		||||
			flags = append(flags, "regnick")
 | 
			
		||||
		}
 | 
			
		||||
		sort.Strings(flags)
 | 
			
		||||
		rb.Add(nil, server.name, "ACC", "LS", "FLAGS", strings.Join(flags, " "))
 | 
			
		||||
		return false
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	subcommand := strings.ToLower(msg.Params[0])
 | 
			
		||||
	// disallow account stuff before connection registration has completed, for now
 | 
			
		||||
	if !client.Registered() {
 | 
			
		||||
		client.Send(nil, server.name, ERR_NOTREGISTERED, "*", client.t("You need to register before you can use that command"))
 | 
			
		||||
		return false
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// make sure reg is enabled
 | 
			
		||||
	if !server.AccountConfig().Registration.Enabled {
 | 
			
		||||
		rb.Add(nil, server.name, "FAIL", "ACC", "REG_UNAVAILABLE", client.t("Account registration is disabled"))
 | 
			
		||||
		return false
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if subcommand == "register" {
 | 
			
		||||
		return accRegisterHandler(server, client, msg, rb)
 | 
			
		||||
@ -61,7 +86,7 @@ func parseCallback(spec string, config *AccountConfig) (callbackNamespace string
 | 
			
		||||
		callbackValues := strings.SplitN(callback, ":", 2)
 | 
			
		||||
		callbackNamespace, callbackValue = callbackValues[0], callbackValues[1]
 | 
			
		||||
	} else {
 | 
			
		||||
		// "the IRC server MAY choose to use mailto as a default"
 | 
			
		||||
		// "If a callback namespace is not ... provided, the IRC server MUST use mailto""
 | 
			
		||||
		callbackNamespace = "mailto"
 | 
			
		||||
		callbackValue = callback
 | 
			
		||||
	}
 | 
			
		||||
@ -81,31 +106,42 @@ func parseCallback(spec string, config *AccountConfig) (callbackNamespace string
 | 
			
		||||
// ACC REGISTER <accountname> [callback_namespace:]<callback> [cred_type] :<credential>
 | 
			
		||||
func accRegisterHandler(server *Server, client *Client, msg ircmsg.IrcMessage, rb *ResponseBuffer) bool {
 | 
			
		||||
	nick := client.Nick()
 | 
			
		||||
	// clients can't reg new accounts if they're already logged in
 | 
			
		||||
	if client.LoggedIntoAccount() {
 | 
			
		||||
		rb.Add(nil, server.name, ERR_REG_UNSPECIFIED_ERROR, nick, "*", client.t("You're already logged into an account"))
 | 
			
		||||
		return false
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// get and sanitise account name
 | 
			
		||||
	account := strings.TrimSpace(msg.Params[1])
 | 
			
		||||
	casefoldedAccount, err := CasefoldName(account)
 | 
			
		||||
	// probably don't need explicit check for "*" here... but let's do it anyway just to make sure
 | 
			
		||||
	if err != nil || msg.Params[1] == "*" {
 | 
			
		||||
		rb.Add(nil, server.name, ERR_REG_UNSPECIFIED_ERROR, nick, account, client.t("Account name is not valid"))
 | 
			
		||||
		return false
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if len(msg.Params) < 4 {
 | 
			
		||||
		rb.Add(nil, server.name, ERR_NEEDMOREPARAMS, nick, msg.Command, client.t("Not enough parameters"))
 | 
			
		||||
		return false
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	account := msg.Params[1]
 | 
			
		||||
 | 
			
		||||
	// check for account name of *
 | 
			
		||||
	if account == "*" {
 | 
			
		||||
		account = nick
 | 
			
		||||
	} else {
 | 
			
		||||
		if server.Config().Accounts.NickReservation.Enabled {
 | 
			
		||||
			rb.Add(nil, server.name, "FAIL", "ACC", "REG_MUST_USE_REGNICK", account, client.t("Must register with current nickname instead of separate account name"))
 | 
			
		||||
			return false
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// clients can't reg new accounts if they're already logged in
 | 
			
		||||
	if client.LoggedIntoAccount() {
 | 
			
		||||
		rb.Add(nil, server.name, "FAIL", "ACC", "REG_UNSPECIFIED_ERROR", account, client.t("You're already logged into an account"))
 | 
			
		||||
		return false
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// sanitise account name
 | 
			
		||||
	casefoldedAccount, err := CasefoldName(account)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		rb.Add(nil, server.name, "FAIL", "ACC", "REG_INVALID_ACCOUNT_NAME", account, client.t("Account name is not valid"))
 | 
			
		||||
		return false
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	callbackSpec := msg.Params[2]
 | 
			
		||||
	callbackNamespace, callbackValue := parseCallback(callbackSpec, server.AccountConfig())
 | 
			
		||||
 | 
			
		||||
	if callbackNamespace == "" {
 | 
			
		||||
		rb.Add(nil, server.name, ERR_REG_INVALID_CALLBACK, nick, account, callbackSpec, client.t("Callback namespace is not supported"))
 | 
			
		||||
		rb.Add(nil, server.name, "FAIL", "ACC", "REG_INVALID_CALLBACK", account, callbackSpec, client.t("Cannot send verification code there"))
 | 
			
		||||
		return false
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
@ -129,12 +165,12 @@ func accRegisterHandler(server *Server, client *Client, msg ircmsg.IrcMessage, r
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	if credentialType == "certfp" && client.certfp == "" {
 | 
			
		||||
		rb.Add(nil, server.name, ERR_REG_INVALID_CRED_TYPE, nick, credentialType, callbackNamespace, client.t("You are not using a TLS certificate"))
 | 
			
		||||
		rb.Add(nil, server.name, "FAIL", "ACC", "REG_INVALID_CREDENTIAL", account, client.t("You must connect with a TLS client certificate to use certfp"))
 | 
			
		||||
		return false
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if !credentialValid {
 | 
			
		||||
		rb.Add(nil, server.name, ERR_REG_INVALID_CRED_TYPE, nick, credentialType, callbackNamespace, client.t("Credential type is not supported"))
 | 
			
		||||
		rb.Add(nil, server.name, "FAIL", "ACC", "REG_INVALID_CRED_TYPE", account, credentialType, client.t("Credential type is not supported"))
 | 
			
		||||
		return false
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
@ -147,14 +183,14 @@ func accRegisterHandler(server *Server, client *Client, msg ircmsg.IrcMessage, r
 | 
			
		||||
 | 
			
		||||
	throttled, remainingTime := client.loginThrottle.Touch()
 | 
			
		||||
	if throttled {
 | 
			
		||||
		rb.Add(nil, server.name, ERR_REG_UNSPECIFIED_ERROR, nick, fmt.Sprintf(client.t("Please wait at least %v and try again"), remainingTime))
 | 
			
		||||
		rb.Add(nil, server.name, "FAIL", "ACC", "REG_UNSPECIFIED_ERROR", account, fmt.Sprintf(client.t("Please wait at least %v and try again"), remainingTime))
 | 
			
		||||
		return false
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	err = server.accounts.Register(client, account, callbackNamespace, callbackValue, passphrase, certfp)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		msg, code := registrationErrorToMessageAndCode(err)
 | 
			
		||||
		rb.Add(nil, server.name, code, nick, "ACC", "REGISTER", client.t(msg))
 | 
			
		||||
		rb.Add(nil, server.name, "FAIL", "ACC", code, account, client.t(msg))
 | 
			
		||||
		return false
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
@ -174,15 +210,17 @@ func accRegisterHandler(server *Server, client *Client, msg ircmsg.IrcMessage, r
 | 
			
		||||
	return false
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func registrationErrorToMessageAndCode(err error) (message, numeric string) {
 | 
			
		||||
func registrationErrorToMessageAndCode(err error) (message, code string) {
 | 
			
		||||
	// default responses: let's be risk-averse about displaying internal errors
 | 
			
		||||
	// to the clients, especially for something as sensitive as accounts
 | 
			
		||||
	code = "REG_UNSPECIFIED_ERROR"
 | 
			
		||||
	message = `Could not register`
 | 
			
		||||
	numeric = ERR_UNKNOWNERROR
 | 
			
		||||
	switch err {
 | 
			
		||||
	case errAccountBadPassphrase:
 | 
			
		||||
		code = "REG_INVALID_CREDENTIAL"
 | 
			
		||||
		message = err.Error()
 | 
			
		||||
	case errAccountAlreadyRegistered, errAccountAlreadyVerified:
 | 
			
		||||
		message = err.Error()
 | 
			
		||||
		numeric = ERR_ACCOUNT_ALREADY_EXISTS
 | 
			
		||||
	case errAccountCreation, errAccountMustHoldNick, errAccountBadPassphrase, errCertfpAlreadyExists, errFeatureDisabled:
 | 
			
		||||
		message = err.Error()
 | 
			
		||||
	}
 | 
			
		||||
@ -194,20 +232,23 @@ func sendSuccessfulRegResponse(client *Client, rb *ResponseBuffer, forNS bool) {
 | 
			
		||||
	if forNS {
 | 
			
		||||
		rb.Notice(client.t("Account created"))
 | 
			
		||||
	} else {
 | 
			
		||||
		rb.Add(nil, client.server.name, RPL_REGISTRATION_SUCCESS, client.nick, client.AccountName(), client.t("Account created"))
 | 
			
		||||
		rb.Add(nil, client.server.name, RPL_REG_SUCCESS, client.nick, client.AccountName(), client.t("Account created"))
 | 
			
		||||
	}
 | 
			
		||||
	sendSuccessfulSaslAuth(client, rb, forNS)
 | 
			
		||||
	sendSuccessfulAccountAuth(client, rb, forNS, false)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// sendSuccessfulSaslAuth means that a SASL auth attempt completed successfully, and is used to dispatch messages.
 | 
			
		||||
func sendSuccessfulSaslAuth(client *Client, rb *ResponseBuffer, forNS bool) {
 | 
			
		||||
// sendSuccessfulAccountAuth means that an account auth attempt completed successfully, and is used to dispatch messages.
 | 
			
		||||
func sendSuccessfulAccountAuth(client *Client, rb *ResponseBuffer, forNS, forSASL bool) {
 | 
			
		||||
	details := client.Details()
 | 
			
		||||
 | 
			
		||||
	if forNS {
 | 
			
		||||
		rb.Notice(fmt.Sprintf(client.t("You're now logged in as %s"), details.accountName))
 | 
			
		||||
	} else {
 | 
			
		||||
		//TODO(dan): some servers send this numeric even for NickServ logins iirc? to confirm and maybe do too
 | 
			
		||||
		rb.Add(nil, client.server.name, RPL_LOGGEDIN, details.nick, details.nickMask, details.accountName, fmt.Sprintf(client.t("You are now logged in as %s"), details.accountName))
 | 
			
		||||
		rb.Add(nil, client.server.name, RPL_SASLSUCCESS, details.nick, client.t("Authentication successful"))
 | 
			
		||||
		if forSASL {
 | 
			
		||||
			rb.Add(nil, client.server.name, RPL_SASLSUCCESS, details.nick, client.t("Authentication successful"))
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// dispatch account-notify
 | 
			
		||||
@ -223,26 +264,33 @@ func sendSuccessfulSaslAuth(client *Client, rb *ResponseBuffer, forNS bool) {
 | 
			
		||||
// ACC VERIFY <accountname> <auth_code>
 | 
			
		||||
func accVerifyHandler(server *Server, client *Client, msg ircmsg.IrcMessage, rb *ResponseBuffer) bool {
 | 
			
		||||
	account := strings.TrimSpace(msg.Params[1])
 | 
			
		||||
 | 
			
		||||
	if len(msg.Params) < 3 {
 | 
			
		||||
		rb.Add(nil, server.name, ERR_NEEDMOREPARAMS, client.Nick(), msg.Command, client.t("Not enough parameters"))
 | 
			
		||||
		return false
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	err := server.accounts.Verify(client, account, msg.Params[2])
 | 
			
		||||
 | 
			
		||||
	var code string
 | 
			
		||||
	var message string
 | 
			
		||||
 | 
			
		||||
	if err == errAccountVerificationInvalidCode {
 | 
			
		||||
		code = ERR_ACCOUNT_INVALID_VERIFY_CODE
 | 
			
		||||
		code = "ACCOUNT_INVALID_VERIFY_CODE"
 | 
			
		||||
		message = err.Error()
 | 
			
		||||
	} else if err == errAccountAlreadyVerified {
 | 
			
		||||
		code = ERR_ACCOUNT_ALREADY_VERIFIED
 | 
			
		||||
		code = "ACCOUNT_ALREADY_VERIFIED"
 | 
			
		||||
		message = err.Error()
 | 
			
		||||
	} else if err != nil {
 | 
			
		||||
		code = ERR_UNKNOWNERROR
 | 
			
		||||
		code = "VERIFY_UNSPECIFIED_ERROR"
 | 
			
		||||
		message = errAccountVerificationFailed.Error()
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if err == nil {
 | 
			
		||||
		sendSuccessfulRegResponse(client, rb, false)
 | 
			
		||||
		rb.Add(nil, server.name, RPL_VERIFY_SUCCESS, client.Nick(), account, client.t("Account verification successful"))
 | 
			
		||||
		sendSuccessfulAccountAuth(client, rb, false, false)
 | 
			
		||||
	} else {
 | 
			
		||||
		rb.Add(nil, server.name, code, client.Nick(), account, client.t(message))
 | 
			
		||||
		rb.Add(nil, server.name, "FAIL", "ACC", code, account, client.t(message))
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return false
 | 
			
		||||
@ -373,7 +421,7 @@ func authPlainHandler(server *Server, client *Client, mechanism string, value []
 | 
			
		||||
		return false
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	sendSuccessfulSaslAuth(client, rb, false)
 | 
			
		||||
	sendSuccessfulAccountAuth(client, rb, false, true)
 | 
			
		||||
	return false
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -401,7 +449,7 @@ func authExternalHandler(server *Server, client *Client, mechanism string, value
 | 
			
		||||
		return false
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	sendSuccessfulSaslAuth(client, rb, false)
 | 
			
		||||
	sendSuccessfulAccountAuth(client, rb, false, true)
 | 
			
		||||
	return false
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -97,7 +97,8 @@ For instance, this would set the kill, oper, account and xline snomasks on dan:
 | 
			
		||||
var Help = map[string]HelpEntry{
 | 
			
		||||
	// Commands
 | 
			
		||||
	"acc": {
 | 
			
		||||
		text: `ACC REGISTER <accountname> [callback_namespace:]<callback> [cred_type] :<credential>
 | 
			
		||||
		text: `ACC LS
 | 
			
		||||
ACC REGISTER <accountname> [callback_namespace:]<callback> [cred_type] :<credential>
 | 
			
		||||
ACC VERIFY <accountname> <auth_code>
 | 
			
		||||
 | 
			
		||||
Used in account registration. See the relevant specs for more info:
 | 
			
		||||
 | 
			
		||||
@ -295,7 +295,7 @@ func nsIdentifyHandler(server *Server, client *Client, command string, params []
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if loginSuccessful {
 | 
			
		||||
		sendSuccessfulSaslAuth(client, rb, true)
 | 
			
		||||
		sendSuccessfulAccountAuth(client, rb, true, true)
 | 
			
		||||
	} else {
 | 
			
		||||
		nsNotice(rb, client.t("Could not login with your TLS certificate or supplied username/password"))
 | 
			
		||||
	}
 | 
			
		||||
@ -406,9 +406,9 @@ func nsRegisterHandler(server *Server, client *Client, command string, params []
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// details could not be stored and relevant numerics have been dispatched, abort
 | 
			
		||||
	message, _ := registrationErrorToMessageAndCode(err)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		errMsg, _ := registrationErrorToMessageAndCode(err)
 | 
			
		||||
		nsNotice(rb, errMsg)
 | 
			
		||||
		nsNotice(rb, client.t(message))
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										364
									
								
								irc/numerics.go
									
									
									
									
									
								
							
							
						
						
									
										364
									
								
								irc/numerics.go
									
									
									
									
									
								
							@ -12,191 +12,185 @@ package irc
 | 
			
		||||
// server ecosystem out there. Custom numerics will be marked as such.
 | 
			
		||||
 | 
			
		||||
const (
 | 
			
		||||
	RPL_WELCOME                     = "001"
 | 
			
		||||
	RPL_YOURHOST                    = "002"
 | 
			
		||||
	RPL_CREATED                     = "003"
 | 
			
		||||
	RPL_MYINFO                      = "004"
 | 
			
		||||
	RPL_ISUPPORT                    = "005"
 | 
			
		||||
	RPL_SNOMASKIS                   = "008"
 | 
			
		||||
	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_WHOISCERTFP                 = "276"
 | 
			
		||||
	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_CHANNELCREATED              = "329"
 | 
			
		||||
	RPL_WHOISACCOUNT                = "330"
 | 
			
		||||
	RPL_NOTOPIC                     = "331"
 | 
			
		||||
	RPL_TOPIC                       = "332"
 | 
			
		||||
	RPL_TOPICTIME                   = "333"
 | 
			
		||||
	RPL_WHOISBOT                    = "335"
 | 
			
		||||
	RPL_WHOISACTUALLY               = "338"
 | 
			
		||||
	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_UNKNOWNERROR                = "400"
 | 
			
		||||
	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_INPUTTOOLONG                = "417"
 | 
			
		||||
	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_REG_UNAVAILABLE             = "440"
 | 
			
		||||
	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_INVALIDUSERNAME             = "468"
 | 
			
		||||
	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"
 | 
			
		||||
	ERR_HELPNOTFOUND                = "524"
 | 
			
		||||
	ERR_CANNOTSENDRP                = "573"
 | 
			
		||||
	RPL_WHOISSECURE                 = "671"
 | 
			
		||||
	RPL_YOURLANGUAGESARE            = "687"
 | 
			
		||||
	RPL_WHOISLANGUAGE               = "690"
 | 
			
		||||
	ERR_CHANNAMEINUSE               = "692"
 | 
			
		||||
	ERR_CANNOTRENAME                = "693"
 | 
			
		||||
	RPL_HELPSTART                   = "704"
 | 
			
		||||
	RPL_HELPTXT                     = "705"
 | 
			
		||||
	RPL_ENDOFHELP                   = "706"
 | 
			
		||||
	ERR_NOPRIVS                     = "723"
 | 
			
		||||
	RPL_MONONLINE                   = "730"
 | 
			
		||||
	RPL_MONOFFLINE                  = "731"
 | 
			
		||||
	RPL_MONLIST                     = "732"
 | 
			
		||||
	RPL_ENDOFMONLIST                = "733"
 | 
			
		||||
	ERR_MONLISTFULL                 = "734"
 | 
			
		||||
	RPL_LOGGEDIN                    = "900"
 | 
			
		||||
	RPL_LOGGEDOUT                   = "901"
 | 
			
		||||
	ERR_NICKLOCKED                  = "902"
 | 
			
		||||
	RPL_SASLSUCCESS                 = "903"
 | 
			
		||||
	ERR_SASLFAIL                    = "904"
 | 
			
		||||
	ERR_SASLTOOLONG                 = "905"
 | 
			
		||||
	ERR_SASLABORTED                 = "906"
 | 
			
		||||
	ERR_SASLALREADY                 = "907"
 | 
			
		||||
	RPL_SASLMECHS                   = "908"
 | 
			
		||||
	RPL_REGISTRATION_SUCCESS        = "920"
 | 
			
		||||
	ERR_ACCOUNT_ALREADY_EXISTS      = "921"
 | 
			
		||||
	ERR_REG_UNSPECIFIED_ERROR       = "922"
 | 
			
		||||
	RPL_VERIFYSUCCESS               = "923"
 | 
			
		||||
	ERR_ACCOUNT_ALREADY_VERIFIED    = "924"
 | 
			
		||||
	ERR_ACCOUNT_INVALID_VERIFY_CODE = "925"
 | 
			
		||||
	RPL_REG_VERIFICATION_REQUIRED   = "927"
 | 
			
		||||
	ERR_REG_INVALID_CRED_TYPE       = "928"
 | 
			
		||||
	ERR_REG_INVALID_CALLBACK        = "929"
 | 
			
		||||
	ERR_TOOMANYLANGUAGES            = "981"
 | 
			
		||||
	ERR_NOLANGUAGE                  = "982"
 | 
			
		||||
	RPL_WELCOME                   = "001"
 | 
			
		||||
	RPL_YOURHOST                  = "002"
 | 
			
		||||
	RPL_CREATED                   = "003"
 | 
			
		||||
	RPL_MYINFO                    = "004"
 | 
			
		||||
	RPL_ISUPPORT                  = "005"
 | 
			
		||||
	RPL_SNOMASKIS                 = "008"
 | 
			
		||||
	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_WHOISCERTFP               = "276"
 | 
			
		||||
	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_CHANNELCREATED            = "329"
 | 
			
		||||
	RPL_WHOISACCOUNT              = "330"
 | 
			
		||||
	RPL_NOTOPIC                   = "331"
 | 
			
		||||
	RPL_TOPIC                     = "332"
 | 
			
		||||
	RPL_TOPICTIME                 = "333"
 | 
			
		||||
	RPL_WHOISBOT                  = "335"
 | 
			
		||||
	RPL_WHOISACTUALLY             = "338"
 | 
			
		||||
	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_UNKNOWNERROR              = "400"
 | 
			
		||||
	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_INPUTTOOLONG              = "417"
 | 
			
		||||
	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_REG_UNAVAILABLE           = "440"
 | 
			
		||||
	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_INVALIDUSERNAME           = "468"
 | 
			
		||||
	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"
 | 
			
		||||
	ERR_HELPNOTFOUND              = "524"
 | 
			
		||||
	ERR_CANNOTSENDRP              = "573"
 | 
			
		||||
	RPL_WHOISSECURE               = "671"
 | 
			
		||||
	RPL_YOURLANGUAGESARE          = "687"
 | 
			
		||||
	RPL_WHOISLANGUAGE             = "690"
 | 
			
		||||
	ERR_CHANNAMEINUSE             = "692"
 | 
			
		||||
	ERR_CANNOTRENAME              = "693"
 | 
			
		||||
	RPL_HELPSTART                 = "704"
 | 
			
		||||
	RPL_HELPTXT                   = "705"
 | 
			
		||||
	RPL_ENDOFHELP                 = "706"
 | 
			
		||||
	ERR_NOPRIVS                   = "723"
 | 
			
		||||
	RPL_MONONLINE                 = "730"
 | 
			
		||||
	RPL_MONOFFLINE                = "731"
 | 
			
		||||
	RPL_MONLIST                   = "732"
 | 
			
		||||
	RPL_ENDOFMONLIST              = "733"
 | 
			
		||||
	ERR_MONLISTFULL               = "734"
 | 
			
		||||
	RPL_LOGGEDIN                  = "900"
 | 
			
		||||
	RPL_LOGGEDOUT                 = "901"
 | 
			
		||||
	ERR_NICKLOCKED                = "902"
 | 
			
		||||
	RPL_SASLSUCCESS               = "903"
 | 
			
		||||
	ERR_SASLFAIL                  = "904"
 | 
			
		||||
	ERR_SASLTOOLONG               = "905"
 | 
			
		||||
	ERR_SASLABORTED               = "906"
 | 
			
		||||
	ERR_SASLALREADY               = "907"
 | 
			
		||||
	RPL_SASLMECHS                 = "908"
 | 
			
		||||
	RPL_REG_SUCCESS               = "920"
 | 
			
		||||
	RPL_VERIFY_SUCCESS            = "923"
 | 
			
		||||
	RPL_REG_VERIFICATION_REQUIRED = "927"
 | 
			
		||||
	ERR_TOOMANYLANGUAGES          = "981"
 | 
			
		||||
	ERR_NOLANGUAGE                = "982"
 | 
			
		||||
 | 
			
		||||
	// draft numerics
 | 
			
		||||
	// these haven't been assigned actual codes, so we use RPL_NONE's code (300),
 | 
			
		||||
 | 
			
		||||
@ -42,7 +42,7 @@ var (
 | 
			
		||||
 | 
			
		||||
	// SupportedCapabilities are the caps we advertise.
 | 
			
		||||
	// MaxLine, SASL and STS are set during server startup.
 | 
			
		||||
	SupportedCapabilities = caps.NewSet(caps.AccountTag, caps.AccountNotify, caps.AwayNotify, caps.Batch, caps.CapNotify, caps.ChgHost, caps.EchoMessage, caps.ExtendedJoin, caps.InviteNotify, caps.LabeledResponse, caps.Languages, caps.MessageTags, caps.MultiPrefix, caps.Rename, caps.Resume, caps.ServerTime, caps.SetName, caps.UserhostInNames)
 | 
			
		||||
	SupportedCapabilities = caps.NewSet(caps.Acc, caps.AccountTag, caps.AccountNotify, caps.AwayNotify, caps.Batch, caps.CapNotify, caps.ChgHost, caps.EchoMessage, caps.ExtendedJoin, caps.InviteNotify, caps.LabeledResponse, caps.Languages, caps.MessageTags, caps.MultiPrefix, caps.Rename, caps.Resume, caps.ServerTime, caps.SetName, caps.UserhostInNames)
 | 
			
		||||
 | 
			
		||||
	// CapValues are the actual values we advertise to v3.2 clients.
 | 
			
		||||
	// actual values are set during server startup.
 | 
			
		||||
@ -173,21 +173,6 @@ func (server *Server) setISupport() (err error) {
 | 
			
		||||
	isupport.Add("TOPICLEN", strconv.Itoa(config.Limits.TopicLen))
 | 
			
		||||
	isupport.Add("UTF8MAPPING", casemappingName)
 | 
			
		||||
 | 
			
		||||
	// account registration
 | 
			
		||||
	if config.Accounts.Registration.Enabled {
 | 
			
		||||
		// 'none' isn't shown in the REGCALLBACKS vars
 | 
			
		||||
		var enabledCallbacks []string
 | 
			
		||||
		for _, name := range server.config.Accounts.Registration.EnabledCallbacks {
 | 
			
		||||
			if name != "*" {
 | 
			
		||||
				enabledCallbacks = append(enabledCallbacks, name)
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		isupport.Add("ACCCOMMANDS", "CREATE,VERIFY")
 | 
			
		||||
		isupport.Add("REGCALLBACKS", strings.Join(enabledCallbacks, ","))
 | 
			
		||||
		isupport.Add("REGCREDTYPES", "passphrase,certfp")
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	err = isupport.RegenerateCachedReply()
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user