package pzconfig import ( "encoding/json" "fmt" "os" "path/filepath" "regexp" "strings" ) // javaLauncherFile — файл, из которого сервер берёт аргументы JVM. const javaLauncherFile = "ProjectZomboid64.json" var xmxRe = regexp.MustCompile(`^-Xm[sx]`) // SetJavaMemory прописывает лимит памяти JVM в ProjectZomboid64.json. Именно // оттуда start-server.sh берёт -Xmx, поэтому менять размер памяти в аргументах // запуска бесполезно. func SetJavaMemory(serverDir, memory string) error { memory = strings.TrimSpace(memory) if memory == "" { return nil } if !regexp.MustCompile(`^[0-9]+[kKmMgG]$`).MatchString(memory) { return fmt.Errorf("объём памяти должен выглядеть как 4g или 8192m, получено %q", memory) } path := filepath.Join(serverDir, javaLauncherFile) raw, err := os.ReadFile(path) if err != nil { return fmt.Errorf("прочитать %s: %w", path, err) } // Разбираем в map, чтобы не потерять поля, о которых мы не знаем. var doc map[string]any if err := json.Unmarshal(raw, &doc); err != nil { return fmt.Errorf("разобрать %s: %w", path, err) } args, _ := doc["vmArgs"].([]any) updated := make([]any, 0, len(args)+2) for _, a := range args { if str, ok := a.(string); ok && xmxRe.MatchString(str) { continue } updated = append(updated, a) } // -Xms равным -Xmx: JVM сразу забирает память и не тратит время на рост // кучи в момент, когда на сервере много игроков. updated = append(updated, "-Xms"+memory, "-Xmx"+memory) doc["vmArgs"] = updated out, err := json.MarshalIndent(doc, "", " ") if err != nil { return err } if err := backupFile(path); err != nil { return err } return writeAtomic(path, out, 0o644) }