aboutsummaryrefslogtreecommitdiff
path: root/internal/game/exit_migrate.go
diff options
context:
space:
mode:
Diffstat (limited to 'internal/game/exit_migrate.go')
-rw-r--r--internal/game/exit_migrate.go39
1 files changed, 35 insertions, 4 deletions
diff --git a/internal/game/exit_migrate.go b/internal/game/exit_migrate.go
index ff905f6..db70c8d 100644
--- a/internal/game/exit_migrate.go
+++ b/internal/game/exit_migrate.go
@@ -112,11 +112,11 @@ func rekeyIntMap[V any](m map[int]V, idMap map[int]int) bool {
return true
}
-// RewriteRoomIDs is the shared entry point called by every room-ID change path
-// (the swapid command and the admin web GUI rename) to migrate room-ID-embedded
+// RewriteRoomIDs is the shared entry point called by every room-ID change
+// path (the swapid command and the admin web GUI rename) to migrate room-ID-embedded
// state across all characters. Online players are updated in memory (and
-// re-saved); offline characters are loaded, rewritten, and saved. It follows
-// the same cross-goroutine mutation precedent as cmd_undig/cmd_summon.
+// re-saved); offline characters are loaded, rewritten, and saved. Callers
+// must be on the owner goroutine (use MigrateRoomIDs from other goroutines).
func (g *Game) RewriteRoomIDs(idMap map[int]int) {
if len(idMap) == 0 {
return
@@ -150,3 +150,34 @@ func (g *Game) RewriteRoomIDs(idMap map[int]int) {
}
}
}
+
+// MigrateRoomIDs is the complete room-ID migration entry point for other
+// goroutines (the admin API and swapid command): player state, Hub room
+// buckets, casino room keys, world room-keyed runtime state, and live mob
+// instances all move together under one owner task. This is what makes a
+// live rename leave NO gameplay or broadcast attached to the old location.
+func (g *Game) MigrateRoomIDs(idMap map[int]int) {
+ if len(idMap) == 0 {
+ return
+ }
+ g.RunOnOwner(func() {
+ g.migrateRoomIDsLocked(idMap)
+ })
+}
+
+// migrateRoomIDsLocked performs the full runtime migration; caller must
+// already be on the owner goroutine.
+func (g *Game) migrateRoomIDsLocked(idMap map[int]int) {
+ if g.Hub != nil {
+ g.Hub.RekeyRooms(idMap)
+ }
+ if g.Casino != nil {
+ g.Casino.RekeyRooms(idMap)
+ }
+ g.World.RekeyRooms(idMap)
+ g.MobStore.RekeyRooms(idMap)
+ // The file paths changed under the world: rebuild its room index so
+ // lookups agree with the post-migration layout.
+ g.World.RebuildRoomIndex(g.DataDir)
+ g.RewriteRoomIDs(idMap)
+}