/* Dosmud hack */ #include "std.h" #include "udp.h" #include "socket.h" #include "inet.h" /* * This has the list of cd muds that are known. We get this from the * mudlist server when we boot. */ #undef DEBUG #ifdef DEBUG #define TP(STR) if (find_player("pinkfish")) tell_object(find_player("pinkfish"), STR) #else #define TP(STR) #endif object monitor; mapping known_muds; int my_port, my_socket; void create() { known_muds = ([ ]); seteuid( getuid() ); call_out( "send_startup_udp", 2 ); call_out( "do_pings", 30 * 60 ); /* Do this every 5 minutes */ } /* create() */ void send_startup_udp() { NAMESERVER->lookup_service( "cd_udp", ( MUD_NAME ), "finish_lookup" ); } /* send_startup_udp() */ void do_pings() { int i; string *muds, ping_packet; call_out( "do_pings", 5 * 60 ); /* Both to keep us alive in tehir arrays and to check on dead muds. */ muds = keys( known_muds ); for( i = 0; i < sizeof( muds ); i++ ) { if( !mapp( known_muds[ muds[ i ] ] ) ) continue; known_muds[ muds[ i ] ][ UDP_NO_CONTACT ] = known_muds[ muds[ i ] ][ UDP_NO_CONTACT ] + 1; PING_Q->send_ping_q( known_muds[ muds[ i ] ][ "HOSTADDRESS" ], known_muds[ muds[ i ] ][ "PORTUDP" ] ); if( known_muds[ muds[ i ] ][ UDP_NO_CONTACT ] >= MAX_RETRYS ) { map_delete( known_muds, muds[ i ] ); } } } /* do_pings() */ void finish_lookup( string service, string addr, int port, mixed *args ) { string host; int dport, i; mixed * muds; TP( "Finished lookup.\n" ); TP( service + ":" + addr + ":" + port + "\n" ); my_port = 6942; muds = MUDLIST_UDP; for( i = 0; i < sizeof( muds ); i += 2 ) { this_object()->send_udp( muds[ i ], muds[ i + 1 ], "@@@" + UDP_STARTUP + this_object()->start_message() + "@@@\n" ); (UDP_PATH + "mudlist_q")->send_mudlist_q( muds[ i ], muds[ i + 1 ] ); } if( !my_socket ) { TP( "Creating socket.\n" ); my_socket = socket_create( DATAGRAM, "read_callback", "close_callback" ); if( my_socket <= 0 ) return; TP( "Binding socket.\n" ); if( socket_bind( my_socket, my_port ) <= 0 ) { TP( "Failing to bind....\n" ); socket_close( my_socket ); } } } /* finish_lookup() */ string start_message() { return "||NAME:" + capitalize( MUD_NAME ) + "||VERSION:10.10" + "||MUDLIB:Discworld" + "||HOST:" + query_host_name() + "||PORT:7680" + "||TCP:some" + "||PORTUDP:" + my_port + "||TIME:" + ctime( time() ); } /* start_message() */ void send_udp( string host, int port, string msg ) { int sock; if( monitor ) tell_object( monitor, "Sending " + msg ); sock = socket_create( DATAGRAM, "read_callback", "close_callback" ); if( sock <= 0 ) { log_file( "CD_NAMESERVER", "Failed to open socket to " + host + " " + port + "\n" ); return; } socket_write( sock, msg, host + " " + port ); socket_close( sock ); } /* send_udp() */ void read_callback( int sock, string msg, string addr ) { string func, rest, *bits, name, arg; mapping args; int i; if( !msg ) msg = ""; /* if(bits[i]) */ if( monitor ) tell_object( monitor, "Got " + msg ); if( !sscanf( msg, "@@@%s||%s@@@%*s", func, rest ) ) { if( !sscanf( msg, "@@@%s@@@%*s", func ) ) { return; } rest = ""; } sscanf( addr, "%s %*s", addr ); if( rest ) bits = explode( rest, "||" ); else bits = ({ }); args = ([ ]); for( i = 0; i < sizeof( bits ); i++ ) { if( bits[ i ] ) if( sscanf( bits[ i ], "%s:%s", name, arg ) == 2 ) { args[ name ] = arg; } } args[ "HOSTADDRESS" ] = addr; if( mapp( known_muds[ args[ "NAME" ] ] ) ) known_muds[ args[ "NAME" ] ][ UDP_NO_CONTACT ] = 0; /* Ok, now we need to lookup the command and execute it... */ if( file_size( UDP_PATH + func + ".c" ) > 0 ) (UDP_PATH + func)->incoming_request( args ); /* Otherwise, we just ignore it... */ } /* read_callback() */ mapping query_known_muds() { return known_muds + ([ ]); } void set_mud_info( string name, mapping junk ) { if( previous_object() != this_object() && file_name( previous_object() )[ 0..strlen( UDP_PATH ) - 1 ] != UDP_PATH ) return; if( !known_muds[ name ] ) { /* Send them a mudlist query... */ (UDP_PATH + "mudlist_q")->send_mudlist_q( junk[ "HOSTADDRESS" ], junk[ "PORTUDP" ] ); } known_muds[ name ] = junk; if( lower_case( name ) != name ) known_muds[ lower_case( name ) ] = name; } /* set_mud_info() */ void zap_mud_info( string name, mapping junk ) { if( previous_object() != this_object() && file_name( previous_object() )[ 0..strlen( UDP_PATH ) - 1 ] != UDP_PATH ) return; map_delete( known_muds, name ); } /* zap_mud_info() */ mapping query_mud_info( string name ) { mixed bing; bing = known_muds[ name ]; if( stringp( bing ) ) return known_muds[ bing ]; return bing; } /* query_mud_info() */ int query_my_port() { return my_port; } void set_monitor( object ob ) { monitor = ob; } object query_monitor() { return monitor; }