More: hellfire

This commit is contained in:
kayos@tcp.direct 2021-10-17 17:16:59 -07:00
parent 410e8686ab
commit 7f101f3656
5 changed files with 31 additions and 13 deletions

@ -484,13 +484,15 @@ func handleISUPPORT(c *Client, e Event) {
j := strings.IndexByte(e.Params[i], '=') j := strings.IndexByte(e.Params[i], '=')
if j < 1 || (j+1) == len(e.Params[i]) { if j < 1 || (j+1) == len(e.Params[i]) {
c.state.serverOptions[e.Params[i]] = "" opt := c.state.serverOptions[e.Params[i]]
opt.Store("")
continue continue
} }
name := e.Params[i][0:j] name := e.Params[i][0:j]
val := e.Params[i][j+1:] val := e.Params[i][j+1:]
c.state.serverOptions[name] = val opt := c.state.serverOptions[name]
opt.Store(val)
} }
c.state.Unlock() c.state.Unlock()

@ -19,6 +19,7 @@ import (
"strconv" "strconv"
"strings" "strings"
"sync" "sync"
"sync/atomic"
"time" "time"
) )
@ -678,10 +679,12 @@ func (c *Client) IsInChannel(channel string) (in bool) {
// //
func (c *Client) GetServerOption(key string) (result string, ok bool) { func (c *Client) GetServerOption(key string) (result string, ok bool) {
c.panicIfNotTracking() c.panicIfNotTracking()
var opt atomic.Value
if opt, ok = c.state.serverOptions[key]; ok {
result = opt.Load().(string)
}
c.state.RLock()
result, ok = c.state.serverOptions[key]
c.state.RUnlock()
return result, ok return result, ok
} }
@ -693,7 +696,13 @@ func (c *Client) GetAllServerOption() (map[string]string, error) {
c.state.RLock() c.state.RLock()
defer c.state.RUnlock() defer c.state.RUnlock()
if len(c.state.serverOptions) > 0 { if len(c.state.serverOptions) > 0 {
return c.state.serverOptions, nil copied := make(map[string]string)
for k, av := range c.state.serverOptions {
if v := av.Load(); v != nil {
copied[k] = av.Load().(string)
}
}
return copied, nil
} else { } else {
return nil, errors.New("server options is empty") return nil, errors.New("server options is empty")
} }

@ -428,13 +428,14 @@ func (c *Client) readLoop(ctx context.Context, errs chan error, wg *sync.WaitGro
func (c *Client) Send(event *Event) { func (c *Client) Send(event *Event) {
var delay time.Duration var delay time.Duration
event.Network = c.NetworkName()
for atomic.CompareAndSwapUint32(&c.atom, stateUnlocked, stateLocked) { for atomic.CompareAndSwapUint32(&c.atom, stateUnlocked, stateLocked) {
randSleep() randSleep()
} }
defer atomic.StoreUint32(&c.atom, stateUnlocked) defer atomic.StoreUint32(&c.atom, stateUnlocked)
if !c.Config.AllowFlood { if !c.Config.AllowFlood {
// Drop the event early as we're disconnected, this way we don't have to wait // Drop the event early as we're disconnected, this way we don't have to wait
// the (potentially long) rate limit delay before dropping. // the (potentially long) rate limit delay before dropping.
if c.conn == nil { if c.conn == nil {

@ -370,8 +370,11 @@ func handleMODE(c *Client, e Event) {
// chanModes returns the ISUPPORT list of server-supported channel modes, // chanModes returns the ISUPPORT list of server-supported channel modes,
// alternatively falling back to ModeDefaults. // alternatively falling back to ModeDefaults.
func (s *state) chanModes() string { func (s *state) chanModes() string {
if modes, ok := s.serverOptions["CHANMODES"]; ok && IsValidChannelMode(modes) { if validmodes, ok := s.serverOptions["CHANMODES"]; ok {
return modes modes := validmodes.Load().(string)
if IsValidChannelMode(modes) {
return modes
}
} }
return ModeDefaults return ModeDefaults
@ -381,8 +384,11 @@ func (s *state) chanModes() string {
// This includes mode characters, as well as user prefix symbols. Falls back // This includes mode characters, as well as user prefix symbols. Falls back
// to DefaultPrefixes if not server-supported. // to DefaultPrefixes if not server-supported.
func (s *state) userPrefixes() string { func (s *state) userPrefixes() string {
if prefix, ok := s.serverOptions["PREFIX"]; ok && isValidUserPrefix(prefix) { if atomicprefix, ok := s.serverOptions["PREFIX"]; ok {
return prefix prefix := atomicprefix.Load().(string)
if isValidUserPrefix(prefix) {
return prefix
}
} }
return DefaultPrefixes return DefaultPrefixes

@ -32,7 +32,7 @@ type state struct {
// serverOptions are the standard capabilities and configurations // serverOptions are the standard capabilities and configurations
// supported by the server at connection time. This also includes // supported by the server at connection time. This also includes
// RPL_ISUPPORT entries. // RPL_ISUPPORT entries.
serverOptions map[string]string serverOptions map[string]atomic.Value
// motd is the servers message of the day. // motd is the servers message of the day.
motd string motd string
@ -52,7 +52,7 @@ func (s *state) reset(initial bool) {
s.host.Store("") s.host.Store("")
s.channels = make(map[string]*Channel) s.channels = make(map[string]*Channel)
s.users = make(map[string]*User) s.users = make(map[string]*User)
s.serverOptions = make(map[string]string) s.serverOptions = make(map[string]atomic.Value)
s.enabledCap = make(map[string]map[string]string) s.enabledCap = make(map[string]map[string]string)
s.tmpCap = make(map[string]map[string]string) s.tmpCap = make(map[string]map[string]string)
s.motd = "" s.motd = ""