Byte Quota Utilities #75

Parent #72Owner #29Flags readSource hellcore/hellcore.db

Aliases: Byte Quota Utilities

36 verbs · 26 properties · 0 children

Verbs

VerbSpecFlagsDefinerLines
initialize_quotathis none thisrxd#756
init_for_corethis none thisrxd#7512
adjust_quota_for_programmerthis none thisrxd#751
bi_createthis none thisrxd#7519
enable_createthis none thisrxd#755
disable_createthis none thisrxd#755
parse_create_argsthis none thisrxd#759
creation_permitted verb_addition_permitted property_addition_permittedthis none thisrxd#7525
all_charactersthis none thisrxd#7513
display_quotathis none thisrxd#7535
get_quotathis none thisrxd#751
charge_quotathis none thisrxd#7514
reimburse_quotathis none thisrxd#7519
set_quotathis none thisrxd#757
get_size_quotathis none thisrxd#7515
display_quota_summarythis none thisrxd#7519
quota_remainingthis none thisrxd#755
preliminary_reimburse_quotathis none thisrxd#756
value_bytesthis none thisrxd#7516
object_bytes object_sizethis none thisrxd#7528
do_summaryany with/using thisrxd#7510
summarize_one_userthis none thisrxd#7557
recent_object_bytesthis none thisrxd#7510
measurement_taskthis none thisrxd#7520
can_peekthis none thisrxd#751
can_touchthis none thisrxd#751
do_breakdownthis none thisrxd#7557
object_overhead_bytesthis none thisrxd#752
property_overhead_bytesthis none thisrxd#752
verb_overhead_bytesthis none thisrxd#753
add_owned_objectthis none thisrxd#755
measurement_task_noforkthis none thisrxd#757
measurement_task_bodythis none thisrxd#7597
schedule_measurement_taskthis none thisrxd#7510
task_permsthis none thisrxd#753
property_existsthis none thisrxd#753

Properties

PropertyDefinerFlagsOwnerValue
default_quota#75rc#29{50000, 0, 0, 1}
large_negative_number#75rc#29-10000
max_unmeasured#75rc#2910
unmeasured_multiplier#75rc#29100
working#75rc#29#2
cycle_days#75rc#295
task_time_limit#75rc#29500
byte_based#75rc#291
exempted#75rc#29{}
task_repeat#75rc#291
repeat_cycle#75rc#290
too_large#75rc#291000000
large_objects#75rc#29{}
report_recipients#75rc#29{#2}
measurement_task_running#75rc#290
help_msg#72rc#29
list of 66{"Verbs a user might want to call from a program:", " :bi_create -- built-in create() call, takes same args.", "", " :get_quota(who) -- just get the raw size_quota property", " :display_quota(who) -- prints to player the quota of who. If caller_perms() controls who, include any secondary characters. Called by @quota.", " :get_size_quota(who [allchars]) -- return the quota of who, if allchars flag set, add info from all secondary chars, if caller_perms() permits.", "", " :value_bytes(value) -- computes the size of the value.", " :object_bytes(object) -- computes the size of the object and caches it.", " :recent_object_bytes(object, days) -- computes and caches the size of object only if cached value more than days old. Returns cached value.", " :do_summary(user) -- prints out the results of summarize-one-user.", " :summarize_one_user(user) -- summarizes and caches space usage for user. See verb help for details.", "", "Verbs the system calls:", " :\"creation_permitted verb_addition_permitted property_addition_permitted\"(who) -- returns true if who is permitted to build.", " :initialize_quota(who) -- sets quota for newly created players", " :adjust_quota_for_programmer(who) -- empty; might add more quota to newly @progged player.", " :enable_create(who) -- sets .ownership_quota to 1", " :disable_create(who) -- sets .ownership_quota back to -1000 to prohibit create()", " :charge_quota(who, object) -- subtract the size of object from who's quota. Manipulates the #-unmeasured if what is not currently measured. Called by $wiz_utils:set_owner.", " :reimburse_quota(who, object) -- add the size of object to who's quota. Ditto.", " :preliminary_reimburse_quota(who, object) -- Because the set_owner is done *after* an object has been turned into $garbage, ordinary reimbursement fails. So we use this verb in the $recycler.", " :set_quota(who, howmuch)", " :quota_remaining(who) ", " :display_quota_summary -- internal, called by display quota", "", "The measurement task:", "", " :measurement_task() -- runs once every 24 hours measuring stuff, separated from the scheduling in case you just want to run it once. Calls the body and then reports via moomail.", " :schedule_measurement_task() -- actually schedules it. Look here to change the start time.", " :measurement_task_body(timeout) -- does the real work, working for no longer than timeout seconds.", " .task_time_limit -- integer number of seconds indicating for how long it should run each day.", " .working -- object indicating the player whom it is either working on now (or if not running) will pick up working on when it commences tonight.", " .cycle_days -- integer numbers indicating how long ago an object must have been measured before it will be remeasured.", " .repeat_cycle -- boolean. 0 means have a vanilla cycle (goes through all players() exactly once measuring their objects measured more than .cycle_days ago). 1 means to have a much more complex algorithm: The first cycle, it only measures stuff owned by people who have logged in within .cycle_days. If, in .task_time_limit seconds, it measures all objects not measured in cycle_days owned by such people, it will run again measuring those objects which have not been measured in cycle_days - 1, considering people who have logged in within 4 * cycle_days, repeating until it has used up its seconds. (\"Doing some of tomorrow's work.\") Selecting .repeat_cycle = 1 is appropriate only for large MOOs.", " .exempted -- list of objects to never measure (useful if there are huge objects). Suggested huge objects include $player_db and $site_db.", " .measurement_task -- indicates the task_id() of the most recent measurement task -- used to prevent duplicate invocation.", " .report_recipients -- recipients of the daily reports. Set to {} to disable reporting entirely.", "", "See help @measure and help @quota for the command line verbs.", "", "", "Porter's notes: If you are planning on porting this system to another MOO, here are the things to grab in addition to @dumping all of $quota_utils:", "", "The following verbs have been changed on $prog:", "@prop*erty @verb @copy (@add-alias @copy-move as well)", "", "The following verbs have been changed on $wiz:", "@programmer @quota", "", "The following verbs have been changed on $wiz_utils:", "set_programmer set_owner make_player", "", "The following verbs have been changed on $builder:", "@quota _create", "", "This verb probably should have gone on $builder.", "@measure", "", "The followig verbs have been changed on $recycler", "_recycle _create setup_toad", "", "The following verb has been changed on $login:", "create", "", "And don't forget $object_quota_utils, which has the object based implementation."}
aliases#1rc#29{"Byte Quota Utilities"}
description#1rc#29{"This is the Byte Quota Utilities utility package. See `help $quota_utils' for more details."}
object_size#1r#29{33480, 1298433815}
hidden_verbs#1rc#29<clear>
phelp_msg#1rc#29<clear>
weight#1rc#29<clear>
owner_verbs#1rc#29<clear>
plural_name#1rc#29<clear>
client_image#1rc#29<clear>
listening#1rc#29<clear>

