Welcome to the Builder Academy

Question TBA-2020 Bug Fix Request

More
28 Feb 2020 07:57 #8593 by Sapphire
Hey there,
I encountered a bug on my older version of the code and loaded up a fresh 2020 copy of TBAMud to see if the bug had been patched, I discovered it had not.

Here is the problem I am encountering. When I create a drop trigger intended for rooms(world) calling upon the %purge% function for single target objects, the mud crashes when attempting to drop a gold coin.

I attempted to figure out what is wrong with this in GDB and it appears to be halting on handler.c, line 692, obj_from_room void function. I was unable to resolve the issue, but I was hoping perhaps someone in the community might have a better grasp than I do on what is causing the crash. It's a major issue for me because I have a significant number of mazes on my mud which are configured with similar triggers to prevent players from dropping objects as bread crumbs. In this instance, a clever player decided to use gold coins to create bread crumbs and that was when we discovered the crash causing bug.

I included a basic copy of the trigger below.

Trigger Editor [1250]

1) Name : Drop Test
2) Intended for : Rooms
3) Trigger types: Drop
4) Numeric Arg : 100
5) Arguments :
6) Commands:
%purge% %object%

W) Copy Trigger
Q) Quit

Please Log in or Create an account to join the conversation.

More
28 Feb 2020 20:54 #8594 by Castillo
Replied by Castillo on topic TBA-2020 Bug Fix Request
The bug is not obvious.

But, it seems that when trying to drop gold from

static void perform_drop_gold

char buf[MAX_STRING_LENGTH];

if (!drop_wtrigger(obj, ch)) {
send_to_char(ch, "%d\r\n", obj->item_number);
// extract_obj(obj);
// return;
}


when returning from drop_wtrigger, obj get either corrupted or deleted. An eventually it will crash into extract_obj(obj).

The test i did in drop_wtrigger:

int drop_wtrigger(obj_data *obj, char_data *actor)
{
struct room_data *room;
trig_data *t;
char buf[MAX_INPUT_LENGTH];
int ret_val;

log("1: %d", obj->item_number);
if (!actor || !SCRIPT_CHECK(&world[IN_ROOM(actor)], WTRIG_DROP))
return 1;

log("2: %d", obj->item_number);
room = &world[IN_ROOM(actor)];
log("3: %d", obj->item_number);
for (t = TRIGGERS(SCRIPT(room)); t; t = t->next)
if (TRIGGER_CHECK(t, WTRIG_DROP) &&
(rand_number(1, 100) <= GET_TRIG_NARG(t))) {
log("4: %d", obj->item_number);
ADD_UID_VAR(buf, t, char_script_id(actor), "actor", 0);
log("5: %d", obj->item_number);
ADD_UID_VAR(buf, t, obj_script_id(obj), "object", 0);
log("6: %d", obj->item_number);
ret_val = script_driver(&room, t, WLD_TRIGGER, TRIG_NEW);
log("7: %d", obj->item_number);
if (obj->carried_by != actor)
return 0;
else
return ret_val;
}

return 1;
}


Produced this:

Feb 28 15:15:06 2020 :: 1: 65535
Feb 28 15:15:06 2020 :: 2: 65535
Feb 28 15:15:06 2020 :: 3: 65535
Feb 28 15:15:06 2020 :: 4: 65535
Feb 28 15:15:06 2020 :: 5: 65535
Feb 28 15:15:06 2020 :: 6: 65535
Feb 28 15:15:06 2020 :: 7: 46528


So, after going into script_driver the trouble start!

I'll check more later.
Bob

Please Log in or Create an account to join the conversation.

More
28 Feb 2020 22:07 #8595 by Castillo
Replied by Castillo on topic TBA-2020 Bug Fix Request
Well.

Feb 28 16:53:40 2020 :: 1: 65535
Feb 28 16:53:40 2020 :: 2: 65535
Feb 28 16:53:40 2020 :: 3: 65535
Feb 28 16:53:40 2020 :: 4: 65535
Feb 28 16:53:40 2020 :: 5: 65535
Feb 28 16:53:40 2020 :: 6: 65535
Feb 28 16:53:40 2020 :: extract_obj: 65535
Feb 28 16:53:40 2020 :: 7: 48928

