Basic functionality

This commit is contained in:
Henri Burau
2024-06-05 18:01:08 +02:00
parent 17f878f088
commit 72dce76e2b
41 changed files with 1568 additions and 176 deletions

42
models/cod4cache.go Normal file
View File

@ -0,0 +1,42 @@
package models
import (
"fmt"
"time"
"github.com/patrickmn/go-cache"
)
type CachedProvider struct {
provider StatusProvider
cache *cache.Cache
}
func NewCachedProvider(provider StatusProvider) (*CachedProvider, error) {
c := cache.New(10*time.Second, 20*time.Second)
return &CachedProvider{
provider: provider,
cache: c,
}, nil
}
func (c *CachedProvider) GetServerStatus(host, port string, timeout time.Duration) (*CoD4ServerStatus, error) {
status, found := c.cache.Get(ID(host, port))
if found {
return status.(*CoD4ServerStatus), nil
} else {
status, err := c.provider.GetServerStatus(host, port, timeout)
if err != nil {
return nil, err
}
c.cache.Set(ID(host, port), status, cache.DefaultExpiration)
return status, nil
}
}
func ID(host, port string) string {
return fmt.Sprintf("%s:%s", host, port)
}

View File

@ -12,38 +12,44 @@ import (
"time"
)
var timeLayout = "Mon Jan 2 15:04:05 2006"
var (
timeLayout = "Mon Jan 2 15:04:05 2006"
)
type StatusProvider interface {
GetServerStatus(string, string, time.Duration) (*CoD4ServerStatus, error)
}
type CoD4Server struct {
server string
port string
protocol string
timeout time.Duration
server string
port string
timeout time.Duration
}
type CoD4ServerStatus struct {
raw string
serverData map[string]string
Name string
MapStartTime time.Time
MapName string
MaxPlayers int
Score []Score
meta map[string]interface{}
}
func NewCOD4ServerStatus(server, port string, timeout time.Duration) (*CoD4Server, error) {
type CoD4UdpClient struct{}
func (CoD4UdpClient) GetServerStatus(server, port string, timeout time.Duration) (*CoD4ServerStatus, error) {
if server == "" || port == "" {
return nil, errors.New("server or port is empty")
}
return &CoD4Server{
server: server,
port: port,
protocol: "udp",
timeout: timeout,
}, nil
}
c := &CoD4Server{
server: server,
port: port,
timeout: timeout,
}
func (c *CoD4Server) GetServerStatus() (*CoD4ServerStatus, error) {
data, err := c.receiveData()
if err != nil {
return nil, err
@ -54,7 +60,7 @@ func (c *CoD4Server) GetServerStatus() (*CoD4ServerStatus, error) {
func (c *CoD4Server) receiveData() (string, error) {
address := fmt.Sprintf("%s:%s", c.server, c.port)
conn, err := net.DialTimeout(c.protocol, address, c.timeout)
conn, err := net.DialTimeout("udp", address, c.timeout)
if err != nil {
return "", fmt.Errorf("could not connect to server: %s", err)
}
@ -105,11 +111,16 @@ func parseServerData(data string) (*CoD4ServerStatus, error) {
c.serverData[tempData[i]] = tempData[i+1]
}
startTime, err := time.ParseInLocation(timeLayout, c.serverData["g_mapStartTime"], time.Local)
if err != nil {
return nil, err
}
c.serverData["sv_hostname"] = colorCode(c.serverData["sv_hostname"])
c.Name = c.serverData["sv_hostname"]
c.serverData["_Maps"] = strings.Join(strings.Split(c.serverData["_Maps"], "-"), ",")
c.MapName = c.serverData["mapname"]
startTime, err := time.ParseInLocation(timeLayout, c.serverData["g_mapStartTime"], time.Local)
c.MaxPlayers, err = strconv.Atoi(c.serverData["sv_maxclients"])
if err != nil {
return nil, err
}
@ -159,9 +170,19 @@ func colorCode(str string) string {
"9": "#6E3C3C",
}
re := regexp.MustCompile(`\^(\d)(.*?)\^`)
return re.ReplaceAllStringFunc(str, func(m string) string {
matches := re.FindStringSubmatch(m)
return fmt.Sprintf(`<span style="color:%s;">%s</span>^`, colorMap[matches[1]], matches[2])
re := regexp.MustCompile(`\^(\d)`)
str = re.ReplaceAllStringFunc(str, func(m string) string {
code := string(m[1])
if color, ok := colorMap[code]; ok {
return fmt.Sprintf(`<span style="color:%s;">`, color)
}
return m
})
// Close open span tags
str += "^"
reClose := regexp.MustCompile(`\^(.*?)\^`)
str = reClose.ReplaceAllString(str, "$1</span>")
return str[:len(str)-1]
}

View File

@ -12,6 +12,7 @@ import (
type Persistence interface {
CreateCapture(context.Context, *Capture) error
UpdateCapture(context.Context, *Capture) error
GetCaptures(context.Context) ([]Capture, error)
GetCapturesByID(context.Context, int64) (*Capture, error)
DeleteCapture(context.Context, int64) error
@ -68,6 +69,12 @@ func (s *SQLitePersistence) GetCapturesByID(ctx context.Context, id int64) (*Cap
return &capture, err
}
func (s *SQLitePersistence) UpdateCapture(ctx context.Context, capture *Capture) error {
_, err := s.db.NewUpdate().Model(capture).WherePK().Exec(ctx)
return err
}
func (s *SQLitePersistence) DeleteCapture(ctx context.Context, id int64) error {
capture := Capture{
ID: id,