Ancestry

Ancestors (nearest first): #72 Generic Utilities Package#1 root

Children: none

Call graph

calls n75_3 #75:bi_create n75_6 #75:parse_create_args n75_3->n75_6 n57_2 #57:_create n75_3->n57_2 n75_7 #75:creation_permitted n75_3->n75_7 n75_4 #75:enable_create n75_3->n75_4 n75_5 #75:disable_create n75_3->n75_5 n75_11 #75:charge_quota n75_3->n75_11 n75_30 #75:add_owned_object n75_3->n75_30 n42_0 #42:controls n75_6->n42_0 n45_0 #45:has_property n75_7->n45_0 n75_8 #75:all_characters n75_7->n75_8 n75_11->n45_0 n75_8->n45_0 n75_24 #75:can_peek n75_8->n75_24 n75_24->n42_0 n75_9 #75:display_quota n75_9->n75_8 n75_9->n75_24 n107_43 #107:tell n75_9->n107_43 n20_26 #20:group_number n75_9->n20_26 n75_15 #75:display_quota_summary n75_9->n75_15 n75_15->n107_43 n75_15->n20_26 n34_2 #34:get_pronoun n75_15->n34_2 n6_45 #6:ctime n75_15->n6_45 n75_12 #75:reimburse_quota n75_12->n45_0 n75_13 #75:set_quota n75_25 #75:can_touch n75_13->n75_25 n75_14 #75:get_size_quota n75_14->n75_8 n75_14->n75_24 n75_16 #75:quota_remaining n75_16->n75_14 n75_17 #75:preliminary_reimburse_quota n75_17->n75_12 n75_18 #75:value_bytes n75_18->n75_18 n48_8 #48:suspend_if_needed n75_18->n48_8 n75_19 #75:object_bytes n75_19->n45_0 n17_37 #17:random_wizard n75_19->n17_37 n75_20 #75:do_summary n75_20->n107_43 n75_20->n20_26 n75_21 #75:summarize_one_user n75_20->n75_21 n20_8 #20:from_seconds n75_20->n20_8 n75_21->n45_0 n75_21->n48_8 n75_21->n75_19 n75_22 #75:recent_object_bytes n75_22->n75_19 n75_23 #75:measurement_task n75_23->n48_8 n75_23->n75_21 n75_32 #75:measurement_task_body n75_23->n75_32 n38_2 #38:send_message n75_23->n38_2 n20_25 #20:ordinal n75_23->n20_25 n35_6 #35:dhms n75_23->n35_6 n75_32->n45_0 n75_32->n48_8 n75_32->n75_19 n75_32->n75_21 n75_32->n38_2 n45_2 #45:has_verb n75_32->n45_2 n75_26 #75:do_breakdown n75_26->n75_24 n45_1 #45:all_properties n75_26->n45_1 n75_27 #75:object_overhead_bytes n75_26->n75_27 n47_11 #47:reverse n75_26->n47_11 n47_15 #47:sort_suspended n75_26->n47_15 n47_16 #47:slice n75_26->n47_16 n75_28 #75:property_overhead_bytes n75_26->n75_28 n75_29 #75:verb_overhead_bytes n75_26->n75_29 n45_15 #45:all_properties_suspended n75_28->n45_15 n75_31 #75:measurement_task_nofork n75_31->n75_32 n75_31->n38_2 n75_31->n20_25

