ds2.1.1/bin/
ds2.1.1/extra/wolfpaw/
ds2.1.1/lib/cmds/admins/
ds2.1.1/lib/cmds/common/
ds2.1.1/lib/cmds/creators/include/
ds2.1.1/lib/cmds/creators/include/SCCS/
ds2.1.1/lib/daemon/services/
ds2.1.1/lib/doc/
ds2.1.1/lib/doc/efun/all/
ds2.1.1/lib/doc/efun/arrays/
ds2.1.1/lib/doc/efun/buffers/
ds2.1.1/lib/doc/efun/compile/
ds2.1.1/lib/doc/efun/floats/
ds2.1.1/lib/doc/efun/functions/
ds2.1.1/lib/doc/efun/general/
ds2.1.1/lib/doc/efun/mixed/
ds2.1.1/lib/doc/efun/numbers/
ds2.1.1/lib/doc/efun/parsing/
ds2.1.1/lib/doc/faq/
ds2.1.1/lib/doc/hbook/
ds2.1.1/lib/doc/help/classes/
ds2.1.1/lib/doc/lpc/basic/
ds2.1.1/lib/doc/lpc/concepts/
ds2.1.1/lib/doc/lpc/constructs/
ds2.1.1/lib/doc/lpc/etc/
ds2.1.1/lib/doc/lpc/intermediate/
ds2.1.1/lib/doc/lpc/types/
ds2.1.1/lib/doc/misc/
ds2.1.1/lib/doc/old/
ds2.1.1/lib/domains/Ylsrim/
ds2.1.1/lib/domains/Ylsrim/adm/
ds2.1.1/lib/domains/Ylsrim/armor/
ds2.1.1/lib/domains/Ylsrim/broken/
ds2.1.1/lib/domains/Ylsrim/fish/
ds2.1.1/lib/domains/Ylsrim/meal/
ds2.1.1/lib/domains/Ylsrim/npc/
ds2.1.1/lib/domains/Ylsrim/obj/
ds2.1.1/lib/domains/Ylsrim/virtual/
ds2.1.1/lib/domains/Ylsrim/weapon/
ds2.1.1/lib/domains/campus/adm/
ds2.1.1/lib/domains/campus/etc/
ds2.1.1/lib/domains/campus/meals/
ds2.1.1/lib/domains/campus/npc/
ds2.1.1/lib/domains/campus/txt/ai/charles/
ds2.1.1/lib/domains/campus/txt/ai/charles/bak2/
ds2.1.1/lib/domains/campus/txt/ai/charles/bak2/bak1/
ds2.1.1/lib/domains/campus/txt/ai/charly/
ds2.1.1/lib/domains/campus/txt/ai/charly/bak/
ds2.1.1/lib/domains/campus/txt/jenny/
ds2.1.1/lib/domains/default/creator/
ds2.1.1/lib/domains/default/doors/
ds2.1.1/lib/domains/default/etc/
ds2.1.1/lib/domains/default/weap/
ds2.1.1/lib/domains/town/doors/
ds2.1.1/lib/domains/town/txt/
ds2.1.1/lib/domains/town/txt/shame/
ds2.1.1/lib/domains/town/virtual/
ds2.1.1/lib/lib/comp/
ds2.1.1/lib/lib/lvs/
ds2.1.1/lib/lib/user/
ds2.1.1/lib/lib/virtual/
ds2.1.1/lib/log/
ds2.1.1/lib/obj/book_source/
ds2.1.1/lib/obj/include/
ds2.1.1/lib/realms/template/
ds2.1.1/lib/realms/template/area/armor/
ds2.1.1/lib/realms/template/area/npc/
ds2.1.1/lib/realms/template/area/obj/
ds2.1.1/lib/realms/template/area/room/
ds2.1.1/lib/realms/template/area/weap/
ds2.1.1/lib/realms/template/bak/
ds2.1.1/lib/realms/template/cmds/
ds2.1.1/lib/save/kills/o/
ds2.1.1/lib/secure/cfg/
ds2.1.1/lib/secure/cfg/classes/
ds2.1.1/lib/secure/cfg/races/SCCS/
ds2.1.1/lib/secure/cmds/creators/include/
ds2.1.1/lib/secure/cmds/players/
ds2.1.1/lib/secure/cmds/players/include/
ds2.1.1/lib/secure/daemon/include/
ds2.1.1/lib/secure/lib/
ds2.1.1/lib/secure/lib/include/
ds2.1.1/lib/secure/lib/net/
ds2.1.1/lib/secure/lib/net/include/
ds2.1.1/lib/secure/lib/std/
ds2.1.1/lib/secure/modules/
ds2.1.1/lib/secure/npc/
ds2.1.1/lib/secure/obj/include/
ds2.1.1/lib/secure/room/
ds2.1.1/lib/secure/save/
ds2.1.1/lib/secure/save/boards/
ds2.1.1/lib/secure/verbs/creators/
ds2.1.1/lib/shadows/
ds2.1.1/lib/spells/
ds2.1.1/lib/verbs/admins/include/
ds2.1.1/lib/verbs/common/
ds2.1.1/lib/verbs/common/include/
ds2.1.1/lib/verbs/creators/
ds2.1.1/lib/verbs/creators/include/
ds2.1.1/lib/verbs/players/include/SCCS/
ds2.1.1/lib/verbs/rooms/
ds2.1.1/lib/verbs/rooms/include/
ds2.1.1/lib/www/errors/
ds2.1.1/lib/www/images/
ds2.1.1/v22.2b14/
ds2.1.1/v22.2b14/ChangeLog.old/
ds2.1.1/v22.2b14/Win32/
ds2.1.1/v22.2b14/compat/
ds2.1.1/v22.2b14/compat/simuls/
ds2.1.1/v22.2b14/include/
ds2.1.1/v22.2b14/testsuite/
ds2.1.1/v22.2b14/testsuite/clone/
ds2.1.1/v22.2b14/testsuite/command/
ds2.1.1/v22.2b14/testsuite/data/
ds2.1.1/v22.2b14/testsuite/etc/
ds2.1.1/v22.2b14/testsuite/include/
ds2.1.1/v22.2b14/testsuite/inherit/
ds2.1.1/v22.2b14/testsuite/inherit/master/
ds2.1.1/v22.2b14/testsuite/log/
ds2.1.1/v22.2b14/testsuite/single/
ds2.1.1/v22.2b14/testsuite/single/tests/compiler/
ds2.1.1/v22.2b14/testsuite/single/tests/efuns/
ds2.1.1/v22.2b14/testsuite/single/tests/operators/
ds2.1.1/v22.2b14/testsuite/u/
ds2.1.1/v22.2b14/tmp/
ds2.1.1/win32/
#include <lib.h>
#include <privs.h>
#include <save.h>
#include <rooms.h>
#include <config.h>

