mud/lib/secure/daemon/mudinfo.c
2020-09-06 05:43:07 -07:00

294 lines
7.3 KiB
C

#include <daemons.h>
#include <lib.h>
#include <save.h>
#include NETWORK_H
inherit LIB_DAEMON;
mapping MudList = ([]);
mapping Unconnected = ([]);
mapping Status = ([]);
mapping Confirmed = ([]);
int attempting, connected, socket ;
object person, player;
string preset;
int age, probing;
string *queue = ({});
static string SaveFile;
int SetQueue(string str){
if(file_exists(str)){
foreach(string line in explode(read_file(str),"\n")){
queue += ({ trim(line) });
}
}
return 1;
}
int SetProbing(int x){
if(x) probing = 1;
else probing = 0;
this_object()->PrintUnconnectedInfo();
return probing;
}
string GetMudName(string mud){
if( MudList[mud] ) return mud;
foreach(string name in keys(MudList)){
if(lower_case(name) == lower_case(mud)) return name;
}
return 0;
}
int PrintMudInfo(string str){
mixed *info;
mixed *list;
mapping borg;
string mud, tempy;
int all = 0;
if(!MudList && unguarded((: file_exists(SaveFile) :))){
RestoreObject(SaveFile, 1);
}
if(!MudList) MudList = ([]);
if(!str || str == "all"){
write("Total muds: "+sizeof(MudList));
write("Muds: "+implode(sort_array(keys(MudList), 1),", "));
return 1;
}
list = INTERMUD_D->GetMudList();
if(mapp(list)){
foreach(mixed key, mixed val in list){
MudList[key] = val;
}
}
if(sizeof(str) && sizeof(tempy = INTERMUD_D->GetMudName(str) )) str = tempy;
if(!tempy){
if(MudList) tempy = GetMudName(str);
}
if(!tempy){
write("Mud not found.");
return 1;
}
info = INTERMUD_D->GetMudList()[tempy];
if(!info) info = MudList[tempy];
if(!info){
write("No information available on "+tempy);
return 1;
}
write("Mudname: "+tempy);
write("Status: "+(info[0] < 0 ? "online" : "offline"));
write("IP address: "+info[1]);
write("Port: "+info[2]);
write("imud out-of-band (tcp OOB) port: "+info[3]);
write("imud udp port (obsolete): "+info[4]);
write("mudlib: "+info[5]);
write("base mudlib: "+info[6]);
write("driver: "+info[7]);
write("mud type: "+info[8]);
write("open status: "+info[9]);
write("admin email: "+info[10]);
if(sizeof(info[11])){
string tmp = "Services: ";
foreach(mixed key, mixed val in info[11]){
if(val) tmp += key+" ";
}
write(tmp+"\n");
}
if(sizeof(info[12])){
write("extra info\n---------- ");
foreach(mixed key, mixed val in info[12]){
write(identify(key)+": "+identify(val));
}
}
return 1;
}
int ReceiveMudInfo(string str,mapping info){
if(!MudList[str]) MudList[str] = info;
return sizeof(MudList[str]);
}
void GenerateConnectionPage(){
string ret = "<html>";
foreach(mixed key in sort_array(keys(MudList),1)){
mapping val = MudList[key];
if(val[0] < 0){
ret += key + " ";
ret += val[6] + " ";
ret += val[1]+" "+val[2]+"<br>";
}
}
write_file("/www/mudlist.html",ret,1);
}
void create(){
mapping list = INTERMUD_D->GetMudList();
SaveFile = save_file(SAVE_MUDINFO);
attempting = 0 ;
connected = 0 ;
socket = 0 ;
person = 0 ;
set_heart_beat(1);
if(unguarded((: file_exists(SaveFile) :))){
RestoreObject(SaveFile);
}
if(mapp(list)){
foreach(mixed key, mixed val in list){
if(!MudList[key]) MudList[key] = val;
}
}
SaveObject(SaveFile);
}
int PrintUnconnectedInfo(){
int rebuild;
if(!Unconnected) Unconnected = ([]);
if(!sizeof(Unconnected)) rebuild = 1;
foreach(mixed key, mixed val in MudList){
if(val[0] != -1){
if(this_player()) write(key+": telnet "+val[1]+" "+val[2]);
if(rebuild) Unconnected[key] = ([ "ip": val[1], "port" : val[2] ]);
}
}
return 1;
}
void heart_beat(){
if(!this_object()) return;
if(time() > age + 2){
this_object()->do_reset();
}
if(sizeof(queue)){
this_object()->do_connect(queue[0], queue[0]);
if(sizeof(queue) > 1) queue = queue[1..];
else queue = ({});
}
else if(probing && !connected && !attempting && sizeof(Unconnected)){
string target = keys(Unconnected)[0];
this_object()->do_connect(Unconnected[target]["ip"]+
" "+Unconnected[target]["port"], target);
map_delete(Unconnected, target);
}
}
void SetConnection(string str){
if(str) preset = str;
}
int do_reconnect()
{
if( !connected )
{
notify_fail( "The telnet client is not connected!\n" ) ;
return 0 ;
}
write("Reconnecting into telnet session.\n");
person = this_player() ;
input_to( "parse_comm", 0 ) ;
return 1 ;
}
int do_reset( string args )
{
if( socket ){
socket_close( socket ) ;
}
attempting = 0 ;
connected = 0 ;
socket = 0 ;
return 1 ;
}
varargs int do_connect(string args, string mud){
int new_socket, sc_result, port ;
string error, ip_address ;
if(preset) args = preset;
if( sscanf( args, "%s %d", ip_address, port ) != 2 ){
return 0 ;
}
if( attempting || connected ){
return 0 ;
}
new_socket = socket_create( STREAM, "read_callback", "close_callback" ) ;
if( new_socket < 0 ){
switch( new_socket ){
case EEMODENOTSUPP :
error = "Socket mode not supported.\n" ;
break ;
case EESOCKET :
error = "Problem creating socket.\n" ;
break ;
case EESETSOCKOPT :
error = "Problem with setsockopt.\n" ;
break ;
case EENONBLOCK :
error = "Problem with setting non-blocking mode.\n" ;
break ;
case EENOSOCKS :
error = "No more available efun sockets.\n" ;
break ;
case EESECURITY :
error = "Security violation attempted.\n" ;
break ;
default :
error = "Unknown error code: " + new_socket + ".\n" ;
break ;
}
return 0 ;
}
sc_result = socket_connect( new_socket, ip_address + " " + port,
"read_callback", "write_callback" ) ;
if( sc_result != EESUCCESS ){
return 0 ;
}
attempting = 1 ;
socket = new_socket ;
age = time();
if(!Status) Status = ([]);
Status[new_socket] = mud;
return 1 ;
}
void read_callback( int fd, mixed message ){
if(!Confirmed) Confirmed = ([]);
if(!Confirmed[Status[fd]]) Confirmed[Status[fd]] = (["banner" : message, ]);
else Confirmed[Status[fd]]["banner"] += message;
}
void close_callback( int fd ){
socket_close( fd ) ;
attempting = 0 ;
connected = 0 ;
socket = 0 ;
}
void write_callback( int fd ){
attempting = 0 ;
connected = 1 ;
}
int parse_comm( string str ){
if(str=="dcon" || str=="quit"){
socket_close( socket ) ;
attempting = 0 ;
connected = 0 ;
socket = 0 ;
person = 0 ;
return 1 ;
}
else {
if( !connected ){
return 1 ;
}
if( attempting ){
return 1 ;
}
socket_write( socket, str + "\n" ) ;
return 1 ;
}
}