|
调整Mud登陆流程。
为了这个我差不多把fluffos和我手头的mudlib读了几遍,终于把这个理顺了。
首先,fluffos这东西本质和客户端一样,有个主脚本入口。定义在config文件中,
比如我手头的mudlib是
- master file : /adm/kernel/master
复制代码 这个具体由fluffos的src/comm.cc负责
用户请求连入后,会先在调用comm.cc里的new_conn_handler
- auto *user = new_user(port, fd, addr, addrlen);
- new_user_event_listener(base, user);
- if (user->connection_type == PORT_TYPE_TELNET) {
- user->telnet = net_telnet_init(user);
- send_initial_telnet_negotiations(user);
- }
- event_base_once(
- base, -1, EV_TIMEOUT,
- [](evutil_socket_t /*fd*/, short /*what*/, void *arg) {
- auto *user = reinterpret_cast(arg);
- on_user_logon(user);
- },
- (void *)user, nullptr);
复制代码
new_user是一个interactive_t对象,本质代表了一个连接
这代码就是初始化新连接,初始化telnet的一些协商,然后调用on_user_login方法,开始尝试登陆
on_user_logon的代码为
- void on_user_logon(interactive_t *user) {
- set_command_giver(master_ob);
- master_ob->flags |= O_ONCE_INTERACTIVE;
- master_ob->interactive = user;
- /*
- * The user object has one extra reference. It is asserted that the
- * master_ob is loaded. Save a pointer to the master ob incase it
- * changes during APPLY_CONNECT. We want to free the reference on
- * the right copy of the object.
- */
- object_t *master, *ob;
- svalue_t *ret;
- master = master_ob;
- add_ref(master_ob, "new_user");
- push_number(user->local_port);
- set_eval(max_eval_cost);
- ret = safe_apply_master_ob(APPLY_CONNECT, 1);
- /* master_ob->interactive can be zero if the master object self
- destructed in the above (don't ask) */
- set_command_giver(nullptr);
复制代码 这个一眼看上去就和lua差不多……
里面其实有个重要的地方,就是master_ob->interactive = user;,连接所有权的转交。之前没接触过mudos,fluffos的文档又不全,这东西看代码卡了我很久……
代码很明显,压入一个数字参数 local port,调用 APPLY_CONNECT方法初始化。
这一段在我的mudlib里是这样的
- object connect(int port)
- {
- object login_ob;
- mixed err;
- err = catch(login_ob = new(LOGIN_OB));
- set_encoding("GBK");
- //if(port == GBK_PORT)
- //{
- // login_ob->set_temp("GBK",1);
- // set_encoding("GBK");
- //}
-
- if (err)
- {
- write("现在有人正在修改使用者连线部份的程式,请待会再来。\n");
- write(err);
- destruct(this_object());
- }
- return login_ob;
- }
复制代码 master.c作为入口负责接受新请求,然后初始化一个登陆对象抛会去。
登陆对象定义在include/globals.h里
- #define LOGIN_OB "/clone/user/login"
复制代码 指向了clone/user/login文件。
这是一个登陆对象,指的是登陆中的用户。很明显,初始化后,用户登陆前,这是我们需要接入的地方。
回到fluffos源代码,初始化后
- ob = ret->u.ob;
- ob->interactive = master_ob->interactive;
- ob->interactive->ob = ob;
- ob->flags |= O_ONCE_INTERACTIVE;
- /*
- * assume the existance of write_prompt and process_input in user.c
- * until proven wrong (after trying to call them).
- */
- ob->interactive->iflags |= (HAS_WRITE_PROMPT | HAS_PROCESS_INPUT);
- free_object(&master, "new_user");
- master_ob->flags &= ~O_ONCE_INTERACTIVE;
- master_ob->interactive = nullptr;
- add_ref(ob, "new_user");
- // start reverse DNS probing.
- query_name_by_addr(ob);
- set_command_giver(ob);
- set_prompt("> ");
- // Call logon() on the object.
- set_eval(max_eval_cost);
- ret = safe_apply(APPLY_LOGON, ob, 0, ORIGIN_DRIVER);
- if (ret == nullptr) {
- debug_message("new_conn_handler: logon() on object %s has failed, the user is disconnected.\n",
- ob->obname);
- remove_interactive(ob, false);
复制代码 主对象把输入接口转交给登陆对象,一次交接,然后开始调用登陆对象logon函数
- void logon()
- {
- remove_call_out("time_out");
- call_out("time_out", LOGIN_TIMEOUT);
- if (interactive(this_object()))
- {
- //log_file("static/logon", sprintf("%s %s\n", ctime(time()), query_ip_number(this_object())));
- set_temp("ip_number", query_ip_number(this_object()));
- }
- LOGIN_D->logon(this_object());
- }
复制代码 很明显,设置ip地址,然后调用登陆服务(根据登陆信息生成玩家对象,转移输入接口所有权,这里坑了我一天,我用登陆对象发gmcp怎么都发不出去,拉最新的fluffos编译再调整兼容性都不行)
我们要改的必然又是这里。目标找到,开始改。
|
|