mirror of
https://github.com/ergochat/ergo.git
synced 2024-11-10 22:19:31 +01:00
commit
b12f2c8132
@ -683,9 +683,9 @@ oper-classes:
|
|||||||
|
|
||||||
# capability names
|
# capability names
|
||||||
capabilities:
|
capabilities:
|
||||||
- "oper:local_kill"
|
- "local_kill"
|
||||||
- "oper:local_ban"
|
- "local_ban"
|
||||||
- "oper:local_unban"
|
- "local_unban"
|
||||||
- "nofakelag"
|
- "nofakelag"
|
||||||
|
|
||||||
# ircd operators
|
# ircd operators
|
||||||
|
@ -1364,12 +1364,17 @@ func (channel *Channel) Kick(client *Client, target *Client, comment string, rb
|
|||||||
func (channel *Channel) Invite(invitee *Client, inviter *Client, rb *ResponseBuffer) {
|
func (channel *Channel) Invite(invitee *Client, inviter *Client, rb *ResponseBuffer) {
|
||||||
chname := channel.Name()
|
chname := channel.Name()
|
||||||
if channel.flags.HasMode(modes.InviteOnly) && !channel.ClientIsAtLeast(inviter, modes.ChannelOperator) {
|
if channel.flags.HasMode(modes.InviteOnly) && !channel.ClientIsAtLeast(inviter, modes.ChannelOperator) {
|
||||||
rb.Add(nil, inviter.server.name, ERR_CHANOPRIVSNEEDED, inviter.Nick(), channel.Name(), inviter.t("You're not a channel operator"))
|
rb.Add(nil, inviter.server.name, ERR_CHANOPRIVSNEEDED, inviter.Nick(), chname, inviter.t("You're not a channel operator"))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if !channel.hasClient(inviter) {
|
if !channel.hasClient(inviter) {
|
||||||
rb.Add(nil, inviter.server.name, ERR_NOTONCHANNEL, inviter.Nick(), channel.Name(), inviter.t("You're not on that channel"))
|
rb.Add(nil, inviter.server.name, ERR_NOTONCHANNEL, inviter.Nick(), chname, inviter.t("You're not on that channel"))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if channel.hasClient(invitee) {
|
||||||
|
rb.Add(nil, inviter.server.name, ERR_USERONCHANNEL, inviter.Nick(), invitee.Nick(), chname, inviter.t("User is already on that channel"))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -293,16 +293,17 @@ func csOpHandler(server *Server, client *Client, command string, params []string
|
|||||||
}
|
}
|
||||||
|
|
||||||
func csRegisterHandler(server *Server, client *Client, command string, params []string, rb *ResponseBuffer) {
|
func csRegisterHandler(server *Server, client *Client, command string, params []string, rb *ResponseBuffer) {
|
||||||
channelName := params[0]
|
if server.Config().Channels.Registration.OperatorOnly && !client.HasRoleCapabs("chanreg") {
|
||||||
|
csNotice(rb, client.t("Channel registration is restricted to server operators"))
|
||||||
channelKey, err := CasefoldChannel(channelName)
|
|
||||||
if err != nil {
|
|
||||||
csNotice(rb, client.t("Channel name is not valid"))
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
channelName := params[0]
|
||||||
channelInfo := server.channels.Get(channelKey)
|
channelInfo := server.channels.Get(channelName)
|
||||||
if channelInfo == nil || !channelInfo.ClientIsAtLeast(client, modes.ChannelOperator) {
|
if channelInfo == nil {
|
||||||
|
csNotice(rb, client.t("No such channel"))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if !channelInfo.ClientIsAtLeast(client, modes.ChannelOperator) {
|
||||||
csNotice(rb, client.t("You must be an oper on the channel to register it"))
|
csNotice(rb, client.t("You must be an oper on the channel to register it"))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -313,7 +314,7 @@ func csRegisterHandler(server *Server, client *Client, command string, params []
|
|||||||
}
|
}
|
||||||
|
|
||||||
// this provides the synchronization that allows exactly one registration of the channel:
|
// this provides the synchronization that allows exactly one registration of the channel:
|
||||||
err = server.channels.SetRegistered(channelKey, account)
|
err := server.channels.SetRegistered(channelName, account)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
csNotice(rb, err.Error())
|
csNotice(rb, err.Error())
|
||||||
return
|
return
|
||||||
|
@ -973,7 +973,7 @@ func (client *Client) HasRoleCapabs(capabs ...string) bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for _, capab := range capabs {
|
for _, capab := range capabs {
|
||||||
if !oper.Class.Capabilities[capab] {
|
if !oper.Class.Capabilities.Has(capab) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -160,7 +160,7 @@ func init() {
|
|||||||
handler: killHandler,
|
handler: killHandler,
|
||||||
minParams: 1,
|
minParams: 1,
|
||||||
oper: true,
|
oper: true,
|
||||||
capabs: []string{"oper:local_kill"}, //TODO(dan): when we have S2S, this will be checked in the command handler itself
|
capabs: []string{"local_kill"}, //TODO(dan): when we have S2S, this will be checked in the command handler itself
|
||||||
},
|
},
|
||||||
"KLINE": {
|
"KLINE": {
|
||||||
handler: klineHandler,
|
handler: klineHandler,
|
||||||
@ -289,7 +289,7 @@ func init() {
|
|||||||
handler: rehashHandler,
|
handler: rehashHandler,
|
||||||
minParams: 0,
|
minParams: 0,
|
||||||
oper: true,
|
oper: true,
|
||||||
capabs: []string{"oper:rehash"},
|
capabs: []string{"rehash"},
|
||||||
},
|
},
|
||||||
"TIME": {
|
"TIME": {
|
||||||
handler: timeHandler,
|
handler: timeHandler,
|
||||||
|
@ -385,12 +385,6 @@ func (cm *Casemapping) UnmarshalYAML(unmarshal func(interface{}) error) (err err
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// ChannelRegistrationConfig controls channel registration.
|
|
||||||
type ChannelRegistrationConfig struct {
|
|
||||||
Enabled bool
|
|
||||||
MaxChannelsPerAccount int `yaml:"max-channels-per-account"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// OperClassConfig defines a specific operator class.
|
// OperClassConfig defines a specific operator class.
|
||||||
type OperClassConfig struct {
|
type OperClassConfig struct {
|
||||||
Title string
|
Title string
|
||||||
@ -534,7 +528,11 @@ type Config struct {
|
|||||||
defaultModes modes.Modes
|
defaultModes modes.Modes
|
||||||
MaxChannelsPerClient int `yaml:"max-channels-per-client"`
|
MaxChannelsPerClient int `yaml:"max-channels-per-client"`
|
||||||
OpOnlyCreation bool `yaml:"operator-only-creation"`
|
OpOnlyCreation bool `yaml:"operator-only-creation"`
|
||||||
Registration ChannelRegistrationConfig
|
Registration struct {
|
||||||
|
Enabled bool
|
||||||
|
OperatorOnly bool `yaml:"operator-only"`
|
||||||
|
MaxChannelsPerAccount int `yaml:"max-channels-per-account"`
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
OperClasses map[string]*OperClassConfig `yaml:"oper-classes"`
|
OperClasses map[string]*OperClassConfig `yaml:"oper-classes"`
|
||||||
@ -584,12 +582,16 @@ type Config struct {
|
|||||||
// OperClass defines an assembled operator class.
|
// OperClass defines an assembled operator class.
|
||||||
type OperClass struct {
|
type OperClass struct {
|
||||||
Title string
|
Title string
|
||||||
WhoisLine string `yaml:"whois-line"`
|
WhoisLine string `yaml:"whois-line"`
|
||||||
Capabilities map[string]bool // map to make lookups much easier
|
Capabilities StringSet // map to make lookups much easier
|
||||||
}
|
}
|
||||||
|
|
||||||
// OperatorClasses returns a map of assembled operator classes from the given config.
|
// OperatorClasses returns a map of assembled operator classes from the given config.
|
||||||
func (conf *Config) OperatorClasses() (map[string]*OperClass, error) {
|
func (conf *Config) OperatorClasses() (map[string]*OperClass, error) {
|
||||||
|
fixupCapability := func(capab string) string {
|
||||||
|
return strings.TrimPrefix(capab, "oper:") // #868
|
||||||
|
}
|
||||||
|
|
||||||
ocs := make(map[string]*OperClass)
|
ocs := make(map[string]*OperClass)
|
||||||
|
|
||||||
// loop from no extends to most extended, breaking if we can't add any more
|
// loop from no extends to most extended, breaking if we can't add any more
|
||||||
@ -619,21 +621,21 @@ func (conf *Config) OperatorClasses() (map[string]*OperClass, error) {
|
|||||||
|
|
||||||
// create new operclass
|
// create new operclass
|
||||||
var oc OperClass
|
var oc OperClass
|
||||||
oc.Capabilities = make(map[string]bool)
|
oc.Capabilities = make(StringSet)
|
||||||
|
|
||||||
// get inhereted info from other operclasses
|
// get inhereted info from other operclasses
|
||||||
if len(info.Extends) > 0 {
|
if len(info.Extends) > 0 {
|
||||||
einfo := ocs[info.Extends]
|
einfo := ocs[info.Extends]
|
||||||
|
|
||||||
for capab := range einfo.Capabilities {
|
for capab := range einfo.Capabilities {
|
||||||
oc.Capabilities[capab] = true
|
oc.Capabilities.Add(fixupCapability(capab))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// add our own info
|
// add our own info
|
||||||
oc.Title = info.Title
|
oc.Title = info.Title
|
||||||
for _, capab := range info.Capabilities {
|
for _, capab := range info.Capabilities {
|
||||||
oc.Capabilities[capab] = true
|
oc.Capabilities.Add(fixupCapability(capab))
|
||||||
}
|
}
|
||||||
if len(info.WhoisLine) > 0 {
|
if len(info.WhoisLine) > 0 {
|
||||||
oc.WhoisLine = info.WhoisLine
|
oc.WhoisLine = info.WhoisLine
|
||||||
@ -1114,7 +1116,7 @@ func (config *Config) generateISupport() (err error) {
|
|||||||
isupport.Add("AWAYLEN", strconv.Itoa(config.Limits.AwayLen))
|
isupport.Add("AWAYLEN", strconv.Itoa(config.Limits.AwayLen))
|
||||||
isupport.Add("CASEMAPPING", "ascii")
|
isupport.Add("CASEMAPPING", "ascii")
|
||||||
isupport.Add("CHANLIMIT", fmt.Sprintf("%s:%d", chanTypes, config.Channels.MaxChannelsPerClient))
|
isupport.Add("CHANLIMIT", fmt.Sprintf("%s:%d", chanTypes, config.Channels.MaxChannelsPerClient))
|
||||||
isupport.Add("CHANMODES", strings.Join([]string{modes.Modes{modes.BanMask, modes.ExceptMask, modes.InviteMask}.String(), "", modes.Modes{modes.UserLimit, modes.Key}.String(), modes.Modes{modes.InviteOnly, modes.Moderated, modes.NoOutside, modes.OpOnlyTopic, modes.ChanRoleplaying, modes.Secret}.String()}, ","))
|
isupport.Add("CHANMODES", strings.Join([]string{modes.Modes{modes.BanMask, modes.ExceptMask, modes.InviteMask}.String(), "", modes.Modes{modes.UserLimit, modes.Key}.String(), modes.Modes{modes.InviteOnly, modes.Moderated, modes.NoOutside, modes.OpOnlyTopic, modes.ChanRoleplaying, modes.Secret, modes.NoCTCP, modes.RegisteredOnly}.String()}, ","))
|
||||||
if config.History.Enabled && config.History.ChathistoryMax > 0 {
|
if config.History.Enabled && config.History.ChathistoryMax > 0 {
|
||||||
isupport.Add("draft/CHATHISTORY", strconv.Itoa(config.History.ChathistoryMax))
|
isupport.Add("draft/CHATHISTORY", strconv.Itoa(config.History.ChathistoryMax))
|
||||||
}
|
}
|
||||||
|
@ -716,7 +716,7 @@ func debugHandler(server *Server, client *Client, msg ircmsg.IrcMessage, rb *Res
|
|||||||
rb.Notice(fmt.Sprintf("CPU profiling stopped"))
|
rb.Notice(fmt.Sprintf("CPU profiling stopped"))
|
||||||
|
|
||||||
case "CRASHSERVER":
|
case "CRASHSERVER":
|
||||||
if !client.HasRoleCapabs("oper:rehash") {
|
if !client.HasRoleCapabs("rehash") {
|
||||||
rb.Notice(client.t("You must have rehash permissions in order to execute DEBUG CRASHSERVER"))
|
rb.Notice(client.t("You must have rehash permissions in order to execute DEBUG CRASHSERVER"))
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
@ -770,7 +770,7 @@ func formatBanForListing(client *Client, key string, info IPBanInfo) string {
|
|||||||
func dlineHandler(server *Server, client *Client, msg ircmsg.IrcMessage, rb *ResponseBuffer) bool {
|
func dlineHandler(server *Server, client *Client, msg ircmsg.IrcMessage, rb *ResponseBuffer) bool {
|
||||||
// check oper permissions
|
// check oper permissions
|
||||||
oper := client.Oper()
|
oper := client.Oper()
|
||||||
if oper == nil || !oper.Class.Capabilities["oper:local_ban"] {
|
if oper == nil || !oper.Class.Capabilities.Has("local_ban") {
|
||||||
rb.Add(nil, server.name, ERR_NOPRIVS, client.nick, msg.Command, client.t("Insufficient oper privs"))
|
rb.Add(nil, server.name, ERR_NOPRIVS, client.nick, msg.Command, client.t("Insufficient oper privs"))
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
@ -1042,7 +1042,7 @@ func inviteHandler(server *Server, client *Client, msg ircmsg.IrcMessage, rb *Re
|
|||||||
|
|
||||||
channel := server.channels.Get(channelName)
|
channel := server.channels.Get(channelName)
|
||||||
if channel == nil {
|
if channel == nil {
|
||||||
rb.Add(nil, server.name, ERR_NOSUCHCHANNEL, client.nick, utils.SafeErrorParam(channelName), client.t("No such channel"))
|
rb.Add(nil, server.name, ERR_NOSUCHCHANNEL, client.Nick(), utils.SafeErrorParam(channelName), client.t("No such channel"))
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1229,7 +1229,7 @@ func klineHandler(server *Server, client *Client, msg ircmsg.IrcMessage, rb *Res
|
|||||||
details := client.Details()
|
details := client.Details()
|
||||||
// check oper permissions
|
// check oper permissions
|
||||||
oper := client.Oper()
|
oper := client.Oper()
|
||||||
if oper == nil || !oper.Class.Capabilities["oper:local_ban"] {
|
if oper == nil || !oper.Class.Capabilities.Has("local_ban") {
|
||||||
rb.Add(nil, server.name, ERR_NOPRIVS, details.nick, msg.Command, client.t("Insufficient oper privs"))
|
rb.Add(nil, server.name, ERR_NOPRIVS, details.nick, msg.Command, client.t("Insufficient oper privs"))
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
@ -2383,7 +2383,7 @@ func topicHandler(server *Server, client *Client, msg ircmsg.IrcMessage, rb *Res
|
|||||||
func unDLineHandler(server *Server, client *Client, msg ircmsg.IrcMessage, rb *ResponseBuffer) bool {
|
func unDLineHandler(server *Server, client *Client, msg ircmsg.IrcMessage, rb *ResponseBuffer) bool {
|
||||||
// check oper permissions
|
// check oper permissions
|
||||||
oper := client.Oper()
|
oper := client.Oper()
|
||||||
if oper == nil || !oper.Class.Capabilities["oper:local_unban"] {
|
if oper == nil || !oper.Class.Capabilities.Has("local_unban") {
|
||||||
rb.Add(nil, server.name, ERR_NOPRIVS, client.nick, msg.Command, client.t("Insufficient oper privs"))
|
rb.Add(nil, server.name, ERR_NOPRIVS, client.nick, msg.Command, client.t("Insufficient oper privs"))
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
@ -2417,7 +2417,7 @@ func unKLineHandler(server *Server, client *Client, msg ircmsg.IrcMessage, rb *R
|
|||||||
details := client.Details()
|
details := client.Details()
|
||||||
// check oper permissions
|
// check oper permissions
|
||||||
oper := client.Oper()
|
oper := client.Oper()
|
||||||
if oper == nil || !oper.Class.Capabilities["oper:local_unban"] {
|
if oper == nil || !oper.Class.Capabilities.Has("local_unban") {
|
||||||
rb.Add(nil, server.name, ERR_NOPRIVS, details.nick, msg.Command, client.t("Insufficient oper privs"))
|
rb.Add(nil, server.name, ERR_NOPRIVS, details.nick, msg.Command, client.t("Insufficient oper privs"))
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
@ -2558,13 +2558,7 @@ func webircHandler(server *Server, client *Client, msg ircmsg.IrcMessage, rb *Re
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
proxiedIP := msg.Params[3]
|
err, quitMsg := client.ApplyProxiedIP(rb.session, msg.Params[3], secure)
|
||||||
// see #211; websocket gateways will wrap ipv6 addresses in square brackets
|
|
||||||
// because IRC parameters can't start with :
|
|
||||||
if strings.HasPrefix(proxiedIP, "[") && strings.HasSuffix(proxiedIP, "]") {
|
|
||||||
proxiedIP = proxiedIP[1 : len(proxiedIP)-1]
|
|
||||||
}
|
|
||||||
err, quitMsg := client.ApplyProxiedIP(rb.session, proxiedIP, secure)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
client.Quit(quitMsg, rb.session)
|
client.Quit(quitMsg, rb.session)
|
||||||
return true
|
return true
|
||||||
|
@ -12,8 +12,11 @@ import (
|
|||||||
"github.com/oragono/oragono/irc/sno"
|
"github.com/oragono/oragono/irc/sno"
|
||||||
)
|
)
|
||||||
|
|
||||||
const hostservHelp = `HostServ lets you manage your vhost (i.e., the string displayed
|
const (
|
||||||
|
hostservHelp = `HostServ lets you manage your vhost (i.e., the string displayed
|
||||||
in place of your client's hostname/IP).`
|
in place of your client's hostname/IP).`
|
||||||
|
hsNickMask = "HostServ!HostServ@localhost"
|
||||||
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
errVHostBadCharacters = errors.New("Vhost contains prohibited characters")
|
errVHostBadCharacters = errors.New("Vhost contains prohibited characters")
|
||||||
@ -173,7 +176,7 @@ the offered vhosts, use /HOSTSERV OFFERLIST.`,
|
|||||||
|
|
||||||
// hsNotice sends the client a notice from HostServ
|
// hsNotice sends the client a notice from HostServ
|
||||||
func hsNotice(rb *ResponseBuffer, text string) {
|
func hsNotice(rb *ResponseBuffer, text string) {
|
||||||
rb.Add(nil, "HostServ!HostServ@localhost", "NOTICE", rb.target.Nick(), text)
|
rb.Add(nil, hsNickMask, "NOTICE", rb.target.Nick(), text)
|
||||||
}
|
}
|
||||||
|
|
||||||
// hsNotifyChannel notifies the designated channel of new vhost activity
|
// hsNotifyChannel notifies the designated channel of new vhost activity
|
||||||
@ -185,7 +188,7 @@ func hsNotifyChannel(server *Server, message string) {
|
|||||||
}
|
}
|
||||||
chname = channel.Name()
|
chname = channel.Name()
|
||||||
for _, client := range channel.Members() {
|
for _, client := range channel.Members() {
|
||||||
client.Send(nil, "HostServ", "PRIVMSG", chname, message)
|
client.Send(nil, hsNickMask, "PRIVMSG", chname, message)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -333,7 +336,7 @@ func hsApproveHandler(server *Server, client *Client, command string, params []s
|
|||||||
hsNotifyChannel(server, chanMsg)
|
hsNotifyChannel(server, chanMsg)
|
||||||
server.snomasks.Send(sno.LocalVhosts, chanMsg)
|
server.snomasks.Send(sno.LocalVhosts, chanMsg)
|
||||||
for _, client := range server.accounts.AccountToClients(user) {
|
for _, client := range server.accounts.AccountToClients(user) {
|
||||||
client.Notice(client.t("Your vhost request was approved by an administrator"))
|
client.Send(nil, hsNickMask, "NOTICE", client.Nick(), client.t("Your vhost request was approved by an administrator"))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -355,9 +358,9 @@ func hsRejectHandler(server *Server, client *Client, command string, params []st
|
|||||||
server.snomasks.Send(sno.LocalVhosts, chanMsg)
|
server.snomasks.Send(sno.LocalVhosts, chanMsg)
|
||||||
for _, client := range server.accounts.AccountToClients(user) {
|
for _, client := range server.accounts.AccountToClients(user) {
|
||||||
if reason == "" {
|
if reason == "" {
|
||||||
client.Notice("Your vhost request was rejected by an administrator")
|
client.Send(nil, hsNickMask, "NOTICE", client.Nick(), client.t("Your vhost request was rejected by an administrator"))
|
||||||
} else {
|
} else {
|
||||||
client.Notice(fmt.Sprintf(client.t("Your vhost request was rejected by an administrator. The reason given was: %s"), reason))
|
client.Send(nil, hsNickMask, "NOTICE", client.Nick(), fmt.Sprintf(client.t("Your vhost request was rejected by an administrator. The reason given was: %s"), reason))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -443,7 +443,7 @@ func (server *Server) Lusers(client *Client, rb *ResponseBuffer) {
|
|||||||
rb.Add(nil, server.name, RPL_LUSEROP, nick, strconv.Itoa(stats.Operators), client.t("IRC Operators online"))
|
rb.Add(nil, server.name, RPL_LUSEROP, nick, strconv.Itoa(stats.Operators), client.t("IRC Operators online"))
|
||||||
rb.Add(nil, server.name, RPL_LUSERUNKNOWN, nick, strconv.Itoa(stats.Unknown), client.t("unregistered connections"))
|
rb.Add(nil, server.name, RPL_LUSERUNKNOWN, nick, strconv.Itoa(stats.Unknown), client.t("unregistered connections"))
|
||||||
rb.Add(nil, server.name, RPL_LUSERCHANNELS, nick, strconv.Itoa(server.channels.Len()), client.t("channels formed"))
|
rb.Add(nil, server.name, RPL_LUSERCHANNELS, nick, strconv.Itoa(server.channels.Len()), client.t("channels formed"))
|
||||||
rb.Add(nil, server.name, RPL_LUSERME, nick, fmt.Sprintf(client.t("I have %[1]d clients and %[2]d servers"), stats.Total, 1))
|
rb.Add(nil, server.name, RPL_LUSERME, nick, fmt.Sprintf(client.t("I have %[1]d clients and %[2]d servers"), stats.Total, 0))
|
||||||
total := strconv.Itoa(stats.Total)
|
total := strconv.Itoa(stats.Total)
|
||||||
max := strconv.Itoa(stats.Max)
|
max := strconv.Itoa(stats.Max)
|
||||||
rb.Add(nil, server.name, RPL_LOCALUSERS, nick, total, max, fmt.Sprintf(client.t("Current local users %[1]s, max %[2]s"), total, max))
|
rb.Add(nil, server.name, RPL_LOCALUSERS, nick, total, max, fmt.Sprintf(client.t("Current local users %[1]s, max %[2]s"), total, max))
|
||||||
|
20
oragono.yaml
20
oragono.yaml
@ -472,6 +472,10 @@ channels:
|
|||||||
# can users register new channels?
|
# can users register new channels?
|
||||||
enabled: true
|
enabled: true
|
||||||
|
|
||||||
|
# restrict new channel registrations to operators only?
|
||||||
|
# (operators can then transfer channels to regular users using /CS TRANSFER)
|
||||||
|
operator-only: false
|
||||||
|
|
||||||
# how many channels can each account register?
|
# how many channels can each account register?
|
||||||
max-channels-per-account: 15
|
max-channels-per-account: 15
|
||||||
|
|
||||||
@ -484,9 +488,9 @@ oper-classes:
|
|||||||
|
|
||||||
# capability names
|
# capability names
|
||||||
capabilities:
|
capabilities:
|
||||||
- "oper:local_kill"
|
- "local_kill"
|
||||||
- "oper:local_ban"
|
- "local_ban"
|
||||||
- "oper:local_unban"
|
- "local_unban"
|
||||||
- "nofakelag"
|
- "nofakelag"
|
||||||
|
|
||||||
# network operator
|
# network operator
|
||||||
@ -499,9 +503,9 @@ oper-classes:
|
|||||||
|
|
||||||
# capability names
|
# capability names
|
||||||
capabilities:
|
capabilities:
|
||||||
- "oper:remote_kill"
|
- "remote_kill"
|
||||||
- "oper:remote_ban"
|
- "remote_ban"
|
||||||
- "oper:remote_unban"
|
- "remote_unban"
|
||||||
|
|
||||||
# server admin
|
# server admin
|
||||||
"server-admin":
|
"server-admin":
|
||||||
@ -513,8 +517,8 @@ oper-classes:
|
|||||||
|
|
||||||
# capability names
|
# capability names
|
||||||
capabilities:
|
capabilities:
|
||||||
- "oper:rehash"
|
- "rehash"
|
||||||
- "oper:die"
|
- "die"
|
||||||
- "accreg"
|
- "accreg"
|
||||||
- "sajoin"
|
- "sajoin"
|
||||||
- "samode"
|
- "samode"
|
||||||
|
Loading…
Reference in New Issue
Block a user