// 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);
}
}
}