dsII/extra/wolfpaw/
dsII/lib/cmds/admins/
dsII/lib/cmds/common/
dsII/lib/cmds/creators/include/
dsII/lib/cmds/creators/include/SCCS/
dsII/lib/daemon/services/
dsII/lib/doc/
dsII/lib/domains/Ylsrim/
dsII/lib/domains/Ylsrim/adm/
dsII/lib/domains/Ylsrim/armor/
dsII/lib/domains/Ylsrim/broken/
dsII/lib/domains/Ylsrim/fish/
dsII/lib/domains/Ylsrim/meal/
dsII/lib/domains/Ylsrim/npc/
dsII/lib/domains/Ylsrim/virtual/
dsII/lib/domains/Ylsrim/weapon/
dsII/lib/domains/campus/adm/
dsII/lib/domains/campus/etc/
dsII/lib/domains/campus/meals/
dsII/lib/domains/campus/npc/
dsII/lib/domains/campus/txt/
dsII/lib/domains/campus/txt/ai/charles/
dsII/lib/domains/campus/txt/ai/charles/bak2/
dsII/lib/domains/campus/txt/ai/charles/bak2/bak1/
dsII/lib/domains/campus/txt/ai/charly/
dsII/lib/domains/campus/txt/ai/charly/bak/
dsII/lib/domains/campus/txt/jenny/
dsII/lib/domains/default/creator/
dsII/lib/domains/default/doors/
dsII/lib/domains/default/etc/
dsII/lib/domains/default/weap/
dsII/lib/domains/town/doors/
dsII/lib/domains/town/txt/
dsII/lib/domains/town/virtual/
dsII/lib/lib/comp/
dsII/lib/lib/lvs/
dsII/lib/lib/user/
dsII/lib/lib/virtual/
dsII/lib/log/archive/
dsII/lib/log/chan/
dsII/lib/log/errors/
dsII/lib/log/open/
dsII/lib/obj/book_source/
dsII/lib/obj/include/
dsII/lib/realms/template/
dsII/lib/realms/template/area/armor/
dsII/lib/realms/template/area/npc/
dsII/lib/realms/template/area/obj/
dsII/lib/realms/template/area/room/
dsII/lib/realms/template/area/weap/
dsII/lib/realms/template/bak/
dsII/lib/realms/template/cmds/
dsII/lib/save/
dsII/lib/save/kills/o/
dsII/lib/secure/cfg/
dsII/lib/secure/cfg/classes/
dsII/lib/secure/cfg/races/SCCS/
dsII/lib/secure/cmds/creators/include/
dsII/lib/secure/cmds/players/
dsII/lib/secure/cmds/players/include/
dsII/lib/secure/daemon/include/
dsII/lib/secure/lib/
dsII/lib/secure/lib/include/
dsII/lib/secure/lib/net/
dsII/lib/secure/lib/net/include/
dsII/lib/secure/lib/std/
dsII/lib/secure/modules/
dsII/lib/secure/npc/
dsII/lib/secure/obj/include/
dsII/lib/secure/room/
dsII/lib/secure/save/boards/
dsII/lib/secure/save/postal/c/cratylus/
dsII/lib/secure/save/votes/
dsII/lib/secure/tmp/
dsII/lib/secure/verbs/creators/
dsII/lib/shadows/
dsII/lib/spells/
dsII/lib/tmp/
dsII/lib/verbs/admins/include/
dsII/lib/verbs/common/
dsII/lib/verbs/common/include/
dsII/lib/verbs/creators/include/
dsII/lib/verbs/players/include/SCCS/
dsII/lib/verbs/rooms/
dsII/lib/verbs/rooms/include/
dsII/lib/www/
dsII/v22.2b14/
dsII/v22.2b14/Win32/
dsII/v22.2b14/compat/
dsII/v22.2b14/compat/simuls/
dsII/v22.2b14/testsuite/
dsII/v22.2b14/testsuite/clone/
dsII/v22.2b14/testsuite/command/
dsII/v22.2b14/testsuite/data/
dsII/v22.2b14/testsuite/etc/
dsII/v22.2b14/testsuite/include/
dsII/v22.2b14/testsuite/inherit/
dsII/v22.2b14/testsuite/inherit/master/
dsII/v22.2b14/testsuite/log/
dsII/v22.2b14/testsuite/single/
dsII/v22.2b14/testsuite/single/tests/compiler/
dsII/v22.2b14/testsuite/single/tests/efuns/
dsII/v22.2b14/testsuite/single/tests/operators/
dsII/v22.2b14/testsuite/u/
dsII/v22.2b14/tmp/
dsII/win32/
// I3 server.
// This file written completely by Tim Johnson (Tim@TimMUD)
// Started by Tim on May 7, 2003.
// http://cie.imaginary.com/protocols/intermud3.html#errors
#include <lib.h>
#include <socket.h>
#include <socket_err.h>
#define DEB_IN  1	// trr-Incoming
#define DEB_OUT 2	// trr-Outgoing
#define DEB_INVALID 3	// trr-Invalid
#define DEB_OTHER 0	// trr-Other
#define MYSERVER 9000	// Port to accept connections on.
#define DEBUGGER_GUY "cratylus"	// Name of who to display trrging info to.
#undef DEBUGGER_GUY
#define DEBUGGER_GUY "guest"
#define MAXIMUM_RETRIES 5
// SEND_WHOLE_MUDLIST makes it act like the official I3 server instead of like the I3 specs
#define SEND_WHOLE_MUDLIST
// SEND_WHOLE_CHANLIST makes it act like the official I3 server instead of like the I3 specs
#define SEND_WHOLE_CHANLIST
inherit LIB_CLEAN;

