package admin import ( "os" "path/filepath" "strconv" ) func nextRoomIDInDir(dataDir string, fromRoomID int) (int, string, error) { base := filepath.Join(dataDir, "rooms") subdir, err := findRoomSubdir(base, fromRoomID) if err != nil { subdir = base } used := map[int]bool{} scanDir(subdir, used) if len(used) == 0 { return 1, subdir, nil } minID := 1<<31 - 1 for id := range used { if id < minID { minID = id } } id := minID for used[id] { id++ } return id, subdir, nil } func findRoomSubdir(base string, roomID int) (string, error) { fileName := strconv.Itoa(roomID) + ".yaml" var found string filepath.WalkDir(base, func(path string, d os.DirEntry, err error) error { if err != nil || found != "" { return nil } if !d.IsDir() && d.Name() == fileName { found = filepath.Dir(path) } return nil }) if found == "" { return "", os.ErrNotExist } return found, nil } func scanDir(dir string, used map[int]bool) { entries, err := os.ReadDir(dir) if err != nil { return } for _, e := range entries { if !e.IsDir() && filepath.Ext(e.Name()) == ".yaml" { idStr := e.Name()[:len(e.Name())-5] if id, err := strconv.Atoi(idStr); err == nil && id > 0 { used[id] = true } } } }