mirror of
				https://github.com/ergochat/ergo.git
				synced 2025-11-04 15:57:30 +01:00 
			
		
		
		
	Move main into the right location; fix a lot of channel messages.
This commit is contained in:
		
							parent
							
								
									78e741af3b
								
							
						
					
					
						commit
						5acc36409a
					
				
							
								
								
									
										2
									
								
								build.sh
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								build.sh
									
									
									
									
									
								
							@ -1,2 +1,2 @@
 | 
			
		||||
#!/bin/bash
 | 
			
		||||
env GOPATH="$PWD" go build
 | 
			
		||||
env GOPATH="$PWD" go install ergonomadic
 | 
			
		||||
 | 
			
		||||
@ -2,6 +2,7 @@ package irc
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"log"
 | 
			
		||||
	"net"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
@ -16,9 +17,9 @@ type Client struct {
 | 
			
		||||
	hostname   string
 | 
			
		||||
	nick       string
 | 
			
		||||
	serverPass bool
 | 
			
		||||
	registered bool
 | 
			
		||||
	// modes
 | 
			
		||||
	away          bool
 | 
			
		||||
	registered    bool
 | 
			
		||||
	invisible     bool
 | 
			
		||||
	wallOps       bool
 | 
			
		||||
	restricted    bool
 | 
			
		||||
@ -48,7 +49,9 @@ func (c *Client) SetReplyToStringChan() {
 | 
			
		||||
	write := StringWriteChan(c.conn)
 | 
			
		||||
	go func() {
 | 
			
		||||
		for reply := range send {
 | 
			
		||||
			write <- reply.String(c)
 | 
			
		||||
			replyStr := reply.String(c)
 | 
			
		||||
			log.Printf("%s <- %s", c.Id(), replyStr)
 | 
			
		||||
			write <- replyStr
 | 
			
		||||
		}
 | 
			
		||||
	}()
 | 
			
		||||
	c.send = send
 | 
			
		||||
@ -88,8 +91,15 @@ func (c *Client) HasUser() bool {
 | 
			
		||||
	return c.username != ""
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (c *Client) Username() string {
 | 
			
		||||
	if c.HasUser() {
 | 
			
		||||
		return c.username
 | 
			
		||||
	}
 | 
			
		||||
	return "*"
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (c *Client) UserHost() string {
 | 
			
		||||
	return fmt.Sprintf("%s!%s@%s", c.nick, c.username, c.hostname)
 | 
			
		||||
	return fmt.Sprintf("%s!%s@%s", c.Nick(), c.Username(), c.hostname)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (c *Client) Id() string {
 | 
			
		||||
 | 
			
		||||
@ -21,6 +21,7 @@ var (
 | 
			
		||||
 | 
			
		||||
type UnknownMessage struct {
 | 
			
		||||
	command string
 | 
			
		||||
	args    []string
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// NB: no constructor, created on demand in parser for invalid messages.
 | 
			
		||||
@ -83,14 +84,16 @@ func NewPassMessage(args []string) (Message, error) {
 | 
			
		||||
	if len(args) < 1 {
 | 
			
		||||
		return nil, NotEnoughArgsError
 | 
			
		||||
	}
 | 
			
		||||
	return &PassMessage{password: args[0]}
 | 
			
		||||
	return &PassMessage{
 | 
			
		||||
		password: args[0],
 | 
			
		||||
	}, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (m *PassMessage) Handle(s *Server, c *Client) {
 | 
			
		||||
	if m.password == server.password {
 | 
			
		||||
	if m.password == s.password {
 | 
			
		||||
		c.serverPass = true
 | 
			
		||||
	} else {
 | 
			
		||||
		c.send <- ErrPass
 | 
			
		||||
		c.send <- ErrPasswdMismatch(s)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -181,11 +184,9 @@ func NewModeMessage(args []string) (Message, error) {
 | 
			
		||||
		return nil, NotEnoughArgsError
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	msg := &ModeMessage{
 | 
			
		||||
		nickname: args[0],
 | 
			
		||||
	}
 | 
			
		||||
	if (len(args) > 1) && CHANNEL_RE.MatchString(args[1]) {
 | 
			
		||||
		cmsg := &ChannelModeMessage{msg}
 | 
			
		||||
		cmsg := new(ChannelModeMessage)
 | 
			
		||||
		cmsg.nickname = args[0]
 | 
			
		||||
		if len(args) > 2 {
 | 
			
		||||
			groups := EXTRACT_MODE_RE.FindStringSubmatch(args[2])
 | 
			
		||||
			cmsg.modes = make([]string, len(groups[2]))
 | 
			
		||||
@ -195,14 +196,18 @@ func NewModeMessage(args []string) (Message, error) {
 | 
			
		||||
				i++
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		if len(args > 3) {
 | 
			
		||||
		if len(args) > 3 {
 | 
			
		||||
			cmsg.modeParams = strings.Split(args[3], ",")
 | 
			
		||||
		}
 | 
			
		||||
		return cmsg
 | 
			
		||||
		return cmsg, nil
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	msg := &ModeMessage{
 | 
			
		||||
		nickname: args[0],
 | 
			
		||||
	}
 | 
			
		||||
	for _, arg := range args[1:] {
 | 
			
		||||
		if !MODE_RE.MatchString(arg) {
 | 
			
		||||
			return nil, ErrUModeUnknownFlag
 | 
			
		||||
			return nil, UModeUnknownFlagError
 | 
			
		||||
		}
 | 
			
		||||
		prefix := arg[0]
 | 
			
		||||
		for _, c := range arg[1:] {
 | 
			
		||||
@ -407,14 +412,14 @@ type OperMessage struct {
 | 
			
		||||
	password string
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func NewOperMessage(args []string) Message {
 | 
			
		||||
func NewOperMessage(args []string) (Message, error) {
 | 
			
		||||
	if len(args) < 2 {
 | 
			
		||||
		return nil, NotEnoughArgsError
 | 
			
		||||
	}
 | 
			
		||||
	return &OperMessage{
 | 
			
		||||
		name:     args[0],
 | 
			
		||||
		password: args[1],
 | 
			
		||||
	}
 | 
			
		||||
	}, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (m *OperMessage) Handle(s *Server, c *Client) {
 | 
			
		||||
 | 
			
		||||
@ -2,31 +2,29 @@ package irc
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"bufio"
 | 
			
		||||
	"log"
 | 
			
		||||
	"net"
 | 
			
		||||
	"strings"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func readTrimmedLine(reader *bufio.Reader) (string, error) {
 | 
			
		||||
	line, err := reader.ReadString('\n')
 | 
			
		||||
	return strings.TrimSpace(line), err
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return "", err
 | 
			
		||||
	}
 | 
			
		||||
	return strings.TrimSpace(line), nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Adapt `net.Conn` to a `chan string`.
 | 
			
		||||
func StringReadChan(conn net.Conn) <-chan string {
 | 
			
		||||
	ch := make(chan string)
 | 
			
		||||
	reader := bufio.NewReader(conn)
 | 
			
		||||
	addr := conn.RemoteAddr()
 | 
			
		||||
	go func() {
 | 
			
		||||
		for {
 | 
			
		||||
			line, err := readTrimmedLine(reader)
 | 
			
		||||
			if line != "" {
 | 
			
		||||
				ch <- line
 | 
			
		||||
				log.Printf("%s -> %s", addr, line)
 | 
			
		||||
			}
 | 
			
		||||
			if err != nil {
 | 
			
		||||
				break
 | 
			
		||||
			}
 | 
			
		||||
			ch <- line
 | 
			
		||||
		}
 | 
			
		||||
		close(ch)
 | 
			
		||||
	}()
 | 
			
		||||
@ -36,14 +34,12 @@ func StringReadChan(conn net.Conn) <-chan string {
 | 
			
		||||
func StringWriteChan(conn net.Conn) chan<- string {
 | 
			
		||||
	ch := make(chan string)
 | 
			
		||||
	writer := bufio.NewWriter(conn)
 | 
			
		||||
	addr := conn.RemoteAddr()
 | 
			
		||||
	go func() {
 | 
			
		||||
		for str := range ch {
 | 
			
		||||
			if _, err := writer.WriteString(str + "\r\n"); err != nil {
 | 
			
		||||
			if _, err := writer.WriteString(str); err != nil {
 | 
			
		||||
				break
 | 
			
		||||
			}
 | 
			
		||||
			writer.Flush()
 | 
			
		||||
			log.Printf("%s <- %s", addr, str)
 | 
			
		||||
		}
 | 
			
		||||
		close(ch)
 | 
			
		||||
	}()
 | 
			
		||||
 | 
			
		||||
@ -26,15 +26,13 @@ var (
 | 
			
		||||
	}
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func ParseMessage(line string) (msg Message, err error) {
 | 
			
		||||
func ParseMessage(line string) (Message, error) {
 | 
			
		||||
	command, args := parseLine(line)
 | 
			
		||||
	constructor, ok := parseCommandFuncs[command]
 | 
			
		||||
	if !ok {
 | 
			
		||||
		msg = &UnknownMessage{command}
 | 
			
		||||
		return
 | 
			
		||||
		return &UnknownMessage{command, args}, nil
 | 
			
		||||
	}
 | 
			
		||||
	msg, err = constructor(args)
 | 
			
		||||
	return
 | 
			
		||||
	return constructor(args)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func parseArg(line string) (arg string, rest string) {
 | 
			
		||||
 | 
			
		||||
@ -21,8 +21,8 @@ type BasicReply struct {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (reply *BasicReply) String(client *Client) string {
 | 
			
		||||
	prefix := fmt.Sprintf(":%s %s %s ", reply.source.Id(), reply.code, client.Nick())
 | 
			
		||||
	return prefix + reply.message
 | 
			
		||||
	return fmt.Sprintf(":%s %s %s %s\r\n", reply.source.Id(), reply.code, client.Nick(),
 | 
			
		||||
		reply.message)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type ChannelReply struct {
 | 
			
		||||
@ -31,8 +31,8 @@ type ChannelReply struct {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (reply *ChannelReply) String(client *Client) string {
 | 
			
		||||
	prefix := fmt.Sprintf(":%s %s %s ", reply.source.Id(), reply.code, reply.channel.name)
 | 
			
		||||
	return prefix + reply.message
 | 
			
		||||
	return fmt.Sprintf(":%s %s %s %s\r\n", reply.source.Id(), reply.code, reply.channel.name,
 | 
			
		||||
		reply.message)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func NewReply(source Identifier, code string, message string) *BasicReply {
 | 
			
		||||
@ -99,11 +99,11 @@ func RplPart(channel *Channel, client *Client, message string) Reply {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func RplNoTopic(channel *Channel) Reply {
 | 
			
		||||
	return &ChannelReply{NewReply(channel.server, RPL_NOTOPIC, ":No topic is set"), channel}
 | 
			
		||||
	return NewReply(channel.server, RPL_NOTOPIC, channel.name+" :No topic is set")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func RplTopic(channel *Channel) Reply {
 | 
			
		||||
	return &ChannelReply{NewReply(channel.server, RPL_TOPIC, ":"+channel.topic), channel}
 | 
			
		||||
	return NewReply(channel.server, RPL_TOPIC, fmt.Sprintf("%s :%s", channel.name, channel.topic))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// server info
 | 
			
		||||
@ -119,7 +119,7 @@ func RplEndOfNames(source Identifier) Reply {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func RplPong(server *Server) Reply {
 | 
			
		||||
	return NewReply(server, RPL_PONG, "")
 | 
			
		||||
	return NewReply(server, RPL_PONG, server.Id())
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// server functions
 | 
			
		||||
 | 
			
		||||
@ -33,6 +33,7 @@ func NewServer(name string) *Server {
 | 
			
		||||
	}
 | 
			
		||||
	go func() {
 | 
			
		||||
		for m := range recv {
 | 
			
		||||
			log.Printf("%s -> %T%+v", m.client.Id(), m.message, m.message)
 | 
			
		||||
			m.message.Handle(server, m.client)
 | 
			
		||||
		}
 | 
			
		||||
	}()
 | 
			
		||||
@ -120,7 +121,7 @@ func (s *Server) UserLogin(c *Client, user string, realName string) {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (s *Server) tryRegister(c *Client) {
 | 
			
		||||
	if !c.registered && c.HasNick() && c.HasUser() && (s.password == "" || c.serverAuth) {
 | 
			
		||||
	if !c.registered && c.HasNick() && c.HasUser() && (s.password == "" || c.serverPass) {
 | 
			
		||||
		c.registered = true
 | 
			
		||||
		c.send <- RplWelcome(s, c)
 | 
			
		||||
		c.send <- RplYourHost(s, c)
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user