mirror of
https://github.com/tbamud/tbamud.git
synced 2026-03-30 17:07:19 +02:00
Only save room contents if something changed
This commit is contained in:
parent
9d54d7d1a6
commit
7fafc7f6ea
5 changed files with 74 additions and 9 deletions
|
|
@ -137,12 +137,12 @@ ACMD(do_save)
|
|||
{
|
||||
char a1[MAX_INPUT_LENGTH], a2[MAX_INPUT_LENGTH];
|
||||
|
||||
/* Parse up to two words so we can accept "save room" or "room save". */
|
||||
/* Accept both orders: "save room" or "room save" */
|
||||
two_arguments(argument, a1, a2);
|
||||
|
||||
/* Does either token equal "room"? (order-agnostic) */
|
||||
const bool wants_room = ((*a1 && !str_cmp(a1, "room")) ||
|
||||
(*a2 && !str_cmp(a2, "room")));
|
||||
/* order-agnostic check */
|
||||
int wants_room = ((*a1 && !str_cmp(a1, "room")) ||
|
||||
(*a2 && !str_cmp(a2, "room")));
|
||||
|
||||
if (wants_room) {
|
||||
room_rnum rnum = IN_ROOM(ch);
|
||||
|
|
@ -163,8 +163,20 @@ ACMD(do_save)
|
|||
/* Room is flagged SAVE → persist its contents */
|
||||
if (RoomSave_now(rnum)) {
|
||||
send_to_char(ch, "Saving room.\r\n");
|
||||
mudlog(NRM, LVL_IMMORT, FALSE,
|
||||
"RoomSave: manual save of room %d by %s.",
|
||||
world[rnum].number, GET_NAME(ch));
|
||||
/* If you added a dirty-save API and want to clear the bit on manual save,
|
||||
you can optionally call it here (guard with a macro if desired):
|
||||
#ifdef ROOMSAVE_HAVE_DIRTY_API
|
||||
RoomSave_clear_dirty(rnum);
|
||||
#endif
|
||||
*/
|
||||
} else {
|
||||
send_to_char(ch, "Room save failed; see logs.\r\n");
|
||||
mudlog(NRM, LVL_IMMORT, TRUE,
|
||||
"SYSERR: RoomSave: manual save FAILED for room %d by %s.",
|
||||
world[rnum].number, GET_NAME(ch));
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
|
|
|||
3
src/db.c
3
src/db.c
|
|
@ -784,7 +784,8 @@ void boot_db(void)
|
|||
}
|
||||
|
||||
/* Restore persistent room contents last so they take precedence. */
|
||||
log("Loading Room Contents.");
|
||||
log("Loading Room Contents.");
|
||||
RoomSave_init_dirty();
|
||||
RoomSave_boot();
|
||||
|
||||
log("Cleaning up last log.");
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@
|
|||
#include "fight.h"
|
||||
#include "quest.h"
|
||||
#include "mud_event.h"
|
||||
#include "roomsave.h"
|
||||
|
||||
/* local file scope variables */
|
||||
static int extractions_pending = 0;
|
||||
|
|
@ -419,11 +420,15 @@ void char_to_room(struct char_data *ch, room_rnum room)
|
|||
/* Give an object to a char. */
|
||||
void obj_to_char(struct obj_data *object, struct char_data *ch)
|
||||
{
|
||||
room_rnum __rs_room = RoomSave_room_of_obj(object); /* where the item currently lives */
|
||||
|
||||
if (object && ch) {
|
||||
object->next_content = ch->carrying;
|
||||
ch->carrying = object;
|
||||
object->carried_by = ch;
|
||||
IN_ROOM(object) = NOWHERE;
|
||||
if (__rs_room != NOWHERE)
|
||||
RoomSave_mark_dirty_room(__rs_room);
|
||||
IS_CARRYING_W(ch) += GET_OBJ_WEIGHT(object);
|
||||
IS_CARRYING_N(ch)++;
|
||||
|
||||
|
|
@ -440,6 +445,7 @@ void obj_to_char(struct obj_data *object, struct char_data *ch)
|
|||
void obj_from_char(struct obj_data *object)
|
||||
{
|
||||
struct obj_data *temp;
|
||||
room_rnum __rs_room = IN_ROOM(object->carried_by);
|
||||
|
||||
if (object == NULL) {
|
||||
log("SYSERR: NULL object passed to obj_from_char.");
|
||||
|
|
@ -455,6 +461,8 @@ void obj_from_char(struct obj_data *object)
|
|||
IS_CARRYING_N(object->carried_by)--;
|
||||
object->carried_by = NULL;
|
||||
object->next_content = NULL;
|
||||
if (__rs_room != NOWHERE)
|
||||
RoomSave_mark_dirty_room(__rs_room);
|
||||
}
|
||||
|
||||
/* Return the effect of a piece of armor in position eq_pos */
|
||||
|
|
@ -689,6 +697,8 @@ void obj_to_room(struct obj_data *object, room_rnum room)
|
|||
object->carried_by = NULL;
|
||||
if (ROOM_FLAGGED(room, ROOM_HOUSE))
|
||||
SET_BIT_AR(ROOM_FLAGS(room), ROOM_HOUSE_CRASH);
|
||||
/* RoomSave: this room’s contents changed */
|
||||
RoomSave_mark_dirty_room(room);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -697,6 +707,7 @@ void obj_from_room(struct obj_data *object)
|
|||
{
|
||||
struct obj_data *temp;
|
||||
struct char_data *t, *tempch;
|
||||
room_rnum __rs_was_room = IN_ROOM(object);
|
||||
|
||||
if (!object || IN_ROOM(object) == NOWHERE) {
|
||||
log("SYSERR: NULL object (%p) or obj not in a room (%d) passed to obj_from_room",
|
||||
|
|
@ -719,6 +730,8 @@ void obj_from_room(struct obj_data *object)
|
|||
SET_BIT_AR(ROOM_FLAGS(IN_ROOM(object)), ROOM_HOUSE_CRASH);
|
||||
IN_ROOM(object) = NOWHERE;
|
||||
object->next_content = NULL;
|
||||
/* RoomSave: room lost an object */
|
||||
RoomSave_mark_dirty_room(__rs_was_room);
|
||||
}
|
||||
|
||||
/* put an object in an object (quaint) */
|
||||
|
|
@ -735,6 +748,8 @@ void obj_to_obj(struct obj_data *obj, struct obj_data *obj_to)
|
|||
obj->next_content = obj_to->contains;
|
||||
obj_to->contains = obj;
|
||||
obj->in_obj = obj_to;
|
||||
/* RoomSave: container changed; mark the room the container ultimately lives in */
|
||||
RoomSave_mark_dirty_room(RoomSave_room_of_obj(obj_to));
|
||||
|
||||
/* Add weight to container, unless unlimited. */
|
||||
if (GET_OBJ_VAL(obj->in_obj, 0) > 0) {
|
||||
|
|
@ -752,6 +767,7 @@ void obj_to_obj(struct obj_data *obj, struct obj_data *obj_to)
|
|||
void obj_from_obj(struct obj_data *obj)
|
||||
{
|
||||
struct obj_data *temp, *obj_from;
|
||||
struct obj_data *__rs_container = obj->in_obj; /* capture before unlink */
|
||||
|
||||
if (obj->in_obj == NULL) {
|
||||
log("SYSERR: (%s): trying to illegally extract obj from obj.", __FILE__);
|
||||
|
|
@ -772,6 +788,8 @@ void obj_from_obj(struct obj_data *obj)
|
|||
}
|
||||
obj->in_obj = NULL;
|
||||
obj->next_content = NULL;
|
||||
/* RoomSave: container changed; mark the room the container ultimately lives in */
|
||||
RoomSave_mark_dirty_room(RoomSave_room_of_obj(__rs_container));
|
||||
}
|
||||
|
||||
/* Set all carried_by to point to new owner */
|
||||
|
|
@ -789,6 +807,7 @@ void extract_obj(struct obj_data *obj)
|
|||
{
|
||||
struct char_data *ch, *next = NULL;
|
||||
struct obj_data *temp;
|
||||
room_rnum __rs_room = RoomSave_room_of_obj(obj);
|
||||
|
||||
if (obj->worn_by != NULL)
|
||||
if (unequip_char(obj->worn_by, obj->worn_on) != obj)
|
||||
|
|
@ -837,6 +856,9 @@ void extract_obj(struct obj_data *obj)
|
|||
if (GET_OBJ_RNUM(obj) == NOTHING || obj->proto_script != obj_proto[GET_OBJ_RNUM(obj)].proto_script)
|
||||
free_proto_script(obj, OBJ_TRIGGER);
|
||||
|
||||
if (__rs_room != NOWHERE)
|
||||
RoomSave_mark_dirty_room(__rs_room);
|
||||
|
||||
free_obj(obj);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@
|
|||
#include "conf.h"
|
||||
#include "sysdep.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <dirent.h>
|
||||
#include <errno.h>
|
||||
#include <limits.h>
|
||||
|
|
@ -36,6 +37,28 @@
|
|||
#define ROOMSAVE_EXT ".rsv"
|
||||
#endif
|
||||
|
||||
static unsigned char *roomsave_dirty = NULL;
|
||||
|
||||
void RoomSave_init_dirty(void) {
|
||||
free(roomsave_dirty);
|
||||
roomsave_dirty = calloc((size_t)top_of_world + 1, 1);
|
||||
}
|
||||
|
||||
void RoomSave_mark_dirty_room(room_rnum rnum) {
|
||||
if (!roomsave_dirty) return;
|
||||
if (rnum != NOWHERE && rnum >= 0 && rnum <= top_of_world)
|
||||
roomsave_dirty[rnum] = 1;
|
||||
}
|
||||
|
||||
/* Where does an object “live” (topmost location -> room)? */
|
||||
room_rnum RoomSave_room_of_obj(struct obj_data *o) {
|
||||
if (!o) return NOWHERE;
|
||||
while (o->in_obj) o = o->in_obj;
|
||||
if (o->carried_by) return IN_ROOM(o->carried_by);
|
||||
if (o->worn_by) return IN_ROOM(o->worn_by);
|
||||
return o->in_room;
|
||||
}
|
||||
|
||||
/* --- helper: read a list of objects until '.' or 'E' and return the head --- */
|
||||
static struct obj_data *roomsave_read_list(FILE *fl) {
|
||||
char line[256];
|
||||
|
|
@ -397,8 +420,9 @@ void RoomSave_boot(void) {
|
|||
/* Save all rooms flagged ROOM_SAVE. Called from point_update() on a cadence. */
|
||||
void RoomSave_autosave_tick(void) {
|
||||
for (room_rnum rnum = 0; rnum <= top_of_world; rnum++) {
|
||||
if (ROOM_FLAGGED(rnum, ROOM_SAVE)) {
|
||||
RoomSave_now(rnum);
|
||||
}
|
||||
if (!ROOM_FLAGGED(rnum, ROOM_SAVE)) continue;
|
||||
if (!roomsave_dirty || !roomsave_dirty[rnum]) continue;
|
||||
if (RoomSave_now(rnum))
|
||||
roomsave_dirty[rnum] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -25,4 +25,10 @@ int RoomSave_now(room_rnum rnum);
|
|||
/* Autosave pass for all rooms flagged ROOM_SAVE. */
|
||||
void RoomSave_autosave_tick(void);
|
||||
|
||||
/* Only save rooms when modified */
|
||||
void RoomSave_init_dirty(void);
|
||||
void RoomSave_mark_dirty_room(room_rnum rnum);
|
||||
/* For container edits: find the room an object ultimately lives in */
|
||||
room_rnum RoomSave_room_of_obj(struct obj_data *obj);
|
||||
|
||||
#endif /* ROOMSAVE_H_ */
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue