@@ -150,7 +150,7 @@ void goon_upload(mixed ret) {
150150}
151151
152152void add_rank_beauty(object ob) {
153- int i, score, t = time();
153+ int i, score, t = time(), steps ;
154154 mapping rank;
155155 string party = ob->query("family/family_name");
156156
@@ -175,12 +175,21 @@ void add_rank_beauty(object ob) {
175175 if (score < 1) return;
176176
177177 for (i = 0; i < sizeof(beauty_ranks); i++)
178- if (!find_player(beauty_ranks[i]["id"]))
179- while (beauty_ranks[i]["time"] + 3600 < t) {
178+ if (!find_player(beauty_ranks[i]["id"])) {
179+ // FIX (AGENTS.md §7.16): shipped /log/rank data carries real
180+ // ~2008 timestamps; against today's wall clock this loop would
181+ // need ~157000 iterations per stale entry and blow the eval-cost
182+ // limit on every single quit (TOP_CMD->add_rank() is called
183+ // unconditionally from cmds/usr/quit.lpc). Cap iterations, then
184+ // unconditionally resync the timestamp to "now" below.
185+ steps = 0;
186+ while (beauty_ranks[i]["time"] + 3600 < t && steps++ < 240) {
180187 beauty_ranks[i]["time"] += 3600;
181188 beauty_ranks[i]["score"] *= 95;
182189 beauty_ranks[i]["score"] /= 100;
183- } else beauty_ranks[i]["time"] = t;
190+ }
191+ beauty_ranks[i]["time"] = t;
192+ } else beauty_ranks[i]["time"] = t;
184193
185194 if (!sizeof(beauty_ranks)) beauty_ranks = ({});
186195 beauty_ranks = sort_array(beauty_ranks, (: sort_rank :));
@@ -202,7 +211,7 @@ void add_rank_beauty(object ob) {
202211}
203212
204213void add_rank_pk(object ob) {
205- int i, score, t = time();
214+ int i, score, t = time(), steps ;
206215 int exp = ob->query("combat_exp");
207216 mapping rank;
208217 string party = ob->query("family/family_name");
@@ -220,12 +229,16 @@ void add_rank_pk(object ob) {
220229 if (score < 1) return;
221230
222231 for (i = 0; i < sizeof(pk_ranks); i++)
223- if (!find_player(pk_ranks[i]["id"]))
224- while (pk_ranks[i]["time"] + 3600 < t) {
232+ if (!find_player(pk_ranks[i]["id"])) {
233+ // FIX (AGENTS.md §7.16): see add_rank_beauty() above.
234+ steps = 0;
235+ while (pk_ranks[i]["time"] + 3600 < t && steps++ < 240) {
225236 pk_ranks[i]["time"] += 3600;
226237 pk_ranks[i]["score"] *= 97;
227238 pk_ranks[i]["score"] /= 100;
228- } else pk_ranks[i]["time"] = t;
239+ }
240+ pk_ranks[i]["time"] = t;
241+ } else pk_ranks[i]["time"] = t;
229242
230243 if (!sizeof(pk_ranks)) pk_ranks = ({});
231244 pk_ranks = sort_array(pk_ranks, (: sort_rank :));
@@ -247,7 +260,7 @@ void add_rank_pk(object ob) {
247260}
248261
249262void add_rank_rich(object ob) {
250- int i, score, t = time();
263+ int i, score, t = time(), steps ;
251264 int exp = ob->query("combat_exp");
252265 int balance = ob->query("balance");
253266 mapping rank;
@@ -267,12 +280,16 @@ void add_rank_rich(object ob) {
267280 if (score < 1) return;
268281
269282 for (i = 0; i < sizeof(rich_ranks); i++)
270- if (!find_player(rich_ranks[i]["id"]))
271- while (rich_ranks[i]["time"] + 3600 < t) {
283+ if (!find_player(rich_ranks[i]["id"])) {
284+ // FIX (AGENTS.md §7.16): see add_rank_beauty() above.
285+ steps = 0;
286+ while (rich_ranks[i]["time"] + 3600 < t && steps++ < 240) {
272287 rich_ranks[i]["time"] += 3600;
273288 rich_ranks[i]["score"] *= 97;
274289 rich_ranks[i]["score"] /= 100;
275- } else rich_ranks[i]["time"] = t;
290+ }
291+ rich_ranks[i]["time"] = t;
292+ } else rich_ranks[i]["time"] = t;
276293
277294 if (!sizeof(rich_ranks)) rich_ranks = ({});
278295 rich_ranks = sort_array(rich_ranks, (: sort_rank :));
@@ -295,7 +312,7 @@ void add_rank_rich(object ob) {
295312
296313
297314void add_rank_worker(object ob) {
298- int i, score, t = time();
315+ int i, score, t = time(), steps ;
299316 int exp = ob->query("combat_exp");
300317 mapping rank;
301318 string party = ob->query("family/family_name");
@@ -334,12 +351,18 @@ void add_rank_worker(object ob) {
334351 if (score < 1) return;
335352
336353 for (i = 0; i < sizeof(worker_ranks); i++)
337- if (!find_player(worker_ranks[i]["id"]))
338- while (worker_ranks[i]["time"] + 3600 < t) {
354+ if (!find_player(worker_ranks[i]["id"])) {
355+ // FIX (AGENTS.md §7.16): see add_rank_beauty() above. This is
356+ // the copy that actually crashed during live testing: every
357+ // `quit` calls add_rank() -> add_rank_worker() unconditionally.
358+ steps = 0;
359+ while (worker_ranks[i]["time"] + 3600 < t && steps++ < 240) {
339360 worker_ranks[i]["time"] += 3600;
340361 worker_ranks[i]["score"] *= 97;
341362 worker_ranks[i]["score"] /= 100;
342- } else worker_ranks[i]["time"] = t;
363+ }
364+ worker_ranks[i]["time"] = t;
365+ } else worker_ranks[i]["time"] = t;
343366
344367 if (!sizeof(worker_ranks)) worker_ranks = ({});
345368 worker_ranks = sort_array(worker_ranks, (: sort_rank :));
@@ -361,7 +384,7 @@ void add_rank_worker(object ob) {
361384}
362385
363386void add_rank(object ob) {
364- int i, score, t = time();
387+ int i, score, t = time(), steps ;
365388 int exp = ob->query("combat_exp");
366389 int age = ob->query("mud_age") / 3600;
367390 mapping rank;
@@ -393,12 +416,16 @@ void add_rank(object ob) {
393416 if (score < 1) return;
394417
395418 for (i = 0; i < sizeof(score_ranks); i++)
396- if (!find_player(score_ranks[i]["id"]))
397- while (score_ranks[i]["time"] + 3600 < t) {
419+ if (!find_player(score_ranks[i]["id"])) {
420+ // FIX (AGENTS.md §7.16): see add_rank_beauty() above.
421+ steps = 0;
422+ while (score_ranks[i]["time"] + 3600 < t && steps++ < 240) {
398423 score_ranks[i]["time"] += 3600;
399424 score_ranks[i]["score"] *= 97;
400425 score_ranks[i]["score"] /= 100;
401- } else score_ranks[i]["time"] = t;
426+ }
427+ score_ranks[i]["time"] = t;
428+ } else score_ranks[i]["time"] = t;
402429
403430 if (!sizeof(score_ranks)) score_ranks = ({});
404431 score_ranks = sort_array(score_ranks, (: sort_rank :));
0 commit comments