Files
2021-02-02 14:13:48 +01:00

176 lines
4.2 KiB
Go

package core
import (
"fmt"
"github.com/chzyer/readline"
"github.com/fatih/color"
"github.com/kgretzky/evilginx2/log"
)
type Help struct {
cmds map[string][]string
categories []string
line_help map[string]string
cmd_names []string
sub_disp map[string][]string
cmd_infos map[string]string
sub_cmds map[string]map[string]string
cmd_layers map[string]int
cmd_completer map[string]*readline.PrefixCompleter
}
func NewHelp() (*Help, error) {
h := &Help{
cmds: make(map[string][]string),
categories: []string{},
line_help: make(map[string]string),
cmd_names: []string{},
sub_disp: make(map[string][]string),
cmd_infos: make(map[string]string),
sub_cmds: make(map[string]map[string]string),
cmd_layers: make(map[string]int),
cmd_completer: make(map[string]*readline.PrefixCompleter),
}
return h, nil
}
func (h *Help) AddCommand(cmd string, category string, cmd_help string, info string, layer int, completer *readline.PrefixCompleter) {
if _, ok := h.cmds[category]; !ok {
h.cmds[category] = []string{}
h.categories = append(h.categories, category)
}
h.cmd_infos[cmd] = info
h.sub_cmds[cmd] = make(map[string]string)
h.sub_disp[cmd] = []string{}
h.cmds[category] = append(h.cmds[category], cmd)
h.cmd_names = append(h.cmd_names, cmd)
h.line_help[cmd] = cmd_help
h.cmd_layers[cmd] = layer
h.cmd_completer[cmd] = completer
}
func (h *Help) AddSubCommand(cmd string, sub_cmds []string, sub_disp string, cmd_help string) {
if subm, ok := h.sub_cmds[cmd]; ok {
subm[sub_disp] = cmd_help
}
if _, ok := h.sub_disp[cmd]; ok {
h.sub_disp[cmd] = append(h.sub_disp[cmd], sub_disp)
}
}
func (h *Help) GetCommands() []string {
return h.cmd_names
}
func (h *Help) GetPrefixCommands(layer int) []string {
var ret []string
for cmd, c_layer := range h.cmd_layers {
if layer&c_layer != 0 {
ret = append(ret, cmd)
}
}
return ret
}
func (h *Help) GetPrefixCompleter(layer int) *readline.PrefixCompleter {
pc := readline.NewPrefixCompleter()
cmds := h.GetPrefixCommands(layer)
var top []readline.PrefixCompleterInterface
for _, cmd := range cmds {
if completer, ok := h.cmd_completer[cmd]; ok {
top = append(top, completer)
}
}
top = append(top, readline.PcItem("help", readline.PcItemDynamic(h.helpPrefixCompleter)))
pc.SetChildren(top)
return pc
}
func (h *Help) Print(layer int) {
var out string
yw := color.New(color.FgYellow)
lb := color.New(color.FgGreen)
for n, cat := range h.categories {
if n > 0 {
out += "\n"
}
cmds, ok := h.cmds[cat]
if ok {
out += fmt.Sprintf(" %s\n\n", yw.Sprint(cat))
var rows, vals []string
for _, cmd := range cmds {
pcmd := cmd
if layer&h.cmd_layers[cmd] != 0 {
pcmd = lb.Sprint(cmd)
}
line_help, _ := h.line_help[cmd]
rows = append(rows, pcmd)
vals = append(vals, line_help)
}
out += AsRows(rows, vals)
}
}
log.Printf("\n%s\n", out)
}
func (h *Help) PrintBrief(cmd string) error {
yw := color.New(color.FgYellow)
var out string
if _, ok := h.line_help[cmd]; !ok {
return fmt.Errorf("command not found")
}
out += fmt.Sprintf(" %s\n\n", yw.Sprint(cmd))
if cmd_info, ok := h.cmd_infos[cmd]; ok {
if len(cmd_info) > 0 {
max_line := 64
n_line := 0
var out_info []rune
out_info = append(out_info, ' ')
r_info := []rune(cmd_info)
for _, r := range r_info {
if r == ' ' && n_line > max_line {
out_info = append(out_info, '\n')
n_line = 0
} else if r == '\n' {
out_info = append(out_info, '\n')
out_info = append(out_info, ' ')
n_line = 0
continue
} else {
n_line++
}
out_info = append(out_info, r)
}
cmd_info = string(out_info)
out += fmt.Sprintf("%s\n", cmd_info)
}
}
if subm, ok := h.sub_cmds[cmd]; ok {
if subn, ok := h.sub_disp[cmd]; ok {
if len(subn) > 0 {
out += "\n"
}
var rows, vals []string
for _, k := range subn {
kk := k
if len(kk) > 0 {
kk = " " + kk
}
rows = append(rows, cmd+kk)
vals = append(vals, subm[k])
}
out += AsDescription(rows, vals)
}
}
log.Printf("\n%s\n", out)
return nil
}
func (h *Help) helpPrefixCompleter(s string) []string {
return h.GetCommands()
}