Super broken but kinda working.

This commit is contained in:
Andrey Petrov 2014-12-22 22:21:07 -08:00
parent a1d5cc6735
commit eda2b7c0d9
7 changed files with 75 additions and 54 deletions

View File

@ -7,7 +7,6 @@ const channelBuffer = 10
// Channel definition, also a Set of User Items
type Channel struct {
id string
topic string
history *History
users *Set
@ -15,11 +14,10 @@ type Channel struct {
}
// Create new channel and start broadcasting goroutine.
func NewChannel(id string) *Channel {
func NewChannel() *Channel {
broadcast := make(chan Message, channelBuffer)
ch := Channel{
id: id,
broadcast: broadcast,
history: NewHistory(historyLen),
users: NewSet(),
@ -27,8 +25,14 @@ func NewChannel(id string) *Channel {
go func() {
for m := range broadcast {
// TODO: Handle commands etc?
ch.users.Each(func(u Item) {
u.(*User).Send(m)
user := u.(*User)
if m.from == user {
// Skip
return
}
user.Send(m)
})
}
}()

View File

@ -11,7 +11,7 @@ func TestChannel(t *testing.T) {
s := &MockScreen{}
u := NewUser("foo")
ch := NewChannel("")
ch := NewChannel()
defer ch.Close()
err := ch.Join(u)

View File

@ -8,7 +8,7 @@ import (
var ErrInvalidCommand error = errors.New("invalid command")
var ErrNoOwner error = errors.New("command without owner")
type CmdHandler func(host Host, msg Message, args []string) error
type CmdHandler func(msg Message, args []string) error
type Commands map[string]CmdHandler
@ -18,7 +18,7 @@ func (c Commands) Add(cmd string, handler CmdHandler) {
}
// Execute command message, assumes IsCommand was checked
func (c Commands) Run(host Host, msg Message) error {
func (c Commands) Run(msg Message) error {
if msg.from == nil {
return ErrNoOwner
}
@ -29,7 +29,7 @@ func (c Commands) Run(host Host, msg Message) error {
return ErrInvalidCommand
}
return handler(host, msg, args)
return handler(msg, args)
}
var defaultCmdHandlers Commands
@ -37,7 +37,7 @@ var defaultCmdHandlers Commands
func init() {
c := Commands{}
c.Add("me", func(host Host, msg Message, args []string) error {
c.Add("me", func(msg Message, args []string) error {
me := strings.TrimLeft(msg.Body, "/me")
if me == "" {
me = " is at a loss for words."

View File

@ -1,28 +0,0 @@
package chat
// Host knows about all the commands and channels.
type Host struct {
defaultChannel *Channel
commands Commands
done chan struct{}
}
func NewHost() *Host {
h := Host{
commands: defaultCmdHandlers,
}
h.defaultChannel = h.CreateChannel("")
return &h
}
func (h *Host) handleCommand(m Message) {
// TODO: ...
}
func (h *Host) broadcast(ch *Channel, m Message) {
// TODO: ...
}
func (h *Host) CreateChannel(id string) *Channel {
return NewChannel(id)
}

View File

@ -9,8 +9,9 @@ import (
// Container for messages sent to chat
type Message struct {
Body string
from *User // Not set for Sys messages
to *User // Only set for PMs
from *User // Not set for Sys messages
to *User // Only set for PMs
channel *Channel // Not set for global commands
timestamp time.Time
themeCache *map[*Theme]string
}
@ -35,6 +36,12 @@ func (m *Message) From(u *User) *Message {
return m
}
// Set channel
func (m *Message) Channel(ch *Channel) *Message {
m.channel = ch
return m
}
// Render message based on the given theme
func (m *Message) Render(*Theme) string {
// TODO: Return []byte?

65
cmd.go
View File

@ -1,7 +1,6 @@
package main
import (
"bufio"
"fmt"
"io/ioutil"
"net/http"
@ -13,6 +12,10 @@ import (
"github.com/alexcesaro/log"
"github.com/alexcesaro/log/golog"
"github.com/jessevdk/go-flags"
"golang.org/x/crypto/ssh"
"github.com/shazow/ssh-chat/chat"
"github.com/shazow/ssh-chat/sshd"
)
import _ "net/http/pprof"
@ -52,9 +55,6 @@ func main() {
}()
}
// Initialize seed for random colors
RandomColorInit()
// Figure out the log level
numVerbose := len(options.Verbose)
if numVerbose > len(logLevels) {
@ -78,12 +78,55 @@ func main() {
return
}
server, err := NewServer(privateKey)
signer, err := ssh.ParsePrivateKey(privateKey)
if err != nil {
logger.Errorf("Failed to create server: %v", err)
logger.Errorf("Failed to prase key: %v", err)
return
}
// TODO: MakeAuth
config := sshd.MakeNoAuth()
config.AddHostKey(signer)
s, err := sshd.ListenSSH(options.Bind, config)
if err != nil {
logger.Errorf("Failed to listen on socket: %v", err)
return
}
defer s.Close()
terminals := s.ServeTerminal()
channel := chat.NewChannel()
// TODO: Move this elsewhere
go func() {
for term := range terminals {
go func() {
defer term.Close()
name := term.Conn.User()
term.SetPrompt(fmt.Sprintf("[%s]", name))
// TODO: term.AutoCompleteCallback = ...
user := chat.NewUserScreen(name, term)
channel.Join(user)
for {
// TODO: Handle commands etc?
line, err := term.ReadLine()
if err != nil {
break
}
m := chat.NewMessage(line).From(user)
channel.Send(*m)
}
// TODO: Handle disconnect sooner (currently closes channel before removing)
channel.Leave(user)
user.Close()
}()
}
}()
/* TODO:
for _, fingerprint := range options.Admin {
server.Op(fingerprint)
}
@ -109,23 +152,17 @@ func main() {
return
}
motdString := string(motd[:])
/* hack to normalize line endings into \r\n */
// hack to normalize line endings into \r\n
motdString = strings.Replace(motdString, "\r\n", "\n", -1)
motdString = strings.Replace(motdString, "\n", "\r\n", -1)
server.SetMotd(motdString)
}
*/
// Construct interrupt handler
sig := make(chan os.Signal, 1)
signal.Notify(sig, os.Interrupt)
err = server.Start(options.Bind)
if err != nil {
logger.Errorf("Failed to start server: %v", err)
return
}
<-sig // Wait for ^C signal
logger.Warningf("Interrupt signal detected, shutting down.")
server.Stop()
}

View File

@ -11,6 +11,7 @@ package sshd
if err != nil {
// Handle opening socket error
}
defer s.Close()
terminals := s.ServeTerminal()
@ -21,7 +22,7 @@ package sshd
term.AutoCompleteCallback = nil // ...
for {
line, err := term.Readline()
line, err := term.ReadLine()
if err != nil {
break
}