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"
"time"
2017-06-15 18:14:19 +02:00
"github.com/goshuirc/irc-go/ircfmt"
"github.com/goshuirc/irc-go/ircmsg"
2017-06-14 20:00:53 +02:00
"github.com/oragono/oragono/irc/sno"
2017-03-11 13:01:40 +01:00
"github.com/tidwall/buntdb"
)
// csHandler handles the /CS and /CHANSERV commands
func csHandler ( server * Server , client * Client , msg ircmsg . IrcMessage ) bool {
server . chanservReceivePrivmsg ( client , strings . Join ( msg . Params , " " ) )
return false
}
func ( server * Server ) chanservReceiveNotice ( client * Client , message string ) {
// do nothing
}
// ChanServNotice sends the client a notice from ChanServ.
func ( client * Client ) ChanServNotice ( text string ) {
client . Send ( nil , fmt . Sprintf ( "ChanServ!services@%s" , client . server . name ) , "NOTICE" , client . nick , text )
}
func ( server * Server ) chanservReceivePrivmsg ( client * Client , message string ) {
var params [ ] string
for _ , p := range strings . Split ( message , " " ) {
if len ( p ) > 0 {
params = append ( params , p )
}
}
if len ( params ) < 1 {
client . ChanServNotice ( "You need to run a command" )
//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 {
client . ChanServNotice ( "Syntax: REGISTER <channel>" )
return
}
2017-03-24 03:52:38 +01:00
if ! server . channelRegistrationEnabled {
client . ChanServNotice ( "Channel registration is not enabled" )
return
}
2017-03-11 13:01:40 +01:00
server . registeredChannelsMutex . Lock ( )
defer server . registeredChannelsMutex . Unlock ( )
channelName := params [ 1 ]
channelKey , err := CasefoldChannel ( channelName )
if err != nil {
client . ChanServNotice ( "Channel name is not valid" )
return
}
channelInfo := server . channels . Get ( channelKey )
if channelInfo == nil {
client . ChanServNotice ( "You must be an oper on the channel to register it" )
return
}
if ! channelInfo . ClientIsAtLeast ( client , ChannelOperator ) {
client . ChanServNotice ( "You must be an oper on the channel to register it" )
return
}
server . store . Update ( func ( tx * buntdb . Tx ) error {
currentChan := server . loadChannelNoMutex ( tx , channelKey )
if currentChan != nil {
client . ChanServNotice ( "Channel is already registered" )
return nil
}
account := client . account
2017-03-28 09:32:03 +02:00
if account == & NoAccount {
2017-03-11 13:01:40 +01:00
client . ChanServNotice ( "You must be logged in to register a channel" )
return nil
}
chanRegInfo := RegisteredChannel {
Name : channelName ,
RegisteredAt : time . Now ( ) ,
Founder : account . Name ,
Topic : channelInfo . topic ,
TopicSetBy : channelInfo . topicSetBy ,
TopicSetTime : channelInfo . topicSetTime ,
}
server . saveChannelNoMutex ( tx , channelKey , chanRegInfo )
client . ChanServNotice ( fmt . Sprintf ( "Channel %s successfully registered" , channelName ) )
server . logger . Info ( "chanserv" , fmt . Sprintf ( "Client %s registered channel %s" , client . nick , channelName ) )
2017-05-28 20:43:09 +02:00
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-03-11 13:01:40 +01:00
channelInfo . membersMutex . Lock ( )
defer channelInfo . membersMutex . Unlock ( )
// give them founder privs
change := channelInfo . applyModeMemberNoMutex ( client , ChannelFounder , Add , client . nickCasefolded )
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 ... )
}
}
return nil
} )
} else {
client . ChanServNotice ( "Sorry, I don't know that command" )
}
}