From 7767f3e52b8ad0fb23d8b146a0dea14c83edd7ce Mon Sep 17 00:00:00 2001 From: "Andreas Renberg (IQAndreas)" Date: Sat, 13 Dec 2014 01:14:18 -0600 Subject: [PATCH 1/3] Add basic terminal color support Also added a little command to test color support. This will come in handy! --- client.go | 3 +++ colors.go | 24 ++++++++++++++++++++++++ 2 files changed, 27 insertions(+) create mode 100644 colors.go diff --git a/client.go b/client.go index 7cc7fce..53bdd61 100644 --- a/client.go +++ b/client.go @@ -119,6 +119,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": 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 +} From 1b73035495f40457a362d4f2166e8f3773f23ef4 Mon Sep 17 00:00:00 2001 From: "Andreas Renberg (IQAndreas)" Date: Sat, 13 Dec 2014 01:32:48 -0600 Subject: [PATCH 2/3] Color usernames with colors (at least next to their messages) --- client.go | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/client.go b/client.go index 53bdd61..0b6b81d 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,6 +49,7 @@ 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), } @@ -83,7 +85,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] ", ColorString(c.Color, c.Name))) } func (c *Client) Fingerprint() string { @@ -222,7 +224,7 @@ func (c *Client) handleShell(channel ssh.Channel) { continue } - msg := fmt.Sprintf("%s: %s", c.Name, line) + msg := fmt.Sprintf("%s: %s", ColorString(c.Color, c.Name), line) if c.IsSilenced() || len(msg) > 1000 { c.Msg <- fmt.Sprintf("-> Message rejected.") continue @@ -233,7 +235,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] ", ColorString(c.Color, c.Name)) hasShell := false From d22e80d2c1d7bbd5bf7711d51ea24fbc3b9b1593 Mon Sep 17 00:00:00 2001 From: "Andreas Renberg (IQAndreas)" Date: Sat, 13 Dec 2014 01:42:23 -0600 Subject: [PATCH 3/3] Make the user's name colored in all messages --- client.go | 22 +++++++++++++--------- server.go | 6 +++--- 2 files changed, 16 insertions(+), 12 deletions(-) diff --git a/client.go b/client.go index 0b6b81d..33bd4f7 100644 --- a/client.go +++ b/client.go @@ -55,6 +55,10 @@ func NewClient(server *Server, conn *ssh.ServerConn) *Client { } } +func (c *Client) ColoredName() string { + return ColorString(c.Color, c.Name) +} + func (c *Client) Write(msg string) { c.term.Write([]byte(msg + "\r\n")) } @@ -85,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] ", ColorString(c.Color, c.Name))) + c.term.SetPrompt(fmt.Sprintf("[%s] ", c.ColoredName())) } func (c *Client) Fingerprint() string { @@ -135,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 { @@ -155,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]) } @@ -176,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": @@ -193,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) } } @@ -215,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: @@ -224,7 +228,7 @@ func (c *Client) handleShell(channel ssh.Channel) { continue } - msg := fmt.Sprintf("%s: %s", ColorString(c.Color, c.Name), line) + msg := fmt.Sprintf("%s: %s", c.ColoredName(), line) if c.IsSilenced() || len(msg) > 1000 { c.Msg <- fmt.Sprintf("-> Message rejected.") continue @@ -235,7 +239,7 @@ func (c *Client) handleShell(channel ssh.Channel) { } func (c *Client) handleChannels(channels <-chan ssh.NewChannel) { - prompt := fmt.Sprintf("[%s] ", ColorString(c.Color, c.Name)) + prompt := fmt.Sprintf("[%s] ", c.ColoredName()) hasShell := false diff --git a/server.go b/server.go index 11bd2ff..9d1dcba 100644 --- a/server.go +++ b/server.go @@ -91,7 +91,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 to change it.", client.Name, newName) + client.Msg <- fmt.Sprintf("-> Your name '%s' is not available, renamed to '%s'. Use /nick to change it.", client.ColoredName(), ColorString(client.Color, newName)) } client.Rename(newName) @@ -99,7 +99,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) { @@ -107,7 +107,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) {