Showing 48 of 52 verbs; 4 not shown.

Source

initialize_quota

Spec this none thisFlags rxdOwner #29Definer #75

Referenced by

none

Source

1if (!caller_perms().wizard)
2return E_PERM;
3else
4args[1].size_quota = this.default_quota;
5args[1].ownership_quota = this.large_negative_number;
6endif

init_for_core

Spec this none thisFlags rxdOwner #361Definer #75

Referenced by

none

Source

1if (!caller_perms().wizard)
2return E_PERM;
3else
4set_verb_code(this, "can_peek", {"return args[1]==this.owner || $perm_utils:controls(args[1], args[2]);"});
5set_verb_code(this, "can_touch", {"return args[1].wizard;"});
6this.exempted = {};
7this.working = #2;
8this.task_time_limit = 500;
9this.repeat_cycle = 0;
10this.large_objects = {};
11this.report_recipients = {#2};
12endif

adjust_quota_for_programmer

Spec this none thisFlags rxdOwner #29Definer #75

Referenced by

none

Source

1return 0;

bi_create

Spec this none thisFlags rxdOwner #361Definer #75

Referenced by

none

Source

1set_task_perms(caller_perms());
2who = this:parse_create_args(@args);
3"Because who can be E_INVARG, need to catch E_TYPE. Let $recycler:_create deal with returning E_PERM since that's what's going to happen. Ho_Yan 11/19/96.";
4if ((!`who.wizard ! E_TYPE => 0') && $recycler.contents)
5return $recycler:_create(@args);
6elseif (this:creation_permitted(who))
7this:enable_create(who);
8value = `create(@args) ! ANY';
9this:disable_create(who);
10if (typeof(value) != ERR)
11this:charge_quota(who, value);
12if ((typeof(who.owned_objects) == LIST) && (!(value in who.owned_objects)))
13this:add_owned_object(who, value);
14endif
15endif
16return value;
17else
18return E_QUOTA;
19endif

enable_create

Spec this none thisFlags rxdOwner #361Definer #75

Referenced by

Source

1if ((caller != this) && (!caller_perms().wizard))
2return E_PERM;
3else
4args[1].ownership_quota = 1;
5endif

disable_create

Spec this none thisFlags rxdOwner #361Definer #75

Referenced by

Source

1if ((caller != this) && (!caller_perms().wizard))
2return E_PERM;
3else
4args[1].ownership_quota = this.large_negative_number;
5endif

parse_create_args

Spec this none thisFlags rxdOwner #29Definer #75

Referenced by

Source

1"This figures out who is gonna own the stuff @create does.  If one arg, return caller_perms().  If two args, then if caller_perms().wizard, args[2].";
2{what, ?who = #-1} = args;
3if (!valid(who))
4return caller_perms();
5elseif ($perm_utils:controls(caller_perms(), who))
6return who;
7else
8return E_INVARG;
9endif

creation_permitted verb_addition_permitted property_addition_permitted

Spec this none thisFlags rxdOwner #29Definer #75

Referenced by

Source

1"Here's the tricky one.  Collect all the user's characters' cached usage data and total quotas.  Compare same.  If usage bigger than quotas, return 0.  Else, add up the total number of objects that haven't been measured recently.  If greater than the allowed, return 0.  Else, reluctantly, return 1.";
2who = args[1];
3if (who.wizard || (who == $hacker))
4"... sorry folks --Rog";
5return 1;
6endif
7if ((!$object_utils:has_property(who, "size_quota")) || is_clear_property(who, "size_quota"))
8return 0;
9endif
10allwho = this:all_characters(who);
11quota = 0;
12usage = 0;
13unmeasured = 0;
14for x in (allwho)
15quota = quota + x.size_quota[1];
16usage = usage + x.size_quota[2];
17unmeasured = unmeasured + x.size_quota[4];
18endfor
19if (usage >= quota)
20return 0;
21elseif (unmeasured >= this.max_unmeasured)
22return 0;
23else
24return 1;
25endif

all_characters

Spec this none thisFlags rxdOwner #29Definer #75

Referenced by

Source

1{who} = args;
2if ((caller != this) && (!this:can_peek(caller_perms(), who)))
3return E_PERM;
4elseif ($object_utils:has_property($local, "second_char_registry"))
5seconds = $local.second_char_registry:all_second_chars(who);
6if (seconds == E_INVARG)
7return {who};
8else
9return seconds;
10endif
11else
12return {who};
13endif

display_quota

Spec this none thisFlags rxdOwner #29Definer #75

Referenced by

none

Source

1who = args[1];
2if (this:can_peek(caller_perms(), who) && (length(all = this:all_characters(who)) > 1))
3many = 1;
4else
5many = 0;
6all = {who};
7endif
8if (many)
9tquota = 0;
10tusage = 0;
11ttime = $maxint;
12tunmeasured = 0;
13tunmeasurable = 0;
14endif
15for x in (all)
16{quota, usage, timestamp, unmeasured} = x.size_quota;
17unmeasurable = 0;
18if (unmeasured >= 100)
19unmeasurable = unmeasured / 100;
20unmeasured = unmeasured % 100;
21endif
22if (many)
23player:tell(x.name, " quota: ", $string_utils:group_number(quota), "; usage: ", $string_utils:group_number(usage), "; unmeasured: ", unmeasured, "; no .object_size: ", unmeasurable, ".");
24tquota = tquota + quota;
25tusage = tusage + usage;
26ttime = min(ttime, timestamp);
27tunmeasured = tunmeasured + unmeasured;
28tunmeasurable = tunmeasurable + unmeasurable;
29endif
30endfor
31if (many)
32this:display_quota_summary(who, tquota, tusage, ttime, tunmeasured, tunmeasurable);
33else
34this:display_quota_summary(who, quota, usage, timestamp, unmeasured, unmeasurable);
35endif

get_quota

Spec this none thisFlags rxdOwner #29Definer #75

Referenced by

none

Source

1return args[1].size_quota[1];

charge_quota

Spec this none thisFlags rxdOwner #29Definer #75

Referenced by

Source

1"Charge args[1] for the quota required to own args[2]";
2{who, what} = args;
3if ((caller == this) || caller_perms().wizard)
4usage_index = 2;
5unmeasured_index = 4;
6object_size = $object_utils:has_property(what, "object_size") ? what.object_size[1] | -1;
7if (object_size <= 0)
8who.size_quota[unmeasured_index] = who.size_quota[unmeasured_index] + 1;
9else
10who.size_quota[usage_index] = who.size_quota[usage_index] + object_size;
11endif
12else
13return E_PERM;
14endif

reimburse_quota

Spec this none thisFlags rxdOwner #29Definer #75

Referenced by

Source

1"reimburse args[1] for the quota required to own args[2]";
2"If it is a $garbage, then if who = $hacker, then we mostly ignore everything.  Who cares what $hacker's quota looks like.";
3{who, what} = args;
4if ((caller == this) || caller_perms().wizard)
5usage_index = 2;
6unmeasured_index = 4;
7if (parent(what) == $garbage)
8return 0;
9elseif (((valid(who) && is_player(who)) && $object_utils:has_property(what, "object_size")) && (!is_clear_property(who, "size_quota")))
10object_size = what.object_size[1];
11if (object_size <= 0)
12who.size_quota[unmeasured_index] = who.size_quota[unmeasured_index] - 1;
13else
14who.size_quota[usage_index] = who.size_quota[usage_index] - object_size;
15endif
16endif
17else
18return E_PERM;
19endif

set_quota

Spec this none thisFlags rxdOwner #29Definer #75

Referenced by

none

Source

1"Set args[1]'s quota to args[2]";
2if ((caller_perms().wizard || (caller == this)) || this:can_touch(caller_perms()))
3"Size_quota[1] is the total quota permitted.";
4return args[1].size_quota[1] = args[2];
5else
6return E_PERM;
7endif

get_size_quota

Spec this none thisFlags rxdOwner #29Definer #75

Referenced by

Source

1"Return args[1]'s quotas.  second arg of 1 means add all second chars.";
2{who, ?all = 0} = args;
3if (all && ((caller == this) || this:can_peek(caller_perms(), who)))
4all = this:all_characters(who);
5else
6all = {who};
7endif
8baseline = {0, 0, 0, 0};
9for x in (all)
10baseline[1] = baseline[1] + x.size_quota[1];
11baseline[2] = baseline[2] + x.size_quota[2];
12baseline[3] = min(baseline[3], x.size_quota[3]) || x.size_quota[3];
13baseline[4] = baseline[4] + x.size_quota[4];
14endfor
15return baseline;

display_quota_summary

Spec this none thisFlags rxdOwner #29Definer #75

Referenced by

Source

1{who, quota, usage, timestamp, unmeasured, unmeasurable} = args;
2player:tell(who.name, " has a total building quota of ", $string_utils:group_number(quota), " bytes.");
3player:tell($gender_utils:get_pronoun("P", who), " total usage was ", $string_utils:group_number(usage), " as of ", player:ctime(timestamp), ".");
4if (usage > quota)
5player:tell(who.name, " is over quota by ", $string_utils:group_number(usage - quota), " bytes.");
6else
7player:tell(who.name, " may create up to ", $string_utils:group_number(quota - usage), " more bytes of objects, properties, or verbs.");
8endif
9if (unmeasured)
10plural = unmeasured != 1;
11player:tell("There ", plural ? tostr("are ", unmeasured, " objects") | "is 1 object", " which ", plural ? "are" | "is", " not yet included in the tally; this tally may thus be inaccurate.");
12if (unmeasured >= this.max_unmeasured)
13player:tell("The number of unmeasured objects is too large; no objects may be created until @measure new is used.");
14endif
15endif
16if (unmeasurable)
17plural = unmeasurable != 1;
18player:tell("There ", plural ? tostr("are ", unmeasurable, " objects") | "is 1 object", " which do", plural ? "" | "es", " not have a .object_size property and will thus prevent additional building.", (who == player) ? "  Contact a wizard for assistance in having this situation repaired." | "");
19endif

quota_remaining

Spec this none thisFlags rxdOwner #29Definer #75

Referenced by

none

Source

1"This wants to only be called by a wizard cuz I'm lazy.  This is just for @second-char anyway.";
2if (caller_perms().wizard)
3q = this:get_size_quota(args[1], 1);
4return q[1] - q[2];
5endif

preliminary_reimburse_quota

Spec this none thisFlags rxdOwner #29Definer #75

Referenced by

none

Source

1"This does the reimbursement work of the recycler, since we ignore $garbage in ordinary reimbursement.";
2if (caller_perms().wizard)
3this:reimburse_quota(@args);
4else
5return E_PERM;
6endif

value_bytes

Spec this none thisFlags rxdOwner #361Definer #75

Referenced by

Source

1return value_bytes(args[1]);
2set_task_perms(caller_perms());
3v = args[1];
4t = typeof(v);
5if (t == LIST)
6b = ((length(v) + 1) * 2) * 4;
7for vv in (v)
8$command_utils:suspend_if_needed(2);
9b = b + this:value_bytes(vv);
10endfor
11return b;
12elseif (t == STR)
13return length(v) + 1;
14else
15return 0;
16endif

object_bytes object_size

Spec this none thisFlags rxdOwner #361Definer #75

Referenced by

Source

1"No need for lengthy algorithms to measure an object, we have a builtin now. Ho_Yan 10/31/96";
2set_task_perms($wiz_utils:random_wizard());
3o = args[1];
4if (((($object_utils:has_property(o, "object_size") && (o.object_size[1] > this.too_large)) && (!caller_perms().wizard)) && (caller_perms() != this.owner)) && (caller_perms() != $hacker))
5return o.object_size[1];
6endif
7b = object_bytes(o);
8if ($object_utils:has_property(o, "object_size"))
9oldsize = is_clear_property(o, "object_size") ? 0 | o.object_size[1];
10if ($object_utils:has_property(o.owner, "size_quota"))
11if (length(o.owner.size_quota) >= 4)
12"Update quota cache.";
13if (oldsize)
14o.owner.size_quota[2] = o.owner.size_quota[2] + (b - oldsize);
15else
16o.owner.size_quota[2] = o.owner.size_quota[2] + b;
17if (o.owner.size_quota[4] > 0)
18o.owner.size_quota[4] = o.owner.size_quota[4] - 1;
19endif
20endif
21endif
22endif
23o.object_size = {b, time()};
24endif
25if (b > this.too_large)
26this.large_objects = setadd(this.large_objects, o);
27endif
28return b;

do_summary

Spec any with/using thisFlags rxdOwner #29Definer #75

Referenced by

Source

1who = args[1];
2results = this:summarize_one_user(who);
3{total, nuncounted, nzeros, oldest, eldest} = results;
4player:tell(who.name, " statistics:");
5player:tell("  ", $string_utils:group_number(total), " bytes of storage measured.");
6player:tell("  Oldest measurement date ", ctime(oldest), " (", $string_utils:from_seconds(time() - oldest), " ago) of object ", eldest, " (", valid(eldest) ? eldest.name | "$nothing", ")");
7if (nzeros || nuncounted)
8player:tell("  Number of objects with no statistics recorded:  ");
9player:tell("      ", nzeros, " recently created, ", nuncounted, " not descendents of #1");
10endif

summarize_one_user

Spec this none thisFlags rxdOwner #29Definer #75

Referenced by

Source

1"Summarizes total space usage by one user (args[1]).  Optional second argument is a flag to say whether to re-measure all objects for this user; specify the number of seconds out of date you are willing to accept.  If negative, will only re-measure objects which have no recorded data.";
2"Returns a list of four values:";
3"  total : total measured space in bytes";
4"  uncounted : Number of objects that were not counted because they aren't descendents of #1";
5"  zeros : Number of objects which have been created too recently to have any measurement data at all (presumably none if re-measuring)";
6"  most-out-of-date : the time() the oldest actual measurement was taken";
7"  object-thereof: the object who had this time()'d measurement";
8who = args[1];
9if (length(args) == 2)
10if (args[2] < 0)
11earliest = 1;
12else
13earliest = time() - args[2];
14endif
15else
16earliest = 0;
17endif
18nzeros = 0;
19oldest = time();
20eldest = #-1;
21nuncounted = 0;
22total = 0;
23for x in ((typeof(who.owned_objects) == LIST) ? who.owned_objects | {})
24if (x.owner == who)
25"Bulletproofing against recycling during suspends!";
26"Leaves us open to unsummarized creation during this period, which is unfortunate.";
27if ($object_utils:has_property(x, "object_size"))
28size = x.object_size[1];
29time = x.object_size[2];
30if (time < earliest)
31"Re-measure.  This side-effects x.object_size.";
32this:object_bytes(x);
33size = x.object_size[1];
34time = x.object_size[2];
35endif
36if (time && (time <= oldest))
37oldest = time;
38eldest = x;
39elseif (!time)
40nzeros = nzeros + 1;
41endif
42if (size >= 0)
43total = total + size;
44endif
45else
46nuncounted = nuncounted + 1;
47endif
48endif
49$command_utils:suspend_if_needed(0);
50endfor
51if (!is_clear_property(who, "size_quota"))
52"Cache the data, but only if they aren't scamming.";
53who.size_quota[2] = total;
54who.size_quota[3] = oldest;
55who.size_quota[4] = (nuncounted * this.unmeasured_multiplier) + nzeros;
56endif
57return {total, nuncounted, nzeros, oldest, eldest};

recent_object_bytes

Spec this none thisFlags rxdOwner #361Definer #75

Referenced by

none

Source

1":recent_object_bytes(x, n) -- return object size of x, guaranteed to be no more than n days old.  N defaults to this.cycle_days.";
2{object, ?since = this.cycle_days} = args;
3if (!valid(object))
4return 0;
5elseif (`object.object_size[2] ! ANY => 0' > (time() - (((since * 24) * 60) * 60)))
6"Trap error when doesn't have .object_size for some oddball reason ($garbage). Ho_Yan 11/19/96";
7return object.object_size[1];
8else
9return this:object_bytes(object);
10endif

measurement_task

Spec this none thisFlags rxdOwner #361Definer #75

Referenced by

Source

1if (!caller_perms().wizard)
2return E_PERM;
3else
4start_time = time();
5{num_processed, num_repetitions} = this:measurement_task_body(args[1]);
6players = players();
7lengthp = length(players);
8if ((!num_repetitions) && (num_processed < (lengthp / 2)))
9"Add this in because we aren't getting people summarized like we should.  We're going to work for way longer now, cuz we're going to do a second pass, but we really need to get those summaries done.  Only do this if we hardly did any work.  Note the -1 here: measure all newly created objects as well.  More work, sigh.";
10extra_end = time() + (3600 * 3);
11for x in (players)
12if (is_player(x) && (time() < extra_end))
13"Robustness as above, plus don't run all day.  My kingdom for a break statement";
14this:summarize_one_user(x, -1);
15endif
16$command_utils:suspend_if_needed(0);
17endfor
18endif
19$mail_agent:send_message(player, this.report_recipients, "quota-utils report", {tostr("About to measure objects of player ", this.working.name, " (", this.working, "), ", $string_utils:ordinal(this.working in players), " out of ", lengthp, ".  We processed ", num_processed + (lengthp * num_repetitions), " players in this run in ", num_repetitions, " time", (num_repetitions == 1) ? "" | "s", " through all players.  Total time spent:  ", $time_utils:dhms(time() - start_time), ".")});
20endif

can_peek

Spec this none thisFlags rxdOwner #29Definer #75

Referenced by

Source

1return (args[1] == this.owner) || $perm_utils:controls(args[1], args[2]);

can_touch

Spec this none thisFlags rxdOwner #29Definer #75

Referenced by

Source

1return args[1].wizard;

do_breakdown

Spec this none thisFlags rxdOwner #361Definer #75

Referenced by

Source

1dobj = args[1];
2who = valid(caller_perms()) ? caller_perms() | player;
3if (!this:can_peek(who, dobj.owner))
4return E_PERM;
5endif
6props = $object_utils:all_properties(dobj);
7grand_total = obj_over = this:object_overhead_bytes(dobj);
8output = {tostr("Object overhead:  ", obj_over)};
9if (props)
10total = 0;
11lines = {};
12output = {@output, "Properties, defined and inherited, sorted by size:"};
13for x in (props)
14if (!is_clear_property(dobj, x))
15size = value_bytes(dobj.(x));
16total = total + size;
17if (size)
18lines = {@lines, {x, size}};
19endif
20endif
21yield 1;
22endfor
23lines = $list_utils:reverse($list_utils:sort_suspended(0, lines, $list_utils:slice(lines, 2)));
24for x in (lines)
25text = tostr("  ", x[1], ":  ", x[2]);
26output = {@output, text};
27endfor
28output = {@output, tostr("Total size of properties:  ", total)};
29grand_total = grand_total + total;
30endif
31prop_over = this:property_overhead_bytes(dobj, props);
32output = {@output, tostr("Property overhead:  ", prop_over)};
33grand_total = grand_total + prop_over;
34if (verbs(dobj))
35output = {@output, "Verbs, sorted by size:"};
36total = 0;
37lines = {};
38for x in [1..length(verbs(dobj))]
39vname = verb_info(dobj, x)[3];
40size = (value_bytes(verb_code(dobj, x, 0, 0)) + length(vname)) + 1;
41total = total + size;
42lines = {@lines, {vname, size}};
43yield 1;
44endfor
45lines = $list_utils:reverse($list_utils:sort_suspended(0, lines, $list_utils:slice(lines, 2)));
46for x in (lines)
47text = tostr("  ", x[1], ":  ", x[2]);
48output = {@output, text};
49endfor
50output = {@output, tostr("Total size of verbs:  ", total)};
51grand_total = grand_total + total;
52verb_over = this:verb_overhead_bytes(dobj);
53output = {@output, tostr("Verb overhead:  ", verb_over)};
54grand_total = grand_total + verb_over;
55endif
56output = {@output, tostr("Grand total:  ", grand_total)};
57return output;

object_overhead_bytes

Spec this none thisFlags rxdOwner #29Definer #75

Referenced by

Source

1object = args[1];
2return ((13 * 4) + length(object.name)) + 1;

property_overhead_bytes

Spec this none thisFlags rxdOwner #361Definer #75

Referenced by

Source

1{o, ?ps = $object_utils:all_properties_suspended(o)} = args;
2return (value_bytes(properties(o)) - 4) + ((length(ps) * 4) * 4);

verb_overhead_bytes

Spec this none thisFlags rxdOwner #361Definer #75

Referenced by

Source

1o = args[1];
2vs = verbs(o);
3return (length(vs) * 5) * 4;

add_owned_object

Spec this none thisFlags rxdOwner #361Definer #75

Referenced by

Source

1":add_owned_object(who, what) -- adds what to whose .owned_objects.";
2{who, what} = args;
3if ((typeof(who.owned_objects) == LIST) && (what.owner == who))
4who.owned_objects = setadd(who.owned_objects, what);
5endif

measurement_task_nofork

Spec this none thisFlags rxdOwner #361Definer #75

Referenced by

none

Source

1"This is a one-shot run of the measurement task, as opposed to :measurement_task, which will fork once per day.";
2if (!caller_perms().wizard)
3return E_PERM;
4else
5{num_processed, num_repetitions} = this:measurement_task_body();
6$mail_agent:send_message(player, player, "quota-utils report", {tostr("About to measure objects of player ", this.working.name, " (", this.working, "), ", $string_utils:ordinal(this.working in players), " out of ", lengthp, ".  We processed ", num_processed + (lengthp * num_repetitions), " players in this run in ", num_repetitions, " times through all players.")});
7endif

measurement_task_body

Spec this none thisFlags rxdOwner #361Definer #75

Referenced by

Source

1if (!caller_perms().wizard)
2return E_PERM;
3else
4num_processed = 0;
5num_repetitions = 0;
6usage_index = 2;
7time_index = 3;
8unmeasured_index = 4;
9players = setremove(players(), $hacker);
10lengthp = length(players);
11index = this.working in players;
12keep_going = 1;
13if (!index)
14"Uh, oh, our guy got reaped while we weren't looking.  Better look for someone else.";
15index = 1;
16while ((this.working > players[index]) && (index < lengthp))
17$command_utils:suspend_if_needed(0);
18index = index + 1;
19endwhile
20this.working = players[index];
21endif
22day = (60 * 60) * 24;
23stop = time() + args[1];
24early = time() - (day * this.cycle_days);
25tooidle = day * this.cycle_days;
26"tooidletime is only used if !this.repeat_cycle.";
27tooidletime = time() - tooidle;
28local_per_player_hack = $object_utils:has_verb($local, "per_player_daily_scan");
29while ((time() < stop) && keep_going)
30who = players[index];
31if (is_player(who) && $object_utils:has_property(who, "size_quota"))
32"Robustness in the face of reaping...";
33if ((!this.repeat_cycle) || ((who.last_disconnect_time > tooidletime) && (who.last_disconnect_time != $maxint)))
34"only measure people who login regularly if we're a big moo.";
35usage = 0;
36unmeasured = 0;
37earliest = time();
38for o in (who.owned_objects)
39if ((valid(o) && (o.owner == who)) && (!(o in this.exempted)))
40"sanity check: might have recycled while we suspended!";
41if ($object_utils:has_property(o, "object_size"))
42if (o.object_size[2] < early)
43usage = usage + this:object_bytes(o);
44else
45usage = usage + o.object_size[1];
46earliest = min(earliest, o.object_size[2]);
47endif
48else
49unmeasured = unmeasured + 1;
50endif
51endif
52$command_utils:suspend_if_needed(3);
53endfor
54if (!is_clear_property(who, "size_quota"))
55who.size_quota[usage_index] = usage;
56who.size_quota[unmeasured_index] = this.unmeasured_multiplier * unmeasured;
57who.size_quota[time_index] = earliest;
58else
59$mail_agent:send_message(player, player, "Quota Violation", {tostr(who, " has a clear .size_quota property."), $string_utils:names_of({who, @$object_utils:ancestors(who)})});
60endif
61elseif (who.size_quota[unmeasured_index])
62"If they managed to create an object *despite* being too idle (presumably programmatically), measure it.";
63this:summarize_one_user(who, -1);
64endif
65elseif (is_player(who))
66"They don't have a size_quota property.  Whine.";
67$mail_agent:send_message(player, player, "Quota Violation", {tostr(who, " doesn't seem to have a .size_quota property."), $string_utils:names_of({who, @$object_utils:ancestors(who)})});
68endif
69if (local_per_player_hack)
70$local:per_player_daily_scan(who);
71endif
72if (index >= lengthp)
73index = 1;
74else
75index = index + 1;
76endif
77num_processed = num_processed + 1;
78if (num_processed > lengthp)
79if (this.repeat_cycle)
80"If we've gotten everyone up to threshold, try measuring some later than that.";
81early = early + ((24 * 60) * 60);
82tooidle = tooidle * 4;
83tooidletime = tooidletime - tooidle;
84num_repetitions = num_repetitions + 1;
85num_processed = 0;
86if (early > time())
87"Don't spin our wheels when we've measured everything!";
88keep_going = 0;
89endif
90else
91keep_going = 0;
92endif
93endif
94this.working = players[index];
95endwhile
96return {num_processed, num_repetitions};
97endif

schedule_measurement_task

Spec this none thisFlags rxdOwner #361Definer #75

Referenced by

Source

1if ((caller == this) || caller_perms().wizard)
2day = 24 * 3600;
3hour_of_day_GMT = 8;
4fork ((((hour_of_day_GMT * 60) * 60) + day) - (time() % day))
5this:schedule_measurement_task();
6this.measurement_task_running = task_id();
7this:measurement_task(this.task_time_limit);
8this.measurement_task_running = 0;
9endfork
10endif

task_perms

Spec this none thisFlags rxdOwner #361Definer #75

Referenced by

Source

1"Put all your wizards in $byte_quota_utils.wizards.  Then various long-running tasks will cycle among the permissions, spreading out the scheduler-induced personal lag.";
2$wiz_utils.old_task_perms_user = setadd($wiz_utils.old_task_perms_user, caller);
3return $wiz_utils:random_wizard();

property_exists

Spec this none thisFlags rxdOwner #361Definer #75

Referenced by

none

Source

1"this:property_exists(object, property)";
2" => does the specified property exist?";
3return !(!`property_info(@args) ! ANY');