2017-03-11 13:01:40 +01:00
// Copyright (c) 2017 Daniel Oaks <daniel@danieloaks.net>
// released under the MIT license
package irc
import (
"fmt"
"strings"
2017-06-15 18:14:19 +02:00
"github.com/goshuirc/irc-go/ircfmt"
2018-02-03 11:21:32 +01:00
"github.com/oragono/oragono/irc/modes"
2017-06-14 20:00:53 +02:00
"github.com/oragono/oragono/irc/sno"
2017-03-11 13:01:40 +01:00
)
// ChanServNotice sends the client a notice from ChanServ.
2018-02-05 15:21:08 +01:00
func ( rb * ResponseBuffer ) ChanServNotice ( text string ) {
rb . Add ( nil , fmt . Sprintf ( "ChanServ!services@%s" , rb . target . server . name ) , "NOTICE" , rb . target . nick , text )
2017-03-11 13:01:40 +01:00
}
2018-02-03 12:15:07 +01:00
// chanservReceiveNotice handles NOTICEs that ChanServ receives.
2018-02-05 15:21:08 +01:00
func ( server * Server ) chanservNoticeHandler ( client * Client , message string , rb * ResponseBuffer ) {
2018-02-03 12:15:07 +01:00
// do nothing
}
// chanservReceiveNotice handles NOTICEs that ChanServ receives.
2018-02-05 15:21:08 +01:00
func ( server * Server ) chanservPrivmsgHandler ( client * Client , message string , rb * ResponseBuffer ) {
2017-03-11 13:01:40 +01:00
var params [ ] string
for _ , p := range strings . Split ( message , " " ) {
if len ( p ) > 0 {
params = append ( params , p )
}
}
if len ( params ) < 1 {
2018-02-05 15:21:08 +01:00
rb . ChanServNotice ( client . t ( "You need to run a command" ) )
2017-03-11 13:01:40 +01:00
//TODO(dan): dump CS help here
return
}
command := strings . ToLower ( params [ 0 ] )
server . logger . Debug ( "chanserv" , fmt . Sprintf ( "Client %s ran command %s" , client . nick , command ) )
if command == "register" {
if len ( params ) < 2 {
2018-02-05 15:21:08 +01:00
rb . ChanServNotice ( client . t ( "Syntax: REGISTER <channel>" ) )
2017-03-11 13:01:40 +01:00
return
}
2018-02-05 15:21:08 +01:00
server . chanservRegisterHandler ( client , params [ 1 ] , rb )
2018-02-03 12:38:28 +01:00
} else {
2018-02-05 15:21:08 +01:00
rb . ChanServNotice ( client . t ( "Sorry, I don't know that command" ) )
2018-02-03 12:38:28 +01:00
}
}
2017-03-24 03:52:38 +01:00
2018-02-03 12:38:28 +01:00
// chanservRegisterHandler handles the ChanServ REGISTER subcommand.
2018-02-05 15:21:08 +01:00
func ( server * Server ) chanservRegisterHandler ( client * Client , channelName string , rb * ResponseBuffer ) {
2018-02-03 12:38:28 +01:00
if ! server . channelRegistrationEnabled {
2018-02-05 15:21:08 +01:00
rb . ChanServNotice ( client . t ( "Channel registration is not enabled" ) )
2018-02-03 12:38:28 +01:00
return
}
2017-03-11 13:01:40 +01:00
2018-02-03 12:38:28 +01:00
channelKey , err := CasefoldChannel ( channelName )
if err != nil {
2018-02-05 15:21:08 +01:00
rb . ChanServNotice ( client . t ( "Channel name is not valid" ) )
2018-02-03 12:38:28 +01:00
return
}
2017-03-11 13:01:40 +01:00
2018-02-03 12:38:28 +01:00
channelInfo := server . channels . Get ( channelKey )
if channelInfo == nil || ! channelInfo . ClientIsAtLeast ( client , modes . ChannelOperator ) {
2018-02-05 15:21:08 +01:00
rb . ChanServNotice ( client . t ( "You must be an oper on the channel to register it" ) )
2018-02-03 12:38:28 +01:00
return
}
2017-03-11 13:01:40 +01:00
2018-02-11 11:30:40 +01:00
if client . Account ( ) == "" {
2018-02-05 15:21:08 +01:00
rb . ChanServNotice ( client . t ( "You must be logged in to register a channel" ) )
2018-02-03 12:38:28 +01:00
return
}
// this provides the synchronization that allows exactly one registration of the channel:
2018-02-11 11:30:40 +01:00
err = channelInfo . SetRegistered ( client . Account ( ) )
2018-02-03 12:38:28 +01:00
if err != nil {
2018-02-05 15:21:08 +01:00
rb . ChanServNotice ( err . Error ( ) )
2018-02-03 12:38:28 +01:00
return
}
2017-03-11 13:01:40 +01:00
2018-02-03 12:38:28 +01:00
// registration was successful: make the database reflect it
go server . channelRegistry . StoreChannel ( channelInfo , true )
2017-03-11 13:01:40 +01:00
2018-02-05 15:21:08 +01:00
rb . ChanServNotice ( fmt . Sprintf ( client . t ( "Channel %s successfully registered" ) , channelName ) )
2017-03-11 13:01:40 +01:00
2018-02-03 12:38:28 +01:00
server . logger . Info ( "chanserv" , fmt . Sprintf ( "Client %s registered channel %s" , client . nick , channelName ) )
server . snomasks . Send ( sno . LocalChannels , fmt . Sprintf ( ircfmt . Unescape ( "Channel registered $c[grey][$r%s$c[grey]] by $c[grey][$r%s$c[grey]]" ) , channelName , client . nickMaskString ) )
2017-11-09 04:19:50 +01:00
2018-02-03 12:38:28 +01:00
// give them founder privs
2018-02-05 15:21:08 +01:00
change := channelInfo . applyModeMemberNoMutex ( client , modes . ChannelFounder , modes . Add , client . NickCasefolded ( ) , rb )
2018-02-03 12:38:28 +01:00
if change != nil {
//TODO(dan): we should change the name of String and make it return a slice here
//TODO(dan): unify this code with code in modes.go
args := append ( [ ] string { channelName } , strings . Split ( change . String ( ) , " " ) ... )
for _ , member := range channelInfo . Members ( ) {
member . Send ( nil , fmt . Sprintf ( "ChanServ!services@%s" , client . server . name ) , "MODE" , args ... )
2017-11-09 04:19:50 +01:00
}
2017-03-11 13:01:40 +01:00
}
}