update caching and server creation

This commit is contained in:
Fran Jurmanović
2025-06-01 19:48:39 +02:00
parent 8a3b11b1ef
commit d57013bb50
26 changed files with 888 additions and 249 deletions

View File

@@ -3,6 +3,7 @@ package db
import (
"acc-server-manager/local/model"
"acc-server-manager/local/utl/logging"
"time"
"go.uber.org/dig"
"gorm.io/driver/sqlite"
@@ -60,10 +61,17 @@ func Migrate(db *gorm.DB) {
if err != nil {
logging.Panic("failed to migrate model.StateHistory")
}
err = db.AutoMigrate(&model.SteamCredentials{})
if err != nil {
logging.Panic("failed to migrate model.SteamCredentials")
}
err = db.AutoMigrate(&model.SystemConfig{})
if err != nil {
logging.Panic("failed to migrate model.SystemConfig")
}
db.FirstOrCreate(&model.ApiModel{Api: "Works"})
Seed(db)
}
func Seed(db *gorm.DB) error {
@@ -85,15 +93,38 @@ func Seed(db *gorm.DB) error {
if err := seedServers(db); err != nil {
return err
}
if err := seedSteamCredentials(db); err != nil {
return err
}
if err := seedSystemConfigs(db); err != nil {
return err
}
return nil
}
func seedSteamCredentials(db *gorm.DB) error {
credentials := []model.SteamCredentials{
{
ID: 1,
Username: "test",
Password: "test",
DateCreated: time.Now().UTC(),
},
}
for _, credential := range credentials {
if err := db.FirstOrCreate(&credential).Error; err != nil {
return err
}
}
return nil
}
func seedServers(db *gorm.DB) error {
servers := []model.Server{
{ID: 1, Name: "ACC Server - Barcelona", ServiceName: "ACC-Barcelona", ConfigPath: "C:\\steamcmd\\acc"},
{ID: 2, Name: "ACC Server - Monza", ServiceName: "ACC-Monza", ConfigPath: "C:\\steamcmd\\acc2"},
{ID: 3, Name: "ACC Server - Spa", ServiceName: "ACC-Spa", ConfigPath: "C:\\steamcmd\\acc3"},
{ID: 4, Name: "ACC Server - League", ServiceName: "ACC-League", ConfigPath: "C:\\steamcmd\\acc-league"},
{ID: 1, Name: "ACC Server - Barcelona", ServiceName: "ACC-Barcelona", Path: "C:\\steamcmd\\acc", FromSteamCMD: true},
{ID: 2, Name: "ACC Server - Monza", ServiceName: "ACC-Monza", Path: "C:\\steamcmd\\acc2", FromSteamCMD: true},
{ID: 3, Name: "ACC Server - Spa", ServiceName: "ACC-Spa", Path: "C:\\steamcmd\\acc3", FromSteamCMD: true},
{ID: 4, Name: "ACC Server - League", ServiceName: "ACC-League", Path: "C:\\steamcmd\\acc-league", FromSteamCMD: true},
}
for _, track := range servers {
@@ -203,3 +234,41 @@ func seedSessionTypes(db *gorm.DB) error {
}
return nil
}
func seedSystemConfigs(db *gorm.DB) error {
configs := []model.SystemConfig{
{
Key: model.ConfigKeySteamCMDPath,
DefaultValue: "c:\\steamcmd\\steamcmd.exe",
Description: "Path to SteamCMD executable",
DateModified: time.Now().UTC().Format(time.RFC3339),
},
{
Key: model.ConfigKeyNSSMPath,
DefaultValue: ".\\nssm.exe",
Description: "Path to NSSM executable",
DateModified: time.Now().UTC().Format(time.RFC3339),
},
}
for _, config := range configs {
var exists bool
err := db.Model(&model.SystemConfig{}).
Select("count(*) > 0").
Where("key = ?", config.Key).
Find(&exists).
Error
if err != nil {
return err
}
if !exists {
if err := db.Create(&config).Error; err != nil {
return err
}
logging.Info("Seeded system config: %s", config.Key)
}
}
return nil
}

View File

@@ -136,8 +136,9 @@ func Panic(format string) {
// RecoverAndLog recovers from panics and logs them
func RecoverAndLog() {
if r := recover(); r != nil {
if logger != nil {
if logger != nil {
logger.Info("Recovering from panic")
if r := recover(); r != nil {
// Get stack trace
buf := make([]byte, 4096)
n := runtime.Stack(buf, false)

87
local/utl/network/port.go Normal file
View File

@@ -0,0 +1,87 @@
package network
import (
"fmt"
"net"
"time"
)
// IsPortAvailable checks if a port is available for both TCP and UDP
func IsPortAvailable(port int) bool {
return IsTCPPortAvailable(port) && IsUDPPortAvailable(port)
}
// IsTCPPortAvailable checks if a TCP port is available
func IsTCPPortAvailable(port int) bool {
addr := fmt.Sprintf(":%d", port)
listener, err := net.Listen("tcp", addr)
if err != nil {
return false
}
listener.Close()
return true
}
// IsUDPPortAvailable checks if a UDP port is available
func IsUDPPortAvailable(port int) bool {
conn, err := net.ListenUDP("udp", &net.UDPAddr{Port: port})
if err != nil {
return false
}
conn.Close()
return true
}
// FindAvailablePort finds an available port starting from the given port
func FindAvailablePort(startPort int) (int, error) {
maxPort := 65535
for port := startPort; port <= maxPort; port++ {
if IsPortAvailable(port) {
return port, nil
}
}
return 0, fmt.Errorf("no available ports found between %d and %d", startPort, maxPort)
}
// FindAvailablePortRange finds a range of consecutive available ports
func FindAvailablePortRange(startPort, count int) ([]int, error) {
maxPort := 65535
ports := make([]int, 0, count)
currentPort := startPort
for len(ports) < count && currentPort <= maxPort {
// Check if we have enough consecutive ports available
available := true
for i := 0; i < count-len(ports); i++ {
if !IsPortAvailable(currentPort + i) {
available = false
currentPort += i + 1
break
}
}
if available {
for i := 0; i < count-len(ports); i++ {
ports = append(ports, currentPort+i)
}
}
}
if len(ports) < count {
return nil, fmt.Errorf("could not find %d consecutive available ports starting from %d", count, startPort)
}
return ports, nil
}
// WaitForPortAvailable waits for a port to become available with timeout
func WaitForPortAvailable(port int, timeout time.Duration) error {
deadline := time.Now().Add(timeout)
for time.Now().Before(deadline) {
if IsPortAvailable(port) {
return nil
}
time.Sleep(100 * time.Millisecond)
}
return fmt.Errorf("timeout waiting for port %d to become available", port)
}

View File

@@ -1,4 +1,4 @@
package regexHandler
package regex_handler
import (
"acc-server-manager/local/model"

View File

@@ -2,7 +2,7 @@ package tracking
import (
"acc-server-manager/local/model"
"acc-server-manager/local/utl/regexHandler"
"acc-server-manager/local/utl/regex_handler"
"bufio"
"os"
"strconv"
@@ -36,13 +36,13 @@ func NewAccServerInstance(server *model.Server, onStateChange func(*model.Server
}
type StateRegexHandler struct {
*regexHandler.RegexHandler
*regex_handler.RegexHandler
test string
}
func NewRegexHandler(str string, test string) *StateRegexHandler {
return &StateRegexHandler{
RegexHandler: regexHandler.New(str),
RegexHandler: regex_handler.New(str),
test: test,
}
}