北大侠客行MUD论坛

 找回密码
 注册
搜索
热搜: 新手 wiki 升级
查看: 23223|回复: 24

跟Akuma一起从头打造mudlib--【第二讲】 作者:Akuma

[复制链接]
发表于 2009-10-1 17:21:24 | 显示全部楼层 |阅读模式
转自mudbuilder.com,akuma原创,akuma是北大侠客行老牌巫师柳残阳

第二讲:指令系统
我思考了一下,决定暂时跳过登录部分,先说指令。毕竟有了指令之后,就可以在线更新和重启,不用不停的kill driver进程了。

在开始之前,我们先思考一个问题,指令是干什么用的,以及我们希望如何管理指令系统。

我们常讲一个词叫I/O,也就是所谓的输入输出。
从最基本的意义上说,指令就是玩家敲的东西,他希望通过敲一些东西,告诉mud“我要做什么”。抛开网络层和mudos底层不讲,我们可以把指令看作是一个字符串(事实上他的确是一个字符串,并且是以\n或者\n\r结尾的字符串,也就是说,很不幸,我们的一telnet为基础的mud不支持指令或者指令参数里带有回车。。。)
然后,mudlib根据一定的规则,找到一段适当的程序去解释玩家的指令,并且给予适当的操作和反馈。

所以我们第一步可以把指令系统归结为如下的需求:
1.想办法获得玩家的输入
--注意,这个规则一定要是规范的,这个规范我们可以随意制订,比如说用100到999的三位数字表示特定含义的指令;当然了,理论上这虽然没问题,但是考虑到我们的zmud或者telnet,玩家的指令是手敲的,你让他记这么多数字不太现实。
于是我还是决定继承传统mud的方法,用“指令英文+空格+参数表”的方式来设计这个规范。
2.我们定一个规则,让玩家输入的指令可以在mudlib里找到那段我们希望他来执行的代码去执行之。
如前所述,我们已经假定了指令规则是 “指令英文+空格+参数表”,那么指令的英文名字本身就是一个很好的代号,我们只要通过一定的编码,赋予不同代号对应的程序段就好了。

======================分割线=================================================

本次讲解的内容分成两个部分,第一部分是简单实现指令,第二部分里我们再进一步细化它。
第一部分代码见附件 newlib.0.2.1.tar.gz

目录结构如下:
.
|-- adm
|  |-- daemons
|  |  `-- cmd_d.c
|  `-- obj
|      |-- master.c
|      `-- simul_efun.c
|-- cmds
|  `-- usr
|      `-- test.c
|-- include
|  `-- globals.h
|-- log
`-- obj
    `-- user.c

重点1.我们首先来解决“获得玩家输入”的部分:
请看这个版本的/obj/user.c。大家还记得吗?上次当我们写第一个echo server的时候,留了个尾巴。当时我们是通过process_input()来“处理”指令。
这一回,我们希望可以把指令系统建立起来,因此我把process_input()的处理暂时注释掉了。
如何获得玩家的输入?
这里我继续使用一般mudlib(es2 类)的做法,通过一个“全局的”add_action()来实现。
请看代码:
void create()
{
        setup();
}
int setup()
{
        log_file("user",sprintf("%O setup at %s\n",this_object(),ctime(time())));
        enable_commands();
        add_action("cmd_hook","",1);
        return 1;
}

正常来说,我们不应该这么早进入这个部分,不过由于暂时还没有登录认证体系,就先这么凑合。这里只是用来表述流程:
一个user_ob被master.c的connect()创建时(记得吗?这个时候他就是一个真正的连线物件了),apply函数create()被呼叫,于是他调用了setup()。
我们可以看到,setup()只干了两件事:
a. enable_commands();
b. add_action("cmd_hook","",1);
add_action()大家在制作谜题的时候会经常遇到,就是给某个物件增加一个“临时的”指令,并且指定用于解释这个指令的函数名字。所有“接触到”这个物体的物体,都可以使用这个指令。
我们这里的用法比较奇怪一些,他大概的意思就是“不管你输入什么,我都认为你是我这个add_action定义的指令”。
我一直觉得这个写法挺古怪的,不过为了兼容和尊重传统,我们继续这么搞吧。
enable_commands()是给物件设置一个标记,好让add_action()有效。

继续看cmd_hook()这个执行函数。
int cmd_hook(string arg)
{
        string verb = query_verb();
        return CMD_D->do_cmd(this_object(),verb,arg);
}

query_verb()这个efun是用来获取玩家的“最近一个指令”,注意是指令,不包括参数表。参数表是由add_action给定的解释函数(这里就是cmd_hook以参数形式传进来的)
然后,我们通过一个daemons来设法去执行这个指令(也就是verb)
return CMD_D->do_cmd(this_object(),verb,arg);

CMD_D一会再看。这里我们要注意的有一个要点,请看从cmd_hook被定义为int型函数开始,我们一直在return(CMD_D里也是一路有return的)。
为什么?这是mudos的一个机制,针对玩家的输入,我们一路处理下来,如果有为true的return。那么系统会认为这个指令被正确的执行了。否则他就会想办法给出报错。
从我们之前看到的">what?"或者一般mud里定义的“>什么?”,一直到使用notify_fail来自定义的错误返回等等。

