/**
*
* Post Office Delivery Handler
* @author Terano
* @started 26 December, 1998
*
*/
#define BASE_PATH "/save/parcels/"
#define SAVE_PATH BASE_PATH + location + "/" + name[0..0]
#define SAVE_FILE BASE_PATH + location + "/" + name[0..0] + "/" + name + ".o"
#define POST_LOG "PARCEL_LOG"
inherit "/global/auto_load";
// This is undefined since uncompress() is broken. Once uncompress() is
// repaired it should be possible to turn compression on but please test
// it first. -- Ceres
#undef USE_COMPRESSION
#include <player_handler.h>
/**
* Parcels is a mapping with player names as keys, and arrays of class parcel
* as values
*/
class parcel {
string from;
string *autoloadinfo;
int exp_time;
}
mapping parcels;
private nosave string _current_name, _current_location;
nosave class parcel *_parcels;
int test_expire( class parcel temp );
/**
* @ignore
*/
void create() {
string dir;
seteuid( master()->creator_file( base_name( this_object() ) ) );
parcels = ([ ]);
if(parcels) {
parcels = copy(parcels);
parcels = ([ ]);
}
_parcels = ({ });
/* foreach(dir in get_dir("/save/parcels/*")) {
if(dir != "." && dir != ".." && file_size("/save/parcels/" + dir) == -2) {
tell_creator("ceres", "Starting %s", dir);
call_out("do_migrate", random(10), 'a', dir);
}
}
*/
}
/**
* @ignore
*/
private void save_file(string name, string location) {
string str;
// Save the old parcels variable.
map_delete(parcels, name);
if(sizeof(keys(parcels)))
unguarded( (: save_object, SAVE_PATH, 2 :));
if(file_size(SAVE_PATH) == -1)
unguarded( (: mkdir, SAVE_PATH :) );
// If they have a parcel then save it to a file. If not delete any existing
// parcel file.
if(_parcels != ({ })) {
str = save_variable(_parcels);
#ifdef USE_COMPRESSION
if(!ungarded( (: write_buffer, SAVE_FILE + ".gz", 0, compress(str) :) ))
#else
if(!unguarded((: write_file, SAVE_FILE, str, 1 :) ))
#endif
log_file(POST_LOG, "%s: error writing to %s\n",
ctime(time()), SAVE_FILE);
} else {
if(file_size(SAVE_FILE) > 0)
unguarded( (: rm, SAVE_FILE :));
if(file_size(SAVE_FILE+".gz") > 0)
unguarded( (: rm, SAVE_FILE + ".gz" :));
}
}
/**
* @ignore
*/
private void load_file( string name, string location ) {
// no need to load if it's the currently loaded one.
if(_current_name == name && _current_location == location)
return;
#ifdef USE_COMPRESSION
if(file_size(SAVE_FILE + ".gz") > 0) {
_parcels = restore_variable(uncompress(read_file(SAVE_FILE)));
} else
#endif
if(file_size(SAVE_FILE) > 0) {
debug_printf("%s", SAVE_FILE);
_parcels = restore_variable(unguarded( (: read_file, SAVE_FILE :) ));
} else if (file_size(SAVE_PATH+ ".o.gz") > 0) {
unguarded( (: restore_object, SAVE_PATH+".o.gz" :));
_parcels = parcels[name];
} else if(file_size(SAVE_PATH+".o") > 0) {
unguarded( (: restore_object, SAVE_PATH :) );
_parcels = parcels[name];
} else {
parcels = ([ ]);
_parcels = ({ });
}
_current_name = name;
_current_location = location;
}
/**
* This function deposits some items for a player
* @param to The name of the player items are going to
* @param from The name of the player sending the items
* @param location The place the items are being sent from
* @param obs An array of the objects being sent
* @return 1 if it worked, or 0 if it screwed up :)
*/
public int deposit(string to, string from, string location, object *obs) {
class parcel temp;
object boxy;
string obsstuff, tmp;
obsstuff = "/global/events"->convert_message(query_multiple_short (obs));
if(!PLAYER_HANDLER->test_user(to))
return 0;
#ifndef __DISTRIBUTION_LIB__
// Do multiplayer checks.
if("/secure/alist"->query_alt(from, to) == 100) {
tmp = capitalize(from) + " sent a parcel containing " +
obsstuff + " to his/her alt " + capitalize(to) + ".";
user_event("inform", tmp, "multiplayer");
log_file("MULTIPLAYERS", ctime(time()) + ": " +
this_player()->convert_message(tmp) + "\n");
} else if("/secure/alist"->query_alt(from, to) > 40) {
tmp = capitalize(from) + " sent a parcel containing " +
obsstuff + " to his/her POSSIBLE alt "+ capitalize(to) + ".";
user_event("inform", tmp, "multiplayer");
log_file("MULTIPLAYERS", ctime(time()) + ": " +
this_player()->convert_message(tmp) + "\n");
}
#endif
load_file(to, location ); // Load up the right save file
if(undefinedp(_parcels) || !arrayp(_parcels))
_parcels = ({ });
boxy = clone_object("/obj/baggage");
boxy->set_name("boxy");
boxy->set_max_weight(100000);
obs->move( boxy );
temp = new( class parcel,
from : from,
exp_time: time() + ( 14 * 24 * 60 * 60));
temp->autoloadinfo = create_auto_load( ({ boxy }), 0 );
_parcels += ({ temp });
save_file(to, location);
boxy->dest_me();
log_file (POST_LOG, "%s: %s deposited %s at %s for %s.\n", ctime(time()),
from, obsstuff, location, to);
}
/**
* This function collects any items available
* @param name Name of the player collecting
* @param location Location collecting from
* @param target An object to move the items into, a room or container
* @param copy An int, if its 1 it doesnt delete the objects from the parcels
* array
* @return 0 if no items or failure, 1 if successful
*/
public int collect(string name, string location, object target, int copy) {
class parcel temp;
object *box_array = ({ });
object *obs = ({ });
string tmp;
load_file(name, location ); // Load up the right save file
if(!_parcels || _parcels == ({ }))
return 0;
foreach(temp in _parcels) {
box_array += load_auto_load_to_array(temp->autoloadinfo, this_player());
#ifndef __DISTRIBUTION_LIB__
obs = all_inventory(box_array[<1]);
// Do multiplayer checks.
if("/secure/alist"->query_alt(name, temp->from) == 100) {
tmp = capitalize(name) + " received a parcel containing " +
"/global/events"->convert_message(query_multiple_short(obs)) +
" from his/her alt " + capitalize(temp->from) + ".";
user_event("inform", tmp, "multiplayer");
log_file("MULTIPLAYERS", ctime(time()) + ": " +
this_player()->convert_message(tmp) + "\n");
} else if("/secure/alist"->query_alt(name, temp->from) > 40) {
tmp = capitalize(name) + " received a parcel containing " +
"/global/events"->convert_message(query_multiple_short(obs)) +
" from his/her POSSIBLE alt "+ capitalize(temp->from) + ".";
user_event("inform", tmp, "multiplayer");
log_file("MULTIPLAYERS", ctime(time()) + ": " +
this_player()->convert_message(tmp) + "\n");
}
#endif
}
foreach( object box in box_array ) {
obs += all_inventory (box);
all_inventory( box )->move( target );
box->dest_me();
}
if ( !copy )
_parcels = ({ });
log_file (POST_LOG, "%s: %s collected %s at %s.\n", ctime(time()),
name, "/global/events"->convert_message(query_multiple_short(obs)),
location);
save_file(name, location);
return 1;
}
/**
* Queries if any parcels are at a location for a person
* @param name of the person
* @param location of the post office
*/
class parcel *queryparcels_for(string name, string location) {
load_file(name, location);
return _parcels;
}
/**
* Migrate packages
* @param letter to expire
* @param location to expire
*/
void do_migrate(int letter, string location) {
string name;
class parcel temp2;
tell_creator("ceres", "Processing %c in %s\n", letter, location);
load_file(sprintf("%c", letter), location);
foreach(name, temp2 in parcels) {
_parcels = filter(temp2, (: test_expire :));
save_file(name, location);
}
if(!sizeof(keys(parcels))) {
name = BASE_PATH + location + "/" + sprintf("%c", letter) + ".o.gz";
unguarded((: rm, name :));
}
if(letter < 'z') {
letter++;
call_out("do_migrate", 15 + random(30), letter, location);
}
}
/**
* @ignore
*/
int test_expire(class parcel temp ) {
if ( temp->exp_time > time() )
return 1;
return 0;
}
/**
* Called when a player deletes
* Deletes all their parcels
* @param string name
* @param int Total Flag
*/
void player_refreshed(mixed name, int total ) {
string location;
string *dirs = map( filter( get_dir( BASE_PATH, -1 ),
(: $1[1] == -2 :) ), (: $1[0] :) );
if (objectp(name))
name = name->query_name();
foreach(location in dirs) {
load_file(name, location);
map_delete(parcels, name);
save_file(name, location);
}
}