init
This commit is contained in:
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
rooms
|
||||||
|
rooms_out
|
||||||
29
assignroom.go
Normal file
29
assignroom.go
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
func AssignExtraRooms(rooms []RoomFolder, roomsPerNight int) {
|
||||||
|
latestnight := 0
|
||||||
|
|
||||||
|
for _, r := range rooms {
|
||||||
|
if r.cfg.night > latestnight {
|
||||||
|
latestnight = r.cfg.night
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
night := latestnight + 1
|
||||||
|
room := 1
|
||||||
|
|
||||||
|
for i, r := range rooms {
|
||||||
|
if r.cfg.night > 0 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
rooms[i].cfg.night = night
|
||||||
|
rooms[i].cfg.room = room
|
||||||
|
|
||||||
|
room++
|
||||||
|
if room > roomsPerNight {
|
||||||
|
room = 1
|
||||||
|
night++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
5
go.mod
Normal file
5
go.mod
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
module zomo.dev/bappackage
|
||||||
|
|
||||||
|
go 1.25.0
|
||||||
|
|
||||||
|
require gopkg.in/ini.v1 v1.67.0 // indirect
|
||||||
2
go.sum
Normal file
2
go.sum
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA=
|
||||||
|
gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
|
||||||
201
ini.go
Normal file
201
ini.go
Normal file
@@ -0,0 +1,201 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"strconv"
|
||||||
|
|
||||||
|
"gopkg.in/ini.v1"
|
||||||
|
)
|
||||||
|
|
||||||
|
type RoomIni struct {
|
||||||
|
night int
|
||||||
|
room int
|
||||||
|
|
||||||
|
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 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
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
meta, err := cfg.GetSection("DEFAULT")
|
||||||
|
if err != nil {
|
||||||
|
return RoomIni{}, fmt.Errorf("unable to load DEFAULT section in %s: %+v", path, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
sections := cfg.Sections()
|
||||||
|
var room *ini.Section = nil
|
||||||
|
|
||||||
|
for _, sec := range sections {
|
||||||
|
if room != nil {
|
||||||
|
fmt.Printf("WARN: extra section in %s, section: %s\n", path, sec.Name())
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if sec.Name() != "default" {
|
||||||
|
room = sec
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
roomIni, err := loadIni(meta, room)
|
||||||
|
if err != nil {
|
||||||
|
return RoomIni{}, fmt.Errorf("ERROR: error loading ini from %s: %+v", path, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return roomIni, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func loadIni(meta *ini.Section, room *ini.Section) (RoomIni, error) {
|
||||||
|
roomini := RoomIni{}
|
||||||
|
|
||||||
|
if val, err := loadInt(meta, "night", -1); err != nil {
|
||||||
|
return RoomIni{}, err
|
||||||
|
} else {
|
||||||
|
roomini.night = val
|
||||||
|
}
|
||||||
|
|
||||||
|
if val, err := loadInt(meta, "room", -1); err != nil {
|
||||||
|
return RoomIni{}, err
|
||||||
|
} else {
|
||||||
|
roomini.room = val
|
||||||
|
}
|
||||||
|
|
||||||
|
if roomini.night > 0 && roomini.room < 1 {
|
||||||
|
return RoomIni{}, fmt.Errorf("night is set but room is not set")
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if val, err := loatFloat(room, "size", 1); err != nil {
|
||||||
|
return RoomIni{}, err
|
||||||
|
} else {
|
||||||
|
roomini.size = val
|
||||||
|
}
|
||||||
|
|
||||||
|
if val, err := loatFloat(room, "speed", 1); err != nil {
|
||||||
|
return RoomIni{}, err
|
||||||
|
} else {
|
||||||
|
roomini.speed = val
|
||||||
|
}
|
||||||
|
|
||||||
|
if val, err := loatFloat(room, "fov", 55); err != nil {
|
||||||
|
return RoomIni{}, err
|
||||||
|
} else {
|
||||||
|
roomini.fov = val
|
||||||
|
}
|
||||||
|
|
||||||
|
if val, err := loatFloat(room, "texture_repeat", 3); err != nil {
|
||||||
|
return RoomIni{}, err
|
||||||
|
} else {
|
||||||
|
roomini.textureRepeat = val
|
||||||
|
}
|
||||||
|
|
||||||
|
if val, err := loatFloat(room, "room_height", 350); err != nil {
|
||||||
|
return RoomIni{}, err
|
||||||
|
} else {
|
||||||
|
roomini.roomHeight = val
|
||||||
|
}
|
||||||
|
|
||||||
|
if val, err := loadInt(room, "layer_frames", 1); err != nil {
|
||||||
|
return RoomIni{}, err
|
||||||
|
} else {
|
||||||
|
roomini.layerFrames = val
|
||||||
|
}
|
||||||
|
|
||||||
|
if val, err := loadInt(room, "fog_color", 0); err != nil {
|
||||||
|
return RoomIni{}, err
|
||||||
|
} else {
|
||||||
|
roomini.fogColor = val
|
||||||
|
}
|
||||||
|
|
||||||
|
if val, err := loatFloat(room, "fog_end", -1); err != nil {
|
||||||
|
return RoomIni{}, err
|
||||||
|
} else {
|
||||||
|
roomini.fogEnd = val
|
||||||
|
}
|
||||||
|
|
||||||
|
if val, err := loatFloat(room, "mini_speed", 1); err != nil {
|
||||||
|
return RoomIni{}, err
|
||||||
|
} else {
|
||||||
|
roomini.miniSpeed = val
|
||||||
|
}
|
||||||
|
|
||||||
|
return roomini, nil
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func loadInt(sec *ini.Section, key string, def int) (int, error) {
|
||||||
|
val, err := sec.GetKey(key)
|
||||||
|
if err != nil {
|
||||||
|
return def, nil
|
||||||
|
}
|
||||||
|
valint, err := val.Int()
|
||||||
|
if err != nil {
|
||||||
|
return def, err
|
||||||
|
}
|
||||||
|
return valint, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func loatFloat(sec *ini.Section, key string, def float64) (float64, error) {
|
||||||
|
val, err := sec.GetKey(key)
|
||||||
|
if err != nil {
|
||||||
|
return def, nil
|
||||||
|
}
|
||||||
|
valfloat, err := val.Float64()
|
||||||
|
if err != nil {
|
||||||
|
return def, err
|
||||||
|
}
|
||||||
|
return valfloat, nil
|
||||||
|
}
|
||||||
131
loadrooms.go
Normal file
131
loadrooms.go
Normal file
@@ -0,0 +1,131 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
"path"
|
||||||
|
"path/filepath"
|
||||||
|
"slices"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
var REQUIRED_IMAGES = []string{
|
||||||
|
"ART",
|
||||||
|
"MINI",
|
||||||
|
"CREDIT",
|
||||||
|
"INTERACT",
|
||||||
|
"FLOOR",
|
||||||
|
"LAYER",
|
||||||
|
"ROOF",
|
||||||
|
"WALL",
|
||||||
|
}
|
||||||
|
var ACCEPTED_IMAGE_EXT = []string{
|
||||||
|
".PNG",
|
||||||
|
".JPG",
|
||||||
|
".BMP",
|
||||||
|
}
|
||||||
|
|
||||||
|
var REQUIRED_AUDIO = []string{
|
||||||
|
"FOOT",
|
||||||
|
"MUSIC",
|
||||||
|
}
|
||||||
|
var ACCEPTED_AUDIO_EXT = []string{
|
||||||
|
".WAV",
|
||||||
|
".MP3",
|
||||||
|
".OGG",
|
||||||
|
".MIDI",
|
||||||
|
}
|
||||||
|
|
||||||
|
type RoomFolder struct {
|
||||||
|
path string
|
||||||
|
cfg RoomIni
|
||||||
|
}
|
||||||
|
|
||||||
|
func LoadRoomFolders(roomspath string) ([]RoomFolder, error) {
|
||||||
|
entries, err := os.ReadDir(roomspath)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
rooms := make([]RoomFolder, 0)
|
||||||
|
|
||||||
|
for _, entry := range entries {
|
||||||
|
entrypath := filepath.Join(roomspath, entry.Name())
|
||||||
|
if !entry.IsDir() {
|
||||||
|
fmt.Printf("WARN: unexpected non-directory found in rooms directory: %s\n", entrypath)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
roomfolder, err := loadRoom(entrypath)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Printf("ERROR: unable to load directory: %s\n", entrypath)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
rooms = append(rooms, roomfolder)
|
||||||
|
}
|
||||||
|
|
||||||
|
return rooms, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func loadRoom(roompath string) (RoomFolder, error) {
|
||||||
|
entries, err := os.ReadDir(roompath)
|
||||||
|
if err != nil {
|
||||||
|
return RoomFolder{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
requiredImages := make([]string, len(REQUIRED_IMAGES))
|
||||||
|
copy(requiredImages, REQUIRED_IMAGES)
|
||||||
|
requiredAudio := make([]string, len(REQUIRED_AUDIO))
|
||||||
|
copy(requiredAudio, REQUIRED_AUDIO)
|
||||||
|
|
||||||
|
roominiName := ""
|
||||||
|
for _, entry := range entries {
|
||||||
|
filename := entry.Name()
|
||||||
|
if strings.ToLower(filename) == "room.ini" {
|
||||||
|
roominiName = filename
|
||||||
|
}
|
||||||
|
|
||||||
|
ext := strings.ToUpper(path.Ext(filename))
|
||||||
|
name := strings.ToUpper(filename[:len(filename)-len(ext)])
|
||||||
|
|
||||||
|
if index := slices.Index(requiredImages, name); index > -1 && slices.Contains(ACCEPTED_IMAGE_EXT, ext) {
|
||||||
|
requiredImages = append(requiredImages[:index], requiredImages[index+1:]...)
|
||||||
|
}
|
||||||
|
|
||||||
|
if index := slices.Index(requiredAudio, name); index > -1 && slices.Contains(ACCEPTED_AUDIO_EXT, ext) {
|
||||||
|
requiredAudio = append(requiredAudio[:index], requiredAudio[index+1:]...)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
errormsg := ""
|
||||||
|
if len(requiredImages) > 0 && len(requiredAudio) > 0 {
|
||||||
|
errormsg = fmt.Sprintf("images: %v, audio: %v", requiredImages, requiredAudio)
|
||||||
|
}
|
||||||
|
if len(requiredImages) > 0 {
|
||||||
|
errormsg = fmt.Sprintf("images: %v", requiredImages)
|
||||||
|
}
|
||||||
|
if len(requiredAudio) > 0 {
|
||||||
|
errormsg = fmt.Sprintf("audio: %v", requiredAudio)
|
||||||
|
}
|
||||||
|
|
||||||
|
if errormsg != "" {
|
||||||
|
return RoomFolder{}, fmt.Errorf("unable to load room %s: missing required %s", roompath, errormsg)
|
||||||
|
}
|
||||||
|
|
||||||
|
cfg := NewRoomIni()
|
||||||
|
if roominiName != "" {
|
||||||
|
newcfg, err := ReadIni(filepath.Join(roompath, "room.ini"))
|
||||||
|
if err != nil {
|
||||||
|
return RoomFolder{}, err
|
||||||
|
}
|
||||||
|
cfg = newcfg
|
||||||
|
}
|
||||||
|
|
||||||
|
return RoomFolder{
|
||||||
|
path: roompath,
|
||||||
|
cfg: cfg,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
22
main.go
Normal file
22
main.go
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
const BASEPATH = "./rooms"
|
||||||
|
const OUTPATH = "./rooms_out"
|
||||||
|
const ROOM_PER_NIGHT = 4
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
if err := mainErr(); err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func mainErr() error {
|
||||||
|
roomFolders, err := LoadRoomFolders(BASEPATH)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
AssignExtraRooms(roomFolders, ROOM_PER_NIGHT)
|
||||||
|
|
||||||
|
return CopyOut(roomFolders, OUTPATH)
|
||||||
|
}
|
||||||
82
out.go
Normal file
82
out.go
Normal file
@@ -0,0 +1,82 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
"path"
|
||||||
|
"path/filepath"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
const FILEPERM = 0644
|
||||||
|
const INIPREFIX = `[SETTINGS]
|
||||||
|
Sensitivity=6
|
||||||
|
Splash1len=2
|
||||||
|
Splash2len=2
|
||||||
|
`
|
||||||
|
|
||||||
|
func CopyOut(roomFolders []RoomFolder, outpath string) error {
|
||||||
|
inistr := INIPREFIX
|
||||||
|
|
||||||
|
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")
|
||||||
|
fmt.Printf("Writing %s\n", 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)
|
||||||
|
fmt.Printf(`Copying:
|
||||||
|
%s
|
||||||
|
to %s
|
||||||
|
`, roomFolder.path, roomoutpath)
|
||||||
|
|
||||||
|
entries, err := os.ReadDir(roomFolder.path)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, entry := range entries {
|
||||||
|
// TODO whitelist files?
|
||||||
|
entrypath := path.Join(roomFolder.path, entry.Name())
|
||||||
|
|
||||||
|
if entry.IsDir() {
|
||||||
|
fmt.Printf("WARN: unexpected folder found in room folder: %s\n", entrypath)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if strings.ToLower(entry.Name()) == "room.ini" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
topath := path.Join(roomoutpath, entry.Name())
|
||||||
|
|
||||||
|
err := copyFile(entrypath, topath)
|
||||||
|
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)
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user