From a47cbc3617e3c3dcb89f30aad9915cca2f8e9438 Mon Sep 17 00:00:00 2001 From: TechnoStrife Date: Sat, 8 Aug 2020 22:44:27 +0300 Subject: [PATCH] Add documentation for each command --- commands/admin/ban.go | 11 +-- commands/admin/config.go | 55 ++++++++++++-- commands/admin/kick.go | 11 ++- commands/admin/mod.go | 48 +++++++++++-- commands/admin/save.go | 5 ++ commands/admin/server.go | 19 ++++- commands/admin/unban.go | 9 ++- commands/commands.go | 146 ++++++++++++++++++++++++++++++-------- commands/utils/mods.go | 14 +++- commands/utils/version.go | 6 +- support/utils.go | 7 ++ 11 files changed, 280 insertions(+), 51 deletions(-) diff --git a/commands/admin/ban.go b/commands/admin/ban.go index 3073e65..49f94c9 100644 --- a/commands/admin/ban.go +++ b/commands/admin/ban.go @@ -8,13 +8,16 @@ import ( "github.com/maxsupermanhd/FactoCord-3.0/support" ) -// BanPlayerUsage comment... -var BanPlayerUsage = "Usage: $ban " +var BanPlayerDoc = support.CommandDoc{ + Name: "ban", + Usage: "$ban ", + Doc: `command bans the player on the server with a specified reason`, +} // BanPlayer bans a player on the server. func BanPlayer(s *discordgo.Session, args string) { if len(args) == 0 { - support.SendFormat(s, BanPlayerUsage) + support.SendFormat(s, "Usage: "+BanPlayerDoc.Usage) return } args2 := strings.SplitN(args+" ", " ", 2) @@ -22,7 +25,7 @@ func BanPlayer(s *discordgo.Session, args string) { reason := strings.TrimSpace(args2[1]) if len(player) == 0 || len(reason) == 0 { - support.SendFormat(s, BanPlayerUsage) + support.SendFormat(s, "Usage: "+BanPlayerDoc.Usage) return } diff --git a/commands/admin/config.go b/commands/admin/config.go index 609bece..1c7535b 100644 --- a/commands/admin/config.go +++ b/commands/admin/config.go @@ -12,19 +12,66 @@ import ( "github.com/maxsupermanhd/FactoCord-3.0/support" ) -// ModCommandUsage ... -var ConfigCommandUsage = "Usage: $config save | load | get | set " +var ConfigCommandDoc = support.CommandDoc{ + Name: "config", + Usage: "$config save | load | get | set ?", + Doc: "command manages FactoCord's config", + Subcommands: []support.CommandDoc{ + {Name: "save", Doc: "command saves FactoCord's config from memory to `config.json`"}, + { + Name: "load", + Doc: "command loads the config from `config.json`.\n" + + "Any unsaved changes after the last `$config save` command will be lost.", + }, + { + Name: "get", + Usage: "$config get ?", + Doc: "command outputs the value of a config setting specified by .\n" + + "All path members are separated by a dot '.'\n" + + "If the path is empty, it outputs the whole config.\n" + + "Examples:\n" + + "```\n" + + "$config get\n" + + "$config get admin_ids\n" + + "$config get admin_ids.0\n" + + "$config get command_roles\n" + + "$config get command_roles.mod\n" + + "$config get messages\n" + + "```", + }, + { + Name: "set", + Usage: "$config set \n" + + "$config set ", + Doc: "command sets the value of a config setting specified by .\n" + + "This command can set only simple types such as strings, numbers, and booleans.\n" + + "If no value is specified, this command deletes the value if possible, otherwise it sets it to a zero-value (0, \"\", false).\n" + + "To add a value to an array or an object specify it's index as '*' (e.g. `$config set admin_ids.* 1234`).\n" + + "Changes made by this command are not automatically saved. Use `$config save` to do it.\n" + + "Examples:" + + "```\n" + + "$config set prefix !\n" + + "$config set game_name \"Factorio 1.0\"\n" + + "$config set ingame_discord_user_colors true\n" + + "$config set admin_ids.0 123456789\n" + + "$config set admin_ids.* 987654321\n" + + "$config set command_roles.mod 55555555\n" + + "$config set messages.server_save **:mango: Game saved!**\n" + + "```", + }, + }, +} // ModCommand returns the list of mods running on the server. func ConfigCommand(s *discordgo.Session, args string) { if args == "" { - support.SendFormat(s, ConfigCommandUsage) + support.SendFormat(s, "Usage: "+ConfigCommandDoc.Usage) return } action, args := support.SplitDivide(args, " ") args = strings.TrimSpace(args) if _, ok := commands[action]; !ok { - support.SendFormat(s, ConfigCommandUsage) + support.SendFormat(s, "Usage: "+ConfigCommandDoc.Usage) return } res := commands[action](args) diff --git a/commands/admin/kick.go b/commands/admin/kick.go index 0d9eef2..db3a415 100644 --- a/commands/admin/kick.go +++ b/commands/admin/kick.go @@ -9,12 +9,17 @@ import ( ) // KickPlayerUsage comment... -var KickPlayerUsage = "Usage: $kick " + +var KickPlayerDoc = support.CommandDoc{ + Name: "kick", + Usage: "$kick ", + Doc: `command kicks the player out from the server with a specified reason`, +} // KickPlayer kicks a player from the server. func KickPlayer(s *discordgo.Session, args string) { if len(args) == 0 { - support.SendFormat(s, KickPlayerUsage) + support.SendFormat(s, "Usage: "+KickPlayerDoc.Usage) return } args2 := strings.SplitN(args+" ", " ", 2) @@ -22,7 +27,7 @@ func KickPlayer(s *discordgo.Session, args string) { reason := strings.TrimSpace(args2[1]) if len(player) == 0 || len(reason) == 0 { - support.SendFormat(s, KickPlayerUsage) + support.SendFormat(s, "Usage: "+KickPlayerDoc.Usage) return } command := "/kick " + player + " " + reason diff --git a/commands/admin/mod.go b/commands/admin/mod.go index 6454728..b8549bf 100644 --- a/commands/admin/mod.go +++ b/commands/admin/mod.go @@ -133,14 +133,54 @@ type modPortalResponse struct { Releases []modRelease } -// ModCommandUsage ... -var ModCommandUsage = "Usage: $mod (add|remove|enable|disable) + | update *" +var ModCommandDoc = support.CommandDoc{ + Name: "mod", + Usage: "$mod (add|remove|enable|disable) + | update *", + Doc: "command downloads, removes, enables and disables several mods.\n" + + "If mod's name contains a whitespace ' ', it's name should be quoted using double quotes (e.g. `\"Squeak Through\"`).\n" + + "All subcommands can process several mods at once. Mods' names should be separated by a whitespace.", + Subcommands: []support.CommandDoc{ + { + Name: "add", + Usage: "$mod add +", + Doc: "command adds mods to mod-list.json and downloads the latest version or a specified version.\n" + + "To download the latest version of a mod type a mod name.\n" + + "To specify a version for a mod add '==' and a version (e.g. `$mod add FNEI==0.3.4`).\n" + + "This command ensures that factorio version is the same as mod's factorio version.", + }, + { + Name: "update", + Usage: "$mod update\n" + + "$mod update +", + Doc: "command updates either the specified mods or all mods.\n" + + "To update a mod to the latest version specify mod name.\n" + + "To update a mod to a specific version type mod name, '==', and mod version (e.g. `$mod update FNEI==0.3.4`).\n" + + "To update all mods to the latest version use `$mod update`.\n" + + "This command ensures that factorio version is the same as mod's factorio version.", + }, + { + Name: "remove", + Usage: "$mod remove +", + Doc: "command removes mods from mod-list.json and deletes mods' files", + }, + { + Name: "enable", + Usage: "$mod enable +", + Doc: "command enables mods in mod-list.json", + }, + { + Name: "disable", + Usage: "$mod disable +", + Doc: "command disables mods in mod-list.json", + }, + }, +} // ModCommand returns the list of mods running on the server. func ModCommand(s *discordgo.Session, args string) { argsList := strings.SplitN(args, " ", 2) if len(argsList) == 0 { - support.SendFormat(s, ModCommandUsage) + support.SendFormat(s, "Usage: "+ModCommandDoc.Usage) return } @@ -154,7 +194,7 @@ func ModCommand(s *discordgo.Session, args string) { return } default: - support.SendFormat(s, ModCommandUsage) + support.SendFormat(s, "Usage: "+ModCommandDoc.Usage) return } diff --git a/commands/admin/save.go b/commands/admin/save.go index 9123647..86fec01 100644 --- a/commands/admin/save.go +++ b/commands/admin/save.go @@ -6,6 +6,11 @@ import ( "github.com/maxsupermanhd/FactoCord-3.0/support" ) +var SaveServerDoc = support.CommandDoc{ + Name: "save", + Doc: `command sends a command to save the game to the server`, +} + // SaveServer executes the save command on the server. func SaveServer(s *discordgo.Session, args string) { if len(args) != 0 { diff --git a/commands/admin/server.go b/commands/admin/server.go index ca97913..3d1f159 100644 --- a/commands/admin/server.go +++ b/commands/admin/server.go @@ -13,7 +13,22 @@ import ( "path/filepath" ) -var ServerCommandUsage = "Usage: $server [stop|start|restart|update ?]" +var ServerCommandDoc = support.CommandDoc{ + Name: "server", + Usage: "$server [stop|start|restart|update ?]", + Doc: `command manages factorio server`, + Subcommands: []support.CommandDoc{ + {Name: "stop", Doc: `command stops the server`}, + {Name: "start", Doc: `command starts the server`}, + {Name: "restart", Doc: `command restarts the server`}, + { + Name: "update", + Doc: `command updates to server to the newest version or to the specified version`, + Usage: "$server update\n" + + "$server update ", + }, + }, +} func ServerCommand(s *discordgo.Session, args string) { action, arg := support.SplitDivide(args, " ") @@ -34,7 +49,7 @@ func ServerCommand(s *discordgo.Session, args string) { case "update": serverUpdate(s, arg) default: - support.SendFormat(s, ServerCommandUsage) + support.SendFormat(s, "Usage: "+ServerCommandDoc.Usage) } } diff --git a/commands/admin/unban.go b/commands/admin/unban.go index 323aa7a..1d2da5e 100644 --- a/commands/admin/unban.go +++ b/commands/admin/unban.go @@ -8,13 +8,16 @@ import ( "github.com/maxsupermanhd/FactoCord-3.0/support" ) -// UnbanPlayerUsage comment... -var UnbanPlayerUsage = "Usage $unban " +var UnbanPlayerDoc = support.CommandDoc{ + Name: "unban", + Usage: "$unban ", + Doc: `command removes the player from the banlist on the server`, +} // UnbanPlayer unbans a player on the server. func UnbanPlayer(s *discordgo.Session, args string) { if strings.ContainsAny(args, " \n\t") { - support.SendFormat(s, UnbanPlayerUsage) + support.SendFormat(s, "Usage: "+UnbanPlayerDoc.Usage) return } command := "/unban " + args diff --git a/commands/commands.go b/commands/commands.go index cabeefe..33f3d3f 100644 --- a/commands/commands.go +++ b/commands/commands.go @@ -1,6 +1,7 @@ package commands import ( + "fmt" "strings" "github.com/bwmarrin/discordgo" @@ -17,6 +18,7 @@ type Command struct { Command func(s *discordgo.Session, args string) Admin bool + Doc *support.CommandDoc Desc string } @@ -24,74 +26,162 @@ type Command struct { var Commands = [...]Command{ // Admin Commands { - Name: "Server", + Name: "server", Command: admin.ServerCommand, Admin: true, - Desc: "Manage factorio server. " + admin.ServerCommandUsage, + Doc: &admin.ServerCommandDoc, + Desc: "Manage factorio server", }, { - Name: "Save", + Name: "save", Command: admin.SaveServer, Admin: true, - Desc: "Save the game.", + Doc: &admin.SaveServerDoc, + Desc: "Save the game", }, { - Name: "Kick", + Name: "kick", Command: admin.KickPlayer, Admin: true, - Desc: "Kick a user from the server. " + admin.KickPlayerUsage, + Doc: &admin.KickPlayerDoc, + Desc: "Kick a user from the server", }, { - Name: "Ban", + Name: "ban", Command: admin.BanPlayer, Admin: true, - Desc: "Ban a user from the server. " + admin.BanPlayerUsage, + Doc: &admin.BanPlayerDoc, + Desc: "Ban a user from the server", }, { - Name: "Unban", + Name: "unban", Command: admin.UnbanPlayer, Admin: true, - Desc: "Unban a user from the server. " + admin.UnbanPlayerUsage, + Doc: &admin.UnbanPlayerDoc, + Desc: "Unban a user from the server", }, { - Name: "Config", + Name: "config", Command: admin.ConfigCommand, Admin: true, - Desc: "Manage config.json. " + admin.ConfigCommandUsage, + Doc: &admin.ConfigCommandDoc, + Desc: "Manage config.json", }, { - Name: "Mod", + Name: "mod", Command: admin.ModCommand, Admin: true, - Desc: "Manage mod-list.json. " + admin.ModCommandUsage, + Doc: &admin.ModCommandDoc, + Desc: "Manage mod-list.json", }, // Util Commands { - Name: "Mods", + Name: "mods", Command: utils.ModsList, Admin: false, - Desc: "List the mods on the server. " + utils.ModListUsage, + Doc: &utils.ModListDoc, + Desc: "List the mods on the server", }, { - Name: "Version", + Name: "version", Command: utils.VersionString, Admin: false, - Desc: "Get server version " + utils.VersionStringUsage, + Doc: &utils.VersionDoc, + Desc: "Get server version", }, { - Name: "Help", + Name: "help", Admin: false, - Desc: "List the commands for Factocord", + Doc: &support.CommandDoc{ + Name: "help", + Usage: "$help\n" + + "$help \n" + + "$help ", + Doc: "command returns list of all commands and documentation about any command and its' subcommands", + }, + Desc: "List the commands for Factocord and get documentation on commands and subcommands. Try `$help help`", }, } -func helpCommand(s *discordgo.Session, m *discordgo.Message) { - var fields []*discordgo.MessageEmbedField +func helpCommand(s *discordgo.Session, args string) { + if args == "" { + helpAllCommands(s) + return + } + args = strings.ToLower(args) + commandName, subcommand := support.SplitDivide(args, " ") + for _, command := range Commands { + if command.Name == commandName { + helpOnCommand(s, command.Doc, subcommand) + return + } + } + support.Send(s, "There's no such command as \""+commandName+"\"") +} + +func helpOnCommand(s *discordgo.Session, command *support.CommandDoc, subcommandName string) { + path := support.Config.Prefix + command.Name + if subcommandName != "" { + found := false + for _, subcommand := range command.Subcommands { + if subcommand.Name == subcommandName { + command = &subcommand + path += " " + subcommandName + found = true + break + } + } + if !found { + support.Send(s, fmt.Sprintf(`Command "%s" has no subcommand "%s"`, command.Name, subcommandName)) + return + } + } + quoted := "`" + path + "`" + embed := &discordgo.MessageEmbed{ + Type: "rich", + Color: 0x6289FF, + Title: fmt.Sprintf("Documentation on `%s` command", path), + Description: support.FormatUsage(quoted + " " + command.Doc), + } + usage := command.Usage + if usage == "" { + usage = path + } + usage = support.FormatUsage(usage) + if strings.Contains(usage, "\n") { + usage = "```\n" + usage + "\n```" + } else { + usage = "`" + usage + "`" + } + embed.Fields = append(embed.Fields, &discordgo.MessageEmbedField{ + Name: "**Usage:**", + Value: usage, + }) + if len(command.Subcommands) > 0 { + subcommands := "" + for _, subcommand := range command.Subcommands { + if subcommands != "" { + subcommands += "\n" + } + subcommands += path + " " + subcommand.Name + } + subcommands = "```\n" + subcommands + "\n```" + embed.Fields = append(embed.Fields, &discordgo.MessageEmbedField{ + Name: "**Subcommands:**", + Value: support.FormatUsage(subcommands), + }) + } + support.SendEmbed(s, embed) +} + +func helpAllCommands(s *discordgo.Session) { + fields := make([]*discordgo.MessageEmbedField, 0, len(Commands)) + for _, command := range Commands { desc := support.FormatUsage(command.Desc) if roleID, exists := support.Config.CommandRoles[strings.ToLower(command.Name)]; exists { - roles, err := s.GuildRoles(m.GuildID) + roles, err := s.GuildRoles(support.GuildID) if err != nil { support.Panik(err, "... when querying guild roles") return @@ -100,15 +190,15 @@ func helpCommand(s *discordgo.Session, m *discordgo.Message) { for _, role := range roles { if role.ID == roleID { found = true - desc += " - Role \"" + role.Name + "\"" + desc = "[Role \"" + role.Name + "\"] " + desc break } } if !found { - desc += " - Role not found in guild" + desc = "[Role not found in guild] " + desc } } else if command.Admin { - desc += " - Admin Only!" + desc = "[Admin] " + desc } fields = append(fields, &discordgo.MessageEmbedField{ Name: support.Config.Prefix + command.Name, @@ -118,7 +208,7 @@ func helpCommand(s *discordgo.Session, m *discordgo.Message) { embed := &discordgo.MessageEmbed{ Type: "rich", Color: 52, - Description: "List of all commands currently available in version 3.0 of FactoCord", + Description: "List of all commands currently available in this version of FactoCord", Title: "FactoCord Commands", Fields: fields, } @@ -132,7 +222,7 @@ func RunCommand(input string, s *discordgo.Session, m *discordgo.Message) { args := strings.TrimSpace(inputvars[1]) if commandName == strings.ToLower("Help") { - helpCommand(s, m) + helpCommand(s, args) return } diff --git a/commands/utils/mods.go b/commands/utils/mods.go index cad1c5b..119adac 100644 --- a/commands/utils/mods.go +++ b/commands/utils/mods.go @@ -21,7 +21,17 @@ type Mod struct { Enabled bool } -var ModListUsage = "Usage: $mods [on | off | all | files]" +var ModListDoc = support.CommandDoc{ + Name: "mods", + Doc: `command outputs information about current mods`, + Usage: "$mods [on | off | all | files]", + Subcommands: []support.CommandDoc{ + {Name: "on", Doc: `command sends currently enabled mods`}, + {Name: "off", Doc: `command sends currently disabled mods`}, + {Name: "all", Doc: `command sends all mods in mod-list.json`}, + {Name: "files", Doc: `command sends filenames of all downloaded mods`}, + }, +} func modList(ModList *ModJson, returnEnabled bool, returnDisabled bool) string { var enabled, disabled int @@ -107,7 +117,7 @@ func ModsList(s *discordgo.Session, args string) { support.Send(s, modsFiles()) return } else { - support.SendFormat(s, ModListUsage) + support.SendFormat(s, "Usage: "+ModListDoc.Usage) return } ModList := &ModJson{} diff --git a/commands/utils/version.go b/commands/utils/version.go index fabf5a5..480a09f 100644 --- a/commands/utils/version.go +++ b/commands/utils/version.go @@ -10,7 +10,11 @@ import ( "github.com/maxsupermanhd/FactoCord-3.0/support" ) -var VersionStringUsage = "Usage: $version" +var VersionDoc = support.CommandDoc{ + Name: "version", + Doc: `command outputs factorio server version and FactoCord version. +If it says that FactoCord version is unknown look into the error.log`, +} func VersionString(s *discordgo.Session, _ string) { factorioVersion, err := support.FactorioVersion() diff --git a/support/utils.go b/support/utils.go index f9939d1..4853544 100644 --- a/support/utils.go +++ b/support/utils.go @@ -327,3 +327,10 @@ func (l *TextListT) RenderNotEmpty() string { return l.Render() } } + +type CommandDoc struct { + Name string + Usage string + Doc string + Subcommands []CommandDoc +}