From 4619fef9a35bf05138f18859bbcec5df7a8dbde0 Mon Sep 17 00:00:00 2001 From: zomo Date: Wed, 15 Apr 2026 20:45:21 -0500 Subject: [PATCH] FEAT: room credits --- ini.go | 105 ++++++++++++++++++++++++++++++++++++++++++++---------- out.go | 77 ++++++++++++++++++++++++++++++++++----- readme.md | 2 +- 3 files changed, 157 insertions(+), 27 deletions(-) diff --git a/ini.go b/ini.go index 5a973a4..62a77f4 100644 --- a/ini.go +++ b/ini.go @@ -3,6 +3,7 @@ package main import ( "fmt" "strconv" + "strings" "gopkg.in/ini.v1" ) @@ -11,6 +12,10 @@ type RoomIni struct { night int room int + name string + credits string + links []string + size float64 speed float64 fov float64 @@ -27,8 +32,7 @@ func (r *RoomIni) ToIni() string { return strconv.FormatFloat(n, 'f', -1, 64) } - return fmt.Sprintf(` -[NIGHT_%d_ROOM_%d] + return fmt.Sprintf(`[NIGHT_%d_ROOM_%d] size=%s speed=%s FOV=%s @@ -48,6 +52,29 @@ Mini_speed=%s ) } +func (r *RoomIni) ToCredits() string { + name := r.name + if name == "" { + name = "unnamed" + } + credits := r.credits + if credits == "" { + credits = "no name" + } + links := strings.Join(r.links, " | ") + if links == "" { + links = "no links" + } + + return fmt.Sprintf(`Night %d - Room %d: %s + By: %s + Links: %s +`, + r.night, r.room, name, + credits, links, + ) +} + func NewRoomIni() RoomIni { return RoomIni{ night: -1, @@ -82,80 +109,107 @@ func ReadIni(path string) (RoomIni, error) { func loadIni(cfg *ini.File) (RoomIni, error) { roomini := RoomIni{} - // meta config - if val, err := loadInt(cfg, "night", -1); err != nil { + if err := loadIniMeta(&roomini, cfg); err != nil { return RoomIni{}, err + } + + if err := loadIniCredits(&roomini, cfg); err != nil { + return RoomIni{}, err + } + + if err := loadIniRoom(&roomini, cfg); err != nil { + return RoomIni{}, err + } + + return roomini, nil +} + +func loadIniMeta(roomini *RoomIni, cfg *ini.File) error { + if val, err := loadInt(cfg, "night", -1); err != nil { + return err } else { roomini.night = val } if val, err := loadInt(cfg, "room", -1); err != nil { - return RoomIni{}, err + return err } else { roomini.room = val } if roomini.night > 0 && roomini.room < 1 { - return RoomIni{}, fmt.Errorf("night is set but room is not set") + return fmt.Errorf("night is set but room is not set") } - // room config + return nil +} + +func loadIniCredits(roomini *RoomIni, cfg *ini.File) error { + roomini.name = loadString(cfg, "name", "") + roomini.credits = loadString(cfg, "credits", "") + + linksstring := loadString(cfg, "links", "") + roomini.links = strings.Split(linksstring, " ") + + return nil +} + +func loadIniRoom(roomini *RoomIni, cfg *ini.File) error { if val, err := loadFloat(cfg, "size", 1); err != nil { - return RoomIni{}, err + return err } else { roomini.size = val } if val, err := loadFloat(cfg, "speed", 1); err != nil { - return RoomIni{}, err + return err } else { roomini.speed = val } if val, err := loadFloat(cfg, "fov", 55); err != nil { - return RoomIni{}, err + return err } else { roomini.fov = val } if val, err := loadFloat(cfg, "texture_repeat", 3); err != nil { - return RoomIni{}, err + return err } else { roomini.textureRepeat = val } if val, err := loadFloat(cfg, "room_height", 350); err != nil { - return RoomIni{}, err + return err } else { roomini.roomHeight = val } if val, err := loadInt(cfg, "layer_frames", 1); err != nil { - return RoomIni{}, err + return err } else { roomini.layerFrames = val } if val, err := loadInt(cfg, "fog_color", 0); err != nil { - return RoomIni{}, err + return err } else { roomini.fogColor = val } if val, err := loadFloat(cfg, "fog_end", -1); err != nil { - return RoomIni{}, err + return err } else { roomini.fogEnd = val } if val, err := loadFloat(cfg, "mini_speed", 1); err != nil { - return RoomIni{}, err + return err } else { roomini.miniSpeed = val } - return roomini, nil - + return nil } func loadInt(cfg *ini.File, key string, def int) (int, error) { @@ -197,3 +251,18 @@ func loadFloat(cfg *ini.File, key string, def float64) (float64, error) { return def, nil } + +func loadString(cfg *ini.File, key string, def string) string { + sections := cfg.Sections() + + for _, sec := range sections { + val, err := sec.GetKey(key) + if err != nil { + continue + } + + return val.String() + } + + return def +} diff --git a/out.go b/out.go index 9479e01..19113cd 100644 --- a/out.go +++ b/out.go @@ -28,17 +28,12 @@ func EmptyOut(outpath string) error { return err } - cfpath := path.Join(outpath, "CF.ini") - exists, err := Exists(cfpath) + err = emptyOutCredits(outpath) if err != nil { return err } - if !exists { - return nil - } - log.Printf("INFO: removing %s", cfpath) - return os.Remove(cfpath) + return emptyOutCF(outpath) } func emptyOutData(outpath string) error { @@ -77,7 +72,36 @@ func emptyOutData(outpath string) error { return nil } +func emptyOutCredits(outpath string) error { + cfpath := path.Join(outpath, "credits.txt") + exists, err := Exists(cfpath) + if err != nil { + return err + } + if !exists { + return nil + } + + log.Printf("INFO: removing %s", cfpath) + return os.Remove(cfpath) +} + +func emptyOutCF(outpath string) error { + cfpath := path.Join(outpath, "CF.ini") + exists, err := Exists(cfpath) + if err != nil { + return err + } + if !exists { + return nil + } + + log.Printf("INFO: removing %s", cfpath) + return os.Remove(cfpath) +} + func CopyOut(roomFolders []RoomFolder, outpath string, splash1len, splash2len int) error { + // base ini settings var inistr strings.Builder fmt.Fprintf(&inistr, `[SETTINGS] Sensitivity=6 @@ -85,18 +109,55 @@ Splash1len=%d Splash2len=%d `, splash1len, splash2len) + // loop through folders + roomcredits := []string{} for _, roomFolder := range roomFolders { err := copyFolder(roomFolder, outpath) if err != nil { return fmt.Errorf("error copying folder %s: %+v", roomFolder.Path, err) } inistr.WriteString(roomFolder.Cfg.ToIni()) + + roomFolder, err = checkCredits(roomFolder); + if err != nil { + return fmt.Errorf("error checking credits in folder %s: %+v", roomFolder.Path, err) + } + + roomcredits = append(roomcredits, roomFolder.Cfg.ToCredits()) } + // save ini file outini := filepath.Join(outpath, "CF.ini") log.Println("INFO:") log.Printf("INFO: Writing %s", outini) - return os.WriteFile(outini, []byte(inistr.String()), FILEPERM) + + if err := os.WriteFile(outini, []byte(inistr.String()), FILEPERM); err != nil { + return err + } + + // save credits file + creditsstring := strings.Join(roomcredits, "\n") + + outcredits := filepath.Join(outpath, "credits.txt") + log.Println("INFO:") + log.Printf("INFO: Writing %s", outcredits) + + return os.WriteFile(outcredits, []byte(creditsstring), FILEPERM) +} + +// doesn't error currently +func checkCredits(roomFolder RoomFolder) (RoomFolder, error) { + if roomFolder.Cfg.name == "" { + log.Println("WARNING: room config has no name, defaulting to folder name") + foldername := filepath.Base(roomFolder.Path) + roomFolder.Cfg.name = foldername + } + + if roomFolder.Cfg.credits == "" { + log.Println("WARNING: room config has no credits") + } + + return roomFolder, nil } func copyFolder(roomFolder RoomFolder, outpath string) error { diff --git a/readme.md b/readme.md index 91adce0..e56c191 100644 --- a/readme.md +++ b/readme.md @@ -94,7 +94,7 @@ rooms └───ROOM.ini ``` -The folder given by `outPath` can safely be the folder with BAP. This program will only touch the `DATA/NIGHT_*` folders and the `CF.ini` file in this folder. +The folder given by `outPath` can safely be the folder with BAP. This program will only touch the `DATA/NIGHT_*` folders, the `CF.ini` file, and a generated `credits.txt` in this folder. `roomPerNight` is used for rooms that do not have an assigned night and room number.