3
0
mirror of https://github.com/ergochat/ergo.git synced 2024-11-10 22:19:31 +01:00

Stuff is no longer completely broken. Just mostly.

This commit is contained in:
Daniel Oaks 2016-06-20 22:53:45 +10:00
parent b8dc10f92d
commit 04442ddef1
9 changed files with 125 additions and 69 deletions

View File

@ -25,6 +25,7 @@ Initial release of Oragono!
* Default channel modes are now (`+nt`), matching most other IRCds. * Default channel modes are now (`+nt`), matching most other IRCds.
* CLI argument names made more consistent with typical software. * CLI argument names made more consistent with typical software.
* ONICK: Renamed to SANICK to be more consistent with other IRCds. * ONICK: Renamed to SANICK to be more consistent with other IRCds.
* USER: Prepend usernames set by the USER command with `"~"`.
### Removed ### Removed
* Gitconfig config format completely removed and replaced with YAML. * Gitconfig config format completely removed and replaced with YAML.

View File

@ -105,14 +105,14 @@ func capHandler(server *Server, client *Client, msg ircmsg.IrcMessage) bool {
// make sure all capabilities actually exist // make sure all capabilities actually exist
for capability := range capabilities { for capability := range capabilities {
if !SupportedCapabilities[capability] { if !SupportedCapabilities[capability] {
client.Send(nil, server.nameString, "CAP", client.nickString, subCommand, capString) client.Send(nil, server.nameString, "CAP", client.nickString, "NAK", capString)
return false return false
} }
} }
for capability := range capabilities { for capability := range capabilities {
client.capabilities[capability] = true client.capabilities[capability] = true
} }
client.Send(nil, server.nameString, "CAP", client.nickString, subCommand, capString) client.Send(nil, server.nameString, "CAP", client.nickString, "ACK", capString)
case "END": case "END":
if !client.registered { if !client.registered {

View File

@ -56,6 +56,7 @@ func NewClient(server *Server, conn net.Conn) *Client {
flags: make(map[UserMode]bool), flags: make(map[UserMode]bool),
server: server, server: server,
socket: &socket, socket: &socket,
nickString: "*", // * is used until actual nick is given
} }
client.Touch() client.Touch()
go client.run() go client.run()
@ -68,7 +69,6 @@ func NewClient(server *Server, conn net.Conn) *Client {
// //
func (client *Client) run() { func (client *Client) run() {
var command Command
var err error var err error
var isExiting bool var isExiting bool
var line string var line string
@ -88,14 +88,14 @@ func (client *Client) run() {
msg, err = ircmsg.ParseLine(line) msg, err = ircmsg.ParseLine(line)
if err != nil { if err != nil {
client.Quit("received malformed command") client.Quit("received malformed line")
break break
} }
cmd, exists := Commands[msg.Command] cmd, exists := Commands[msg.Command]
if !exists { if !exists {
//TODO(dan): Reply with 400 or whatever unknown cmd is client.Send(nil, client.server.nameString, ERR_UNKNOWNCOMMAND, client.nickString, msg.Command, "Unknown command")
client.Quit("Received unknown command") continue
} }
isExiting = cmd.Run(client.server, client, msg) isExiting = cmd.Run(client.server, client, msg)

View File

@ -127,6 +127,7 @@ type ChannelModeCommand struct {
changes ChannelModeChanges changes ChannelModeChanges
} }
/*
// MODE <channel> ( "+" / "-" )? *( "+" / "-" / <mode character> ) *<modeparams> // MODE <channel> ( "+" / "-" )? *( "+" / "-" / <mode character> ) *<modeparams>
func ParseChannelModeCommand(channel Name, args []string) (Command, error) { func ParseChannelModeCommand(channel Name, args []string) (Command, error) {
cmd := &ChannelModeCommand{ cmd := &ChannelModeCommand{

View File

@ -23,7 +23,7 @@ func (cmd *Command) Run(server *Server, client *Client, msg ircmsg.IrcMessage) b
// command silently ignored // command silently ignored
return false return false
} }
if (!cmd.oper) && (!client.flags[Operator]) { if cmd.oper && !client.flags[Operator] {
client.Send(nil, server.nameString, ERR_NOPRIVILEGES, client.nickString, "Permission Denied - You're not an IRC operator") client.Send(nil, server.nameString, ERR_NOPRIVILEGES, client.nickString, "Permission Denied - You're not an IRC operator")
return false return false
} }
@ -87,11 +87,10 @@ var Commands = map[string]Command{
handler: listHandler, handler: listHandler,
minParams: 0, minParams: 0,
}, },
/*TODO(dan): ADD THIS BACK.
"MODE": Command{ "MODE": Command{
handler: modeHandler, handler: modeHandler,
minParams: 1, minParams: 1,
},*/ },
"MOTD": Command{ "MOTD": Command{
handler: motdHandler, handler: motdHandler,
minParams: 0, minParams: 0,
@ -153,7 +152,7 @@ var Commands = map[string]Command{
usablePreReg: true, usablePreReg: true,
minParams: 0, minParams: 0,
}, },
/*TODO(dan): ADD THIS BACK IN /*TODO(dan): Add this back in
"THEATRE": Command{ "THEATRE": Command{
handler: theatreHandler, handler: theatreHandler,
minParams: 1, minParams: 1,

View File

@ -69,6 +69,7 @@ func (il *ISupportList) RegenerateCachedReply() {
func (client *Client) RplISupport() { func (client *Client) RplISupport() {
for _, tokenline := range client.server.isupport.CachedReply { for _, tokenline := range client.server.isupport.CachedReply {
client.Send(nil, client.server.nameString, RPL_ISUPPORT, tokenline...) // ugly trickery ahead
client.Send(nil, client.server.nameString, RPL_ISUPPORT, append([]string{client.nickString}, tokenline...)...)
} }
} }

View File

@ -7,6 +7,8 @@ package irc
import ( import (
"strings" "strings"
"github.com/DanielOaks/girc-go/ircmsg"
) )
// user mode flags // user mode flags
@ -126,24 +128,65 @@ var (
// commands // commands
// //
/* // MODE <target> [<modestring> [<mode arguments>...]]
func (m *ModeCommand) HandleServer(s *Server) { func modeHandler(server *Server, client *Client, msg ircmsg.IrcMessage) bool {
client := m.Client() name := NewName(msg.Params[0])
target := s.clients.Get(m.nickname) if name.IsChannel() {
// return cmodeHandler(server, client, msg)
client.Notice("CMODEs are not yet supported!")
return false
} else {
return umodeHandler(server, client, msg)
}
}
// MODE <target> [<modestring> [<mode arguments>...]]
func umodeHandler(server *Server, client *Client, msg ircmsg.IrcMessage) bool {
nickname := NewName(msg.Params[0])
target := server.clients.Get(nickname)
if target == nil { if target == nil {
client.ErrNoSuchNick(m.nickname) client.Send(nil, server.nameString, ERR_NOSUCHNICK, client.nickString, msg.Params[0], "No such nick")
return return false
} }
//TODO(dan): restricting to Operator here should be done with SAMODE only
// point SAMODE at this handler too, if they are operator and SAMODE was called then fine
if client != target && !client.flags[Operator] { if client != target && !client.flags[Operator] {
client.ErrUsersDontMatch() if len(msg.Params) > 1 {
return client.Send(nil, server.nameString, ERR_USERSDONTMATCH, client.nickString, "Can't change modes for other users")
} else {
client.Send(nil, server.nameString, ERR_USERSDONTMATCH, client.nickString, "Can't view modes for other users")
}
return false
} }
changes := make(ModeChanges, 0, len(m.changes)) // assemble changes
changes := make(ModeChanges, 0)
for _, change := range m.changes { if len(msg.Params) > 1 {
modeArg := msg.Params[0]
op := ModeOp(modeArg[0])
if (op == Add) || (op == Remove) {
modeArg = modeArg[1:]
} else {
client.Send(nil, server.nameString, ERR_UNKNOWNERROR, client.nickString, "MODE", "Mode string could not be parsed correctly")
return false
}
for _, mode := range modeArg {
if mode == '-' || mode == '+' {
op = ModeOp(mode)
continue
}
changes = append(changes, &ModeChange{
mode: UserMode(mode),
op: op,
})
}
for _, change := range changes {
switch change.mode { switch change.mode {
case Invisible, ServerNotice, WallOps: case Invisible, ServerNotice, WallOps:
switch change.op { switch change.op {
@ -172,14 +215,17 @@ func (m *ModeCommand) HandleServer(s *Server) {
} }
} }
} }
}
if len(changes) > 0 { if len(changes) > 0 {
client.Reply(RplModeChanges(client, target, changes)) client.Send(nil, client.nickMaskString, "MODE", target.nickString, changes.String())
} else if client == target { } else if client == target {
client.RplUModeIs(client) client.Send(nil, target.nickMaskString, RPL_UMODEIS, target.nickString, target.ModeString())
} }
return false
} }
/*
func (msg *ChannelModeCommand) HandleServer(server *Server) { func (msg *ChannelModeCommand) HandleServer(server *Server) {
client := msg.Client() client := msg.Client()
channel := server.channels.Get(msg.channel) channel := server.channels.Get(msg.channel)

View File

@ -90,6 +90,7 @@ const (
RPL_USERS = "393" RPL_USERS = "393"
RPL_ENDOFUSERS = "394" RPL_ENDOFUSERS = "394"
RPL_NOUSERS = "395" RPL_NOUSERS = "395"
ERR_UNKNOWNERROR = "400"
ERR_NOSUCHNICK = "401" ERR_NOSUCHNICK = "401"
ERR_NOSUCHSERVER = "402" ERR_NOSUCHSERVER = "402"
ERR_NOSUCHCHANNEL = "403" ERR_NOSUCHCHANNEL = "403"

View File

@ -287,11 +287,11 @@ func (s *Server) tryRegister(c *Client) {
// send welcome text // send welcome text
//NOTE(dan): we specifically use the NICK here instead of the nickmask //NOTE(dan): we specifically use the NICK here instead of the nickmask
// see http://modern.ircdocs.horse/#rplwelcome-001 for details on why we avoid using the nickmask // see http://modern.ircdocs.horse/#rplwelcome-001 for details on why we avoid using the nickmask
c.Send(nil, s.nameString, RPL_WELCOME, fmt.Sprintf("Welcome to the Internet Relay Network %s", c.nickString)) c.Send(nil, s.nameString, RPL_WELCOME, c.nickString, fmt.Sprintf("Welcome to the Internet Relay Network %s", c.nickString))
c.Send(nil, s.nameString, RPL_YOURHOST, fmt.Sprintf("Your host is %s, running version %s", s.nameString, SEM_VER)) c.Send(nil, s.nameString, RPL_YOURHOST, c.nickString, fmt.Sprintf("Your host is %s, running version %s", s.nameString, SEM_VER))
c.Send(nil, s.nameString, RPL_CREATED, fmt.Sprintf("This server was created %s", s.ctime.Format(time.RFC1123))) c.Send(nil, s.nameString, RPL_CREATED, c.nickString, fmt.Sprintf("This server was created %s", s.ctime.Format(time.RFC1123)))
//TODO(dan): Look at adding last optional [<channel modes with a parameter>] parameter //TODO(dan): Look at adding last optional [<channel modes with a parameter>] parameter
c.Send(nil, s.nameString, RPL_MYINFO, s.nameString, SEM_VER, supportedUserModesString, supportedChannelModesString) c.Send(nil, s.nameString, RPL_MYINFO, c.nickString, s.nameString, SEM_VER, supportedUserModesString, supportedChannelModesString)
c.RplISupport() c.RplISupport()
s.MOTD(c) s.MOTD(c)
} }
@ -332,6 +332,12 @@ func passHandler(server *Server, client *Client, msg ircmsg.IrcMessage) bool {
return false return false
} }
// if no password exists, skip checking
if len(server.password) == 0 {
client.authorized = true
return false
}
// check the provided password // check the provided password
password := []byte(msg.Params[0]) password := []byte(msg.Params[0])
if ComparePassword(server.password, password) != nil { if ComparePassword(server.password, password) != nil {
@ -383,8 +389,8 @@ func userHandler(server *Server, client *Client, msg ircmsg.IrcMessage) bool {
// we do it this way to ONLY replace what hasn't already been set // we do it this way to ONLY replace what hasn't already been set
server.clients.Remove(client) server.clients.Remove(client)
if client.username != "" { if !client.HasUsername() {
client.username = Name(msg.Params[0]) client.username = Name("~" + msg.Params[0])
client.updateNickMask() client.updateNickMask()
} }
if client.realname != "" { if client.realname != "" {
@ -446,6 +452,7 @@ func joinHandler(server *Server, client *Client, msg ircmsg.IrcMessage) bool {
for i, nameString := range channels { for i, nameString := range channels {
name = Name(nameString) name = Name(nameString)
if !name.IsChannel() { if !name.IsChannel() {
fmt.Println("ISN'T CHANNEL NAME:", nameString)
client.Send(nil, server.nameString, ERR_NOSUCHCHANNEL, client.nickString, nameString, "No such channel") client.Send(nil, server.nameString, ERR_NOSUCHCHANNEL, client.nickString, nameString, "No such channel")
continue continue
} }
@ -551,10 +558,10 @@ func (client *Client) WhoisChannelsNames(target *Client) []string {
// WHOIS [ <target> ] <mask> *( "," <mask> ) // WHOIS [ <target> ] <mask> *( "," <mask> )
func whoisHandler(server *Server, client *Client, msg ircmsg.IrcMessage) bool { func whoisHandler(server *Server, client *Client, msg ircmsg.IrcMessage) bool {
var masksString string var masksString string
var target string //var target string
if len(msg.Params) > 1 { if len(msg.Params) > 1 {
target = msg.Params[0] //target = msg.Params[0]
masksString = msg.Params[1] masksString = msg.Params[1]
} else { } else {
masksString = msg.Params[0] masksString = msg.Params[0]
@ -639,10 +646,10 @@ func whoHandler(server *Server, client *Client, msg ircmsg.IrcMessage) bool {
//TODO(dan): is this used and would I put this param in the Modern doc? //TODO(dan): is this used and would I put this param in the Modern doc?
// if not, can we remove it? // if not, can we remove it?
var operatorOnly bool //var operatorOnly bool
if len(msg.Params) > 1 && msg.Params[1] == "o" { //if len(msg.Params) > 1 && msg.Params[1] == "o" {
operatorOnly = true // operatorOnly = true
} //}
if mask == "" { if mask == "" {
for _, channel := range server.channels { for _, channel := range server.channels {
@ -679,7 +686,7 @@ func operHandler(server *Server, client *Client, msg ircmsg.IrcMessage) bool {
} }
client.flags[Operator] = true client.flags[Operator] = true
client.Send(nil, server.nameString, RPL_YOUREOPER, client.nickString, "You are not an IRC operator") client.Send(nil, server.nameString, RPL_YOUREOPER, client.nickString, "You are now an IRC operator")
//TODO(dan): Should this be sent automagically as part of setting the flag/mode? //TODO(dan): Should this be sent automagically as part of setting the flag/mode?
modech := ModeChanges{&ModeChange{ modech := ModeChanges{&ModeChange{
mode: Operator, mode: Operator,
@ -740,10 +747,10 @@ func isonHandler(server *Server, client *Client, msg ircmsg.IrcMessage) bool {
// MOTD [<target>] // MOTD [<target>]
func motdHandler(server *Server, client *Client, msg ircmsg.IrcMessage) bool { func motdHandler(server *Server, client *Client, msg ircmsg.IrcMessage) bool {
//TODO(dan): hook this up when we have multiple servers I guess??? //TODO(dan): hook this up when we have multiple servers I guess???
var target string //var target string
if len(msg.Params) > 0 { //if len(msg.Params) > 0 {
target = msg.Params[0] // target = msg.Params[0]
} //}
server.MOTD(client) server.MOTD(client)
return false return false
@ -902,10 +909,10 @@ func namesHandler(server *Server, client *Client, msg ircmsg.IrcMessage) bool {
if len(msg.Params) > 0 { if len(msg.Params) > 0 {
channels = strings.Split(msg.Params[0], ",") channels = strings.Split(msg.Params[0], ",")
} }
var target string //var target string
if len(msg.Params) > 1 { //if len(msg.Params) > 1 {
target = msg.Params[1] // target = msg.Params[1]
} //}
if len(channels) == 0 { if len(channels) == 0 {
for _, channel := range server.channels { for _, channel := range server.channels {
@ -1002,10 +1009,10 @@ func whowasHandler(server *Server, client *Client, msg ircmsg.IrcMessage) bool {
if len(msg.Params) > 1 { if len(msg.Params) > 1 {
count, _ = strconv.ParseInt(msg.Params[1], 10, 64) count, _ = strconv.ParseInt(msg.Params[1], 10, 64)
} }
var target string //var target string
if len(msg.Params) > 2 { //if len(msg.Params) > 2 {
target = msg.Params[2] // target = msg.Params[2]
} //}
for _, nickname := range nicknames { for _, nickname := range nicknames {
results := server.whoWas.Find(Name(nickname), count) results := server.whoWas.Find(Name(nickname), count)
if len(results) == 0 { if len(results) == 0 {