// Unsaved variables...
static private int router_socket;
// socket that the router is using
static private mapping sockets;
// physically connected sockets and their info
static private mapping connected_muds;
// muds that have successfully done a startup
// (key=mudname, value=fd)
//static private
mapping listening;
// list of muds listening to each channel
// (key=chan name, value=mud array)

// Saved variables...
string router_name; // Name of the router.
string *router_list; // Ordered list of routers to use.
mapping mudinfo; // Info about all the muds which the router knows about.
mapping channels; // Info about all the channels the router handles.
mapping channel_updates; // Tells when a channel was last changed.
int channel_update_counter; // Counter for the most recent change.
// Why is this not a part of the channels mapping?
// Because I need to remember that some channels got deleted.
mapping mudinfo_updates; // Like channel_updates except for muds.
int mudinfo_update_counter; // Similar to channel_update_counter

// Prototypes
void write_data(int fd, mixed data);
void close_connection(int fd);
static mapping muds_on_this_fd(int fd);
static mapping muds_not_on_this_fd(int fd);
static void broadcast_data(mapping targets, mixed data);
// Ones with their own files...
static void broadcast_chanlist(string channame);
static void broadcast_mudlist(string mudname);
static varargs void Debug(string str, int level);
static void process_channel(int fd, mixed *info);
static void process_startup_req(int protocol, mixed info, int fd);
static void read_callback(int fd, mixed info);
static void remove_mud(string mudname);
static void send_chanlist_reply(string mudname, int old_chanid);
static void send_mudlist(string mudname);
static void send_mudlist_updates(string updating_mudname, int old_mudlist_id);
static void send_startup_reply(string mudname);
static void send_error(string mud, string user, string errcode, string errmsg, mixed *info);
// core_stuff.h...
static void create();
static void setup();
void remove();
// funcs.h...
static mapping muds_on_this_fd(int fd);
int value_equals(string a,int b, int c);
static mapping muds_not_on_this_fd(int fd);
int value_not_equals(string a,int b, int c);
// socket_stuff.h
static void close_callback(int fd);
static void listen_callback(int fd);
static void write_data_retry(int fd, mixed data, int counter);
static void close_connection(int fd);
static void write_data(int fd, mixed data);
static void broadcast_data(mapping targets, mixed data);

// Code for all the stuff in the prototypes...
#include "./broadcast_chanlist.h"
#include "./broadcast_mudlist.h"
#include "./debug.h"
#include "./process_channel.h"
#include "./process_startup_req.h"
#include "./read_callback.h"
#include "./remove_mud.h"
#include "./send_chanlist_reply.h"
#include "./send_mudlist_updates.h"
#include "./send_startup_reply.h"
#include "./send_error.h"

#include "./core_stuff.h"
#include "./funcs.h"
#include "./socket_stuff.h"
#include "./hosted_channels.h"

// trrging stuff...
mapping query_mudinfo(){ return copy(mudinfo); }
mapping query_mud(string str){ return copy(mudinfo[str]); }
void get_info() {
    write_file ("/tmp/info.txt",
      "router_name: "+router_name+
      "\nrouter_list"+identify(router_list)+
      "\nchannel_update_counter: "+ channel_update_counter+
      "\nchannels:"+identify(channels)+
      "\nchannel_updates:"+identify(channel_updates)+
      "\nlistening:"+identify(listening)+
      "\nmudinfo:"+identify(mudinfo)+
      "\nmudinfo_update_counter: "+ mudinfo_update_counter+
      "\nmudinfo_updates:"+identify(mudinfo_updates)+
      "\nconnected:"+identify(connected_muds)+"\n");
}
void clear(){ string mudname; foreach(mudname in keys(mudinfo)) remove_mud(mudname); 
}

mapping GetConnectedMuds(){
    return copy(connected_muds);
}

string *AddBannedMud(string str){
    if( !((int)master()->valid_apply(({ "SECURE" }))) )
	error("Illegal attempt to access admintool: "+get_stack()+" "+identify(previous_object(-1)));

    banned_muds += ({ str });
    return banned_muds;
}

string *RemoveBannedMud(string str){
    if( !((int)master()->valid_apply(({ "SECURE" }))) )
	error("Illegal attempt to access admintool: "+get_stack()+" "+identify(previous_object(-1)));

    banned_muds -= ({ str });
    return banned_muds;
}

void clear_discs(){ 
    string mudname; 
    foreach(mudname in keys(mudinfo)) {
	if(query_mud(mudname)["disconnect_time"] &&
	  time() - query_mud(mudname)["disconnect_time"] > 60 &&
	  time() - query_mud(mudname)["disconnect_time"] < 80){
	    //trr("Removing mud: "+identify(mudname),"red");
	    //remove_mud(mudname);
	    trr("Broadcasting updated mudlist.","white");
	    broadcast_mudlist(mudname);

	}
    }
}