diff --git a/client.go b/client.go index 7cc7fce..33bd4f7 100644 --- a/client.go +++ b/client.go @@ -35,6 +35,7 @@ type Client struct { Conn *ssh.ServerConn Msg chan string Name string + Color string Op bool ready chan struct{} term *terminal.Terminal @@ -48,11 +49,16 @@ func NewClient(server *Server, conn *ssh.ServerConn) *Client { Server: server, Conn: conn, Name: conn.User(), + Color: RandomColor(), Msg: make(chan string, MSG_BUFFER), ready: make(chan struct{}, 1), } } +func (c *Client) ColoredName() string { + return ColorString(c.Color, c.Name) +} + func (c *Client) Write(msg string) { c.term.Write([]byte(msg + "\r\n")) } @@ -83,7 +89,7 @@ func (c *Client) Resize(width int, height int) error { func (c *Client) Rename(name string) { c.Name = name - c.term.SetPrompt(fmt.Sprintf("[%s] ", name)) + c.term.SetPrompt(fmt.Sprintf("[%s] ", c.ColoredName())) } func (c *Client) Fingerprint() string { @@ -119,6 +125,9 @@ func (c *Client) handleShell(channel ssh.Channel) { if isCmd { // TODO: Factor this out. switch parts[0] { + case "/test-colors": // Shh, this command is a secret! + c.Write(ColorString("32", "Lorem ipsum dolor sit amet,")) + c.Write("consectetur " + ColorString("31;1", "adipiscing") + " elit.") case "/exit": channel.Close() case "/help": @@ -130,7 +139,7 @@ func (c *Client) handleShell(channel ssh.Channel) { if me == "" { me = " is at a loss for words." } - msg := fmt.Sprintf("** %s%s", c.Name, me) + msg := fmt.Sprintf("** %s%s", c.ColoredName(), me) if c.IsSilenced() || len(msg) > 1000 { c.Msg <- fmt.Sprintf("-> Message rejected.") } else { @@ -150,7 +159,7 @@ func (c *Client) handleShell(channel ssh.Channel) { if len(version) > 100 { version = "Evil Jerk with a superlong string" } - c.Msg <- fmt.Sprintf("-> %s is %s via %s", client.Name, client.Fingerprint(), version) + c.Msg <- fmt.Sprintf("-> %s is %s via %s", client.ColoredName(), client.Fingerprint(), version) } else { c.Msg <- fmt.Sprintf("-> No such name: %s", parts[1]) } @@ -171,10 +180,10 @@ func (c *Client) handleShell(channel ssh.Channel) { c.Msg <- fmt.Sprintf("-> No such name: %s", parts[1]) } else { fingerprint := client.Fingerprint() - client.Write(fmt.Sprintf("-> Banned by %s.", c.Name)) + client.Write(fmt.Sprintf("-> Banned by %s.", c.ColoredName())) c.Server.Ban(fingerprint, nil) client.Conn.Close() - c.Server.Broadcast(fmt.Sprintf("* %s was banned by %s", parts[1], c.Name), nil) + c.Server.Broadcast(fmt.Sprintf("* %s was banned by %s", parts[1], c.ColoredName()), nil) } } case "/op": @@ -188,7 +197,7 @@ func (c *Client) handleShell(channel ssh.Channel) { c.Msg <- fmt.Sprintf("-> No such name: %s", parts[1]) } else { fingerprint := client.Fingerprint() - client.Write(fmt.Sprintf("-> Made op by %s.", c.Name)) + client.Write(fmt.Sprintf("-> Made op by %s.", c.ColoredName())) c.Server.Op(fingerprint) } } @@ -210,7 +219,7 @@ func (c *Client) handleShell(channel ssh.Channel) { c.Msg <- fmt.Sprintf("-> No such name: %s", parts[1]) } else { client.Silence(duration) - client.Write(fmt.Sprintf("-> Silenced for %s by %s.", duration, c.Name)) + client.Write(fmt.Sprintf("-> Silenced for %s by %s.", duration, c.ColoredName())) } } default: @@ -219,7 +228,7 @@ func (c *Client) handleShell(channel ssh.Channel) { continue } - msg := fmt.Sprintf("%s: %s", c.Name, line) + msg := fmt.Sprintf("%s: %s", c.ColoredName(), line) if c.IsSilenced() || len(msg) > 1000 { c.Msg <- fmt.Sprintf("-> Message rejected.") continue @@ -230,7 +239,7 @@ func (c *Client) handleShell(channel ssh.Channel) { } func (c *Client) handleChannels(channels <-chan ssh.NewChannel) { - prompt := fmt.Sprintf("[%s] ", c.Name) + prompt := fmt.Sprintf("[%s] ", c.ColoredName()) hasShell := false diff --git a/colors.go b/colors.go new file mode 100644 index 0000000..16e8ad9 --- /dev/null +++ b/colors.go @@ -0,0 +1,24 @@ +package main + +import ( + "math/rand" + "time" +) + +const RESET string = "\033[0m" +const BOLD string = "\033[1m" +const DIM string = "\033[2m" +const UNDERLINE string = "\033[4m" +const BLINK string = "\033[5m" +const INVERT string = "\033[7m" + +var colors = []string { "31", "32", "33", "34", "35", "36", "37", "91", "92", "93", "94", "95", "96", "97" } + +func RandomColor() string { + rand.Seed(time.Now().UTC().UnixNano()) + return colors[rand.Intn(len(colors))] +} + +func ColorString(format string, msg string) string { + return BOLD + "\033[" + format + "m" + msg + RESET +} diff --git a/server.go b/server.go index 72f8506..abdd61e 100644 --- a/server.go +++ b/server.go @@ -99,7 +99,7 @@ func (s *Server) Add(client *Client) { newName, err := s.proposeName(client.Name) if err != nil { - client.Msg <- fmt.Sprintf("-> Your name '%s' is not available, renamed to '%s'. Use /nick <name> to change it.", client.Name, newName) + client.Msg <- fmt.Sprintf("-> Your name '%s' is not available, renamed to '%s'. Use /nick <name> to change it.", client.ColoredName(), ColorString(client.Color, newName)) } client.Rename(newName) @@ -107,7 +107,7 @@ func (s *Server) Add(client *Client) { num := len(s.clients) s.lock.Unlock() - s.Broadcast(fmt.Sprintf("* %s joined. (Total connected: %d)", client.Name, num), client) + s.Broadcast(fmt.Sprintf("* %s joined. (Total connected: %d)", client.ColoredName(), num), client) } func (s *Server) Remove(client *Client) { @@ -115,7 +115,7 @@ func (s *Server) Remove(client *Client) { delete(s.clients, client.Name) s.lock.Unlock() - s.Broadcast(fmt.Sprintf("* %s left.", client.Name), nil) + s.Broadcast(fmt.Sprintf("* %s left.", client.ColoredName()), nil) } func (s *Server) proposeName(name string) (string, error) {