- Posts: 27
- Thank you received: 5
TBA-2020 Bug Fix Request
- Sapphire
- Topic Author
- Offline
- Junior Member
-
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.
- Castillo
- Offline
- Junior Member
-
- Posts: 39
- Thank you received: 3
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.
- Castillo
- Offline
- Junior Member
-
- Posts: 39
- Thank you received: 3
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.
- thomas
-
- Offline
- Administrator
-
- Posts: 765
- Thank you received: 145
Please Log in or Create an account to join the conversation.
- thomas
-
- Offline
- Administrator
-
- Posts: 765
- Thank you received: 145
Please Log in or Create an account to join the conversation.
- Castillo
- Offline
- Junior Member
-
- Posts: 39
- Thank you received: 3
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.
- thomas
-
- Offline
- Administrator
-
- Posts: 765
- Thank you received: 145
But we need this extract_obj to happen when the script returns 0. This means "disallow drop".
Consider what would happen if the script didn't purge the object - when dropping a coin, a "coin" object is created for this explicit purpose. If we don't extract it, it will become a memory leak.
Please Log in or Create an account to join the conversation.
- thomas
-
- Offline
- Administrator
-
- Posts: 765
- Thank you received: 145
Please Log in or Create an account to join the conversation.
- Castillo
- Offline
- Junior Member
-
- Posts: 39
- Thank you received: 3
I need to learn the scripts system. I got to understand that drop_wtrigger not onlyConsider what would happen if the script didn't purge the object - when dropping a coin, a "coin" object is created for this explicit purpose. If we don't extract it, it will become a memory leak.
process action "purge", but also "nodrop". That makes sens, the issue raise because the function is "multi purpose".
Cool,I think I have a solution - have a look at github: github.com/tbamud/tbamud/issues/83
Thanks, for your explanation.
Bob
Please Log in or Create an account to join the conversation.
- Sapphire
- Topic Author
- Offline
- Junior Member
-
- Posts: 27
- Thank you received: 5
Please Log in or Create an account to join the conversation.
- Sapphire
- Topic Author
- Offline
- Junior Member
-
- Posts: 27
- Thank you received: 5
Please Log in or Create an account to join the conversation.
- Castillo
- Offline
- Junior Member
-
- Posts: 39
- Thank you received: 3
With Cedit it's possible to stack them, but they never actually combine. It just seems like strange behavior considering a mort with 1,000,000 coins can produce 1,000,000 instances of gold piles if they are given enough time.
(35) One miserable gold coin is lying here.
Stacking look good, but if each coins is having an object structures it use memory. Reaching 100k, or 1M should takes lot of times, though.
What looks bad is when you get all:
18H 100M 84V (news) (motd) > get all
You get a gold coin.
There was 1 coin.
You get a gold coin.
There was 1 coin.
You get a gold coin.
There was 1 coin.
You get a gold coin.
There was 1 coin.
You get a gold coin.
There was 1 coin.
You get a gold coin.
There was 1 coin.
You get a gold coin.
There was 1 coin.
You get a gold coin.
There was 1 coin.
You get a gold coin.
There was 1 coin.
You get a gold coin.
There was 1 coin.
You get a gold coin.
There was 1 coin.
You get a gold coin.
There was 1 coin.
You get a gold coin.
There was 1 coin.
You get a gold coin.
There was 1 coin.
You get a gold coin.
There was 1 coin.
You get a gold coin.
There was 1 coin.
You get a gold coin.
There was 1 coin.
You get a gold coin.
There was 1 coin.
You get a gold coin.
There was 1 coin.
You get a gold coin.
There was 1 coin.
You get a gold coin.
There was 1 coin.
You get a gold coin.
There was 1 coin.
You get a gold coin.
There was 1 coin.
You get a gold coin.
There was 1 coin.
You get a gold coin.
There was 1 coin.
You get a gold coin.
There was 1 coin.
You get a gold coin.
There was 1 coin.
You get a gold coin.
There was 1 coin.
You get a gold coin.
There was 1 coin.
You get a gold coin.
There was 1 coin.
You get a gold coin.
There was 1 coin.
You get a gold coin.
There was 1 coin.
You get a gold coin.
There was 1 coin.
You get a gold coin.
There was 1 coin.
You get a gold coin.
There was 1 coin.
I don't know. Making a unique coins pile per room that combine shouldn't be too hard,
but is that what it should be?
Bob
Please Log in or Create an account to join the conversation.
- Castillo
- Offline
- Junior Member
-
- Posts: 39
- Thank you received: 3
It just to give an idea of what a unique stack of coins could be.
In fact, instead of a double extract_obj, and create_money. There should probably be
an update_room_coins function.
Also, if you cast 'invisibility' on the stack on ground, after that if you kill a mobile. Once the corpse decay. The money will sums up and become visible.
This is just a quick 11 lines example.
Bob
void obj_to_room(struct obj_data *object, room_rnum room)
{
+ struct obj_data *obj_room, *coins;
if (!object || room == NOWHERE || room > top_of_world)
log("SYSERR: Illegal value(s) passed to obj_to_room. (Room #%d/%d, obj %p)",
room, top_of_world, (void *)object);
else {
+ if (GET_OBJ_TYPE(object) == ITEM_MONEY) {
+ for (obj_room = world[room].contents; obj_room; obj_room = obj_room->next_content)
+ if (GET_OBJ_TYPE(obj_room) == ITEM_MONEY) {
+ coins = create_money(GET_OBJ_COST(obj_room) + GET_OBJ_COST(object));
+ extract_obj(obj_room);
+ extract_obj(object);
+ object = coins;
+ break;
+ }
+ }
object->next_content = world[room].contents;
world[room].contents = object;
IN_ROOM(object) = room;
object->carried_by = NULL;
if (ROOM_FLAGGED(room, ROOM_HOUSE))
SET_BIT_AR(ROOM_FLAGS(room), ROOM_HOUSE_CRASH);
}
Please Log in or Create an account to join the conversation.
- thomas
-
- Offline
- Administrator
-
- Posts: 765
- Thank you received: 145
Oh, you might want to follow the links to the pull request: github.com/tbamud/tbamud/pull/84/files?u...%93&diff=unified&w=1Sapphire wrote: I read through the github post you made, but I'm not sure where I should begin. Is this a definitive fix? It appears to be in a patch format at first, but then there are alternate solutions offered. Which would you say is the best path to a crash free mud?
Please Log in or Create an account to join the conversation.
- JTP
- Offline
- Platinum Member
-
- Posts: 937
- Thank you received: 17
Please Log in or Create an account to join the conversation.
- Sapphire
- Topic Author
- Offline
- Junior Member
-
- Posts: 27
- Thank you received: 5
Please Log in or Create an account to join the conversation.
- thomas
-
- Offline
- Administrator
-
- Posts: 765
- Thank you received: 145
Yes, but I'm not entirely satisfied with it.JTP wrote: Does the pull Update work ?
I think it will need a little more tweaking (for instance, at least one of the functions should be inline) before it can be merged.
Please Log in or Create an account to join the conversation.
- thomas
-
- Offline
- Administrator
-
- Posts: 765
- Thank you received: 145
Please Log in or Create an account to join the conversation.