首先如果那些声名版权如何如何的人如果抄袭本文中的编程思想不经本人
同意,本人将保留追究的权利。
本想发在清华BBS的MUD版,但清华BBS注册时间较长,于是原信先
发在了华中BBS上。不想昨天华中BBS唯护,那信被删掉于是改投到这里
,希望不会再遭厄运。希望这封信对各地的Mud巫师能有所帮助。
据我了解现在所有大陆上运行的MUD都是清华转译台湾annihilator
的ES的衍生版,如侠客行、风云、XO等等。FTP和联网Mud功能是在台湾
ES中实现的,但由于当时大家到ES了解不够深入,这部分代码在清华ES
中没有完成移值,功能没有实现。后来的这些版本中有的嫌多而删掉了。
我曾和USTC_MUD的一个巫师讨论过ES2,当时我们除了/adm/daemons
一些程序外,其它部分都已经称得上十分熟悉了。他说他曾改过/adm/daemons
下的所有程序,除/adm/daemon/network下的部分是底层用户和服务器连
接部分是最基本的已经做好不用再改,现在回想一下当时我们都嫌这段代
码太长没看以致于根本不了解它实现了什么。
当时我的心思是做几个职业(丐帮[偷],杀手帮[杀],医生公会[疗],
镖局[护],警察[捕]),能根据不同职业定不同任务而不简单只是杀人和给
东西简单的情节。为了寻找一些函数的说明我只好求助于MudOS的说明文档,
在socket部分的惊喜地发现了Mud的网络功能,也就是说可以实现不同Mud之
间的通讯!
以后就是从/adm/daemons/channeld.c程序入手,从网络核心程序
/adm/daemons/network/dns_master.c开始分析,在两个实验机上秘密编程
(科大除USTC_MUD外所有MUD均不合法,一经发现立即封掉IP),断断续续用
了近一个月的时间研究代码,基本实现联网功能。
Mud的端口号分配是这样的,除去在config.XXX中列出的游戏端口之外,
它还设置/include/net/ftpconfig.h中的FTPD_PORT(4100)为上下传文件服务
ftp端口,游戏端口+4为Mud互联端口。
dns_master工作的原理是这样的,当一开机后,它自动地在/include
/net/config.h中给出的LISTNODES(待联Mud网络端口列表)中进行ping,如果
成功则用send_udp向对方互联端口发送关于本地Mud的一些基本信息(如地址,
网络名称,网络端口等),信息流格式为@@@||信息||@@@。对方在互联端口接收
后read_callback,将其加入本地的互联Mud列表,互联Mud名列表中(可以用query_muds
及query_svc获得)并回送当地已接受信息,发出方接收后同时登记该互联端口,
以后双方就可以实现即时通讯。发送方将信息打包后,用dns_master的send_udp
向所有登记的互联端口发出信息,对方通过read_callback接收成mapping类型数
据,就可以通过/adm/daemons/network/services中的各个程序的incoming_request
处理该数据消息,实现通讯。ES2中实现的频道互联(gwiz,es)可供参考。
这种通讯只要一方把对方列入待连Mud列表就可实现,如果本机开机之时对
方的Mud尚未开放刚要等一段时间4*REFRESH_INTERVAL(5分钟)和PING_INTERVAL
(半小时)后再重新试一次。如果开放则继续上面工作。
这种网络互联可以把多个Mud联结起来,使参与者可以成百上千,是单个
Mud远不能及。而网间交谈(gtell),网间巫师交谈(gwiz_msg),网间使用者
列表(gfinger)功能亦得以实现,如果要加上去巫师只需仿照CHANNEL_D进行
修改就可以。网络功能是实现Mud扩展的重要手段,是MudOS中的精华所在,
是单个Mud远不能比的。这一点值得重多巫师花大精力投入和学习。
再远一点,实现不同Mud间的时空穿越也是完全有可能的。MudOS虽然不支
持object型的数据流,但可以在公共物件统一的前提下,用字符流传送玩家数
据及相关资料实现从一个Mud离开到另一个Mud中去,这样相当于把一个Mud地图
扩大几倍,比如从北京的Mud联到上海,则北京的这人档案就移到了上海而下
次这人只能从上海开始登录,这是一项极有挑战性和吸引力的工作。建议大家
注意一下socket有关函数的说明文档,了解它的强大功能。上面的话不是天方
夜潭只要努力实现它是完全有可能的。
以下转载自www.niub.net之mud制作论坛
作者:darks 发表时间:2001年5月8日 17:34
--------------------------------------------------------------------------------
Mud的互连 对于intermud2来说 是双向得
一般都是这边发出一个数据包 数据包里面制定了一个文件
系统会自动调用对方Mud的这个文件的incoming什么的一个函数来处理相应事务。
如果这个调用出错了,那么就会导致失败。
对于emote来说,出错可能是:gchanneel调用不对或者对方没有这个emote指令。
这里举个例子 比如是tell指令
gtell发送的一个包如下:
DNS_MASTER->send_udp(minfo["HOSTADDRESS"], minfo["PORTUDP"],
"@@@" + DNS_GTELL +
"||NAME:" + Mud_name() +
"||PORTUDP:" + udp_port() +
"||WIZTO:" + wiz_to +
"||WIZFROM:" + capitalize(geteuid(source)) +
"||CNAME:" + source->name(1) +
"||MSG:"+msg+"@@@\n");
这里需要调用对方Mud的 dns_gtell文件
那么如果对方mud有这个文件,这个文件的incoming_request()函数就会被呼叫
我们一般在这个函数里面加些判断(主意这个函数是对方Mud的,也就是说这些操
作是针对对方Mud而言)然后做这样的事情:
if (TELL_CMD->remote_tell( info["CNAME"], info["WIZFROM"],info["NAME"],info["WIZTO"], info["MSG"] ))
reply = "你告诉"+info["CNAME"]+"("+capitalize(info["WIZTO"])+"@"+Mud_name()+"):" + info["MSG"];
else
reply = "没有这个人。\n";
调用tell指令里面的remote_tell,然后就把reply这个字符串返回到我们的Mud
这个单纯的返回可以使用:
(AUX_PATH+"affirmation_a")->send_affirmation_a(info["HOSTADDRESS"],
info["PORTUDP"],"Gtell@" + Mud_name(),
info["WIZFROM"], reply, "gtell");
这样完成。
基本上 chat emote who finger都是可以这样做
互联的基本原理非常简单: 对于Mud_A Mud_B而言
Mud_A-->发送信息(Mud_B地址端口 一个文件名FILE 参数)-->Mud_B的FILE调用
incoming_request()函数,传递过来的参数作为函数的参数使用-->处理过程-->将
需要返回的信息通过同样方式传回给Mud_A-->Mud_A处理反馈信息
作者:super 发表时间:2001年6月27日 13:05
--------------------------------------------------------------------------------
MUD里面有专门一个物件列阵来存放玩家信息的。
也就是users(),里面的每一个元素就是一个在线玩家。
然后比如说你要向大家发信息的话。
我们就一个一个把信息传送给users()中的每一个OBJ。
这是MUD层的理解,如果深入到网络层的话呢。
当你LOGIN的时候,也会有一个列阵来存放你的网络信息,包括IP,等等之类的。
并且从服务器主接口会自动分配一个子接口给你,然后你的ZMUD就可以跟服务器
通过这个子接口进行通信。当你要向所有玩家,也就是所有接口发讯系的时候。
服务器就会循环接口列阵,给每一个接口发送所需要的消息。这样,不就收到信息了吗?
这种服务器分配接口,有状态的连接,我们又叫做TCP连接。
另外你所说的MUD之间的互连,和上面那种连接又不一样了。
MUD间的互连就是MUD间通过事先定义好的IP列阵来发送信息。
这种发送方式不需要连接,它向某个地方发送一段消息,不管那个地方通不通,都发送。
而那边的服务器呢,就一直贞听某一知名端口,发现有人发信息,就不管三七二十一。
先收了再说,收了以后呢,再对发过来的东西进行解析,然后再进入运算层。
这种无需任何状态的连接,就叫无状态连接,又叫UDP连接。
区别:
打个比方吧,A和B住同一栋楼,两个不同单元。
A要喊B,有两种方法,一种是把头伸出窗户外面喊。
另一种方法就是打电话。但是呢,把头伸出窗外喊的话,就必须先确定B听到了这句话
我才能说下句话,而且B不在家的话,我也可以喊,只不过他听不到罢了。
而打电话呢,就必须在电话通了的情况下才能通话,但是通话的时候呢,你无须确定
他是否听见,因为他是肯定听得见的。
那种喊的方法呢,就是UDP连接。也就是MUD间的通信方式。
那种打电话的方法呢,就是TCP连接,也就是MUD内的玩家之间的通信方式。
前一种方法由于耗系统资源相当少,所以运用得十分广泛,现在的OICQ就是用的UDP连接。
但是呢,由于UDP连接无状态,所以无法保证消息的可靠性,这种方式应付聊天是最好不
过了。
后一种方法呢,由于消耗系统资源比较大,而且占带宽,所以,只有在对某些十分重要的
数据才用TCP连接,比如目前的TELNET,FTP等等都是用的TCP连接。
尊重作者 转载请注明出处52mud.com