aboutsummaryrefslogtreecommitdiff
path: root/internal/game/cmd_room_remove.go
diff options
context:
space:
mode:
authorhistoria <[not public]>2026-09-19 03:52:04 -0400
committerhistoria <[not public]>2026-09-19 03:52:04 -0400
commitbab5dd653039d026eb3d4e46da7aafef7137fe7c (patch)
tree9a1d8686dbcef8c145e3593511153768ae08962c /internal/game/cmd_room_remove.go
parent0e60567a7a0addb9421769ee7be7853bfa8788cb (diff)
downloadthehouseoficarus-bab5dd653039d026eb3d4e46da7aafef7137fe7c.tar.gz
fix: journal in-game room insert/remove, rewrite non-room room refs on rename/swap, seed admin grid from edited room, type action switches
Diffstat (limited to 'internal/game/cmd_room_remove.go')
-rw-r--r--internal/game/cmd_room_remove.go33
1 files changed, 23 insertions, 10 deletions
diff --git a/internal/game/cmd_room_remove.go b/internal/game/cmd_room_remove.go
index 361cc74..79b84d8 100644
--- a/internal/game/cmd_room_remove.go
+++ b/internal/game/cmd_room_remove.go
@@ -166,15 +166,21 @@ func (g *Game) roomRemove(sess *net.Session, args []string) {
return
}
- // Apply: rewire A's dir exit to C, preserving A's current dir-exit props.
+ // Stage A, C, and B's deletion into ONE journal transaction: the previous
+ // sequential writes could delete B after rewriting A but before C, leaving
+ // the map half-pulled with no recovery record. The transaction restores
+ // every before-image on any failure or crash.
+ txn := g.newTxn()
+
+ // Rewire A's dir exit to C, preserving A's current dir-exit props.
aRoom.Exits[dir] = world.RewirePreserving(aExit, cID)
aData, err := yaml.Marshal(aRoom)
if err != nil {
sess.WriteLine("Error updating current room YAML.")
return
}
- if err := writeRoomFile(aPath, aData); err != nil {
- sess.WriteLine("Error writing current room file.")
+ if err := txn.Replace(aPath, aData, 0644); err != nil {
+ sess.WriteLine(fmt.Sprintf("Error writing current room file: %v", err))
return
}
@@ -183,21 +189,28 @@ func (g *Game) roomRemove(sess *net.Session, args []string) {
cPath, cPathOK := g.World.GetRoomPath(cID)
if cPathOK {
cData, cerr := yaml.Marshal(cRoom)
- if cerr == nil {
- if werr := writeRoomFile(cPath, cData); werr != nil {
- sess.WriteLine(fmt.Sprintf("Warning: could not link the opposite exit in room %d: %v", cID, werr))
- }
+ if cerr != nil {
+ sess.WriteLine(fmt.Sprintf("Error updating room %d YAML: %v", cID, cerr))
+ return
+ }
+ if err := txn.Replace(cPath, cData, 0644); err != nil {
+ sess.WriteLine(fmt.Sprintf("Error linking the opposite exit in room %d: %v", cID, err))
+ return
}
}
- // Delete B's file.
+ // Delete B's file in the same transaction.
bPath, bPathOK := g.World.GetRoomPath(bID)
if !bPathOK {
sess.WriteLine(fmt.Sprintf("Room file for %d not found.", bID))
return
}
- if rerr := os.Remove(bPath); rerr != nil {
- sess.WriteLine(fmt.Sprintf("Error deleting room file: %v", rerr))
+ if err := txn.Delete(bPath); err != nil {
+ sess.WriteLine(fmt.Sprintf("Error deleting room file: %v", err))
+ return
+ }
+ if err := txn.Commit(); err != nil {
+ sess.WriteLine(fmt.Sprintf("Error committing room remove: %v", err))
return
}