package main import ( _ "embed" "fmt" "image" "image/color" "image/png" "log" "os" "path" "path/filepath" "slices" "strings" ) //go:embed silence.wav var SILENCE_WAV []byte const FILEPERM = 0644 // only deletes DATA/NIGHT_* folders and the CF.ini file // will not touch TITLE or any game files // so this can be ran safely in your game's directory func EmptyOut(outpath string) error { err := emptyOutData(outpath) if err != nil { return err } 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 emptyOutData(outpath string) error { datapath := path.Join(outpath, "DATA") exists, err := Exists(datapath) if err != nil { return err } if !exists { return nil } entries, err := os.ReadDir(datapath) if err != nil { return err } nightprefix := "NIGHT_" for _, entry := range entries { if entry.Name()[0] == '.' || !entry.IsDir() { continue } name := strings.ToUpper(entry.Name()) if len(name) >= len(nightprefix) && name[:len(nightprefix)] == nightprefix { nightpath := path.Join(datapath, entry.Name()) log.Printf("INFO: removing %s", nightpath) err = os.RemoveAll(nightpath) if err != nil { return err } } } return nil } func CopyOut(roomFolders []RoomFolder, outpath string, splash1len, splash2len int) error { inistr := fmt.Sprintf(`[SETTINGS] Sensitivity=6 Splash1len=%d Splash2len=%d `, splash1len, splash2len) for _, roomFolder := range roomFolders { err := copyFolder(roomFolder, outpath) if err != nil { return fmt.Errorf("error copying folder %s: %+v", roomFolder.Path, err) } inistr += roomFolder.Cfg.ToIni() } outini := filepath.Join(outpath, "CF.ini") log.Println("INFO:") log.Printf("INFO: Writing %s", outini) return os.WriteFile(outini, []byte(inistr), FILEPERM) } func copyFolder(roomFolder RoomFolder, outpath string) error { nightdir := fmt.Sprintf("NIGHT_%d", roomFolder.Cfg.night) roomdir := fmt.Sprintf("ROOM_%d", roomFolder.Cfg.room) roomoutpath := filepath.Join(outpath, "DATA", nightdir, roomdir) os.MkdirAll(roomoutpath, FILEPERM) log.Println("INFO:") log.Printf("INFO: Copying %s", roomFolder.Path) log.Printf("INFO: to %s", roomoutpath) if roomFolder.IsDefaultCfg { log.Println("INFO: room.ini was not found, using default settings") } entries, err := os.ReadDir(roomFolder.Path) if err != nil { return err } extraRequiredImages := gameExtraRequiredImages() extraRequiredAudio := gameExtraRequiredAudios() for _, entry := range entries { if entry.Name()[0] == '.' || entry.IsDir() { continue } name, ext := SplitExt(entry.Name()) if !isAcceptedFile(name, ext) { continue } if index := slices.Index(extraRequiredImages, name); index > -1 && isAcceptedImageExt(ext) { extraRequiredImages = append(extraRequiredImages[:index], extraRequiredImages[index+1:]...) } if index := slices.Index(extraRequiredAudio, name); index > -1 && isAcceptedAudioExt(ext) { extraRequiredAudio = append(extraRequiredAudio[:index], extraRequiredAudio[index+1:]...) } frompath := path.Join(roomFolder.Path, entry.Name()) topath := path.Join(roomoutpath, entry.Name()) err := copyFile(frompath, topath) if err != nil { return err } } if len(extraRequiredImages) > 0 { log.Printf("INFO: necessary optional images will use a transparent file: %v", extraRequiredImages) transparent := image.NewRGBA(image.Rectangle{image.Point{0, 0}, image.Point{1, 1}}) transparent.Set(0, 0, color.RGBA{0xff, 0xff, 0xff, 0x01}) for _, imagename := range extraRequiredImages { imagepath := path.Join(roomoutpath, imagename+".png") f, err := os.Create(imagepath) if err != nil { return err } png.Encode(f, transparent) } } if len(extraRequiredAudio) > 0 { log.Printf("INFO: necessary optional audios will use a silent file: %v", extraRequiredAudio) for _, audioname := range extraRequiredAudio { audiopath := path.Join(roomoutpath, audioname+".wav") err := os.WriteFile(audiopath, SILENCE_WAV, FILEPERM) if err != nil { return err } } } return nil } func copyFile(from, to string) error { fromdata, err := os.ReadFile(from) if err != nil { return err } return os.WriteFile(to, fromdata, FILEPERM) }