- Timestamp:
- Mar 25, 2020, 8:03:13 PM (5 years ago)
- Location:
- trunk
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/service.go
r120 r150 13 13 const serviceNick = "BouncerServ" 14 14 15 type serviceCommandSet map[string]*serviceCommand 16 15 17 type serviceCommand struct { 16 usage string 17 desc string 18 handle func(dc *downstreamConn, params []string) error 18 usage string 19 desc string 20 handle func(dc *downstreamConn, params []string) error 21 children serviceCommandSet 19 22 } 20 23 … … 34 37 } 35 38 36 var name string 37 var params []string 38 if len(words) > 0 { 39 name = strings.ToLower(words[0]) 40 params = words[1:] 41 } 42 43 cmd, ok := serviceCommands[name] 44 if !ok { 45 sendServicePRIVMSG(dc, fmt.Sprintf(`error: unknown command %q (type "help" for a list of commands)`, name)) 39 cmd, params, err := serviceCommands.Get(words) 40 if err != nil { 41 sendServicePRIVMSG(dc, fmt.Sprintf(`error: %v (type "help" for a list of commands)`, err)) 46 42 return 47 43 } … … 52 48 } 53 49 54 var serviceCommands map[string]serviceCommand 50 func (cmds serviceCommandSet) Get(params []string) (*serviceCommand, []string, error) { 51 if len(params) == 0 { 52 return nil, nil, fmt.Errorf("no command specified") 53 } 54 55 name := params[0] 56 params = params[1:] 57 58 cmd, ok := cmds[name] 59 if !ok { 60 for k := range cmds { 61 if !strings.HasPrefix(k, name) { 62 continue 63 } 64 if cmd != nil { 65 return nil, params, fmt.Errorf("command %q is ambiguous", name) 66 } 67 cmd = cmds[k] 68 } 69 } 70 if cmd == nil { 71 return nil, params, fmt.Errorf("command %q not found", name) 72 } 73 74 if len(params) == 0 || len(cmd.children) == 0 { 75 return cmd, params, nil 76 } 77 return cmd.children.Get(params) 78 } 79 80 var serviceCommands serviceCommandSet 55 81 56 82 func init() { 57 serviceCommands = map[string]serviceCommand{83 serviceCommands = serviceCommandSet{ 58 84 "help": { 59 85 usage: "[command]", … … 61 87 handle: handleServiceHelp, 62 88 }, 63 "create-network": { 64 usage: "-addr <addr> [-name name] [-username username] [-pass pass] [-realname realname] [-nick nick]", 65 desc: "add a new network", 66 handle: handleServiceCreateNetwork, 89 "network": { 90 children: serviceCommandSet{ 91 "create": { 92 usage: "-addr <addr> [-name name] [-username username] [-pass pass] [-realname realname] [-nick nick]", 93 desc: "add a new network", 94 handle: handleServiceCreateNetwork, 95 }, 96 }, 67 97 }, 98 } 99 } 100 101 func appendServiceCommandSetHelp(cmds serviceCommandSet, prefix []string, l *[]string) { 102 for name, cmd := range cmds { 103 words := append(prefix, name) 104 if len(cmd.children) == 0 { 105 s := strings.Join(words, " ") 106 *l = append(*l, s) 107 } else { 108 appendServiceCommandSetHelp(cmd.children, words, l) 109 } 68 110 } 69 111 } … … 71 113 func handleServiceHelp(dc *downstreamConn, params []string) error { 72 114 if len(params) > 0 { 73 name := strings.ToLower(params[0]) 74 cmd, ok := serviceCommands[name] 75 if !ok { 76 return fmt.Errorf("unknown command %q", name) 115 cmd, rest, err := serviceCommands.Get(params) 116 if err != nil { 117 return err 77 118 } 119 words := params[:len(params)-len(rest)] 78 120 79 text := name 80 if cmd.usage != "" { 81 text += " " + cmd.usage 121 if len(cmd.children) > 0 { 122 var l []string 123 appendServiceCommandSetHelp(cmd.children, words, &l) 124 sendServicePRIVMSG(dc, "available commands: "+strings.Join(l, ", ")) 125 } else { 126 text := strings.Join(words, " ") 127 if cmd.usage != "" { 128 text += " " + cmd.usage 129 } 130 text += ": " + cmd.desc 131 132 sendServicePRIVMSG(dc, text) 82 133 } 83 text += ": " + cmd.desc84 85 sendServicePRIVMSG(dc, text)86 134 } else { 87 135 var l []string 88 for name := range serviceCommands { 89 l = append(l, name) 90 } 136 appendServiceCommandSetHelp(serviceCommands, nil, &l) 91 137 sendServicePRIVMSG(dc, "available commands: "+strings.Join(l, ", ")) 92 138 } … … 108 154 } 109 155 if *addr == "" { 110 return fmt.Errorf("flag addr is required")156 return fmt.Errorf("flag -addr is required") 111 157 } 112 158 -
trunk/soju.1.scd
r122 r150 72 72 # IRC SERVICE 73 73 74 soju exposes an IRC service called BouncerServ to manage the bouncer. Commands 75 can be sent via regular private messages (_/msg BouncerServ <command> [args...]_). 74 soju exposes an IRC service called *BouncerServ* to manage the bouncer. 75 Commands can be sent via regular private messages 76 (_/msg BouncerServ <command> [args...]_). Commands may be written in full or 77 abbreviated form, for instance *network* can be abbreviated as *net* or just 78 *n*. 76 79 77 80 *help* [command] … … 79 82 the command. 80 83 81 * create-network* *-addr* <addr> [options...]84 *network create* *-addr* <addr> [options...] 82 85 Connect to a new network at _addr_. _-addr_ is mandatory. Other options are: 83 86
Note:
See TracChangeset
for help on using the changeset viewer.