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