Files
panel/pkg/regionmedic/localize.go
T
dbledeez a00bd620a1 Panel — public source drop (v0.9.0)
Self-hostable game-server control panel: controller + agent + 26 game
modules. One-line install (prebuilt release, no Go required):

  curl -fsSL https://git.pdxtechs.com/dbledeez/panel/raw/branch/main/install.sh | sudo bash

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-14 21:17:39 -07:00

104 lines
3.1 KiB
Go
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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
}