重点2.规范的管理和找到指令对应的处理函数:
在前边我们已经获执行指令取到了所有必要的信息,包括指令名字,参数表(还有是“谁”的指令),接下来我们就要开始想办法执行他了。
请看/adm/daemons/cmd_d.c(有些lib里可能叫做commandd.c之类的)
目前我们只有这么一句
int do_cmd(object me,string verb,string arg)
{
        return ("/cmds/usr/"+verb)->main(me,arg);
}
这也就是刚才在cmd_hook()里调用的函数体了。
这里不用多解释,我们就是通过"/cmds/usr/"+verb拼出了需要使用的指令的文件名字,然后把“谁”和“什么”传到他的main()函数里了。

其实在lpc里,main()并不是一个特定的函数,指令里用这个函数名作为入口,我猜是当年某个习惯c的人随手定的规则。不过为了讲解的作用,我们还是继承下来。

我们特意创建了/cmds/usr/test.c这样一个指令,大家可以自己看看。

ok,现在我们的指令流程已经初步创建起来了,如果你现在启动我们0.2.1版的lib,连接上去,敲:
test xxxxx
就会获得如下的反馈:
in cmd test: arg=xxxxx
这说明指令test已经正确的被执行了。
兴奋的我们准备再敲点别的。。比如asdfasdf asdfsdf这样子。。。
嗯。。。。没有反应。
如果你这个时候去看/log,就会发现多了一个error_handler目录。很不幸,一般来说,看到这个就表示我们的lib有“runtime error”(运行时断错误,也就是说,程序可以被编译,没有语法错误,但是在运行中出了错)。

这说明我们的程序缺乏起码的容错性。
这也就是我们在 lib.0.2.2.tar.gz当中需要解决的内容。

=====================分割线==================================================
有点小忙。。。
稍后我把第二讲的下半部分补全。需要解决三个问题:
1.鲁棒性,无论如何我们不希望总出现error_handler。也就是说,无论玩家怎么乱输入,我们都应该可以处理,而不是任由它报错。。。
2.便于管理,我们希望找到一个方法,让指令的处理文件有序的呆在一个地方,并且可以方便且正确的被程序找到。
3.安全性,即权限,看本文的wiz居多,我们总不希望玩家可以随便执行巫师指令吧。。。那么我们就要想个办法,让适合的人能执行适合的指令,而不是相反。
请等待第二讲·下~~谢谢。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x
北大侠客行Mud(pkuxkx.com),最好的中文Mud游戏!
发表于 2009-10-1 17:22:49 | 显示全部楼层
icer发的真tmd散……收藏都快不够放了
北大侠客行Mud(pkuxkx.com),最好的中文Mud游戏!
发表于 2009-10-1 17:28:22 | 显示全部楼层
为啥不放在一个铁子里面...
北大侠客行Mud(pkuxkx.com),最好的中文Mud游戏!
 楼主| 发表于 2009-10-1 17:43:16 | 显示全部楼层
懒得占楼,不知道akuma要发几篇
北大侠客行Mud(pkuxkx.com),最好的中文Mud游戏!
发表于 2009-10-1 18:35:15 | 显示全部楼层
akuma这厮居然还活着?
现在他在干什么呢?
从北侠到红豆开始到现在的这一段时间里发生的事情我一无所知,真的很想知道。

[ 本帖最后由 sway 于 2009-10-1 06:44 PM 编辑 ]
北大侠客行Mud(pkuxkx.com),最好的中文Mud游戏!
 楼主| 发表于 2009-10-1 19:57:47 | 显示全部楼层
活着,开了个风云,在mudbuilder混呢。至于具体在干啥我也不知道了
北大侠客行Mud(pkuxkx.com),最好的中文Mud游戏!
发表于 2009-10-1 20:46:08 | 显示全部楼层
不能把他拉回到北侠来么?
北大侠客行Mud(pkuxkx.com),最好的中文Mud游戏!
发表于 2009-10-6 17:09:09 | 显示全部楼层
冰冰快去,更新第三讲!
北大侠客行Mud(pkuxkx.com),最好的中文Mud游戏!
发表于 2009-10-19 11:35:53 | 显示全部楼层
嗯。。。就是我。。。
北大侠客行Mud(pkuxkx.com),最好的中文Mud游戏!
发表于 2009-10-19 13:15:42 | 显示全部楼层
你居然还有精力和心情写这个,佩服!。。。
北大侠客行Mud(pkuxkx.com),最好的中文Mud游戏!
您需要登录后才可以回帖 登录 | 注册

本版积分规则

Archiver|手机版|小黑屋|北大侠客行MUD ( 京ICP备16065414号-1 )

GMT+8, 2024-11-27 11:50 PM , Processed in 0.011350 second(s), 15 queries .

Powered by Discuz! X3.4

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表