mirror of
https://github.com/ergochat/ergo.git
synced 2024-11-25 13:29:27 +01:00
commit
847922e53d
@ -346,6 +346,9 @@ func (channel *Channel) IsEmpty() bool {
|
|||||||
|
|
||||||
// Join joins the given client to this channel (if they can be joined).
|
// Join joins the given client to this channel (if they can be joined).
|
||||||
func (channel *Channel) Join(client *Client, key string, isSajoin bool, rb *ResponseBuffer) {
|
func (channel *Channel) Join(client *Client, key string, isSajoin bool, rb *ResponseBuffer) {
|
||||||
|
account := client.Account()
|
||||||
|
nickMaskCasefolded := client.NickMaskCasefolded()
|
||||||
|
|
||||||
channel.stateMutex.RLock()
|
channel.stateMutex.RLock()
|
||||||
chname := channel.name
|
chname := channel.name
|
||||||
chcfname := channel.nameCasefolded
|
chcfname := channel.nameCasefolded
|
||||||
@ -354,6 +357,7 @@ func (channel *Channel) Join(client *Client, key string, isSajoin bool, rb *Resp
|
|||||||
limit := channel.userLimit
|
limit := channel.userLimit
|
||||||
chcount := len(channel.members)
|
chcount := len(channel.members)
|
||||||
_, alreadyJoined := channel.members[client]
|
_, alreadyJoined := channel.members[client]
|
||||||
|
persistentMode := channel.accountToUMode[account]
|
||||||
channel.stateMutex.RUnlock()
|
channel.stateMutex.RUnlock()
|
||||||
|
|
||||||
if alreadyJoined {
|
if alreadyJoined {
|
||||||
@ -361,9 +365,9 @@ func (channel *Channel) Join(client *Client, key string, isSajoin bool, rb *Resp
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
account := client.Account()
|
// the founder can always join (even if they disabled auto +q on join);
|
||||||
nickMaskCasefolded := client.NickMaskCasefolded()
|
// anyone who automatically receives halfop or higher can always join
|
||||||
hasPrivs := isSajoin || (founder != "" && founder == account)
|
hasPrivs := isSajoin || (founder != "" && founder == account) || (persistentMode != 0 && persistentMode != modes.Voice)
|
||||||
|
|
||||||
if !hasPrivs && limit != 0 && chcount >= limit {
|
if !hasPrivs && limit != 0 && chcount >= limit {
|
||||||
rb.Add(nil, client.server.name, ERR_CHANNELISFULL, chname, fmt.Sprintf(client.t("Cannot join channel (+%s)"), "l"))
|
rb.Add(nil, client.server.name, ERR_CHANNELISFULL, chname, fmt.Sprintf(client.t("Cannot join channel (+%s)"), "l"))
|
||||||
@ -404,7 +408,7 @@ func (channel *Channel) Join(client *Client, key string, isSajoin bool, rb *Resp
|
|||||||
if newChannel {
|
if newChannel {
|
||||||
givenMode = modes.ChannelOperator
|
givenMode = modes.ChannelOperator
|
||||||
} else {
|
} else {
|
||||||
givenMode = channel.accountToUMode[account]
|
givenMode = persistentMode
|
||||||
}
|
}
|
||||||
if givenMode != 0 {
|
if givenMode != 0 {
|
||||||
channel.members[client].SetMode(givenMode, true)
|
channel.members[client].SetMode(givenMode, true)
|
||||||
@ -803,6 +807,8 @@ func (channel *Channel) sendSplitMessage(msgid, cmd string, histType history.Ite
|
|||||||
nickmask := client.NickMaskString()
|
nickmask := client.NickMaskString()
|
||||||
account := client.AccountName()
|
account := client.AccountName()
|
||||||
|
|
||||||
|
now := time.Now().UTC()
|
||||||
|
|
||||||
for _, member := range channel.Members() {
|
for _, member := range channel.Members() {
|
||||||
if minPrefix != nil && !channel.ClientIsAtLeast(member, minPrefixMode) {
|
if minPrefix != nil && !channel.ClientIsAtLeast(member, minPrefixMode) {
|
||||||
// STATUSMSG
|
// STATUSMSG
|
||||||
@ -817,11 +823,10 @@ func (channel *Channel) sendSplitMessage(msgid, cmd string, histType history.Ite
|
|||||||
tagsToUse = clientOnlyTags
|
tagsToUse = clientOnlyTags
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO(slingamn) evaluate an optimization where we reuse `nickmask` and `account`
|
|
||||||
if message == nil {
|
if message == nil {
|
||||||
member.SendFromClient(msgid, client, tagsToUse, cmd, channel.name)
|
member.sendFromClientInternal(false, now, msgid, nickmask, account, tagsToUse, cmd, channel.name)
|
||||||
} else {
|
} else {
|
||||||
member.SendSplitMsgFromClient(msgid, client, tagsToUse, cmd, channel.name, *message)
|
member.sendSplitMsgFromClientInternal(false, now, msgid, nickmask, account, tagsToUse, cmd, channel.name, *message)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -831,6 +836,7 @@ func (channel *Channel) sendSplitMessage(msgid, cmd string, histType history.Ite
|
|||||||
Message: *message,
|
Message: *message,
|
||||||
Nick: nickmask,
|
Nick: nickmask,
|
||||||
AccountName: account,
|
AccountName: account,
|
||||||
|
Time: now,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -28,7 +28,7 @@ import (
|
|||||||
const (
|
const (
|
||||||
// IdentTimeoutSeconds is how many seconds before our ident (username) check times out.
|
// IdentTimeoutSeconds is how many seconds before our ident (username) check times out.
|
||||||
IdentTimeoutSeconds = 1.5
|
IdentTimeoutSeconds = 1.5
|
||||||
IRCv3TimestampFormat = "2006-01-02T15:04:05.999Z"
|
IRCv3TimestampFormat = "2006-01-02T15:04:05.000Z"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@ -332,12 +332,6 @@ func (client *Client) Active() {
|
|||||||
client.atime = time.Now()
|
client.atime = time.Now()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Touch marks the client as alive (as it it has a connection to us and we
|
|
||||||
// can receive messages from it).
|
|
||||||
func (client *Client) Touch() {
|
|
||||||
client.idletimer.Touch()
|
|
||||||
}
|
|
||||||
|
|
||||||
// Ping sends the client a PING message.
|
// Ping sends the client a PING message.
|
||||||
func (client *Client) Ping() {
|
func (client *Client) Ping() {
|
||||||
client.Send(nil, "", "PING", client.nick)
|
client.Send(nil, "", "PING", client.nick)
|
||||||
|
@ -189,7 +189,7 @@ func (clients *ClientManager) FindAll(userhost string) (set ClientSet) {
|
|||||||
clients.RLock()
|
clients.RLock()
|
||||||
defer clients.RUnlock()
|
defer clients.RUnlock()
|
||||||
for _, client := range clients.byNick {
|
for _, client := range clients.byNick {
|
||||||
if matcher.Match(client.nickMaskCasefolded) {
|
if matcher.Match(client.NickMaskCasefolded()) {
|
||||||
set.Add(client)
|
set.Add(client)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -209,7 +209,7 @@ func (clients *ClientManager) Find(userhost string) *Client {
|
|||||||
clients.RLock()
|
clients.RLock()
|
||||||
defer clients.RUnlock()
|
defer clients.RUnlock()
|
||||||
for _, client := range clients.byNick {
|
for _, client := range clients.byNick {
|
||||||
if matcher.Match(client.nickMaskCasefolded) {
|
if matcher.Match(client.NickMaskCasefolded()) {
|
||||||
matchedClient = client
|
matchedClient = client
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
@ -12,13 +12,12 @@ import (
|
|||||||
|
|
||||||
// Command represents a command accepted from a client.
|
// Command represents a command accepted from a client.
|
||||||
type Command struct {
|
type Command struct {
|
||||||
handler func(server *Server, client *Client, msg ircmsg.IrcMessage, rb *ResponseBuffer) bool
|
handler func(server *Server, client *Client, msg ircmsg.IrcMessage, rb *ResponseBuffer) bool
|
||||||
oper bool
|
oper bool
|
||||||
usablePreReg bool
|
usablePreReg bool
|
||||||
leaveClientActive bool // if true, leaves the client active time alone. reversed because we can't default a struct element to True
|
leaveClientIdle bool // if true, leaves the client active time alone
|
||||||
leaveClientIdle bool
|
minParams int
|
||||||
minParams int
|
capabs []string
|
||||||
capabs []string
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Run runs this command with the given client/message.
|
// Run runs this command with the given client/message.
|
||||||
@ -54,11 +53,10 @@ func (cmd *Command) Run(server *Server, client *Client, msg ircmsg.IrcMessage) b
|
|||||||
server.tryRegister(client)
|
server.tryRegister(client)
|
||||||
}
|
}
|
||||||
|
|
||||||
if !cmd.leaveClientIdle {
|
// most servers do this only for PING/PONG, but we'll do it for any command:
|
||||||
client.Touch()
|
client.idletimer.Touch()
|
||||||
}
|
|
||||||
|
|
||||||
if !cmd.leaveClientActive {
|
if !cmd.leaveClientIdle {
|
||||||
client.Active()
|
client.Active()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -118,8 +116,9 @@ func init() {
|
|||||||
minParams: 2,
|
minParams: 2,
|
||||||
},
|
},
|
||||||
"ISON": {
|
"ISON": {
|
||||||
handler: isonHandler,
|
handler: isonHandler,
|
||||||
minParams: 1,
|
minParams: 1,
|
||||||
|
leaveClientIdle: true,
|
||||||
},
|
},
|
||||||
"JOIN": {
|
"JOIN": {
|
||||||
handler: joinHandler,
|
handler: joinHandler,
|
||||||
@ -200,16 +199,16 @@ func init() {
|
|||||||
minParams: 1,
|
minParams: 1,
|
||||||
},
|
},
|
||||||
"PING": {
|
"PING": {
|
||||||
handler: pingHandler,
|
handler: pingHandler,
|
||||||
usablePreReg: true,
|
usablePreReg: true,
|
||||||
minParams: 1,
|
minParams: 1,
|
||||||
leaveClientActive: true,
|
leaveClientIdle: true,
|
||||||
},
|
},
|
||||||
"PONG": {
|
"PONG": {
|
||||||
handler: pongHandler,
|
handler: pongHandler,
|
||||||
usablePreReg: true,
|
usablePreReg: true,
|
||||||
minParams: 1,
|
minParams: 1,
|
||||||
leaveClientActive: true,
|
leaveClientIdle: true,
|
||||||
},
|
},
|
||||||
"PRIVMSG": {
|
"PRIVMSG": {
|
||||||
handler: privmsgHandler,
|
handler: privmsgHandler,
|
||||||
|
@ -2478,16 +2478,25 @@ func whoisHandler(server *Server, client *Client, msg ircmsg.IrcMessage, rb *Res
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
handleService := func(nick string) bool {
|
||||||
|
cfnick, _ := CasefoldName(nick)
|
||||||
|
service, ok := OragonoServices[cfnick]
|
||||||
|
if !ok {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
clientNick := client.Nick()
|
||||||
|
rb.Add(nil, client.server.name, RPL_WHOISUSER, clientNick, service.Name, service.Name, "localhost", "*", fmt.Sprintf(client.t("Network service, for more info /msg %s HELP"), service.Name))
|
||||||
|
// hehe
|
||||||
|
if client.HasMode(modes.TLS) {
|
||||||
|
rb.Add(nil, client.server.name, RPL_WHOISSECURE, clientNick, service.Name, client.t("is using a secure connection"))
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
if client.HasMode(modes.Operator) {
|
if client.HasMode(modes.Operator) {
|
||||||
masks := strings.Split(masksString, ",")
|
for _, mask := range strings.Split(masksString, ",") {
|
||||||
for _, mask := range masks {
|
matches := server.clients.FindAll(mask)
|
||||||
casefoldedMask, err := Casefold(mask)
|
if len(matches) == 0 && !handleService(mask) {
|
||||||
if err != nil {
|
|
||||||
rb.Add(nil, client.server.name, ERR_NOSUCHNICK, client.nick, mask, client.t("No such nick"))
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
matches := server.clients.FindAll(casefoldedMask)
|
|
||||||
if len(matches) == 0 {
|
|
||||||
rb.Add(nil, client.server.name, ERR_NOSUCHNICK, client.nick, mask, client.t("No such nick"))
|
rb.Add(nil, client.server.name, ERR_NOSUCHNICK, client.nick, mask, client.t("No such nick"))
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
@ -2496,15 +2505,15 @@ func whoisHandler(server *Server, client *Client, msg ircmsg.IrcMessage, rb *Res
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// only get the first request
|
// only get the first request; also require a nick, not a mask
|
||||||
casefoldedMask, err := Casefold(strings.Split(masksString, ",")[0])
|
nick := strings.Split(masksString, ",")[0]
|
||||||
mclient := server.clients.Get(casefoldedMask)
|
mclient := server.clients.Get(nick)
|
||||||
if err != nil || mclient == nil {
|
if mclient != nil {
|
||||||
rb.Add(nil, client.server.name, ERR_NOSUCHNICK, client.nick, masksString, client.t("No such nick"))
|
|
||||||
// fall through, ENDOFWHOIS is always sent
|
|
||||||
} else {
|
|
||||||
client.getWhoisOf(mclient, rb)
|
client.getWhoisOf(mclient, rb)
|
||||||
|
} else if !handleService(nick) {
|
||||||
|
rb.Add(nil, client.server.name, ERR_NOSUCHNICK, client.nick, masksString, client.t("No such nick"))
|
||||||
}
|
}
|
||||||
|
// fall through, ENDOFWHOIS is always sent
|
||||||
}
|
}
|
||||||
rb.Add(nil, server.name, RPL_ENDOFWHOIS, client.nick, masksString, client.t("End of /WHOIS list"))
|
rb.Add(nil, server.name, RPL_ENDOFWHOIS, client.nick, masksString, client.t("End of /WHOIS list"))
|
||||||
return false
|
return false
|
||||||
|
@ -3,8 +3,11 @@
|
|||||||
|
|
||||||
package isupport
|
package isupport
|
||||||
|
|
||||||
import "fmt"
|
import (
|
||||||
import "sort"
|
"fmt"
|
||||||
|
"sort"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
maxLastArgLength = 400
|
maxLastArgLength = 400
|
||||||
@ -102,7 +105,7 @@ func (il *List) GetDifference(newil *List) [][]string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// RegenerateCachedReply regenerates the cached RPL_ISUPPORT reply
|
// RegenerateCachedReply regenerates the cached RPL_ISUPPORT reply
|
||||||
func (il *List) RegenerateCachedReply() {
|
func (il *List) RegenerateCachedReply() (err error) {
|
||||||
il.CachedReply = make([][]string, 0)
|
il.CachedReply = make([][]string, 0)
|
||||||
var length int // Length of the current cache
|
var length int // Length of the current cache
|
||||||
var cache []string // Token list cache
|
var cache []string // Token list cache
|
||||||
@ -116,6 +119,10 @@ func (il *List) RegenerateCachedReply() {
|
|||||||
|
|
||||||
for _, name := range tokens {
|
for _, name := range tokens {
|
||||||
token := getTokenString(name, il.Tokens[name])
|
token := getTokenString(name, il.Tokens[name])
|
||||||
|
if token[0] == ':' || strings.Contains(token, " ") {
|
||||||
|
err = fmt.Errorf("bad isupport token (cannot contain spaces or start with :): %s", token)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
if len(token)+length <= maxLastArgLength {
|
if len(token)+length <= maxLastArgLength {
|
||||||
// account for the space separating tokens
|
// account for the space separating tokens
|
||||||
@ -136,4 +143,6 @@ func (il *List) RegenerateCachedReply() {
|
|||||||
if len(cache) > 0 {
|
if len(cache) > 0 {
|
||||||
il.CachedReply = append(il.CachedReply, cache)
|
il.CachedReply = append(il.CachedReply, cache)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
@ -26,7 +26,10 @@ func TestISUPPORT(t *testing.T) {
|
|||||||
tListLong.AddNoValue("D")
|
tListLong.AddNoValue("D")
|
||||||
tListLong.AddNoValue("E")
|
tListLong.AddNoValue("E")
|
||||||
tListLong.AddNoValue("F")
|
tListLong.AddNoValue("F")
|
||||||
tListLong.RegenerateCachedReply()
|
err := tListLong.RegenerateCachedReply()
|
||||||
|
if err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
|
|
||||||
longReplies := [][]string{
|
longReplies := [][]string{
|
||||||
{"1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D"},
|
{"1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D"},
|
||||||
@ -44,7 +47,10 @@ func TestISUPPORT(t *testing.T) {
|
|||||||
tList1.Add("INVEX", "i")
|
tList1.Add("INVEX", "i")
|
||||||
tList1.AddNoValue("EXTBAN")
|
tList1.AddNoValue("EXTBAN")
|
||||||
tList1.Add("RANDKILL", "whenever")
|
tList1.Add("RANDKILL", "whenever")
|
||||||
tList1.RegenerateCachedReply()
|
err = tList1.RegenerateCachedReply()
|
||||||
|
if err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
|
|
||||||
expected := [][]string{{"CASEMAPPING=rfc1459-strict", "EXTBAN", "INVEX=i", "RANDKILL=whenever", "SASL=yes"}}
|
expected := [][]string{{"CASEMAPPING=rfc1459-strict", "EXTBAN", "INVEX=i", "RANDKILL=whenever", "SASL=yes"}}
|
||||||
if !reflect.DeepEqual(tList1.CachedReply, expected) {
|
if !reflect.DeepEqual(tList1.CachedReply, expected) {
|
||||||
@ -58,7 +64,10 @@ func TestISUPPORT(t *testing.T) {
|
|||||||
tList2.AddNoValue("INVEX")
|
tList2.AddNoValue("INVEX")
|
||||||
tList2.Add("EXTBAN", "TestBah")
|
tList2.Add("EXTBAN", "TestBah")
|
||||||
tList2.AddNoValue("STABLEKILL")
|
tList2.AddNoValue("STABLEKILL")
|
||||||
tList2.RegenerateCachedReply()
|
err = tList2.RegenerateCachedReply()
|
||||||
|
if err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
|
|
||||||
expected = [][]string{{"CASEMAPPING=ascii", "EXTBAN=TestBah", "INVEX", "SASL=yes", "STABLEKILL"}}
|
expected = [][]string{{"CASEMAPPING=ascii", "EXTBAN=TestBah", "INVEX", "SASL=yes", "STABLEKILL"}}
|
||||||
if !reflect.DeepEqual(tList2.CachedReply, expected) {
|
if !reflect.DeepEqual(tList2.CachedReply, expected) {
|
||||||
@ -72,3 +81,26 @@ func TestISUPPORT(t *testing.T) {
|
|||||||
t.Error("difference reply does not match expected difference reply")
|
t.Error("difference reply does not match expected difference reply")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestBadToken(t *testing.T) {
|
||||||
|
list := NewList()
|
||||||
|
list.Add("NETWORK", "Bad Network Name")
|
||||||
|
list.Add("SASL", "yes")
|
||||||
|
list.Add("CASEMAPPING", "rfc1459-strict")
|
||||||
|
list.Add("INVEX", "i")
|
||||||
|
list.AddNoValue("EXTBAN")
|
||||||
|
|
||||||
|
err := list.RegenerateCachedReply()
|
||||||
|
if err == nil {
|
||||||
|
t.Error("isupport token generation should fail due to space in network name")
|
||||||
|
}
|
||||||
|
|
||||||
|
// should produce a list containing the other, valid params
|
||||||
|
numParams := 0
|
||||||
|
for _, tokenLine := range list.CachedReply {
|
||||||
|
numParams += len(tokenLine)
|
||||||
|
}
|
||||||
|
if numParams != 4 {
|
||||||
|
t.Errorf("expected the other 4 params to be generated, got %v", list.CachedReply)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -250,7 +250,7 @@ func (logger *singleLogger) Log(level Level, logType string, messageParts ...str
|
|||||||
}
|
}
|
||||||
|
|
||||||
sep := grey(":")
|
sep := grey(":")
|
||||||
fullStringFormatted := fmt.Sprintf("%s %s %s %s %s %s ", timeGrey(time.Now().UTC().Format("2006-01-02T15:04:05Z")), sep, levelDisplay, sep, section(logType), sep)
|
fullStringFormatted := fmt.Sprintf("%s %s %s %s %s %s ", timeGrey(time.Now().UTC().Format("2006-01-02T15:04:05.000Z")), sep, levelDisplay, sep, section(logType), sep)
|
||||||
fullStringRaw := fmt.Sprintf("%s : %s : %s : ", time.Now().UTC().Format("2006-01-02T15:04:05Z"), LogLevelDisplayNames[level], logType)
|
fullStringRaw := fmt.Sprintf("%s : %s : %s : ", time.Now().UTC().Format("2006-01-02T15:04:05Z"), LogLevelDisplayNames[level], logType)
|
||||||
for i, p := range messageParts {
|
for i, p := range messageParts {
|
||||||
fullStringFormatted += p
|
fullStringFormatted += p
|
||||||
|
@ -9,7 +9,6 @@ import (
|
|||||||
"bufio"
|
"bufio"
|
||||||
"crypto/tls"
|
"crypto/tls"
|
||||||
"fmt"
|
"fmt"
|
||||||
"math/rand"
|
|
||||||
"net"
|
"net"
|
||||||
"net/http"
|
"net/http"
|
||||||
_ "net/http/pprof"
|
_ "net/http/pprof"
|
||||||
@ -148,7 +147,7 @@ func NewServer(config *Config, logger *logger.Manager) (*Server, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// setISupport sets up our RPL_ISUPPORT reply.
|
// setISupport sets up our RPL_ISUPPORT reply.
|
||||||
func (server *Server) setISupport() {
|
func (server *Server) setISupport() (err error) {
|
||||||
maxTargetsString := strconv.Itoa(maxTargets)
|
maxTargetsString := strconv.Itoa(maxTargets)
|
||||||
|
|
||||||
config := server.Config()
|
config := server.Config()
|
||||||
@ -193,11 +192,15 @@ func (server *Server) setISupport() {
|
|||||||
isupport.Add("REGCREDTYPES", "passphrase,certfp")
|
isupport.Add("REGCREDTYPES", "passphrase,certfp")
|
||||||
}
|
}
|
||||||
|
|
||||||
isupport.RegenerateCachedReply()
|
err = isupport.RegenerateCachedReply()
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
server.configurableStateMutex.Lock()
|
server.configurableStateMutex.Lock()
|
||||||
server.isupport = isupport
|
server.isupport = isupport
|
||||||
server.configurableStateMutex.Unlock()
|
server.configurableStateMutex.Unlock()
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func loadChannelList(channel *Channel, list string, maskMode modes.Mode) {
|
func loadChannelList(channel *Channel, list string, maskMode modes.Mode) {
|
||||||
@ -371,13 +374,7 @@ func (server *Server) createListener(addr string, tlsConfig *tls.Config, bindMod
|
|||||||
|
|
||||||
// generateMessageID returns a network-unique message ID.
|
// generateMessageID returns a network-unique message ID.
|
||||||
func (server *Server) generateMessageID() string {
|
func (server *Server) generateMessageID() string {
|
||||||
// we don't need the full like 30 chars since the unixnano below handles
|
return utils.GenerateSecretToken()
|
||||||
// most of our uniqueness requirements, so just truncate at 5
|
|
||||||
lastbit := strconv.FormatInt(rand.Int63(), 36)
|
|
||||||
if 5 < len(lastbit) {
|
|
||||||
lastbit = lastbit[:4]
|
|
||||||
}
|
|
||||||
return fmt.Sprintf("%s%s", strconv.FormatInt(time.Now().UTC().UnixNano(), 36), lastbit)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
@ -794,7 +791,10 @@ func (server *Server) applyConfig(config *Config, initial bool) (err error) {
|
|||||||
// set RPL_ISUPPORT
|
// set RPL_ISUPPORT
|
||||||
var newISupportReplies [][]string
|
var newISupportReplies [][]string
|
||||||
oldISupportList := server.ISupport()
|
oldISupportList := server.ISupport()
|
||||||
server.setISupport()
|
err = server.setISupport()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
if oldISupportList != nil {
|
if oldISupportList != nil {
|
||||||
newISupportReplies = oldISupportList.GetDifference(server.ISupport())
|
newISupportReplies = oldISupportList.GetDifference(server.ISupport())
|
||||||
}
|
}
|
||||||
|
@ -8,10 +8,8 @@ package main
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
"math/rand"
|
|
||||||
"strings"
|
"strings"
|
||||||
"syscall"
|
"syscall"
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/docopt/docopt-go"
|
"github.com/docopt/docopt-go"
|
||||||
"github.com/oragono/oragono/irc"
|
"github.com/oragono/oragono/irc"
|
||||||
@ -114,7 +112,6 @@ Options:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if arguments["run"].(bool) {
|
} else if arguments["run"].(bool) {
|
||||||
rand.Seed(time.Now().UTC().UnixNano())
|
|
||||||
if !arguments["--quiet"].(bool) {
|
if !arguments["--quiet"].(bool) {
|
||||||
logman.Info("startup", fmt.Sprintf("Oragono v%s starting", irc.SemVer))
|
logman.Info("startup", fmt.Sprintf("Oragono v%s starting", irc.SemVer))
|
||||||
if commit == "" {
|
if commit == "" {
|
||||||
|
Loading…
Reference in New Issue
Block a user