panel — open-source game server manager (public release)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
2026-07-14 19:19:43 -07:00
commit 658bda1d24
2160 changed files with 300413 additions and 0 deletions
+103
View File
@@ -0,0 +1,103 @@
package regionmedic
import (
"fmt"
"strconv"
"strings"
)
// floorMod returns the mathematical (floored) modulo, always in [0, m).
func floorMod(a, m int) int { return ((a % m) + m) % m }
// floorDiv returns the floored integer division (rounds toward -inf).
func floorDiv(a, m int) int {
q := a / m
if (a%m != 0) && ((a < 0) != (m < 0)) {
q--
}
return q
}
// RegionCoord identifies a region file r.<X>.<Z>.7rg in the 32×32-chunk grid.
type RegionCoord struct {
X int `json:"x"`
Z int `json:"z"`
}
// FileName returns the on-disk region filename, e.g. "r.-2.0.7rg".
func (rc RegionCoord) FileName() string { return fmt.Sprintf("r.%d.%d.7rg", rc.X, rc.Z) }
// String returns the canonical region id, e.g. "r.-2.0".
func (rc RegionCoord) String() string { return fmt.Sprintf("r.%d.%d", rc.X, rc.Z) }
// RegionForChunk maps a global chunk coordinate to its region (floored /32).
func RegionForChunk(cx, cz int) RegionCoord {
return RegionCoord{X: floorDiv(cx, RegionSide), Z: floorDiv(cz, RegionSide)}
}
// ParseRegionFileName parses "r.<X>.<Z>.7rg" -> RegionCoord. ok=false otherwise.
// Handles negative coordinates, e.g. "r.-2.0.7rg" -> {X:-2, Z:0}.
func ParseRegionFileName(name string) (RegionCoord, bool) {
if !strings.HasPrefix(name, "r.") || !strings.HasSuffix(name, ".7rg") {
return RegionCoord{}, false
}
mid := strings.TrimSuffix(strings.TrimPrefix(name, "r."), ".7rg")
// mid is "<X>.<Z>" where X and Z may be negative. Split on the dot that
// separates them: there is exactly one '.' between two integers.
x, z, ok := splitTwoInts(mid)
if !ok {
return RegionCoord{}, false
}
return RegionCoord{X: x, Z: z}, true
}
// ParseErrorBackup parses 7DTD chunk-salvage filenames written on a failed load:
//
// error_backup_<cx>_<cz>.comp.bak
// error_backup_<cx>_<cz>.uncomp.bak
//
// returning the global chunk coordinates. ok=false if name is not such a file.
func ParseErrorBackup(name string) (cx, cz int, ok bool) {
const pfx = "error_backup_"
if !strings.HasPrefix(name, pfx) {
return 0, 0, false
}
rest := name[len(pfx):]
// Strip the known suffixes.
switch {
case strings.HasSuffix(rest, ".comp.bak"):
rest = strings.TrimSuffix(rest, ".comp.bak")
case strings.HasSuffix(rest, ".uncomp.bak"):
rest = strings.TrimSuffix(rest, ".uncomp.bak")
default:
return 0, 0, false
}
// rest is "<cx>_<cz>" with possibly-negative ints separated by '_'.
i := strings.LastIndex(rest, "_")
if i <= 0 || i >= len(rest)-1 {
return 0, 0, false
}
a, err1 := strconv.Atoi(rest[:i])
b, err2 := strconv.Atoi(rest[i+1:])
if err1 != nil || err2 != nil {
return 0, 0, false
}
return a, b, true
}
// splitTwoInts splits "<a>.<b>" into two ints where each may be negative.
// The separator is the first '.' that is not a leading minus sign position.
func splitTwoInts(s string) (int, int, bool) {
// Find a '.' that splits into two parseable ints. Scan candidate dots.
for i := 1; i < len(s); i++ {
if s[i] != '.' {
continue
}
a, err1 := strconv.Atoi(s[:i])
b, err2 := strconv.Atoi(s[i+1:])
if err1 == nil && err2 == nil {
return a, b, true
}
}
return 0, 0, false
}