diff --git a/client.go b/client.go index 7e570c2..805fa5c 100644 --- a/client.go +++ b/client.go @@ -23,6 +23,7 @@ const HELP_TEXT string = SYSTEM_MESSAGE_FORMAT + `-> Available commands: /whois $NAME - Display information about another connected user. /msg $NAME $MESSAGE - Sends a private message to a user. /motd - Prints the Message of the Day + /theme [color|mono] - Set client theme ` + RESET const OP_HELP_TEXT string = SYSTEM_MESSAGE_FORMAT + `-> Available operator commands: @@ -30,6 +31,7 @@ const OP_HELP_TEXT string = SYSTEM_MESSAGE_FORMAT + `-> Available operator comma /kick $NAME - Kick em' out. /op $NAME - Promote a user to server operator. /silence $NAME - Revoke a user's ability to speak. + /shutdown $MESSAGE - Broadcast message and shutdown server /motd $MESSAGE - Sets the Message of the Day /whitelist $FINGERPRINT - Adds pubkey fingerprint to the connection whitelist ` + RESET @@ -60,6 +62,7 @@ type Client struct { silencedUntil time.Time lastTX time.Time beepMe bool + colorMe bool } func NewClient(server *Server, conn *ssh.ServerConn) *Client { @@ -71,6 +74,7 @@ func NewClient(server *Server, conn *ssh.ServerConn) *Client { Msg: make(chan string, MSG_BUFFER), ready: make(chan struct{}, 1), lastTX: time.Now(), + colorMe: true, } } @@ -83,6 +87,9 @@ func (c *Client) SysMsg(msg string, args ...interface{}) { } func (c *Client) Write(msg string) { + if(!c.colorMe) { + msg = DeColorString(msg) + } c.term.Write([]byte(msg + "\r\n")) } @@ -130,7 +137,15 @@ func (c *Client) Resize(width int, height int) error { func (c *Client) Rename(name string) { c.Name = name - c.term.SetPrompt(fmt.Sprintf("[%s] ", c.ColoredName())) + var prompt string + + if(c.colorMe) { + prompt = c.ColoredName() + } else { + prompt = c.Name + } + + c.term.SetPrompt(fmt.Sprintf("[%s] ", prompt)) } func (c *Client) Fingerprint() string { @@ -297,6 +312,24 @@ func (c *Client) handleShell(channel ssh.Channel) { client.SysMsg("Silenced for %s by %s.", duration, c.ColoredName()) } } + case "/shutdown": + if !c.Server.IsOp(c) { + c.SysMsg("You're not an admin.") + } else { + var split []string = strings.SplitN(line, " ", 2) + var msg string + if len(split) > 1 { + msg = split[1] + } else { + msg = "" + } + // Shutdown after 5 seconds + go func() { + c.Server.Broadcast(ColorString("31", msg), nil) + time.Sleep(time.Second * 5) + c.Server.Stop() + }() + } case "/msg": /* Send a PM */ /* Make sure we have a recipient and a message */ if len(parts) < 2 { @@ -325,6 +358,21 @@ func (c *Client) handleShell(channel ssh.Channel) { c.Server.SetMotd(newmotd) c.Server.MotdBroadcast(c) } + case "/theme": + if len(parts) < 2 { + c.SysMsg("Missing $THEME from: /theme $THEME") + c.SysMsg("Choose either color or mono") + } else { + // Sets colorMe attribute of client + if parts[1] == "mono" { + c.colorMe = false + } else if parts[1] == "color" { + c.colorMe = true + } + // Rename to reset prompt + c.Rename(c.Name) + } + case "/whitelist": /* whitelist a fingerprint */ if !c.Server.IsOp(c) { c.SysMsg("You're not an admin.") diff --git a/colors.go b/colors.go index 1e85441..5f16a68 100644 --- a/colors.go +++ b/colors.go @@ -5,6 +5,7 @@ import ( "strings" "math/rand" "time" + "regexp" ) const RESET string = "\033[0m" @@ -16,6 +17,13 @@ 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" } +// For removing ANSI Escapes +var deColor *regexp.Regexp = regexp.MustCompile("\033\\[[\\d;]+m") + +func DeColorString(s string) string { + s = deColor.ReplaceAllString(s, "") + return s +} func RandomColor256() string { return fmt.Sprintf("38;05;%d", rand.Intn(256)) @@ -38,4 +46,4 @@ func RandomColorInit() { // This is not HTML where you can just do a to resume your previous formatting! func ContinuousFormat(format string, str string) string { return SYSTEM_MESSAGE_FORMAT + strings.Replace(str, RESET, format, -1) + RESET -} +} \ No newline at end of file