<commit_before>package irc

import (
	"bufio"
	"database/sql"
	"fmt"
	"log"
	"net"
	"net/http"
	"os"
	"os/signal"
	"strings"
	"syscall"
	"time"
)

type ServerCommand interface {
	Command
	HandleServer(*Server)
}

type RegServerCommand interface {
	Command
	HandleRegServer(*Server)
}

type Server struct {
	channels  ChannelNameMap
	clients   *ClientLookupSet
	commands  chan Command
	ctime     time.Time
	db        *sql.DB
	idle      chan *Client
	motdFile  string
	name      Name
	newConns  chan net.Conn
	operators map[Name][]byte
	password  []byte
	signals   chan os.Signal
	whoWas    *WhoWasList
	theaters  map[Name][]byte
	isupport  *ISupportList
}

var (
	SERVER_SIGNALS = []os.Signal{syscall.SIGINT, syscall.SIGHUP,
		syscall.SIGTERM, syscall.SIGQUIT}
)

func NewServer(config *Config) *Server {
	server := &Server{
		channels:  make(ChannelNameMap),
		clients:   NewClientLookupSet(),
		commands:  make(chan Command),
		ctime:     time.Now(),
		db:        OpenDB(config.Server.Database),
		idle:      make(chan *Client),
		motdFile:  config.Server.MOTD,
		name:      NewName(config.Server.Name),
		newConns:  make(chan net.Conn),
		operators: config.Operators(),
		signals:   make(chan os.Signal, len(SERVER_SIGNALS)),
		whoWas:    NewWhoWasList(100),
		theaters:  config.Theaters(),
	}

	if config.Server.Password != "" {
		server.password = config.Server.PasswordBytes()
	}

	server.loadChannels()

	for _, addr := range config.Server.Listen {
		server.listen(addr)
	}

	if config.Server.Wslisten != "" {
		server.wslisten(config.Server.Wslisten)
	}

	signal.Notify(server.signals, SERVER_SIGNALS...)

	// add RPL_ISUPPORT tokens
	server.isupport = NewISupportList()
	server.isupport.Add("CASEMAPPING", "ascii")
	server.isupport.Add("CHANMODES", "")  //TODO(dan): Channel mode list here
	server.isupport.Add("CHANNELLEN", "") //TODO(dan): Support channel length
	server.isupport.Add("CHANTYPES", "#")
	server.isupport.Add("EXCEPTS", "")
	server.isupport.Add("INVEX", "")
	server.isupport.Add("KICKLEN", "") //TODO(dan): Support kick length?
	server.isupport.Add("MAXLIST", "") //TODO(dan): Support max list length?
	server.isupport.Add("MODES", "")   //TODO(dan): Support max modes?
	server.isupport.Add("NETWORK", config.Network.Name)
	server.isupport.Add("NICKLEN", "") //TODO(dan): Support nick length
	server.isupport.Add("PREFIX", "(ov)@+")
	server.isupport.Add("STATUSMSG", "@+") //TODO(dan): Autogenerate based on PREFIXes, make sure it's actually supported
	server.isupport.Add("TARGMAX", "")     //TODO(dan): Support this
	server.isupport.Add("TOPICLEN", "")    //TODO(dan): Support topic length
	server.isupport.RegenerateCachedReply()

	return server
}

func loadChannelList(channel *Channel, list string, maskMode ChannelMode) {
	if list == "" {
		return
	}
	channel.lists[maskMode].AddAll(NewNames(strings.Split(list, " ")))<commit_msg>isupport: STATUSMSG isn't supported, don't advertise it<commit_after>package irc

import (
	"bufio"
	"database/sql"
	"fmt"
	"log"
	"net"
	"net/http"
	"os"
	"os/signal"
	"strings"
	"syscall"
	"time"
)

type ServerCommand interface {
	Command
	HandleServer(*Server)
}

type RegServerCommand interface {
	Command
	HandleRegServer(*Server)
}

type Server struct {
	channels  ChannelNameMap
	clients   *ClientLookupSet
	commands  chan Command
	ctime     time.Time
	db        *sql.DB
	idle      chan *Client
	motdFile  string
	name      Name
	newConns  chan net.Conn
	operators map[Name][]byte
	password  []byte
	signals   chan os.Signal
	whoWas    *WhoWasList
	theaters  map[Name][]byte
	isupport  *ISupportList
}

var (
	SERVER_SIGNALS = []os.Signal{syscall.SIGINT, syscall.SIGHUP,
		syscall.SIGTERM, syscall.SIGQUIT}
)

func NewServer(config *Config) *Server {
	server := &Server{
		channels:  make(ChannelNameMap),
		clients:   NewClientLookupSet(),
		commands:  make(chan Command),
		ctime:     time.Now(),
		db:        OpenDB(config.Server.Database),
		idle:      make(chan *Client),
		motdFile:  config.Server.MOTD,
		name:      NewName(config.Server.Name),
		newConns:  make(chan net.Conn),
		operators: config.Operators(),
		signals:   make(chan os.Signal, len(SERVER_SIGNALS)),
		whoWas:    NewWhoWasList(100),
		theaters:  config.Theaters(),
	}

	if config.Server.Password != "" {
		server.password = config.Server.PasswordBytes()
	}

	server.loadChannels()

	for _, addr := range config.Server.Listen {
		server.listen(addr)
	}

	if config.Server.Wslisten != "" {
		server.wslisten(config.Server.Wslisten)
	}

	signal.Notify(server.signals, SERVER_SIGNALS...)

	// add RPL_ISUPPORT tokens
	server.isupport = NewISupportList()
	server.isupport.Add("CASEMAPPING", "ascii")
	server.isupport.Add("CHANMODES", "")  //TODO(dan): Channel mode list here
	server.isupport.Add("CHANNELLEN", "") //TODO(dan): Support channel length
	server.isupport.Add("CHANTYPES", "#")
	server.isupport.Add("EXCEPTS", "")
	server.isupport.Add("INVEX", "")
	server.isupport.Add("KICKLEN", "") //TODO(dan): Support kick length?
	server.isupport.Add("MAXLIST", "") //TODO(dan): Support max list length?
	server.isupport.Add("MODES", "")   //TODO(dan): Support max modes?
	server.isupport.Add("NETWORK", config.Network.Name)
	server.isupport.Add("NICKLEN", "") //TODO(dan): Support nick length
	server.isupport.Add("PREFIX", "(ov)@+")
	// server.isupport.Add("STATUSMSG", "@+") //TODO(dan): Autogenerate based on PREFIXes, support STATUSMSG
	server.isupport.Add("TARGMAX", "")  //TODO(dan): Support this
	server.isupport.Add("TOPICLEN", "") //TODO(dan): Support topic length
	server.isupport.RegenerateCachedReply()

	return server
}

func loadChannelList(channel *Channel, list string, maskMode ChannelMode) {
	if list == "" {
		return
	}
	channel.lists[maskMode].AddAll(NewNames(strings.Split(list, " ")))
{'fraction_non_alphanumeric': 0.14992164374020547, 'fraction_numerical': 0.0010447501305937664, 'mean_word_length': 4.333333333333333, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7434801', 'n_tokens_mistral': 2120, 'n_tokens_neox': 2080, 'n_words': 401}