Files
VRCWT-OSC/VRWT_Tool/VRC_OSC/internal/config/config.go
2026-06-24 02:38:06 +09:00

147 lines
3.1 KiB
Go

package config
import (
"bufio"
"os"
"path/filepath"
"strconv"
"strings"
"vrc_osc_go/internal/common"
)
type Config struct {
OSC OSCConfig
VrcLog VrcLogConfig
}
type OSCConfig struct {
Host string
Port int
}
type VrcLogConfig struct {
SelfName string
GuestNames []string
GuestFile string
StaffNames []string
MissingCount int
LogPatterns []string
}
func Load(path string) (*Config, error) {
cfg := &Config{
OSC: OSCConfig{Host: "127.0.0.1", Port: 9001},
}
if path == "" {
path = filepath.Join(common.RootDir(), "config", "config.toml")
} else if !filepath.IsAbs(path) {
path = filepath.Join(common.RootDir(), path)
}
file, err := os.Open(path)
if err != nil {
return cfg, nil
}
defer file.Close()
var section string
scanner := bufio.NewScanner(file)
for scanner.Scan() {
line := strings.TrimSpace(scanner.Text())
line = strings.TrimPrefix(line, "\ufeff")
if line == "" || strings.HasPrefix(line, "#") {
continue
}
if strings.HasPrefix(line, "[") && strings.HasSuffix(line, "]") {
section = strings.Trim(line, "[]")
continue
}
parts := strings.SplitN(line, "=", 2)
if len(parts) != 2 {
continue
}
key := strings.TrimSpace(parts[0])
val := strings.TrimSpace(parts[1])
val = strings.Trim(val, "\"'")
switch section {
case "osc":
switch key {
case "host":
cfg.OSC.Host = val
case "port":
if n, err := strconv.Atoi(val); err == nil {
cfg.OSC.Port = n
}
}
case "self":
if key == "name" {
cfg.VrcLog.SelfName = val
}
case "notice":
if key == "missing_count" {
if n, err := strconv.Atoi(val); err == nil {
cfg.VrcLog.MissingCount = n
}
}
case "vrc_log":
if key == "patterns" {
cfg.VrcLog.LogPatterns = parseList(val)
}
case "staff":
if key == "names" {
cfg.VrcLog.StaffNames = parseList(val)
}
case "guest":
switch key {
case "names":
cfg.VrcLog.GuestNames = parseList(val)
case "file":
cfg.VrcLog.GuestFile = val
}
}
}
if cfg.VrcLog.GuestFile != "" {
if !filepath.IsAbs(cfg.VrcLog.GuestFile) {
cfg.VrcLog.GuestFile = filepath.Join(common.RootDir(), cfg.VrcLog.GuestFile)
}
if names, err := loadLines(cfg.VrcLog.GuestFile); err == nil {
cfg.VrcLog.GuestNames = names
}
}
return cfg, scanner.Err()
}
func parseList(value string) []string {
value = strings.TrimSpace(value)
value = strings.TrimPrefix(value, "[")
value = strings.TrimSuffix(value, "]")
if value == "" {
return nil
}
parts := strings.Split(value, ",")
out := make([]string, 0, len(parts))
for _, part := range parts {
part = strings.TrimSpace(strings.Trim(part, "\"'"))
if part != "" {
out = append(out, part)
}
}
return out
}
func loadLines(path string) ([]string, error) {
data, err := os.ReadFile(path)
if err != nil {
return nil, err
}
lines := strings.Split(string(data), "\n")
out := make([]string, 0, len(lines))
for _, line := range lines {
line = strings.TrimSpace(strings.TrimPrefix(line, "\ufeff"))
if line != "" && !strings.HasPrefix(line, "#") {
out = append(out, line)
}
}
return out, nil
}