Strip @ prefix on names in commands

Names can be passed to commands with @ prefixed to them.

When forcing a color change on another user the @ explicitly defines
the name, instead of simply being stripped off.  This will allow the
a user named "red" to have their color changed: `/color @red blue`

A bunch of the color command code has changed with this to make things
less ambiguous and to add some other checks.  `/color red #FF0000` and
`/color @red red` will change the color of the user "red" to the color
red while `/color red red`will return with an error.  Note that the
color an name arguments can be in any order.

Resolves #64
This commit is contained in:
Zorchenhimer 2019-03-24 15:15:28 -04:00
parent 87f8839a33
commit 2f252d5ae8
3 changed files with 84 additions and 27 deletions

View File

@ -94,16 +94,18 @@ var commands = &CommandControl{
return "Missing name to change to." return "Missing name to change to."
} }
newName := args[0] newName := strings.TrimLeft(args[0], "@")
oldName := cl.name oldName := cl.name
forced := false forced := false
// Two arguments to force a name change on another user: `/nick OldName NewName`
if len(args) == 2 { if len(args) == 2 {
if !cl.IsAdmin { if !cl.IsAdmin {
return "Only admins can do that PeepoSus" return "Only admins can do that PeepoSus"
} }
oldName = args[0] oldName = strings.TrimLeft(args[0], "@")
newName = args[1] newName = strings.TrimLeft(args[1], "@")
forced = true forced = true
} }
@ -182,18 +184,19 @@ var commands = &CommandControl{
return "You can only unmod yourself, not others." return "You can only unmod yourself, not others."
} }
if len(args) == 0 || (len(args) == 1 && args[0] == cl.name) { if len(args) == 0 || (len(args) == 1 && strings.TrimLeft(args[0], "@") == cl.name) {
cl.Unmod() cl.Unmod()
cl.belongsTo.AddModNotice(cl.name + " has unmodded themselves") cl.belongsTo.AddModNotice(cl.name + " has unmodded themselves")
return "You have unmodded yourself." return "You have unmodded yourself."
} }
name := strings.TrimLeft(args[0], "@")
if err := cl.belongsTo.Unmod(args[0]); err != nil { if err := cl.belongsTo.Unmod(name); err != nil {
return err.Error() return err.Error()
} }
cl.belongsTo.AddModNotice(cl.name + " has unmodded " + args[0]) cl.belongsTo.AddModNotice(cl.name + " has unmodded " + name)
return fmt.Sprintf(`%s has been unmodded.`, args[0]) return ""
}, },
}, },
@ -203,7 +206,7 @@ var commands = &CommandControl{
if len(args) == 0 { if len(args) == 0 {
return "Missing name to kick." return "Missing name to kick."
} }
return cl.belongsTo.Kick(args[0]) return cl.belongsTo.Kick(strings.TrimLeft(args[0], "@"))
}, },
}, },
@ -213,8 +216,10 @@ var commands = &CommandControl{
if len(args) == 0 { if len(args) == 0 {
return "missing name to ban." return "missing name to ban."
} }
fmt.Printf("[ban] Attempting to ban %s\n", strings.Join(args, ""))
return cl.belongsTo.Ban(args[0]) name := strings.TrimLeft(args[0], "@")
fmt.Printf("[ban] Attempting to ban %s\n", name)
return cl.belongsTo.Ban(name)
}, },
}, },
@ -224,13 +229,14 @@ var commands = &CommandControl{
if len(args) == 0 { if len(args) == 0 {
return "missing name to unban." return "missing name to unban."
} }
fmt.Printf("[ban] Attempting to unban %s\n", strings.Join(args, "")) name := strings.TrimLeft(args[0], "@")
fmt.Printf("[ban] Attempting to unban %s\n", name)
err := settings.RemoveBan(args[0]) err := settings.RemoveBan(name)
if err != nil { if err != nil {
return err.Error() return err.Error()
} }
cl.belongsTo.AddModNotice(cl.name + " has unbanned " + args[0]) cl.belongsTo.AddModNotice(cl.name + " has unbanned " + name)
return "" return ""
}, },
}, },
@ -252,11 +258,13 @@ var commands = &CommandControl{
if len(args) == 0 { if len(args) == 0 {
return "Missing user to mod." return "Missing user to mod."
} }
if err := cl.belongsTo.Mod(args[0]); err != nil {
name := strings.TrimLeft(args[0], "@")
if err := cl.belongsTo.Mod(name); err != nil {
return err.Error() return err.Error()
} }
cl.belongsTo.AddModNotice(cl.name + " has modded " + args[0]) cl.belongsTo.AddModNotice(cl.name + " has modded " + name)
return fmt.Sprintf(`%s has been modded.`, args[0]) return ""
}, },
}, },
@ -387,22 +395,71 @@ func getHelp(lvl common.CommandLevel) map[string]string {
var cmdColor = Command{ var cmdColor = Command{
HelpText: "Change user color.", HelpText: "Change user color.",
Function: func(cl *Client, args []string) string { Function: func(cl *Client, args []string) string {
if len(args) > 2 {
return "Too many arguments!"
}
// If the caller is priviledged enough, they can change the color of another user // If the caller is priviledged enough, they can change the color of another user
if len(args) == 2 && (cl.IsMod || cl.IsAdmin) { if len(args) == 2 {
color := "" if !(cl.IsMod || cl.IsAdmin) {
name := "" return "You cannot change someone else's color. PeepoSus"
for _, s := range args {
if common.IsValidColor(s) {
color = s
} else {
name = s
} }
name, color := "", ""
if strings.ToLower(args[0]) == strings.ToLower(args[1]) ||
(common.IsValidColor(args[0]) && common.IsValidColor(args[1])) {
return "Name and color are ambiguous. Prefix the name with '@' or color with '#'"
} }
// Check for explicit name
if strings.HasPrefix(args[0], "@") {
name = strings.TrimLeft(args[0], "@")
color = args[1]
fmt.Println("Found explicit name: ", name)
} else if strings.HasPrefix(args[1], "@") {
name = strings.TrimLeft(args[1], "@")
color = args[0]
fmt.Println("Found explicit name: ", name)
// Check for explicit color
} else if strings.HasPrefix(args[0], "#") {
name = strings.TrimPrefix(args[1], "@") // this shouldn't be needed, but just in case.
color = args[0]
fmt.Println("Found explicit color: ", color)
} else if strings.HasPrefix(args[1], "#") {
name = strings.TrimPrefix(args[0], "@") // this shouldn't be needed, but just in case.
color = args[1]
fmt.Println("Found explicit color: ", color)
// Guess
} else if common.IsValidColor(args[0]) {
name = strings.TrimPrefix(args[1], "@")
color = args[0]
fmt.Println("Guessed name: ", name, " and color: ", color)
} else if common.IsValidColor(args[1]) {
name = strings.TrimPrefix(args[0], "@")
color = args[1]
fmt.Println("Guessed name: ", name, " and color: ", color)
}
if name == "" {
return "Cannot determine name. Prefix name with @."
}
if color == "" {
return "Cannot determine color. Prefix name with @."
}
if color == "" { if color == "" {
fmt.Printf("[color:mod] %s missing color\n", cl.name) fmt.Printf("[color:mod] %s missing color\n", cl.name)
return "Missing color" return "Missing color"
} }
if name == "" {
fmt.Printf("[color:mod] %s missing name\n", cl.name)
return "Missing name"
}
if err := cl.belongsTo.ForceColorChange(name, color); err != nil { if err := cl.belongsTo.ForceColorChange(name, color); err != nil {
return err.Error() return err.Error()
} }

View File

@ -85,7 +85,7 @@ func (cr *ChatRoom) Join(name, uid string) (*Client, error) {
return nil, errors.New("connection is missing from temp connections") return nil, errors.New("connection is missing from temp connections")
} }
if !common.IsValidName(name) || common.IsValidColor(name) { if !common.IsValidName(name) {
return nil, UserFormatError{Name: name} return nil, UserFormatError{Name: name}
} }

View File

@ -12,5 +12,5 @@ var usernameRegex *regexp.Regexp = regexp.MustCompile(`^[0-9a-zA-Z_-]+$`)
// and is not a valid color name // and is not a valid color name
func IsValidName(name string) bool { func IsValidName(name string) bool {
return 3 <= len(name) && len(name) <= 36 && return 3 <= len(name) && len(name) <= 36 &&
usernameRegex.MatchString(name) && !IsValidColor(name) usernameRegex.MatchString(name)
} }