inherit LIB_DAEMON;

int SnoopClean();

string *snooped = ({});
object *snoopers = ({});
string *monitored  = ({}); 
mapping Watchers = ([]);
int count = 0;
int just_loaded = 1;
object *prevusers;

void eventLoadRogues();

static void create() {
    daemon::create();
    debug("SNOOP_D restarted.","red");
    if( file_size( SAVE_SNOOP __SAVE_EXTENSION__ ) > 0 )
	unguarded( (: restore_object, SAVE_SNOOP, 1 :) );
    SetNoClean(1);
    SnoopClean();
    set_heart_beat(1);
    if(GLOBAL_MONITOR == 0 && sizeof(monitored)){
	call_out( (: eventLoadRogues :), 1);
    }
    snoopers = filter(objects(), (: base_name($1) == "/secure/obj/snooper" :) );
    prevusers = users();
}

void RegisterSnooper(){
    object registrant = previous_object();
    if(base_name(registrant) == "/secure/obj/snooper" &&
      member_array(registrant,snoopers) == -1) snoopers += ({ registrant });
    unguarded( (: save_object, SAVE_SNOOP, 1 :) );
}

void UnregisterSnooper(){
    object registrant = previous_object();
    if(base_name(registrant) == "/secure/obj/snooper" &&
      member_array(registrant,snoopers) != -1) snoopers -= ({ registrant });
    unguarded( (: save_object, SAVE_SNOOP, 1 :) );
}

