From d77bb17771c975fa58d4f96a01b154b03afd8f49 Mon Sep 17 00:00:00 2001 From: shaoying Date: Sun, 1 Apr 2018 11:06:09 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E8=84=9A=E6=9C=AC=E6=B6=88?= =?UTF-8?q?=E6=81=AF=E5=A4=84=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/context/aaa/aaa.go | 29 +++++++---- src/context/cli/cli.go | 74 ++++++++++++++++++++++++++-- src/context/ctx.go | 108 +++++++++++++++++++++++++++-------------- src/context/nfs/nfs.go | 18 ++----- src/context/web/web.go | 39 ++++++++++----- 5 files changed, 189 insertions(+), 79 deletions(-) diff --git a/src/context/aaa/aaa.go b/src/context/aaa/aaa.go index 9a553e88..6b7cb38d 100644 --- a/src/context/aaa/aaa.go +++ b/src/context/aaa/aaa.go @@ -1,6 +1,6 @@ -package aaa - -import ( +package aaa // {{{ +// }}} +import ( // {{{ "context" "crypto/md5" @@ -12,18 +12,22 @@ import ( "time" ) +// }}} + type AAA struct { sessions map[string]*ctx.Context *ctx.Context } -func (aaa *AAA) Session(meta string) string { +func (aaa *AAA) Session(meta string) string { // {{{ bs := md5.Sum([]byte(fmt.Sprintln("%d%d%s", time.Now().Unix(), rand.Int(), meta))) sessid := hex.EncodeToString(bs[:]) return sessid } -func (aaa *AAA) Spawn(m *ctx.Message, c *ctx.Context, arg ...string) ctx.Server { +// }}} + +func (aaa *AAA) Spawn(m *ctx.Message, c *ctx.Context, arg ...string) ctx.Server { // {{{ c.Caches = map[string]*ctx.Cache{} c.Configs = map[string]*ctx.Config{} @@ -32,7 +36,8 @@ func (aaa *AAA) Spawn(m *ctx.Message, c *ctx.Context, arg ...string) ctx.Server return s } -func (aaa *AAA) Begin(m *ctx.Message, arg ...string) ctx.Server { +// }}} +func (aaa *AAA) Begin(m *ctx.Message, arg ...string) ctx.Server { // {{{ aaa.Context.Master(nil) aaa.Caches["group"] = &ctx.Cache{Name: "用户组", Value: "", Help: "用户组"} aaa.Caches["username"] = &ctx.Cache{Name: "用户名", Value: "", Help: "用户名"} @@ -64,7 +69,8 @@ func (aaa *AAA) Begin(m *ctx.Message, arg ...string) ctx.Server { return aaa } -func (aaa *AAA) Start(m *ctx.Message, arg ...string) bool { +// }}} +func (aaa *AAA) Start(m *ctx.Message, arg ...string) bool { // {{{ if len(arg) > 1 && m.Cap("sessid") == "" { m.Cap("group", arg[0]) m.Cap("username", arg[1]) @@ -79,7 +85,8 @@ func (aaa *AAA) Start(m *ctx.Message, arg ...string) bool { return false } -func (aaa *AAA) Close(m *ctx.Message, arg ...string) bool { +// }}} +func (aaa *AAA) Close(m *ctx.Message, arg ...string) bool { // {{{ switch aaa.Context { case m.Target(): root := Pulse.Target().Server.(*AAA) @@ -91,6 +98,8 @@ func (aaa *AAA) Close(m *ctx.Message, arg ...string) bool { return true } +// }}} + var Pulse *ctx.Message var Index = &ctx.Context{Name: "aaa", Help: "认证中心", Caches: map[string]*ctx.Cache{ @@ -102,7 +111,7 @@ var Index = &ctx.Context{Name: "aaa", Help: "认证中心", }, Commands: map[string]*ctx.Command{ "login": &ctx.Command{Name: "login [sessid]|[[group] username password]]", Help: "用户登录", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) { - m.Target(c) + m.Target(c) // {{{ aaa := c.Server.(*AAA) switch len(arg) { @@ -144,7 +153,7 @@ var Index = &ctx.Context{Name: "aaa", Help: "认证中心", m.Source().Group, m.Source().Owner = msg.Cap("group"), msg.Target() aaa.sessions[m.Cap("sessid")] = msg.Target() m.Echo(msg.Cap("sessid")) - } + } // }}} }}, }, Index: map[string]*ctx.Context{ diff --git a/src/context/cli/cli.go b/src/context/cli/cli.go index 61a142ef..948b2139 100644 --- a/src/context/cli/cli.go +++ b/src/context/cli/cli.go @@ -62,6 +62,7 @@ func (cli *CLI) Begin(m *ctx.Message, arg ...string) ctx.Server { // {{{ cli.Caches["target"] = &ctx.Cache{Name: "操作目标", Value: cli.Name, Help: "命令操作的目标"} cli.Caches["result"] = &ctx.Cache{Name: "执行结果", Value: "", Help: "前一条命令的执行结果"} + cli.Caches["last"] = &ctx.Cache{Name: "前一条消息", Value: "0", Help: "前一条命令的编号"} cli.Caches["back"] = &ctx.Cache{Name: "前一条指令", Value: "", Help: "前一条指令"} cli.Caches["next"] = &ctx.Cache{Name: "下一条指令", Value: "", Help: "下一条指令"} @@ -106,16 +107,17 @@ func (cli *CLI) Begin(m *ctx.Message, arg ...string) ctx.Server { // {{{ yac.Cmd("train", "op1", "op1", "mul{", "$", "@", "}") yac.Cmd("train", "op1", "op1", "mul{", "-z", "-n", "}") + yac.Cmd("train", "op1", "op1", "mul{", "-e", "-f", "-d", "}") yac.Cmd("train", "op1", "op1", "mul{", "-", "+", "}") yac.Cmd("train", "op2", "op2", "mul{", "+", "-", "*", "/", "}") yac.Cmd("train", "op2", "op2", "mul{", ">", ">=", "<", "<=", "=", "!=", "}") - yac.Cmd("train", "val", "val", "opt{", "op1", "}", "mul{", "num", "key", "str", "}") + yac.Cmd("train", "val", "val", "opt{", "op1", "}", "mul{", "num", "key", "str", "tran", "}") yac.Cmd("train", "exp", "exp", "val", "rep{", "op2", "val", "}") yac.Cmd("train", "val", "val", "(", "exp", ")") yac.Cmd("train", "stm", "var", "var", "key", "opt{", "=", "exp", "}") - yac.Cmd("train", "stm", "let", "let", "key", "=", "exp") + yac.Cmd("train", "stm", "let", "let", "key", "mul{", "=", "<-", "}", "exp") yac.Cmd("train", "stm", "if", "if", "exp") yac.Cmd("train", "stm", "elif", "elif", "exp") yac.Cmd("train", "stm", "for", "for", "exp") @@ -306,6 +308,25 @@ var Index = &ctx.Context{Name: "cli", Help: "管理中心", } } // }}} }}, + "time": &ctx.Command{Name: "time format when", Help: "睡眠, time(ns/us/ms/s/m/h): 时间值(纳秒/微秒/毫秒/秒/分钟/小时)", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) { + t := time.Now() // {{{ + if len(arg) > 1 { + n, e := strconv.Atoi(arg[1]) + m.Assert(e) + t = time.Unix(int64(n), 0) + } + + f := "" + if len(arg) > 0 { + f = arg[0] + } + + if f == "" { + m.Echo("%d", t.Unix()) + } else { + m.Echo(t.Format(f)) + } // }}} + }}, "express": &ctx.Command{Name: "express exp", Help: "表达式运算", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) { result := "false" // {{{ switch len(arg) { @@ -455,6 +476,24 @@ var Index = &ctx.Context{Name: "cli", Help: "管理中心", } else { m.Echo("true") } + case "-e": + if _, e := os.Stat(arg[1]); e == nil { + m.Echo("true") + } else { + m.Echo("false") + } + case "-f": + if info, e := os.Stat(arg[1]); e == nil && !info.IsDir() { + m.Echo("true") + } else { + m.Echo("false") + } + case "-d": + if info, e := os.Stat(arg[1]); e == nil && info.IsDir() { + m.Echo("true") + } else { + m.Echo("false") + } case "$": m.Echo(m.Cap(arg[1])) case "@": @@ -483,7 +522,7 @@ var Index = &ctx.Context{Name: "cli", Help: "管理中心", } for i := len(op) - 1; i >= 0; i-- { - num[i] = m.Cmd("express", num[i], op[i], num[i+1]).Get("result") + num[i] = m.Spawn(m.Target()).Cmd("express", num[i], op[i], num[i+1]).Get("result") } m.Echo("%s", num[0]) @@ -510,6 +549,20 @@ var Index = &ctx.Context{Name: "cli", Help: "管理中心", case "@": m.Echo(msg.Conf(arg[1])) } + case 4: + switch arg[0] { + case "$": + m.Echo(arg[2]) + case "@": + m.Echo(arg[2]) + } + default: + switch arg[0] { + case "$": + m.Result(0, "cache", arg[1:]) + case "@": + m.Result(0, "config", arg[1:]) + } } } else { m.Set("result", arg...) @@ -558,6 +611,7 @@ var Index = &ctx.Context{Name: "cli", Help: "管理中心", m.Cap("target", cli.target.Name) m.Set("result", msg.Meta["result"]...) + m.Capi("last", 0, msg.Code()) } else { m.Set("result", arg...) @@ -567,7 +621,12 @@ var Index = &ctx.Context{Name: "cli", Help: "管理中心", "var": &ctx.Command{Name: "var a [= exp]", Help: "定义变量, a: 变量名, exp: 表达式", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) { if _, ok := m.Target().Server.(*CLI); m.Assert(ok) && !m.Caps("skip") { // {{{ if m.Cap(arg[1], arg[1], "", "临时变量"); len(arg) > 3 { - m.Cap(arg[1], arg[3]) + switch arg[2] { + case "=": + m.Cap(arg[1], arg[3]) + case "<-": + m.Cap(arg[1], m.Cap("last")) + } } } else { m.Set("result", arg...) @@ -575,7 +634,12 @@ var Index = &ctx.Context{Name: "cli", Help: "管理中心", }}, "let": &ctx.Command{Name: "let a = exp", Help: "设置变量, a: 变量名, exp: 表达式(a {+|-|*|/|%} b)", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) { if _, ok := m.Target().Server.(*CLI); m.Assert(ok) && !m.Caps("skip") { // {{{ - m.Cap(arg[1], arg[3]) + switch arg[2] { + case "=": + m.Cap(arg[1], arg[3]) + case "<-": + m.Cap(arg[1], m.Cap("last")) + } } else { m.Set("result", arg...) } // }}} diff --git a/src/context/ctx.go b/src/context/ctx.go index 20ef4017..cc094635 100644 --- a/src/context/ctx.go +++ b/src/context/ctx.go @@ -522,7 +522,7 @@ func (m *Message) Log(action string, ctx *Context, str string, arg ...interface{ } if l := m.Sess("log"); l != nil { - if i++; i > 20000 { + if i++; i > 80000 { debug.PrintStack() os.Exit(1) } @@ -542,6 +542,8 @@ func (m *Message) Gdb(action string) { // {{{ // }}} func (m *Message) Check(s *Context, arg ...string) bool { // {{{ + return true + if s.Owner == nil { return true } @@ -627,8 +629,10 @@ func (m *Message) Assert(e interface{}, msg ...string) bool { // {{{ msg = msg[2:] } case *Message: - os.Exit(1) - panic(e) + if result, ok := e.Meta["result"]; ok && len(result) > 0 && result[0] == "error: " { + panic(e) + } + return true default: return true } @@ -647,7 +651,6 @@ func (m *Message) Assert(e interface{}, msg ...string) bool { // {{{ } m.Set("result", "error: ", fmt.Sprintln(e), "\n") - os.Exit(1) panic(e) } @@ -655,9 +658,9 @@ func (m *Message) Assert(e interface{}, msg ...string) bool { // {{{ func (m *Message) AssertOne(msg *Message, safe bool, hand ...func(msg *Message)) *Message { // {{{ defer func() { if e := recover(); e != nil { + switch e.(type) { case *Message: - os.Exit(1) panic(e) } @@ -824,7 +827,8 @@ func (m *Message) Find(name string, root ...bool) *Message { // {{{ // }}} func (m *Message) Sess(key string, arg ...string) *Message { // {{{ - if len(arg) > 0 { + + if _, ok := m.target.Sessions[key]; !ok && len(arg) > 0 { root := true if len(arg) > 2 { root = Right(arg[2]) @@ -1595,7 +1599,7 @@ var Index = &Context{Name: "ctx", Help: "模块中心", } // }}} }}, - "message": &Command{Name: "message code", Help: "查看消息", Hand: func(m *Message, c *Context, key string, arg ...string) { + "message": &Command{Name: "message code meta index", Help: "查看消息", Hand: func(m *Message, c *Context, key string, arg ...string) { switch len(arg) { // {{{ case 0: m.Echo("\033[31mrequests:\033[0m\n") @@ -1657,19 +1661,39 @@ var Index = &Context{Name: "ctx", Help: "模块中心", } ms = append(ms, ms[i].messages...) } + case 2, 3: + index := 0 + if len(arg) == 3 { + n, e := strconv.Atoi(arg[2]) + m.Assert(e) + index = n + } + + n, e := strconv.Atoi(arg[0]) + m.Assert(e) + + ms := []*Message{m.root} + for i := 0; i < len(ms); i++ { + if ms[i].code == n { + if meta, ok := ms[i].Meta[arg[1]]; ok { + m.Echo(meta[index]) + } + } + ms = append(ms, ms[i].messages...) + } } // }}} }}, "detail": &Command{Name: "detail index val...", Help: "查看消息", Hand: func(m *Message, c *Context, key string, arg ...string) { - msg := m.Spawn(m.Target()) + msg := m.Spawn(m.Target()) // {{{ msg.Detail(1, "nie", 1, []string{"123", "123"}, true, []bool{false, true}, []int{1, 2, 2}) m.Echo("%v", msg.Meta) msg.Detail(2, "nie") m.Echo("%v", msg.Meta) - + // }}} }}, "option": &Command{Name: "option key val...", Help: "查看消息", Hand: func(m *Message, c *Context, key string, arg ...string) { if len(arg) > 0 { // {{{ @@ -1843,7 +1867,12 @@ var Index = &Context{Name: "ctx", Help: "模块中心", x.Hand = nil } } + default: + msg := m.Spawn(m.Target()).Cmd(arg) + msg.Option("nrecv", m.Option("nrecv")) + m.Meta = msg.Meta } + return m.BackTrace(func(m *Message) bool { if all { @@ -1860,31 +1889,37 @@ var Index = &Context{Name: "ctx", Help: "模块中心", return all }) m.Assert(m.Has("result"), "%s 命令不存在", arg[0]) - case 3: - cmd := &Command{} - m.BackTrace(func(m *Message) bool { - if x, ok := m.target.Commands[arg[0]]; ok && x.Hand != nil { - *cmd = *x - } - return all - }) + default: + msg := m.Spawn(m.Target()).Cmd(arg) + msg.Option("nrecv", m.Option("nrecv")) + m.Meta = msg.Meta + /* + case 3: + cmd := &Command{} + m.BackTrace(func(m *Message) bool { + if x, ok := m.target.Commands[arg[0]]; ok && x.Hand != nil { + *cmd = *x + } + return all + }) - if m.Check(m.target, "commands", arg[0]) { - if x, ok := m.target.Commands[arg[0]]; ok { - if m.target.Owner == nil || m.master.Owner == m.target.Owner { - x.Name = arg[1] - x.Help = arg[2] - m.Echo("%s\n %s\n", x.Name, x.Help) + if m.Check(m.target, "commands", arg[0]) { + if x, ok := m.target.Commands[arg[0]]; ok { + if m.target.Owner == nil || m.master.Owner == m.target.Owner { + x.Name = arg[1] + x.Help = arg[2] + m.Echo("%s\n %s\n", x.Name, x.Help) + } + } else { + if m.target.Commands == nil { + m.target.Commands = map[string]*Command{} + } + cmd.Name = arg[1] + cmd.Help = arg[2] + m.target.Commands[arg[0]] = cmd + } } - } else { - if m.target.Commands == nil { - m.target.Commands = map[string]*Command{} - } - cmd.Name = arg[1] - cmd.Help = arg[2] - m.target.Commands[arg[0]] = cmd - } - } + */ } // }}} }}, @@ -1997,9 +2032,6 @@ var Index = &Context{Name: "ctx", Help: "模块中心", } m.Cap(arg[0], arg[2]) case 4: - if m.source == m.source.master { - m.source, m.target = m.target, m.source - } m.Cap(arg[0], arg[1:]...) } // }}} @@ -2013,8 +2045,10 @@ var Index = &Context{Name: "ctx", Help: "模块中心", }, Index: map[string]*Context{ "void": &Context{Name: "void", - Caches: map[string]*Cache{}, - Configs: map[string]*Config{}, + Caches: map[string]*Cache{}, + Configs: map[string]*Config{ + "bench.log": &Config{}, + }, Commands: map[string]*Command{ "message": &Command{}, "context": &Command{}, diff --git a/src/context/nfs/nfs.go b/src/context/nfs/nfs.go index 11190275..570d3fb5 100644 --- a/src/context/nfs/nfs.go +++ b/src/context/nfs/nfs.go @@ -89,6 +89,7 @@ func (nfs *NFS) Start(m *ctx.Message, arg ...string) bool { // {{{ nfs.send = make(map[string]*ctx.Message) target, msg := m.Target(), m.Spawn(m.Target()) + nfs.Caches["target"] = &ctx.Cache{Name: "target", Value: target.Name, Help: "文件名"} for { line, e := nfs.Reader.ReadString('\n') @@ -140,6 +141,7 @@ func (nfs *NFS) Start(m *ctx.Message, arg ...string) bool { // {{{ send.Recv <- true } msg = m.Spawn(target) + m.Cap("target", target.Name) continue } @@ -295,22 +297,10 @@ var Index = &ctx.Context{Name: "nfs", Help: "存储中心", }}, "listen": &ctx.Command{Name: "listen args...", Help: "启动文件服务, args: 参考tcp模块, listen命令的参数", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) { - tcp := m.Sess("tcp") // {{{ - if tcp == nil { - tcp = m.Sess("tcp", "tcp") - } - m.Assert(tcp != nil) - tcp.Cmd(m.Meta["detail"]) - // }}} + m.Cap("stream", m.Sess("tcp", "tcp").Cmd(m.Meta["detail"]).Cap("address")) }}, "dial": &ctx.Command{Name: "dial args...", Help: "连接文件服务, args: 参考tcp模块, dial命令的参数", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) { - tcp := m.Sess("tcp") // {{{ - if tcp == nil { - tcp = m.Sess("tcp", "tcp") - } - m.Assert(tcp != nil) - tcp.Cmd(m.Meta["detail"]) - // }}} + m.Sess("tcp", "tcp").Cmd(m.Meta["detail"]) }}, "send": &ctx.Command{Name: "send [file] args...", Help: "连接文件服务, args: 参考tcp模块, dial命令的参数", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) { if nfs, ok := m.Target().Server.(*NFS); m.Assert(ok) { // {{{ diff --git a/src/context/web/web.go b/src/context/web/web.go index 3beb9bfd..43a72ec8 100644 --- a/src/context/web/web.go +++ b/src/context/web/web.go @@ -1,6 +1,6 @@ -package web - -import ( +package web // {{{ +// }}} +import ( // {{{ "context" "html/template" @@ -14,6 +14,8 @@ import ( "strings" ) +// }}} + type MUX interface { Handle(string, http.Handler) HandleFunc(string, func(http.ResponseWriter, *http.Request)) @@ -28,7 +30,7 @@ type WEB struct { *ctx.Context } -func (web *WEB) AppendJson(msg *ctx.Message) string { +func (web *WEB) AppendJson(msg *ctx.Message) string { // {{{ result := []string{"{"} for i, k := range msg.Meta["append"] { result = append(result, fmt.Sprintf("\"%s\": [", k)) @@ -47,17 +49,19 @@ func (web *WEB) AppendJson(msg *ctx.Message) string { return strings.Join(result, "") } -func (web *WEB) Trans(m *ctx.Message, key string, hand func(*ctx.Message, *ctx.Context, string, ...string)) { +// }}} +func (web *WEB) Trans(m *ctx.Message, key string, hand func(*ctx.Message, *ctx.Context, string, ...string)) { // {{{ web.HandleFunc(key, func(w http.ResponseWriter, r *http.Request) { msg := m.Spawn(m.Target()).Set("detail", key) + for k, v := range r.Form { msg.Add("option", k, v...) } for _, v := range r.Cookies() { msg.Add("option", v.Name, v.Value) } - msg.Log("cmd", nil, "%s [] %v", key, msg.Meta["option"]) + msg.Put("option", "request", r).Put("option", "response", w) if hand(msg, msg.Target(), key); len(msg.Meta["append"]) > 0 { msg.Set("result", web.AppendJson(msg)) @@ -70,7 +74,8 @@ func (web *WEB) Trans(m *ctx.Message, key string, hand func(*ctx.Message, *ctx.C }) } -func (web *WEB) ServeHTTP(w http.ResponseWriter, r *http.Request) { +// }}} +func (web *WEB) ServeHTTP(w http.ResponseWriter, r *http.Request) { // {{{ if web.Message != nil { log.Println() web.Log("cmd", nil, "%v %s %s", r.RemoteAddr, r.Method, r.URL) @@ -100,7 +105,9 @@ func (web *WEB) ServeHTTP(w http.ResponseWriter, r *http.Request) { } } -func (web *WEB) Spawn(m *ctx.Message, c *ctx.Context, arg ...string) ctx.Server { +// }}} + +func (web *WEB) Spawn(m *ctx.Message, c *ctx.Context, arg ...string) ctx.Server { // {{{ c.Caches = map[string]*ctx.Cache{} c.Configs = map[string]*ctx.Config{} @@ -109,7 +116,9 @@ func (web *WEB) Spawn(m *ctx.Message, c *ctx.Context, arg ...string) ctx.Server return s } -func (web *WEB) Begin(m *ctx.Message, arg ...string) ctx.Server { +// }}} +func (web *WEB) Begin(m *ctx.Message, arg ...string) ctx.Server { // {{{ + web.Context.Master(nil) web.Caches["route"] = &ctx.Cache{Name: "请求路径", Value: "/" + web.Context.Name + "/", Help: "请求路径"} web.Caches["register"] = &ctx.Cache{Name: "已初始化(yes/no)", Value: "no", Help: "模块是否已初始化"} web.Caches["master"] = &ctx.Cache{Name: "服务入口(yes/no)", Value: "no", Help: "服务入口"} @@ -130,7 +139,8 @@ func (web *WEB) Begin(m *ctx.Message, arg ...string) ctx.Server { return web } -func (web *WEB) Start(m *ctx.Message, arg ...string) bool { +// }}} +func (web *WEB) Start(m *ctx.Message, arg ...string) bool { // {{{ if len(arg) > 0 { m.Cap("directory", arg[0]) } @@ -192,7 +202,8 @@ func (web *WEB) Start(m *ctx.Message, arg ...string) bool { return true } -func (web *WEB) Close(m *ctx.Message, arg ...string) bool { +// }}} +func (web *WEB) Close(m *ctx.Message, arg ...string) bool { // {{{ switch web.Context { case m.Target(): case m.Source(): @@ -200,6 +211,8 @@ func (web *WEB) Close(m *ctx.Message, arg ...string) bool { return true } +// }}} + var Index = &ctx.Context{Name: "web", Help: "应用中心", Caches: map[string]*ctx.Cache{}, Configs: map[string]*ctx.Config{}, @@ -208,7 +221,7 @@ var Index = &ctx.Context{Name: "web", Help: "应用中心", m.Set("detail", arg...).Target().Start(m) }}, "route": &ctx.Command{Name: "route directory|template|script route content", Help: "添加应用内容", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) { - mux, ok := m.Target().Server.(MUX) + mux, ok := m.Target().Server.(MUX) // {{{ m.Assert(ok, "模块类型错误") m.Assert(len(arg) == 3, "缺少参数") @@ -249,7 +262,7 @@ var Index = &ctx.Context{Name: "web", Help: "应用中心", } } }) - } + } // }}} }}, "/demo": &ctx.Command{Name: "/demo", Help: "应用示例", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) { m.Add("append", "hi", "hello")