Permalink
Browse files

Fix room deletion bug, add rooms table printing cmd.

If the room being deleted wasn't first in the list, the previous rooms
in the list occupying that position in the rooms table were no longer
being referenced (only rooms past the deleted one). Specifically,
deleting rented rooms after a recreate dropped references to the other
room occupying that position in the table, which due to the order of
room loading tended to be around the kc1-kd4 area. This case is now
handled correctly.

Added an admin "show roomtable" command which prints the rooms table to
admin log, and allowed this issue to be debugged.
  • Loading branch information...
skittles1 committed Jan 12, 2016
1 parent 2ee195b commit 35db18ae00c7713da4d6bb4564454eab93c68bce
Showing with 77 additions and 14 deletions.
  1. +9 −1 blakserv/adminfn.c
  2. +67 −13 blakserv/roomdata.c
  3. +1 −0 blakserv/roomdata.h
View
@@ -98,7 +98,8 @@ void AdminShowMemory(int session_id,admin_parm_type parms[],
void AdminShowCalled(int session_id,admin_parm_type parms[],
int num_blak_parm,parm_node blak_parm[]);
void AdminShowCalledClass(class_node *c);
-
+void AdminShowRoomTable(int session_id, admin_parm_type parms[],
+ int num_blak_parm, parm_node blak_parm[]);
void AdminShowBlockers(int session_id,admin_parm_type parms[],
int num_blak_parm,parm_node blak_parm[]);
void AdminShowObject(int session_id,admin_parm_type parms[],
@@ -343,6 +344,7 @@ admin_table_type admin_show_table[] =
{ AdminShowProtocol, {N}, F, A|M, NULL, 0, "protocol", "Show protocol message counts" },
{ AdminShowReferences, {S,S,N}, F, A|M, NULL, 0, "references", "Show what objects or lists reference a particular data value" },
{ AdminShowResource, {S,N}, F, A|M, NULL, 0, "resource", "Show a resource by resource name" },
+ { AdminShowRoomTable, {N}, F, A|M, NULL, 0, "roomtable", "Show the rooms table" },
{ AdminShowStatus, {N}, F, A|M, NULL, 0, "status", "Show system status" },
{ AdminShowString, {I,N}, F, A|M, NULL, 0, "string", "Show one string by string id" },
{ AdminShowSuspended, {N}, F, A|M, NULL, 0, "suspended", "Show all suspended accounts" },
@@ -1500,6 +1502,12 @@ void AdminShowCalledClass(class_node *c)
}
}
+void AdminShowRoomTable(int session_id, admin_parm_type parms[],
+ int num_blak_parm, parm_node blak_parm[])
+{
+ PrintRoomTable();
+}
+
void AdminShowBlockers(int session_id,admin_parm_type parms[],
int num_blak_parm,parm_node blak_parm[])
{
View
@@ -119,24 +119,54 @@ void UnloadRoom(room_node *r)
return;
}
+ if (!rooms)
+ {
+ bprintf("UnloadRoomData couldn't get room table!");
+
+ return;
+ }
+
room_hash = r->data.roomdata_id % INIT_ROOMTABLE_SIZE;
- if (rooms)
+
+ // Get rooms occupying this position in rooms table.
+ room = rooms[room_hash];
+
+ if (!room)
{
- // Free the room.
- room = rooms[room_hash];
- while (room)
+ bprintf("UnloadRoomData got NULL data for room %i at room table entry %i!",
+ r->data.roomdata_id, room_hash);
+
+ return;
+ }
+
+ // If the room we want to free is first, set rooms at this position
+ // to the next room in this list.
+ if (room->data.roomdata_id == r->data.roomdata_id)
+ {
+ rooms[room_hash] = room->next;
+ BSPFreeRoom(&room->data);
+ FreeMemory(MALLOC_ID_ROOM, room, sizeof(room_node));
+ room = NULL;
+
+ return;
+ }
+
+ // Otherwise check the next room in list.
+ while (room->next)
+ {
+ if (room->next->data.roomdata_id == r->data.roomdata_id)
{
+ // Matched, set temp to the room to be freed.
temp = room->next;
- if (room->data.roomdata_id == r->data.roomdata_id)
- {
- BSPFreeRoom(&room->data);
- FreeMemory(MALLOC_ID_ROOM, room, sizeof(room_node));
- room = NULL;
- rooms[room_hash] = temp;
- return;
- }
- room = room->next;
+ // Set current room's next pointer to the next pointer
+ // of the room we're freeing.
+ room->next = room->next->next;
+ BSPFreeRoom(&temp->data);
+ FreeMemory(MALLOC_ID_ROOM, temp, sizeof(room_node));
+
+ return;
}
+ room = room->next;
}
// If we get to this point, we didn't find the room we wanted to unload.
@@ -163,6 +193,30 @@ room_node * GetRoomDataByID(int id)
return NULL;
}
+// Prints the rooms in rooms table to admin log.
+void PrintRoomTable()
+{
+ room_node *room;
+
+ if (!rooms)
+ {
+ aprintf("No rooms table loaded.\n");
+
+ return;
+ }
+
+ for (int i = 0; i < INIT_ROOMTABLE_SIZE; i++)
+ {
+ room = rooms[i];
+ while (room)
+ {
+ aprintf("Room at position %i, roomdata %i, resource %s\n",
+ i, room->data.roomdata_id, GetResourceStrByLanguageID(room->data.resource_id,0));
+ room = room->next;
+ }
+ }
+}
+
void ForEachRoom(void(*callback_func)(room_node *r))
{
room_node *node;
View
@@ -27,6 +27,7 @@ void ResetRooms(void);
int LoadRoom(int resource_id);
void UnloadRoom(room_node *r);
room_node* GetRoomDataByID(int id);
+void PrintRoomTable();
void ForEachRoom(void(*callback_func)(room_node *r));
#endif

0 comments on commit 35db18a

Please sign in to comment.