void eventLoadRogues(){
    if( !((int)master()->valid_apply(({ PRIV_SECURE }))) ) return;
    foreach(string rogue in monitored) this_object()->CheckBot(rogue);
    snoopers = filter(objects(), (: base_name($1) == "/secure/obj/snooper" :) );
}

int CheckBot(string str){
    object cloan, foo;
    int allset, already_watched = 0;
    string *immune;
    string name;

    if(!str) str = "foo";
    str = lower_case(str);
    foo = find_player(str);
    if(sizeof(snoopers)){
	foreach(object snoopbox in snoopers){
	    if(clonep(snoopbox) ) {
	    }
	    else snoopers -= ({snoopbox});
	    if(snoopbox && snoopbox->GetSnooped() && snoopbox->GetSnooped() == str) {
		already_watched = 1;
	    }
	    if(snoopbox->GetSnooped() && (!find_player(snoopbox->GetSnooped()) ||!(snoopbox->GetSnooped()))) {
	    }
	}
    }
    if(!already_watched && foo && (GLOBAL_MONITOR > 0 || member_array(str, monitored) != -1 || member_array(str, snooped) != -1 )){
	if(archp(find_player(str)) && GLOBAL_MONITOR == 2) return 0;
	cloan=new("/secure/obj/snooper");
	cloan->eventStartSnoop(str);
    }
    unguarded( (: save_object, SAVE_SNOOP, 1 :) );
    return 1;
}

void CheckSnooped(){
    object *lusers = users();
    just_loaded = 0;
    foreach(object user in lusers){
	CheckBot(user->GetKeyName());
    }
    prevusers = lusers;
}

int SnoopClean(){
    snoopers = filter(objects(), (: base_name($1) == "/secure/obj/snooper" :) );
    if(sizeof(snoopers)){
	foreach(object snoopbox in snoopers){
	    if(snoopbox && !clonep(snoopbox) ) {
		snoopers -= ({snoopbox});
	    }
	    else {
		object subject;
		string dude = snoopbox->GetSnooped();
		if(dude) subject = find_player(dude);
		if(!dude || !subject || !query_snooping(snoopbox) || 
		  (member_array(dude,snooped) == -1 && member_array(dude,monitored) == -1 && GLOBAL_MONITOR < 1 )){
		    snoopbox->eventDestruct();
		    snoopers -= ({snoopbox});
		}
	    }
	}
    }
    return 1;
}

int eventDestruct(){
    if( !((int)master()->valid_apply(({ "SECURE" }))) )
	error("Illegal attempt to destruct snoop: "+get_stack()+" "+identify(previous_object(-1)));
    return ::eventDestruct();
}


void heart_beat(){
    count++;

    if( !(count % 5) ) CheckSnooped();

    if( !(count % 10)) {
	foreach(object snoopbox in snoopers){
	    if(!snoopbox) snoopers -= ({ snoopbox });
	}
	SnoopClean();
    }
    if(count > 100) count = 0;
}

void reset(){
    if(query_heart_beat(this_object()) < 1) set_heart_beat(60);
    CheckSnooped();
}

int GetSnoop(string target, string msg){
    if(target != "cratylus") {
    }
    if(base_name(previous_object()) != "/secure/obj/snooper") return 0;
    else if(sizeof(Watchers[target])) {
	foreach(string watcher in Watchers[target]){
	    tell_player(watcher, target+"% "+msg);
	}
    }
    else Watchers[target] = ({});
    return 1;
}

