From a1b6613c6c6a2f8d6e1ecd47e766bd40f92ac295 Mon Sep 17 00:00:00 2001 From: historia <[not public]> Date: Sun, 28 Jun 2026 02:40:30 -0400 Subject: feat: admin accounts, god mode, OLC commands like dig/room, 'inline' objects changed to 'local' objects --- internal/game/cmd_swapid.go | 126 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 126 insertions(+) create mode 100644 internal/game/cmd_swapid.go (limited to 'internal/game/cmd_swapid.go') diff --git a/internal/game/cmd_swapid.go b/internal/game/cmd_swapid.go new file mode 100644 index 0000000..6ee1118 --- /dev/null +++ b/internal/game/cmd_swapid.go @@ -0,0 +1,126 @@ +package game + +import ( + "fmt" + "os" + "path/filepath" + "regexp" + "strconv" + + "thehouseoficarus/internal/net" +) + +func (g *Game) executeSwapID(sess *net.Session, args []string, rawInput string) { + if !g.checkAdmin(sess) { + sess.WriteLine("Unknown command.") + return + } + p := sess.Player + if p == nil { + return + } + + var id1, id2 int + switch len(args) { + case 1: + id1 = p.RoomID + var err error + id2, err = strconv.Atoi(args[0]) + if err != nil { + sess.WriteLine("Invalid room ID.") + return + } + case 2: + var err error + id1, err = strconv.Atoi(args[0]) + if err != nil { + sess.WriteLine("Invalid room ID.") + return + } + id2, err = strconv.Atoi(args[1]) + if err != nil { + sess.WriteLine("Invalid room ID.") + return + } + default: + sess.WriteLine("Usage: swapid or swapid ") + return + } + + if id1 == id2 { + sess.WriteLine("Cannot swap a room with itself.") + return + } + + path1, ok1 := g.World.GetRoomPath(id1) + path2, ok2 := g.World.GetRoomPath(id2) + if !ok1 { + sess.WriteLine(fmt.Sprintf("Room %d not found.", id1)) + return + } + if !ok2 { + sess.WriteLine(fmt.Sprintf("Room %d not found.", id2)) + return + } + + roomsDir := filepath.Join(g.DataDir, "rooms") + re1 := regexp.MustCompile(fmt.Sprintf(`\b%d\b`, id1)) + re2 := regexp.MustCompile(fmt.Sprintf(`\b%d\b`, id2)) + placeholder := fmt.Sprintf("__SWAPID_TEMP_%d__", id1^id2) + + var modified []string + err := filepath.WalkDir(roomsDir, func(roomPath string, d os.DirEntry, err error) error { + if err != nil || d.IsDir() || filepath.Ext(roomPath) != ".yaml" { + return nil + } + data, rerr := os.ReadFile(roomPath) + if rerr != nil { + return nil + } + text := string(data) + if !re1.MatchString(text) && !re2.MatchString(text) { + return nil + } + text = re1.ReplaceAllString(text, placeholder) + text = re2.ReplaceAllString(text, strconv.Itoa(id1)) + text = regexp.MustCompile(placeholder).ReplaceAllString(text, strconv.Itoa(id2)) + if werr := os.WriteFile(roomPath, []byte(text), 0644); werr != nil { + return werr + } + modified = append(modified, roomPath) + return nil + }) + if err != nil { + sess.WriteLine(fmt.Sprintf("Error updating room files: %v", err)) + return + } + + tempPath := path1 + ".swapid-tmp" + if rerr := os.Rename(path1, tempPath); rerr != nil { + sess.WriteLine(fmt.Sprintf("Error renaming room %d: %v", id1, rerr)) + return + } + if rerr := os.Rename(path2, path1); rerr != nil { + os.Rename(tempPath, path1) + sess.WriteLine(fmt.Sprintf("Error renaming room %d: %v", id2, rerr)) + return + } + if rerr := os.Rename(tempPath, path2); rerr != nil { + os.Rename(path2, path1) + os.Rename(tempPath, path1) + sess.WriteLine(fmt.Sprintf("Error finishing rename: %v", rerr)) + return + } + + g.World.RebuildRoomIndex(g.DataDir) + g.World.LoadRoom(id1) + g.World.LoadRoom(id2) + + if p.RoomID == id1 { + p.RoomID = id2 + } else if p.RoomID == id2 { + p.RoomID = id1 + } + + sess.WriteLine(fmt.Sprintf("Swapped room IDs %d and %d (%d files updated).", id1, id2, len(modified))) +} -- cgit v1.2.3