mail_q.c
来自「C实现的MUD,对大家基本入门网络游戏很有帮助!」· C语言 代码 · 共 220 行
C
220 行
/*//// File : mail_q.c// Author : Inspiral@Tabor// Created : 93-08-20// Purpose : Handles the receipt/transmission of udp mail messages//*/ #include <net/dns.h>#include <net/daemons.h>#include <net/config.h>#include <net/macros.h> inherit F_CLEAN_UP;inherit F_SAVE; #define WHO find_player( "inspiral" )#define TELL( x ) if( WHO ) tell_object( WHO, x + "\n" ) // keys: mudname// values: int representing the index of the msg we are on.mapping mail_outgoing; // keys: mudname// values: the fields in the mail message...WIZTO, CC, MSG, etc.mapping mail_incoming; void create(){ seteuid( getuid() ); mail_outgoing = ([ ]); mail_incoming = ([ ]); // Turn saving 'on' in the save daemon.} string query_save_file() { return DATA_DIR + "netmail"; } // We're sent here by mail_a or ping_avarargs void check_for_mail( string mudname, int flag ){ mapping outmsg, info; string package; int index, size; outmsg = ([ ]); mudname = htonn( mudname );// outmsg = ( mapping ) NETMAIL_D -> check_for_mail( mudname ); switch( flag ) { case 3: // A ping_a calls this, as does the netmail server. // It simply means: start sending if there's anything to send, // or continue with the current message we are sending. if( !mail_outgoing[mudname] ) { // We will have something to send to this mud, and currently, // there is nothing in our mail_q outgoing buffer. So, we // properly initialize it. mail_outgoing[mudname] = ([ ]); } // There seem to be indices for this mud in the mail_q, but no mail to // be found to send to them...most likely due to an admin purge // of old or bad mail. if( !sizeof( outmsg ) ) { map_delete( mail_outgoing, mudname ); break; } // If more than a minute has passed since the last time we've // sent to this mud, start over, since something on one or both ends // could be out of sync./* if( time() - mail_outgoing[mudname]["time"] > 60 ) { mail_outgoing[mudname] = ([ "time": time(), "index" : 0 ]); }*/ // Do nothing, since it came from a ping while we are sending. break; case 2: case 1: // case 1 is when the other mud wants us to resend the current // message, case 2 is when they want us to send our next message, // if we have one. if( !sizeof( outmsg ) ) { // Nothing to be sent out now, so clear the status. // We shouldn't get here from case 1, only case 2. map_delete( mail_outgoing, mudname ); break; } // Reset the index and time; mail_outgoing[mudname] = ([ "time" : time(), "index" : 0 ]); break; case 0: // We get 0 from mail_a, so we continue sending the current message. mail_outgoing[mudname]["time"] = time(); mail_outgoing[mudname]["index"] += MAIL_PACKET_SIZE; break; } // One last check on our stack for this mud, before we send data. if( !sizeof( outmsg ) || !mail_outgoing[mudname] ) return; info = ( mapping ) DNS_MASTER -> query_mud_info( mudname ); if( !info || !info["NAME"] || !info["PORTUDP"] ) return; TELL( "MAILQ: Sending to " + mudname ); outmsg["MSG"] = replace_string( outmsg["MSG"], "|", " \b|" ); outmsg["MSG"] = replace_string( outmsg["MSG"], "@", " \b@" ); TELL( "message size: " + strlen( outmsg["MSG"] ) ); package = "@@@" + DNS_MAIL_Q + "||NAME:" + Mud_name() + "||PORTUDP:" + udp_port(); if( !mail_outgoing[mudname]["index"] ) { package += "||WIZTO:" + outmsg["WIZTO"] + "||WIZFROM:" + outmsg["WIZFROM"] + "||DATE:" + time() + "||SUBJECT:" + outmsg["SUBJECT"]; if( outmsg["CC"] ) package += "||CC:" + outmsg["CC"]; } index = mail_outgoing[mudname]["index"]; size = strlen( outmsg["MSG"] ); if( size <= MAIL_PACKET_SIZE || ( (index-1) + MAIL_PACKET_SIZE ) >= size ) { TELL( "Sending ENDMSG:1." ); package += "||ENDMSG:1"; } TELL( "MAILQ: Sending: " + (index) + ".." + ((index-1)+MAIL_PACKET_SIZE) ); package += "||MSG:" + outmsg["MSG"][(index)..( (index-1) + MAIL_PACKET_SIZE )]; package += "@@@\n"; DNS_MASTER -> send_udp( info["HOSTADDRESS"], info["PORTUDP"], package ); return;} // If we are here, then we are receiving mail from a mud.void incoming_request( mapping info ) { if( !info["NAME"] || !info["PORTUDP"] ) return; if( !DNS_MASTER -> query_mud_info( info["NAME"] ) ) PING_Q -> send_ping_q( info["HOSTADDRESS"], info["PORTUDP"] ); // Here we put the info in something netmail can use.// info["MSG"] = strip_backspace( info["MSG"] ); if( info["WIZTO"] ) { // If they send us a WIZTO field, we assume (rightly) that this // is a new message, so we effectively set our buffer for this // particular mud with whatever we've been sent. mail_incoming[ info["NAME"] ] = info; } else { // If we have no data in the incoming buffer for this mud, and // the mud didn't send us a WIZTO field, something must have gone // wrong, so we ask them to RESEND the message from the beginning. if( !mail_incoming[ info["NAME"] ] ) info[ "RESEND" ] = 1; else mail_incoming[info["NAME"]]["MSG"] += info["MSG"]; } // Send them an affirmation that we receive the mail, and suitable // affirm also if they sent us an ENDMSG flag (which indicates that // we can process the message. // If we send RESEND:1, we are asking them to resend the message. DNS_MASTER -> send_udp( info["HOSTADDRESS"], info["PORTUDP"], "@@@" + DNS_MAIL_A + "||NAME:" + Mud_name() + "||PORTUDP:" + udp_port() + ( info["ENDMSG"] ? "||ENDMSG:1" : "" ) + ( info["RESEND"] ? "||RESEND:1" : "" ) + "@@@\n" ); TELL( "MAILQ: Sending mail_a " + ( info["ENDMSG"] ? ", ENDMSG:1 " : "" ) + ( info["RESEND"] ? ", RESEND:1" : "" ) + "." ); if( info["ENDMSG"] ) { // If we received an ENDMSG, then we are ready to process the contents // of our buffer. So, we send off the packet, and clear the incoming // buffer for that mud. TELL( "MAILQ: Sending to netmail." ); catch( NETMAIL_D -> incoming_mail( mail_incoming[ info["NAME"] ] ) ); map_delete( mail_incoming, info["NAME"] ); }} // This is nice for debugging.void get_status() {// write( "mail_outgoing:\n" + identify( mail_outgoing ) + // "\nmail_incoming:\n" + identify( mail_incoming ) + "\n" );} void clear_queues() { mail_outgoing = ([ ]); mail_incoming = ([ ]);} /* EOF */
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?