int AddWatcher(string watcher, string target){
    if(!valid_snoop(find_player(watcher), find_player(target))) {
	return 0;
    }
    if(Watchers[target] && member_array(watcher,Watchers[target]) != -1){
	return 0;
    }
    if(!Watchers[target] || !sizeof(Watchers[target])) {
	Watchers[target] = ({ watcher });
    }
    else {
	Watchers[target] += ({ watcher });
    }
    if(member_array(target,snooped) == -1) snooped += ({target});
    CheckBot(target);
    unguarded( (: save_object, SAVE_SNOOP, 1 :) );
    return 1;
}

int RemoveWatcher(string watcher, string target){
    if(!valid_snoop(find_player(watcher), find_player(target))) return 0;
    if(this_player() && interactive(this_player())){
	if(this_player()->GetKeyName() != watcher && !archp(this_player())) return 0;
    }
    else return 0;

    if(!Watchers[target] || !sizeof(Watchers[target])) return 0;
    else if(member_array(watcher, Watchers[target]) != -1) 
	Watchers[target] -= ({ watcher });
    if((!Watchers[target] || !sizeof(Watchers[target])) &&
      member_array(target, monitored) == -1) {
	foreach(object snoopbox in snoopers){
	    if(snoopbox->GetSnooped() == target) snoopbox->eventDestruct(); 
	}
    }
    if(!Watchers[target] || !sizeof(Watchers[target])) {
	snooped -= ({target});
	if(Watchers[target]) map_delete(Watchers, target);
    }
    CheckBot("adsfgrertgrsgnfxmy");
    unguarded( (: save_object, SAVE_SNOOP, 1 :) );
    return 1;
}

int AddMonitor(string requestor, string target){
    if(member_array(target, monitored) == -1) monitored += ({ target });
    unguarded( (: save_object, SAVE_SNOOP, 1 :) );
    CheckBot(target);
    return 1;
}

int RemoveMonitor(object requestor, string target){
    if(!archp(requestor)) return 0;
    monitored -= ({ target });
    unguarded( (: save_object, SAVE_SNOOP, 1 :) );
    if(Watchers[target] && sizeof(Watchers[target])) return 1;
    foreach(object snoopbox in snoopers){
	if(snoopbox->GetSnooped() == target) snoopbox->eventDestruct(); 
    }
    if(Watchers[target] && !sizeof(Watchers[target])) map_delete(Watchers, target);
    CheckBot("asreg54eqwhtrbsf");
    unguarded( (: save_object, SAVE_SNOOP, 1 :) );
    return 1;
}

int ReportLinkDeath(string str){
    if(!find_player(str)){
	foreach(object snoopbox in snoopers){
	    if(snoopbox->GetSnooped() == str) snoopbox->eventDestruct(); 
	}
	map_delete(Watchers, str);
	unguarded( (: save_object, SAVE_SNOOP, 1 :) );
	return 1;
    }
    return 0;
}

int ReportReconnect(string str){
    if(base_name(previous_object()) == LIB_CONNECT){
	foreach(object snoopbox in snoopers){
	    if(snoopbox->GetSnooped() == str) snoopbox->eventDestruct(); 
	}
	map_delete(Watchers, str);
	CheckBot(str);
	unguarded( (: save_object, SAVE_SNOOP, 1 :) );
	return 1;
    }
    return 0;
}

int Report(){
    if( !((int)master()->valid_apply(({ PRIV_SECURE }))) ){
	return 0;
    }
    write("Watchers: "+identify(Watchers)+"\n");
    write("snoopers: "+identify(snoopers)+"\n");
    write("snooped: "+identify(snooped)+"\n");
    write("monitored: "+identify(monitored)+"\n");
    return 1;
}