dns_masterold.c
来自「C实现的MUD,对大家基本入门网络游戏很有帮助!」· C语言 代码 · 共 721 行 · 第 1/2 页
C
721 行
// Ported to ES2 mudlib by Annihilator@ES2#include <mudlib.h>#include <socket_err.h>#include <net/config.h>#include <net/daemons.h>#include <net/dns.h>#include <net/socket.h>#include <net/services.h>#include <net/macros.h>#define DEBUG#define STD_SERVICE ({ "mail", "finger", "rwho_q", "tell", "gwizmsg" })#define MY_LOG_FILE "dns_master"inherit F_DBASE;private int my_port, socket_id;private mapping muds;private mapping mud_svc;private mapping this_host;private mixed * bootsrv;private int bootsrv_retry;private int seq_ctr;private mapping seq_entries;#ifdef DEBUG# define debug(x) if(monitor) message("diagnostic", (x), monitor)static object monitor = 0;#else# define debug(x)#endifint startup_udp();void send_udp(string host, int port, string msg);void read_callback(int sock, string msg, string addr);string start_message();private string *muds_ip, *muds_port, *muds_name;int check_mud(string ip, string port, string name);void init_database();void refresh_database();void do_pings();void set_mud_info(string name, mapping junk);void zap_mud_info(string name, mapping junk);void support_q_callback(mapping info);private void query_services(string mud, string address, string port, string tcp);int query_service_method(string mud, string service);mapping query_mud_info(string name);string get_host_name(string alias);int get_mudresource(string mud, string resource);int dns_mudp(string name);mapping query_muds();mapping query_svc();varargs int idx_request(function f);void sequence_callback(int idx, mixed param);void sequence_clean_up();#ifdef DEBUGmixed * query_bootsrv();void dump_sequencer();void set_monitor(object ob);object query_monitor();#endifprivate void restore_euid();void aux_log(string file, string entry);void aux_warning(string warning);private void log(string entry);void resolve_callback(string address, string my_ip, int key);int startup_udp(){ int err_no; if (socket_id) return 0; socket_id = socket_create(DATAGRAM, "read_callback", "close_callback"); if (socket_id < 0) { log("Failed to acquire socket.\n"); return 0; } err_no = socket_bind(socket_id, my_port); while( err_no == EEADDRINUSE ) { my_port++; err_no = socket_bind(socket_id, my_port); } if( err_no <= 0 ) { log( sprintf("Failed to bind socket of UDP services, error = %d.\n", err_no)); socket_close(socket_id); return 0; } return 1;}void send_udp(string host, int port, string msg){ int sock; if (!ACCESS_CHECK(previous_object())&& file_name(previous_object())[0..strlen(AUX_PATH) - 1] != AUX_PATH) return; if(sscanf(msg,"||TIME:%*s")==0) msg=replace_string(msg,"||NAME:", "||TIME:"+ctime(time())+"||NAME:",1); if(sscanf(msg,"||USERS:%*s")==0) msg=replace_string(msg,"||NAME:", "||USERS:"+sizeof(users())+"||NAME:",1); debug("DNS: Sending " + msg); sock = socket_create(DATAGRAM, "read_callback", "close_callback"); if (sock <= 0) { log("Failed to open socket to " + host + " " + port + "\n"); return; } socket_write(sock, msg, host + " " + port); socket_close(sock);}void read_callback(int sock, string msg, string addr){ string func, rest="", *bits, name, arg; mapping args; int i; debug("DNS: Got " + msg); if( !sscanf(msg, "@@@%s||%s@@@%*s", func, rest)) { if (!sscanf(msg, "@@@%s@@@%*s", func)) return; rest = ""; } sscanf(addr, "%s %*s", addr); if(strlen(rest)<2) return; bits = explode(rest, "||"); args = allocate_mapping(sizeof(bits)+3); i = sizeof(bits); while (i--) if (bits[i] && sscanf(bits[i], "%s:%s", name, arg) == 2) args[name] = arg; args["HOSTADDRESS"] = addr; if (args["NAME"]) { args["NAME"]= htonn(args["NAME"]); args["ALIAS"] = htonn(args["NAME"]); } if(!check_mud(addr,"","")) { return; } if (mapp(muds[args["NAME"]])) muds[args["NAME"]][DNS_NO_CONTACT] = 0; debug("DNS: got message "+mapp(muds[args["NAME"]])+ " "+args["NAME"]+"\n"); if (mapp(muds[args["NAME"]])) { if(!undefinedp(args["TIME"]) && args["TIME"]) muds[args["NAME"]]+=(["TIME":args["TIME"]]); if(!undefinedp(args["USERS"]) && args["USERS"]) muds[args["NAME"]]+=(["USERS":args["USERS"]]); } if (file_size(AUX_PATH + func + ".c") > 0) (AUX_PATH + func)->incoming_request(args);}int query_udp_port(){ return my_port;}string query_mud_name(){ return INTERMUD_MUD_NAME;}void send_shutdown(){ string *mud_names; int i; if(!muds || sizeof(muds)==0) return; mud_names = keys(muds); i = sizeof(mud_names); while (i--) SHUTDOWN->send_shutdown(muds[mud_names[i]]["HOSTADDRESS"], muds[mud_names[i]]["PORTUDP"]); socket_close(socket_id); CHANNEL_D->do_channel(this_object(), "sys", "送出网路关闭讯息。\n");}string start_message(){ return sprintf( "||MUDNAME:%s||NAME:%s||VERSION:%s||MUDLIB:%s||HOST:%s||PORT:%d" "||PORTUDP:%d||TCP:%s", MUD_NAME, Mud_name(), MUDLIB_VERSION, MUDLIB_NAME, query_host_name(), mud_port(), my_port, TCP_SERVICE_LEVEL);}void init_database(){ int i; string message, *list; if( MUDLIST_A->query_db_flag() ) { call_out("refresh_database", REFRESH_INTERVAL); call_out("sequence_clean_up", 4 * SERVICE_TIMEOUT); do_pings(); return; } message = sprintf("@@@%s%s@@@\n", DNS_STARTUP, start_message()); list = values( LISTNODES ); i = sizeof( list ); while( i-- ) { sscanf( list[i], "%s %d", bootsrv[0], bootsrv[1] ); send_udp(bootsrv[0], bootsrv[1], message); MUDLIST_Q->send_mudlist_q(bootsrv[0], bootsrv[1]); } call_out("init_database", 60); return;}void refresh_database(){ int i; string *list; while(find_call_out("refresh_database") != -1){ } call_out("refresh_database", REFRESH_INTERVAL); list = values( LISTNODES ); i = sizeof( list ); while( i-- ) { sscanf( list[i], "%s %d", bootsrv[0], bootsrv[1] ); MUDLIST_Q->send_mudlist_q(bootsrv[0], bootsrv[1]); }}void do_pings(){ int i; string *mud_names; if(find_call_out("do_pings") != -1) return; call_out("do_pings", PING_INTERVAL); mud_names = keys(muds); i = sizeof(mud_names); while (i--) { if(undefinedp(mud_svc[mud_names[i]])) continue; muds[mud_names[i]] [DNS_NO_CONTACT]++; PING_Q->send_ping_q(muds[mud_names[i]]["HOSTADDRESS"], muds[mud_names[i]]["PORTUDP"]); if (muds[mud_names[i]][DNS_NO_CONTACT] >= MAX_RETRYS) zap_mud_info(mud_names[i], 0); }}void set_mud_info(string name, mapping junk){ string tcp; int new_mud; int svc; if( !(ACCESS_CHECK(previous_object()))&& file_name(previous_object())[0..strlen(AUX_PATH) - 1] != AUX_PATH) return; name = htonn( name ); while( name[strlen(name)-1] == '.' ) name = name[ 0..strlen(name)-2 ]; if (name == mud_nname()) return; if(undefinedp(junk["PORTUDP"])|| undefinedp(junk["HOSTADDRESS"])|| undefinedp(junk["NAME"]) || !check_mud(junk["HOSTADDRESS"], junk["PORTUDP"],junk["NAME"])) { return; } junk["NAME"] = htonn(junk["NAME"]); junk["ALIAS"] = nntoh( junk["NAME"] ); if( (undefinedp(muds[name]) || undefinedp(muds[name]["TIME"]))&& !undefinedp(junk["TIME"]) ) CHANNEL_D->do_channel(this_object(), "sys", junk["MUDNAME"]+"("+junk["NAME"]+") "+ junk["HOSTADDRESS"]+" "+junk["PORT"]+" 加入互连。"); if (!undefinedp(mud_svc[name])) { muds[name] = junk; return; } if (!undefinedp(muds[name])) this_object()->aux_log("dns_mud_conv", "Udp contact from: "+name+"\n"); if (!junk["TCP"]) junk["TCP"] = TCP_NONE; muds[name] = junk; tcp = junk["TCP"]; switch (tcp) { case TCP_ALL: mud_svc[name] = ([ "mail" : SVC_TCP, "finger" : SVC_TCP | SVC_UDP | SVC_KNOWN, "tell" : SVC_TCP | SVC_UDP | SVC_KNOWN, "rwho_q" : SVC_UDP, "gwizmsg" : SVC_UDP, ]); break; case TCP_ONLY: mud_svc[name] = ([ "mail" : SVC_TCP | SVC_NO_UDP | SVC_KNOWN, "finger" : SVC_TCP | SVC_NO_UDP | SVC_KNOWN, "tell" : SVC_TCP | SVC_NO_UDP | SVC_KNOWN, "rwho_q" : SVC_NO_UDP, "gwizmsg" : SVC_NO_UDP, ]); break; case TCP_SOME: mud_svc[name] = ([ "mail" : SVC_UNKNOWN, "finger" : SVC_UDP, "tell" : SVC_UDP, "rwho_q" : SVC_UDP, "gwizmsg" : SVC_UDP, ]); break; default: mud_svc[name] = ([ "mail" : SVC_NO_TCP, "finger" : SVC_NO_TCP | SVC_UDP | SVC_KNOWN, "tell" : SVC_NO_TCP | SVC_UDP | SVC_KNOWN, "rwho_q" : SVC_NO_TCP | SVC_UDP | SVC_KNOWN, "gwizmsg" : SVC_NO_TCP | SVC_UDP | SVC_KNOWN, ]); break;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?