package main import ( "fmt" "strconv" "strings" "gopkg.in/ini.v1" ) type RoomIni struct { night int room int name string credits string links []string size float64 speed float64 fov float64 textureRepeat float64 roomHeight float64 layerFrames int fogColor int fogEnd float64 miniSpeed float64 } func (r *RoomIni) ToIni() string { f := func(n float64) string { return strconv.FormatFloat(n, 'f', -1, 64) } return fmt.Sprintf(`[NIGHT_%d_ROOM_%d] size=%s speed=%s FOV=%s Texture_Repeat=%s Room_Height=%s Layer_Frames=%d Fog_Color=%d Fog_End=%s Mini_speed=%s `, r.night, r.room, f(r.size), f(r.speed), f(r.fov), f(r.textureRepeat), f(r.roomHeight), r.layerFrames, r.fogColor, f(r.fogEnd), f(r.miniSpeed), ) } 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, room: -1, size: 1, speed: 1, fov: 55, textureRepeat: 3, roomHeight: 350, layerFrames: 1, fogColor: 0, fogEnd: -1, miniSpeed: 1, } } func ReadIni(path string) (RoomIni, error) { cfg, err := ini.InsensitiveLoad(path) if err != nil { return RoomIni{}, err } roomIni, err := loadIni(cfg) if err != nil { return RoomIni{}, fmt.Errorf("ERROR: error loading ini from %s: %+v", path, err) } return roomIni, nil } func loadIni(cfg *ini.File) (RoomIni, error) { roomini := RoomIni{} 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 err } else { roomini.room = val } if roomini.night > 0 && roomini.room < 1 { return fmt.Errorf("night is set but room is not set") } 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 err } else { roomini.size = val } if val, err := loadFloat(cfg, "speed", 1); err != nil { return err } else { roomini.speed = val } if val, err := loadFloat(cfg, "fov", 55); err != nil { return err } else { roomini.fov = val } if val, err := loadFloat(cfg, "texture_repeat", 3); err != nil { return err } else { roomini.textureRepeat = val } if val, err := loadFloat(cfg, "room_height", 350); err != nil { return err } else { roomini.roomHeight = val } if val, err := loadInt(cfg, "layer_frames", 1); err != nil { return err } else { roomini.layerFrames = val } if val, err := loadInt(cfg, "fog_color", 0); err != nil { return err } else { roomini.fogColor = val } if val, err := loadFloat(cfg, "fog_end", -1); err != nil { return err } else { roomini.fogEnd = val } if val, err := loadFloat(cfg, "mini_speed", 1); err != nil { return err } else { roomini.miniSpeed = val } return nil } func loadInt(cfg *ini.File, key string, def int) (int, error) { sections := cfg.Sections() for _, sec := range sections { val, err := sec.GetKey(key) if err != nil { continue } valint, err := val.Int() if err != nil { return def, err } return valint, nil } return def, nil } func loadFloat(cfg *ini.File, key string, def float64) (float64, error) { sections := cfg.Sections() for _, sec := range sections { val, err := sec.GetKey(key) if err != nil { continue } valfloat, err := val.Float64() if err != nil { return def, err } return valfloat, nil } 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 }