/*
* $Locker: $
* $Id: player_handler.c,v 1.61 2003/05/27 22:53:39 ceres Exp $
*/
/**
* A hander to allow the testing of values on players when they aren't logged
* in. These methods used to exist in the login object but now they're here.
* <p>
* @author Ceres
*/
inherit "/global/family";
inherit "/std/living/nationality";
#include <alias.h>
#include <player.h>
#include <login_handler.h>
#include <access.h>
#define MAX_CACHE_SIZE MAX_PLAYERS
#define CACHE_TIMEOUT 900
#define INACTIVE_LIMIT 1209600
#define ILLEGAL ({ "black", "blood", "cyber", "dark", "penis", "cock", "pussy",\
"fuck", "shit", "death", "deth", "dragon", "fish", "hell", "mage", "pink", "lord",\
"shadow", "evil", "killer", "slayer" })
/* Basic player variables needed by the login object. */
private int gender;
private int creator;
private int time_on;
private int last_log_on;
private string last_on_from;
private int activity_counter;
private int start_time;
private string password;
private string deity;
private string guild_ob;
private string cap_name;
private mapping aliases;
private mapping map_prop;
private mapping new_skills;
private mapping player_info;
private mixed *guild_data;
private int _flags;
private string home_dir;
string player_ob;
class player_record {
int cached;
int touched;
int deleting;
int appealing;
int gender;
int creator;
int active;
int level;
string cap_name;
mapping map_prop;
mapping player_info;
string deity;
string guild;
mixed *guild_data;
int age;
int last;
int flags;
string last_on_from;
int start_time;
string family_name;
string player_title;
string password;
mixed *project;
mixed *plan;
mixed *reference;
mixed *signature;
string home_dir;
string nationality;
string nationality_region;
mixed nationality_data;
}
nosave mapping player_cache;
nosave string prev, prev_find, prev_name;
nosave int prev_count, prev_finds, delay;
int requests,
cache_hits;
void create() {
seteuid("Root");
player_ob = "/global/player";
player_cache = ([ ]);
} /* create() */
object my_find_player(string player) {
//Just guessing at what this should be initialised to.
string *funs, stack = "";
object *obs;
int i;
if(prev_name == player)
return find_player(player);
prev_name = player;
if (base_name(previous_object()) == prev_find && delay > time() - 60 &&
prev_name == player) {
prev_finds++;
} else {
prev_finds = 1;
delay = time();
prev_find = base_name(previous_object());
}
if(!(prev_finds % 25)) {
obs = call_stack(1);
funs = call_stack(2);
for(i=0; i<sizeof(obs); i++) {
if(clonep(obs[i]))
stack += base_name(obs[i]) + "#" + obs[i]->query_name();
else
stack += base_name(obs[i]);
stack += "->" + funs[i] + "()\n";
}
log_file("GARBAGE", "%s %s checked %d players in %d seconds.\n%s",
ctime(time())[4..18], prev_find, prev_finds, time() - delay,
stack);
}
return find_player(player);
}
void clean_cache() {
string name;
foreach(name in keys(player_cache)) {
if (player_cache[name]->cached < time() - CACHE_TIMEOUT) {
map_delete(player_cache, name);
}
}
}
void remove_cache_entry(string name) {
map_delete(player_cache, name);
}
private int validate_name(string name) {
if (!stringp(name) || !name || name == "logon" || name[0] == '.' ||
(sscanf(name, "%*s %*s") == 2) || strlen(name) < 2) {
return 0;
}
if (sizeof(explode(name, "..")) > 1) {
return 0;
}
return 1;
}
/**
* This method returns the path to the player file.
* This is the player files actual normal location, it was written to
* allow moving the player files around easier.
* @param name the name of the player whose file to find
* @see test_user()
* @see query_delete_player_file_name()
*/
string query_player_file_name(string name) {
#ifdef USE_RAMDISK
if(PLAYER_RAM_DIR) {
if(file_size(PLAYER_RAM_DIR + name[0..0] + "/" + name + ".o.gz") == -1) {
if(file_size(PLAYER_SAVE_DIR + name[0..0] + "/" + name + ".o.gz") > -1) {
unguarded((: cp,
PLAYER_SAVE_DIR + name[0..0] + "/" + name + ".o.gz",
PLAYER_RAM_DIR + name[0..0] + "/" + name + ".o.gz" :));
} else if((file_size(PLAYER_SAVE_DIR+name[0..0]+"/"+name+".o") >-1)) {
unguarded((: cp,
PLAYER_SAVE_DIR + name[0..0] + "/" + name + ".o",
PLAYER_RAM_DIR + name[0..0] + "/" + name + ".o" :));
unguarded((: compress_file,
PLAYER_RAM_DIR + name[0..0] + "/" + name + ".o" :));
}
}
return PLAYER_RAM_DIR + name[0..0] + "/" + name;
}
#endif
return PLAYER_SAVE_DIR + name[0..0] + "/" + name;
}
string query_player_ram_file_name(string name) {
return PLAYER_RAM_DIR + name[0..0] + "/" + name;
}
string query_player_disk_file_name(string name) {
return PLAYER_SAVE_DIR + name[0..0] + "/" + name;
}
/**
* This method returns the path to the deleted player file.
* This is the deleted player files actual normal location, it was written to
* allow moving the player files around easier.
* @param name the name of the player whose file to find
* @see test_user()
* @see query_delete_player_file_name()
*/
string query_delete_player_file_name(string name) {
return PLAYER_SAVE_DIR + DELETE_DIR + "/" + name;
}
/**
* This method returns the path to the pending appeal player file.
* This is the appeal player files actual normal location, it was written to
* allow moving the player files around easier.
* @param name the name of the player whose file to find
* @see test_user()
* @see query_delete_player_file_name()
*/
string query_appeal_player_file_name(string name) {
return PLAYER_SAVE_DIR + APPEAL_DIR + "/" + name;
}
/**
* This method will load in the player file. It will return 0 if the player
* file either does not exist or the input string is incorrect.
* @param name the name to try and read in
* @return 1 if the player file exists, 0 if not
*/
int load_player(string name) {
class player_record tmp;
mixed *file;
int diff, deleting, appealing;
string tstr, fname;
object loaded_guild_ob;
if (!validate_name(name)) {
return 0;
}
requests++;
// Check if we have a cached copy of this file. If so, only use the cached
// copy if the cached time * 10 is less than the last touched time
// ie. files which were modified recently should be cached for less time.
if (player_cache[name]) {
if (10 * (time() - player_cache[name]->cached) <
(time() - player_cache[name]->touched)) {
cache_hits++;
return 1;
}
}
// check if the file exists and get info about it.
if(file = unguarded((: get_dir, query_player_ram_file_name(name) + ".o.gz",
-1 :)))
fname = query_player_ram_file_name(name);
if (!file || !sizeof(file) || file[0][1] < 0) {
file = unguarded((: get_dir, query_player_disk_file_name(name) +
".o.gz", -1 :));
fname = query_player_disk_file_name(name);
}
if (!file || !sizeof(file) || file[0][1] < 0) {
file = unguarded((: get_dir, query_player_disk_file_name(name) +
".o", -1 :));
fname = query_player_disk_file_name(name);
}
if (!file || !sizeof(file) || file[0][1] < 0) {
file = unguarded((: get_dir, query_delete_player_file_name(name) + ".o.gz",
-1 :));
fname = query_delete_player_file_name(name);
}
if (!file || !sizeof(file) || file[0][1] < 0) {
file = unguarded((: get_dir, query_delete_player_file_name(name) + ".o",
-1 :));
fname = query_delete_player_file_name(name);
}
if (!file || !sizeof(file) || file[0][1] < 0) {
file = unguarded((: get_dir, query_appeal_player_file_name(name) + ".o.gz",
-1 :));
fname = query_appeal_player_file_name(name);
}
if (!file || !sizeof(file) || file[0][1] < 0) {
file = unguarded((: get_dir, query_appeal_player_file_name(name) + ".o",
-1 :));
fname = query_appeal_player_file_name(name);
}
if(!file || !sizeof(file) || file[0][1] < 0)
return 0;
// If we've got a cached copy of this file see if the original's touched
// time is the same as that for our copy, if so use the cached copy
// and update the 'cached' time.
if(player_cache[name] && player_cache[name]->touched == file[0][2]) {
player_cache[name]->cached = time();
cache_hits++;
return 1;
}
// restore the file and setup the data.
gender = 0;
creator = 0;
time_on = 0;
last_log_on = 0;
last_on_from = 0;
activity_counter = 0;
start_time = 0;
password = 0;
deity = 0;
guild_ob = 0;
cap_name = 0;
player_info = ([ ]);
aliases = ([ ]);
new_skills = ([ ]);
map_prop = ([ ]);
guild_data = 0;
if (base_name(previous_object()) == prev && delay > time() - 60) {
prev_count++;
} else {
prev_count = 1;
delay = time();
prev = base_name(previous_object());
}
if (!(prev_count % 25)) {
tstr = prev;
if (tstr == "/secure/login" && sizeof(previous_object(-1)) > 1) {
tstr = base_name(previous_object(-1)[1]);
}
log_file("GARBAGE", "%s %s loaded %d player files in %d seconds.\n",
ctime(time())[4..18], tstr, prev_count, time() - delay);
}
#ifdef DEBUG
string ob;
if (base_name(previous_object()) != "/secure/login") {
ob = base_name(previous_object());
} else {
ob = base_name(previous_object(-1)[1]);
}
log_file("CDEBUG", "%s: %O:%O\n", ob, call_stack(1), call_stack(2));
#endif
if(!unguarded((: restore_object, fname, 1 :)))
return 0;
// Find out how long their deletion/appeal has to go before they're
// removed.
if(fname == query_appeal_player_file_name(name)) {
appealing = file[0][2];
} else if(fname == query_delete_player_file_name(name)) {
deleting = file[0][2];
}
tmp = new (class player_record,
cached: time(),
touched: file[0][2],
deleting: deleting,
appealing: appealing,
gender: gender,
creator: creator,
active: 0,
level: 0,
cap_name: cap_name,
player_info: player_info,
map_prop: map_prop,
deity: deity,
guild: guild_ob,
guild_data: guild_data,
flags: _flags,
age: time_on,
last: last_log_on,
last_on_from: last_on_from,
start_time: start_time,
family_name: query_family_name(),
player_title: query_player_title(),
nationality: query_nationality(),
nationality_region: query_nationality_region(),
nationality_data: query_nationality_data(),
password: password);
if(aliases) {
if (aliases[".project"])
tmp->project = aliases[".project"][0..1023];
if (aliases[".plan"])
tmp->plan = aliases[".plan"][0..1023];
if (aliases[".reference"])
tmp->reference = aliases[".reference"][0..1023];
if (aliases[".signature"])
tmp->signature = aliases[".signature"][0..240];
}
// are they active.
diff = (time() - last_log_on) / (3600 * 24 * 7);
diff *= 10;
tmp->active = (activity_counter - diff) > -50 ? 1 : 0;
// calculate their level
if (guild_ob) {
loaded_guild_ob = load_object( guild_ob );
if ( loaded_guild_ob ) {
tmp->level = (int) guild_ob->query_level(this_object());
}
else {
tmp->level = 0;
}
}
player_cache[name] = tmp;
if ((sizeof(player_cache) > MAX_CACHE_SIZE) &&
(find_call_out("clean_cache") == -1))
call_out("clean_cache", 60);
return 1;
}
/**
* This method converts an alias into a string. This is used by the
* projects and plans and so on.
* @param al the alias to turn into a string
* @return the converted string
*/
string make_string(mixed *al, int max) {
string str;
int i;
int lines;
str = ALIAS_CMD->alias_string(al);
sscanf(str, "%s $*$", str);
str = replace(str, sprintf("%c", 7), "^G");
str = replace(str, ({ "@@", "@ @ ", "\\;", "$escaped$", ";", "\n",
"$escaped$", ";" }));
for (i = lines = 0; i < sizeof(str) && i < max*80 && lines < max; i++) {
if (str[i] == '\n' || str[i] == ';') {
lines++;
}
}
return str[0..i - 1];
}
/**
* This method figures out if the user exists even if they are not on.
* @param str the name of the user
* @return 1 if they exist, 0 if they do not
*/
int test_user(string str) {
if (player_cache[str])
return 1;
if (!validate_name(str))
return 0;
return file_size(query_player_disk_file_name(str) + ".o.gz") > 0 ||
file_size(query_player_disk_file_name(str) + ".o") > 0 ||
file_size(PLAYER_RAM_DIR + str[0..0] + "/" + str + ".o.gz") > 0 ||
file_size(PLAYER_RAM_DIR + str[0..0] + "/" + str + ".o") > 0 ||
file_size(query_delete_player_file_name(str) + ".o.gz") > 0 ||
file_size(query_delete_player_file_name(str) + ".o") > 0 ||
file_size(query_appeal_player_file_name(str) + ".o.gz") > 0 ||
file_size(query_appeal_player_file_name(str) + ".o") > 0;
}
/**
* This method figures out if the user is marked for deletion.
* @param str the name of the user
* @return 1 if they are marked for deletion, 0 if they do not
*/
int test_deleting(string str) {
if (player_cache[str])
return player_cache[str]->deleting;
if (!validate_name(str))
return 0;
if (file_size(query_delete_player_file_name(str) + ".o") > 0)
return stat(query_delete_player_file_name(str) + ".o")[1];
if(file_size(query_delete_player_file_name(str) + ".o.gz") > 0)
return stat(query_delete_player_file_name(str) + ".o.gz")[1];
return 0;
}
/**
* This method figures out if the user is marked for deletion pending appeal.
* @param str the name of the user
* @return 1 if they are marked for deletion, 0 if they do not
*/
int test_appealing(string str) {
if (player_cache[str])
return player_cache[str]->appealing;
if (!validate_name(str))
return 0;
if (file_size(query_appeal_player_file_name(str) + ".o") > 0)
return stat(query_appeal_player_file_name(str) + ".o")[1];
if(file_size(query_appeal_player_file_name(str) + ".o.gz") > 0)
return stat(query_appeal_player_file_name(str) + ".o.gz")[1];
return 0;
}
/**
* This method determines the gender of the player even if they are
* not currently on
* @param str the name of the user
* @return the players gender
* @see /std/living/gender.c
*/
int test_gender(string str) {
if (find_player(str)) {
map_delete(player_cache, str);
return find_player(str)->query_gender();
}
if (!load_player(str))
return 0;
return player_cache[str]->gender;
}
/**
* This method determines if a player is still active.
* If you need to perform this on a lot of players please use the noload
* parameter. When noload is set to 1 test_active will not attempt to load
* the player file if it isn't currently loaded and will instead just do a
* simple calculation of the players last login time. This is less accurate
* but avoids lagging the mud.
*
* @param player the name of the user
* @param noload optional parameter to prevent test_active() loading the
* player
file.
* @return active or inactive (1 or 0)
*/
varargs int test_active(string player, int noload) {
mixed *file;
if (find_player(player)) {
map_delete(player_cache, player);
return 1;
}
if (noload) {
if (player_cache[player])
return player_cache[player]->active;
file =
unguarded((: stat,
query_player_disk_file_name(player) + ".o" :));
if (!file || !sizeof(file)) {
file =
unguarded((: stat,
query_player_disk_file_name(player) + ".o.gz" :));
}
return (sizeof(file) && file[1] > time() - INACTIVE_LIMIT);
}
if (!load_player(player))
return 0;
return player_cache[player]->active;
}
/**
* This method returns a players cap_name.
* @param str the name of the user
* @return the players cap name
*/
string query_cap_name(string str) {
if (find_player(str)) {
map_delete(player_cache, str);
return find_player(str)->query_cap_name();
}
if (!load_player(str))
return 0;
return player_cache[str]->cap_name;
}
/**
* This method determines the level of the player even if they are
* not currently on
* @param str the name of the user
* @return the players level
* @see /std/living/gender.c
*/
int test_level(string str) {
if (find_player(str)) {
map_delete(player_cache, str);
return find_player(str)->query_level();
}
if (!load_player(str))
return 0;
return player_cache[str]->level;
}
/**
* This method is called by query_level() in the base guild
* inheritable to determine the specialisation of the current
* player.
*/
mixed query_guild_data() {
return guild_data;
} /* query_guild_data() */
/* Added by Presto 12/20/97. Needed for test_level.
== not sure about this -- Ceres == */
int query_skill(string skill) {
if (mapp(new_skills)) {
return new_skills[skill];
}
return 0;
}
/**
* This method checks to see if the name is banished of not.
* @param name the check for banishment.
* @return 1 if it banished, 0 if not
*/
int test_banished(string name) {
return file_size(BANISH_DIR + name[0..0] + "/" + name + ".o") != -1;
}
/**
* Validate a name by checking if it, or bits of it are banished.
* @param name The name to be validated.
* @param full Should we do full checks or just the basics.
* @return 1 if it's ok, 0 if not.
*/
varargs int test_valid(string name) {
string *bits, bit, tname;
name = lower_case(name);
tname = replace(name, ({ "'", "", "_", " " }));
bits = explode(tname, " ");
name = replace(name, ({ "'", " ", "_", " " }));
bits += explode(name, " ");
foreach(bit in bits) {
if (bit == "the" || bit == "von" || bit == "sto" || bit == "here" ||
bit == "there" || bit == "time") {
continue;
}
if (test_banished(bit))
return 0;
}
name = replace(name, ({ " ", "" }));
if (test_banished(name))
return 0;
foreach(bit in ILLEGAL) {
if (strsrch(name, bit) != -1)
return 0;
}
return 1;
}
/**
* This method determines the real name of the player even if they are
* not currently on
* @param str the name of the user
* @return the players real name
* @see /std/living/gender.c
*/
string test_real_name(string str) {
if (find_player(str)) {
map_delete(player_cache, str);
return find_player(str)->query_real_name();
}
if (!load_player(str))
return "";
return player_cache[str]->player_info["real_name"];
}
/**
* This method determines the email of the player even if they are
* not currently on.
* @param str the name of the user
* @return the players email
*/
string test_email(string str) {
if(file_name(previous_object())[0..13] != "/secure/finger" &&
file_name(previous_object())[0..12] != "/secure/login" &&
file_name(previous_object())[0..13] != "/secure/nlogin")
return "";
if (find_player(str)) {
map_delete(player_cache, str);
return find_player(str)->query_email();
}
if (!load_player(str))
return "";
return player_cache[str]->player_info["email"];
}
/**
* This method determines the birthday of the player even if they are
* not currently on
* @param str the name of the user
* @return the players birthday (if set)
*/
string test_birthday(string str) {
if (find_player(str)) {
map_delete(player_cache, str);
return find_player(str)->query_birthday();
}
if (!load_player(str))
return "";
return player_cache[str]->player_info["birthday"];
}
/**
* This method determines the players location finger information even if they
* are not currently on
* @param str the name of the user
* @return the players location
*/
string test_location(string str) {
if (find_player(str)) {
map_delete(player_cache, str);
return find_player(str)->query_where();
}
if (!load_player(str))
return "";
return player_cache[str]->player_info["location"];
}
/**
* This method determines the players homepage information even if they
* are not currently on
* @param str the name of the user
* @return the players location
*/
string test_homepage(string str) {
if (find_player(str)) {
map_delete(player_cache, str);
return find_player(str)->query_homepage();
}
if (!load_player(str))
return "";
return player_cache[str]->player_info["homepage"];
}
/**
* This method determines the description of the player even if they are
* not currently on
* @param str the name of the user
* @return the players description
*/
string test_desc(string str) {
if (find_player(str)) {
map_delete(player_cache, str);
return find_player(str)->query_desc();
}
if (!load_player(str))
return "";
return player_cache[str]->player_info["desc"];
}
/**
* This method returns the current value of the player flag on the
* player, even if they are not currently on.
* @param word the player name
* @return 1 if they are a player killer, 0 if not
*/
mixed test_player_killer(string word, string str) {
if (find_player(word)) {
map_delete(player_cache, word);
return find_player(word)->query_player_killer();
}
if (!load_player(word)) {
return 0;
}
return player_cache[word]->flags & PLAYER_KILLER_FLAG;
}
/**
* This method returns the current value of the property on the
* player, even if they are not currently on.
* @param word the player name
* @param str the property to query
* @return the value of the property
*/
mixed test_property(string word, string str) {
if (find_player(word)) {
map_delete(player_cache, word);
return find_player(word)->query_property(str);
}
if (!load_player(word))
return 0;
return player_cache[word]->map_prop[str];
}
/**
* This method updates the cached properties, it's called by
* /secure/login.
*/
void special_add_property(string pname, string prop, mixed val) {
if(player_cache[pname])
player_cache[pname]->map_prop[prop] = val;
}
/**
* This method determines the deity of the player even if they are
* not currently on.
* @param str the name of the user
* @return the players deity
*/
string test_deity(string word) {
if (find_player(word)) {
map_delete(player_cache, word);
return find_player(word)->query_deity();
}
if (!load_player(word))
return 0;
return player_cache[word]->deity;
}
/**
* This method determines the guild of the player even if they are
* not currently on.
* @param str the name of the user
* @return the players guild
*/
string test_guild(string word) {
if (find_player(word)) {
map_delete(player_cache, word);
return find_player(word)->query_guild_ob();
}
if (!load_player(word))
return "";
return player_cache[word]->guild;
}
/**
* This method determines the guild data of the player even if they are
* not currently on.
* @param str the name of the user
* @return the players guild data
*/
mixed *test_guild_data(string word) {
if (find_player(word)) {
map_delete(player_cache, word);
return find_player(word)->query_guild_data();
}
if (!load_player(word))
return ({ });
return player_cache[word]->guild_data;
}
/**
* This method determines the age of the player even if they are
* not currently on.
* @param str the name of the user
* @return the players age
*/
int test_age(string word) {
if (find_player(word)) {
map_delete(player_cache, word);
return find_player(word)->query_time_on();
}
if (!load_player(word))
return 0;
return player_cache[word]->age;
}
/**
* This method determines the last log on of the player even if they are
* not currently on.
* @param str the name of the user
* @return the players last log on
*/
int test_last(string word, int noload) {
mixed *file;
if (find_player(word)) {
map_delete(player_cache, word);
return find_player(word)->query_last_log_on();
}
if (noload) {
if (player_cache[word]) {
return player_cache[word]->last;
}
word = replace(word, ({ "/", "", "\\", "" }) );
file =
unguarded((: stat, query_player_ram_file_name(word) + ".o" :));
if (!file || !sizeof(file)) {
file = unguarded((: stat,
query_player_disk_file_name(word)+".o.gz" :));
}
if(!file || !sizeof(file)) {
file = unguarded((: stat,
query_delete_player_file_name(word)+
".o" :));
}
if (!file || !sizeof(file)) {
file = unguarded((: stat,
query_delete_player_file_name(word)+
".o.gz" :));
}
if(!file || !sizeof(file)) {
file = unguarded((: stat,
query_appeal_player_file_name(word)+
".o" :));
}
if (!file || !sizeof(file)) {
file = unguarded((: stat,
query_appeal_player_file_name(word)+
".o.gz" :));
}
if (!sizeof(file))
return 0;
return file[1];
}
if (!load_player(word)) {
return 0;
}
// This needs to be -ve to be consistant..
return player_cache[word]->last;
}
/**
* This method determines the last log on of the player even if they are
* not currently on.
* @param str the name of the user
* @return the players last log on
*/
string test_last_on_from(string word) {
if (find_player(word)) {
map_delete(player_cache, word);
return query_ip_name(find_player(word)) + " (" +
query_ip_number(find_player(word)) + ") ";
}
if (!load_player(word)) {
return 0;
}
// This needs to be -ve to be consistant..
return player_cache[word]->last_on_from;
}
/**
* This method determines the time the player started at.
* @param str the name of the user
* @return the players last log on
*/
int test_start_time(string word) {
if (find_player(word)) {
map_delete(player_cache, word);
return find_player(word)->query_start_time();
}
if (!load_player(word))
return 0;
return player_cache[word]->start_time;
}
/**
* This method determines if the player is a creator.
* @param str the name of the user
* @return the player to test
* @see test_last()
* @see test_user()
* @see test_creator()
*/
int test_creator(string str) {
str = lower_case (str);
if (find_player(str)) {
map_delete(player_cache, str);
return find_player(str)->query_creator();
}
if (!load_player(str))
return 0;
return player_cache[str]->creator;
}
/**
* This method returns the players home directory
* @param str the name of the user
* @return the player to test
*/
string test_home_dir(string str) {
if (find_player(str)) {
map_delete(player_cache, str);
return find_player(str)->query_home_dir();
}
if (!load_player(str))
return 0;
return player_cache[str]->home_dir;
}
/**
* This method returns the players family name
* @param str the name of the user
* @return the family name
*/
string test_family(string str) {
if (find_player(str)) {
map_delete(player_cache, str);
return find_player(str)->query_family_name();
}
if (!load_player(str))
return 0;
return player_cache[str]->family_name;
}
/**
* This method returns the players title.
* @param str the name of the user
* @return the title
*/
string test_player_title(string str) {
if (find_player(str)) {
map_delete(player_cache, str);
return find_player(str)->query_player_title();
}
if (!load_player(str))
return 0;
return player_cache[str]->player_title;
}
/** @ignore yes */
int test_password(string name, string pass) {
if (!load_player(name)) {
return 0;
}
// Have to do this since its the only function that requires restoring
// from a file if the player is active!
if (find_player(name) && player_cache[name]->password == "") {
if(file_size(query_player_ram_file_name(name) + ".o.gz") > 0)
unguarded((: restore_object, query_player_ram_file_name(name), 1 :));
else
unguarded((: restore_object, query_player_disk_file_name(name), 1 :));
player_cache[name]->password = password;
}
return crypt(pass, player_cache[name]->password) ==
player_cache[name]->password;
}
/** @ignore yes */
string get_password(string name) {
if(file_name(previous_object()) != "/secure/ftp_auth")
return "x";
if(!load_player(name))
return "x";
if(find_player(name) && player_cache[name]->password == "") {
unguarded((: restore_object,
query_player_disk_file_name(name), 1 :));
//player_cache[name]->password = password;
}
return player_cache[name]->password;
}
/**
* This method returns the signature to use on posts for the player
* even when they are off line.
* @param name the name of the player
* @return the signature, "" if none
*/
string query_signature(string name) {
string sig;
if (find_player(name)) {
map_delete(player_cache, name);
sig =
make_string(find_player(name)->query_player_alias(".signature"),
3);
} else {
if (!load_player(name))
return "";
sig = make_string(player_cache[name]->signature, 3);
}
if (sig && sig != "")
sig = "\n--\n" + strip_colours(sig);
return sig;
}
/**
* This method returns the players .project even when they are off line.
* @param name the name of the player
* @return the project, "" if none
*/
string query_project(string name, int unused) {
if (find_player(name)) {
map_delete(player_cache, name);
if (find_player(name)->query_player_alias(".project"))
return make_string(find_player(name)->query_player_alias(".project"), 5);
else
return "";
}
if (!load_player(name))
return "";
return make_string(player_cache[name]->project, 5);
}
/**
* This method returns the players .plan even when they are off line.
* @param name the name of the player
* @return the plan, "" if none
*/
string query_plan(string name, int unused) {
if (find_player(name)) {
map_delete(player_cache, name);
if (find_player(name)->query_player_alias(".plan"))
return make_string(find_player(name)->query_player_alias(".plan"),
5);
else
return "";
}
if (!load_player(name))
return "";
return make_string(player_cache[name]->plan, 5);
}
/**
* This method returns the players .reference even when they are off line.
* @param name the name of the player
* @return the reference, "" if none
*/
string query_reference(string name) {
if (find_player(name)) {
map_delete(player_cache, name);
if (find_player(name)->query_player_alias(".reference"))
return make_string(find_player(name)->
query_player_alias(".reference"), 20);
else
return "";
}
if (!load_player(name))
return "";
return make_string(player_cache[name]->reference, 20);
}
/**
* This method returns the players nationality.
* @param str the name of the user
* @return the nationality
*/
string test_nationality(string str) {
if (find_player(str)) {
map_delete(player_cache, str);
return find_player(str)->query_nationality();
}
if (!load_player(str)) {
return 0;
}
return ((class player_record)player_cache[str])->nationality;
}
/**
* This method returns the players nationality region.
* @param str the name of the user
* @return the nationality region
*/
string test_nationality_region(string str) {
if (find_player(str)) {
map_delete(player_cache, str);
return find_player(str)->query_nationality_region();
}
if (!load_player(str)) {
return 0;
}
return player_cache[str]->nationality_region;
}
/**
* This method returns the players nationality data.
* @param str the name of the user
* @return the nationality data
*/
string test_nationality_data(string str) {
if (find_player(str)) {
map_delete(player_cache, str);
return find_player(str)->query_nationality_data();
}
if (!load_player(str)) {
return 0;
}
return player_cache[str]->nationality_data;
}
/**
* Check if a players personal allow list permits logins from this IP
* @param name The player name.
* @param ip The IP address.
*/
int test_ip_allowed(string name, string ip) {
string *ips;
// Always allow the localhost. If they're logged in via the shell let
// them in :)
if(ip == "127.0.0.1")
return 1;
if(find_player(name)) {
map_delete(player_cache, name);
ips = find_player(name)->query_rhosts();
} else if (load_player(name))
ips = player_cache[name]->player_info["allowed_ips"];
if(!ips || !sizeof(ips))
return 1;
while(strlen(ip)) {
if(member_array(ip, ips) != -1)
return 1;
ip = implode((string *)explode(ip, ".")[0..<2], ".");
}
return 0;
}
mixed *stats() {
int percentage;
if (requests)
percentage = (cache_hits * 100) / requests;
return ({ ({ "cache size", sizeof(player_cache) }),
({ "requests", requests }),
({ "cache hits", cache_hits }),
({ "cache misses", requests - cache_hits }),
({ "percentage hits", percentage }), });
}
nomask int query_prevent_shadow(object ob) { return 1; }