diff options
| author | historia <[not public]> | 2026-06-28 02:40:30 -0400 |
|---|---|---|
| committer | historia <[not public]> | 2026-06-28 02:40:30 -0400 |
| commit | a1b6613c6c6a2f8d6e1ecd47e766bd40f92ac295 (patch) | |
| tree | 4ff8fefb029c93f2aa3db7361658b0b4e9805b66 /internal/game/cmd_swapid.go | |
| parent | 87dacfbb3dd16e7f55a82361eace98f9a39d75c8 (diff) | |
| download | thehouseoficarus-a1b6613c6c6a2f8d6e1ecd47e766bd40f92ac295.tar.gz | |
feat: admin accounts, god mode, OLC commands like dig/room, 'inline' objects changed to 'local' objects
Diffstat (limited to 'internal/game/cmd_swapid.go')
| -rw-r--r-- | internal/game/cmd_swapid.go | 126 |
1 files changed, 126 insertions, 0 deletions
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 <id> or swapid <id1> <id2>") + 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))) +} |