I added log to extract_obj function, and it show after #6 and before exist #7 the object get extracted. This is done by script_driver(&room, t, WLD_TRIGGER, TRIG_NEW);

So,

} else {
char buf[MAX_STRING_LENGTH];

if (!drop_wtrigger(obj, ch)) {
extract_obj(obj);
return;
}


This is a double extract_obj(obj) call, because drop_wtrigger extract obj, and also go into the scope where it will extract_obj(obj) again.

Bob

Please Log in or Create an account to join the conversation.

More
28 Feb 2020 22:41 #8596 by thomas
Replied by thomas on topic TBA-2020 Bug Fix Request
Nicely spotted. It's not easy to fix, though. I'll see if I can't get time to look at it tomorrow night

Please Log in or Create an account to join the conversation.

More
29 Feb 2020 23:36 #8597 by thomas
Replied by thomas on topic TBA-2020 Bug Fix Request
While I'm brainstorming the solution, I've opened a github issue

github.com/tbamud/tbamud/issues/83

Please Log in or Create an account to join the conversation.

More
29 Feb 2020 23:54 #8598 by Castillo
Replied by Castillo on topic TBA-2020 Bug Fix Request
Drop object works fine, and when you compare both code, and do some tests:
static int perform_drop and static void perform_drop_gold

I think it become obvious

static int perform_drop(struct char_data *ch, struct obj_data *obj,
byte mode, const char *sname, room_rnum RDR)
{
char buf[MAX_STRING_LENGTH];
int value;

if (!drop_otrigger(obj, ch))
return 0;

if ((mode == SCMD_DROP) && !drop_wtrigger(obj, ch))
return 0;


That perform_drop_gold should do the same.

static void perform_drop_gold(struct char_data *ch, int amount, byte mode, room_rnum RDR)
{
struct obj_data *obj;

if (amount <= 0)
send_to_char(ch, "Heh heh heh.. we are jolly funny today, eh?\r\n");
else if (GET_GOLD(ch) < amount)
send_to_char(ch, "You don't have that many coins!\r\n");
else {
if (mode != SCMD_JUNK) {
WAIT_STATE(ch, PULSE_VIOLENCE); /* to prevent coin-bombing */
obj = create_money(amount);
if (mode == SCMD_DONATE) {
send_to_char(ch, "You throw some gold into the air where it disappears in a puff of smoke!\r\n");
act("$n throws some gold into the air where it disappears in a puff of smoke!",
FALSE, ch, 0, 0, TO_ROOM);
obj_to_room(obj, RDR);
act("$p suddenly appears in a puff of orange smoke!", 0, 0, obj, 0, TO_ROOM);
} else {
char buf[MAX_STRING_LENGTH];

if (!drop_wtrigger(obj, ch)) {
extract_obj(obj);
return;
}


When i drop a bread:

Feb 29 18:39:42 2020 :: 1: 9
Feb 29 18:39:42 2020 :: 2: 9
Feb 29 18:39:42 2020 :: 3: 9
Feb 29 18:39:42 2020 :: 4: 9
Feb 29 18:39:42 2020 :: 5: 9
Feb 29 18:39:42 2020 :: 6: 9
Feb 29 18:39:42 2020 :: extract_obj: 9
Feb 29 18:39:42 2020 :: 7: 39800


The bread also get extracted by !drop_wtrigger(obj, ch) and it also return 0. Without extracting again.

if ((mode == SCMD_DROP) && !drop_wtrigger(obj, ch))
return 0;


Shouldn't perform_drop_gold do the same?

if (!drop_wtrigger(obj, ch)) {
// extract_obj(obj);
return; // just return
}


tested:

drop 1 coin
drop 100 coins

drop_wtrigger always succeed to extract the obj.

Bob

Please Log in or Create an account to join the conversation.

Time to create page: 0.293 seconds