initial vhosts implementation, #183

This commit is contained in:
Shivaram Lingamneni 2018-04-19 02:48:19 -04:00
parent 40d6cd02da
commit 5e62cc4ebc
15 changed files with 1013 additions and 365 deletions

View file

@ -5,7 +5,6 @@ package irc
import (
"fmt"
"sort"
"strings"
"github.com/goshuirc/irc-go/ircfmt"
@ -22,29 +21,16 @@ To see in-depth help for a specific ChanServ command, try:
Here are the commands you can use:
%s`
type csCommand struct {
capabs []string // oper capabs the given user has to have to access this command
handler func(server *Server, client *Client, command, params string, rb *ResponseBuffer)
help string
helpShort string
oper bool // true if the user has to be an oper to use this command
}
var (
chanservCommands = map[string]*csCommand{
"help": {
help: `Syntax: $bHELP [command]$b
HELP returns information on the given command.`,
helpShort: `$bHELP$b shows in-depth information about commands.`,
},
chanservCommands = map[string]*serviceCommand{
"op": {
handler: csOpHandler,
help: `Syntax: $bOP #channel [nickname]$b
OP makes the given nickname, or yourself, a channel admin. You can only use
this command if you're the founder of the channel.`,
helpShort: `$bOP$b makes the given user (or yourself) a channel admin.`,
helpShort: `$bOP$b makes the given user (or yourself) a channel admin.`,
authRequired: true,
},
"register": {
handler: csRegisterHandler,
@ -53,7 +39,8 @@ this command if you're the founder of the channel.`,
REGISTER lets you own the given channel. If you rejoin this channel, you'll be
given admin privs on it. Modes set on the channel and the topic will also be
remembered.`,
helpShort: `$bREGISTER$b lets you own a given channel.`,
helpShort: `$bREGISTER$b lets you own a given channel.`,
authRequired: true,
},
}
)
@ -63,91 +50,6 @@ func csNotice(rb *ResponseBuffer, text string) {
rb.Add(nil, "ChanServ", "NOTICE", rb.target.Nick(), text)
}
// chanservReceiveNotice handles NOTICEs that ChanServ receives.
func (server *Server) chanservNoticeHandler(client *Client, message string, rb *ResponseBuffer) {
// do nothing
}
// chanservReceiveNotice handles NOTICEs that ChanServ receives.
func (server *Server) chanservPrivmsgHandler(client *Client, message string, rb *ResponseBuffer) {
commandName, params := utils.ExtractParam(message)
commandName = strings.ToLower(commandName)
commandInfo := chanservCommands[commandName]
if commandInfo == nil {
csNotice(rb, client.t("Unknown command. To see available commands, run /CS HELP"))
return
}
if commandInfo.oper && !client.HasMode(modes.Operator) {
csNotice(rb, client.t("Command restricted"))
return
}
if 0 < len(commandInfo.capabs) && !client.HasRoleCapabs(commandInfo.capabs...) {
csNotice(rb, client.t("Command restricted"))
return
}
// custom help handling here to prevent recursive init loop
if commandName == "help" {
csHelpHandler(server, client, commandName, params, rb)
return
}
if commandInfo.handler == nil {
csNotice(rb, client.t("Command error. Please report this to the developers"))
return
}
server.logger.Debug("chanserv", fmt.Sprintf("Client %s ran command %s", client.Nick(), commandName))
commandInfo.handler(server, client, commandName, params, rb)
}
func csHelpHandler(server *Server, client *Client, command, params string, rb *ResponseBuffer) {
csNotice(rb, ircfmt.Unescape(client.t("*** $bChanServ HELP$b ***")))
if params == "" {
// show general help
var shownHelpLines sort.StringSlice
for _, commandInfo := range chanservCommands {
// skip commands user can't access
if commandInfo.oper && !client.HasMode(modes.Operator) {
continue
}
if 0 < len(commandInfo.capabs) && !client.HasRoleCapabs(commandInfo.capabs...) {
continue
}
shownHelpLines = append(shownHelpLines, " "+client.t(commandInfo.helpShort))
}
// sort help lines
sort.Sort(shownHelpLines)
// assemble help text
assembledHelpLines := strings.Join(shownHelpLines, "\n")
fullHelp := ircfmt.Unescape(fmt.Sprintf(client.t(chanservHelp), assembledHelpLines))
// push out help text
for _, line := range strings.Split(fullHelp, "\n") {
csNotice(rb, line)
}
} else {
commandInfo := chanservCommands[strings.ToLower(strings.TrimSpace(params))]
if commandInfo == nil {
csNotice(rb, client.t("Unknown command. To see available commands, run /CS HELP"))
} else {
for _, line := range strings.Split(ircfmt.Unescape(client.t(commandInfo.help)), "\n") {
csNotice(rb, line)
}
}
}
csNotice(rb, ircfmt.Unescape(client.t("*** $bEnd of ChanServ HELP$b ***")))
}
func csOpHandler(server *Server, client *Client, command, params string, rb *ResponseBuffer) {
channelName, clientToOp := utils.ExtractParam(params)
@ -171,13 +73,7 @@ func csOpHandler(server *Server, client *Client, command, params string, rb *Res
}
clientAccount := client.Account()
if clientAccount == "" {
csNotice(rb, client.t("You must be logged in to op on a channel"))
return
}
if clientAccount != channelInfo.Founder() {
if clientAccount == "" || clientAccount != channelInfo.Founder() {
csNotice(rb, client.t("You must be the channel founder to op"))
return
}
@ -239,11 +135,6 @@ func csRegisterHandler(server *Server, client *Client, command, params string, r
return
}
if client.Account() == "" {
csNotice(rb, client.t("You must be logged in to register a channel"))
return
}
// this provides the synchronization that allows exactly one registration of the channel:
err = channelInfo.SetRegistered(client.Account())
if err != nil {